Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/introductions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ like this:
pragma solidity ^0.8.24;

import { FHE } from "@fhevm/solidity/lib/FHE.sol";
import { SepoliaZamaFHEVMConfig } from "@fhevm/solidity/config/ZamaFHEVMConfig.sol";
import { SepoliaConfig } from "@fhevm/solidity/config/ZamaConfig.sol";

contract MyCounter is SepoliaZamaFHEVMConfig {
euint64 counter;
Expand Down
2 changes: 1 addition & 1 deletion docs/introductions/architecture_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ compatibility:
- **On-chain smart contracts** describe encrypted logic symbolically, managing access control and state via FHE handles.
- **Off-chain coprocessors** listen to emitted events, reconstruct the compute graph, and perform the actual encrypted
computation.
- **The Gateway** acts as the protocol coordinator — verifying proofs, relaying requests, and managing data flow between
- **The Relayer** acts as the protocol coordinator — verifying proofs, relaying requests, and managing data flow between
the blockchain, the coprocessors, and the KMS.
- **The KMS** is a decentralized, threshold-secure network that handles private key operations like decryption and
signing, without ever reconstructing the full key.
Expand Down
4 changes: 2 additions & 2 deletions docs/introductions/fhe-on-blockchain.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ To overcome these challenges, Zama introduced a hybrid architecture for FHEVM th
- **Off-chain**
- Coprocessors execute FHE operations using the evaluation key.
- Results are stored off-chain, and only references (handles) are returned on-chain.
- **Gateway & KMS**
- **Relayer & KMS**

- The Gateway coordinates between the blockchain, users, and the KMS.
- The relayer coordinates between the blockchain, users, and the KMS.
- The Key Management System securely handles decryption via threshold MPC, supporting both smart contract and user
decryption.

Expand Down
2 changes: 1 addition & 1 deletion docs/introductions/introduction-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Otherwise, pick your path:
integrate the SDK, and run your first confidential app.

⚙️ Go to [Architecture](./architecture_overview.md) – Explore how the protocol works under the hood: smart contracts,
coprocessors, the Gateway, and the KMS.
coprocessors, the relayer, and the KMS.

🧰 Go to [Tooling](../solidity-guides/solidity-overview.md) – Discover how to use the Hardhat plugin and debugging tools
designed to make FHE development seamless.
Expand Down
23 changes: 13 additions & 10 deletions docs/introductions/table_of_addresses.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
## Table of all addresses

Save this in your `.env` file:
Save this in your `.env` file.

| Contract/Service | Address/Value |
| ---------------------- | ------------------------------------------ |
| TFHE_EXECUTOR_CONTRACT | 0x687408aB54661ba0b4aeF3a44156c616c6955E07 |
| ACL_CONTRACT | 0xFee8407e2f5e3Ee68ad77cAE98c434e637f516e5 |
| PAYMENT_CONTRACT | 0xFb03BE574d14C256D56F09a198B586bdfc0A9de2 |
| KMS_VERIFIER_CONTRACT | 0x9D6891A6240D6130c54ae243d8005063D05fE14b |
| GATEWAY_CONTRACT | 0x33347831500F1e73f0ccCBb95c9f86B94d7b1123 |
| PUBLIC_KEY_ID | 0301c5dd3e2702992b7c12930b7d4defeaaa52cf |
| GATEWAY_URL | `https://gateway.sepolia.zama.ai/` |
These are Sepolia addresses.

| Contract/Service | Address/Value |
|----------------------------|------------------------------------------------|
| FHEVM_EXECUTOR_CONTRACT | 0x848B0066793BcC60346Da1F49049357399B8D595 |
| ACL_CONTRACT | 0x687820221192C5B662b25367F70076A37bc79b6c |
| HCU_LIMIT_CONTRACT | 0x594BB474275918AF9609814E68C61B1587c5F838 |
| KMS_VERIFIER_CONTRACT | 0x1364cBBf2cDF5032C47d8226a6f6FBD2AFCDacAC |
| INPUT_VERIFIER_CONTRACT | 0xbc91f3daD1A5F19F8390c400196e58073B6a0BC4 |
| DECRYPTION_ORACLE_CONTRACT | 0xa02Cda4Ca3a71D7C46997716F4283aa851C28812 |
| PUBLIC_KEY_ID | 0301c5dd3e2702992b7c12930b7d4defeaaa52cf |
| RELAYER_URL | `https://relayer.testnet.zama.cloud/v1/keyurl` |
32 changes: 15 additions & 17 deletions docs/solidity-guides/configure.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ This document explains how to enable encrypted computations in your smart contra

## Core configuration setup

To utilize encrypted computations in Solidity contracts, you must configure the **FHE library** and **Gateway addresses**. The `fhevm` package simplifies this process with prebuilt configuration contracts, allowing you to focus on developing your contract’s logic without handling the underlying cryptographic setup.
To utilize encrypted computations in Solidity contracts, you must configure the **FHE library** and **Relayer addresses**. The `fhevm` package simplifies this process with prebuilt configuration contracts, allowing you to focus on developing your contract’s logic without handling the underlying cryptographic setup.

## Key components configured automatically

1. **FHE library**: Sets up encryption parameters and cryptographic keys.
2. **Gateway**: Manages secure cryptographic operations, including reencryption and decryption.
2. **Relayer**: Manages secure cryptographic operations, including reencryption and decryption.
3. **Network-specific settings**: Adapts to local testing, testnets (Sepolia for example), or mainnet deployment.

By inheriting these configuration contracts, you ensure seamless initialization and functionality across environments.
Expand All @@ -22,7 +22,7 @@ This configuration contract initializes the **fhevm environment** with required

```solidity
// For Ethereum Sepolia
import { SepoliaZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol";
import { SepoliaZamaFHEVMConfig } from "@fhevm/solidity/config/ZamaFHEVMConfig.sol";
```

**Purpose:**
Expand All @@ -36,7 +36,7 @@ import { SepoliaZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol";
// SPDX-License-Identifier: BSD-3-Clause-Clear
pragma solidity ^0.8.24;

import { SepoliaZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol";
import { SepoliaZamaFHEVMConfig } from "@fhevm/solidity/config/ZamaFHEVMConfig.sol";

contract MyERC20 is SepoliaZamaFHEVMConfig {
constructor() {
Expand All @@ -45,33 +45,31 @@ contract MyERC20 is SepoliaZamaFHEVMConfig {
}
```

## ZamaGatewayConfig.sol
## ZamaRela.sol

To perform decryption or reencryption, your contract must interact with the **Gateway**, which acts as a secure bridge between the blockchain, coprocessor, and Key Management System (KMS).
To perform decryption or reencryption, your contract must interact with the **Relayer**, which acts as a secure bridge between the blockchain, coprocessor, and Key Management System (KMS).

**Import based on your environment**

```solidity
// For Ethereum Sepolia
import { SepoliaZamaGatewayConfig } from "fhevm/config/ZamaGatewayConfig.sol";
// For Sepolia
import { SepoliaConfig } from "@fhevm/solidity/config/ZamaConfig.sol";
```

**Purpose**

- Configures the Gateway for secure cryptographic operations.
- Configures the relayer for secure cryptographic operations.
- Facilitates reencryption and decryption requests.

**Example: Configuring the gateway with Sepolia settings**
**Example: Configuring the relayer with Sepolia settings**

```solidity
import "fhevm/lib/FHE.sol";
import { SepoliaZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol";
import { SepoliaZamaGatewayConfig } from "fhevm/config/ZamaGatewayConfig.sol";
import "fhevm/gateway/GatewayCaller.sol";
import "@fhevm/solidity/lib/FHE.sol";
import { SepoliaConfig } from "@fhevm/solidity/config/ZamaConfig.sol";

contract Test is SepoliaZamaFHEVMConfig, SepoliaZamaGatewayConfig, GatewayCaller {
contract Test is SepoliaConfig {
constructor() {
// Gateway and FHEVM environment initialized automatically
// Relayer and FHEVM environment initialized automatically
}
}
```
Expand Down Expand Up @@ -99,4 +97,4 @@ require(FHE.isInitialized(counter), "Counter not initialized!");

## Summary

By leveraging prebuilt configuration contracts like `ZamaFHEVMConfig.sol` and `ZamaGatewayConfig.sol`, you can efficiently set up your smart contract for encrypted computations. These tools abstract the complexity of cryptographic initialization, allowing you to focus on building secure, confidential smart contracts.
By leveraging prebuilt a configuration contract like `ZamaConfig.sol`, you can efficiently set up your smart contract for encrypted computations. These tools abstract the complexity of cryptographic initialization, allowing you to focus on building secure, confidential smart contracts.
4 changes: 2 additions & 2 deletions docs/solidity-guides/debug_decrypt.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The `debug.decrypt[XX]` functions allow you to decrypt encrypted handles into pl
### Key points

- **Environment**: The `debug.decrypt[XX]` functions work **only in mocked environments** (e.g., `hardhat` network).
- **Production limitation**: In production, decryption is performed asynchronously via the Gateway and requires an authorized onchain request.
- **Production limitation**: In production, decryption is performed asynchronously via the relayer and requires an authorized onchain request.
- **Encrypted types**: The `debug.decrypt[XX]` functions supports various encrypted types, including integers, and booleans.
- **Bypass ACL authorization**: The `debug.decrypt[XX]` functions allow decryption without ACL authorization, useful for verifying encrypted operations during development and testing.

Expand Down Expand Up @@ -106,4 +106,4 @@ if (network.name !== "hardhat") {
## **Best practices**

- **Use only for debugging**: These functions require access to private keys and are meant exclusively for local testing and debugging.
- **Production decryption**: For production, always use the asynchronous Gateway-based decryption.
- **Production decryption**: For production, always use the asynchronous relayer-based decryption.
50 changes: 21 additions & 29 deletions docs/solidity-guides/decryption/decrypt.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,69 +3,61 @@
This section explains how to handle decryption in fhevm. Decryption allows plaintext data to be accessed when required for contract logic or user presentation, ensuring confidentiality is maintained throughout the process.

{% hint style="info" %}
Understanding how encryption, decryption and reencryption works is a prerequisit before implementation, see [Encryption, Decryption, Re-encryption, and Computation](../d_re_ecrypt_compute.md).
Understanding how encryption, decryption and reencryption works is a prerequisite before implementation, see [Encryption, Decryption, Re-encryption, and Computation](../../introductions/d_re_ecrypt_compute.md).
{% endhint %}

Decryption is essential in two primary cases:

1. **Smart contract logic**: A contract requires plaintext values for computations or decision-making.
2. **User interaction**: Plaintext data needs to be revealed to all users, such as revealing the decision of the vote.

To learn how decryption works see [Encryption, Decryption, Re-encryption, and Computation](../d_re_ecrypt_compute.md)
To learn how decryption works see [Encryption, Decryption, Re-encryption, and Computation](../../introductions/d_re_ecrypt_compute.md).

## Overview

Decryption in FHEVM is an asynchronous process that involves the Gateway and Key Management System (KMS). Contracts requiring decryption must extend the GatewayCaller contract, which imports the necessary libraries and provides access to the Gateway.

Here’s an example of how to request decryption in a contract:
Decryption in FHEVM is an asynchronous process that involves the Relayer and Key Management System (KMS).
Here’s an example of how to safely request decryption in a contract.

### Example: asynchronous decryption in a contract

```solidity
pragma solidity ^0.8.24;

import "fhevm/lib/FHE.sol";
import { SepoliaZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol";
import { SepoliaZamaGatewayConfig } from "fhevm/config/ZamaGatewayConfig.sol";
import "fhevm/gateway/GatewayCaller.sol";
import "@fhevm/solidity/lib/FHE.sol";
import { SepoliaConfig } from "@fhevm/solidity/config/ZamaConfig.sol";

contract TestAsyncDecrypt is SepoliaZamaFHEVMConfig, SepoliaZamaGatewayConfig, GatewayCaller {
contract TestAsyncDecrypt is SepoliaConfig {
ebool xBool;
bool public yBool;
bool isDecryptionPending;
uint256 latestRequestId;

constructor() {
xBool = FHE.asEbool(true);
FHE.allowThis(xBool);
}

function requestBool() public {
require(!isDecryptionPending, "Decryption is in progress");
uint256[] memory cts = new uint256[](1);
cts[0] = Gateway.toUint256(xBool);
Gateway.requestDecryption(cts, this.myCustomCallback.selector, 0, block.timestamp + 100, false);
cts[0] = FHE.toUint256(xBool);
uint256 latestRequestId = FHE.requestDecryption(cts, this.myCustomCallback.selector);

/// @dev This prevents sending multiple requests before the first callback was sent.
isDecryptionPending = true;
}

function myCustomCallback(uint256 /*requestID*/, bool decryptedInput) public onlyGateway returns (bool) {
function myCustomCallback(uint256 requestId, bool decryptedInput, bytes[] memory signatures) public returns (bool) {
/// @dev This check is used to verify that the request id is the expected one.
require(requestId == latestRequestId, "Invalid requestId");
FHE.checkSignatures(requestId, signatures);
yBool = decryptedInput;
isDecryptionPending = false;
return yBool;
}
}
```

#### Key additions to the code

1. **Configuration imports**: The configuration contracts are imported to set up the FHEVM environment and Gateway.

```solidity
import { SepoliaZamaFHEVMConfig } from "fhevm/config/ZamaFHEVMConfig.sol";
import { SepoliaZamaGatewayConfig } from "fhevm/config/ZamaGatewayConfig.sol";
```

2. **`GatewayCaller` import**:\
The `GatewayCaller` contract is imported to enable decryption requests.

```solidity
import "fhevm/gateway/GatewayCaller.sol";
```

### Next steps

Explore advanced decryption techniques and learn more about re-encryption:
Expand Down
17 changes: 7 additions & 10 deletions docs/solidity-guides/decryption/decrypt_details.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This document provides a detailed guide on implementing decryption in your smart

## `DecryptionOracle` setup

The `DecryptionOracle` is pre-deployed on the FHEVM testnet. It uses a default relayer account specified in the `PRIVATE_KEY_GATEWAY_RELAYER` or `ADDRESS_GATEWAY_RELAYER` environment variable in the `.env` file.
The `DecryptionOracle` is pre-deployed on the FHEVM testnet. It uses a default relayer account specified in the `.env` file.

Anyone can fulfill decryption requests but it is essential to add signature verification (and to include a logic to invalidate the replay of decryption requests). The role of the `DecryptionOracle` contract is to independently verify the KMS signature during execution. This ensures that the relayers cannot manipulate or send fraudulent decryption results, even if compromised.

Expand All @@ -15,21 +15,19 @@ There are two functions to consider: `requestDecryption` and `checkSignatures`.
You can call the function `FHE.requestDecryption` as such:

```solidity
function requestDecryption(uint256 requestID, bytes32[] calldata ctsHandles, bytes4 callbackSelector) external payable;
function requestDecryption(bytes32[] calldata ctsHandles, bytes4 callbackSelector) external payable returns (uint256 requestId);
```

#### Function arguments

The first argument, `requestID`, is a counter that is incremented at the smart contract level after each decryption request.

The second argument, `ctsHandles`, should be an array of ciphertexts handles which could be of different types, i.e `uint256` values coming from unwrapping handles of type either `ebool`, `euint8`, `euint16`, `euint32`, `euint64` or `eaddress`. 
The first argument, `ctsHandles`, should be an array of ciphertexts handles which could be of different types, i.e `uint256` values coming from unwrapping handles of type either `ebool`, `euint8`, `euint16`, `euint32`, `euint64` or `eaddress`. 

`ctsHandles` is the array of ciphertexts that are requested to be decrypted. Tthe relayer will send the corresponding ciphertexts to the KMS for decryption before fulfilling the request.

`callbackSelector` is the function selector of the callback function, which will be called once the relayer fulfils the decryption request.

```solidity
function [callbackName](uint256 requestID, XXX x_0, XXX x_1, ..., XXX x_N-1) external;
function [callbackName](uint256 requestID, XXX x_0, XXX x_1, ..., XXX x_N-1, bytes[] memory signatures) external;
```

Notice that `XXX` should be the decrypted type, which is a native Solidity type corresponding to the original ciphertext type, following this table of conventions:
Expand Down Expand Up @@ -61,8 +59,7 @@ You can call the function `FHE.checkSignatures` as such:

#### Function arguments

The first argument, `requestID`, is the value used as an argument in the `requestDecryption`function.

The second argument, `signatures`, is an array of signatures from the KMS.
The first argument, `requestID`, is the value that was returned in the `requestDecryption`function.
The second argument, `signatures`, is an array of signatures from the KMS signers.

If
This function reverts if the signatures are invalid.
10 changes: 5 additions & 5 deletions docs/solidity-guides/decryption/reencryption.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This document explains how to perform user decryption. User decryption required
Re-encryption in FHEVM enables the secure sharing or reuse of encrypted data under a new public key without exposing the plaintext. This feature is essential for scenarios where encrypted data must be transferred between contracts, dApps, or users while maintaining its confidentiality.

{% hint style="info" %}
Before implementing re-encryption, ensure you are familiar with the foundational concepts of encryption, re-encryption and computation. Refer to [Encryption, Decryption, Re-encryption, and Computation](../d_re_ecrypt_compute.md).
Before implementing re-encryption, ensure you are familiar with the foundational concepts of encryption, re-encryption and computation. Refer to [Encryption, Decryption, Re-encryption, and Computation](../introductions/d_re_ecrypt_compute.md).
{% endhint %}

## When to use user decryption
Expand All @@ -18,7 +18,7 @@ The re-encryption process involves retrieving ciphertext from the blockchain and

This ensures that the data remains encrypted under the blockchain’s FHE key but can be securely shared with a user by re-encrypting it under the user’s NaCl public key.

Re-encryption is facilitated by the **Gateway** and the **Key Management System (KMS)**. The workflow consists of the following:
Re-encryption is facilitated by the **Relayer** and the **Key Management System (KMS)**. The workflow consists of the following:

1. Retrieving the ciphertext from the blockchain using a contract’s view function.
2. Re-encrypting the ciphertext client-side with the user’s public key, ensuring only the user can decrypt it.
Expand All @@ -28,7 +28,7 @@ Re-encryption is facilitated by the **Gateway** and the **Key Management System
To retrieve the ciphertext that needs to be re-encrypted, you can implement a view function in your smart contract. Below is an example implementation:

```solidity
import "fhevm/lib/FHE.sol";
import "@fhevm/solidity/lib/FHE.sol";

contract ConfidentialERC20 {
...
Expand Down Expand Up @@ -77,7 +77,7 @@ const signature = await window.ethereum.request({ method: "eth_signTypedData_v4"
const ConfidentialERC20 = new Contract(CONTRACT_ADDRESS, abi, signer).connect(provider);
const encryptedBalance = ConfidentialERC20.balanceOf(userAddress);

// This function will call the gateway and decrypt the received value with the provided private key
// This function will call the relayer and decrypt the received value with the provided private key
const userBalance = instance.reencrypt(
encryptedBalance, // the encrypted balance
privateKey, // the private key generated by the dApp
Expand All @@ -96,4 +96,4 @@ This code retrieves the user’s encrypted balance, re-encrypts it with their pu

- **`instance.generateKeypair()`**: Generates a public-private keypair for the user.
- **`instance.createEIP712(publicKey, CONTRACT_ADDRESS)`**: Creates an EIP712 object for signing the user’s public key.
- **`instance.reencrypt()`**: Facilitates the re-encryption process by contacting the Gateway and decrypting the data locally with the private key.
- **`instance.reencrypt()`**: Facilitates the re-encryption process by contacting the relayer and decrypting the data locally with the private key.
Loading