@@ -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`.
204204pub trait CryptoRng : RngCore { }
205205
206206impl < 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.
276291pub 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
302317impl < 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