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.
251if (!j12) ++j13;253WriteLE32(c + 0, x0);254WriteLE32(c + 4, x1);255WriteLE32(c + 8, x2);256WriteLE32(c + 12, x3);257WriteLE32(c + 16, x4);258WriteLE32(c + 20, x5);259WriteLE32(c + 24, x6);260WriteLE32(c + 28, x7);261WriteLE32(c + 32, x8);262WriteLE32(c + 36, x9);263WriteLE32(c + 40, x10);264WriteLE32(c + 44, x11);265WriteLE32(c + 48, x12);266WriteLE32(c + 52, x13);267WriteLE32(c + 56, x14);268WriteLE32(c + 60, x15);270if (blocks == 1) {271input[8] = j12;272input[9] = j13;273return;274}275blocks -= 1;276c += BLOCKLEN;277m += BLOCKLEN;278}279}281void ChaCha20::Keystream(std::span<std::byte> out) noexcept282{283if (out.empty()) return;284if (m_bufleft) {285unsigned reuse = std::min<size_t>(m_bufleft, out.size());286std::copy(m_buffer.end() - m_bufleft, m_buffer.end() - m_bufleft + reuse, out.begin());287m_bufleft -= reuse;288out = out.subspan(reuse);289}290if (out.size() >= m_aligned.BLOCKLEN) {291size_t blocks = out.size() / m_aligned.BLOCKLEN;292m_aligned.Keystream(out.first(blocks * m_aligned.BLOCKLEN));293out = out.subspan(blocks * m_aligned.BLOCKLEN);294}295if (!out.empty()) {296m_aligned.Keystream(m_buffer);297std::copy(m_buffer.begin(), m_buffer.begin() + out.size(), out.begin());298m_bufleft = m_aligned.BLOCKLEN - out.size();299}300}302void ChaCha20::Crypt(std::span<const std::byte> input, std::span<std::byte> output) noexcept303{304assert(input.size() == output.size());306if (!input.size()) return;307if (m_bufleft) {308unsigned reuse = std::min<size_t>(m_bufleft, input.size());309for (unsigned i = 0; i < reuse; i++) {310output[i] = input[i] ^ m_buffer[m_aligned.BLOCKLEN - m_bufleft + i];311}312m_bufleft -= reuse;313output = output.subspan(reuse);314input = input.subspan(reuse);315}316if (input.size() >= m_aligned.BLOCKLEN) {317size_t blocks = input.size() / m_aligned.BLOCKLEN;318m_aligned.Crypt(input.first(blocks * m_aligned.BLOCKLEN), output.first(blocks * m_aligned.BLOCKLEN));319output = output.subspan(blocks * m_aligned.BLOCKLEN);320input = input.subspan(blocks * m_aligned.BLOCKLEN);321}322if (!input.empty()) {323m_aligned.Keystream(m_buffer);324for (unsigned i = 0; i < input.size(); i++) {325output[i] = input[i] ^ m_buffer[i];326}327m_bufleft = m_aligned.BLOCKLEN - input.size();328}329}331ChaCha20::~ChaCha20()332{333memory_cleanse(m_buffer.data(), m_buffer.size());334}336void ChaCha20::SetKey(std::span<const std::byte> key) noexcept337{338m_aligned.SetKey(key);339m_bufleft = 0;340memory_cleanse(m_buffer.data(), m_buffer.size());341}343FSChaCha20::FSChaCha20(std::span<const std::byte> key, uint32_t rekey_interval) noexcept :344m_chacha20(key), m_rekey_interval(rekey_interval)345{346assert(key.size() == KEYLEN);347}349void FSChaCha20::Crypt(std::span<const std::byte> input, std::span<std::byte> output) noexcept350{351assert(input.size() == output.size());353// Invoke internal stream cipher for actual encryption/decryption.354m_chacha20.Crypt(input, output);356// Rekey after m_rekey_interval encryptions/decryptions.357if (++m_chunk_counter == m_rekey_interval) {358// Get new key from the stream cipher.359std::byte new_key[KEYLEN];360m_chacha20.Keystream(new_key);361// Update its key.362m_chacha20.SetKey(new_key);363// Wipe the key (a copy remains inside m_chacha20, where it'll be wiped on the next rekey364// or on destruction).365memory_cleanse(new_key, sizeof(new_key));366// Set the nonce for the new section of output.367m_chacha20.Seek({0, ++m_rekey_counter}, 0);368// Reset the chunk counter.369m_chunk_counter = 0;370}371}
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.