Bitcoin Core 22.99.0
P2P Digital Currency
sigcache.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2020 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
20namespace {
26class CSignatureCache
27{
28private:
30 CSHA256 m_salted_hasher_ecdsa;
31 CSHA256 m_salted_hasher_schnorr;
33 map_type setValid;
34 std::shared_mutex cs_sigcache;
35
36public:
37 CSignatureCache()
38 {
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 static constexpr unsigned char PADDING_ECDSA[32] = {'E'};
45 static constexpr unsigned char PADDING_SCHNORR[32] = {'S'};
46 m_salted_hasher_ecdsa.Write(nonce.begin(), 32);
47 m_salted_hasher_ecdsa.Write(PADDING_ECDSA, 32);
48 m_salted_hasher_schnorr.Write(nonce.begin(), 32);
49 m_salted_hasher_schnorr.Write(PADDING_SCHNORR, 32);
50 }
51
52 void
53 ComputeEntryECDSA(uint256& entry, const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) const
54 {
55 CSHA256 hasher = m_salted_hasher_ecdsa;
56 hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(vchSig.data(), vchSig.size()).Finalize(entry.begin());
57 }
58
59 void
60 ComputeEntrySchnorr(uint256& entry, const uint256 &hash, Span<const unsigned char> sig, const XOnlyPubKey& pubkey) const
61 {
62 CSHA256 hasher = m_salted_hasher_schnorr;
63 hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(sig.data(), sig.size()).Finalize(entry.begin());
64 }
65
66 bool
67 Get(const uint256& entry, const bool erase)
68 {
69 std::shared_lock<std::shared_mutex> lock(cs_sigcache);
70 return setValid.contains(entry, erase);
71 }
72
73 void Set(const uint256& entry)
74 {
75 std::unique_lock<std::shared_mutex> lock(cs_sigcache);
76 setValid.insert(entry);
77 }
78 uint32_t setup_bytes(size_t n)
79 {
80 return setValid.setup_bytes(n);
81 }
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*/
90static CSignatureCache signatureCache;
91} // namespace
92
93// To be called once in AppInitMain/BasicTestingSetup to initialize the
94// signatureCache.
96{
97 // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero,
98 // setup_bytes creates the minimum possible cache (2 elements).
99 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 size_t nElems = signatureCache.setup_bytes(nMaxCacheSize);
101 LogPrintf("Using %zu MiB out of %zu/2 requested for signature cache, able to store %zu elements\n",
102 (nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);
103}
104
105bool CachingTransactionSignatureChecker::VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
106{
107 uint256 entry;
108 signatureCache.ComputeEntryECDSA(entry, sighash, vchSig, pubkey);
109 if (signatureCache.Get(entry, !store))
110 return true;
112 return false;
113 if (store)
114 signatureCache.Set(entry);
115 return true;
116}
117
119{
120 uint256 entry;
121 signatureCache.ComputeEntrySchnorr(entry, sighash, sig, pubkey);
122 if (signatureCache.Get(entry, !store)) return true;
123 if (!TransactionSignatureChecker::VerifySchnorrSignature(sig, pubkey, sighash)) return false;
124 if (store) signatureCache.Set(entry);
125 return true;
126}
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: system.cpp:596
An encapsulated public key.
Definition: pubkey.h:33
const unsigned char * data() const
Definition: pubkey.h:112
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:111
A hasher class for SHA-256.
Definition: sha256.h:14
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:663
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:637
bool VerifySchnorrSignature(Span< const unsigned char > sig, const XOnlyPubKey &pubkey, const uint256 &sighash) const override
Definition: sigcache.cpp:118
bool VerifyECDSASignature(const std::vector< unsigned char > &vchSig, const CPubKey &vchPubKey, const uint256 &sighash) const override
Definition: sigcache.cpp:105
cache implements a cache with properties similar to a cuckoo-set.
Definition: cuckoocache.h:159
virtual bool VerifySchnorrSignature(Span< const unsigned char > sig, const XOnlyPubKey &pubkey, const uint256 &sighash) const
virtual bool VerifyECDSASignature(const std::vector< unsigned char > &vchSig, const CPubKey &vchPubKey, const uint256 &sighash) const
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:93
constexpr std::size_t size() const noexcept
Definition: span.h:182
constexpr C * data() const noexcept
Definition: span.h:169
static constexpr size_t size()
Definition: pubkey.h:277
const unsigned char * data() const
Definition: pubkey.h:276
unsigned char * begin()
Definition: uint256.h:58
256-bit opaque blob.
Definition: uint256.h:124
#define LogPrintf(...)
Definition: logging.h:187
unsigned int nonce
Definition: miner_tests.cpp:54
static unsigned const char sighash[]
Definition: sighash.json.h:2
uint256 GetRandHash() noexcept
Definition: random.cpp:601
void InitSignatureCache()
Definition: sigcache.cpp:95
static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE
Definition: sigcache.h:18
static const int64_t MAX_MAX_SIG_CACHE_SIZE
Definition: sigcache.h:20
ArgsManager gArgs
Definition: system.cpp:85