Bitcoin Core  27.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-2022 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 <crypto/sha256.h>
9 #include <logging.h>
10 #include <pubkey.h>
11 #include <random.h>
12 #include <script/interpreter.h>
13 #include <span.h>
14 #include <uint256.h>
15 
16 #include <mutex>
17 #include <shared_mutex>
18 #include <vector>
19 
20 SignatureCache::SignatureCache(const size_t max_size_bytes)
21 {
23  // We want the nonce to be 64 bytes long to force the hasher to process
24  // this chunk, which makes later hash computations more efficient. We
25  // just write our 32-byte entropy, and then pad with 'E' for ECDSA and
26  // 'S' for Schnorr (followed by 0 bytes).
27  static constexpr unsigned char PADDING_ECDSA[32] = {'E'};
28  static constexpr unsigned char PADDING_SCHNORR[32] = {'S'};
29  m_salted_hasher_ecdsa.Write(nonce.begin(), 32);
30  m_salted_hasher_ecdsa.Write(PADDING_ECDSA, 32);
31  m_salted_hasher_schnorr.Write(nonce.begin(), 32);
32  m_salted_hasher_schnorr.Write(PADDING_SCHNORR, 32);
33 
34  const auto [num_elems, approx_size_bytes] = setValid.setup_bytes(max_size_bytes);
35  LogPrintf("Using %zu MiB out of %zu MiB requested for signature cache, able to store %zu elements\n",
36  approx_size_bytes >> 20, max_size_bytes >> 20, num_elems);
37 }
38 
39 void SignatureCache::ComputeEntryECDSA(uint256& entry, const uint256& hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) const
40 {
42  hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(vchSig.data(), vchSig.size()).Finalize(entry.begin());
43 }
44 
46 {
48  hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(sig.data(), sig.size()).Finalize(entry.begin());
49 }
50 
51 bool SignatureCache::Get(const uint256& entry, const bool erase)
52 {
53  std::shared_lock<std::shared_mutex> lock(cs_sigcache);
54  return setValid.contains(entry, erase);
55 }
56 
57 void SignatureCache::Set(const uint256& entry)
58 {
59  std::unique_lock<std::shared_mutex> lock(cs_sigcache);
60  setValid.insert(entry);
61 }
62 
63 bool CachingTransactionSignatureChecker::VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
64 {
65  uint256 entry;
66  m_signature_cache.ComputeEntryECDSA(entry, sighash, vchSig, pubkey);
67  if (m_signature_cache.Get(entry, !store))
68  return true;
69  if (!TransactionSignatureChecker::VerifyECDSASignature(vchSig, pubkey, sighash))
70  return false;
71  if (store)
72  m_signature_cache.Set(entry);
73  return true;
74 }
75 
77 {
78  uint256 entry;
79  m_signature_cache.ComputeEntrySchnorr(entry, sighash, sig, pubkey);
80  if (m_signature_cache.Get(entry, !store)) return true;
81  if (!TransactionSignatureChecker::VerifySchnorrSignature(sig, pubkey, sighash)) return false;
82  if (store) m_signature_cache.Set(entry);
83  return true;
84 }
An encapsulated public key.
Definition: pubkey.h:34
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:112
const unsigned char * data() const
Definition: pubkey.h:113
A hasher class for SHA-256.
Definition: sha256.h:14
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:726
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:700
bool VerifySchnorrSignature(Span< const unsigned char > sig, const XOnlyPubKey &pubkey, const uint256 &sighash) const override
Definition: sigcache.cpp:76
SignatureCache & m_signature_cache
Definition: sigcache.h:67
bool VerifyECDSASignature(const std::vector< unsigned char > &vchSig, const CPubKey &vchPubKey, const uint256 &sighash) const override
Definition: sigcache.cpp:63
void insert(Element e)
insert loops at most depth_limit times trying to insert a hash at various locations in the table via ...
Definition: cuckoocache.h:397
bool contains(const Element &e, const bool erase) const
contains iterates through the hash locations for a given element and checks to see if it is present.
Definition: cuckoocache.h:474
std::pair< uint32_t, size_t > setup_bytes(size_t bytes)
setup_bytes is a convenience function which accounts for internal memory usage when deciding how many...
Definition: cuckoocache.h:364
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
SignatureCache(size_t max_size_bytes)
Definition: sigcache.cpp:20
CSHA256 m_salted_hasher_schnorr
Definition: sigcache.h:43
void ComputeEntrySchnorr(uint256 &entry, const uint256 &hash, Span< const unsigned char > sig, const XOnlyPubKey &pubkey) const
Definition: sigcache.cpp:45
void ComputeEntryECDSA(uint256 &entry, const uint256 &hash, const std::vector< unsigned char > &vchSig, const CPubKey &pubkey) const
Definition: sigcache.cpp:39
map_type setValid
Definition: sigcache.h:45
std::shared_mutex cs_sigcache
Definition: sigcache.h:46
CSHA256 m_salted_hasher_ecdsa
Entries are SHA256(nonce || 'E' or 'S' || 31 zero bytes || signature hash || public key || signature)...
Definition: sigcache.h:42
bool Get(const uint256 &entry, const bool erase)
Definition: sigcache.cpp:51
void Set(const uint256 &entry)
Definition: sigcache.cpp:57
constexpr std::size_t size() const noexcept
Definition: span.h:187
constexpr C * data() const noexcept
Definition: span.h:174
static constexpr size_t size()
Definition: pubkey.h:293
const unsigned char * data() const
Definition: pubkey.h:294
constexpr unsigned char * begin()
Definition: uint256.h:68
256-bit opaque blob.
Definition: uint256.h:106
#define LogPrintf(...)
Definition: logging.h:244
unsigned int nonce
Definition: miner_tests.cpp:75
uint256 GetRandHash() noexcept
Generate a random uint256.
Definition: random.h:454