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; } }