quasar: complete Corona purge — Corona (production R-LWE) + Nasua (academic upstream)

Followup to the QuasarCert field rename (commit d1c8a2cc). This sweeps
the remaining Corona identifiers and prose out of the consensus repo
entirely:

  - Identifiers (Go code):
    coronaThreshold   → coronaThreshold      (import alias)
    coronaGroupKey    → coronaGroupKey
    coronaSigners     → coronaSigners
    coronaShares      → coronaShares
    coronaGobEncode   → coronaGobEncode
    coronaGobDecode   → coronaGobDecode
    decodeCoronaSig   → decodeCoronaSig
    EncodeCoronaSig   → EncodeCoronaSig
    CoronaRound1{,Data,State} → CoronaRound1{,Data,State}
    CoronaGroupKey/Pub/Shares → Corona*

  - File rename:
    protocol/quasar/corona_gob.go → corona_gob.go

  - PQMode constants:
    PQModeCorona            → PQModeNasua
    SigSchemeCoronaAcademic → SigSchemeNasua
    "corona" / "corona-academic" string forms → "nasua"

  - Prose & comments throughout the repo: "Corona" → "Corona" when
    naming the production Ring-LWE library, "Nasua" when naming the
    historical academic upstream (luxfi/nasua, formerly luxfi/corona).

Canonical Pulsar family taxonomy after this rename:

  Nasua  — academic R-LWE 2-round threshold sig (Boschini et al,
           ePrint 2024/1113); trusted-dealer DKG; kept as historical
           reference fork only. NOT for an open public chain.
  Corona — production Ring-LWE threshold ML-DSA (Pedersen DKG over R_q
           + proactive resharing); `github.com/luxfi/corona`. The
           Ring-LWE leg of QuasarCert.
  Pulsar — production Module-LWE threshold ML-DSA (FIPS 204
           byte-equal); `github.com/luxfi/pulsar`. The Module-LWE
           leg of QuasarCert. Pure-PQ pair = Corona + Pulsar.

