PRCYCoin  2.0.0.7rc1
P2P Digital Currency
whitelist_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_WHITELIST_IMPL_H_
8 #define _SECP256K1_WHITELIST_IMPL_H_
9 
10 static int secp256k1_whitelist_hash_pubkey(secp256k1_scalar* output, secp256k1_gej* pubkey) {
11  unsigned char h[32];
12  unsigned char c[33];
13  secp256k1_sha256 sha;
14  int overflow = 0;
15  size_t size = 33;
16  secp256k1_ge ge;
17 
18  secp256k1_ge_set_gej(&ge, pubkey);
19 
20  secp256k1_sha256_initialize(&sha);
21  if (!secp256k1_eckey_pubkey_serialize(&ge, c, &size, SECP256K1_EC_COMPRESSED)) {
22  return 0;
23  }
24  secp256k1_sha256_write(&sha, c, size);
25  secp256k1_sha256_finalize(&sha, h);
26 
27  secp256k1_scalar_set_b32(output, h, &overflow);
28  if (overflow || secp256k1_scalar_is_zero(output)) {
29  /* This return path is mathematically impossible to hit */
30  secp256k1_scalar_clear(output);
31  return 0;
32  }
33  return 1;
34 }
35 
36 static int secp256k1_whitelist_tweak_pubkey(const secp256k1_context2* ctx, secp256k1_gej* pub_tweaked) {
37  secp256k1_scalar tweak;
38  secp256k1_scalar zero;
39  int ret;
40 
41  secp256k1_scalar_set_int(&zero, 0);
42 
43  ret = secp256k1_whitelist_hash_pubkey(&tweak, pub_tweaked);
44  if (ret) {
45  secp256k1_ecmult(&ctx->ecmult_ctx, pub_tweaked, pub_tweaked, &tweak, &zero);
46  }
47  return ret;
48 }
49 
50 static int secp256k1_whitelist_compute_tweaked_privkey(const secp256k1_context2* ctx, secp256k1_scalar* skey, const unsigned char *online_key, const unsigned char *summed_key) {
51  secp256k1_scalar tweak;
52  int ret = 1;
53  int overflow = 0;
54 
55  secp256k1_scalar_set_b32(skey, summed_key, &overflow);
56  if (overflow || secp256k1_scalar_is_zero(skey)) {
57  ret = 0;
58  }
59  if (ret) {
60  secp256k1_gej pkeyj;
61  secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pkeyj, skey);
62  ret = secp256k1_whitelist_hash_pubkey(&tweak, &pkeyj);
63  }
64  if (ret) {
65  secp256k1_scalar sonline;
66  secp256k1_scalar_mul(skey, skey, &tweak);
67 
68  secp256k1_scalar_set_b32(&sonline, online_key, &overflow);
69  if (overflow || secp256k1_scalar_is_zero(&sonline)) {
70  ret = 0;
71  }
72  secp256k1_scalar_add(skey, skey, &sonline);
73  secp256k1_scalar_clear(&sonline);
74  secp256k1_scalar_clear(&tweak);
75  }
76 
77  if (!ret) {
78  secp256k1_scalar_clear(skey);
79  }
80  return ret;
81 }
82 
83 /* Takes a list of pubkeys and combines them to form the public keys needed
84  * for the ring signature; also produce a commitment to every one that will
85  * be our "message". */
86 static int secp256k1_whitelist_compute_keys_and_message(const secp256k1_context2* ctx, unsigned char *msg32, secp256k1_gej *keys, const secp256k1_pubkey2 *online_pubkeys, const secp256k1_pubkey2 *offline_pubkeys, const int n_keys, const secp256k1_pubkey2 *sub_pubkey) {
87  unsigned char c[33];
88  size_t size = 33;
89  secp256k1_sha256 sha;
90  int i;
91  secp256k1_ge subkey_ge;
92 
93  secp256k1_sha256_initialize(&sha);
94  secp256k1_pubkey2_load(ctx, &subkey_ge, sub_pubkey);
95 
96  /* commit to sub-key */
97  if (!secp256k1_eckey_pubkey_serialize(&subkey_ge, c, &size, SECP256K1_EC_COMPRESSED)) {
98  return 0;
99  }
100  secp256k1_sha256_write(&sha, c, size);
101  for (i = 0; i < n_keys; i++) {
102  secp256k1_ge offline_ge;
103  secp256k1_ge online_ge;
104  secp256k1_gej tweaked_gej;
105 
106  /* commit to fixed keys */
107  secp256k1_pubkey2_load(ctx, &offline_ge, &offline_pubkeys[i]);
108  if (!secp256k1_eckey_pubkey_serialize(&offline_ge, c, &size, SECP256K1_EC_COMPRESSED)) {
109  return 0;
110  }
111  secp256k1_sha256_write(&sha, c, size);
112  secp256k1_pubkey2_load(ctx, &online_ge, &online_pubkeys[i]);
113  if (!secp256k1_eckey_pubkey_serialize(&online_ge, c, &size, SECP256K1_EC_COMPRESSED)) {
114  return 0;
115  }
116  secp256k1_sha256_write(&sha, c, size);
117 
118  /* compute tweaked keys */
119  secp256k1_gej_set_ge(&tweaked_gej, &offline_ge);
120  secp256k1_gej_add_ge_var(&tweaked_gej, &tweaked_gej, &subkey_ge, NULL);
121  secp256k1_whitelist_tweak_pubkey(ctx, &tweaked_gej);
122  secp256k1_gej_add_ge_var(&keys[i], &tweaked_gej, &online_ge, NULL);
123  }
124  secp256k1_sha256_finalize(&sha, msg32);
125  return 1;
126 }
127 
128 
129 #endif
SECP256K1_EC_COMPRESSED
#define SECP256K1_EC_COMPRESSED
Flag to pass to secp256k1_ec_pubkey_serialize2 and secp256k1_ec_privkey_export.
Definition: secp256k1_2.h:172
secp256k1_pubkey2
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1_2.h:66
secp256k1_sha256
Definition: hash.h:13
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_gej
A group element of the secp256k1 curve, in jacobian coordinates.
Definition: group.h:24
secp256k1_context_struct2
Definition: secp256k1_types.h:15
secp256k1_ge
A group element of the secp256k1 curve, in affine coordinates.
Definition: group.h:14
secp256k1_context_struct2::ecmult_gen_ctx
secp256k1_ecmult_gen_context ecmult_gen_ctx
Definition: secp256k1_types.h:17