Skip to content

Commit 341196c

Browse files
siparoconnor-blockstream
authored andcommitted
Add tests to exercise lambda split near bounds
1 parent bff7fff commit 341196c

File tree

1 file changed

+94
-5
lines changed

1 file changed

+94
-5
lines changed

src/tests.c

Lines changed: 94 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2634,6 +2634,87 @@ void test_point_times_order(const secp256k1_gej *point) {
26342634
ge_equals_ge(&res3, &secp256k1_ge_const_g);
26352635
}
26362636

2637+
/* These scalars reach large (in absolute value) outputs when fed to secp256k1_scalar_split_lambda.
2638+
*
2639+
* They are computed as:
2640+
* - For a in [-2, -1, 0, 1, 2]:
2641+
* - For b in [-3, -1, 1, 3]:
2642+
* - Output (a*LAMBDA + (ORDER+b)/2) % ORDER
2643+
*/
2644+
static const secp256k1_scalar scalars_near_split_bounds[20] = {
2645+
SECP256K1_SCALAR_CONST(0xd938a566, 0x7f479e3e, 0xb5b3c7fa, 0xefdb3749, 0x3aa0585c, 0xc5ea2367, 0xe1b660db, 0x0209e6fc),
2646+
SECP256K1_SCALAR_CONST(0xd938a566, 0x7f479e3e, 0xb5b3c7fa, 0xefdb3749, 0x3aa0585c, 0xc5ea2367, 0xe1b660db, 0x0209e6fd),
2647+
SECP256K1_SCALAR_CONST(0xd938a566, 0x7f479e3e, 0xb5b3c7fa, 0xefdb3749, 0x3aa0585c, 0xc5ea2367, 0xe1b660db, 0x0209e6fe),
2648+
SECP256K1_SCALAR_CONST(0xd938a566, 0x7f479e3e, 0xb5b3c7fa, 0xefdb3749, 0x3aa0585c, 0xc5ea2367, 0xe1b660db, 0x0209e6ff),
2649+
SECP256K1_SCALAR_CONST(0x2c9c52b3, 0x3fa3cf1f, 0x5ad9e3fd, 0x77ed9ba5, 0xb294b893, 0x3722e9a5, 0x00e698ca, 0x4cf7632d),
2650+
SECP256K1_SCALAR_CONST(0x2c9c52b3, 0x3fa3cf1f, 0x5ad9e3fd, 0x77ed9ba5, 0xb294b893, 0x3722e9a5, 0x00e698ca, 0x4cf7632e),
2651+
SECP256K1_SCALAR_CONST(0x2c9c52b3, 0x3fa3cf1f, 0x5ad9e3fd, 0x77ed9ba5, 0xb294b893, 0x3722e9a5, 0x00e698ca, 0x4cf7632f),
2652+
SECP256K1_SCALAR_CONST(0x2c9c52b3, 0x3fa3cf1f, 0x5ad9e3fd, 0x77ed9ba5, 0xb294b893, 0x3722e9a5, 0x00e698ca, 0x4cf76330),
2653+
SECP256K1_SCALAR_CONST(0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xd576e735, 0x57a4501d, 0xdfe92f46, 0x681b209f),
2654+
SECP256K1_SCALAR_CONST(0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xd576e735, 0x57a4501d, 0xdfe92f46, 0x681b20a0),
2655+
SECP256K1_SCALAR_CONST(0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xd576e735, 0x57a4501d, 0xdfe92f46, 0x681b20a1),
2656+
SECP256K1_SCALAR_CONST(0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xd576e735, 0x57a4501d, 0xdfe92f46, 0x681b20a2),
2657+
SECP256K1_SCALAR_CONST(0xd363ad4c, 0xc05c30e0, 0xa5261c02, 0x88126459, 0xf85915d7, 0x7825b696, 0xbeebc5c2, 0x833ede11),
2658+
SECP256K1_SCALAR_CONST(0xd363ad4c, 0xc05c30e0, 0xa5261c02, 0x88126459, 0xf85915d7, 0x7825b696, 0xbeebc5c2, 0x833ede12),
2659+
SECP256K1_SCALAR_CONST(0xd363ad4c, 0xc05c30e0, 0xa5261c02, 0x88126459, 0xf85915d7, 0x7825b696, 0xbeebc5c2, 0x833ede13),
2660+
SECP256K1_SCALAR_CONST(0xd363ad4c, 0xc05c30e0, 0xa5261c02, 0x88126459, 0xf85915d7, 0x7825b696, 0xbeebc5c2, 0x833ede14),
2661+
SECP256K1_SCALAR_CONST(0x26c75a99, 0x80b861c1, 0x4a4c3805, 0x1024c8b4, 0x704d760e, 0xe95e7cd3, 0xde1bfdb1, 0xce2c5a42),
2662+
SECP256K1_SCALAR_CONST(0x26c75a99, 0x80b861c1, 0x4a4c3805, 0x1024c8b4, 0x704d760e, 0xe95e7cd3, 0xde1bfdb1, 0xce2c5a43),
2663+
SECP256K1_SCALAR_CONST(0x26c75a99, 0x80b861c1, 0x4a4c3805, 0x1024c8b4, 0x704d760e, 0xe95e7cd3, 0xde1bfdb1, 0xce2c5a44),
2664+
SECP256K1_SCALAR_CONST(0x26c75a99, 0x80b861c1, 0x4a4c3805, 0x1024c8b4, 0x704d760e, 0xe95e7cd3, 0xde1bfdb1, 0xce2c5a45)
2665+
};
2666+
2667+
void test_ecmult_target(const secp256k1_scalar* target, int mode) {
2668+
/* Mode: 0=ecmult_gen, 1=ecmult, 2=ecmult_const */
2669+
secp256k1_scalar n1, n2;
2670+
secp256k1_ge p;
2671+
secp256k1_gej pj, p1j, p2j, ptj;
2672+
static const secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
2673+
2674+
/* Generate random n1,n2 such that n1+n2 = -target. */
2675+
random_scalar_order_test(&n1);
2676+
secp256k1_scalar_add(&n2, &n1, target);
2677+
secp256k1_scalar_negate(&n2, &n2);
2678+
2679+
/* Generate a random input point. */
2680+
if (mode != 0) {
2681+
random_group_element_test(&p);
2682+
secp256k1_gej_set_ge(&pj, &p);
2683+
}
2684+
2685+
/* EC multiplications */
2686+
if (mode == 0) {
2687+
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &p1j, &n1);
2688+
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &p2j, &n2);
2689+
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &ptj, target);
2690+
} else if (mode == 1) {
2691+
secp256k1_ecmult(&ctx->ecmult_ctx, &p1j, &pj, &n1, &zero);
2692+
secp256k1_ecmult(&ctx->ecmult_ctx, &p2j, &pj, &n2, &zero);
2693+
secp256k1_ecmult(&ctx->ecmult_ctx, &ptj, &pj, target, &zero);
2694+
} else {
2695+
secp256k1_ecmult_const(&p1j, &p, &n1, 256);
2696+
secp256k1_ecmult_const(&p2j, &p, &n2, 256);
2697+
secp256k1_ecmult_const(&ptj, &p, target, 256);
2698+
}
2699+
2700+
/* Add them all up: n1*P + n2*P + target*P = (n1+n2+target)*P = (n1+n1-n1-n2)*P = 0. */
2701+
secp256k1_gej_add_var(&ptj, &ptj, &p1j, NULL);
2702+
secp256k1_gej_add_var(&ptj, &ptj, &p2j, NULL);
2703+
CHECK(secp256k1_gej_is_infinity(&ptj));
2704+
}
2705+
2706+
void run_ecmult_near_split_bound(void) {
2707+
int i;
2708+
unsigned j;
2709+
for (i = 0; i < 4*count; ++i) {
2710+
for (j = 0; j < sizeof(scalars_near_split_bounds) / sizeof(scalars_near_split_bounds[0]); ++j) {
2711+
test_ecmult_target(&scalars_near_split_bounds[j], 0);
2712+
test_ecmult_target(&scalars_near_split_bounds[j], 1);
2713+
test_ecmult_target(&scalars_near_split_bounds[j], 2);
2714+
}
2715+
}
2716+
}
2717+
26372718
void run_point_times_order(void) {
26382719
int i;
26392720
secp256k1_fe x = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 2);
@@ -3555,14 +3636,12 @@ void run_ecmult_gen_blind(void) {
35553636

35563637
#ifdef USE_ENDOMORPHISM
35573638
/***** ENDOMORPHISH TESTS *****/
3558-
void test_scalar_split(void) {
3559-
secp256k1_scalar full;
3639+
void test_scalar_split(const secp256k1_scalar* full) {
35603640
secp256k1_scalar s1, slam;
35613641
const unsigned char zero[32] = {0};
35623642
unsigned char tmp[32];
35633643

3564-
random_scalar_order_test(&full);
3565-
secp256k1_scalar_split_lambda(&s1, &slam, &full);
3644+
secp256k1_scalar_split_lambda(&s1, &slam, full);
35663645

35673646
/* check that both are <= 128 bits in size */
35683647
if (secp256k1_scalar_is_high(&s1)) {
@@ -3578,8 +3657,17 @@ void test_scalar_split(void) {
35783657
CHECK(memcmp(zero, tmp, 16) == 0);
35793658
}
35803659

3660+
35813661
void run_endomorphism_tests(void) {
3582-
test_scalar_split();
3662+
unsigned i;
3663+
for (i = 0; i < 100U * count; ++i) {
3664+
secp256k1_scalar full;
3665+
random_scalar_order_test(&full);
3666+
test_scalar_split(&full);
3667+
}
3668+
for (i = 0; i < sizeof(scalars_near_split_bounds) / sizeof(scalars_near_split_bounds[0]); ++i) {
3669+
test_scalar_split(&scalars_near_split_bounds[i]);
3670+
}
35833671
}
35843672
#endif
35853673

@@ -5626,6 +5714,7 @@ int main(int argc, char **argv) {
56265714
/* ecmult tests */
56275715
run_wnaf();
56285716
run_point_times_order();
5717+
run_ecmult_near_split_bound();
56295718
run_ecmult_chain();
56305719
run_ecmult_constants();
56315720
run_ecmult_gen_blind();

0 commit comments

Comments
 (0)