Comment on page
😯
No Branching/If...else?
Writing code with Fully Homomorphic Encryption (FHE) introduces a fundamental shift in how we handle conditionals or branches in our code. As you already know, with FHE, we're operating on encrypted data. This means we can't use typical
if...else
branching structures, because we don't have visibility into the actual values we're comparing.For example, this will not work:
euint32 a = TFHE.asEuint32(10);
euint32 b = TFHE.asEuint32(20);
if (TFHE.lt(a, b)) {
return TFHE.reencrypt(a);
} else {
return TFHE.reencrypt(b);
}
When writing Solidity contracts for our blockchain, you'll need to consider all possible branches of a conditional at the same time. It's somewhat akin to writing constant-time cryptographic code, where you want to avoid timing attacks that could leak information about secret data.
To handle these conditionals, we use a concept called a "ciphertext multiplexer", or
cmux
for short. A multiplexer in the digital logic is a combinational circuit that selects binary information from one of many input lines and directs it to a single output line. The selection of a particular input line is controlled by a set of selection lines.cmux
operates on encrypted unsigned integers (euint
), and it takes three arguments - a condition, a 'true' branch, and a 'false' branch. It evaluates both branches, but only the result from the branch corresponding to the condition will be "real", while the other will be "garbage". It's vital to note that all operations happen regardless of the condition's truth, ensuring constant execution time and preventing potential leaks of information about the condition or the data.ebool isHigher = TFHE.lt(existingBid, value);
bids[msg.sender] = TFHE.cmux(isHigher, value, existingBid);
In this snippet, the bidder is trying to place a new bid that is higher than their existing one. The
TFHE.lt
function checks if the existing bid is less than the new value and assigns the result to isHigher
.Then
TFHE.cmux
takes over. If isHigher
is true (remember, this is still an encrypted boolean, not a plaintext one), it returns the value
(the new bid), otherwise, it returns existingBid
. This gets assigned to bids[msg.sender]
, effectively replacing the old bid with the new one if the new one is higher.The crucial part here is that all these operations take place on encrypted data, so the actual value of the bids and the result of the comparison stay concealed. It's a powerful pattern to handle conditional execution in the context of FHE data, maintaining privacy without sacrificing functionality.
Last modified 4mo ago