Skip to content

Commit b21d1a9

Browse files
committed
Improve documentation
1 parent 449cb38 commit b21d1a9

File tree

1 file changed

+46
-21
lines changed

1 file changed

+46
-21
lines changed

src/lib.rs

+46-21
Original file line numberDiff line numberDiff line change
@@ -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.
760756
pub 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)]
892917
pub struct StdRng(IsaacWordRng);
893918

0 commit comments

Comments
 (0)