diff --git a/src/secp256k1.c b/src/secp256k1.c index 41138b57..5ed38241 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -57,6 +57,8 @@ } \ } while(0) +/* Note that whenever you change the context struct, you must also change the + * context_eq function. */ struct secp256k1_context_struct { secp256k1_ecmult_gen_context ecmult_gen_ctx; secp256k1_callback illegal_callback; diff --git a/src/tests.c b/src/tests.c index fd564a2c..2f0620f4 100644 --- a/src/tests.c +++ b/src/tests.c @@ -146,6 +146,38 @@ void run_selftest_tests(void) { secp256k1_selftest(); } +int ecmult_gen_context_eq(const secp256k1_ecmult_gen_context *a, const secp256k1_ecmult_gen_context *b) { + return a->built == b->built + && secp256k1_scalar_eq(&a->blind, &b->blind) + && secp256k1_gej_eq_var(&a->initial, &b->initial); +} + +int context_eq(const secp256k1_context *a, const secp256k1_context *b) { + return a->declassify == b->declassify + && ecmult_gen_context_eq(&a->ecmult_gen_ctx, &b->ecmult_gen_ctx) + && a->illegal_callback.fn == b->illegal_callback.fn + && a->illegal_callback.data == b->illegal_callback. +data + && a->error_callback.fn == b->error_callback.fn + && a->error_callback.data == b->error_callback.data; +} + +void test_deprecated_flags(void) { + unsigned int flags[] = { SECP256K1_CONTEXT_SIGN, + SECP256K1_CONTEXT_VERIFY, + SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY }; + int i; + /* Check that a context created with any of the flags in the flags array is + * identical to the NONE context. */ + for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++) { + secp256k1_context *tmp_ctx; + CHECK(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE) == secp256k1_context_preallocated_size(flags[i])); + tmp_ctx = secp256k1_context_create(flags[i]); + CHECK(context_eq(ctx, tmp_ctx)); + secp256k1_context_destroy(tmp_ctx); + } +} + void run_context_tests(int use_prealloc) { secp256k1_pubkey pubkey; secp256k1_pubkey zero_pubkey; @@ -153,15 +185,8 @@ void run_context_tests(int use_prealloc) { unsigned char ctmp[32]; int32_t ecount; int32_t ecount2; - secp256k1_context *none; - secp256k1_context *sign; - secp256k1_context *vrfy; - secp256k1_context *both; secp256k1_context *sttc; - void *none_prealloc = NULL; - void *sign_prealloc = NULL; - void *vrfy_prealloc = NULL; - void *both_prealloc = NULL; + void *ctx_prealloc = NULL; void *sttc_prealloc = NULL; secp256k1_gej pubj; @@ -173,45 +198,32 @@ void run_context_tests(int use_prealloc) { CHECK(secp256k1_context_no_precomp == secp256k1_context_static); if (use_prealloc) { - none_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); - sign_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN)); - vrfy_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY)); - both_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); + ctx_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); + CHECK(ctx_prealloc != NULL); + ctx = secp256k1_context_preallocated_create(ctx_prealloc, SECP256K1_CONTEXT_NONE); sttc_prealloc = malloc(secp256k1_context_preallocated_clone_size(secp256k1_context_static)); - CHECK(none_prealloc != NULL); - CHECK(sign_prealloc != NULL); - CHECK(vrfy_prealloc != NULL); - CHECK(both_prealloc != NULL); CHECK(sttc_prealloc != NULL); - none = secp256k1_context_preallocated_create(none_prealloc, SECP256K1_CONTEXT_NONE); - sign = secp256k1_context_preallocated_create(sign_prealloc, SECP256K1_CONTEXT_SIGN); - vrfy = secp256k1_context_preallocated_create(vrfy_prealloc, SECP256K1_CONTEXT_VERIFY); - both = secp256k1_context_preallocated_create(both_prealloc, SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); sttc = secp256k1_context_preallocated_clone(secp256k1_context_static, sttc_prealloc); } else { - none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); - sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); sttc = secp256k1_context_clone(secp256k1_context_static); + ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); } + test_deprecated_flags(); + memset(&zero_pubkey, 0, sizeof(zero_pubkey)); ecount = 0; ecount2 = 10; secp256k1_context_set_illegal_callback(sttc, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount2); + secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount2); /* set error callback (to a function that still aborts in case malloc() fails in secp256k1_context_clone() below) */ - secp256k1_context_set_error_callback(sign, secp256k1_default_illegal_callback_fn, NULL); - CHECK(sign->error_callback.fn != vrfy->error_callback.fn); - CHECK(sign->error_callback.fn == secp256k1_default_illegal_callback_fn); + secp256k1_context_set_error_callback(ctx, secp256k1_default_illegal_callback_fn, NULL); + CHECK(ctx->error_callback.fn != sttc->error_callback.fn); + CHECK(ctx->error_callback.fn == secp256k1_default_illegal_callback_fn); /* check if sizes for cloning are consistent */ - CHECK(secp256k1_context_preallocated_clone_size(none) == secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); - CHECK(secp256k1_context_preallocated_clone_size(sign) == secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN)); - CHECK(secp256k1_context_preallocated_clone_size(vrfy) == secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY)); - CHECK(secp256k1_context_preallocated_clone_size(both) == secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); + CHECK(secp256k1_context_preallocated_clone_size(ctx) == secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); CHECK(secp256k1_context_preallocated_clone_size(sttc) >= sizeof(secp256k1_context)); /*** clone and destroy all of them to make sure cloning was complete ***/ @@ -220,58 +232,31 @@ void run_context_tests(int use_prealloc) { if (use_prealloc) { /* clone into a non-preallocated context and then again into a new preallocated one. */ - ctx_tmp = none; none = secp256k1_context_clone(none); secp256k1_context_preallocated_destroy(ctx_tmp); - free(none_prealloc); none_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); CHECK(none_prealloc != NULL); - ctx_tmp = none; none = secp256k1_context_preallocated_clone(none, none_prealloc); secp256k1_context_destroy(ctx_tmp); - - ctx_tmp = sign; sign = secp256k1_context_clone(sign); secp256k1_context_preallocated_destroy(ctx_tmp); - free(sign_prealloc); sign_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN)); CHECK(sign_prealloc != NULL); - ctx_tmp = sign; sign = secp256k1_context_preallocated_clone(sign, sign_prealloc); secp256k1_context_destroy(ctx_tmp); - - ctx_tmp = vrfy; vrfy = secp256k1_context_clone(vrfy); secp256k1_context_preallocated_destroy(ctx_tmp); - free(vrfy_prealloc); vrfy_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY)); CHECK(vrfy_prealloc != NULL); - ctx_tmp = vrfy; vrfy = secp256k1_context_preallocated_clone(vrfy, vrfy_prealloc); secp256k1_context_destroy(ctx_tmp); - - ctx_tmp = both; both = secp256k1_context_clone(both); secp256k1_context_preallocated_destroy(ctx_tmp); - free(both_prealloc); both_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); CHECK(both_prealloc != NULL); - ctx_tmp = both; both = secp256k1_context_preallocated_clone(both, both_prealloc); secp256k1_context_destroy(ctx_tmp); + ctx_tmp = ctx; ctx = secp256k1_context_clone(ctx); secp256k1_context_preallocated_destroy(ctx_tmp); + free(ctx_prealloc); ctx_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); CHECK(ctx_prealloc != NULL); + ctx_tmp = ctx; ctx = secp256k1_context_preallocated_clone(ctx, ctx_prealloc); secp256k1_context_destroy(ctx_tmp); } else { /* clone into a preallocated context and then again into a new non-preallocated one. */ void *prealloc_tmp; prealloc_tmp = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); CHECK(prealloc_tmp != NULL); - ctx_tmp = none; none = secp256k1_context_preallocated_clone(none, prealloc_tmp); secp256k1_context_destroy(ctx_tmp); - ctx_tmp = none; none = secp256k1_context_clone(none); secp256k1_context_preallocated_destroy(ctx_tmp); - free(prealloc_tmp); - - prealloc_tmp = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN)); CHECK(prealloc_tmp != NULL); - ctx_tmp = sign; sign = secp256k1_context_preallocated_clone(sign, prealloc_tmp); secp256k1_context_destroy(ctx_tmp); - ctx_tmp = sign; sign = secp256k1_context_clone(sign); secp256k1_context_preallocated_destroy(ctx_tmp); - free(prealloc_tmp); - - prealloc_tmp = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY)); CHECK(prealloc_tmp != NULL); - ctx_tmp = vrfy; vrfy = secp256k1_context_preallocated_clone(vrfy, prealloc_tmp); secp256k1_context_destroy(ctx_tmp); - ctx_tmp = vrfy; vrfy = secp256k1_context_clone(vrfy); secp256k1_context_preallocated_destroy(ctx_tmp); - free(prealloc_tmp); - - prealloc_tmp = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); CHECK(prealloc_tmp != NULL); - ctx_tmp = both; both = secp256k1_context_preallocated_clone(both, prealloc_tmp); secp256k1_context_destroy(ctx_tmp); - ctx_tmp = both; both = secp256k1_context_clone(both); secp256k1_context_preallocated_destroy(ctx_tmp); + ctx_tmp = ctx; ctx = secp256k1_context_preallocated_clone(ctx, prealloc_tmp); secp256k1_context_destroy(ctx_tmp); + ctx_tmp = ctx; ctx = secp256k1_context_clone(ctx); secp256k1_context_preallocated_destroy(ctx_tmp); free(prealloc_tmp); } } /* Verify that the error callback makes it across the clone. */ - CHECK(sign->error_callback.fn != vrfy->error_callback.fn); - CHECK(sign->error_callback.fn == secp256k1_default_illegal_callback_fn); + CHECK(ctx->error_callback.fn != sttc->error_callback.fn); + CHECK(ctx->error_callback.fn == secp256k1_default_illegal_callback_fn); /* And that it resets back to default. */ - secp256k1_context_set_error_callback(sign, NULL, NULL); - CHECK(vrfy->error_callback.fn == sign->error_callback.fn); + secp256k1_context_set_error_callback(ctx, NULL, NULL); + CHECK(ctx->error_callback.fn == sttc->error_callback.fn); /*** attempt to use them ***/ random_scalar_order_test(&msg); random_scalar_order_test(&key); - secp256k1_ecmult_gen(&both->ecmult_gen_ctx, &pubj, &key); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubj, &key); secp256k1_ge_set_gej(&pub, &pubj); /* Verify context-type checking illegal-argument errors. */ @@ -279,29 +264,29 @@ void run_context_tests(int use_prealloc) { CHECK(secp256k1_ec_pubkey_create(sttc, &pubkey, ctmp) == 0); CHECK(ecount == 1); VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(sign, &pubkey, ctmp) == 1); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 1); VG_CHECK(&pubkey, sizeof(pubkey)); CHECK(secp256k1_ecdsa_sign(sttc, &sig, ctmp, ctmp, NULL, NULL) == 0); CHECK(ecount == 2); VG_UNDEF(&sig, sizeof(sig)); - CHECK(secp256k1_ecdsa_sign(sign, &sig, ctmp, ctmp, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, ctmp, ctmp, NULL, NULL) == 1); VG_CHECK(&sig, sizeof(sig)); CHECK(ecount2 == 10); - CHECK(secp256k1_ecdsa_verify(sign, &sig, ctmp, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, ctmp, &pubkey) == 1); CHECK(ecount2 == 10); CHECK(secp256k1_ecdsa_verify(sttc, &sig, ctmp, &pubkey) == 1); CHECK(ecount == 2); - CHECK(secp256k1_ec_pubkey_tweak_add(sign, &pubkey, ctmp) == 1); + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp) == 1); CHECK(ecount2 == 10); CHECK(secp256k1_ec_pubkey_tweak_add(sttc, &pubkey, ctmp) == 1); CHECK(ecount == 2); - CHECK(secp256k1_ec_pubkey_tweak_mul(sign, &pubkey, ctmp) == 1); + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, ctmp) == 1); CHECK(ecount2 == 10); CHECK(secp256k1_ec_pubkey_negate(sttc, &pubkey) == 1); CHECK(ecount == 2); - CHECK(secp256k1_ec_pubkey_negate(sign, &pubkey) == 1); + CHECK(secp256k1_ec_pubkey_negate(ctx, &pubkey) == 1); CHECK(ecount == 2); - CHECK(secp256k1_ec_pubkey_negate(sign, NULL) == 0); + CHECK(secp256k1_ec_pubkey_negate(ctx, NULL) == 0); CHECK(ecount2 == 11); CHECK(secp256k1_ec_pubkey_negate(sttc, &zero_pubkey) == 0); CHECK(ecount == 3); @@ -311,49 +296,37 @@ void run_context_tests(int use_prealloc) { CHECK(ecount == 3); CHECK(secp256k1_context_randomize(sttc, NULL) == 1); CHECK(ecount == 3); - CHECK(secp256k1_context_randomize(sign, ctmp) == 1); + CHECK(secp256k1_context_randomize(ctx, ctmp) == 1); CHECK(ecount2 == 11); - CHECK(secp256k1_context_randomize(sign, NULL) == 1); + CHECK(secp256k1_context_randomize(ctx, NULL) == 1); CHECK(ecount2 == 11); secp256k1_context_set_illegal_callback(sttc, NULL, NULL); - secp256k1_context_set_illegal_callback(sign, NULL, NULL); + secp256k1_context_set_illegal_callback(ctx, NULL, NULL); /* obtain a working nonce */ do { random_scalar_order_test(&nonce); - } while(!secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); + } while(!secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); /* try signing */ - CHECK(secp256k1_ecdsa_sig_sign(&sign->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); - CHECK(secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); + CHECK(secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); /* try verifying */ CHECK(secp256k1_ecdsa_sig_verify(&sigr, &sigs, &pub, &msg)); - CHECK(secp256k1_ecdsa_sig_verify(&sigr, &sigs, &pub, &msg)); /* cleanup */ if (use_prealloc) { - secp256k1_context_preallocated_destroy(none); - secp256k1_context_preallocated_destroy(sign); - secp256k1_context_preallocated_destroy(vrfy); - secp256k1_context_preallocated_destroy(both); + secp256k1_context_preallocated_destroy(ctx); secp256k1_context_preallocated_destroy(sttc); - free(none_prealloc); - free(sign_prealloc); - free(vrfy_prealloc); - free(both_prealloc); + free(ctx_prealloc); free(sttc_prealloc); } else { - secp256k1_context_destroy(none); - secp256k1_context_destroy(sign); - secp256k1_context_destroy(vrfy); - secp256k1_context_destroy(both); + secp256k1_context_destroy(ctx); secp256k1_context_destroy(sttc); } /* Defined as no-op. */ secp256k1_context_destroy(NULL); secp256k1_context_preallocated_destroy(NULL); - } void run_scratch_tests(void) {