Skip to main content

Supported Types and Operations

The library exposes utility functions for FHE operations. The goal of the library is to provide a seamless developer experience for writing smart contracts that can operate on confidential data.

Types​

The library provides a type system that is checked both at compile time and at run time. The structure and operations related to these types are described in this sections.

We currently support encrypted integers of bit length up to 256 bits and special types such as ebool and eaddress.

The encrypted integers behave as much as possible as Solidity's integer types. However, behaviour such as "revert on overflow" is not supported as this would leak some information of the encrypted integers. Therefore, arithmetic on euint types is unchecked, i.e. there is wrap-around on overlow.

In the back-end, encrypted integers are FHE ciphertexts. The library abstracts away the ciphertexts and presents pointers to ciphertexts, or ciphertext handles, to the smart contract developer. The euint, ebool and eaddress types are wrappers over these handles.

Supported types
nameBit SizeUsage
euint88Compute
euint1616Compute
euint3232Compute
euint6464Compute
euint128128Compute
euint256256Compute
ebool8Compute
eaddress160Compute
nameBit SizeUsage
inEuint88Input
inEuint1616Input
inEuint3232Input
inEuint6464Input
inEuint128128Input
inEuint256256Input
inEbool8Input
inEaddress160Input

Operations​

There are three ways to perform operations with FHE.sol:

Using Direct Function Calls​

Direct function calls are the most straightforward way to perform operations with FHE.sol. For example, if you want to add two encrypted 8-bit integers (euint8), you can do so as follows:

euint8 result = FHE.add(lhs, rhs);

Here, lhs and rhs are your euint8 variables, and result will store the outcome of the addition.

Using Library Bindings​

FHE.sol also provides library bindings, allowing for a more natural syntax. To use this, you first need to include the library for your specific data type. For euint8, the usage would look like this:

euint8 result = lhs.add(rhs);

In this example, lhs.add(rhs) performs the addition, using the library function implicitly.

Utilizing Operator Overloading​

For an even more intuitive approach, FHE.sol supports operator overloading. This means you can use standard arithmetic operators like +, -, *, etc., directly on encrypted types. Here's how you can use it for adding two euint8 values:

euint8 result = lhs + rhs;

With operator overloading, lhs + rhs performs the addition seamlessly.

Comparisons​

Unlike other operations in FHE.sol, comparison operations do not support their respective operators (e.g. >, < etc.). This is because solidity expects these operators to return a boolean value, which is not possible with FHE. Intuitively, this is because returning a boolean value would leak information about the encrypted data.

Instead, comparison operations are implemented as functions that return an ebool type.

tip

The ebool type is not a real boolean type. It is implemented as a euint8

Supported Operations​

tip

A documented documentation of each and every function in FHE.sol (including inputs and outputs) can be found in FHE.sol

All operations supported by FHE.sol are listed in the table below. For performance reasons, not all operations are supported for all types.

Please refer to the table below for a comprehensive list of supported operations. This list will evolve as the network matures.

Note that all functions are supported in both direct function calls and library bindings. However, operator overloading is only supported for the operations listed in the table (solidity please support operator overloading for boolean return types!).

nameFHE.sol functionOperatoreuint8euint16euint32euint64euint128euint256ebooleaddress
Additionadd+βœ“βœ“βœ“βœ“βœ“n/an/an/a
Subtractionsub-βœ“βœ“βœ“βœ“βœ“n/an/an/a
Multiplicationmul*βœ“βœ“βœ“βœ“xn/an/an/a
Bitwise Andand&βœ“βœ“βœ“βœ“βœ“n/aβœ“n/a
Bitwise Oror|βœ“βœ“βœ“βœ“βœ“n/aβœ“n/a
Bitwise Xorxor^βœ“βœ“βœ“βœ“βœ“n/aβœ“n/a
Divisiondiv/βœ“βœ“βœ“xxn/an/an/a
Remainderrem%βœ“βœ“βœ“xxn/an/an/a
Shift Rightshr>>βœ“βœ“βœ“βœ“βœ“n/an/an/a
Shift Leftshl<<βœ“βœ“βœ“βœ“βœ“n/an/an/a
Equaleqn/aβœ“βœ“βœ“βœ“βœ“βœ“βœ“βœ“
Not equalnen/aβœ“βœ“βœ“βœ“βœ“βœ“βœ“βœ“
Greater than or equalgten/aβœ“βœ“βœ“βœ“βœ“n/an/an/a
Greater thangtn/aβœ“βœ“βœ“βœ“βœ“n/an/an/a
Less than or equallten/aβœ“βœ“βœ“βœ“βœ“n/an/an/a
Less thanltn/aβœ“βœ“βœ“βœ“βœ“n/an/an/a
Minminn/aβœ“βœ“βœ“βœ“βœ“n/an/an/a
Maxmaxn/aβœ“βœ“βœ“βœ“βœ“n/an/an/a
Notnotn/aβœ“βœ“βœ“βœ“βœ“n/aβœ“n/a
Selectselectn/aβœ“βœ“βœ“βœ“βœ“βœ“βœ“βœ“
Requirereqn/aβœ“βœ“βœ“βœ“βœ“βœ“βœ“βœ“
Decryptdecryptn/aβœ“βœ“βœ“βœ“βœ“βœ“βœ“βœ“
Seal OutputsealOutputn/aβœ“βœ“βœ“βœ“βœ“βœ“βœ“βœ“
danger

At the moment it is not possible to do ebool result = (lhs == rhs) and others that return a boolean result. This is because FHE.sol expects a ebool, while Solidity only allows overloading to return a regular boolean. Instead, we recommend ebool result = lhs.eq(rhs).

danger

Using require and decrypt in a TX is dangerous as it can break the confidentiality of the data. Please refer to Useful-Tips to read some more

tip

Division and Remainder by 0 will output with an encrypted representation of the maximal value of the uint that is used (Ex. encrypted 255 for euint8)