use rand::{Rng, RngCore, SeedableRng}; pub struct MersenneTwister { state: [u32; 624], index: u32, } pub struct MersenneTwisterSeed([u8; 2500]); impl Default for MersenneTwisterSeed { fn default() -> MersenneTwisterSeed { MersenneTwisterSeed([0; 2500]) } } impl AsMut<[u8]> for MersenneTwisterSeed { fn as_mut(&mut self) -> &mut [u8] { &mut self.0 } } fn mt_seed_to_state(seed: MersenneTwisterSeed) -> MersenneTwister { let mut state = [0; 624]; for i in 0..624 { let idx = i * 4; state[i] = u32::from_ne_bytes([ seed.0[idx], seed.0[idx + 1], seed.0[idx + 2], seed.0[idx + 3], ]); } let index = u32::from_ne_bytes([ seed.0[2496], seed.0[2497], seed.0[2498], seed.0[2499], ]) % 624; MersenneTwister { state, index } } fn mt_state_to_seed(state: [u32; 624], index: u32) -> MersenneTwisterSeed { let mut seed = MersenneTwisterSeed([0; 2500]); let mut idx = 0; for i in &state[..] { let bytes = u32::to_ne_bytes(*i); seed.0[idx as usize] = bytes[0]; seed.0[(idx + 1) as usize] = bytes[1]; seed.0[(idx + 2) as usize] = bytes[2]; seed.0[(idx + 3) as usize] = bytes[3]; idx += 4; } let bytes = u32::to_ne_bytes(index); seed.0[2496] = bytes[0]; seed.0[2497] = bytes[1]; seed.0[2498] = bytes[2]; seed.0[2499] = bytes[3]; seed } impl MersenneTwister { fn new_unseeded() -> MersenneTwister { MersenneTwister { state: [0; 624], index: 0, } } pub fn from_u32(seed: u32) -> MersenneTwister { let mut state = [0; 624]; state[0] = seed; for i in 1..624 { let prev = state[i - 1]; state[i] = 1812433253u32 .wrapping_mul(prev ^ (prev >> 30)) .wrapping_add(i as u32); } MersenneTwister::from_seed(mt_state_to_seed(state, 0)) } pub fn from_state(state: [u32; 624], index: u32) -> MersenneTwister { MersenneTwister::from_seed(mt_state_to_seed(state, index)) } } impl RngCore for MersenneTwister { fn next_u32(&mut self) -> u32 { if self.index == 0 { for i in 0..624 { let y = (self.state[i] & 0x80000000) .wrapping_add(self.state[(i + 1) % 624] & 0x7fffffff); self.state[i] = self.state[(i + 397) % 624] ^ (y >> 1); if (y % 2) != 0 { self.state[i] = self.state[i] ^ 0x9908b0df; } } } let mut y = self.state[self.index as usize]; y = y ^ (y >> 11); y = y ^ ((y << 7) & 0x9d2c5680); y = y ^ ((y << 15) & 0xefc60000); y = y ^ (y >> 18); self.index = (self.index + 1) % 624; return y; } fn next_u64(&mut self) -> u64 { rand_core::impls::next_u64_via_u32(self) } fn fill_bytes(&mut self, dest: &mut [u8]) { rand_core::impls::fill_bytes_via_next(self, dest) } fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> { Ok(rand_core::impls::fill_bytes_via_next(self, dest)) } } impl SeedableRng for MersenneTwister { type Seed = MersenneTwisterSeed; fn from_seed(seed: MersenneTwisterSeed) -> MersenneTwister { let mut mt = MersenneTwister::new_unseeded(); let MersenneTwister { state, index } = mt_seed_to_state(seed); for i in 0..624 { mt.state[i] = state[i]; } mt.index = index; mt } } impl Clone for MersenneTwister { fn clone(&self) -> MersenneTwister { MersenneTwister { state: self.state, index: self.index, } } } impl std::fmt::Debug for MersenneTwister { fn fmt( &self, f: &mut std::fmt::Formatter, ) -> Result<(), std::fmt::Error> { write!(f, "MersenneTwister {{ ")?; std::fmt::Debug::fmt(&&self.state[..], f)?; write!(f, ", ")?; std::fmt::Debug::fmt(&self.index, f)?; write!(f, " }}") } } pub fn mt19937_stream_cipher(ciphertext: &[u8], key: u32) -> Vec { let mut mt = MersenneTwister::from_u32(key); let keystream: Vec = mt .sample_iter(&rand::distributions::Standard) .take(ciphertext.len()) .collect(); return crate::primitives::fixed_xor(ciphertext, &keystream[..]); } #[test] fn test_mt19937_stream_cipher() { let key = rand::thread_rng().gen(); let plaintext = b"Summertime and the wind is blowing outside in lower \ Chelsea and I don't know what I'm doing in the city, the \ sun is always in my eyes"; let ciphertext = mt19937_stream_cipher(&plaintext[..], key); assert!(&plaintext[..] != &ciphertext[..]); let plaintext2 = mt19937_stream_cipher(&ciphertext[..], key); assert_eq!(&plaintext[..], &plaintext2[..]); }