Commit Graph
84 Commits
Author SHA1 Message Date
z c33ddeb37a docs(brand): add hero banner v0.10.3 2026-06-28 20:35:31 -07:00
z b4895c433e chore(brand): dynamic hero banner 2026-06-28 20:35:30 -07:00
zeekay 65dbf7891e bump: dealerless pulsar/corona/dkg/mlwe (no trusted dealer, no-reconstruct)
Move to the dealerless threshold-signature stack: corona v0.10.2 (Module-LWE
Ringtail, dealerless Pedersen-VSS) + pulsar v1.7.1 (dealerless Mithril RSS keygen
+ no-reconstruct signing, trusted dealer ripped) + dkg v0.3.5 + mlwe v0.2.1.
2026-06-28 19:39:51 -07:00
zeekay 40186f01f9 docs(LLM): record v0.10.2 — Phase-2 SP 800-185 + Lagrange routed onto luxfi/mlwe (byte-preserving) 2026-06-28 13:11:59 -07:00
zeekay c85b5cf2ba merge refactor/onto-mlwe (v0.10.2): route SP 800-185 + Lagrange onto luxfi/mlwe — byte-preserving de-dup
One-and-one-way completion: Pulsar AND Corona now both consume the single
github.com/luxfi/mlwe base (v0.2.1) for the shared Module-LWE primitives.
Corona remains Module-LWE (Ringtail/Raccoon line).

WHAT THIS MERGES (transcript + Lagrange routing ONLY — no scope creep):
  - hash/sha3.go: cSHAKE256 / KMAC256 / TupleHash256 / EncodeString now
    vend from mlwe/transcript (the single SP 800-185 surface). Corona keeps
    ONLY its domain-separation tags. hash/sp800_185.go (the local primitive
    copy) is deleted; its NIST primitive vectors now live in mlwe/transcript.
  - primitives/shamir.go: ComputeLagrangeCoefficients delegates field
    arithmetic + interpolation to mlwe/share (NewPrimeField + Lagrange@0);
    Corona keeps the adapter lifting each scalar into the R_q ring.Poly.

DELIBERATELY NOT ROUTED (kept byte-incompatible / audited):
  - Lattigo 48-bit ring stays Lattigo (re-rolling audited Lattigo forbidden).
  - The seeded Shamir deal (ShamirSecretSharing) stays Corona/Pulsar-specific
    (its sampler is byte-incompatible with mlwe.Split).

CORRECTNESS GATE — Go byte-parity (PROVEN, this is the gate):
  Every Corona KAT oracle was run on the pre-refactor baseline (main 17ac4f3,
  Corona-local impls) and on this branch (mlwe v0.2.1 routed), and every
  emitted byte is identical: 19/19 KAT files byte-identical old==new
  (recursive diff clean + sha256 manifest match), covering the exact files
  this change touches (corona_oracle_v2 transcript_hash, shamir_share,
  sign_verify_e2e) plus the full oracle surface (reshare, activation, dkg,
  sign, shamir_general, shamir_tk, transcripts_byte, m4_* samplers).
  e2e threshold variants (3,2),(5,3),(7,4),(10,7) pass; go build ./... and
  go test ./... green across all packages.

  mlwe v0.2.0 -> v0.2.1 is byte-safe by source inspection: the only delta
  between those tags is added *_bench_test.go files (test-only, never
  compiled into the consuming binary); zero production bytes changed in
  mlwe/transcript or mlwe/share. The oracle parity above confirms this
  empirically.

CI-GATE NOTE — C++ cross-runtime byte gate is a POST-MERGE CONFIRMATION,
not a merge blocker:
  cmd/cross_runtime_verify (requires luxcpp cmake/conan/blst) runs in CI as
  a post-merge confirmation. The Go byte-parity above is the correctness
  gate and is sufficient to merge, by this transitivity argument:
    - Old Go bytes == New Go bytes (proven: 19/19 byte-identical).
    - The C++ runtime and the Go runtime share NO build inputs — the C++
      port does not depend on go.mod / luxfi/mlwe at all.
    - Therefore this dependency change CANNOT shift any C++ byte, and the
      C++<->Go KAT relationship is INVARIANT under this change: whatever
      C++==Go (or C++!=Go) held before, holds identically after.
  So the post-merge C++ run can only re-confirm the pre-existing C++<->Go
  state; it cannot regress as a result of this Go-only de-dup.

