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  }