@@ -22,8 +22,9 @@ namespace {
2222class CSignatureCache
2323{
2424private:
25- // ! Entries are SHA256(nonce || signature hash || public key || signature):
26- CSHA256 m_salted_hasher;
25+ // ! Entries are SHA256(nonce || 'E' or 'S' || 31 zero bytes || signature hash || public key || signature):
26+ CSHA256 m_salted_hasher_ecdsa;
27+ CSHA256 m_salted_hasher_schnorr;
2728 typedef CuckooCache::cache<uint256, SignatureCacheHasher> map_type;
2829 map_type setValid;
2930 boost::shared_mutex cs_sigcache;
@@ -34,18 +35,30 @@ class CSignatureCache
3435 uint256 nonce = GetRandHash ();
3536 // We want the nonce to be 64 bytes long to force the hasher to process
3637 // this chunk, which makes later hash computations more efficient. We
37- // just write our 32-byte entropy twice to fill the 64 bytes.
38- m_salted_hasher.Write (nonce.begin (), 32 );
39- m_salted_hasher.Write (nonce.begin (), 32 );
38+ // just write our 32-byte entropy, and then pad with 'E' for ECDSA and
39+ // 'S' for Schnorr (followed by 0 bytes).
40+ static constexpr unsigned char PADDING_ECDSA[32 ] = {' E' };
41+ static constexpr unsigned char PADDING_SCHNORR[32 ] = {' S' };
42+ m_salted_hasher_ecdsa.Write (nonce.begin (), 32 );
43+ m_salted_hasher_ecdsa.Write (PADDING_ECDSA, 32 );
44+ m_salted_hasher_schnorr.Write (nonce.begin (), 32 );
45+ m_salted_hasher_schnorr.Write (PADDING_SCHNORR, 32 );
4046 }
4147
4248 void
4349 ComputeEntryECDSA (uint256& entry, const uint256 &hash, const std::vector<unsigned char >& vchSig, const CPubKey& pubkey)
4450 {
45- CSHA256 hasher = m_salted_hasher ;
51+ CSHA256 hasher = m_salted_hasher_ecdsa ;
4652 hasher.Write (hash.begin (), 32 ).Write (&pubkey[0 ], pubkey.size ()).Write (&vchSig[0 ], vchSig.size ()).Finalize (entry.begin ());
4753 }
4854
55+ void
56+ ComputeEntrySchnorr (uint256& entry, const uint256 &hash, Span<const unsigned char > sig, const XOnlyPubKey& pubkey)
57+ {
58+ CSHA256 hasher = m_salted_hasher_schnorr;
59+ hasher.Write (hash.begin (), 32 ).Write (&pubkey[0 ], pubkey.size ()).Write (sig.data (), sig.size ()).Finalize (entry.begin ());
60+ }
61+
4962 bool
5063 Get (const uint256& entry, const bool erase)
5164 {
@@ -97,3 +110,13 @@ bool CachingTransactionSignatureChecker::VerifyECDSASignature(const std::vector<
97110 signatureCache.Set (entry);
98111 return true ;
99112}
113+
114+ bool CachingTransactionSignatureChecker::VerifySchnorrSignature (Span<const unsigned char > sig, const XOnlyPubKey& pubkey, const uint256& sighash) const
115+ {
116+ uint256 entry;
117+ signatureCache.ComputeEntrySchnorr (entry, sighash, sig, pubkey);
118+ if (signatureCache.Get (entry, !store)) return true ;
119+ if (!TransactionSignatureChecker::VerifySchnorrSignature (sig, pubkey, sighash)) return false ;
120+ if (store) signatureCache.Set (entry);
121+ return true ;
122+ }
0 commit comments