163 secp256k1_scalar *term,
166 const secp256k1_scalar *randomizer,
169 const int use_h = idx >= ctx->
vec_len;
170 const size_t proof_idx = use_h ? idx - ctx->
vec_len : idx;
171 const size_t scalar_idx = proof_idx / proof->
block_size;
172 const size_t local_idx = proof_idx % proof->
block_size;
173 secp256k1_scalar factor;
177 VERIFY_CHECK(scalar_idx < proof->final_grouping);
181 secp256k1_scalar yfactor;
183 secp256k1_scalar_mul(&factor, &factor, &yfactor);
184 secp256k1_scalar_mul(&factor, &factor, &proof->
b[scalar_idx]);
186 secp256k1_scalar_mul(&factor, &factor, &proof->
a[scalar_idx]);
188 secp256k1_scalar_mul(&factor, &factor, randomizer);
189 secp256k1_scalar_negate(term, &factor);
195 if (idx < 2 * ctx->vec_len) {
197 if (idx < ctx->vec_len) {
198 *pt = ctx->
geng[idx];
203 secp256k1_scalar_clear(sc);
204 for (i = 0; i < ctx->
n_proofs; i++) {
205 secp256k1_scalar term;
208 secp256k1_scalar rangeproof_offset;
212 secp256k1_scalar_add(&term, &term, &rangeproof_offset);
214 secp256k1_scalar_add(sc, sc, &term);
217 size_t real_idx = idx - 2 * ctx->
vec_len;
218 const size_t proof_idx = real_idx / (2 * ctx->
lg_vec_len);
220 *pt = ctx->
proof[proof_idx].
lr[real_idx];
222 *sc = ctx->
proof[proof_idx].
xsq[real_idx / 2];
226 secp256k1_scalar_mul(sc, sc, &ctx->
randomizer[proof_idx]);
232 secp256k1_scalar_clear(sc);
233 for (i = 0; i < ctx->
n_proofs; i++) {
234 secp256k1_scalar term;
238 secp256k1_scalar_add(sc, sc, &term);
241 size_t proof_idx = 0;
246 VERIFY_CHECK(proof_idx < ctx->n_proofs);
261 secp256k1_sha256 sha256;
263 unsigned char commit[32];
264 size_t total_n_points = 2 * vec_len + !!shared_g + 1;
266 secp256k1_scalar zero;
281 secp256k1_scalar_clear(&zero);
285 ecmult_data.
genh = gens->
gens + gens->
n / 2;
292 secp256k1_sha256_initialize(&sha256);
293 for (i = 0; i < n_proofs; i++) {
294 secp256k1_sha256_write(&sha256, proof[i].proof, plen);
295 secp256k1_sha256_write(&sha256, proof[i].commit, 32);
296 secp256k1_scalar_get_b32(commit, &proof[i].p_offs);
297 secp256k1_sha256_write(&sha256, commit, 32);
299 secp256k1_sha256_finalize(&sha256, commit);
301 secp256k1_scalar_clear(&ecmult_data.
p_offs);
302 for (i = 0; i < n_proofs; i++) {
303 const unsigned char *serproof = proof[i].
proof;
304 unsigned char proof_commit[32];
305 secp256k1_scalar dot;
307 secp256k1_scalar negprod;
316 secp256k1_scalar_set_b32(&dot, serproof, &overflow);
322 secp256k1_sha256_initialize(&sha256);
323 secp256k1_sha256_write(&sha256, proof[i].commit, 32);
324 secp256k1_sha256_write(&sha256, serproof, 32);
325 secp256k1_sha256_finalize(&sha256, proof_commit);
329 for (j = 0; j < n_ab; j++) {
331 secp256k1_scalar_set_b32(&ab[j], serproof, &overflow);
344 ecmult_data.
proof[i].
a[j] = ab[j];
348 secp256k1_sha256_initialize(&sha256);
349 secp256k1_sha256_write(&sha256, commit, 32);
350 secp256k1_sha256_finalize(&sha256, commit);
351 secp256k1_scalar_set_b32(&ecmult_data.
randomizer[i], commit, &overflow);
352 if (overflow || secp256k1_scalar_is_zero(&ecmult_data.
randomizer[i])) {
359 secp256k1_scalar_set_b32(&x, proof_commit, &overflow);
360 if (overflow || secp256k1_scalar_is_zero(&x)) {
364 secp256k1_scalar_negate(&negprod, &negprod);
365 secp256k1_scalar_add(&negprod, &negprod, &dot);
366 secp256k1_scalar_mul(&x, &x, &negprod);
367 secp256k1_scalar_add(&x, &x, &proof[i].p_offs);
369 secp256k1_scalar_mul(&x, &x, &ecmult_data.
randomizer[i]);
370 secp256k1_scalar_add(&ecmult_data.
p_offs, &ecmult_data.
p_offs, &x);
375 if (!secp256k1_scalar_is_zero(&negprod)) {
387 for (j = 1; j <= ecmult_data.
lg_vec_len; j++) {
391 for (j = 0; j < ecmult_data.
lg_vec_len; j++) {
392 const size_t lidx = 2 * j;
393 const size_t ridx = 2 * j + 1;
403 secp256k1_scalar_set_b32(&ecmult_data.
proof[i].
x[j], proof_commit, &overflow);
404 if (overflow || secp256k1_scalar_is_zero(&ecmult_data.
proof[i].
x[j])) {
408 secp256k1_scalar_inverse_var(&ecmult_data.
proof[i].
xinv[j], &ecmult_data.
proof[i].
x[j]);
409 secp256k1_scalar_sqr(&ecmult_data.
proof[i].
xsq[j], &ecmult_data.
proof[i].
x[j]);
420 return secp256k1_gej_is_infinity(&r);
567static int secp256k1_bulletproof_inner_product_real_prove_impl(
const secp256k1_ecmult_context *ecmult_ctx, secp256k1_scratch *scratch, secp256k1_ge *out_pt,
size_t *pt_idx,
const secp256k1_ge *g, secp256k1_ge *geng, secp256k1_ge *genh, secp256k1_scalar *a_arr, secp256k1_scalar *b_arr,
const secp256k1_scalar *yinv,
const secp256k1_scalar *ux,
const size_t n,
unsigned char *commit) {
570 secp256k1_scalar zero;
581 secp256k1_scalar_clear(&zero);
584 for (halfwidth = n / 2, i = 0; halfwidth >
IP_AB_SCALARS / 4; halfwidth /= 2, i++) {
585 secp256k1_gej tmplj, tmprj;
592 secp256k1_scalar_clear(&pfdata.
g_sc);
593 for (j = 0; j < halfwidth; j++) {
594 secp256k1_scalar prod;
595 secp256k1_scalar_mul(&prod, &a_arr[2*j], &b_arr[2*j + 1]);
596 secp256k1_scalar_add(&pfdata.
g_sc, &pfdata.
g_sc, &prod);
598 secp256k1_scalar_mul(&pfdata.
g_sc, &pfdata.
g_sc, ux);
600 secp256k1_scalar_set_int(&pfdata.
yinvn, 1);
602 secp256k1_ge_set_gej(&out_pt[(*pt_idx)++], &tmplj);
605 secp256k1_scalar_clear(&pfdata.g_sc);
606 for (j = 0; j < halfwidth; j++) {
607 secp256k1_scalar prod;
608 secp256k1_scalar_mul(&prod, &a_arr[2*j + 1], &b_arr[2*j]);
609 secp256k1_scalar_add(&pfdata.g_sc, &pfdata.g_sc, &prod);
611 secp256k1_scalar_mul(&pfdata.g_sc, &pfdata.g_sc, ux);
613 secp256k1_scalar_set_int(&pfdata.yinvn, 1);
615 secp256k1_ge_set_gej(&out_pt[(*pt_idx)++], &tmprj);
619 secp256k1_scalar_set_b32(&pfdata.x[i], commit, &overflow);
620 if (overflow || secp256k1_scalar_is_zero(&pfdata.x[i])) {
623 secp256k1_scalar_inverse_var(&pfdata.xinv[i], &pfdata.x[i]);
626 for (j = 0; j < halfwidth; j++) {
627 secp256k1_scalar tmps;
628 secp256k1_scalar_mul(&a_arr[2*j], &a_arr[2*j], &pfdata.x[i]);
629 secp256k1_scalar_mul(&tmps, &a_arr[2*j + 1], &pfdata.xinv[i]);
630 secp256k1_scalar_add(&a_arr[j], &a_arr[2*j], &tmps);
632 secp256k1_scalar_mul(&b_arr[2*j], &b_arr[2*j], &pfdata.xinv[i]);
633 secp256k1_scalar_mul(&tmps, &b_arr[2*j + 1], &pfdata.x[i]);
634 secp256k1_scalar_add(&b_arr[j], &b_arr[2*j], &tmps);
639 if ((n > 2048 && i == 3) || (n > 128 && i == 2) || (n > 32 && i == 1)) {
640 secp256k1_scalar yinv2;
642 for (j = 0; j < halfwidth; j++) {
645 pfdata.geng += 2u << i;
646 secp256k1_ge_set_gej(&geng[j], &rj);
647 secp256k1_scalar_set_int(&pfdata.yinvn, 1);
649 pfdata.genh += 2u << i;
650 secp256k1_ge_set_gej(&genh[j], &rj);
653 secp256k1_scalar_sqr(&yinv2, yinv);
654 for (j = 0; j < i; j++) {
655 secp256k1_scalar_sqr(&yinv2, &yinv2);
657 if (!
secp256k1_bulletproof_inner_product_real_prove_impl(ecmult_ctx, scratch, out_pt, pt_idx, g, geng, genh, a_arr, b_arr, &yinv2, ux, halfwidth, commit)) {
667 secp256k1_sha256 sha256;
669 unsigned char commit[32];
670 secp256k1_scalar *a_arr;
671 secp256k1_scalar *b_arr;
672 secp256k1_ge *out_pt;
678 secp256k1_scalar dot;
691 for (i = 0; i < n; i++) {
692 cb(&a[i], NULL, 2*i, cb_data);
693 cb(&b[i], NULL, 2*i+1, cb_data);
697 secp256k1_scalar_get_b32(proof, &dot);
699 for (i = 0; i < n; i++) {
700 secp256k1_scalar_get_b32(&proof[32 * (i + 1)], &a[i]);
701 secp256k1_scalar_get_b32(&proof[32 * (i + n + 1)], &b[i]);
703 VERIFY_CHECK(*proof_len == 32 * (2 * n + 1));
717 VERIFY_CHECK(a_arr != NULL);
718 VERIFY_CHECK(b_arr != NULL);
719 VERIFY_CHECK(gens != NULL);
721 for (i = 0; i < n; i++) {
722 cb(&a_arr[i], NULL, 2*i, cb_data);
723 cb(&b_arr[i], NULL, 2*i+1, cb_data);
724 geng[i] = gens->
gens[i];
725 genh[i] = gens->
gens[i + gens->
n/2];
730 secp256k1_scalar_get_b32(proof, &dot);
733 secp256k1_sha256_initialize(&sha256);
734 secp256k1_sha256_write(&sha256, commit_inp, 32);
735 secp256k1_sha256_write(&sha256, proof, 32);
736 secp256k1_sha256_finalize(&sha256, commit);
740 secp256k1_scalar_set_b32(&ux, commit, &overflow);
741 if (overflow || secp256k1_scalar_is_zero(&ux)) {
747 if (!
secp256k1_bulletproof_inner_product_real_prove_impl(ecmult_ctx, scratch, out_pt, &pt_idx, gens->
blinding_gen, geng, genh, a_arr, b_arr, yinv, &ux, n, commit)) {
753 for (i = 0; i < half_n_ab; i++) {
754 secp256k1_scalar_get_b32(&proof[32 * i], &a_arr[i]);
755 secp256k1_scalar_get_b32(&proof[32 * (i + half_n_ab)], &b_arr[i]);
757 proof += 64 * half_n_ab;
static int secp256k1_bulletproof_inner_product_real_prove_impl(const secp256k1_ecmult_context *ecmult_ctx, secp256k1_scratch *scratch, secp256k1_ge *out_pt, size_t *pt_idx, const secp256k1_ge *g, secp256k1_ge *geng, secp256k1_ge *genh, secp256k1_scalar *a_arr, secp256k1_scalar *b_arr, const secp256k1_scalar *yinv, const secp256k1_scalar *ux, const size_t n, unsigned char *commit)