mirror of
https://github.com/luxfi/precompile.git
synced 2026-09-24 00:26:21 +00:00
Under the enable-everything precompile policy these verify-only precompiles are no longer refused under strict-PQ, so any divergence between the luxfi/accel GPU/SIMD path and the pure-CPU path is a LIVE consensus split: GPU-equipped and CPU-only validators would return different verify verdicts on the same input and the chain forks. Several accel paths were also outright wrong-primitive forgery surfaces. LAW applied: the GPU verdict must be byte-identical to the CPU verdict on every input, or the accel path is a consensus hazard and is removed. CPU (pure-Go, CGO_ENABLED=0) is now the single source of truth for every on-chain verdict. None of these GPU kernels can be proven byte-identical here, and several are provably NOT, so every verdict-trusting accel branch is deleted and routed to the canonical CPU verifier. Determinism over speed. Active forgery/wrong-output in the DEFAULT build (accelcrypto CPU fallback leaked non-CPU semantics, err==nil): - sr25519: verified via the accel Ed25519 kernel -> a valid Ed25519 signature was ACCEPTED as a valid sr25519/Schnorrkel signature (wrong-curve forgery). - blake3: accelcrypto.Hash(HashBlake3) returns BLAKE2b, not BLAKE3; the "real blake3" fallback was dead code. OpHash256 + MerkleRoot emitted BLAKE2b. Latent splits (reachable only under -tags accel + a GPU backend): - frost: FROST-Schnorr verified through the SigECDSA kernel (wrong primitive + 32B x-only key mis-framed as a 33B ECDSA key). - cggmp21: SigECDSA kernel truncated the 65B key to 33B and skipped the CPU path's recover-and-compare binding (ignored the v byte). - ed25519: GPU Ed25519 kernel not proven byte-identical to the canonical verifier on cofactor / non-canonical-S / small-order edge cases. - secp256r1: P-256 inputs sent to the fixed-curve secp256k1 ECDSA kernel. - mldsa: GPU verified with EMPTY context; precompile binds the FIPS-204 ctx "lux-evm-precompile-mldsa-v1" -> different mu, different verdict. - bls12381 / zk(groth16): GPU MSM result trusted without re-verification and with no curve binding carried to the kernel. - kzg4844: GPU commitment used the backend's OWN embedded trusted setup (empty SRS) instead of the canonical EIP-4844 SRS -> breaks KZG binding. - ai_mining (BatchVerifyMLDSA/BatchAccumulator): accel batch kernel truncates messages to 32 bytes and is mode-fixed -> diverges from VerifyMLDSA. - fhe: GPU computed BFV arithmetic while CPU computes TFHE (different scheme, incompatible ciphertext, nil relin key) -> corrupt + divergent ciphertext. Cleanups (no split, vestigial): removed dead mlkem encapsulateGPU; removed the hpke GPU pre-warm that discarded its result and returned the CPU output anyway. slhdsa was already CPU-only (prior identical fix). Tests (differential / forgery proofs, all green CGO_ENABLED=0 and CGO -race): - sr25519: a valid Ed25519 sig is now REJECTED; real sr25519 still verifies. - blake3: OpHash256/MerkleRoot output == BLAKE3 and != BLAKE2b. - cggmp21: flipped recovery byte is rejected (recover-compare authoritative). - frost: a valid ECDSA sig is rejected as FROST-Schnorr. - ed25519: verdict matches the canonical ed25519.Verify oracle over 64x4 vectors. - mldsa: empty-ctx sig (the accel framing) rejected; precompileCtx sig accepted. Net -593 LOC. No consensus code touched.
FHE Precompile
Fully Homomorphic Encryption (FHE) precompile for Lux blockchain, enabling privacy-preserving smart contracts.
Overview
This precompile provides FHE operations using the CKKS (Cheon-Kim-Kim-Song) scheme implemented in pure Go via luxfi/lattice. It supports threshold decryption through the T-Chain (67-of-100 validators via LP-333).
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ C-Chain (EVM) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Smart Contracts │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │
│ │ │ FHERC20.sol │ │ Auction.sol │ │ PrivateVote.sol │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ └────────┬────────┘ │ │
│ └──────────┼────────────────┼──────────────────┼──────────┘ │
│ │ │ │ │
│ ┌──────────▼────────────────▼──────────────────▼──────────┐ │
│ │ FHE Precompiles │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │
│ │ │ FHE (0x80) │ │ ACL (0x81) │ │ Gateway (0x83) │ │ │
│ │ │ Operations │ │ Access Ctrl │ │ Decryption │ │ │
│ │ └──────┬──────┘ └─────────────┘ └────────┬────────┘ │ │
│ └─────────┼───────────────────────────────────┼───────────┘ │
└────────────┼───────────────────────────────────┼───────────────┘
│ Warp Message │ Warp Message
▼ ▼
┌────────────────────────┐ ┌─────────────────────────────┐
│ Z-Chain (zkVM) │ │ T-Chain (Threshold) │
│ ┌──────────────────┐ │ │ ┌───────────────────────┐ │
│ │ FHE Processor │ │ │ │ Threshold Decryptor │ │
│ │ - CKKS Ops │ │ │ │ - 67-of-100 shares │ │
│ │ - Coprocessor │ │ │ │ - CKKS Multiparty │ │
│ │ - luxfi/lattice│ │ │ │ - Share Combiner │ │
│ └──────────────────┘ │ │ └───────────────────────┘ │
└────────────────────────┘ └─────────────────────────────┘
Precompile Addresses
| Precompile | Address | Purpose |
|---|---|---|
| FHE | 0x0200000000000000000000000000000000000080 |
Core FHE operations |
| ACL | 0x0200000000000000000000000000000000000081 |
Access control |
| InputVerifier | 0x0200000000000000000000000000000000000082 |
Input validation |
| FHEDecrypt | 0x0200000000000000000000000000000000000083 |
Threshold decryption via T-Chain |
Encrypted Types
| Type | Description | Solidity |
|---|---|---|
ebool |
Encrypted boolean | type ebool is bytes32 |
euint8 |
Encrypted 8-bit uint | type euint8 is bytes32 |
euint16 |
Encrypted 16-bit uint | type euint16 is bytes32 |
euint32 |
Encrypted 32-bit uint | type euint32 is bytes32 |
euint64 |
Encrypted 64-bit uint | type euint64 is bytes32 |
euint128 |
Encrypted 128-bit uint | type euint128 is bytes32 |
euint256 |
Encrypted 256-bit uint | type euint256 is bytes32 |
eaddress |
Encrypted address | type eaddress is bytes32 |
Operations
Arithmetic
add(a, b)- Additionsub(a, b)- Subtractionmul(a, b)- Multiplicationdiv(a, b)- Divisionrem(a, b)- Remainderneg(a)- Negation
Comparison
lt(a, b)- Less thanle(a, b)- Less than or equalgt(a, b)- Greater thange(a, b)- Greater than or equaleq(a, b)- Equalne(a, b)- Not equalmin(a, b)- Minimummax(a, b)- Maximum
Bitwise
and(a, b)- Bitwise ANDor(a, b)- Bitwise ORxor(a, b)- Bitwise XORnot(a)- Bitwise NOTshl(a, bits)- Shift leftshr(a, bits)- Shift right
Conditional
select(cond, ifTrue, ifFalse)- Conditional select
Randomness
rand(type)- Generate encrypted random value
Gas Costs
| Operation | Gas Cost |
|---|---|
| Encryption | 50,000 |
| Add/Sub | 65,000 |
| Mul | 150,000 |
| Div/Rem | 500,000 |
| Comparison | 60,000 |
| Bitwise | 50,000 |
| Select | 100,000 |
| Random | 100,000 |
| Decrypt Request | 10,000 |
Usage Example
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {FHE, euint64, ebool} from "lux-standard/contracts/fhe/FHE.sol";
contract PrivateBalance {
mapping(address => euint64) private balances;
function deposit(uint64 amount) external {
euint64 encrypted = FHE.asEuint64(amount);
balances[msg.sender] = FHE.add(balances[msg.sender], encrypted);
FHE.allowThis(balances[msg.sender]);
}
function transfer(address to, uint64 amount) external {
euint64 encAmount = FHE.asEuint64(amount);
// Check sufficient balance (encrypted comparison)
ebool sufficient = FHE.ge(balances[msg.sender], encAmount);
// Conditional update (works on encrypted data)
balances[msg.sender] = FHE.select(
sufficient,
FHE.sub(balances[msg.sender], encAmount),
balances[msg.sender]
);
balances[to] = FHE.select(
sufficient,
FHE.add(balances[to], encAmount),
balances[to]
);
}
}
Decryption Flow
- Request: Contract calls
FHE.decrypt(value)orGateway.decrypt(handle, type) - Warp: Request sent to T-Chain via Warp messaging
- Threshold: 67-of-100 validators contribute decryption shares
- Combine: Shares combined to recover plaintext
- Fulfill: Result returned via
fulfill(requestId, result)callback - Poll/Callback: Contract retrieves result via
reveal(requestId)or receives callback
Files
module.go- Module registrationcontract.go- FHE precompile implementationacl.go- Access control implementation (in evm/precompile)gateway.go- Decryption gateway (in evm/precompile)IFHE.sol- Solidity interfaces
Related Components
luxfi/lattice- Pure Go CKKS implementationnode/vms/zkvm/fhe- Z-Chain FHE processornode/vms/thresholdvm- T-Chain threshold operationsstandard/contracts/fhe- Solidity FHE library
License
Copyright (C) 2019-2024, Lux Partners Limited. All rights reserved. See the file LICENSE for licensing terms.