Comparisons, Branching, and Loops

Programs are often written with control flow structures such as conditionals and loops in order to repeat actions or change the flow of execution based on certain conditions. Here will will go into what control flow mechanisms can be expressed in a FHE program.

Comparisons

We support the common comparison operators between plaintext and encrypted values: <, >, <=, >=, ==, and !=.

[[clang::fhe_program]] void compare(
    [[clang::encrypted]] uint32_t a,
    [[clang::encrypted]] uint32_t b,
    [[clang::encrypted]] bool *result_lt,
    [[clang::encrypted]] bool *result_gt,
    [[clang::encrypted]] bool *result_le,
    [[clang::encrypted]] bool *result_ge,
    [[clang::encrypted]] bool *result_eq,
    [[clang::encrypted]] bool *result_ne
) {
    *result_lt = (a < b);
    *result_gt = (a > b);
    *result_le = (a <= b);
    *result_ge = (a >= b);
    *result_eq = (a == b);
    *result_ne = (a != b);
}

Branching and the Ternary Operator

We do not support if statements in FHE programs at the moment. However, we do support the ternary operator ?: which can be used to implement choosing between two values based on a condition. This enables writing more complex logic in FHE programs.

[[clang::fhe_program]] uint8_t max(
    [[clang::encrypted]] uint8_t a,
    [[clang::encrypted]] uint8_t b
) {
    // Use the ternary operator to select the maximum value
    return (a > b) ? a : b;
}

Loops

Loops where the loop condition is in plaintext are supported in FHE programs, which includes both while loops and for loops.

[[clang::fhe_program]] uint32_t sum(
    [[clang::encrypted]] uint32_t* a,
    uint32_t len
) {
    uint32_t x = 0;

    for (uint32_t i = 0; i < len; i++) {
        x += a[i];
    }

    return x;
}