PRE-EXISTING DRIFT (documented, NOT introduced here, NOT a crypto-byte diff):
  The sign_verify_e2e KAT's prose "description" field references
  threshold.GenerateKeysTrustedDealer (a ~13-byte wording difference vs a
  plain "GenerateKeys" phrasing) — a Go<->C++ description-string mismatch in
  the cross-runtime comparison, orthogonal to cryptographic bytes. It
  pre-dates this branch; sign_verify_e2e.json is sha256-identical old==new
  here, so this change leaves it exactly as it was.

Tag: v0.10.2
v0.10.2
2026-06-28 13:09:07 -07:00
zeekay 9e6a6cab8c refactor(hash,primitives): route SP 800-185 + Lagrange onto luxfi/mlwe v0.2.1
Byte-preserving de-dup: Corona's SP 800-185 transcript surface
(hash/sha3.go; deletes the local hash/sp800_185.go) and
ComputeLagrangeCoefficients (primitives/shamir.go) now consume the
shared github.com/luxfi/mlwe base — the single Module-LWE primitive
surface for the Lux stack (Corona + Pulsar).

Routed onto mlwe:
  - hash/sha3.go: cSHAKE256 / KMAC256 / TupleHash256 / EncodeString
    -> github.com/luxfi/mlwe/transcript. Corona retains ONLY its
    domain-separation tags; the byte encodings live in mlwe/transcript.
  - primitives/shamir.go: ComputeLagrangeCoefficients delegates the
    field arithmetic + interpolation to github.com/luxfi/mlwe/share
    (NewPrimeField + Lagrange at point 0); Corona keeps the adapter
    that lifts each scalar into the R_q constant-term ring.Poly.

Deliberately NOT routed (byte-incompatible / audited):
  - Lattigo 48-bit ring stays Lattigo (re-rolling audited Lattigo forbidden).
  - The seeded Shamir deal (ShamirSecretSharing) stays Corona-specific
    (its sampler is byte-incompatible with mlwe.Split).

Corona remains Module-LWE (Ringtail/Raccoon line).

Byte-parity gate: every Corona KAT oracle emits byte-identical output
old (Corona-local impls) == new (mlwe-routed). Go byte-parity is the
correctness gate; the C++ cross-runtime byte gate is a post-merge CI
confirmation (see merge commit CI-GATE note).
2026-06-28 13:02:56 -07:00
zeekay 17ac4f350e merge Corona no-reconstruct-signing audit (v0.10.0): STRICT trustless lane certified — sign path proven no-reconstruct v0.10.1 2026-06-28 01:21:23 -07:00
zeekay 1367e9bb97 docs: certify Corona a STRICT trustless lane (no-reconstruct signing, gate 5)
- LLM.md: Latest Tag -> v0.10.0; record the no-reconstruct signing gate +
  v0.9.0 DKG cutover in the recent-commits table.
- PROOF-CLAIMS.md: catalogue the new code-level conformance gate alongside
  the Lean-4 secret_aggregate_no_reconstruct proof, framed honestly as a
  TEST gate (not a proof-assistant artifact).

