ppad-fixed-0.1.0: 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.Scalar

Description

Montgomery form Wider words, as well as arithmetic operations, with domain derived from the secp256k1 elliptic curve scalar group order.

Synopsis

Montgomery form, secp256k1 scalar group order modulus

data Montgomery Source #

Montgomery-form Wider words, on the Montgomery domain defined by the secp256k1 scalar group order.

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

Constructors

Montgomery !(# Limb, Limb, Limb, Limb #) 

render :: Montgomery -> String Source #

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

>>> putStrLn (render 1)
(4624529908474429119, 4994812053365940164, 1, 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.

retr Source #

Arguments

:: Montgomery

value in Montgomery form

-> Wider

retrieved value

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

redc# Source #

Arguments

:: (# Limb, Limb, Limb, Limb #)

lower limbs

-> (# Limb, Limb, Limb, Limb #)

upper limbs

-> (# Limb, Limb, Limb, Limb #)

result

retr# :: (# Limb, Limb, Limb, Limb #) -> (# Limb, Limb, Limb, Limb #) Source #

Constant-time selection

select# Source #

Arguments

:: (# Limb, Limb, Limb, Limb #)

a

-> (# Limb, Limb, Limb, Limb #)

b

-> Choice

c

-> (# Limb, Limb, Limb, Limb #)

result

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

Montgomery arithmetic

add Source #

Arguments

:: Montgomery

augend

-> Montgomery

addend

-> Montgomery

sum

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

:: (# Limb, Limb, Limb, Limb #)

augend

-> (# Limb, Limb, Limb, Limb #)

addend

-> (# Limb, Limb, Limb, Limb #)

sum

sub Source #

Arguments

:: Montgomery

minuend

-> Montgomery

subtrahend

-> Montgomery

difference

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

:: (# Limb, Limb, Limb, Limb #)

minuend

-> (# Limb, Limb, Limb, Limb #)

subtrahend

-> (# Limb, Limb, Limb, Limb #)

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# :: (# Limb, Limb, Limb, Limb #) -> (# Limb, Limb, Limb, Limb #) -> (# Limb, Limb, Limb, Limb #) Source #

sqr Source #

Arguments

:: Montgomery

argument

-> Montgomery

square

Squaring in the Montgomery domain.

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

sqr# :: (# Limb, Limb, Limb, Limb #) -> (# Limb, Limb, Limb, Limb #) 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
115792089237316195423570985008687907852837564279074904382605163141518161494336
>>> (negate 1 :: Montgomery) + 1
0

neg# Source #

Arguments

:: (# Limb, Limb, Limb, Limb #)

argument

-> (# Limb, Limb, Limb, Limb #)

modular negation

inv Source #

Arguments

:: Montgomery

argument

-> Montgomery

inverse

Multiplicative inverse in the Montgomery domain.

> inv 2

57896044618658097711785492504343953926418782139537452191302581570759080747169 >> inv 2 * 2 1

inv# :: (# Limb, Limb, Limb, Limb #) -> (# Limb, Limb, Limb, Limb #) Source #

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

Exponentiation in the Montgomery domain.

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

odd# :: (# Limb, Limb, Limb, Limb #) -> Choice Source #

odd :: Montgomery -> Bool Source #

Check if a Montgomery value is odd.

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