Bitcoin Core  22.99.0
P2P Digital Currency
random.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 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 #ifndef BITCOIN_RANDOM_H
7 #define BITCOIN_RANDOM_H
8 
9 #include <crypto/chacha20.h>
10 #include <crypto/common.h>
11 #include <uint256.h>
12 
13 #include <chrono>
14 #include <cstdint>
15 #include <limits>
16 
69 void GetRandBytes(unsigned char* buf, int num) noexcept;
71 uint64_t GetRand(uint64_t nMax) noexcept;
73 template <typename D>
74 D GetRandomDuration(typename std::common_type<D>::type max) noexcept
75 // Having the compiler infer the template argument from the function argument
76 // is dangerous, because the desired return value generally has a different
77 // type than the function argument. So std::common_type is used to force the
78 // call site to specify the type of the return value.
79 {
80  assert(max.count() > 0);
81  return D{GetRand(max.count())};
82 };
83 constexpr auto GetRandMicros = GetRandomDuration<std::chrono::microseconds>;
84 constexpr auto GetRandMillis = GetRandomDuration<std::chrono::milliseconds>;
85 
95 std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval);
96 
97 int GetRandInt(int nMax) noexcept;
98 uint256 GetRandHash() noexcept;
99 
108 void GetStrongRandBytes(unsigned char* buf, int num) noexcept;
109 
115 void RandAddPeriodic() noexcept;
116 
123 void RandAddEvent(const uint32_t event_info) noexcept;
124 
132 {
133 private:
136 
137  unsigned char bytebuf[64];
139 
140  uint64_t bitbuf;
142 
143  void RandomSeed();
144 
146  {
147  if (requires_seed) {
148  RandomSeed();
149  }
150  rng.Keystream(bytebuf, sizeof(bytebuf));
151  bytebuf_size = sizeof(bytebuf);
152  }
153 
155  {
156  bitbuf = rand64();
157  bitbuf_size = 64;
158  }
159 
160 public:
161  explicit FastRandomContext(bool fDeterministic = false) noexcept;
162 
164  explicit FastRandomContext(const uint256& seed) noexcept;
165 
166  // Do not permit copying a FastRandomContext (move it, or create a new one to get reseeded).
167  FastRandomContext(const FastRandomContext&) = delete;
169  FastRandomContext& operator=(const FastRandomContext&) = delete;
170 
172  FastRandomContext& operator=(FastRandomContext&& from) noexcept;
173 
175  uint64_t rand64() noexcept
176  {
177  if (bytebuf_size < 8) FillByteBuffer();
178  uint64_t ret = ReadLE64(bytebuf + 64 - bytebuf_size);
179  bytebuf_size -= 8;
180  return ret;
181  }
182 
184  uint64_t randbits(int bits) noexcept
185  {
186  if (bits == 0) {
187  return 0;
188  } else if (bits > 32) {
189  return rand64() >> (64 - bits);
190  } else {
191  if (bitbuf_size < bits) FillBitBuffer();
192  uint64_t ret = bitbuf & (~(uint64_t)0 >> (64 - bits));
193  bitbuf >>= bits;
194  bitbuf_size -= bits;
195  return ret;
196  }
197  }
198 
202  uint64_t randrange(uint64_t range) noexcept
203  {
204  assert(range);
205  --range;
206  int bits = CountBits(range);
207  while (true) {
208  uint64_t ret = randbits(bits);
209  if (ret <= range) return ret;
210  }
211  }
212 
214  std::vector<unsigned char> randbytes(size_t len);
215 
217  uint32_t rand32() noexcept { return randbits(32); }
218 
220  uint256 rand256() noexcept;
221 
223  bool randbool() noexcept { return randbits(1); }
224 
225  // Compatibility with the C++11 UniformRandomBitGenerator concept
226  typedef uint64_t result_type;
227  static constexpr uint64_t min() { return 0; }
228  static constexpr uint64_t max() { return std::numeric_limits<uint64_t>::max(); }
229  inline uint64_t operator()() noexcept { return rand64(); }
230 };
231 
242 template <typename I, typename R>
243 void Shuffle(I first, I last, R&& rng)
244 {
245  while (first != last) {
246  size_t j = rng.randrange(last - first);
247  if (j) {
248  using std::swap;
249  swap(*first, *(first + j));
250  }
251  ++first;
252  }
253 }
254 
255 /* Number of random bytes returned by GetOSRand.
256  * When changing this constant make sure to change all call sites, and make
257  * sure that the underlying OS APIs for all platforms support the number.
258  * (many cap out at 256 bytes).
259  */
260 static const int NUM_OS_RANDOM_BYTES = 32;
261 
265 void GetOSRand(unsigned char* ent32);
266 
270 bool Random_SanityCheck();
271 
278 void RandomInit();
279 
280 #endif // BITCOIN_RANDOM_H
ReadLE64
static uint64_t ReadLE64(const unsigned char *ptr)
Definition: common.h:31
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:719
assert
assert(!tx.IsCoinBase())
FastRandomContext::FillBitBuffer
void FillBitBuffer()
Definition: random.h:154
uint256.h
NUM_OS_RANDOM_BYTES
static const int NUM_OS_RANDOM_BYTES
Definition: random.h:260
Random_SanityCheck
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:642
RandomInit
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:711
chacha20.h
common.h
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:586
FastRandomContext::bitbuf
uint64_t bitbuf
Definition: random.h:140
FastRandomContext::randbits
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:184
ChaCha20::Keystream
void Keystream(unsigned char *c, size_t bytes)
outputs the keystream of size <bytes> into
Definition: chacha20.cpp:74
FastRandomContext::FillByteBuffer
void FillByteBuffer()
Definition: random.h:145
GetRandMicros
constexpr auto GetRandMicros
Definition: random.h:83
FastRandomContext::rand32
uint32_t rand32() noexcept
Generate a random 32-bit integer.
Definition: random.h:217
RandAddPeriodic
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:587
Shuffle
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:243
FastRandomContext::bytebuf_size
int bytebuf_size
Definition: random.h:138
GetOSRand
void GetOSRand(unsigned char *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:277
uint256
256-bit opaque blob.
Definition: uint256.h:126
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:588
FastRandomContext::bitbuf_size
int bitbuf_size
Definition: random.h:141
FastRandomContext::max
static constexpr uint64_t max()
Definition: random.h:228
FastRandomContext::requires_seed
bool requires_seed
Definition: random.h:134
GetRandInt
int GetRandInt(int nMax) noexcept
Definition: random.cpp:597
GetRandHash
uint256 GetRandHash() noexcept
Definition: random.cpp:602
FastRandomContext::result_type
uint64_t result_type
Definition: random.h:226
GetRandomDuration
D GetRandomDuration(typename std::common_type< D >::type max) noexcept
Generate a uniform random duration in the range [0..max).
Definition: random.h:74
GetRand
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
Definition: random.cpp:592
FastRandomContext::randrange
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:202
FastRandomContext::min
static constexpr uint64_t min()
Definition: random.h:227
FastRandomContext::rng
ChaCha20 rng
Definition: random.h:135
FastRandomContext::operator()
uint64_t operator()() noexcept
Definition: random.h:229
ChaCha20
A class for ChaCha20 256-bit stream cipher developed by Daniel J.
Definition: chacha20.h:13
GetRandBytes
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:585
GetRandMillis
constexpr auto GetRandMillis
Definition: random.h:84
FastRandomContext
Fast randomness source.
Definition: random.h:131
CountBits
static uint64_t CountBits(uint64_t x)
Return the smallest number n such that (x >> n) == 0 (or 64 if the highest bit in x is set.
Definition: common.h:90