Add testcases for bulletproofs++ norm arugment
This commit is contained in:
parent
46c7391154
commit
2574516483
@ -187,12 +187,199 @@ void test_norm_util_helpers(void) {
|
|||||||
secp256k1_scalar_set_int(&res, 256); CHECK(secp256k1_scalar_eq(&res, &r_pows[3]));
|
secp256k1_scalar_set_int(&res, 256); CHECK(secp256k1_scalar_eq(&res, &r_pows[3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void secp256k1_norm_arg_commit_initial_data(
|
||||||
|
secp256k1_sha256* transcript,
|
||||||
|
const secp256k1_scalar* r,
|
||||||
|
const secp256k1_bulletproofs_generators* gens_vec,
|
||||||
|
size_t g_len, /* Same as n_vec_len, g_len + c_vec_len = gens->n */
|
||||||
|
const secp256k1_scalar* c_vec,
|
||||||
|
size_t c_vec_len,
|
||||||
|
const secp256k1_ge* commit
|
||||||
|
) {
|
||||||
|
/* Commit to the initial public values */
|
||||||
|
unsigned char ser_commit[33], ser_scalar[32], ser_le64[8];
|
||||||
|
size_t i;
|
||||||
|
secp256k1_ge comm = *commit;
|
||||||
|
secp256k1_bulletproofs_pp_sha256_tagged_commitment_init(transcript);
|
||||||
|
secp256k1_fe_normalize(&comm.x);
|
||||||
|
secp256k1_fe_normalize(&comm.y);
|
||||||
|
CHECK(secp256k1_bulletproofs_serialize_pt(&ser_commit[0], &comm));
|
||||||
|
secp256k1_sha256_write(transcript, ser_commit, 33);
|
||||||
|
secp256k1_scalar_get_b32(ser_scalar, r);
|
||||||
|
secp256k1_sha256_write(transcript, ser_scalar, 32);
|
||||||
|
secp256k1_bulletproofs_le64(ser_le64, g_len);
|
||||||
|
secp256k1_sha256_write(transcript, ser_le64, 8);
|
||||||
|
secp256k1_bulletproofs_le64(ser_le64, gens_vec->n);
|
||||||
|
secp256k1_sha256_write(transcript, ser_le64, 8);
|
||||||
|
for (i = 0; i < gens_vec->n; i++) {
|
||||||
|
secp256k1_fe_normalize(&gens_vec->gens[i].x);
|
||||||
|
secp256k1_fe_normalize(&gens_vec->gens[i].y);
|
||||||
|
CHECK(secp256k1_bulletproofs_serialize_pt(&ser_commit[0], &gens_vec->gens[i]));
|
||||||
|
secp256k1_sha256_write(transcript, ser_commit, 33);
|
||||||
|
}
|
||||||
|
secp256k1_bulletproofs_le64(ser_le64, c_vec_len);
|
||||||
|
secp256k1_sha256_write(transcript, ser_le64, 8);
|
||||||
|
for (i = 0; i < c_vec_len; i++) {
|
||||||
|
secp256k1_scalar_get_b32(ser_scalar, &c_vec[i]);
|
||||||
|
secp256k1_sha256_write(transcript, ser_scalar, 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
that also commits to the initial public values used in the protocol. In this case, these public
|
||||||
|
values are commitment.
|
||||||
|
*/
|
||||||
|
static int secp256k1_norm_arg_prove(
|
||||||
|
secp256k1_scratch_space* scratch,
|
||||||
|
unsigned char* proof,
|
||||||
|
size_t *proof_len,
|
||||||
|
const secp256k1_scalar* r,
|
||||||
|
const secp256k1_bulletproofs_generators* gens_vec,
|
||||||
|
const secp256k1_scalar* n_vec,
|
||||||
|
size_t n_vec_len,
|
||||||
|
const secp256k1_scalar* l_vec,
|
||||||
|
size_t l_vec_len,
|
||||||
|
const secp256k1_scalar* c_vec,
|
||||||
|
size_t c_vec_len,
|
||||||
|
const secp256k1_ge* commit
|
||||||
|
) {
|
||||||
|
secp256k1_scalar *ns, *ls, *cs;
|
||||||
|
secp256k1_ge *gs, comm = *commit;
|
||||||
|
size_t scratch_checkpoint;
|
||||||
|
size_t g_len = n_vec_len, h_len = l_vec_len;
|
||||||
|
int res;
|
||||||
|
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));
|
||||||
|
|
||||||
|
/* Commit to the initial public values */
|
||||||
|
secp256k1_norm_arg_commit_initial_data(&transcript, r, gens_vec, g_len, c_vec, c_vec_len, &comm);
|
||||||
|
|
||||||
|
res = secp256k1_bulletproofs_pp_rangeproof_norm_product_prove(
|
||||||
|
ctx,
|
||||||
|
scratch,
|
||||||
|
proof,
|
||||||
|
proof_len,
|
||||||
|
&transcript, /* Transcript hash of the parent protocol */
|
||||||
|
r,
|
||||||
|
gs,
|
||||||
|
gens_vec->n,
|
||||||
|
ns,
|
||||||
|
n_vec_len,
|
||||||
|
ls,
|
||||||
|
l_vec_len,
|
||||||
|
cs,
|
||||||
|
c_vec_len
|
||||||
|
);
|
||||||
|
secp256k1_scratch_apply_checkpoint(&ctx->error_callback, scratch, scratch_checkpoint);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify the proof */
|
||||||
|
static int secp256k1_norm_arg_verify(
|
||||||
|
secp256k1_scratch_space* scratch,
|
||||||
|
const unsigned char* proof,
|
||||||
|
size_t proof_len,
|
||||||
|
const secp256k1_scalar* r,
|
||||||
|
const secp256k1_bulletproofs_generators* gens_vec,
|
||||||
|
size_t g_len,
|
||||||
|
const secp256k1_scalar* c_vec,
|
||||||
|
size_t c_vec_len,
|
||||||
|
const secp256k1_ge* commit
|
||||||
|
) {
|
||||||
|
secp256k1_ge comm = *commit;
|
||||||
|
int res;
|
||||||
|
secp256k1_sha256 transcript;
|
||||||
|
|
||||||
|
/* Commit to the initial public values */
|
||||||
|
secp256k1_norm_arg_commit_initial_data(&transcript, r, gens_vec, g_len, c_vec, c_vec_len, &comm);
|
||||||
|
|
||||||
|
res = secp256k1_bulletproofs_pp_rangeproof_norm_product_verify(
|
||||||
|
ctx,
|
||||||
|
scratch,
|
||||||
|
proof,
|
||||||
|
proof_len,
|
||||||
|
&transcript,
|
||||||
|
r,
|
||||||
|
gens_vec,
|
||||||
|
g_len,
|
||||||
|
c_vec,
|
||||||
|
c_vec_len,
|
||||||
|
commit
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
secp256k1_ge commit;
|
||||||
|
size_t i, plen;
|
||||||
|
int res;
|
||||||
|
secp256k1_bulletproofs_generators *gs = secp256k1_bulletproofs_generators_create(ctx, n + m);
|
||||||
|
secp256k1_scratch *scratch = secp256k1_scratch_space_create(ctx, 1000*1000); /* shouldn't need much */
|
||||||
|
unsigned char proof[1000];
|
||||||
|
plen = 1000;
|
||||||
|
random_scalar_order(&r);
|
||||||
|
secp256k1_scalar_sqr(&q, &r);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
random_scalar_order(&n_vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < m; i++) {
|
||||||
|
random_scalar_order(&l_vec[i]);
|
||||||
|
random_scalar_order(&c_vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = secp256k1_bulletproofs_commit(ctx, scratch, &commit, gs, n_vec, n, l_vec, m, c_vec, m, &q);
|
||||||
|
CHECK(res == 1);
|
||||||
|
res = secp256k1_norm_arg_prove(scratch, proof, &plen, &r, gs, n_vec, n, l_vec, m, c_vec, m, &commit);
|
||||||
|
CHECK(res == 1);
|
||||||
|
|
||||||
|
res = secp256k1_norm_arg_verify(scratch, proof, plen, &r, gs, n, c_vec, m, &commit);
|
||||||
|
CHECK(res == 1);
|
||||||
|
|
||||||
|
/* Changing any of last two scalars should break the proof */
|
||||||
|
proof[plen - 1] ^= 1;
|
||||||
|
res = secp256k1_norm_arg_verify(scratch, proof, plen, &r, gs, n, c_vec, m, &commit);
|
||||||
|
CHECK(res == 0);
|
||||||
|
proof[plen - 1 - 32] ^= 1;
|
||||||
|
res = secp256k1_norm_arg_verify(scratch, proof, plen, &r, gs, n, c_vec, m, &commit);
|
||||||
|
CHECK(res == 0);
|
||||||
|
|
||||||
|
secp256k1_scratch_space_destroy(ctx, scratch);
|
||||||
|
secp256k1_bulletproofs_generators_destroy(ctx, gs);
|
||||||
|
}
|
||||||
|
|
||||||
void run_bulletproofs_tests(void) {
|
void run_bulletproofs_tests(void) {
|
||||||
test_log_exp();
|
test_log_exp();
|
||||||
test_norm_util_helpers();
|
test_norm_util_helpers();
|
||||||
test_bulletproofs_generators_api();
|
test_bulletproofs_generators_api();
|
||||||
test_bulletproofs_generators_fixed();
|
test_bulletproofs_generators_fixed();
|
||||||
test_bulletproofs_pp_tagged_hash();
|
test_bulletproofs_pp_tagged_hash();
|
||||||
|
|
||||||
|
norm_arg_test(1, 1);
|
||||||
|
norm_arg_test(1, 64);
|
||||||
|
norm_arg_test(64, 1);
|
||||||
|
norm_arg_test(32, 32);
|
||||||
|
norm_arg_test(32, 64);
|
||||||
|
norm_arg_test(64, 32);
|
||||||
|
norm_arg_test(64, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user