From 21ae64852a531c36ae3166aa2b6f1fbaaf76c6f9 Mon Sep 17 00:00:00 2001 From: Frank Denis <124872+jedisct1@users.noreply.github.com> Date: Fri, 22 Dec 2023 16:57:16 +0100 Subject: [PATCH] std.crypto.kem.kyber: mitigate KyberSlash (#18316) On some architectures, including AMD Zen CPUs, dividing a secret by a constant denominator may not be a constant-time operation. And most Kyber implementations, including ours, could leak the hamming weight of the shared secret because of this. See: https://kyberslash.cr.yp.to Multiplications aren't guaranteed to be constant-time either, but at least on the CPUs we currently support, it is. --- lib/std/crypto/kyber_d00.zig | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/std/crypto/kyber_d00.zig b/lib/std/crypto/kyber_d00.zig index ba6ed67ec8..ad8e060765 100644 --- a/lib/std/crypto/kyber_d00.zig +++ b/lib/std/crypto/kyber_d00.zig @@ -1020,8 +1020,15 @@ const Poly = struct { // = ⌊(2ᵈ/q)x+½⌋ mod⁺ 2ᵈ // = ⌊((x << d) + q/2) / q⌋ mod⁺ 2ᵈ // = DIV((x << d) + q/2, q) & ((1<> 36) == 1); + const u: u32 = @intCast((@as(u64, t + q_over_2) * 20642679) >> 36); + in[i] = @intCast(u & two_d_min_1); } // Now we pack the d-bit integers from `in' into out as bytes.