Skip to content

Commit 6d218a6

Browse files
committed
Test ecmult functions for all i*2^j for j=0..255 and odd i=1..255.
1 parent 1e5d50f commit 6d218a6

File tree

1 file changed

+77
-25
lines changed

1 file changed

+77
-25
lines changed

src/tests.c

+77-25
Original file line numberDiff line numberDiff line change
@@ -3690,37 +3690,89 @@ void run_wnaf(void) {
36903690
CHECK(secp256k1_scalar_is_zero(&n));
36913691
}
36923692

3693+
static int test_ecmult_accumulate_cb(secp256k1_scalar* sc, secp256k1_ge* pt, size_t idx, void* data) {
3694+
const secp256k1_scalar* indata = (const secp256k1_scalar*)data;
3695+
*sc = *indata;
3696+
*pt = secp256k1_ge_const_g;
3697+
CHECK(idx == 0);
3698+
return 1;
3699+
}
3700+
3701+
void test_ecmult_accumulate(secp256k1_sha256* acc, const secp256k1_scalar* x, secp256k1_scratch* scratch) {
3702+
/* Compute x*G in 6 different ways, serialize it uncompressed, and feed it into acc. */
3703+
secp256k1_gej rj1, rj2, rj3, rj4, rj5, rj6, gj, infj;
3704+
secp256k1_ge r;
3705+
const secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
3706+
unsigned char bytes[65];
3707+
size_t size = 65;
3708+
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
3709+
secp256k1_gej_set_infinity(&infj);
3710+
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rj1, x);
3711+
secp256k1_ecmult(&ctx->ecmult_ctx, &rj2, &gj, x, &zero);
3712+
secp256k1_ecmult(&ctx->ecmult_ctx, &rj3, &infj, &zero, x);
3713+
secp256k1_ecmult_multi_var(NULL, &ctx->ecmult_ctx, scratch, &rj4, x, NULL, NULL, 0);
3714+
secp256k1_ecmult_multi_var(NULL, &ctx->ecmult_ctx, scratch, &rj5, &zero, test_ecmult_accumulate_cb, (void*)x, 1);
3715+
secp256k1_ecmult_const(&rj6, &secp256k1_ge_const_g, x, 256);
3716+
secp256k1_ge_set_gej_var(&r, &rj1);
3717+
ge_equals_gej(&r, &rj2);
3718+
ge_equals_gej(&r, &rj3);
3719+
ge_equals_gej(&r, &rj4);
3720+
ge_equals_gej(&r, &rj5);
3721+
ge_equals_gej(&r, &rj6);
3722+
if (secp256k1_ge_is_infinity(&r)) {
3723+
/* Store infinity as 0x00 */
3724+
const unsigned char zerobyte[1] = {0};
3725+
secp256k1_sha256_write(acc, zerobyte, 1);
3726+
} else {
3727+
/* Store other points using their uncompressed serialization. */
3728+
secp256k1_eckey_pubkey_serialize(&r, bytes, &size, 0);
3729+
CHECK(size == 65);
3730+
secp256k1_sha256_write(acc, bytes, size);
3731+
}
3732+
}
3733+
36933734
void test_ecmult_constants(void) {
3694-
/* Test ecmult_gen() for [0..36) and [order-36..0). */
3735+
/* Test ecmult_gen for:
3736+
* - For i in 0..36:
3737+
* - Key i
3738+
* - Key -i
3739+
* - For i in 0..255:
3740+
* - For j in 1..255 (only odd values):
3741+
* - Key (j*2^i) mod order
3742+
*/
36953743
secp256k1_scalar x;
3696-
secp256k1_gej r;
3697-
secp256k1_ge ng;
3698-
int i;
3699-
int j;
3700-
secp256k1_ge_neg(&ng, &secp256k1_ge_const_g);
3701-
for (i = 0; i < 36; i++ ) {
3702-
secp256k1_scalar_set_int(&x, i);
3703-
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x);
3704-
for (j = 0; j < i; j++) {
3705-
if (j == i - 1) {
3706-
ge_equals_gej(&secp256k1_ge_const_g, &r);
3707-
}
3708-
secp256k1_gej_add_ge(&r, &r, &ng);
3709-
}
3710-
CHECK(secp256k1_gej_is_infinity(&r));
3711-
}
3712-
for (i = 1; i <= 36; i++ ) {
3744+
secp256k1_sha256 acc;
3745+
unsigned char b32[32];
3746+
int i, j;
3747+
secp256k1_scratch_space *scratch = secp256k1_scratch_space_create(ctx, 65536);
3748+
3749+
/* Expected hash of all the computed points; created with an independent
3750+
* implementation. */
3751+
static const unsigned char expected32[32] = {
3752+
0xe4, 0x71, 0x1b, 0x4d, 0x14, 0x1e, 0x68, 0x48,
3753+
0xb7, 0xaf, 0x47, 0x2b, 0x4c, 0xd2, 0x04, 0x14,
3754+
0x3a, 0x75, 0x87, 0x60, 0x1a, 0xf9, 0x63, 0x60,
3755+
0xd0, 0xcb, 0x1f, 0xaa, 0x85, 0x9a, 0xb7, 0xb4
3756+
};
3757+
secp256k1_sha256_initialize(&acc);
3758+
for (i = 0; i <= 36; ++i) {
37133759
secp256k1_scalar_set_int(&x, i);
3760+
test_ecmult_accumulate(&acc, &x, scratch);
37143761
secp256k1_scalar_negate(&x, &x);
3715-
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x);
3716-
for (j = 0; j < i; j++) {
3717-
if (j == i - 1) {
3718-
ge_equals_gej(&ng, &r);
3719-
}
3720-
secp256k1_gej_add_ge(&r, &r, &secp256k1_ge_const_g);
3762+
test_ecmult_accumulate(&acc, &x, scratch);
3763+
};
3764+
for (i = 0; i < 256; ++i) {
3765+
for (j = 1; j < 256; j += 2) {
3766+
int k;
3767+
secp256k1_scalar_set_int(&x, j);
3768+
for (k = 0; k < i; ++k) secp256k1_scalar_add(&x, &x, &x);
3769+
test_ecmult_accumulate(&acc, &x, scratch);
37213770
}
3722-
CHECK(secp256k1_gej_is_infinity(&r));
37233771
}
3772+
secp256k1_sha256_finalize(&acc, b32);
3773+
CHECK(secp256k1_memcmp_var(b32, expected32, 32) == 0);
3774+
3775+
secp256k1_scratch_space_destroy(ctx, scratch);
37243776
}
37253777

37263778
void run_ecmult_constants(void) {

0 commit comments

Comments
 (0)