From ebc1c263b44d084052ec1d7610f25632a19baee3 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Mon, 7 Sep 2026 21:03:22 +0200 Subject: [PATCH 1/2] crypto.ff: hide constant-time selection masks from optimizer Hide the selection mask so LLVM can't replace it with a branch around the calling loop. Fixes #37023 --- lib/std/crypto/ff.zig | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/std/crypto/ff.zig b/lib/std/crypto/ff.zig index 4a465f433635179162db81870e7a3ec162027e4d..26e3ec82fc43e221927dd539e88c9ac5f9a1caac 100644 --- a/lib/std/crypto/ff.zig +++ b/lib/std/crypto/ff.zig @@ -1083,12 +1083,20 @@ pub fn Modulus(comptime max_bits: comptime_int) type { }; } +fn valueBarrier(x: Limb) Limb { + if (@inComptime() or builtin.zig_backend == .stage2_c) return x; + return asm ("" + : [ret] "=r" (-> Limb), + : [x] "0" (x), + ); +} + const ct = if (std.options.side_channels_mitigations == .none) ct_unprotected else ct_protected; const ct_protected = struct { // Returns x if on is true, otherwise y. fn select(on: bool, x: Limb, y: Limb) Limb { - const mask = @as(Limb, 0) -% @intFromBool(on); + const mask = valueBarrier(@as(Limb, 0) -% @intFromBool(on)); return y ^ (mask & (y ^ x)); } -- 2.54.0 From d7fe3b57fcb207532d1e37d6185269112f02910c Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sat, 3 Oct 2026 14:34:22 +0200 Subject: [PATCH 2/2] Make valueBarrier a no-op on stage2_wasm --- lib/std/crypto/ff.zig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/std/crypto/ff.zig b/lib/std/crypto/ff.zig index 26e3ec82fc43e221927dd539e88c9ac5f9a1caac..81f55539af0c276f20dbef4cfe96809ddf317ab3 100644 --- a/lib/std/crypto/ff.zig +++ b/lib/std/crypto/ff.zig @@ -1084,7 +1084,11 @@ pub fn Modulus(comptime max_bits: comptime_int) type { } fn valueBarrier(x: Limb) Limb { - if (@inComptime() or builtin.zig_backend == .stage2_c) return x; + if (@inComptime()) return x; + switch (builtin.zig_backend) { + .stage2_c, .stage2_wasm => return x, + else => {}, + } return asm ("" : [ret] "=r" (-> Limb), : [x] "0" (x), -- 2.54.0