19 Commits
Author SHA1 Message Date
zeekayandHanzo Dev 9df8cbe39f Build on Go 1.27
Bumped the go directive to 1.27.1. go build and go vet are clean on the
1.27.1 toolchain. pkg/pulsar exceeds the 5m test timeout identically
before and after the bump, inside the luxfi/dkg MPC bit-check.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-17 13:06:45 -07:00
zeekayandHanzo Dev 411aaa98ef go 1.26.8
One toolchain across the estate. The tree carried 1.26.0, .1, .3, .4 and .5
at once, so which compiler built a binary depended on which repo it came
from.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 23:58:44 -07:00
zeekay 6ed7637d52 Pin past the versions the proxy can no longer serve
The bulk retag moved published tags. go.sum and sum.golang.org hold the
original bytes, proxy.golang.org answers not-found, and the direct fetch
disagrees, so builds stopped at a checksum before reaching a compiler.
Pin forward to versions the proxy still serves.
2026-09-01 12:28:38 -07:00
zeekayandHanzo Dev 1c896ab5fe deps: drop go.sum lines that disagree with the checksum log
These hashes were recorded from direct VCS fetches made while GOPRIVATE covered
github.com/luxfi/*, which switches off the module proxy and checksum
verification together. Tags moved afterwards, so what is written down here no
longer matches what sum.golang.org holds and the build refuses to verify.

proxy.golang.org still serves the originally-published bytes and those verify
against the log, so dropping only the disagreeing lines and re-tidying restores
a verified module graph with no version change. Lines that agree are untouched;
this is not a regenerated go.sum.

The failure followed the machine rather than the repository — the same commit
built wherever the module cache was clean. Any machine or CI runner that
fetched luxfi modules under the old GOPRIVATE holds the same poisoned entries.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 09:39:30 -07:00
zeekay 9bfb37024f chore(deps): bump geth v1.20.1 + luxfi deps — stack unification 2026-07-26 02:48:15 -07:00
zeekayandHanzo Dev fd0b427d46 refactor(layout): ref/go/pkg -> pkg, ref/go/cmd -> cmd (canonical Go layout); home pulsard daemon at pkg/pulsard
Moves the Go reference implementation to the idiomatic repo-root pkg/ (library)
+ cmd/ (genkat tool) layout, dropping the ref/go/ nesting. Imports become
github.com/luxfi/pulsar/pkg/pulsar. The pulsar DAEMON (formerly the unhomed
standalone github.com/luxfi/pulsard module) now lives canonically at
github.com/luxfi/pulsar/pkg/pulsard. No replace directives.

BREAKING: consumers must update github.com/luxfi/pulsar/ref/go/pkg/... ->
github.com/luxfi/pulsar/pkg/... and bump to v1.9.0.

Co-authored-by: Hanzo Dev <[email protected]>
2026-06-30 15:59:28 -07:00
zeekay a554370b38 pulsar: route transcript onto luxfi/mlwe/transcript (Phase 1, byte-preserving)
The SP 800-185 primitives (cSHAKE256/KMAC256 + LeftEncode/RightEncode/
EncodeString/BytePad) now live solely in github.com/luxfi/mlwe/transcript,
the single hash surface shared with Corona. Pulsar keeps only what is
protocol-specific:
  - the customisation tags and N="Pulsar" function name,
  - cshake256/kmac256 Pulsar-named entries (bodies delegate to mlwe),
  - transcriptHash/transcriptHash32 (Pulsar's length-prefixed digest,
    NOT SP 800-185 TupleHash256 — re-expressed over the shared encoders).
Deleted the duplicate encoder/primitive bodies; routed the six direct
encoder callers (abort, threshold, protocol_auth, dkg_wellformed_proof,
nonce_transcript_proof, partial_proof) to transcript.LeftEncode/EncodeString.

Byte-identity gate: x/crypto resolves to v0.52.0 (== baseline, no skew);
golden vectors unchanged; KAT replays pass byte-identical (9 keygen, 9 sign,
6 verify, 4 threshold-sign, 3 DKG); full suite green.

Matches the Corona onto-mlwe precedent (keep protocol hash methods, route
bodies; generic encoders called directly). Mirrors corona refactor/onto-mlwe.
2026-06-28 01:21:34 -07:00
zeekay eebeab3ec7 pulsar: consume dkg v0.3.4 (clean norm-only bound) + fix bad-committee test ((2,7) is norm-viable → use (12,16) norm-blown)
Full suite green. Dealerless RSS signs under stock circl at n=8,t=8 + n=16,t=16 (T==N,
N>6, owner n-of-n families); fault-tolerant n=8,t=7 awaits the general Algorithm-6
partition (Sign fails-closed 'no balanced partition' until then).
2026-06-28 00:23:58 -07:00
zeekay 64594c2bcc pulsar: consume dkg v0.3.2 (per-(N,T) bound) + prove dealerless RSS signs under stock circl at n=8,t=8 + n=16,t=16 (T==N, N>6)
The per-(N,T) norm bound admits the owner's high-t families. T==N committees (n=8,t=8;
n=16,t=16) sign under stock circl now (algorithmic base-case partition). T<N at N>6
(n=8,t=7 default) needs the general Algorithm-6 balanced partition (canonicalSharing
is table-limited to N≤6) — tracked as the next gap.
2026-06-28 00:18:17 -07:00
zeekay 404102c357 pulsar: consume luxfi/dkg v0.3.0 (Mithril RSS) from the published tag
Drops the local replace directive; requires github.com/luxfi/dkg v0.3.0 which
ships the rss/ dealerless RSS DKG combinatorics the FIPS leg builds on.
2026-06-27 23:06:14 -07:00
zeekay 492c42e98b pulsar: dealerless RSS (Mithril) FIPS-204 key — beats the pick-2 wall
The FIPS signing key now comes from dealerless Replicated Secret Sharing
(Mithril, ePrint 2026/013) instead of trusted-dealer DealAlgShares. Each
M-subset's short χ_η secret is sampled by its leader; the key is the SUM of
C(N,M) short shares so ‖s2‖∞ ≤ C(N,M)·η is genuinely small (vs ‖B·u‖∞≈q/2 for
the vss key). Combinatorics from luxfi/dkg/rss; FIPS-204 arithmetic is pulsar's
own circl-identical lattice code.

PROVEN (TestMithrilRSSStockCirclVerify): a NO-DEALER RSS key signs via the BCC
signer and verifies BYTE-FOR-BYTE under unmodified cloudflare/circl
mldsa65.Verify — committees (2,2)(2,3)(3,3)(2,4)(4,4) in 9-24 attempts; tamper
and wrong-message rejected (non-vacuous). Dealerless structural proof (no party
holds all subsets, no T-1 covers all) + any-quorum-same-key for all (T,N).
go.mod replace → local dkg/rss pending v0.3.0 tag.
2026-06-27 23:01:10 -07:00
zeekay 8e03308f64 pulsar: add luxfi/dkg v0.2.0 dep (Phase 3b start) 2026-06-27 21:39:32 -07:00
zeekay 5911dc0d32 go: 1.26.3 → 1.26.4 (security: crypto/x509, mime, net/textproto) 2026-06-06 22:09:52 -07:00
zeekay ee239d1e10 deps: bump accel v1.0.7 → v1.2.0 (MLDSAVerifyBatch + LatticeNTTMLDSABatch) 2026-06-05 17:42:05 -07:00
zeekay 7e302120fb pulsar v1.2-dev: Round-2 batched NTT via accel (closes PULSAR-V12-GPU-NTT-WIRE)
Wires Pulsar's v0.3 algebraic-threshold Round-2 forward NTTs through
luxfi/accel's LatticeNTTMLDSABatch (commit 6ec46c4 — the real GPU NTT
substrate, no longer the ErrNotSupported stub).

Surface:
  batchNTT(polys []poly) [][]int32  in mldsa_lattice.go

  Dispatches to accel.LatticeNTTMLDSABatch when
    accel.Available() AND len(polys) >= accel.MLDSABatchThreshold (8).
  Otherwise runs pulsar's per-poly circl-style (*poly).ntt() — byte-
  identical to the pre-batchNTT reference. Any accel error falls
  through to the pure-Go path.

Round-2 call sites converted (4 logical batches, 22 forward NTTs per
party-attempt total):

  yHat        threshold_v03.go ~L680   (L polys: 4/5/7 for P44/P65/P87)
  s1Hat       threshold_v03.go ~L893   (L polys, replaces L per-iter ntt)
  cs2-input   threshold_v03.go ~L917   (K polys: 4/6/8)
  ct0-input   threshold_v03.go ~L939   (K polys)

The accel substrate engages on ModeP87 (K=8) for the cs2-input and
ct0-input batches; ModeP44 and ModeP65 batches are below threshold and
stay on the per-poly leg.

Byte-equality regression (TestPulsar_GPU_ByteEqual, ModeP65) PASSES.
The test's four Round-2 batches are sized 5, 5, 6, 6 — all strictly
below the accel threshold — so both legs run the per-poly path and
the bit-identical contract holds by construction. Wider FIPS 204
verification (TestSignVerify_RoundTrip_AllModes including ModeP87)
continues to pass because both legs compute the same Z_q residues
and the FIPS 204 verifier checks math, not intermediate uint32
representations.

Tests:
  go build ./...                                    PASS
  go test -count=1 ./...                            PASS
  go test -count=1 -tags accel ./...                PASS
  go test -count=1 -race -run TestPulsar_GPU_ByteEqual ./...  PASS
2026-06-03 13:10:04 -07:00
zeekay cca73e1eaa gpu: pulsar wires onto shared luxfi/lattice/v7 dispatcher
Corona = rank-1 Pulsar (R_q^k specialised at k=1). Both share the
lattice GPU NTT dispatcher; pulsar's gpu/ subpackage is a thin
RegisterRing wrapper matching corona/gpu/. Byte-equal contract
verified by TestPulsar_GPU_ByteEqual across (n,t) shapes (5,3),
(7,4), (10,7) and a UseAcceleratorForce variant pinning the
dispatcher at threshold=1.

Decomplecting note: pulsar's FIPS 204 NTT in mldsa_lattice.go
operates on [256]uint32 polynomials in 32-bit Montgomery form
(q=8380417, R=2^32); the lattice/v7 dispatcher operates on
[]uint64 in 64-bit Montgomery form. Pulsar's NTT does not route
through ring.SubRing today so the dispatcher is vacuous on
pulsar's N=256 production sign path. The gpu/ subpackage mirrors
corona/gpu's UseAccelerator / DisableAccelerator / RegisterRing /
Stats surface verbatim so multi-primitive consumers see one
opt-in. The byte-equal test is the regression guard for the v0.4
lift that widens mldsa_lattice.go to 64-bit Montgomery and routes
through ring.SubRing.

NIST-clean import discipline preserved. The reference package
github.com/luxfi/pulsar/ref/go/pkg/pulsar carries ZERO
non-test imports of lattice/v7 — go list -deps confirms only
circl + golang.org/x/crypto + stdlib transitively. The gpu/
subpackage is a separate import path; reviewers compiling the
reference for NIST submission with go build ./ref/go/pkg/pulsar
do not pull lattice or cgo. Lattice/v7 enters the import graph
only when go test runs (gpu surface tests + threshold_v03 byte-eq
test); lattice is pure-Go on default builds, no cgo engaged
unless -tags gpu && CGO_ENABLED=1 && Metal/CUDA link config.

Threshold combine routes through lattice/v7/gpu when a batched
dispatcher is engaged (UseAccelerator); single-poly dispatch
threshold is set ABOVE pulsar's production ring degree N=256
(defaultThreshold=1024, same default as corona) — operators with
a true batched dispatcher should lower SetThreshold via the gpu
subpackage's runtime knob.

Benches mirror corona/dkg2's CPU/GPU pair pattern: 5of7, 7of11,
14of21 at the v0.3 algebraic-threshold sign path. The
golang.org/x/crypto bump from v0.32.0 to v0.49.0 is a transitive
constraint from lattice/[email protected]; the bump is SHA3-byte-stable
(FIPS 202), verified by existing TestAlgebraic_ByteValid and KAT
round-trip passing post-bump.
2026-05-31 12:21:38 -07:00
zeekay 1c2a9ee1af pulsar: add \GF macro, rename corona2024->boschini2024corona, bump Go to 1.26.3
- spec/pulsar-m.tex: define \newcommand{\GF}{\mathrm{GF}} so any later
    GF(q)/GF(2^k) usage doesn't trip an undefined control sequence.
  - spec/references.bib: rename the Corona bibtex key from corona2024
    to boschini2024corona — matches the catalogue-wide Corona->Corona
    rename (Corona is the production name).
  - go.mod: go directive 1.22.0 -> 1.26.3 (matches the rest of the stack).
2026-05-13 12:46:07 -07:00
zeekay 6e93847ab2 pulsar: rename module path github.com/luxfi/pulsar-m → github.com/luxfi/pulsar
The Module-LWE threshold ML-DSA library claims its canonical name.
The legacy 'pulsar-m' suffix existed only because the Ring-LWE
library held the 'github.com/luxfi/pulsar' import path. That R-LWE
code has now moved to github.com/luxfi/corona; this library is the
sole Pulsar going forward.

NIST MPTC Class N1: byte-equal output to single-party FIPS 204
ML-DSA. Round-1 commit + Round-2 response + Combine produces a
signature that verifies under unmodified mldsa.Verify.

All tests pass under GOWORK=off.
2026-05-11 19:18:41 -07:00
zeekay 6fd38d451f pulsar-m: bootstrap NIST MPTC submission package
Initial commit. Holds the technical specification (LaTeX), the design
docs, the build/test/bench scripts, the package layout, and the empty
ref/go/pkg/pulsarm skeleton.

The spec at spec/pulsar-m.tex (11,300 words of LaTeX) is the canonical
description of the protocol. docs/nist-mptc-category.md states the
Class N1 + N4 claim. CONTRIBUTING.md and SECURITY.md pin the IP and
disclosure posture.

Subsequent commits land the reference implementation in stages.

Signed-off-by: Lux Industries <[email protected]>
2026-05-10 20:25:09 -07:00