Skip to content

test: add holistic signing boundary regressions - #33

Merged
piotr-roslaniec merged 5 commits into
devfrom
test/holistic-signing-boundaries
Sep 30, 2026
Merged

piotr-roslaniec merged 5 commits into
devfrom
test/holistic-signing-boundaries

Conversation

@piotr-roslaniec

Copy link
Copy Markdown

Add high-value durable regression tests for three validated holistic findings:

1. Security-v2 ceremony abort on message/width mismatch

  • TestSecurityV2CeremonyAbortsOnMessageMismatch/opposingPartySignsDifferentMessage:
    11-party security-v2 ceremony where party 1 uses a different message (43 vs 42).
    Round-2 BobMid verification fails due to SSID mismatch (message bound into SSID).
    Ceremony aborts with error attributed to the opposing party (party 1).
    Asserts no signature on any end channel.

  • TestSecurityV2CeremonyAbortsOnMessageMismatch/opposingPartyUsesDifferentFullBytesLen:
    Same integer (42) but party 1 uses width 31 vs others' width 32.
    SSID differs by width (fullBytesLen bound into SSID), same abort behavior.
    Asserts opposing culprit attribution and no signature produced.

Runtime bounded by stopping at first proof-verification failure (round 2), not full key generation.

2. Signing Start range gate

  • TestSigningStartMessageRangeGate/rejectsMessageEqualToCurveOrder:
    Start() with m == curve order N returns error; no round-1 messages emitted.

  • TestSigningStartMessageRangeGate/acceptsMessageEqualToOrderMinusOne:
    Start() with m == N-1 succeeds and emits 2 round-1 messages (directed + broadcast).

3. Deterministic out-of-order readiness accumulation for round.ok

  • TestSigningRound1OutOfOrderReadinessAccumulation:
    Signing round1.Update accumulates ok[2]=true (later peer) even when earlier peer 1 is incomplete.
    Proves the changed loop-continue behavior (commit db3fca8) is preserved.

  • TestKeygenRound1OutOfOrderReadinessAccumulation:
    Analogous keygen round1.Update test with real KGRound1Message fixtures.
    Proves the same accumulation behavior in the keygen path.

All tests reuse existing fixtures and helpers; no production changes.

Add high-value durable regression tests for three validated holistic findings:

1. Security-v2 ceremony aborts when fixture-backed parties diverge on message or fullBytesLen
   - TestSecurityV2CeremonyAbortsOnMessageMismatch/opposingPartySignsDifferentMessage:
     11-party security-v2 ceremony where party 1 uses a different message.
     Round-2 BobMid verification fails (SSID mismatch), ceremony aborts.
     Asserts no signature on any end channel and culprit attributed to opposing party.
   - TestSecurityV2CeremonyAbortsOnMessageMismatch/opposingPartyUsesDifferentFullBytesLen:
     Same integer (42), but party 1 uses width 31 vs others' 32.
     SSID differs by width, same abort behavior with opposing culprit attribution.

2. Signing Start range gate: m == curve order rejected, m == q-1 accepted
   - TestSigningStartMessageRangeGate/rejectsMessageEqualToCurveOrder:
     Start() with m=N returns error, no round-1 messages emitted.
   - TestSigningStartMessageRangeGate/acceptsMessageEqualToOrderMinusOne:
     Start() with m=N-1 succeeds, emits 2 round-1 messages (directed + broadcast).

3. Deterministic out-of-order readiness accumulation for round.ok behavior
   - TestSigningRound1OutOfOrderReadinessAccumulation:
     Signing round1.Update accumulates ok[2]=true even when earlier peer 1 is incomplete.
     Proves the changed loop-continue behavior (commit db3fca8) is preserved.
   - TestKeygenRound1OutOfOrderReadinessAccumulation:
     Analogous keygen round1.Update test with real KGRound1Message fixtures.

All tests reuse existing fixtures and helpers; no production changes.
1. Drain party 0's own round-1 output before mismatch delivery, and use a
   larger out-channel buffer, so a regression that removes SSID binding
   (round 2 unexpectedly succeeding) cannot deadlock on a full channel.
2. Await every party's Start() completion via a done-channel barrier before
   collecting/delivering messages, instead of relying on goroutine scheduling
   or leaving errCh unread.
3. Assert abort Round()==2 and that the full culprit set (accounting for the
   BobMid/BobMidWC duplicate-sender pair) is exactly the opposing party, plus
   bounded-deadline no-signature checks on every end channel.
4. Replace the keygen readiness fixture's real DLN/Mod proof generation
   (which only exercised round1.Update's type/broadcast check) with a
   minimal deterministic KGRound1Message construction; drops runtime from
   ~8s to ~7ms.
…re race

1. Route real round-1 messages to BOTH opposing-context receivers instead of
   only party 0. collectRound1MessagesForTargets drains every party's own
   out channel exactly once and partitions each message (broadcast or
   directed) to whichever of the two targets it's addressed to. Asserts:
   - party 0 (majority context) rejects only the single opposing party
     (its culprit set is exactly {party 1})
   - party 1 (minority context) rejects every other party, since its own
     SSID differs from all of them (its culprit set is exactly the other
     n-1 parties)
   Both must abort in round 2 with these exact culprit sets.

2. Fix a no-signature check race: the previous sequential loop shared one
   context.WithTimeout across selects, so once it fired on an earlier
   channel, later channels' selects raced an already-closed ctx.Done()
   against a possibly-ready endCh, non-deterministically masking a real
   signature. assertNoSignatureWithinWindow now monitors every end channel
   concurrently for the full window via one goroutine per channel (sharing
   ctx.Done() is safe here since closing a channel wakes every receiver),
   then performs a final nonblocking check per channel with no competing
   canceled context to catch anything buffered exactly at the boundary.
@piotr-roslaniec
piotr-roslaniec merged commit 76d088e into dev Sep 30, 2026
4 checks passed
@piotr-roslaniec

Copy link
Copy Markdown
Author

Holistic boundary regressions verified and merged into dev at 76d088ef0bf0640d9d939f72463e3b55f3f503fe.

  • Independent review caught and fixed channel deadlocks, unobserved startup errors, one-sided receiver coverage, incomplete culprit assertions, and a timeout/select race that could hide an unexpected signature.
  • Final mismatch scenarios route real round-1 proof messages to both opposing-context receivers; both must abort in round 2 with complete opposing culprit sets and no signature.
  • Added m == q rejection and m == q-1 boundary coverage.
  • Added deterministic signing/keygen out-of-order readiness regressions; the keygen fixture avoids unused proof generation.
  • Parent race stress: signing scenarios passed 3 runs and keygen readiness passed 10 runs.
  • GitHub Actions run 36650652739 passed vet, keygen units, full tests, and the historical oracle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant