void run_ecmult_chain(void) { /* random starting point A (on the curve) */ secp256k1_fe_t ax; secp256k1_fe_set_hex(&ax, "8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004", 64); secp256k1_fe_t ay; secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64); secp256k1_gej_t a; secp256k1_gej_set_xy(&a, &ax, &ay); /* two random initial factors xn and gn */ secp256k1_num_t xn; secp256k1_num_set_hex(&xn, "84cc5452f7fde1edb4d38a8ce9b1b84ccef31f146e569be9705d357a42985407", 64); secp256k1_num_t gn; secp256k1_num_set_hex(&gn, "a1e58d22553dcd42b23980625d4c57a96e9323d42b3152e5ca2c3990edc7c9de", 64); /* two small multipliers to be applied to xn and gn in every iteration: */ secp256k1_num_t xf; secp256k1_num_set_hex(&xf, "1337", 4); secp256k1_num_t gf; secp256k1_num_set_hex(&gf, "7113", 4); /* accumulators with the resulting coefficients to A and G */ secp256k1_num_t ae; secp256k1_num_set_int(&ae, 1); secp256k1_num_t ge; secp256k1_num_set_int(&ge, 0); /* the point being computed */ secp256k1_gej_t x = a; const secp256k1_num_t *order = &secp256k1_ge_consts->order; for (int i=0; i<200*count; i++) { /* in each iteration, compute X = xn*X + gn*G; */ secp256k1_ecmult(&x, &x, &xn, &gn); /* also compute ae and ge: the actual accumulated factors for A and G */ /* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */ secp256k1_num_mod_mul(&ae, &ae, &xn, order); secp256k1_num_mod_mul(&ge, &ge, &xn, order); secp256k1_num_add(&ge, &ge, &gn); secp256k1_num_mod(&ge, order); /* modify xn and gn */ secp256k1_num_mod_mul(&xn, &xn, &xf, order); secp256k1_num_mod_mul(&gn, &gn, &gf, order); /* verify */ if (i == 19999) { char res[132]; int resl = 132; secp256k1_gej_get_hex(res, &resl, &x); CHECK(strcmp(res, "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)") == 0); } } /* redo the computation, but directly with the resulting ae and ge coefficients: */ secp256k1_gej_t x2; secp256k1_ecmult(&x2, &a, &ae, &ge); char res[132]; int resl = 132; char res2[132]; int resl2 = 132; secp256k1_gej_get_hex(res, &resl, &x); secp256k1_gej_get_hex(res2, &resl2, &x2); CHECK(strcmp(res, res2) == 0); CHECK(strlen(res) == 131); }
void run_ecmult_chain(void) { /* random starting point A (on the curve) */ secp256k1_fe_t ax; VERIFY_CHECK(secp256k1_fe_set_hex(&ax, "8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004", 64)); secp256k1_fe_t ay; VERIFY_CHECK(secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64)); secp256k1_gej_t a; secp256k1_gej_set_xy(&a, &ax, &ay); /* two random initial factors xn and gn */ static const unsigned char xni[32] = { 0x84, 0xcc, 0x54, 0x52, 0xf7, 0xfd, 0xe1, 0xed, 0xb4, 0xd3, 0x8a, 0x8c, 0xe9, 0xb1, 0xb8, 0x4c, 0xce, 0xf3, 0x1f, 0x14, 0x6e, 0x56, 0x9b, 0xe9, 0x70, 0x5d, 0x35, 0x7a, 0x42, 0x98, 0x54, 0x07 }; secp256k1_scalar_t xn; secp256k1_scalar_set_b32(&xn, xni, NULL); static const unsigned char gni[32] = { 0xa1, 0xe5, 0x8d, 0x22, 0x55, 0x3d, 0xcd, 0x42, 0xb2, 0x39, 0x80, 0x62, 0x5d, 0x4c, 0x57, 0xa9, 0x6e, 0x93, 0x23, 0xd4, 0x2b, 0x31, 0x52, 0xe5, 0xca, 0x2c, 0x39, 0x90, 0xed, 0xc7, 0xc9, 0xde }; secp256k1_scalar_t gn; secp256k1_scalar_set_b32(&gn, gni, NULL); /* two small multipliers to be applied to xn and gn in every iteration: */ static const unsigned char xfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x13,0x37}; secp256k1_scalar_t xf; secp256k1_scalar_set_b32(&xf, xfi, NULL); static const unsigned char gfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x71,0x13}; secp256k1_scalar_t gf; secp256k1_scalar_set_b32(&gf, gfi, NULL); /* accumulators with the resulting coefficients to A and G */ secp256k1_scalar_t ae; secp256k1_scalar_set_int(&ae, 1); secp256k1_scalar_t ge; secp256k1_scalar_set_int(&ge, 0); /* the point being computed */ secp256k1_gej_t x = a; for (int i=0; i<200*count; i++) { /* in each iteration, compute X = xn*X + gn*G; */ secp256k1_ecmult(&x, &x, &xn, &gn); /* also compute ae and ge: the actual accumulated factors for A and G */ /* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */ secp256k1_scalar_mul(&ae, &ae, &xn); secp256k1_scalar_mul(&ge, &ge, &xn); secp256k1_scalar_add(&ge, &ge, &gn); /* modify xn and gn */ secp256k1_scalar_mul(&xn, &xn, &xf); secp256k1_scalar_mul(&gn, &gn, &gf); /* verify */ if (i == 19999) { char res[132]; int resl = 132; secp256k1_gej_get_hex(res, &resl, &x); CHECK(strcmp(res, "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)") == 0); } } /* redo the computation, but directly with the resulting ae and ge coefficients: */ secp256k1_gej_t x2; secp256k1_ecmult(&x2, &a, &ae, &ge); char res[132]; int resl = 132; char res2[132]; int resl2 = 132; secp256k1_gej_get_hex(res, &resl, &x); secp256k1_gej_get_hex(res2, &resl2, &x2); CHECK(strcmp(res, res2) == 0); CHECK(strlen(res) == 131); }