commit dcd62655b7c29584d4783226ea5d9742d6231d29 Author: Matt Date: Mon Aug 18 21:42:46 2025 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..51df615 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ascon" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f5e85b9 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ascon" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/README.md b/README.md new file mode 100644 index 0000000..42cb68f --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# ascon rust + +Do not use this at all for anything what so ever. + +I wanted to implement ascon to see how it worked and also wanted to get some rust practice in. diff --git a/src/ascon.rs b/src/ascon.rs new file mode 100644 index 0000000..6cad6ac --- /dev/null +++ b/src/ascon.rs @@ -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] +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..f4addf7 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,13 @@ +use std::{env, fs}; + +mod ascon; + +fn main() { + println!("Hello, world!"); + let args: Vec = env::args().collect(); + if args.len() < 2 { + panic!("Argument not provided") + } + let data = fs::read(args[1].clone()).expect("Failed to read file"); + ascon::ascon256(&data).hex(); +}