Audit verdict (branch audit/no-reconstruct-signing): Corona threshold signing
is no-reconstruct — each party emits z_i = R_i*u + maskPrime_i + c*lambda_i*s_i
- mask_i from its OWN share; SignFinalize sums the masked partials z_sum = Sum
z_j = R*u + c*s; the secret s = Sum lambda_j*s_j appears only as the coefficient
of the public challenge c inside the masked aggregate and is never materialised.
Dealerless keygen (keyera.Bootstrap) + no-reconstruct signing => strict
trustless lane for STRICT_DUAL_PQ / POLARIS_MAX.
v0.10.0
2026-06-28 00:57:18 -07:00
zeekay 500d319328 test(threshold): pin Corona no-reconstruct signing (gate 5, trustless-by-default)
Structural + behavioural proof that the Corona threshold SIGNING path never
forms the full secret s, even transiently at sign time:

  GATE A (structural, go/ast): every signing/verify function body is scanned;
    none calls an across-party reconstruction primitive (reconstruct /
    interpolate / combineShares / recover* / ShamirSecretSharing /
    lagrangeAtZero / selectQuorum) and none invokes the trusted-dealer keygen
    (Gen / GenerateKeysTrustedDealer). Per-party Lagrange (party.Lambda on the
    party's OWN share) is the legitimate no-reconstruct mechanism and is NOT
    forbidden. Negative-control verified: injecting a reconstruct call into
    SignFinalize trips GATE A.

  GATE B (behavioural, reflect): Round1Data/Round2Data/Signature carry no
    share/sk/seed/lambda; Finalize ingests only map[int]*Round2Data (masked z
    partials) — the aggregator never holds a second party's secret.

  GATE C (independent verifier): a real (3,5) no-reconstruct ceremony, each
    Signer from exactly ONE share, verifies under the bare Corona verifier
    (public data only) and the stateless wire verifier; tamper rejected.

Verdict: Corona is a STRICT trustless lane — dealerless keygen (keyera.Bootstrap)
+ no-reconstruct signing. Sub-quorum-cannot-forge is pinned separately by
TestThresholdSubQuorumCannotForge.
2026-06-28 00:53:54 -07:00
zeekay 7996ad7a75 merge Phase-3a: corona onto luxfi/dkg v0.2.0 — dealerless no-reconstruct DKG
keyera.Bootstrap drives luxfi/dkg vss share-dealing + blame; keeps corona's own
Path-(a) noise-flooded Round_Xi finalize (the vss Pedersen T is discarded — Ring-LWE
tolerates large blinding). Deployed group key byte-identical (golden KAT). dkg2 deleted.
2026-06-27 22:29:52 -07:00
zeekay 2cecc08c63 refactor(corona): delete the dkg2 package — superseded by luxfi/dkg vss
The Pedersen-VSS DKG share-dealing now runs entirely on github.com/luxfi/dkg
(proven byte-identical at cutover); corona's own copy is dead. Remove it and its
now-orphaned tooling, keeping only corona-specific code (Ringtail signing, β
rounding, Path (a) finalize — all in sign/, utils/, keyera/, untouched).

Deleted:
  - dkg2/ (the whole package: Round1/Round2/commits/complaint/GPU dispatch).
  - cmd/dkg2_oracle/ (the dkg2 KAT generator; the DKG KAT now lives in
    luxfi/dkg's own ring/vss vectors).
  - keyera/cutover_gate_test.go (the transitional dkg2-vs-vss equality gate; its
    job is done — permanent byte-stability is pinned by the golden KAT, and the
    PIN-4 convention assertion is preserved dkg2-free in pin4_convention_test.go).

Updated:
  - cmd/cross_runtime_oracle drops the dkg2 manifest leg (the luxcpp C++ dkg2
    cross-runtime gate migrates to luxfi/dkg separately — flagged, not silently
    broken).
  - keyera/reanchor doc comments + threshold bench comment point at luxfi/dkg.

go build ./... + go test ./... -count=1 green (13 ok / 0 fail), go vet + gofmt
clean. The golden byte-stability KAT + Bootstrap→sign→verify + dishonest-dealer
abort all still pass on the vss path.
v0.9.0
2026-06-27 22:03:55 -07:00
zeekay 259a1a2cae feat(keyera): drive the dealerless DKG through luxfi/dkg vss
Rewire BootstrapPedersen's no-reconstruct share-dealing onto the shared
github.com/luxfi/dkg library (vss + blame + ring.Ringtail()), dropping the
in-keyera dependence on corona/dkg2. corona keeps ONLY its scheme-specific
finalize: Path (a) noise flooding + Round_Xi, which turns the per-party secret
shares s_j into the LWE-shaped Ringtail public key bTilde = Round_Xi(A·s+e'').
The vss Pedersen aggregate T = A·s1+B·u is NOT corona's group key (its B·u term
is not a small LWE error), so vss is used purely for the no-reconstruct share
distribution + identifiable blame.

Mechanism:
  - BootstrapPedersen draws per-party sampling seeds from the ceremony entropy
    (same sequencing as before) and threads each into vss.Party.Round1, so the
    χ draws — hence the Pedersen commits and the secret shares — are byte-
    identical to the prior dkg2 path (cutover gates B/C/E).
  - DealPedersen runs Round 1 + opens every sealed envelope; FinishBootstrapPedersen
    runs Round 3 (Pedersen verify + aggregate) then Path (a) + KeyShare assembly.
    The two-phase split is the test seam for identifiable abort (tamper an opened
    share, observe ErrBootstrapPedersenAbort + re-checkable blame).
  - Commit digests are recomputed under the corona HashSuite over the lattigo
    wire bytes of vss's commits — byte-identical to dkg2's CommitDigest — so the
    noise seed and transcript hash are preserved.
  - AbortEvidence now carries luxfi/dkg blame.Complaint (accused-by-NodeID,
    third-party re-checkable via vss.RecheckBadDelivery); the in-process channel
    identities are derived deterministically and affect only the (immediately-
    opened) envelope ciphertext, never any byte-stable output.

Proof: the frozen golden KAT (bTilde / transcript / shares digests for 5/3 and
3/2) PASSES against the vss path — the group key, transcript, and shares are
preserved byte-for-byte. Determinism, Bootstrap→sign→verify, dishonest-dealer
abort (+ RecheckBadDelivery), reanchor round-trip/abort, and the no-master-secret
structural checks all green. Public API (Bootstrap/KeyEra/EpochShareState/
BootstrapTranscript/GroupKey/KeyShare) unchanged.
2026-06-27 21:55:51 -07:00
zeekay aaa666de29 test(keyera): cutover gate E — vss Round3 aggregateShare+verifyPedersen byte-identical to dkg2 Round2Identify
Completes the share-dealing byte-equality proof (gates A-E): vss's real
Round3 (verifyPedersen + aggregateShare) accepts dkg2's contributions
cross-implementation and produces s_j = Sigma_i f_i(j) byte-identical to
dkg2.Round2Identify. With A-E green the BootstrapPedersen swap onto
vss (Round1 -> OpenDealerShare -> Round3.ShareResult.Share) preserves the
group key + per-party shares byte-for-byte; corona's Path-(a) noise-flood
finalize is unchanged. PIN 4 resolved: no R^{-1} scaling adapter needed.
2026-06-27 21:49:21 -07:00
zeekay 1c6cf6166f test(keyera): freeze BootstrapPedersen golden byte-stability KAT
Capture the group key (bTilde), transcript hash, and per-validator shares from
the dkg2-backed BootstrapPedersen at the cutover point, as frozen SHA-256
digests for two committee shapes (5/3, 3/2). This is the permanent byte-for-byte
target the luxfi/dkg rewire must reproduce — proving the group-key convention,
transcript, and shares are PRESERVED (not re-baselined) when the no-reconstruct
share-dealing moves to vss while corona keeps its own Path-(a) finalize.
2026-06-27 21:44:03 -07:00
zeekay 374e600952 test(keyera): luxfi/dkg v0.2.0 cutover gate — Ringtail byte-identical to dkg2
Phase 3a step 1: require github.com/luxfi/dkg v0.2.0 and prove, before any
rewire, that the shared library's ring.Ringtail() binding reproduces
corona/dkg2's KAT-pinned arithmetic byte-for-byte.

Gate (cutover_gate_test.go), all green:
  (A) ring.Ringtail() A,B == dkg2.DeriveA/DeriveB over all 8x7 slots.
  (B) vss's REAL Party.Round1 commits == dkg2.Round1WithSeed commits for the
      same 32-byte sampling seed (exercises vss computeCommits, not a re-impl).
  (C) vss Horner shares (ring.ScalarMulVec/VecAdd) == dkg2 big.Int Horner shares
      for every recipient — the Barrett-vs-bigint paths agree on the canonical
      representative in [0,q).
  (D) PIN 4 pinned to ground truth: dkg2.Round2 b_ped (IMForm+INTT) = vss group
      commit T (INTT-only) scaled by R^{-1}; the two differ by EXACTLY the
      Montgomery factor R (MForm(b_ped)==T). corona's PRODUCTION key is NEITHER:
      keyera Path-(a) noise flooding multiplies NTT-Mont operands so the R is
      correctly cancelled, yielding the TRUE A·s+e'' — convention-aligned with
      vss's TRUE T. dkg2's R^{-1}-scaled b_ped is an internal Round2 value the
      production path discards, so the rewire (keep corona's finalize, use vss
      for share-dealing) preserves the group key with NO convention change.
2026-06-27 21:39:39 -07:00
zeekay 321f5968b8 docs: state the dual-leg diversity claim accurately (not an over-correction)
The prior pass swung too far: it answered "does running both give diversity?"
with a flat "No, both are Module-LWE." That under-credits the real security.

Accurate, layered claim now installed in design-decisions / README / SUBMISSION /
nist-mptc-category:
- Pulsar and Corona are distinct SCHEMES at different PARAMETER regimes
  (Pulsar = FIPS-204 ML-DSA deterministic FS-with-aborts, q=8380417; Corona =
  Ringtail/Raccoon masked threshold, q=0x1000000004A01, params tuned for
  threshold). In AND-mode an adversary must forge BOTH; a cryptanalytic,
  parameter-specific, or implementation flaw in one does not transfer — the pair
  is strictly stronger than either leg alone ("both have to be cracked").
- What it is NOT: hardness-ASSUMPTION diversity. Both rest on Module-LWE/SIS, so a
  fundamental Module-LWE break threatens both lattice legs; assumption-disjoint
  diversity is the hash-based Magnetar (SLH-DSA) leg.

Docs-only; go build green; no shims.
v0.8.2
2026-06-27 17:02:21 -07:00
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).
v0.8.1
2026-06-27 16:12:24 -07:00
zeekay 26eb3f35b7 corona: docs to v0.8.0 — dealerless Pedersen DKG is the production keygen default
dkg2/BootstrapPedersen (dealerless Pedersen DKG over R_q = Z_q[X]/(X^256+1)) is the production keygen default since v0.7.5; signing never reconstructs the master secret (SignFinalize sums partials). Corona carries the permissionless / no-trusted-dealer guarantee in the Quasar AND-mode dual-PQ cert that Pulsar's byte-FIPS-204 keygen cannot (a dealerless sum of FIPS secrets breaks ML-DSA's S_eta bound). README/LLM/BLOCKERS refreshed; stale v0.7.4 / WIP -> v0.8.0 / Production. Not FIPS byte-equal; no fabricated cert-size figure.
2026-06-27 14:15:00 -07:00
zeekay f08e2b57aa threshold: make trusted-dealer keygen explicit, drop dead ReconstructSecret, pin sub-quorum soundness
Part of the Lux threshold-crypto security rip (killing trusted-dealer /
full-key-reconstruction footguns).

