miden-stdlib 0.1.0

Miden VM standard library
1
2
3
4
5
6
7
8
9
10
11
12
13

## std::math::secp256k1
| Procedure | Description |
| ----------- | ------------- |
| u256_mod_mul.2 |  Given two 256 -bit numbers on stack, where each number is represented in<br /> radix-2^32 form ( i.e. each number having eight 32 -bit limbs ), following function<br /> computes modular multiplication of those two operands, computing 256 -bit result.<br /><br /> Stack expected as below, holding input<br /><br /> [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<br /><br /> After finishing execution of this function, stack should look like<br /><br /> [c0, c1, c2, c3, c4, c5, c6, c7] \| c[0..8] is a 256 -bit number<br /><br /> Note, for computing modular multiplication of a[0..8] & b[0..8],<br /> school book multiplication equipped with montgomery reduction technique<br /> is used, which is why a[0..8], b[0..8] are expected to be in montgomery form,<br /> while computed c[0..8] will also be in montgomery form. |
| u256_mod_add |  Given two 256 -bit numbers on stack, where each number is represented in<br /> radix-2^32 form ( i.e. each number having eight 32 -bit limbs ), following function<br /> computes modular addition of those two operands, in secp256k1 prime field.<br /><br /> Stack expected as below, holding input<br /><br /> [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<br /><br /> After finishing execution of this function, stack should look like<br /><br /> [c0, c1, c2, c3, c4, c5, c6, c7] \| c[0..8] is a 256 -bit number<br /><br /> This implementation takes inspiration from https://gist.github.com/itzmeanjan/d4853347dfdfa853993f5ea059824de6#file-test_montgomery_arithmetic-py-L236-L256 |
| u256_mod_neg |  Given a secp256k1 field element ( say `a` ) on stack, represented in Montgomery form <br /> ( i.e. number having eight 32 -bit limbs ), following function negates it to<br /> field element `a'` \| a' + a = 0<br /><br /> Stack expected as below, holding input<br /><br /> [a0, a1, a2, a3, a4, a5, a6, a7] \| a[0..8] is a secp256k1 field element<br /><br /> After finishing execution of this function, stack should look like<br /><br /> [c0, c1, c2, c3, c4, c5, c6, c7] \| c[0..8] is a secp256k1 field element<br /><br /> See https://github.com/itzmeanjan/secp256k1/blob/ec3652afe8ed72b29b0e39273a876a898316fb9a/field.py#L77-L95 |
| u256_mod_sub |  Given two secp256k1 field elements, say a, b, ( represented in Montgomery form, each number having <br /> eight 32 -bit limbs ) on stack, following function computes modular subtraction of those <br /> two operands c = a + (-b) = a - b<br /><br /> Stack expected as below, holding input<br /><br /> [a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, b3, b4, b5, b6, b7] \| a[0..8], b[0..8] are secp256k1 field elements<br /><br /> After finishing execution of this function, stack should look like<br /><br /> [c0, c1, c2, c3, c4, c5, c6, c7] \| c[0..8] is a secp256k1 field element<br /><br /> See https://github.com/itzmeanjan/secp256k1/blob/ec3652afe8ed72b29b0e39273a876a898316fb9a/field.py#L97-L101 |
| to_mont |  Given a 256 -bit number on stack, represented in radix-2^32 <br /> form i.e. eight 32 -bit limbs, this routine computes Montgomery<br /> representation of provided radix-2^32 number.<br /><br /> - u256 radix-2^32 form input expected on stack as<br /><br />  [a0, a1, a2, a3, a4, a5, a6, a7]<br /><br /> - u256 montgomery form output on stack<br /><br /> [a0`, a1`, a2`, a3`, a4`, a5`, a6`, a7`]<br /><br /> See section 2.2 of https://eprint.iacr.org/2017/1057.pdf |
| from_mont |  Given a 256 -bit number on stack, represented in Montgomery <br /> form i.e. eight 32 -bit limbs, this routine computes radix-2^32<br /> representation of provided u256 number.<br /><br /> - u256 montgomery form input on stack expected<br /><br />  [a0, a1, a2, a3, a4, a5, a6, a7]<br /><br /> - u256 radix-2^32 form output on stack as<br /><br /> [a0`, a1`, a2`, a3`, a4`, a5`, a6`, a7`]<br /><br /> See section 2.2 of https://eprint.iacr.org/2017/1057.pdf |
| point_doubling.12 |  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]] |
| point_addition.16 |  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]] |
| point_mul.20 |  Given 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 <br /> of 32 -bit width ), this routine multiplies group identity point <br /> ( 0, 1, 0 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  |