Skip to content

fix: constant-time modular arithmetic in interactive bootstrapping decrypt path#1211

Open
BAder82t wants to merge 1 commit into
openfheorg:devfrom
BAder82t:fix/ct-decrypt-path
Open

fix: constant-time modular arithmetic in interactive bootstrapping decrypt path#1211
BAder82t wants to merge 1 commit into
openfheorg:devfrom
BAder82t:fix/ct-decrypt-path

Conversation

@BAder82t

Copy link
Copy Markdown
Collaborator

Summary

Closes #1198.

PolynomialRound (called from IntBootDecrypt) operates on
cs = c[1]*s + c[0] — a polynomial directly correlated to the secret
key. Its inner loop called ModMulFastConst and ModAddFastEq on each
coefficient, both of which contain secret-dependent conditional branches
that are timing oracles.

This PR follows the architecture suggested when closing #1177: CT
variants are added alongside the originals and used only in the
sensitive decrypt path. All other callers — NTT butterfly, EvalMult,
server-side operations — remain on the original fast variants unchanged.

Changes

  • new utils/constanttime.hSubIfGE and AddIfNeg branchless primitives in namespace lbcrypto::ct
  • ubintnat.hModAddFastEqCT and ModMulFastConstCT added alongside originals; originals untouched
  • rns-multiparty.cppPolynomialRound uses CT variants (4 lines)

Benchmarks (Apple M-series, clang -O3, 20M random inputs)

Function Original (branch) CT (mask)
ModAddFastEq 0.18 ns 0.17 ns (−3%)
ModMulFastConst 0.71 ns 0.71 ns (0%)

No regression. The mask idiom eliminates unpredictable branch penalties
without asm barriers, so vectorisation and scheduling are preserved.

2050/2050 tests pass.

Known limitation

CT guarantees do not hold on WASM (__EMSCRIPTEN__). The MultD
function used inside ModMulFastConstCT emulates 128-bit multiply in
software with carry-detect branches that are data-dependent on every
multiply. Fixing this requires a branchless carry implementation and is
out of scope here; it is documented in constanttime.h.

…crypt path

Closes openfheorg#1198. Adds CT variants of ModAddFastEq and ModMulFastConst used
in PolynomialRound, which operates on cs = c[1]*s + c[0] — a polynomial
that is directly secret-key-correlated. The original branching variants
remain untouched for server-side hot paths (NTT, EvalMult, etc.).

New utils/constanttime.h provides SubIfGE and AddIfNeg using the
branchless mask idiom (no asm barriers, vectorisation preserved).
NativeIntegerT gains ModAddFastEqCT and ModMulFastConstCT alongside
the existing fast variants.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant