Branches in branch-free code
The provided source material discusses the branch instructions present in addition operations when using RV32, a 32-bit register architecture. RV32 registers are limited to 32 bits, requiring the 128-bit addition to be divided into four smaller sub-additions. Each sub-addition involves passing the carry from one to another, resulting in conditional branches that hinder constant-time operations.
The text highlights how conditional moves can be used in other architectures, such as x86 and AArch64, to avoid these branches. However, on RV32, even simple comparisons result in branches. The article also mentions the inconsistent behavior of compilers, such as GCC and Clang, in compiling code for different architectures. For instance, the addition in Zig, when compiled with different compiler versions, still results in conditional branches.
The article notes that even when writing code in a constant-time manner, one must be wary of the compiler's behavior and potential side channels. Compiling code for various targets, such as WebAssembly, Cortex-M0, and generic 32-bit PowerPC, reveals that many targets still produce branches. The text concludes by discussing workarounds, such as using branchless instructions (Zicond) in RISC-V, which can successfully eliminate branches in conditional selection operations.
Written by urgent.news from Lobsters's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.