24 #include <openssl/err.h>
25 #include <openssl/rand.h>
27 static void RandFailure()
29 LogPrintf(
"Failed to read randomness, aborting\n");
33 static inline int64_t GetPerformanceCounter()
37 QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
40 gettimeofday(&t, NULL);
41 nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec);
49 int64_t nCounter = GetPerformanceCounter();
50 RAND_add(&nCounter,
sizeof(nCounter), 1.5);
54 static void RandAddSeedPerfmon()
63 static int64_t nLastPerfmon;
64 if (
GetTime() < nLastPerfmon + 10 * 60)
68 std::vector<unsigned char> vData(250000, 0);
70 unsigned long nSize = 0;
71 const size_t nMaxSize = 10000000;
74 ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA,
"Global", NULL, NULL, vData.data(), &nSize);
75 if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
77 vData.resize(std::max((vData.size() * 3) / 2, nMaxSize));
79 RegCloseKey(HKEY_PERFORMANCE_DATA);
80 if (ret == ERROR_SUCCESS) {
81 RAND_add(vData.data(), nSize, nSize / 100.0);
83 LogPrint(
"rand",
"%s: %lu bytes\n", __func__, nSize);
85 static bool warned =
false;
87 LogPrintf(
"%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret);
95 static void GetOSRand(
unsigned char *ent32)
99 int ret = CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
103 ret = CryptGenRandom(hProvider, 32, ent32);
107 CryptReleaseContext(hProvider, 0);
109 int f = open(
"/dev/urandom", O_RDONLY);
115 ssize_t n = read(f, ent32 + have, 32 - have);
116 if (n <= 0 || n + have > 32) {
127 if (RAND_bytes(buf, num) != 1) {
136 unsigned char buf[64];
139 RandAddSeedPerfmon();
141 hasher.
Write(buf, 32);
145 hasher.
Write(buf, 32);
160 uint64_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
164 }
while (nRand >= nRange);
165 return (nRand % nMax);
183 if (fDeterministic) {
189 }
while (tmp == 0 || tmp == 0x9068ffffU);
193 }
while (tmp == 0 || tmp == 0x464fffffU);
A hasher class for SHA-512.
void Finalize(unsigned char hash[OUTPUT_SIZE])
CSHA512 & Write(const unsigned char *data, size_t len)
FastRandomContext(bool fDeterministic=false)
void memory_cleanse(void *ptr, size_t len)
void * memcpy(void *a, const void *b, size_t c)
uint64_t GetRand(uint64_t nMax)
void GetStrongRandBytes(unsigned char *out, int num)
Function to gather random data from multiple sources, failing whenever any of those source fail to pr...
void GetRandBytes(unsigned char *buf, int num)
Functions to gather random data via the OpenSSL PRNG.
#define LogPrint(category,...)
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units.