Skip to content
Merged
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
16 changes: 8 additions & 8 deletions library/core/src/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,31 @@ use crate::ops::RangeFull;

/// A source of randomness.
#[unstable(feature = "random", issue = "130703")]
pub trait RandomSource {
pub trait Rng {
/// Fills `bytes` with random bytes.
///
/// Note that calling `fill_bytes` multiple times is not equivalent to calling `fill_bytes` once
/// with a larger buffer. A `RandomSource` is allowed to return different bytes for those two
/// cases. For instance, this allows a `RandomSource` to generate a word at a time and throw
/// part of it away if not needed.
/// with a larger buffer. An `Rng` is allowed to return different bytes for those two cases. For
/// instance, this allows an `Rng` to generate a word at a time and throw part of it away if not
/// needed.
fn fill_bytes(&mut self, bytes: &mut [u8]);
}

/// A trait representing a distribution of random values for a type.
#[unstable(feature = "random", issue = "130703")]
pub trait Distribution<T> {
/// Samples a random value from the distribution, using the specified random source.
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T;
fn sample(&self, source: &mut (impl Rng + ?Sized)) -> T;
}

impl<T, DT: Distribution<T>> Distribution<T> for &DT {
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T {
fn sample(&self, source: &mut (impl Rng + ?Sized)) -> T {
(*self).sample(source)
}
}

impl Distribution<bool> for RangeFull {
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> bool {
fn sample(&self, source: &mut (impl Rng + ?Sized)) -> bool {
let byte: u8 = RangeFull.sample(source);
byte & 1 == 1
}
Expand All @@ -37,7 +37,7 @@ impl Distribution<bool> for RangeFull {
macro_rules! impl_primitive {
($t:ty) => {
impl Distribution<$t> for RangeFull {
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> $t {
fn sample(&self, source: &mut (impl Rng + ?Sized)) -> $t {
let mut bytes = (0 as $t).to_ne_bytes();
source.fill_bytes(&mut bytes);
<$t>::from_ne_bytes(bytes)
Expand Down
16 changes: 8 additions & 8 deletions library/std/src/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub use core::random::*;

use crate::sys::random as sys;

/// The default random source.
/// The system random number generator.
///
/// This asks the system for random data suitable for cryptographic purposes
/// such as key generation. If security is a concern, consult the platform
Expand All @@ -16,7 +16,7 @@ use crate::sys::random as sys;
/// security is not a concern, consider using an alternative random number
/// generator (potentially seeded from this one).
///
/// If you need to fill a buffer with random bytes, use `DefaultRandomSource.fill_bytes(&mut buf)`.
/// If you need to fill a buffer with random bytes, use `SystemRng.fill_bytes(&mut buf)`.
///
/// # Underlying sources
///
Expand Down Expand Up @@ -59,20 +59,20 @@ use crate::sys::random as sys;
#[doc(alias = "getrandom", alias = "getentropy", alias = "arc4random")]
#[derive(Default, Debug, Clone, Copy)]
#[unstable(feature = "random", issue = "130703")]
pub struct DefaultRandomSource;
pub struct SystemRng;

#[unstable(feature = "random", issue = "130703")]
impl RandomSource for DefaultRandomSource {
impl Rng for SystemRng {
fn fill_bytes(&mut self, bytes: &mut [u8]) {
sys::fill_bytes(bytes)
}
}

/// Generates a random value from a distribution, using the default random source.
///
/// This is a convenience function for `dist.sample(&mut DefaultRandomSource)` and will sample
/// according to the same distribution as the underlying [`Distribution`] trait implementation. See
/// [`DefaultRandomSource`] for more information about how randomness is sourced.
/// This is a convenience function for `dist.sample(&mut SystemRng)` and will sample according to
/// the same distribution as the underlying [`Distribution`] trait implementation. See [`SystemRng`]
/// for more information about how randomness is sourced.
///
/// # Examples
///
Expand All @@ -95,5 +95,5 @@ impl RandomSource for DefaultRandomSource {
/// [version 4/variant 1 UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
#[unstable(feature = "random", issue = "130703")]
pub fn random<T>(dist: impl Distribution<T>) -> T {
dist.sample(&mut DefaultRandomSource)
dist.sample(&mut SystemRng)
}
10 changes: 5 additions & 5 deletions library/std/src/sys/random/arc4random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
//! Contrary to its name, `arc4random` doesn't actually use the horribly-broken
//! RC4 cypher anymore, at least not on modern systems, but rather something
//! like ChaCha20 with continual reseeding from the OS. That makes it an ideal
//! source of large quantities of cryptographically secure data, which is exactly
//! what we need for `DefaultRandomSource`. Unfortunately, it's not available
//! on all UNIX systems, most notably Linux (until recently, but it's just a
//! wrapper for `getrandom`. Since we need to hook into `getrandom` directly
//! for `HashMap` keys anyway, we just keep our version).
//! source of large quantities of cryptographically secure data, which is
//! exactly what we need for `SystemRng`. Unfortunately, it's not available on
//! all UNIX systems, most notably Linux (until recently, but it's just a
//! wrapper for `getrandom`. Since we need to hook into `getrandom` directly for
//! `HashMap` keys anyway, we just keep our version).

#[cfg(not(any(
target_os = "haiku",
Expand Down
10 changes: 5 additions & 5 deletions library/std/src/sys/random/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
//!
//! One additional consideration to make is that the non-blocking pool is not
//! always initialized during early boot. We want the best quality of randomness
//! for the output of `DefaultRandomSource` so we simply wait until it is
//! initialized. When `HashMap` keys however, this represents a potential source
//! of deadlocks, as the additional entropy may only be generated once the
//! program makes forward progress. In that case, we just use the best random
//! data the system has available at the time.
//! for the output of `SystemRng` so we simply wait until it is initialized.
//! When `HashMap` keys however, this represents a potential source of
//! deadlocks, as the additional entropy may only be generated once the program
//! makes forward progress. In that case, we just use the best random data the
//! system has available at the time.
//!
//! So in conclusion, we always want the output of the non-blocking pool, but
//! may need to wait until it is initialized. The default behavior of `getrandom`
Expand Down
Loading