diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 9f7bb9592b..a5c9198239 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -74,7 +74,9 @@ class CSignatureCache // ELEMENTS: void ComputeEntryRangeProof(uint256& entry, const std::vector& proof, const std::vector& commitment, const std::vector& asset_commitment, const CScript& scriptPubKey) { CSHA256 hasher = m_salted_hasher_range_proof; - hasher.Write(proof.data(), proof.size()).Write(commitment.data(), commitment.size()).Write(asset_commitment.data(), asset_commitment.size()).Write(scriptPubKey.data(), scriptPubKey.size()).Finalize(entry.begin()); + // Commit to field lengths first: without them, distinct (proof, commitment, asset_commitment, scriptPubKey) tuples that concatenate to the same byte stream collide to one cache key. The key is process-local (salted per start, never serialized or compared across nodes), so the array's native byte order is fine. + const uint64_t lengths[4] = {proof.size(), commitment.size(), asset_commitment.size(), scriptPubKey.size()}; + hasher.Write(reinterpret_cast(lengths), sizeof(lengths)).Write(proof.data(), proof.size()).Write(commitment.data(), commitment.size()).Write(asset_commitment.data(), asset_commitment.size()).Write(scriptPubKey.data(), scriptPubKey.size()).Finalize(entry.begin()); } void ComputeEntrySurjectionProof(uint256& entry, const uint256 &hash, const std::vector& proof, const std::vector& commitment) { CSHA256 hasher = m_salted_hasher_surjection_proof; diff --git a/src/test/blind_tests.cpp b/src/test/blind_tests.cpp index 8cb328f195..eae42e5d49 100644 --- a/src/test/blind_tests.cpp +++ b/src/test/blind_tests.cpp @@ -6,6 +6,7 @@ #include #include #include +#include