fixed

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

commit bdbabb7d66332fe28243fb2d1da53aaa73cc7792
parent d32ed8938f78d157bff3f70eb5f28b0bc86f447e
Author: Jared Tobin <jared@jtobin.io>
Date:   Sun, 30 Nov 2025 15:14:47 +0400

lib: consistent naming for overflowing addition

Diffstat:
Mlib/Data/Word/Wide.hs | 18+++++++++---------
Mlib/Data/Word/Wider.hs | 20+++++++++++++++-----
Mlib/Numeric/Montgomery/Secp256k1/Curve.hs | 32++++++++++++++++----------------
Mlib/Numeric/Montgomery/Secp256k1/Scalar.hs | 32++++++++++++++++----------------
Mppad-fixed.cabal | 1+
5 files changed, 57 insertions(+), 46 deletions(-)

diff --git a/lib/Data/Word/Wide.hs b/lib/Data/Word/Wide.hs @@ -34,12 +34,12 @@ module Data.Word.Wide ( -- * Arithmetic , add - , add_c + , add_o , sub , mul -- * Unboxed Arithmetic - , add_c# + , add_o# , add_w# , sub_b# , sub_w# @@ -147,24 +147,24 @@ not (Wide w) = Wide (not_w# w) -- | Overflowing addition, computing 'a + b', returning the sum and a -- carry bit. -add_c# +add_o# :: (# Limb, Limb #) -- ^ augend -> (# Limb, Limb #) -- ^ addend -> (# (# Limb, Limb #), Limb #) -- ^ (# sum, carry bit #) -add_c# (# a0, a1 #) (# b0, b1 #) = +add_o# (# a0, a1 #) (# b0, b1 #) = let !(# s0, c0 #) = L.add_o# a0 b0 !(# s1, c1 #) = L.add_c# a1 b1 c0 in (# (# s0, s1 #), c1 #) -{-# INLINE add_c# #-} +{-# INLINE add_o# #-} -- | Overflowing addition on 'Wide' words, computing 'a + b', returning -- the sum and carry. -add_c +add_o :: Wide -- ^ augend -> Wide -- ^ addend -> (Wide, Word) -- ^ (sum, carry) -add_c (Wide a) (Wide b) = - let !(# s, Limb c #) = add_c# a b +add_o (Wide a) (Wide b) = + let !(# s, Limb c #) = add_o# a b in (Wide s, W# c) -- | Wrapping addition, computing 'a + b'. @@ -173,7 +173,7 @@ add_w# -> (# Limb, Limb #) -- ^ addend -> (# Limb, Limb #) -- ^ sum add_w# a b = - let !(# c, _ #) = add_c# a b + let !(# c, _ #) = add_o# a b in c {-# INLINE add_w# #-} diff --git a/lib/Data/Word/Wider.hs b/lib/Data/Word/Wider.hs @@ -206,17 +206,27 @@ not (Wider w) = Wider (not# w) -- | Overflowing addition, computing 'a + b', returning the sum and a -- carry bit. -add_c# +add_o# :: (# Limb, Limb, Limb, Limb #) -- ^ augend -> (# Limb, Limb, Limb, Limb #) -- ^ addend -> (# (# Limb, Limb, Limb, Limb #), Limb #) -- ^ (# sum, carry bit #) -add_c# (# a0, a1, a2, a3 #) (# b0, b1, b2, b3 #) = +add_o# (# a0, a1, a2, a3 #) (# b0, b1, b2, b3 #) = let !(# s0, c0 #) = L.add_o# a0 b0 !(# s1, c1 #) = L.add_c# a1 b1 c0 !(# s2, c2 #) = L.add_c# a2 b2 c1 !(# s3, c3 #) = L.add_c# a3 b3 c2 in (# (# s0, s1, s2, s3 #), c3 #) -{-# INLINE add_c# #-} +{-# INLINE add_o# #-} + +-- | Overflowing addition, computing 'a + b', returning the sum and a +-- carry bit. +add_o + :: Wider + -> Wider + -> (Wider, Word) +add_o (Wider a) (Wider b) = + let !(# s, Limb c #) = add_o# a b + in (Wider s, W# c) -- | Wrapping addition, computing 'a + b'. add_w# @@ -224,7 +234,7 @@ add_w# -> (# Limb, Limb, Limb, Limb #) -- ^ addend -> (# Limb, Limb, Limb, Limb #) -- ^ sum add_w# a b = - let !(# c, _ #) = add_c# a b + let !(# c, _ #) = add_o# a b in c {-# INLINE add_w# #-} @@ -243,7 +253,7 @@ add_mod# -> (# Limb, Limb, Limb, Limb #) -- ^ modulus -> (# Limb, Limb, Limb, Limb #) -- ^ sum add_mod# a b m = - let !(# w, c #) = add_c# a b + let !(# w, c #) = add_o# a b in sub_mod_c# w c m m {-# INLINE add_mod# #-} diff --git a/lib/Numeric/Montgomery/Secp256k1/Curve.hs b/lib/Numeric/Montgomery/Secp256k1/Curve.hs @@ -181,70 +181,70 @@ mul_inner# (# x0, x1, x2, x3 #) (# y0, y1, y2, y3 #) = !n = Limb 0xD838091DD2253531## !axy0 = L.mul_c# x0 y0 !u0 = L.mul_w# (lo axy0) n - !(# (# _, a0 #), c0 #) = W.add_c# (L.mul_c# u0 m0) axy0 + !(# (# _, a0 #), c0 #) = W.add_o# (L.mul_c# u0 m0) axy0 !carry0 = (# a0, c0 #) !axy0_1 = L.mul_c# x0 y1 !umc0_1 = W.add_w# (L.mul_c# u0 m1) carry0 - !(# (# o0, ab0_1 #), c0_1 #) = W.add_c# axy0_1 umc0_1 + !(# (# o0, ab0_1 #), c0_1 #) = W.add_o# axy0_1 umc0_1 !carry0_1 = (# ab0_1, c0_1 #) !axy0_2 = L.mul_c# x0 y2 !umc0_2 = W.add_w# (L.mul_c# u0 m2) carry0_1 - !(# (# p0, ab0_2 #), c0_2 #) = W.add_c# axy0_2 umc0_2 + !(# (# p0, ab0_2 #), c0_2 #) = W.add_o# axy0_2 umc0_2 !carry0_2 = (# ab0_2, c0_2 #) !axy0_3 = L.mul_c# x0 y3 !umc0_3 = W.add_w# (L.mul_c# u0 m3) carry0_2 - !(# (# q0, ab0_3 #), c0_3 #) = W.add_c# axy0_3 umc0_3 + !(# (# q0, ab0_3 #), c0_3 #) = W.add_o# axy0_3 umc0_3 !carry0_3 = (# ab0_3, c0_3 #) !(# r0, mc0 #) = carry0_3 !axy1 = wadd_w# (L.mul_c# x1 y0) o0 !u1 = L.mul_w# (lo axy1) n - !(# (# _, a1 #), c1 #) = W.add_c# (L.mul_c# u1 m0) axy1 + !(# (# _, a1 #), c1 #) = W.add_o# (L.mul_c# u1 m0) axy1 !carry1 = (# a1, c1 #) !axy1_1 = wadd_w# (L.mul_c# x1 y1) p0 !umc1_1 = W.add_w# (L.mul_c# u1 m1) carry1 - !(# (# o1, ab1_1 #), c1_1 #) = W.add_c# axy1_1 umc1_1 + !(# (# o1, ab1_1 #), c1_1 #) = W.add_o# axy1_1 umc1_1 !carry1_1 = (# ab1_1, c1_1 #) !axy1_2 = wadd_w# (L.mul_c# x1 y2) q0 !umc1_2 = W.add_w# (L.mul_c# u1 m2) carry1_1 - !(# (# p1, ab1_2 #), c1_2 #) = W.add_c# axy1_2 umc1_2 + !(# (# p1, ab1_2 #), c1_2 #) = W.add_o# axy1_2 umc1_2 !carry1_2 = (# ab1_2, c1_2 #) !axy1_3 = wadd_w# (L.mul_c# x1 y3) r0 !umc1_3 = W.add_w# (L.mul_c# u1 m3) carry1_2 - !(# (# q1, ab1_3 #), c1_3 #) = W.add_c# axy1_3 umc1_3 + !(# (# q1, ab1_3 #), c1_3 #) = W.add_o# axy1_3 umc1_3 !carry1_3 = (# ab1_3, c1_3 #) !(# r1, mc1 #) = wadd_w# carry1_3 mc0 !axy2 = wadd_w# (L.mul_c# x2 y0) o1 !u2 = L.mul_w# (lo axy2) n - !(# (# _, a2 #), c2 #) = W.add_c# (L.mul_c# u2 m0) axy2 + !(# (# _, a2 #), c2 #) = W.add_o# (L.mul_c# u2 m0) axy2 !carry2 = (# a2, c2 #) !axy2_1 = wadd_w# (L.mul_c# x2 y1) p1 !umc2_1 = W.add_w# (L.mul_c# u2 m1) carry2 - !(# (# o2, ab2_1 #), c2_1 #) = W.add_c# axy2_1 umc2_1 + !(# (# o2, ab2_1 #), c2_1 #) = W.add_o# axy2_1 umc2_1 !carry2_1 = (# ab2_1, c2_1 #) !axy2_2 = wadd_w# (L.mul_c# x2 y2) q1 !umc2_2 = W.add_w# (L.mul_c# u2 m2) carry2_1 - !(# (# p2, ab2_2 #), c2_2 #) = W.add_c# axy2_2 umc2_2 + !(# (# p2, ab2_2 #), c2_2 #) = W.add_o# axy2_2 umc2_2 !carry2_2 = (# ab2_2, c2_2 #) !axy2_3 = wadd_w# (L.mul_c# x2 y3) r1 !umc2_3 = W.add_w# (L.mul_c# u2 m3) carry2_2 - !(# (# q2, ab2_3 #), c2_3 #) = W.add_c# axy2_3 umc2_3 + !(# (# q2, ab2_3 #), c2_3 #) = W.add_o# axy2_3 umc2_3 !carry2_3 = (# ab2_3, c2_3 #) !(# r2, mc2 #) = wadd_w# carry2_3 mc1 !axy3 = wadd_w# (L.mul_c# x3 y0) o2 !u3 = L.mul_w# (lo axy3) n - !(# (# _, a3 #), c3 #) = W.add_c# (L.mul_c# u3 m0) axy3 + !(# (# _, a3 #), c3 #) = W.add_o# (L.mul_c# u3 m0) axy3 !carry3 = (# a3, c3 #) !axy3_1 = wadd_w# (L.mul_c# x3 y1) p2 !umc3_1 = W.add_w# (L.mul_c# u3 m1) carry3 - !(# (# o3, ab3_1 #), c3_1 #) = W.add_c# axy3_1 umc3_1 + !(# (# o3, ab3_1 #), c3_1 #) = W.add_o# axy3_1 umc3_1 !carry3_1 = (# ab3_1, c3_1 #) !axy3_2 = wadd_w# (L.mul_c# x3 y2) q2 !umc3_2 = W.add_w# (L.mul_c# u3 m2) carry3_1 - !(# (# p3, ab3_2 #), c3_2 #) = W.add_c# axy3_2 umc3_2 + !(# (# p3, ab3_2 #), c3_2 #) = W.add_o# axy3_2 umc3_2 !carry3_2 = (# ab3_2, c3_2 #) !axy3_3 = wadd_w# (L.mul_c# x3 y3) r2 !umc3_3 = W.add_w# (L.mul_c# u3 m3) carry3_2 - !(# (# q3, ab3_3 #), c3_3 #) = W.add_c# axy3_3 umc3_3 + !(# (# q3, ab3_3 #), c3_3 #) = W.add_o# axy3_3 umc3_3 !carry3_3 = (# ab3_3, c3_3 #) !(# r3, mc3 #) = wadd_w# carry3_3 mc2 in (# (# o3, p3, q3, r3 #), mc3 #) diff --git a/lib/Numeric/Montgomery/Secp256k1/Scalar.hs b/lib/Numeric/Montgomery/Secp256k1/Scalar.hs @@ -182,70 +182,70 @@ mul_inner# (# x0, x1, x2, x3 #) (# y0, y1, y2, y3 #) = !n = Limb 0x4B0DFF665588B13F## !axy0 = L.mul_c# x0 y0 !u0 = L.mul_w# (lo axy0) n - !(# (# _, a0 #), c0 #) = W.add_c# (L.mul_c# u0 m0) axy0 + !(# (# _, a0 #), c0 #) = W.add_o# (L.mul_c# u0 m0) axy0 !carry0 = (# a0, c0 #) !axy0_1 = L.mul_c# x0 y1 !umc0_1 = W.add_w# (L.mul_c# u0 m1) carry0 - !(# (# o0, ab0_1 #), c0_1 #) = W.add_c# axy0_1 umc0_1 + !(# (# o0, ab0_1 #), c0_1 #) = W.add_o# axy0_1 umc0_1 !carry0_1 = (# ab0_1, c0_1 #) !axy0_2 = L.mul_c# x0 y2 !umc0_2 = W.add_w# (L.mul_c# u0 m2) carry0_1 - !(# (# p0, ab0_2 #), c0_2 #) = W.add_c# axy0_2 umc0_2 + !(# (# p0, ab0_2 #), c0_2 #) = W.add_o# axy0_2 umc0_2 !carry0_2 = (# ab0_2, c0_2 #) !axy0_3 = L.mul_c# x0 y3 !umc0_3 = W.add_w# (L.mul_c# u0 m3) carry0_2 - !(# (# q0, ab0_3 #), c0_3 #) = W.add_c# axy0_3 umc0_3 + !(# (# q0, ab0_3 #), c0_3 #) = W.add_o# axy0_3 umc0_3 !carry0_3 = (# ab0_3, c0_3 #) !(# r0, mc0 #) = carry0_3 !axy1 = wadd_w# (L.mul_c# x1 y0) o0 !u1 = L.mul_w# (lo axy1) n - !(# (# _, a1 #), c1 #) = W.add_c# (L.mul_c# u1 m0) axy1 + !(# (# _, a1 #), c1 #) = W.add_o# (L.mul_c# u1 m0) axy1 !carry1 = (# a1, c1 #) !axy1_1 = wadd_w# (L.mul_c# x1 y1) p0 !umc1_1 = W.add_w# (L.mul_c# u1 m1) carry1 - !(# (# o1, ab1_1 #), c1_1 #) = W.add_c# axy1_1 umc1_1 + !(# (# o1, ab1_1 #), c1_1 #) = W.add_o# axy1_1 umc1_1 !carry1_1 = (# ab1_1, c1_1 #) !axy1_2 = wadd_w# (L.mul_c# x1 y2) q0 !umc1_2 = W.add_w# (L.mul_c# u1 m2) carry1_1 - !(# (# p1, ab1_2 #), c1_2 #) = W.add_c# axy1_2 umc1_2 + !(# (# p1, ab1_2 #), c1_2 #) = W.add_o# axy1_2 umc1_2 !carry1_2 = (# ab1_2, c1_2 #) !axy1_3 = wadd_w# (L.mul_c# x1 y3) r0 !umc1_3 = W.add_w# (L.mul_c# u1 m3) carry1_2 - !(# (# q1, ab1_3 #), c1_3 #) = W.add_c# axy1_3 umc1_3 + !(# (# q1, ab1_3 #), c1_3 #) = W.add_o# axy1_3 umc1_3 !carry1_3 = (# ab1_3, c1_3 #) !(# r1, mc1 #) = wadd_w# carry1_3 mc0 !axy2 = wadd_w# (L.mul_c# x2 y0) o1 !u2 = L.mul_w# (lo axy2) n - !(# (# _, a2 #), c2 #) = W.add_c# (L.mul_c# u2 m0) axy2 + !(# (# _, a2 #), c2 #) = W.add_o# (L.mul_c# u2 m0) axy2 !carry2 = (# a2, c2 #) !axy2_1 = wadd_w# (L.mul_c# x2 y1) p1 !umc2_1 = W.add_w# (L.mul_c# u2 m1) carry2 - !(# (# o2, ab2_1 #), c2_1 #) = W.add_c# axy2_1 umc2_1 + !(# (# o2, ab2_1 #), c2_1 #) = W.add_o# axy2_1 umc2_1 !carry2_1 = (# ab2_1, c2_1 #) !axy2_2 = wadd_w# (L.mul_c# x2 y2) q1 !umc2_2 = W.add_w# (L.mul_c# u2 m2) carry2_1 - !(# (# p2, ab2_2 #), c2_2 #) = W.add_c# axy2_2 umc2_2 + !(# (# p2, ab2_2 #), c2_2 #) = W.add_o# axy2_2 umc2_2 !carry2_2 = (# ab2_2, c2_2 #) !axy2_3 = wadd_w# (L.mul_c# x2 y3) r1 !umc2_3 = W.add_w# (L.mul_c# u2 m3) carry2_2 - !(# (# q2, ab2_3 #), c2_3 #) = W.add_c# axy2_3 umc2_3 + !(# (# q2, ab2_3 #), c2_3 #) = W.add_o# axy2_3 umc2_3 !carry2_3 = (# ab2_3, c2_3 #) !(# r2, mc2 #) = wadd_w# carry2_3 mc1 !axy3 = wadd_w# (L.mul_c# x3 y0) o2 !u3 = L.mul_w# (lo axy3) n - !(# (# _, a3 #), c3 #) = W.add_c# (L.mul_c# u3 m0) axy3 + !(# (# _, a3 #), c3 #) = W.add_o# (L.mul_c# u3 m0) axy3 !carry3 = (# a3, c3 #) !axy3_1 = wadd_w# (L.mul_c# x3 y1) p2 !umc3_1 = W.add_w# (L.mul_c# u3 m1) carry3 - !(# (# o3, ab3_1 #), c3_1 #) = W.add_c# axy3_1 umc3_1 + !(# (# o3, ab3_1 #), c3_1 #) = W.add_o# axy3_1 umc3_1 !carry3_1 = (# ab3_1, c3_1 #) !axy3_2 = wadd_w# (L.mul_c# x3 y2) q2 !umc3_2 = W.add_w# (L.mul_c# u3 m2) carry3_1 - !(# (# p3, ab3_2 #), c3_2 #) = W.add_c# axy3_2 umc3_2 + !(# (# p3, ab3_2 #), c3_2 #) = W.add_o# axy3_2 umc3_2 !carry3_2 = (# ab3_2, c3_2 #) !axy3_3 = wadd_w# (L.mul_c# x3 y3) r2 !umc3_3 = W.add_w# (L.mul_c# u3 m3) carry3_2 - !(# (# q3, ab3_3 #), c3_3 #) = W.add_c# axy3_3 umc3_3 + !(# (# q3, ab3_3 #), c3_3 #) = W.add_o# axy3_3 umc3_3 !carry3_3 = (# ab3_3, c3_3 #) !(# r3, mc3 #) = wadd_w# carry3_3 mc2 in (# (# o3, p3, q3, r3 #), mc3 #) diff --git a/ppad-fixed.cabal b/ppad-fixed.cabal @@ -48,6 +48,7 @@ test-suite fixed-tests other-modules: Limb Wide + Wider ghc-options: -rtsopts -Wall -O2