Overview
The FHE library provides a comprehensive set of functions for working with Fully Homomorphic Encryption (FHE) in Solidity smart contracts. This library enables you to perform computations on encrypted data without decrypting it, ensuring privacy throughout your contract’s execution.
All functions in the FHE library are prefixed with FHE. when called. For example: FHE.add(a, b) or FHE.allowPublic(value).
Encrypted Data Types
The library supports the following encrypted data types:
| Type | Description |
|---|
ebool | Encrypted boolean value |
euint8 | Encrypted 8-bit unsigned integer |
euint16 | Encrypted 16-bit unsigned integer |
euint32 | Encrypted 32-bit unsigned integer |
euint64 | Encrypted 64-bit unsigned integer |
euint128 | Encrypted 128-bit unsigned integer |
eaddress | Encrypted Ethereum address |
Type Conversion
From Plaintext to Encrypted Types
asEbool
Plaintext boolean value to encrypt
Optional security zone identifier for isolating encrypted computations
Converts a plaintext boolean value to an encrypted boolean.
ebool encrypted = FHE.asEbool(true);
ebool encryptedWithZone = FHE.asEbool(true, 1);
asEuint8
Plaintext value to encrypt (must fit in 8 bits)
Optional security zone identifier
Encrypted 8-bit unsigned integer
Converts a plaintext value to an encrypted 8-bit unsigned integer.
euint8 encrypted = FHE.asEuint8(42);
asEuint16
Plaintext value to encrypt (must fit in 16 bits)
Optional security zone identifier
Encrypted 16-bit unsigned integer
Converts a plaintext value to an encrypted 16-bit unsigned integer.
euint16 encrypted = FHE.asEuint16(1000);
asEuint32
Plaintext value to encrypt (must fit in 32 bits)
Optional security zone identifier
Encrypted 32-bit unsigned integer
Converts a plaintext value to an encrypted 32-bit unsigned integer.
euint32 encrypted = FHE.asEuint32(50000);
asEuint64
Plaintext value to encrypt (must fit in 64 bits)
Optional security zone identifier
Encrypted 64-bit unsigned integer
Converts a plaintext value to an encrypted 64-bit unsigned integer.
euint64 encrypted = FHE.asEuint64(1000000000);
asEuint128
Plaintext value to encrypt (must fit in 128 bits)
Optional security zone identifier
Encrypted 128-bit unsigned integer
Converts a plaintext value to an encrypted 128-bit unsigned integer.
euint128 encrypted = FHE.asEuint128(1000000000000000000);
asEaddress
Plaintext Ethereum address to encrypt
Optional security zone identifier
Encrypted Ethereum address
Converts a plaintext address value to an encrypted address.
eaddress encrypted = FHE.asEaddress(0x1234567890123456789012345678901234567890);
asEbool (from InEbool)
Encrypted input structure containing boolean data
Converts an encrypted input structure to an encrypted boolean.
ebool encrypted = FHE.asEbool(encryptedInput);
asEuint8 (from InEuint8)
Encrypted input structure containing 8-bit integer data
Encrypted 8-bit unsigned integer
Converts an encrypted input structure to an encrypted 8-bit unsigned integer.
euint8 encrypted = FHE.asEuint8(encryptedInput);
asEuint16 (from InEuint16)
Encrypted input structure containing 16-bit integer data
Encrypted 16-bit unsigned integer
Converts an encrypted input structure to an encrypted 16-bit unsigned integer.
euint16 encrypted = FHE.asEuint16(encryptedInput);
asEuint32 (from InEuint32)
Encrypted input structure containing 32-bit integer data
Encrypted 32-bit unsigned integer
Converts an encrypted input structure to an encrypted 32-bit unsigned integer.
euint32 encrypted = FHE.asEuint32(encryptedInput);
asEuint64 (from InEuint64)
Encrypted input structure containing 64-bit integer data
Encrypted 64-bit unsigned integer
Converts an encrypted input structure to an encrypted 64-bit unsigned integer.
euint64 encrypted = FHE.asEuint64(encryptedInput);
asEuint128 (from InEuint128)
Encrypted input structure containing 128-bit integer data
Encrypted 128-bit unsigned integer
Converts an encrypted input structure to an encrypted 128-bit unsigned integer.
euint128 encrypted = FHE.asEuint128(encryptedInput);
asEaddress (from InEaddress)
Encrypted input structure containing address data
Encrypted Ethereum address
Converts an encrypted input structure to an encrypted address.
eaddress encrypted = FHE.asEaddress(encryptedInput);
Type Conversion Between Encrypted Types
asEbool (from euint)
Converts various encrypted integer types to an encrypted boolean.
ebool result = FHE.asEbool(euint8Value);
ebool result = FHE.asEbool(euint16Value);
ebool result = FHE.asEbool(euint32Value);
ebool result = FHE.asEbool(euint64Value);
ebool result = FHE.asEbool(euint128Value);
ebool result = FHE.asEbool(eaddressValue);
asEuint8 (from other encrypted types)
Converts various encrypted types to an encrypted 8-bit unsigned integer.
euint8 result = FHE.asEuint8(eboolValue);
euint8 result = FHE.asEuint8(euint16Value);
euint8 result = FHE.asEuint8(euint32Value);
euint8 result = FHE.asEuint8(euint64Value);
euint8 result = FHE.asEuint8(euint128Value);
euint8 result = FHE.asEuint8(eaddressValue);
asEuint16 (from other encrypted types)
Converts various encrypted types to an encrypted 16-bit unsigned integer.
euint16 result = FHE.asEuint16(eboolValue);
euint16 result = FHE.asEuint16(euint8Value);
euint16 result = FHE.asEuint16(euint32Value);
euint16 result = FHE.asEuint16(euint64Value);
euint16 result = FHE.asEuint16(euint128Value);
euint16 result = FHE.asEuint16(eaddressValue);
asEuint32 (from other encrypted types)
Converts various encrypted types to an encrypted 32-bit unsigned integer.
euint32 result = FHE.asEuint32(eboolValue);
euint32 result = FHE.asEuint32(euint8Value);
euint32 result = FHE.asEuint32(euint16Value);
euint32 result = FHE.asEuint32(euint64Value);
euint32 result = FHE.asEuint32(euint128Value);
euint32 result = FHE.asEuint32(eaddressValue);
asEuint64 (from other encrypted types)
Converts various encrypted types to an encrypted 64-bit unsigned integer.
euint64 result = FHE.asEuint64(eboolValue);
euint64 result = FHE.asEuint64(euint8Value);
euint64 result = FHE.asEuint64(euint16Value);
euint64 result = FHE.asEuint64(euint32Value);
euint64 result = FHE.asEuint64(euint128Value);
euint64 result = FHE.asEuint64(eaddressValue);
asEuint128 (from other encrypted types)
Converts various encrypted types to an encrypted 128-bit unsigned integer.
euint128 result = FHE.asEuint128(eboolValue);
euint128 result = FHE.asEuint128(euint8Value);
euint128 result = FHE.asEuint128(euint16Value);
euint128 result = FHE.asEuint128(euint32Value);
euint128 result = FHE.asEuint128(euint64Value);
euint128 result = FHE.asEuint128(eaddressValue);
asEaddress (from euint128)
Converts an encrypted 128-bit unsigned integer to an encrypted address.
eaddress result = FHE.asEaddress(euint128Value);
Arithmetic Operations
add
Performs addition of two encrypted unsigned integers.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (must match lhs type)
result
euint8 | euint16 | euint32 | euint64 | euint128
Sum of the two encrypted values
euint8 sum = FHE.add(a, b);
euint32 sum = FHE.add(x, y);
sub
Performs subtraction of two encrypted unsigned integers.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (must match lhs type)
result
euint8 | euint16 | euint32 | euint64 | euint128
Difference of the two encrypted values
euint8 diff = FHE.sub(a, b);
euint32 diff = FHE.sub(x, y);
mul
Performs multiplication of two encrypted unsigned integers.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (must match lhs type)
result
euint8 | euint16 | euint32 | euint64 | euint128
Product of the two encrypted values
euint8 product = FHE.mul(a, b);
euint32 product = FHE.mul(x, y);
div
Performs division of two encrypted unsigned integers.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value (dividend)
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (divisor, must match lhs type)
result
euint8 | euint16 | euint32 | euint64 | euint128
Quotient of the division
Division by zero will cause the operation to revert. Ensure the divisor is non-zero.
euint8 quotient = FHE.div(a, b);
euint32 quotient = FHE.div(x, y);
rem
Calculates the remainder when dividing two encrypted unsigned integers.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value (dividend)
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (divisor, must match lhs type)
result
euint8 | euint16 | euint32 | euint64 | euint128
Remainder of the division
euint8 remainder = FHE.rem(a, b);
euint32 remainder = FHE.rem(x, y);
square
Calculates the square of an encrypted unsigned integer.
value
euint8 | euint16 | euint32 | euint64 | euint128
required
Encrypted value to square
result
euint8 | euint16 | euint32 | euint64 | euint128
Square of the encrypted value
euint8 squared = FHE.square(a);
euint32 squared = FHE.square(x);
Bitwise Operations
and
Performs a bitwise AND operation on two encrypted values.
lhs
ebool | euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value
rhs
ebool | euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (must match lhs type)
result
ebool | euint8 | euint16 | euint32 | euint64 | euint128
Result of the bitwise AND operation
ebool result = FHE.and(a, b);
euint8 result = FHE.and(x, y);
Performs a bitwise OR operation on two encrypted values.
lhs
ebool | euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value
rhs
ebool | euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (must match lhs type)
result
ebool | euint8 | euint16 | euint32 | euint64 | euint128
Result of the bitwise OR operation
ebool result = FHE.or(a, b);
euint8 result = FHE.or(x, y);
xor
Performs a bitwise XOR operation on two encrypted values.
lhs
ebool | euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value
rhs
ebool | euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (must match lhs type)
result
ebool | euint8 | euint16 | euint32 | euint64 | euint128
Result of the bitwise XOR operation
ebool result = FHE.xor(a, b);
euint8 result = FHE.xor(x, y);
not
Performs a bitwise NOT operation on an encrypted value.
value
ebool | euint8 | euint16 | euint32 | euint64 | euint128
required
Encrypted value to negate
result
ebool | euint8 | euint16 | euint32 | euint64 | euint128
Result of the bitwise NOT operation
ebool result = FHE.not(a);
euint8 result = FHE.not(x);
shl
Performs a shift left operation on an encrypted unsigned integer.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Encrypted value to shift
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Number of bits to shift left (must match lhs type)
result
euint8 | euint16 | euint32 | euint64 | euint128
Result of the shift left operation
euint8 result = FHE.shl(value, shiftAmount);
euint32 result = FHE.shl(x, y);
shr
Performs a shift right operation on an encrypted unsigned integer.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Encrypted value to shift
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Number of bits to shift right (must match lhs type)
result
euint8 | euint16 | euint32 | euint64 | euint128
Result of the shift right operation
euint8 result = FHE.shr(value, shiftAmount);
euint32 result = FHE.shr(x, y);
rol
Performs a rotate left operation on an encrypted unsigned integer.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Encrypted value to rotate
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Number of bits to rotate left (must match lhs type)
result
euint8 | euint16 | euint32 | euint64 | euint128
Result of the rotate left operation
euint8 result = FHE.rol(value, rotateAmount);
euint32 result = FHE.rol(x, y);
ror
Performs a rotate right operation on an encrypted unsigned integer.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Encrypted value to rotate
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Number of bits to rotate right (must match lhs type)
result
euint8 | euint16 | euint32 | euint64 | euint128
Result of the rotate right operation
euint8 result = FHE.ror(value, rotateAmount);
euint32 result = FHE.ror(x, y);
Comparison Operations
Checks if two encrypted values are equal and returns an encrypted boolean.
lhs
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Left-hand side encrypted value
rhs
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Right-hand side encrypted value (must match lhs type)
Encrypted boolean indicating equality
ebool isEqual = FHE.eq(a, b);
ebool isEqual = FHE.eq(address1, address2);
Checks if two encrypted values are not equal and returns an encrypted boolean.
lhs
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Left-hand side encrypted value
rhs
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Right-hand side encrypted value (must match lhs type)
Encrypted boolean indicating inequality
ebool isNotEqual = FHE.ne(a, b);
ebool isNotEqual = FHE.ne(address1, address2);
Checks if the first encrypted unsigned integer is less than the second and returns an encrypted boolean.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (must match lhs type)
Encrypted boolean indicating if lhs is less than rhs
ebool isLessThan = FHE.lt(a, b);
ebool isLessThan = FHE.lt(x, y);
lte
Checks if the first encrypted unsigned integer is less than or equal to the second and returns an encrypted boolean.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (must match lhs type)
Encrypted boolean indicating if lhs is less than or equal to rhs
ebool isLessEqual = FHE.lte(a, b);
ebool isLessEqual = FHE.lte(x, y);
Checks if the first encrypted unsigned integer is greater than the second and returns an encrypted boolean.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (must match lhs type)
Encrypted boolean indicating if lhs is greater than rhs
ebool isGreaterThan = FHE.gt(a, b);
ebool isGreaterThan = FHE.gt(x, y);
gte
Checks if the first encrypted unsigned integer is greater than or equal to the second and returns an encrypted boolean.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (must match lhs type)
Encrypted boolean indicating if lhs is greater than or equal to rhs
ebool isGreaterEqual = FHE.gte(a, b);
ebool isGreaterEqual = FHE.gte(x, y);
Min/Max Functions
min
Returns the smaller of two encrypted unsigned integers.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (must match lhs type)
result
euint8 | euint16 | euint32 | euint64 | euint128
The smaller of the two encrypted values
euint8 minimum = FHE.min(a, b);
euint32 minimum = FHE.min(x, y);
max
Returns the larger of two encrypted unsigned integers.
lhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Left-hand side encrypted value
rhs
euint8 | euint16 | euint32 | euint64 | euint128
required
Right-hand side encrypted value (must match lhs type)
result
euint8 | euint16 | euint32 | euint64 | euint128
The larger of the two encrypted values
euint8 maximum = FHE.max(a, b);
euint32 maximum = FHE.max(x, y);
Control Flow
select
Conditionally selects between two encrypted values based on an encrypted boolean condition.
Encrypted boolean condition
ifTrue
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Value to return if condition is true
ifFalse
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Value to return if condition is false (must match ifTrue type)
result
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
Selected value based on condition
Use select instead of if/else statements when working with encrypted values. Conditional branching doesn’t work with encrypted data.
euint8 result = FHE.select(condition, a, b);
ebool result = FHE.select(condition, trueValue, falseValue);
eaddress result = FHE.select(condition, address1, address2);
Decryption Results
getDecryptResult
Retrieves a published decryption result. This function should be called after a result has been published via publishDecryptResult.
Hash of the encrypted value that was previously decrypted
This function will revert if the decryption result is not available yet. Use getDecryptResultSafe for non-reverting behavior.
uint256 result = FHE.getDecryptResult(ctHash);
getDecryptResultSafe
Safely retrieves the decrypted result of a previously decrypted value. Unlike getDecryptResult, this function returns a boolean flag indicating whether the decryption is complete.
Hash of the encrypted value that was previously decrypted
Decrypted result value (valid only if decrypted is true)
Boolean indicating whether the decryption has completed successfully
(uint256 result, bool decrypted) = FHE.getDecryptResultSafe(ctHash);
if (decrypted) {
// Use result
}
Decrypt Result Publishing & Verification
publishDecryptResult
Publishes a signed decrypt result from the Threshold Network to the chain. The TaskManager verifies the ECDSA signature before storing the result. Anyone holding a valid signature can call this.
ctHash
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress | uint256
required
The ciphertext hash to publish a result for
result
bool | uint8 | uint16 | uint32 | uint64 | uint128 | address | uint256
required
The decrypted plaintext value (type matches the ctHash type)
The ECDSA signature from the Threshold Network’s Dispatcher
// Publish a decrypt result for a euint64
FHE.publishDecryptResult(myEncryptedValue, uint64(42), signature);
// Publish for an ebool
FHE.publishDecryptResult(myEncryptedBool, true, signature);
verifyDecryptResult
Verifies a decrypt result signature without publishing. Reverts if the signature is invalid.
ctHash
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress | uint256
required
The ciphertext hash
result
bool | uint8 | uint16 | uint32 | uint64 | uint128 | address | uint256
required
The decrypted plaintext value
The ECDSA signature to verify
Returns true if the signature is valid. Reverts otherwise.
bool valid = FHE.verifyDecryptResult(myEncryptedValue, uint64(42), signature);
publishDecryptResultBatch
Publishes multiple signed decrypt results in a single transaction for gas efficiency.
Array of ciphertext hashes
Array of decrypted plaintext values
Array of ECDSA signatures (one per result)
FHE.publishDecryptResultBatch(ctHashes, results, signatures);
verifyDecryptResultSafe
Same as verifyDecryptResult, but returns false instead of reverting on invalid signatures.
ctHash
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress | uint256
required
The ciphertext hash
plaintext
bool | uint8 | uint16 | uint32 | uint64 | uint128 | address | uint256
required
The decrypted plaintext value
The ECDSA signature to verify
Returns true if valid, false if invalid (never reverts on bad signature)
bool valid = FHE.verifyDecryptResultSafe(myEncryptedValue, uint64(42), signature);
if (!valid) {
revert("Invalid decrypt result signature");
}
verifyDecryptResultSafe
Like verifyDecryptResult, but returns false instead of reverting if the signature is invalid.
ctHash
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Ciphertext handle of the encrypted value
plaintext
bool | uint8 | uint16 | uint32 | uint64 | uint128 | address
required
The decrypted plaintext value
The Threshold Network signature
True if the signature is valid, false otherwise (does not revert)
bool valid = FHE.verifyDecryptResultSafe(encryptedAmount, amount, signature);
if (valid) {
// proceed with verified plaintext
}
publishDecryptResultBatch
Publishes multiple decrypted results on-chain in a single call. Each element is verified independently.
ctHashes
ebool[] | euint8[] | euint16[] | euint32[] | euint64[] | euint128[] | eaddress[]
required
Array of ciphertext handles
plaintexts
bool[] | uint8[] | uint16[] | uint32[] | uint64[] | uint128[] | address[]
required
Array of decrypted plaintext values (must match ctHashes length and type)
Array of Threshold Network signatures (must match ctHashes length)
euint64[] memory handles = new euint64[](2);
handles[0] = encryptedBid1;
handles[1] = encryptedBid2;
uint64[] memory values = new uint64[](2);
values[0] = bid1Plaintext;
values[1] = bid2Plaintext;
bytes[] memory sigs = new bytes[](2);
sigs[0] = sig1;
sigs[1] = sig2;
FHE.publishDecryptResultBatch(handles, values, sigs);
verifyDecryptResultBatch
Verifies multiple Threshold Network signatures in a single call without storing results. Reverts if any signature is invalid.
ctHashes
ebool[] | euint8[] | euint16[] | euint32[] | euint64[] | euint128[] | eaddress[]
required
Array of ciphertext handles
plaintexts
bool[] | uint8[] | uint16[] | uint32[] | uint64[] | uint128[] | address[]
required
Array of decrypted plaintext values
Array of Threshold Network signatures
True if all signatures are valid (reverts otherwise)
bool allValid = FHE.verifyDecryptResultBatch(handles, values, sigs);
verifyDecryptResultBatchSafe
Like verifyDecryptResultBatch, but returns a bool[] indicating which entries are valid instead of reverting.
ctHashes
ebool[] | euint8[] | euint16[] | euint32[] | euint64[] | euint128[] | eaddress[]
required
Array of ciphertext handles
plaintexts
bool[] | uint8[] | uint16[] | uint32[] | uint64[] | uint128[] | address[]
required
Array of decrypted plaintext values
Array of Threshold Network signatures
Array of booleans — true for each valid signature, false for invalid
bool[] memory results = FHE.verifyDecryptResultBatchSafe(handles, values, sigs);
for (uint i = 0; i < results.length; i++) {
if (results[i]) {
// entry i is valid
}
}
Access Control
allow
Grants permission to the specified account to access the encrypted value.
value
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Encrypted value to grant access to
Address of the account to grant access to
FHE.allow(encryptedValue, userAddress);
allowThis
Grants permission to the current contract to access the encrypted value.
value
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Encrypted value to grant access to
Call allowThis after modifying encrypted values if you need to access them later in the same contract.
euint32 counter = FHE.add(counter, FHE.asEuint32(1));
FHE.allowThis(counter); // Required for future access
allowPublic
Grants public permission to access the encrypted value. Once called, anyone can request decryption of this value off-chain via decryptForTx without needing a permit.
value
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Encrypted value to grant public access to
Once allowPublic is called, the value can be decrypted by anyone. Only use this when you intend to reveal the value publicly (e.g., after an auction closes or when unwrapping tokens).
// Allow anyone to decrypt the winning bid after auction closes
FHE.allowPublic(highestBid);
FHE.allowPublic(highestBidder);
// Now anyone can call decryptForTx off-chain without a permit
allowSender
Grants permission to the message sender to access the encrypted value.
value
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Encrypted value to grant access to
FHE.allowSender(encryptedValue);
allowTransient
Grants temporary permission to the specified account to access the encrypted value.
value
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Encrypted value to grant access to
Address of the account to grant temporary access to
FHE.allowTransient(encryptedValue, userAddress);
isAllowed
Checks if the specified account has permission to access the encrypted value.
value
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Encrypted value to check access for
Address of the account to check
True if the account has permission, false otherwise
bool hasAccess = FHE.isAllowed(encryptedValue, userAddress);
isPubliclyAllowed
Checks if the encrypted value has been granted public access via allowPublic.
value
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Encrypted value to check
True if the value is publicly accessible, false otherwise
bool isPublic = FHE.isPubliclyAllowed(encryptedValue);
Utility Functions
isInitialized
Checks whether an encrypted value has been initialized (i.e., is not a zero/empty handle).
value
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Encrypted value to check
True if the value has been initialized, false otherwise
if (FHE.isInitialized(encryptedBalance)) {
// safe to use
}
unwrap
Extracts the raw bytes32 handle from a typed encrypted value.
value
ebool | euint8 | euint16 | euint32 | euint64 | euint128 | eaddress
required
Encrypted value to unwrap
The underlying ciphertext handle
bytes32 handle = FHE.unwrap(encryptedValue);
wrapEbool / wrapEuint8 / wrapEuint16 / wrapEuint32 / wrapEuint64 / wrapEuint128 / wrapEaddress
Wraps a raw bytes32 handle into a typed encrypted value. Use this when you have a raw handle (e.g., from storage or an event) and need to convert it to a typed encrypted value.
Raw ciphertext handle to wrap
ebool val = FHE.wrapEbool(handle);
euint8 val = FHE.wrapEuint8(handle);
euint16 val = FHE.wrapEuint16(handle);
euint32 val = FHE.wrapEuint32(handle);
euint64 val = FHE.wrapEuint64(handle);
euint128 val = FHE.wrapEuint128(handle);
eaddress val = FHE.wrapEaddress(handle);
Bindings
The FHE library provides binding libraries that enable syntactic sugar for working with encrypted types. These bindings allow for more intuitive and object-oriented usage patterns.
Using Bindings
With bindings, you can use encrypted types with dot notation instead of calling FHE.* functions:
// Without bindings
euint8 sum = FHE.add(a, b);
// With bindings
euint8 sum = a.add(b);
Each encrypted type has a corresponding binding library that includes all the operations available for that type.
Example with Bindings
// Use secure encrypted input
InEuint8 encryptedInputA; // Provided by client-side encryption
InEuint8 encryptedInputB; // Provided by client-side encryption
euint8 a = FHE.asEuint8(encryptedInputA);
euint8 b = FHE.asEuint8(encryptedInputB);
// Arithmetic operations
euint8 sum = a.add(b); // Addition
euint8 diff = a.sub(b); // Subtraction
euint8 product = a.mul(b); // Multiplication
euint8 quotient = a.div(b); // Division
euint8 remainder = a.rem(b); // Remainder
euint8 squared = a.square(); // Square
// Bitwise operations
euint8 bitwiseAnd = a.and(b); // AND
euint8 bitwiseOr = a.or(b); // OR
euint8 bitwiseXor = a.xor(b); // XOR
euint8 bitwiseNot = a.not(); // NOT
euint8 shiftLeft = a.shl(b); // Shift Left
euint8 shiftRight = a.shr(b); // Shift Right
euint8 rotateLeft = a.rol(b); // Rotate Left
euint8 rotateRight = a.ror(b); // Rotate Right
// Comparison operations
ebool isEqual = a.eq(b); // Equal
ebool isNotEqual = a.ne(b); // Not Equal
ebool isLessThan = a.lt(b); // Less Than
ebool isLessEqual = a.lte(b); // Less Than or Equal
ebool isGreaterThan = a.gt(b); // Greater Than
ebool isGreaterEqual = a.gte(b); // Greater Than or Equal
// Min/Max functions
euint8 minimum = a.min(b); // Minimum
euint8 maximum = a.max(b); // Maximum
// Type conversion
ebool converted = a.toBool(); // Convert to ebool
euint16 toU16 = a.toU16(); // Convert to euint16
euint32 toU32 = a.toU32(); // Convert to euint32
euint64 toU64 = a.toU64(); // Convert to euint64
euint128 toU128 = a.toU128(); // Convert to euint128
// Utility
bool initialized = a.isInitialized(); // Check if initialized
bytes32 handle = a.unwrap(); // Get raw handle
// Access control
a.allow(address); // Allow access
a.allowThis(); // Allow this contract
a.allowPublic(); // Allow public access
a.allowSender(); // Allow sender
a.allowTransient(address); // Allow transient access
bool hasAccess = a.isAllowed(address); // Check access
Security Considerations
Always consider security implications when working with encrypted data.
-
Initialization: All FHE functions check if their inputs are initialized and set them to 0 if not.
-
Decryption: Decryption is a two-phase process — mark values with
allowPublic on-chain, decrypt off-chain via the Client SDK, then publish/verify the result with publishDecryptResult or verifyDecryptResult. Only reveal values when absolutely necessary.
-
Security Zones: Some functions accept a
securityZone parameter to isolate different encrypted computations. FHE operations can only be performed between ciphertexts that share the same security zone.
-
Access Control: The library provides fine-grained access control through the
allow* functions. Always set proper permissions before accessing encrypted values.
-
Type Safety: Ensure encrypted values use compatible types when performing operations. Type mismatches will cause errors.
Example Usage
Basic Example
This example shows how to perform private computations while keeping all intermediate values encrypted:
// Use secure encrypted input
InEuint8 encryptedInputA; // Provided by client-side encryption
InEuint8 encryptedInputB; // Provided by client-side encryption
euint8 a = FHE.asEuint8(encryptedInputA);
euint8 b = FHE.asEuint8(encryptedInputB);
// Perform operations
euint8 sum = FHE.add(a, b); // Encrypted addition
euint8 product = FHE.mul(a, b); // Encrypted multiplication
ebool isGreater = FHE.gt(b, a); // Encrypted comparison
// Conditional logic
euint8 result = FHE.select(isGreater, sum, product);
// Grant access for future use and allow public decryption
FHE.allowThis(result);
FHE.allowPublic(result);
// Off-chain: client calls decryptForTx(ctHash) to get plaintext + signature
// On-chain: publish the verified result
// FHE.publishDecryptResult(result, plaintext, signature);
Example with Bindings
// Use secure encrypted input
InEuint8 encryptedInputA; // Provided by client-side encryption
InEuint8 encryptedInputB; // Provided by client-side encryption
euint8 a = FHE.asEuint8(encryptedInputA);
euint8 b = FHE.asEuint8(encryptedInputB);
// Perform operations using dot notation
euint8 sum = a.add(b); // Encrypted addition
euint8 product = a.mul(b); // Encrypted multiplication
ebool isGreater = b.gt(a); // Encrypted comparison
// Conditional logic
euint8 result = isGreater.select(sum, product);
// Grant access for future use and allow public decryption
result.allowThis();
result.allowPublic();
Next Steps