Bitcoin ABC  0.22.13
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 #include <util/strencodings.h> // for ARRAYLEN
45 #endif
46 
47 [[noreturn]] static void RandFailure() {
48  LogPrintf("Failed to read randomness, aborting\n");
49  std::abort();
50 }
51 
52 static inline int64_t GetPerformanceCounter() noexcept {
53 // Read the hardware time stamp counter when available.
54 // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
55 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
56  return __rdtsc();
57 #elif !defined(_MSC_VER) && defined(__i386__)
58  uint64_t r = 0;
59  // Constrain the r variable to the eax:edx pair.
60  __asm__ volatile("rdtsc" : "=A"(r));
61  return r;
62 #elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
63  uint64_t r1 = 0, r2 = 0;
64  // Constrain r1 to rax and r2 to rdx.
65  __asm__ volatile("rdtsc" : "=a"(r1), "=d"(r2));
66  return (r2 << 32) | r1;
67 #else
68  // Fall back to using C++11 clock (usually microsecond or nanosecond
69  // precision)
70  return std::chrono::high_resolution_clock::now().time_since_epoch().count();
71 #endif
72 }
73 
74 #ifdef HAVE_GETCPUID
75 static bool g_rdrand_supported = false;
76 static bool g_rdseed_supported = false;
77 static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
78 static constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
79 #ifdef bit_RDRND
80 static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND,
81  "Unexpected value for bit_RDRND");
82 #endif
83 #ifdef bit_RDSEED
84 static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED,
85  "Unexpected value for bit_RDSEED");
86 #endif
87 
88 static void InitHardwareRand() {
89  uint32_t eax, ebx, ecx, edx;
90  GetCPUID(1, 0, eax, ebx, ecx, edx);
91  if (ecx & CPUID_F1_ECX_RDRAND) {
92  g_rdrand_supported = true;
93  }
94  GetCPUID(7, 0, eax, ebx, ecx, edx);
95  if (ebx & CPUID_F7_EBX_RDSEED) {
96  g_rdseed_supported = true;
97  }
98 }
99 
100 static void ReportHardwareRand() {
101  // This must be done in a separate function, as InitHardwareRand() may be
102  // indirectly called from global constructors, before logging is
103  // initialized.
104  if (g_rdseed_supported) {
105  LogPrintf("Using RdSeed as additional entropy source\n");
106  }
107  if (g_rdrand_supported) {
108  LogPrintf("Using RdRand as an additional entropy source\n");
109  }
110 }
111 
117 static uint64_t GetRdRand() noexcept {
118  // RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce
119  // this risk.
120 #ifdef __i386__
121  uint8_t ok;
122  uint32_t r1, r2;
123  for (int i = 0; i < 10; ++i) {
124  // rdrand %eax
125  __asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1"
126  : "=a"(r1), "=q"(ok)::"cc");
127  if (ok) {
128  break;
129  }
130  }
131  for (int i = 0; i < 10; ++i) {
132  // rdrand %eax
133  __asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1"
134  : "=a"(r2), "=q"(ok)::"cc");
135  if (ok) {
136  break;
137  }
138  }
139  return (uint64_t(r2) << 32) | r1;
140 #elif defined(__x86_64__) || defined(__amd64__)
141  uint8_t ok;
142  uint64_t r1;
143  for (int i = 0; i < 10; ++i) {
144  // rdrand %rax
145  __asm__ volatile(".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1"
146  : "=a"(r1), "=q"(ok)::"cc");
147  if (ok) {
148  break;
149  }
150  }
151  return r1;
152 #else
153 #error "RdRand is only supported on x86 and x86_64"
154 #endif
155 }
156 
162 static uint64_t GetRdSeed() noexcept {
163  // RdSeed may fail when the HW RNG is overloaded. Loop indefinitely until
164  // enough entropy is gathered, but pause after every failure.
165 #ifdef __i386__
166  uint8_t ok;
167  uint32_t r1, r2;
168  do {
169  // rdseed %eax
170  __asm__ volatile(".byte 0x0f, 0xc7, 0xf8; setc %1"
171  : "=a"(r1), "=q"(ok)::"cc");
172  if (ok) {
173  break;
174  }
175  __asm__ volatile("pause");
176  } while (true);
177  do {
178  // rdseed %eax
179  __asm__ volatile(".byte 0x0f, 0xc7, 0xf8; setc %1"
180  : "=a"(r2), "=q"(ok)::"cc");
181  if (ok) {
182  break;
183  }
184  __asm__ volatile("pause");
185  } while (true);
186  return (uint64_t(r2) << 32) | r1;
187 #elif defined(__x86_64__) || defined(__amd64__)
188  uint8_t ok;
189  uint64_t r1;
190  do {
191  // rdseed %rax
192  __asm__ volatile(".byte 0x48, 0x0f, 0xc7, 0xf8; setc %1"
193  : "=a"(r1), "=q"(ok)::"cc");
194  if (ok) {
195  break;
196  }
197  __asm__ volatile("pause");
198  } while (true);
199  return r1;
200 #else
201 #error "RdSeed is only supported on x86 and x86_64"
202 #endif
203 }
204 
205 #else
206 
212 static void InitHardwareRand() {}
213 static void ReportHardwareRand() {}
214 #endif
215 
220 static void SeedHardwareFast(CSHA512 &hasher) noexcept {
221 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
222  if (g_rdrand_supported) {
223  uint64_t out = GetRdRand();
224  hasher.Write((const uint8_t *)&out, sizeof(out));
225  return;
226  }
227 #endif
228 }
229 
234 static void SeedHardwareSlow(CSHA512 &hasher) noexcept {
235 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
236  // When we want 256 bits of entropy, prefer RdSeed over RdRand, as it's
237  // guaranteed to produce independent randomness on every call.
238  if (g_rdseed_supported) {
239  for (int i = 0; i < 4; ++i) {
240  uint64_t out = GetRdSeed();
241  hasher.Write((const uint8_t *)&out, sizeof(out));
242  }
243  return;
244  }
245  // When falling back to RdRand, XOR the result of 1024 results.
246  // This guarantees a reseeding occurs between each.
247  if (g_rdrand_supported) {
248  for (int i = 0; i < 4; ++i) {
249  uint64_t out = 0;
250  for (int j = 0; j < 1024; ++j) {
251  out ^= GetRdRand();
252  }
253  hasher.Write((const uint8_t *)&out, sizeof(out));
254  }
255  return;
256  }
257 #endif
258 }
259 
264 static void Strengthen(const uint8_t (&seed)[32], int microseconds,
265  CSHA512 &hasher) noexcept {
266  CSHA512 inner_hasher;
267  inner_hasher.Write(seed, sizeof(seed));
268 
269  // Hash loop
270  uint8_t buffer[64];
271  int64_t stop = GetTimeMicros() + microseconds;
272  do {
273  for (int i = 0; i < 1000; ++i) {
274  inner_hasher.Finalize(buffer);
275  inner_hasher.Reset();
276  inner_hasher.Write(buffer, sizeof(buffer));
277  }
278  // Benchmark operation and feed it into outer hasher.
279  int64_t perf = GetPerformanceCounter();
280  hasher.Write((const uint8_t *)&perf, sizeof(perf));
281  } while (GetTimeMicros() < stop);
282 
283  // Produce output from inner state and feed it to outer hasher.
284  inner_hasher.Finalize(buffer);
285  hasher.Write(buffer, sizeof(buffer));
286  // Try to clean up.
287  inner_hasher.Reset();
288  memory_cleanse(buffer, sizeof(buffer));
289 }
290 
291 #ifndef WIN32
292 
296 static void GetDevURandom(uint8_t *ent32) {
297  int f = open("/dev/urandom", O_RDONLY);
298  if (f == -1) {
299  RandFailure();
300  }
301  int have = 0;
302  do {
303  ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
304  if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
305  close(f);
306  RandFailure();
307  }
308  have += n;
309  } while (have < NUM_OS_RANDOM_BYTES);
310  close(f);
311 }
312 #endif
313 
315 void GetOSRand(uint8_t *ent32) {
316 #if defined(WIN32)
317  HCRYPTPROV hProvider;
318  int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL,
319  CRYPT_VERIFYCONTEXT);
320  if (!ret) {
321  RandFailure();
322  }
323  ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32);
324  if (!ret) {
325  RandFailure();
326  }
327  CryptReleaseContext(hProvider, 0);
328 #elif defined(HAVE_SYS_GETRANDOM)
329 
335  int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0);
336  if (rv != NUM_OS_RANDOM_BYTES) {
337  if (rv < 0 && errno == ENOSYS) {
338  /* Fallback for kernel <3.17: the return value will be -1 and errno
339  * ENOSYS if the syscall is not available, in that case fall back
340  * to /dev/urandom.
341  */
342  GetDevURandom(ent32);
343  } else {
344  RandFailure();
345  }
346  }
347 #elif defined(HAVE_GETENTROPY) && defined(__OpenBSD__)
348 
355  if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
356  RandFailure();
357  }
358 #elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
359 
362  if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
363  RandFailure();
364  }
365 #elif defined(HAVE_SYSCTL_ARND)
366 
370  static const int name[2] = {CTL_KERN, KERN_ARND};
371  int have = 0;
372  do {
373  size_t len = NUM_OS_RANDOM_BYTES - have;
374  if (sysctl(name, ARRAYLEN(name), ent32 + have, &len, nullptr, 0) != 0) {
375  RandFailure();
376  }
377  have += len;
378  } while (have < NUM_OS_RANDOM_BYTES);
379 #else
380 
384  GetDevURandom(ent32);
385 #endif
386 }
387 
388 namespace {
389 
390 class RNGState {
391  Mutex m_mutex;
401  uint8_t m_state[32] GUARDED_BY(m_mutex) = {0};
402  uint64_t m_counter GUARDED_BY(m_mutex) = 0;
403  bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
404 
405  Mutex m_events_mutex;
406  CSHA256 m_events_hasher GUARDED_BY(m_events_mutex);
407 
408 public:
409  RNGState() noexcept { InitHardwareRand(); }
410 
411  ~RNGState() {}
412 
413  void AddEvent(uint32_t event_info) noexcept {
414  LOCK(m_events_mutex);
415 
416  m_events_hasher.Write((const uint8_t *)&event_info, sizeof(event_info));
417  // Get the low four bytes of the performance counter. This translates to
418  // roughly the subsecond part.
419  uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
420  m_events_hasher.Write((const uint8_t *)&perfcounter,
421  sizeof(perfcounter));
422  }
423 
427  void SeedEvents(CSHA512 &hasher) noexcept {
428  // We use only SHA256 for the events hashing to get the ASM speedups we
429  // have for SHA256, since we want it to be fast as network peers may be
430  // able to trigger it repeatedly.
431  LOCK(m_events_mutex);
432 
433  uint8_t events_hash[32];
434  m_events_hasher.Finalize(events_hash);
435  hasher.Write(events_hash, 32);
436 
437  // Re-initialize the hasher with the finalized state to use later.
438  m_events_hasher.Reset();
439  m_events_hasher.Write(events_hash, 32);
440  }
441 
449  bool MixExtract(uint8_t *out, size_t num, CSHA512 &&hasher,
450  bool strong_seed) noexcept {
451  assert(num <= 32);
452  uint8_t buf[64];
453  static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE,
454  "Buffer needs to have hasher's output size");
455  bool ret;
456  {
457  LOCK(m_mutex);
458  ret = (m_strongly_seeded |= strong_seed);
459  // Write the current state of the RNG into the hasher
460  hasher.Write(m_state, 32);
461  // Write a new counter number into the state
462  hasher.Write((const uint8_t *)&m_counter, sizeof(m_counter));
463  ++m_counter;
464  // Finalize the hasher
465  hasher.Finalize(buf);
466  // Store the last 32 bytes of the hash output as new RNG state.
467  memcpy(m_state, buf + 32, 32);
468  }
469  // If desired, copy (up to) the first 32 bytes of the hash output as
470  // output.
471  if (num) {
472  assert(out != nullptr);
473  memcpy(out, buf, num);
474  }
475  // Best effort cleanup of internal state
476  hasher.Reset();
477  memory_cleanse(buf, 64);
478  return ret;
479  }
480 };
481 
482 RNGState &GetRNGState() noexcept {
483  // This C++11 idiom relies on the guarantee that static variable are
484  // initialized on first call, even when multiple parallel calls are
485  // permitted.
486  static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
487  return g_rng[0];
488 }
489 } // namespace
490 
497 static void SeedTimestamp(CSHA512 &hasher) noexcept {
498  int64_t perfcounter = GetPerformanceCounter();
499  hasher.Write((const uint8_t *)&perfcounter, sizeof(perfcounter));
500 }
501 
502 static void SeedFast(CSHA512 &hasher) noexcept {
503  uint8_t buffer[32];
504 
505  // Stack pointer to indirectly commit to thread/callstack
506  const uint8_t *ptr = buffer;
507  hasher.Write((const uint8_t *)&ptr, sizeof(ptr));
508 
509  // Hardware randomness is very fast when available; use it always.
510  SeedHardwareFast(hasher);
511 
512  // High-precision timestamp
513  SeedTimestamp(hasher);
514 }
515 
516 static void SeedSlow(CSHA512 &hasher, RNGState &rng) noexcept {
517  uint8_t buffer[32];
518 
519  // Everything that the 'fast' seeder includes
520  SeedFast(hasher);
521 
522  // OS randomness
523  GetOSRand(buffer);
524  hasher.Write(buffer, sizeof(buffer));
525 
526  // Add the events hasher into the mix
527  rng.SeedEvents(hasher);
528 
529  // High-precision timestamp.
530  //
531  // Note that we also commit to a timestamp in the Fast seeder, so we
532  // indirectly commit to a benchmark of all the entropy gathering sources in
533  // this function).
534  SeedTimestamp(hasher);
535 }
536 
538 static void SeedStrengthen(CSHA512 &hasher, RNGState &rng,
539  int microseconds) noexcept {
540  // Generate 32 bytes of entropy from the RNG, and a copy of the entropy
541  // already in hasher.
542  uint8_t strengthen_seed[32];
543  rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher),
544  false);
545  // Strengthen the seed, and feed it into hasher.
546  Strengthen(strengthen_seed, microseconds, hasher);
547 }
548 
549 static void SeedPeriodic(CSHA512 &hasher, RNGState &rng) noexcept {
550  // Everything that the 'fast' seeder includes
551  SeedFast(hasher);
552 
553  // High-precision timestamp
554  SeedTimestamp(hasher);
555 
556  // Add the events hasher into the mix
557  rng.SeedEvents(hasher);
558 
559  // Dynamic environment data (performance monitoring, ...)
560  auto old_size = hasher.Size();
561  RandAddDynamicEnv(hasher);
563  "Feeding %i bytes of dynamic environment data into RNG\n",
564  hasher.Size() - old_size);
565 
566  // Strengthen for 10ms
567  SeedStrengthen(hasher, rng, 10000);
568 }
569 
570 static void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept {
571  // Gather 256 bits of hardware randomness, if available
572  SeedHardwareSlow(hasher);
573 
574  // Everything that the 'slow' seeder includes.
575  SeedSlow(hasher, rng);
576 
577  // Dynamic environment data (performance monitoring, ...)
578  auto old_size = hasher.Size();
579  RandAddDynamicEnv(hasher);
580 
581  // Static environment data
582  RandAddStaticEnv(hasher);
583  LogPrint(BCLog::RAND, "Feeding %i bytes of environment data into RNG\n",
584  hasher.Size() - old_size);
585 
586  // Strengthen for 100ms
587  SeedStrengthen(hasher, rng, 100000);
588 }
589 
590 enum class RNGLevel {
591  FAST,
592  SLOW,
593  PERIODIC,
594 };
595 
596 static void ProcRand(uint8_t *out, int num, RNGLevel level) noexcept {
597  // Make sure the RNG is initialized first (as all Seed* function possibly
598  // need hwrand to be available).
599  RNGState &rng = GetRNGState();
600 
601  assert(num <= 32);
602 
603  CSHA512 hasher;
604  switch (level) {
605  case RNGLevel::FAST:
606  SeedFast(hasher);
607  break;
608  case RNGLevel::SLOW:
609  SeedSlow(hasher, rng);
610  break;
611  case RNGLevel::PERIODIC:
612  SeedPeriodic(hasher, rng);
613  break;
614  }
615 
616  // Combine with and update state
617  if (!rng.MixExtract(out, num, std::move(hasher), false)) {
618  // On the first invocation, also seed with SeedStartup().
619  CSHA512 startup_hasher;
620  SeedStartup(startup_hasher, rng);
621  rng.MixExtract(out, num, std::move(startup_hasher), true);
622  }
623 }
624 
625 void GetRandBytes(uint8_t *buf, int num) noexcept {
626  ProcRand(buf, num, RNGLevel::FAST);
627 }
628 void GetStrongRandBytes(uint8_t *buf, int num) noexcept {
629  ProcRand(buf, num, RNGLevel::SLOW);
630 }
631 void RandAddPeriodic() noexcept {
632  ProcRand(nullptr, 0, RNGLevel::PERIODIC);
633 }
634 
635 void RandAddEvent(const uint32_t event_info) noexcept {
636  GetRNGState().AddEvent(event_info);
637 }
638 
640 
641 uint64_t GetRand(uint64_t nMax) noexcept {
643 }
644 
645 std::chrono::microseconds
646 GetRandMicros(std::chrono::microseconds duration_max) noexcept {
647  return std::chrono::microseconds{GetRand(duration_max.count())};
648 }
649 
650 std::chrono::milliseconds
651 GetRandMillis(std::chrono::milliseconds duration_max) noexcept {
652  return std::chrono::milliseconds{GetRand(duration_max.count())};
653 }
654 
655 int GetRandInt(int nMax) noexcept {
656  return GetRand(nMax);
657 }
658 
659 uint256 GetRandHash() noexcept {
660  uint256 hash;
661  GetRandBytes((uint8_t *)&hash, sizeof(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[0], 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 
772 operator=(FastRandomContext &&from) noexcept {
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 }
CSHA512 & Write(const uint8_t *data, size_t len)
Definition: sha512.cpp:248
static const int NUM_OS_RANDOM_BYTES
Number of random bytes returned by GetOSRand.
Definition: random.h:252
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:786
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:635
uint64_t GetRand(uint64_t nMax) noexcept
Definition: random.cpp:641
#define LogPrint(category,...)
Definition: logging.h:192
FastRandomContext & operator=(const FastRandomContext &)=delete
uint256 GetRandHash() noexcept
Definition: random.cpp:659
static void SeedHardwareSlow(CSHA512 &hasher) noexcept
Add 256 bits of entropy gathered from hardware to hasher.
Definition: random.cpp:234
#define ARRAYLEN(array)
Utilities for converting data from/to strings.
Definition: strencodings.h:19
uint256 rand256() noexcept
generate a random uint256.
Definition: random.cpp:681
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:174
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:631
FastRandomContext(bool fDeterministic=false) noexcept
Definition: random.cpp:762
static void SeedStrengthen(CSHA512 &hasher, RNGState &rng, int microseconds) noexcept
Extract entropy from rng, strengthen it, and feed it into hasher.
Definition: random.cpp:538
Called by RandAddPeriodic()
std::chrono::microseconds GetRandMicros(std::chrono::microseconds duration_max) noexcept
Definition: random.cpp:646
void GetRandBytes(uint8_t *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:625
static void ProcRand(uint8_t *out, int num, RNGLevel level) noexcept
Definition: random.cpp:596
RNGLevel
Definition: random.cpp:590
static void SeedFast(CSHA512 &hasher) noexcept
Definition: random.cpp:502
static void RandFailure()
Definition: random.cpp:47
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
Definition: cleanse.cpp:14
std::chrono::milliseconds GetRandMillis(std::chrono::milliseconds duration_max) noexcept
Definition: random.cpp:651
#define LOCK(cs)
Definition: sync.h:230
const char * name
Definition: rest.cpp:43
Fast randomness source.
Definition: random.h:113
CSHA512 & Reset()
Definition: sha512.cpp:289
static void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:570
void Finalize(uint8_t hash[OUTPUT_SIZE])
Definition: sha512.cpp:273
void RandomSeed()
Definition: random.cpp:665
static void GetDevURandom(uint8_t *ent32)
Fallback: get 32 bytes of system entropy from /dev/urandom.
Definition: random.cpp:296
uint8_t * begin()
Definition: uint256.h:76
Automatically called by GetStrongRandBytes.
static constexpr size_t OUTPUT_SIZE
Definition: sha512.h:19
std::vector< uint8_t > randbytes(size_t len)
Generate random bytes.
Definition: random.cpp:690
static void SeedPeriodic(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:549
void GetOSRand(uint8_t *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:315
int64_t GetTimeMicros()
Returns the system time (not mockable)
Definition: time.cpp:67
bool requires_seed
Definition: random.h:115
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:628
256-bit opaque blob.
Definition: uint256.h:120
Automatically called by GetRandBytes.
static void ReportHardwareRand()
Definition: random.cpp:213
static void SeedSlow(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:516
static UniValue stop(const Config &config, const JSONRPCRequest &jsonRequest)
Definition: server.cpp:198
uint160 rand160() noexcept
generate a random uint160.
Definition: random.cpp:671
160-bit opaque blob.
Definition: uint256.h:108
#define GUARDED_BY(x)
Definition: threadsafety.h:45
A hasher class for SHA-512.
Definition: sha512.h:12
bool g_mock_deterministic_tests
Definition: random.cpp:639
static void SeedHardwareFast(CSHA512 &hasher) noexcept
Add 64 bits of entropy gathered from hardware to hasher.
Definition: random.cpp:220
A hasher class for SHA-256.
Definition: sha256.h:13
void RandAddStaticEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that does not change over time.
Definition: randomenv.cpp:341
int GetRandInt(int nMax) noexcept
Definition: random.cpp:655
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:706
static void InitHardwareRand()
Access to other hardware random number generators could be added here later, assuming it is sufficien...
Definition: random.cpp:212
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:188
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:264
static int64_t GetPerformanceCounter() noexcept
Definition: random.cpp:52
static void SeedTimestamp(CSHA512 &hasher) noexcept
A note on the use of noexcept in the seeding functions below:
Definition: random.cpp:497
void RandAddDynamicEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that changes over time.
Definition: randomenv.cpp:257