Skip to content

Commit

Permalink
Merge #286: shallue_van_de_woestijne rewrite
Browse files Browse the repository at this point in the history
6b9d335 generator: add shallue_van_de_woestijne test for t = 0 (Jonas Nick)
2652224 generators: shallue_van_de_woestijne improve comments (Jonas Nick)
5d87e80 shallue_van_de_woestijne rewrite (Russell O'Connor)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 6b9d335
  jonasnick:
    ACK 6b9d335

Tree-SHA512: 4a5ca291ec760ea54a43ff0b811ca1fac024002172d4639919fb97f63cfa0e75a580674c86a5a0ac9866e00520be4dd8d1d37b6d2fd8d2057e42a804dbf9127c
  • Loading branch information
jonasnick committed Jan 25, 2024
2 parents b5a6812 + 6b9d335 commit 03aecaf
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 42 deletions.
93 changes: 55 additions & 38 deletions src/modules/generator/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,61 +107,78 @@ static void shallue_van_de_woestijne(secp256k1_ge* ge, const secp256k1_fe* t) {
x2 = -(x1 + 1)
x3 = 1 + 1/w^2
To avoid the 2 divisions, compute the above in numerator/denominator form:
wn = c * t
wd = 1 + 7 + t^2
x1n = d*wd - t*wn
x1d = wd
x2n = -(x1n + wd)
x2d = wd
x3n = wd^2 + c^2 * t^2
x3d = (c * t)^2
The joint denominator j = wd * c^2 * t^2, and
1 / x1d = 1/j * c^2 * t^2
1 / x2d = x3d = 1/j * wd
To avoid the 2 divisions, compute the joint denominator j = wd * x3d, where
wd = 1 + b + t^2
x3d = c^2 * t^2 = -3 * t^2
so that if j != 0, then
1 / wd = 1/j * x3d
1 / x3d = 1/j * wd
x1 = d - c * t^2 * x3d / j
x3 = 1 + wd^3 / j
If j = 0, the function outputs the point (d, f(d)). This point is equal
to (x1, f(x1)) as defined above if division by 0 is defined to be 0. In
below code this is not special-cased because secp256k1_fe_inv returns 0
on input 0.
j = 0 happens only when t = 0 (since wd != 0 as -8 is not a square).
*/

static const secp256k1_fe c = SECP256K1_FE_CONST(0x0a2d2ba9, 0x3507f1df, 0x233770c2, 0xa797962c, 0xc61f6d15, 0xda14ecd4, 0x7d8d27ae, 0x1cd5f852);
static const secp256k1_fe negc = SECP256K1_FE_CONST(0xf5d2d456, 0xcaf80e20, 0xdcc88f3d, 0x586869d3, 0x39e092ea, 0x25eb132b, 0x8272d850, 0xe32a03dd);
static const secp256k1_fe d = SECP256K1_FE_CONST(0x851695d4, 0x9a83f8ef, 0x919bb861, 0x53cbcb16, 0x630fb68a, 0xed0a766a, 0x3ec693d6, 0x8e6afa40);
static const secp256k1_fe b = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 7);
static const secp256k1_fe b_plus_one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 8);

secp256k1_fe wn, wd, x1n, x2n, x3n, x3d, jinv, tmp, x1, x2, x3, alphain, betain, gammain, y1, y2, y3;
secp256k1_fe wd, x3d, jinv, tmp, x1, x2, x3, alphain, betain, gammain, y1, y2, y3;
int alphaquad, betaquad;

