1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
/*!
Random number generators.
Pseudorandom number generators
-------------------------------
These generators implement fast PRNG which are suitable for normal use in non-cryptography applications.
* [`SplitMix64`](SplitMix64) Rng:
Simple 64-bit state generator uses wrapping addition, wrapping multiplication, XOR and shifts.
* [`Xoshiro256`](Xoshiro256) Rng:
Kindly taken from [Sebastiano Vigna](http://vigna.di.unimi.it/)'s excellent [PRNG shootout](http://prng.di.unimi.it/) article.
Cryptographically secure generators
-----------------------------------
These generators implement suitable CSPRNG implementations without calling out to the system or hardware directly.
* [`ChaCha20`](ChaCha20) Rng:
Daniel J. Bernstein's ChaCha20 adapted as a deterministic random number generator.
*/
#![allow(unsafe_code)]
use crate::Random;
/// Random number generator interface.
pub trait Rng {
/// Returns the next `u32` in the sequence.
fn next_u32(&mut self) -> u32;
/// Returns the next `u64` in the sequence.
fn next_u64(&mut self) -> u64;
/// Returns a uniform random `f32` in the half-open interval `[1.0, 2.0)`.
///
/// As only 23 bits are necessary to construct a random float in this range,
/// implementations may override this method to provide a more efficient implementation.
///
/// The default implementation simply gets its random bits from `next_u32`.
fn next_f32(&mut self) -> f32 {
crate::impls::rng_f32(self.next_u32())
}
/// Returns a uniform random `f64` in the half-open interval `[1.0, 2.0)`.
///
/// As only 52 bits are necessary to construct a random double in this range,
/// implementations may override this method to provide a more efficient implementation.
///
/// The default implementation simply gets its random bits from `next_u64`.
fn next_f64(&mut self) -> f64 {
crate::impls::rng_f64(self.next_u64())
}
/// Fills the next `u32` elements in the sequence.
///
/// Implementations are not required to implement this method with `next_u32`.
/// This may produce distinct values compared to filling naively with `next_u32`.
///
/// Implementations are required to produce the same result regardless of endianness.
fn fill_u32(&mut self, buffer: &mut [u32]);
/// Fills the next `u64` elements in the sequence.
fn fill_u64(&mut self, buffer: &mut [u64]);
/// Fills the byte slice with uniform random bytes.
///
/// Implementations are required to produce the same result regardless of endianness.
fn fill_bytes(&mut self, buffer: &mut [u8]);
/// Advances the internal state significantly.
///
/// Useful to produce deterministic independent random number generators for parallel computation.
fn jump(&mut self);
}
/// Constructors for deterministic random number generators.
pub trait SeedRng: Sized {
/// Creates a new instance seeded securely from system entropy.
///
/// This method is the recommended way to construct PRNGs since it is convenient and secure.
///
/// # Panics
///
/// If [`getentropy`](getentropy) is unable to provide secure entropy this method will panic.
fn new() -> Random<Self>;
/// Creates a new PRNG seeded from another `Rng`.
///
/// This may be useful when needing to rapidly seed many PRNGs from a master PRNG, and to allow forking of PRNGs.
///
/// The master PRNG should use a sufficiently different algorithm from the child PRNG (ideally a CSPRNG) to avoid correlations between the child PRNGs.
fn from_rng<R: Rng + ?Sized>(rng: &mut Random<R>) -> Random<Self>;
/// Creates a new PRNG using the given seed.
///
/// The seed is not required to look random, the PRNG constructor must ensure it can handle degenerate seed values by mixing it first.
/// The PRNG constructor should not panic on degenerate seed values (such as zero) and instead replace it with something else.
///
/// This **is not suitable for cryptography**, as should be clear given that the input size is only 64 bits.
///
/// Implementations are required to be reproducible given the same seed.
/// _Changing_ the implementation of this function should be considered a breaking change.
fn from_seed(seed: u64) -> Random<Self>;
}
macro_rules! forward_seed_rng_impl {
($ty:ty) => {
impl $ty {
/// Creates a new instance seeded securely from system entropy.
///
/// See the [`SeedRng`](SeedRng::new) trait for more information.
#[inline]
pub fn new() -> Random<$ty> {
SeedRng::new()
}
/// Creates a new PRNG seeded from another `Rng`.
///
/// See the [`SeedRng`](SeedRng::from_rng) trait for more information.
#[inline]
pub fn from_rng<R: Rng + ?Sized>(rng: &mut Random<R>) -> Random<$ty> {
SeedRng::from_rng(rng)
}
/// Creates a new PRNG using the given seed.
///
/// See the [`SeedRng`](SeedRng::from_seed) trait for more information.
#[inline]
pub fn from_seed(seed: u64) -> Random<$ty> {
SeedRng::from_seed(seed)
}
}
}
}
//----------------------------------------------------------------
// Random number generators
mod splitmix64;
pub use self::splitmix64::SplitMix64;
mod xoshiro256;
pub use self::xoshiro256::Xoshiro256;
mod mock;
pub use self::mock::MockRng;
cfg_if::cfg_if! {
if #[cfg(feature = "std")] {
mod read;
pub use self::read::ReadRng;
}
}
mod chacha20;
pub use self::chacha20::ChaCha20;
mod entropy;
pub use self::entropy::getentropy;
//----------------------------------------------------------------
#[test]
fn test_trait_object() {
// Ensure Rng is usable as a trait object
let mut rng = crate::new();
fn test(rng: &mut Random<dyn Rng>) {
let _: i32 = rng.next();
}
test(&mut rng);
}