1
0
Files
rust-ascon/src/ascon.rs

90 lines
2.1 KiB
Rust
Raw Normal View History

2025-08-18 21:42:46 +01:00
pub struct HashResult {
result: [u64; 4],
}
impl HashResult {
pub fn hex(&self) {
for i in 0..4 {
print!("{:016X}", self.result[i]);
}
println!();
}
}
pub fn ascon256(input: &[u8]) -> HashResult {
let mut state = [0u64; 5];
state[0] = 0x00400c0000000100;
state = permutate(state);
let mut chunked_iterator = input.chunks_exact(8);
let mut sized_chunk = [0u8; 8];
for chunk in &mut chunked_iterator {
sized_chunk.copy_from_slice(chunk);
state[0] ^= u64::from_be_bytes(sized_chunk);
state = permutate(state);
}
let remainder = chunked_iterator.remainder();
if !remainder.is_empty() {
sized_chunk = [0u8; 8];
sized_chunk[..remainder.len()].copy_from_slice(remainder);
sized_chunk[remainder.len()] |= 0x80;
state[0] ^= u64::from_be_bytes(sized_chunk);
}
let mut res = HashResult { result: [0u64; 4] };
state = permutate(state);
for i in 0..3 {
res.result[i] = state[0];
state = permutate(state);
}
res.result[3] = state[0];
res
}
fn permutate(input: [u64; 5]) -> [u64; 5] {
let mut state = input;
for i in 0..12 {
state = diffusion(sbox(add_constants(i, state)));
}
state
}
fn diffusion(input: [u64; 5]) -> [u64; 5] {
let [mut x0, mut x1, mut x2, mut x3, mut x4] = input;
x0 ^= x0.rotate_right(19) ^ x0.rotate_right(28);
x1 ^= x1.rotate_right(61) ^ x1.rotate_right(39);
x2 ^= x2.rotate_right(1) ^ x2.rotate_right(6);
x3 ^= x3.rotate_right(10) ^ x3.rotate_right(17);
x4 ^= x4.rotate_right(7) ^ x4.rotate_right(41);
[x0, x1, x2, x3, x4]
}
fn add_constants(round: u64, mut input: [u64; 5]) -> [u64; 5] {
input[2] ^= ((0b1111 - round) << 4) | round;
input
}
fn sbox(input: [u64; 5]) -> [u64; 5] {
let [mut x0, mut x1, mut x2, mut x3, mut x4] = input;
x0 ^= x4;
x4 ^= x3;
x2 ^= x1;
2025-08-18 22:53:19 +01:00
let t0 = !x0 & x1;
let t1 = !x1 & x2;
let t2 = !x2 & x3;
let t3 = !x3 & x4;
let t4 = !x4 & x0;
2025-08-18 21:42:46 +01:00
x0 ^= t1;
x1 ^= t2;
x2 ^= t3;
x3 ^= t4;
x4 ^= t0;
x1 ^= x0;
x0 ^= x4;
x3 ^= x2;
[x0, x1, !x2, x3, x4]
}