Encrypted values that are stored on-chain can be decrypted in 2 ways, depending on the need.

The function TFHE.decrypt() can be used to directly decrypt an encrypted state. For example, you could use it to reveal everyone's cards at the end of each round. Please note that once decrypted, the plain text value will be viewable to the public, so it is important to make sure that this function is well protected under various smart contracts logics.

function decryptAmount(euint8 amount) public view returns (uint8) {
    return TFHE.decrypt(amount);

Alternatively, it is also possible to decrypt in a way so that only the end user can see the plain text value using TFHE.reencrypt(). This can be useful in scenarios in which a user wants to view their own private balances, without revealing the plain text to the public. The difference between TFHE.decrypt() and TFHE.reencrypt() is that the latter also takes in a publicKey as input. The validators will decrypt the user data and immediately re-encrypt the plain text using this publicKey. The re-encrypted plain text can then be decrypted locally by the user on the client side, using the respective privateKey.

// returns the decryption of `ciphertext`, encrypted under `publicKey`.
function reencrypt(euint32 ciphertext, bytes32 publicKey) internal view returns (bytes memory reencrypted)

// if the handle of `ciphertext` is equal to `0`, returns `defaultValue` encrypted under `publicKey`.
// otherwise, returns as above
function reencrypt(euint32 ciphertext, bytes32 publicKey, uint32 defaultValue) internal view returns (bytes memory reencrypted)

The publicKey and privateKey pair is generated using generateToken() from fhevmjs (see Decryption).

Here's an example of how TFHE.reencrypt() is used for the balanceOf function the private ERC-20 contract:

pageConfidential ERC-20

Last updated