mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 18:49:30 +01:00
Document RNG design in random.h
This commit is contained in:
parent
f2e60ca985
commit
223de8d94d
@ -282,6 +282,14 @@ namespace {
|
||||
|
||||
class RNGState {
|
||||
Mutex m_mutex;
|
||||
/* The RNG state consists of 256 bits of entropy, taken from the output of
|
||||
* one operation's SHA512 output, and fed as input to the next one.
|
||||
* Carrying 256 bits of entropy should be sufficient to guarantee
|
||||
* unpredictability as long as any entropy source was ever unpredictable
|
||||
* to an attacker. To protect against situations where an attacker might
|
||||
* observe the RNG's state, fresh entropy is always mixed when
|
||||
* GetStrongRandBytes is called.
|
||||
*/
|
||||
unsigned char m_state[32] GUARDED_BY(m_mutex) = {0};
|
||||
uint64_t m_counter GUARDED_BY(m_mutex) = 0;
|
||||
bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
|
||||
|
43
src/random.h
43
src/random.h
@ -13,6 +13,49 @@
|
||||
#include <stdint.h>
|
||||
#include <limits>
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* - 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.
|
||||
* - Bytes from OpenSSL's RNG (which itself may be seeded from various sources)
|
||||
* - 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.
|
||||
*
|
||||
* - RandAddSeedSleep() seeds everything that fast seeding includes, but additionally:
|
||||
* - A high-precision timestamp before and after sleeping 1ms.
|
||||
* - (On Windows) Once every 10 minutes, performance monitoring data from the OS.
|
||||
* These just exploit the fact the system is idle to improve the quality of the RNG
|
||||
* slightly.
|
||||
*
|
||||
* 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:
|
||||
* - (On Windows) Performance monitoring data from the OS.
|
||||
* - (On Windows) Through OpenSSL, the screen contents.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generate random data via the internal PRNG.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user