Skip to content

Commit

Permalink
bitcoin: add routine to check a Schnorr sig given a 33-byte pubkey.
Browse files Browse the repository at this point in the history
There's no secp256k1 routine to do this, but we're going to need it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
rustyrussell committed Sep 29, 2022
1 parent 58f5b59 commit a3017c2
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
25 changes: 25 additions & 0 deletions bitcoin/signature.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
9 changes: 9 additions & 0 deletions bitcoin/signature.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit a3017c2

Please sign in to comment.