diff --git a/bitcoin/signature.c b/bitcoin/signature.c index 4e0cda8ad..ee668db92 100644 --- a/bitcoin/signature.c +++ b/bitcoin/signature.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #undef DEBUG @@ -415,3 +416,27 @@ void bip340_sighash_init(struct sha256_ctx *sctx, sha256_update(sctx, &taghash, sizeof(taghash)); } + +bool check_schnorr_sig(const struct sha256 *hash, + const secp256k1_pubkey *pubkey, + const struct bip340sig *sig) +{ + /* FIXME: uuuugly! There's no non-xonly verify function. */ + u8 raw[PUBKEY_CMPR_LEN]; + size_t outlen = sizeof(raw); + secp256k1_xonly_pubkey xonly_pubkey; + + if (!secp256k1_ec_pubkey_serialize(secp256k1_ctx, raw, &outlen, + pubkey, + SECP256K1_EC_COMPRESSED)) + abort(); + assert(outlen == PUBKEY_CMPR_LEN); + if (!secp256k1_xonly_pubkey_parse(secp256k1_ctx, &xonly_pubkey, raw+1)) + abort(); + + return secp256k1_schnorrsig_verify(secp256k1_ctx, + sig->u8, + hash->u.u8, + sizeof(hash->u.u8), + &xonly_pubkey) == 1; +} diff --git a/bitcoin/signature.h b/bitcoin/signature.h index 29d368148..0ba9eba0e 100644 --- a/bitcoin/signature.h +++ b/bitcoin/signature.h @@ -5,12 +5,14 @@ #include #include +struct sha256; struct sha256_double; struct sha256_ctx; struct bitcoin_tx; struct pubkey; struct privkey; struct bitcoin_tx_output; +struct bip340sig; enum sighash_type { SIGHASH_ALL = 1, @@ -121,6 +123,13 @@ bool check_tx_sig(const struct bitcoin_tx *tx, size_t input_num, const struct pubkey *key, const struct bitcoin_signature *sig); +/** + * check a Schnorr signature + */ +bool check_schnorr_sig(const struct sha256 *hash, + const secp256k1_pubkey *pubkey, + const struct bip340sig *sig); + /* Give DER encoding of signature: returns length used (<= 73). */ size_t signature_to_der(u8 der[73], const struct bitcoin_signature *sig);