Pitfall

Insufficient Soundness from Reduced Iteration Count

What can go wrong. Some Fiat-Shamir-transformed proofs, such as the DLN proof of knowledge used in GG18/GG20/CGGMP21, reach their target soundness only by running many parallel challenge-response repetitions. If the iteration count is set such that the soundness error is high, an adversary can simply guess responses and convince the verifier without holding the claimed witness.

Security implication. An adversary brute-forces candidate proofs offline until one passes within the reduced soundness margin. DLN proofs in GG18 are repeated $k$ times and the soundness error is $2^{-k}$. So to forge a proof without knowing the discrete log, an attacker needs to guess all $k$ challenge bits, with a probability of $2^{-k}$. This is the c-guess attack as documented by Verichains. In Multichain’s fork, $k$ was set as low as $k = 1$, where each attempt succeeds with probability $1/2$.

How to avoid. Keep the iteration count at the value the specification mandates: at least 128 for CGGMP21 / GG18 / GG20 DLN proofs. If performance is the concern, switch to a compiled non-interactive proof instead of cutting rounds.

Example Multichain fastMPC DLN Iterations = 1 (TSSHOCK) (Verichains TSSHOCK report, 7727e4f)

Multichain’s anyswap/FastMulThreshold-DSA, a fork of bnb-chain/tss-lib, reduced the DLN proof iteration constant from thse spec-mandated 128 down to 1 in commit 4e543437c6, collapsing the soundness margin to a coin flip per attempt (source):

1// FILE: smpc-lib/crypto/ec2/ntildeZK.go — anyswap/FastMulThreshold-DSA @ 4e543437 (vulnerable)
2const (
3    // Iterations iter times
4    Iterations              = 1
5)

Verichains demonstrated the TSSHOCK c-guess attack against this configuration: the adversary submits parallel signing requests, forges a valid DLN proof on roughly half of them, and uses the forged proof to extract a signing key share in a single signing ceremony.

The fix in commit 7727e4f833 restored the constant (source):

1// FILE: smpc-lib/crypto/ec2/ntildeZK.go — anyswap/FastMulThreshold-DSA @ 7727e4f8 (fixed)
2const (
3    // Iterations iter times
4    Iterations              = 128
5)