/* ZUPT — X25519 Constant-Time Conditional Swap (Jasmin) * Copyright (c) 2026 Cristian Cezar Moisés * SPDX-License-Identifier: AGPL-3.0-or-later * * CT-REQUIRED: fe_cswap must not leak cond via timing. * This is the only CT-critical field operation in X25519. * fe_add/fe_sub/fe_mul use the C fallback. No fixed-latency claim is made for * every compiler, x86-64 CPU, or resulting binary. * * 4 × u64 limbs, pure register operations, no intrinsics needed. */ export fn zupt_fe_cswap( reg u64 a_ptr, reg u64 b_ptr, reg u64 cond) { reg u64 mask ta tb diff; inline int i; mask = 0; mask -= cond; for i = 0 to 4 { ta = [a_ptr + 8 * i]; tb = [b_ptr + 8 * i]; diff = ta; diff ^= tb; diff &= mask; ta ^= diff; tb ^= diff; [a_ptr + 8 * i] = ta; [b_ptr + 8 * i] = tb; } }