fhEVM
WebsiteLibrariesProduct & ServicesDevelopersSupport
0.4
0.4
  • Welcome to fhEVM
  • Getting Started
    • What is fhEVM
    • Connecting to Zama Devnet
    • Using Zama Faucet
    • Local dev node
    • Whitepaper
  • Fundamentals
    • Write contract
      • Using Hardhat
      • Using Remix
      • Other development environment
    • Use encrypted types
    • Operations on encrypted types
    • Branching in FHE
    • Decrypt and reencrypt
    • Generate random number
    • Contracts standard library
  • Guides
    • Gas estimation
    • Common pitfalls and best practises
    • How can I break a loop ?
    • Encrypt an input
    • Reencryption
    • Use the CLI
    • Build a web application
    • Build with Node
    • Common webpack errors
  • Tutorials
    • See all tutorials
    • Write confidential smart contract with fhEVM
  • References
    • API Function specifications
    • Repositories
  • Developer
    • Contributing
    • Development roadmap
    • Release note
    • Feature request
    • Bug report
Powered by GitBook

Libraries

  • TFHE-rs
  • Concrete
  • Concrete ML
  • fhEVM

Developers

  • Blog
  • Documentation
  • Github
  • FHE resources

Company

  • About
  • Introduction to FHE
  • Media
  • Careers
On this page
  • How it's working
  • Generate your typed data structure and call the method
  • Write the Solidity code
  • Decrypt the reencryption

Was this helpful?

Export as PDF
  1. Guides

Reencryption

How it's working

The reencryption process involves converting a ciphertext that was encrypted with the FHE blockchain key into one that is encrypted with the NaCl public key generated by the client. First, the user needs to provide two elements:

  • The NaCl box private/public key pair is generated by the client library (fhevmjs).

  • A signature of an EIP-712 object that contains the public key and the contract authorized to initiate a reencryption request.

Then, the contract verifies the signature by generating the EIP-712 with the provided public key and contract address. The signature must match the msg.sender. If the signature match, the contract can return the reencryption of the value with the provided public key

Note that this mechanism grants the application (whether web-based or node-based) access to all the ciphertext made available by the mentioned contract for the user.

Generate your typed data structure and call the method

You can generate the data to sign by using the generatePublicKey method. To sign, we'll use the eth_signTypedData_v4 method available on wallets.

const instance = getInstance();
const reencryption = instance.generatePublicKey("0x1c786b8ca49D932AFaDCEc00827352B503edf16c"); // The allowed contract address
const params = [userAddress, JSON.stringify(reencryption.eip712)];
const sign = await window.ethereum.request({
  method: "eth_signTypedData_v4",
  params,
});

// We call the balanceOf method to get the reencrypt balance
const encryptedBalance = await contract.balanceOf(reencryption.publicKey, sign);

Write the Solidity code

Getting a reencryption needs to be implemented into the contract and on the client side. We'll take the balanceOf method of an ERC-20 contract.

This view function needs to validate the user to prevent anyone to reencrypt any user's balance. To prevent this, the user provides a signature of the given public key and the contract address. Since this is something very useful, fhEVM library provide an abstract to use in your contract:

import "fhevm/abstracts/Reencrypt.sol";

contract EncryptedERC20 is Reencrypt {
  function balanceOf(
    bytes32 publicKey,
    bytes calldata signature
  ) public view onlySignedPublicKey(publicKey, signature) returns (bytes memory) {
    return TFHE.reencrypt(balances[msg.sender], publicKey, 0);
  }
}

The modifier onlySignedPublicKey(publicKey, signature) will verify the signature of the user.

Decrypt the reencryption

When generating the public key using generatePublicKey, the corresponding private key is kept by the fhEVM instance and linked to the specified contract. To decrypt a value using the user's private key, you only need to provide the contract address and the encrypted value.

const encryptedBalance = await contract.balanceOf(reencryption.publicKey, sign);
const balance = instance.decrypt("0x1c786b8ca49D932AFaDCEc00827352B503edf16c", encryptedBalance);
PreviousEncrypt an inputNextUse the CLI

Last updated 1 year ago

Was this helpful?