bitcoin: add routine to check a Schnorr sig given a 33-byte pubkey.

There's no secp256k1 routine to do this, but we're going to need it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2022-09-29 13:19:03 +09:30
parent 0195b41461
commit c9d42d8279
2 changed files with 34 additions and 0 deletions

View File

@ -9,6 +9,7 @@
#include <bitcoin/tx.h>
#include <ccan/mem/mem.h>
#include <common/type_to_string.h>
#include <secp256k1_schnorrsig.h>
#include <wire/wire.h>
#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;
}

View File

@ -5,12 +5,14 @@
#include <ccan/tal/tal.h>
#include <secp256k1.h>
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);