Changeset View
Changeset View
Standalone View
Standalone View
src/random.cpp
Show First 20 Lines • Show All 206 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
} | } | ||||
#else | #else | ||||
/** | /** | ||||
* Access to other hardware random number generators could be added here later, | * Access to other hardware random number generators could be added here later, | ||||
* assuming it is sufficiently fast (in the order of a few hundred CPU cycles). | * assuming it is sufficiently fast (in the order of a few hundred CPU cycles). | ||||
* Slower sources should probably be invoked separately, and/or only from | * Slower sources should probably be invoked separately, and/or only from | ||||
* RandAddSeedSleep (which is called during idle background operation). | * RandAddPeriodic (which is called once a minute). | ||||
*/ | */ | ||||
static void InitHardwareRand() {} | static void InitHardwareRand() {} | ||||
static void ReportHardwareRand() {} | static void ReportHardwareRand() {} | ||||
#endif | #endif | ||||
/** | /** | ||||
* Add 64 bits of entropy gathered from hardware to hasher. Do nothing if not | * Add 64 bits of entropy gathered from hardware to hasher. Do nothing if not | ||||
* supported. | * supported. | ||||
▲ Show 20 Lines • Show All 273 Lines • ▼ Show 20 Lines | void LockingCallbackOpenSSL(int mode, int i, const char *file, | ||||
} else { | } else { | ||||
rng.GetOpenSSLMutex(i).unlock(); | rng.GetOpenSSLMutex(i).unlock(); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* 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, with the sole exception | * None of the RNG code should ever throw any exception. | ||||
* of MilliSleep in SeedSleep, which can (and does) support interruptions which | |||||
* cause a boost::thread_interrupted to be thrown. | |||||
* | |||||
* This means that SeedSleep, and all functions that invoke it are throwing. | |||||
* However, we know that GetRandBytes() and GetStrongRandBytes() never trigger | |||||
* this sleeping logic, so they are noexcept. The same is true for all the | |||||
* GetRand*() functions that use GetRandBytes() indirectly. | |||||
* | |||||
* TODO: After moving away from interruptible boost-based thread management, | |||||
* everything can become noexcept here. | |||||
*/ | */ | ||||
static void SeedTimestamp(CSHA512 &hasher) noexcept { | static void SeedTimestamp(CSHA512 &hasher) noexcept { | ||||
int64_t perfcounter = GetPerformanceCounter(); | int64_t perfcounter = GetPerformanceCounter(); | ||||
hasher.Write((const uint8_t *)&perfcounter, sizeof(perfcounter)); | hasher.Write((const uint8_t *)&perfcounter, sizeof(perfcounter)); | ||||
} | } | ||||
static void SeedFast(CSHA512 &hasher) noexcept { | static void SeedFast(CSHA512 &hasher) noexcept { | ||||
Show All 39 Lines | static void SeedStrengthen(CSHA512 &hasher, RNGState &rng, | ||||
// already in hasher. | // already in hasher. | ||||
uint8_t strengthen_seed[32]; | uint8_t strengthen_seed[32]; | ||||
rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher), | rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher), | ||||
false); | false); | ||||
// Strengthen the seed, and feed it into hasher. | // Strengthen the seed, and feed it into hasher. | ||||
Strengthen(strengthen_seed, microseconds, hasher); | Strengthen(strengthen_seed, microseconds, hasher); | ||||
} | } | ||||
static void SeedPeriodic(CSHA512 &hasher, RNGState &rng) { | static void SeedPeriodic(CSHA512 &hasher, RNGState &rng) noexcept { | ||||
// Everything that the 'fast' seeder includes | // Everything that the 'fast' seeder includes | ||||
SeedFast(hasher); | SeedFast(hasher); | ||||
// High-precision timestamp | // High-precision timestamp | ||||
SeedTimestamp(hasher); | SeedTimestamp(hasher); | ||||
// Dynamic environment data (performance monitoring, ...) | // Dynamic environment data (performance monitoring, ...) | ||||
auto old_size = hasher.Size(); | auto old_size = hasher.Size(); | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void GetRandBytes(uint8_t *buf, int num) noexcept { | void GetRandBytes(uint8_t *buf, int num) noexcept { | ||||
ProcRand(buf, num, RNGLevel::FAST); | ProcRand(buf, num, RNGLevel::FAST); | ||||
} | } | ||||
void GetStrongRandBytes(uint8_t *buf, int num) noexcept { | void GetStrongRandBytes(uint8_t *buf, int num) noexcept { | ||||
ProcRand(buf, num, RNGLevel::SLOW); | ProcRand(buf, num, RNGLevel::SLOW); | ||||
} | } | ||||
void RandAddPeriodic() { | void RandAddPeriodic() noexcept { | ||||
ProcRand(nullptr, 0, RNGLevel::PERIODIC); | ProcRand(nullptr, 0, RNGLevel::PERIODIC); | ||||
} | } | ||||
bool g_mock_deterministic_tests{false}; | bool g_mock_deterministic_tests{false}; | ||||
uint64_t GetRand(uint64_t nMax) noexcept { | uint64_t GetRand(uint64_t nMax) noexcept { | ||||
return FastRandomContext(g_mock_deterministic_tests).randrange(nMax); | return FastRandomContext(g_mock_deterministic_tests).randrange(nMax); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 134 Lines • Show Last 20 Lines |