Skip to content

Commit 20448b8

Browse files
committed
Remove unused Jacobi symbol support
No exposed functions rely on Jacobi symbol computation anymore. Remove it; it can always be brough back later if needed.
1 parent 5437e7b commit 20448b8

File tree

6 files changed

+11
-197
lines changed

6 files changed

+11
-197
lines changed

src/bench_internal.c

+4-44
Original file line numberDiff line numberDiff line change
@@ -246,35 +246,17 @@ void bench_group_add_affine_var(void* arg, int iters) {
246246
}
247247
}
248248

249-
void bench_group_jacobi_var(void* arg, int iters) {
250-
int i, j = 0;
251-
bench_inv *data = (bench_inv*)arg;
252-
253-
for (i = 0; i < iters; i++) {
254-
j += secp256k1_gej_has_quad_y_var(&data->gej[0]);
255-
/* Vary the Y and Z coordinates of the input (the X coordinate doesn't matter to
256-
secp256k1_gej_has_quad_y_var). Note that the resulting coordinates will
257-
generally not correspond to a point on the curve, but this is not a problem
258-
for the code being benchmarked here. Adding and normalizing have less
259-
overhead than EC operations (which could guarantee the point remains on the
260-
curve). */
261-
secp256k1_fe_add(&data->gej[0].y, &data->fe[1]);
262-
secp256k1_fe_add(&data->gej[0].z, &data->fe[2]);
263-
secp256k1_fe_normalize_var(&data->gej[0].y);
264-
secp256k1_fe_normalize_var(&data->gej[0].z);
265-
}
266-
CHECK(j <= iters);
267-
}
268-
269249
void bench_group_to_affine_var(void* arg, int iters) {
270250
int i;
271251
bench_inv *data = (bench_inv*)arg;
272252

273253
for (i = 0; i < iters; ++i) {
274254
secp256k1_ge_set_gej_var(&data->ge[1], &data->gej[0]);
275255
/* Use the output affine X/Y coordinates to vary the input X/Y/Z coordinates.
276-
Similar to bench_group_jacobi_var, this approach does not result in
277-
coordinates of points on the curve. */
256+
Note that the resulting coordinates will generally not correspond to a point
257+
on the curve, but this is not a problem for the code being benchmarked here.
258+
Adding and normalizing have less overhead than EC operations (which could
259+
guarantee the point remains on the curve). */
278260
secp256k1_fe_add(&data->gej[0].x, &data->ge[1].y);
279261
secp256k1_fe_add(&data->gej[0].y, &data->fe[2]);
280262
secp256k1_fe_add(&data->gej[0].z, &data->ge[1].x);
@@ -360,24 +342,6 @@ void bench_context_sign(void* arg, int iters) {
360342
}
361343
}
362344

363-
#ifndef USE_NUM_NONE
364-
void bench_num_jacobi(void* arg, int iters) {
365-
int i, j = 0;
366-
bench_inv *data = (bench_inv*)arg;
367-
secp256k1_num nx, na, norder;
368-
369-
secp256k1_scalar_get_num(&nx, &data->scalar[0]);
370-
secp256k1_scalar_order_get_num(&norder);
371-
secp256k1_scalar_get_num(&na, &data->scalar[1]);
372-
373-
for (i = 0; i < iters; i++) {
374-
j += secp256k1_num_jacobi(&nx, &norder);
375-
secp256k1_num_add(&nx, &nx, &na);
376-
}
377-
CHECK(j <= iters);
378-
}
379-
#endif
380-
381345
int main(int argc, char **argv) {
382346
bench_inv data;
383347
int iters = get_iters(20000);
@@ -401,7 +365,6 @@ int main(int argc, char **argv) {
401365
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, iters*10);
402366
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, iters*10);
403367
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, iters*10);
404-
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "jacobi")) run_benchmark("group_jacobi_var", bench_group_jacobi_var, bench_setup, NULL, &data, 10, iters);
405368
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "to_affine")) run_benchmark("group_to_affine_var", bench_group_to_affine_var, bench_setup, NULL, &data, 10, iters);
406369

