miden-stdlib 0.19.1

Miden VM standard library
Documentation
1
2
3
4
5
6
7
8

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