Skip to content

Commit 3dafa0e

Browse files
committed
Address comments
1 parent 57536ad commit 3dafa0e

File tree

4 files changed

+73
-48
lines changed

4 files changed

+73
-48
lines changed

src/distributions/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
//! - [`Normal`] distribution, and [`StandardNormal`] as a primitive
8484
//! - Related to Bernoulli trials (yes/no events, with a given probability):
8585
//! - [`Binomial`] distribution
86+
//! - [`Bernoulli`] distribution, similar to [`Rng::gen_bool`].
8687
//! - Related to positive real-valued quantities that grow exponentially
8788
//! (e.g. prices, incomes, populations):
8889
//! - [`LogNormal`] distribution
@@ -145,6 +146,7 @@
145146
//! [Floating point implementation]: struct.Standard.html#floating-point-implementation
146147
// distributions
147148
//! [`Alphanumeric`]: struct.Alphanumeric.html
149+
//! [`Bernoulli`]: struct.Bernoulli.html
148150
//! [`Binomial`]: struct.Binomial.html
149151
//! [`ChiSquared`]: struct.ChiSquared.html
150152
//! [`Exp`]: struct.Exp.html

src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@
158158
//! [`OsRng`], [`EntropyRng`] and [`ReadRng`]. Other RNGs, like [`ThreadRng`]
159159
//! and [`StdRng`], can be used with all methods without concern.
160160
//!
161+
//! One further problem is that if Rand is unable to get any external randomness
162+
//! when initializing an RNG with [`EntropyRng`], it will panic in
163+
//! [`FromEntropy::from_entropy`], and notably in [`thread_rng`]. Except by
164+
//! compromising security, this problem is as unsolvable as running out of
165+
//! memory.
166+
//!
161167
//!
162168
//! # Distinction between Rand and `rand_core`
163169
//!
@@ -366,6 +372,7 @@ pub trait Rng: RngCore {
366372
/// println!("{}", x);
367373
/// println!("{:?}", rng.gen::<(f64, bool)>());
368374
/// ```
375+
#[inline]
369376
fn gen<T>(&mut self) -> T where Standard: Distribution<T> {
370377
Standard.sample(self)
371378
}
@@ -943,6 +950,7 @@ pub fn weak_rng() -> XorShiftRng {
943950
/// [`thread_rng`]: fn.thread_rng.html
944951
/// [`Standard`]: distributions/struct.Standard.html
945952
#[cfg(feature="std")]
953+
#[inline]
946954
pub fn random<T>() -> T where Standard: Distribution<T> {
947955
thread_rng().gen()
948956
}
@@ -963,6 +971,7 @@ pub fn random<T>() -> T where Standard: Distribution<T> {
963971
/// println!("{:?}", sample);
964972
/// ```
965973
#[cfg(feature="std")]
974+
#[inline]
966975
#[deprecated(since="0.4.0", note="renamed to seq::sample_iter")]
967976
pub fn sample<T, I, R>(rng: &mut R, iterable: I, amount: usize) -> Vec<T>
968977
where I: IntoIterator<Item=T>,

src/prng/mod.rs

Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
//!
1717
//! As mentioned there, PRNGs fall in two broad categories:
1818
//!
19-
//! - [normal PRNGs], primarily designed for simulations
19+
//! - [basic PRNGs], primarily designed for simulations
2020
//! - [CSPRNGs], primarily designed for cryptography
2121
//!
22-
//! In simple terms, the normal PRNGs are often predictable; CSPRNGs should not
22+
//! In simple terms, the basic PRNGs are often predictable; CSPRNGs should not
2323
//! be predictable *when used correctly*.
2424
//!
2525
//! Contents of this documentation:
@@ -34,9 +34,9 @@
3434
//!
3535
//! # The generators
3636
//!
37-
//! ## Normal pseudo-random number generators (PRNGs)
37+
//! ## Basic pseudo-random number generators (PRNGs)
3838
//!
39-
//! The goal of normal, non-cryptographic PRNGs is usually to find a good
39+
//! The goal of regular, non-cryptographic PRNGs is usually to find a good
4040
//! balance between simplicity, quality, memory usage and performance. These
4141
//! algorithms are very important to Monte Carlo simulations, and also suitable
4242
//! for several other problems such as randomized algorithms and games (except
@@ -47,13 +47,33 @@
4747
//!
4848
//! | name | full name | performance | memory | quality | period | features |
4949
//! |------|-----------|-------------|--------|---------|--------|----------|
50-
//! | [`XorShiftRng`] | Xorshift 32/128 | ⭐⭐⭐ | 16 bytes | | `u32` * 2<sup>128</sup> - 1 | — |
50+
//! | [`XorShiftRng`] | Xorshift 32/128 | ★★★☆☆ | 16 bytes | ★☆☆☆☆ | `u32` * 2<sup>128</sup> - 1 | — |
5151
//!
52+
// Quality stars [not rendered in documentation]:
53+
// 5. reserved for crypto-level (e.g. ChaCha8, ISAAC)
54+
// 4. good performance on TestU01 and PractRand, good theory
55+
// (e.g. PCG, truncated Xorshift*)
56+
// 3. good performance on TestU01 and PractRand, but "falling through the
57+
// cracks" or insufficient theory (e.g. SFC, Xoshiro)
58+
// 2. imperfect performance on tests or other limiting properties, but not
59+
// terrible (e.g. Xoroshiro128+)
60+
// 1. clear deficiencies in test results, cycle length, theory, or other
61+
// properties (e.g. Xorshift)
62+
//
63+
// Performance stars [not rendered in documentation]:
64+
// Meant to give an indication of relative performance. Roughly follows a log
65+
// scale, based on the performance of `next_u64` on a current i5/i7:
66+
// - 5. 8000 MB/s+
67+
// - 4. 4000 MB/s+
68+
// - 3. 2000 MB/s+
69+
// - 2. 1000 MB/s+
70+
// - 1. < 1000 MB/s
71+
//
5272
//! ## Cryptographically secure pseudo-random number generators (CSPRNGs)
5373
//!
54-
//! CSPRNGs have much higher requirements than normal PRNGs. The primary
74+
//! CSPRNGs have much higher requirements than basic PRNGs. The primary
5575
//! consideration is security. Performance and simplicity are also important,
56-
//! but in general CSPRNGs are more complex and slower than normal PRNGs.
76+
//! but in general CSPRNGs are more complex and slower than regular PRNGs.
5777
//! Quality is no longer a concern, as it is a requirement for a
5878
//! CSPRNG that the output is basically indistinguishable from true randomness
5979
//! since any bias or correlation makes the output more predictable.
@@ -65,12 +85,12 @@
6585
//!
6686
//! Rand currently provides two trustworthy CSPRNGs and two CSPRNG-like PRNGs:
6787
//!
68-
//! | name | full name | performance | initialization | memory | predictability | backtracking resistance |
88+
//! | name | full name | performance | initialization | memory | predictability | forward secrecy |
6989
//! |------|-----------|--------------|--------------|----------|----------------|-------------------------|
70-
//! | [`ChaChaRng`] | ChaCha20 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 136 bytes | secure | no |
71-
//! | [`Hc128Rng`] | HC-128 | ⭐⭐⭐⭐⭐ | | 4176 bytes | secure | no |
72-
//! | [`IsaacRng`] | ISAAC | ⭐⭐⭐⭐ | | 2072 bytes | unknown | unknown |
73-
//! | [`Isaac64Rng`] | ISAAC-64 | ⭐⭐⭐⭐⭐ | | 4136 bytes| unknown | unknown |
90+
//! | [`ChaChaRng`] | ChaCha20 | ★☆☆☆☆ | fast | 136 bytes | secure | no |
91+
//! | [`Hc128Rng`] | HC-128 | ★★☆☆☆ | slow | 4176 bytes | secure | no |
92+
//! | [`IsaacRng`] | ISAAC | ★★☆☆☆ | slow | 2072 bytes | unknown | unknown |
93+
//! | [`Isaac64Rng`] | ISAAC-64 | ★★☆☆☆ | slow | 4136 bytes| unknown | unknown |
7494
//!
7595
//! It should be noted that the ISAAC generators are only included for
7696
//! historical reasons, they have been with the Rust language since the very
@@ -83,7 +103,7 @@
83103
//! First it has to be said most PRNGs are very fast, and will rarely be a
84104
//! performance bottleneck.
85105
//!
86-
//! Performance of normal PRNGs is a bit of a subtle thing. It depends a lot on
106+
//! Performance of basic PRNGs is a bit of a subtle thing. It depends a lot on
87107
//! the CPU architecture (32 vs. 64 bits), inlining, and also on the number of
88108
//! available registers. This often causes the performance to be affected by
89109
//! surrounding code due to inlining and other usage of registers.
@@ -98,15 +118,16 @@
98118
//! CSPRNGs are a little different in that they typically generate a block of
99119
//! output in a cache, and pull outputs from the cache. This allows them to have
100120
//! good amortised performance, and reduces or completely removes the influence
101-
//! of surrounding code on the CSPRNG performance. It does however cause *poor
102-
//! worst case performance*.
121+
//! of surrounding code on the CSPRNG performance.
103122
//!
104-
//! ## State size
123+
//! ### Worst-case performance
124+
//! Because CSPRNGs usually produce a block of values into a cache, they have
125+
//! poor worst case performance (in contrast to regular PRNGs).
105126
//!
106-
//! Normal PRNGs often use very little memory, commonly only a few words, where
107-
//! a *word* is usually either `u32` or `u64`. This is not universal however,
108-
//! for example the historically popular Mersenne Twister MT19937 algorithm
109-
//! requires 2.5 kB of state.
127+
//! Simple PRNGs often use very little memory, commonly only a few words, where
128+
//! a *word* is usually either `u32` or `u64`. This is not true for all
129+
//! non-cryptographic PRNGs however, for example the historically popular
130+
//! Mersenne Twister MT19937 algorithm requires 2.5 kB of state.
110131
//!
111132
//! CSPRNGs typically require more memory; since the seed size is recommended
112133
//! to be at least 192 bits and some more may be required for the algorithm,
@@ -124,7 +145,7 @@
124145
//!
125146
//! # Quality
126147
//!
127-
//! Many normal PRNGs are not much more than a couple of bitwise and arithmetic
148+
//! Many basic PRNGs are not much more than a couple of bitwise and arithmetic
128149
//! operations. Their simplicity gives good performance, but also means there
129150
//! are small regularities hidden in the generated random number stream.
130151
//!
@@ -146,16 +167,6 @@
146167
//! output values.
147168
//!
148169
//! ### Quality stars:
149-
// 5. reserved for crypto-level (e.g. ChaCha8, ISAAC)
150-
// 4. good performance on TestU01 and PractRand, good theory
151-
// (e.g. PCG, truncated Xorshift*)
152-
// 3. good performance on TestU01 and PractRand, but "falling through the
153-
// cracks" or insufficient theory (e.g. SFC, Xoshiro)
154-
// 2. imperfect performance on tests or other limiting properties, but not
155-
// terrible (e.g. Xoroshiro128+)
156-
// 1. clear deficiencies in test results, cycle length, theory, or other
157-
// properties (e.g. Xorshift)
158-
//!
159170
//! PRNGs with 3 stars or more should be good enough for any purpose.
160171
//! 1 or 2 stars may be good enough for typical apps and games, but do not work
161172
//! well with all algorithms.
@@ -204,27 +215,27 @@
204215
//!
205216
//! From the context of any PRNG, one can ask the question *given some previous
206217
//! output from the PRNG, is it possible to predict the next output value?*
218+
//! This is an important property in any situation where there might be an
219+
//! adversary.
207220
//!
208-
//! Normal PRNGs tend to fall into one of two categories here; *yes* and
209-
//! *with effort*. In some cases prediction is trivial; e.g. plain Xorshift
210-
//! outputs part of its state without mutation, and prediction is as simple as
211-
//! seeding a new Xorshift generator from four `u32` outputs. The widely-used
212-
//! Mersenne Twister algorithms are also easy to predict, though more samples
213-
//! are required (624 `u32` samples, in the case of MT19937). Other generators,
214-
//! like [PCG](http://www.pcg-random.org/predictability.html) and truncated
215-
//! Xorshift* are harder to predict, but not outside the realm of common
216-
//! mathematics and a desktop PC.
221+
//! Regular PRNGs tend to be predictable, although with varying difficulty. In
222+
//! some cases prediction is trivial, for example plain Xorshift outputs part of
223+
//! its state without mutation, and prediction is as simple as seeding a new
224+
//! Xorshift generator from four `u32` outputs. Other generators, like
225+
//! [PCG](http://www.pcg-random.org/predictability.html) and truncated Xorshift*
226+
//! are harder to predict, but not outside the realm of common mathematics and a
227+
//! desktop PC.
217228
//!
218229
//! The basic security that CSPRNGs must provide is the infeasibility to predict
219230
//! output. This requirement is formalized as the [next-bit test]; this is
220231
//! roughly stated as: given the first *k* bits of a random sequence, the
221232
//! sequence satisfies the next-bit test if there is no algorithm able to
222233
//! predict the next bit using reasonable computing power.
223234
//!
224-
//! A further security that *some* CSPRNGs provide is backtracking resistance:
235+
//! A further security that *some* CSPRNGs provide is forward secrecy:
225236
//! in the event that the CSPRNGs state is revealed at some point, it must be
226237
//! infeasible to reconstruct previous states or output. Note that many CSPRNGs
227-
//! *do not* have backtracking resistance in their usual formulations.
238+
//! *do not* have forward secrecy in their usual formulations.
228239
//!
229240
//! As an outsider it is hard to get a good idea about the security of an
230241
//! algorithm. People in the field of cryptography spend a lot of effort
@@ -283,7 +294,7 @@
283294
//!
284295
//!
285296
//! [`rngs` module]: ../rngs/index.html
286-
//! [normal PRNGs]: #normal-pseudo-random-number-generators-prngs
297+
//! [basic PRNGs]: #basic-pseudo-random-number-generators-prngs
287298
//! [CSPRNGs]: #cryptographically-secure-pseudo-random-number-generators-csprngs
288299
//! [`XorShiftRng`]: struct.XorShiftRng.html
289300
//! [`ChaChaRng`]: chacha/struct.ChaChaRng.html

src/rngs/entropy.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ use rngs::{OsRng, JitterRng};
1515

1616
/// An interface returning random data from external source(s), provided
1717
/// specifically for securely seeding algorithmic generators (PRNGs).
18-
///
18+
///
1919
/// Where possible, `EntropyRng` retrieves random data from the operating
2020
/// system's interface for random numbers ([`OsRng`]); if that fails it will
2121
/// fall back to the [`JitterRng`] entropy collector. In the latter case it will
2222
/// still try to use [`OsRng`] on the next usage.
23-
///
23+
///
2424
/// If no secure source of entropy is available `EntropyRng` will panic on use;
2525
/// i.e. it should never output predictable data.
2626
///
@@ -32,9 +32,12 @@ use rngs::{OsRng, JitterRng};
3232
///
3333
/// # Panics
3434
///
35-
/// In the extraordinary situation that both [`OsRng`] and [`JitterRng`] fail,
36-
/// only [`try_fill_bytes`] is able to report the error, and only the one from
37-
/// `OsRng`. The other [`RngCore`] methods will panic in case of an error.
35+
/// On most systems, like Windows, Linux, macOS and *BSD on common hardware, it
36+
/// is highly unlikely for both [`OsRng`] and [`JitterRng`] to fail. But on
37+
/// combinations like webassembly without Emscripten or stdweb both sources are
38+
/// unavailable. If both sources fail, only [`try_fill_bytes`] is able to
39+
/// report the error, and only the one from `OsRng`. The other [`RngCore`]
40+
/// methods will panic in case of an error.
3841
///
3942
/// [`OsRng`]: struct.OsRng.html
4043
/// [`JitterRng`]: jitter/struct.JitterRng.html

0 commit comments

Comments
 (0)