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