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