|
1 | | -//! The `Generator` trait and implementation helpers |
| 1 | +//! The [`Generator`] trait and [`BlockRng`] |
2 | 2 | //! |
3 | | -//! The [`Generator`] trait exists to assist in the implementation of RNGs |
4 | | -//! which generate a block of data in a cache instead of returning generated |
5 | | -//! values directly. |
| 3 | +//! Trait [`Generator`] and marker trait [`CryptoGenerator`] may be implemented |
| 4 | +//! by block-generators; that is PRNGs whose output is a *block* of words, such |
| 5 | +//! as `[u32; 16]`. |
6 | 6 | //! |
7 | | -//! Usage of this trait is optional, but provides two advantages: |
8 | | -//! implementations only need to concern themselves with generation of the |
9 | | -//! block, not the various [`RngCore`] methods (especially [`fill_bytes`], where |
10 | | -//! the optimal implementations are not trivial), and this allows |
11 | | -//! `ReseedingRng` (see [`rand`](https://docs.rs/rand) crate) perform periodic |
12 | | -//! reseeding with very low overhead. |
| 7 | +//! The struct [`BlockRng`] wraps such a [`Generator`] together with an output |
| 8 | +//! buffer and implements several methods (e.g. [`BlockRng::next_word`]) to |
| 9 | +//! assist in the implementation of [`RngCore`]. Note that (unlike in earlier |
| 10 | +//! versions of `rand_core`) [`BlockRng`] itself does not implement [`RngCore`] |
| 11 | +//! since in practice we found it was always beneficial to use a wrapper type |
| 12 | +//! over [`BlockRng`]. |
13 | 13 | //! |
14 | 14 | //! # Example |
15 | 15 | //! |
|
27 | 27 | //! } |
28 | 28 | //! } |
29 | 29 | //! |
30 | | -//! // optionally, also implement CryptoGenerator and SeedableRng for MyRngCore |
31 | | -//! |
32 | | -//! // Final RNG. |
33 | | -//! struct MyRng(BlockRng<MyRngCore>); |
| 30 | +//! // Our RNG is a wrapper over BlockRng |
| 31 | +//! pub struct MyRng(BlockRng<MyRngCore>); |
34 | 32 | //! |
35 | 33 | //! impl SeedableRng for MyRng { |
36 | 34 | //! type Seed = [u8; 32]; |
|
56 | 54 | //! } |
57 | 55 | //! } |
58 | 56 | //! |
| 57 | +//! // And if applicable: impl CryptoRng for MyRng {} |
| 58 | +//! |
59 | 59 | //! let mut rng = MyRng::seed_from_u64(0); |
60 | 60 | //! println!("First value: {}", rng.next_u32()); |
61 | 61 | //! ``` |
62 | 62 | //! |
| 63 | +//! # ReseedingRng |
| 64 | +//! |
| 65 | +//! The [`Generator`] trait supports usage of [`rand::rngs::ReseedingRng`]. |
| 66 | +//! This requires that [`SeedableRng`] be implemented on the "core" generator. |
| 67 | +//! Additionally, it may be useful to implement [`CryptoGenerator`]. |
| 68 | +//! (This is in addition to any implementations on an [`RngCore`] type.) |
| 69 | +//! |
63 | 70 | //! [`Generator`]: crate::block::Generator |
64 | | -//! [`fill_bytes`]: RngCore::fill_bytes |
| 71 | +//! [`RngCore`]: crate::RngCore |
| 72 | +//! [`SeedableRng`]: crate::SeedableRng |
| 73 | +//! [`rand::rngs::ReseedingRng`]: https://docs.rs/rand/latest/rand/rngs/struct.ReseedingRng.html |
65 | 74 |
|
66 | 75 | use crate::le::{Observable, fill_via_chunks}; |
67 | 76 | use core::fmt; |
@@ -97,39 +106,20 @@ pub trait Generator { |
97 | 106 | /// `#[cfg(test)]` attribute to ensure that mock "crypto" generators cannot be |
98 | 107 | /// used in production. |
99 | 108 | /// |
100 | | -/// See [`CryptoRng`] docs for more information. |
| 109 | +/// See [`CryptoRng`](crate::CryptoRng) docs for more information. |
101 | 110 | pub trait CryptoGenerator: Generator {} |
102 | 111 |
|
103 | | -/// A wrapper type implementing [`RngCore`] for some type implementing |
104 | | -/// [`Generator`] with `u32` array buffer; i.e. this can be used to implement |
105 | | -/// a full RNG from just a `generate` function. |
106 | | -/// |
107 | | -/// The `core` field may be accessed directly but the results buffer may not. |
108 | | -/// PRNG implementations can simply use a type alias |
109 | | -/// (`pub type MyRng = BlockRng<MyRngCore>;`) but might prefer to use a |
110 | | -/// wrapper type (`pub struct MyRng(BlockRng<MyRngCore>);`); the latter must |
111 | | -/// re-implement `RngCore` but hides the implementation details and allows |
112 | | -/// extra functionality to be defined on the RNG |
113 | | -/// (e.g. `impl MyRng { fn set_stream(...){...} }`). |
114 | | -/// |
115 | | -/// `BlockRng` has heavily optimized implementations of the [`RngCore`] methods |
116 | | -/// reading values from the results buffer, as well as |
117 | | -/// calling [`Generator::generate`] directly on the output array when |
118 | | -/// [`fill_bytes`] is called on a large array. These methods also handle |
119 | | -/// the bookkeeping of when to generate a new batch of values. |
| 112 | +/// RNG functionality for a block [`Generator`] |
120 | 113 | /// |
121 | | -/// No whole generated `u32` values are thrown away and all values are consumed |
122 | | -/// in-order. [`next_u32`] simply takes the next available `u32` value. |
123 | | -/// [`next_u64`] is implemented by combining two `u32` values, least |
124 | | -/// significant first. [`fill_bytes`] consume a whole number of `u32` values, |
125 | | -/// converting each `u32` to a byte slice in little-endian order. If the requested byte |
126 | | -/// length is not a multiple of 4, some bytes will be discarded. |
| 114 | +/// This type encompasses a [`Generator`] [`core`](Self::core) and a buffer. |
| 115 | +/// It provides optimized implementations of methods required by an [`RngCore`]. |
127 | 116 | /// |
128 | | -/// For easy initialization `BlockRng` also implements [`SeedableRng`]. |
| 117 | +/// All values are consumed in-order of generation. No whole words (e.g. `u32` |
| 118 | +/// or `u64`) are discarded, though where a word is partially used (e.g. for a |
| 119 | +/// byte-fill whose length is not a multiple of the word size) the rest of the |
| 120 | +/// word is discarded. |
129 | 121 | /// |
130 | | -/// [`next_u32`]: RngCore::next_u32 |
131 | | -/// [`next_u64`]: RngCore::next_u64 |
132 | | -/// [`fill_bytes`]: RngCore::fill_bytes |
| 122 | +/// [`RngCore`]: crate::RngCore |
133 | 123 | #[derive(Clone)] |
134 | 124 | pub struct BlockRng<G: Generator> { |
135 | 125 | results: G::Output, |
|
0 commit comments