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