mirror of
https://github.com/luxfi/corona.git
synced 2026-09-24 00:25:54 +00:00
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:
@@ -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
@@ -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`.
|
||||
@@ -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
|
||||
@@ -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).
|
||||
@@ -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`.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
@@ -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
@@ -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`
|
||||
@@ -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`)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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
|
||||
Executable
+32
@@ -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/"
|
||||
Executable
+45
@@ -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"
|
||||
Executable
+100
@@ -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
|
||||
Executable
+225
@@ -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
|
||||
Executable
+20
@@ -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" "$@"
|
||||
Executable
+47
@@ -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"
|
||||
Reference in New Issue
Block a user