pulsar v0.3: fix mu domain-separator in iso/debug tests + clarify byte-equality gap

The mu fix in v1.0.15 (Round2Sign + AlgebraicAggregate use FIPS 204
§5.4 mu = SHAKE256(tr || 0x00 || |ctx| || ctx || M)) made the
algebraic z computation byte-equal to circl's z. But the iso/debug
test helpers were still computing the OLD mu (tr || M without
domain separator), so they recomputed a "ghost z" that didn't
match Round2Sign's actual output.

This commit aligns the test helpers with the production mu:
- threshold_v03_iso_test.go line 98-105: add 0x00, 0x00 prefix
- threshold_v03_debug_test.go line 216-222: same

After this fix:
- TestAlgebraic_Debug_AlgebraicReconstruction PASS (zRecon vs zRef: 0 diffs)
- TestAlgebraic_Debug_ZSumVsCircl PASS (z matches circl byte-for-byte)
- TestAlgebraic_Debug_PartyZRecomputation PASS

Public-BFT-safety contract (load-bearing test):
- TestAlgebraic_NoSkAccess PASS — AlgebraicAggregate function signature
  has NO sk parameter and function body NEVER references KeyFromSeed,
  mldsaSign, or any sk-bearing primitive.

Other v0.3 tests still passing:
- TestAlgebraic_BadMAC_Detected, BadCommit_Detected, DishonestParty_BadZ
- TestAlgebraic_DealerReproducible, TminusOne_Fails, RestartConverges

Remaining FAIL (BLOCKERS.md::PULSAR-V03-1):
- TestAlgebraic_FullCycle_n5_t3, VariousQuorums, ByteValid, RealRNG_Smokes
- These all fail because the output signature, while ALGEBRAICALLY
  CORRECT (debug tests confirm z, mu, c̃, c match circl), does not
  pass circl's FIPS 204 Verify. The bug is somewhere subtle in:
    (a) cs2 / ct0 sum across the per-party contributions
    (b) The MakeHint args or boundary semantics
    (c) The sigEncode pack at the byte level
- All primitive checks against circl source verified equivalent
  (decompose, makeHint, packHint, packLeGamma1). Bug needs side-by-side
  debugging with breakpoints comparing intermediate buffers; deferred
  to a focused session.

The public-BFT-safety CONTRACT (no sk access) is satisfied today.
The byte-equality FOR INTEROP with stock FIPS 204 verifiers is the
remaining gap.
This commit is contained in:
2026-05-22 00:41:16 -07:00
parent 77c9b92487
commit 773ab199b5
2 changed files with 5 additions and 0 deletions
@@ -213,10 +213,12 @@ func TestAlgebraic_Debug_ZSumVsCircl(t *testing.T) {
_, _, _, gamma2 := modeTauOmega(ModeP65)
w1, _ := decomposeVec(w, gamma2)
w1Packed := packW1Vec(w1, gamma2, K)
// μ = SHAKE-256(tr || 0x00 || |ctx| || ctx || M, 64) per FIPS 204 §5.4.
var mu [64]byte
{
h := newShake256()
_, _ = h.Write(setup.Tr[:])
_, _ = h.Write([]byte{0x00, 0x00})
_, _ = h.Write(msg)
_, _ = h.Read(mu[:])
}
@@ -95,10 +95,13 @@ func TestAlgebraic_Debug_PartyZRecomputation(t *testing.T) {
_, _, _, gamma2 := modeTauOmega(ModeP65)
w1, _ := decomposeVec(w, gamma2)
w1Packed := packW1Vec(w1, gamma2, K)
// μ = SHAKE-256(tr || 0x00 || |ctx| || ctx || M, 64) per FIPS 204 §5.4.
// Must match Round2Sign's mu derivation in threshold_v03.go.
var mu [64]byte
{
h := newShake256()
_, _ = h.Write(setup.Tr[:])
_, _ = h.Write([]byte{0x00, 0x00})
_, _ = h.Write(msg)
_, _ = h.Read(mu[:])
}