PRCYCoin  2.0.0.7rc1
P2P Digital Currency
circuit_impl.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (c) 2018 Andrew Poelstra *
3  * Distributed under the MIT software license, see the accompanying *
4  * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
5  **********************************************************************/
6 
7 #ifndef SECP256K1_MODULE_BULLETPROOF_CIRCUIT_IMPL
8 #define SECP256K1_MODULE_BULLETPROOF_CIRCUIT_IMPL
9 
12 #include "group.h"
13 
14 #include <stdlib.h>
15 
16 typedef struct {
22 
23 static int secp256k1_bulletproof_circuit_abgh_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data) {
25  const int is_g = idx % 2 == 0;
26 
27  (void) pt;
28  if (is_g) {
29  /* l(x) */
30  if (idx / 2 < ctx->assn->n_gates) {
31  secp256k1_scalar_mul(sc, &ctx->comp_circ->l3[idx / 2], &ctx->x);
32  secp256k1_scalar_add(sc, sc, &ctx->assn->ao[idx / 2]);
33  secp256k1_scalar_mul(sc, sc, &ctx->x);
34  } else {
35  secp256k1_scalar_mul(sc, &ctx->comp_circ->l3[idx / 2], &ctx->x2);
36  }
37  secp256k1_scalar_add(sc, sc, &ctx->comp_circ->l1[idx / 2]);
38  secp256k1_scalar_mul(sc, sc, &ctx->x);
39  } else {
40  /* r(x) */
41  secp256k1_scalar_mul(sc, &ctx->comp_circ->r3[idx / 2], &ctx->x2);
42  secp256k1_scalar_add(sc, sc, &ctx->comp_circ->r1[idx / 2]);
43  secp256k1_scalar_mul(sc, sc, &ctx->x);
44  secp256k1_scalar_add(sc, sc, &ctx->comp_circ->r0[idx / 2]);
45  }
46 
47  return 1;
48 }
49 
50 /* Proof format:
51  *
52  * Serialized scalars (32 bytes) t, tau_x, mu, a, b
53  * Serialized points (bit array of parity followed by 32 bytes): A_I, A_O, S, T_1, T_3, T_4, T_5, T_6, [inner product proof points]
54  */
55 static int secp256k1_bulletproof_relation66_prove_impl(const secp256k1_ecmult_context *ecmult_ctx, secp256k1_scratch *scratch, unsigned char *proof, size_t *plen, const secp256k1_bulletproof_circuit_assignment *assn, const secp256k1_ge *commitp, const secp256k1_scalar *blinds, size_t nc, const secp256k1_ge *value_gen, const secp256k1_bulletproof_circuit *circ, const secp256k1_bulletproof_generators *gens, const unsigned char *nonce, const unsigned char *extra_commit, size_t extra_commit_len) {
59  unsigned char commit[32] = {0};
60  secp256k1_scalar alpha, beta, rho, mu;
61  secp256k1_scalar tau1, tau3, tau4, tau5, tau6, taux; /* tau2 missing on purpose */
62  secp256k1_scalar t[7]; /* t[1..6] are coefficients; t[0] is the polynomial evaluated at x */
63  secp256k1_scalar tauv; /* <z, WV*gamma> term in eq (73) */
64  secp256k1_scalar x, xn, y, yinv, z;
65  secp256k1_scalar tmp;
66  secp256k1_gej aij, aoj, sj;
67  secp256k1_ge tmpge;
68  secp256k1_ge out_pt[8];
69  int overflow;
70  size_t i;
71 
72  if (assn->n_gates > circ->n_gates || assn->n_commits > circ->n_commits || nc != circ->n_commits) {
73  return 0;
74  }
75  if (*plen < 64 + 256 + 1) { /* inner product argument will do a more precise check and assignment */
76  return 0;
77  }
78 
79  /* Commit to all input data */
80  if (nc != 0) {
81  secp256k1_bulletproof_update_commit_n(commit, commitp, nc);
82  }
83  secp256k1_bulletproof_update_commit_n(commit, value_gen, 1);
84  /* TODO commit to circuit */
85  if (extra_commit != NULL) {
86  secp256k1_sha256_initialize(&sha256);
87  secp256k1_sha256_write(&sha256, commit, 32);
88  secp256k1_sha256_write(&sha256, extra_commit, extra_commit_len);
89  secp256k1_sha256_finalize(&sha256, commit);
90  }
91 
92  /* Setup, generate randomness */
93  secp256k1_scalar_chacha20(&alpha, &beta, nonce, 0);
94  secp256k1_scalar_chacha20(&rho, &tau1, nonce, 1);
95  secp256k1_scalar_chacha20(&tau3, &tau4, nonce, 2); /* t2 will be generated deterministically */
96  secp256k1_scalar_chacha20(&tau5, &tau6, nonce, 3);
97 
98  /* Compute blinding factors in comp_circ.l3 and comp_circ.r3 */
100  return 0;
101  }
102  comp_circ = secp256k1_bulletproof_pf_slsr(scratch, circ, nonce);
103 
104  /* Compute A_I, A_O, S */
105  secp256k1_ecmult_const(&aij, gens->blinding_gen, &alpha, 256);
106  for (i = 0; i < circ->n_bits; i++) {
107  secp256k1_ge aterm = gens->gens[i + gens->n/2];
108 
109  secp256k1_ge_neg(&aterm, &aterm);
110  secp256k1_fe_cmov(&aterm.x, &gens->gens[i].x, secp256k1_scalar_is_one(&assn->al[i]));
111  secp256k1_fe_cmov(&aterm.y, &gens->gens[i].y, secp256k1_scalar_is_one(&assn->al[i]));
112  secp256k1_gej_add_ge(&aij, &aij, &aterm);
113  }
114  secp256k1_ge_set_gej(&tmpge, &aij);
115  secp256k1_bulletproof_vector_commit(&aij, assn->al + circ->n_bits, gens->gens + circ->n_bits, assn->n_gates - circ->n_bits, NULL, NULL);
116  secp256k1_gej_add_ge(&aij, &aij, &tmpge);
117  secp256k1_ge_set_gej(&tmpge, &aij);
118  secp256k1_bulletproof_vector_commit(&aij, assn->ar + circ->n_bits, gens->gens + circ->n_bits + gens->n/2, assn->n_gates - circ->n_bits, NULL, NULL);
119  secp256k1_gej_add_ge(&aij, &aij, &tmpge);
120 
121  secp256k1_bulletproof_vector_commit(&aoj, assn->ao + circ->n_bits, gens->gens + circ->n_bits, assn->n_gates - circ->n_bits, &beta, gens->blinding_gen);
122 
123  secp256k1_ecmult_const(&sj, gens->blinding_gen, &rho, 256);
124  for (i = 0; i < circ->n_gates; i++) {
125  secp256k1_gej termj;
126  secp256k1_ge term;
127 
128  secp256k1_ecmult_const(&termj, &gens->gens[i], &comp_circ->l3[i], 256);
129  secp256k1_ge_set_gej(&term, &termj);
130  secp256k1_gej_add_ge(&sj, &sj, &term);
131  secp256k1_ecmult_const(&termj, &gens->gens[i + gens->n/2], &comp_circ->r3[i], 256);
132  secp256k1_ge_set_gej(&term, &termj);
133  secp256k1_gej_add_ge(&sj, &sj, &term);
134  }
135 
136  /* get challenges y and z */
137  secp256k1_ge_set_gej(&out_pt[0], &aij);
138  secp256k1_ge_set_gej(&out_pt[1], &aoj);
139  secp256k1_ge_set_gej(&out_pt[2], &sj);
140 
141  secp256k1_bulletproof_update_commit_n(commit, &out_pt[0], 3);
142  secp256k1_scalar_set_b32(&y, commit, &overflow);
143  if (overflow || secp256k1_scalar_is_zero(&y)) {
144  secp256k1_scratch_deallocate_frame(scratch);
145  return 0;
146  }
147  secp256k1_bulletproof_update_commit_n(commit, NULL, 0);
148  secp256k1_scalar_set_b32(&z, commit, &overflow);
149  if (overflow || secp256k1_scalar_is_zero(&z)) {
150  secp256k1_scratch_deallocate_frame(scratch);
151  return 0;
152  }
153  secp256k1_scalar_inverse_var(&yinv, &y);
154 
155  /* complete circuit compression */
156  secp256k1_bulletproof_pf_compress_circuit(comp_circ, circ, assn, &y, &yinv, &z);
157 
158  /* Compute coefficients t[1..6] */
159  /* Observe that
160  * l = l1 * X + l2 * X^2 + l3 * X^3
161  * r = r0 + r1 * X + r3 * X^3
162  * with l2 = ao, so that
163  * t1 = <l1, r0>
164  * t2 = <l1, r1> + <ao, r0>
165  * t3 = <ao, r1> + <l3, r0>
166  * t4 = <l3, r1> + <l1, r3>
167  * t5 = <ao, r3>
168  * t6 = <l3, r3>
169  * So we compute these terms and add them to t1,t3,etc as running sums.
170  */
171 
172  for (i = 0; i < 6; i++) {
173  secp256k1_scalar_clear(&t[i + 1]);
174  }
175  for (i = 0; i < circ->n_gates; i++) {
176  secp256k1_scalar ao;
177 
178  if (i < assn->n_gates) {
179  ao = assn->ao[i];
180  } else {
181  secp256k1_scalar_clear(&ao);
182  }
183 
184  /* Now that we have the individual coefficients, compute the dot product */
185  secp256k1_scalar_mul(&tmp, &comp_circ->l1[i], &comp_circ->r0[i]);
186  secp256k1_scalar_add(&t[1], &t[1], &tmp);
187 
188  secp256k1_scalar_mul(&tmp, &comp_circ->l1[i], &comp_circ->r1[i]);
189  secp256k1_scalar_add(&t[2], &t[2], &tmp);
190  secp256k1_scalar_mul(&tmp, &ao, &comp_circ->r0[i]);
191  secp256k1_scalar_add(&t[2], &t[2], &tmp);
192 
193  secp256k1_scalar_mul(&tmp, &ao, &comp_circ->r1[i]);
194  secp256k1_scalar_add(&t[3], &t[3], &tmp);
195  secp256k1_scalar_mul(&tmp, &comp_circ->l3[i], &comp_circ->r0[i]);
196  secp256k1_scalar_add(&t[3], &t[3], &tmp);
197 
198  secp256k1_scalar_mul(&tmp, &comp_circ->l3[i], &comp_circ->r1[i]);
199  secp256k1_scalar_add(&t[4], &t[4], &tmp);
200  secp256k1_scalar_mul(&tmp, &comp_circ->l1[i], &comp_circ->r3[i]);
201  secp256k1_scalar_add(&t[4], &t[4], &tmp);
202 
203  secp256k1_scalar_mul(&tmp, &ao, &comp_circ->r3[i]);
204  secp256k1_scalar_add(&t[5], &t[5], &tmp);
205 
206  secp256k1_scalar_mul(&tmp, &comp_circ->l3[i], &comp_circ->r3[i]);
207  secp256k1_scalar_add(&t[6], &t[6], &tmp);
208  }
209 
210  /* Compute T1, T3, T4, T5, T6 */
211  secp256k1_bulletproof_vector_commit(&aij, &t[1], value_gen, 1, &tau1, gens->blinding_gen);
212  secp256k1_ge_set_gej(&out_pt[3], &aij);
213 
214  secp256k1_bulletproof_vector_commit(&aij, &t[3], value_gen, 1, &tau3, gens->blinding_gen);
215  secp256k1_ge_set_gej(&out_pt[4], &aij);
216 
217  secp256k1_bulletproof_vector_commit(&aij, &t[4], value_gen, 1, &tau4, gens->blinding_gen);
218  secp256k1_ge_set_gej(&out_pt[5], &aij);
219 
220  secp256k1_bulletproof_vector_commit(&aij, &t[5], value_gen, 1, &tau5, gens->blinding_gen);
221  secp256k1_ge_set_gej(&out_pt[6], &aij);
222 
223  secp256k1_bulletproof_vector_commit(&aij, &t[6], value_gen, 1, &tau6, gens->blinding_gen);
224  secp256k1_ge_set_gej(&out_pt[7], &aij);
225 
226  /* Compute x, tau_x, mu and t */
227  secp256k1_bulletproof_update_commit_n(commit, &out_pt[3], 5);
228  secp256k1_scalar_set_b32(&x, commit, &overflow);
229  if (overflow || secp256k1_scalar_is_zero(&x)) {
230  secp256k1_scratch_deallocate_frame(scratch);
231  return 0;
232  }
233 
234  secp256k1_scalar_mul(&alpha, &alpha, &x);
235  secp256k1_scalar_mul(&tau1, &tau1, &x);
236 
237  secp256k1_scalar_sqr(&xn, &x);
238  secp256k1_scalar_mul(&beta, &beta, &xn);
239  secp256k1_scalar_clear(&tauv);
240  for (i = 0; i < circ->n_commits; i++) {
241  secp256k1_scalar zwv;
242  secp256k1_scalar_mul(&zwv, &comp_circ->wv[i], &blinds[i]);
243  secp256k1_scalar_add(&tauv, &tauv, &zwv);
244  }
245  secp256k1_scalar_mul(&tauv, &tauv, &xn);
246 
247  secp256k1_scalar_mul(&xn, &xn, &x);
248  secp256k1_scalar_mul(&rho, &rho, &xn);
249  secp256k1_scalar_mul(&tau3, &tau3, &xn);
250 
251  secp256k1_scalar_mul(&xn, &xn, &x);
252  secp256k1_scalar_mul(&tau4, &tau4, &xn);
253 
254  secp256k1_scalar_mul(&xn, &xn, &x);
255  secp256k1_scalar_mul(&tau5, &tau5, &xn);
256 
257  secp256k1_scalar_mul(&xn, &xn, &x);
258  secp256k1_scalar_mul(&tau6, &tau6, &xn);
259 
260  secp256k1_scalar_add(&taux, &tau1, &tauv);
261  secp256k1_scalar_add(&taux, &taux, &tau3);
262  secp256k1_scalar_add(&taux, &taux, &tau4);
263  secp256k1_scalar_add(&taux, &taux, &tau5);
264  secp256k1_scalar_add(&taux, &taux, &tau6);
265 
266  secp256k1_scalar_add(&mu, &alpha, &beta);
267  secp256k1_scalar_add(&mu, &mu, &rho);
268 
269  /* Negate taux and mu so verifier doesn't have to */
270  secp256k1_scalar_negate(&mu, &mu);
271  secp256k1_scalar_negate(&taux, &taux);
272 
273  /* Encode circuit stuff */
274  secp256k1_scalar_get_b32(&proof[0], &taux);
275  secp256k1_scalar_get_b32(&proof[32], &mu);
276  secp256k1_bulletproof_serialize_points(&proof[64], out_pt, 8);
277 
278  /* Mix these scalars into the hash so the input to the inner product proof is fixed */
279  secp256k1_sha256_initialize(&sha256);
280  secp256k1_sha256_write(&sha256, commit, 32);
281  secp256k1_sha256_write(&sha256, proof, 64);
282  secp256k1_sha256_finalize(&sha256, commit);
283 
284  /* Compute l and r, do inner product proof */
285  abgh_data.x = x;
286  secp256k1_scalar_sqr(&abgh_data.x2, &x);
287  abgh_data.comp_circ = comp_circ;
288  abgh_data.assn = assn;
289  *plen -= 64 + 256 + 1;
290  if (secp256k1_bulletproof_inner_product_prove_impl(ecmult_ctx, scratch, &proof[64 + 256 + 1], plen, gens, &yinv, circ->n_gates, secp256k1_bulletproof_circuit_abgh_callback, (void *) &abgh_data, commit) == 0) {
291  secp256k1_scratch_deallocate_frame(scratch);
292  return 0;
293  }
294  *plen += 64 + 256 + 1;
295 
296  secp256k1_scratch_deallocate_frame(scratch);
297  return 1;
298 }
299 
300 typedef struct {
306  /* state tracking */
307  size_t count;
308  /* eq 83 */
309  secp256k1_ge age[3];
310  /* eq 82 */
312  secp256k1_ge tge[5];
316  size_t n_gates;
317  size_t n_commits;
319 
320 static int secp256k1_bulletproof_circuit_vfy_callback(secp256k1_scalar *sc, secp256k1_ge *pt, secp256k1_scalar *randomizer, size_t idx, void *data) {
322 
323  if (idx < ctx->n_gates) { /* Gi */
324  secp256k1_scalar_mul(sc, &ctx->comp_circ->wr[idx], &ctx->x);
325  secp256k1_scalar_mul(sc, sc, randomizer);
326  } else if (idx < 2 * ctx->n_gates) { /* Hi */
327  secp256k1_scalar dot;
328  idx -= ctx->n_gates;
329 
330  secp256k1_scalar_set_int(&dot, 1);
331  secp256k1_scalar_negate(&dot, &dot);
332  secp256k1_scalar_add(sc, &ctx->comp_circ->wl_wo[idx], &dot);
333 
334  secp256k1_scalar_mul(sc, sc, randomizer);
335  /* return a (scalar, point) pair to add to the multiexp */
336  } else {
337  switch(ctx->count) {
338  /* g^(x^2(k + <z^Q, c>) - t) (82) */
339  case 0: {
340  secp256k1_scalar_negate(sc, &ctx->t);
341  secp256k1_scalar_add(sc, sc, &ctx->comp_circ->c_sum);
342  secp256k1_scalar_mul(sc, sc, &ctx->randomizer82);
343  *pt = *ctx->value_gen;
344  break;
345  }
346  /* A_I^x (83) */
347  case 1:
348  *sc = ctx->x;
349  *pt = ctx->age[0];
350  break;
351  /* A_O^(x^2) (83) */
352  case 2:
353  secp256k1_scalar_sqr(sc, &ctx->x);
354  *pt = ctx->age[1];
355  break;
356  /* S^(x^3) (83) */
357  case 3:
358  secp256k1_scalar_sqr(sc, &ctx->x); /* TODO cache previous squaring */
359  secp256k1_scalar_mul(sc, sc, &ctx->x);
360  *pt = ctx->age[2];
361  break;
362  /* T_1^x (82) */
363  case 4:
364  secp256k1_scalar_mul(sc, &ctx->x, &ctx->randomizer82);
365  *pt = ctx->tge[0];
366  break;
367  default:
368  if (ctx->count < 9) {
369  size_t i;
370  secp256k1_scalar_mul(sc, &ctx->x, &ctx->randomizer82);
371  for (i = 0; i < ctx->count - 3; i++) {
372  secp256k1_scalar_mul(sc, sc, &ctx->x);
373  }
374  *pt = ctx->tge[ctx->count - 4];
375  } else if (ctx->count < 9 + ctx->n_commits) {
376  /* V^(x^2 . (z^Q . W_V)) (82) */
377  secp256k1_scalar_mul(sc, &ctx->comp_circ->wv[ctx->count - 9], &ctx->randomizer82);
378  *pt = ctx->commits[ctx->count - 9];
379  } else {
380  VERIFY_CHECK(!"bulletproof: too many points added by circuit_verify_impl to inner_product_verify_impl");
381  }
382  }
383  secp256k1_scalar_mul(sc, sc, randomizer);
384  ctx->count++;
385  }
386  return 1;
387 }
388 
389 static int secp256k1_bulletproof_relation66_verify_impl(const secp256k1_ecmult_context *ecmult_ctx, secp256k1_scratch *scratch, const unsigned char* const* proof, size_t n_proofs, size_t plen, const secp256k1_ge* const* commitp, size_t *nc, const secp256k1_ge *value_gen, const secp256k1_bulletproof_circuit* const* circ, const secp256k1_bulletproof_generators *gens, const unsigned char **extra_commit, size_t *extra_commit_len) {
390  int ret;
393  size_t i;
394 
395  /* sanity-check input */
396  if (plen < 64 + 256 + 1) { /* inner product argument will do a more precise check */
397  return 0;
398  }
399  if (plen > SECP256K1_BULLETPROOF_MAX_PROOF) {
400  return 0;
401  }
402 
403  if (!secp256k1_scratch_allocate_frame(scratch, n_proofs * (sizeof(*ecmult_data) + sizeof(*innp_ctx)), 2)) {
404  return 0;
405  }
406  ecmult_data = (secp256k1_bulletproof_circuit_vfy_ecmult_context *)secp256k1_scratch_alloc(scratch, n_proofs * sizeof(*ecmult_data));
407  innp_ctx = (secp256k1_bulletproof_innerproduct_context *)secp256k1_scratch_alloc(scratch, n_proofs * sizeof(*innp_ctx));
408  if (!secp256k1_bulletproof_vfy_compressed_circuit_allocate_frame(scratch, circ[0], n_proofs)) {
409  secp256k1_scratch_deallocate_frame(scratch);
410  return 0;
411  }
412 
413  for (i = 0; i < n_proofs; i++) {
415  unsigned char randomizer82[32] = {0}; /* randomizer for eq (82) so we can add it to eq (83) to save a separate multiexp */
416  unsigned char commit[32] = {0};
417  secp256k1_scalar taux, mu;
419  int overflow;
420 
421  /* Commit to all input data: pedersen commit, asset generator, extra_commit */
422  if (nc != NULL) {
423  secp256k1_bulletproof_update_commit_n(commit, commitp[i], nc[i]);
424  }
425  secp256k1_bulletproof_update_commit_n(commit, value_gen, 1);
426  if (extra_commit != NULL && extra_commit[i] != NULL) {
427  secp256k1_sha256_initialize(&sha256);
428  secp256k1_sha256_write(&sha256, commit, 32);
429  secp256k1_sha256_write(&sha256, extra_commit[i], extra_commit_len[i]);
430  secp256k1_sha256_finalize(&sha256, commit);
431  }
432 
433  /* Deserialize everything */
434  secp256k1_bulletproof_deserialize_point(&ecmult_data[i].age[0], &proof[i][64], 0, 8);
435  secp256k1_bulletproof_deserialize_point(&ecmult_data[i].age[1], &proof[i][64], 1, 8);
436  secp256k1_bulletproof_deserialize_point(&ecmult_data[i].age[2], &proof[i][64], 2, 8);
437  secp256k1_bulletproof_deserialize_point(&ecmult_data[i].tge[0], &proof[i][64], 3, 8);
438  secp256k1_bulletproof_deserialize_point(&ecmult_data[i].tge[1], &proof[i][64], 4, 8);
439  secp256k1_bulletproof_deserialize_point(&ecmult_data[i].tge[2], &proof[i][64], 5, 8);
440  secp256k1_bulletproof_deserialize_point(&ecmult_data[i].tge[3], &proof[i][64], 6, 8);
441  secp256k1_bulletproof_deserialize_point(&ecmult_data[i].tge[4], &proof[i][64], 7, 8);
442 
443  /* Compute y, z, x */
444  secp256k1_bulletproof_update_commit_n(commit, ecmult_data[i].age, 3);
445  secp256k1_scalar_set_b32(&y, commit, &overflow);
446  if (overflow || secp256k1_scalar_is_zero(&y)) {
447  secp256k1_scratch_deallocate_frame(scratch);
448  secp256k1_scratch_deallocate_frame(scratch);
449  return 0;
450  }
451  ecmult_data[i].y = y;
452  secp256k1_scalar_inverse_var(&ecmult_data[i].yinv, &y); /* TODO batch this into another inverse */
453  secp256k1_bulletproof_update_commit_n(commit, NULL, 0);
454  secp256k1_scalar_set_b32(&ecmult_data[i].z, commit, &overflow);
455  if (overflow || secp256k1_scalar_is_zero(&ecmult_data[i].z)) {
456  secp256k1_scratch_deallocate_frame(scratch);
457  secp256k1_scratch_deallocate_frame(scratch);
458  return 0;
459  }
460 
461  secp256k1_bulletproof_update_commit_n(commit, ecmult_data[i].tge, 5);
462  secp256k1_scalar_set_b32(&ecmult_data[i].x, commit, &overflow);
463  if (overflow || secp256k1_scalar_is_zero(&ecmult_data[i].x)) {
464  secp256k1_scratch_deallocate_frame(scratch);
465  secp256k1_scratch_deallocate_frame(scratch);
466  return 0;
467  }
468 
469  ecmult_data[i].comp_circ = secp256k1_bulletproof_vfy_compress_circuit(scratch, circ[i], &ecmult_data[i].x, &ecmult_data[i].y, &ecmult_data[i].yinv, &ecmult_data[i].z);
470 
471  /* Extract scalars */
472  secp256k1_scalar_set_b32(&taux, &proof[i][0], &overflow);
473  if (overflow || secp256k1_scalar_is_zero(&taux)) {
474  secp256k1_scratch_deallocate_frame(scratch);
475  secp256k1_scratch_deallocate_frame(scratch);
476  return 0;
477  }
478  secp256k1_scalar_set_b32(&mu, &proof[i][32], &overflow);
479  if (overflow || secp256k1_scalar_is_zero(&mu)) {
480  secp256k1_scratch_deallocate_frame(scratch);
481  secp256k1_scratch_deallocate_frame(scratch);
482  return 0;
483  }
484  /* A little sketchy, we read t (l(x) . r(x)) off the front of the inner product proof,
485  * which we otherwise treat as a black box */
486  secp256k1_scalar_set_b32(&ecmult_data[i].t, &proof[i][64 + 256 + 1], &overflow);
487  if (overflow || secp256k1_scalar_is_zero(&ecmult_data[i].t)) {
488  secp256k1_scratch_deallocate_frame(scratch);
489  secp256k1_scratch_deallocate_frame(scratch);
490  return 0;
491  }
492 
493  /* Mix these scalars into the hash so the input to the inner product proof is fixed */
494  secp256k1_sha256_initialize(&sha256);
495  secp256k1_sha256_write(&sha256, commit, 32);
496  secp256k1_sha256_write(&sha256, proof[i], 64);
497  secp256k1_sha256_finalize(&sha256, commit);
498 
499  secp256k1_sha256_initialize(&sha256);
500  secp256k1_sha256_write(&sha256, commit, 32);
501  secp256k1_sha256_finalize(&sha256, randomizer82);
502  secp256k1_scalar_set_b32(&ecmult_data[i].randomizer82, randomizer82, &overflow);
503  if (overflow || secp256k1_scalar_is_zero(&ecmult_data[i].randomizer82)) {
504  secp256k1_scratch_deallocate_frame(scratch);
505  secp256k1_scratch_deallocate_frame(scratch);
506  return 0;
507  }
508 
509  /* compute exponent offsets */
510  ecmult_data[i].count = 0;
511 
512  ecmult_data[i].value_gen = value_gen;
513  if (nc == NULL) {
514  ecmult_data[i].commits = NULL;
515  } else {
516  ecmult_data[i].commits = commitp[i];
517  }
518  ecmult_data[i].n_gates = circ[i]->n_gates;
519  if (nc == NULL) {
520  ecmult_data[i].n_commits = 0;
521  } else {
522  ecmult_data[i].n_commits = nc[i];
523  }
524 
525  secp256k1_scalar_mul(&taux, &taux, &ecmult_data[i].randomizer82);
526  secp256k1_scalar_add(&mu, &mu, &taux);
527 
528  innp_ctx[i].proof = &proof[i][64 + 256 + 1];
529  innp_ctx[i].p_offs = mu;
530  innp_ctx[i].yinv = ecmult_data[i].yinv;
531  memcpy(innp_ctx[i].commit, commit, 32);
532  innp_ctx[i].rangeproof_cb = secp256k1_bulletproof_circuit_vfy_callback;
533  innp_ctx[i].rangeproof_cb_data = (void *) &ecmult_data[i];
534  innp_ctx[i].n_extra_rangeproof_points = 9 + ecmult_data[i].n_commits;
535  }
536  ret = secp256k1_bulletproof_inner_product_verify_impl(ecmult_ctx, scratch, gens, circ[0]->n_gates, innp_ctx, n_proofs, plen - (64 + 256 + 1), 1);
537  secp256k1_scratch_deallocate_frame(scratch);
538  secp256k1_scratch_deallocate_frame(scratch);
539  return ret;
540 }
541 
542 #endif
secp256k1_scratch_space_struct2
Definition: scratch.h:14
VERIFY_CHECK
#define VERIFY_CHECK(cond)
Definition: util.h:61
secp256k1_bulletproof_pf_compressed_circuit::l1
secp256k1_scalar * l1
Definition: circuit_compress_impl.h:23
secp256k1_bulletproof_circuit::n_commits
size_t n_commits
Definition: main_impl.h:33
secp256k1_ge::y
secp256k1_fe y
Definition: group.h:20
secp256k1_bulletproof_circuit::n_bits
size_t n_bits
Definition: main_impl.h:35
secp256k1_bulletproof_circuit_assignment::al
secp256k1_scalar * al
Definition: main_impl.h:48
secp256k1_bulletproof_generators::n
size_t n
Definition: main_impl.h:55
secp256k1_bulletproof_circuit_assignment::ar
secp256k1_scalar * ar
Definition: main_impl.h:49
secp256k1_bulletproof_innerproduct_context::p_offs
secp256k1_scalar p_offs
Definition: inner_product_impl.h:75
secp256k1_bulletproof_vfy_compressed_circuit::wl_wo
secp256k1_scalar * wl_wo
Definition: circuit_compress_impl.h:18
secp256k1_bulletproof_circuit_vfy_ecmult_context::t
secp256k1_scalar t
Definition: circuit_impl.h:313
secp256k1_bulletproof_circuit_vfy_ecmult_context
Definition: circuit_impl.h:300
sha256
Internal SHA-256 implementation.
Definition: sha256.cpp:15
secp256k1_bulletproof_innerproduct_context
Definition: inner_product_impl.h:73
memcpy
void * memcpy(void *a, const void *b, size_t c)
Definition: glibc_compat.cpp:15
secp256k1_bulletproof_pf_compressed_circuit::wv
secp256k1_scalar * wv
Definition: circuit_compress_impl.h:30
secp256k1_bulletproof_innerproduct_context::proof
const unsigned char * proof
Definition: inner_product_impl.h:74
secp256k1_bulletproof_circuit_vfy_ecmult_context::tge
secp256k1_ge tge[5]
Definition: circuit_impl.h:312
secp256k1_bulletproof_circuit_vfy_ecmult_context::value_gen
const secp256k1_ge * value_gen
Definition: circuit_impl.h:314
secp256k1_sha256
Definition: hash.h:13
secp256k1_bulletproof_pf_compressed_circuit::r0
secp256k1_scalar * r0
Definition: circuit_compress_impl.h:26
secp256k1_bulletproof_circuit_assignment::n_gates
size_t n_gates
Definition: main_impl.h:46
secp256k1_bulletproof_circuit_vfy_ecmult_context::comp_circ
const secp256k1_bulletproof_vfy_compressed_circuit * comp_circ
Definition: circuit_impl.h:305
SECP256K1_BULLETPROOF_MAX_PROOF
#define SECP256K1_BULLETPROOF_MAX_PROOF
Definition: secp256k1_bulletproofs.h:31
secp256k1_bulletproof_vfy_compressed_circuit_allocate_frame
int secp256k1_bulletproof_vfy_compressed_circuit_allocate_frame(secp256k1_scratch *scratch, const secp256k1_bulletproof_circuit *circ, size_t n_proofs)
Definition: circuit_compress_impl.h:75
secp256k1_bulletproof_vfy_compressed_circuit
Definition: circuit_compress_impl.h:12
secp256k1_bulletproof_generators::gens
secp256k1_ge * gens
Definition: main_impl.h:57
inner_product_impl.h
secp256k1_bulletproof_innerproduct_context::rangeproof_cb
secp256k1_bulletproof_vfy_callback * rangeproof_cb
Definition: inner_product_impl.h:78
secp256k1_bulletproof_vfy_compressed_circuit::c_sum
secp256k1_scalar c_sum
Definition: circuit_compress_impl.h:17
secp256k1_bulletproof_pf_compressed_circuit::l3
secp256k1_scalar * l3
Definition: circuit_compress_impl.h:25
secp256k1_scalar
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
secp256k1_bulletproof_circuit_vfy_ecmult_context::n_commits
size_t n_commits
Definition: circuit_impl.h:317
secp256k1_gej
A group element of the secp256k1 curve, in jacobian coordinates.
Definition: group.h:24
secp256k1_bulletproof_pf_compressed_circuit_allocate_frame
int secp256k1_bulletproof_pf_compressed_circuit_allocate_frame(secp256k1_scratch *scratch, const secp256k1_bulletproof_circuit *circ)
Definition: circuit_compress_impl.h:160
secp256k1_bulletproof_pf_compressed_circuit::r1
secp256k1_scalar * r1
Definition: circuit_compress_impl.h:27
secp256k1_bulletproof_vfy_compressed_circuit::wr
secp256k1_scalar * wr
Definition: circuit_compress_impl.h:19
secp256k1_bulletproof_innerproduct_context::rangeproof_cb_data
void * rangeproof_cb_data
Definition: inner_product_impl.h:79
secp256k1_bulletproof_circuit_vfy_ecmult_context::randomizer82
secp256k1_scalar randomizer82
Definition: circuit_impl.h:311
secp256k1_bulletproof_circuit_vfy_ecmult_context::commits
const secp256k1_ge * commits
Definition: circuit_impl.h:315
secp256k1_bulletproof_circuit_assignment::ao
secp256k1_scalar * ao
Definition: main_impl.h:50
secp256k1_bulletproof_pf_compressed_circuit
Definition: circuit_compress_impl.h:21
secp256k1_bulletproof_circuit_abgh_data::assn
const secp256k1_bulletproof_circuit_assignment * assn
Definition: circuit_impl.h:23
secp256k1_bulletproof_circuit_vfy_ecmult_context::x
secp256k1_scalar x
Definition: circuit_impl.h:301
secp256k1_bulletproof_circuit_vfy_ecmult_context::yinv
secp256k1_scalar yinv
Definition: circuit_impl.h:303
secp256k1_bulletproof_vfy_compressed_circuit::wv
secp256k1_scalar * wv
Definition: circuit_compress_impl.h:20
secp256k1_bulletproof_circuit::n_gates
size_t n_gates
Definition: main_impl.h:32
util.h
secp256k1_bulletproof_circuit_vfy_ecmult_context::z
secp256k1_scalar z
Definition: circuit_impl.h:304
secp256k1_bulletproof_pf_compress_circuit
void secp256k1_bulletproof_pf_compress_circuit(secp256k1_bulletproof_pf_compressed_circuit *ret, const secp256k1_bulletproof_circuit *circ, const secp256k1_bulletproof_circuit_assignment *assn, const secp256k1_scalar *y, const secp256k1_scalar *yinv, const secp256k1_scalar *z)
Definition: circuit_compress_impl.h:192
secp256k1_bulletproof_circuit_assignment
Definition: main_impl.h:45
secp256k1_bulletproof_generators::blinding_gen
secp256k1_ge * blinding_gen
Definition: main_impl.h:62
secp256k1_bulletproof_circuit_vfy_ecmult_context::y
secp256k1_scalar y
Definition: circuit_impl.h:302
secp256k1_bulletproof_circuit_assignment::n_commits
size_t n_commits
Definition: main_impl.h:47
secp256k1_bulletproof_innerproduct_context::n_extra_rangeproof_points
size_t n_extra_rangeproof_points
Definition: inner_product_impl.h:80
secp256k1_bulletproof_circuit_vfy_ecmult_context::count
size_t count
Definition: circuit_impl.h:307
secp256k1_bulletproof_pf_compressed_circuit::r3
secp256k1_scalar * r3
Definition: circuit_compress_impl.h:29
secp256k1_bulletproof_circuit
Definition: main_impl.h:31
secp256k1_bulletproof_circuit_vfy_ecmult_context::n_gates
size_t n_gates
Definition: circuit_impl.h:316
secp256k1_bulletproof_pf_slsr
secp256k1_bulletproof_pf_compressed_circuit * secp256k1_bulletproof_pf_slsr(secp256k1_scratch *scratch, const secp256k1_bulletproof_circuit *circ, const unsigned char *nonce)
Definition: circuit_compress_impl.h:169
secp256k1_ge::x
secp256k1_fe x
Definition: group.h:19
secp256k1_ecmult_context
Definition: ecmult.h:15
secp256k1_bulletproof_circuit_abgh_data::x2
secp256k1_scalar x2
Definition: circuit_impl.h:22
secp256k1_bulletproof_circuit_abgh_data::comp_circ
const secp256k1_bulletproof_pf_compressed_circuit * comp_circ
Definition: circuit_impl.h:24
secp256k1_bulletproof_innerproduct_context::yinv
secp256k1_scalar yinv
Definition: inner_product_impl.h:76
secp256k1_bulletproof_vfy_compress_circuit
secp256k1_bulletproof_vfy_compressed_circuit * secp256k1_bulletproof_vfy_compress_circuit(secp256k1_scratch *scratch, const secp256k1_bulletproof_circuit *circ, const secp256k1_scalar *x, const secp256k1_scalar *y, const secp256k1_scalar *yinv, const secp256k1_scalar *z)
Definition: circuit_compress_impl.h:83
secp256k1_ge
A group element of the secp256k1 curve, in affine coordinates.
Definition: group.h:14
secp256k1_bulletproof_generators
Definition: main_impl.h:54
secp256k1_bulletproof_circuit_vfy_ecmult_context::age
secp256k1_ge age[3]
Definition: circuit_impl.h:309
secp256k1_bulletproof_circuit_abgh_data::x
secp256k1_scalar x
Definition: circuit_impl.h:21
secp256k1_bulletproof_circuit_abgh_data
Definition: circuit_impl.h:16