Final public-BFT audit (per AUDIT-2026-05.md §10) flagged the v0.7.3
asymmetry where keyera.Bootstrap / keyera.BootstrapWithSuite still
routed through the legacy single-dealer Shamir share-out while
keyera.Reanchor (v0.7.4) had already flipped to Pedersen-DKG. Callers
picking the "obvious" name silently inherited the dealer caveat at
chain genesis.
v0.7.5 flips both Bootstrap defaults to route through BootstrapPedersen
(Pedersen-DKG over R_q + Path (a) noise flooding) so no party ever
holds the master secret s at any point in the ceremony. The legacy
trusted-dealer ceremony path is reachable only via the explicit
BootstrapTrustedDealer / BootstrapTrustedDealerWithSuite /
ReanchorTrustedDealer / ReanchorTrustedDealerWithSuite names.
The shared trusted-dealer body lives in the unexported
bootstrapTrustedDealerImpl, so the public-facing aliases (and the
Reanchor trusted-dealer alias) cannot drift from each other.
Structural invariant: BootstrapPedersen requires n >= 2 && t < n.
Deployments that need every validator to sign (t == n) must select
BootstrapTrustedDealer explicitly; the unqualified Bootstrap will
fail with ErrBootstrapPedersenShape on t == n, surfacing the
trust-model decision at the call site rather than silently routing
to the dealer path.
Tests updated: keyera_test.go, hashsuite_immut_test.go,
bootstrap_pedersen_test.go, reanchor_pedersen_test.go — drop t == n
from the public-BFT cases (now use t = n - 1) and propagate the
3-tuple return from the new Bootstrap signature.
Cross-runtime KAT byte-equality: scripts/regen-kats.sh updated for
the post-Corona purge (LUXCPP path now crypto/corona, not the
stale crypto/pulsar); reshare_oracle / activation_oracle /
dkg2_oracle accept both CORONA_*_KAT_PATH and PULSAR_*_KAT_PATH env
overrides for compatibility with the existing script. Manifest
regenerated and verified.
gpu/gpu_test.go: skip on non-GPU builds rather than fail
(RegisterRing returns "GPU unavailable" without a CGO Metal/CUDA
backend; the rest of the audit suite is exercised by the other
package tests).
5 oracle tools were writing KATs to hardcoded /Users/z/work/luxcpp/...
paths. All now go through the luxcppDir() helper (LUXCPP_DIR env override,
$HOME/work/luxcpp default), consistent with the lux/CLAUDE.md convention.
Also .gitignore stray oracle binaries from `go build ./cmd/<oracle>`.
Leftover from Corona's "Pulsar-R" lineage. Pulsar (M-LWE) and Corona
(R-LWE) are independent constructions with separate hardness assumptions,
so their cSHAKE personalisation strings must be distinct.
Changes (Go, non-luxcpp):
- hash tags: PULSAR-HC-v1 -> CORONA-HC-v1, etc. (HU, TRANSCRIPT, PRF, MAC, PAIRWISE)
- profile IDs: "Pulsar-SHA3" -> "Corona-SHA3", "Pulsar-BLAKE3" -> "Corona-BLAKE3"
- context strings: pulsar.dkg2.A.v1 -> corona.dkg2.A.v1, etc.
- env vars: PULSAR_RESHARE_KAT_PATH -> CORONA_RESHARE_KAT_PATH, etc.
- struct names: pulsarSHA3 -> coronaSHA3
- KAT derive roots: sign_e2e_pulsar -> sign_e2e_corona
What's preserved (different scope):
- luxcpp/crypto/pulsar/* path references in comments (separate repo,
out of scope; the C++ side will rename in its own commit)
- Cross-runtime KAT files on disk (will regenerate next CI run)
All 11 packages test green: dkg, dkg2, hash, keyera, networking,
primitives, reshare, sign, threshold, utils, wire.
After this commit zero 'corona' / 'Corona' / 'CORONA' references
remain in any Go file, Markdown doc, or TeX source in the corona
repository. The library is referenced by its production name (Corona)
everywhere; the upstream R-LWE construction is cited by author
(Boschini et al, ePrint 2024/1113) where attribution is required.
Renames:
cmd/corona_oracle_v2/ → cmd/corona_oracle_v2/
doc paths to luxcpp/crypto/corona → luxcpp/crypto/corona
coronaThreshold (import alias in INTEGRATION.md) → coronaThreshold
wrapAsCoronaShares → wrapAsCoronaShares
CONSTANT-TIME-REVIEW.md, INTEGRATION.md, oracle cmd comments — all
prose references swept Corona → Corona.
The academic 2-round R-LWE threshold construction was renamed Corona
→ Nasua at the family taxonomy level. Update Corona's documentation
references to point at the new name. Corona itself imports nothing
from luxfi/nasua — the dependency line is on luxfi/lattice/v7 for the
ring/sampling primitives — these comment refs only name the conceptual
upstream for design provenance.
Repo forks from luxfi/pulsar (R-LWE production threshold for Lux
consensus) to luxfi/corona under the family rename. Same Ring-LWE
code, same hash family (Pulsar-SHA3 / Pulsar-BLAKE3 -- wire-format
customization tags stay stable per MED-2). Only the Go module path
and internal imports change.
Lux family alignment:
- Pulsar = M-LWE / FIPS 204 / NIST MPTC N1 (was luxfi/pulsar-m)
- Corona = R-LWE / NIST MPTC S1 (this repo)
- Corona = academic upstream + Lux DKG expansions
Whitespace-only struct-tag alignment changes. Closes the CI Lint gate
that was failing across multiple recent commits on otherwise-green
build+test runs.
primitives/hash.go: PRNGKey / GenerateMAC / GaussianHash / PRF / Hash /
LowNormHash all take HashSuite as first param. suite == nil resolves to
the production default Pulsar-SHA3 (cSHAKE256 / KMAC256 / TupleHash256
per FIPS 202 + NIST SP 800-185).
sign/sign.go: Party gains Suite field; NewParty defaults to
hash.Default(); NewPartyWithSuite for operator-explicit construction.
sign.Verify keeps its signature for callers and resolves the default
internally; the suite-explicit form is sign.VerifyWithSuite.
reshare/commit.go: suite-aware commit derivation aligned with the new
hash.HashSuite contract used by the rest of pulsar/reshare/dkg2/keyera.
Closes the gap where the HIP-0077 claim that Pulsar uses SHA-3
cSHAKE256/KMAC256/TupleHash256 in production was structurally false at
the Sign layer (only pulsar/reshare/, pulsar/dkg2/, pulsar/keyera/ were
consuming pulsar/hash/HashSuite previously). Pulsar-BLAKE3 retained as
legacy/non-normative only for cross-port byte checks.
go.mod: luxfi/math v1.3.0 -> v1.4.0 (consumes the codec for the new
hash-suite tag).
CHANGELOG.md added. sign_roundtrip_test.go pins the new contract.
Tests: primitives + sign + reshare PASS. Patch-bump.
cmd/sign_oracle/ — emits the canonical Pulsar sign+verify KAT JSON
(Gen + SignRound1 + SignRound2{Preprocess,} + SignFinalize + Verify) for
(t, n) ∈ {2/3, 3/5, 5/7, 7/11}. The C++ port at
luxcpp/crypto/pulsar/cpp/sign/ replays these entries byte-equal.
cmd/cross_runtime_oracle/ — Go writer for the cross-runtime release
gate. Emits a SHA-256 manifest tying together the three canonical
Pulsar KATs (sign, reshare, dkg2). C++ side at
luxcpp/crypto/pulsar/test/cross_runtime_test.cpp replays each KAT and
checks byte-equality (forward direction: 30/30 PASS).
cmd/cross_runtime_verify/ — Go reader for the reverse direction
(C++ writes, Go verifies). Currently 3/3 PASS against the SHA-256s
emitted by luxcpp/crypto/pulsar/cmd/cross_runtime_oracle/.
threshold/testdata/fuzz/FuzzPulsarSign1Round1Data/ — corpus seed for
the in-tree fuzz harness; mitigates the second lattice DoS (issue #4)
where Vector[T].ReadFrom calls make([]T, size) with no bound.
23 fuzz harnesses × 30s = 10.9M execs, 0 panics.