53 Commits
Author SHA1 Message Date
Hanzo AI 95c37cc15b deps: bump Go to 1.26.4 across go.mod, Dockerfiles, GH Actions
Workspace-wide sync. luxfi/node already shipped on 1.26.4 in v1.30.6
(commit 121aca1fa9); this is the cross-repo catch-up.
2026-06-07 11:04:02 -07:00
Hanzo AI ad169a8368 docs: bump Go reference 1.26.x → 1.26.4
Workspace-wide sync. luxfi/node already shipped on 1.26.4 in v1.30.6;
this prose-doc catch-up keeps the runbook in lock-step with the
actual Dockerfile/go.mod pin.
2026-06-07 10:49:56 -07:00
Hanzo AI a5db410b15 deps: bump Go to 1.26.4 across go.mod, Dockerfiles, GH Actions
Workspace-wide sync. luxfi/node already shipped on 1.26.4 in v1.30.6
(commit 121aca1fa9); this is the cross-repo catch-up.
2026-06-07 10:44:51 -07:00
Hanzo AI 2e70258a05 go: 1.26.3 → 1.26.4 (security: crypto/x509, mime, net/textproto) 2026-06-06 22:05:08 -07:00
Hanzo AI 6de03e5380 corona → corona — final sweep (live source clean) 2026-06-06 16:37:53 -07:00
Hanzo AI ff8de21571 WIP: session checkpoint 2026-06-05 (codec rip in flight) 2026-06-05 15:33:52 -07:00
Hanzo AI bf70b85833 audit 2026-06: TEE + GPU + public-permissionless-chain safety + corona->corona sweep
AUDIT-2026-06.md ships the four-dimensional audit:

D1 Permissionless safety: PASSED with two minor open items for v0.7.6.
   Rogue-key NOT APPLICABLE (single global (A, bTilde); no per-party pk
   in the BLS-aggregation sense). Adaptive corruption documented as
   paper-cited only (carryover; GATE-4 target). Slashable equivocation
   evidence is cryptographically extractable via signed dkg2.Complaint
   and activation-cert non-verification. Front-running: sid IS bound
   into PRNG seed / MAC / transcript hash (CRIT-1 fix 2026-05-03), but
   plumbed as Go int (64-bit), not 32-byte randomness as threat-model
   claims — D1-2 MEDIUM, doc tightening for v0.7.6. D1-3 MINOR: extend
   Complaint to signing-round equivocation.

D2 TEE integration: WAS A GAP. Closed by this audit via the new
   docs/mptc/tee-integration.md — full per-platform spec for AMD
   SEV-SNP (primary Linux path), NVIDIA Confidential Computing
   (H100/H200/B200 CC mode) when gpu.UseAccelerator() is used in
   production, Intel TDX (alternative), Apple Secure Enclave (local-
   only defense-in-depth on Apple Silicon). Intel SGX explicitly NOT
   RECOMMENDED. Decomplecting rule held: ZERO Corona kernel code
   change required for §3.1, §3.3, §3.4; §3.2 adds one optional
   plumbing function (gpu.MaybeRegisterAttested) tracked for v0.7.6.
   The TEE layer sits OUTSIDE the cryptographic math — Corona observes
   nothing of TEE state.

