If-Then-Else

Conditional logic using FHE.select for privacy-preserving branching. Demonstrates if-then-else logic on encrypted values. Unlike regular if/else, FHE.select avoids information leakage by evaluating both branches.

To run this example correctly, make sure the files are placed in the following directories:

  • .sol file → <your-project-root-dir>/contracts/

  • .ts file → <your-project-root-dir>/test/

This ensures Hardhat can compile and test your contracts as expected.

🔐 FHE API Reference (8 items)

Types: ebool · euint8 · externalEuint8

Functions:

  • FHE.allow() - Grants PERMANENT permission for address to decrypt/use value

  • FHE.allowThis() - Grants contract permission to operate on ciphertext

  • FHE.fromExternal() - Validates and converts external encrypted input using inputProof

  • FHE.ge() - Encrypted greater-or-equal: returns ebool(a >= b)

  • FHE.select() - Encrypted if-then-else: select(cond, a, b) → returns a if true, b if false

// SPDX-License-Identifier: BSD-3-Clause-Clear
pragma solidity ^0.8.24;

import {FHE, ebool, euint8, externalEuint8} from "@fhevm/solidity/lib/FHE.sol";
import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";

/**
 * @notice Conditional logic using FHE.select for privacy-preserving branching.
 *         Demonstrates if-then-else logic on encrypted values. Unlike regular
 *         if/else, FHE.select avoids information leakage by evaluating both branches.
 *
 * @dev Evaluates both branches using encrypted conditions (FHE.select ~120k gas).
 */
contract FHEIfThenElse is ZamaEthereumConfig {
    euint8 private _a;
    euint8 private _b;
    euint8 private _max;

    /// @notice Sets the first operand (encrypted)
    function setA(externalEuint8 inputA, bytes calldata inputProof) external {
        _a = FHE.fromExternal(inputA, inputProof);
        FHE.allowThis(_a);
    }

    /// @notice Sets the second operand (encrypted)
    function setB(externalEuint8 inputB, bytes calldata inputProof) external {
        _b = FHE.fromExternal(inputB, inputProof);
        FHE.allowThis(_b);
    }

    /// @notice Compute max(a, b) without revealing which is larger
    /// @dev Uses FHE.select() - the encrypted "if-then-else"
    function computeMax() external {
        ebool aIsGreaterOrEqual = FHE.ge(_a, _b);

        // 🔀 Why select? if/else would leak which branch was taken!
        // select evaluates BOTH branches, picks one based on encrypted condition
        _max = FHE.select(aIsGreaterOrEqual, _a, _b);

        // Grant permissions for decryption
        FHE.allowThis(_max);
        FHE.allow(_max, msg.sender);
    }

    /// @notice Returns the encrypted result
    function result() public view returns (euint8) {
        return _max;
    }
}

Last updated