Bitcoin Core  27.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 <config/bitcoin-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(MAC_OSX))
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 
48 namespace {
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  */
55 static 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 
64 inline 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
85 bool g_rdrand_supported = false;
86 bool g_rdseed_supported = false;
87 constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
88 constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
89 #ifdef bit_RDRND
90 static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND, "Unexpected value for bit_RDRND");
91 #endif
92 #ifdef bit_RDSEED
93 static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED, "Unexpected value for bit_RDSEED");
94 #endif
95 
96 void 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 
109 void 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 
125 uint64_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 
160 uint64_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 
194 bool g_rndr_supported = false;
195 
196 void InitHardwareRand()
197 {
198  if (getauxval(AT_HWCAP2) & HWCAP2_RNG) {
199  g_rndr_supported = true;
200  }
201 }
202 
203 void 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 
216 uint64_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 
234 uint64_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  */
254 void InitHardwareRand() {}
255 void ReportHardwareRand() {}
256 #endif
257 
259 void 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 
276 void 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 
309 void 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 
360 void 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(MAC_OSX)
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 
415 class 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 
436 public:
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 
525 RNGState& 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 
538 void SeedTimestamp(CSHA512& hasher) noexcept
539 {
540  int64_t perfcounter = GetPerformanceCounter();
541  hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
542 }
543 
544 void 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 
559 void 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 
581 void 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 
591 void 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 (performance monitoring, ...)
603  auto old_size = hasher.Size();
604  RandAddDynamicEnv(hasher);
605  LogPrint(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 
611 void 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 (performance monitoring, ...)
620  auto old_size = hasher.Size();
621  RandAddDynamicEnv(hasher);
622 
623  // Static environment data
624  RandAddStaticEnv(hasher);
625  LogPrint(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 
631 enum class RNGLevel {
632  FAST,
633  SLOW,
634  PERIODIC,
635 };
636 
637 void 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 
670 void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept
671 {
672  GetRNGState().MakeDeterministic(seed);
673 }
674 
675 void GetRandBytes(Span<unsigned char> bytes) noexcept
676 {
677  ProcRand(bytes.data(), bytes.size(), RNGLevel::FAST, /*always_use_real_rng=*/false);
678 }
679 
681 {
682  ProcRand(bytes.data(), bytes.size(), RNGLevel::SLOW, /*always_use_real_rng=*/true);
683 }
684 
685 void RandAddPeriodic() noexcept
686 {
687  ProcRand(nullptr, 0, RNGLevel::PERIODIC, /*always_use_real_rng=*/false);
688 }
689 
690 void RandAddEvent(const uint32_t event_info) noexcept { GetRNGState().AddEvent(event_info); }
691 
693 {
694  uint256 seed = GetRandHash();
695  rng.SetKey(MakeByteSpan(seed));
696  requires_seed = false;
697 }
698 
700 {
701  if (requires_seed) RandomSeed();
702  rng.Keystream(output);
703 }
704 
705 FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), rng(MakeByteSpan(seed)) {}
706 
707 void FastRandomContext::Reseed(const uint256& seed) noexcept
708 {
709  FlushCache();
710  requires_seed = false;
711  rng = {MakeByteSpan(seed)};
712 }
713 
715 {
716  uint64_t start = GetPerformanceCounter();
717 
718  /* This does not measure the quality of randomness, but it does test that
719  * GetOSRand() overwrites all 32 bytes of the output given a maximum
720  * number of tries.
721  */
722  static constexpr int MAX_TRIES{1024};
723  uint8_t data[NUM_OS_RANDOM_BYTES];
724  bool overwritten[NUM_OS_RANDOM_BYTES] = {}; /* Tracks which bytes have been overwritten at least once */
725  int num_overwritten;
726  int tries = 0;
727  /* Loop until all bytes have been overwritten at least once, or max number tries reached */
728  do {
729  memset(data, 0, NUM_OS_RANDOM_BYTES);
730  GetOSRand(data);
731  for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
732  overwritten[x] |= (data[x] != 0);
733  }
734 
735  num_overwritten = 0;
736  for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
737  if (overwritten[x]) {
738  num_overwritten += 1;
739  }
740  }
741 
742  tries += 1;
743  } while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
744  if (num_overwritten != NUM_OS_RANDOM_BYTES) return false; /* If this failed, bailed out after too many tries */
745 
746  // Check that GetPerformanceCounter increases at least during a GetOSRand() call + 1ms sleep.
747  std::this_thread::sleep_for(std::chrono::milliseconds(1));
748  uint64_t stop = GetPerformanceCounter();
749  if (stop == start) return false;
750 
751  // We called GetPerformanceCounter. Use it as entropy.
752  CSHA512 to_add;
753  to_add.Write((const unsigned char*)&start, sizeof(start));
754  to_add.Write((const unsigned char*)&stop, sizeof(stop));
755  GetRNGState().MixExtract(nullptr, 0, std::move(to_add), false, /*always_use_real_rng=*/true);
756 
757  return true;
758 }
759 
760 static constexpr std::array<std::byte, ChaCha20::KEYLEN> ZERO_KEY{};
761 
762 FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_seed(!fDeterministic), rng(ZERO_KEY)
763 {
764  // Note that despite always initializing with ZERO_KEY, requires_seed is set to true if not
765  // fDeterministic. That means the rng will be reinitialized with a secure random key upon first
766  // use.
767 }
768 
770 {
771  // Invoke RNG code to trigger initialization (if not already performed)
772  ProcRand(nullptr, 0, RNGLevel::FAST, /*always_use_real_rng=*/true);
773 
774  ReportHardwareRand();
775 }
776 
777 double MakeExponentiallyDistributed(uint64_t uniform) noexcept
778 {
779  // To convert uniform into an exponentially-distributed double, we use two steps:
780  // - Convert uniform into a uniformly-distributed double in range [0, 1), use the expression
781  // ((uniform >> 11) * 0x1.0p-53), as described in https://prng.di.unimi.it/ under
782  // "Generating uniform doubles in the unit interval". Call this value x.
783  // - Given an x in uniformly distributed in [0, 1), we find an exponentially distributed value
784  // by applying the quantile function to it. For the exponential distribution with mean 1 this
785  // is F(x) = -log(1 - x).
786  //
787  // Combining the two, and using log1p(x) = log(1 + x), we obtain the following:
788  return -std::log1p((uniform >> 11) * -0x1.0p-53);
789 }
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:762
ChaCha20 rng
Definition: random.h:380
void RandomSeed() noexcept
Definition: random.cpp:692
void Reseed(const uint256 &seed) noexcept
Reseed with explicit seed (only for testing).
Definition: random.cpp:707
bool requires_seed
Definition: random.h:379
void fillrand(Span< std::byte > output) noexcept
Fill a byte Span with random bytes.
Definition: random.cpp:699
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:127
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:263
#define LogError(...)
Definition: logging.h:241
#define LogPrintf(...)
Definition: logging.h:244
@ RAND
Definition: logging.h:54
void GetRandBytes(Span< unsigned char > bytes) noexcept
Generate random data via the internal PRNG.
Definition: random.cpp:675
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:685
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:680
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:714
static constexpr std::array< std::byte, ChaCha20::KEYLEN > ZERO_KEY
Definition: random.cpp:760
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:769
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:690
double MakeExponentiallyDistributed(uint64_t uniform) noexcept
Given a uniformly random uint64_t, return an exponentially distributed double with mean 1.
Definition: random.cpp:777
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:309
void RandAddDynamicEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that changes over time.
Definition: randomenv.cpp:228
const char * name
Definition: rest.cpp:49
static RPCHelpMan stop()
Definition: server.cpp:171
Span< std::byte > AsWritableBytes(Span< T > s) noexcept
Definition: span.h:271
Span< const std::byte > MakeByteSpan(V &&v) noexcept
Definition: span.h:277
#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())