Skip to content

Commit b3225bd

Browse files
authored
Merge pull request #446 from dhardy/block-value-order
Specify value consumption order for block-based RNGs
2 parents c654d5d + 904d1fe commit b3225bd

File tree

5 files changed

+49
-10
lines changed

5 files changed

+49
-10
lines changed

rand_core/src/block.rs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,31 @@ pub trait BlockRngCore {
9090
///
9191
/// `BlockRng` has heavily optimized implementations of the [`RngCore`] methods
9292
/// reading values from the results buffer, as well as
93-
/// calling `BlockRngCore::generate` directly on the output array when
94-
/// `fill_bytes` / `try_fill_bytes` is called on a large array. These methods
93+
/// calling [`BlockRngCore::generate`] directly on the output array when
94+
/// [`fill_bytes`] / [`try_fill_bytes`] is called on a large array. These methods
9595
/// also handle the bookkeeping of when to generate a new batch of values.
96-
/// No generated values are ever thown away and all values are consumed
97-
/// in-order (this may be important for reproducibility).
96+
///
97+
/// No whole generated `u32` values are thown away and all values are consumed
98+
/// in-order. [`next_u32`] simply takes the next available `u32` value.
99+
/// [`next_u64`] is implemented by combining two `u32` values, least
100+
/// significant first. [`fill_bytes`] and [`try_fill_bytes`] consume a whole
101+
/// number of `u32` values, converting each `u32` to a byte slice in
102+
/// little-endian order. If the requested byte length is not a multiple of 4,
103+
/// some bytes will be discarded.
98104
///
99105
/// See also [`BlockRng64`] which uses `u64` array buffers. Currently there is
100106
/// no direct support for other buffer types.
101107
///
102108
/// For easy initialization `BlockRng` also implements [`SeedableRng`].
103109
///
104110
/// [`BlockRngCore`]: BlockRngCore.t.html
111+
/// [`BlockRngCore::generate`]: trait.BlockRngCore.html#tymethod.generate
112+
/// [`BlockRng64`]: struct.BlockRng64.html
105113
/// [`RngCore`]: ../RngCore.t.html
114+
/// [`next_u32`]: ../trait.RngCore.html#tymethod.next_u32
115+
/// [`next_u64`]: ../trait.RngCore.html#tymethod.next_u64
116+
/// [`fill_bytes`]: ../trait.RngCore.html#tymethod.fill_bytes
117+
/// [`try_fill_bytes`]: ../trait.RngCore.html#tymethod.try_fill_bytes
106118
/// [`SeedableRng`]: ../SeedableRng.t.html
107119
#[derive(Clone)]
108120
#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
@@ -289,15 +301,23 @@ impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng<R> {
289301
/// This is similar to [`BlockRng`], but specialized for algorithms that operate
290302
/// on `u64` values.
291303
///
292-
/// Like [`BlockRng`], this wrapper does not throw away whole results and does
293-
/// use all generated values in-order. The behaviour of `next_u32` is however
294-
/// a bit special: half of a `u64` is consumed, leaving the other half in the
295-
/// buffer. If the next function called is `next_u32` then the other half is
296-
/// then consumed, however both `next_u64` and `fill_bytes` discard any
297-
/// half-consumed `u64`s when called.
304+
/// No whole generated `u64` values are thrown away and all values are consumed
305+
/// in-order. [`next_u64`] simply takes the next available `u64` value.
306+
/// [`next_u32`] is however a bit special: half of a `u64` is consumed, leaving
307+
/// the other half in the buffer. If the next function called is [`next_u32`]
308+
/// then the other half is then consumed, however both [`next_u64`] and
309+
/// [`fill_bytes`] discard the rest of any half-consumed `u64`s when called.
310+
///
311+
/// [`fill_bytes`] and [`try_fill_bytes`] consume a whole number of `u64`
312+
/// values. If the requested length is not a multiple of 8, some bytes will be
313+
/// discarded.
298314
///
299315
/// [`BlockRngCore`]: BlockRngCore.t.html
300316
/// [`RngCore`]: ../RngCore.t.html
317+
/// [`next_u32`]: ../trait.RngCore.html#tymethod.next_u32
318+
/// [`next_u64`]: ../trait.RngCore.html#tymethod.next_u64
319+
/// [`fill_bytes`]: ../trait.RngCore.html#tymethod.fill_bytes
320+
/// [`try_fill_bytes`]: ../trait.RngCore.html#tymethod.try_fill_bytes
301321
/// [`BlockRng`]: struct.BlockRng.html
302322
#[derive(Clone)]
303323
#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]

src/prng/chacha.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ const STATE_WORDS: usize = 16;
5454
/// counter counter nonce nonce
5555
/// ```
5656
///
57+
/// This implementation uses an output buffer of sixteen `u32` words, and uses
58+
/// [`BlockRng`] to implement the [`RngCore`] methods.
59+
///
5760
/// [1]: D. J. Bernstein, [*ChaCha, a variant of Salsa20*](
5861
/// https://cr.yp.to/chacha.html)
5962
///
@@ -62,6 +65,8 @@ const STATE_WORDS: usize = 16;
6265
///
6366
/// [`set_word_pos`]: #method.set_word_pos
6467
/// [`set_stream`]: #method.set_stream
68+
/// [`BlockRng`]: ../../../rand_core/block/struct.BlockRng.html
69+
/// [`RngCore`]: ../../trait.RngCore.html
6570
#[derive(Clone, Debug)]
6671
pub struct ChaChaRng(BlockRng<ChaChaCore>);
6772

src/prng/hc128.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ const SEED_WORDS: usize = 8; // 128 bit key followed by 128 bit iv
4444
/// We support seeding with a 256-bit array, which matches the 128-bit key
4545
/// concatenated with a 128-bit IV from the stream cipher.
4646
///
47+
/// This implementation uses an output buffer of sixteen `u32` words, and uses
48+
/// [`BlockRng`] to implement the [`RngCore`] methods.
49+
///
4750
/// ## References
4851
/// [1]: Hongjun Wu (2008). ["The Stream Cipher HC-128"](
4952
/// http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf).
@@ -61,6 +64,9 @@ const SEED_WORDS: usize = 8; // 128 bit key followed by 128 bit iv
6164
///
6265
/// [5]: Internet Engineering Task Force (Februari 2015),
6366
/// ["Prohibiting RC4 Cipher Suites"](https://tools.ietf.org/html/rfc7465).
67+
///
68+
/// [`BlockRng`]: ../../../rand_core/block/struct.BlockRng.html
69+
/// [`RngCore`]: ../../trait.RngCore.html
6470
#[derive(Clone, Debug)]
6571
pub struct Hc128Rng(BlockRng<Hc128Core>);
6672

src/prng/isaac.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
7575
/// ISAAC therefore needs a lot of memory, relative to other non-vrypto RNGs.
7676
/// 2 * 256 * 4 = 2 kb to hold the state and results.
7777
///
78+
/// This implementation uses [`BlockRng`] to implement the [`RngCore`] methods.
79+
///
7880
/// ## References
7981
/// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number generator*](
8082
/// http://burtleburtle.net/bob/rand/isaacafa.html)
@@ -86,6 +88,8 @@ const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
8688
/// https://eprint.iacr.org/2006/438)
8789
///
8890
/// [`Hc128Rng`]: ../hc128/struct.Hc128Rng.html
91+
/// [`BlockRng`]: ../../../rand_core/block/struct.BlockRng.html
92+
/// [`RngCore`]: ../../trait.RngCore.html
8993
#[derive(Clone, Debug)]
9094
#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
9195
pub struct IsaacRng(BlockRng<IsaacCore>);

src/prng/isaac64.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,17 @@ const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
6969
/// }
7070
/// ```
7171
///
72+
/// This implementation uses [`BlockRng64`] to implement the [`RngCore`] methods.
73+
///
7274
/// See for more information the documentation of [`IsaacRng`].
7375
///
7476
/// [1]: Bob Jenkins, [*ISAAC and RC4*](
7577
/// http://burtleburtle.net/bob/rand/isaac.html)
7678
///
7779
/// [`IsaacRng`]: ../isaac/struct.IsaacRng.html
7880
/// [`Hc128Rng`]: ../hc128/struct.Hc128Rng.html
81+
/// [`BlockRng64`]: ../../../rand_core/block/struct.BlockRng64.html
82+
/// [`RngCore`]: ../../trait.RngCore.html
7983
#[derive(Clone, Debug)]
8084
#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
8185
pub struct Isaac64Rng(BlockRng64<Isaac64Core>);

0 commit comments

Comments
 (0)