/root/bitcoin/src/secp256k1/src/modules/extrakeys/main_impl.h
Line | Count | Source |
1 | | /*********************************************************************** |
2 | | * Copyright (c) 2020 Jonas Nick * |
3 | | * Distributed under the MIT software license, see the accompanying * |
4 | | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* |
5 | | ***********************************************************************/ |
6 | | |
7 | | #ifndef SECP256K1_MODULE_EXTRAKEYS_MAIN_H |
8 | | #define SECP256K1_MODULE_EXTRAKEYS_MAIN_H |
9 | | |
10 | | #include "../../../include/secp256k1.h" |
11 | | #include "../../../include/secp256k1_extrakeys.h" |
12 | | #include "../../util.h" |
13 | | |
14 | 0 | static SECP256K1_INLINE int secp256k1_xonly_pubkey_load(const secp256k1_context* ctx, secp256k1_ge *ge, const secp256k1_xonly_pubkey *pubkey) { |
15 | 0 | return secp256k1_pubkey_load(ctx, ge, (const secp256k1_pubkey *) pubkey); |
16 | 0 | } |
17 | | |
18 | 0 | static SECP256K1_INLINE void secp256k1_xonly_pubkey_save(secp256k1_xonly_pubkey *pubkey, secp256k1_ge *ge) { |
19 | | #ifdef VERIFY |
20 | | /* ensure that the group element's Y coordinate is even, as per definition of x-only public keys */ |
21 | | secp256k1_fe y = ge->y; |
22 | | secp256k1_fe_normalize_var(&y); |
23 | | VERIFY_CHECK(!secp256k1_fe_is_odd(&y)); |
24 | | #endif |
25 | |
|
26 | 0 | secp256k1_pubkey_save((secp256k1_pubkey *) pubkey, ge); |
27 | 0 | } |
28 | | |
29 | 0 | int secp256k1_xonly_pubkey_parse(const secp256k1_context* ctx, secp256k1_xonly_pubkey *pubkey, const unsigned char *input32) { |
30 | 0 | secp256k1_ge pk; |
31 | 0 | secp256k1_fe x; |
32 | |
|
33 | 0 | VERIFY_CHECK(ctx != NULL); |
34 | 0 | ARG_CHECK(pubkey != NULL); |
35 | 0 | memset(pubkey, 0, sizeof(*pubkey)); |
36 | 0 | ARG_CHECK(input32 != NULL); |
37 | | |
38 | 0 | if (!secp256k1_fe_set_b32_limit(&x, input32)) { Branch (38:9): [True: 0, False: 0]
|
39 | 0 | return 0; |
40 | 0 | } |
41 | 0 | if (!secp256k1_ge_set_xo_var(&pk, &x, 0)) { Branch (41:9): [True: 0, False: 0]
|
42 | 0 | return 0; |
43 | 0 | } |
44 | 0 | if (!secp256k1_ge_is_in_correct_subgroup(&pk)) { Branch (44:9): [True: 0, False: 0]
|
45 | 0 | return 0; |
46 | 0 | } |
47 | 0 | secp256k1_xonly_pubkey_save(pubkey, &pk); |
48 | 0 | return 1; |
49 | 0 | } |
50 | | |
51 | 0 | int secp256k1_xonly_pubkey_serialize(const secp256k1_context* ctx, unsigned char *output32, const secp256k1_xonly_pubkey *pubkey) { |
52 | 0 | secp256k1_ge pk; |
53 | |
|
54 | 0 | VERIFY_CHECK(ctx != NULL); |
55 | 0 | ARG_CHECK(output32 != NULL); |
56 | 0 | memset(output32, 0, 32); |
57 | 0 | ARG_CHECK(pubkey != NULL); |
58 | | |
59 | 0 | if (!secp256k1_xonly_pubkey_load(ctx, &pk, pubkey)) { Branch (59:9): [True: 0, False: 0]
|
60 | 0 | return 0; |
61 | 0 | } |
62 | 0 | secp256k1_fe_get_b32(output32, &pk.x); |
63 | 0 | return 1; |
64 | 0 | } |
65 | | |
66 | 0 | int secp256k1_xonly_pubkey_cmp(const secp256k1_context* ctx, const secp256k1_xonly_pubkey* pk0, const secp256k1_xonly_pubkey* pk1) { |
67 | 0 | unsigned char out[2][32]; |
68 | 0 | const secp256k1_xonly_pubkey* pk[2]; |
69 | 0 | int i; |
70 | |
|
71 | 0 | VERIFY_CHECK(ctx != NULL); |
72 | 0 | pk[0] = pk0; pk[1] = pk1; |
73 | 0 | for (i = 0; i < 2; i++) { Branch (73:17): [True: 0, False: 0]
|
74 | | /* If the public key is NULL or invalid, xonly_pubkey_serialize will |
75 | | * call the illegal_callback and return 0. In that case we will |
76 | | * serialize the key as all zeros which is less than any valid public |
77 | | * key. This results in consistent comparisons even if NULL or invalid |
78 | | * pubkeys are involved and prevents edge cases such as sorting |
79 | | * algorithms that use this function and do not terminate as a |
80 | | * result. */ |
81 | 0 | if (!secp256k1_xonly_pubkey_serialize(ctx, out[i], pk[i])) { Branch (81:13): [True: 0, False: 0]
|
82 | | /* Note that xonly_pubkey_serialize should already set the output to |
83 | | * zero in that case, but it's not guaranteed by the API, we can't |
84 | | * test it and writing a VERIFY_CHECK is more complex than |
85 | | * explicitly memsetting (again). */ |
86 | 0 | memset(out[i], 0, sizeof(out[i])); |
87 | 0 | } |
88 | 0 | } |
89 | 0 | return secp256k1_memcmp_var(out[0], out[1], sizeof(out[1])); |
90 | 0 | } |
91 | | |
92 | | /** Keeps a group element as is if it has an even Y and otherwise negates it. |
93 | | * y_parity is set to 0 in the former case and to 1 in the latter case. |
94 | | * Requires that the coordinates of r are normalized. */ |
95 | 0 | static int secp256k1_extrakeys_ge_even_y(secp256k1_ge *r) { |
96 | 0 | int y_parity = 0; |
97 | 0 | VERIFY_CHECK(!secp256k1_ge_is_infinity(r)); |
98 | |
|
99 | 0 | if (secp256k1_fe_is_odd(&r->y)) { Branch (99:9): [True: 0, False: 0]
|
100 | 0 | secp256k1_fe_negate(&r->y, &r->y, 1); |
101 | 0 | y_parity = 1; |
102 | 0 | } |
103 | 0 | return y_parity; |
104 | 0 | } |
105 | | |
106 | 0 | int secp256k1_xonly_pubkey_from_pubkey(const secp256k1_context* ctx, secp256k1_xonly_pubkey *xonly_pubkey, int *pk_parity, const secp256k1_pubkey *pubkey) { |
107 | 0 | secp256k1_ge pk; |
108 | 0 | int tmp; |
109 | |
|
110 | 0 | VERIFY_CHECK(ctx != NULL); |
111 | 0 | ARG_CHECK(xonly_pubkey != NULL); |
112 | 0 | ARG_CHECK(pubkey != NULL); |
113 | | |
114 | 0 | if (!secp256k1_pubkey_load(ctx, &pk, pubkey)) { Branch (114:9): [True: 0, False: 0]
|
115 | 0 | return 0; |
116 | 0 | } |
117 | 0 | tmp = secp256k1_extrakeys_ge_even_y(&pk); |
118 | 0 | if (pk_parity != NULL) { Branch (118:9): [True: 0, False: 0]
|
119 | 0 | *pk_parity = tmp; |
120 | 0 | } |
121 | 0 | secp256k1_xonly_pubkey_save(xonly_pubkey, &pk); |
122 | 0 | return 1; |
123 | 0 | } |
124 | | |
125 | 0 | int secp256k1_xonly_pubkey_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, const secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) { |
126 | 0 | secp256k1_ge pk; |
127 | |
|
128 | 0 | VERIFY_CHECK(ctx != NULL); |
129 | 0 | ARG_CHECK(output_pubkey != NULL); |
130 | 0 | memset(output_pubkey, 0, sizeof(*output_pubkey)); |
131 | 0 | ARG_CHECK(internal_pubkey != NULL); |
132 | 0 | ARG_CHECK(tweak32 != NULL); |
133 | | |
134 | 0 | if (!secp256k1_xonly_pubkey_load(ctx, &pk, internal_pubkey) Branch (134:9): [True: 0, False: 0]
|
135 | 0 | || !secp256k1_ec_pubkey_tweak_add_helper(&pk, tweak32)) { Branch (135:12): [True: 0, False: 0]
|
136 | 0 | return 0; |
137 | 0 | } |
138 | 0 | secp256k1_pubkey_save(output_pubkey, &pk); |
139 | 0 | return 1; |
140 | 0 | } |
141 | | |
142 | 0 | int secp256k1_xonly_pubkey_tweak_add_check(const secp256k1_context* ctx, const unsigned char *tweaked_pubkey32, int tweaked_pk_parity, const secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) { |
143 | 0 | secp256k1_ge pk; |
144 | 0 | unsigned char pk_expected32[32]; |
145 | |
|
146 | 0 | VERIFY_CHECK(ctx != NULL); |
147 | 0 | ARG_CHECK(internal_pubkey != NULL); |
148 | 0 | ARG_CHECK(tweaked_pubkey32 != NULL); |
149 | 0 | ARG_CHECK(tweak32 != NULL); |
150 | | |
151 | 0 | if (!secp256k1_xonly_pubkey_load(ctx, &pk, internal_pubkey) Branch (151:9): [True: 0, False: 0]
|
152 | 0 | || !secp256k1_ec_pubkey_tweak_add_helper(&pk, tweak32)) { Branch (152:12): [True: 0, False: 0]
|
153 | 0 | return 0; |
154 | 0 | } |
155 | 0 | secp256k1_fe_normalize_var(&pk.x); |
156 | 0 | secp256k1_fe_normalize_var(&pk.y); |
157 | 0 | secp256k1_fe_get_b32(pk_expected32, &pk.x); |
158 | |
|
159 | 0 | return secp256k1_memcmp_var(&pk_expected32, tweaked_pubkey32, 32) == 0 Branch (159:12): [True: 0, False: 0]
|
160 | 0 | && secp256k1_fe_is_odd(&pk.y) == tweaked_pk_parity; Branch (160:16): [True: 0, False: 0]
|
161 | 0 | } |
162 | | |
163 | 0 | static void secp256k1_keypair_save(secp256k1_keypair *keypair, const secp256k1_scalar *sk, secp256k1_ge *pk) { |
164 | 0 | secp256k1_scalar_get_b32(&keypair->data[0], sk); |
165 | 0 | secp256k1_pubkey_save((secp256k1_pubkey *)&keypair->data[32], pk); |
166 | 0 | } |
167 | | |
168 | | |
169 | 0 | static int secp256k1_keypair_seckey_load(const secp256k1_context* ctx, secp256k1_scalar *sk, const secp256k1_keypair *keypair) { |
170 | 0 | int ret; |
171 | |
|
172 | 0 | ret = secp256k1_scalar_set_b32_seckey(sk, &keypair->data[0]); |
173 | | /* We can declassify ret here because sk is only zero if a keypair function |
174 | | * failed (which zeroes the keypair) and its return value is ignored. */ |
175 | 0 | secp256k1_declassify(ctx, &ret, sizeof(ret)); |
176 | 0 | ARG_CHECK(ret); |
177 | 0 | return ret; |
178 | 0 | } |
179 | | |
180 | | /* Load a keypair into pk and sk (if non-NULL). This function declassifies pk |
181 | | * and ARG_CHECKs that the keypair is not invalid. It always initializes sk and |
182 | | * pk with dummy values. */ |
183 | 0 | static int secp256k1_keypair_load(const secp256k1_context* ctx, secp256k1_scalar *sk, secp256k1_ge *pk, const secp256k1_keypair *keypair) { |
184 | 0 | int ret; |
185 | 0 | const secp256k1_pubkey *pubkey = (const secp256k1_pubkey *)&keypair->data[32]; |
186 | | |
187 | | /* Need to declassify the pubkey because pubkey_load ARG_CHECKs if it's |
188 | | * invalid. */ |
189 | 0 | secp256k1_declassify(ctx, pubkey, sizeof(*pubkey)); |
190 | 0 | ret = secp256k1_pubkey_load(ctx, pk, pubkey); |
191 | 0 | if (sk != NULL) { Branch (191:9): [True: 0, False: 0]
|
192 | 0 | ret = ret && secp256k1_keypair_seckey_load(ctx, sk, keypair); Branch (192:15): [True: 0, False: 0]
Branch (192:22): [True: 0, False: 0]
|
193 | 0 | } |
194 | 0 | if (!ret) { Branch (194:9): [True: 0, False: 0]
|
195 | 0 | *pk = secp256k1_ge_const_g; |
196 | 0 | if (sk != NULL) { Branch (196:13): [True: 0, False: 0]
|
197 | 0 | *sk = secp256k1_scalar_one; |
198 | 0 | } |
199 | 0 | } |
200 | 0 | return ret; |
201 | 0 | } |
202 | | |
203 | 0 | int secp256k1_keypair_create(const secp256k1_context* ctx, secp256k1_keypair *keypair, const unsigned char *seckey32) { |
204 | 0 | secp256k1_scalar sk; |
205 | 0 | secp256k1_ge pk; |
206 | 0 | int ret = 0; |
207 | 0 | VERIFY_CHECK(ctx != NULL); |
208 | 0 | ARG_CHECK(keypair != NULL); |
209 | 0 | memset(keypair, 0, sizeof(*keypair)); |
210 | 0 | ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); |
211 | 0 | ARG_CHECK(seckey32 != NULL); |
212 | | |
213 | 0 | ret = secp256k1_ec_pubkey_create_helper(&ctx->ecmult_gen_ctx, &sk, &pk, seckey32); |
214 | 0 | secp256k1_keypair_save(keypair, &sk, &pk); |
215 | 0 | secp256k1_memczero(keypair, sizeof(*keypair), !ret); |
216 | |
|
217 | 0 | secp256k1_scalar_clear(&sk); |
218 | 0 | return ret; |
219 | 0 | } |
220 | | |
221 | 0 | int secp256k1_keypair_sec(const secp256k1_context* ctx, unsigned char *seckey, const secp256k1_keypair *keypair) { |
222 | 0 | VERIFY_CHECK(ctx != NULL); |
223 | 0 | ARG_CHECK(seckey != NULL); |
224 | 0 | memset(seckey, 0, 32); |
225 | 0 | ARG_CHECK(keypair != NULL); |
226 | | |
227 | 0 | memcpy(seckey, &keypair->data[0], 32); |
228 | 0 | return 1; |
229 | 0 | } |
230 | | |
231 | 0 | int secp256k1_keypair_pub(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_keypair *keypair) { |
232 | 0 | VERIFY_CHECK(ctx != NULL); |
233 | 0 | ARG_CHECK(pubkey != NULL); |
234 | 0 | memset(pubkey, 0, sizeof(*pubkey)); |
235 | 0 | ARG_CHECK(keypair != NULL); |
236 | | |
237 | 0 | memcpy(pubkey->data, &keypair->data[32], sizeof(*pubkey)); |
238 | 0 | return 1; |
239 | 0 | } |
240 | | |
241 | 0 | int secp256k1_keypair_xonly_pub(const secp256k1_context* ctx, secp256k1_xonly_pubkey *pubkey, int *pk_parity, const secp256k1_keypair *keypair) { |
242 | 0 | secp256k1_ge pk; |
243 | 0 | int tmp; |
244 | |
|
245 | 0 | VERIFY_CHECK(ctx != NULL); |
246 | 0 | ARG_CHECK(pubkey != NULL); |
247 | 0 | memset(pubkey, 0, sizeof(*pubkey)); |
248 | 0 | ARG_CHECK(keypair != NULL); |
249 | | |
250 | 0 | if (!secp256k1_keypair_load(ctx, NULL, &pk, keypair)) { Branch (250:9): [True: 0, False: 0]
|
251 | 0 | return 0; |
252 | 0 | } |
253 | 0 | tmp = secp256k1_extrakeys_ge_even_y(&pk); |
254 | 0 | if (pk_parity != NULL) { Branch (254:9): [True: 0, False: 0]
|
255 | 0 | *pk_parity = tmp; |
256 | 0 | } |
257 | 0 | secp256k1_xonly_pubkey_save(pubkey, &pk); |
258 | |
|
259 | 0 | return 1; |
260 | 0 | } |
261 | | |
262 | 0 | int secp256k1_keypair_xonly_tweak_add(const secp256k1_context* ctx, secp256k1_keypair *keypair, const unsigned char *tweak32) { |
263 | 0 | secp256k1_ge pk; |
264 | 0 | secp256k1_scalar sk; |
265 | 0 | int y_parity; |
266 | 0 | int ret; |
267 | |
|
268 | 0 | VERIFY_CHECK(ctx != NULL); |
269 | 0 | ARG_CHECK(keypair != NULL); |
270 | 0 | ARG_CHECK(tweak32 != NULL); |
271 | | |
272 | 0 | ret = secp256k1_keypair_load(ctx, &sk, &pk, keypair); |
273 | 0 | memset(keypair, 0, sizeof(*keypair)); |
274 | |
|
275 | 0 | y_parity = secp256k1_extrakeys_ge_even_y(&pk); |
276 | 0 | if (y_parity == 1) { Branch (276:9): [True: 0, False: 0]
|
277 | 0 | secp256k1_scalar_negate(&sk, &sk); |
278 | 0 | } |
279 | |
|
280 | 0 | ret &= secp256k1_ec_seckey_tweak_add_helper(&sk, tweak32); |
281 | 0 | ret &= secp256k1_ec_pubkey_tweak_add_helper(&pk, tweak32); |
282 | |
|
283 | 0 | secp256k1_declassify(ctx, &ret, sizeof(ret)); |
284 | 0 | if (ret) { Branch (284:9): [True: 0, False: 0]
|
285 | 0 | secp256k1_keypair_save(keypair, &sk, &pk); |
286 | 0 | } |
287 | |
|
288 | 0 | secp256k1_scalar_clear(&sk); |
289 | 0 | return ret; |
290 | 0 | } |
291 | | |
292 | | #endif |