Skip to content

Commit 03aecaf

Browse files
committed
Merge #286: shallue_van_de_woestijne rewrite
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
2 parents b5a6812 + 6b9d335 commit 03aecaf

File tree

2 files changed

+61
-42
lines changed

2 files changed

+61
-42
lines changed

src/modules/generator/main_impl.h

+55-38
Original file line numberDiff line numberDiff line change
@@ -107,61 +107,78 @@ static void shallue_van_de_woestijne(secp256k1_ge* ge, const secp256k1_fe* t) {
107107
x2 = -(x1 + 1)
108108
x3 = 1 + 1/w^2
109109
110-
To avoid the 2 divisions, compute the above in numerator/denominator form:
111-
wn = c * t
112-
wd = 1 + 7 + t^2
113-
x1n = d*wd - t*wn
114-
x1d = wd
115-
x2n = -(x1n + wd)
116-
x2d = wd
117-
x3n = wd^2 + c^2 * t^2
118-
x3d = (c * t)^2
119-
120-
The joint denominator j = wd * c^2 * t^2, and
121-
1 / x1d = 1/j * c^2 * t^2
122-
1 / x2d = x3d = 1/j * wd
110+
To avoid the 2 divisions, compute the joint denominator j = wd * x3d, where
111+
wd = 1 + b + t^2
112+
x3d = c^2 * t^2 = -3 * t^2
113+
114+
so that if j != 0, then
115+
116+
1 / wd = 1/j * x3d
117+
1 / x3d = 1/j * wd
118+
119+
x1 = d - c * t^2 * x3d / j
120+
x3 = 1 + wd^3 / j
121+
122+
If j = 0, the function outputs the point (d, f(d)). This point is equal
123+
to (x1, f(x1)) as defined above if division by 0 is defined to be 0. In
124+
below code this is not special-cased because secp256k1_fe_inv returns 0
125+
on input 0.
126+
127+
j = 0 happens only when t = 0 (since wd != 0 as -8 is not a square).
123128
*/
124129

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

130-
secp256k1_fe wn, wd, x1n, x2n, x3n, x3d, jinv, tmp, x1, x2, x3, alphain, betain, gammain, y1, y2, y3;
133+
secp256k1_fe wd, x3d, jinv, tmp, x1, x2, x3, alphain, betain, gammain, y1, y2, y3;
131134
int alphaquad, betaquad;
132135

133-
secp256k1_fe_mul(&wn, &c, t); /* mag 1 */
136+
/* wd = t^2 */
134137
secp256k1_fe_sqr(&wd, t); /* mag 1 */
135-
secp256k1_fe_add(&wd, &b_plus_one); /* mag 2 */
136-
secp256k1_fe_mul(&tmp, t, &wn); /* mag 1 */
137-
secp256k1_fe_negate(&tmp, &tmp, 1); /* mag 2 */
138-
secp256k1_fe_mul(&x1n, &d, &wd); /* mag 1 */
139-
secp256k1_fe_add(&x1n, &tmp); /* mag 3 */
140-
x2n = x1n; /* mag 3 */
141-
secp256k1_fe_add(&x2n, &wd); /* mag 5 */
142-
secp256k1_fe_negate(&x2n, &x2n, 5); /* mag 6 */
143-
secp256k1_fe_mul(&x3d, &c, t); /* mag 1 */
144-
secp256k1_fe_sqr(&x3d, &x3d); /* mag 1 */
145-
secp256k1_fe_sqr(&x3n, &wd); /* mag 1 */
146-
secp256k1_fe_add(&x3n, &x3d); /* mag 2 */
147-
secp256k1_fe_mul(&jinv, &x3d, &wd); /* mag 1 */
138+
/* x1 = -c * t^2 */
139+
secp256k1_fe_mul(&x1, &negc, &wd); /* mag 1 */
140+
/* x3d = t^2 */
141+
x3d = wd; /* mag 1 */
142+
/* x3d = 3 * t^2 */
143+
secp256k1_fe_mul_int(&x3d, 3); /* mag 3 */
144+
/* x3d = -3 * t^2 */
145+
secp256k1_fe_negate(&x3d, &x3d, 3); /* mag 4 */
146+
/* wd = 1 + b + t^2 */
147+
secp256k1_fe_add_int(&wd, SECP256K1_B + 1); /* mag 2 */
148+
/* jinv = wd * x3d */
149+
secp256k1_fe_mul(&jinv, &wd, &x3d); /* mag 1 */
150+
/* jinv = 1/(wd * x3d) */
148151
secp256k1_fe_inv(&jinv, &jinv); /* mag 1 */
149-
secp256k1_fe_mul(&x1, &x1n, &x3d); /* mag 1 */
152+
/* x1 = -c * t^2 * x3d */
153+
secp256k1_fe_mul(&x1, &x1, &x3d); /* mag 1 */
154+
/* x1 = -c * t^2 * x3d * 1/j */
150155
secp256k1_fe_mul(&x1, &x1, &jinv); /* mag 1 */
151-
secp256k1_fe_mul(&x2, &x2n, &x3d); /* mag 1 */
152-
secp256k1_fe_mul(&x2, &x2, &jinv); /* mag 1 */
153-
secp256k1_fe_mul(&x3, &x3n, &wd); /* mag 1 */
156+
/* x1 = d + -c * t^2 * x3d * 1/j */
157+
secp256k1_fe_add(&x1, &d); /* mag 2 */
158+
/* x2 = x1 */
159+
x2 = x1; /* mag 2 */
160+
/* x2 = x1 + 1 */
161+
secp256k1_fe_add_int(&x2, 1); /* mag 3 */
162+
/* x2 = - (x1 + 1) */
163+
secp256k1_fe_negate(&x2, &x2, 3); /* mag 4 */
164+
/* x3 = wd^2 */
165+
secp256k1_fe_sqr(&x3, &wd); /* mag 1 */
166+
/* x3 = wd^3 */
167+
secp256k1_fe_mul(&x3, &x3, &wd); /* mag 1 */
168+
/* x3 = wd^3 * 1/j */
154169
secp256k1_fe_mul(&x3, &x3, &jinv); /* mag 1 */
170+
/* x3 = 1 + (wd^3 * 1/j) */
171+
secp256k1_fe_add_int(&x3, 1); /* mag 2 */
155172

156173
secp256k1_fe_sqr(&alphain, &x1); /* mag 1 */
157174
secp256k1_fe_mul(&alphain, &alphain, &x1); /* mag 1 */
158-
secp256k1_fe_add(&alphain, &b); /* mag 2 */
175+
secp256k1_fe_add_int(&alphain, SECP256K1_B); /* mag 2 */
159176
secp256k1_fe_sqr(&betain, &x2); /* mag 1 */
160177
secp256k1_fe_mul(&betain, &betain, &x2); /* mag 1 */
161-
secp256k1_fe_add(&betain, &b); /* mag 2 */
178+
secp256k1_fe_add_int(&betain, SECP256K1_B); /* mag 2 */
162179
secp256k1_fe_sqr(&gammain, &x3); /* mag 1 */
163180
secp256k1_fe_mul(&gammain, &gammain, &x3); /* mag 1 */
164-
secp256k1_fe_add(&gammain, &b); /* mag 2 */
181+
secp256k1_fe_add_int(&gammain, SECP256K1_B); /* mag 2 */
165182

166183
alphaquad = secp256k1_fe_sqrt(&y1, &alphain);
167184
betaquad = secp256k1_fe_sqrt(&y2, &betain);

src/modules/generator/tests_impl.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ static void test_generator_api(void) {
4848

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

9395
for (s = 0; s < 2; s++) {
@@ -96,9 +98,9 @@ static void test_shallue_van_de_woestijne(void) {
9698
secp256k1_fe_normalize(&fe);
9799
}
98100
shallue_van_de_woestijne(&ge, &fe);
101+
CHECK(secp256k1_ge_is_valid_var(&ge));
99102
secp256k1_ge_to_storage(&ges, &ge);
100-
101-
CHECK(secp256k1_memcmp_var(&ges, &results[i * 2 + s - 2], sizeof(secp256k1_ge_storage)) == 0);
103+
CHECK(secp256k1_memcmp_var(&ges, &results[i * 2 + s], sizeof(secp256k1_ge_storage)) == 0);
102104
}
103105
}
104106
}

0 commit comments

Comments
 (0)