diff --git a/Cargo.lock b/Cargo.lock index e61f987d..5ae14c45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,12 +221,31 @@ dependencies = [ "hex-literal", ] +[[package]] +name = "multimixer-128" +version = "0.1.0" +dependencies = [ + "digest", + "hex-literal", + "rand_chacha", +] + [[package]] name = "ppv-lite86" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + [[package]] name = "rand_core" version = "0.6.4" diff --git a/Cargo.toml b/Cargo.toml index e94b026b..644cf566 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ members = [ "md2", "md4", "md5", + "multimixer-128", "ripemd", "sha1", "sha1-checked", diff --git a/multimixer-128/Cargo.toml b/multimixer-128/Cargo.toml index 6c273c28..31c131e8 100644 --- a/multimixer-128/Cargo.toml +++ b/multimixer-128/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] digest = "=0.11.0-pre.8" +rand_chacha = "0.3.1" [dev-dependencies] digest = { version = "=0.11.0-pre.8", features = ["dev"] } diff --git a/multimixer-128/benches/mod.rs b/multimixer-128/benches/mod.rs new file mode 100644 index 00000000..c0b4060b --- /dev/null +++ b/multimixer-128/benches/mod.rs @@ -0,0 +1,15 @@ +#![feature(test)] +extern crate test; + +use digest::bench_update; +use digest::crypto_common::KeyInit; +use multimixer_128::Multimixer; +use test::Bencher; +//Multimixer::from_core(MultimixerCore::dummy_bencher()); +bench_update!( + Multimixer::new(&[0u8;32].into()); + multimixer_10 10; + multimixer_100 100; + multimixer_1000 1000; + multimixer_10000 10000; +); diff --git a/multimixer-128/src/lib.rs b/multimixer-128/src/lib.rs index 607e6289..3ffbaead 100644 --- a/multimixer-128/src/lib.rs +++ b/multimixer-128/src/lib.rs @@ -12,30 +12,61 @@ use digest::{ }, HashMarker, OutputSizeUser, }; +use rand_chacha::rand_core::{RngCore, SeedableRng}; +use rand_chacha::ChaCha8Rng; const BLOCKSIZE: usize = 32; +#[derive(Clone)] pub struct MultimixerCore { key_blocks: Vec>, block_sums: [u64; 8usize], block_index: usize, + rng: Option, } pub type Multimixer = CoreWrapper; impl MultimixerCore { fn compress(&mut self, message_block: &Block) { - //self.x[0] = message_block & 0xffffff_000000_000000_000000_000000_000000_000000_000000; - let mut x: [u32; 4usize] = [0u32; 4]; - let mut h = [0u32; 4]; + //let mut h = [0u32; 4]; let mut y = [0u32; 4]; - let mut k = [0u32; 4]; + //let mut k = [0u32; 4]; let mut a = [0u32; 4]; let mut b = [0u32; 4]; let mut p = [0u32; 4]; let mut q = [0u32; 4]; + let (h, k) = if let Some(ref mut rng) = self.rng.as_mut() { + let mut h = [0u32; 4]; + let mut k = [0u32; 4]; + + for i in 0..4 { + h[i] = rng.next_u32(); + k[i] = rng.next_u32(); + } + (h, k) + } else { + let mut h = [0u32; 4]; + let mut k = [0u32; 4]; + for i in 0..4 { + h[i] = u32::from_ne_bytes([ + self.key_blocks[self.block_index][i * 4], + self.key_blocks[self.block_index][i * 4 + 1], + self.key_blocks[self.block_index][i * 4 + 2], + self.key_blocks[self.block_index][i * 4 + 3], + ]); + k[i] = u32::from_ne_bytes([ + self.key_blocks[self.block_index][i * 4 + 16], + self.key_blocks[self.block_index][i * 4 + 17], + self.key_blocks[self.block_index][i * 4 + 18], + self.key_blocks[self.block_index][i * 4 + 19], + ]); + } + (h, k) + }; + for i in 0..4 { x[i] = u32::from_ne_bytes([ message_block[0 + i * 4], @@ -49,18 +80,6 @@ impl MultimixerCore { message_block[18 + i * 4], message_block[19 + i * 4], ]); - h[i] = u32::from_ne_bytes([ - self.key_blocks[self.block_index][i * 4], - self.key_blocks[self.block_index][i * 4 + 1], - self.key_blocks[self.block_index][i * 4 + 2], - self.key_blocks[self.block_index][i * 4 + 3], - ]); - k[i] = u32::from_ne_bytes([ - self.key_blocks[self.block_index][i * 4 + 16], - self.key_blocks[self.block_index][i * 4 + 17], - self.key_blocks[self.block_index][i * 4 + 18], - self.key_blocks[self.block_index][i * 4 + 19], - ]); a[i] = x[i].wrapping_add(h[i]); b[i] = y[i].wrapping_add(k[i]); @@ -86,20 +105,16 @@ impl MultimixerCore { p[3] as u64 * q[3] as u64, ]; - // let mut block_temp = [0u64; 8usize]; - // Update blk_temp with the results from Blk_res for i in 0..self.block_sums.len() { self.block_sums[i] = self.block_sums[i].wrapping_add(block_res[i]); } - println!("block_sums: {:02x?}", self.block_sums); - println!("x: {:x?}", x); - println!("y: {:x?}", y); + self.block_index += 1; } fn finalize(&self, out: &mut digest::Output) { for (i, block) in self.block_sums.iter().enumerate() { - let bytes = block.to_le_bytes(); // Convert u64 to little-endian byte array + let bytes = block.to_ne_bytes(); // Convert u64 to little-endian byte array for (j, &byte) in bytes.iter().enumerate() { out[i * 8 + j] = byte; } @@ -109,13 +124,28 @@ impl MultimixerCore { impl KeySizeUser for MultimixerCore { type KeySize = U32; + + fn key_size() -> usize { + Self::KeySize::USIZE + } } impl KeyInit for MultimixerCore { + //Uses the key to initialize ChaCha8Rng RNG and fills the key_blocks array fn new(key: &Key) -> Self { - Self::new_from_slice(key).expect("Key has correct length") + Self { + block_sums: [0; 8], + key_blocks: Vec::new(), + block_index: 0, + rng: Some(ChaCha8Rng::from_seed( + key.as_slice() + .try_into() + .expect("Key needs to be able to use as seed."), + )), + } } + //Uses key instead of RNG, needs to be same size as message. fn new_from_slice(key: &[u8]) -> Result { let key_block_size = ::KeySize::USIZE; if key.len() % key_block_size != 0 { @@ -125,6 +155,7 @@ impl KeyInit for MultimixerCore { block_sums: [0; 8], key_blocks: Vec::new(), block_index: 0, + rng: None, }; for block in key.chunks(key_block_size) { @@ -170,15 +201,9 @@ impl UpdateCore for MultimixerCore { impl FixedOutputCore for MultimixerCore { fn finalize_fixed_core( &mut self, - buffer: &mut digest::core_api::Buffer, + _buffer: &mut digest::core_api::Buffer, out: &mut digest::Output, ) { - //let pos = buffer.get_pos(); - //let rem = buffer.remaining() as u8; - //let mut block = buffer.pad_with_zeros(); - //block[pos..].iter_mut().for_each(|b| *b = rem); - - //self.compress(&block); self.finalize(out); } } diff --git a/multimixer-128/tests/mod.rs b/multimixer-128/tests/mod.rs index c1cd2a7a..c1ff5ca7 100644 --- a/multimixer-128/tests/mod.rs +++ b/multimixer-128/tests/mod.rs @@ -5,13 +5,19 @@ use hex_literal::hex; use multimixer_128::Multimixer; -// digest::new_test!(toy_main, "toy", Toy, fixed_reset_test); Need to find out how to make .blb testdata. +#[test] +fn multimixer_10_test() { + let key = &hex!("4420823cfde6f1c26b30f90ec7dd01e4887534a20f0b0d04c36ed80e71e0fd77"); + let mut h = Multimixer::new(key.into()); + let data = [0; 100]; + digest::Update::update(&mut h, &data[..]); +} #[test] fn multimixer_simple_test() { let key = &hex!("4420823cfde6f1c26b30f90ec7dd01e4887534a20f0b0d04c36ed80e71e0fd77"); let message = &hex!("b07670eb940bd5335f973daad8619b91ffc911f57cced458bbbf2ce03753c9bd"); - let mut h = Multimixer::new(key.into()); + let mut h = Multimixer::new_from_slice(key).unwrap(); h.update(message); assert_eq!( h.finalize_fixed().as_slice(),