Zion Boggan

In-depth vulnerability research, detection engineering & applied cryptography.

● Open to security-research & detection roles
GitHub · LinkedIn · Email
← Research notebook
Crypto soundness

Finding 04: Fiat-Shamir Challenge Truncates proof.A in MTA Range ZKP

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