PRCYCoin  2.0.0.7rc1
P2P Digital Currency
main_impl.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (c) 2014-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_MAIN
8 #define SECP256K1_MODULE_COMMITMENT_MAIN
9 
10 #include "group.h"
11 
13 
20 static const secp256k1_generator secp256k1_generator_h_internal = {{
21  0x50, 0x92, 0x9b, 0x74, 0xc1, 0xa0, 0x49, 0x54, 0xb7, 0x8b, 0x4b, 0x60, 0x35, 0xe9, 0x7a, 0x5e,
22  0x07, 0x8a, 0x5a, 0x0f, 0x28, 0xec, 0x96, 0xd5, 0x47, 0xbf, 0xee, 0x9a, 0xce, 0x80, 0x3a, 0xc0,
23  0x31, 0xd3, 0xc6, 0x86, 0x39, 0x73, 0x92, 0x6e, 0x04, 0x9e, 0x63, 0x7c, 0xb1, 0xb5, 0xf4, 0x0a,
24  0x36, 0xda, 0xc2, 0x8a, 0xf1, 0x76, 0x69, 0x68, 0xc3, 0x0c, 0x23, 0x13, 0xf3, 0xa3, 0x89, 0x04
25 }};
26 
27 const secp256k1_generator *secp256k1_generator_h = &secp256k1_generator_h_internal;
28 
29 static void secp256k1_pedersen_commitment_load(secp256k1_ge* ge, const secp256k1_pedersen_commitment* commit) {
30  secp256k1_fe fe;
31  secp256k1_fe_set_b32(&fe, &commit->data[1]);
32  secp256k1_ge_set_xquad(ge, &fe);
33  if (commit->data[0] & 1) {
34  secp256k1_ge_neg(ge, ge);
35  }
36 }
37 
38 static void secp256k1_pedersen_commitment_save(secp256k1_pedersen_commitment* commit, secp256k1_ge* ge) {
39  secp256k1_fe_normalize(&ge->x);
40  secp256k1_fe_get_b32(&commit->data[1], &ge->x);
41  commit->data[0] = 9 ^ secp256k1_fe_is_quad_var(&ge->y);
42 }
43 
44 int secp256k1_pedersen_commitment_to_serialized_pubkey(secp256k1_pedersen_commitment* commit, unsigned char* pubkey, size_t* length) {
45  secp256k1_ge ge;
46  secp256k1_pedersen_commitment_load(&ge, commit);
47  return secp256k1_eckey_pubkey_serialize(&ge, pubkey, length, 1);
48 }
49 
50 void secp256k1_pedersen_serialized_pubkey_to_commitment(const unsigned char* pubkey, size_t length, secp256k1_pedersen_commitment* commit) {
51  secp256k1_ge ge;
52  secp256k1_eckey_pubkey_parse(&ge, pubkey, length);
53  secp256k1_pedersen_commitment_save(commit, &ge);
54 }
55 
56 int secp256k1_pedersen_commitment_parse(const secp256k1_context2* ctx, secp256k1_pedersen_commitment* commit, const unsigned char *input) {
57  secp256k1_fe x;
58  secp256k1_ge ge;
59 
60  VERIFY_CHECK(ctx != NULL);
61  ARG_CHECK(commit != NULL);
62  ARG_CHECK(input != NULL);
63  (void) ctx;
64 
65  if ((input[0] & 0xFE) != 8 ||
66  !secp256k1_fe_set_b32(&x, &input[1]) ||
67  !secp256k1_ge_set_xquad(&ge, &x)) {
68  return 0;
69  }
70  if (input[0] & 1) {
71  secp256k1_ge_neg(&ge, &ge);
72  }
73  secp256k1_pedersen_commitment_save(commit, &ge);
74  return 1;
75 }
76 
77 int secp256k1_pedersen_commitment_serialize(const secp256k1_context2* ctx, unsigned char *output, const secp256k1_pedersen_commitment* commit) {
78  secp256k1_ge ge;
79 
80  VERIFY_CHECK(ctx != NULL);
81  ARG_CHECK(output != NULL);
82  ARG_CHECK(commit != NULL);
83 
84  secp256k1_pedersen_commitment_load(&ge, commit);
85 
86  output[0] = 9 ^ secp256k1_fe_is_quad_var(&ge.y);
87  secp256k1_fe_normalize_var(&ge.x);
88  secp256k1_fe_get_b32(&output[1], &ge.x);
89  return 1;
90 }
91 
92 /* Generates a pedersen commitment: *commit = blind * G + value * G2. The blinding factor is 32 bytes.*/
93 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) {
94  secp256k1_ge value_genp;
95  secp256k1_ge blind_genp;
96  secp256k1_gej rj;
98  secp256k1_scalar sec;
99  int overflow;
100  int ret = 0;
101  VERIFY_CHECK(ctx != NULL);
102  ARG_CHECK(commit != NULL);
103  ARG_CHECK(blind != NULL);
104  ARG_CHECK(value_gen != NULL);
105  ARG_CHECK(blind_gen != NULL);
106  secp256k1_generator_load(&value_genp, value_gen);
107  secp256k1_generator_load(&blind_genp, blind_gen);
108  secp256k1_scalar_set_b32(&sec, blind, &overflow);
109  if (!overflow) {
110  secp256k1_pedersen_ecmult(&rj, &sec, value, &value_genp, &blind_genp);
111  if (!secp256k1_gej_is_infinity(&rj)) {
112  secp256k1_ge_set_gej(&r, &rj);
113  secp256k1_pedersen_commitment_save(commit, &r);
114  ret = 1;
115  }
116  secp256k1_gej_clear(&rj);
117  secp256k1_ge_clear(&r);
118  }
119  secp256k1_scalar_clear(&sec);
120  return ret;
121 }
122 
126 int secp256k1_pedersen_blind_sum(const secp256k1_context2* ctx, unsigned char *blind_out, const unsigned char * const *blinds, size_t n, size_t npositive) {
127  secp256k1_scalar acc;
129  size_t i;
130  int overflow;
131  VERIFY_CHECK(ctx != NULL);
132  ARG_CHECK(blind_out != NULL);
133  ARG_CHECK(blinds != NULL);
134  ARG_CHECK(npositive <= n);
135  (void) ctx;
136  secp256k1_scalar_set_int(&acc, 0);
137  for (i = 0; i < n; i++) {
138  secp256k1_scalar_set_b32(&x, blinds[i], &overflow);
139  if (overflow) {
140  return 0;
141  }
142  if (i >= npositive) {
143  secp256k1_scalar_negate(&x, &x);
144  }
145  secp256k1_scalar_add(&acc, &acc, &x);
146  }
147  secp256k1_scalar_get_b32(blind_out, &acc);
148  secp256k1_scalar_clear(&acc);
149  secp256k1_scalar_clear(&x);
150  return 1;
151 }
152 
153 /* Takes two lists of commitments and sums the first set and subtracts the second and verifies that they sum to excess. */
154 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) {
155  secp256k1_gej accj;
156  secp256k1_ge add;
157  size_t i;
158  VERIFY_CHECK(ctx != NULL);
159  ARG_CHECK(!n_pos || (pos != NULL));
160  ARG_CHECK(!n_neg || (neg != NULL));
161  (void) ctx;
162  secp256k1_gej_set_infinity(&accj);
163  for (i = 0; i < n_neg; i++) {
164  secp256k1_pedersen_commitment_load(&add, neg[i]);
165  secp256k1_gej_add_ge_var(&accj, &accj, &add, NULL);
166  }
167  secp256k1_gej_neg(&accj, &accj);
168  for (i = 0; i < n_pos; i++) {
169  secp256k1_pedersen_commitment_load(&add, pos[i]);
170  secp256k1_gej_add_ge_var(&accj, &accj, &add, NULL);
171  }
172  return secp256k1_gej_is_infinity(&accj);
173 }
174 
176  const secp256k1_context2* ctx,
177  const secp256k1_pedersen_commitment * const* pos,
178  size_t n_pos,
179  const secp256k1_pedersen_commitment * const* neg,
180  size_t n_neg,
182  secp256k1_gej accj;
183  secp256k1_ge add;
184  secp256k1_ge outGe;
185  size_t i;
186  VERIFY_CHECK(ctx != NULL);
187  ARG_CHECK(!n_pos || (pos != NULL));
188  ARG_CHECK(!n_neg || (neg != NULL));
189  (void) ctx;
190  secp256k1_gej_set_infinity(&accj);
191  for (i = 0; i < n_neg; i++) {
192  secp256k1_pedersen_commitment_load(&add, neg[i]);
193  secp256k1_gej_add_ge_var(&accj, &accj, &add, NULL);
194  }
195  secp256k1_gej_neg(&accj, &accj);
196  for (i = 0; i < n_pos; i++) {
197  secp256k1_pedersen_commitment_load(&add, pos[i]);
198  secp256k1_gej_add_ge_var(&accj, &accj, &add, NULL);
199  }
200  secp256k1_ge_set_gej(&outGe, &accj);
201  secp256k1_pedersen_commitment_save(out, &outGe);
202  return 1;
203 }
204 
206  const secp256k1_context2* ctx,
207  const secp256k1_pedersen_commitment * const* pos,
208  size_t n_pos,
210  secp256k1_gej accj;
211  secp256k1_ge add;
212  secp256k1_ge outGe;
213  size_t i;
214  VERIFY_CHECK(ctx != NULL);
215  ARG_CHECK(!n_pos || (pos != NULL));
216  (void) ctx;
217  secp256k1_gej_set_infinity(&accj);
218  for (i = 0; i < n_pos; i++) {
219  secp256k1_pedersen_commitment_load(&add, pos[i]);
220  secp256k1_gej_add_ge_var(&accj, &accj, &add, NULL);
221  }
222  secp256k1_ge_set_gej(&outGe, &accj);
223  secp256k1_pedersen_commitment_save(out, &outGe);
224  return 1;
225 }
226 
227 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) {
228  secp256k1_scalar sum;
229  secp256k1_scalar tmp;
230  size_t i;
231 
232  VERIFY_CHECK(ctx != NULL);
233  ARG_CHECK(n_total == 0 || value != NULL);
234  ARG_CHECK(n_total == 0 || generator_blind != NULL);
235  ARG_CHECK(n_total == 0 || blinding_factor != NULL);
236  ARG_CHECK(n_total > n_inputs);
237  (void) ctx;
238 
239  if (n_total == 0) {
240  return 1;
241  }
242 
243  secp256k1_scalar_set_int(&sum, 0);
244  for (i = 0; i < n_total; i++) {
245  int overflow = 0;
246  secp256k1_scalar addend;
247  secp256k1_scalar_set_u64(&addend, value[i]); /* s = v */
248 
249  secp256k1_scalar_set_b32(&tmp, generator_blind[i], &overflow);
250  if (overflow == 1) {
251  secp256k1_scalar_clear(&tmp);
252  secp256k1_scalar_clear(&addend);
253  secp256k1_scalar_clear(&sum);
254  return 0;
255  }
256  secp256k1_scalar_mul(&addend, &addend, &tmp); /* s = vr */
257 
258  secp256k1_scalar_set_b32(&tmp, blinding_factor[i], &overflow);
259  if (overflow == 1) {
260  secp256k1_scalar_clear(&tmp);
261  secp256k1_scalar_clear(&addend);
262  secp256k1_scalar_clear(&sum);
263  return 0;
264  }
265  secp256k1_scalar_add(&addend, &addend, &tmp); /* s = vr + r' */
266  secp256k1_scalar_cond_negate(&addend, i < n_inputs); /* s is negated if it's an input */
267  secp256k1_scalar_add(&sum, &sum, &addend); /* sum += s */
268  secp256k1_scalar_clear(&addend);
269  }
270 
271  /* Right now tmp has the last pedersen blinding factor. Subtract the sum from it. */
272  secp256k1_scalar_negate(&sum, &sum);
273  secp256k1_scalar_add(&tmp, &tmp, &sum);
274  secp256k1_scalar_get_b32(blinding_factor[n_total - 1], &tmp);
275 
276  secp256k1_scalar_clear(&tmp);
277  secp256k1_scalar_clear(&sum);
278  return 1;
279 }
280 
281 #endif
secp256k1_pedersen_commitment_to_serialized_pubkey
int secp256k1_pedersen_commitment_to_serialized_pubkey(secp256k1_pedersen_commitment *commit, unsigned char *pubkey, size_t *length)
Definition: main_impl.h:44
VERIFY_CHECK
#define VERIFY_CHECK(cond)
Definition: util.h:61
secp256k1_pedersen_commitment_parse
int secp256k1_pedersen_commitment_parse(const secp256k1_context2 *ctx, secp256k1_pedersen_commitment *commit, const unsigned char *input)
Parse a 33-byte commitment into a commitment object.
Definition: main_impl.h:56
secp256k1_ge::y
secp256k1_fe y
Definition: group.h:20
secp256k1_pedersen_verify_tally
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)
Verify a tally of Pedersen commitments Returns 1: commitments successfully sum to zero.
Definition: main_impl.h:154
secp256k1_pedersen_commitment_sum_pos
int secp256k1_pedersen_commitment_sum_pos(const secp256k1_context2 *ctx, const secp256k1_pedersen_commitment *const *pos, size_t n_pos, secp256k1_pedersen_commitment *out)
Definition: main_impl.h:205
secp256k1_generator_h
const secp256k1_generator * secp256k1_generator_h
Static constant generator 'h' maintained for historical reasons.
Definition: main_impl.h:27
r
void const uint64_t uint64_t * r
Definition: field_5x52_asm_impl.h:10
secp256k1_generator
Opaque data structure that stores a base point.
Definition: secp256k1_generator.h:20
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
secp256k1_gej
A group element of the secp256k1 curve, in jacobian coordinates.
Definition: group.h:24
secp256k1_fe
Definition: field_10x26.h:12
secp256k1_pedersen_commit
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)
Generate a Pedersen commitment.
Definition: main_impl.h:93
pedersen_impl.h
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_pedersen_commitment_serialize
int secp256k1_pedersen_commitment_serialize(const secp256k1_context2 *ctx, unsigned char *output, const secp256k1_pedersen_commitment *commit)
Serialize a commitment object into a serialized byte sequence.
Definition: main_impl.h:77
secp256k1_ge::x
secp256k1_fe x
Definition: group.h:19
secp256k1_pedersen_blind_generator_blind_sum
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_commitment_sum
int secp256k1_pedersen_commitment_sum(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_pedersen_commitment *out)
Definition: main_impl.h:175
secp256k1_ge
A group element of the secp256k1 curve, in affine coordinates.
Definition: group.h:14
secp256k1_pedersen_serialized_pubkey_to_commitment
void secp256k1_pedersen_serialized_pubkey_to_commitment(const unsigned char *pubkey, size_t length, secp256k1_pedersen_commitment *commit)
Definition: main_impl.h:50
ARG_CHECK
#define ARG_CHECK(cond)
Definition: secp256k1_2.c:38
secp256k1_pedersen_blind_sum
int secp256k1_pedersen_blind_sum(const secp256k1_context2 *ctx, unsigned char *blind_out, const unsigned char *const *blinds, size_t n, size_t npositive)
Takes a list of n pointers to 32 byte blinding values, the first negs of which are treated with posit...
Definition: main_impl.h:126