PIVX Core  5.6.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 developers
3 // Copyright (c) 2019-2021 The PIVX Core developers
4 // Distributed under the MIT/X11 software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #ifndef PIVX_RANDOM_H
8 #define PIVX_RANDOM_H
9 
10 #include "crypto/chacha20.h"
11 #include "crypto/common.h"
12 #include "uint256.h"
13 
14 #include <stdint.h>
15 #include <limits>
16 
69 void GetRandBytes(unsigned char* buf, int num) noexcept;
70 uint64_t GetRand(uint64_t nMax) noexcept;
71 int GetRandInt(int nMax) noexcept;
72 uint256 GetRandHash() noexcept;
73 
74 bool GetRandBool(double rate) noexcept;
75 
84 void GetStrongRandBytes(unsigned char* buf, int num) noexcept;
85 
91 void RandAddPeriodic() noexcept;
92 
99 void RandAddEvent(const uint32_t event_info) noexcept;
100 
108 private:
109  bool requires_seed{false};
111 
112  unsigned char bytebuf[64];
113  int bytebuf_size{0};
114 
115  uint64_t bitbuf{0};
116  int bitbuf_size{0};
117 
118  void RandomSeed();
119 
121  {
122  if (requires_seed) {
123  RandomSeed();
124  }
125  rng.Keystream(bytebuf, sizeof(bytebuf));
126  bytebuf_size = sizeof(bytebuf);
127  }
128 
130  {
131  bitbuf = rand64();
132  bitbuf_size = 64;
133  }
134 
135 public:
136  explicit FastRandomContext(bool fDeterministic = false) noexcept;
137 
139  explicit FastRandomContext(const uint256& seed) noexcept;
140 
141  // Do not permit copying a FastRandomContext (move it, or create a new one to get reseeded).
144  FastRandomContext& operator=(const FastRandomContext&) = delete;
145 
147  FastRandomContext& operator=(FastRandomContext&& from) noexcept;
148 
150  uint64_t rand64() noexcept
151  {
152  if (bytebuf_size < 8) FillByteBuffer();
153  uint64_t ret = ReadLE64(bytebuf + 64 - bytebuf_size);
154  bytebuf_size -= 8;
155  return ret;
156  }
157 
159  uint64_t randbits(int bits) noexcept {
160  if (bits == 0) {
161  return 0;
162  } else if (bits > 32) {
163  return rand64() >> (64 - bits);
164  } else {
165  if (bitbuf_size < bits) FillBitBuffer();
166  uint64_t ret = bitbuf & (~(uint64_t)0 >> (64 - bits));
167  bitbuf >>= bits;
168  bitbuf_size -= bits;
169  return ret;
170  }
171  }
172 
174  uint64_t randrange(uint64_t range) noexcept
175  {
176  --range;
177  int bits = CountBits(range);
178  while (true) {
179  uint64_t ret = randbits(bits);
180  if (ret <= range) return ret;
181  }
182  }
183 
185  std::vector<unsigned char> randbytes(size_t len);
186 
188  uint16_t rand16() { return randbits(16); }
189 
191  uint32_t rand32() noexcept { return randbits(32); }
192 
194  uint256 rand256() noexcept;
195 
197  bool randbool() noexcept { return randbits(1); }
198 
199  // Compatibility with the C++11 UniformRandomBitGenerator concept
200  typedef uint64_t result_type;
201  static constexpr uint64_t min() { return 0; }
202  static constexpr uint64_t max() { return std::numeric_limits<uint64_t>::max(); }
203  inline uint64_t operator()() noexcept { return rand64(); }
204 };
205 
216 template<typename I, typename R>
217 void Shuffle(I first, I last, R&& rng)
218 {
219  while (first != last) {
220  size_t j = rng.randrange(last - first);
221  if (j) {
222  using std::swap;
223  swap(*first, *(first + j));
224  }
225  ++first;
226  }
227 }
228 
229 /* Number of random bytes returned by GetOSRand.
230  * When changing this constant make sure to change all call sites, and make
231  * sure that the underlying OS APIs for all platforms support the number.
232  * (many cap out at 256 bytes).
233  */
234 static const ssize_t NUM_OS_RANDOM_BYTES = 32;
235 
239 void GetOSRand(unsigned char *ent32);
240 
244 bool Random_SanityCheck();
245 
252 void RandomInit();
253 
254 #endif // PIVX_RANDOM_H
A class for ChaCha20 256-bit stream cipher developed by Daniel J.
Definition: chacha20.h:14
void Keystream(unsigned char *c, size_t bytes)
outputs the keystream of size <bytes> into
Definition: chacha20.cpp:74
Fast randomness source.
Definition: random.h:107
uint32_t rand32() noexcept
Generate a random 32-bit integer.
Definition: random.h:191
uint16_t rand16()
Generate a random 16-bit integer.
Definition: random.h:188
void FillBitBuffer()
Definition: random.h:129
ChaCha20 rng
Definition: random.h:110
static constexpr uint64_t max()
Definition: random.h:202
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:159
static constexpr uint64_t min()
Definition: random.h:201
uint64_t result_type
Definition: random.h:200
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:174
uint64_t operator()() noexcept
Definition: random.h:203
void FillByteBuffer()
Definition: random.h:120
256-bit opaque blob.
Definition: uint256.h:138
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:581
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:217
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:579
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:580
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:647
uint256 GetRandHash() noexcept
Definition: random.cpp:596
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:716
bool GetRandBool(double rate) noexcept
Definition: random.cpp:603
uint64_t GetRand(uint64_t nMax) noexcept
Definition: random.cpp:586
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:582
void GetOSRand(unsigned char *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:278
int GetRandInt(int nMax) noexcept
Definition: random.cpp:591
#define R(a, b)