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