aboutsummaryrefslogtreecommitdiff
path: root/rand/src/prng
diff options
context:
space:
mode:
authorDaniel Mueller <deso@posteo.net>2019-01-02 21:14:10 -0800
committerDaniel Mueller <deso@posteo.net>2019-01-02 21:14:10 -0800
commitecf3474223ca3d16a10f12dc2272e3b0ed72c1bb (patch)
tree03134a683791176b49ef5c92e8d6acd24c3b5a9b /rand/src/prng
parent686f61b75055ecb02baf9d9449525ae447a3bed1 (diff)
downloadnitrocli-ecf3474223ca3d16a10f12dc2272e3b0ed72c1bb.tar.gz
nitrocli-ecf3474223ca3d16a10f12dc2272e3b0ed72c1bb.tar.bz2
Update nitrokey crate to 0.2.3
This change updates the nitrokey crate to version 0.2.3. This version bumps the rand crate used to 0.6.1, which in turn requires an additional set of dependencies. Import subrepo nitrokey/:nitrokey at b3e2adc5bb1300441ca74cc7672617c042f3ea31 Import subrepo rand/:rand at 73613ff903512e9503e41cc8ba9eae76269dc598 Import subrepo rustc_version/:rustc_version at 0294f2ba2018bf7be672abd53db351ce5055fa02 Import subrepo semver-parser/:semver-parser at 750da9b11a04125231b1fb293866ca036845acee Import subrepo semver/:semver at 5eb6db94fa03f4d5c64a625a56188f496be47598
Diffstat (limited to 'rand/src/prng')
-rw-r--r--rand/src/prng/chacha.rs321
-rw-r--r--rand/src/prng/isaac.rs328
-rw-r--r--rand/src/prng/isaac64.rs340
-rw-r--r--rand/src/prng/mod.rs74
-rw-r--r--rand/src/prng/xorshift.rs101
5 files changed, 30 insertions, 1134 deletions
diff --git a/rand/src/prng/chacha.rs b/rand/src/prng/chacha.rs
deleted file mode 100644
index a73e8e7..0000000
--- a/rand/src/prng/chacha.rs
+++ /dev/null
@@ -1,321 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The ChaCha random number generator.
-
-use core::num::Wrapping as w;
-use {Rng, SeedableRng, Rand};
-
-#[allow(bad_style)]
-type w32 = w<u32>;
-
-const KEY_WORDS : usize = 8; // 8 words for the 256-bit key
-const STATE_WORDS : usize = 16;
-const CHACHA_ROUNDS: u32 = 20; // Cryptographically secure from 8 upwards as of this writing
-
-/// A random number generator that uses the ChaCha20 algorithm [1].
-///
-/// The ChaCha algorithm is widely accepted as suitable for
-/// cryptographic purposes, but this implementation has not been
-/// verified as such. Prefer a generator like `OsRng` that defers to
-/// the operating system for cases that need high security.
-///
-/// [1]: D. J. Bernstein, [*ChaCha, a variant of
-/// Salsa20*](http://cr.yp.to/chacha.html)
-#[derive(Copy, Clone, Debug)]
-pub struct ChaChaRng {
- buffer: [w32; STATE_WORDS], // Internal buffer of output
- state: [w32; STATE_WORDS], // Initial state
- index: usize, // Index into state
-}
-
-static EMPTY: ChaChaRng = ChaChaRng {
- buffer: [w(0); STATE_WORDS],
- state: [w(0); STATE_WORDS],
- index: STATE_WORDS
-};
-
-
-macro_rules! quarter_round{
- ($a: expr, $b: expr, $c: expr, $d: expr) => {{
- $a = $a + $b; $d = $d ^ $a; $d = w($d.0.rotate_left(16));
- $c = $c + $d; $b = $b ^ $c; $b = w($b.0.rotate_left(12));
- $a = $a + $b; $d = $d ^ $a; $d = w($d.0.rotate_left( 8));
- $c = $c + $d; $b = $b ^ $c; $b = w($b.0.rotate_left( 7));
- }}
-}
-
-macro_rules! double_round{
- ($x: expr) => {{
- // Column round
- quarter_round!($x[ 0], $x[ 4], $x[ 8], $x[12]);
- quarter_round!($x[ 1], $x[ 5], $x[ 9], $x[13]);
- quarter_round!($x[ 2], $x[ 6], $x[10], $x[14]);
- quarter_round!($x[ 3], $x[ 7], $x[11], $x[15]);
- // Diagonal round
- quarter_round!($x[ 0], $x[ 5], $x[10], $x[15]);
- quarter_round!($x[ 1], $x[ 6], $x[11], $x[12]);
- quarter_round!($x[ 2], $x[ 7], $x[ 8], $x[13]);
- quarter_round!($x[ 3], $x[ 4], $x[ 9], $x[14]);
- }}
-}
-
-#[inline]
-fn core(output: &mut [w32; STATE_WORDS], input: &[w32; STATE_WORDS]) {
- *output = *input;
-
- for _ in 0..CHACHA_ROUNDS / 2 {
- double_round!(output);
- }
-
- for i in 0..STATE_WORDS {
- output[i] = output[i] + input[i];
- }
-}
-
-impl ChaChaRng {
-
- /// Create an ChaCha random number generator using the default
- /// fixed key of 8 zero words.
- ///
- /// # Examples
- ///
- /// ```rust
- /// use rand::{Rng, ChaChaRng};
- ///
- /// let mut ra = ChaChaRng::new_unseeded();
- /// println!("{:?}", ra.next_u32());
- /// println!("{:?}", ra.next_u32());
- /// ```
- ///
- /// Since this equivalent to a RNG with a fixed seed, repeated executions
- /// of an unseeded RNG will produce the same result. This code sample will
- /// consistently produce:
- ///
- /// - 2917185654
- /// - 2419978656
- pub fn new_unseeded() -> ChaChaRng {
- let mut rng = EMPTY;
- rng.init(&[0; KEY_WORDS]);
- rng
- }
-
- /// Sets the internal 128-bit ChaCha counter to
- /// a user-provided value. This permits jumping
- /// arbitrarily ahead (or backwards) in the pseudorandom stream.
- ///
- /// Since the nonce words are used to extend the counter to 128 bits,
- /// users wishing to obtain the conventional ChaCha pseudorandom stream
- /// associated with a particular nonce can call this function with
- /// arguments `0, desired_nonce`.
- ///
- /// # Examples
- ///
- /// ```rust
- /// use rand::{Rng, ChaChaRng};
- ///
- /// let mut ra = ChaChaRng::new_unseeded();
- /// ra.set_counter(0u64, 1234567890u64);
- /// println!("{:?}", ra.next_u32());
- /// println!("{:?}", ra.next_u32());
- /// ```
- pub fn set_counter(&mut self, counter_low: u64, counter_high: u64) {
- self.state[12] = w((counter_low >> 0) as u32);
- self.state[13] = w((counter_low >> 32) as u32);
- self.state[14] = w((counter_high >> 0) as u32);
- self.state[15] = w((counter_high >> 32) as u32);
- self.index = STATE_WORDS; // force recomputation
- }
-
- /// Initializes `self.state` with the appropriate key and constants
- ///
- /// We deviate slightly from the ChaCha specification regarding
- /// the nonce, which is used to extend the counter to 128 bits.
- /// This is provably as strong as the original cipher, though,
- /// since any distinguishing attack on our variant also works
- /// against ChaCha with a chosen-nonce. See the XSalsa20 [1]
- /// security proof for a more involved example of this.
- ///
- /// The modified word layout is:
- /// ```text
- /// constant constant constant constant
- /// key key key key
- /// key key key key
- /// counter counter counter counter
- /// ```
- /// [1]: Daniel J. Bernstein. [*Extending the Salsa20
- /// nonce.*](http://cr.yp.to/papers.html#xsalsa)
- fn init(&mut self, key: &[u32; KEY_WORDS]) {
- self.state[0] = w(0x61707865);
- self.state[1] = w(0x3320646E);
- self.state[2] = w(0x79622D32);
- self.state[3] = w(0x6B206574);
-
- for i in 0..KEY_WORDS {
- self.state[4+i] = w(key[i]);
- }
-
- self.state[12] = w(0);
- self.state[13] = w(0);
- self.state[14] = w(0);
- self.state[15] = w(0);
-
- self.index = STATE_WORDS;
- }
-
- /// Refill the internal output buffer (`self.buffer`)
- fn update(&mut self) {
- core(&mut self.buffer, &self.state);
- self.index = 0;
- // update 128-bit counter
- self.state[12] = self.state[12] + w(1);
- if self.state[12] != w(0) { return };
- self.state[13] = self.state[13] + w(1);
- if self.state[13] != w(0) { return };
- self.state[14] = self.state[14] + w(1);
- if self.state[14] != w(0) { return };
- self.state[15] = self.state[15] + w(1);
- }
-}
-
-impl Rng for ChaChaRng {
- #[inline]
- fn next_u32(&mut self) -> u32 {
- if self.index == STATE_WORDS {
- self.update();
- }
-
- let value = self.buffer[self.index % STATE_WORDS];
- self.index += 1;
- value.0
- }
-}
-
-impl<'a> SeedableRng<&'a [u32]> for ChaChaRng {
-
- fn reseed(&mut self, seed: &'a [u32]) {
- // reset state
- self.init(&[0u32; KEY_WORDS]);
- // set key in place
- let key = &mut self.state[4 .. 4+KEY_WORDS];
- for (k, s) in key.iter_mut().zip(seed.iter()) {
- *k = w(*s);
- }
- }
-
- /// Create a ChaCha generator from a seed,
- /// obtained from a variable-length u32 array.
- /// Only up to 8 words are used; if less than 8
- /// words are used, the remaining are set to zero.
- fn from_seed(seed: &'a [u32]) -> ChaChaRng {
- let mut rng = EMPTY;
- rng.reseed(seed);
- rng
- }
-}
-
-impl Rand for ChaChaRng {
- fn rand<R: Rng>(other: &mut R) -> ChaChaRng {
- let mut key : [u32; KEY_WORDS] = [0; KEY_WORDS];
- for word in key.iter_mut() {
- *word = other.gen();
- }
- SeedableRng::from_seed(&key[..])
- }
-}
-
-
-#[cfg(test)]
-mod test {
- use {Rng, SeedableRng};
- use super::ChaChaRng;
-
- #[test]
- fn test_rng_rand_seeded() {
- let s = ::test::rng().gen_iter::<u32>().take(8).collect::<Vec<u32>>();
- let mut ra: ChaChaRng = SeedableRng::from_seed(&s[..]);
- let mut rb: ChaChaRng = SeedableRng::from_seed(&s[..]);
- assert!(::test::iter_eq(ra.gen_ascii_chars().take(100),
- rb.gen_ascii_chars().take(100)));
- }
-
- #[test]
- fn test_rng_seeded() {
- let seed : &[_] = &[0,1,2,3,4,5,6,7];
- let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
- let mut rb: ChaChaRng = SeedableRng::from_seed(seed);
- assert!(::test::iter_eq(ra.gen_ascii_chars().take(100),
- rb.gen_ascii_chars().take(100)));
- }
-
- #[test]
- fn test_rng_reseed() {
- let s = ::test::rng().gen_iter::<u32>().take(8).collect::<Vec<u32>>();
- let mut r: ChaChaRng = SeedableRng::from_seed(&s[..]);
- let string1: String = r.gen_ascii_chars().take(100).collect();
-
- r.reseed(&s);
-
- let string2: String = r.gen_ascii_chars().take(100).collect();
- assert_eq!(string1, string2);
- }
-
- #[test]
- fn test_rng_true_values() {
- // Test vectors 1 and 2 from
- // http://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
- let seed : &[_] = &[0u32; 8];
- let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
-
- let v = (0..16).map(|_| ra.next_u32()).collect::<Vec<_>>();
- assert_eq!(v,
- vec!(0xade0b876, 0x903df1a0, 0xe56a5d40, 0x28bd8653,
- 0xb819d2bd, 0x1aed8da0, 0xccef36a8, 0xc70d778b,
- 0x7c5941da, 0x8d485751, 0x3fe02477, 0x374ad8b8,
- 0xf4b8436a, 0x1ca11815, 0x69b687c3, 0x8665eeb2));
-
- let v = (0..16).map(|_| ra.next_u32()).collect::<Vec<_>>();
- assert_eq!(v,
- vec!(0xbee7079f, 0x7a385155, 0x7c97ba98, 0x0d082d73,
- 0xa0290fcb, 0x6965e348, 0x3e53c612, 0xed7aee32,
- 0x7621b729, 0x434ee69c, 0xb03371d5, 0xd539d874,
- 0x281fed31, 0x45fb0a51, 0x1f0ae1ac, 0x6f4d794b));
-
-
- let seed : &[_] = &[0,1,2,3,4,5,6,7];
- let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
-
- // Store the 17*i-th 32-bit word,
- // i.e., the i-th word of the i-th 16-word block
- let mut v : Vec<u32> = Vec::new();
- for _ in 0..16 {
- v.push(ra.next_u32());
- for _ in 0..16 {
- ra.next_u32();
- }
- }
-
- assert_eq!(v,
- vec!(0xf225c81a, 0x6ab1be57, 0x04d42951, 0x70858036,
- 0x49884684, 0x64efec72, 0x4be2d186, 0x3615b384,
- 0x11cfa18e, 0xd3c50049, 0x75c775f6, 0x434c6530,
- 0x2c5bad8f, 0x898881dc, 0x5f1c86d9, 0xc1f8e7f4));
- }
-
- #[test]
- fn test_rng_clone() {
- let seed : &[_] = &[0u32; 8];
- let mut rng: ChaChaRng = SeedableRng::from_seed(seed);
- let mut clone = rng.clone();
- for _ in 0..16 {
- assert_eq!(rng.next_u64(), clone.next_u64());
- }
- }
-}
diff --git a/rand/src/prng/isaac.rs b/rand/src/prng/isaac.rs
deleted file mode 100644
index cf5eb67..0000000
--- a/rand/src/prng/isaac.rs
+++ /dev/null
@@ -1,328 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The ISAAC random number generator.
-
-#![allow(non_camel_case_types)]
-
-use core::slice;
-use core::iter::repeat;
-use core::num::Wrapping as w;
-use core::fmt;
-
-use {Rng, SeedableRng, Rand};
-
-#[allow(bad_style)]
-type w32 = w<u32>;
-
-const RAND_SIZE_LEN: usize = 8;
-const RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
-const RAND_SIZE_USIZE: usize = 1 << RAND_SIZE_LEN;
-
-/// A random number generator that uses the ISAAC algorithm[1].
-///
-/// The ISAAC algorithm is generally accepted as suitable for
-/// cryptographic purposes, but this implementation has not be
-/// verified as such. Prefer a generator like `OsRng` that defers to
-/// the operating system for cases that need high security.
-///
-/// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number
-/// generator*](http://www.burtleburtle.net/bob/rand/isaacafa.html)
-#[derive(Copy)]
-pub struct IsaacRng {
- cnt: u32,
- rsl: [w32; RAND_SIZE_USIZE],
- mem: [w32; RAND_SIZE_USIZE],
- a: w32,
- b: w32,
- c: w32,
-}
-
-static EMPTY: IsaacRng = IsaacRng {
- cnt: 0,
- rsl: [w(0); RAND_SIZE_USIZE],
- mem: [w(0); RAND_SIZE_USIZE],
- a: w(0), b: w(0), c: w(0),
-};
-
-impl IsaacRng {
-
- /// Create an ISAAC random number generator using the default
- /// fixed seed.
- pub fn new_unseeded() -> IsaacRng {
- let mut rng = EMPTY;
- rng.init(false);
- rng
- }
-
- /// Initialises `self`. If `use_rsl` is true, then use the current value
- /// of `rsl` as a seed, otherwise construct one algorithmically (not
- /// randomly).
- fn init(&mut self, use_rsl: bool) {
- let mut a = w(0x9e3779b9);
- let mut b = a;
- let mut c = a;
- let mut d = a;
- let mut e = a;
- let mut f = a;
- let mut g = a;
- let mut h = a;
-
- macro_rules! mix {
- () => {{
- a=a^(b<<11); d=d+a; b=b+c;
- b=b^(c>>2); e=e+b; c=c+d;
- c=c^(d<<8); f=f+c; d=d+e;
- d=d^(e>>16); g=g+d; e=e+f;
- e=e^(f<<10); h=h+e; f=f+g;
- f=f^(g>>4); a=a+f; g=g+h;
- g=g^(h<<8); b=b+g; h=h+a;
- h=h^(a>>9); c=c+h; a=a+b;
- }}
- }
-
- for _ in 0..4 {
- mix!();
- }
-
- if use_rsl {
- macro_rules! memloop {
- ($arr:expr) => {{
- for i in (0..RAND_SIZE_USIZE/8).map(|i| i * 8) {
- a=a+$arr[i ]; b=b+$arr[i+1];
- c=c+$arr[i+2]; d=d+$arr[i+3];
- e=e+$arr[i+4]; f=f+$arr[i+5];
- g=g+$arr[i+6]; h=h+$arr[i+7];
- mix!();
- self.mem[i ]=a; self.mem[i+1]=b;
- self.mem[i+2]=c; self.mem[i+3]=d;
- self.mem[i+4]=e; self.mem[i+5]=f;
- self.mem[i+6]=g; self.mem[i+7]=h;
- }
- }}
- }
-
- memloop!(self.rsl);
- memloop!(self.mem);
- } else {
- for i in (0..RAND_SIZE_USIZE/8).map(|i| i * 8) {
- mix!();
- self.mem[i ]=a; self.mem[i+1]=b;
- self.mem[i+2]=c; self.mem[i+3]=d;
- self.mem[i+4]=e; self.mem[i+5]=f;
- self.mem[i+6]=g; self.mem[i+7]=h;
- }
- }
-
- self.isaac();
- }
-
- /// Refills the output buffer (`self.rsl`)
- #[inline]
- fn isaac(&mut self) {
- self.c = self.c + w(1);
- // abbreviations
- let mut a = self.a;
- let mut b = self.b + self.c;
-
- const MIDPOINT: usize = RAND_SIZE_USIZE / 2;
-
- macro_rules! ind {
- ($x:expr) => ( self.mem[($x >> 2usize).0 as usize & (RAND_SIZE_USIZE - 1)] )
- }
-
- let r = [(0, MIDPOINT), (MIDPOINT, 0)];
- for &(mr_offset, m2_offset) in r.iter() {
-
- macro_rules! rngstepp {
- ($j:expr, $shift:expr) => {{
- let base = $j;
- let mix = a << $shift;
-
- let x = self.mem[base + mr_offset];
- a = (a ^ mix) + self.mem[base + m2_offset];
- let y = ind!(x) + a + b;
- self.mem[base + mr_offset] = y;
-
- b = ind!(y >> RAND_SIZE_LEN) + x;
- self.rsl[base + mr_offset] = b;
- }}
- }
-
- macro_rules! rngstepn {
- ($j:expr, $shift:expr) => {{
- let base = $j;
- let mix = a >> $shift;
-
- let x = self.mem[base + mr_offset];
- a = (a ^ mix) + self.mem[base + m2_offset];
- let y = ind!(x) + a + b;
- self.mem[base + mr_offset] = y;
-
- b = ind!(y >> RAND_SIZE_LEN) + x;
- self.rsl[base + mr_offset] = b;
- }}
- }
-
- for i in (0..MIDPOINT/4).map(|i| i * 4) {
- rngstepp!(i + 0, 13);
- rngstepn!(i + 1, 6);
- rngstepp!(i + 2, 2);
- rngstepn!(i + 3, 16);
- }
- }
-
- self.a = a;
- self.b = b;
- self.cnt = RAND_SIZE;
- }
-}
-
-// Cannot be derived because [u32; 256] does not implement Clone
-impl Clone for IsaacRng {
- fn clone(&self) -> IsaacRng {
- *self
- }
-}
-
-impl Rng for IsaacRng {
- #[inline]
- fn next_u32(&mut self) -> u32 {
- if self.cnt == 0 {
- // make some more numbers
- self.isaac();
- }
- self.cnt -= 1;
-
- // self.cnt is at most RAND_SIZE, but that is before the
- // subtraction above. We want to index without bounds
- // checking, but this could lead to incorrect code if someone
- // misrefactors, so we check, sometimes.
- //
- // (Changes here should be reflected in Isaac64Rng.next_u64.)
- debug_assert!(self.cnt < RAND_SIZE);
-
- // (the % is cheaply telling the optimiser that we're always
- // in bounds, without unsafe. NB. this is a power of two, so
- // it optimises to a bitwise mask).
- self.rsl[(self.cnt % RAND_SIZE) as usize].0
- }
-}
-
-impl<'a> SeedableRng<&'a [u32]> for IsaacRng {
- fn reseed(&mut self, seed: &'a [u32]) {
- // make the seed into [seed[0], seed[1], ..., seed[seed.len()
- // - 1], 0, 0, ...], to fill rng.rsl.
- let seed_iter = seed.iter().map(|&x| x).chain(repeat(0u32));
-
- for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
- *rsl_elem = w(seed_elem);
- }
- self.cnt = 0;
- self.a = w(0);
- self.b = w(0);
- self.c = w(0);
-
- self.init(true);
- }
-
- /// Create an ISAAC random number generator with a seed. This can
- /// be any length, although the maximum number of elements used is
- /// 256 and any more will be silently ignored. A generator
- /// constructed with a given seed will generate the same sequence
- /// of values as all other generators constructed with that seed.
- fn from_seed(seed: &'a [u32]) -> IsaacRng {
- let mut rng = EMPTY;
- rng.reseed(seed);
- rng
- }
-}
-
-impl Rand for IsaacRng {
- fn rand<R: Rng>(other: &mut R) -> IsaacRng {
- let mut ret = EMPTY;
- unsafe {
- let ptr = ret.rsl.as_mut_ptr() as *mut u8;
-
- let slice = slice::from_raw_parts_mut(ptr, RAND_SIZE_USIZE * 4);
- other.fill_bytes(slice);
- }
- ret.cnt = 0;
- ret.a = w(0);
- ret.b = w(0);
- ret.c = w(0);
-
- ret.init(true);
- return ret;
- }
-}
-
-impl fmt::Debug for IsaacRng {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "IsaacRng {{}}")
- }
-}
-
-#[cfg(test)]
-mod test {
- use {Rng, SeedableRng};
- use super::IsaacRng;
-
- #[test]
- fn test_rng_32_rand_seeded() {
- let s = ::test::rng().gen_iter::<u32>().take(256).collect::<Vec<u32>>();
- let mut ra: IsaacRng = SeedableRng::from_seed(&s[..]);
- let mut rb: IsaacRng = SeedableRng::from_seed(&s[..]);
- assert!(::test::iter_eq(ra.gen_ascii_chars().take(100),
- rb.gen_ascii_chars().take(100)));
- }
-
- #[test]
- fn test_rng_32_seeded() {
- let seed: &[_] = &[1, 23, 456, 7890, 12345];
- let mut ra: IsaacRng = SeedableRng::from_seed(seed);
- let mut rb: IsaacRng = SeedableRng::from_seed(seed);
- assert!(::test::iter_eq(ra.gen_ascii_chars().take(100),
- rb.gen_ascii_chars().take(100)));
- }
-
- #[test]
- fn test_rng_32_reseed() {
- let s = ::test::rng().gen_iter::<u32>().take(256).collect::<Vec<u32>>();
- let mut r: IsaacRng = SeedableRng::from_seed(&s[..]);
- let string1: String = r.gen_ascii_chars().take(100).collect();
-
- r.reseed(&s[..]);
-
- let string2: String = r.gen_ascii_chars().take(100).collect();
- assert_eq!(string1, string2);
- }
-
- #[test]
- fn test_rng_32_true_values() {
- let seed: &[_] = &[1, 23, 456, 7890, 12345];
- let mut ra: IsaacRng = SeedableRng::from_seed(seed);
- // Regression test that isaac is actually using the above vector
- let v = (0..10).map(|_| ra.next_u32()).collect::<Vec<_>>();
- assert_eq!(v,
- vec!(2558573138, 873787463, 263499565, 2103644246, 3595684709,
- 4203127393, 264982119, 2765226902, 2737944514, 3900253796));
-
- let seed: &[_] = &[12345, 67890, 54321, 9876];
- let mut rb: IsaacRng = SeedableRng::from_seed(seed);
- // skip forward to the 10000th number
- for _ in 0..10000 { rb.next_u32(); }
-
- let v = (0..10).map(|_| rb.next_u32()).collect::<Vec<_>>();
- assert_eq!(v,
- vec!(3676831399, 3183332890, 2834741178, 3854698763, 2717568474,
- 1576568959, 3507990155, 179069555, 141456972, 2478885421));
- }
-}
diff --git a/rand/src/prng/isaac64.rs b/rand/src/prng/isaac64.rs
deleted file mode 100644
index b98e3fe..0000000
--- a/rand/src/prng/isaac64.rs
+++ /dev/null
@@ -1,340 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The ISAAC-64 random number generator.
-
-use core::slice;
-use core::iter::repeat;
-use core::num::Wrapping as w;
-use core::fmt;
-
-use {Rng, SeedableRng, Rand};
-
-#[allow(bad_style)]
-type w64 = w<u64>;
-
-const RAND_SIZE_64_LEN: usize = 8;
-const RAND_SIZE_64: usize = 1 << RAND_SIZE_64_LEN;
-
-/// A random number generator that uses ISAAC-64[1], the 64-bit
-/// variant of the ISAAC algorithm.
-///
-/// The ISAAC algorithm is generally accepted as suitable for
-/// cryptographic purposes, but this implementation has not be
-/// verified as such. Prefer a generator like `OsRng` that defers to
-/// the operating system for cases that need high security.
-///
-/// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number
-/// generator*](http://www.burtleburtle.net/bob/rand/isaacafa.html)
-#[derive(Copy)]
-pub struct Isaac64Rng {
- cnt: usize,
- rsl: [w64; RAND_SIZE_64],
- mem: [w64; RAND_SIZE_64],
- a: w64,
- b: w64,
- c: w64,
-}
-
-static EMPTY_64: Isaac64Rng = Isaac64Rng {
- cnt: 0,
- rsl: [w(0); RAND_SIZE_64],
- mem: [w(0); RAND_SIZE_64],
- a: w(0), b: w(0), c: w(0),
-};
-
-impl Isaac64Rng {
- /// Create a 64-bit ISAAC random number generator using the
- /// default fixed seed.
- pub fn new_unseeded() -> Isaac64Rng {
- let mut rng = EMPTY_64;
- rng.init(false);
- rng
- }
-
- /// Initialises `self`. If `use_rsl` is true, then use the current value
- /// of `rsl` as a seed, otherwise construct one algorithmically (not
- /// randomly).
- fn init(&mut self, use_rsl: bool) {
- macro_rules! init {
- ($var:ident) => (
- let mut $var = w(0x9e3779b97f4a7c13);
- )
- }
- init!(a); init!(b); init!(c); init!(d);
- init!(e); init!(f); init!(g); init!(h);
-
- macro_rules! mix {
- () => {{
- a=a-e; f=f^(h>>9); h=h+a;
- b=b-f; g=g^(a<<9); a=a+b;
- c=c-g; h=h^(b>>23); b=b+c;
- d=d-h; a=a^(c<<15); c=c+d;
- e=e-a; b=b^(d>>14); d=d+e;
- f=f-b; c=c^(e<<20); e=e+f;
- g=g-c; d=d^(f>>17); f=f+g;
- h=h-d; e=e^(g<<14); g=g+h;
- }}
- }
-
- for _ in 0..4 {
- mix!();
- }
-
- if use_rsl {
- macro_rules! memloop {
- ($arr:expr) => {{
- for i in (0..RAND_SIZE_64 / 8).map(|i| i * 8) {
- a=a+$arr[i ]; b=b+$arr[i+1];
- c=c+$arr[i+2]; d=d+$arr[i+3];
- e=e+$arr[i+4]; f=f+$arr[i+5];
- g=g+$arr[i+6]; h=h+$arr[i+7];
- mix!();
- self.mem[i ]=a; self.mem[i+1]=b;
- self.mem[i+2]=c; self.mem[i+3]=d;
- self.mem[i+4]=e; self.mem[i+5]=f;
- self.mem[i+6]=g; self.mem[i+7]=h;
- }
- }}
- }
-
- memloop!(self.rsl);
- memloop!(self.mem);
- } else {
- for i in (0..RAND_SIZE_64 / 8).map(|i| i * 8) {
- mix!();
- self.mem[i ]=a; self.mem[i+1]=b;
- self.mem[i+2]=c; self.mem[i+3]=d;
- self.mem[i+4]=e; self.mem[i+5]=f;
- self.mem[i+6]=g; self.mem[i+7]=h;
- }
- }
-
- self.isaac64();
- }
-
- /// Refills the output buffer (`self.rsl`)
- fn isaac64(&mut self) {
- self.c = self.c + w(1);
- // abbreviations
- let mut a = self.a;
- let mut b = self.b + self.c;
- const MIDPOINT: usize = RAND_SIZE_64 / 2;
- const MP_VEC: [(usize, usize); 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
- macro_rules! ind {
- ($x:expr) => {
- *self.mem.get_unchecked((($x >> 3usize).0 as usize) & (RAND_SIZE_64 - 1))
- }
- }
-
- for &(mr_offset, m2_offset) in MP_VEC.iter() {
- for base in (0..MIDPOINT / 4).map(|i| i * 4) {
-
- macro_rules! rngstepp {
- ($j:expr, $shift:expr) => {{
- let base = base + $j;
- let mix = a ^ (a << $shift);
- let mix = if $j == 0 {!mix} else {mix};
-
- unsafe {
- let x = *self.mem.get_unchecked(base + mr_offset);
- a = mix + *self.mem.get_unchecked(base + m2_offset);
- let y = ind!(x) + a + b;
- *self.mem.get_unchecked_mut(base + mr_offset) = y;
-
- b = ind!(y >> RAND_SIZE_64_LEN) + x;
- *self.rsl.get_unchecked_mut(base + mr_offset) = b;
- }
- }}
- }
-
- macro_rules! rngstepn {
- ($j:expr, $shift:expr) => {{
- let base = base + $j;
- let mix = a ^ (a >> $shift);
- let mix = if $j == 0 {!mix} else {mix};
-
- unsafe {
- let x = *self.mem.get_unchecked(base + mr_offset);
- a = mix + *self.mem.get_unchecked(base + m2_offset);
- let y = ind!(x) + a + b;
- *self.mem.get_unchecked_mut(base + mr_offset) = y;
-
- b = ind!(y >> RAND_SIZE_64_LEN) + x;
- *self.rsl.get_unchecked_mut(base + mr_offset) = b;
- }
- }}
- }
-
- rngstepp!(0, 21);
- rngstepn!(1, 5);
- rngstepp!(2, 12);
- rngstepn!(3, 33);
- }
- }
-
- self.a = a;
- self.b = b;
- self.cnt = RAND_SIZE_64;
- }
-}
-
-// Cannot be derived because [u32; 256] does not implement Clone
-impl Clone for Isaac64Rng {
- fn clone(&self) -> Isaac64Rng {
- *self
- }
-}
-
-impl Rng for Isaac64Rng {
- #[inline]
- fn next_u32(&mut self) -> u32 {
- self.next_u64() as u32
- }
-
- #[inline]
- fn next_u64(&mut self) -> u64 {
- if self.cnt == 0 {
- // make some more numbers
- self.isaac64();
- }
- self.cnt -= 1;
-
- // See corresponding location in IsaacRng.next_u32 for
- // explanation.
- debug_assert!(self.cnt < RAND_SIZE_64);
- self.rsl[(self.cnt % RAND_SIZE_64) as usize].0
- }
-}
-
-impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng {
- fn reseed(&mut self, seed: &'a [u64]) {
- // make the seed into [seed[0], seed[1], ..., seed[seed.len()
- // - 1], 0, 0, ...], to fill rng.rsl.
- let seed_iter = seed.iter().map(|&x| x).chain(repeat(0u64));
-
- for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
- *rsl_elem = w(seed_elem);
- }
- self.cnt = 0;
- self.a = w(0);
- self.b = w(0);
- self.c = w(0);
-
- self.init(true);
- }
-
- /// Create an ISAAC random number generator with a seed. This can
- /// be any length, although the maximum number of elements used is
- /// 256 and any more will be silently ignored. A generator
- /// constructed with a given seed will generate the same sequence
- /// of values as all other generators constructed with that seed.
- fn from_seed(seed: &'a [u64]) -> Isaac64Rng {
- let mut rng = EMPTY_64;
- rng.reseed(seed);
- rng
- }
-}
-
-impl Rand for Isaac64Rng {
- fn rand<R: Rng>(other: &mut R) -> Isaac64Rng {
- let mut ret = EMPTY_64;
- unsafe {
- let ptr = ret.rsl.as_mut_ptr() as *mut u8;
-
- let slice = slice::from_raw_parts_mut(ptr, RAND_SIZE_64 * 8);
- other.fill_bytes(slice);
- }
- ret.cnt = 0;
- ret.a = w(0);
- ret.b = w(0);
- ret.c = w(0);
-
- ret.init(true);
- return ret;
- }
-}
-
-impl fmt::Debug for Isaac64Rng {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "Isaac64Rng {{}}")
- }
-}
-
-#[cfg(test)]
-mod test {
- use {Rng, SeedableRng};
- use super::Isaac64Rng;
-
- #[test]
- fn test_rng_64_rand_seeded() {
- let s = ::test::rng().gen_iter::<u64>().take(256).collect::<Vec<u64>>();
- let mut ra: Isaac64Rng = SeedableRng::from_seed(&s[..]);
- let mut rb: Isaac64Rng = SeedableRng::from_seed(&s[..]);
- assert!(::test::iter_eq(ra.gen_ascii_chars().take(100),
- rb.gen_ascii_chars().take(100)));
- }
-
- #[test]
- fn test_rng_64_seeded() {
- let seed: &[_] = &[1, 23, 456, 7890, 12345];
- let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
- let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
- assert!(::test::iter_eq(ra.gen_ascii_chars().take(100),
- rb.gen_ascii_chars().take(100)));
- }
-
- #[test]
- fn test_rng_64_reseed() {
- let s = ::test::rng().gen_iter::<u64>().take(256).collect::<Vec<u64>>();
- let mut r: Isaac64Rng = SeedableRng::from_seed(&s[..]);
- let string1: String = r.gen_ascii_chars().take(100).collect();
-
- r.reseed(&s[..]);
-
- let string2: String = r.gen_ascii_chars().take(100).collect();
- assert_eq!(string1, string2);
- }
-
- #[test]
- fn test_rng_64_true_values() {
- let seed: &[_] = &[1, 23, 456, 7890, 12345];
- let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
- // Regression test that isaac is actually using the above vector
- let v = (0..10).map(|_| ra.next_u64()).collect::<Vec<_>>();
- assert_eq!(v,
- vec!(547121783600835980, 14377643087320773276, 17351601304698403469,
- 1238879483818134882, 11952566807690396487, 13970131091560099343,
- 4469761996653280935, 15552757044682284409, 6860251611068737823,
- 13722198873481261842));
-
- let seed: &[_] = &[12345, 67890, 54321, 9876];
- let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
- // skip forward to the 10000th number
- for _ in 0..10000 { rb.next_u64(); }
-
- let v = (0..10).map(|_| rb.next_u64()).collect::<Vec<_>>();
- assert_eq!(v,
- vec!(18143823860592706164, 8491801882678285927, 2699425367717515619,
- 17196852593171130876, 2606123525235546165, 15790932315217671084,
- 596345674630742204, 9947027391921273664, 11788097613744130851,
- 10391409374914919106));
- }
-
- #[test]
- fn test_rng_clone() {
- let seed: &[_] = &[1, 23, 456, 7890, 12345];
- let mut rng: Isaac64Rng = SeedableRng::from_seed(seed);
- let mut clone = rng.clone();
- for _ in 0..16 {
- assert_eq!(rng.next_u64(), clone.next_u64());
- }
- }
-}
diff --git a/rand/src/prng/mod.rs b/rand/src/prng/mod.rs
index ed3e018..3c0d27b 100644
--- a/rand/src/prng/mod.rs
+++ b/rand/src/prng/mod.rs
@@ -1,51 +1,37 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
+// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Pseudo random number generators are algorithms to produce *apparently
-//! random* numbers deterministically, and usually fairly quickly.
+//! Pseudo-random number generators.
+//!
+//! This module is deprecated:
//!
-//! So long as the algorithm is computationally secure, is initialised with
-//! sufficient entropy (i.e. unknown by an attacker), and its internal state is
-//! also protected (unknown to an attacker), the output will also be
-//! *computationally secure*. Computationally Secure Pseudo Random Number
-//! Generators (CSPRNGs) are thus suitable sources of random numbers for
-//! cryptography. There are a couple of gotchas here, however. First, the seed
-//! used for initialisation must be unknown. Usually this should be provided by
-//! the operating system and should usually be secure, however this may not
-//! always be the case (especially soon after startup). Second, user-space
-//! memory may be vulnerable, for example when written to swap space, and after
-//! forking a child process should reinitialise any user-space PRNGs. For this
-//! reason it may be preferable to source random numbers directly from the OS
-//! for cryptographic applications.
-//!
-//! PRNGs are also widely used for non-cryptographic uses: randomised
-//! algorithms, simulations, games. In these applications it is usually not
-//! important for numbers to be cryptographically *unguessable*, but even
-//! distribution and independence from other samples (from the point of view
-//! of someone unaware of the algorithm used, at least) may still be important.
-//! Good PRNGs should satisfy these properties, but do not take them for
-//! granted; Wikipedia's article on
-//! [Pseudorandom number generators](https://en.wikipedia.org/wiki/Pseudorandom_number_generator)
-//! provides some background on this topic.
-//!
-//! Care should be taken when seeding (initialising) PRNGs. Some PRNGs have
-//! short periods for some seeds. If one PRNG is seeded from another using the
-//! same algorithm, it is possible that both will yield the same sequence of
-//! values (with some lag).
-
-mod chacha;
-mod isaac;
-mod isaac64;
-mod xorshift;
+//! - documentation has moved to
+//! [The Book](https://rust-random.github.io/book/guide-rngs.html),
+//! - PRNGs have moved to other `rand_*` crates.
-pub use self::chacha::ChaChaRng;
-pub use self::isaac::IsaacRng;
-pub use self::isaac64::Isaac64Rng;
-pub use self::xorshift::XorShiftRng;
+// Deprecations (to be removed in 0.7)
+#[doc(hidden)] #[allow(deprecated)]
+pub use deprecated::XorShiftRng;
+#[doc(hidden)] pub mod isaac {
+ // Note: we miss `IsaacCore` here but probably unimportant.
+ #[allow(deprecated)] pub use deprecated::IsaacRng;
+}
+#[doc(hidden)] pub mod isaac64 {
+ #[allow(deprecated)] pub use deprecated::Isaac64Rng;
+}
+#[doc(hidden)] #[allow(deprecated)] pub use deprecated::{IsaacRng, Isaac64Rng};
+#[doc(hidden)] pub mod chacha {
+ // Note: we miss `ChaChaCore` here but probably unimportant.
+ #[allow(deprecated)] pub use deprecated::ChaChaRng;
+}
+#[doc(hidden)] #[allow(deprecated)] pub use deprecated::ChaChaRng;
+#[doc(hidden)] pub mod hc128 {
+ // Note: we miss `Hc128Core` here but probably unimportant.
+ #[allow(deprecated)] pub use deprecated::Hc128Rng;
+}
+#[doc(hidden)] #[allow(deprecated)] pub use deprecated::Hc128Rng;
diff --git a/rand/src/prng/xorshift.rs b/rand/src/prng/xorshift.rs
deleted file mode 100644
index dd367e9..0000000
--- a/rand/src/prng/xorshift.rs
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Xorshift generators
-
-use core::num::Wrapping as w;
-use {Rng, SeedableRng, Rand};
-
-/// An Xorshift[1] random number
-/// generator.
-///
-/// The Xorshift algorithm is not suitable for cryptographic purposes
-/// but is very fast. If you do not know for sure that it fits your
-/// requirements, use a more secure one such as `IsaacRng` or `OsRng`.
-///
-/// [1]: Marsaglia, George (July 2003). ["Xorshift
-/// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
-/// Statistical Software*. Vol. 8 (Issue 14).
-#[allow(missing_copy_implementations)]
-#[derive(Clone, Debug)]
-pub struct XorShiftRng {
- x: w<u32>,
- y: w<u32>,
- z: w<u32>,
- w: w<u32>,
-}
-
-impl XorShiftRng {
- /// Creates a new XorShiftRng instance which is not seeded.
- ///
- /// The initial values of this RNG are constants, so all generators created
- /// by this function will yield the same stream of random numbers. It is
- /// highly recommended that this is created through `SeedableRng` instead of
- /// this function
- pub fn new_unseeded() -> XorShiftRng {
- XorShiftRng {
- x: w(0x193a6754),
- y: w(0xa8a7d469),
- z: w(0x97830e05),
- w: w(0x113ba7bb),
- }
- }
-}
-
-impl Rng for XorShiftRng {
- #[inline]
- fn next_u32(&mut self) -> u32 {
- let x = self.x;
- let t = x ^ (x << 11);
- self.x = self.y;
- self.y = self.z;
- self.z = self.w;
- let w_ = self.w;
- self.w = w_ ^ (w_ >> 19) ^ (t ^ (t >> 8));
- self.w.0
- }
-}
-
-impl SeedableRng<[u32; 4]> for XorShiftRng {
- /// Reseed an XorShiftRng. This will panic if `seed` is entirely 0.
- fn reseed(&mut self, seed: [u32; 4]) {
- assert!(!seed.iter().all(|&x| x == 0),
- "XorShiftRng.reseed called with an all zero seed.");
-
- self.x = w(seed[0]);
- self.y = w(seed[1]);
- self.z = w(seed[2]);
- self.w = w(seed[3]);
- }
-
- /// Create a new XorShiftRng. This will panic if `seed` is entirely 0.
- fn from_seed(seed: [u32; 4]) -> XorShiftRng {
- assert!(!seed.iter().all(|&x| x == 0),
- "XorShiftRng::from_seed called with an all zero seed.");
-
- XorShiftRng {
- x: w(seed[0]),
- y: w(seed[1]),
- z: w(seed[2]),
- w: w(seed[3]),
- }
- }
-}
-
-impl Rand for XorShiftRng {
- fn rand<R: Rng>(rng: &mut R) -> XorShiftRng {
- let mut tuple: (u32, u32, u32, u32) = rng.gen();
- while tuple == (0, 0, 0, 0) {
- tuple = rng.gen();
- }
- let (x, y, z, w_) = tuple;
- XorShiftRng { x: w(x), y: w(y), z: w(z), w: w(w_) }
- }
-}