Skip to content

Commit a21d11e

Browse files
committed
Merge with master and update CHANGELOG
2 parents 12d27e8 + 8ca4d2a commit a21d11e

File tree

4 files changed

+211
-30
lines changed

4 files changed

+211
-30
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [Unreleased]
8+
### Other
9+
- Remove `zerocopy` dependency (#1607)
10+
11+
## [0.9.2] - 2025-02-22
12+
### API changes
13+
- Relax `Sized` bound on impls of `TryRngCore`, `TryCryptoRng` and `UnwrapMut` (#1593)
14+
- Add `UnwrapMut::re` to reborrow the inner rng with a tighter lifetime (#1595)
15+
16+
## [0.9.1] - 2025-02-16
17+
### API changes
18+
- Add `TryRngCore::unwrap_mut`, providing an impl of `RngCore` over `&mut rng` (#1589)
19+
720
## [0.9.0] - 2025-01-27
821
### Dependencies and features
922
- Bump the MSRV to 1.63.0 (#1207, #1246, #1269, #1341, #1416, #1536); note that 1.60.0 may work for dependents when using `--ignore-rust-version`

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rand_core"
3-
version = "0.9.0"
3+
version = "0.9.2"
44
authors = ["The Rand Project Developers", "The Rust Project Developers"]
55
license = "MIT OR Apache-2.0"
66
readme = "README.md"

src/block.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ impl<R: BlockRngCore<Item = u32>> RngCore for BlockRng<R> {
197197
fn next_u64(&mut self) -> u64 {
198198
let read_u64 = |results: &[u32], index| {
199199
let data = &results[index..=index + 1];
200-
u64::from(data[1]) << 32 | u64::from(data[0])
200+
(u64::from(data[1]) << 32) | u64::from(data[0])
201201
};
202202

203203
let len = self.results.as_ref().len();

src/lib.rs

Lines changed: 196 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -175,32 +175,32 @@ where
175175
}
176176
}
177177

178-
/// A marker trait used to indicate that an [`RngCore`] implementation is
179-
/// supposed to be cryptographically secure.
180-
///
181-
/// *Cryptographically secure generators*, also known as *CSPRNGs*, should
182-
/// satisfy an additional properties over other generators: given the first
183-
/// *k* bits of an algorithm's output
178+
/// A marker trait over [`RngCore`] for securely unpredictable RNGs
179+
///
180+
/// This marker trait indicates that the implementing generator is intended,
181+
/// when correctly seeded and protected from side-channel attacks such as a
182+
/// leaking of state, to be a cryptographically secure generator. This trait is
183+
/// provided as a tool to aid review of cryptographic code, but does not by
184+
/// itself guarantee suitability for cryptographic applications.
185+
///
186+
/// Implementors of `CryptoRng` automatically implement the [`TryCryptoRng`]
187+
/// trait.
188+
///
189+
/// Implementors of `CryptoRng` should only implement [`Default`] if the
190+
/// `default()` instances are themselves secure generators: for example if the
191+
/// implementing type is a stateless interface over a secure external generator
192+
/// (like [`OsRng`]) or if the `default()` instance uses a strong, fresh seed.
193+
///
194+
/// Formally, a CSPRNG (Cryptographically Secure Pseudo-Random Number Generator)
195+
/// should satisfy an additional property over other generators: assuming that
196+
/// the generator has been appropriately seeded and has unknown state, then
197+
/// given the first *k* bits of an algorithm's output
184198
/// sequence, it should not be possible using polynomial-time algorithms to
185199
/// predict the next bit with probability significantly greater than 50%.
186200
///
187-
/// Some generators may satisfy an additional property, however this is not
188-
/// required by this trait: if the CSPRNG's state is revealed, it should not be
189-
/// computationally-feasible to reconstruct output prior to this. Some other
190-
/// generators allow backwards-computation and are considered *reversible*.
191-
///
192-
/// Note that this trait is provided for guidance only and cannot guarantee
193-
/// suitability for cryptographic applications. In general it should only be
194-
/// implemented for well-reviewed code implementing well-regarded algorithms.
195-
///
196-
/// Note also that use of a `CryptoRng` does not protect against other
197-
/// weaknesses such as seeding from a weak entropy source or leaking state.
198-
///
199-
/// Note that implementors of [`CryptoRng`] also automatically implement
200-
/// the [`TryCryptoRng`] trait.
201-
///
202-
/// [`BlockRngCore`]: block::BlockRngCore
203-
/// [`Infallible`]: core::convert::Infallible
201+
/// An optional property of CSPRNGs is backtracking resistance: if the CSPRNG's
202+
/// state is revealed, it will not be computationally-feasible to reconstruct
203+
/// prior output values. This property is not required by `CryptoRng`.
204204
pub trait CryptoRng: RngCore {}
205205

206206
impl<T: DerefMut> CryptoRng for T where T::Target: CryptoRng {}
@@ -236,6 +236,11 @@ pub trait TryRngCore {
236236
UnwrapErr(self)
237237
}
238238

239+
/// Wrap RNG with the [`UnwrapMut`] wrapper.
240+
fn unwrap_mut(&mut self) -> UnwrapMut<'_, Self> {
241+
UnwrapMut(self)
242+
}
243+
239244
/// Convert an [`RngCore`] to a [`RngReadAdapter`].
240245
#[cfg(feature = "std")]
241246
fn read_adapter(&mut self) -> RngReadAdapter<'_, Self>
@@ -249,7 +254,7 @@ pub trait TryRngCore {
249254
// Note that, unfortunately, this blanket impl prevents us from implementing
250255
// `TryRngCore` for types which can be dereferenced to `TryRngCore`, i.e. `TryRngCore`
251256
// will not be automatically implemented for `&mut R`, `Box<R>`, etc.
252-
impl<R: RngCore> TryRngCore for R {
257+
impl<R: RngCore + ?Sized> TryRngCore for R {
253258
type Error = core::convert::Infallible;
254259

255260
#[inline]
@@ -269,13 +274,23 @@ impl<R: RngCore> TryRngCore for R {
269274
}
270275
}
271276

272-
/// A marker trait used to indicate that a [`TryRngCore`] implementation is
273-
/// supposed to be cryptographically secure.
277+
/// A marker trait over [`TryRngCore`] for securely unpredictable RNGs
278+
///
279+
/// This trait is like [`CryptoRng`] but for the trait [`TryRngCore`].
274280
///
275-
/// See [`CryptoRng`] docs for more information about cryptographically secure generators.
281+
/// This marker trait indicates that the implementing generator is intended,
282+
/// when correctly seeded and protected from side-channel attacks such as a
283+
/// leaking of state, to be a cryptographically secure generator. This trait is
284+
/// provided as a tool to aid review of cryptographic code, but does not by
285+
/// itself guarantee suitability for cryptographic applications.
286+
///
287+
/// Implementors of `TryCryptoRng` should only implement [`Default`] if the
288+
/// `default()` instances are themselves secure generators: for example if the
289+
/// implementing type is a stateless interface over a secure external generator
290+
/// (like [`OsRng`]) or if the `default()` instance uses a strong, fresh seed.
276291
pub trait TryCryptoRng: TryRngCore {}
277292

278-
impl<R: CryptoRng> TryCryptoRng for R {}
293+
impl<R: CryptoRng + ?Sized> TryCryptoRng for R {}
279294

280295
/// Wrapper around [`TryRngCore`] implementation which implements [`RngCore`]
281296
/// by panicking on potential errors.
@@ -301,6 +316,45 @@ impl<R: TryRngCore> RngCore for UnwrapErr<R> {
301316

302317
impl<R: TryCryptoRng> CryptoRng for UnwrapErr<R> {}
303318

319+
/// Wrapper around [`TryRngCore`] implementation which implements [`RngCore`]
320+
/// by panicking on potential errors.
321+
#[derive(Debug, Eq, PartialEq, Hash)]
322+
pub struct UnwrapMut<'r, R: TryRngCore + ?Sized>(pub &'r mut R);
323+
324+
impl<'r, R: TryRngCore + ?Sized> UnwrapMut<'r, R> {
325+
/// Reborrow with a new lifetime
326+
///
327+
/// Rust allows references like `&T` or `&mut T` to be "reborrowed" through
328+
/// coercion: essentially, the pointer is copied under a new, shorter, lifetime.
329+
/// Until rfcs#1403 lands, reborrows on user types require a method call.
330+
#[inline(always)]
331+
pub fn re<'b>(&'b mut self) -> UnwrapMut<'b, R>
332+
where
333+
'r: 'b,
334+
{
335+
UnwrapMut(self.0)
336+
}
337+
}
338+
339+
impl<R: TryRngCore + ?Sized> RngCore for UnwrapMut<'_, R> {
340+
#[inline]
341+
fn next_u32(&mut self) -> u32 {
342+
self.0.try_next_u32().unwrap()
343+
}
344+
345+
#[inline]
346+
fn next_u64(&mut self) -> u64 {
347+
self.0.try_next_u64().unwrap()
348+
}
349+
350+
#[inline]
351+
fn fill_bytes(&mut self, dst: &mut [u8]) {
352+
self.0.try_fill_bytes(dst).unwrap()
353+
}
354+
}
355+
356+
impl<R: TryCryptoRng + ?Sized> CryptoRng for UnwrapMut<'_, R> {}
357+
304358
/// A random number generator that can be explicitly seeded.
305359
///
306360
/// This trait encapsulates the low-level functionality common to all
@@ -600,4 +654,118 @@ mod test {
600654
// value-breakage test:
601655
assert_eq!(results[0], 5029875928683246316);
602656
}
657+
658+
// A stub RNG.
659+
struct SomeRng;
660+
661+
impl RngCore for SomeRng {
662+
fn next_u32(&mut self) -> u32 {
663+
unimplemented!()
664+
}
665+
fn next_u64(&mut self) -> u64 {
666+
unimplemented!()
667+
}
668+
fn fill_bytes(&mut self, _: &mut [u8]) {
669+
unimplemented!()
670+
}
671+
}
672+
673+
impl CryptoRng for SomeRng {}
674+
675+
#[test]
676+
fn dyn_rngcore_to_tryrngcore() {
677+
// Illustrates the need for `+ ?Sized` bound in `impl<R: RngCore> TryRngCore for R`.
678+
679+
// A method in another crate taking a fallible RNG
680+
fn third_party_api(_rng: &mut (impl TryRngCore + ?Sized)) -> bool {
681+
true
682+
}
683+
684+
// A method in our crate requiring an infallible RNG
685+
fn my_api(rng: &mut dyn RngCore) -> bool {
686+
// We want to call the method above
687+
third_party_api(rng)
688+
}
689+
690+
assert!(my_api(&mut SomeRng));
691+
}
692+
693+
#[test]
694+
fn dyn_cryptorng_to_trycryptorng() {
695+
// Illustrates the need for `+ ?Sized` bound in `impl<R: CryptoRng> TryCryptoRng for R`.
696+
697+
// A method in another crate taking a fallible RNG
698+
fn third_party_api(_rng: &mut (impl TryCryptoRng + ?Sized)) -> bool {
699+
true
700+
}
701+
702+
// A method in our crate requiring an infallible RNG
703+
fn my_api(rng: &mut dyn CryptoRng) -> bool {
704+
// We want to call the method above
705+
third_party_api(rng)
706+
}
707+
708+
assert!(my_api(&mut SomeRng));
709+
}
710+
711+
#[test]
712+
fn dyn_unwrap_mut_tryrngcore() {
713+
// Illustrates the need for `+ ?Sized` bound in
714+
// `impl<R: TryRngCore> RngCore for UnwrapMut<'_, R>`.
715+
716+
fn third_party_api(_rng: &mut impl RngCore) -> bool {
717+
true
718+
}
719+
720+
fn my_api(rng: &mut (impl TryRngCore + ?Sized)) -> bool {
721+
let mut infallible_rng = rng.unwrap_mut();
722+
third_party_api(&mut infallible_rng)
723+
}
724+
725+
assert!(my_api(&mut SomeRng));
726+
}
727+
728+
#[test]
729+
fn dyn_unwrap_mut_trycryptorng() {
730+
// Illustrates the need for `+ ?Sized` bound in
731+
// `impl<R: TryCryptoRng> CryptoRng for UnwrapMut<'_, R>`.
732+
733+
fn third_party_api(_rng: &mut impl CryptoRng) -> bool {
734+
true
735+
}
736+
737+
fn my_api(rng: &mut (impl TryCryptoRng + ?Sized)) -> bool {
738+
let mut infallible_rng = rng.unwrap_mut();
739+
third_party_api(&mut infallible_rng)
740+
}
741+
742+
assert!(my_api(&mut SomeRng));
743+
}
744+
745+
#[test]
746+
fn reborrow_unwrap_mut() {
747+
struct FourRng;
748+
749+
impl TryRngCore for FourRng {
750+
type Error = core::convert::Infallible;
751+
fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
752+
Ok(4)
753+
}
754+
fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
755+
unimplemented!()
756+
}
757+
fn try_fill_bytes(&mut self, _: &mut [u8]) -> Result<(), Self::Error> {
758+
unimplemented!()
759+
}
760+
}
761+
762+
let mut rng = FourRng;
763+
let mut rng = rng.unwrap_mut();
764+
765+
assert_eq!(rng.next_u32(), 4);
766+
let mut rng2 = rng.re();
767+
assert_eq!(rng2.next_u32(), 4);
768+
drop(rng2);
769+
assert_eq!(rng.next_u32(), 4);
770+
}
603771
}

0 commit comments

Comments
 (0)