Bitcoin
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 <stdint.h>
14 #include <limits>
15 
70 void GetRandBytes(unsigned char* buf, int num) noexcept;
71 uint64_t GetRand(uint64_t nMax) noexcept;
72 int GetRandInt(int nMax) noexcept;
73 uint256 GetRandHash() noexcept;
74 
83 void GetStrongRandBytes(unsigned char* buf, int num) noexcept;
84 
90 void RandAddSeedSleep();
91 
99 private:
102 
103  unsigned char bytebuf[64];
105 
108 
109  void RandomSeed();
110 
112  {
113  if (requires_seed) {
114  RandomSeed();
115  }
116  rng.Keystream(bytebuf, sizeof(bytebuf));
117  bytebuf_size = sizeof(bytebuf);
118  }
119 
121  {
122  bitbuf = rand64();
123  bitbuf_size = 64;
124  }
125 
126 public:
127  explicit FastRandomContext(bool fDeterministic = false) noexcept;
128 
130  explicit FastRandomContext(const uint256& seed) noexcept;
131 
132  // Do not permit copying a FastRandomContext (move it, or create a new one to get reseeded).
133  FastRandomContext(const FastRandomContext&) = delete;
135  FastRandomContext& operator=(const FastRandomContext&) = delete;
136 
138  FastRandomContext& operator=(FastRandomContext&& from) noexcept;
139 
141  uint64_t rand64() noexcept
142  {
143  if (bytebuf_size < 8) FillByteBuffer();
144  uint64_t ret = ReadLE64(bytebuf + 64 - bytebuf_size);
145  bytebuf_size -= 8;
146  return ret;
147  }
148 
150  uint64_t randbits(int bits) noexcept {
151  if (bits == 0) {
152  return 0;
153  } else if (bits > 32) {
154  return rand64() >> (64 - bits);
155  } else {
156  if (bitbuf_size < bits) FillBitBuffer();
157  uint64_t ret = bitbuf & (~(uint64_t)0 >> (64 - bits));
158  bitbuf >>= bits;
159  bitbuf_size -= bits;
160  return ret;
161  }
162  }
163 
165  uint64_t randrange(uint64_t range) noexcept
166  {
167  --range;
168  int bits = CountBits(range);
169  while (true) {
170  uint64_t ret = randbits(bits);
171  if (ret <= range) return ret;
172  }
173  }
174 
176  std::vector<unsigned char> randbytes(size_t len);
177 
179  uint32_t rand32() noexcept { return randbits(32); }
180 
182  uint256 rand256() noexcept;
183 
185  bool randbool() noexcept { return randbits(1); }
186 
187  // Compatibility with the C++11 UniformRandomBitGenerator concept
189  static constexpr uint64_t min() { return 0; }
190  static constexpr uint64_t max() { return std::numeric_limits<uint64_t>::max(); }
191  inline uint64_t operator()() noexcept { return rand64(); }
192 };
193 
204 template<typename I, typename R>
205 void Shuffle(I first, I last, R&& rng)
206 {
207  while (first != last) {
208  size_t j = rng.randrange(last - first);
209  if (j) {
210  using std::swap;
211  swap(*first, *(first + j));
212  }
213  ++first;
214  }
215 }
216 
217 /* Number of random bytes returned by GetOSRand.
218  * When changing this constant make sure to change all call sites, and make
219  * sure that the underlying OS APIs for all platforms support the number.
220  * (many cap out at 256 bytes).
221  */
222 static const int NUM_OS_RANDOM_BYTES = 32;
223 
227 void GetOSRand(unsigned char *ent32);
228 
232 bool Random_SanityCheck();
233 
240 void RandomInit();
241 
242 #endif // BITCOIN_RANDOM_H
static const int NUM_OS_RANDOM_BYTES
Definition: random.h:222
def randbool(p=0.5)
Definition: gen_key_io_test_vectors.py:216
int GetRandInt(int nMax) noexcept
Definition: random.cpp:670
void FillByteBuffer()
Definition: random.h:111
int RandomSeed()
Definition: testharness.cc:67
static constexpr uint64_t min()
Definition: random.h:189
uint64_t bitbuf
Definition: random.h:106
static constexpr uint64_t max()
Definition: random.h:190
void FillBitBuffer()
Definition: random.h:120
bool Random_SanityCheck()
Definition: random.cpp:715
void RandAddSeedSleep()
Definition: random.cpp:661
Definition: chacha20.h:13
uint64_t randrange(uint64_t range) noexcept
Definition: random.h:165
uint64_t result_type
Definition: random.h:188
void GetStrongRandBytes(unsigned char *buf, int num) noexcept
Definition: random.cpp:660
unsigned int uint32_t
Definition: stdint.h:21
void RandomInit()
Definition: random.cpp:784
unsigned long long uint64_t
Definition: stdint.h:22
void Keystream(unsigned char *c, size_t bytes)
Definition: chacha20.cpp:74
uint32_t rand32() noexcept
Definition: random.h:179
static uint64_t CountBits(uint64_t x)
Definition: common.h:83
void GetRandBytes(unsigned char *buf, int num) noexcept
Definition: random.cpp:659
Definition: uint256.h:121
void Shuffle(I first, I last, R &&rng)
Definition: random.h:205
int bytebuf_size
Definition: random.h:104
ChaCha20 rng
Definition: random.h:101
bool requires_seed
Definition: random.h:100
uint256 GetRandHash() noexcept
Definition: random.cpp:675
void GetOSRand(unsigned char *ent32)
Definition: random.cpp:330
static uint64_t ReadLE64(const unsigned char *ptr)
Definition: common.h:31
Definition: random.h:98
int bitbuf_size
Definition: random.h:107
uint64_t randbits(int bits) noexcept
Definition: random.h:150
uint64_t operator()() noexcept
Definition: random.h:191
uint64_t GetRand(uint64_t nMax) noexcept
Definition: random.cpp:665