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