rangeproof: add unit test for malleating single-value proofs

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.
This commit is contained in:
Andrew Poelstra
2024-06-19 15:27:06 +00:00
parent d661a93cc9
commit 3a1c39625e

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,