Files
corona/CHANGELOG.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

23 KiB
Raw Permalink Blame History

corona CHANGELOG

Notable changes to the corona module. Pre-release; semantic versioning applied per PHILOSOPHY.md (patch only -- never minor/major without explicit approval).

v0.7.5 (public-BFT Bootstrap default — symmetry with Reanchor)

Closes the last asymmetry left over from v0.7.3: the unqualified keyera.Bootstrap and keyera.BootstrapWithSuite entrypoints still routed through the legacy single-dealer Shamir share-out, so any caller who picked the "obvious" name silently inherited the trusted-dealer caveat at chain genesis. v0.7.5 flips both defaults to BootstrapPedersen: no single party ever holds the master secret s at any point in the ceremony. The mirror move was already made in v0.7.4 for Reanchor; v0.7.5 completes the symmetry so the API surface has one safe default for opening a key era and one explicit opt-in (BootstrapTrustedDealer / ReanchorTrustedDealer) for HSM / TEE ceremonies.

Signature changes (keyera/keyera.go)

  • keyera.Bootstrap(t, validators, groupID, eraID, entropy) now returns (*KeyEra, *BootstrapTranscript, error) (was (*KeyEra, error)) and routes through BootstrapPedersen. Callers MUST commit the transcript to the chain for the era to ratify.
  • keyera.BootstrapWithSuite mirrors the same signature change and routes through BootstrapPedersen with the supplied suite.

Public-BFT-safe path (no functional change vs v0.7.4)

  • BootstrapPedersen and ReanchorPedersen remain the canonical implementations; the v0.7.5 change is a default-routing flip, not a new construction.

Legacy trusted-dealer aliases (explicit opt-in only)

  • keyera.BootstrapTrustedDealer / keyera.BootstrapTrustedDealerWithSuite continue to expose the legacy single-dealer Shamir share-out (byte-equivalent to the pre-v0.7.5 unqualified Bootstrap). The shared implementation is now the unexported bootstrapTrustedDealerImpl so the public-facing aliases cannot drift from each other; ReanchorTrustedDealerWithSuite also routes through this helper.

Structural invariant

  • BootstrapPedersen requires n >= 2 && t < n. The unqualified Bootstrap therefore inherits the same constraint, by construction; callers that need t == n (every validator MUST sign) must select the trusted-dealer entrypoint explicitly. This is the "loud name" the cryptographer's audit prompt asks for: any deployment that cannot tolerate the dealer's trust boundary will be caught at the call site, not silently.

Tests

All green via GOWORK=off go test -count=1 -short ./...:

  • keyera_test.go -- updated to drop t == n from the public-BFT cases (now uses t = n - 1); Bootstrap 3-tuple return propagated.
  • hashsuite_immut_test.go -- same threshold adjustment.
  • bootstrap_pedersen_test.go -- TestBootstrapTrustedDealer_Legacy Alias renamed to TestBootstrapTrustedDealer_StandalonePath since the two paths are no longer byte-equivalent; the test pins that the Pedersen Bootstrap correctly rejects t == n.

Documentation

  • DEPLOYMENT-RUNBOOK.md §Bootstrap-Trust decision matrix updated: the unqualified Bootstrap now appears in the "public-BFT" row; the trusted-dealer alias is the explicit HSM/TEE-ceremony row.
  • AUDIT-2026-05.md §0 v0.7.5 closure note; §8.5 new caveat: chains that historically used t == n MUST adopt t < n to take the public-BFT path. Otherwise they remain on BootstrapTrustedDealer with the dealer caveat explicit at the call site.

Cross-runtime byte equality

  • The unqualified Bootstrap bytes diverge from prior runs because the underlying ceremony changed. No deployed KAT pins Bootstrap output; the canonical KATs target BootstrapPedersen (under its own name) and BootstrapTrustedDealer (under its own name). Future cross-runtime ports MUST distinguish the two paths by name.

v0.7.4 (public-BFT Reanchor via dkg2 Pedersen-DKG; mathSqrt cleanup)

