diff options
Diffstat (limited to 'rand/src/rngs/mod.rs')
-rw-r--r-- | rand/src/rngs/mod.rs | 253 |
1 files changed, 95 insertions, 158 deletions
diff --git a/rand/src/rngs/mod.rs b/rand/src/rngs/mod.rs index 847fc94..abf3243 100644 --- a/rand/src/rngs/mod.rs +++ b/rand/src/rngs/mod.rs @@ -6,177 +6,114 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Random number generators and adapters for common usage: -//! -//! - [`ThreadRng`], a fast, secure, auto-seeded thread-local generator -//! - [`StdRng`] and [`SmallRng`], algorithms to cover typical usage -//! - [`EntropyRng`], [`OsRng`] and [`JitterRng`] as entropy sources -//! - [`mock::StepRng`] as a simple counter for tests -//! - [`adapter::ReadRng`] to read from a file/stream -//! - [`adapter::ReseedingRng`] to reseed a PRNG on clone / process fork etc. -//! -//! # Background — Random number generators (RNGs) -//! -//! Computers are inherently deterministic, so to get *random* numbers one -//! either has to use a hardware generator or collect bits of *entropy* from -//! various sources (e.g. event timestamps, or jitter). This is a relatively -//! slow and complicated operation. -//! -//! Generally the operating system will collect some entropy, remove bias, and -//! use that to seed its own PRNG; [`OsRng`] provides an interface to this. -//! [`JitterRng`] is an entropy collector included with Rand that measures -//! jitter in the CPU execution time, and jitter in memory access time. -//! [`EntropyRng`] is a wrapper that uses the best entropy source that is -//! available. -//! -//! ## Pseudo-random number generators -//! -//! What is commonly used instead of "true" random number renerators, are -//! *pseudo-random number generators* (PRNGs), deterministic algorithms that -//! produce an infinite stream of pseudo-random numbers from a small random -//! seed. PRNGs are faster, and have better provable properties. The numbers -//! produced can be statistically of very high quality and can be impossible to -//! predict. (They can also have obvious correlations and be trivial to predict; -//! quality varies.) -//! -//! There are two different types of PRNGs: those developed for simulations -//! and statistics, and those developed for use in cryptography; the latter are -//! called Cryptographically Secure PRNGs (CSPRNG or CPRNG). Both types can -//! have good statistical quality but the latter also have to be impossible to -//! predict, even after seeing many previous output values. Rand provides a good -//! default algorithm from each class: -//! -//! - [`SmallRng`] is a PRNG chosen for low memory usage, high performance and -//! good statistical quality. -//! - [`StdRng`] is a CSPRNG chosen for good performance and trust of security -//! (based on reviews, maturity and usage). The current algorithm is HC-128, -//! which is one of the recommendations by ECRYPT's eSTREAM project. -//! -//! The above PRNGs do not cover all use-cases; more algorithms can be found in -//! the [`prng` module], as well as in several other crates. For example, you -//! may wish a CSPRNG with significantly lower memory usage than [`StdRng`] -//! while being less concerned about performance, in which case [`ChaChaRng`] -//! is a good choice. -//! -//! One complexity is that the internal state of a PRNG must change with every -//! generated number. For APIs this generally means a mutable reference to the -//! state of the PRNG has to be passed around. -//! -//! A solution is [`ThreadRng`]. This is a thread-local implementation of -//! [`StdRng`] with automatic seeding on first use. It is the best choice if you -//! "just" want a convenient, secure, fast random number source. Use via the -//! [`thread_rng`] function, which gets a reference to the current thread's -//! local instance. -//! -//! ## Seeding -//! -//! As mentioned above, PRNGs require a random seed in order to produce random -//! output. This is especially important for CSPRNGs, which are still -//! deterministic algorithms, thus can only be secure if their seed value is -//! also secure. To seed a PRNG, use one of: -//! -//! - [`FromEntropy::from_entropy`]; this is the most convenient way to seed -//! with fresh, secure random data. -//! - [`SeedableRng::from_rng`]; this allows seeding from another PRNG or -//! from an entropy source such as [`EntropyRng`]. -//! - [`SeedableRng::from_seed`]; this is mostly useful if you wish to be able -//! to reproduce the output sequence by using a fixed seed. (Don't use -//! [`StdRng`] or [`SmallRng`] in this case since different algorithms may be -//! used by future versions of Rand; use an algorithm from the -//! [`prng` module].) -//! -//! ## Conclusion -//! -//! - [`thread_rng`] is what you often want to use. -//! - If you want more control, flexibility, or better performance, use -//! [`StdRng`], [`SmallRng`] or an algorithm from the [`prng` module]. -//! - Use [`FromEntropy::from_entropy`] to seed new PRNGs. -//! - If you need reproducibility, use [`SeedableRng::from_seed`] combined with -//! a named PRNG. -//! -//! More information and notes on cryptographic security can be found -//! in the [`prng` module]. -//! -//! ## Examples -//! -//! Examples of seeding PRNGs: -//! -//! ``` -//! use rand::prelude::*; -//! # use rand::Error; -//! -//! // StdRng seeded securely by the OS or local entropy collector: -//! let mut rng = StdRng::from_entropy(); -//! # let v: u32 = rng.gen(); -//! -//! // SmallRng seeded from thread_rng: -//! # fn try_inner() -> Result<(), Error> { -//! let mut rng = SmallRng::from_rng(thread_rng())?; -//! # let v: u32 = rng.gen(); -//! # Ok(()) -//! # } -//! # try_inner().unwrap(); -//! -//! // SmallRng seeded by a constant, for deterministic results: -//! let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16]; // byte array -//! let mut rng = SmallRng::from_seed(seed); -//! # let v: u32 = rng.gen(); -//! ``` -//! -//! -//! # Implementing custom RNGs -//! -//! If you want to implement custom RNG, see the [`rand_core`] crate. The RNG -//! will have to implement the [`RngCore`] trait, where the [`Rng`] trait is -//! build on top of. -//! -//! If the RNG needs seeding, also implement the [`SeedableRng`] trait. -//! -//! [`CryptoRng`] is a marker trait cryptographically secure PRNGs can -//! implement. -//! -//! -// This module: -//! [`ThreadRng`]: struct.ThreadRng.html -//! [`StdRng`]: struct.StdRng.html -//! [`SmallRng`]: struct.SmallRng.html -//! [`EntropyRng`]: struct.EntropyRng.html -//! [`OsRng`]: struct.OsRng.html -//! [`JitterRng`]: struct.JitterRng.html -// Other traits and functions: -//! [`rand_core`]: https://crates.io/crates/rand_core -//! [`prng` module]: ../prng/index.html -//! [`CryptoRng`]: ../trait.CryptoRng.html -//! [`FromEntropy`]: ../trait.FromEntropy.html -//! [`FromEntropy::from_entropy`]: ../trait.FromEntropy.html#tymethod.from_entropy -//! [`RngCore`]: ../trait.RngCore.html -//! [`Rng`]: ../trait.Rng.html -//! [`SeedableRng`]: ../trait.SeedableRng.html -//! [`SeedableRng::from_rng`]: ../trait.SeedableRng.html#tymethod.from_rng -//! [`SeedableRng::from_seed`]: ../trait.SeedableRng.html#tymethod.from_seed -//! [`thread_rng`]: ../fn.thread_rng.html -//! [`mock::StepRng`]: mock/struct.StepRng.html -//! [`adapter::ReadRng`]: adapter/struct.ReadRng.html -//! [`adapter::ReseedingRng`]: adapter/struct.ReseedingRng.html -//! [`ChaChaRng`]: ../../rand_chacha/struct.ChaChaRng.html +//! 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; -mod jitter; 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; - -pub use self::jitter::{JitterRng, TimerError}; +#[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="rand_os")] -pub use rand_os::OsRng; +#[cfg(feature="getrandom")] pub use rand_core::OsRng; |