Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
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/sha256.h>
14#include <crypto/sha512.h>
15#include <logging.h> // for LogPrintf()
16#include <randomenv.h>
17#include <span.h>
19#include <support/cleanse.h>
20#include <sync.h> // for Mutex
21#include <util/time.h> // for GetTimeMicros()
22
23#include <cmath>
24#include <cstdlib>
25#include <memory>
26#include <thread>
27
28#ifndef WIN32
29#include <fcntl.h>
30#include <sys/time.h>
31#endif
32
33#ifdef HAVE_SYS_GETRANDOM
34#include <linux/random.h>
35#include <sys/syscall.h>
36#endif
37#if defined(HAVE_GETENTROPY) || \
38 (defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX))
39#include <unistd.h>
40#endif
41#if defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
42#include <sys/random.h>
43#endif
44#ifdef HAVE_SYSCTL_ARND
45#include <sys/sysctl.h>
46#endif
47
48[[noreturn]] static void RandFailure() {
49 LogPrintf("Failed to read randomness, aborting\n");
50 std::abort();
51}
52
53static inline int64_t GetPerformanceCounter() noexcept {
54// Read the hardware time stamp counter when available.
55// See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
56#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
57 return __rdtsc();
58#elif !defined(_MSC_VER) && defined(__i386__)
59 uint64_t r = 0;
60 // Constrain the r variable to the eax:edx pair.
61 __asm__ volatile("rdtsc" : "=A"(r));
62 return r;
63#elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
64 uint64_t r1 = 0, r2 = 0;
65 // Constrain r1 to rax and r2 to rdx.
66 __asm__ volatile("rdtsc" : "=a"(r1), "=d"(r2));
67 return (r2 << 32) | r1;
68#else
69 // Fall back to using C++11 clock (usually microsecond or nanosecond
70 // precision)
71 return std::chrono::high_resolution_clock::now().time_since_epoch().count();
72#endif
73}
74
75#ifdef HAVE_GETCPUID
76static bool g_rdrand_supported = false;
77static bool g_rdseed_supported = false;
78static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
79static constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
80#ifdef bit_RDRND
81static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND,
82 "Unexpected value for bit_RDRND");
83#endif
84#ifdef bit_RDSEED
85static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED,
86 "Unexpected value for bit_RDSEED");
87#endif
88
89static void InitHardwareRand() {
91 GetCPUID(1, 0, eax, ebx, ecx, edx);
93 g_rdrand_supported = true;
94 }
95 GetCPUID(7, 0, eax, ebx, ecx, edx);
97 g_rdseed_supported = true;
98 }
99}
100
101static void ReportHardwareRand() {
102 // This must be done in a separate function, as InitHardwareRand() may be
103 // indirectly called from global constructors, before logging is
104 // initialized.
105 if (g_rdseed_supported) {
106 LogPrintf("Using RdSeed as additional entropy source\n");
107 }
108 if (g_rdrand_supported) {
109 LogPrintf("Using RdRand as an additional entropy source\n");
110 }
111}
112
118static uint64_t GetRdRand() noexcept {
119 // RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce
120 // this risk.
121#ifdef __i386__
122 uint8_t ok;
123 // Initialize to 0 to silence a compiler warning that r1 or r2 may be used
124 // uninitialized. Even if rdrand fails (!ok) it will set the output to 0,
125 // but there is no way that the compiler could know that.
126 uint32_t r1 = 0, r2 = 0;
127 for (int i = 0; i < 10; ++i) {
128 // rdrand %eax
129 __asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1"
130 : "=a"(r1), "=q"(ok)::"cc");
131 if (ok) {
132 break;
133 }
134 }
135 for (int i = 0; i < 10; ++i) {
136 // rdrand %eax
137 __asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1"
138 : "=a"(r2), "=q"(ok)::"cc");
139 if (ok) {
140 break;
141 }
142 }
143 return (uint64_t(r2) << 32) | r1;
144#elif defined(__x86_64__) || defined(__amd64__)
145 uint8_t ok;
146 uint64_t r1 = 0; // See above why we initialize to 0.
147 for (int i = 0; i < 10; ++i) {
148 // rdrand %rax
149 __asm__ volatile(".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1"
150 : "=a"(r1), "=q"(ok)::"cc");
151 if (ok) {
152 break;
153 }
154 }
155 return r1;
156#else
157#error "RdRand is only supported on x86 and x86_64"
158#endif
159}
160
166static uint64_t GetRdSeed() noexcept {
167 // RdSeed may fail when the HW RNG is overloaded. Loop indefinitely until
168 // enough entropy is gathered, but pause after every failure.
169#ifdef __i386__
170 uint8_t ok;
171 uint32_t r1, r2;
172 do {
173 // rdseed %eax
174 __asm__ volatile(".byte 0x0f, 0xc7, 0xf8; setc %1"
175 : "=a"(r1), "=q"(ok)::"cc");
176 if (ok) {
177 break;
178 }
179 __asm__ volatile("pause");
180 } while (true);
181 do {
182 // rdseed %eax
183 __asm__ volatile(".byte 0x0f, 0xc7, 0xf8; setc %1"
184 : "=a"(r2), "=q"(ok)::"cc");
185 if (ok) {
186 break;
187 }
188 __asm__ volatile("pause");
189 } while (true);
190 return (uint64_t(r2) << 32) | r1;
191#elif defined(__x86_64__) || defined(__amd64__)
192 uint8_t ok;
193 uint64_t r1;
194 do {
195 // rdseed %rax
196 __asm__ volatile(".byte 0x48, 0x0f, 0xc7, 0xf8; setc %1"
197 : "=a"(r1), "=q"(ok)::"cc");
198 if (ok) {
199 break;
200 }
201 __asm__ volatile("pause");
202 } while (true);
203 return r1;
204#else
205#error "RdSeed is only supported on x86 and x86_64"
206#endif
207}
208
209#else
216static void InitHardwareRand() {}
217static void ReportHardwareRand() {}
218#endif
219
224static void SeedHardwareFast(CSHA512 &hasher) noexcept {
225#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
226 if (g_rdrand_supported) {
227 uint64_t out = GetRdRand();
228 hasher.Write((const uint8_t *)&out, sizeof(out));
229 return;
230 }
231#endif
232}
233
238static void SeedHardwareSlow(CSHA512 &hasher) noexcept {
239#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
240 // When we want 256 bits of entropy, prefer RdSeed over RdRand, as it's
241 // guaranteed to produce independent randomness on every call.
242 if (g_rdseed_supported) {
243 for (int i = 0; i < 4; ++i) {
244 uint64_t out = GetRdSeed();
245 hasher.Write((const uint8_t *)&out, sizeof(out));
246 }
247 return;
248 }
249 // When falling back to RdRand, XOR the result of 1024 results.
250 // This guarantees a reseeding occurs between each.
251 if (g_rdrand_supported) {
252 for (int i = 0; i < 4; ++i) {
253 uint64_t out = 0;
254 for (int j = 0; j < 1024; ++j) {
255 out ^= GetRdRand();
256 }
257 hasher.Write((const uint8_t *)&out, sizeof(out));
258 }
259 return;
260 }
261#endif
262}
263
268static void Strengthen(const uint8_t (&seed)[32], int microseconds,
269 CSHA512 &hasher) noexcept {
271 inner_hasher.Write(seed, sizeof(seed));
272
273 // Hash loop
274 uint8_t buffer[64];
276 do {
277 for (int i = 0; i < 1000; ++i) {
278 inner_hasher.Finalize(buffer);
279 inner_hasher.Reset();
280 inner_hasher.Write(buffer, sizeof(buffer));
281 }
282 // Benchmark operation and feed it into outer hasher.
284 hasher.Write((const uint8_t *)&perf, sizeof(perf));
285 } while (GetTimeMicros() < stop);
286
287 // Produce output from inner state and feed it to outer hasher.
288 inner_hasher.Finalize(buffer);
289 hasher.Write(buffer, sizeof(buffer));
290 // Try to clean up.
291 inner_hasher.Reset();
292 memory_cleanse(buffer, sizeof(buffer));
293}
294
295#ifndef WIN32
301 int f = open("/dev/urandom", O_RDONLY);
302 if (f == -1) {
303 RandFailure();
304 }
305 int have = 0;
306 do {
307 ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
309 close(f);
310 RandFailure();
311 }
312 have += n;
313 } while (have < NUM_OS_RANDOM_BYTES);
314 close(f);
315}
316#endif
317
320#if defined(WIN32)
322 int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL,
324 if (!ret) {
325 RandFailure();
326 }
328 if (!ret) {
329 RandFailure();
330 }
332#elif defined(HAVE_SYS_GETRANDOM)
340 if (rv != NUM_OS_RANDOM_BYTES) {
341 if (rv < 0 && errno == ENOSYS) {
342 /* Fallback for kernel <3.17: the return value will be -1 and errno
343 * ENOSYS if the syscall is not available, in that case fall back
344 * to /dev/urandom.
345 */
347 } else {
348 RandFailure();
349 }
350 }
351#elif defined(HAVE_GETENTROPY) && defined(__OpenBSD__)
360 RandFailure();
361 }
362 // Silence a compiler warning about unused function.
364#elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
369 RandFailure();
370 }
371 // Silence a compiler warning about unused function.
373#elif defined(HAVE_SYSCTL_ARND)
378 static const int name[2] = {CTL_KERN, KERN_ARND};
379 int have = 0;
380 do {
381 size_t len = NUM_OS_RANDOM_BYTES - have;
382 if (sysctl(name, std::size(name), ent32 + have, &len, nullptr, 0) !=
383 0) {
384 RandFailure();
385 }
386 have += len;
387 } while (have < NUM_OS_RANDOM_BYTES);
388 // Silence a compiler warning about unused function.
390#else
396#endif
397}
398
399namespace {
400
401class RNGState {
402 Mutex m_mutex;
412 uint8_t m_state[32] GUARDED_BY(m_mutex) = {0};
413 uint64_t m_counter GUARDED_BY(m_mutex) = 0;
414 bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
415
416 Mutex m_events_mutex;
417 CSHA256 m_events_hasher GUARDED_BY(m_events_mutex);
418
419public:
420 RNGState() noexcept { InitHardwareRand(); }
421
422 ~RNGState() {}
423
424 void AddEvent(uint32_t event_info) noexcept
425 EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex) {
426 LOCK(m_events_mutex);
427
428 m_events_hasher.Write((const uint8_t *)&event_info, sizeof(event_info));
429 // Get the low four bytes of the performance counter. This translates to
430 // roughly the subsecond part.
431 uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
432 m_events_hasher.Write((const uint8_t *)&perfcounter,
433 sizeof(perfcounter));
434 }
435
439 void SeedEvents(CSHA512 &hasher) noexcept
440 EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex) {
441 // We use only SHA256 for the events hashing to get the ASM speedups we
442 // have for SHA256, since we want it to be fast as network peers may be
443 // able to trigger it repeatedly.
444 LOCK(m_events_mutex);
445
448 hasher.Write(events_hash, 32);
449
450 // Re-initialize the hasher with the finalized state to use later.
451 m_events_hasher.Reset();
452 m_events_hasher.Write(events_hash, 32);
453 }
454
462 bool MixExtract(uint8_t *out, size_t num, CSHA512 &&hasher,
463 bool strong_seed) noexcept
464 EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) {
465 assert(num <= 32);
466 uint8_t buf[64];
467 static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE,
468 "Buffer needs to have hasher's output size");
469 bool ret;
470 {
471 LOCK(m_mutex);
473 // Write the current state of the RNG into the hasher
474 hasher.Write(m_state, 32);
475 // Write a new counter number into the state
476 hasher.Write((const uint8_t *)&m_counter, sizeof(m_counter));
477 ++m_counter;
478 // Finalize the hasher
479 hasher.Finalize(buf);
480 // Store the last 32 bytes of the hash output as new RNG state.
481 memcpy(m_state, buf + 32, 32);
482 }
483 // If desired, copy (up to) the first 32 bytes of the hash output as
484 // output.
485 if (num) {
486 assert(out != nullptr);
487 memcpy(out, buf, num);
488 }
489 // Best effort cleanup of internal state
490 hasher.Reset();
491 memory_cleanse(buf, 64);
492 return ret;
493 }
494};
495
496RNGState &GetRNGState() noexcept {
497 // This C++11 idiom relies on the guarantee that static variable are
498 // initialized on first call, even when multiple parallel calls are
499 // permitted.
500 static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
501 return g_rng[0];
502}
503} // namespace
504
511static void SeedTimestamp(CSHA512 &hasher) noexcept {
513 hasher.Write((const uint8_t *)&perfcounter, sizeof(perfcounter));
514}
515
516static void SeedFast(CSHA512 &hasher) noexcept {
517 uint8_t buffer[32];
518
519 // Stack pointer to indirectly commit to thread/callstack
520 const uint8_t *ptr = buffer;
521 hasher.Write((const uint8_t *)&ptr, sizeof(ptr));
522
523 // Hardware randomness is very fast when available; use it always.
524 SeedHardwareFast(hasher);
525
526 // High-precision timestamp
527 SeedTimestamp(hasher);
528}
529
530static void SeedSlow(CSHA512 &hasher, RNGState &rng) noexcept {
531 uint8_t buffer[32];
532
533 // Everything that the 'fast' seeder includes
534 SeedFast(hasher);
535
536 // OS randomness
538 hasher.Write(buffer, sizeof(buffer));
539
540 // Add the events hasher into the mix
541 rng.SeedEvents(hasher);
542
543 // High-precision timestamp.
544 //
545 // Note that we also commit to a timestamp in the Fast seeder, so we
546 // indirectly commit to a benchmark of all the entropy gathering sources in
547 // this function).
548 SeedTimestamp(hasher);
549}
550
552static void SeedStrengthen(CSHA512 &hasher, RNGState &rng,
553 int microseconds) noexcept {
554 // Generate 32 bytes of entropy from the RNG, and a copy of the entropy
555 // already in hasher.
557 rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher),
558 false);
559 // Strengthen the seed, and feed it into hasher.
561}
562
563static void SeedPeriodic(CSHA512 &hasher, RNGState &rng) noexcept {
564 // Everything that the 'fast' seeder includes
565 SeedFast(hasher);
566
567 // High-precision timestamp
568 SeedTimestamp(hasher);
569
570 // Add the events hasher into the mix
571 rng.SeedEvents(hasher);
572
573 // Dynamic environment data (performance monitoring, ...)
574 auto old_size = hasher.Size();
575 RandAddDynamicEnv(hasher);
577 "Feeding %i bytes of dynamic environment data into RNG\n",
578 hasher.Size() - old_size);
579
580 // Strengthen for 10ms
581 SeedStrengthen(hasher, rng, 10000);
582}
583
584static void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept {
585 // Gather 256 bits of hardware randomness, if available
586 SeedHardwareSlow(hasher);
587
588 // Everything that the 'slow' seeder includes.
589 SeedSlow(hasher, rng);
590
591 // Dynamic environment data (performance monitoring, ...)
592 auto old_size = hasher.Size();
593 RandAddDynamicEnv(hasher);
594
595 // Static environment data
596 RandAddStaticEnv(hasher);
597 LogPrint(BCLog::RAND, "Feeding %i bytes of environment data into RNG\n",
598 hasher.Size() - old_size);
599
600 // Strengthen for 100ms
601 SeedStrengthen(hasher, rng, 100000);
602}
603
604enum class RNGLevel {
605 FAST,
606 SLOW,
607 PERIODIC,
608};
609
610static void ProcRand(uint8_t *out, int num, RNGLevel level) noexcept {
611 // Make sure the RNG is initialized first (as all Seed* function possibly
612 // need hwrand to be available).
613 RNGState &rng = GetRNGState();
614
615 assert(num <= 32);
616
617 CSHA512 hasher;
618 switch (level) {
619 case RNGLevel::FAST:
620 SeedFast(hasher);
621 break;
622 case RNGLevel::SLOW:
623 SeedSlow(hasher, rng);
624 break;
626 SeedPeriodic(hasher, rng);
627 break;
628 }
629
630 // Combine with and update state
631 if (!rng.MixExtract(out, num, std::move(hasher), false)) {
632 // On the first invocation, also seed with SeedStartup().
635 rng.MixExtract(out, num, std::move(startup_hasher), true);
636 }
637}
638
639void GetRandBytes(Span<uint8_t> bytes) noexcept {
640 ProcRand(bytes.data(), bytes.size(), RNGLevel::FAST);
641}
642void GetStrongRandBytes(Span<uint8_t> bytes) noexcept {
643 ProcRand(bytes.data(), bytes.size(), RNGLevel::SLOW);
644}
645void RandAddPeriodic() noexcept {
646 ProcRand(nullptr, 0, RNGLevel::PERIODIC);
647}
648
649void RandAddEvent(const uint32_t event_info) noexcept {
650 GetRNGState().AddEvent(event_info);
651}
652
654
658
660 uint256 hash;
661 GetRandBytes(hash);
662 return hash;
663}
664
666 uint256 seed = GetRandHash();
667 rng.SetKey(seed.begin(), 32);
668 requires_seed = false;
669}
670
672 if (bytebuf_size < 20) {
674 }
675 uint160 ret;
676 memcpy(ret.begin(), bytebuf + 64 - bytebuf_size, 20);
677 bytebuf_size -= 20;
678 return ret;
679}
680
682 if (bytebuf_size < 32) {
684 }
685 uint256 ret;
686 memcpy(ret.begin(), bytebuf + 64 - bytebuf_size, 32);
687 bytebuf_size -= 32;
688 return ret;
689}
690std::vector<uint8_t> FastRandomContext::randbytes(size_t len) {
691 if (requires_seed) {
692 RandomSeed();
693 }
694 std::vector<uint8_t> ret(len);
695 if (len > 0) {
696 rng.Keystream(ret.data(), len);
697 }
698 return ret;
699}
700
702 : requires_seed(false), bytebuf_size(0), bitbuf_size(0) {
703 rng.SetKey(seed.begin(), 32);
704}
705
708
714 static const ssize_t MAX_TRIES = 1024;
716 /* Tracks which bytes have been overwritten at least once */
718 int num_overwritten;
719 int tries = 0;
724 do {
725 memset(data, 0, NUM_OS_RANDOM_BYTES);
726 GetOSRand(data);
727 for (int x = 0; x < NUM_OS_RANDOM_BYTES; ++x) {
728 overwritten[x] |= (data[x] != 0);
729 }
730
731 num_overwritten = 0;
732 for (int x = 0; x < NUM_OS_RANDOM_BYTES; ++x) {
733 if (overwritten[x]) {
734 num_overwritten += 1;
735 }
736 }
737
738 tries += 1;
740 /* If this failed, bailed out after too many tries */
742 return false;
743 }
744
745 // Check that GetPerformanceCounter increases at least during a GetOSRand()
746 // call + 1ms sleep.
747 std::this_thread::sleep_for(std::chrono::milliseconds(1));
749 if (stop == start) {
750 return false;
751 }
752
753 // We called GetPerformanceCounter. Use it as entropy.
755 to_add.Write((const uint8_t *)&start, sizeof(start));
756 to_add.Write((const uint8_t *)&stop, sizeof(stop));
757 GetRNGState().MixExtract(nullptr, 0, std::move(to_add), false);
758
759 return true;
760}
761
763 : requires_seed(!fDeterministic), bytebuf_size(0), bitbuf_size(0) {
764 if (!fDeterministic) {
765 return;
766 }
767 uint256 seed;
768 rng.SetKey(seed.begin(), 32);
769}
770
773 requires_seed = from.requires_seed;
774 rng = from.rng;
775 std::copy(std::begin(from.bytebuf), std::end(from.bytebuf),
776 std::begin(bytebuf));
777 bytebuf_size = from.bytebuf_size;
778 bitbuf = from.bitbuf;
779 bitbuf_size = from.bitbuf_size;
780 from.requires_seed = true;
781 from.bytebuf_size = 0;
782 from.bitbuf_size = 0;
783 return *this;
784}
785
787 // Invoke RNG code to trigger initialization (if not already performed)
788 ProcRand(nullptr, 0, RNGLevel::FAST);
789
791}
792
793std::chrono::microseconds
794GetExponentialRand(std::chrono::microseconds now,
795 std::chrono::seconds average_interval) {
796 double unscaled = -std::log1p(GetRand(uint64_t{1} << 48) *
797 -0.0000000000000035527136788 /* -1/2^48 */);
798 return now + std::chrono::duration_cast<std::chrono::microseconds>(
800}
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
void SetKey(const uint8_t *key, size_t keylen)
set key with flexible keylength; 256bit recommended
Definition chacha20.cpp:32
void Keystream(uint8_t *c, size_t bytes)
outputs the keystream of size <bytes> into
Definition chacha20.cpp:79
Fast randomness source.
Definition random.h:156
uint160 rand160() noexcept
generate a random uint160.
Definition random.cpp:671
std::vector< uint8_t > randbytes(size_t len)
Generate random bytes.
Definition random.cpp:690
FastRandomContext(bool fDeterministic=false) noexcept
Definition random.cpp:762
uint256 rand256() noexcept
generate a random uint256.
Definition random.cpp:681
ChaCha20 rng
Definition random.h:159
uint8_t bytebuf[64]
Definition random.h:161
FastRandomContext & operator=(const FastRandomContext &)=delete
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition random.h:231
void FillByteBuffer()
Definition random.h:169
A Span is an object that can refer to a contiguous sequence of objects.
Definition span.h:93
uint8_t * begin()
Definition uint256.h:85
160-bit opaque blob.
Definition uint256.h:117
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:238
#define LogPrintf(...)
Definition logging.h:227
@ RAND
Definition logging.h:53
std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval)
Return a timestamp in the future sampled from an exponential distribution (https://en....
Definition random.cpp:794
static void ReportHardwareRand()
Definition random.cpp:217
void GetRandBytes(Span< uint8_t > bytes) noexcept
Overall design of the RNG and entropy sources.
Definition random.cpp:639
static void SeedStrengthen(CSHA512 &hasher, RNGState &rng, int microseconds) noexcept
Extract entropy from rng, strengthen it, and feed it into hasher.
Definition random.cpp:552
static void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept
Definition random.cpp:584
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition random.cpp:645
bool g_mock_deterministic_tests
Definition random.cpp:653
static void SeedFast(CSHA512 &hasher) noexcept
Definition random.cpp:516
static void GetDevURandom(uint8_t *ent32)
Fallback: get 32 bytes of system entropy from /dev/urandom.
Definition random.cpp:300
static void InitHardwareRand()
Access to other hardware random number generators could be added here later, assuming it is sufficien...
Definition random.cpp:216
static void SeedHardwareFast(CSHA512 &hasher) noexcept
Add 64 bits of entropy gathered from hardware to hasher.
Definition random.cpp:224
uint64_t GetRandInternal(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
Definition random.cpp:655
void GetOSRand(uint8_t *ent32)
Get 32 bytes of system entropy.
Definition random.cpp:319
static void SeedTimestamp(CSHA512 &hasher) noexcept
A note on the use of noexcept in the seeding functions below:
Definition random.cpp:511
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition random.cpp:706
static void Strengthen(const uint8_t(&seed)[32], int microseconds, CSHA512 &hasher) noexcept
Use repeated SHA512 to strengthen the randomness in seed32, and feed into hasher.
Definition random.cpp:268
uint256 GetRandHash() noexcept
Definition random.cpp:659
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition random.cpp:786
static void SeedPeriodic(CSHA512 &hasher, RNGState &rng) noexcept
Definition random.cpp:563
static void ProcRand(uint8_t *out, int num, RNGLevel level) noexcept
Definition random.cpp:610
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition random.cpp:649
static void RandFailure()
Definition random.cpp:48
RNGLevel
Definition random.cpp:604
@ SLOW
Automatically called by GetStrongRandBytes.
@ PERIODIC
Called by RandAddPeriodic()
@ FAST
Automatically called by GetRandBytes.
static void SeedHardwareSlow(CSHA512 &hasher) noexcept
Add 256 bits of entropy gathered from hardware to hasher.
Definition random.cpp:238
static int64_t GetPerformanceCounter() noexcept
Definition random.cpp:53
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:642
static void SeedSlow(CSHA512 &hasher, RNGState &rng) noexcept
Definition random.cpp:530
uint256 GetRandHash() noexcept
Definition random.cpp:659
static const int NUM_OS_RANDOM_BYTES
Number of random bytes returned by GetOSRand.
Definition random.h:308
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
void RandAddStaticEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that does not change over time.
void RandAddDynamicEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that changes over time.
const char * name
Definition rest.cpp:47
static RPCHelpMan stop()
Definition server.cpp:211
#define LOCK(cs)
Definition sync.h:306
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define GUARDED_BY(x)
int64_t GetTimeMicros()
Returns the system time (not mockable)
Definition time.cpp:105
assert(!tx.IsCoinBase())