Bitcoin ABC  0.22.12
P2P Digital Currency
random.h
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 #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 
72 void GetRandBytes(uint8_t *buf, int num) noexcept;
73 uint64_t GetRand(uint64_t nMax) noexcept;
74 std::chrono::microseconds
75 GetRandMicros(std::chrono::microseconds duration_max) noexcept;
76 int GetRandInt(int nMax) noexcept;
77 uint256 GetRandHash() noexcept;
78 
87 void GetStrongRandBytes(uint8_t *buf, int num) noexcept;
88 
95 void RandAddPeriodic() noexcept;
96 
103 void RandAddEvent(const uint32_t event_info) noexcept;
104 
112 private:
115 
116  uint8_t bytebuf[64];
118 
119  uint64_t bitbuf;
121 
122  void RandomSeed();
123 
124  void FillByteBuffer() {
125  if (requires_seed) {
126  RandomSeed();
127  }
128  rng.Keystream(bytebuf, sizeof(bytebuf));
129  bytebuf_size = sizeof(bytebuf);
130  }
131 
132  void FillBitBuffer() {
133  bitbuf = rand64();
134  bitbuf_size = 64;
135  }
136 
137 public:
138  explicit FastRandomContext(bool fDeterministic = false) noexcept;
139 
141  explicit FastRandomContext(const uint256 &seed) noexcept;
142 
143  // Do not permit copying a FastRandomContext (move it, or create a new one
144  // to get reseeded).
145  FastRandomContext(const FastRandomContext &) = delete;
146  FastRandomContext(FastRandomContext &&) = delete;
147  FastRandomContext &operator=(const FastRandomContext &) = delete;
148 
153  FastRandomContext &operator=(FastRandomContext &&from) noexcept;
154 
156  uint64_t rand64() noexcept {
157  if (bytebuf_size < 8) {
158  FillByteBuffer();
159  }
160  uint64_t ret = ReadLE64(bytebuf + 64 - bytebuf_size);
161  bytebuf_size -= 8;
162  return ret;
163  }
164 
166  uint64_t randbits(int bits) noexcept {
167  if (bits == 0) {
168  return 0;
169  } else if (bits > 32) {
170  return rand64() >> (64 - bits);
171  } else {
172  if (bitbuf_size < bits) {
173  FillBitBuffer();
174  }
175  uint64_t ret = bitbuf & (~uint64_t(0) >> (64 - bits));
176  bitbuf >>= bits;
177  bitbuf_size -= bits;
178  return ret;
179  }
180  }
181 
183  uint64_t randrange(uint64_t range) noexcept {
184  assert(range);
185  --range;
186  int bits = CountBits(range);
187  while (true) {
188  uint64_t ret = randbits(bits);
189  if (ret <= range) {
190  return ret;
191  }
192  }
193  }
194 
196  std::vector<uint8_t> randbytes(size_t len);
197 
199  uint32_t rand32() noexcept { return randbits(32); }
200 
202  uint160 rand160() noexcept;
203 
205  uint256 rand256() noexcept;
206 
208  bool randbool() noexcept { return randbits(1); }
209 
210  // Compatibility with the C++11 UniformRandomBitGenerator concept
211  typedef uint64_t result_type;
212  static constexpr uint64_t min() { return 0; }
213  static constexpr uint64_t max() {
214  return std::numeric_limits<uint64_t>::max();
215  }
216  inline uint64_t operator()() noexcept { return rand64(); }
217 };
218 
230 template <typename I, typename R> void Shuffle(I first, I last, R &&rng) {
231  while (first != last) {
232  size_t j = rng.randrange(last - first);
233  if (j) {
234  using std::swap;
235  swap(*first, *(first + j));
236  }
237  ++first;
238  }
239 }
240 
247 static const int NUM_OS_RANDOM_BYTES = 32;
248 
253 void GetOSRand(uint8_t *ent32);
254 
259 bool Random_SanityCheck();
260 
267 void RandomInit();
268 
269 #endif // BITCOIN_RANDOM_H
static const int NUM_OS_RANDOM_BYTES
Number of random bytes returned by GetOSRand.
Definition: random.h:247
void Keystream(uint8_t *c, size_t bytes)
outputs the keystream of size <bytes> into
Definition: chacha20.cpp:79
int GetRandInt(int nMax) noexcept
Definition: random.cpp:650
uint64_t bitbuf
Definition: random.h:119
void GetOSRand(uint8_t *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:315
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:701
void GetRandBytes(uint8_t *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:625
void FillBitBuffer()
Definition: random.h:132
void FillByteBuffer()
Definition: random.h:124
A class for ChaCha20 256-bit stream cipher developed by Daniel J.
Definition: chacha20.h:15
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:166
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:781
Fast randomness source.
Definition: random.h:111
static constexpr uint64_t max()
Definition: random.h:213
std::chrono::microseconds GetRandMicros(std::chrono::microseconds duration_max) noexcept
Definition: random.cpp:646
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:631
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:76
uint64_t result_type
Definition: random.h:211
uint32_t rand32() noexcept
Generate a random 32-bit integer.
Definition: random.h:199
bool requires_seed
Definition: random.h:113
256-bit opaque blob.
Definition: uint256.h:120
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:230
uint256 GetRandHash() noexcept
Definition: random.cpp:654
uint64_t operator()() noexcept
Definition: random.h:216
160-bit opaque blob.
Definition: uint256.h:108
static constexpr uint64_t min()
Definition: random.h:212
bool randbool() noexcept
Generate a random boolean.
Definition: random.h:208
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:628
ChaCha20 rng
Definition: random.h:114
uint64_t rand64() noexcept
Generate a random 64-bit integer.
Definition: random.h:156
static uint64_t ReadLE64(const uint8_t *ptr)
Definition: common.h:29
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:635
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:183
uint64_t GetRand(uint64_t nMax) noexcept
Definition: random.cpp:641