Skip to content

Commit 169fa06

Browse files
committed
ReseedingRng: use new rand_core::block::Generator trait
1 parent 86adc17 commit 169fa06

File tree

1 file changed

+40
-30
lines changed

1 file changed

+40
-30
lines changed

src/rngs/reseeding.rs

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010
//! A wrapper around another PRNG that reseeds it after it
1111
//! generates a certain number of random bytes.
1212
13+
use core::fmt;
1314
use core::mem::size_of_val;
1415

15-
use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng};
16+
use rand_core::block::{BlockRng, CryptoGenerator, Generator};
1617
use rand_core::{CryptoRng, RngCore, SeedableRng, TryCryptoRng, TryRngCore};
1718

18-
/// A wrapper around any PRNG that implements [`BlockRngCore`], that adds the
19+
/// A wrapper around any PRNG that implements [`Generator`], that adds the
1920
/// ability to reseed it.
2021
///
2122
/// `ReseedingRng` reseeds the underlying PRNG in the following cases:
@@ -53,7 +54,7 @@ use rand_core::{CryptoRng, RngCore, SeedableRng, TryCryptoRng, TryRngCore};
5354
///
5455
/// ```
5556
/// use chacha20::ChaCha20Core; // Internal part of ChaChaRng that
56-
/// // implements BlockRngCore
57+
/// // implements Generator
5758
/// use rand::prelude::*;
5859
/// use rand::rngs::OsRng;
5960
/// use rand::rngs::ReseedingRng;
@@ -63,18 +64,28 @@ use rand_core::{CryptoRng, RngCore, SeedableRng, TryCryptoRng, TryRngCore};
6364
/// println!("{}", reseeding_rng.random::<u64>());
6465
/// ```
6566
///
66-
/// [`BlockRngCore`]: rand_core::block::BlockRngCore
67+
/// [`Generator`]: rand_core::block::Generator
6768
/// [`ReseedingRng::new`]: ReseedingRng::new
6869
/// [`reseed()`]: ReseedingRng::reseed
69-
#[derive(Debug)]
70-
pub struct ReseedingRng<R, Rsdr>(BlockRng<ReseedingCore<R, Rsdr>>)
70+
pub struct ReseedingRng<G, Rsdr>(BlockRng<ReseedingCore<G, Rsdr>>)
7171
where
72-
R: BlockRngCore + SeedableRng,
72+
G: Generator + SeedableRng,
7373
Rsdr: TryRngCore;
7474

75-
impl<R, Rsdr> ReseedingRng<R, Rsdr>
75+
impl<G: fmt::Debug, Rsdr: fmt::Debug> fmt::Debug for ReseedingRng<G, Rsdr>
76+
where
77+
G: Generator + SeedableRng,
78+
G::Output: fmt::Debug,
79+
Rsdr: TryRngCore,
80+
{
81+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82+
f.debug_tuple("ReseedingRng").field(&self.0).finish()
83+
}
84+
}
85+
86+
impl<const N: usize, G, Rsdr> ReseedingRng<G, Rsdr>
7687
where
77-
R: BlockRngCore + SeedableRng,
88+
G: Generator<Output = [u32; N]> + SeedableRng,
7889
Rsdr: TryRngCore,
7990
{
8091
/// Create a new `ReseedingRng` from an existing PRNG, combined with a RNG
@@ -100,9 +111,9 @@ where
100111

101112
// TODO: this should be implemented for any type where the inner type
102113
// implements RngCore, but we can't specify that because ReseedingCore is private
103-
impl<R, Rsdr> RngCore for ReseedingRng<R, Rsdr>
114+
impl<const N: usize, G, Rsdr> RngCore for ReseedingRng<G, Rsdr>
104115
where
105-
R: BlockRngCore<Item = u32> + SeedableRng,
116+
G: Generator<Output = [u32; N]> + SeedableRng,
106117
Rsdr: TryRngCore,
107118
{
108119
#[inline(always)]
@@ -120,51 +131,50 @@ where
120131
}
121132
}
122133

123-
impl<R, Rsdr> CryptoRng for ReseedingRng<R, Rsdr>
134+
impl<const N: usize, G, Rsdr> CryptoRng for ReseedingRng<G, Rsdr>
124135
where
125-
R: BlockRngCore<Item = u32> + SeedableRng + CryptoBlockRng,
136+
G: Generator<Output = [u32; N]> + SeedableRng + CryptoGenerator,
126137
Rsdr: TryCryptoRng,
127138
{
128139
}
129140

