Bitcoin Core  0.19.99
P2P Digital Currency
random.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 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> // For std::chrono::microseconds
14 #include <cstdint>
15 #include <limits>
16 
71 void GetRandBytes(unsigned char* buf, int num) noexcept;
72 uint64_t GetRand(uint64_t nMax) noexcept;
73 std::chrono::microseconds GetRandMicros(std::chrono::microseconds duration_max) noexcept;
74 int GetRandInt(int nMax) noexcept;
75 uint256 GetRandHash() noexcept;
76 
85 void GetStrongRandBytes(unsigned char* buf, int num) noexcept;
86 
92 void RandAddSeedSleep();
93 
101 private:
104 
105  unsigned char bytebuf[64];
107 
108  uint64_t bitbuf;
110 
111  void RandomSeed();
112 
114  {
115  if (requires_seed) {
116  RandomSeed();
117  }
118  rng.Keystream(bytebuf, sizeof(bytebuf));
119  bytebuf_size = sizeof(bytebuf);
120  }
121 
123  {
124  bitbuf = rand64();
125  bitbuf_size = 64;
126  }
127 
128 public:
129  explicit FastRandomContext(bool fDeterministic = false) noexcept;
130 
132  explicit FastRandomContext(const uint256& seed) noexcept;
133 
134  // Do not permit copying a FastRandomContext (move it, or create a new one to get reseeded).
135  FastRandomContext(const FastRandomContext&) = delete;
136  FastRandomContext(FastRandomContext&&) = delete;
137  FastRandomContext& operator=(const FastRandomContext&) = delete;
138 
140  FastRandomContext& operator=(FastRandomContext&& from) noexcept;
141 
143  uint64_t rand64() noexcept
144  {
145  if (bytebuf_size < 8) FillByteBuffer();
146  uint64_t ret = ReadLE64(bytebuf + 64 - bytebuf_size);
147  bytebuf_size -= 8;
148  return ret;
149  }
150 
152  uint64_t randbits(int bits) noexcept {
153  if (bits == 0) {
154  return 0;
155  } else if (bits > 32) {
156  return rand64() >> (64 - bits);
157  } else {
158  if (bitbuf_size < bits) FillBitBuffer();
159  uint64_t ret = bitbuf & (~(uint64_t)0 >> (64 - bits));
160  bitbuf >>= bits;
161  bitbuf_size -= bits;
162  return ret;
163  }
164  }
165 
167  uint64_t randrange(uint64_t range) noexcept
168  {
169  --range;
170  int bits = CountBits(range);
171  while (true) {
172  uint64_t ret = randbits(bits);
173  if (ret <= range) return ret;
174  }
175  }
176 
178  std::vector<unsigned char> randbytes(size_t len);
179 
181  uint32_t rand32() noexcept { return randbits(32); }
182 
184  uint256 rand256() noexcept;
185 
187  bool randbool() noexcept { return randbits(1); }
188 
189  // Compatibility with the C++11 UniformRandomBitGenerator concept
190  typedef uint64_t result_type;
191  static constexpr uint64_t min() { return 0; }
192  static constexpr uint64_t max() { return std::numeric_limits<uint64_t>::max(); }
193  inline uint64_t operator()() noexcept { return rand64(); }
194 };
195 
206 template<typename I, typename R>
207 void Shuffle(I first, I last, R&& rng)
208 {
209  while (first != last) {
210  size_t j = rng.randrange(last - first);
211  if (j) {
212  using std::swap;
213  swap(*first, *(first + j));
214  }
215  ++first;
216  }
217 }
218 
219 /* Number of random bytes returned by GetOSRand.
220  * When changing this constant make sure to change all call sites, and make
221  * sure that the underlying OS APIs for all platforms support the number.
222  * (many cap out at 256 bytes).
223  */
224 static const int NUM_OS_RANDOM_BYTES = 32;
225 
229 void GetOSRand(unsigned char *ent32);
230 
234 bool Random_SanityCheck();
235 
242 void RandomInit();
243 
244 #endif // BITCOIN_RANDOM_H
static const int NUM_OS_RANDOM_BYTES
Definition: random.h:224
int GetRandInt(int nMax) noexcept
Definition: random.cpp:675
uint64_t bitbuf
Definition: random.h:108
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:720
void RandAddSeedSleep()
Sleep for 1ms, gather entropy from various sources, and feed them to the PRNG state.
Definition: random.cpp:661
void FillBitBuffer()
Definition: random.h:122
void FillByteBuffer()
Definition: random.h:113
A class for ChaCha20 256-bit stream cipher developed by Daniel J.
Definition: chacha20.h:13
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:152
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:660
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:789
Fast randomness source.
Definition: random.h:100
static constexpr uint64_t max()
Definition: random.h:192
std::chrono::microseconds GetRandMicros(std::chrono::microseconds duration_max) noexcept
Definition: random.cpp:670
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:83
uint64_t result_type
Definition: random.h:190
uint32_t rand32() noexcept
Generate a random 32-bit integer.
Definition: random.h:181
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:659
bool requires_seed
Definition: random.h:102
256-bit opaque blob.
Definition: uint256.h:121
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:207
void Keystream(unsigned char *c, size_t bytes)
outputs the keystream of size <bytes> into
Definition: chacha20.cpp:74
uint256 GetRandHash() noexcept
Definition: random.cpp:680
void GetOSRand(unsigned char *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:330
uint64_t operator()() noexcept
Definition: random.h:193
static uint64_t ReadLE64(const unsigned char *ptr)
Definition: common.h:31
static constexpr uint64_t min()
Definition: random.h:191
bool randbool() noexcept
Generate a random boolean.
Definition: random.h:187
ChaCha20 rng
Definition: random.h:103
uint64_t rand64() noexcept
Generate a random 64-bit integer.
Definition: random.h:143
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:167
uint64_t GetRand(uint64_t nMax) noexcept
Definition: random.cpp:665