Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
252/** Generate a random integer in the range [0..range), with range > 0. */253template<std::integral I>254I randrange(I range) noexcept255{256static_assert(std::numeric_limits<I>::max() <= std::numeric_limits<uint64_t>::max());257Assume(range > 0);258uint64_t maxval = range - 1U;259int bits = std::bit_width(maxval);260while (true) {261uint64_t ret = Impl().randbits(bits);262if (ret <= maxval) return ret;263}264}266/** Fill a span with random bytes. */267void fillrand(std::span<std::byte> span) noexcept268{269while (span.size() >= 8) {270uint64_t gen = Impl().rand64();271WriteLE64(span.data(), gen);272span = span.subspan(8);273}274if (span.size() >= 4) {275uint32_t gen = Impl().rand32();276WriteLE32(span.data(), gen);277span = span.subspan(4);278}279while (span.size()) {280span[0] = std::byte(Impl().template randbits<8>());281span = span.subspan(1);282}283}285/** Generate a random integer in its entire (non-negative) range. */286template<std::integral I>287I rand() noexcept288{289static_assert(std::numeric_limits<I>::max() <= std::numeric_limits<uint64_t>::max());290static constexpr auto BITS = std::bit_width(uint64_t(std::numeric_limits<I>::max()));291static_assert(std::numeric_limits<I>::max() == std::numeric_limits<uint64_t>::max() >> (64 - BITS));292return I(Impl().template randbits<BITS>());293}295/** Generate random bytes. */296template <BasicByte B = unsigned char>297std::vector<B> randbytes(size_t len) noexcept298{299std::vector<B> ret(len);300Impl().fillrand(MakeWritableByteSpan(ret));301return ret;302}304/** Generate fixed-size random bytes. */305template <size_t N, BasicByte B = std::byte>306std::array<B, N> randbytes() noexcept307{308std::array<B, N> ret;309Impl().fillrand(MakeWritableByteSpan(ret));310return ret;311}313/** Generate a random 32-bit integer. */314uint32_t rand32() noexcept { return Impl().template randbits<32>(); }316/** generate a random uint256. */317uint256 rand256() noexcept318{319uint256 ret;320Impl().fillrand(MakeWritableByteSpan(ret));321return ret;322}324/** Generate a random boolean. */325bool randbool() noexcept { return Impl().template randbits<1>(); }327/** Return the time point advanced by a uniform random duration. */328template <typename Tp>329Tp rand_uniform_delay(const Tp& time, typename Tp::duration range) noexcept330{331return time + Impl().template rand_uniform_duration<Tp>(range);332}334/** Generate a uniform random duration in the range from 0 (inclusive) to range (exclusive). */335template <typename Chrono> requires StdChronoDuration<typename Chrono::duration>336typename Chrono::duration rand_uniform_duration(typename Chrono::duration range) noexcept337{338using Dur = typename Chrono::duration;339return range.count() > 0 ? /* interval [0..range) */ Dur{Impl().randrange(range.count())} :340range.count() < 0 ? /* interval (range..0] */ -Dur{Impl().randrange(-range.count())} :341/* interval [0..0] */ Dur{0};342};344/** Generate a uniform random duration in the range [0..max). Precondition: max.count() > 0 */345template <StdChronoDuration Dur>346Dur randrange(std::common_type_t<Dur> range) noexcept347// Having the compiler infer the template argument from the function argument348// is dangerous, because the desired return value generally has a different349// type than the function argument. So std::common_type is used to force the350// call site to specify the type of the return value.351{352return Dur{Impl().randrange(range.count())};353}355/**356* Return a duration sampled from an exponential distribution357* (https://en.wikipedia.org/wiki/Exponential_distribution). Successive events358* whose intervals are distributed according to this form a memoryless Poisson359* process. This should be used for repeated network events (e.g. sending a360* certain type of message) to minimize leaking information to observers.361*362* The probability of an event occurring before time x is 1 - e^-(x/a) where a363* is the average interval between events.364* */365std::chrono::microseconds rand_exp_duration(std::chrono::microseconds mean) noexcept366{367using namespace std::chrono_literals;368auto unscaled = MakeExponentiallyDistributed(Impl().rand64());369return std::chrono::duration_cast<std::chrono::microseconds>(unscaled * mean + 0.5us);370}372// Compatibility with the UniformRandomBitGenerator concept373typedef uint64_t result_type;374static constexpr uint64_t min() noexcept { return 0; }375static constexpr uint64_t max() noexcept { return std::numeric_limits<uint64_t>::max(); }376inline uint64_t operator()() noexcept { return Impl().rand64(); }377};379/**380* Fast randomness source. This is seeded once with secure random data, but381* is completely deterministic and does not gather more entropy after that.382*383* This class is not thread-safe.384*/385class FastRandomContext : public RandomMixin<FastRandomContext>386{387private:388bool requires_seed;389ChaCha20 rng;391void RandomSeed() noexcept;393public:394/** Construct a FastRandomContext with GetRandHash()-based entropy (or zero key if fDeterministic). */395explicit FastRandomContext(bool fDeterministic = false) noexcept;397/** Initialize with explicit seed (only for testing) */398explicit FastRandomContext(const uint256& seed) noexcept;400/** Reseed with explicit seed (only for testing). */401void Reseed(const uint256& seed) noexcept;403/** Generate a random 64-bit integer. */404uint64_t rand64() noexcept405{406if (requires_seed) RandomSeed();407std::array<std::byte, 8> buf;408rng.Keystream(buf);409return ReadLE64(buf.data());410}412/** Fill a byte span with random bytes. This overrides the RandomMixin version. */413void fillrand(std::span<std::byte> output) noexcept;414};416/** xoroshiro128++ PRNG. Extremely fast, not appropriate for cryptographic purposes.417*418* Memory footprint is very small, period is 2^128 - 1.419* This class is not thread-safe.420*421* Reference implementation available at https://prng.di.unimi.it/xoroshiro128plusplus.c422* See https://prng.di.unimi.it/423*/424class InsecureRandomContext : public RandomMixin<InsecureRandomContext>425{426uint64_t m_s0;427uint64_t m_s1;429[[nodiscard]] constexpr static uint64_t SplitMix64(uint64_t& seedval) noexcept430{431uint64_t z = (seedval += 0x9e3779b97f4a7c15);432z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;433z = (z ^ (z >> 27)) * 0x94d049bb133111eb;434return z ^ (z >> 31);435}437public:438constexpr explicit InsecureRandomContext(uint64_t seedval) noexcept439: m_s0(SplitMix64(seedval)), m_s1(SplitMix64(seedval)) {}441constexpr void Reseed(uint64_t seedval) noexcept442{443FlushCache();444m_s0 = SplitMix64(seedval);445m_s1 = SplitMix64(seedval);446}448constexpr uint64_t rand64() noexcept449{450uint64_t s0 = m_s0, s1 = m_s1;451const uint64_t result = std::rotl(s0 + s1, 17) + s0;452s1 ^= s0;453m_s0 = std::rotl(s0, 49) ^ s1 ^ (s1 << 21);454m_s1 = std::rotl(s1, 28);455return result;456}457};460/* ==================== CONVENIENCE FUNCTIONS FOR COMMONLY USED RANDOMNESS ==================== */462/** Generate a random uint256. */463inline uint256 GetRandHash() noexcept464{465uint256 hash;466GetRandBytes(hash);467return hash;468}470/* ============================= MISCELLANEOUS TEST-ONLY FUNCTIONS ============================= */472/** Check that OS randomness is available and returning the requested number473* of bytes.474*/475bool Random_SanityCheck();477#endif // BITCOIN_RANDOM_H