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 dApp.

First, your contract needs to implement a view function to return the ciphertext to reencrypt:

import "fhevm/lib/TFHE.sol";

contract EncryptedERC20 {
  ...
  function balanceOf(account address) public view returns (bytes euint64) {
    return balances[msg.sender];
  }
  ...
}

Then, you can implement the client side code. This example would run in a browser:

import abi from "./abi.json";
import { Contract, BrowserProvider } from "ethers";
import { createInstance } from "fhevmjs";

const CONTRACT_ADDRESS = "";

const provider = new BrowserProvider(window.ethereum);
const accounts = await provider.send("eth_requestAccounts", []);
const USER_ADDRESS = accounts[0];

// Create a fhevmjs instance using the Zama's network and the Zama's Gateway
const instance = await createInstance({
  chainId: 8009,
  networkUrl: "https://devnet.zama.ai",
  gatewayUrl: "https://gateway.zama.ai",
});

// Generate the private and public key, used for the reencryption
const { publicKey, privateKey } = instance.generateKeypair();

// Create an EIP712 object for the user to sign.
const eip712 = instance.createEIP712(publicKey, CONTRACT_ADDRESS);

// Request the user's signature on the public key
const params = [USER_ADDRESS, JSON.stringify(eip712)];
const signature = await window.ethereum.request({ method: "eth_signTypedData_v4", params });

// Get the ciphertext to reencrypt
const encryptedERC20 = new Contract(CONTRACT_ADDRESS, abi, signer).connect(provider);
const encryptedBalance = encryptedERC20.balanceOf(userAddress);

// This function will call the gateway and decrypt the received value with the provided private key
const userBalance = instance.reencrypt(
  encryptedBalance, // the encrypted balance
  privateKey, // the private key generated by the dApp
  publicKey, // the public key generated by the dApp
  signature, // the user's signature of the public key
  CONTRACT_ADDRESS, // The contract address where the ciphertext is
  USER_ADDRESS, // The user address where the ciphertext is
);

console.log(userBalance);

Last updated