ppad-fixed-0.1.3: Large fixed-width words and constant-time arithmetic.
Copyright(c) 2025 Jared Tobin
LicenseMIT
MaintainerJared Tobin <jared@ppad.tech>
Safe HaskellNone
LanguageHaskell2010

Numeric.Montgomery.Secp256k1.Curve

Description

Montgomery form Wider words, as well as arithmetic operations, with domain derived from the secp256k1 elliptic curve field prime.

Synopsis

Montgomery form, secp256k1 field prime modulus

data Montgomery Source #

Montgomery-form Wider words, on the Montgomery domain defined by the secp256k1 field prime.

>>> let one = 1 :: Montgomery
>>> one
1
>>> putStrLn (render one)
(4294968273, 0, 0, 0)

Constructors

Montgomery !Limb4 

Instances

Instances details
Num Montgomery Source #

Note that fromInteger necessarily runs in variable time due to conversion from the variable-size, potentially heap-allocated Integer type.

Instance details

Defined in Numeric.Montgomery.Secp256k1.Curve

Show Montgomery Source # 
Instance details

Defined in Numeric.Montgomery.Secp256k1.Curve

NFData Montgomery Source # 
Instance details

Defined in Numeric.Montgomery.Secp256k1.Curve

Methods

rnf :: Montgomery -> () #

render :: Montgomery -> String Source #

Render a Montgomery value as a String, showing its individual Limbs.

>>> putStrLn (render 1)
(4294968273, 0, 0, 0)

to :: Wider -> Montgomery Source #

Convert a Wider word to the Montgomery domain.

from :: Montgomery -> Wider Source #

Retrieve a Montgomery word from the Montgomery domain.

This function is a synonym for retr.

zero :: Montgomery Source #

Zero (the additive unit) in the Montgomery domain.

one :: Montgomery Source #

One (the multiplicative unit) in the Montgomery domain.

Comparison

eq :: Montgomery -> Montgomery -> Choice Source #

Constant-time equality comparison.

eq_vartime :: Montgomery -> Montgomery -> Bool Source #

Variable-time equality comparison.

Reduction and retrieval

redc Source #

Arguments

:: Montgomery

low wider-word, Montgomery form

-> Montgomery

high wider-word, Montgomery form

-> Montgomery

reduced value

Montgomery reduction.

The first argument represents the low words, and the second the high words, of an extra-large eight-limb word in Montgomery form.

redc# Source #

Arguments

:: Limb4

lower limbs

-> Limb4

upper limbs

-> Limb4

result

Montgomery reduction.

retr Source #

Arguments

:: Montgomery

value in montgomery form

-> Wider

retrieved value

Retrieve a Montgomery value from the Montgomery domain, producing a Wider word.

retr# :: Limb4 -> Limb4 Source #

Constant-time selection

select Source #

Arguments

:: Montgomery

a

-> Montgomery

b

-> Choice

c

-> Montgomery

result

Return a if c is truthy, otherwise return b.

>>> import qualified Data.Choice as C
>>> select 0 1 (C.true# ())
1

select# Source #

Arguments

:: Limb4

a

-> Limb4

b

-> Choice

c

-> Limb4

result

Montgomery arithmetic

add :: Montgomery -> Montgomery -> Montgomery Source #

Addition in the Montgomery domain.

Note that Montgomery is an instance of Num, so you can use + to apply this function.

>>> 1 + 1 :: Montgomery
2

add# Source #

Arguments

:: Limb4

augend

-> Limb4

addend

-> Limb4

sum

sub :: Montgomery -> Montgomery -> Montgomery Source #

Subtraction in the Montgomery domain.

Note that Montgomery is an instance of Num, so you can use - to apply this function.

>>> 1 - 1 :: Montgomery
0

sub# Source #

Arguments

:: Limb4

minuend

-> Limb4

subtrahend

-> Limb4

difference

mul Source #

Arguments

:: Montgomery

multiplicand in montgomery form

-> Montgomery

multiplier in montgomery form

-> Montgomery

montgomery product

Multiplication in the Montgomery domain.

Note that Montgomery is an instance of Num, so you can use * to apply this function.

>>> 1 * 1 :: Montgomery
1

mul# :: Limb4 -> Limb4 -> Limb4 Source #

sqr :: Montgomery -> Montgomery Source #

Squaring in the Montgomery domain.

>>> sqr 1
1
>>> sqr 2
4
>>> sqr (negate 2)
4

sqr# :: Limb4 -> Limb4 Source #

neg :: Montgomery -> Montgomery Source #

Additive inverse in the Montgomery domain.

Note that Montgomery is an instance of Num, so you can use negate to apply this function.

>>> negate 1 :: Montgomery
115792089237316195423570985008687907853269984665640564039457584007908834671662
>>> (negate 1 :: Montgomery) + 1
0

neg# Source #

Arguments

:: Limb4

argument

-> Limb4

modular negation

inv :: Montgomery -> Montgomery Source #

Multiplicative inverse in the Montgomery domain.

> inv 2

57896044618658097711785492504343953926634992332820282019728792003954417335832 >> inv 2 * 2 1

inv# :: Limb4 -> Limb4 Source #

sqrt_vartime :: Montgomery -> Maybe Montgomery Source #

Square root (Tonelli-Shanks) in the Montgomery domain.

Returns Nothing if the square root doesn't exist.

Note that the square root calculation itself is performed in constant time; we branch only when casting to Maybe at the end.

>>> sqrt_vartime 4
Just 2
>>> sqrt_vartime 15
Just 69211104694897500952317515077652022726490027694212560352756646854116994689233
>>> (*) <$> sqrt_vartime 15 <*> sqrt_vartime 15
Just 15

sqrt# :: Limb4 -> (# Limb4, Choice #) Source #

exp :: Montgomery -> Wider -> Montgomery Source #

Exponentiation in the Montgomery domain.

>>> exp 2 3
8
>>> exp 2 10
1024

exp# :: Limb4 -> Limb4 -> Limb4 Source #

odd# :: Limb4 -> Choice Source #

odd_vartime :: Montgomery -> Bool Source #

Check if a Montgomery value is odd.

Note that the comparison is performed in constant time, but we branch when converting to Bool.

>>> odd 1
True
>>> odd 2
False
>>> Data.Word.Wider.odd (retr 3) -- parity is preserved
True