github.com/ethereum/go-ethereum@v1.16.1/crypto/secp256k1/libsecp256k1/src/modules/schnorrsig/main_impl.h (about)

     1  /***********************************************************************
     2   * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick                 *
     3   * Distributed under the MIT software license, see the accompanying    *
     4   * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
     5   ***********************************************************************/
     6  
     7  #ifndef SECP256K1_MODULE_SCHNORRSIG_MAIN_H
     8  #define SECP256K1_MODULE_SCHNORRSIG_MAIN_H
     9  
    10  #include "../../../include/secp256k1.h"
    11  #include "../../../include/secp256k1_schnorrsig.h"
    12  #include "../../hash.h"
    13  
    14  /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
    15   * SHA256 to SHA256("BIP0340/nonce")||SHA256("BIP0340/nonce"). */
    16  static void secp256k1_nonce_function_bip340_sha256_tagged(secp256k1_sha256 *sha) {
    17      secp256k1_sha256_initialize(sha);
    18      sha->s[0] = 0x46615b35ul;
    19      sha->s[1] = 0xf4bfbff7ul;
    20      sha->s[2] = 0x9f8dc671ul;
    21      sha->s[3] = 0x83627ab3ul;
    22      sha->s[4] = 0x60217180ul;
    23      sha->s[5] = 0x57358661ul;
    24      sha->s[6] = 0x21a29e54ul;
    25      sha->s[7] = 0x68b07b4cul;
    26  
    27      sha->bytes = 64;
    28  }
    29  
    30  /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
    31   * SHA256 to SHA256("BIP0340/aux")||SHA256("BIP0340/aux"). */
    32  static void secp256k1_nonce_function_bip340_sha256_tagged_aux(secp256k1_sha256 *sha) {
    33      secp256k1_sha256_initialize(sha);
    34      sha->s[0] = 0x24dd3219ul;
    35      sha->s[1] = 0x4eba7e70ul;
    36      sha->s[2] = 0xca0fabb9ul;
    37      sha->s[3] = 0x0fa3166dul;
    38      sha->s[4] = 0x3afbe4b1ul;
    39      sha->s[5] = 0x4c44df97ul;
    40      sha->s[6] = 0x4aac2739ul;
    41      sha->s[7] = 0x249e850aul;
    42  
    43      sha->bytes = 64;
    44  }
    45  
    46  /* algo argument for nonce_function_bip340 to derive the nonce exactly as stated in BIP-340
    47   * by using the correct tagged hash function. */
    48  static const unsigned char bip340_algo[] = {'B', 'I', 'P', '0', '3', '4', '0', '/', 'n', 'o', 'n', 'c', 'e'};
    49  
    50  static const unsigned char schnorrsig_extraparams_magic[4] = SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC;
    51  
    52  static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) {
    53      secp256k1_sha256 sha;
    54      unsigned char masked_key[32];
    55      int i;
    56  
    57      if (algo == NULL) {
    58          return 0;
    59      }
    60  
    61      if (data != NULL) {
    62          secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha);
    63          secp256k1_sha256_write(&sha, data, 32);
    64          secp256k1_sha256_finalize(&sha, masked_key);
    65          for (i = 0; i < 32; i++) {
    66              masked_key[i] ^= key32[i];
    67          }
    68      } else {
    69          /* Precomputed TaggedHash("BIP0340/aux", 0x0000...00); */
    70          static const unsigned char ZERO_MASK[32] = {
    71                84, 241, 105, 207, 201, 226, 229, 114,
    72               116, 128,  68,  31, 144, 186,  37, 196,
    73               136, 244,  97, 199,  11,  94, 165, 220,
    74               170, 247, 175, 105, 39,  10, 165,  20
    75          };
    76          for (i = 0; i < 32; i++) {
    77              masked_key[i] = key32[i] ^ ZERO_MASK[i];
    78          }
    79      }
    80  
    81      /* Tag the hash with algo which is important to avoid nonce reuse across
    82       * algorithms. If this nonce function is used in BIP-340 signing as defined
    83       * in the spec, an optimized tagging implementation is used. */
    84      if (algolen == sizeof(bip340_algo)
    85              && secp256k1_memcmp_var(algo, bip340_algo, algolen) == 0) {
    86          secp256k1_nonce_function_bip340_sha256_tagged(&sha);
    87      } else {
    88          secp256k1_sha256_initialize_tagged(&sha, algo, algolen);
    89      }
    90  
    91      /* Hash masked-key||pk||msg using the tagged hash as per the spec */
    92      secp256k1_sha256_write(&sha, masked_key, 32);
    93      secp256k1_sha256_write(&sha, xonly_pk32, 32);
    94      secp256k1_sha256_write(&sha, msg, msglen);
    95      secp256k1_sha256_finalize(&sha, nonce32);
    96      secp256k1_sha256_clear(&sha);
    97      secp256k1_memclear(masked_key, sizeof(masked_key));
    98  
    99      return 1;
   100  }
   101  
   102  const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340 = nonce_function_bip340;
   103  
   104  /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
   105   * SHA256 to SHA256("BIP0340/challenge")||SHA256("BIP0340/challenge"). */
   106  static void secp256k1_schnorrsig_sha256_tagged(secp256k1_sha256 *sha) {
   107      secp256k1_sha256_initialize(sha);
   108      sha->s[0] = 0x9cecba11ul;
   109      sha->s[1] = 0x23925381ul;
   110      sha->s[2] = 0x11679112ul;
   111      sha->s[3] = 0xd1627e0ful;
   112      sha->s[4] = 0x97c87550ul;
   113      sha->s[5] = 0x003cc765ul;
   114      sha->s[6] = 0x90f61164ul;
   115      sha->s[7] = 0x33e9b66aul;
   116      sha->bytes = 64;
   117  }
   118  
   119  static void secp256k1_schnorrsig_challenge(secp256k1_scalar* e, const unsigned char *r32, const unsigned char *msg, size_t msglen, const unsigned char *pubkey32)
   120  {
   121      unsigned char buf[32];
   122      secp256k1_sha256 sha;
   123  
   124      /* tagged hash(r.x, pk.x, msg) */
   125      secp256k1_schnorrsig_sha256_tagged(&sha);
   126      secp256k1_sha256_write(&sha, r32, 32);
   127      secp256k1_sha256_write(&sha, pubkey32, 32);
   128      secp256k1_sha256_write(&sha, msg, msglen);
   129      secp256k1_sha256_finalize(&sha, buf);
   130      /* Set scalar e to the challenge hash modulo the curve order as per
   131       * BIP340. */
   132      secp256k1_scalar_set_b32(e, buf, NULL);
   133  }
   134  
   135  static int secp256k1_schnorrsig_sign_internal(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_nonce_function_hardened noncefp, void *ndata) {
   136      secp256k1_scalar sk;
   137      secp256k1_scalar e;
   138      secp256k1_scalar k;
   139      secp256k1_gej rj;
   140      secp256k1_ge pk;
   141      secp256k1_ge r;
   142      unsigned char buf[32] = { 0 };
   143      unsigned char pk_buf[32];
   144      unsigned char seckey[32];
   145      int ret = 1;
   146  
   147      VERIFY_CHECK(ctx != NULL);
   148      ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
   149      ARG_CHECK(sig64 != NULL);
   150      ARG_CHECK(msg != NULL || msglen == 0);
   151      ARG_CHECK(keypair != NULL);
   152  
   153      if (noncefp == NULL) {
   154          noncefp = secp256k1_nonce_function_bip340;
   155      }
   156  
   157      ret &= secp256k1_keypair_load(ctx, &sk, &pk, keypair);
   158      /* Because we are signing for a x-only pubkey, the secret key is negated
   159       * before signing if the point corresponding to the secret key does not
   160       * have an even Y. */
   161      if (secp256k1_fe_is_odd(&pk.y)) {
   162          secp256k1_scalar_negate(&sk, &sk);
   163      }
   164  
   165      secp256k1_scalar_get_b32(seckey, &sk);
   166      secp256k1_fe_get_b32(pk_buf, &pk.x);
   167      ret &= !!noncefp(buf, msg, msglen, seckey, pk_buf, bip340_algo, sizeof(bip340_algo), ndata);
   168      secp256k1_scalar_set_b32(&k, buf, NULL);
   169      ret &= !secp256k1_scalar_is_zero(&k);
   170      secp256k1_scalar_cmov(&k, &secp256k1_scalar_one, !ret);
   171  
   172      secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rj, &k);
   173      secp256k1_ge_set_gej(&r, &rj);
   174  
   175      /* We declassify r to allow using it as a branch point. This is fine
   176       * because r is not a secret. */
   177      secp256k1_declassify(ctx, &r, sizeof(r));
   178      secp256k1_fe_normalize_var(&r.y);
   179      if (secp256k1_fe_is_odd(&r.y)) {
   180          secp256k1_scalar_negate(&k, &k);
   181      }
   182      secp256k1_fe_normalize_var(&r.x);
   183      secp256k1_fe_get_b32(&sig64[0], &r.x);
   184  
   185      secp256k1_schnorrsig_challenge(&e, &sig64[0], msg, msglen, pk_buf);
   186      secp256k1_scalar_mul(&e, &e, &sk);
   187      secp256k1_scalar_add(&e, &e, &k);
   188      secp256k1_scalar_get_b32(&sig64[32], &e);
   189  
   190      secp256k1_memczero(sig64, 64, !ret);
   191      secp256k1_scalar_clear(&k);
   192      secp256k1_scalar_clear(&sk);
   193      secp256k1_memclear(seckey, sizeof(seckey));
   194      secp256k1_gej_clear(&rj);
   195  
   196      return ret;
   197  }
   198  
   199  int secp256k1_schnorrsig_sign32(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) {
   200      /* We cast away const from the passed aux_rand32 argument since we know the default nonce function does not modify it. */
   201      return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg32, 32, keypair, secp256k1_nonce_function_bip340, (unsigned char*)aux_rand32);
   202  }
   203  
   204  int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) {
   205      return secp256k1_schnorrsig_sign32(ctx, sig64, msg32, keypair, aux_rand32);
   206  }
   207  
   208  int secp256k1_schnorrsig_sign_custom(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_schnorrsig_extraparams *extraparams) {
   209      secp256k1_nonce_function_hardened noncefp = NULL;
   210      void *ndata = NULL;
   211      VERIFY_CHECK(ctx != NULL);
   212  
   213      if (extraparams != NULL) {
   214          ARG_CHECK(secp256k1_memcmp_var(extraparams->magic,
   215                                         schnorrsig_extraparams_magic,
   216                                         sizeof(extraparams->magic)) == 0);
   217          noncefp = extraparams->noncefp;
   218          ndata = extraparams->ndata;
   219      }
   220      return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg, msglen, keypair, noncefp, ndata);
   221  }
   222  
   223  int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_xonly_pubkey *pubkey) {
   224      secp256k1_scalar s;
   225      secp256k1_scalar e;
   226      secp256k1_gej rj;
   227      secp256k1_ge pk;
   228      secp256k1_gej pkj;
   229      secp256k1_fe rx;
   230      secp256k1_ge r;
   231      unsigned char buf[32];
   232      int overflow;
   233  
   234      VERIFY_CHECK(ctx != NULL);
   235      ARG_CHECK(sig64 != NULL);
   236      ARG_CHECK(msg != NULL || msglen == 0);
   237      ARG_CHECK(pubkey != NULL);
   238  
   239      if (!secp256k1_fe_set_b32_limit(&rx, &sig64[0])) {
   240          return 0;
   241      }
   242  
   243      secp256k1_scalar_set_b32(&s, &sig64[32], &overflow);
   244      if (overflow) {
   245          return 0;
   246      }
   247  
   248      if (!secp256k1_xonly_pubkey_load(ctx, &pk, pubkey)) {
   249          return 0;
   250      }
   251  
   252      /* Compute e. */
   253      secp256k1_fe_get_b32(buf, &pk.x);
   254      secp256k1_schnorrsig_challenge(&e, &sig64[0], msg, msglen, buf);
   255  
   256      /* Compute rj =  s*G + (-e)*pkj */
   257      secp256k1_scalar_negate(&e, &e);
   258      secp256k1_gej_set_ge(&pkj, &pk);
   259      secp256k1_ecmult(&rj, &pkj, &e, &s);
   260  
   261      secp256k1_ge_set_gej_var(&r, &rj);
   262      if (secp256k1_ge_is_infinity(&r)) {
   263          return 0;
   264      }
   265  
   266      secp256k1_fe_normalize_var(&r.y);
   267      return !secp256k1_fe_is_odd(&r.y) &&
   268             secp256k1_fe_equal(&rx, &r.x);
   269  }
   270  
   271  #endif