vestigia

Detect where execution depends on secrets.
git clone git://git.ppad.tech/vestigia.git
Log | Files | Refs | README | LICENSE

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