1 /*************************************************************************
2 * To the extent possible under law, the author(s) have dedicated all *
3 * copyright and related and neighboring rights to the software in this *
4 * file to the public domain worldwide. This software is distributed *
5 * without any warranty. For the CC0 Public Domain Dedication, see *
6 * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
7 *************************************************************************/
8 9 /** This file demonstrates how to use the MuSig module to create a
10 * 3-of-3 multisignature. Additionally, see the documentation in
11 * include/secp256k1_musig.h and doc/musig.md.
12 */
13 14 #include <stdio.h>
15 #include <assert.h>
16 #include <string.h>
17 18 #include <secp256k1.h>
19 #include <secp256k1_extrakeys.h>
20 #include <secp256k1_musig.h>
21 #include <secp256k1_schnorrsig.h>
22 23 #include "examples_util.h"
24 25 struct signer_secrets {
26 secp256k1_keypair keypair;
27 secp256k1_musig_secnonce secnonce;
28 };
29 30 struct signer {
31 secp256k1_pubkey pubkey;
32 secp256k1_musig_pubnonce pubnonce;
33 secp256k1_musig_partial_sig partial_sig;
34 };
35 36 /* Number of public keys involved in creating the aggregate signature */
37 #define N_SIGNERS 3
38 /* Create a key pair, store it in signer_secrets->keypair and signer->pubkey */
39 static int create_keypair(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer) {
40 unsigned char seckey[32];
41 42 if (!fill_random(seckey, sizeof(seckey))) {
43 printf("Failed to generate randomness\n");
44 return 0;
45 }
46 /* Try to create a keypair with a valid context. This only fails if the
47 * secret key is zero or out of range (greater than secp256k1's order). Note
48 * that the probability of this occurring is negligible with a properly
49 * functioning random number generator. */
50 if (!secp256k1_keypair_create(ctx, &signer_secrets->keypair, seckey)) {
51 return 0;
52 }
53 if (!secp256k1_keypair_pub(ctx, &signer->pubkey, &signer_secrets->keypair)) {
54 return 0;
55 }
56 57 secure_erase(seckey, sizeof(seckey));
58 return 1;
59 }
60 61 /* Tweak the pubkey corresponding to the provided keyagg cache, update the cache
62 * and return the tweaked aggregate pk. */
63 static int tweak(const secp256k1_context* ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *cache) {
64 secp256k1_pubkey output_pk;
65 /* For BIP 32 tweaking the plain_tweak is set to a hash as defined in BIP
66 * 32. */
67 unsigned char plain_tweak[32] = "this could be a BIP32 tweak....";
68 /* For Taproot tweaking the xonly_tweak is set to the TapTweak hash as
69 * defined in BIP 341 */
70 unsigned char xonly_tweak[32] = "this could be a Taproot tweak..";
71 72 73 /* Plain tweaking which, for example, allows deriving multiple child
74 * public keys from a single aggregate key using BIP32 */
75 if (!secp256k1_musig_pubkey_ec_tweak_add(ctx, NULL, cache, plain_tweak)) {
76 return 0;
77 }
78 /* Note that we did not provide an output_pk argument, because the
79 * resulting pk is also saved in the cache and so if one is just interested
80 * in signing, the output_pk argument is unnecessary. On the other hand, if
81 * one is not interested in signing, the same output_pk can be obtained by
82 * calling `secp256k1_musig_pubkey_get` right after key aggregation to get
83 * the full pubkey and then call `secp256k1_ec_pubkey_tweak_add`. */
84 85 /* Xonly tweaking which, for example, allows creating Taproot commitments */
86 if (!secp256k1_musig_pubkey_xonly_tweak_add(ctx, &output_pk, cache, xonly_tweak)) {
87 return 0;
88 }
89 /* Note that if we wouldn't care about signing, we can arrive at the same
90 * output_pk by providing the untweaked public key to
91 * `secp256k1_xonly_pubkey_tweak_add` (after converting it to an xonly pubkey
92 * if necessary with `secp256k1_xonly_pubkey_from_pubkey`). */
93 94 /* Now we convert the output_pk to an xonly pubkey to allow to later verify
95 * the Schnorr signature against it. For this purpose we can ignore the
96 * `pk_parity` output argument; we would need it if we would have to open
97 * the Taproot commitment. */
98 if (!secp256k1_xonly_pubkey_from_pubkey(ctx, agg_pk, NULL, &output_pk)) {
99 return 0;
100 }
101 return 1;
102 }
103 104 /* Sign a message hash with the given key pairs and store the result in sig */
105 static int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer, const secp256k1_musig_keyagg_cache *cache, const unsigned char *msg32, unsigned char *sig64) {
106 int i;
107 const secp256k1_musig_pubnonce *pubnonces[N_SIGNERS];
108 const secp256k1_musig_partial_sig *partial_sigs[N_SIGNERS];
109 /* The same for all signers */
110 secp256k1_musig_session session;
111 secp256k1_musig_aggnonce agg_pubnonce;
112 113 for (i = 0; i < N_SIGNERS; i++) {
114 unsigned char seckey[32];
115 unsigned char session_secrand[32];
116 /* Create random session ID. It is absolutely necessary that the session ID
117 * is unique for every call of secp256k1_musig_nonce_gen. Otherwise
118 * it's trivial for an attacker to extract the secret key! */
119 if (!fill_random(session_secrand, sizeof(session_secrand))) {
120 return 0;
121 }
122 if (!secp256k1_keypair_sec(ctx, seckey, &signer_secrets[i].keypair)) {
123 return 0;
124 }
125 /* Initialize session and create secret nonce for signing and public
126 * nonce to send to the other signers. */
127 if (!secp256k1_musig_nonce_gen(ctx, &signer_secrets[i].secnonce, &signer[i].pubnonce, session_secrand, seckey, &signer[i].pubkey, msg32, NULL, NULL)) {
128 return 0;
129 }
130 pubnonces[i] = &signer[i].pubnonce;
131 132 secure_erase(seckey, sizeof(seckey));
133 }
134 135 /* Communication round 1: Every signer sends their pubnonce to the
136 * coordinator. The coordinator runs secp256k1_musig_nonce_agg and sends
137 * agg_pubnonce to each signer */
138 if (!secp256k1_musig_nonce_agg(ctx, &agg_pubnonce, pubnonces, N_SIGNERS)) {
139 return 0;
140 }
141 142 /* Every signer creates a partial signature */
143 for (i = 0; i < N_SIGNERS; i++) {
144 /* Initialize the signing session by processing the aggregate nonce */
145 if (!secp256k1_musig_nonce_process(ctx, &session, &agg_pubnonce, msg32, cache)) {
146 return 0;
147 }
148 /* partial_sign will clear the secnonce by setting it to 0. That's because
149 * you must _never_ reuse the secnonce (or use the same session_secrand to
150 * create a secnonce). If you do, you effectively reuse the nonce and
151 * leak the secret key. */
152 if (!secp256k1_musig_partial_sign(ctx, &signer[i].partial_sig, &signer_secrets[i].secnonce, &signer_secrets[i].keypair, cache, &session)) {
153 return 0;
154 }
155 partial_sigs[i] = &signer[i].partial_sig;
156 }
157 /* Communication round 2: Every signer sends their partial signature to the
158 * coordinator, who verifies the partial signatures and aggregates them. */
159 for (i = 0; i < N_SIGNERS; i++) {
160 /* To check whether signing was successful, it suffices to either verify
161 * the aggregate signature with the aggregate public key using
162 * secp256k1_schnorrsig_verify, or verify all partial signatures of all
163 * signers individually. Verifying the aggregate signature is cheaper but
164 * verifying the individual partial signatures has the advantage that it
165 * can be used to determine which of the partial signatures are invalid
166 * (if any), i.e., which of the partial signatures cause the aggregate
167 * signature to be invalid and thus the protocol run to fail. It's also
168 * fine to first verify the aggregate sig, and only verify the individual
169 * sigs if it does not work.
170 */
171 if (!secp256k1_musig_partial_sig_verify(ctx, &signer[i].partial_sig, &signer[i].pubnonce, &signer[i].pubkey, cache, &session)) {
172 return 0;
173 }
174 }
175 return secp256k1_musig_partial_sig_agg(ctx, sig64, &session, partial_sigs, N_SIGNERS);
176 }
177 178 int main(void) {
179 secp256k1_context* ctx;
180 int i;
181 struct signer_secrets signer_secrets[N_SIGNERS];
182 struct signer signers[N_SIGNERS];
183 const secp256k1_pubkey *pubkeys_ptr[N_SIGNERS];
184 secp256k1_xonly_pubkey agg_pk;
185 secp256k1_musig_keyagg_cache cache;
186 unsigned char msg[32] = "this_could_be_the_hash_of_a_msg";
187 unsigned char sig[64];
188 189 /* Create a secp256k1 context */
190 ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
191 printf("Creating key pairs......");
192 fflush(stdout);
193 for (i = 0; i < N_SIGNERS; i++) {
194 if (!create_keypair(ctx, &signer_secrets[i], &signers[i])) {
195 printf("FAILED\n");
196 return 1;
197 }
198 pubkeys_ptr[i] = &signers[i].pubkey;
199 }
200 printf("ok\n");
201 202 /* The aggregate public key produced by secp256k1_musig_pubkey_agg depends
203 * on the order of the provided public keys. If there is no canonical order
204 * of the signers, the individual public keys can optionally be sorted with
205 * secp256k1_ec_pubkey_sort to ensure that the aggregate public key is
206 * independent of the order of signers. */
207 printf("Sorting public keys.....");
208 fflush(stdout);
209 if (!secp256k1_ec_pubkey_sort(ctx, pubkeys_ptr, N_SIGNERS)) {
210 printf("FAILED\n");
211 return 1;
212 }
213 printf("ok\n");
214 215 printf("Combining public keys...");
216 fflush(stdout);
217 /* If you just want to aggregate and not sign, you can call
218 * secp256k1_musig_pubkey_agg with the keyagg_cache argument set to NULL
219 * while providing a non-NULL agg_pk argument. */
220 if (!secp256k1_musig_pubkey_agg(ctx, NULL, &cache, pubkeys_ptr, N_SIGNERS)) {
221 printf("FAILED\n");
222 return 1;
223 }
224 printf("ok\n");
225 printf("Tweaking................");
226 fflush(stdout);
227 /* Optionally tweak the aggregate key */
228 if (!tweak(ctx, &agg_pk, &cache)) {
229 printf("FAILED\n");
230 return 1;
231 }
232 printf("ok\n");
233 printf("Signing message.........");
234 fflush(stdout);
235 if (!sign(ctx, signer_secrets, signers, &cache, msg, sig)) {
236 printf("FAILED\n");
237 return 1;
238 }
239 printf("ok\n");
240 printf("Verifying signature.....");
241 fflush(stdout);
242 if (!secp256k1_schnorrsig_verify(ctx, sig, msg, 32, &agg_pk)) {
243 printf("FAILED\n");
244 return 1;
245 }
246 printf("ok\n");
247 248 /* It's best practice to try to clear secrets from memory after using them.
249 * This is done because some bugs can allow an attacker to leak memory, for
250 * example through "out of bounds" array access (see Heartbleed), or the OS
251 * swapping them to disk. Hence, we overwrite secret key material with zeros.
252 *
253 * Here we are preventing these writes from being optimized out, as any good compiler
254 * will remove any writes that aren't used. */
255 for (i = 0; i < N_SIGNERS; i++) {
256 secure_erase(&signer_secrets[i], sizeof(signer_secrets[i]));
257 }
258 secp256k1_context_destroy(ctx);
259 return 0;
260 }
261