Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/tests.c
Show First 20 Lines • Show All 2,566 Lines • ▼ Show 20 Lines | |||||
void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi_func ecmult_multi) { | void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi_func ecmult_multi) { | ||||
int ncount; | int ncount; | ||||
secp256k1_scalar szero; | secp256k1_scalar szero; | ||||
secp256k1_scalar sc[32]; | secp256k1_scalar sc[32]; | ||||
secp256k1_ge pt[32]; | secp256k1_ge pt[32]; | ||||
secp256k1_gej r; | secp256k1_gej r; | ||||
secp256k1_gej r2; | secp256k1_gej r2; | ||||
ecmult_multi_data data; | ecmult_multi_data data; | ||||
secp256k1_scratch *scratch_empty; | |||||
data.sc = sc; | data.sc = sc; | ||||
data.pt = pt; | data.pt = pt; | ||||
secp256k1_scalar_set_int(&szero, 0); | secp256k1_scalar_set_int(&szero, 0); | ||||
/* No points to multiply */ | /* No points to multiply */ | ||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, NULL, ecmult_multi_callback, &data, 0)); | CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, NULL, ecmult_multi_callback, &data, 0)); | ||||
Show All 18 Lines | for (ncount = 0; ncount < count; ncount++) { | ||||
/* 1-point */ | /* 1-point */ | ||||
secp256k1_ecmult(&ctx->ecmult_ctx, &r2, &ptgj, &sc[0], &szero); | secp256k1_ecmult(&ctx->ecmult_ctx, &r2, &ptgj, &sc[0], &szero); | ||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, 1)); | CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, 1)); | ||||
secp256k1_gej_neg(&r2, &r2); | secp256k1_gej_neg(&r2, &r2); | ||||
secp256k1_gej_add_var(&r, &r, &r2, NULL); | secp256k1_gej_add_var(&r, &r, &r2, NULL); | ||||
CHECK(secp256k1_gej_is_infinity(&r)); | CHECK(secp256k1_gej_is_infinity(&r)); | ||||
/* Try to multiply 1 point, but scratch space is empty */ | |||||
scratch_empty = secp256k1_scratch_create(&ctx->error_callback, 0); | |||||
CHECK(!ecmult_multi(&ctx->ecmult_ctx, scratch_empty, &r, &szero, ecmult_multi_callback, &data, 1)); | |||||
secp256k1_scratch_destroy(scratch_empty); | |||||
/* Try to multiply 1 point, but callback returns false */ | /* Try to multiply 1 point, but callback returns false */ | ||||
CHECK(!ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_false_callback, &data, 1)); | CHECK(!ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_false_callback, &data, 1)); | ||||
/* 2-point */ | /* 2-point */ | ||||
secp256k1_ecmult(&ctx->ecmult_ctx, &r2, &ptgj, &sc[0], &sc[1]); | secp256k1_ecmult(&ctx->ecmult_ctx, &r2, &ptgj, &sc[0], &sc[1]); | ||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, 2)); | CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, 2)); | ||||
secp256k1_gej_neg(&r2, &r2); | secp256k1_gej_neg(&r2, &r2); | ||||
secp256k1_gej_add_var(&r, &r, &r2, NULL); | secp256k1_gej_add_var(&r, &r, &r2, NULL); | ||||
▲ Show 20 Lines • Show All 180 Lines • ▼ Show 20 Lines | /* Run through s0*(t0*P) + s1*(t1*P) exhaustively for many small values of s0, s1, t0, t1 */ | ||||
CHECK(secp256k1_gej_is_infinity(&actual)); | CHECK(secp256k1_gej_is_infinity(&actual)); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
void test_ecmult_multi_batch_single(secp256k1_ecmult_multi_func ecmult_multi) { | |||||
secp256k1_scalar szero; | |||||
secp256k1_scalar sc[32]; | |||||
secp256k1_ge pt[32]; | |||||
secp256k1_gej r; | |||||
ecmult_multi_data data; | |||||
secp256k1_scratch *scratch_empty; | |||||
data.sc = sc; | |||||
data.pt = pt; | |||||
secp256k1_scalar_set_int(&szero, 0); | |||||
/* Try to multiply 1 point, but scratch space is empty.*/ | |||||
scratch_empty = secp256k1_scratch_create(&ctx->error_callback, 0); | |||||
CHECK(!ecmult_multi(&ctx->ecmult_ctx, scratch_empty, &r, &szero, ecmult_multi_callback, &data, 1)); | |||||
secp256k1_scratch_destroy(scratch_empty); | |||||
} | |||||
void test_secp256k1_pippenger_bucket_window_inv(void) { | void test_secp256k1_pippenger_bucket_window_inv(void) { | ||||
int i; | int i; | ||||
CHECK(secp256k1_pippenger_bucket_window_inv(0) == 0); | CHECK(secp256k1_pippenger_bucket_window_inv(0) == 0); | ||||
for(i = 1; i <= PIPPENGER_MAX_BUCKET_WINDOW; i++) { | for(i = 1; i <= PIPPENGER_MAX_BUCKET_WINDOW; i++) { | ||||
#ifdef USE_ENDOMORPHISM | #ifdef USE_ENDOMORPHISM | ||||
/* Bucket_window of 8 is not used with endo */ | /* Bucket_window of 8 is not used with endo */ | ||||
if (i == 8) { | if (i == 8) { | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | for(i = 0; i < n_points; i++) { | ||||
secp256k1_gej_set_ge(&ptgj, &ptg); | secp256k1_gej_set_ge(&ptgj, &ptg); | ||||
pt[i] = ptg; | pt[i] = ptg; | ||||
random_scalar_order(&sc[i]); | random_scalar_order(&sc[i]); | ||||
secp256k1_ecmult(&ctx->ecmult_ctx, &ptgj, &ptgj, &sc[i], NULL); | secp256k1_ecmult(&ctx->ecmult_ctx, &ptgj, &ptgj, &sc[i], NULL); | ||||
secp256k1_gej_add_var(&r2, &r2, &ptgj, NULL); | secp256k1_gej_add_var(&r2, &r2, &ptgj, NULL); | ||||
} | } | ||||
data.sc = sc; | data.sc = sc; | ||||
data.pt = pt; | data.pt = pt; | ||||
secp256k1_gej_neg(&r2, &r2); | |||||
/* Test with empty scratch space */ | /* Test with empty scratch space. It should compute the correct result using | ||||
* ecmult_mult_simple algorithm which doesn't require a scratch space. */ | |||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 0); | scratch = secp256k1_scratch_create(&ctx->error_callback, 0); | ||||
CHECK(!secp256k1_ecmult_multi_var(&ctx->ecmult_ctx, scratch, &r, &scG, ecmult_multi_callback, &data, 1)); | CHECK(secp256k1_ecmult_multi_var(&ctx->ecmult_ctx, scratch, &r, &scG, ecmult_multi_callback, &data, n_points)); | ||||
secp256k1_gej_add_var(&r, &r, &r2, NULL); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
secp256k1_scratch_destroy(scratch); | secp256k1_scratch_destroy(scratch); | ||||
/* Test with space for 1 point in pippenger. That's not enough because | /* Test with space for 1 point in pippenger. That's not enough because | ||||
* ecmult_multi selects strauss which requires more memory. */ | * ecmult_multi selects strauss which requires more memory. It should | ||||
* therefore select the simple algorithm. */ | |||||
scratch = secp256k1_scratch_create(&ctx->error_callback, secp256k1_pippenger_scratch_size(1, 1) + PIPPENGER_SCRATCH_OBJECTS*ALIGNMENT); | scratch = secp256k1_scratch_create(&ctx->error_callback, secp256k1_pippenger_scratch_size(1, 1) + PIPPENGER_SCRATCH_OBJECTS*ALIGNMENT); | ||||
CHECK(!secp256k1_ecmult_multi_var(&ctx->ecmult_ctx, scratch, &r, &scG, ecmult_multi_callback, &data, 1)); | CHECK(secp256k1_ecmult_multi_var(&ctx->ecmult_ctx, scratch, &r, &scG, ecmult_multi_callback, &data, n_points)); | ||||
secp256k1_gej_add_var(&r, &r, &r2, NULL); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
secp256k1_scratch_destroy(scratch); | secp256k1_scratch_destroy(scratch); | ||||
secp256k1_gej_neg(&r2, &r2); | |||||
for(i = 1; i <= n_points; i++) { | for(i = 1; i <= n_points; i++) { | ||||
if (i > ECMULT_PIPPENGER_THRESHOLD) { | if (i > ECMULT_PIPPENGER_THRESHOLD) { | ||||
int bucket_window = secp256k1_pippenger_bucket_window(i); | int bucket_window = secp256k1_pippenger_bucket_window(i); | ||||
size_t scratch_size = secp256k1_pippenger_scratch_size(i, bucket_window); | size_t scratch_size = secp256k1_pippenger_scratch_size(i, bucket_window); | ||||
scratch = secp256k1_scratch_create(&ctx->error_callback, scratch_size + PIPPENGER_SCRATCH_OBJECTS*ALIGNMENT); | scratch = secp256k1_scratch_create(&ctx->error_callback, scratch_size + PIPPENGER_SCRATCH_OBJECTS*ALIGNMENT); | ||||
} else { | } else { | ||||
size_t scratch_size = secp256k1_strauss_scratch_size(i); | size_t scratch_size = secp256k1_strauss_scratch_size(i); | ||||
scratch = secp256k1_scratch_create(&ctx->error_callback, scratch_size + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT); | scratch = secp256k1_scratch_create(&ctx->error_callback, scratch_size + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT); | ||||
Show All 11 Lines | void run_ecmult_multi_tests(void) { | ||||
secp256k1_scratch *scratch; | secp256k1_scratch *scratch; | ||||
test_secp256k1_pippenger_bucket_window_inv(); | test_secp256k1_pippenger_bucket_window_inv(); | ||||
test_ecmult_multi_pippenger_max_points(); | test_ecmult_multi_pippenger_max_points(); | ||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 819200); | scratch = secp256k1_scratch_create(&ctx->error_callback, 819200); | ||||
test_ecmult_multi(scratch, secp256k1_ecmult_multi_var); | test_ecmult_multi(scratch, secp256k1_ecmult_multi_var); | ||||
test_ecmult_multi(NULL, secp256k1_ecmult_multi_var); | test_ecmult_multi(NULL, secp256k1_ecmult_multi_var); | ||||
test_ecmult_multi(scratch, secp256k1_ecmult_pippenger_batch_single); | test_ecmult_multi(scratch, secp256k1_ecmult_pippenger_batch_single); | ||||
test_ecmult_multi_batch_single(secp256k1_ecmult_pippenger_batch_single); | |||||
test_ecmult_multi(scratch, secp256k1_ecmult_strauss_batch_single); | test_ecmult_multi(scratch, secp256k1_ecmult_strauss_batch_single); | ||||
test_ecmult_multi_batch_single(secp256k1_ecmult_strauss_batch_single); | |||||
secp256k1_scratch_destroy(scratch); | secp256k1_scratch_destroy(scratch); | ||||
/* Run test_ecmult_multi with space for exactly one point */ | /* Run test_ecmult_multi with space for exactly one point */ | ||||
scratch = secp256k1_scratch_create(&ctx->error_callback, secp256k1_strauss_scratch_size(1) + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT); | scratch = secp256k1_scratch_create(&ctx->error_callback, secp256k1_strauss_scratch_size(1) + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT); | ||||
test_ecmult_multi(scratch, secp256k1_ecmult_multi_var); | test_ecmult_multi(scratch, secp256k1_ecmult_multi_var); | ||||
secp256k1_scratch_destroy(scratch); | secp256k1_scratch_destroy(scratch); | ||||
test_ecmult_multi_batch_size_helper(); | test_ecmult_multi_batch_size_helper(); | ||||
▲ Show 20 Lines • Show All 2,184 Lines • Show Last 20 Lines |