diff --git a/file.jpg b/file.jpg new file mode 100644 index 0000000..a4a6f97 Binary files /dev/null and b/file.jpg differ diff --git a/flamegraph.svg b/flamegraph.svg new file mode 100644 index 0000000..459afeb --- /dev/null +++ b/flamegraph.svg @@ -0,0 +1,491 @@ +Flame Graph Reset ZoomSearch [ld-linux-x86-64.so.2] (149,404 samples, 0.27%)[ld-linux-x86-64.so.2] (137,469 samples, 0.25%)[ld-linux-x86-64.so.2] (137,469 samples, 0.25%)[ld-linux-x86-64.so.2] (137,469 samples, 0.25%)[ld-linux-x86-64.so.2] (137,469 samples, 0.25%)[ld-linux-x86-64.so.2] (150,103 samples, 0.27%)[ld-linux-x86-64.so.2] (150,164 samples, 0.27%)[ld-linux-x86-64.so.2] (150,165 samples, 0.27%)[unknown] (54,753,263 samples, 99.73%)[unknown]sha3::sha3::keccak_permute (54,753,263 samples, 99.73%)sha3::sha3::keccak_permuteall (54,903,767 samples, 100%)sha3 (54,903,767 samples, 100.00%)sha3 \ No newline at end of file diff --git a/perf.data b/perf.data new file mode 100644 index 0000000..2dc2a26 Binary files /dev/null and b/perf.data differ diff --git a/perf.data.old b/perf.data.old new file mode 100644 index 0000000..f87c4ee Binary files /dev/null and b/perf.data.old differ diff --git a/src/consts.rs b/src/consts.rs new file mode 100644 index 0000000..d769441 --- /dev/null +++ b/src/consts.rs @@ -0,0 +1,258 @@ +pub const LFSR_LUT: [(bool, u8); 256] = [ + (false, 0x00), + (true, 0x02), + (false, 0x04), + (true, 0x06), + (false, 0x08), + (true, 0x0a), + (false, 0x0c), + (true, 0x0e), + (false, 0x10), + (true, 0x12), + (false, 0x14), + (true, 0x16), + (false, 0x18), + (true, 0x1a), + (false, 0x1c), + (true, 0x1e), + (false, 0x20), + (true, 0x22), + (false, 0x24), + (true, 0x26), + (false, 0x28), + (true, 0x2a), + (false, 0x2c), + (true, 0x2e), + (false, 0x30), + (true, 0x32), + (false, 0x34), + (true, 0x36), + (false, 0x38), + (true, 0x3a), + (false, 0x3c), + (true, 0x3e), + (false, 0x40), + (true, 0x42), + (false, 0x44), + (true, 0x46), + (false, 0x48), + (true, 0x4a), + (false, 0x4c), + (true, 0x4e), + (false, 0x50), + (true, 0x52), + (false, 0x54), + (true, 0x56), + (false, 0x58), + (true, 0x5a), + (false, 0x5c), + (true, 0x5e), + (false, 0x60), + (true, 0x62), + (false, 0x64), + (true, 0x66), + (false, 0x68), + (true, 0x6a), + (false, 0x6c), + (true, 0x6e), + (false, 0x70), + (true, 0x72), + (false, 0x74), + (true, 0x76), + (false, 0x78), + (true, 0x7a), + (false, 0x7c), + (true, 0x7e), + (false, 0x80), + (true, 0x82), + (false, 0x84), + (true, 0x86), + (false, 0x88), + (true, 0x8a), + (false, 0x8c), + (true, 0x8e), + (false, 0x90), + (true, 0x92), + (false, 0x94), + (true, 0x96), + (false, 0x98), + (true, 0x9a), + (false, 0x9c), + (true, 0x9e), + (false, 0xa0), + (true, 0xa2), + (false, 0xa4), + (true, 0xa6), + (false, 0xa8), + (true, 0xaa), + (false, 0xac), + (true, 0xae), + (false, 0xb0), + (true, 0xb2), + (false, 0xb4), + (true, 0xb6), + (false, 0xb8), + (true, 0xba), + (false, 0xbc), + (true, 0xbe), + (false, 0xc0), + (true, 0xc2), + (false, 0xc4), + (true, 0xc6), + (false, 0xc8), + (true, 0xca), + (false, 0xcc), + (true, 0xce), + (false, 0xd0), + (true, 0xd2), + (false, 0xd4), + (true, 0xd6), + (false, 0xd8), + (true, 0xda), + (false, 0xdc), + (true, 0xde), + (false, 0xe0), + (true, 0xe2), + (false, 0xe4), + (true, 0xe6), + (false, 0xe8), + (true, 0xea), + (false, 0xec), + (true, 0xee), + (false, 0xf0), + (true, 0xf2), + (false, 0xf4), + (true, 0xf6), + (false, 0xf8), + (true, 0xfa), + (false, 0xfc), + (true, 0xfe), + (false, 0x71), + (true, 0x73), + (false, 0x75), + (true, 0x77), + (false, 0x79), + (true, 0x7b), + (false, 0x7d), + (true, 0x7f), + (false, 0x61), + (true, 0x63), + (false, 0x65), + (true, 0x67), + (false, 0x69), + (true, 0x6b), + (false, 0x6d), + (true, 0x6f), + (false, 0x51), + (true, 0x53), + (false, 0x55), + (true, 0x57), + (false, 0x59), + (true, 0x5b), + (false, 0x5d), + (true, 0x5f), + (false, 0x41), + (true, 0x43), + (false, 0x45), + (true, 0x47), + (false, 0x49), + (true, 0x4b), + (false, 0x4d), + (true, 0x4f), + (false, 0x31), + (true, 0x33), + (false, 0x35), + (true, 0x37), + (false, 0x39), + (true, 0x3b), + (false, 0x3d), + (true, 0x3f), + (false, 0x21), + (true, 0x23), + (false, 0x25), + (true, 0x27), + (false, 0x29), + (true, 0x2b), + (false, 0x2d), + (true, 0x2f), + (false, 0x11), + (true, 0x13), + (false, 0x15), + (true, 0x17), + (false, 0x19), + (true, 0x1b), + (false, 0x1d), + (true, 0x1f), + (false, 0x01), + (true, 0x03), + (false, 0x05), + (true, 0x07), + (false, 0x09), + (true, 0x0b), + (false, 0x0d), + (true, 0x0f), + (false, 0xf1), + (true, 0xf3), + (false, 0xf5), + (true, 0xf7), + (false, 0xf9), + (true, 0xfb), + (false, 0xfd), + (true, 0xff), + (false, 0xe1), + (true, 0xe3), + (false, 0xe5), + (true, 0xe7), + (false, 0xe9), + (true, 0xeb), + (false, 0xed), + (true, 0xef), + (false, 0xd1), + (true, 0xd3), + (false, 0xd5), + (true, 0xd7), + (false, 0xd9), + (true, 0xdb), + (false, 0xdd), + (true, 0xdf), + (false, 0xc1), + (true, 0xc3), + (false, 0xc5), + (true, 0xc7), + (false, 0xc9), + (true, 0xcb), + (false, 0xcd), + (true, 0xcf), + (false, 0xb1), + (true, 0xb3), + (false, 0xb5), + (true, 0xb7), + (false, 0xb9), + (true, 0xbb), + (false, 0xbd), + (true, 0xbf), + (false, 0xa1), + (true, 0xa3), + (false, 0xa5), + (true, 0xa7), + (false, 0xa9), + (true, 0xab), + (false, 0xad), + (true, 0xaf), + (false, 0x91), + (true, 0x93), + (false, 0x95), + (true, 0x97), + (false, 0x99), + (true, 0x9b), + (false, 0x9d), + (true, 0x9f), + (false, 0x81), + (true, 0x83), + (false, 0x85), + (true, 0x87), + (false, 0x89), + (true, 0x8b), + (false, 0x8d), + (true, 0x8f), +]; diff --git a/src/lib.rs b/src/lib.rs index 1199bac..84f7cb4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +pub mod consts; pub mod sha3; #[cfg(test)] diff --git a/src/main.rs b/src/main.rs index 1764ff6..724791b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,48 @@ +use std::{env, fs::File, io::Read, time}; + use sha3::sha3::Sha3_256; fn main() { + let args: Vec = env::args().collect(); + + if args.len() != 2 { + eprintln!("Usage: {} ", args[0]); + std::process::exit(1); + } + + let filename = &args[1]; + let mut file = File::open(filename).unwrap(); + + let mut file_data = Vec::new(); + + file.read_to_end(&mut file_data).unwrap(); + let mut sha = Sha3_256::default(); // println!("{:?}", (0x01 as u64).to_ne_bytes()); - let text = "hola"; + // let text = "hola"; - sha.absorb(text.as_bytes()); - let res = sha.squeeze(); + let now = time::Instant::now(); - let expected_res: [u8; 32] = [ - 0x8a, 0xf1, 0x3d, 0x92, 0x44, 0x61, 0x8e, 0xee, 0x87, 0x6d, 0x04, 0x31, 0xf3, 0x44, 0x9a, - 0xa4, 0xff, 0x95, 0x27, 0x4c, 0xa3, 0xe7, 0xe5, 0xc6, 0x54, 0x19, 0x79, 0x49, 0x9f, 0x5b, - 0x85, 0xde, - ]; + sha.absorb(&file_data); + let res: [u8; 32] = sha.squeeze(); + let elapsed = now.elapsed().as_micros() as f32; + + // let expected_res: [u8; 32] = [ + // 0x8a, 0xf1, 0x3d, 0x92, 0x44, 0x61, 0x8e, 0xee, 0x87, 0x6d, 0x04, 0x31, 0xf3, 0x44, 0x9a, + // 0xa4, 0xff, 0x95, 0x27, 0x4c, 0xa3, 0xe7, 0xe5, 0xc6, 0x54, 0x19, 0x79, 0x49, 0x9f, 0x5b, + // 0x85, 0xde, + // ]; + + print!("SHA3-256: "); for i in 0..32 { - print!("{:#001x} ", res[i]); + print!("{:x}", res[i]); } println!(); - assert!(res == expected_res); - println!("FUNCIONAAAAA"); + println!("Time taken: {} ms", elapsed / 1000_f32); + + // assert!(res == expected_res); } diff --git a/src/sha3.rs b/src/sha3.rs index df0c91f..c596786 100644 --- a/src/sha3.rs +++ b/src/sha3.rs @@ -5,37 +5,42 @@ use std::array; +use crate::consts::LFSR_LUT; + const RATE_256: usize = 136; const TOTAL_STATE_SIZE: usize = 200; +const TOTAL_STATE_SIZE_U64: usize = 25; const ROUNDS: usize = 24; const DELIMITER_SUFFIX: u8 = 0x06; // delimiter suffix for sha3 #[derive(Debug)] pub struct Sha3_256 { - state: [u8; TOTAL_STATE_SIZE], + state: [u64; TOTAL_STATE_SIZE_U64], } impl Default for Sha3_256 { fn default() -> Self { Self { - state: [0; TOTAL_STATE_SIZE], + state: [0; TOTAL_STATE_SIZE_U64], } } } impl Sha3_256 { pub fn absorb(&mut self, input: &[u8]) { + // let (inputs_u64, rem) = input.as_chunks::<8>(); + let state_u8 = [u8; 200]; + // Xor input with rate let mut remaining = input.len(); let mut off = 0; let mut in_len = 0; while remaining > 0 { in_len = remaining.min(RATE_256); - println!("{}", in_len); for i in 0..in_len { self.state[i] ^= input[i + off]; } - off += in_len - 1; + off += in_len; remaining -= in_len; if in_len == RATE_256 { @@ -44,6 +49,10 @@ impl Sha3_256 { } } + // for bytes in inputs_u64 { + + // } + self.state[in_len] ^= DELIMITER_SUFFIX; if (DELIMITER_SUFFIX & 0x80) != 0 && in_len == RATE_256 - 1 { @@ -69,35 +78,35 @@ impl Sha3_256 { keccak_permute(&mut self.state); } } - // *self.state.first_chunk().unwrap() + res } } fn keccak_permute(input: &mut [u8; TOTAL_STATE_SIZE]) { - let (lanes, _) = input.as_chunks_mut::<8>(); + // let (lanes, _) = input.as_chunks_mut::<8>(); let mut lfsr_state = 0x01_u8; for _ in 0..ROUNDS { // θ step let c: [u64; 5] = array::from_fn(|x| { - get_lane(lanes, x, 0) - ^ get_lane(lanes, x, 1) - ^ get_lane(lanes, x, 2) - ^ get_lane(lanes, x, 3) - ^ get_lane(lanes, x, 4) + get_lane2(input, x, 0) + ^ get_lane2(input, x, 1) + ^ get_lane2(input, x, 2) + ^ get_lane2(input, x, 3) + ^ get_lane2(input, x, 4) }); let mut d: u64; for x in 0..5 { d = c[(x + 4) % 5] ^ rol64(c[(x + 1) % 5], 1); for y in 0..5 { - xor_lane(d, lanes, x, y); + xor_lane2(d, input, x, y); } } // ρ and π steps let (mut x, mut y) = (1, 0); - let mut current = get_lane(lanes, x, y); + let mut current = get_lane2(input, x, y); let mut temp: u64; for t in 0..24 { @@ -106,8 +115,8 @@ fn keccak_permute(input: &mut [u8; TOTAL_STATE_SIZE]) { x = y; y = y2; - temp = get_lane(lanes, x, y); - set_lane(rol64(current, r), x, y, lanes); + temp = get_lane2(input, x, y); + set_lane2(rol64(current, r), x, y, input); current = temp; } @@ -115,14 +124,14 @@ fn keccak_permute(input: &mut [u8; TOTAL_STATE_SIZE]) { let mut temp2 = [0_u64; 5]; for y in 0..5 { for x in 0..5 { - temp2[x] = get_lane(lanes, x, y); + temp2[x] = get_lane2(input, x, y); } for x in 0..5 { - set_lane( + set_lane2( temp2[x] ^ ((!temp2[(x + 1) % 5]) & temp2[(x + 2) % 5]), x, y, - lanes, + input, ); } } @@ -131,8 +140,14 @@ fn keccak_permute(input: &mut [u8; TOTAL_STATE_SIZE]) { for j in 0..7 { let bit_pos: usize = (1 << j) - 1; - if lfsr86540(&mut lfsr_state) { - xor_lane((1 as u64) << bit_pos, lanes, 0, 0); + let (lfsr_out, new_lfsr) = LFSR_LUT[lfsr_state as usize]; + lfsr_state = new_lfsr; + // if lfsr86540(&mut lfsr_state) { + // xor_lane((1 as u64) << bit_pos, lanes, 0, 0); + // } + + if lfsr_out { + xor_lane2((1 as u64) << bit_pos, input, 0, 0); } } } @@ -143,11 +158,22 @@ fn get_lane(lanes: &[[u8; 8]], x: usize, y: usize) -> u64 { u64::from_ne_bytes(lanes[x + 5 * y]) } +#[inline] +fn get_lane2(lanes: &[64; TOTAL_STATE_SIZE], x: usize, y: usize) -> u64 { + u64::from_ne_bytes(lanes[x + 5 * y..x + 5 * y + 8].try_into().unwrap()) +} + #[inline] fn set_lane(lane: u64, x: usize, y: usize, lanes: &mut [[u8; 8]]) { lanes[x + 5 * y] = lane.to_ne_bytes(); } +#[inline] +fn set_lane2(lane: u64, x: usize, y: usize, lanes: &mut [u8; TOTAL_STATE_SIZE]) { + // lanes[x + 5 * y] = lane.to_ne_bytes(); + lanes[x + 5 * y..x + 5 * y + 8].copy_from_slice(&lane.to_ne_bytes()); +} + #[inline] fn rol64(v: u64, off: usize) -> u64 { ((v) << off) ^ ((v) >> (64 - off)) @@ -157,15 +183,20 @@ fn rol64(v: u64, off: usize) -> u64 { fn xor_lane(lane: u64, lanes: &mut [[u8; 8]], x: usize, y: usize) { set_lane(get_lane(lanes, x, y) ^ lane, x, y, lanes); } +#[inline] +fn xor_lane2(lane: u64, lanes: &mut [u8; TOTAL_STATE_SIZE], x: usize, y: usize) { + set_lane2(get_lane2(lanes, x, y) ^ lane, x, y, lanes); +} // Function that computes the linear feedback shift register (LFSR) // I have absolutely no idea wtf is this shit. Copied from a github repo lol. -fn lfsr86540(lfsr: &mut u8) -> bool { - let res = (*lfsr & 0x01) != 0; - if (*lfsr & 0x80) != 0 { - *lfsr = (*lfsr << 1) ^ 0x71; - } else { - *lfsr <<= 1; - } - res -} +// SUSCEPTIBLE TO BE CONVERTED INTO A TABLE +// fn lfsr86540(lfsr: &mut u8) -> bool { +// let res = (*lfsr & 0x01) != 0; +// if (*lfsr & 0x80) != 0 { +// *lfsr = (*lfsr << 1) ^ 0x71; +// } else { +// *lfsr <<= 1; +// } +// res +// }