fixed

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

commit c093234ac07dbaf2961159363209b012082a0f40
parent 5ca4c9d8fcfc4d7b7d0e7695e5250fd9ec539d62
Author: Jared Tobin <jared@jtobin.io>
Date:   Fri, 21 Nov 2025 13:17:38 +0400

lib: montgomery inv fix for scalar domain

Diffstat:
Metc/generate_inv.sh | 22+++++++++++++++++++---
Mlib/Numeric/Montgomery/Secp256k1/Curve.hs | 5+++++
Mlib/Numeric/Montgomery/Secp256k1/Scalar.hs | 23+++++++++++++++++------
3 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/etc/generate_inv.sh b/etc/generate_inv.sh @@ -22,17 +22,33 @@ # a^-1 = a ^ q - 2 mod q # secp256k1 field prime - 2 -# exponent="1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111011111111111111111111110000101101" +exponent_curve="1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111011111111111111111111110000101101" # secp256k1 scalar group order - 2 -exponent="1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111010111010101011101101110011100110101011110100100010100000001110111011111111010010010111101000110011010000001101100100000101000001" +exponent_scalar="1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111010111010101011101101110011100110101011110100100010100000001110111011111111010010010111101000110011010000001101100100000100111111" + +# adjust me as desired; use 'curve' or 'scalar' +target="scalar" + +declare exponent + +if [[ $target == "curve" ]]; then + exponent=$exponent_curve +elif [[ $target == "scalar" ]]; then + exponent=$exponent_scalar +fi echo "-- generated by etc/generate_inv.sh" echo "inv#" echo " :: (# Word#, Word#, Word#, Word# #)" echo " -> (# Word#, Word#, Word#, Word# #)" echo "inv# a =" -echo " let !t0 = (# 0x1000003D1##, 0##, 0##, 0## #) -- montgomery 'one'" +if [[ $target == "curve" ]]; then + echo " let !t0 = (# 0x1000003D1##, 0##, 0##, 0## #)" +elif [[ $target == "scalar" ]]; then + echo " let !t0 = (# 0x402DA1732FC9BEBF##, 0x4551231950B75FC4##" + echo " , 0x0000000000000001##, 0x0000000000000000## #)" +fi label=1 diff --git a/lib/Numeric/Montgomery/Secp256k1/Curve.hs b/lib/Numeric/Montgomery/Secp256k1/Curve.hs @@ -18,6 +18,8 @@ import Prelude hiding (div, mod, or, and, not, quot, rem, recip) -- montgomery arithmetic, specialized to the secp256k1 field prime modulus -- 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F +-- XX define constants here, current approach is fragile + -- utilities ------------------------------------------------------------------ -- Wide wrapping addition, when addend is only a limb. @@ -353,6 +355,9 @@ sqr# a = mul# a a sqr :: Wider -> Wider sqr (Wider a) = Wider (mul# a a) +one :: Wider +one = Wider (# 0x1000003D1##, 0##, 0##, 0## #) + -- generated by etc/generate_inv.sh inv# :: (# Word#, Word#, Word#, Word# #) diff --git a/lib/Numeric/Montgomery/Secp256k1/Scalar.hs b/lib/Numeric/Montgomery/Secp256k1/Scalar.hs @@ -18,6 +18,8 @@ import Prelude hiding (div, mod, or, and, not, quot, rem, recip) -- montgomery arithmetic, specialized to the secp256k1 scalar group order -- 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 +-- XX define constants here, current approach is fragile + -- utilities ------------------------------------------------------------------ -- Wide wrapping addition, when addend is only a limb. @@ -354,12 +356,17 @@ sqr# a = mul# a a sqr :: Wider -> Wider sqr (Wider a) = Wider (mul# a a) +one :: Wider +one = Wider (# 0x402DA1732FC9BEBF##, 0x4551231950B75FC4## + , 0x0000000000000001##, 0x0000000000000000## #) + -- generated by etc/generate_inv.sh inv# :: (# Word#, Word#, Word#, Word# #) -> (# Word#, Word#, Word#, Word# #) inv# a = - let !t0 = (# 0x1000003D1##, 0##, 0##, 0## #) -- montgomery 'one' + let !t0 = (# 0x402DA1732FC9BEBF##, 0x4551231950B75FC4## + , 0x0000000000000001##, 0x0000000000000000## #) !t1 = sqr# t0 !t2 = mul# a t1 !t3 = sqr# t2 @@ -800,15 +807,19 @@ inv# a = !t438 = mul# a t437 !t439 = sqr# t438 !t440 = sqr# t439 - !t441 = mul# a t440 - !t442 = sqr# t441 + !t441 = sqr# t440 + !t442 = mul# a t441 !t443 = sqr# t442 - !t444 = sqr# t443 + !t444 = mul# a t443 !t445 = sqr# t444 - !t446 = sqr# t445 + !t446 = mul# a t445 !t447 = sqr# t446 !t448 = mul# a t447 - !r = t448 + !t449 = sqr# t448 + !t450 = mul# a t449 + !t451 = sqr# t450 + !t452 = mul# a t451 + !r = t452 in r {-# INLINE inv# #-}