Closes the Reanchor trusted-dealer regression flagged in v0.7.3 red review: keyera.Reanchor previously called BootstrapWithSuite (the trusted-dealer path) under the hood, so a governance-driven Reanchor re-introduced the dealer caveat at every rotation. v0.7.4 routes Reanchor through ReanchorPedersen by default (Pedersen-DKG over R_q + Path (a) noise flooding) so no party ever holds the new era's master secret s at any point in the rotation. The legacy trusted-dealer behaviour is retained behind explicit ReanchorTrustedDealer aliases for HSM / TEE ceremonies.

New public surface (keyera/reanchor_pedersen.go)

  • keyera.ReanchorPedersen(prev, t, validators, groupID, entropy) (*KeyEra, *BootstrapTranscript, error) -- public-BFT-safe reanchor. Routes through BootstrapPedersen with the new era's EraID = prev.EraID+1 and GenesisEpoch = prev.State.Epoch+1.
  • keyera.ReanchorPedersenWithSuite(prev, suite, t, validators, groupID, entropy) (*KeyEra, *BootstrapTranscript, error) -- suite-explicit variant. Reanchor is the only lifecycle entrypoint that may pin a hash profile different from the prior era's.

Signature changes (keyera/keyera.go)

  • keyera.Reanchor and keyera.ReanchorWithSuite now return (*KeyEra, *BootstrapTranscript, error) (was (*KeyEra, error)) and route through ReanchorPedersen. The transcript MUST be committed to the chain for the new era to ratify.
  • keyera.ReanchorTrustedDealer / keyera.ReanchorTrustedDealerWithSuite -- new explicit aliases for the legacy single-dealer path. Byte-equivalent to the pre-v0.7.4 trusted-dealer Reanchor behaviour. Use ONLY for ceremony scenarios where a non-distributed trust root is acceptable by policy (see DEPLOYMENT-RUNBOOK.md §Bootstrap-Trust).

Cleanup (keyera/bootstrap_pedersen.go)

  • mathSqrt -- a 12-iteration Newton's-method in-tree implementation -- replaced with stdlib math.Sqrt. The "keeps the import surface tight" rationale was false parsimony; the Path (a) noise σ is computed once at bootstrap and stdlib gives the canonical IEEE 754 result without ULP drift.

Tests (keyera/reanchor_pedersen_test.go)

All green via GOWORK=off go test -count=1 -short ./keyera/:

  • TestReanchorPedersen_RoundTrip -- bootstrap → reanchor → sign with new shares → verify under new GroupKey. Asserts EraID increments, GenesisEpoch + State.Epoch advance, HashSuiteID is inherited, transcript is non-nil.
  • TestReanchorPedersen_NoMasterSecret -- structural assertions that no dkg2.DKGSession field exposes the master secret and no two new-committee shares collide.
  • TestReanchorPedersen_DishonestParty -- tampered share triggers ErrBootstrapPedersenAbort with a named ComplaintBadDelivery.
  • TestReanchorTrustedDealer_LegacyAlias -- legacy alias still works; byte-equivalent across ReanchorTrustedDealer and ReanchorTrustedDealerWithSuite(Corona-SHA3).

Existing tests updated to the new signature:

  • TestReanchorOpensNewEra (keyera/keyera_test.go) -- now uses t=2, n=3 because the public-BFT-safe path requires t < n.
  • TestReanchorMayChangeSuite (keyera/hashsuite_immut_test.go) -- same threshold adjustment; same suite-migration assertion.

Documentation

  • AUDIT-2026-05.md -- §0 v0.7.4 closure note; §8.3 caveat updated (Reanchor closure); §9 references with verified IACR ePrint IDs for the 2025 citations (2024/959, 2024/1113, 2025/871, 2025/872, 2025/1691) and explicit [citation TBD] for unverifiable lines rather than fabricated IDs.
  • DEPLOYMENT-RUNBOOK.md -- §Bootstrap-Trust decision matrix expanded to cover Reanchor; default routing pinned to Pedersen-DKG for both Bootstrap and Reanchor.

Cross-runtime byte equality

  • KAT manifest preserved (scripts/regen-kats.manifest.sha256); no cross-runtime KATs reference BootstrapPedersen transcripts.
  • math.Sqrt vs the previous Newton-12-iter implementation diverges by 1 ULP for some n (e.g. n=2, n=10). No deployed KAT pins pathANoiseParameters output, so this is harmless within the in-tree replay tests; future cross-runtime ports MUST use math.Sqrt (or equivalent IEEE 754 stdlib sqrt) to byte-match.

