From 92871c62314183fa49d1b33add5c216b3bb3a31e Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Tue, 17 Apr 2018 20:19:25 -0400 Subject: [PATCH 1/3] Actually cache range and surjection proofs --- src/script/sigcache.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index d7601a196c..4e40d48463 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -179,6 +179,10 @@ bool CachingRangeProofChecker::VerifyRangeProof(const std::vector return false; } + if (store) { + rangeProofCache.Set(entry); + } + return true; } @@ -216,5 +220,9 @@ bool CachingSurjectionProofChecker::VerifySurjectionProof(secp256k1_surjectionpr return false; } + if (store) { + surjectionProofCache.Set(entry); + } + return true; } From 957216523881768d9bcd6c5092dd5d50495dcd4e Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Wed, 25 Apr 2018 10:45:14 -0400 Subject: [PATCH 2/3] simplify rangeproof validation caching --- src/script/sigcache.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 4e40d48463..17d1177d01 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -63,6 +63,11 @@ public: CSHA256().Write(nonce.begin(), 32).Write(hash.begin(), 32).Write(&pubkey[0], pubkey.size()).Write(&vchSig[0], vchSig.size()).Write(&vchCommitment[0], vchCommitment.size()).Write(&scriptPubKey[0], scriptPubKey.size()).Finalize(entry.begin()); } + void ComputeEntry(uint256& entry, const std::vector& proof, const std::vector& commitment) + { + CSHA256().Write(nonce.begin(), nonce.size()).Write(proof.data(), proof.size()).Write(commitment.data(), commitment.size()).Finalize(entry.begin()); + } + bool Get(const uint256& entry, const bool erase) { @@ -145,9 +150,8 @@ bool CachingTransactionSignatureChecker::VerifySignature(const std::vector& vchRangeProof, const std::vector& vchValueCommitment, const std::vector& vchAssetCommitment, const CScript& scriptPubKey, const secp256k1_context* secp256k1_ctx_verify_amounts) const { - CPubKey pubkey(vchValueCommitment); uint256 entry; - rangeProofCache.ComputeEntry(entry, uint256(), vchRangeProof, pubkey, vchAssetCommitment, scriptPubKey); + rangeProofCache.ComputeEntry(entry, vchRangeProof, vchValueCommitment); if (rangeProofCache.Get(entry, !store)) { return true; From 4815bc62cd0027d20a6888f98d33edb464531f04 Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Wed, 25 Apr 2018 10:45:37 -0400 Subject: [PATCH 3/3] simplify and speedup surjection proof caching --- src/script/sigcache.cpp | 31 +++++++++++++------------------ src/script/sigcache.h | 2 +- src/validation.cpp | 9 ++++++--- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 17d1177d01..9191c8cd42 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -68,6 +68,13 @@ public: CSHA256().Write(nonce.begin(), nonce.size()).Write(proof.data(), proof.size()).Write(commitment.data(), commitment.size()).Finalize(entry.begin()); } + void ComputeEntry(uint256& entry, const uint256 &hash, const std::vector& proof, const std::vector& commitment) + { + CSHA256().Write(nonce.begin(), nonce.size()).Write(hash.begin(), 32).Write(proof.data(), proof.size()).Write(commitment.data(), commitment.size()).Finalize(entry.begin()); + } + + + bool Get(const uint256& entry, const bool erase) { @@ -190,31 +197,19 @@ bool CachingRangeProofChecker::VerifyRangeProof(const std::vector return true; } -bool CachingSurjectionProofChecker::VerifySurjectionProof(secp256k1_surjectionproof& proof, std::vector& vTags, secp256k1_generator& gen, const secp256k1_context* secp256k1_ctx_verify_amounts) const +bool CachingSurjectionProofChecker::VerifySurjectionProof(secp256k1_surjectionproof& proof, std::vector& vTags, secp256k1_generator& gen, const secp256k1_context* secp256k1_ctx_verify_amounts, const uint256& wtxid) const { - // Serialize objects + + // Serialize proof std::vector vchproof; size_t proof_len = 0; vchproof.resize(secp256k1_surjectionproof_serialized_size(secp256k1_ctx_verify_amounts, &proof)); secp256k1_surjectionproof_serialize(secp256k1_ctx_verify_amounts, &vchproof[0], &proof_len, &proof); - std::vector tagCommit; - tagCommit.resize(33); - CSHA256 sha2; - for (unsigned int i = 0; i vchGen; - vchGen.resize(CConfidentialValue::nCommittedSize); - secp256k1_generator_serialize(secp256k1_ctx_verify_amounts, &vchGen[0], &gen); - - CPubKey pubkey(vchGen); + // wtxid commits to all data including surj targets + // we need to specify the proof and output asset point to be unique uint256 entry; - surjectionProofCache.ComputeEntry(entry, uint256(tagCommit), vchproof, pubkey, vchGen, CScript()); + surjectionProofCache.ComputeEntry(entry, wtxid, vchproof, std::vector(std::begin(gen.data), std::end(gen.data))); if (surjectionProofCache.Get(entry, !store)) { return true; diff --git a/src/script/sigcache.h b/src/script/sigcache.h index c0e329dc8e..aeaada29f9 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -55,7 +55,7 @@ public: store = storeIn; }; - bool VerifySurjectionProof(secp256k1_surjectionproof& proof, std::vector& vTags, secp256k1_generator& gen, const secp256k1_context* ctx) const; + bool VerifySurjectionProof(secp256k1_surjectionproof& proof, std::vector& vTags, secp256k1_generator& gen, const secp256k1_context* ctx, const uint256& wtxid) const; }; diff --git a/src/validation.cpp b/src/validation.cpp index 4958b0db41..2d996dd09d 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -628,9 +628,10 @@ private: secp256k1_surjectionproof proof; std::vector vTags; secp256k1_generator gen; + uint256 wtxid; const bool store; public: - CSurjectionCheck(secp256k1_surjectionproof& proofIn, std::vector& tags_in, secp256k1_generator& genIn, const bool storeIn) : proof(proofIn), vTags(tags_in), gen(genIn), store(storeIn) {} + CSurjectionCheck(secp256k1_surjectionproof& proof_in, std::vector& tags_in, secp256k1_generator& gen_in, uint256& wtxid_in, const bool store_in) : proof(proof_in), vTags(tags_in), gen(gen_in), wtxid(wtxid_in), store(store_in) {} bool operator()(); }; @@ -676,7 +677,7 @@ bool CBalanceCheck::operator()() bool CSurjectionCheck::operator()() { - return CachingSurjectionProofChecker(store).VerifySurjectionProof(proof, vTags, gen, secp256k1_ctx_verify_amounts); + return CachingSurjectionProofChecker(store).VerifySurjectionProof(proof, vTags, gen, secp256k1_ctx_verify_amounts, wtxid); } } // namespace @@ -713,6 +714,8 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve memset(explBlinds, 0, sizeof(explBlinds)); int ret; + uint256 wtxid(tx.GetHashWithWitness()); + // This list is used to verify surjection proofs. // Proofs must be constructed with the list being in // order of input and non-null issuance pseudo-inputs, with @@ -993,7 +996,7 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve if (secp256k1_surjectionproof_parse(secp256k1_ctx_verify_amounts, &proof, &ptxoutwit->vchSurjectionproof[0], ptxoutwit->vchSurjectionproof.size()) != 1) return false; - if (QueueCheck(pvChecks, new CSurjectionCheck(proof, targetGenerators, gen, cacheStore)) != SCRIPT_ERR_OK) { + if (QueueCheck(pvChecks, new CSurjectionCheck(proof, targetGenerators, gen, wtxid, cacheStore)) != SCRIPT_ERR_OK) { return false; } }