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