initial commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
@@ -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"
|
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "ascon"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
5
README.md
Normal file
5
README.md
Normal file
@@ -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.
|
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]
|
||||
}
|
13
src/main.rs
Normal file
13
src/main.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
use std::{env, fs};
|
||||
|
||||
mod ascon;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
let args: Vec<String> = 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();
|
||||
}
|
Reference in New Issue
Block a user