std::rand: documentation & references.
Most importantly, links to the papers/references for the core algorithms (the RNG ones & the distribution ones).
This commit is contained in:
parent
148f737c19
commit
e0eb128086
|
@ -8,17 +8,17 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Sampling from random distributions
|
||||
/*!
|
||||
Sampling from random distributions.
|
||||
|
||||
// Some implementations use the Ziggurat method
|
||||
// https://en.wikipedia.org/wiki/Ziggurat_algorithm
|
||||
//
|
||||
// The version used here is ZIGNOR [Doornik 2005, "An Improved
|
||||
// Ziggurat Method to Generate Normal Random Samples"] which is slower
|
||||
// (about double, it generates an extra random number) than the
|
||||
// canonical version [Marsaglia & Tsang 2000, "The Ziggurat Method for
|
||||
// Generating Random Variables"], but more robust. If one wanted, one
|
||||
// could implement VIZIGNOR the ZIGNOR paper for more speed.
|
||||
This is a generalization of `Rand` to allow parameters to control the
|
||||
exact properties of the generated values, e.g. the mean and standard
|
||||
deviation of a normal distribution. The `Sample` trait is the most
|
||||
general, and allows for generating values that change some state
|
||||
internally. The `IndependentSample` trait is for generating values
|
||||
that do not need to record state.
|
||||
|
||||
*/
|
||||
|
||||
use num;
|
||||
use rand::{Rng,Rand};
|
||||
|
@ -27,16 +27,18 @@ pub use self::range::Range;
|
|||
|
||||
pub mod range;
|
||||
|
||||
/// Things that can be used to create a random instance of `Support`.
|
||||
/// Types that can be used to create a random instance of `Support`.
|
||||
pub trait Sample<Support> {
|
||||
/// Generate a random value of `Support`, using `rng` as the
|
||||
/// source of randomness.
|
||||
fn sample<R: Rng>(&mut self, rng: &mut R) -> Support;
|
||||
}
|
||||
|
||||
/// `Sample`s that do not require keeping track of state, so each
|
||||
/// sample is (statistically) independent of all others, assuming the
|
||||
/// `Rng` used has this property.
|
||||
/// `Sample`s that do not require keeping track of state.
|
||||
///
|
||||
/// Since no state is recored, each sample is (statistically)
|
||||
/// independent of all others, assuming the `Rng` used has this
|
||||
/// property.
|
||||
// XXX maybe having this separate is overkill (the only reason is to
|
||||
// take &self rather than &mut self)? or maybe this should be the
|
||||
// trait called `Sample` and the other should be `DependentSample`.
|
||||
|
@ -91,13 +93,19 @@ fn ziggurat<R:Rng>(rng: &mut R,
|
|||
}
|
||||
}
|
||||
|
||||
/// A wrapper around an `f64` to generate N(0, 1) random numbers (a.k.a. a
|
||||
/// standard normal, or Gaussian). Multiplying the generated values by the
|
||||
/// desired standard deviation `sigma` then adding the desired mean `mu` will
|
||||
/// give N(mu, sigma^2) distributed random numbers.
|
||||
/// A wrapper around an `f64` to generate N(0, 1) random numbers
|
||||
/// (a.k.a. a standard normal, or Gaussian).
|
||||
///
|
||||
/// Note that this has to be unwrapped before use as an `f64` (using either
|
||||
/// `*` or `cast::transmute` is safe).
|
||||
/// See `Normal` for the general normal distribution. That this has to
|
||||
/// be unwrapped before use as an `f64` (using either `*` or
|
||||
/// `cast::transmute` is safe).
|
||||
///
|
||||
/// Implemented via the ZIGNOR variant[1] of the Ziggurat method.
|
||||
///
|
||||
/// [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
|
||||
/// Generate Normal Random
|
||||
/// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
|
||||
/// College, Oxford
|
||||
pub struct StandardNormal(f64);
|
||||
|
||||
impl Rand for StandardNormal {
|
||||
|
@ -135,8 +143,10 @@ impl Rand for StandardNormal {
|
|||
}
|
||||
}
|
||||
|
||||
/// The `N(mean, std_dev**2)` distribution, i.e. samples from a normal
|
||||
/// distribution with mean `mean` and standard deviation `std_dev`.
|
||||
/// The normal distribution `N(mean, std_dev**2)`.
|
||||
///
|
||||
/// This uses the ZIGNOR variant of the Ziggurat method, see
|
||||
/// `StandardNormal` for more details.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -175,12 +185,20 @@ impl IndependentSample<f64> for Normal {
|
|||
}
|
||||
}
|
||||
|
||||
/// A wrapper around an `f64` to generate Exp(1) random numbers. Dividing by
|
||||
/// the desired rate `lambda` will give Exp(lambda) distributed random
|
||||
/// numbers.
|
||||
/// A wrapper around an `f64` to generate Exp(1) random numbers.
|
||||
///
|
||||
/// Note that this has to be unwrapped before use as an `f64` (using either
|
||||
/// See `Exp` for the general exponential distribution.Note that this
|
||||
// has to be unwrapped before use as an `f64` (using either
|
||||
/// `*` or `cast::transmute` is safe).
|
||||
///
|
||||
/// Implemented via the ZIGNOR variant[1] of the Ziggurat method. The
|
||||
/// exact description in the paper was adjusted to use tables for the
|
||||
/// exponential distribution rather than normal.
|
||||
///
|
||||
/// [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
|
||||
/// Generate Normal Random
|
||||
/// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
|
||||
/// College, Oxford
|
||||
pub struct Exp1(f64);
|
||||
|
||||
// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
|
||||
|
@ -203,8 +221,7 @@ impl Rand for Exp1 {
|
|||
}
|
||||
}
|
||||
|
||||
/// The `Exp(lambda)` distribution; i.e. samples from the exponential
|
||||
/// distribution with rate parameter `lambda`.
|
||||
/// The exponential distribution `Exp(lambda)`.
|
||||
///
|
||||
/// This distribution has density function: `f(x) = lambda *
|
||||
/// exp(-lambda * x)` for `x > 0`.
|
||||
|
|
|
@ -18,10 +18,15 @@ use option::{None, Some};
|
|||
static RAND_SIZE_LEN: u32 = 8;
|
||||
static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
|
||||
|
||||
/// A random number generator that uses the [ISAAC
|
||||
/// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29).
|
||||
/// A random number generator that uses the ISAAC algorithm[1].
|
||||
///
|
||||
/// The ISAAC algorithm is suitable for cryptographic purposes.
|
||||
/// 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)
|
||||
pub struct IsaacRng {
|
||||
priv cnt: u32,
|
||||
priv rsl: [u32, .. RAND_SIZE],
|
||||
|
@ -212,11 +217,16 @@ impl<'self> SeedableRng<&'self [u32]> for IsaacRng {
|
|||
static RAND_SIZE_64_LEN: uint = 8;
|
||||
static RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN;
|
||||
|
||||
/// A random number generator that uses the 64-bit variant of the
|
||||
/// [ISAAC
|
||||
/// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29).
|
||||
/// A random number generator that uses ISAAC-64[1], the 64-bit
|
||||
/// variant of the ISAAC algorithm.
|
||||
///
|
||||
/// The ISAAC algorithm is suitable for cryptographic purposes.
|
||||
/// 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)
|
||||
pub struct Isaac64Rng {
|
||||
priv cnt: uint,
|
||||
priv rsl: [u64, .. RAND_SIZE_64],
|
||||
|
|
|
@ -28,6 +28,23 @@ from an operating-system source of randomness, e.g. `/dev/urandom` on
|
|||
Unix systems, and will automatically reseed itself from this source
|
||||
after generating 32 KiB of random data.
|
||||
|
||||
# Cryptographic security
|
||||
|
||||
An application that requires random numbers for cryptographic purposes
|
||||
should prefer `OSRng`, which reads randomness from one of the source
|
||||
that the operating system provides (e.g. `/dev/urandom` on
|
||||
Unixes). The other random number generators provided by this module
|
||||
are either known to be insecure (`XorShiftRng`), or are not verified
|
||||
to be secure (`IsaacRng`, `Isaac64Rng` and `StdRng`).
|
||||
|
||||
*Note*: on Linux, `/dev/random` is more secure than `/dev/urandom`,
|
||||
but it is a blocking RNG, and will wait until it has determined that
|
||||
it has collected enough entropy to fulfill a request for random
|
||||
data. It can be used with the `Rng` trait provided by this module by
|
||||
opening the file and passing it to `reader::ReaderRng`. Since it
|
||||
blocks, `/dev/random` should only be used to retrieve small amounts of
|
||||
randomness.
|
||||
|
||||
# Examples
|
||||
|
||||
```rust
|
||||
|
@ -516,8 +533,8 @@ pub trait SeedableRng<Seed>: Rng {
|
|||
|
||||
/// Create a random number generator with a default algorithm and seed.
|
||||
///
|
||||
/// It returns the cryptographically-safest `Rng` algorithm currently
|
||||
/// available in Rust. If you require a specifically seeded `Rng` for
|
||||
/// It returns the strongest `Rng` algorithm currently implemented in
|
||||
/// pure Rust. If you require a specifically seeded `Rng` for
|
||||
/// consistency over time you should pick one algorithm and create the
|
||||
/// `Rng` yourself.
|
||||
///
|
||||
|
@ -592,12 +609,16 @@ pub fn weak_rng() -> XorShiftRng {
|
|||
XorShiftRng::new()
|
||||
}
|
||||
|
||||
/// An [Xorshift random number
|
||||
/// generator](http://en.wikipedia.org/wiki/Xorshift).
|
||||
/// 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`.
|
||||
/// 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).
|
||||
pub struct XorShiftRng {
|
||||
priv x: u32,
|
||||
priv y: u32,
|
||||
|
|
|
@ -30,8 +30,12 @@ type HCRYPTPROV = c_long;
|
|||
// assume they work when we call them.
|
||||
|
||||
/// A random number generator that retrieves randomness straight from
|
||||
/// the operating system. On Unix-like systems this reads from
|
||||
/// `/dev/urandom`, on Windows this uses `CryptGenRandom`.
|
||||
/// the operating system. Platform sources:
|
||||
///
|
||||
/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
|
||||
/// `/dev/urandom`.
|
||||
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
|
||||
/// service provider with the `PROV_RSA_FULL` type.
|
||||
///
|
||||
/// This does not block.
|
||||
#[cfg(unix)]
|
||||
|
@ -39,8 +43,12 @@ pub struct OSRng {
|
|||
priv inner: ReaderRng<file::FileStream>
|
||||
}
|
||||
/// A random number generator that retrieves randomness straight from
|
||||
/// the operating system. On Unix-like systems this reads from
|
||||
/// `/dev/urandom`, on Windows this uses `CryptGenRandom`.
|
||||
/// the operating system. Platform sources:
|
||||
///
|
||||
/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
|
||||
/// `/dev/urandom`.
|
||||
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
|
||||
/// service provider with the `PROV_RSA_FULL` type.
|
||||
///
|
||||
/// This does not block.
|
||||
#[cfg(windows)]
|
||||
|
|
|
@ -672,6 +672,8 @@ extern "C" CDECL void
|
|||
rust_win32_rand_acquire(HCRYPTPROV* phProv) {
|
||||
win32_require
|
||||
(_T("CryptAcquireContext"),
|
||||
// changes to the parameters here should be reflected in the docs of
|
||||
// std::rand::os::OSRng
|
||||
CryptAcquireContext(phProv, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT|CRYPT_SILENT));
|
||||
|
||||
|
|
Loading…
Reference in New Issue