Bitcoin ABC 0.32.5
P2P Digital Currency
random.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2016 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 <random.h>
7
8#ifdef WIN32
9#include <compat.h> // for Windows API
10#include <wincrypt.h>
11#endif
12#include <compat/cpuid.h>
13#include <crypto/chacha20.h>
14#include <crypto/sha256.h>
15#include <crypto/sha512.h>
16#include <logging.h> // for LogPrintf()
17#include <randomenv.h>
18#include <span.h>
20#include <support/cleanse.h>
21#include <sync.h> // for Mutex
22#include <util/time.h> // for GetTimeMicros()
23
24#include <array>
25#include <cmath>
26#include <cstdlib>
27#include <memory>
28#include <optional>
29#include <thread>
30
31#ifndef WIN32
32#include <fcntl.h>
33#include <sys/time.h>
34#endif
35
36#ifdef HAVE_SYS_GETRANDOM
37#include <linux/random.h>
38#include <sys/syscall.h>
39#endif
40#if defined(HAVE_GETENTROPY) || \
41 (defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX))
42#include <unistd.h>
43#endif
44#if defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
45#include <sys/random.h>
46#endif
47#ifdef HAVE_SYSCTL_ARND
48#include <sys/sysctl.h>
49#endif
50
51namespace {
52
59const int NUM_OS_RANDOM_BYTES = 32;
60
61[[noreturn]] void RandFailure() {
62 LogError("Failed to read randomness, aborting\n");
63 std::abort();
64}
65
66inline int64_t GetPerformanceCounter() noexcept {
67// Read the hardware time stamp counter when available.
68// See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
69#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
70 return __rdtsc();
71#elif !defined(_MSC_VER) && defined(__i386__)
72 uint64_t r = 0;
73 // Constrain the r variable to the eax:edx pair.
74 __asm__ volatile("rdtsc" : "=A"(r));
75 return r;
76#elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
77 uint64_t r1 = 0, r2 = 0;
78 // Constrain r1 to rax and r2 to rdx.
79 __asm__ volatile("rdtsc" : "=a"(r1), "=d"(r2));
80 return (r2 << 32) | r1;
81#else
82 // Fall back to using C++11 clock (usually microsecond or nanosecond
83 // precision)
84 return std::chrono::high_resolution_clock::now().time_since_epoch().count();
85#endif
86}
87
88#ifdef HAVE_GETCPUID
89bool g_rdrand_supported = false;
90bool g_rdseed_supported = false;
91constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
92constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
93#ifdef bit_RDRND
94static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND,
95 "Unexpected value for bit_RDRND");
96#endif
97#ifdef bit_RDSEED
98static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED,
99 "Unexpected value for bit_RDSEED");
100#endif
101
102void InitHardwareRand() {
103 uint32_t eax, ebx, ecx, edx;
104 GetCPUID(1, 0, eax, ebx, ecx, edx);
105 if (ecx & CPUID_F1_ECX_RDRAND) {
106 g_rdrand_supported = true;
107 }
108 GetCPUID(7, 0, eax, ebx, ecx, edx);
109 if (ebx & CPUID_F7_EBX_RDSEED) {
110 g_rdseed_supported = true;
111 }
112}
113
114void ReportHardwareRand() {
115 // This must be done in a separate function, as InitHardwareRand() may be
116 // indirectly called from global constructors, before logging is
117 // initialized.
118 if (g_rdseed_supported) {
119 LogPrintf("Using RdSeed as additional entropy source\n");
120 }
121 if (g_rdrand_supported) {
122 LogPrintf("Using RdRand as an additional entropy source\n");
123 }
124}
125
131uint64_t GetRdRand() noexcept {
132 // RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce
133 // this risk.
134#ifdef __i386__
135 uint8_t ok;
136 // Initialize to 0 to silence a compiler warning that r1 or r2 may be used
137 // uninitialized. Even if rdrand fails (!ok) it will set the output to 0,
138 // but there is no way that the compiler could know that.
139 uint32_t r1 = 0, r2 = 0;
140 for (int i = 0; i < 10; ++i) {
141 // rdrand %eax
142 __asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1"
143 : "=a"(r1), "=q"(ok)::"cc");
144 if (ok) {
145 break;
146 }
147 }
148 for (int i = 0; i < 10; ++i) {
149 // rdrand %eax
150 __asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1"
151 : "=a"(r2), "=q"(ok)::"cc");
152 if (ok) {
153 break;
154 }
155 }
156 return (uint64_t(r2) << 32) | r1;
157#elif defined(__x86_64__) || defined(__amd64__)
158 uint8_t ok;
159 uint64_t r1 = 0; // See above why we initialize to 0.
160 for (int i = 0; i < 10; ++i) {
161 // rdrand %rax
162 __asm__ volatile(".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1"
163 : "=a"(r1), "=q"(ok)::"cc");
164 if (ok) {
165 break;
166 }
167 }
168 return r1;
169#else
170#error "RdRand is only supported on x86 and x86_64"
171#endif
172}
173
179uint64_t GetRdSeed() noexcept {
180 // RdSeed may fail when the HW RNG is overloaded. Loop indefinitely until
181 // enough entropy is gathered, but pause after every failure.
182#ifdef __i386__
183 uint8_t ok;
184 uint32_t r1, r2;
185 do {
186 // rdseed %eax
187 __asm__ volatile(".byte 0x0f, 0xc7, 0xf8; setc %1"
188 : "=a"(r1), "=q"(ok)::"cc");
189 if (ok) {
190 break;
191 }
192 __asm__ volatile("pause");
193 } while (true);
194 do {
195 // rdseed %eax
196 __asm__ volatile(".byte 0x0f, 0xc7, 0xf8; setc %1"
197 : "=a"(r2), "=q"(ok)::"cc");
198 if (ok) {
199 break;
200 }
201 __asm__ volatile("pause");
202 } while (true);
203 return (uint64_t(r2) << 32) | r1;
204#elif defined(__x86_64__) || defined(__amd64__)
205 uint8_t ok;
206 uint64_t r1;
207 do {
208 // rdseed %rax
209 __asm__ volatile(".byte 0x48, 0x0f, 0xc7, 0xf8; setc %1"
210 : "=a"(r1), "=q"(ok)::"cc");
211 if (ok) {
212 break;
213 }
214 __asm__ volatile("pause");
215 } while (true);
216 return r1;
217#else
218#error "RdSeed is only supported on x86 and x86_64"
219#endif
220}
221
222#else
229void InitHardwareRand() {}
230void ReportHardwareRand() {}
231#endif
232
237void SeedHardwareFast(CSHA512 &hasher) noexcept {
238#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
239 if (g_rdrand_supported) {
240 uint64_t out = GetRdRand();
241 hasher.Write((const uint8_t *)&out, sizeof(out));
242 return;
243 }
244#endif
245}
246
251void SeedHardwareSlow(CSHA512 &hasher) noexcept {
252#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
253 // When we want 256 bits of entropy, prefer RdSeed over RdRand, as it's
254 // guaranteed to produce independent randomness on every call.
255 if (g_rdseed_supported) {
256 for (int i = 0; i < 4; ++i) {
257 uint64_t out = GetRdSeed();
258 hasher.Write((const uint8_t *)&out, sizeof(out));
259 }
260 return;
261 }
262 // When falling back to RdRand, XOR the result of 1024 results.
263 // This guarantees a reseeding occurs between each.
264 if (g_rdrand_supported) {
265 for (int i = 0; i < 4; ++i) {
266 uint64_t out = 0;
267 for (int j = 0; j < 1024; ++j) {
268 out ^= GetRdRand();
269 }
270 hasher.Write((const uint8_t *)&out, sizeof(out));
271 }
272 return;
273 }
274#endif
275}
276
281void Strengthen(const uint8_t (&seed)[32], SteadyClock::duration dur,
282 CSHA512 &hasher) noexcept {
283 CSHA512 inner_hasher;
284 inner_hasher.Write(seed, sizeof(seed));
285
286 // Hash loop
287 uint8_t buffer[64];
288
289 const auto stop{SteadyClock::now() + dur};
290 do {
291 for (int i = 0; i < 1000; ++i) {
292 inner_hasher.Finalize(buffer);
293 inner_hasher.Reset();
294 inner_hasher.Write(buffer, sizeof(buffer));
295 }
296 // Benchmark operation and feed it into outer hasher.
297 int64_t perf = GetPerformanceCounter();
298 hasher.Write((const uint8_t *)&perf, sizeof(perf));
299 } while (SteadyClock::now() < stop);
300
301 // Produce output from inner state and feed it to outer hasher.
302 inner_hasher.Finalize(buffer);
303 hasher.Write(buffer, sizeof(buffer));
304 // Try to clean up.
305 inner_hasher.Reset();
306 memory_cleanse(buffer, sizeof(buffer));
307}
308
309#ifndef WIN32
314void GetDevURandom(uint8_t *ent32) {
315 int f = open("/dev/urandom", O_RDONLY);
316 if (f == -1) {
317 RandFailure();
318 }
319 int have = 0;
320 do {
321 ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
322 if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
323 close(f);
324 RandFailure();
325 }
326 have += n;
327 } while (have < NUM_OS_RANDOM_BYTES);
328 close(f);
329}
330#endif
331
333void GetOSRand(uint8_t *ent32) {
334#if defined(WIN32)
335 HCRYPTPROV hProvider;
336 int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL,
337 CRYPT_VERIFYCONTEXT);
338 if (!ret) {
339 RandFailure();
340 }
341 ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32);
342 if (!ret) {
343 RandFailure();
344 }
345 CryptReleaseContext(hProvider, 0);
346#elif defined(HAVE_SYS_GETRANDOM)
353 int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0);
354 if (rv != NUM_OS_RANDOM_BYTES) {
355 if (rv < 0 && errno == ENOSYS) {
356 /* Fallback for kernel <3.17: the return value will be -1 and errno
357 * ENOSYS if the syscall is not available, in that case fall back
358 * to /dev/urandom.
359 */
360 GetDevURandom(ent32);
361 } else {
362 RandFailure();
363 }
364 }
365#elif defined(HAVE_GETENTROPY) && defined(__OpenBSD__)
373 if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
374 RandFailure();
375 }
376 // Silence a compiler warning about unused function.
377 (void)GetDevURandom;
378#elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
382 if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
383 RandFailure();
384 }
385 // Silence a compiler warning about unused function.
386 (void)GetDevURandom;
387#elif defined(HAVE_SYSCTL_ARND)
392 static const int name[2] = {CTL_KERN, KERN_ARND};
393 int have = 0;
394 do {
395 size_t len = NUM_OS_RANDOM_BYTES - have;
396 if (sysctl(name, std::size(name), ent32 + have, &len, nullptr, 0) !=
397 0) {
398 RandFailure();
399 }
400 have += len;
401 } while (have < NUM_OS_RANDOM_BYTES);
402 // Silence a compiler warning about unused function.
403 (void)GetDevURandom;
404#else
409 GetDevURandom(ent32);
410#endif
411}
412
413class RNGState {
414 Mutex m_mutex;
424 uint8_t m_state[32] GUARDED_BY(m_mutex) = {0};
425 uint64_t m_counter GUARDED_BY(m_mutex) = 0;
426 bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
427
432 std::optional<ChaCha20> m_deterministic_prng GUARDED_BY(m_mutex);
433
434 Mutex m_events_mutex;
435 CSHA256 m_events_hasher GUARDED_BY(m_events_mutex);
436
437public:
438 RNGState() noexcept { InitHardwareRand(); }
439
440 ~RNGState() = default;
441
442 void AddEvent(uint32_t event_info) noexcept
443 EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex) {
444 LOCK(m_events_mutex);
445
446 m_events_hasher.Write((const uint8_t *)&event_info, sizeof(event_info));
447 // Get the low four bytes of the performance counter. This translates to
448 // roughly the subsecond part.
449 uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
450 m_events_hasher.Write((const uint8_t *)&perfcounter,
451 sizeof(perfcounter));
452 }
453
457 void SeedEvents(CSHA512 &hasher) noexcept
458 EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex) {
459 // We use only SHA256 for the events hashing to get the ASM speedups we
460 // have for SHA256, since we want it to be fast as network peers may be
461 // able to trigger it repeatedly.
462 LOCK(m_events_mutex);
463
464 uint8_t events_hash[32];
465 m_events_hasher.Finalize(events_hash);
466 hasher.Write(events_hash, 32);
467
468 // Re-initialize the hasher with the finalized state to use later.
469 m_events_hasher.Reset();
470 m_events_hasher.Write(events_hash, 32);
471 }
472
477 void MakeDeterministic(const uint256 &seed) noexcept
478 EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) {
479 LOCK(m_mutex);
480 m_deterministic_prng.emplace(MakeByteSpan(seed));
481 }
492 bool MixExtract(uint8_t *out, size_t num, CSHA512 &&hasher,
493 bool strong_seed, bool always_use_real_rng) noexcept
494 EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) {
495 assert(num <= 32);
496 uint8_t buf[64];
497 static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE,
498 "Buffer needs to have hasher's output size");
499 bool ret;
500 {
501 LOCK(m_mutex);
502 ret = (m_strongly_seeded |= strong_seed);
503 // Write the current state of the RNG into the hasher
504 hasher.Write(m_state, 32);
505 // Write a new counter number into the state
506 hasher.Write((const uint8_t *)&m_counter, sizeof(m_counter));
507 ++m_counter;
508 // Finalize the hasher
509 hasher.Finalize(buf);
510 // Store the last 32 bytes of the hash output as new RNG state.
511 memcpy(m_state, buf + 32, 32);
512 // Handle requests for deterministic randomness.
513 if (!always_use_real_rng && m_deterministic_prng.has_value())
514 [[unlikely]] {
515 // Overwrite the beginning of buf, which will be used for
516 // output.
517 m_deterministic_prng->Keystream(
518 AsWritableBytes(Span{buf, num}));
519 // Do not require strong seeding for deterministic output.
520 ret = true;
521 }
522 }
523 // If desired, copy (up to) the first 32 bytes of the hash output as
524 // output.
525 if (num) {
526 assert(out != nullptr);
527 memcpy(out, buf, num);
528 }
529 // Best effort cleanup of internal state
530 hasher.Reset();
531 memory_cleanse(buf, 64);
532 return ret;
533 }
534};
535
536RNGState &GetRNGState() noexcept {
537 // This C++11 idiom relies on the guarantee that static variable are
538 // initialized on first call, even when multiple parallel calls are
539 // permitted.
540 static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
541 return g_rng[0];
542}
543
550void SeedTimestamp(CSHA512 &hasher) noexcept {
551 int64_t perfcounter = GetPerformanceCounter();
552 hasher.Write((const uint8_t *)&perfcounter, sizeof(perfcounter));
553}
554
555void SeedFast(CSHA512 &hasher) noexcept {
556 uint8_t buffer[32];
557
558 // Stack pointer to indirectly commit to thread/callstack
559 const uint8_t *ptr = buffer;
560 hasher.Write((const uint8_t *)&ptr, sizeof(ptr));
561
562 // Hardware randomness is very fast when available; use it always.
563 SeedHardwareFast(hasher);
564
565 // High-precision timestamp
566 SeedTimestamp(hasher);
567}
568
569void SeedSlow(CSHA512 &hasher, RNGState &rng) noexcept {
570 uint8_t buffer[32];
571
572 // Everything that the 'fast' seeder includes
573 SeedFast(hasher);
574
575 // OS randomness
576 GetOSRand(buffer);
577 hasher.Write(buffer, sizeof(buffer));
578
579 // Add the events hasher into the mix
580 rng.SeedEvents(hasher);
581
582 // High-precision timestamp.
583 //
584 // Note that we also commit to a timestamp in the Fast seeder, so we
585 // indirectly commit to a benchmark of all the entropy gathering sources in
586 // this function).
587 SeedTimestamp(hasher);
588}
589
591void SeedStrengthen(CSHA512 &hasher, RNGState &rng,
592 SteadyClock::duration dur) noexcept {
593 // Generate 32 bytes of entropy from the RNG, and a copy of the entropy
594 // already in hasher.
595 // Never use the deterministic PRNG for this, as the result is only used
596 // internally.
597 uint8_t strengthen_seed[32];
598 rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher),
599 false, /*always_use_real_rng=*/true);
600 // Strengthen the seed, and feed it into hasher.
601 Strengthen(strengthen_seed, dur, hasher);
602}
603
604void SeedPeriodic(CSHA512 &hasher, RNGState &rng) noexcept {
605 // Everything that the 'fast' seeder includes
606 SeedFast(hasher);
607
608 // High-precision timestamp
609 SeedTimestamp(hasher);
610
611 // Add the events hasher into the mix
612 rng.SeedEvents(hasher);
613
614 // Dynamic environment data (performance monitoring, ...)
615 auto old_size = hasher.Size();
616 RandAddDynamicEnv(hasher);
618 "Feeding %i bytes of dynamic environment data into RNG\n",
619 hasher.Size() - old_size);
620
621 // Strengthen for 10 ms
622 SeedStrengthen(hasher, rng, 10ms);
623}
624
625void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept {
626 // Gather 256 bits of hardware randomness, if available
627 SeedHardwareSlow(hasher);
628
629 // Everything that the 'slow' seeder includes.
630 SeedSlow(hasher, rng);
631
632 // Dynamic environment data (performance monitoring, ...)
633 auto old_size = hasher.Size();
634 RandAddDynamicEnv(hasher);
635
636 // Static environment data
637 RandAddStaticEnv(hasher);
638 LogPrint(BCLog::RAND, "Feeding %i bytes of environment data into RNG\n",
639 hasher.Size() - old_size);
640
641 // Strengthen for 100 ms
642 SeedStrengthen(hasher, rng, 100ms);
643}
644
645enum class RNGLevel {
646 FAST,
647 SLOW,
648 PERIODIC,
649};
650
651void ProcRand(uint8_t *out, int num, RNGLevel level,
652 bool always_use_real_rng) noexcept {
653 // Make sure the RNG is initialized first (as all Seed* function possibly
654 // need hwrand to be available).
655 RNGState &rng = GetRNGState();
656
657 assert(num <= 32);
658
659 CSHA512 hasher;
660 switch (level) {
661 case RNGLevel::FAST:
662 SeedFast(hasher);
663 break;
664 case RNGLevel::SLOW:
665 SeedSlow(hasher, rng);
666 break;
667 case RNGLevel::PERIODIC:
668 SeedPeriodic(hasher, rng);
669 break;
670 }
671
672 // Combine with and update state
673 if (!rng.MixExtract(out, num, std::move(hasher), false,
674 always_use_real_rng)) {
675 // On the first invocation, also seed with SeedStartup().
676 CSHA512 startup_hasher;
677 SeedStartup(startup_hasher, rng);
678 rng.MixExtract(out, num, std::move(startup_hasher), true,
679 always_use_real_rng);
680 }
681}
682
683} // namespace
684
686void MakeRandDeterministicDANGEROUS(const uint256 &seed) noexcept {
687 GetRNGState().MakeDeterministic(seed);
688}
689
690void GetRandBytes(Span<uint8_t> bytes) noexcept {
691 ProcRand(bytes.data(), bytes.size(), RNGLevel::FAST,
692 /*always_use_real_rng=*/false);
693}
694
695void GetStrongRandBytes(Span<uint8_t> bytes) noexcept {
696 ProcRand(bytes.data(), bytes.size(), RNGLevel::SLOW,
697 /*always_use_real_rng=*/true);
698}
699
700void RandAddPeriodic() noexcept {
701 ProcRand(nullptr, 0, RNGLevel::PERIODIC, /*always_use_real_rng=*/false);
702}
703
704void RandAddEvent(const uint32_t event_info) noexcept {
705 GetRNGState().AddEvent(event_info);
706}
707
709 uint256 seed = GetRandHash();
710 rng.SetKey(MakeByteSpan(seed));
711 requires_seed = false;
712}
713
715 if (requires_seed) {
716 RandomSeed();
717 }
718 rng.Keystream(output);
719}
720
722 : requires_seed(false), rng(MakeByteSpan(seed)) {}
723
724void FastRandomContext::Reseed(const uint256 &seed) noexcept {
725 FlushCache();
726 requires_seed = false;
727 rng = {MakeByteSpan(seed)};
728}
729
731 uint64_t start = GetPerformanceCounter();
732
738 static const ssize_t MAX_TRIES = 1024;
739 uint8_t data[NUM_OS_RANDOM_BYTES];
740 /* Tracks which bytes have been overwritten at least once */
741 bool overwritten[NUM_OS_RANDOM_BYTES] = {};
742 int num_overwritten;
743 int tries = 0;
748 do {
749 memset(data, 0, NUM_OS_RANDOM_BYTES);
750 GetOSRand(data);
751 for (int x = 0; x < NUM_OS_RANDOM_BYTES; ++x) {
752 overwritten[x] |= (data[x] != 0);
753 }
754
755 num_overwritten = 0;
756 for (int x = 0; x < NUM_OS_RANDOM_BYTES; ++x) {
757 if (overwritten[x]) {
758 num_overwritten += 1;
759 }
760 }
761
762 tries += 1;
763 } while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
764 /* If this failed, bailed out after too many tries */
765 if (num_overwritten != NUM_OS_RANDOM_BYTES) {
766 return false;
767 }
768
769 // Check that GetPerformanceCounter increases at least during a GetOSRand()
770 // call + 1ms sleep.
771 std::this_thread::sleep_for(std::chrono::milliseconds(1));
772 uint64_t stop = GetPerformanceCounter();
773 if (stop == start) {
774 return false;
775 }
776
777 // We called GetPerformanceCounter. Use it as entropy.
778 CSHA512 to_add;
779 to_add.Write((const uint8_t *)&start, sizeof(start));
780 to_add.Write((const uint8_t *)&stop, sizeof(stop));
781 GetRNGState().MixExtract(nullptr, 0, std::move(to_add), false,
782 /*always_use_real_rng=*/true);
783
784 return true;
785}
786
787static constexpr std::array<std::byte, ChaCha20::KEYLEN> ZERO_KEY{};
788
789FastRandomContext::FastRandomContext(bool fDeterministic) noexcept
790 : requires_seed(!fDeterministic), rng(ZERO_KEY) {
791 // Note that despite always initializing with ZERO_KEY, requires_seed is set
792 // to true if not fDeterministic. That means the rng will be reinitialized
793 // with a secure random key upon first use.
794}
795
797 // Invoke RNG code to trigger initialization (if not already performed)
798 ProcRand(nullptr, 0, RNGLevel::FAST, /*always_use_real_rng=*/true);
799
800 ReportHardwareRand();
801}
802
803double MakeExponentiallyDistributed(uint64_t uniform) noexcept {
804 // To convert uniform into an exponentially-distributed double, we use two
805 // steps:
806 // - Convert uniform into a uniformly-distributed double in range [0, 1),
807 // use the expression ((uniform >> 11) * 0x1.0p-53), as described in
808 // https://prng.di.unimi.it/ under "Generating uniform doubles in the unit
809 // interval". Call this value x.
810 // - Given an x in uniformly distributed in [0, 1), we find an exponentially
811 // distributed value by applying the quantile function to it. For the
812 // exponential distribution with mean 1 this is F(x) = -log(1 - x).
813 //
814 // Combining the two, and using log1p(x) = log(1 + x), we obtain the
815 // following:
816 return -std::log1p((uniform >> 11) * -0x1.0p-53);
817}
A hasher class for SHA-256.
Definition: sha256.h:13
A hasher class for SHA-512.
Definition: sha512.h:12
CSHA512 & Write(const uint8_t *data, size_t len)
Definition: sha512.cpp:248
static constexpr size_t OUTPUT_SIZE
Definition: sha512.h:19
CSHA512 & Reset()
Definition: sha512.cpp:289
void Finalize(uint8_t hash[OUTPUT_SIZE])
Definition: sha512.cpp:273
void SetKey(Span< const std::byte > key) noexcept
Set KEYLEN-byte key, and seek to nonce 0 and block position 0.
Definition: chacha20.cpp:357
FastRandomContext(bool fDeterministic=false) noexcept
Construct a FastRandomContext with GetRandHash()-based entropy (or zero key if fDeterministic).
Definition: random.cpp:789
ChaCha20 rng
Definition: random.h:414
void RandomSeed() noexcept
Definition: random.cpp:708
void Reseed(const uint256 &seed) noexcept
Reseed with explicit seed (only for testing).
Definition: random.cpp:724
bool requires_seed
Definition: random.h:413
void fillrand(Span< std::byte > output) noexcept
Fill a byte Span with random bytes.
Definition: random.cpp:714
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:94
256-bit opaque blob.
Definition: uint256.h:129
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
Definition: cleanse.cpp:14
#define LogPrint(category,...)
Definition: logging.h:452
#define LogError(...)
Definition: logging.h:419
#define LogPrintf(...)
Definition: logging.h:424
@ RAND
Definition: logging.h:82
void GetRandBytes(Span< uint8_t > bytes) noexcept
================== BASE RANDOMNESS GENERATION FUNCTIONS ====================
Definition: random.cpp:690
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:700
bool Random_SanityCheck()
=============== MISCELLANEOUS TEST-ONLY FUNCTIONS ======================
Definition: random.cpp:730
static constexpr std::array< std::byte, ChaCha20::KEYLEN > ZERO_KEY
Definition: random.cpp:787
void MakeRandDeterministicDANGEROUS(const uint256 &seed) noexcept
Internal function to set g_determinstic_rng.
Definition: random.cpp:686
void RandomInit()
Overall design of the RNG and entropy sources.
Definition: random.cpp:796
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:704
double MakeExponentiallyDistributed(uint64_t uniform) noexcept
Given a uniformly random uint64_t, return an exponentially distributed double with mean 1.
Definition: random.cpp:803
void GetStrongRandBytes(Span< uint8_t > bytes) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
Definition: random.cpp:695
uint256 GetRandHash() noexcept
========== CONVENIENCE FUNCTIONS FOR COMMONLY USED RANDOMNESS ==========
Definition: random.h:494
void RandAddStaticEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that does not change over time.
Definition: randomenv.cpp:341
void RandAddDynamicEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that changes over time.
Definition: randomenv.cpp:257
const char * name
Definition: rest.cpp:47
static RPCHelpMan stop()
Definition: server.cpp:212
Span< std::byte > AsWritableBytes(Span< T > s) noexcept
Definition: span.h:298
Span< const std::byte > MakeByteSpan(V &&v) noexcept
Definition: span.h:302
#define LOCK(cs)
Definition: sync.h:306
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56
#define GUARDED_BY(x)
Definition: threadsafety.h:45
assert(!tx.IsCoinBase())