Summary
A malicious validator can repeatedly send shares that fail Feldman verification, causing all honest validators to fail the ack phase. The ceremony times out and resets to REGISTERING each cycle. If the attacker persists, the ceremony never completes — a liveness denial-of-service.
Current behavior
During the ack phase in ackDKGRound (app/prepare_proposal_ceremony.go L488–L500), each validator decrypts every other contributor's share and verifies it against their Feldman commitments via VerifyFeldmanShare. If any contributor's share fails verification, the entire ack is aborted — the validator does not inject MsgAckExecutiveAuthorityKey. When all honest validators fail to ack, the DEALT timeout fires and the EndBlocker resets the ceremony to REGISTERING. The malicious validator repeats on the next cycle.
Why naive "skip the bad contributor" doesn't work
A sophisticated attacker can send valid shares to some validators and invalid shares to others. Validators who received good shares include the attacker in their combined polynomial; those who received bad shares exclude them. The two groups end up with shares of different combined polynomials — threshold decryption would fail at tally time.
Attempted solution: majority-vote skip set (closed)
A majority-vote skip set mechanism was prototyped in #78 but closed without merging — the implementation touched proto definitions, the ack handler, the confirm/timeout EndBlocker, and ProcessProposal validation, adding substantial complexity across 8+ files for an attack that requires a compromised bonded validator. The PR also surfaced additional edge cases (coordinated 2-validator liveness attack, threshold not recomputed after stripping, unverifiable skip claims) that would need further design work.
How it would have worked
Each ack would carry a skipped_contributors list. At confirmation, the chain determines the majority skip set and only counts acks compatible with it:
| Scenario |
Majority decision |
Stripped |
Remaining |
Result |
k < n/2 |
No skip |
k validators who reported {skip j} |
n - k > n/2 ≥ t |
Confirms with j |
k ≥ n/2 |
Skip j |
n - k validators who reported {no skip} |
k ≥ n/2 ≥ t |
Confirms without j |
k = n - 1 |
Unanimous skip j |
None |
n - 1 ≥ t |
Confirms trivially |
A single attacker cannot prevent confirmation under honest majority. The attack degrades to requiring two or more colluding validators doing coordinated selective targeting.
Long-term solution: SNARK-based share validity
The cleanest fix is requiring each contributor to attach a succinct proof (e.g. Halo2/IPA) that their encrypted shares are consistent with their published Feldman commitments. On-chain verification replaces the per-validator Feldman check entirely — invalid contributions are rejected at ContributeDKG time, before the ceremony reaches DEALT. This is the approach used in protocols like GOLDEN.
Why the risk is acceptable today
| Factor |
Assessment |
| Attacker profile |
Must be a bonded, approved validator who intentionally modifies their node software |
| Detectability |
Every honest validator logs the offender: contributor %s: share failed Feldman verification. Attribution is immediate and unanimous. |
| Impact scope |
Liveness delay only (repeated ceremony timeouts). No safety violation — votes, keys, and funds are never at risk. |
| Remediation |
Identify offender from logs → governance proposal or chain upgrade to jail/remove → ceremony completes on next cycle |
Decision
Accept as a known limitation. The attack surface is narrow (bonded validators only), fully attributable, and liveness-only. The majority-vote skip mechanism was attempted (#78) but adds too much protocol complexity for today. Long-term, SNARK-based share validity proofs are the right path.
References
Summary
A malicious validator can repeatedly send shares that fail Feldman verification, causing all honest validators to fail the ack phase. The ceremony times out and resets to
REGISTERINGeach cycle. If the attacker persists, the ceremony never completes — a liveness denial-of-service.Current behavior
During the ack phase in
ackDKGRound(app/prepare_proposal_ceremony.goL488–L500), each validator decrypts every other contributor's share and verifies it against their Feldman commitments viaVerifyFeldmanShare. If any contributor's share fails verification, the entire ack is aborted — the validator does not injectMsgAckExecutiveAuthorityKey. When all honest validators fail to ack, the DEALT timeout fires and the EndBlocker resets the ceremony toREGISTERING. The malicious validator repeats on the next cycle.Why naive "skip the bad contributor" doesn't work
A sophisticated attacker can send valid shares to some validators and invalid shares to others. Validators who received good shares include the attacker in their combined polynomial; those who received bad shares exclude them. The two groups end up with shares of different combined polynomials — threshold decryption would fail at tally time.
Attempted solution: majority-vote skip set (closed)
A majority-vote skip set mechanism was prototyped in #78 but closed without merging — the implementation touched proto definitions, the ack handler, the confirm/timeout EndBlocker, and ProcessProposal validation, adding substantial complexity across 8+ files for an attack that requires a compromised bonded validator. The PR also surfaced additional edge cases (coordinated 2-validator liveness attack, threshold not recomputed after stripping, unverifiable skip claims) that would need further design work.
How it would have worked
Each ack would carry a
skipped_contributorslist. At confirmation, the chain determines the majority skip set and only counts acks compatible with it:k < n/2kvalidators who reported{skip j}n - k > n/2 ≥ tjk ≥ n/2jn - kvalidators who reported{no skip}k ≥ n/2 ≥ tjk = n - 1jn - 1 ≥ tA single attacker cannot prevent confirmation under honest majority. The attack degrades to requiring two or more colluding validators doing coordinated selective targeting.
Long-term solution: SNARK-based share validity
The cleanest fix is requiring each contributor to attach a succinct proof (e.g. Halo2/IPA) that their encrypted shares are consistent with their published Feldman commitments. On-chain verification replaces the per-validator Feldman check entirely — invalid contributions are rejected at
ContributeDKGtime, before the ceremony reaches DEALT. This is the approach used in protocols like GOLDEN.Why the risk is acceptable today
contributor %s: share failed Feldman verification. Attribution is immediate and unanimous.Decision
Accept as a known limitation. The attack surface is narrow (bonded validators only), fully attributable, and liveness-only. The majority-vote skip mechanism was attempted (#78) but adds too much protocol complexity for today. Long-term, SNARK-based share validity proofs are the right path.
References
app/prepare_proposal_ceremony.goL488–L500x/vote/module.goEndBlocker DEALT timeout handlerdocs/tss-ceremony.md§Issue 2