407370
if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, iters);
@@ -414,8 +377,5 @@ int main(int argc, char **argv) {
414377
if (have_flag(argc, argv, "context") || have_flag(argc, argv, "verify")) run_benchmark("context_verify", bench_context_verify, bench_setup, NULL, &data, 10, 1 + iters/1000);
415378
if (have_flag(argc, argv, "context") || have_flag(argc, argv, "sign")) run_benchmark("context_sign", bench_context_sign, bench_setup, NULL, &data, 10, 1 + iters/100);
416379

417-
#ifndef USE_NUM_NONE
418-
if (have_flag(argc, argv, "num") || have_flag(argc, argv, "jacobi")) run_benchmark("num_jacobi", bench_num_jacobi, bench_setup, NULL, &data, 10, iters*10);
419-
#endif
420380
return 0;
421381
}

src/field.h

-3
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,6 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a);
104104
* itself. */
105105
static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a);
106106

107-
/** Checks whether a field element is a quadratic residue. */
108-
static int secp256k1_fe_is_quad_var(const secp256k1_fe *a);
109-
110107
/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be
111108
* at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */
112109
static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a);

src/field_impl.h

-25
Original file line numberDiff line numberDiff line change
@@ -136,31 +136,6 @@ static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) {
136136
return secp256k1_fe_equal(&t1, a);
137137
}
138138

139-
static int secp256k1_fe_is_quad_var(const secp256k1_fe *a) {
140-
#ifndef USE_NUM_NONE
141-
unsigned char b[32];
142-
secp256k1_num n;
143-
secp256k1_num m;
144-
/* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */
145-
static const unsigned char prime[32] = {
146-
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
147-
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
148-
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
149-
0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F
150-
};
151-
152-
secp256k1_fe c = *a;
153-
secp256k1_fe_normalize_var(&c);
154-
secp256k1_fe_get_b32(b, &c);
155-
secp256k1_num_set_bin(&n, b, 32);
156-
secp256k1_num_set_bin(&m, prime, 32);
157-
return secp256k1_num_jacobi(&n, &m) >= 0;
158-
#else
159-
secp256k1_fe r;
160-
return secp256k1_fe_sqrt(&r, a);
161-
#endif
162-
}
163-
164139
static const secp256k1_fe secp256k1_fe_one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1);
165140

166141
#endif /* SECP256K1_FIELD_IMPL_H */

src/group.h

-9
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,6 @@ typedef struct {
4343
/** Set a group element equal to the point with given X and Y coordinates */
4444
static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y);
4545

46-
/** Set a group element (affine) equal to the point with the given X coordinate
47-
* and a Y coordinate that is a quadratic residue modulo p. The return value
48-
* is true iff a coordinate with the given X coordinate exists.
49-
*/
50-
static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x);
51-
5246
/** Set a group element (affine) equal to the point with the given X coordinate, and given oddness
5347
* for Y. Return value indicates whether the result is valid. */
5448
static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd);
@@ -96,9 +90,6 @@ static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a);
9690
/** Check whether a group element is the point at infinity. */
9791
static int secp256k1_gej_is_infinity(const secp256k1_gej *a);
9892

99-
/** Check whether a group element's y coordinate is a quadratic residue. */
100-
static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a);
101-
10293
/** Set r equal to the double of a. Constant time. */
10394
static void secp256k1_gej_double(secp256k1_gej *r, const secp256k1_gej *a);
10495

src/group_impl.h

+2-20
Original file line numberDiff line numberDiff line change
@@ -207,18 +207,14 @@ static void secp256k1_ge_clear(secp256k1_ge *r) {
207207
secp256k1_fe_clear(&r->y);
208208
}
209209

210-
static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x) {
210+
static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd) {
211211
secp256k1_fe x2, x3;
212212
r->x = *x;
213213
secp256k1_fe_sqr(&x2, x);
214214
secp256k1_fe_mul(&x3, x, &x2);
215215
r->infinity = 0;
216216
secp256k1_fe_add(&x3, &secp256k1_fe_const_b);
217-
return secp256k1_fe_sqrt(&r->y, &x3);
218-
}
219-
220-
static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd) {
221-
if (!secp256k1_ge_set_xquad(r, x)) {
217+
if (!secp256k1_fe_sqrt(&r->y, &x3)) {
222218
return 0;
223219
}
224220
secp256k1_fe_normalize_var(&r->y);
@@ -655,20 +651,6 @@ static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a) {
655651
secp256k1_fe_mul(&r->x, &r->x, &beta);
656652
}
657653

658-
static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a) {
659-
secp256k1_fe yz;
660-
661-
if (a->infinity) {
662-
return 0;
663-
}
664-
665-
/* We rely on the fact that the Jacobi symbol of 1 / a->z^3 is the same as
666-
* that of a->z. Thus a->y / a->z^3 is a quadratic residue iff a->y * a->z
667-
is */
668-
secp256k1_fe_mul(&yz, &a->y, &a->z);
669-
return secp256k1_fe_is_quad_var(&yz);
670-
}
671-
672654
static int secp256k1_ge_is_in_correct_subgroup(const secp256k1_ge* ge) {
673655
#ifdef EXHAUSTIVE_TEST_ORDER
674656
secp256k1_gej out;

src/tests.c

+5-96
Original file line numberDiff line numberDiff line change
@@ -750,74 +750,12 @@ void test_num_mod(void) {
750750
CHECK(secp256k1_num_is_zero(&n));
751751
}
752752

753-
void test_num_jacobi(void) {
754-
secp256k1_scalar sqr;
755-
secp256k1_scalar small;
756-
secp256k1_scalar five; /* five is not a quadratic residue */
757-
secp256k1_num order, n;
758-
int i;
759-
/* squares mod 5 are 1, 4 */
760-
const int jacobi5[10] = { 0, 1, -1, -1, 1, 0, 1, -1, -1, 1 };
761-
762-
/* check some small values with 5 as the order */
763-
secp256k1_scalar_set_int(&five, 5);
764-
secp256k1_scalar_get_num(&order, &five);
765-
for (i = 0; i < 10; ++i) {
766-
secp256k1_scalar_set_int(&small, i);
767-
secp256k1_scalar_get_num(&n, &small);
768-
CHECK(secp256k1_num_jacobi(&n, &order) == jacobi5[i]);
769-
}
770-
771-
/** test large values with 5 as group order */
772-
secp256k1_scalar_get_num(&order, &five);
773-
/* we first need a scalar which is not a multiple of 5 */
774-
do {
775-
secp256k1_num fiven;
776-
random_scalar_order_test(&sqr);
777-
secp256k1_scalar_get_num(&fiven, &five);
778-
secp256k1_scalar_get_num(&n, &sqr);
779-
secp256k1_num_mod(&n, &fiven);
780-
} while (secp256k1_num_is_zero(&n));
781-
/* next force it to be a residue. 2 is a nonresidue mod 5 so we can
782-
* just multiply by two, i.e. add the number to itself */
783-
if (secp256k1_num_jacobi(&n, &order) == -1) {
784-
secp256k1_num_add(&n, &n, &n);
785-
}
786-
787-
/* test residue */
788-
CHECK(secp256k1_num_jacobi(&n, &order) == 1);
789-
/* test nonresidue */
790-
secp256k1_num_add(&n, &n, &n);
791-
CHECK(secp256k1_num_jacobi(&n, &order) == -1);
792-
793-
/** test with secp group order as order */
794-
secp256k1_scalar_order_get_num(&order);
795-
random_scalar_order_test(&sqr);
796-
secp256k1_scalar_mul(&sqr, &sqr, &sqr);
797-
/* test residue */
798-
secp256k1_scalar_get_num(&n, &sqr);
799-
CHECK(secp256k1_num_jacobi(&n, &order) == 1);
800-
/* test nonresidue */
801-
secp256k1_scalar_mul(&sqr, &sqr, &five);
802-
secp256k1_scalar_get_num(&n, &sqr);
803-
CHECK(secp256k1_num_jacobi(&n, &order) == -1);
804-
/* test multiple of the order*/
805-
CHECK(secp256k1_num_jacobi(&order, &order) == 0);
806-
807-
/* check one less than the order */
808-
secp256k1_scalar_set_int(&small, 1);
809-
secp256k1_scalar_get_num(&n, &small);
810-
secp256k1_num_sub(&n, &order, &n);
811-
CHECK(secp256k1_num_jacobi(&n, &order) == 1); /* sage confirms this is 1 */
812-
}
813-
814753
void run_num_smalltests(void) {
815754
int i;
816755
for (i = 0; i < 100*count; i++) {
817756
test_num_negate();
818757
test_num_add_sub();
819758
test_num_mod();
820-
test_num_jacobi();
821759
}
822760
}
823761
#endif
@@ -2959,64 +2897,35 @@ void run_ec_combine(void) {
29592897
void test_group_decompress(const secp256k1_fe* x) {
29602898
/* The input itself, normalized. */
29612899
secp256k1_fe fex = *x;
2962-
secp256k1_fe fez;
2963-
/* Results of set_xquad_var, set_xo_var(..., 0), set_xo_var(..., 1). */
2964-
secp256k1_ge ge_quad, ge_even, ge_odd;
2965-
secp256k1_gej gej_quad;
2900+
/* Results of set_xo_var(..., 0), set_xo_var(..., 1). */
2901+
secp256k1_ge ge_even, ge_odd;
29662902
/* Return values of the above calls. */
2967-
int res_quad, res_even, res_odd;
2903+
int res_even, res_odd;
29682904

29692905
secp256k1_fe_normalize_var(&fex);
29702906

2971-
res_quad = secp256k1_ge_set_xquad(&ge_quad, &fex);
29722907
res_even = secp256k1_ge_set_xo_var(&ge_even, &fex, 0);
29732908
res_odd = secp256k1_ge_set_xo_var(&ge_odd, &fex, 1);
29742909

2975-
CHECK(res_quad == res_even);
2976-
CHECK(res_quad == res_odd);
2910+
CHECK(res_even == res_odd);
29772911

2978-
if (res_quad) {
2979-
secp256k1_fe_normalize_var(&ge_quad.x);
2912+
if (res_even) {
29802913
secp256k1_fe_normalize_var(&ge_odd.x);
29812914
secp256k1_fe_normalize_var(&ge_even.x);
2982-
secp256k1_fe_normalize_var(&ge_quad.y);
29832915
secp256k1_fe_normalize_var(&ge_odd.y);
29842916
secp256k1_fe_normalize_var(&ge_even.y);
29852917

29862918
/* No infinity allowed. */
2987-
CHECK(!ge_quad.infinity);
29882919
CHECK(!ge_even.infinity);
29892920
CHECK(!ge_odd.infinity);
29902921

29912922
/* Check that the x coordinates check out. */
2992-
CHECK(secp256k1_fe_equal_var(&ge_quad.x, x));
29932923
CHECK(secp256k1_fe_equal_var(&ge_even.x, x));
29942924
CHECK(secp256k1_fe_equal_var(&ge_odd.x, x));
29952925

2996-
/* Check that the Y coordinate result in ge_quad is a square. */
2997-
CHECK(secp256k1_fe_is_quad_var(&ge_quad.y));
2998-
29992926
/* Check odd/even Y in ge_odd, ge_even. */
30002927
CHECK(secp256k1_fe_is_odd(&ge_odd.y));
30012928
CHECK(!secp256k1_fe_is_odd(&ge_even.y));
3002-
3003-
/* Check secp256k1_gej_has_quad_y_var. */
3004-
secp256k1_gej_set_ge(&gej_quad, &ge_quad);
3005-
CHECK(secp256k1_gej_has_quad_y_var(&gej_quad));
3006-
do {
3007-
random_fe_test(&fez);
3008-
} while (secp256k1_fe_is_zero(&fez));
3009-
secp256k1_gej_rescale(&gej_quad, &fez);
3010-
CHECK(secp256k1_gej_has_quad_y_var(&gej_quad));
3011-
secp256k1_gej_neg(&gej_quad, &gej_quad);
3012-
CHECK(!secp256k1_gej_has_quad_y_var(&gej_quad));
3013-
do {
3014-
random_fe_test(&fez);
3015-
} while (secp256k1_fe_is_zero(&fez));
3016-
secp256k1_gej_rescale(&gej_quad, &fez);
3017-
CHECK(!secp256k1_gej_has_quad_y_var(&gej_quad));
3018-
secp256k1_gej_neg(&gej_quad, &gej_quad);
3019-
CHECK(secp256k1_gej_has_quad_y_var(&gej_quad));
30202929
}
30212930
}
30222931

0 commit comments

Comments
 (0)