secp256k1_fe_mul(&wn, &c, t); /* mag 1 */
/* wd = t^2 */
secp256k1_fe_sqr(&wd, t); /* mag 1 */
secp256k1_fe_add(&wd, &b_plus_one); /* mag 2 */
secp256k1_fe_mul(&tmp, t, &wn); /* mag 1 */
secp256k1_fe_negate(&tmp, &tmp, 1); /* mag 2 */
secp256k1_fe_mul(&x1n, &d, &wd); /* mag 1 */
secp256k1_fe_add(&x1n, &tmp); /* mag 3 */
x2n = x1n; /* mag 3 */
secp256k1_fe_add(&x2n, &wd); /* mag 5 */
secp256k1_fe_negate(&x2n, &x2n, 5); /* mag 6 */
secp256k1_fe_mul(&x3d, &c, t); /* mag 1 */
secp256k1_fe_sqr(&x3d, &x3d); /* mag 1 */
secp256k1_fe_sqr(&x3n, &wd); /* mag 1 */
secp256k1_fe_add(&x3n, &x3d); /* mag 2 */
secp256k1_fe_mul(&jinv, &x3d, &wd); /* mag 1 */
/* x1 = -c * t^2 */
secp256k1_fe_mul(&x1, &negc, &wd); /* mag 1 */
/* x3d = t^2 */
x3d = wd; /* mag 1 */
/* x3d = 3 * t^2 */
secp256k1_fe_mul_int(&x3d, 3); /* mag 3 */
/* x3d = -3 * t^2 */
secp256k1_fe_negate(&x3d, &x3d, 3); /* mag 4 */
/* wd = 1 + b + t^2 */
secp256k1_fe_add_int(&wd, SECP256K1_B + 1); /* mag 2 */
/* jinv = wd * x3d */
secp256k1_fe_mul(&jinv, &wd, &x3d); /* mag 1 */
/* jinv = 1/(wd * x3d) */
secp256k1_fe_inv(&jinv, &jinv); /* mag 1 */
secp256k1_fe_mul(&x1, &x1n, &x3d); /* mag 1 */
/* x1 = -c * t^2 * x3d */
secp256k1_fe_mul(&x1, &x1, &x3d); /* mag 1 */
/* x1 = -c * t^2 * x3d * 1/j */
secp256k1_fe_mul(&x1, &x1, &jinv); /* mag 1 */
secp256k1_fe_mul(&x2, &x2n, &x3d); /* mag 1 */
secp256k1_fe_mul(&x2, &x2, &jinv); /* mag 1 */
secp256k1_fe_mul(&x3, &x3n, &wd); /* mag 1 */
/* x1 = d + -c * t^2 * x3d * 1/j */
secp256k1_fe_add(&x1, &d); /* mag 2 */
/* x2 = x1 */
x2 = x1; /* mag 2 */
/* x2 = x1 + 1 */
secp256k1_fe_add_int(&x2, 1); /* mag 3 */
/* x2 = - (x1 + 1) */
secp256k1_fe_negate(&x2, &x2, 3); /* mag 4 */
/* x3 = wd^2 */
secp256k1_fe_sqr(&x3, &wd); /* mag 1 */
/* x3 = wd^3 */
secp256k1_fe_mul(&x3, &x3, &wd); /* mag 1 */
/* x3 = wd^3 * 1/j */
secp256k1_fe_mul(&x3, &x3, &jinv); /* mag 1 */
/* x3 = 1 + (wd^3 * 1/j) */
secp256k1_fe_add_int(&x3, 1); /* mag 2 */

secp256k1_fe_sqr(&alphain, &x1); /* mag 1 */
secp256k1_fe_mul(&alphain, &alphain, &x1); /* mag 1 */
secp256k1_fe_add(&alphain, &b); /* mag 2 */
secp256k1_fe_add_int(&alphain, SECP256K1_B); /* mag 2 */
secp256k1_fe_sqr(&betain, &x2); /* mag 1 */
secp256k1_fe_mul(&betain, &betain, &x2); /* mag 1 */
secp256k1_fe_add(&betain, &b); /* mag 2 */
secp256k1_fe_add_int(&betain, SECP256K1_B); /* mag 2 */
secp256k1_fe_sqr(&gammain, &x3); /* mag 1 */
secp256k1_fe_mul(&gammain, &gammain, &x3); /* mag 1 */
secp256k1_fe_add(&gammain, &b); /* mag 2 */
secp256k1_fe_add_int(&gammain, SECP256K1_B); /* mag 2 */

