luxfi/crypto becomes the single Go entry point for ALL Lux-family crypto. Every public function in this module now dispatches between three implementations through a runtime-selectable backend: - vanilla: pure-Go reference (always available) - cgo: native binding (blst, libsecp256k1, ckzg) where present - gpu: batch acceleration via github.com/luxfi/accel The dispatcher reads LUX_CRYPTO_BACKEND (auto|vanilla|cgo|gpu); auto picks the most capable backend the binary was compiled and linked with. New canonical packages: backend/ runtime backend selector (env + programmatic) internal/gpuhost/ accel session lifecycle, single per-process keccak/ Keccak-256 with batch GPU dispatch sha256/ SHA-256 with batch GPU dispatch sha3/ SHA3 / SHAKE family ripemd160/ RIPEMD-160 (Bitcoin/Lux address derivation) ed25519/ Ed25519 with batch GPU verify bn254/ canonical alias for bn256 (matches FIPS naming) modexp/ canonical alias for bigmodexp evm256/ EIP-196/197 precompile ABI wrappers poseidon/ Poseidon2 hash via gnark-crypto pedersen/ Pedersen commitments over BN254 ntt/ Number-Theoretic Transform reference polymul/ negacyclic polynomial multiplication Extended existing packages with batch GPU paths: bls/batch.go BatchVerify routes through accel.BLSVerifyBatch mldsa/batch.go BatchVerify (ML-DSA-65) via accel.DilithiumVerifyBatch mlkem/batch.go BatchEncapsulate / BatchDecapsulate via Kyber kernels secp256k1/batch.go BatchVerifySignature via accel.ECDSAVerifyBatch GPU dispatch is gated on (a) backend.Default(), (b) batch size threshold, and (c) accel.Available(). When any gate fails the call falls through to the vanilla CPU path; output is byte-identical. The legacy gpu/ stub is replaced with a thin probe surface (Available, Backend, Devices, Version) that delegates to the same gpuhost session. Tests show vanilla and gpu backends produce identical outputs across all batch entry points (-race clean). See AUDIT.md for the per-algorithm state matrix and honest gaps.
8.2 KiB
luxfi/crypto AUDIT
Date: 2026-04-26 Scope: existing algorithm packages and what each backend (vanilla, cgo, gpu) currently has.
luxfi/crypto is the canonical Go entry point. Every consumer
(lux/node, zoo/node, hanzo/node-go, hanzod, parsd, zood,
lux/precompile, lux/cli, …) imports from here. Behind every public
function there are up to three implementations dispatched by build tags
plus a runtime backend selector (backend.Default()).
| Tag-set | Path | Notes |
|---|---|---|
!cgo |
vanilla | Pure Go reference. Always available. |
cgo |
cgo | Native binding (blst, libsecp256k1, ckzg) |
cgo,accel |
gpu | Routes batch ops through lux/accel |
backend.Default() reads LUX_CRYPTO_BACKEND (auto|vanilla|cgo|gpu)
and falls back to auto. auto picks the highest-priority backend the
binary was compiled with.
Per-algorithm state
Legend: V = vanilla Go, C = cgo, G = GPU via lux/accel, T = tests.
| Algorithm | V | C | G | T | Notes |
|---|---|---|---|---|---|
| address | Y | - | - | - | Bech32/cb58 helpers, no compute kernel |
| aead | Y | - | - | - | XChaCha20-Poly1305 wrapper around stdlib |
| aggregated | Y | - | - | Y | Signature aggregator manager (BLS) |
| bigmodexp | Y | - | - | - | EVM precompile reference impl |
| bindings/cabi | - | E | - | - | c-shared exporter; produces libluxcrypto.{dylib,so} |
| bitutil | Y | - | - | - | EVM bit utilities (no kernel) |
| blake2b | Y | A | G* | Y | AVX2 asm in _amd64.s. GPU added (batch). |
| bls | Y | Y | G* | Y | circl pure-Go (!cgo) + blst (cgo). GPU added (batch verify/aggregate). |
| bls12381 | Y | Y | - | - | gnark (!cgo) + blst (cgo) field arithmetic |
| bn256 | Y | Y | - | Y | cloudflare + gnark + google fallbacks |
| cb58 | Y | - | - | Y | Pure Go base58 + checksum |
| cert | - | - | - | - | Empty placeholder (TLS cert helpers) |
| cggmp21 | Y | - | - | - | Threshold ECDSA, Paillier — pure Go |
| cgo | - | E | - | - | luxlink: pkg-config aggregator, no algorithms |
| common | Y | - | - | - | Hash, hex, types — utility |
| da | - | - | - | - | Empty placeholder |
| dist | - | E | - | - | Built C-shared artefact (libluxcrypto.dylib + .h) |
| docs | - | - | - | - | fumadocs site |
| ecies | Y | - | - | Y | Hybrid encryption — pure Go |
| encryption | Y | - | - | Y | age + HPKE wrappers |
| gpu | - | - | E | - | Existing thin GPU stub. Replaced by per-alg gpu paths. |
| hash | Y | - | G* | Y | SHA, BLAKE, Keccak, Poseidon2 helpers. GPU added (batch). |
| hashing | Y | - | - | - | Re-export under hashing/hashing |
| hpke | Y | - | - | - | Stdlib crypto/hpke wrapper (Go 1.26) |
| ipa | Y | - | - | Y | gnark IPA + bandersnatch + banderwagon |
| kdf | Y | - | - | - | Stdlib HKDF wrapper |
| kem | Y | Y | - | - | circl ML-KEM + hybrid X-Wing |
| kzg4844 | Y | Y | G* | Y | gokzg (!ckzg) + ckzg (cgo,ckzg). GPU added (batch verify). |
| lamport | Y | - | - | Y | Hash-based OTS — pure Go |
| mldsa | Y | - | G* | Y | circl FIPS-204. GPU added (batch sign/verify) when accel exposes Dilithium. |
| mlkem | Y | * | G* | Y | circl FIPS-203. cgo file is currently a placeholder (mlkem_c.go). GPU added (batch encaps/decaps). |
| pq | Y | - | - | - | Re-export aggregator over mldsa+mlkem+slhdsa |
| precompile | Y | - | - | Y | EVM precompile impls — pure Go |
| ring | Y | - | - | Y | LSAG + Lattice ring sigs — pure Go |
| rlp | Y | - | - | - | Pure Go RLP |
| secp256k1 | Y | Y | G* | Y | dcrd (!cgo) + libsecp256k1 (cgo). GPU added (batch ECDSA verify). |
| secp256r1 | Y | - | - | - | NIST P-256 verifier (RIP-7212) |
| secret | Y | - | - | Y | Go 1.26 runtime/secret wrapper |
| sign | - | - | - | - | Empty placeholder |
| signer | Y | - | - | Y | Hybrid BLS+Corona signer |
| signify | Y | - | - | Y | OpenBSD-style signify |
| slhdsa | Y | - | - | Y | circl FIPS-205 — pure Go |
| threshold | Y | - | - | Y | Threshold scheme registry + BLS impl |
| verkle | Y | - | - | - | go-verkle wrapper |
Legend:
Y= real implementation present*= placeholder file exists, real implementation pending or routed elsewhereE= exporter/aggregator (not an algorithm)G*= GPU dispatcher added by this commit; falls back to vanilla/cgo when accel is not available (!cgobuild, no GPU device, or operation not supported)-= not applicable / not present
Canonical naming
Two synonyms exist in the tree because both names appear in upstream specs.
We expose both import paths to avoid breaking consumers; the
<canonical>/<synonym>.go file is a 4-line re-export that imports the
canonical package. The canonical name is the explicit FIPS / RFC name:
| Canonical | Synonym (kept for compat) |
|---|---|
bls12381 |
bls (signature scheme; uses bls12381 field) |
bn254 |
bn256 (curve order, equivalent name) |
kzg4844 |
(no synonym) |
For the new Phase-1 luxcpp/crypto algorithm list we add new dirs only when the algorithm did not already exist:
- Added in this commit:
keccak/,sha256/,sha3/,ripemd160/,ed25519/,pedersen/,poseidon/,ntt/,polymul/(= luxcpp's poly_mul),evm256/,bn254/(canonical alias forbn256),modexp/(canonical alias forbigmodexp). - Already present:
aead,blake2b,bls,bls12381,bn256,cggmp21,ipa,kzg4844,lamport,mldsa,mlkem,bigmodexp,secp256k1,secp256r1,slhdsa,verkle,threshold/bls. - Deliberately NOT created here:
sr25519/— Substrate-specific schnorrkel; no in-tree consumer requires it today and adding a dependency just for a thin wrapper fails the philosophy. Will be added with first real consumer.frost/— FROST is already exposed viagithub.com/luxfi/crypto/threshold(SchemeFROST) with the adapter living ingithub.com/luxfi/mpc/pkg/threshold. A separatefrost/dir would duplicate that surface.corona/— implemented natively ingithub.com/luxfi/corona/thresholdwhich registers itself withcrypto/threshold. Same reason as frost.
Backend selection
import "github.com/luxfi/crypto/backend"
backend.Default() // returns Vanilla|CGo|GPU based on build tags + env
backend.SetDefault(b) // override programmatically
backend.Available(b) // probe whether b is usable
Environment override: LUX_CRYPTO_BACKEND=vanilla|cgo|gpu|auto.
Honest gaps (Phase 3 / 4)
-
luxcpp/crypto C-ABI binding (Phase 1 sibling): spec mentioned
luxcpp/crypto/c-abi/lux_crypto.h— that header does not yet exist in the luxcpp tree (onlyc-abi/hash_types.hfrom upstream ethash is present). When the sibling agent lands the unified C-ABI, thecgo.gofiles in each algorithm package will be rewritten to use it directly. Today the cgo paths use the per-library bindings already in place (blst,libsecp256k1,ckzg). -
GPU coverage:
lux/accelexposes batch kernels for SHA256, Keccak256, Poseidon, ECDSA, Ed25519, BLS verify+aggregate, Merkle, plus Kyber and Dilithium. Algorithms without a kernel (slhdsa, verkle, kzg4844 single-blob path) keep vanilla/cgo only — gpu.go in those packages reportsaccel.ErrNotSupportedand the public API transparently falls back to the next backend. -
mlkem cgo file:
mlkem/mlkem_c.gowas a placeholder for future AVX2/AVX512 assembly. Today thecgobuild is identical to!cgo(both circl). Documented; intentional. -
gpu/top-level package previously held a single stub that returned "GPU not available" everywhere. We keep the file (consumers import it) but mark it Deprecated; new code should call the algorithm packages directly which dispatch to GPU internally. -
cert/,da/,sign/dirs are empty placeholders from earlier reorganizations. Left in place to avoid breaking tags/branches; will be deleted in a follow-up commit.