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