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]>
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)}