src/modules/iceberg/vectors.h opens with regeneration instructions that
name ./tools/test_vectors_iceberg_generate.py, and that script was never
committed. The same header calls the file "the one thing in this
repository that cannot be rebuilt from what the repository contains",
which the missing generator made true twice over: neither the reference
nor the tool that reads it was reachable from a clone.
Recovered from the tree the Iceberg C is vendored in, at
sources/secp256k1-kmp/native/secp256k1 of the benchmark repository
(bitcoin-core/secp256k1 branch iceberg-module, commit 96201552, per that
repository's PINS.txt). Confirmed to be the generator that produced the
checked-in vectors before committing it:
- its HEADER template reproduces the header of vectors.h exactly,
including the ICEBERG_VECTOR_MAX_PARTICIPANTS 9 and
ICEBERG_VECTOR_MAX_SEEDS 126 it computes from the configuration list;
- its seed rule, sha256("iceberg test vectors|<label>|<rank>"),
reproduces the checked-in 2of3 seeds byte for byte;
- the whole of that tree's src/modules/iceberg/ matches this one byte
for byte except tests_impl.h, which differs only because the tests
here are ported to the unit_test.h test-module framework.
The script cannot be re-run from a clone alone, by design: it takes the
nkohen/Iceberg Python reference as its argument and that reference is
deliberately not vendored, since it is not ours and pinning a copy would
hide it drifting. Its docstring gives the clone and the pinned commit
(7b55ef6d), which is now the whole of what regenerating requires.
Also restore the executable bit on the frost and chilldkg generators.
Both carry a usage line telling the reader to run them directly, and
every other generator in tools/ is 0755.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Final phase of the ChillDKG module: upstream test vectors, a
DKG->FROST integration test, boundary tests, full module
documentation and a runnable example.
Test vectors:
- tools/test_vectors_chilldkg_generate.py converts all 10 upstream
bip-frost-dkg JSON vector files into src/modules/chilldkg/vectors.h
(modeled on tools/test_vectors_frost_generate.py; takes the vectors
directory as an argument; upstream pinned to commit
a91896883f85b159415ecf298d5e844879af112d, recorded in the generated
header with the exact regeneration invocation; regeneration is
reproducible byte-for-byte).
- tests_impl.h vector runners execute 191 of 241 upstream cases
through the public API: hostpubkey_gen, params_hash,
participant_step1/step2/finalize/investigate,
coordinator_step1/finalize/investigate, recover. Happy paths are
byte-exact (pmsg1/cmsg1/pmsg2/cmsg2/dkg_output/recovery/cinv);
error cases assert both the fault enum and fault_index against
expectedError.participantId. The 50 skipped cases are
wrong-length/wrong-count inputs not expressible with the
fixed-size C API; each skip is documented in vectors.h.
Boundary/robustness tests: t=1, t=n, n=2, a full n=128/t=2 session
end-to-end with per-participant secshare*G == pubshare checks and a
recovery roundtrip, and a state1 memcpy roundtrip (step2 from a copied
state object).
DKG->FROST integration test (guarded by ENABLE_MODULE_FROST): a full
ChillDKG session (n=3, t=2) feeds (secshare, thresh_pk, pubshares)
directly into the frost module. ChillDKG's thresh_pk is already
TapTweak'ed, so frost_tweak_cache_init is called with no further
tweaks (frost's tweaked x-only key asserted equal to the x-only part
of the ChillDKG thresh_pk); signers 0 and 2 run nonce_gen, nonce_agg,
session_init with the shared x = id+1 convention, frost_sign,
partial_sig_verify and partial_sig_agg; the aggregate signature
verifies as a plain BIP-340 signature against the threshold key.
Example: examples/chilldkg.c runs a full 2-of-3 DKG session (host key
generation, params hash, participant/coordinator steps, finalize, and
a recovery roundtrip via participant_recover) with fixed-size buffers
and secret erasure. Wired into Makefile.am and
examples/CMakeLists.txt exactly like frost_example (runs as a TEST);
chilldkg_example binary added to .gitignore.
Docs: src/modules/chilldkg/chilldkg.md now documents the protocol
summary, message-flow table with exact byte sizes, blame taxonomy,
recovery workflow, security notes (host key reuse/retention, fresh
randomness per session, state secrecy, recovery-data sensitivity) and
the pinned reference commit; src/modules/frost/frost.md points at the
new module as the intended DKG.
Bug fix found by the vector runner (recover tcId 9): the internal
recover() passed a possibly-NULL fault_index from coordinator_recover
to certeq_verify, which dereferences it on failure; now uses a local.
Verified: make check 10/10 (3 test suites + 7 examples incl.
chilldkg_example, exit 0 when run); CMake ctest 428/428 with chilldkg
+ frost, and a no-frost build confirms the ENABLE_MODULE_FROST guard;
make distdir includes vectors.h, the example and the generator.
The module is feature-complete against bip-frost-dkg v0.3.0-dev at
a91896883f85b159415ecf298d5e844879af112d. The BIP is still a draft;
tagged hashes and wire formats may change upstream.