mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 04:52:59 +01:00
Merge #10322: Use hardware timestamps in RNG seeding
2c0a6f1
Use sanity check timestamps as entropy (Pieter Wuille)33f853d
Test that GetPerformanceCounter() increments (Pieter Wuille)f544094
Use hardware timestamps in RNG seeding (Pieter Wuille) Tree-SHA512: ea96ff56d425b5dc693b4dd35c8aa64ba20a01b9bd7d2d65298ece623f434e8cfa190f9c0f9b76df8aa496547bfa64533eb751edec8401d09bd5ee3478928a59
This commit is contained in:
parent
15f7f9c850
commit
b13d92079d
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -43,15 +45,22 @@ static void RandFailure()
|
|||||||
|
|
||||||
static inline int64_t GetPerformanceCounter()
|
static inline int64_t GetPerformanceCounter()
|
||||||
{
|
{
|
||||||
int64_t nCounter = 0;
|
// Read the hardware time stamp counter when available.
|
||||||
#ifdef WIN32
|
// See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
|
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
|
||||||
|
return __rdtsc();
|
||||||
|
#elif !defined(_MSC_VER) && defined(__i386__)
|
||||||
|
uint64_t r = 0;
|
||||||
|
__asm__ volatile ("rdtsc" : "=A"(r)); // Constrain the r variable to the eax:edx pair.
|
||||||
|
return r;
|
||||||
|
#elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
|
||||||
|
uint64_t r1 = 0, r2 = 0;
|
||||||
|
__asm__ volatile ("rdtsc" : "=a"(r1), "=d"(r2)); // Constrain r1 to rax and r2 to rdx.
|
||||||
|
return (r2 << 32) | r1;
|
||||||
#else
|
#else
|
||||||
timeval t;
|
// Fall back to using C++11 clock (usually microsecond or nanosecond precision)
|
||||||
gettimeofday(&t, NULL);
|
return std::chrono::high_resolution_clock::now().time_since_epoch().count();
|
||||||
nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec);
|
|
||||||
#endif
|
#endif
|
||||||
return nCounter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RandAddSeed()
|
void RandAddSeed()
|
||||||
@ -265,6 +274,8 @@ FastRandomContext::FastRandomContext(const uint256& seed) : requires_seed(false)
|
|||||||
|
|
||||||
bool Random_SanityCheck()
|
bool Random_SanityCheck()
|
||||||
{
|
{
|
||||||
|
uint64_t start = GetPerformanceCounter();
|
||||||
|
|
||||||
/* This does not measure the quality of randomness, but it does test that
|
/* This does not measure the quality of randomness, but it does test that
|
||||||
* OSRandom() overwrites all 32 bytes of the output given a maximum
|
* OSRandom() overwrites all 32 bytes of the output given a maximum
|
||||||
* number of tries.
|
* number of tries.
|
||||||
@ -291,7 +302,18 @@ bool Random_SanityCheck()
|
|||||||
|
|
||||||
tries += 1;
|
tries += 1;
|
||||||
} while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
|
} while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
|
||||||
return (num_overwritten == NUM_OS_RANDOM_BYTES); /* If this failed, bailed out after too many tries */
|
if (num_overwritten != NUM_OS_RANDOM_BYTES) return false; /* If this failed, bailed out after too many tries */
|
||||||
|
|
||||||
|
// Check that GetPerformanceCounter increases at least during a GetOSRand() call + 1ms sleep.
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
uint64_t stop = GetPerformanceCounter();
|
||||||
|
if (stop == start) return false;
|
||||||
|
|
||||||
|
// We called GetPerformanceCounter. Use it as entropy.
|
||||||
|
RAND_add((const unsigned char*)&start, sizeof(start), 1);
|
||||||
|
RAND_add((const unsigned char*)&stop, sizeof(stop), 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FastRandomContext::FastRandomContext(bool fDeterministic) : requires_seed(!fDeterministic), bytebuf_size(0), bitbuf_size(0)
|
FastRandomContext::FastRandomContext(bool fDeterministic) : requires_seed(!fDeterministic), bytebuf_size(0), bitbuf_size(0)
|
||||||
|
Loading…
Reference in New Issue
Block a user