Branch data Line data Source code
# 1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto
# 2 : : // Copyright (c) 2009-2021 The Bitcoin Core developers
# 3 : : // Distributed under the MIT software license, see the accompanying
# 4 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
# 5 : :
# 6 : : #include <script/sigcache.h>
# 7 : :
# 8 : : #include <pubkey.h>
# 9 : : #include <random.h>
# 10 : : #include <uint256.h>
# 11 : : #include <util/system.h>
# 12 : :
# 13 : : #include <cuckoocache.h>
# 14 : :
# 15 : : #include <algorithm>
# 16 : : #include <mutex>
# 17 : : #include <shared_mutex>
# 18 : : #include <vector>
# 19 : :
# 20 : : namespace {
# 21 : : /**
# 22 : : * Valid signature cache, to avoid doing expensive ECDSA signature checking
# 23 : : * twice for every transaction (once when accepted into memory pool, and
# 24 : : * again when accepted into the block chain)
# 25 : : */
# 26 : : class CSignatureCache
# 27 : : {
# 28 : : private:
# 29 : : //! Entries are SHA256(nonce || 'E' or 'S' || 31 zero bytes || signature hash || public key || signature):
# 30 : : CSHA256 m_salted_hasher_ecdsa;
# 31 : : CSHA256 m_salted_hasher_schnorr;
# 32 : : typedef CuckooCache::cache<uint256, SignatureCacheHasher> map_type;
# 33 : : map_type setValid;
# 34 : : std::shared_mutex cs_sigcache;
# 35 : :
# 36 : : public:
# 37 : : CSignatureCache()
# 38 : 828 : {
# 39 : 828 : uint256 nonce = GetRandHash();
# 40 : : // We want the nonce to be 64 bytes long to force the hasher to process
# 41 : : // this chunk, which makes later hash computations more efficient. We
# 42 : : // just write our 32-byte entropy, and then pad with 'E' for ECDSA and
# 43 : : // 'S' for Schnorr (followed by 0 bytes).
# 44 : 828 : static constexpr unsigned char PADDING_ECDSA[32] = {'E'};
# 45 : 828 : static constexpr unsigned char PADDING_SCHNORR[32] = {'S'};
# 46 : 828 : m_salted_hasher_ecdsa.Write(nonce.begin(), 32);
# 47 : 828 : m_salted_hasher_ecdsa.Write(PADDING_ECDSA, 32);
# 48 : 828 : m_salted_hasher_schnorr.Write(nonce.begin(), 32);
# 49 : 828 : m_salted_hasher_schnorr.Write(PADDING_SCHNORR, 32);
# 50 : 828 : }
# 51 : :
# 52 : : void
# 53 : : ComputeEntryECDSA(uint256& entry, const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) const
# 54 : 220447 : {
# 55 : 220447 : CSHA256 hasher = m_salted_hasher_ecdsa;
# 56 : 220447 : hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(vchSig.data(), vchSig.size()).Finalize(entry.begin());
# 57 : 220447 : }
# 58 : :
# 59 : : void
# 60 : : ComputeEntrySchnorr(uint256& entry, const uint256 &hash, Span<const unsigned char> sig, const XOnlyPubKey& pubkey) const
# 61 : 13269 : {
# 62 : 13269 : CSHA256 hasher = m_salted_hasher_schnorr;
# 63 : 13269 : hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(sig.data(), sig.size()).Finalize(entry.begin());
# 64 : 13269 : }
# 65 : :
# 66 : : bool
# 67 : : Get(const uint256& entry, const bool erase)
# 68 : 234134 : {
# 69 : 234134 : std::shared_lock<std::shared_mutex> lock(cs_sigcache);
# 70 : 234134 : return setValid.contains(entry, erase);
# 71 : 234134 : }
# 72 : :
# 73 : : void Set(const uint256& entry)
# 74 : 17045 : {
# 75 : 17045 : std::unique_lock<std::shared_mutex> lock(cs_sigcache);
# 76 : 17045 : setValid.insert(entry);
# 77 : 17045 : }
# 78 : : uint32_t setup_bytes(size_t n)
# 79 : 1629 : {
# 80 : 1629 : return setValid.setup_bytes(n);
# 81 : 1629 : }
# 82 : : };
# 83 : :
# 84 : : /* In previous versions of this code, signatureCache was a local static variable
# 85 : : * in CachingTransactionSignatureChecker::VerifySignature. We initialize
# 86 : : * signatureCache outside of VerifySignature to avoid the atomic operation per
# 87 : : * call overhead associated with local static variables even though
# 88 : : * signatureCache could be made local to VerifySignature.
# 89 : : */
# 90 : : static CSignatureCache signatureCache;
# 91 : : } // namespace
# 92 : :
# 93 : : // To be called once in AppInitMain/BasicTestingSetup to initialize the
# 94 : : // signatureCache.
# 95 : : void InitSignatureCache()
# 96 : 1629 : {
# 97 : : // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero,
# 98 : : // setup_bytes creates the minimum possible cache (2 elements).
# 99 : 1629 : size_t nMaxCacheSize = std::min(std::max((int64_t)0, gArgs.GetIntArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20);
# 100 : 1629 : size_t nElems = signatureCache.setup_bytes(nMaxCacheSize);
# 101 : 1629 : LogPrintf("Using %zu MiB out of %zu/2 requested for signature cache, able to store %zu elements\n",
# 102 : 1629 : (nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);
# 103 : 1629 : }
# 104 : :
# 105 : : bool CachingTransactionSignatureChecker::VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
# 106 : 220565 : {
# 107 : 220565 : uint256 entry;
# 108 : 220565 : signatureCache.ComputeEntryECDSA(entry, sighash, vchSig, pubkey);
# 109 [ + + ]: 220565 : if (signatureCache.Get(entry, !store))
# 110 : 139030 : return true;
# 111 [ + + ]: 81535 : if (!TransactionSignatureChecker::VerifyECDSASignature(vchSig, pubkey, sighash))
# 112 : 743 : return false;
# 113 [ + + ]: 80792 : if (store)
# 114 : 16587 : signatureCache.Set(entry);
# 115 : 80792 : return true;
# 116 : 81535 : }
# 117 : :
# 118 : : bool CachingTransactionSignatureChecker::VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const
# 119 : 13269 : {
# 120 : 13269 : uint256 entry;
# 121 : 13269 : signatureCache.ComputeEntrySchnorr(entry, sighash, sig, pubkey);
# 122 [ + + ]: 13269 : if (signatureCache.Get(entry, !store)) return true;
# 123 [ + + ]: 8101 : if (!TransactionSignatureChecker::VerifySchnorrSignature(sig, pubkey, sighash)) return false;
# 124 [ + + ]: 7962 : if (store) signatureCache.Set(entry);
# 125 : 7962 : return true;
# 126 : 8101 : }
|