v0.7.3 (public-BFT Bootstrap via dkg2 Pedersen-DKG + Path (a) noise flooding)

Closes the last trusted-dealer caveat in keyera.Bootstrap for any deployment that cannot vouch for a single dealer's host platform. The trusted-dealer path is retained (under a renamed alias) for genesis ceremonies where a non-distributed trust root is acceptable by policy.

New public surface (keyera/bootstrap_pedersen.go)

  • keyera.BootstrapPedersen(suite, t, validators, groupID, eraID, entropy) (*KeyEra, *BootstrapTranscript, error) -- public-BFT-safe bootstrap. Routes the keygen ceremony through dkg2/ (Pedersen-DKG over R_q) + Path (a) noise flooding so no single party ever holds the master secret s at any point in the ceremony.

  • keyera.FinishBootstrapPedersen(suite, t, validators, ..., dkgParams, sessions, round1) (*KeyEra, *BootstrapTranscript, error) -- kernel entrypoint that drives Rounds 1.5 + 2 + Path (a) on a pre-computed set of Round 1 outputs. Tests use this to inject deliberately dishonest contributions and exercise the identifiable-abort path.

  • keyera.BootstrapTrustedDealer / keyera.BootstrapTrustedDealerWithSuite -- renamed aliases for the legacy single-dealer path. Retained for genesis ceremonies where the foundation explicitly chooses a non-distributed trust root (see DEPLOYMENT-RUNBOOK.md §Bootstrap-Trust decision matrix).

  • keyera.BootstrapTranscript -- public, byte-stable record produced by every Pedersen bootstrap run. Honest validators that observe the same cohort messages compute identical transcript bytes; the chain commits to TranscriptHash to ratify the era.

  • keyera.AbortEvidence + keyera.ExtractAbortEvidence(err) -- public surface for identifiable-abort consumption. A non-nil AbortEvidence carries the disqualified set and signed dkg2.Complaints ready for the slashing pipeline.

Tests (keyera/bootstrap_pedersen_test.go)

All green via GOWORK=off go test -count=1 -short ./keyera/:

  • TestBootstrapPedersen_RoundTrip -- 5-party Pedersen-DKG with t=3; transcript determinism across replays; bTilde / digest stability.
  • TestBootstrapPedersen_DishonestDealer -- tampered share-to-recipient-0 triggers ErrBootstrapPedersenAbort naming sender 2; AbortEvidence carries a re-checkable ComplaintBadDelivery.
  • TestBootstrapPedersen_FollowedBySign -- Pedersen bootstrap → standard 2-round threshold sign → threshold.Verify PASS. The noise-flooded GroupKey is structurally identical to a trusted-dealer Corona setup.
  • TestBootstrapPedersen_NoMasterSecretInMemory -- structural assertion that dkg2.DKGSession exposes no master-secret field, and that no two parties' SkShares / Lambdas collide.
  • TestBootstrapPedersen_ParameterValidation -- bounds checking.
  • TestBootstrapPedersen_DefaultSuite -- nil resolves to Corona-SHA3.
  • TestBootstrapTrustedDealer_LegacyAlias -- legacy alias is byte- equivalent to historical Bootstrap.

Documentation

  • AUDIT-2026-05.md -- read-only SOTA refresh covering threshold lattice DKG / signing literature 2024-2026. Verdict: Boschini-Takahashi-Tibouchi 2024/1113 remains canonical; 2025 follow-ups (del Pino, Doerner-Kondi, Hofheinz, Beimel-Eitan) are complementary or non-blocking; no SOTA refresh blocks this revision.
  • DEPLOYMENT-RUNBOOK.md -- new §Bootstrap-Trust decision matrix documenting Option A (BootstrapPedersen, recommended) vs Option B (BootstrapTrustedDealer, ceremony-only) trade-off.
  • keyera/keyera.go -- inline trust-model documentation pointing at BootstrapPedersen as the public-BFT-safe alternative.

Cross-runtime byte equality

  • KAT manifest preserved (scripts/regen-kats.manifest.sha256); existing trusted-dealer KATs continue to byte-match ~/work/luxcpp/crypto/corona/.
  • BootstrapPedersen adds new ceremony bytes (deterministic given entropy); a future cross-runtime port can pin them via the public BootstrapTranscript.TranscriptHash.

