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