Skip to content

Commit

Permalink
Merge pull request #62 from zama-ai/clearerContractsDocs
Browse files Browse the repository at this point in the history
chore: updates deployment docs
  • Loading branch information
jatZama authored Oct 9, 2024
2 parents 0c28ad5 + 76f4c3c commit c006e66
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 20 deletions.
Binary file added docs/assets/fhEVMContracts.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 33 additions & 11 deletions docs/fundamentals/fhevm/contracts.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
# Contracts
# Diagram - fhEVM contracts on the host chain

![fhEVM Contracts](../../assets/fhEVMContracts.png)

# Contracts fundamentals

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.

On the Executor, we actually execute the FHE operations on the ciphertexts the handles refer to. If a new ciphertext is generated in the Executor as a result of an FHE operation, it is inserted into the blockchain (into the ciphertext storage contract, see [Storage](storage.md)) under a handle that is deterministically generated in the TFHEExecutor contract.
On the Executor, we actually execute the FHE operations on the ciphertexts the handles refer to. If a new ciphertext is generated in the Executor as a result of an FHE operation, it is inserted into the blockchain (into the ciphertext storage contract, see [Storage](storage.md)) 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.

## TFHEExecutor Contract

Expand All @@ -14,26 +20,42 @@ H = keccak256(fheOperation, input1, input2, ..., inputN)

Inputs can either be other handles or plaintext values.

_Note:_ As of now, TFHEExecutor emloys precompiles and not symbolic execution. It will soon be migrated to symbolic execution.

## ACL Contract

