1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// ---------------- [ File: bitcoin-random/src/lib.rs ]
/*!
| Overall design of the RNG and entropy sources.
|
| We maintain a single global 256-bit RNG state
| for all high-quality randomness.
|
| The following (classes of) functions interact
| with that state by mixing in new entropy, and
| optionally extracting random output from it:
|
| - The GetRand*() class of functions, as well as
| construction of FastRandomContext objects,
| perform 'fast' seeding, consisting of mixing
| in:
|
| - A stack pointer (indirectly committing to
| calling thread and call stack)
|
| - A high-precision timestamp (rdtsc when
| available, c++ high_resolution_clock
| otherwise)
|
| - 64 bits from the hardware RNG (rdrand) when
| available.
|
| These entropy sources are very fast, and only
| designed to protect against situations where
| a VM state restore/copy results in multiple
| systems with the same randomness.
|
| FastRandomContext on the other hand does not
| protect against this once created, but is
| even faster (and acceptable to use inside
| tight loops).
|
| - The GetStrongRand*() class of function
| perform 'slow' seeding, including everything
| that fast seeding includes, but additionally:
|
| - OS entropy (/dev/urandom, getrandom(),
| ...). The application will terminate if
| this entropy source fails.
|
| - Another high-precision timestamp
| (indirectly committing to a benchmark of
| all the previous sources).
|
| These entropy sources are slower, but
| designed to make sure the RNG state contains
| fresh data that is unpredictable to
| attackers.
|
| - RandAddPeriodic() seeds everything that fast
| seeding includes, but additionally:
|
| - A high-precision timestamp
|
| - Dynamic environment data (performance
| monitoring, ...)
|
| - Strengthen the entropy for 10 ms using
| repeated SHA512.
|
| This is run once every minute.
|
| On first use of the RNG (regardless of what
| function is called first), all entropy sources
| used in the 'slow' seeder are included, but
| also:
|
| - 256 bits from the hardware RNG
| (rdseed or rdrand) when available.
|
| - Dynamic environment data (performance
| monitoring, ...)
|
| - Static environment data
|
| - Strengthen the entropy for 100 ms using
| repeated SHA512.
|
| When mixing in new entropy, H = SHA512(entropy
| || old_rng_state) is computed, and (up to)
| the first 32 bytes of H are produced as output,
| while the last 32 bytes become the new RNG
| state.
*/
use *;
x!
x!
x!
x!
x!
x!
x!
x!
x!
x!
x!
x!
x!
x!
x!
x!
x!
x!
x!
x!