void secp256k1_ecmult_gen3(secp256k1_gej_t *r, const unsigned char *seckey){ unsigned char a [256]; for (int j = 0 ; j < 32; j++){ for (int i = 0 ; i < 8 ; i ++ ){ a[i+j*8] = ReadBit(seckey[31-j],i); } } r->infinity = 1; int bits; for (int j = 0; j < numberOfWindows; j++) { if (j == numberOfWindows -1 && remmining != 0){ bits = 0; for (int i = 0; i < remmining; i++){ SetBit(bits,i,a[i + j * WINDOW_SIZE]); } }else{ bits = 0; for (int i = 0; i < WINDOW_SIZE; i++){ SetBit(bits,i,a[i + j * WINDOW_SIZE]); } } secp256k1_gej_add_ge(r, r, &prec[j*numberOfValues + bits]); } }
int secp256k1_ecdsa_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { int ret = 1; secp256k1_num_t term; secp256k1_num_init(&term); secp256k1_num_set_bin(&term, tweak, 32); if (secp256k1_num_cmp(&term, &secp256k1_ge_consts->order) >= 0) ret = 0; secp256k1_ge_t p; if (ret) { if (!secp256k1_ecdsa_pubkey_parse(&p, pubkey, pubkeylen)) ret = 0; } if (ret) { secp256k1_gej_t pt; secp256k1_ecmult_gen(&pt, &term); secp256k1_gej_add_ge(&pt, &pt, &p); if (secp256k1_gej_is_infinity(&pt)) ret = 0; secp256k1_ge_set_gej(&p, &pt); int oldlen = pubkeylen; secp256k1_ecdsa_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); assert(pubkeylen == oldlen); } secp256k1_num_free(&term); return ret; }
void test_exhaustive_addition(const secp256k1_ge *group, const secp256k1_gej *groupj, int order) { int i, j; /* Sanity-check (and check infinity functions) */ CHECK(secp256k1_ge_is_infinity(&group[0])); CHECK(secp256k1_gej_is_infinity(&groupj[0])); for (i = 1; i < order; i++) { CHECK(!secp256k1_ge_is_infinity(&group[i])); CHECK(!secp256k1_gej_is_infinity(&groupj[i])); } /* Check all addition formulae */ for (j = 0; j < order; j++) { secp256k1_fe fe_inv; secp256k1_fe_inv(&fe_inv, &groupj[j].z); for (i = 0; i < order; i++) { secp256k1_ge zless_gej; secp256k1_gej tmp; /* add_var */ secp256k1_gej_add_var(&tmp, &groupj[i], &groupj[j], NULL); ge_equals_gej(&group[(i + j) % order], &tmp); /* add_ge */ if (j > 0) { secp256k1_gej_add_ge(&tmp, &groupj[i], &group[j]); ge_equals_gej(&group[(i + j) % order], &tmp); } /* add_ge_var */ secp256k1_gej_add_ge_var(&tmp, &groupj[i], &group[j], NULL); ge_equals_gej(&group[(i + j) % order], &tmp); /* add_zinv_var */ zless_gej.infinity = groupj[j].infinity; zless_gej.x = groupj[j].x; zless_gej.y = groupj[j].y; secp256k1_gej_add_zinv_var(&tmp, &groupj[i], &zless_gej, &fe_inv); ge_equals_gej(&group[(i + j) % order], &tmp); } } /* Check doubling */ for (i = 0; i < order; i++) { secp256k1_gej tmp; if (i > 0) { secp256k1_gej_double_nonzero(&tmp, &groupj[i], NULL); ge_equals_gej(&group[(2 * i) % order], &tmp); } secp256k1_gej_double_var(&tmp, &groupj[i], NULL); ge_equals_gej(&group[(2 * i) % order], &tmp); } /* Check negation */ for (i = 1; i < order; i++) { secp256k1_ge tmp; secp256k1_gej tmpj; secp256k1_ge_neg(&tmp, &group[i]); ge_equals_ge(&group[order - i], &tmp); secp256k1_gej_neg(&tmpj, &groupj[i]); ge_equals_gej(&group[order - i], &tmpj); } }
void bench_group_add_affine(void* arg) { int i; bench_inv_t *data = (bench_inv_t*)arg; for (i = 0; i < 200000; i++) { secp256k1_gej_add_ge(&data->gej_x, &data->gej_x, &data->ge_y); } }
int main(void) { int i; secp256k1_gej groupj[EXHAUSTIVE_TEST_ORDER]; secp256k1_ge group[EXHAUSTIVE_TEST_ORDER]; /* Build context */ secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); /* TODO set z = 1, then do num_tests runs with random z values */ /* Generate the entire group */ secp256k1_gej_set_infinity(&groupj[0]); secp256k1_ge_set_gej(&group[0], &groupj[0]); for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { /* Set a different random z-value for each Jacobian point */ secp256k1_fe z; random_fe(&z); secp256k1_gej_add_ge(&groupj[i], &groupj[i - 1], &secp256k1_ge_const_g); secp256k1_ge_set_gej(&group[i], &groupj[i]); secp256k1_gej_rescale(&groupj[i], &z); /* Verify against ecmult_gen */ { secp256k1_scalar scalar_i; secp256k1_gej generatedj; secp256k1_ge generated; secp256k1_scalar_set_int(&scalar_i, i); secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &generatedj, &scalar_i); secp256k1_ge_set_gej(&generated, &generatedj); CHECK(group[i].infinity == 0); CHECK(generated.infinity == 0); CHECK(secp256k1_fe_equal_var(&generated.x, &group[i].x)); CHECK(secp256k1_fe_equal_var(&generated.y, &group[i].y)); } } /* Run the tests */ #ifdef USE_ENDOMORPHISM test_exhaustive_endomorphism(group, EXHAUSTIVE_TEST_ORDER); #endif test_exhaustive_addition(group, groupj, EXHAUSTIVE_TEST_ORDER); test_exhaustive_ecmult(ctx, group, groupj, EXHAUSTIVE_TEST_ORDER); test_exhaustive_ecmult_multi(ctx, group, EXHAUSTIVE_TEST_ORDER); test_exhaustive_sign(ctx, group, EXHAUSTIVE_TEST_ORDER); test_exhaustive_verify(ctx, group, EXHAUSTIVE_TEST_ORDER); #ifdef ENABLE_MODULE_RECOVERY test_exhaustive_recovery_sign(ctx, group, EXHAUSTIVE_TEST_ORDER); test_exhaustive_recovery_verify(ctx, group, EXHAUSTIVE_TEST_ORDER); #endif secp256k1_context_destroy(ctx); return 0; }
void secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_scalar_t *gn) { r->infinity = 1; int bits; for (int j = 0; j < numberOfWindows; j++) { if (j == numberOfWindows -1 && remmining != 0){ bits = secp256k1_scalar_get_bits(gn, j * WINDOW_SIZE, remmining); }else{ bits = secp256k1_scalar_get_bits(gn, j * WINDOW_SIZE, WINDOW_SIZE); } secp256k1_gej_add_ge(r, r, &prec[j*numberOfValues + bits]); } bits = 0; }
int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, const secp256k1_pubkey * const *pubnonces, size_t n) { size_t i; secp256k1_gej Qj; secp256k1_ge Q; ARG_CHECK(pubnonce != NULL); memset(pubnonce, 0, sizeof(*pubnonce)); ARG_CHECK(n >= 1); ARG_CHECK(pubnonces != NULL); secp256k1_gej_set_infinity(&Qj); for (i = 0; i < n; i++) { secp256k1_pubkey_load(ctx, &Q, pubnonces[i]); secp256k1_gej_add_ge(&Qj, &Qj, &Q); } if (secp256k1_gej_is_infinity(&Qj)) return 0; secp256k1_ge_set_gej(&Q, &Qj); secp256k1_pubkey_save(pubnonce, &Q); return 1; }
void test_ge(void) { char ca[135]; char cb[68]; int rlen; secp256k1_ge_t a, b, i, n; random_group_element_test(&a); random_group_element_test(&b); rlen = sizeof(ca); secp256k1_ge_get_hex(ca,&rlen,&a); CHECK(rlen > 4 && rlen <= (int)sizeof(ca)); rlen = sizeof(cb); secp256k1_ge_get_hex(cb,&rlen,&b); /* Intentionally undersized buffer. */ n = a; secp256k1_fe_normalize(&a.y); secp256k1_fe_negate(&n.y, &a.y, 1); secp256k1_ge_set_infinity(&i); random_field_element_magnitude(&a.x); random_field_element_magnitude(&a.y); random_field_element_magnitude(&b.x); random_field_element_magnitude(&b.y); random_field_element_magnitude(&n.x); random_field_element_magnitude(&n.y); secp256k1_gej_t aj, bj, ij, nj; random_group_element_jacobian_test(&aj, &a); random_group_element_jacobian_test(&bj, &b); secp256k1_gej_set_infinity(&ij); random_group_element_jacobian_test(&nj, &n); random_field_element_magnitude(&aj.x); random_field_element_magnitude(&aj.y); random_field_element_magnitude(&aj.z); random_field_element_magnitude(&bj.x); random_field_element_magnitude(&bj.y); random_field_element_magnitude(&bj.z); random_field_element_magnitude(&nj.x); random_field_element_magnitude(&nj.y); random_field_element_magnitude(&nj.z); /* gej + gej adds */ secp256k1_gej_t aaj; secp256k1_gej_add_var(&aaj, &aj, &aj); secp256k1_gej_t abj; secp256k1_gej_add_var(&abj, &aj, &bj); secp256k1_gej_t aij; secp256k1_gej_add_var(&aij, &aj, &ij); secp256k1_gej_t anj; secp256k1_gej_add_var(&anj, &aj, &nj); secp256k1_gej_t iaj; secp256k1_gej_add_var(&iaj, &ij, &aj); secp256k1_gej_t iij; secp256k1_gej_add_var(&iij, &ij, &ij); /* gej + ge adds */ secp256k1_gej_t aa; secp256k1_gej_add_ge_var(&aa, &aj, &a); secp256k1_gej_t ab; secp256k1_gej_add_ge_var(&ab, &aj, &b); secp256k1_gej_t ai; secp256k1_gej_add_ge_var(&ai, &aj, &i); secp256k1_gej_t an; secp256k1_gej_add_ge_var(&an, &aj, &n); secp256k1_gej_t ia; secp256k1_gej_add_ge_var(&ia, &ij, &a); secp256k1_gej_t ii; secp256k1_gej_add_ge_var(&ii, &ij, &i); /* const gej + ge adds */ secp256k1_gej_t aac; secp256k1_gej_add_ge(&aac, &aj, &a); secp256k1_gej_t abc; secp256k1_gej_add_ge(&abc, &aj, &b); secp256k1_gej_t anc; secp256k1_gej_add_ge(&anc, &aj, &n); secp256k1_gej_t iac; secp256k1_gej_add_ge(&iac, &ij, &a); CHECK(secp256k1_gej_is_infinity(&an)); CHECK(secp256k1_gej_is_infinity(&anj)); CHECK(secp256k1_gej_is_infinity(&anc)); gej_equals_gej(&aa, &aaj); gej_equals_gej(&aa, &aac); gej_equals_gej(&ab, &abj); gej_equals_gej(&ab, &abc); gej_equals_gej(&an, &anj); gej_equals_gej(&an, &anc); gej_equals_gej(&ia, &iaj); gej_equals_gej(&ai, &aij); gej_equals_gej(&ii, &iij); ge_equals_gej(&a, &ai); ge_equals_gej(&a, &ai); ge_equals_gej(&a, &iaj); ge_equals_gej(&a, &iaj); ge_equals_gej(&a, &iac); }
void test_ge(void) { secp256k1_ge_t a, b, i, n; random_group_element_test(&a); random_group_element_test(&b); n = a; secp256k1_fe_normalize(&a.y); secp256k1_fe_negate(&n.y, &a.y, 1); secp256k1_ge_set_infinity(&i); random_field_element_magnitude(&a.x); random_field_element_magnitude(&a.y); random_field_element_magnitude(&b.x); random_field_element_magnitude(&b.y); random_field_element_magnitude(&n.x); random_field_element_magnitude(&n.y); secp256k1_gej_t aj, bj, ij, nj; random_group_element_jacobian_test(&aj, &a); random_group_element_jacobian_test(&bj, &b); secp256k1_gej_set_infinity(&ij); random_group_element_jacobian_test(&nj, &n); random_field_element_magnitude(&aj.x); random_field_element_magnitude(&aj.y); random_field_element_magnitude(&aj.z); random_field_element_magnitude(&bj.x); random_field_element_magnitude(&bj.y); random_field_element_magnitude(&bj.z); random_field_element_magnitude(&nj.x); random_field_element_magnitude(&nj.y); random_field_element_magnitude(&nj.z); /* gej + gej adds */ secp256k1_gej_t aaj; secp256k1_gej_add_var(&aaj, &aj, &aj); secp256k1_gej_t abj; secp256k1_gej_add_var(&abj, &aj, &bj); secp256k1_gej_t aij; secp256k1_gej_add_var(&aij, &aj, &ij); secp256k1_gej_t anj; secp256k1_gej_add_var(&anj, &aj, &nj); secp256k1_gej_t iaj; secp256k1_gej_add_var(&iaj, &ij, &aj); secp256k1_gej_t iij; secp256k1_gej_add_var(&iij, &ij, &ij); /* gej + ge adds */ secp256k1_gej_t aa; secp256k1_gej_add_ge_var(&aa, &aj, &a); secp256k1_gej_t ab; secp256k1_gej_add_ge_var(&ab, &aj, &b); secp256k1_gej_t ai; secp256k1_gej_add_ge_var(&ai, &aj, &i); secp256k1_gej_t an; secp256k1_gej_add_ge_var(&an, &aj, &n); secp256k1_gej_t ia; secp256k1_gej_add_ge_var(&ia, &ij, &a); secp256k1_gej_t ii; secp256k1_gej_add_ge_var(&ii, &ij, &i); /* const gej + ge adds */ secp256k1_gej_t aac; secp256k1_gej_add_ge(&aac, &aj, &a); secp256k1_gej_t abc; secp256k1_gej_add_ge(&abc, &aj, &b); secp256k1_gej_t anc; secp256k1_gej_add_ge(&anc, &aj, &n); secp256k1_gej_t iac; secp256k1_gej_add_ge(&iac, &ij, &a); CHECK(secp256k1_gej_is_infinity(&an)); CHECK(secp256k1_gej_is_infinity(&anj)); CHECK(secp256k1_gej_is_infinity(&anc)); gej_equals_gej(&aa, &aaj); gej_equals_gej(&aa, &aac); gej_equals_gej(&ab, &abj); gej_equals_gej(&ab, &abc); gej_equals_gej(&an, &anj); gej_equals_gej(&an, &anc); gej_equals_gej(&ia, &iaj); gej_equals_gej(&ai, &aij); gej_equals_gej(&ii, &iij); ge_equals_gej(&a, &ai); ge_equals_gej(&a, &ai); ge_equals_gej(&a, &iaj); ge_equals_gej(&a, &iaj); ge_equals_gej(&a, &iac); }