@@ -752,36 +752,58 @@ impl<S> SeedRestriction for S where S: private::Sealed + Default + AsMut<[u8]> {
752752
753753/// A random number generator that can be explicitly seeded.
754754///
755- /// There are two subtle differences between `from_rng` and`from_seed` (beyond
756- /// the obvious): first, that `from_rng` has no reproducibility requirement, and
757- /// second, that `from_rng` may directly fill internal states larger than
758- /// `SeedableRng::Seed`, where `from_seed` may need some extra step to expand
759- /// the input.
755+ /// Each pseudo-random number generator (PRNG) should implement this.
760756pub trait SeedableRng : Sized {
761- /// Seed type.
757+ /// Seed type, which is restricted to `u8` arrays with a length of
758+ /// 4, 8, 12, 16, 24 and 32.
759+ ///
760+ /// It is recommended to seed PRNG's with a seed of more than circa
761+ /// 100 bits, which means an array of `[u8; 12]` or greater to avoid picking
762+ /// RNG's with partially overlapping periods.
763+ ///
764+ /// For cryptographic RNG's a seed of 256 bits is recommended, `[u8; 32]`.
762765 type Seed : SeedRestriction ;
763766
764767 /// Create a new PRNG using the given seed.
765768 ///
766- /// Each PRNG should implement this.
769+ /// PRNG implementations are allowed to assume that bits in the seed are
770+ /// well distributed. That means usually that the number of one and zero
771+ /// bits are about equal, and values like 0, 1 and (size - 1) are unlikely.
767772 ///
768- /// Reproducibility is required; that is, a fixed PRNG seeded using this
769- /// function with a fixed seed should produce the same sequence of output
770- /// today, and in the future. PRNGs not able to satisfy this should make
771- /// clear notes in their documentation. It is however not required that this
772- /// function yield the same state as a reference implementation of the PRNG
773- /// given equivalent seed; if necessary another constructor should be used.
773+ /// PRNG implementations are recommended to be reproducible. A PRNG seeded
774+ /// using this function with a fixed seed should produce the same sequence
775+ /// of output in the future and on different architectures (with for example
776+ /// different endianness).
774777 ///
775- /// It may be expected that bits in the seed are well distributed, i.e. that
776- /// values like 0, 1 and (size - 1) are unlikely.
778+ /// It is however not required that this function yield the same state as a
779+ /// reference implementation of the PRNG given equivalent seed; if necessary
780+ /// another constructor can be used.
777781 fn from_seed ( seed : Self :: Seed ) -> Self ;
778782
779783 /// Create a new PRNG seeded from another `Rng`.
780784 ///
781- /// Seeding from a cryptographic generator should be fine. On the other
782- /// hand, seeding a simple numerical generator from another of the same
783- /// type sometimes has serious side effects such as effectively cloning the
784- /// generator.
785+ /// This is the recommended way to initialize PRNGs. See the `NewSeeded`
786+ /// trait that provides a convenient `new` method using `from_rng` and a
787+ /// good entropy source.
788+ ///
789+ /// It is recommended to use a good source of randomness to initialize the
790+ /// PRNG. Otherwise small PRNG's could show statistical bias in the first
791+ /// couple of results, and possibly not use their entire period well.
792+ /// Cryptographic PRNG's can be less secure or even insecure when they are
793+ /// seeded from a non-cryptographic PRNG.
794+ ///
795+ /// Examples of good RNG's for seeding are entropy sources like `OsRng` and
796+ /// `JitterRng`. Also cryptographically secure PRNG's (like `thread_rng`)
797+ /// can be used without hesitation.
798+ ///
799+ /// Seeding a small PRNG from another small PRNG is be possible, but
800+ /// something to be careful with. An extreme example of how this can go
801+ /// wrong is seeding an Xorshift RNG from another Xorshift RNG. That will
802+ /// effectively clone the generator.
803+ ///
804+ /// PRNG implementations are allowed to assume that a good RNG is provided
805+ /// for seeding, and that it is cryptographically secure when appropriate.
806+ /// There are no reproducibility requirements like endianness conversion.
785807 fn from_rng < R : Rng > ( mut rng : R ) -> Result < Self , Error > {
786808 let mut seed = Self :: Seed :: default ( ) ;
787809 let size = mem:: size_of :: < Self :: Seed > ( ) as usize ;
@@ -886,8 +908,11 @@ pub struct Closed01<F>(pub F);
886908/// The standard RNG. This is designed to be efficient on the current
887909/// platform.
888910///
889- /// The underlying algorithm is not fixed, thus values from this generator
890- /// cannot be guaranteed to be reproducible.
911+ /// Reproducibility of output from this generator is not required, thus future
912+ /// library versions may use a different internal generator with different
913+ /// output. Further, this generator may not be portable and can produce
914+ /// different output depending on the architecture. If you require reproducible
915+ /// output, use a named RNG, for example `ChaChaRng`.
891916#[ derive( Clone , Debug ) ]
892917pub struct StdRng ( IsaacWordRng ) ;
893918
0 commit comments