|
76 | 76 | //! use [`SeedableRng::from_seed`] or a constructor specific to the generator
|
77 | 77 | //! (e.g. [`IsaacRng::new_from_u64`]).
|
78 | 78 | //!
|
79 |
| -//! # Applying / converting random data |
| 79 | +//! ## Applying / converting random data |
80 | 80 | //!
|
81 | 81 | //! The [`RngCore`] trait allows generators to implement a common interface for
|
82 | 82 | //! retrieving random data, but how should you use this? Typically users should
|
|
94 | 94 | //!
|
95 | 95 | //! The [`seq`] module has a few tools applicable to sliceable or iterable data.
|
96 | 96 | //!
|
97 |
| -//! # Cryptographic security |
| 97 | +//! ## Cryptographic security |
| 98 | +//! |
| 99 | +//! First, lets recap some terminology: |
| 100 | +//! |
| 101 | +//! - **PRNG:** *Pseudo-Random-Number-Generator* is another name for an |
| 102 | +//! *algorithmic generator* |
| 103 | +//! - **CSPRNG:** a *Cryptographically Secure* PRNG |
98 | 104 | //!
|
99 | 105 | //! Security analysis requires a threat model and expert review; we can provide
|
100 |
| -//! neither, but can provide some guidance. We assume that the goal is to |
101 |
| -//! obtain secret random data and that some source of secrets ("entropy") is |
102 |
| -//! available; that is, [`EntropyRng`] is functional. |
103 |
| -//! |
104 |
| -//! Potential threat: is the entropy source secure? The primary entropy source |
105 |
| -//! is [`OsRng`] which is simply a wrapper around the platform's native "secure |
106 |
| -//! entropy source"; usually this is available (outside of embedded platforms) |
107 |
| -//! and usually you can trust this (some caveats may apply; see [`OsRng`] doc). |
108 |
| -//! The fallback source used by [`EntropyRng`] is [`JitterRng`] which runs extensive |
109 |
| -//! tests on the quality of the CPU timer and is conservative in its estimates |
110 |
| -//! of the entropy harvested from each time sample; this makes it slow but very |
111 |
| -//! strong. Using [`EntropyRng`] directly should therefore be secure; the main |
112 |
| -//! reason not to is performance, which is why many applications use local |
113 |
| -//! algorithmic generators. |
114 |
| -//! |
115 |
| -//! Potential threat: are algorithmic generators predictable? Certainly some |
116 |
| -//! are; algorithmic generators fall broadly into two categories: those using a |
117 |
| -//! small amount of state (e.g. one to four 32- or 64-bit words) designed for |
118 |
| -//! non-security applications and those designed to be secure, typically with |
119 |
| -//! much larger state space and complex initialisation. The former should not be |
120 |
| -//! trusted to be secure, the latter may or may not have known weaknesses or |
121 |
| -//! may even have been proven secure under a specified adversarial model. We |
122 |
| -//! provide some notes on the security of the cryptographic algorithmic |
123 |
| -//! generators provided by this crate, [`Hc128Rng`] and [`ChaChaRng`]. Note that |
124 |
| -//! previously [`IsaacRng`] and [`Isaac64Rng`] were used as "reasonably strong |
125 |
| -//! generators"; these have no known weaknesses but also have no proofs of |
126 |
| -//! security, thus are not recommended for cryptographic uses. |
127 |
| -//! |
128 |
| -//! Potential threat: could the internal state of a cryptographic generator be |
129 |
| -//! leaked? This falls under the topic of "side channel attacks", and multiple |
130 |
| -//! variants are possible: the state of the generators being accidentally |
131 |
| -//! printed in log files or some other application output, the process's memory |
132 |
| -//! being copied somehow, the process being forked and both sub-processes |
133 |
| -//! outputting the same random sequence but such that one of those can be read; |
134 |
| -//! likely some other side-channel attacks are possible in some circumstances. |
135 |
| -//! It is typically impossible to prove immunity to all side-channel attacks, |
136 |
| -//! however some mitigation of known threats is usually possible, for example |
137 |
| -//! all generators implemented in this crate have a custom `Debug` |
138 |
| -//! implementation omitting all internal state, and [`ReseedingRng`] allows |
139 |
| -//! periodic reseeding such that a long-running process with leaked generator |
140 |
| -//! state should eventually recover to an unknown state. In the future we plan |
141 |
| -//! to add further mitigations; see issue #314. |
| 106 | +//! neither, but we can provide a few hints. We assume that the goal is to |
| 107 | +//! produce secret apparently-random data. Therefore, we need: |
142 | 108 | //!
|
143 |
| -//! We provide the [`CryptoRng`] marker trait as an indication of which random |
144 |
| -//! generators/sources may be used for cryptographic applications; this should |
145 |
| -//! be considered advisory only does not imply any protection against |
146 |
| -//! side-channel attacks. |
| 109 | +//! - A good source of entropy. A known algorithm given known input data is |
| 110 | +//! trivial to predict, and likewise if there's a non-negligable chance that |
| 111 | +//! the input to a PRNG is guessable then there's a chance its output is too. |
| 112 | +//! We recommend seeding CSPRNGs with [`EntropyRng`] or [`OsRng`] which |
| 113 | +//! provide fresh "random" values from an external source. |
| 114 | +//! One can also seed from another CSPRNG, e.g. `thread_rng`, which is faster, |
| 115 | +//! but adds another component which must be trusted. |
| 116 | +//! - A strong algorithmic generator. It is possible to use a good entropy |
| 117 | +//! source like `OsRng` directly, and in some cases this is the best option, |
| 118 | +//! but for better performance (or if requiring reproducible values generated |
| 119 | +//! from a fixed seed) it is common to use a local CSPRNG. The basic security |
| 120 | +//! that CSPRNGs must provide is making it infeasible to predict future output |
| 121 | +//! given a sample of past output. A further security that *some* CSPRNGs |
| 122 | +//! provide is *forward secrecy*; this ensures that in the event that the |
| 123 | +//! algorithm's state is revealed, it is infeasible to reconstruct past |
| 124 | +//! output. See the [`CryptoRng`] trait and notes on individual algorithms. |
| 125 | +//! - To be careful not to leak secrets like keys and CSPRNG's internal state |
| 126 | +//! and robust against "side channel attacks". This goes well beyond the scope |
| 127 | +//! of random number generation, but this crate takes some precautions: |
| 128 | +//! - to avoid printing CSPRNG state in log files, implementations have a |
| 129 | +//! custom `Debug` implementation which omits all internal state |
| 130 | +//! - `thread_rng` uses [`ReseedingRng`] to periodically refresh its state |
| 131 | +//! - in the future we plan to add some protection against fork attacks |
| 132 | +//! (where the process is forked and each clone generates the same "random" |
| 133 | +//! numbers); this is not yet implemented (see issues #314, #370) |
147 | 134 | //!
|
148 | 135 | //! # Examples
|
149 | 136 | //!
|
@@ -489,9 +476,9 @@ pub trait Rng: RngCore {
|
489 | 476 | /// # Accuracy note
|
490 | 477 | ///
|
491 | 478 | /// `gen_bool` uses 32 bits of the RNG, so if you use it to generate close
|
492 |
| - /// to or more than 2^32 results, a tiny bias may become noticable. |
| 479 | + /// to or more than `2^32` results, a tiny bias may become noticable. |
493 | 480 | /// A notable consequence of the method used here is that the worst case is
|
494 |
| - /// `rng.gen_bool(0.0)`: it has a chance of 1 in 2^32 of being true, while |
| 481 | + /// `rng.gen_bool(0.0)`: it has a chance of 1 in `2^32` of being true, while |
495 | 482 | /// it should always be false. But using `gen_bool` to consume *many* values
|
496 | 483 | /// from an RNG just to consistently generate `false` does not match with
|
497 | 484 | /// the intent of this method.
|
|
0 commit comments