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_COMMITMENT_TESTS
8 #define SECP256K1_MODULE_COMMITMENT_TESTS
9 
10 #include <string.h>
11 
12 #include "group.h"
13 #include "scalar.h"
14 #include "testrand.h"
15 #include "util.h"
16 
18 
19 static void test_commitment_api(void) {
21  const secp256k1_pedersen_commitment *commit_ptr = &commit;
22  unsigned char blind[32];
23  unsigned char blind_out[32];
24  const unsigned char *blind_ptr = blind;
25  unsigned char *blind_out_ptr = blind_out;
26  uint64_t val = secp256k1_rand32();
27 
32  int32_t ecount;
33 
34  secp256k1_context_set_error_callback(none, counting_illegal_callback_fn, &ecount);
35  secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount);
36  secp256k1_context_set_error_callback(vrfy, counting_illegal_callback_fn, &ecount);
37  secp256k1_context_set_error_callback(both, counting_illegal_callback_fn, &ecount);
38  secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount);
39  secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount);
40  secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount);
41  secp256k1_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount);
42 
43  secp256k1_rand256(blind);
45  CHECK(ecount == 1);
47  CHECK(ecount == 2);
49  CHECK(ecount == 2);
50 
52  CHECK(ecount == 3);
54  CHECK(ecount == 4);
55  CHECK(secp256k1_pedersen_commit(sign, &commit, blind, val, NULL, &secp256k1_generator_const_g) == 0);
56  CHECK(ecount == 5);
57  CHECK(secp256k1_pedersen_commit(sign, &commit, blind, val, &secp256k1_generator_const_h, NULL) == 0);
58  CHECK(ecount == 6);
59 
60  CHECK(secp256k1_pedersen_blind_sum(none, blind_out, &blind_ptr, 1, 1) != 0);
61  CHECK(ecount == 6);
62  CHECK(secp256k1_pedersen_blind_sum(none, NULL, &blind_ptr, 1, 1) == 0);
63  CHECK(ecount == 7);
64  CHECK(secp256k1_pedersen_blind_sum(none, blind_out, NULL, 1, 1) == 0);
65  CHECK(ecount == 8);
66  CHECK(secp256k1_pedersen_blind_sum(none, blind_out, &blind_ptr, 0, 1) == 0);
67  CHECK(ecount == 9);
68  CHECK(secp256k1_pedersen_blind_sum(none, blind_out, &blind_ptr, 0, 0) != 0);
69  CHECK(ecount == 9);
70 
72  CHECK(secp256k1_pedersen_verify_tally(none, &commit_ptr, 1, &commit_ptr, 1) != 0);
73  CHECK(secp256k1_pedersen_verify_tally(none, NULL, 0, &commit_ptr, 1) == 0);
74  CHECK(secp256k1_pedersen_verify_tally(none, &commit_ptr, 1, NULL, 0) == 0);
75  CHECK(secp256k1_pedersen_verify_tally(none, NULL, 0, NULL, 0) != 0);
76  CHECK(ecount == 9);
77  CHECK(secp256k1_pedersen_verify_tally(none, NULL, 1, &commit_ptr, 1) == 0);
78  CHECK(ecount == 10);
79  CHECK(secp256k1_pedersen_verify_tally(none, &commit_ptr, 1, NULL, 1) == 0);
80  CHECK(ecount == 11);
81 
82  CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, &blind_ptr, &blind_out_ptr, 1, 0) != 0);
83  CHECK(ecount == 11);
84  CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, &blind_ptr, &blind_out_ptr, 1, 1) == 0);
85  CHECK(ecount == 12);
86  CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, &blind_ptr, &blind_out_ptr, 0, 0) == 0);
87  CHECK(ecount == 13);
88  CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, NULL, &blind_ptr, &blind_out_ptr, 1, 0) == 0);
89  CHECK(ecount == 14);
90  CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, NULL, &blind_out_ptr, 1, 0) == 0);
91  CHECK(ecount == 15);
92  CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, &blind_ptr, NULL, 1, 0) == 0);
93  CHECK(ecount == 16);
94 
99 }
100 
101 static void test_pedersen(void) {
102  secp256k1_pedersen_commitment commits[19];
103  const secp256k1_pedersen_commitment *cptr[19];
104  unsigned char blinds[32*19];
105  const unsigned char *bptr[19];
107  uint64_t values[19];
108  int64_t totalv;
109  int i;
110  int inputs;
111  int outputs;
112  int total;
113  inputs = (secp256k1_rand32() & 7) + 1;
114  outputs = (secp256k1_rand32() & 7) + 2;
115  total = inputs + outputs;
116  for (i = 0; i < 19; i++) {
117  cptr[i] = &commits[i];
118  bptr[i] = &blinds[i * 32];
119  }
120  totalv = 0;
121  for (i = 0; i < inputs; i++) {
122  values[i] = secp256k1_rands64(0, INT64_MAX - totalv);
123  totalv += values[i];
124  }
125  for (i = 0; i < outputs - 1; i++) {
126  values[i + inputs] = secp256k1_rands64(0, totalv);
127  totalv -= values[i + inputs];
128  }
129  values[total - 1] = totalv;
130 
131  for (i = 0; i < total - 1; i++) {
133  secp256k1_scalar_get_b32(&blinds[i * 32], &s);
134  }
135  CHECK(secp256k1_pedersen_blind_sum(ctx, &blinds[(total - 1) * 32], bptr, total - 1, inputs));
136  for (i = 0; i < total; i++) {
137  CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i], &secp256k1_generator_const_h, &secp256k1_generator_const_g));
138  }
139  CHECK(secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs));
140  CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[inputs], outputs, cptr, inputs));
141  if (inputs > 0 && values[0] > 0) {
142  CHECK(!secp256k1_pedersen_verify_tally(ctx, cptr, inputs - 1, &cptr[inputs], outputs));
143  }
145  for (i = 0; i < 4; i++) {
146  secp256k1_scalar_get_b32(&blinds[i * 32], &s);
147  }
148  values[0] = INT64_MAX;
149  values[1] = 0;
150  values[2] = 1;
151  for (i = 0; i < 3; i++) {
152  CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i], &secp256k1_generator_const_h, &secp256k1_generator_const_g));
153  }
154  CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[0], 1, &cptr[0], 1));
155  CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[1], 1));
156 }
157 
158 #define MAX_N_GENS 30
160  const size_t n_inputs = (secp256k1_rand32() % (MAX_N_GENS / 2)) + 1;
161  const size_t n_outputs = (secp256k1_rand32() % (MAX_N_GENS / 2)) + 1;
162  const size_t n_generators = n_inputs + n_outputs;
163  unsigned char *generator_blind[MAX_N_GENS];
164  unsigned char *pedersen_blind[MAX_N_GENS];
165  secp256k1_generator generator[MAX_N_GENS];
167  const secp256k1_pedersen_commitment *commit_ptr[MAX_N_GENS];
168  size_t i;
169  int64_t total_value;
170  uint64_t value[MAX_N_GENS];
171 
173 
174  unsigned char generator_seed[32];
176  secp256k1_scalar_get_b32(generator_seed, &s);
177  /* Create all the needed generators */
178  for (i = 0; i < n_generators; i++) {
179  generator_blind[i] = (unsigned char*) malloc(32);
180  pedersen_blind[i] = (unsigned char*) malloc(32);
181 
183  secp256k1_scalar_get_b32(generator_blind[i], &s);
185  secp256k1_scalar_get_b32(pedersen_blind[i], &s);
186 
187  CHECK(secp256k1_generator_generate_blinded(ctx, &generator[i], generator_seed, generator_blind[i]));
188 
189  commit_ptr[i] = &commit[i];
190  }
191 
192  /* Compute all the values -- can be positive or negative */
193  total_value = 0;
194  for (i = 0; i < n_outputs; i++) {
195  value[n_inputs + i] = secp256k1_rands64(0, INT64_MAX - total_value);
196  total_value += value[n_inputs + i];
197  }
198  for (i = 0; i < n_inputs - 1; i++) {
199  value[i] = secp256k1_rands64(0, total_value);
200  total_value -= value[i];
201  }
202  value[i] = total_value;
203 
204  /* Correct for blinding factors and do the commitments */
205  CHECK(secp256k1_pedersen_blind_generator_blind_sum(ctx, value, (const unsigned char * const *) generator_blind, pedersen_blind, n_generators, n_inputs));
206  for (i = 0; i < n_generators; i++) {
207  CHECK(secp256k1_pedersen_commit(ctx, &commit[i], pedersen_blind[i], value[i], &generator[i], &secp256k1_generator_const_h));
208  }
209 
210  /* Verify */
211  CHECK(secp256k1_pedersen_verify_tally(ctx, &commit_ptr[0], n_inputs, &commit_ptr[n_inputs], n_outputs));
212 
213  /* Cleanup */
214  for (i = 0; i < n_generators; i++) {
215  free(generator_blind[i]);
216  free(pedersen_blind[i]);
217  }
218 }
219 #undef MAX_N_GENS
220 
222  int i;
223  test_commitment_api();
224  for (i = 0; i < 10*count; i++) {
225  test_pedersen();
226  }
228 }
229 
230 #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_CONTEXT_NONE
#define SECP256K1_CONTEXT_NONE
Definition: secp256k1_2.h:169
secp256k1_generator_generate_blinded
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_generator_generate_blinded(const secp256k1_context2 *ctx, secp256k1_generator *gen, const unsigned char *key32, const unsigned char *blind32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Generate a blinded generator for the curve.
Definition: main_impl.h:238
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
test_multiple_generators
void test_multiple_generators(void)
Definition: tests_impl.h:159
secp256k1_context_destroy
SECP256K1_API void secp256k1_context_destroy(secp256k1_context2 *ctx)
Destroy a secp256k1 context object.
Definition: secp256k1_2.c:110
secp256k1_generator
Opaque data structure that stores a base point.
Definition: secp256k1_generator.h:20
MAX_N_GENS
#define MAX_N_GENS
Definition: tests_impl.h:158
secp256k1_scalar
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
random_scalar_order
void random_scalar_order(secp256k1_scalar_t *num)
Definition: tests.c:80
secp256k1_pedersen_blind_generator_blind_sum
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_generator_blind_sum(const secp256k1_context2 *ctx, const uint64_t *value, const unsigned char *const *generator_blind, unsigned char *const *blinding_factor, size_t n_total, size_t n_inputs)
Sets the final Pedersen blinding factor correctly when the generators themselves have blinding factor...
Definition: main_impl.h:227
secp256k1_pedersen_verify_tally
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_verify_tally(const secp256k1_context2 *ctx, const secp256k1_pedersen_commitment *const *pos, size_t n_pos, const secp256k1_pedersen_commitment *const *neg, size_t n_neg) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4)
Verify a tally of Pedersen commitments Returns 1: commitments successfully sum to zero.
Definition: main_impl.h:154
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
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
run_commitment_tests
void run_commitment_tests(void)
Definition: tests_impl.h:221
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
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_pedersen_blind_sum
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_sum(const secp256k1_context2 *ctx, unsigned char *blind_out, const unsigned char *const *blinds, size_t n, size_t npositive) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Computes the sum of multiple positive and negative blinding factors.
Definition: main_impl.h:126
secp256k1_commitment.h
SECP256K1_CONTEXT_SIGN
#define SECP256K1_CONTEXT_SIGN
Definition: secp256k1_2.h:168