fixed

Pure Haskell large fixed-width integers and Montgomery arithmetic.
git clone git://git.ppad.tech/fixed.git
Log | Files | Refs | README | LICENSE

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:
Mlib/Numeric/Montgomery/Secp256k1/Curve.hs | 27+++++++++++++++++++++++++++
Mlib/Numeric/Montgomery/Secp256k1/Scalar.hs | 27+++++++++++++++++++++++++++
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) +