mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-06-26 18:02:35 +00:00
feat(legacy): Implement SLIP-0025 CoinJoin accounts.
This commit is contained in:
parent
0b3216146e
commit
0466972f30
1
legacy/firmware/.changelog.d/2718.added.3
Normal file
1
legacy/firmware/.changelog.d/2718.added.3
Normal file
@ -0,0 +1 @@
|
|||||||
|
Implement SLIP-0025 coinjoin accounts.
|
@ -487,7 +487,7 @@ static bool check_cointype(const CoinInfo *coin, uint32_t slip44, bool full) {
|
|||||||
|
|
||||||
bool coin_path_check(const CoinInfo *coin, InputScriptType script_type,
|
bool coin_path_check(const CoinInfo *coin, InputScriptType script_type,
|
||||||
uint32_t address_n_count, const uint32_t *address_n,
|
uint32_t address_n_count, const uint32_t *address_n,
|
||||||
bool has_multisig, bool full_check) {
|
bool has_multisig, PathSchema unlock, bool full_check) {
|
||||||
// This function checks that the path is a recognized path for the given coin.
|
// This function checks that the path is a recognized path for the given coin.
|
||||||
// Used by GetAddress to prevent ransom attacks where a user could be coerced
|
// Used by GetAddress to prevent ransom attacks where a user could be coerced
|
||||||
// to use an address with an unenumerable path and used by SignTx to ensure
|
// to use an address with an unenumerable path and used by SignTx to ensure
|
||||||
@ -732,6 +732,29 @@ bool coin_path_check(const CoinInfo *coin, InputScriptType script_type,
|
|||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m/10025' : SLIP25 CoinJoin
|
||||||
|
// m / purpose' / coin_type' / account' / script_type' / change /
|
||||||
|
// address_index
|
||||||
|
if (address_n[0] == PATH_SLIP25_PURPOSE) {
|
||||||
|
valid = valid && coin->has_taproot;
|
||||||
|
valid = valid && (coin->bech32_prefix != NULL);
|
||||||
|
valid = valid && (address_n_count == 6);
|
||||||
|
valid = valid && check_cointype(coin, address_n[1], full_check);
|
||||||
|
valid = valid && (address_n[2] == (PATH_HARDENED | 0)); // Only first acc.
|
||||||
|
valid = valid && (address_n[3] == (PATH_HARDENED | 1)); // Only SegWit v1.
|
||||||
|
valid = valid && (address_n[4] <= PATH_MAX_CHANGE);
|
||||||
|
valid = valid &&
|
||||||
|
((unlock == SCHEMA_SLIP25_TAPROOT) ||
|
||||||
|
(unlock == SCHEMA_SLIP25_TAPROOT_EXTERNAL && address_n[4] == 0));
|
||||||
|
valid = valid && (address_n[5] <= PATH_MAX_ADDRESS_INDEX);
|
||||||
|
if (full_check) {
|
||||||
|
// we do not support Multisig for CoinJoin
|
||||||
|
valid = valid && !has_multisig;
|
||||||
|
valid = valid && (script_type == InputScriptType_SPENDTAPROOT);
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
// unknown path
|
// unknown path
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,12 @@
|
|||||||
|
|
||||||
#define ser_length_size(len) ((len) < 253 ? 1 : (len) < 0x10000 ? 3 : 5)
|
#define ser_length_size(len) ((len) < 253 ? 1 : (len) < 0x10000 ? 3 : 5)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SCHEMA_NONE,
|
||||||
|
SCHEMA_SLIP25_TAPROOT,
|
||||||
|
SCHEMA_SLIP25_TAPROOT_EXTERNAL
|
||||||
|
} PathSchema;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t data[64];
|
uint8_t data[64];
|
||||||
} Slip21Node;
|
} Slip21Node;
|
||||||
@ -84,7 +90,7 @@ int cryptoIdentityFingerprint(const IdentityType *identity, uint8_t *hash);
|
|||||||
|
|
||||||
bool coin_path_check(const CoinInfo *coin, InputScriptType script_type,
|
bool coin_path_check(const CoinInfo *coin, InputScriptType script_type,
|
||||||
uint32_t address_n_count, const uint32_t *address_n,
|
uint32_t address_n_count, const uint32_t *address_n,
|
||||||
bool has_multisig, bool full_check);
|
bool has_multisig, PathSchema unlock, bool full_check);
|
||||||
|
|
||||||
bool is_multisig_input_script_type(InputScriptType script_type);
|
bool is_multisig_input_script_type(InputScriptType script_type);
|
||||||
bool is_multisig_output_script_type(OutputScriptType script_type);
|
bool is_multisig_output_script_type(OutputScriptType script_type);
|
||||||
|
@ -155,7 +155,8 @@ bool fsm_layoutVerifyMessage(const uint8_t *msg, uint32_t len);
|
|||||||
bool fsm_layoutPathWarning(void);
|
bool fsm_layoutPathWarning(void);
|
||||||
bool fsm_checkCoinPath(const CoinInfo *coin, InputScriptType script_type,
|
bool fsm_checkCoinPath(const CoinInfo *coin, InputScriptType script_type,
|
||||||
uint32_t address_n_count, const uint32_t *address_n,
|
uint32_t address_n_count, const uint32_t *address_n,
|
||||||
bool has_multisig, bool show_warning);
|
bool has_multisig, MessageType message_type,
|
||||||
|
bool show_warning);
|
||||||
|
|
||||||
bool fsm_getOwnershipId(uint8_t *script_pubkey, size_t script_pubkey_size,
|
bool fsm_getOwnershipId(uint8_t *script_pubkey, size_t script_pubkey_size,
|
||||||
uint8_t ownership_id[32]);
|
uint8_t ownership_id[32]);
|
||||||
|
@ -128,6 +128,36 @@ void fsm_msgGetPublicKey(const GetPublicKey *msg) {
|
|||||||
layoutHome();
|
layoutHome();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PathSchema fsm_getUnlockedSchema(MessageType message_type) {
|
||||||
|
if (message_type == MessageType_MessageType_AuthorizeCoinJoin) {
|
||||||
|
// Grant full access to SLIP-25 account.
|
||||||
|
return SCHEMA_SLIP25_TAPROOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authorization_type == MessageType_MessageType_AuthorizeCoinJoin) {
|
||||||
|
const AuthorizeCoinJoin *authorization = config_getCoinJoinAuthorization();
|
||||||
|
if (authorization == NULL ||
|
||||||
|
authorization->address_n[0] != PATH_SLIP25_PURPOSE) {
|
||||||
|
return SCHEMA_NONE;
|
||||||
|
}
|
||||||
|
// SLIP-25 access unlocked.
|
||||||
|
} else if (unlock_path == PATH_SLIP25_PURPOSE) {
|
||||||
|
// SLIP-25 access unlocked.
|
||||||
|
} else {
|
||||||
|
return SCHEMA_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (message_type) {
|
||||||
|
case MessageType_MessageType_GetOwnershipProof:
|
||||||
|
case MessageType_MessageType_SignTx:
|
||||||
|
// Grant full access to SLIP-25 account.
|
||||||
|
return SCHEMA_SLIP25_TAPROOT;
|
||||||
|
default:
|
||||||
|
// Grant access to SLIP-25 account's external chain.
|
||||||
|
return SCHEMA_SLIP25_TAPROOT_EXTERNAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void fsm_msgSignTx(const SignTx *msg) {
|
void fsm_msgSignTx(const SignTx *msg) {
|
||||||
CHECK_INITIALIZED
|
CHECK_INITIALIZED
|
||||||
|
|
||||||
@ -140,6 +170,8 @@ void fsm_msgSignTx(const SignTx *msg) {
|
|||||||
|
|
||||||
CHECK_PIN
|
CHECK_PIN
|
||||||
|
|
||||||
|
PathSchema unlock = fsm_getUnlockedSchema(MessageType_MessageType_SignTx);
|
||||||
|
|
||||||
const CoinInfo *coin = fsm_getCoin(msg->has_coin_name, msg->coin_name);
|
const CoinInfo *coin = fsm_getCoin(msg->has_coin_name, msg->coin_name);
|
||||||
if (!coin) return;
|
if (!coin) return;
|
||||||
|
|
||||||
@ -152,7 +184,7 @@ void fsm_msgSignTx(const SignTx *msg) {
|
|||||||
const HDNode *node = fsm_getDerivedNode(coin->curve_name, NULL, 0, NULL);
|
const HDNode *node = fsm_getDerivedNode(coin->curve_name, NULL, 0, NULL);
|
||||||
if (!node) return;
|
if (!node) return;
|
||||||
|
|
||||||
signing_init(msg, coin, node);
|
signing_init(msg, coin, node, unlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fsm_msgTxAck(TxAck *msg) {
|
void fsm_msgTxAck(TxAck *msg) {
|
||||||
@ -165,15 +197,18 @@ void fsm_msgTxAck(TxAck *msg) {
|
|||||||
|
|
||||||
bool fsm_checkCoinPath(const CoinInfo *coin, InputScriptType script_type,
|
bool fsm_checkCoinPath(const CoinInfo *coin, InputScriptType script_type,
|
||||||
uint32_t address_n_count, const uint32_t *address_n,
|
uint32_t address_n_count, const uint32_t *address_n,
|
||||||
bool has_multisig, bool show_warning) {
|
bool has_multisig, MessageType message_type,
|
||||||
|
bool show_warning) {
|
||||||
|
PathSchema unlock = fsm_getUnlockedSchema(message_type);
|
||||||
|
|
||||||
if (coin_path_check(coin, script_type, address_n_count, address_n,
|
if (coin_path_check(coin, script_type, address_n_count, address_n,
|
||||||
has_multisig, true)) {
|
has_multisig, unlock, true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_getSafetyCheckLevel() == SafetyCheckLevel_Strict &&
|
if (config_getSafetyCheckLevel() == SafetyCheckLevel_Strict &&
|
||||||
!coin_path_check(coin, script_type, address_n_count, address_n,
|
!coin_path_check(coin, script_type, address_n_count, address_n,
|
||||||
has_multisig, false)) {
|
has_multisig, unlock, false)) {
|
||||||
fsm_sendFailure(FailureType_Failure_DataError, _("Forbidden key path"));
|
fsm_sendFailure(FailureType_Failure_DataError, _("Forbidden key path"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -218,6 +253,7 @@ void fsm_msgGetAddress(const GetAddress *msg) {
|
|||||||
|
|
||||||
if (!fsm_checkCoinPath(coin, msg->script_type, msg->address_n_count,
|
if (!fsm_checkCoinPath(coin, msg->script_type, msg->address_n_count,
|
||||||
msg->address_n, msg->has_multisig,
|
msg->address_n, msg->has_multisig,
|
||||||
|
MessageType_MessageType_GetAddress,
|
||||||
msg->show_display)) {
|
msg->show_display)) {
|
||||||
layoutHome();
|
layoutHome();
|
||||||
return;
|
return;
|
||||||
@ -304,7 +340,8 @@ void fsm_msgSignMessage(const SignMessage *msg) {
|
|||||||
if (!coin) return;
|
if (!coin) return;
|
||||||
|
|
||||||
if (!fsm_checkCoinPath(coin, msg->script_type, msg->address_n_count,
|
if (!fsm_checkCoinPath(coin, msg->script_type, msg->address_n_count,
|
||||||
msg->address_n, false, true)) {
|
msg->address_n, false,
|
||||||
|
MessageType_MessageType_SignMessage, true)) {
|
||||||
layoutHome();
|
layoutHome();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -424,7 +461,8 @@ void fsm_msgGetOwnershipId(const GetOwnershipId *msg) {
|
|||||||
if (!coin) return;
|
if (!coin) return;
|
||||||
|
|
||||||
if (!fsm_checkCoinPath(coin, msg->script_type, msg->address_n_count,
|
if (!fsm_checkCoinPath(coin, msg->script_type, msg->address_n_count,
|
||||||
msg->address_n, msg->has_multisig, false)) {
|
msg->address_n, msg->has_multisig,
|
||||||
|
MessageType_MessageType_GetOwnershipId, false)) {
|
||||||
layoutHome();
|
layoutHome();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -662,7 +700,9 @@ void fsm_msgAuthorizeCoinJoin(const AuthorizeCoinJoin *msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!fsm_checkCoinPath(coin, msg->script_type, msg->address_n_count + 2,
|
if (!fsm_checkCoinPath(coin, msg->script_type, msg->address_n_count + 2,
|
||||||
msg->address_n, false, !path_warning_shown)) {
|
msg->address_n, false,
|
||||||
|
MessageType_MessageType_AuthorizeCoinJoin,
|
||||||
|
!path_warning_shown)) {
|
||||||
layoutHome();
|
layoutHome();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -68,8 +68,6 @@ static const char *slip44_extras(uint32_t coin_type) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BIP32_MAX_LAST_ELEMENT 1000000
|
|
||||||
|
|
||||||
static const char *address_n_str(const uint32_t *address_n,
|
static const char *address_n_str(const uint32_t *address_n,
|
||||||
size_t address_n_count,
|
size_t address_n_count,
|
||||||
bool address_is_account) {
|
bool address_is_account) {
|
||||||
@ -80,30 +78,47 @@ static const char *address_n_str(const uint32_t *address_n,
|
|||||||
return _("Path: m");
|
return _("Path: m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ACCOUNT_NONE,
|
||||||
|
ACCOUNT_BIP44,
|
||||||
|
ACCOUNT_BIP49,
|
||||||
|
ACCOUNT_BIP84,
|
||||||
|
ACCOUNT_BIP86,
|
||||||
|
ACCOUNT_SLIP25
|
||||||
|
} account_type = ACCOUNT_NONE;
|
||||||
|
|
||||||
|
if ((address_n[1] & PATH_HARDENED) && (address_n[2] & PATH_HARDENED) &&
|
||||||
|
(address_n[address_n_count - 2] <= PATH_MAX_CHANGE) &&
|
||||||
|
(address_n[address_n_count - 1] <= PATH_MAX_ADDRESS_INDEX)) {
|
||||||
|
if (address_n_count == 5 && address_n[0] == PATH_HARDENED + 44) {
|
||||||
|
account_type = ACCOUNT_BIP44;
|
||||||
|
} else if (address_n_count == 5 && address_n[0] == PATH_HARDENED + 49) {
|
||||||
|
account_type = ACCOUNT_BIP49;
|
||||||
|
} else if (address_n_count == 5 && address_n[0] == PATH_HARDENED + 84) {
|
||||||
|
account_type = ACCOUNT_BIP84;
|
||||||
|
} else if (address_n_count == 5 && address_n[0] == PATH_HARDENED + 86) {
|
||||||
|
account_type = ACCOUNT_BIP86;
|
||||||
|
} else if (address_n_count == 6 && address_n[0] == PATH_SLIP25_PURPOSE &&
|
||||||
|
(address_n[3] & PATH_HARDENED)) {
|
||||||
|
account_type = ACCOUNT_SLIP25;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// known BIP44/49/84/86 path
|
// known BIP44/49/84/86 path
|
||||||
static char path[100];
|
static char path[100];
|
||||||
if (address_n_count == 5 &&
|
if (account_type != ACCOUNT_NONE) {
|
||||||
(address_n[0] == (PATH_HARDENED + 44) ||
|
|
||||||
address_n[0] == (PATH_HARDENED + 49) ||
|
|
||||||
address_n[0] == (PATH_HARDENED + 84) ||
|
|
||||||
address_n[0] == (PATH_HARDENED + 86)) &&
|
|
||||||
(address_n[1] & PATH_HARDENED) && (address_n[2] & PATH_HARDENED) &&
|
|
||||||
(address_n[3] <= 1) && (address_n[4] <= BIP32_MAX_LAST_ELEMENT)) {
|
|
||||||
bool taproot = (address_n[0] == (PATH_HARDENED + 86));
|
|
||||||
bool native_segwit = (address_n[0] == (PATH_HARDENED + 84));
|
|
||||||
bool p2sh_segwit = (address_n[0] == (PATH_HARDENED + 49));
|
|
||||||
bool legacy = false;
|
bool legacy = false;
|
||||||
const CoinInfo *coin = coinBySlip44(address_n[1]);
|
const CoinInfo *coin = coinBySlip44(address_n[1]);
|
||||||
const char *abbr = 0;
|
const char *abbr = 0;
|
||||||
if (taproot) {
|
if (account_type == ACCOUNT_BIP86 || account_type == ACCOUNT_SLIP25) {
|
||||||
if (coin && coin->has_taproot && coin->bech32_prefix) {
|
if (coin && coin->has_taproot && coin->bech32_prefix) {
|
||||||
abbr = coin->coin_shortcut;
|
abbr = coin->coin_shortcut;
|
||||||
}
|
}
|
||||||
} else if (native_segwit) {
|
} else if (account_type == ACCOUNT_BIP84) {
|
||||||
if (coin && coin->has_segwit && coin->bech32_prefix) {
|
if (coin && coin->has_segwit && coin->bech32_prefix) {
|
||||||
abbr = coin->coin_shortcut;
|
abbr = coin->coin_shortcut;
|
||||||
}
|
}
|
||||||
} else if (p2sh_segwit) {
|
} else if (account_type == ACCOUNT_BIP49) {
|
||||||
if (coin && coin->has_segwit) {
|
if (coin && coin->has_segwit) {
|
||||||
abbr = coin->coin_shortcut;
|
abbr = coin->coin_shortcut;
|
||||||
}
|
}
|
||||||
@ -125,19 +140,21 @@ static const char *address_n_str(const uint32_t *address_n,
|
|||||||
if (abbr && accnum < 100) {
|
if (abbr && accnum < 100) {
|
||||||
memzero(path, sizeof(path));
|
memzero(path, sizeof(path));
|
||||||
strlcpy(path, abbr, sizeof(path));
|
strlcpy(path, abbr, sizeof(path));
|
||||||
// account naming:
|
// Account naming:
|
||||||
// "Legacy", "Legacy SegWit", "SegWit" and "Taproot"
|
// "Legacy", "Legacy SegWit", "SegWit", "Taproot" and "Coinjoin" for
|
||||||
// for BIP44/P2PKH, BIP49/P2SH-P2WPKH, BIP84/P2WPKH and BIP86/P2TR
|
// BIP44/P2PKH, BIP49/P2SH-P2WPKH, BIP84/P2WPKH, BIP86/P2TR, SLIP25/P2TR
|
||||||
// respectively.
|
// respectively. For non-segwit coins we use only BIP44 with no special
|
||||||
// For non-segwit coins we use only BIP44 with no special naming.
|
// naming.
|
||||||
if (legacy) {
|
if (legacy) {
|
||||||
strlcat(path, " Legacy", sizeof(path));
|
strlcat(path, " Legacy", sizeof(path));
|
||||||
} else if (p2sh_segwit) {
|
} else if (account_type == ACCOUNT_BIP49) {
|
||||||
strlcat(path, " L.SegWit", sizeof(path));
|
strlcat(path, " L.SegWit", sizeof(path));
|
||||||
} else if (native_segwit) {
|
} else if (account_type == ACCOUNT_BIP84) {
|
||||||
strlcat(path, " SegWit", sizeof(path));
|
strlcat(path, " SegWit", sizeof(path));
|
||||||
} else if (taproot) {
|
} else if (account_type == ACCOUNT_BIP86) {
|
||||||
strlcat(path, " Taproot", sizeof(path));
|
strlcat(path, " Taproot", sizeof(path));
|
||||||
|
} else if (account_type == ACCOUNT_SLIP25) {
|
||||||
|
strlcat(path, " Coinjoin", sizeof(path));
|
||||||
}
|
}
|
||||||
if (address_is_account) {
|
if (address_is_account) {
|
||||||
strlcat(path, " address #", sizeof(path));
|
strlcat(path, " address #", sizeof(path));
|
||||||
|
@ -104,6 +104,7 @@ static uint64_t orig_total_in, orig_external_in, orig_total_out,
|
|||||||
orig_change_out;
|
orig_change_out;
|
||||||
static uint32_t progress, progress_step, progress_meta_step;
|
static uint32_t progress, progress_step, progress_meta_step;
|
||||||
static uint32_t tx_weight;
|
static uint32_t tx_weight;
|
||||||
|
PathSchema unlocked_schema;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t inputs_count;
|
uint32_t inputs_count;
|
||||||
@ -922,7 +923,8 @@ static bool fill_input_script_pubkey(TxInputType *in) {
|
|||||||
|
|
||||||
static bool derive_node(TxInputType *tinput) {
|
static bool derive_node(TxInputType *tinput) {
|
||||||
if (!coin_path_check(coin, tinput->script_type, tinput->address_n_count,
|
if (!coin_path_check(coin, tinput->script_type, tinput->address_n_count,
|
||||||
tinput->address_n, tinput->has_multisig, false) &&
|
tinput->address_n, tinput->has_multisig, unlocked_schema,
|
||||||
|
false) &&
|
||||||
config_getSafetyCheckLevel() == SafetyCheckLevel_Strict) {
|
config_getSafetyCheckLevel() == SafetyCheckLevel_Strict) {
|
||||||
fsm_sendFailure(FailureType_Failure_DataError, _("Forbidden key path"));
|
fsm_sendFailure(FailureType_Failure_DataError, _("Forbidden key path"));
|
||||||
signing_abort();
|
signing_abort();
|
||||||
@ -935,7 +937,8 @@ static bool derive_node(TxInputType *tinput) {
|
|||||||
// through a warning screen before we sign the input.
|
// through a warning screen before we sign the input.
|
||||||
if (!foreign_address_confirmed &&
|
if (!foreign_address_confirmed &&
|
||||||
!coin_path_check(coin, tinput->script_type, tinput->address_n_count,
|
!coin_path_check(coin, tinput->script_type, tinput->address_n_count,
|
||||||
tinput->address_n, tinput->has_multisig, true)) {
|
tinput->address_n, tinput->has_multisig, unlocked_schema,
|
||||||
|
true)) {
|
||||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||||
_("Transaction has changed during signing"));
|
_("Transaction has changed during signing"));
|
||||||
signing_abort();
|
signing_abort();
|
||||||
@ -1098,8 +1101,8 @@ static bool tx_info_init(TxInfo *tx_info, uint32_t inputs_count,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void signing_init(const SignTx *msg, const CoinInfo *_coin,
|
void signing_init(const SignTx *msg, const CoinInfo *_coin, const HDNode *_root,
|
||||||
const HDNode *_root) {
|
PathSchema unlock) {
|
||||||
coin = _coin;
|
coin = _coin;
|
||||||
amount_unit = msg->has_amount_unit ? msg->amount_unit : AmountUnit_BITCOIN;
|
amount_unit = msg->has_amount_unit ? msg->amount_unit : AmountUnit_BITCOIN;
|
||||||
serialize = msg->has_serialize ? msg->serialize : true;
|
serialize = msg->has_serialize ? msg->serialize : true;
|
||||||
@ -1150,6 +1153,7 @@ void signing_init(const SignTx *msg, const CoinInfo *_coin,
|
|||||||
memzero(&output, sizeof(TxOutputType));
|
memzero(&output, sizeof(TxOutputType));
|
||||||
memzero(&resp, sizeof(TxRequest));
|
memzero(&resp, sizeof(TxRequest));
|
||||||
is_replacement = false;
|
is_replacement = false;
|
||||||
|
unlocked_schema = unlock;
|
||||||
signing = true;
|
signing = true;
|
||||||
progress = 0;
|
progress = 0;
|
||||||
// we step by 500/inputs_count per input in phase1 and phase2
|
// we step by 500/inputs_count per input in phase1 and phase2
|
||||||
|
@ -24,11 +24,12 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "bip32.h"
|
#include "bip32.h"
|
||||||
#include "coins.h"
|
#include "coins.h"
|
||||||
|
#include "crypto.h"
|
||||||
#include "hasher.h"
|
#include "hasher.h"
|
||||||
#include "messages-bitcoin.pb.h"
|
#include "messages-bitcoin.pb.h"
|
||||||
|
|
||||||
void signing_init(const SignTx *msg, const CoinInfo *_coin,
|
void signing_init(const SignTx *msg, const CoinInfo *_coin, const HDNode *_root,
|
||||||
const HDNode *_root);
|
PathSchema unlock);
|
||||||
void signing_abort(void);
|
void signing_abort(void);
|
||||||
void signing_txack(TransactionType *tx);
|
void signing_txack(TransactionType *tx);
|
||||||
|
|
||||||
|
@ -399,7 +399,6 @@ def test_sign_tx_large(client: Client):
|
|||||||
assert delay <= max_expected_delay
|
assert delay <= max_expected_delay
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip_t1
|
|
||||||
def test_sign_tx_spend(client: Client):
|
def test_sign_tx_spend(client: Client):
|
||||||
# NOTE: FAKE input tx
|
# NOTE: FAKE input tx
|
||||||
|
|
||||||
@ -440,6 +439,7 @@ def test_sign_tx_spend(client: Client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
with client:
|
with client:
|
||||||
|
tt = client.features.model == "T"
|
||||||
client.set_expected_responses(
|
client.set_expected_responses(
|
||||||
[
|
[
|
||||||
messages.ButtonRequest(code=B.Other),
|
messages.ButtonRequest(code=B.Other),
|
||||||
@ -448,9 +448,9 @@ def test_sign_tx_spend(client: Client):
|
|||||||
request_output(0),
|
request_output(0),
|
||||||
request_output(1),
|
request_output(1),
|
||||||
messages.ButtonRequest(code=B.ConfirmOutput),
|
messages.ButtonRequest(code=B.ConfirmOutput),
|
||||||
messages.ButtonRequest(code=B.ConfirmOutput),
|
(tt, messages.ButtonRequest(code=B.ConfirmOutput)),
|
||||||
messages.ButtonRequest(code=B.SignTx),
|
|
||||||
messages.ButtonRequest(code=B.SignTx),
|
messages.ButtonRequest(code=B.SignTx),
|
||||||
|
(tt, messages.ButtonRequest(code=B.SignTx)),
|
||||||
request_input(0),
|
request_input(0),
|
||||||
request_output(0),
|
request_output(0),
|
||||||
request_output(1),
|
request_output(1),
|
||||||
@ -612,7 +612,6 @@ def test_get_public_key(client: Client):
|
|||||||
assert resp.xpub == EXPECTED_XPUB
|
assert resp.xpub == EXPECTED_XPUB
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip_t1
|
|
||||||
def test_get_address(client: Client):
|
def test_get_address(client: Client):
|
||||||
# Ensure that the SLIP-0025 external chain is inaccessible without user confirmation.
|
# Ensure that the SLIP-0025 external chain is inaccessible without user confirmation.
|
||||||
with pytest.raises(TrezorFailure, match="Forbidden key path"):
|
with pytest.raises(TrezorFailure, match="Forbidden key path"):
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
"T1": {
|
"T1": {
|
||||||
"device_tests": {
|
"device_tests": {
|
||||||
|
"T1_bitcoin-test_authorize_coinjoin.py::test_get_address": "402c3f89f6ad5fd3bc78f804b376c36c918fc685cc2c77b38c6ae030af738d22",
|
||||||
"T1_bitcoin-test_authorize_coinjoin.py::test_get_public_key": "9b3c916759b79048a4ab3e3fe8ce0ea0cf8d4ae6cfb66a5d712f21edfdb01782",
|
"T1_bitcoin-test_authorize_coinjoin.py::test_get_public_key": "9b3c916759b79048a4ab3e3fe8ce0ea0cf8d4ae6cfb66a5d712f21edfdb01782",
|
||||||
|
"T1_bitcoin-test_authorize_coinjoin.py::test_sign_tx_spend": "edeb75022cc6bff15d1274ba9bac4cf41dd8ea5771436010ae07fd441dc73b69",
|
||||||
"T1_bitcoin-test_bcash.py::test_attack_change_input": "6111e313995d38c3970c92e48047fe4088c83666c64c6c859f69a232ad62829b",
|
"T1_bitcoin-test_bcash.py::test_attack_change_input": "6111e313995d38c3970c92e48047fe4088c83666c64c6c859f69a232ad62829b",
|
||||||
"T1_bitcoin-test_bcash.py::test_send_bch_change": "6111e313995d38c3970c92e48047fe4088c83666c64c6c859f69a232ad62829b",
|
"T1_bitcoin-test_bcash.py::test_send_bch_change": "6111e313995d38c3970c92e48047fe4088c83666c64c6c859f69a232ad62829b",
|
||||||
"T1_bitcoin-test_bcash.py::test_send_bch_multisig_change": "0962a2e630e06b6d20282cc241be40f41bc1648d0a26247c7c008f32a197d0cb",
|
"T1_bitcoin-test_bcash.py::test_send_bch_multisig_change": "0962a2e630e06b6d20282cc241be40f41bc1648d0a26247c7c008f32a197d0cb",
|
||||||
|
Loading…
Reference in New Issue
Block a user