|
13 | 13 | #include <stdint.h>
|
14 | 14 | #include <limits>
|
15 | 15 |
|
| 16 | +/** |
| 17 | + * Overall design of the RNG and entropy sources. |
| 18 | + * |
| 19 | + * We maintain a single global 256-bit RNG state for all high-quality randomness. |
| 20 | + * The following (classes of) functions interact with that state by mixing in new |
| 21 | + * entropy, and optionally extracting random output from it: |
| 22 | + * |
| 23 | + * - The GetRand*() class of functions, as well as construction of FastRandomContext objects, |
| 24 | + * perform 'fast' seeding, consisting of mixing in: |
| 25 | + * - A stack pointer (indirectly committing to calling thread and call stack) |
| 26 | + * - A high-precision timestamp (rdtsc when available, c++ high_resolution_clock otherwise) |
| 27 | + * - Hardware RNG (rdrand) when available. |
| 28 | + * These entropy sources are very fast, and only designed to protect against situations |
| 29 | + * where a VM state restore/copy results in multiple systems with the same randomness. |
| 30 | + * FastRandomContext on the other hand does not protect against this once created, but |
| 31 | + * is even faster (and acceptable to use inside tight loops). |
| 32 | + * |
| 33 | + * - The GetStrongRand*() class of function perform 'slow' seeding, including everything |
| 34 | + * that fast seeding includes, but additionally: |
| 35 | + * - OS entropy (/dev/urandom, getrandom(), ...). The application will terminate if |
| 36 | + * this entropy source fails. |
| 37 | + * - Bytes from OpenSSL's RNG (which itself may be seeded from various sources) |
| 38 | + * - Another high-precision timestamp (indirectly committing to a benchmark of all the |
| 39 | + * previous sources). |
| 40 | + * These entropy sources are slower, but designed to make sure the RNG state contains |
| 41 | + * fresh data that is unpredictable to attackers. |
| 42 | + * |
| 43 | + * - RandAddSeedSleep() seeds everything that fast seeding includes, but additionally: |
| 44 | + * - A high-precision timestamp before and after sleeping 1ms. |
| 45 | + * - (On Windows) Once every 10 minutes, performance monitoring data from the OS. |
| 46 | + * These just exploit the fact the system is idle to improve the quality of the RNG |
| 47 | + * slightly. |
| 48 | + * |
| 49 | + * On first use of the RNG (regardless of what function is called first), all entropy |
| 50 | + * sources used in the 'slow' seeder are included, but also: |
| 51 | + * - (On Windows) Performance monitoring data from the OS. |
| 52 | + * - (On Windows) Through OpenSSL, the screen contents. |
| 53 | + * |
| 54 | + * When mixing in new entropy, H = SHA512(entropy || old_rng_state) is computed, and |
| 55 | + * (up to) the first 32 bytes of H are produced as output, while the last 32 bytes |
| 56 | + * become the new RNG state. |
| 57 | +*/ |
| 58 | + |
16 | 59 | /**
|
17 | 60 | * Generate random data via the internal PRNG.
|
18 | 61 | *
|
|
0 commit comments