v0.7.0 (Tier A full closure -- EC + Lean + Jasmin + dudect scaffolding)

This revision lands the Tier A formal-methods scaffolding for Corona, mirroring Pulsar's structure exactly. Closes GATE-1 / GATE-2 / GATE-3a from the v0.6.0 sign-off.

EasyCrypt theories (13 files; admit budget 0/0)

  • proofs/easycrypt/Corona_N1.ec -- master byte-equality theorem (corona_n1_byte_equality).
  • proofs/easycrypt/Corona_N4.ec -- reshare public-key preservation (corona_n4_pk_preservation_honest).
  • proofs/easycrypt/Corona_N1_Memory.ec -- byte-memory model + frame laws.
  • proofs/easycrypt/Corona_N1_Signature_Codec.ec -- signature codec.
  • proofs/easycrypt/Corona_N1_Combine_Layout.ec -- Combine byte layout.
  • proofs/easycrypt/Corona_N1_Sign_Layout.ec -- Sign byte layout.
  • proofs/easycrypt/Corona_N1_Combine_Refinement.ec -- 3 byte-walk + memory-separation + layout-frame axioms.
  • proofs/easycrypt/Corona_N1_Sign_Refinement.ec -- 3 byte-walk axioms.
  • proofs/easycrypt/Corona_N1_Combine_Wrapper.ec -- wrapper bridge.
  • proofs/easycrypt/Corona_N1_Sign_Wrapper.ec -- wrapper bridge.
  • proofs/easycrypt/Corona_N1_Extracted.ec -- IMPLEMENTATION-BACKED end-to-end theorem.
  • proofs/easycrypt/lemmas/RLWE_Functional.ec -- in-house EC mechanization of Boschini ePrint 2024/1113 §3 Sign + Verify.
  • proofs/easycrypt/lemmas/Corona_CT.ec -- constant-time obligations.
  • proofs/easycrypt/README.md -- file map + admit budget.

Lean <-> EC bridge (5 axioms)

  • proofs/lean-easycrypt-bridge.md -- 5-axiom Lean <-> EC bridge: lagrange_inverse_eval, threshold_partial_response_identity, add_share_zeroR, reconstruct_linear, shamir_correct.
  • ~/work/lux/proofs/lean/Crypto/Corona/Shamir.lean -- Lagrange-over- polynomial-ring algebraic core.
  • ~/work/lux/proofs/lean/Crypto/Corona/OutputInterchange.lean -- Class N1 verifier-compatibility.
  • ~/work/lux/proofs/lean/Crypto/Corona/Unforgeability.lean -- EUF-CMA reduction to Module-LWE.
  • ~/work/lux/proofs/lean/Crypto/Corona/dkg2.lean -- Pedersen-VSS DKG.

