1
mirror of https://github.com/hashcat/hashcat synced 2024-12-23 14:13:43 +01:00

Refactoring: Extract transform_public, point_mul_xy and set_precomputed_basepoint_g. Add constants and documentation.

This commit is contained in:
Bernard Ladenthin 2021-02-08 23:02:47 +01:00
parent 19f4b44840
commit b85ffd63fb
2 changed files with 389 additions and 42 deletions

View File

@ -1730,11 +1730,10 @@ DECLSPEC void point_get_coords (secp256k1_t *r, const u32 *x, const u32 *y)
r->xy[95] = neg[7];
}
/*
* Convert the tweak/scalar k to w-NAF (window size is 4).
* @param out: naf a pointer to an u32 array with a size of 33.
* @param in: k a pointer to a tweak/scalar which should be converted.
* @param naf out: w-NAF form of the tweak/scalar, a pointer to an u32 array with a size of 33.
* @param k in: tweak/scalar which should be converted, a pointer to an u32 array with a size of 8.
* @return Returns the loop start index.
*/
DECLSPEC int convert_to_window_naf (u32 *naf, const u32 *k)
@ -1837,9 +1836,16 @@ DECLSPEC int convert_to_window_naf (u32 *naf, const u32 *k)
return loop_start;
}
DECLSPEC void point_mul (u32 *r, const u32 *k, GLOBAL_AS const secp256k1_t *tmps)
/*
* @param x1 out: x coordinate, a pointer to an u32 array with a size of 8.
* @param y1 out: y coordinate, a pointer to an u32 array with a size of 8.
* @param k in: tweak/scalar which should be converted, a pointer to an u32 array with a size of 8.
* @param tmps in: a basepoint for the multiplication.
* @return Returns the x coordinate with a leading parity/sign (for odd/even y), it is named a compressed coordinate.
*/
DECLSPEC void point_mul_xy (u32 *x1, u32 *y1, const u32 *k, GLOBAL_AS const secp256k1_t *tmps)
{
u32 naf[32 + 1] = { 0 }; // we need one extra slot
u32 naf[SECP256K1_NAF_SIZE] = { 0 };
int loop_start = convert_to_window_naf(naf, k);
// first set:
@ -1851,7 +1857,6 @@ DECLSPEC void point_mul (u32 *r, const u32 *k, GLOBAL_AS const secp256k1_t *tmps
const u32 x_pos = ((multiplier - 1 + odd) >> 1) * 24;
const u32 y_pos = odd ? (x_pos + 8) : (x_pos + 16);
u32 x1[8];
x1[0] = tmps->xy[x_pos + 0];
x1[1] = tmps->xy[x_pos + 1];
@ -1862,8 +1867,6 @@ DECLSPEC void point_mul (u32 *r, const u32 *k, GLOBAL_AS const secp256k1_t *tmps
x1[6] = tmps->xy[x_pos + 6];
x1[7] = tmps->xy[x_pos + 7];
u32 y1[8];
y1[0] = tmps->xy[y_pos + 0];
y1[1] = tmps->xy[y_pos + 1];
y1[2] = tmps->xy[y_pos + 2];
@ -1971,51 +1974,51 @@ DECLSPEC void point_mul (u32 *r, const u32 *k, GLOBAL_AS const secp256k1_t *tmps
mul_mod (z1, z2, z1); // z1^3
mul_mod (y1, y1, z1); // y1_affine
// return values are already in x1 and y1
}
/*
* @param r out: x coordinate with leading parity/sign (for odd/even y), a pointer to an u32 array with a size of 9.
* @param k in: tweak/scalar which should be converted, a pointer to an u32 array with a size of 8.
* @param tmps in: a basepoint for the multiplication.
* @return Returns the x coordinate with a leading parity/sign (for odd/even y), it is named a compressed coordinate.
*/
DECLSPEC void point_mul (u32 *r, const u32 *k, GLOBAL_AS const secp256k1_t *tmps)
{
u32 x[8];
u32 y[8];
point_mul_xy(x, y, k, tmps);
/*
* output:
*/
// shift by 1 byte (8 bits) to make room and add the parity/sign (for odd/even y):
r[8] = (x1[0] << 24);
r[7] = (x1[0] >> 8) | (x1[1] << 24);
r[6] = (x1[1] >> 8) | (x1[2] << 24);
r[5] = (x1[2] >> 8) | (x1[3] << 24);
r[4] = (x1[3] >> 8) | (x1[4] << 24);
r[3] = (x1[4] >> 8) | (x1[5] << 24);
r[2] = (x1[5] >> 8) | (x1[6] << 24);
r[1] = (x1[6] >> 8) | (x1[7] << 24);
r[0] = (x1[7] >> 8);
r[8] = (x[0] << 24);
r[7] = (x[0] >> 8) | (x[1] << 24);
r[6] = (x[1] >> 8) | (x[2] << 24);
r[5] = (x[2] >> 8) | (x[3] << 24);
r[4] = (x[3] >> 8) | (x[4] << 24);
r[3] = (x[4] >> 8) | (x[5] << 24);
r[2] = (x[5] >> 8) | (x[6] << 24);
r[1] = (x[6] >> 8) | (x[7] << 24);
r[0] = (x[7] >> 8);
const u32 type = 0x02 | (y1[0] & 1); // (note: 0b10 | 0b01 = 0x03)
const u32 type = 0x02 | (y[0] & 1); // (note: 0b10 | 0b01 = 0x03)
r[0] = r[0] | type << 24; // 0x02 or 0x03
}
DECLSPEC u32 parse_public (secp256k1_t *r, const u32 *k)
/*
* Transform a x coordinate and separate parity to secp256k1_t.
* @param r out: x and y coordinates.
* @param x in: x coordinate which should be converted, a pointer to an u32 array with a size of 8.
* @param first_byte in: The parity of the y coordinate, a u32.
* @return Returns 0 if successfull, returns 1 if x is greater than the basepoint.
*/
DECLSPEC u32 transform_public (secp256k1_t *r, const u32 *x, const u32 first_byte)
{
// verify:
const u32 first_byte = k[0] & 0xff;
if ((first_byte != '\x02') && (first_byte != '\x03'))
{
return 1;
}
// load k into x without the first byte:
u32 x[8];
x[0] = (k[7] & 0xff00) << 16 | (k[7] & 0xff0000) | (k[7] & 0xff000000) >> 16 | (k[8] & 0xff);
x[1] = (k[6] & 0xff00) << 16 | (k[6] & 0xff0000) | (k[6] & 0xff000000) >> 16 | (k[7] & 0xff);
x[2] = (k[5] & 0xff00) << 16 | (k[5] & 0xff0000) | (k[5] & 0xff000000) >> 16 | (k[6] & 0xff);
x[3] = (k[4] & 0xff00) << 16 | (k[4] & 0xff0000) | (k[4] & 0xff000000) >> 16 | (k[5] & 0xff);
x[4] = (k[3] & 0xff00) << 16 | (k[3] & 0xff0000) | (k[3] & 0xff000000) >> 16 | (k[4] & 0xff);
x[5] = (k[2] & 0xff00) << 16 | (k[2] & 0xff0000) | (k[2] & 0xff000000) >> 16 | (k[3] & 0xff);
x[6] = (k[1] & 0xff00) << 16 | (k[1] & 0xff0000) | (k[1] & 0xff000000) >> 16 | (k[2] & 0xff);
x[7] = (k[0] & 0xff00) << 16 | (k[0] & 0xff0000) | (k[0] & 0xff000000) >> 16 | (k[1] & 0xff);
u32 p[8];
p[0] = SECP256K1_P0;
@ -2067,3 +2070,163 @@ DECLSPEC u32 parse_public (secp256k1_t *r, const u32 *k)
return 0;
}
/*
* Parse a x coordinate with leading parity to secp256k1_t.
* @param r out: x and y coordinates.
* @param k in: x coordinate which should be converted with leading parity, a pointer to an u32 array with a size of 9.
* @return Returns 0 if successfull, returns 1 if x is greater than the basepoint or the parity has an unexpected value.
*/
DECLSPEC u32 parse_public (secp256k1_t *r, const u32 *k)
{
// verify:
const u32 first_byte = k[0] & 0xff;
if ((first_byte != '\x02') && (first_byte != '\x03'))
{
return 1;
}
// load k into x without the first byte:
u32 x[8];
x[0] = (k[7] & 0xff00) << 16 | (k[7] & 0xff0000) | (k[7] & 0xff000000) >> 16 | (k[8] & 0xff);
x[1] = (k[6] & 0xff00) << 16 | (k[6] & 0xff0000) | (k[6] & 0xff000000) >> 16 | (k[7] & 0xff);
x[2] = (k[5] & 0xff00) << 16 | (k[5] & 0xff0000) | (k[5] & 0xff000000) >> 16 | (k[6] & 0xff);
x[3] = (k[4] & 0xff00) << 16 | (k[4] & 0xff0000) | (k[4] & 0xff000000) >> 16 | (k[5] & 0xff);
x[4] = (k[3] & 0xff00) << 16 | (k[3] & 0xff0000) | (k[3] & 0xff000000) >> 16 | (k[4] & 0xff);
x[5] = (k[2] & 0xff00) << 16 | (k[2] & 0xff0000) | (k[2] & 0xff000000) >> 16 | (k[3] & 0xff);
x[6] = (k[1] & 0xff00) << 16 | (k[1] & 0xff0000) | (k[1] & 0xff000000) >> 16 | (k[2] & 0xff);
x[7] = (k[0] & 0xff00) << 16 | (k[0] & 0xff0000) | (k[0] & 0xff000000) >> 16 | (k[1] & 0xff);
return transform_public(r, x, first_byte);
}
/*
* Set precomputed values of the basepoint g to a secp256k1 structure.
* @param r out: x and y coordinates. pre-computed points: (x1,y1,-y1),(x3,y3,-y3),(x5,y5,-y5),(x7,y7,-y7)
*/
DECLSPEC void set_precomputed_basepoint_g (secp256k1_t *r) {
// x1
r->xy[ 0] = SECP256K1_G_PRE_COMPUTED_00;
r->xy[ 1] = SECP256K1_G_PRE_COMPUTED_01;
r->xy[ 2] = SECP256K1_G_PRE_COMPUTED_02;
r->xy[ 3] = SECP256K1_G_PRE_COMPUTED_03;
r->xy[ 4] = SECP256K1_G_PRE_COMPUTED_04;
r->xy[ 5] = SECP256K1_G_PRE_COMPUTED_05;
r->xy[ 6] = SECP256K1_G_PRE_COMPUTED_06;
r->xy[ 7] = SECP256K1_G_PRE_COMPUTED_07;
// y1
r->xy[ 8] = SECP256K1_G_PRE_COMPUTED_08;
r->xy[ 9] = SECP256K1_G_PRE_COMPUTED_09;
r->xy[10] = SECP256K1_G_PRE_COMPUTED_10;
r->xy[11] = SECP256K1_G_PRE_COMPUTED_11;
r->xy[12] = SECP256K1_G_PRE_COMPUTED_12;
r->xy[13] = SECP256K1_G_PRE_COMPUTED_13;
r->xy[14] = SECP256K1_G_PRE_COMPUTED_14;
r->xy[15] = SECP256K1_G_PRE_COMPUTED_15;
// -y1
r->xy[16] = SECP256K1_G_PRE_COMPUTED_16;
r->xy[17] = SECP256K1_G_PRE_COMPUTED_17;
r->xy[18] = SECP256K1_G_PRE_COMPUTED_18;
r->xy[19] = SECP256K1_G_PRE_COMPUTED_19;
r->xy[20] = SECP256K1_G_PRE_COMPUTED_20;
r->xy[21] = SECP256K1_G_PRE_COMPUTED_21;
r->xy[22] = SECP256K1_G_PRE_COMPUTED_22;
r->xy[23] = SECP256K1_G_PRE_COMPUTED_23;
// x3
r->xy[24] = SECP256K1_G_PRE_COMPUTED_24;
r->xy[25] = SECP256K1_G_PRE_COMPUTED_25;
r->xy[26] = SECP256K1_G_PRE_COMPUTED_26;
r->xy[27] = SECP256K1_G_PRE_COMPUTED_27;
r->xy[28] = SECP256K1_G_PRE_COMPUTED_28;
r->xy[29] = SECP256K1_G_PRE_COMPUTED_29;
r->xy[30] = SECP256K1_G_PRE_COMPUTED_30;
r->xy[31] = SECP256K1_G_PRE_COMPUTED_31;
// y3
r->xy[32] = SECP256K1_G_PRE_COMPUTED_32;
r->xy[33] = SECP256K1_G_PRE_COMPUTED_33;
r->xy[34] = SECP256K1_G_PRE_COMPUTED_34;
r->xy[35] = SECP256K1_G_PRE_COMPUTED_35;
r->xy[36] = SECP256K1_G_PRE_COMPUTED_36;
r->xy[37] = SECP256K1_G_PRE_COMPUTED_37;
r->xy[38] = SECP256K1_G_PRE_COMPUTED_38;
r->xy[39] = SECP256K1_G_PRE_COMPUTED_39;
// -y3
r->xy[40] = SECP256K1_G_PRE_COMPUTED_40;
r->xy[41] = SECP256K1_G_PRE_COMPUTED_41;
r->xy[42] = SECP256K1_G_PRE_COMPUTED_42;
r->xy[43] = SECP256K1_G_PRE_COMPUTED_43;
r->xy[44] = SECP256K1_G_PRE_COMPUTED_44;
r->xy[45] = SECP256K1_G_PRE_COMPUTED_45;
r->xy[46] = SECP256K1_G_PRE_COMPUTED_46;
r->xy[47] = SECP256K1_G_PRE_COMPUTED_47;
// x5
r->xy[48] = SECP256K1_G_PRE_COMPUTED_48;
r->xy[49] = SECP256K1_G_PRE_COMPUTED_49;
r->xy[50] = SECP256K1_G_PRE_COMPUTED_50;
r->xy[51] = SECP256K1_G_PRE_COMPUTED_51;
r->xy[52] = SECP256K1_G_PRE_COMPUTED_52;
r->xy[53] = SECP256K1_G_PRE_COMPUTED_53;
r->xy[54] = SECP256K1_G_PRE_COMPUTED_54;
r->xy[55] = SECP256K1_G_PRE_COMPUTED_55;
// y5
r->xy[56] = SECP256K1_G_PRE_COMPUTED_56;
r->xy[57] = SECP256K1_G_PRE_COMPUTED_57;
r->xy[58] = SECP256K1_G_PRE_COMPUTED_58;
r->xy[59] = SECP256K1_G_PRE_COMPUTED_59;
r->xy[60] = SECP256K1_G_PRE_COMPUTED_60;
r->xy[61] = SECP256K1_G_PRE_COMPUTED_61;
r->xy[62] = SECP256K1_G_PRE_COMPUTED_62;
r->xy[63] = SECP256K1_G_PRE_COMPUTED_63;
// -y5
r->xy[64] = SECP256K1_G_PRE_COMPUTED_64;
r->xy[65] = SECP256K1_G_PRE_COMPUTED_65;
r->xy[66] = SECP256K1_G_PRE_COMPUTED_66;
r->xy[67] = SECP256K1_G_PRE_COMPUTED_67;
r->xy[68] = SECP256K1_G_PRE_COMPUTED_68;
r->xy[69] = SECP256K1_G_PRE_COMPUTED_69;
r->xy[70] = SECP256K1_G_PRE_COMPUTED_70;
r->xy[71] = SECP256K1_G_PRE_COMPUTED_71;
// x7
r->xy[72] = SECP256K1_G_PRE_COMPUTED_72;
r->xy[73] = SECP256K1_G_PRE_COMPUTED_73;
r->xy[74] = SECP256K1_G_PRE_COMPUTED_74;
r->xy[75] = SECP256K1_G_PRE_COMPUTED_75;
r->xy[76] = SECP256K1_G_PRE_COMPUTED_76;
r->xy[77] = SECP256K1_G_PRE_COMPUTED_77;
r->xy[78] = SECP256K1_G_PRE_COMPUTED_78;
r->xy[79] = SECP256K1_G_PRE_COMPUTED_79;
// y7
r->xy[80] = SECP256K1_G_PRE_COMPUTED_80;
r->xy[81] = SECP256K1_G_PRE_COMPUTED_81;
r->xy[82] = SECP256K1_G_PRE_COMPUTED_82;
r->xy[83] = SECP256K1_G_PRE_COMPUTED_83;
r->xy[84] = SECP256K1_G_PRE_COMPUTED_84;
r->xy[85] = SECP256K1_G_PRE_COMPUTED_85;
r->xy[86] = SECP256K1_G_PRE_COMPUTED_86;
r->xy[87] = SECP256K1_G_PRE_COMPUTED_87;
// -y7
r->xy[88] = SECP256K1_G_PRE_COMPUTED_88;
r->xy[89] = SECP256K1_G_PRE_COMPUTED_89;
r->xy[90] = SECP256K1_G_PRE_COMPUTED_90;
r->xy[91] = SECP256K1_G_PRE_COMPUTED_91;
r->xy[92] = SECP256K1_G_PRE_COMPUTED_92;
r->xy[93] = SECP256K1_G_PRE_COMPUTED_93;
r->xy[94] = SECP256K1_G_PRE_COMPUTED_94;
r->xy[95] = SECP256K1_G_PRE_COMPUTED_95;
}

View File

@ -10,6 +10,8 @@
#define SECP256K1_B 7
// finite field Fp
// p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
#define SECP256K1_P0 0xfffffc2f
#define SECP256K1_P1 0xfffffffe
#define SECP256K1_P2 0xffffffff
@ -19,6 +21,8 @@
#define SECP256K1_P6 0xffffffff
#define SECP256K1_P7 0xffffffff
// prime order N
// n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
#define SECP256K1_N0 0xd0364141
#define SECP256K1_N1 0xbfd25e8c
#define SECP256K1_N2 0xaf48a03b
@ -28,14 +32,194 @@
#define SECP256K1_N6 0xffffffff
#define SECP256K1_N7 0xffffffff
// the base point G in compressed form for transform_public
// G = 02 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
#define SECP256K1_G_PARITY 0x00000002
#define SECP256K1_G0 0x16f81798
#define SECP256K1_G1 0x59f2815b
#define SECP256K1_G2 0x2dce28d9
#define SECP256K1_G3 0x029bfcdb
#define SECP256K1_G4 0xce870b07
#define SECP256K1_G5 0x55a06295
#define SECP256K1_G6 0xf9dcbbac
#define SECP256K1_G7 0x79be667e
// the base point G in compressed form for parse_public
// parity and reversed byte/char (8 bit) byte order
// G = 02 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
#define SECP256K1_G_STRING0 0x66be7902
#define SECP256K1_G_STRING1 0xbbdcf97e
#define SECP256K1_G_STRING2 0x62a055ac
#define SECP256K1_G_STRING3 0x0b87ce95
#define SECP256K1_G_STRING4 0xfc9b0207
#define SECP256K1_G_STRING5 0x28ce2ddb
#define SECP256K1_G_STRING6 0x81f259d9
#define SECP256K1_G_STRING7 0x17f8165b
#define SECP256K1_G_STRING8 0x00000098
// pre computed values, can be verified using private keys for
// x1 is the same as the basepoint g
// x1 WIF: KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn
// x3 WIF: KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74sHUHy8S
// x5 WIF: KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU75s2EPgZf
// x7 WIF: KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU76rnZwVdz
// x1: 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
// x1: 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
#define SECP256K1_G_PRE_COMPUTED_00 0x16f81798
#define SECP256K1_G_PRE_COMPUTED_01 0x59f2815b
#define SECP256K1_G_PRE_COMPUTED_02 0x2dce28d9
#define SECP256K1_G_PRE_COMPUTED_03 0x029bfcdb
#define SECP256K1_G_PRE_COMPUTED_04 0xce870b07
#define SECP256K1_G_PRE_COMPUTED_05 0x55a06295
#define SECP256K1_G_PRE_COMPUTED_06 0xf9dcbbac
#define SECP256K1_G_PRE_COMPUTED_07 0x79be667e
// y1: 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8
// y1: 483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
#define SECP256K1_G_PRE_COMPUTED_08 0xfb10d4b8
#define SECP256K1_G_PRE_COMPUTED_09 0x9c47d08f
#define SECP256K1_G_PRE_COMPUTED_10 0xa6855419
#define SECP256K1_G_PRE_COMPUTED_11 0xfd17b448
#define SECP256K1_G_PRE_COMPUTED_12 0x0e1108a8
#define SECP256K1_G_PRE_COMPUTED_13 0x5da4fbfc
#define SECP256K1_G_PRE_COMPUTED_14 0x26a3c465
#define SECP256K1_G_PRE_COMPUTED_15 0x483ada77
// -y1: B7C52588 D95C3B9A A25B0403 F1EEF757 02E84BB7 597AABE6 63B82F6F 04EF2777
// -y1: B7C52588D95C3B9AA25B0403F1EEF75702E84BB7597AABE663B82F6F04EF2777
#define SECP256K1_G_PRE_COMPUTED_16 0x04ef2777
#define SECP256K1_G_PRE_COMPUTED_17 0x63b82f6f
#define SECP256K1_G_PRE_COMPUTED_18 0x597aabe6
#define SECP256K1_G_PRE_COMPUTED_19 0x02e84bb7
#define SECP256K1_G_PRE_COMPUTED_20 0xf1eef757
#define SECP256K1_G_PRE_COMPUTED_21 0xa25b0403
#define SECP256K1_G_PRE_COMPUTED_22 0xd95c3b9a
#define SECP256K1_G_PRE_COMPUTED_23 0xb7c52588
// x3: F9308A01 9258C310 49344F85 F89D5229 B531C845 836F99B0 8601F113 BCE036F9
// x3: F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9
#define SECP256K1_G_PRE_COMPUTED_24 0xbce036f9
#define SECP256K1_G_PRE_COMPUTED_25 0x8601f113
#define SECP256K1_G_PRE_COMPUTED_26 0x836f99b0
#define SECP256K1_G_PRE_COMPUTED_27 0xb531c845
#define SECP256K1_G_PRE_COMPUTED_28 0xf89d5229
#define SECP256K1_G_PRE_COMPUTED_29 0x49344f85
#define SECP256K1_G_PRE_COMPUTED_30 0x9258c310
#define SECP256K1_G_PRE_COMPUTED_31 0xf9308a01
// y3: 388F7B0F 632DE814 0FE337E6 2A37F356 6500A999 34C2231B 6CB9FD75 84B8E672
// y3: 388F7B0F632DE8140FE337E62A37F3566500A99934C2231B6CB9FD7584B8E672
#define SECP256K1_G_PRE_COMPUTED_32 0x84b8e672
#define SECP256K1_G_PRE_COMPUTED_33 0x6cb9fd75
#define SECP256K1_G_PRE_COMPUTED_34 0x34c2231b
#define SECP256K1_G_PRE_COMPUTED_35 0x6500a999
#define SECP256K1_G_PRE_COMPUTED_36 0x2a37f356
#define SECP256K1_G_PRE_COMPUTED_37 0x0fe337e6
#define SECP256K1_G_PRE_COMPUTED_38 0x632de814
#define SECP256K1_G_PRE_COMPUTED_39 0x388f7b0f
// -y3: C77084F0 9CD217EB F01CC819 D5C80CA9 9AFF5666 CB3DDCE4 93460289 7B4715BD
// -y3: C77084F09CD217EBF01CC819D5C80CA99AFF5666CB3DDCE4934602897B4715BD
#define SECP256K1_G_PRE_COMPUTED_40 0x7b4715bd
#define SECP256K1_G_PRE_COMPUTED_41 0x93460289
#define SECP256K1_G_PRE_COMPUTED_42 0xcb3ddce4
#define SECP256K1_G_PRE_COMPUTED_43 0x9aff5666
#define SECP256K1_G_PRE_COMPUTED_44 0xd5c80ca9
#define SECP256K1_G_PRE_COMPUTED_45 0xf01cc819
#define SECP256K1_G_PRE_COMPUTED_46 0x9cd217eb
#define SECP256K1_G_PRE_COMPUTED_47 0xc77084f0
// x5: 2F8BDE4D 1A072093 55B4A725 0A5C5128 E88B84BD DC619AB7 CBA8D569 B240EFE4
// x5: 2F8BDE4D1A07209355B4A7250A5C5128E88B84BDDC619AB7CBA8D569B240EFE4
#define SECP256K1_G_PRE_COMPUTED_48 0xb240efe4
#define SECP256K1_G_PRE_COMPUTED_49 0xcba8d569
#define SECP256K1_G_PRE_COMPUTED_50 0xdc619ab7
#define SECP256K1_G_PRE_COMPUTED_51 0xe88b84bd
#define SECP256K1_G_PRE_COMPUTED_52 0x0a5c5128
#define SECP256K1_G_PRE_COMPUTED_53 0x55b4a725
#define SECP256K1_G_PRE_COMPUTED_54 0x1a072093
#define SECP256K1_G_PRE_COMPUTED_55 0x2f8bde4d
// y5: D8AC2226 36E5E3D6 D4DBA9DD A6C9C426 F788271B AB0D6840 DCA87D3A A6AC62D6
// y5: D8AC222636E5E3D6D4DBA9DDA6C9C426F788271BAB0D6840DCA87D3AA6AC62D6
#define SECP256K1_G_PRE_COMPUTED_56 0xa6ac62d6
#define SECP256K1_G_PRE_COMPUTED_57 0xdca87d3a
#define SECP256K1_G_PRE_COMPUTED_58 0xab0d6840
#define SECP256K1_G_PRE_COMPUTED_59 0xf788271b
#define SECP256K1_G_PRE_COMPUTED_60 0xa6c9c426
#define SECP256K1_G_PRE_COMPUTED_61 0xd4dba9dd
#define SECP256K1_G_PRE_COMPUTED_62 0x36e5e3d6
#define SECP256K1_G_PRE_COMPUTED_63 0xd8ac2226
// -y5: 2753DDD9 C91A1C29 2B245622 59363BD9 0877D8E4 54F297BF 235782C4 59539959
// -y5: 2753DDD9C91A1C292B24562259363BD90877D8E454F297BF235782C459539959
#define SECP256K1_G_PRE_COMPUTED_64 0x59539959
#define SECP256K1_G_PRE_COMPUTED_65 0x235782c4
#define SECP256K1_G_PRE_COMPUTED_66 0x54f297bf
#define SECP256K1_G_PRE_COMPUTED_67 0x0877d8e4
#define SECP256K1_G_PRE_COMPUTED_68 0x59363bd9
#define SECP256K1_G_PRE_COMPUTED_69 0x2b245622
#define SECP256K1_G_PRE_COMPUTED_70 0xc91a1c29
#define SECP256K1_G_PRE_COMPUTED_71 0x2753ddd9
// x7: 5CBDF064 6E5DB4EA A398F365 F2EA7A0E 3D419B7E 0330E39C E92BDDED CAC4F9BC
// x7: 5CBDF0646E5DB4EAA398F365F2EA7A0E3D419B7E0330E39CE92BDDEDCAC4F9BC
#define SECP256K1_G_PRE_COMPUTED_72 0xcac4f9bc
#define SECP256K1_G_PRE_COMPUTED_73 0xe92bdded
#define SECP256K1_G_PRE_COMPUTED_74 0x0330e39c
#define SECP256K1_G_PRE_COMPUTED_75 0x3d419b7e
#define SECP256K1_G_PRE_COMPUTED_76 0xf2ea7a0e
#define SECP256K1_G_PRE_COMPUTED_77 0xa398f365
#define SECP256K1_G_PRE_COMPUTED_78 0x6e5db4ea
#define SECP256K1_G_PRE_COMPUTED_79 0x5cbdf064
// y7: 6AEBCA40 BA255960 A3178D6D 861A54DB A813D0B8 13FDE7B5 A5082628 087264DA
// y7: 6AEBCA40BA255960A3178D6D861A54DBA813D0B813FDE7B5A5082628087264DA
#define SECP256K1_G_PRE_COMPUTED_80 0x087264da
#define SECP256K1_G_PRE_COMPUTED_81 0xa5082628
#define SECP256K1_G_PRE_COMPUTED_82 0x13fde7b5
#define SECP256K1_G_PRE_COMPUTED_83 0xa813d0b8
#define SECP256K1_G_PRE_COMPUTED_84 0x861a54db
#define SECP256K1_G_PRE_COMPUTED_85 0xa3178d6d
#define SECP256K1_G_PRE_COMPUTED_86 0xba255960
#define SECP256K1_G_PRE_COMPUTED_87 0x6aebca40
// -y7: 951435BF 45DAA69F 5CE87292 79E5AB24 57EC2F47 EC02184A 5AF7D9D6 F78D9755
// -y7: 951435BF45DAA69F5CE8729279E5AB2457EC2F47EC02184A5AF7D9D6F78D9755
#define SECP256K1_G_PRE_COMPUTED_88 0xf78d9755
#define SECP256K1_G_PRE_COMPUTED_89 0x5af7d9d6
#define SECP256K1_G_PRE_COMPUTED_90 0xec02184a
#define SECP256K1_G_PRE_COMPUTED_91 0x57ec2f47
#define SECP256K1_G_PRE_COMPUTED_92 0x79e5ab24
#define SECP256K1_G_PRE_COMPUTED_93 0x5ce87292
#define SECP256K1_G_PRE_COMPUTED_94 0x45daa69f
#define SECP256K1_G_PRE_COMPUTED_95 0x951435bf
#define SECP256K1_PRE_COMPUTED_XY_SIZE 96
#define SECP256K1_NAF_SIZE 33 // 32+1, we need one extra slot
#define PUBLIC_KEY_LENGTH_WITHOUT_PARITY 8
#define PUBLIC_KEY_LENGTH_X_Y_WITHOUT_PARITY 16
// 8+1 to make room for the parity
#define PUBLIC_KEY_LENGTH_WITH_PARITY 9
// (32*8 == 256)
#define PRIVATE_KEY_LENGTH 8
typedef struct secp256k1
{
u32 xy[96]; // pre-computed points: (x1,y1,-y1),(x3,y3,-y3),(x5,y5,-y5),(x7,y7,-y7)
u32 xy[SECP256K1_PRE_COMPUTED_XY_SIZE]; // pre-computed points: (x1,y1,-y1),(x3,y3,-y3),(x5,y5,-y5),(x7,y7,-y7)
} secp256k1_t;
DECLSPEC u32 transform_public (secp256k1_t *r, const u32 *x, const u32 first_byte);
DECLSPEC u32 parse_public (secp256k1_t *r, const u32 *k);
DECLSPEC void point_mul_xy (u32 *x1, u32 *y1, const u32 *k, GLOBAL_AS const secp256k1_t *tmps);
DECLSPEC void point_mul (u32 *r, const u32 *k, GLOBAL_AS const secp256k1_t *tmps);
DECLSPEC void set_precomputed_basepoint_g (secp256k1_t *r);
#endif // _INC_ECC_SECP256K1_H