| 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 = "130703" )] |
| 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 random data suitable for cryptographic purposes |
| 14 | /// such as key generation. If security is a concern, consult the platform |
| 15 | /// documentation below for the specific guarantees your target provides. |
| 16 | /// |
| 17 | /// The high quality of randomness provided by this source means it can be quite |
| 18 | /// slow on some targets. If you need a large quantity of random numbers and |
| 19 | /// security is not a concern, consider using an alternative random number |
| 20 | /// generator (potentially seeded from this one). |
| 21 | /// |
| 22 | /// # Underlying sources |
| 23 | /// |
| 24 | /// Platform | Source |
| 25 | /// -----------------------|--------------------------------------------------------------- |
| 26 | /// Linux | [`getrandom`] or [`/dev/urandom`] after polling `/dev/random` |
| 27 | /// Windows | [`ProcessPrng`](https://learn.microsoft.com/en-us/windows/win32/seccng/processprng) |
| 28 | /// Apple | `CCRandomGenerateBytes` |
| 29 | /// DragonFly | [`arc4random_buf`](https://man.dragonflybsd.org/?command=arc4random) |
| 30 | /// ESP-IDF | [`esp_fill_random`](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html#_CPPv415esp_fill_randomPv6size_t) |
| 31 | /// FreeBSD | [`arc4random_buf`](https://man.freebsd.org/cgi/man.cgi?query=arc4random) |
| 32 | /// Fuchsia | [`cprng_draw`](https://fuchsia.dev/reference/syscalls/cprng_draw) |
| 33 | /// Haiku | `arc4random_buf` |
| 34 | /// Illumos | [`arc4random_buf`](https://www.illumos.org/man/3C/arc4random) |
| 35 | /// NetBSD | [`arc4random_buf`](https://man.netbsd.org/arc4random.3) |
| 36 | /// OpenBSD | [`arc4random_buf`](https://man.openbsd.org/arc4random.3) |
| 37 | /// Solaris | [`arc4random_buf`](https://docs.oracle.com/cd/E88353_01/html/E37843/arc4random-3c.html) |
| 38 | /// Vita | `arc4random_buf` |
| 39 | /// Hermit | `read_entropy` |
| 40 | /// Horizon, Cygwin | `getrandom` |
| 41 | /// AIX, Hurd, L4Re, QNX | `/dev/urandom` |
| 42 | /// Redox | `/scheme/rand` |
| 43 | /// RTEMS | [`arc4random_buf`](https://docs.rtems.org/branches/master/bsp-howto/getentropy.html) |
| 44 | /// SGX | [`rdrand`](https://en.wikipedia.org/wiki/RDRAND) |
| 45 | /// SOLID | `SOLID_RNG_SampleRandomBytes` |
| 46 | /// TEEOS | `TEE_GenerateRandom` |
| 47 | /// UEFI | [`EFI_RNG_PROTOCOL`](https://uefi.org/specs/UEFI/2.10/37_Secure_Technologies.html#random-number-generator-protocol) |
| 48 | /// VxWorks | `randABytes` after waiting for `randSecure` to become ready |
| 49 | /// WASI | [`random_get`](https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#-random_getbuf-pointeru8-buf_len-size---result-errno) |
| 50 | /// ZKVM | `sys_rand` |
| 51 | /// |
| 52 | /// Note that the sources used might change over time. |
| 53 | /// |
| 54 | /// Consult the documentation for the underlying operations on your supported |
| 55 | /// targets to determine whether they provide any particular desired properties, |
| 56 | /// such as support for reseeding on VM fork operations. |
| 57 | /// |
| 58 | /// [`getrandom`]: https://www.man7.org/linux/man-pages/man2/getrandom.2.html |
| 59 | /// [`/dev/urandom`]: https://www.man7.org/linux/man-pages/man4/random.4.html |
| 60 | #[derive (Default, Debug, Clone, Copy)] |
| 61 | #[unstable (feature = "random" , issue = "130703" )] |
| 62 | pub struct DefaultRandomSource; |
| 63 | |
| 64 | #[unstable (feature = "random" , issue = "130703" )] |
| 65 | impl RandomSource for DefaultRandomSource { |
| 66 | fn fill_bytes(&mut self, bytes: &mut [u8]) { |
| 67 | sys::fill_bytes(bytes) |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | /// Generates a random value with the default random source. |
| 72 | /// |
| 73 | /// This is a convenience function for `T::random(&mut DefaultRandomSource)` and |
| 74 | /// will sample according to the same distribution as the underlying [`Random`] |
| 75 | /// trait implementation. See [`DefaultRandomSource`] for more information about |
| 76 | /// how randomness is sourced. |
| 77 | /// |
| 78 | /// **Warning:** Be careful when manipulating random values! The |
| 79 | /// [`random`](Random::random) method on integers samples them with a uniform |
| 80 | /// distribution, so a value of 1 is just as likely as [`i32::MAX`]. By using |
| 81 | /// modulo operations, some of the resulting values can become more likely than |
| 82 | /// others. Use audited crates when in doubt. |
| 83 | /// |
| 84 | /// # Examples |
| 85 | /// |
| 86 | /// Generating a [version 4/variant 1 UUID] represented as text: |
| 87 | /// ``` |
| 88 | /// #![feature(random)] |
| 89 | /// |
| 90 | /// use std::random::random; |
| 91 | /// |
| 92 | /// let bits: u128 = random(); |
| 93 | /// let g1 = (bits >> 96) as u32; |
| 94 | /// let g2 = (bits >> 80) as u16; |
| 95 | /// let g3 = (0x4000 | (bits >> 64) & 0x0fff) as u16; |
| 96 | /// let g4 = (0x8000 | (bits >> 48) & 0x3fff) as u16; |
| 97 | /// let g5 = (bits & 0xffffffffffff) as u64; |
| 98 | /// let uuid = format!("{g1:08x}-{g2:04x}-{g3:04x}-{g4:04x}-{g5:012x}" ); |
| 99 | /// println!("{uuid}" ); |
| 100 | /// ``` |
| 101 | /// |
| 102 | /// [version 4/variant 1 UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) |
| 103 | #[unstable (feature = "random" , issue = "130703" )] |
| 104 | pub fn random<T: Random>() -> T { |
| 105 | T::random(&mut DefaultRandomSource) |
| 106 | } |
| 107 | |