Bitcoin ABC  0.24.11
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  // Initialize to 0 to silence a compiler warning that r1 or r2 may be used
123  // uninitialized. Even if rdrand fails (!ok) it will set the output to 0,
124  // but there is no way that the compiler could know that.
125  uint32_t r1 = 0, r2 = 0;
126  for (int i = 0; i < 10; ++i) {
127  // rdrand %eax
128  __asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1"
129  : "=a"(r1), "=q"(ok)::"cc");
130  if (ok) {
131  break;
132  }
133  }
134  for (int i = 0; i < 10; ++i) {
135  // rdrand %eax
136  __asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1"
137  : "=a"(r2), "=q"(ok)::"cc");
138  if (ok) {
139  break;
140  }
141  }
142  return (uint64_t(r2) << 32) | r1;
143 #elif defined(__x86_64__) || defined(__amd64__)
144  uint8_t ok;
145  uint64_t r1 = 0; // See above why we initialize to 0.
146  for (int i = 0; i < 10; ++i) {
147  // rdrand %rax
148  __asm__ volatile(".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1"
149  : "=a"(r1), "=q"(ok)::"cc");
150  if (ok) {
151  break;
152  }
153  }
154  return r1;
155 #else
156 #error "RdRand is only supported on x86 and x86_64"
157 #endif
158 }
159 
165 static uint64_t GetRdSeed() noexcept {
166  // RdSeed may fail when the HW RNG is overloaded. Loop indefinitely until
167  // enough entropy is gathered, but pause after every failure.
168 #ifdef __i386__
169  uint8_t ok;
170  uint32_t r1, r2;
171  do {
172  // rdseed %eax
173  __asm__ volatile(".byte 0x0f, 0xc7, 0xf8; setc %1"
174  : "=a"(r1), "=q"(ok)::"cc");
175  if (ok) {
176  break;
177  }
178  __asm__ volatile("pause");
179  } while (true);
180  do {
181  // rdseed %eax
182  __asm__ volatile(".byte 0x0f, 0xc7, 0xf8; setc %1"
183  : "=a"(r2), "=q"(ok)::"cc");
184  if (ok) {
185  break;
186  }
187  __asm__ volatile("pause");
188  } while (true);
189  return (uint64_t(r2) << 32) | r1;
190 #elif defined(__x86_64__) || defined(__amd64__)
191  uint8_t ok;
192  uint64_t r1;
193  do {
194  // rdseed %rax
195  __asm__ volatile(".byte 0x48, 0x0f, 0xc7, 0xf8; setc %1"
196  : "=a"(r1), "=q"(ok)::"cc");
197  if (ok) {
198  break;
199  }
200  __asm__ volatile("pause");
201  } while (true);
202  return r1;
203 #else
204 #error "RdSeed is only supported on x86 and x86_64"
205 #endif
206 }
207 
208 #else
209 
215 static void InitHardwareRand() {}
216 static void ReportHardwareRand() {}
217 #endif
218 
223 static void SeedHardwareFast(CSHA512 &hasher) noexcept {
224 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
225  if (g_rdrand_supported) {
226  uint64_t out = GetRdRand();
227  hasher.Write((const uint8_t *)&out, sizeof(out));
228  return;
229  }
230 #endif
231 }
232 
237 static void SeedHardwareSlow(CSHA512 &hasher) noexcept {
238 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
239  // When we want 256 bits of entropy, prefer RdSeed over RdRand, as it's
240  // guaranteed to produce independent randomness on every call.
241  if (g_rdseed_supported) {
242  for (int i = 0; i < 4; ++i) {
243  uint64_t out = GetRdSeed();
244  hasher.Write((const uint8_t *)&out, sizeof(out));
245  }
246  return;
247  }
248  // When falling back to RdRand, XOR the result of 1024 results.
249  // This guarantees a reseeding occurs between each.
250  if (g_rdrand_supported) {
251  for (int i = 0; i < 4; ++i) {
252  uint64_t out = 0;
253  for (int j = 0; j < 1024; ++j) {
254  out ^= GetRdRand();
255  }
256  hasher.Write((const uint8_t *)&out, sizeof(out));
257  }
258  return;
259  }
260 #endif
261 }
262 
267 static void Strengthen(const uint8_t (&seed)[32], int microseconds,
268  CSHA512 &hasher) noexcept {
269  CSHA512 inner_hasher;
270  inner_hasher.Write(seed, sizeof(seed));
271 
272  // Hash loop
273  uint8_t buffer[64];
274  int64_t stop = GetTimeMicros() + microseconds;
275  do {
276  for (int i = 0; i < 1000; ++i) {
277  inner_hasher.Finalize(buffer);
278  inner_hasher.Reset();
279  inner_hasher.Write(buffer, sizeof(buffer));
280  }
281  // Benchmark operation and feed it into outer hasher.
282  int64_t perf = GetPerformanceCounter();
283  hasher.Write((const uint8_t *)&perf, sizeof(perf));
284  } while (GetTimeMicros() < stop);
285 
286  // Produce output from inner state and feed it to outer hasher.
287  inner_hasher.Finalize(buffer);
288  hasher.Write(buffer, sizeof(buffer));
289  // Try to clean up.
290  inner_hasher.Reset();
291  memory_cleanse(buffer, sizeof(buffer));
292 }
293 
294 #ifndef WIN32
295 
299 static void GetDevURandom(uint8_t *ent32) {
300  int f = open("/dev/urandom", O_RDONLY);
301  if (f == -1) {
302  RandFailure();
303  }
304  int have = 0;
305  do {
306  ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
307  if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
308  close(f);
309  RandFailure();
310  }
311  have += n;
312  } while (have < NUM_OS_RANDOM_BYTES);
313  close(f);
314 }
315 #endif
316 
318 void GetOSRand(uint8_t *ent32) {
319 #if defined(WIN32)
320  HCRYPTPROV hProvider;
321  int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL,
322  CRYPT_VERIFYCONTEXT);
323  if (!ret) {
324  RandFailure();
325  }
326  ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32);
327  if (!ret) {
328  RandFailure();
329  }
330  CryptReleaseContext(hProvider, 0);
331 #elif defined(HAVE_SYS_GETRANDOM)
332 
338  int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0);
339  if (rv != NUM_OS_RANDOM_BYTES) {
340  if (rv < 0 && errno == ENOSYS) {
341  /* Fallback for kernel <3.17: the return value will be -1 and errno
342  * ENOSYS if the syscall is not available, in that case fall back
343  * to /dev/urandom.
344  */
345  GetDevURandom(ent32);
346  } else {
347  RandFailure();
348  }
349  }
350 #elif defined(HAVE_GETENTROPY) && defined(__OpenBSD__)
351 
358  if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
359  RandFailure();
360  }
361  // Silence a compiler warning about unused function.
362  (void)GetDevURandom;
363 #elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
364 
367  if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
368  RandFailure();
369  }
370  // Silence a compiler warning about unused function.
371  (void)GetDevURandom;
372 #elif defined(HAVE_SYSCTL_ARND)
373 
377  static const int name[2] = {CTL_KERN, KERN_ARND};
378  int have = 0;
379  do {
380  size_t len = NUM_OS_RANDOM_BYTES - have;
381  if (sysctl(name, ARRAYLEN(name), ent32 + have, &len, nullptr, 0) != 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
389 
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 }
SeedHardwareFast
static void SeedHardwareFast(CSHA512 &hasher) noexcept
Add 64 bits of entropy gathered from hardware to hasher.
Definition: random.cpp:223
RandFailure
static void RandFailure()
Definition: random.cpp:47
FastRandomContext::rand256
uint256 rand256() noexcept
generate a random uint256.
Definition: random.cpp:680
ChaCha20::Keystream
void Keystream(uint8_t *c, size_t bytes)
outputs the keystream of size <bytes> into
Definition: chacha20.cpp:79
Strengthen
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:267
sync.h
RNGLevel::FAST
@ FAST
Automatically called by GetRandBytes.
SeedFast
static void SeedFast(CSHA512 &hasher) noexcept
Definition: random.cpp:511
NUM_OS_RANDOM_BYTES
static const int NUM_OS_RANDOM_BYTES
Number of random bytes returned by GetOSRand.
Definition: random.h:268
sha512.h
cpuid.h
randomenv.h
AnnotatedMixin< std::mutex >
GetRandBytes
void GetRandBytes(uint8_t *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:634
FastRandomContext::FastRandomContext
FastRandomContext(bool fDeterministic=false) noexcept
Definition: random.cpp:761
GUARDED_BY
#define GUARDED_BY(x)
Definition: threadsafety.h:45
memory_cleanse
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
Definition: cleanse.cpp:14
FastRandomContext::operator=
FastRandomContext & operator=(const FastRandomContext &)=delete
GetRand
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
Definition: random.cpp:650
GetOSRand
void GetOSRand(uint8_t *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:318
strencodings.h
RNGLevel::SLOW
@ SLOW
Automatically called by GetStrongRandBytes.
random.h
GetRandInt
int GetRandInt(int nMax) noexcept
Definition: random.cpp:654
SeedSlow
static void SeedSlow(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:525
FastRandomContext::FillByteBuffer
void FillByteBuffer()
Definition: random.h:142
SeedStartup
static void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:579
CSHA512::OUTPUT_SIZE
static constexpr size_t OUTPUT_SIZE
Definition: sha512.h:19
RandAddEvent
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
SeedTimestamp
static void SeedTimestamp(CSHA512 &hasher) noexcept
A note on the use of noexcept in the seeding functions below:
Definition: random.cpp:506
compat.h
CSHA512::Reset
CSHA512 & Reset()
Definition: sha512.cpp:289
cleanse.h
CSHA512::Finalize
void Finalize(uint8_t hash[OUTPUT_SIZE])
Definition: sha512.cpp:273
GetRandHash
uint256 GetRandHash() noexcept
Definition: random.cpp:658
time.h
SeedHardwareSlow
static void SeedHardwareSlow(CSHA512 &hasher) noexcept
Add 256 bits of entropy gathered from hardware to hasher.
Definition: random.cpp:237
FastRandomContext::RandomSeed
void RandomSeed()
Definition: random.cpp:664
GetStrongRandBytes
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
FastRandomContext::rand160
uint160 rand160() noexcept
generate a random uint160.
Definition: random.cpp:670
FastRandomContext::bytebuf_size
int bytebuf_size
Definition: random.h:135
uint256
256-bit opaque blob.
Definition: uint256.h:127
LogPrint
#define LogPrint(category,...)
Definition: logging.h:193
ProcRand
static void ProcRand(uint8_t *out, int num, RNGLevel level) noexcept
Definition: random.cpp:605
RandomInit
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:785
base_blob::begin
uint8_t * begin()
Definition: uint256.h:83
FastRandomContext::randbytes
std::vector< uint8_t > randbytes(size_t len)
Generate random bytes.
Definition: random.cpp:689
g_mock_deterministic_tests
bool g_mock_deterministic_tests
Definition: random.cpp:648
secure.h
ChaCha20::SetKey
void SetKey(const uint8_t *key, size_t keylen)
set key with flexible keylength; 256bit recommended
Definition: chacha20.cpp:32
name
const char * name
Definition: rest.cpp:43
FastRandomContext::requires_seed
bool requires_seed
Definition: random.h:131
RandAddStaticEnv
void RandAddStaticEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that does not change over time.
Definition: randomenv.cpp:341
sha256.h
BCLog::RAND
@ RAND
Definition: logging.h:51
GetDevURandom
static void GetDevURandom(uint8_t *ent32)
Fallback: get 32 bytes of system entropy from /dev/urandom.
Definition: random.cpp:299
stop
static RPCHelpMan stop()
Definition: server.cpp:203
uint160
160-bit opaque blob.
Definition: uint256.h:115
FastRandomContext::bytebuf
uint8_t bytebuf[64]
Definition: random.h:134
RandAddDynamicEnv
void RandAddDynamicEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that changes over time.
Definition: randomenv.cpp:257
LOCK
#define LOCK(cs)
Definition: sync.h:241
ARRAYLEN
#define ARRAYLEN(array)
Utilities for converting data from/to strings.
Definition: strencodings.h:20
CSHA512
A hasher class for SHA-512.
Definition: sha512.h:12
SeedPeriodic
static void SeedPeriodic(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:558
Random_SanityCheck
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:705
logging.h
CSHA256
A hasher class for SHA-256.
Definition: sha256.h:13
FastRandomContext::randrange
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:204
GetTimeMicros
int64_t GetTimeMicros()
Returns the system time (not mockable)
Definition: time.cpp:67
FastRandomContext::rng
ChaCha20 rng
Definition: random.h:132
GetPerformanceCounter
static int64_t GetPerformanceCounter() noexcept
Definition: random.cpp:52
InitHardwareRand
static void InitHardwareRand()
Access to other hardware random number generators could be added here later, assuming it is sufficien...
Definition: random.cpp:215
RandAddPeriodic
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:640
ReportHardwareRand
static void ReportHardwareRand()
Definition: random.cpp:216
RNGLevel
RNGLevel
Definition: random.cpp:599
SeedStrengthen
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
LogPrintf
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:175
CSHA512::Write
CSHA512 & Write(const uint8_t *data, size_t len)
Definition: sha512.cpp:248
FastRandomContext
Fast randomness source.
Definition: random.h:129
RNGLevel::PERIODIC
@ PERIODIC
Called by RandAddPeriodic()