initial commit
This commit is contained in:
95
src/ascon.rs
Normal file
95
src/ascon.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
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;
|
||||
|
||||
let mut t0 = !x0;
|
||||
let mut t1 = !x1;
|
||||
let mut t2 = !x2;
|
||||
let mut t3 = !x3;
|
||||
let mut t4 = !x4;
|
||||
|
||||
t0 &= x1;
|
||||
t1 &= x2;
|
||||
t2 &= x3;
|
||||
t3 &= x4;
|
||||
t4 &= x0;
|
||||
|
||||
x0 ^= t1;
|
||||
x1 ^= t2;
|
||||
x2 ^= t3;
|
||||
x3 ^= t4;
|
||||
x4 ^= t0;
|
||||
|
||||
x1 ^= x0;
|
||||
x0 ^= x4;
|
||||
x3 ^= x2;
|
||||
|
||||
[x0, x1, !x2, x3, x4]
|
||||
}
|
Reference in New Issue
Block a user