diff --git a/hashers/src/balloon.rs b/hashers/src/balloon.rs index 4e989dc6..367969ce 100644 --- a/hashers/src/balloon.rs +++ b/hashers/src/balloon.rs @@ -1,6 +1,8 @@ // https://eprint.iacr.org/2016/027.pdf -use std::ops::Range; +use std::{mem, ops::Range}; + +use num::{BigUint, FromPrimitive}; use crate::{ sha::{Sha2_256, Sha2_512}, @@ -40,14 +42,6 @@ impl Balloon { const BLOCKSIZE: usize = 32; // for SHA256 const DELTA: u64 = 3; - fn extract_block(n: usize, blocks: &[u8]) -> &[u8] { - &blocks[n * Self::BLOCKSIZE..][..Self::BLOCKSIZE] - } - - fn extract_block_mut(n: usize, blocks: &mut [u8]) -> &mut [u8] { - &mut blocks[n * Self::BLOCKSIZE..][..Self::BLOCKSIZE] - } - fn extract_range(n: usize) -> Range { (n * Self::BLOCKSIZE)..(n * Self::BLOCKSIZE + Self::BLOCKSIZE) } @@ -73,6 +67,7 @@ impl StatefulHasher for Balloon { } fn finalize(self) -> Vec { + let m_cost_big_int = BigUint::from_u64(self.m_cost).unwrap(); let mut ctr: u64 = 0; let mut blocks: Vec = Vec::with_capacity(self.total_memory()); // Step 1. Expand input into buffer @@ -86,7 +81,7 @@ impl StatefulHasher for Balloon { for i in 1..self.m_cost as usize { h.update(&ctr.to_le_bytes()); ctr += 1; - h.update(&Self::extract_block(i, &blocks)); + h.update(&blocks[Self::extract_range(i)]); blocks.extend(h.finalize_and_reset()); } @@ -116,8 +111,12 @@ impl StatefulHasher for Balloon { ctr += 1; h.update(&self.salt); h.update(&idx_block); - let other = h.finalize_and_reset(); // convert to an integer - let other: usize = todo!(); + let other = BigUint::from_bytes_le(&h.finalize_and_reset()) % &m_cost_big_int; // convert to an integer + let other = usize::from_le_bytes( + other.to_bytes_le()[..mem::size_of::()] + .try_into() + .unwrap(), + ); h.update(&ctr.to_le_bytes()); ctr += 1; diff --git a/hashers/src/belt.rs b/hashers/src/belt.rs index 1344b7c8..26f6c98a 100644 --- a/hashers/src/belt.rs +++ b/hashers/src/belt.rs @@ -1,43 +1,9 @@ -use crate::traits::ClassicHasher; -use utils::byte_formatting::ByteFormat; - -pub struct BeltHash { - pub input_format: ByteFormat, - pub output_format: ByteFormat, -} +pub struct BeltHash {} impl Default for BeltHash { fn default() -> Self { - Self { - input_format: ByteFormat::Utf8, - output_format: ByteFormat::Hex, - } - } -} - -impl BeltHash { - pub fn input(mut self, input: ByteFormat) -> Self { - self.input_format = input; - self + Self {} } - - pub fn output(mut self, output: ByteFormat) -> Self { - self.output_format = output; - self - } -} - -impl ClassicHasher for BeltHash { - fn hash(&self, bytes: &[u8]) -> Vec { - todo!() - } - - crate::hash_bytes_from_string! {} } -crate::basic_hash_tests!( - test1, - BeltHash::default(), - "INPUT", - "OUTPUT"; -); +impl BeltHash {} diff --git a/hashers/src/blake/blake3.rs b/hashers/src/blake/blake3.rs index 9591e06a..71a4db08 100644 --- a/hashers/src/blake/blake3.rs +++ b/hashers/src/blake/blake3.rs @@ -1,4 +1,4 @@ -use crate::{blake_double_round, traits::ClassicHasher}; +use crate::blake_double_round; use std::cmp::min; use utils::byte_formatting::{make_u32s_le, ByteFormat}; @@ -378,90 +378,90 @@ impl Default for Blake3 { } } -impl ClassicHasher for Blake3 { - fn hash(&self, bytes: &[u8]) -> Vec { - let mut out = vec![0; self.hash_len as usize]; - let mut h = match self.mode { - Blake3Mode::Unkeyed => Blake3Hasher::new(), - Blake3Mode::Keyed => Blake3Hasher::new_keyed(&self.key), - Blake3Mode::KeyDerivation => Blake3Hasher::new_derive_key(&self.key_context), - }; - h.update(bytes); - h.finalize(&mut out); - out - } - - crate::hash_bytes_from_string! {} -} - -#[cfg(test)] -mod blake3_tests { - use itertools::Itertools; - - use super::*; - - // Test vectors from here - // https://github.com/BLAKE3-team/BLAKE3/blob/master/test_vectors/test_vectors.json - - #[test] - fn test_unkeyed() { - let mut hasher = Blake3::default(); - hasher.input_format = ByteFormat::Hex; - hasher.output_format = ByteFormat::Hex; - hasher.mode = Blake3Mode::Unkeyed; - - let input: Vec = (0..251).collect_vec(); - - let hashes: [&str; 5] = [ - "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262e00f03e7b69af26b7faaf09fcd333050338ddfe085b8cc869ca98b206c08243a26f5487789e8f660afe6c99ef9e0c52b92e7393024a80459cf91f476f9ffdbda7001c22e159b402631f277ca96f2defdf1078282314e763699a31c5363165421cce14d", - "2d3adedff11b61f14c886e35afa036736dcd87a74d27b5c1510225d0f592e213c3a6cb8bf623e20cdb535f8d1a5ffb86342d9c0b64aca3bce1d31f60adfa137b358ad4d79f97b47c3d5e79f179df87a3b9776ef8325f8329886ba42f07fb138bb502f4081cbcec3195c5871e6c23e2cc97d3c69a613eba131e5f1351f3f1da786545e5", - "d81293fda863f008c09e92fc382a81f5a0b4a1251cba1634016a0f86a6bd640de3137d477156d1fde56b0cf36f8ef18b44b2d79897bece12227539ac9ae0a5119da47644d934d26e74dc316145dcb8bb69ac3f2e05c242dd6ee06484fcb0e956dc44355b452c5e2bbb5e2b66e99f5dd443d0cbcaaafd4beebaed24ae2f8bb672bcef78", - "10108970eeda3eb932baac1428c7a2163b0e924c9a9e25b35bba72b28f70bd11a182d27a591b05592b15607500e1e8dd56bc6c7fc063715b7a1d737df5bad3339c56778957d870eb9717b57ea3d9fb68d1b55127bba6a906a4a24bbd5acb2d123a37b28f9e9a81bbaae360d58f85e5fc9d75f7c370a0cc09b6522d9c8d822f2f28f485", - "b98cb0ff3623be03326b373de6b9095218513e64f1ee2edd2525c7ad1e5cffd29a3f6b0b978d6608335c09dc94ccf682f9951cdfc501bfe47b9c9189a6fc7b404d120258506341a6d802857322fbd20d3e5dae05b95c88793fa83db1cb08e7d8008d1599b6209d78336e24839724c191b2a52a80448306e0daa84a3fdb566661a37e11", - ]; - - for (length, hash) in [0, 1, 127, 1023, 3072].into_iter().zip(hashes.into_iter()) { - let input_string = - ByteFormat::Hex.byte_iter_to_text(input.iter().cloned().cycle().take(length)); - assert_eq!( - hash[0..64], - hasher.hash_bytes_from_string(&input_string).unwrap(), - "failed on input length {}", - length - ); - } - } - - #[test] - fn test_keyed() { - let mut hasher = Blake3::default(); - hasher.input_format = ByteFormat::Hex; - hasher.output_format = ByteFormat::Hex; - hasher.mode = Blake3Mode::Keyed; - hasher.key = "whats the Elvish word for friend" - .as_bytes() - .try_into() - .unwrap(); - - let input: Vec = (0..251).collect_vec(); - - let hashes = [ - "92b2b75604ed3c761f9d6f62392c8a9227ad0ea3f09573e783f1498a4ed60d26b18171a2f22a4b94822c701f107153dba24918c4bae4d2945c20ece13387627d3b73cbf97b797d5e59948c7ef788f54372df45e45e4293c7dc18c1d41144a9758be58960856be1eabbe22c2653190de560ca3b2ac4aa692a9210694254c371e851bc8f", - "6d7878dfff2f485635d39013278ae14f1454b8c0a3a2d34bc1ab38228a80c95b6568c0490609413006fbd428eb3fd14e7756d90f73a4725fad147f7bf70fd61c4e0cf7074885e92b0e3f125978b4154986d4fb202a3f331a3fb6cf349a3a70e49990f98fe4289761c8602c4e6ab1138d31d3b62218078b2f3ba9a88e1d08d0dd4cea11", - "c64200ae7dfaf35577ac5a9521c47863fb71514a3bcad18819218b818de85818ee7a317aaccc1458f78d6f65f3427ec97d9c0adb0d6dacd4471374b621b7b5f35cd54663c64dbe0b9e2d95632f84c611313ea5bd90b71ce97b3cf645776f3adc11e27d135cbadb9875c2bf8d3ae6b02f8a0206aba0c35bfe42574011931c9a255ce6dc", - "c951ecdf03288d0fcc96ee3413563d8a6d3589547f2c2fb36d9786470f1b9d6e890316d2e6d8b8c25b0a5b2180f94fb1a158ef508c3cde45e2966bd796a696d3e13efd86259d756387d9becf5c8bf1ce2192b87025152907b6d8cc33d17826d8b7b9bc97e38c3c85108ef09f013e01c229c20a83d9e8efac5b37470da28575fd755a10", - "044a0e7b172a312dc02a4c9a818c036ffa2776368d7f528268d2e6b5df19177022f302d0529e4174cc507c463671217975e81dab02b8fdeb0d7ccc7568dd22574c783a76be215441b32e91b9a904be8ea81f7a0afd14bad8ee7c8efc305ace5d3dd61b996febe8da4f56ca0919359a7533216e2999fc87ff7d8f176fbecb3d6f34278b", - ]; - - for (length, hash) in [0, 1, 127, 1023, 3072].into_iter().zip(hashes.into_iter()) { - let input_string = - ByteFormat::Hex.byte_iter_to_text(input.iter().cloned().cycle().take(length)); - assert_eq!( - hash[0..64], - hasher.hash_bytes_from_string(&input_string).unwrap(), - "failed on input length {}", - length - ); - } - } -} +// impl ClassicHasher for Blake3 { +// fn hash(&self, bytes: &[u8]) -> Vec { +// let mut out = vec![0; self.hash_len as usize]; +// let mut h = match self.mode { +// Blake3Mode::Unkeyed => Blake3Hasher::new(), +// Blake3Mode::Keyed => Blake3Hasher::new_keyed(&self.key), +// Blake3Mode::KeyDerivation => Blake3Hasher::new_derive_key(&self.key_context), +// }; +// h.update(bytes); +// h.finalize(&mut out); +// out +// } + +// crate::hash_bytes_from_string! {} +// } + +// #[cfg(test)] +// mod blake3_tests { +// use itertools::Itertools; + +// use super::*; + +// // Test vectors from here +// // https://github.com/BLAKE3-team/BLAKE3/blob/master/test_vectors/test_vectors.json + +// #[test] +// fn test_unkeyed() { +// let mut hasher = Blake3::default(); +// hasher.input_format = ByteFormat::Hex; +// hasher.output_format = ByteFormat::Hex; +// hasher.mode = Blake3Mode::Unkeyed; + +// let input: Vec = (0..251).collect_vec(); + +// let hashes: [&str; 5] = [ +// "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262e00f03e7b69af26b7faaf09fcd333050338ddfe085b8cc869ca98b206c08243a26f5487789e8f660afe6c99ef9e0c52b92e7393024a80459cf91f476f9ffdbda7001c22e159b402631f277ca96f2defdf1078282314e763699a31c5363165421cce14d", +// "2d3adedff11b61f14c886e35afa036736dcd87a74d27b5c1510225d0f592e213c3a6cb8bf623e20cdb535f8d1a5ffb86342d9c0b64aca3bce1d31f60adfa137b358ad4d79f97b47c3d5e79f179df87a3b9776ef8325f8329886ba42f07fb138bb502f4081cbcec3195c5871e6c23e2cc97d3c69a613eba131e5f1351f3f1da786545e5", +// "d81293fda863f008c09e92fc382a81f5a0b4a1251cba1634016a0f86a6bd640de3137d477156d1fde56b0cf36f8ef18b44b2d79897bece12227539ac9ae0a5119da47644d934d26e74dc316145dcb8bb69ac3f2e05c242dd6ee06484fcb0e956dc44355b452c5e2bbb5e2b66e99f5dd443d0cbcaaafd4beebaed24ae2f8bb672bcef78", +// "10108970eeda3eb932baac1428c7a2163b0e924c9a9e25b35bba72b28f70bd11a182d27a591b05592b15607500e1e8dd56bc6c7fc063715b7a1d737df5bad3339c56778957d870eb9717b57ea3d9fb68d1b55127bba6a906a4a24bbd5acb2d123a37b28f9e9a81bbaae360d58f85e5fc9d75f7c370a0cc09b6522d9c8d822f2f28f485", +// "b98cb0ff3623be03326b373de6b9095218513e64f1ee2edd2525c7ad1e5cffd29a3f6b0b978d6608335c09dc94ccf682f9951cdfc501bfe47b9c9189a6fc7b404d120258506341a6d802857322fbd20d3e5dae05b95c88793fa83db1cb08e7d8008d1599b6209d78336e24839724c191b2a52a80448306e0daa84a3fdb566661a37e11", +// ]; + +// for (length, hash) in [0, 1, 127, 1023, 3072].into_iter().zip(hashes.into_iter()) { +// let input_string = +// ByteFormat::Hex.byte_iter_to_text(input.iter().cloned().cycle().take(length)); +// assert_eq!( +// hash[0..64], +// hasher.hash_bytes_from_string(&input_string).unwrap(), +// "failed on input length {}", +// length +// ); +// } +// } + +// #[test] +// fn test_keyed() { +// let mut hasher = Blake3::default(); +// hasher.input_format = ByteFormat::Hex; +// hasher.output_format = ByteFormat::Hex; +// hasher.mode = Blake3Mode::Keyed; +// hasher.key = "whats the Elvish word for friend" +// .as_bytes() +// .try_into() +// .unwrap(); + +// let input: Vec = (0..251).collect_vec(); + +// let hashes = [ +// "92b2b75604ed3c761f9d6f62392c8a9227ad0ea3f09573e783f1498a4ed60d26b18171a2f22a4b94822c701f107153dba24918c4bae4d2945c20ece13387627d3b73cbf97b797d5e59948c7ef788f54372df45e45e4293c7dc18c1d41144a9758be58960856be1eabbe22c2653190de560ca3b2ac4aa692a9210694254c371e851bc8f", +// "6d7878dfff2f485635d39013278ae14f1454b8c0a3a2d34bc1ab38228a80c95b6568c0490609413006fbd428eb3fd14e7756d90f73a4725fad147f7bf70fd61c4e0cf7074885e92b0e3f125978b4154986d4fb202a3f331a3fb6cf349a3a70e49990f98fe4289761c8602c4e6ab1138d31d3b62218078b2f3ba9a88e1d08d0dd4cea11", +// "c64200ae7dfaf35577ac5a9521c47863fb71514a3bcad18819218b818de85818ee7a317aaccc1458f78d6f65f3427ec97d9c0adb0d6dacd4471374b621b7b5f35cd54663c64dbe0b9e2d95632f84c611313ea5bd90b71ce97b3cf645776f3adc11e27d135cbadb9875c2bf8d3ae6b02f8a0206aba0c35bfe42574011931c9a255ce6dc", +// "c951ecdf03288d0fcc96ee3413563d8a6d3589547f2c2fb36d9786470f1b9d6e890316d2e6d8b8c25b0a5b2180f94fb1a158ef508c3cde45e2966bd796a696d3e13efd86259d756387d9becf5c8bf1ce2192b87025152907b6d8cc33d17826d8b7b9bc97e38c3c85108ef09f013e01c229c20a83d9e8efac5b37470da28575fd755a10", +// "044a0e7b172a312dc02a4c9a818c036ffa2776368d7f528268d2e6b5df19177022f302d0529e4174cc507c463671217975e81dab02b8fdeb0d7ccc7568dd22574c783a76be215441b32e91b9a904be8ea81f7a0afd14bad8ee7c8efc305ace5d3dd61b996febe8da4f56ca0919359a7533216e2999fc87ff7d8f176fbecb3d6f34278b", +// ]; + +// for (length, hash) in [0, 1, 127, 1023, 3072].into_iter().zip(hashes.into_iter()) { +// let input_string = +// ByteFormat::Hex.byte_iter_to_text(input.iter().cloned().cycle().take(length)); +// assert_eq!( +// hash[0..64], +// hasher.hash_bytes_from_string(&input_string).unwrap(), +// "failed on input length {}", +// length +// ); +// } +// } +// } diff --git a/hashers/src/checksum/bsd.rs b/hashers/src/checksum/bsd.rs index 1a0e9f1a..d072b56f 100644 --- a/hashers/src/checksum/bsd.rs +++ b/hashers/src/checksum/bsd.rs @@ -1,44 +1,22 @@ -use utils::byte_formatting::ByteFormat; - -use crate::traits::ClassicHasher; - -pub struct BsdChecksum { - pub input_format: ByteFormat, - pub output_format: ByteFormat, -} +pub struct BsdChecksum {} impl Default for BsdChecksum { fn default() -> Self { - Self { - input_format: ByteFormat::Hex, - output_format: ByteFormat::Hex, - } + Self {} } } impl BsdChecksum {} -impl ClassicHasher for BsdChecksum { - fn hash(&self, bytes: &[u8]) -> Vec { - let mut out = 0_u16; - for byte in bytes { - out = out.rotate_right(1); - out = out.wrapping_add(*byte as u16); - } - out.to_le_bytes().to_vec() - } - - crate::hash_bytes_from_string! {} -} - -#[cfg(test)] -mod bsd_tests { - use super::*; - - #[test] - fn test() { - let mut hasher = BsdChecksum::default(); - hasher.input_format = ByteFormat::Hex; - hasher.output_format = ByteFormat::Hex; - } -} +// impl ClassicHasher for BsdChecksum { +// fn hash(&self, bytes: &[u8]) -> Vec { +// let mut out = 0_u16; +// for byte in bytes { +// out = out.rotate_right(1); +// out = out.wrapping_add(*byte as u16); +// } +// out.to_le_bytes().to_vec() +// } + +// crate::hash_bytes_from_string! {} +// } diff --git a/hashers/src/checksum/crc.rs b/hashers/src/checksum/crc.rs index 064460eb..f3b9fb9b 100644 --- a/hashers/src/checksum/crc.rs +++ b/hashers/src/checksum/crc.rs @@ -1,10 +1,9 @@ -use crate::{errors::HasherError, traits::ClassicHasher}; +use crate::errors::HasherError; use num::Zero; use utils::{ bit_polynomial::BitPolynomial, bits::{bit_string, Bit}, - byte_formatting::ByteFormat, }; pub enum CrcAlgorithm { @@ -34,16 +33,12 @@ impl CrcAlgorithm { // https://www.ghsi.de/pages/subpages/Online%20CRC%20Calculation/indexDetails.php?Polynom=111011011011100010000011001000001&Message=E100CAFE pub struct CyclicRedundancyCheckHash { - pub input_format: ByteFormat, - pub output_format: ByteFormat, pub mode: CrcAlgorithm, } impl Default for CyclicRedundancyCheckHash { fn default() -> Self { Self { - input_format: ByteFormat::Hex, - output_format: ByteFormat::Hex, mode: CrcAlgorithm::Crc32, } } @@ -51,69 +46,69 @@ impl Default for CyclicRedundancyCheckHash { impl CyclicRedundancyCheckHash {} -impl ClassicHasher for CyclicRedundancyCheckHash { - fn hash(&self, bytes: &[u8]) -> Vec { - // Convert the bytes to a vector of Bits and treat it as a polynomial - let data = BitPolynomial::from_bytes(bytes).coef; - let mut state = vec![Bit::zero(); 32]; - - println!("data: {:?}", bit_string(&data)); - - println!("init: {:?}", bit_string(&state)); - for data_bit in data { - let inv = data_bit ^ state[31]; - state[31] = state[30] ^ inv; - state[30] = state[29] ^ inv; - state[29] = state[28]; - state[28] = state[27] ^ inv; - state[27] = state[26] ^ inv; - state[26] = state[25]; - state[25] = state[24] ^ inv; - state[24] = state[23] ^ inv; - state[23] = state[22]; - state[22] = state[21] ^ inv; - state[21] = state[20] ^ inv; - state[20] = state[19] ^ inv; - state[19] = state[18]; - state[18] = state[17]; - state[17] = state[16]; - state[16] = state[15] ^ inv; - state[15] = state[14]; - state[14] = state[13]; - state[13] = state[12]; - state[12] = state[11]; - state[11] = state[10]; - state[10] = state[09] ^ inv; - state[09] = state[08] ^ inv; - state[08] = state[07]; - state[07] = state[06]; - state[06] = state[05] ^ inv; - state[05] = state[04]; - state[04] = state[03]; - state[03] = state[02]; - state[02] = state[01]; - state[01] = state[00]; - state[00] ^= inv; - println!("{data_bit} {:?}", bit_string(&state)); - } - - // let s: String = r.bit_string().chars().rev().collect(); - // println!("{s}"); - - // Convert the CRC syndrome into bytes for output - // ByteFormat::Bit.text_to_bytes(&r.bit_string()).unwrap() - todo!() - } - - fn hash_bytes_from_string(&self, text: &str) -> Result { - let mut bytes = self - .input_format - .text_to_bytes(text) - .map_err(|_| HasherError::general("byte format error"))?; - let out = self.hash(&mut bytes); - Ok(self.output_format.byte_slice_to_text(&out)) - } -} +// impl ClassicHasher for CyclicRedundancyCheckHash { +// fn hash(&self, bytes: &[u8]) -> Vec { +// // Convert the bytes to a vector of Bits and treat it as a polynomial +// let data = BitPolynomial::from_bytes(bytes).coef; +// let mut state = vec![Bit::zero(); 32]; + +// println!("data: {:?}", bit_string(&data)); + +// println!("init: {:?}", bit_string(&state)); +// for data_bit in data { +// let inv = data_bit ^ state[31]; +// state[31] = state[30] ^ inv; +// state[30] = state[29] ^ inv; +// state[29] = state[28]; +// state[28] = state[27] ^ inv; +// state[27] = state[26] ^ inv; +// state[26] = state[25]; +// state[25] = state[24] ^ inv; +// state[24] = state[23] ^ inv; +// state[23] = state[22]; +// state[22] = state[21] ^ inv; +// state[21] = state[20] ^ inv; +// state[20] = state[19] ^ inv; +// state[19] = state[18]; +// state[18] = state[17]; +// state[17] = state[16]; +// state[16] = state[15] ^ inv; +// state[15] = state[14]; +// state[14] = state[13]; +// state[13] = state[12]; +// state[12] = state[11]; +// state[11] = state[10]; +// state[10] = state[09] ^ inv; +// state[09] = state[08] ^ inv; +// state[08] = state[07]; +// state[07] = state[06]; +// state[06] = state[05] ^ inv; +// state[05] = state[04]; +// state[04] = state[03]; +// state[03] = state[02]; +// state[02] = state[01]; +// state[01] = state[00]; +// state[00] ^= inv; +// println!("{data_bit} {:?}", bit_string(&state)); +// } + +// // let s: String = r.bit_string().chars().rev().collect(); +// // println!("{s}"); + +// // Convert the CRC syndrome into bytes for output +// // ByteFormat::Bit.text_to_bytes(&r.bit_string()).unwrap() +// todo!() +// } + +// fn hash_bytes_from_string(&self, text: &str) -> Result { +// let mut bytes = self +// .input_format +// .text_to_bytes(text) +// .map_err(|_| HasherError::general("byte format error"))?; +// let out = self.hash(&mut bytes); +// Ok(self.output_format.byte_slice_to_text(&out)) +// } +// } #[cfg(test)] mod crc_hasher_tests { @@ -135,14 +130,14 @@ mod crc_hasher_tests { // } // } - #[test] - fn test() { - let hasher = CyclicRedundancyCheckHash::default(); - - hasher.hash_bytes_from_string("E100CAFE").unwrap(); - // assert_eq!( - // "ef1a85f0", - // hasher.hash_bytes_from_string("E100CAFE").unwrap() - // ); - } + // #[test] + // fn test() { + // let hasher = CyclicRedundancyCheckHash::default(); + + // hasher.hash_bytes_from_string("E100CAFE").unwrap(); + // assert_eq!( + // "ef1a85f0", + // hasher.hash_bytes_from_string("E100CAFE").unwrap() + // ); + // } } diff --git a/hashers/src/crypt.rs b/hashers/src/crypt.rs index 8d2c2bbb..55fa4cb1 100644 --- a/hashers/src/crypt.rs +++ b/hashers/src/crypt.rs @@ -1,65 +1,44 @@ -use crate::{auxiliary::des_functions::Des, traits::ClassicHasher}; +use crate::auxiliary::des_functions::Des; use utils::byte_formatting::ByteFormat; pub struct CryptDes { - pub input_format: ByteFormat, - pub output_format: ByteFormat, pub salt: [bool; 12], // only 12 bits used } impl Default for CryptDes { fn default() -> Self { - Self { - input_format: ByteFormat::Utf8, - output_format: ByteFormat::Hex, - salt: [false; 12], - } + Self { salt: [false; 12] } } } -impl CryptDes { - pub fn input(mut self, input: ByteFormat) -> Self { - self.input_format = input; - self - } - - pub fn output(mut self, output: ByteFormat) -> Self { - self.output_format = output; - self - } - - pub fn salt(mut self, salt: [bool; 12]) -> Self { - self.salt = salt; - self - } -} - -impl ClassicHasher for CryptDes { - fn hash(&self, bytes: &[u8]) -> Vec { - // Load the bytes of the key into a u64 - let mut key: u64 = 0; - for i in 0..8 { - key = key << 8; - if let Some(byte) = bytes.get(i) { - key |= *byte as u64 - } - } - - // Setup DES - let mut cipher = Des::default(); - cipher.ksa(key); - - // Encrypt the block 25 times using the salted block function - let mut block = 0; - for _ in 0..25 { - block = cipher.encrypt_block_salt(block, self.salt); - } - - block.to_be_bytes().to_vec() - } - - crate::hash_bytes_from_string! {} -} +impl CryptDes {} + +// impl ClassicHasher for CryptDes { +// fn hash(&self, bytes: &[u8]) -> Vec { +// // Load the bytes of the key into a u64 +// let mut key: u64 = 0; +// for i in 0..8 { +// key = key << 8; +// if let Some(byte) = bytes.get(i) { +// key |= *byte as u64 +// } +// } + +// // Setup DES +// let mut cipher = Des::default(); +// cipher.ksa(key); + +// // Encrypt the block 25 times using the salted block function +// let mut block = 0; +// for _ in 0..25 { +// block = cipher.encrypt_block_salt(block, self.salt); +// } + +// block.to_be_bytes().to_vec() +// } + +// crate::hash_bytes_from_string! {} +// } // crate::basic_hash_tests!( // test1, diff --git a/hashers/src/gost.rs b/hashers/src/gost.rs index a500af62..116e305c 100644 --- a/hashers/src/gost.rs +++ b/hashers/src/gost.rs @@ -1,6 +1,5 @@ -use crate::traits::ClassicHasher; use utils::byte_formatting::{fill_u32s_be, u32s_to_bytes_be, xor_into_bytes}; -use utils::{byte_formatting::ByteFormat, padding::zero_padding}; +use utils::padding::zero_padding; pub const GOST_R_34_12_2015: [u64; 8] = [ 0xc462a5b9e8d703f1, @@ -36,8 +35,6 @@ pub const GOST_R_TEST: [u64; 8] = [ ]; pub struct GostCipher { - pub input_format: ByteFormat, - pub output_format: ByteFormat, pub sboxes: [u64; 8], pub subkeys: [u32; 8], } @@ -45,8 +42,6 @@ pub struct GostCipher { impl Default for GostCipher { fn default() -> Self { Self { - input_format: ByteFormat::Hex, - output_format: ByteFormat::Hex, sboxes: GOST_R_34_12_2015.clone(), subkeys: [0; 8], } @@ -201,67 +196,63 @@ fn compress(h: [u8; 32], m: [u8; 32], cipher: &mut GostCipher) -> [u8; 32] { #[derive(Debug, Clone)] pub struct Gost { - pub input_format: ByteFormat, - pub output_format: ByteFormat, - pub iv: [u8; 32], - pub sboxes: [u64; 8], + iv: [u8; 32], + sboxes: [u64; 8], } impl Default for Gost { fn default() -> Self { Self { - input_format: ByteFormat::Utf8, - output_format: ByteFormat::Hex, iv: [0; 32], sboxes: GOST_R_34_12_2015.clone(), } } } -impl ClassicHasher for Gost { - fn hash(&self, bytes: &[u8]) -> Vec { - let mut input = bytes.to_vec(); - - // Final block is padded with zeroes - zero_padding(&mut input, 32); - - let mut h = self.iv; - let mut ctrl = [0; 32]; - - let mut cipher = GostCipher::default().with_sboxes(self.sboxes); - - // Take input in 256-bit blocks - for block in input.chunks_exact(32) { - for i in 0..32 { - ctrl[i] ^= block[i] - } - h = compress(h, block.try_into().unwrap(), &mut cipher) - } - - // Compress in the length of the input - let mut l = [0; 32]; - for (i, b) in ((bytes.len() * 8) as u64).to_be_bytes().iter().enumerate() { - l[i + 23] = *b - } - h = compress(h, l, &mut cipher); - - // Compress in the check value - compress(h, ctrl, &mut cipher).to_vec() - } - - crate::hash_bytes_from_string! {} -} - -crate::basic_hash_tests!( - test1, Gost::default(), - "The quick brown fox jumps over the lazy dog", - "77b7fa410c9ac58a25f49bca7d0468c9296529315eaca76bd1a10f376d1f4294"; - - test2, Gost::default(), - "This is message, length=32 bytes", - "b1c466d37519b82e8319819ff32595e047a28cb6f83eff1c6916a815a637fffa"; - - test3, Gost::default(), - "Suppose the original message has length = 50 bytes", - "471aba57a60a770d3a76130635c1fbea4ef14de51f78b4ae57dd893b62f55208"; -); +// impl ClassicHasher for Gost { +// fn hash(&self, bytes: &[u8]) -> Vec { +// let mut input = bytes.to_vec(); + +// // Final block is padded with zeroes +// zero_padding(&mut input, 32); + +// let mut h = self.iv; +// let mut ctrl = [0; 32]; + +// let mut cipher = GostCipher::default().with_sboxes(self.sboxes); + +// // Take input in 256-bit blocks +// for block in input.chunks_exact(32) { +// for i in 0..32 { +// ctrl[i] ^= block[i] +// } +// h = compress(h, block.try_into().unwrap(), &mut cipher) +// } + +// // Compress in the length of the input +// let mut l = [0; 32]; +// for (i, b) in ((bytes.len() * 8) as u64).to_be_bytes().iter().enumerate() { +// l[i + 23] = *b +// } +// h = compress(h, l, &mut cipher); + +// // Compress in the check value +// compress(h, ctrl, &mut cipher).to_vec() +// } + +// crate::hash_bytes_from_string! {} +// } + +// crate::basic_hash_tests!( +// test1, Gost::default(), +// "The quick brown fox jumps over the lazy dog", +// "77b7fa410c9ac58a25f49bca7d0468c9296529315eaca76bd1a10f376d1f4294"; + +// test2, Gost::default(), +// "This is message, length=32 bytes", +// "b1c466d37519b82e8319819ff32595e047a28cb6f83eff1c6916a815a637fffa"; + +// test3, Gost::default(), +// "Suppose the original message has length = 50 bytes", +// "471aba57a60a770d3a76130635c1fbea4ef14de51f78b4ae57dd893b62f55208"; +// ); diff --git a/hashers/src/haval.rs b/hashers/src/haval.rs index cef0ca2d..93c90911 100644 --- a/hashers/src/haval.rs +++ b/hashers/src/haval.rs @@ -1,43 +1,29 @@ +use super::auxiliary::haval_arrays::D; use crate::{ auxiliary::haval_functions::{ finalize_128, finalize_160, finalize_192, finalize_224, finalize_256, h1, h2, h3, h4, h5, haval_padding, }, - traits::ClassicHasher, + traits::StatefulHasher, }; -use super::auxiliary::haval_arrays::D; -use utils::byte_formatting::ByteFormat; - pub struct Haval { - pub input_format: ByteFormat, - pub output_format: ByteFormat, - pub rounds: u32, - pub hash_len: u32, + rounds: u32, + hash_len: u32, + buffer: Vec, } impl Default for Haval { fn default() -> Self { Self { - input_format: ByteFormat::Utf8, - output_format: ByteFormat::Hex, rounds: 5, hash_len: 32, + buffer: Vec::new(), } } } impl Haval { - pub fn input(mut self, input: ByteFormat) -> Self { - self.input_format = input; - self - } - - pub fn output(mut self, output: ByteFormat) -> Self { - self.output_format = output; - self - } - pub fn rounds(mut self, rounds: u32) -> Self { assert!( rounds == 3 || rounds == 4 || rounds == 5, @@ -76,8 +62,12 @@ impl Haval { } } -impl ClassicHasher for Haval { - fn hash(&self, bytes: &[u8]) -> Vec { +impl StatefulHasher for Haval { + fn update(&mut self, bytes: &[u8]) { + todo!() + } + + fn finalize(mut self) -> Vec { assert!( self.rounds == 3 || self.rounds == 4 || self.rounds == 5, "rounds must be 3, 4, or 5" @@ -87,12 +77,11 @@ impl ClassicHasher for Haval { "output length is in bytes and must be 16, 20, 24, 28, or 32" ); - let mut input = bytes.to_vec(); - haval_padding(&mut input, self.hash_len as u8, self.rounds as u8); + haval_padding(&mut self.buffer, self.hash_len as u8, self.rounds as u8); let mut state = D; - for block in input.chunks_exact(128) { + for block in self.buffer.chunks_exact(128) { let mut x = [0u32; 32]; for (elem, chunk) in x.iter_mut().zip(block.chunks_exact(4)) { *elem = u32::from_le_bytes(chunk.try_into().unwrap()); @@ -114,29 +103,28 @@ impl ClassicHasher for Haval { unreachable!("output length is in bytes and must be 16, 20, 24, 28, or 32") } } - - crate::hash_bytes_from_string! {} + crate::stateful_hash_helpers!(); } -#[cfg(test)] -mod haval_tests { - use super::*; - - #[test] - fn test_haval_256_5() { - let hasher = Haval::default().rounds(5).hash_len(32); - assert_eq!( - "be417bb4dd5cfb76c7126f4f8eeb1553a449039307b1a3cd451dbfdc0fbbe330", - hasher.hash_bytes_from_string("").unwrap() - ); - } - - #[test] - fn test_haval_128_3() { - let hasher = Haval::default().rounds(3).hash_len(16); - assert_eq!( - "c68f39913f901f3ddf44c707357a7d70", - hasher.hash_bytes_from_string("").unwrap() - ); - } -} +// #[cfg(test)] +// mod haval_tests { +// use super::*; + +// #[test] +// fn test_haval_256_5() { +// let hasher = Haval::default().rounds(5).hash_len(32); +// assert_eq!( +// "be417bb4dd5cfb76c7126f4f8eeb1553a449039307b1a3cd451dbfdc0fbbe330", +// hasher.hash_bytes_from_string("").unwrap() +// ); +// } + +// #[test] +// fn test_haval_128_3() { +// let hasher = Haval::default().rounds(3).hash_len(16); +// assert_eq!( +// "c68f39913f901f3ddf44c707357a7d70", +// hasher.hash_bytes_from_string("").unwrap() +// ); +// } +// } diff --git a/hashers/src/md6.rs b/hashers/src/md6.rs index f3a435b3..be5afe30 100644 --- a/hashers/src/md6.rs +++ b/hashers/src/md6.rs @@ -1,6 +1,6 @@ use std::collections::VecDeque; -use crate::traits::{ClassicHasher, StatefulHasher}; +use crate::traits::StatefulHasher; use utils::padding::zero_padding; /// 960 bits of √6 diff --git a/hashers/src/skein.rs b/hashers/src/skein.rs index 43352a36..4020659b 100644 --- a/hashers/src/skein.rs +++ b/hashers/src/skein.rs @@ -1,7 +1,5 @@ use utils::byte_formatting::{fill_u64s_le, ByteFormat}; -use crate::traits::ClassicHasher; - macro_rules! mix { ($a: ident, $b: ident, $r: literal) => { $a = $a.wrapping_add($b); @@ -45,8 +43,6 @@ fn four_rounds( const C240: u64 = 0x1BD11BDAA9FC1A22; pub struct Skein256 { - pub input_format: ByteFormat, - pub output_format: ByteFormat, pub key: [u64; Self::WORDS], pub tweak: [u64; 2], } @@ -54,8 +50,6 @@ pub struct Skein256 { impl Default for Skein256 { fn default() -> Self { Self { - input_format: ByteFormat::Utf8, - output_format: ByteFormat::Hex, key: [0; Self::WORDS], tweak: [0; 2], } @@ -106,11 +100,3 @@ impl Skein256 { // Incorporates the tweak information for each block to make each block and each mode unique fn ubi() {} } - -impl ClassicHasher for Skein256 { - fn hash(&self, bytes: &[u8]) -> Vec { - todo!() - } - - crate::hash_bytes_from_string! {} -} diff --git a/hashers/src/traits.rs b/hashers/src/traits.rs index dd3acb63..49b25a96 100644 --- a/hashers/src/traits.rs +++ b/hashers/src/traits.rs @@ -1,9 +1,9 @@ use crate::errors::HasherError; -pub trait ClassicHasher { - fn hash(&self, bytes: &[u8]) -> Vec; - fn hash_bytes_from_string(&self, text: &str) -> Result; -} +// pub trait ClassicHasher { +// fn hash(&self, bytes: &[u8]) -> Vec; +// fn hash_bytes_from_string(&self, text: &str) -> Result; +// } pub trait StatefulHasher { // Update the hasher's state with some bytes. @@ -22,6 +22,11 @@ pub trait StatefulHasher { fn hash_multiple(self, bytes: &[&[u8]]) -> Vec; } +pub trait ResettableHasher { + // Finalize the hash with any padding and processing of final blocks then output bytes. Resets the hasher to its starting state, allowing it to be reused. + fn finalize_and_reset(&mut self, bytes: &[u8]) -> Vec; +} + #[macro_export] macro_rules! stateful_hash_helpers { () => { @@ -59,34 +64,34 @@ macro_rules! hash_bytes_from_string { }; } -#[macro_export] -macro_rules! basic_hash_tests { - ($($test_name: ident, $hasher: expr, $input: expr, $output: expr);+ $(;)?) => { - #[cfg(test)] - mod basic_tests { - use super::*; - $( - #[test] - fn $test_name() { - assert_eq!($output, $hasher.hash_bytes_from_string($input).unwrap()); - } - )+ - } - }; - // Optional variant with module name for separation - (($mod_name: ident)?; $($name: ident, $hasher: expr, $input: expr, $output: expr);+ $(;)?) => { - #[cfg(test)] - mod $mod_name { - use super::*; - $( - #[test] - fn $name() { - assert_eq!($output, $hasher.hash_bytes_from_string($input).unwrap()); - } - )+ - } - }; -} +// #[macro_export] +// macro_rules! basic_hash_tests { +// ($($test_name: ident, $hasher: expr, $input: expr, $output: expr);+ $(;)?) => { +// #[cfg(test)] +// mod basic_tests { +// use super::*; +// $( +// #[test] +// fn $test_name() { +// assert_eq!($output, $hasher.hash_bytes_from_string($input).unwrap()); +// } +// )+ +// } +// }; +// // Optional variant with module name for separation +// (($mod_name: ident)?; $($name: ident, $hasher: expr, $input: expr, $output: expr);+ $(;)?) => { +// #[cfg(test)] +// mod $mod_name { +// use super::*; +// $( +// #[test] +// fn $name() { +// assert_eq!($output, $hasher.hash_bytes_from_string($input).unwrap()); +// } +// )+ +// } +// }; +// } #[macro_export] macro_rules! stateful_hash_tests { diff --git a/hashers/src/vsh.rs b/hashers/src/vsh.rs index 475d670f..c669bc2c 100644 --- a/hashers/src/vsh.rs +++ b/hashers/src/vsh.rs @@ -1,30 +1,14 @@ use crypto_bigint::U1024; use utils::byte_formatting::ByteFormat; -use crate::traits::ClassicHasher; - pub struct Vsh { - pub input_format: ByteFormat, - pub output_format: ByteFormat, pub n: U1024, } impl Default for Vsh { fn default() -> Self { Self { - input_format: ByteFormat::Utf8, - output_format: ByteFormat::Hex, n: Default::default(), } } } - -impl ClassicHasher for Vsh { - fn hash(&self, bytes: &[u8]) -> Vec { - let mut x = U1024::ONE; - - todo!() - } - - crate::hash_bytes_from_string! {} -} diff --git a/src/hasher_panel/blake3_controls.rs b/src/hasher_panel/blake3_controls.rs index 2269090c..aa408856 100644 --- a/src/hasher_panel/blake3_controls.rs +++ b/src/hasher_panel/blake3_controls.rs @@ -5,7 +5,6 @@ use egui::Button; use hashers::{ blake::blake3::{Blake3, Blake3Mode}, errors::HasherError, - traits::ClassicHasher, }; use rand::{thread_rng, RngCore}; use utils::byte_formatting::ByteFormat; @@ -129,10 +128,6 @@ impl HasherFrame for Blake3Frame { } fn hash_string(&self, text: &str) -> Result { - if self.hasher.mode == Blake3Mode::Keyed && !self.valid_key { - Err(HasherError::key("BLAKE3 keyed hash can only be called when exactly 64 hexadecimal digits (256 bits) of key are given")) - } else { - self.hasher.hash_bytes_from_string(text) - } + todo!() } }