Files
pulsar/vectors
zeekay 1793dd64ac pulsar-m: KAT vectors for keygen / sign / verify / threshold / dkg
Canonical Known Answer Tests for the Pulsar-M v0.1 reference,
generated by ref/go/cmd/genkat. Re-running scripts/gen_vectors.sh on
a clean checkout reproduces these files byte-identically — the
deterministic-fixture gate.

Coverage:

  vectors/keygen.json        — 9 KATs (3 seeds × 3 modes)
                                 seed → (public_key, private_key)
  vectors/sign.json          — 9 KATs (3 messages × 3 modes)
                                 (seed, message) → signature
  vectors/verify.json        — 6 KATs (3 positive + 3 negative)
                                 (pubkey, message, signature, valid)
  vectors/threshold-sign.json — 4 KATs at (n,t) ∈ {(3,2),(5,3),
                                 (7,4),(10,7)} for Pulsar-M-65;
                                 every signature passes
                                 mldsa65.Verify (Class N1 demo)
  vectors/dkg.json           — 3 KATs at (3,2), (5,3), (7,4) for
                                 Pulsar-M-65; per-party shares and
                                 transcript hash committed

The replay harness in kat_test.go reads each JSON at test time and
verifies the round-trip:

  - Keygen replay: KeyFromSeed(seed) reproduces (pk, sk)
  - Sign replay:   Sign(deterministic) reproduces signature
  - Verify replay: pulsarm.Verify accepts every positive case and
                   rejects every negative case
  - Threshold:     every committed signature passes pulsarm.Verify
                   (which dispatches to FIPS 204 ML-DSA.Verify
                   verbatim — the load-bearing Class N1 property)
  - DKG:           wire-format invariants (sizes match parameter
                   set, transcript hash is 48 bytes, share count
                   matches committee count)

scripts/gen_vectors.sh + scripts/test.sh are now functional CI
gates.

Signed-off-by: Lux Industries <[email protected]>
2026-05-10 20:26:37 -07:00
..

Test vectors

Two formats per NIST MPTC submission norms:

  • kat-v1.json — input/output vectors per MPTC §IO-Testing. Each entry is a single threshold ceremony with full (n, t, party_seeds, public_params, shares, commitments, preprocessing_transcript, message, per_party_messages, final_signature, verify_result, abort_evidence).

  • kat-v1.rsp — CAVS-style response file for compatibility with legacy ACVP-inspired tooling. One signature per stanza, deterministic from a 48-byte seed.

transcripts/ holds full-protocol KATs for (n, t) sweeps — transcripts/n3-t2.jsonl, transcripts/n7-t5.jsonl, etc. — each line a complete protocol run.

Cross-validation against FIPS 204

The headline interchangeability claim (Class N1) requires every final_signature in kat-v1.json to verify against unmodified FIPS 204 ML-DSA.Verify(pk, message, signature) returning accept. The cross-validation harness at test/interoperability/ runs each KAT through:

  • the reference implementation in ref/go/
  • the FIPS 204 reference (Dilithium pq-crystals C reference)
  • a third independent ML-DSA implementation (BoringSSL FIPS or OpenSSL 3.0 PQ provider, whichever is available)

A KAT mismatch with any of the three is a release blocker.

Determinism

Every entry in kat-v1.json is reproducible from master_seed (a 48-byte hex value at the head of the file). scripts/gen_vectors.sh must produce byte-identical output on any fresh checkout. Drift here is a CI failure.

Status

  • KAT generator (ref/go/cmd/genkat) — implementation pending
  • First v1 KAT set
  • FIPS 204 cross-validation
  • Independent-impl cross-validation
  • Encoded into vectors/transcripts/ for (n, t) ∈ {(3,2), (5,3), (7,5), (10,7), (16,11), (32,21)}