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 uint32_t
rand32() noexcept {
return Impl().template randbits<32>(); }
319 template <
typename Tp>
322 return time +
Impl().template rand_uniform_duration<Tp>(range);
329 using Dur =
typename Chrono::duration;
330 return range.count() > 0 ? Dur{
Impl().randrange(range.count())} :
331 range.count() < 0 ? -Dur{
Impl().randrange(-range.count())} :
336 template <StdChronoDuration Dur>
337 Dur
randrange(
typename std::common_type_t<Dur> range)
noexcept
343 return Dur{
Impl().randrange(range.count())};
358 using namespace std::chrono_literals;
360 return std::chrono::duration_cast<std::chrono::microseconds>(unscaled * mean + 0.5us);
365 static constexpr uint64_t
min() noexcept {
return 0; }
366 static constexpr uint64_t
max() noexcept {
return std::numeric_limits<uint64_t>::max(); }
398 std::array<std::byte, 8> buf;
420 [[nodiscard]]
constexpr static uint64_t
SplitMix64(uint64_t& seedval)
noexcept
422 uint64_t z = (seedval += 0x9e3779b97f4a7c15);
423 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
424 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
425 return z ^ (z >> 31);
432 constexpr void Reseed(uint64_t seedval)
noexcept
442 const uint64_t result =
std::rotl(s0 + s1, 17) + s0;
#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
Mixin class that provides helper randomness functions.
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 uint64_t ReadLE64(const unsigned char *ptr)
static void WriteLE32(unsigned char *ptr, uint32_t x)
static void WriteLE64(unsigned char *ptr, uint64_t x)
void GetRandBytes(Span< unsigned char > bytes) noexcept
Generate random data via the internal PRNG.
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
void GetStrongRandBytes(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 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.
unsigned char * UCharCast(char *c)
Span< std::byte > MakeWritableByteSpan(V &&v) noexcept
static SECP256K1_INLINE uint64_t rotl(const uint64_t x, int k)