Comment on page

Require vs. Optimistic Require

A require statement is used to evaluate conditions immediately. If a condition is not met, the execution of the contract halts and any state changes are reverted.
uint a = 10;
uint b = 20;
require(a > b, "A must be greater than B");
// some operations...
In the above example, if a isn't greater than b, the execution stops, and the "some operations" part never gets executed.
Let's demonstrate how to use require on encrypted integers:
euint32 a = TFHE.asEuint32(some_encrypted_value);
euint32 b = TFHE.asEuint32(some_other_encrypted_value);
TFHE.req(TFHE.le(a, b));
// some operations...
In this example the execution will be immediately halted if the condition is not met.
in the FHE context, using require to evaluate conditions on encrypted integers is computationally expensive due to the complexity of operations on encrypted data. This cost can compound if there are multiple require statements in a single execution.
To manage this, we introduce the concept of optimistic require. It allows deferring the evaluation of conditions until the end of the function execution, providing a more efficient way of dealing with conditions in FHE contracts.
euint32 a = TFHE.asEuint32(some_encrypted_value);
euint32 b = TFHE.asEuint32(some_other_encrypted_value);
TFHE.optReq(TFHE.le(a, b));
// some operations...
Here, the "some operations" part will get executed irrespective of whether a is less than or equal to b. The condition TFHE.le(a, b) will be evaluated at the end of execution. If it's false, the transaction will be reverted, just as if a require statement had failed. This allows more efficient execution of multiple `require` statements

So why use "optimistic require"?

It's all about performance. Since all the conditions are evaluated at the end of the function, we don't need to pause after each step to check. This results in faster execution. However, there's a trade-off: It can consume more gas because it allows computations that might not be necessary if a condition isn't met.
A complete example of this concept can be seen in the OptimisticRequire Contract.
Pro Tip: Optimistic require can also be used to prevent side-channel leakage from the gas used by the contract. Examining the gas used can be used to infer things about what happened, even without knowing the data!