PRCYCoin  2.0.0.7rc1
P2P Digital Currency
main_impl.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (c) 2016 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_WHITELIST_MAIN
8 #define SECP256K1_MODULE_WHITELIST_MAIN
9 
12 
13 #define MAX_KEYS SECP256K1_WHITELIST_MAX_N_KEYS /* shorter alias */
14 
15 int secp256k1_whitelist_sign(const secp256k1_context2* ctx, secp256k1_whitelist_signature *sig, const secp256k1_pubkey2 *online_pubkeys, const secp256k1_pubkey2 *offline_pubkeys, const size_t n_keys, const secp256k1_pubkey2 *sub_pubkey, const unsigned char *online_seckey, const unsigned char *summed_seckey, const size_t index, secp256k1_nonce_function2 noncefp, const void *noncedata) {
16  secp256k1_gej pubs[MAX_KEYS];
18  secp256k1_scalar sec, non;
19  unsigned char msg32[32];
20  int ret;
21 
22  if (noncefp == NULL) {
24  }
25 
26  /* Sanity checks */
27  VERIFY_CHECK(ctx != NULL);
28  ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
29  ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
30  ARG_CHECK(sig != NULL);
31  ARG_CHECK(online_pubkeys != NULL);
32  ARG_CHECK(offline_pubkeys != NULL);
33  ARG_CHECK(n_keys <= MAX_KEYS);
34  ARG_CHECK(sub_pubkey != NULL);
35  ARG_CHECK(online_seckey != NULL);
36  ARG_CHECK(summed_seckey != NULL);
37  ARG_CHECK(index < n_keys);
38 
39  /* Compute pubkeys: online_pubkey + tweaked(offline_pubkey + address), and message */
40  ret = secp256k1_whitelist_compute_keys_and_message(ctx, msg32, pubs, online_pubkeys, offline_pubkeys, n_keys, sub_pubkey);
41 
42  /* Compute signing key: online_seckey + tweaked(summed_seckey) */
43  if (ret) {
44  ret = secp256k1_whitelist_compute_tweaked_privkey(ctx, &sec, online_seckey, summed_seckey);
45  }
46  /* Compute nonce and random s-values */
47  if (ret) {
48  unsigned char seckey32[32];
49  unsigned int count = 0;
50  int overflow = 0;
51 
52  secp256k1_scalar_get_b32(seckey32, &sec);
53  while (1) {
54  size_t i;
55  unsigned char nonce32[32];
56  int done;
57  ret = noncefp(nonce32, msg32, seckey32, NULL, (void*)noncedata, count);
58  if (!ret) {
59  break;
60  }
61  secp256k1_scalar_set_b32(&non, nonce32, &overflow);
62  memset(nonce32, 0, 32);
63  if (overflow || secp256k1_scalar_is_zero(&non)) {
64  count++;
65  continue;
66  }
67  done = 1;
68  for (i = 0; i < n_keys; i++) {
69  msg32[0] ^= i + 1;
70  msg32[1] ^= (i + 1) / 0x100;
71  ret = noncefp(&sig->data[32 * (i + 1)], msg32, seckey32, NULL, (void*)noncedata, count);
72  if (!ret) {
73  break;
74  }
75  secp256k1_scalar_set_b32(&s[i], &sig->data[32 * (i + 1)], &overflow);
76  msg32[0] ^= i + 1;
77  msg32[1] ^= (i + 1) / 0x100;
78  if (overflow || secp256k1_scalar_is_zero(&s[i])) {
79  count++;
80  done = 0;
81  break;
82  }
83  }
84  if (done) {
85  break;
86  }
87  }
88  memset(seckey32, 0, 32);
89  }
90  /* Actually sign */
91  if (ret) {
92  sig->n_keys = n_keys;
93  ret = secp256k1_borromean_sign(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx, &sig->data[0], s, pubs, &non, &sec, &n_keys, &index, 1, msg32, 32);
94  /* Signing will change s[index], so update in the sig structure */
95  secp256k1_scalar_get_b32(&sig->data[32 * (index + 1)], &s[index]);
96  }
97 
98  secp256k1_scalar_clear(&non);
99  secp256k1_scalar_clear(&sec);
100  return ret;
101 }
102 
103 int secp256k1_whitelist_verify(const secp256k1_context2* ctx, const secp256k1_whitelist_signature *sig, const secp256k1_pubkey2 *online_pubkeys, const secp256k1_pubkey2 *offline_pubkeys, const size_t n_keys, const secp256k1_pubkey2 *sub_pubkey) {
105  secp256k1_gej pubs[MAX_KEYS];
106  unsigned char msg32[32];
107  size_t i;
108 
109  VERIFY_CHECK(ctx != NULL);
110  ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
111  ARG_CHECK(sig != NULL);
112  ARG_CHECK(online_pubkeys != NULL);
113  ARG_CHECK(offline_pubkeys != NULL);
114  ARG_CHECK(sub_pubkey != NULL);
115 
116  if (sig->n_keys > MAX_KEYS || sig->n_keys != n_keys) {
117  return 0;
118  }
119  for (i = 0; i < sig->n_keys; i++) {
120  int overflow = 0;
121  secp256k1_scalar_set_b32(&s[i], &sig->data[32 * (i + 1)], &overflow);
122  if (overflow || secp256k1_scalar_is_zero(&s[i])) {
123  return 0;
124  }
125  }
126 
127  /* Compute pubkeys: online_pubkey + tweaked(offline_pubkey + address), and message */
128  if (!secp256k1_whitelist_compute_keys_and_message(ctx, msg32, pubs, online_pubkeys, offline_pubkeys, sig->n_keys, sub_pubkey)) {
129  return 0;
130  }
131  /* Do verification */
132  return secp256k1_borromean_verify(&ctx->ecmult_ctx, NULL, &sig->data[0], s, pubs, &sig->n_keys, 1, msg32, 32);
133 }
134 
136  return sig->n_keys;
137 }
138 
139 int secp256k1_whitelist_signature_parse(const secp256k1_context2* ctx, secp256k1_whitelist_signature *sig, const unsigned char *input, size_t input_len) {
140  VERIFY_CHECK(ctx != NULL);
141  ARG_CHECK(sig != NULL);
142  ARG_CHECK(input != NULL);
143 
144  if (input_len == 0) {
145  return 0;
146  }
147 
148  sig->n_keys = input[0];
149  if (sig->n_keys >= MAX_KEYS || input_len != 1 + 32 * (sig->n_keys + 1)) {
150  return 0;
151  }
152  memcpy(&sig->data[0], &input[1], 32 * (sig->n_keys + 1));
153 
154  return 1;
155 }
156 
157 int secp256k1_whitelist_signature_serialize(const secp256k1_context2* ctx, unsigned char *output, size_t *output_len, const secp256k1_whitelist_signature *sig) {
158  VERIFY_CHECK(ctx != NULL);
159  ARG_CHECK(output != NULL);
160  ARG_CHECK(output_len != NULL);
161  ARG_CHECK(sig != NULL);
162 
163  if (*output_len < 1 + 32 * (sig->n_keys + 1)) {
164  return 0;
165  }
166 
167  output[0] = sig->n_keys;
168  memcpy(&output[1], &sig->data[0], 32 * (sig->n_keys + 1));
169  *output_len = 1 + 32 * (sig->n_keys + 1);
170 
171  return 1;
172 }
173 
174 #endif
VERIFY_CHECK
#define VERIFY_CHECK(cond)
Definition: util.h:61
whitelist_impl.h
secp256k1_whitelist_signature::n_keys
size_t n_keys
Definition: secp256k1_whitelist.h:35
secp256k1_whitelist_signature_n_keys
size_t secp256k1_whitelist_signature_n_keys(const secp256k1_whitelist_signature *sig)
Returns the number of keys a signature expects to have.
Definition: main_impl.h:135
memcpy
void * memcpy(void *a, const void *b, size_t c)
Definition: glibc_compat.cpp:15
secp256k1_pubkey2
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1_2.h:66
secp256k1_context_struct2::ecmult_ctx
secp256k1_ecmult_context ecmult_ctx
Definition: secp256k1_types.h:16
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
MAX_KEYS
#define MAX_KEYS
Definition: main_impl.h:13
secp256k1_nonce_function2
int(* secp256k1_nonce_function2)(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int attempt)
A pointer to a function to deterministically generate a nonce.
Definition: secp256k1_2.h:99
secp256k1_whitelist_signature
Opaque data structure that holds a parsed whitelist proof.
Definition: secp256k1_whitelist.h:34
secp256k1_whitelist.h
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_nonce_function_default
const SECP256K1_API secp256k1_nonce_function2 secp256k1_nonce_function_default
A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979).
Definition: secp256k1_2.c:373
secp256k1_whitelist_signature_serialize
int secp256k1_whitelist_signature_serialize(const secp256k1_context2 *ctx, unsigned char *output, size_t *output_len, const secp256k1_whitelist_signature *sig)
Serialize a whitelist signature.
Definition: main_impl.h:157
secp256k1_whitelist_signature::data
unsigned char data[32 *(1+SECP256K1_WHITELIST_MAX_N_KEYS)]
Definition: secp256k1_whitelist.h:37
secp256k1_whitelist_verify
int secp256k1_whitelist_verify(const secp256k1_context2 *ctx, const secp256k1_whitelist_signature *sig, const secp256k1_pubkey2 *online_pubkeys, const secp256k1_pubkey2 *offline_pubkeys, const size_t n_keys, const secp256k1_pubkey2 *sub_pubkey)
Verify a whitelist signature Returns 1: signature is valid 0: signature is not valid In: ctx: pointer...
Definition: main_impl.h:103
secp256k1_context_struct2
Definition: secp256k1_types.h:15
secp256k1_whitelist_signature_parse
int secp256k1_whitelist_signature_parse(const secp256k1_context2 *ctx, secp256k1_whitelist_signature *sig, const unsigned char *input, size_t input_len)
Parse a whitelist signature.
Definition: main_impl.h:139
secp256k1_whitelist_sign
int secp256k1_whitelist_sign(const secp256k1_context2 *ctx, secp256k1_whitelist_signature *sig, const secp256k1_pubkey2 *online_pubkeys, const secp256k1_pubkey2 *offline_pubkeys, const size_t n_keys, const secp256k1_pubkey2 *sub_pubkey, const unsigned char *online_seckey, const unsigned char *summed_seckey, const size_t index, secp256k1_nonce_function2 noncefp, const void *noncedata)
Compute a whitelist signature Returns 1: signature was successfully created 0: signature was not succ...
Definition: main_impl.h:15
secp256k1_context_struct2::ecmult_gen_ctx
secp256k1_ecmult_gen_context ecmult_gen_ctx
Definition: secp256k1_types.h:17
ARG_CHECK
#define ARG_CHECK(cond)
Definition: secp256k1_2.c:38