scratch: add stack frame support

This commit is contained in:
Andrew Poelstra
2018-03-20 13:21:33 +00:00
parent 9bc2e26502
commit 6fe50439ae
8 changed files with 92 additions and 76 deletions

View File

@@ -258,29 +258,32 @@ void run_scratch_tests(void) {
/* Test public API */
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);
scratch = secp256k1_scratch_space_create(none, 1000);
CHECK(scratch != NULL);
CHECK(ecount == 1);
secp256k1_scratch_space_destroy(scratch);
scratch = secp256k1_scratch_space_create(none, 100, 1000);
CHECK(scratch != NULL);
CHECK(ecount == 1);
CHECK(ecount == 0);
/* Test internal API */
CHECK(secp256k1_scratch_max_allocation(scratch, 0) == 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);
CHECK(secp256k1_scratch_resize(scratch, 950, 1) == 1);
CHECK(secp256k1_scratch_resize(scratch, 1000, 1) == 0);
CHECK(secp256k1_scratch_resize(scratch, 2000, 1) == 0);
/* Allocating 500 bytes with no frame fails */
CHECK(secp256k1_scratch_alloc(scratch, 500) == NULL);
CHECK(secp256k1_scratch_max_allocation(scratch, 0) == 1000);
/* ...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_alloc(scratch, 500) == NULL);
/* cleanup */
secp256k1_scratch_space_destroy(scratch);
secp256k1_context_destroy(none);
@@ -2558,7 +2561,6 @@ void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi_func e
data.sc = sc;
data.pt = pt;
secp256k1_scalar_set_int(&szero, 0);
secp256k1_scratch_reset(scratch);
/* No points to multiply */
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, NULL, ecmult_multi_callback, &data, 0));
@@ -2590,7 +2592,7 @@ void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi_func e
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, 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));
secp256k1_scratch_destroy(scratch_empty);
@@ -2816,7 +2818,7 @@ void test_ecmult_multi_pippenger_max_points(void) {
int bucket_window = 0;
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);
n_points_supported = secp256k1_pippenger_max_points(scratch);
if (n_points_supported == 0) {
@@ -2824,7 +2826,8 @@ void test_ecmult_multi_pippenger_max_points(void) {
continue;
}
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);
}
CHECK(bucket_window == PIPPENGER_MAX_BUCKET_WINDOW);
@@ -2866,13 +2869,13 @@ void test_ecmult_multi_batching(void) {
data.pt = pt;
/* 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));
secp256k1_scratch_destroy(scratch);
/* Test with space for 1 point in pippenger. That's not enough because
* 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));
secp256k1_scratch_destroy(scratch);
@@ -2881,10 +2884,10 @@ void test_ecmult_multi_batching(void) {
if (i > ECMULT_PIPPENGER_THRESHOLD) {
int bucket_window = secp256k1_pippenger_bucket_window(i);
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 {
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));
secp256k1_gej_add_var(&r, &r, &r2, NULL);
@@ -2900,14 +2903,14 @@ void run_ecmult_multi_tests(void) {
test_secp256k1_pippenger_bucket_window_inv();
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_pippenger_batch_single);
test_ecmult_multi(scratch, secp256k1_ecmult_strauss_batch_single);
secp256k1_scratch_destroy(scratch);
/* 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);
secp256k1_scratch_destroy(scratch);