alphaquad = secp256k1_fe_sqrt(&y1, &alphain);
betaquad = secp256k1_fe_sqrt(&y2, &betain);
Expand Down
10 changes: 6 additions & 4 deletions src/modules/generator/tests_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ static void test_generator_api(void) {

static void test_shallue_van_de_woestijne(void) {
/* Matches with the output of the shallue_van_de_woestijne.sage SAGE program */
static const secp256k1_ge_storage results[32] = {
static const secp256k1_ge_storage results[34] = {
SECP256K1_GE_STORAGE_CONST(0x851695d4, 0x9a83f8ef, 0x919bb861, 0x53cbcb16, 0x630fb68a, 0xed0a766a, 0x3ec693d6, 0x8e6afa40, 0x4218f20a, 0xe6c646b3, 0x63db6860, 0x5822fb14, 0x264ca8d2, 0x587fdd6f, 0xbc750d58, 0x7e76a7ee),
SECP256K1_GE_STORAGE_CONST(0x851695d4, 0x9a83f8ef, 0x919bb861, 0x53cbcb16, 0x630fb68a, 0xed0a766a, 0x3ec693d6, 0x8e6afa40, 0x4218f20a, 0xe6c646b3, 0x63db6860, 0x5822fb14, 0x264ca8d2, 0x587fdd6f, 0xbc750d58, 0x7e76a7ee),
SECP256K1_GE_STORAGE_CONST(0xedd1fd3e, 0x327ce90c, 0xc7a35426, 0x14289aee, 0x9682003e, 0x9cf7dcc9, 0xcf2ca974, 0x3be5aa0c, 0x0225f529, 0xee75acaf, 0xccfc4560, 0x26c5e46b, 0xf80237a3, 0x3924655a, 0x16f90e88, 0x085ed52a),
SECP256K1_GE_STORAGE_CONST(0xedd1fd3e, 0x327ce90c, 0xc7a35426, 0x14289aee, 0x9682003e, 0x9cf7dcc9, 0xcf2ca974, 0x3be5aa0c, 0xfdda0ad6, 0x118a5350, 0x3303ba9f, 0xd93a1b94, 0x07fdc85c, 0xc6db9aa5, 0xe906f176, 0xf7a12705),
SECP256K1_GE_STORAGE_CONST(0x2c5cdc9c, 0x338152fa, 0x85de92cb, 0x1bee9907, 0x765a922e, 0x4f037cce, 0x14ecdbf2, 0x2f78fe15, 0x56716069, 0x6818286b, 0x72f01a3e, 0x5e8caca7, 0x36249160, 0xc7ded69d, 0xd51913c3, 0x03a2fa97),
Expand Down Expand Up @@ -87,7 +89,7 @@ static void test_shallue_van_de_woestijne(void) {
secp256k1_fe fe;
secp256k1_ge_storage ges;
int i, s;
for (i = 1; i <= 16; i++) {
for (i = 0; i <= 16; i++) {
secp256k1_fe_set_int(&fe, i);

for (s = 0; s < 2; s++) {
Expand All @@ -96,9 +98,9 @@ static void test_shallue_van_de_woestijne(void) {
secp256k1_fe_normalize(&fe);
}
shallue_van_de_woestijne(&ge, &fe);
CHECK(secp256k1_ge_is_valid_var(&ge));
secp256k1_ge_to_storage(&ges, &ge);

CHECK(secp256k1_memcmp_var(&ges, &results[i * 2 + s - 2], sizeof(secp256k1_ge_storage)) == 0);
CHECK(secp256k1_memcmp_var(&ges, &results[i * 2 + s], sizeof(secp256k1_ge_storage)) == 0);
}
}
}
Expand Down

0 comments on commit 03aecaf

Please sign in to comment.