PRCYCoin  2.0.0.7rc1
P2P Digital Currency
tests_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_MODULE_RANGEPROOF_TESTS
8 #define SECP256K1_MODULE_RANGEPROOF_TESTS
9 
10 #include <string.h>
11 
12 #include "group.h"
13 #include "scalar.h"
14 #include "testrand.h"
15 #include "util.h"
16 
19 
20 static void test_rangeproof_api(const secp256k1_context2 *none, const secp256k1_context2 *sign, const secp256k1_context2 *vrfy, const secp256k1_context2 *both, const int32_t *ecount) {
21  unsigned char proof[5134];
22  unsigned char blind[32];
24  uint64_t vmin = secp256k1_rand32();
25  uint64_t val = vmin + secp256k1_rand32();
26  size_t len = sizeof(proof);
27  /* we'll switch to dylan thomas for this one */
28  const unsigned char message[68] = "My tears are like the quiet drift / Of petals from some magic rose;";
29  size_t mlen = sizeof(message);
30  const unsigned char ext_commit[72] = "And all my grief flows from the rift / Of unremembered skies and snows.";
31  size_t ext_commit_len = sizeof(ext_commit);
32 
33  secp256k1_rand256(blind);
35 
36  CHECK(secp256k1_rangeproof_sign(none, proof, &len, vmin, &commit, blind, commit.data, 0, 0, val, message, mlen, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
37  CHECK(*ecount == 1);
38  CHECK(secp256k1_rangeproof_sign(sign, proof, &len, vmin, &commit, blind, commit.data, 0, 0, val, message, mlen, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
39  CHECK(*ecount == 2);
40  CHECK(secp256k1_rangeproof_sign(vrfy, proof, &len, vmin, &commit, blind, commit.data, 0, 0, val, message, mlen, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
41  CHECK(*ecount == 3);
42  CHECK(secp256k1_rangeproof_sign(both, proof, &len, vmin, &commit, blind, commit.data, 0, 0, val, message, mlen, ext_commit, ext_commit_len, &secp256k1_generator_const_h) != 0);
43  CHECK(*ecount == 3);
44 
45  CHECK(secp256k1_rangeproof_sign(both, NULL, &len, vmin, &commit, blind, commit.data, 0, 0, val, message, mlen, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
46  CHECK(*ecount == 4);
47  CHECK(secp256k1_rangeproof_sign(both, proof, NULL, vmin, &commit, blind, commit.data, 0, 0, val, message, mlen, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
48  CHECK(*ecount == 5);
49  CHECK(secp256k1_rangeproof_sign(both, proof, &len, vmin, NULL, blind, commit.data, 0, 0, val, message, mlen, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
50  CHECK(*ecount == 6);
51  CHECK(secp256k1_rangeproof_sign(both, proof, &len, vmin, &commit, NULL, commit.data, 0, 0, val, message, mlen, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
52  CHECK(*ecount == 7);
53  CHECK(secp256k1_rangeproof_sign(both, proof, &len, vmin, &commit, blind, NULL, 0, 0, val, message, mlen, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
54  CHECK(*ecount == 8);
55  CHECK(secp256k1_rangeproof_sign(both, proof, &len, vmin, &commit, blind, commit.data, 0, 0, vmin - 1, message, mlen, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
56  CHECK(*ecount == 8);
57  CHECK(secp256k1_rangeproof_sign(both, proof, &len, vmin, &commit, blind, commit.data, 0, 0, val, NULL, mlen, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
58  CHECK(*ecount == 9);
59  CHECK(secp256k1_rangeproof_sign(both, proof, &len, vmin, &commit, blind, commit.data, 0, 0, val, NULL, 0, ext_commit, ext_commit_len, &secp256k1_generator_const_h) != 0);
60  CHECK(*ecount == 9);
61  CHECK(secp256k1_rangeproof_sign(both, proof, &len, vmin, &commit, blind, commit.data, 0, 0, val, NULL, 0, NULL, ext_commit_len, &secp256k1_generator_const_h) == 0);
62  CHECK(*ecount == 10);
63  CHECK(secp256k1_rangeproof_sign(both, proof, &len, vmin, &commit, blind, commit.data, 0, 0, val, NULL, 0, NULL, 0, &secp256k1_generator_const_h) != 0);
64  CHECK(*ecount == 10);
65  CHECK(secp256k1_rangeproof_sign(both, proof, &len, vmin, &commit, blind, commit.data, 0, 0, val, NULL, 0, NULL, 0, NULL) == 0);
66  CHECK(*ecount == 11);
67 
68  CHECK(secp256k1_rangeproof_sign(both, proof, &len, vmin, &commit, blind, commit.data, 0, 0, val, message, mlen, ext_commit, ext_commit_len, &secp256k1_generator_const_h) != 0);
69  {
70  int exp;
71  int mantissa;
72  uint64_t min_value;
73  uint64_t max_value;
74  CHECK(secp256k1_rangeproof_info(none, &exp, &mantissa, &min_value, &max_value, proof, len) != 0);
75  CHECK(exp == 0);
76  CHECK(((uint64_t) 1 << mantissa) > val - vmin);
77  CHECK(((uint64_t) 1 << (mantissa - 1)) <= val - vmin);
78  CHECK(min_value == vmin);
79  CHECK(max_value >= val);
80 
81  CHECK(secp256k1_rangeproof_info(none, NULL, &mantissa, &min_value, &max_value, proof, len) == 0);
82  CHECK(*ecount == 12);
83  CHECK(secp256k1_rangeproof_info(none, &exp, NULL, &min_value, &max_value, proof, len) == 0);
84  CHECK(*ecount == 13);
85  CHECK(secp256k1_rangeproof_info(none, &exp, &mantissa, NULL, &max_value, proof, len) == 0);
86  CHECK(*ecount == 14);
87  CHECK(secp256k1_rangeproof_info(none, &exp, &mantissa, &min_value, NULL, proof, len) == 0);
88  CHECK(*ecount == 15);
89  CHECK(secp256k1_rangeproof_info(none, &exp, &mantissa, &min_value, &max_value, NULL, len) == 0);
90  CHECK(*ecount == 16);
91  CHECK(secp256k1_rangeproof_info(none, &exp, &mantissa, &min_value, &max_value, proof, 0) == 0);
92  CHECK(*ecount == 16);
93  }
94  {
95  uint64_t min_value;
96  uint64_t max_value;
97  CHECK(secp256k1_rangeproof_verify(none, &min_value, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
98  CHECK(*ecount == 17);
99  CHECK(secp256k1_rangeproof_verify(sign, &min_value, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
100  CHECK(*ecount == 18);
101  CHECK(secp256k1_rangeproof_verify(vrfy, &min_value, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) != 0);
102  CHECK(*ecount == 18);
103 
104  CHECK(secp256k1_rangeproof_verify(vrfy, NULL, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
105  CHECK(*ecount == 19);
106  CHECK(secp256k1_rangeproof_verify(vrfy, &min_value, NULL, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
107  CHECK(*ecount == 20);
108  CHECK(secp256k1_rangeproof_verify(vrfy, &min_value, &max_value, NULL, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
109  CHECK(*ecount == 21);
110  CHECK(secp256k1_rangeproof_verify(vrfy, &min_value, &max_value, &commit, NULL, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
111  CHECK(*ecount == 22);
112  CHECK(secp256k1_rangeproof_verify(vrfy, &min_value, &max_value, &commit, proof, 0, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
113  CHECK(*ecount == 22);
114  CHECK(secp256k1_rangeproof_verify(vrfy, &min_value, &max_value, &commit, proof, len, NULL, ext_commit_len, &secp256k1_generator_const_h) == 0);
115  CHECK(*ecount == 23);
116  CHECK(secp256k1_rangeproof_verify(vrfy, &min_value, &max_value, &commit, proof, len, NULL, 0, &secp256k1_generator_const_h) == 0);
117  CHECK(*ecount == 23);
118  CHECK(secp256k1_rangeproof_verify(vrfy, &min_value, &max_value, &commit, proof, len, NULL, 0, NULL) == 0);
119  CHECK(*ecount == 24);
120  }
121  {
122  unsigned char blind_out[32];
123  unsigned char message_out[68];
124  uint64_t value_out;
125  uint64_t min_value;
126  uint64_t max_value;
127  size_t message_len = sizeof(message_out);
128 
129  CHECK(secp256k1_rangeproof_rewind(none, blind_out, &value_out, message_out, &message_len, commit.data, &min_value, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
130  CHECK(*ecount == 25);
131  CHECK(secp256k1_rangeproof_rewind(sign, blind_out, &value_out, message_out, &message_len, commit.data, &min_value, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
132  CHECK(*ecount == 26);
133  CHECK(secp256k1_rangeproof_rewind(vrfy, blind_out, &value_out, message_out, &message_len, commit.data, &min_value, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
134  CHECK(*ecount == 27);
135  CHECK(secp256k1_rangeproof_rewind(both, blind_out, &value_out, message_out, &message_len, commit.data, &min_value, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) != 0);
136  CHECK(*ecount == 27);
137 
138  CHECK(min_value == vmin);
139  CHECK(max_value >= val);
140  CHECK(value_out == val);
141  CHECK(message_len == sizeof(message_out));
142  CHECK(memcmp(message, message_out, sizeof(message_out)) == 0);
143 
144  CHECK(secp256k1_rangeproof_rewind(both, NULL, &value_out, message_out, &message_len, commit.data, &min_value, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) != 0);
145  CHECK(*ecount == 27); /* blindout may be NULL */
146  CHECK(secp256k1_rangeproof_rewind(both, blind_out, NULL, message_out, &message_len, commit.data, &min_value, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) != 0);
147  CHECK(*ecount == 27); /* valueout may be NULL */
148  CHECK(secp256k1_rangeproof_rewind(both, blind_out, &value_out, NULL, &message_len, commit.data, &min_value, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
149  CHECK(*ecount == 28);
150  CHECK(secp256k1_rangeproof_rewind(both, blind_out, &value_out, NULL, 0, commit.data, &min_value, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) != 0);
151  CHECK(*ecount == 28);
152  CHECK(secp256k1_rangeproof_rewind(both, blind_out, &value_out, NULL, 0, NULL, &min_value, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
153  CHECK(*ecount == 29);
154  CHECK(secp256k1_rangeproof_rewind(both, blind_out, &value_out, NULL, 0, commit.data, NULL, &max_value, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
155  CHECK(*ecount == 30);
156  CHECK(secp256k1_rangeproof_rewind(both, blind_out, &value_out, NULL, 0, commit.data, &min_value, NULL, &commit, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
157  CHECK(*ecount == 31);
158  CHECK(secp256k1_rangeproof_rewind(both, blind_out, &value_out, NULL, 0, commit.data, &min_value, &max_value, NULL, proof, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
159  CHECK(*ecount == 32);
160  CHECK(secp256k1_rangeproof_rewind(both, blind_out, &value_out, NULL, 0, commit.data, &min_value, &max_value, &commit, NULL, len, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
161  CHECK(*ecount == 33);
162  CHECK(secp256k1_rangeproof_rewind(both, blind_out, &value_out, NULL, 0, commit.data, &min_value, &max_value, &commit, proof, 0, ext_commit, ext_commit_len, &secp256k1_generator_const_h) == 0);
163  CHECK(*ecount == 33);
164  CHECK(secp256k1_rangeproof_rewind(both, blind_out, &value_out, NULL, 0, commit.data, &min_value, &max_value, &commit, proof, len, NULL, ext_commit_len, &secp256k1_generator_const_h) == 0);
165  CHECK(*ecount == 34);
166  CHECK(secp256k1_rangeproof_rewind(both, blind_out, &value_out, NULL, 0, commit.data, &min_value, &max_value, &commit, proof, len, NULL, 0, &secp256k1_generator_const_h) == 0);
167  CHECK(*ecount == 34);
168  CHECK(secp256k1_rangeproof_rewind(both, blind_out, &value_out, NULL, 0, commit.data, &min_value, &max_value, &commit, proof, len, NULL, 0, NULL) == 0);
169  CHECK(*ecount == 35);
170  }
171 }
172 
173 static void test_api(void) {
178  int32_t ecount;
179  int i;
180 
181  secp256k1_context_set_error_callback(none, counting_illegal_callback_fn, &ecount);
182  secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount);
183  secp256k1_context_set_error_callback(vrfy, counting_illegal_callback_fn, &ecount);
184  secp256k1_context_set_error_callback(both, counting_illegal_callback_fn, &ecount);
185  secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount);
186  secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount);
187  secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount);
188  secp256k1_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount);
189 
190  for (i = 0; i < count; i++) {
191  ecount = 0;
192  test_rangeproof_api(none, sign, vrfy, both, &ecount);
193  }
194 
199 }
200 
201 static void test_borromean(void) {
202  unsigned char e0[32];
203  secp256k1_scalar s[64];
204  secp256k1_gej pubs[64];
205  secp256k1_scalar k[8];
206  secp256k1_scalar sec[8];
207  secp256k1_ge ge;
208  secp256k1_scalar one;
209  unsigned char m[32];
210  size_t rsizes[8];
211  size_t secidx[8];
212  size_t nrings;
213  size_t i;
214  size_t j;
215  int c;
216  secp256k1_rand256_test(m);
217  nrings = 1 + (secp256k1_rand32()&7);
218  c = 0;
219  secp256k1_scalar_set_int(&one, 1);
220  if (secp256k1_rand32()&1) {
221  secp256k1_scalar_negate(&one, &one);
222  }
223  for (i = 0; i < nrings; i++) {
224  rsizes[i] = 1 + (secp256k1_rand32()&7);
225  secidx[i] = secp256k1_rand32() % rsizes[i];
226  random_scalar_order(&sec[i]);
227  random_scalar_order(&k[i]);
228  if(secp256k1_rand32()&7) {
229  sec[i] = one;
230  }
231  if(secp256k1_rand32()&7) {
232  k[i] = one;
233  }
234  for (j = 0; j < rsizes[i]; j++) {
235  random_scalar_order(&s[c + j]);
236  if(secp256k1_rand32()&7) {
237  s[i] = one;
238  }
239  if (j == secidx[i]) {
240  secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubs[c + j], &sec[i]);
241  } else {
243  random_group_element_jacobian_test(&pubs[c + j],&ge);
244  }
245  }
246  c += rsizes[i];
247  }
248  CHECK(secp256k1_borromean_sign(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx, e0, s, pubs, k, sec, rsizes, secidx, nrings, m, 32));
249  CHECK(secp256k1_borromean_verify(&ctx->ecmult_ctx, NULL, e0, s, pubs, rsizes, nrings, m, 32));
250  i = secp256k1_rand32() % c;
251  secp256k1_scalar_negate(&s[i],&s[i]);
252  CHECK(!secp256k1_borromean_verify(&ctx->ecmult_ctx, NULL, e0, s, pubs, rsizes, nrings, m, 32));
253  secp256k1_scalar_negate(&s[i],&s[i]);
254  secp256k1_scalar_set_int(&one, 1);
255  for(j = 0; j < 4; j++) {
256  i = secp256k1_rand32() % c;
257  if (secp256k1_rand32() & 1) {
258  secp256k1_gej_double_var(&pubs[i],&pubs[i], NULL);
259  } else {
260  secp256k1_scalar_add(&s[i],&s[i],&one);
261  }
262  CHECK(!secp256k1_borromean_verify(&ctx->ecmult_ctx, NULL, e0, s, pubs, rsizes, nrings, m, 32));
263  }
264 }
265 
266 static void test_rangeproof(void) {
267  const uint64_t testvs[11] = {0, 1, 5, 11, 65535, 65537, INT32_MAX, UINT32_MAX, INT64_MAX - 1, INT64_MAX, UINT64_MAX};
270  unsigned char proof[5134 + 1]; /* One additional byte to test if trailing bytes are rejected */
271  unsigned char blind[32];
272  unsigned char blindout[32];
273  unsigned char message[4096];
274  size_t mlen;
275  uint64_t v;
276  uint64_t vout;
277  uint64_t vmin;
278  uint64_t minv;
279  uint64_t maxv;
280  size_t len;
281  size_t i;
282  size_t j;
283  size_t k;
284  /* Short message is a Simone de Beauvoir quote */
285  const unsigned char message_short[120] = "When I see my own likeness in the depths of someone else's consciousness, I always experience a moment of panic.";
286  /* Long message is 0xA5 with a bunch of this quote in the middle */
287  unsigned char message_long[3968];
288  memset(message_long, 0xa5, sizeof(message_long));
289  for (i = 1200; i < 3600; i += 120) {
290  memcpy(&message_long[i], message_short, sizeof(message_short));
291  }
292 
293  secp256k1_rand256(blind);
294  for (i = 0; i < 11; i++) {
295  v = testvs[i];
297  for (vmin = 0; vmin < (i<9 && i > 0 ? 2 : 1); vmin++) {
298  const unsigned char *input_message = NULL;
299  size_t input_message_len = 0;
300  /* vmin is always either 0 or 1; if it is 1, then we have no room for a message.
301  * If it's 0, we use "minimum encoding" and only have room for a small message when
302  * `testvs[i]` is >= 4; for a large message when it's >= 2^32. */
303  if (vmin == 0 && i > 2) {
304  input_message = message_short;
305  input_message_len = sizeof(message_short);
306  }
307  if (vmin == 0 && i > 7) {
308  input_message = message_long;
309  input_message_len = sizeof(message_long);
310  }
311  len = 5134;
312  CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, 0, 0, v, input_message, input_message_len, NULL, 0, &secp256k1_generator_const_h));
313  CHECK(len <= 5134);
314  mlen = 4096;
315  CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len, NULL, 0, &secp256k1_generator_const_h));
316  if (input_message != NULL) {
317  CHECK(memcmp(message, input_message, input_message_len) == 0);
318  }
319  for (j = input_message_len; j < mlen; j++) {
320  CHECK(message[j] == 0);
321  }
322  CHECK(mlen <= 4096);
323  CHECK(memcmp(blindout, blind, 32) == 0);
324  CHECK(vout == v);
325  CHECK(minv <= v);
326  CHECK(maxv >= v);
327  len = 5134;
328  CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, v, &commit, blind, commit.data, -1, 64, v, NULL, 0, NULL, 0, &secp256k1_generator_const_h));
329  CHECK(len <= 73);
330  CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, NULL, 0, &secp256k1_generator_const_h));
331  CHECK(memcmp(blindout, blind, 32) == 0);
332  CHECK(vout == v);
333  CHECK(minv == v);
334  CHECK(maxv == v);
335 
336  /* Check with a committed message */
337  len = 5134;
338  CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, v, &commit, blind, commit.data, -1, 64, v, NULL, 0, message_short, sizeof(message_short), &secp256k1_generator_const_h));
339  CHECK(len <= 73);
340  CHECK(!secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, NULL, 0, &secp256k1_generator_const_h));
341  CHECK(!secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, message_long, sizeof(message_long), &secp256k1_generator_const_h));
342  CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, message_short, sizeof(message_short), &secp256k1_generator_const_h));
343  CHECK(memcmp(blindout, blind, 32) == 0);
344  CHECK(vout == v);
345  CHECK(minv == v);
346  CHECK(maxv == v);
347  }
348  }
349  secp256k1_rand256(blind);
350  v = INT64_MAX - 1;
352  for (i = 0; i < 19; i++) {
353  len = 5134;
354  CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, i, 0, v, NULL, 0, NULL, 0, &secp256k1_generator_const_h));
355  CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len, NULL, 0, &secp256k1_generator_const_h));
356  CHECK(len <= 5134);
357  CHECK(minv <= v);
358  CHECK(maxv >= v);
359  /* Make sure it fails when validating with a committed message */
360  CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len, message_short, sizeof(message_short), &secp256k1_generator_const_h));
361  }
362  secp256k1_rand256(blind);
363  {
364  /*Malleability test.*/
365  v = secp256k1_rands64(0, 255);
367  len = 5134;
368  CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, 0, 3, v, NULL, 0, NULL, 0, &secp256k1_generator_const_h));
369  CHECK(len <= 5134);
370  /* Test if trailing bytes are rejected. */
371  proof[len] = v;
372  CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len + 1, NULL, 0, &secp256k1_generator_const_h));
373  for (i = 0; i < len*8; i++) {
374  proof[i >> 3] ^= 1 << (i & 7);
375  CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len, NULL, 0, &secp256k1_generator_const_h));
376  proof[i >> 3] ^= 1 << (i & 7);
377  }
378  CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len, NULL, 0, &secp256k1_generator_const_h));
379  CHECK(minv <= v);
380  CHECK(maxv >= v);
381  }
382  memcpy(&commit2, &commit, sizeof(commit));
383  for (i = 0; i < 10 * (size_t) count; i++) {
384  int exp;
385  int min_bits;
386  v = secp256k1_rands64(0, UINT64_MAX >> (secp256k1_rand32()&63));
387  vmin = 0;
388  if ((v < INT64_MAX) && (secp256k1_rand32()&1)) {
389  vmin = secp256k1_rands64(0, v);
390  }
391  secp256k1_rand256(blind);
393  len = 5134;
394  exp = (int)secp256k1_rands64(0,18)-(int)secp256k1_rands64(0,18);
395  if (exp < 0) {
396  exp = -exp;
397  }
398  min_bits = (int)secp256k1_rands64(0,64)-(int)secp256k1_rands64(0,64);
399  if (min_bits < 0) {
400  min_bits = -min_bits;
401  }
402  CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, exp, min_bits, v, NULL, 0, NULL, 0, &secp256k1_generator_const_h));
403  CHECK(len <= 5134);
404  mlen = 4096;
405  CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len, NULL, 0, &secp256k1_generator_const_h));
406  for (j = 0; j < mlen; j++) {
407  CHECK(message[j] == 0);
408  }
409  CHECK(mlen <= 4096);
410  CHECK(memcmp(blindout, blind, 32) == 0);
411  CHECK(vout == v);
412  CHECK(minv <= v);
413  CHECK(maxv >= v);
414  CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, NULL, 0, &secp256k1_generator_const_h));
415  memcpy(&commit2, &commit, sizeof(commit));
416  }
417  for (j = 0; j < 10; j++) {
418  for (i = 0; i < 96; i++) {
419  secp256k1_rand256(&proof[i * 32]);
420  }
421  for (k = 0; k < 128; k++) {
422  len = k;
423  CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit2, proof, len, NULL, 0, &secp256k1_generator_const_h));
424  }
425  len = secp256k1_rands64(0, 3072);
426  CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit2, proof, len, NULL, 0, &secp256k1_generator_const_h));
427  }
428 }
429 
431  const unsigned char vector_1[] = {
432  0x62, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x02, 0x2a, 0x5c, 0x42, 0x0e, 0x1d,
433  0x51, 0xe1, 0xb7, 0xf3, 0x69, 0x04, 0xb5, 0xbb, 0x9b, 0x41, 0x66, 0x14, 0xf3, 0x64, 0x42, 0x26,
434  0xe3, 0xa7, 0x6a, 0x06, 0xbb, 0xa8, 0x5a, 0x49, 0x6f, 0x19, 0x76, 0xfb, 0xe5, 0x75, 0x77, 0x88,
435  0xab, 0xa9, 0x66, 0x44, 0x80, 0xea, 0x29, 0x95, 0x7f, 0xdf, 0x72, 0x4a, 0xaf, 0x02, 0xbe, 0xdd,
436  0x5d, 0x15, 0xd8, 0xae, 0xff, 0x74, 0xc9, 0x8c, 0x1a, 0x67, 0x0e, 0xb2, 0x57, 0x22, 0x99, 0xc3,
437  0x21, 0x46, 0x6f, 0x15, 0x58, 0x0e, 0xdb, 0xe6, 0x6e, 0xc4, 0x0d, 0xfe, 0x6f, 0x04, 0x6b, 0x0d,
438  0x18, 0x3d, 0x78, 0x40, 0x98, 0x56, 0x4e, 0xe4, 0x4a, 0x74, 0x90, 0xa7, 0xac, 0x9c, 0x16, 0xe0,
439  0x3e, 0x81, 0xaf, 0x0f, 0xe3, 0x4f, 0x34, 0x99, 0x52, 0xf7, 0xa7, 0xf6, 0xd3, 0x83, 0xa0, 0x17,
440  0x4b, 0x2d, 0xa7, 0xd4, 0xfd, 0xf7, 0x84, 0x45, 0xc4, 0x11, 0x71, 0x3d, 0x4a, 0x22, 0x34, 0x09,
441  0x9c, 0xa7, 0xe5, 0xc8, 0xba, 0x04, 0xbf, 0xfd, 0x25, 0x11, 0x7d, 0xa4, 0x43, 0x45, 0xc7, 0x62,
442  0x9e, 0x7b, 0x80, 0xf6, 0x09, 0xbb, 0x1b, 0x2e, 0xf3, 0xcd, 0x23, 0xe0, 0xed, 0x81, 0x43, 0x42,
443  0xbe, 0xc4, 0x9f, 0x58, 0x8a, 0x0d, 0x66, 0x79, 0x09, 0x70, 0x11, 0x68, 0x3d, 0x87, 0x38, 0x1c,
444  0x3c, 0x85, 0x52, 0x5b, 0x62, 0xf7, 0x3e, 0x7e, 0x87, 0xa2, 0x99, 0x24, 0xd0, 0x7d, 0x18, 0x63,
445  0x56, 0x48, 0xa4, 0x3a, 0xfe, 0x65, 0xfa, 0xa4, 0xd0, 0x67, 0xaa, 0x98, 0x65, 0x4d, 0xe4, 0x22,
446  0x75, 0x45, 0x52, 0xe8, 0x41, 0xc7, 0xed, 0x38, 0xeb, 0xf5, 0x02, 0x90, 0xc9, 0x45, 0xa3, 0xb0,
447  0x4d, 0x03, 0xd7, 0xab, 0x43, 0xe4, 0x21, 0xfc, 0x83, 0xd6, 0x12, 0x1d, 0x76, 0xb1, 0x3c, 0x67,
448  0x63, 0x1f, 0x52, 0x9d, 0xc3, 0x23, 0x5c, 0x4e, 0xa6, 0x8d, 0x01, 0x4a, 0xba, 0x9a, 0xf4, 0x16,
449  0x5b, 0x67, 0xc8, 0xe1, 0xd2, 0x42, 0x6d, 0xdf, 0xcd, 0x08, 0x6a, 0x73, 0x41, 0x6a, 0xc2, 0x84,
450  0xc6, 0x31, 0xbe, 0x57, 0xcb, 0x0e, 0xde, 0xbf, 0x71, 0xd5, 0x8a, 0xf7, 0x24, 0xb2, 0xa7, 0x89,
451  0x96, 0x62, 0x4f, 0xd9, 0xf7, 0xc3, 0xde, 0x4c, 0xab, 0x13, 0x72, 0xb4, 0xb3, 0x35, 0x04, 0x82,
452  0xa8, 0x75, 0x1d, 0xde, 0x46, 0xa8, 0x0d, 0xb8, 0x23, 0x44, 0x00, 0x44, 0xfa, 0x53, 0x6c, 0x2d,
453  0xce, 0xd3, 0xa6, 0x80, 0xa1, 0x20, 0xca, 0xd1, 0x63, 0xbb, 0xbe, 0x39, 0x5f, 0x9d, 0x27, 0x69,
454  0xb3, 0x33, 0x1f, 0xdb, 0xda, 0x67, 0x05, 0x37, 0xbe, 0x65, 0xe9, 0x7e, 0xa9, 0xc3, 0xff, 0x37,
455  0x8a, 0xb4, 0x2d, 0xfe, 0xf2, 0x16, 0x85, 0xc7, 0x0f, 0xd9, 0xbe, 0x14, 0xd1, 0x80, 0x14, 0x9f,
456  0x58, 0x56, 0x98, 0x41, 0xf6, 0x26, 0xf7, 0xa2, 0x71, 0x66, 0xb4, 0x7a, 0x9c, 0x12, 0x73, 0xd3,
457  0xdf, 0x77, 0x2b, 0x49, 0xe5, 0xca, 0x50, 0x57, 0x44, 0x6e, 0x3f, 0x58, 0x56, 0xbc, 0x21, 0x70,
458  0x4f, 0xc6, 0xaa, 0x12, 0xff, 0x7c, 0xa7, 0x3d, 0xed, 0x46, 0xc1, 0x40, 0xe6, 0x58, 0x09, 0x2a,
459  0xda, 0xb3, 0x76, 0xab, 0x44, 0xb5, 0x4e, 0xb3, 0x12, 0xe0, 0x26, 0x8a, 0x52, 0xac, 0x49, 0x1d,
460  0xe7, 0x06, 0x53, 0x3a, 0x01, 0x35, 0x21, 0x2e, 0x86, 0x48, 0xc5, 0x75, 0xc1, 0xa2, 0x7d, 0x22,
461  0x53, 0xf6, 0x3f, 0x41, 0xc5, 0xb3, 0x08, 0x7d, 0xa3, 0x67, 0xc0, 0xbb, 0xb6, 0x8d, 0xf0, 0xd3,
462  0x01, 0x72, 0xd3, 0x63, 0x82, 0x01, 0x1a, 0xe7, 0x1d, 0x22, 0xfa, 0x95, 0x33, 0xf6, 0xf2, 0xde,
463  0xa2, 0x53, 0x86, 0x55, 0x5a, 0xb4, 0x2e, 0x75, 0x75, 0xc6, 0xd5, 0x93, 0x9c, 0x57, 0xa9, 0x1f,
464  0xb9, 0x3e, 0xe8, 0x1c, 0xbf, 0xac, 0x1c, 0x54, 0x6f, 0xf5, 0xab, 0x41, 0xee, 0xb3, 0x0e, 0xd0,
465  0x76, 0xc4, 0x1a, 0x45, 0xcd, 0xf1, 0xd6, 0xcc, 0xb0, 0x83, 0x70, 0x73, 0xbc, 0x88, 0x74, 0xa0,
466  0x5b, 0xe7, 0x98, 0x10, 0x36, 0xbf, 0xec, 0x23, 0x1c, 0xc2, 0xb5, 0xba, 0x4b, 0x9d, 0x7f, 0x8c,
467  0x8a, 0xe2, 0xda, 0x18, 0xdd, 0xab, 0x27, 0x8a, 0x15, 0xeb, 0xb0, 0xd4, 0x3a, 0x8b, 0x77, 0x00,
468  0xc7, 0xbb, 0xcc, 0xfa, 0xba, 0xa4, 0x6a, 0x17, 0x5c, 0xf8, 0x51, 0x5d, 0x8d, 0x16, 0xcd, 0xa7,
469  0x0e, 0x71, 0x97, 0x98, 0x78, 0x5a, 0x41, 0xb3, 0xf0, 0x1f, 0x87, 0x2d, 0x65, 0xcd, 0x29, 0x49,
470  0xd2, 0x87, 0x2c, 0x91, 0xa9, 0x5f, 0xcc, 0xa9, 0xd8, 0xbb, 0x53, 0x18, 0xe7, 0xd6, 0xec, 0x65,
471  0xa6, 0x45, 0xf6, 0xce, 0xcf, 0x48, 0xf6, 0x1e, 0x3d, 0xd2, 0xcf, 0xcb, 0x3a, 0xcd, 0xbb, 0x92,
472  0x29, 0x24, 0x16, 0x7f, 0x8a, 0xa8, 0x5c, 0x0c, 0x45, 0x71, 0x33
473  };
474  const unsigned char commit_1[] = {
475  0x08,
476  0xf5, 0x1e, 0x0d, 0xc5, 0x86, 0x78, 0x51, 0xa9, 0x00, 0x00, 0xef, 0x4d, 0xe2, 0x94, 0x60, 0x89,
477  0x83, 0x04, 0xb4, 0x0e, 0x90, 0x10, 0x05, 0x1c, 0x7f, 0xd7, 0x33, 0x92, 0x1f, 0xe7, 0x74, 0x59
478  };
479  size_t min_value_1;
480  size_t max_value_1;
482 
483  CHECK(secp256k1_pedersen_commitment_parse(ctx, &pc, commit_1));
484 
486  ctx,
487  &min_value_1, &max_value_1,
488  &pc,
489  vector_1, sizeof(vector_1),
490  NULL, 0,
492  ));
493 }
494 
496  const unsigned char two_g[33] = {
497  0x09,
498  0xc6, 0x04, 0x7f, 0x94, 0x41, 0xed, 0x7d, 0x6d, 0x30, 0x45, 0x40, 0x6e, 0x95, 0xc0, 0x7c, 0xd8,
499  0x5c, 0x77, 0x8e, 0x4b, 0x8c, 0xef, 0x3c, 0xa7, 0xab, 0xac, 0x09, 0xb9, 0x5c, 0x70, 0x9e, 0xe5
500  };
501  unsigned char result[33];
503 
504  CHECK(secp256k1_pedersen_commitment_parse(ctx, &parse, two_g));
505  CHECK(secp256k1_pedersen_commitment_serialize(ctx, result, &parse));
506  CHECK(memcmp(two_g, result, 33) == 0);
507 
508  result[0] = 0x08;
509  CHECK(secp256k1_pedersen_commitment_parse(ctx, &parse, result));
510  result[0] = 0x0c;
511  CHECK(!secp256k1_pedersen_commitment_parse(ctx, &parse, result));
512 }
513 
515  int i;
516  test_api();
519  for (i = 0; i < 2*count; i++) {
520  test_borromean();
521  }
522  test_rangeproof();
523 }
524 
525 #endif
secp256k1_pedersen_commit
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commit(const secp256k1_context2 *ctx, secp256k1_pedersen_commitment *commit, const unsigned char *blind, uint64_t value, const secp256k1_generator *value_gen, const secp256k1_generator *blind_gen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6)
Generate a Pedersen commitment.
Definition: main_impl.h:93
secp256k1_rangeproof_info
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_info(const secp256k1_context2 *ctx, int *exp, int *mantissa, uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, size_t plen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5)
Extract some basic information from a range-proof.
Definition: main_impl.h:17
SECP256K1_CONTEXT_NONE
#define SECP256K1_CONTEXT_NONE
Definition: secp256k1_2.h:169
secp256k1_rangeproof_rewind
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_rewind(const secp256k1_context2 *ctx, unsigned char *blind_out, uint64_t *value_out, unsigned char *message_out, size_t *outlen, const unsigned char *nonce, uint64_t *min_value, uint64_t *max_value, const secp256k1_pedersen_commitment *commit, const unsigned char *proof, size_t plen, const unsigned char *extra_commit, size_t extra_commit_len, const secp256k1_generator *gen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8) SECP256K1_ARG_NONNULL(9) SECP256K1_ARG_NONNULL(10) SECP256K1_ARG_NONNULL(14)
Verify a range proof proof and rewind the proof to recover information sent by its author.
Definition: main_impl.h:32
secp256k1_pedersen_commitment_parse
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commitment_parse(const secp256k1_context2 *ctx, secp256k1_pedersen_commitment *commit, const unsigned char *input) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a 33-byte commitment into a commitment object.
Definition: main_impl.h:56
random_group_element_jacobian_test
void random_group_element_jacobian_test(secp256k1_gej_t *gej, const secp256k1_ge_t *ge)
Definition: tests.c:54
secp256k1_context_set_error_callback
SECP256K1_API void secp256k1_context_set_error_callback(secp256k1_context2 *ctx, void(*fun)(const char *message, void *data), const void *data) SECP256K1_ARG_NONNULL(1)
Set a callback function to be called when an internal consistency check fails.
Definition: secp256k1_2.c:127
memcpy
void * memcpy(void *a, const void *b, size_t c)
Definition: glibc_compat.cpp:15
secp256k1_context_destroy
SECP256K1_API void secp256k1_context_destroy(secp256k1_context2 *ctx)
Destroy a secp256k1 context object.
Definition: secp256k1_2.c:110
secp256k1_rangeproof_verify
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_verify(const secp256k1_context2 *ctx, uint64_t *min_value, uint64_t *max_value, const secp256k1_pedersen_commitment *commit, const unsigned char *proof, size_t plen, const unsigned char *extra_commit, size_t extra_commit_len, const secp256k1_generator *gen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(9)
Verify a proof that a committed value is within a range.
Definition: main_impl.h:55
secp256k1_scalar
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
secp256k1_pedersen_commitment::data
unsigned char data[64]
Definition: secp256k1_commitment.h:23
random_scalar_order
void random_scalar_order(secp256k1_scalar_t *num)
Definition: tests.c:80
secp256k1_generator_h
const SECP256K1_API secp256k1_generator * secp256k1_generator_h
Static constant generator 'h' maintained for historical reasons.
Definition: main_impl.h:27
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
test_pedersen_commitment_fixed_vector
void test_pedersen_commitment_fixed_vector(void)
Definition: tests_impl.h:495
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_pedersen_commitment_serialize
SECP256K1_API int secp256k1_pedersen_commitment_serialize(const secp256k1_context2 *ctx, unsigned char *output, const secp256k1_pedersen_commitment *commit) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Serialize a commitment object into a serialized byte sequence.
Definition: main_impl.h:77
secp256k1_rangeproof_sign
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_sign(const secp256k1_context2 *ctx, unsigned char *proof, size_t *plen, uint64_t min_value, const secp256k1_pedersen_commitment *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value, const unsigned char *message, size_t msg_len, const unsigned char *extra_commit, size_t extra_commit_len, const secp256k1_generator *gen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(15)
Author a proof that a committed value is within a range.
Definition: main_impl.h:73
secp256k1_rangeproof.h
run_rangeproof_tests
void run_rangeproof_tests(void)
Definition: tests_impl.h:514
secp256k1_context_struct2
Definition: secp256k1_types.h:15
secp256k1_pedersen_commitment
Opaque data structure that stores a Pedersen commitment.
Definition: secp256k1_commitment.h:22
secp256k1_generator_const_g
const SECP256K1_API secp256k1_generator secp256k1_generator_const_g
Standard secp256k1 generator G.
Definition: main_impl.h:18
random_group_element_test
void random_group_element_test(secp256k1_ge_t *ge)
Definition: tests.c:45
secp256k1_generator_const_h
const SECP256K1_API secp256k1_generator secp256k1_generator_const_h
Alternate secp256k1 generator from Elements Alpha.
Definition: main_impl.h:32
secp256k1_context_set_illegal_callback
SECP256K1_API void secp256k1_context_set_illegal_callback(secp256k1_context2 *ctx, void(*fun)(const char *message, void *data), const void *data) SECP256K1_ARG_NONNULL(1)
Set a callback function to be called when an illegal argument is passed to an API call.
Definition: secp256k1_2.c:119
secp256k1_context_create2
SECP256K1_API secp256k1_context2 * secp256k1_context_create2(unsigned int flags) SECP256K1_WARN_UNUSED_RESULT
Create a secp256k1 context object.
Definition: secp256k1_2.c:75
test_rangeproof_fixed_vectors
void test_rangeproof_fixed_vectors(void)
Definition: tests_impl.h:430
SECP256K1_CONTEXT_VERIFY
#define SECP256K1_CONTEXT_VERIFY
Flags to pass to secp256k1_context_create2.
Definition: secp256k1_2.h:167
CHECK
#define CHECK(cond)
Definition: util.h:43
secp256k1_commitment.h
secp256k1_ge
A group element of the secp256k1 curve, in affine coordinates.
Definition: group.h:14
SECP256K1_CONTEXT_SIGN
#define SECP256K1_CONTEXT_SIGN
Definition: secp256k1_2.h:168