Jasmin sources

  • jasmin/lib/corona_params.jinc -- parameter set.
  • jasmin/lib/seed.jinc -- per-round PRNG seed derivation.
  • jasmin/lib/transcript.jinc -- transcript-hash binder.
  • jasmin/lib/mac.jinc -- per-peer MAC primitive.
  • jasmin/lib/lagrange.jinc -- Lagrange-coefficient computation.
  • jasmin/threshold/round1.jazz -- per-party Round-1 commit (#ct).
  • jasmin/threshold/round2.jazz -- per-party Round-2 response (#ct).
  • jasmin/threshold/combine.jazz -- Combine aggregation (#ct).
  • jasmin/rlwe/sign.jazz -- centralized Boschini Sign reference.
  • jasmin/README.md -- layout + refinement-target table.

dudect harness

  • ct/dudect/verify_ct.go + dudect_verify.c -- Verify harness.
  • ct/dudect/combine_ct.go + dudect_combine.c -- Combine harness.
  • ct/dudect/dudect_compat.h -- AArch64 cycle-counter compat shim.
  • ct/dudect/Makefile + fetch.sh + run-submission.sh.

CI orchestrator (7 gates)

  • scripts/check-high-assurance.sh -- mirrors Pulsar's structure exactly. Sequences jasmin + ec-admits + ec-regressions + ec-refinement-scaffold + lean-bridge + extraction + ec-compile.
  • scripts/checks/ec-admits.sh -- admit-budget 0/0 static guard.
  • scripts/checks/ec-regressions.sh -- retired-axiom regression guard.
  • scripts/checks/ec-refinement-scaffold.sh -- declare-axiom hygiene.
  • scripts/checks/ec-compile.sh -- EC compile gate.
  • scripts/checks/jasmin.sh -- jasmin type-check + jasmin-ct gate.
  • scripts/checks/extraction.sh -- Jasmin -> EC extraction sanity.
  • scripts/check-lean-bridge.sh -- 5-axiom Lean <-> EC bridge guard.

Tests

  • threshold/e2e_threshold_variants_test.go -- (3,2), (5,3), (7,4), (10,7) committee-size e2e variants + KAT replay determinism.
  • threshold/fuzz_verify_test.go -- FuzzVerifyParseSignature + FuzzVerifyRandomBytes.

Documentation updates

  • AXIOM-INVENTORY.md -- v0.7.0 EC residual axiom inventory (admit budget 0/0; 5 Lean-bridged + N codec + construction-level axioms).
  • PROOF-CLAIMS.md -- §3.1 and §3.7 updated to reflect the EC + Lean
    • Jasmin scaffold landing.
  • CRYPTOGRAPHER-SIGN-OFF.md -- v0.2; closes GATE-1, GATE-2, GATE-3a; opens GATE-3b, GATE-4, GATE-5 as v0.8.0 audit-grade targets.

v0.5.0 (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 Module-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 Module-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 Module-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

corona/primitives/hash.go no longer hardcodes blake3.New(). Every Sign-path primitive now takes a hash.HashSuite as its first argument:

PRNGKey(suite, skShare)                       // was PRNGKey(skShare)
PRNGKeyForRound(suite, skShare, sid)          // was PRNGKeyForRound(skShare, sid)
GenerateMAC(suite, TildeD, MACKey, ...)       // was GenerateMAC(TildeD, MACKey, ...)
GaussianHash(suite, r, hash, mu, sigma, ...)  // was GaussianHash(r, hash, mu, sigma, ...)
PRF(suite, r, sd_ij, key, mu, hash, n)        // was PRF(r, sd_ij, key, mu, hash, n)
Hash(suite, A, b, D, sid, T)                  // was Hash(A, b, D, sid, T)
LowNormHash(suite, r, A, b, h, mu, kappa)     // was LowNormHash(r, A, b, h, mu, kappa)

suite == nil resolves to the production default, Corona-SHA3 (cSHAKE256 / KMAC256 / TupleHash256 per FIPS 202 + NIST SP 800-185). The legacy Corona-BLAKE3 suite remains available via hash.NewCoronaBLAKE3() for cross-port byte checks.

sign.Party gains a Suite hash.HashSuite field, defaulted by NewParty to hash.Default(). Operators can construct with an explicit suite via NewPartyWithSuite(id, r, rXi, rNu, sampler, suite). The free function sign.Verify(...) keeps its previous signature and now resolves to the production default internally; the suite-explicit form is sign.VerifyWithSuite(suite, ...).

This closes the gap where the HIP-0077 claim that Corona uses SHA-3 cSHAKE256/KMAC256/TupleHash256 in production was structurally false at the Sign layer (only corona/reshare/, corona/dkg2/, corona/keyera/ were consuming corona/hash/HashSuite previously).

Follow-up — KAT regeneration

The historical BLAKE3 KAT transcripts emitted by cmd/corona_oracle_v2 were computed against the previous raw blake3.New() framing in primitives/hash.go. After this refactor, the oracle still emits under coronahash.NewCoronaBLAKE3(), but the framing now includes the suite's customization tags (CORONA-HC-v1, CORONA-HU-v1, CORONA-PRF-v1, etc.) and length-prefixing, so the emitted bytes no longer byte-match pre-refactor JSON.

The Corona-SHA3 production KATs are not yet emitted. Both lie outside the scope of this PR:

  • Regenerate the legacy BLAKE3 oracle JSON (go run ./cmd/corona_oracle_v2 emit --out ./test/kats/blake3) and cross-validate with the C++ port.
  • Land a parallel cmd/corona_oracle_v3 (or --suite flag) that emits Corona-SHA3 KATs under ./test/kats/sha3/ and pin them as the normative reference for downstream ports.

The skipped test TestKATsRegenerated in primitives/hash_test.go is the placeholder guard.