PRCYCoin  2.0.0.7rc1
P2P Digital Currency
rangeproof_impl.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (c) 2015 Gregory Maxwell *
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_RANGEPROOF_IMPL_H_
8 #define _SECP256K1_RANGEPROOF_IMPL_H_
9 
10 #include "eckey.h"
11 #include "scalar.h"
12 #include "group.h"
13 #include "rangeproof.h"
14 #include "hash_impl.h"
15 #include "util.h"
16 
19 
20 SECP256K1_INLINE static void secp256k1_rangeproof_pub_expand(secp256k1_gej *pubs,
21  int exp, size_t *rsizes, size_t rings, const secp256k1_ge* genp) {
22  secp256k1_gej base;
23  size_t i;
24  size_t j;
25  size_t npub;
26  VERIFY_CHECK(exp < 19);
27  if (exp < 0) {
28  exp = 0;
29  }
30  secp256k1_gej_set_ge(&base, genp);
31  secp256k1_gej_neg(&base, &base);
32  while (exp--) {
33  /* Multiplication by 10 */
34  secp256k1_gej tmp;
35  secp256k1_gej_double_var(&tmp, &base, NULL);
36  secp256k1_gej_double_var(&base, &tmp, NULL);
37  secp256k1_gej_double_var(&base, &base, NULL);
38  secp256k1_gej_add_var(&base, &base, &tmp, NULL);
39  }
40  npub = 0;
41  for (i = 0; i < rings; i++) {
42  for (j = 1; j < rsizes[i]; j++) {
43  secp256k1_gej_add_var(&pubs[npub + j], &pubs[npub + j - 1], &base, NULL);
44  }
45  if (i < rings - 1) {
46  secp256k1_gej_double_var(&base, &base, NULL);
47  secp256k1_gej_double_var(&base, &base, NULL);
48  }
49  npub += rsizes[i];
50  }
51 }
52 
53 SECP256K1_INLINE static void secp256k1_rangeproof_serialize_point(unsigned char* data, const secp256k1_ge *point) {
54  secp256k1_fe pointx;
55  pointx = point->x;
56  secp256k1_fe_normalize(&pointx);
57  data[0] = !secp256k1_fe_is_quad_var(&point->y);
58  secp256k1_fe_get_b32(data + 1, &pointx);
59 }
60 
61 SECP256K1_INLINE static int secp256k1_rangeproof_genrand(secp256k1_scalar *sec, secp256k1_scalar *s, unsigned char *message,
62  size_t *rsizes, size_t rings, const unsigned char *nonce, const secp256k1_ge *commit, const unsigned char *proof, size_t len, const secp256k1_ge* genp) {
63  unsigned char tmp[32];
64  unsigned char rngseed[32 + 33 + 33 + 10];
66  secp256k1_scalar acc;
67  int overflow;
68  int ret;
69  size_t i;
70  size_t j;
71  int b;
72  size_t npub;
73  VERIFY_CHECK(len <= 10);
74  memcpy(rngseed, nonce, 32);
75  secp256k1_rangeproof_serialize_point(rngseed + 32, commit);
76  secp256k1_rangeproof_serialize_point(rngseed + 32 + 33, genp);
77  memcpy(rngseed + 33 + 33 + 32, proof, len);
78  secp256k1_rfc6979_hmac_sha256_initialize(&rng, rngseed, 32 + 33 + 33 + len);
79  secp256k1_scalar_clear(&acc);
80  npub = 0;
81  ret = 1;
82  for (i = 0; i < rings; i++) {
83  if (i < rings - 1) {
84  secp256k1_rfc6979_hmac_sha256_generate(&rng, tmp, 32);
85  do {
86  secp256k1_rfc6979_hmac_sha256_generate(&rng, tmp, 32);
87  secp256k1_scalar_set_b32(&sec[i], tmp, &overflow);
88  } while (overflow || secp256k1_scalar_is_zero(&sec[i]));
89  secp256k1_scalar_add(&acc, &acc, &sec[i]);
90  } else {
91  secp256k1_scalar_negate(&acc, &acc);
92  sec[i] = acc;
93  }
94  for (j = 0; j < rsizes[i]; j++) {
95  secp256k1_rfc6979_hmac_sha256_generate(&rng, tmp, 32);
96  if (message) {
97  for (b = 0; b < 32; b++) {
98  tmp[b] ^= message[(i * 4 + j) * 32 + b];
99  message[(i * 4 + j) * 32 + b] = tmp[b];
100  }
101  }
102  secp256k1_scalar_set_b32(&s[npub], tmp, &overflow);
103  ret &= !(overflow || secp256k1_scalar_is_zero(&s[npub]));
104  npub++;
105  }
106  }
107  secp256k1_rfc6979_hmac_sha256_finalize(&rng);
108  secp256k1_scalar_clear(&acc);
109  memset(tmp, 0, 32);
110  return ret;
111 }
112 
113 SECP256K1_INLINE static int secp256k1_range_proveparams(uint64_t *v, size_t *rings, size_t *rsizes, size_t *npub, size_t *secidx, uint64_t *min_value,
114  int *mantissa, uint64_t *scale, int *exp, int *min_bits, uint64_t value) {
115  size_t i;
116  *rings = 1;
117  rsizes[0] = 1;
118  secidx[0] = 0;
119  *scale = 1;
120  *mantissa = 0;
121  *npub = 0;
122  if (*min_value == UINT64_MAX) {
123  /* If the minimum value is the maximal representable value, then we cannot code a range. */
124  *exp = -1;
125  }
126  if (*exp >= 0) {
127  int max_bits;
128  uint64_t v2;
129  if ((*min_value && value > INT64_MAX) || (value && *min_value >= INT64_MAX)) {
130  /* If either value or min_value is >= 2^63-1 then the other must by zero to avoid overflowing the proven range. */
131  return 0;
132  }
133  max_bits = *min_value ? secp256k1_clz64_var(*min_value) : 64;
134  if (*min_bits > max_bits) {
135  *min_bits = max_bits;
136  }
137  if (*min_bits > 61 || value > INT64_MAX) {
143  *exp = 0;
144  }
145  /* Mask off the least significant digits, as requested. */
146  *v = value - *min_value;
147  /* If the user has asked for more bits of proof then there is room for in the exponent, reduce the exponent. */
148  v2 = *min_bits ? (UINT64_MAX>>(64-*min_bits)) : 0;
149  for (i = 0; (int) i < *exp && (v2 <= UINT64_MAX / 10); i++) {
150  *v /= 10;
151  v2 *= 10;
152  }
153  *exp = i;
154  v2 = *v;
155  for (i = 0; (int) i < *exp; i++) {
156  v2 *= 10;
157  *scale *= 10;
158  }
159  /* If the masked number isn't precise, compute the public offset. */
160  *min_value = value - v2;
161  /* How many bits do we need to represent our value? */
162  *mantissa = *v ? 64 - secp256k1_clz64_var(*v) : 1;
163  if (*min_bits > *mantissa) {
164  /* If the user asked for more precision, give it to them. */
165  *mantissa = *min_bits;
166  }
167  /* Digits in radix-4, except for the last digit if our mantissa length is odd. */
168  *rings = (*mantissa + 1) >> 1;
169  for (i = 0; i < *rings; i++) {
170  rsizes[i] = ((i < *rings - 1) | (!(*mantissa&1))) ? 4 : 2;
171  *npub += rsizes[i];
172  secidx[i] = (*v >> (i*2)) & 3;
173  }
174  VERIFY_CHECK(*mantissa>0);
175  VERIFY_CHECK((*v & ~(UINT64_MAX>>(64-*mantissa))) == 0); /* Did this get all the bits? */
176  } else {
177  /* A proof for an exact value. */
178  *exp = 0;
179  *min_value = value;
180  *v = 0;
181  *npub = 2;
182  }
183  VERIFY_CHECK(*v * *scale + *min_value == value);
184  VERIFY_CHECK(*rings > 0);
185  VERIFY_CHECK(*rings <= 32);
186  VERIFY_CHECK(*npub <= 128);
187  return 1;
188 }
189 
190 /* strawman interface, writes proof in proof, a buffer of plen, proves with respect to min_value the range for commit which has the provided blinding factor and value. */
191 SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmult_context* ecmult_ctx,
192  const secp256k1_ecmult_gen_context* ecmult_gen_ctx,
193  unsigned char *proof, size_t *plen, uint64_t min_value,
194  const secp256k1_ge *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value,
195  const unsigned char *message, size_t msg_len, const unsigned char *extra_commit, size_t extra_commit_len, const secp256k1_ge* genp){
196  secp256k1_gej pubs[128]; /* Candidate digits for our proof, most inferred. */
197  secp256k1_scalar s[128]; /* Signatures in our proof, most forged. */
198  secp256k1_scalar sec[32]; /* Blinding factors for the correct digits. */
199  secp256k1_scalar k[32]; /* Nonces for our non-forged signatures. */
200  secp256k1_scalar stmp;
201  secp256k1_sha256 sha256_m;
202  unsigned char prep[4096];
203  unsigned char tmp[33];
204  unsigned char *signs; /* Location of sign flags in the proof. */
205  uint64_t v;
206  uint64_t scale; /* scale = 10^exp. */
207  int mantissa; /* Number of bits proven in the blinded value. */
208  size_t rings; /* How many digits will our proof cover. */
209  size_t rsizes[32]; /* How many possible values there are for each place. */
210  size_t secidx[32]; /* Which digit is the correct one. */
211  size_t len; /* Number of bytes used so far. */
212  size_t i;
213  int overflow;
214  size_t npub;
215  len = 0;
216  if (*plen < 65 || min_value > value || min_bits > 64 || min_bits < 0 || exp < -1 || exp > 18) {
217  return 0;
218  }
219  if (!secp256k1_range_proveparams(&v, &rings, rsizes, &npub, secidx, &min_value, &mantissa, &scale, &exp, &min_bits, value)) {
220  return 0;
221  }
222  proof[len] = (rsizes[0] > 1 ? (64 | exp) : 0) | (min_value ? 32 : 0);
223  len++;
224  if (rsizes[0] > 1) {
225  VERIFY_CHECK(mantissa > 0 && mantissa <= 64);
226  proof[len] = mantissa - 1;
227  len++;
228  }
229  if (min_value) {
230  for (i = 0; i < 8; i++) {
231  proof[len + i] = (min_value >> ((7-i) * 8)) & 255;
232  }
233  len += 8;
234  }
235  /* Do we have enough room in the proof for the message? Each ring gives us 128 bytes, but the
236  * final ring is used to encode the blinding factor and the value, so we can't use that. (Well,
237  * technically there are 64 bytes available if we avoided the other data, but this is difficult
238  * because it's not always in the same place. */
239  if (msg_len > 0 && msg_len > 128 * (rings - 1)) {
240  return 0;
241  }
242  /* Do we have enough room for the proof? */
243  if (*plen - len < 32 * (npub + rings - 1) + 32 + ((rings+6) >> 3)) {
244  return 0;
245  }
246  secp256k1_sha256_initialize(&sha256_m);
247  secp256k1_rangeproof_serialize_point(tmp, commit);
248  secp256k1_sha256_write(&sha256_m, tmp, 33);
249  secp256k1_rangeproof_serialize_point(tmp, genp);
250  secp256k1_sha256_write(&sha256_m, tmp, 33);
251  secp256k1_sha256_write(&sha256_m, proof, len);
252 
253  memset(prep, 0, 4096);
254  if (message != NULL) {
255  memcpy(prep, message, msg_len);
256  }
257  /* Note, the data corresponding to the blinding factors must be zero. */
258  if (rsizes[rings - 1] > 1) {
259  size_t idx;
260  /* Value encoding sidechannel. */
261  idx = rsizes[rings - 1] - 1;
262  idx -= secidx[rings - 1] == idx;
263  idx = ((rings - 1) * 4 + idx) * 32;
264  for (i = 0; i < 8; i++) {
265  prep[8 + i + idx] = prep[16 + i + idx] = prep[24 + i + idx] = (v >> (56 - i * 8)) & 255;
266  prep[i + idx] = 0;
267  }
268  prep[idx] = 128;
269  }
270  if (!secp256k1_rangeproof_genrand(sec, s, prep, rsizes, rings, nonce, commit, proof, len, genp)) {
271  return 0;
272  }
273  memset(prep, 0, 4096);
274  for (i = 0; i < rings; i++) {
275  /* Sign will overwrite the non-forged signature, move that random value into the nonce. */
276  k[i] = s[i * 4 + secidx[i]];
277  secp256k1_scalar_clear(&s[i * 4 + secidx[i]]);
278  }
285  secp256k1_scalar_set_b32(&stmp, blind, &overflow);
286  secp256k1_scalar_add(&sec[rings - 1], &sec[rings - 1], &stmp);
287  if (overflow || secp256k1_scalar_is_zero(&sec[rings - 1])) {
288  return 0;
289  }
290  signs = &proof[len];
291  /* We need one sign bit for each blinded value we send. */
292  for (i = 0; i < (rings + 6) >> 3; i++) {
293  signs[i] = 0;
294  len++;
295  }
296  npub = 0;
297  for (i = 0; i < rings; i++) {
298  /*OPT: Use the precomputed gen2 basis?*/
299  secp256k1_pedersen_ecmult(&pubs[npub], &sec[i], ((uint64_t)secidx[i] * scale) << (i*2), genp, &secp256k1_ge_const_g);
300  if (secp256k1_gej_is_infinity(&pubs[npub])) {
301  return 0;
302  }
303  if (i < rings - 1) {
304  unsigned char tmpc[33];
305  secp256k1_ge c;
306  unsigned char quadness;
307  /*OPT: split loop and batch invert.*/
308  /*OPT: do not compute full pubs[npub] in ge form; we only need x */
309  secp256k1_ge_set_gej_var(&c, &pubs[npub]);
310  secp256k1_rangeproof_serialize_point(tmpc, &c);
311  quadness = tmpc[0];
312  secp256k1_sha256_write(&sha256_m, tmpc, 33);
313  signs[i>>3] |= quadness << (i&7);
314  memcpy(&proof[len], tmpc + 1, 32);
315  len += 32;
316  }
317  npub += rsizes[i];
318  }
319  secp256k1_rangeproof_pub_expand(pubs, exp, rsizes, rings, genp);
320  if (extra_commit != NULL) {
321  secp256k1_sha256_write(&sha256_m, extra_commit, extra_commit_len);
322  }
323  secp256k1_sha256_finalize(&sha256_m, tmp);
324  if (!secp256k1_borromean_sign(ecmult_ctx, ecmult_gen_ctx, &proof[len], s, pubs, k, sec, rsizes, secidx, rings, tmp, 32)) {
325  return 0;
326  }
327  len += 32;
328  for (i = 0; i < npub; i++) {
329  secp256k1_scalar_get_b32(&proof[len],&s[i]);
330  len += 32;
331  }
332  VERIFY_CHECK(len <= *plen);
333  *plen = len;
334  memset(prep, 0, 4096);
335  return 1;
336 }
337 
338 /* Computes blinding factor x given k, s, and the challenge e. */
339 SECP256K1_INLINE static void secp256k1_rangeproof_recover_x(secp256k1_scalar *x, const secp256k1_scalar *k, const secp256k1_scalar *e,
340  const secp256k1_scalar *s) {
341  secp256k1_scalar stmp;
342  secp256k1_scalar_negate(x, s);
343  secp256k1_scalar_add(x, x, k);
344  secp256k1_scalar_inverse(&stmp, e);
345  secp256k1_scalar_mul(x, x, &stmp);
346 }
347 
348 /* Computes ring's nonce given the blinding factor x, the challenge e, and the signature s. */
349 SECP256K1_INLINE static void secp256k1_rangeproof_recover_k(secp256k1_scalar *k, const secp256k1_scalar *x, const secp256k1_scalar *e,
350  const secp256k1_scalar *s) {
351  secp256k1_scalar stmp;
352  secp256k1_scalar_mul(&stmp, x, e);
353  secp256k1_scalar_add(k, s, &stmp);
354 }
355 
356 SECP256K1_INLINE static void secp256k1_rangeproof_ch32xor(unsigned char *x, const unsigned char *y) {
357  int i;
358  for (i = 0; i < 32; i++) {
359  x[i] ^= y[i];
360  }
361 }
362 
363 SECP256K1_INLINE static int secp256k1_rangeproof_rewind_inner(secp256k1_scalar *blind, uint64_t *v,
364  unsigned char *m, size_t *mlen, secp256k1_scalar *ev, secp256k1_scalar *s,
365  size_t *rsizes, size_t rings, const unsigned char *nonce, const secp256k1_ge *commit, const unsigned char *proof, size_t len, const secp256k1_ge *genp) {
366  secp256k1_scalar s_orig[128];
367  secp256k1_scalar sec[32];
368  secp256k1_scalar stmp;
369  unsigned char prep[4096];
370  unsigned char tmp[32];
371  uint64_t value;
372  size_t offset;
373  size_t i;
374  size_t j;
375  int b;
376  size_t skip1;
377  size_t skip2;
378  size_t npub;
379  npub = ((rings - 1) << 2) + rsizes[rings-1];
380  VERIFY_CHECK(npub <= 128);
381  VERIFY_CHECK(npub >= 1);
382  memset(prep, 0, 4096);
383  /* Reconstruct the provers random values. */
384  secp256k1_rangeproof_genrand(sec, s_orig, prep, rsizes, rings, nonce, commit, proof, len, genp);
385  *v = UINT64_MAX;
386  secp256k1_scalar_clear(blind);
387  if (rings == 1 && rsizes[0] == 1) {
388  /* With only a single proof, we can only recover the blinding factor. */
389  secp256k1_rangeproof_recover_x(blind, &s_orig[0], &ev[0], &s[0]);
390  if (v) {
391  *v = 0;
392  }
393  if (mlen) {
394  *mlen = 0;
395  }
396  return 1;
397  }
398  npub = (rings - 1) << 2;
399  for (j = 0; j < 2; j++) {
400  size_t idx;
401  /* Look for a value encoding in the last ring. */
402  idx = npub + rsizes[rings - 1] - 1 - j;
403  secp256k1_scalar_get_b32(tmp, &s[idx]);
404  secp256k1_rangeproof_ch32xor(tmp, &prep[idx * 32]);
405  if ((tmp[0] & 128) && (memcmp(&tmp[16], &tmp[24], 8) == 0) && (memcmp(&tmp[8], &tmp[16], 8) == 0)) {
406  value = 0;
407  for (i = 0; i < 8; i++) {
408  value = (value << 8) + tmp[24 + i];
409  }
410  if (v) {
411  *v = value;
412  }
413  memcpy(&prep[idx * 32], tmp, 32);
414  break;
415  }
416  }
417  if (j > 1) {
418  /* Couldn't extract a value. */
419  if (mlen) {
420  *mlen = 0;
421  }
422  return 0;
423  }
424  skip1 = rsizes[rings - 1] - 1 - j;
425  skip2 = ((value >> ((rings - 1) << 1)) & 3);
426  if (skip1 == skip2) {
427  /*Value is in wrong position.*/
428  if (mlen) {
429  *mlen = 0;
430  }
431  return 0;
432  }
433  skip1 += (rings - 1) << 2;
434  skip2 += (rings - 1) << 2;
435  /* Like in the rsize[] == 1 case, Having figured out which s is the one which was not forged, we can recover the blinding factor. */
436  secp256k1_rangeproof_recover_x(&stmp, &s_orig[skip2], &ev[skip2], &s[skip2]);
437  secp256k1_scalar_negate(&sec[rings - 1], &sec[rings - 1]);
438  secp256k1_scalar_add(blind, &stmp, &sec[rings - 1]);
439  if (!m || !mlen || *mlen == 0) {
440  if (mlen) {
441  *mlen = 0;
442  }
443  /* FIXME: cleanup in early out/failure cases. */
444  return 1;
445  }
446  offset = 0;
447  npub = 0;
448  for (i = 0; i < rings; i++) {
449  size_t idx;
450  idx = (value >> (i << 1)) & 3;
451  for (j = 0; j < rsizes[i]; j++) {
452  if (npub == skip1 || npub == skip2) {
453  npub++;
454  continue;
455  }
456  if (idx == j) {
461  secp256k1_rangeproof_recover_k(&stmp, &sec[i], &ev[npub], &s[npub]);
462  } else {
463  stmp = s[npub];
464  }
465  secp256k1_scalar_get_b32(tmp, &stmp);
466  secp256k1_rangeproof_ch32xor(tmp, &prep[npub * 32]);
467  for (b = 0; b < 32 && offset < *mlen; b++) {
468  m[offset] = tmp[b];
469  offset++;
470  }
471  npub++;
472  }
473  }
474  *mlen = offset;
475  memset(prep, 0, 4096);
476  for (i = 0; i < 128; i++) {
477  secp256k1_scalar_clear(&s_orig[i]);
478  }
479  for (i = 0; i < 32; i++) {
480  secp256k1_scalar_clear(&sec[i]);
481  }
482  secp256k1_scalar_clear(&stmp);
483  return 1;
484 }
485 
486 SECP256K1_INLINE static int secp256k1_rangeproof_getheader_impl(size_t *offset, int *exp, int *mantissa, uint64_t *scale,
487  uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, size_t plen) {
488  int i;
489  int has_nz_range;
490  int has_min;
491  if (plen < 65 || ((proof[*offset] & 128) != 0)) {
492  return 0;
493  }
494  has_nz_range = proof[*offset] & 64;
495  has_min = proof[*offset] & 32;
496  *exp = -1;
497  *mantissa = 0;
498  if (has_nz_range) {
499  *exp = proof[*offset] & 31;
500  *offset += 1;
501  if (*exp > 18) {
502  return 0;
503  }
504  *mantissa = proof[*offset] + 1;
505  if (*mantissa > 64) {
506  return 0;
507  }
508  *max_value = UINT64_MAX>>(64-*mantissa);
509  } else {
510  *max_value = 0;
511  }
512  *offset += 1;
513  *scale = 1;
514  for (i = 0; i < *exp; i++) {
515  if (*max_value > UINT64_MAX / 10) {
516  return 0;
517  }
518  *max_value *= 10;
519  *scale *= 10;
520  }
521  *min_value = 0;
522  if (has_min) {
523  if(plen - *offset < 8) {
524  return 0;
525  }
526  /*FIXME: Compact minvalue encoding?*/
527  for (i = 0; i < 8; i++) {
528  *min_value = (*min_value << 8) | proof[*offset + i];
529  }
530  *offset += 8;
531  }
532  if (*max_value > UINT64_MAX - *min_value) {
533  return 0;
534  }
535  *max_value += *min_value;
536  return 1;
537 }
538 
539 /* Verifies range proof (len plen) for commit, the min/max values proven are put in the min/max arguments; returns 0 on failure 1 on success.*/
540 SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecmult_context* ecmult_ctx,
541  const secp256k1_ecmult_gen_context* ecmult_gen_ctx,
542  unsigned char *blindout, uint64_t *value_out, unsigned char *message_out, size_t *outlen, const unsigned char *nonce,
543  uint64_t *min_value, uint64_t *max_value, const secp256k1_ge *commit, const unsigned char *proof, size_t plen, const unsigned char *extra_commit, size_t extra_commit_len, const secp256k1_ge* genp) {
544  secp256k1_gej accj;
545  secp256k1_gej pubs[128];
546  secp256k1_ge c;
547  secp256k1_scalar s[128];
548  secp256k1_scalar evalues[128]; /* Challenges, only used during proof rewind. */
549  secp256k1_sha256 sha256_m;
550  size_t rsizes[32];
551  int ret;
552  size_t i;
553  int exp;
554  int mantissa;
555  size_t offset;
556  size_t rings;
557  int overflow;
558  size_t npub;
559  int offset_post_header;
560  uint64_t scale;
561  unsigned char signs[31];
562  unsigned char m[33];
563  const unsigned char *e0;
564  offset = 0;
565  if (!secp256k1_rangeproof_getheader_impl(&offset, &exp, &mantissa, &scale, min_value, max_value, proof, plen)) {
566  return 0;
567  }
568  offset_post_header = offset;
569  rings = 1;
570  rsizes[0] = 1;
571  npub = 1;
572  if (mantissa != 0) {
573  rings = (mantissa >> 1);
574  for (i = 0; i < rings; i++) {
575  rsizes[i] = 4;
576  }
577  npub = (mantissa >> 1) << 2;
578  if (mantissa & 1) {
579  rsizes[rings] = 2;
580  npub += rsizes[rings];
581  rings++;
582  }
583  }
584  VERIFY_CHECK(rings <= 32);
585  if (plen - offset < 32 * (npub + rings - 1) + 32 + ((rings+6) >> 3)) {
586  return 0;
587  }
588  secp256k1_sha256_initialize(&sha256_m);
589  secp256k1_rangeproof_serialize_point(m, commit);
590  secp256k1_sha256_write(&sha256_m, m, 33);
591  secp256k1_rangeproof_serialize_point(m, genp);
592  secp256k1_sha256_write(&sha256_m, m, 33);
593  secp256k1_sha256_write(&sha256_m, proof, offset);
594  for(i = 0; i < rings - 1; i++) {
595  signs[i] = (proof[offset + ( i>> 3)] & (1 << (i & 7))) != 0;
596  }
597  offset += (rings + 6) >> 3;
598  if ((rings - 1) & 7) {
599  /* Number of coded blinded points is not a multiple of 8, force extra sign bits to 0 to reject mutation. */
600  if ((proof[offset - 1] >> ((rings - 1) & 7)) != 0) {
601  return 0;
602  }
603  }
604  npub = 0;
605  secp256k1_gej_set_infinity(&accj);
606  if (*min_value) {
607  secp256k1_scalar mvs;
608  secp256k1_scalar_set_u64(&mvs, *min_value);
609  secp256k1_ecmult_const(&accj, genp, &mvs, 64);
610  secp256k1_scalar_clear(&mvs);
611  }
612  for(i = 0; i < rings - 1; i++) {
613  secp256k1_fe fe;
614  if (!secp256k1_fe_set_b32(&fe, &proof[offset]) ||
615  !secp256k1_ge_set_xquad(&c, &fe)) {
616  return 0;
617  }
618  if (signs[i]) {
619  secp256k1_ge_neg(&c, &c);
620  }
621  /* Not using secp256k1_rangeproof_serialize_point as we almost have it
622  * serialized form already. */
623  secp256k1_sha256_write(&sha256_m, &signs[i], 1);
624  secp256k1_sha256_write(&sha256_m, &proof[offset], 32);
625  secp256k1_gej_set_ge(&pubs[npub], &c);
626  secp256k1_gej_add_ge_var(&accj, &accj, &c, NULL);
627  offset += 32;
628  npub += rsizes[i];
629  }
630  secp256k1_gej_neg(&accj, &accj);
631  secp256k1_gej_add_ge_var(&pubs[npub], &accj, commit, NULL);
632  if (secp256k1_gej_is_infinity(&pubs[npub])) {
633  return 0;
634  }
635  secp256k1_rangeproof_pub_expand(pubs, exp, rsizes, rings, genp);
636  npub += rsizes[rings - 1];
637  e0 = &proof[offset];
638  offset += 32;
639  for (i = 0; i < npub; i++) {
640  secp256k1_scalar_set_b32(&s[i], &proof[offset], &overflow);
641  if (overflow) {
642  return 0;
643  }
644  offset += 32;
645  }
646  if (offset != plen) {
647  /*Extra data found, reject.*/
648  return 0;
649  }
650  if (extra_commit != NULL) {
651  secp256k1_sha256_write(&sha256_m, extra_commit, extra_commit_len);
652  }
653  secp256k1_sha256_finalize(&sha256_m, m);
654  ret = secp256k1_borromean_verify(ecmult_ctx, nonce ? evalues : NULL, e0, s, pubs, rsizes, rings, m, 32);
655  if (ret && nonce) {
656  /* Given the nonce, try rewinding the witness to recover its initial state. */
657  secp256k1_scalar blind;
658  uint64_t vv;
659  if (!ecmult_gen_ctx) {
660  return 0;
661  }
662  if (!secp256k1_rangeproof_rewind_inner(&blind, &vv, message_out, outlen, evalues, s, rsizes, rings, nonce, commit, proof, offset_post_header, genp)) {
663  return 0;
664  }
665  /* Unwind apparently successful, see if the commitment can be reconstructed. */
666  /* FIXME: should check vv is in the mantissa's range. */
667  vv = (vv * scale) + *min_value;
668  secp256k1_pedersen_ecmult(&accj, &blind, vv, genp, &secp256k1_ge_const_g);
669  if (secp256k1_gej_is_infinity(&accj)) {
670  return 0;
671  }
672  secp256k1_gej_neg(&accj, &accj);
673  secp256k1_gej_add_ge_var(&accj, &accj, commit, NULL);
674  if (!secp256k1_gej_is_infinity(&accj)) {
675  return 0;
676  }
677  if (blindout) {
678  secp256k1_scalar_get_b32(blindout, &blind);
679  }
680  if (value_out) {
681  *value_out = vv;
682  }
683  }
684  return ret;
685 }
686 
687 #endif
VERIFY_CHECK
#define VERIFY_CHECK(cond)
Definition: util.h:61
secp256k1_ge::y
secp256k1_fe y
Definition: group.h:20
b
void const uint64_t * b
Definition: field_5x52_asm_impl.h:10
memcpy
void * memcpy(void *a, const void *b, size_t c)
Definition: glibc_compat.cpp:15
secp256k1_sha256
Definition: hash.h:13
secp256k1_scalar
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
secp256k1_borromean_sign
int secp256k1_borromean_sign(const secp256k1_ecmult_context *ecmult_ctx, const secp256k1_ecmult_gen_context *ecmult_gen_ctx, unsigned char *e0, secp256k1_scalar *s, const secp256k1_gej *pubs, const secp256k1_scalar *k, const secp256k1_scalar *sec, const size_t *rsizes, const size_t *secidx, size_t nrings, const unsigned char *m, size_t mlen)
Definition: borromean_impl.h:112
secp256k1_gej
A group element of the secp256k1 curve, in jacobian coordinates.
Definition: group.h:24
secp256k1_borromean_verify
int secp256k1_borromean_verify(const secp256k1_ecmult_context *ecmult_ctx, secp256k1_scalar *evalues, const unsigned char *e0, const secp256k1_scalar *s, const secp256k1_gej *pubs, const size_t *rsizes, size_t nrings, const unsigned char *m, size_t mlen)
"Borromean" ring signature.
Definition: borromean_impl.h:58
secp256k1_fe
Definition: field_10x26.h:12
hash_impl.h
secp256k1_ecmult_gen_context
Definition: ecmult_gen.h:13
borromean.h
pedersen_impl.h
secp256k1_rfc6979_hmac_sha256
Definition: hash.h:31
SECP256K1_INLINE
#define SECP256K1_INLINE
Definition: secp256k1.h:23
secp256k1_ge::x
secp256k1_fe x
Definition: group.h:19
secp256k1_ecmult_context
Definition: ecmult.h:15
rangeproof.h
secp256k1_ge
A group element of the secp256k1 curve, in affine coordinates.
Definition: group.h:14