The [ACL](https://github.com/zama-ai/fhevm/blob/main/lib/ACL.sol) 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 passing ciphertexts from one contract to another, for FHE computation on ciphertexts, for decryption and for reencryption of a ciphertext to a user-provided key.
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.

### Garbage Collection of Allowed Ciphertexts Data

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.

## Gateway Contract
## KMSVerifier Contract

The [Gateway](https://github.com/zama-ai/fhevm/blob/main/gateway/GatewayContract.sol) contract is an onchain contract designed to interact with an offchain Gateway component that handles decryption requests. When a dApp calls the `requestDecryption` function, the Gateway contract emits an event that is caught by the Gateway service.
The [KMSVerifier](https://github.com/zama-ai/fhevm/blob/main/lib/KMSVerifier.sol) 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.

_Note_: It is possible to have multiple Gateways, so multiple Gateway contracts can also be deployed.
KMS signers addresses are stored and updated in the contract.

## KMSVerifier 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 first the user to send a ZKPOK to be checked by the KMS nodes. If the proof is checked by 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.

## InputVerifier Contract

This is the only contract which implementation differs between coprocessor and native. For coprocessor, we use [InputVerifier.coprocessor.sol](https://github.com/zama-ai/fhevm/blob/main/lib/InputVerifier.coprocessor.sol), while for native we use [InputVerifier.native.sol](https://github.com/zama-ai/fhevm/blob/main/lib/InputVerifier.native.sol).

The [KMSVerifier](https://github.com/zama-ai/fhevm/blob/main/lib/KMSVerifier.sol) contract allows any dApp to verify a received decryption. This contract exposes a function `verifySignatures` which receives the decryption and signatures coming from the TKMS.
The native InputVerifier contract just forwards the user input handles with the kms signers' signatures from TFHEExecutor (when the verifyCiphertext function is called, to insert user inputs) to the KMSVerifier contract, by calling its `verifyInputEIP712KMSSignatures` function.

The coprocessor version of InputVerifier also forwards the kms signers' signatures from TFHEExecutor to KMSVerifier, but in addition, the InputVerifier contract in this case also checks the coprocessor's account signature which includes the computed handles (the KMS signatures only include the hash of the packed ciphertext, not the handles). This additional check is done via the `verifyEIP712Copro` function.

In native case, the handles are computed onchain, on the other hand for coprocessor, we trust the handles computation done by the coprocessor service beforehand.

## FHEPayment Contract

This contract could be used in theory to handle payments of users for FHE operations, but in current version we decided to set the FHE gas price to `0`, to make developer's experience simpler on Sepolia. We could simply change those two constants to positive values at a later stage, if we want to introduce real payments: [FHE gas price constants](https://github.com/zama-ai/fhevm/blob/main/lib/FHEPayment.sol#L33-L34).

However, even with null FHE gas price, we still need to deploy this contract for security, especially for coprocessor (where we could not tweak native gas to be used with FHE operations differently, contrarily to native), for security reason to avoid DOS attacks by malicious devs. Indeed, this contract also tracks the FHE gas consumed in each block, and reverts the transactions inside a block if the FHE gas block limit is exceeded.

## Gateway Contract

The [Gateway](https://github.com/zama-ai/fhevm/blob/main/gateway/GatewayContract.sol) contract is an onchain contract designed to interact with an offchain Gateway component that handles decryption requests. When a dApp calls the `requestDecryption` function, the Gateway contract emits an event that is caught by the Gateway service.

Verifier addresses are stored and updated in the contract.
_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.
17 changes: 8 additions & 9 deletions docs/getting_started/fhevm/contracts.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Deploy initial contracts

0/ Prerequisites: First, git clone `fhevm` repo main branch, install dependencies with `npm i`(node.js version should be at least `20`), then create a`.env` file in root of the repo.
0/ Prerequisites: First, git clone `fhevm` repo main branch, 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 [`.env.example.deployment` file](https://github.com/zama-ai/fhevm/blob/main/.env.example.deployment).
For instance, 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:
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:

```
export PRIVATE_KEY_FHEVM_DEPLOYER="0c66d8cde71d2faa29d0cb6e3a567d31279b6eace67b0a9d9ba869c119843a5e"
Expand All @@ -25,7 +25,7 @@ For the `SEPOLIA_RPC_URL` env variable, you can either get one from a service pr
**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 [foundry](https://book.getfoundry.sh/getting-started/installation) installed, you can generate fresh Ethereum private key / address pairs locally with this command:
`cast wallet new`.

2/ Then run the precompute addresses tasks -> this will write on disk the correct addresses needed to launch the modified Geth node (`TFHEExecutor` address) and the Gateway service (`GatewayContract` one) and - I think - the `ACL` and `KMSVerifier` addresses which would be needed to setup some values inside the ASC contract on KMS chain, in files such as: `lib/.env.acl`, `lib/.env.kmsverifier`, `gateway/env.gateway` etc. This script typically consists of the first part of [`./launch-fhevm.sh` file](https://github.com/zama-ai/fhevm/blob/main/launch-fhevm.sh) :
2/ Then run the precomputing contract addresses script [`./precompute-addresses.sh`](https://github.com/zama-ai/fhevm/blob/main/precompute-addresses.sh) -> 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 - I think - the `ACL` and `KMSVerifier` addresses which would be needed to setup some values inside the ASC contract on KMS chain, in files such as: `lib/.env.acl`, `lib/.env.kmsverifier`, `gateway/env.gateway` etc. This script is found exactly inside the [`./precompute-addresses.sh` file](https://github.com/zama-ai/fhevm/blob/main/precompute-addresses.sh) :

```
#!/bin/bash
Expand All @@ -38,7 +38,7 @@ npx hardhat task:computeGatewayAddress --private-key "$PRIVATE_KEY_GATEWAY_DEPLO
npx hardhat task:computeACLAddress --private-key "$PRIVATE_KEY_FHEVM_DEPLOYER"
npx hardhat task:computeTFHEExecutorAddress --private-key "$PRIVATE_KEY_FHEVM_DEPLOYER"
npx hardhat task:computeKMSVerifierAddress --private-key "$PRIVATE_KEY_FHEVM_DEPLOYER"
npx hardhat task:computeInputVerifierAddress --private-key "$PRIVATE_KEY_FHEVM_DEPLOYER"
npx hardhat task:computeInputVerifierAddress --private-key "$PRIVATE_KEY_FHEVM_DEPLOYER" --use-address true
npx hardhat task:computeFHEPaymentAddress --private-key "$PRIVATE_KEY_FHEVM_DEPLOYER"
```

Expand All @@ -56,17 +56,16 @@ npx hardhat task:computeFHEPaymentAddress --private-key "$PRIVATE_KEY_FHEVM_DEPL

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.

5/ Run the deployment script (part after the commented line).
Typically this script contains the second part of [`./launch-fhevm.sh` file](https://github.com/zama-ai/fhevm/blob/main/launch-fhevm.sh) :
5/ Finally, run the deployment script [`./launch-fhevm-sepolia.sh`](https://github.com/zama-ai/fhevm/blob/main/launch-fhevm-sepolia.sh).
This script is found exactly inside the [`./launch-fhevm-sepolia.sh` file](https://github.com/zama-ai/fhevm/blob/main/launch-fhevm-sepolia.sh) :

```
#!/bin/bash
# This script should be launched after precomputing the addresses via `precompute-addresses.sh`, and preferably after setting up the different services - KMS, Geth node, Gateway
npx hardhat clean
PRIVATE_KEY_GATEWAY_DEPLOYER=$(grep PRIVATE_KEY_GATEWAY_DEPLOYER .env | cut -d '"' -f 2)
PRIVATE_KEY_FHEVM_DEPLOYER=$(grep PRIVATE_KEY_FHEVM_DEPLOYER .env | cut -d '"' -f 2)
NUM_KMS_SIGNERS=$(grep NUM_KMS_SIGNERS .env | cut -d '"' -f 2)
IS_COPROCESSOR=$(grep IS_COPROCESSOR .env | cut -d '"' -f 2)
npx hardhat compile:specific --contract lib
npx hardhat compile:specific --contract gateway
Expand All @@ -77,7 +76,7 @@ npx hardhat task:deployKMSVerifier --private-key "$PRIVATE_KEY_FHEVM_DEPLOYER" -
npx hardhat task:deployInputVerifier --private-key "$PRIVATE_KEY_FHEVM_DEPLOYER" --network sepolia
npx hardhat task:deployFHEPayment --private-key "$PRIVATE_KEY_FHEVM_DEPLOYER" --network sepolia
npx hardhat task:addSigners --num-signers $NUM_KMS_SIGNERS --private-key "$PRIVATE_KEY_FHEVM_DEPLOYER" --use-address true --network sepolia
npx hardhat task:addSigners --num-signers "$NUM_KMS_SIGNERS" --private-key "$PRIVATE_KEY_FHEVM_DEPLOYER" --use-address true --network sepolia
npx hardhat task:launchFhevm --skip-get-coin true --use-address true --network sepolia
Expand Down

0 comments on commit c006e66

Please sign in to comment.