Files
corona/SPEC.md
zeekay df1db68bd0 docs/comments: correct lattice-family label Ring-LWE -> Module-LWE (Corona is Module-LWE)
Corona is Module-LWE (threshold-Raccoon/Ringtail), NOT Ring-LWE. Confirmed in code: sign/sign.go samples A in R_q^{8x7} (sign.go:87 SamplePolyMatrix M=8,N=7), secret s a rank-7 ring vector, b=A*s+e (sign.go:106-107) over R_q=Z_q[X]/(X^256+1) (LogN=8), q=0x1000000004A01 -- rank>1 module structure, not rank-1 ring-LWE. threshold/threshold.go:4-5 already said Module-LWE.

Fixed the family label across README, SPEC, SUBMISSION, NIST-SUBMISSION, PATENTS, LLM, CONTRIBUTING, SECURITY, CHANGELOG, DEPLOYMENT-RUNBOOK, Makefile, AXIOM-INVENTORY, PROOF-CLAIMS, BLOCKERS, CRYPTOGRAPHER-SIGN-OFF, FIPS-TRACEABILITY, TRUSTED-COMPUTING-BASE, AUDIT-2026-05/06, docs/mptc/*, jasmin/README, 3 Go comments + cli help string.

Also corrected the downstream false claim that Corona (Ring-LWE) and Pulsar (Module-LWE) are 'different lattice families' giving 'structural/family diversity': both are Module-LWE, so the Double-Lattice defense is construction/implementation diversity (threshold-Raccoon vs ML-DSA), not hardness-family diversity; a Module-LWE break affects both legs (hash-based Magnetar is the assumption-diversifier). Fixed companion R-SIS -> Module-SIS where it was the module scheme's SIS assumption; added the Langlois-Stehle (DCC 2015) Module-LWE citation alongside LPR 2010.

Delicate artifacts: proof identifiers (rlwe_sign_op, RLWE_Functional theory/file, *_eq_rlwe bridges, CentralRLWESign, RLWESign, rlwe_compute_*) were NOT renamed -- EasyCrypt/jasmin toolchains are absent here so a rename cannot be compile-verified, and .assurance/ gates parse those names. Added clarifying naming notes to the 5 prominent .ec files, proofs/easycrypt/README.md, AXIOM-INVENTORY.md, and jasmin/rlwe/sign.jazz. .assurance/*.txt left untouched (already say Module-LWE/Module-SIS; rlwe tokens are gate-parsed identifiers). Left AUDIT-2026-06.md:463 historical rename-log and the ProtoStar-LWE paper-title substring untouched.

go build ./... and go test ./... green (GOWORK=off; all packages ok).
2026-06-27 16:12:24 -07:00

15 KiB
Raw Permalink Blame History

SPEC — Corona Threshold Module-LWE Signature (v0.2)

Standalone protocol specification for Corona — a 2-round threshold Module-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 Module-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 (a different Module-LWE construction — see Pulsar at ~/work/lux/pulsar/).
  • Verifier implementations beyond the Corona reference verifier (sign/sign.go:Verify). No third-party Module-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 Module-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.
  • Module-LWE hardness over the fixed parameter set (Langlois-Stehlé 2015 module generalisation of 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 Module-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.