diff --git a/src/modules/bulletproofs/tests_impl.h b/src/modules/bulletproofs/tests_impl.h index ff7519f2..9943fef5 100644 --- a/src/modules/bulletproofs/tests_impl.h +++ b/src/modules/bulletproofs/tests_impl.h @@ -203,6 +203,7 @@ static void secp256k1_norm_arg_commit_initial_data( secp256k1_bulletproofs_pp_sha256_tagged_commitment_init(transcript); secp256k1_fe_normalize(&comm.x); secp256k1_fe_normalize(&comm.y); + CHECK(secp256k1_ge_is_infinity(&comm) == 0); CHECK(secp256k1_bulletproofs_serialize_pt(&ser_commit[0], &comm)); secp256k1_sha256_write(transcript, ser_commit, 33); secp256k1_scalar_get_b32(ser_scalar, r); @@ -225,6 +226,28 @@ static void secp256k1_norm_arg_commit_initial_data( } } +static void copy_vectors_into_scratch(secp256k1_scratch_space* scratch, + secp256k1_scalar **ns, + secp256k1_scalar **ls, + secp256k1_scalar **cs, + secp256k1_ge **gs, + const secp256k1_scalar *n_vec, + const secp256k1_scalar *l_vec, + const secp256k1_scalar *c_vec, + const secp256k1_ge *gens_vec, + size_t g_len, + size_t h_len) { + *ns = (secp256k1_scalar*)secp256k1_scratch_alloc(&ctx->error_callback, scratch, g_len * sizeof(secp256k1_scalar)); + *ls = (secp256k1_scalar*)secp256k1_scratch_alloc(&ctx->error_callback, scratch, h_len * sizeof(secp256k1_scalar)); + *cs = (secp256k1_scalar*)secp256k1_scratch_alloc(&ctx->error_callback, scratch, h_len * sizeof(secp256k1_scalar)); + *gs = (secp256k1_ge*)secp256k1_scratch_alloc(&ctx->error_callback, scratch, (g_len + h_len) * sizeof(secp256k1_ge)); + CHECK(ns != NULL && ls != NULL && cs != NULL && gs != NULL); + memcpy(*ns, n_vec, g_len * sizeof(secp256k1_scalar)); + memcpy(*ls, l_vec, h_len * sizeof(secp256k1_scalar)); + memcpy(*cs, c_vec, h_len * sizeof(secp256k1_scalar)); + memcpy(*gs, gens_vec, (g_len + h_len) * sizeof(secp256k1_ge)); +} + /* A complete norm argument. In contrast to secp256k1_bulletproofs_pp_rangeproof_norm_product_prove, this is meant to be used as a standalone norm argument. This is a simple wrapper around secp256k1_bulletproofs_pp_rangeproof_norm_product_prove @@ -253,18 +276,8 @@ static int secp256k1_norm_arg_prove( secp256k1_sha256 transcript; scratch_checkpoint = secp256k1_scratch_checkpoint(&ctx->error_callback, scratch); - ns = (secp256k1_scalar*)secp256k1_scratch_alloc(&ctx->error_callback, scratch, g_len * sizeof(secp256k1_scalar)); - ls = (secp256k1_scalar*)secp256k1_scratch_alloc(&ctx->error_callback, scratch, h_len * sizeof(secp256k1_scalar)); - cs = (secp256k1_scalar*)secp256k1_scratch_alloc(&ctx->error_callback, scratch, h_len * sizeof(secp256k1_scalar)); - gs = (secp256k1_ge*)secp256k1_scratch_alloc(&ctx->error_callback, scratch, (g_len + h_len) * sizeof(secp256k1_ge)); - if (ns == NULL || ls == NULL || cs == NULL || gs == NULL) { - secp256k1_scratch_apply_checkpoint(&ctx->error_callback, scratch, scratch_checkpoint); - return 0; - } - memcpy(ns, n_vec, g_len * sizeof(secp256k1_scalar)); - memcpy(ls, l_vec, h_len * sizeof(secp256k1_scalar)); - memcpy(cs, c_vec, h_len * sizeof(secp256k1_scalar)); - memcpy(gs, gens_vec->gens, (g_len + h_len) * sizeof(secp256k1_ge)); + + copy_vectors_into_scratch(scratch, &ns, &ls, &cs, &gs, n_vec, l_vec, c_vec, gens_vec->gens, g_len, h_len); /* Commit to the initial public values */ secp256k1_norm_arg_commit_initial_data(&transcript, r, gens_vec, g_len, c_vec, c_vec_len, &comm); @@ -324,6 +337,67 @@ static int secp256k1_norm_arg_verify( return res; } +void norm_arg_zero(void) { + secp256k1_scalar n_vec[64], l_vec[64], c_vec[64]; + secp256k1_scalar r, q; + secp256k1_ge commit; + size_t i; + secp256k1_scratch *scratch = secp256k1_scratch_space_create(ctx, 1000*10); /* shouldn't need much */ + unsigned char proof[1000]; + secp256k1_sha256 transcript; + + random_scalar_order(&r); + secp256k1_scalar_sqr(&q, &r); + + /* l is zero vector and n is zero vectors of length 1 each. */ + { + size_t plen = sizeof(proof); + unsigned int n_vec_len = 1; + unsigned int c_vec_len = 1; + secp256k1_bulletproofs_generators *gens = secp256k1_bulletproofs_generators_create(ctx, n_vec_len + c_vec_len); + + secp256k1_scalar_set_int(&n_vec[0], 0); + secp256k1_scalar_set_int(&l_vec[0], 0); + random_scalar_order(&c_vec[0]); + + secp256k1_sha256_initialize(&transcript); /* No challenges used in n = 1, l = 1, but we set transcript as a good practice*/ + CHECK(secp256k1_bulletproofs_commit(ctx, scratch, &commit, gens, n_vec, n_vec_len, l_vec, c_vec_len, c_vec, c_vec_len, &q)); + { + secp256k1_scalar *ns, *ls, *cs; + secp256k1_ge *gs; + size_t scratch_checkpoint = secp256k1_scratch_checkpoint(&ctx->error_callback, scratch); + copy_vectors_into_scratch(scratch, &ns, &ls, &cs, &gs, n_vec, l_vec, c_vec, gens->gens, n_vec_len, c_vec_len); + CHECK(secp256k1_bulletproofs_pp_rangeproof_norm_product_prove(ctx, scratch, proof, &plen, &transcript, &r, gs, gens->n, ns, n_vec_len, ls, c_vec_len, cs, c_vec_len)); + secp256k1_scratch_apply_checkpoint(&ctx->error_callback, scratch, scratch_checkpoint); + } + secp256k1_sha256_initialize(&transcript); + CHECK(secp256k1_bulletproofs_pp_rangeproof_norm_product_verify(ctx, scratch, proof, plen, &transcript, &r, gens, c_vec_len, c_vec, c_vec_len, &commit)); + + secp256k1_bulletproofs_generators_destroy(ctx, gens); + } + + /* l is the zero vector and longer than n. This results in one of the + * internal commitments X or R to be the point at infinity. */ + { + unsigned int n_vec_len = 1; + unsigned int c_vec_len = 2; + secp256k1_bulletproofs_generators *gs = secp256k1_bulletproofs_generators_create(ctx, n_vec_len + c_vec_len); + size_t plen = sizeof(proof); + for (i = 0; i < n_vec_len; i++) { + random_scalar_order(&n_vec[i]); + } + for (i = 0; i < c_vec_len; i++) { + secp256k1_scalar_set_int(&l_vec[i], 0); + random_scalar_order(&c_vec[i]); + } + CHECK(secp256k1_bulletproofs_commit(ctx, scratch, &commit, gs, n_vec, n_vec_len, l_vec, c_vec_len, c_vec, c_vec_len, &q)); + CHECK(!secp256k1_norm_arg_prove(scratch, proof, &plen, &r, gs, n_vec, n_vec_len, l_vec, c_vec_len, c_vec, c_vec_len, &commit)); + secp256k1_bulletproofs_generators_destroy(ctx, gs); + } + + secp256k1_scratch_space_destroy(ctx, scratch); +} + void norm_arg_test(unsigned int n, unsigned int m) { secp256k1_scalar n_vec[64], l_vec[64], c_vec[64]; secp256k1_scalar r, q; @@ -373,6 +447,7 @@ void run_bulletproofs_tests(void) { test_bulletproofs_generators_fixed(); test_bulletproofs_pp_tagged_hash(); + norm_arg_zero(); norm_arg_test(1, 1); norm_arg_test(1, 64); norm_arg_test(64, 1);