commit 9b4726690a9435f20fb183937d13cf2dbc3ed3ad
parent 40bbdb599fd366cc298572ed57aedfc993e233c6
Author: Jared Tobin <jared@jtobin.io>
Date: Wed, 17 Dec 2025 16:47:20 -0330
lib: add const-time montgomery selection
Diffstat:
2 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/lib/Numeric/Montgomery/Secp256k1/Curve.hs b/lib/Numeric/Montgomery/Secp256k1/Curve.hs
@@ -34,6 +34,10 @@ module Numeric.Montgomery.Secp256k1.Curve (
, redc#
, retr#
+ -- * Constant-time selection
+ , select#
+ , select
+
-- * Montgomery arithmetic
, add
, add#
@@ -1032,3 +1036,26 @@ odd# = WW.odd#
-- True
odd :: Montgomery -> Bool
odd (Montgomery m) = C.decide (odd# m)
+
+-- constant-time selection ----------------------------------------------------
+
+select#
+ :: (# Limb, Limb, Limb, Limb #) -- ^ a
+ -> (# Limb, Limb, Limb, Limb #) -- ^ b
+ -> C.Choice -- ^ c
+ -> (# Limb, Limb, Limb, Limb #) -- ^ result
+select# = WW.select#
+{-# INLINE select# #-}
+
+-- | Return a if c is truthy, otherwise return b.
+--
+-- >>> import qualified Data.Choice as C
+-- >>> select 0 1 (C.true# ())
+-- 1
+select
+ :: Montgomery -- ^ a
+ -> Montgomery -- ^ b
+ -> C.Choice -- ^ c
+ -> Montgomery -- ^ result
+select (Montgomery a) (Montgomery b) c = Montgomery (select# a b c)
+
diff --git a/lib/Numeric/Montgomery/Secp256k1/Scalar.hs b/lib/Numeric/Montgomery/Secp256k1/Scalar.hs
@@ -34,6 +34,10 @@ module Numeric.Montgomery.Secp256k1.Scalar (
, redc#
, retr#
+ -- * Constant-time selection
+ , select#
+ , select
+
-- * Montgomery arithmetic
, add
, add#
@@ -970,3 +974,26 @@ odd# = WW.odd#
-- True
odd :: Montgomery -> Bool
odd (Montgomery m) = C.decide (odd# m)
+
+-- constant-time selection ----------------------------------------------------
+
+select#
+ :: (# Limb, Limb, Limb, Limb #) -- ^ a
+ -> (# Limb, Limb, Limb, Limb #) -- ^ b
+ -> C.Choice -- ^ c
+ -> (# Limb, Limb, Limb, Limb #) -- ^ result
+select# = WW.select#
+{-# INLINE select# #-}
+
+-- | Return a if c is truthy, otherwise return b.
+--
+-- >>> import qualified Data.Choice as C
+-- >>> select 0 1 (C.true# ())
+-- 1
+select
+ :: Montgomery -- ^ a
+ -> Montgomery -- ^ b
+ -> C.Choice -- ^ c
+ -> Montgomery -- ^ result
+select (Montgomery a) (Montgomery b) c = Montgomery (select# a b c)
+