mirror of
https://github.com/luxfi/math.git
synced 2026-07-27 03:38:49 +00:00
ntt, poly, rns, sample
Eight pure-Go reference packages that own the canonical semantics of
every cryptographic-math primitive Lux protocols share. Backends
(AVX2 / NEON / cgo+C++ / CUDA / Metal / WGSL) plug in behind the
substrate; KATs gate byte-equality across them.
Packages added:
* params/ — ModulusID, NTTParamID, FHEParamID, PulsarParamID,
HashSuiteID, BackendID; KATHeader required-fields
schema. Stable string IDs; renaming is a breaking
change.
* backend/ — Policy enum (PureGo / NativeCPU / GPUPreferred /
GPURequired); Resolve(policy, registered) returns the
BackendID per LP-107's fallback chain. GPURequired
returns ErrUnavailable when no GPU backend is
registered.
* codec/ — Bounded readers (closes lattice issues #2 + #4 DoS
class permanently). Limits + LimitError + Reader.
ReadUint{16,32,64}Slice all reject the 70T-element
attack input before allocating; depth + frame-bytes
caps; iterative (no recursion). Regression test
TestReadUint64Slice_RejectsHugeLength encodes the
original lattice issue #4 input.
* modarith/ — Modulus type with QInv, R2, Barrett constants
(computed via math/big once per modulus). AddMod /
SubMod / MulMod (Div64 reference path). MontMulMod /
ToMontgomery / FromMontgomery cross-checked against
MulMod across 100 random Pulsar-Q pairs.
ReductionMode enum byte-equal to lattice/types.
* ntt/ — Service + Backend interface; pure-Go backend
delegates to lattice/v7/ring.SubRing.NTT/INTT (the
canonical Lattigo-derived Montgomery NTT body — no
re-implementation, just dispatch). Round-trip +
batch + determinism tests on Pulsar N=256.
* poly/ — Add / Sub / ScalarMul / PointwiseMul (NTT-domain) /
negacyclic Mul (NTT round-trip). Composes modarith +
ntt; no lower-level reach.
* rns/ — Basis(Moduli, Name) for FHE RNS chains. Single +
two-prime construction validated; rejects even moduli.
Phase 3 will add basis-extension and modulus-switching.
* sample/ — Uniform (rejection sampling, mask-and-retry); Ternary
(density + sign byte); CenteredBinomial (popcount
difference); DiscreteGaussianRejection (6-sigma cutoff).
All take an io.Reader so callers can KAT-replay.
Architecture invariants enforced in package docs:
- Go is the canonical semantic reference.
- Backend selection MUST NOT alter transcript bytes (consensus
paths default to PolicyPureGo / PolicyNativeCPU).
- No unbounded codec readers anywhere near wire formats.
- No re-implementation: where lattice/v7/ring already owns the
canonical body, we delegate, not fork.
- One ID space; renaming is a breaking change.
Test posture: 8/8 packages green via `GOWORK=off go test ./...`.
Phases 3-7 (queued):
3. lattice consumes math
4. pulsar consumes lattice + math
5. fhe consumes math
6. luxcpp/crypto/math native backend mirror
7. cross-runtime KAT release gate
See SUBSTRATE.md for the full posture and migration plan; full LP at
~/work/lux/lps/LP-107-lux-math-substrate.md.
4.7 KiB
4.7 KiB
Lux Math — High-Performance Cryptographic Substrate
LP-107 reference implementation. The luxfi/math Go module owns the
canonical Go reference for every cryptographic-math primitive that
Lux protocols share, with a backend interface that lets native CPU
(AVX2 / NEON / cgo+C++) and GPU (CUDA / Metal / WGSL) realizations
drop in behind it.
Substrate packages (LP-107 Phase 2)
| Package | Owns | Status |
|---|---|---|
params |
ModulusID, NTTParamID, FHEParamID, PulsarParamID, HashSuiteID, BackendID; KAT header schema | ✅ pure-Go reference, validated |
backend |
Policy enum (PureGo / NativeCPU / GPUPreferred / GPURequired), Resolve() dispatch | ✅ pure-Go reference, validated |
codec |
Bounded readers (closes lattice issues #2 + #4 DoS class) | ✅ pure-Go reference, validated |
modarith |
Barrett, Montgomery, AddMod / SubMod / MulMod, ReductionMode | ✅ pure-Go reference, validated |
ntt |
NTT Service + Backend interface; pure-Go backend delegates to lattice/v7/ring.SubRing.NTT/INTT |
✅ pure-Go reference, validated |
poly |
Polynomial Add / Sub / ScalarMul / PointwiseMul / negacyclic Mul (via NTT round-trip) | ✅ pure-Go reference, validated |
rns |
RNS Basis primitives (single + multi-prime towers) | ✅ pure-Go reference, validated |
sample |
Uniform / Ternary / CenteredBinomial / DiscreteGaussianRejection samplers | ✅ pure-Go reference, validated |
Architecture invariants
- Go is the canonical semantic reference. C++ / GPU backends realize the same contract; KATs prove byte-equality.
- Backend selection MUST NOT alter transcript bytes for consensus
paths. Default policy is
PolicyPureGoorPolicyNativeCPU. - No unbounded codec readers. Every wire-format decode goes
through
codec.Reader; theReadUint64Slicerecursion + OOM bug classes are fixed centrally. - No re-implementation. Where the canonical impl already lives
in
luxfi/lattice(Lattigo-derived NTT/Montgomery), the substrate delegates rather than fork. LP-107 Phase 3 inverts the dependency. - One ID space.
params.ModulusID/NTTParamID/ etc. are stable strings; renaming is a breaking change. KATs key off them.
Test posture
GOWORK=off go test ./...
| Package | Tests |
|---|---|
params |
ModulusID/NTTParamID/FHEParamID/PulsarParamID/HashSuiteID/BackendID validation; KATHeader required-fields |
backend |
Policy String + Validate; Resolve fallback chain (PureGo / NativeCPU / GPUPreferred / GPURequired); GPU-required-no-GPU returns ErrUnavailable |
codec |
Limits validation; Uvarint round-trip; happy-path uint16/32/64 slice reads; regression test for lattice issue #4 (70T-element attack input rejected with LimitError); depth + frame-bytes caps |
modarith |
NewModulus rejects zero/even; QInv satisfies q*QInv ≡ -1 mod 2^64; AddMod / SubMod / MulMod cross-checked vs math/big across 1000 random pairs; Montgomery round-trip + 100 randomized MontMul-vs-MulMod cross-checks; LazyModeFits |
ntt |
Params validation; PureGo round-trip on Pulsar N=256; batch round-trip; determinism across two Service instances |
poly |
Add+Sub round-trip; ScalarMul; negacyclic Mul via NTT (a=2 * b=3 → coefficient 0 = 6, others = 0) |
rns |
Basis construction (single-prime + two-prime); rejection of empty + even moduli |
sample |
Uniform determinism (same seed → byte-equal output); Ternary distribution + balance; CenteredBinomial range-bounded; DiscreteGaussianRejection 1000-sample range |
Migration plan (LP-107 Phases 3-7)
- Phase 3 —
latticeconsumesmath.lattice/ring/SubRing.NTTrewires to delegate tomath/ntt. Pulsar / Lens / FHE see no source change at first; v0.2.0 deprecates directlattice/ringimports for new code. - Phase 4 —
pulsarconsumeslattice+math. Drop ad-hoc Montgomery code; consumemath/modarith. - Phase 5 —
fheconsumesmath. Share NTT/RNS primitives with Pulsar where parameter-compatible. - Phase 6 —
luxcpp/crypto/mathmirrors the Go module structure and becomes the native backend formath/ntt,math/poly,math/sample. KATs gate every byte across runtimes. - Phase 7 — Cross-runtime KAT release gate. Go math KAT → C++ verifies; C++ math KAT → Go verifies; GPU math KAT → CPU verifies.
Design references
LP-107— full spec.lattice/v7/ring— canonical Lattigo-derived NTT/Montgomery body that this module delegates to.luxcpp/crypto/corona— native C++ Montgomery NTT that Phase 6 mirrors asmathC++.