Bitcoin Core  27.99.0
P2P Digital Currency
random.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2022 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 <span.h>
12 #include <uint256.h>
13 
14 #include <bit>
15 #include <cassert>
16 #include <chrono>
17 #include <cstdint>
18 #include <limits>
19 #include <vector>
20 
73 void GetRandBytes(Span<unsigned char> bytes) noexcept;
75 uint64_t GetRandInternal(uint64_t nMax) noexcept;
80 template<typename T>
81 T GetRand(T nMax=std::numeric_limits<T>::max()) noexcept {
82  static_assert(std::is_integral<T>(), "T must be integral");
83  static_assert(std::numeric_limits<T>::max() <= std::numeric_limits<uint64_t>::max(), "GetRand only supports up to uint64_t");
84  return T(GetRandInternal(nMax));
85 }
87 template <typename D>
88 D GetRandomDuration(typename std::common_type<D>::type max) noexcept
89 // Having the compiler infer the template argument from the function argument
90 // is dangerous, because the desired return value generally has a different
91 // type than the function argument. So std::common_type is used to force the
92 // call site to specify the type of the return value.
93 {
94  assert(max.count() > 0);
95  return D{GetRand(max.count())};
96 };
97 constexpr auto GetRandMicros = GetRandomDuration<std::chrono::microseconds>;
98 constexpr auto GetRandMillis = GetRandomDuration<std::chrono::milliseconds>;
99 
109 std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval);
110 
111 uint256 GetRandHash() noexcept;
112 
121 void GetStrongRandBytes(Span<unsigned char> bytes) noexcept;
122 
128 void RandAddPeriodic() noexcept;
129 
136 void RandAddEvent(const uint32_t event_info) noexcept;
137 
145 {
146 private:
149 
150  uint64_t bitbuf;
152 
153  void RandomSeed();
154 
156  {
157  bitbuf = rand64();
158  bitbuf_size = 64;
159  }
160 
161 public:
162  explicit FastRandomContext(bool fDeterministic = false) noexcept;
163 
165  explicit FastRandomContext(const uint256& seed) noexcept;
166 
167  // Do not permit copying a FastRandomContext (move it, or create a new one to get reseeded).
170  FastRandomContext& operator=(const FastRandomContext&) = delete;
171 
173  FastRandomContext& operator=(FastRandomContext&& from) noexcept;
174 
176  uint64_t rand64() noexcept
177  {
178  if (requires_seed) RandomSeed();
179  std::array<std::byte, 8> buf;
180  rng.Keystream(buf);
181  return ReadLE64(UCharCast(buf.data()));
182  }
183 
185  uint64_t randbits(int bits) noexcept
186  {
187  if (bits == 0) {
188  return 0;
189  } else if (bits > 32) {
190  return rand64() >> (64 - bits);
191  } else {
192  if (bitbuf_size < bits) FillBitBuffer();
193  uint64_t ret = bitbuf & (~uint64_t{0} >> (64 - bits));
194  bitbuf >>= bits;
195  bitbuf_size -= bits;
196  return ret;
197  }
198  }
199 
203  uint64_t randrange(uint64_t range) noexcept
204  {
205  assert(range);
206  --range;
207  int bits = std::bit_width(range);
208  while (true) {
209  uint64_t ret = randbits(bits);
210  if (ret <= range) return ret;
211  }
212  }
213 
215  template <typename B = unsigned char>
216  std::vector<B> randbytes(size_t len);
217 
219  void fillrand(Span<std::byte> output);
220 
222  uint32_t rand32() noexcept { return randbits(32); }
223 
225  uint256 rand256() noexcept;
226 
228  bool randbool() noexcept { return randbits(1); }
229 
231  template <typename Tp>
232  Tp rand_uniform_delay(const Tp& time, typename Tp::duration range)
233  {
234  return time + rand_uniform_duration<Tp>(range);
235  }
236 
238  template <typename Chrono>
239  typename Chrono::duration rand_uniform_duration(typename Chrono::duration range) noexcept
240  {
241  using Dur = typename Chrono::duration;
242  return range.count() > 0 ? /* interval [0..range) */ Dur{randrange(range.count())} :
243  range.count() < 0 ? /* interval (range..0] */ -Dur{randrange(-range.count())} :
244  /* interval [0..0] */ Dur{0};
245  };
246 
247  // Compatibility with the UniformRandomBitGenerator concept
248  typedef uint64_t result_type;
249  static constexpr uint64_t min() { return 0; }
250  static constexpr uint64_t max() { return std::numeric_limits<uint64_t>::max(); }
251  inline uint64_t operator()() noexcept { return rand64(); }
252 };
253 
264 template <typename I, typename R>
265 void Shuffle(I first, I last, R&& rng)
266 {
267  while (first != last) {
268  size_t j = rng.randrange(last - first);
269  if (j) {
270  using std::swap;
271  swap(*first, *(first + j));
272  }
273  ++first;
274  }
275 }
276 
277 /* Number of random bytes returned by GetOSRand.
278  * When changing this constant make sure to change all call sites, and make
279  * sure that the underlying OS APIs for all platforms support the number.
280  * (many cap out at 256 bytes).
281  */
282 static const int NUM_OS_RANDOM_BYTES = 32;
283 
287 void GetOSRand(unsigned char* ent32);
288 
292 bool Random_SanityCheck();
293 
300 void RandomInit();
301 
302 #endif // BITCOIN_RANDOM_H
int ret
Unrestricted ChaCha20 cipher.
Definition: chacha20.h:78
void Keystream(Span< std::byte > out) noexcept
outputs the keystream to out.
Definition: chacha20.cpp:282
Fast randomness source.
Definition: random.h:145
Chrono::duration rand_uniform_duration(typename Chrono::duration range) noexcept
Generate a uniform random duration in the range from 0 (inclusive) to range (exclusive).
Definition: random.h:239
uint32_t rand32() noexcept
Generate a random 32-bit integer.
Definition: random.h:222
void FillBitBuffer()
Definition: random.h:155
uint64_t bitbuf
Definition: random.h:150
Tp rand_uniform_delay(const Tp &time, typename Tp::duration range)
Return the time point advanced by a uniform random duration.
Definition: random.h:232
ChaCha20 rng
Definition: random.h:148
static constexpr uint64_t max()
Definition: random.h:250
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:185
static constexpr uint64_t min()
Definition: random.h:249
uint64_t result_type
Definition: random.h:245
bool requires_seed
Definition: random.h:147
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:203
uint64_t operator()() noexcept
Definition: random.h:251
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:98
256-bit opaque blob.
Definition: uint256.h:106
static uint64_t ReadLE64(const unsigned char *ptr)
Definition: common.h:27
#define T(expected, seed, data)
std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval)
Return a timestamp in the future sampled from an exponential distribution (https://en....
Definition: random.cpp:764
D GetRandomDuration(typename std::common_type< D >::type max) noexcept
Generate a uniform random duration in the range [0..max).
Definition: random.h:88
constexpr auto GetRandMicros
Definition: random.h:97
void GetRandBytes(Span< unsigned char > bytes) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:638
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:640
constexpr auto GetRandMillis
Definition: random.h:98
uint64_t GetRandInternal(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
Definition: random.cpp:645
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:265
void GetStrongRandBytes(Span< unsigned char > bytes) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
Definition: random.cpp:639
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:690
uint256 GetRandHash() noexcept
Definition: random.cpp:650
static const int NUM_OS_RANDOM_BYTES
Definition: random.h:282
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:756
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:641
void GetOSRand(unsigned char *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:351
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition: random.h:81
unsigned char * UCharCast(char *c)
Definition: span.h:288
assert(!tx.IsCoinBase())