4 Commits
Author SHA1 Message Date
Hanzo AI 333b13fc9c mldsa: propagate accel.ErrInvalidArgument as hard error (Red CRITICAL-2)
Closes Red CRITICAL-2 (red-c-new-1). The luxcpp/accel layer's M-1
tri-state propagation (5a02e55b) was effectively defeated by Go
consumers that swallowed every error into a silent CPU fallback. The
consensus-split-prevention claim was hollow: a malformed input the
GPU rejected with INVALID_ARGUMENT would silently CPU-pass via
cloudflare/circl, which accepts arbitrary-length messages per FIPS
204. Two nodes running the same input could produce different
verdicts depending on whether they ran GPU or CPU → consensus split.

Fix: ErrInvalidArgument from accel propagates as a hard error;
ErrNotSupported, ErrOutOfMemory, ErrKernelFailed, ErrNoBackends
remain silent-fallback (they're recoverable: GPU path unavailable,
not contract violation). Three call sites updated:

  * crypto/mldsa/gpu.go::batchVerifyGPU — returns (false, err) with
    ErrInvalidArgument so batch.go::BatchVerify panics (no error
    return, same shape as existing length-mismatch + mixed-mode
    panics in the same function).
  * crypto/mldsa/gpu.go::batchSignGPU — same shape; batch.go::
    BatchSign already returns error so it surfaces directly.
  * crypto/pq/mldsa/gpu/gpu_cgo.go::{signBatch,verifyBatch} — same
    classifier; signBatch returns the error to BatchSign caller,
    verifyBatch returns (nil, err) to BatchVerify caller.

Skip-list in batchVerifyGPU: when ErrInvalidArgument bubbles from
MLDSAVerifyBatch and the mode is ML-DSA-65, do NOT fall back to the
legacy DilithiumVerifyBatch path — that path runs the SAME C ABI
under a different dispatch slot and would reject again. Only mask
the legacy retry when the FIRST error was something other than
ErrInvalidArgument (NotSupported is the canonical case: a substrate
that doesn't publish the new MLDSAVerifyBatch slot but does publish
the legacy Dilithium3 kernel).

New test: pq/mldsa/gpu/invalid_argument_propagation_test.go locks
the policy in as a unit test. It verifies:
  1. accel.ErrInvalidArgument exists.
  2. errors.Is(...) detects it through fmt.Errorf %w wraps.
  3. Other accel sentinels do not alias it.
  4. The classifier ("hard" vs "recover") matches the dispatch code
     for nil, ErrInvalidArgument (raw + wrapped), ErrNotSupported,
     ErrOutOfMemory, ErrKernelFailed, ErrNoBackends, and an unrelated
     error.

This is the propagation policy test the prompt asked for. A
real-input fault-injection test would need a > 2 GB synthetic
message (Go can't construct one in CI memory budgets) or a session
mock harness (overengineering for a single check); the policy test
locks the error-routing logic at the exact `errors.Is` boundary
where the contract lives.

luxgo crypto module version stays at current; no breaking-API change.
2026-06-05 02:38:14 -07:00
Hanzo AI 158edb279c fix: gofmt -s across repo (CI format check) 2026-06-02 11:39:06 -07:00
Hanzo AI 589cd47a92 crypto: runtime dispatch provenance for mldsa+slhdsa, ML-DSA-44/87 batch tests
Adds Provenance() on slhdsa/mldsa packages so reviewers can ask the
running binary "which dispatch tier is live right now?" instead of
trusting a static claim. Honest by construction: a release build
without the SLH-DSA / ML-DSA backend plugin reports TierAccelCPUFallback
or TierGoroutineParallelCPU, never TierGPUSubstrate.

The strong-symbol observation is recorded by batchVerifyGPU /
batchSignGPU after a successful C ABI dispatch; subsequent
GetProvenance() calls report TierGPUSubstrate. The cache only goes
0 -> 1 so transient tensor allocation failures cannot regress
provenance to "no plugin".

mldsa/batch.go: 3-tier dispatch (GPU -> goroutine-parallel CPU ->
serial CPU), mirroring slhdsa. concurrentBatchThreshold=8 tuned for
the FIPS 204 verify cost.

ML-DSA-44 and ML-DSA-87 batch tests pin KAT replay + CPU/GPU
equivalence + tamper rejection across the dispatch tiers. Previously
only ML-DSA-65 had this coverage.

Removed dead pq/slhdsa/gpu/gpu.go (replaced by the live dispatcher
in slhdsa/gpu.go).
2026-05-21 14:11:16 -07:00
Hanzo AI ecaca10cdb canonical Go entry: backend selector + batch GPU paths via lux/accel
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.
2025-12-27 19:30:33 -08:00