Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The fhEVM backend allows users to run their own L1 or coprocessor with fhEVM technology. It enables confidential smart contracts on the EVM using FHE.
Learn the basics of fhEVM backend, set it up, and make it run with ease.
Refer to the API and access additional resources for in-depth explanations while working with fhEVM.
Ask technical questions and discuss with the community. Our team of experts usually answers within 24 hours in working days.
Collaborate with us to advance the FHE spaces and drive innovation together.
We value your feedback! Take a 5-question developer survey to improve the fhEVM library and the documentation and help other developers use FHE.
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.
The Executor is configured via command line switches and environment variables, e.g.:
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
).
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.
This document is a guide listing detailed steps to integrate fhevm-backend
into go-ethereum or any other implementations that follow the same architecture.
This document is based on go-ethereum v1.13.5
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.
For fhEVM-native, to start the setup, you can use our demo repository. Note that, at the time of writing, the demo repository doesn't yet use the fhEVM-native model that is implemented here - instead, it uses the fhEVM-native implementation that uses precompiles (instead of symbolic execution) and FHE computation is done inside geth (as opposed to an external Executor we have here).
For fhEVM-coprocessor, please look at the coprocessor section of the getting started guide.
An fhEVM-native node consists of the following components:
full node/validator node
Executor service
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.
Following is an example of how to deploy initial contracts on the Ethereum Sepolia testnet. Deploying on Ethereum mainnet should be almost identical and should be possible by just changing the SEPOLIA_RPC_URL to ETHEREUM_MAINNET_RPC_URL and poiting to a correct RPC node.
node_modules/fhevm-core-contracts/addresses/.env.acl
for ACL address
node_modules/fhevm-core-contracts/addresses/.env.exec
for TFHEExecutor address
node_modules/fhevm-core-contracts/addresses/.env.kmsverifier
for KMSVerifier address
node_modules/fhevm-core-contracts/addresses/.env.inputverifier
for InputVerifier address
node_modules/fhevm-core-contracts/addresses/.env.fhegaslimit
for FHEGasLimit address
gateway/.env.gateway
for GatewayContract address.
3/ Launch and setup the Geth node, the Gateway service, setup the KMS, all these using previously precomputed addresses.
Important: Later after deployment, the GATEWAY_RELAYER
should also receive a LOT more funds than the other addresses since this is the account which will send tx one each decryption fulfilment. I would advise for eg 3
ETH for the FHEVM_DEPLOYER
account, 0.5
ETH for the GATEWAY_DEPLOYER
to be safe, and at least 10
ETH for the GATEWAY_RELAYER
at first (to be refilled later if its balance becomes low) to be on the safe side. Another advise is to check current gas price on Sepolia before deployment and avoiding periods where gas prices are spiking to huge values (>100 GWei), for eg by consulting
The funding of GATEWAY_RELAYER
account is the only part which is not strictly needed during deployment, and this account could be funded later, after all deployment steps will be completed.
Note that in previous example, we supposed deployment would happen on Sepolia, this is why we used the --network sepolia
flag. Note also the last 6 lines which are responsible to verify all contracts which have just been deployed on Sepolia, using the Etherscan API key, after waiting 2 minutes to make sure that the contracts bytecode were correctly propagated. This last command only makes sense if you plan to deploy on a network with Etherscan support, such as Sepolia or Ethereum mainnet.
Important: at this stage the openzeppelin-upgrades
plugin will write on disk an .openzeppelin/
folder with some files in it (for eg typically a sepolia.json
file if you deploy on Sepolia). It will be critical to keep this folder saved, to be able to do safe upgrades of smart contracts if needed some day. Similarly, you must also keep all the .env.XXX
files written inside both of node_modules/fhevm-core-contracts/addresses
and gateway/
directories saved, because those contains the proxy addresses which might also be needed during the upgrade process.
1/ After deployment, if you wish to launch some hardhat test on Sepolia, you first need to add a MNEMONIC
env variable inside your .env
file. You can generate this variable using foundry with this command: cast wallet new-mnemonic -w 15 -a 5
. Your new .env
file should then looks like this - please replace MNEMONIC
by your own value:
2/ The previous command will also show you the 5
addresses of accounts (alice, bob, carol, dave, eve) used inside the hardhat tests, that you will need to fund via the faucet. An alternative way to get the addresses of those accounts could be to simply run: npx hardhat accounts --network sepolia
, then the first 5 addresses logged will be those that need funding.
Important: Currently, for all tests, you just need to fund the first 3 accounts (alice, bob, carol), this could help you to avoid wasting gas. For the EncryptedERC20 ones in particular, you only need to fund the first 2 accounts (alice, bob). No need to actually fund all of the first 5 accounts, unless you want later to run more complex tests like the Confidential AMM, etc, which have not been updated for new Solidity API anyways, yet.
3/ Now you can run any hardhat test with the usual command. For instance, if you want to run the EncryptedERC20 related tests you can use: npx hardhat test test/encryptedERC20/* --network sepolia
. As another example, you could run the asynchronous decryption tests via: npx hardhat test test/gatewayDecrypt/* --network sepolia
.
1/ For upgrading the ACL contract, save the new implementation in a solidity file somewhere in your local fhevm
repo, then simply run this command:
In previous command, you should modify PRIVATE_KEY_FHEVM_DEPLOYER
with your own value, and replace examples/ACLUpgradedExample.sol:ACLUpgradedExample
with the path and the name of the new ACL implementation contract that you wish to use. The --verify-contract
is an optional flag, whish will add an Etherscan verification step after deployment of the new implementation, pausing 2 minutes between deployment and Etherscan verification.
You can use similar commands for any contracts that you wish to upgrade, just using any of the following tasks, to replace the task:upgradeACL
from previous upgrade command :
Important: Note that for the task:upgradeGatewayContract
you should use the PRIVATE_KEY_GATEWAY_DEPLOYER
as the private-key
value. Also, note that those upgrade scripts would only work if the updated implementations do not have a reintializer function, i.e if part of storage does not need to be reinitialized, which should be almost always the case. In the rare case where you need a reinitializer in the new implementation, the upgrade script should be customized according to the arguments needed for the reinitialization.
This document is based on go-ethereum v1.14.3
To start a local geth coprocessor full node, please have a look at: https://github.com/zama-ai/go-ethereum-coprocessor/blob/master/Dockerfile.devnode
This document is still work in progress. Above repositories serve as reference for now.
More detailed description of the architecture and FHE execution can be found in and .
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 directory of fhevm-engine
.
At the time of writing, the implementation is not yet implemented.
0/ Prerequisites: First, git clone fhevm
repo and checkout the , install dependencies with npm i
(node.js version should be at least 20
), then create a.env
file in root of the repo.
1/ Fill correct values in the .env
file by first copying the . Your .env
file should have the following format, while replacing the 2 private keys values PRIVATE_KEY_FHEVM_DEPLOYER
and PRIVATE_KEY_GATEWAY_DEPLOYER
with your own keys, and taking the KMS addresses to be aligned with what is used by KMS, as well as the ADDRESS_GATEWAY_RELAYER
relayer address to be aligned with the Gateway service, and the ADDRESS_COPROCESSOR
coprocessor account address to be aligned with the coprocessor service:
For the SEPOLIA_RPC_URL
env variable, you can either get one from a service provider for free like Infura, or use your own RPC URL if you are running a node yourself. For ETHERSCAN_API_KEY
it is needed to verify source code of smart contracts on Sepolia/mainnet Etherscan (if you deploy coprocessor on Sepolia or mainnet for instance) and you can get a free Etherscan API key from: .
Important : the PRIVATE_KEY_FHEVM_DEPLOYER
and PRIVATE_KEY_GATEWAY_DEPLOYER
are expected to have a nonce of 0
initially (i.e never sent any tx before with those) for the deployment scripts to succeed later. If you have installed, you can generate fresh Ethereum private key / address pairs locally with this command: cast wallet new
.
2/ Then run the precomputing contract addresses script -> this will write on disk the correct contract addresses needed to launch the modified Geth node (TFHEExecutor
address) and the Gateway service (GatewayContract
one) and the ACL
and KMSVerifier
addresses which would be needed to setup some values inside the ASC contract on KMS chain. The precomputed addresses for the core contracts are located inside:
This script is found exactly inside the :
4/ Use the faucet to give some funds to the FHEVM_DEPLOYER
address, and the and the GATEWAY_DEPLOYER
addresses. Note that you can compute the address corresponding to a private key, if you have installed, via this command: cast wallet address [PRIVATE_KEY]
.
.
5/ Finally, run the deployment script . This script is found exactly inside the :
This document is a guide listing detailed steps to integrate fhevm-backend
into or any other implementations that follow the same architecture. We use geth
and go-ethereum
interchangeably from now on.
The Go library that we integrate into geth is .
We also have changes to geth itself here .
To execute the actual FHE computation, a is needed.
A Coprocesor 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:
server that handles:
gRPC requests for computation from geth
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.
Please note that a Coprocessor geth full node is needed in order to execute blocks on the host blockchain and trigger FHE computation.
At the highest level, the system consists of two subsystems: an fhEVM-native blockchain or an fhEVM-coprocessor and a TKMS.
An fhEVM-native blockchain itself consists of a set of validator nodes with each one running an Executor. An executor is tasked with actual FHE computation, whereas the validator runs symbolic execution (see below). Persisted FHE ciphertexts in smart contracts are stored on-chain in fhEVM-native. Furthermore, note that all fhEVM-native validators must have an associated Executor, meaning that if an existing blockchain is used, validators must all be modified.
An fhEVM-coprocessor configuration consists unmodified host blockchain validators and an off-chain Coprocessor component that is responsible for FHE computation. FHE ciphertexts are stored in a local off-chain database and in a public off-chain Data Availability (DA) layer. Note that the Coprocessor itself requires a modified host blockchain full-node.
In some contexts it doesn't matter whether fhEVM-native or fhEVM-blockchain is used. In such cases, we could use the collective term fhEVM.
A Threshold Key Management System (TKMS) is a component that runs a blockchain as a communication layer for a threshold protocol to manage the secret FHE key and handle decryption and reencryption.
These two subsystems are not directly connected; instead, a component called a Gateway handles communication between them.
An fhEVM processes all transactions, including those involving operations on encrypted data types. Operations on encrypted data are executed symbolically, meaning that the actual FHE computation is not done - instead, only constraints on symbolic inputs (handles) are checked and the returned result is just a new handle. A handle can be seen as a pointer to a ciphertext, similar to an identifier. After the operations are executed symbolically, the Executor in fhEVM-native or the Coprocessor in fhEVM-coprocessor perform the actual FHE computation on the ciphertexts. If a result handle is stored in a smart contract, the corresponding result ciphertext is stored on-chain for fhEVM-native. For fhEVM-coprocessor, all ciphertexts are stored in a Coprocessor-local off-chain database and in a public off-chain Data Availability (DA) layer.
No fhEVM node (neither Executor nor Coprocessor) has access to the secret FHE key; instead, an fhEVM node has a public bootstrap key that allows it to perform computations on ciphertexts. The bootstrap key itself does not allow any fhEVM node to decrypt any ciphertexts (as the secret FHE key is managed by the TKMS).
The Gateway takes part in decryption and the reencryption, interacting with both the fhEVM and the TKMS.
A decryption can be requested from any smart contract. In this case, the Gateway acts as an oracle: the dApp calls the Gateway contract with the necessary materials for decryption. The Gateway contract will then emit an event that is monitored for by the Gateway service.
A user can directly request a reencryption through an HTTP call. In this case, the Gateway acts as a Web2 service: the user provides a public key for the reencryption, a signature, and the handle of the ciphertext to be reencrypted.
The Gateway sends transactions to the TKMS blockchain, which serves as the communication layer, to request the decryption or reencryption. When the TKMS responds with a TKMS blockchain event, the Gateway will transmit the decryption either through a Solidity callback function on-chain (on the fhEVM) or the reencryption by responding synchronously to the HTTP call from the user.
The Gateway is not a trusted party, meaning that a malicious Gateway will not be able to compromise correctness or privacy of the system. At most, it would be able to ignore requests between the fhEVM and the TKMS, impacting the liveness of decryption and reencryption. However, that can be prevented by deploying multiple Gateways and assuming at least one is honest.
The TKMS is a full key management solution for TFHE, more specifically TFHE-rs, based on a maliciously secure and robust MPC Protocol. It leverages a blockchain as its communication layer and utilizes a threshold protocol to manage decryption and reencryption requests securely. When a decryption or reencryption is requested, the TKMS processes the request using its cryptographic mechanisms, ensuring that no single entity has access to the full decryption (FHE secret) key. Instead, the decryption or reencryption is carried out in a distributed manner, which enhances security by minimizing the risk of key exposure.
The fhEVM employs symbolic execution - essentially, inputs to FHE operations are symbolic values (also called handles) that refer to ciphertexts. We check constraints on these handles, but ignore their actual values.
Inside the Executor (in fhEVM-native) and inside the Coprocessor, we actually execute the FHE operations on the ciphertexts the handles refer to. If a new ciphertext is generated as a result of an FHE operation, it is inserted into the blockchain for fhEVM-native (into the ciphertext storage contract, see Storage) or into the DB and DA for Coprocessor under a handle that is deterministically generated by the TFHEExecutor contract.
Note: All those contracts are initially deployed behind UUPS proxies, so could be upgraded by their owner at any time. Unless if the owner renounces ownership, after which the protocol could be considered imumutable.
Symbolic execution on the blockchain is implemented via the TFHEExecutor contract. One of its main responsibilites is to deterministically generate ciphertext handles. For this, we hash the FHE operation requested and the inputs to produce the result handle H:
Inputs can either be other handles or plaintext values.
The ACL contract enforces access control for ciphertexts. The model we adopt is very simple - a ciphertext is either allowed for an address or not. An address can be any address - either an EOA address or a contract address. Essentially, it is a mapping from handle to a set of addresses that are allowed to use the handle.
Access control applies to transfering ciphertexts from one contract to another, for FHE computation on ciphertexts, for decryption and for reencryption of a ciphertext to a user-provided key.
Data in the ACL contract grows indefinitely as new ciphertexts are produced. We might want to expose ways for developers to reclaim space by marking that certain ciphertexts are no longer needed and, consequently, zeroing the slot in the ACL. A future effort will look into that.
The KMSVerifier contract allows any dApp to verify a received decryption. This contract exposes a function verifyDecryptionEIP712KMSSignatures
which receives the decryption result and signatures coming from the TKMS.
KMS signers addresses are stored and updated in the contract.
The KMSVerifier contract is also responsible for checking the signatures of KMS signers when a user is inputing a new ciphertext, since this process involves the user firstly sending a ZKPoK to be verified by the KMS nodes. If the proof verifies successfully at the KMS, each KMS signer will sign a hash of the new user input and the signatures will be returned to the user, who will then be able to input new handles onchain. This is done via the verifyInputEIP712KMSSignatures
function.
The InputVerifier checks the coprocessors accounts' signatures which include the computed handles (the KMS signatures only include the hash of the packed ciphertext, not the handles). We trust the handles computation done by the coprocessors before using them in transactions onchain.
This contract is needed for security, especially for coprocessor where we could not tweak native gas to be used for FHE operations as for native: FHE gas price constants.
This contract tracks the FHEGas consumed in each block, and reverts the transactions inside a block if the FHEGas block limit is exceeded.
The DecryptionOracle is an onchain contract designed to interact with an offchain Gateway component that handles decryption requests. When a dApp calls the requestDecryption
function, the DecryptionOracle
contract emits an event that is caught by the Gateway service.
Note: It is possible to have multiple Gateways, so multiple Gateway contracts can also be deployed. This is the only contract from this documentation page that is not strictly part of "core fhEVM" contracts, and as such, it should not be considered as a "trusted" contract. We only trust the KMS and the core fhEVM contracts. The Gateway is only bridging trust from host chain to KMS chain via storage proofs, and from KMS chain to the host chain via the signatures from KMS signers.
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.
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.
Docker 26+ installed on your system.
fhEVM validator running and configured.
TKMS running and configured.
Zama Gateway requires several specific configurations as shown in the provided docker-compose-gateway.yml
file.
Run the Zama Gateway Docker Compose:
To obtain the Key ID
for the GATEWAY__KMS__KEY_ID
environment variable, run the following command:
The following diagram shows an fhEVM-native blockchain with 4 validators.
Note: For brevity, we don't show P2P connections between validators and the full node in the diagram.
Each validator has two components:
the validator node software that executes blocks and connects to other validators over the blockchain's P2P network
the Executor that is responsible for the actual FHE computation
The Executor exposes an API that the validator node uses to send FHE computation requests.
A full node is similar to validators in the sense that it executes all blocks. The difference is that the full node doesn't have stake in the network and, therefore, cannot propose blocks. The full node has all the blockchain data locally. It can be used by the Gateway over RPC or WebSocket endpoints, allowing the Gateway to fetch storage proofs, fetch ciphertexts, listen for events on the fhEVM blockchain, etc.
The Gateway is a client from the TKMS' perspective and sends decryption/reencryption transactions, listens for "decryption ready" events, etc.
A dApp uses the fhevmjs library to interact with the fhEVM. Some examples are:
connect over HTTP to the Gateway for reencryptions
encrypt and decrypt data from the blockchain
send transactions via a full node
get the FHE public key from a full node
Symbolic execution is a method of constructing a computational graph of FHE operations without actually doing the FHE computation. It works by utilizing what we call a ciphertext handle. The handle could be thought of as an unique "pointer" to a given FHE ciphertext.and is implemented as a 32-byte value that is a result of applying a hash function to either an FHE ciphertext or other handles. Symbolic execution also checks constraints on input handles (e.g. the access control list, whether types match, etc.).
Inputs can either be other handles or plaintext values.
Note that fhEVM-native and fhEVM-coprocessor send both input handles and result handles for FHE computation. It is able to do that, because result handles are computed symbolically in the TFHEExecutor contract. That allows for parallel FHE computation by analysing which computations are independent.
The Executor or Coprocessor can detect a conflict if an output of computation A (or the output of another computation depending on the output of A) is also used as an input in a subsequent computation B. We call these computations dependent
and we need to execute them in order.
On the other hand, if two computations have inputs that are not related to their outputs, we call them independent
and can schedule them to run in parallel.
Some settings of the Coprocessor backend are configured by inserting entries in the PostgreSQL DB.
The tenants
table contains a list of tenants that are using the Coprocessor backend. A tenant could be thought of as a separate blockchain (or a separate FHE key, i.e. using multiple FHE keys on a blockchain). The fields in tenants
are:
You can use the --help
command line switch on the coprocessor to get a help screen as follows:
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
).
A secret signing key is needed to allow the Coprocessor backend sign input insertion requests. A coprocessor.key
file can be given on the command line for the server as:
The secret signing key must be kept safe when operating the Coprocessor.
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.
The TKMS is used to manage secret FHE key material and securely execute decryptions, reencryptions, key generation, etc. The TKMS is itself a blockchain. See .
Symbolic execution onchain is implemented via the contract. One of its main responsibilites is to deterministically generate ciphertext handles. For this, we hash the FHE operation requested and the inputs to produce the result handle H:
At the time of writing, we don't have a tool or automation for doing the configuration. The DB schema can be used as a reference, though: .
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
tenant_id
unique tenant identifier
tenant_api_key
an API key that authenticates access to the server
chain_id
the chain ID of the chain this tenant operates on
verifying_contract_address
address of the InputVerifier contract
acl_contract_address
address of the ACL contract
pks_key
a serialization of the FHE public key
sks_key
a serialization of the FHE server key
public_params
a serialization of the CRS public params
cks_key
optional secret FHE key, for debugging only
is_admin
if tenant is an administrator
Generating a new set of keys and crs is necessary when creating a new FHE Co-processor.
To do so one can use the TKMS cli tool packaged in the following docker image.
The configuration file of the CLI will need to be modified or mounted to a volume accessible within the Docker container. The accessible/modified file must include:
Insecure key generation is the fastest way to generate a new key. The key is generated by a single party and shared with the other parties. Hence it is not directly insecure, but instead only generated with a centralized trust assumption.
Secure key generation takes a lot longer and is a two step process. For development purposes insecure key generation is the recommended way since it is much faster.
This will do some pre-processing needed for key-generation. The pre-processing id will be needed to then launch a distributed key generation.
The CRS is a public object used to generate zero-knowledge-proofs of plaintext knowledge (required to add a new ciphertext). The max-num-bits
argument specifies the maximum number of bits provable with a given CRS, usually 2048 is used, since this is the size of the largest data-type currently supported.
As for the insecure key-generation this operation will be done by a single party.
This will launch a distributed CRS generation.
For an fhEVM-native blockchain to operate and execute FHE computations, certain contracts need to be available when creating the chain - see Contracts. Strictly speaking, these contracts don't have to be available in the genesis block and can be deployed in the second block of the chain, at runtime.
FHE-related keys need to available for the chain to operate properly. For example, a public FHE execution key is needed at the Executor to be able to compute on encrypted data.
As a convenience, the FHE public key can also be stored on validators/full nodes.
Ciphertexts in fhEVM-native are stored onchain in the storage of a predefined contract that has no code and is used just for ciphertexts. At the time of writing, its address is 0x5e.
Contract storage in the EVM is a key-value store. For ciphertexts, we use the handle as a key and the value is the actual ciphertext.
Furthermore, stored ciphertexts are immutable, making ciphertext storage append-only.
Ciphertexts can be read by anyone. We expose the GetCiphertext
function on the FheLib
precompiled contract. Nodes/validators must support it.
The GetCiphertext
function returns a serialized TFHE ciphertext given:
the ebool/e(u)int value (also called a handle) for which the ciphertext is requested
GetCiphertext only works via the eth_call
RPC.
To call GetCiphertext via eth_call
, the following Python can serve as an example:
The execution layer in fhEVM can perform computations on ciphertexts. At some point, it becomes necessary to reveal the actual values of these ciphertexts. However, the private key is managed by the KMS (Key Management System). The question arises: how can we perform asynchronous decryption requests (which make the values public) and re-encryptions (for personal information) when the execution layer and the KMS are decoupled? This is where inclusion proofs come into play.
This section will be elaborated upon in the future to explain the validation of root hash integrity.
Block execution in fhEVM-native is split into two parts:
Symbolic Execution
FHE Computation
Symbolic execution happens onchain, inside the TFHEExecutor contract (inside the EVM). Essentially, the EVM accumulates all requested FHE operations in a block with their input handles and the corresponding result handles. It also remembers which result handles are stored via the SSTORE opcode. No FHE computations are done inside the EVM itself.
For more on symbolic execution, please see Symbolic Execution.
At the end of the block, the EVM sends a networking call to the Executor with the accumulated FHE computations. The Executor is free to do the FHE computations via any method, e.g. in parallel, on a cluster of compute nodes, via CPUs, GPUs, FPGAs or ASICs. The EVM waits until FHE computation for the block is done.
Finally, when results are returned to the EVM, it persists onchain the ciphertexts whose handles have been SSTOREd during symbolic execution. That way the EVM can avoid persisting ciphertexts that are intermediate results and are never actually stored by the smart contract developer.
The TFHEExecutor contract is deployed when the chain is created and is at a well-known address that is also known by blockchain nodes. When a node (validator or full node) detects a call to this address (a CALL or STATICCALL opcode), the EVM running in the node looks at the function signature and determines which FHE computation is being requested. The result handle is the result of this particular call to the TFHEExecutor contract and the EVM can accumulate it in the computations list for the block.
Since the Executor can extract data dependencies from the SyncCompute
request, it can use them to execute FHE computations in parallel.
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.
When we talk about inputs, we refer to encrypted data users send to an fhEVM-native blockchain or an fhEVM-coprocessor. Data is in the form of FHE ciphertexts. An example would be the amount to be transferred when calling an ERC20 transfer function.
It is important that confidential data sent by users cannot be seen by anyone. Without measures, there are multiple ways that could happen, for example:
anyone decrypting the ciphertext
anyone doing arbitrary computations via the ciphertext (e.g. adding 0 to it), producing a new ciphertext that itself is decrypted (including malicious actors using ciphertexts of other users)
using the ciphertext in a malicious contract that leads to decryption
Furthermore, if users are allowed to send arbitrary ciphertexts (including malformed ones or maliciously-crafted ones), that could lead to revealing data about the FHE secret key.
Therefore, we employ zero-knowledge proofs of knowledge (ZKPoK) of input FHE ciphertexts that guarantee:
ciphertext is well-formed (i.e. encryption has been done correctly)
the user knows the plaintext value
the input ciphertext can only be used in a particular smart contract
The ZKPoK is verified by the KMS which delivers a signature (KMS_S) to the user. When the input byte array is passed to an TFHE.asEuintXX()
function to convert from a ciphertext to a handle that can be used in smart contracts for FHE operations, the KMS_S is verified.
To greatly reduce the size of FHE ciphertexts inputs, we utilize a feature called compact lists. It allows us to pack multiple values efficiently. It is useful when there is only one input and even more so when the are multiple inputs in a call to a smart contract.
We define the einput
type that refers to a particular ciphertext in the list. The list itself is serialized and passed as a byte array. For example, inputA
and inputB
refer to ciphertexts in the list and the serialized list is inputProof
:
Note that inputProof
also contains the ZKPoK.
Handling inputs requires a few steps. The first one is for the user to retrieve public key material from the Gateway. The second is to encrypt plaintext inputs and compute the associated ZKPoK. Last step is to use inputs as "usual" inputs in a smart contract.
The first step to generate an encrypted input is to retrieve the blockchain related FHE public key material. The Gateway is the component the user queries to get that material.
The Gateway is exposing a /keys
endpoint that returns the FHE public key and CRS alongside a signature. Users are able to verify them using KMSVerifier smart contract.
In this phase, the user encrypts the plaintext input with the FHE public key to get ciphertext C
and compute the proof ZkPoK
. C
is bounded to be used with a contractAddress
and by a callerAddress
. The goal is for C
to be signed the KMS to enable the usage of the input within smart contracts later.
C == ciphertext - Encrypted with the blockchain FHE public key
ZKPoK == Zero-Knowledge Proof of Knowledvge - Computed on the user side
eInput == type + index
S == Signature
When the user receives the KMS signature, it means that the ZKPoK has been verified by the KMS and the input could be used within fhEVM. This is quite useful because on the fhEVM only the KMS signature will be verified and that is faster than verifying a ZkPoK.
Block execution in fhEVM-coprocessor is split into two parts:
Symbolic Execution (onchain)
FHE Computation (offchain)
Symbolic execution happens onchain, inside the TFHEExecutor contract (inside the EVM). Essentially, the EVM accumulates all requested FHE operations in a block with their input handles and the corresponding result handles. Then, at the end of block execution, it sends an AsyncCompute
request to the coprocessor such that FHE computation can be done eventually. Note that FHE computation can be done at a future point in time, after the block has been committed on the host blockchain. We can do that, symbolic execution only needs handles and doesn't actual FHE ciphertexts. Actual FHE ciphertexts are needed only on decryption and reencryption, i.e. when a user wants to see the plaintext value.
For more on symbolic execution, please see Symbolic Execution.
Note that, for now, we omit the Data Availability (DA) layer. It is still work in progress and the Coprocessor only inserts FHE ciphertexts into its local DB. Eventually, we would like that FHE ciphertexts are also inserted into the DA.
Since the Coprocessor can extract data dependencies from the AsyncCompute
request, it can use them to execute FHE computations in parallel.
At the time of writing, the Coprocessor uses a simple policy to schedule FHE computation on multiple threads. More optimal policies will be introduced in the future and made configurable.
Everything in fhEVM is encrypted, at some point one could need to decrypt somes values. Let's give as illustration a blind auction application. After reaching the end of the auction, one need to discover (only) the winner, here is where a asynchronous decrypt could appear.
The Gateway acts as an oracle service: it will listen to decryption request events and return the decrypted value through a callback function. The responsabilities of the Gateway are:
Listening decryption request from fhEVM that contains a handle h
that corresponds to a ciphertext C
Computing a storage proof P
to attest h (i.e. C) is decryptable
Retrieve C from fhEVM using h
as key
Send a decyption request to TKMS which in turn is running an internal blockchain aka KMS BC
Wait and listen for decyptionResponse
(containing the plaitext and a few signatures from KMS to attest the integrity of the palintext) event from KMS BC
Return decyptionResponse
through the callback function
We allow explicit decryption requests for any encrypted type. The values are decrypted with the network private key.
The blockchain handles all decryption, reencryption, and key management operations between all fhEVM chains, co-processors etc. and the KMS engine.
ISC (Inclusion proof Smart Contract): Smart contract which handles validation of decryption/re-encryption requests for a specific fhEVM. Thus is contains custom logic for validation for a single fhEVM.
ASC (Application Smart Contract): A single smart contract to which transaction from the gateway (connector) are submitted to for all fhEVM's. All requests will pass through this contract and decryption and re-encryption requests will be validated by the appropriate ISC contract.
All operations must be paid for with tokens. Currently the tokenomics is not implemented and hence tokens can be constructed freely using a focet.
The KMS blockchain is deployed using n
servers where n
is the number of MPC parties. Each run their own validator docker image but is depoyed on the same machine as each of the MPC parties.
The dApp retrieves the ciphertext from the view function (e.g., balanceOf).
The dApp generates a keypair for the user and requests the user to sign the public key.
The dApp calls the gateway, providing the ciphertext, public key, user address, contract address, and the user's signature.
The dApp decrypts the received value with the private key.
The KMS system consists of a frontend, backend and temporary storage components. One big usage-case of the KMS system is to facilitate key generation and decryption for one or more fhEVMs.
We now briefly outline each of these components along with their constituents:
fhEVM validator: The validator node running the fhEVM blockchain.
Gateway: Untrusted service that listens for decryption events on the fhEVM blockchain and propagates these as decryption requests to the KMS, and propagates decryption results back to the fhEVM blockchain. Used in a similar fashion to handle reencryption requests from a user.
Gateway KMS Connector: A simple translation service that offers a gRPC interface for the gateway to communicate with the KMS blockchain. Calls from the gateway are submitted as transactions to the KMS blockchain, and result events from the KMS blockchain are returned to the gateway.
KV-store: A simple storage service that temporarily holds the actual FHE ciphertexts on behalf of the KMS blockchain (which instead stores a hash digest of the ciphertext).
KMS Validator: The validator node running the KMS blockchain.
KMS Connector: A simple translation service that listens for request events from the KMS blockchain and turn these into gRPC calls to the KMS Core. Likewise, results from the KMS Core are submitted as transactions back to the KMS blockchain.
KMS Core: Trusted gRPC service that implements the actual cryptographic operations such as decryption and reencryption. All results are signed.
KMS Engine: The actual computational engine carrying out the FHE cryptographic key operations in a Nitro enclave
S3: Public S3 instance storing the public keys for the FHE schemes for easy access.
The Frontend consists of the KMS blockchain. More specifically through an ASC contract. Each of which is unique for each application (e.g. each layer 1 blockchain).
The frontend makes up the public interface of the KMS, through which all requests are going. It consists of the KMS blockchain together with a collection of smart contracts. This gives it several desirable properties:
Decentralized enforcement of policies.
Trustable audit log of all actions performed by the KMS.
Support for payments of the operators.
Total ordering of requests (which is useful for some backends).
It consists of the following components:
Smart contracts: ISC, ASC and Config SC.
Responsible for receiving, validating and processing requests and updates from the fhEVM. Including decryption, reencryption, validator updates, key generation and setup.
KMS validators (realized through CometBFT).
The entities realizing the KMS blockchain. There may, or may not, be a 1-1 mapping between each validator and a threshold party in the KMS backend.
Multiple ISCs are deployed on the blockchain, typically one for each application (e.g. fhEVM blockchain) or application type (e.g. EVM blockchain). Each of these can keep application-specific state in order to verify requests from the application. For instance, an ISC for an fhEVM blockchain holds the identity of the current set of validators, so that access controls lists (ACLs) in decryption and reencryption requests can be validated by checking state inclusion proofs against the state roof of the fhEVM blockchain.
All decryption and reencryption requests are submitted as transactions to an ASC. The ASC performs universal validation and forwards ACL validation to the appropriate ISC. If all validations are ok then the ASC calls the backend by emitting an event that will trigger the backend to actually fulfill the request. Once the request has been fulfilled, the backend submits a fulfillment transaction back to the ASC.
All payments to the KMS is also handled through the ASC to which the transaction is submitted. These payments are used to incentivize the KMS operators.
Note that the KMS blockchain may be operated by a single validator if decentralization is not needed, or either in a permissioned or permissionless fashion for the decentralized setting.
The backend consists of the KMS core. It is the most security critical component of the entire system and a compromise of this could lead to breakage of both correctness, confidentiality and robustness. Because of this we have designed it to support threshold security and Enclave support, along with isolation of the security critical Engine from the general Internet.
The backend fulfills the requests as determined by the frontend. It comes in two flavors:
Each backend type is further described in their own document but each logical party in the backend (which will be 1 for the centralized case and n for the threshold case) generally consists of the following components:
Connector
A KMS blockchain client that supports both reading from and posting to the KMS blockchain. It is responsible for relaying information between the Coordinator and the KMS blockchain. Hence it connects the frontend and backend.
Coordinator
A gRPC server which is responsible for load-balancing. It relays each call to an appropriate Core.
A gRPC server which is responsible for managing the requests to the KMS. It relays the FHE-related aspects of requests onto a Core.
Core
The part of the system responsible for cryptographic tasks in relation to requests. This includes the FHE operations (which is handled by a sub-component called the Engine
), along with request validation and signcryption. Observe that the Engine
and Core
are not connected through a network, but that the Engine
code is simply imported and called from Core
.
More specifically the coordinator listens for events from the ASC (received through the Connector) and triggers the Core to fulfill operations. This means that the blockchain is the ground truth of which requests are processed, and each backend instance can independently authenticate these. The backend make use of a vault to keep and share sensitive material.
The design of the backend consisting of multiple components is done to make it possible to isolate the cryptographic Engine from the public Internet and make it completely agnostic to the fhEVM and even the KMS blockchain. It will simply only communicate with the Core Service and trust its requests blindly. However, this does not pose a security risk as the Core Service and Connector must be executed on the same machine and will only issue commands if signed and finalized by the KMS blockchain.
Each Core Service holds a signature key which is used to validate the authenticity of the operations which will eventually get passed back down to the fhEVM. More specifically this key is used to sign fulfillment transactions and fingerprints of public material.
The Core Service and Engine is also AWS-friendly, in the sense that it can take advantage of AWS Nitro and AWS KMS to offer additional security. However, they can also be operated in a "developer mode" where the use of AWS components is bypassed, and the sensitive material is simply kept in clear-text on disc. This mode is useful for developers to run a KMS on for instance their laptops.
A S3-compatible storage system can also be used to store the key material for easy public access. When used with Nitro private material can also be stored in signcrypted form, allowing easy rolling of servers since they can then be stateless.
In case of a horizontal scaling multiple Cores may be launched and managed by the Coordinator. I.e. the Coordinator will be responsible for load-balancing the requests between the Cores it control. This may be realized based on the underlying event, where the hash value of the event payload is used to determine which Core should process it. This means that the Coordinator only has relevance in the system when each party has multiple Cores. If there is only a single Core per party, then the Coordinator can be excluded from the system and requests from the Connector goes directly to the Core.
Each logical backend party also holds a signature key but may be shared between each Core in the case of horizontal scaling. This key is used to sign fulfillment transactions and fingerprints of public material.
Note that backends may choose to batch operations across request transactions in order to e.g. optimize the overall network load.
Note that two-way attestation should happen between the Coordinator and Core, along with the Coordinator and Connector to ensure e.g. that the Coordinator is not triggering other operations than those approved by the frontend.
Note that while the backend protects secret material, selective failure attacks may allow an adversary to extract secret keys by submitting malformed ciphertexts for decryption and reencryption. The KMS itself has no built in mechanism for protecting against this, so there is an implicit trust assumption that only well-formed ciphertexts are submitted to the KMS for decryption and reencryption. This in turn means that there is an implicit trust assumption that whoever produced the ciphertexts did so "honestly", which must be ensured externally (e.g. by the fhEVM).
Note also that the threshold assumption used by the threshold backend is not based on PoS but rather on a classic MPC threshold assumption that remains unjustified from an incentive point of view. Future work aims to address this.
All calls on the Coordinator, which are not just simple data retrieval, will be identified with a unique request_id
, even if a call is conceptually repeated. This request_id
will be used to uniquely identify the result of call, e.g. preprocessed material, a decrypted ciphertext, etc. More specifically from each call (posted on the blockchain in ASC
) the ASC
will derive a unique request_id
from the call and map this to a 160 bit hex encoded string. This specific approach to ID generation is used in order to ensure the IDs are human readable and recognizable for blockchain (Ethereum) developers.
The result of key generation and CRS generation will be two chunks of information: One which is large and can be stored insecure in any public medium (this will be the CRS and the different public keys), the other will be a structure containing handles, IDs and signatures, which be stored internally on the coordinator and on the KMS blockchain in ASC
. This information will be used to validate the keys/CRS' which a client can retrieve through an insecure connection from any public domain. More specifically the information will be a hash digest of the large element and a signature from the coordinator on this hash digest, along with the request_id
associated with the large element.
We require that it is possible for clients to uniquely derive a URI for the large material based on the small material (and any auxiliary information stored on the blockchain). The large data could for example be stored on IPFS, in which case the URI would be uniquely derived purely from the hash digest of the large element. Alternatively the large data could be stored on S3, a file-system or a webserver s.t. http://www.<some url>.com/keys/<requestID>/<key_type>.bin
.
The storage component is used to make available public material that is not suitable for storing in the frontend fulfillment transactions. This includes public FHE keys and CRSs. Instead, only URIs and signed fingerprints of this material is stored in the fulfillment transactions. The fingerprint is computed using a cryptographic hash function.
The storage component can be entirely untrusted from a security perspective, and comes in two flavors with different availability properties:
AWS S3 buckets.
The local file system.
The storage component is expected to have high availability, although all material stored therein can easily be replicated without security risk.
While the KMS protects secret material, selective failure attacks may allow an adversary to extract secret keys by submitting malformed ciphertexts for decryption and reencryption. The KMS itself has no built in mechanism for protecting against this, so there is an implicit trust assumption that only well-formed ciphertexts are submitted to the KMS for decryption and reencryption. This in turn means that there is an implicit trust assumption that whoever produced the ciphertexts did so "honestly", which must be ensured externally (e.g. by the fhEVM).
Note also that the threshold assumption used by the threshold backend is not based on PoS but rather on a classic MPC threshold assumption that remains unjustified from an incentive point of view. Future work aims to address this.
Decryption is public: It means everyone will be able to see the value. If this is a personal information see
The KMS blochhain is implemented using the Cosmos framework. More specifically with . This is a permissioned blockchain that is based on BFT consensus that allows for high throughput and low latency, but only supports a small number of validators (since consensus requires mutual interaction between all validator).
Reencryption is performed on the client side by calling the gateway service using the library. To do this, you need to provide a view function that returns the ciphertext to be reencrypted.
where sensitive material is kept in its typical form.
where sensitive material is secret shared
Secret material is protected by the KMS either through the use of secure enclaves or through threshold secret sharing (see ).
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.
The gateway can run on a medium machine with 4 cores and 8 GB of RAM, such as a t3.xlarge.
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.
The Key Management System (TKMS) is a self-contained service for performing sensitive cryptographic operations, including for a native fhEVM or a co-processor. It offers:
FHE key generation: Generate a fresh FHE keypair; the secret key is stored securely inside the KMS and the public key is made available for download. This generation also includes bootstrapping keys with a secret PRF seed for randomness generation.
FHE decryption: Decrypt a ciphertext encrypted under an FHE key known by the KMS and return the plaintext.
FHE reencryption: Decrypt a ciphertext encrypted under an FHE key known by the KMS and return the plaintext encrypted under a client supplied public key.
Public material download: Return URIs and signed fingerprints of the public material.
CRS generation: Generate a fresh CRS, and make it available for download.
One KMS instance can support multiple applications at the same time. This is implemented via per application or per application type smart contracts running in the KMS. These smart contracts are customizable to for instance implement application specific authorization logic (e.g. ACLs).
The KMS system is facilitated through a gateway service which is designed not to be required to be trusted, thus a malicious Gateway Service will not be able to compromise correctness or privacy of the system, but at most be able to block requests and responses between the fhEVM and the KMS. However, this can be prevented by simply deploying multiple Gateways Services.
Furthermore we observe that it is possible to implement payment to a Gateway service through the KMS blockchain, thus incentivizing such a service to be honest and reliable.
The Gateway Service consists of two different Connectors in order to decouple a specific fhEVM from a specific KMS. This will make it simpler to roll new blockchain protocols on either the fhEVM or KMS side without requiring modifications to the Gateway, but instead only require the writing of new Connectors.
Coprocessor: An off-chain component in fhEVM-native that does the actual FHE computation.
Executor: A component that runs alongside the fhEVM-native blockchain node/validator and does the FHE computation. The node/validator and the Executor communicate over a network connection.
FheLib: A precompiled contract on fhEVM-native that is available on nodes/validators. Exposes functions such as reading FHE ciphertexts from the on-chain storage in fhEVM-native, etc. At the time of writing, it exists at address 0x000000000000000000000000000000000000005d.
fhEVM-coprocessor: An fhEVM configuration where an off-chain Coprocessor component does the actual FHE computation. FHE ciphertexts are stored in an off-chain database local to the Coprocessor and in an off-chain public Data Availablility (DA) layer. No modifications the validator software of the existing chain is required (except for the full-node running for the Coprocessor).
fhEVM-native: An fhEVM configuration where each validator is paired with an Executor. FHE ciphertexts are stored on-chain. fhEVM-native requires modifications to the validator software of an existing chain.
fhevmjs: A JavaScript library that allows dApps to interact with the fhEVM.
handle: A handle refers to (or is a pointer to) a ciphertext in the fhEVM. A handle uniquely refers to a single ciphertext from the user's perspective.
KMS: Key Management Service. Used for managing secret FHE key material.
Symbolic Execution: Onchain execution where inputs to FHE operations are symbolic values (also called handles) that refer to ciphertexts. We check constraints on these handles, but ignore their actual values.
TFHE: An Fully Homomorphic Encryption scheme used in fhEVM and TKMS.
TKMS: Threshold Key Management Service. Uses threshold cryptography and multi-party computation. See KMS.
ZKPoK: Zero-knowledge proof of knowledge of an input FHE ciphertext.
ACL Smart Contract: Smart contract deployed on the fhEVM blockchain to manage access control of ciphertexts. dApp contracts use this to persists their own access rights and to delegate access to other contracts.
Gateway Smart Contract: Smart contract deployed on the fhEVM blockchain that is used by a dApp smart contract to request a decrypt. This emits an event that triggers the gateway.
KMS Smart Contract: Smart contract running on the fhEVM blockchain that is used by a dApp contract to verify decryption results from the TKMS. To that end, it contains the identity of the TKMS and is used to verify its signatures.
fhEVM ISC: Smart contract which contains all the custom logic needed to validate whether an operation such as decryption, is permitted on a given fhEVM chain. Specifically this involves inclusion proofs of an ACL. Note there is one ISC for each fhEVM.
fhEVM ASC: Smart contract to which transactions from the gateway (connector) are submitted to. This contract contains all logic required to work with any fhEVM blockchain. It handles any fhEVM chain-specific logic (such as ACL validation) by calling the ISC associated with the given fhEVM chain.
The following diagram shows an fhEVM-coprocessor that is integrated alongside an existing host blockchain.
An important note to point out is that the Coprocessor is an offchain component. It contains the following sub-components:
host blockchain full node that executes all blocks on the host blockchain
an executor that does FHE computation
a local database for storing FHE ciphertexts
Essentially, as the Coprocessor executes blocks and when an FHE operation is detected, the executor sub-component would actually execute the FHE computation and load/store FHE ciphertexts from the local database (and the DA). For more on execution, please look at Symbolic Execution and FHE Computation.
The Data Availability (DA) is a publicly-verifiable database that is a mirror of the local Coprocessor database. The reason for having is to allow anyone to verify the behaviour of the Coprocessor by examining the results it posts to it.
The Gateway is responsible for handling input verification, decryption and reencryption and host blockchain validator set updates, all via/in the KMS.
The threshold realization is part of the same binary as the KMS Core, but n
KMS Cores are running independently of each other, hosted by different companies. This means that in order to compromise the secret FHE key that is able to decrypt all ciphertexts, one would only need to compromise the key storage of at least t
KMS Cores administered by distinct companies on distinct servers. More specifically this may simply involve compromising more than t
local file-systems if Nitro is not used, more than t
Nitro enclaves.
Public and private key storage may be done on the local filesystem, or it may be outsourced to an S3 instance. Observe that there is a different strategy for the public, respectively the private key material. This is because the public key material is never loaded again after construction by the KMS Core, but is required to be easily accessible to other systems. On the other hand, the private key material is only used by the KMS Core and is never exposed to other systems. Furthermore, it is loaded into RAM during each booting of the KMS Core.
The cryptographic operations carried out by the threshold back=end are fulfilled by an MPC implementation of the necessary operations of the tfhe-rs library. The underlying MPC protocol is what is known as a statistically maliciously robust and proactively secure MPC protocol. Specifically this implies the following:
Statistically: the underlying protocols cannot be “broken” by an adversary regardless of the amount of computation power. This also means that they do not rely on any exotic cryptographic assumptions. (For practical reasons standard security of hash functions is still required.)
Maliciously Robust: the protocol can finish execution correctly with up to t
parties misbehaving by running rogue software or not participating.
Proactive: it is possible to "undo" a leakage of key material of at most t
parties byt refreshing their key shares. That is, if a few servers are compromised it is possible to make the stolen material 100% useless without the need to regenerate a new public key.
The MPC protocol is based on peer-reviewed cryptographic core protocols and peer reviewed modifications. For more modifications see this paper.
There are two ways to contribute to the Zama fhEVM:
Open issues to report bugs and typos, or to suggest new ideas
Request to become an official contributor by emailing hello@zama.ai.
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!