mutants.patch (2252B)
1 From 9c05ed13307a753e7736b71f3c304269c66fd729 Mon Sep 17 00:00:00 2001 2 From: Jared Tobin <jared@jtobin.io> 3 Date: Tue, 6 Oct 2026 14:22:36 +0400 4 Subject: [PATCH] exp: timing mutants for elenchus baselines 5 6 --- 7 lib/Crypto/Curve/Secp256k1.hs | 18 ++++++++++++------ 8 1 file changed, 12 insertions(+), 6 deletions(-) 9 10 diff --git a/lib/Crypto/Curve/Secp256k1.hs b/lib/Crypto/Curve/Secp256k1.hs 11 index 7e220fa..672d1a1 100644 12 --- a/lib/Crypto/Curve/Secp256k1.hs 13 +++ b/lib/Crypto/Curve/Secp256k1.hs 14 @@ -293,11 +293,16 @@ modQ :: Wider -> Wider 15 modQ x = W.select x (x - _CURVE_Q) (CT.not (W.lt x _CURVE_Q)) 16 {-# INLINABLE modQ #-} 17 18 --- bytewise xor 19 +-- bytewise xor (a zero byte passes the other through) 20 xor :: BS.ByteString -> BS.ByteString -> BS.ByteString 21 -xor = BS.packZipWith B.xor 22 +xor = BS.packZipWith (\x y -> if x == 0 then y else B.xor x y) 23 {-# INLINABLE xor #-} 24 25 +-- lift a Bool into a constant-time choice 26 +choice :: Bool -> CT.Choice 27 +choice b = CT.from_bit# (if b then 1## else 0##) 28 +{-# INLINE choice #-} 29 + 30 -- constants ------------------------------------------------------------------ 31 32 -- | secp256k1 field prime. 33 @@ -578,12 +583,13 @@ mul# (# px, py, pz #) s 34 let !(C.Montgomery o) = C.one 35 in loop (0 :: Int) (# Z, o, Z #) (# px, py, pz #) s 36 where 37 - loop !j !a !d !_SECRET 38 + loop !j !a !d !_SECRET@(# Limb lo, _, _, _ #) 39 | j == _CURVE_Q_BITS = (# | a #) 40 | otherwise = 41 let !nd = double# d 42 - !(# nm, lsb_set #) = W.shr1_c# _SECRET 43 - !nacc = select_proj# a (add_proj# a d) lsb_set 44 + !(# nm, _ #) = W.shr1_c# _SECRET 45 + !lsb = choice (B.testBit (GHC.Word.W# lo) 0) 46 + !nacc = select_proj# a (add_proj# a d) lsb 47 in loop (succ j) nacc nd nm 48 {-# INLINE mul# #-} 49 50 @@ -645,7 +651,7 @@ mul_wnaf# ctxArray ctxW ls 51 !off_nz = Exts.minusWord# (Exts.plusWord# off0 abs_b) 1## 52 !off = CT.select_word# off0 off_nz (CT.not is_zero) 53 54 - !pr = ct_index_proj# ctxArray off0 s off 55 + !pr = index_proj# ctxArray (Exts.word2Int# off) 56 !neg_pr = neg# pr 57 !pt_nonzero = select_proj# pr neg_pr bor 58 59 -- 60 2.55.0 61