File: README.md
About
What is FHEVM?
FHEVM is the core framework of the Zama Confidential Blockchain Protocol. It enables confidential smart contracts on EVM-compatible blockchains by leveraging Fully Homomorphic Encryption (FHE), allowing encrypted data to be processed directly onchain.
FHEVM ensures both confidentiality and composability, with the following guarantees:
- End-to-end encryption of transactions and state: Data included in transactions is encrypted and never visible to anyone.
- Composability and data availability on-chain: States are updated while remaining encrypted at all times.
- No impact on existing dApps and state: Encrypted state co-exists alongside public one, and doesn't impact existing dApps.
Table of contents
Project structure
The directories of this repository are organized in the following way:
FHEVM Contracts
gateway-contracts/: Smart contracts managing the gateway between on-chain and off-chain components.host-contracts/: Smart Contracts deployed on the host chain for orchestrating FHE workflows.
FHEVM Compute Engines
coprocessor/: Rust-based coprocessor implementation for FHE operations.kms-connector/: Interface for integrating with Key Management Services (KMS) to handle encryption keys securely.
FHEVM Utilities
charts/: Helm charts and deployment configurations for the stack.golden-container-images/: Docker golden images for Node.js and Rust environments used as base images by the stack.test-suite/: Integration with docker-compose and tests covering end-to-end FHEVM stack behavior.
Main features
- Privacy by design: Building decentralized apps with full privacy and confidentiality on Ethereum, leveraging FHE.
- Solidity integration: Write FHEVM contracts like any standard Solidity contract using Solidity. Compatible with existing toolchains β such as Hardhat and Foundry (coming soon).
- Programmable privacy: Define exactly what data is encrypted and write the access control logic directly in your smart contracts.
- High precision encrypted integers : Up to 256 bits of precision for integers.
- Full range of operators: All typical operators are available:
+,-,*,/,<,>,==, ternary-if, boolean operationsβ¦. Consecutive FHE operations are not limited. - Security: The underlying FHE crypto-scheme of FHEVM is quantum-resistant. Decryption is managed via a key management system (KMS) using multi-party computation (MPC), ensuring security even if some parties are compromised or misbehaving.
- Symbolic execution of FHE computations: All FHE operations are executed symbolically on the host chain, significantly reducing execution time. The actual computations on encrypted data are offloaded asynchronously to our coprocessor, allowing for faster, efficient, and scalable processing.
Learn more about FHEVM features in the documentation and in our whitepaper.
Use cases
FHEVM is built for developers to write confidential smart contracts without the need to learn cryptography. Leveraging FHEVM, you can unlock a myriad of new use cases such as DeFi, gaming, and more. For instance:
- Confidential transfers: Keep balances and amounts private, without using mixers.
- Tokenization: Swap tokens and RWAs on-chain without others seeing the amounts.
- Blind auctions: Bid on items without revealing the amount or the winner.
- On-chain games: Keep moves, selections, cards, or items hidden until ready to reveal.
- Confidential voting: Prevents bribery and blackmailing by keeping votes private.
- Encrypted DIDs: Store identities on-chain and generate attestations without ZK.
Learn more use cases in the list of examples.
Resources
Documentation β Official documentation of FHEVM.
Whitepaper β Technical overview of FHEVM's cryptographic design.
Examples β Examples of building confidential smart contracts.
Awesome Zama β FHEVM β Curated articles, talks, and ecosystem projects.
Working with FHEVM
Citations
To cite FHEVM or the whitepaper in academic papers, please use the following entries:
@Misc{FHEVM,
title={{FHEVM: A full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications},
author={Zama},
year={2025},
note={\url{https://github.com/zama-ai/fhevm}},
}Contributing
There are two ways to contribute to FHEVM:
- Open issues to report bugs and typos, or to suggest new ideas
- Request to become an official contributor by emailing [email protected].
Becoming an approved contributor involves signing our Contributor License Agreement (CLA). Only approved contributors can send pull requests, so please make sure to get in touch before you do!
License
This software is distributed under the BSD-3-Clause-Clear license. Read this for more details.
FAQ
Is Zamaβs technology free to use?
Zamaβs libraries are free to use under the BSD 3-Clause Clear license only for development, research, prototyping, and experimentation purposes. However, for any commercial use of Zama's open source code, companies must purchase Zamaβs commercial patent license.
Everything we do is open source, and we are very transparent on what it means for our users, you can read more about how we monetize our open source products at Zama in this blog post.
What do I need to do if I want to use Zamaβs technology for commercial purposes?
To commercially use Zamaβs technology you need to be granted Zamaβs patent license. Please contact us at [email protected] for more information.
Do you file IP on your technology?
Yes, all Zamaβs technologies are patented.
Can you customize a solution for my specific use case?
We are open to collaborating and advancing the FHE space with our partners. If you have specific needs, please email us at [email protected].
Support
π If you find this project helpful or interesting, please consider giving it a star on GitHub! Your support helps to grow the community and motivates further development.
File: charts/kms-connector/README.md
kms-connector
A helm chart to distribute and deploy the Zama KMS Connector services.
Chart Details
This chart deploys the following components:
- kms-connector-db-migration: A Kubernetes Job to run database migrations.
- kms-connector-gw-listener: A service that listens for events from the gateway chain.
- kms-connector-kms-worker: A service that interacts with the KMS-Core.
- kms-connector-tx-sender: A service that sends transactions to the gateway chain.
- kms-connector-endpoint: A service that serves the HTTP decryption interface, reached through the proxy.
- kms-connector-proxy: A TLS-terminating proxy that authenticates the relayer with an API key and forwards requests to the endpoint.
The proxy needs two secrets that this chart does not create: a kubernetes.io/tls secret (kmsConnectorProxy.tls.secretName) with the certificate it serves, and a secret holding the SHA-256 digest of the relayer API key (kmsConnectorProxy.apiKeyDigest.secret, or apiKeyDigest.value inline). Its Service is a ClusterIP; exposing it outside the cluster (TLS passthrough, since the proxy terminates TLS itself) is left to the deployment.
Installing the Chart
To pull and install the OCI Helm chart from ghcr.io:
helm registry login ghcr.io/zama-ai/fhevm/charts
helm install kms-connector oci://ghcr.io/zama-ai/fhevm/charts/kms-connectorTo pull and install the OCI Helm chart from hub.zama.ai:
helm registry login hub.zama.ai
helm install kms oci://hub.zama.ai/zama-protocol/zama-ai/fhevm/charts/kms-connectorSmart contract addresses, chain IDs and host chains
Contract addresses, chain IDs and the set of deployed host chains are loaded
from a per-network preset bundled in configs/contracts-<network>.yaml,
selected via commonConfig.network (one of "", devnet, testnet,mainnet; an unrecognized value fails the render). Each preset provides:
gateway.{chainId,decryption,gatewayConfig,kmsGeneration}ethereum.protocolConfig(ProtocolConfig is only on Ethereum)hostChains.<name>.{chainId,aclAddress}for every host chain deployed on
that network.
Gateway and Ethereum-only values are overridden withcommonConfig.gatewayChainId,commonConfig.gatewayContractAddresses.*andcommonConfig.ethereumContractAddresses.*.
A non-empty override wins over the preset.
RPC URLs from secrets
RPC endpoints often embed an API key. Keep them out of the values file by
declaring the secret as an environment variable in commonConfig.env and
referencing it from the URL with the Kubernetes $(VAR) syntax, which the
kubelet expands at container start:
commonConfig:
env:
- name: ETHEREUM_RPC_URL
valueFrom:
secretKeyRef:
name: host-chain-rpc
key: ethereum-url
hostChains:
ethereum:
url: "$(ETHEREUM_RPC_URL)"Configuration
The following table lists the configurable parameters of the kms-connector chart and their default values.
| Parameter | Description | Default |
|---|---|---|
commonConfig.databaseUrl |
The database URL. | postgresql://$(DATABASE_ENDPOINT)/connector |
commonConfig.network |
Selects the bundled preset ("", devnet, testnet, mainnet): chain IDs, contract addresses and deployed host chains. |
"" |
commonConfig.gatewayUrl |
The gateway URL. | http://gateway-node:8546 |
commonConfig.gatewayChainId |
Gateway chain ID. Overrides the network preset when set. | "" |
commonConfig.gatewayContractAddresses |
Gateway contract addresses (decryption, gatewayConfig). Each overrides the preset when set. |
{} |
commonConfig.hostChains |
Host chains served by the connector, a map of <name>: {url, chainId, aclAddress}. Every chain deployed on network must have a url (may be $(VAR)); chainId/aclAddress override the preset when set. An ethereum entry is required. |
ethereum and polygon with empty URLs |
commonConfig.ethereumContractAddresses |
Ethereum-only contract addresses (kmsGeneration, protocolConfig). Each overrides the preset when set. |
{} |
commonConfig.tracing.enabled |
If true, enable tracing for all components. |
false |
commonConfig.tracing.endpoint |
The OpenTelemetry collector endpoint. | http://otel-deployment-opentelemetry-collector.observability.svc.cluster.local:4317 |
commonConfig.env |
Environment variables to be injected into all containers. | {} |
kmsConnectorDbMigration.enabled |
If true, run the database migration job. |
true |
kmsConnectorDbMigration.image.name |
The docker image name for the database migration job. | ghcr.io/zama-ai/fhevm/kms-connector/db-migration |
kmsConnectorDbMigration.image.tag |
The docker image tag for the database migration job. | v0.15.0 |
kmsConnectorGwListener.enabled |
If true, deploy the gateway listener. |
true |
kmsConnectorGwListener.image.name |
The docker imagename for the gateway listener. | ghcr.io/zama-ai/fhevm/kms-connector/gw-listener |
kmsConnectorGwListener.image.tag |
The docker image tag for the gateway listener. | v0.15.0 |
kmsConnectorGwListener.replicas |
The number of replicas for the gateway listener. | 1 |
kmsConnectorKmsWorker.enabled |
If true, deploy the KMS worker. |
true |
kmsConnectorKmsWorker.image.name |
The docker image name for the KMS worker. | ghcr.io/zama-ai/fhevm/kms-connector/kms-worker |
kmsConnectorKmsWorker.image.tag |
The docker image tag for the KMS worker. | v0.15.0 |
kmsConnectorKmsWorker.replicas |
The number of replicas for the KMS worker. | 1 |
kmsConnectorTxSender.enabled |
If true, deploy the transaction sender. |
true |
kmsConnectorTxSender.image.name |
The docker image name for the transaction sender. | ghcr.io/zama-ai/fhevm/kms-connector/tx-sender |
kmsConnectorTxSender.image.tag |
The docker image tag for the transaction sender. | v0.15.0 |
kmsConnectorTxSender.replicas |
The number of replicas for the transaction sender. | 1 |
kmsConnectorTxSender.awsKms.enabled |
Whether to enable the AWS KMS signer for the transaction sender. | false |
kmsConnectorTxSender.awsKms.configmap.name |
The name of the configmap containing the AWS KMS Key ID. | mpc-party |
kmsConnectorTxSender.awsKms.configmap.key |
The key in the configmap containing the AWS KMS Key ID. | KMS_CONNECTOR_AWS_KMS_CONFIG__KEY_ID |
kmsConnectorTxSender.wallet.secret.name |
The name of the secret containing the wallet. | kms-connector-tx-sender |
kmsConnectorTxSender.wallet.secret.key |
The key in the secret containing the wallet. | kms-wallet |
kmsConnectorEndpoint.enabled |
If true, deploy the endpoint. |
true |
kmsConnectorEndpoint.image.name |
The docker image name for the endpoint. | ghcr.io/zama-ai/fhevm/kms-connector/endpoint |
kmsConnectorEndpoint.image.tag |
The docker image tag for the endpoint. | v0.15.0 |
kmsConnectorEndpoint.replicas |
The number of replicas for the endpoint. | 1 |
kmsConnectorProxy.enabled |
If true, deploy the proxy (requires the endpoint). |
true |
kmsConnectorProxy.image.name |
The docker image name for the proxy. | ghcr.io/zama-ai/fhevm/kms-connector/proxy |
kmsConnectorProxy.image.tag |
The docker image tag for the proxy. | v0.15.0 |
kmsConnectorProxy.replicas |
The number of replicas for the proxy. | 1 |
kmsConnectorProxy.apiKeyDigest.value |
Inline SHA-256 digest of the relayer API key; read from the secret below when empty. | "" |
kmsConnectorProxy.apiKeyDigest.secret.name |
The name of the secret containing the API key digest. | kms-connector-proxy |
kmsConnectorProxy.apiKeyDigest.secret.key |
The key in the secret containing the API key digest. | api-key-digest |
kmsConnectorProxy.tls.secretName |
The kubernetes.io/tls secret served by the proxy. |
kms-connector-proxy-tls |
podAnnotations |
Annotations to be added to all pods. | {} |
podLabels |
Labels to be added to all pods. | {} |
File: coprocessor/docs/guides/hardware.md
Node and gateway hardware
FHEVM validator
Validators perform all operations on ciphertext, which requires powerful machines. FHE computations benefit from multi-threading, so we recommend using hpc7a instances or equivalent, with at least 48 physical cores.
Gateway
The gateway can run on a medium machine with 4 cores and 8 GB of RAM, such as a t3.xlarge.
TKMS
The TKMS needs to carry out heavy cryptographic operations on the ciphertexts. We recommend using at least a c5.4xlarge instance or equivalent, with at least 16 physical cores.
File: coprocessor/docs/getting_started/gateway/configuration.md
Configuration
The gateway acts as a bridge between the execution layer and the Threshold Key Management System (TKMS). Due to its central role, it needs to be properly configured. This document details all
the environment variables and gives an example of docker compose to run the gateway.
Dependencies
- Zama Gateway: Depends on FHEVM and Gateway KV Store, which is initialized with the Zama KMS Docker Compose command. Therefore, this is the last Docker Compose command that should be run.
Prerequisites
- Docker 26+ installed on your system.
- FHEVM validator running and configured.
- TKMS running and configured.
Configuring Docker Compose Environment Variables
Example Docker Compose for Zama Gateway
name: zama-gateway
services:
gateway:
image: ghcr.io/zama-ai/kms-blockchain-gateway-dev:latest
command:
- "gateway"
environment:
- GATEWAY__ETHEREUM__CHAIN_ID=9000
- GATEWAY__ETHEREUM__LISTENER_TYPE=FHEVM_V1_1
- GATEWAY__ETHEREUM__WSS_URL=ws://fhevm-validator:8546
- GATEWAY__ETHEREUM__HTTP_URL=http://fhevm-validator:8545
- GATEWAY__ETHEREUM__FHE_LIB_ADDRESS=000000000000000000000000000000000000005d
- GATEWAY__ETHEREUM__ORACLE_PREDEPLOY_ADDRESS=c8c9303Cd7F337fab769686B593B87DC3403E0ce
- GATEWAY__KMS__ADDRESS=http://kms-validator:9090
- GATEWAY__KMS__KEY_ID=408d8cbaa51dece7f782fe04ba0b1c1d017b1088
- GATEWAY__STORAGE__URL=http://gateway-store:8088
- ASC_CONN__BLOCKCHAIN__ADDRESSES=http://kms-validator:9090
- GATEWAY__ETHEREUM__RELAYER_KEY=7ec931411ad75a7c201469a385d6f18a325d4923f9f213bd882bbea87e160b67Zama Gateway requires several specific configurations as shown in the provided docker-compose-gateway.yml file.
| Variable | Description | Default Value |
|---|---|---|
| GATEWAY__ETHEREUM__CHAIN_ID | Chain ID for FHEVM | 9000 |
| GATEWAY__ETHEREUM__LISTENER_TYPE | Listener type for Ethereum gateway | FHEVM_V1_1 |
| GATEWAY__ETHEREUM__WSS_URL | WebSocket URL for FHEVM Ethereum. You need to run FHEVM first and set this data | ws://localhost:9090 |
| GATEWAY__ETHEREUM__FHE_LIB_ADDRESS | FHE library address for Ethereum gateway. This should be obtained from FHEVM once it is running and configured | 000000000000000000000000000000000000005d |
| GATEWAY__ETHEREUM__ORACLE_PREDEPLOY_ADDRESS | Oracle predeploy contract address for FHEVM gateway | c8c9303Cd7F337fab769686B593B87DC3403E0cd |
| GATEWAY__KMS__ADDRESS | Address for KMS gateway | http://localhost:9090 |
| GATEWAY__KMS__KEY_ID | Key ID for KMS gateway. Refer to the How to Obtain KMS Key ID section | 04a1aa8ba5e95fb4dc42e06add00b0c2ce3ea424 |
| GATEWAY__STORAGE__URL | URL for storage gateway | http://localhost:8088 |
| ASC_CONN__BLOCKCHAIN__ADDRESSES | Blockchain addresses for ASC connection. Same as GATEWAY__KMS__ADDRESS |
http://localhost:9090 |
| GATEWAY__ETHEREUM__RELAYER_KEY | Private key of the relayer | 7ec931411ad75a7c201469a385d6f18a325d4923f9f213bd882bbea87e160b67 |
Steps for Running
- Run the Zama Gateway Docker Compose:
docker compose -f docker-compose-gateway.yml up -d:warning: Requirement: At start, the Gateway will try to connect to the websocker URL
GATEWAY__ETHEREUM__WSS_URL. Ensure it is running and the port is opened.
KMS Key ID
To obtain the Key ID for the GATEWAY__KMS__KEY_ID environment variable, run the following command:
> docker run -ti ghcr.io/zama-ai/kms-service-dev:latest ls keys/PUB/PublicKey
04a1aa8ba5e95fb4dc42e06add00b0c2ce3ea424 8e917efb2fe00ebbe8f73b2ba2ed80e7e28970deFile: coprocessor/docs/getting_started/fhevm/native/configuration.md
Configuration
At the time of writing, FHEVM-native is still not fully implemented, namely the geth integration is not done. Configuration settings will be listed here when they are implemented.
Executor
The Executor is configured via command line switches and environment variables, e.g.:
executor --help
Usage: executor [OPTIONS]
Options:
--tokio-threads <TOKIO_THREADS> [default: 4]
--fhe-compute-threads <FHE_COMPUTE_THREADS> [default: 8]
--policy-fhe-compute-threads [default: 8]
--server-addr <SERVER_ADDR> [default: 127.0.0.1:50051]
-h, --help Print help
-V, --versionThreads
Note that there are three thread pools in the Executor:
- tokio
- FHE compute
- policy FHE compute
The tokio one (set via --tokio-threads) determines how many tokio threads are spawned. These threads are used for async tasks and should not be blocked.
The FHE compute threads are the ones that actually run the FHE computation by default (set via --fhe-compute-threads).
If an non-default scheduling policy is being used, the policy FHE compute threads are being used (set via --policy-fhe-compute-threads).
Scheduling Policies
Different scheduling policies can be set for FHE computation via the FHEVM_DF_SCHEDULE environment variable with possible choices: LOOP, FINE_GRAIN, MAX_PARALLELISM, MAX_LOCALITY.
File: coprocessor/docs/getting_started/fhevm/native/executor.md
Executor
An FHEVM-native node consists of the following components:
- full node/validator node
- Executor service
More detailed description of the architecture and FHE execution can be found in Architecture and FHE Computation.
The Executor service is a gRPC server that accepts FHE computation requests from the full node/validator node and executes them. It is implemented in the executor directory of fhevm-engine.
At the time of writing, the geth implementation is not yet implemented.
The Executor is almost fully functional. We don't yet provide Docker images for it, but it can be built as a normal Rust project.
File: coprocessor/docs/getting_started/fhevm/native/geth.md
Integration
This document is a guide listing detailed steps to integrate FHEVM-backend into go-ethereum or any other implementations that follow the same architecture.
{% hint style="info" %}
This document is based on go-ethereum v1.13.5
{% endhint %}
An FHEVM-native node consists of the following components:
- full node/validator node
- Executor service
At the time of writing, the geth full node/validator node is not yet implemented. The Executor is almost fully functional.
File: coprocessor/docs/getting_started/fhevm/coprocessor/configuration.md
Configuration
Coprocessor Backend
Command Line
You can use the --help command line switch on the coprocessor to get a help screen as follows:
coprocessor --help
Usage: coprocessor [OPTIONS]
Options:
--run-bg-worker
Run the background worker
--generate-fhe-keys
Generate fhe keys and exit
--work-items-batch-size <WORK_ITEMS_BATCH_SIZE>
Work items batch size [default: 10]
--tenant-key-cache-size <TENANT_KEY_CACHE_SIZE>
Tenant key cache size [default: 32]
--coprocessor-fhe-threads <COPROCESSOR_FHE_THREADS>
Coprocessor FHE processing threads [default: 8]
--tokio-threads <TOKIO_THREADS>
Tokio Async IO threads [default: 4]
--pg-pool-max-connections
Postgres pool max connections [default: 10]
--metrics-addr <METRICS_ADDR>
Prometheus metrics server address [default: 0.0.0.0:9100]
--database-url <DATABASE_URL>
Postgres database url. If unspecified DATABASE_URL environment variable is used
--service-name <SERVICE_NAME>
Coprocessor service name in OTLP traces [default: coprocessor]
-h, --help
Print help
-V, --version
Print versionThreads
Note that there are two thread pools in the Coprocessor backend:
- tokio
- FHE compute
The tokio one (set via --tokio-threads) determines how many tokio threads are spawned. These threads are used for async tasks and should not be blocked.
The FHE compute threads are the ones that actually run the FHE computation (set via --coprocessor-fhe-threads).
RDS IAM Authentication
When using AWS RDS/PostgreSQL IAM database authentication, DATABASE_URL should not contain a
password. Use a URL such aspostgresql://[email protected]:5432/coprocessor and
set DATABASE_IAM_AUTH_ENABLED=true. The runtime will fetch AWS credentials from the default
provider chain, generate 15-minute IAM tokens automatically, and refresh pooled connections before
they expire. Set DATABASE_IAM_REGION and DATABASE_SSL_ROOT_CERT_PATH as well: the former pins
token signing to the correct AWS region, and the latter is required for verify-full TLS against
the RDS endpoint.
File: coprocessor/docs/getting_started/fhevm/coprocessor/coprocessor_backend.md
Coprocessor Backend
A Coprocessor backend is needed to run alongside the geth node. The Coprocessor backend executes the actual FHE computation. Please look at FHE Computation for more info.
The coprocessor backend is implemented in the Coprocessor directory of fhevm-engine.
It consists of the following components:
- listeners that propagate events to the DB and Gateway,
- server that handles:
- input insertion requests to the DB from the Gateway
- FHE ciphertext read requests from the Gateway
- PostgreSQL DB for storing computation requests and FHE ciphertexts
- worker that reads comoutation requests from the DB, does the FHE computation and inserts result FHE ciphertexts into the DB
The server and the worker can be run as separate processes or as a single process. In both cases they communicate with one another through the DB.
The Coprocessor backend supports multi-tenancy in the sense that it can perform FHE computation for separate host blockchains, under different FHE keys.
You can use pre-generated Docker images for the Coprocessor backend node or build them yourself as described in the README.