- Rename threshold.GenerateKeys -> threshold.GenerateKeysTrustedDealer.
  The function samples the full secret and sets sign.K / sign.Threshold in
  one process: it IS the trusted dealer. The new name mirrors
  keyera.BootstrapTrustedDealer so the trust model is explicit and
  greppable. Doc comment now states it is for test/KAT/CT/CLI/oracle use
  only, and that production chain keygen uses keyera.Bootstrap (dealerless
  Pedersen DKG). Stays exported; every caller updated (cli, ct/dudect,
  same-package tests) plus stale comment refs in cmd, keyera, wire,
  reshare.

- Delete utils.ReconstructSecret. It Lagrange-interpolates the full secret
  from shares and had zero callers anywhere in the repo: a
  reconstruction-shaped footgun left dead. CompareSecrets and the section
  retained.

- Include threshold/minority_soundness_test.go: an adversarial negative
  pinning that a strict sub-quorum cannot assemble a signature that
  verifies under the group key (uncancelled PRF mask fails the L2-norm
  gate). A sub-quorum forgery would be a catastrophic finality break.
v0.8.0
2026-06-26 21:13:45 -07:00
Antje Worring 7c102d2d14 fix(threshold): reject duplicate PartyID in Round2/Finalize signing combine (kernel-boundary uniq guard; was caller-enforced). + TestFinalize/Round2_DuplicatePartyID_Rejected v0.7.9 2026-06-21 20:40:00 -07:00
Antje Worring 6b4d5d529b docs: correct stale 'no EC toolchain' claims; note combine bridge discharged to lemma + jasminc available v0.7.8 2026-06-21 19:14:18 -07:00
Antje Worring baf2ba8c40 fix(ec): machine-check all 14 theories (R_q_xi order, w_low_t, wrapper intros, RLWE_Functional comment); discharge combine bridge C11 to a lemma via no_leak_z_aggregate keystone, residual shrunk to public w-agreement v0.7.7 2026-06-21 18:10:48 -07:00
Antje Worring ba9fe18360 proofs: de-misdirect the reconstruct-then-sign EC cone with a no-leak model
The EC byte-equality (corona_n1_byte_equality) proved the threshold combine
bit-equals CombineAbs, whose sign_abs_op_lifted_eq_rlwe bridge pins it to
rlwe_sign_op on the LAGRANGE-RECONSTRUCTED master secret -- exactly the path
the Boschini/Raccoon production combine must never take (CORONA-EC-RECON-MODEL).
This pass re-scopes that cone as IDEALISED CORRECTNESS and adds the HONEST
production model whose residual is a STANDARD Module-LWE/MSIS reduction.

