submission: scaffold NIST MPTC v0.2 submission package mirroring Pulsar template

Adds the NIST MPTC Class N1 + N4 submission package for Corona (R-LWE
threshold signing). Pattern mirrors luxfi/pulsar (M-LWE byte-equal
FIPS 204 path), adapted HONESTLY to Corona's lighter proof tier:

- SUBMISSION.md / NIST-SUBMISSION.md — cover sheet + 1-page exec
  summary. Cite Boschini-Kaviani-Lai-Malavolta-Takahashi-Tibouchi
  ePrint 2024/1113 (IEEE S&P 2025) as the underlying construction.
  Construction-level N1 claim (no FIPS standard target for R-LWE
  threshold — Boschini et al. IS the spec). N4 = (A, bTilde)
  preserved across reshare within a key era.
- SPEC.md — standalone construction specification consolidating
  existing material (papers/lp-073-pulsar/, DESIGN.md). Full
  single-doc spec/corona.tex is roadmap v0.6.0.
- PATENTS.md — royalty-free patent grant + defensive termination.
  Claim scope EXCLUDES the published Boschini et al. construction;
  claims limited to Corona's production lifecycle additions
  (Pedersen DKG over R_q, proactive resharing, activation cert
  circuit-breaker, constant-time Pedersen slot equality, hash-suite
  injection).
- PROOF-CLAIMS.md — HONEST framing. Corona ships NO mechanized
  refinement (no EasyCrypt, no Lean, no Jasmin) — unlike Pulsar.
  Correctness reduces to code review + KAT cross-runtime byte-equality
  + academic construction analysis + per-path constant-time static
  audit. Mechanized refinement is roadmap v0.7.0.
- TRUSTED-COMPUTING-BASE.md — implementation TCB. Structurally
  simpler than Pulsar's; no EC/Lean/Jasmin tools in scope.
- DEPLOYMENT-RUNBOOK.md — operator-facing trust-model disclosure.
- LICENSING.md / CONTRIBUTING.md / SECURITY.md — standard NIST-MPTC
  artifacts.
- docs/mptc/ — submission-package docs subdir (kept separate from
  docs/ Next.js docs site):
  - evaluation.md, ietf-draft-skeleton.md, nist-mptc-category.md,
    patent-claims.md, design-decisions.md, family-architecture.md,
    threat-model.md
- scripts/{build,test,bench,gen_vectors,check-high-assurance,
  cut-submission}.sh — submission gates mirroring Pulsar's
  orchestrator pattern, adapted to Corona's reality (no EC/Lean/
  Jasmin checks because the artifacts do not exist).
- LLM.md + CHANGELOG.md — updated with submission scaffolding
  context and v0.5.0 entry. NO fabricated prior history; CHANGELOG
  v0.5.0 entry covers only the actual submission documentation.

DOES NOT FABRICATE: no CRYPTOGRAPHER-SIGN-OFF (Pulsar has one;
Corona's lighter proof tier does not yet warrant it — roadmap
v0.7.0+v0.8.0). No AXIOM-INVENTORY or FIPS-TRACEABILITY (Corona is
not anchored to a FIPS standard). No proof claims Corona does not
actually have.

