Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/tests.c
Show First 20 Lines • Show All 252 Lines • ▼ Show 20 Lines | |||||
void run_scratch_tests(void) { | void run_scratch_tests(void) { | ||||
int32_t ecount = 0; | int32_t ecount = 0; | ||||
secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); | secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); | ||||
secp256k1_scratch_space *scratch; | secp256k1_scratch_space *scratch; | ||||
/* Test public API */ | /* Test public API */ | ||||
secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount); | secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount); | ||||
scratch = secp256k1_scratch_space_create(none, 100, 10); | |||||
CHECK(scratch == NULL); | |||||
CHECK(ecount == 1); | |||||
scratch = secp256k1_scratch_space_create(none, 100, 100); | |||||
CHECK(scratch != NULL); | |||||
CHECK(ecount == 1); | |||||
secp256k1_scratch_space_destroy(scratch); | |||||
scratch = secp256k1_scratch_space_create(none, 100, 1000); | scratch = secp256k1_scratch_space_create(none, 1000); | ||||
CHECK(scratch != NULL); | CHECK(scratch != NULL); | ||||
CHECK(ecount == 1); | CHECK(ecount == 0); | ||||
/* Test internal API */ | /* Test internal API */ | ||||
CHECK(secp256k1_scratch_max_allocation(scratch, 0) == 1000); | CHECK(secp256k1_scratch_max_allocation(scratch, 0) == 1000); | ||||
CHECK(secp256k1_scratch_max_allocation(scratch, 1) < 1000); | CHECK(secp256k1_scratch_max_allocation(scratch, 1) < 1000); | ||||
CHECK(secp256k1_scratch_resize(scratch, 50, 1) == 1); /* no-op */ | |||||
CHECK(secp256k1_scratch_resize(scratch, 200, 1) == 1); | /* Allocating 500 bytes with no frame fails */ | ||||
CHECK(secp256k1_scratch_resize(scratch, 950, 1) == 1); | CHECK(secp256k1_scratch_alloc(scratch, 500) == NULL); | ||||
CHECK(secp256k1_scratch_resize(scratch, 1000, 1) == 0); | CHECK(secp256k1_scratch_max_allocation(scratch, 0) == 1000); | ||||
CHECK(secp256k1_scratch_resize(scratch, 2000, 1) == 0); | |||||
/* ...but pushing a new stack frame does affect the max allocation */ | |||||
CHECK(secp256k1_scratch_allocate_frame(scratch, 500, 1) == 1); | |||||
CHECK(secp256k1_scratch_max_allocation(scratch, 1) < 500); /* 500 - ALIGNMENT */ | |||||
CHECK(secp256k1_scratch_alloc(scratch, 500) != NULL); | |||||
CHECK(secp256k1_scratch_alloc(scratch, 500) == NULL); | |||||
CHECK(secp256k1_scratch_allocate_frame(scratch, 500, 1) == 0); | |||||
/* ...and this effect is undone by popping the frame */ | |||||
secp256k1_scratch_deallocate_frame(scratch); | |||||
CHECK(secp256k1_scratch_max_allocation(scratch, 0) == 1000); | CHECK(secp256k1_scratch_max_allocation(scratch, 0) == 1000); | ||||
CHECK(secp256k1_scratch_alloc(scratch, 500) == NULL); | |||||
/* cleanup */ | /* cleanup */ | ||||
secp256k1_scratch_space_destroy(scratch); | secp256k1_scratch_space_destroy(scratch); | ||||
secp256k1_context_destroy(none); | secp256k1_context_destroy(none); | ||||
} | } | ||||
/***** HASH TESTS *****/ | /***** HASH TESTS *****/ | ||||
▲ Show 20 Lines • Show All 2,262 Lines • ▼ Show 20 Lines | void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi_func ecmult_multi) { | ||||
secp256k1_gej r; | secp256k1_gej r; | ||||
secp256k1_gej r2; | secp256k1_gej r2; | ||||
ecmult_multi_data data; | ecmult_multi_data data; | ||||
secp256k1_scratch *scratch_empty; | 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); | ||||
secp256k1_scratch_reset(scratch); | |||||
/* 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)); | ||||
/* Check 1- and 2-point multiplies against ecmult */ | /* Check 1- and 2-point multiplies against ecmult */ | ||||
for (ncount = 0; ncount < count; ncount++) { | for (ncount = 0; ncount < count; ncount++) { | ||||
secp256k1_ge ptg; | secp256k1_ge ptg; | ||||
secp256k1_gej ptgj; | secp256k1_gej ptgj; | ||||
Show All 15 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 */ | /* Try to multiply 1 point, but scratch space is empty */ | ||||
scratch_empty = secp256k1_scratch_create(&ctx->error_callback, 0, 0); | scratch_empty = secp256k1_scratch_create(&ctx->error_callback, 0); | ||||
CHECK(!ecmult_multi(&ctx->ecmult_ctx, scratch_empty, &r, &szero, ecmult_multi_callback, &data, 1)); | CHECK(!ecmult_multi(&ctx->ecmult_ctx, scratch_empty, &r, &szero, ecmult_multi_callback, &data, 1)); | ||||
secp256k1_scratch_destroy(scratch_empty); | 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]); | ||||
▲ Show 20 Lines • Show All 209 Lines • ▼ Show 20 Lines | |||||
void test_ecmult_multi_pippenger_max_points(void) { | void test_ecmult_multi_pippenger_max_points(void) { | ||||
size_t scratch_size = secp256k1_rand_int(256); | size_t scratch_size = secp256k1_rand_int(256); | ||||
size_t max_size = secp256k1_pippenger_scratch_size(secp256k1_pippenger_bucket_window_inv(PIPPENGER_MAX_BUCKET_WINDOW-1)+512, 12); | size_t max_size = secp256k1_pippenger_scratch_size(secp256k1_pippenger_bucket_window_inv(PIPPENGER_MAX_BUCKET_WINDOW-1)+512, 12); | ||||
secp256k1_scratch *scratch; | secp256k1_scratch *scratch; | ||||
size_t n_points_supported; | size_t n_points_supported; | ||||
int bucket_window = 0; | int bucket_window = 0; | ||||
for(; scratch_size < max_size; scratch_size+=256) { | for(; scratch_size < max_size; scratch_size+=256) { | ||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 0, scratch_size); | scratch = secp256k1_scratch_create(&ctx->error_callback, scratch_size); | ||||
CHECK(scratch != NULL); | CHECK(scratch != NULL); | ||||
n_points_supported = secp256k1_pippenger_max_points(scratch); | n_points_supported = secp256k1_pippenger_max_points(scratch); | ||||
if (n_points_supported == 0) { | if (n_points_supported == 0) { | ||||
secp256k1_scratch_destroy(scratch); | secp256k1_scratch_destroy(scratch); | ||||
continue; | continue; | ||||
} | } | ||||
bucket_window = secp256k1_pippenger_bucket_window(n_points_supported); | bucket_window = secp256k1_pippenger_bucket_window(n_points_supported); | ||||
CHECK(secp256k1_scratch_resize(scratch, secp256k1_pippenger_scratch_size(n_points_supported, bucket_window), PIPPENGER_SCRATCH_OBJECTS)); | CHECK(secp256k1_scratch_allocate_frame(scratch, secp256k1_pippenger_scratch_size(n_points_supported, bucket_window), PIPPENGER_SCRATCH_OBJECTS)); | ||||
secp256k1_scratch_deallocate_frame(scratch); | |||||
secp256k1_scratch_destroy(scratch); | secp256k1_scratch_destroy(scratch); | ||||
} | } | ||||
CHECK(bucket_window == PIPPENGER_MAX_BUCKET_WINDOW); | CHECK(bucket_window == PIPPENGER_MAX_BUCKET_WINDOW); | ||||
} | } | ||||
/** | /** | ||||
* Run secp256k1_ecmult_multi_var with num points and a scratch space restricted to | * Run secp256k1_ecmult_multi_var with num points and a scratch space restricted to | ||||
* 1 <= i <= num points. | * 1 <= i <= num points. | ||||
Show All 25 Lines | for(i = 0; i < n_points; i++) { | ||||
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; | ||||
/* Test with empty scratch space */ | /* Test with empty scratch space */ | ||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 0, 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, 1)); | ||||
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. */ | ||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 0, 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, 1)); | ||||
secp256k1_scratch_destroy(scratch); | secp256k1_scratch_destroy(scratch); | ||||
secp256k1_gej_neg(&r2, &r2); | 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, 0, 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, 0, scratch_size + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT); | scratch = secp256k1_scratch_create(&ctx->error_callback, scratch_size + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT); | ||||
} | } | ||||
CHECK(secp256k1_ecmult_multi_var(&ctx->ecmult_ctx, scratch, &r, &scG, ecmult_multi_callback, &data, n_points)); | 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); | secp256k1_gej_add_var(&r, &r, &r2, NULL); | ||||
CHECK(secp256k1_gej_is_infinity(&r)); | CHECK(secp256k1_gej_is_infinity(&r)); | ||||
secp256k1_scratch_destroy(scratch); | secp256k1_scratch_destroy(scratch); | ||||
} | } | ||||
free(sc); | free(sc); | ||||
free(pt); | free(pt); | ||||
} | } | ||||
void run_ecmult_multi_tests(void) { | 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, 0, 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(scratch, secp256k1_ecmult_pippenger_batch_single); | test_ecmult_multi(scratch, secp256k1_ecmult_pippenger_batch_single); | ||||
test_ecmult_multi(scratch, secp256k1_ecmult_strauss_batch_single); | test_ecmult_multi(scratch, 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, 0, 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_batching(); | test_ecmult_multi_batching(); | ||||
} | } | ||||
void test_wnaf(const secp256k1_scalar *number, int w) { | void test_wnaf(const secp256k1_scalar *number, int w) { | ||||
secp256k1_scalar x, two, t; | secp256k1_scalar x, two, t; | ||||
▲ Show 20 Lines • Show All 2,177 Lines • Show Last 20 Lines |