Skip to content

DKG: corrupted-share DoS vector (liveness-only, deferred) #80

Description

@p0mvn

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions