Bitcoin Core 22.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-2020 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
69void GetRandBytes(unsigned char* buf, int num) noexcept;
71uint64_t GetRand(uint64_t nMax) noexcept;
73template <typename D>
74D GetRandomDuration(typename std::common_type<D>::type max) noexcept
75// Having the compiler infer the template argument from the function argument
76// is dangerous, because the desired return value generally has a different
77// type than the function argument. So std::common_type is used to force the
78// call site to specify the type of the return value.
79{
80 assert(max.count() > 0);
81 return D{GetRand(max.count())};
82};
83constexpr auto GetRandMicros = GetRandomDuration<std::chrono::microseconds>;
84constexpr auto GetRandMillis = GetRandomDuration<std::chrono::milliseconds>;
85int GetRandInt(int nMax) noexcept;
86uint256 GetRandHash() noexcept;
87
96void GetStrongRandBytes(unsigned char* buf, int num) noexcept;
97
103void RandAddPeriodic() noexcept;
104
111void RandAddEvent(const uint32_t event_info) noexcept;
112
120{
121private:
124
125 unsigned char bytebuf[64];
127
128 uint64_t bitbuf;
130
131 void RandomSeed();
132
134 {
135 if (requires_seed) {
136 RandomSeed();
137 }
138 rng.Keystream(bytebuf, sizeof(bytebuf));
139 bytebuf_size = sizeof(bytebuf);
140 }
141
143 {
144 bitbuf = rand64();
145 bitbuf_size = 64;
146 }
147
148public:
149 explicit FastRandomContext(bool fDeterministic = false) noexcept;
150
152 explicit FastRandomContext(const uint256& seed) noexcept;
153
154 // Do not permit copying a FastRandomContext (move it, or create a new one to get reseeded).
157 FastRandomContext& operator=(const FastRandomContext&) = delete;
158
160 FastRandomContext& operator=(FastRandomContext&& from) noexcept;
161
163 uint64_t rand64() noexcept
164 {
165 if (bytebuf_size < 8) FillByteBuffer();
166 uint64_t ret = ReadLE64(bytebuf + 64 - bytebuf_size);
167 bytebuf_size -= 8;
168 return ret;
169 }
170
172 uint64_t randbits(int bits) noexcept
173 {
174 if (bits == 0) {
175 return 0;
176 } else if (bits > 32) {
177 return rand64() >> (64 - bits);
178 } else {
179 if (bitbuf_size < bits) FillBitBuffer();
180 uint64_t ret = bitbuf & (~(uint64_t)0 >> (64 - bits));
181 bitbuf >>= bits;
182 bitbuf_size -= bits;
183 return ret;
184 }
185 }
186
190 uint64_t randrange(uint64_t range) noexcept
191 {
192 assert(range);
193 --range;
194 int bits = CountBits(range);
195 while (true) {
196 uint64_t ret = randbits(bits);
197 if (ret <= range) return ret;
198 }
199 }
200
202 std::vector<unsigned char> randbytes(size_t len);
203
205 uint32_t rand32() noexcept { return randbits(32); }
206
208 uint256 rand256() noexcept;
209
211 bool randbool() noexcept { return randbits(1); }
212
213 // Compatibility with the C++11 UniformRandomBitGenerator concept
214 typedef uint64_t result_type;
215 static constexpr uint64_t min() { return 0; }
216 static constexpr uint64_t max() { return std::numeric_limits<uint64_t>::max(); }
217 inline uint64_t operator()() noexcept { return rand64(); }
218};
219
230template <typename I, typename R>
231void Shuffle(I first, I last, R&& rng)
232{
233 while (first != last) {
234 size_t j = rng.randrange(last - first);
235 if (j) {
236 using std::swap;
237 swap(*first, *(first + j));
238 }
239 ++first;
240 }
241}
242
243/* Number of random bytes returned by GetOSRand.
244 * When changing this constant make sure to change all call sites, and make
245 * sure that the underlying OS APIs for all platforms support the number.
246 * (many cap out at 256 bytes).
247 */
248static const int NUM_OS_RANDOM_BYTES = 32;
249
253void GetOSRand(unsigned char* ent32);
254
258bool Random_SanityCheck();
259
266void RandomInit();
267
268#endif // BITCOIN_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:120
uint32_t rand32() noexcept
Generate a random 32-bit integer.
Definition: random.h:205
void FillBitBuffer()
Definition: random.h:142
uint64_t bitbuf
Definition: random.h:128
ChaCha20 rng
Definition: random.h:123
static constexpr uint64_t max()
Definition: random.h:216
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:172
static constexpr uint64_t min()
Definition: random.h:215
uint64_t result_type
Definition: random.h:214
bool requires_seed
Definition: random.h:122
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:190
uint64_t operator()() noexcept
Definition: random.h:217
void FillByteBuffer()
Definition: random.h:133
256-bit opaque blob.
Definition: uint256.h:124
static uint64_t ReadLE64(const unsigned char *ptr)
Definition: common.h:31
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:90
D GetRandomDuration(typename std::common_type< D >::type max) noexcept
Generate a uniform random duration in the range [0..max).
Definition: random.h:74
constexpr auto GetRandMicros
Definition: random.h:83
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:586
constexpr auto GetRandMillis
Definition: random.h:84
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:231
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:584
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:585
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:641
uint256 GetRandHash() noexcept
Definition: random.cpp:601
static const int NUM_OS_RANDOM_BYTES
Definition: random.h:248
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:710
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
Definition: random.cpp:591
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:587
void GetOSRand(unsigned char *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:276
int GetRandInt(int nMax) noexcept
Definition: random.cpp:596
assert(!tx.IsCoinBase())