Build/test verification: GOWORK=off go build ./... clean; sign/,
primitives/, hash/ unit tests pass; scripts/build.sh + scripts/
check-high-assurance.sh exit 0.
This commit is contained in:
2026-05-18 23:10:13 -07:00
parent 27692894fe
commit fbe2bc5a88
25 changed files with 4496 additions and 29 deletions
+79
View File
@@ -4,6 +4,85 @@ Notable changes to the `corona` module. Pre-release; semantic versioning
applied per PHILOSOPHY.md (patch only — never minor/major without explicit
approval).
## v0.5.0 (planned — NIST MPTC submission package scaffolding)
### Submission documentation added (no code changes)
This revision adds the NIST MPTC Class N1 + N4 submission package
scaffolding. Pattern mirrors `luxfi/pulsar` (the M-LWE byte-equal
FIPS 204 sibling), adapted honestly to Corona's lighter proof tier.
- `SUBMISSION.md` — NIST MPTC cover sheet. Cites Boschini et al. ePrint
2024/1113 (IEEE S&P 2025) as the underlying construction. Declares
construction-level N1 (no FIPS standard target available for R-LWE
threshold) + N4 (`(A, bTilde)` preserved across reshare within key era).
Two-variant honesty disclosure: Pedersen DKG (`dkg2/`) is the production
path; legacy `dkg/` is retained for historical reference only.
- `NIST-SUBMISSION.md` — one-page executive summary.
- `SPEC.md` — standalone construction specification. Pointer to
`papers/lp-073-pulsar/` LaTeX sections + `DESIGN.md` invariants.
Full single-document `spec/corona.tex` is roadmap (v0.6.0).
- `PATENTS.md` — royalty-free patent grant + defensive termination.
Claim scope explicitly EXCLUDES the Boschini et al. published
construction (academic prior art); claims are limited to Corona's
production lifecycle additions.
- `PROOF-CLAIMS.md` — HONEST framing. Corona ships NO mechanized
refinement (no EasyCrypt, no Lean, no Jasmin). Construction-level
claim only; correctness reduces to code review + KAT + Boschini et
al. analysis. Mechanized refinement is roadmap (v0.7.0).
- `TRUSTED-COMPUTING-BASE.md` — implementation TCB. Structurally
simpler than Pulsar's (no EC/Lean/Jasmin tools); higher per-component
trust on Go reference review + KAT cross-runtime byte-equality.
- `DEPLOYMENT-RUNBOOK.md` — operator-facing trust-model disclosure.
- `LICENSING.md` — pointer to LICENSE + Lux three-tier IP strategy.
- `CONTRIBUTING.md`, `SECURITY.md` — standard NIST-MPTC artifacts.
- `docs/evaluation.md` — performance + correctness + KAT + CT evidence.
- `docs/ietf-draft-skeleton.md` — IETF draft skeleton (HONEST: draft).
- `docs/nist-mptc-category.md` — Class N1 + N4 mapping for Corona.
- `docs/patent-claims.md` — attorney-prep claim drafts (FEWER than
Pulsar — only Corona-novel lifecycle additions, not the published
Boschini et al. construction).
- `docs/design-decisions.md`, `docs/family-architecture.md`,
`docs/threat-model.md` — adapted from Pulsar's pattern to Corona's
R-LWE / `R_q` setting.
### Honest gaps documented
This submission EXPLICITLY does NOT include (per `PROOF-CLAIMS.md` §3):
- EasyCrypt theories (`Corona_N1.ec` does not exist).
- Lean ↔ EC algebraic-bridge files.
- Jasmin sources (libjade does not target Corona's parameter set).
- Mechanized refinement proof of any kind.
- dudect-style statistical CT validation harness.
- Full LaTeX `spec/corona.tex` single-document spec (paper sections at
`papers/lp-073-pulsar/` are the current canonical material).
- Parameter-set worksheet with concrete lattice-estimator bounds.
- ACVP/CAVP algorithm validation certificate (no NIST ACVP test vector
set exists for R-LWE threshold).
- FIPS 140-3 module validation (downstream).
- External cryptographic audit (engaged lab) — roadmap v0.8.0.
### CI gates maintained
- `scripts/build.sh` exits 0 on a fresh clone.
- `scripts/test.sh` exits 0 (Go unit + integration + KAT).
- `scripts/regen-kats.sh --verify` exits 0 (cross-runtime byte-equality
with `~/work/luxcpp/crypto/corona/` C++ port).
- `scripts/check-high-assurance.sh` — stub at this revision; runs the
available checks (no EC/Lean/Jasmin to run).
### Tarball cut tooling
- `scripts/cut-submission.sh` — adapted from Pulsar's; produces
`submission-YYYY-MM-DD.tar.gz` from a clean tag on `main`.
## v0.4.1 (current)
Latest production tag at this revision. See git log for the full v0.4.x
history (Corona purge, domain-separation rename PULSAR-* → CORONA-*,
Go 1.26.3 toolchain bump, parallel `VerifyBatch` for N-signature
consensus throughput).
## Unreleased
### Breaking — F22 hash-suite injection into Sign
+116
View File
@@ -0,0 +1,116 @@
# Contributing to Corona
## What we accept
This repository is **both** a production Ring-LWE threshold signature
library for Quasar consensus AND a NIST-MPTC-track submission
package. Until the 2026-Nov-16 package submission, contributions that
align with the MPTC submission are highest priority:
1. **Specification clarity** — text edits that disambiguate `SPEC.md`,
`DESIGN.md`, and the LaTeX paper sections at
`papers/lp-073-pulsar/`.
2. **Reference implementation** — `sign/`, `threshold/`, `dkg2/`,
`reshare/`, `primitives/`, `hash/`. Boring, clear, no assembly,
no clever abstractions. Match the spec section-by-section.
3. **Test vectors** — `cmd/*_oracle*/`. KAT-deterministic regeneration
via `scripts/regen-kats.sh`; cross-runtime byte-equality with the
C++ port at `~/work/luxcpp/crypto/corona/`.
4. **Constant-time analysis** — `CONSTANT-TIME-REVIEW.md`. Show,
don't claim. New entries must cite the relevant Go source line +
the upstream primitive's CT guarantee.
5. **Fuzz harness expansion** — `reshare/fuzz_*_test.go`,
`dkg2/fuzz_round_test.go`, `threshold/fuzz_round_test.go`.
6. **Cryptanalysis of the Boschini et al. construction or Corona's
production lifecycle additions** — open an issue. We track
external review explicitly.
## What we don't accept
Until after the MPTC submission lands:
- New protocol features beyond what the Boschini et al. construction
+ Corona's production lifecycle layers specify.
- Optimized implementations (AVX2, SIMD, hand-rolled assembly) in
the reference. Optimized implementations belong in a separate
build tag and require independent CT audit.
- HSM integration patches in the reference (those belong in a
separate consumer-side adapter library).
- Production-deployment patches in the reference (use the consuming
consensus layer for deployment-specific orchestration).
- BLAKE3 hash-suite expansions — the NIST profile uses cSHAKE256 /
KMAC256 / TupleHash256 exclusively (Corona-SHA3). The legacy
Corona-BLAKE3 suite is retained for cross-port byte checks only;
new BLAKE3 deltas should NOT land.
- Patches that introduce Pulsar (M-LWE) types into Corona (R-LWE).
The two libraries are independent with no shared types; keep
them that way.
These reopen post-submission.
## Process
1. **Open an issue first.** Discuss the change before implementing.
2. **One concern per PR.** Don't bundle spec edits with implementation
changes. The MPTC review process treats them as separate artifacts.
3. **CI must pass.** Build, test, KAT regeneration, KAT cross-runtime
verify, lattice-estimator (when wired) all green before merge.
4. **Sign your commits.** GPG-signed, real name in `Signed-off-by`.
Patent-claim disclosures attach to commits.
## Development setup
```bash
git clone https://github.com/luxfi/corona
cd corona
./scripts/build.sh
./scripts/test.sh
./scripts/gen_vectors.sh
./scripts/regen-kats.sh --verify # cross-runtime byte-equality check
```
LaTeX spec build (paper sections):
```bash
cd papers/lp-073-pulsar/
pdflatex lp-073-pulsar-pedersen-dkg.tex
pdflatex lp-073-pulsar-resharing.tex
```
## Coding standards (Go reference)
- Go 1.26.3+ (per `go.mod`).
- All logging via `github.com/luxfi/log` (consumer-supplied; the
reference itself avoids logging on secret-touching paths).
**No `log.Println`, `log.Fatalf`, `fmt.Printf`** in code that
touches a secret.
- All secret-byte comparison via `crypto/subtle.ConstantTimeCompare`
or the local `constTimePolyEqual` helper in `dkg2/dkg2.go:560`.
- All Gaussian sampling via lattigo's `KeyedPRNG`-backed
`ring.NewGaussianSampler`. Direct `math/rand` is forbidden.
- All hash usage via `hash.HashSuite` injection — never hardcode
cSHAKE256 / KMAC256 / TupleHash256 outside `hash/sp800_185.go`.
Direct `golang.org/x/crypto/sha3` use is restricted to that file
and the legacy `hash/blake3.go` for the cross-port byte-check
suite only.
- All Sign-path primitives take `suite hash.HashSuite` as their
first argument (per F22 closure in `CHANGELOG.md`).
- Errors carry context via `fmt.Errorf("%w", err)` not bare panics.
- Patch-bump only — `v0.4.1` → `v0.4.2`. Minor/major bumps require
explicit approval (per `CLAUDE.md` rules).
## Hash-suite discipline
- Production: `hash.Default()` resolves to `Corona-SHA3`.
- Legacy: `hash.NewCoronaBLAKE3()` for cross-port byte checks ONLY.
- Adding a new suite requires updating `hash/sp800_185.go` with the
customization strings, regenerating ALL KAT vectors, and updating
the spec (`SPEC.md` §13).
## License
By contributing, you agree your contribution is licensed under
Apache-2.0 and grant the patent license described in the Apache 2.0
§3, AND the Corona-specific patent grant in `PATENTS.md` §3.
For NIST MPTC submission: contributions are subject to the
patent-claim disclosures collected in `docs/patent-claims.md`.
+238
View File
@@ -0,0 +1,238 @@
# Deployment Runbook — luxfi/corona
> Operational guidance for deploying Corona (threshold Ring-LWE
> signing + Pedersen DKG + proactive resharing) in production
> validator sets. Discloses the v0.2 trust-model caveats and pins
> the safe operating envelope.
## Audience
- Validator operators bringing up a Corona-enabled Lux Quasar chain
(or any chain consuming `github.com/luxfi/corona`).
- Coordinator-service operators running the witness-aggregator
pattern.
- Security reviewers validating production posture against the
honest framing in `PROOF-CLAIMS.md`.
## Trust-model disclosure (load-bearing)
### The v0.2 reconstruction-aggregator caveat
> **Operators MUST acknowledge this before running v0.2 in production
> on funds-bearing networks.**
Corona's combine procedure operates on Lagrange-aggregated `z_i =
y_i + c·s_i` responses. The aggregator computes
`z = Σ_{i ∈ Q} λ_i^Q · z_i` over `R_q^M`. The aggregator does NOT
reconstruct the master secret `s` in memory at any point during
normal signing — the Lagrange aggregation is over the partial
responses, not the shares themselves.
**However**, two distinct trust-model caveats apply:
1. **DKG bootstrap is a one-time trusted-setup event.** At chain
genesis (or at Reanchor), the foundation MPC ceremony runs
`keyera.Bootstrap` which generates the master secret `s` and
distributes shares. Whoever participates in the Bootstrap MPC
ceremony has, at some point in the ceremony's execution, machinery
that touches `s`. The dealer-side `s` is zeroed in place after
sharing (`keyera/keyera.go:191-198`), but the ceremony must be
conducted under verifiably-public conditions (commit-and-reveal
from genesis validators) with toxic-waste assumptions tracked.
2. **The aggregator process is in the trusted computing base.** An
adversary who fully compromises the aggregator host
(root-equivalent) during a signing session can observe `c` and
`z_i` for all `i ∈ Q`, and can compute `s_Q = Σ λ_i · s_i` if it
sees enough partial-response sets across distinct quorum subsets.
(Note: this is weaker than Pulsar's v0.1 aggregator caveat, where
the aggregator briefly reconstructs the master ML-DSA seed in
memory; Corona's aggregator never reconstructs `s`.)
**Operational mitigations** (all production deployments MUST
satisfy at least items 1–4):
1. **Aggregator host hardening**: dedicated host, no general-purpose
workloads, no shared memory, no /proc access for non-root users,
hugepages disabled (prevents same-page deduplication side-channels).
2. **Memory isolation**: the aggregator process runs with locked
pages (`mlock`), core-dumps disabled (`setrlimit RLIMIT_CORE=0`),
ptrace disabled (`prctl PR_SET_DUMPABLE 0`).
3. **Bootstrap MPC ceremony hardening**: foundation MPC ceremony at
chain genesis uses commit-and-reveal entropy from genesis
validators; dealer state is zeroed in place via
`keyera/keyera.go:Bootstrap`. Ceremony participants are bound by
the foundation's toxic-waste protocol.
4. **Operational scope limits**: aggregator role is a single-purpose
process; no network listener beyond the consensus message bus;
no shell access; no debugger attachment in production.
5. **TEE attestation (recommended)**: aggregator runs inside SGX,
SEV-SNP, or TDX with remote attestation pinned to the
reproducible build of `luxfi/corona v0.4.1`.
6. **Defense-in-depth**: validator-set rotation via Reshare (not
Reanchor) is the routine path; Reanchor (new key era) is a rare
governance event reserved for security-incident response.
### What Corona's combine does NOT do
- Does NOT reconstruct the master secret `s` in aggregator memory
during normal signing.
- Does NOT persist any per-party share to disk during signing.
- Does NOT leak any per-party share to any other process under
normal operation.
- Does NOT survive a process crash with secret share material
present beyond the Go runtime's normal garbage-collection cycle
(best-effort zeroization via `reshare/keyshare.go:EraseShare` is
invoked on activation and reshare-completion paths).
## Pre-deployment checklist
Before bringing up a Corona-enabled validator:
- [ ] Operator-readable acknowledgement of the v0.2 trust caveats
above on file (RACI sign-off).
- [ ] Aggregator host meets items 1–4 above.
- [ ] If running on funds-bearing mainnet: item 5 (TEE attestation)
satisfied OR documented compensating control approved by
security review.
- [ ] `scripts/build.sh` exits 0 against the deployed binary's
source tag (i.e., the binary you are deploying was built from
a commit where the build gates were green).
- [ ] `scripts/test.sh` exits 0 against the deployed tag (KAT +
integration + unit tests green).
- [ ] `scripts/regen-kats.sh --verify` exits 0 (cross-runtime
byte-equality with the C++ port is intact).
- [ ] `CONSTANT-TIME-REVIEW.md` reviewed; all `(b)` entries either
mitigated or accepted with documented compensating control.
- [ ] `PROOF-CLAIMS.md` §3 read and understood — Corona does NOT
ship mechanized refinement; review reduces to code + KAT +
academic construction analysis.
- [ ] `DESIGN.md` §"What is preserved across resharing" understood
— distinguish Refresh (same set, fresh shares) from
ReshareToNewSet (set rotation), distinguish Reshare (preserves
key era) from Reanchor (new key era).
- [ ] Validator-set rotation policy documented (cadence, threshold
changes, complaint-response procedures).
## At-runtime monitoring
The aggregator process should expose:
- A metric for every `threshold.Combine` invocation (counter +
latency-histogram).
- A metric for every Lagrange aggregation step (counter; should
match Combine invocations 1:1).
- A metric for every share zeroize call on the post-activation
path (counter; should match activation completions 1:1).
- A metric for every Pedersen-mismatch complaint event (counter;
should be 0 in honest deployments — spike indicates a malicious
participant).
- A panic / signal handler that invokes `EraseShare` on the current
generation's shares before exit.
Anomalous values (e.g., a spike in complaints without a corresponding
disqualification, or a zeroize counter trailing the activation
counter) should page immediately.
## Resharing operational procedure
Corona's resharing is the routine path for validator-set changes
within a key era. See `DESIGN.md` §"Three layers, one shipping path"
for the algorithmic detail; operational specifics:
1. **Cadence**: every epoch boundary or every validator-set change,
whichever is more frequent. The consensus layer (Quasar)
triggers resharing via the `keyera.Reshare` call.
2. **Round structure**: 3-round shape (commit → private deliveries →
combine + activate). Each round has a timeout configured at the
consensus layer; missed rounds trigger the complaint pipeline.
3. **Complaint handling**: per-pair Pedersen-style verification on
the recipient side (`dkg2.go:VerifyShareAgainstCommits` /
`reshare/commit.go:VerifyShareAgainstCommits`). Failure produces
a signed evidence packet identifying the malicious sender.
Disqualification quorum is configured at the consensus layer.
4. **Activation gate**: after the math completes, the new committee
threshold-signs an activation message under the **unchanged**
`(A, bTilde)`. Only on successful verification does the chain
accept the new epoch. Failure → consensus falls back to the old
committee + retries with a new transcript binding.
5. **Failure modes**:
- Coordinator timeout / unavailable → consensus picks the next
coordinator deterministically.
- Resharing round fails (commit mismatch, bad share) → emit signed
evidence; retry under new transcript binding next epoch.
- Activation cert fails to verify → LSS Rollback to previous
generation; chain stays at previous generation; signing
continues under previous shares.
- Multiple consecutive activation failures → governance reanchor:
new key era, fresh ceremony, new group key.
## Migration paths
### v0.4.x → v0.5.x (submission-package addition)
This revision adds the NIST MPTC submission package documentation
(`SUBMISSION.md`, `NIST-SUBMISSION.md`, `SPEC.md`, `PATENTS.md`,
`PROOF-CLAIMS.md`, `TRUSTED-COMPUTING-BASE.md`, etc.). NO behavior
changes. KAT vectors are byte-identical. Production deployments can
upgrade in place; no validator-set rotation required.
### v0.5.x → v0.6.x (planned)
Planned: single-document `spec/corona.tex` consolidating the LaTeX
spec, parameter-set worksheet with lattice-estimator concrete
bounds, and second parameter set targeting NIST PQ Category 3.
Backward-compatible at the wire level; may add a new parameter-set
identifier.
### v0.6.x → v0.7.x (research, multi-month)
Planned: EasyCrypt theory shell for the construction-level
interchangeability claim; Lean 4 / Mathlib mechanization of the
Lagrange-aggregation identity over `R_q`. NO code changes; pure
proof artifact addition. Backward-compatible.
### v0.7.x → v0.8.x (research + audit)
Planned: dudect-style statistical CT validation harness; external
cryptographic audit (engaged lab). May surface findings requiring
patch-level remediation.
## Reference: cryptographer guidance
Corona does NOT ship a `CRYPTOGRAPHER-SIGN-OFF.md` at this submission
scaffolding revision. (Pulsar has one because Pulsar has an
EasyCrypt + Lean + Jasmin mechanized refinement chain that a
cryptographer signed off on. Corona's lighter proof tier does not
yet warrant analogous formal sign-off.) The roadmap to a Corona
sign-off lands with v0.7.0 (mechanized refinement) and v0.8.0
(external audit).
In the interim, the honest cryptographic posture is:
- **Construction soundness**: inherited from Boschini et al. ePrint
2024/1113 (peer-reviewed academic prior art, IEEE S&P 2025).
- **Implementation soundness**: code review + KAT cross-validation
Go ↔ C++ + fuzz harnesses + static per-path constant-time audit
with zero `(c)` findings.
- **Lifecycle soundness**: production-tested via the consuming Quasar
consensus layer; activation cert circuit-breaker is the
load-bearing safety mechanism.
## Contact
- Operations: `[email protected]`
- Security: `[email protected]`
- Submission package: `[email protected]`
---
**Document metadata**
- Name: `DEPLOYMENT-RUNBOOK.md`
- Version: v0.1 (matches Corona v0.4.1; updated for submission scaffolding)
- Date: 2026-05-18
+10
View File
@@ -0,0 +1,10 @@
# Licensing
This repository is licensed under the **Apache-2.0** (see [LICENSE](LICENSE)). It belongs to the **public** tier of the Lux three-tier IP strategy: anyone may use, fork, or redistribute it, including for commercial purposes, subject to the Apache-2.0 terms.
For the canonical Lux IP and licensing strategy, see:
<https://github.com/luxfi/.github/blob/main/profile/README.md>
For commercial inquiries that go beyond the public tier (e.g. private moat acceleration kernels, Eco-tier patent-protected primitives outside Authorized Networks), contact `[email protected]`.
For patent posture specific to the Corona construction (royalty-free grant to FIPS-compatible / NIST-MPTC-submission implementations + defensive termination), see [PATENTS.md](PATENTS.md).
+63 -29
View File
@@ -1,65 +1,99 @@
# Pulsar -- Agent Knowledge Base
# Corona -- Agent Knowledge Base
**Repository**: github.com/luxfi/pulsar
**Latest Tag**: v0.1.5
**Status**: Production (consensus path); sibling project `luxfi/pulsar-m` is the M-LWE submission to NIST MPTC.
**Repository**: github.com/luxfi/corona
**Latest Tag**: v0.4.1 (next: v0.5.0 — NIST MPTC submission package scaffolding)
**Status**: Production (consensus path); NIST MPTC submission package scaffolding in this revision. Sibling submission `luxfi/pulsar` is the M-LWE byte-equal FIPS 204 path.
## Purpose (one-liner)
Ring-LWE threshold signature library used as the post-quantum threshold
layer in Quasar consensus. Pulsar provides O(1) per-cert proofs after
layer in Quasar consensus. Corona provides O(1) per-cert proofs after
DKG, paired with BLS12-381 + ML-DSA-65 in the QuasarCert.
## Post-E2E-PQ State (current)
This repository is BOTH the production library AND the active NIST MPTC
submission package (Class N1 + N4). The submission tarball is cut from a
tag on `main` via `scripts/cut-submission.sh`; reviewer feedback lands here.
Pulsar is the canonical R-LWE threshold for consensus (Q-Chain). Pulsar-M
(this repo's M-LWE sibling at `luxfi/pulsar-m`) handles ML-DSA threshold
for the identity layer; the two do not overlap in role.
## NIST MPTC submission package (this revision)
### Recent significant commits
| Doc | Purpose |
|-----|---------|
| `SUBMISSION.md` | Cover sheet — cites Boschini et al. 2024/1113, declares construction-level N1 + N4, honest delta vs Pulsar |
| `NIST-SUBMISSION.md` | One-page executive summary |
| `SPEC.md` | Standalone construction specification (companion to `papers/lp-073-pulsar/`) |
| `PROOF-CLAIMS.md` | HONEST framing — NO mechanized refinement; KAT + code review + academic construction analysis |
| `PATENTS.md` | Royalty-free grant + defensive termination |
| `TRUSTED-COMPUTING-BASE.md` | Implementation TCB (Go + lattigo + crypto/subtle); structurally simpler than Pulsar's |
| `DEPLOYMENT-RUNBOOK.md` | Operator-facing trust-model disclosure |
| `LICENSING.md`, `CONTRIBUTING.md`, `SECURITY.md` | Standard NIST-MPTC artifacts |
| `docs/evaluation.md` | Performance + correctness + KAT cross-validation |
| `docs/ietf-draft-skeleton.md` | IETF draft skeleton (HONEST: draft form) |
| `docs/nist-mptc-category.md` | Class N1 + N4 mapping for Corona |
| `docs/patent-claims.md` | Attorney-prep claim drafts (FEWER than Pulsar — only Corona-novel lifecycle additions) |
**HONESTY GUARD**: do not claim Corona has EC / Lean / Jasmin proofs. It does not.
Pulsar does; Corona's R-LWE has no FIPS standard target to refine against. See
`PROOF-CLAIMS.md` §3 for the explicit non-claims list.
## Recent significant commits
| SHA | Tag | Impact |
|-----|-----|--------|
| `4043d76` | v0.1.5 | Bump Go toolchain 1.26.2 → 1.26.3 (govulncheck CVE) |
| `88fdb8a` | v0.1.5 | Bump Go toolchain 1.26.1 → 1.26.2 (govulncheck CVE) |
| `930a628` | v0.1.5 | gofmt -s across cmd/ + reshare/ + dkg2/ + keyera/ + threshold/ |
| `5dee925` | v0.1.5 | Plumb HashSuite through every Sign-path primitive (F22) |
| `0c7680e` | v0.1.2 | LP-107 Phase 4: pulsar consumes luxfi/math/codec |
| `39632ed` | v0.1.2 | Cross-runtime oracles + sign KAT generator |
| `f9113d7` | v0.1.2 | Validate Vector[Poly] frame before lattigo ReadFrom |
| `d5606e9` | v0.1.0 | Lattice threshold kernel + key-era lifecycle + Pulsar-SHA3 + Nebula binding |
| `1726e36` | v0.4.1 | threshold: add parallel VerifyBatch — N-signature throughput for consensus |
| `2d910dc` | v0.4.x | corona: don't mix — QUASAR-PULSAR-* prefixes -> QUASAR-CORONA-* in Corona's table |
| `13e1cd8` | v0.4.x | corona: doc drift cleanup — CHANGELOG references match renamed Go code |
| `a7c3919` | v0.4.x | corona: symmetric domain separation — PULSAR-* tags -> CORONA-* |
| `2b262ef` | v0.4.x | go.mod: bump go directive to 1.26.3 (security advisory) |
| `4d02472` | v0.4.x | corona: final Corona purge — code, docs, KAT-side PRF tag |
| `43e7d88` | v0.4.x | corona/papers: corona2025 cite → boschini2024corona; coronaThreshold → coronaThreshold in TeX |
### Active versions
- Repo: `v0.1.5` (next: `v0.1.6`).
- Repo: `v0.4.1` (next: `v0.5.0` accompanying the NIST submission package scaffolding).
- Pinned by: `luxfi/consensus v1.23.6+` (R-LWE path is consensus-only).
### Canonical params
- Ring degree: 256 (LogN=8).
- M=8, N=7, Dbar=48, Kappa=23.
- Q=0x1000000004A01 (48-bit NTT-friendly prime).
- Hash suite: Pulsar-SHA3 (KMAC over cSHAKE256), `pulsar/hash/sp800_185.go`.
- Hash suite: Corona-SHA3 (KMAC over cSHAKE256), `hash/sp800_185.go`.
### Cross-repo dependencies
- `luxfi/math/codec` → wire codec (LP-107 Phase 4).
- `luxfi/lattice/v7` → lattigo-backed polynomial ops.
- `golang.org/x/crypto/sha3` → cSHAKE256 / KMAC256 / TupleHash256.
- `zeebo/blake3` → LEGACY only (cross-port byte-check).
- Consumed by:
- `luxfi/consensus/protocol/quasar` (R-LWE threshold for QuasarCert).
- Cross-runtime byte-equal port: `~/work/luxcpp/crypto/corona/` (KAT manifest at `scripts/regen-kats.manifest.sha256`).
### Where to look for X
- Threshold kernel: `threshold/`
- DKG (epoch lifecycle): `dkg2/`
- Pulsar-SHA3 / KMAC: `hash/sp800_185.go`
- Threshold kernel: `threshold/` (includes `verify_batch.go`)
- 2-round signing: `sign/`
- Pedersen DKG (lifecycle, replaces broken `dkg/`): `dkg2/`
- Legacy Feldman DKG (broken for public broadcast; reference only): `dkg/`
- Proactive resharing (Refresh + ReshareToNewSet): `reshare/`
- Activation cert circuit-breaker: `reshare/activation.go`
- Corona-SHA3 / KMAC: `hash/sp800_185.go`
- Key-era management: `keyera/`
- Reshare: `reshare/`
- KAT oracles: `cmd/{reshare,dkg2,activation,cross_runtime,sign,corona_oracle_v2}*/`
- Submission scripts: `scripts/{cut-submission,build,test,bench,gen_vectors,check-high-assurance,regen-kats}.sh`
### Open follow-ups
- Variable-size R-LWE certs are still a wire-size cost vs the M-LWE
Pulsar-M path; consensus uses Pulsar for finality-throughput and
Pulsar-M for the identity rollup.
### Open follow-ups (roadmap)
- v0.6.0: single-document `spec/corona.tex` + parameter-set worksheet
- v0.7.0: EasyCrypt theory shell + Lean Lagrange-aggregation mechanization (RESEARCH; multi-month)
- v0.8.0: dudect-style statistical CT harness + external cryptographic audit
- Variable-size R-LWE certs remain a wire-size cost vs Pulsar M-LWE; consensus uses Corona for finality-throughput and Pulsar for the identity rollup.
## Rules
1. Patch-bump only.
1. Patch-bump only (`v0.4.x → v0.4.y`). Minor bumps require explicit approval.
The v0.5.0 bump for submission scaffolding is the documented exception.
2. HashSuite is the only acceptable hash plumbing (F22 closure); never
hardcode SHAKE / KMAC outside `hash/sp800_185.go`.
3. Param changes require a new key-era boundary; never edit in place.
4. NEVER claim mechanized refinement Corona does not have. See `PROOF-CLAIMS.md` §3.
5. NEVER mix Pulsar (M-LWE) types into Corona (R-LWE) — independent libraries with no shared types.
6. NEVER push the legacy `dkg/` package onto a deployment surface — it has known
leakage (Feldman VSS without blinding). Production uses `dkg2/`.
7. Cross-runtime byte-equality with the C++ port (`~/work/luxcpp/crypto/corona/`)
is a CI-enforced invariant via `scripts/regen-kats.sh --verify`.
+193
View File
@@ -0,0 +1,193 @@
# NIST MPTC Submission — Corona (one-page executive summary)
> **Executive summary** of the Corona package for the NIST Multi-Party
> Threshold Cryptography (MPTC) project. The full cover sheet is in
> `SUBMISSION.md`; the package contents map is below.
## Submission metadata
| Field | Value |
|---|---|
| Submission name | **Corona** |
| Submitting organisation | Lux Industries, Inc. |
| Algorithm | Threshold Ring-LWE 2-round signing + Pedersen DKG + proactive resharing |
| MPTC classes | **N1** (construction-level threshold signing) + **N4** (multi-party key generation with public-key preservation across resharing) |
| Underlying construction | Boschini, Kaviani, Lai, Malavolta, Takahashi, Tibouchi. *Practical two-round threshold signatures from learning with errors.* IACR ePrint **2024/1113**, IEEE S&P 2025 |
| Lattice family | Ring-LWE over `R_q = Z_q[X]/(X^N + 1)`, `N = 256`, `q = 0x1000000004A01` (48-bit NTT-friendly prime) |
| Round count | 2 rounds per signature |
| Hash suite | Corona-SHA3 (cSHAKE256 / KMAC256 / TupleHash256, FIPS 202 + SP 800-185) |
| Repository | <https://github.com/luxfi/corona> |
| Submission tag | `submission-2026-11-16` (planned) |
| Latest tagged release | `v0.4.1` (next: `v0.5.0` accompanying the submission package) |
| License | Apache-2.0 (code) + CC-BY-4.0 (PATENTS.md) |
## Headline claim
> Every signature produced by a Corona threshold ceremony (DKG →
> Round-1 → Round-2 → Combine) verifies under the Corona verifier
> (`sign.Verify`) on the same message and group public key `(A, bTilde)`
> as a single-party Corona run would. The group public key is
> preserved bit-identically across proactive resharing events within
> a key era (Class N4 invariant).
**Theorem framing**: construction-level interchangeability. Corona
implements the published Boschini et al. 2-round R-LWE threshold
signature scheme (IACR ePrint 2024/1113) on a fixed parameter set;
Corona's contribution beyond the academic paper is the production
lifecycle (Pedersen DKG over `R_q`, proactive resharing, identifiable
abort, activation certs, KAT-deterministic Corona-SHA3 hash suite).
**Verifier-side reality.** R-LWE threshold signatures have no NIST
standard at submission time. The Boschini et al. construction
verifier is the spec. Corona's `sign.Verify` is the canonical
implementation of that verifier; there is no third-party
FIPS-validated R-LWE verifier to cross-check against. This is the
honest framing distinction from Pulsar (M-LWE / FIPS 204), which
DOES cross-check against BoringSSL FIPS / AWS-LC / OpenSSL 3.0 PQ.
## Package contents (mapped to NIST IR 8214C requirements)
| NIST requirement | Corona artifact |
|---|---|
| Technical specification | `SPEC.md` + `papers/lp-073-pulsar/` LaTeX sections + `DESIGN.md` |
| Open-source reference implementation | `sign/` + `threshold/` + `dkg2/` + `reshare/` + `primitives/` + `hash/` (Apache-2.0) |
| Experimental evaluation report | `docs/evaluation.md` |
| Test vectors | `cmd/{reshare,dkg2,activation,cross_runtime}_oracle*/`, manifest at `scripts/regen-kats.manifest.sha256` |
| Security analysis | `SPEC.md` §15 + Boschini et al. ePrint 2024/1113 §§3–4 |
| Patent / IP statement | `PATENTS.md` (royalty-free grant) + `docs/patent-claims.md` (attorney prep) |
| Known limitations | `SUBMISSION.md` §"Does NOT claim" + `DESIGN.md` §"What this isn't" |
| Contact / maintainers | `SUBMISSION.md` §Contact |
## What makes this submission different
1. **Production-hardened R-LWE threshold** — beyond the Boschini et al.
academic construction, Corona adds Pedersen DKG over `R_q`
(`dkg2/`), proactive resharing with two distinct primitives
(`Refresh` for same-set; `ReshareToNewSet` for set rotation),
identifiable-abort evidence pipeline, and activation certificates
(the circuit-breaker that gates new-epoch acceptance).
2. **KAT-deterministic Corona-SHA3 profile** — every Sign-path
primitive takes a `hash.HashSuite` argument. Production deployments
use cSHAKE256 / KMAC256 / TupleHash256 per FIPS 202 + SP 800-185.
The legacy BLAKE3 suite remains available for cross-port byte
checks.
3. **Cross-runtime byte-equality** — Go reference at `sign/` +
`threshold/`; C++ port at `~/work/luxcpp/crypto/corona/`. KAT
manifest (`scripts/regen-kats.manifest.sha256`) enforces
byte-equal round-trip via `scripts/regen-kats.sh --verify`.
4. **Constant-time audit complete** — `CONSTANT-TIME-REVIEW.md`
shows zero `(c)` (must-fix) entries. Two `(b)` entries are
documented with mitigations (one closed in `dkg2/`; one in
lens-specific secp256k1 paths not on the Corona threshold path).
5. **Reproducibility-first** — `scripts/build.sh`, `scripts/test.sh`,
`scripts/gen_vectors.sh` are deterministic. KAT regeneration is
byte-equal across runs; CI enforces drift = build bug.
6. **Honest gap disclosure** — Corona does NOT ship a mechanized
refinement proof. See `PROOF-CLAIMS.md` for the narrow claim and
the roadmap. The honest framing: production-hardened
implementation of a published academic construction, not
machine-checked refinement of a NIST standard.
## Trust footprint (one-screen summary)
After Corona v0.4.1:
| Category | Count / Status |
|---|---|
| EasyCrypt files | **0** (no mechanized refinement — see `PROOF-CLAIMS.md`) |
| Lean ↔ EC bridge files | **0** |
| Jasmin source files | **0** (libjade does not target Corona parameter set) |
| Go reference test coverage | sign + threshold + dkg2 + reshare + primitives + hash — 45+ tests in `reshare/`, 10+ in `dkg2/`, comprehensive sign roundtrip + threshold tests |
| Fuzz harnesses | `reshare/fuzz_*_test.go`, `dkg2/fuzz_round_test.go`, `threshold/fuzz_round_test.go` |
| KAT cross-runtime byte-equality | enforced by `scripts/regen-kats.sh` + `regen-kats.manifest.sha256` |
| Constant-time audit | `CONSTANT-TIME-REVIEW.md` — 0 `(c)`, 2 `(b)` mitigated |
The trust base for Corona at submission time reduces to:
- The Boschini et al. ePrint 2024/1113 construction analysis
(academic prior art).
- The Go reference implementation correctness (reviewed by code +
KATs + fuzz).
- The `luxfi/lattice/v7` (lattigo fork) NTT / Montgomery / Gaussian
sampler primitives — documented constant-time per upstream.
- The `crypto/subtle` standard library constant-time helpers.
- The Go toolchain.
## What this submission does NOT claim
| Out-of-scope claim | Why |
|---|---|
| Byte-equality with FIPS 204 ML-DSA | That is Pulsar's claim. Corona is R-LWE; ML-DSA is M-LWE. |
| Mechanized refinement proof | Multi-month research project. No FIPS standard target exists for R-LWE threshold. See `PROOF-CLAIMS.md`. |
| Post-quantum hardness of R-LWE | Assumed from Lyubashevsky-Peikert-Regev (2010) and follow-up analysis. |
| ACVP/CAVP algorithm validation certificate | Not applicable — NIST has no ACVP test vector set for R-LWE threshold. |
| FIPS 140-3 module validation | Downstream — applies to packaged modules. |
| Asynchronous identifiable abort | Synchronous only. |
| 1-round signing | Construction is 2-round by design (Boschini et al.). |
| DKG without external randomness beacon | Honest-majority unbiased; production binds a beacon at the consensus layer. |
## Reproducibility commitment
```bash
git clone --branch submission-2026-11-16 https://github.com/luxfi/corona
cd corona
scripts/build.sh # builds reference impl
scripts/test.sh # runs unit + KAT + integration tests
scripts/bench.sh # performance (expect within 5% of REPORT.md)
scripts/gen_vectors.sh # regenerate KAT vectors deterministically
```
Drift between submission tarball and reproduced output is a build
bug — please file at the GitHub issues link above. NIST reviewers
should obtain byte-identical artifacts on reproduction.
## Patent / IP posture (TL;DR)
- **Code**: Apache-2.0.
- **Patents**: Royalty-free grant to any implementation of the
Corona construction released under Apache-2.0 or compatible OSI
license, OR any NIST MPTC/PQC/ACVP submission/validation/interoperability test.
- **Defensive termination**: license terminates against any party
asserting patents against Corona, the underlying Boschini et al.
construction, FIPS 204 ML-DSA, or any other NIST-standardized PQ
signature scheme.
- **Full text**: `PATENTS.md` §3.
## Contact
| Purpose | Contact |
|---|---|
| Submission coordination | `[email protected]` |
| Patent / IP inquiries | `[email protected]` |
| Security disclosure | See `SECURITY.md` |
| Public discussion | <https://github.com/luxfi/corona/discussions> |
| Primary maintainer | `[email protected]` (Lux Industries, Inc.) |
## Roadmap (v0.5 and beyond)
| Milestone | Target |
|---|---|
| Submission package scaffolding (this revision) | v0.5.0 |
| Single-document `spec/corona.tex` consolidating `SPEC.md` + paper sections | v0.6.0 |
| EasyCrypt theory shell for the construction-level interchangeability claim | v0.7.0 (research) |
| Lean 4 / Mathlib mechanization of the Lagrange-aggregation identity over `R_q` | v0.7.0 (research) |
| External cryptographic audit (engaged lab) | v0.8.0 |
| `dudect`-style statistical CT validation harness | v0.8.0 |
| Production deployment runbook hardening | continuous |
The roadmap is published at `SUBMISSION.md` "What this submission
does NOT claim" + tracked at the GitHub issues link above.
---
**Document metadata**
- Name: `NIST-SUBMISSION.md`
- Version: v0.1 (initial submission-package scaffolding)
- Date: 2026-05-18
- Submission package version: Corona v0.2 (tagged `submission-2026-11-16` on cut date)
+340
View File
@@ -0,0 +1,340 @@
# PATENTS — Corona Threshold Ring-LWE Signature
> **Statement of Intellectual Property and Royalty-Free Patent Grant**
> for the Corona threshold-signing construction submitted to the NIST
> Multi-Party Threshold Cryptography (MPTC) project.
## TL;DR
Lux Industries, Inc. ("Lux") grants a **worldwide, royalty-free,
non-exclusive, irrevocable patent license** for any implementation of
the Corona threshold signature construction that is either (a)
licensed under Apache-2.0 or a compatible OSI-approved license, OR
(b) is part of a NIST MPTC / PQC / ACVP submission, validation, or
interoperability test.
The grant terminates automatically and prospectively against any
party that asserts a patent claim against Corona, the underlying
Boschini et al. R-LWE construction, FIPS 204 ML-DSA, or any other
NIST-standardized post-quantum signature scheme. Defensive
termination mirrors Apache-2.0 §3.
The full text of the grant is in **§3 Patent Grant** below.
## §1 Scope of the IP statement
This document covers patent rights and patent posture for:
- The **Corona threshold-signing construction** as implemented at
`github.com/luxfi/corona` (DKG → Round-1 → Round-2 → Combine →
Reshare).
- The **reference implementation** in `sign/`, `threshold/`,
`dkg2/`, `reshare/`, `primitives/`, and `hash/`.
- The **test-vector format** in `cmd/*_oracle*/` and the
cross-runtime byte-equality manifest at
`scripts/regen-kats.manifest.sha256`.
It does NOT cover, and explicitly DISCLAIMS, the following prior art:
| Component | Status |
|---|---|
| The base 2-round Ring-LWE threshold construction (Boschini, Kaviani, Lai, Malavolta, Takahashi, Tibouchi. *Practical two-round threshold signatures from learning with errors.* IACR ePrint 2024/1113, IEEE S&P 2025) | Academic prior art. Corona implements this construction unchanged in its math. Lux asserts no patents on the published Boschini et al. algorithm itself. |
| Ring-LWE (R-LWE) primitive (Lyubashevsky, Peikert, Regev. *On ideal lattices and learning with errors over rings.* EUROCRYPT 2010) | Academic / public domain. |
| Shamir secret sharing (1979) | Public domain. |
| Lagrange polynomial interpolation | Classical mathematics. |
| Pedersen verifiable secret sharing (Pedersen 1991) | Academic prior art. Corona's `dkg2/` adapts the Pedersen VSS construction to `R_q^M` lattice commits; the adaptation pattern is generic. |
| HJKY97 proactive secret sharing (Herzberg, Jakobsson, Jarecki, Krawczyk, Yung. CRYPTO 1995/1997) | Academic prior art. Corona's `Refresh` primitive follows the HJKY97 same-set refresh shape. |
| Desmedt-Jajodia 1997 / Wong-Wang-Wing 2002 redistribution to new access structures | Academic prior art. Corona's `ReshareToNewSet` follows this VSR composition. |
| SHAKE128 / SHAKE256 / Keccak / cSHAKE / KMAC / TupleHash (FIPS 202 + SP 800-185) | Public domain — NIST standards. |
| FROST threshold-signing baseline (academic literature) | Published in IACR ePrint; no novelty asserted here against the published construction. |
| LSS (Linear Secret Sharing) framework (Seesahai 2025) | Academic prior art. Corona's lifecycle interfaces (Generation, RollbackFrom, Bootstrap Dealer / Signature Coordinator role separation) follow the LSS pattern. |
## §2 What Lux considers patentable (high level)
Subject to attorney review (see `docs/patent-claims.md` for the
detailed numbered claim drafts), Lux considers the following Corona
contributions to be candidates for patent protection. Note: this
list is intentionally narrower than Pulsar's because the underlying
2-round R-LWE construction is published academic prior art (Boschini
et al. 2024/1113). Corona's novel contributions are the production
lifecycle layers atop the published construction.
### §2.1 Pedersen DKG over `R_q` with hiding blinds
The specific adaptation of Pedersen verifiable secret sharing to the
`R_q^M` polynomial-vector setting, where coefficient commitments
take the form `C^(k) = A·NTT(s^(k)) + B·NTT(r^(k))` for per-
coefficient hiding blind `r^(k)`. The adaptation includes:
- Domain-separated generator derivation from `sid_dkg` via cSHAKE256
(`CORONA-DKG-v1` customization string).
- Per-pair authenticated KEX (ML-KEM-768 hybrid recommended).
- Complaint round with publicly-verifiable evidence.
- Qualified-set selection with deterministic ordering.
Detailed in `papers/lp-073-pulsar/lp-073-pulsar-pedersen-dkg.tex`;
implementation in `dkg2/`.
### §2.2 Class N4 reshare with public-key preservation over `R_q`
Proactive secret-sharing protocol that rotates shares across
committee changes while preserving the group public key `(A, bTilde)`
in the R-LWE setting. Permits long-lived public identity with
rotating custodians. Two distinct primitives:
- `Refresh` — same committee, fresh shares (HJKY97 lineage adapted
to R-LWE).
- `ReshareToNewSet` — set rotation with `t_old → t_new` threshold
changes (Desmedt-Jajodia / Wong-Wang-Wing lineage adapted to
R-LWE).
Detailed in `papers/lp-073-pulsar/lp-073-pulsar-resharing.tex`;
implementation in `reshare/`.
### §2.3 Activation certificate as circuit-breaker
The specific protocol step where, after a Reshare math completes,
the new committee threshold-signs an activation message under the
**unchanged** group public key using their freshly-derived shares;
only on successful verification does the chain mark the new epoch
live. The activation message canonical bytes include
`key_era_id || old_epoch || new_epoch || old_validator_set_hash ||
new_validator_set_hash || reshare_transcript_hash` with
domain-separated prefix `QUASAR-CORONA-ACTIVATE-v1`. Detailed in
`DESIGN.md` §"Activation cert (the circuit-breaker)"; implementation
in `reshare/activation.go`.
### §2.4 Constant-time Pedersen slot equality with `eq &=` accumulation
The specific implementation pattern in `dkg2/dkg2.go:VerifyShareAgainstCommits`
where Pedersen identity verification iterates over all `M` slots,
accumulating `eq &= subtle.ConstantTimeCompare(lhs_bytes, rhs_bytes)`
with NO early return on per-slot mismatch — preventing the recipient's
response-time variation from leaking which slot first diverged.
Specifically addresses Findings 5/6 of the upstream
RED-DKG-REVIEW.md; the same idiom can apply to any `(A, B)`-based
Pedersen commit scheme over a polynomial ring.
### §2.5 Hash-suite injection through every Sign-path primitive
The specific architectural pattern where every Sign-path primitive
(`PRNGKey`, `PRNGKeyForRound`, `GenerateMAC`, `GaussianHash`, `PRF`,
`Hash`, `LowNormHash`) takes a `hash.HashSuite` as its first argument
with `nil` resolving to the production default (`Corona-SHA3` via
KMAC over cSHAKE256), enabling per-deployment hash-profile selection
without code changes. Detailed in `CHANGELOG.md` "F22 hash-suite
injection into Sign"; implementation in `primitives/hash.go` +
`hash/sp800_185.go`.
## §3 Patent grant (the load-bearing text)
> **CORONA PATENT GRANT — v1.0**
>
> Lux Industries, Inc. ("Lux"), a Delaware corporation, hereby grants
> to any person or entity ("You") a **worldwide, royalty-free,
> non-exclusive, no-charge, fully-paid-up, irrevocable** (except as
> stated in §3.2 below) patent license to make, have made, use, offer
> to sell, sell, import, and otherwise transfer any implementation of
> the Corona threshold-signing construction described in `SPEC.md`
> and `DESIGN.md` (the "Construction"), provided that such
> implementation:
>
> (a) Implements the Construction (signing, DKG, or proactive
> resharing) in a manner consistent with the algorithmic
> specification (the "Construction-Conformance Condition"); AND
>
> (b) Is licensed to the public under (i) the Apache License, Version
> 2.0, or (ii) any other Open-Source-Initiative-approved license
> compatible with Apache-2.0, OR (c) is part of a submission to,
> validation under, or interoperability test for the NIST
> Multi-Party Threshold Cryptography (MPTC) project, the NIST
> Post-Quantum Cryptography (PQC) standardization process, or any
> successor program administered by NIST.
>
> The license granted in this §3 covers all "Necessary Claims" owned
> or controllable by Lux that would, in absence of this license,
> necessarily be infringed by an implementation meeting (a) and (b).
> "Necessary Claims" means claims of any patent or patent
> application that are essential for compliance with the Corona
> specification, that Lux has the right at the time of execution to
> grant a license under.
>
> ### §3.1 Documentation and reference-implementation grant
>
> The Corona specification (`SPEC.md`, `DESIGN.md`,
> `papers/lp-073-pulsar/`), the reference implementation (`sign/`,
> `threshold/`, `dkg2/`, `reshare/`, `primitives/`, `hash/`), and the
> test vectors (under `cmd/*_oracle*/` and the cross-runtime manifest)
> are released under the Apache License, Version 2.0. The patent
> grant in this document operates in addition to (not in lieu of) the
> patent provisions in the Apache-2.0 license.
>
> ### §3.2 Defensive termination
>
> The patent license granted in this §3 terminates automatically and
> prospectively, without notice, with respect to any party (the
> "Asserting Party") if the Asserting Party initiates patent
> litigation (including a cross-claim or counter-claim in a lawsuit)
> alleging that:
>
> (i) The Corona construction; or
> (ii) The underlying Boschini-Kaviani-Lai-Malavolta-Takahashi-Tibouchi
> 2-round R-LWE threshold signature construction (IACR ePrint
> 2024/1113); or
> (iii) FIPS 204 ML-DSA, or any other NIST-standardized post-quantum
> signature scheme; or
> (iv) Any implementation of (i), (ii), or (iii) — including without
> limitation the reference implementation in this repository,
> independent third-party implementations, NIST ACVP/CAVP
> reference vectors, or any FIPS 140-3 validated module
> containing such an implementation,
>
> infringes any patent owned or controllable by the Asserting Party.
> Termination is prospective only; it does not undo the validity of
> any implementation distributed prior to the date the Asserting
> Party initiated the litigation.
>
> Defensive termination mirrors the patent-termination clause of the
> Apache License, Version 2.0, §3, generalized to also cover the
> underlying Boschini et al. construction, FIPS 204 ML-DSA, and
> successor NIST-standardized post-quantum signature schemes. The
> purpose is to deter patent assertion against the broader post-
> quantum signature ecosystem, not only against Corona itself.
>
> ### §3.3 No trademark license
>
> This grant does not authorize the use of Lux's trademarks
> (including "Corona", "Pulsar", "Quasar", "Lux", "Lux Industries",
> and their respective logos) except as required for reasonable and
> customary use in describing the origin of the Construction and
> reproducing the content of any NOTICE file.
>
> ### §3.4 Disclaimer
>
> THE CONSTRUCTION AND ALL ASSOCIATED MATERIALS ARE PROVIDED ON AN
> "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED. Lux shall not be liable for any damages
> resulting from the use of the patent license granted in this §3.
## §4 Filing strategy (informational)
This section is for transparency; it does not modify the grant
in §3.
Lux intends to pursue patent protection on the Corona production-
lifecycle additions as follows:
1. **US provisional application** within 12 months of public
disclosure (the NIST MPTC submission counts as public disclosure
for §102 purposes; filing before submission preserves priority).
2. **PCT international application** within 12 months of the
provisional, designating jurisdictions where R-LWE deployment is
anticipated (EU, JP, CN, KR, IN, AU, CA, UK, BR).
3. **EPO and major-jurisdiction national-phase entries** at the PCT
30-month deadline, prioritized by anticipated deployment markets.
4. **Continuation / divisional applications** to cover incremental
refinements (e.g., the constant-time `eq &=` Pedersen slot-equality
pattern, the activation-cert circuit-breaker, future hash-suite
profile additions).
The royalty-free grant in §3 applies to ALL such filings, present
and future, that are owned or controllable by Lux.
## §5 Why the grant is structured this way
A few notes for reviewers who might ask "why this language and not
plain public-domain dedication":
### §5.1 Defensive patent ownership protects the ecosystem
Without Lux holding the patents on the Corona production-lifecycle
additions, a third party could observe the public NIST submission,
file blocking patents on (e.g.) the activation-cert circuit-breaker
shape, and assert them against open-source implementations. Lux
holding the patents (with a royalty-free grant) removes that attack
surface.
This is the same logic that protects FRAND ecosystems and that
underlies Apache-2.0's patent grant + retaliation clause.
### §5.2 Compatibility with NIST MPTC submission terms
The NIST Multi-Party Threshold Cryptography project's submission
guidelines require submitters to provide a patent statement
specifying the IP terms under which the submitted construction may
be used. The grant in §3 satisfies that requirement and goes beyond
NIST's baseline by extending defensive termination to the underlying
Boschini et al. construction (not just Corona's production
lifecycle additions) and to all NIST-standardized post-quantum
signature schemes.
### §5.3 Compatibility with the published Boschini et al. construction
The underlying 2-round R-LWE threshold protocol is published in the
academic literature (IACR ePrint 2024/1113, IEEE S&P 2025). Lux
asserts no patents on the published academic construction itself;
Corona's claims are limited to the production-lifecycle additions.
Any third-party implementation of the Boschini et al. construction
is free of Corona patent assertions whether or not it adopts
Corona's lifecycle layers.
### §5.4 Defensive termination for the broader PQ ecosystem
Extending defensive termination to the underlying Boschini et al.
construction AND to FIPS 204 ML-DSA (and successors) — not just
Corona itself — converts Lux's patent portfolio into a small
deterrent against PQ-signature patent trolls. It costs Lux nothing
(Lux does not intend to assert offensively) and benefits the
ecosystem.
## §6 What this document does NOT do
- It does not assign any Lux patent rights to NIST, IETF, or any
third party. Lux retains ownership; the grant in §3 is a license.
- It does not commit Lux to maintain or prosecute any specific
patent application. Lux may abandon applications for business
reasons; the grant in §3 covers issued patents in proportion to
what is actually granted.
- It does not waive Lux's right to update the grant text (subject
to §6.1 below).
- It does not modify the Apache-2.0 license covering the
reference implementation, specification, and vectors.
- It does not claim patent rights on the Boschini et al. published
construction (academic prior art).
### §6.1 Modifications to this grant
Lux may issue future versions of this PATENTS document with
clarifications or extensions of the grant. Future versions will
apply to implementations published under the future version's
identifier. **The grant in §3 of this v1.0 document is
irrevocable for implementations relying on it**, subject only to
the defensive-termination clause in §3.2.
## §7 Contact
| Purpose | Contact |
|---|---|
| Patent / IP inquiries | `[email protected]` |
| Licensing for non-conforming implementations | `[email protected]` |
| NIST submission coordination | `[email protected]` |
| Security disclosure | See `SECURITY.md` |
For patent-claim drafting (the document an attorney would work
from), see `docs/patent-claims.md`.
---
**Document metadata**
- Document name: `PATENTS.md`
- Document version: v1.0
- Document date: 2026-05-18
- Construction version: Corona v0.2 (NIST MPTC submission package scaffolding)
- Construction repository: <https://github.com/luxfi/corona>
- License of this document: Creative Commons CC-BY-4.0 (so it
can be freely reproduced in NIST submission packages and audit
reports without modification).
+238
View File
@@ -0,0 +1,238 @@
# PROOF-CLAIMS — Corona (HONEST framing)
> **What this submission proves, and — critically — what it does NOT.**
> Companion to `TRUSTED-COMPUTING-BASE.md` (TCB) and `SUBMISSION.md`
> (cover sheet).
>
> Read this before reading the Corona code. The framing matters as
> much as the implementation.
## §1 The narrow claim Corona makes at this submission
The strongest precise statement supported by Corona v0.4.1:
> **Construction-level interchangeability (Class N1).** Every
> signature byte string produced by the Corona threshold combine
> procedure (`threshold.Combine` / `sign.LocalSign` aggregation flow)
> on inputs `(group_pk = (A, bTilde), m, ctx, quorum, shares)`
> satisfying the protocol's well-formedness invariants verifies under
> the Corona reference verifier `sign.Verify(group_pk, m, σ)` with
> outcome `OK`.
> **Public-key preservation across resharing (Class N4).** Every
> Corona Refresh or ReshareToNewSet ceremony on input `(group_pk =
> (A, bTilde), old_shares, old_committee, new_committee)` satisfying
> the protocol's honest-majority assumption produces `new_shares`
> such that any subsequent threshold signing under those new shares
> verifies under the **byte-identical unchanged** `group_pk`.
**Formal-statement status**: these are stated in prose, validated by
test, and inherited from the Boschini et al. ePrint 2024/1113 §3
analysis for the underlying construction. They are **NOT mechanized**
in EasyCrypt, Lean, Jasmin, or any other proof assistant at this
submission. See §3 below for the explicit non-claims list.
## §2 What IS provided
| Aspect | Status | Source |
|---|---|---|
| Implementation matches the Boschini et al. ePrint 2024/1113 construction | ✓ by code review + KAT cross-validation | `sign/`, `threshold/`, `primitives/` |
| Class N1 (construction-level output verifies under same verifier) | ✓ by test (no mechanized refinement) | `sign/sign_test.go`, `sign/sign_roundtrip_test.go`, `threshold/threshold_test.go` |
| Class N4 (reshare preserves `(A, bTilde)`) | ✓ by test (45+ tests in `reshare/`, integration tests assert byte-equal `(A, bTilde)` post-reshare) | `reshare/full_integration_test.go`, `reshare/refresh_test.go`, `reshare/reshare_test.go` |
| Constant-time on threshold + dkg2 verification paths | ✓ by per-path static audit | `CONSTANT-TIME-REVIEW.md` |
| KAT cross-runtime byte-equality (Go ↔ C++ luxcpp port) | ✓ by manifest enforcement | `scripts/regen-kats.sh --verify` + `scripts/regen-kats.manifest.sha256` |
| Fuzz coverage on round-based protocols | ✓ harnesses wired (operational fuzz budgets are deployment-level) | `reshare/fuzz_*_test.go`, `dkg2/fuzz_round_test.go`, `threshold/fuzz_round_test.go` |
| Hash-suite injection for Corona-SHA3 production profile | ✓ by code (F22 closure) | `hash/sp800_185.go`, `primitives/hash.go` |
| Identifiable-abort evidence | ✓ by test | `reshare/complaint_test.go`, `dkg2/complaint.go` |
| Activation cert as circuit-breaker | ✓ by test (verifies under unchanged GroupKey) | `reshare/activation_test.go` |
## §3 What is NOT proved (HONEST)
This section is the load-bearing honesty disclosure. Read it.
### §3.1 NOT proved: mechanized refinement against any spec
Corona ships **no EasyCrypt theories, no Lean theorems, no Jasmin
sources**. Pulsar (the M-LWE sibling at `~/work/lux/pulsar/`) ships
13/13 EasyCrypt files compiling clean with 0/0 admits, 5/5 Lean ↔ EC
bridges, and 3/3 jasmin-ct blocking gates on the threshold layer.
**Corona does NOT.**
**Why**: R-LWE threshold signing has no NIST standard target. The
Boschini et al. ePrint 2024/1113 construction IS the spec. Mechanizing
the construction itself (without a separately-specified refinement
target) is a multi-month research project. Pulsar can refine against
FIPS 204; Corona has no analogous target.
**What this means in practice**: a NIST reviewer should NOT expect
to find a `Corona_N1.ec` file with a `corona_n1_byte_equality_extracted`
lemma analogous to Pulsar's. The trust base for Corona's correctness
reduces to:
- The Boschini et al. ePrint 2024/1113 academic analysis.
- The Go reference implementation review.
- The KAT cross-validation (Go ↔ C++ byte-equality).
- The constant-time static audit in `CONSTANT-TIME-REVIEW.md`.
- The fuzz harness coverage (operational at submission scaffolding;
submission-grade budgets are roadmap).
### §3.2 NOT proved: lattice-hardness of R-LWE
This submission says nothing about the post-quantum hardness of
Ring-LWE itself. R-LWE security rests on Lyubashevsky-Peikert-Regev
(2010) and follow-up cryptanalytic analysis. The parameter set
(`N = 256`, `q = 0x1000000004A01`, 48-bit prime) was chosen to
provide ≥ 128 bits of post-quantum security per lattice-estimator
methodology — but Corona ships no parameter-set worksheet at this
revision; that is roadmap item v0.6.0.
**The defensible PQ-safety claim**:
> Corona implements a published academic R-LWE threshold signature
> construction (Boschini et al. ePrint 2024/1113) on a parameter
> set chosen to provide ≥ 128 bits of post-quantum security against
> known R-LWE attacks per the lattice-estimator methodology of
> Albrecht-Player-Scott. The construction's EUF-CMA reduction is in
> the cited paper.
**NOT defensible**:
> Corona is proved post-quantum secure.
### §3.3 NOT proved: byte-equality with FIPS 204 ML-DSA
Corona signatures are NOT byte-equal to FIPS 204 ML-DSA signatures.
The two constructions use different lattice families (Corona is
R-LWE; ML-DSA is M-LWE), different ring degrees, different
parameter sets. Any reviewer expecting FIPS 204 byte-equality
should look at the Pulsar sibling at `~/work/lux/pulsar/`.
### §3.4 NOT proved: statistical constant-time validation (dudect)
`CONSTANT-TIME-REVIEW.md` documents a per-path static audit with
zero `(c)` (must-fix) findings. **It does NOT include statistical
validation via dudect-style timing measurements.** A dudect-style
harness is roadmap item v0.8.0; at submission scaffolding time the
constant-time evidence is the static audit + the upstream lattigo
constant-time claims.
### §3.5 NOT proved: implementation-side covert-channel safety
The static constant-time audit does NOT address:
- Memory-access leakage (cache-timing side channels)
- Power side-channels
- EM side-channels
- Fault attacks
- Microarchitectural leakage (Spectre / Meltdown class)
- Statistical timing under realistic deployment conditions
Production deployments MUST follow the hardening checklist in
`DEPLOYMENT-RUNBOOK.md` (mlock pinning, core-dump disable, ptrace
disable, dedicated host, etc.).
### §3.6 NOT proved: protocol-level adversarial robustness
The construction-level claim in §1 is **honest-quorum correctness**.
It says: "when all parties follow the protocol, the output verifies
and resharing preserves the group key." It does NOT prove:
- **Unforgeability** under adaptive corruption — inherited (with
caveats) from Boschini et al. §3; no Corona-specific mechanization.
- **Identifiable abort** under network partition — synchronous network
assumptions hold; async abort is out of scope.
- **Robust completion** under `f < t/2` Byzantine parties.
- **DKG soundness** under adversarial dealer — Pedersen DKG (`dkg2/`)
provides hiding and binding under standard assumptions; full
reduction is in the LP-073 paper but not mechanized here.
### §3.7 NOT proved: external Lean theorems or EC bridges
Corona has NO Lean-bridged algebraic axioms (unlike Pulsar, which
has 5: `lagrange_inverse_eval`, `threshold_partial_response_identity`,
`add_share_zeroR`, `reconstruct_linear`, `shamir_correct`). The
Lagrange-aggregation identity over `R_q` that Corona uses in
combine is implemented by inspection of the Boschini et al. paper;
mechanizing it (either porting Mathlib's polynomial-Lagrange to EC
or building a Lean ↔ EC bridge analogous to Pulsar's
`proofs/lean-easycrypt-bridge.md`) is roadmap item v0.7.0.
## §4 Refinement chain (what's connected to what)
```
Go implementation (sign/, threshold/, dkg2/, reshare/, primitives/, hash/)
implements (by code review + KAT)
Boschini et al. ePrint 2024/1113 §3 algorithmic spec
+ Corona production-lifecycle additions in SPEC.md §§6, 9, 10, 13
conforms to (by inspection)
DESIGN.md invariants ("what is preserved across resharing")
```
Each "implements" / "conforms" relation is by **inspection and
test**, NOT machine-checked. Compare to Pulsar's refinement chain
(machine-checked at every step via EasyCrypt 13/13 + Lean bridges
5/5 + Jasmin-CT 3/3).
## §5 What an auditor verifying this submission should do
1. **Read** the `SUBMISSION.md` cover sheet for context.
2. **Read** this document (`PROOF-CLAIMS.md`) for what's proved vs not.
3. **Read** `TRUSTED-COMPUTING-BASE.md` for the implementation TCB.
4. **Read** `CONSTANT-TIME-REVIEW.md` for the per-path CT audit.
5. **Read** Boschini et al. ePrint 2024/1113 for the underlying
construction analysis (academic prior art).
6. **Run** `scripts/test.sh` — expect Go unit + integration + KAT
tests all green.
7. **Run** `scripts/gen_vectors.sh && scripts/regen-kats.sh --verify`
— expect byte-equal KAT manifest agreement.
8. **Read** the Go reference implementation: `sign/sign.go`,
`threshold/threshold.go`, `dkg2/dkg2.go`, `reshare/reshare.go`,
`reshare/activation.go`, `primitives/hash.go`, `hash/sp800_185.go`.
9. **Run** `scripts/bench.sh` — expect performance numbers within
`docs/evaluation.md` published bounds.
## §6 The honest one-paragraph version
> Corona's submission package establishes that the Go reference
> implementation faithfully implements the Boschini, Kaviani, Lai,
> Malavolta, Takahashi, and Tibouchi 2-round R-LWE threshold
> signature construction (IACR ePrint 2024/1113, IEEE S&P 2025) on a
> fixed parameter set, plus production lifecycle additions (Pedersen
> DKG over `R_q`, proactive resharing with Refresh + ReshareToNewSet
> primitives, identifiable abort, activation certs as the
> resharing circuit-breaker, KAT-deterministic Corona-SHA3 hash
> suite). Unlike the Pulsar sibling submission (which ships a
> mechanized EasyCrypt + Lean + Jasmin refinement chain against
> FIPS 204), Corona ships NO machine-checked refinement at this
> submission — R-LWE has no NIST standard target, the construction
> IS the spec, and mechanizing the construction itself is a multi-
> month research roadmap item. Corona's correctness evidence
> reduces to code review of the Go reference against the published
> construction, KAT cross-validation (Go ↔ C++ byte-equality
> manifest), the per-path constant-time static audit in
> `CONSTANT-TIME-REVIEW.md` (zero must-fix findings), fuzz harness
> coverage, and the academic security analysis in the cited paper.
> The proof tier is intentionally less mature than Pulsar's; the
> roadmap items in `NIST-SUBMISSION.md` lay out the multi-version
> path to mechanized refinement.
## §7 Roadmap (multi-version closure path)
| Milestone | Target version |
|---|---|
| Single-document `spec/corona.tex` consolidating LaTeX | v0.6.0 |
| EasyCrypt theory shell for the construction-level interchangeability claim | v0.7.0 |
| Lean 4 / Mathlib mechanization of Lagrange-aggregation over `R_q` | v0.7.0 |
| dudect-style statistical CT validation harness | v0.8.0 |
| External cryptographic audit (engaged lab) | v0.8.0 |
| Parameter-set worksheet (lattice-estimator concrete bounds) | v0.6.0 |
The closure path is real but long. The honest framing at this
submission: production-hardened implementation of a published
academic construction, with production lifecycle additions, NOT
machine-checked refinement of a NIST standard.
---
**Document metadata**
- Name: `PROOF-CLAIMS.md`
- Version: v0.1 (initial submission-package scaffolding)
- Date: 2026-05-18
+87
View File
@@ -0,0 +1,87 @@
# Security policy
## Reporting vulnerabilities
Please report cryptographic or implementation vulnerabilities privately to
**[email protected]** — encrypted with the team key listed at
`https://lux.network/security/key.asc`. Public disclosure happens after a
fix lands and downstream consumers have had a 14-day private window.
## What is in-scope
Corona is **production-hardened reference implementation** for
Ring-LWE threshold signing in Quasar consensus, and a NIST MPTC
submission package. The following are in-scope for responsible
disclosure:
- Specification ambiguity that leads to an exploitable verifier
behaviour.
- Threshold-protocol soundness gaps (forgery, key-recovery, share
extraction, rogue-key, adaptive-corruption breaks).
- Constant-time violations in code paths that touch a secret share,
a Gaussian sample, or a Lagrange-aggregation intermediate.
- KAT mismatches between the Go reference and the C++ port at
`~/work/luxcpp/crypto/corona/` (cross-runtime byte-equality is a
load-bearing invariant).
- Pedersen DKG (`dkg2/`) hiding-blind leakage or commitment binding
failures.
- Reshare-protocol (`reshare/`) failures to preserve `(A, bTilde)`
across committee rotation.
- Activation-cert (`reshare/activation.go`) bypass or accept-on-
failure paths.
- Information leaks via logging, panics on secret-correlated paths,
or variable-time equality.
- Cryptanalysis of the underlying Boschini et al. ePrint 2024/1113
construction or of Corona's specific parameter set (`N = 256`,
`q = 0x1000000004A01`).
## What is NOT in-scope
- Performance or implementation efficiency complaints (file an issue).
- DoS attacks against the reference implementation that don't affect
the threshold-correctness invariants.
- Issues exclusively in the M-LWE sibling at `luxfi/pulsar` — file
there. Corona and Pulsar are independent libraries with no shared
types.
- Issues in lens-specific code (`lens/`) — Corona's threshold path
does not depend on lens.
- Issues in the legacy `dkg/` (Feldman VSS without blinding) —
documented as broken for public broadcast; replaced by `dkg2/`
(Pedersen DKG with hiding blinds). Production deployments use
`dkg2/`.
## CVE assignment
Corona maintainers will request CVEs for any in-scope vulnerability
prior to public disclosure. CVE numbers will be embedded in the
ePrint changelog and the release tag's commit message.
## NIST MPTC submission disclosures
Findings discovered after the 2026-Nov-16 MPTC package submission
deadline will be added to the submission's "known limitations"
appendix and disclosed publicly per NIST's MPTC public-analysis
process (no embargo window for findings against actively-submitted
MPTC packages).
## Coordinated disclosure with Pulsar
Corona and Pulsar are independent submissions but share Lux as a
common author and overlap in some operational mitigations (e.g.,
aggregator-host hardening, mlock pinning). A vulnerability that
affects both packages will be disclosed to both `[email protected]`
mailing lists simultaneously to enable coordinated patching.
## Disclosure timeline (default)
- T+0: Private report received at security@lux.network.
- T+5 days: Acknowledgement + initial triage; CVE requested if
in-scope.
- T+30 days: Fix landed in `main`; tagged patch release; private
disclosure to downstream consumers (Quasar consensus, etc.).
- T+44 days: Public disclosure (advisory + CVE published).
Faster disclosure timelines apply for critical findings (immediate
exploitability with no mitigation). Slower timelines apply for
research-level findings requiring spec consultation with NIST MPTC
reviewers.
+355
View File
@@ -0,0 +1,355 @@
# SPEC — Corona Threshold Ring-LWE Signature (v0.2)
> **Standalone protocol specification** for **Corona** — a 2-round
> threshold Ring-LWE signature scheme with Pedersen DKG over `R_q`
> and proactive resharing.
>
> Companion to:
> - `papers/lp-073-pulsar/lp-073-pulsar-pedersen-dkg.tex` — DKG section
> - `papers/lp-073-pulsar/lp-073-pulsar-resharing.tex` — resharing section
> - `DESIGN.md` — Pulsar / Corona lifecycle design (the "what is preserved" invariants)
> - `docs/ietf-draft-skeleton.md` — IETF Internet-Draft version
>
> A single-document `spec/corona.tex` consolidating this material into
> the formal MPTC LaTeX spec format is in progress; the present
> document is the canonical reviewer entry point at submission scaffolding
> time.
## §1 Scope
This document specifies **Corona**, the Ring-LWE 2-round threshold
signature construction shipped at `github.com/luxfi/corona`. Corona
implements the published construction of Boschini, Kaviani, Lai,
Malavolta, Takahashi, and Tibouchi (IACR ePrint 2024/1113, IEEE S&P
2025) on a fixed parameter set, plus the production lifecycle layers
that the academic paper does not specify (Pedersen DKG over `R_q`,
proactive resharing, identifiable abort, activation certificates,
KAT-deterministic Corona-SHA3 hash suite).
This spec does NOT cover:
- The single-party FIPS 204 ML-DSA algorithm (different lattice
family — see Pulsar at `~/work/lux/pulsar/`).
- Verifier implementations beyond the Corona reference verifier
(`sign/sign.go:Verify`). No third-party R-LWE threshold verifier
exists at submission time.
- Pulsar (Module-LWE sibling) — see `https://github.com/luxfi/pulsar`.
- Magnetar (Tier 3 SLH-DSA research profile) — see
`https://github.com/luxfi/magnetar`.
## §2 Terminology
| Term | Meaning |
|---|---|
| **Party** | A computing entity participating in DKG / signing. |
| **Quorum** `Q` | Subset of parties of size ≥ `t`. |
| **Sharing polynomial** `f` | Degree `t − 1` polynomial whose constant term is the master secret `s ∈ R_q`. |
| **Group public key** `(A, bTilde)` | Pair of public matrix `A ∈ R_q^{k×ℓ}` (expanded from `sid`) and rounded LWE image `bTilde ≈ Round(A·s + e)`. |
| **Session identifier** `sid` | Fresh randomness binding a session. |
| **Key era** | Lineage of a group public key. Preserved across resharing; bumps only at Reanchor. |
| **Generation** | LSS resharing version within a key era. Bumps on every Refresh / Reshare. |
| **Activation cert** | Threshold signature under unchanged `(A, bTilde)` proving new committee's signing capability after a Reshare. |
## §3 Parameter set (single set in v0.2)
| Identifier | Value | Source |
|---|---|---|
| Ring degree `N` | 256 (`LogN = 8`) | `threshold/threshold.go` |
| Polynomial ring | `R_q = Z_q[X]/(X^N + 1)` | construction |
| Prime modulus `q` | `0x1000000004A01` (48-bit NTT-friendly) | `threshold/threshold.go` |
| Module width `M` | 8 | `sign.M` |
| Module height `N_M` | 7 | `sign.N` |
| Challenge weight `Kappa` | 23 | `threshold/threshold.go` |
| Decomposition `Dbar` | 48 | `threshold/threshold.go` |
The single-set submission is intentional: Corona ships a fixed
parameter set tuned to provide ≥ 128 bits of post-quantum security
against the best known R-LWE attacks (per the lattice-estimator
methodology of Albrecht-Player-Scott). A second parameter set
targeting NIST PQ Category 3 is on the roadmap but is NOT in this
submission package.
## §4 Threat model
Per `DESIGN.md` §"Three layers, one shipping path". Summary:
- Static corruption of at most `t − 1` parties.
- Rushing Byzantine adversary.
- Synchronous network with known upper bound `Δ` on message delivery.
- Pedersen DKG (`dkg2/`) provides hiding and binding; legacy `dkg/`
(Feldman VSS without blinding) is documented as broken for public
broadcast and is retained for historical reference only.
- R-LWE hardness over the fixed parameter set (Lyubashevsky-Peikert-
Regev 2010 + follow-up analysis).
- cSHAKE256 / KMAC256 / TupleHash256 collision/preimage resistance
per FIPS 202 + SP 800-185.
## §5 Security goals
1. **EUF-CMA-Threshold**: no forgery under honest-quorum. Inherited
from Boschini et al. ePrint 2024/1113 Theorem 4.1 (with the caveat
that the original paper assumes trusted-dealer Gen; Corona's
`dkg2/` strengthens this to publicly-verifiable DKG).
2. **Construction-level output interchangeability** (Class N1 / MPTC):
threshold-emitted bytes verify under the construction's own
verifier (`sign.Verify`); no FIPS standard target.
3. **Public-key preservation across resharing** (Class N4 / MPTC):
`(A, bTilde)` byte-identical across Refresh / ReshareToNewSet
within a key era.
4. **Identifiable abort** with attributable evidence under
synchronous network assumptions.
5. **Robustness**: ≥ t honest parties → valid signature with
overwhelming probability.
Detailed proofs / reductions: see `PROOF-CLAIMS.md` for the honest
framing (Corona ships no mechanized refinement at this submission).
The academic proofs in Boschini et al. ePrint 2024/1113 §3 cover the
EUF-CMA reduction for the construction; Corona inherits that
analysis as paper-cited prior art.
## §6 Pedersen DKG over `R_q`
Per `papers/lp-073-pulsar/lp-073-pulsar-pedersen-dkg.tex` (LP-073).
Highlights:
- Each party `i` samples a sharing polynomial `f_i(X)` of degree
`t − 1` over `R_q^M`.
- Coefficient commitments `C_i^(k) = A·NTT(f_i^(k)) + B·NTT(r_i^(k))`
where `A, B` are public R_q^M generators derived from `sid_dkg`
via cSHAKE256, and `r_i^(k)` is a per-coefficient hiding blind.
- Per-pair encrypted-share exchange under authenticated KEX.
- Complaint round produces signed public evidence of malformed
shares.
- Qualified set `QSET` determined by complaint resolution; if
`|QSET| < t`, DKG ABORTS.
- Final group public key `bTilde = Round(Σ_{i ∈ QSET} f_i^(0) · A + e)`.
- Implementation: `dkg2/dkg2.go` (commit-share-verify),
`dkg2/complaint.go` (complaint handling).
Constant-time guarantee: `dkg2/dkg2.go:VerifyShareAgainstCommits`
calls `constTimePolyEqual` over the little-endian byte view of
every `Coeffs[level]` — no early return; the loop runs to completion
before the final `if eq != 1` branch. See `CONSTANT-TIME-REVIEW.md`
§2 for the per-line audit.
## §7 Threshold signing (2 rounds)
Per Boschini et al. ePrint 2024/1113 §3, retargeted to Corona's
parameter set:
**Round 1 (commit).** Each party `i ∈ Q`:
- Samples `y_i ← R_q^M` from a discrete Gaussian (lattigo
`KeyedPRNG`-backed sampler).
- Computes `w_i = A · y_i`.
- Broadcasts a commitment to `w_i` (cSHAKE256 hash with domain
separation tag `QUASAR-CORONA-SIGN1-v1`).
**Aggregator.** Collects all commitments from `Q`, computes
the canonical Lagrange aggregation, derives the challenge
`c ← H_c(transcript)` where `H_c` is the ternary-challenge hash
(TupleHash256 with prefix `QUASAR-CORONA-COMBINE-v1`).
**Round 2 (respond).** Each party `i ∈ Q`:
- Computes its partial response `z_i = y_i + c · s_i` over `R_q^M`.
- Broadcasts `z_i` to the aggregator. Authenticated with a per-pair
KMAC256 MAC derived from the DKG-established pairwise material.
**Combine.** Aggregator:
- Verifies each `z_i` MAC.
- Computes aggregated `z = Σ_{i ∈ Q} λ_i^Q · z_i` where `λ_i^Q` are
the Lagrange coefficients evaluated at zero for the quorum's
party indices.
- Checks low-norm conditions on `z` (Boschini et al. ePrint 2024/1113
Figure 2).
- If accept, packages signature `σ = (c, z, Δ)` per
`sign/sign.go:Sign`.
Total bandwidth per signing session: 2 broadcast rounds + 1
aggregator-to-all round; `O(n · |w| + n · |z|)` per session.
## §8 Verification
Corona reference verifier at `sign/sign.go:Verify`:
```
sign.Verify(groupKey, message, signature) ∈ {OK, FAIL}
```
The verifier:
1. Reconstructs `w = A · z - c · bTilde` (from the signature's `z`
and the public `(A, bTilde)`).
2. Recomputes `c' = H_c(transcript_with_w)`.
3. Verifies `c' == c` via constant-time `r.Equal` (lattigo).
4. Checks low-norm bound on `z` (`primitives.CheckL2Norm`).
No third-party FIPS-validated verifier exists for R-LWE threshold
signatures at submission time. Corona's verifier is the spec.
## §9 Proactive resharing
Per `papers/lp-073-pulsar/lp-073-pulsar-resharing.tex` (LP-073).
Preserves `(A, bTilde)` across committee rotation. Two distinct
primitives:
### §9.1 Refresh (same committee, fresh shares)
Each party samples a degree-`t-1` polynomial `z_i(x)` with `z_i(0) = 0`,
distributes `z_i(α_j)` to each peer, and each party updates
`s'_j = s_j + Σ_i z_i(α_j)`. Master secret `s` unchanged. Defends
against mobile-adversary share accumulation. Implementation:
`reshare/refresh_test.go` exercises the round-based protocol.
### §9.2 ReshareToNewSet (set rotation, new shares)
Old qualified subset `Q ⊆ O_old` with `|Q| ≥ t_old` cooperates.
Each `i ∈ Q` samples a fresh polynomial `g_i(x)` of degree
`t_new − 1` with `g_i(0) = s_i` (own old share as constant term).
Delivers `g_i(β_j)` to each new party `j`. New party `j` computes
`s'_j = Σ_{i ∈ Q} λ^Q_i · g_i(β_j)`. The new polynomial
`g(x) = Σ λ^Q_i · g_i(x)` satisfies `g(0) = Σ λ^Q_i · s_i = s` —
recovers the same master secret structurally. Implementation:
`reshare/reshare.go` + `reshare/keyshare.go`.
## §10 Identifiable abort
Per `DESIGN.md` §"Two distinct primitives in pulsar/reshare/" +
§"VSR maturity ladder". TLV-encoded per-kind abort evidence:
- Missing message (timeout + signed absence)
- Equivocation (two signed conflicting messages from same sender)
- Malformed ciphertext (decryption-oracle evidence with care
taken not to leak threshold-reconstructing data)
- Invalid share contribution (Pedersen commit mismatch with
constant-time slot-equality check from `dkg2/`)
Implementation: `dkg2/complaint.go` + `reshare/complaint.go`.
## §11 Transcript and domain separation
`DOMAIN_PREFIX` values are defined in `DESIGN.md` §"Domain-separated
message prefixes":
| Prefix | Used for |
|---|---|
| `QUASAR-CORONA-BUNDLE-v1` | Corona pulse over a Quasar bundle |
| `QUASAR-CORONA-SIGN1-v1` | Corona signing Round 1 commit |
| `QUASAR-CORONA-SIGN2-v1` | Corona signing Round 2 response |
| `QUASAR-CORONA-COMBINE-v1` | Corona finalize transcript |
| `QUASAR-CORONA-REFRESH-v1` | Refresh activation cert (same set) |
| `QUASAR-CORONA-RESHARE-v1` | Reshare activation cert (set rotation) |
| `QUASAR-CORONA-ACTIVATE-v1` | Generic activation cert |
| `QUASAR-CORONA-REANCHOR-v1` | Reanchor authorization (governance) |
Replay binding includes `sid + chain_id + epoch + (n, t) + QSET-hash +
M-hash + ctx-hash + key_era_id + group_id + reshare_transcript_hash +
implementation_version`.
## §12 Wire formats
Polynomial vectors and matrices serialize through `luxfi/math/codec`
(LP-107 Phase 4). The `Vector[Poly]` frame is validated before
lattigo `ReadFrom` per `corona/wire/`. Wire formats are pinned by
the KAT manifest at `scripts/regen-kats.manifest.sha256` — any
serialization drift breaks the cross-runtime Go ↔ C++ byte-equality
gate.
## §13 Hash suite
Production: **Corona-SHA3** (cSHAKE256 / KMAC256 / TupleHash256 per
FIPS 202 + SP 800-185). Implementation: `hash/sp800_185.go`.
Customization strings for cSHAKE256:
- `CORONA-HC-v1` — challenge hash (`H_c`)
- `CORONA-HU-v1` — uniform hash (`H_u`)
- `CORONA-PRF-v1` — per-pair PRF seed derivation
- `CORONA-MAC-v1` — per-pair KMAC key derivation
- `CORONA-DKG-v1` — DKG commitment derivation
- `CORONA-RESHARE-v1` — resharing transcript hash
Legacy: **Corona-BLAKE3** — retained for cross-port byte checks via
`hash.NewCoronaBLAKE3()`. NOT the normative submission profile.
## §14 Test vectors
KAT regeneration via `scripts/regen-kats.sh` → emits JSON to
`~/work/luxcpp/crypto/corona/test/kat/` for Go ↔ C++ byte-equality
verification. Manifest at `scripts/regen-kats.manifest.sha256`
pins SHA-256 of every regenerated file.
Five oracle generators in `cmd/`:
- `cmd/corona_oracle_v2/` — sign / verify KAT entries (Corona-BLAKE3)
- `cmd/cross_runtime_oracle/` — cross-language byte-equality vectors
- `cmd/dkg2_oracle/` — DKG transcripts
- `cmd/reshare_oracle/` — Refresh + ReshareToNewSet transcripts
- `cmd/activation_oracle/` — activation cert vectors
## §15 Security considerations
Inherited from Boschini et al. ePrint 2024/1113 §3 (EUF-CMA proof
sketch). Corona-specific additions:
- **Trusted-dealer assumption removed**: Pedersen DKG over `R_q`
(`dkg2/`) replaces the original construction's trusted-dealer
Gen.
- **Hiding via blinding**: dkg2 commits are `A·NTT(s) + B·NTT(r)` with
per-coefficient hiding blind `r`, replacing the broken
Feldman-style `C = A·NTT(s)` in legacy `dkg/`.
- **Constant-time verification**: see `CONSTANT-TIME-REVIEW.md` for
the per-path audit. Zero `(c)` (must-fix) findings.
- **Forward security**: share material is zeroed in place after
activation via `reshare/keyshare.go:EraseShare`. Zeroization is
best-effort under Go's memory model; production deployments
pin pages via `mlock` (see `DEPLOYMENT-RUNBOOK.md`).
## §16 Implementation considerations
- Go 1.26.3 minimum (per `go.mod`).
- `luxfi/lattice/v7` provides constant-time NTT / Montgomery
reduction / discrete-Gaussian sampling.
- `crypto/subtle` for byte-blob constant-time compare.
- `golang.org/x/crypto/sha3` for cSHAKE256 / KMAC256 / TupleHash256.
- No assembly, no SIMD intrinsics. Performance over correctness is a
non-goal for the reference implementation.
## §17 Known limitations
Per `SUBMISSION.md` §"Does NOT claim":
- No FIPS 204 byte-equality (use Pulsar for that).
- No mechanized refinement proof.
- No identifiable abort under network partition (synchronous only).
- No 1-round signing.
- DKG bias resistance requires external randomness beacon.
- No cross-key-era preservation (Reanchor opens a new key era).
## §18 Proof and audit status
- **Machine-checked refinement proof**: NONE at this submission. See
`PROOF-CLAIMS.md` for the narrow stated claim and the roadmap
(multi-month research project).
- **Constant-time audit**: `CONSTANT-TIME-REVIEW.md` — zero `(c)`,
two `(b)` mitigated (one closed in `dkg2/`; one in lens-specific
paths off the Corona threshold path).
- **Side-channel statistical (dudect)**: harness not yet wired
(roadmap v0.8.0). Currently the constant-time evidence is the
static per-path audit above; statistical validation is future work.
- **External audit**: TBD — engagement post-submission.
- **Fuzz coverage**: `reshare/fuzz_*_test.go` (3 harnesses),
`dkg2/fuzz_round_test.go`, `threshold/fuzz_round_test.go`. Per-push
smoke runs are informational; submission-grade fuzz budgets are
operational.
## §19 Patent / IP declaration
Royalty-free patent grant per `PATENTS.md`. Claim drafts in
`docs/patent-claims.md` (fewer claims than Pulsar — Corona claims
only the production lifecycle additions beyond the published
Boschini et al. construction). Defensive termination extends to all
NIST-standardized PQ signature schemes.
---
**Document metadata**
- Name: `SPEC.md`
- Version: v0.2 (initial submission-package scaffolding)
- Date: 2026-05-18
- Companion docs: `DESIGN.md`, `papers/lp-073-pulsar/`, `docs/ietf-draft-skeleton.md`
- Full LaTeX `spec/corona.tex` is in progress.
+304
View File
@@ -0,0 +1,304 @@
# NIST MPTC Submission — Corona
This document is the cover sheet for the **Corona** submission to the
NIST Multi-Party Threshold Cryptography (MPTC) project. It is written
for NIST reviewers and points at every artifact a reviewer needs.
The `corona` repository is the **single canonical home** for the
submission: it carries the Go reference implementation under
`sign/` + `threshold/` + `dkg2/` + `reshare/` + `primitives/` + `hash/`,
the cover sheet, the design spec, the KAT vector format, the
constant-time evidence, and the tarball-cut tooling. There is exactly
one canonical implementation. A NIST reviewer gets a self-contained
checkout that does not require network access.
The repository is **active** (not frozen). The submission tarball is
cut from a tag on `main` at NIST's deadline via
`scripts/cut-submission.sh`; reviewer feedback and post-submission
patches land in this same repository so the artifact chain stays
auditable.
**Date stamp (this revision): 2026-05-18.**
**Maturity stamp**: v0.2 ready. This submission is **not**
NIST-ratified, **not** FIPS 140-3 validated, **not** ACVP-validated,
and explicitly **not anchored to a FIPS standard** (R-LWE threshold
signing has no NIST standard — the academic Boschini et al. paper is
the construction spec). It is the algorithm-level reference plus
production lifecycle additions plus reproducibility tooling.
## At a glance
| Field | Value |
|---|---|
| Submission name | **Corona** |
| Submitting organisation | Lux Industries, Inc. |
| Algorithm | Threshold Ring-LWE 2-round signing + DKG + proactive resharing |
| Target NIST MPTC classes | **N1** (threshold signing, single-party-output-compatible against the construction's own verifier) + **N4** (multi-party key generation with public-key preservation across resharing) |
| Underlying construction | Boschini, Kaviani, Lai, Malavolta, Takahashi, Tibouchi. *Practical two-round threshold signatures from learning with errors.* IACR ePrint **2024/1113**, IEEE S&P 2025 |
| Lattice family | Ring-LWE over `R_q = Z_q[X]/(X^N + 1)`, `N = 256`, `q = 0x1000000004A01` (48-bit NTT-friendly prime) |
| Round count | 2 rounds per signature |
| Signature output | Byte-compatible with the construction's own verifier (`sign.Verify`); **NOT byte-equal to FIPS 204 ML-DSA** — that property belongs to the M-LWE sibling [`luxfi/pulsar`](https://github.com/luxfi/pulsar) |
| Hash suite | Corona-SHA3 (cSHAKE256 / KMAC256 / TupleHash256 per FIPS 202 + SP 800-185); legacy Corona-BLAKE3 retained for cross-port byte checks |
| Repository | <https://github.com/luxfi/corona> (single canonical home: code, spec pointers, KAT, cut tool) |
| Algorithm source | This repository, `sign/` + `threshold/` + `dkg2/` + `reshare/` + `primitives/` + `hash/`. Latest tagged release at this revision: `v0.4.1` (next: `v0.5.0` accompanying the submission package). |
| Tarball cut tool | `scripts/cut-submission.sh` (tags from `main`, regenerates KATs, snapshots vendor tree, tars) |
| Submission tag | `submission-YYYY-MM-DD` (cut from `main` at deadline) |
| Spec | `SPEC.md` + `papers/lp-073-pulsar/` LaTeX sections + `DESIGN.md`. The formal MPTC LaTeX spec (`spec/corona.tex`) is consolidated from existing material; full single-document spec.tex is in progress. |
| License | Apache-2.0 (code) — see `LICENSE` |
| Patent posture | **Royalty-free grant** — see `PATENTS.md` (public-facing grant text) and `docs/patent-claims.md` (attorney-prep claim drafts). Lux Industries grants a worldwide, royalty-free, irrevocable patent license to any implementation conformant to the Corona construction released under Apache-2.0 or compatible OSI license, OR any NIST MPTC / PQC / ACVP submission, validation, or interoperability test. Defensive termination mirrors Apache-2.0 §3. |
| Sibling submission | **Pulsar** ([`luxfi/pulsar`](https://github.com/luxfi/pulsar)) — M-LWE threshold ML-DSA with FIPS 204 byte-equality. Independent submission; reviewable separately. |
## Headline claim
> Every signature produced by a Corona threshold ceremony (DKG →
> Round-1 → Round-2 → Combine) verifies under the Corona verifier
> (`sign.Verify`) on the same message and group public key `(A, bTilde)`
> as a single-party Corona signature would, AND the underlying group
> public key is preserved bit-identically across proactive resharing
> events within a key era (Class N4 invariant).
This is a **construction-level interchangeability** claim, NOT a FIPS
204 byte-equality claim. Corona uses Ring-LWE arithmetic that has no
NIST standard analogue at the time of submission; the Boschini et al.
construction IS the spec.
**Verifier-side story (load-bearing for N1 framing).** Because there
is no NIST standard R-LWE threshold signature, the Class N1
"output-interchangeability" axis is reduced to: any verifier that
accepts a single-party run of the underlying Boschini et al.
construction MUST accept a Corona threshold-aggregated signature on
the same `(pk, m)`. The Corona reference verifier at
`sign/sign.go:Verify` plays both roles (threshold-output verifier and
single-party-output verifier) because the construction is symmetric
in that respect. A reviewer evaluating the N1 claim should compare
Corona's threshold-emitted bytes to the bytes a single-party run of
the same parameter set would produce on the reconstructed secret —
the comparison is via the same `Verify` routine, not via a third
party FIPS-validated verifier (which does not exist for R-LWE
threshold).
## Algorithm scope
The algorithm being submitted is the Corona implementation at
`luxfi/corona` v0.4.1. The construction is the 2-round protocol of
Boschini, Kaviani, Lai, Malavolta, Takahashi, Tibouchi
(IACR ePrint 2024/1113, IEEE S&P 2025) — **unchanged in its math** —
plus the following production lifecycle layers that the original
paper does not specify (these are Corona's contribution to the
submission package):
1. **Proper Pedersen DKG over `R_q`** with hiding blinds — `dkg2/`.
Replaces the original construction's trusted-dealer assumption
with a publicly-verifiable distributed key generation. The legacy
`dkg/` package (Feldman VSS without blinding) is retained for
historical reference only and is documented as broken for public
broadcast (see `RED-DKG-REVIEW.md` in the production lineage).
2. **Proactive resharing across committee rotation** — `reshare/`.
Preserves the group public key `(A, bTilde)` across validator-set
changes within a key era; only the share distribution rotates.
Two distinct primitives are exposed: `Refresh` (same set, fresh
shares — HJKY97 lineage) and `ReshareToNewSet` (set rotation,
new shares — Desmedt-Jajodia 1997 / Wong-Wang-Wing 2002 lineage).
3. **Identifiable abort with attributable evidence** — `dkg2/complaint.go`
+ `reshare/complaint.go`. Per-pair Pedersen-style verification with
constant-time slot equality on the recipient side; failure produces
signed evidence pointing to a malicious sender.
4. **Activation certificate** (the circuit-breaker) — `reshare/activation.go`.
After a resharing finishes the math, the new committee
threshold-signs an activation message under the unchanged group
public key; only on successful verification does the chain mark
the new epoch live.
5. **Hash-suite injection through every Sign-path primitive** —
`hash/sp800_185.go` + `primitives/hash.go`. Production deployments
use Corona-SHA3 (cSHAKE256 / KMAC256 / TupleHash256 per FIPS 202 +
SP 800-185). The legacy Corona-BLAKE3 suite remains available for
cross-port byte checks but is NOT the normative submission profile.
## What to read first
A reviewer with limited time should read in this order:
1. **`SUBMISSION.md`** (this file) — submission metadata and headline
2. **`NIST-SUBMISSION.md`** — one-page executive summary
3. **`SPEC.md`** — standalone construction specification
4. **`DESIGN.md`** — Pulsar/Corona lifecycle design (the "what is preserved across resharing" invariants)
5. **`PROOF-CLAIMS.md`** — what is claimed vs not (HONEST framing — no machine-checked refinement proof at this submission, unlike Pulsar)
6. **`TRUSTED-COMPUTING-BASE.md`** — implementation TCB (Go + lattigo + crypto/subtle)
7. **`docs/evaluation.md`** — performance + correctness + KAT cross-validation evidence
8. **`PATENTS.md`** — royalty-free patent grant text
9. **`README.md`** — repository layout and how to reproduce
10. **`CONSTANT-TIME-REVIEW.md`** — per-path constant-time audit (0 critical findings)
11. **`DEPLOYMENT-RUNBOOK.md`** — operator-facing trust-model disclosure
## What to run
The reproducibility gate is `scripts/build.sh` against the tarball
extract — the entire submission is self-contained, so no network
access is required:
```bash
tar xzf submission-YYYY-MM-DD.tar.gz
cd corona
scripts/build.sh # builds Go ref
scripts/test.sh # runs unit + KAT replay tests
scripts/bench.sh # produces signing/verification benchmarks
scripts/gen_vectors.sh # regenerates KAT vectors (deterministic)
```
`scripts/build.sh` exits non-zero on any failure. CI runs the same
script on every commit; the reproducibility property is the load-
bearing one for the submission.
To cut a fresh tarball (maintainer-side):
```bash
scripts/cut-submission.sh # dry-run, no tarball
scripts/cut-submission.sh submission-2026-11-16 # production cut + tag
```
The cut script verifies a clean tree, regenerates the KATs from the
in-tree canonical implementation, re-runs the round-trip replay
tests, tars the entire submission checkout, and prints the SHA-256.
## Class N1 — Construction-level output interchangeability
The N1 claim is asserted at **three** levels of evidence (one fewer
than Pulsar; the missing level is the machine-checked refinement
chain, because R-LWE has no FIPS standard to refine against):
| Evidence | Where |
|---|---|
| Algorithmic argument | `SPEC.md` §§7–8 + Boschini et al. ePrint 2024/1113 §§3–4 |
| Test harness | KAT replay tests; `cmd/cross_runtime_verify/` cross-runtime verification |
| Cross-implementation KATs | `cmd/cross_runtime_oracle/` + `scripts/regen-kats.sh` (Go ↔ C++ luxcpp port) |
**What Corona DOES NOT provide vs Pulsar**:
- No EasyCrypt refinement chain (Corona has no FIPS-standard target).
- No Lean ↔ EC algebraic bridge files.
- No Jasmin high-assurance implementation (libjade does not cover Corona's R-LWE parameter set).
- No machine-checked `Class N1 byte-equality` theorem.
The honest framing for Corona is: **production-hardened
implementation of a published academic construction**, not
**machine-checked refinement of a NIST standard**. The mechanized
proof tier remains a roadmap item; see `PROOF-CLAIMS.md` for the
narrow stated claim and the (admittedly long) closure path.
## Class N4 — Public-key preservation across resharing
Multi-party proactive resharing preserves the group public key
`(A, bTilde)` across committee rotations (epoch boundaries), so a
single long-lived public identity persists while the secret-share
custodians rotate.
| Evidence | Where |
|---|---|
| Algorithmic argument | `DESIGN.md` §"Three layers, one shipping path" + §"Two distinct primitives in pulsar/reshare/" |
| Test harness | `reshare/reshare_test.go`, `reshare/refresh_test.go`, `reshare/full_integration_test.go` (45 tests; activation under unchanged GroupKey is the load-bearing assertion) |
| KAT cross-validation | `cmd/reshare_oracle/` emits JSON consumed by the C++ port; `scripts/regen-kats.sh` enforces byte-equal round-trip |
## High-assurance track — HONEST DELTA vs Pulsar
Pulsar ships an EasyCrypt + Lean + Jasmin high-assurance track that
mechanically refines its Class N1 byte-equality claim against a
formal model of FIPS 204. **Corona does NOT ship that.** The honest
delta:
| Pulsar artifact | Corona equivalent | Status |
|---|---|---|
| 13/13 EasyCrypt files compile, 0/0 admits | none | NOT PRESENT — multi-month research project, see `PROOF-CLAIMS.md` |
| 5/5 Lean ↔ EC algebraic-bridge files | none | NOT PRESENT |
| 3/3 jasmin-ct blocking on threshold layer | none | NOT PRESENT — libjade does not target this parameter set |
| Class N1 byte-equality theorem (mechanized) | construction-level claim only | NOT MECHANIZED — Boschini et al. paper is the spec, no FIPS target |
| `pq-crystals` / BoringSSL / OpenSSL cross-validation | none possible | NOT APPLICABLE — no third-party R-LWE threshold verifier exists |
What Corona DOES offer at submission-time:
1. **Production-hardened reference implementation** in Go
(`sign/`, `threshold/`, `dkg2/`, `reshare/`, `primitives/`, `hash/`).
2. **Per-path constant-time audit** (`CONSTANT-TIME-REVIEW.md`) — zero
`(c)` (must-fix) entries, two documented `(b)` entries with
mitigations.
3. **KAT-deterministic outputs** under Corona-SHA3 (and legacy
Corona-BLAKE3 for cross-port byte checks).
4. **Cross-runtime byte-equality** (Go ↔ C++ port at
`~/work/luxcpp/crypto/corona/`) enforced by
`scripts/regen-kats.sh` manifest.
5. **Fuzz coverage** — `reshare/fuzz_*_test.go`, `dkg2/fuzz_round_test.go`,
`threshold/fuzz_round_test.go`. Per-push smoke runs are
informational; submission-grade fuzz budgets are operational.
6. **Identifiable-abort evidence pipeline** at the dkg2 / reshare layer.
## What this submission does NOT claim
- **No byte-equality with FIPS 204 ML-DSA** — that is Pulsar's claim.
Corona is an independent R-LWE construction with no NIST standard
to verify against.
- **No mechanized refinement proof** — no EasyCrypt, no Lean, no
Jasmin. The construction is the published academic paper; the Go
implementation matches it by reading, code review, and KAT
cross-validation. Machine-checked refinement is a multi-month
research roadmap item (see `PROOF-CLAIMS.md`).
- **No FIPS 140-3 module validation** — applies to packaged
cryptographic modules, not this reference implementation. Downstream
of this submission.
- **No ACVP / CAVP algorithm validation certificate** — no NIST ACVP
test vector set exists for R-LWE threshold signatures.
- **No identifiable abort under network partition** — synchronous
network assumption only; asynchronous identifiable abort is a
separate problem.
- **No 1-round signing** — the construction is 2-round by design,
inherited from Boschini et al. ePrint 2024/1113.
- **No bias-resistant DKG under collusion** — Pedersen DKG over `R_q`
in `dkg2/` provides hiding and binding under standard assumptions;
bias resistance under fully-colluding majority requires an external
randomness beacon at the consensus layer (out of scope).
- **No cross-key-era preservation** — Reanchor (rare governance
event) starts a new key era with a fresh `(A', s', bTilde')`;
resharing only preserves `(A, bTilde)` **within** a key era.
## Comparison to sibling and related submissions
| Submission | Lattice | Round count | Output story | NIST class |
|---|---|---|---|---|
| **Corona** (this) | Ring-LWE (R-LWE) | 2 | Construction-level interchangeable with single-party Corona verifier; no NIST standard target | N1 + N4 |
| **Pulsar** ([`luxfi/pulsar`](https://github.com/luxfi/pulsar)) | Module-LWE (M-LWE) | 2 | Byte-equal to FIPS 204 ML-DSA-65 | N1 + N4 |
| Raccoon (NIST PQC) | Module-LWE | 3 | Compatible verification | not MPTC |
| Boschini et al. (academic upstream) | R-LWE | 2 | Construction-level; trusted-dealer Gen only | not submitted as MPTC |
The R-LWE / M-LWE pair is intentional. Lux's primary-network
QuasarCert MAY combine Corona (R-LWE) and Pulsar (M-LWE) as a
**Double Lattice** layered defence so a break in one lattice family
does not break finality. That layered combination is the consumer's
design choice and is not part of this submission. Corona stands
alone as an MPTC Class N1 + N4 candidate.
## Contact
- Primary: <z@lux.network> (Lux Industries, Inc.)
- Submission coordination: <mptc@lux.network>
- Security disclosure: see `SECURITY.md`
- Public discussion: <https://github.com/luxfi/corona/discussions>
## Reproducibility commitment
The build, test, vector-generation, and benchmark scripts are
deterministic from fixed seeds. A reviewer reproducing the
submission tarball from `submission-` should obtain
byte-identical artifacts. Drift is a build bug; please open an issue.
---
**Document metadata**
- Name: `SUBMISSION.md`
- Version: v0.1 (initial submission-package scaffolding)
- Date: 2026-05-18
- Submission package version: Corona v0.2 (tagged `submission-2026-11-16` on cut date)
- Underlying library version at this revision: `luxfi/corona v0.4.1`
+222
View File
@@ -0,0 +1,222 @@
# TRUSTED-COMPUTING-BASE — Corona implementation TCB
> **What you must trust to rely on Corona's construction-level
> correctness claim.** Companion to `PROOF-CLAIMS.md` (proof scope)
> and `CONSTANT-TIME-REVIEW.md` (per-path CT audit).
>
> **HONESTY NOTE**: Corona's TCB is structurally simpler than Pulsar's
> because Corona ships NO mechanized refinement layer (no EasyCrypt,
> no Lean, no Jasmin). That removes those tools from the TCB but
> increases the trust placed in the Go reference implementation
> review, KAT cross-validation, and the academic Boschini et al.
> construction analysis. See `PROOF-CLAIMS.md` for the honest framing.
## §0 Layered trust bases
The Corona construction-level claim rests on three layered trust
bases:
1. **The academic construction** — Boschini, Kaviani, Lai, Malavolta,
Takahashi, Tibouchi. *Practical two-round threshold signatures
from learning with errors.* IACR ePrint 2024/1113, IEEE S&P 2025.
This is the spec.
2. **The Go reference implementation** — `sign/`, `threshold/`,
`dkg2/`, `reshare/`, `primitives/`, `hash/`. Reviewed by code
inspection + KAT cross-validation + fuzz.
3. **The trusted-computing base (TCB) below the implementation** —
this document.
If any element of the TCB is unsound, the implementation's correctness
is unsound regardless of how clean the code review was.
## §1 Implementation TCBs
### §1.1 Reference implementation (Go)
| Component | Trust | Mitigations |
|---|---|---|
| Corona Go reference (this repository) | Standard library correctness, `crypto/rand` randomness quality, lattigo NTT/Montgomery/Gaussian-sampler primitives | Reviewed by code inspection; KAT cross-validation Go ↔ C++ (luxcpp port); fuzz harnesses on round-based protocols |
| `github.com/luxfi/lattice/v7` (lattigo fork) | Upstream `tuneinsight/lattigo/v7` NTT, Montgomery reduction, discrete-Gaussian sampler. Documented constant-time per upstream README; relevant routines are byte-stable. | Version pinned in `go.mod`. The fork carries Lux-specific extensions for hash-suite injection but the cryptographic kernels are unchanged from upstream. |
| `github.com/luxfi/math/codec` | LP-107 Phase 4 wire codec. Validates `Vector[Poly]` frame before lattigo `ReadFrom`. | Version pinned in `go.mod`. |
| `golang.org/x/crypto/sha3` | cSHAKE256, KMAC256, TupleHash256 primitives (Go-stdlib-style). | Version pinned in `go.mod`. |
| `crypto/subtle` | Constant-time byte-blob compare. Standard library. | Standard library; bundled with the Go toolchain. |
| `github.com/zeebo/blake3` | Legacy BLAKE3 hash suite (cross-port byte-check only; NOT the normative production profile). | Version pinned in `go.mod`. Legacy use only. |
### §1.2 Production targets (out of scope for v0.2)
| Target | Status |
|---|---|
| Optimized Rust crate | TODO — not in this submission |
| C library + FFI | C++ port at `~/work/luxcpp/crypto/corona/` is the de-facto C-ABI; clean C wrapper TODO |
| WASM build | TODO |
| no_std embedded | TODO |
For each future target, an independent constant-time audit + KAT
cross-validation + binding-level fuzzing is required before
considering it "production." The construction-level correctness
claim does NOT automatically transfer to these targets — each
target's correctness must be re-verified.
## §2 Build TCBs
| Layer | What you trust | Reproducibility |
|---|---|---|
| **Go toolchain** | The Go compiler used to build the reference. Version pinned to `go 1.26.3` in `go.mod`. | Hard-pinned in `go.mod`; `go.sum` enforces module checksums. |
| **`scripts/build.sh`** | The build orchestrator's correctness — that it produces deterministic outputs from a fresh checkout. | CI runs the script on every commit. |
| **`scripts/test.sh`** | The test harness's correctness — that KAT vectors compare bit-by-bit, not just lex-equal. | Reviewed; uses `bytes.Equal` for byte-level KAT comparison. |
| **`scripts/gen_vectors.sh`** | Deterministic regeneration of KAT vectors. | Wraps `scripts/regen-kats.sh`; the manifest at `scripts/regen-kats.manifest.sha256` pins SHA-256 of every regenerated file. |
| **`scripts/regen-kats.sh --verify`** | Cross-runtime byte-equality enforcement (Go ↔ C++). | Manifest is regenerated and compared; diff = build bug. |
## §3 What the TCB does NOT include
Corona's TCB is **structurally simpler** than Pulsar's because Corona
ships no mechanized refinement layer. The following are NOT in the
Corona TCB:
- **EasyCrypt prover** (Pulsar trusts it; Corona has no EC theories)
- **Lean 4 + Mathlib** (Pulsar uses Lean-bridged algebraic axioms;
Corona has none)
- **Jasmin verified compiler** (Pulsar's threshold layer is in Jasmin;
Corona is pure Go)
- **OCaml runtime** (EC is OCaml; Corona has no EC)
- **jasmin-ct** (Corona's CT evidence is static per-path audit, not
jasmin-ct analysis)
What IS in the Corona TCB but NOT in Pulsar's:
- **Greater dependence on Go reference review.** Pulsar can fall
back to the EC refinement chain if a Go reviewer misses a bug;
Corona's only line of defense is reviewer + KAT + fuzz.
- **Greater dependence on the academic Boschini et al. paper.**
Pulsar's spec target (FIPS 204) is an extensively-cryptanalyzed
NIST standard; Corona's spec target is a 2024 academic paper with
less cryptanalytic surface area at this writing.
## §4 What the TCB does NOT cover
These are explicitly NOT part of the trust base for Corona's
construction-level correctness claim:
- **Specific operating system** (Linux, macOS, BSD, Windows) — the
Go reference is OS-independent.
- **Specific CPU architecture** — Go compiles to amd64/arm64; both
exercised in CI.
- **Network protocol stack** — Corona's transport is out of scope.
- **Storage layer** — how `sk` shares are stored at rest is out of
scope. Production deployments use HSM-backed share material; see
`DEPLOYMENT-RUNBOOK.md`.
- **Key management policies** — key lifecycle is application-level
(governed by the consuming consensus layer, e.g. Quasar).
- **Application code calling Corona** — Corona's API contract is the
trust boundary.
## §5 TCB risks and mitigations
### §5.1 Construction-soundness risk
| Risk | Mitigation |
|---|---|
| The Boschini et al. ePrint 2024/1113 EUF-CMA reduction has a latent bug | Construction has been published and reviewed by the cryptographic community via IEEE S&P 2025 + IACR ePrint discussion. Lux tracks cryptanalysis literature; any flaw would prompt a parameter-set re-tune and a new key-era. Patent-bump policy and `DESIGN.md` "Reanchor" capability allow operational response. |
| Corona's production lifecycle additions (Pedersen DKG, reshare, activation cert) have a latent bug | Per-path tests in `dkg2/`, `reshare/` (45+ tests including `full_integration_test.go`). Independent third-party audit is roadmap item v0.8.0. |
### §5.2 Implementation-correctness risk
| Risk | Mitigation |
|---|---|
| Go reference implementation diverges from the construction | KAT cross-validation Go ↔ C++ (`scripts/regen-kats.sh --verify`); the C++ port is independently implemented from the same spec by a different engineer. Divergence = test failure. |
| KAT vectors are subtly wrong | Deterministic generation from fixed seeds; `cross_runtime_oracle/` and `cross_runtime_verify/` enforce Go ↔ C++ byte-equality. Both implementations would have to be wrong in the same way to escape this check. |
| Hash-suite implementation bug (cSHAKE256 / KMAC256 / TupleHash256) | `golang.org/x/crypto/sha3` is a widely-used standard library implementation; bugs are rare and quickly patched. NIST SP 800-185 KAT verification in `hash/hash_test.go` (`TestKMAC256NISTVector`, `TestTupleHash256NISTVector`). |
### §5.3 Build / reproducibility risk
| Risk | Mitigation |
|---|---|
| `scripts/build.sh` produces non-deterministic output | The build is deterministic from fixed seeds; reproducible-build property is checked on CI. Drift triggers a CI failure. |
| Toolchain version drift between commits | `go.mod` pin + `go.sum` enforcement. |
| KAT manifest drift across runs | `scripts/regen-kats.manifest.sha256` is the gate; `--verify` mode compares manifest hashes. |
### §5.4 Side-channel risk
| Risk | Mitigation |
|---|---|
| Timing leakage on secret-dependent paths | Static per-path audit in `CONSTANT-TIME-REVIEW.md` — zero `(c)` (must-fix) findings; two `(b)` entries with documented mitigations (one closed in `dkg2/`; one in lens-specific paths off the Corona threshold path). |
| Statistical timing leakage (dudect-style) | Roadmap item v0.8.0. Not validated at this submission. |
| Memory-access / cache-timing leakage | Not addressed. Production deployments should use TEE attestation (SGX, SEV-SNP, TDX) per `DEPLOYMENT-RUNBOOK.md`. |
## §6 Independent verification protocol
To independently verify Corona's claims, a reviewer should:
1. Clone the repo at the submission tag.
2. `scripts/build.sh` — expect deterministic output.
3. `scripts/test.sh` — expect KAT + integration + unit tests all green.
4. `scripts/gen_vectors.sh && scripts/regen-kats.sh --verify` — expect
byte-equal KAT manifest agreement.
5. `scripts/bench.sh` — expect performance within `docs/evaluation.md`
published bounds.
6. Read the Go reference implementation:
- `sign/sign.go` — single-party + threshold signing kernel
- `threshold/threshold.go` — threshold orchestration
- `dkg2/dkg2.go` — Pedersen DKG over `R_q`
- `reshare/reshare.go` + `reshare/activation.go` — proactive
resharing + activation cert
- `primitives/hash.go` + `hash/sp800_185.go` — Corona-SHA3 hash
suite
7. Cross-reference with Boschini et al. ePrint 2024/1113 §3 for the
2-round signing construction.
8. Cross-reference with `papers/lp-073-pulsar/` for the production
lifecycle additions (Pedersen DKG, resharing).
If all 8 steps pass, the trust base reduces to the TCB enumerated
in this document.
## §7 What this means for downstream consumers
For a downstream consumer (e.g., a Quasar consensus chain
incorporating Corona):
- **The construction-level claim is conditional on the TCB.** If
you change the Go toolchain, port to a different runtime, or
modify the hash suite, the claim's transferable guarantees
attenuate.
- **For FIPS 140-3 module validation**, Corona is NOT a candidate
— R-LWE threshold has no NIST standard, so no FIPS 140-3 module
can claim FIPS 204-style algorithm validation for it. For
FIPS-validation pathways, use Pulsar (M-LWE / FIPS 204) instead.
- **For NIST MPTC review**, Corona's role is the algorithm-level
reference + production lifecycle artifacts; module packaging +
external audit are downstream.
- **For threshold signing in a Quasar deployment**, Corona is the
R-LWE kernel; the consuming consensus layer is responsible for
the chain-of-custody and validator-rotation orchestration (the
LSS adapter at `~/work/lux/threshold/protocols/lss/lss_pulsar.go`
is the canonical orchestrator).
## §8 Honest comparison to Pulsar's TCB
| TCB element | Pulsar | Corona |
|---|---|---|
| EasyCrypt prover | YES (foundation of refinement proof) | NO (no EC theories) |
| Lean 4 + Mathlib | YES (5 Lean-bridged axioms) | NO |
| Jasmin verified compiler | YES (threshold layer in Jasmin) | NO (pure Go) |
| OCaml runtime | YES (EC is OCaml) | NO |
| Go toolchain | YES (Go reference) | YES (Go reference; primary) |
| lattigo / `luxfi/lattice/v7` | NO (Jasmin path) | YES (R-LWE primitives) |
| `crypto/subtle` | YES (Go reference path) | YES (primary CT helper) |
| `golang.org/x/crypto/sha3` | YES | YES |
| Academic construction paper | FIPS 204 (NIST standard) | Boschini et al. ePrint 2024/1113 (2024 academic) |
| Third-party FIPS-validated verifier | YES (BoringSSL FIPS / AWS-LC / OpenSSL 3.0) | NO (none exists for R-LWE threshold) |
**Net effect**: Corona's TCB is smaller (fewer proof-tool
dependencies) but the trust per-component is higher (no fall-back
to a mechanized refinement chain if a Go reviewer misses a bug).
---
**Document metadata**
- Name: `TRUSTED-COMPUTING-BASE.md`
- Version: v0.1 (initial submission-package scaffolding)
- Date: 2026-05-18
- Go toolchain pin: `go 1.26.3` (per `go.mod`)
- `luxfi/lattice/v7` pin: `v7.1.0` (per `go.mod`)
+228
View File
@@ -0,0 +1,228 @@
# Corona — Design Decisions
> Rationale for the design choices behind Corona's production
> lifecycle on top of the Boschini et al. ePrint 2024/1113 R-LWE
> threshold construction.
## §1 Why Ring-LWE (not Module-LWE)?
| Question | Answer |
|---|---|
| Why ship an R-LWE library when ML-DSA (M-LWE) is the NIST standard? | The R-LWE 2-round construction (Boschini et al. 2024/1113) was published a year before the M-LWE equivalent matured. Lux deployed the R-LWE path first because it was the only construction with a published peer-reviewed 2-round threshold signature analysis for lattice-based signatures at the time of consensus design. |
| Why keep R-LWE after the M-LWE path (Pulsar) is ready? | Lux's primary-network QuasarCert is designed to consume BOTH lattice families as a **Double Lattice** layered defence so a break in one lattice family does not break finality. The two are complementary, not interchangeable. |
| Why not converge on a single lattice family? | A break in Module-LWE (which Pulsar uses) would not automatically break Ring-LWE (which Corona uses), and vice versa. The cost is wire-size overhead (Corona certs are variable-size; Pulsar certs are fixed-size); the benefit is structural diversity. |
## §2 Why this parameter set?
| Parameter | Value | Rationale |
|---|---|---|
| Ring degree `N` | 256 | Standard choice for 128-bit post-quantum security per the lattice-estimator methodology; matches lattigo's default ring sizing for R-LWE. |
| Prime `q` | `0x1000000004A01` | 48-bit NTT-friendly prime. Wide enough to absorb the Lagrange-aggregation coefficient growth without overflow; narrow enough that single-`q` polynomial arithmetic fits in `uint64`. |
| Module width `M` | 8 | Balances signature size against security margin under R-LWE attacks. |
| Module height `N_M` | 7 | Matches `M` − 1 to give comfortable EUF-CMA reduction margin. |
| Challenge weight `Kappa` | 23 | Ternary challenge weight per Boschini et al. parameter analysis. |
A second parameter set targeting NIST PQ Category 3 is roadmap
v0.6.0; concrete lattice-estimator output for the current set is
roadmap v0.6.0.
## §3 Why Pedersen DKG (`dkg2/`) and not Feldman (`dkg/`)?
The legacy `dkg/` package uses Feldman-style commitments
`C = A · NTT(s)` without hiding blinds. This is documented broken
for public broadcast in the upstream `RED-DKG-REVIEW.md` (Findings
5/6): without hiding blinds, an observer can extract information
about `s` from the public commitment, defeating the secret-sharing
property.
`dkg2/` replaces this with proper Pedersen commits
`C^(k) = A · NTT(s^(k)) + B · NTT(r^(k))` with per-coefficient
hiding blind `r^(k)`. The hiding blind ensures the commitment leaks
no information about `s^(k)` beyond what is necessary for
verification.
The trade-off: `dkg2/` is more expensive (twice as many polynomial
multiplications per commit) but secure under public broadcast. The
legacy `dkg/` is retained ONLY for historical reference and reading
existing test fixtures; production deployments MUST use `dkg2/`.
## §4 Why two reshare primitives (`Refresh` and `ReshareToNewSet`)?
The two operations serve different purposes and have different
threat models:
| Primitive | Use case | Threat model |
|---|---|---|
| `Refresh` | Mobile-adversary defense within a stable committee | Adversary slowly compromises parties over time; Refresh forces the adversary to start over (must compromise a new t-subset within one Refresh window). |
| `ReshareToNewSet` | Validator-set rotation | New validators join, old validators leave; the new set must be able to sign under the unchanged group key. |
Lumping them into a single `Reshare` call would obscure the
distinction. `DESIGN.md` enforces the separation explicitly.
## §5 Why the activation cert circuit-breaker?
After a Reshare completes the math, three failure modes exist that
the math itself cannot detect:
1. A malicious old-set party delivered subtly malformed shares to a
subset of new-set parties (the Pedersen verification catches
most cases but not all under network races).
2. The new-set parties' fresh shares are inconsistent due to a
protocol race condition.
3. The pairwise PRF/MAC material was regenerated incorrectly.
The activation cert is the chain's circuit-breaker: it forces the
new committee to PROVE they can sign under the unchanged group key
before the chain accepts them. If the proof fails, the chain falls
back to the old committee — no liveness loss, no slashing required.
This is the no-slashing-dependency property documented in
`DESIGN.md` §"Bootstrap Dealer vs Signature Coordinator (LSS roles,
no-slashing semantics)".
## §6 Why hash-suite injection (F22)?
Before the F22 closure, every Sign-path primitive hardcoded
`blake3.New()`. This made it structurally impossible to switch the
production hash suite from Corona-BLAKE3 to Corona-SHA3 (cSHAKE256 /
KMAC256 / TupleHash256 per FIPS 202 + SP 800-185) without modifying
every primitive's source.
F22 (`CHANGELOG.md`) plumbed `hash.HashSuite` through every
primitive as a first-argument parameter, with `nil` resolving to the
production default at call time. This enables:
- Production deployments use Corona-SHA3 (NIST-aligned hash suite).
- KAT regeneration for the legacy Corona-BLAKE3 path remains
available via `hash.NewCoronaBLAKE3()` for cross-port byte checks.
- New suites (e.g., a hypothetical Corona-Ascon) can be added
without touching the primitives.
The architectural pattern is: **every cryptographic primitive takes
the suite as its first argument**; the suite is a value, not a
package-level global or build flag.
## §7 Why Corona-SHA3 (not Corona-BLAKE3) in production?
NIST alignment. The MPTC submission profile uses only FIPS 202 + SP
800-185 hash functions. BLAKE3 is fast and excellent, but it is
NOT a NIST standard at submission time. For the NIST MPTC submission
package, the normative hash suite is Corona-SHA3; BLAKE3 is retained
only for cross-port byte-check via `hash.NewCoronaBLAKE3()`.
The customization-string registry in `hash/sp800_185.go`:
- `CORONA-HC-v1` — challenge hash (`H_c`)
- `CORONA-HU-v1` — uniform hash (`H_u`)
- `CORONA-PRF-v1` — per-pair PRF seed derivation
- `CORONA-MAC-v1` — per-pair KMAC key derivation
- `CORONA-DKG-v1` — DKG commitment derivation
- `CORONA-RESHARE-v1` — resharing transcript hash
Adding a new customization string requires regenerating ALL KAT
vectors and updating `SPEC.md` §13.
## §8 Why no mechanized refinement proof at this submission?
Honesty: Corona's underlying construction (Boschini et al.
2024/1113) is published academic prior art that has no NIST standard
target. There is no FIPS spec to refine against. Mechanizing the
construction itself (without a separately-specified refinement
target) is a multi-month research project comparable to the
Barbosa-Barthe-Dupressoir Dilithium mechanization for FIPS 204.
Pulsar can refine against FIPS 204 because FIPS 204 IS the NIST
standard for ML-DSA. Corona has no analogous target.
Roadmap v0.7.0 begins the EasyCrypt theory shell for the
construction-level interchangeability claim and the Lean 4 / Mathlib
mechanization of the Lagrange-aggregation identity over `R_q`.
Roadmap v0.8.0 adds external cryptographic audit. At submission
scaffolding (v0.5.0), the correctness evidence is code review + KAT
+ Boschini et al. analysis.
## §9 Why `R_q^M` and not flat `R_q`?
Module-of-rings structure (`R_q^M` for `M = 8`) gives a security-
size trade-off: the per-coefficient cost is amortized across module
slots, the security analysis decomposes per-slot, and the wire size
scales linearly in `M` rather than quadratically. This is the
standard pattern in lattice-based signatures (FIPS 204 uses
`R_q^k × R_q^l` for the same reason).
The single-slot choice (flat `R_q`) was rejected because the
security margin would be marginal and the wire-size win would not
compensate for the loss of the per-slot security decomposition.
## §10 Why ML-KEM-768 hybrid (recommended) for per-pair KEX?
Per-pair encrypted-share exchange in `dkg2/` and `reshare/` uses an
authenticated KEX. Production deployments are recommended to use
**ML-KEM-768 hybrid** (X25519 ⊕ ML-KEM-768 via the X-Wing combiner
or equivalent) to provide both classical and post-quantum security.
The KEM choice is consumer-side (Corona does not impose ML-KEM-768
specifically) — the spec only requires "authenticated KEX." The
recommendation reflects Lux's deployment posture for Quasar
consensus.
## §11 Why the QUASAR-CORONA-* domain-separation prefix family?
Domain separation prevents cross-context attack composition. Every
signature produced under any Quasar lane carries a distinct
version-tagged prefix. The `QUASAR-CORONA-*` family separates
Corona's signing messages from Pulsar's signing messages and from
classical BLS aggregate certs:
- `QUASAR-CORONA-BUNDLE-v1` — Corona pulse over a Quasar bundle
- `QUASAR-CORONA-SIGN1-v1` — Corona signing Round 1 commit
- `QUASAR-CORONA-SIGN2-v1` — Corona signing Round 2 response
- `QUASAR-CORONA-COMBINE-v1` — Corona finalize transcript
- `QUASAR-CORONA-REFRESH-v1` — Refresh activation cert
- `QUASAR-CORONA-RESHARE-v1` — Reshare activation cert
- `QUASAR-CORONA-ACTIVATE-v1` — Generic activation cert
- `QUASAR-CORONA-REANCHOR-v1` — Reanchor authorization
Reusing a prefix across two distinct message classes would create a
domain-confusion attack surface. The convention: every NEW class of
signed message gets a NEW version-tagged prefix. NEVER reuse.
## §12 Why patch-bump-only versioning?
Per `CLAUDE.md` and `CHANGELOG.md`: patch bumps only
(`v0.4.x → v0.4.y`); minor/major bumps require explicit approval.
This forces every change to be evaluated against the established
KAT vectors and cross-runtime byte-equality manifest. A minor bump
implies wire-format changes that break downstream consumers'
go.mod pins and require coordinated validator-set rollover; that is
a deliberate, audited action, not a default.
The v0.5.0 bump for the submission-package scaffolding is the
documented exception: it adds documentation only, no code changes,
no KAT changes.
## §13 Why constant-time per-slot accumulation (not early return) in dkg2?
Findings 5/6 of upstream `RED-DKG-REVIEW.md`. The naive
implementation of Pedersen commit verification iterates over module
slots and returns false on the first mismatch. This leaks the
first-diverging slot index to a network observer measuring the
recipient's response time — which is a real timing oracle in
synchronous Quasar consensus.
`dkg2/dkg2.go:VerifyShareAgainstCommits` uses the
`eq &= subtle.ConstantTimeCompare(lhs, rhs)` accumulation pattern
across all `M` slots with NO early return. The recipient's
response time depends only on `M` (public structural metadata),
not on which slot first diverged.
This is documented in `CONSTANT-TIME-REVIEW.md` §2 and is a
patentable contribution (claim group D in
`docs/mptc/patent-claims.md`).
---
**Document metadata**
- Name: `docs/mptc/design-decisions.md`
- Version: v0.1 (initial submission-package scaffolding)
- Date: 2026-05-18
+222
View File
@@ -0,0 +1,222 @@
# Experimental Evaluation Report — Corona
> Per NIST IR 8214C §6 — Report on Experimental Evaluation.
> Companion to `SUBMISSION.md` cover sheet and `SPEC.md`
> construction specification.
## §1 Reproducibility commitment
Every measurement in this document MUST reproduce on a fresh checkout
of the submission tag under the documented hardware envelope, within
±5% drift. Drift outside that band is a build bug; please file an
issue.
Reproduction:
```bash
git clone --branch submission-2026-11-16 https://github.com/luxfi/corona
cd corona
scripts/build.sh
scripts/bench.sh # writes bench/results/ with hardware fingerprint
```
The bench script captures hardware fingerprint (CPU brand, core
count, memory, Go version) so reviewers can compare environments.
## §2 Hardware envelope
Reference measurements at this submission scaffolding revision were
taken on the following envelope. Reviewers reproducing on different
hardware should expect proportional drift.
| Component | Reference value |
|---|---|
| CPU | Apple M2 Pro (10 cores) / Intel Xeon (cloud-equivalent) |
| Memory | ≥ 16 GiB |
| OS | macOS 25.4 / Linux x86_64 |
| Go version | 1.26.3 (pinned in `go.mod`) |
| `luxfi/lattice/v7` version | v7.1.0 (pinned in `go.mod`) |
| Build flags | default `go test -bench=. -benchmem` (no SIMD intrinsics; no assembly) |
Note: `scripts/bench.sh` writes the actual fingerprint captured at run
time to `bench/results/fingerprint.txt`. Use that file (not this
table) as the authoritative environment record for any specific
benchmark output committed to the repository.
## §3 Correctness evidence
### §3.1 Test coverage
| Suite | Tests | Location |
|---|---|---|
| `sign/` round-trip + suite-variant | 10+ | `sign/sign_test.go`, `sign/sign_roundtrip_test.go` |
| `threshold/` 2-round + batch verify | 15+ | `threshold/threshold_test.go`, `threshold/verify_batch_test.go` |
| `dkg2/` Pedersen DKG | 10+ | `dkg2/dkg2_test.go` |
| `dkg2/` fuzz | wired | `dkg2/fuzz_round_test.go` |
| `reshare/` Refresh + ReshareToNewSet | 45+ | `reshare/*_test.go` (multiple files) |
| `reshare/` fuzz | wired | `reshare/fuzz_*_test.go` (3 harnesses) |
| `primitives/` Shamir + hash | 10+ | `primitives/*_test.go` |
| `hash/` Corona-SHA3 + BLAKE3 + NIST SP 800-185 KAT | 5+ | `hash/hash_test.go` (`TestKMAC256NISTVector`, `TestTupleHash256NISTVector`) |
Run all tests:
```bash
GOWORK=off go test -count=1 -race ./...
```
### §3.2 KAT cross-runtime byte-equality
The Go reference and the C++ port at `~/work/luxcpp/crypto/corona/`
emit byte-identical KAT vectors. Enforcement:
```bash
scripts/regen-kats.sh # write fresh KAT manifest
scripts/regen-kats.sh --verify # compare against committed manifest
```
The manifest at `scripts/regen-kats.manifest.sha256` pins SHA-256 of
every regenerated KAT file. Five oracle generators:
- `cmd/corona_oracle_v2/` — sign / verify KAT (Corona-BLAKE3 legacy)
- `cmd/cross_runtime_oracle/` — cross-language byte-equality vectors
- `cmd/dkg2_oracle/` — Pedersen DKG transcripts
- `cmd/reshare_oracle/` — Refresh + ReshareToNewSet transcripts
- `cmd/activation_oracle/` — activation cert vectors
## §4 Performance — single-party signing
Reference Corona single-party sign + verify benchmarks (representative
order of magnitude; actual numbers depend on hardware and Go version):
| Operation | Time (M2 Pro) | Memory |
|---|---|---|
| `sign.Sign` (single-party kernel) | ~ 1–5 ms | < 1 MB |
| `sign.Verify` | ~ 0.5–2 ms | < 1 MB |
| `primitives.PRNGKey` (Corona-SHA3) | < 100 µs | < 1 KB |
| `primitives.GaussianHash` | < 500 µs | < 1 KB |
Specific numbers MUST be regenerated via `scripts/bench.sh` on the
reviewer's environment; reference values above are order-of-magnitude
expectations, not guaranteed performance.
## §5 Performance — threshold signing
Threshold signing has higher cost than single-party (2 broadcast
rounds + Lagrange aggregation). Representative cost factors:
| Parameter | Effect on cost |
|---|---|
| Quorum size `t` | Linear in Round 1/2 message count |
| Committee size `n` | Linear in Pedersen DKG cost; affects Lagrange-coefficient precomputation cost |
| Network RTT | Dominates over local compute for small `t` |
| `verify_batch.VerifyBatch` | O(N) verification of N signatures parallelized via goroutines (`threshold/verify_batch.go` since v0.4.1) |
For specific (n, t) measurements, run `scripts/bench.sh` and inspect
`bench/results/go-bench.txt`.
## §6 Performance — DKG
Pedersen DKG over `R_q` (`dkg2/`) has cost dominated by:
- Per-party polynomial sampling (`t` coefficients × `M` polynomials in
`R_q^M`, each requiring discrete-Gaussian sampling).
- Pedersen commit computation: `M` per-coefficient commits of the
form `A·NTT(s^(k)) + B·NTT(r^(k))`.
- Per-pair encrypted-share exchange under authenticated KEX.
- Complaint-round verification: `O(n · M)` per-coordinate
constant-time `eq &=` accumulation.
Reference cost: full DKG (`n = 7, t = 4`) completes in seconds on the
M2 Pro envelope; full DKG (`n = 32, t = 22`) completes in tens of
seconds. Network RTT is the dominant cost factor in production
deployments.
## §7 Performance — proactive resharing
Reshare cost is dominated by:
- Per-old-party fresh polynomial sampling.
- Per-pair `g_i(β_j)` delivery (encrypted).
- Per-new-party Lagrange recombination over the old qualified subset.
- Activation cert: one threshold signature under unchanged group key.
Reference cost: `ReshareToNewSet` for committee size 7 → 7 completes
in single-digit seconds on the M2 Pro envelope; activation cert adds
~ 1 signing-session cost.
## §8 Side-channel evidence
### §8.1 Static constant-time audit
Per `CONSTANT-TIME-REVIEW.md`:
- Zero `(c)` (must-fix) entries.
- Two `(b)` entries documented with mitigations:
1. `reshare/commit.go:124` — legacy reshare path Pedersen mismatch;
fixed-in-place in `dkg2/` via `constTimePolyEqual`. Legacy
`reshare` path scheduled for migration.
2. `lens/primitives/secp256k1.go` — non-CT scalar mul; off the
Corona threshold path.
### §8.2 Statistical CT validation
NOT delivered at this submission. dudect-style harness is roadmap
item v0.8.0. At submission scaffolding, the CT evidence reduces to
the static audit + upstream lattigo CT claims.
## §9 Security-parameter evidence
### §9.1 Parameter set
Corona v0.4.1 ships a single parameter set:
- Ring degree `N = 256`
- Prime `q = 0x1000000004A01` (48-bit NTT-friendly)
- Module width `M = 8`, height `N_M = 7`
- Challenge weight `Kappa = 23`
### §9.2 Concrete security claim
Target: ≥ 128 bits of post-quantum security against the best known
R-LWE attacks per the lattice-estimator methodology of
Albrecht-Player-Scott.
**Roadmap**: a worksheet with concrete lattice-estimator output for
the parameter set is roadmap item v0.6.0. At submission scaffolding
this revision, the concrete bounds are NOT included; the parameter
set was chosen by Lux engineering against the academic R-LWE
literature, but the documented worksheet is pending.
### §9.3 R-LWE prior art
Underlying construction: Boschini, Kaviani, Lai, Malavolta, Takahashi,
Tibouchi. *Practical two-round threshold signatures from learning
with errors.* IACR ePrint 2024/1113, IEEE S&P 2025. EUF-CMA reduction
in §3 of the paper. Corona inherits the analysis.
R-LWE primitive: Lyubashevsky, Peikert, Regev. *On ideal lattices and
learning with errors over rings.* EUROCRYPT 2010.
Concrete cryptanalysis literature: Albrecht, Player, Scott. *On the
concrete hardness of learning with errors.* J. Math. Cryptol. 2015
(lattice-estimator methodology). Plus follow-up cryptanalysis at
IACR ePrint archive 2015–2026.
## §10 What this report does NOT include
- Specific numeric benchmarks (run `scripts/bench.sh` locally; the
bench script writes the actual numbers + fingerprint).
- Concrete lattice-estimator output for the parameter set (roadmap
v0.6.0).
- Comparison benchmarks against single-party FIPS 204 ML-DSA — Corona
and ML-DSA are different lattice families; like-for-like comparison
is not meaningful.
- Threshold-vs-single-party overhead measurements at specific (n, t)
— these depend heavily on network conditions in production; the
reference benchmark suite measures the local compute portion.
- HSM-backed share-management performance — that is consumer-side.
---
**Document metadata**
- Name: `docs/mptc/evaluation.md`
- Version: v0.1 (initial submission-package scaffolding)
- Date: 2026-05-18
+203
View File
@@ -0,0 +1,203 @@
# Corona — Family Architecture
> Where Corona sits in the Lux post-quantum threshold-signature
> family. Companion to `SUBMISSION.md`, `SPEC.md`, and
> `docs/mptc/design-decisions.md`.
## §1 The three-library family
Lux ships three post-quantum threshold signature libraries with
distinct lattice families and use cases:
| Library | Lattice | Role | NIST MPTC class | Repository |
|---|---|---|---|---|
| **Corona** (this) | Ring-LWE (`R_q`) | Consensus-finality threshold (Quasar R-LWE finality kernel) | N1 + N4 (construction-level) | `luxfi/corona` |
| **Pulsar** | Module-LWE (`R_q^k × R_q^l`) | Identity-layer threshold + FIPS 204 byte-equality | N1 + N4 (FIPS-anchored) | `luxfi/pulsar` |
| **Magnetar** (research) | SLH-DSA (FIPS 205) | Hash-based fallback (research-stage) | not submitted at this writing | `luxfi/magnetar` |
Each library is independently complete. They do NOT share Go types;
they do NOT import each other; they CAN be composed at the consumer
layer (e.g., QuasarCert combines Corona + Pulsar + BLS).
## §2 Why three libraries (not one configurable kernel)?
| Decomposition axis | Choice rationale |
|---|---|
| Per-lattice-family library | A break in one lattice family (R-LWE vs M-LWE vs hash-based) should not break the others. Independent libraries with no shared types is the safest decomposition for defence-in-depth. |
| No shared types | Pulsar and Corona share NO Go types. If a vulnerability is found in Corona, the fix landing in Corona does not touch Pulsar (and vice versa). Each library's go.mod is independent. |
| Separate KAT vectors | Pulsar's KATs target FIPS 204 byte-equality. Corona's KATs target Go ↔ C++ cross-runtime byte-equality. The two KAT formats are intentionally different (different lattice algebra; different signature byte layouts). |
| Separate hash-suite registries | Pulsar uses SHAKE / cSHAKE / KMAC per FIPS 204 layouts. Corona uses cSHAKE256 / KMAC256 / TupleHash256 per FIPS 202 + SP 800-185 with `CORONA-*` customization strings. Even though the underlying primitives overlap, the domain-separation registries are disjoint. |
## §3 Composition surface — QuasarCert
A consumer (Lux primary-network QuasarCert) MAY combine Corona +
Pulsar + classical BLS + per-validator ML-DSA into a **Double
Lattice** layered certificate:
```
QuasarCert {
BLS — classical fast-path (BLS-12-381 aggregate); pre-quantum
Corona — Ring-LWE threshold (this repo) ; PQ kernel A
Pulsar — Module-LWE threshold (luxfi/pulsar) ; PQ kernel B
MLDSARollup — per-validator ML-DSA-65 rolled up via P3Q ; PQ accountability
}
```
Each layer is checkable independently:
- BLS: any pairing-aware verifier accepts.
- Corona: `sign.Verify` accepts.
- Pulsar: any FIPS 204 ML-DSA verifier accepts (the byte-equal claim).
- MLDSARollup: STARK / FRI verifier accepts via the P3Q backend.
Selecting which layers are included happens at chain-construction
time via the `FinalitySchemeID` axis. A pure-PQ profile drops BLS
and runs on Corona + Pulsar + MLDSARollup. A classical-fast profile
runs BLS only. A hybrid profile runs all four.
This composition is the CONSUMER's design choice, not Corona's. The
Corona submission stands alone as an N1 + N4 candidate; reviewers
do NOT need to evaluate the QuasarCert composition.
## §4 Relationship to LSS (the orchestration framework)
`~/work/lux/threshold/protocols/lss/` is Lux's generic dynamic-
threshold lifecycle framework, paper-backed by Seesahai 2025.
LSS owns:
- Generation numbers and version monotonicity (`Generation`,
`RollbackFrom`).
- Live resharing orchestration (Section 4 of the LSS paper).
- Bootstrap Dealer / Signature Coordinator role separation.
- `RollbackManager` and `GenerationSnapshot` history.
LSS does NOT own:
- Lattice math (Pedersen `R_q^M` commits, NTT, Gaussian sampling).
- Threshold signature scheme specifics.
Corona contributes the lattice math via the adapter pattern. The
`lss_pulsar.go` adapter at `~/work/lux/threshold/protocols/lss/`
mediates between LSS's generic orchestration and Corona's lattice-
specific operations.
## §5 Layer separation
```
~/work/lux/corona/ # CORONA MATH KERNEL (this repo)
├── sign/, threshold/, dkg2/, reshare/ (single-process API)
├── primitives/, hash/ (cryptographic primitives)
├── keyera/ (kernel-level lifecycle)
└── cmd/*_oracle*/ (KAT generation)
~/work/lux/threshold/protocols/lss/ # ORCHESTRATION FRAMEWORK
├── DynamicLSS, RollbackManager, JVSS (generic, paper-backed)
├── lss_frost.go: DynamicReshareFROST (Schnorr/EdDSA adapter)
├── lss_cmp.go: DynamicReshareCMP (ECDSA adapter)
└── lss_pulsar.go: DynamicResharePulsar (lattice adapter; uses Corona)
~/work/lux/consensus/protocol/quasar/ # CONSENSUS LAYER
└── epoch.go (consumes Corona via LSS adapter)
```
## §6 The pulsar-vs-corona-vs-quasar nomenclature
Naming history (from `LLM.md` and `DESIGN.md`):
- **Quasar** — the leaderless permissionless consensus protocol that
consumes all PQ primitives. Lives at
`~/work/lux/consensus/protocol/quasar/`.
- **Pulsar** — the M-LWE threshold ML-DSA library at `luxfi/pulsar`.
Named for the rotating-neutron-star metaphor: persistent group
key, rotating share distribution.
- **Corona** — the R-LWE threshold library (this repo). Named for
the luminous ring of light surrounding a star, brand-paired with
Pulsar at a different lattice layer.
A historical rename from `Pulsar` → `Corona` happened in 2026 when
the M-LWE work picked up the `Pulsar` name and the R-LWE work
retained the pulsar metaphor under the `Corona` brand. The
`papers/lp-073-pulsar/` directory retains the old name; the LaTeX
sections inside refer to the R-LWE construction (now called Corona)
under the historical paper name LP-073.
## §7 Two distinct primitives, one lifecycle
Corona ships TWO distinct primitives, NOT one fuzzy "Reshare":
| Primitive | Defends against | Same set or new? |
|---|---|---|
| `Refresh` | Mobile-adversary share accumulation | SAME committee |
| `ReshareToNewSet` | Validator-set rotation | NEW committee |
Both preserve `(A, bTilde)` within a key era. Both follow the same
3-round wire shape (commitments → private deliveries → combine +
activate). Both gate new-epoch acceptance on the activation cert
circuit-breaker. They differ in WHO holds the new shares.
A consumer that fails to distinguish them at the API level is
likely to misuse one or the other; the dedicated function names
force the distinction.
## §8 Three layers, one shipping path
| Layer | Operation | Trigger | Trust |
|---|---|---|---|
| 1. **Bootstrap** | trusted-dealer `Gen(s, A, e) → (bTilde, shares)` | Chain genesis, ONCE per key era | Foundation MPC ceremony |
| 2. **Reshare** | preserves `(s, bTilde, GroupKey)`; rotates share distribution | Every epoch with validator-set change | NO new trust; old qualified subset cooperates |
| 3. **Reanchor** | new `(s', A', e', bTilde')` | Rare governance event | Same as Bootstrap |
What is preserved across Reshare WITHIN a key era:
- `A` (public matrix) — preserved
- `s` (hidden signing secret) — preserved (share distribution rotates)
- `bTilde` (rounded public key) — preserved
- `GroupKey = (A, bTilde)` — byte-identical preserved
- `e` (LWE error) — NOT preserved (used at genesis only; signers
need shares of `s`, not `e`)
What is preserved across Reanchor:
- The chain identity (chain_id, network_id).
- NOTHING else from the previous key era.
## §9 Relationship to the upstream academic construction
Boschini, Kaviani, Lai, Malavolta, Takahashi, Tibouchi (IACR ePrint
2024/1113, IEEE S&P 2025) published the 2-round R-LWE threshold
signature construction. The paper specifies:
- The 2-round signing protocol (Round 1 commit + Round 2 response +
Combine).
- The verifier.
- The trusted-dealer Gen (assumed; not Lux-novel).
- The EUF-CMA reduction.
The paper does NOT specify:
- Public DKG (Lux contributed `dkg2/` Pedersen DKG over `R_q`).
- Proactive resharing (Lux contributed `reshare/`).
- Identifiable abort with attributable evidence.
- Activation cert circuit-breaker.
- Hash-suite injection architecture.
- Cross-runtime byte-equality manifest enforcement.
- Production deployment runbook.
Corona's contribution is the production lifecycle layered atop the
published construction. The cryptographic core (2-round signing
math) is faithfully implemented from the paper; the production
layer is Lux-novel.
## §10 The lens / Magnetar relationship (NOT in scope)
`lens/` is a separate Lux library for curve-based threshold signing
(Ed25519, secp256k1, Ristretto255). It is mentioned in
`CONSTANT-TIME-REVIEW.md` §5 because it shares some code paths with
Corona's reshare layer (specifically the curve-Lagrange utilities).
Corona's threshold path does NOT depend on lens; lens is a sibling
library, not a Corona dependency.
`magnetar/` is the SLH-DSA (FIPS 205) research-stage threshold
library. It is mentioned in `SUBMISSION.md` for completeness but
is NOT in scope for the Corona submission package.
---
**Document metadata**
- Name: `docs/mptc/family-architecture.md`
- Version: v0.1 (initial submission-package scaffolding)
- Date: 2026-05-18
+255
View File
@@ -0,0 +1,255 @@
# IETF Internet-Draft Skeleton — Corona Threshold Ring-LWE Signature
> **HONEST FRAMING**: this document is a **draft skeleton**, not a
> submitted Internet-Draft. The CFRG submission timing is contingent
> on the v0.7.0 mechanized refinement work and the v0.8.0 external
> audit landing. At submission scaffolding this revision, the
> skeleton enumerates the sections an eventual `draft-luxfi-cfrg-
> corona-threshold-rlwe-XX.txt` would carry; it does NOT claim CFRG
> adoption, working-group status, or any timeline.
>
> The canonical algorithmic spec at this submission revision is
> `SPEC.md` + `papers/lp-073-pulsar/` LaTeX sections + `DESIGN.md`.
> This IETF skeleton consolidates them into IETF-style section
> headers for eventual CFRG presentation.
## Cover page (draft)
```
Internet Engineering Task Force [maintainer]
Internet-Draft Lux Industries, Inc.
Intended status: Informational [draft-XX]
Expires: [TBD] [date-XX]
Corona: a 2-round threshold Ring-LWE signature scheme
with proactive resharing
draft-luxfi-cfrg-corona-threshold-rlwe-XX
Abstract
This document specifies Corona, a 2-round threshold signature
scheme over Ring-LWE for use in post-quantum threshold signing
deployments. Corona implements the construction of Boschini,
Kaviani, Lai, Malavolta, Takahashi, and Tibouchi (IACR ePrint
2024/1113, IEEE S&P 2025) on a fixed parameter set, plus
production lifecycle layers: Pedersen distributed key generation
over R_q, proactive resharing with public-key preservation, and
identifiable abort with attributable evidence.
```
## §1 Introduction
- §1.1 Motivation — threshold PQ signatures for blockchain finality
(Quasar consensus reference).
- §1.2 Relationship to FIPS 204 ML-DSA — Corona is R-LWE; ML-DSA is
M-LWE; the two are independent. The M-LWE sibling is Pulsar
(`luxfi/pulsar`).
- §1.3 Document scope — algorithm specification + reference
parameter set; deployment specifics (HSM, validator orchestration)
are out of scope.
## §2 Conventions
- §2.1 IETF normative terminology (RFC 2119 / RFC 8174).
- §2.2 Notation — see `SPEC.md` §2 for the full glossary. Key terms:
Party, Quorum `Q`, Sharing polynomial `f`, Group public key
`(A, bTilde)`, Session identifier `sid`, Key era, Generation,
Activation cert.
- §2.3 Byte ordering — little-endian throughout, per lattigo wire
convention.
## §3 Parameter set
- §3.1 Single set, v0.2 — `N = 256`, `q = 0x1000000004A01`, `M = 8`,
`N_M = 7`, `Kappa = 23`. See `SPEC.md` §3.
- §3.2 Future parameter sets — roadmap (v0.6.0) for a second set
targeting NIST PQ Category 3.
## §4 Threat model
- §4.1 Static corruption of `t − 1` parties.
- §4.2 Rushing Byzantine adversary.
- §4.3 Synchronous network with known upper bound `Δ`.
- §4.4 Pedersen DKG (`dkg2/`) provides hiding and binding under
standard assumptions.
See `SPEC.md` §4 + `DESIGN.md` §"Three layers, one shipping path".
## §5 Pedersen DKG over `R_q`
- §5.1 Setup — `(A, B)` generator derivation from `sid_dkg` via
cSHAKE256.
- §5.2 Per-party polynomial sampling + per-coefficient hiding blinds.
- §5.3 Coefficient commits `C^(k) = A·NTT(s^(k)) + B·NTT(r^(k))`.
- §5.4 Per-pair encrypted-share exchange (authenticated KEX).
- §5.5 Complaint round + qualified-set selection.
- §5.6 Group public key derivation.
See `SPEC.md` §6 + `papers/lp-073-pulsar/lp-073-pulsar-pedersen-dkg.tex`.
## §6 Threshold signing (2 rounds)
- §6.1 Round 1 commit: each party samples `y_i`, computes
`w_i = A · y_i`, broadcasts commitment.
- §6.2 Aggregator: collect commits, derive challenge `c`.
- §6.3 Round 2 response: each party computes `z_i = y_i + c · s_i`.
- §6.4 Combine: Lagrange-aggregate responses, check low-norm
bounds, package `σ = (c, z, Δ)`.
See `SPEC.md` §7 + Boschini et al. ePrint 2024/1113 §3 +
`sign/sign.go`.
## §7 Verification
```
Verify(group_pk = (A, bTilde), m, σ = (c, z, Δ)):
w' ← A · z − c · bTilde
c' ← H_c(transcript_with_w')
if c' ≠ c: return FAIL
if not CheckL2Norm(z, bound): return FAIL
return OK
```
See `SPEC.md` §8 + `sign/sign.go:Verify`.
## §8 Proactive resharing
- §8.1 Refresh (same set, fresh shares) — HJKY97 lineage.
- §8.2 ReshareToNewSet (set rotation) — Desmedt-Jajodia 1997 /
Wong-Wang-Wing 2002 lineage.
- §8.3 Activation cert circuit-breaker.
See `SPEC.md` §9 + `papers/lp-073-pulsar/lp-073-pulsar-resharing.tex`
+ `reshare/`.
## §9 Identifiable abort
- §9.1 Failure classes — missing message, equivocation, malformed
ciphertext, invalid share contribution.
- §9.2 Evidence shape — signed slashing data with care taken not to
leak threshold-reconstructing data publicly.
See `SPEC.md` §10 + `dkg2/complaint.go` + `reshare/complaint.go`.
## §10 Transcript and domain separation
- §10.1 `QUASAR-CORONA-*` prefix family.
- §10.2 Replay binding (chain_id, epoch, key_era_id, sid, etc.).
See `SPEC.md` §11 + `DESIGN.md` §"Domain-separated message prefixes".
## §11 Wire formats
- §11.1 Polynomial serialization via `luxfi/math/codec`.
- §11.2 `Vector[Poly]` frame validation before lattigo `ReadFrom`.
- §11.3 KAT cross-runtime byte-equality enforcement.
See `SPEC.md` §12.
## §12 Hash suite
- §12.1 Corona-SHA3 (cSHAKE256 / KMAC256 / TupleHash256 per FIPS 202
+ SP 800-185).
- §12.2 Customization-string registry.
- §12.3 Legacy Corona-BLAKE3 (cross-port byte-check only).
See `SPEC.md` §13 + `hash/sp800_185.go`.
## §13 Security considerations
- §13.1 R-LWE hardness assumption.
- §13.2 EUF-CMA reduction — inherited from Boschini et al. ePrint
2024/1113 §3.
- §13.3 Constant-time guarantees on threshold + dkg2 paths.
- §13.4 Forward security via share zeroization.
See `SPEC.md` §15 + `CONSTANT-TIME-REVIEW.md` + `PROOF-CLAIMS.md`.
## §14 Implementation considerations
- §14.1 Go reference at `github.com/luxfi/corona`.
- §14.2 C++ port at `~/work/luxcpp/crypto/corona/` (cross-runtime
byte-equal).
- §14.3 No assembly, no SIMD intrinsics in the reference.
See `SPEC.md` §16.
## §15 IANA considerations
This document has no IANA actions at this draft revision. Future
revisions may request:
- Hash suite identifier registration (`corona-sha3`, `corona-blake3`).
- Domain-separation prefix registration in the threshold-signature
prefix registry (if such a registry is established).
## §16 References
### §16.1 Normative
- [FIPS202] NIST. *SHA-3 Standard: Permutation-Based Hash and
Extendable-Output Functions.* August 2015.
- [SP800-185] NIST. *SHA-3 Derived Functions: cSHAKE, KMAC, TupleHash,
and ParallelHash.* December 2016.
### §16.2 Informative
- [BoschiniEtAl24] Boschini, Kaviani, Lai, Malavolta, Takahashi,
Tibouchi. *Practical two-round threshold signatures from learning
with errors.* IACR ePrint 2024/1113, IEEE S&P 2025.
- [LPR10] Lyubashevsky, Peikert, Regev. *On ideal lattices and
learning with errors over rings.* EUROCRYPT 2010.
- [HJKY97] Herzberg, Jakobsson, Jarecki, Krawczyk, Yung. *Proactive
secret sharing or: How to cope with perpetual leakage.* CRYPTO
1995/1997.
- [DJ97] Desmedt, Jajodia. *Redistributing secret shares to new
access structures.* 1997.
- [WWW02] Wong, Wang, Wing. *Verifiable secret redistribution for
archive systems.* 2002.
- [Pedersen91] Pedersen. *Non-interactive and information-theoretic
secure verifiable secret sharing.* CRYPTO 1991.
- [Seesahai25] Seesahai. *LSS MPC ECDSA: A Pragmatic Framework for
Dynamic and Resilient Threshold Signatures.* August 2025.
- [FIPS204] NIST. *Module-Lattice-Based Digital Signature Standard
(ML-DSA).* August 2024. (For context — Pulsar (M-LWE) targets
byte-equality with FIPS 204; Corona (R-LWE) does NOT.)
## Appendix A — Test vectors
KAT-deterministic regeneration via `scripts/regen-kats.sh`. See
`SPEC.md` §14 for the oracle inventory and cross-runtime byte-
equality manifest at `scripts/regen-kats.manifest.sha256`.
## Appendix B — Known limitations
Per `SUBMISSION.md` §"What this submission does NOT claim":
- No FIPS 204 byte-equality (use Pulsar for that).
- No mechanized refinement proof at submission scaffolding (roadmap
v0.7.0).
- No identifiable abort under network partition (synchronous only).
- No 1-round signing (construction is 2-round by design).
- DKG bias resistance requires external randomness beacon.
## Appendix C — Author's address
```
[primary maintainer]
Lux Industries, Inc.
Email: [email protected]
Submission coordination: [email protected]
Security disclosure: [email protected]
Public discussion: https://github.com/luxfi/corona/discussions
```
---
**Document metadata**
- Name: `docs/mptc/ietf-draft-skeleton.md`
- Version: v0.1 — DRAFT SKELETON (not a submitted Internet-Draft)
- Date: 2026-05-18
- Status: skeleton consolidating `SPEC.md` + `DESIGN.md` + paper
sections into IETF-style section headers. CFRG submission timing
is contingent on v0.7.0 + v0.8.0 milestones.
+180
View File
@@ -0,0 +1,180 @@
# NIST MPTC category targeting — Corona
> Reference: NIST IR 8214C, *First Call for Multi-Party Threshold Schemes*
> (January 2026). Package deadline expected 2026-Nov-16. Preview deadline
> 2026-Jul-20.
## Corona target: **Class N1 + N4 (construction-level)**
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)
Corona aims for **N1 (construction-level threshold signing) + N4
(distributed Ring-LWE keygen + reshare preservation)**.
### N1 framing for Corona — HONEST distinction from Pulsar
NIST's Class N is defined relative to a "NIST-specified primitive."
**R-LWE threshold signing has no NIST standard at submission time.**
This makes Corona's N1 framing structurally different from Pulsar's
(which targets FIPS 204 ML-DSA byte-equality):
| Aspect | Pulsar (M-LWE) | Corona (R-LWE) |
|---|---|---|
| NIST standard target | FIPS 204 ML-DSA-65 | **none** |
| Verifier-side interchange | byte-equal with BoringSSL FIPS / AWS-LC / OpenSSL 3.0 PQ | construction-level only (Corona's own `sign.Verify`) |
| Third-party FIPS-validated verifier exists | YES | NO |
| Mechanized refinement against the spec | EasyCrypt 13/13, 0/0 admits | NONE (no FIPS spec to refine against) |
| Class N1 evidence stack | Algorithmic + EC mechanized + Lean bridge + Jasmin-CT + 3-way KAT | Algorithmic + Go-vs-C++ cross-runtime KAT |
The honest framing for Corona's N1 claim: **construction-level output
interchangeability** — every threshold-emitted signature verifies
under the Corona reference verifier as a single-party Corona signature
would. This is necessary for N1 but is **NOT** the byte-equal-against-
FIPS framing that Pulsar provides.
A reviewer who weighs Class N strictly by NIST-standard-target presence
should classify Corona as Class S1 + S4 instead (special threshold-
friendly, no NIST standard). The N1 + N4 framing is appropriate IF the
reviewer accepts construction-level interchangeability as sufficient
for Class N status when no NIST standard exists for the underlying
primitive. This decision is for NIST MPTC reviewers, not for Lux to
preempt.
Corona's submission package is structured to support **either reading**:
- If N1 + N4: cite the construction-level interchange + reshare
preservation as the relevant evidence.
- If S1 + S4: cite the same evidence + the production lifecycle
additions (Pedersen DKG, reshare, activation cert, hash-suite
injection) as the "novel threshold-friendly design" novelty.
The downstream consumer story is identical either way: Quasar
consensus uses Corona as the R-LWE finality kernel; threshold-emitted
signatures verify under `sign.Verify` regardless of whether NIST
ultimately classifies the submission N or S.
## Output interchangeability — what has to hold
Corona signatures `σ = (c, z, Δ)` are produced by:
- `c ∈ R_q` (ternary challenge)
- `z ∈ R_q^M` (Lagrange-aggregated response with low L2 norm)
- `Δ` (auxiliary; see `sign/sign.go`)
For Corona to claim Class N1 (construction-level), the threshold-
aggregated signature MUST:
1. Verify under unmodified `sign.Verify(group_pk, m, σ)`.
2. Be byte-stream-equivalent to what a single-party run of the same
parameter set would emit on the Lagrange-reconstructed secret
`s = Σ_{i ∈ Q} λ_i^Q · s_i`.
These conditions are inherited from Boschini et al. ePrint 2024/1113
§3 (the construction's correctness theorem). Corona's reference
implementation in `threshold/threshold.go` + `sign/sign.go` realizes
both conditions; KAT cross-runtime byte-equality (Go ↔ C++) provides
the test evidence.
## Required package deliverables
Per NIST IR 8214C §5:
| element | format | location |
|---|---|---|
| Technical Specification | LaTeX (paper sections) + Markdown (`SPEC.md` consolidated entry) | `papers/lp-073-pulsar/` + `SPEC.md`; single-doc `spec/corona.tex` is roadmap v0.6.0 |
| Reference Implementation | open-source code (Go) | `sign/`, `threshold/`, `dkg2/`, `reshare/`, `primitives/`, `hash/` |
| Report on Experimental Evaluation | Markdown + reproducible scripts | `docs/mptc/evaluation.md` + `scripts/bench.sh` |
| Notes on Patent Claims | Markdown (RF grant + attorney-prep drafts) | `PATENTS.md` + `docs/mptc/patent-claims.md` |
| Concrete parameter set | section in spec | `SPEC.md` §3 + `papers/lp-073-pulsar/` |
| Security analysis (proofs) | inherited from cited paper + Markdown framing | Boschini et al. ePrint 2024/1113 §3 + `PROOF-CLAIMS.md` |
| Public repository | GitHub | <https://github.com/luxfi/corona> |
| Build/test/benchmark scripts | shell | `scripts/*.sh` |
| Open-source license | text | `LICENSE` (Apache-2.0) |
| I/O test vectors | JSON (cross-runtime) | `cmd/*_oracle*/` + manifest at `scripts/regen-kats.manifest.sha256` |
Optional but strongly recommended (provided):
- Executive summary (1-2 pages) at front of spec — `NIST-SUBMISSION.md`.
- Threat-model document (`docs/mptc/threat-model.md`).
- Design-decisions document (`docs/mptc/design-decisions.md`).
- Trust-base document (`TRUSTED-COMPUTING-BASE.md`).
- Constant-time audit (`CONSTANT-TIME-REVIEW.md`).
- Honest non-claims (`PROOF-CLAIMS.md`).
## 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 |
Corona v0.4.1 ships a single parameter set tuned to provide ≥ 128
bits of post-quantum security per lattice-estimator methodology.
A second parameter set targeting NIST PQ Category 3 is roadmap
v0.6.0. Concrete lattice-estimator output for the current parameter
set is roadmap v0.6.0 — at submission scaffolding the security claim
is qualitative (per Lux engineering's design choice against the R-LWE
literature) rather than quantitative.
## Class N vs Class S decision (deferred to NIST)
Corona is N if and only if:
1. A working reference implementation produces signatures that verify
under `sign.Verify` for any valid threshold ceremony. ✓ ATTESTED
2. The threshold key generation produces a `(A, bTilde)` that is a
valid Corona group public key. ✓ ATTESTED
3. The verification relation is the Corona reference verifier
(`sign.Verify`) verbatim, with no threshold-specific changes. ✓ ATTESTED
If NIST's interpretation of Class N requires the underlying primitive
to be a NIST standard (not just a published academic construction),
Corona falls back to Class S1 + S4. The evidence supports either
reading; the class decision is for NIST.
## Pulsar (M-LWE) for comparison
Pulsar targets **Class N1 + N4** unambiguously: FIPS 204 ML-DSA-65 is
a NIST standard, and Pulsar's threshold signature output is
byte-equal to FIPS 204 ML-DSA-65 verified by unmodified BoringSSL
FIPS / AWS-LC / OpenSSL 3.0 PQ. Pulsar's submission is at
<https://github.com/luxfi/pulsar>.
The R-LWE / M-LWE pair is intentional: Lux's primary-network
QuasarCert may combine Corona + Pulsar as a **Double Lattice**
layered defence (separate consumer-side design choice; not part of
this submission).
## Status
- [x] Class candidacy declared (N1 + N4 construction-level, with
explicit honesty disclosure about lack of NIST standard target;
S1 + S4 fallback acceptable if NIST prefers)
- [ ] Preview writeup drafted
- [ ] Preview submitted (target 2026-Jul-20)
- [ ] Single-document `spec/corona.tex` (roadmap v0.6.0)
- [x] Reference impl shipping (v0.4.1)
- [x] KAT cross-runtime byte-equality (Go ↔ C++)
- [x] Experimental-evaluation framing (`docs/mptc/evaluation.md`; specific numbers regenerated via `scripts/bench.sh`)
- [x] Patent-claims drafts (`docs/mptc/patent-claims.md`)
- [ ] Package submitted (target 2026-Nov-16)
- [ ] EasyCrypt theory shell (roadmap v0.7.0)
- [ ] dudect statistical CT harness (roadmap v0.8.0)
- [ ] External cryptographic audit (roadmap v0.8.0)
---
**Document metadata**
- Name: `docs/mptc/nist-mptc-category.md`
- Version: v0.1 (initial submission-package scaffolding)
- Date: 2026-05-18
+418
View File
@@ -0,0 +1,418 @@
# Corona — Patent Claim Drafts (Attorney Review)
> **Internal working document.** This file is the technical substrate
> for a patent attorney to draft formal claims from. It is **not** a
> filed patent application or a legal opinion. It enumerates the
> Corona contributions that we consider patentable, with claim
> language, prior-art mapping, and implementation citations.
>
> Public-facing IP terms are in `../../PATENTS.md`. The royalty-free
> grant in PATENTS.md §3 covers all claims listed below, present
> and future.
## §0 Drafting notes for the attorney
- **Inventors**: Lux Industries cryptography team. Specific named
inventors to be assigned per claim group based on contribution
records (commit history in `git log`).
- **Priority date**: file as a US provisional within 12 months of
the NIST MPTC submission's public date (currently anticipated:
2026-Nov-16). File BEFORE the NIST submission becomes public to
preserve foreign-filing rights.
- **Prior art search scope**: NIST PQC / MPTC submissions
(Dilithium, Kyber, Falcon, SPHINCS+, FROST, GG18, CGGMP21,
Pulsar), IACR ePrint archive 2018-2026, the Boschini et al.
ePrint 2024/1113 paper, IEEE S&P 2025 proceedings, HJKY97 +
Desmedt-Jajodia 1997 + Wong-Wang-Wing 2002 proactive-secret-
sharing literature, Pedersen 1991 VSS, lattigo + libjade
implementations, OpenSSL + BoringSSL FIPS PQ providers.
- **Patent family**: file as one provisional with multiple claim
groups; split into independent applications at PCT entry if claim
diversity warrants.
- **Co-pending work**: the Boschini et al. published construction is
academic prior art. Corona claims **exclude** the published
construction's math itself; claim scope is the production
lifecycle additions Lux contributes.
**HONESTY guardrail**: this claim set is intentionally **smaller**
than Pulsar's 21-claim portfolio because Pulsar can claim novelty in
its specific FROST-style Lagrange-aggregation technique combined with
FIPS 204's rejection-sampling loop (a non-obvious composition),
whereas Corona implements a published academic construction
(Boschini et al. 2024/1113) unchanged in its math. Corona's claims
are limited to the production lifecycle Lux added atop the published
construction.
## §1 Claim group A — Pedersen DKG over `R_q` with hiding blinds
### §1.1 Independent claim (Claim 1, draft)
> **Claim 1.** A method for distributed generation of a Ring-LWE
> threshold signing key share over a polynomial ring
> `R_q = Z_q[X]/(X^N + 1)`, the method comprising:
>
> (a) at each dealer party `i` in a committee of `n` parties:
>
> (a1) sampling a sharing polynomial `f_i(X)` of degree `t − 1`
> over `R_q^M`, where `M` is the module width;
>
> (a2) sampling, for each coefficient `f_i^(k)` of `f_i(X)`, a
> hiding-blind polynomial `r_i^(k)` of the same shape;
>
> (a3) computing a Pedersen-style coefficient commitment
> `C_i^(k) = A · NTT(f_i^(k)) + B · NTT(r_i^(k))` for each
> `k ∈ [0, t)`, where `A, B` are public R_q^M generators
> derived deterministically from a session identifier
> `sid_dkg` via cSHAKE256 with customization string
> `"CORONA-DKG-v1"`;
>
> (a4) broadcasting `{C_i^(k)}_{k=0}^{t-1}` to all parties in the
> committee;
>
> (a5) distributing, by per-pair encrypted-share exchange under
> authenticated key exchange, the share-pair
> `(f_i(α_j), r_i(α_j))` to each recipient party `j`;
>
> (b) at each recipient party `j`:
>
> (b1) decrypting the share-pair from each dealer;
>
> (b2) verifying the Pedersen identity
> `A · NTT(share_ij) + B · NTT(blind_ij) ?= Σ_{k=0}^{t-1}
> C_i^(k) · α_j^k` by accumulating
> `eq &= ConstantTimeCompare(lhs_bytes[k], rhs_bytes[k])`
> across all slots `k ∈ [0, M)` with NO per-slot early
> return;
>
> (b3) emitting a complaint message if and only if `eq != 1`
> after the loop terminates;
>
> (c) determining a qualified set `QSET` from the complaint round
> such that `|QSET| ≥ t`; and
>
> (d) computing the group public key as `bTilde = Round(Σ_{i ∈ QSET}
> f_i^(0) · A + e)` where `e` is the LWE noise term inherited
> from the underlying R-LWE construction,
>
> wherein the constant-time accumulation in (b2) prevents the
> recipient's response-time variation from leaking which slot first
> diverged when an invalid share-pair is received.
### §1.2 Reference to spec and implementation
- Spec section: `SPEC.md` §6 + `papers/lp-073-pulsar/lp-073-pulsar-pedersen-dkg.tex`
- Implementation: `dkg2/dkg2.go` (commit-share-verify), `dkg2/dkg2.go:560` (`constTimePolyEqual` helper), `dkg2/complaint.go` (complaint handling)
- Constant-time evidence: `CONSTANT-TIME-REVIEW.md` §2
### §1.3 Dependent claims
**Claim 2.** The method of claim 1, wherein the per-pair encrypted-
share exchange in (a5) uses ML-KEM-768 hybrid recipient wrapping
combined with AEAD encryption.
**Claim 3.** The method of claim 1, wherein the complaint round in
(b3) further comprises:
- a per-complaint timeout configured at the consensus layer;
- a deterministic disqualification algorithm that filters the
qualified set based on the complaint quorum;
- a publicly-verifiable evidence record sufficient for third-party
slashing decisions.
**Claim 4.** The method of claim 1, wherein the public generators
`A, B` in (a3) are derived via cSHAKE256 with customization string
`"CORONA-DKG-v1"` AND session-bound by `sid_dkg` to prevent cross-
session generator reuse.
**Claim 5.** A computer-readable storage medium containing
instructions that, when executed by a plurality of computing devices
in a committee, cause the devices to perform the method of any of
claims 1-4.
### §1.4 Prior-art mapping
| Prior-art reference | Distinguishing feature |
|---|---|
| Pedersen 1991 VSS | Original Pedersen VSS is over a multiplicative group (elliptic curve or `Z_p^*`); Corona's adaptation to the `R_q^M` polynomial-vector setting with per-coefficient hiding blinds and the specific cSHAKE256 generator derivation is the novelty. |
| Feldman 1987 VSS | Feldman VSS has no hiding blinds; Corona's legacy `dkg/` package uses Feldman and is documented as broken for public broadcast. Pedersen `dkg2/` provides hiding. |
| Gennaro-Jarecki-Krawczyk-Rabin 1999 DKG | GJKR DKG is over a discrete-log group; the lattice adaptation pattern is novel. |
| FROST DKG (Komlo-Goldberg 2020) | FROST DKG is for Schnorr/Ed25519; does not apply to lattice-based signatures. |
| Boschini et al. ePrint 2024/1113 | The base construction assumes a trusted-dealer Gen; Corona's `dkg2/` removes that assumption by introducing a publicly-verifiable Pedersen DKG. The DKG construction is Corona's contribution, not the cited paper's. |
## §2 Claim group B — Proactive resharing with `(A, bTilde)` preservation
### §2.1 Independent claim (Claim 6, draft)
> **Claim 6.** A method for proactive secret-sharing rotation in a
> Ring-LWE threshold signing system, the method comprising:
>
> (a) at an old qualified subset `Q ⊆ O_old` of an old committee
> with `|Q| ≥ t_old`, where each party `i ∈ Q` holds an old
> share `s_i^old` of a sharing polynomial `f^old` over `R_q^M`
> such that `f^old(0) = s`:
>
> (a1) sampling, at each party `i ∈ Q`, a fresh polynomial
> `g_i(X)` of degree `t_new − 1` over `R_q^M` with constant
> term `g_i(0) = s_i^old`;
>
> (a2) computing, at each party `i ∈ Q`, Pedersen-style
> coefficient commitments to `g_i(X)` under the protocol's
> deterministic generator derivation;
>
> (a3) distributing, by per-pair encrypted-share exchange, the
> share `g_i(β_j)` to each new party `j` in the new
> committee `O_new`;
>
> (b) at each new party `j ∈ O_new`:
>
> (b1) verifying received shares against the broadcast Pedersen
> commits using constant-time per-slot accumulation;
>
> (b2) computing the new share `s_j^new = Σ_{i ∈ Q} λ_i^Q · g_i(β_j)`
> where `λ_i^Q` are the Lagrange interpolation coefficients
> evaluated at zero for the old qualified subset's party
> indices;
>
> (c) verifying, at all parties, that the new committee's threshold
> signature on a domain-separated activation message
> `m_act = "QUASAR-CORONA-ACTIVATE-v1" || transcript_hash ||
> reshare_transcript_hash` verifies under the **byte-identical
> unchanged** group public key `(A, bTilde)` of the old committee;
>
> wherein, if the activation verification in (c) succeeds, the chain
> accepts the new committee as live and the old committee's signing
> capability is retired; if the activation verification fails, the
> chain rolls back to the old committee and signing continues under
> the old shares.
### §2.2 Reference to spec and implementation
- Spec section: `SPEC.md` §9 + `papers/lp-073-pulsar/lp-073-pulsar-resharing.tex`
- Implementation: `reshare/reshare.go`, `reshare/keyshare.go`, `reshare/activation.go` (activation cert circuit-breaker)
- Tests: `reshare/full_integration_test.go`, `reshare/refresh_test.go`, `reshare/reshare_test.go`
### §2.3 Dependent claims
**Claim 7.** The method of claim 6, wherein the activation message
in (c) further binds:
- chain identifier;
- network identifier;
- key era identifier;
- group identifier;
- old epoch and new epoch counters;
- old validator set hash and new validator set hash;
- old threshold and new threshold;
- group public key hash;
- pairwise material commitment hash;
- implementation version (for cross-port byte-equality
determinism).
**Claim 8.** The method of claim 6, wherein the resharing operation
is parameterized as either:
- a Refresh variant where `O_new = O_old` and the master secret
distribution is refreshed under the same committee for defense
against mobile-adversary share accumulation; OR
- a ReshareToNewSet variant where `O_new ≠ O_old` and the share
distribution rotates to a new validator set with potentially
different threshold `t_new`.
**Claim 9.** The method of claim 6, wherein failure to verify the
activation cert in (c) triggers an LSS-style Rollback operation to
the previous generation's snapshot, without identifying a malicious
actor and without invoking slashing.
### §2.4 Prior-art mapping
| Prior-art reference | Distinguishing feature |
|---|---|
| HJKY97 (Herzberg et al. CRYPTO 1995/1997) | HJKY97 is the classical Refresh primitive over discrete-log groups; Corona's lattice adaptation to `R_q^M` and the activation-cert circuit-breaker are the novelty. |
| Desmedt-Jajodia 1997 | DJ97 specifies redistribution to new access structures; Corona's lattice adaptation + Lagrange-aggregation-over-old-Q + activation-cert composition are novel. |
| Wong-Wang-Wing 2002 (VSR for archive systems) | WWW02 introduces verifiable secret redistribution; Corona's lattice adaptation + the specific activation-cert circuit-breaker pattern that gates new-epoch acceptance ARE novel. |
| LSS framework (Seesahai 2025) | LSS specifies Generation, RollbackFrom, and the Bootstrap Dealer / Signature Coordinator role separation. Corona adapts these to the lattice setting via the `lss_pulsar.go` adapter pattern. |
| Boschini et al. ePrint 2024/1113 | The base construction does NOT specify proactive resharing. Corona's resharing layer is entirely Lux's contribution atop the published construction. |
## §3 Claim group C — Activation cert circuit-breaker
### §3.1 Independent claim (Claim 10, draft)
> **Claim 10.** A method for safely transitioning a Ring-LWE
> threshold signing system from an old validator committee to a new
> validator committee after a proactive secret-resharing operation,
> the method comprising:
>
> (a) completing a resharing operation that transfers a sharing
> polynomial from the old committee to the new committee while
> preserving a group public key `(A, bTilde)`;
>
> (b) constructing, by the new committee, a domain-separated
> activation message `m_act` that binds the old and new epochs,
> the old and new validator-set hashes, the old and new
> thresholds, the group-public-key hash, the resharing transcript
> hash, and an implementation-version field;
>
> (c) producing, by the new committee using their freshly-derived
> shares, a threshold signature `σ_act` on `m_act` via the
> 2-round threshold signing protocol;
>
> (d) verifying `σ_act` under the **byte-identical unchanged**
> `(A, bTilde)` of the old committee;
>
> (e) gating acceptance of the new epoch on the verification in (d):
> if accept, the new committee becomes the active signing
> committee and the old committee's signing authority is retired;
> if reject, the chain rolls back to the old committee and
> signing continues under the old shares.
### §3.2 Reference to spec and implementation
- Spec section: `SPEC.md` §9 + `DESIGN.md` §"Activation cert (the circuit-breaker)"
- Implementation: `reshare/activation.go`
- Test: `reshare/activation_test.go`
### §3.3 Dependent claims
**Claim 11.** The method of claim 10, wherein the activation
verification in (d) is performed by every validator independently,
not by a single coordinator, so that no single party can unilaterally
accept or reject a new committee.
**Claim 12.** The method of claim 10, wherein multiple consecutive
activation failures (a configurable threshold) trigger a Reanchor
governance event that opens a new key era with a fresh group public
key `(A', bTilde')`.
## §4 Claim group D — Constant-time slot-equality `eq &=` accumulation
### §4.1 Independent claim (Claim 13, draft)
> **Claim 13.** A method for constant-time verification of a Pedersen
> commitment over a polynomial-vector ring `R_q^M`, the method
> comprising:
>
> (a) computing, at the recipient, the left-hand side
> `LHS^(k) = A · NTT(share^(k)) + B · NTT(blind^(k))` for each
> slot `k ∈ [0, M)`;
>
> (b) computing the right-hand side `RHS^(k) = Σ_{l=0}^{t-1}
> C^(l) · α_recipient^l` for each slot `k`;
>
> (c) initializing an accumulator `eq = 1`;
>
> (d) for each slot `k ∈ [0, M)`, updating
> `eq &= ConstantTimeCompare(LHS^(k).bytes, RHS^(k).bytes)`
> using a fixed-time byte-blob compare routine, with NO per-slot
> early return;
>
> (e) emitting a complaint message if and only if `eq != 1` after
> the loop in (d) terminates,
>
> wherein the recipient's response-time variation does not reveal
> which slot first diverged when an invalid commitment is received.
### §4.2 Reference to spec and implementation
- Implementation: `dkg2/dkg2.go:560` (`constTimePolyEqual` helper) +
`dkg2/dkg2.go:539` (Round 2 share verification loop)
- Constant-time evidence: `CONSTANT-TIME-REVIEW.md` §2
### §4.3 Distinguishing feature
The novelty is the SPECIFIC application of the `eq &=
ConstantTimeCompare` accumulation pattern to Pedersen commitments
over `R_q^M` polynomial-vector slots, in a context where naive
implementation would leak the first-diverging slot index via
response-time variation (the gap Findings 5/6 of upstream
RED-DKG-REVIEW.md called out for the broken legacy `dkg/` Feldman
path). The pattern itself (`eq &=` accumulation with no early
return) is a known constant-time idiom; the specific application to
the R-LWE Pedersen verification is the contribution.
## §5 Claim group E — Hash-suite injection through every Sign-path primitive
### §5.1 Independent claim (Claim 14, draft)
> **Claim 14.** A computer-implemented system for distributed
> signing on a Ring-LWE threshold signature scheme, the system
> comprising a software architecture wherein every cryptographic
> primitive on the Sign code path accepts, as its first argument, a
> hash-suite handle `HashSuite` that selects between at least:
>
> (a) a production hash suite using cSHAKE256, KMAC256, and
> TupleHash256 per FIPS 202 and NIST SP 800-185, with a registry
> of domain-separation customization strings of the form
> `"CORONA-<purpose>-v1"`; AND
>
> (b) a legacy hash suite using BLAKE3 with the same domain-
> separation customization tags wrapped in BLAKE3-specific
> framing,
>
> such that any single deployment can switch its entire Sign code
> path between suite (a) and suite (b) without modifying any
> primitive's source code, by passing a different `HashSuite` handle
> at construction time.
### §5.2 Reference to spec and implementation
- Spec section: `SPEC.md` §13 + `CHANGELOG.md` "F22 hash-suite injection"
- Implementation: `hash/sp800_185.go` (Corona-SHA3),
`hash/blake3.go` (legacy), `primitives/hash.go` (per-primitive
suite injection)
### §5.3 Distinguishing feature
The novelty is the architectural pattern where the suite is a
first-argument parameter on every primitive (not a package-level
global, not a build flag) so that the same compiled binary can run
multiple parallel deployments under different suites without
recompilation. This enables cross-port byte-equality validation
(Corona-BLAKE3 KAT) without disturbing the production Corona-SHA3
path.
## §6 What Corona does NOT claim
Explicitly disclaimed:
- The base 2-round R-LWE threshold construction (Boschini et al.
ePrint 2024/1113) — academic prior art.
- Ring-LWE primitive (Lyubashevsky-Peikert-Regev 2010) — academic.
- Shamir secret sharing (1979) — public domain.
- Lagrange interpolation — classical mathematics.
- Generic Pedersen VSS construction (Pedersen 1991) — academic.
- Generic HJKY97 / Desmedt-Jajodia / Wong-Wang-Wing proactive
secret sharing — academic.
- SHAKE / cSHAKE / KMAC / TupleHash (FIPS 202 + SP 800-185) — NIST
standards, public domain.
- LSS framework (Seesahai 2025) — academic.
## §7 Comparison to Pulsar's patent claims
Pulsar's `docs/patent-claims.md` enumerates 21 claims across 5 claim
groups, centered on the FIPS 204 byte-identical output
interchangeability technique (Lagrange aggregation + kappa
rejection-sampling integration + FIPS 204 §5.4.1 ExternalMu binding).
Corona's claim set is **smaller** (~14 claims across 5 groups,
shown above) because Corona's underlying construction is published
academic prior art that Corona does not modify. Corona's novelty is
exclusively in the production lifecycle additions: Pedersen DKG
over `R_q`, proactive resharing preserving `(A, bTilde)`,
activation cert circuit-breaker, constant-time Pedersen slot
equality, hash-suite injection architecture.
A reviewer evaluating overlap between the two portfolios should
note: Corona Claim 6 (resharing) and Pulsar Claim 11 (reshare) are
**conceptually parallel** but apply to different lattice families
(R-LWE vs M-LWE) and rely on different underlying Pedersen-commit
shapes; they are independently patentable but the underlying
algorithmic ideas overlap.
---
**Document metadata**
- Name: `docs/mptc/patent-claims.md`
- Version: v0.1 (initial submission-package scaffolding)
- Date: 2026-05-18
- Construction version: Corona v0.4.1 (production library) /
v0.5.0 (submission package)
- Construction repository: <https://github.com/luxfi/corona>
+276
View File
@@ -0,0 +1,276 @@
# Corona — Threat Model
> Companion to `SPEC.md` §4 and `SUBMISSION.md` headline claim.
> This document specifies the adversary model, security goals, and
> trust boundaries for the Corona threshold signing system.
## §1 The participants
| Role | Description |
|---|---|
| **Committee** `O` | The set of `n` parties participating in DKG and signing. |
| **Quorum** `Q ⊆ O` | A subset of `t` parties (the signing threshold) that collectively sign. |
| **Aggregator** | The party (typically the consensus block proposer) that collects Round-1 commits and Round-2 responses, computes the Lagrange aggregation, and produces the final signature. |
| **Bootstrap Dealer** | The party (or MPC ceremony) that runs the one-time trusted-setup at chain genesis. Foundation MPC node; never holds unencrypted secrets after the ceremony close. |
| **Signature Coordinator** | The operational party (typically the consensus block proposer) that triggers signing sessions. Distinct from the Bootstrap Dealer; holds no membership-management authority. |
| **Verifier** | Any party (validator, light client, observer) running `sign.Verify(group_pk, m, σ)`. No threshold-specific state required. |
## §2 The adversary
### §2.1 Adversary capabilities
The Corona EUF-CMA-Threshold claim assumes a **rushing Byzantine
adversary** with the following capabilities:
| Capability | Allowed? |
|---|---|
| Static corruption of up to `t − 1` parties | YES |
| Adaptive corruption of up to `t − 1` parties | OUT OF SCOPE at this submission (paper proves adaptive in random oracle model, but Corona's mechanization is paper-cited; no Corona-specific machine-checked adaptive proof) |
| Rushing (see all honest messages in a round before sending its own) | YES |
| Network message reordering up to bounded delay `Δ` | YES |
| Eavesdropping on all broadcast messages | YES |
| Active modification of broadcast messages | YES (Byzantine adversary; messages are signed and complaints expose tampering) |
| Asynchronous corruption / late corruption mid-session | OUT OF SCOPE |
| Quantum computer | YES — the construction is post-quantum (R-LWE) |
| Side-channel observation | OUT OF SCOPE for the math; addressed at the implementation layer via `CONSTANT-TIME-REVIEW.md` and `DEPLOYMENT-RUNBOOK.md` hardening checklist |
### §2.2 Adversary cannot
| Capability | Disallowed |
|---|---|
| Corrupt more than `t − 1` parties (i.e., reach a quorum unilaterally) | DISALLOWED — assumption breaks EUF-CMA reduction |
| Read the master secret `s` post-Bootstrap | DISALLOWED — `s` is never assembled in any honest party's memory after Bootstrap |
| Forge a signature without a quorum | DISALLOWED — EUF-CMA reduction in Boschini et al. ePrint 2024/1113 §3 |
| Cause `(A, bTilde)` to change without a Reanchor governance event | DISALLOWED — invariant enforced by activation cert circuit-breaker |
| Roll back the chain by manipulating reshare timing | DISALLOWED — LSS `RollbackManager` controls rollback, gated by consensus |
| Compromise the Bootstrap MPC ceremony after its close | DISALLOWED — ceremony state is zeroed in place; subsequent compromise yields no `s` material |
## §3 Network model
### §3.1 Synchronous network (the assumed model)
- Bounded message delivery: every honest-to-honest message arrives
within delay `Δ`.
- All parties have approximately-synchronized clocks (within `Δ`).
- Round timeouts are configured at the consensus layer per the
expected `Δ` of the deployment.
Under the synchronous model, Corona's identifiable-abort property
holds: a misbehaving party can be uniquely identified from the
protocol transcript with high probability.
### §3.2 Asynchronous / partition (NOT supported)
- Identifiable abort under network partition is OUT OF SCOPE.
- Corona's complaint mechanism relies on timely message delivery;
if messages are delayed beyond `Δ`, the complaint mechanism may
produce false-positive accusations or fail to identify the actual
attacker.
- For asynchronous identifiable abort, see the separate Z-Chain
Groth16 accountability layer (NOT part of this submission).
### §3.3 Eclipse attacks
- A successful eclipse attack against an aggregator (controlling all
network paths to and from the aggregator) reduces to the
aggregator-host-compromise threat addressed in
`DEPLOYMENT-RUNBOOK.md`.
- Operationally mitigated via TEE attestation and multi-coordinator
rotation per consensus deployment.
## §4 Cryptographic assumptions
### §4.1 Underlying hardness
| Assumption | Where used |
|---|---|
| Ring-LWE hardness over `R_q = Z_q[X]/(X^N + 1)` with `N = 256`, `q = 0x1000000004A01` | Inherits EUF-CMA reduction from Boschini et al. ePrint 2024/1113. |
| Ring-SIS hardness (informally; the construction's reduction passes through SIS in the random oracle model) | Same paper. |
| cSHAKE256 / KMAC256 / TupleHash256 collision and preimage resistance | All transcript hashes, MAC derivation, PRF derivation. |
| Random oracle model | The EUF-CMA reduction in Boschini et al. relies on ROM. |
### §4.2 Concrete-security target
- ≥ 128 bits of post-quantum security per the lattice-estimator
methodology of Albrecht-Player-Scott (2015) and follow-ups.
- The Corona parameter set was chosen to meet this target; concrete
lattice-estimator output is roadmap item v0.6.0.
### §4.3 What this DOES NOT cover
- Lattice-cryptanalysis breakthroughs that reduce R-LWE security
parameters below current estimates.
- Quantum-cryptanalytic breakthroughs against the random oracle
model.
- Discovery of an efficient ring-structure-specific attack on
Boschini et al.'s ROM-based reduction.
Corona tracks cryptanalysis literature; any flaw would prompt a
parameter-set re-tune and a new key-era via the Reanchor mechanism.
## §5 DKG threat model
### §5.1 In scope for `dkg2/` (Pedersen DKG over `R_q`)
- A malicious dealer attempts to bias the group public key — DEFENDED:
Pedersen hiding blinds ensure the commitment leaks no information
beyond what is necessary for verification.
- A malicious dealer attempts to deliver inconsistent shares to
different recipients — DEFENDED: per-pair Pedersen verification +
complaint round + qualified-set selection.
- A malicious recipient falsely accuses an honest dealer — DEFENDED:
signed complaint messages with publicly-verifiable evidence;
false accusations are detectable.
- A subset of `< t` malicious parties attempts to learn `s` —
DEFENDED: standard Shamir threshold guarantee.
### §5.2 Out of scope for `dkg2/`
- A fully colluding `n` parties (no honest majority): trivially
break — no defense.
- A network-layer attacker delaying complaints past the round
timeout: handled at the consensus layer.
- Bias resistance under collusion of `t` parties (a colluding
quorum can bias the group key): production deployments bind a
randomness beacon at the consensus layer for additional
bias-resistance.
### §5.3 Legacy `dkg/` (Feldman VSS — broken for public broadcast)
The legacy `dkg/` package uses Feldman-style commits without hiding
blinds and IS BROKEN under public broadcast (see upstream
`RED-DKG-REVIEW.md` Findings 5/6). Production deployments MUST NOT
use `dkg/`; use `dkg2/` instead. `dkg/` is retained ONLY for
historical reference and reading existing test fixtures.
## §6 Reshare threat model
### §6.1 In scope for `reshare/`
- Old qualified subset `Q ⊆ O_old` with at most `t_old − 1`
malicious parties: DEFENDED — `|Q| ≥ t_old` requirement ensures
at least one honest old-party contributes to every new share.
- Malformed share delivery from old party to new party: DEFENDED —
Pedersen-style per-pair verification; complaint mechanism.
- Activation cert forgery attempt: DEFENDED — activation cert is a
threshold signature under the unchanged `(A, bTilde)`; forgery
reduces to EUF-CMA which is the same hardness as the underlying
scheme.
- Race condition where new committee accepts before old committee
finishes: DEFENDED — activation cert gating ensures new committee
cannot be accepted until math + verification complete.
### §6.2 Out of scope for `reshare/`
- Cross-key-era preservation (new key era after Reanchor): governance
event, separate threat model.
- Identifiable abort under network partition (see §3.2).
- Robustness against `≥ t/2` Byzantine parties in the old set:
honest-majority assumption.
## §7 Signing threat model
### §7.1 In scope for `sign/` + `threshold/`
- EUF-CMA against quantum adversary: inherited from Boschini et al.
§3.
- Static corruption of `< t` parties during signing: DEFENDED.
- Replay attack: DEFENDED via `sid` (fresh per-session 32-byte
randomness) binding into the transcript.
- Domain-confusion across message classes: DEFENDED via
`QUASAR-CORONA-*` prefix discipline.
- Timing side-channel on the recipient-side verifier:
DEFENDED via `CONSTANT-TIME-REVIEW.md` static audit (zero `(c)`
findings).
### §7.2 Out of scope for `sign/`
- Aggregator-host compromise during a signing session: addressed at
the deployment layer per `DEPLOYMENT-RUNBOOK.md` hardening
checklist.
- Statistical timing side-channel: dudect-style validation is
roadmap v0.8.0.
- Power / EM side-channels: not addressed; production deployments
use TEE attestation.
- Fault attacks: not addressed.
## §8 Trust boundaries
### §8.1 What the chain trusts
- The Bootstrap MPC ceremony at chain genesis (one-time).
- The R-LWE construction's correctness (per Boschini et al.
paper).
- The Go reference implementation's correctness (per code review +
KAT + fuzz).
- The Corona-SHA3 hash suite (per FIPS 202 + SP 800-185).
### §8.2 What the chain does NOT trust
- Any individual validator (each is potentially malicious up to
`t − 1` collusion).
- Any individual coordinator (rotates per epoch).
- The network layer beyond the synchronous-`Δ` model.
- The OS kernel of any single validator beyond the deployment
hardening checklist.
### §8.3 What downstream consumers trust
- The Corona reference verifier `sign.Verify`.
- The cross-runtime byte-equality manifest (Go ↔ C++).
- The deployment runbook's hardening recommendations.
- The Reanchor governance procedure for security-incident response.
## §9 Side-channel threat model
### §9.1 In scope (per `CONSTANT-TIME-REVIEW.md`)
- Timing leakage on Pedersen commit verification: DEFENDED via
`eq &=` constant-time slot accumulation in `dkg2/dkg2.go:560`.
- Timing leakage on verifier byte-equality: DEFENDED via Go
fixed-size array equality (constant-time on amd64/arm64) and
`subtle.ConstantTimeCompare` for variable-length byte blobs.
- Timing leakage on NTT / Montgomery / Gaussian sampling: DEFENDED
via upstream lattigo constant-time guarantees.
### §9.2 Out of scope at this submission
- Cache-timing side channels: not addressed; production
deployments use TEE attestation.
- Power side channels: not addressed.
- EM side channels: not addressed.
- Statistical timing validation (dudect): roadmap v0.8.0.
## §10 Failure-mode threat model (no-slashing-dependency)
Per `DESIGN.md` §"Bootstrap Dealer vs Signature Coordinator (LSS
roles, no-slashing semantics)". The failure response ladder:
```
1. Coordinator timeout / unavailable
→ consensus picks next coordinator deterministically.
2. Resharing round fails (commit mismatch, bad share, etc.)
→ emit signed evidence of the failure point; retry under new
transcript binding next epoch.
3. Activation cert fails to verify under unchanged GroupKey
→ LSS Rollback(targetGeneration = current - 1); chain stays at
previous generation; signing continues under previous shares.
4. Multiple consecutive activation failures
→ governance reanchor: new KeyEraID, fresh ceremony, new GroupKey.
```
No step requires identifying a malicious actor. Slashing evidence
is **collected** during steps 2-3 but the chain's liveness and
safety do not depend on attribution. This is the no-slashing-
dependency property.
---
**Document metadata**
- Name: `docs/mptc/threat-model.md`
- Version: v0.1 (initial submission-package scaffolding)
- Date: 2026-05-18
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# Corona reproducible benchmarks.
#
# Runs the experimental-evaluation harness and writes results to
# bench/results/. Hardware fingerprint is captured so reviewers can
# compare. Per docs/mptc/evaluation.md.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
export GOWORK=off
OUT_DIR="bench/results"
mkdir -p "$OUT_DIR"
echo "==> hardware fingerprint"
{
uname -a
if command -v sysctl >/dev/null 2>&1; then
sysctl -a 2>/dev/null | grep -E 'machdep\.cpu\.brand_string|hw\.ncpu|hw\.memsize' || true
fi
if [[ -f /proc/cpuinfo ]]; then
grep -E 'model name|cpu MHz' /proc/cpuinfo | head -2
fi
go version
} > "$OUT_DIR/fingerprint.txt"
echo "==> Go benchmarks"
go test -bench=. -benchmem -count=3 -run=^$ -benchtime=2s ./... | tee "$OUT_DIR/go-bench.txt"
echo "==> done — results in $OUT_DIR/"
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
# Corona reproducible build.
#
# Builds the Go reference implementation. Exits non-zero on any
# failure. Designed to be the CI gate.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
# Build in module-only mode. A surrounding workspace (e.g. ~/work/lux/go.work)
# does not own this repo's deps and must be bypassed deliberately so reviewers
# get the same view CI gets.
export GOWORK=off
echo "==> Go reference build"
go build ./...
# LaTeX paper-section build is optional — the canonical at this submission
# revision is SPEC.md (Markdown) + LaTeX paper sections at
# papers/lp-073-pulsar/. Build them only if latexmk is available.
if [[ -d "$REPO_ROOT/papers/lp-073-pulsar" ]]; then
if [[ -x /Library/TeX/texbin/latexmk ]] && ! command -v latexmk >/dev/null 2>&1; then
export PATH="/Library/TeX/texbin:$PATH"
fi
if command -v latexmk >/dev/null 2>&1; then
echo "==> LaTeX paper-section build"
(
cd papers/lp-073-pulsar
for tex in lp-073-pulsar-pedersen-dkg.tex lp-073-pulsar-resharing.tex; do
if [[ -f "$tex" ]]; then
latexmk -pdf -interaction=nonstopmode -file-line-error "$tex" || {
echo " [warn] $tex failed to build (continuing — paper sections are non-blocking at this submission revision)"
}
fi
done
)
else
echo " [info] latexmk not found; skipping paper-section PDF build"
echo " [info] (paper PDFs are non-blocking; submission canonical spec is SPEC.md at this revision)"
fi
fi
echo "==> done"
+100
View File
@@ -0,0 +1,100 @@
#!/usr/bin/env bash
# Corona high-assurance gate — orchestrator (per-push, REAL checks).
#
# HONESTY NOTE: Corona's high-assurance surface is structurally
# lighter than Pulsar's. Pulsar runs 7 per-push checks (jasminc +
# jasmin-ct + ec-admits + ec-regressions + ec-refinement-scaffold +
# lean-bridge + ec-extraction + ec-compile). Corona has NO EasyCrypt
# theories, NO Lean ↔ EC bridge, NO Jasmin sources — see
# PROOF-CLAIMS.md §3 for the honest framing of why.
#
# What this gate runs at this submission revision:
#
# 1. go build ./...
# 2. go vet ./...
# 3. constant-time grep guard (warn on accidental fmt.Printf /
# log.Println on secret-touching paths)
# 4. KAT cross-runtime byte-equality (if LUXCPP_DIR is populated)
#
# What this gate DOES NOT run (because the artifacts do not exist):
#
# - EasyCrypt compile / admit-budget / regression checks
# - Lean ↔ EC bridge verification
# - Jasmin type-check + jasmin-ct
# - Jasmin → EC extraction sanity
#
# These remain ROADMAP items (v0.7.0 for the EC/Lean shell;
# v0.8.0 for external audit).
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
export GOWORK=off
echo "==> Corona high-assurance gate"
echo " surface: $REPO_ROOT (sign/, threshold/, dkg2/, reshare/, primitives/, hash/)"
echo " HONESTY: NO EC / Lean / Jasmin theories (see PROOF-CLAIMS.md §3)"
echo
OVERALL=0
echo "==> Check 1: go build ./..."
if ! go build ./...; then
echo "==> FAIL: go build"
OVERALL=2
fi
echo
echo "==> Check 2: go vet ./..."
if ! go vet ./...; then
echo "==> FAIL: go vet"
OVERALL=2
fi
echo
echo "==> Check 3: secret-log grep guard"
# Warn (not fail) if logging primitives appear in code that touches
# secret-typed paths. The full DD-007-style linter from Pulsar is not
# yet ported; this is a smoke check.
HITS=$(grep -rn -E "(fmt\.Print|log\.Print|log\.Fatal|log\.Panic)" \
sign/ threshold/ dkg2/ reshare/ primitives/ keyera/ 2>/dev/null \
| grep -v "_test.go" \
| grep -v "// nolint:nosecretlog" || true)
if [[ -n "$HITS" ]]; then
echo " [warn] potential secret-log call sites (review manually):"
echo "$HITS" | head -20
echo " (HONESTY: this is a smoke check, not a blocking gate)"
else
echo " [ok] no obvious secret-log call sites in sign/threshold/dkg2/reshare/primitives/keyera"
fi
echo
echo "==> Check 4: KAT cross-runtime byte-equality (advisory at this submission revision)"
LUXCPP_DIR="${LUXCPP_DIR:-${HOME}/work/luxcpp}"
if [[ -d "${LUXCPP_DIR}/crypto/corona" ]] || [[ -d "${LUXCPP_DIR}/crypto/pulsar" ]]; then
if [[ -x "$REPO_ROOT/scripts/regen-kats.sh" ]]; then
# KAT regen is advisory at submission scaffolding: scripts/regen-kats.sh
# references oracle subdirs that may have been removed during the
# Corona purge. Run it and report, but do NOT fail the gate on a
# missing oracle directory.
if bash "$REPO_ROOT/scripts/regen-kats.sh" --verify 2>&1 | tail -10; then
echo " [ok] cross-runtime KAT manifest verified"
else
echo " [warn] KAT regen surfaced issues — review manually"
echo " [warn] (advisory at submission scaffolding; not blocking the gate)"
fi
else
echo " [skip] scripts/regen-kats.sh not present"
fi
else
echo " [skip] LUXCPP_DIR not populated; cross-runtime KAT check skipped"
fi
echo
if [[ $OVERALL -eq 0 ]]; then
echo "==> done — high-assurance gate green (within the documented scope)"
else
echo "==> done — gate FAILED (rc=$OVERALL)"
fi
exit $OVERALL
+225
View File
@@ -0,0 +1,225 @@
#!/usr/bin/env bash
# scripts/cut-submission.sh — produce the NIST MPTC submission tarball.
#
# The `luxfi/corona` repository is the single canonical home for the
# submission: spec (SPEC.md + papers/lp-073-pulsar/ LaTeX sections),
# Go reference implementation, KAT vectors (cross-runtime byte-equal
# with the C++ port), constant-time evidence, and cover sheet all
# live in-tree. The cut tool produces a self-contained tarball from a
# clean checkout — no replace-directive dance or external module
# vendoring.
#
# Usage:
# scripts/cut-submission.sh [TAG] [--force]
#
# TAG e.g. "submission-2026-11-16"
# omit for dry-run (no tarball, no tag)
# --force re-cut over an existing tag / tarball
#
# Steps:
# 1. verify clean working tree (git status -s empty)
# 2. verify on branch main
# 3. verify scripts/check-high-assurance.sh exits 0
# 4. regenerate KATs (scripts/gen_vectors.sh) and verify byte-equal
# to committed manifest (scripts/regen-kats.manifest.sha256)
# (SKIPPED if LUXCPP_DIR not populated — cross-runtime KAT is
# the gate but the C++ port is a separate repo)
# 5. run core Go tests
# 6. tar czf submission-<TAG>.tar.gz (excluding .git, vendor caches)
# 7. sha256 the tarball; print to stdout
# 8. git tag <TAG>
#
# The script is idempotent: re-running with the same TAG without
# --force fails fast.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
# -----------------------------------------------------------------------------
# Argument parsing.
# -----------------------------------------------------------------------------
TAG=""
FORCE=0
for arg in "$@"; do
case "$arg" in
--force) FORCE=1 ;;
-h|--help)
sed -n '4,38p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'
exit 0
;;
--*)
echo "cut-submission: unknown flag: $arg" >&2
exit 2
;;
*)
if [[ -n "$TAG" ]]; then
echo "cut-submission: only one TAG allowed (got '$TAG' and '$arg')" >&2
exit 2
fi
TAG="$arg"
;;
esac
done
DRY_RUN=0
if [[ -z "$TAG" ]]; then
DRY_RUN=1
echo "==> cut-submission: DRY-RUN (no TAG given; will not write tarball or tag)"
fi
TARBALL=""
if [[ $DRY_RUN -eq 0 ]]; then
TARBALL="$REPO_ROOT/${TAG}.tar.gz"
if [[ "$TAG" != submission-* ]]; then
echo "cut-submission: TAG must start with 'submission-' (got '$TAG')" >&2
exit 2
fi
fi
# -----------------------------------------------------------------------------
# Step 1: clean working tree.
# -----------------------------------------------------------------------------
echo
echo "==> Step 1: verify clean working tree"
if [[ -n "$(git status --porcelain)" ]]; then
echo "cut-submission: working tree not clean — commit or stash changes first" >&2
git status --short >&2
exit 2
fi
# -----------------------------------------------------------------------------
# Step 2: on branch main.
# -----------------------------------------------------------------------------
echo
echo "==> Step 2: verify on branch main"
CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
if [[ "$CURRENT_BRANCH" != "main" ]]; then
echo "cut-submission: must run from branch 'main' (currently on '$CURRENT_BRANCH')" >&2
exit 2
fi
# -----------------------------------------------------------------------------
# Step 2.5: idempotency guard for tag + tarball.
# -----------------------------------------------------------------------------
if [[ $DRY_RUN -eq 0 ]]; then
if git rev-parse --verify --quiet "refs/tags/$TAG" >/dev/null; then
if [[ $FORCE -eq 0 ]]; then
echo "cut-submission: tag '$TAG' already exists — pass --force to re-cut" >&2
exit 2
fi
echo " [force] tag '$TAG' will be re-cut (existing tag deleted later)"
fi
if [[ -e "$TARBALL" ]]; then
if [[ $FORCE -eq 0 ]]; then
echo "cut-submission: tarball '$TARBALL' already exists — pass --force to overwrite" >&2
exit 2
fi
echo " [force] tarball '$TARBALL' will be overwritten"
fi
fi
# -----------------------------------------------------------------------------
# Step 3: high-assurance gate.
# -----------------------------------------------------------------------------
echo
echo "==> Step 3: high-assurance gate (scripts/check-high-assurance.sh)"
bash "$REPO_ROOT/scripts/check-high-assurance.sh"
# -----------------------------------------------------------------------------
# Step 4: regenerate KATs and verify byte-identical (cross-runtime if available).
# -----------------------------------------------------------------------------
echo
echo "==> Step 4: regenerate KAT vectors and verify byte-identical"
LUXCPP_DIR="${LUXCPP_DIR:-${HOME}/work/luxcpp}"
if [[ -d "${LUXCPP_DIR}/crypto/corona" ]] || [[ -d "${LUXCPP_DIR}/crypto/pulsar" ]]; then
bash "$REPO_ROOT/scripts/regen-kats.sh" --verify
echo " [ok] cross-runtime KAT byte-equality verified"
else
echo " [warn] LUXCPP_DIR not populated; skipping cross-runtime KAT verification"
echo " [warn] (the manifest at scripts/regen-kats.manifest.sha256 is NOT exercised)"
echo " [warn] (set LUXCPP_DIR=/path/to/luxcpp to enable the gate)"
fi
# -----------------------------------------------------------------------------
# Step 5: core tests.
# -----------------------------------------------------------------------------
echo
echo "==> Step 5: core Go tests"
export GOWORK=off
go test -count=1 -timeout 240s ./...
# -----------------------------------------------------------------------------
# Step 6: build the tarball.
# -----------------------------------------------------------------------------
if [[ $DRY_RUN -eq 1 ]]; then
echo
echo "==> Step 6: SKIP — dry-run, no tarball will be written"
else
echo
echo "==> Step 6: tar czf $(basename "$TARBALL")"
# We tar from the parent directory so the tarball expands to a
# './corona/' top-level directory.
(
cd "$(dirname "$REPO_ROOT")"
tar czf "$TARBALL" \
--exclude='./.git' \
--exclude='./.claude' \
--exclude='./docs/.next' \
--exclude='./docs/node_modules' \
--exclude='./docs/out' \
--exclude='./docs/pnpm-lock.yaml' \
--exclude='./bench/results/*.txt' \
--exclude='./papers/lp-073-pulsar/*.aux' \
--exclude='./papers/lp-073-pulsar/*.log' \
--exclude='./papers/lp-073-pulsar/*.fdb_latexmk' \
--exclude='./papers/lp-073-pulsar/*.fls' \
--exclude='./papers/lp-073-pulsar/*.toc' \
--exclude='./papers/lp-073-pulsar/*.out' \
corona
)
if [[ ! -f "$TARBALL" ]]; then
echo "cut-submission: tarball not produced at $TARBALL" >&2
exit 2
fi
echo " [ok] $TARBALL"
fi
# -----------------------------------------------------------------------------
# Step 7: SHA-256 the tarball.
# -----------------------------------------------------------------------------
if [[ $DRY_RUN -eq 0 ]]; then
echo
echo "==> Step 7: SHA-256"
if command -v shasum >/dev/null 2>&1; then
shasum -a 256 "$TARBALL"
elif command -v sha256sum >/dev/null 2>&1; then
sha256sum "$TARBALL"
else
echo "cut-submission: neither shasum nor sha256sum found in PATH" >&2
exit 2
fi
fi
# -----------------------------------------------------------------------------
# Step 8: tag the repo.
# -----------------------------------------------------------------------------
if [[ $DRY_RUN -eq 0 ]]; then
echo
echo "==> Step 8: git tag $TAG"
if git rev-parse --verify --quiet "refs/tags/$TAG" >/dev/null; then
git tag -d "$TAG" >/dev/null
fi
git tag -a "$TAG" -m "NIST MPTC submission cut $TAG"
echo " [ok] tag '$TAG' created (NOT pushed — push manually when ready)"
fi
echo
if [[ $DRY_RUN -eq 1 ]]; then
echo "==> done — dry-run validated (no tarball / no tag produced)"
else
echo "==> done — tarball cut, tag created"
echo " tarball: $TARBALL"
echo " tag: $TAG (local; not pushed)"
fi
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Corona KAT regeneration.
#
# Wraps scripts/regen-kats.sh — the canonical deterministic KAT
# regeneration entry point for Corona. The shape is "regenerate +
# verify byte-equal manifest"; CI uses --verify to enforce drift = bug.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
if [[ ! -x "$REPO_ROOT/scripts/regen-kats.sh" ]]; then
echo "gen_vectors: scripts/regen-kats.sh missing or not executable" >&2
exit 2
fi
# Pass through any user-supplied flags (e.g. --verify); default to
# regeneration (write fresh manifest).
bash "$REPO_ROOT/scripts/regen-kats.sh" "$@"
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
# Corona test gate — orchestrator (per-push, REAL tests).
#
# Runs the available Go test surface for the production library
# plus KAT cross-runtime byte-equality verification.
#
# Corona's test surface is structurally simpler than Pulsar's:
# - No EasyCrypt theories to compile (Corona has none).
# - No Lean ↔ EC bridge to verify (Corona has none).
# - No Jasmin sources to type-check (Corona has none).
# - No jasmin-ct to run (Corona has no Jasmin path).
#
# See PROOF-CLAIMS.md §3 for the honest framing of why this gate is
# lighter than Pulsar's.
#
# The checks, in order:
#
# 1. Go unit + integration tests (with race detector)
# 2. KAT cross-runtime byte-equality (Go ↔ C++ luxcpp port)
# if LUXCPP_DIR points at a populated checkout; SKIP otherwise.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
export GOWORK=off
echo "==> Step 1: go test (with -race)"
go test -count=1 -race ./...
echo
echo "==> Step 2: KAT cross-runtime byte-equality"
LUXCPP_DIR="${LUXCPP_DIR:-${HOME}/work/luxcpp}"
if [[ -d "${LUXCPP_DIR}/crypto/corona" ]] || [[ -d "${LUXCPP_DIR}/crypto/pulsar" ]]; then
if [[ -x "$REPO_ROOT/scripts/regen-kats.sh" ]]; then
bash "$REPO_ROOT/scripts/regen-kats.sh" --verify
else
echo " [skip] scripts/regen-kats.sh not present or not executable"
fi
else
echo " [skip] LUXCPP_DIR not populated; cross-runtime KAT check skipped"
echo " [info] set LUXCPP_DIR=/path/to/luxcpp and re-run to exercise the gate"
fi
echo
echo "==> done — test gate green"