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