Bitcoin Core 29.99.0
P2P Digital Currency
random.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-present The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include <bitcoin-build-config.h> // IWYU pragma: keep
7
8#include <random.h>
9
10#include <compat/compat.h>
11#include <compat/cpuid.h>
12#include <crypto/chacha20.h>
13#include <crypto/sha256.h>
14#include <crypto/sha512.h>
15#include <logging.h>
16#include <randomenv.h>
17#include <span.h>
19#include <support/cleanse.h>
20#include <sync.h>
21#include <util/time.h>
22
23#include <array>
24#include <cmath>
25#include <cstdlib>
26#include <optional>
27#include <thread>
28
29#ifdef WIN32
30#include <windows.h>
31#include <wincrypt.h>
32#else
33#include <fcntl.h>
34#include <sys/time.h>
35#endif
36
37#if defined(HAVE_GETRANDOM) || (defined(HAVE_GETENTROPY_RAND) && defined(__APPLE__))
38#include <sys/random.h>
39#endif
40
41#ifdef HAVE_SYSCTL_ARND
42#include <sys/sysctl.h>
43#endif
44
45namespace {
46
47/* Number of random bytes returned by GetOSRand.
48 * When changing this constant make sure to change all call sites, and make
49 * sure that the underlying OS APIs for all platforms support the number.
50 * (many cap out at 256 bytes).
51 */
52static const int NUM_OS_RANDOM_BYTES = 32;
53
54
55[[noreturn]] void RandFailure()
56{
57 LogError("Failed to read randomness, aborting\n");
58 std::abort();
59}
60
61inline int64_t GetPerformanceCounter() noexcept
62{
63 // Read the hardware time stamp counter when available.
64 // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
65#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
66 return __rdtsc();
67#elif !defined(_MSC_VER) && defined(__i386__)
68 uint64_t r = 0;
69 __asm__ volatile ("rdtsc" : "=A"(r)); // Constrain the r variable to the eax:edx pair.
70 return r;
71#elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
72 uint64_t r1 = 0, r2 = 0;
73 __asm__ volatile ("rdtsc" : "=a"(r1), "=d"(r2)); // Constrain r1 to rax and r2 to rdx.
74 return (r2 << 32) | r1;
75#else
76 // Fall back to using standard library clock (usually microsecond or nanosecond precision)
77 return std::chrono::high_resolution_clock::now().time_since_epoch().count();
78#endif
79}
80
81#ifdef HAVE_GETCPUID
82bool g_rdrand_supported = false;
83bool g_rdseed_supported = false;
84constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
85constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
86#ifdef bit_RDRND
87static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND, "Unexpected value for bit_RDRND");
88#endif
89#ifdef bit_RDSEED
90static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED, "Unexpected value for bit_RDSEED");
91#endif
92
93void InitHardwareRand()
94{
95 uint32_t eax, ebx, ecx, edx;
96 GetCPUID(1, 0, eax, ebx, ecx, edx);
97 if (ecx & CPUID_F1_ECX_RDRAND) {
98 g_rdrand_supported = true;
99 }
100 GetCPUID(7, 0, eax, ebx, ecx, edx);
101 if (ebx & CPUID_F7_EBX_RDSEED) {
102 g_rdseed_supported = true;
103 }
104}
105
106void ReportHardwareRand()
107{
108 // This must be done in a separate function, as InitHardwareRand() may be indirectly called
109 // from global constructors, before logging is initialized.
110 if (g_rdseed_supported) {
111 LogPrintf("Using RdSeed as an additional entropy source\n");
112 }
113 if (g_rdrand_supported) {
114 LogPrintf("Using RdRand as an additional entropy source\n");
115 }
116}
117
122uint64_t GetRdRand() noexcept
123{
124 // RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce this risk.
125#ifdef __i386__
126 uint8_t ok = 0;
127 // Initialize to 0 to silence a compiler warning that r1 or r2 may be used
128 // uninitialized. Even if rdrand fails (!ok) it will set the output to 0,
129 // but there is no way that the compiler could know that.
130 uint32_t r1 = 0, r2 = 0;
131 for (int i = 0; i < 10; ++i) {
132 __asm__ volatile (".byte 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdrand %eax
133 if (ok) break;
134 }
135 for (int i = 0; i < 10; ++i) {
136 __asm__ volatile (".byte 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r2), "=q"(ok) :: "cc"); // rdrand %eax
137 if (ok) break;
138 }
139 return (((uint64_t)r2) << 32) | r1;
140#elif defined(__x86_64__) || defined(__amd64__)
141 uint8_t ok = 0;
142 uint64_t r1 = 0; // See above why we initialize to 0.
143 for (int i = 0; i < 10; ++i) {
144 __asm__ volatile (".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdrand %rax
145 if (ok) break;
146 }
147 return r1;
148#else
149#error "RdRand is only supported on x86 and x86_64"
150#endif
151}
152
157uint64_t GetRdSeed() noexcept
158{
159 // RdSeed may fail when the HW RNG is overloaded. Loop indefinitely until enough entropy is gathered,
160 // but pause after every failure.
161#ifdef __i386__
162 uint8_t ok = 0;
163 uint32_t r1, r2;
164 do {
165 __asm__ volatile (".byte 0x0f, 0xc7, 0xf8; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdseed %eax
166 if (ok) break;
167 __asm__ volatile ("pause");
168 } while(true);
169 do {
170 __asm__ volatile (".byte 0x0f, 0xc7, 0xf8; setc %1" : "=a"(r2), "=q"(ok) :: "cc"); // rdseed %eax
171 if (ok) break;
172 __asm__ volatile ("pause");
173 } while(true);
174 return (((uint64_t)r2) << 32) | r1;
175#elif defined(__x86_64__) || defined(__amd64__)
176 uint8_t ok;
177 uint64_t r1;
178 do {
179 __asm__ volatile (".byte 0x48, 0x0f, 0xc7, 0xf8; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdseed %rax
180 if (ok) break;
181 __asm__ volatile ("pause");
182 } while(true);
183 return r1;
184#else
185#error "RdSeed is only supported on x86 and x86_64"
186#endif
187}
188
189#else
190/* Access to other hardware random number generators could be added here later,
191 * assuming it is sufficiently fast (in the order of a few hundred CPU cycles).
192 * Slower sources should probably be invoked separately, and/or only from
193 * RandAddPeriodic (which is called once a minute).
194 */
195void InitHardwareRand() {}
196void ReportHardwareRand() {}
197#endif
198
200void SeedHardwareFast(CSHA512& hasher) noexcept {
201#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
202 if (g_rdrand_supported) {
203 uint64_t out = GetRdRand();
204 hasher.Write((const unsigned char*)&out, sizeof(out));
205 return;
206 }
207#endif
208}
209
211void SeedHardwareSlow(CSHA512& hasher) noexcept {
212#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
213 // When we want 256 bits of entropy, prefer RdSeed over RdRand, as it's
214 // guaranteed to produce independent randomness on every call.
215 if (g_rdseed_supported) {
216 for (int i = 0; i < 4; ++i) {
217 uint64_t out = GetRdSeed();
218 hasher.Write((const unsigned char*)&out, sizeof(out));
219 }
220 return;
221 }
222 // When falling back to RdRand, XOR the result of 1024 results.
223 // This guarantees a reseeding occurs between each.
224 if (g_rdrand_supported) {
225 for (int i = 0; i < 4; ++i) {
226 uint64_t out = 0;
227 for (int j = 0; j < 1024; ++j) out ^= GetRdRand();
228 hasher.Write((const unsigned char*)&out, sizeof(out));
229 }
230 return;
231 }
232#endif
233}
234
236void Strengthen(const unsigned char (&seed)[32], SteadyClock::duration dur, CSHA512& hasher) noexcept
237{
238 CSHA512 inner_hasher;
239 inner_hasher.Write(seed, sizeof(seed));
240
241 // Hash loop
242 unsigned char buffer[64];
243 const auto stop{SteadyClock::now() + dur};
244 do {
245 for (int i = 0; i < 1000; ++i) {
246 inner_hasher.Finalize(buffer);
247 inner_hasher.Reset();
248 inner_hasher.Write(buffer, sizeof(buffer));
249 }
250 // Benchmark operation and feed it into outer hasher.
251 int64_t perf = GetPerformanceCounter();
252 hasher.Write((const unsigned char*)&perf, sizeof(perf));
253 } while (SteadyClock::now() < stop);
254
255 // Produce output from inner state and feed it to outer hasher.
256 inner_hasher.Finalize(buffer);
257 hasher.Write(buffer, sizeof(buffer));
258 // Try to clean up.
259 inner_hasher.Reset();
260 memory_cleanse(buffer, sizeof(buffer));
261}
262
263#ifndef WIN32
267[[maybe_unused]] void GetDevURandom(unsigned char *ent32)
268{
269 int f = open("/dev/urandom", O_RDONLY);
270 if (f == -1) {
271 RandFailure();
272 }
273 int have = 0;
274 do {
275 ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
276 if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
277 close(f);
278 RandFailure();
279 }
280 have += n;
281 } while (have < NUM_OS_RANDOM_BYTES);
282 close(f);
283}
284#endif
285
287void GetOSRand(unsigned char *ent32)
288{
289#if defined(WIN32)
290 HCRYPTPROV hProvider;
291 int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
292 if (!ret) {
293 RandFailure();
294 }
295 ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32);
296 if (!ret) {
297 RandFailure();
298 }
299 CryptReleaseContext(hProvider, 0);
300#elif defined(HAVE_GETRANDOM)
301 /* Linux. From the getrandom(2) man page:
302 * "If the urandom source has been initialized, reads of up to 256 bytes
303 * will always return as many bytes as requested and will not be
304 * interrupted by signals."
305 */
306 if (getrandom(ent32, NUM_OS_RANDOM_BYTES, 0) != NUM_OS_RANDOM_BYTES) {
307 RandFailure();
308 }
309#elif defined(__OpenBSD__)
310 /* OpenBSD. From the arc4random(3) man page:
311 "Use of these functions is encouraged for almost all random number
312 consumption because the other interfaces are deficient in either
313 quality, portability, standardization, or availability."
314 The function call is always successful.
315 */
316 arc4random_buf(ent32, NUM_OS_RANDOM_BYTES);
317#elif defined(HAVE_GETENTROPY_RAND) && defined(__APPLE__)
318 if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
319 RandFailure();
320 }
321#elif defined(HAVE_SYSCTL_ARND)
322 /* FreeBSD, NetBSD and similar. It is possible for the call to return less
323 * bytes than requested, so need to read in a loop.
324 */
325 static int name[2] = {CTL_KERN, KERN_ARND};
326 int have = 0;
327 do {
328 size_t len = NUM_OS_RANDOM_BYTES - have;
329 if (sysctl(name, std::size(name), ent32 + have, &len, nullptr, 0) != 0) {
330 RandFailure();
331 }
332 have += len;
333 } while (have < NUM_OS_RANDOM_BYTES);
334#else
335 /* Fall back to /dev/urandom if there is no specific method implemented to
336 * get system entropy for this OS.
337 */
338 GetDevURandom(ent32);
339#endif
340}
341
342class RNGState {
343 Mutex m_mutex;
344 /* The RNG state consists of 256 bits of entropy, taken from the output of
345 * one operation's SHA512 output, and fed as input to the next one.
346 * Carrying 256 bits of entropy should be sufficient to guarantee
347 * unpredictability as long as any entropy source was ever unpredictable
348 * to an attacker. To protect against situations where an attacker might
349 * observe the RNG's state, fresh entropy is always mixed when
350 * GetStrongRandBytes is called.
351 */
352 unsigned char m_state[32] GUARDED_BY(m_mutex) = {0};
353 uint64_t m_counter GUARDED_BY(m_mutex) = 0;
354 bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
355
358 std::optional<ChaCha20> m_deterministic_prng GUARDED_BY(m_mutex);
359
360 Mutex m_events_mutex;
361 CSHA256 m_events_hasher GUARDED_BY(m_events_mutex);
362
363public:
364 RNGState() noexcept
365 {
366 InitHardwareRand();
367 }
368
369 ~RNGState() = default;
370
371 void AddEvent(uint32_t event_info) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex)
372 {
373 LOCK(m_events_mutex);
374
375 m_events_hasher.Write((const unsigned char *)&event_info, sizeof(event_info));
376 // Get the low four bytes of the performance counter. This translates to roughly the
377 // subsecond part.
378 uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
379 m_events_hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
380 }
381
385 void SeedEvents(CSHA512& hasher) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex)
386 {
387 // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
388 // since we want it to be fast as network peers may be able to trigger it repeatedly.
389 LOCK(m_events_mutex);
390
391 unsigned char events_hash[32];
392 m_events_hasher.Finalize(events_hash);
393 hasher.Write(events_hash, 32);
394
395 // Re-initialize the hasher with the finalized state to use later.
396 m_events_hasher.Reset();
397 m_events_hasher.Write(events_hash, 32);
398 }
399
401 void MakeDeterministic(const uint256& seed) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
402 {
403 LOCK(m_mutex);
404 m_deterministic_prng.emplace(MakeByteSpan(seed));
405 }
406
414 bool MixExtract(unsigned char* out, size_t num, CSHA512&& hasher, bool strong_seed, bool always_use_real_rng) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
415 {
416 assert(num <= 32);
417 unsigned char buf[64];
418 static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE, "Buffer needs to have hasher's output size");
419 bool ret;
420 {
421 LOCK(m_mutex);
422 ret = (m_strongly_seeded |= strong_seed);
423 // Write the current state of the RNG into the hasher
424 hasher.Write(m_state, 32);
425 // Write a new counter number into the state
426 hasher.Write((const unsigned char*)&m_counter, sizeof(m_counter));
427 ++m_counter;
428 // Finalize the hasher
429 hasher.Finalize(buf);
430 // Store the last 32 bytes of the hash output as new RNG state.
431 memcpy(m_state, buf + 32, 32);
432 // Handle requests for deterministic randomness.
433 if (!always_use_real_rng && m_deterministic_prng.has_value()) [[unlikely]] {
434 // Overwrite the beginning of buf, which will be used for output.
435 m_deterministic_prng->Keystream(std::as_writable_bytes(std::span{buf, num}));
436 // Do not require strong seeding for deterministic output.
437 ret = true;
438 }
439 }
440 // If desired, copy (up to) the first 32 bytes of the hash output as output.
441 if (num) {
442 assert(out != nullptr);
443 memcpy(out, buf, num);
444 }
445 // Best effort cleanup of internal state
446 hasher.Reset();
447 memory_cleanse(buf, 64);
448 return ret;
449 }
450};
451
452RNGState& GetRNGState() noexcept
453{
454 // This idiom relies on the guarantee that static variable are initialized
455 // on first call, even when multiple parallel calls are permitted.
456 static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
457 return g_rng[0];
458}
459
460/* A note on the use of noexcept in the seeding functions below:
461 *
462 * None of the RNG code should ever throw any exception.
463 */
464
465void SeedTimestamp(CSHA512& hasher) noexcept
466{
467 int64_t perfcounter = GetPerformanceCounter();
468 hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
469}
470
471void SeedFast(CSHA512& hasher) noexcept
472{
473 unsigned char buffer[32];
474
475 // Stack pointer to indirectly commit to thread/callstack
476 const unsigned char* ptr = buffer;
477 hasher.Write((const unsigned char*)&ptr, sizeof(ptr));
478
479 // Hardware randomness is very fast when available; use it always.
480 SeedHardwareFast(hasher);
481
482 // High-precision timestamp
483 SeedTimestamp(hasher);
484}
485
486void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept
487{
488 unsigned char buffer[32];
489
490 // Everything that the 'fast' seeder includes
491 SeedFast(hasher);
492
493 // OS randomness
494 GetOSRand(buffer);
495 hasher.Write(buffer, sizeof(buffer));
496
497 // Add the events hasher into the mix
498 rng.SeedEvents(hasher);
499
500 // High-precision timestamp.
501 //
502 // Note that we also commit to a timestamp in the Fast seeder, so we indirectly commit to a
503 // benchmark of all the entropy gathering sources in this function).
504 SeedTimestamp(hasher);
505}
506
508void SeedStrengthen(CSHA512& hasher, RNGState& rng, SteadyClock::duration dur) noexcept
509{
510 // Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
511 // Never use the deterministic PRNG for this, as the result is only used internally.
512 unsigned char strengthen_seed[32];
513 rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher), false, /*always_use_real_rng=*/true);
514 // Strengthen the seed, and feed it into hasher.
515 Strengthen(strengthen_seed, dur, hasher);
516}
517
518void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
519{
520 // Everything that the 'fast' seeder includes
521 SeedFast(hasher);
522
523 // High-precision timestamp
524 SeedTimestamp(hasher);
525
526 // Add the events hasher into the mix
527 rng.SeedEvents(hasher);
528
529 // Dynamic environment data (clocks, resource usage, ...)
530 auto old_size = hasher.Size();
531 RandAddDynamicEnv(hasher);
532 LogDebug(BCLog::RAND, "Feeding %i bytes of dynamic environment data into RNG\n", hasher.Size() - old_size);
533
534 // Strengthen for 10 ms
535 SeedStrengthen(hasher, rng, 10ms);
536}
537
538void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
539{
540 // Gather 256 bits of hardware randomness, if available
541 SeedHardwareSlow(hasher);
542
543 // Everything that the 'slow' seeder includes.
544 SeedSlow(hasher, rng);
545
546 // Dynamic environment data (clocks, resource usage, ...)
547 auto old_size = hasher.Size();
548 RandAddDynamicEnv(hasher);
549
550 // Static environment data
551 RandAddStaticEnv(hasher);
552 LogDebug(BCLog::RAND, "Feeding %i bytes of environment data into RNG\n", hasher.Size() - old_size);
553
554 // Strengthen for 100 ms
555 SeedStrengthen(hasher, rng, 100ms);
556}
557
558enum class RNGLevel {
559 FAST,
560 SLOW,
561 PERIODIC,
562};
563
564void ProcRand(unsigned char* out, int num, RNGLevel level, bool always_use_real_rng) noexcept
565{
566 // Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
567 RNGState& rng = GetRNGState();
568
569 assert(num <= 32);
570
571 CSHA512 hasher;
572 switch (level) {
573 case RNGLevel::FAST:
574 SeedFast(hasher);
575 break;
576 case RNGLevel::SLOW:
577 SeedSlow(hasher, rng);
578 break;
579 case RNGLevel::PERIODIC:
580 SeedPeriodic(hasher, rng);
581 break;
582 }
583
584 // Combine with and update state
585 if (!rng.MixExtract(out, num, std::move(hasher), false, always_use_real_rng)) {
586 // On the first invocation, also seed with SeedStartup().
587 CSHA512 startup_hasher;
588 SeedStartup(startup_hasher, rng);
589 rng.MixExtract(out, num, std::move(startup_hasher), true, always_use_real_rng);
590 }
591}
592
593} // namespace
594
595
597void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept
598{
599 GetRNGState().MakeDeterministic(seed);
600}
601std::atomic<bool> g_used_g_prng{false}; // Only accessed from tests
602
603void GetRandBytes(std::span<unsigned char> bytes) noexcept
604{
605 g_used_g_prng = true;
606 ProcRand(bytes.data(), bytes.size(), RNGLevel::FAST, /*always_use_real_rng=*/false);
607}
608
609void GetStrongRandBytes(std::span<unsigned char> bytes) noexcept
610{
611 ProcRand(bytes.data(), bytes.size(), RNGLevel::SLOW, /*always_use_real_rng=*/true);
612}
613
614void RandAddPeriodic() noexcept
615{
616 ProcRand(nullptr, 0, RNGLevel::PERIODIC, /*always_use_real_rng=*/false);
617}
618
619void RandAddEvent(const uint32_t event_info) noexcept { GetRNGState().AddEvent(event_info); }
620
622{
623 uint256 seed = GetRandHash();
624 rng.SetKey(MakeByteSpan(seed));
625 requires_seed = false;
626}
627
628void FastRandomContext::fillrand(std::span<std::byte> output) noexcept
629{
630 if (requires_seed) RandomSeed();
631 rng.Keystream(output);
632}
633
634FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), rng(MakeByteSpan(seed)) {}
635
636void FastRandomContext::Reseed(const uint256& seed) noexcept
637{
638 FlushCache();
639 requires_seed = false;
640 rng = {MakeByteSpan(seed)};
641}
642
644{
645 uint64_t start = GetPerformanceCounter();
646
647 /* This does not measure the quality of randomness, but it does test that
648 * GetOSRand() overwrites all 32 bytes of the output given a maximum
649 * number of tries.
650 */
651 static constexpr int MAX_TRIES{1024};
652 uint8_t data[NUM_OS_RANDOM_BYTES];
653 bool overwritten[NUM_OS_RANDOM_BYTES] = {}; /* Tracks which bytes have been overwritten at least once */
654 int num_overwritten;
655 int tries = 0;
656 /* Loop until all bytes have been overwritten at least once, or max number tries reached */
657 do {
658 memset(data, 0, NUM_OS_RANDOM_BYTES);
659 GetOSRand(data);
660 for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
661 overwritten[x] |= (data[x] != 0);
662 }
663
664 num_overwritten = 0;
665 for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
666 if (overwritten[x]) {
667 num_overwritten += 1;
668 }
669 }
670
671 tries += 1;
672 } while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
673 if (num_overwritten != NUM_OS_RANDOM_BYTES) return false; /* If this failed, bailed out after too many tries */
674
675 // Check that GetPerformanceCounter increases at least during a GetOSRand() call + 1ms sleep.
676 std::this_thread::sleep_for(std::chrono::milliseconds(1));
677 uint64_t stop = GetPerformanceCounter();
678 if (stop == start) return false;
679
680 // We called GetPerformanceCounter. Use it as entropy.
681 CSHA512 to_add;
682 to_add.Write((const unsigned char*)&start, sizeof(start));
683 to_add.Write((const unsigned char*)&stop, sizeof(stop));
684 GetRNGState().MixExtract(nullptr, 0, std::move(to_add), false, /*always_use_real_rng=*/true);
685
686 return true;
687}
688
689static constexpr std::array<std::byte, ChaCha20::KEYLEN> ZERO_KEY{};
690
691FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_seed(!fDeterministic), rng(ZERO_KEY)
692{
693 // Note that despite always initializing with ZERO_KEY, requires_seed is set to true if not
694 // fDeterministic. That means the rng will be reinitialized with a secure random key upon first
695 // use.
696}
697
699{
700 // Invoke RNG code to trigger initialization (if not already performed)
701 ProcRand(nullptr, 0, RNGLevel::FAST, /*always_use_real_rng=*/true);
702
703 ReportHardwareRand();
704}
705
706double MakeExponentiallyDistributed(uint64_t uniform) noexcept
707{
708 // To convert uniform into an exponentially-distributed double, we use two steps:
709 // - Convert uniform into a uniformly-distributed double in range [0, 1), use the expression
710 // ((uniform >> 11) * 0x1.0p-53), as described in https://prng.di.unimi.it/ under
711 // "Generating uniform doubles in the unit interval". Call this value x.
712 // - Given an x in uniformly distributed in [0, 1), we find an exponentially distributed value
713 // by applying the quantile function to it. For the exponential distribution with mean 1 this
714 // is F(x) = -log(1 - x).
715 //
716 // Combining the two, and using log1p(x) = log(1 + x), we obtain the following:
717 return -std::log1p((uniform >> 11) * -0x1.0p-53);
718}
int ret
A hasher class for SHA-256.
Definition: sha256.h:14
A hasher class for SHA-512.
Definition: sha512.h:13
static constexpr size_t OUTPUT_SIZE
Definition: sha512.h:20
CSHA512 & Reset()
Definition: sha512.cpp:202
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha512.cpp:185
CSHA512 & Write(const unsigned char *data, size_t len)
Definition: sha512.cpp:159
void SetKey(std::span< const std::byte > key) noexcept
Set 32-byte key, and seek to nonce 0 and block position 0.
Definition: chacha20.cpp:337
FastRandomContext(bool fDeterministic=false) noexcept
Construct a FastRandomContext with GetRandHash()-based entropy (or zero key if fDeterministic).
Definition: random.cpp:691
ChaCha20 rng
Definition: random.h:380
void RandomSeed() noexcept
Definition: random.cpp:621
void fillrand(std::span< std::byte > output) noexcept
Fill a byte span with random bytes.
Definition: random.cpp:628
void Reseed(const uint256 &seed) noexcept
Reseed with explicit seed (only for testing).
Definition: random.cpp:636
bool requires_seed
Definition: random.h:379
256-bit opaque blob.
Definition: uint256.h:196
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
Definition: cleanse.cpp:14
#define LogError(...)
Definition: logging.h:263
#define LogDebug(category,...)
Definition: logging.h:280
#define LogPrintf(...)
Definition: logging.h:266
@ RAND
Definition: logging.h:56
std::atomic< bool > g_used_g_prng
Definition: random.cpp:601
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:614
void GetStrongRandBytes(std::span< unsigned char > bytes) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
Definition: random.cpp:609
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:643
static constexpr std::array< std::byte, ChaCha20::KEYLEN > ZERO_KEY
Definition: random.cpp:689
void MakeRandDeterministicDANGEROUS(const uint256 &seed) noexcept
Internal function to set g_determinstic_rng.
Definition: random.cpp:597
void RandomInit()
Overall design of the RNG and entropy sources.
Definition: random.cpp:698
void GetRandBytes(std::span< unsigned char > bytes) noexcept
Generate random data via the internal PRNG.
Definition: random.cpp:603
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:619
double MakeExponentiallyDistributed(uint64_t uniform) noexcept
Given a uniformly random uint64_t, return an exponentially distributed double with mean 1.
Definition: random.cpp:706
uint256 GetRandHash() noexcept
Generate a random uint256.
Definition: random.h:454
void RandAddStaticEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that does not change over time.
Definition: randomenv.cpp:267
void RandAddDynamicEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that changes over time.
Definition: randomenv.cpp:188
const char * name
Definition: rest.cpp:49
static RPCHelpMan stop()
Definition: server.cpp:155
auto MakeByteSpan(const V &v) noexcept
Definition: span.h:84
#define LOCK(cs)
Definition: sync.h:257
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
#define GUARDED_BY(x)
Definition: threadsafety.h:38
assert(!tx.IsCoinBase())