Skip to content

Commit 8cfe210

Browse files
committed
Simplify and deprecate EntropyRng
1 parent 23e1f04 commit 8cfe210

File tree

6 files changed

+29
-208
lines changed

6 files changed

+29
-208
lines changed

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,6 @@ functionality depending on `std`:
102102

103103
- `thread_rng()`, and `random()` are not available, as they require thread-local
104104
storage and an entropy source.
105-
- `OsRng` and `EntropyRng` are unavailable.
106-
- `JitterRng` code is still present, but a nanosecond timer must be provided via
107-
`JitterRng::new_with_timer`
108105
- Since no external entropy is available, it is not possible to create
109106
generators with fresh seeds using the `FromEntropy` trait (user must provide
110107
a seed).

benches/generators.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use test::{black_box, Bencher};
2525

2626
use rand::prelude::*;
2727
use rand::rngs::adapter::ReseedingRng;
28-
use rand::rngs::{OsRng, JitterRng, EntropyRng};
28+
use rand::rngs::{OsRng, JitterRng};
2929
use rand_isaac::{IsaacRng, Isaac64Rng};
3030
use rand_chacha::ChaChaRng;
3131
use rand_hc::{Hc128Rng, Hc128Core};
@@ -185,7 +185,7 @@ const RESEEDING_THRESHOLD: u64 = 1024*1024*1024; // something high enough to get
185185
fn reseeding_hc128_bytes(b: &mut Bencher) {
186186
let mut rng = ReseedingRng::new(Hc128Core::from_entropy(),
187187
RESEEDING_THRESHOLD,
188-
EntropyRng::new());
188+
OsRng);
189189
let mut buf = [0u8; BYTES_LEN];
190190
b.iter(|| {
191191
for _ in 0..RAND_BENCH_N {
@@ -202,7 +202,7 @@ macro_rules! reseeding_uint {
202202
fn $fnn(b: &mut Bencher) {
203203
let mut rng = ReseedingRng::new(Hc128Core::from_entropy(),
204204
RESEEDING_THRESHOLD,
205-
EntropyRng::new());
205+
OsRng);
206206
b.iter(|| {
207207
let mut accum: $ty = 0;
208208
for _ in 0..RAND_BENCH_N {

src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ impl_as_byte_slice_arrays!(!div 4096, N,N,N,N,N,N,N,);
456456
/// entropy. This trait is automatically implemented for any PRNG implementing
457457
/// [`SeedableRng`] and is not intended to be implemented by users.
458458
///
459-
/// This is equivalent to using `SeedableRng::from_rng(EntropyRng::new())` then
459+
/// This is equivalent to using `SeedableRng::from_rng(OsRng)` then
460460
/// unwrapping the result.
461461
///
462462
/// Since this is convenient and secure, it is the recommended way to create
@@ -477,7 +477,7 @@ impl_as_byte_slice_arrays!(!div 4096, N,N,N,N,N,N,N,);
477477
/// println!("Random die roll: {}", rng.gen_range(1, 7));
478478
/// ```
479479
///
480-
/// [`EntropyRng`]: rngs::EntropyRng
480+
/// [`OsRng`]: rngs::OsRng
481481
#[cfg(feature="std")]
482482
pub trait FromEntropy: SeedableRng {
483483
/// Creates a new instance, automatically seeded with fresh entropy.
@@ -497,11 +497,11 @@ pub trait FromEntropy: SeedableRng {
497497
/// ```
498498
/// # use rand::Error;
499499
/// use rand::prelude::*;
500-
/// use rand::rngs::EntropyRng;
500+
/// use rand::rngs::OsRng;
501501
///
502502
/// # fn try_inner() -> Result<(), Error> {
503503
/// // This uses StdRng, but is valid for any R: SeedableRng
504-
/// let mut rng = StdRng::from_rng(EntropyRng::new())?;
504+
/// let mut rng = StdRng::from_rng(OsRng)?;
505505
///
506506
/// println!("random number: {}", rng.gen_range(1, 10));
507507
/// # Ok(())
@@ -515,7 +515,7 @@ pub trait FromEntropy: SeedableRng {
515515
#[cfg(feature="std")]
516516
impl<R: SeedableRng> FromEntropy for R {
517517
fn from_entropy() -> R {
518-
R::from_rng(rngs::EntropyRng::new()).unwrap_or_else(|err|
518+
R::from_rng(rngs::OsRng).unwrap_or_else(|err|
519519
panic!("FromEntropy::from_entropy() failed: {}", err))
520520
}
521521
}

src/rngs/entropy.rs

Lines changed: 12 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -8,51 +8,20 @@
88

99
//! Entropy generator, or wrapper around external generators
1010
11-
use rand_core::{RngCore, CryptoRng, Error, ErrorKind, impls};
11+
#![allow(deprecated)] // whole module is deprecated
12+
13+
use rand_core::{RngCore, CryptoRng, Error};
1214
#[allow(unused)]
13-
use rngs;
15+
use rngs::OsRng;
1416

1517
/// An interface returning random data from external source(s), provided
1618
/// specifically for securely seeding algorithmic generators (PRNGs).
1719
///
18-
/// Where possible, `EntropyRng` retrieves random data from the operating
19-
/// system's interface for random numbers ([`OsRng`]); if that fails it will
20-
/// fall back to the [`JitterRng`] entropy collector. In the latter case it will
21-
/// still try to use [`OsRng`] on the next usage.
22-
///
23-
/// If no secure source of entropy is available `EntropyRng` will panic on use;
24-
/// i.e. it should never output predictable data.
25-
///
26-
/// This is either a little slow ([`OsRng`] requires a system call) or extremely
27-
/// slow ([`JitterRng`] must use significant CPU time to generate sufficient
28-
/// jitter); for better performance it is common to seed a local PRNG from
29-
/// external entropy then primarily use the local PRNG ([`thread_rng`] is
30-
/// provided as a convenient, local, automatically-seeded CSPRNG).
31-
///
32-
/// # Panics
33-
///
34-
/// On most systems, like Windows, Linux, macOS and *BSD on common hardware, it
35-
/// is highly unlikely for both [`OsRng`] and [`JitterRng`] to fail. But on
36-
/// combinations like webassembly without Emscripten or stdweb both sources are
37-
/// unavailable. If both sources fail, only [`try_fill_bytes`] is able to
38-
/// report the error, and only the one from `OsRng`. The other [`RngCore`]
39-
/// methods will panic in case of an error.
40-
///
41-
/// [`OsRng`]: rngs::OsRng
42-
/// [`thread_rng`]: crate::thread_rng
43-
/// [`JitterRng`]: crate::rngs::JitterRng
44-
/// [`try_fill_bytes`]: RngCore::try_fill_bytes
20+
/// This is deprecated. It is suggested you use [`rngs::OsRng`] instead.
4521
#[derive(Debug)]
22+
#[deprecated(since="0.7.0", note="use rngs::OsRng instead")]
4623
pub struct EntropyRng {
47-
source: Source,
48-
}
49-
50-
#[derive(Debug)]
51-
enum Source {
52-
Os(Os),
53-
Custom(Custom),
54-
Jitter(Jitter),
55-
None,
24+
source: OsRng,
5625
}
5726

5827
impl EntropyRng {
@@ -62,7 +31,7 @@ impl EntropyRng {
6231
/// those are done on first use. This is done to make `new` infallible,
6332
/// and `try_fill_bytes` the only place to report errors.
6433
pub fn new() -> Self {
65-
EntropyRng { source: Source::None }
34+
EntropyRng { source: OsRng }
6635
}
6736
}
6837

@@ -74,167 +43,25 @@ impl Default for EntropyRng {
7443

7544
impl RngCore for EntropyRng {
7645
fn next_u32(&mut self) -> u32 {
77-
impls::next_u32_via_fill(self)
46+
self.source.next_u32()
7847
}
7948

8049
fn next_u64(&mut self) -> u64 {
81-
impls::next_u64_via_fill(self)
50+
self.source.next_u64()
8251
}
8352

8453
fn fill_bytes(&mut self, dest: &mut [u8]) {
85-
self.try_fill_bytes(dest).unwrap_or_else(|err|
86-
panic!("all entropy sources failed; first error: {}", err))
54+
self.source.fill_bytes(dest)
8755
}
8856

8957
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
90-
let mut reported_error = None;
91-
92-
if let Source::Os(ref mut os_rng) = self.source {
93-
match os_rng.fill(dest) {
94-
Ok(()) => return Ok(()),
95-
Err(err) => {
96-
warn!("EntropyRng: OsRng failed \
97-
[trying other entropy sources]: {}", err);
98-
reported_error = Some(err);
99-
},
100-
}
101-
} else if Os::is_supported() {
102-
match Os::new_and_fill(dest) {
103-
Ok(os_rng) => {
104-
debug!("EntropyRng: using OsRng");
105-
self.source = Source::Os(os_rng);
106-
return Ok(());
107-
},
108-
Err(err) => { reported_error = reported_error.or(Some(err)) },
109-
}
110-
}
111-
112-
if let Source::Custom(ref mut rng) = self.source {
113-
match rng.fill(dest) {
114-
Ok(()) => return Ok(()),
115-
Err(err) => {
116-
warn!("EntropyRng: custom entropy source failed \
117-
[trying other entropy sources]: {}", err);
118-
reported_error = Some(err);
119-
},
120-
}
121-
} else if Custom::is_supported() {
122-
match Custom::new_and_fill(dest) {
123-
Ok(custom) => {
124-
debug!("EntropyRng: using custom entropy source");
125-
self.source = Source::Custom(custom);
126-
return Ok(());
127-
},
128-
Err(err) => { reported_error = reported_error.or(Some(err)) },
129-
}
130-
}
131-
132-
if let Source::Jitter(ref mut jitter_rng) = self.source {
133-
match jitter_rng.fill(dest) {
134-
Ok(()) => return Ok(()),
135-
Err(err) => {
136-
warn!("EntropyRng: JitterRng failed: {}", err);
137-
reported_error = Some(err);
138-
},
139-
}
140-
} else if Jitter::is_supported() {
141-
match Jitter::new_and_fill(dest) {
142-
Ok(jitter_rng) => {
143-
debug!("EntropyRng: using JitterRng");
144-
self.source = Source::Jitter(jitter_rng);
145-
return Ok(());
146-
},
147-
Err(err) => { reported_error = reported_error.or(Some(err)) },
148-
}
149-
}
150-
151-
if let Some(err) = reported_error {
152-
Err(Error::with_cause(ErrorKind::Unavailable,
153-
"All entropy sources failed",
154-
err))
155-
} else {
156-
Err(Error::new(ErrorKind::Unavailable,
157-
"No entropy sources available"))
158-
}
58+
self.source.try_fill_bytes(dest)
15959
}
16060
}
16161

16262
impl CryptoRng for EntropyRng {}
16363

16464

165-
166-
trait EntropySource {
167-
fn new_and_fill(dest: &mut [u8]) -> Result<Self, Error>
168-
where Self: Sized;
169-
170-
fn fill(&mut self, dest: &mut [u8]) -> Result<(), Error>;
171-
172-
fn is_supported() -> bool { true }
173-
}
174-
175-
#[allow(unused)]
176-
#[derive(Clone, Debug)]
177-
struct NoSource;
178-
179-
#[allow(unused)]
180-
impl EntropySource for NoSource {
181-
fn new_and_fill(dest: &mut [u8]) -> Result<Self, Error> {
182-
Err(Error::new(ErrorKind::Unavailable, "Source not supported"))
183-
}
184-
185-
fn fill(&mut self, dest: &mut [u8]) -> Result<(), Error> {
186-
unreachable!()
187-
}
188-
189-
fn is_supported() -> bool { false }
190-
}
191-
192-
193-
#[cfg(feature="getrandom")]
194-
#[derive(Clone, Debug)]
195-
pub struct Os(rngs::OsRng);
196-
197-
#[cfg(feature="getrandom")]
198-
impl EntropySource for Os {
199-
fn new_and_fill(dest: &mut [u8]) -> Result<Self, Error> {
200-
let rng = rngs::OsRng;
201-
rngs::OsRng.try_fill_bytes(dest)?;
202-
Ok(Os(rng))
203-
}
204-
205-
fn fill(&mut self, dest: &mut [u8]) -> Result<(), Error> {
206-
self.0.try_fill_bytes(dest)
207-
}
208-
}
209-
210-
#[cfg(not(feature="std"))]
211-
type Os = NoSource;
212-
213-
214-
type Custom = NoSource;
215-
216-
217-
#[cfg(not(target_arch = "wasm32"))]
218-
#[derive(Clone, Debug)]
219-
pub struct Jitter(rngs::JitterRng);
220-
221-
#[cfg(not(target_arch = "wasm32"))]
222-
impl EntropySource for Jitter {
223-
fn new_and_fill(dest: &mut [u8]) -> Result<Self, Error> {
224-
let mut rng = rngs::JitterRng::new()?;
225-
rng.try_fill_bytes(dest)?;
226-
Ok(Jitter(rng))
227-
}
228-
229-
fn fill(&mut self, dest: &mut [u8]) -> Result<(), Error> {
230-
self.0.try_fill_bytes(dest)
231-
}
232-
}
233-
234-
#[cfg(target_arch = "wasm32")]
235-
type Jitter = NoSource;
236-
237-
23865
#[cfg(test)]
23966
mod test {
24067
use super::*;

src/rngs/mod.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//!
1111
//! - [`ThreadRng`], a fast, secure, auto-seeded thread-local generator
1212
//! - [`StdRng`] and [`SmallRng`], algorithms to cover typical usage
13-
//! - [`EntropyRng`], [`OsRng`] and [`JitterRng`] as entropy sources
13+
//! - [`OsRng`] as an entropy source
1414
//! - [`mock::StepRng`] as a simple counter for tests
1515
//! - [`adapter::ReadRng`] to read from a file/stream
1616
//! - [`adapter::ReseedingRng`] to reseed a PRNG on clone / process fork etc.
@@ -26,8 +26,6 @@
2626
//! use that to seed its own PRNG; [`OsRng`] provides an interface to this.
2727
//! [`JitterRng`] is an entropy collector included with Rand that measures
2828
//! jitter in the CPU execution time, and jitter in memory access time.
29-
//! [`EntropyRng`] is a wrapper that uses the best entropy source that is
30-
//! available.
3129
//!
3230
//! ## Pseudo-random number generators
3331
//!
@@ -78,7 +76,7 @@
7876
//! - [`FromEntropy::from_entropy`]; this is the most convenient way to seed
7977
//! with fresh, secure random data.
8078
//! - [`SeedableRng::from_rng`]; this allows seeding from another PRNG or
81-
//! from an entropy source such as [`EntropyRng`].
79+
//! from an entropy source such as [`OsRng`].
8280
//! - [`SeedableRng::from_seed`]; this is mostly useful if you wish to be able
8381
//! to reproduce the output sequence by using a fixed seed. (Don't use
8482
//! [`StdRng`] or [`SmallRng`] in this case since different algorithms may be
@@ -138,7 +136,6 @@
138136
//! [`SmallRng`]: rngs::SmallRng
139137
//! [`StdRng`]: rngs::StdRng
140138
//! [`ThreadRng`]: rngs::ThreadRng
141-
//! [`EntropyRng`]: rngs::EntropyRng
142139
//! [`JitterRng`]: rngs::JitterRng
143140
//! [`mock::StepRng`]: rngs::mock::StepRng
144141
//! [`adapter::ReadRng`]: rngs::adapter::ReadRng
@@ -156,6 +153,7 @@ mod std;
156153

157154

158155
pub use rand_jitter::{JitterRng, TimerError};
156+
#[allow(deprecated)]
159157
#[cfg(feature="std")] pub use self::entropy::EntropyRng;
160158

161159
pub use self::small::SmallRng;

0 commit comments

Comments
 (0)