aboutsummaryrefslogtreecommitdiff
path: root/rand/src/rngs
diff options
context:
space:
mode:
Diffstat (limited to 'rand/src/rngs')
-rw-r--r--rand/src/rngs/adapter/mod.rs15
-rw-r--r--rand/src/rngs/adapter/read.rs148
-rw-r--r--rand/src/rngs/adapter/reseeding.rs357
-rw-r--r--rand/src/rngs/entropy.rs76
-rw-r--r--rand/src/rngs/mock.rs64
-rw-r--r--rand/src/rngs/mod.rs119
-rw-r--r--rand/src/rngs/small.rs115
-rw-r--r--rand/src/rngs/std.rs100
-rw-r--r--rand/src/rngs/thread.rs124
9 files changed, 0 insertions, 1118 deletions
diff --git a/rand/src/rngs/adapter/mod.rs b/rand/src/rngs/adapter/mod.rs
deleted file mode 100644
index 659ff26..0000000
--- a/rand/src/rngs/adapter/mod.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// 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.
-
-//! Wrappers / adapters forming RNGs
-
-#[cfg(feature="std")] mod read;
-mod reseeding;
-
-#[cfg(feature="std")] pub use self::read::{ReadRng, ReadError};
-pub use self::reseeding::ReseedingRng;
diff --git a/rand/src/rngs/adapter/read.rs b/rand/src/rngs/adapter/read.rs
deleted file mode 100644
index 901462e..0000000
--- a/rand/src/rngs/adapter/read.rs
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-// Copyright 2013 The Rust Project Developers.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// 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.
-
-//! A wrapper around any Read to treat it as an RNG.
-
-use std::io::Read;
-use std::fmt;
-
-use rand_core::{RngCore, Error, impls};
-
-
-/// An RNG that reads random bytes straight from any type supporting
-/// [`std::io::Read`], for example files.
-///
-/// This will work best with an infinite reader, but that is not required.
-///
-/// This can be used with `/dev/urandom` on Unix but it is recommended to use
-/// [`OsRng`] instead.
-///
-/// # Panics
-///
-/// `ReadRng` uses [`std::io::Read::read_exact`], which retries on interrupts.
-/// All other errors from the underlying reader, including when it does not
-/// have enough data, will only be reported through [`try_fill_bytes`].
-/// The other [`RngCore`] methods will panic in case of an error.
-///
-/// # Example
-///
-/// ```
-/// use rand::Rng;
-/// use rand::rngs::adapter::ReadRng;
-///
-/// let data = vec![1, 2, 3, 4, 5, 6, 7, 8];
-/// let mut rng = ReadRng::new(&data[..]);
-/// println!("{:x}", rng.gen::<u32>());
-/// ```
-///
-/// [`OsRng`]: crate::rngs::OsRng
-/// [`try_fill_bytes`]: RngCore::try_fill_bytes
-#[derive(Debug)]
-pub struct ReadRng<R> {
- reader: R
-}
-
-impl<R: Read> ReadRng<R> {
- /// Create a new `ReadRng` from a `Read`.
- pub fn new(r: R) -> ReadRng<R> {
- ReadRng {
- reader: r
- }
- }
-}
-
-impl<R: Read> RngCore for ReadRng<R> {
- fn next_u32(&mut self) -> u32 {
- impls::next_u32_via_fill(self)
- }
-
- fn next_u64(&mut self) -> u64 {
- impls::next_u64_via_fill(self)
- }
-
- fn fill_bytes(&mut self, dest: &mut [u8]) {
- self.try_fill_bytes(dest).unwrap_or_else(|err|
- panic!("reading random bytes from Read implementation failed; error: {}", err));
- }
-
- fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
- if dest.is_empty() { return Ok(()); }
- // Use `std::io::read_exact`, which retries on `ErrorKind::Interrupted`.
- self.reader.read_exact(dest).map_err(|e| Error::new(ReadError(e)))
- }
-}
-
-/// `ReadRng` error type
-#[derive(Debug)]
-pub struct ReadError(std::io::Error);
-
-impl fmt::Display for ReadError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "ReadError: {}", self.0)
- }
-}
-
-impl std::error::Error for ReadError {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- Some(&self.0)
- }
-}
-
-
-#[cfg(test)]
-mod test {
- use super::ReadRng;
- use crate::RngCore;
-
- #[test]
- fn test_reader_rng_u64() {
- // transmute from the target to avoid endianness concerns.
- let v = vec![0u8, 0, 0, 0, 0, 0, 0, 1,
- 0 , 0, 0, 0, 0, 0, 0, 2,
- 0, 0, 0, 0, 0, 0, 0, 3];
- let mut rng = ReadRng::new(&v[..]);
-
- assert_eq!(rng.next_u64(), 1_u64.to_be());
- assert_eq!(rng.next_u64(), 2_u64.to_be());
- assert_eq!(rng.next_u64(), 3_u64.to_be());
- }
-
- #[test]
- fn test_reader_rng_u32() {
- let v = vec![0u8, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3];
- let mut rng = ReadRng::new(&v[..]);
-
- assert_eq!(rng.next_u32(), 1_u32.to_be());
- assert_eq!(rng.next_u32(), 2_u32.to_be());
- assert_eq!(rng.next_u32(), 3_u32.to_be());
- }
-
- #[test]
- fn test_reader_rng_fill_bytes() {
- let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let mut w = [0u8; 8];
-
- let mut rng = ReadRng::new(&v[..]);
- rng.fill_bytes(&mut w);
-
- assert!(v == w);
- }
-
- #[test]
- fn test_reader_rng_insufficient_bytes() {
- let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let mut w = [0u8; 9];
-
- let mut rng = ReadRng::new(&v[..]);
-
- let result = rng.try_fill_bytes(&mut w);
- assert!(result.is_err());
- println!("Error: {}", result.unwrap_err());
- }
-}
diff --git a/rand/src/rngs/adapter/reseeding.rs b/rand/src/rngs/adapter/reseeding.rs
deleted file mode 100644
index ec88efe..0000000
--- a/rand/src/rngs/adapter/reseeding.rs
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-// Copyright 2013 The Rust Project Developers.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// 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.
-
-//! A wrapper around another PRNG that reseeds it after it
-//! generates a certain number of random bytes.
-
-use core::mem::size_of;
-
-use rand_core::{RngCore, CryptoRng, SeedableRng, Error};
-use rand_core::block::{BlockRngCore, BlockRng};
-
-/// A wrapper around any PRNG that implements [`BlockRngCore`], that adds the
-/// ability to reseed it.
-///
-/// `ReseedingRng` reseeds the underlying PRNG in the following cases:
-///
-/// - On a manual call to [`reseed()`].
-/// - After `clone()`, the clone will be reseeded on first use.
-/// - After a process is forked, the RNG in the child process is reseeded within
-/// the next few generated values, depending on the block size of the
-/// underlying PRNG. For ChaCha and Hc128 this is a maximum of
-/// 15 `u32` values before reseeding.
-/// - After the PRNG has generated a configurable number of random bytes.
-///
-/// # When should reseeding after a fixed number of generated bytes be used?
-///
-/// Reseeding after a fixed number of generated bytes is never strictly
-/// *necessary*. Cryptographic PRNGs don't have a limited number of bytes they
-/// can output, or at least not a limit reachable in any practical way. There is
-/// no such thing as 'running out of entropy'.
-///
-/// Occasionally reseeding can be seen as some form of 'security in depth'. Even
-/// if in the future a cryptographic weakness is found in the CSPRNG being used,
-/// or a flaw in the implementation, occasionally reseeding should make
-/// exploiting it much more difficult or even impossible.
-///
-/// Use [`ReseedingRng::new`] with a `threshold` of `0` to disable reseeding
-/// after a fixed number of generated bytes.
-///
-/// # Error handling
-///
-/// Although unlikely, reseeding the wrapped PRNG can fail. `ReseedingRng` will
-/// never panic but try to handle the error intelligently through some
-/// combination of retrying and delaying reseeding until later.
-/// If handling the source error fails `ReseedingRng` will continue generating
-/// data from the wrapped PRNG without reseeding.
-///
-/// Manually calling [`reseed()`] will not have this retry or delay logic, but
-/// reports the error.
-///
-/// # Example
-///
-/// ```
-/// use rand::prelude::*;
-/// use rand_chacha::ChaCha20Core; // Internal part of ChaChaRng that
-/// // implements BlockRngCore
-/// use rand::rngs::OsRng;
-/// use rand::rngs::adapter::ReseedingRng;
-///
-/// let prng = ChaCha20Core::from_entropy();
-/// let mut reseeding_rng = ReseedingRng::new(prng, 0, OsRng);
-///
-/// println!("{}", reseeding_rng.gen::<u64>());
-///
-/// let mut cloned_rng = reseeding_rng.clone();
-/// assert!(reseeding_rng.gen::<u64>() != cloned_rng.gen::<u64>());
-/// ```
-///
-/// [`BlockRngCore`]: rand_core::block::BlockRngCore
-/// [`ReseedingRng::new`]: ReseedingRng::new
-/// [`reseed()`]: ReseedingRng::reseed
-#[derive(Debug)]
-pub struct ReseedingRng<R, Rsdr>(BlockRng<ReseedingCore<R, Rsdr>>)
-where R: BlockRngCore + SeedableRng,
- Rsdr: RngCore;
-
-impl<R, Rsdr> ReseedingRng<R, Rsdr>
-where R: BlockRngCore + SeedableRng,
- Rsdr: RngCore
-{
- /// Create a new `ReseedingRng` from an existing PRNG, combined with a RNG
- /// to use as reseeder.
- ///
- /// `threshold` sets the number of generated bytes after which to reseed the
- /// PRNG. Set it to zero to never reseed based on the number of generated
- /// values.
- pub fn new(rng: R, threshold: u64, reseeder: Rsdr) -> Self {
- ReseedingRng(BlockRng::new(ReseedingCore::new(rng, threshold, reseeder)))
- }
-
- /// Reseed the internal PRNG.
- pub fn reseed(&mut self) -> Result<(), Error> {
- self.0.core.reseed()
- }
-}
-
-// TODO: this should be implemented for any type where the inner type
-// implements RngCore, but we can't specify that because ReseedingCore is private
-impl<R, Rsdr: RngCore> RngCore for ReseedingRng<R, Rsdr>
-where R: BlockRngCore<Item = u32> + SeedableRng,
- <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>
-{
- #[inline(always)]
- fn next_u32(&mut self) -> u32 {
- self.0.next_u32()
- }
-
- #[inline(always)]
- fn next_u64(&mut self) -> u64 {
- self.0.next_u64()
- }
-
- fn fill_bytes(&mut self, dest: &mut [u8]) {
- self.0.fill_bytes(dest)
- }
-
- fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
- self.0.try_fill_bytes(dest)
- }
-}
-
-impl<R, Rsdr> Clone for ReseedingRng<R, Rsdr>
-where R: BlockRngCore + SeedableRng + Clone,
- Rsdr: RngCore + Clone
-{
- fn clone(&self) -> ReseedingRng<R, Rsdr> {
- // Recreating `BlockRng` seems easier than cloning it and resetting
- // the index.
- ReseedingRng(BlockRng::new(self.0.core.clone()))
- }
-}
-
-impl<R, Rsdr> CryptoRng for ReseedingRng<R, Rsdr>
-where R: BlockRngCore + SeedableRng + CryptoRng,
- Rsdr: RngCore + CryptoRng {}
-
-#[derive(Debug)]
-struct ReseedingCore<R, Rsdr> {
- inner: R,
- reseeder: Rsdr,
- threshold: i64,
- bytes_until_reseed: i64,
- fork_counter: usize,
-}
-
-impl<R, Rsdr> BlockRngCore for ReseedingCore<R, Rsdr>
-where R: BlockRngCore + SeedableRng,
- Rsdr: RngCore
-{
- type Item = <R as BlockRngCore>::Item;
- type Results = <R as BlockRngCore>::Results;
-
- fn generate(&mut self, results: &mut Self::Results) {
- let global_fork_counter = fork::get_fork_counter();
- if self.bytes_until_reseed <= 0 ||
- self.is_forked(global_fork_counter) {
- // We get better performance by not calling only `reseed` here
- // and continuing with the rest of the function, but by directly
- // returning from a non-inlined function.
- return self.reseed_and_generate(results, global_fork_counter);
- }
- let num_bytes = results.as_ref().len() * size_of::<Self::Item>();
- self.bytes_until_reseed -= num_bytes as i64;
- self.inner.generate(results);
- }
-}
-
-impl<R, Rsdr> ReseedingCore<R, Rsdr>
-where R: BlockRngCore + SeedableRng,
- Rsdr: RngCore
-{
- /// Create a new `ReseedingCore`.
- fn new(rng: R, threshold: u64, reseeder: Rsdr) -> Self {
- use ::core::i64::MAX;
- fork::register_fork_handler();
-
- // Because generating more values than `i64::MAX` takes centuries on
- // current hardware, we just clamp to that value.
- // Also we set a threshold of 0, which indicates no limit, to that
- // value.
- let threshold =
- if threshold == 0 { MAX }
- else if threshold <= MAX as u64 { threshold as i64 }
- else { MAX };
-
- ReseedingCore {
- inner: rng,
- reseeder,
- threshold: threshold as i64,
- bytes_until_reseed: threshold as i64,
- fork_counter: 0,
- }
- }
-
- /// Reseed the internal PRNG.
- fn reseed(&mut self) -> Result<(), Error> {
- R::from_rng(&mut self.reseeder).map(|result| {
- self.bytes_until_reseed = self.threshold;
- self.inner = result
- })
- }
-
- fn is_forked(&self, global_fork_counter: usize) -> bool {
- // In theory, on 32-bit platforms, it is possible for
- // `global_fork_counter` to wrap around after ~4e9 forks.
- //
- // This check will detect a fork in the normal case where
- // `fork_counter < global_fork_counter`, and also when the difference
- // between both is greater than `isize::MAX` (wrapped around).
- //
- // It will still fail to detect a fork if there have been more than
- // `isize::MAX` forks, without any reseed in between. Seems unlikely
- // enough.
- (self.fork_counter.wrapping_sub(global_fork_counter) as isize) < 0
- }
-
- #[inline(never)]
- fn reseed_and_generate(&mut self,
- results: &mut <Self as BlockRngCore>::Results,
- global_fork_counter: usize)
- {
- #![allow(clippy::if_same_then_else)] // false positive
- if self.is_forked(global_fork_counter) {
- info!("Fork detected, reseeding RNG");
- } else {
- trace!("Reseeding RNG (periodic reseed)");
- }
-
- let num_bytes =
- results.as_ref().len() * size_of::<<R as BlockRngCore>::Item>();
-
- if let Err(e) = self.reseed() {
- warn!("Reseeding RNG failed: {}", e);
- let _ = e;
- }
- self.fork_counter = global_fork_counter;
-
- self.bytes_until_reseed = self.threshold - num_bytes as i64;
- self.inner.generate(results);
- }
-}
-
-impl<R, Rsdr> Clone for ReseedingCore<R, Rsdr>
-where R: BlockRngCore + SeedableRng + Clone,
- Rsdr: RngCore + Clone
-{
- fn clone(&self) -> ReseedingCore<R, Rsdr> {
- ReseedingCore {
- inner: self.inner.clone(),
- reseeder: self.reseeder.clone(),
- threshold: self.threshold,
- bytes_until_reseed: 0, // reseed clone on first use
- fork_counter: self.fork_counter,
- }
- }
-}
-
-impl<R, Rsdr> CryptoRng for ReseedingCore<R, Rsdr>
-where R: BlockRngCore + SeedableRng + CryptoRng,
- Rsdr: RngCore + CryptoRng {}
-
-
-#[cfg(all(unix, not(target_os="emscripten")))]
-mod fork {
- use core::sync::atomic::{AtomicUsize, AtomicBool, Ordering};
- #[allow(deprecated)] // Required for compatibility with Rust < 1.24.
- use core::sync::atomic::{ATOMIC_USIZE_INIT, ATOMIC_BOOL_INIT};
-
- // Fork protection
- //
- // We implement fork protection on Unix using `pthread_atfork`.
- // When the process is forked, we increment `RESEEDING_RNG_FORK_COUNTER`.
- // Every `ReseedingRng` stores the last known value of the static in
- // `fork_counter`. If the cached `fork_counter` is less than
- // `RESEEDING_RNG_FORK_COUNTER`, it is time to reseed this RNG.
- //
- // If reseeding fails, we don't deal with this by setting a delay, but just
- // don't update `fork_counter`, so a reseed is attempted as soon as
- // possible.
-
- #[allow(deprecated)]
- static RESEEDING_RNG_FORK_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
-
- pub fn get_fork_counter() -> usize {
- RESEEDING_RNG_FORK_COUNTER.load(Ordering::Relaxed)
- }
-
- #[allow(deprecated)]
- static FORK_HANDLER_REGISTERED: AtomicBool = ATOMIC_BOOL_INIT;
-
- extern fn fork_handler() {
- // Note: fetch_add is defined to wrap on overflow
- // (which is what we want).
- RESEEDING_RNG_FORK_COUNTER.fetch_add(1, Ordering::Relaxed);
- }
-
- pub fn register_fork_handler() {
- if !FORK_HANDLER_REGISTERED.load(Ordering::Relaxed) {
- unsafe { libc::pthread_atfork(None, None, Some(fork_handler)) };
- FORK_HANDLER_REGISTERED.store(true, Ordering::Relaxed);
- }
- }
-}
-
-#[cfg(not(all(unix, not(target_os="emscripten"))))]
-mod fork {
- pub fn get_fork_counter() -> usize { 0 }
- pub fn register_fork_handler() {}
-}
-
-
-#[cfg(test)]
-mod test {
- use crate::{Rng, SeedableRng};
- use crate::rngs::std::Core;
- use crate::rngs::mock::StepRng;
- use super::ReseedingRng;
-
- #[test]
- fn test_reseeding() {
- let mut zero = StepRng::new(0, 0);
- let rng = Core::from_rng(&mut zero).unwrap();
- let thresh = 1; // reseed every time the buffer is exhausted
- let mut reseeding = ReseedingRng::new(rng, thresh, zero);
-
- // RNG buffer size is [u32; 64]
- // Debug is only implemented up to length 32 so use two arrays
- let mut buf = ([0u32; 32], [0u32; 32]);
- reseeding.fill(&mut buf.0);
- reseeding.fill(&mut buf.1);
- let seq = buf;
- for _ in 0..10 {
- reseeding.fill(&mut buf.0);
- reseeding.fill(&mut buf.1);
- assert_eq!(buf, seq);
- }
- }
-
- #[test]
- fn test_clone_reseeding() {
- let mut zero = StepRng::new(0, 0);
- let rng = Core::from_rng(&mut zero).unwrap();
- let mut rng1 = ReseedingRng::new(rng, 32*4, zero);
-
- let first: u32 = rng1.gen();
- for _ in 0..10 { let _ = rng1.gen::<u32>(); }
-
- let mut rng2 = rng1.clone();
- assert_eq!(first, rng2.gen::<u32>());
- }
-}
diff --git a/rand/src/rngs/entropy.rs b/rand/src/rngs/entropy.rs
deleted file mode 100644
index 1ed59ab..0000000
--- a/rand/src/rngs/entropy.rs
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// 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.
-
-//! Entropy generator, or wrapper around external generators
-
-#![allow(deprecated)] // whole module is deprecated
-
-use rand_core::{RngCore, CryptoRng, Error};
-use crate::rngs::OsRng;
-
-/// An interface returning random data from external source(s), provided
-/// specifically for securely seeding algorithmic generators (PRNGs).
-///
-/// This is deprecated. It is suggested you use [`rngs::OsRng`] instead.
-///
-/// [`rngs::OsRng`]: crate::rngs::OsRng
-#[derive(Debug)]
-#[deprecated(since="0.7.0", note="use rngs::OsRng instead")]
-pub struct EntropyRng {
- source: OsRng,
-}
-
-impl EntropyRng {
- /// Create a new `EntropyRng`.
- ///
- /// This method will do no system calls or other initialization routines,
- /// those are done on first use. This is done to make `new` infallible,
- /// and `try_fill_bytes` the only place to report errors.
- pub fn new() -> Self {
- EntropyRng { source: OsRng }
- }
-}
-
-impl Default for EntropyRng {
- fn default() -> Self {
- EntropyRng::new()
- }
-}
-
-impl RngCore for EntropyRng {
- fn next_u32(&mut self) -> u32 {
- self.source.next_u32()
- }
-
- fn next_u64(&mut self) -> u64 {
- self.source.next_u64()
- }
-
- fn fill_bytes(&mut self, dest: &mut [u8]) {
- self.source.fill_bytes(dest)
- }
-
- fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
- self.source.try_fill_bytes(dest)
- }
-}
-
-impl CryptoRng for EntropyRng {}
-
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- #[test]
- fn test_entropy() {
- let mut rng = EntropyRng::new();
- let n = (rng.next_u32() ^ rng.next_u32()).count_ones();
- assert!(n >= 2); // p(failure) approx 1e-7
- }
-}
diff --git a/rand/src/rngs/mock.rs b/rand/src/rngs/mock.rs
deleted file mode 100644
index b4081da..0000000
--- a/rand/src/rngs/mock.rs
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// 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.
-
-//! Mock random number generator
-
-use rand_core::{RngCore, Error, impls};
-
-/// A simple implementation of `RngCore` for testing purposes.
-///
-/// This generates an arithmetic sequence (i.e. adds a constant each step)
-/// over a `u64` number, using wrapping arithmetic. If the increment is 0
-/// the generator yields a constant.
-///
-/// ```
-/// use rand::Rng;
-/// use rand::rngs::mock::StepRng;
-///
-/// let mut my_rng = StepRng::new(2, 1);
-/// let sample: [u64; 3] = my_rng.gen();
-/// assert_eq!(sample, [2, 3, 4]);
-/// ```
-#[derive(Debug, Clone)]
-pub struct StepRng {
- v: u64,
- a: u64,
-}
-
-impl StepRng {
- /// Create a `StepRng`, yielding an arithmetic sequence starting with
- /// `initial` and incremented by `increment` each time.
- pub fn new(initial: u64, increment: u64) -> Self {
- StepRng { v: initial, a: increment }
- }
-}
-
-impl RngCore for StepRng {
- #[inline]
- fn next_u32(&mut self) -> u32 {
- self.next_u64() as u32
- }
-
- #[inline]
- fn next_u64(&mut self) -> u64 {
- let result = self.v;
- self.v = self.v.wrapping_add(self.a);
- result
- }
-
- #[inline]
- fn fill_bytes(&mut self, dest: &mut [u8]) {
- impls::fill_bytes_via_next(self, dest);
- }
-
- #[inline]
- fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
- self.fill_bytes(dest);
- Ok(())
- }
-}
diff --git a/rand/src/rngs/mod.rs b/rand/src/rngs/mod.rs
deleted file mode 100644
index abf3243..0000000
--- a/rand/src/rngs/mod.rs
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// 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.
-
-//! Random number generators and adapters
-//!
-//! ## Background: Random number generators (RNGs)
-//!
-//! Computers cannot produce random numbers from nowhere. We classify
-//! random number generators as follows:
-//!
-//! - "True" random number generators (TRNGs) use hard-to-predict data sources
-//! (e.g. the high-resolution parts of event timings and sensor jitter) to
-//! harvest random bit-sequences, apply algorithms to remove bias and
-//! estimate available entropy, then combine these bits into a byte-sequence
-//! or an entropy pool. This job is usually done by the operating system or
-//! a hardware generator (HRNG).
-//! - "Pseudo"-random number generators (PRNGs) use algorithms to transform a
-//! seed into a sequence of pseudo-random numbers. These generators can be
-//! fast and produce well-distributed unpredictable random numbers (or not).
-//! They are usually deterministic: given algorithm and seed, the output
-//! sequence can be reproduced. They have finite period and eventually loop;
-//! with many algorithms this period is fixed and can be proven sufficiently
-//! long, while others are chaotic and the period depends on the seed.
-//! - "Cryptographically secure" pseudo-random number generators (CSPRNGs)
-//! are the sub-set of PRNGs which are secure. Security of the generator
-//! relies both on hiding the internal state and using a strong algorithm.
-//!
-//! ## Traits and functionality
-//!
-//! All RNGs implement the [`RngCore`] trait, as a consequence of which the
-//! [`Rng`] extension trait is automatically implemented. Secure RNGs may
-//! additionally implement the [`CryptoRng`] trait.
-//!
-//! All PRNGs require a seed to produce their random number sequence. The
-//! [`SeedableRng`] trait provides three ways of constructing PRNGs:
-//!
-//! - `from_seed` accepts a type specific to the PRNG
-//! - `from_rng` allows a PRNG to be seeded from any other RNG
-//! - `seed_from_u64` allows any PRNG to be seeded from a `u64` insecurely
-//! - `from_entropy` securely seeds a PRNG from fresh entropy
-//!
-//! Use the [`rand_core`] crate when implementing your own RNGs.
-//!
-//! ## Our generators
-//!
-//! This crate provides several random number generators:
-//!
-//! - [`OsRng`] is an interface to the operating system's random number
-//! source. Typically the operating system uses a CSPRNG with entropy
-//! provided by a TRNG and some type of on-going re-seeding.
-//! - [`ThreadRng`], provided by the [`thread_rng`] function, is a handle to a
-//! thread-local CSPRNG with periodic seeding from [`OsRng`]. Because this
-//! is local, it is typically much faster than [`OsRng`]. It should be
-//! secure, though the paranoid may prefer [`OsRng`].
-//! - [`StdRng`] is a CSPRNG chosen for good performance and trust of security
-//! (based on reviews, maturity and usage). The current algorithm is ChaCha20,
-//! which is well established and rigorously analysed.
-//! [`StdRng`] provides the algorithm used by [`ThreadRng`] but without
-//! periodic reseeding.
-//! - [`SmallRng`] is an **insecure** PRNG designed to be fast, simple, require
-//! little memory, and have good output quality.
-//!
-//! The algorithms selected for [`StdRng`] and [`SmallRng`] may change in any
-//! release and may be platform-dependent, therefore they should be considered
-//! **not reproducible**.
-//!
-//! ## Additional generators
-//!
-//! **TRNGs**: The [`rdrand`] crate provides an interface to the RDRAND and
-//! RDSEED instructions available in modern Intel and AMD CPUs.
-//! The [`rand_jitter`] crate provides a user-space implementation of
-//! entropy harvesting from CPU timer jitter, but is very slow and has
-//! [security issues](https://github.com/rust-random/rand/issues/699).
-//!
-//! **PRNGs**: Several companion crates are available, providing individual or
-//! families of PRNG algorithms. These provide the implementations behind
-//! [`StdRng`] and [`SmallRng`] but can also be used directly, indeed *should*
-//! be used directly when **reproducibility** matters.
-//! Some suggestions are: [`rand_chacha`], [`rand_pcg`], [`rand_xoshiro`].
-//! A full list can be found by searching for crates with the [`rng` tag].
-//!
-//! [`SmallRng`]: rngs::SmallRng
-//! [`StdRng`]: rngs::StdRng
-//! [`OsRng`]: rngs::OsRng
-//! [`ThreadRng`]: rngs::ThreadRng
-//! [`mock::StepRng`]: rngs::mock::StepRng
-//! [`adapter::ReadRng`]: rngs::adapter::ReadRng
-//! [`adapter::ReseedingRng`]: rngs::adapter::ReseedingRng
-//! [`rdrand`]: https://crates.io/crates/rdrand
-//! [`rand_jitter`]: https://crates.io/crates/rand_jitter
-//! [`rand_chacha`]: https://crates.io/crates/rand_chacha
-//! [`rand_pcg`]: https://crates.io/crates/rand_pcg
-//! [`rand_xoshiro`]: https://crates.io/crates/rand_xoshiro
-//! [`rng` tag]: https://crates.io/keywords/rng
-
-pub mod adapter;
-
-#[cfg(feature="std")] mod entropy;
-pub mod mock; // Public so we don't export `StepRng` directly, making it a bit
- // more clear it is intended for testing.
-#[cfg(feature="small_rng")]
-mod small;
-mod std;
-#[cfg(feature="std")] pub(crate) mod thread;
-
-#[allow(deprecated)]
-#[cfg(feature="std")] pub use self::entropy::EntropyRng;
-
-#[cfg(feature="small_rng")]
-pub use self::small::SmallRng;
-pub use self::std::StdRng;
-#[cfg(feature="std")] pub use self::thread::ThreadRng;
-
-#[cfg(feature="getrandom")] pub use rand_core::OsRng;
diff --git a/rand/src/rngs/small.rs b/rand/src/rngs/small.rs
deleted file mode 100644
index 6571363..0000000
--- a/rand/src/rngs/small.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// 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.
-
-//! A small fast RNG
-
-use rand_core::{RngCore, SeedableRng, Error};
-
-#[cfg(all(not(target_os = "emscripten"), target_pointer_width = "64"))]
-type Rng = rand_pcg::Pcg64Mcg;
-#[cfg(not(all(not(target_os = "emscripten"), target_pointer_width = "64")))]
-type Rng = rand_pcg::Pcg32;
-
-/// A small-state, fast non-crypto PRNG
-///
-/// `SmallRng` may be a good choice when a PRNG with small state, cheap
-/// initialization, good statistical quality and good performance are required.
-/// It is **not** a good choice when security against prediction or
-/// reproducibility are important.
-///
-/// This PRNG is **feature-gated**: to use, you must enable the crate feature
-/// `small_rng`.
-///
-/// The algorithm is deterministic but should not be considered reproducible
-/// due to dependence on platform and possible replacement in future
-/// library versions. For a reproducible generator, use a named PRNG from an
-/// external crate, e.g. [rand_pcg] or [rand_chacha].
-/// Refer also to [The Book](https://rust-random.github.io/book/guide-rngs.html).
-///
-/// The PRNG algorithm in `SmallRng` is chosen to be
-/// efficient on the current platform, without consideration for cryptography
-/// or security. The size of its state is much smaller than [`StdRng`].
-/// The current algorithm is [`Pcg64Mcg`](rand_pcg::Pcg64Mcg) on 64-bit
-/// platforms and [`Pcg32`](rand_pcg::Pcg32) on 32-bit platforms. Both are
-/// implemented by the [rand_pcg] crate.
-///
-/// # Examples
-///
-/// Initializing `SmallRng` with a random seed can be done using [`SeedableRng::from_entropy`]:
-///
-/// ```
-/// use rand::{Rng, SeedableRng};
-/// use rand::rngs::SmallRng;
-///
-/// // Create small, cheap to initialize and fast RNG with a random seed.
-/// // The randomness is supplied by the operating system.
-/// let mut small_rng = SmallRng::from_entropy();
-/// # let v: u32 = small_rng.gen();
-/// ```
-///
-/// When initializing a lot of `SmallRng`'s, using [`thread_rng`] can be more
-/// efficient:
-///
-/// ```
-/// use std::iter;
-/// use rand::{SeedableRng, thread_rng};
-/// use rand::rngs::SmallRng;
-///
-/// // Create a big, expensive to initialize and slower, but unpredictable RNG.
-/// // This is cached and done only once per thread.
-/// let mut thread_rng = thread_rng();
-/// // Create small, cheap to initialize and fast RNGs with random seeds.
-/// // One can generally assume this won't fail.
-/// let rngs: Vec<SmallRng> = iter::repeat(())
-/// .map(|()| SmallRng::from_rng(&mut thread_rng).unwrap())
-/// .take(10)
-/// .collect();
-/// ```
-///
-/// [`StdRng`]: crate::rngs::StdRng
-/// [`thread_rng`]: crate::thread_rng
-/// [rand_chacha]: https://crates.io/crates/rand_chacha
-/// [rand_pcg]: https://crates.io/crates/rand_pcg
-#[derive(Clone, Debug)]
-pub struct SmallRng(Rng);
-
-impl RngCore for SmallRng {
- #[inline(always)]
- fn next_u32(&mut self) -> u32 {
- self.0.next_u32()
- }
-
- #[inline(always)]
- fn next_u64(&mut self) -> u64 {
- 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 SmallRng {
- type Seed = <Rng as SeedableRng>::Seed;
-
- #[inline(always)]
- fn from_seed(seed: Self::Seed) -> Self {
- SmallRng(Rng::from_seed(seed))
- }
-
- #[inline(always)]
- fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
- Rng::from_rng(rng).map(SmallRng)
- }
-}
diff --git a/rand/src/rngs/std.rs b/rand/src/rngs/std.rs
deleted file mode 100644
index 22e08ae..0000000
--- a/rand/src/rngs/std.rs
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// 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.
-
-//! The standard RNG
-
-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 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.
-///
-/// 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.
-///
-/// [rand_chacha]: https://crates.io/crates/rand_chacha
-#[derive(Clone, Debug)]
-pub struct StdRng(Rng);
-
-impl RngCore for StdRng {
- #[inline(always)]
- fn next_u32(&mut self) -> u32 {
- self.0.next_u32()
- }
-
- #[inline(always)]
- fn next_u64(&mut self) -> u64 {
- 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 = <Rng as SeedableRng>::Seed;
-
- #[inline(always)]
- fn from_seed(seed: Self::Seed) -> Self {
- StdRng(Rng::from_seed(seed))
- }
-
- #[inline(always)]
- fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
- Rng::from_rng(rng).map(StdRng)
- }
-}
-
-impl CryptoRng for StdRng {}
-
-
-#[cfg(test)]
-mod test {
- 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];
-
- #[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);
- }
-}
diff --git a/rand/src/rngs/thread.rs b/rand/src/rngs/thread.rs
deleted file mode 100644
index 2006f41..0000000
--- a/rand/src/rngs/thread.rs
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// 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.
-
-//! Thread-local random number generator
-
-use std::cell::UnsafeCell;
-use std::ptr::NonNull;
-
-use crate::{RngCore, CryptoRng, SeedableRng, Error};
-use crate::rngs::adapter::ReseedingRng;
-use crate::rngs::OsRng;
-use super::std::Core;
-
-// Rationale for using `UnsafeCell` in `ThreadRng`:
-//
-// Previously we used a `RefCell`, with an overhead of ~15%. There will only
-// ever be one mutable reference to the interior of the `UnsafeCell`, because
-// we only have such a reference inside `next_u32`, `next_u64`, etc. Within a
-// single thread (which is the definition of `ThreadRng`), there will only ever
-// be one of these methods active at a time.
-//
-// A possible scenario where there could be multiple mutable references is if
-// `ThreadRng` is used inside `next_u32` and co. But the implementation is
-// completely under our control. We just have to ensure none of them use
-// `ThreadRng` internally, which is nonsensical anyway. We should also never run
-// `ThreadRng` in destructors of its implementation, which is also nonsensical.
-
-
-// Number of generated bytes after which to reseed `ThreadRng`.
-// According to benchmarks, reseeding has a noticable impact with thresholds
-// of 32 kB and less. We choose 64 kB to avoid significant overhead.
-const THREAD_RNG_RESEED_THRESHOLD: u64 = 1024 * 64;
-
-/// The type returned by [`thread_rng`], essentially just a reference to the
-/// PRNG in thread-local memory.
-///
-/// `ThreadRng` uses the same PRNG as [`StdRng`] for security and performance.
-/// As hinted by the name, the generator is thread-local. `ThreadRng` is a
-/// handle to this generator and thus supports `Copy`, but not `Send` or `Sync`.
-///
-/// Unlike `StdRng`, `ThreadRng` uses the [`ReseedingRng`] wrapper to reseed
-/// the PRNG from fresh entropy every 64 kiB of random data.
-/// [`OsRng`] is used to provide seed data.
-///
-/// Note that the reseeding is done as an extra precaution against side-channel
-/// attacks and mis-use (e.g. if somehow weak entropy were supplied initially).
-/// The PRNG algorithms used are assumed to be secure.
-///
-/// [`ReseedingRng`]: crate::rngs::adapter::ReseedingRng
-/// [`StdRng`]: crate::rngs::StdRng
-#[derive(Copy, Clone, Debug)]
-pub struct ThreadRng {
- // inner raw pointer implies type is neither Send nor Sync
- rng: NonNull<ReseedingRng<Core, OsRng>>,
-}
-
-thread_local!(
- static THREAD_RNG_KEY: UnsafeCell<ReseedingRng<Core, OsRng>> = {
- let r = Core::from_rng(OsRng).unwrap_or_else(|err|
- panic!("could not initialize thread_rng: {}", err));
- let rng = ReseedingRng::new(r,
- THREAD_RNG_RESEED_THRESHOLD,
- OsRng);
- UnsafeCell::new(rng)
- }
-);
-
-/// Retrieve the lazily-initialized thread-local random number generator,
-/// seeded by the system. Intended to be used in method chaining style,
-/// e.g. `thread_rng().gen::<i32>()`, or cached locally, e.g.
-/// `let mut rng = thread_rng();`. Invoked by the `Default` trait, making
-/// `ThreadRng::default()` equivalent.
-///
-/// For more information see [`ThreadRng`].
-pub fn thread_rng() -> ThreadRng {
- let raw = THREAD_RNG_KEY.with(|t| t.get());
- let nn = NonNull::new(raw).unwrap();
- ThreadRng { rng: nn }
-}
-
-impl Default for ThreadRng {
- fn default() -> ThreadRng {
- crate::prelude::thread_rng()
- }
-}
-
-impl RngCore for ThreadRng {
- #[inline(always)]
- fn next_u32(&mut self) -> u32 {
- unsafe { self.rng.as_mut().next_u32() }
- }
-
- #[inline(always)]
- fn next_u64(&mut self) -> u64 {
- unsafe { self.rng.as_mut().next_u64() }
- }
-
- fn fill_bytes(&mut self, dest: &mut [u8]) {
- unsafe { self.rng.as_mut().fill_bytes(dest) }
- }
-
- fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
- unsafe { self.rng.as_mut().try_fill_bytes(dest) }
- }
-}
-
-impl CryptoRng for ThreadRng {}
-
-
-#[cfg(test)]
-mod test {
- #[test]
- fn test_thread_rng() {
- use crate::Rng;
- let mut r = crate::thread_rng();
- r.gen::<i32>();
- assert_eq!(r.gen_range(0, 1), 0);
- }
-}