Add the coordinator side of the ChillDKG protocol
(bip-frost-dkg v0.3.0-dev, reference commit
a91896883f85b159415ecf298d5e844879af112d), as thin wrappers over the
Phase 2 encpedpop coordinator internals (whose cmsg1 output was
already verified byte-identical to the reference coordinator_step1).
Public API:
- secp256k1_chilldkg_coordinator_step1: takes an array of pointers to
the n participant pmsg1 messages (musig/frost-style convention),
parses each with checked scalar parse, aggregates SimplPedPop and
EncPedPop, builds eq_input (including the enc_secshares suffix,
mirroring the reference) and emits cmsg1 (162n + 33(t-1) bytes).
PoPs are not verified coordinator-side, exactly as the reference.
- secp256k1_chilldkg_coordinator_finalize: concatenates the n CertEq
pmsg2 signatures into the 64n-byte certificate, verifies all of them
via certeq_verify (hostpubkeys recovered from eq_input at offset
4+33t), and outputs the coordinator-side DKG result: threshold
pubkey, pubshares and recovery data -- no secshare.
- secp256k1_chilldkg_coordinator_state: opaque, 21041 bytes,
magic-validated, holds only t, n, eq_input, thresh_pk and pubshares
-- no secret material, documented as freely copyable/persistable so
a stateless coordinator is possible.
Blame mapping (verified against chilldkg.py):
- malformed pmsg1 (bad commitment encoding, overflowing encrypted
share) -> FAULTY_PARTICIPANT(sender index),
- invalid CertEq signature -> FAULTY_PARTICIPANT(failing index)
(deliberately different from participant_finalize, which maps the
same failure to FAULTY_COORDINATOR -- matching the reference),
- invalid session params -> INVALID_INPUT; all outputs zeroed on
failure.
tests_impl.h: chilldkg_coordinator_api_test runs a full n=3,t=2
session through only the public APIs on both sides, byte-exact
against the Python reference vectors and cross-checked against every
participant's finalize outputs; blame cases (malformed pmsg1 and
overflowing share -> FAULTY_PARTICIPANT with the right index, bad
CertEq sig -> FAULTY_PARTICIPANT(2), zeroed outputs); misuse coverage
(NULL args, corrupted state magic).
Verified: make check 3/3 (incl. noverify); CMake ctest 365/365;
./tests --target=chilldkg green.