New proofs/easycrypt/Corona_N1_NoLeak.ec (written; machine-recheck pending
EasyCrypt -- no `ec` on host, scripts/checks/ec-compile.sh is the CI gate):
  - mask_telescope_zero [B, Lean-backed]: Sum_i (maskPrime_i - mask_i) = 0 --
    the pairwise-PRF masks (z_i = R_i*u + maskPrime_i + c*lambda_i*s_i - mask_i)
    are the same double sum reindexed (Fubini), so they cancel on aggregation.
    Machine-checked in Lean as pairwise_mask_telescopes.
  - no_leak_z_aggregate: the surviving aggregate is R*u + c*s by Lagrange-at-0
    WITHOUT forming the master secret and with no per-party c*s_i ever exposed.
  - no_leak_reduction [C-standard, OPEN]: under Module-LWE + Module-SIS the
    public transcript leaks nothing about s beyond one Boschini signature. The
    honest replacement for sign_abs_op_lifted_eq_rlwe -- a reduction to the SAME
    substrate AXIOM-INVENTORY.md §1 already lists, secret NEVER reconstructed.

The CORRECTNESS CORE is machine-checked in Lean 4 + Mathlib on this host
(luxfi/proofs: Crypto.Corona.NoLeakAggregate / Threshold_Lagrange; lake build
green, #print axioms shows no sorryAx).

Disclosure updated to match reality: AXIOM-INVENTORY (new Bucket C-standard +
"A is machine-checked in Lean"), PROOF-CLAIMS (two models, §0 Disclosure 1),
BLOCKERS (CORONA-EC-RECON-MODEL re-scoped, first criterion now [x]), budget
AXIOM 56->58. Framework gate PASS (all 5 checks); go build + full test suite green.
2026-06-21 15:26:31 -07:00
Antje Worring 5906b09508 Revert "reshare: gate master-secret reconstruction behind corona_research [RED-2]"
This reverts commit 71110cbeeb.
2026-06-21 15:10:41 -07:00
Antje Worring 71110cbeeb reshare: gate master-secret reconstruction behind corona_research [RED-2]
reshare.Verify Lagrange-interpolates the input shares at X=0 and RETURNS the
reconstructed master secret to its caller (its own doc: "MUST NOT be used in
production"). Its only non-test caller is cmd/reshare_oracle (a KAT generator).
Left in the production package with no boundary, it is a latent master-key
footgun.

Fix (surgical split, not whole-file tag): reshare.go also defines the
production Reshare/Refresh/Share that keyera imports, so the file cannot be
tagged out. Move ONLY Verify into verify_reconstruct.go behind
//go:build corona_research; its shared interpolation helpers (selectQuorum,
lagrangeAtZero, sortedKeys) stay in reshare.go because production uses them.
Gate the sole non-test caller cmd/reshare_oracle/main.go with the same tag.

Tests: the reshare/refresh tests that reconstruct the secret (via Verify) move
into reshare_research_test.go / refresh_research_test.go / the tagged
integration_test.go and run under -tags corona_research. The production-
behaviour tests that do NOT reconstruct (determinism, arg validation, t=1
identity, fuzz, transcript) stay in the default build — no coverage lost.
Generic test helpers shared across both builds (cloneVector, runRoundsAndVerify)
move to untagged clone_test.go / signrounds_test.go.

Verification:
- default `go build ./...` exits 0; reshare.Verify ABSENT from the default
  build (proven: a Verify-calling test does not compile into the default run).
- default `go test ./...`: 0 failures; production tests run.
- `go test -tags corona_research ./...`: green; reconstruction tests + oracle
  compile and run (TestReshareSecretInvariant etc. pass).
- gofmt + vet clean in both build modes.
- security/framework/check.sh corona: PASS (no CLOSED-but-reconstructs blocker).
2026-06-21 15:02:59 -07:00
Antje Worring 83031bf331 high-assurance: repoint gate references to luxfi/security/framework (canonical home) 2026-06-21 14:22:36 -07:00
Antje Worring 988e4cc15a proofs: honest bucketed axiom inventory + reconstruct-then-sign disclosure
Reclassify (not reduce) the EasyCrypt axiom surface and correct the prior
inventory's understatement. NO axioms discharged this pass (honest): no
easycrypt toolchain on host, and every in-file-derivable axiom is already a
proved lemma; residual A/B axioms are over abstract ops/constants
(op group_pk_width : int., op sig_len : int.) and the C axioms are open.

- AXIOM-INVENTORY.md: replace the §2 table that mislabelled the wrapper
  bridges and section-local module contracts as "Discharged in the
  Wrapper". They are now correctly bucket C / OPEN: combine_body_spec hides
  the Boschini combine steps 2-6, and combine_abs_op_lifted_bridge /
  sign_abs_op_lifted_eq_rlwe pin the lifted op to rlwe_sign_op on the
  Lagrange-RECONSTRUCTED master secret (reconstruct-then-sign). Complete
  bucketed census of all 56 axioms -- A (18, 5 Lean-bridged), B (27), C
  (11) -- one row per axiom with name, file:line, justification. CT
  contracts (sign_round{1,2}_constant_time) classified C/fail-closed.
- PROOF-CLAIMS.md: add assurance vocabulary + two load-bearing disclosures
  -- (1) the EC byte-equality MODELS reconstruct-then-sign; (2) Corona has
  NO independent interop verifier (R-LWE has no NIST target), so its
  byte-equality is asserted + same-construction Go<->C++ KAT, never
  "proven/verified". Corrects the §4 claim that Pulsar is machine-checked
  "at every step" (it too rests on the same reconstruct-then-sign cone).
- BLOCKERS.md (new): CORONA-EC-RECON-MODEL, CORONA-CT-PENDING,
  CORONA-NO-INDEP-VERIFIER -- all OPEN, all cross-referenced to the shared
  external-review gate.
- .assurance/reviewed-axioms.txt: list every load-bearing / security-cone
  axiom (A: 5 Lean-bridged; C: combine_body_axiom, S_functional_spec,
  combine_body_spec, combine_abs_op_lifted_bridge, sign_abs_op_lifted_eq_rlwe)
  with bucket + justification.
- .assurance/budget.txt: correct prose (0 real admit. tactics; AXIOM=56 exact).

Framework gate (circular-proof + axiom-budget + the other three) PASS with
full disclosure. go test ./... green (no Go touched).
2026-06-21 14:20:05 -07:00
Antje Worring 9284af66c6 high-assurance: declare unproven-assertion budget + reviewed axioms
Enforced by ~/work/lux/proofs/framework/check.sh. Caps the current trust
surface so it cannot silently grow; the goal is to drive it down.
2026-06-21 13:37:32 -07:00
Antje Worring dc15c54a47 harden: hedged 256-bit nonce key, DRY CT comparator, honest CT/proof docs
Closes the CRIT-1 residual (D1-2) sid-entropy gap and the CT/doc hygiene
gaps to bring Corona to the no-leak/no-gap bar. EasyCrypt proofs untouched.

PRIORITY 1 — anti-nonce-reuse / no-leak durability:
- The Round-1 nonce-PRF key no longer keys on a bare 64-bit sid. It now
  derives from a 256-bit domain-separated SessionID (primitives.DeriveSessionID:
  TranscriptHash("corona.sign.session-id.v1" || be64(sid) || T)) AND a fresh
  per-signature 256-bit hedge salt drawn inside the kernel from party.Rand
  (default crypto/rand). PRNGKeyForRound = PRF(skShare, "CoronaNonceV3" ||
  sessionID || salt). Hedging restores threshold-Raccoon's fresh-per-signature
  nonce posture: reuse durability no longer rests on the external consensus
  layer never reissuing an sid — even an sid collision yields distinct R with
  prob 2^-256. A deterministic 256-bit SessionID alone is necessary but NOT
  sufficient (it repeats when sid repeats); the salt is what closes the leak.
- SignRound1 is fail-closed: rejects an all-zero derived SessionID or all-zero
  salt with ErrDegenerateSession, and surfaces a short-read error. The
  consensus slot-uniqueness invariant is documented as a HARD precondition at
  SignRound1 and Signer.Round1 (no longer a buried comment).
- KAT/oracle determinism preserved via one seam: sign.DeterministicNonceSource
  (KeyedPRNG over seed || "corona.sign.nonce-salt.v1" || partyIndex), set on
  Party.Rand / Signer.SetNonceRand only by reproducibility harnesses.
- SignRound1 / Signer.Round1 now return an error; all call sites updated.
- KAT REGEN: only sign_verify_e2e.json changes (nonce-key bytes moved);
  transcript_hash.json / MAC / legacy PRNGKey vectors are byte-stable, proving
  the consensus-agreed transcript path was left untouched. Regenerated via
  `bash scripts/regen-kats.sh`; `--verify` confirms byte-determinism (10 files).
- Regression: sign/nonce_reuse_test.go proves same-(skShare,sid) yields distinct
  D (fresh R), pinned-nonce reproduces byte-identically, and the degenerate-
  session guard fires. TestE2EKATReplayDeterminism rewritten to assert both the
  hedged-differs and pinned-reproduces properties (was a defanged no-op).

PRIORITY 2 — constant-time hygiene:
- reshare/commit.go already used a constant-time comparator; the real gap was
  the verbatim duplication of constTimePolyEqual+uint64SliceToBytes across dkg2
  and reshare. Consolidated to one canonical utils.ConstantTimePolyEqual; both
  delegate (no dkg2<->reshare dependency). Orphaned imports removed.
- FullRankCheck and the reshare commit path are now covered in the CT review
  with their public-operand justification.

PRIORITY 3 — doc accuracy:
- CONSTANT-TIME-REVIEW.md rewritten Corona-specific and file:line-accurate:
  drops the stale Pulsar/lens/warp/secp256k1 content; audits the real call
  sites (hedged nonce key, masking PRF, lattigo samplers as the residual TCB
  axiom, utils.ConstantTimePolyEqual, CheckL2Norm/Verify/FullRankCheck big.Int
  variable-time on PUBLIC operands, activation/commit-digest array equality,
  keyera/reshare zeroization).
- PROOF-CLAIMS.md §1: threshold.Combine / sign.LocalSign (nonexistent) -> the
  real sign.Party.SignFinalize exposed as threshold.Signer.Finalize.
- threshold/threshold.go package doc: Ring-LWE -> Module-LWE.
2026-06-21 08:21:58 -07:00
zeekay 4d9334ee94 corona→corona: academic Corona now only in lp-220-p3q-corona 2026-06-11 10:27:40 -07:00
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
Lux PatentsandHanzo AI 7ec104b20e remove detailed patent-claims docs (relocated to lux-private/patents)
Detailed invention disclosures are sensitive pre-filing material. Moved to
lux-private/patents to preserve international filing rights (EU/JP/KR/CN
absolute-novelty rule). Cross-ref: github.com/lux-private/patents/bundles/
2026-05-19 11:29:59 -07:00