Bitcoin ABC  0.24.10
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;
77 uint64_t GetRand(uint64_t nMax) noexcept;
82 template <typename D>
83 D GetRandomDuration(typename std::common_type<D>::type max) noexcept {
84  // Having the compiler infer the template argument from the function
85  // argument is dangerous, because the desired return value generally has a
86  // different type than the function argument. So std::common_type is used to
87  // force the call site to specify the type of the return value.
88 
89  assert(max.count() > 0);
90  return D{GetRand(max.count())};
91 };
92 constexpr auto GetRandMicros = GetRandomDuration<std::chrono::microseconds>;
93 constexpr auto GetRandMillis = GetRandomDuration<std::chrono::milliseconds>;
94 int GetRandInt(int nMax) noexcept;
95 uint256 GetRandHash() noexcept;
96 
105 void GetStrongRandBytes(uint8_t *buf, int num) noexcept;
106 
113 void RandAddPeriodic() noexcept;
114 
121 void RandAddEvent(const uint32_t event_info) noexcept;
122 
130 private:
133 
134  uint8_t bytebuf[64];
136 
137  uint64_t bitbuf;
139 
140  void RandomSeed();
141 
142  void FillByteBuffer() {
143  if (requires_seed) {
144  RandomSeed();
145  }
146  rng.Keystream(bytebuf, sizeof(bytebuf));
147  bytebuf_size = sizeof(bytebuf);
148  }
149 
150  void FillBitBuffer() {
151  bitbuf = rand64();
152  bitbuf_size = 64;
153  }
154 
155 public:
156  explicit FastRandomContext(bool fDeterministic = false) noexcept;
157 
159  explicit FastRandomContext(const uint256 &seed) noexcept;
160 
161  // Do not permit copying a FastRandomContext (move it, or create a new one
162  // to get reseeded).
163  FastRandomContext(const FastRandomContext &) = delete;
165  FastRandomContext &operator=(const FastRandomContext &) = delete;
166 
171  FastRandomContext &operator=(FastRandomContext &&from) noexcept;
172 
174  uint64_t rand64() noexcept {
175  if (bytebuf_size < 8) {
176  FillByteBuffer();
177  }
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  if (bits == 0) {
186  return 0;
187  } else if (bits > 32) {
188  return rand64() >> (64 - bits);
189  } else {
190  if (bitbuf_size < bits) {
191  FillBitBuffer();
192  }
193  uint64_t ret = bitbuf & (~uint64_t(0) >> (64 - bits));
194  bitbuf >>= bits;
195  bitbuf_size -= bits;
196  return ret;
197  }
198  }
199 
204  uint64_t randrange(uint64_t range) noexcept {
205  assert(range);
206  --range;
207  int bits = CountBits(range);
208  while (true) {
209  uint64_t ret = randbits(bits);
210  if (ret <= range) {
211  return ret;
212  }
213  }
214  }
215 
217  std::vector<uint8_t> randbytes(size_t len);
218 
220  uint32_t rand32() noexcept { return randbits(32); }
221 
223  uint160 rand160() noexcept;
224 
226  uint256 rand256() noexcept;
227 
229  bool randbool() noexcept { return randbits(1); }
230 
231  // Compatibility with the C++11 UniformRandomBitGenerator concept
232  typedef uint64_t result_type;
233  static constexpr uint64_t min() { return 0; }
234  static constexpr uint64_t max() {
235  return std::numeric_limits<uint64_t>::max();
236  }
237  inline uint64_t operator()() noexcept { return rand64(); }
238 };
239 
251 template <typename I, typename R> void Shuffle(I first, I last, R &&rng) {
252  while (first != last) {
253  size_t j = rng.randrange(last - first);
254  if (j) {
255  using std::swap;
256  swap(*first, *(first + j));
257  }
258  ++first;
259  }
260 }
261 
268 static const int NUM_OS_RANDOM_BYTES = 32;
269 
274 void GetOSRand(uint8_t *ent32);
275 
280 bool Random_SanityCheck();
281 
288 void RandomInit();
289 
290 #endif // BITCOIN_RANDOM_H
FastRandomContext::FillBitBuffer
void FillBitBuffer()
Definition: random.h:150
ChaCha20::Keystream
void Keystream(uint8_t *c, size_t bytes)
outputs the keystream of size <bytes> into
Definition: chacha20.cpp:79
uint256.h
NUM_OS_RANDOM_BYTES
static const int NUM_OS_RANDOM_BYTES
Number of random bytes returned by GetOSRand.
Definition: random.h:268
ReadLE64
static uint64_t ReadLE64(const uint8_t *ptr)
Definition: common.h:29
Random_SanityCheck
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:705
GetRandBytes
void GetRandBytes(uint8_t *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:634
GetOSRand
void GetOSRand(uint8_t *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:318
RandomInit
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:785
chacha20.h
FastRandomContext::bitbuf
uint64_t bitbuf
Definition: random.h:137
FastRandomContext::randbits
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:184
FastRandomContext::FillByteBuffer
void FillByteBuffer()
Definition: random.h:142
GetRandMicros
constexpr auto GetRandMicros
Definition: random.h:92
FastRandomContext::rand32
uint32_t rand32() noexcept
Generate a random 32-bit integer.
Definition: random.h:220
RandAddPeriodic
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:640
Shuffle
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:251
FastRandomContext::bytebuf_size
int bytebuf_size
Definition: random.h:135
uint256
256-bit opaque blob.
Definition: uint256.h:127
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:644
FastRandomContext::bitbuf_size
int bitbuf_size
Definition: random.h:138
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:82
FastRandomContext::max
static constexpr uint64_t max()
Definition: random.h:234
FastRandomContext::requires_seed
bool requires_seed
Definition: random.h:131
GetStrongRandBytes
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:637
uint160
160-bit opaque blob.
Definition: uint256.h:115
GetRandInt
int GetRandInt(int nMax) noexcept
Definition: random.cpp:654
common.h
GetRandHash
uint256 GetRandHash() noexcept
Definition: random.cpp:658
FastRandomContext::result_type
uint64_t result_type
Definition: random.h:232
GetRandomDuration
D GetRandomDuration(typename std::common_type< D >::type max) noexcept
Generate a uniform random duration in the range [0..max).
Definition: random.h:83
GetRand
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
Definition: random.cpp:650
FastRandomContext::randrange
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:204
FastRandomContext::min
static constexpr uint64_t min()
Definition: random.h:233
FastRandomContext::rng
ChaCha20 rng
Definition: random.h:132
FastRandomContext::operator()
uint64_t operator()() noexcept
Definition: random.h:237
ChaCha20
A class for ChaCha20 256-bit stream cipher developed by Daniel J.
Definition: chacha20.h:15
GetRandMillis
constexpr auto GetRandMillis
Definition: random.h:93
FastRandomContext
Fast randomness source.
Definition: random.h:129