## std::math::secp256k1::group
| Procedure | Description |
| ----------- | ------------- |
| double | Given a secp256k1 point in projective coordinate system ( i.e. with x, y, z -coordinates
as secp256k1 prime field elements, represented in Montgomery form ), this routine adds
that point with self i.e. does point doubling on elliptic curve, using exception-free
doubling formula from algorithm 9 of https://eprint.iacr.org/2015/1060.pdf, while
following prototype implementation https://github.com/itzmeanjan/secp256k1/blob/ec3652a/point.py#L131-L165
Input:
12 memory addresses on stack such that first 6 memory addresses are for input point &
last 6 are for storing resulting point.
First 6 addresses hold input elliptic curve point's x, y, z -coordinates, where each coordinate
is represented in Montgomery form, as eight 32 -bit limbs.
Similarly, last 6 addresses hold resulting (doubled) point's x, y, z -coordinates, where each
coordinate is represented in Montgomery form, as eight 32 -bit limbs. Note, this is where
output will be written, so called is expected to read doubled point from last 6 memory addresses.
Expected stack during invocation of this routine:
[x_addr[0..4], x_addr[4..8], y_addr[0..4], y_addr[4..8], z_addr[0..4], z_addr[4..8],
x3_addr[0..4], x3_addr[4..8], y3_addr[0..4], y3_addr[4..8], z3_addr[0..4], z3_addr[4..8]]
Note, (X, Y, Z) => input point
(X3, Y3, Z3) => output point
Output:
Last 6 memory addresses of 12 memory addresses which were provided during invocation, where resulting doubled
point is kept in similar form. For seeing X3, Y3, Z3 -coordinates of doubled point, one needs to read from
those 6 memory addresses.
Stack at end of execution of routine looks like
[x3_addr[0..4], x3_addr[4..8], y3_addr[0..4], y3_addr[4..8], z3_addr[0..4], z3_addr[4..8]]
|
| add | Given two secp256k1 points in projective coordinate system ( i.e. with x, y, z -coordinates
as secp256k1 prime field elements, represented in Montgomery form, each coordinate using eight 32 -bit limbs ),
this routine adds those two points on elliptic curve, using exception-free addition formula from
algorithm 7 of https://eprint.iacr.org/2015/1060.pdf, while following prototype
implementation https://github.com/itzmeanjan/secp256k1/blob/ec3652a/point.py#L60-L115
Input:
18 memory addresses on stack such that first 6 memory addresses are for first input point, next 6
memory addresses holding x, y, z -coordinates of second input point & last 6 addresses are for storing
resulting point ( addition of two input points ).
Expected stack during invocation of this routine:
[x1_addr[0..4], x1_addr[4..8], y1_addr[0..4], y1_addr[4..8], z1_addr[0..4], z1_addr[4..8],
x2_addr[0..4], x2_addr[4..8], y2_addr[0..4], y2_addr[4..8], z2_addr[0..4], z2_addr[4..8],
x3_addr[0..4], x3_addr[4..8], y3_addr[0..4], y3_addr[4..8], z3_addr[0..4], z3_addr[4..8]]
Note, (X1, Y1, Z1) => input point 1
(X2, Y2, Z2) => input point 2
(X3, Y3, Z3) => output point
Output:
Last 6 memory addresses of 18 input memory addresses which were provided during invocation, where resulting elliptic curve
point is kept in similar form. For seeing X3, Y3, Z3 -coordinates of doubled point, one needs to read from
those 6 memory addresses.
Stack at end of execution of routine looks like
[x3_addr[0..4], x3_addr[4..8], y3_addr[0..4], y3_addr[4..8], z3_addr[0..4], z3_addr[4..8]]
|
| mul | Given an elliptic curve point in projective coordinate system ( total 24 field elements
required for representing x, y, z coordinate values s.t. they are provided by 6 distinct
memory addresses ) and a 256 -bit scalar, in radix-2^32 representation ( such that it
takes 8 stack elements to represent whole scalar, where each limb is of 32 -bit width ),
this routine multiplies elliptic curve point by given scalar, producing another point
on secp256k1 curve, which will also be presented in projective coordinate system.
Input:
During invocation, this routine expects stack in following form
[X_addr_0, X_addr_1, Y_addr_0, Y_addr_1, Z_addr_0, Z_addr_1, Sc0, Sc1, Sc2, Sc3, Sc4, Sc5, Sc6, Sc7, X'_addr_0, X'_addr_1, Y'_addr_0, Y'_addr_1, Z'_addr_0, Z'_addr_1, ...]
X_addr_0, X_addr_1 -> Input secp256k1 point's X -coordinate to be placed, in Montgomery form, in given addresses
Y_addr_0, Y_addr_1 -> Input secp256k1 point's Y -coordinate to be placed, in Montgomery form, in given addresses
Z_addr_1, Z_addr_1 -> Input secp256k1 point's Z -coordinate to be placed, in Montgomery form, in given addresses
Sc{0..8} -> 256 -bit scalar in radix-2^32 form \| Sc0 is least significant limb & Sc7 is most significant limb
X'_addr_0, X'_addr_1 -> Resulting secp256k1 point's X -coordinate to be placed, in Montgomery form, in given addresses
Y'_addr_0, Y'_addr_1 -> Resulting secp256k1 point's Y -coordinate to be placed, in Montgomery form, in given addresses
Z'_addr_1, Z'_addr_1 -> Resulting secp256k1 point's Z -coordinate to be placed, in Montgomery form, in given addresses
Output:
At end of execution of this routine, stack should look like below
[X_addr_0, X_addr_1, Y_addr_0, Y_addr_1, Z_addr_0, Z_addr_1, ...]
X_addr_0, X_addr_1 -> Resulting secp256k1 point's X -coordinate written, in Montgomery form, in given addresses
Y_addr_0, Y_addr_1 -> Resulting secp256k1 point's Y -coordinate written, in Montgomery form, in given addresses
Z_addr_0, Z_addr_1 -> Resulting secp256k1 point's Z -coordinate written, in Montgomery form, in given addresses
One interested in resulting point, should read from provided addresses on stack.
This routine implements double-and-add algorithm, while following
https://github.com/itzmeanjan/secp256k1/blob/d23ea7d/point.py#L174-L186
If base point being multiplied is secp256k1 curve generator point, one should use `gen_point` routine,
which is almost 2x faster !
|
| gen_mul | Given a 256 -bit scalar, in radix-2^32 representation ( such that it takes 8 stack elements
to represent whole scalar, where each limb is of 32 -bit width ), this routine multiplies
secp256k1 generator point ( in projective coordinate system ) with given scalar, producing
another point on secp256k1 curve, which will also be presented in projective coordinate
system.
Input:
During invocation, this routine expects stack in following form
[Sc0, Sc1, Sc2, Sc3, Sc4, Sc5, Sc6, Sc7, X_addr_0, X_addr_1, Y_addr_0, Y_addr_1, Z_addr_0, Z_addr_1, ...]
Sc{0..8} -> 256 -bit scalar in radix-2^32 form \| Sc0 is least significant limb & Sc7 is most significant limb
X_addr_0, X_addr_1 -> Resulting secp256k1 point's X -coordinate to be placed, in Montgomery form, in given addresses
Y_addr_0, Y_addr_1 -> Resulting secp256k1 point's Y -coordinate to be placed, in Montgomery form, in given addresses
Z_addr_1, Z_addr_1 -> Resulting secp256k1 point's Z -coordinate to be placed, in Montgomery form, in given addresses
Output:
At end of execution of this routine, stack should look like below
[X_addr_0, X_addr_1, Y_addr_0, Y_addr_1, Z_addr_0, Z_addr_1, ...]
X_addr_0, X_addr_1 -> Resulting secp256k1 point's X -coordinate written, in Montgomery form, in given addresses
Y_addr_0, Y_addr_1 -> Resulting secp256k1 point's Y -coordinate written, in Montgomery form, in given addresses
Z_addr_0, Z_addr_1 -> Resulting secp256k1 point's Z -coordinate written, in Montgomery form, in given addresses
One interested in resulting point, should read from provided address on stack.
This routine implements double-and-add algorithm, while following
https://github.com/itzmeanjan/secp256k1/blob/d23ea7d/point.py#L174-L186
Note, this routine is a specialised instantiation of secp256k1 point multiplication, where we know what the base
point is, so we enjoy faster computation ( because all point doublings can be precomputed, saving us 256 point doublings ! ).
|