Notes on the chilldkg module API
================================

This module implements ChillDKG, a distributed key generation (DKG) protocol
for FROST, as specified by the bip-frost-dkg BIP draft
(https://github.com/BlockstreamResearch/bip-frost-dkg, version 0.3.0-dev). In
a ChillDKG session, n participants jointly generate a threshold key with the
help of an untrusted coordinator, such that no party (including the
coordinator) learns more than its own secret share, and every participant
obtains the threshold public key and the public shares of all participants.
The output is designed to feed directly into the frost module
(`include/secp256k1_frost.h`), which implements FROST signing (BIP 445) and
explicitly leaves DKG out of scope.

The implementation and its test vectors
(`tools/test_vectors_chilldkg_generate.py`) are validated against the pinned
reference commit `a91896883f85b159415ecf298d5e844879af112d` (v0.3.0-dev).

**This module is experimental.** Do not use it in production. The API should
not be considered stable. The underlying BIP is still a draft (v0.3.0-dev):
tagged hashes, wire formats, and protocol details may change in future BIP
versions.

The module depends on the schnorrsig module (for the CertEq certificate and
proofs of possession) and the ecdh module (for encrypted share distribution).

A usage example can be found in `examples/chilldkg.c`.

Protocol summary
----------------

Participants are identified by identifiers 0..n-1; participant i sits at
polynomial x-coordinate i + 1 (the same convention as the frost module). The
threshold t is the number of participants required to sign. The number of
participants must not exceed SECP256K1_CHILLDKG_MAX_PARTICIPANTS (128); the
state objects are fixed-size and the library does not allocate memory, so all
message buffers are caller-allocated (use the `secp256k1_chilldkg_*_msg1_len`,
`secp256k1_chilldkg_*_msg2_len`, `secp256k1_chilldkg_recovery_data_len` and
`secp256k1_chilldkg_investigation_msg_len` helpers to size them).

The coordinator is untrusted: it routes and aggregates messages but learns
nothing about the secret shares, and it cannot forge the outcome — all its
messages are verified by the participants. All coordinator sends are
broadcasts to all participants.

| Step | Function | Message | Size | Contents |
|---|---|---|---|---|
| participant step 1 | `secp256k1_chilldkg_participant_step1` | pmsg1 | 33t + 32n + 97 | VSS commitment, PoP, pubnonce, encrypted shares |
| coordinator step 1 | `secp256k1_chilldkg_coordinator_step1` | cmsg1 | 162n + 33(t-1) | commitments, pops, pubnonces, summed encrypted shares |
| participant step 2 | `secp256k1_chilldkg_participant_step2` | pmsg2 | 64 | CertEq signature over the transcript |
| coordinator finalize | `secp256k1_chilldkg_coordinator_finalize` | cmsg2 | 64n | certificate (the n CertEq signatures) |
| participant finalize | `secp256k1_chilldkg_participant_finalize` | — | — | DKG output + recovery data |

The resulting threshold public key is tweaked with a TapTweak-style tweak such
that the BIP 341 script path is unspendable; the tweak is already included in
the (secret and public) shares output by this module, so the outputs can be
used with the frost module directly (initialize the frost tweak cache from
the threshold public key and apply no further tweaks, unless the application
wants additional tweaks).

Blame taxonomy
--------------

Protocol functions report faults via the `secp256k1_chilldkg_fault` enum plus
a `fault_index` output:

- `SECP256K1_CHILLDKG_FAULTY_COORDINATOR`: the coordinator deviated from the
  protocol (detected by a participant).
- `SECP256K1_CHILLDKG_FAULTY_PARTICIPANT(i)`: participant i deviated from the
  protocol (detected by the coordinator, or an invalid recovery
  acknowledgment of participant i).
- `SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR(i)`: participant i
  appears to be faulty, but the coordinator may have framed them (detected by
  a participant).
- `SECP256K1_CHILLDKG_UNKNOWN_FAULTY_PARTICIPANT_OR_COORDINATOR`: a fault was
  detected but cannot be attributed without the investigation procedure; call
  `secp256k1_chilldkg_coordinator_investigate` (coordinator) and
  `secp256k1_chilldkg_participant_investigate` (participant, with the
  `inv_data` output by `secp256k1_chilldkg_participant_step2`) to attribute
  the fault.
- `SECP256K1_CHILLDKG_INVALID_INPUT`: the caller provided invalid input (bad
  host secret key, invalid session parameters, invalid recovery data).

Recovery
--------

`secp256k1_chilldkg_participant_finalize` and
`secp256k1_chilldkg_coordinator_finalize` output the recovery data
(`eq_input || certificate`). It is self-delimiting and self-authenticating:
anyone holding it can verify that the session succeeded, and a participant
can recover its DKG output at any time from the recovery data and its host
secret key (`secp256k1_chilldkg_participant_recover`; the coordinator uses
`secp256k1_chilldkg_coordinator_recover`). This also covers the case where
some participants never receive cmsg2: they can be convinced of the success
of the session later by being presented with the recovery data.

Callers SHOULD ensure that all participants deem the session successful
before using the threshold public key (e.g., before sending funds to it). The
recommended way is to collect recovery acknowledgments from all participants
(`secp256k1_chilldkg_recovery_ack_sign` and
`secp256k1_chilldkg_recovery_acks_verify`).

Security notes
--------------

- The host secret key is the participant's long-term identity and the basis
  of all session secrets. The same host key pair may be reused in multiple
  sessions. Do NOT erase the host secret key after a session, even a failed
  one: another participant may have succeeded, and this participant can
  recover its output later from the recovery data.
- `random32` in `secp256k1_chilldkg_participant_step1` must be FRESH
  cryptographically secure randomness for every session; reusing it across
  sessions can leak the host secret key. The function rejects all-zero
  randomness as a guard against a malfunctioning RNG.
- `state2` and `inv_data` contain secret key material (the secret share and
  decryption pads); keep them secret and do not copy them. `state1` and the
  coordinator state contain no secrets and can be copied (e.g., to persist
  them).
- Each state object must not be reused: pass `state1` to at most one
  `participant_step2` call, `state2` to at most one `participant_finalize`
  call, and the coordinator state to at most one `coordinator_finalize` call.
- The recovery data does not reveal the secret shares (they are encrypted),
  but it commits to the session's participants and outcome; treat it as
  sensitive metadata.
