/* Zupt — X25519 Constant-Time Conditional Swap (Jasmin) * Copyright (c) 2026 Cristian Cezar Moisés — MIT License * * 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 C fallback (data-independent timing * on x86-64 — ADD/MUL have fixed latency). * * 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; } }