mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-23 23:08:14 +00:00
feat(legacy): Implement GetAddress for taproot.
This commit is contained in:
parent
34e8284331
commit
6c9c727359
1
legacy/firmware/.changelog.d/1656.added.1
Normal file
1
legacy/firmware/.changelog.d/1656.added.1
Normal file
@ -0,0 +1 @@
|
||||
Support GetAddress for Taproot addresses.
|
@ -233,7 +233,8 @@ void fsm_msgGetAddress(const GetAddress *msg) {
|
||||
}
|
||||
|
||||
bool is_cashaddr = coin->cashaddr_prefix != NULL;
|
||||
bool is_bech32 = msg->script_type == InputScriptType_SPENDWITNESS;
|
||||
bool is_bech32 = msg->script_type == InputScriptType_SPENDWITNESS ||
|
||||
msg->script_type == InputScriptType_SPENDTAPROOT;
|
||||
if (!fsm_layoutAddress(address, desc, is_cashaddr || is_bech32,
|
||||
is_cashaddr ? strlen(coin->cashaddr_prefix) + 1 : 0,
|
||||
msg->address_n, msg->address_n_count, false,
|
||||
|
@ -33,8 +33,10 @@
|
||||
#include "ripemd160.h"
|
||||
#include "segwit_addr.h"
|
||||
#include "util.h"
|
||||
#include "zkp_bip340.h"
|
||||
|
||||
#define SEGWIT_VERSION_0 0
|
||||
#define SEGWIT_VERSION_1 1
|
||||
|
||||
#define CASHADDR_P2KH (0)
|
||||
#define CASHADDR_P2SH (8)
|
||||
@ -143,21 +145,27 @@ bool compute_address(const CoinInfo *coin, InputScriptType script_type,
|
||||
address, MAX_ADDR_SIZE)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (coin->cashaddr_prefix) {
|
||||
raw[0] = CASHADDR_P2SH | CASHADDR_160;
|
||||
ripemd160(digest, 32, raw + 1);
|
||||
if (!cash_addr_encode(address, coin->cashaddr_prefix, raw, 21)) {
|
||||
return 0;
|
||||
} else if (script_type == InputScriptType_SPENDADDRESS ||
|
||||
script_type == InputScriptType_SPENDMULTISIG) {
|
||||
if (coin->cashaddr_prefix) {
|
||||
raw[0] = CASHADDR_P2SH | CASHADDR_160;
|
||||
ripemd160(digest, 32, raw + 1);
|
||||
if (!cash_addr_encode(address, coin->cashaddr_prefix, raw, 21)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// non-segwit p2sh multisig
|
||||
prelen = address_prefix_bytes_len(coin->address_type_p2sh);
|
||||
address_write_prefix_bytes(coin->address_type_p2sh, raw);
|
||||
ripemd160(digest, 32, raw + prelen);
|
||||
if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_base58,
|
||||
address, MAX_ADDR_SIZE)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// non-segwit p2sh multisig
|
||||
prelen = address_prefix_bytes_len(coin->address_type_p2sh);
|
||||
address_write_prefix_bytes(coin->address_type_p2sh, raw);
|
||||
ripemd160(digest, 32, raw + prelen);
|
||||
if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_base58,
|
||||
address, MAX_ADDR_SIZE)) {
|
||||
return 0;
|
||||
}
|
||||
// unsupported script type
|
||||
return 0;
|
||||
}
|
||||
} else if (script_type == InputScriptType_SPENDWITNESS) {
|
||||
// segwit p2wpkh: pubkey hash is ripemd160 of sha256
|
||||
@ -169,6 +177,17 @@ bool compute_address(const CoinInfo *coin, InputScriptType script_type,
|
||||
digest, 20)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (script_type == InputScriptType_SPENDTAPROOT) {
|
||||
// taproot
|
||||
if (!coin->has_taproot || !coin->has_segwit || !coin->bech32_prefix) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t tweaked_pubkey[32];
|
||||
zkp_bip340_tweak_public_key(node->public_key + 1, NULL, tweaked_pubkey);
|
||||
if (!segwit_addr_encode(address, coin->bech32_prefix, SEGWIT_VERSION_1,
|
||||
tweaked_pubkey, 32)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (script_type == InputScriptType_SPENDP2SHWITNESS) {
|
||||
// segwit p2wpkh embedded in p2sh
|
||||
if (!coin->has_segwit) {
|
||||
@ -177,16 +196,22 @@ bool compute_address(const CoinInfo *coin, InputScriptType script_type,
|
||||
ecdsa_get_address_segwit_p2sh(
|
||||
node->public_key, coin->address_type_p2sh, coin->curve->hasher_pubkey,
|
||||
coin->curve->hasher_base58, address, MAX_ADDR_SIZE);
|
||||
} else if (coin->cashaddr_prefix) {
|
||||
ecdsa_get_address_raw(node->public_key, CASHADDR_P2KH | CASHADDR_160,
|
||||
coin->curve->hasher_pubkey, raw);
|
||||
if (!cash_addr_encode(address, coin->cashaddr_prefix, raw, 21)) {
|
||||
return 0;
|
||||
} else if (script_type == InputScriptType_SPENDADDRESS ||
|
||||
script_type == InputScriptType_SPENDMULTISIG) {
|
||||
if (coin->cashaddr_prefix) {
|
||||
ecdsa_get_address_raw(node->public_key, CASHADDR_P2KH | CASHADDR_160,
|
||||
coin->curve->hasher_pubkey, raw);
|
||||
if (!cash_addr_encode(address, coin->cashaddr_prefix, raw, 21)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
ecdsa_get_address(node->public_key, coin->address_type,
|
||||
coin->curve->hasher_pubkey, coin->curve->hasher_base58,
|
||||
address, MAX_ADDR_SIZE);
|
||||
}
|
||||
} else {
|
||||
ecdsa_get_address(node->public_key, coin->address_type,
|
||||
coin->curve->hasher_pubkey, coin->curve->hasher_base58,
|
||||
address, MAX_ADDR_SIZE);
|
||||
// unsupported script type
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -45,33 +45,29 @@ VECTORS = ( # coin, path, script_type, address
|
||||
proto.InputScriptType.SPENDWITNESS,
|
||||
"bc1qktmhrsmsenepnnfst8x6j27l0uqv7ggrg8x38q",
|
||||
),
|
||||
pytest.param(
|
||||
(
|
||||
"Testnet",
|
||||
"86'/1'/0'/0/0",
|
||||
proto.InputScriptType.SPENDTAPROOT,
|
||||
"tb1pswrqtykue8r89t9u4rprjs0gt4qzkdfuursfnvqaa3f2yql07zmq8s8a5u",
|
||||
marks=pytest.mark.skip_t1,
|
||||
),
|
||||
pytest.param(
|
||||
(
|
||||
"Testnet",
|
||||
"86'/1'/0'/1/0",
|
||||
proto.InputScriptType.SPENDTAPROOT,
|
||||
"tb1pn2d0yjeedavnkd8z8lhm566p0f2utm3lgvxrsdehnl94y34txmts5s7t4c",
|
||||
marks=pytest.mark.skip_t1,
|
||||
),
|
||||
pytest.param(
|
||||
(
|
||||
"Bitcoin",
|
||||
"86'/0'/0'/0/0",
|
||||
proto.InputScriptType.SPENDTAPROOT,
|
||||
"bc1ptxs597p3fnpd8gwut5p467ulsydae3rp9z75hd99w8k3ljr9g9rqx6ynaw",
|
||||
marks=pytest.mark.skip_t1,
|
||||
),
|
||||
pytest.param(
|
||||
(
|
||||
"Bitcoin",
|
||||
"86'/0'/0'/1/0",
|
||||
proto.InputScriptType.SPENDTAPROOT,
|
||||
"bc1pgypgja2hmcx2l6s2ssq75k6ev68ved6nujcspt47dgvkp8euc70s6uegk6",
|
||||
marks=pytest.mark.skip_t1,
|
||||
),
|
||||
pytest.param(
|
||||
"Groestlcoin",
|
||||
@ -114,7 +110,6 @@ def test_show_segwit(client, show_display, coin, path, script_type, address):
|
||||
|
||||
|
||||
# Tests https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki#test-vectors
|
||||
@pytest.mark.skip_t1
|
||||
@pytest.mark.setup_client(
|
||||
mnemonic="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user