Merge ElementsProject/secp256k1-zkp#295: rangeproof: add unit test for malleating single-value proofs

3a1c39625e rangeproof: add unit test for malleating single-value proofs (Andrew Poelstra)

Pull request description:

  I was a bit confused reading `secp256k1_rangeproof_getheader_impl` because in the case of single-value proofs (`has_nz_range == 0`) some bits of the header are unconstrained. At first I thought this was a malleability vector. And I think I've had this same confusion in the past.

  But in fact it is not a malleability vector because the whole header gets hashed into the proof.

  Add a unit test to confirm this to reduce future confusion.

ACKs for top commit:
  real-or-random:
    utACK 3a1c39625e

Tree-SHA512: 9670cd04fcc0bb322d89c2c86ef863e13c29e4477dc6fecdda16b9a745e42a84f237a7ec387b3291f334e2a5c5806a8cc7cc00e40246ad5b36366be841195b4b
This commit is contained in:
Andrew Poelstra
2024-06-20 01:48:56 +00:00

View File

@@ -422,6 +422,7 @@ static void test_single_value_proof(uint64_t val) {
uint64_t val_out = 0;
size_t m_len_out = 0;
size_t i;
secp256k1_testrand256(blind);
secp256k1_testrand256(nonce);
@@ -463,6 +464,30 @@ static void test_single_value_proof(uint64_t val) {
CHECK(plen == 73);
}
/* Test if trailing bytes are rejected. */
proof[plen] = 0;
CHECK(secp256k1_rangeproof_verify(
CTX,
&min_val_out, &max_val_out,
&commit,
proof, plen + 1,
NULL, 0,
secp256k1_generator_h
) == 0);
/* Test if single-bit malleation is caught */
for (i = 0; i < plen*8; i++) {
proof[i >> 3] ^= 1 << (i & 7);
CHECK(secp256k1_rangeproof_verify(
CTX,
&min_val_out, &max_val_out,
&commit,
proof, plen,
NULL, 0,
secp256k1_generator_h
) == 0);
proof[i >> 3] ^= 1 << (i & 7);
}
/* Test if unchanged proof is accepted. */
CHECK(secp256k1_rangeproof_verify(
CTX,
&min_val_out, &max_val_out,