2020-05-12 21:19:03 +00:00
|
|
|
/**********************************************************************
|
|
|
|
* Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick *
|
|
|
|
* Distributed under the MIT software license, see the accompanying *
|
|
|
|
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
#ifndef _SECP256K1_MODULE_SCHNORRSIG_MAIN_
|
|
|
|
#define _SECP256K1_MODULE_SCHNORRSIG_MAIN_
|
|
|
|
|
|
|
|
#include "include/secp256k1.h"
|
|
|
|
#include "include/secp256k1_schnorrsig.h"
|
|
|
|
#include "hash.h"
|
|
|
|
|
2020-05-12 21:23:22 +00:00
|
|
|
/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
|
|
|
|
* SHA256 to SHA256("BIP0340/nonce")||SHA256("BIP0340/nonce"). */
|
|
|
|
static void secp256k1_nonce_function_bip340_sha256_tagged(secp256k1_sha256 *sha) {
|
|
|
|
secp256k1_sha256_initialize(sha);
|
|
|
|
sha->s[0] = 0x46615b35ul;
|
|
|
|
sha->s[1] = 0xf4bfbff7ul;
|
|
|
|
sha->s[2] = 0x9f8dc671ul;
|
|
|
|
sha->s[3] = 0x83627ab3ul;
|
|
|
|
sha->s[4] = 0x60217180ul;
|
|
|
|
sha->s[5] = 0x57358661ul;
|
|
|
|
sha->s[6] = 0x21a29e54ul;
|
|
|
|
sha->s[7] = 0x68b07b4cul;
|
|
|
|
|
|
|
|
sha->bytes = 64;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
|
|
|
|
* SHA256 to SHA256("BIP0340/aux")||SHA256("BIP0340/aux"). */
|
|
|
|
static void secp256k1_nonce_function_bip340_sha256_tagged_aux(secp256k1_sha256 *sha) {
|
|
|
|
secp256k1_sha256_initialize(sha);
|
|
|
|
sha->s[0] = 0x24dd3219ul;
|
|
|
|
sha->s[1] = 0x4eba7e70ul;
|
|
|
|
sha->s[2] = 0xca0fabb9ul;
|
|
|
|
sha->s[3] = 0x0fa3166dul;
|
|
|
|
sha->s[4] = 0x3afbe4b1ul;
|
|
|
|
sha->s[5] = 0x4c44df97ul;
|
|
|
|
sha->s[6] = 0x4aac2739ul;
|
|
|
|
sha->s[7] = 0x249e850aul;
|
|
|
|
|
|
|
|
sha->bytes = 64;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* algo16 argument for nonce_function_bip340 to derive the nonce exactly as stated in BIP-340
|
|
|
|
* by using the correct tagged hash function. */
|
|
|
|
static const unsigned char bip340_algo16[16] = "BIP0340/nonce\0\0\0";
|
|
|
|
|
|
|
|
static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo16, void *data) {
|
|
|
|
secp256k1_sha256 sha;
|
|
|
|
unsigned char masked_key[32];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (algo16 == NULL) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data != NULL) {
|
|
|
|
secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha);
|
|
|
|
secp256k1_sha256_write(&sha, data, 32);
|
|
|
|
secp256k1_sha256_finalize(&sha, masked_key);
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
|
|
masked_key[i] ^= key32[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Tag the hash with algo16 which is important to avoid nonce reuse across
|
|
|
|
* algorithms. If this nonce function is used in BIP-340 signing as defined
|
|
|
|
* in the spec, an optimized tagging implementation is used. */
|
|
|
|
if (memcmp(algo16, bip340_algo16, 16) == 0) {
|
|
|
|
secp256k1_nonce_function_bip340_sha256_tagged(&sha);
|
|
|
|
} else {
|
|
|
|
int algo16_len = 16;
|
|
|
|
/* Remove terminating null bytes */
|
|
|
|
while (algo16_len > 0 && !algo16[algo16_len - 1]) {
|
|
|
|
algo16_len--;
|
|
|
|
}
|
|
|
|
secp256k1_sha256_initialize_tagged(&sha, algo16, algo16_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Hash (masked-)key||pk||msg using the tagged hash as per the spec */
|
|
|
|
if (data != NULL) {
|
|
|
|
secp256k1_sha256_write(&sha, masked_key, 32);
|
|
|
|
} else {
|
|
|
|
secp256k1_sha256_write(&sha, key32, 32);
|
|
|
|
}
|
|
|
|
secp256k1_sha256_write(&sha, xonly_pk32, 32);
|
|
|
|
secp256k1_sha256_write(&sha, msg32, 32);
|
|
|
|
secp256k1_sha256_finalize(&sha, nonce32);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340 = nonce_function_bip340;
|
2020-05-12 21:19:03 +00:00
|
|
|
|
|
|
|
#endif
|