mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-24 23:38:09 +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_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,
|
if (!fsm_layoutAddress(address, desc, is_cashaddr || is_bech32,
|
||||||
is_cashaddr ? strlen(coin->cashaddr_prefix) + 1 : 0,
|
is_cashaddr ? strlen(coin->cashaddr_prefix) + 1 : 0,
|
||||||
msg->address_n, msg->address_n_count, false,
|
msg->address_n, msg->address_n_count, false,
|
||||||
|
@ -33,8 +33,10 @@
|
|||||||
#include "ripemd160.h"
|
#include "ripemd160.h"
|
||||||
#include "segwit_addr.h"
|
#include "segwit_addr.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "zkp_bip340.h"
|
||||||
|
|
||||||
#define SEGWIT_VERSION_0 0
|
#define SEGWIT_VERSION_0 0
|
||||||
|
#define SEGWIT_VERSION_1 1
|
||||||
|
|
||||||
#define CASHADDR_P2KH (0)
|
#define CASHADDR_P2KH (0)
|
||||||
#define CASHADDR_P2SH (8)
|
#define CASHADDR_P2SH (8)
|
||||||
@ -143,21 +145,27 @@ bool compute_address(const CoinInfo *coin, InputScriptType script_type,
|
|||||||
address, MAX_ADDR_SIZE)) {
|
address, MAX_ADDR_SIZE)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (coin->cashaddr_prefix) {
|
} else if (script_type == InputScriptType_SPENDADDRESS ||
|
||||||
raw[0] = CASHADDR_P2SH | CASHADDR_160;
|
script_type == InputScriptType_SPENDMULTISIG) {
|
||||||
ripemd160(digest, 32, raw + 1);
|
if (coin->cashaddr_prefix) {
|
||||||
if (!cash_addr_encode(address, coin->cashaddr_prefix, raw, 21)) {
|
raw[0] = CASHADDR_P2SH | CASHADDR_160;
|
||||||
return 0;
|
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 {
|
} else {
|
||||||
// non-segwit p2sh multisig
|
// unsupported script type
|
||||||
prelen = address_prefix_bytes_len(coin->address_type_p2sh);
|
return 0;
|
||||||
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 if (script_type == InputScriptType_SPENDWITNESS) {
|
} else if (script_type == InputScriptType_SPENDWITNESS) {
|
||||||
// segwit p2wpkh: pubkey hash is ripemd160 of sha256
|
// segwit p2wpkh: pubkey hash is ripemd160 of sha256
|
||||||
@ -169,6 +177,17 @@ bool compute_address(const CoinInfo *coin, InputScriptType script_type,
|
|||||||
digest, 20)) {
|
digest, 20)) {
|
||||||
return 0;
|
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) {
|
} else if (script_type == InputScriptType_SPENDP2SHWITNESS) {
|
||||||
// segwit p2wpkh embedded in p2sh
|
// segwit p2wpkh embedded in p2sh
|
||||||
if (!coin->has_segwit) {
|
if (!coin->has_segwit) {
|
||||||
@ -177,16 +196,22 @@ bool compute_address(const CoinInfo *coin, InputScriptType script_type,
|
|||||||
ecdsa_get_address_segwit_p2sh(
|
ecdsa_get_address_segwit_p2sh(
|
||||||
node->public_key, coin->address_type_p2sh, coin->curve->hasher_pubkey,
|
node->public_key, coin->address_type_p2sh, coin->curve->hasher_pubkey,
|
||||||
coin->curve->hasher_base58, address, MAX_ADDR_SIZE);
|
coin->curve->hasher_base58, address, MAX_ADDR_SIZE);
|
||||||
} else if (coin->cashaddr_prefix) {
|
} else if (script_type == InputScriptType_SPENDADDRESS ||
|
||||||
ecdsa_get_address_raw(node->public_key, CASHADDR_P2KH | CASHADDR_160,
|
script_type == InputScriptType_SPENDMULTISIG) {
|
||||||
coin->curve->hasher_pubkey, raw);
|
if (coin->cashaddr_prefix) {
|
||||||
if (!cash_addr_encode(address, coin->cashaddr_prefix, raw, 21)) {
|
ecdsa_get_address_raw(node->public_key, CASHADDR_P2KH | CASHADDR_160,
|
||||||
return 0;
|
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 {
|
} else {
|
||||||
ecdsa_get_address(node->public_key, coin->address_type,
|
// unsupported script type
|
||||||
coin->curve->hasher_pubkey, coin->curve->hasher_base58,
|
return 0;
|
||||||
address, MAX_ADDR_SIZE);
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -45,33 +45,29 @@ VECTORS = ( # coin, path, script_type, address
|
|||||||
proto.InputScriptType.SPENDWITNESS,
|
proto.InputScriptType.SPENDWITNESS,
|
||||||
"bc1qktmhrsmsenepnnfst8x6j27l0uqv7ggrg8x38q",
|
"bc1qktmhrsmsenepnnfst8x6j27l0uqv7ggrg8x38q",
|
||||||
),
|
),
|
||||||
pytest.param(
|
(
|
||||||
"Testnet",
|
"Testnet",
|
||||||
"86'/1'/0'/0/0",
|
"86'/1'/0'/0/0",
|
||||||
proto.InputScriptType.SPENDTAPROOT,
|
proto.InputScriptType.SPENDTAPROOT,
|
||||||
"tb1pswrqtykue8r89t9u4rprjs0gt4qzkdfuursfnvqaa3f2yql07zmq8s8a5u",
|
"tb1pswrqtykue8r89t9u4rprjs0gt4qzkdfuursfnvqaa3f2yql07zmq8s8a5u",
|
||||||
marks=pytest.mark.skip_t1,
|
|
||||||
),
|
),
|
||||||
pytest.param(
|
(
|
||||||
"Testnet",
|
"Testnet",
|
||||||
"86'/1'/0'/1/0",
|
"86'/1'/0'/1/0",
|
||||||
proto.InputScriptType.SPENDTAPROOT,
|
proto.InputScriptType.SPENDTAPROOT,
|
||||||
"tb1pn2d0yjeedavnkd8z8lhm566p0f2utm3lgvxrsdehnl94y34txmts5s7t4c",
|
"tb1pn2d0yjeedavnkd8z8lhm566p0f2utm3lgvxrsdehnl94y34txmts5s7t4c",
|
||||||
marks=pytest.mark.skip_t1,
|
|
||||||
),
|
),
|
||||||
pytest.param(
|
(
|
||||||
"Bitcoin",
|
"Bitcoin",
|
||||||
"86'/0'/0'/0/0",
|
"86'/0'/0'/0/0",
|
||||||
proto.InputScriptType.SPENDTAPROOT,
|
proto.InputScriptType.SPENDTAPROOT,
|
||||||
"bc1ptxs597p3fnpd8gwut5p467ulsydae3rp9z75hd99w8k3ljr9g9rqx6ynaw",
|
"bc1ptxs597p3fnpd8gwut5p467ulsydae3rp9z75hd99w8k3ljr9g9rqx6ynaw",
|
||||||
marks=pytest.mark.skip_t1,
|
|
||||||
),
|
),
|
||||||
pytest.param(
|
(
|
||||||
"Bitcoin",
|
"Bitcoin",
|
||||||
"86'/0'/0'/1/0",
|
"86'/0'/0'/1/0",
|
||||||
proto.InputScriptType.SPENDTAPROOT,
|
proto.InputScriptType.SPENDTAPROOT,
|
||||||
"bc1pgypgja2hmcx2l6s2ssq75k6ev68ved6nujcspt47dgvkp8euc70s6uegk6",
|
"bc1pgypgja2hmcx2l6s2ssq75k6ev68ved6nujcspt47dgvkp8euc70s6uegk6",
|
||||||
marks=pytest.mark.skip_t1,
|
|
||||||
),
|
),
|
||||||
pytest.param(
|
pytest.param(
|
||||||
"Groestlcoin",
|
"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
|
# Tests https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki#test-vectors
|
||||||
@pytest.mark.skip_t1
|
|
||||||
@pytest.mark.setup_client(
|
@pytest.mark.setup_client(
|
||||||
mnemonic="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
mnemonic="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user