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.
251hasher.Write((const unsigned char*)&perf, sizeof(perf));252} while (SteadyClock::now() < stop);254// Produce output from inner state and feed it to outer hasher.255inner_hasher.Finalize(buffer);256hasher.Write(buffer, sizeof(buffer));257// Try to clean up.258inner_hasher.Reset();259memory_cleanse(buffer, sizeof(buffer));260}262#ifndef WIN32263/** Fallback: get 32 bytes of system entropy from /dev/urandom. The most264* compatible way to get cryptographic randomness on UNIX-ish platforms.265*/266[[maybe_unused]] void GetDevURandom(unsigned char *ent32)267{268int f = open("/dev/urandom", O_RDONLY);269if (f == -1) {270RandFailure();271}272int have = 0;273do {274ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);275if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {276close(f);277RandFailure();278}279have += n;280} while (have < NUM_OS_RANDOM_BYTES);281close(f);282}283#endif285/** Get 32 bytes of system entropy. */286void GetOSRand(unsigned char *ent32)287{288#if defined(WIN32)289constexpr uint32_t STATUS_SUCCESS{0x00000000};290NTSTATUS status = BCryptGenRandom(/*hAlgorithm=*/NULL,291/*pbBuffer=*/ent32,292/*cbBuffer=*/NUM_OS_RANDOM_BYTES,293/*dwFlags=*/BCRYPT_USE_SYSTEM_PREFERRED_RNG);295if (status != STATUS_SUCCESS) {296RandFailure();297}298#elif defined(HAVE_GETRANDOM)299/* Linux. From the getrandom(2) man page:300* "If the urandom source has been initialized, reads of up to 256 bytes301* will always return as many bytes as requested and will not be302* interrupted by signals."303*/304if (getrandom(ent32, NUM_OS_RANDOM_BYTES, 0) != NUM_OS_RANDOM_BYTES) {305RandFailure();306}307#elif defined(__OpenBSD__)308/* OpenBSD. From the arc4random(3) man page:309"Use of these functions is encouraged for almost all random number310consumption because the other interfaces are deficient in either311quality, portability, standardization, or availability."312The function call is always successful.313*/314arc4random_buf(ent32, NUM_OS_RANDOM_BYTES);315#elif defined(HAVE_GETENTROPY_RAND) && defined(__APPLE__)316if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {317RandFailure();318}319#elif defined(HAVE_SYSCTL_ARND)320/* FreeBSD, NetBSD and similar. It is possible for the call to return less321* bytes than requested, so need to read in a loop.322*/323static int name[2] = {CTL_KERN, KERN_ARND};324int have = 0;325do {326size_t len = NUM_OS_RANDOM_BYTES - have;327if (sysctl(name, std::size(name), ent32 + have, &len, nullptr, 0) != 0) {328RandFailure();329}330have += len;331} while (have < NUM_OS_RANDOM_BYTES);332#else333/* Fall back to /dev/urandom if there is no specific method implemented to334* get system entropy for this OS.335*/336GetDevURandom(ent32);337#endif338}340class RNGState {341Mutex m_mutex;342/* The RNG state consists of 256 bits of entropy, taken from the output of343* one operation's SHA512 output, and fed as input to the next one.344* Carrying 256 bits of entropy should be sufficient to guarantee345* unpredictability as long as any entropy source was ever unpredictable346* to an attacker. To protect against situations where an attacker might347* observe the RNG's state, fresh entropy is always mixed when348* GetStrongRandBytes is called.349*/350unsigned char m_state[32] GUARDED_BY(m_mutex) = {0};351uint64_t m_counter GUARDED_BY(m_mutex) = 0;352bool m_strongly_seeded GUARDED_BY(m_mutex) = false;354/** If not nullopt, the output of this RNGState is redirected and drawn from here355* (unless always_use_real_rng is passed to MixExtract). */356std::optional<ChaCha20> m_deterministic_prng GUARDED_BY(m_mutex);358Mutex m_events_mutex;359CSHA256 m_events_hasher GUARDED_BY(m_events_mutex);361public:362RNGState() noexcept363{364InitHardwareRand();365}367~RNGState() = default;369void AddEvent(uint32_t event_info) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex)370{371LOCK(m_events_mutex);373m_events_hasher.Write((const unsigned char *)&event_info, sizeof(event_info));374// Get the low four bytes of the performance counter. This translates to roughly the375// subsecond part.376uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);377m_events_hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));378}380/**381* Feed (the hash of) all events added through AddEvent() to hasher.382*/383void SeedEvents(CSHA512& hasher) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex)384{385// We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,386// since we want it to be fast as network peers may be able to trigger it repeatedly.387LOCK(m_events_mutex);389unsigned char events_hash[32];390m_events_hasher.Finalize(events_hash);391hasher.Write(events_hash, 32);393// Re-initialize the hasher with the finalized state to use later.394m_events_hasher.Reset();395m_events_hasher.Write(events_hash, 32);396}398/** Make the output of MixExtract (unless always_use_real_rng) deterministic, with specified seed. */399void MakeDeterministic(const uint256& seed) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)400{401LOCK(m_mutex);402m_deterministic_prng.emplace(MakeByteSpan(seed));403}405/** Extract up to 32 bytes of entropy from the RNG state, mixing in new entropy from hasher.406*407* If this function has never been called with strong_seed = true, false is returned.408*409* If always_use_real_rng is false, and MakeDeterministic has been called before, output410* from the deterministic PRNG instead.411*/412bool MixExtract(unsigned char* out, size_t num, CSHA512&& hasher, bool strong_seed, bool always_use_real_rng) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)413{414assert(num <= 32);415unsigned char buf[64];416static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE, "Buffer needs to have hasher's output size");417bool ret;418{419LOCK(m_mutex);420ret = (m_strongly_seeded |= strong_seed);421// Write the current state of the RNG into the hasher422hasher.Write(m_state, 32);423// Write a new counter number into the state424hasher.Write((const unsigned char*)&m_counter, sizeof(m_counter));425++m_counter;426// Finalize the hasher427hasher.Finalize(buf);428// Store the last 32 bytes of the hash output as new RNG state.429memcpy(m_state, buf + 32, 32);430// Handle requests for deterministic randomness.431if (!always_use_real_rng && m_deterministic_prng.has_value()) [[unlikely]] {432// Overwrite the beginning of buf, which will be used for output.433m_deterministic_prng->Keystream(std::as_writable_bytes(std::span{buf, num}));434// Do not require strong seeding for deterministic output.435ret = true;436}437}438// If desired, copy (up to) the first 32 bytes of the hash output as output.439if (num) {440assert(out != nullptr);441memcpy(out, buf, num);442}443// Best effort cleanup of internal state444hasher.Reset();445memory_cleanse(buf, 64);446return ret;447}448};450RNGState& GetRNGState() noexcept451{452// This idiom relies on the guarantee that static variable are initialized453// on first call, even when multiple parallel calls are permitted.454static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);455return g_rng[0];456}458/* A note on the use of noexcept in the seeding functions below:459*460* None of the RNG code should ever throw any exception.461*/463void SeedTimestamp(CSHA512& hasher) noexcept464{465int64_t perfcounter = GetPerformanceCounter();466hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));467}469void SeedFast(CSHA512& hasher) noexcept470{471unsigned char buffer[32];473// Stack pointer to indirectly commit to thread/callstack474const unsigned char* ptr = buffer;475hasher.Write((const unsigned char*)&ptr, sizeof(ptr));477// Hardware randomness is very fast when available; use it always.478SeedHardwareFast(hasher);480// High-precision timestamp481SeedTimestamp(hasher);482}484void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept485{486unsigned char buffer[32];488// Everything that the 'fast' seeder includes489SeedFast(hasher);491// OS randomness492GetOSRand(buffer);493hasher.Write(buffer, sizeof(buffer));495// Add the events hasher into the mix496rng.SeedEvents(hasher);498// High-precision timestamp.499//500// Note that we also commit to a timestamp in the Fast seeder, so we indirectly commit to a
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.