zama_fhe
The public Dart API for the Zama Protocol (fhEVM) plus all the pure-Dart
protocol glue behind it. No Flutter, no native, no web dependency — the same code
runs on every platform; a crypto backend (zama_fhe_ffi native, or web JS
interop) just satisfies the FhevmBackend / KmsBackend interfaces.
It is a faithful, test-verified port of the client half of
@zama-fhe/relayer-sdk.
What's in here
| Area | Status | Notes |
|---|---|---|
High-level client (FhevmInstance) |
✅ | one object: createEncryptedInput, publicDecrypt, userDecrypt, lazy key fetch |
Encrypted-input builder (EncryptedInputBuilder) |
✅ | fluent .addBool/.add8..256/.addAddress → .encrypt() → {handles, inputProof} |
| User-decrypt orchestration | ✅ | keygen → EIP-712 → sign → relayer → threshold verify → decrypt, in one call |
Backend interfaces (FhevmBackend, KmsBackend) |
✅ | pluggable native/web crypto; FheInputValue, EncryptedPayload, DecryptedValue |
Network configs (FhevmNetworkConfig) |
✅ | Sepolia + mainnet addresses, chain ids, gateway ids, relayer URLs |
FHE type system (FheType) |
✅ | ebool, euint8..256, eaddress with on-chain type ids |
Ciphertext handle computation (FhevmHandle) |
✅ | client-side keccak derivation + exact 32-byte layout |
EIP-712 typed data (Eip712TypedData, KmsEip712) |
✅ | user / delegated / public decryption authorization |
Relayer client (RelayerClient) |
✅ | /keyurl, /input-proof, /public-decrypt, /user-decrypt — async POST/poll, Retry-After, typed errors. Accepted live by Sepolia. |
inputProof assembly + public-decrypt decode |
✅ | byte assembly; cleartext decode (ebool/eaddress/euintX) |
KMS threshold-signature verification (KmsResponseVerifier) |
✅ | recovers each response sig vs on-chain getKmsSigners() ≥ getThreshold() |
On-chain calls (ConfidentialContract) |
✅ | web3dart wrapper: maps handles→bytes32, encodes/sends {handle, inputProof}, reads state |
| keccak256 + hex utils | ✅ | Ethereum keccak (via pointycastle) |
| TFHE encryption + ZK proof | ⛔ native backend | heavy crypto; provided by zama_fhe_ffi (Rust FFI) / WASM backend |
| ML-KEM user-decryption unwrap | ⛔ native backend | the kms client crypto; provided by zama_fhe_ffi (KmsNativeBackend) |
Proven end-to-end on live Sepolia: encrypt → relayer accepts → on-chain
increment → public-decrypt (M1) and private threshold-verified user-decrypt
(M2). See ../../ROADMAP.md.
Verification
The handle computation is checked against the exact reference test vectors
shipped in @zama-fhe/relayer-sdk (input-proof-payload-*.json): real proven
ciphertext blobs and the handles the official SDK derived from them, across
multiple FHE types and multi-input proofs. The EIP-712 implementation is checked
against the canonical EIP-712 "Mail" domain-separator and signing-digest vectors.
dart pub get
dart test # 45 passing, incl. reference handle vectors + EIP-712 vectors
Example
The everyday path uses FhevmInstance (see the repo root README for the full
encrypt → on-chain → decrypt quickstart). The lower-level primitives are also
public when you need them:
import 'package:zama_fhe/zama_fhe.dart';
const net = FhevmNetworkConfig.sepolia;
// Compute handles client-side from a proven blob (never trust the relayer):
final handles = FhevmHandle.computeInputHandles(
ciphertextWithZkProof: provenBlob, // from the crypto backend
aclContractAddress: net.aclContractAddress,
chainId: BigInt.from(net.chainId),
encryptionBits: [32], // one euint32 input
);
// Build EIP-712 typed data for a private user decryption; hand `.toJson()`
// to a wallet for `eth_signTypedData_v4`:
final typedData = KmsEip712.fromNetwork(net).createUserDecrypt(
publicKey: ephemeralMlKemPublicKeyHex,
contractAddresses: [contractAddress],
startTimestamp: nowSeconds,
durationDays: 7,
);
License
BSD-3-Clause-Clear (matching the upstream Zama crates). Note: Zama's FHE methods are patented; commercial use requires Zama's patent license.
Libraries
- zama_fhe
- Pure-Dart client primitives for the Zama Protocol (fhEVM).