Severity: P4 (Low), Code defect, NOT exploitable in CMP protocol
Exploitation Path: NOT VIABLE
After tracing the full protocol flow through cmp_setup_service.cpp and mta.cpp, the CMP protocol always uses the VERIFIER’s Ring Pedersen parameters for both proof generation and verification. A malicious party choosing t=1, s=1 only weakens their own verification of received proofs, providing zero advantage. The honest party always uses their OWN properly-generated Ring Pedersen when verifying the attacker’s proofs.
Summary
The ring_pedersen_parameters_zkp_verify() function accepts t = 1 and/or s = 1 as valid parameters. The coprime check gcd(n, 1) = 1 passes for any n. A trivial ZKP (all A[i] = 1, all z[i] = 0) passes all 128 verification rounds. With these parameters, all Ring Pedersen commitments collapse to the constant 1 regardless of the committed value.
Location
- File:
src/common/crypto/commitments/ring_pedersen.c - Function:
ring_pedersen_parameters_zkp_verify(), line 756 - Missing check: After line 811 (coprime check for s)
Root Cause
Checks performed:
1. n is not prime (line 800), passes for valid RSA modulus
2. gcd(n, t) = 1 (line 806), passes for t=1
3. gcd(n, s) = 1 (line 811), passes for s=1
Missing: explicit rejection of BN_is_one(t), BN_is_one(s), t == n-1, s == n-1
PoC Verified
PoC confirms all 128 ZKP rounds pass with t=s=1, and demonstrates commitment(x,r) = 1 for all x, r.
Remediation
if (BN_is_one(pub->t) || BN_is_one(pub->s))
goto cleanup;
References
- CMP-2020 (ePrint 2020/492) Section 3.3: Ring Pedersen parameters must generate the full group
Source · github.com/zionsworking/security-research-notebook · writeups/fireblocks/01-ring-pedersen-degenerate-params-P4.md