|
6 | 6 | // option. This file may not be copied, modified, or distributed
|
7 | 7 | // except according to those terms.
|
8 | 8 |
|
9 |
| -//! Random number generators and adapters for common usage: |
10 |
| -//! |
11 |
| -//! - [`ThreadRng`], a fast, secure, auto-seeded thread-local generator |
12 |
| -//! - [`StdRng`] and [`SmallRng`], algorithms to cover typical usage |
13 |
| -//! - [`OsRng`] as an entropy source |
14 |
| -//! - [`mock::StepRng`] as a simple counter for tests |
15 |
| -//! - [`adapter::ReadRng`] to read from a file/stream |
16 |
| -//! - [`adapter::ReseedingRng`] to reseed a PRNG on clone / process fork etc. |
17 |
| -//! |
18 |
| -//! # Background — Random number generators (RNGs) |
19 |
| -//! |
20 |
| -//! Computers are inherently deterministic, so to get *random* numbers one |
21 |
| -//! either has to use a hardware generator or collect bits of *entropy* from |
22 |
| -//! various sources (e.g. event timestamps, or jitter). This is a relatively |
23 |
| -//! slow and complicated operation. |
24 |
| -//! |
25 |
| -//! Generally the operating system will collect some entropy, remove bias, and |
26 |
| -//! use that to seed its own PRNG; [`OsRng`] provides an interface to this. |
27 |
| -//! Some alternatives are available although not normally required; see the |
28 |
| -//! [`rdrand`] and [`rand_jitter`] crates. |
29 |
| -//! |
30 |
| -//! ## Pseudo-random number generators |
31 |
| -//! |
32 |
| -//! What is commonly used instead of "true" random number renerators, are |
33 |
| -//! *pseudo-random number generators* (PRNGs), deterministic algorithms that |
34 |
| -//! produce an infinite stream of pseudo-random numbers from a small random |
35 |
| -//! seed. PRNGs are faster, and have better provable properties. The numbers |
36 |
| -//! produced can be statistically of very high quality and can be impossible to |
37 |
| -//! predict. (They can also have obvious correlations and be trivial to predict; |
38 |
| -//! quality varies.) |
39 |
| -//! |
40 |
| -//! There are two different types of PRNGs: those developed for simulations |
41 |
| -//! and statistics, and those developed for use in cryptography; the latter are |
42 |
| -//! called Cryptographically Secure PRNGs (CSPRNG or CPRNG). Both types can |
43 |
| -//! have good statistical quality but the latter also have to be impossible to |
44 |
| -//! predict, even after seeing many previous output values. Rand provides a good |
45 |
| -//! default algorithm from each class: |
46 |
| -//! |
47 |
| -//! - [`SmallRng`] is a PRNG chosen for low memory usage, high performance and |
48 |
| -//! good statistical quality. |
49 |
| -//! - [`StdRng`] is a CSPRNG chosen for good performance and trust of security |
50 |
| -//! (based on reviews, maturity and usage). The current algorithm is HC-128, |
51 |
| -//! which is one of the recommendations by ECRYPT's eSTREAM project. |
52 |
| -//! |
53 |
| -//! The above PRNGs do not cover all use-cases; more algorithms can be found in |
54 |
| -//! the [`prng`][crate::prng] module, as well as in several other crates. For example, you |
55 |
| -//! may wish a CSPRNG with significantly lower memory usage than [`StdRng`] |
56 |
| -//! while being less concerned about performance, in which case [`ChaChaRng`] |
57 |
| -//! (from the `rand_chacha` crate) is a good choice. |
58 |
| -//! |
59 |
| -//! One complexity is that the internal state of a PRNG must change with every |
60 |
| -//! generated number. For APIs this generally means a mutable reference to the |
61 |
| -//! state of the PRNG has to be passed around. |
62 |
| -//! |
63 |
| -//! A solution is [`ThreadRng`]. This is a thread-local implementation of |
64 |
| -//! [`StdRng`] with automatic seeding on first use. It is the best choice if you |
65 |
| -//! "just" want a convenient, secure, fast random number source. Use via the |
66 |
| -//! [`thread_rng`] function, which gets a reference to the current thread's |
67 |
| -//! local instance. |
68 |
| -//! |
69 |
| -//! ## Seeding |
70 |
| -//! |
71 |
| -//! As mentioned above, PRNGs require a random seed in order to produce random |
72 |
| -//! output. This is especially important for CSPRNGs, which are still |
73 |
| -//! deterministic algorithms, thus can only be secure if their seed value is |
74 |
| -//! also secure. To seed a PRNG, use one of: |
75 |
| -//! |
76 |
| -//! - [`FromEntropy::from_entropy`]; this is the most convenient way to seed |
77 |
| -//! with fresh, secure random data. |
78 |
| -//! - [`SeedableRng::from_rng`]; this allows seeding from another PRNG or |
79 |
| -//! from an entropy source such as [`OsRng`]. |
80 |
| -//! - [`SeedableRng::from_seed`]; this is mostly useful if you wish to be able |
81 |
| -//! to reproduce the output sequence by using a fixed seed. (Don't use |
82 |
| -//! [`StdRng`] or [`SmallRng`] in this case since different algorithms may be |
83 |
| -//! used by future versions of Rand; use an algorithm from the |
84 |
| -//! [`prng`] module.) |
85 |
| -//! |
86 |
| -//! ## Conclusion |
87 |
| -//! |
88 |
| -//! - [`thread_rng`] is what you often want to use. |
89 |
| -//! - If you want more control, flexibility, or better performance, use |
90 |
| -//! [`StdRng`], [`SmallRng`] or an algorithm from the [`prng`] module. |
91 |
| -//! - Use [`FromEntropy::from_entropy`] to seed new PRNGs. |
92 |
| -//! - If you need reproducibility, use [`SeedableRng::from_seed`] combined with |
93 |
| -//! a named PRNG. |
94 |
| -//! |
95 |
| -//! More information and notes on cryptographic security can be found |
96 |
| -//! in the [`prng`] module. |
97 |
| -//! |
98 |
| -//! ## Examples |
99 |
| -//! |
100 |
| -//! Examples of seeding PRNGs: |
101 |
| -//! |
102 |
| -//! ``` |
103 |
| -//! use rand::prelude::*; |
104 |
| -//! # use rand::Error; |
105 |
| -//! |
106 |
| -//! // StdRng seeded securely by the OS or local entropy collector: |
107 |
| -//! let mut rng = StdRng::from_entropy(); |
108 |
| -//! # let v: u32 = rng.gen(); |
109 |
| -//! |
110 |
| -//! // SmallRng seeded from thread_rng: |
111 |
| -//! # fn try_inner() -> Result<(), Error> { |
112 |
| -//! let mut rng = SmallRng::from_rng(thread_rng())?; |
113 |
| -//! # let v: u32 = rng.gen(); |
114 |
| -//! # Ok(()) |
115 |
| -//! # } |
116 |
| -//! # try_inner().unwrap(); |
117 |
| -//! |
118 |
| -//! // SmallRng seeded by a constant, for deterministic results: |
119 |
| -//! let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16]; // byte array |
120 |
| -//! let mut rng = SmallRng::from_seed(seed); |
121 |
| -//! # let v: u32 = rng.gen(); |
122 |
| -//! ``` |
123 |
| -//! |
124 |
| -//! |
125 |
| -//! # Implementing custom RNGs |
126 |
| -//! |
127 |
| -//! If you want to implement custom RNG, see the [`rand_core`] crate. The RNG |
128 |
| -//! will have to implement the [`RngCore`] trait, where the [`Rng`] trait is |
129 |
| -//! build on top of. |
130 |
| -//! |
131 |
| -//! If the RNG needs seeding, also implement the [`SeedableRng`] trait. |
132 |
| -//! |
133 |
| -//! [`CryptoRng`] is a marker trait cryptographically secure PRNGs can |
134 |
| -//! implement. |
| 9 | +//! Random number generators and adapters |
| 10 | +//! |
| 11 | +//! ## Background: Random number generators (RNGs) |
| 12 | +//! |
| 13 | +//! Computers cannot produce random numbers from nowhere. We classify |
| 14 | +//! random number generators as follows: |
| 15 | +//! |
| 16 | +//! - "True" random number generators (TRNGs) use hard-to-predict data sources |
| 17 | +//! (e.g. the high-resolution parts of event timings and sensor jitter) to |
| 18 | +//! harvest random bit-sequences, apply algorithms to remove bias and |
| 19 | +//! estimate available entropy, then combine these bits into a byte-sequence |
| 20 | +//! or an entropy pool. This job is usually done by the operating system or |
| 21 | +//! a hardware generator (HRNG). |
| 22 | +//! - "Pseudo"-random number generators (PRNGs) use algorithms to transform a |
| 23 | +//! seed into a sequence of pseudo-random numbers. These generators can be |
| 24 | +//! fast and produce well-distributed unpredictable random numbers (or not). |
| 25 | +//! They are usually deterministic: given algorithm and seed, the output |
| 26 | +//! sequence can be reproduced. They have finite period and eventually loop; |
| 27 | +//! with many algorithms this period is fixed and can be proven sufficiently |
| 28 | +//! long, while others are chaotic and the period depends on the seed. |
| 29 | +//! - "Cryptographically secure" pseudo-random number generators (CSPRNGs) |
| 30 | +//! are the sub-set of PRNGs which are secure. Security of the generator |
| 31 | +//! relies both on hiding the internal state and using a strong algorithm. |
| 32 | +//! |
| 33 | +//! ## Traits and functionality |
| 34 | +//! |
| 35 | +//! All RNGs implement the [`RngCore`] trait, as a consequence of which the |
| 36 | +//! [`Rng`] extension trait is automatically implemented. Secure RNGs may |
| 37 | +//! additionally implement the [`CryptoRng`] trait. |
| 38 | +//! |
| 39 | +//! All PRNGs require a seed to produce their random number sequence. The |
| 40 | +//! [`SeedableRng`] trait provides three ways of constructing PRNGs: |
| 41 | +//! |
| 42 | +//! - `from_seed` accepts a type specific to the PRNG |
| 43 | +//! - `from_rng` allows a PRNG to be seeded from any other RNG |
| 44 | +//! - `seed_from_u64` allows any PRNG to be seeded from a `u64` insecurely |
| 45 | +//! |
| 46 | +//! Additionally, [`FromEntropy::from_entropy`] is a shortcut for seeding from |
| 47 | +//! [`OsRng`]. |
| 48 | +//! |
| 49 | +//! Use the [`rand_core`] crate when implementing your own RNGs. |
| 50 | +//! |
| 51 | +//! ## Our generators |
| 52 | +//! |
| 53 | +//! This crate provides several random number generators: |
| 54 | +//! |
| 55 | +//! - [`OsRng`] is an interface to the operating system's random number |
| 56 | +//! source. Typically the operating system uses a CSPRNG with entropy |
| 57 | +//! provided by a TRNG and some type of on-going re-seeding. |
| 58 | +//! - [`ThreadRng`], provided by the [`thread_rng`] function, is a handle to a |
| 59 | +//! thread-local CSPRNG with periodic seeding from [`OsRng`]. Because this |
| 60 | +//! is local, it is typically much faster than [`OsRng`]. It should be |
| 61 | +//! secure, though the paranoid may prefer [`OsRng`]. |
| 62 | +//! - [`StdRng`] is a CSPRNG chosen for good performance and trust of security |
| 63 | +//! (based on reviews, maturity and usage). The current algorithm is HC-128, |
| 64 | +//! which is one of the recommendations by ECRYPT's eSTREAM project. |
| 65 | +//! [`StdRng`] provides the algorithm used by [`ThreadRng`] but without |
| 66 | +//! periodic reseeding. |
| 67 | +//! - [`SmallRng`] is an **insecure** PRNG designed to be fast, simple, require |
| 68 | +//! little memory, and have good output quality. |
| 69 | +//! |
| 70 | +//! The algorithms selected for [`StdRng`] and [`SmallRng`] may change in any |
| 71 | +//! release and may be platform-dependent, therefore they should be considered |
| 72 | +//! **not reproducible**. |
| 73 | +//! |
| 74 | +//! ## Additional generators |
| 75 | +//! |
| 76 | +//! **TRNGs**: The [`rdrand`] crate provides an interface to the RDRAND and |
| 77 | +//! RDSEED instructions available in modern Intel and AMD CPUs. |
| 78 | +//! The [`rand_jitter`] crate provides a user-space implementation of |
| 79 | +//! entropy harvesting from CPU timer jitter, but is very slow and has |
| 80 | +//! [security issues](https://github.com/rust-random/rand/issues/699). |
| 81 | +//! |
| 82 | +//! **PRNGs**: Several companion crates are available, providing individual or |
| 83 | +//! families of PRNG algorithms. These provide the implementations behind |
| 84 | +//! [`StdRng`] and [`SmallRng`] but can also be used directly, indeed *should* |
| 85 | +//! be used directly when **reproducibility** matters. |
| 86 | +//! Some suggestions are: [`rand_chacha`], [`rand_pcg`], [`rand_xoshiro`]. |
| 87 | +//! A full list can be found by searching for crates with the [`rng` tag]. |
135 | 88 | //!
|
136 | 89 | //! [`SmallRng`]: rngs::SmallRng
|
137 | 90 | //! [`StdRng`]: rngs::StdRng
|
| 91 | +//! [`OsRng`]: rngs::OsRng |
138 | 92 | //! [`ThreadRng`]: rngs::ThreadRng
|
139 | 93 | //! [`mock::StepRng`]: rngs::mock::StepRng
|
140 | 94 | //! [`adapter::ReadRng`]: rngs::adapter::ReadRng
|
141 | 95 | //! [`adapter::ReseedingRng`]: rngs::adapter::ReseedingRng
|
142 | 96 | //! [`ChaChaRng`]: ../../rand_chacha/struct.ChaChaRng.html
|
143 | 97 | //! [`rdrand`]: https://crates.io/crates/rdrand
|
144 | 98 | //! [`rand_jitter`]: https://crates.io/crates/rand_jitter
|
| 99 | +//! [`rand_chacha`]: https://crates.io/crates/rand_chacha |
| 100 | +//! [`rand_pcg`]: https://crates.io/crates/rand_pcg |
| 101 | +//! [`rand_xoshiro`]: https://crates.io/crates/rand_xoshiro |
| 102 | +//! [`rng` tag]: https://crates.io/keywords/rng |
145 | 103 |
|
146 | 104 | pub mod adapter;
|
147 | 105 |
|
|
0 commit comments