chilldkg-protocol-summary
ChillDKG lets participants settle on one FROST threshold key, each holding a single secret share, with no trusted dealer, no secret channels between them, and a coordinator nobody has to trust.
A DKG exists to dodge one specific danger: any dealer who hands out shares also knows the secret behind them. ChillDKG removes the dealer. Each participant brings its own random polynomial, and the threshold key is the sum of all the constant terms, so the full key only ever exists as a sum no single party can compute. What makes it "chill" is the list of crutches it refuses to lean on.
What it doesn't require
- Secret channels. Participants only need authenticated channels, not confidential ones. Each outgoing share is encrypted with a key derived by ECDH between the two host keys. Authenticated is not the same as confidential, and ChillDKG assumes only the cheaper of the two.
- A trusted coordinator. A star-topology coordinator aggregates and relays so participants never talk pairwise. It can stall the protocol, but it cannot forge a message, bias the key, or learn it.
- A separate agreement primitive. Every honest participant ends up with the same key, proven by a certificate the participants build themselves. The same certificate later doubles as a backup credential.
- Anonymous failure. When a check fails, ChillDKG names the participant or coordinator responsible instead of just aborting.
The modular stack
ChillDKG is three layers, each wrapping the one below and adding exactly one capability. The reference code keeps one file per layer.
SimplPedPop Pedersen DKG + proof-of-possession, over secret channels
└─ EncPedPop + ECDH encryption of shares -> needs only authenticated channels
└─ ChillDKG + certifying equality check + recovery data + blame
- SimplPedPop is the core: each participant shares a random polynomial via Shamir secret sharing and proves it knows its own secret with a proof of possession.
- EncPedPop drops the need for private channels by encrypting every outgoing share.
- ChillDKG drops the need for a trusted agreement primitive, swapping the abstract equality check for a concrete certifying one (CertEq), and adds recovery data.
The actors
- Participants : each holds a long-term host key pair, contributes a polynomial, and walks away with one secret share.
- Coordinator: collects round-1 messages, broadcasts the aggregate, then gathers round-2 signatures into the certificate. Untrusted throughout.
The protocol flow
Function names in parentheses are the public entry points in the reference implementation.
Pre-round (setup). Each participant derives its host public key (hostpubkey_gen), shares it, and everyone fixes the session parameters . A params_id pins down the exact session, so two participants who disagree about who is in the room will notice immediately.
Round 1, participant (participant_step1).
- Derive a fresh session seed from the host seed plus new randomness.
- Generate a degree polynomial .
- Commit to the coefficients: with . This VSS commitment is what lets everyone else check shares without seeing the polynomial.
- Build a proof of possession: a Schnorr signature proving knowledge of the secret constant term .
- Compute each other participant's share and encrypt it with a pad from ECDH (this participant's ephemeral nonce against the recipient's host pubkey).
- Send
ParticipantMsg1to the coordinator.
Aggregation (coordinator_step1). The coordinator sums the commitments and bundles every proof of possession, encrypted share, and ephemeral public nonce into CoordinatorMsg1, broadcast back to all.
Round 2, participant (participant_step2).
- Verify every proof of possession. Abort and blame participant if one fails.
- Assemble the summed commitment and compute each participant's public share.
- Decrypt own share and check it against its public share.
- Apply the Taproot tweak (an unspendable script-path tweak of the threshold key) to get the tweaked threshold pubkey, secret share, and public shares. See frost-tweak-randomness for why the tweak lands cleanly on each share.
- Build the session transcript and sign it with the host key. That signature is this participant's piece of CertEq.
- Send
ParticipantMsg2(the signature) to the coordinator.
Certificate (coordinator_finalize). The coordinator collects all host-key signatures into one certificate and returns CoordinatorMsg2.
Finalize, participant (participant_finalize). Verify the certificate against every host pubkey. If it holds, return the DKGOutput (secret share, threshold pubkey, all public shares) and the recovery data.
The certifying equality check (CertEq)
This is what the "Chill" buys you. A plain DKG assumes some outside primitive that guarantees every honest party sees the same result. ChillDKG makes that primitive concrete: agreement is the moment each participant signs its transcript with its host key and the bundle of all signatures verifies.
Two things then fall out for free. A valid certificate is transferable evidence that the whole group agreed on this exact key, which is exactly why it doubles as recovery data. And because each signature is bound to a known host key, a bad one names its signer.
Optional sub-protocols
- Investigation (
coordinator_investigate/participant_investigate): runs only when a share fails validation. The coordinator hands out per-participant investigation data so the victim can prove whether a specific sender or the coordinator is at fault. - Recovery (
recover): rebuilds a participant's share and the full output from the recovery-data blob plus its host secret key, with no live session. - Recovery acknowledgment (
participant_recovery_ack_sign/participant_recovery_acks_verify): participants sign off that they have stored the recovery data, so the group knows a backup exists before anyone trusts the key.