mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-08-04 14:04:49 +02:00
random: cleanup order, comments, static
This commit is contained in:
parent
8e31cf9c9b
commit
2c91330dd6
@ -45,13 +45,23 @@
|
|||||||
#include <sys/auxv.h>
|
#include <sys/auxv.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[[noreturn]] static void RandFailure()
|
namespace {
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
|
||||||
|
[[noreturn]] void RandFailure()
|
||||||
{
|
{
|
||||||
LogPrintf("Failed to read randomness, aborting\n");
|
LogPrintf("Failed to read randomness, aborting\n");
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int64_t GetPerformanceCounter() noexcept
|
inline int64_t GetPerformanceCounter() noexcept
|
||||||
{
|
{
|
||||||
// Read the hardware time stamp counter when available.
|
// Read the hardware time stamp counter when available.
|
||||||
// See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
|
// See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
|
||||||
@ -72,10 +82,10 @@ static inline int64_t GetPerformanceCounter() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_GETCPUID
|
#ifdef HAVE_GETCPUID
|
||||||
static bool g_rdrand_supported = false;
|
bool g_rdrand_supported = false;
|
||||||
static bool g_rdseed_supported = false;
|
bool g_rdseed_supported = false;
|
||||||
static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
|
constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
|
||||||
static constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
|
constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
|
||||||
#ifdef bit_RDRND
|
#ifdef bit_RDRND
|
||||||
static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND, "Unexpected value for bit_RDRND");
|
static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND, "Unexpected value for bit_RDRND");
|
||||||
#endif
|
#endif
|
||||||
@ -83,7 +93,7 @@ static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND, "Unexpected value for bit_RDRND"
|
|||||||
static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED, "Unexpected value for bit_RDSEED");
|
static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED, "Unexpected value for bit_RDSEED");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void InitHardwareRand()
|
void InitHardwareRand()
|
||||||
{
|
{
|
||||||
uint32_t eax, ebx, ecx, edx;
|
uint32_t eax, ebx, ecx, edx;
|
||||||
GetCPUID(1, 0, eax, ebx, ecx, edx);
|
GetCPUID(1, 0, eax, ebx, ecx, edx);
|
||||||
@ -96,7 +106,7 @@ static void InitHardwareRand()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReportHardwareRand()
|
void ReportHardwareRand()
|
||||||
{
|
{
|
||||||
// This must be done in a separate function, as InitHardwareRand() may be indirectly called
|
// This must be done in a separate function, as InitHardwareRand() may be indirectly called
|
||||||
// from global constructors, before logging is initialized.
|
// from global constructors, before logging is initialized.
|
||||||
@ -112,7 +122,7 @@ static void ReportHardwareRand()
|
|||||||
*
|
*
|
||||||
* Must only be called when RdRand is supported.
|
* Must only be called when RdRand is supported.
|
||||||
*/
|
*/
|
||||||
static uint64_t GetRdRand() noexcept
|
uint64_t GetRdRand() noexcept
|
||||||
{
|
{
|
||||||
// RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce this risk.
|
// RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce this risk.
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
@ -147,7 +157,7 @@ static uint64_t GetRdRand() noexcept
|
|||||||
*
|
*
|
||||||
* Must only be called when RdSeed is supported.
|
* Must only be called when RdSeed is supported.
|
||||||
*/
|
*/
|
||||||
static uint64_t GetRdSeed() noexcept
|
uint64_t GetRdSeed() noexcept
|
||||||
{
|
{
|
||||||
// RdSeed may fail when the HW RNG is overloaded. Loop indefinitely until enough entropy is gathered,
|
// RdSeed may fail when the HW RNG is overloaded. Loop indefinitely until enough entropy is gathered,
|
||||||
// but pause after every failure.
|
// but pause after every failure.
|
||||||
@ -181,16 +191,16 @@ static uint64_t GetRdSeed() noexcept
|
|||||||
|
|
||||||
#elif defined(__aarch64__) && defined(HWCAP2_RNG)
|
#elif defined(__aarch64__) && defined(HWCAP2_RNG)
|
||||||
|
|
||||||
static bool g_rndr_supported = false;
|
bool g_rndr_supported = false;
|
||||||
|
|
||||||
static void InitHardwareRand()
|
void InitHardwareRand()
|
||||||
{
|
{
|
||||||
if (getauxval(AT_HWCAP2) & HWCAP2_RNG) {
|
if (getauxval(AT_HWCAP2) & HWCAP2_RNG) {
|
||||||
g_rndr_supported = true;
|
g_rndr_supported = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReportHardwareRand()
|
void ReportHardwareRand()
|
||||||
{
|
{
|
||||||
// This must be done in a separate function, as InitHardwareRand() may be indirectly called
|
// This must be done in a separate function, as InitHardwareRand() may be indirectly called
|
||||||
// from global constructors, before logging is initialized.
|
// from global constructors, before logging is initialized.
|
||||||
@ -203,7 +213,7 @@ static void ReportHardwareRand()
|
|||||||
*
|
*
|
||||||
* Must only be called when RNDR is supported.
|
* Must only be called when RNDR is supported.
|
||||||
*/
|
*/
|
||||||
static uint64_t GetRNDR() noexcept
|
uint64_t GetRNDR() noexcept
|
||||||
{
|
{
|
||||||
uint8_t ok;
|
uint8_t ok;
|
||||||
uint64_t r1;
|
uint64_t r1;
|
||||||
@ -221,7 +231,7 @@ static uint64_t GetRNDR() noexcept
|
|||||||
*
|
*
|
||||||
* Must only be called when RNDRRS is supported.
|
* Must only be called when RNDRRS is supported.
|
||||||
*/
|
*/
|
||||||
static uint64_t GetRNDRRS() noexcept
|
uint64_t GetRNDRRS() noexcept
|
||||||
{
|
{
|
||||||
uint8_t ok;
|
uint8_t ok;
|
||||||
uint64_t r1;
|
uint64_t r1;
|
||||||
@ -241,12 +251,12 @@ static uint64_t GetRNDRRS() noexcept
|
|||||||
* Slower sources should probably be invoked separately, and/or only from
|
* Slower sources should probably be invoked separately, and/or only from
|
||||||
* RandAddPeriodic (which is called once a minute).
|
* RandAddPeriodic (which is called once a minute).
|
||||||
*/
|
*/
|
||||||
static void InitHardwareRand() {}
|
void InitHardwareRand() {}
|
||||||
static void ReportHardwareRand() {}
|
void ReportHardwareRand() {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Add 64 bits of entropy gathered from hardware to hasher. Do nothing if not supported. */
|
/** Add 64 bits of entropy gathered from hardware to hasher. Do nothing if not supported. */
|
||||||
static void SeedHardwareFast(CSHA512& hasher) noexcept {
|
void SeedHardwareFast(CSHA512& hasher) noexcept {
|
||||||
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
|
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
|
||||||
if (g_rdrand_supported) {
|
if (g_rdrand_supported) {
|
||||||
uint64_t out = GetRdRand();
|
uint64_t out = GetRdRand();
|
||||||
@ -263,7 +273,7 @@ static void SeedHardwareFast(CSHA512& hasher) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Add 256 bits of entropy gathered from hardware to hasher. Do nothing if not supported. */
|
/** Add 256 bits of entropy gathered from hardware to hasher. Do nothing if not supported. */
|
||||||
static void SeedHardwareSlow(CSHA512& hasher) noexcept {
|
void SeedHardwareSlow(CSHA512& hasher) noexcept {
|
||||||
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
|
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
|
||||||
// When we want 256 bits of entropy, prefer RdSeed over RdRand, as it's
|
// When we want 256 bits of entropy, prefer RdSeed over RdRand, as it's
|
||||||
// guaranteed to produce independent randomness on every call.
|
// guaranteed to produce independent randomness on every call.
|
||||||
@ -296,7 +306,7 @@ static void SeedHardwareSlow(CSHA512& hasher) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Use repeated SHA512 to strengthen the randomness in seed32, and feed into hasher. */
|
/** Use repeated SHA512 to strengthen the randomness in seed32, and feed into hasher. */
|
||||||
static void Strengthen(const unsigned char (&seed)[32], SteadyClock::duration dur, CSHA512& hasher) noexcept
|
void Strengthen(const unsigned char (&seed)[32], SteadyClock::duration dur, CSHA512& hasher) noexcept
|
||||||
{
|
{
|
||||||
CSHA512 inner_hasher;
|
CSHA512 inner_hasher;
|
||||||
inner_hasher.Write(seed, sizeof(seed));
|
inner_hasher.Write(seed, sizeof(seed));
|
||||||
@ -327,7 +337,7 @@ static void Strengthen(const unsigned char (&seed)[32], SteadyClock::duration du
|
|||||||
/** Fallback: get 32 bytes of system entropy from /dev/urandom. The most
|
/** Fallback: get 32 bytes of system entropy from /dev/urandom. The most
|
||||||
* compatible way to get cryptographic randomness on UNIX-ish platforms.
|
* compatible way to get cryptographic randomness on UNIX-ish platforms.
|
||||||
*/
|
*/
|
||||||
[[maybe_unused]] static void GetDevURandom(unsigned char *ent32)
|
[[maybe_unused]] void GetDevURandom(unsigned char *ent32)
|
||||||
{
|
{
|
||||||
int f = open("/dev/urandom", O_RDONLY);
|
int f = open("/dev/urandom", O_RDONLY);
|
||||||
if (f == -1) {
|
if (f == -1) {
|
||||||
@ -402,8 +412,6 @@ void GetOSRand(unsigned char *ent32)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class RNGState {
|
class RNGState {
|
||||||
Mutex m_mutex;
|
Mutex m_mutex;
|
||||||
/* The RNG state consists of 256 bits of entropy, taken from the output of
|
/* The RNG state consists of 256 bits of entropy, taken from the output of
|
||||||
@ -521,20 +529,19 @@ RNGState& GetRNGState() noexcept
|
|||||||
static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
|
static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
|
||||||
return g_rng[0];
|
return g_rng[0];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* A note on the use of noexcept in the seeding functions below:
|
/* A note on the use of noexcept in the seeding functions below:
|
||||||
*
|
*
|
||||||
* None of the RNG code should ever throw any exception.
|
* None of the RNG code should ever throw any exception.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void SeedTimestamp(CSHA512& hasher) noexcept
|
void SeedTimestamp(CSHA512& hasher) noexcept
|
||||||
{
|
{
|
||||||
int64_t perfcounter = GetPerformanceCounter();
|
int64_t perfcounter = GetPerformanceCounter();
|
||||||
hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
|
hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SeedFast(CSHA512& hasher) noexcept
|
void SeedFast(CSHA512& hasher) noexcept
|
||||||
{
|
{
|
||||||
unsigned char buffer[32];
|
unsigned char buffer[32];
|
||||||
|
|
||||||
@ -549,7 +556,7 @@ static void SeedFast(CSHA512& hasher) noexcept
|
|||||||
SeedTimestamp(hasher);
|
SeedTimestamp(hasher);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept
|
void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept
|
||||||
{
|
{
|
||||||
unsigned char buffer[32];
|
unsigned char buffer[32];
|
||||||
|
|
||||||
@ -571,7 +578,7 @@ static void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Extract entropy from rng, strengthen it, and feed it into hasher. */
|
/** Extract entropy from rng, strengthen it, and feed it into hasher. */
|
||||||
static void SeedStrengthen(CSHA512& hasher, RNGState& rng, SteadyClock::duration dur) noexcept
|
void SeedStrengthen(CSHA512& hasher, RNGState& rng, SteadyClock::duration dur) noexcept
|
||||||
{
|
{
|
||||||
// Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
|
// Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
|
||||||
// Never use the deterministic PRNG for this, as the result is only used internally.
|
// Never use the deterministic PRNG for this, as the result is only used internally.
|
||||||
@ -581,7 +588,7 @@ static void SeedStrengthen(CSHA512& hasher, RNGState& rng, SteadyClock::duration
|
|||||||
Strengthen(strengthen_seed, dur, hasher);
|
Strengthen(strengthen_seed, dur, hasher);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
|
void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
|
||||||
{
|
{
|
||||||
// Everything that the 'fast' seeder includes
|
// Everything that the 'fast' seeder includes
|
||||||
SeedFast(hasher);
|
SeedFast(hasher);
|
||||||
@ -601,7 +608,7 @@ static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
|
|||||||
SeedStrengthen(hasher, rng, 10ms);
|
SeedStrengthen(hasher, rng, 10ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
|
void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
|
||||||
{
|
{
|
||||||
// Gather 256 bits of hardware randomness, if available
|
// Gather 256 bits of hardware randomness, if available
|
||||||
SeedHardwareSlow(hasher);
|
SeedHardwareSlow(hasher);
|
||||||
@ -627,7 +634,7 @@ enum class RNGLevel {
|
|||||||
PERIODIC, //!< Called by RandAddPeriodic()
|
PERIODIC, //!< Called by RandAddPeriodic()
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ProcRand(unsigned char* out, int num, RNGLevel level, bool always_use_real_rng) noexcept
|
void ProcRand(unsigned char* out, int num, RNGLevel level, bool always_use_real_rng) noexcept
|
||||||
{
|
{
|
||||||
// Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
|
// Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
|
||||||
RNGState& rng = GetRNGState();
|
RNGState& rng = GetRNGState();
|
||||||
@ -656,6 +663,9 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level, bool always_us
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
/** Internal function to set g_determinstic_rng. Only accessed from tests. */
|
/** Internal function to set g_determinstic_rng. Only accessed from tests. */
|
||||||
void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept
|
void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept
|
||||||
{
|
{
|
||||||
@ -679,13 +689,6 @@ void RandAddPeriodic() noexcept
|
|||||||
|
|
||||||
void RandAddEvent(const uint32_t event_info) noexcept { GetRNGState().AddEvent(event_info); }
|
void RandAddEvent(const uint32_t event_info) noexcept { GetRNGState().AddEvent(event_info); }
|
||||||
|
|
||||||
uint256 GetRandHash() noexcept
|
|
||||||
{
|
|
||||||
uint256 hash;
|
|
||||||
GetRandBytes(hash);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FastRandomContext::RandomSeed() noexcept
|
void FastRandomContext::RandomSeed() noexcept
|
||||||
{
|
{
|
||||||
uint256 seed = GetRandHash();
|
uint256 seed = GetRandHash();
|
||||||
|
101
src/random.h
101
src/random.h
@ -28,8 +28,8 @@
|
|||||||
* The following (classes of) functions interact with that state by mixing in new
|
* The following (classes of) functions interact with that state by mixing in new
|
||||||
* entropy, and optionally extracting random output from it:
|
* entropy, and optionally extracting random output from it:
|
||||||
*
|
*
|
||||||
* - The GetRand*() class of functions, as well as construction of FastRandomContext objects,
|
* - GetRandBytes, GetRandHash, GetRandDur, as well as construction of FastRandomContext
|
||||||
* perform 'fast' seeding, consisting of mixing in:
|
* objects, perform 'fast' seeding, consisting of mixing in:
|
||||||
* - A stack pointer (indirectly committing to calling thread and call stack)
|
* - A stack pointer (indirectly committing to calling thread and call stack)
|
||||||
* - A high-precision timestamp (rdtsc when available, c++ high_resolution_clock otherwise)
|
* - A high-precision timestamp (rdtsc when available, c++ high_resolution_clock otherwise)
|
||||||
* - 64 bits from the hardware RNG (rdrand) when available.
|
* - 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
|
* FastRandomContext on the other hand does not protect against this once created, but
|
||||||
* is even faster (and acceptable to use inside tight loops).
|
* 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:
|
* that fast seeding includes, but additionally:
|
||||||
* - OS entropy (/dev/urandom, getrandom(), ...). The application will terminate if
|
* - OS entropy (/dev/urandom, getrandom(), ...). The application will terminate if
|
||||||
* this entropy source fails.
|
* this entropy source fails.
|
||||||
@ -53,7 +53,7 @@
|
|||||||
* - Strengthen the entropy for 10 ms using repeated SHA512.
|
* - Strengthen the entropy for 10 ms using repeated SHA512.
|
||||||
* This is run once every minute.
|
* This is run once every minute.
|
||||||
*
|
*
|
||||||
* On first use of the RNG (regardless of what function is called first), all entropy
|
* - 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:
|
* sources used in the 'slow' seeder are included, but also:
|
||||||
* - 256 bits from the hardware RNG (rdseed or rdrand) when available.
|
* - 256 bits from the hardware RNG (rdseed or rdrand) when available.
|
||||||
* - Dynamic environment data (performance monitoring, ...)
|
* - Dynamic environment data (performance monitoring, ...)
|
||||||
@ -71,27 +71,16 @@
|
|||||||
* only depends on the seed it was initialized with, possibly until it is reinitialized.
|
* only depends on the seed it was initialized with, possibly until it is reinitialized.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Thread-safe.
|
|
||||||
*/
|
|
||||||
void GetRandBytes(Span<unsigned char> bytes) noexcept;
|
|
||||||
|
|
||||||
uint256 GetRandHash() noexcept;
|
/* ============================= INITIALIZATION AND ADDING ENTROPY ============================= */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gather entropy from various sources, feed it into the internal PRNG, and
|
* Initialize global RNG state and log any CPU features that are used.
|
||||||
* generate random data using it.
|
|
||||||
*
|
*
|
||||||
* This function will cause failure whenever the OS RNG fails.
|
* Calling this function is optional. RNG state will be initialized when first
|
||||||
*
|
* needed if it is not called.
|
||||||
* Thread-safe.
|
|
||||||
*/
|
*/
|
||||||
void GetStrongRandBytes(Span<unsigned char> bytes) noexcept;
|
void RandomInit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gather entropy from various expensive sources, and feed them to the PRNG state.
|
* Gather entropy from various expensive sources, and feed them to the PRNG state.
|
||||||
@ -108,6 +97,47 @@ void RandAddPeriodic() noexcept;
|
|||||||
*/
|
*/
|
||||||
void RandAddEvent(const uint32_t event_info) noexcept;
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================= RANDOM NUMBER GENERATION CLASSES =============================
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
// Forward declaration of RandomMixin, used in RandomNumberGenerator concept.
|
// Forward declaration of RandomMixin, used in RandomNumberGenerator concept.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class RandomMixin;
|
class RandomMixin;
|
||||||
@ -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.
|
/** More efficient than using std::shuffle on a FastRandomContext.
|
||||||
*
|
*
|
||||||
* This is more efficient as std::shuffle will consume entropy in groups of
|
* 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.
|
/* ============================= MISCELLANEOUS TEST-ONLY FUNCTIONS ============================= */
|
||||||
* 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);
|
|
||||||
|
|
||||||
/** Check that OS randomness is available and returning the requested number
|
/** Check that OS randomness is available and returning the requested number
|
||||||
* of bytes.
|
* of bytes.
|
||||||
*/
|
*/
|
||||||
bool Random_SanityCheck();
|
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
|
#endif // BITCOIN_RANDOM_H
|
||||||
|
@ -33,7 +33,7 @@ BOOST_AUTO_TEST_SUITE(cuckoocache_tests);
|
|||||||
|
|
||||||
/* Test that no values not inserted into the cache are read out of it.
|
/* Test that no values not inserted into the cache are read out of it.
|
||||||
*
|
*
|
||||||
* There are no repeats in the first 200000 insecure_GetRandHash calls
|
* There are no repeats in the first 200000 InsecureRand256() calls
|
||||||
*/
|
*/
|
||||||
BOOST_AUTO_TEST_CASE(test_cuckoocache_no_fakes)
|
BOOST_AUTO_TEST_CASE(test_cuckoocache_no_fakes)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user