Debug decrypt

This guide explains how to use the debug.decrypt[XX] functions for debugging encrypted data in mocked environments during development with fhEVM.

[!WARNING] The debug.decrypt[XX] functions should not be used in production as they rely on private keys.

Overview

The debug.decrypt[XX] functions allow you to decrypt encrypted handles into plaintext values. This feature is useful for debugging encrypted operations such as transfers, balance checks, and other computations involving FHE-encrypted data.

Key points

  • Environment: The debug.decrypt[XX] functions work only in mocked environments (e.g., hardhat network).

  • Production limitation: In production, decryption is performed asynchronously via the Gateway and requires an authorized onchain request.

  • Encrypted types: The debug.decrypt[XX] functions supports various encrypted types, including integers, booleans, and ebytesXX.

  • Bypass ACL authorization: The debug.decrypt[XX] functions allow decryption without ACL authorization, useful for verifying encrypted operations during development and testing.

Supported functions

Integer decryption

Decrypts encrypted integers of different bit-widths (euint4, euint8, ..., euint256).

Function Name
Returns
Encrypted Type

decrypt4

bigint

euint4

decrypt8

bigint

euint8

decrypt16

bigint

euint16

decrypt32

bigint

euint32

decrypt64

bigint

euint64

decrypt128

bigint

euint128

decrypt256

bigint

euint256

Boolean decryption

Decrypts encrypted booleans (ebool).

Function Name
Returns
Encrypted Type

decryptBool

boolean

ebool

Byte array decryption

Decrypts encrypted byte arrays of various sizes (ebytesXX).

Function Name
Returns
Encrypted Type

decryptEbytes64

string

ebytes64

decryptEbytes128

string

ebytes128

decryptEbytes256

string

ebytes256

Address decryption

Decrypts encrypted addresses.

Function Name
Returns
Encrypted Type

decryptAddress

string

eaddress

Function usage

Example: decrypting encrypted values

import { debug } from "../utils";

// Decrypt a 64-bit encrypted integer
const handle64: bigint = await this.erc20.balanceOf(this.signers.alice);
const plaintextValue: bigint = await debug.decrypt64(handle64);
console.log("Decrypted Balance:", plaintextValue);

[!NOTE] To utilize the debug functions, import the utils.ts file.

For a more complete example, refer to the ConfidentialERC20 test file.

Example: decrypting byte arrays

// Decrypt a 128-byte encrypted value
const ebytes128Handle: bigint = ...; // Get handle for the encrypted bytes
const decryptedBytes: string = await debug.decryptEbytes128(ebytes128Handle);
console.log("Decrypted Bytes:", decryptedBytes);

How it works

Verifying types

Each decryption function includes a type verification step to ensure the provided handle matches the expected encrypted type. If the type is mismatched, an error is thrown.

function verifyType(handle: bigint, expectedType: number) {
  const typeCt = handle >> 8n;
  if (Number(typeCt % 256n) !== expectedType) {
    throw "Wrong encrypted type for the handle";
  }
}

Environment checks

[!CAUTION] The functions only work in the hardhat network. Attempting to use them in a production environment will result in an error.

if (network.name !== "hardhat") {
  throw Error("This function can only be called in mocked mode");
}

Best practices

  • Use only for debugging: These functions require access to private keys and are meant exclusively for local testing and debugging.

  • Production decryption: For production, always use the asynchronous Gateway-based decryption.

Last updated