130141
#[derive(Debug)]
131-
struct ReseedingCore<R, Rsdr> {
132-
inner: R,
142+
struct ReseedingCore<G, Rsdr> {
143+
inner: G,
133144
reseeder: Rsdr,
134145
threshold: i64,
135146
bytes_until_reseed: i64,
136147
}
137148

138-
impl<R, Rsdr> BlockRngCore for ReseedingCore<R, Rsdr>
149+
impl<G, Rsdr> Generator for ReseedingCore<G, Rsdr>
139150
where
140-
R: BlockRngCore + SeedableRng,
151+
G: Generator + SeedableRng,
141152
Rsdr: TryRngCore,
142153
{
143-
type Item = <R as BlockRngCore>::Item;
144-
type Results = <R as BlockRngCore>::Results;
154+
type Output = <G as Generator>::Output;
145155

146-
fn generate(&mut self, results: &mut Self::Results) {
156+
fn generate(&mut self, results: &mut Self::Output) {
147157
if self.bytes_until_reseed <= 0 {
148158
// We get better performance by not calling only `reseed` here
149159
// and continuing with the rest of the function, but by directly
150160
// returning from a non-inlined function.
151161
return self.reseed_and_generate(results);
152162
}
153-
let num_bytes = size_of_val(results.as_ref());
163+
let num_bytes = size_of_val(results);
154164
self.bytes_until_reseed -= num_bytes as i64;
155165
self.inner.generate(results);
156166
}
157167
}
158168

159-
impl<R, Rsdr> ReseedingCore<R, Rsdr>
169+
impl<G, Rsdr> ReseedingCore<G, Rsdr>
160170
where
161-
R: BlockRngCore + SeedableRng,
171+
G: Generator + SeedableRng,
162172
Rsdr: TryRngCore,
163173
{
164174
/// Create a new `ReseedingCore`.
165175
///
166176
/// `threshold` is the maximum number of bytes produced by
167-
/// [`BlockRngCore::generate`] before attempting reseeding.
177+
/// [`Generator::generate`] before attempting reseeding.
168178
fn new(threshold: u64, mut reseeder: Rsdr) -> Result<Self, Rsdr::Error> {
169179
// Because generating more values than `i64::MAX` takes centuries on
170180
// current hardware, we just clamp to that value.
@@ -178,7 +188,7 @@ where
178188
i64::MAX
179189
};
180190

181-
let inner = R::try_from_rng(&mut reseeder)?;
191+
let inner = G::try_from_rng(&mut reseeder)?;
182192

183193
Ok(ReseedingCore {
184194
inner,
@@ -190,17 +200,17 @@ where
190200

191201
/// Reseed the internal PRNG.
192202
fn reseed(&mut self) -> Result<(), Rsdr::Error> {
193-
R::try_from_rng(&mut self.reseeder).map(|result| {
203+
G::try_from_rng(&mut self.reseeder).map(|result| {
194204
self.bytes_until_reseed = self.threshold;
195205
self.inner = result
196206
})
197207
}
198208

199209
#[inline(never)]
200-
fn reseed_and_generate(&mut self, results: &mut <Self as BlockRngCore>::Results) {
210+
fn reseed_and_generate(&mut self, results: &mut G::Output) {
201211
trace!("Reseeding RNG (periodic reseed)");
202212

203-
let num_bytes = size_of_val(results.as_ref());
213+
let num_bytes = size_of_val(results);
204214

205215
if let Err(e) = self.reseed() {
206216
warn!("Reseeding RNG failed: {}", e);
@@ -212,9 +222,9 @@ where
212222
}
213223
}
214224

215-
impl<R, Rsdr> CryptoBlockRng for ReseedingCore<R, Rsdr>
225+
impl<G, Rsdr> CryptoGenerator for ReseedingCore<G, Rsdr>
216226
where
217-
R: BlockRngCore<Item = u32> + SeedableRng + CryptoBlockRng,
227+
G: Generator + SeedableRng + CryptoGenerator,
218228
Rsdr: TryCryptoRng,
219229
{
220230
}

0 commit comments

Comments
 (0)