1- //! The `BlockRngCore ` trait and implementation helpers
1+ //! The `Generator ` trait and implementation helpers
22//!
3- //! The [`BlockRngCore `] trait exists to assist in the implementation of RNGs
3+ //! The [`Generator `] trait exists to assist in the implementation of RNGs
44//! which generate a block of data in a cache instead of returning generated
55//! values directly.
66//!
1515//!
1616//! ```no_run
1717//! use rand_core::{RngCore, SeedableRng};
18- //! use rand_core::block::{BlockRngCore , BlockRng};
18+ //! use rand_core::block::{Generator , BlockRng};
1919//!
2020//! struct MyRngCore;
2121//!
22- //! impl BlockRngCore for MyRngCore {
23- //! type Results = [u32; 16];
22+ //! impl Generator for MyRngCore {
23+ //! type Result = [u32; 16];
2424//!
25- //! fn generate(&mut self, results : &mut Self::Results ) {
25+ //! fn generate(&mut self, result : &mut Self::Result ) {
2626//! unimplemented!()
2727//! }
2828//! }
3434//! }
3535//! }
3636//!
37- //! // optionally, also implement CryptoBlockRng for MyRngCore
37+ //! // optionally, also implement CryptoGenerator for MyRngCore
3838//!
3939//! // Final RNG.
4040//! let mut rng = BlockRng::<MyRngCore>::seed_from_u64(0);
4141//! println!("First value: {}", rng.next_u32());
4242//! ```
4343//!
44- //! [`BlockRngCore `]: crate::block::BlockRngCore
44+ //! [`Generator `]: crate::block::Generator
4545//! [`fill_bytes`]: RngCore::fill_bytes
4646
4747use crate :: le:: fill_via_chunks;
@@ -50,28 +50,54 @@ use core::fmt;
5050#[ cfg( feature = "serde" ) ]
5151use serde:: { Deserialize , Serialize } ;
5252
53- /// A trait for RNGs which do not generate random numbers individually, but in
54- /// blocks (typically `[u32; N]`). This technique is commonly used by
55- /// cryptographic RNGs to improve performance.
56- ///
57- /// See the [module][crate::block] documentation for details.
58- pub trait BlockRngCore {
59- /// Results type. This is the 'block' an RNG implementing `BlockRngCore`
60- /// generates, which will usually be an array like `[u32; 16]`.
61- type Results ;
62-
63- /// Generate a new block of results.
64- fn generate ( & mut self , results : & mut Self :: Results ) ;
53+ /// A random generator
54+ pub trait Generator {
55+ /// The result type.
56+ ///
57+ /// This could be a simple word like `u64` or an array like `[u32; 16]`.
58+ type Result ;
59+
60+ /// Generate a new result.
61+ ///
62+ /// Since [`Self::Result`] may be large, the output is passed by reference.
63+ /// Word generators should likely implement this as a shim over another
64+ /// method:
65+ /// ```
66+ /// pub struct CountingGenerator(u64);
67+ /// impl CountingGenerator {
68+ /// fn next(&mut self) -> u64 {
69+ /// let x = self.0;
70+ /// self.0 = self.0.wrapping_add(1);
71+ /// x
72+ /// }
73+ /// }
74+ ///
75+ /// impl rand_core::block::Generator for CountingGenerator {
76+ /// type Result = u64;
77+ ///
78+ /// #[inline]
79+ /// fn generate(&mut self, result: &mut Self::Result) {
80+ /// *result = self.next();
81+ /// }
82+ /// }
83+ /// ```
84+ fn generate ( & mut self , result : & mut Self :: Result ) ;
6585}
6686
67- /// A marker trait used to indicate that an [`RngCore`] implementation is
68- /// supposed to be cryptographically secure.
87+ /// A cryptographically secure generator
88+ ///
89+ /// This is a marker trait used to indicate that a [`Generator`] implementation
90+ /// is supposed to be cryptographically secure.
91+ ///
92+ /// Mock generators should not implement this trait *except* under a
93+ /// `#[cfg(test)]` attribute to ensure that mock "crypto" generators cannot be
94+ /// used in production.
6995///
7096/// See [`CryptoRng`] docs for more information.
71- pub trait CryptoBlockRng : BlockRngCore { }
97+ pub trait CryptoGenerator : Generator { }
7298
7399/// A wrapper type implementing [`RngCore`] for some type implementing
74- /// [`BlockRngCore `] with `u32` array buffer; i.e. this can be used to implement
100+ /// [`Generator `] with `u32` array buffer; i.e. this can be used to implement
75101/// a full RNG from just a `generate` function.
76102///
77103/// The `core` field may be accessed directly but the results buffer may not.
@@ -84,7 +110,7 @@ pub trait CryptoBlockRng: BlockRngCore {}
84110///
85111/// `BlockRng` has heavily optimized implementations of the [`RngCore`] methods
86112/// reading values from the results buffer, as well as
87- /// calling [`BlockRngCore ::generate`] directly on the output array when
113+ /// calling [`Generator ::generate`] directly on the output array when
88114/// [`fill_bytes`] is called on a large array. These methods also handle
89115/// the bookkeeping of when to generate a new batch of values.
90116///
@@ -108,18 +134,18 @@ pub trait CryptoBlockRng: BlockRngCore {}
108134#[ cfg_attr(
109135 feature = "serde" ,
110136 serde(
111- bound = "for<'x> R: Serialize + Deserialize<'x>, for<'x> R::Results : Serialize + Deserialize<'x>"
137+ bound = "for<'x> R: Serialize + Deserialize<'x>, for<'x> R::Result : Serialize + Deserialize<'x>"
112138 )
113139) ]
114- pub struct BlockRng < R : BlockRngCore > {
115- results : R :: Results ,
140+ pub struct BlockRng < R : Generator > {
141+ results : R :: Result ,
116142 index : usize ,
117143 /// The *core* part of the RNG, implementing the `generate` function.
118144 pub core : R ,
119145}
120146
121147// Custom Debug implementation that does not expose the contents of `results`.
122- impl < const N : usize , R : BlockRngCore < Results = [ u32 ; N ] > + fmt:: Debug > fmt:: Debug for BlockRng < R > {
148+ impl < const N : usize , R : Generator < Result = [ u32 ; N ] > + fmt:: Debug > fmt:: Debug for BlockRng < R > {
123149 fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
124150 fmt. debug_struct ( "BlockRng" )
125151 . field ( "core" , & self . core )
@@ -129,9 +155,9 @@ impl<const N: usize, R: BlockRngCore<Results = [u32; N]> + fmt::Debug> fmt::Debu
129155 }
130156}
131157
132- impl < const N : usize , R : BlockRngCore < Results = [ u32 ; N ] > > BlockRng < R > {
158+ impl < const N : usize , R : Generator < Result = [ u32 ; N ] > > BlockRng < R > {
133159 /// Create a new `BlockRng` from an existing RNG implementing
134- /// `BlockRngCore `. Results will be generated on first use.
160+ /// `Generator `. Result will be generated on first use.
135161 #[ inline]
136162 pub fn new ( core : R ) -> BlockRng < R > {
137163 BlockRng {
@@ -168,7 +194,7 @@ impl<const N: usize, R: BlockRngCore<Results = [u32; N]>> BlockRng<R> {
168194 }
169195}
170196
171- impl < const N : usize , R : BlockRngCore < Results = [ u32 ; N ] > > RngCore for BlockRng < R > {
197+ impl < const N : usize , R : Generator < Result = [ u32 ; N ] > > RngCore for BlockRng < R > {
172198 #[ inline]
173199 fn next_u32 ( & mut self ) -> u32 {
174200 if self . index >= self . results . as_ref ( ) . len ( ) {
@@ -221,7 +247,7 @@ impl<const N: usize, R: BlockRngCore<Results = [u32; N]>> RngCore for BlockRng<R
221247 }
222248}
223249
224- impl < const N : usize , R : BlockRngCore < Results = [ u32 ; N ] > + SeedableRng > SeedableRng
250+ impl < const N : usize , R : Generator < Result = [ u32 ; N ] > + SeedableRng > SeedableRng
225251 for BlockRng < R >
226252{
227253 type Seed = R :: Seed ;
@@ -247,10 +273,10 @@ impl<const N: usize, R: BlockRngCore<Results = [u32; N]> + SeedableRng> Seedable
247273 }
248274}
249275
250- impl < const N : usize , R : CryptoBlockRng < Results = [ u32 ; N ] > > CryptoRng for BlockRng < R > { }
276+ impl < const N : usize , R : CryptoGenerator < Result = [ u32 ; N ] > > CryptoRng for BlockRng < R > { }
251277
252278/// A wrapper type implementing [`RngCore`] for some type implementing
253- /// [`BlockRngCore `] with `u64` array buffer; i.e. this can be used to implement
279+ /// [`Generator `] with `u64` array buffer; i.e. this can be used to implement
254280/// a full RNG from just a `generate` function.
255281///
256282/// This is similar to [`BlockRng`], but specialized for algorithms that operate
@@ -271,16 +297,16 @@ impl<const N: usize, R: CryptoBlockRng<Results = [u32; N]>> CryptoRng for BlockR
271297/// [`fill_bytes`]: RngCore::fill_bytes
272298#[ derive( Clone ) ]
273299#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
274- pub struct BlockRng64 < R : BlockRngCore + ?Sized > {
275- results : R :: Results ,
300+ pub struct BlockRng64 < R : Generator + ?Sized > {
301+ results : R :: Result ,
276302 index : usize ,
277303 half_used : bool , // true if only half of the previous result is used
278304 /// The *core* part of the RNG, implementing the `generate` function.
279305 pub core : R ,
280306}
281307
282308// Custom Debug implementation that does not expose the contents of `results`.
283- impl < const N : usize , R : BlockRngCore < Results = [ u64 ; N ] > + fmt:: Debug > fmt:: Debug
309+ impl < const N : usize , R : Generator < Result = [ u64 ; N ] > + fmt:: Debug > fmt:: Debug
284310 for BlockRng64 < R >
285311{
286312 fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
@@ -293,9 +319,9 @@ impl<const N: usize, R: BlockRngCore<Results = [u64; N]> + fmt::Debug> fmt::Debu
293319 }
294320}
295321
296- impl < const N : usize , R : BlockRngCore < Results = [ u64 ; N ] > > BlockRng64 < R > {
322+ impl < const N : usize , R : Generator < Result = [ u64 ; N ] > > BlockRng64 < R > {
297323 /// Create a new `BlockRng` from an existing RNG implementing
298- /// `BlockRngCore `. Results will be generated on first use.
324+ /// `Generator `. Results will be generated on first use.
299325 #[ inline]
300326 pub fn new ( core : R ) -> BlockRng64 < R > {
301327 let results_empty = [ 0 ; N ] ;
@@ -336,7 +362,7 @@ impl<const N: usize, R: BlockRngCore<Results = [u64; N]>> BlockRng64<R> {
336362 }
337363}
338364
339- impl < const N : usize , R : BlockRngCore < Results = [ u64 ; N ] > > RngCore for BlockRng64 < R > {
365+ impl < const N : usize , R : Generator < Result = [ u64 ; N ] > > RngCore for BlockRng64 < R > {
340366 #[ inline]
341367 fn next_u32 ( & mut self ) -> u32 {
342368 let mut index = self . index - self . half_used as usize ;
@@ -388,7 +414,7 @@ impl<const N: usize, R: BlockRngCore<Results = [u64; N]>> RngCore for BlockRng64
388414 }
389415}
390416
391- impl < const N : usize , R : BlockRngCore < Results = [ u64 ; N ] > + SeedableRng > SeedableRng
417+ impl < const N : usize , R : Generator < Result = [ u64 ; N ] > + SeedableRng > SeedableRng
392418 for BlockRng64 < R >
393419{
394420 type Seed = R :: Seed ;
@@ -414,22 +440,22 @@ impl<const N: usize, R: BlockRngCore<Results = [u64; N]> + SeedableRng> Seedable
414440 }
415441}
416442
417- impl < const N : usize , R : CryptoBlockRng < Results = [ u64 ; N ] > > CryptoRng for BlockRng64 < R > { }
443+ impl < const N : usize , R : CryptoGenerator < Result = [ u64 ; N ] > > CryptoRng for BlockRng64 < R > { }
418444
419445#[ cfg( test) ]
420446mod test {
421- use crate :: block:: { BlockRng , BlockRng64 , BlockRngCore } ;
447+ use crate :: block:: { BlockRng , BlockRng64 , Generator } ;
422448 use crate :: { RngCore , SeedableRng } ;
423449
424450 #[ derive( Debug , Clone ) ]
425451 struct DummyRng {
426452 counter : u32 ,
427453 }
428454
429- impl BlockRngCore for DummyRng {
430- type Results = [ u32 ; 16 ] ;
455+ impl Generator for DummyRng {
456+ type Result = [ u32 ; 16 ] ;
431457
432- fn generate ( & mut self , results : & mut Self :: Results ) {
458+ fn generate ( & mut self , results : & mut Self :: Result ) {
433459 for r in results {
434460 * r = self . counter ;
435461 self . counter = self . counter . wrapping_add ( 3511615421 ) ;
@@ -476,10 +502,10 @@ mod test {
476502 counter : u64 ,
477503 }
478504
479- impl BlockRngCore for DummyRng64 {
480- type Results = [ u64 ; 8 ] ;
505+ impl Generator for DummyRng64 {
506+ type Result = [ u64 ; 8 ] ;
481507
482- fn generate ( & mut self , results : & mut Self :: Results ) {
508+ fn generate ( & mut self , results : & mut Self :: Result ) {
483509 for r in results {
484510 * r = self . counter ;
485511 self . counter = self . counter . wrapping_add ( 2781463553396133981 ) ;
0 commit comments