2023-07-14 08:41:26 +01:00
|
|
|
function(add_example name)
|
|
|
|
|
set(target_name ${name}_example)
|
|
|
|
|
add_executable(${target_name} ${name}.c)
|
|
|
|
|
target_include_directories(${target_name} PRIVATE
|
|
|
|
|
${PROJECT_SOURCE_DIR}/include
|
|
|
|
|
)
|
|
|
|
|
target_link_libraries(${target_name}
|
|
|
|
|
secp256k1
|
|
|
|
|
$<$<PLATFORM_ID:Windows>:bcrypt>
|
|
|
|
|
)
|
2026-01-20 16:53:17 +00:00
|
|
|
add_test(NAME secp256k1.example.${name} COMMAND ${target_name})
|
2026-01-13 17:26:47 +00:00
|
|
|
set_tests_properties(secp256k1.example.${name} PROPERTIES
|
|
|
|
|
LABELS secp256k1_example
|
|
|
|
|
)
|
2023-07-14 08:41:26 +01:00
|
|
|
endfunction()
|
2023-03-08 13:33:16 +00:00
|
|
|
|
2023-07-14 08:41:26 +01:00
|
|
|
add_example(ecdsa)
|
2023-03-08 13:33:16 +00:00
|
|
|
|
|
|
|
|
if(SECP256K1_ENABLE_MODULE_ECDH)
|
2023-07-14 08:41:26 +01:00
|
|
|
add_example(ecdh)
|
2023-03-08 13:33:16 +00:00
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
|
2023-07-14 08:41:26 +01:00
|
|
|
add_example(schnorr)
|
2023-03-08 13:33:16 +00:00
|
|
|
endif()
|
2024-06-25 03:11:21 +02:00
|
|
|
|
|
|
|
|
if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
|
|
|
|
|
add_example(ellswift)
|
|
|
|
|
endif()
|
2024-01-06 20:17:27 +00:00
|
|
|
|
|
|
|
|
if(SECP256K1_ENABLE_MODULE_MUSIG)
|
|
|
|
|
add_example(musig)
|
|
|
|
|
endif()
|
2026-08-31 00:05:16 +02:00
|
|
|
|
|
|
|
|
if(SECP256K1_ENABLE_MODULE_FROST)
|
|
|
|
|
add_example(frost)
|
|
|
|
|
endif()
|
chilldkg: Phase 6 - test vectors, FROST integration, docs, example
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.
2026-08-31 06:52:58 +02:00
|
|
|
|
|
|
|
|
if(SECP256K1_ENABLE_MODULE_CHILLDKG)
|
|
|
|
|
add_example(chilldkg)
|
|
|
|
|
endif()
|
2026-08-31 12:25:09 +02:00
|
|
|
|
|
|
|
|
if(SECP256K1_ENABLE_MODULE_ICEBERG)
|
|
|
|
|
add_example(iceberg)
|
|
|
|
|
endif()
|
frost_enrollment: add the example program
Fifth of six commits. examples/frost_enrollment.c runs a 2-of-3 group
through an enrollment to 2-of-4, signs with the new participant, and then
repairs a lost share -- all roles in one process, following
examples/frost.c's structure.
The example exists mostly to demonstrate two things the API cannot
enforce and that a reader would otherwise have to reconstruct from the
documentation.
First, the verification flow, in the order that makes it non-circular:
1. obtain thresh_pk from a source authenticated INDEPENDENTLY of the
helpers (here, the dealer step, commented as the stand-in);
2. validate the helpers' public shares against it with
secp256k1_frost_threshold_info_validate;
3. derive the expected public share from those validated shares;
4. only then run round 2, passing the same authenticated thresh_pk.
Skip step 1 or 2 and every check in round 2 still passes -- on a share
from whatever polynomial t colluding helpers chose to present. The
example says so at the point where it would be tempting to skip them.
Second, the authorization gap. There is no authorization step in the
protocol: anyone who convinces t helpers to run it receives a valid
share, and in repair mode that is an existing participant's actual
share. The precondition sits in the comment on enroll(), where a reader
copying the function will see it, and again at the repair call site,
which is where it bites hardest.
Beyond that the example is a working reference for the parts that are
fiddly to get right from the header alone: the transposition between
round 1.1's output buffers and round 1.2's input buffer (helper j
collects entry j of every helper's buffer), the opposite own-slot
conventions of the two round-1.2 buffers, the n -> n+1 bookkeeping with
threshold_info_validate over the extended table, and the fact that the
resulting signature verifies against the group's ORIGINAL threshold
public key, since enrollment changes neither the polynomial nor any
existing share.
The repair half asserts byte equality with the original secret share and
the original public share, so a regression there fails the example rather
than passing quietly.
Wired into both build systems next to the iceberg example: Makefile.am
(noinst_PROGRAMS and TESTS under ENABLE_MODULE_FROST_ENROLLMENT) and
examples/CMakeLists.txt. The .gitignore entry landed with the Phase 1
scaffolding.
Verification. Autotools: builds warning-free and `make check` reports
12/12 PASS including frost_enrollment_example; five consecutive runs exit
0 (the key material is freshly random each time, so this exercises both
threshold-key parities in practice). CMake: with
-DSECP256K1_BUILD_EXAMPLES=ON, ctest runs all nine examples and
secp256k1.example.frost_enrollment passes; the full ctest suite is
523/523 with frost, chilldkg, iceberg, prefractal and frost-enrollment
all enabled. The source is clean under gcc -std=c89 -pedantic -Wall
-Wextra.
Note for anyone reproducing this: examples are OFF by default in both
build systems (--enable-examples for autotools,
-DSECP256K1_BUILD_EXAMPLES=ON for CMake), so a plain build will not
compile this file at all.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 04:30:48 +02:00
|
|
|
|
|
|
|
|
if(SECP256K1_ENABLE_MODULE_FROST_ENROLLMENT)
|
|
|
|
|
add_example(frost_enrollment)
|
|
|
|
|
endif()
|