e2e/go.mod required github.com/luxfi/precompile v0.5.27 with no replace, so the
suite compiled against a published artifact 33 patch releases behind the tree it
lives in. e2e/clob already had `replace => ../..`; the parent module never did.
The consequence was not that the tests were weak, it was that they could not
observe this repo at all — seven of them had been failing against real code and
nothing could report it. Adding the replace also removes the checksum failure
they hit on the way in: the v0.5.27 tag was force-moved after publication, so
github now serves bytes that do not match what sum.golang.org attests, and the
suite could not resolve its own parent.
With the replace in place, the seven pre-existing failures are visible, and all
seven were the tests being wrong:
StableSwap x4 — the calldata was written by hand at each of four call sites
with a one-byte token count and the amplification factor last. getD and getDy
read a four-byte count and take the amplification before the balances. The
layout now lives in encodeGetD/encodeGetDy and nowhere else, which is what
stops it drifting again.
CGGMP21 — threshold ECDSA on secp256k1, handed a P-256 key. The precompile
refused it correctly. Now generates a real secp256k1 key and signature.
FROST — verifies secp256k1 x-only Schnorr via curve.Secp256k1{}.LiftX; the
test built an edwards25519 key, on the strength of a comment claiming FROST
keys are Ed25519-compatible, which is not true of this implementation.
Ed25519 — took 32 bytes from rand.Read and required them to be a canonical
scalar, which holds about one time in sixteen, then hand-rolled a SHA-256
Schnorr with s = k - e*x. RFC 8032 uses SHA-512 and s = r + e*a, and the
precompile calls ed25519.Verify, so it could not have verified even with a
valid scalar. Now signs with crypto/ed25519.
Keys come from a seeded source so a failure reproduces. Added the negative
cases these lacked entirely: signature bound to its message, every bit-flip
refused, all-zero key refused, truncated and over-long frames refused, and
gas charged on refusal. FROST keeps only its refusal cases here — the positive
path needs the threshold library's domain-separated challenge, which belongs in
frost/real_sig_test.go rather than in a second copy.
Also removes cmd/safekatdump and cmd/safekatverify. safekatdump's doc comment
claimed it "generates real known-answer test (KAT) vectors"; it generates a
fresh key and a fresh signature from rand.Reader on every run and safekatverify
then checks that our verifier accepts what our signer just produced. That
passes unchanged if the implementation is uniformly wrong on both sides, which
is the failure a KAT exists to catch. Nothing consumed the output: no Makefile
target, no CI step, no checked-in fixture, and no reference to either program
anywhere outside their own doc comments. Genuine frozen vectors now live in the
packages, under go test, where they run.
e2e/clob is left alone: it replaces github.com/luxfi/dex with a sibling working
checkout, so it currently fails on an undefined symbol from that tree's
in-progress state rather than anything here.
Lux Precompiled Contracts
Native EVM precompiles for the Lux blockchain. Each precompile is a Go package that implements contract.StatefulPrecompiledContract and registers via modules.RegisterModule() in its init().
Geth provides NewPrecompileAdapter() to wrap these into geth-compatible precompiles. L1 chains select which precompiles to enable via PrecompileOverrider.
Precompiles
Post-Quantum Cryptography (baseline — all Lux chains)
| Package | Address | Description | Gas |
|---|---|---|---|
mldsa |
0x0200...0006 |
ML-DSA-65 signature verify (FIPS 204) | 100k + 10/byte |
slhdsa |
0x0600...0001 |
SLH-DSA signature verify (FIPS 205) | 15k–250k by mode |
mlkem |
0x0200...0007 |
ML-KEM-768 encapsulate/decapsulate | 50k base |
xwing |
0x2221 |
X-Wing hybrid KEM (X25519 + ML-KEM-768) | 40k |
Threshold Signatures
| Package | Address | Description | Gas |
|---|---|---|---|
frost |
0x0800...0002 |
FROST Schnorr threshold verify (secp256k1/Ed25519) | 50k + 5k/signer |
cggmp21 |
0x0800...0003 |
CGGMP21 threshold ECDSA verify (secp256k1) | 75k + 10k/signer |
Corona |
0x0200...000B |
Module-LWE lattice threshold verify (post-quantum) | 150k + 10k/party |
Curves & Signatures
| Package | Address | Description | Gas |
|---|---|---|---|
sr25519 |
0x0A00...0001 |
Schnorrkel verify for Substrate→EVM migration | 9k + 3/byte |
ed25519 |
0x3211...0000 |
Ed25519 signature verify | 3k |
secp256r1 |
0x0100 |
P-256 ECDSA verify (WebAuthn/passkeys) | 3.5k |
Hashing
| Package | Address | Description | Gas |
|---|---|---|---|
blake3 |
0x0500...0004 |
Blake3 hash, Merkle root, KDF, XOF | 100 + 3–5/word |
kzg4844 |
0xB002 |
KZG polynomial commitment (EIP-4844) | 50k |
Privacy & ZK
| Package | Address | Description | Gas |
|---|---|---|---|
zk |
0x0900 |
ZK proof verification (Groth16, PLONK, fflonk, Halo2) | 180k–500k |
fhe |
— | Fully homomorphic encryption ops | variable |
ring |
0x9202 |
Ring signature verification | variable |
ecies |
0x9201 |
ECIES encryption/decryption | variable |
hpke |
0x9200 |
Hybrid public key encryption | variable |
DEX
| Package | Address | Description | Gas |
|---|---|---|---|
dex |
0x0400...0000 |
Native DEX (PoolManager, Router, Hooks, Lending) | variable |
Infrastructure
| Package | Address | Description | Gas |
|---|---|---|---|
ai |
0x0300...0000 |
AI mining (ML-DSA verify, TEE attestation, rewards) | variable |
quasar |
— | Hybrid consensus certificate verification | variable |
dead |
0x0000...0000 |
Dead address interceptor | minimal |
graph |
— | GraphQL query precompile | variable |
bridge |
— | Cross-chain bridge verification | variable |
attestation |
0x0300...0001-05 |
TEE/GPU attestation (NVTrust, TPM, SGX/SEV/TDX) | 25k–75k |
anchor |
0x0700...0010 |
Cross-chain state anchoring | 2.6k–25k |
vrf |
0x3213 |
ECVRF verify (RFC 9381) | 20k |
compute |
0x0300...0010 |
AI compute attestation | variable |
Support Packages
| Package | Purpose |
|---|---|
contract |
Core interfaces (StatefulPrecompiledContract, AccessibleState) |
modules |
Module registration system and reserved address ranges |
precompileconfig |
Config interfaces (Upgrade, Timestamp, IsDisabled) |
registry |
Address-to-LP mapping |
Structure
Each precompile follows this pattern:
<name>/
├── contract.go # Run(), RequiredGas(), Address()
├── contract_test.go # Tests with known vectors
├── module.go # init() → modules.RegisterModule()
└── I<Name>.sol # Solidity interface (optional)
Adding a Precompile
- Pick an address in a reserved range
- Implement
contract.StatefulPrecompiledContract - Register via
modules.RegisterModule()ininit() - Add tests (valid, invalid, gas, edge cases)
- Wire into your L1 via
PrecompileOverrideror geth'sLuxPrecompiles()
Building
go build ./...
go test ./...
go test -bench=. ./sr25519/ # benchmark a specific package
CGO is required for sr25519 (sr25519-donna C library). All other packages are pure Go.
License
Copyright (C) 2025, Lux Industries, Inc. All rights reserved.
ZK-Friendly Curves (0x0500)
| Package | Address | Description | Gas |
|---|---|---|---|
poseidon |
0x0500..05 |
Poseidon/Poseidon2 hash (ZK-optimized, PQ-safe) | 800 |
pedersen |
0x0500..06 |
Pedersen commitment (legacy, NOT PQ-safe) | 6,000 |
babyjubjub |
0x0500..07 |
Baby Jubjub curve (BN254 scalar field, zkEVM) | 3,000 |
pasta |
0x0500..08 |
Pallas + Vesta curves (Halo2 proving) | 5,000 |
Symmetric & Key Exchange
| Package | Address | Description | Gas |
|---|---|---|---|
aes |
0x9210 |
AES-256-GCM authenticated encryption | 5,000 |
chacha20 |
0x9211 |
ChaCha20-Poly1305 stream cipher | 4,000 |
x25519 |
0x9203 |
X25519 Diffie-Hellman key exchange | 10,000 |
xwing |
0x0200..0C |
X-Wing hybrid KEM (X25519 + ML-KEM-768) | 50,000 |
curve25519 |
0x9204 |
Raw Curve25519 point operations | 5,000 |
Math (0x0450)
| Package | Address | Description | Gas |
|---|---|---|---|
math |
0x0450 |
MulDiv, Sqrt, Log2, Exp, Pow (fixed-point) | 50 + 5/word |
Saves ~2000 gas per MulDiv vs Solidity. Used by every DeFi calculation.
StableSwap (0x0460)
| Package | Address | Description | Gas |
|---|---|---|---|
stableswap |
0x0460 |
Curve-style constant-sum AMM | 5,000 |
10x gas savings vs Solidity StableSwap. For pegged-asset pools (LUSD/USDC, LETH/stETH).
Compute Market (0x0310)
| Package | Address | Description | Gas |
|---|---|---|---|
compute |
0x0310 |
AI compute marketplace | 10,000-50,000 |
Integrates with A-Chain TEE attestation. Register GPU providers, submit jobs, verify compute, claim $AI rewards.