6#ifndef BITCOIN_RANDOM_H
7#define BITCOIN_RANDOM_H
149 { rng.rand64() }
noexcept -> std::same_as<uint64_t>;
157 []<
class Rep, class Period>(
std::type_identity<std::chrono::duration<Rep, Period>>){}(
158 std::type_identity<T>());
208 if (bits == 64)
return Impl().rand64();
219 uint64_t gen =
Impl().rand64();
225 return ret & ((uint64_t{1} << bits) - 1);
232 static_assert(Bits >= 0 && Bits <= 64);
233 if constexpr (Bits == 64) {
234 return Impl().rand64();
242 uint64_t gen =
Impl().rand64();
247 constexpr uint64_t MASK = (uint64_t{1} << Bits) - 1;
253 template<std::
integral I>
256 static_assert(std::numeric_limits<I>::max() <= std::numeric_limits<uint64_t>::max());
258 uint64_t maxval = range - 1U;
259 int bits = std::bit_width(maxval);
261 uint64_t
ret =
Impl().randbits(bits);
262 if (
ret <= maxval)
return ret;
269 while (span.size() >= 8) {
270 uint64_t gen =
Impl().rand64();
272 span = span.subspan(8);
274 if (span.size() >= 4) {
275 uint32_t gen =
Impl().rand32();
277 span = span.subspan(4);
279 while (span.size()) {
280 span[0] = std::byte(
Impl().
template randbits<8>());
281 span = span.subspan(1);
286 template<std::
integral I>
289 static_assert(std::numeric_limits<I>::max() <= std::numeric_limits<uint64_t>::max());
290 static constexpr auto BITS = std::bit_width(uint64_t(std::numeric_limits<I>::max()));
291 static_assert(std::numeric_limits<I>::max() == std::numeric_limits<uint64_t>::max() >> (64 - BITS));
292 return I(
Impl().
template randbits<BITS>());
296 template <BasicByte B =
unsigned char>
299 std::vector<B>
ret(len);
305 template <
size_t N, BasicByte B = std::
byte>
308 std::array<B, N>
ret;
314 uint32_t
rand32() noexcept {
return Impl().template randbits<32>(); }
328 template <
typename Tp>
331 return time +
Impl().template rand_uniform_duration<Tp>(range);
338 using Dur =
typename Chrono::duration;
339 return range.count() > 0 ? Dur{
Impl().randrange(range.count())} :
340 range.count() < 0 ? -Dur{
Impl().randrange(-range.count())} :
345 template <StdChronoDuration Dur>
352 return Dur{
Impl().randrange(range.count())};
367 using namespace std::chrono_literals;
369 return std::chrono::duration_cast<std::chrono::microseconds>(unscaled * mean + 0.5us);
374 static constexpr uint64_t
min() noexcept {
return 0; }
375 static constexpr uint64_t
max() noexcept {
return std::numeric_limits<uint64_t>::max(); }
407 std::array<std::byte, 8> buf;
413 void fillrand(std::span<std::byte> output)
noexcept;
429 [[nodiscard]]
constexpr static uint64_t
SplitMix64(uint64_t& seedval)
noexcept
431 uint64_t z = (seedval += 0x9e3779b97f4a7c15);
432 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
433 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
434 return z ^ (z >> 31);
441 constexpr void Reseed(uint64_t seedval)
noexcept
451 const uint64_t result =
std::rotl(s0 + s1, 17) + s0;
#define Assume(val)
Assume is the identity function.
Unrestricted ChaCha20 cipher.
void Keystream(std::span< std::byte > out) noexcept
outputs the keystream to out.
uint64_t rand64() noexcept
Generate a random 64-bit integer.
void RandomSeed() noexcept
void fillrand(std::span< std::byte > output) noexcept
Fill a byte span with random bytes.
void Reseed(const uint256 &seed) noexcept
Reseed with explicit seed (only for testing).
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
Mixin class that provides helper randomness functions.
void fillrand(std::span< std::byte > span) noexcept
Fill a span with random bytes.
static constexpr uint64_t max() noexcept
constexpr RandomMixin() noexcept=default
RandomNumberGenerator auto & Impl() noexcept
Access the underlying generator.
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.
std::array< B, N > randbytes() noexcept
Generate fixed-size random bytes.
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.
Dur randrange(std::common_type_t< Dur > range) noexcept
Generate a uniform random duration in the range [0..max).
uint64_t operator()() noexcept
A concept for RandomMixin-based random number generators.
A concept for C++ std::chrono durations.
void WriteLE32(B *ptr, uint32_t x)
uint64_t ReadLE64(const B *ptr)
void WriteLE64(B *ptr, uint64_t x)
void RandAddEvent(uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
void GetStrongRandBytes(std::span< unsigned char > bytes) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
uint256 GetRandHash() noexcept
Generate a random uint256.
void RandomInit()
Overall design of the RNG and entropy sources.
void GetRandBytes(std::span< unsigned char > bytes) noexcept
Generate random data via the internal PRNG.
double MakeExponentiallyDistributed(uint64_t uniform) noexcept
Given a uniformly random uint64_t, return an exponentially distributed double with mean 1.
auto MakeWritableByteSpan(V &&v) noexcept
static SECP256K1_INLINE uint64_t rotl(const uint64_t x, int k)