musig.c raw

   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