diff options
author | Pieter Wuille <pieter@wuille.net> | 2024-03-11 14:10:44 -0400 |
---|---|---|
committer | Pieter Wuille <pieter@wuille.net> | 2024-07-01 12:39:57 -0400 |
commit | 2c91330dd68064e402e8eceea3df9474bb7afd48 (patch) | |
tree | 7823d0ce6235b49452ddb4764a250d87c6242891 /src/random.h | |
parent | 8e31cf9c9b5e9fdd01e8b220c08a3ccde5cf584c (diff) |
random: cleanup order, comments, static
Diffstat (limited to 'src/random.h')
-rw-r--r-- | src/random.h | 105 |
1 files changed, 64 insertions, 41 deletions
diff --git a/src/random.h b/src/random.h index 821c84fce3..ea517d2d2e 100644 --- a/src/random.h +++ b/src/random.h @@ -28,8 +28,8 @@ * 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: + * - GetRandBytes, GetRandHash, GetRandDur, 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. @@ -38,7 +38,7 @@ * 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 + * - The GetStrongRandBytes() function performs 'slow' seeding, including everything * that fast seeding includes, but additionally: * - OS entropy (/dev/urandom, getrandom(), ...). The application will terminate if * this entropy source fails. @@ -53,12 +53,12 @@ * - 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. + * - 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 @@ -71,42 +71,72 @@ * only depends on the seed it was initialized with, possibly until it is reinitialized. */ + +/* ============================= INITIALIZATION AND ADDING ENTROPY ============================= */ + +/** + * Initialize global RNG state and log any CPU features that are used. + * + * Calling this function is optional. RNG state will be initialized when first + * needed if it is not called. + */ +void RandomInit(); + +/** + * Gather entropy from various expensive sources, and feed them to the PRNG state. + * + * Thread-safe. + */ +void RandAddPeriodic() noexcept; + +/** + * Gathers entropy from the low bits of the time at which events occur. Should + * be called with a uint32_t describing the event at the time an event occurs. + * + * Thread-safe. + */ +void RandAddEvent(const uint32_t event_info) noexcept; + + +/* =========================== BASE RANDOMNESS GENERATION FUNCTIONS =========================== + * + * All produced randomness is eventually generated by one of these functions. + */ + /** * Generate random data via the internal PRNG. * * These functions are designed to be fast (sub microsecond), but do not necessarily * meaningfully add entropy to the PRNG state. * + * In test mode (see SeedRandomForTest in src/test/util/random.h), the normal PRNG state is + * bypassed, and a deterministic, seeded, PRNG is used instead. + * * Thread-safe. */ void GetRandBytes(Span<unsigned char> bytes) noexcept; -uint256 GetRandHash() noexcept; - /** * Gather entropy from various sources, feed it into the internal PRNG, and * generate random data using it. * * This function will cause failure whenever the OS RNG fails. * + * The normal PRNG is never bypassed here, even in test mode. + * * Thread-safe. */ void GetStrongRandBytes(Span<unsigned char> bytes) noexcept; -/** - * Gather entropy from various expensive sources, and feed them to the PRNG state. - * - * Thread-safe. - */ -void RandAddPeriodic() noexcept; -/** - * Gathers entropy from the low bits of the time at which events occur. Should - * be called with a uint32_t describing the event at the time an event occurs. +/* ============================= RANDOM NUMBER GENERATION CLASSES ============================= * - * Thread-safe. + * In this section, 3 classes are defined: + * - RandomMixin: a base class that adds functionality to all RNG classes. + * - FastRandomContext: a cryptographic RNG (seeded through GetRandBytes in its default + * constructor). + * - InsecureRandomContext: a non-cryptographic, very fast, RNG. */ -void RandAddEvent(const uint32_t event_info) noexcept; // Forward declaration of RandomMixin, used in RandomNumberGenerator concept. template<typename T> @@ -430,6 +460,17 @@ public: } }; + +/* ==================== CONVENIENCE FUNCTIONS FOR COMMONLY USED RANDOMNESS ==================== */ + +/** Generate a random uint256. */ +inline uint256 GetRandHash() noexcept +{ + uint256 hash; + GetRandBytes(hash); + return hash; +} + /** More efficient than using std::shuffle on a FastRandomContext. * * This is more efficient as std::shuffle will consume entropy in groups of @@ -453,29 +494,11 @@ void Shuffle(I first, I last, R&& rng) } } -/* Number of random bytes returned by GetOSRand. - * When changing this constant make sure to change all call sites, and make - * sure that the underlying OS APIs for all platforms support the number. - * (many cap out at 256 bytes). - */ -static const int NUM_OS_RANDOM_BYTES = 32; - -/** Get 32 bytes of system entropy. Do not use this in application code: use - * GetStrongRandBytes instead. - */ -void GetOSRand(unsigned char* ent32); +/* ============================= MISCELLANEOUS TEST-ONLY FUNCTIONS ============================= */ /** Check that OS randomness is available and returning the requested number * of bytes. */ bool Random_SanityCheck(); -/** - * Initialize global RNG state and log any CPU features that are used. - * - * Calling this function is optional. RNG state will be initialized when first - * needed if it is not called. - */ -void RandomInit(); - #endif // BITCOIN_RANDOM_H |