/root/bitcoin/src/secp256k1/src/modules/musig/session_impl.h
Line | Count | Source |
1 | | /*********************************************************************** |
2 | | * Distributed under the MIT software license, see the accompanying * |
3 | | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* |
4 | | ***********************************************************************/ |
5 | | |
6 | | #ifndef SECP256K1_MODULE_MUSIG_SESSION_IMPL_H |
7 | | #define SECP256K1_MODULE_MUSIG_SESSION_IMPL_H |
8 | | |
9 | | #include <string.h> |
10 | | |
11 | | #include "../../../include/secp256k1.h" |
12 | | #include "../../../include/secp256k1_extrakeys.h" |
13 | | #include "../../../include/secp256k1_musig.h" |
14 | | |
15 | | #include "keyagg.h" |
16 | | #include "session.h" |
17 | | #include "../../eckey.h" |
18 | | #include "../../hash.h" |
19 | | #include "../../scalar.h" |
20 | | #include "../../util.h" |
21 | | |
22 | | /* Outputs 33 zero bytes if the given group element is the point at infinity and |
23 | | * otherwise outputs the compressed serialization */ |
24 | 0 | static void secp256k1_musig_ge_serialize_ext(unsigned char *out33, secp256k1_ge* ge) { |
25 | 0 | if (secp256k1_ge_is_infinity(ge)) { |
26 | 0 | memset(out33, 0, 33); |
27 | 0 | } else { |
28 | 0 | int ret; |
29 | 0 | size_t size = 33; |
30 | 0 | ret = secp256k1_eckey_pubkey_serialize(ge, out33, &size, 1); |
31 | | #ifdef VERIFY |
32 | | /* Serialize must succeed because the point is not at infinity */ |
33 | | VERIFY_CHECK(ret && size == 33); |
34 | | #else |
35 | 0 | (void) ret; |
36 | 0 | #endif |
37 | 0 | } |
38 | 0 | } |
39 | | |
40 | | /* Outputs the point at infinity if the given byte array is all zero, otherwise |
41 | | * attempts to parse compressed point serialization. */ |
42 | 0 | static int secp256k1_musig_ge_parse_ext(secp256k1_ge* ge, const unsigned char *in33) { |
43 | 0 | unsigned char zeros[33] = { 0 }; |
44 | |
|
45 | 0 | if (secp256k1_memcmp_var(in33, zeros, sizeof(zeros)) == 0) { |
46 | 0 | secp256k1_ge_set_infinity(ge); |
47 | 0 | return 1; |
48 | 0 | } |
49 | 0 | if (!secp256k1_eckey_pubkey_parse(ge, in33, 33)) { |
50 | 0 | return 0; |
51 | 0 | } |
52 | 0 | return secp256k1_ge_is_in_correct_subgroup(ge); |
53 | 0 | } |
54 | | |
55 | | static const unsigned char secp256k1_musig_secnonce_magic[4] = { 0x22, 0x0e, 0xdc, 0xf1 }; |
56 | | |
57 | 0 | static void secp256k1_musig_secnonce_save(secp256k1_musig_secnonce *secnonce, const secp256k1_scalar *k, const secp256k1_ge *pk) { |
58 | 0 | memcpy(&secnonce->data[0], secp256k1_musig_secnonce_magic, 4); |
59 | 0 | secp256k1_scalar_get_b32(&secnonce->data[4], &k[0]); |
60 | 0 | secp256k1_scalar_get_b32(&secnonce->data[36], &k[1]); |
61 | 0 | secp256k1_ge_to_bytes(&secnonce->data[68], pk); |
62 | 0 | } |
63 | | |
64 | 0 | static int secp256k1_musig_secnonce_load(const secp256k1_context* ctx, secp256k1_scalar *k, secp256k1_ge *pk, const secp256k1_musig_secnonce *secnonce) { |
65 | 0 | int is_zero; |
66 | 0 | ARG_CHECK(secp256k1_memcmp_var(&secnonce->data[0], secp256k1_musig_secnonce_magic, 4) == 0); |
67 | | /* We make very sure that the nonce isn't invalidated by checking the values |
68 | | * in addition to the magic. */ |
69 | 0 | is_zero = secp256k1_is_zero_array(&secnonce->data[4], 2 * 32); |
70 | 0 | secp256k1_declassify(ctx, &is_zero, sizeof(is_zero)); |
71 | 0 | ARG_CHECK(!is_zero); |
72 | | |
73 | 0 | secp256k1_scalar_set_b32(&k[0], &secnonce->data[4], NULL); |
74 | 0 | secp256k1_scalar_set_b32(&k[1], &secnonce->data[36], NULL); |
75 | 0 | secp256k1_ge_from_bytes(pk, &secnonce->data[68]); |
76 | 0 | return 1; |
77 | 0 | } |
78 | | |
79 | | /* If flag is true, invalidate the secnonce; otherwise leave it. Constant-time. */ |
80 | 0 | static void secp256k1_musig_secnonce_invalidate(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, int flag) { |
81 | 0 | secp256k1_memczero(secnonce->data, sizeof(secnonce->data), flag); |
82 | | /* The flag argument is usually classified. So, the line above makes the |
83 | | * magic and public key classified. However, we need both to be |
84 | | * declassified. Note that we don't declassify the entire object, because if |
85 | | * flag is 0, then k[0] and k[1] have not been zeroed. */ |
86 | 0 | secp256k1_declassify(ctx, secnonce->data, sizeof(secp256k1_musig_secnonce_magic)); |
87 | 0 | secp256k1_declassify(ctx, &secnonce->data[68], 64); |
88 | 0 | } |
89 | | |
90 | | static const unsigned char secp256k1_musig_pubnonce_magic[4] = { 0xf5, 0x7a, 0x3d, 0xa0 }; |
91 | | |
92 | | /* Saves two group elements into a pubnonce. Requires that none of the provided |
93 | | * group elements is infinity. */ |
94 | 0 | static void secp256k1_musig_pubnonce_save(secp256k1_musig_pubnonce* nonce, const secp256k1_ge* ges) { |
95 | 0 | int i; |
96 | 0 | memcpy(&nonce->data[0], secp256k1_musig_pubnonce_magic, 4); |
97 | 0 | for (i = 0; i < 2; i++) { |
98 | 0 | secp256k1_ge_to_bytes(nonce->data + 4+64*i, &ges[i]); |
99 | 0 | } |
100 | 0 | } |
101 | | |
102 | | /* Loads two group elements from a pubnonce. Returns 1 unless the nonce wasn't |
103 | | * properly initialized */ |
104 | 0 | static int secp256k1_musig_pubnonce_load(const secp256k1_context* ctx, secp256k1_ge* ges, const secp256k1_musig_pubnonce* nonce) { |
105 | 0 | int i; |
106 | |
|
107 | 0 | ARG_CHECK(secp256k1_memcmp_var(&nonce->data[0], secp256k1_musig_pubnonce_magic, 4) == 0); |
108 | 0 | for (i = 0; i < 2; i++) { |
109 | 0 | secp256k1_ge_from_bytes(&ges[i], nonce->data + 4 + 64*i); |
110 | 0 | } |
111 | 0 | return 1; |
112 | 0 | } |
113 | | |
114 | | static const unsigned char secp256k1_musig_aggnonce_magic[4] = { 0xa8, 0xb7, 0xe4, 0x67 }; |
115 | | |
116 | 0 | static void secp256k1_musig_aggnonce_save(secp256k1_musig_aggnonce* nonce, const secp256k1_ge* ges) { |
117 | 0 | int i; |
118 | 0 | memcpy(&nonce->data[0], secp256k1_musig_aggnonce_magic, 4); |
119 | 0 | for (i = 0; i < 2; i++) { |
120 | 0 | secp256k1_ge_to_bytes_ext(&nonce->data[4 + 64*i], &ges[i]); |
121 | 0 | } |
122 | 0 | } |
123 | | |
124 | 0 | static int secp256k1_musig_aggnonce_load(const secp256k1_context* ctx, secp256k1_ge* ges, const secp256k1_musig_aggnonce* nonce) { |
125 | 0 | int i; |
126 | |
|
127 | 0 | ARG_CHECK(secp256k1_memcmp_var(&nonce->data[0], secp256k1_musig_aggnonce_magic, 4) == 0); |
128 | 0 | for (i = 0; i < 2; i++) { |
129 | 0 | secp256k1_ge_from_bytes_ext(&ges[i], &nonce->data[4 + 64*i]); |
130 | 0 | } |
131 | 0 | return 1; |
132 | 0 | } |
133 | | |
134 | | static const unsigned char secp256k1_musig_session_cache_magic[4] = { 0x9d, 0xed, 0xe9, 0x17 }; |
135 | | |
136 | | /* A session consists of |
137 | | * - 4 byte session cache magic |
138 | | * - 1 byte the parity of the final nonce |
139 | | * - 32 byte serialized x-only final nonce |
140 | | * - 32 byte nonce coefficient b |
141 | | * - 32 byte signature challenge hash e |
142 | | * - 32 byte scalar s that is added to the partial signatures of the signers |
143 | | */ |
144 | 0 | static void secp256k1_musig_session_save(secp256k1_musig_session *session, const secp256k1_musig_session_internal *session_i) { |
145 | 0 | unsigned char *ptr = session->data; |
146 | |
|
147 | 0 | memcpy(ptr, secp256k1_musig_session_cache_magic, 4); |
148 | 0 | ptr += 4; |
149 | 0 | *ptr = session_i->fin_nonce_parity; |
150 | 0 | ptr += 1; |
151 | 0 | memcpy(ptr, session_i->fin_nonce, 32); |
152 | 0 | ptr += 32; |
153 | 0 | secp256k1_scalar_get_b32(ptr, &session_i->noncecoef); |
154 | 0 | ptr += 32; |
155 | 0 | secp256k1_scalar_get_b32(ptr, &session_i->challenge); |
156 | 0 | ptr += 32; |
157 | 0 | secp256k1_scalar_get_b32(ptr, &session_i->s_part); |
158 | 0 | } |
159 | | |
160 | 0 | static int secp256k1_musig_session_load(const secp256k1_context* ctx, secp256k1_musig_session_internal *session_i, const secp256k1_musig_session *session) { |
161 | 0 | const unsigned char *ptr = session->data; |
162 | |
|
163 | 0 | ARG_CHECK(secp256k1_memcmp_var(ptr, secp256k1_musig_session_cache_magic, 4) == 0); |
164 | 0 | ptr += 4; |
165 | 0 | session_i->fin_nonce_parity = *ptr; |
166 | 0 | ptr += 1; |
167 | 0 | memcpy(session_i->fin_nonce, ptr, 32); |
168 | 0 | ptr += 32; |
169 | 0 | secp256k1_scalar_set_b32(&session_i->noncecoef, ptr, NULL); |
170 | 0 | ptr += 32; |
171 | 0 | secp256k1_scalar_set_b32(&session_i->challenge, ptr, NULL); |
172 | 0 | ptr += 32; |
173 | 0 | secp256k1_scalar_set_b32(&session_i->s_part, ptr, NULL); |
174 | 0 | return 1; |
175 | 0 | } |
176 | | |
177 | | static const unsigned char secp256k1_musig_partial_sig_magic[4] = { 0xeb, 0xfb, 0x1a, 0x32 }; |
178 | | |
179 | 0 | static void secp256k1_musig_partial_sig_save(secp256k1_musig_partial_sig* sig, secp256k1_scalar *s) { |
180 | 0 | memcpy(&sig->data[0], secp256k1_musig_partial_sig_magic, 4); |
181 | 0 | secp256k1_scalar_get_b32(&sig->data[4], s); |
182 | 0 | } |
183 | | |
184 | 0 | static int secp256k1_musig_partial_sig_load(const secp256k1_context* ctx, secp256k1_scalar *s, const secp256k1_musig_partial_sig* sig) { |
185 | 0 | int overflow; |
186 | |
|
187 | 0 | ARG_CHECK(secp256k1_memcmp_var(&sig->data[0], secp256k1_musig_partial_sig_magic, 4) == 0); |
188 | 0 | secp256k1_scalar_set_b32(s, &sig->data[4], &overflow); |
189 | | /* Parsed signatures can not overflow */ |
190 | 0 | VERIFY_CHECK(!overflow); |
191 | 0 | return 1; |
192 | 0 | } |
193 | | |
194 | 0 | int secp256k1_musig_pubnonce_parse(const secp256k1_context* ctx, secp256k1_musig_pubnonce* nonce, const unsigned char *in66) { |
195 | 0 | secp256k1_ge ges[2]; |
196 | 0 | int i; |
197 | |
|
198 | 0 | VERIFY_CHECK(ctx != NULL); |
199 | 0 | ARG_CHECK(nonce != NULL); |
200 | 0 | ARG_CHECK(in66 != NULL); |
201 | | |
202 | 0 | for (i = 0; i < 2; i++) { |
203 | 0 | if (!secp256k1_eckey_pubkey_parse(&ges[i], &in66[33*i], 33)) { |
204 | 0 | return 0; |
205 | 0 | } |
206 | 0 | if (!secp256k1_ge_is_in_correct_subgroup(&ges[i])) { |
207 | 0 | return 0; |
208 | 0 | } |
209 | 0 | } |
210 | 0 | secp256k1_musig_pubnonce_save(nonce, ges); |
211 | 0 | return 1; |
212 | 0 | } |
213 | | |
214 | 0 | int secp256k1_musig_pubnonce_serialize(const secp256k1_context* ctx, unsigned char *out66, const secp256k1_musig_pubnonce* nonce) { |
215 | 0 | secp256k1_ge ges[2]; |
216 | 0 | int i; |
217 | |
|
218 | 0 | VERIFY_CHECK(ctx != NULL); |
219 | 0 | ARG_CHECK(out66 != NULL); |
220 | 0 | memset(out66, 0, 66); |
221 | 0 | ARG_CHECK(nonce != NULL); |
222 | | |
223 | 0 | if (!secp256k1_musig_pubnonce_load(ctx, ges, nonce)) { |
224 | 0 | return 0; |
225 | 0 | } |
226 | 0 | for (i = 0; i < 2; i++) { |
227 | 0 | int ret; |
228 | 0 | size_t size = 33; |
229 | 0 | ret = secp256k1_eckey_pubkey_serialize(&ges[i], &out66[33*i], &size, 1); |
230 | | #ifdef VERIFY |
231 | | /* serialize must succeed because the point was just loaded */ |
232 | | VERIFY_CHECK(ret && size == 33); |
233 | | #else |
234 | 0 | (void) ret; |
235 | 0 | #endif |
236 | 0 | } |
237 | 0 | return 1; |
238 | 0 | } |
239 | | |
240 | 0 | int secp256k1_musig_aggnonce_parse(const secp256k1_context* ctx, secp256k1_musig_aggnonce* nonce, const unsigned char *in66) { |
241 | 0 | secp256k1_ge ges[2]; |
242 | 0 | int i; |
243 | |
|
244 | 0 | VERIFY_CHECK(ctx != NULL); |
245 | 0 | ARG_CHECK(nonce != NULL); |
246 | 0 | ARG_CHECK(in66 != NULL); |
247 | | |
248 | 0 | for (i = 0; i < 2; i++) { |
249 | 0 | if (!secp256k1_musig_ge_parse_ext(&ges[i], &in66[33*i])) { |
250 | 0 | return 0; |
251 | 0 | } |
252 | 0 | } |
253 | 0 | secp256k1_musig_aggnonce_save(nonce, ges); |
254 | 0 | return 1; |
255 | 0 | } |
256 | | |
257 | 0 | int secp256k1_musig_aggnonce_serialize(const secp256k1_context* ctx, unsigned char *out66, const secp256k1_musig_aggnonce* nonce) { |
258 | 0 | secp256k1_ge ges[2]; |
259 | 0 | int i; |
260 | |
|
261 | 0 | VERIFY_CHECK(ctx != NULL); |
262 | 0 | ARG_CHECK(out66 != NULL); |
263 | 0 | memset(out66, 0, 66); |
264 | 0 | ARG_CHECK(nonce != NULL); |
265 | | |
266 | 0 | if (!secp256k1_musig_aggnonce_load(ctx, ges, nonce)) { |
267 | 0 | return 0; |
268 | 0 | } |
269 | 0 | for (i = 0; i < 2; i++) { |
270 | 0 | secp256k1_musig_ge_serialize_ext(&out66[33*i], &ges[i]); |
271 | 0 | } |
272 | 0 | return 1; |
273 | 0 | } |
274 | | |
275 | 0 | int secp256k1_musig_partial_sig_parse(const secp256k1_context* ctx, secp256k1_musig_partial_sig* sig, const unsigned char *in32) { |
276 | 0 | secp256k1_scalar tmp; |
277 | 0 | int overflow; |
278 | 0 | VERIFY_CHECK(ctx != NULL); |
279 | 0 | ARG_CHECK(sig != NULL); |
280 | 0 | ARG_CHECK(in32 != NULL); |
281 | | |
282 | | /* Ensure that using the signature will fail if parsing fails (and the user |
283 | | * doesn't check the return value). */ |
284 | 0 | memset(sig, 0, sizeof(*sig)); |
285 | |
|
286 | 0 | secp256k1_scalar_set_b32(&tmp, in32, &overflow); |
287 | 0 | if (overflow) { |
288 | 0 | return 0; |
289 | 0 | } |
290 | 0 | secp256k1_musig_partial_sig_save(sig, &tmp); |
291 | 0 | return 1; |
292 | 0 | } |
293 | | |
294 | 0 | int secp256k1_musig_partial_sig_serialize(const secp256k1_context* ctx, unsigned char *out32, const secp256k1_musig_partial_sig* sig) { |
295 | 0 | VERIFY_CHECK(ctx != NULL); |
296 | 0 | ARG_CHECK(out32 != NULL); |
297 | 0 | ARG_CHECK(sig != NULL); |
298 | 0 | ARG_CHECK(secp256k1_memcmp_var(&sig->data[0], secp256k1_musig_partial_sig_magic, 4) == 0); |
299 | | |
300 | 0 | memcpy(out32, &sig->data[4], 32); |
301 | 0 | return 1; |
302 | 0 | } |
303 | | |
304 | | /* Write optional inputs into the hash */ |
305 | 0 | static void secp256k1_nonce_function_musig_helper(secp256k1_sha256 *sha, unsigned int prefix_size, const unsigned char *data, unsigned char len) { |
306 | 0 | unsigned char zero[7] = { 0 }; |
307 | | /* The spec requires length prefixes to be between 1 and 8 bytes |
308 | | * (inclusive) */ |
309 | 0 | VERIFY_CHECK(prefix_size >= 1 && prefix_size <= 8); |
310 | | /* Since the length of all input data fits in a byte, we can always pad the |
311 | | * length prefix with prefix_size - 1 zero bytes. */ |
312 | 0 | secp256k1_sha256_write(sha, zero, prefix_size - 1); |
313 | 0 | if (data != NULL) { |
314 | 0 | secp256k1_sha256_write(sha, &len, 1); |
315 | 0 | secp256k1_sha256_write(sha, data, len); |
316 | 0 | } else { |
317 | 0 | len = 0; |
318 | 0 | secp256k1_sha256_write(sha, &len, 1); |
319 | 0 | } |
320 | 0 | } |
321 | | |
322 | | /* Initializes SHA256 with fixed midstate. This midstate was computed by applying |
323 | | * SHA256 to SHA256("MuSig/aux")||SHA256("MuSig/aux"). */ |
324 | 0 | static void secp256k1_nonce_function_musig_sha256_tagged_aux(secp256k1_sha256 *sha) { |
325 | 0 | secp256k1_sha256_initialize(sha); |
326 | 0 | sha->s[0] = 0xa19e884bul; |
327 | 0 | sha->s[1] = 0xf463fe7eul; |
328 | 0 | sha->s[2] = 0x2f18f9a2ul; |
329 | 0 | sha->s[3] = 0xbeb0f9fful; |
330 | 0 | sha->s[4] = 0x0f37e8b0ul; |
331 | 0 | sha->s[5] = 0x06ebd26ful; |
332 | 0 | sha->s[6] = 0xe3b243d2ul; |
333 | 0 | sha->s[7] = 0x522fb150ul; |
334 | 0 | sha->bytes = 64; |
335 | 0 | } |
336 | | |
337 | | /* Initializes SHA256 with fixed midstate. This midstate was computed by applying |
338 | | * SHA256 to SHA256("MuSig/nonce")||SHA256("MuSig/nonce"). */ |
339 | 0 | static void secp256k1_nonce_function_musig_sha256_tagged(secp256k1_sha256 *sha) { |
340 | 0 | secp256k1_sha256_initialize(sha); |
341 | 0 | sha->s[0] = 0x07101b64ul; |
342 | 0 | sha->s[1] = 0x18003414ul; |
343 | 0 | sha->s[2] = 0x0391bc43ul; |
344 | 0 | sha->s[3] = 0x0e6258eeul; |
345 | 0 | sha->s[4] = 0x29d26b72ul; |
346 | 0 | sha->s[5] = 0x8343937eul; |
347 | 0 | sha->s[6] = 0xb7a0a4fbul; |
348 | 0 | sha->s[7] = 0xff568a30ul; |
349 | 0 | sha->bytes = 64; |
350 | 0 | } |
351 | | |
352 | 0 | static void secp256k1_nonce_function_musig(secp256k1_scalar *k, const unsigned char *session_secrand, const unsigned char *msg32, const unsigned char *seckey32, const unsigned char *pk33, const unsigned char *agg_pk32, const unsigned char *extra_input32) { |
353 | 0 | secp256k1_sha256 sha; |
354 | 0 | unsigned char rand[32]; |
355 | 0 | unsigned char i; |
356 | 0 | unsigned char msg_present; |
357 | |
|
358 | 0 | if (seckey32 != NULL) { |
359 | 0 | secp256k1_nonce_function_musig_sha256_tagged_aux(&sha); |
360 | 0 | secp256k1_sha256_write(&sha, session_secrand, 32); |
361 | 0 | secp256k1_sha256_finalize(&sha, rand); |
362 | 0 | for (i = 0; i < 32; i++) { |
363 | 0 | rand[i] ^= seckey32[i]; |
364 | 0 | } |
365 | 0 | } else { |
366 | 0 | memcpy(rand, session_secrand, sizeof(rand)); |
367 | 0 | } |
368 | |
|
369 | 0 | secp256k1_nonce_function_musig_sha256_tagged(&sha); |
370 | 0 | secp256k1_sha256_write(&sha, rand, sizeof(rand)); |
371 | 0 | secp256k1_nonce_function_musig_helper(&sha, 1, pk33, 33); |
372 | 0 | secp256k1_nonce_function_musig_helper(&sha, 1, agg_pk32, 32); |
373 | 0 | msg_present = msg32 != NULL; |
374 | 0 | secp256k1_sha256_write(&sha, &msg_present, 1); |
375 | 0 | if (msg_present) { |
376 | 0 | secp256k1_nonce_function_musig_helper(&sha, 8, msg32, 32); |
377 | 0 | } |
378 | 0 | secp256k1_nonce_function_musig_helper(&sha, 4, extra_input32, 32); |
379 | |
|
380 | 0 | for (i = 0; i < 2; i++) { |
381 | 0 | unsigned char buf[32]; |
382 | 0 | secp256k1_sha256 sha_tmp = sha; |
383 | 0 | secp256k1_sha256_write(&sha_tmp, &i, 1); |
384 | 0 | secp256k1_sha256_finalize(&sha_tmp, buf); |
385 | 0 | secp256k1_scalar_set_b32(&k[i], buf, NULL); |
386 | | |
387 | | /* Attempt to erase secret data */ |
388 | 0 | secp256k1_memclear(buf, sizeof(buf)); |
389 | 0 | secp256k1_sha256_clear(&sha_tmp); |
390 | 0 | } |
391 | 0 | secp256k1_memclear(rand, sizeof(rand)); |
392 | 0 | secp256k1_sha256_clear(&sha); |
393 | 0 | } |
394 | | |
395 | 0 | static int secp256k1_musig_nonce_gen_internal(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, secp256k1_musig_pubnonce *pubnonce, const unsigned char *input_nonce, const unsigned char *seckey, const secp256k1_pubkey *pubkey, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *extra_input32) { |
396 | 0 | secp256k1_scalar k[2]; |
397 | 0 | secp256k1_ge nonce_pts[2]; |
398 | 0 | secp256k1_gej nonce_ptj[2]; |
399 | 0 | int i; |
400 | 0 | unsigned char pk_ser[33]; |
401 | 0 | size_t pk_ser_len = sizeof(pk_ser); |
402 | 0 | unsigned char aggpk_ser[32]; |
403 | 0 | unsigned char *aggpk_ser_ptr = NULL; |
404 | 0 | secp256k1_ge pk; |
405 | 0 | int pk_serialize_success; |
406 | 0 | int ret = 1; |
407 | |
|
408 | 0 | ARG_CHECK(pubnonce != NULL); |
409 | 0 | memset(pubnonce, 0, sizeof(*pubnonce)); |
410 | 0 | ARG_CHECK(pubkey != NULL); |
411 | 0 | ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); |
412 | | |
413 | | /* Check that the seckey is valid to be able to sign for it later. */ |
414 | 0 | if (seckey != NULL) { |
415 | 0 | secp256k1_scalar sk; |
416 | 0 | ret &= secp256k1_scalar_set_b32_seckey(&sk, seckey); |
417 | 0 | secp256k1_scalar_clear(&sk); |
418 | 0 | } |
419 | |
|
420 | 0 | if (keyagg_cache != NULL) { |
421 | 0 | secp256k1_keyagg_cache_internal cache_i; |
422 | 0 | if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) { |
423 | 0 | return 0; |
424 | 0 | } |
425 | | /* The loaded point cache_i.pk can not be the point at infinity. */ |
426 | 0 | secp256k1_fe_get_b32(aggpk_ser, &cache_i.pk.x); |
427 | 0 | aggpk_ser_ptr = aggpk_ser; |
428 | 0 | } |
429 | 0 | if (!secp256k1_pubkey_load(ctx, &pk, pubkey)) { |
430 | 0 | return 0; |
431 | 0 | } |
432 | 0 | pk_serialize_success = secp256k1_eckey_pubkey_serialize(&pk, pk_ser, &pk_ser_len, 1); |
433 | |
|
434 | | #ifdef VERIFY |
435 | | /* A pubkey cannot be the point at infinity */ |
436 | | VERIFY_CHECK(pk_serialize_success); |
437 | | VERIFY_CHECK(pk_ser_len == sizeof(pk_ser)); |
438 | | #else |
439 | 0 | (void) pk_serialize_success; |
440 | 0 | #endif |
441 | |
|
442 | 0 | secp256k1_nonce_function_musig(k, input_nonce, msg32, seckey, pk_ser, aggpk_ser_ptr, extra_input32); |
443 | 0 | VERIFY_CHECK(!secp256k1_scalar_is_zero(&k[0])); |
444 | 0 | VERIFY_CHECK(!secp256k1_scalar_is_zero(&k[1])); |
445 | 0 | secp256k1_musig_secnonce_save(secnonce, k, &pk); |
446 | 0 | secp256k1_musig_secnonce_invalidate(ctx, secnonce, !ret); |
447 | | |
448 | | /* Compute pubnonce as two gejs */ |
449 | 0 | for (i = 0; i < 2; i++) { |
450 | 0 | secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &nonce_ptj[i], &k[i]); |
451 | 0 | secp256k1_scalar_clear(&k[i]); |
452 | 0 | } |
453 | | |
454 | | /* Batch convert to two public ges */ |
455 | 0 | secp256k1_ge_set_all_gej(nonce_pts, nonce_ptj, 2); |
456 | 0 | for (i = 0; i < 2; i++) { |
457 | 0 | secp256k1_gej_clear(&nonce_ptj[i]); |
458 | 0 | } |
459 | |
|
460 | 0 | for (i = 0; i < 2; i++) { |
461 | 0 | secp256k1_declassify(ctx, &nonce_pts[i], sizeof(nonce_pts[i])); |
462 | 0 | } |
463 | | /* None of the nonce_pts will be infinity because k != 0 with overwhelming |
464 | | * probability */ |
465 | 0 | secp256k1_musig_pubnonce_save(pubnonce, nonce_pts); |
466 | 0 | return ret; |
467 | 0 | } |
468 | | |
469 | 0 | int secp256k1_musig_nonce_gen(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, secp256k1_musig_pubnonce *pubnonce, unsigned char *session_secrand32, const unsigned char *seckey, const secp256k1_pubkey *pubkey, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *extra_input32) { |
470 | 0 | int ret = 1; |
471 | |
|
472 | 0 | VERIFY_CHECK(ctx != NULL); |
473 | 0 | ARG_CHECK(secnonce != NULL); |
474 | 0 | memset(secnonce, 0, sizeof(*secnonce)); |
475 | 0 | ARG_CHECK(session_secrand32 != NULL); |
476 | | |
477 | | /* Check in constant time that the session_secrand32 is not 0 as a |
478 | | * defense-in-depth measure that may protect against a faulty RNG. */ |
479 | 0 | ret &= !secp256k1_is_zero_array(session_secrand32, 32); |
480 | | |
481 | | /* We can declassify because branching on ret is only relevant when this |
482 | | * function called with an invalid session_secrand32 argument */ |
483 | 0 | secp256k1_declassify(ctx, &ret, sizeof(ret)); |
484 | 0 | if (ret == 0) { |
485 | 0 | secp256k1_musig_secnonce_invalidate(ctx, secnonce, 1); |
486 | 0 | return 0; |
487 | 0 | } |
488 | | |
489 | 0 | ret &= secp256k1_musig_nonce_gen_internal(ctx, secnonce, pubnonce, session_secrand32, seckey, pubkey, msg32, keyagg_cache, extra_input32); |
490 | | |
491 | | /* Set the session_secrand32 buffer to zero to prevent the caller from using |
492 | | * nonce_gen multiple times with the same buffer. */ |
493 | 0 | secp256k1_memczero(session_secrand32, 32, ret); |
494 | 0 | return ret; |
495 | 0 | } |
496 | | |
497 | 0 | int secp256k1_musig_nonce_gen_counter(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, secp256k1_musig_pubnonce *pubnonce, uint64_t nonrepeating_cnt, const secp256k1_keypair *keypair, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *extra_input32) { |
498 | 0 | unsigned char buf[32] = { 0 }; |
499 | 0 | unsigned char seckey[32]; |
500 | 0 | secp256k1_pubkey pubkey; |
501 | 0 | int ret; |
502 | |
|
503 | 0 | VERIFY_CHECK(ctx != NULL); |
504 | 0 | ARG_CHECK(secnonce != NULL); |
505 | 0 | memset(secnonce, 0, sizeof(*secnonce)); |
506 | 0 | ARG_CHECK(keypair != NULL); |
507 | | |
508 | 0 | secp256k1_write_be64(buf, nonrepeating_cnt); |
509 | | /* keypair_sec and keypair_pub do not fail if the arguments are not NULL */ |
510 | 0 | ret = secp256k1_keypair_sec(ctx, seckey, keypair); |
511 | 0 | VERIFY_CHECK(ret); |
512 | 0 | ret = secp256k1_keypair_pub(ctx, &pubkey, keypair); |
513 | 0 | VERIFY_CHECK(ret); |
514 | 0 | #ifndef VERIFY |
515 | 0 | (void) ret; |
516 | 0 | #endif |
517 | |
|
518 | 0 | if (!secp256k1_musig_nonce_gen_internal(ctx, secnonce, pubnonce, buf, seckey, &pubkey, msg32, keyagg_cache, extra_input32)) { |
519 | 0 | return 0; |
520 | 0 | } |
521 | 0 | secp256k1_memclear(seckey, sizeof(seckey)); |
522 | 0 | return 1; |
523 | 0 | } |
524 | | |
525 | 0 | static int secp256k1_musig_sum_pubnonces(const secp256k1_context* ctx, secp256k1_gej *summed_pubnonces, const secp256k1_musig_pubnonce * const* pubnonces, size_t n_pubnonces) { |
526 | 0 | size_t i; |
527 | 0 | int j; |
528 | |
|
529 | 0 | secp256k1_gej_set_infinity(&summed_pubnonces[0]); |
530 | 0 | secp256k1_gej_set_infinity(&summed_pubnonces[1]); |
531 | |
|
532 | 0 | for (i = 0; i < n_pubnonces; i++) { |
533 | 0 | secp256k1_ge nonce_pts[2]; |
534 | 0 | if (!secp256k1_musig_pubnonce_load(ctx, nonce_pts, pubnonces[i])) { |
535 | 0 | return 0; |
536 | 0 | } |
537 | 0 | for (j = 0; j < 2; j++) { |
538 | 0 | secp256k1_gej_add_ge_var(&summed_pubnonces[j], &summed_pubnonces[j], &nonce_pts[j], NULL); |
539 | 0 | } |
540 | 0 | } |
541 | 0 | return 1; |
542 | 0 | } |
543 | | |
544 | 0 | int secp256k1_musig_nonce_agg(const secp256k1_context* ctx, secp256k1_musig_aggnonce *aggnonce, const secp256k1_musig_pubnonce * const* pubnonces, size_t n_pubnonces) { |
545 | 0 | secp256k1_gej aggnonce_ptsj[2]; |
546 | 0 | secp256k1_ge aggnonce_pts[2]; |
547 | 0 | VERIFY_CHECK(ctx != NULL); |
548 | 0 | ARG_CHECK(aggnonce != NULL); |
549 | 0 | ARG_CHECK(pubnonces != NULL); |
550 | 0 | ARG_CHECK(n_pubnonces > 0); |
551 | | |
552 | 0 | if (!secp256k1_musig_sum_pubnonces(ctx, aggnonce_ptsj, pubnonces, n_pubnonces)) { |
553 | 0 | return 0; |
554 | 0 | } |
555 | 0 | secp256k1_ge_set_all_gej_var(aggnonce_pts, aggnonce_ptsj, 2); |
556 | 0 | secp256k1_musig_aggnonce_save(aggnonce, aggnonce_pts); |
557 | 0 | return 1; |
558 | 0 | } |
559 | | |
560 | | /* Initializes SHA256 with fixed midstate. This midstate was computed by applying |
561 | | * SHA256 to SHA256("MuSig/noncecoef")||SHA256("MuSig/noncecoef"). */ |
562 | 0 | static void secp256k1_musig_compute_noncehash_sha256_tagged(secp256k1_sha256 *sha) { |
563 | 0 | secp256k1_sha256_initialize(sha); |
564 | 0 | sha->s[0] = 0x2c7d5a45ul; |
565 | 0 | sha->s[1] = 0x06bf7e53ul; |
566 | 0 | sha->s[2] = 0x89be68a6ul; |
567 | 0 | sha->s[3] = 0x971254c0ul; |
568 | 0 | sha->s[4] = 0x60ac12d2ul; |
569 | 0 | sha->s[5] = 0x72846dcdul; |
570 | 0 | sha->s[6] = 0x6c81212ful; |
571 | 0 | sha->s[7] = 0xde7a2500ul; |
572 | 0 | sha->bytes = 64; |
573 | 0 | } |
574 | | |
575 | | /* tagged_hash(aggnonce[0], aggnonce[1], agg_pk, msg) */ |
576 | 0 | static void secp256k1_musig_compute_noncehash(unsigned char *noncehash, secp256k1_ge *aggnonce, const unsigned char *agg_pk32, const unsigned char *msg) { |
577 | 0 | unsigned char buf[33]; |
578 | 0 | secp256k1_sha256 sha; |
579 | 0 | int i; |
580 | |
|
581 | 0 | secp256k1_musig_compute_noncehash_sha256_tagged(&sha); |
582 | 0 | for (i = 0; i < 2; i++) { |
583 | 0 | secp256k1_musig_ge_serialize_ext(buf, &aggnonce[i]); |
584 | 0 | secp256k1_sha256_write(&sha, buf, sizeof(buf)); |
585 | 0 | } |
586 | 0 | secp256k1_sha256_write(&sha, agg_pk32, 32); |
587 | 0 | secp256k1_sha256_write(&sha, msg, 32); |
588 | 0 | secp256k1_sha256_finalize(&sha, noncehash); |
589 | 0 | } |
590 | | |
591 | | /* out_nonce = nonce_pts[0] + b*nonce_pts[1] */ |
592 | 0 | static void secp256k1_effective_nonce(secp256k1_gej *out_nonce, const secp256k1_ge *nonce_pts, const secp256k1_scalar *b) { |
593 | 0 | secp256k1_gej tmp; |
594 | |
|
595 | 0 | secp256k1_gej_set_ge(&tmp, &nonce_pts[1]); |
596 | 0 | secp256k1_ecmult(out_nonce, &tmp, b, NULL); |
597 | 0 | secp256k1_gej_add_ge_var(out_nonce, out_nonce, &nonce_pts[0], NULL); |
598 | 0 | } |
599 | | |
600 | 0 | static void secp256k1_musig_nonce_process_internal(int *fin_nonce_parity, unsigned char *fin_nonce, secp256k1_scalar *b, secp256k1_ge *aggnonce_pts, const unsigned char *agg_pk32, const unsigned char *msg) { |
601 | 0 | unsigned char noncehash[32]; |
602 | 0 | secp256k1_ge fin_nonce_pt; |
603 | 0 | secp256k1_gej fin_nonce_ptj; |
604 | |
|
605 | 0 | secp256k1_musig_compute_noncehash(noncehash, aggnonce_pts, agg_pk32, msg); |
606 | 0 | secp256k1_scalar_set_b32(b, noncehash, NULL); |
607 | | /* fin_nonce = aggnonce_pts[0] + b*aggnonce_pts[1] */ |
608 | 0 | secp256k1_effective_nonce(&fin_nonce_ptj, aggnonce_pts, b); |
609 | 0 | secp256k1_ge_set_gej(&fin_nonce_pt, &fin_nonce_ptj); |
610 | 0 | if (secp256k1_ge_is_infinity(&fin_nonce_pt)) { |
611 | 0 | fin_nonce_pt = secp256k1_ge_const_g; |
612 | 0 | } |
613 | | /* fin_nonce_pt is not the point at infinity */ |
614 | 0 | secp256k1_fe_normalize_var(&fin_nonce_pt.x); |
615 | 0 | secp256k1_fe_get_b32(fin_nonce, &fin_nonce_pt.x); |
616 | 0 | secp256k1_fe_normalize_var(&fin_nonce_pt.y); |
617 | 0 | *fin_nonce_parity = secp256k1_fe_is_odd(&fin_nonce_pt.y); |
618 | 0 | } |
619 | | |
620 | 0 | int secp256k1_musig_nonce_process(const secp256k1_context* ctx, secp256k1_musig_session *session, const secp256k1_musig_aggnonce *aggnonce, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache) { |
621 | 0 | secp256k1_keyagg_cache_internal cache_i; |
622 | 0 | secp256k1_ge aggnonce_pts[2]; |
623 | 0 | unsigned char fin_nonce[32]; |
624 | 0 | secp256k1_musig_session_internal session_i; |
625 | 0 | unsigned char agg_pk32[32]; |
626 | |
|
627 | 0 | VERIFY_CHECK(ctx != NULL); |
628 | 0 | ARG_CHECK(session != NULL); |
629 | 0 | ARG_CHECK(aggnonce != NULL); |
630 | 0 | ARG_CHECK(msg32 != NULL); |
631 | 0 | ARG_CHECK(keyagg_cache != NULL); |
632 | | |
633 | 0 | if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) { |
634 | 0 | return 0; |
635 | 0 | } |
636 | 0 | secp256k1_fe_get_b32(agg_pk32, &cache_i.pk.x); |
637 | |
|
638 | 0 | if (!secp256k1_musig_aggnonce_load(ctx, aggnonce_pts, aggnonce)) { |
639 | 0 | return 0; |
640 | 0 | } |
641 | | |
642 | 0 | secp256k1_musig_nonce_process_internal(&session_i.fin_nonce_parity, fin_nonce, &session_i.noncecoef, aggnonce_pts, agg_pk32, msg32); |
643 | 0 | secp256k1_schnorrsig_challenge(&session_i.challenge, fin_nonce, msg32, 32, agg_pk32); |
644 | | |
645 | | /* If there is a tweak then set `challenge` times `tweak` to the `s`-part.*/ |
646 | 0 | secp256k1_scalar_set_int(&session_i.s_part, 0); |
647 | 0 | if (!secp256k1_scalar_is_zero(&cache_i.tweak)) { |
648 | 0 | secp256k1_scalar e_tmp; |
649 | 0 | secp256k1_scalar_mul(&e_tmp, &session_i.challenge, &cache_i.tweak); |
650 | 0 | if (secp256k1_fe_is_odd(&cache_i.pk.y)) { |
651 | 0 | secp256k1_scalar_negate(&e_tmp, &e_tmp); |
652 | 0 | } |
653 | 0 | session_i.s_part = e_tmp; |
654 | 0 | } |
655 | 0 | memcpy(session_i.fin_nonce, fin_nonce, sizeof(session_i.fin_nonce)); |
656 | 0 | secp256k1_musig_session_save(session, &session_i); |
657 | 0 | return 1; |
658 | 0 | } |
659 | | |
660 | 0 | static void secp256k1_musig_partial_sign_clear(secp256k1_scalar *sk, secp256k1_scalar *k) { |
661 | 0 | secp256k1_scalar_clear(sk); |
662 | 0 | secp256k1_scalar_clear(&k[0]); |
663 | 0 | secp256k1_scalar_clear(&k[1]); |
664 | 0 | } |
665 | | |
666 | 0 | int secp256k1_musig_partial_sign(const secp256k1_context* ctx, secp256k1_musig_partial_sig *partial_sig, secp256k1_musig_secnonce *secnonce, const secp256k1_keypair *keypair, const secp256k1_musig_keyagg_cache *keyagg_cache, const secp256k1_musig_session *session) { |
667 | 0 | secp256k1_scalar sk; |
668 | 0 | secp256k1_ge pk, keypair_pk; |
669 | 0 | secp256k1_scalar k[2]; |
670 | 0 | secp256k1_scalar mu, s; |
671 | 0 | secp256k1_keyagg_cache_internal cache_i; |
672 | 0 | secp256k1_musig_session_internal session_i; |
673 | 0 | int ret; |
674 | |
|
675 | 0 | VERIFY_CHECK(ctx != NULL); |
676 | |
|
677 | 0 | ARG_CHECK(secnonce != NULL); |
678 | | /* Fails if the magic doesn't match */ |
679 | 0 | ret = secp256k1_musig_secnonce_load(ctx, k, &pk, secnonce); |
680 | | /* Set nonce to zero to avoid nonce reuse. This will cause subsequent calls |
681 | | * of this function to fail */ |
682 | 0 | memset(secnonce, 0, sizeof(*secnonce)); |
683 | 0 | if (!ret) { |
684 | 0 | secp256k1_musig_partial_sign_clear(&sk, k); |
685 | 0 | return 0; |
686 | 0 | } |
687 | | |
688 | 0 | ARG_CHECK(partial_sig != NULL); |
689 | 0 | ARG_CHECK(keypair != NULL); |
690 | 0 | ARG_CHECK(keyagg_cache != NULL); |
691 | 0 | ARG_CHECK(session != NULL); |
692 | | |
693 | 0 | if (!secp256k1_keypair_load(ctx, &sk, &keypair_pk, keypair)) { |
694 | 0 | secp256k1_musig_partial_sign_clear(&sk, k); |
695 | 0 | return 0; |
696 | 0 | } |
697 | 0 | ARG_CHECK(secp256k1_fe_equal(&pk.x, &keypair_pk.x) |
698 | 0 | && secp256k1_fe_equal(&pk.y, &keypair_pk.y)); |
699 | 0 | if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) { |
700 | 0 | secp256k1_musig_partial_sign_clear(&sk, k); |
701 | 0 | return 0; |
702 | 0 | } |
703 | | |
704 | | /* Negate sk if secp256k1_fe_is_odd(&cache_i.pk.y)) XOR cache_i.parity_acc. |
705 | | * This corresponds to the line "Let d = g⋅gacc⋅d' mod n" in the |
706 | | * specification. */ |
707 | 0 | if ((secp256k1_fe_is_odd(&cache_i.pk.y) |
708 | 0 | != cache_i.parity_acc)) { |
709 | 0 | secp256k1_scalar_negate(&sk, &sk); |
710 | 0 | } |
711 | | |
712 | | /* Multiply KeyAgg coefficient */ |
713 | 0 | secp256k1_musig_keyaggcoef(&mu, &cache_i, &pk); |
714 | 0 | secp256k1_scalar_mul(&sk, &sk, &mu); |
715 | |
|
716 | 0 | if (!secp256k1_musig_session_load(ctx, &session_i, session)) { |
717 | 0 | secp256k1_musig_partial_sign_clear(&sk, k); |
718 | 0 | return 0; |
719 | 0 | } |
720 | | |
721 | 0 | if (session_i.fin_nonce_parity) { |
722 | 0 | secp256k1_scalar_negate(&k[0], &k[0]); |
723 | 0 | secp256k1_scalar_negate(&k[1], &k[1]); |
724 | 0 | } |
725 | | |
726 | | /* Sign */ |
727 | 0 | secp256k1_scalar_mul(&s, &session_i.challenge, &sk); |
728 | 0 | secp256k1_scalar_mul(&k[1], &session_i.noncecoef, &k[1]); |
729 | 0 | secp256k1_scalar_add(&k[0], &k[0], &k[1]); |
730 | 0 | secp256k1_scalar_add(&s, &s, &k[0]); |
731 | 0 | secp256k1_musig_partial_sig_save(partial_sig, &s); |
732 | 0 | secp256k1_musig_partial_sign_clear(&sk, k); |
733 | 0 | return 1; |
734 | 0 | } |
735 | | |
736 | 0 | int secp256k1_musig_partial_sig_verify(const secp256k1_context* ctx, const secp256k1_musig_partial_sig *partial_sig, const secp256k1_musig_pubnonce *pubnonce, const secp256k1_pubkey *pubkey, const secp256k1_musig_keyagg_cache *keyagg_cache, const secp256k1_musig_session *session) { |
737 | 0 | secp256k1_keyagg_cache_internal cache_i; |
738 | 0 | secp256k1_musig_session_internal session_i; |
739 | 0 | secp256k1_scalar mu, e, s; |
740 | 0 | secp256k1_gej pkj; |
741 | 0 | secp256k1_ge nonce_pts[2]; |
742 | 0 | secp256k1_gej rj; |
743 | 0 | secp256k1_gej tmp; |
744 | 0 | secp256k1_ge pkp; |
745 | |
|
746 | 0 | VERIFY_CHECK(ctx != NULL); |
747 | 0 | ARG_CHECK(partial_sig != NULL); |
748 | 0 | ARG_CHECK(pubnonce != NULL); |
749 | 0 | ARG_CHECK(pubkey != NULL); |
750 | 0 | ARG_CHECK(keyagg_cache != NULL); |
751 | 0 | ARG_CHECK(session != NULL); |
752 | | |
753 | 0 | if (!secp256k1_musig_session_load(ctx, &session_i, session)) { |
754 | 0 | return 0; |
755 | 0 | } |
756 | | |
757 | 0 | if (!secp256k1_musig_pubnonce_load(ctx, nonce_pts, pubnonce)) { |
758 | 0 | return 0; |
759 | 0 | } |
760 | | /* Compute "effective" nonce rj = nonce_pts[0] + b*nonce_pts[1] */ |
761 | | /* TODO: use multiexp to compute -s*G + e*mu*pubkey + nonce_pts[0] + b*nonce_pts[1] */ |
762 | 0 | secp256k1_effective_nonce(&rj, nonce_pts, &session_i.noncecoef); |
763 | |
|
764 | 0 | if (!secp256k1_pubkey_load(ctx, &pkp, pubkey)) { |
765 | 0 | return 0; |
766 | 0 | } |
767 | 0 | if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) { |
768 | 0 | return 0; |
769 | 0 | } |
770 | | /* Multiplying the challenge by the KeyAgg coefficient is equivalent |
771 | | * to multiplying the signer's public key by the coefficient, except |
772 | | * much easier to do. */ |
773 | 0 | secp256k1_musig_keyaggcoef(&mu, &cache_i, &pkp); |
774 | 0 | secp256k1_scalar_mul(&e, &session_i.challenge, &mu); |
775 | | |
776 | | /* Negate e if secp256k1_fe_is_odd(&cache_i.pk.y)) XOR cache_i.parity_acc. |
777 | | * This corresponds to the line "Let g' = g⋅gacc mod n" and the multiplication "g'⋅e" |
778 | | * in the specification. */ |
779 | 0 | if (secp256k1_fe_is_odd(&cache_i.pk.y) |
780 | 0 | != cache_i.parity_acc) { |
781 | 0 | secp256k1_scalar_negate(&e, &e); |
782 | 0 | } |
783 | |
|
784 | 0 | if (!secp256k1_musig_partial_sig_load(ctx, &s, partial_sig)) { |
785 | 0 | return 0; |
786 | 0 | } |
787 | | /* Compute -s*G + e*pkj + rj (e already includes the keyagg coefficient mu) */ |
788 | 0 | secp256k1_scalar_negate(&s, &s); |
789 | 0 | secp256k1_gej_set_ge(&pkj, &pkp); |
790 | 0 | secp256k1_ecmult(&tmp, &pkj, &e, &s); |
791 | 0 | if (session_i.fin_nonce_parity) { |
792 | 0 | secp256k1_gej_neg(&rj, &rj); |
793 | 0 | } |
794 | 0 | secp256k1_gej_add_var(&tmp, &tmp, &rj, NULL); |
795 | |
|
796 | 0 | return secp256k1_gej_is_infinity(&tmp); |
797 | 0 | } |
798 | | |
799 | 0 | int secp256k1_musig_partial_sig_agg(const secp256k1_context* ctx, unsigned char *sig64, const secp256k1_musig_session *session, const secp256k1_musig_partial_sig * const* partial_sigs, size_t n_sigs) { |
800 | 0 | size_t i; |
801 | 0 | secp256k1_musig_session_internal session_i; |
802 | |
|
803 | 0 | VERIFY_CHECK(ctx != NULL); |
804 | 0 | ARG_CHECK(sig64 != NULL); |
805 | 0 | ARG_CHECK(session != NULL); |
806 | 0 | ARG_CHECK(partial_sigs != NULL); |
807 | 0 | ARG_CHECK(n_sigs > 0); |
808 | | |
809 | 0 | if (!secp256k1_musig_session_load(ctx, &session_i, session)) { |
810 | 0 | return 0; |
811 | 0 | } |
812 | 0 | for (i = 0; i < n_sigs; i++) { |
813 | 0 | secp256k1_scalar term; |
814 | 0 | if (!secp256k1_musig_partial_sig_load(ctx, &term, partial_sigs[i])) { |
815 | 0 | return 0; |
816 | 0 | } |
817 | 0 | secp256k1_scalar_add(&session_i.s_part, &session_i.s_part, &term); |
818 | 0 | } |
819 | 0 | secp256k1_scalar_get_b32(&sig64[32], &session_i.s_part); |
820 | 0 | memcpy(&sig64[0], session_i.fin_nonce, 32); |
821 | 0 | return 1; |
822 | 0 | } |
823 | | |
824 | | #endif |