From 8638f0e0cecad113e11b826a41bed1fe7a8d3b85 Mon Sep 17 00:00:00 2001 From: sanket1729 Date: Wed, 26 Oct 2022 00:08:35 -0700 Subject: [PATCH] Add internal BP++ commit API --- .../bulletproofs_pp_norm_product_impl.h | 66 +++++++++++++++++++ src/modules/bulletproofs/bulletproofs_util.h | 1 + 2 files changed, 67 insertions(+) diff --git a/src/modules/bulletproofs/bulletproofs_pp_norm_product_impl.h b/src/modules/bulletproofs/bulletproofs_pp_norm_product_impl.h index 1e17ed34..f366fea2 100644 --- a/src/modules/bulletproofs/bulletproofs_pp_norm_product_impl.h +++ b/src/modules/bulletproofs/bulletproofs_pp_norm_product_impl.h @@ -78,4 +78,70 @@ static void secp256k1_bulletproofs_powers_of_r(secp256k1_scalar *powers, const s secp256k1_scalar_sqr(&powers[i], &powers[i - 1]); } } + +typedef struct ecmult_bp_commit_cb_data { + const secp256k1_scalar *n; + const secp256k1_ge *g; + const secp256k1_scalar *l; + size_t g_len; +} ecmult_bp_commit_cb_data; + +static int ecmult_bp_commit_cb(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *cbdata) { + ecmult_bp_commit_cb_data *data = (ecmult_bp_commit_cb_data*) cbdata; + *pt = data->g[idx]; + if (idx < data->g_len) { + *sc = data->n[idx]; + } else { + *sc = data->l[idx - data->g_len]; + } + return 1; +} + +/* Create a commitment `commit` = vG + n_vec*G_vec + l_vec*H_vec where + v = |n_vec*n_vec|_q + . |w|_q denotes q-weighted norm of w and + denotes inner product of l and r. +*/ +static int secp256k1_bulletproofs_commit( + const secp256k1_context* ctx, + secp256k1_scratch_space* scratch, + secp256k1_ge* commit, + const secp256k1_bulletproofs_generators* g_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_scalar* q +) { + secp256k1_scalar v, l_c; + /* First n_vec_len generators are Gs, rest are Hs*/ + VERIFY_CHECK(g_vec->n == (n_vec_len + l_vec_len)); + VERIFY_CHECK(l_vec_len == c_vec_len); + + /* It is possible to extend to support n_vec and c_vec to not be power of + two. For the initial iterations of the code, we stick to powers of two for simplicity.*/ + VERIFY_CHECK(secp256k1_is_power_of_two(n_vec_len)); + VERIFY_CHECK(secp256k1_is_power_of_two(c_vec_len)); + + /* Compute v = n_vec*n_vec*q + l_vec*c_vec */ + secp256k1_weighted_scalar_inner_product(&v, n_vec, 0 /*a offset */, n_vec, 0 /*b offset*/, 1 /*step*/, n_vec_len, q); + secp256k1_scalar_inner_product(&l_c, l_vec, 0 /*a offset */, c_vec, 0 /*b offset*/, 1 /*step*/, l_vec_len); + secp256k1_scalar_add(&v, &v, &l_c); + + { + ecmult_bp_commit_cb_data data; + secp256k1_gej commitj; + data.g = g_vec->gens; + data.n = n_vec; + data.l = l_vec; + data.g_len = n_vec_len; + + if (!secp256k1_ecmult_multi_var(&ctx->error_callback, scratch, &commitj, &v, ecmult_bp_commit_cb, (void*) &data, n_vec_len + l_vec_len)) { + return 0; + } + secp256k1_ge_set_gej_var(commit, &commitj); + } + return 1; +} #endif diff --git a/src/modules/bulletproofs/bulletproofs_util.h b/src/modules/bulletproofs/bulletproofs_util.h index 2bdae23f..07f6fc62 100644 --- a/src/modules/bulletproofs/bulletproofs_util.h +++ b/src/modules/bulletproofs/bulletproofs_util.h @@ -10,6 +10,7 @@ #include "field.h" #include "group.h" #include "hash.h" +#include "eckey.h" /* Outputs a pair of points, amortizing the parity byte between them * Assumes both points' coordinates have been normalized.