fixed

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

commit 2028df25ebed756248130625ee9138e8f2da595e
parent 150b356c3e9c8d8cb8792ebe4b83db5ed3b7c925
Author: Jared Tobin <jared@jtobin.io>
Date:   Wed, 24 Dec 2025 09:50:04 -0330

lib: export unboxed montgomery exp

Diffstat:
Mlib/Data/Word/Wider.hs | 6+++---
Mlib/Numeric/Montgomery/Secp256k1/Curve.hs | 12++++++++++--
Mlib/Numeric/Montgomery/Secp256k1/Scalar.hs | 12++++++++++--
3 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/lib/Data/Word/Wider.hs b/lib/Data/Word/Wider.hs @@ -506,9 +506,9 @@ add_o# (# a0, a1, a2, a3 #) (# b0, b1, b2, b3 #) = -- >>> add_o 1 (2 ^ (256 :: Word) - 1) -- (0,1) add_o - :: Wider - -> Wider - -> (Wider, Word) + :: Wider -- ^ augend + -> Wider -- ^ addend + -> (Wider, Word) -- ^ (sum, carry bit) add_o (Wider a) (Wider b) = let !(# s, Limb c #) = add_o# a b in (Wider s, W# c) diff --git a/lib/Numeric/Montgomery/Secp256k1/Curve.hs b/lib/Numeric/Montgomery/Secp256k1/Curve.hs @@ -54,6 +54,7 @@ module Numeric.Montgomery.Secp256k1.Curve ( , sqrt_vartime , sqrt# , exp + , exp# , odd# , odd_vartime ) where @@ -1526,7 +1527,13 @@ sqrt# a = -- >>> exp 2 10 -- 1024 exp :: Montgomery -> Wider -> Montgomery -exp (Montgomery b) (Wider e) = +exp (Montgomery b) (Wider e) = Montgomery (exp# b e) + +exp# + :: (# Limb, Limb, Limb, Limb #) + -> (# Limb, Limb, Limb, Limb #) + -> (# Limb, Limb, Limb, Limb #) +exp# b e = let !o = (# Limb 0x1000003D1##, Limb 0##, Limb 0##, Limb 0## #) loop !r !_ !_ 0 = r loop !r !m !ex !n = @@ -1535,7 +1542,8 @@ exp (Montgomery b) (Wider e) = !nr = select# r candidate bit !nm = sqr# m in loop nr nm ne (n - 1) - in Montgomery (loop o b e (256 :: Word)) + in loop o b e (256 :: Word) +{-# INLINE exp# #-} odd# :: (# Limb, Limb, Limb, Limb #) -> C.Choice odd# = WW.odd# diff --git a/lib/Numeric/Montgomery/Secp256k1/Scalar.hs b/lib/Numeric/Montgomery/Secp256k1/Scalar.hs @@ -52,6 +52,7 @@ module Numeric.Montgomery.Secp256k1.Scalar ( , inv , inv# , exp + , exp# , odd# , odd_vartime ) where @@ -950,7 +951,13 @@ inv (Montgomery w) = Montgomery (inv# w) -- >>> exp 2 10 -- 1024 exp :: Montgomery -> Wider -> Montgomery -exp (Montgomery b) (Wider e) = +exp (Montgomery b) (Wider e) = Montgomery (exp# b e) + +exp# + :: (# Limb, Limb, Limb, Limb #) + -> (# Limb, Limb, Limb, Limb #) + -> (# Limb, Limb, Limb, Limb #) +exp# b e = let !o = (# Limb 0x402DA1732FC9BEBF##, Limb 0x4551231950B75FC4## , Limb 0x0000000000000001##, Limb 0x0000000000000000## #) loop !r !_ !_ 0 = r @@ -960,7 +967,8 @@ exp (Montgomery b) (Wider e) = !nr = select# r candidate bit !nm = sqr# m in loop nr nm ne (n - 1) - in Montgomery (loop o b e (256 :: Word)) + in loop o b e (256 :: Word) +{-# INLINE exp# #-} odd# :: (# Limb, Limb, Limb, Limb #) -> C.Choice odd# = WW.odd#