Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

README: rand is not a crypto library #1514

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@
[![API](https://img.shields.io/badge/api-master-yellow.svg)](https://rust-random.github.io/rand/rand)
[![API](https://docs.rs/rand/badge.svg)](https://docs.rs/rand)

Rand is a Rust library supporting random generators:
Rand is a set of crates supporting (pseudo-)random generators:

- A standard RNG trait: [`rand_core::RngCore`](https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html)
- Fast implementations of the best-in-class [cryptographic](https://rust-random.github.io/book/guide-rngs.html#cryptographically-secure-pseudo-random-number-generators-csprngs) and
[non-cryptographic](https://rust-random.github.io/book/guide-rngs.html#basic-pseudo-random-number-generators-prngs) generators: [`rand::rngs`](https://docs.rs/rand/latest/rand/rngs/index.html), and more RNGs: [`rand_chacha`](https://docs.rs/rand_chacha), [`rand_xoshiro`](https://docs.rs/rand_xoshiro/), [`rand_pcg`](https://docs.rs/rand_pcg/), [rngs repo](https://github.com/rust-random/rngs/)
- [`rand::rng`](https://docs.rs/rand/latest/rand/fn.rng.html) is an asymtotically-fast, reasonably secure generator available on all `std` targets
- Secure seeding via the [`getrandom` crate](https://crates.io/crates/getrandom)
- Built over a standard RNG trait: [`rand_core::RngCore`](https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html)
- With fast implementations of both [strong](https://rust-random.github.io/book/guide-rngs.html#cryptographically-secure-pseudo-random-number-generators-csprngs) and
[small](https://rust-random.github.io/book/guide-rngs.html#basic-pseudo-random-number-generators-prngs) generators: [`rand::rngs`](https://docs.rs/rand/latest/rand/rngs/index.html), and more RNGs: [`rand_chacha`](https://docs.rs/rand_chacha), [`rand_xoshiro`](https://docs.rs/rand_xoshiro/), [`rand_pcg`](https://docs.rs/rand_pcg/), [rngs repo](https://github.com/rust-random/rngs/)
- [`rand::rng`](https://docs.rs/rand/latest/rand/fn.rng.html) is an asymptotically-fast, automatically-seeded and reasonably strong generator available on all `std` targets
- Direct support for seeding generators from the [`getrandom` crate](https://crates.io/crates/getrandom)

Supporting random value generation and random processes:
With broad support for random value generation and random processes:

- [`Standard`](https://docs.rs/rand/latest/rand/distributions/struct.Standard.html) random value generation
- Ranged [`Uniform`](https://docs.rs/rand/latest/rand/distributions/struct.Uniform.html) number generation for many types
- A flexible [`distributions`](https://docs.rs/rand/*/rand/distr/index.html) module
- Samplers for a large number of random number distributions via our own
- [`Standard`](https://docs.rs/rand/latest/rand/distributions/struct.Standard.html) random value sampling,
[`Uniform`](https://docs.rs/rand/latest/rand/distributions/struct.Uniform.html)-ranged value sampling
and [more](https://docs.rs/rand/latest/rand/distr/index.html)
- Samplers for a large number of non-uniform random number distributions via our own
[`rand_distr`](https://docs.rs/rand_distr) and via
the [`statrs`](https://docs.rs/statrs/0.13.0/statrs/)
- Random processes (mostly choose and shuffle) via [`rand::seq`](https://docs.rs/rand/latest/rand/seq/index.html) traits
Expand All @@ -42,6 +42,20 @@ It's also worth pointing out what Rand *is not*:
time of new distributions, commonly-used parameters, and parameters of the
current sampler.

Rand is not a cryptographic library.
While it is our aim that some sub-sets of the library
([`rand::rng()`](https://docs.rs/rand/latest/rand/fn.rng.html),
[`rand::rngs::StdRng`](https://docs.rs/rand/latest/rand/rngs/struct.StdRng.html))
are (when used correctly) unpredictable,
we cannot guarantee this. We keep copies of
[some outputs](https://docs.rs/rand_core/latest/rand_core/block/struct.BlockRng.html)
in memory longer than necessary and do not
[`zeroize`](https://crates.io/crates/zeroize) used buffers and generators.
We do not automatically reseed on fork (see
[`ThreadRng`](https://docs.rs/rand/latest/rand/rngs/struct.ThreadRng.html)).
Rand cannot provide any guarantees of security.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can recommend using getrandom directly if you need guarantees? Most crypto applications don't need a userspace CSPRNG, and I think this is what crypto libraries like ring do.



Documentation:

- [The Rust Rand Book](https://rust-random.github.io/book)
Expand Down
8 changes: 4 additions & 4 deletions rand_core/src/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@
use crate::{TryCryptoRng, TryRngCore};
use getrandom::getrandom;

/// A random number generator that retrieves randomness from the
/// operating system.
/// An interface over the operating-system's random data source
///
/// This is a zero-sized struct. It can be freely constructed with `OsRng`.
/// This is a zero-sized struct. It can be freely constructed with just `OsRng`.
///
/// The implementation is provided by the [getrandom] crate. Refer to
/// [getrandom] documentation for details.
Expand All @@ -32,7 +31,8 @@ use getrandom::getrandom;
///
/// After the first successful call, it is highly unlikely that failures or
/// significant delays will occur (although performance should be expected to
/// be much slower than a user-space PRNG).
/// be much slower than a user-space
/// [PRNG](https://rust-random.github.io/book/guide-gen.html#pseudo-random-number-generators)).
///
/// # Usage example
/// ```
Expand Down
49 changes: 33 additions & 16 deletions src/rngs/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,36 @@ const THREAD_RNG_RESEED_THRESHOLD: u64 = 1024 * 64;
/// A reference to the thread-local generator
///
/// This type is a reference to a lazily-initialized thread-local generator.
/// An instance can be obtained via [`rand::rng()`][crate::rng())] or via
/// `ThreadRng::default()`.
/// An instance can be obtained via [`rand::rng()`][crate::rng()] or via
/// [`ThreadRng::default()`].
/// The handle cannot be passed between threads (is not `Send` or `Sync`).
///
/// `ThreadRng` uses the same CSPRNG as [`StdRng`], ChaCha12. As with
/// [`StdRng`], the algorithm may be changed, subject to reasonable expectations
/// of security and performance.
/// # Security
///
/// `ThreadRng` is automatically seeded from [`OsRng`] with periodic reseeding
/// (every 64 kiB — see [`ReseedingRng`] documentation for details).
/// Security must be considered relative to a threat model and validation
/// requirements. The Rand project can provide no guarantee of fitness for
/// purpose. The design criteria for `ThreadRng` are as follows:
///
/// - Automatic seeding via [`OsRng`] and periodically thereafter (see
/// ([`ReseedingRng`] documentation). Limitation: there is no automatic
/// reseeding on process fork (see [below](#fork)).
/// - A rigorusly analyzed, unpredictable (cryptographic) pseudo-random generator
/// (see [the book on security](https://rust-random.github.io/book/guide-rngs.html#security)).
/// The currently selected algorithm is ChaCha (12-rounds).
/// See also [`StdRng`] documentation.
/// - Not to leak internal state through [`Debug`] or serialization
/// implementations.
/// - No further protections exist to in-memory state. In particular, the
/// implementation is not required to zero memory on exit (of the process or

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious.. is that because it's onerous to implement or causes a performance hit or something else?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zeroize? It's just not been done (so far). It has been implemented by the chacha20 crate, so we gain this feature when we switch (with a little adjustment to ThreadRng).

/// thread). (This may change in the future.)
/// - Be fast enough for general-purpose usage. Note in particular that
/// `ThreadRng` is designed to be a "fast, reasonably secure generator"
/// (where "reasonably secure" implies the above criteria).
///
/// We leave it to the user to determine whether this generator meets their
/// security requirements. For an alternative, see [`OsRng`].
///
/// # Fork
///
/// `ThreadRng` is not automatically reseeded on fork. It is recommended to
/// explicitly call [`ThreadRng::reseed`] immediately after a fork, for example:
Expand All @@ -68,13 +88,6 @@ const THREAD_RNG_RESEED_THRESHOLD: u64 = 1024 * 64;
/// from an interrupt (e.g. a fork handler) unless it can be guaranteed that no
/// other method on the same `ThreadRng` is currently executing.
///
/// Security must be considered relative to a threat model and validation
/// requirements. `ThreadRng` attempts to meet basic security considerations
/// for producing unpredictable random numbers: use a CSPRNG, use a
/// recommended platform-specific seed ([`OsRng`]), and avoid
/// leaking internal secrets e.g. via [`Debug`] implementation or serialization.
/// Memory is not zeroized on drop.
///
/// [`ReseedingRng`]: crate::rngs::ReseedingRng
/// [`StdRng`]: crate::rngs::StdRng
#[derive(Clone)]
Expand Down Expand Up @@ -115,9 +128,9 @@ thread_local!(
}
);

/// Access a local, pre-initialized generator
/// Access a fast, pre-initialized generator
///
/// This is a reasonably fast unpredictable thread-local instance of [`ThreadRng`].
/// This is a handle to the local [`ThreadRng`].
///
/// See also [`crate::rngs`] for alternatives.
///
Expand All @@ -139,6 +152,10 @@ thread_local!(
/// println!("A simulated die roll: {}", rng.random_range(1..=6));
/// # }
/// ```
///
/// # Security
///
/// Refer to [`ThreadRng#Security`].
pub fn rng() -> ThreadRng {
let rng = THREAD_RNG_KEY.with(|t| t.clone());
ThreadRng { rng }
Expand Down