mirror of
https://github.com/luxfi/crypto.git
synced 2026-07-27 01:54:50 +00:00
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.
66 lines
1.4 KiB
Go
66 lines
1.4 KiB
Go
package bls
|
|
|
|
import "testing"
|
|
|
|
func TestBatchVerifyMatchesScalar(t *testing.T) {
|
|
n := BatchThreshold + 4
|
|
pks := make([]*PublicKey, n)
|
|
msgs := make([][]byte, n)
|
|
sigs := make([]*Signature, n)
|
|
|
|
for i := 0; i < n; i++ {
|
|
sk, err := NewSecretKey()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
pks[i] = sk.PublicKey()
|
|
msgs[i] = []byte{byte(i), byte(i << 1), byte(i + 7)}
|
|
sig, err := sk.Sign(msgs[i])
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sigs[i] = sig
|
|
}
|
|
|
|
got := BatchVerify(pks, msgs, sigs)
|
|
for i := range got {
|
|
if !got[i] {
|
|
t.Errorf("batch[%d] reported invalid", i)
|
|
}
|
|
if Verify(pks[i], sigs[i], msgs[i]) != got[i] {
|
|
t.Errorf("batch/scalar disagree at %d", i)
|
|
}
|
|
}
|
|
|
|
// Tamper one signature: BLS signatures are bytes; flip one bit.
|
|
tampered := SignatureToBytes(sigs[0])
|
|
tampered[0] ^= 0x01
|
|
bad, err := SignatureFromBytes(tampered)
|
|
if err != nil {
|
|
// Some bit-flips trip decompress validation, which is also a "false"
|
|
// answer; in that case skip and try next.
|
|
for i := 1; i < SignatureLen; i++ {
|
|
tampered = SignatureToBytes(sigs[0])
|
|
tampered[i] ^= 0x01
|
|
bad, err = SignatureFromBytes(tampered)
|
|
if err == nil {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if err == nil && bad != nil {
|
|
sigs[0] = bad
|
|
got = BatchVerify(pks, msgs, sigs)
|
|
if got[0] {
|
|
t.Error("batch accepted tampered signature")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBatchVerifyEmpty(t *testing.T) {
|
|
got := BatchVerify(nil, nil, nil)
|
|
if len(got) != 0 {
|
|
t.Errorf("empty input returned len %d", len(got))
|
|
}
|
|
}
|