PRCYCoin  2.0.0.7rc1
P2P Digital Currency
rangeproof_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_RANGEPROOF_IMPL
8 #define SECP256K1_MODULE_BULLETPROOF_RANGEPROOF_IMPL
9 
12 #include "group.h"
13 
14 #define MAX_NBITS 64
15 
16 typedef struct {
27  size_t n;
28  /* eq (61) stuff */
29  size_t count;
35  const uint64_t *min_value;
36  size_t n_commits;
40 
41 static int secp256k1_bulletproof_rangeproof_vfy_callback(secp256k1_scalar *sc, secp256k1_ge *pt, secp256k1_scalar *randomizer, size_t idx, void *data) {
43 
44  if (idx == 0) {
45  secp256k1_scalar_mul(&ctx->g_exponent, &ctx->negz, randomizer);
46  secp256k1_scalar_mul(&ctx->z_randomized, &ctx->z, randomizer);
47  }
48 
49  if (idx < ctx->n) {
50  *sc = ctx->g_exponent;
51  } else if (idx < 2 * ctx->n) {
52  const size_t nbits = ctx->n / ctx->n_commits;
53  const size_t commit_idx = (idx - ctx->n) / nbits;
54  const size_t bit_idx = (idx - ctx->n) % nbits;
55 
56  if (bit_idx == 0) {
57  size_t i;
58  secp256k1_scalar tmp;
59  secp256k1_scalar_mul(&tmp, &ctx->z, &ctx->yinvn);
60  secp256k1_scalar_sqr(&ctx->zsq, &ctx->z);
61  for (i = 0; i < commit_idx; i++) {
62  secp256k1_scalar_mul(&ctx->zsq, &ctx->zsq, &tmp);
63  }
64  secp256k1_scalar_mul(&ctx->zsq, &ctx->zsq, randomizer);
65  }
66  secp256k1_scalar_add(sc, &ctx->zsq, &ctx->z_randomized);
67 
68  secp256k1_scalar_mul(&ctx->zsq, &ctx->zsq, &ctx->yinv);
69  secp256k1_scalar_add(&ctx->zsq, &ctx->zsq, &ctx->zsq);
70  } else {
71  switch(ctx->count) {
72  /* S^x in eq (62) */
73  case 2:
74  *sc = ctx->x;
75  *pt = ctx->s;
76  break;
77  /* A in eq (62) */
78  case 1:
79  *pt = ctx->a;
80  secp256k1_scalar_set_int(sc, 1);
81  break;
82  /* G^[k(y, z) + sum_i y^i - t] from eq (61) */
83  case 0: {
84  size_t i;
86  secp256k1_scalar twosum;
87  secp256k1_scalar tmp;
88 
89  secp256k1_scalar_clear(&twosum);
90  secp256k1_scalar_clear(&yn);
91  secp256k1_scalar_set_int(&tmp, 1);
92 
93  secp256k1_scalar_sqr(&ctx->zsq, &ctx->z); /* need to re-set this */
94  secp256k1_scalar_negate(sc, &ctx->zsq); /* -z^2 */
95  secp256k1_scalar_add(sc, sc, &ctx->z); /* z - z^2 */
96 
97  for (i = 0; i < ctx->n_commits; i++) {
98  const size_t nbits = ctx->n / ctx->n_commits;
99  secp256k1_scalar negzn;
100  secp256k1_scalar twon;
101  size_t j;
102 
103  secp256k1_scalar_clear(&twon);
104  for (j = 0; j < nbits; j++) {
105  secp256k1_scalar_mul(&yn, &yn, &ctx->y);
106  secp256k1_scalar_add(&twon, &twon, &twon);
107 
108  secp256k1_scalar_add(&yn, &yn, &tmp);
109  secp256k1_scalar_add(&twon, &twon, &tmp);
110  }
111 
112  secp256k1_scalar_mul(&negzn, &ctx->zsq, &ctx->negz);
113  for (j = 0; j < i; j++) {
114  secp256k1_scalar_mul(&negzn, &negzn, &ctx->z);
115  }
116  if (ctx->min_value != NULL) {
117  secp256k1_scalar mv;
118  secp256k1_scalar_set_int(&mv, ctx->min_value[i]);
119  secp256k1_scalar_mul(&mv, &mv, &ctx->negz);
120  secp256k1_scalar_mul(&mv, &mv, &ctx->z);
121  for (j = 0; j < i; j++) {
122  secp256k1_scalar_mul(&negzn, &negzn, &ctx->z);
123  }
124  secp256k1_scalar_add(&twosum, &twosum, &mv);
125  }
126  secp256k1_scalar_mul(&twon, &twon, &negzn);
127  secp256k1_scalar_add(&twosum, &twosum, &twon);
128  } /* yn = 1 + y + ... + y^(n-1); twosum = (z^3 + ... + z^{2 + n_commits})(1 + 2 + ... + 2^(n-1)) */
129 
130 
131  secp256k1_scalar_mul(sc, sc, &yn); /* (z - z^2)(1 + ... + y^(n-1)) */
132  secp256k1_scalar_add(sc, sc, &twosum); /* (z - z^2)(1 + ... + y^(n-1)) - z^3(1 + ... + 2^(n-1)) */
133  secp256k1_scalar_negate(&tmp, &ctx->t);
134  secp256k1_scalar_add(sc, sc, &tmp); /* (z - z^2)(1 + ... + y^n) - z^3(1 + ... + 2^n) - t */
135  secp256k1_scalar_mul(sc, sc, &ctx->randomizer61);
136  *pt = *ctx->asset;
137  break;
138  }
139  /* T1^x in eq (61) */
140  case 3:
141  secp256k1_scalar_mul(sc, &ctx->x, &ctx->randomizer61);
142  *pt = ctx->t1;
143  break;
144  /* T2^x^2 in eq (61) */
145  case 4:
146  secp256k1_scalar_sqr(sc, &ctx->x);
147  secp256k1_scalar_mul(sc, sc, &ctx->randomizer61);
148  *pt = ctx->t2;
149  break;
150  /* V^z^2 in eq (61) */
151  default:
152  VERIFY_CHECK(ctx->count < 5 + ctx->n_commits);
153 
154  secp256k1_scalar_mul(sc, &ctx->zsq, &ctx->randomizer61);
155  secp256k1_scalar_mul(&ctx->zsq, &ctx->zsq, &ctx->z);
156  *pt = ctx->commit[ctx->count - 5];
157  break;
158  }
159  secp256k1_scalar_mul(sc, sc, randomizer);
160  ctx->count++;
161  }
162  return 1;
163 }
164 
165 static int secp256k1_bulletproof_rangeproof_verify_impl(const secp256k1_ecmult_context *ecmult_ctx, secp256k1_scratch *scratch, const unsigned char* const* proof, const size_t n_proofs, const size_t plen, size_t nbits, const uint64_t* const* min_value, const secp256k1_ge* const* commitp, size_t n_commits, const secp256k1_ge *value_gen, const secp256k1_bulletproof_generators *gens, const unsigned char* const* extra_commit, size_t *extra_commit_len) {
168  int ret;
169  size_t i;
170  int same_generators = 1;
171 
172  /* sanity-check input */
173  if (secp256k1_popcountl(nbits) != 1 || nbits > MAX_NBITS) {
174  return 0;
175  }
176  if (plen < 64 + 128 + 1 + 32) { /* inner product argument will do a more precise check */
177  return 0;
178  }
179  if (plen > SECP256K1_BULLETPROOF_MAX_PROOF) {
180  return 0;
181  }
182 
183  if (!secp256k1_scratch_allocate_frame(scratch, n_proofs * (sizeof(*ecmult_data) + sizeof(*innp_ctx)), 2)) {
184  return 0;
185  }
186  ecmult_data = (secp256k1_bulletproof_vfy_ecmult_context *)secp256k1_scratch_alloc(scratch, n_proofs * sizeof(*ecmult_data));
187  innp_ctx = (secp256k1_bulletproof_innerproduct_context *)secp256k1_scratch_alloc(scratch, n_proofs * sizeof(*innp_ctx));
188 
189  /* Check if all generators are equal. If so, we can amortize all their scalar multiplications
190  * by them and save one scalar-ge multiplication per proof. */
191  VERIFY_CHECK(!secp256k1_ge_is_infinity(&value_gen[0]));
192  for (i = 1; i < n_proofs; i++) {
193  VERIFY_CHECK(!secp256k1_ge_is_infinity(&value_gen[i]));
194  if (!secp256k1_fe_equal_var(&value_gen[i].x, &value_gen[i - 1].x) ||
195  !secp256k1_fe_equal_var(&value_gen[i].y, &value_gen[i - 1].y)) {
196  same_generators = 0;
197  }
198  }
199 
200  for (i = 0; i < n_proofs; i++) {
202  unsigned char commit[32] = {0};
203  unsigned char randomizer61[32] = {0}; /* randomizer for eq (61) so we can add it to eq (62) to save a separate multiexp */
204  secp256k1_scalar taux, mu;
205  secp256k1_ge age, sge;
206  int overflow;
207  size_t j;
208 
209  /* Commit to all input data: min value, pedersen commit, asset generator, extra_commit */
210  if (min_value != NULL && min_value[i] != NULL) {
211  unsigned char len[4];
212  secp256k1_sha256_initialize(&sha256);
213  secp256k1_sha256_write(&sha256, commit, 32);
214  len[0] = n_commits;
215  len[1] = n_commits >> 8;
216  len[2] = n_commits >> 16;
217  len[3] = n_commits >> 24;
218  secp256k1_sha256_write(&sha256, len, 4);
219  for (j = 0; j < n_commits; j++) {
220  unsigned char vbuf[8];
221  vbuf[0] = min_value[i][j];
222  vbuf[1] = min_value[i][j] >> 8;
223  vbuf[2] = min_value[i][j] >> 16;
224  vbuf[3] = min_value[i][j] >> 24;
225  vbuf[4] = min_value[i][j] >> 32;
226  vbuf[5] = min_value[i][j] >> 40;
227  vbuf[6] = min_value[i][j] >> 48;
228  vbuf[7] = min_value[i][j] >> 56;
229  secp256k1_sha256_write(&sha256, vbuf, 8);
230  }
231  secp256k1_sha256_finalize(&sha256, commit);
232  }
233  for (j = 0; j < n_commits; j++) {
234  secp256k1_bulletproof_update_commit(commit, &commitp[i][j], &value_gen[i]);
235  }
236  if (extra_commit != NULL && extra_commit[i] != NULL) {
237  secp256k1_sha256_initialize(&sha256);
238  secp256k1_sha256_write(&sha256, commit, 32);
239  secp256k1_sha256_write(&sha256, extra_commit[i], extra_commit_len[i]);
240  secp256k1_sha256_finalize(&sha256, commit);
241  }
242 
243  /* Compute y, z, x */
244  if (!secp256k1_bulletproof_deserialize_point(&age, &proof[i][64], 0, 4) ||
245  !secp256k1_bulletproof_deserialize_point(&sge, &proof[i][64], 1, 4)) {
246  return 0;
247  }
248 
249  secp256k1_bulletproof_update_commit(commit, &age, &sge);
250  secp256k1_scalar_set_b32(&ecmult_data[i].y, commit, &overflow);
251  if (overflow || secp256k1_scalar_is_zero(&ecmult_data[i].y)) {
252  secp256k1_scratch_deallocate_frame(scratch);
253  return 0;
254  }
255  secp256k1_bulletproof_update_commit(commit, &age, &sge);
256  secp256k1_scalar_set_b32(&ecmult_data[i].z, commit, &overflow);
257  if (overflow || secp256k1_scalar_is_zero(&ecmult_data[i].z)) {
258  secp256k1_scratch_deallocate_frame(scratch);
259  return 0;
260  }
261 
262  if (!secp256k1_bulletproof_deserialize_point(&ecmult_data[i].t1, &proof[i][64], 2, 4) ||
263  !secp256k1_bulletproof_deserialize_point(&ecmult_data[i].t2, &proof[i][64], 3, 4)) {
264  return 0;
265  }
266 
267  secp256k1_bulletproof_update_commit(commit, &ecmult_data[i].t1, &ecmult_data[i].t2);
268  secp256k1_scalar_set_b32(&ecmult_data[i].x, commit, &overflow);
269  if (overflow || secp256k1_scalar_is_zero(&ecmult_data[i].x)) {
270  secp256k1_scratch_deallocate_frame(scratch);
271  return 0;
272  }
273 
274  /* compute exponent offsets */
275  secp256k1_scalar_inverse_var(&ecmult_data[i].yinv, &ecmult_data[i].y); /* TODO somehow batch this w the inner-product argument inverse */
276  ecmult_data[i].yinvn = ecmult_data[i].yinv;
277  for (j = 0; j < secp256k1_floor_lg(nbits); j++) {
278  secp256k1_scalar_sqr(&ecmult_data[i].yinvn, &ecmult_data[i].yinvn);
279  }
280  secp256k1_scalar_sqr(&ecmult_data[i].zsq, &ecmult_data[i].z);
281  secp256k1_scalar_negate(&ecmult_data[i].negz, &ecmult_data[i].z);
282 
283  /* Update commit with remaining data for the inner product proof */
284  secp256k1_sha256_initialize(&sha256);
285  secp256k1_sha256_write(&sha256, commit, 32);
286  secp256k1_sha256_write(&sha256, &proof[i][0], 64);
287  secp256k1_sha256_finalize(&sha256, commit);
288 
289  secp256k1_sha256_initialize(&sha256);
290  secp256k1_sha256_write(&sha256, commit, 32);
291  secp256k1_sha256_finalize(&sha256, randomizer61);
292  secp256k1_scalar_set_b32(&ecmult_data[i].randomizer61, randomizer61, &overflow);
293  if (overflow || secp256k1_scalar_is_zero(&ecmult_data[i].randomizer61)) {
294  secp256k1_scratch_deallocate_frame(scratch);
295  return 0;
296  }
297 
298  /* Deserialize everything else */
299  secp256k1_scalar_set_b32(&taux, &proof[i][0], &overflow);
300  if (overflow || secp256k1_scalar_is_zero(&taux)) {
301  secp256k1_scratch_deallocate_frame(scratch);
302  return 0;
303  }
304  secp256k1_scalar_set_b32(&mu, &proof[i][32], &overflow);
305  if (overflow || secp256k1_scalar_is_zero(&mu)) {
306  secp256k1_scratch_deallocate_frame(scratch);
307  return 0;
308  }
309  /* A little sketchy, we read t (l(x) . r(x)) off the front of the inner product proof,
310  * which we otherwise treat as a black box */
311  secp256k1_scalar_set_b32(&ecmult_data[i].t, &proof[i][64 + 128 + 1], &overflow);
312  if (overflow || secp256k1_scalar_is_zero(&ecmult_data[i].t)) {
313  secp256k1_scratch_deallocate_frame(scratch);
314  return 0;
315  }
316 
317  /* Verify inner product proof */
318  ecmult_data[i].a = age;
319  ecmult_data[i].s = sge;
320  ecmult_data[i].n = nbits * n_commits;
321  ecmult_data[i].count = 0;
322  ecmult_data[i].asset = &value_gen[i];
323  ecmult_data[i].min_value = min_value == NULL ? NULL : min_value[i];
324  ecmult_data[i].commit = commitp[i];
325  ecmult_data[i].n_commits = n_commits;
326  secp256k1_scalar_mul(&taux, &taux, &ecmult_data[i].randomizer61);
327  secp256k1_scalar_add(&mu, &mu, &taux);
328 
329  innp_ctx[i].proof = &proof[i][64 + 128 + 1];
330  innp_ctx[i].p_offs = mu;
331  memcpy(innp_ctx[i].commit, commit, 32);
332  innp_ctx[i].yinv = ecmult_data[i].yinv;
333  innp_ctx[i].rangeproof_cb = secp256k1_bulletproof_rangeproof_vfy_callback;
334  innp_ctx[i].rangeproof_cb_data = (void *) &ecmult_data[i];
335  innp_ctx[i].n_extra_rangeproof_points = 5 + n_commits;
336  }
337 
338  ret = secp256k1_bulletproof_inner_product_verify_impl(ecmult_ctx, scratch, gens, nbits * n_commits, innp_ctx, n_proofs, plen - (64 + 128 + 1), same_generators);
339  secp256k1_scratch_deallocate_frame(scratch);
340  return ret;
341 }
342 
343 typedef struct {
344  const unsigned char *nonce;
349  const uint64_t *val;
350  const uint64_t *min_val;
351  size_t n_vals;
352  size_t nbits;
353  size_t count;
355 
356 static void secp256k1_lr_generator_init(secp256k1_bulletproof_lr_generator *generator, const unsigned char *nonce, const secp256k1_scalar *y, const secp256k1_scalar *z, size_t nbits, const uint64_t *val, const uint64_t *min_val, size_t n_vals) {
357  generator->nonce = nonce;
358  generator->y = *y;
359  generator->z = *z;
360  secp256k1_scalar_set_int(&generator->yn, 1);
361  generator->nbits = nbits;
362  generator->val = val;
363  generator->min_val = min_val;
364  generator->n_vals = n_vals;
365  generator->count = 0;
366 }
367 
368 static void secp256k1_lr_generate(secp256k1_bulletproof_lr_generator *generator, secp256k1_scalar *lout, secp256k1_scalar *rout, const secp256k1_scalar *x) {
369  const size_t commit_idx = generator->count / generator->nbits;
370  const size_t bit_idx = generator->count % generator->nbits;
371  const uint64_t mv = generator->min_val == NULL ? 0 : generator->min_val[commit_idx];
372  const int bit = ((generator->val[commit_idx] - mv) >> bit_idx) & 1;
373  secp256k1_scalar sl, sr;
374  secp256k1_scalar negz;
375 
376  if (bit_idx == 0) {
377  size_t i;
378  secp256k1_scalar_sqr(&generator->z22n, &generator->z);
379  for (i = 0; i < commit_idx; i++) {
380  secp256k1_scalar_mul(&generator->z22n, &generator->z22n, &generator->z);
381  }
382  }
383 
384  secp256k1_scalar_chacha20(&sl, &sr, generator->nonce, generator->count + 2);
385  secp256k1_scalar_mul(&sl, &sl, x);
386  secp256k1_scalar_mul(&sr, &sr, x);
387 
388  secp256k1_scalar_set_int(lout, bit);
389  secp256k1_scalar_negate(&negz, &generator->z);
390  secp256k1_scalar_add(lout, lout, &negz);
391  secp256k1_scalar_add(lout, lout, &sl);
392 
393  secp256k1_scalar_set_int(rout, 1 - bit);
394  secp256k1_scalar_negate(rout, rout);
395  secp256k1_scalar_add(rout, rout, &generator->z);
396  secp256k1_scalar_add(rout, rout, &sr);
397  secp256k1_scalar_mul(rout, rout, &generator->yn);
398  secp256k1_scalar_add(rout, rout, &generator->z22n);
399 
400  generator->count++;
401  secp256k1_scalar_mul(&generator->yn, &generator->yn, &generator->y);
402  secp256k1_scalar_add(&generator->z22n, &generator->z22n, &generator->z22n);
403 }
404 
405 typedef struct {
410 
411 static int secp256k1_bulletproof_abgh_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data) {
413  const int is_g = idx % 2 == 0;
414 
415  (void) pt;
416  if (is_g) {
417  secp256k1_lr_generate(&ctx->lr_gen, sc, &ctx->cache, &ctx->x);
418  } else {
419  *sc = ctx->cache;
420  }
421 
422  return 1;
423 }
424 
425 /* Proof format: t, tau_x, mu, a, b, A, S, T_1, T_2, {L_i}, {R_i}
426  * 5 scalar + [4 + 2log(n)] ge
427  *
428  * The non-bold `h` in the Bulletproofs paper corresponds to our gens->blinding_gen
429  * while the non-bold `g` corresponds to the asset type `value_gen`.
430  */
431 static int
432 secp256k1_bulletproof_rangeproof_prove_impl(const secp256k1_ecmult_context *ecmult_ctx, secp256k1_scratch *scratch,
433  unsigned char *proof, size_t *plen, const size_t nbits,
434  const uint64_t *value, const uint64_t *min_value,
435  const secp256k1_scalar *blind, const secp256k1_ge *commitp,
436  size_t n_commits, const secp256k1_ge *value_gen,
437  const secp256k1_bulletproof_generators *gens, const unsigned char *nonce,
438  const unsigned char *extra_commit, size_t extra_commit_len) {
441  secp256k1_scalar zero;
443  unsigned char commit[32] = {0};
444  secp256k1_scalar alpha, rho;
445  secp256k1_scalar t0, t1, t2;
446  secp256k1_scalar tau1, tau2, taux, mu;
448  secp256k1_scalar z, zsq;
449  secp256k1_scalar x, xsq;
450  secp256k1_scalar tmps;
451  secp256k1_gej aj, sj;
452  secp256k1_gej tmpj;
453  size_t i, j;
454  int overflow;
455  /* inner product proof variables */
456  secp256k1_ge out_pt[4];
457 
458  if (secp256k1_popcountl(nbits) != 1 || nbits > MAX_NBITS) {
459  return 0;
460  }
461  for (i = 0; i < n_commits; i++) {
462  uint64_t mv = min_value == NULL ? 0 : min_value[i];
463  if (mv > value[i]) {
464  return 0;
465  }
466  if (nbits < 64 && (value[i] - mv) >= (1ull << nbits)) {
467  return 0;
468  }
469  }
470  if (*plen < 128 + 64 + 1) { /* inner product argument will check and assign plen */
471  return 0;
472  }
473 
474  secp256k1_scalar_clear(&zero);
475 
476  /* Commit to all input data: min value, pedersen commit, asset generator, extra_commit */
477  if (min_value != NULL) {
478  unsigned char len[4];
479  secp256k1_sha256_initialize(&sha256);
480  secp256k1_sha256_write(&sha256, commit, 32);
481  len[0] = n_commits;
482  len[1] = n_commits >> 8;
483  len[2] = n_commits >> 16;
484  len[3] = n_commits >> 24;
485  secp256k1_sha256_write(&sha256, len, 4);
486  for (i = 0; i < n_commits; i++) {
487  unsigned char vbuf[8];
488  vbuf[0] = min_value[i];
489  vbuf[1] = min_value[i] >> 8;
490  vbuf[2] = min_value[i] >> 16;
491  vbuf[3] = min_value[i] >> 24;
492  vbuf[4] = min_value[i] >> 32;
493  vbuf[5] = min_value[i] >> 40;
494  vbuf[6] = min_value[i] >> 48;
495  vbuf[7] = min_value[i] >> 56;
496  secp256k1_sha256_write(&sha256, vbuf, 8);
497  }
498  secp256k1_sha256_finalize(&sha256, commit);
499  }
500  for (i = 0; i < n_commits; i++) {
501  secp256k1_bulletproof_update_commit(commit, &commitp[i], value_gen); /* TODO be less stupid about this */
502  }
503  if (extra_commit != NULL) {
504  secp256k1_sha256_initialize(&sha256);
505  secp256k1_sha256_write(&sha256, commit, 32);
506  secp256k1_sha256_write(&sha256, extra_commit, extra_commit_len);
507  secp256k1_sha256_finalize(&sha256, commit);
508  }
509 
510  secp256k1_scalar_chacha20(&alpha, &rho, nonce, 0);
511  secp256k1_scalar_chacha20(&tau1, &tau2, nonce, 1);
512  /* Encrypt value into alpha, so it will be recoverable from -mu by someone who knows `nonce` */
513  if (n_commits == 1) {
514  secp256k1_scalar vals;
515  secp256k1_scalar_set_u64(&vals, value[0]);
516  secp256k1_scalar_negate(&vals, &vals); /* Negate so it'll be positive in -mu */
517  secp256k1_scalar_add(&alpha, &alpha, &vals);
518  }
519 
520  /* Compute A and S */
521  secp256k1_ecmult_const(&aj, &gens->blinding_gen[0], &alpha, 256);
522  secp256k1_ecmult_const(&sj, &gens->blinding_gen[0], &rho, 256);
523  for (i = 0; i < n_commits; i++) {
524  for (j = 0; j < nbits; j++) {
525  secp256k1_scalar sl, sr;
526  uint64_t mv = min_value == NULL ? 0 : min_value[i];
527  size_t al = !!((value[i] - mv) & (1ull << j));
528  secp256k1_ge aterm = gens->gens[i * nbits + j + gens->n/2];
529  secp256k1_ge sterm;
530  secp256k1_gej stermj;
531 
532  secp256k1_scalar_chacha20(&sl, &sr, nonce, i * nbits + j + 2);
533 
534  secp256k1_ge_neg(&aterm, &aterm);
535  secp256k1_fe_cmov(&aterm.x, &gens->gens[i * nbits + j].x, al);
536  secp256k1_fe_cmov(&aterm.y, &gens->gens[i * nbits + j].y, al);
537 
538  secp256k1_gej_add_ge(&aj, &aj, &aterm);
539 
540  secp256k1_ecmult_const(&stermj, &gens->gens[i * nbits + j], &sl, 256);
541  secp256k1_ge_set_gej(&sterm, &stermj);
542  secp256k1_gej_add_ge(&sj, &sj, &sterm);
543  secp256k1_ecmult_const(&stermj, &gens->gens[i * nbits + j + gens->n/2], &sr, 256);
544  secp256k1_ge_set_gej(&sterm, &stermj);
545  secp256k1_gej_add_ge(&sj, &sj, &sterm);
546  }
547  }
548 
549  /* get challenges y and z */
550  secp256k1_ge_set_gej(&out_pt[0], &aj);
551  secp256k1_ge_set_gej(&out_pt[1], &sj);
552 
553  secp256k1_bulletproof_update_commit(commit, &out_pt[0], &out_pt[1]);
554  secp256k1_scalar_set_b32(&y, commit, &overflow);
555  if (overflow || secp256k1_scalar_is_zero(&y)) {
556  return 0;
557  }
558  secp256k1_bulletproof_update_commit(commit, &out_pt[0], &out_pt[1]); /* TODO rehashing A and S to get a second challenge is overkill */
559  secp256k1_scalar_set_b32(&z, commit, &overflow);
560  if (overflow || secp256k1_scalar_is_zero(&z)) {
561  return 0;
562  }
563  secp256k1_scalar_sqr(&zsq, &z);
564 
565  /* Compute coefficients t0, t1, t2 of the <l, r> polynomial */
566  /* t0 = l(0) dot r(0) */
567  secp256k1_lr_generator_init(&lr_gen, nonce, &y, &z, nbits, value, min_value, n_commits);
568  secp256k1_scalar_clear(&t0);
569  for (i = 0; i < nbits * n_commits; i++) {
570  secp256k1_scalar l, r;
571  secp256k1_lr_generate(&lr_gen, &l, &r, &zero);
572  secp256k1_scalar_mul(&l, &l, &r);
573  secp256k1_scalar_add(&t0, &t0, &l);
574  }
575 
576  /* A = t0 + t1 + t2 = l(1) dot r(1) */
577  secp256k1_lr_generator_init(&lr_gen, nonce, &y, &z, nbits, value, min_value, n_commits);
578  secp256k1_scalar_clear(&t1);
579  for (i = 0; i < nbits * n_commits; i++) {
580  secp256k1_scalar one;
581  secp256k1_scalar l, r;
582  secp256k1_scalar_set_int(&one, 1);
583  secp256k1_lr_generate(&lr_gen, &l, &r, &one);
584  secp256k1_scalar_mul(&l, &l, &r);
585  secp256k1_scalar_add(&t1, &t1, &l);
586  }
587 
588  /* B = t0 - t1 + t2 = l(-1) dot r(-1) */
589  secp256k1_lr_generator_init(&lr_gen, nonce, &y, &z, nbits, value, min_value, n_commits);
590  secp256k1_scalar_clear(&t2);
591  for (i = 0; i < nbits * n_commits; i++) {
592  secp256k1_scalar negone;
593  secp256k1_scalar l, r;
594  secp256k1_scalar_set_int(&negone, 1);
595  secp256k1_scalar_negate(&negone, &negone);
596  secp256k1_lr_generate(&lr_gen, &l, &r, &negone);
597  secp256k1_scalar_mul(&l, &l, &r);
598  secp256k1_scalar_add(&t2, &t2, &l);
599  }
600 
601  /* t1 = (A - B)/2 */
602  secp256k1_scalar_set_int(&tmps, 2);
603  secp256k1_scalar_inverse_var(&tmps, &tmps);
604  secp256k1_scalar_negate(&t2, &t2);
605  secp256k1_scalar_add(&t1, &t1, &t2);
606  secp256k1_scalar_mul(&t1, &t1, &tmps);
607 
608  /* t2 = -(-B + t0) + t1 */
609  secp256k1_scalar_add(&t2, &t2, &t0);
610  secp256k1_scalar_negate(&t2, &t2);
611  secp256k1_scalar_add(&t2, &t2, &t1);
612 
613  /* Compute Ti = t_i*A + tau_i*G for i = 1,2 */
614  secp256k1_ecmult_const(&tmpj, value_gen, &t1, 256);
615  secp256k1_ge_set_gej(&out_pt[2], &tmpj);
616  secp256k1_ecmult_const(&tmpj, &gens->blinding_gen[0], &tau1, 256);
617  secp256k1_gej_add_ge(&tmpj, &tmpj, &out_pt[2]);
618  secp256k1_ge_set_gej(&out_pt[2], &tmpj);
619 
620  secp256k1_ecmult_const(&tmpj, value_gen, &t2, 256);
621  secp256k1_ge_set_gej(&out_pt[3], &tmpj);
622  secp256k1_ecmult_const(&tmpj, &gens->blinding_gen[0], &tau2, 256);
623  secp256k1_gej_add_ge(&tmpj, &tmpj, &out_pt[3]);
624  secp256k1_ge_set_gej(&out_pt[3], &tmpj);
625 
626  /* get challenge x */
627  secp256k1_bulletproof_update_commit(commit, &out_pt[2], &out_pt[3]);
628  secp256k1_scalar_set_b32(&x, commit, &overflow);
629  if (overflow || secp256k1_scalar_is_zero(&x)) {
630  return 0;
631  }
632  secp256k1_scalar_sqr(&xsq, &x);
633 
634  /* compute tau_x and mu */
635  secp256k1_scalar_mul(&taux, &tau1, &x);
636  secp256k1_scalar_mul(&tmps, &tau2, &xsq);
637  secp256k1_scalar_add(&taux, &taux, &tmps);
638  for (i = 0; i < n_commits; i++) {
639  secp256k1_scalar_mul(&tmps, &zsq, &blind[i]);
640  secp256k1_scalar_add(&taux, &taux, &tmps);
641  secp256k1_scalar_mul(&zsq, &zsq, &z);
642  }
643 
644  secp256k1_scalar_mul(&mu, &rho, &x);
645  secp256k1_scalar_add(&mu, &mu, &alpha);
646 
647  /* Negate taux and mu so the verifier doesn't have to */
648  secp256k1_scalar_negate(&taux, &taux);
649  secp256k1_scalar_negate(&mu, &mu);
650 
651  /* Encode rangeproof stuff */
652  secp256k1_scalar_get_b32(&proof[0], &taux);
653  secp256k1_scalar_get_b32(&proof[32], &mu);
654  secp256k1_bulletproof_serialize_points(&proof[64], out_pt, 4);
655 
656  /* Mix this into the hash so the input to the inner product proof is fixed */
657  secp256k1_sha256_initialize(&sha256);
658  secp256k1_sha256_write(&sha256, commit, 32);
659  secp256k1_sha256_write(&sha256, proof, 64);
660  secp256k1_sha256_finalize(&sha256, commit);
661 
662  /* Compute l and r, do inner product proof */
663  abgh_data.x = x;
664  secp256k1_lr_generator_init(&abgh_data.lr_gen, nonce, &y, &z, nbits, value, min_value, n_commits);
665  *plen -= 64 + 128 + 1;
666  secp256k1_scalar_inverse_var(&y, &y);
667  if (secp256k1_bulletproof_inner_product_prove_impl(ecmult_ctx, scratch, &proof[64 + 128 + 1], plen, gens, &y, nbits * n_commits, secp256k1_bulletproof_abgh_callback, (void *) &abgh_data, commit) == 0) {
668  return 0;
669  }
670  *plen += 64 + 128 + 1;
671 
672  return 1;
673 }
674 
675 static int secp256k1_bulletproof_rangeproof_rewind_impl(uint64_t *value, secp256k1_scalar *blind, const unsigned char *proof, const size_t plen, uint64_t min_value, const secp256k1_pedersen_commitment *pcommit, const secp256k1_generator *value_gen, const secp256k1_ge *blind_gen, const unsigned char *nonce, const unsigned char *extra_commit, size_t extra_commit_len) {
677  static const unsigned char zero24[24] = { 0 };
678  unsigned char commit[32] = { 0 };
679  unsigned char lrparity;
680  secp256k1_scalar taux, mu;
681  secp256k1_scalar alpha, rho, tau1, tau2;
682  secp256k1_scalar x, z;
683  secp256k1_ge commitp, value_genp;
684  secp256k1_gej rewind_commitj;
685  int overflow;
686 
687  if (plen < 64 + 128 + 1 || plen > SECP256K1_BULLETPROOF_MAX_PROOF) {
688  return 0;
689  }
690 
691  /* Extract data from beginning of proof */
692  secp256k1_scalar_set_b32(&taux, &proof[0], &overflow);
693  if (overflow || secp256k1_scalar_is_zero(&taux)) {
694  return 0;
695  }
696  secp256k1_scalar_set_b32(&mu, &proof[32], &overflow);
697  if (overflow || secp256k1_scalar_is_zero(&mu)) {
698  return 0;
699  }
700 
701  secp256k1_scalar_chacha20(&alpha, &rho, nonce, 0);
702  secp256k1_scalar_chacha20(&tau1, &tau2, nonce, 1);
703 
704  if (min_value > 0) {
705  unsigned char vbuf[8];
706  const unsigned char len[4] = { 1, 0, 0, 0 };
707  vbuf[0] = min_value;
708  vbuf[1] = min_value >> 8;
709  vbuf[2] = min_value >> 16;
710  vbuf[3] = min_value >> 24;
711  vbuf[4] = min_value >> 32;
712  vbuf[5] = min_value >> 40;
713  vbuf[6] = min_value >> 48;
714  vbuf[7] = min_value >> 56;
715  secp256k1_sha256_initialize(&sha256);
716  secp256k1_sha256_write(&sha256, commit, 32);
717  secp256k1_sha256_write(&sha256, len, 4);
718  secp256k1_sha256_write(&sha256, vbuf, 8);
719  secp256k1_sha256_finalize(&sha256, commit);
720  }
721 
722  secp256k1_pedersen_commitment_load(&commitp, pcommit);
723  secp256k1_generator_load(&value_genp, value_gen);
724  secp256k1_bulletproof_update_commit(commit, &commitp, &value_genp);
725 
726  if (extra_commit != NULL) {
727  secp256k1_sha256_initialize(&sha256);
728  secp256k1_sha256_write(&sha256, commit, 32);
729  secp256k1_sha256_write(&sha256, extra_commit, extra_commit_len);
730  secp256k1_sha256_finalize(&sha256, commit);
731  }
732 
733  /* Extract A and S to compute y and z */
734  lrparity = 2 * !!(proof[64] & 1) + !!(proof[64] & 2);
735  /* y */
736  secp256k1_sha256_initialize(&sha256);
737  secp256k1_sha256_write(&sha256, commit, 32);
738  secp256k1_sha256_write(&sha256, &lrparity, 1);
739  secp256k1_sha256_write(&sha256, &proof[65], 64);
740  secp256k1_sha256_finalize(&sha256, commit);
741 
742  /* z */
743  secp256k1_sha256_initialize(&sha256);
744  secp256k1_sha256_write(&sha256, commit, 32);
745  secp256k1_sha256_write(&sha256, &lrparity, 1);
746  secp256k1_sha256_write(&sha256, &proof[65], 64);
747  secp256k1_sha256_finalize(&sha256, commit);
748 
749  secp256k1_scalar_set_b32(&z, commit, &overflow);
750  if (overflow || secp256k1_scalar_is_zero(&z)) {
751  return 0;
752  }
753 
754  /* x */
755  lrparity = 2 * !!(proof[64] & 4) + !!(proof[64] & 8);
756  secp256k1_sha256_initialize(&sha256);
757  secp256k1_sha256_write(&sha256, commit, 32);
758  secp256k1_sha256_write(&sha256, &lrparity, 1);
759  secp256k1_sha256_write(&sha256, &proof[129], 64);
760  secp256k1_sha256_finalize(&sha256, commit);
761 
762  secp256k1_scalar_set_b32(&x, commit, &overflow);
763  if (overflow || secp256k1_scalar_is_zero(&x)) {
764  return 0;
765  }
766 
767  /* Compute candidate mu and add to (negated) mu from proof to get value */
768  secp256k1_scalar_mul(&rho, &rho, &x);
769  secp256k1_scalar_add(&mu, &mu, &rho);
770  secp256k1_scalar_add(&mu, &mu, &alpha);
771 
772  secp256k1_scalar_get_b32(commit, &mu);
773  if (memcmp(commit, zero24, 24) != 0) {
774  return 0;
775  }
776  *value = commit[31] + ((uint64_t) commit[30] << 8) +
777  ((uint64_t) commit[29] << 16) + ((uint64_t) commit[28] << 24) +
778  ((uint64_t) commit[27] << 32) + ((uint64_t) commit[26] << 40) +
779  ((uint64_t) commit[25] << 48) + ((uint64_t) commit[24] << 56);
780 
781  /* Derive blinding factor */
782  secp256k1_scalar_mul(&tau1, &tau1, &x);
783  secp256k1_scalar_mul(&tau2, &tau2, &x);
784  secp256k1_scalar_mul(&tau2, &tau2, &x);
785 
786  secp256k1_scalar_add(&taux, &taux, &tau1);
787  secp256k1_scalar_add(&taux, &taux, &tau2);
788 
789  secp256k1_scalar_sqr(&z, &z);
790  secp256k1_scalar_inverse_var(&z, &z);
791  secp256k1_scalar_mul(blind, &taux, &z);
792  secp256k1_scalar_negate(blind, blind);
793 
794  /* Check blinding factor */
795  secp256k1_pedersen_ecmult(&rewind_commitj, blind, *value, &value_genp, blind_gen);
796  secp256k1_gej_neg(&rewind_commitj, &rewind_commitj);
797  secp256k1_gej_add_ge_var(&rewind_commitj, &rewind_commitj, &commitp, NULL);
798 
799  return secp256k1_gej_is_infinity(&rewind_commitj);
800 }
801 
802 #endif
secp256k1_scratch_space_struct2
Definition: scratch.h:14
secp256k1_bulletproof_vfy_ecmult_context::n_commits
size_t n_commits
Definition: rangeproof_impl.h:36
secp256k1_bulletproof_vfy_ecmult_context::asset
const secp256k1_ge * asset
Definition: rangeproof_impl.h:33
secp256k1_bulletproof_vfy_ecmult_context::randomizer61
secp256k1_scalar randomizer61
Definition: rangeproof_impl.h:30
secp256k1_bulletproof_vfy_ecmult_context::zsq
secp256k1_scalar zsq
Definition: rangeproof_impl.h:21
VERIFY_CHECK
#define VERIFY_CHECK(cond)
Definition: util.h:61
secp256k1_bulletproof_vfy_ecmult_context::yinvn
secp256k1_scalar yinvn
Definition: rangeproof_impl.h:18
secp256k1_bulletproof_vfy_ecmult_context::z_randomized
secp256k1_scalar z_randomized
Definition: rangeproof_impl.h:20
secp256k1_ge::y
secp256k1_fe y
Definition: group.h:20
secp256k1_bulletproof_lr_generator::min_val
const uint64_t * min_val
Definition: rangeproof_impl.h:350
secp256k1_bulletproof_generators::n
size_t n
Definition: main_impl.h:55
secp256k1_bulletproof_innerproduct_context::p_offs
secp256k1_scalar p_offs
Definition: inner_product_impl.h:75
sha256
Internal SHA-256 implementation.
Definition: sha256.cpp:15
secp256k1_bulletproof_innerproduct_context
Definition: inner_product_impl.h:73
secp256k1_bulletproof_vfy_ecmult_context::s
secp256k1_ge s
Definition: rangeproof_impl.h:26
memcpy
void * memcpy(void *a, const void *b, size_t c)
Definition: glibc_compat.cpp:15
secp256k1_bulletproof_innerproduct_context::proof
const unsigned char * proof
Definition: inner_product_impl.h:74
secp256k1_bulletproof_lr_generator::z
secp256k1_scalar z
Definition: rangeproof_impl.h:346
secp256k1_bulletproof_vfy_ecmult_context::t1
secp256k1_ge t1
Definition: rangeproof_impl.h:37
secp256k1_sha256
Definition: hash.h:13
secp256k1_bulletproof_lr_generator::z22n
secp256k1_scalar z22n
Definition: rangeproof_impl.h:348
secp256k1_bulletproof_vfy_ecmult_context::t2
secp256k1_ge t2
Definition: rangeproof_impl.h:38
secp256k1_bulletproof_lr_generator::val
const uint64_t * val
Definition: rangeproof_impl.h:349
SECP256K1_BULLETPROOF_MAX_PROOF
#define SECP256K1_BULLETPROOF_MAX_PROOF
Definition: secp256k1_bulletproofs.h:31
secp256k1_bulletproof_vfy_ecmult_context::count
size_t count
Definition: rangeproof_impl.h:29
secp256k1_bulletproof_vfy_ecmult_context::a
secp256k1_ge a
Definition: rangeproof_impl.h:25
secp256k1_bulletproof_vfy_ecmult_context::t
secp256k1_scalar t
Definition: rangeproof_impl.h:32
secp256k1_bulletproof_generators::gens
secp256k1_ge * gens
Definition: main_impl.h:57
r
void const uint64_t uint64_t * r
Definition: field_5x52_asm_impl.h:10
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_ecmult_context::commit
const secp256k1_ge * commit
Definition: rangeproof_impl.h:34
secp256k1_generator
Opaque data structure that stores a base point.
Definition: secp256k1_generator.h:20
secp256k1_bulletproof_lr_generator::nbits
size_t nbits
Definition: rangeproof_impl.h:352
secp256k1_scalar
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
secp256k1_bulletproof_vfy_ecmult_context::z
secp256k1_scalar z
Definition: rangeproof_impl.h:19
secp256k1_gej
A group element of the secp256k1 curve, in jacobian coordinates.
Definition: group.h:24
secp256k1_bulletproof_abgh_data
Definition: rangeproof_impl.h:405
secp256k1_bulletproof_lr_generator::count
size_t count
Definition: rangeproof_impl.h:353
secp256k1_bulletproof_innerproduct_context::rangeproof_cb_data
void * rangeproof_cb_data
Definition: inner_product_impl.h:79
secp256k1_bulletproof_lr_generator::n_vals
size_t n_vals
Definition: rangeproof_impl.h:351
secp256k1_bulletproof_vfy_ecmult_context
Definition: rangeproof_impl.h:16
secp256k1_bulletproof_lr_generator::nonce
const unsigned char * nonce
Definition: rangeproof_impl.h:344
secp256k1_bulletproof_vfy_ecmult_context::negz
secp256k1_scalar negz
Definition: rangeproof_impl.h:23
util.h
secp256k1_bulletproof_vfy_ecmult_context::min_value
const uint64_t * min_value
Definition: rangeproof_impl.h:35
secp256k1_bulletproof_vfy_ecmult_context::x
secp256k1_scalar x
Definition: rangeproof_impl.h:24
secp256k1_bulletproof_vfy_ecmult_context::n
size_t n
Definition: rangeproof_impl.h:27
secp256k1_bulletproof_generators::blinding_gen
secp256k1_ge * blinding_gen
Definition: main_impl.h:62
secp256k1_bulletproof_lr_generator::yn
secp256k1_scalar yn
Definition: rangeproof_impl.h:347
secp256k1_pedersen_commitment
Opaque data structure that stores a Pedersen commitment.
Definition: secp256k1_commitment.h:22
secp256k1_bulletproof_innerproduct_context::n_extra_rangeproof_points
size_t n_extra_rangeproof_points
Definition: inner_product_impl.h:80
secp256k1_bulletproof_vfy_ecmult_context::yinv
secp256k1_scalar yinv
Definition: rangeproof_impl.h:17
secp256k1_bulletproof_vfy_ecmult_context::y
secp256k1_scalar y
Definition: rangeproof_impl.h:31
secp256k1_bulletproof_vfy_ecmult_context::g_exponent
secp256k1_scalar g_exponent
Definition: rangeproof_impl.h:22
secp256k1_bulletproof_abgh_data::cache
secp256k1_scalar cache
Definition: rangeproof_impl.h:407
secp256k1_ge::x
secp256k1_fe x
Definition: group.h:19
secp256k1_ecmult_context
Definition: ecmult.h:15
MAX_NBITS
#define MAX_NBITS
Definition: rangeproof_impl.h:14
secp256k1_bulletproof_innerproduct_context::yinv
secp256k1_scalar yinv
Definition: inner_product_impl.h:76
secp256k1_bulletproof_abgh_data::lr_gen
secp256k1_bulletproof_lr_generator lr_gen
Definition: rangeproof_impl.h:408
secp256k1_bulletproof_lr_generator
Definition: rangeproof_impl.h:343
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_abgh_data::x
secp256k1_scalar x
Definition: rangeproof_impl.h:406
secp256k1_bulletproof_lr_generator::y
secp256k1_scalar y
Definition: rangeproof_impl.h:345