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