6#ifndef BITCOIN_RANDOM_H
7#define BITCOIN_RANDOM_H
153 { rng.rand64() }
noexcept -> std::same_as<uint64_t>;
156 requires std::derived_from<std::remove_reference_t<T>,
163 []<
class Rep, class Period>(
164 std::type_identity<std::chrono::duration<Rep, Period>>) {
165 }(std::type_identity<T>());
197 return static_cast<T &
>(*this);
220 return Impl().rand64();
234 uint64_t gen =
Impl().rand64();
240 return ret & ((uint64_t{1} << bits) - 1);
245 static_assert(Bits >= 0 && Bits <= 64);
246 if constexpr (Bits == 64) {
247 return Impl().rand64();
255 uint64_t gen =
Impl().rand64();
260 constexpr uint64_t MASK = (uint64_t{1} << Bits) - 1;
266 template <std::
integral I> I
randrange(I range)
noexcept {
267 static_assert(std::numeric_limits<I>::max() <=
268 std::numeric_limits<uint64_t>::max());
270 uint64_t maxval = range - 1U;
271 int bits = std::bit_width(maxval);
273 uint64_t ret =
Impl().randbits(bits);
282 while (span.size() >= 8) {
283 uint64_t gen =
Impl().rand64();
285 span = span.subspan(8);
287 if (span.size() >= 4) {
288 uint32_t gen =
Impl().rand32();
290 span = span.subspan(4);
292 while (span.size()) {
293 span[0] = std::byte(
Impl().
template randbits<8>());
294 span = span.subspan(1);
299 template <std::
integral I> I
rand() noexcept {
300 static_assert(std::numeric_limits<I>::max() <=
301 std::numeric_limits<uint64_t>::max());
302 static constexpr auto BITS =
303 std::bit_width(uint64_t(std::numeric_limits<I>::max()));
304 static_assert(std::numeric_limits<I>::max() ==
305 std::numeric_limits<uint64_t>::max() >> (64 - BITS));
306 return I(
Impl().
template randbits<BITS>());
310 template <BasicByte B = u
int8_t>
312 std::vector<B> ret(len);
318 uint32_t
rand32() noexcept {
return Impl().template randbits<32>(); }
338 template <
typename Tp>
340 typename Tp::duration range)
noexcept {
341 return time + rand_uniform_duration<Tp>(range);
348 template <
typename Chrono>
350 typename Chrono::duration
352 using Dur =
typename Chrono::duration;
353 return range.count() > 0
354 ? Dur{
Impl().randrange(
357 ? -Dur{
Impl().randrange(
367 template <StdChronoDuration Dur>
368 Dur
randrange(
typename std::common_type_t<Dur> range)
noexcept
374 return Dur{
Impl().randrange(range.count())};
388 std::chrono::microseconds
390 using namespace std::chrono_literals;
392 return std::chrono::duration_cast<std::chrono::microseconds>(
393 unscaled * mean + 0.5us);
398 static constexpr uint64_t
min() noexcept {
return 0; }
399 static constexpr uint64_t
max() noexcept {
400 return std::numeric_limits<uint64_t>::max();
436 std::array<std::byte, 8> buf;
463 [[nodiscard]]
constexpr static uint64_t
465 uint64_t z = (seedval += 0x9e3779b97f4a7c15);
466 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
467 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
468 return z ^ (z >> 31);
475 constexpr void Reseed(uint64_t seedval)
noexcept {
483 const uint64_t result = std::rotl(s0 + s1, 17) + s0;
485 m_s0 = std::rotl(s0, 49) ^ s1 ^ (s1 << 21);
486 m_s1 = std::rotl(s1, 28);
511template <
typename I, RandomNumberGenerator R>
513 while (first != last) {
514 size_t j = rng.randrange(last - first);
517 swap(*first, *(first + j));
#define Assume(val)
Assume is the identity function.
Unrestricted ChaCha20 cipher.
void Keystream(Span< std::byte > out) noexcept
outputs the keystream to out.
uint64_t rand64() noexcept
Generate a random 64-bit integer.
void RandomSeed() noexcept
void Reseed(const uint256 &seed) noexcept
Reseed with explicit seed (only for testing).
void fillrand(Span< std::byte > output) noexcept
Fill a byte Span with random bytes.
static constexpr uint64_t SplitMix64(uint64_t &seedval) noexcept
constexpr uint64_t rand64() noexcept
constexpr void Reseed(uint64_t seedval) noexcept
constexpr InsecureRandomContext(uint64_t seedval) noexcept
===================== RANDOM NUMBER GENERATION CLASSES =====================
uint160 rand160() noexcept
generate a random uint160.
static constexpr uint64_t max() noexcept
constexpr RandomMixin() noexcept=default
RandomNumberGenerator auto & Impl() noexcept
Access the underlying generator.
Dur randrange(typename std::common_type_t< Dur > range) noexcept
Generate a uniform random duration in the range [0..max).
void fillrand(Span< std::byte > span) noexcept
Fill a Span with random bytes.
Tp rand_uniform_delay(const Tp &time, typename Tp::duration range) noexcept
Return the time point advanced by a uniform random duration.
Chrono::duration rand_uniform_duration(typename Chrono::duration range) noexcept
Generate a uniform random duration in the range from 0 (inclusive) to range (exclusive).
I randrange(I range) noexcept
Generate a random integer in the range [0..range), with range > 0.
uint256 rand256() noexcept
generate a random uint256.
bool randbool() noexcept
Generate a random boolean.
I rand() noexcept
Generate a random integer in its entire (non-negative) range.
std::vector< B > randbytes(size_t len) noexcept
Generate random bytes.
constexpr void FlushCache() noexcept
std::chrono::microseconds rand_exp_duration(std::chrono::microseconds mean) noexcept
Return a duration sampled from an exponential distribution (https://en.wikipedia.org/wiki/Exponential...
static constexpr uint64_t min() noexcept
uint32_t rand32() noexcept
Generate a random 32-bit integer.
uint64_t randbits() noexcept
Same as above, but with compile-time fixed bits count.
uint64_t operator()() noexcept
A Span is an object that can refer to a contiguous sequence of objects.
A concept for RandomMixin-based random number generators.
A concept for C++ std::chrono durations.
static void WriteLE32(uint8_t *ptr, uint32_t x)
static uint64_t ReadLE64(const uint8_t *ptr)
static void WriteLE64(uint8_t *ptr, uint64_t x)
Implement std::hash so RCUPtr can be used as a key for maps or sets.
void GetRandBytes(Span< uint8_t > bytes) noexcept
================== BASE RANDOMNESS GENERATION FUNCTIONS ====================
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
bool Random_SanityCheck()
=============== MISCELLANEOUS TEST-ONLY FUNCTIONS ======================
uint256 GetRandHash() noexcept
========== CONVENIENCE FUNCTIONS FOR COMMONLY USED RANDOMNESS ==========
void RandomInit()
Overall design of the RNG and entropy sources.
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
double MakeExponentiallyDistributed(uint64_t uniform) noexcept
Given a uniformly random uint64_t, return an exponentially distributed double with mean 1.
void GetStrongRandBytes(Span< uint8_t > bytes) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
uint8_t * UCharCast(char *c)
Span< std::byte > MakeWritableByteSpan(V &&v) noexcept