Access Control List
How it works?
fhEVM includes an Access Control List (ACL) system that allows you to define which addresses have the right to manipulate a ciphertext. This feature prevents any address from accessing the contents of any ciphertext.
These ACLs can be adjusted in two ways:
TFHE.allow(ciphertext, address)
Permanently, on the blockchain. This allows a ciphertext to be used by a specific address at any time.TFHE.allowTransient(ciphertext, address)
Temporarily. The ciphertext is then authorized only for the duration of the transaction.
Permanent allowance will store the ACL in a dedicated contract, while a temporary allowance will store it in transient storage, allowing developers to save gas. Transient allowance is particularly useful when calling an external function using a ciphertext as a parameter.
To illustrate, here is a simple example where one function calls another:
Automatic (transient) allowance
To simplify matters, a number of functions automatically generate temporary access (using TFHE.allowTransient
) for the contract that calls the function. This applies to:
TFHE.asEuintXX()
,TFHE.asEaddress()
,TFHE.asEbool()
TFHE.randXX()
All results from computation (
TFHE.add()
,TFHE.select()
, ...)
Security best practice: isSenderAllowed()
When a function receives a ciphertext (such as ebool
, euint8
, eaddress
, ...), it needs to verify that the sender also has access to this ciphertext. This is important because otherwise, a contract could send any ciphertext authorized for the contract and potentially exploit the function to retrieve the value. For example, an attacker could transfer someone's balance as an encrypted amount. Without require(TFHE.isSenderAllowed(encryptedAmount))
, an attacker who doesn't have access to this balance could determine the value by transferring the balance between two well-funded accounts.
ACL for reencryption
If a ciphertext must be reencrypted by a user, then explicit access must be granted to them. If this authorization is not given, the user will be unable to request a reencryption of this ciphertext. Due to the reencryption mechanism, a user signs a public key associated with a specific contract; therefore, the ciphertext also needs to be allowed for the contract. Let's take, for example, a transfer in an ERC20:
Last updated