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 precomputeTable(int window_size){ secp256k1_gej_t gj; // base point in jacobian coordinates secp256k1_gej_t *table; WINDOW_SIZE = window_size; numberOfValues = (int) pow(2.0,window_size); if (256 % window_size == 0){ numberOfWindows = (256 / window_size); }else{ numberOfWindows = (256 / window_size) + 1; } remmining = 256 % window_size; table = (secp256k1_gej_t *)malloc(numberOfWindows*numberOfValues*sizeof(secp256k1_gej_t)); prec = (secp256k1_ge_t *)malloc(numberOfWindows*numberOfValues*sizeof(secp256k1_ge_t)); secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); printf("%d %d %d %d\n",window_size,numberOfWindows,numberOfValues,remmining); secp256k1_ge_const_g; { static const unsigned char nums_b32[33] = "The scalar for this x is unknown"; secp256k1_fe_t nums_x; secp256k1_ge_t nums_ge; VERIFY_CHECK(secp256k1_fe_set_b32(&nums_x, nums_b32)); VERIFY_CHECK(secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0)); secp256k1_gej_set_ge(&nums_gej, &nums_ge); /* Add G to make the bits in x uniformly distributed. */ secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g, NULL); } secp256k1_gej_t gbase; secp256k1_gej_t numsbase; gbase = gj; /* (2^w_size)^num_of_windows * G */ numsbase = nums_gej; /* 2^num_of_windows * nums. */ for (int j = 0; j < numberOfWindows; j++) { //[number of windows][each value from 0 - (2^window_size - 1)] table[j*numberOfValues] = numsbase; for (int i = 1; i < numberOfValues; i++) { secp256k1_gej_add_var(&table[j*numberOfValues + i], &table[j*numberOfValues + i - 1], &gbase, NULL); } for (int i = 0; i < window_size; i++) { secp256k1_gej_double_var(&gbase, &gbase, NULL); } /* Multiply numbase by 2. */ secp256k1_gej_double_var(&numsbase, &numsbase, NULL); if (j == numberOfWindows-2) { /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ secp256k1_gej_neg(&numsbase, &numsbase); secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL); } } secp256k1_ge_set_all_gej_var(numberOfWindows*numberOfValues, prec, table, 0); printf(""); free(table); }