Bitcoin ABC  0.26.3
P2P Digital Currency
random.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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 #ifdef WIN32
9 #include <compat.h> // for Windows API
10 #include <wincrypt.h>
11 #endif
12 #include <compat/cpuid.h>
13 #include <crypto/sha256.h>
14 #include <crypto/sha512.h>
15 #include <logging.h> // for LogPrintf()
16 #include <randomenv.h>
17 #include <span.h>
19 #include <support/cleanse.h>
20 #include <sync.h> // for Mutex
21 #include <util/time.h> // for GetTimeMicros()
22 
23 #include <cmath>
24 #include <cstdlib>
25 #include <memory>
26 #include <thread>
27 
28 #ifndef WIN32
29 #include <fcntl.h>
30 #include <sys/time.h>
31 #endif
32 
33 #ifdef HAVE_SYS_GETRANDOM
34 #include <linux/random.h>
35 #include <sys/syscall.h>
36 #endif
37 #if defined(HAVE_GETENTROPY) || \
38  (defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX))
39 #include <unistd.h>
40 #endif
41 #if defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
42 #include <sys/random.h>
43 #endif
44 #ifdef HAVE_SYSCTL_ARND
45 #include <sys/sysctl.h>
46 #endif
47 
48 [[noreturn]] static void RandFailure() {
49  LogPrintf("Failed to read randomness, aborting\n");
50  std::abort();
51 }
52 
53 static inline int64_t GetPerformanceCounter() noexcept {
54 // Read the hardware time stamp counter when available.
55 // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
56 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
57  return __rdtsc();
58 #elif !defined(_MSC_VER) && defined(__i386__)
59  uint64_t r = 0;
60  // Constrain the r variable to the eax:edx pair.
61  __asm__ volatile("rdtsc" : "=A"(r));
62  return r;
63 #elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
64  uint64_t r1 = 0, r2 = 0;
65  // Constrain r1 to rax and r2 to rdx.
66  __asm__ volatile("rdtsc" : "=a"(r1), "=d"(r2));
67  return (r2 << 32) | r1;
68 #else
69  // Fall back to using C++11 clock (usually microsecond or nanosecond
70  // precision)
71  return std::chrono::high_resolution_clock::now().time_since_epoch().count();
72 #endif
73 }
74 
75 #ifdef HAVE_GETCPUID
76 static bool g_rdrand_supported = false;
77 static bool g_rdseed_supported = false;
78 static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
79 static constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
80 #ifdef bit_RDRND
81 static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND,
82  "Unexpected value for bit_RDRND");
83 #endif
84 #ifdef bit_RDSEED
85 static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED,
86  "Unexpected value for bit_RDSEED");
87 #endif
88 
89 static void InitHardwareRand() {
90  uint32_t eax, ebx, ecx, edx;
91  GetCPUID(1, 0, eax, ebx, ecx, edx);
92  if (ecx & CPUID_F1_ECX_RDRAND) {
93  g_rdrand_supported = true;
94  }
95  GetCPUID(7, 0, eax, ebx, ecx, edx);
96  if (ebx & CPUID_F7_EBX_RDSEED) {
97  g_rdseed_supported = true;
98  }
99 }
100 
101 static void ReportHardwareRand() {
102  // This must be done in a separate function, as InitHardwareRand() may be
103  // indirectly called from global constructors, before logging is
104  // initialized.
105  if (g_rdseed_supported) {
106  LogPrintf("Using RdSeed as additional entropy source\n");
107  }
108  if (g_rdrand_supported) {
109  LogPrintf("Using RdRand as an additional entropy source\n");
110  }
111 }
112 
118 static uint64_t GetRdRand() noexcept {
119  // RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce
120  // this risk.
121 #ifdef __i386__
122  uint8_t ok;
123  // Initialize to 0 to silence a compiler warning that r1 or r2 may be used
124  // uninitialized. Even if rdrand fails (!ok) it will set the output to 0,
125  // but there is no way that the compiler could know that.
126  uint32_t r1 = 0, r2 = 0;
127  for (int i = 0; i < 10; ++i) {
128  // rdrand %eax
129  __asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1"
130  : "=a"(r1), "=q"(ok)::"cc");
131  if (ok) {
132  break;
133  }
134  }
135  for (int i = 0; i < 10; ++i) {
136  // rdrand %eax
137  __asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1"
138  : "=a"(r2), "=q"(ok)::"cc");
139  if (ok) {
140  break;
141  }
142  }
143  return (uint64_t(r2) << 32) | r1;
144 #elif defined(__x86_64__) || defined(__amd64__)
145  uint8_t ok;
146  uint64_t r1 = 0; // See above why we initialize to 0.
147  for (int i = 0; i < 10; ++i) {
148  // rdrand %rax
149  __asm__ volatile(".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1"
150  : "=a"(r1), "=q"(ok)::"cc");
151  if (ok) {
152  break;
153  }
154  }
155  return r1;
156 #else
157 #error "RdRand is only supported on x86 and x86_64"
158 #endif
159 }
160 
166 static uint64_t GetRdSeed() noexcept {
167  // RdSeed may fail when the HW RNG is overloaded. Loop indefinitely until
168  // enough entropy is gathered, but pause after every failure.
169 #ifdef __i386__
170  uint8_t ok;
171  uint32_t r1, r2;
172  do {
173  // rdseed %eax
174  __asm__ volatile(".byte 0x0f, 0xc7, 0xf8; setc %1"
175  : "=a"(r1), "=q"(ok)::"cc");
176  if (ok) {
177  break;
178  }
179  __asm__ volatile("pause");
180  } while (true);
181  do {
182  // rdseed %eax
183  __asm__ volatile(".byte 0x0f, 0xc7, 0xf8; setc %1"
184  : "=a"(r2), "=q"(ok)::"cc");
185  if (ok) {
186  break;
187  }
188  __asm__ volatile("pause");
189  } while (true);
190  return (uint64_t(r2) << 32) | r1;
191 #elif defined(__x86_64__) || defined(__amd64__)
192  uint8_t ok;
193  uint64_t r1;
194  do {
195  // rdseed %rax
196  __asm__ volatile(".byte 0x48, 0x0f, 0xc7, 0xf8; setc %1"
197  : "=a"(r1), "=q"(ok)::"cc");
198  if (ok) {
199  break;
200  }
201  __asm__ volatile("pause");
202  } while (true);
203  return r1;
204 #else
205 #error "RdSeed is only supported on x86 and x86_64"
206 #endif
207 }
208 
209 #else
216 static void InitHardwareRand() {}
217 static void ReportHardwareRand() {}
218 #endif
219 
224 static void SeedHardwareFast(CSHA512 &hasher) noexcept {
225 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
226  if (g_rdrand_supported) {
227  uint64_t out = GetRdRand();
228  hasher.Write((const uint8_t *)&out, sizeof(out));
229  return;
230  }
231 #endif
232 }
233 
238 static void SeedHardwareSlow(CSHA512 &hasher) noexcept {
239 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
240  // When we want 256 bits of entropy, prefer RdSeed over RdRand, as it's
241  // guaranteed to produce independent randomness on every call.
242  if (g_rdseed_supported) {
243  for (int i = 0; i < 4; ++i) {
244  uint64_t out = GetRdSeed();
245  hasher.Write((const uint8_t *)&out, sizeof(out));
246  }
247  return;
248  }
249  // When falling back to RdRand, XOR the result of 1024 results.
250  // This guarantees a reseeding occurs between each.
251  if (g_rdrand_supported) {
252  for (int i = 0; i < 4; ++i) {
253  uint64_t out = 0;
254  for (int j = 0; j < 1024; ++j) {
255  out ^= GetRdRand();
256  }
257  hasher.Write((const uint8_t *)&out, sizeof(out));
258  }
259  return;
260  }
261 #endif
262 }
263 
268 static void Strengthen(const uint8_t (&seed)[32], int microseconds,
269  CSHA512 &hasher) noexcept {
270  CSHA512 inner_hasher;
271  inner_hasher.Write(seed, sizeof(seed));
272 
273  // Hash loop
274  uint8_t buffer[64];
275  int64_t stop = GetTimeMicros() + microseconds;
276  do {
277  for (int i = 0; i < 1000; ++i) {
278  inner_hasher.Finalize(buffer);
279  inner_hasher.Reset();
280  inner_hasher.Write(buffer, sizeof(buffer));
281  }
282  // Benchmark operation and feed it into outer hasher.
283  int64_t perf = GetPerformanceCounter();
284  hasher.Write((const uint8_t *)&perf, sizeof(perf));
285  } while (GetTimeMicros() < stop);
286 
287  // Produce output from inner state and feed it to outer hasher.
288  inner_hasher.Finalize(buffer);
289  hasher.Write(buffer, sizeof(buffer));
290  // Try to clean up.
291  inner_hasher.Reset();
292  memory_cleanse(buffer, sizeof(buffer));
293 }
294 
295 #ifndef WIN32
300 static void GetDevURandom(uint8_t *ent32) {
301  int f = open("/dev/urandom", O_RDONLY);
302  if (f == -1) {
303  RandFailure();
304  }
305  int have = 0;
306  do {
307  ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
308  if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
309  close(f);
310  RandFailure();
311  }
312  have += n;
313  } while (have < NUM_OS_RANDOM_BYTES);
314  close(f);
315 }
316 #endif
317 
319 void GetOSRand(uint8_t *ent32) {
320 #if defined(WIN32)
321  HCRYPTPROV hProvider;
322  int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL,
323  CRYPT_VERIFYCONTEXT);
324  if (!ret) {
325  RandFailure();
326  }
327  ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32);
328  if (!ret) {
329  RandFailure();
330  }
331  CryptReleaseContext(hProvider, 0);
332 #elif defined(HAVE_SYS_GETRANDOM)
339  int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0);
340  if (rv != NUM_OS_RANDOM_BYTES) {
341  if (rv < 0 && errno == ENOSYS) {
342  /* Fallback for kernel <3.17: the return value will be -1 and errno
343  * ENOSYS if the syscall is not available, in that case fall back
344  * to /dev/urandom.
345  */
346  GetDevURandom(ent32);
347  } else {
348  RandFailure();
349  }
350  }
351 #elif defined(HAVE_GETENTROPY) && defined(__OpenBSD__)
359  if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
360  RandFailure();
361  }
362  // Silence a compiler warning about unused function.
363  (void)GetDevURandom;
364 #elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
368  if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
369  RandFailure();
370  }
371  // Silence a compiler warning about unused function.
372  (void)GetDevURandom;
373 #elif defined(HAVE_SYSCTL_ARND)
378  static const int name[2] = {CTL_KERN, KERN_ARND};
379  int have = 0;
380  do {
381  size_t len = NUM_OS_RANDOM_BYTES - have;
382  if (sysctl(name, std::size(name), ent32 + have, &len, nullptr, 0) !=
383  0) {
384  RandFailure();
385  }
386  have += len;
387  } while (have < NUM_OS_RANDOM_BYTES);
388  // Silence a compiler warning about unused function.
389  (void)GetDevURandom;
390 #else
395  GetDevURandom(ent32);
396 #endif
397 }
398 
399 namespace {
400 
401 class RNGState {
402  Mutex m_mutex;
412  uint8_t m_state[32] GUARDED_BY(m_mutex) = {0};
413  uint64_t m_counter GUARDED_BY(m_mutex) = 0;
414  bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
415 
416  Mutex m_events_mutex;
417  CSHA256 m_events_hasher GUARDED_BY(m_events_mutex);
418 
419 public:
420  RNGState() noexcept { InitHardwareRand(); }
421 
422  ~RNGState() {}
423 
424  void AddEvent(uint32_t event_info) noexcept
425  EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex) {
426  LOCK(m_events_mutex);
427 
428  m_events_hasher.Write((const uint8_t *)&event_info, sizeof(event_info));
429  // Get the low four bytes of the performance counter. This translates to
430  // roughly the subsecond part.
431  uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
432  m_events_hasher.Write((const uint8_t *)&perfcounter,
433  sizeof(perfcounter));
434  }
435 
439  void SeedEvents(CSHA512 &hasher) noexcept
440  EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex) {
441  // We use only SHA256 for the events hashing to get the ASM speedups we
442  // have for SHA256, since we want it to be fast as network peers may be
443  // able to trigger it repeatedly.
444  LOCK(m_events_mutex);
445 
446  uint8_t events_hash[32];
447  m_events_hasher.Finalize(events_hash);
448  hasher.Write(events_hash, 32);
449 
450  // Re-initialize the hasher with the finalized state to use later.
451  m_events_hasher.Reset();
452  m_events_hasher.Write(events_hash, 32);
453  }
454 
462  bool MixExtract(uint8_t *out, size_t num, CSHA512 &&hasher,
463  bool strong_seed) noexcept
464  EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) {
465  assert(num <= 32);
466  uint8_t buf[64];
467  static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE,
468  "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 uint8_t *)&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
484  // output.
485  if (num) {
486  assert(out != nullptr);
487  memcpy(out, buf, num);
488  }
489  // Best effort cleanup of internal state
490  hasher.Reset();
491  memory_cleanse(buf, 64);
492  return ret;
493  }
494 };
495 
496 RNGState &GetRNGState() noexcept {
497  // This C++11 idiom relies on the guarantee that static variable are
498  // initialized on first call, even when multiple parallel calls are
499  // permitted.
500  static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
501  return g_rng[0];
502 }
503 } // namespace
504 
511 static void SeedTimestamp(CSHA512 &hasher) noexcept {
512  int64_t perfcounter = GetPerformanceCounter();
513  hasher.Write((const uint8_t *)&perfcounter, sizeof(perfcounter));
514 }
515 
516 static void SeedFast(CSHA512 &hasher) noexcept {
517  uint8_t buffer[32];
518 
519  // Stack pointer to indirectly commit to thread/callstack
520  const uint8_t *ptr = buffer;
521  hasher.Write((const uint8_t *)&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  uint8_t buffer[32];
532 
533  // Everything that the 'fast' seeder includes
534  SeedFast(hasher);
535 
536  // OS randomness
537  GetOSRand(buffer);
538  hasher.Write(buffer, sizeof(buffer));
539 
540  // Add the events hasher into the mix
541  rng.SeedEvents(hasher);
542 
543  // High-precision timestamp.
544  //
545  // Note that we also commit to a timestamp in the Fast seeder, so we
546  // indirectly commit to a benchmark of all the entropy gathering sources in
547  // this function).
548  SeedTimestamp(hasher);
549 }
550 
552 static void SeedStrengthen(CSHA512 &hasher, RNGState &rng,
553  int microseconds) noexcept {
554  // Generate 32 bytes of entropy from the RNG, and a copy of the entropy
555  // already in hasher.
556  uint8_t strengthen_seed[32];
557  rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher),
558  false);
559  // Strengthen the seed, and feed it into hasher.
560  Strengthen(strengthen_seed, microseconds, hasher);
561 }
562 
563 static void SeedPeriodic(CSHA512 &hasher, RNGState &rng) noexcept {
564  // Everything that the 'fast' seeder includes
565  SeedFast(hasher);
566 
567  // High-precision timestamp
568  SeedTimestamp(hasher);
569 
570  // Add the events hasher into the mix
571  rng.SeedEvents(hasher);
572 
573  // Dynamic environment data (performance monitoring, ...)
574  auto old_size = hasher.Size();
575  RandAddDynamicEnv(hasher);
577  "Feeding %i bytes of dynamic environment data into RNG\n",
578  hasher.Size() - old_size);
579 
580  // Strengthen for 10ms
581  SeedStrengthen(hasher, rng, 10000);
582 }
583 
584 static void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept {
585  // Gather 256 bits of hardware randomness, if available
586  SeedHardwareSlow(hasher);
587 
588  // Everything that the 'slow' seeder includes.
589  SeedSlow(hasher, rng);
590 
591  // Dynamic environment data (performance monitoring, ...)
592  auto old_size = hasher.Size();
593  RandAddDynamicEnv(hasher);
594 
595  // Static environment data
596  RandAddStaticEnv(hasher);
597  LogPrint(BCLog::RAND, "Feeding %i bytes of environment data into RNG\n",
598  hasher.Size() - old_size);
599 
600  // Strengthen for 100ms
601  SeedStrengthen(hasher, rng, 100000);
602 }
603 
604 enum class RNGLevel {
605  FAST,
606  SLOW,
607  PERIODIC,
608 };
609 
610 static void ProcRand(uint8_t *out, int num, RNGLevel level) noexcept {
611  // Make sure the RNG is initialized first (as all Seed* function possibly
612  // need hwrand to be available).
613  RNGState &rng = GetRNGState();
614 
615  assert(num <= 32);
616 
617  CSHA512 hasher;
618  switch (level) {
619  case RNGLevel::FAST:
620  SeedFast(hasher);
621  break;
622  case RNGLevel::SLOW:
623  SeedSlow(hasher, rng);
624  break;
625  case RNGLevel::PERIODIC:
626  SeedPeriodic(hasher, rng);
627  break;
628  }
629 
630  // Combine with and update state
631  if (!rng.MixExtract(out, num, std::move(hasher), false)) {
632  // On the first invocation, also seed with SeedStartup().
633  CSHA512 startup_hasher;
634  SeedStartup(startup_hasher, rng);
635  rng.MixExtract(out, num, std::move(startup_hasher), true);
636  }
637 }
638 
639 void GetRandBytes(Span<uint8_t> bytes) noexcept {
640  ProcRand(bytes.data(), bytes.size(), RNGLevel::FAST);
641 }
642 void GetStrongRandBytes(Span<uint8_t> bytes) noexcept {
643  ProcRand(bytes.data(), bytes.size(), RNGLevel::SLOW);
644 }
645 void RandAddPeriodic() noexcept {
646  ProcRand(nullptr, 0, RNGLevel::PERIODIC);
647 }
648 
649 void RandAddEvent(const uint32_t event_info) noexcept {
650  GetRNGState().AddEvent(event_info);
651 }
652 
654 
655 uint64_t GetRandInternal(uint64_t nMax) noexcept {
657 }
658 
659 uint256 GetRandHash() noexcept {
660  uint256 hash;
661  GetRandBytes(hash);
662  return hash;
663 }
664 
666  uint256 seed = GetRandHash();
667  rng.SetKey(seed.begin(), 32);
668  requires_seed = false;
669 }
670 
672  if (bytebuf_size < 20) {
673  FillByteBuffer();
674  }
675  uint160 ret;
676  memcpy(ret.begin(), bytebuf + 64 - bytebuf_size, 20);
677  bytebuf_size -= 20;
678  return ret;
679 }
680 
682  if (bytebuf_size < 32) {
683  FillByteBuffer();
684  }
685  uint256 ret;
686  memcpy(ret.begin(), bytebuf + 64 - bytebuf_size, 32);
687  bytebuf_size -= 32;
688  return ret;
689 }
690 std::vector<uint8_t> FastRandomContext::randbytes(size_t len) {
691  if (requires_seed) {
692  RandomSeed();
693  }
694  std::vector<uint8_t> ret(len);
695  if (len > 0) {
696  rng.Keystream(ret.data(), len);
697  }
698  return ret;
699 }
700 
702  : requires_seed(false), bytebuf_size(0), bitbuf_size(0) {
703  rng.SetKey(seed.begin(), 32);
704 }
705 
707  uint64_t start = GetPerformanceCounter();
708 
714  static const ssize_t MAX_TRIES = 1024;
715  uint8_t data[NUM_OS_RANDOM_BYTES];
716  /* Tracks which bytes have been overwritten at least once */
717  bool overwritten[NUM_OS_RANDOM_BYTES] = {};
718  int num_overwritten;
719  int tries = 0;
724  do {
725  memset(data, 0, NUM_OS_RANDOM_BYTES);
726  GetOSRand(data);
727  for (int x = 0; x < NUM_OS_RANDOM_BYTES; ++x) {
728  overwritten[x] |= (data[x] != 0);
729  }
730 
731  num_overwritten = 0;
732  for (int x = 0; x < NUM_OS_RANDOM_BYTES; ++x) {
733  if (overwritten[x]) {
734  num_overwritten += 1;
735  }
736  }
737 
738  tries += 1;
739  } while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
740  /* If this failed, bailed out after too many tries */
741  if (num_overwritten != NUM_OS_RANDOM_BYTES) {
742  return false;
743  }
744 
745  // Check that GetPerformanceCounter increases at least during a GetOSRand()
746  // call + 1ms sleep.
747  std::this_thread::sleep_for(std::chrono::milliseconds(1));
748  uint64_t stop = GetPerformanceCounter();
749  if (stop == start) {
750  return false;
751  }
752 
753  // We called GetPerformanceCounter. Use it as entropy.
754  CSHA512 to_add;
755  to_add.Write((const uint8_t *)&start, sizeof(start));
756  to_add.Write((const uint8_t *)&stop, sizeof(stop));
757  GetRNGState().MixExtract(nullptr, 0, std::move(to_add), false);
758 
759  return true;
760 }
761 
762 FastRandomContext::FastRandomContext(bool fDeterministic) noexcept
763  : requires_seed(!fDeterministic), bytebuf_size(0), bitbuf_size(0) {
764  if (!fDeterministic) {
765  return;
766  }
767  uint256 seed;
768  rng.SetKey(seed.begin(), 32);
769 }
770 
773  requires_seed = from.requires_seed;
774  rng = from.rng;
775  std::copy(std::begin(from.bytebuf), std::end(from.bytebuf),
776  std::begin(bytebuf));
777  bytebuf_size = from.bytebuf_size;
778  bitbuf = from.bitbuf;
779  bitbuf_size = from.bitbuf_size;
780  from.requires_seed = true;
781  from.bytebuf_size = 0;
782  from.bitbuf_size = 0;
783  return *this;
784 }
785 
786 void RandomInit() {
787  // Invoke RNG code to trigger initialization (if not already performed)
788  ProcRand(nullptr, 0, RNGLevel::FAST);
789 
791 }
792 
793 std::chrono::microseconds
794 GetExponentialRand(std::chrono::microseconds now,
795  std::chrono::seconds average_interval) {
796  double unscaled = -std::log1p(GetRand(uint64_t{1} << 48) *
797  -0.0000000000000035527136788 /* -1/2^48 */);
798  return now + std::chrono::duration_cast<std::chrono::microseconds>(
799  unscaled * average_interval + 0.5us);
800 }
A hasher class for SHA-256.
Definition: sha256.h:13
A hasher class for SHA-512.
Definition: sha512.h:12
CSHA512 & Write(const uint8_t *data, size_t len)
Definition: sha512.cpp:248
static constexpr size_t OUTPUT_SIZE
Definition: sha512.h:19
CSHA512 & Reset()
Definition: sha512.cpp:289
void Finalize(uint8_t hash[OUTPUT_SIZE])
Definition: sha512.cpp:273
void SetKey(const uint8_t *key, size_t keylen)
set key with flexible keylength; 256bit recommended
Definition: chacha20.cpp:32
void Keystream(uint8_t *c, size_t bytes)
outputs the keystream of size <bytes> into
Definition: chacha20.cpp:79
Fast randomness source.
Definition: random.h:156
uint160 rand160() noexcept
generate a random uint160.
Definition: random.cpp:671
std::vector< uint8_t > randbytes(size_t len)
Generate random bytes.
Definition: random.cpp:690
FastRandomContext(bool fDeterministic=false) noexcept
Definition: random.cpp:762
uint256 rand256() noexcept
generate a random uint256.
Definition: random.cpp:681
void RandomSeed()
Definition: random.cpp:665
ChaCha20 rng
Definition: random.h:159
FastRandomContext & operator=(const FastRandomContext &)=delete
uint8_t bytebuf[64]
Definition: random.h:161
bool requires_seed
Definition: random.h:158
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:231
void FillByteBuffer()
Definition: random.h:169
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:93
uint8_t * begin()
Definition: uint256.h:83
160-bit opaque blob.
Definition: uint256.h:115
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:210
#define LogPrintf(...)
Definition: logging.h:206
@ RAND
Definition: logging.h:53
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:794
static void ReportHardwareRand()
Definition: random.cpp:217
void GetRandBytes(Span< uint8_t > bytes) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:639
static void SeedStrengthen(CSHA512 &hasher, RNGState &rng, int microseconds) noexcept
Extract entropy from rng, strengthen it, and feed it into hasher.
Definition: random.cpp:552
static void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:584
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:645
bool g_mock_deterministic_tests
Definition: random.cpp:653
static void SeedFast(CSHA512 &hasher) noexcept
Definition: random.cpp:516
static void GetDevURandom(uint8_t *ent32)
Fallback: get 32 bytes of system entropy from /dev/urandom.
Definition: random.cpp:300
static void InitHardwareRand()
Access to other hardware random number generators could be added here later, assuming it is sufficien...
Definition: random.cpp:216
static void SeedHardwareFast(CSHA512 &hasher) noexcept
Add 64 bits of entropy gathered from hardware to hasher.
Definition: random.cpp:224
uint64_t GetRandInternal(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
Definition: random.cpp:655
void GetOSRand(uint8_t *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:319
static void SeedTimestamp(CSHA512 &hasher) noexcept
A note on the use of noexcept in the seeding functions below:
Definition: random.cpp:511
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:706
static void Strengthen(const uint8_t(&seed)[32], int microseconds, CSHA512 &hasher) noexcept
Use repeated SHA512 to strengthen the randomness in seed32, and feed into hasher.
Definition: random.cpp:268
uint256 GetRandHash() noexcept
Definition: random.cpp:659
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:786
static void SeedPeriodic(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:563
static void ProcRand(uint8_t *out, int num, RNGLevel level) noexcept
Definition: random.cpp:610
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:649
static void RandFailure()
Definition: random.cpp:48
RNGLevel
Definition: random.cpp:604
@ SLOW
Automatically called by GetStrongRandBytes.
@ PERIODIC
Called by RandAddPeriodic()
@ FAST
Automatically called by GetRandBytes.
static void SeedHardwareSlow(CSHA512 &hasher) noexcept
Add 256 bits of entropy gathered from hardware to hasher.
Definition: random.cpp:238
static int64_t GetPerformanceCounter() noexcept
Definition: random.cpp:53
void GetStrongRandBytes(Span< uint8_t > bytes) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
Definition: random.cpp:642
static void SeedSlow(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:530
static const int NUM_OS_RANDOM_BYTES
Number of random bytes returned by GetOSRand.
Definition: random.h:308
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:85
void RandAddStaticEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that does not change over time.
Definition: randomenv.cpp:341
void RandAddDynamicEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that changes over time.
Definition: randomenv.cpp:257
const char * name
Definition: rest.cpp:48
static RPCHelpMan stop()
Definition: server.cpp:209
#define LOCK(cs)
Definition: sync.h:306
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56
#define GUARDED_BY(x)
Definition: threadsafety.h:45
int64_t GetTimeMicros()
Returns the system time (not mockable)
Definition: time.cpp:105
assert(!tx.IsCoinBase())