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
9.4 KiB
TRUSTED-COMPUTING-BASE — Pulsar EC/Jasmin/OCaml TCB
What you must trust below the residual EasyCrypt axioms. Companion to
AXIOM-INVENTORY.md(the axioms above the TCB) andPROOF-CLAIMS.md(the proof scope).
The Pulsar Class N1 byte-equality theorem rests on three layered trust bases:
- EasyCrypt residual axioms — enumerated in
AXIOM-INVENTORY.md. - Lean theorems used as bridges — enumerated in
proofs/lean-easycrypt-bridge.md. - The trusted-computing base (TCB) below the proof tools — THIS document.
If any element of the TCB is unsound, the proof's conclusion is unsound regardless of the axiom inventory.
§1 Verifier TCBs
| Layer | What you trust | Why |
|---|---|---|
| EasyCrypt prover | Soundness of the EC type-checker, tactic engine, and byphoare/equiv Hoare-logic implementation. Specifically: easycrypt-dev at git-hash 909464e (pinned via opam in jasmin switch). |
EC's soundness is the foundation of the refinement proof. Bugs in EC could allow proofs that don't actually establish what they claim. |
| Lean 4 + Mathlib | Soundness of the Lean 4 kernel and Mathlib's polynomial-Lagrange theory. Specifically: lean4 at version listed in ~/work/lux/proofs/lean/lean-toolchain. |
The 5 Lean-bridged axioms (lagrange_inverse_eval, threshold_partial_response_identity, etc.) trust Lean's kernel to have verified the corresponding theorems. |
| Jasmin verified compiler | Soundness of the Jasmin → assembly compilation chain. Specifically: jasminc from ~/.opam/jasmin/bin. |
The threshold layer's constant-time guarantees and byte-walk correctness depend on Jasmin compiling the .jazz sources to assembly that preserves semantics. |
| OCaml runtime | OCaml's runtime correctness (the language EasyCrypt is implemented in). | EC is an OCaml program; OCaml bugs could affect EC's soundness. |
| Operating-system kernel and CPU | The host kernel scheduler, memory protections, and CPU instruction semantics. | Standard for any cryptographic implementation; not Pulsar-specific. |
§2 Build TCBs
| Layer | What you trust | Reproducibility |
|---|---|---|
opam switch jasmin |
The specific opam package versions captured at submission time. | Pinned via opam switch export (committed to repo) |
| Go toolchain | The Go compiler used to build ref/go/. |
Version pinned in go.mod |
scripts/build.sh |
The build orchestrator's correctness — that it produces deterministic outputs from a fresh checkout. | CI runs the script on every commit; reproducible-build property is load-bearing for the NIST submission. |
scripts/check-high-assurance.sh |
The gate orchestrator — that all 7 per-push checks actually fail when they should. | Each per-check script is independently runnable (scripts/checks/*.sh); the orchestrator just sequences them. |
scripts/test.sh |
The test harness's correctness — that KAT vectors compare bit-by-bit, not just lex-equal. | Reviewed; reference impl uses bytes.Equal for KAT comparison. |
scripts/gen_vectors.sh |
Deterministic generation of KAT vectors from seed. | The 48-byte seed is committed; KATs regenerate deterministically. |
§3 Implementation TCBs
§3.1 Reference implementation (ref/go/)
| Component | Trust | Mitigations |
|---|---|---|
Go reference impl (ref/go/pkg/pulsar/) |
Standard library correctness, crypto/rand randomness quality |
Reviewed; cross-validated against pq-crystals reference + BoringSSL FIPS |
cloudflare/circl (ML-DSA-65 single-party reference for cross-validation) |
Upstream Cloudflare CIRCL library | Version pinned in go.mod |
| Encoding/decoding of FIPS 204 byte formats | Direct from FIPS 204 §3.5 spec text | Reviewed against test vectors |
§3.2 Production targets (out of scope for v0.1)
| Target | Status |
|---|---|
| Optimized Rust crate | TODO (Tier 1) — not in this submission |
| C library + FFI | TODO (Tier 1) |
| WASM build | TODO (Tier 2) |
| no_std embedded | TODO (Tier 2) |
For each future target, an independent constant-time audit + KAT cross-validation + binding-level fuzzing is required before considering it "production." The Class N1 byte-equality theorem does NOT automatically transfer to these targets — each target's correctness must be re-verified.
§4 Jasmin / libjade TCB
| Layer | What you trust |
|---|---|
jasmin/ml-dsa-65/ (libjade ML-DSA-65 single-party baseline) |
Upstream Formosa-Crypto libjade Dilithium-3 Jasmin sources at the pinned commit. Fetched on-demand by jasmin/ml-dsa-65/fetch.sh. |
jasmin/threshold/{round1,round2,combine}.jazz |
Pulsar threshold-layer Jasmin sources (~1400 lines total). Hand-written, reviewed. |
| Jasmin → EasyCrypt extraction | The jasmin extract -lang EC tool. Currently version-pinned to a specific Formosa-Crypto build. |
| jasmin-ct (constant-time analyzer) | Soundness of jasmin-ct's type system for detecting secret-dependent control flow. Threshold layer green (3/3); libjade sign advisory (#2). |
§5 What the TCB does NOT include
These are explicitly NOT part of the trust base for the N1 byte-equality theorem:
- Specific operating system (Linux, macOS, BSD, Windows) — the proof is OS-independent.
- Specific CPU architecture — the Jasmin sources target x86_64 with documented ARM port path; the EC proof is architecture- independent.
- Network protocol stack — Pulsar's transport is out of scope for the byte-equality theorem.
- Storage layer — how
skis stored at rest is out of scope. - Key management policies — key lifecycle is application-level.
- Application code calling Pulsar — Pulsar's API contract is the trust boundary.
§6 TCB risks and mitigations
§6.1 EasyCrypt soundness bugs
| Risk | Mitigation |
|---|---|
A latent bug in EC's equiv tactic could allow proofs that don't actually establish refinement |
Pin EC to a specific commit; track upstream bug reports; cross-validate critical theorems via multiple proof paths (e.g., byphoare vs equiv) |
| Inconsistent axiom additions could derive ⊥ | Hard-pinned admit budget = 0/0; ec-regressions.sh flags retired axiom shapes; ec-refinement-scaffold.sh flags untracked declare axiom additions |
§6.2 Lean soundness bugs
| Risk | Mitigation |
|---|---|
| Lean kernel bug could invalidate a bridged theorem | Lean 4 + Mathlib are widely used; bugs are rare and quickly patched. Pin to specific Mathlib version. |
| Bridge mistranslation between Lean theorem statement and EC axiom statement | scripts/check-lean-bridge.sh verifies axiom-name + Lean-theorem-name + file existence at every per-push CI run; manual review of bridge correspondence at axiom-introduction commits |
§6.3 Jasmin compiler bugs
| Risk | Mitigation |
|---|---|
| Jasmin compiler emits assembly that doesn't preserve semantics | Jasmin is a verified compiler — the verified path goes Jasmin → safety-checked IR → register-allocated assembly. Bugs in the verifier itself are the residual risk. |
| Side-channel timing bug despite jasmin-ct green | jasmin-ct is a STATIC analyzer; it doesn't catch micro-architectural leakage. Pair with dynamic dudect tests (ct/dudect/ — nightly, 10⁹ samples). |
§6.4 Build reproducibility breaks
| Risk | Mitigation |
|---|---|
scripts/build.sh produces non-deterministic output |
The build is currently deterministic from a 48-byte seed; reproducible-build property is checked on CI. Drift triggers a CI failure. |
| Toolchain version drift between commits | opam switch pin + go.mod toolchain directive |
§7 Independent verification protocol
To independently verify Pulsar's claims, a reviewer should:
- Clone the repo at the submission tag.
- Set up the opam switch as documented in
README.md. - Run
scripts/build.sh— expect deterministic output. - Run
scripts/check-high-assurance.sh— expect 0/0 admits + 5/5 Lean bridges + 13/13 EC compile. - Run
scripts/test.sh— expect KAT cross-validation against 3 independent ML-DSA implementations. - Run
scripts/bench.sh— expect performance within published bounds. - Read
AXIOM-INVENTORY.mdand verify each axiom's statement matches the cited file:line. - For Lean-bridged axioms, clone the Lean repo and verify the Lean theorems compile + prove what the bridge document claims.
If all 8 steps pass, the trust base reduces to the TCB enumerated in this document.
§8 What this means for downstream consumers
For a downstream consumer (e.g., a blockchain protocol incorporating Pulsar):
- The proof transfer is conditional on the TCB. If you change the build toolchain, recompile EC theorems, or port to a different platform, the proof's transferable guarantees attenuate.
- For FIPS 140-3 module validation, you need an end-to-end audit of the production module (Pulsar reference impl is not a FIPS module by itself). Pulsar's role is the algorithm-level reference + proof artifact; module packaging is downstream.
- For ACVP/CAVP algorithm validation, you can use Pulsar's reference implementation as the input to a lab-run validation; the proof artifact strengthens the implementation-correctness argument but does NOT substitute for algorithm-conformance testing.
Document metadata
- Name:
TRUSTED-COMPUTING-BASE.md - Version: v1.0 (post v10)
- Date: 2026-05-18
- EC version pin:
git-hash 909464e(opam switchjasmin) - Lean version pin: see
lean-toolchainfile in~/work/lux/proofs/lean/