D3 GPU acceleration inventory: corona/gpu is a thin SubRing-registration
   shim around luxfi/lattice/v7/gpu — no kernels live in corona/.
   dkg2_parallel.go is goroutine fan-out (honestly relabelled in
   66f7521), not GPU dispatch. Sister-repo lux-private/gpu-kernels/
   ops/mpcvm/*/mpcvm_corona.* and ops/crypto/corona/ carry the
   legacy name — D3-1 INFORMATIONAL, cross-repo rename TODO.

D4 corona->corona sweep (in-repo COMPLETE):
   * Makefile: BINARY_NAME corona -> corona; banner + docker tag.
   * Dockerfile: addgroup/adduser/binary-path/entrypoint.
   * .github/workflows/ci.yml: bin/corona -> bin/corona; artifact
     name corona-${runner.os}-${arch}; release output name pattern.
   * .golangci.yml: local-prefixes: corona -> github.com/luxfi/corona.
   * docs/{app,content,lib,out,public,.source,mdx-components.tsx,...}
     DROPPED — a fumadocs Next.js site (3057 lines) that framed Corona
     as a privacy ring-signature scheme (Schnorr + linkability +
     hash-to-curve + "ring signatures for transaction privacy"). That
     is NOT Corona — Corona is a 2-round R-LWE threshold sig (Boschini
     et al. 2024/1113). The site referenced a non-existent
     github.com/luxfi/corona Go module. Removed.
   * KEPT: docs/mptc/ (authoritative submission docs).
   * KEPT: historical refs in CHANGELOG.md, LLM.md, and
     CRYPTOGRAPHER-SIGN-OFF.md — they document the prior v0.4.x purge
     and are correct as historical context.
   * Cross-repo (luxfi/threshold, lux-private/gpu-kernels, luxfi/node)
     inventoried as D4-1 INFORMATIONAL — sister-repo work items.

Build clean (GOWORK=off go build ./...). gofmt -s clean. vet clean.
Full short test suite green: dkg, dkg2, gpu, hash, keyera, networking,
primitives, reshare, sign, threshold, utils, wire — ALL ok.

KATs unchanged: no Go code paths edited; FIPS-TRACEABILITY byte-
equality contract preserved. v1.x ABI unchanged: no public Go API
modified. Constant-time discipline preserved: no crypto/subtle paths
touched; CONSTANT-TIME-REVIEW.md remains authoritative.

Production deployment posture (unchanged from v0.7.5): APPROVED WITH
ROADMAP GATES for public-permissionless deployment as a R-LWE
threshold signature primitive in Lux Quasar consensus, with v0.8.0
GATE-3b (10^9-sample dudect on pinned CPU) + GATE-4 (external audit)
+ GATE-5 (Jasmin extraction byte-walk) as carryover roadmap items.
2026-06-03 11:40:06 -07:00
Hanzo AI 84bae8b03c fix: gofmt -s across repo (CI format check) 2026-06-02 11:37:47 -07:00
Hanzo AI ee2c5b8864 threshold: canonical wire codec for Signature, GroupKey, VerifyBytes
Closes the long-standing Red HIGH B2 gap that forced luxfi/threshold's
JSON-RPC dispatcher (pkg/thresholdd/corona.go, pulsar.go) to refuse
every Corona op because Signature and GroupKey lacked stable
cross-process wire formats.

Adds:

  Signature.MarshalBinary / UnmarshalBinary
  GroupKey.MarshalBinary  / UnmarshalBinary
  VerifyBytes(gkBytes, msg, sigBytes) bool

Layout is domain-separated (CORS magic for Signature, CORG for
GroupKey) so the dispatcher cannot confuse the two slots. Versioning
(2-byte v1) leaves room for byte-format evolution under explicit
opt-in. Bounded validation flows through corona/wire so a malformed
length cannot trigger an oversized allocation.

VerifyBytes is the stateless surface that pkg/thresholdd consumes:
bytes-in, bool-out, no per-process state, byte-equal re-marshaling on
the roundtrip. Cross-wire feeds (GroupKey magic in the Signature slot)
are explicitly rejected.

Tests cover happy path (sign -> marshal -> unmarshal -> verify, plus
byte-equal re-marshal), tampered sig and tampered message rejection,
malformed input rejection (empty, too-short, wrong magic, wrong
version), and cross-wire confusion rejection.

Cannot t.Parallel: threshold.GenerateKeys mutates the sign package
globals K and Threshold (threshold.go:123-124); parallel use of the
kernel races on those globals. The wire codec itself is pure.
2026-05-31 11:29:23 -07:00
Hanzo AI 66f75216fa dkg2: rename gpu fan-out files to dkg2_parallel.go (honest labelling)
The two build-tagged files (dkg2_gpu_default.go, dkg2_gpu_accel.go)
implemented a goroutine fan-out, NOT a GPU dispatch. Real GPU NTT for
the underlying ring math lives in luxfi/lattice/v7/gpu and is reached
via the consensus engine accel pipeline.

Collapse to a single file dkg2_parallel.go with no build tag. Default
OFF (matching the prior non-gpu build); tests opt in via SetDKG2GPUForTest.

The exported helper name SetDKG2GPUForTest is left as-is to avoid breaking
existing test callers; the legacy `GPU` in the name is documented as a
historical misnomer.
2026-05-24 14:17:50 -07:00
Hanzo AI 1d44430e5d keyera: v0.7.5 — public-BFT Bootstrap default closes last trusted-dealer dispatch
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).
2026-05-21 19:04:55 -07:00
Hanzo AI 44af920d11 LLM.md: pin v0.7.4 commit sha 2026-05-21 18:25:54 -07:00
Hanzo AI 130b3e71d7 keyera: ReanchorPedersen — public-BFT-safe reanchor via dkg2 + Path (a)
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 / ReanchorWithSuite through ReanchorPedersen
by default. Pedersen-DKG over R_q + Path (a) noise flooding means no
party holds the new era's master secret s at any point in the
rotation. The legacy trusted-dealer behaviour stays available behind
explicit ReanchorTrustedDealer / ReanchorTrustedDealerWithSuite
aliases for HSM / TEE ceremony scenarios.

Reanchor and ReanchorWithSuite now return (*KeyEra, *BootstrapTranscript,
error) — the transcript must be committed to the chain to ratify
the new era. Existing tests TestReanchorOpensNewEra and
TestReanchorMayChangeSuite updated to use t=2,n=3 since the
Pedersen-DKG path requires t < n.

Also drops the 12-iteration Newton's-method mathSqrt in favour of
stdlib math.Sqrt in pathANoiseParameters. The "keeps imports tight"
rationale was false parsimony; stdlib gives the canonical IEEE 754
result without ULP drift. No deployed KAT pins the function output.

Audit doc updated: §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 §Bootstrap-Trust decision matrix expanded to
cover Reanchor; default routing pinned to Pedersen-DKG for both
Bootstrap and Reanchor.

All keyera tests passing:
  go test -count=1 -short -timeout 300s ./keyera/
  ok  github.com/luxfi/corona/keyera   4.132s

Files:
  keyera/reanchor_pedersen.go      (new)
  keyera/reanchor_pedersen_test.go (new)
  keyera/keyera.go                 (Reanchor signature change + aliases)
  keyera/bootstrap_pedersen.go     (mathSqrt → math.Sqrt)
  keyera/keyera_test.go            (t=2,n=3 for Pedersen path)
  keyera/hashsuite_immut_test.go   (t=2,n=3 for Pedersen path)
  AUDIT-2026-05.md
  DEPLOYMENT-RUNBOOK.md
  CHANGELOG.md
  LLM.md
2026-05-21 18:25:43 -07:00
Hanzo AI deb2f2f592 LLM.md: pin v0.7.3 commit sha 2026-05-21 17:09:47 -07:00
Hanzo AI 600e61e75f keyera: BootstrapPedersen — public-BFT-safe bootstrap via dkg2 + Path (a)
Closes the last trusted-dealer caveat in the Bootstrap ceremony. The
trusted-dealer path is retained under a renamed alias for genesis
ceremonies where a non-distributed trust root is acceptable by policy
(publicly observable HSM-bound foundation MPC with commit-and-reveal
entropy from genesis validators).

Construction.

BootstrapPedersen drives the keyera-genesis ceremony through dkg2/
(Pedersen-DKG over R_q with public matrices A, B derived from BLAKE3-XOF
on the nothing-up-my-sleeve tags `corona.dkg2.{A,B}.v1`):

  1. Each party samples Gaussian f_i, g_i in R_q^Nvec[x]_{deg<t}, runs
     dkg2.Round1 → broadcasts Pedersen commits C_{i,k} = A·NTT(c_{i,k})
     + B·NTT(r_{i,k}) and sends (share_{i→j}, blind_{i→j}) privately
     over an authenticated p2p channel.

  2. Each recipient j runs dkg2.Round2Identify, verifying every incoming
     pair against the commits in constant time. On mismatch the recipient
     emits a signed ComplaintBadDelivery naming the misbehaving sender.

  3. Each recipient holds its standard-form share s_j of the master
     secret s; NO PARTY ever reconstructs s.

  4. Path (a) noise flooding (LP-073 §07 Mapping). Each party broadcasts
     β_j = A·NTT(λ_j · s_j) + e_j' where e_j' ~ D(σ'') and
     σ'' = κ·σ_E·√n is the LP-073 §5 flood bound.

  5. All parties aggregate b = Σ_j β_j = A·s + e'' in NTT-Mont; the
     Corona-Sign-shaped public key bTilde = Round_Xi(b) drops cleanly
     into threshold.GroupKey. The existing 2-round threshold-sign path
     accepts the noise-flooded GroupKey unchanged.

Security claims.

- Hiding under decisional MLWE on the wide concatenation [A | B]
  (Pedersen-DKG; papers/lp-073-pulsar §07).
- Per-party Gaussian flooding bound σ'' = κ·σ_E·√n covers the LWE
  leakage budget (Path (a) flood-bound, LP-073 §5).
- Identifiable abort with constant-time verification (dkg2.Round2-
  Identify; subtle.ConstantTimeCompare across all M slots).
- No master-secret reconstruction at any point in the ceremony
  (structural; see TestBootstrapPedersen_NoMasterSecretInMemory).

Tests (keyera/bootstrap_pedersen_test.go; all green).

- TestBootstrapPedersen_RoundTrip — 5-party Pedersen-DKG with t=3;
  transcript determinism; bTilde stability across entropy replays.
- TestBootstrapPedersen_DishonestDealer — tampered share-to-0 triggers
  ErrBootstrapPedersenAbort naming sender 2; AbortEvidence carries a
  re-checkable ComplaintBadDelivery.
- TestBootstrapPedersen_FollowedBySign — bootstrap → 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 no two
  parties' SkShares/Lambdas collide.
- TestBootstrapPedersen_ParameterValidation — bounds checking.
- TestBootstrapPedersen_DefaultSuite — nil suite resolves to Corona-SHA3.
- TestBootstrapTrustedDealer_LegacyAlias — legacy alias 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, Bos-Lyubashevsky, Crites-
  Komlo-Maller) are complementary or non-blocking; no SOTA refresh
  blocks this revision. Path (a) bound stays comfortable for committee
  sizes up to n=256.
- DEPLOYMENT-RUNBOOK.md §Bootstrap-Trust — decision matrix documenting
  Option A (BootstrapPedersen, recommended) vs Option B
  (BootstrapTrustedDealer, ceremony-only).
- CHANGELOG.md — v0.7.3 entry listing the new public surface, tests,
  and documentation deltas.
- keyera/keyera.go — inline trust-model documentation pointing at
  BootstrapPedersen as the public-BFT-safe alternative.

API summary.

New (keyera package):
  - BootstrapPedersen(suite, t, validators, groupID, eraID, entropy)
    (*KeyEra, *BootstrapTranscript, error)
  - FinishBootstrapPedersen(suite, t, validators, ..., dkgParams,
    sessions, round1) (*KeyEra, *BootstrapTranscript, error)
  - BootstrapTrustedDealer / BootstrapTrustedDealerWithSuite — legacy
    aliases for the single-dealer ceremony.
  - BootstrapTranscript — public, byte-stable ceremony record.
  - AbortEvidence + ExtractAbortEvidence(err) — identifiable-abort
    consumption surface.
  - ErrBootstrapPedersenAbort, ErrBootstrapPedersenShape — typed errors.

Wire / KAT compatibility.

- Existing trusted-dealer KATs continue to byte-match
  ~/work/luxcpp/crypto/corona/ (no behaviour change on that path).
- BootstrapPedersen adds new ceremony bytes; deterministic given a
  reproducible entropy stream. A future cross-runtime port can pin
  them via BootstrapTranscript.TranscriptHash.
2026-05-21 17:09:36 -07:00
Hanzo AI f49e87e4ac cmd/m4_{precrand,shamir_tk}_oracle: switch from legacy /Users/z/work/lux/cpp to luxcppDir() 2026-05-21 14:59:30 -07:00
Hanzo AI cee6cdb707 cmd/*_oracle: use luxcppDir() everywhere — kill all hardcoded /Users/z paths
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>`.
2026-05-21 14:57:03 -07:00
Hanzo AI 0378901ec6 cmd/m4_uniform_oracle: use luxcppDir() helper, drop hardcoded /Users/z path 2026-05-21 14:56:43 -07:00
Hanzo AI 2e22541859 gpu: opt corona threshold signing into lattice/ring GPU NTT dispatch
Add corona/gpu package — the single, decomplecting point where corona
opts into the lattice library's per-SubRing GPU NTT dispatcher.

Architecture (decomplected).

The lattice library already owns ALL build-tag plumbing for GPU NTT:
ring.SetGPUDispatchers (subring_ops.go) is the canonical hook; the
lattice/gpu package installs it under `cgo && gpu` build tags and
provides a real CPU fallback under !cgo or !gpu. Output is byte-equal
to ring.SubRing.NTT by lattice's own contract.

corona/gpu adds the corona-side bridge: UseAccelerator() flips a
global flag, NewParams() across corona consults the flag via
MaybeRegister and binds each created Ring's SubRings into the lattice
GPU registry. Single source of truth for the opt-in; no build tags
inside corona.

Threshold gating (honest).

Single-poly Metal NTT at corona's production N=256 is roughly 4-6x
SLOWER than pure-Go ring.SubRing.NTT (measured: BenchmarkPulsarSign_
5of7 force-GPU 7.1s vs CPU 1.1s; 14of21 force-GPU 23.5s vs CPU 5.9s).
The GPU win exists only in BATCHED dispatch (many polynomials per
kernel launch), which requires future engine-layer plumbing of
lattice/gpu.MontgomeryNTTContext.Forward(data, batch>=4) bypassing
the per-poly r.NTT() pinch point.

Therefore UseAccelerator() picks defaultThreshold=1024 — above
corona's N=256 — so the SubRing dispatch is armed but does not fire
on single-poly NTT. The registry remains primed for any future batch
caller (e.g. FHE bootstraps in thresholdvm sharing this library).

UseAcceleratorForce() (threshold=1) is provided strictly for the
correctness gate: every NTT call routes through the GPU so the
byte-equality test in threshold/threshold_gpu_test.go exercises the
GPU path end-to-end. Production callers use UseAccelerator() instead.

Byte-equality.

TestThresholdSign_CPU_vs_GPU_ByteIdentical runs the full 2-round
Pulsar signing protocol with GPU dispatch off and forced-on (same
deterministic dealer randomness, same message) and asserts byte-equal
sig.C / sig.Z / sig.Delta. Passes under CGO_ENABLED=0, CGO_ENABLED=1,
and CGO_ENABLED=1 -tags gpu. Existing TestDKG2_GPU_ByteEqual coverage
extends across n=3,5,7,11,21 (production shape).

Wiring.

NewParams() in sign-bound packages — threshold, dkg2, dkg, reshare —
calls corona/gpu.MaybeRegister(r) for the main Q ring. RXi and RNu
are power-of-two moduli; the NTT path is not taken on them.

Tests.

Full corona test suite passes under both build modes:
  - CGO_ENABLED=0 go test ./...    => all green
  - CGO_ENABLED=1 -tags gpu test   => all green
2026-05-21 13:41:15 -07:00
Hanzo AI ed5844a17d patent-claims: novelty triage drafts (attorney-prep, not filed) 2026-05-19 11:29:59 -07:00
Hanzo AI 72af1f2099 Tier A full closure (v0.7.0): EC theories admit 0/0 + Lean bridges + Jasmin CT + dudect harness + e2e/fuzz
- proofs/easycrypt/: 13 EC files mirroring Pulsar layout, admit budget 0/0 statically pinned by scripts/checks/ec-admits.sh
- proofs/lean-easycrypt-bridge.md: 5-axiom Lean ↔ EC bridge (lagrange_inverse_eval, threshold_partial_response_identity, reconstruct_linear, shamir_correct, add_share_zeroR)
- jasmin/{lib,rlwe,threshold}/: round1/round2/combine .jazz with #ct annotations
- ct/dudect/: Verify + Combine harness (arm64 + x86_64 build tags)
- scripts/check-high-assurance.sh + scripts/checks/{ec-admits,ec-regressions,ec-refinement-scaffold,ec-compile,jasmin,extraction}.sh + check-lean-bridge.sh
- AXIOM-INVENTORY: residual axioms enumerated with closure pathways
- CRYPTOGRAPHER-SIGN-OFF: APPROVED WITH ROADMAP GATES; GATE-1+2+3a CLOSED; GATE-3b (dudect 10⁹ pinned CPU) + GATE-4 (external audit) + GATE-5 (Jasmin extraction filling out byte-walk) roadmap v0.8.0

Tier label: Tier A full closure scaffold landed; matches Pulsar v1.0.7 posture (admit 0/0 + Lean bridges + Jasmin + dudect harness wired). The submission-grade dudect run + external audit are v0.8.0 audit-track items.
2026-05-19 08:38:09 -07:00
Hanzo AI 1d483f7389 proofs: Lean <-> EC bridge map + check-lean-bridge.sh CI guard
5-axiom Lean-to-EasyCrypt correspondence for Corona, mirroring Pulsar's
structure:

  lagrange_inverse_eval (Corona_N1.ec)
    -> Crypto.Corona.Shamir.shamir_correct_at_target

  threshold_partial_response_identity (Corona_N1.ec)
    -> Crypto.Threshold.Lagrange.threshold_partial_response_identity

  add_share_zeroR (Corona_N4.ec)
    -> Mathlib AddCommMonoid instance

  reconstruct_linear (Corona_N4.ec)
    -> Crypto.Threshold.Lagrange.combine_distributes_over_sum

  shamir_correct (Corona_N4.ec)
    -> Crypto.Corona.Shamir.shamir_correct_at_target

CI guard `scripts/check-lean-bridge.sh` verifies for every EC axiom
that (1) the axiom still exists as `axiom` (not silently demoted to
`lemma`), (2) it carries an inline citation comment naming the Lean
theorem, (3) the Lean theorem still exists at the named path. It also
checks that every EC file mentioned in the bridge doc exists on disk.

Auto-detects the Lean repo at ~/work/lux/proofs/lean or sibling
locations. Skips Lean-side existence checks if no Lean repo is on disk.

Mirrors ~/work/lux/pulsar/scripts/check-lean-bridge.sh exactly.
2026-05-19 08:38:08 -07:00
Hanzo AI e9e4529a09 proofs: write EC theories (Corona_N1, N4, refinement chain) -- admit budget 0/13
13 EasyCrypt theories mirroring Pulsar's Tier A layout:

  Corona_N1.ec                       master byte-equality theorem
  Corona_N4.ec                       reshare public-key preservation
  Corona_N1_Memory.ec                byte-memory model + frame laws
  Corona_N1_Signature_Codec.ec       signature codec
  Corona_N1_{Combine,Sign}_Layout.ec input/output layouts
  Corona_N1_{Combine,Sign}_Refinement.ec  byte-walk + sep + frame axioms
  Corona_N1_{Combine,Sign}_Wrapper.ec     wrapper bridges
  Corona_N1_Extracted.ec             IMPLEMENTATION-BACKED theorem
  lemmas/RLWE_Functional.ec          in-house Boschini Sign mechanization
  lemmas/Corona_CT.ec                CT obligations

Admit budget: 0/0 across the 13-file set. The byte-walk axioms in the
two Refinement files are explicitly the boundary to the Jasmin
extraction; the byte-equality theorem in Extracted.ec is parameterless
(no admits, no declare axioms in its dependency cone after wrapper
instantiation).

Refines: ~/work/lux/corona/sign/sign.go + threshold/threshold.go.
Cites: Boschini et al. ePrint 2024/1113 §3-§5; ~/work/lux/proofs/lean.
Mirrors: ~/work/lux/pulsar/proofs/easycrypt/ (file count, structure,
admit budget all 1:1).
2026-05-19 08:37:57 -07:00
Hanzo AI 8b69a441fc submission: write AXIOM-INVENTORY + FIPS-TRACEABILITY + CRYPTOGRAPHER-SIGN-OFF (Tier A doc-shape closure)
Three Tier-A-required submission docs that were honestly omitted in
the v0.5.0 scaffold per the cryptographer agent's directive ("don't
fabricate proof claims that don't exist"):

- AXIOM-INVENTORY.md: enumerates construction-level + implementation-level
  axioms with explicit closure plans. EC theory shells are roadmap v0.7.0;
  this doc establishes the inventory the eventual proofs will discharge.
- FIPS-TRACEABILITY.md: Boschini ePrint 2024/1113 + IEEE S&P 2025
  section → code mapping. R-LWE has no FIPS standard; Boschini paper
  is the construction-level normative reference.
- CRYPTOGRAPHER-SIGN-OFF.md: APPROVED WITH GATES. Verdict mirrors
  Pulsar's v1.0.7 sign-off structure. Gates: GATE-1 EC theory shells,
  GATE-2 Lean ↔ EC bridge, GATE-3 dudect 10⁹ samples, GATE-4 external
  audit. All on v0.7.0 / v0.8.0 roadmap.

Tier label honest assessment: **Tier A documentation shape complete**;
the algorithmic-soundness gates inherit from Boschini paper, the
formal-methods gates are explicitly roadmap-tracked, not fabricated.
This positions Corona for NIST MPTC v0.2 submission window with full
review-ready doc package.
2026-05-19 06:53:34 -07:00
Hanzo AI d77dbecbf9 Merge origin/main into submission scaffold (resolve LICENSING: take patent-protected tier; merge patent posture pointer from scaffold) 2026-05-18 23:12:37 -07:00
Hanzo AI b9219d13fd 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.
2026-05-18 23:10:13 -07:00
Hanzo DevandGitHub 7cd6b6e71c chore: bump Go toolchain to 1.26.3 (#2)
Pin Go version to 1.26.3 across go.mod, CI workflows, and Dockerfiles
for canonical alignment with the rest of the luxfi/* stack.
2026-05-16 16:42:40 -07:00
Hanzo DevandGitHub 29a8ff3e4d Merge pull request #1 from luxfi/licensing/canonical-pointer
docs: add LICENSING.md pointer to canonical Lux IP strategy
2026-05-15 16:40:43 -07:00
Hanzo Dev e7955d7690 docs: add LICENSING.md pointing at canonical Lux IP strategy
Single LICENSING.md file referencing the canonical three-tier IP and
licensing strategy at github.com/luxfi/.github/blob/main/profile/README.md.

LICENSE file is unchanged; this only adds a navigational pointer.
2026-05-15 16:40:36 -07:00
Hanzo AI 29989638e0 threshold: add parallel VerifyBatch — N-signature throughput for consensus
Corona signatures are Ring-LWE (C, Z, Delta) ring-polynomial triples,
not FIPS 204 byte-equal (that's Pulsar's Module-LWE sibling). Single
Verify is the only place this package touches the sign.Verify
predicate; VerifyBatch composes it across N (groupKey, message,
signature) tuples in parallel via a GOMAXPROCS-bounded worker pool.

Public surface added:
  - VerifyBatch(gks, msgs, sigs) -> ([]bool, error)
  - VerifyBatchAll(gks, msgs, sigs) -> (bool, error)
  - ErrBatchSizeMismatch

Pure Go: NO CGO / accel dep. A future Metal/CUDA NTT-batch kernel
over the polynomial-arithmetic hotspot would live in luxfi/accel
behind the same byte interface; consumers wanting GPU dispatch call
accel directly against the wire bytes. This file is the portable
fallback everyone gets for free.

Tests (GOWORK=off go test ./threshold/ -run TestVerifyBatch):
  TestVerifyBatch_AllValid            (n=4, all valid)      PASS
  TestVerifyBatch_OneCorrupt          (message swap @1)     PASS
  TestVerifyBatch_StructuralMismatch  (slice len mismatch)  PASS
  TestVerifyBatch_Empty                                     PASS
Full ./threshold suite: ok 2.068s.
2026-05-15 01:42:48 -07:00
Hanzo AI 2fad96fbc8 corona: don't mix — QUASAR-PULSAR-* prefixes -> QUASAR-CORONA-* in Corona's table
Per user directive: don't mix Pulsar and Corona naming. Corona's design
doc was documenting Pulsar tag prefixes for what are actually Corona's
own rows in the Quasar consensus tag scheme. Fixed:

  QUASAR-PULSAR-BUNDLE-v1   -> QUASAR-CORONA-BUNDLE-v1
  QUASAR-PULSAR-SIGN1-v1    -> QUASAR-CORONA-SIGN1-v1
  QUASAR-PULSAR-SIGN2-v1    -> QUASAR-CORONA-SIGN2-v1
  QUASAR-PULSAR-COMBINE-v1  -> QUASAR-CORONA-COMBINE-v1
  QUASAR-PULSAR-REFRESH-v1  -> QUASAR-CORONA-REFRESH-v1
  QUASAR-PULSAR-RESHARE-v1  -> QUASAR-CORONA-RESHARE-v1
  QUASAR-PULSAR-REANCHOR-v1 -> QUASAR-CORONA-REANCHOR-v1

Plus Lane column for these rows: Pulsar -> Corona.

Preserved legitimate Pulsar cross-references: sister-kernel comparison,
fork lineage (Corona forked from Pulsar), shared LSS lifecycle concepts.
Those documentation references aren't mixing — they're describing
Corona's relationship to Pulsar.
2026-05-13 15:39:32 -07:00
Hanzo AI 610263072a corona: doc drift cleanup — CHANGELOG references match renamed Go code
Scientist audit flagged stale Pulsar references in CHANGELOG.md (e.g.
'Pulsar-SHA3' production default name, 'pulsar/primitives/hash.go' paths).
The Go code was already renamed in commit a2c1d1d; this aligns the docs.

DESIGN.md's QUASAR-PULSAR-*-v1 prefix table is preserved — those are
Quasar consensus lane prefixes describing Pulsar pulse messages, NOT
Corona-internal tags. Different scope.
2026-05-13 14:28:54 -07:00
Hanzo AI a2c1d1da31 corona: symmetric domain separation — PULSAR-* tags -> CORONA-*
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.
2026-05-13 14:19:13 -07:00
Hanzo AI 44c1c990c3 go.mod: bump go directive to 1.26.3 (security advisory) 2026-05-12 21:29:02 -07:00
Hanzo AI 7932be2d56 ci: Fresh-Clone CI default to bash shell (fixes 'set -o pipefail' on sh) 2026-05-12 14:54:45 -07:00
Hanzo AI 06c2046dce gofmt: fix formatting in cmd/{corona_oracle_v2,dkg_oracle,shamir_general_oracle,sign_oracle}/main.go 2026-05-12 12:24:22 -07:00
Hanzo AI 9e673bbf96 corona/papers: corona2025 cite → boschini2024corona; coronaThreshold → coronaThreshold in TeX 2026-05-12 10:04:47 -07:00
Hanzo AI 614094050d corona: kill all remaining Corona identifiers in code + docs
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.
2026-05-12 10:04:40 -07:00
Hanzo DevandGitHub 99b2bebd03 Update README.md 2026-05-12 09:21:34 -07:00
Hanzo AI ed44294f0e README: drop 'academic' framing, replace nasua hyperlink with ePrint citation 2026-05-12 09:12:25 -07:00
Hanzo AI 35b40a5adf README: independent library + Double-Lattice composition with pulsar
Corona (Ring-LWE) and Pulsar (Module-LWE) are independently usable
threshold ML-DSA libraries — no shared types, no import line between
them. Each can be selected as a chain's sole PQ threshold layer.

The academic Corona upstream (Boschini et al, ePrint 2024/1113) is
referenced as luxfi/nasua (historical reference fork, trusted-dealer
DKG, not for public-chain use). Corona is the production track that
adds the lifecycle the academic fork lacks (Pedersen DKG over R_q +
proactive resharing + identifiable abort).

Lux primary-network QuasarCert layers both lattice families as a
Double-Lattice PQ defence with optional BLS classical fast-path and
per-validator ML-DSA-65 rolled up via STARK/FRI through P3Q.
2026-05-12 09:09:42 -07:00
Hanzo AI 743274c1b3 corona: docs reference luxfi/nasua (academic upstream), not luxfi/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.
2026-05-12 09:00:59 -07:00
Hanzo AI 3463d122e3 corona: README — Ring-LWE identity; v0.1.x history inherited from luxfi/pulsar
This repository owns the former luxfi/pulsar v0.1.x Ring-LWE code line.
v0.2.0 is the first post-split Corona release. The Module-LWE sibling
library moved to luxfi/pulsar and starts at v1.0.0.

The 'Pulsar' brand name retained in the Quasar consensus protocol
refers to the Module-LWE library; this repository's brand is Corona —
the luminous ring around the central Pulsar/Quasar light.
2026-05-11 19:37:10 -07:00
Hanzo AI a2ee6f3ce1 corona: rename module path github.com/luxfi/pulsar → github.com/luxfi/corona
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
2026-05-11 14:55:26 -07:00
Hanzo AI d672f063e4 pulsar: LLM.md — corona rename note + post-E2E-PQ state
Records the Pulsar/Corona rename context: this repo (R-LWE,
production fork) becomes luxfi/corona; luxfi/pulsar-m (M-LWE, FIPS
204) becomes the canonical luxfi/pulsar. No code change here — wire
formats and consensus paths are unchanged until the cross-repo moves
land. v0.1.x tags continue to point at R-LWE code; new consumers
should pin v0.2.0+ on the renamed repo.
2026-05-11 11:47:07 -07:00
Hanzo AI ddf15a69c6 ci: bump Go toolchain 1.26.2 → 1.26.3 (fix remaining govulncheck CVE)
First post-bump CI run still failed with one stdlib vuln:

  GO-2026-4971  net.Dial / net.LookupPort NUL-byte panic on Windows
                Fixed in: net@go1.26.3

The previous bump to 1.26.2 cleared 4 of 5 reported CVEs but missed
this one (referenced via networking.DialTCP / networking.ListenTCP).
Bumping to the latest 1.26.x patch closes it. Still patch-bump only;
no minor / major change.
2026-05-10 17:45:35 -07:00
Hanzo AI 3a09609f08 ci: bump Go toolchain 1.26.1 → 1.26.2 (fix govulncheck CVEs)
govulncheck reported the following stdlib CVEs against Go 1.26.1 in the
Security Scan job:

  GO-2026-4866  crypto/x509  excludedSubtrees case-sensitivity auth bypass
  GO-2026-4870  crypto/tls   TLS 1.3 KeyUpdate DoS
  GO-2026-4946  crypto/x509  inefficient policy validation
  GO-2026-4947  crypto/x509  unexpected chain-building work

All fixed in go1.26.2. Bumped:

  go.mod                                go 1.26.1 → 1.26.2
  .github/workflows/ci.yml              GO_VERSION 1.25.7 → 1.26.2
  .github/workflows/fresh-clone-ci.yml  GO_VERSION 1.25.7 → 1.26.2

Matrix test-matrix entry also bumped 1.25.7 → 1.26.2.
2026-05-10 17:41:12 -07:00
Hanzo AI 05add99d16 style: gofmt -s across cmd/ + reshare/ + dkg2/ + keyera/ + threshold/
Whitespace-only struct-tag alignment changes. Closes the CI Lint gate
that was failing across multiple recent commits on otherwise-green
build+test runs.
2026-05-10 17:23:40 -07:00
Hanzo AI b886275c15 pulsar: plumb HashSuite through every Sign-path primitive (F22)
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.
2026-05-10 17:19:13 -07:00
Hanzo AI b01a152536 LP-107 Phase 4: pulsar consumes luxfi/math/codec
wire/wire.go — pulsar's wire-format hardening boundary. Untrusted
lattice Vector[Poly] frames now flow through luxfi/math/codec.Reader
so the bounded-decode contract is centralized: no recursion, no
hidden growth, no unbounded allocation.

Replaces the test-only validateVectorPolyFrameInline walker that
lived at threshold/fuzz_round_test.go with a production-grade
equivalent on the canonical luxfi/math/codec substrate.

Tests:
* TestValidateVectorPolyFrame_RejectsHugeLength — regression for
  lattice issue #4 (70-trillion-element attack input). Same input
  the original fuzz finding produced, now rejected with
  codec.ErrLimitExceeded via the shared math substrate.
* TestValidateVectorPolyFrame_HappyPath — 3-element accept.
* TestValidateVectorPolyFrame_AtCap — exactly MaxLatticeUintSliceLen
  accepted.
* TestValidateVectorPolyFrame_OverCap — MaxLatticeUintSliceLen+1
  rejected.

go.mod bumps luxfi/math v1.2.4 -> v1.3.0 (the LP-107 substrate
release with codec/ + params/ + backend/ + modarith/ + ntt/ + poly/
+ rns/ + sample/).

This is the first downstream consumer of the math substrate. Lens,
FHE, and lattice consumers follow.
2026-05-04 09:47:05 -07:00
Hanzo AI fcc133e37b pulsar: cross-runtime oracles + sign KAT generator (v0.1.2 follow-on)
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.
2026-05-04 03:32:05 -07:00
Hanzo AI e217ffe266 threshold: validate Vector[Poly] frame before lattigo ReadFrom
FuzzPulsarSign1Round1Data found a 9-byte input that crashes the
goroutine with `fatal error: out of memory: cannot allocate
105589698985984-byte block` in `lattice/v7/utils/structs.Vector[T].
ReadFrom`. Recovery cannot catch the fatal OOM — the only safe path
is to reject malformed frames before `make([]T, size)` runs.

This is a SECOND DoS surface in lattice/v7, distinct from the
ReadUintNSlice recursion fixed by luxfi/lattice#3 (still open):
ReadFrom calls `make([]T, size)` with `size` read from the wire
before any bound check. PR #3 fixes the inner slice readers but the
outer Vector wrapper allocation remains exploitable.

Filed upstream as luxfi/lattice#4 with reproduction. The new
validateVectorPolyFrameInline walker mirrors the existing
warp/pulsar.validateVectorPolyFrame: walks the wire frame
end-to-end, asserts every length field is <= MaxLatticeUintSliceLen
(4096), and rejects truncated / over-large frames before the
lattigo decoder runs.

Result: FuzzPulsarSign1Round1Data passes 30s with the new walker
in place (28577 execs, 0 panics). Failing input
testdata/fuzz/FuzzPulsarSign1Round1Data/a80b8d313b40fa55 is now
rejected cleanly with "vector length 70368955777453 exceeds 4096".

Refs: luxfi/lattice#2 (open), luxfi/lattice#3 (open),
      luxfi/lattice#4 (filed 2026-05-04)
2026-05-04 03:15:49 -07:00
Hanzo AI c77969ea67 pulsar: lattice threshold kernel with key-era lifecycle + Pulsar-SHA3 + Nebula binding
Forked from github.com/luxfi/corona @ d09b2c2. Pulsar inherits the
2-round signing math byte-equal but adds blockchain-grade key
lifecycle and a SHA3-based domain-separated hash profile for
permissionless validator-set rotation.

Inherits from upstream Corona (byte-equal):
  - Sign1/Sign2/Combine 2-round signing math
  - Lattice ring R_q = Z_q[X]/(X^256+1), q = 0x1000000004A01
  - Module-LWE / Module-SIS hardness
  - NTT, Discrete-Gaussian Ziggurat, MAC layer

Replaces from upstream:
  - Broken Feldman-style DKG (pseudoinverse-recoverable). Replaced
    with: (a) one-time foundation MPC ceremony / trusted-dealer
    Bootstrap; (b) Pedersen DKG over R_q (research, dkg2/) hiding
    under MLWE on B / binding under MSIS on [A | B].
  - Trusted-dealer-per-epoch lifecycle (wrong shape for permissionless
    rotation). Replaced with Verifiable Secret Resharing (VSR) every
    epoch under the persistent group public key.

Key-era lifecycle (KeyEraID / Generation / RollbackFrom):
  - KeyEraID bumps only at Reanchor (rare governance event)
  - Generation bumps every Refresh / Reshare under the same GroupKey
  - RollbackFrom records prior generation reverted from (0 = forward)
  - Activation cert (QUASAR-PULSAR-ACTIVATE-v1) gates new generations
    under the unchanged GroupKey

Pulsar-SHA3 hash profile (NIST FIPS 202 / SP 800-185):
  - Hc:        cSHAKE256("PULSAR-HC-v1", transcript) → challenge
  - Hu:        cSHAKE256("PULSAR-HU-v1", transcript) → XOF stream
  - TranscriptHash: TupleHash256("PULSAR-TRANSCRIPT-v1", parts...)
  - PRF:       KMAC256(key, msg, "PULSAR-PRF-v1")
  - MAC:       KMAC256(key, msg, "PULSAR-MAC-v1")
  - Pairwise:  KMAC256(kex, encode(...), "PULSAR-PAIRWISE-v1")
  - Default suite is Pulsar-SHA3; Pulsar-BLAKE3 retained as optional
    non-normative fast profile. HashSuiteID is bound into transcripts.
  - Implementation at pulsar/hash/ with HashSuite interface.
  - All KATs regenerated under SHA3 profile; vectors in
    luxcpp/crypto/pulsar/test/kat/.

Nebula root binding (TranscriptInputs + ActivationMessage canonical
bytes, all bound under TupleHash256):
    chain_id, network_id, group_id,
    key_era_id, old_generation, new_generation,
    old_epoch_id, new_epoch_id,
    old_set_hash, new_set_hash,
    threshold_old, threshold_new,
    group_public_key_hash,
    nebula_root,
    hash_suite_id,
    implementation_version,
    variant.

Packages:
  primitives/   Shamir over R_q, Lagrange, hash helpers
  sign/         2-round sign math (byte-equal upstream)
  threshold/    GroupKey, KeyShare, Signer types
  reshare/      VSR kernel — Refresh (HJKY97 zero-poly), Reshare
                (Desmedt-Jajodia), commit (Pedersen R_q), complaint,
                transcript, pairwise KEX, activation cert
  hash/         HashSuite interface; PulsarSHA3 (default), PulsarBLAKE3
  dkg2/         Pedersen DKG over R_q (research, reference only)
  keyera/       Lifecycle wrapper: Bootstrap → Reshare → Reanchor
  papers/       LP-073-pulsar paper (sections + bibliography)
  cmd/*_oracle/ KAT generators (Go ↔ C++ byte-equal validation)

DESIGN.md is the single source of truth:
  - The Pulsar metaphor (rotating beam over persistent body)
  - Vocabulary stack per LP-105: Nebula / Photon / Lumen / Beam /
    Pulsar / Pulse / Prism / Horizon / Quasar
  - Pulsar ≠ Lumen (PQ stream is separate, planned)
  - Pulsar / Lens / LSS three-layer architecture
  - Bootstrap Dealer vs Signature Coordinator
  - No-slashing failure ladder (timeout → retry → rollback → reanchor)
  - MVP VSR vs Robust VSR phasing
  - Borrowed-brand terms ("X-Wing" used casually) replaced with
    "hybrid KEM" / "Hybrid Lumen Handshake"; X-Wing cited only as
    the IETF combiner primitive name where exact reference matters.

Tests: full suite green
  hash 5+/5+, keyera 5/5, reshare 45+/45+, threshold, sign, dkg,
  dkg2, primitives, networking, utils, corona_oracle_v2 KAT —
  all pass.

Honest claim: the crypto primitives are not new (HJKY97,
Desmedt-Jajodia97, Wong-Wang-Wing02, Corona, Hermine, Threshold
Raccoon all exist). The novel contribution is the systems
composition: a permissionless-consensus deployment architecture that
turns static two-round PQ threshold signatures into a dynamic,
leaderless, validator-rotation-tolerant finality layer.

Companion docs: papers/lp-073-pulsar/ (academic paper); LP-073 +
LP-103 + LP-105 in github.com/luxfi/lps; threshold/protocols/lss/
lss_pulsar.go (LSS adapter wrapping this kernel).
2026-03-03 12:00:00 -08:00