summaryrefslogtreecommitdiffstats
path: root/src/random.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-04-09 00:06:18 -0400
committerJesse Luehrs <doy@tozt.net>2019-04-09 02:00:33 -0400
commitf1f522df90e4af23f442067e269463710193148d (patch)
treeb397d986d68623e79f12499da64f76f26cd30f99 /src/random.rs
parent6807601cb64e7b18b832cab2939cbb107e3727bb (diff)
downloadmatasano-f1f522df90e4af23f442067e269463710193148d.tar.gz
matasano-f1f522df90e4af23f442067e269463710193148d.zip
get this compiling again
Diffstat (limited to 'src/random.rs')
-rw-r--r--src/random.rs170
1 files changed, 119 insertions, 51 deletions
diff --git a/src/random.rs b/src/random.rs
index e248293..69bab3f 100644
--- a/src/random.rs
+++ b/src/random.rs
@@ -1,18 +1,91 @@
-use rand::{Rand, Rng, SeedableRng};
+use rand::{Rng, RngCore, SeedableRng};
pub struct MersenneTwister {
state: [u32; 624],
- index: usize,
+ 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 }
+ 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 Rng for MersenneTwister {
- fn next_u32 (&mut self) -> u32 {
+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)
@@ -24,7 +97,7 @@ impl Rng for MersenneTwister {
}
}
- let mut y = self.state[self.index];
+ let mut y = self.state[self.index as usize];
y = y ^ (y >> 11);
y = y ^ ((y << 7) & 0x9d2c5680);
y = y ^ ((y << 15) & 0xefc60000);
@@ -34,73 +107,68 @@ impl Rng for MersenneTwister {
return y;
}
-}
-impl SeedableRng<u32> for MersenneTwister {
- fn reseed (&mut self, seed: u32) {
- self.state[0] = seed;
- for i in 1..624 {
- let prev = self.state[i - 1];
- self.state[i] = 1812433253u32
- .wrapping_mul(prev ^ (prev >> 30))
- .wrapping_add(i as u32);
- }
+ fn next_u64(&mut self) -> u64 {
+ rand_core::impls::next_u64_via_u32(self)
}
- fn from_seed (seed: u32) -> MersenneTwister {
- let mut mt = MersenneTwister::new_unseeded();
- mt.reseed(seed);
- mt
+ fn fill_bytes(&mut self, dest: &mut [u8]) {
+ rand_core::impls::fill_bytes_via_next(self, dest)
}
-}
-impl SeedableRng<([u32; 624], usize)> for MersenneTwister {
- fn reseed (&mut self, seed: ([u32; 624], usize)) {
- let (state, index) = seed;
- for i in 0..624 {
- self.state[i] = state[i];
- }
- self.index = index;
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
+ Ok(rand_core::impls::fill_bytes_via_next(self, dest))
}
+}
- fn from_seed (seed: ([u32; 624], usize)) -> MersenneTwister {
+impl SeedableRng for MersenneTwister {
+ type Seed = MersenneTwisterSeed;
+
+ fn from_seed(seed: MersenneTwisterSeed) -> MersenneTwister {
let mut mt = MersenneTwister::new_unseeded();
- mt.reseed(seed);
+ let MersenneTwister { state, index } = mt_seed_to_state(seed);
+ for i in 0..624 {
+ mt.state[i] = state[i];
+ }
+ mt.index = index;
mt
}
}
-impl Rand for MersenneTwister {
- fn rand<R: Rng> (other: &mut R) -> MersenneTwister {
- MersenneTwister::from_seed(other.next_u32())
- }
-}
-
impl Clone for MersenneTwister {
- fn clone (&self) -> MersenneTwister {
- MersenneTwister { state: self.state, index: self.index }
+ 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> {
- try!(write!(f, "MersenneTwister {{ "));
- try!(::std::fmt::Debug::fmt(&&self.state[..], f));
- try!(write!(f, ", "));
- try!(::std::fmt::Debug::fmt(&self.index, f));
+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<u8> {
- let mut mt = MersenneTwister::from_seed(key);
- let keystream: Vec<u8> = mt.gen_iter().take(ciphertext.len()).collect();
- return ::primitives::fixed_xor(ciphertext, &keystream[..]);
+pub fn mt19937_stream_cipher(ciphertext: &[u8], key: u32) -> Vec<u8> {
+ let mut mt = MersenneTwister::from_u32(key);
+ let keystream: Vec<u8> = 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();
+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";