aboutsummaryrefslogtreecommitdiff
path: root/rand/src/rngs/std.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rand/src/rngs/std.rs')
-rw-r--r--rand/src/rngs/std.rs59
1 files changed, 39 insertions, 20 deletions
diff --git a/rand/src/rngs/std.rs b/rand/src/rngs/std.rs
index ce1658b..22e08ae 100644
--- a/rand/src/rngs/std.rs
+++ b/rand/src/rngs/std.rs
@@ -8,25 +8,30 @@
//! The standard RNG
-use {RngCore, CryptoRng, Error, SeedableRng};
-use rand_hc::Hc128Rng;
+use crate::{RngCore, CryptoRng, Error, SeedableRng};
+
+#[cfg(target_os = "emscripten")] pub(crate) use rand_hc::Hc128Core as Core;
+#[cfg(not(target_os = "emscripten"))] pub(crate) use rand_chacha::ChaCha20Core as Core;
+#[cfg(target_os = "emscripten")] use rand_hc::Hc128Rng as Rng;
+#[cfg(not(target_os = "emscripten"))] use rand_chacha::ChaCha20Rng as Rng;
/// The standard RNG. The PRNG algorithm in `StdRng` is chosen to be efficient
/// on the current platform, to be statistically strong and unpredictable
/// (meaning a cryptographically secure PRNG).
///
-/// The current algorithm used on all platforms is [HC-128].
+/// The current algorithm used is the ChaCha block cipher with either 20 or 12
+/// rounds (see the `stdrng_*` feature flags, documented in the README).
+/// This may change as new evidence of cipher security and performance
+/// becomes available.
///
-/// Reproducibility of output from this generator is however not required, thus
-/// future library versions may use a different internal generator with
-/// different output. Further, this generator may not be portable and can
-/// produce different output depending on the architecture. If you require
-/// reproducible output, use a named RNG, for example [`ChaChaRng`].
+/// The algorithm is deterministic but should not be considered reproducible
+/// due to dependence on configuration and possible replacement in future
+/// library versions. For a secure reproducible generator, we recommend use of
+/// the [rand_chacha] crate directly.
///
-/// [HC-128]: ../../rand_hc/struct.Hc128Rng.html
-/// [`ChaChaRng`]: ../../rand_chacha/struct.ChaChaRng.html
+/// [rand_chacha]: https://crates.io/crates/rand_chacha
#[derive(Clone, Debug)]
-pub struct StdRng(Hc128Rng);
+pub struct StdRng(Rng);
impl RngCore for StdRng {
#[inline(always)]
@@ -39,24 +44,28 @@ impl RngCore for StdRng {
self.0.next_u64()
}
+ #[inline(always)]
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.0.fill_bytes(dest);
}
+ #[inline(always)]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
self.0.try_fill_bytes(dest)
}
}
impl SeedableRng for StdRng {
- type Seed = <Hc128Rng as SeedableRng>::Seed;
+ type Seed = <Rng as SeedableRng>::Seed;
+ #[inline(always)]
fn from_seed(seed: Self::Seed) -> Self {
- StdRng(Hc128Rng::from_seed(seed))
+ StdRng(Rng::from_seed(seed))
}
+ #[inline(always)]
fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
- Hc128Rng::from_rng(rng).map(StdRng)
+ Rng::from_rng(rng).map(StdRng)
}
}
@@ -65,17 +74,27 @@ impl CryptoRng for StdRng {}
#[cfg(test)]
mod test {
- use {RngCore, SeedableRng};
- use rngs::StdRng;
+ use crate::{RngCore, SeedableRng};
+ use crate::rngs::StdRng;
#[test]
fn test_stdrng_construction() {
+ // Test value-stability of StdRng. This is expected to break any time
+ // the algorithm is changed.
let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
- let mut rng1 = StdRng::from_seed(seed);
- assert_eq!(rng1.next_u64(), 15759097995037006553);
- let mut rng2 = StdRng::from_rng(rng1).unwrap();
- assert_eq!(rng2.next_u64(), 6766915756997287454);
+ #[cfg(any(feature="stdrng_strong", not(feature="stdrng_fast")))]
+ let target = [3950704604716924505, 5573172343717151650];
+ #[cfg(all(not(feature="stdrng_strong"), feature="stdrng_fast"))]
+ let target = [10719222850664546238, 14064965282130556830];
+
+ let mut rng0 = StdRng::from_seed(seed);
+ let x0 = rng0.next_u64();
+
+ let mut rng1 = StdRng::from_rng(rng0).unwrap();
+ let x1 = rng1.next_u64();
+
+ assert_eq!([x0, x1], target);
}
}