8
8
// except according to those terms.
9
9
10
10
//! Random number generation traits
11
- //!
11
+ //!
12
12
//! This crate is mainly of interest to crates publishing implementations of
13
13
//! [`RngCore`]. Other users are encouraged to use the [`rand`] crate instead
14
14
//! which re-exports the main traits and error types.
15
15
//!
16
16
//! [`RngCore`] is the core trait implemented by algorithmic pseudo-random number
17
17
//! generators and external random-number sources.
18
- //!
18
+ //!
19
19
//! [`SeedableRng`] is an extension trait for construction from fixed seeds and
20
20
//! other random number generators.
21
- //!
21
+ //!
22
22
//! [`Error`] is provided for error-handling. It is safe to use in `no_std`
23
23
//! environments.
24
- //!
24
+ //!
25
25
//! The [`impls`] and [`le`] sub-modules include a few small functions to assist
26
26
//! implementation of [`RngCore`].
27
- //!
27
+ //!
28
28
//! [`rand`]: https://docs.rs/rand
29
29
30
30
#![ doc( html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png" ,
@@ -60,34 +60,34 @@ pub mod le;
60
60
61
61
62
62
/// The core of a random number generator.
63
- ///
63
+ ///
64
64
/// This trait encapsulates the low-level functionality common to all
65
65
/// generators, and is the "back end", to be implemented by generators.
66
- /// End users should normally use `Rng` trait from the [`rand`] crate,
66
+ /// End users should normally use the `Rng` trait from the [`rand`] crate,
67
67
/// which is automatically implemented for every type implementing `RngCore`.
68
- ///
68
+ ///
69
69
/// Three different methods for generating random data are provided since the
70
70
/// optimal implementation of each is dependent on the type of generator. There
71
71
/// is no required relationship between the output of each; e.g. many
72
72
/// implementations of [`fill_bytes`] consume a whole number of `u32` or `u64`
73
73
/// values and drop any remaining unused bytes.
74
- ///
74
+ ///
75
75
/// The [`try_fill_bytes`] method is a variant of [`fill_bytes`] allowing error
76
76
/// handling; it is not deemed sufficiently useful to add equivalents for
77
77
/// [`next_u32`] or [`next_u64`] since the latter methods are almost always used
78
78
/// with algorithmic generators (PRNGs), which are normally infallible.
79
- ///
79
+ ///
80
80
/// Algorithmic generators implementing [`SeedableRng`] should normally have
81
81
/// *portable, reproducible* output, i.e. fix Endianness when converting values
82
82
/// to avoid platform differences, and avoid making any changes which affect
83
83
/// output (except by communicating that the release has breaking changes).
84
- ///
84
+ ///
85
85
/// Typically implementators will implement only one of the methods available
86
86
/// in this trait directly, then use the helper functions from the
87
87
/// [`impls`] module to implement the other methods.
88
- ///
88
+ ///
89
89
/// It is recommended that implementations also implement:
90
- ///
90
+ ///
91
91
/// - `Debug` with a custom implementation which *does not* print any internal
92
92
/// state (at least, [`CryptoRng`]s should not risk leaking state through
93
93
/// `Debug`).
@@ -99,37 +99,37 @@ pub mod le;
99
99
/// implement [`SeedableRng`], to guide users towards proper seeding.
100
100
/// External / hardware RNGs can choose to implement `Default`.
101
101
/// - `Eq` and `PartialEq` could be implemented, but are probably not useful.
102
- ///
102
+ ///
103
103
/// # Example
104
- ///
104
+ ///
105
105
/// A simple example, obviously not generating very *random* output:
106
- ///
106
+ ///
107
107
/// ```
108
108
/// #![allow(dead_code)]
109
109
/// use rand_core::{RngCore, Error, impls};
110
- ///
110
+ ///
111
111
/// struct CountingRng(u64);
112
- ///
112
+ ///
113
113
/// impl RngCore for CountingRng {
114
114
/// fn next_u32(&mut self) -> u32 {
115
115
/// self.next_u64() as u32
116
116
/// }
117
- ///
117
+ ///
118
118
/// fn next_u64(&mut self) -> u64 {
119
119
/// self.0 += 1;
120
120
/// self.0
121
121
/// }
122
- ///
122
+ ///
123
123
/// fn fill_bytes(&mut self, dest: &mut [u8]) {
124
124
/// impls::fill_bytes_via_next(self, dest)
125
125
/// }
126
- ///
126
+ ///
127
127
/// fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
128
128
/// Ok(self.fill_bytes(dest))
129
129
/// }
130
130
/// }
131
131
/// ```
132
- ///
132
+ ///
133
133
/// [`rand`]: https://docs.rs/rand
134
134
/// [`try_fill_bytes`]: RngCore::try_fill_bytes
135
135
/// [`fill_bytes`]: RngCore::fill_bytes
@@ -148,7 +148,7 @@ pub trait RngCore {
148
148
///
149
149
/// RNGs must implement at least one method from this trait directly. In
150
150
/// the case this method is not implemented directly, it can be implemented
151
- /// via [`next_u32`][impls::next_u64_via_u32] or via
151
+ /// via [`next_u32`][impls::next_u64_via_u32] or via
152
152
/// [`fill_bytes`][impls::next_u64_via_fill].
153
153
fn next_u64 ( & mut self ) -> u64 ;
154
154
@@ -161,7 +161,7 @@ pub trait RngCore {
161
161
/// fail the implementation must choose how best to handle errors here
162
162
/// (e.g. panic with a descriptive message or log a warning and retry a few
163
163
/// times).
164
- ///
164
+ ///
165
165
/// This method should guarantee that `dest` is entirely filled
166
166
/// with new data, and may panic if this is impossible
167
167
/// (e.g. reading past the end of a file that is being used as the
@@ -174,49 +174,49 @@ pub trait RngCore {
174
174
/// generating random data thus making this the primary method implemented
175
175
/// by external (true) RNGs (e.g. `OsRng`) which can fail. It may be used
176
176
/// directly to generate keys and to seed (infallible) PRNGs.
177
- ///
177
+ ///
178
178
/// Other than error handling, this method is identical to [`fill_bytes`];
179
179
/// thus this may be implemented using `Ok(self.fill_bytes(dest))` or
180
180
/// `fill_bytes` may be implemented with
181
181
/// `self.try_fill_bytes(dest).unwrap()` or more specific error handling.
182
- ///
182
+ ///
183
183
/// [`fill_bytes`]: RngCore::fill_bytes
184
184
fn try_fill_bytes ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , Error > ;
185
185
}
186
186
187
187
/// A marker trait used to indicate that an [`RngCore`] or [`BlockRngCore`]
188
188
/// implementation is supposed to be cryptographically secure.
189
- ///
189
+ ///
190
190
/// *Cryptographically secure generators*, also known as *CSPRNGs*, should
191
191
/// satisfy an additional properties over other generators: given the first
192
192
/// *k* bits of an algorithm's output
193
193
/// sequence, it should not be possible using polynomial-time algorithms to
194
194
/// predict the next bit with probability significantly greater than 50%.
195
- ///
195
+ ///
196
196
/// Some generators may satisfy an additional property, however this is not
197
197
/// required by this trait: if the CSPRNG's state is revealed, it should not be
198
198
/// computationally-feasible to reconstruct output prior to this. Some other
199
199
/// generators allow backwards-computation and are consided *reversible*.
200
- ///
200
+ ///
201
201
/// Note that this trait is provided for guidance only and cannot guarantee
202
202
/// suitability for cryptographic applications. In general it should only be
203
203
/// implemented for well-reviewed code implementing well-regarded algorithms.
204
- ///
204
+ ///
205
205
/// Note also that use of a `CryptoRng` does not protect against other
206
206
/// weaknesses such as seeding from a weak entropy source or leaking state.
207
- ///
207
+ ///
208
208
/// [`BlockRngCore`]: block::BlockRngCore
209
209
pub trait CryptoRng { }
210
210
211
211
/// A random number generator that can be explicitly seeded.
212
212
///
213
213
/// This trait encapsulates the low-level functionality common to all
214
214
/// pseudo-random number generators (PRNGs, or algorithmic generators).
215
- ///
216
- /// The `FromEntropy` trait from [`rand`] crate is automatically
215
+ ///
216
+ /// The `FromEntropy` trait from the [`rand`] crate is automatically
217
217
/// implemented for every type implementing `SeedableRng`, providing
218
218
/// a convenient `from_entropy()` constructor.
219
- ///
219
+ ///
220
220
/// [`rand`]: https://docs.rs/rand
221
221
pub trait SeedableRng : Sized {
222
222
/// Seed type, which is restricted to types mutably-dereferencable as `u8`
@@ -288,17 +288,17 @@ pub trait SeedableRng: Sized {
288
288
/// for example `0xBAD5EEDu32` or `0x0DDB1A5E5BAD5EEDu64` ("odd biases? bad
289
289
/// seed"). This is assuming only a small number of values must be rejected.
290
290
fn from_seed ( seed : Self :: Seed ) -> Self ;
291
-
291
+
292
292
/// Create a new PRNG using a `u64` seed.
293
- ///
293
+ ///
294
294
/// This is a convenience-wrapper around `from_seed` to allow construction
295
295
/// of any `SeedableRng` from a simple `u64` value. It is designed such that
296
296
/// low Hamming Weight numbers like 0 and 1 can be used and should still
297
297
/// result in good, independent seeds to the PRNG which is returned.
298
- ///
298
+ ///
299
299
/// This **is not suitable for cryptography**, as should be clear given that
300
300
/// the input size is only 64 bits.
301
- ///
301
+ ///
302
302
/// Implementations for PRNGs *may* provide their own implementations of
303
303
/// this function, but the default implementation should be good enough for
304
304
/// all purposes. *Changing* the implementation of this function should be
@@ -307,33 +307,33 @@ pub trait SeedableRng: Sized {
307
307
// We use PCG32 to generate a u32 sequence, and copy to the seed
308
308
const MUL : u64 = 6364136223846793005 ;
309
309
const INC : u64 = 11634580027462260723 ;
310
-
310
+
311
311
let mut seed = Self :: Seed :: default ( ) ;
312
312
for chunk in seed. as_mut ( ) . chunks_mut ( 4 ) {
313
313
// We advance the state first (to get away from the input value,
314
314
// in case it has low Hamming Weight).
315
315
state = state. wrapping_mul ( MUL ) . wrapping_add ( INC ) ;
316
-
316
+
317
317
// Use PCG output function with to_le to generate x:
318
318
let xorshifted = ( ( ( state >> 18 ) ^ state) >> 27 ) as u32 ;
319
319
let rot = ( state >> 59 ) as u32 ;
320
320
let x = xorshifted. rotate_right ( rot) . to_le ( ) ;
321
-
321
+
322
322
unsafe {
323
323
let p = & x as * const u32 as * const u8 ;
324
324
copy_nonoverlapping ( p, chunk. as_mut_ptr ( ) , chunk. len ( ) ) ;
325
325
}
326
326
}
327
-
327
+
328
328
Self :: from_seed ( seed)
329
329
}
330
-
330
+
331
331
/// Create a new PRNG seeded from another `Rng`.
332
332
///
333
333
/// This is the recommended way to initialize PRNGs with fresh entropy. The
334
- /// `FromEntropy` trait from [`rand`] crate provides a convenient
334
+ /// `FromEntropy` trait from the [`rand`] crate provides a convenient
335
335
/// `from_entropy` method based on `from_rng`.
336
- ///
336
+ ///
337
337
/// Usage of this method is not recommended when reproducibility is required
338
338
/// since implementing PRNGs are not required to fix Endianness and are
339
339
/// allowed to modify implementations in new releases.
@@ -346,7 +346,7 @@ pub trait SeedableRng: Sized {
346
346
/// between them.
347
347
///
348
348
/// Prefer to seed from a strong external entropy source like `OsRng` from
349
- /// [`rand_os`] crate or from a cryptographic PRNG; if creating a new
349
+ /// the [`rand_os`] crate or from a cryptographic PRNG; if creating a new
350
350
/// generator for cryptographic uses you *must* seed from a strong source.
351
351
///
352
352
/// Seeding a small PRNG from another small PRNG is possible, but
@@ -357,7 +357,7 @@ pub trait SeedableRng: Sized {
357
357
///
358
358
/// PRNG implementations are allowed to assume that a good RNG is provided
359
359
/// for seeding, and that it is cryptographically secure when appropriate.
360
- ///
360
+ ///
361
361
/// [`rand`]: https://docs.rs/rand
362
362
/// [`rand_os`]: https://docs.rs/rand_os
363
363
fn from_rng < R : RngCore > ( mut rng : R ) -> Result < Self , Error > {
@@ -436,7 +436,7 @@ impl<R: CryptoRng + ?Sized> CryptoRng for Box<R> {}
436
436
#[ cfg( test) ]
437
437
mod test {
438
438
use super :: * ;
439
-
439
+
440
440
#[ test]
441
441
fn test_seed_from_u64 ( ) {
442
442
struct SeedableNum ( u64 ) ;
@@ -448,29 +448,29 @@ mod test {
448
448
SeedableNum ( x[ 0 ] )
449
449
}
450
450
}
451
-
451
+
452
452
const N : usize = 8 ;
453
453
const SEEDS : [ u64 ; N ] = [ 0u64 , 1 , 2 , 3 , 4 , 8 , 16 , -1i64 as u64 ] ;
454
454
let mut results = [ 0u64 ; N ] ;
455
455
for ( i, seed) in SEEDS . iter ( ) . enumerate ( ) {
456
456
let SeedableNum ( x) = SeedableNum :: seed_from_u64 ( * seed) ;
457
457
results[ i] = x;
458
458
}
459
-
459
+
460
460
for ( i1, r1) in results. iter ( ) . enumerate ( ) {
461
461
let weight = r1. count_ones ( ) ;
462
462
// This is the binomial distribution B(64, 0.5), so chance of
463
463
// weight < 20 is binocdf(19, 64, 0.5) = 7.8e-4, and same for
464
464
// weight > 44.
465
465
assert ! ( weight >= 20 && weight <= 44 ) ;
466
-
466
+
467
467
for ( i2, r2) in results. iter ( ) . enumerate ( ) {
468
468
if i1 == i2 { continue ; }
469
469
let diff_weight = ( r1 ^ r2) . count_ones ( ) ;
470
470
assert ! ( diff_weight >= 20 ) ;
471
471
}
472
472
}
473
-
473
+
474
474
// value-breakage test:
475
475
assert_eq ! ( results[ 0 ] , 5029875928683246316 ) ;
476
476
}
0 commit comments