fixed

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

commit 6b9df020dfb848788ebdeff00a42e69f436d7ed4
parent e103f7cb117e2179a52e3415becb8d4f24aa64f5
Author: Jared Tobin <jared@jtobin.io>
Date:   Fri, 12 Dec 2025 07:49:38 +0400

montgomery: add eq

Diffstat:
Mlib/Numeric/Montgomery/Secp256k1/Curve.hs | 29++++++++++++++++++++++-------
Mlib/Numeric/Montgomery/Secp256k1/Scalar.hs | 29++++++++++++++++++++++-------
2 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/lib/Numeric/Montgomery/Secp256k1/Curve.hs b/lib/Numeric/Montgomery/Secp256k1/Curve.hs @@ -24,6 +24,10 @@ module Numeric.Montgomery.Secp256k1.Curve ( , zero , one + -- * Comparison + , eq + , eq_vartime + -- * Reduction and retrieval , redc , retr @@ -81,13 +85,6 @@ render (Montgomery (# Limb a, Limb b, Limb c, Limb d #)) = instance Show Montgomery where show = show . from --- XX replace with 'eq', remove instance -instance Eq Montgomery where - Montgomery a == Montgomery b = - let !(# Limb a0, Limb a1, Limb a2, Limb a3 #) = a - !(# Limb b0, Limb b1, Limb b2, Limb b3 #) = b - in C.decide (C.ct_eq_wider# (# a0, a1, a2, a3 #) (# b0, b1, b2, b3 #)) - instance Num Montgomery where a + b = add a b a - b = sub a b @@ -99,6 +96,9 @@ instance Num Montgomery where Montgomery (# Limb 0##, Limb 0##, Limb 0##, Limb 0## #) -> 0 _ -> 1 +instance Eq Montgomery where + a == b = C.decide (eq a b) + instance NFData Montgomery where rnf (Montgomery a) = case a of (# _, _, _, _ #) -> () @@ -117,6 +117,21 @@ lo :: (# Limb, Limb #) -> Limb lo (# l, _ #) = l {-# INLINE lo #-} +-- comparison ----------------------------------------------------------------- + +-- | Constant-time equality comparison. +eq :: Montgomery -> Montgomery -> C.Choice +eq + (Montgomery (# Limb a0, Limb a1, Limb a2, Limb a3 #)) + (Montgomery (# Limb b0, Limb b1, Limb b2, Limb b3 #)) + = C.ct_eq_wider# (# a0, a1, a2, a3 #) (# b0, b1, b2, b3 #) +{-# INLINE eq #-} + +-- | Variable-time equality comparison. +eq_vartime :: Montgomery -> Montgomery -> Bool +eq_vartime (Montgomery (Wider -> a)) (Montgomery (Wider -> b)) = + WW.eq_vartime a b + -- innards -------------------------------------------------------------------- redc_inner# diff --git a/lib/Numeric/Montgomery/Secp256k1/Scalar.hs b/lib/Numeric/Montgomery/Secp256k1/Scalar.hs @@ -24,6 +24,10 @@ module Numeric.Montgomery.Secp256k1.Scalar ( , zero , one + -- * Comparison + , eq + , eq_vartime + -- * Reduction and retrieval , redc , retr @@ -81,13 +85,6 @@ render (Montgomery (# Limb a, Limb b, Limb c, Limb d #)) = "(" <> show (W# a) <> ", " <> show (W# b) <> ", " <> show (W# c) <> ", " <> show (W# d) <> ")" --- XX replace with 'eq', remove instance -instance Eq Montgomery where - Montgomery a == Montgomery b = - let !(# Limb a0, Limb a1, Limb a2, Limb a3 #) = a - !(# Limb b0, Limb b1, Limb b2, Limb b3 #) = b - in C.decide (C.ct_eq_wider# (# a0, a1, a2, a3 #) (# b0, b1, b2, b3 #)) -- XX sane? - instance Num Montgomery where a + b = add a b a - b = sub a b @@ -99,6 +96,9 @@ instance Num Montgomery where Montgomery (# Limb 0##, Limb 0##, Limb 0##, Limb 0## #) -> 0 _ -> 1 +instance Eq Montgomery where + a == b = C.decide (eq a b) + instance NFData Montgomery where rnf (Montgomery a) = case a of (# _, _, _, _ #) -> () @@ -117,6 +117,21 @@ lo :: (# Limb, Limb #) -> Limb lo (# l, _ #) = l {-# INLINE lo #-} +-- comparison ----------------------------------------------------------------- + +-- | Constant-time equality comparison. +eq :: Montgomery -> Montgomery -> C.Choice +eq + (Montgomery (# Limb a0, Limb a1, Limb a2, Limb a3 #)) + (Montgomery (# Limb b0, Limb b1, Limb b2, Limb b3 #)) + = C.ct_eq_wider# (# a0, a1, a2, a3 #) (# b0, b1, b2, b3 #) +{-# INLINE eq #-} + +-- | Variable-time equality comparison. +eq_vartime :: Montgomery -> Montgomery -> Bool +eq_vartime (Montgomery (Wider -> a)) (Montgomery (Wider -> b)) = + WW.eq_vartime a b + -- innards -------------------------------------------------------------------- redc_inner#