Given [b, c, a, carry] on stack top, following function computes
tmp = a + (b * c) + carry
hi = tmp >> 32
lo = tmp & 0xffff_ffff
return (hi, lo)
At end of execution of this function, stack top should look like [hi, lo]
See https://github.com/itzmeanjan/secp256k1/blob/6e5e654823a073add7d62b21ed88e9de9bb06869/field/base_field_utils.py#L41-L46
## std::math::secp256k1::base_field
| Procedure | Description |
| ----------- | ------------- |
| mul | Given two 256 -bit numbers ( elements belonging to secp256k1 base field ) on stack,
where each number is represented in radix-2^32 form ( i.e. each number having eight
32 -bit limbs ), following function computes modular multiplication of those two
operands, computing 256 -bit result, which belongs to secp256k1 base field.
Stack expected as below, holding input
[a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, b3, b4, b5, b6, b7, ...] \| a[0..8], b[0..8] are 256 -bit numbers
After finishing execution of this function, stack should look like
[c0, c1, c2, c3, c4, c5, c6, c7, ...] \| c[0..8] is a 256 -bit number
Note, for computing modular multiplication of a[0..8] & b[0..8],
school book multiplication equipped with Montgomery reduction technique
is used, which is why a[0..8], b[0..8] are expected to be in Montgomery form,
while computed c[0..8] will also be in Montgomery form.
See https://github.com/itzmeanjan/secp256k1/blob/6e5e654823a073add7d62b21ed88e9de9bb06869/field/base_field_utils.py#L101-L222
|
| add | Given two 256 -bit numbers ( elements belonging to secp256k1 base field ) on stack,
where each number is represented in radix-2^32 form ( i.e. each number having eight
32 -bit limbs ), following function computes modular addition of those two operands,
in secp256k1 base field.
Stack expected as below, holding input
[a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, b3, b4, b5, b6, b7, ...] \| a[0..8], b[0..8] are 256 -bit numbers
After finishing execution of this function, stack should look like
[c0, c1, c2, c3, c4, c5, c6, c7, ...] \| c[0..8] is a 256 -bit number
See https://github.com/itzmeanjan/secp256k1/blob/6e5e654823a073add7d62b21ed88e9de9bb06869/field/base_field.py#L57-L76
|
| neg | Given a secp256k1 base field element ( say a ) on stack, represented in Montgomery form
( i.e. number having eight 32 -bit limbs ), following function negates it to
field element a' \| a' + a = 0
Stack expected as below, holding input
[a0, a1, a2, a3, a4, a5, a6, a7, ...] \| a[0..8] is a secp256k1 base field element
After finishing execution of this function, stack should look like
[c0, c1, c2, c3, c4, c5, c6, c7, ...] \| c[0..8] is a secp256k1 base field element
See https://github.com/itzmeanjan/secp256k1/blob/6e5e654823a073add7d62b21ed88e9de9bb06869/field/base_field.py#L78-L96
|
| sub | Given two secp256k1 base field elements, say a, b, ( represented in Montgomery form,
each number having eight 32 -bit limbs ) on stack, following function computes modular
subtraction of those two operands c = a + (-b) = a - b
Stack expected as below, holding input
[a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, b3, b4, b5, b6, b7, ...] \| a[0..8], b[0..8] are secp256k1 base field elements
After finishing execution of this function, stack should look like
[c0, c1, c2, c3, c4, c5, c6, c7, ...] \| c[0..8] is a secp256k1 base field element
See https://github.com/itzmeanjan/secp256k1/blob/6e5e654823a073add7d62b21ed88e9de9bb06869/field/base_field.py#L98-L102
|
| to_mont | Given a 256 -bit number on stack, represented in radix-2^32 form i.e. eight 32 -bit limbs,
this routine computes Montgomery representation of provided radix-2^32 number.
Stack expected in form
[a0, a1, a2, a3, a4, a5, a6, a7, ...]
Final stack should look like
[a0', a1', a2', a3', a4', a5', a6', a7', ...]
See section 2.2 of https://eprint.iacr.org/2017/1057.pdf
See https://github.com/itzmeanjan/secp256k1/blob/6e5e654823a073add7d62b21ed88e9de9bb06869/field/base_field_utils.py#L225-L232
for implementation
|
| from_mont | Given a 256 -bit number on stack, represented in Montgomery form i.e. eight 32 -bit limbs,
this routine computes radix-2^32 representation of provided u256 number.
Stack expected as
[a0, a1, a2, a3, a4, a5, a6, a7, ...]
Final stack should look like
[a0', a1', a2', a3', a4', a5', a6', a7', ...]
See section 2.2 of https://eprint.iacr.org/2017/1057.pdf
See https://github.com/itzmeanjan/secp256k1/blob/6e5e654823a073add7d62b21ed88e9de9bb06869/field/base_field_utils.py#L235-L241
for implementation
|
| inv | Given an element ( say a ) of secp256k1 base field, this routine computes multiplicative
inverse ( say a' ) of that element s.t. a * a' = 1 ( mod p ) \| p = secp256k1 base field prime
Expected stack state
[a0, a1, a2, a3, a4, a5, a6, a7, ...] \| a[0..8] is a 256 -bit number
Final stack state
[b0, b1, b2, b3, b4, b5, b6, b7, ...] \| b[0..8] is a 256 -bit number s.t. b = a^-1 ( mod p )
Note, both input and output stays in Montgomery form. If 0 is input operand, then multiplicative
inverse can't be computed, which is why output result is also 0.
See https://github.com/itzmeanjan/secp256k1/blob/37b339db3e03d24c2977399eb8896ef515ebb09b/field/base_field.py#L114-L132
|