Inside Bitcoin
Opening the selected file…
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.
1// Copyright (c) 2009-2010 Satoshi Nakamoto2// Copyright (c) 2009-present The Bitcoin Core developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.6#ifndef BITCOIN_HASH_H7#define BITCOIN_HASH_H9#include <attributes.h>10#include <crypto/common.h>11#include <crypto/ripemd160.h>12#include <crypto/sha256.h>13#include <prevector.h>14#include <serialize.h>15#include <span.h>16#include <support/cleanse.h>17#include <uint256.h>19#include <string>20#include <vector>22/** A BIP32 chain code. Cleansed on destruction. */23class ChainCode : public base_blob<256> {24public:25constexpr ChainCode() = default;26constexpr explicit ChainCode(std::span<const unsigned char> vch) : base_blob<256>(vch) {}27constexpr explicit ChainCode(const base_blob<256>& b) : base_blob<256>(b) {}28~ChainCode() { memory_cleanse(data(), size()); }29};31/** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */32class CHash256 {33private:34CSHA256 sha;35public:36static constexpr size_t OUTPUT_SIZE{CSHA256::OUTPUT_SIZE};38void Finalize(std::span<unsigned char> output) {39assert(output.size() == OUTPUT_SIZE);40unsigned char buf[CSHA256::OUTPUT_SIZE];41sha.Finalize(buf);42sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data());43}45CHash256& Write(std::span<const unsigned char> input) {46sha.Write(input.data(), input.size());47return *this;48}50CHash256& Reset() {51sha.Reset();52return *this;53}54};56/** A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160). */57class CHash160 {58private:59CSHA256 sha;60public:61static constexpr size_t OUTPUT_SIZE{CRIPEMD160::OUTPUT_SIZE};63void Finalize(std::span<unsigned char> output) {64assert(output.size() == OUTPUT_SIZE);65unsigned char buf[CSHA256::OUTPUT_SIZE];66sha.Finalize(buf);67CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data());68}70CHash160& Write(std::span<const unsigned char> input) {71sha.Write(input.data(), input.size());72return *this;73}75CHash160& Reset() {76sha.Reset();77return *this;78}79};81/** Compute the 256-bit hash of an object. */82template<typename T>83inline uint256 Hash(const T& in1)84{85uint256 result;86CHash256().Write(MakeUCharSpan(in1)).Finalize(result);87return result;88}90/** Compute the 256-bit hash of the concatenation of two objects. */91template<typename T1, typename T2>92inline uint256 Hash(const T1& in1, const T2& in2) {93uint256 result;94CHash256().Write(MakeUCharSpan(in1)).Write(MakeUCharSpan(in2)).Finalize(result);95return result;96}98/** Compute the 160-bit hash an object. */99template<typename T1>100inline uint160 Hash160(const T1& in1)101{102uint160 result;103CHash160().Write(MakeUCharSpan(in1)).Finalize(result);104return result;105}107/** A writer stream (for serialization) that computes a 256-bit hash. */108class HashWriter109{110private:111CSHA256 ctx;113public:114void write(std::span<const std::byte> src)115{116ctx.Write(UCharCast(src.data()), src.size());117}119/** Compute the double-SHA256 hash of all data written to this object.120*121* Invalidates this object.122*/123uint256 GetHash() {124uint256 result;125ctx.Finalize(result.begin());126ctx.Reset().Write(result.begin(), CSHA256::OUTPUT_SIZE).Finalize(result.begin());127return result;128}130/** Compute the SHA256 hash of all data written to this object.131*132* Invalidates this object.133*/134uint256 GetSHA256() {135uint256 result;136ctx.Finalize(result.begin());137return result;138}140/**141* Returns the first 64 bits from the resulting hash.142*/143inline uint64_t GetCheapHash() {144uint256 result = GetHash();145return ReadLE64(result.begin());146}148template <typename T>149HashWriter& operator<<(const T& obj)150{151::Serialize(*this, obj);152return *this;153}154};156/** Reads data from an underlying stream, while hashing the read data. */157template <typename Source>158class HashVerifier : public HashWriter159{160private:161Source& m_source;163public:164explicit HashVerifier(Source& source LIFETIMEBOUND) : m_source{source} {}166void read(std::span<std::byte> dst)167{168m_source.read(dst);169this->write(dst);170}172void ignore(size_t num_bytes)173{174std::byte data[1024];175while (num_bytes > 0) {176size_t now = std::min<size_t>(num_bytes, 1024);177read({data, now});178num_bytes -= now;179}180}182template <typename T>183HashVerifier<Source>& operator>>(T&& obj)184{185::Unserialize(*this, obj);186return *this;187}188};190/** Writes data to an underlying source stream, while hashing the written data. */191template <typename Source>192class HashedSourceWriter : public HashWriter193{194private:195Source& m_source;197public:198explicit HashedSourceWriter(Source& source LIFETIMEBOUND) : HashWriter{}, m_source{source} {}200void write(std::span<const std::byte> src)201{202m_source.write(src);203HashWriter::write(src);204}206template <typename T>207HashedSourceWriter& operator<<(const T& obj)208{209::Serialize(*this, obj);210return *this;211}212};214/** Single-SHA256 a 32-byte input (represented as uint256). */215[[nodiscard]] uint256 SHA256Uint256(const uint256& input);217unsigned int MurmurHash3(unsigned int nHashSeed, std::span<const unsigned char> vDataToHash);219void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);221/** Return a HashWriter primed for tagged hashes (as specified in BIP 340).222*223* The returned object will have SHA256(tag) written to it twice (= 64 bytes).224* A tagged hash can be computed by feeding the message into this object, and225* then calling HashWriter::GetSHA256().226*/227HashWriter TaggedHash(const std::string& tag);229/** Compute the 160-bit RIPEMD-160 hash of an array. */230inline uint160 RIPEMD160(std::span<const unsigned char> data)231{232uint160 result;233CRIPEMD160().Write(data.data(), data.size()).Finalize(result.begin());234return result;235}237#endif // BITCOIN_HASH_H