From 5668f1d2eedeb925b3c58fd7366802a65258f23e Mon Sep 17 00:00:00 2001 From: Aurora Poppyseed <30662672+poppyseedDev@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:49:39 +0100 Subject: [PATCH] docs: prettier and adressing some changes --- docs/developer/roadmap.md | 27 ++-- docs/fundamentals/acl.md | 23 ++-- docs/fundamentals/architecture_overview.md | 85 ++++++------ docs/fundamentals/d_re_ecrypt_compute.md | 128 +++++++++--------- docs/fundamentals/first_step/acl_examples.md | 72 ++++++---- docs/fundamentals/first_step/configure.md | 68 +++++----- docs/fundamentals/first_step/decrypt.md | 43 +++--- .../first_step/decrypt_details.md | 2 +- docs/fundamentals/first_step/inputs.md | 66 ++++----- docs/fundamentals/first_step/operations.md | 82 +++++------ docs/fundamentals/first_step/reencryption.md | 80 +++++------ docs/fundamentals/first_step/start.md | 72 +++++----- docs/fundamentals/first_step/types.md | 65 +++++---- docs/getting_started/ethereum.md | 23 ++-- docs/getting_started/key_concepts.md | 21 ++- docs/getting_started/repositories.md | 42 +++--- .../getting_started/write_contract/hardhat.md | 39 +++--- docs/guides/conditions.md | 23 ++-- docs/guides/error_handling.md | 11 +- docs/guides/frontend/cli.md | 54 +++++++- docs/guides/frontend/node.md | 4 +- docs/guides/random.md | 21 +-- docs/references/functions.md | 72 +++++++--- docs/tutorials/see-all-tutorials.md | 9 +- 24 files changed, 643 insertions(+), 489 deletions(-) diff --git a/docs/developer/roadmap.md b/docs/developer/roadmap.md index 6b94397f..69c6aadf 100644 --- a/docs/developer/roadmap.md +++ b/docs/developer/roadmap.md @@ -2,23 +2,22 @@ ## Features -| name | description | ETA | -| -------------------- | ------------------------------------------------------------ | ------ | -| Foundry template | [ Forge ](https://book.getfoundry.sh/reference/forge/forge) | Q1 '25 | +| name | description | ETA | +| ---------------- | ----------------------------------------------------------- | ------ | +| Foundry template | [ Forge ](https://book.getfoundry.sh/reference/forge/forge) | Q1 '25 | ## Operations -| name | function name | type | ETA | -| --------------------- | ------------------- | ------------------ | --------------- | -| Signed Integers | `eintX` | | Coming soon | -| Add w/ overflow check | `TFHE.safeAdd` | Binary, Decryption | Coming soon | -| Sub w/ overflow check | `TFHE.safeSub` | Binary, Decryption | Coming soon | -| Mul w/ overflow check | `TFHE.safeMul` | Binary, Decryption | Coming soon | -| Random signed int | `TFHE.randEintX()` | Random | - | -| Div | `TFHE.div` | Binary | - | -| Rem | `TFHE.rem` | Binary | - | -| Set inclusion | `TFHE.isIn()` | Binary | - | - +| name | function name | type | ETA | +| --------------------- | ------------------ | ------------------ | ----------- | +| Signed Integers | `eintX` | | Coming soon | +| Add w/ overflow check | `TFHE.safeAdd` | Binary, Decryption | Coming soon | +| Sub w/ overflow check | `TFHE.safeSub` | Binary, Decryption | Coming soon | +| Mul w/ overflow check | `TFHE.safeMul` | Binary, Decryption | Coming soon | +| Random signed int | `TFHE.randEintX()` | Random | - | +| Div | `TFHE.div` | Binary | - | +| Rem | `TFHE.rem` | Binary | - | +| Set inclusion | `TFHE.isIn()` | Binary | - | > **_NOTE 1:_** Random encrypted integers that are generated fully on-chain. Currently, implemented as a mockup by using a PRNG in the plain. > Not for use in production! diff --git a/docs/fundamentals/acl.md b/docs/fundamentals/acl.md index 82ba4fd6..fa236095 100644 --- a/docs/fundamentals/acl.md +++ b/docs/fundamentals/acl.md @@ -14,25 +14,25 @@ Encrypted data in fhEVM is entirely confidential, meaning that without proper ac - **Secure Computations**: Ensure that only authorized entities can manipulate or decrypt encrypted data. - **Gas Efficiency**: Optimize permissions using transient access for temporary needs, reducing storage and gas costs. - ## How does the ACL work? ### Types of access -1. **Permanent Allowance**: - - Configured using `TFHE.allow(ciphertext, address)`. - - Grants long-term access to the ciphertext for a specific address. +1. **Permanent Allowance**: + + - Configured using `TFHE.allow(ciphertext, address)`. + - Grants long-term access to the ciphertext for a specific address. - Stored in a dedicated contract for persistent storage. -2. **Transient Allowance**: - - Configured using `TFHE.allowTransient(ciphertext, address)`. - - Grants access to the ciphertext only for the duration of the current transaction. - - Stored in transient storage, reducing gas costs. +2. **Transient Allowance**: + - Configured using `TFHE.allowTransient(ciphertext, address)`. + - Grants access to the ciphertext only for the duration of the current transaction. + - Stored in transient storage, reducing gas costs. - Ideal for temporary operations like passing ciphertexts to external functions. -**Syntactic sugar**: -- `TFHE.allowThis(ciphertext)` is shorthand for `TFHE.allow(ciphertext, address(this))`. It authorizes the current contract to reuse a ciphertext handle in future transactions. +**Syntactic sugar**: +- `TFHE.allowThis(ciphertext)` is shorthand for `TFHE.allow(ciphertext, address(this))`. It authorizes the current contract to reuse a ciphertext handle in future transactions. ### Transient vs. permanent allowance @@ -41,7 +41,6 @@ Encrypted data in fhEVM is entirely confidential, meaning that without proper ac | **Transient** | Temporary access during a transaction. | [Transient storage](https://eips.ethereum.org/EIPS/eip-1153) (EIP-1153) | Calling external functions or computations with ciphertexts. Use when wanting to save on gas costs. | | **Permanent** | Long-term access across multiple transactions. | Dedicated contract storage | Persistent ciphertexts for contracts or users requiring ongoing access. | - ## Granting and verifying access ### Granting access @@ -69,4 +68,4 @@ To check if an entity has permission to access a ciphertext, use functions like --- -For a detailed explanation of the ACL's functionality, including code examples and advanced configurations, see [working with the acl](./first_step/acl_examples.md). \ No newline at end of file +For a detailed explanation of the ACL's functionality, including code examples and advanced configurations, see [working with the acl](./first_step/acl_examples.md). diff --git a/docs/fundamentals/architecture_overview.md b/docs/fundamentals/architecture_overview.md index f5e9d296..67e26170 100644 --- a/docs/fundamentals/architecture_overview.md +++ b/docs/fundamentals/architecture_overview.md @@ -1,4 +1,3 @@ - # Architecture Overview This document provides developers with the essential architectural concepts needed to start building with fhEVM. Rather than diving deep into implementation details, it focuses on the key components and principles that enable confidential smart contract development. @@ -10,33 +9,36 @@ The goal is to give you just enough understanding of the architecture to begin c Fully Homomorphic Encryption (FHE) is an advanced cryptographic technique that allows computations to be performed directly on encrypted data, without the need for decryption. This ensures that data remains confidential throughout its entire lifecycle, even during processing. With FHE: + - Sensitive data can be securely encrypted while still being useful for computations. - The results of computations are encrypted, maintaining end-to-end privacy. FHE operates using three types of keys, each playing a crucial role in its functionality: ### **1.1 Private key** + - **Purpose**: - for securely decrypting results - Decrypts ciphertexts to recover the original plaintext. - **Usage in fhEVM**: Managed securely by the Key Management System (KMS) using a threshold MPC protocol. This ensures no single entity ever possesses the full private key. ### **1.2 Public key** -- **Purpose**: - for encrypting data. - Encrypts plaintexts into ciphertexts. + +- **Purpose**: - for encrypting data. - Encrypts plaintexts into ciphertexts. - **Usage in fhEVM**: Shared globally to allow users and smart contracts to encrypt inputs or states. It ensures that encrypted data can be processed without revealing the underlying information. ### **1.3 Evaluation key** -- **Purpose**: - for performing encrypted computations - Enables efficient homomorphic operations (e.g., addition, multiplication) on ciphertexts. + +- **Purpose**: - for performing encrypted computations - Enables efficient homomorphic operations (e.g., addition, multiplication) on ciphertexts. - **Usage in fhEVM**: Provided to FHE nodes (on-chain validators or off-chain coprocessors) to perform computations on encrypted data while preserving confidentiality. These three keys work together to facilitate private and secure computations, forming the foundation of FHE-based systems like fhEVM.
FHE Keys Overview
Overview of FHE Keys and their roles
- - ## **2. Bringing FHE to Blockchain: From Library to fhEVM** ### **2.1 Building on Zama's FHE library** -At its core, the fhEVM is built on Zama's high-performance FHE library, **TFHE-rs**, written in Rust. This library implements the TFHE (Torus Fully Homomorphic Encryption) scheme and is designed to perform secure computations on encrypted data efficiently. + +At its core, the fhEVM is built on Zama's high-performance FHE library, **TFHE-rs**, written in Rust. This library implements the TFHE (Torus Fully Homomorphic Encryption) scheme and is designed to perform secure computations on encrypted data efficiently. > **Info**: > For detailed documentation and implementation examples on the `tfhe-rs` library, visit the [TFHE-rs documentation](https://docs.zama.ai/tfhe-rs). @@ -44,6 +46,7 @@ At its core, the fhEVM is built on Zama's high-performance FHE library, **TFHE-r However, integrating a standalone FHE library like TFHE-rs into a blockchain environment involves unique challenges. Blockchain systems demand efficient processing, public verifiability, and seamless interoperability, all while preserving their decentralized nature. To address these requirements, Zama designed the fhEVM, a system that bridges the computational power of TFHE-rs with the transparency and scalability of blockchain technology. ### **2.2 Challenges in blockchain integration** + Integrating FHE into blockchain systems posed several challenges that needed to be addressed to achieve the goals of confidentiality, composability, and scalability: 1. **Transparency and privacy**: Blockchains are inherently transparent, where all on-chain data is publicly visible. FHE solves this by keeping all sensitive data encrypted, ensuring privacy without sacrificing usability. @@ -51,23 +54,21 @@ Integrating FHE into blockchain systems posed several challenges that needed to 3. **Composability**: Smart contracts needed to interact seamlessly with each other, even when operating on encrypted data. 4. **Performance and scalability**: FHE computations are resource-intensive, and blockchain systems require high throughput to remain practical. - To overcome these challenges, Zama introduced a hybrid architecture for fhEVM that combines: - - **On-chain** functionality for managing state and enforcing access controls. - - **Off-chain** processing via a coprocessor to execute resource-intensive FHE computations. +- **On-chain** functionality for managing state and enforcing access controls. +- **Off-chain** processing via a coprocessor to execute resource-intensive FHE computations. ## **3 fhEVM components overview** The fhEVM architecture is built around four primary components, each contributing to the system's functionality and performance. These components work together to enable the development and execution of private, composable smart contracts on EVM-compatible blockchains. Below is an overview of these components and their responsibilities: -| **Component** | **Description** | **Key Functions** | -|-------------------------------|------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------| -| **fhEVM Smart Contracts** | Smart contracts deployed on the blockchain to manage encrypted data and interactions. | Includes the Access Control List (ACL) contract, `TFHE.sol` Solidity library, `Gateway.sol` and other FHE-enabled smart contracts. | -| **Gateway** | An off-chain service that bridges the blockchain with the cryptographic systems like KMS and coprocessor. | Acts as an intermediary to forward the necessary requests and results between the blockchain, the KMS, and users. | -| **Coprocessor** | An off-chain computational engine designed to execute resource-intensive FHE operations. | Executes symbolic FHE operations, manages ciphertext storage, and ensures efficient computation handling. | -| **Key Management System (KMS)** | A decentralized cryptographic service that securely manages FHE keys and validates operations. | Manages the global FHE key (public, private, evaluation), performs threshold decryption, and validates ZKPoKs. | - +| **Component** | **Description** | **Key Functions** | +| ------------------------------- | --------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| **fhEVM Smart Contracts** | Smart contracts deployed on the blockchain to manage encrypted data and interactions. | Includes the Access Control List (ACL) contract, `TFHE.sol` Solidity library, `Gateway.sol` and other FHE-enabled smart contracts. | +| **Gateway** | An off-chain service that bridges the blockchain with the cryptographic systems like KMS and coprocessor. | Acts as an intermediary to forward the necessary requests and results between the blockchain, the KMS, and users. | +| **Coprocessor** | An off-chain computational engine designed to execute resource-intensive FHE operations. | Executes symbolic FHE operations, manages ciphertext storage, and ensures efficient computation handling. | +| **Key Management System (KMS)** | A decentralized cryptographic service that securely manages FHE keys and validates operations. | Manages the global FHE key (public, private, evaluation), performs threshold decryption, and validates ZKPoKs. |
FHE Keys Overview
High level overview of the fhEVM Architecture
@@ -75,7 +76,7 @@ The fhEVM architecture is built around four primary components, each contributin ### **Developer guide to creating confidential smart contracts** -As a developer working with fhEVM, your workflow typically involves two key elements: +As a developer working with fhEVM, your workflow typically involves two key elements: 1. **Frontend development**: You create a frontend interface for users to interact with your confidential application. This includes encrypting inputs using the public FHE key and submitting them to the blockchain. @@ -87,19 +88,23 @@ As a developer working with fhEVM, your workflow typically involves two key elem ### **fhEVM smart contracts** -fhEVM smart contracts include the Access Control List (ACL) contract, `TFHE.sol` library, and related FHE-enabled contracts. +fhEVM smart contracts include the Access Control List (ACL) contract, `TFHE.sol` library, and related FHE-enabled contracts. #### **Symbolic execution in Solidity** -fhEVM implements **symbolic execution** to optimize FHE computations: -- **Handles**: Operations on encrypted data return "handles" (references to ciphertexts) instead of immediate results. + +fhEVM implements **symbolic execution** to optimize FHE computations: + +- **Handles**: Operations on encrypted data return "handles" (references to ciphertexts) instead of immediate results. - **Lazy Execution**: Actual computations are performed asynchronously, offloading resource-intensive tasks to the coprocessor. This approach ensures high throughput and flexibility in managing encrypted data. #### **Zero-Knowledge proofs of knowledge (ZKPoKs)** -fhEVM incorporates ZKPoKs to verify the correctness of encrypted inputs and outputs: -- **Validation**: ZKPoKs ensure that inputs are correctly formed and correspond to known plaintexts without revealing sensitive data. -- **Integrity**: They prevent misuse of ciphertexts and ensure the correctness of computations. + +fhEVM incorporates ZKPoKs to verify the correctness of encrypted inputs and outputs: + +- **Validation**: ZKPoKs ensure that inputs are correctly formed and correspond to known plaintexts without revealing sensitive data. +- **Integrity**: They prevent misuse of ciphertexts and ensure the correctness of computations. By combining symbolic execution and ZKPoKs, fhEVM smart contracts maintain both privacy and verifiability. @@ -107,22 +112,24 @@ By combining symbolic execution and ZKPoKs, fhEVM smart contracts maintain both ### **Coprocessor** -The coprocessor is the backbone for handling computationally intensive FHE tasks. +The coprocessor is the backbone for handling computationally intensive FHE tasks. #### **Key functions**: -1. **Execution**: Performs operations such as addition, multiplication, and comparison on encrypted data. -2. **Ciphertext management**: Stores encrypted inputs, states, and outputs securely, either off-chain or in a dedicated on-chain database. + +1. **Execution**: Performs operations such as addition, multiplication, and comparison on encrypted data. +2. **Ciphertext management**: Stores encrypted inputs, states, and outputs securely, either off-chain or in a dedicated on-chain database. --- ### **Gateway** -The Gateway acts as the bridge between the blockchain, coprocessor, and KMS. +The Gateway acts as the bridge between the blockchain, coprocessor, and KMS. #### **Key functions**: -- **API for developers**: Exposes endpoints for submitting encrypted inputs, retrieving outputs, and managing ciphertexts. -- **Proof validation**: Forwards ZKPoKs to the KMS for verification. -- **Off-chain coordination**: Relays encrypted data and computation results between on-chain and off-chain systems. + +- **API for developers**: Exposes endpoints for submitting encrypted inputs, retrieving outputs, and managing ciphertexts. +- **Proof validation**: Forwards ZKPoKs to the KMS for verification. +- **Off-chain coordination**: Relays encrypted data and computation results between on-chain and off-chain systems. The Gateway simplifies the development process by abstracting the complexity of cryptographic operations. @@ -130,19 +137,19 @@ The Gateway simplifies the development process by abstracting the complexity of ### **Key management system (KMS)** -The KMS securely manages the cryptographic backbone of fhEVM by maintaining and distributing the global FHE keys. +The KMS securely manages the cryptographic backbone of fhEVM by maintaining and distributing the global FHE keys. #### **Key functions**: -- **Threshold decryption**: Uses Multi-Party Computation (MPC) to securely decrypt ciphertexts without exposing the private key to any single entity. -- **ZKPoK validation**: Verifies proofs of plaintext knowledge to ensure that encrypted inputs are valid. -- **Key distribution**: Maintains the global FHE keys, which include: - - **Public key**: Used for encrypting data (accessible to the frontend and smart contracts). - - **Private key**: Stored securely in the KMS and used for decryption. - - **Evaluation key**: Used by the coprocessor to perform FHE computations. -The KMS ensures robust cryptographic security, preventing single points of failure and maintaining public verifiability. +- **Threshold decryption**: Uses Multi-Party Computation (MPC) to securely decrypt ciphertexts without exposing the private key to any single entity. +- **ZKPoK validation**: Verifies proofs of plaintext knowledge to ensure that encrypted inputs are valid. +- **Key distribution**: Maintains the global FHE keys, which include: + - **Public key**: Used for encrypting data (accessible to the frontend and smart contracts). + - **Private key**: Stored securely in the KMS and used for decryption. + - **Evaluation key**: Used by the coprocessor to perform FHE computations. +The KMS ensures robust cryptographic security, preventing single points of failure and maintaining public verifiability. --- -In the next section, we will dive deeper into encryption, re-encryption, and decryption processes, including how they interact with the KMS and Gateway services. For more details, see [Decrypt and re-encrypt](./d_re_ecrypt_compute.md). \ No newline at end of file +In the next section, we will dive deeper into encryption, re-encryption, and decryption processes, including how they interact with the KMS and Gateway services. For more details, see [Decrypt and re-encrypt](./d_re_ecrypt_compute.md). diff --git a/docs/fundamentals/d_re_ecrypt_compute.md b/docs/fundamentals/d_re_ecrypt_compute.md index ae450b28..650fd94d 100644 --- a/docs/fundamentals/d_re_ecrypt_compute.md +++ b/docs/fundamentals/d_re_ecrypt_compute.md @@ -8,16 +8,18 @@ The fhEVM system ensures end-to-end confidentiality by leveraging Fully Homomorp ## **FHE Keys and Their Locations** -1. **Public Key**: - - **Location**: Directly accessible from the frontend or the smart contract. - - **Role**: Used to encrypt plaintext data before submission to the blockchain or during contract execution. +1. **Public Key**: -2. **Private Key**: - - **Location**: Stored securely in the Key Management System (KMS). - - **Role**: Used for decrypting ciphertexts when necessary, either to verify results or enable user-specific plaintext access. + - **Location**: Directly accessible from the frontend or the smart contract. + - **Role**: Used to encrypt plaintext data before submission to the blockchain or during contract execution. -3. **Evaluation Key**: - - **Location**: Stored on the coprocessor. +2. **Private Key**: + + - **Location**: Stored securely in the Key Management System (KMS). + - **Role**: Used for decrypting ciphertexts when necessary, either to verify results or enable user-specific plaintext access. + +3. **Evaluation Key**: + - **Location**: Stored on the coprocessor. - **Role**: Enables operations on ciphertexts (e.g., addition, multiplication) without decrypting them.
FHE Keys Overview
High level overview of the fhEVM Architecture
@@ -27,16 +29,17 @@ The fhEVM system ensures end-to-end confidentiality by leveraging Fully Homomorp ## **Workflow: Encryption, Decryption, and Processing** ### **1. Encryption** + Encryption is the starting point for any interaction with the fhEVM system, ensuring that data is protected before it is transmitted or processed. -- **How It Works**: - 1. The **frontend** or client application uses the **public key** to encrypt user-provided plaintext inputs. - 2. The encrypted data (ciphertext) is submitted to the blockchain as part of a transaction or stored for later computation. +- **How It Works**: -- **Data Flow**: - - **Source**: Frontend or smart contract. - - **Destination**: Blockchain (for storage and symbolic execution) or coprocessor (for processing). + 1. The **frontend** or client application uses the **public key** to encrypt user-provided plaintext inputs. + 2. The encrypted data (ciphertext) is submitted to the blockchain as part of a transaction or stored for later computation. +- **Data Flow**: + - **Source**: Frontend or smart contract. + - **Destination**: Blockchain (for storage and symbolic execution) or coprocessor (for processing).
re-encryption
@@ -45,41 +48,43 @@ You can read about the implemention details in [our encryption guide](../fundame --- ### **2. Computation** + Encrypted computations are performed using the **evaluation key** on the coprocessor. -- **How It Works**: - 1. The blockchain initiates symbolic execution, generating a set of operations to be performed on encrypted data. - 2. These operations are offloaded to the **coprocessor**, which uses the **evaluation key** to compute directly on the ciphertexts. - 3. The coprocessor returns updated ciphertexts to the blockchain for storage or further use. +- **How It Works**: + + 1. The blockchain initiates symbolic execution, generating a set of operations to be performed on encrypted data. + 2. These operations are offloaded to the **coprocessor**, which uses the **evaluation key** to compute directly on the ciphertexts. + 3. The coprocessor returns updated ciphertexts to the blockchain for storage or further use. - **Data Flow**: - - **Source**: Blockchain smart contracts (via symbolic execution). - - **Processing**: Coprocessor (using the evaluation key). - - **Destination**: Blockchain (updated ciphertexts). + - **Source**: Blockchain smart contracts (via symbolic execution). + - **Processing**: Coprocessor (using the evaluation key). + - **Destination**: Blockchain (updated ciphertexts).
computation
--- ### **3. Decryption** + Decryption is used when plaintext results are required for contract logic or for presentation to a user. After the decryption in preformed on the blockchain, the decrypted result is exposed to everyone who has access to the blockchain.
decryption
- **How it works**: - Validators on the blockchain do not possess the private key needed for decryption. Instead, the **Key Management System (KMS)** securely holds the private key. If plaintext values are needed, the process is facilitated by a service called the **Gateway**, which provides two options: - - 1. **For Smart Contract Logic**: - The Gateway acts as an oracle service, listening for decryption request events emitted by the blockchain. Upon receiving such a request, the Gateway interacts with the KMS to decrypt the ciphertext and sends the plaintext back to the smart contract via a callback function. + Validators on the blockchain do not possess the private key needed for decryption. Instead, the **Key Management System (KMS)** securely holds the private key. If plaintext values are needed, the process is facilitated by a service called the **Gateway**, which provides two options: + + 1. **For Smart Contract Logic**: + The Gateway acts as an oracle service, listening for decryption request events emitted by the blockchain. Upon receiving such a request, the Gateway interacts with the KMS to decrypt the ciphertext and sends the plaintext back to the smart contract via a callback function. - 2. **For dApps**: + 2. **For dApps**: If a dApp needs plaintext values, the Gateway enables re-encryption of the ciphertext. The KMS securely re-encrypts the ciphertext with the dApp's public key, ensuring that only the dApp can decrypt and access the plaintext. - **Data flow**: - - **Source**: Blockchain or dApp (ciphertext). - - **Processing**: KMS performs decryption or re-encryption via the Gateway. - - **Destination**: Plaintext is either sent to the smart contract or re-encrypted and delivered to the dApp. - + - **Source**: Blockchain or dApp (ciphertext). + - **Processing**: KMS performs decryption or re-encryption via the Gateway. + - **Destination**: Plaintext is either sent to the smart contract or re-encrypted and delivered to the dApp.
re-encryption
re-encryption
@@ -91,26 +96,28 @@ You can read about the implemention details in [our decryption guide](../fundame Re-encryption enables encrypted data to be securely shared or reused under a different encryption key without ever revealing the plaintext. This process is essential for scenarios where data needs to be accessed by another contract, dApp, or user while maintaining confidentiality. - #### How it works -Re-encryption is facilitated by the **Gateway** in collaboration with the **Key Management System (KMS)**: -1. The Gateway receives a re-encryption request, which includes details of the original ciphertext and the target public key. -2. The KMS securely decrypts the ciphertext using its private key and re-encrypts the data with the recipient's public key. +Re-encryption is facilitated by the **Gateway** in collaboration with the **Key Management System (KMS)**: + +1. The Gateway receives a re-encryption request, which includes details of the original ciphertext and the target public key. +2. The KMS securely decrypts the ciphertext using its private key and re-encrypts the data with the recipient's public key. 3. The re-encrypted ciphertext is then sent to the intended recipient. --- #### Data flow -1. **source**: - - The process starts with an original ciphertext retrieved from the blockchain or a dApp. +1. **source**: + + - The process starts with an original ciphertext retrieved from the blockchain or a dApp. + +2. **processing**: -2. **processing**: - - The Gateway forwards the re-encryption request to the KMS. + - The Gateway forwards the re-encryption request to the KMS. - The KMS handles decryption and re-encryption using the appropriate keys. -3. **destination**: +3. **destination**: - The re-encrypted ciphertext is delivered to the target entity, such as a dApp, user, or another contract.
re-encryption
re-encryption process
@@ -121,44 +128,43 @@ Re-encryption is facilitated by the **Gateway** in collaboration with the **Key Re-encryption is initiated on the client side via the **Gateway service** using the [`fhevmjs`](https://github.com/zama-ai/fhevmjs/) library. Here’s the general workflow: -1. **Retrieve the ciphertext**: +1. **Retrieve the ciphertext**: + - The dApp calls a view function (e.g., `balanceOf`) on the smart contract to get the handle of the ciphertext to be re-encrypted. -2. **Generate and sign a keypair**: - - The dApp generates a keypair for the user. +2. **Generate and sign a keypair**: + + - The dApp generates a keypair for the user. - The user signs the public key to ensure authenticity. -3. **Submit re-encryption request**: - - The dApp calls the Gateway, providing the following information: - - The ciphertext handle. - - The user’s public key. - - The user’s address. - - The smart contract address. - - The user’s signature. +3. **Submit re-encryption request**: -4. **Decrypt the re-encrypted ciphertext**: - - The dApp receives the re-encrypted ciphertext from the Gateway. - - The dApp decrypts the ciphertext locally using the private key. + - The dApp calls the Gateway, providing the following information: + - The ciphertext handle. + - The user’s public key. + - The user’s address. + - The smart contract address. + - The user’s signature. +4. **Decrypt the re-encrypted ciphertext**: + - The dApp receives the re-encrypted ciphertext from the Gateway. + - The dApp decrypts the ciphertext locally using the private key.
re-encryption
re-encryption
- You can read [our guide explaining how to use it](../fundamentals/first_step/reencryption.md). - - --- ## **Tying It All Together** The flow of information across the fhEVM components during these operations highlights how the system ensures privacy while maintaining usability: -| **Operation** | **Keys Used** | **Flow of Information** | -|-------------------|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **Encryption** | Public Key | Frontend encrypts plaintext → Ciphertext submitted to blockchain or coprocessor. | -| **Computation** | Evaluation Key | Blockchain initiates computation → Coprocessor processes ciphertext using evaluation key → Updated ciphertext returned to blockchain. | -| **Decryption** | Private Key | Blockchain or Gateway sends ciphertext to KMS → KMS decrypts using private key → Plaintext returned to authorized requester (e.g., frontend or specific user). | +| **Operation** | **Keys Used** | **Flow of Information** | +| ----------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Encryption** | Public Key | Frontend encrypts plaintext → Ciphertext submitted to blockchain or coprocessor. | +| **Computation** | Evaluation Key | Blockchain initiates computation → Coprocessor processes ciphertext using evaluation key → Updated ciphertext returned to blockchain. | +| **Decryption** | Private Key | Blockchain or Gateway sends ciphertext to KMS → KMS decrypts using private key → Plaintext returned to authorized requester (e.g., frontend or specific user). | | **Re-encryption** | Private and Target Keys | Blockchain or Gateway sends ciphertext to KMS → KMS re-encrypts using private key and target key → Updated ciphertext returned to blockchain, frontend, or other contract/user. | -This architecture ensures that sensitive data remains encrypted throughout its lifecycle, with decryption or re-encryption only occurring in controlled, secure environments. By separating key roles and processing responsibilities, fhEVM provides a scalable and robust framework for private smart contracts. \ No newline at end of file +This architecture ensures that sensitive data remains encrypted throughout its lifecycle, with decryption or re-encryption only occurring in controlled, secure environments. By separating key roles and processing responsibilities, fhEVM provides a scalable and robust framework for private smart contracts. diff --git a/docs/fundamentals/first_step/acl_examples.md b/docs/fundamentals/first_step/acl_examples.md index 60e8208c..9bbeb9b6 100644 --- a/docs/fundamentals/first_step/acl_examples.md +++ b/docs/fundamentals/first_step/acl_examples.md @@ -1,32 +1,36 @@ -# implementing access control with acl +# Implementing access control with acl This page provides detailed instructions and examples on how to use and implement the ACL (Access Control List) in fhEVM. For an overview of ACL concepts and their importance, refer to the [access control list (ACL) overview](../acl.md). --- -## controlling access: permanent and transient allowances +## Controlling access: permanent and transient allowances The ACL system allows you to define two types of permissions for accessing ciphertexts: -### permanent allowance -- **Function**: `TFHE.allow(ciphertext, address)` -- **Purpose**: Grants persistent access to a ciphertext for a specific address. -- **Storage**: Permissions are saved in a dedicated ACL contract, making them available across transactions. +### Permanent allowance -### transient allowance -- **Function**: `TFHE.allowTransient(ciphertext, address)` -- **Purpose**: Grants temporary access for the duration of a single transaction. -- **Storage**: Permissions are stored in transient storage to save gas costs. +- **Function**: `TFHE.allow(ciphertext, address)` +- **Purpose**: Grants persistent access to a ciphertext for a specific address. +- **Storage**: Permissions are saved in a dedicated ACL contract, making them available across transactions. + +### Transient allowance + +- **Function**: `TFHE.allowTransient(ciphertext, address)` +- **Purpose**: Grants temporary access for the duration of a single transaction. +- **Storage**: Permissions are stored in transient storage to save gas costs. - **Use Case**: Ideal for passing encrypted values between functions or contracts during a transaction. -### syntactic sugar -- **Function**: `TFHE.allowThis(ciphertext)` -- **Equivalent To**: `TFHE.allow(ciphertext, address(this))` +### Syntactic sugar + +- **Function**: `TFHE.allowThis(ciphertext)` +- **Equivalent To**: `TFHE.allow(ciphertext, address(this))` - **Purpose**: Simplifies granting permanent access to the current contract for managing ciphertexts. --- ### Example: granting permissions in a multi-contract setup + ```solidity import "fhevm/lib/TFHE.sol"; @@ -75,14 +79,15 @@ contract SecretStore { Some functions automatically grant transient allowances to the calling contract, simplifying workflow. These include: -- **Type Conversion**: - - `TFHE.asEuintXX()`, `TFHE.asEbool()`, `TFHE.asEaddress()` -- **Random Value Generation**: - - `TFHE.randXX()` -- **Computation Results**: - - `TFHE.add()`, `TFHE.select()` +- **Type Conversion**: + - `TFHE.asEuintXX()`, `TFHE.asEbool()`, `TFHE.asEaddress()` +- **Random Value Generation**: + - `TFHE.randXX()` +- **Computation Results**: + - `TFHE.add()`, `TFHE.select()` + +### Example: random value generation -### example: random value generation ```solidity function randomize() public { // Generate a random encrypted value with transient allowance @@ -98,9 +103,26 @@ function randomize() public { ## Security best practices ### Verifying sender access -When receiving ciphertexts as input, always verify that the sender is authorized to access them. Use the `TFHE.isSenderAllowed()` function to enforce this check. + +When processing ciphertexts as input, it’s essential to validate that the sender is authorized to interact with the provided encrypted data. Failing to perform this verification can expose the system to inference attacks where malicious actors attempt to deduce private information. + +#### Example scenario: Encrypted ERC20 attack + +Consider an **Encrypted ERC20 token**. An attacker controlling two accounts, **Account A** and **Account B**, with 100 tokens in Account A, could exploit the system as follows: + +1. The attacker attempts to send the target user's encrypted balance from **Account A** to **Account B**. +2. Observing the transaction outcome, the attacker gains information: + - **If successful**: The target's balance is equal to or less than 100 tokens. + - **If failed**: The target's balance exceeds 100 tokens. + +This type of attack allows the attacker to infer private balances without explicit access. + +To prevent this, always use the `TFHE.isSenderAllowed()` function to verify that the sender has legitimate access to the encrypted amount being transferred. + +--- #### Example: secure verification + ```solidity function transfer(address to, euint64 encryptedAmount, bytes calldata inputProof) public { // Ensure the sender is authorized to access the encrypted amount @@ -112,14 +134,16 @@ function transfer(address to, euint64 encryptedAmount, bytes calldata inputProof } ``` +By enforcing this check, you can safeguard against inference attacks and ensure that encrypted values are only manipulated by authorized entities. + ## ACL for reencryption -If a ciphertext must be reencrypted by a user, then explicit access must be granted to them. If this authorization is not given, the user will be unable to request a reencryption of this ciphertext. +If a ciphertext can be reencrypted by a user, explicit access must be granted to them. Additionally, the reencryption mechanism requires the signature of a public key associated with the contract address. Therefore, a value that needs to be reencrypted must be explicitly authorized for both the user and the contract. Due to the reencryption mechanism, a user signs a public key associated with a specific contract; therefore, the ciphertext also needs to be allowed for the contract. - ### Example: Secure Transfer in Encrypted ERC-20 + ```solidity function transfer(address to, euint64 encryptedAmount) public { require(TFHE.isSenderAllowed(encryptedAmount), "The caller is not authorized to access this encrypted amount."); @@ -142,4 +166,4 @@ function transfer(address to, euint64 encryptedAmount) public { --- -By understanding how to grant and verify permissions, you can effectively manage access to encrypted data in your fhEVM smart contracts. For additional context, see the [ACL overview](../acl.md). \ No newline at end of file +By understanding how to grant and verify permissions, you can effectively manage access to encrypted data in your fhEVM smart contracts. For additional context, see the [ACL overview](../acl.md). diff --git a/docs/fundamentals/first_step/configure.md b/docs/fundamentals/first_step/configure.md index 16976eed..7738bd96 100644 --- a/docs/fundamentals/first_step/configure.md +++ b/docs/fundamentals/first_step/configure.md @@ -1,10 +1,10 @@ -# Configuring your smart contract for encrypted computations +# Configuring your smart contract for encrypted computations This document describes how to enable encrypted computations in your smart contract by setting up the `fhEVM` environment. This involves configuring essential functions and integrating specific libraries to handle encrypted data securely and efficiently. --- -## Workflow for writing confidential smart contracts +## Workflow for writing confidential smart contracts 1. **Use the Hardhat Template**: Start with our custom [`fhevm-hardhat-template` repository](https://github.com/zama-ai/fhevm-hardhat-template). Hardhat is a powerful development environment for Solidity, allowing you to write, test, and deploy contracts to the `fhEVM` using TypeScript. @@ -13,50 +13,56 @@ This document describes how to enable encrypted computations in your smart contr Develop your contract as if it were intended for a traditional EVM chain. Use cleartext variables and basic logic, which simplifies reasoning about the contract’s functionality. 3. **Add Encryption**: - Integrate the `TFHE` Solidity library to enable encryption. Convert sensitive variables (e.g., `uintX`) into encrypted types (e.g., `euintX`) to ensure confidentiality. Refer to the [pitfalls to avoid and best practices](../../guides/pitfalls.md) guide for detailed advice. - For inspiration, check out the examples in the [`fhevm` contracts repository](https://github.com/zama-ai/fhevm-contracts). + Integrate the `TFHE` Solidity library to enable encryption. Convert sensitive variables (e.g., `uintX`) into encrypted types (e.g., `euintX`) to ensure confidentiality. Refer to the [pitfalls to avoid and best practices](../../guides/pitfalls.md) guide for detailed advice. + +4. **Leverage Example Templates**: + The [fhevm-contracts repository](https://github.com/zama-ai/fhevm-contracts) provides a collection of example smart contracts demonstrating common FHE patterns and best practices. Use these templates to: + - Study proven implementation patterns + - Understand gas optimization techniques + - Learn how to properly handle encrypted operations + - See real-world examples of confidential smart contracts --- -## Core configuration functions +## Core configuration functions Below are the key configuration functions needed to enable encrypted operations in your contract. -### `setFHEVM` +### `setFHEVM` -This function initializes the FHEVM environment with the required configuration. +This function initializes the FHEVM environment with the required configuration. ```solidity function setFHEVM(FHEVMConfig.FHEVMConfigStruct memory fhevmConfig) public -``` +``` -- **Purpose**: Sets encryption parameters, including cryptographic keys and supported ciphertext types. -- **Usage**: Call this function in the constructor to ensure proper initialization. -- **Default Configuration**: Use `FHEVMConfig.defaultConfig()` for a standard encryption setup. +- **Purpose**: Sets encryption parameters, including cryptographic keys and supported ciphertext types. +- **Usage**: Call this function in the constructor to ensure proper initialization. +- **Default Configuration**: Use `FHEVMConfig.defaultConfig()` for a standard encryption setup. -#### Example +#### Example ```solidity constructor() { - // Initialize the FHEVM environment with default settings - TFHE.setFHEVM(FHEVMConfig.defaultConfig()); + // Initialize the FHEVM environment with default settings + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); } -``` +``` --- -### `isInitialized` +### `isInitialized` -This utility function verifies whether a given encrypted variable is initialized. +This utility function verifies whether a given encrypted variable is initialized. ```solidity function isInitialized(T v) internal pure returns (bool) -``` +``` -- **Purpose**: Prevents uninitialized encrypted variables from being used, avoiding unexpected behavior. -- **Usage**: Use this check in critical functions or constructors. +- **Purpose**: Prevents uninitialized encrypted variables from being used, avoiding unexpected behavior. +- **Usage**: Use this check in critical functions or constructors. -#### Example +#### Example ```solidity require(TFHE.isInitialized(counter), "Counter not initialized!"); @@ -64,27 +70,27 @@ require(TFHE.isInitialized(counter), "Counter not initialized!"); --- -### `setGateway` +### `setGateway` -When performing decryption or re-encryption, you must configure the contract to interact with the `Gateway`. +When performing decryption or re-encryption, you must configure the contract to interact with the `Gateway`. ```solidity Gateway.setGateway(Gateway.defaultGatewayAddress()); -``` +``` The Gateway serves as the bridge between the blockchain, coprocessor, and KMS for secure cryptographic operations. -#### Example +#### Example ```solidity import "fhevm/lib/TFHE.sol"; import "fhevm/gateway/GatewayCaller.sol"; contract Test is GatewayCaller { - constructor() { - // Set up the FHEVM and Gateway configurations - TFHE.setFHEVM(FHEVMConfig.defaultConfig()); - Gateway.setGateway(Gateway.defaultGatewayAddress()); - } + constructor() { + // Set up the FHEVM and Gateway configurations + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); + Gateway.setGateway(Gateway.defaultGatewayAddress()); + } } -``` \ No newline at end of file +``` diff --git a/docs/fundamentals/first_step/decrypt.md b/docs/fundamentals/first_step/decrypt.md index 755288a9..9f30cd10 100644 --- a/docs/fundamentals/first_step/decrypt.md +++ b/docs/fundamentals/first_step/decrypt.md @@ -4,23 +4,23 @@ As a continuation of your journey in writing confidential smart contracts, this > **_NOTE:_** Understanding how encryption, decryption and reencryption works is a prerequisit before implementation, see [Encryption, Decryption, Re-encryption, and Computation](../d_re_ecrypt_compute.md) -# decryption: accessing encrypted data securely +# decryption: accessing encrypted data securely -As a continuation of your journey in writing confidential smart contracts, 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. +As a continuation of your journey in writing confidential smart contracts, 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. --- ## When to use decryption? Decryption is essential in two primary cases: -1. **Smart Contract Logic**: A contract requires plaintext values for computations or decision-making. + +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) - ## 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. @@ -59,22 +59,22 @@ contract TestAsyncDecrypt is GatewayCaller { } ``` -### Key additions to the code +### Key additions to the code 1. **`GatewayCaller` import**: - The `GatewayCaller` contract is imported to enable decryption requests. + The `GatewayCaller` contract is imported to enable decryption requests. ```solidity import "fhevm/gateway/GatewayCaller.sol"; ``` 2. **`Gateway.setGateway` function**: - This function sets the address of the Gateway contract, which processes decryption requests. It is typically called in the constructor: + This function sets the address of the Gateway contract, which processes decryption requests. It is typically called in the constructor: ```solidity constructor() { - TFHE.setFHEVM(FHEVMConfig.defaultConfig()); - Gateway.setGateway(Gateway.defaultGatewayAddress()); + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); + Gateway.setGateway(Gateway.defaultGatewayAddress()); } ``` @@ -138,18 +138,16 @@ contract EncryptedCounter3 is GatewayCaller { ``` - ## Tests for `EncryptedCounter3` Here’s a sample test for the Encrypted Counter contract using Hardhat: ```ts -import { expect } from "chai"; -import { ethers } from "hardhat"; - import { awaitAllDecryptionResults, initGateway } from "../asyncDecrypt"; import { createInstances } from "../instance"; import { getSigners, initSigners } from "../signers"; +import { expect } from "chai"; +import { ethers } from "hardhat"; describe("EncryptedCounter3", function () { before(async function () { @@ -187,32 +185,33 @@ describe("EncryptedCounter3", function () { expect(decryptedValue).to.equal(5); }); }); - ``` -### Key additions in testing +### Key additions in testing + +1. **Initialize the Gateway**: -1. **Initialize the Gateway**: ```typescript await initGateway(); // Initialize the gateway for decryption ``` -2. **Request decryption and wait for results**: +2. **Request decryption and wait for results**: + ```typescript const decryptTx = await this.counterContract.requestDecryptCounter({ gasLimit: 5_000_000 }); await decryptTx.wait(); await awaitAllDecryptionResults(); ``` -3. **Verify the decrypted value**: +3. **Verify the decrypted value**: ```typescript const decryptedValue = await this.counterContract.getDecryptedCounter(); expect(decryptedValue).to.equal(5); ``` +## Next steps -## Next steps +Explore advanced decryption techniques and learn more about re-encryption: -Explore advanced decryption techniques and learn more about re-encryption: -- [Decryption in Depth](./decrypt_details.md) -- [Re-encryption](./reencryption.md) +- [Decryption in Depth](./decrypt_details.md) +- [Re-encryption](./reencryption.md) diff --git a/docs/fundamentals/first_step/decrypt_details.md b/docs/fundamentals/first_step/decrypt_details.md index 17c3b502..7dc6f040 100644 --- a/docs/fundamentals/first_step/decrypt_details.md +++ b/docs/fundamentals/first_step/decrypt_details.md @@ -4,7 +4,7 @@ This document provides a detailed guide on implementing decryption in your smart ## `GatewayContract` set up -The [`GatewayContract`](https://github.com/zama-ai/fhevm/blob/main/gateway/GatewayContract.sol) 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 [`GatewayContract`](../../../gateway/GatewayContract.sol) 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. Relayers are the only accounts authorized to fulfill decryption requests. The role of the `GatewayContract`, however, is to independently verify the KMS signature during execution. This ensures that the relayers cannot manipulate or send fraudulent decryption results, even if compromised. However, the relayers are still trusted to forward decryption requests on time. diff --git a/docs/fundamentals/first_step/inputs.md b/docs/fundamentals/first_step/inputs.md index 599e5220..433fd044 100644 --- a/docs/fundamentals/first_step/inputs.md +++ b/docs/fundamentals/first_step/inputs.md @@ -4,19 +4,18 @@ This document introduces the concept of encrypted inputs in the fhEVM, explainin > **_NOTE:_** Understanding how encryption, decryption and reencryption works is a prerequisit before implementation, see [Encryption, Decryption, Re-encryption, and Computation](../d_re_ecrypt_compute.md) -Encrypted inputs are a core feature of fhEVM, enabling users to push encrypted data onto the blockchain while ensuring data confidentiality and integrity. - +Encrypted inputs are a core feature of fhEVM, enabling users to push encrypted data onto the blockchain while ensuring data confidentiality and integrity. ## What Are Encrypted Inputs? Encrypted inputs are data values submitted by users in ciphertext form. These inputs allow sensitive information to remain confidential while still being processed by smart contracts. They are accompanied by **Zero-Knowledge Proofs of Knowledge (ZKPoKs)** to ensure the validity of the encrypted data without revealing the plaintext. ### **Key Characteristics of Encrypted Inputs**: + 1. **Confidentiality**: Data is encrypted using the public FHE key, ensuring that only authorized parties can decrypt or process the values. 2. **Validation via ZKPoKs**: Each encrypted input is accompanied by a proof verifying that the user knows the plaintext value of the ciphertext, preventing replay attacks or misuse. 3. **Efficient Packing**: All inputs for a transaction are packed into a single ciphertext in a user-defined order, optimizing the size and generation of the zero-knowledge proof. - ## Parameters in Encrypted Functions When a function in a smart contract is called, it may accept two types of parameters for encrypted inputs: @@ -42,7 +41,6 @@ function myExample( In this example, `param1`, `param2`, and `param3` are encrypted inputs, while `inputProof` contains the corresponding ZKPoK to validate their authenticity. - ## Client-Side Implementation To interact with such a function, developers can use the [fhevmjs](https://github.com/zama-ai/fhevmjs) library to create and manage encrypted inputs. Below is an example implementation: @@ -72,6 +70,7 @@ contract.myExample( ``` In this example: + - **`add64`, `addBool`, and `add8`**: Specify the types and values of inputs to encrypt. - **`encrypt`**: Generates the encrypted inputs and the zero-knowledge proof. @@ -80,6 +79,7 @@ In this example: Smart contracts process encrypted inputs by verifying them against the associated zero-knowledge proof. This is done using the `TFHE.asEuintXX`, `TFHE.asEbool`, or `TFHE.asEaddress` functions, which validate the input and convert it into the appropriate encrypted type. ### Example Validation that goes along the Client-Side implementation + This example demonstrates a function that performs multiple encrypted operations, such as updating a user's encrypted balance and toggling an encrypted boolean flag: ```solidity @@ -112,6 +112,7 @@ This example demonstrates a function that performs multiple encrypted operations ``` ### Example Validation in the `encyrptedERC20.sol` Smart Contract + Here’s an example of a smart contract function that verifies an encrypted input before proceeding: ```solidity @@ -129,21 +130,22 @@ function transfer( ``` ### How validation works + 1. **Input Verification**: - The `TFHE.asEuintXX` function ensures that the input is a valid ciphertext with a corresponding ZKPoK. + The `TFHE.asEuintXX` function ensures that the input is a valid ciphertext with a corresponding ZKPoK. 2. **Type Conversion**: The function transforms the `einput` into the appropriate encrypted type (`euintXX`, `ebool`, etc.) for further operations within the contract. + --- ## **Best Practices** -- **Input Packing**: Minimize the size and complexity of zero-knowledge proofs by packing all encrypted inputs into a single ciphertext. -- **Frontend Encryption**: Always encrypt inputs using the FHE public key on the client side to ensure data confidentiality. -- **Proof Management**: Ensure that the correct zero-knowledge proof is associated with each encrypted input to avoid validation errors. +- **Input Packing**: Minimize the size and complexity of zero-knowledge proofs by packing all encrypted inputs into a single ciphertext. +- **Frontend Encryption**: Always encrypt inputs using the FHE public key on the client side to ensure data confidentiality. +- **Proof Management**: Ensure that the correct zero-knowledge proof is associated with each encrypted input to avoid validation errors. Encrypted inputs and their validation form the backbone of secure and private interactions in the fhEVM. By leveraging these tools, developers can create robust, privacy-preserving smart contracts without compromising functionality or scalability. - ## Upgrade of our Counter contract Now that we have new knowledge on how to add encrypted inputs, let's upgrade our counter contract. @@ -159,33 +161,32 @@ import "fhevm/lib/TFHE.sol"; /// @dev Uses TFHE library for fully homomorphic encryption operations /// @custom:experimental This contract is experimental and uses FHE technology contract EncryptedCounter2 { - euint8 counter; - - constructor() { - TFHE.setFHEVM(FHEVMConfig.defaultConfig()); - - // Initialize counter with an encrypted zero value - counter = TFHE.asEuint8(0); - TFHE.allowThis(counter); - } - - function incrementBy(einput amount, bytes calldata inputProof) public { - // Convert input to euint8 and add to counter - euint8 incrementAmount = TFHE.asEuint8(amount, inputProof); - counter = TFHE.add(counter, incrementAmount); - TFHE.allowThis(counter); - } + euint8 counter; + + constructor() { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); + + // Initialize counter with an encrypted zero value + counter = TFHE.asEuint8(0); + TFHE.allowThis(counter); + } + + function incrementBy(einput amount, bytes calldata inputProof) public { + // Convert input to euint8 and add to counter + euint8 incrementAmount = TFHE.asEuint8(amount, inputProof); + counter = TFHE.add(counter, incrementAmount); + TFHE.allowThis(counter); + } } ``` ### Tests of for the Counter contract ```ts -import { expect } from "chai"; -import { ethers } from "hardhat"; - import { createInstances } from "../instance"; import { getSigners, initSigners } from "../signers"; +import { expect } from "chai"; +import { ethers } from "hardhat"; describe("EncryptedCounter2", function () { before(async function () { @@ -212,7 +213,6 @@ describe("EncryptedCounter2", function () { await tx.wait(); }); }); - ``` ### How it works @@ -222,6 +222,7 @@ The `EncryptedCounter2` contract builds on the previous example by adding suppor 1. **Encrypted State**: Like before, the contract maintains an encrypted counter state variable of type `euint8`. 2. **Encrypted Input Handling**: The `incrementBy` function accepts two parameters: + - `einput amount`: An encrypted input handle representing the increment value - `bytes calldata inputProof`: The zero-knowledge proof validating the encrypted input @@ -230,12 +231,11 @@ The `EncryptedCounter2` contract builds on the previous example by adding suppor - This conversion validates the proof and creates a usable encrypted value - The value is then added to the counter using homomorphic addition - ### 👀 Can you spot a problem with this contract? -While we have resolved our problem with the Counter value visibility, there is still the problem with the Access Control for the `counter`. +While we have resolved our problem with the Counter value visibility, there is still the problem with the Access Control for the `counter`. 1. **Access Control for `counter`**: - The counter is encrypted, but no access is granted to decrypt or view its value. Without proper ACL permissions, the counter remains inaccessible to users. To resolve this, refer to: - - [decryption](./decrypt.md) + The counter is encrypted, but no access is granted to decrypt or view its value. Without proper ACL permissions, the counter remains inaccessible to users. To resolve this, refer to: + - [decryption](./decrypt.md) - [re-encryption](./reencryption.md) diff --git a/docs/fundamentals/first_step/operations.md b/docs/fundamentals/first_step/operations.md index de539022..95102377 100644 --- a/docs/fundamentals/first_step/operations.md +++ b/docs/fundamentals/first_step/operations.md @@ -3,18 +3,19 @@ This document outlines the operations supported on encrypted types in the `TFHE` library, enabling arithmetic, bitwise, comparison, and more on Fully Homomorphic Encryption (FHE) ciphertexts. ## Arithmetic operations + The following arithmetic operations are supported for encrypted integers (`euintX`): -| Name | Function name | Symbol | Type | -| ----------------------- | ------------------- | ------ | ------- | -| Add | `TFHE.add` | `+` | Binary | -| Subtract | `TFHE.sub` | `-` | Binary | -| Multiply | `TFHE.mul` | `*` | Binary | -| Divide (plaintext divisor) | `TFHE.div` | | Binary | -| Reminder (plaintext divisor) | `TFHE.rem` | | Binary | -| Negation | `TFHE.neg` | `-` | Unary | -| Min | `TFHE.min` | | Binary | -| Max | `TFHE.max` | | Binary | +| Name | Function name | Symbol | Type | +| ---------------------------- | ------------- | ------ | ------ | +| Add | `TFHE.add` | `+` | Binary | +| Subtract | `TFHE.sub` | `-` | Binary | +| Multiply | `TFHE.mul` | `*` | Binary | +| Divide (plaintext divisor) | `TFHE.div` | | Binary | +| Reminder (plaintext divisor) | `TFHE.rem` | | Binary | +| Negation | `TFHE.neg` | `-` | Unary | +| Min | `TFHE.min` | | Binary | +| Max | `TFHE.max` | | Binary | > **Note**: Division (TFHE.div) and remainder (TFHE.rem) operations are currently supported only with plaintext divisors. @@ -22,47 +23,48 @@ The following arithmetic operations are supported for encrypted integers (`euint The TFHE library also supports bitwise operations, including shifts and rotations: -| Name | Function name | Symbol | Type | -| ----------------------- | ------------------- | ------ | ------- | -| Bitwise AND | `TFHE.and` | `&` | Binary | -| Bitwise OR | `TFHE.or` | `\|` | Binary | -| Bitwise XOR | `TFHE.xor` | `^` | Binary | -| Bitwise NOT | `TFHE.not` | `~` | Unary | -| Shift Right | `TFHE.shr` | | Binary | -| Shift Left | `TFHE.shl` | | Binary | -| Rotate Right | `TFHE.rotr` | | Binary | -| Rotate Left | `TFHE.rotl` | | Binary | +| Name | Function name | Symbol | Type | +| ------------ | ------------- | ------ | ------ | +| Bitwise AND | `TFHE.and` | `&` | Binary | +| Bitwise OR | `TFHE.or` | `\|` | Binary | +| Bitwise XOR | `TFHE.xor` | `^` | Binary | +| Bitwise NOT | `TFHE.not` | `~` | Unary | +| Shift Right | `TFHE.shr` | | Binary | +| Shift Left | `TFHE.shl` | | Binary | +| Rotate Right | `TFHE.rotr` | | Binary | +| Rotate Left | `TFHE.rotl` | | Binary | {% hint style="info" %} - The shift operators `TFHE.shr` and `TFHE.shl` can take any encrypted type `euintX` as a first operand and either a `uint8`or a `euint8` as a second operand, however the second operand will always be computed modulo the number of bits of the first operand. For example, `TFHE.shr(euint64 x, 70)` is equivalent to `TFHE.shr(euint64 x, 6)` because `70 % 64 = 6`. This differs from the classical shift operators in Solidity, where there is no intermediate modulo operation, so for instance any `uint64` shifted right via `>>` would give a null result. - {% endhinr %} +The shift operators `TFHE.shr` and `TFHE.shl` can take any encrypted type `euintX` as a first operand and either a `uint8`or a `euint8` as a second operand, however the second operand will always be computed modulo the number of bits of the first operand. For example, `TFHE.shr(euint64 x, 70)` is equivalent to `TFHE.shr(euint64 x, 6)` because `70 % 64 = 6`. This differs from the classical shift operators in Solidity, where there is no intermediate modulo operation, so for instance any `uint64` shifted right via `>>` would give a null result. +{% endhinr %} ## Comparison operations + Encrypted integers can be compared using the following functions: -| Name | Function name | Symbol | Type | +| Name | Function name | Symbol | Type | | ----------------------- | ------------------- | ------ | ------- | -| Equal | `TFHE.eq` | | Binary | -| Not equal | `TFHE.ne` | | Binary | -| Greater than or equal | `TFHE.ge` | | Binary | -| Greater than | `TFHE.gt` | | Binary | -| Less than or equal | `TFHE.le` | | Binary | -| Less than | `TFHE.lt` | | Binary | +| Equal | `TFHE.eq` | | Binary | +| Not equal | `TFHE.ne` | | Binary | +| Greater than or equal | `TFHE.ge` | | Binary | +| Greater than | `TFHE.gt` | | Binary | +| Less than or equal | `TFHE.le` | | Binary | +| Less than | `TFHE.lt` | | Binary | -## Ternary operation +## Ternary operation The `TFHE.select` function is a ternary operation that selects one of two encrypted values based on an encrypted condition: -| Name | Function name | Symbol | Type | -| ----------------------- | ------------------- | ------ | ------- | -| Select | `TFHE.select` | | Ternary | +| Name | Function name | Symbol | Type | +| ------ | ------------- | ------ | ------- | +| Select | `TFHE.select` | | Ternary | ## Random operations You can generate cryptographically secure random numbers fully on-chain: -| **Name** | **Function Name** | **Symbol** | **Type** | -|-------------------------|-------------------------|------------|-----------| -| Random Unsigned Integer | `TFHE.randEuintX()` | | Random | +| **Name** | **Function Name** | **Symbol** | **Type** | +| ----------------------- | ------------------- | ---------- | -------- | +| Random Unsigned Integer | `TFHE.randEuintX()` | | Random | For more details, refer to the [Random Encrypted Numbers](../../guides/random.md) document. @@ -72,17 +74,17 @@ The `TFHE` library supports operator overloading for encrypted integers (e.g., ` > **Example**: > Overloaded operators make code more concise: + ```solidity euint64 a = TFHE.asEuint64(42); euint64 b = TFHE.asEuint64(58); euint64 sum = a + b; // Calls TFHE.add under the hood ``` - ## Additional Resources -- For detailed API specifications, visit the [fhEVM API Documentation](../../references/functions.md). -- Check our [Roadmap](../../developer/roadmap.md) for upcoming features or submit a feature request on [Discord](https://discord.com/invite/fhe-org). +- For detailed API specifications, visit the [fhEVM API Documentation](../../references/functions.md). +- Check our [Roadmap](../../developer/roadmap.md) for upcoming features or submit a feature request on [Discord](https://discord.com/invite/fhe-org). - Join the discussion on the [Community Forum](https://community.zama.ai/c/fhevm/15). --- @@ -91,4 +93,4 @@ euint64 sum = a + b; // Calls TFHE.add under the hood **Zama 5-Question Developer Survey** We want to hear from you! Take 1 minute to share your thoughts and helping us enhance our documentation and libraries. **👉** [**Click here**](https://www.zama.ai/developer-survey) to participate. -{% endhint %} \ No newline at end of file +{% endhint %} diff --git a/docs/fundamentals/first_step/reencryption.md b/docs/fundamentals/first_step/reencryption.md index 695b9ffa..63b8f46b 100644 --- a/docs/fundamentals/first_step/reencryption.md +++ b/docs/fundamentals/first_step/reencryption.md @@ -1,26 +1,27 @@ -# Re-encryption: sharing encrypted data securely +# Re-encryption: sharing encrypted data securely This document explains how to perform re-encryption. Re-encryption is required when you want a user to access their private data without it being exposed to the blockchain. -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. +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. -> **_NOTE:_** 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). +> **_NOTE:_** 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). -## When to use re-encryption +## When to use re-encryption Re-encryption is particularly useful in scenarios such as: + 1. **User Access**: Allowing individual users to securely access and read their encrypted private data, such as balances or counters. -## Overview +## Overview The re-encryption process involves retrieving ciphertext from the blockchain and performing re-encryption on the client-side. In other words we take the data that has been encrypted by the KMS, decrypt it and encrypt it with the users private key, so only he can access the information. 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: - 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. +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. ## Step 1: retrieve the ciphertext @@ -37,6 +38,7 @@ contract EncryptedERC20 { ... } ``` + Here, `balanceOf` allows retrieval of the user’s encrypted balance stored on the blockchain. ## Step 2: re-encrypt the ciphertext @@ -91,19 +93,19 @@ console.log(userBalance); This code retrieves the user’s encrypted balance, re-encrypts it with their public key, and decrypts it on the client-side using their private key. -### Key additions to the code +### Key additions to the code - 1. **`instance.generateKeypair()`**: Generates a public-private keypair for the user. +1. **`instance.generateKeypair()`**: Generates a public-private keypair for the user. - 2. **`instance.createEIP712(publicKey, CONTRACT_ADDRESS)`**: Creates an EIP712 object for signing the user’s public key. +2. **`instance.createEIP712(publicKey, CONTRACT_ADDRESS)`**: Creates an EIP712 object for signing the user’s public key. - 3. **`instance.reencrypt()`**: Facilitates the re-encryption process by contacting the Gateway and decrypting the data locally with the private key. +3. **`instance.reencrypt()`**: Facilitates the re-encryption process by contacting the Gateway and decrypting the data locally with the private key. -## Applying re-encryption to the counter example +## Applying re-encryption to the counter example Here’s an enhanced **Encrypted Counter** example where each user maintains their own encrypted counter. Re-encryption is used to securely share counter values with individual users. -### Encrypted counter with re-encryption +### Encrypted counter with re-encryption ```solidity // SPDX-License-Identifier: MIT @@ -117,39 +119,38 @@ import "fhevm/lib/TFHE.sol"; /// @custom:security Each user can only access and modify their own counter /// @custom:experimental This contract is experimental and uses FHE technology contract EncryptedCounter4 { - // Mapping from user address to their encrypted counter value - mapping(address => euint8) private counters; + // Mapping from user address to their encrypted counter value + mapping(address => euint8) private counters; - constructor() { - TFHE.setFHEVM(FHEVMConfig.defaultConfig()); - } + constructor() { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); + } - function incrementBy(einput amount, bytes calldata inputProof) public { - // Initialize counter if it doesn't exist - if (!TFHE.isInitialized(counters[msg.sender])) { - counters[msg.sender] = TFHE.asEuint8(0); - } - - // Convert input to euint8 and add to sender's counter - euint8 incrementAmount = TFHE.asEuint8(amount, inputProof); - counters[msg.sender] = TFHE.add(counters[msg.sender], incrementAmount); - TFHE.allowThis(counters[msg.sender]); - TFHE.allow(counters[msg.sender], msg.sender); + function incrementBy(einput amount, bytes calldata inputProof) public { + // Initialize counter if it doesn't exist + if (!TFHE.isInitialized(counters[msg.sender])) { + counters[msg.sender] = TFHE.asEuint8(0); } - function getCounter() public view returns (euint8) { - // Return the encrypted counter value for the sender - return counters[msg.sender]; - } -} + // Convert input to euint8 and add to sender's counter + euint8 incrementAmount = TFHE.asEuint8(amount, inputProof); + counters[msg.sender] = TFHE.add(counters[msg.sender], incrementAmount); + TFHE.allowThis(counters[msg.sender]); + TFHE.allow(counters[msg.sender], msg.sender); + } + function getCounter() public view returns (euint8) { + // Return the encrypted counter value for the sender + return counters[msg.sender]; + } +} ``` --- ### Frontend code of re-encryption / tests for EncryptedCounter4 -Here’s a sample test to verify re-encryption functionality: +Here’s a sample test to verify re-encryption functionality: ```ts import { expect } from "chai"; @@ -227,12 +228,13 @@ describe("EncryptedCounter4", function () { }); ``` + --- -### Key additions in testing +### Key additions in testing - 1. **`setupReencryption():`** Prepares the re-encryption process by generating keys and a signature for the user. +1. **`setupReencryption():`** Prepares the re-encryption process by generating keys and a signature for the user. - 2. **`instance.reencrypt():`** Facilitates re-encryption and local decryption of the data for testing purposes. +2. **`instance.reencrypt():`** Facilitates re-encryption and local decryption of the data for testing purposes. - 3. **Validation:** Confirms that the decrypted counter matches the expected value. +3. **Validation:** Confirms that the decrypted counter matches the expected value. diff --git a/docs/fundamentals/first_step/start.md b/docs/fundamentals/first_step/start.md index fdb20e54..ef8f555f 100644 --- a/docs/fundamentals/first_step/start.md +++ b/docs/fundamentals/first_step/start.md @@ -27,27 +27,26 @@ import "fhevm/lib/TFHE.sol"; /// @custom:notice This contract has limited real-world utility and serves primarily as a starting point /// for understanding how to implement basic FHE operations in Solidity contract EncryptedCounter1 { - euint8 counter; - euint8 CONST_ONE; - - constructor() { - TFHE.setFHEVM(FHEVMConfig.defaultConfig()); - - // Initialize counter with an encrypted zero value - counter = TFHE.asEuint8(0); - TFHE.allowThis(counter); - // Save on gas by computing the constant here - CONST_ONE = TFHE.asEuint8(1); - TFHE.allowThis(CONST_ONE); - } - - function increment() public { - // Perform encrypted addition to increment the counter - counter = TFHE.add(counter, CONST_ONE); - TFHE.allowThis(counter); - } + euint8 counter; + euint8 CONST_ONE; + + constructor() { + TFHE.setFHEVM(FHEVMConfig.defaultConfig()); + + // Initialize counter with an encrypted zero value + counter = TFHE.asEuint8(0); + TFHE.allowThis(counter); + // Save on gas by computing the constant here + CONST_ONE = TFHE.asEuint8(1); + TFHE.allowThis(CONST_ONE); + } + + function increment() public { + // Perform encrypted addition to increment the counter + counter = TFHE.add(counter, CONST_ONE); + TFHE.allowThis(counter); + } } - ``` ### How it works @@ -55,10 +54,11 @@ contract EncryptedCounter1 { 1. **Configuring fhevm**: The constructor initializes the FHEVM environment with a default configuration using `TFHE.setFHEVM(FHEVMConfig.defaultConfig())`. -2. **Initializing encrypted variables**: - - The `counter` variable is set to an encrypted `0` using `TFHE.asEuint8(0)`. - - Permissions are granted to the contract itself for the `counter` ciphertext using `TFHE.allowThis(counter)`. - - A constant `CONST_ONE` is initialized as an encrypted value to represent the number `1`. +2. **Initializing encrypted variables**: + + - The `counter` variable is set to an encrypted `0` using `TFHE.asEuint8(0)`. + - Permissions are granted to the contract itself for the `counter` ciphertext using `TFHE.allowThis(counter)`. + - A constant `CONST_ONE` is initialized as an encrypted value to represent the number `1`. 3. **Encrypted operations**: The `increment()` function adds the encrypted constant `CONST_ONE` to the `counter` using `TFHE.add`. @@ -68,22 +68,23 @@ contract EncryptedCounter1 { There are two notable issues with this contract: 1. **Counter Value Visibility**: - Since the counter is incremented by a fixed value, observers could deduce its value by analyzing blockchain events. To address this, see the documentation on: + Since the counter is incremented by a fixed value, observers could deduce its value by analyzing blockchain events. To address this, see the documentation on: + - [encryption and secure inputs](./inputs.md) 2. **Access Control for `counter`**: - The counter is encrypted, but no access is granted to decrypt or view its value. Without proper ACL permissions, the counter remains inaccessible to users. To resolve this, refer to: - - [decryption](./decrypt.md) + The counter is encrypted, but no access is granted to decrypt or view its value. Without proper ACL permissions, the counter remains inaccessible to users. To resolve this, refer to: + - [decryption](./decrypt.md) - [re-encryption](./reencryption.md) ## Your first tests + With any contracts that you write you will need to write tests as well. You can start by using something like this as a template: ```ts -import { ethers } from "hardhat"; - import { createInstances } from "../instance"; import { getSigners, initSigners } from "../signers"; +import { ethers } from "hardhat"; describe("EncryptedCounter1", function () { before(async function () { @@ -112,23 +113,26 @@ describe("EncryptedCounter1", function () { The test file demonstrates key concepts for testing fhEVM smart contracts: 1. **Test Setup**: + - `before`: Initializes test signers (users) that will interact with the contract - `beforeEach`: Deploys a fresh instance of the contract before each test - Creates FHE instances for each signer to handle encryption/decryption 2. **Test Structure**: + ```ts describe("Contract Name", function() { // Setup hooks before(async function() { ... }) - beforeEach(async function() { ... }) - + beforeEach(async function() { ... }) + // Individual test cases it("should do something", async function() { ... }) }); ``` 3. **Key Components**: + - `createInstances()`: Sets up FHE instances for each signer to handle encrypted operations - `getSigners()`: Provides test accounts to interact with the contract - `contractFactory.deploy()`: Creates a new contract instance for testing @@ -144,8 +148,8 @@ The test file demonstrates key concepts for testing fhEVM smart contracts: Congratulations! You’ve configured and written your first confidential smart contract. Here are some ideas to expand your knowledge: -- **Explore Advanced Configurations**: Customize the `FHEVMConfig` to suit specific encryption requirements. -- **Add Functionalities**: Extend the contract by adding decrement functionality or resetting the counter. +- **Explore Advanced Configurations**: Customize the `FHEVMConfig` to suit specific encryption requirements. +- **Add Functionalities**: Extend the contract by adding decrement functionality or resetting the counter. - **Integrate Frontend**: Learn how to decrypt and display encrypted data in a dApp using the `fhevmjs` library. -For more information, refer to the [fhEVM documentation](https://docs.zama.ai/fhevm). \ No newline at end of file +For more information, refer to the [fhEVM documentation](https://docs.zama.ai/fhevm). diff --git a/docs/fundamentals/first_step/types.md b/docs/fundamentals/first_step/types.md index 1216cc7b..db4c3a1e 100644 --- a/docs/fundamentals/first_step/types.md +++ b/docs/fundamentals/first_step/types.md @@ -7,7 +7,8 @@ This document introduces the encrypted integer types provided by the `TFHE` libr The `TFHE` library offers a robust type system with encrypted integer types, enabling secure computations on confidential data in smart contracts. These encrypted types are validated both at compile time and runtime to ensure correctness and security. ### Key features of encrypted types -- Encrypted integers function similarly to Solidity’s native integer types, but they operate on **Fully Homomorphic Encryption (FHE)** ciphertexts. + +- Encrypted integers function similarly to Solidity’s native integer types, but they operate on **Fully Homomorphic Encryption (FHE)** ciphertexts. - Arithmetic operations on `e(u)int` types are **unchecked**, meaning they wrap around on overflow. This design choice ensures confidentiality by avoiding the leakage of information through error detection. - Future versions of the `TFHE` library will support encrypted integers with overflow checking, but with the trade-off of exposing limited information about the operands. @@ -22,26 +23,26 @@ Encrypted integers in fhEVM are represented as FHE ciphertexts, abstracted using The `TFHE` library currently supports the following encrypted types: -| **Type** | **Supported** | -|------------------|---------------------| -| `ebool` | Yes | -| `euint4` | Yes | -| `euint8` | Yes | -| `euint16` | Yes | -| `euint32` | Yes | -| `euint64` | Yes | -| `euint128` | Yes | -| `euint256` | Yes | -| `eaddress` | Yes | -| `ebytes64` | Yes | -| `ebytes128` | Yes | -| `ebytes256` | Yes | -| `eint8` | No, coming soon | -| `eint16` | No, coming soon | -| `eint32` | No, coming soon | -| `eint64` | No, coming soon | -| `eint128` | No, coming soon | -| `eint256` | No, coming soon | +| **Type** | **Supported** | +| ----------- | --------------- | +| `ebool` | Yes | +| `euint4` | Yes | +| `euint8` | Yes | +| `euint16` | Yes | +| `euint32` | Yes | +| `euint64` | Yes | +| `euint128` | Yes | +| `euint256` | Yes | +| `eaddress` | Yes | +| `ebytes64` | Yes | +| `ebytes128` | Yes | +| `ebytes256` | Yes | +| `eint8` | No, coming soon | +| `eint16` | No, coming soon | +| `eint32` | No, coming soon | +| `eint64` | No, coming soon | +| `eint128` | No, coming soon | +| `eint256` | No, coming soon | > **Note** > Higher-precision integer types are available in the `TFHE-rs` library and can be added to `fhEVM` as needed. @@ -53,6 +54,7 @@ The `TFHE` library currently supports the following encrypted types: The `TFHE` library provides functions to cast between encrypted and unencrypted types, as well as between encrypted types of different precisions. Casting is handled using the `TFHE.asEuintXX()` or `TFHE.asEbool()` methods. ### Example: casting + ```solidity euint64 value64 = TFHE.asEuint64(7262); // Cast unencrypted uint64 to encrypted euint64 euint32 value32 = TFHE.asEuint32(value64); // Cast encrypted euint64 to euint32 @@ -60,15 +62,16 @@ ebool valueBool = TFHE.asEbool(value32); // Cast encrypted euint32 to ebool ``` ### Supported casting functions + The table below summarizes the available casting functions: -| **From Type** | **To Type** | **Function** | -|------------------|-------------------|------------------------| -| `uintX` | `euintX` | `TFHE.asEuintXX` | -| `euintX` | Higher precision | `TFHE.asEuintXX` | -| `euintX` | `ebool` | `TFHE.asEbool` | -| `address` | `eaddress` | `TFHE.asEaddress` | -| `bytesXX` | `ebytesXX` | `TFHE.asEbytesXX` | +| **From Type** | **To Type** | **Function** | +| ------------- | ---------------- | ----------------- | +| `uintX` | `euintX` | `TFHE.asEuintXX` | +| `euintX` | Higher precision | `TFHE.asEuintXX` | +| `euintX` | `ebool` | `TFHE.asEbool` | +| `address` | `eaddress` | `TFHE.asEaddress` | +| `bytesXX` | `ebytesXX` | `TFHE.asEbytesXX` | > **Tip** > Casting between encrypted types is efficient and often necessary when handling data with differing precision requirements. @@ -80,14 +83,17 @@ The table below summarizes the available casting functions: When using encrypted types as state variables in smart contracts, avoid declaring them with the `immutable` or `constant` keywords. This is because the `TFHE.asEuintXX()` method relies on a precompiled contract, making the value resolution at compile time infeasible. ### Best practices for declaration + Instead of using `immutable` or `constant`, declare and initialize encrypted state variables like this: #### Inline initialization + ```solidity euint64 private totalSupply = TFHE.asEuint64(0); ``` #### Initialization in constructor + ```solidity euint64 private totalSupply; @@ -105,9 +111,10 @@ constructor() { ## **Summary** The encrypted types in the `TFHE` library are designed to offer security and flexibility when working with confidential data in smart contracts. Key points to remember include: + - Encrypted integers operate as wrappers over FHE ciphertexts. - Arithmetic operations are unchecked to preserve confidentiality. - Type casting is straightforward, with extensive support for converting between encrypted types and unencrypted inputs. - Encrypted state variables must be initialized at runtime rather than using `immutable` or `constant`. -By following these guidelines and leveraging the flexibility of the `TFHE` library, developers can seamlessly integrate encrypted types into their smart contract workflows. \ No newline at end of file +By following these guidelines and leveraging the flexibility of the `TFHE` library, developers can seamlessly integrate encrypted types into their smart contract workflows. diff --git a/docs/getting_started/ethereum.md b/docs/getting_started/ethereum.md index d8598e4e..ab651002 100644 --- a/docs/getting_started/ethereum.md +++ b/docs/getting_started/ethereum.md @@ -4,13 +4,7 @@ Our testnet is up and running on Ethereum Sepolia. ## Network Information -| Fields | Value | -| ------------------ | --------------------------------------------- | -| Network | Ethereum Sepolia | -| RPC URL | `https://eth-sepolia.g.alchemy.com/v2/[API-KEY\]`| -| Chain ID | 11155111 | -| Currency symbol | ETH | -| Block explorer URL | https://sepolia.etherscan.io | +If you need access to a Sepolia node and aren’t sure how to proceed, consider using a node provider like Alchemy, Infura, or similar services. These providers offer easy setup and management, allowing you to create an API key to connect to the network seamlessly. ## Getting test ETH @@ -19,10 +13,15 @@ You can get test ETH for Sepolia from these faucets: - [Alchemy Sepolia Faucet](https://www.alchemy.com/faucets/ethereum-sepolia) - [QuickNode Sepolia Faucet](https://faucet.quicknode.com/ethereum/sepolia) -## Configuring MetaMask +## Configuring Sepolia on your wallet -Most networks, including Sepolia, are already configured in MetaMask. If you need to add it manually: +Most Ethereum wallets have built-in support for testnets like Sepolia. You can add Sepolia to your wallet in two ways: -1. Open MetaMask and click on the network dropdown -2. Click "Add Network" -3. Select "Sepolia" from the popular networks list or add manually using the network information above +1. **Automatic Configuration**: + Many wallets like MetaMask have Sepolia pre-configured. Simply open your network selector and choose "Show/hide test networks" to enable testnet visibility. + +2. **Manual Configuration**: The exact steps for manual configuration will vary by wallet, but generally involve: + 1. Opening network settings + 2. Selecting "Add Network" or "Add Network Manually" + 3. Filling in the above information + 4. Saving the configuration diff --git a/docs/getting_started/key_concepts.md b/docs/getting_started/key_concepts.md index ca1ddff0..87069055 100644 --- a/docs/getting_started/key_concepts.md +++ b/docs/getting_started/key_concepts.md @@ -3,6 +3,7 @@
## 1.1. Introduction + The Fully Homomorphic Ethereum Virtual Machine (fhEVM) is a groundbreaking protocol enabling **confidential smart contracts** on EVM-compatible blockchains. By leveraging Fully Homomorphic Encryption (FHE), fhEVM ensures complete data privacy without sacrificing composability or usability. ## 1.2. Table of Contents @@ -18,19 +19,21 @@ The Fully Homomorphic Ethereum Virtual Machine (fhEVM) is a groundbreaking proto - [1.4.4. Access control mechanism](#144-access-control-mechanism) - [1.5. Architectural overview](#15-architectural-overview) - ## 1.3. Core principles + The design of fhEVM is guided by the following principles: + 1. **Preserving Security**: No impact on the underlying blockchain's security guarantees. 2. **Public Verifiability**: All computations are publicly verifiable while keeping data confidential. 3. **Developer Accessibility**: Build confidential smart contracts using familiar Solidity tooling, without requiring cryptographic expertise. 4. **Composability**: Confidential smart contracts are fully interoperable with each other and public contracts. - ## 1.4. Key features ### 1.4.1. Encrypted data types + fhEVM introduces encrypted data types compatible with Solidity: + - **Booleans**: `ebool` - **Unsigned Integers**: `euint4`, `euint8`, `euint16`, `euint32`, `euint64`, `euint128`, `euint256` - **Addresses**: `eaddress` @@ -42,7 +45,9 @@ Encrypted data is represented as ciphertext handles, ensuring secure computation For more information see [use of encrypted types](../fundamentals/first_step/types.md). ### 1.4.2. Casting types + fhEVM provides functions to cast between encrypted types: + - **Casting between encrypted types**: `TFHE.asEbool` converts encrypted integers to encrypted booleans - **Casting to encrypted types**: `TFHE.asEuintX` converts plaintext values to encrypted types - **Casting to encrypted addresses**: `TFHE.asEaddress` converts plaintext addresses to encrypted addresses @@ -50,9 +55,10 @@ fhEVM provides functions to cast between encrypted types: For more information see [use of encrypted types](../fundamentals/first_step/types.md). - ### 1.4.3. Confidential computation + fhEVM enables symbolic execution of encrypted operations, supporting: + - Arithmetic: `TFHE.add`, `TFHE.sub`, `TFHE.mul`, `TFHE.min`, `TFHE.max`, `TFHE.neg`, `TFHE.div`, `TFHE.rem` - Note: `div` and `rem` operations are supported only with plaintext divisors - Bitwise: `TFHE.and`, `TFHE.or`, `TFHE.xor`, `TFHE.not`, `TFHE.shl`, `TFHE.shr`, `TFHE.rotl`, `TFHE.rotr` @@ -63,21 +69,22 @@ For more information on operations, see [Operations on encrypted types](../funda For more information on conditional branching, see [Conditional logic in FHE](../guides/conditions.md). For more information on random number generation, see [Generate Random Encrypted Numbers](../guides/random.md). - ### 1.4.4. Access control mechanism + fhEVM enforces access control with a blockchain-based Access Control List (ACL): + - **Persistent Access**: `TFHE.allow`, `TFHE.allowThis` grants permanent permissions for ciphertexts. - **Transient Access**: `TFHE.allowTransient` provides temporary access for specific transactions. - **Validation**: `TFHE.isSenderAllowed` ensures that only authorized entities can interact with ciphertexts. For more information see [ACL](../fundamentals/acl.md) - ## 1.5. Architectural overview -The fhEVM architecture provides the foundation for confidential smart contracts on EVM-compatible blockchains. At its core is Fully Homomorphic Encryption (FHE), a cryptographic technique enabling computations directly on encrypted data, ensuring privacy at every stage. This system relies on three key types: the **public key** (used for encrypting data), the **private key** (used for decryption and securely managed by the Key Management System or KMS), and the **evaluation key** (enabling encrypted computations performed by the coprocessor). +The fhEVM architecture provides the foundation for confidential smart contracts on EVM-compatible blockchains. At its core is Fully Homomorphic Encryption (FHE), a cryptographic technique enabling computations directly on encrypted data, ensuring privacy at every stage. This system relies on three key types: the **public key** (used for encrypting data), the **private key** (used for decryption and securely managed by the Key Management System or KMS), and the **evaluation key** (enabling encrypted computations performed by the coprocessor). The fhEVM leverages Zama's TFHE library, integrating seamlessly with blockchain environments to address transparency, composability, and scalability challenges. Its hybrid architecture combines: + - **On-chain smart contracts** for encrypted state management and access controls. - **Off-chain coprocessors** for resource-intensive FHE computations. - **The Gateway** to coordinate between blockchain, KMS, and coprocessors. @@ -85,4 +92,4 @@ The fhEVM leverages Zama's TFHE library, integrating seamlessly with blockchain This architecture enables developers to write private, composable smart contracts using symbolic execution and zero-knowledge proofs, ensuring data confidentiality and computational integrity. -For a detailed exploration of the fhEVM architecture, including components, workflows, and deployment models, see [Architecture Overview](../fundamentals/architecture_overview.md). \ No newline at end of file +For a detailed exploration of the fhEVM architecture, including components, workflows, and deployment models, see [Architecture Overview](../fundamentals/architecture_overview.md). diff --git a/docs/getting_started/repositories.md b/docs/getting_started/repositories.md index e49c6930..0b2bd364 100644 --- a/docs/getting_started/repositories.md +++ b/docs/getting_started/repositories.md @@ -8,14 +8,19 @@ Explore our curated list of repositories to jumpstart your FHE development, cont Quickly set up your development environment with these ready-to-use templates: -| **Repository** | **Description** | -|-------------------------------------------------------------------------------|-----------------------------------------------------------| -| [fhevm-contracts](https://github.com/zama-ai/fhevm-contracts) | Example FHE-enabled smart contracts | -| [fhevm-hardhat-template](https://github.com/zama-ai/fhevm-hardhat-template) | Hardhat template for FHE smart contract development | -| [fhevm-react-template](https://github.com/zama-ai/fhevm-react-template) | React.js template for building FHE dApps | -| [fhevm-next-template](https://github.com/zama-ai/fhevm-next-template) | Next.js template for FHE-enabled dApps | -| [fhevm-vue-template](https://github.com/zama-ai/fhevm-vue-template) | Vue.js template for developing FHE dApps | -| [fhevm-remix-plugin](https://github.com/zama-ai/fhevm-remix-plugin) | Remix IDE plugin for FHE development | +| **Repository** | **Description** | +| --------------------------------------------------------------------------- | --------------------------------------------------- | +| [fhevm-contracts](https://github.com/zama-ai/fhevm-contracts) | Example FHE-enabled smart contracts | +| [fhevm-hardhat-template](https://github.com/zama-ai/fhevm-hardhat-template) | Hardhat template for FHE smart contract development | +| [fhevm-react-template](https://github.com/zama-ai/fhevm-react-template) | React.js template for building FHE dApps | +| [fhevm-next-template](https://github.com/zama-ai/fhevm-next-template) | Next.js template for FHE-enabled dApps | +| [fhevm-vue-template](https://github.com/zama-ai/fhevm-vue-template) | Vue.js template for developing FHE dApps | + +## **IDE plugins** + +| **Repository** | **Description** | +| ------------------------------------------------------------------- | ------------------------------------ | +| [fhevm-remix-plugin](https://github.com/zama-ai/fhevm-remix-plugin) | Remix IDE plugin for FHE development | --- @@ -31,10 +36,10 @@ Contribute to the development of FHE technologies and earn rewards through Zama Access the essential libraries for building and integrating FHE-enabled applications: -| **Repository** | **Description** | -|-----------------------------------------------------------------|------------------------------------------------| -| [fhevm](https://github.com/zama-ai/fhevm/) | Solidity library for FHE operations | -| [fhevmjs](https://github.com/zama-ai/fhevmjs/) | JavaScript library for client-side FHE | +| **Repository** | **Description** | +| ---------------------------------------------- | -------------------------------------- | +| [fhevm](https://github.com/zama-ai/fhevm/) | Solidity library for FHE operations | +| [fhevmjs](https://github.com/zama-ai/fhevmjs/) | JavaScript library for client-side FHE | --- @@ -42,13 +47,12 @@ Access the essential libraries for building and integrating FHE-enabled applicat Explore the foundational implementations enabling FHE integration with blockchain systems: -| **Repository** | **Description** | -|------------------------------------------------------------------|--------------------------------------------------------------| -| [fhevm-go](https://github.com/zama-ai/fhevm-go/) | Go implementation of the FHE Virtual Machine | -| [go-ethereum](https://github.com/zama-ai/go-ethereum) | Fork of go-ethereum v1.10.19 with FHE capabilities | -| [zbc-go-ethereum](https://github.com/zama-ai/zbc-go-ethereum/) | Modified go-ethereum with enhanced FHE support | -| [evmos](https://github.com/zama-ai/evmos) | Fork of Evmos v9.1.0 with FHE features | +| **Repository** | **Description** | +| -------------------------------------------------------------- | -------------------------------------------------- | +| [fhevm-go](https://github.com/zama-ai/fhevm-go/) | Go implementation of the FHE Virtual Machine | +| [go-ethereum](https://github.com/zama-ai/go-ethereum) | Fork of go-ethereum v1.10.19 with FHE capabilities | +| [zbc-go-ethereum](https://github.com/zama-ai/zbc-go-ethereum/) | Modified go-ethereum with enhanced FHE support | --- -Use these repositories to accelerate your development, integrate FHE into your applications, or contribute to the growing ecosystem. For more resources and guides, refer to the [fhEVM Documentation](https://docs.zama.ai/fhevm). \ No newline at end of file +Use these repositories to accelerate your development, integrate FHE into your applications, or contribute to the growing ecosystem. For more resources and guides, refer to the [fhEVM Documentation](https://docs.zama.ai/fhevm). diff --git a/docs/getting_started/write_contract/hardhat.md b/docs/getting_started/write_contract/hardhat.md index b56e4aa8..a3e02095 100644 --- a/docs/getting_started/write_contract/hardhat.md +++ b/docs/getting_started/write_contract/hardhat.md @@ -10,7 +10,7 @@ To start writing smart contracts with fhEVM, we recommend using our [Hardhat tem This document guides you to start with fhEVM by using our [Hardhat template](https://github.com/zama-ai/fhevm-hardhat-template). -## Using hardhat with fhevm +## Using hardhat with fhEVM To start writing smart contracts with fhEVM, we recommend using our [Hardhat template](https://github.com/zama-ai/fhevm-hardhat-template). This template simplifies the development process by allowing you to launch an fhEVM Docker image and run your smart contracts on it. For more details, refer to the [README](https://github.com/zama-ai/fhevm-hardhat-template/blob/main/README.md). @@ -20,7 +20,8 @@ To start writing smart contracts with fhEVM, we recommend using our [Hardhat tem The Hardhat template comes pre-configured with tools and libraries to streamline the development process: -- **Frameworks and Libraries**: +- **Frameworks and Libraries**: + - [Hardhat](https://github.com/nomiclabs/hardhat): Compile, deploy, and test smart contracts. - [TypeChain](https://github.com/ethereum-ts/TypeChain): Generate TypeScript bindings for contracts. - [Ethers.js](https://github.com/ethers-io/ethers.js/): Ethereum library for interactions. @@ -40,11 +41,13 @@ The Hardhat template comes pre-configured with tools and libraries to streamline ### Prerequisites -1. **Install [pnpm](https://pnpm.io/installation)** for dependency management. +1. **Install [pnpm](https://pnpm.io/installation)** for dependency management. 2. **Set up a mnemonic**: Create a `.env` file by copying `.env.example`: + ```bash cp .env.example .env ``` + Generate a mnemonic using [this tool](https://iancoleman.io/bip39/) if needed. 3. **Install dependencies**: Ensure you’re using Node.js v20 or later: @@ -58,15 +61,15 @@ The Hardhat template comes pre-configured with tools and libraries to streamline Here’s a list of essential commands to work with the Hardhat template: -| **Command** | **Description** | -|-----------------------|-------------------------------------------------------------------------------------------------| -| `pnpm compile` | Compiles the smart contracts. | -| `pnpm typechain` | Compiles contracts and generates TypeChain bindings. | -| `pnpm test` | Runs tests locally in mocked mode, simulating FHE operations. | -| `pnpm lint:sol` | Lints Solidity code. | -| `pnpm lint:ts` | Lints TypeScript code. | -| `pnpm clean` | Cleans contract artifacts, cache, and coverage reports. | -| `pnpm coverage` | Analyzes test coverage (mocked mode only). | +| **Command** | **Description** | +| ---------------- | ------------------------------------------------------------- | +| `pnpm compile` | Compiles the smart contracts. | +| `pnpm typechain` | Compiles contracts and generates TypeChain bindings. | +| `pnpm test` | Runs tests locally in mocked mode, simulating FHE operations. | +| `pnpm lint:sol` | Lints Solidity code. | +| `pnpm lint:ts` | Lints TypeScript code. | +| `pnpm clean` | Cleans contract artifacts, cache, and coverage reports. | +| `pnpm coverage` | Analyzes test coverage (mocked mode only). | --- @@ -74,14 +77,15 @@ Here’s a list of essential commands to work with the Hardhat template: ### Mocked mode -Mocked mode allows faster testing by simulating FHE operations. This mode runs tests on a local Hardhat network without requiring a real fhEVM node. Use the following commands: +Mocked mode allows faster testing by simulating FHE operations. This mode runs tests on a local Hardhat network without requiring a real fhEVM node. Use the following commands: + +- **Run tests**: -- **Run tests**: ```bash pnpm test ``` -- **Analyze coverage**: +- **Analyze coverage**: ```bash pnpm coverage ``` @@ -92,9 +96,10 @@ Mocked mode allows faster testing by simulating FHE operations. This mode runs t ### Non-mocked mode -Non-mocked mode uses a real fhEVM node, such as the coprocessor on the Sepolia test network. +Non-mocked mode uses a real fhEVM node, such as the coprocessor on the Sepolia test network. + +- **Run tests on Sepolia**: -- **Run tests on Sepolia**: ```bash npx hardhat test [PATH_TO_TEST] --network sepolia ``` diff --git a/docs/guides/conditions.md b/docs/guides/conditions.md index 763810a8..9f94ee91 100644 --- a/docs/guides/conditions.md +++ b/docs/guides/conditions.md @@ -49,33 +49,38 @@ function bid(einput encryptedValue, bytes calldata inputProof) external onlyBefo > **Note**: This is a simplified example to demonstrate the functionality. For a complete implementation with proper error handling and additional features, see the [BlindAuction contract example](https://github.com/zama-ai/fhevm/blob/29fe1f12236010737d86df156dc22eb6dedd0caa/examples/BlindAuction.sol#L92-L143). ### **How It Works** -1. **Comparison**: - - The `TFHE.lt` function compares `highestBid` and `bid`, returning an `ebool` (`isAbove`) that indicates whether the new bid is higher. -2. **Selection**: +1. **Comparison**: + + - The `TFHE.lt` function compares `highestBid` and `bid`, returning an `ebool` (`isAbove`) that indicates whether the new bid is higher. + +2. **Selection**: + - The `TFHE.select` function updates `highestBid` to either the new bid or the previous highest bid, based on the encrypted condition `isAbove`. -3. **Permission Handling**: +3. **Permission Handling**: - After updating `highestBid`, the contract reauthorizes itself to manipulate the updated ciphertext using `TFHE.allowThis`. - ## **Key Considerations** ### **1. Value Change Behavior** + Each time `TFHE.select` assigns a value, a new ciphertext is created, even if the underlying plaintext value remains unchanged. This behavior is inherent to FHE and ensures data confidentiality, but developers should account for it when designing their smart contracts. ### **2. Gas Consumption** + Using `TFHE.select` and other encrypted operations incurs additional gas costs compared to traditional Solidity logic. Optimize your code to minimize unnecessary operations. ### **3. Access Control** + Always use appropriate ACL functions (e.g., `TFHE.allowThis`, `TFHE.allow`) to ensure the updated ciphertexts are authorized for use in future computations or transactions. --- ## **Summary** -- **`TFHE.select`** is a powerful tool for conditional logic on encrypted values. -- Encrypted booleans (`ebool`) and values maintain confidentiality, enabling privacy-preserving logic. -- Developers should account for gas costs and ciphertext behavior when designing conditional operations. +- **`TFHE.select`** is a powerful tool for conditional logic on encrypted values. +- Encrypted booleans (`ebool`) and values maintain confidentiality, enabling privacy-preserving logic. +- Developers should account for gas costs and ciphertext behavior when designing conditional operations. -For more information on the supported operations, see the [fhEVM API documentation](../references/functions.md). \ No newline at end of file +For more information on the supported operations, see the [fhEVM API documentation](../references/functions.md). diff --git a/docs/guides/error_handling.md b/docs/guides/error_handling.md index 81c581ca..e46a3040 100644 --- a/docs/guides/error_handling.md +++ b/docs/guides/error_handling.md @@ -5,6 +5,7 @@ This document explains how to handle errors effectively in fhEVM smart contracts ## **Challenges in Error Handling** In the context of encrypted data: + 1. **No Automatic Reversion**: Transactions do not revert if a condition fails, making it challenging to notify users of issues like insufficient funds or invalid inputs. 2. **Limited Feedback**: Encrypted computations lack direct mechanisms for exposing failure reasons while maintaining confidentiality. @@ -16,6 +17,11 @@ To address these challenges, implement an **error handler** that records the mos ### **Example Implementation** +For a complete implementation of error handling, see our reference contracts: + +- [EncryptedErrors.sol](https://github.com/zama-ai/fhevm-contracts/blob/main/contracts/utils/EncryptedErrors.sol) - Base error handling contract +- [EncryptedERC20WithErrors.sol](https://github.com/zama-ai/fhevm-contracts/blob/main/contracts/token/ERC20/extensions/EncryptedERC20WithErrors.sol) - Example usage in an ERC20 token + The following contract demonstrates how to implement and use an error handler: ```solidity @@ -78,14 +84,17 @@ function _transfer(address from, address to, euint32 amount) internal { ## **How It Works** 1. **Define Error Codes**: + - `NO_ERROR`: Indicates a successful operation. - `NOT_ENOUGH_FUNDS`: Indicates insufficient balance for a transfer. 2. **Record Errors**: + - Use the `setLastError` function to log the latest error for a specific address along with the current timestamp. - Emit the `ErrorChanged` event to notify external systems (e.g., dApps) about the error state change. 3. **Conditional Updates**: + - Use the `TFHE.select` function to update balances and log errors based on the transfer condition (`canTransfer`). 4. **Frontend Integration**: @@ -123,4 +132,4 @@ function getLastError(address user) public view returns (euint8 error, uint time --- -By implementing error handlers as demonstrated, developers can ensure a seamless user experience while maintaining the privacy and integrity of encrypted data operations. \ No newline at end of file +By implementing error handlers as demonstrated, developers can ensure a seamless user experience while maintaining the privacy and integrity of encrypted data operations. diff --git a/docs/guides/frontend/cli.md b/docs/guides/frontend/cli.md index d0fb1631..9b48bbee 100644 --- a/docs/guides/frontend/cli.md +++ b/docs/guides/frontend/cli.md @@ -1,20 +1,60 @@ -# Use the CLI +# Using the CLI -This document introduces the Command-Line Interface (CLI) tool that is included in the `fhevmjs` package. +The `fhevmjs` Command-Line Interface (CLI) tool provides a simple and efficient way to encrypt data for use with the blockchain's Fully Homomorphic Encryption (FHE) system. This guide explains how to install and use the CLI to encrypt integers and booleans for confidential smart contracts. -It can be used for encrypting 8/16/32 bit integers with the blockchain's Fully Homomorphic Encryption (FHE) public key. -To get started with fhevmjs CLI, first, ensure you have Node.js installed on your system. Next, install the fhevmjs package globally using the '-g' flag, which allows you to access the CLI tool from any directory: +--- + +## Installation + +Ensure you have [Node.js](https://nodejs.org/) installed on your system before proceeding. Then, globally install the `fhevmjs` package to enable the CLI tool: ```bash npm install -g fhevmjs ``` -Once installed, `fhevm` command should be available. You can get all commands and options available with `fhevm help` or `fhevm encrypt help`. +Once installed, you can access the CLI using the `fhevm` command. Verify the installation and explore available commands using: + +```bash +fhevm help +``` + +To see specific options for encryption, run: + +```bash +fhevm encrypt help +``` + +--- + +## Encrypting Data -## Examples +The CLI allows you to encrypt integers and booleans for use in smart contracts. Encryption is performed using the blockchain's FHE public key, ensuring the confidentiality of your data. -Encrypt input `71721075` as 64bits integer and `1` as boolean for contract `0x8Fdb26641d14a80FCCBE87BF455338Dd9C539a50` and user `0xa5e1defb98EFe38EBb2D958CEe052410247F4c80`: +### Syntax + +```bash +fhevm encrypt --node ... +``` + +- **`--node`**: Specifies the RPC URL of the blockchain node (e.g., `http://localhost:8545`). +- **``**: The address of the contract interacting with the encrypted data. +- **``**: The address of the user associated with the encrypted data. +- **``**: The data to encrypt, followed by its type: + - `:64` for 64-bit integers + - `:1` for booleans + +--- + +### Example Usage + +Encrypt the integer `71721075` (64-bit) and the boolean `1` for the contract at `0x8Fdb26641d14a80FCCBE87BF455338Dd9C539a50` and the user at `0xa5e1defb98EFe38EBb2D958CEe052410247F4c80`: ```bash fhevm encrypt --node http://localhost:8545 0x8Fdb26641d14a80FCCBE87BF455338Dd9C539a50 0xa5e1defb98EFe38EBb2D958CEe052410247F4c80 71721075:64 1:1 ``` + +--- + +## Additional Resources + +For more advanced features and examples, refer to the [fhevmjs documentation](../../). diff --git a/docs/guides/frontend/node.md b/docs/guides/frontend/node.md index 88173ff8..d06a3ef3 100644 --- a/docs/guides/frontend/node.md +++ b/docs/guides/frontend/node.md @@ -35,8 +35,8 @@ const { createInstance } = require("fhevmjs"); const createFhevmInstance = async () => { return createInstance({ - chainId: 8009, - networkUrl: "https://devnet.zama.ai/", + chainId: 11155111, // Sepolia chain ID + networkUrl: "https://rpc.sepolia.org/", // Sepolia RPC URL gatewayUrl: "https://gateway.zama.ai", }); }; diff --git a/docs/guides/random.md b/docs/guides/random.md index d9f19bba..b21c6840 100644 --- a/docs/guides/random.md +++ b/docs/guides/random.md @@ -4,14 +4,13 @@ This document explains how to generate cryptographically secure random encrypted ## **Key Notes on Random Number Generation** -- **On-Chain Execution**: Random number generation must be executed during a transaction, as it requires the pseudo-random number generator (PRNG) state to be updated on-chain. This operation cannot be performed using the `eth_call` RPC method. -- **Cryptographic Security**: The generated random numbers are cryptographically secure and encrypted, ensuring privacy and unpredictability. +- **On-Chain Execution**: Random number generation must be executed during a transaction, as it requires the pseudo-random number generator (PRNG) state to be updated on-chain. This operation cannot be performed using the `eth_call` RPC method. +- **Cryptographic Security**: The generated random numbers are cryptographically secure and encrypted, ensuring privacy and unpredictability. {% hint style="info" %} Random number generation must be performed during transactions, as it requires the pseudo-random number generator (PRNG) state to be mutated on-chain. Therefore, it cannot be executed using the `eth_call` RPC method. {% endhint %} - ## **Basic Usage** The `TFHE` library allows you to generate random encrypted numbers of various bit sizes. Below is a list of supported types and their usage: @@ -29,9 +28,10 @@ euint256 r256 = TFHE.randEuint256(); // Random 256-bit number ``` ### **Example: Random Boolean** + ```solidity function randomBoolean() public returns (ebool) { - return TFHE.randEbool(); + return TFHE.randEbool(); } ``` @@ -47,9 +47,10 @@ euint32 r32 = TFHE.randEuint32(1000000); // Random number between 0-999999 ``` ### **Example: Random Number with Upper Bound** + ```solidity function randomBoundedNumber(uint16 upperBound) public returns (euint16) { - return TFHE.randEuint16(upperBound); + return TFHE.randEuint16(upperBound); } ``` @@ -67,9 +68,10 @@ ebytes256 rb256 = TFHE.randEbytes256(); // 256 bytes (2048 bits) ``` ### **Example: Random Bytes** + ```solidity function randomBytes256() public returns (ebytes256) { - return TFHE.randEbytes256(); + return TFHE.randEbytes256(); } ``` @@ -78,11 +80,10 @@ function randomBytes256() public returns (ebytes256) { ## **Security Considerations** 1. **Cryptographic Security**: - The random numbers are generated using a cryptographically secure pseudo-random number generator (CSPRNG) and remain encrypted until explicitly decrypted. + The random numbers are generated using a cryptographically secure pseudo-random number generator (CSPRNG) and remain encrypted until explicitly decrypted. 2. **Gas Consumption**: - Each call to a random number generation function consumes gas. Developers should optimize the use of these functions, especially in gas-sensitive contracts. + Each call to a random number generation function consumes gas. Developers should optimize the use of these functions, especially in gas-sensitive contracts. 3. **Privacy Guarantee**: - Random values are fully encrypted, ensuring they cannot be accessed or predicted by unauthorized parties. - + Random values are fully encrypted, ensuring they cannot be accessed or predicted by unauthorized parties. diff --git a/docs/references/functions.md b/docs/references/functions.md index ae40aa70..c8de0d59 100644 --- a/docs/references/functions.md +++ b/docs/references/functions.md @@ -1,10 +1,13 @@ # 1. TFHE Library API Documentation + This document provides an overview of the functions available in the `TFHE` Solidity library. The TFHE library provides functionality for working with encrypted types and performing operations on them. It implements fully homomorphic encryption (FHE) operations in Solidity. ## 1.1. Overview + The `TFHE` Solidity library provides essential functionality for working with encrypted data types and performing fully homomorphic encryption (FHE) operations in smart contracts. It is designed to streamline the developer experience while maintaining flexibility and performance. ### 1.1.1. **Core Functionality** + - **Homomorphic Operations**: Enables arithmetic, bitwise, and comparison operations on encrypted values. - **Ciphertext-Plaintext Interoperability**: Supports operations that mix encrypted and plaintext operands, provided the plaintext operand's size does not exceed the encrypted operand's size. - Example: `add(uint8 a, euint8 b)` is valid, but `add(uint32 a, euint16 b)` is not. @@ -12,13 +15,13 @@ The `TFHE` Solidity library provides essential functionality for working with en - **Implicit Upcasting**: Automatically adjusts operand types when necessary to ensure compatibility during operations on encrypted data. ### 1.1.2. **Key Features** + - **Flexibility**: Handles a wide range of encrypted data types, including booleans, integers, addresses, and byte arrays. - **Performance Optimization**: Prioritizes efficient computation by supporting optimized operator versions for mixed plaintext and ciphertext inputs. - **Ease of Use**: Offers consistent APIs across all supported data types, enabling a smooth developer experience. The library ensures that all operations on encrypted data follow the constraints of FHE while abstracting complexity, allowing developers to focus on building privacy-preserving smart contracts. - ## 1.2. Table of Contents - [1. TFHE Library API Documentation](#1-tfhe-library-api-documentation) @@ -75,17 +78,18 @@ The library ensures that all operations on encrypted data follow the constraints - [5.3. Example](#53-example) - [6. Additional Notes](#6-additional-notes) - # 2. Types ## 2.1. Encrypted Data Types ### 2.1.1. Boolean + - `ebool`: Encrypted boolean value ### 2.1.2. Unsigned Integers + - `euint4`: Encrypted 4-bit unsigned integer -- `euint8`: Encrypted 8-bit unsigned integer +- `euint8`: Encrypted 8-bit unsigned integer - `euint16`: Encrypted 16-bit unsigned integer - `euint32`: Encrypted 32-bit unsigned integer - `euint64`: Encrypted 64-bit unsigned integer @@ -93,15 +97,18 @@ The library ensures that all operations on encrypted data follow the constraints - `euint256`: Encrypted 256-bit unsigned integer ### 2.1.3. Addresses & Bytes + - `eaddress`: Encrypted Ethereum address - `ebytes64`: Encrypted 64-byte value -- `ebytes128`: Encrypted 128-byte value +- `ebytes128`: Encrypted 128-byte value - `ebytes256`: Encrypted 256-byte value ### 2.1.4. Special Types + - `einput`: Input type for encrypted operations (bytes32) ## 2.2. Casting Types + - **Casting between encrypted types**: `TFHE.asEbool` converts encrypted integers to encrypted booleans - **Casting to encrypted types**: `TFHE.asEuintX` converts plaintext values to encrypted types - **Casting to encrypted addresses**: `TFHE.asEaddress` converts plaintext addresses to encrypted addresses @@ -139,33 +146,38 @@ function asEuint16(uint16 value) internal view returns (euint16) The `asEbool` functions behave similarly to the `asEuint` functions, but for encrypted boolean values. - # 3. Core Functions ## 3.1. Configuration + ```solidity function setFHEVM(FHEVMConfig.FHEVMConfigStruct memory fhevmConfig) internal ``` + Sets the FHEVM configuration for encrypted operations. ## 3.2. Initialization Checks + ```solidity function isInitialized(T v) internal pure returns (bool) ``` + Returns true if the encrypted value is initialized, false otherwise. Supported for all encrypted types (T can be ebool, euint*, eaddress, ebytes*). ## 3.3. Arithmetic operations -Available for euint* types: + +Available for euint\* types: + ```solidity function add(T a, T b) internal returns (T) -function sub(T a, T b) internal returns (T) +function sub(T a, T b) internal returns (T) function mul(T a, T b) internal returns (T) ``` + - Arithmetic: `TFHE.add`, `TFHE.sub`, `TFHE.mul`, `TFHE.min`, `TFHE.max`, `TFHE.neg`, `TFHE.div`, `TFHE.rem` - Note: `div` and `rem` operations are supported only with plaintext divisors - ### 3.3.1. Arithmetic operations (`add`, `sub`, `mul`, `div`, `rem`) Performs the operation homomorphically. @@ -187,7 +199,9 @@ function div(euint32 a, uint32 b) internal pure returns (euint32) ``` ### 3.3.2. Min/Max Operations - `min`, `max` -Available for euint* types: + +Available for euint\* types: + ```solidity function min(T a, T b) internal returns (T) function max(T a, T b) internal returns (T) @@ -213,8 +227,8 @@ The `not` operator returns the value obtained after flipping all the bits of the > **_NOTE:_** More information about the behavior of these operators can be found at the [TFHE-rs docs](https://docs.zama.ai/tfhe-rs/getting-started/operations#arithmetic-operations.). - ## 3.4. Bitwise operations + - Bitwise: `TFHE.and`, `TFHE.or`, `TFHE.xor`, `TFHE.not`, `TFHE.shl`, `TFHE.shr`, `TFHE.rotl`, `TFHE.rotr` ### 3.4.1. Bitwise operations (`AND`, `OR`, `XOR`) @@ -223,7 +237,8 @@ Unlike other binary operations, bitwise operations do not natively accept a mix To ease developer experience, the `TFHE` library adds function overloads for these operations. Such overloads implicitely do a trivial encryption before actually calling the operation function, as shown in the examples below. -Available for euint* types: +Available for euint\* types: + ```solidity function and(T a, T b) internal returns (T) function or(T a, T b) internal returns (T) @@ -265,22 +280,24 @@ function rotr(euint32 a, euint16 b) internal view returns (euint32) ``` ## 3.5. Comparison operation (`eq`, `ne`, `ge`, `gt`, `le`, `lt`) + > **Note** that in the case of ciphertext-plaintext operations, since our backend only accepts plaintext right operands, calling the operation with a plaintext left operand will actually invert the operand order and call the _opposite_ comparison. The result of comparison operations is an encrypted boolean (`ebool`). In the backend, the boolean is represented by an encrypted unsinged integer of bit width 8, but this is abstracted away by the Solidity library. - Available for all encrypted types: + ```solidity function eq(T a, T b) internal returns (ebool) function ne(T a, T b) internal returns (ebool) ``` -Additional comparisons for euint* types: +Additional comparisons for euint\* types: + ```solidity function ge(T a, T b) internal returns (ebool) function gt(T a, T b) internal returns (ebool) -function le(T a, T b) internal returns (ebool) +function le(T a, T b) internal returns (ebool) function lt(T a, T b) internal returns (ebool) ``` @@ -298,11 +315,13 @@ function gt(euint16 a, uint32 b) internal view returns (ebool) ``` ## 3.6. Multiplexer operator (`select`) + ```solidity function select(ebool control, T a, T b) internal returns (T) ``` + If control is true, returns a, otherwise returns b. -Available for ebool, eaddress, and ebytes* types. +Available for ebool, eaddress, and ebytes\* types. This operator takes three inputs. The first input `b` is of type `ebool` and the two others of type `euintX`. If `b` is an encryption of `true`, the first integer parameter is returned. Otherwise, the second integer parameter is returned. @@ -337,6 +356,7 @@ The `TFHE` library provides a robust set of access control functions for managin ## 4.1. Permission management ### 4.1.1. Functions + ```solidity function allow(T value, address account) internal function allowThis(T value) internal @@ -344,8 +364,9 @@ function allowTransient(T value, address account) internal ``` #### 4.1.1.1. Descriptions -- **`allow`**: Grants **permanent access** to a specific address. Permissions are stored persistently in a dedicated ACL contract. -- **`allowThis`**: Grants the **current contract** access to an encrypted value. + +- **`allow`**: Grants **permanent access** to a specific address. Permissions are stored persistently in a dedicated ACL contract. +- **`allowThis`**: Grants the **current contract** access to an encrypted value. - **`allowTransient`**: Grants **temporary access** to a specific address for the duration of the transaction. Permissions are stored in transient storage for reduced gas costs. ### 4.1.2. Access control list (ACL) overview @@ -353,6 +374,7 @@ function allowTransient(T value, address account) internal The `allow` and `allowTransient` functions enable fine-grained control over who can access, decrypt, and reencrypt encrypted values. Temporary permissions (`allowTransient`) are ideal for minimizing gas usage in scenarios where access is needed only within a single transaction. #### 4.1.2.1. Example: granting access + ```solidity // Store an encrypted value. euint32 r = TFHE.asEuint32(94); @@ -370,13 +392,15 @@ TFHE.allowTransient(r, 0x1234567890abcdef1234567890abcdef12345678); ## 4.2. Permission checks ### 4.2.1. Functions + ```solidity function isAllowed(T value, address account) internal view returns (bool) function isSenderAllowed(T value) internal view returns (bool) ``` ### 4.2.2. Descriptions -- **`isAllowed`**: Checks whether a specific address has permission to access a ciphertext. + +- **`isAllowed`**: Checks whether a specific address has permission to access a ciphertext. - **`isSenderAllowed`**: Similar to `isAllowed`, but automatically checks permissions for the `msg.sender`. > **Note**: Both functions return `true` if the ciphertext is authorized for the specified address, regardless of whether the allowance is stored in the ACL contract or in transient storage. @@ -386,6 +410,7 @@ function isSenderAllowed(T value) internal view returns (bool) These functions help ensure that only authorized accounts or contracts can access encrypted values. #### 4.2.3.1. Example: permission verification + ```solidity // Store an encrypted value. euint32 r = TFHE.asEuint32(94); @@ -400,21 +425,24 @@ bool isCallerAllowed = TFHE.isSenderAllowed(r); // depends on msg.sender # 5. Storage Management ## 5.1. **Function** + ```solidity function cleanTransientStorage() internal ``` ## 5.2. Description + - **`cleanTransientStorage`**: Removes all temporary permissions from transient storage. Use this function at the end of a transaction to ensure no residual permissions remain. ## 5.3. Example + ```solidity // Clean up transient storage at the end of a function. function finalize() public { - // Perform operations... - - // Clean up transient storage. - TFHE.cleanTransientStorage(); + // Perform operations... + + // Clean up transient storage. + TFHE.cleanTransientStorage(); } ``` diff --git a/docs/tutorials/see-all-tutorials.md b/docs/tutorials/see-all-tutorials.md index 13eb3d21..f145c1ce 100644 --- a/docs/tutorials/see-all-tutorials.md +++ b/docs/tutorials/see-all-tutorials.md @@ -5,7 +5,7 @@ **Solidity smart contracts - templates** - [ERC-20](https://github.com/zama-ai/fhevm-contracts/tree/main/contracts/token/ERC20): A variation of the standard ERC20 smart contract that incorporates encrypted balances, providing additional privacy for token holders. -- [Governor DAO](https://github.com/zama-ai/fhevm-contracts/tree/main/contracts/governance): A DAO smart contract that facilitates governance decisions through encrypted voting +- [Governance](https://github.com/zama-ai/fhevm-contracts/tree/main/contracts/governance): A DAO smart contract that facilitates governance decisions through encrypted voting For more information on individual contracts, see the [fhevm-contracts repository](https://github.com/zama-ai/fhevm-contracts). @@ -20,8 +20,8 @@ For more information on individual contracts, see the [fhevm-contracts repositor - [Cipherbomb UI](https://github.com/immortal-tofu/cipherbomb-ui): A multiplayer game where players must defuse an encrypted bomb by guessing the correct sequence of numbers. - ### Blog tutorials: + - [Suffragium: An Encrypted Onchain Voting System Leveraging ZK and FHE Using Zama's fhEVM](https://www.zama.ai/post/encrypted-onchain-voting-using-zk-and-fhe-with-zama-fhevm) #### Legacy - Not compatible with latest fhEVM @@ -33,14 +33,15 @@ For more information on individual contracts, see the [fhevm-contracts repositor - [Confidential ERC-20 Tokens Using Homomorphic Encryption and the fhEVM](https://www.zama.ai/post/confidential-erc-20-tokens-using-homomorphic-encryption) - June 2023 ### Video tutorials: - - [Zama - FHE on Ethereum (Presentation at The Zama CoFHE Shop during EthCC 7)](https://www.youtube.com/watch?v=WngC5cvV_fc&ab_channel=Zama) + +- [Zama - FHE on Ethereum (Presentation at The Zama CoFHE Shop during EthCC 7)](https://www.youtube.com/watch?v=WngC5cvV_fc&ab_channel=Zama) #### Legacy - Not compatible with latest fhEVM -- [\[Video tutorial\] How to Write Confidential Smart Contracts Using Zama's fhEVM](https://www.zama.ai/post/video-tutorial-how-to-write-confidential-smart-contracts-using-zamas-fhevm) - October 2023 - [Using asynchronous decryption in Solidity contracts with fhEVM](https://www.zama.ai/post/video-tutorial-using-asynchronous-decryption-in-solidity-contracts-with-fhevm) - April 2024 - [Accelerate your code testing and get code coverage using fhEVM mocks](https://www.zama.ai/post/video-tutorial-accelerate-your-code-testing-and-get-code-coverage-using-fhevm-mocks) - January 2024 - [Use the CMUX operator on Zama’s fhEVM](https://www.youtube.com/watch?v=7icM0EOSvU0) - October 2023 +- [\[Video tutorial\] How to Write Confidential Smart Contracts Using Zama's fhEVM](https://www.zama.ai/post/video-tutorial-how-to-write-confidential-smart-contracts-using-zamas-fhevm) - October 2023 - [Workshop during ETHcc: Homomorphic Encryption in the EVM](https://www.youtube.com/watch?v=eivfVykPP8U) - July 2023 {% hint style="success" %}