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