Files
secp256k1-zkp/src/modules
Kgothatso Ngako 69766dd331 frost_enrollment: close the review's test coverage gaps
Six new tests and repairs to two that were confounded. The suite goes
from 12 cases to 16.

Two existing tests would have stayed green with the checks they target
deleted, which is the worst kind of passing test:

- The "helper id out of range" case also passed new_id = 5 > n = 4,
  which params_are_valid rejects several lines earlier. It now uses a
  valid enrollment target (new_id = 4) and an id of 5, so the id range
  check is the sole failing condition.
- Every call in the empty-set test used (n = 1, t = 2), which fails on
  threshold > n_participants regardless of n_ids. It now uses
  (n = 2, t = 2, new_id = 2) -- a valid tuple in every respect except
  n_ids = 0.

New coverage, in the order the review ranked it:

- run_frost_enrollment_api_test: NULL for every ARG_NONNULL pointer on
  all five entry points, plus an unusable pubkey object on the four that
  take one (previously only params_hash was covered). Also asserts that
  a shares_gen call rejected at an ARG_CHECK does NOT consume the seed,
  since it never reaches the body -- the complement of the "a failed
  call always consumes it" property the previous commit pinned.
- run_frost_enrollment_infinity_test: pubshare_derive's infinity
  rejection, which nothing reached before. With u = 2 and new_id = 2 the
  Lagrange coefficients are exactly -1 and 2, so P_0 = 2*P_1 makes the
  interpolation vanish; the same two points at a different target
  succeed, which is what distinguishes the infinity check from a
  parameter rejection.
- run_frost_enrollment_max_size_test: full protocol runs at the largest
  sizes the API admits -- enrollment at n = 127 with u = 127, and repair
  in a full n = 128 group with u = 127. u cannot reach 128 in either
  mode (enrollment needs n < 128, repair excludes the target from the
  helper set), so these reach one entry below the fixed-size arrays'
  bound, which is as far as a valid tuple goes. Everything before this
  capped at n <= 7. Runs in 51 ms.
- run_frost_enrollment_no_side_effects_test: the C analogue of the
  reference implementation's test_participant_not_in_dkg, which plan
  §1.2 listed and the Phase 3 list dropped. Every existing
  participant's secret share, public share and the group key are
  byte-identical before and after an enrollment, and the new share
  differs from all of them.
- The pubshare_derive test now also pins the OTHER end of the
  polynomial. The public API cannot ask for x-coordinate 0 -- that is
  identifier -1, and new_id is a uint32_t bounded by n_participants --
  so the convention there is checked by running frost's own
  derive_thresh_pubkey over the same loaded points and requiring it to
  reproduce the group key. With the existing check at x = new_id, both
  ends of the interpolation this module depends on are now fixed.

Test-structure repairs the review called out:

- The mismatch test's disagreement now enters where it would in reality,
  at helper 0's round 1.1 call (which is made with new_id = 3 while
  helper 1 uses 4), rather than by running a clean round and
  overwriting the outputs afterwards.
- The oversized-helper-set test re-points a single dealt run at {0,1}
  and then {0,1,2} through a named helper, instead of struct-copying a
  ~540 KB run and hand-editing u and ids[2] -- which would have broken
  silently if deal()'s helper-selection rule changed.
- frost_enrollment_test_run instances in the mismatch test are now
  static. That test needs four live at once, which was over 2 MB of
  stack.
- The randomized test's `if (sub_ids[t-2] >= new_id) continue;` was
  unreachable: the loop bound gives sub_ids[t-2] <= n-1 and new_id == n
  in that branch. It is now the CHECK that states the invariant.
- The pubshare_derive test's `k` was reset and reused as both helper
  counter and aligned-array index inside the same loop body.

Verification: 16/16 pass at -i=16, -i=200 and -i=1000; ./tests,
./noverify_tests and ./exhaustive_tests exit 0; the module is clean
under valgrind (0 errors from 0 contexts).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 10:21:13 +02:00
..
2026-06-02 14:25:34 +02:00