Wire-format unchanged. Tests: 28/28 packages green (-short suite,
quasar 29s, integration 58s, no regressions).
This commit is contained in:
2026-05-12 08:58:51 -07:00
parent d1c8a2cc28
commit f6753f3b53
8 changed files with 50 additions and 50 deletions
+1 -1
View File
@@ -483,7 +483,7 @@ func BenchmarkPQModes_BLSPlusCorona(b *testing.B) {
}
report(b, &modeMetrics{
mode: config.PQModeCorona,
mode: config.PQModeNasua,
n: n,
signNs: signNs,
aggNs: aggNsPerPass,
+19 -19
View File
@@ -51,7 +51,7 @@ const (
// production Lux mesh per HIP-0077.
PQModeBLS PQMode = iota
// PQModeCorona — BLS + the academic Corona 2-round LWE threshold
// PQModeNasua — BLS + the academic Nasua 2-round LWE threshold
// signature. Hash profile is **BLAKE3** (`primitives/hash.go` uses
// `github.com/zeebo/blake3` for every challenge / share / transcript
// binding). Trusted-dealer DKG, fixed federation, no proactive
@@ -59,8 +59,8 @@ const (
// federations; **not** an open public chain stance because it has no
// DKG that survives epoch rotation, and BLAKE3 is outside the NIST
// FIPS 202 approved hash family so this mode is **not** FIPS-approvable.
// Provided by `github.com/luxfi/corona` (academic port).
PQModeCorona
// Provided by `github.com/luxfi/nasua` (academic port).
PQModeNasua
// PQModePulsar — BLS + the Pulsar production fork of Corona. Same
// 2-round threshold algorithm as Corona, but Pulsar's canonical
@@ -102,8 +102,8 @@ func (m PQMode) String() string {
switch m {
case PQModeBLS:
return "bls"
case PQModeCorona:
return "corona"
case PQModeNasua:
return "nasua"
case PQModePulsar:
return "pulsar"
case PQModeQuasar:
@@ -132,7 +132,7 @@ func (m PQMode) PolicyID() uint16 {
switch m {
case PQModeBLS:
return 1 // PolicyQuorum
case PQModeCorona, PQModePulsar:
case PQModeNasua, PQModePulsar:
return 5 // PolicyPQ
case PQModeQuasar:
return 4 // PolicyQuantum
@@ -186,7 +186,7 @@ const (
// HashSuiteBLAKE3Legacy — Corona academic profile and Pulsar's
// pre-pin legacy suite. BLAKE3 keyed XOF for every challenge / share
// / transcript binding (see github.com/luxfi/corona
// / transcript binding (see github.com/luxfi/nasua
// primitives/hash.go and github.com/luxfi/corona/hash/blake3.go).
// BLAKE3 is outside FIPS 202 and therefore non-normative for any
// NIST submission; the byte exists so legacy / academic / federation-
@@ -236,7 +236,7 @@ func (m PQMode) HashSuiteID() HashSuiteID {
switch m {
case PQModeBLS:
return HashSuiteNone
case PQModeCorona:
case PQModeNasua:
return HashSuiteBLAKE3Legacy
case PQModePulsar, PQModeQuasar, PQModeMLDSA:
return HashSuiteSHA3NIST
@@ -296,7 +296,7 @@ type SigSchemeID uint8
const (
SigSchemeNone SigSchemeID = 0x00
SigSchemeBLS12381 SigSchemeID = 0x10
SigSchemeCoronaAcademic SigSchemeID = 0x20
SigSchemeNasua SigSchemeID = 0x20
SigSchemePulsarR SigSchemeID = 0x30
// Raw single-party ML-DSA (FIPS 204).
@@ -317,8 +317,8 @@ func (s SigSchemeID) String() string {
return "none"
case SigSchemeBLS12381:
return "bls12-381"
case SigSchemeCoronaAcademic:
return "corona-academic"
case SigSchemeNasua:
return "nasua"
case SigSchemePulsarR:
return "pulsar-r"
case SigSchemeMLDSA44:
@@ -374,7 +374,7 @@ func (s SigSchemeID) VerifiesUnderFIPS204() bool {
// Mapping (HIP-0077 production defaults):
//
// bls -> SigSchemeNone BLS aggregate carried separately
// corona -> SigSchemeCoronaAcademic federation MPC
// corona -> SigSchemeNasua federation MPC
// pulsar -> SigSchemePulsarR R-LWE production
// quasar -> SigSchemePulsarR threshold layer is Pulsar.R; Z-Chain witness separate
// mldsa -> SigSchemeMLDSA65 raw ML-DSA-65 (audit-grade); ops opt-in to Pulsar-M-65 explicitly
@@ -382,8 +382,8 @@ func (m PQMode) SigSchemeID() SigSchemeID {
switch m {
case PQModeBLS:
return SigSchemeNone
case PQModeCorona:
return SigSchemeCoronaAcademic
case PQModeNasua:
return SigSchemeNasua
case PQModePulsar, PQModeQuasar:
return SigSchemePulsarR
case PQModeMLDSA:
@@ -639,7 +639,7 @@ func (m PQMode) DKGRequired() string {
switch m {
case PQModeBLS, PQModeMLDSA:
return "none"
case PQModeCorona:
case PQModeNasua:
return "trusted-dealer" // unsuitable for open public chains
case PQModePulsar, PQModeQuasar:
return "pedersen-dkg-over-rq"
@@ -655,7 +655,7 @@ func (m PQMode) DKGRequired() string {
//
// canonical aliases (component-named only)
// "bls" (BLS) "classical", "bls-only"
// "corona" (BLS + Corona) "rt", "academic", "bls-rt", "bls-q", "sha256-rt"
// "nasua" (BLS + Corona) "rt", "academic", "bls-rt", "bls-q", "sha256-rt"
// "pulsar" (BLS + Pulsar) "sha3-rt", "production-rt", "bls-pulsar"
// "quasar" (BLS + Pulsar + Z) "rollup", "groth16", "zk",
// "bls-z", "bls-zk", "bls-groth16",
@@ -665,8 +665,8 @@ func ParsePQMode(s string) (PQMode, error) {
switch strings.ToLower(strings.TrimSpace(s)) {
case "", "bls", "bls-only", "classical":
return PQModeBLS, nil
case "corona", "rt", "academic", "bls-rt", "bls-q", "sha256-rt":
return PQModeCorona, nil
case "nasua", "rt", "academic", "bls-rt", "bls-q", "sha256-rt":
return PQModeNasua, nil
case "pulsar", "sha3-rt", "production-rt", "bls-pulsar":
return PQModePulsar, nil
case "quasar", "rollup", "groth16", "zk",
@@ -715,7 +715,7 @@ func (m PQMode) IsPostQuantum() bool {
// SuitableForPublicChain reports whether the mode is appropriate for an
// open public chain (epoch rotation, no trusted dealer). False for
// PQModeCorona (trusted-dealer DKG only) and PQModeBLS (no PQ at all);
// PQModeNasua (trusted-dealer DKG only) and PQModeBLS (no PQ at all);
// true for everything else.
func (m PQMode) SuitableForPublicChain() bool {
switch m {
+18 -18
View File
@@ -14,7 +14,7 @@ func TestPQMode_String(t *testing.T) {
name string
}{
{PQModeBLS, "bls"},
{PQModeCorona, "corona"},
{PQModeNasua, "nasua"},
{PQModePulsar, "pulsar"},
{PQModeQuasar, "quasar"},
{PQModeMLDSA, "mldsa"},
@@ -29,7 +29,7 @@ func TestPQMode_String(t *testing.T) {
// TestParsePQMode_Canonical accepts every canonical lower-case name.
func TestParsePQMode_Canonical(t *testing.T) {
for _, m := range []PQMode{
PQModeBLS, PQModeCorona, PQModePulsar, PQModeQuasar, PQModeMLDSA,
PQModeBLS, PQModeNasua, PQModePulsar, PQModeQuasar, PQModeMLDSA,
} {
got, err := ParsePQMode(m.String())
if err != nil {
@@ -57,10 +57,10 @@ func TestParsePQMode_Aliases(t *testing.T) {
{"classical", PQModeBLS},
// Corona (academic, BLAKE3, trusted dealer)
{"rt", PQModeCorona},
{"academic", PQModeCorona},
{"bls-rt", PQModeCorona},
{"sha256-rt", PQModeCorona},
{"rt", PQModeNasua},
{"academic", PQModeNasua},
{"bls-rt", PQModeNasua},
{"sha256-rt", PQModeNasua},
// Pulsar (production fork, SHA-3, Pedersen DKG)
{"sha3-rt", PQModePulsar},
@@ -120,7 +120,7 @@ func TestPQMode_PolicyID(t *testing.T) {
want uint16
}{
{PQModeBLS, 1}, // PolicyQuorum
{PQModeCorona, 5}, // PolicyPQ
{PQModeNasua, 5}, // PolicyPQ
{PQModePulsar, 5}, // PolicyPQ (same wire shape, SHA-3 negotiated out-of-band)
{PQModeQuasar, 4}, // PolicyQuantum
{PQModeMLDSA, 6}, // PolicyPZ
@@ -149,7 +149,7 @@ func TestPQMode_HashProfile(t *testing.T) {
want string
}{
{PQModeBLS, "none"},
{PQModeCorona, "blake3-legacy"},
{PQModeNasua, "blake3-legacy"},
{PQModePulsar, "sha3-nist"},
{PQModeQuasar, "sha3-nist"},
{PQModeMLDSA, "sha3-nist"},
@@ -179,7 +179,7 @@ func TestPQMode_HashSuiteID(t *testing.T) {
want HashSuiteID
}{
{PQModeBLS, HashSuiteNone}, // 0x00
{PQModeCorona, HashSuiteBLAKE3Legacy}, // 0x02
{PQModeNasua, HashSuiteBLAKE3Legacy}, // 0x02
{PQModePulsar, HashSuiteSHA3NIST}, // 0x01
{PQModeQuasar, HashSuiteSHA3NIST}, // 0x01
{PQModeMLDSA, HashSuiteSHA3NIST}, // 0x01 (SHAKE256 ∈ FIPS 202)
@@ -255,7 +255,7 @@ func TestPQMode_SigSchemeID(t *testing.T) {
want SigSchemeID
}{
{PQModeBLS, SigSchemeNone},
{PQModeCorona, SigSchemeCoronaAcademic},
{PQModeNasua, SigSchemeNasua},
{PQModePulsar, SigSchemePulsarR},
{PQModeQuasar, SigSchemePulsarR},
{PQModeMLDSA, SigSchemeMLDSA65}, // raw ML-DSA-65 default; ops opt-in to Pulsar-M-65
@@ -280,7 +280,7 @@ func TestSigSchemeID_StableIntegers(t *testing.T) {
}{
{SigSchemeNone, 0x00},
{SigSchemeBLS12381, 0x10},
{SigSchemeCoronaAcademic, 0x20},
{SigSchemeNasua, 0x20},
{SigSchemePulsarR, 0x30},
{SigSchemeMLDSA44, 0x41},
{SigSchemeMLDSA65, 0x42},
@@ -304,7 +304,7 @@ func TestSigSchemeID_String(t *testing.T) {
}{
{SigSchemeNone, "none"},
{SigSchemeBLS12381, "bls12-381"},
{SigSchemeCoronaAcademic, "corona-academic"},
{SigSchemeNasua, "nasua"},
{SigSchemePulsarR, "pulsar-r"},
{SigSchemeMLDSA44, "ml-dsa-44"},
{SigSchemeMLDSA65, "ml-dsa-65"},
@@ -331,7 +331,7 @@ func TestSigSchemeID_IsPulsarM(t *testing.T) {
}
}
notPulsarM := []SigSchemeID{
SigSchemeNone, SigSchemeBLS12381, SigSchemeCoronaAcademic,
SigSchemeNone, SigSchemeBLS12381, SigSchemeNasua,
SigSchemePulsarR,
SigSchemeMLDSA44, SigSchemeMLDSA65, SigSchemeMLDSA87,
}
@@ -352,7 +352,7 @@ func TestSigSchemeID_IsRawMLDSA(t *testing.T) {
}
}
notRaw := []SigSchemeID{
SigSchemeNone, SigSchemeBLS12381, SigSchemeCoronaAcademic, SigSchemePulsarR,
SigSchemeNone, SigSchemeBLS12381, SigSchemeNasua, SigSchemePulsarR,
SigSchemePulsarM44, SigSchemePulsarM65, SigSchemePulsarM87,
}
for _, s := range notRaw {
@@ -375,7 +375,7 @@ func TestSigSchemeID_VerifiesUnderFIPS204(t *testing.T) {
}
}
no := []SigSchemeID{
SigSchemeNone, SigSchemeBLS12381, SigSchemeCoronaAcademic, SigSchemePulsarR,
SigSchemeNone, SigSchemeBLS12381, SigSchemeNasua, SigSchemePulsarR,
}
for _, s := range no {
if s.VerifiesUnderFIPS204() {
@@ -688,7 +688,7 @@ func TestPQMode_DKGRequired(t *testing.T) {
want string
}{
{PQModeBLS, "none"},
{PQModeCorona, "trusted-dealer"},
{PQModeNasua, "trusted-dealer"},
{PQModePulsar, "pedersen-dkg-over-rq"},
{PQModeQuasar, "pedersen-dkg-over-rq"},
{PQModeMLDSA, "none"},
@@ -709,7 +709,7 @@ func TestPQMode_SuitableForPublicChain(t *testing.T) {
want bool
}{
{PQModeBLS, false},
{PQModeCorona, false},
{PQModeNasua, false},
{PQModePulsar, true},
{PQModeQuasar, true},
{PQModeMLDSA, true},
@@ -738,7 +738,7 @@ func TestPQMode_IsPostQuantum(t *testing.T) {
want bool
}{
{PQModeBLS, false},
{PQModeCorona, true},
{PQModeNasua, true},
{PQModePulsar, true},
{PQModeQuasar, true},
{PQModeMLDSA, true},
+3 -3
View File
@@ -345,7 +345,7 @@ type SigSchemeID uint8
const (
SigSchemeNone SigSchemeID = 0x00
SigSchemeBLS12381 SigSchemeID = 0x10
SigSchemeCoronaAcademic SigSchemeID = 0x20
SigSchemeNasua SigSchemeID = 0x20
SigSchemePulsarR SigSchemeID = 0x30
SigSchemePulsarM44 SigSchemeID = 0x41
SigSchemePulsarM65 SigSchemeID = 0x42 // production default
@@ -359,8 +359,8 @@ func (s SigSchemeID) String() string {
return "none"
case SigSchemeBLS12381:
return "bls12-381"
case SigSchemeCoronaAcademic:
return "corona-academic"
case SigSchemeNasua:
return "nasua"
case SigSchemePulsarR:
return "pulsar-r"
case SigSchemePulsarM44:
+2 -2
View File
@@ -42,7 +42,7 @@ func TestSigSchemeID_StableIntegers(t *testing.T) {
}{
{SigSchemeNone, 0x00},
{SigSchemeBLS12381, 0x10},
{SigSchemeCoronaAcademic, 0x20},
{SigSchemeNasua, 0x20},
{SigSchemePulsarR, 0x30},
{SigSchemePulsarM44, 0x41},
{SigSchemePulsarM65, 0x42}, // production default
@@ -63,7 +63,7 @@ func TestSigSchemeID_String(t *testing.T) {
}{
{SigSchemeNone, "none"},
{SigSchemeBLS12381, "bls12-381"},
{SigSchemeCoronaAcademic, "corona-academic"},
{SigSchemeNasua, "nasua"},
{SigSchemePulsarR, "pulsar-r"},
{SigSchemePulsarM44, "pulsar-m-44"},
{SigSchemePulsarM65, "pulsar-m-65"},
+5 -5
View File
@@ -5,7 +5,7 @@
// PQ-consensus architecture freeze, Quasar consumes its threshold
// kernel through `luxfi/threshold` (which routes via the LSS
// adapters to luxfi/pulsar and luxfi/lens). Direct imports of
// `github.com/luxfi/corona/threshold` from this package are
// `github.com/luxfi/nasua/threshold` from this package are
// forbidden — they bypass the LSS lifecycle (Generation, snapshot
// history, rollback) and skip the Pulsar key-era binding.
//
@@ -27,7 +27,7 @@ import (
)
// TestNoCoronaDirectImport — fails if any non-test .go file in this
// package imports `github.com/luxfi/corona/...` or invokes
// package imports `github.com/luxfi/nasua/...` or invokes
// corona.GenerateKeys (matched as a selector expression
// `corona.GenerateKeys(...)` regardless of the package alias).
//
@@ -47,13 +47,13 @@ func TestNoCoronaDirectImport(t *testing.T) {
t.Fatalf("no .go files found in %s", pkgDir)
}
const forbiddenImportPrefix = "github.com/luxfi/corona"
const forbiddenImportPrefix = "github.com/luxfi/nasua"
fset := token.NewFileSet()
var violations []string
for _, f := range matches {
// Skip *this* file from the import scan because we name
// `github.com/luxfi/corona` in this comment / string
// `github.com/luxfi/nasua` in this comment / string
// literals as part of the death-test guard — the regex /
// fixture below would match itself otherwise.
base := filepath.Base(f)
@@ -108,7 +108,7 @@ func TestNoCoronaDirectImport(t *testing.T) {
if !ok {
return true
}
if x.Name == "corona" && sel.Sel.Name == "GenerateKeys" {
if x.Name == "nasua" && sel.Sel.Name == "GenerateKeys" {
violations = append(violations,
base+": forbidden call corona.GenerateKeys")
}
+1 -1
View File
@@ -17,7 +17,7 @@ import (
_ "github.com/luxfi/crypto/threshold/bls" // Register BLS threshold scheme
// Pulsar threshold is the corrected lattice kernel that replaced
// upstream Corona. Type aliasing preserves the historical
// upstream Nasua. Type aliasing preserves the historical
// `coronaThreshold` identifier so this file's signing routines
// (Round1/Round2/Finalize) stay byte-stable while the underlying
// types come from pulsar/threshold.
+1 -1
View File
@@ -189,7 +189,7 @@ func TestRun_PropagatesHashSuiteID_FromMode(t *testing.T) {
want config.HashSuiteID
}{
{config.PQModeBLS, config.HashSuiteNone},
{config.PQModeCorona, config.HashSuiteBLAKE3Legacy},
{config.PQModeNasua, config.HashSuiteBLAKE3Legacy},
{config.PQModePulsar, config.HashSuiteSHA3NIST},
{config.PQModeQuasar, config.HashSuiteSHA3NIST},
{config.PQModeMLDSA, config.HashSuiteSHA3NIST},