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); }
int secp256k1_ecdsa_privkey_tweak_mul(unsigned char *seckey, const unsigned char *tweak) { int ret = 1; secp256k1_num_t factor; secp256k1_num_init(&factor); secp256k1_num_set_bin(&factor, tweak, 32); if (secp256k1_num_is_zero(&factor)) ret = 0; if (secp256k1_num_cmp(&factor, &secp256k1_ge_consts->order) >= 0) ret = 0; secp256k1_num_t sec; secp256k1_num_init(&sec); if (ret) { secp256k1_num_set_bin(&sec, seckey, 32); secp256k1_num_mod_mul(&sec, &sec, &factor, &secp256k1_ge_consts->order); } if (ret) secp256k1_num_get_bin(seckey, 32, &sec); secp256k1_num_free(&sec); secp256k1_num_free(&factor); return ret; }