feat(legacy): verify bip340 pubkeys used in p2tr addresses

pull/2098/head
Pavol Rusnak 2 years ago committed by Andrew Kozlik
parent 3c0cb4d763
commit ea6b005003

@ -184,6 +184,27 @@ int zkp_bip340_verify_digest(const uint8_t *public_key_bytes,
return result;
}
// BIP340 Schnorr public key verification
// public_key_bytes has 32 bytes
// returns 0 if verification succeeded
int zkp_bip340_verify_publickey(const uint8_t *public_key_bytes) {
int result = 0;
secp256k1_xonly_pubkey xonly_pubkey = {0};
const secp256k1_context *context_read_only = zkp_context_get_read_only();
if (result == 0) {
if (secp256k1_xonly_pubkey_parse(context_read_only, &xonly_pubkey,
public_key_bytes) != 1) {
result = 1;
}
}
memzero(&xonly_pubkey, sizeof(xonly_pubkey));
return result;
}
// BIP340 Schnorr public key tweak
// internal_public_key has 32 bytes
// root_hash has 32 bytes or is empty (NULL)

@ -11,6 +11,7 @@ int zkp_bip340_sign_digest(const uint8_t *private_key_bytes,
int zkp_bip340_verify_digest(const uint8_t *public_key_bytes,
const uint8_t *signature_bytes,
const uint8_t *digest);
int zkp_bip340_verify_publickey(const uint8_t *public_key_bytes);
int zkp_bip340_tweak_public_key(const uint8_t *internal_public_key,
const uint8_t *root_hash,
uint8_t *output_public_key);

@ -0,0 +1 @@
Add extra check for Taproot scripts validity

@ -295,6 +295,16 @@ static int address_to_script_pubkey(const CoinInfo *coin, const char *address,
coin->bech32_prefix, address)) {
return 0;
}
// check that the witness version is recognized
if (witver != 0 && witver != 1) {
return 0;
}
// check that P2TR address encodes a valid BIP340 public key
if (witver == 1) {
if (addr_raw_len != 32 || zkp_bip340_verify_publickey(addr_raw) != 0) {
return 0;
}
}
// push 1 byte version id (opcode OP_0 = 0, OP_i = 80+i)
// push addr_raw (segwit_addr_decode makes sure addr_raw_len is at most 40)
script_pubkey[0] = witver == 0 ? 0 : 80 + witver;

Loading…
Cancel
Save