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.
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#include <script/sigcache.h>8#include <crypto/sha256.h>9#include <pubkey.h>10#include <random.h>11#include <script/interpreter.h>12#include <uint256.h>13#include <util/log.h>15#include <mutex>16#include <shared_mutex>17#include <utility>18#include <vector>20SignatureCache::SignatureCache(const size_t max_size_bytes)21{22uint256 nonce = GetRandHash();23// We want the nonce to be 64 bytes long to force the hasher to process24// this chunk, which makes later hash computations more efficient. We25// just write our 32-byte entropy, and then pad with 'E' for ECDSA and26// 'S' for Schnorr (followed by 0 bytes).27static constexpr unsigned char PADDING_ECDSA[32] = {'E'};28static constexpr unsigned char PADDING_SCHNORR[32] = {'S'};29m_salted_hasher_ecdsa.Write(nonce.begin(), 32);30m_salted_hasher_ecdsa.Write(PADDING_ECDSA, 32);31m_salted_hasher_schnorr.Write(nonce.begin(), 32);32m_salted_hasher_schnorr.Write(PADDING_SCHNORR, 32);34const auto [num_elems, approx_size_bytes] = setValid.setup_bytes(max_size_bytes);35LogInfo("Using %zu MiB out of %zu MiB requested for signature cache, able to store %zu elements",36approx_size_bytes >> 20, max_size_bytes >> 20, num_elems);37}39void SignatureCache::ComputeEntryECDSA(uint256& entry, const uint256& hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) const40{41CSHA256 hasher = m_salted_hasher_ecdsa;42hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(vchSig.data(), vchSig.size()).Finalize(entry.begin());43}45void SignatureCache::ComputeEntrySchnorr(uint256& entry, const uint256& hash, std::span<const unsigned char> sig, const XOnlyPubKey& pubkey) const46{47CSHA256 hasher = m_salted_hasher_schnorr;48hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(sig.data(), sig.size()).Finalize(entry.begin());49}51bool SignatureCache::Get(const uint256& entry, const bool erase)52{53std::shared_lock<std::shared_mutex> lock(cs_sigcache);54return setValid.contains(entry, erase);55}57void SignatureCache::Set(const uint256& entry)58{59std::unique_lock<std::shared_mutex> lock(cs_sigcache);60setValid.insert(entry);61}63bool CachingTransactionSignatureChecker::VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const64{65uint256 entry;66m_signature_cache.ComputeEntryECDSA(entry, sighash, vchSig, pubkey);67if (m_signature_cache.Get(entry, !store))68return true;69if (!TransactionSignatureChecker::VerifyECDSASignature(vchSig, pubkey, sighash))70return false;71if (store)72m_signature_cache.Set(entry);73return true;74}76bool CachingTransactionSignatureChecker::VerifySchnorrSignature(std::span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const77{78uint256 entry;79m_signature_cache.ComputeEntrySchnorr(entry, sighash, sig, pubkey);80if (m_signature_cache.Get(entry, !store)) return true;81if (!TransactionSignatureChecker::VerifySchnorrSignature(sig, pubkey, sighash)) return false;82if (store) m_signature_cache.Set(entry);83return true;84}