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 @@
+
\ 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
+// }