Single repo, one canonical impl + spec + proofs + KAT + cut tool.
Per "ONE and ONLY ONE way to do things" the prior dual-repo split
(luxfi/pulsar = production library, luxfi/pulsar-mptc = NIST MPTC
submission framework) is collapsed into a single canonical home at
github.com/luxfi/pulsar. SINGLE-IMPL-PLAN.md (now marked COMPLETED)
describes the steps; this commit lands the final step.
Files moved (89 new):
16 submission docs (SUBMISSION, NIST-SUBMISSION, SPEC, SUITE,
PATENTS, AXIOM-INVENTORY, PROOF-CLAIMS, FIPS-TRACEABILITY,
TRUSTED-COMPUTING-BASE, HANZO-CRYPTO-SUITE, INFORMATION-
ARCHITECTURE, ROADMAP, CHANGELOG, SYNC-STATUS, STATUS-
SUBMISSION-READINESS, SINGLE-IMPL-PLAN)
10 docs/ supplements (ietf-draft-skeleton, magnetar, evaluation,
patent-claims, x-wing-sig, design-decisions, family-architecture,
threat-model, nist-mptc-category, patent-notes-draft)
19 proofs/ (13 EC theories + 2 EC lemmas + 4 metadata/READMEs +
lean-easycrypt-bridge.md)
14 jasmin/ (lib/* + ml-dsa-65 fetch + threshold/{combine,round1,
round2}.jazz + READMEs)
10 ct/dudect/ (Makefile, combine_ct.go, dudect_combine.c,
dudect_compat.h, dudect_verify.c, fetch.sh, README, run-
submission.sh, verify_ct.go) + ct/jasmin-ct-libjade.md
1 .github/workflows/ci.yml
1 test/interoperability/n1_class_test.go (19/19 N1 subtests)
1 bench/results/REPORT.md
11 scripts/ (cut-submission, check-high-assurance, check-lean-
bridge, nightly, extract-jasmin-ec, checks/{ec-admits, ec-
compile, ec-refinement-scaffold, ec-regressions, extraction,
jasmin}, checks/test/{go-unit, interop, kat, no-secret-logs})
Files merged (16 overlapping, mptc-canonical chosen because newer +
post-rewire-correct; pulsar versions still bore stale "Pulsar-M" /
"pulsarm" branding):
README.md, BLOCKERS.md, CONTRIBUTING.md, LICENSE, LICENSING.md,
SECURITY.md, .gitignore, bench/run_all.sh, vectors/dkg.json (v1.0.7
regen), scripts/{bench,build,gen_vectors,sbom,test}.sh,
spec/{pulsar,parameters,system-model}.tex,
CRYPTOGRAPHER-SIGN-OFF.md (path refs).
Pulsar-only spec supplements preserved:
spec/{blockers,design-decisions,family-architecture,nist-mptc-
category,patent-notes,threat-model}.tex.
Path rewrites applied: 158 occurrences across 26 files
github.com/luxfi/pulsar-mptc -> github.com/luxfi/pulsar
~/work/lux/pulsar-mptc/ -> ~/work/lux/pulsar/
luxfi/pulsar-mptc -> luxfi/pulsar
pulsar-mptc/ -> ./
Narrative collapses (no more two-repo framing):
SUBMISSION.md "At a glance" — single Repository row
SYNC-STATUS.md — rewritten to single-repo state
SINGLE-IMPL-PLAN.md — marked COMPLETED 2026-05-18
HANZO-CRYPTO-SUITE.md — tier 1 row = single canonical home
scripts/cut-submission.sh — replace/vendor dance removed; cuts
directly from in-tree canonical sources
go.mod: dropped mptc's replace directive (no longer needed since this
IS the canonical pulsar repo). Module path is github.com/luxfi/pulsar.
Deps: cloudflare/circl v1.6.3, golang.org/x/crypto v0.32.0.
Verification:
GOWORK=off go build ./... PASS
GOWORK=off go test -count=1 ./... PASS (1.4s)
GOWORK=off go test -race ./ref/... PASS (14.7s)
go test ./test/interoperability/ PASS (19/19 N1 subtests)
scripts/check-high-assurance.sh PASS
scripts/check-lean-bridge.sh PASS (5/5 bridges)
scripts/gen_vectors.sh byte-identical replay
scripts/cut-submission.sh --help PASS
Pulsar — EasyCrypt theories
This directory holds the EasyCrypt theories for Pulsar's
high-assurance track. EasyCrypt
(https://github.com/EasyCrypt/easycrypt) is the machine-checked
proof assistant for cryptographic protocols paired with Jasmin
(../../jasmin/). The libjade single-party ML-DSA-65 EasyCrypt
theories are imported from ../../jasmin/ml-dsa-65/libjade/
(fetched on demand); the Pulsar-specific theories live here.
Headline
The high-assurance stack is now structurally ready for final mechanized closure. All local EasyCrypt theorem bodies are admit-free, per-push gates are green, threshold Jasmin CT is blocking, fuzz / KAT / interop / dudect gates are wired at documented budgets, and the extracted N1 theorem has no section-local module-contract axioms. The only remaining implementation-refinement assumptions are two localized byte-walk axioms over pure signature output, each with a committed proof roadmap. The Lean↔EC algebraic bridge is named, cited, and CI-guarded.
The next proof-count milestone is combine_body_compute_sig_spec:
closing it reduces the implementation-refinement cone from 2 to 1.
Status — current trust boundary
| Item | Count |
|---|---|
| Section-local module-contract axioms in extracted N1 corollary | 0 |
| Localized implementation-refinement axioms in dependency cone | 2 |
| Lean-bridged algebraic axioms (Lagrange/Shamir) | 4 |
EasyCrypt admit budget |
0 / 0 |
| EC files in the per-push gate | 13 |
declare axiom in refinement scaffolds |
0 |
The 2 remaining implementation-refinement axioms are byte-walks over the pure signature output of the extracted Jasmin procedures:
Pulsar_N1_Combine_Refinement.combine_body_compute_sig_spec(tracked #4; roadmap inextraction/combine-byte-walk-roadmap.md)Pulsar_N1_Sign_Refinement.sign_body_compute_sig_spec(tracked #3; roadmap inextraction/sign-byte-walk-roadmap.md; ghost contract for ctx/rho_rnd documented in the named block insidePulsar_N1_Sign_Refinement.ec)
The 4 Lean-bridged axioms are the Shamir / Lagrange algebraic
identities that EasyCrypt's first-order theory does not natively
cover. Each corresponds 1:1 to a proved Lean theorem in
~/work/lux/proofs/lean/Crypto/; the correspondence is named
inline (see comments preceding the axioms in Pulsar_N1.ec and
Pulsar_N4.ec) and operationally guarded by
../../scripts/check-lean-bridge.sh. See
../lean-easycrypt-bridge.md for the full correspondence table.
Strict closure is not reached. Every other obligation — module contracts, wrapper bridges, memory-frame separations, layout-correctness conjuncts, ABI bridge identities — has been collapsed to a lemma or eliminated by the structural decomplect.
Files
Layered structure (each file owns one concern; the dependency graph is acyclic and explicit):
| File | Concern |
|---|---|
Pulsar_N1.ec |
Class N1 protocol-level spec: abstract types, Pulsar_Threshold + MLDSA65_Sign module types, FIPS204Sign + CombineAbs modules, generic pulsar_n1_byte_equality theorem (inside section ClassN1) |
Pulsar_N4.ec |
Class N4: public-key preservation across proactive resharing (committee rotation) |
Pulsar_N1_Memory.ec |
Byte-memory model: mem_t, load/store primitives + proved frame laws. No axioms |
Pulsar_N1_Signature_Codec.ec |
FIPS 204 §3.5.5 signature codec: signature_t, encode/decode/length, memory read/write + proved frame lemmas |
Pulsar_N1_Combine_Layout.ec |
Combine ABI: c_tilde / t0 / r2_msg wire types + encoders, combine_ptrs_t, layout_combine_args, proved encode_combine_args_layout |
Pulsar_N1_Sign_Layout.ec |
libjade Sign ABI: sk + message wire types + encoders, sign_ptrs_t, layout_sign_args, proved encode_sign_args_layout |
Pulsar_N1_Combine_Refinement.ec |
Combine refinement scaffold: combine_full_args_t ghost args, combine_abs_op definition, the one remaining byte-walk axiom (combine_body_compute_sig_spec), derived lemmas |
Pulsar_N1_Sign_Refinement.ec |
Sign refinement scaffold: sign_full_args_t (ghost ctx/rho_rnd contract block), sign_abs_op definition, the one remaining byte-walk axiom, derived lemmas |
Pulsar_N1_Combine_Wrapper.ec |
Combine wrapper module + bridge lemma + procedure-level equiv against CombineAbs |
Pulsar_N1_Sign_Wrapper.ec |
Sign wrapper module + bridge lemma + procedure-level equiv against FIPS204Sign |
Pulsar_N1_Extracted.ec |
Composition: the concrete extracted N1 byte-equality corollary (applies Pulsar_N1.pulsar_n1_byte_equality with the two wrapper-bridge equivs) |
lemmas/MLDSA65_Functional.ec |
FIPS 204 ML-DSA-65 functional ops (pack_signature, sample_in_ball, expand_a, etc.) |
lemmas/Pulsar_CT.ec |
Constant-time obligations under the Barthe–Grégoire–Laporte leakage model |
Dependency layering:
Pulsar_N1 ──┐
│
Memory ── Signature_Codec
│ │
├── Combine_Layout Sign_Layout
│ │ │
│ Combine_Refinement Sign_Refinement
│ │ │
│ Combine_Wrapper Sign_Wrapper
│ │_________ Extracted ____│
│
└── (Pulsar_N1: protocol types + module types + generic theorem)
Sign_Layout no longer transitively depends on combine-specific
encoders. The two layouts are siblings sharing Memory +
Signature_Codec.
Conventions
admitis banned (budget 0/0; enforced by../../scripts/checks/ec-admits.sh).declare axiomis banned in refinement scaffolds (enforced by../../scripts/checks/ec-refinement-scaffold.sh).- Lean-bridged axioms carry an inline citation comment naming the
Lean theorem and file (enforced by
../../scripts/check-lean-bridge.sh). - Per-push gate is real-budget:
../../scripts/check-high-assurance.shruns every check at the budget that matters (jasmin-ct, EC admit budget, EC regression guards, refinement-scaffold guard, Lean bridge guard, Jasmin→EC extraction, EC compile). No smoke gates. - Real-budget dudect (10⁹ samples per target) + 1h-per-target
fuzz run from the nightly gate:
../../scripts/nightly.sh.
How to check
Per-push:
../../scripts/check-high-assurance.sh # proof gate
../../scripts/test.sh # Go test gate
Nightly (multi-hour, cron-scheduled):
../../scripts/nightly.sh
Per-check (independently runnable):
bash ../../scripts/checks/ec-compile.sh
bash ../../scripts/checks/jasmin.sh
bash ../../scripts/checks/ec-admits.sh
bash ../../scripts/check-lean-bridge.sh
# ... etc, see scripts/checks/
Citations
- Barthe, Grégoire, Laporte. Secure compilation of side-channel countermeasures: The case of cryptographic constant-time. CSF 2018.
- Barbosa, Barthe, Doczkal, Don, Fehr, Grégoire, Huang, Hülsing, Lee, Wu. Fixing and Mechanizing the Security Proof of Fiat–Shamir with Aborts and Dilithium. CRYPTO 2023.
- Almeida et al. Formally verifying Kyber. CRYPTO 2024.
- libjade ML-DSA EasyCrypt theories — https://github.com/formosa-crypto/libjade/tree/main/proof
Cross-references
../lean-easycrypt-bridge.md— Lean↔EC axiom correspondence tableextraction/combine-byte-walk-roadmap.md— combine byte-walk sub-step decomposition (10 sub-claims)extraction/sign-byte-walk-roadmap.md— sign byte-walk sub-step decomposition (7 sub-claims)../../ct/jasmin-ct-libjade.md— libjade jasmin-ct issue write-up (tracked #2)