mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-12-11 05:03:16 +01:00
Seed RNG with precision timestamps on receipt of net messages.
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <random.h>
|
||||
|
||||
#include <compat/cpuid.h>
|
||||
#include <crypto/sha256.h>
|
||||
#include <crypto/sha512.h>
|
||||
#include <support/cleanse.h>
|
||||
#ifdef WIN32
|
||||
@@ -449,6 +450,23 @@ static void SeedFast(CSHA512& hasher) noexcept
|
||||
SeedTimestamp(hasher);
|
||||
}
|
||||
|
||||
// We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
|
||||
// since we want it to be fast as network peers may be able to trigger it repeatedly.
|
||||
static Mutex events_mutex;
|
||||
static CSHA256 events_hasher;
|
||||
static void SeedEvents(CSHA512& hasher)
|
||||
{
|
||||
LOCK(events_mutex);
|
||||
|
||||
unsigned char events_hash[32];
|
||||
events_hasher.Finalize(events_hash);
|
||||
hasher.Write(events_hash, 32);
|
||||
|
||||
// Re-initialize the hasher with the finalized state to use later.
|
||||
events_hasher.Reset();
|
||||
events_hasher.Write(events_hash, 32);
|
||||
}
|
||||
|
||||
static void SeedSlow(CSHA512& hasher) noexcept
|
||||
{
|
||||
unsigned char buffer[32];
|
||||
@@ -460,6 +478,9 @@ static void SeedSlow(CSHA512& hasher) noexcept
|
||||
GetOSRand(buffer);
|
||||
hasher.Write(buffer, sizeof(buffer));
|
||||
|
||||
// Add the events hasher into the mix
|
||||
SeedEvents(hasher);
|
||||
|
||||
// High-precision timestamp.
|
||||
//
|
||||
// Note that we also commit to a timestamp in the Fast seeder, so we indirectly commit to a
|
||||
@@ -485,6 +506,9 @@ static void SeedPeriodic(CSHA512& hasher, RNGState& rng)
|
||||
// High-precision timestamp
|
||||
SeedTimestamp(hasher);
|
||||
|
||||
// Add the events hasher into the mix
|
||||
SeedEvents(hasher);
|
||||
|
||||
// Dynamic environment data (performance monitoring, ...)
|
||||
auto old_size = hasher.Size();
|
||||
RandAddDynamicEnv(hasher);
|
||||
@@ -553,6 +577,15 @@ void GetRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNG
|
||||
void GetStrongRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::SLOW); }
|
||||
void RandAddPeriodic() { ProcRand(nullptr, 0, RNGLevel::PERIODIC); }
|
||||
|
||||
void RandAddEvent(const uint32_t event_info) {
|
||||
LOCK(events_mutex);
|
||||
events_hasher.Write((const unsigned char *)&event_info, sizeof(event_info));
|
||||
// Get the low four bytes of the performance counter. This translates to roughly the
|
||||
// subsecond part.
|
||||
uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
|
||||
events_hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
|
||||
}
|
||||
|
||||
bool g_mock_deterministic_tests{false};
|
||||
|
||||
uint64_t GetRand(uint64_t nMax) noexcept
|
||||
|
||||
Reference in New Issue
Block a user