std: implement the random feature · qinheping/verify-rust-std@a095a76 (original) (raw)

``

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 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. If you need a large quantity of random numbers and security is not a

`

``

19

`+

/// concern, consider using an alternative random number generator (potentially

`

``

20

`+

/// 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]

``

``

28

`` +

/// macOS and other UNIXes | [getentropy]

``

``

29

`` +

/// other Apple platforms | CCRandomGenerateBytes

``

``

30

`` +

/// ESP-IDF | [esp_fill_random]

``

``

31

`` +

/// Fuchsia | [cprng_draw]

``

``

32

`` +

/// Hermit | read_entropy

``

``

33

`` +

/// Horizon | getrandom shim

``

``

34

`` +

/// Hurd, L4Re, QNX | /dev/urandom

``

``

35

`` +

/// NetBSD before 10.0 | [kern.arandom]

``

``

36

`` +

/// Redox | /scheme/rand

``

``

37

`` +

/// SGX | [rdrand]

``

``

38

`` +

/// SOLID | SOLID_RNG_SampleRandomBytes

``

``

39

`` +

/// TEEOS | TEE_GenerateRandom

``

``

40

`` +

/// UEFI | [EFI_RNG_PROTOCOL]

``

``

41

`` +

/// VxWorks | randABytes after waiting for randSecure to become ready

``

``

42

`` +

/// WASI | random_get

``

``

43

`` +

/// ZKVM | sys_rand

``

``

44

`+

///

`

``

45

`+

/// Disclaimer: The sources used might change over time.

`

``

46

`+

///

`

``

47

`` +

/// [getrandom]: https://www.man7.org/linux/man-pages/man2/getrandom.2.html

``

``

48

`` +

/// [/dev/urandom]: https://www.man7.org/linux/man-pages/man4/random.4.html

``

``

49

`` +

/// [ProcessPrng]: https://learn.microsoft.com/en-us/windows/win32/seccng/processprng

``

``

50

`` +

/// [getentropy]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getentropy.html

``

``

51

`` +

/// [esp_fill_random]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html#_CPPv415esp_fill_randomPv6size_t

``

``

52

`` +

/// [cprng_draw]: https://fuchsia.dev/reference/syscalls/cprng_draw

``

``

53

`` +

/// [kern.arandom]: https://man.netbsd.org/rnd.4

``

``

54

`` +

/// [rdrand]: https://en.wikipedia.org/wiki/RDRAND

``

``

55

`` +

/// [EFI_RNG_PROTOCOL]: https://uefi.org/specs/UEFI/2.10/37_Secure_Technologies.html#random-number-generator-protocol

``

``

56

`+

#[derive(Default, Debug, Clone, Copy)]

`

``

57

`+

#[unstable(feature = "random", issue = "none")]

`

``

58

`+

pub struct DefaultRandomSource;

`

``

59

+

``

60

`+

#[unstable(feature = "random", issue = "none")]

`

``

61

`+

impl RandomSource for DefaultRandomSource {

`

``

62

`+

fn fill_bytes(&mut self, bytes: &mut [u8]) {

`

``

63

`+

sys::fill_bytes(bytes)

`

``

64

`+

}

`

``

65

`+

}

`

``

66

+

``

67

`+

/// Generates a random value with the default random source.

`

``

68

`+

///

`

``

69

`` +

/// This is a convenience function for T::random(&mut DefaultRandomSource) and

``

``

70

`` +

/// will sample according to the same distribution as the underlying [Random]

``

``

71

`+

/// trait implementation.

`

``

72

`+

///

`

``

73

`+

/// Warning: Be careful when manipulating random values! The

`

``

74

`` +

/// random method on integers samples them with a uniform

``

``

75

`` +

/// distribution, so a value of 1 is just as likely as [i32::MAX]. By using

``

``

76

`+

/// modulo operations, some of the resulting values can become more likely than

`

``

77

`+

/// others. Use audited crates when in doubt.

`

``

78

`+

///

`

``

79

`+

/// # Examples

`

``

80

`+

///

`

``

81

`+

/// Generating a [version 4/variant 1 UUID] represented as text:

`

``

82


/// ```

``

83

`+

/// #![feature(random)]

`

``

84

`+

///

`

``

85

`+

/// use std::random::random;

`

``

86

`+

///

`

``

87

`+

/// let bits = random::();

`

``

88

`+

/// let g1 = (bits >> 96) as u32;

`

``

89

`+

/// let g2 = (bits >> 80) as u16;

`

``

90

`+

/// let g3 = (0x4000 | (bits >> 64) & 0x0fff) as u16;

`

``

91

`+

/// let g4 = (0x8000 | (bits >> 48) & 0x3fff) as u16;

`

``

92

`+

/// let g5 = (bits & 0xffffffffffff) as u64;

`

``

93

`+

/// let uuid = format!("{g1:08x}-{g2:04x}-{g3:04x}-{g4:04x}-{g5:012x}");

`

``

94

`+

/// println!("{uuid}");

`

``

95


/// ```

``

96

`+

///

`

``

97

`+

/// [version 4/variant 1 UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)

`

``

98

`+

pub fn random<T: Random>() -> T {

`

``

99

`+

T::random(&mut DefaultRandomSource)

`

``

100

`+

}

`