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