main_impl.h (11498B)
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 haskellsecp256k1_v0_1_0_nonce_function_bip340_sha256_tagged(haskellsecp256k1_v0_1_0_sha256 *sha) { 17 haskellsecp256k1_v0_1_0_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 haskellsecp256k1_v0_1_0_nonce_function_bip340_sha256_tagged_aux(haskellsecp256k1_v0_1_0_sha256 *sha) { 33 haskellsecp256k1_v0_1_0_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[13] = "BIP0340/nonce"; 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 haskellsecp256k1_v0_1_0_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 haskellsecp256k1_v0_1_0_nonce_function_bip340_sha256_tagged_aux(&sha); 63 haskellsecp256k1_v0_1_0_sha256_write(&sha, data, 32); 64 haskellsecp256k1_v0_1_0_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 && haskellsecp256k1_v0_1_0_memcmp_var(algo, bip340_algo, algolen) == 0) { 86 haskellsecp256k1_v0_1_0_nonce_function_bip340_sha256_tagged(&sha); 87 } else { 88 haskellsecp256k1_v0_1_0_sha256_initialize_tagged(&sha, algo, algolen); 89 } 90 91 /* Hash masked-key||pk||msg using the tagged hash as per the spec */ 92 haskellsecp256k1_v0_1_0_sha256_write(&sha, masked_key, 32); 93 haskellsecp256k1_v0_1_0_sha256_write(&sha, xonly_pk32, 32); 94 haskellsecp256k1_v0_1_0_sha256_write(&sha, msg, msglen); 95 haskellsecp256k1_v0_1_0_sha256_finalize(&sha, nonce32); 96 return 1; 97 } 98 99 const haskellsecp256k1_v0_1_0_nonce_function_hardened haskellsecp256k1_v0_1_0_nonce_function_bip340 = nonce_function_bip340; 100 101 /* Initializes SHA256 with fixed midstate. This midstate was computed by applying 102 * SHA256 to SHA256("BIP0340/challenge")||SHA256("BIP0340/challenge"). */ 103 static void haskellsecp256k1_v0_1_0_schnorrsig_sha256_tagged(haskellsecp256k1_v0_1_0_sha256 *sha) { 104 haskellsecp256k1_v0_1_0_sha256_initialize(sha); 105 sha->s[0] = 0x9cecba11ul; 106 sha->s[1] = 0x23925381ul; 107 sha->s[2] = 0x11679112ul; 108 sha->s[3] = 0xd1627e0ful; 109 sha->s[4] = 0x97c87550ul; 110 sha->s[5] = 0x003cc765ul; 111 sha->s[6] = 0x90f61164ul; 112 sha->s[7] = 0x33e9b66aul; 113 sha->bytes = 64; 114 } 115 116 static void haskellsecp256k1_v0_1_0_schnorrsig_challenge(haskellsecp256k1_v0_1_0_scalar* e, const unsigned char *r32, const unsigned char *msg, size_t msglen, const unsigned char *pubkey32) 117 { 118 unsigned char buf[32]; 119 haskellsecp256k1_v0_1_0_sha256 sha; 120 121 /* tagged hash(r.x, pk.x, msg) */ 122 haskellsecp256k1_v0_1_0_schnorrsig_sha256_tagged(&sha); 123 haskellsecp256k1_v0_1_0_sha256_write(&sha, r32, 32); 124 haskellsecp256k1_v0_1_0_sha256_write(&sha, pubkey32, 32); 125 haskellsecp256k1_v0_1_0_sha256_write(&sha, msg, msglen); 126 haskellsecp256k1_v0_1_0_sha256_finalize(&sha, buf); 127 /* Set scalar e to the challenge hash modulo the curve order as per 128 * BIP340. */ 129 haskellsecp256k1_v0_1_0_scalar_set_b32(e, buf, NULL); 130 } 131 132 static int haskellsecp256k1_v0_1_0_schnorrsig_sign_internal(const haskellsecp256k1_v0_1_0_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const haskellsecp256k1_v0_1_0_keypair *keypair, haskellsecp256k1_v0_1_0_nonce_function_hardened noncefp, void *ndata) { 133 haskellsecp256k1_v0_1_0_scalar sk; 134 haskellsecp256k1_v0_1_0_scalar e; 135 haskellsecp256k1_v0_1_0_scalar k; 136 haskellsecp256k1_v0_1_0_gej rj; 137 haskellsecp256k1_v0_1_0_ge pk; 138 haskellsecp256k1_v0_1_0_ge r; 139 unsigned char buf[32] = { 0 }; 140 unsigned char pk_buf[32]; 141 unsigned char seckey[32]; 142 int ret = 1; 143 144 VERIFY_CHECK(ctx != NULL); 145 ARG_CHECK(haskellsecp256k1_v0_1_0_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); 146 ARG_CHECK(sig64 != NULL); 147 ARG_CHECK(msg != NULL || msglen == 0); 148 ARG_CHECK(keypair != NULL); 149 150 if (noncefp == NULL) { 151 noncefp = haskellsecp256k1_v0_1_0_nonce_function_bip340; 152 } 153 154 ret &= haskellsecp256k1_v0_1_0_keypair_load(ctx, &sk, &pk, keypair); 155 /* Because we are signing for a x-only pubkey, the secret key is negated 156 * before signing if the point corresponding to the secret key does not 157 * have an even Y. */ 158 if (haskellsecp256k1_v0_1_0_fe_is_odd(&pk.y)) { 159 haskellsecp256k1_v0_1_0_scalar_negate(&sk, &sk); 160 } 161 162 haskellsecp256k1_v0_1_0_scalar_get_b32(seckey, &sk); 163 haskellsecp256k1_v0_1_0_fe_get_b32(pk_buf, &pk.x); 164 ret &= !!noncefp(buf, msg, msglen, seckey, pk_buf, bip340_algo, sizeof(bip340_algo), ndata); 165 haskellsecp256k1_v0_1_0_scalar_set_b32(&k, buf, NULL); 166 ret &= !haskellsecp256k1_v0_1_0_scalar_is_zero(&k); 167 haskellsecp256k1_v0_1_0_scalar_cmov(&k, &haskellsecp256k1_v0_1_0_scalar_one, !ret); 168 169 haskellsecp256k1_v0_1_0_ecmult_gen(&ctx->ecmult_gen_ctx, &rj, &k); 170 haskellsecp256k1_v0_1_0_ge_set_gej(&r, &rj); 171 172 /* We declassify r to allow using it as a branch point. This is fine 173 * because r is not a secret. */ 174 haskellsecp256k1_v0_1_0_declassify(ctx, &r, sizeof(r)); 175 haskellsecp256k1_v0_1_0_fe_normalize_var(&r.y); 176 if (haskellsecp256k1_v0_1_0_fe_is_odd(&r.y)) { 177 haskellsecp256k1_v0_1_0_scalar_negate(&k, &k); 178 } 179 haskellsecp256k1_v0_1_0_fe_normalize_var(&r.x); 180 haskellsecp256k1_v0_1_0_fe_get_b32(&sig64[0], &r.x); 181 182 haskellsecp256k1_v0_1_0_schnorrsig_challenge(&e, &sig64[0], msg, msglen, pk_buf); 183 haskellsecp256k1_v0_1_0_scalar_mul(&e, &e, &sk); 184 haskellsecp256k1_v0_1_0_scalar_add(&e, &e, &k); 185 haskellsecp256k1_v0_1_0_scalar_get_b32(&sig64[32], &e); 186 187 haskellsecp256k1_v0_1_0_memczero(sig64, 64, !ret); 188 haskellsecp256k1_v0_1_0_scalar_clear(&k); 189 haskellsecp256k1_v0_1_0_scalar_clear(&sk); 190 memset(seckey, 0, sizeof(seckey)); 191 192 return ret; 193 } 194 195 int haskellsecp256k1_v0_1_0_schnorrsig_sign32(const haskellsecp256k1_v0_1_0_context* ctx, unsigned char *sig64, const unsigned char *msg32, const haskellsecp256k1_v0_1_0_keypair *keypair, const unsigned char *aux_rand32) { 196 /* We cast away const from the passed aux_rand32 argument since we know the default nonce function does not modify it. */ 197 return haskellsecp256k1_v0_1_0_schnorrsig_sign_internal(ctx, sig64, msg32, 32, keypair, haskellsecp256k1_v0_1_0_nonce_function_bip340, (unsigned char*)aux_rand32); 198 } 199 200 int haskellsecp256k1_v0_1_0_schnorrsig_sign(const haskellsecp256k1_v0_1_0_context* ctx, unsigned char *sig64, const unsigned char *msg32, const haskellsecp256k1_v0_1_0_keypair *keypair, const unsigned char *aux_rand32) { 201 return haskellsecp256k1_v0_1_0_schnorrsig_sign32(ctx, sig64, msg32, keypair, aux_rand32); 202 } 203 204 int haskellsecp256k1_v0_1_0_schnorrsig_sign_custom(const haskellsecp256k1_v0_1_0_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const haskellsecp256k1_v0_1_0_keypair *keypair, haskellsecp256k1_v0_1_0_schnorrsig_extraparams *extraparams) { 205 haskellsecp256k1_v0_1_0_nonce_function_hardened noncefp = NULL; 206 void *ndata = NULL; 207 VERIFY_CHECK(ctx != NULL); 208 209 if (extraparams != NULL) { 210 ARG_CHECK(haskellsecp256k1_v0_1_0_memcmp_var(extraparams->magic, 211 schnorrsig_extraparams_magic, 212 sizeof(extraparams->magic)) == 0); 213 noncefp = extraparams->noncefp; 214 ndata = extraparams->ndata; 215 } 216 return haskellsecp256k1_v0_1_0_schnorrsig_sign_internal(ctx, sig64, msg, msglen, keypair, noncefp, ndata); 217 } 218 219 int haskellsecp256k1_v0_1_0_schnorrsig_verify(const haskellsecp256k1_v0_1_0_context* ctx, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const haskellsecp256k1_v0_1_0_xonly_pubkey *pubkey) { 220 haskellsecp256k1_v0_1_0_scalar s; 221 haskellsecp256k1_v0_1_0_scalar e; 222 haskellsecp256k1_v0_1_0_gej rj; 223 haskellsecp256k1_v0_1_0_ge pk; 224 haskellsecp256k1_v0_1_0_gej pkj; 225 haskellsecp256k1_v0_1_0_fe rx; 226 haskellsecp256k1_v0_1_0_ge r; 227 unsigned char buf[32]; 228 int overflow; 229 230 VERIFY_CHECK(ctx != NULL); 231 ARG_CHECK(sig64 != NULL); 232 ARG_CHECK(msg != NULL || msglen == 0); 233 ARG_CHECK(pubkey != NULL); 234 235 if (!haskellsecp256k1_v0_1_0_fe_set_b32_limit(&rx, &sig64[0])) { 236 return 0; 237 } 238 239 haskellsecp256k1_v0_1_0_scalar_set_b32(&s, &sig64[32], &overflow); 240 if (overflow) { 241 return 0; 242 } 243 244 if (!haskellsecp256k1_v0_1_0_xonly_pubkey_load(ctx, &pk, pubkey)) { 245 return 0; 246 } 247 248 /* Compute e. */ 249 haskellsecp256k1_v0_1_0_fe_get_b32(buf, &pk.x); 250 haskellsecp256k1_v0_1_0_schnorrsig_challenge(&e, &sig64[0], msg, msglen, buf); 251 252 /* Compute rj = s*G + (-e)*pkj */ 253 haskellsecp256k1_v0_1_0_scalar_negate(&e, &e); 254 haskellsecp256k1_v0_1_0_gej_set_ge(&pkj, &pk); 255 haskellsecp256k1_v0_1_0_ecmult(&rj, &pkj, &e, &s); 256 257 haskellsecp256k1_v0_1_0_ge_set_gej_var(&r, &rj); 258 if (haskellsecp256k1_v0_1_0_ge_is_infinity(&r)) { 259 return 0; 260 } 261 262 haskellsecp256k1_v0_1_0_fe_normalize_var(&r.y); 263 return !haskellsecp256k1_v0_1_0_fe_is_odd(&r.y) && 264 haskellsecp256k1_v0_1_0_fe_equal(&rx, &r.x); 265 } 266 267 #endif