mirror of
https://github.com/luxfi/crypto.git
synced 2026-07-27 01:54:50 +00:00
Adds the canonical runtime substrate selector for luxfi/crypto and decomplects
all per-algorithm GPU dispatchers behind it.
New `backend` API:
- Default()/SetDefault/Resolved()/IsGPU/IsCGo/IsVanilla — runtime selection
- CGoAvailable()/GPUAvailable() — real probes (was stubbed)
- Probe() returning Snapshot{Default, Resolved, CGo, GPU, Disabled,
GPUBackend, GPUDeviceCount, AccelVersion, Fallbacks}
- GPUDisabled() reads LUX_GPU_DISABLE operator kill switch
- RecordFallback(reason, where) atomic counter + one-shot log per reason,
low-cardinality FallbackReason enum (disabled / unsupported / probe_failed
/ backend_unavailable / abi_mismatch)
Dispatcher cleanup (one-and-one-way):
- All Resolve(gpuhost.Available(), false) call sites replaced with IsGPU()
- hqc switched to IsVanilla() (its accel batch wins for any non-vanilla pick)
- gpu/gpu.go now delegates entirely to backend (no separate session)
- internal/gpuhost dropped Snapshot()/Provenance — backend.Probe() canonical
Build tag policy: CGo is the only gate. There is no `gpu` build tag.
LLM.md documents the canonical surface.
65 lines
1.5 KiB
Go
65 lines
1.5 KiB
Go
package backend_test
|
|
|
|
// Determinism contract: when a caller flips CRYPTO_BACKEND between vanilla
|
|
// and gpu, the output of every public function in luxfi/crypto MUST be
|
|
// byte-identical. This test exercises the contract on the algorithms we have
|
|
// batch GPU paths for.
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/rand"
|
|
"testing"
|
|
|
|
"github.com/luxfi/crypto/backend"
|
|
"github.com/luxfi/crypto/keccak256"
|
|
"github.com/luxfi/crypto/sha256"
|
|
)
|
|
|
|
func TestKeccak256BatchAcrossBackends(t *testing.T) {
|
|
inputs := make([][]byte, keccak256.BatchThreshold+8)
|
|
for i := range inputs {
|
|
buf := make([]byte, 32)
|
|
rand.Read(buf)
|
|
inputs[i] = buf
|
|
}
|
|
|
|
prev := backend.Default()
|
|
t.Cleanup(func() { backend.SetDefault(prev) })
|
|
|
|
backend.SetDefault(backend.Vanilla)
|
|
vanilla := keccak256.SumBatch(inputs)
|
|
|
|
backend.SetDefault(backend.GPU)
|
|
gpu := keccak256.SumBatch(inputs)
|
|
|
|
for i := range vanilla {
|
|
if vanilla[i] != gpu[i] {
|
|
t.Errorf("keccak[%d] vanilla=%x gpu=%x", i, vanilla[i], gpu[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSHA256BatchAcrossBackends(t *testing.T) {
|
|
inputs := make([][]byte, sha256.BatchThreshold+8)
|
|
for i := range inputs {
|
|
buf := make([]byte, 32)
|
|
rand.Read(buf)
|
|
inputs[i] = buf
|
|
}
|
|
|
|
prev := backend.Default()
|
|
t.Cleanup(func() { backend.SetDefault(prev) })
|
|
|
|
backend.SetDefault(backend.Vanilla)
|
|
vanilla := sha256.Sum256Batch(inputs)
|
|
|
|
backend.SetDefault(backend.GPU)
|
|
gpu := sha256.Sum256Batch(inputs)
|
|
|
|
for i := range vanilla {
|
|
if !bytes.Equal(vanilla[i][:], gpu[i][:]) {
|
|
t.Errorf("sha256[%d] vanilla=%x gpu=%x", i, vanilla[i], gpu[i])
|
|
}
|
|
}
|
|
}
|