|
| 1 | +//! Random value generation. |
| 2 | +//! |
| 3 | +//! The [`Random`] trait allows generating a random value for a type using a |
| 4 | +//! given [`RandomSource`]. |
| 5 | +
|
| 6 | +#[unstable(feature = "random", issue = "none")] |
| 7 | +pub use core::random::*; |
| 8 | + |
| 9 | +use crate::sys::random as sys; |
| 10 | + |
| 11 | +/// The default random source. |
| 12 | +/// |
| 13 | +/// This asks the system for the best random data it can provide, meaning the |
| 14 | +/// resulting bytes *should* be usable for cryptographic purposes. Check your |
| 15 | +/// platform's documentation for the specific guarantees it provides. The high |
| 16 | +/// quality of randomness provided by this source means it is quite slow. If |
| 17 | +/// you need a larger quantity of random numbers, consider using another random |
| 18 | +/// number generator (potentially seeded from this one). |
| 19 | +/// |
| 20 | +/// # Examples |
| 21 | +/// |
| 22 | +/// Generating a [version 4/variant 1 UUID] represented as text: |
| 23 | +/// ``` |
| 24 | +/// #![feature(random)] |
| 25 | +/// |
| 26 | +/// use std::random::{DefaultRandomSource, Random}; |
| 27 | +/// |
| 28 | +/// let bits = u128::random(&mut DefaultRandomSource); |
| 29 | +/// let g1 = (bits >> 96) as u32; |
| 30 | +/// let g2 = (bits >> 80) as u16; |
| 31 | +/// let g3 = (0x4000 | (bits >> 64) & 0x0fff) as u16; |
| 32 | +/// let g4 = (0x8000 | (bits >> 48) & 0x3fff) as u16; |
| 33 | +/// let g5 = (bits & 0xffffffffffff) as u64; |
| 34 | +/// let uuid = format!("{g1:08x}-{g2:04x}-{g3:04x}-{g4:04x}-{g5:012x}"); |
| 35 | +/// println!("{uuid}"); |
| 36 | +/// ``` |
| 37 | +/// |
| 38 | +/// [version 4/variant 1 UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) |
| 39 | +/// |
| 40 | +/// # Underlying sources |
| 41 | +/// |
| 42 | +/// Platform | Source |
| 43 | +/// -----------------------|--------------------------------------------------------------- |
| 44 | +/// Linux | [`getrandom`] or [`/dev/urandom`] after polling `/dev/random` |
| 45 | +/// Windows | [`ProcessPrng`] |
| 46 | +/// macOS and other UNIXes | [`getentropy`] |
| 47 | +/// other Apple platforms | `CCRandomGenerateBytes` |
| 48 | +/// Fuchsia | [`cprng_draw`] |
| 49 | +/// Hermit | `read_entropy` |
| 50 | +/// Horizon | `getrandom` shim |
| 51 | +/// Hurd, L4Re, QNX | `/dev/urandom` |
| 52 | +/// NetBSD before 10.0 | [`kern.arandom`] |
| 53 | +/// Redox | `/scheme/rand` |
| 54 | +/// SGX | [`rdrand`] |
| 55 | +/// SOLID | `SOLID_RNG_SampleRandomBytes` |
| 56 | +/// TEEOS | `TEE_GenerateRandom` |
| 57 | +/// UEFI | [`EFI_RNG_PROTOCOL`] |
| 58 | +/// VxWorks | `randABytes` after waiting for `randSecure` to become ready |
| 59 | +/// WASI | `random_get` |
| 60 | +/// ZKVM | `sys_rand` |
| 61 | +/// |
| 62 | +/// **Disclaimer:** The sources used might change over time. |
| 63 | +/// |
| 64 | +/// [`getrandom`]: https://www.man7.org/linux/man-pages/man2/getrandom.2.html |
| 65 | +/// [`/dev/urandom`]: https://www.man7.org/linux/man-pages/man4/random.4.html |
| 66 | +/// [`ProcessPrng`]: https://learn.microsoft.com/en-us/windows/win32/seccng/processprng |
| 67 | +/// [`getentropy`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getentropy.html |
| 68 | +/// [`cprng_draw`]: https://fuchsia.dev/reference/syscalls/cprng_draw |
| 69 | +/// [`kern.arandom`]: https://man.netbsd.org/rnd.4 |
| 70 | +/// [`rdrand`]: https://en.wikipedia.org/wiki/RDRAND |
| 71 | +/// [`EFI_RNG_PROTOCOL`]: https://uefi.org/specs/UEFI/2.10/37_Secure_Technologies.html#random-number-generator-protocol |
| 72 | +#[derive(Default, Debug, Clone, Copy)] |
| 73 | +#[unstable(feature = "random", issue = "none")] |
| 74 | +pub struct DefaultRandomSource; |
| 75 | + |
| 76 | +#[unstable(feature = "random", issue = "none")] |
| 77 | +impl RandomSource for DefaultRandomSource { |
| 78 | + fn fill_bytes(&mut self, bytes: &mut [u8]) { |
| 79 | + sys::fill_bytes(bytes, false) |
| 80 | + } |
| 81 | +} |
| 82 | + |
| 83 | +/// A best-effort random source used for creating hash-map seeds. |
| 84 | +#[unstable(feature = "random", issue = "none")] |
| 85 | +pub(crate) struct BestEffortRandomSource; |
| 86 | + |
| 87 | +impl RandomSource for BestEffortRandomSource { |
| 88 | + fn fill_bytes(&mut self, bytes: &mut [u8]) { |
| 89 | + sys::fill_bytes(bytes, true) |
| 90 | + } |
| 91 | +} |
0 commit comments