Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The best way to start writing smart contracts with fhEVM is to use our Hardhat template.
It allows you to start a fhEVM docker image and run your smart contract on it. Read the README for more information.
📙 White paper | 📁 Github | 💛 Community support | 🟨 Zama Bounty Program
There used to be a dilemma in blockchain: keep your application and user data on-chain, allowing everyone to see it, or keep it privately off-chain and lose contract composability. Thanks to a breakthrough in homomorphic encryption, Zama’s fhEVM makes it possible to run confidential smart contracts on encrypted data, guaranteeing both confidentiality and composability.
fhevmjs is a javascript library that enables developers to interact with blockchains using Zama's cutting-edge technology based on TFHE (Fully Homomorphic Encryption over the Torus). This library provides a seamless integration of TFHE encryption capabilities into web3 applications, allowing for secure and private interactions with smart contracts.
The Solidity library we introduce is a powerful tool that empowers developers to manipulate encrypted data using TFHE within smart contracts. With this library, developers can perform computations over encrypted data, such as addition, multiplication, comparison and more, while maintaining the confidentiality of the underlying information.
Workshop during ETHcc [by Morten Dahl — Zama]
Confidential ERC-20 Tokens Using Homomorphic Encryption [by [Clément Danjou — Zama]
On-chain Blind Auctions Using Homomorphic Encryption [by Clément Danjou — Zama]
Battleship [by Owen Murovec]
Darkpool [by Owen Murovec]
You can use to interact with a blockchain using fhEVM. If you want to send an encrypted input, you need to encrypt it with for example. It becomes more complex if you want to reencrypt a value directly in Remix.
To avoid this problem, we developed a with these two missing features:
Encryption of input
Generation of public key and signature for reencryption and decryption.
You can use it on .
First, to import TFHE library, simply import it at the top of your contract.
import "fhevm/lib/TFHE.sol";
Be sure to be on the correct network before deploying your contract
If you need to get coins for a specific wallet, you can use the faucet as follow:
We provide a docker image to spin up a fhEVM node for local development.
You can get 10 Zama token on https://faucet.zama.ai/
The functions exposed by the TFHE
Solidity library come in various shapes and sizes in order to facilitate developer experience. For example, most binary operators (e.g., add
) can take as input any combination of the following types:
euint8
euint16
euint32
Note that in the backend, FHE operations are only defined on same-type operands. Therefore, the TFHE
Solidity library will do implicit upcasting if necessary.
Most binary operators are also defined with a mix of ciphertext and plaintext inputs. In this case, operators can take as input operands of the following types
euint8
euint16
euint32
uint8
uint16
uint32
under the condition that the size of the uint
operand is at most the size of the euint
operand. For example, add(uint8 a, euint8 b)
is defined but add(uint16 a, euint16 b)
is not. Note that these ciphertext-plaintext operations may take less time to compute than ciphertext-ciphertext operations.
In the backend, FHE operations are only defined on same-type operands. Therefore, the TFHE
Solidity library will do implicit upcasting if necessary.
asEuint
The asEuint
functions serve three purposes:
verify ciphertext bytes and return a valid handle to the calling smart contract;
cast a euintX
typed ciphertext to a euintY
typed ciphertext, where X != Y
;
trivially encrypt a plaintext value.
The first case is used to process encrypted inputs, e.g. user-provided ciphertexts. Those are generally included in a transaction payload.
The second case is self-explanatory. When X > Y
, the most significant bits are dropped. When X < Y
, the ciphertext is padded to the left with trivial encryptions of 0
.
The third case is used to "encrypt" a public value so that it can be used as a ciphertext. Note that what we call a trivial encryption is not secure in any sense. When trivially encrypting a plaintext value, this value is still visible in the ciphertext bytes. More information about trivial encryption can be found here.
asEbool
The asEbool
functions behave similarly to the asEuint
functions, but for encrypted boolean values.
The reencrypt functions takes as inputs a ciphertext and a public encryption key (namely, a NaCl box).
During reencryption, the ciphertext is decrypted using the network private key (the threshold decryption protocol is in the works). Then, the decrypted result is encrypted under the user-provided public encryption key. The result of this encryption is sent back to the caller as bytes memory
.
It is also possible to provide a default value to the reencrypt
function. In this case, if the provided ciphertext is not initialized (i.e., if the ciphertext handle is 0
), the function will return an encryption of the provided default value.
NOTE: If one of the following operations is called with an uninitialized ciphertext handle as an operand, this handle will be made to point to a trivial encryption of
0
before the operation is executed.
add
, sub
, mul
)Performs the operation homomorphically.
Note that division is not currently supported.
AND
, OR
, XOR
)Unlike other binary operations, bitwise operations do not natively accept a mix of ciphertext and plaintext inputs. 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.
<<
, >>
)Shifts the bits of the base two representation of a
by b
positions.
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.
cmux
)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.
min
, max
Returns the minimum (resp. maximum) of the two given values.
neg
, not
)There are two unary operators: neg
(-
) and not
(!
). Note that since we work with unsigned integers, the result of negation is interpreted as the modular opposite. The not
operator returns the value obtained after flipping all the bits of the operand.
NOTE: More information about the behavior of these operators can be found at the TFHE-rs docs.
We allow explicit decryption requests for any encrypted type. The values are decrypted through the distributed decryption protocol and are stored on-chain.
The result of comparison operations is of type ebool
. Typical boolean operations are not currently supported for this type.
The purpose of the ebool
type is two-fold:
control bit for the cmux
operator;
input for optimistic encrypted require (optReq
) statements.
The decryption statements described above may lead to important delays during the transaction execution as several of them may need to be processed in a single transaction. Given that those decryptions might be used for control flow by using the Solidity require
function, we introduce optimistic require statements (optReq
). These require statements take as input a value to type ebool
and are accumulated throughout the execution of the transaction. The accumulated boolean value is decrypted via the threshold decryption protocol either when an explicit decryption is executed, or at the very end of a transaction execution. If the decryption returns false
, the transaction is reverted. Otherwise, state changes are persisted as usual. Optimistic requires may be more efficient, but this efficiency comes at the price of paying the full transaction gas cost if one of the boolean predicates is false.
Welcome to the documentation for fhEVM Solidity Library! This comprehensive guide provides developers with detailed information on the library's functions, parameters, and usage examples. Explore how to leverage TFHE's powerful capabilities for computing over encrypted data within Solidity smart contracts, enabling secure computations and encrypted data manipulation. Unlock a new level of privacy and confidentiality in your blockchain applications with fhEVM Solidity Library.
To get started with fhEVM Solidity Library, you need to install it as a dependency in your JavaScript project. You can do this using npm (Node Package Manager) or Yarn. Open your terminal and navigate to your project's directory, then run one of the following commands:
This will download and install the fhEVM Solidity Library and its dependencies into your project.
Here are the main steps from the official guide provided by Metamask:
Add these informations to access to blockchain
fhevmjs include a Command-Line Interface (CLI) tool. With this handy utility, you can encrypt 8/16/32bits integer with the blockchain's 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:
Once installed, fhevm
command should be available. You can get all commands and options available with fhevm help
or fhevm encrypt help
.
Encrypt 71721075 as 32bits integer:
The library exposes utility functions for TFHE operations. The goal of the library is to provide a seamless developer experience for writing smart contracts that can operate on confidential data.
The library provides a type system that is checked both at compile time and at run time. The structure and operations related to these types are described in this sections.
We currently support encrypted integers of bit length up to 32 bits.
Our library provides the following types :
ebool
euint8
euint16
euint32
These encrypted integers behave as much as possible as Solidity's integer types. However, behaviour such as "revert on overflow" is not supported as this would leak some information of the encrypted integers. Therefore, arithmetic on euint
types is , i.e. there is wrap-around on overlow.
In the back-end, encrypted integers are TFHE ciphertexts. The library abstracts away the ciphertexts and presents pointers to ciphertexts, or ciphertext handles, to the smart contract developer. The euint
types are wrappers over these handles.
The library exposes utility functions for operations on TFHE ciphertexts. The list of supported operations is presented below.
name | function name | type |
---|
Fields | Value |
---|---|
Fields | Value |
---|---|
More information about the supported operations can be found at the .
Network Name
Zama Network
New RPC URL
https://devnet.zama.ai
Chain ID
8009
Currency symbol
ZAMA
Block explorer URL (Optional)
https://main.explorer.zama.ai
Network Name
Zama Local
New RPC URL
http://localhost:8545/
Chain ID
9000
Currency symbol
ZAMA
Block explorer URL (Optional)
Add |
| Binary |
Sub |
| Binary |
Mul |
| Binary |
BitAnd |
| Binary |
BitOr |
| Binary |
BitXor |
| Binary |
Shift Right |
| Binary |
Shift Left |
| Binary |
Equal |
| Binary |
Not equal |
| Binary |
Greater than or equal |
| Binary |
Greater than |
| Binary |
Less than or equal |
| Binary |
Less than |
| Binary |
Min |
| Binary |
Max |
| Binary |
Neg |
| Unary |
Not |
| Unary |
Cmux |
| Ternary |
The library provides a convenient function that generates a JSON object based on the EIP-712 standard. This JSON object includes a public key and is specifically designed to facilitate data reencryption in a smart contract environment.
By utilizing this JSON object and having it signed by the user, a secure process of reencrypting data becomes possible within a smart contract. The signed JSON includes the necessary information, including the public key, which allows for seamless reencryption of the data.
options
(required):
verifyingContract: string
(required): The address of the contract
name: string
(optional): The name used in the EIP712
version: string
(optional): The version used in the EIP712
FhevmToken
contractAddress: string
(required): address of the contract
ciphertext: Uint8Array | string
(required): a ciphertext, as a binary or hex string, to decrypt
number
This method allows you to store the signature of a public key for a specific contract, in order to retrieve it later. The signature is also serialized in serializeKeypairs
.
contractAddress: string
(required): address of the contract
signature: string
(required): the signature of the EIP-712 token
This method returns true if contract has a keypair and a signature.
contractAddress: string
(required): address of the contract
boolean
This method returns the saved public key and signature for a specific contract. If the contract has no keypair or no signature, this method returns null
.
contractAddress: string
(required): address of the contract
TokenSignature
or null
This method is useful if you want to store contract keypairs in the user LocalStorage.
ExportedContractKeypairs
:
The library provides a set of functions to encrypt integers of various sizes (8, 16, and 32 bits) using the blockchain's public key. These encrypted integers can then be securely used as parameters for smart contract methods within the blockchain ecosystem.
value: number
(required): A number between 0 and 255.
Uint8Array
value: number
(required): A number between 0 and 65535.
Uint8Array
value: number
(required): A number between 0 and 4294967295.
Uint8Array
To use the library in your project, you need to load WASM of first with initFhevm
.
In the codebase, there is a new URL('tfhe_bg.wasm')
which triggers a resolve by Webpack. If yo u encounter an issue, you can add a fallback for this file by adding a resolve configuration in y our webpack.config.js
:
If you encounter any other issue, you can force import of the browser package.
If you have an issue with bundling the library (for example with some SSR framework), you can use the prebundled version available in fhevmjs/bundle
. Just embed the library with a <script>
tag and you're good to go.
Welcome to the documentation for fhevmjs, a JavaScript library that enables interaction with blockchain using Zama's technology! This comprehensive guide provides developers with detailed information on encryption of data using TFHE (Fully Homomorphic Encryption over the Torus) and generation of EIP-719 tokens for reencrypt data.
To get started with fhevmjs, you need to install it as a dependency in your JavaScript project. You can do this using npm, Yarn or pnpm. Open your terminal and navigate to your project's directory, then run one of the following commands:
This will download and install the fhevmjs library and its dependencies into your project.
First, you need to create an instance. An instance allows you to:
Encrypt inputs with blockchain public key
Manage user keys to reencrypt contract's encrypted data
params
(required):
chainId
(required): Id of the chain
publicKey
(required): Public key of the blockchain
keypairs
(optional): A list of keypairs associated with contract
Promise<FhevmInstance>
With a bundler such as Webpack or Rollup, imports will be replaced with the version mentioned in the "browser"
field of the package.json
. If you encounter issue with typing, you can use this using TypeScript 5.
Workshop during ETHcc by Morten Dahl (Zama)
Confidential ERC-20 Tokens Using Homomorphic Encryption by Clément Danjou (Zama)
On-chain Blind Auctions Using Homomorphic Encryption by Clément Danjou (Zama)