mirror of
https://github.com/luxfi/pulsar.git
synced 2026-09-24 00:25:52 +00:00
pulsar-m: convert NIST MPTC deliverables docs/*.md → spec/*.tex (CLAUDE.md LaTeX-only rule)
Per ~/.claude/CLAUDE.md ("papers/proofs/audits stay in LaTeX, never .md"
+ "NEVER write random summary files"), the six NIST MPTC submission
deliverables move from docs/ Markdown into spec/ LaTeX as
\input{...} chapters of pulsar-m.tex:
docs/nist-mptc-category.md -> spec/nist-mptc-category.tex
docs/patent-notes-draft.md -> spec/patent-notes.tex
docs/threat-model.md -> spec/threat-model.tex
docs/known-limitations.md -> spec/known-limitations.tex
docs/family-architecture.md -> spec/family-architecture.tex
docs/design-decisions.md -> spec/design-decisions.tex
Content preserved verbatim; only LaTeX-syntax stylistic edits.
pulsar-m.tex now \inputs each as its own section / appendix.
Go-source comments that referenced docs/* updated to spec/*.tex.
README + CONTRIBUTING refreshed.
GOWORK=off go test -count=1 ./... clean.
This commit is contained in:
+1
-1
@@ -70,4 +70,4 @@ By contributing, you agree your contribution is licensed under Apache-2.0
|
||||
and grant the patent license described in the Apache 2.0 §3.
|
||||
|
||||
For NIST MPTC submission: contributions are subject to the patent-claim
|
||||
disclosures collected in `docs/patent-notes-draft.md`.
|
||||
disclosures collected in `spec/patent-notes.tex`.
|
||||
|
||||
@@ -71,7 +71,7 @@ pulsar-m/
|
||||
## Quickstart
|
||||
|
||||
> **Pulsar-M is in pre-spec stage.** Reference impl, vectors, and bench harness
|
||||
> ship after the spec freezes. Track [docs/known-limitations.md](docs/known-limitations.md)
|
||||
> ship after the spec freezes. Track [spec/known-limitations.tex](spec/known-limitations.tex)
|
||||
> for what's stable vs in-flight.
|
||||
|
||||
```bash
|
||||
@@ -90,7 +90,7 @@ cd pulsar-m
|
||||
| Technical Specification | `spec/pulsar-m.pdf` (built from `spec/pulsar-m.tex`) | draft |
|
||||
| Reference Implementation | `ref/go/` | skeleton |
|
||||
| Report on Experimental Evaluation | `bench/results/REPORT.md` | TBD |
|
||||
| Notes on Patent Claims | `docs/patent-notes-draft.md` | TBD |
|
||||
| Notes on Patent Claims | `spec/patent-notes.tex` | TBD |
|
||||
| Open-source license | `LICENSE` (Apache-2.0) | ✓ |
|
||||
| Build/test/benchmark scripts | `scripts/` | skeleton |
|
||||
| I/O test vectors | `vectors/kat-v1.{json,rsp}` | TBD |
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
# Design decisions log
|
||||
|
||||
Each entry: decision, rationale, alternatives, status, date.
|
||||
|
||||
## DD-001 Target FIPS 204 output interchangeability (Class N)
|
||||
|
||||
**Decision.** Pulsar-M aims for Class N1 + N4 (NIST MPTC IR 8214C):
|
||||
threshold-produced signatures verify under unmodified FIPS 204
|
||||
ML-DSA.Verify.
|
||||
|
||||
**Rationale.** Output interchangeability gives the strongest NIST
|
||||
positioning. FIPS-validated ML-DSA modules in 2026 (BoringSSL FIPS,
|
||||
AWS-LC, OpenSSL 3.0) consume Pulsar-M certs without code changes. This
|
||||
is the headline pitch for MPTC.
|
||||
|
||||
**Alternative.** Class S (special threshold-friendly primitive). Easier
|
||||
spec, but does not give the FIPS-module-compatibility win. Pulsar
|
||||
(R-LWE) takes this path.
|
||||
|
||||
**Status.** Targeted. Final class decision deferred until reference impl
|
||||
demonstrates byte-equal output on at least one parameter set.
|
||||
|
||||
## DD-002 Hash family: SHA-3 (cSHAKE256 / KMAC256 / TupleHash256) only
|
||||
|
||||
**Decision.** Pulsar-M's NIST profile uses exclusively the FIPS 202 + SP
|
||||
800-185 hash family. No BLAKE3.
|
||||
|
||||
**Rationale.** NIST MPTC §4.6 lists allowed symmetric primitives for
|
||||
Class N: AES, Ascon, SHA-2, SHA-3, SHAKE/cSHAKE, HMAC/KMAC/CMAC/GMAC.
|
||||
BLAKE3 is not on the list. Including BLAKE3 in the NIST submission
|
||||
profile is a strategic liability.
|
||||
|
||||
The same SHAKE-256 sponge is used internally by ML-DSA-65 (FIPS 204
|
||||
§5.1). Sharing the hash family with the underlying primitive removes a
|
||||
whole class of cryptanalytic concern (cross-domain collisions, mixed
|
||||
hash-family soundness arguments).
|
||||
|
||||
**Alternative considered.** Dual-suite with BLAKE3 as the production
|
||||
profile and SHA-3 as the NIST profile, like Pulsar's current dual-suite.
|
||||
Rejected because Pulsar-M is NIST-track and shouldn't ship a non-NIST
|
||||
default.
|
||||
|
||||
**Status.** Final.
|
||||
|
||||
## DD-003 Lattice: Module-LWE per FIPS 204, not Ring-LWE
|
||||
|
||||
**Decision.** Pulsar-M operates over `R_q^k` (module of polynomials)
|
||||
with the same `(q, k, ℓ, η, β, ω, ...)` parameter set as ML-DSA-65.
|
||||
Not `R_q` (single polynomial) as Pulsar / Corona use.
|
||||
|
||||
**Rationale.** This is the whole point of the project. Class N1
|
||||
interchangeability requires the protocol's signing operation to land on
|
||||
exactly the FIPS 204 σ encoding, which is M-LWE-shaped.
|
||||
|
||||
**Alternative.** Stay R-LWE. Easier (we already have Pulsar). But then
|
||||
we lose the Class N positioning and become Class S like Pulsar.
|
||||
|
||||
**Status.** Final.
|
||||
|
||||
## DD-004 Reference implementation language: Go
|
||||
|
||||
**Decision.** Reference implementation is Go (`ref/go/`). C
|
||||
implementation comes after spec encodings freeze (`ref/c/`).
|
||||
|
||||
**Rationale.** Go matches Pulsar's reference; reuses our Pedersen DKG
|
||||
and reshare patterns from `pulsar/dkg2/` and `pulsar/reshare/`. Clear,
|
||||
boring, no assembly. NIST MPTC §4.3 doesn't mandate language.
|
||||
|
||||
**Alternative.** C reference first. Standard NIST PQC submission style.
|
||||
Rejected for round 1 because we need to ship by 2026-Nov-16; Go is
|
||||
faster to write and review. C reference becomes a follow-on artifact
|
||||
for round 2 review.
|
||||
|
||||
**Status.** Final for MPTC round 1.
|
||||
|
||||
## DD-005 DKG: Pedersen-style over `R_q^k`
|
||||
|
||||
**Decision.** Distributed keygen uses Pedersen DKG over the M-LWE module
|
||||
ring, with Feldman-style verifiable secret sharing replaced by the
|
||||
module-shaped Pedersen commitment scheme.
|
||||
|
||||
**Rationale.** Pulsar's `dkg2/` package already does this for `R_q`
|
||||
(R-LWE). The M-LWE port preserves the soundness argument with constant
|
||||
overhead per coefficient slot.
|
||||
|
||||
**Alternative.** Trusted-dealer DKG (academic Corona). Rejected:
|
||||
incompatible with open public chains (HIP-0077 §"Pulsar vs Corona").
|
||||
|
||||
**Status.** Final.
|
||||
|
||||
## DD-006 Proactive resharing: HJKY97-style with beacon-randomized quorum
|
||||
|
||||
**Decision.** Long-lived deployments use proactive secret resharing with
|
||||
a beacon-derived per-reshare quorum selection (not deterministic
|
||||
smallest-ID).
|
||||
|
||||
**Rationale.** Deterministic quorum selection (Pulsar's current
|
||||
`reshare.go:206-209`) lets a mobile adversary game the corrupt-set
|
||||
positioning. HIP-0077 red review F10 flagged this. Pulsar-M's reshare
|
||||
selects via the chain's randomness beacon at the reshare epoch boundary.
|
||||
|
||||
**Alternative.** Deterministic quorum, accept the leakage as a documented
|
||||
limitation. Rejected for MPTC submission.
|
||||
|
||||
**Status.** Final.
|
||||
|
||||
## DD-007 No application-level logging in secret-touching code paths
|
||||
|
||||
**Decision.** Secret-touching functions (Sign, Verify-of-shares, DKG
|
||||
verification, reshare verification) emit zero log lines. Constant-time
|
||||
analysis treats any log call as a failed gate.
|
||||
|
||||
**Rationale.** Pulsar's pre-fix `log.Println(Bsquare, sumSquares)` in
|
||||
`sign.go` (HIP-0077 red F8) is exactly the failure mode this rule
|
||||
prevents. A logged value derived from secret state is a side channel
|
||||
even at debug level.
|
||||
|
||||
**Alternative.** Allow debug logging gated by build tag. Rejected:
|
||||
build tags get accidentally enabled in production; the rule is
|
||||
absolute.
|
||||
|
||||
**Status.** Final. CI gate: `go vet -vettool=...` plus a custom linter
|
||||
that rejects `log.*`, `fmt.Print*`, `panic` in `pkg/sign/`, `pkg/dkg/`,
|
||||
`pkg/reshare/`.
|
||||
|
||||
## DD-008 Encoding freeze before C reference
|
||||
|
||||
**Decision.** Reference Go locks every byte of the wire encoding before
|
||||
the C reference begins. Inputs to the freeze: spec §"Encodings", KAT
|
||||
suite v0, cross-vendor review with at least one external lattice impl
|
||||
team.
|
||||
|
||||
**Rationale.** Two implementations diverging on encoding is a recurring
|
||||
source of NIST PQC submission rejections. Freeze first, port second.
|
||||
|
||||
**Status.** Targeted for end of August 2026.
|
||||
|
||||
## DD-009 Patent claims: prepared in advance
|
||||
|
||||
**Decision.** Patent-claim disclosures collected in
|
||||
`docs/patent-notes-draft.md` from day 1 of the repo. Every contribution
|
||||
adds the contributor's patent-claim notice (or explicit "no claims").
|
||||
|
||||
**Rationale.** NIST MPTC §6 requires Notes on Patent Claims as a package
|
||||
deliverable. Late collection blows up the submission timeline.
|
||||
|
||||
**Status.** In progress.
|
||||
|
||||
## DD-010 Two-track NIST plan: MPTC now, CMVP later
|
||||
|
||||
**Decision.** Track A targets MPTC submission 2026-Nov-16. Track B
|
||||
prepares for eventual NIST PQC standardization + CMVP module
|
||||
validation, which is a multi-year process not scheduled.
|
||||
|
||||
**Rationale.** MPTC is the active NIST process for threshold schemes
|
||||
right now. CMVP requires an approved standard, which threshold schemes
|
||||
don't yet have. We can prepare a clean module boundary for future CMVP
|
||||
work without waiting for the standard.
|
||||
|
||||
**Status.** Track A active. Track B is a parallel readiness exercise,
|
||||
not a near-term gate.
|
||||
@@ -1,190 +0,0 @@
|
||||
# The Pulsar threshold-signature family
|
||||
|
||||
> **Pulsar** is one name for a family of lattice-based threshold signature
|
||||
> schemes. Variants share the same protocol skeleton (2-round threshold
|
||||
> sign, Pedersen DKG with proper hiding, proactive resharing,
|
||||
> identifiable abort) but differ in the underlying lattice problem and
|
||||
> NIST-compatibility target.
|
||||
|
||||
This document is the canonical statement of the family architecture.
|
||||
Every Pulsar variant references it. Every NIST submission cites it.
|
||||
Every consumer that wires "the Pulsar family" into a downstream system
|
||||
points here for the variant table.
|
||||
|
||||
## Variants
|
||||
|
||||
| variant | repo (target) | lattice basis | hash family (canonical) | FIPS 204 verifier interchange? | NIST MPTC class | status |
|
||||
|-----------|-----------------------------------|---------------|--------------------------------|--------------------------------|-----------------|-------------------------------|
|
||||
| **Pulsar** (was Pulsar.M / pulsar-m) | `github.com/luxfi/pulsar` | Module-LWE (`R_q^k`) | SHA-3 / cSHAKE256 (SP 800-185) | yes — output is a single FIPS 204 ML-DSA σ | Class N1 + N4 | this repo; reference complete, KAT-pinned |
|
||||
| **Corona** (was Pulsar.R / luxfi/pulsar) | `github.com/luxfi/corona` | Ring-LWE (`R_q`) | SHA-3 / cSHAKE256 (SP 800-185) | no — special threshold-friendly primitive | Class S1 + S4 | production R-LWE fork, lifecycle DKG complete |
|
||||
| **Corona** (academic upstream + Lux expansions) | `github.com/luxfi/corona` | Ring-LWE (`R_q`) | BLAKE3 (academic) / SHA-3 (Lux expansions) | no | academic | upstream + lifecycle DKG expansions in flight |
|
||||
|
||||
All variants share:
|
||||
|
||||
- **Protocol skeleton** — 2-round threshold sign, Pedersen DKG, proactive
|
||||
resharing with beacon-randomized quorum, identifiable abort with signed
|
||||
complaints.
|
||||
- **Hash suite** — NIST SP 800-185 (cSHAKE256, KMAC256, TupleHash256) is
|
||||
canonical for every NIST-track variant. BLAKE3 deltas appear only in
|
||||
legacy / academic profiles (`Pulsar.R-BLAKE3`, upstream Corona) and
|
||||
are explicitly out-of-scope for any MPTC submission.
|
||||
- **Constant-time discipline** — every secret-touching path constant-time
|
||||
via `crypto/subtle` or local equivalents. No stdlib `log` in any
|
||||
primitive package; all logging goes through `github.com/luxfi/log` at
|
||||
fields the threat model has explicitly classified as public.
|
||||
- **Implementation language** — Go reference; C / Rust conformance after
|
||||
encoding-freeze gate per variant.
|
||||
|
||||
What differs between variants:
|
||||
|
||||
- **Algebra** — Ring-LWE for Corona, Module-LWE for Pulsar. The
|
||||
algebraic shape determines parameter sizes, signature sizes, and the
|
||||
structure of the Pedersen commitment scheme.
|
||||
- **Verification target** — Corona verifies under its own verifier
|
||||
(a custom 2-round-aggregated check); Pulsar verifies under
|
||||
unmodified FIPS 204 ML-DSA.Verify. The latter is the single highest-
|
||||
value property of the family.
|
||||
- **NIST submission posture** — see Class column above.
|
||||
- **Production maturity** — Pulsar.R has a hardened reshare path,
|
||||
KAT suite, deployed code. Pulsar.M has a complete spec
|
||||
(`spec/pulsar-m.tex` plus `parameters.tex`, `system-model.tex`,
|
||||
`security-games.tex`), a working Go reference (single-party and
|
||||
threshold paths, both GF(257) and GF(q) Shamir layers), and a
|
||||
KAT suite. The scaling target N* = 1,111,111 is empirically
|
||||
validated. Production hardening (HSM integration, formal CT
|
||||
guarantees, cross-implementation conformance vs. BoringSSL FIPS /
|
||||
AWS-LC / OpenSSL 3) is round-2 work.
|
||||
|
||||
## Why one family
|
||||
|
||||
NIST MPTC IR 8214C accepts each variant as a separate submission package
|
||||
in either Class N or Class S. Submitting two as a coordinated **family**:
|
||||
|
||||
1. **Reuses infrastructure once.** The DKG harness, KAT cross-validation,
|
||||
transcript binding, constant-time analysis, lattice-estimator runs,
|
||||
patent disclosure, and IP review build to a shared `pulsar-test/` and
|
||||
`pulsar-spec-common/` set of artifacts both submissions reference.
|
||||
2. **Cross-validates the protocol skeleton.** A reviewer attacking the
|
||||
Pedersen DKG soundness in Pulsar.R is also attacking it in Pulsar.M.
|
||||
Soundness arguments compose; reviewers don't have to redo work.
|
||||
3. **Demonstrates orthogonality.** Both submissions running on the same
|
||||
2-round structure with different lattice bases is itself a security
|
||||
argument: the family's robustness comes from a small, audited
|
||||
protocol skeleton with parameterized algebra, not from a one-off
|
||||
primitive.
|
||||
4. **Forwards-only.** Adding `Pulsar.W` (or whichever future variant)
|
||||
becomes a parameter-set + algebra change against the same skeleton,
|
||||
not a new project. The naming reservation is pre-paid.
|
||||
|
||||
## What goes where
|
||||
|
||||
| artifact | shared | Pulsar.R | Pulsar.M |
|
||||
|-----------------------------------|--------------|-----------------------------------|-------------------------------------|
|
||||
| 2-round protocol description | shared spec | parameterised for `R_q` | parameterised for `R_q^k` |
|
||||
| Pedersen DKG (proper hiding) | shared spec | params for `R_q` | params for `R_q^k` |
|
||||
| Proactive resharing (beacon-rand) | shared spec | params for `R_q` | params for `R_q^k` |
|
||||
| Reference Go impl | shared testkit | full primitive in `pulsar/` | full primitive in `pulsar-m/` |
|
||||
| KATs | shared format | `vectors/` per repo | `vectors/` per repo |
|
||||
| Lattice estimator | shared script | parameter file per variant | parameter file per variant |
|
||||
| Patent claims | shared review | repo-local `patent-notes.md` | repo-local `patent-notes.md` |
|
||||
| MPTC technical specification PDF | NO | `pulsar/spec/pulsar-r.pdf` | `pulsar-m/spec/pulsar-m.pdf` |
|
||||
| MPTC submission package | NO — separate Class S vs Class N | one per variant | one per variant |
|
||||
|
||||
Two separate MPTC packages, one shared technical foundation. The shared
|
||||
material is brought in by reference from each submission's spec PDF,
|
||||
matching how PQ-CRYSTALS submitted Dilithium and Kyber as related
|
||||
algorithms in Round 3.
|
||||
|
||||
## Naming discipline
|
||||
|
||||
Three sibling threshold-signature libraries; each is its own NIST
|
||||
MPTC submission package (no umbrella package).
|
||||
|
||||
- **Pulsar** — the FIPS 204-compatible Module-LWE threshold. Always
|
||||
capitalised, no hyphen, no suffix. Identifier form: `pulsar`.
|
||||
- **Corona** — the Ring-LWE production threshold (Lux's hardened fork
|
||||
of Corona). Always capitalised. Identifier form: `corona`.
|
||||
- **Corona** — the academic Ring-LWE upstream plus Lux's lifecycle
|
||||
DKG expansions. Always capitalised. Identifier form: `corona`.
|
||||
|
||||
Naming rules:
|
||||
|
||||
- Do not write "Pulsar.M" or "Pulsar-M" in new prose; both are the
|
||||
pre-rebrand legacy names of the M-LWE threshold (now just "Pulsar").
|
||||
- Do not write "Pulsar.R" or "Pulsar-R"; the R-LWE threshold is now
|
||||
"Corona" -- distinct name, distinct repo.
|
||||
- HashSuiteID byte (per HIP-0077 §"Lux consensus PQ modes") identifies
|
||||
the **hash family**, not the variant. Pulsar and Corona canonical
|
||||
profiles both use `HashSuiteSHA3 = 2`. A future Pulsar with a
|
||||
different hash family (e.g. SHAKE256 only) would claim a new
|
||||
HashSuiteID without renaming the variant.
|
||||
|
||||
## Repo organisation
|
||||
|
||||
```
|
||||
~/work/lux/
|
||||
├── pulsar/ ← Pulsar.R (R-LWE, production fork of Corona)
|
||||
│ ├── sign/
|
||||
│ ├── primitives/
|
||||
│ ├── dkg2/ ← Pedersen DKG over R_q
|
||||
│ ├── reshare/ ← proactive resharing
|
||||
│ ├── hash/ ← Pulsar-SHA3 + Pulsar-BLAKE3 (legacy)
|
||||
│ └── ...
|
||||
├── pulsar-m/ ← Pulsar.M (M-LWE, FIPS 204-compatible)
|
||||
│ ├── ref/go/
|
||||
│ ├── spec/ ← own MPTC technical spec PDF
|
||||
│ ├── docs/ ← family-architecture.md = THIS file
|
||||
│ └── ...
|
||||
├── corona/ ← academic upstream (NOT Pulsar; cited as the
|
||||
│ R-LWE 2-round skeleton's origin)
|
||||
└── consensus/
|
||||
└── protocol/quasar/ ← witness orchestrator that consumes Pulsar
|
||||
variants via WitnessProducer interface
|
||||
```
|
||||
|
||||
The `consensus/protocol/quasar/` orchestrator binds to Pulsar variants
|
||||
through `QWitnessProducer` (interface in
|
||||
`consensus/protocol/quasar/witness_producer.go`). Quasar doesn't know
|
||||
which variant produces the witness — it gets a `[]byte` and a
|
||||
HashSuiteID. Variants are interchangeable at the orchestration layer,
|
||||
which is exactly the orthogonality the family architecture claims.
|
||||
|
||||
## NIST submission strategy
|
||||
|
||||
Per CTO Decision 4 (recorded in this branch's HIP-0077 process notes):
|
||||
|
||||
> Submit BOTH. Pulsar.M leads (Class N1+N4, FIPS 204 verifier-interchangeable,
|
||||
> highest strategic value). Pulsar.R parallel (Class S1+S4, established
|
||||
> production code, demonstrates the family's R-LWE branch). Withdrawing
|
||||
> either wastes existing work; submitting both forces the team to factor
|
||||
> shared infrastructure into reusable modules — the orthogonality
|
||||
> requirement.
|
||||
|
||||
Single Git tag, simultaneous cut: `mptc-preview-2026` on `pulsar` and
|
||||
`pulsar-m` at the same SHA discipline. Both submissions reference frozen
|
||||
artifacts. Drift between the two repos after the tag is only allowed
|
||||
via amendments NIST permits in the public-analysis window.
|
||||
|
||||
## Status
|
||||
|
||||
- [x] Pulsar.R production code (shipping in Lux primary network)
|
||||
- [x] Pulsar.R hardening: F8 (no log of secret state), F9 (constant-time reshare), F12 (LIGHT_MNEMONIC guard)
|
||||
- [ ] Pulsar.R MPTC spec doc finalised (`pulsar/spec/pulsar-r.pdf` to be added)
|
||||
- [ ] Pulsar.R `mptc-preview-2026` tag
|
||||
- [x] Pulsar.M repo bootstrap (`pulsar-m/`)
|
||||
- [ ] Pulsar.M Module-LWE algorithm body in spec (in flight via scientist agent)
|
||||
- [ ] Pulsar.M reference implementation
|
||||
- [ ] Pulsar.M FIPS 204 cross-validation (output interchangeability proof)
|
||||
- [ ] Pulsar.M `mptc-preview-2026` tag
|
||||
- [ ] Family architecture cross-reference baked into HIP-0077
|
||||
|
||||
## See also
|
||||
|
||||
- HIP-0077 (`hanzo/hips/HIPs/hip-0077-mesh-identity-gossip-and-payments.md`)
|
||||
— defines the PQMode enum that selects which Pulsar variant the
|
||||
consensus layer asks for.
|
||||
- HIP-0078 (in flight) — Q-Chain PQ-rollup. Replaces Z-Chain Groth16/BN254
|
||||
with a PQ-secure SNARK. Pulsar.M's per-validator ML-DSA-65 sigs are the
|
||||
rollup target.
|
||||
- NIST IR 8214C — *First Call for Multi-Party Threshold Schemes* (January
|
||||
2026, package deadline 2026-Nov-16).
|
||||
@@ -1,206 +0,0 @@
|
||||
# Known limitations
|
||||
|
||||
Maintained as a living document. Better that reviewers see the gaps before
|
||||
they find them.
|
||||
|
||||
## Spec / protocol
|
||||
|
||||
### Output interchangeability with FIPS 204 — DEMONSTRATED IN v0.1
|
||||
|
||||
The headline claim — "Pulsar-M signatures verify under unmodified
|
||||
FIPS 204 ML-DSA.Verify" — holds for the v0.1 reference. The
|
||||
`pulsarm.Verify` entry point dispatches to
|
||||
`cloudflare/circl/sign/mldsa{44,65,87}.Verify` verbatim; the
|
||||
threshold-sign output is the same byte-for-byte signature an
|
||||
unmodified FIPS 204 signer would have produced on the
|
||||
reconstructed seed. KAT cross-validation lives at
|
||||
`ref/go/pkg/pulsarm/kat_test.go: TestKAT_ThresholdSign_Replay`,
|
||||
which verifies every committed threshold signature under
|
||||
`pulsarm.Verify` and therefore under the underlying FIPS 204
|
||||
verifier.
|
||||
|
||||
### v0.1 uses reconstruction-aggregator; v0.2 will use Lagrange-linearity
|
||||
|
||||
v0.1 instantiates the threshold protocol via a
|
||||
**reconstruction-aggregator** model: a threshold quorum delivers
|
||||
byte-wise Shamir shares of the FIPS 204 seed to an aggregator
|
||||
(any honest quorum member), which Lagrange-reconstructs the
|
||||
master byte-sum in GF(257), runs the deterministic cSHAKE256 mix
|
||||
that DKG committed to, and calls FIPS 204 Sign once. The master
|
||||
seed lives in the aggregator's memory for the duration of one
|
||||
Sign call.
|
||||
|
||||
The pulsar-m.tex §4.2 **Lagrange-linearity sign** path — each
|
||||
party computes `z_i = y_i + c · λ_i · s_i` locally and the
|
||||
aggregator sums them, with the master secret never reconstructed
|
||||
— is the v0.2 target. It is mathematically equivalent at the
|
||||
output level (the produced signature is byte-equal) but
|
||||
information-theoretically stronger because no party ever holds
|
||||
the master secret.
|
||||
|
||||
The v0.1 model is acceptable for the round-1 MPTC submission
|
||||
when paired with the reshare cadence specified in
|
||||
`spec/system-model.tex` (no aggregator holds a secret across more
|
||||
than one signature). v0.2 ships the stronger soundness property
|
||||
that adaptive-corruption analysis requires.
|
||||
|
||||
### Pedersen commitments: RO model in v0.1, M-LWE in v0.2
|
||||
|
||||
v0.1 uses cSHAKE256 RO-binding commitments
|
||||
`C_i = cSHAKE256(c_i || blind_i)`. v0.2 replaces them with the
|
||||
R_q^k Pedersen commitment of `spec/pulsar-m.tex` §3.2:
|
||||
`C_{i,k} = A · c_{i,k} + B · r_{i,k}`. Both bindings are sound;
|
||||
the v0.2 M-LWE binding is the post-quantum-safe variant required
|
||||
for the formal proof to reduce to an M-LWE / MSIS hardness
|
||||
assumption (the v0.1 RO-binding reduces to cSHAKE256 collision
|
||||
resistance, which itself reduces to SHA-3 security).
|
||||
|
||||
### Per-byte Shamir: dual-field design
|
||||
|
||||
v0.1 Shamir-shares the FIPS 204 seed byte-wise. The reference
|
||||
implementation supports two fields:
|
||||
|
||||
- **GF(257)** for committees with n ≤ 256 (default for small
|
||||
validator sets, 64-byte wire share).
|
||||
- **GF(q) = GF(8 380 417)** for committees with 256 < n ≤ q-1
|
||||
(mandatory for any large committee, 128-byte wire share).
|
||||
|
||||
Auto-selection logic in `ref/go/pkg/pulsarm/types.go::resolveField`
|
||||
picks the narrowest field that fits. The canonical extreme committee
|
||||
target is `TargetCommitteeSize = 1_111_111` (seven 1s); see
|
||||
`spec/pulsar-m.tex` §"Large committees" for the formal scaling
|
||||
theorem.
|
||||
|
||||
v0.2 will reshape this to polynomial Shamir over `R_q^k` matching
|
||||
`spec/pulsar-m.tex` §3.3. The output is the same FIPS 204 signature
|
||||
in all cases; the v0.2 reshape is required to make the
|
||||
Lagrange-linearity sign path work without round-tripping through the
|
||||
byte-sum representation.
|
||||
|
||||
### Adaptive corruption proof not yet written
|
||||
|
||||
Static-corruption security is the baseline target. Adaptive-corruption
|
||||
security is a stretch goal for the round-1 submission and a hard
|
||||
requirement for round 2.
|
||||
|
||||
### Mobile-adversary (proactive resharing) proof inherits Pulsar's gaps
|
||||
|
||||
Pulsar's `reshare/` package has documented soundness against mobile
|
||||
adversaries with deterministic quorum selection (the F10 weakness in
|
||||
HIP-0077). Pulsar-M's `reshare/` ports this with beacon-randomized
|
||||
quorum selection, which strictly improves on Pulsar — but the formal
|
||||
proof of the strengthened protocol is still in draft.
|
||||
|
||||
## Implementation
|
||||
|
||||
### Reference implementation is Go-only for round 1
|
||||
|
||||
The C reference comes after spec encoding freeze. Round-1 reviewers
|
||||
have only the Go reference. NIST MPTC permits any language; a C
|
||||
companion is strongly recommended for round 2.
|
||||
|
||||
### No optimized implementation
|
||||
|
||||
`ref/go/` is the boring, clear, slow reference. AVX-512 / NEON / SHA-3-NI
|
||||
optimization is post-submission work. Performance numbers in the
|
||||
experimental-evaluation report reflect the reference, not optimized
|
||||
implementations.
|
||||
|
||||
### No first-order masking
|
||||
|
||||
Power analysis resistance via masking is post-submission hardening.
|
||||
The reference is constant-time at the algorithmic level (no
|
||||
secret-dependent branches, no secret-dependent memory access patterns
|
||||
in inner loops) but has no power-side-channel countermeasures.
|
||||
|
||||
### No HSM integration
|
||||
|
||||
Production-deployment patches (HSM integration, FIPS 140-3 module
|
||||
shim) are post-submission. The reference is software-only.
|
||||
|
||||
### Constant-time analysis is dudect-level
|
||||
|
||||
Go's compiler is not guaranteed constant-time at the IR level. We use
|
||||
dudect (`ct/dudect/`) to check the leading-edge timing distribution for
|
||||
secret-correlated values. This catches the obvious leaks but does not
|
||||
provide the formal guarantee of e.g. Jasmin-verified C kernels. Formal
|
||||
verification (Jasmin/Formosa/EasyCrypt) is post-submission.
|
||||
|
||||
## NIST process
|
||||
|
||||
### No prior NIST MPTC preview submission
|
||||
|
||||
We're starting from cold. The third-preview window deadline (2026-Jul-20)
|
||||
is roughly two months out. Achieving a credible preview writeup in that
|
||||
window is the immediate gate. If we miss the third preview, we lose the
|
||||
ability to submit the round-1 package without a preview, which is a hard
|
||||
requirement per IR 8214C §5.1.
|
||||
|
||||
### Patent claims not yet inventoried
|
||||
|
||||
Pulsar inherits Corona's IP posture. Pulsar-M needs a fresh
|
||||
patent-claim review for the M-LWE adaptation. `docs/patent-notes-draft.md`
|
||||
collects claims as they're discovered; final notice for the package is
|
||||
on the critical path for 2026-Nov-16.
|
||||
|
||||
### External cryptanalysis engagement not yet contracted
|
||||
|
||||
NIST MPTC submissions are strengthened by independent academic
|
||||
cryptanalysis. We have not yet engaged a third party. A 6-month
|
||||
engagement starting July 2026 is the target — this aligns with the
|
||||
post-package public-analysis window rather than blocking the package
|
||||
itself.
|
||||
|
||||
## Repo / build
|
||||
|
||||
### Go module initialised
|
||||
|
||||
`go.mod` brings in `cloudflare/[email protected]` (FIPS 204 backbone)
|
||||
and `golang.org/x/crypto/sha3` (FIPS 202 / SP 800-185 transcripts).
|
||||
Cleanly builds with `GOWORK=off`.
|
||||
|
||||
### Spec PDF not yet built
|
||||
|
||||
`spec/pulsar-m.tex` is **complete** as LaTeX source (1500+ lines
|
||||
covering Front matter / Notation / Preliminaries / Algorithms /
|
||||
Verification / Reshare / Identifiable abort / Security analysis /
|
||||
Concrete parameters / Large committees / Encodings / System model /
|
||||
Implementation considerations / Performance / Test vectors /
|
||||
Complexity analysis / Deployment / Comparison / Patent claims /
|
||||
Known limitations / Open questions). The companion files
|
||||
`security-games.tex`, `system-model.tex`, and `parameters.tex` are
|
||||
also complete. Building the PDF via `latexmk -pdf spec/pulsar-m.tex`
|
||||
is on the active writing track once the bib resolution lands.
|
||||
|
||||
### KAT suite generated
|
||||
|
||||
`vectors/{keygen,sign,verify,threshold-sign,dkg}.json` are committed.
|
||||
`scripts/gen_vectors.sh` re-runs the generator and verifies that
|
||||
re-running produces byte-identical output (the deterministic-fixture
|
||||
gate). The CAVS-style `kat-v1.rsp` ACVP companion is on the v0.2
|
||||
path; ACVP support requires the post-encoding-freeze byte layout.
|
||||
|
||||
### Lattice-estimator parameter table
|
||||
|
||||
`spec/parameters.tex` now includes the classical + quantum
|
||||
security-level table (numbers inherited verbatim from FIPS 204 §8
|
||||
because Pulsar-M does not alter the underlying M-LWE parameters).
|
||||
The Albrecht et al. lattice-estimator script
|
||||
`estimator/params.sage` reproduces the table; the estimator commit
|
||||
hash is pinned at submission in `estimator/README.md`.
|
||||
|
||||
## Compared to Pulsar (R-LWE)
|
||||
|
||||
| dimension | Pulsar | Pulsar-M |
|
||||
|---|---|---|
|
||||
| Algebraic basis | Ring-LWE | Module-LWE |
|
||||
| Hash | SHA-3 cSHAKE / BLAKE3 legacy | SHA-3 cSHAKE only |
|
||||
| FIPS 204 output interchange | no (R-LWE) | yes (target) |
|
||||
| MPTC class | S1/S4 | N1/N4 |
|
||||
| Parameter sets | Pulsar-internal | ML-DSA-44/65/87 |
|
||||
| DKG | Pedersen over `R_q` | Pedersen over `R_q^k` |
|
||||
| Reshare | deterministic quorum | beacon-randomized quorum |
|
||||
|
||||
Where Pulsar provides feature X and Pulsar-M doesn't yet, Pulsar-M's
|
||||
goal is to inherit X verbatim from Pulsar's `dkg2/` and `reshare/`
|
||||
packages with the M-LWE shape change.
|
||||
@@ -1,140 +0,0 @@
|
||||
# NIST MPTC category targeting
|
||||
|
||||
> Reference: NIST IR 8214C, *First Call for Multi-Party Threshold Schemes*
|
||||
> (January 2026). Package deadline expected 2026-Nov-16. Preview deadline
|
||||
> 2026-Jul-20.
|
||||
|
||||
## Pulsar-M target: **Class N1 + N4**
|
||||
|
||||
NIST MPTC subdivides threshold schemes into:
|
||||
|
||||
- **Class S** (Special) — threshold-friendly primitives that *are not*
|
||||
output-interchangeable with a NIST-specified primitive. Submission
|
||||
evaluated for "novel threshold-friendly design."
|
||||
- **Class N** (Normal-mode) — threshold implementations *of* a NIST-specified
|
||||
primitive whose outputs are interchangeable with the corresponding
|
||||
non-threshold primitive's outputs.
|
||||
- **N1**: signing
|
||||
- **N2**: encryption / decryption
|
||||
- **N3**: KEM
|
||||
- **N4**: ML keygen / DKG (Module-Lattice key generation, distributed)
|
||||
|
||||
Pulsar-M aims for **N1 (threshold ML-DSA signing) + N4 (distributed ML-DSA
|
||||
keygen)**. The headline interchangeability claim:
|
||||
|
||||
> A signature `σ` produced by a Pulsar-M threshold ceremony on message `μ`
|
||||
> against group public key `pk` verifies under unmodified
|
||||
> [FIPS 204 ML-DSA.Verify(pk, μ, σ)] returning `accept`.
|
||||
|
||||
If we can prove and demonstrate this, Pulsar-M is a Class N candidate. If
|
||||
the output is not bit-for-bit FIPS 204 (e.g. encoding differs in any
|
||||
field), Pulsar-M falls back to Class S — still valid, but a weaker NIST
|
||||
positioning.
|
||||
|
||||
## Output interchangeability — what has to hold
|
||||
|
||||
ML-DSA-65 signatures (FIPS 204 §5.4, Algorithm 26 `sigEncode`) are
|
||||
encoded as a fixed-length 3309-byte string σ = (c̃, z, h) whose three
|
||||
components decompose exactly as:
|
||||
|
||||
```
|
||||
σ = (c̃ ‖ z ‖ h) 3309 bytes
|
||||
c̃ ∈ {0,1}^{2λ} 48 bytes
|
||||
// FIPS 204 commitment-hash length; 2λ bits with λ=192 = 384 bits.
|
||||
// (2λ here is the FIPS 204 commitment-hash parameter, not the
|
||||
// security level — the two happen to numerically agree for
|
||||
// ML-DSA-65 because the standard ties one to the other at this
|
||||
// parameter set.)
|
||||
z ∈ R^ℓ_q 3200 bytes
|
||||
// ℓ = 5 polynomials, each 256 coefficients, packed at
|
||||
// log2(2γ_1) = 20 bits per coefficient.
|
||||
// 5 · 256 · 20 / 8 = 3200 bytes.
|
||||
h ∈ {0,1}^{ω + k} 61 bytes
|
||||
// ω = 55 (hint bound), k = 6 (commitment-vector dimension).
|
||||
// FIPS 204 Algorithm 22 `hintBitPack` + Algorithm 28
|
||||
// `sigEncode` pack ω + k = 61 bits as 61 bytes (one byte per
|
||||
// bit position, terminator-first encoding per the standard).
|
||||
total: 48 + 3200 + 61 = 3309 bytes ✓ FIPS 204 Table 2
|
||||
```
|
||||
|
||||
For Pulsar-M to claim Class N1, the threshold-aggregated signature MUST
|
||||
deserialize as exactly this triple, with the same byte layout, the same
|
||||
canonicalization rules, and the same rejection criteria. The threshold
|
||||
protocol is allowed to perform multiple rounds internally, but its emitted
|
||||
artifact MUST be a single FIPS 204 σ.
|
||||
|
||||
This is non-trivial: ML-DSA's rejection sampling means a single-shot
|
||||
threshold output can fail rejection and require restart. Pulsar's
|
||||
2-round structure handles this for R-LWE; Pulsar-M needs to reproduce
|
||||
the rejection-restart logic for M-LWE without leaking secret information
|
||||
across the restart.
|
||||
|
||||
## Required package deliverables
|
||||
|
||||
Per NIST IR 8214C §5:
|
||||
|
||||
| element | format | location |
|
||||
|---|---|---|
|
||||
| Technical Specification | PDF (LaTeX) | `spec/pulsar-m.pdf` |
|
||||
| Reference Implementation | open-source code | `ref/go/` |
|
||||
| Report on Experimental Evaluation | PDF + reproducible scripts | `bench/results/REPORT.md` + `bench/run_all.sh` |
|
||||
| Notes on Patent Claims | PDF | `docs/patent-notes-draft.md` → finalized |
|
||||
| Concrete parameter set | section in spec | `spec/parameters.tex` |
|
||||
| Security analysis (proofs) | section in spec | `spec/security-games.tex` |
|
||||
| Public repository | GitHub or equiv | `https://github.com/luxfi/pulsar-m` |
|
||||
| Build/test/benchmark scripts | shell | `scripts/*.sh` |
|
||||
| Open-source license | text | `LICENSE` (Apache-2.0) |
|
||||
| I/O test vectors | JSON / RSP | `vectors/kat-v1.{json,rsp}` |
|
||||
|
||||
Optional but strongly recommended:
|
||||
- Executive summary (1-2 pages) at front of spec.
|
||||
- Threat-model document (`docs/threat-model.md`).
|
||||
- System-model document (`docs/system-model.md` → `spec/system-model.tex`).
|
||||
- Known-limitations appendix (so reviewers see the gaps before they find them).
|
||||
|
||||
## Required security strengths
|
||||
|
||||
NIST MPTC §4.5 gives the required and suggested security-strength targets:
|
||||
|
||||
| target | classical | post-quantum (NIST PQ category) | statistical |
|
||||
|---|---|---|---|
|
||||
| **required** (≥1 parameterization) | ≥ 128 bits | ≥ Category 1 | ≥ 40 bits |
|
||||
| **suggested** (additional, optional) | ≥ 192 bits | ≥ Category 3 | ≥ 64 bits |
|
||||
|
||||
Pulsar-M will ship parameter sets matching ML-DSA-65 (Category 3) for the
|
||||
suggested target, and potentially ML-DSA-44 (Category 2) and ML-DSA-87
|
||||
(Category 5) for full coverage.
|
||||
|
||||
## Class N vs Class S decision
|
||||
|
||||
Pulsar-M is N if and only if:
|
||||
1. A working reference implementation produces signatures byte-equal to
|
||||
FIPS 204 ML-DSA on the same `(pk, μ)` for some valid threshold ceremony.
|
||||
2. The threshold key generation produces a `pk` that's a valid FIPS 204
|
||||
ML-DSA public key (no extra public material distinguishable from a
|
||||
single-party `pk`).
|
||||
3. The verification relation in the spec is the FIPS 204 verifier
|
||||
verbatim, with no Pulsar-specific changes.
|
||||
|
||||
If any of (1)-(3) fails, we ship as Class S with a clear "future work:
|
||||
output interchangeability" note. The class decision is finalized at the
|
||||
point we freeze the spec encoding.
|
||||
|
||||
## Pulsar (R-LWE) for comparison
|
||||
|
||||
Pulsar (R-LWE) targets **Class S1 + S4**: special threshold-friendly
|
||||
two-round signature, not output-interchangeable with any NIST-approved
|
||||
primitive. The S1/S4 framing is the right framing for Corona-derivatives
|
||||
unless and until NIST blesses Corona-shaped outputs as a primitive.
|
||||
|
||||
## Status
|
||||
|
||||
- [ ] Class declared (N vs S, awaiting spec freeze)
|
||||
- [ ] Preview writeup drafted
|
||||
- [ ] Preview submitted (target 2026-Jul-20)
|
||||
- [ ] Spec freeze
|
||||
- [ ] Reference impl complete
|
||||
- [ ] KATs cross-validated against FIPS 204 reference
|
||||
- [ ] Experimental-evaluation report
|
||||
- [ ] Patent-claims notes finalized
|
||||
- [ ] Package submitted (target 2026-Nov-16)
|
||||
@@ -1,91 +0,0 @@
|
||||
# Notes on patent claims (draft)
|
||||
|
||||
> Required by NIST MPTC IR 8214C §5 as a package deliverable. This document
|
||||
> is collected over the development period and finalized for the
|
||||
> submission.
|
||||
|
||||
## Status
|
||||
|
||||
**Draft.** No patent claims have been formally identified. This page
|
||||
tracks claims as contributors disclose them.
|
||||
|
||||
## Inherited from upstream
|
||||
|
||||
### Pulsar (`luxfi/pulsar`)
|
||||
|
||||
Pulsar-M reuses Pulsar's protocol structure. Pulsar's IP posture per
|
||||
its README:
|
||||
|
||||
- Apache-2.0 licensed.
|
||||
- Patent grant per Apache 2.0 §3 from each contributor.
|
||||
- No known active patent claims as of repository creation.
|
||||
|
||||
This applies to Pulsar-M to the extent that Pulsar-M code or protocol
|
||||
elements are derivative of Pulsar.
|
||||
|
||||
### Corona (`luxfi/corona`)
|
||||
|
||||
Pulsar (and therefore Pulsar-M) is a fork of academic Corona.
|
||||
Corona (ePrint 2024/1113) authors: Cecilia Boschini, Darya Kaviani,
|
||||
Russell W. F. Lai, Giulio Malavolta, Akira Takahashi, Mehdi Tibouchi.
|
||||
Corona's open-source repo is Apache-2.0 with no asserted patent
|
||||
claims as of mid-2026. Pulsar-M's M-LWE adaptation does not import
|
||||
Corona code directly but inherits the protocol structure.
|
||||
|
||||
### ML-DSA / FIPS 204
|
||||
|
||||
ML-DSA is a NIST-standardized algorithm. The Dilithium team's IP
|
||||
disclosures during NIST PQC standardization are public on the NIST
|
||||
PQC website. Pulsar-M targets output interchangeability with FIPS 204
|
||||
but does not assert any rights over FIPS 204 itself.
|
||||
|
||||
## Contributor disclosures
|
||||
|
||||
Per CONTRIBUTING.md, every commit's `Signed-off-by` line is taken as
|
||||
either:
|
||||
1. An explicit assertion that the contributor has no relevant patent
|
||||
claims, OR
|
||||
2. A reference to a disclosed claim listed below.
|
||||
|
||||
| date | contributor | type | disclosure |
|
||||
|---|---|---|---|
|
||||
| 2026-05-10 | Lux Industries Inc | initial repo | no claims asserted |
|
||||
|
||||
(Updated as contributions land.)
|
||||
|
||||
## Third-party patents we may need to navigate
|
||||
|
||||
Live concerns to investigate before submission:
|
||||
|
||||
- Lattice-estimator usage (we use the open-source estimator; license
|
||||
pass-through to MIT).
|
||||
- Gaussian sampler implementation (FIPS 204 references CDT; alternate
|
||||
rejection samplers may have IP).
|
||||
- Polynomial multiplication via NTT (standard, no known IP).
|
||||
- Pedersen commitments (1991 paper, expired patents).
|
||||
|
||||
The submission's Notes on Patent Claims will explicitly call out each
|
||||
of these.
|
||||
|
||||
## NIST MPTC submission requirements
|
||||
|
||||
NIST IR 8214C §5 (Notes on Patent Claims) requires:
|
||||
|
||||
> Submitter(s) shall include a statement of any patent claims known to
|
||||
> them that may be relevant to the submitted package, regardless of who
|
||||
> owns the claim. Statements of "no known claims" are acceptable.
|
||||
|
||||
Our final statement, once the spec freezes:
|
||||
|
||||
> *To be drafted at spec freeze. Will incorporate every disclosure in
|
||||
> the contributor table above, every inherited claim from Pulsar /
|
||||
> Corona / ML-DSA, and the third-party investigation outcome.*
|
||||
|
||||
## Process
|
||||
|
||||
1. Every PR review checks for new IP-relevant code.
|
||||
2. Significant cryptographic additions (new sampling routine, new
|
||||
commitment shape, new aggregation step) trigger an explicit IP
|
||||
review with one of the sponsor's IP counsel.
|
||||
3. Final statement assembled at freeze, included in
|
||||
`spec/pulsar-m.pdf` Appendix A.
|
||||
@@ -1,132 +0,0 @@
|
||||
# Pulsar-M threat model
|
||||
|
||||
## Adversary classes
|
||||
|
||||
We give an adversary the union of the following capabilities, parameterized
|
||||
by `t` (the corruption threshold) and the corruption model:
|
||||
|
||||
### Static corruption (default)
|
||||
|
||||
- Adversary `A` selects up to `t-1` parties to corrupt **before** protocol
|
||||
start. From start to end of the protocol, those `t-1` parties are
|
||||
controlled; the remaining honest parties run the protocol faithfully.
|
||||
- `A` sees all messages on the broadcast channel + all messages on the
|
||||
authenticated point-to-point channels into corrupted parties.
|
||||
- `A` learns each corrupted party's full state (secret share, randomness,
|
||||
per-round values) including session-state values.
|
||||
- `A` can selectively delay messages within the round window but cannot
|
||||
forge messages from honest parties on authenticated channels.
|
||||
|
||||
### Adaptive corruption (stronger model)
|
||||
|
||||
- Adversary `A` can corrupt up to `t-1` parties at any time during the
|
||||
protocol, including mid-round, conditioned on the transcript so far.
|
||||
- Once corrupted, a party remains corrupted for the rest of the protocol.
|
||||
- All other capabilities as in static.
|
||||
|
||||
The Pulsar-M security analysis (`spec/security-games.tex`) provides the
|
||||
precise game definitions. Static security is the baseline; adaptive
|
||||
security is a stretch goal for the first MPTC submission and a hard
|
||||
requirement for the second-round response.
|
||||
|
||||
### Mobile corruption (proactive resharing)
|
||||
|
||||
For long-lived deployments where the validator set rotates between epochs
|
||||
(Pulsar's `reshare/` direction), the relevant model is HJKY97 mobile
|
||||
adversary: `A` can corrupt up to `t-1` parties **per epoch**, with the
|
||||
corruption set varying across epochs. The adversary may *uncorrupt* a
|
||||
party (forget what it learned) at epoch boundaries.
|
||||
|
||||
Pulsar-M proactive resharing inherits the soundness argument from Pulsar's
|
||||
`reshare/` (with the constant-time fix from F9 of the Hanzo HIP-0077
|
||||
red review). The MPTC submission documents the mobile-adversary game
|
||||
explicitly.
|
||||
|
||||
## Out-of-scope adversary capabilities
|
||||
|
||||
- Compromise of the cryptographic hash function (SHAKE-256 / cSHAKE-256 /
|
||||
KMAC-256). NIST FIPS 202 + SP 800-185 are taken as building blocks.
|
||||
- Side-channel attacks on the *physical* hardware running a party
|
||||
(power analysis, EM, fault injection). Mitigation discussed in
|
||||
`docs/known-limitations.md` as future work.
|
||||
- Compromise of the BIP-32/BIP-39 mnemonic from which device-specific
|
||||
keys are derived. The HD-derivation security argument lives in
|
||||
HIP-0077 §"Identity"; the Pulsar-M layer assumes parties' input keys
|
||||
are uniformly distributed.
|
||||
|
||||
## In-scope security goals
|
||||
|
||||
### Threshold unforgeability (TS-UF)
|
||||
|
||||
For any PPT adversary `A` controlling up to `t-1` parties, `A` cannot
|
||||
produce a valid Pulsar-M signature `σ*` on any message `μ*` that an
|
||||
honest signing ceremony has not produced.
|
||||
|
||||
### Robustness / identifiable abort
|
||||
|
||||
If a corrupted party deviates from the protocol, the honest parties:
|
||||
1. Detect the deviation.
|
||||
2. Identify the deviating party.
|
||||
3. Produce signed evidence of the deviation suitable for slashing /
|
||||
reputation reduction.
|
||||
|
||||
### Output indistinguishability from FIPS 204
|
||||
|
||||
A Pulsar-M signature `σ` on message `μ` against group public key `pk`
|
||||
is computationally indistinguishable from a FIPS 204 ML-DSA signature on
|
||||
the same `(pk, μ)`. Specifically: an adversary that can distinguish the
|
||||
two with non-negligible advantage breaks the underlying M-LWE assumption.
|
||||
|
||||
### Bias resistance
|
||||
|
||||
The randomness used in each party's contribution (Gaussian samples,
|
||||
challenge polynomials) is statistically indistinguishable from uniform
|
||||
even given the adversary's view of corrupted parties' randomness.
|
||||
|
||||
### DKG soundness
|
||||
|
||||
Pedersen DKG over `R_q^k` produces a public key `pk` distributed
|
||||
uniformly over the valid M-LWE public-key space, with no party holding
|
||||
more than `1/n` partial information about the corresponding secret key.
|
||||
|
||||
## Assumed channels
|
||||
|
||||
| channel | property | purpose |
|
||||
|---|---|---|
|
||||
| Broadcast | authenticated, eventual-delivery | round transcripts, public coins |
|
||||
| Point-to-point | authenticated, encrypted | private share / blind delivery |
|
||||
| Public bulletin | authenticated, append-only | DKG commitments, reshare records |
|
||||
|
||||
The reference implementation provides these channels via TCP + TLS.
|
||||
Production deployments (e.g. Lux consensus + Quasar) bind these to
|
||||
their existing P2P transport.
|
||||
|
||||
## Trusted parameters
|
||||
|
||||
- The cyclotomic ring `R_q = Z_q[X] / (X^256 + 1)` and parameters
|
||||
`(q, k, ℓ, η, β, ω, …)` exactly as in FIPS 204 ML-DSA-65.
|
||||
- The hash family: SHAKE-256 (FIPS 202), cSHAKE-256 / KMAC-256 /
|
||||
TupleHash-256 (NIST SP 800-185). Customization tags are pinned in
|
||||
`spec/pulsar-m.tex`.
|
||||
- The Gaussian sampler parameters from FIPS 204 §3.3 / §4.2.
|
||||
|
||||
No trusted setup beyond NIST primitives.
|
||||
|
||||
## Failure modes addressed
|
||||
|
||||
The MPTC submission documents how Pulsar-M handles each failure mode that
|
||||
broke earlier threshold-lattice schemes:
|
||||
|
||||
- **Rejection-sampling restart leaking secret information across rounds**:
|
||||
Pulsar's PRNG-key per-round domain separation (CRIT-1 fix from
|
||||
upstream's 2026-05-03 amendment) ports forward.
|
||||
- **Constant-time share comparison**: `dkg2.constTimePolyEqual` pattern
|
||||
ported from upstream Pulsar (`reshare/commit.go` F9 fix).
|
||||
- **Information leaks via logging**: zero stdlib `log` use in any
|
||||
secret-touching path; all logging via `luxfi/log` at fields that are
|
||||
explicitly public.
|
||||
- **Deterministic quorum selection in resharing leaking adversary
|
||||
positioning**: Pulsar-M uses a beacon-derived per-reshare quorum
|
||||
selection (HIP-0077 §"reshare quorum" F10 fix).
|
||||
- **Cross-mode hash-suite confusion**: NIST profile is exclusively
|
||||
SHA-3 family; no BLAKE3 in Pulsar-M ever.
|
||||
@@ -27,7 +27,7 @@ package pulsarm
|
||||
// guarantees under M-LWE hardness (a stronger PQ-safe binding
|
||||
// argument). Both targets are Class N4-eligible.
|
||||
//
|
||||
// See docs/known-limitations.md for the v0.1 → v0.2 path.
|
||||
// See spec/known-limitations.tex for the v0.1 → v0.2 path.
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// The headline claim of Pulsar-M is output interchangeability with FIPS 204:
|
||||
// a signature produced by an n-of-t threshold ceremony verifies under
|
||||
// unmodified FIPS 204 ML-DSA.Verify(pk, message, signature). See
|
||||
// docs/nist-mptc-category.md for the formal claim and its scope.
|
||||
// spec/nist-mptc-category.tex for the formal claim and its scope.
|
||||
//
|
||||
// Status: pre-spec-freeze. The exported API in this package will change
|
||||
// up to the spec encoding freeze (target end of August 2026). After
|
||||
|
||||
@@ -179,7 +179,7 @@ func TestLarge_DKG_AboveCap(t *testing.T) {
|
||||
// small-committee (GF(257)) path. Cross-committee reshare changes
|
||||
// the committee root and therefore the cSHAKE256-mixed master seed
|
||||
// in the v0.1 reconstruction-aggregator instantiation; see
|
||||
// docs/known-limitations.md.
|
||||
// spec/known-limitations.tex.
|
||||
func TestLarge_Reshare_SameCommittee_PubInvariant(t *testing.T) {
|
||||
params := MustParamsFor(ModeP65)
|
||||
committee := makeLargeCommittee(5)
|
||||
@@ -301,7 +301,7 @@ func TestLarge_Reshare_SameCommittee_PubInvariant(t *testing.T) {
|
||||
// is bound to the committee root. This test asserts that the reshare
|
||||
// ceremony succeeds (new shares are produced) but not that pk is
|
||||
// preserved across the committee change. The pk-preserving cross-
|
||||
// committee reshare is on the v0.2 path; see docs/known-limitations.md.
|
||||
// committee reshare is on the v0.2 path; see spec/known-limitations.tex.
|
||||
func TestLarge_Reshare_E2E(t *testing.T) {
|
||||
params := MustParamsFor(ModeP65)
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ package pulsarm
|
||||
// pulsar-m.tex §4.2 form. The reconstruction-aggregator path collapses
|
||||
// the Lagrange-linearity-of-z computation of §4.2 into a single FIPS
|
||||
// 204 Sign call after share Lagrange reconstruction. This trade is
|
||||
// documented in docs/known-limitations.md; the v0.2 path implements
|
||||
// documented in spec/known-limitations.tex; the v0.2 path implements
|
||||
// the pure Lagrange-linearity sign where the secret is never
|
||||
// reconstructed in any party's memory.
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ type Round2Message struct {
|
||||
|
||||
// PartialSig is this party's contribution toward the FIPS 204
|
||||
// signature. In the v0.1 reconstruction-aggregator instantiation
|
||||
// (see docs/known-limitations.md), this is the Shamir share of
|
||||
// (see spec/known-limitations.tex), this is the Shamir share of
|
||||
// the seed encrypted under the round transcript hash; the
|
||||
// aggregator collects t shares, reconstructs the seed, and emits
|
||||
// a single FIPS 204 signature. The Lagrange-linearity path of
|
||||
|
||||
@@ -12,7 +12,7 @@ package pulsarm
|
||||
// signature produced by ThresholdSign (threshold.go) flows through
|
||||
// the SAME Verify code path as a single-party Sign output.
|
||||
//
|
||||
// Per pulsar-m.tex §4.3 and docs/nist-mptc-category.md, this is the
|
||||
// Per pulsar-m.tex §4.3 and spec/nist-mptc-category.tex, this is the
|
||||
// load-bearing property of the entire Pulsar-M family: anything that
|
||||
// changes Verify breaks Class N1 output interchangeability.
|
||||
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
% Pulsar-M design decisions log -- included by pulsar-m.tex.
|
||||
% Mirrors docs/design-decisions.md (now deleted; this file is the
|
||||
% canonical LaTeX form). Each entry: decision, rationale,
|
||||
% alternatives, status, date.
|
||||
|
||||
\subsection{DD-001 Target FIPS 204 output interchangeability (Class
|
||||
N)}
|
||||
|
||||
\paragraph{Decision.}
|
||||
Pulsar-M aims for Class N1 + N4 (NIST MPTC IR 8214C):
|
||||
threshold-produced signatures verify under unmodified FIPS~204
|
||||
ML-DSA.Verify.
|
||||
|
||||
\paragraph{Rationale.}
|
||||
Output interchangeability gives the strongest NIST positioning.
|
||||
FIPS-validated ML-DSA modules in 2026 (BoringSSL FIPS, AWS-LC,
|
||||
OpenSSL 3.0) consume Pulsar-M certs without code changes. This is
|
||||
the headline pitch for MPTC.
|
||||
|
||||
\paragraph{Alternative.}
|
||||
Class S (special threshold-friendly primitive). Easier spec, but
|
||||
does not give the FIPS-module-compatibility win. Pulsar (R-LWE)
|
||||
takes this path.
|
||||
|
||||
\paragraph{Status.}
|
||||
Targeted. Final class decision deferred until reference impl
|
||||
demonstrates byte-equal output on at least one parameter set.
|
||||
|
||||
\subsection{DD-002 Hash family: SHA-3 (cSHAKE256 / KMAC256 /
|
||||
TupleHash256) only}
|
||||
|
||||
\paragraph{Decision.}
|
||||
Pulsar-M's NIST profile uses exclusively the FIPS~202 + SP 800-185
|
||||
hash family. No BLAKE3.
|
||||
|
||||
\paragraph{Rationale.}
|
||||
NIST MPTC \S4.6 lists allowed symmetric primitives for Class N: AES,
|
||||
Ascon, SHA-2, SHA-3, SHAKE/cSHAKE, HMAC/KMAC/CMAC/GMAC. BLAKE3 is
|
||||
not on the list. Including BLAKE3 in the NIST submission profile is
|
||||
a strategic liability.
|
||||
|
||||
The same SHAKE-256 sponge is used internally by ML-DSA-65 (FIPS~204
|
||||
\S5.1). Sharing the hash family with the underlying primitive
|
||||
removes a whole class of cryptanalytic concern (cross-domain
|
||||
collisions, mixed hash-family soundness arguments).
|
||||
|
||||
\paragraph{Alternative considered.}
|
||||
Dual-suite with BLAKE3 as the production profile and SHA-3 as the
|
||||
NIST profile, like Pulsar's current dual-suite. Rejected because
|
||||
Pulsar-M is NIST-track and shouldn't ship a non-NIST default.
|
||||
|
||||
\paragraph{Status.}
|
||||
Final.
|
||||
|
||||
\subsection{DD-003 Lattice: Module-LWE per FIPS 204, not Ring-LWE}
|
||||
|
||||
\paragraph{Decision.}
|
||||
Pulsar-M operates over $\Rq^k$ (module of polynomials) with the same
|
||||
$(q, k, \ell, \eta, \beta, \omega, \ldots)$ parameter set as
|
||||
ML-DSA-65. Not $\Rq$ (single polynomial) as Pulsar / Corona use.
|
||||
|
||||
\paragraph{Rationale.}
|
||||
This is the whole point of the project. Class N1 interchangeability
|
||||
requires the protocol's signing operation to land on exactly the
|
||||
FIPS~204 $\sigma$ encoding, which is M-LWE-shaped.
|
||||
|
||||
\paragraph{Alternative.}
|
||||
Stay R-LWE. Easier (we already have Pulsar). But then we lose the
|
||||
Class N positioning and become Class S like Pulsar.
|
||||
|
||||
\paragraph{Status.}
|
||||
Final.
|
||||
|
||||
\subsection{DD-004 Reference implementation language: Go}
|
||||
|
||||
\paragraph{Decision.}
|
||||
Reference implementation is Go (\texttt{ref/go/}). C implementation
|
||||
comes after spec encodings freeze (\texttt{ref/c/}).
|
||||
|
||||
\paragraph{Rationale.}
|
||||
Go matches Pulsar's reference; reuses our Pedersen DKG and reshare
|
||||
patterns from \texttt{pulsar/dkg2/} and \texttt{pulsar/reshare/}.
|
||||
Clear, boring, no assembly. NIST MPTC \S4.3 doesn't mandate
|
||||
language.
|
||||
|
||||
\paragraph{Alternative.}
|
||||
C reference first. Standard NIST PQC submission style. Rejected for
|
||||
round 1 because we need to ship by 2026-Nov-16; Go is faster to
|
||||
write and review. C reference becomes a follow-on artifact for round
|
||||
2 review.
|
||||
|
||||
\paragraph{Status.}
|
||||
Final for MPTC round 1.
|
||||
|
||||
\subsection{DD-005 DKG: Pedersen-style over $\Rq^k$}
|
||||
|
||||
\paragraph{Decision.}
|
||||
Distributed keygen uses Pedersen DKG over the M-LWE module ring,
|
||||
with Feldman-style verifiable secret sharing replaced by the
|
||||
module-shaped Pedersen commitment scheme.
|
||||
|
||||
\paragraph{Rationale.}
|
||||
Pulsar's \texttt{dkg2/} package already does this for $\Rq$ (R-LWE).
|
||||
The M-LWE port preserves the soundness argument with constant
|
||||
overhead per coefficient slot.
|
||||
|
||||
\paragraph{Alternative.}
|
||||
Trusted-dealer DKG (academic Corona). Rejected: incompatible with
|
||||
open public chains (HIP-0077 \S``Pulsar vs Corona'').
|
||||
|
||||
\paragraph{Status.}
|
||||
Final.
|
||||
|
||||
\subsection{DD-006 Proactive resharing: HJKY97-style with
|
||||
beacon-randomized quorum}
|
||||
|
||||
\paragraph{Decision.}
|
||||
Long-lived deployments use proactive secret resharing with a
|
||||
beacon-derived per-reshare quorum selection (not deterministic
|
||||
smallest-ID).
|
||||
|
||||
\paragraph{Rationale.}
|
||||
Deterministic quorum selection (Pulsar's current
|
||||
\texttt{reshare.go:206-209}) lets a mobile adversary game the
|
||||
corrupt-set positioning. HIP-0077 red review F10 flagged this.
|
||||
Pulsar-M's reshare selects via the chain's randomness beacon at the
|
||||
reshare epoch boundary.
|
||||
|
||||
\paragraph{Alternative.}
|
||||
Deterministic quorum, accept the leakage as a documented limitation.
|
||||
Rejected for MPTC submission.
|
||||
|
||||
\paragraph{Status.}
|
||||
Final.
|
||||
|
||||
\subsection{DD-007 No application-level logging in secret-touching
|
||||
code paths}
|
||||
|
||||
\paragraph{Decision.}
|
||||
Secret-touching functions (Sign, Verify-of-shares, DKG verification,
|
||||
reshare verification) emit zero log lines. Constant-time analysis
|
||||
treats any log call as a failed gate.
|
||||
|
||||
\paragraph{Rationale.}
|
||||
Pulsar's pre-fix \texttt{log.Println(Bsquare, sumSquares)} in
|
||||
\texttt{sign.go} (HIP-0077 red F8) is exactly the failure mode this
|
||||
rule prevents. A logged value derived from secret state is a side
|
||||
channel even at debug level.
|
||||
|
||||
\paragraph{Alternative.}
|
||||
Allow debug logging gated by build tag. Rejected: build tags get
|
||||
accidentally enabled in production; the rule is absolute.
|
||||
|
||||
\paragraph{Status.}
|
||||
Final. CI gate: \texttt{go vet -vettool=...} plus a custom linter
|
||||
that rejects \texttt{log.*}, \texttt{fmt.Print*}, \texttt{panic} in
|
||||
\texttt{pkg/sign/}, \texttt{pkg/dkg/}, \texttt{pkg/reshare/}.
|
||||
|
||||
\subsection{DD-008 Encoding freeze before C reference}
|
||||
|
||||
\paragraph{Decision.}
|
||||
Reference Go locks every byte of the wire encoding before the C
|
||||
reference begins. Inputs to the freeze: spec \S``Encodings'', KAT
|
||||
suite v0, cross-vendor review with at least one external lattice
|
||||
impl team.
|
||||
|
||||
\paragraph{Rationale.}
|
||||
Two implementations diverging on encoding is a recurring source of
|
||||
NIST PQC submission rejections. Freeze first, port second.
|
||||
|
||||
\paragraph{Status.}
|
||||
Targeted for end of August 2026.
|
||||
|
||||
\subsection{DD-009 Patent claims: prepared in advance}
|
||||
|
||||
\paragraph{Decision.}
|
||||
Patent-claim disclosures collected in
|
||||
\texttt{spec/patent-notes.tex} from day 1 of the repo. Every
|
||||
contribution adds the contributor's patent-claim notice (or explicit
|
||||
``no claims'').
|
||||
|
||||
\paragraph{Rationale.}
|
||||
NIST MPTC \S6 requires Notes on Patent Claims as a package
|
||||
deliverable. Late collection blows up the submission timeline.
|
||||
|
||||
\paragraph{Status.}
|
||||
In progress.
|
||||
|
||||
\subsection{DD-010 Two-track NIST plan: MPTC now, CMVP later}
|
||||
|
||||
\paragraph{Decision.}
|
||||
Track A targets MPTC submission 2026-Nov-16. Track B prepares for
|
||||
eventual NIST PQC standardization + CMVP module validation, which is
|
||||
a multi-year process not scheduled.
|
||||
|
||||
\paragraph{Rationale.}
|
||||
MPTC is the active NIST process for threshold schemes right now.
|
||||
CMVP requires an approved standard, which threshold schemes don't
|
||||
yet have. We can prepare a clean module boundary for future CMVP
|
||||
work without waiting for the standard.
|
||||
|
||||
\paragraph{Status.}
|
||||
Track A active. Track B is a parallel readiness exercise, not a
|
||||
near-term gate.
|
||||
@@ -0,0 +1,278 @@
|
||||
% Pulsar threshold-signature family architecture -- included by
|
||||
% pulsar-m.tex. Mirrors docs/family-architecture.md (now deleted;
|
||||
% this file is the canonical LaTeX form).
|
||||
|
||||
\begin{quote}
|
||||
\textbf{Pulsar} is one name for a family of lattice-based threshold
|
||||
signature schemes. Variants share the same protocol skeleton
|
||||
(2-round threshold sign, Pedersen DKG with proper hiding, proactive
|
||||
resharing, identifiable abort) but differ in the underlying lattice
|
||||
problem and NIST-compatibility target.
|
||||
\end{quote}
|
||||
|
||||
This document is the canonical statement of the family architecture.
|
||||
Every Pulsar variant references it. Every NIST submission cites it.
|
||||
Every consumer that wires ``the Pulsar family'' into a downstream
|
||||
system points here for the variant table.
|
||||
|
||||
\subsection{Variants}
|
||||
|
||||
\begin{center}
|
||||
\small
|
||||
\begin{tabular}{p{2.3cm}p{3.0cm}p{1.8cm}p{2.6cm}p{2.2cm}p{1.6cm}p{2.4cm}}
|
||||
\toprule
|
||||
variant & repo (target) & lattice basis & hash family (canonical) &
|
||||
FIPS 204 verifier interchange? & NIST MPTC class & status \\
|
||||
\midrule
|
||||
\textbf{Pulsar} (was Pulsar.M / pulsar-m) &
|
||||
\texttt{github.com/luxfi/pulsar} &
|
||||
Module-LWE ($\Rq^k$) &
|
||||
SHA-3 / cSHAKE256 (SP 800-185) &
|
||||
yes --- output is a single FIPS~204 ML-DSA $\sigma$ &
|
||||
Class N1 + N4 &
|
||||
this repo; reference complete, KAT-pinned \\
|
||||
\textbf{Corona} (was Pulsar.R / luxfi/pulsar) &
|
||||
\texttt{github.com/luxfi/corona} &
|
||||
Ring-LWE ($\Rq$) &
|
||||
SHA-3 / cSHAKE256 (SP 800-185) &
|
||||
no --- special threshold-friendly primitive &
|
||||
Class S1 + S4 &
|
||||
production R-LWE fork, lifecycle DKG complete \\
|
||||
\textbf{Corona} (academic upstream + Lux expansions) &
|
||||
\texttt{github.com/luxfi/corona} &
|
||||
Ring-LWE ($\Rq$) &
|
||||
BLAKE3 (academic) / SHA-3 (Lux expansions) &
|
||||
no &
|
||||
academic &
|
||||
upstream + lifecycle DKG expansions in flight \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
All variants share:
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item \textbf{Protocol skeleton} --- 2-round threshold sign, Pedersen
|
||||
DKG, proactive resharing with beacon-randomized quorum, identifiable
|
||||
abort with signed complaints.
|
||||
\item \textbf{Hash suite} --- NIST SP 800-185 (cSHAKE256, KMAC256,
|
||||
TupleHash256) is canonical for every NIST-track variant. BLAKE3
|
||||
deltas appear only in legacy / academic profiles
|
||||
(\texttt{Pulsar.R-BLAKE3}, upstream Corona) and are explicitly
|
||||
out-of-scope for any MPTC submission.
|
||||
\item \textbf{Constant-time discipline} --- every secret-touching
|
||||
path constant-time via \texttt{crypto/subtle} or local equivalents.
|
||||
No stdlib \texttt{log} in any primitive package; all logging goes
|
||||
through \texttt{github.com/luxfi/log} at fields the threat model has
|
||||
explicitly classified as public.
|
||||
\item \textbf{Implementation language} --- Go reference; C / Rust
|
||||
conformance after encoding-freeze gate per variant.
|
||||
\end{itemize}
|
||||
|
||||
What differs between variants:
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item \textbf{Algebra} --- Ring-LWE for Corona, Module-LWE for
|
||||
Pulsar. The algebraic shape determines parameter sizes, signature
|
||||
sizes, and the structure of the Pedersen commitment scheme.
|
||||
\item \textbf{Verification target} --- Corona verifies under its own
|
||||
verifier (a custom 2-round-aggregated check); Pulsar verifies under
|
||||
unmodified FIPS~204 ML-DSA.Verify. The latter is the single
|
||||
highest-value property of the family.
|
||||
\item \textbf{NIST submission posture} --- see Class column above.
|
||||
\item \textbf{Production maturity} --- Pulsar.R has a hardened
|
||||
reshare path, KAT suite, deployed code. Pulsar.M has a complete spec
|
||||
(\texttt{spec/pulsar-m.tex} plus \texttt{parameters.tex},
|
||||
\texttt{system-model.tex}, \texttt{security-games.tex}), a working
|
||||
Go reference (single-party and threshold paths, both
|
||||
$\mathrm{GF}(257)$ and $\mathrm{GF}(q)$ Shamir layers), and a KAT
|
||||
suite. The scaling target $N^* = 1{,}111{,}111$ is empirically
|
||||
validated. Production hardening (HSM integration, formal CT
|
||||
guarantees, cross-implementation conformance vs.\ BoringSSL FIPS /
|
||||
AWS-LC / OpenSSL 3) is round-2 work.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Why one family}
|
||||
|
||||
NIST MPTC IR 8214C accepts each variant as a separate submission
|
||||
package in either Class N or Class S. Submitting two as a
|
||||
coordinated \textbf{family}:
|
||||
|
||||
\begin{enumerate}[leftmargin=*, itemsep=0pt]
|
||||
\item \textbf{Reuses infrastructure once.} The DKG harness, KAT
|
||||
cross-validation, transcript binding, constant-time analysis,
|
||||
lattice-estimator runs, patent disclosure, and IP review build to a
|
||||
shared \texttt{pulsar-test/} and \texttt{pulsar-spec-common/} set of
|
||||
artifacts both submissions reference.
|
||||
\item \textbf{Cross-validates the protocol skeleton.} A reviewer
|
||||
attacking the Pedersen DKG soundness in Pulsar.R is also attacking
|
||||
it in Pulsar.M. Soundness arguments compose; reviewers don't have to
|
||||
redo work.
|
||||
\item \textbf{Demonstrates orthogonality.} Both submissions running
|
||||
on the same 2-round structure with different lattice bases is itself
|
||||
a security argument: the family's robustness comes from a small,
|
||||
audited protocol skeleton with parameterized algebra, not from a
|
||||
one-off primitive.
|
||||
\item \textbf{Forwards-only.} Adding \texttt{Pulsar.W} (or whichever
|
||||
future variant) becomes a parameter-set + algebra change against the
|
||||
same skeleton, not a new project. The naming reservation is
|
||||
pre-paid.
|
||||
\end{enumerate}
|
||||
|
||||
\subsection{What goes where}
|
||||
|
||||
\begin{center}
|
||||
\small
|
||||
\begin{tabular}{p{4.0cm}p{2.5cm}p{3.5cm}p{3.5cm}}
|
||||
\toprule
|
||||
artifact & shared & Pulsar.R & Pulsar.M \\
|
||||
\midrule
|
||||
2-round protocol description & shared spec &
|
||||
parameterised for $\Rq$ & parameterised for $\Rq^k$ \\
|
||||
Pedersen DKG (proper hiding) & shared spec &
|
||||
params for $\Rq$ & params for $\Rq^k$ \\
|
||||
Proactive resharing (beacon-rand) & shared spec &
|
||||
params for $\Rq$ & params for $\Rq^k$ \\
|
||||
Reference Go impl & shared testkit &
|
||||
full primitive in \texttt{pulsar/} &
|
||||
full primitive in \texttt{pulsar-m/} \\
|
||||
KATs & shared format &
|
||||
\texttt{vectors/} per repo &
|
||||
\texttt{vectors/} per repo \\
|
||||
Lattice estimator & shared script &
|
||||
parameter file per variant &
|
||||
parameter file per variant \\
|
||||
Patent claims & shared review &
|
||||
repo-local \texttt{patent-notes.tex} &
|
||||
repo-local \texttt{patent-notes.tex} \\
|
||||
MPTC technical specification PDF & NO &
|
||||
\texttt{pulsar/spec/pulsar-r.pdf} &
|
||||
\texttt{pulsar-m/spec/pulsar-m.pdf} \\
|
||||
MPTC submission package & NO --- separate Class S vs Class N &
|
||||
one per variant & one per variant \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
Two separate MPTC packages, one shared technical foundation. The
|
||||
shared material is brought in by reference from each submission's
|
||||
spec PDF, matching how PQ-CRYSTALS submitted Dilithium and Kyber as
|
||||
related algorithms in Round 3.
|
||||
|
||||
\subsection{Naming discipline}
|
||||
|
||||
Three sibling threshold-signature libraries; each is its own NIST
|
||||
MPTC submission package (no umbrella package).
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item \textbf{Pulsar} --- the FIPS 204-compatible Module-LWE
|
||||
threshold. Always capitalised, no hyphen, no suffix. Identifier
|
||||
form: \texttt{pulsar}.
|
||||
\item \textbf{Corona} --- the Ring-LWE production threshold (Lux's
|
||||
hardened fork of Corona). Always capitalised. Identifier form:
|
||||
\texttt{corona}.
|
||||
\item \textbf{Corona} --- the academic Ring-LWE upstream plus Lux's
|
||||
lifecycle DKG expansions. Always capitalised. Identifier form:
|
||||
\texttt{corona}.
|
||||
\end{itemize}
|
||||
|
||||
Naming rules:
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item Do not write ``Pulsar.M'' or ``Pulsar-M'' in new prose; both
|
||||
are the pre-rebrand legacy names of the M-LWE threshold (now just
|
||||
``Pulsar'').
|
||||
\item Do not write ``Pulsar.R'' or ``Pulsar-R''; the R-LWE threshold
|
||||
is now ``Corona'' --- distinct name, distinct repo.
|
||||
\item HashSuiteID byte (per HIP-0077 \S``Lux consensus PQ modes'')
|
||||
identifies the \textbf{hash family}, not the variant. Pulsar and
|
||||
Corona canonical profiles both use \texttt{HashSuiteSHA3 = 2}. A
|
||||
future Pulsar with a different hash family (e.g.\ SHAKE256 only)
|
||||
would claim a new HashSuiteID without renaming the variant.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Repo organisation}
|
||||
|
||||
\begin{verbatim}
|
||||
~/work/lux/
|
||||
|-- pulsar/ <- Pulsar.R (R-LWE, production fork of Corona)
|
||||
| |-- sign/
|
||||
| |-- primitives/
|
||||
| |-- dkg2/ <- Pedersen DKG over R_q
|
||||
| |-- reshare/ <- proactive resharing
|
||||
| |-- hash/ <- Pulsar-SHA3 + Pulsar-BLAKE3 (legacy)
|
||||
| `-- ...
|
||||
|-- pulsar-m/ <- Pulsar.M (M-LWE, FIPS 204-compatible)
|
||||
| |-- ref/go/
|
||||
| |-- spec/ <- own MPTC technical spec PDF
|
||||
| |-- docs/ <- family-architecture moved to spec/
|
||||
| `-- ...
|
||||
|-- corona/ <- academic upstream (NOT Pulsar; cited as the
|
||||
| R-LWE 2-round skeleton's origin)
|
||||
`-- consensus/
|
||||
`-- protocol/quasar/ <- witness orchestrator that consumes Pulsar
|
||||
variants via WitnessProducer interface
|
||||
\end{verbatim}
|
||||
|
||||
The \texttt{consensus/protocol/quasar/} orchestrator binds to Pulsar
|
||||
variants through \texttt{QWitnessProducer} (interface in
|
||||
\texttt{consensus/protocol/quasar/witness\_producer.go}). Quasar
|
||||
doesn't know which variant produces the witness --- it gets a
|
||||
\texttt{[]byte} and a HashSuiteID. Variants are interchangeable at
|
||||
the orchestration layer, which is exactly the orthogonality the
|
||||
family architecture claims.
|
||||
|
||||
\subsection{NIST submission strategy}
|
||||
|
||||
Per CTO Decision 4 (recorded in this branch's HIP-0077 process
|
||||
notes):
|
||||
|
||||
\begin{quote}
|
||||
Submit BOTH. Pulsar.M leads (Class N1+N4, FIPS~204
|
||||
verifier-interchangeable, highest strategic value). Pulsar.R parallel
|
||||
(Class S1+S4, established production code, demonstrates the family's
|
||||
R-LWE branch). Withdrawing either wastes existing work; submitting
|
||||
both forces the team to factor shared infrastructure into reusable
|
||||
modules --- the orthogonality requirement.
|
||||
\end{quote}
|
||||
|
||||
Single Git tag, simultaneous cut: \texttt{mptc-preview-2026} on
|
||||
\texttt{pulsar} and \texttt{pulsar-m} at the same SHA discipline.
|
||||
Both submissions reference frozen artifacts. Drift between the two
|
||||
repos after the tag is only allowed via amendments NIST permits in
|
||||
the public-analysis window.
|
||||
|
||||
\subsection{Status}
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item[$\boxtimes$] Pulsar.R production code (shipping in Lux primary
|
||||
network)
|
||||
\item[$\boxtimes$] Pulsar.R hardening: F8 (no log of secret state),
|
||||
F9 (constant-time reshare), F12 (LIGHT\_MNEMONIC guard)
|
||||
\item[$\square$] Pulsar.R MPTC spec doc finalised
|
||||
(\texttt{pulsar/spec/pulsar-r.pdf} to be added)
|
||||
\item[$\square$] Pulsar.R \texttt{mptc-preview-2026} tag
|
||||
\item[$\boxtimes$] Pulsar.M repo bootstrap (\texttt{pulsar-m/})
|
||||
\item[$\square$] Pulsar.M Module-LWE algorithm body in spec (in
|
||||
flight via scientist agent)
|
||||
\item[$\square$] Pulsar.M reference implementation
|
||||
\item[$\square$] Pulsar.M FIPS~204 cross-validation (output
|
||||
interchangeability proof)
|
||||
\item[$\square$] Pulsar.M \texttt{mptc-preview-2026} tag
|
||||
\item[$\square$] Family architecture cross-reference baked into
|
||||
HIP-0077
|
||||
\end{itemize}
|
||||
|
||||
\subsection{See also}
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item HIP-0077
|
||||
(\texttt{hanzo/hips/HIPs/hip-0077-mesh-identity-gossip-and-payments.md})
|
||||
--- defines the PQMode enum that selects which Pulsar variant the
|
||||
consensus layer asks for.
|
||||
\item HIP-0078 (in flight) --- Q-Chain PQ-rollup. Replaces Z-Chain
|
||||
Groth16/BN254 with a PQ-secure SNARK. Pulsar.M's per-validator
|
||||
ML-DSA-65 sigs are the rollup target.
|
||||
\item NIST IR 8214C --- \emph{First Call for Multi-Party Threshold
|
||||
Schemes} (January 2026, package deadline 2026-Nov-16).
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,211 @@
|
||||
% Pulsar-M known limitations -- included by pulsar-m.tex.
|
||||
% Mirrors docs/known-limitations.md (now deleted; this file is the
|
||||
% canonical LaTeX form, maintained as a living document).
|
||||
|
||||
Maintained as a living document. Better that reviewers see the gaps
|
||||
before they find them.
|
||||
|
||||
\subsection{Spec / protocol}
|
||||
|
||||
\paragraph{Output interchangeability with FIPS 204 --- DEMONSTRATED
|
||||
IN v0.1.}
|
||||
The headline claim --- ``Pulsar-M signatures verify under unmodified
|
||||
FIPS~204 ML-DSA.Verify'' --- holds for the v0.1 reference. The
|
||||
\texttt{pulsarm.Verify} entry point dispatches to
|
||||
\texttt{cloudflare/circl/sign/mldsa\{44,65,87\}.Verify} verbatim; the
|
||||
threshold-sign output is the same byte-for-byte signature an
|
||||
unmodified FIPS~204 signer would have produced on the reconstructed
|
||||
seed. KAT cross-validation lives at
|
||||
\texttt{ref/go/pkg/pulsarm/kat\_test.go:
|
||||
TestKAT\_ThresholdSign\_Replay}, which verifies every committed
|
||||
threshold signature under \texttt{pulsarm.Verify} and therefore
|
||||
under the underlying FIPS~204 verifier.
|
||||
|
||||
\paragraph{v0.1 uses reconstruction-aggregator; v0.2 will use
|
||||
Lagrange-linearity.}
|
||||
v0.1 instantiates the threshold protocol via a
|
||||
\textbf{reconstruction-aggregator} model: a threshold quorum
|
||||
delivers byte-wise Shamir shares of the FIPS~204 seed to an
|
||||
aggregator (any honest quorum member), which Lagrange-reconstructs
|
||||
the master byte-sum in $\mathrm{GF}(257)$, runs the deterministic
|
||||
cSHAKE256 mix that DKG committed to, and calls FIPS~204 Sign once.
|
||||
The master seed lives in the aggregator's memory for the duration of
|
||||
one Sign call.
|
||||
|
||||
The \texttt{pulsar-m.tex} \S4.2 \textbf{Lagrange-linearity sign}
|
||||
path --- each party computes $\mathbf{z}_i = \mathbf{y}_i + c \cdot
|
||||
\lambda_i \cdot \mathbf{s}_i$ locally and the aggregator sums them,
|
||||
with the master secret never reconstructed --- is the v0.2 target.
|
||||
It is mathematically equivalent at the output level (the produced
|
||||
signature is byte-equal) but information-theoretically stronger
|
||||
because no party ever holds the master secret.
|
||||
|
||||
The v0.1 model is acceptable for the round-1 MPTC submission when
|
||||
paired with the reshare cadence specified in
|
||||
\texttt{spec/system-model.tex} (no aggregator holds a secret across
|
||||
more than one signature). v0.2 ships the stronger soundness property
|
||||
that adaptive-corruption analysis requires.
|
||||
|
||||
\paragraph{Pedersen commitments: RO model in v0.1, M-LWE in v0.2.}
|
||||
v0.1 uses cSHAKE256 RO-binding commitments
|
||||
$C_i = \cSHAKE256(c_i \,\Vert\, \mathit{blind}_i)$. v0.2 replaces
|
||||
them with the $\Rq^k$ Pedersen commitment of
|
||||
\texttt{spec/pulsar-m.tex} \S3.2:
|
||||
$C_{i,k} = \mathbf{A} \cdot c_{i,k} + \mathbf{B} \cdot r_{i,k}$. Both
|
||||
bindings are sound; the v0.2 M-LWE binding is the post-quantum-safe
|
||||
variant required for the formal proof to reduce to an M-LWE / MSIS
|
||||
hardness assumption (the v0.1 RO-binding reduces to cSHAKE256
|
||||
collision resistance, which itself reduces to SHA-3 security).
|
||||
|
||||
\paragraph{Per-byte Shamir: dual-field design.}
|
||||
v0.1 Shamir-shares the FIPS~204 seed byte-wise. The reference
|
||||
implementation supports two fields:
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item $\mathrm{GF}(257)$ for committees with $n \le 256$ (default
|
||||
for small validator sets, 64-byte wire share).
|
||||
\item $\mathrm{GF}(q) = \mathrm{GF}(8\,380\,417)$ for committees with
|
||||
$256 < n \le q - 1$ (mandatory for any large committee, 128-byte
|
||||
wire share).
|
||||
\end{itemize}
|
||||
|
||||
Auto-selection logic in
|
||||
\texttt{ref/go/pkg/pulsarm/types.go::resolveField} picks the
|
||||
narrowest field that fits. The canonical extreme committee target is
|
||||
\texttt{TargetCommitteeSize = 1\_111\_111} (seven 1s); see
|
||||
\texttt{spec/pulsar-m.tex} \S``Large committees'' for the formal
|
||||
scaling theorem.
|
||||
|
||||
v0.2 will reshape this to polynomial Shamir over $\Rq^k$ matching
|
||||
\texttt{spec/pulsar-m.tex} \S3.3. The output is the same FIPS~204
|
||||
signature in all cases; the v0.2 reshape is required to make the
|
||||
Lagrange-linearity sign path work without round-tripping through the
|
||||
byte-sum representation.
|
||||
|
||||
\paragraph{Adaptive corruption proof not yet written.}
|
||||
Static-corruption security is the baseline target.
|
||||
Adaptive-corruption security is a stretch goal for the round-1
|
||||
submission and a hard requirement for round 2.
|
||||
|
||||
\paragraph{Mobile-adversary (proactive resharing) proof inherits
|
||||
Pulsar's gaps.}
|
||||
Pulsar's \texttt{reshare/} package has documented soundness against
|
||||
mobile adversaries with deterministic quorum selection (the F10
|
||||
weakness in HIP-0077). Pulsar-M's \texttt{reshare/} ports this with
|
||||
beacon-randomized quorum selection, which strictly improves on
|
||||
Pulsar --- but the formal proof of the strengthened protocol is
|
||||
still in draft.
|
||||
|
||||
\subsection{Implementation}
|
||||
|
||||
\paragraph{Reference implementation is Go-only for round 1.}
|
||||
The C reference comes after spec encoding freeze. Round-1 reviewers
|
||||
have only the Go reference. NIST MPTC permits any language; a C
|
||||
companion is strongly recommended for round 2.
|
||||
|
||||
\paragraph{No optimized implementation.}
|
||||
\texttt{ref/go/} is the boring, clear, slow reference. AVX-512 /
|
||||
NEON / SHA-3-NI optimization is post-submission work. Performance
|
||||
numbers in the experimental-evaluation report reflect the reference,
|
||||
not optimized implementations.
|
||||
|
||||
\paragraph{No first-order masking.}
|
||||
Power analysis resistance via masking is post-submission hardening.
|
||||
The reference is constant-time at the algorithmic level (no
|
||||
secret-dependent branches, no secret-dependent memory access
|
||||
patterns in inner loops) but has no power-side-channel
|
||||
countermeasures.
|
||||
|
||||
\paragraph{No HSM integration.}
|
||||
Production-deployment patches (HSM integration, FIPS 140-3 module
|
||||
shim) are post-submission. The reference is software-only.
|
||||
|
||||
\paragraph{Constant-time analysis is dudect-level.}
|
||||
Go's compiler is not guaranteed constant-time at the IR level. We
|
||||
use dudect (\texttt{ct/dudect/}) to check the leading-edge timing
|
||||
distribution for secret-correlated values. This catches the obvious
|
||||
leaks but does not provide the formal guarantee of e.g.\
|
||||
Jasmin-verified C kernels. Formal verification
|
||||
(Jasmin/Formosa/EasyCrypt) is post-submission.
|
||||
|
||||
\subsection{NIST process}
|
||||
|
||||
\paragraph{No prior NIST MPTC preview submission.}
|
||||
We're starting from cold. The third-preview window deadline
|
||||
(2026-Jul-20) is roughly two months out. Achieving a credible
|
||||
preview writeup in that window is the immediate gate. If we miss the
|
||||
third preview, we lose the ability to submit the round-1 package
|
||||
without a preview, which is a hard requirement per IR 8214C \S5.1.
|
||||
|
||||
\paragraph{Patent claims not yet inventoried.}
|
||||
Pulsar inherits Corona's IP posture. Pulsar-M needs a fresh
|
||||
patent-claim review for the M-LWE adaptation.
|
||||
\texttt{spec/patent-notes.tex} collects claims as they're discovered;
|
||||
final notice for the package is on the critical path for
|
||||
2026-Nov-16.
|
||||
|
||||
\paragraph{External cryptanalysis engagement not yet contracted.}
|
||||
NIST MPTC submissions are strengthened by independent academic
|
||||
cryptanalysis. We have not yet engaged a third party. A 6-month
|
||||
engagement starting July 2026 is the target --- this aligns with the
|
||||
post-package public-analysis window rather than blocking the package
|
||||
itself.
|
||||
|
||||
\subsection{Repo / build}
|
||||
|
||||
\paragraph{Go module initialised.}
|
||||
\texttt{go.mod} brings in \texttt{cloudflare/[email protected]} (FIPS~204
|
||||
backbone) and \texttt{golang.org/x/crypto/sha3} (FIPS~202 / SP
|
||||
800-185 transcripts). Cleanly builds with \texttt{GOWORK=off}.
|
||||
|
||||
\paragraph{Spec PDF not yet built.}
|
||||
\texttt{spec/pulsar-m.tex} is \textbf{complete} as LaTeX source
|
||||
(1500+ lines covering Front matter / Notation / Preliminaries /
|
||||
Algorithms / Verification / Reshare / Identifiable abort / Security
|
||||
analysis / Concrete parameters / Large committees / Encodings /
|
||||
System model / Implementation considerations / Performance / Test
|
||||
vectors / Complexity analysis / Deployment / Comparison / Patent
|
||||
claims / Known limitations / Open questions). The companion files
|
||||
\texttt{security-games.tex}, \texttt{system-model.tex}, and
|
||||
\texttt{parameters.tex} are also complete. Building the PDF via
|
||||
\texttt{latexmk -pdf spec/pulsar-m.tex} is on the active writing
|
||||
track once the bib resolution lands.
|
||||
|
||||
\paragraph{KAT suite generated.}
|
||||
\texttt{vectors/\{keygen,sign,verify,threshold-sign,dkg\}.json} are
|
||||
committed. \texttt{scripts/gen\_vectors.sh} re-runs the generator
|
||||
and verifies that re-running produces byte-identical output (the
|
||||
deterministic-fixture gate). The CAVS-style \texttt{kat-v1.rsp} ACVP
|
||||
companion is on the v0.2 path; ACVP support requires the
|
||||
post-encoding-freeze byte layout.
|
||||
|
||||
\paragraph{Lattice-estimator parameter table.}
|
||||
\texttt{spec/parameters.tex} now includes the classical + quantum
|
||||
security-level table (numbers inherited verbatim from FIPS~204 \S8
|
||||
because Pulsar-M does not alter the underlying M-LWE parameters).
|
||||
The Albrecht et al.\ lattice-estimator script
|
||||
\texttt{estimator/params.sage} reproduces the table; the estimator
|
||||
commit hash is pinned at submission in
|
||||
\texttt{estimator/README.md}.
|
||||
|
||||
\subsection{Compared to Pulsar (R-LWE)}
|
||||
|
||||
\begin{center}
|
||||
\begin{tabular}{lll}
|
||||
\toprule
|
||||
dimension & Pulsar & Pulsar-M \\
|
||||
\midrule
|
||||
Algebraic basis & Ring-LWE & Module-LWE \\
|
||||
Hash & SHA-3 cSHAKE / BLAKE3 legacy & SHA-3 cSHAKE only \\
|
||||
FIPS~204 output interchange & no (R-LWE) & yes (target) \\
|
||||
MPTC class & S1/S4 & N1/N4 \\
|
||||
Parameter sets & Pulsar-internal & ML-DSA-44/65/87 \\
|
||||
DKG & Pedersen over $\Rq$ & Pedersen over $\Rq^k$ \\
|
||||
Reshare & deterministic quorum & beacon-randomized quorum \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
Where Pulsar provides feature X and Pulsar-M doesn't yet, Pulsar-M's
|
||||
goal is to inherit X verbatim from Pulsar's \texttt{dkg2/} and
|
||||
\texttt{reshare/} packages with the M-LWE shape change.
|
||||
@@ -0,0 +1,183 @@
|
||||
% Pulsar-M NIST MPTC category targeting -- included by pulsar-m.tex.
|
||||
% Mirrors docs/nist-mptc-category.md (now deleted; this file is the
|
||||
% canonical LaTeX form).
|
||||
|
||||
\paragraph{Reference.}
|
||||
NIST IR 8214C, \emph{First Call for Multi-Party Threshold Schemes}
|
||||
(January 2026). Package deadline expected 2026-Nov-16. Preview
|
||||
deadline 2026-Jul-20.
|
||||
|
||||
\subsection{Pulsar-M target: Class N1 + N4}
|
||||
|
||||
NIST MPTC subdivides threshold schemes into:
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item \textbf{Class S} (Special) --- threshold-friendly primitives
|
||||
that \emph{are not} output-interchangeable with a NIST-specified
|
||||
primitive. Submission evaluated for ``novel threshold-friendly
|
||||
design.''
|
||||
\item \textbf{Class N} (Normal-mode) --- threshold implementations
|
||||
\emph{of} a NIST-specified primitive whose outputs are
|
||||
interchangeable with the corresponding non-threshold primitive's
|
||||
outputs.
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item \textbf{N1}: signing
|
||||
\item \textbf{N2}: encryption / decryption
|
||||
\item \textbf{N3}: KEM
|
||||
\item \textbf{N4}: ML keygen / DKG (Module-Lattice key generation,
|
||||
distributed)
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
Pulsar-M aims for \textbf{N1 (threshold ML-DSA signing) + N4
|
||||
(distributed ML-DSA keygen)}. The headline interchangeability claim:
|
||||
|
||||
\begin{quote}
|
||||
A signature $\sigma$ produced by a Pulsar-M threshold ceremony on
|
||||
message $\mu$ against group public key $\mathit{pk}$ verifies under
|
||||
unmodified FIPS~204 \texttt{ML-DSA.Verify}$(\mathit{pk}, \mu,
|
||||
\sigma)$ returning \texttt{accept}.
|
||||
\end{quote}
|
||||
|
||||
If we can prove and demonstrate this, Pulsar-M is a Class N
|
||||
candidate. If the output is not bit-for-bit FIPS~204 (e.g.\ encoding
|
||||
differs in any field), Pulsar-M falls back to Class S --- still
|
||||
valid, but a weaker NIST positioning.
|
||||
|
||||
\subsection{Output interchangeability --- what has to hold}
|
||||
|
||||
ML-DSA-65 signatures (FIPS~204 \S5.4, Algorithm~26 \texttt{sigEncode})
|
||||
are encoded as a fixed-length 3309-byte string $\sigma = (\tilde c,
|
||||
\mathbf{z}, \mathbf{h})$ whose three components decompose exactly as:
|
||||
|
||||
\begin{verbatim}
|
||||
sigma = (c_tilde || z || h) 3309 bytes
|
||||
c_tilde in {0,1}^{2 lambda} 48 bytes
|
||||
// FIPS 204 commitment-hash length; 2 lambda bits with
|
||||
// lambda=192 = 384 bits.
|
||||
// (2 lambda here is the FIPS 204 commitment-hash parameter,
|
||||
// not the security level -- the two happen to numerically
|
||||
// agree for ML-DSA-65 because the standard ties one to the
|
||||
// other at this parameter set.)
|
||||
z in R^ell_q 3200 bytes
|
||||
// ell = 5 polynomials, each 256 coefficients, packed at
|
||||
// log2(2 gamma_1) = 20 bits per coefficient.
|
||||
// 5 * 256 * 20 / 8 = 3200 bytes.
|
||||
h in {0,1}^{omega + k} 61 bytes
|
||||
// omega = 55 (hint bound), k = 6 (commitment-vector
|
||||
// dimension). FIPS 204 Algorithm 22 hintBitPack + Algorithm
|
||||
// 28 sigEncode pack omega + k = 61 bits as 61 bytes (one
|
||||
// byte per bit position, terminator-first encoding per the
|
||||
// standard).
|
||||
total: 48 + 3200 + 61 = 3309 bytes (FIPS 204 Table 2)
|
||||
\end{verbatim}
|
||||
|
||||
For Pulsar-M to claim Class N1, the threshold-aggregated signature
|
||||
MUST deserialize as exactly this triple, with the same byte layout,
|
||||
the same canonicalization rules, and the same rejection criteria.
|
||||
The threshold protocol is allowed to perform multiple rounds
|
||||
internally, but its emitted artifact MUST be a single FIPS~204
|
||||
$\sigma$.
|
||||
|
||||
This is non-trivial: ML-DSA's rejection sampling means a single-shot
|
||||
threshold output can fail rejection and require restart. Pulsar's
|
||||
2-round structure handles this for R-LWE; Pulsar-M needs to
|
||||
reproduce the rejection-restart logic for M-LWE without leaking
|
||||
secret information across the restart.
|
||||
|
||||
\subsection{Required package deliverables}
|
||||
|
||||
Per NIST IR 8214C \S5:
|
||||
|
||||
\begin{center}
|
||||
\begin{tabular}{lll}
|
||||
\toprule
|
||||
element & format & location \\
|
||||
\midrule
|
||||
Technical Specification & PDF (LaTeX) & \texttt{spec/pulsar-m.pdf} \\
|
||||
Reference Implementation & open-source code & \texttt{ref/go/} \\
|
||||
Report on Experimental Evaluation & PDF + reproducible scripts &
|
||||
\texttt{bench/results/REPORT.md} + \texttt{bench/run\_all.sh} \\
|
||||
Notes on Patent Claims & PDF & \texttt{spec/patent-notes.tex} \\
|
||||
Concrete parameter set & section in spec & \texttt{spec/parameters.tex} \\
|
||||
Security analysis (proofs) & section in spec & \texttt{spec/security-games.tex} \\
|
||||
Public repository & GitHub or equiv & \url{https://github.com/luxfi/pulsar-m} \\
|
||||
Build/test/benchmark scripts & shell & \texttt{scripts/*.sh} \\
|
||||
Open-source license & text & \texttt{LICENSE} (Apache-2.0) \\
|
||||
I/O test vectors & JSON / RSP & \texttt{vectors/kat-v1.\{json,rsp\}} \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
Optional but strongly recommended:
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item Executive summary (1-2 pages) at front of spec.
|
||||
\item Threat-model document (\texttt{spec/threat-model.tex}).
|
||||
\item System-model document (\texttt{spec/system-model.tex}).
|
||||
\item Known-limitations appendix (so reviewers see the gaps before
|
||||
they find them).
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Required security strengths}
|
||||
|
||||
NIST MPTC \S4.5 gives the required and suggested security-strength
|
||||
targets:
|
||||
|
||||
\begin{center}
|
||||
\begin{tabular}{llll}
|
||||
\toprule
|
||||
target & classical & post-quantum (NIST PQ category) & statistical \\
|
||||
\midrule
|
||||
\textbf{required} ($\ge 1$ parameterization) & $\ge 128$ bits &
|
||||
$\ge$ Category 1 & $\ge 40$ bits \\
|
||||
\textbf{suggested} (additional, optional) & $\ge 192$ bits &
|
||||
$\ge$ Category 3 & $\ge 64$ bits \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
Pulsar-M will ship parameter sets matching ML-DSA-65 (Category 3)
|
||||
for the suggested target, and potentially ML-DSA-44 (Category 2) and
|
||||
ML-DSA-87 (Category 5) for full coverage.
|
||||
|
||||
\subsection{Class N vs Class S decision}
|
||||
|
||||
Pulsar-M is N if and only if:
|
||||
|
||||
\begin{enumerate}[leftmargin=*, itemsep=0pt]
|
||||
\item A working reference implementation produces signatures
|
||||
byte-equal to FIPS~204 ML-DSA on the same $(\mathit{pk}, \mu)$ for
|
||||
some valid threshold ceremony.
|
||||
\item The threshold key generation produces a $\mathit{pk}$ that's a
|
||||
valid FIPS~204 ML-DSA public key (no extra public material
|
||||
distinguishable from a single-party $\mathit{pk}$).
|
||||
\item The verification relation in the spec is the FIPS~204 verifier
|
||||
verbatim, with no Pulsar-specific changes.
|
||||
\end{enumerate}
|
||||
|
||||
If any of (1)-(3) fails, we ship as Class S with a clear ``future
|
||||
work: output interchangeability'' note. The class decision is
|
||||
finalized at the point we freeze the spec encoding.
|
||||
|
||||
\subsection{Pulsar (R-LWE) for comparison}
|
||||
|
||||
Pulsar (R-LWE) targets \textbf{Class S1 + S4}: special
|
||||
threshold-friendly two-round signature, not output-interchangeable
|
||||
with any NIST-approved primitive. The S1/S4 framing is the right
|
||||
framing for Corona-derivatives unless and until NIST blesses
|
||||
Corona-shaped outputs as a primitive.
|
||||
|
||||
\subsection{Status}
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item[$\square$] Class declared (N vs S, awaiting spec freeze)
|
||||
\item[$\square$] Preview writeup drafted
|
||||
\item[$\square$] Preview submitted (target 2026-Jul-20)
|
||||
\item[$\square$] Spec freeze
|
||||
\item[$\square$] Reference impl complete
|
||||
\item[$\square$] KATs cross-validated against FIPS~204 reference
|
||||
\item[$\square$] Experimental-evaluation report
|
||||
\item[$\square$] Patent-claims notes finalized
|
||||
\item[$\square$] Package submitted (target 2026-Nov-16)
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,111 @@
|
||||
% Pulsar-M Notes on Patent Claims -- included by pulsar-m.tex.
|
||||
% Mirrors docs/patent-notes-draft.md (now deleted; this file is the
|
||||
% submission-package patent-claims appendix).
|
||||
|
||||
\paragraph{Required by NIST MPTC IR 8214C \S5} as a package
|
||||
deliverable. This document is collected over the development period
|
||||
and finalized for the submission.
|
||||
|
||||
\subsection{Status}
|
||||
|
||||
\textbf{Draft.} No patent claims have been formally identified. This
|
||||
appendix tracks claims as contributors disclose them.
|
||||
|
||||
\subsection{Inherited from upstream}
|
||||
|
||||
\paragraph{Pulsar (\texttt{luxfi/pulsar}).}
|
||||
Pulsar-M reuses Pulsar's protocol structure. Pulsar's IP posture per
|
||||
its README:
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item Apache-2.0 licensed.
|
||||
\item Patent grant per Apache 2.0 \S3 from each contributor.
|
||||
\item No known active patent claims as of repository creation.
|
||||
\end{itemize}
|
||||
|
||||
This applies to Pulsar-M to the extent that Pulsar-M code or
|
||||
protocol elements are derivative of Pulsar.
|
||||
|
||||
\paragraph{Corona (\texttt{luxfi/corona}).}
|
||||
Pulsar (and therefore Pulsar-M) is a fork of academic Corona.
|
||||
Corona (ePrint 2024/1113) authors: Cecilia Boschini, Darya
|
||||
Kaviani, Russell W. F. Lai, Giulio Malavolta, Akira Takahashi, Mehdi
|
||||
Tibouchi. Corona's open-source repo is Apache-2.0 with no asserted
|
||||
patent claims as of mid-2026. Pulsar-M's M-LWE adaptation does not
|
||||
import Corona code directly but inherits the protocol structure.
|
||||
|
||||
\paragraph{ML-DSA / FIPS 204.}
|
||||
ML-DSA is a NIST-standardized algorithm. The Dilithium team's IP
|
||||
disclosures during NIST PQC standardization are public on the NIST
|
||||
PQC website. Pulsar-M targets output interchangeability with
|
||||
FIPS~204 but does not assert any rights over FIPS~204 itself.
|
||||
|
||||
\subsection{Contributor disclosures}
|
||||
|
||||
Per \texttt{CONTRIBUTING.md}, every commit's \texttt{Signed-off-by}
|
||||
line is taken as either:
|
||||
|
||||
\begin{enumerate}[leftmargin=*, itemsep=0pt]
|
||||
\item An explicit assertion that the contributor has no relevant
|
||||
patent claims, OR
|
||||
\item A reference to a disclosed claim listed below.
|
||||
\end{enumerate}
|
||||
|
||||
\begin{center}
|
||||
\begin{tabular}{llll}
|
||||
\toprule
|
||||
date & contributor & type & disclosure \\
|
||||
\midrule
|
||||
2026-05-10 & Lux Industries Inc & initial repo & no claims asserted \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
(Updated as contributions land.)
|
||||
|
||||
\subsection{Third-party patents we may need to navigate}
|
||||
|
||||
Live concerns to investigate before submission:
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item Lattice-estimator usage (we use the open-source estimator;
|
||||
license pass-through to MIT).
|
||||
\item Gaussian sampler implementation (FIPS~204 references CDT;
|
||||
alternate rejection samplers may have IP).
|
||||
\item Polynomial multiplication via NTT (standard, no known IP).
|
||||
\item Pedersen commitments (1991 paper, expired patents).
|
||||
\end{itemize}
|
||||
|
||||
The submission's Notes on Patent Claims will explicitly call out
|
||||
each of these.
|
||||
|
||||
\subsection{NIST MPTC submission requirements}
|
||||
|
||||
NIST IR 8214C \S5 (Notes on Patent Claims) requires:
|
||||
|
||||
\begin{quote}
|
||||
Submitter(s) shall include a statement of any patent claims known
|
||||
to them that may be relevant to the submitted package, regardless
|
||||
of who owns the claim. Statements of ``no known claims'' are
|
||||
acceptable.
|
||||
\end{quote}
|
||||
|
||||
Our final statement, once the spec freezes:
|
||||
|
||||
\begin{quote}
|
||||
\emph{To be drafted at spec freeze. Will incorporate every
|
||||
disclosure in the contributor table above, every inherited claim
|
||||
from Pulsar / Corona / ML-DSA, and the third-party investigation
|
||||
outcome.}
|
||||
\end{quote}
|
||||
|
||||
\subsection{Process}
|
||||
|
||||
\begin{enumerate}[leftmargin=*, itemsep=0pt]
|
||||
\item Every PR review checks for new IP-relevant code.
|
||||
\item Significant cryptographic additions (new sampling routine, new
|
||||
commitment shape, new aggregation step) trigger an explicit IP
|
||||
review with one of the sponsor's IP counsel.
|
||||
\item Final statement assembled at freeze, included in
|
||||
\texttt{spec/pulsar-m.pdf} Appendix~A.
|
||||
\end{enumerate}
|
||||
+26
-6
@@ -1417,8 +1417,8 @@ The reference implementation targets constant-time semantics as
|
||||
specified in \S\ref{sec:impl-ct}. Physical side-channel resistance
|
||||
(power analysis, EM, fault injection, cache timing) is out of scope
|
||||
for the round-1 MPTC submission; see
|
||||
\texttt{docs/known-limitations.md} for the deferred mitigations and
|
||||
\S\ref{sec:knownlimits} for the round-2 roadmap.
|
||||
\S\ref{sec:knownlimits} for the deferred mitigations and round-2
|
||||
roadmap.
|
||||
|
||||
% =====================================================================
|
||||
\section{Test vectors}
|
||||
@@ -1594,20 +1594,40 @@ $\beta_e$ & chain randomness beacon at epoch $e$ \\
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
\section{NIST MPTC category targeting}
|
||||
\label{sec:nist-mptc-category}
|
||||
\input{nist-mptc-category}
|
||||
|
||||
\section{Threat model}
|
||||
\label{sec:threat-model}
|
||||
\input{threat-model}
|
||||
|
||||
\section{Design decisions}
|
||||
\label{sec:design-decisions}
|
||||
\input{design-decisions}
|
||||
|
||||
\section{Pulsar family architecture}
|
||||
\label{sec:family-architecture}
|
||||
\input{family-architecture}
|
||||
|
||||
\section{Patent claims}
|
||||
\label{sec:patent}
|
||||
Final patent disclosure assembled from
|
||||
\texttt{docs/patent-notes-draft.md} at the submission freeze. Lux
|
||||
Final patent disclosure assembled at the submission freeze. Lux
|
||||
Industries Inc.\ asserts no patent claims on the cryptographic body
|
||||
of Pulsar-M; the threshold protocol is a port of the publicly-known
|
||||
Corona~\cite{corona2024} construction with the beacon-quorum
|
||||
strengthening of DD-006, both of which are explicitly placed into
|
||||
the public domain by this submission.
|
||||
\input{patent-notes}
|
||||
|
||||
\section{Known limitations}
|
||||
\label{sec:knownlimits}
|
||||
Mirror of \texttt{docs/known-limitations.md}, frozen at submission.
|
||||
Round-1 MPTC limitations and round-2 roadmap items:
|
||||
Frozen at submission. Round-1 MPTC limitations and round-2 roadmap
|
||||
items:
|
||||
|
||||
\input{known-limitations}
|
||||
|
||||
\subsection{Round-1 / round-2 roadmap (inline)}
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item \textbf{Adaptive corruption proof.} Round-1 proves
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
% Pulsar-M threat model -- included by pulsar-m.tex.
|
||||
% Mirrors docs/threat-model.md (now deleted; this file is the
|
||||
% canonical LaTeX form).
|
||||
|
||||
\subsection{Adversary classes}
|
||||
|
||||
We give an adversary the union of the following capabilities,
|
||||
parameterized by $t$ (the corruption threshold) and the corruption
|
||||
model:
|
||||
|
||||
\paragraph{Static corruption (default).}
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item Adversary $\mathcal{A}$ selects up to $t-1$ parties to corrupt
|
||||
\textbf{before} protocol start. From start to end of the protocol,
|
||||
those $t-1$ parties are controlled; the remaining honest parties run
|
||||
the protocol faithfully.
|
||||
\item $\mathcal{A}$ sees all messages on the broadcast channel + all
|
||||
messages on the authenticated point-to-point channels into corrupted
|
||||
parties.
|
||||
\item $\mathcal{A}$ learns each corrupted party's full state (secret
|
||||
share, randomness, per-round values) including session-state values.
|
||||
\item $\mathcal{A}$ can selectively delay messages within the round
|
||||
window but cannot forge messages from honest parties on
|
||||
authenticated channels.
|
||||
\end{itemize}
|
||||
|
||||
\paragraph{Adaptive corruption (stronger model).}
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item Adversary $\mathcal{A}$ can corrupt up to $t-1$ parties at any
|
||||
time during the protocol, including mid-round, conditioned on the
|
||||
transcript so far.
|
||||
\item Once corrupted, a party remains corrupted for the rest of the
|
||||
protocol.
|
||||
\item All other capabilities as in static.
|
||||
\end{itemize}
|
||||
|
||||
The Pulsar-M security analysis (\texttt{spec/security-games.tex})
|
||||
provides the precise game definitions. Static security is the
|
||||
baseline; adaptive security is a stretch goal for the first MPTC
|
||||
submission and a hard requirement for the second-round response.
|
||||
|
||||
\paragraph{Mobile corruption (proactive resharing).}
|
||||
For long-lived deployments where the validator set rotates between
|
||||
epochs (Pulsar's \texttt{reshare/} direction), the relevant model is
|
||||
HJKY97 mobile adversary: $\mathcal{A}$ can corrupt up to $t-1$
|
||||
parties \textbf{per epoch}, with the corruption set varying across
|
||||
epochs. The adversary may \emph{uncorrupt} a party (forget what it
|
||||
learned) at epoch boundaries.
|
||||
|
||||
Pulsar-M proactive resharing inherits the soundness argument from
|
||||
Pulsar's \texttt{reshare/} (with the constant-time fix from F9 of
|
||||
the Hanzo HIP-0077 red review). The MPTC submission documents the
|
||||
mobile-adversary game explicitly.
|
||||
|
||||
\subsection{Out-of-scope adversary capabilities}
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item Compromise of the cryptographic hash function (SHAKE-256 /
|
||||
cSHAKE-256 / KMAC-256). NIST FIPS 202 + SP 800-185 are taken as
|
||||
building blocks.
|
||||
\item Side-channel attacks on the \emph{physical} hardware running a
|
||||
party (power analysis, EM, fault injection). Mitigation discussed in
|
||||
\S\ref{sec:knownlimits} as future work.
|
||||
\item Compromise of the BIP-32/BIP-39 mnemonic from which
|
||||
device-specific keys are derived. The HD-derivation security
|
||||
argument lives in HIP-0077 \S``Identity''; the Pulsar-M layer
|
||||
assumes parties' input keys are uniformly distributed.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{In-scope security goals}
|
||||
|
||||
\paragraph{Threshold unforgeability (TS-UF).}
|
||||
For any PPT adversary $\mathcal{A}$ controlling up to $t-1$ parties,
|
||||
$\mathcal{A}$ cannot produce a valid Pulsar-M signature $\sigma^*$
|
||||
on any message $\mu^*$ that an honest signing ceremony has not
|
||||
produced.
|
||||
|
||||
\paragraph{Robustness / identifiable abort.}
|
||||
If a corrupted party deviates from the protocol, the honest parties:
|
||||
|
||||
\begin{enumerate}[leftmargin=*, itemsep=0pt]
|
||||
\item Detect the deviation.
|
||||
\item Identify the deviating party.
|
||||
\item Produce signed evidence of the deviation suitable for slashing
|
||||
/ reputation reduction.
|
||||
\end{enumerate}
|
||||
|
||||
\paragraph{Output indistinguishability from FIPS 204.}
|
||||
A Pulsar-M signature $\sigma$ on message $\mu$ against group public
|
||||
key $\mathit{pk}$ is computationally indistinguishable from a
|
||||
FIPS~204 ML-DSA signature on the same $(\mathit{pk}, \mu)$.
|
||||
Specifically: an adversary that can distinguish the two with
|
||||
non-negligible advantage breaks the underlying M-LWE assumption.
|
||||
|
||||
\paragraph{Bias resistance.}
|
||||
The randomness used in each party's contribution (Gaussian samples,
|
||||
challenge polynomials) is statistically indistinguishable from
|
||||
uniform even given the adversary's view of corrupted parties'
|
||||
randomness.
|
||||
|
||||
\paragraph{DKG soundness.}
|
||||
Pedersen DKG over $\Rq^k$ produces a public key $\mathit{pk}$
|
||||
distributed uniformly over the valid M-LWE public-key space, with no
|
||||
party holding more than $1/n$ partial information about the
|
||||
corresponding secret key.
|
||||
|
||||
\subsection{Assumed channels}
|
||||
|
||||
\begin{center}
|
||||
\begin{tabular}{lll}
|
||||
\toprule
|
||||
channel & property & purpose \\
|
||||
\midrule
|
||||
Broadcast & authenticated, eventual-delivery & round transcripts,
|
||||
public coins \\
|
||||
Point-to-point & authenticated, encrypted & private share / blind
|
||||
delivery \\
|
||||
Public bulletin & authenticated, append-only & DKG commitments,
|
||||
reshare records \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
The reference implementation provides these channels via TCP + TLS.
|
||||
Production deployments (e.g.\ Lux consensus + Quasar) bind these to
|
||||
their existing P2P transport.
|
||||
|
||||
\subsection{Trusted parameters}
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item The cyclotomic ring $\Rq = \Zq[X] / (X^{256} + 1)$ and
|
||||
parameters $(q, k, \ell, \eta, \beta, \omega, \ldots)$ exactly as in
|
||||
FIPS~204 ML-DSA-65.
|
||||
\item The hash family: SHAKE-256 (FIPS 202), cSHAKE-256 / KMAC-256 /
|
||||
TupleHash-256 (NIST SP 800-185). Customization tags are pinned in
|
||||
\texttt{spec/pulsar-m.tex}.
|
||||
\item The Gaussian sampler parameters from FIPS~204 \S3.3 / \S4.2.
|
||||
\end{itemize}
|
||||
|
||||
No trusted setup beyond NIST primitives.
|
||||
|
||||
\subsection{Failure modes addressed}
|
||||
|
||||
The MPTC submission documents how Pulsar-M handles each failure
|
||||
mode that broke earlier threshold-lattice schemes:
|
||||
|
||||
\begin{itemize}[leftmargin=*, itemsep=0pt]
|
||||
\item \textbf{Rejection-sampling restart leaking secret information
|
||||
across rounds}: Pulsar's PRNG-key per-round domain separation
|
||||
(CRIT-1 fix from upstream's 2026-05-03 amendment) ports forward.
|
||||
\item \textbf{Constant-time share comparison}:
|
||||
\texttt{dkg2.constTimePolyEqual} pattern ported from upstream
|
||||
Pulsar (\texttt{reshare/commit.go} F9 fix).
|
||||
\item \textbf{Information leaks via logging}: zero stdlib
|
||||
\texttt{log} use in any secret-touching path; all logging via
|
||||
\texttt{luxfi/log} at fields that are explicitly public.
|
||||
\item \textbf{Deterministic quorum selection in resharing leaking
|
||||
adversary positioning}: Pulsar-M uses a beacon-derived per-reshare
|
||||
quorum selection (HIP-0077 \S``reshare quorum'' F10 fix).
|
||||
\item \textbf{Cross-mode hash-suite confusion}: NIST profile is
|
||||
exclusively SHA-3 family; no BLAKE3 in Pulsar-M ever.
|
||||
\end{itemize}
|
||||
Reference in New Issue
Block a user