Severity: P3 (Medium), Weakened ZKP soundness
Summary
genarate_mta_range_zkp_seed() hashes only BN_num_bytes(proof.S) bytes of proof.A instead of all BN_num_bytes(proof.A) bytes. For 2048-bit Paillier, only 256 of 512 bytes are included in the Fiat-Shamir challenge. The upper 256 bytes of A are completely unbound, modifying them does not change the challenge hash.
Location
- File:
src/common/cosigner/mta.cpp, lines 102-104
std::vector<uint8_t> n(BN_num_bytes(proof.A)); // 512 bytes
BN_bn2bin(proof.A, n.data()); // A serialized
SHA256_Update(&ctx, n.data(), BN_num_bytes(proof.S)); // BUG: only 256 bytes hashed
PoC Verified
Modified A[256:512]: db2d3473e6004c65... (all bits flipped)
Vulnerable hash(original): 0dd45a1b19a84102...
Vulnerable hash(modified): 0dd45a1b19a84102...
Same challenge: YES ← UPPER HALF OF A IS UNBOUND!
Remediation
SHA256_Update(&ctx, n.data(), BN_num_bytes(proof.A));
Source · github.com/zionsworking/security-research-notebook · writeups/fireblocks/04-fiat-shamir-truncation-mta-P3.md