Skip to content

Commit e2d35a9

Browse files
sipaFabcien
authored andcommitted
[SECP256K1] Add tests to exercise lambda split near bounds
Summary: Partial backport 5/11 of secp256k1 [[bitcoin-core/secp256k1#830 | PR830]]: bitcoin-core/secp256k1@9d2f2b4 Depends on D8040. Test Plan: ninja check-secp256k1 Reviewers: #bitcoin_abc, deadalnix Reviewed By: #bitcoin_abc, deadalnix Differential Revision: https://reviews.bitcoinabc.org/D8041
1 parent 51e4185 commit e2d35a9

File tree

1 file changed

+94
-5
lines changed

1 file changed

+94
-5
lines changed

src/secp256k1/src/tests.c

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

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

35533634
#ifdef USE_ENDOMORPHISM
35543635
/***** ENDOMORPHISH TESTS *****/
3555-
void test_scalar_split(void) {
3556-
secp256k1_scalar full;
3636+
void test_scalar_split(const secp256k1_scalar* full) {
35573637
secp256k1_scalar s1, slam;
35583638
const unsigned char zero[32] = {0};
35593639
unsigned char tmp[32];
35603640

3561-
random_scalar_order_test(&full);
3562-
secp256k1_scalar_split_lambda(&s1, &slam, &full);
3641+
secp256k1_scalar_split_lambda(&s1, &slam, full);
35633642

35643643
/* check that both are <= 128 bits in size */
35653644
if (secp256k1_scalar_is_high(&s1)) {
@@ -3575,8 +3654,17 @@ void test_scalar_split(void) {
35753654
CHECK(secp256k1_memcmp_var(zero, tmp, 16) == 0);
35763655
}
35773656

3657+
35783658
void run_endomorphism_tests(void) {
3579-
test_scalar_split();
3659+
unsigned i;
3660+
for (i = 0; i < 100U * count; ++i) {
3661+
secp256k1_scalar full;
3662+
random_scalar_order_test(&full);
3663+
test_scalar_split(&full);
3664+
}
3665+
for (i = 0; i < sizeof(scalars_near_split_bounds) / sizeof(scalars_near_split_bounds[0]); ++i) {
3666+
test_scalar_split(&scalars_near_split_bounds[i]);
3667+
}
35803668
}
35813669
#endif
35823670

@@ -5596,6 +5684,7 @@ int main(int argc, char **argv) {
55965684
/* ecmult tests */
55975685
run_wnaf();
55985686
run_point_times_order();
5687+
run_ecmult_near_split_bound();
55995688
run_ecmult_chain();
56005689
run_ecmult_constants();
56015690
run_ecmult_gen_blind();

0 commit comments

Comments
 (0)