Bitcoin ABC 0.32.4
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 <span.h>
12#include <uint256.h>
13
14#include <chrono>
15#include <cstdint>
16#include <limits>
17
73void GetRandBytes(Span<uint8_t> bytes) noexcept;
78uint64_t GetRandInternal(uint64_t nMax) noexcept;
84template <typename T>
85T GetRand(T nMax = std::numeric_limits<T>::max()) noexcept {
86 static_assert(std::is_integral<T>(), "T must be integral");
87 static_assert(std::numeric_limits<T>::max() <=
88 std::numeric_limits<uint64_t>::max(),
89 "GetRand only supports up to uint64_t");
90 return T(GetRandInternal(nMax));
91}
96template <typename D>
97D GetRandomDuration(typename std::common_type<D>::type max) noexcept {
98 // Having the compiler infer the template argument from the function
99 // argument is dangerous, because the desired return value generally has a
100 // different type than the function argument. So std::common_type is used to
101 // force the call site to specify the type of the return value.
102
103 assert(max.count() > 0);
104 return D{GetRand(max.count())};
105};
106constexpr auto GetRandMicros = GetRandomDuration<std::chrono::microseconds>;
107constexpr auto GetRandMillis = GetRandomDuration<std::chrono::milliseconds>;
108
118std::chrono::microseconds
119GetExponentialRand(std::chrono::microseconds now,
120 std::chrono::seconds average_interval);
121
122uint256 GetRandHash() noexcept;
123
132void GetStrongRandBytes(Span<uint8_t> bytes) noexcept;
133
140void RandAddPeriodic() noexcept;
141
148void RandAddEvent(const uint32_t event_info) noexcept;
149
157private:
160
161 uint64_t bitbuf;
163
164 void RandomSeed() noexcept;
165
166 void FillBitBuffer() noexcept {
167 bitbuf = rand64();
168 bitbuf_size = 64;
169 }
170
171public:
172 explicit FastRandomContext(bool fDeterministic = false) noexcept;
173
175 explicit FastRandomContext(const uint256 &seed) noexcept;
176
177 // Do not permit copying a FastRandomContext (move it, or create a new one
178 // to get reseeded).
181 FastRandomContext &operator=(const FastRandomContext &) = delete;
182
187 FastRandomContext &operator=(FastRandomContext &&from) noexcept;
188
190 uint64_t rand64() noexcept {
191 if (requires_seed) {
192 RandomSeed();
193 }
194 std::array<std::byte, 8> buf;
195 rng.Keystream(buf);
196 return ReadLE64(UCharCast(buf.data()));
197 }
198
200 uint64_t randbits(int bits) noexcept {
201 if (bits == 0) {
202 return 0;
203 } else if (bits > 32) {
204 return rand64() >> (64 - bits);
205 } else {
206 if (bitbuf_size < bits) {
207 FillBitBuffer();
208 }
209 uint64_t ret = bitbuf & (~uint64_t(0) >> (64 - bits));
210 bitbuf >>= bits;
211 bitbuf_size -= bits;
212 return ret;
213 }
214 }
215
220 uint64_t randrange(uint64_t range) noexcept {
221 assert(range);
222 --range;
223 int bits = CountBits(range);
224 while (true) {
225 uint64_t ret = randbits(bits);
226 if (ret <= range) {
227 return ret;
228 }
229 }
230 }
231
233 template <BasicByte B = uint8_t>
234 std::vector<B> randbytes(size_t len) noexcept {
235 std::vector<B> ret(len);
236 fillrand(MakeWritableByteSpan(ret));
237 return ret;
238 }
239
241 void fillrand(Span<std::byte> output) noexcept;
242
244 uint32_t rand32() noexcept { return randbits(32); }
245
247 uint160 rand160() noexcept {
248 uint160 ret;
249 fillrand(MakeWritableByteSpan(ret));
250 return ret;
251 }
252
254 uint256 rand256() noexcept {
255 uint256 ret;
256 fillrand(MakeWritableByteSpan(ret));
257 return ret;
258 }
259
261 bool randbool() noexcept { return randbits(1); }
262
264 template <typename Tp>
265 Tp rand_uniform_delay(const Tp &time,
266 typename Tp::duration range) noexcept {
267 using Dur = typename Tp::duration;
268 Dur dur{range.count() > 0
269 ? /* interval [0..range) */ Dur{randrange(range.count())}
270 : range.count() < 0
271 ? /* interval (range..0] */ -Dur{randrange(-range.count())}
272 :
273 /* interval [0..0] */ Dur{0}};
274 return time + dur;
275 }
276
277 // Compatibility with the C++11 UniformRandomBitGenerator concept
278 typedef uint64_t result_type;
279 static constexpr uint64_t min() noexcept { return 0; }
280 static constexpr uint64_t max() noexcept {
281 return std::numeric_limits<uint64_t>::max();
282 }
283 inline uint64_t operator()() noexcept { return rand64(); }
284};
285
297template <typename I, typename R> void Shuffle(I first, I last, R &&rng) {
298 while (first != last) {
299 size_t j = rng.randrange(last - first);
300 if (j) {
301 using std::swap;
302 swap(*first, *(first + j));
303 }
304 ++first;
305 }
306}
307
314static const int NUM_OS_RANDOM_BYTES = 32;
315
320void GetOSRand(uint8_t *ent32);
321
326bool Random_SanityCheck();
327
334void RandomInit();
335
336#endif // BITCOIN_RANDOM_H
Unrestricted ChaCha20 cipher.
Definition: chacha20.h:89
void Keystream(Span< std::byte > out) noexcept
outputs the keystream to out.
Definition: chacha20.cpp:298
Fast randomness source.
Definition: random.h:156
Tp rand_uniform_delay(const Tp &time, typename Tp::duration range) noexcept
Return the time point advanced by a uniform random duration.
Definition: random.h:265
static constexpr uint64_t max() noexcept
Definition: random.h:280
uint160 rand160() noexcept
generate a random uint160.
Definition: random.h:247
uint32_t rand32() noexcept
Generate a random 32-bit integer.
Definition: random.h:244
uint64_t bitbuf
Definition: random.h:161
uint256 rand256() noexcept
generate a random uint256.
Definition: random.h:254
bool randbool() noexcept
Generate a random boolean.
Definition: random.h:261
ChaCha20 rng
Definition: random.h:159
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:200
std::vector< B > randbytes(size_t len) noexcept
Generate random bytes.
Definition: random.h:234
static constexpr uint64_t min() noexcept
Definition: random.h:279
uint64_t result_type
Definition: random.h:278
bool requires_seed
Definition: random.h:158
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:220
uint64_t operator()() noexcept
Definition: random.h:283
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:94
160-bit opaque blob.
Definition: uint256.h:117
256-bit opaque blob.
Definition: uint256.h:129
static uint64_t ReadLE64(const uint8_t *ptr)
Definition: common.h:29
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
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:768
D GetRandomDuration(typename std::common_type< D >::type max) noexcept
Generate a uniform random duration in the range [0..max).
Definition: random.h:97
constexpr auto GetRandMicros
Definition: random.h:106
void GetRandBytes(Span< uint8_t > bytes) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:642
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:648
constexpr auto GetRandMillis
Definition: random.h:107
uint64_t GetRandInternal(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
Definition: random.cpp:658
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:297
void GetOSRand(uint8_t *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:322
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:684
uint256 GetRandHash() noexcept
Definition: random.cpp:662
static const int NUM_OS_RANDOM_BYTES
Number of random bytes returned by GetOSRand.
Definition: random.h:314
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:760
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:652
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:85
void GetStrongRandBytes(Span< uint8_t > bytes) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
Definition: random.cpp:645
uint8_t * UCharCast(char *c)
Definition: span.h:310
Span< std::byte > MakeWritableByteSpan(V &&v) noexcept
Definition: span.h:305
assert(!tx.IsCoinBase())