Skip to content

Commit 45f87af

Browse files
committed
Improve documentation
1 parent 449cb38 commit 45f87af

File tree

1 file changed

+43
-21
lines changed

1 file changed

+43
-21
lines changed

src/lib.rs

+43-21
Original file line numberDiff line numberDiff line change
@@ -752,36 +752,55 @@ 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.
762762
type Seed: SeedRestriction;
763763

764764
/// Create a new PRNG using the given seed.
765765
///
766-
/// Each PRNG should implement this.
766+
/// PRNG implementations are allowed to assume that bits in the seed are
767+
/// well distributed. That means usually that the number of one and zero
768+
/// bits are about equal, and values like 0, 1 and (size - 1) are unlikely.
767769
///
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.
770+
/// PRNG implementations are recommended to be reproducible. A PRNG seeded
771+
/// using this function with a fixed seed should produce the same sequence
772+
/// of output in the future and on different architectures (with for example
773+
/// different endianness).
774774
///
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.
775+
/// It is however not required that this function yield the same state as a
776+
/// reference implementation of the PRNG given equivalent seed; if necessary
777+
/// another constructor can be used.
777778
fn from_seed(seed: Self::Seed) -> Self;
778779

779780
/// Create a new PRNG seeded from another `Rng`.
780781
///
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.
782+
/// This is the recommended way to initialize PRNGs. See the `NewSeeded`
783+
/// trait that provides a convenient `new` method using `from_rng` and a
784+
/// good entropy source.
785+
///
786+
/// It is recommended to use a good source of randomness to initialize the
787+
/// PRNG. Otherwise small PRNG's could show statistical bias in the first
788+
/// couple of results, and possibly not use their entire period well.
789+
/// Cryptographic PRNG's can be less secure or even insecure when they are
790+
/// seeded from a non-cryptographic PRNG.
791+
///
792+
/// Examples of good RNG's for seeding are entropy sources like `OsRng` and
793+
/// `JitterRng`. Also cryptographically secure PRNG's (like `thread_rng`)
794+
/// can be used without hesitation.
795+
///
796+
/// Seeding a small PRNG from another small PRNG is be possible, but
797+
/// something to be careful with. An extreme example of how this can go
798+
/// wrong is seeding an Xorshift RNG from another Xorshift RNG. That will
799+
/// effectively clone the generator.
800+
///
801+
/// PRNG implementations are allowed to assume that a good RNG is provided
802+
/// for seeding, and that it is cryptographically secure when appropriate.
803+
/// There are no reproducibility requirements like endianness conversion.
785804
fn from_rng<R: Rng>(mut rng: R) -> Result<Self, Error> {
786805
let mut seed = Self::Seed::default();
787806
let size = mem::size_of::<Self::Seed>() as usize;
@@ -886,8 +905,11 @@ pub struct Closed01<F>(pub F);
886905
/// The standard RNG. This is designed to be efficient on the current
887906
/// platform.
888907
///
889-
/// The underlying algorithm is not fixed, thus values from this generator
890-
/// cannot be guaranteed to be reproducible.
908+
/// Reproducibility of output from this generator is not required, thus future
909+
/// library versions may use a different internal generator with different
910+
/// output. Further, this generator may not be portable and can produce
911+
/// different output depending on the architecture. If you require reproducible
912+
/// output, use a named RNG, for example `ChaChaRng`.
891913
#[derive(Clone, Debug)]
892914
pub struct StdRng(IsaacWordRng);
893915

0 commit comments

Comments
 (0)