From f96215070d890afe86724002597e7e186cf7b530 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 8 Oct 2024 17:39:57 +0200 Subject: [PATCH 01/57] Added parsing for musig(); generalized key placeholders in wallet policies to more general key expressions --- src/common/wallet.c | 174 +++++++++++++++++++----- src/common/wallet.h | 47 +++++-- src/handler/lib/policy.c | 103 +++++++------- src/handler/lib/policy.h | 2 +- src/handler/sign_psbt.c | 2 +- src/handler/sign_psbt/sign_psbt_cache.c | 2 +- src/handler/sign_psbt/sign_psbt_cache.h | 2 +- unit-tests/test_wallet.c | 148 ++++++++++++++------ 8 files changed, 334 insertions(+), 146 deletions(-) diff --git a/src/common/wallet.c b/src/common/wallet.c index 6b956ab13..dccb20251 100644 --- a/src/common/wallet.c +++ b/src/common/wallet.c @@ -424,23 +424,120 @@ int parse_policy_map_key_info(buffer_t *buffer, policy_map_key_info_t *out, int return 0; } -// parses a placeholder from in_buf, storing it in out. On success, the pointed placeholder_index is -// stored in out->placeholder_index, and then it's incremented. -static int parse_placeholder(buffer_t *in_buf, - int version, - policy_node_key_placeholder_t *out, - uint16_t *placeholder_index) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcomment" +// The compiler doesn't like /** inside a block comment, so we disable this warning temporarily. + +/** + * Parses a key expression, in one of the following forms: + * - Single key index: + * - @IDX/** + * - @IDX//* + * - MuSig2 aggregate key (only if is_taproot is true): + * - musig(@IDX,@IDX,...,@IDX)/** + * - musig(@IDX,@IDX,...,@IDX)//* + * where IDX is a key index. + */ +#pragma GCC diagnostic pop +static int parse_keyexpr(buffer_t *in_buf, + int version, + policy_node_keyexpr_t *out, + bool is_taproot, + buffer_t *out_buf, + uint16_t *placeholder_index) { char c; - if (!buffer_read_u8(in_buf, (uint8_t *) &c) || c != '@') { - return WITH_ERROR(-1, "Expected key placeholder starting with '@'"); + if (!buffer_read_u8(in_buf, (uint8_t *) &c)) { + return WITH_ERROR(-1, "Expected key placeholder"); } - uint32_t k; - if (parse_unsigned_decimal(in_buf, &k) == -1 || k > INT16_MAX) { - return WITH_ERROR(-1, "The key index in a placeholder must be at most 32767"); - } + if (c == '@') { + out->type = KEY_EXPRESSION_NORMAL; + + uint32_t k; + if (parse_unsigned_decimal(in_buf, &k) == -1 || k > INT16_MAX) { + return WITH_ERROR(-1, "The key index in a placeholder must be at most 32767"); + } + + out->key_index = (int16_t) k; + } else if (c == 'm') { + // parse a musig(key1,...,keyn) expression, where each key is a key expression + if (!consume_characters(in_buf, "usig(", 5)) { + return WITH_ERROR(-1, "Expected musig key expression"); + } + + if (!is_taproot) { + return WITH_ERROR(-1, "musig is only allows in taproot"); + } + + out->type = KEY_EXPRESSION_MUSIG; + + if (version != WALLET_POLICY_VERSION_V2) { + return WITH_ERROR(-1, "musig key expressions are only supported with version number 2"); + } + + uint16_t key_placeholders[MAX_PUBKEYS_PER_MUSIG]; + int n_musig_keys = 0; + + // parse comma-separated list of @NUM + while (true) { + if (!buffer_read_u8(in_buf, (uint8_t *) &c) || c != '@') { + return WITH_ERROR(-1, "Expected key placeholder starting with '@'"); + } + + uint32_t k; + if (parse_unsigned_decimal(in_buf, &k) == -1 || k > INT16_MAX) { + return WITH_ERROR(-1, "The key index in a placeholder must be at most 32767"); + } - out->key_index = (int16_t) k; + if (n_musig_keys >= MAX_PUBKEYS_PER_MUSIG) { + return WITH_ERROR(-1, "Too many keys in musig"); + } + + key_placeholders[n_musig_keys] = (uint16_t) k; + ++n_musig_keys; + + // the next character must be "," if there are more keys, or ')' otherwise + if (!buffer_read_u8(in_buf, (uint8_t *) &c)) { + return WITH_ERROR(-1, "Expression terminated prematurely"); + } + + if (c == ')') { + break; + } else if (c != ',') { + return WITH_ERROR(-1, "Invalid character in musig; expected ',' or ')'"); + } + } + + if (n_musig_keys < 2) { + return WITH_ERROR(-1, "musig must have at least 2 key indexes"); + } + if (n_musig_keys > MAX_PUBKEYS_PER_MUSIG) { + return WITH_ERROR(-1, "Too many keys in musig"); + } + + // allocate musig structures + + musig_aggr_key_info_t *musig_info = + (musig_aggr_key_info_t *) buffer_alloc(out_buf, sizeof(musig_info), true); + + if (musig_info == NULL) { + return WITH_ERROR(-1, "Out of memory"); + } + + uint16_t *key_indexes = + (uint16_t *) buffer_alloc(out_buf, sizeof(uint16_t) * n_musig_keys, true); + if (key_indexes == NULL) { + return WITH_ERROR(-1, "Out of memory"); + } + memcpy(key_indexes, key_placeholders, sizeof(uint16_t) * n_musig_keys); + + musig_info->n = n_musig_keys; + i_uint16(&musig_info->key_indexes, key_indexes); + + i_musig_aggr_key_info(&out->musig_info, musig_info); + } else { + return WITH_ERROR(-1, "Expected key placeholder starting with '@', or musig"); + } if (version == WALLET_POLICY_VERSION_V1) { // default values for compatibility with the new code @@ -1394,13 +1491,13 @@ static int parse_script(buffer_t *in_buf, return WITH_ERROR(-1, "Out of memory"); } - policy_node_key_placeholder_t *key_placeholder = - buffer_alloc(out_buf, sizeof(policy_node_key_placeholder_t), true); + policy_node_keyexpr_t *key_placeholder = + buffer_alloc(out_buf, sizeof(policy_node_keyexpr_t), true); if (key_placeholder == NULL) { return WITH_ERROR(-1, "Out of memory"); } - i_policy_node_key_placeholder(&node->key_placeholder, key_placeholder); + i_policy_node_keyexpr(&node->key_placeholder, key_placeholder); if (token == TOKEN_WPKH) { if (depth > 0 && ((context_flags & CONTEXT_WITHIN_SH) == 0)) { @@ -1412,7 +1509,13 @@ static int parse_script(buffer_t *in_buf, node->base.type = token; - if (0 > parse_placeholder(in_buf, version, key_placeholder, &key_placeholder_count)) { + bool is_taproot = (context_flags & CONTEXT_WITHIN_TR) != 0; + if (0 > parse_keyexpr(in_buf, + version, + key_placeholder, + is_taproot, + out_buf, + &key_placeholder_count)) { return WITH_ERROR(-1, "Couldn't parse key placeholder"); } @@ -1475,14 +1578,19 @@ static int parse_script(buffer_t *in_buf, return WITH_ERROR(-1, "Out of memory"); } - policy_node_key_placeholder_t *key_placeholder = - buffer_alloc(out_buf, sizeof(policy_node_key_placeholder_t), true); + policy_node_keyexpr_t *key_placeholder = + buffer_alloc(out_buf, sizeof(policy_node_keyexpr_t), true); if (key_placeholder == NULL) { return WITH_ERROR(-1, "Out of memory"); } - i_policy_node_key_placeholder(&node->key_placeholder, key_placeholder); + i_policy_node_keyexpr(&node->key_placeholder, key_placeholder); - if (0 > parse_placeholder(in_buf, version, key_placeholder, &key_placeholder_count)) { + if (0 > parse_keyexpr(in_buf, + version, + key_placeholder, + true, + out_buf, + &key_placeholder_count)) { return WITH_ERROR(-1, "Couldn't parse key placeholder"); } @@ -1559,7 +1667,8 @@ static int parse_script(buffer_t *in_buf, return WITH_ERROR(-1, "Out of memory"); } - if ((context_flags & CONTEXT_WITHIN_TR) != 0) { + bool is_taproot = (context_flags & CONTEXT_WITHIN_TR) != 0; + if (is_taproot) { if (token != TOKEN_MULTI_A && token != TOKEN_SORTEDMULTI_A) { return WITH_ERROR( -1, @@ -1597,7 +1706,7 @@ static int parse_script(buffer_t *in_buf, // We allocate the array of key indices at the current position in the output buffer // (on success) buffer_alloc(out_buf, 0, true); // ensure alignment of current pointer - i_policy_node_key_placeholder(&node->key_placeholders, buffer_get_cur(out_buf)); + i_policy_node_keyexpr(&node->key_placeholders, buffer_get_cur(out_buf)); node->n = 0; while (true) { @@ -1612,18 +1721,21 @@ static int parse_script(buffer_t *in_buf, return WITH_ERROR(-1, "Expected ','"); } - policy_node_key_placeholder_t *key_placeholder = - (policy_node_key_placeholder_t *) buffer_alloc( - out_buf, - sizeof(policy_node_key_placeholder_t), - true); // we align this pointer, as there's padding in an array of - // structures + policy_node_keyexpr_t *key_placeholder = (policy_node_keyexpr_t *) buffer_alloc( + out_buf, + sizeof(policy_node_keyexpr_t), + true); // we align this pointer, as there's padding in an array of + // structures if (key_placeholder == NULL) { return WITH_ERROR(-1, "Out of memory"); } - if (0 > - parse_placeholder(in_buf, version, key_placeholder, &key_placeholder_count)) { + if (0 > parse_keyexpr(in_buf, + version, + key_placeholder, + is_taproot, + out_buf, + &key_placeholder_count)) { return WITH_ERROR(-1, "Error parsing key placeholder"); } diff --git a/src/common/wallet.h b/src/common/wallet.h index 219111ad1..eff17d2a9 100644 --- a/src/common/wallet.h +++ b/src/common/wallet.h @@ -19,6 +19,10 @@ // bitcoin-core supports up to 20, but we limit to 16 as bigger pushes require special handling. #define MAX_PUBKEYS_PER_MULTISIG 16 +// The maximum number of keys supported in a musig() key expression +// It is basically unlimited in theory, but we need to set a practical limit. +#define MAX_PUBKEYS_PER_MUSIG MAX_PUBKEYS_PER_MULTISIG + #define WALLET_POLICY_VERSION_V1 1 // the legacy version of the first release #define WALLET_POLICY_VERSION_V2 2 // the current full version @@ -292,19 +296,39 @@ typedef struct policy_node_ext_info_s { * array don't have extra derivation steps. */ #pragma GCC diagnostic pop -// 12 bytes + +DEFINE_REL_PTR(uint16, uint16_t) + +typedef struct { + int16_t n; // number of key indexes + rptr_uint16_t key_indexes; // pointer to an array of exactly n key indexes +} musig_aggr_key_info_t; + +DEFINE_REL_PTR(musig_aggr_key_info, musig_aggr_key_info_t) + +typedef enum { + KEY_EXPRESSION_NORMAL = 0, // a key expression with a single key placeholder + KEY_EXPRESSION_MUSIG = 1 // a key expression containing a musig() +} KeyExpressionType; + +// 16 bytes typedef struct { // the following fields are only used in V2 uint32_t num_first; // NUM_a of //* uint32_t num_second; // NUM_b of //* - // common between V1 and V2 - int16_t key_index; // index of the key + KeyExpressionType type; + union { + // type == 0 + int16_t key_index; // index of the key (common between V1 and V2) + // type == 1 + rptr_musig_aggr_key_info_t musig_info; // only used in V2 + }; int16_t placeholder_index; // index of the placeholder in the descriptor template, in parsing order -} policy_node_key_placeholder_t; +} policy_node_keyexpr_t; -DEFINE_REL_PTR(policy_node_key_placeholder, policy_node_key_placeholder_t) +DEFINE_REL_PTR(policy_node_keyexpr, policy_node_keyexpr_t) // 4 bytes typedef struct { @@ -335,7 +359,7 @@ typedef policy_node_with_script3_t policy_node_with_scripts_t; // 4 bytes typedef struct { struct policy_node_s base; - rptr_policy_node_key_placeholder_t key_placeholder; + rptr_policy_node_keyexpr_t key_placeholder; } policy_node_with_key_t; // 8 bytes @@ -346,11 +370,10 @@ typedef struct { // 12 bytes typedef struct { - struct policy_node_s base; // type is TOKEN_MULTI or TOKEN_SORTEDMULTI - int16_t k; // threshold - int16_t n; // number of keys - rptr_policy_node_key_placeholder_t - key_placeholders; // pointer to array of exactly n key placeholders + struct policy_node_s base; // type is TOKEN_MULTI or TOKEN_SORTEDMULTI + int16_t k; // threshold + int16_t n; // number of keys + rptr_policy_node_keyexpr_t key_placeholders; // pointer to array of exactly n key placeholders } policy_node_multisig_t; // 8 bytes @@ -400,7 +423,7 @@ typedef struct policy_node_tree_s { typedef struct { struct policy_node_s base; - rptr_policy_node_key_placeholder_t key_placeholder; + rptr_policy_node_keyexpr_t key_placeholder; rptr_policy_node_tree_t tree; // NULL if tr(KP) } policy_node_tr_t; diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index 63c8e61a7..ae289fadc 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -456,7 +456,7 @@ __attribute__((noinline, warn_unused_result)) static int get_extended_pubkey( __attribute__((warn_unused_result)) static int get_derived_pubkey( dispatcher_context_t *dispatcher_context, const wallet_derivation_info_t *wdi, - const policy_node_key_placeholder_t *key_placeholder, + const policy_node_keyexpr_t *key_placeholder, uint8_t out[static 33]) { PRINT_STACK_POINTER(); @@ -575,11 +575,10 @@ __attribute__((warn_unused_result)) static int process_generic_node(policy_parse const policy_node_with_key_t *policy = (const policy_node_with_key_t *) node->policy_node; uint8_t compressed_pubkey[33]; - if (-1 == - get_derived_pubkey(state->dispatcher_context, - state->wdi, - r_policy_node_key_placeholder(&policy->key_placeholder), - compressed_pubkey)) { + if (-1 == get_derived_pubkey(state->dispatcher_context, + state->wdi, + r_policy_node_keyexpr(&policy->key_placeholder), + compressed_pubkey)) { return -1; } @@ -597,11 +596,10 @@ __attribute__((warn_unused_result)) static int process_generic_node(policy_parse const policy_node_with_key_t *policy = (const policy_node_with_key_t *) node->policy_node; uint8_t compressed_pubkey[33]; - if (-1 == - get_derived_pubkey(state->dispatcher_context, - state->wdi, - r_policy_node_key_placeholder(&policy->key_placeholder), - compressed_pubkey)) { + if (-1 == get_derived_pubkey(state->dispatcher_context, + state->wdi, + r_policy_node_keyexpr(&policy->key_placeholder), + compressed_pubkey)) { return -1; } if (!state->is_taproot) { @@ -690,7 +688,7 @@ __attribute__((warn_unused_result)) static int process_pkh_wpkh_node(policy_pars if (-1 == get_derived_pubkey(state->dispatcher_context, state->wdi, - r_policy_node_key_placeholder(&policy->key_placeholder), + r_policy_node_keyexpr(&policy->key_placeholder), compressed_pubkey)) { return -1; } else if (policy->base.type == TOKEN_PKH) { @@ -817,11 +815,10 @@ __attribute__((warn_unused_result)) static int process_multi_sortedmulti_node( uint8_t compressed_pubkey[33]; if (policy->base.type == TOKEN_MULTI) { - if (-1 == - get_derived_pubkey(state->dispatcher_context, - state->wdi, - &r_policy_node_key_placeholder(&policy->key_placeholders)[i], - compressed_pubkey)) { + if (-1 == get_derived_pubkey(state->dispatcher_context, + state->wdi, + &r_policy_node_keyexpr(&policy->key_placeholders)[i], + compressed_pubkey)) { return -1; } } else { @@ -843,11 +840,11 @@ __attribute__((warn_unused_result)) static int process_multi_sortedmulti_node( for (int j = 0; j < policy->n; j++) { if (!bitvector_get(used, j)) { uint8_t cur_pubkey[33]; - if (-1 == get_derived_pubkey( - state->dispatcher_context, - state->wdi, - &r_policy_node_key_placeholder(&policy->key_placeholders)[j], - cur_pubkey)) { + if (-1 == + get_derived_pubkey(state->dispatcher_context, + state->wdi, + &r_policy_node_keyexpr(&policy->key_placeholders)[j], + cur_pubkey)) { return -1; } @@ -895,11 +892,10 @@ __attribute__((warn_unused_result)) static int process_multi_a_sortedmulti_a_nod uint8_t compressed_pubkey[33]; if (policy->base.type == TOKEN_MULTI_A) { - if (-1 == - get_derived_pubkey(state->dispatcher_context, - state->wdi, - &r_policy_node_key_placeholder(&policy->key_placeholders)[i], - compressed_pubkey)) { + if (-1 == get_derived_pubkey(state->dispatcher_context, + state->wdi, + &r_policy_node_keyexpr(&policy->key_placeholders)[i], + compressed_pubkey)) { return -1; } } else { @@ -911,11 +907,11 @@ __attribute__((warn_unused_result)) static int process_multi_a_sortedmulti_a_nod for (int j = 0; j < policy->n; j++) { if (!bitvector_get(used, j)) { uint8_t cur_pubkey[33]; - if (-1 == get_derived_pubkey( - state->dispatcher_context, - state->wdi, - &r_policy_node_key_placeholder(&policy->key_placeholders)[j], - cur_pubkey)) { + if (-1 == + get_derived_pubkey(state->dispatcher_context, + state->wdi, + &r_policy_node_keyexpr(&policy->key_placeholders)[j], + cur_pubkey)) { return -1; } @@ -1024,7 +1020,7 @@ int get_wallet_script(dispatcher_context_t *dispatcher_context, policy_node_with_key_t *pkh_policy = (policy_node_with_key_t *) policy; if (0 > get_derived_pubkey(dispatcher_context, wdi, - r_policy_node_key_placeholder(&pkh_policy->key_placeholder), + r_policy_node_keyexpr(&pkh_policy->key_placeholder), compressed_pubkey)) { return -1; } @@ -1043,7 +1039,7 @@ int get_wallet_script(dispatcher_context_t *dispatcher_context, policy_node_with_key_t *wpkh_policy = (policy_node_with_key_t *) policy; if (0 > get_derived_pubkey(dispatcher_context, wdi, - r_policy_node_key_placeholder(&wpkh_policy->key_placeholder), + r_policy_node_keyexpr(&wpkh_policy->key_placeholder), compressed_pubkey)) { return -1; } @@ -1122,7 +1118,7 @@ int get_wallet_script(dispatcher_context_t *dispatcher_context, if (0 > get_derived_pubkey(dispatcher_context, wdi, - r_policy_node_key_placeholder(&tr_policy->key_placeholder), + r_policy_node_keyexpr(&tr_policy->key_placeholder), compressed_pubkey)) { return -1; } @@ -1350,16 +1346,16 @@ __attribute__((noinline)) int get_wallet_internal_script_hash( // For a standard descriptor template, return the corresponding BIP44 purpose // Otherwise, returns -1. static int get_bip44_purpose(const policy_node_t *descriptor_template) { - const policy_node_key_placeholder_t *kp = NULL; + const policy_node_keyexpr_t *kp = NULL; int purpose = -1; switch (descriptor_template->type) { case TOKEN_PKH: - kp = r_policy_node_key_placeholder( + kp = r_policy_node_keyexpr( &((const policy_node_with_key_t *) descriptor_template)->key_placeholder); purpose = 44; // legacy break; case TOKEN_WPKH: - kp = r_policy_node_key_placeholder( + kp = r_policy_node_keyexpr( &((const policy_node_with_key_t *) descriptor_template)->key_placeholder); purpose = 84; // native segwit break; @@ -1370,8 +1366,7 @@ static int get_bip44_purpose(const policy_node_t *descriptor_template) { return -1; } - kp = r_policy_node_key_placeholder( - &((const policy_node_with_key_t *) inner)->key_placeholder); + kp = r_policy_node_keyexpr(&((const policy_node_with_key_t *) inner)->key_placeholder); purpose = 49; // nested segwit break; } @@ -1381,7 +1376,7 @@ static int get_bip44_purpose(const policy_node_t *descriptor_template) { return -1; } - kp = r_policy_node_key_placeholder( + kp = r_policy_node_keyexpr( &((const policy_node_tr_t *) descriptor_template)->key_placeholder); purpose = 86; // standard single-key P2TR break; @@ -1522,7 +1517,7 @@ bool check_wallet_hmac(const uint8_t wallet_id[static 32], const uint8_t wallet_ static int get_key_placeholder_by_index_in_tree(const policy_node_tree_t *tree, unsigned int i, const policy_node_t **out_tapleaf_ptr, - policy_node_key_placeholder_t *out_placeholder) { + policy_node_keyexpr_t *out_placeholder) { if (tree->is_leaf) { int ret = get_key_placeholder_by_index(r_policy_node(&tree->script), i, NULL, out_placeholder); @@ -1552,9 +1547,9 @@ static int get_key_placeholder_by_index_in_tree(const policy_node_tree_t *tree, int get_key_placeholder_by_index(const policy_node_t *policy, unsigned int i, const policy_node_t **out_tapleaf_ptr, - policy_node_key_placeholder_t *out_placeholder) { + policy_node_keyexpr_t *out_placeholder) { // make sure that out_placeholder is a valid pointer, if the output is not needed - policy_node_key_placeholder_t tmp; + policy_node_keyexpr_t tmp; if (out_placeholder == NULL) { out_placeholder = &tmp; } @@ -1580,8 +1575,8 @@ int get_key_placeholder_by_index(const policy_node_t *policy, if (i == 0) { policy_node_with_key_t *wpkh = (policy_node_with_key_t *) policy; memcpy(out_placeholder, - r_policy_node_key_placeholder(&wpkh->key_placeholder), - sizeof(policy_node_key_placeholder_t)); + r_policy_node_keyexpr(&wpkh->key_placeholder), + sizeof(policy_node_keyexpr_t)); } return 1; } @@ -1589,8 +1584,8 @@ int get_key_placeholder_by_index(const policy_node_t *policy, policy_node_tr_t *tr = (policy_node_tr_t *) policy; if (i == 0) { memcpy(out_placeholder, - r_policy_node_key_placeholder(&tr->key_placeholder), - sizeof(policy_node_key_placeholder_t)); + r_policy_node_keyexpr(&tr->key_placeholder), + sizeof(policy_node_keyexpr_t)); } if (!isnull_policy_node_tree(&tr->tree)) { int ret_tree = get_key_placeholder_by_index_in_tree( @@ -1616,9 +1611,9 @@ int get_key_placeholder_by_index(const policy_node_t *policy, const policy_node_multisig_t *node = (const policy_node_multisig_t *) policy; if (i < (unsigned int) node->n) { - policy_node_key_placeholder_t *placeholders = - r_policy_node_key_placeholder(&node->key_placeholders); - memcpy(out_placeholder, &placeholders[i], sizeof(policy_node_key_placeholder_t)); + policy_node_keyexpr_t *placeholders = + r_policy_node_keyexpr(&node->key_placeholders); + memcpy(out_placeholder, &placeholders[i], sizeof(policy_node_keyexpr_t)); } return node->n; @@ -1737,7 +1732,7 @@ int count_distinct_keys_info(const policy_node_t *policy) { } for (int cur = 0; cur < n_placeholders; ++cur) { - policy_node_key_placeholder_t placeholder; + policy_node_keyexpr_t placeholder; if (0 > get_key_placeholder_by_index(policy, cur, NULL, &placeholder)) { return -1; } @@ -1928,12 +1923,12 @@ int is_policy_sane(dispatcher_context_t *dispatcher_context, // proportional to the depth of the wallet policy's abstract syntax tree. for (int i = 0; i < n_placeholders - 1; i++) { // no point in running this for the last placeholder - policy_node_key_placeholder_t kp_i; + policy_node_keyexpr_t kp_i; if (0 > get_key_placeholder_by_index(policy, i, NULL, &kp_i)) { return WITH_ERROR(-1, "Unexpected error retrieving placeholders from the policy"); } for (int j = i + 1; j < n_placeholders; j++) { - policy_node_key_placeholder_t kp_j; + policy_node_keyexpr_t kp_j; if (0 > get_key_placeholder_by_index(policy, j, NULL, &kp_j)) { return WITH_ERROR(-1, "Unexpected error retrieving placeholders from the policy"); } diff --git a/src/handler/lib/policy.h b/src/handler/lib/policy.h index ad9f897b3..68ac71d5a 100644 --- a/src/handler/lib/policy.h +++ b/src/handler/lib/policy.h @@ -197,7 +197,7 @@ __attribute__((warn_unused_result)) int get_key_placeholder_by_index( const policy_node_t *policy, unsigned int i, const policy_node_t **out_tapleaf_ptr, - policy_node_key_placeholder_t *out_placeholder); + policy_node_keyexpr_t *out_placeholder); /** * Determines the expected number of unique keys in the provided policy's key information. diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 419d6dbee..1b8a4ae62 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -106,7 +106,7 @@ typedef struct { } output_info_t; typedef struct { - policy_node_key_placeholder_t placeholder; + policy_node_keyexpr_t placeholder; int cur_index; uint32_t fingerprint; uint8_t key_derivation_length; diff --git a/src/handler/sign_psbt/sign_psbt_cache.c b/src/handler/sign_psbt/sign_psbt_cache.c index c89f17af2..30803afaa 100644 --- a/src/handler/sign_psbt/sign_psbt_cache.c +++ b/src/handler/sign_psbt/sign_psbt_cache.c @@ -1,7 +1,7 @@ #include "sign_psbt_cache.h" int derive_first_step_for_pubkey(const serialized_extended_pubkey_t *base_key, - const policy_node_key_placeholder_t *placeholder, + const policy_node_keyexpr_t *placeholder, sign_psbt_cache_t *cache, bool is_change, serialized_extended_pubkey_t *out_pubkey) { diff --git a/src/handler/sign_psbt/sign_psbt_cache.h b/src/handler/sign_psbt/sign_psbt_cache.h index e0c7b38d5..5baf44ecd 100644 --- a/src/handler/sign_psbt/sign_psbt_cache.h +++ b/src/handler/sign_psbt/sign_psbt_cache.h @@ -53,7 +53,7 @@ number of BIP-32 derivations is cut almost by half when using the cache. * @return 0 on success, -1 on failure. */ int derive_first_step_for_pubkey(const serialized_extended_pubkey_t *base_key, - const policy_node_key_placeholder_t *placeholder, + const policy_node_keyexpr_t *placeholder, sign_psbt_cache_t *cache, bool is_change, serialized_extended_pubkey_t *out_pubkey); \ No newline at end of file diff --git a/unit-tests/test_wallet.c b/unit-tests/test_wallet.c index 975545487..c330f430e 100644 --- a/unit-tests/test_wallet.c +++ b/unit-tests/test_wallet.c @@ -32,16 +32,35 @@ static int parse_policy(const char *descriptor_template, uint8_t *out, size_t ou // about half of the memory would be needed #define MAX_WALLET_POLICY_MEMORY_SIZE 512 -// convenience function to compactly check common assertions on a key placeholder pointer -static void check_key_placeholder(const policy_node_key_placeholder_t *ptr, - int key_index, - uint32_t num_first, - uint32_t num_second) { +// convenience function to compactly check common assertions on a pointer to a key expression with a +// single placeholder +static void check_key_expr_plain(const policy_node_keyexpr_t *ptr, + int key_index, + uint32_t num_first, + uint32_t num_second) { + assert_int_equal(ptr->type, KEY_EXPRESSION_NORMAL); assert_int_equal(ptr->key_index, key_index); assert_int_equal(ptr->num_first, num_first); assert_int_equal(ptr->num_second, num_second); } +// convenience function to compactly check assertions on a pointer to a key expression with a musig +static void check_key_expr_musig(const policy_node_keyexpr_t *ptr, + int n_musig_keys, + const uint16_t *key_indices, + uint32_t num_first, + uint32_t num_second) { + assert_int_equal(ptr->type, KEY_EXPRESSION_MUSIG); + musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&ptr->musig_info); + assert_int_equal(musig_info->n, n_musig_keys); + uint16_t *musig_key_indexes = r_uint16(&musig_info->key_indexes); + for (int i = 0; i < n_musig_keys; i++) { + assert_int_equal(musig_key_indexes[i], key_indices[i]); + } + assert_int_equal(ptr->num_first, num_first); + assert_int_equal(ptr->num_second, num_second); +} + static void test_parse_policy_map_singlesig_1(void **state) { (void) state; @@ -53,7 +72,7 @@ static void test_parse_policy_map_singlesig_1(void **state) { policy_node_with_key_t *node_1 = (policy_node_with_key_t *) out; assert_int_equal(node_1->base.type, TOKEN_PKH); - check_key_placeholder(r_policy_node_key_placeholder(&node_1->key_placeholder), 0, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&node_1->key_placeholder), 0, 0, 1); } static void test_parse_policy_map_singlesig_2(void **state) { @@ -71,7 +90,7 @@ static void test_parse_policy_map_singlesig_2(void **state) { policy_node_with_key_t *inner = (policy_node_with_key_t *) r_policy_node(&root->script); assert_int_equal(inner->base.type, TOKEN_WPKH); - check_key_placeholder(r_policy_node_key_placeholder(&inner->key_placeholder), 0, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&inner->key_placeholder), 0, 0, 1); } static void test_parse_policy_map_singlesig_3(void **state) { @@ -93,7 +112,7 @@ static void test_parse_policy_map_singlesig_3(void **state) { policy_node_with_key_t *inner = (policy_node_with_key_t *) r_policy_node(&mid->script); assert_int_equal(inner->base.type, TOKEN_PKH); - check_key_placeholder(r_policy_node_key_placeholder(&inner->key_placeholder), 0, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&inner->key_placeholder), 0, 0, 1); } static void test_parse_policy_map_multisig_1(void **state) { @@ -109,9 +128,9 @@ static void test_parse_policy_map_multisig_1(void **state) { assert_int_equal(node_1->base.type, TOKEN_SORTEDMULTI); assert_int_equal(node_1->k, 2); assert_int_equal(node_1->n, 3); - check_key_placeholder(&r_policy_node_key_placeholder(&node_1->key_placeholders)[0], 0, 0, 1); - check_key_placeholder(&r_policy_node_key_placeholder(&node_1->key_placeholders)[1], 1, 0, 1); - check_key_placeholder(&r_policy_node_key_placeholder(&node_1->key_placeholders)[2], 2, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&node_1->key_placeholders)[0], 0, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&node_1->key_placeholders)[1], 1, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&node_1->key_placeholders)[2], 2, 0, 1); } static void test_parse_policy_map_multisig_2(void **state) { @@ -132,7 +151,7 @@ static void test_parse_policy_map_multisig_2(void **state) { assert_int_equal(inner->k, 3); assert_int_equal(inner->n, 5); for (int i = 0; i < 5; i++) { - check_key_placeholder(&r_policy_node_key_placeholder(&inner->key_placeholders)[i], i, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&inner->key_placeholders)[i], i, 0, 1); } } @@ -158,7 +177,7 @@ static void test_parse_policy_map_multisig_3(void **state) { assert_int_equal(inner->k, 3); assert_int_equal(inner->n, 5); for (int i = 0; i < 5; i++) { - check_key_placeholder(&r_policy_node_key_placeholder(&inner->key_placeholders)[i], i, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&inner->key_placeholders)[i], i, 0, 1); } } @@ -175,7 +194,7 @@ static void test_parse_policy_tr(void **state) { policy_node_tr_t *root = (policy_node_tr_t *) out; assert_true(isnull_policy_node_tree(&root->tree)); - check_key_placeholder(r_policy_node_key_placeholder(&root->key_placeholder), 0, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&root->key_placeholder), 0, 0, 1); // Simple tr with a TREE that is a simple script res = parse_policy("tr(@0/**,pk(@1/**))", out, sizeof(out)); @@ -183,7 +202,7 @@ static void test_parse_policy_tr(void **state) { assert_true(res >= 0); root = (policy_node_tr_t *) out; - check_key_placeholder(r_policy_node_key_placeholder(&root->key_placeholder), 0, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&root->key_placeholder), 0, 0, 1); assert_int_equal(r_policy_node_tree(&root->tree)->is_leaf, true); @@ -191,7 +210,7 @@ static void test_parse_policy_tr(void **state) { (policy_node_with_key_t *) r_policy_node(&r_policy_node_tree(&root->tree)->script); assert_int_equal(tapscript->base.type, TOKEN_PK); - check_key_placeholder(r_policy_node_key_placeholder(&tapscript->key_placeholder), 1, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&tapscript->key_placeholder), 1, 0, 1); // Simple tr with a TREE with two tapleaves res = parse_policy("tr(@0/**,{pk(@1/**),pk(@2/<5;7>/*)})", out, sizeof(out)); @@ -199,7 +218,7 @@ static void test_parse_policy_tr(void **state) { assert_true(res >= 0); root = (policy_node_tr_t *) out; - check_key_placeholder(r_policy_node_key_placeholder(&root->key_placeholder), 0, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&root->key_placeholder), 0, 0, 1); policy_node_tree_t *taptree = r_policy_node_tree(&root->tree); @@ -212,7 +231,7 @@ static void test_parse_policy_tr(void **state) { (policy_node_with_key_t *) r_policy_node(&taptree_left->script); assert_int_equal(tapscript_left->base.type, TOKEN_PK); - check_key_placeholder(r_policy_node_key_placeholder(&tapscript_left->key_placeholder), 1, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&tapscript_left->key_placeholder), 1, 0, 1); policy_node_tree_t *taptree_right = (policy_node_tree_t *) r_policy_node_tree(&taptree->right_tree); @@ -221,10 +240,7 @@ static void test_parse_policy_tr(void **state) { (policy_node_with_key_t *) r_policy_node(&taptree_right->script); assert_int_equal(tapscript_right->base.type, TOKEN_PK); - check_key_placeholder(r_policy_node_key_placeholder(&tapscript_right->key_placeholder), - 2, - 5, - 7); + check_key_expr_plain(r_policy_node_keyexpr(&tapscript_right->key_placeholder), 2, 5, 7); } static void test_parse_policy_tr_multisig(void **state) { @@ -242,9 +258,9 @@ static void test_parse_policy_tr_multisig(void **state) { policy_node_tr_t *root = (policy_node_tr_t *) out; - assert_int_equal(r_policy_node_key_placeholder(&root->key_placeholder)->key_index, 0); - assert_int_equal(r_policy_node_key_placeholder(&root->key_placeholder)->num_first, 0); - assert_int_equal(r_policy_node_key_placeholder(&root->key_placeholder)->num_second, 1); + assert_int_equal(r_policy_node_keyexpr(&root->key_placeholder)->key_index, 0); + assert_int_equal(r_policy_node_keyexpr(&root->key_placeholder)->num_first, 0); + assert_int_equal(r_policy_node_keyexpr(&root->key_placeholder)->num_second, 1); policy_node_tree_t *taptree = r_policy_node_tree(&root->tree); @@ -259,14 +275,8 @@ static void test_parse_policy_tr_multisig(void **state) { assert_int_equal(tapscript_left->base.type, TOKEN_MULTI_A); assert_int_equal(tapscript_left->k, 1); assert_int_equal(tapscript_left->n, 2); - check_key_placeholder(&r_policy_node_key_placeholder(&tapscript_left->key_placeholders)[0], - 1, - 0, - 1); - check_key_placeholder(&r_policy_node_key_placeholder(&tapscript_left->key_placeholders)[1], - 2, - 0, - 1); + check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_left->key_placeholders)[0], 1, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_left->key_placeholders)[1], 2, 0, 1); policy_node_tree_t *taptree_right = (policy_node_tree_t *) r_policy_node_tree(&taptree->right_tree); @@ -277,18 +287,58 @@ static void test_parse_policy_tr_multisig(void **state) { assert_int_equal(tapscript_right->base.type, TOKEN_SORTEDMULTI_A); assert_int_equal(tapscript_right->k, 2); assert_int_equal(tapscript_right->n, 3); - check_key_placeholder(&r_policy_node_key_placeholder(&tapscript_right->key_placeholders)[0], - 3, - 0, - 1); - check_key_placeholder(&r_policy_node_key_placeholder(&tapscript_right->key_placeholders)[1], - 4, - 0, - 1); - check_key_placeholder(&r_policy_node_key_placeholder(&tapscript_right->key_placeholders)[2], - 5, - 0, - 1); + check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_right->key_placeholders)[0], 3, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_right->key_placeholders)[1], 4, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_right->key_placeholders)[2], 5, 0, 1); +} + +static void test_parse_policy_tr_musig_keypath(void **state) { + (void) state; + + uint8_t out[MAX_WALLET_POLICY_MEMORY_SIZE]; + int res; + + res = parse_policy("tr(musig(@2,@0,@1)/<3;13>/*)", out, sizeof(out)); + + assert_true(res >= 0); + + policy_node_tr_t *root = (policy_node_tr_t *) out; + assert_int_equal(root->base.type, TOKEN_TR); + assert_true(isnull_policy_node_tree(&root->tree)); + + check_key_expr_musig(r_policy_node_keyexpr(&root->key_placeholder), + 3, + (uint16_t[]){2, 0, 1}, + 3, + 13); +} + +static void test_parse_policy_tr_musig_scriptpath(void **state) { + (void) state; + + uint8_t out[MAX_WALLET_POLICY_MEMORY_SIZE]; + int res; + + // tr with a musig in the script path + res = parse_policy("tr(@1/**,pk(musig(@2,@0,@3)/**))", out, sizeof(out)); + + assert_true(res >= 0); + + policy_node_tr_t *root = (policy_node_tr_t *) out; + assert_int_equal(root->base.type, TOKEN_TR); + + assert_false(isnull_policy_node_tree(&root->tree)); + policy_node_tree_t *tree = r_policy_node_tree(&root->tree); + assert_true(tree->is_leaf); + + policy_node_with_key_t *script_pk = (policy_node_with_key_t *) r_policy_node(&tree->script); + assert_int_equal(script_pk->base.type, TOKEN_PK); + + check_key_expr_musig(r_policy_node_keyexpr(&script_pk->key_placeholder), + 3, + (uint16_t[]){2, 0, 3}, + 0, + 1); } static void test_get_policy_segwit_version(void **state) { @@ -377,6 +427,14 @@ static void test_failures(void **state) { assert_true(0 > parse_policy("tr(@0/**,sortedmulti(2,@1,@2))", out, sizeof(out))); assert_true(0 > parse_policy("tr(@0/**,sh(pk(@0/**)))", out, sizeof(out))); assert_true(0 > parse_policy("tr(@0/**,wsh(pk(@0/**)))", out, sizeof(out))); + + // invalid usages of musig expressions + assert_true(0 > parse_policy("tr(musig(@0,@1))", out, sizeof(out))); // missing derivations + assert_true(0 > parse_policy("tr(musig()/**)", out, sizeof(out))); // empty musig + assert_true(0 > parse_policy("tr(musig(@0)/**)", out, sizeof(out))); // needs at least two keys + assert_true(0 > parse_policy("wpkh(musig(@0,@1)/**)", out, sizeof(out))); // not taproot + assert_true( + 0 > parse_policy("tr(musig(@0,musig(@1,@2))/**)", out, sizeof(out))); // can't nest musig } enum TestMode { From 5efbc36aadf1ec3e19db7f17aaded2cb333d2542 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 8 Oct 2024 18:38:45 +0200 Subject: [PATCH 02/57] Rename "key placeholder" with "key expression" where appropriate; added some comments. Generalizing to key expressions containing musig() makes it necessary to distinguish the key expressions in the wallet policy from the actual key placeholders that are just indexes to the list of key informations (@num in the descriptor template), whereas the two concepts were often not clearly separated in the code base. Renaming to "key expressions" makes the distinction more clear. --- src/common/wallet.c | 74 +++--- src/common/wallet.h | 41 ++-- src/handler/lib/policy.c | 212 +++++++++-------- src/handler/lib/policy.h | 31 ++- src/handler/sign_psbt.c | 294 ++++++++++++------------ src/handler/sign_psbt/sign_psbt_cache.c | 22 +- src/handler/sign_psbt/sign_psbt_cache.h | 10 +- unit-tests/test_wallet.c | 58 ++--- 8 files changed, 357 insertions(+), 385 deletions(-) diff --git a/src/common/wallet.c b/src/common/wallet.c index dccb20251..628d1277a 100644 --- a/src/common/wallet.c +++ b/src/common/wallet.c @@ -444,10 +444,10 @@ static int parse_keyexpr(buffer_t *in_buf, policy_node_keyexpr_t *out, bool is_taproot, buffer_t *out_buf, - uint16_t *placeholder_index) { + uint16_t *keyexpr_index) { char c; if (!buffer_read_u8(in_buf, (uint8_t *) &c)) { - return WITH_ERROR(-1, "Expected key placeholder"); + return WITH_ERROR(-1, "Expected key expression"); } if (c == '@') { @@ -475,7 +475,7 @@ static int parse_keyexpr(buffer_t *in_buf, return WITH_ERROR(-1, "musig key expressions are only supported with version number 2"); } - uint16_t key_placeholders[MAX_PUBKEYS_PER_MUSIG]; + uint16_t keys[MAX_PUBKEYS_PER_MUSIG]; int n_musig_keys = 0; // parse comma-separated list of @NUM @@ -493,7 +493,7 @@ static int parse_keyexpr(buffer_t *in_buf, return WITH_ERROR(-1, "Too many keys in musig"); } - key_placeholders[n_musig_keys] = (uint16_t) k; + keys[n_musig_keys] = (uint16_t) k; ++n_musig_keys; // the next character must be "," if there are more keys, or ')' otherwise @@ -529,14 +529,14 @@ static int parse_keyexpr(buffer_t *in_buf, if (key_indexes == NULL) { return WITH_ERROR(-1, "Out of memory"); } - memcpy(key_indexes, key_placeholders, sizeof(uint16_t) * n_musig_keys); + memcpy(key_indexes, keys, sizeof(uint16_t) * n_musig_keys); musig_info->n = n_musig_keys; i_uint16(&musig_info->key_indexes, key_indexes); i_musig_aggr_key_info(&out->musig_info, musig_info); } else { - return WITH_ERROR(-1, "Expected key placeholder starting with '@', or musig"); + return WITH_ERROR(-1, "Expected key expression starting with '@', or musig"); } if (version == WALLET_POLICY_VERSION_V1) { @@ -550,12 +550,12 @@ static int parse_keyexpr(buffer_t *in_buf, || !buffer_peek(in_buf, &next_character) // we must be able to read the next character || !(next_character == '*' || next_character == '<') // and it must be '*' or '<' ) { - return WITH_ERROR(-1, "Expected /** or //* in key placeholder"); + return WITH_ERROR(-1, "Expected /** or //* in key expression"); } if (next_character == '*') { if (!consume_characters(in_buf, "**", 2)) { - return WITH_ERROR(-1, "Expected /** or //* in key placeholder"); + return WITH_ERROR(-1, "Expected /** or //* in key expression"); } out->num_first = 0; out->num_second = 1; @@ -565,18 +565,18 @@ static int parse_keyexpr(buffer_t *in_buf, out->num_first > 0x80000000u) { return WITH_ERROR( -1, - "Expected /** or //* in key placeholder, with unhardened M and N"); + "Expected /** or //* in key expression, with unhardened M and N"); } if (!consume_character(in_buf, ';')) { - return WITH_ERROR(-1, "Expected /** or //* in key placeholder"); + return WITH_ERROR(-1, "Expected /** or //* in key expression"); } if (parse_unsigned_decimal(in_buf, &out->num_second) == -1 || out->num_second > 0x80000000u) { return WITH_ERROR( -1, - "Expected /** or //* in key placeholder, with unhardened M and N"); + "Expected /** or //* in key expression, with unhardened M and N"); } if (out->num_first == out->num_second) { @@ -584,15 +584,15 @@ static int parse_keyexpr(buffer_t *in_buf, } if (!consume_characters(in_buf, ">/*", 3)) { - return WITH_ERROR(-1, "Expected /** or //* in key placeholder"); + return WITH_ERROR(-1, "Expected /** or //* in key expression"); } } } else { return WITH_ERROR(-1, "Invalid version number"); } - out->placeholder_index = *placeholder_index; - ++(*placeholder_index); + out->keyexpr_index = *keyexpr_index; + ++(*keyexpr_index); return 0; } @@ -648,13 +648,13 @@ static int parse_script(buffer_t *in_buf, unsigned int context_flags) { int n_wrappers = 0; - // Keep track of how many key placeholders have been created while parsing + // Keep track of how many key expressions have been created while parsing // This allows to know the counter even in recursive calls - static uint16_t key_placeholder_count = 0; + static uint16_t key_expression_count = 0; if (depth == 0) { // reset the counter on function entry, but not in recursive calls - key_placeholder_count = 0; + key_expression_count = 0; } policy_node_t *outermost_node = (policy_node_t *) buffer_get_cur(out_buf); @@ -1491,13 +1491,13 @@ static int parse_script(buffer_t *in_buf, return WITH_ERROR(-1, "Out of memory"); } - policy_node_keyexpr_t *key_placeholder = + policy_node_keyexpr_t *key_expr = buffer_alloc(out_buf, sizeof(policy_node_keyexpr_t), true); - if (key_placeholder == NULL) { + if (key_expr == NULL) { return WITH_ERROR(-1, "Out of memory"); } - i_policy_node_keyexpr(&node->key_placeholder, key_placeholder); + i_policy_node_keyexpr(&node->key, key_expr); if (token == TOKEN_WPKH) { if (depth > 0 && ((context_flags & CONTEXT_WITHIN_SH) == 0)) { @@ -1512,11 +1512,11 @@ static int parse_script(buffer_t *in_buf, bool is_taproot = (context_flags & CONTEXT_WITHIN_TR) != 0; if (0 > parse_keyexpr(in_buf, version, - key_placeholder, + key_expr, is_taproot, out_buf, - &key_placeholder_count)) { - return WITH_ERROR(-1, "Couldn't parse key placeholder"); + &key_expression_count)) { + return WITH_ERROR(-1, "Couldn't parse key expression"); } if (token == TOKEN_WPKH) { @@ -1578,20 +1578,16 @@ static int parse_script(buffer_t *in_buf, return WITH_ERROR(-1, "Out of memory"); } - policy_node_keyexpr_t *key_placeholder = + policy_node_keyexpr_t *key_expr = buffer_alloc(out_buf, sizeof(policy_node_keyexpr_t), true); - if (key_placeholder == NULL) { + if (key_expr == NULL) { return WITH_ERROR(-1, "Out of memory"); } - i_policy_node_keyexpr(&node->key_placeholder, key_placeholder); + i_policy_node_keyexpr(&node->key, key_expr); - if (0 > parse_keyexpr(in_buf, - version, - key_placeholder, - true, - out_buf, - &key_placeholder_count)) { - return WITH_ERROR(-1, "Couldn't parse key placeholder"); + if (0 > + parse_keyexpr(in_buf, version, key_expr, true, out_buf, &key_expression_count)) { + return WITH_ERROR(-1, "Couldn't parse key expression"); } uint8_t c; @@ -1706,7 +1702,7 @@ static int parse_script(buffer_t *in_buf, // We allocate the array of key indices at the current position in the output buffer // (on success) buffer_alloc(out_buf, 0, true); // ensure alignment of current pointer - i_policy_node_keyexpr(&node->key_placeholders, buffer_get_cur(out_buf)); + i_policy_node_keyexpr(&node->keys, buffer_get_cur(out_buf)); node->n = 0; while (true) { @@ -1721,22 +1717,22 @@ static int parse_script(buffer_t *in_buf, return WITH_ERROR(-1, "Expected ','"); } - policy_node_keyexpr_t *key_placeholder = (policy_node_keyexpr_t *) buffer_alloc( + policy_node_keyexpr_t *key_expr = (policy_node_keyexpr_t *) buffer_alloc( out_buf, sizeof(policy_node_keyexpr_t), true); // we align this pointer, as there's padding in an array of // structures - if (key_placeholder == NULL) { + if (key_expr == NULL) { return WITH_ERROR(-1, "Out of memory"); } if (0 > parse_keyexpr(in_buf, version, - key_placeholder, + key_expr, is_taproot, out_buf, - &key_placeholder_count)) { - return WITH_ERROR(-1, "Error parsing key placeholder"); + &key_expression_count)) { + return WITH_ERROR(-1, "Error parsing key expression"); } ++node->n; diff --git a/src/common/wallet.h b/src/common/wallet.h index eff17d2a9..9c0dc1aef 100644 --- a/src/common/wallet.h +++ b/src/common/wallet.h @@ -284,19 +284,6 @@ typedef struct policy_node_ext_info_s { unsigned int x : 1; // the last opcode is not EQUAL, CHECKSIG, or CHECKMULTISIG } policy_node_ext_info_t; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcomment" -// The compiler doesn't like /** inside a block comment, so we disable this warning temporarily. - -/** Structure representing a key placeholder. - * In V1, it's the index of a key expression in the key informations array, which includes the final - * / ** step. - * In V2, it's the index of a key expression in the key informations array, plus the two - * numbers a, b in the //* derivation steps; here, the xpubs in the key informations - * array don't have extra derivation steps. - */ -#pragma GCC diagnostic pop - DEFINE_REL_PTR(uint16, uint16_t) typedef struct { @@ -307,10 +294,22 @@ typedef struct { DEFINE_REL_PTR(musig_aggr_key_info, musig_aggr_key_info_t) typedef enum { - KEY_EXPRESSION_NORMAL = 0, // a key expression with a single key placeholder + KEY_EXPRESSION_NORMAL = 0, // a key expression with a single key expression KEY_EXPRESSION_MUSIG = 1 // a key expression containing a musig() } KeyExpressionType; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcomment" +// The compiler doesn't like /** inside a block comment, so we disable this warning temporarily. + +/** Structure representing a key expression. + * In V1, it's the index of a key in the key informations array, which includes the final /** step. + * In V2, it's the index of a key in the key informations array, plus the two numbers a, b in the + * //* derivation steps; here, the xpubs in the key informations array don't have extra + * derivation steps. + */ +#pragma GCC diagnostic pop + // 16 bytes typedef struct { // the following fields are only used in V2 @@ -325,7 +324,7 @@ typedef struct { rptr_musig_aggr_key_info_t musig_info; // only used in V2 }; int16_t - placeholder_index; // index of the placeholder in the descriptor template, in parsing order + keyexpr_index; // index of the key expression in the descriptor template, in parsing order } policy_node_keyexpr_t; DEFINE_REL_PTR(policy_node_keyexpr, policy_node_keyexpr_t) @@ -359,7 +358,7 @@ typedef policy_node_with_script3_t policy_node_with_scripts_t; // 4 bytes typedef struct { struct policy_node_s base; - rptr_policy_node_keyexpr_t key_placeholder; + rptr_policy_node_keyexpr_t key; } policy_node_with_key_t; // 8 bytes @@ -370,10 +369,10 @@ typedef struct { // 12 bytes typedef struct { - struct policy_node_s base; // type is TOKEN_MULTI or TOKEN_SORTEDMULTI - int16_t k; // threshold - int16_t n; // number of keys - rptr_policy_node_keyexpr_t key_placeholders; // pointer to array of exactly n key placeholders + struct policy_node_s base; // type is TOKEN_MULTI or TOKEN_SORTEDMULTI + int16_t k; // threshold + int16_t n; // number of keys + rptr_policy_node_keyexpr_t keys; // pointer to array of exactly n key expressions } policy_node_multisig_t; // 8 bytes @@ -423,7 +422,7 @@ typedef struct policy_node_tree_s { typedef struct { struct policy_node_s base; - rptr_policy_node_keyexpr_t key_placeholder; + rptr_policy_node_keyexpr_t key; rptr_policy_node_tree_t tree; // NULL if tr(KP) } policy_node_tr_t; diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index ae289fadc..e4875dae3 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -456,13 +456,13 @@ __attribute__((noinline, warn_unused_result)) static int get_extended_pubkey( __attribute__((warn_unused_result)) static int get_derived_pubkey( dispatcher_context_t *dispatcher_context, const wallet_derivation_info_t *wdi, - const policy_node_keyexpr_t *key_placeholder, + const policy_node_keyexpr_t *key_expr, uint8_t out[static 33]) { PRINT_STACK_POINTER(); serialized_extended_pubkey_t ext_pubkey; - int ret = get_extended_pubkey(dispatcher_context, wdi, key_placeholder->key_index, &ext_pubkey); + int ret = get_extended_pubkey(dispatcher_context, wdi, key_expr->key_index, &ext_pubkey); if (ret < 0) { return -1; } @@ -470,7 +470,7 @@ __attribute__((warn_unused_result)) static int get_derived_pubkey( // we derive the // child of this pubkey // we reuse the same memory of ext_pubkey if (0 > derive_first_step_for_pubkey(&ext_pubkey, - key_placeholder, + key_expr, wdi->sign_psbt_cache, wdi->change, &ext_pubkey)) { @@ -577,7 +577,7 @@ __attribute__((warn_unused_result)) static int process_generic_node(policy_parse uint8_t compressed_pubkey[33]; if (-1 == get_derived_pubkey(state->dispatcher_context, state->wdi, - r_policy_node_keyexpr(&policy->key_placeholder), + r_policy_node_keyexpr(&policy->key), compressed_pubkey)) { return -1; } @@ -598,7 +598,7 @@ __attribute__((warn_unused_result)) static int process_generic_node(policy_parse uint8_t compressed_pubkey[33]; if (-1 == get_derived_pubkey(state->dispatcher_context, state->wdi, - r_policy_node_keyexpr(&policy->key_placeholder), + r_policy_node_keyexpr(&policy->key), compressed_pubkey)) { return -1; } @@ -688,7 +688,7 @@ __attribute__((warn_unused_result)) static int process_pkh_wpkh_node(policy_pars if (-1 == get_derived_pubkey(state->dispatcher_context, state->wdi, - r_policy_node_keyexpr(&policy->key_placeholder), + r_policy_node_keyexpr(&policy->key), compressed_pubkey)) { return -1; } else if (policy->base.type == TOKEN_PKH) { @@ -817,7 +817,7 @@ __attribute__((warn_unused_result)) static int process_multi_sortedmulti_node( if (policy->base.type == TOKEN_MULTI) { if (-1 == get_derived_pubkey(state->dispatcher_context, state->wdi, - &r_policy_node_keyexpr(&policy->key_placeholders)[i], + &r_policy_node_keyexpr(&policy->keys)[i], compressed_pubkey)) { return -1; } @@ -840,11 +840,10 @@ __attribute__((warn_unused_result)) static int process_multi_sortedmulti_node( for (int j = 0; j < policy->n; j++) { if (!bitvector_get(used, j)) { uint8_t cur_pubkey[33]; - if (-1 == - get_derived_pubkey(state->dispatcher_context, - state->wdi, - &r_policy_node_keyexpr(&policy->key_placeholders)[j], - cur_pubkey)) { + if (-1 == get_derived_pubkey(state->dispatcher_context, + state->wdi, + &r_policy_node_keyexpr(&policy->keys)[j], + cur_pubkey)) { return -1; } @@ -894,7 +893,7 @@ __attribute__((warn_unused_result)) static int process_multi_a_sortedmulti_a_nod if (policy->base.type == TOKEN_MULTI_A) { if (-1 == get_derived_pubkey(state->dispatcher_context, state->wdi, - &r_policy_node_keyexpr(&policy->key_placeholders)[i], + &r_policy_node_keyexpr(&policy->keys)[i], compressed_pubkey)) { return -1; } @@ -907,11 +906,10 @@ __attribute__((warn_unused_result)) static int process_multi_a_sortedmulti_a_nod for (int j = 0; j < policy->n; j++) { if (!bitvector_get(used, j)) { uint8_t cur_pubkey[33]; - if (-1 == - get_derived_pubkey(state->dispatcher_context, - state->wdi, - &r_policy_node_keyexpr(&policy->key_placeholders)[j], - cur_pubkey)) { + if (-1 == get_derived_pubkey(state->dispatcher_context, + state->wdi, + &r_policy_node_keyexpr(&policy->keys)[j], + cur_pubkey)) { return -1; } @@ -1020,7 +1018,7 @@ int get_wallet_script(dispatcher_context_t *dispatcher_context, policy_node_with_key_t *pkh_policy = (policy_node_with_key_t *) policy; if (0 > get_derived_pubkey(dispatcher_context, wdi, - r_policy_node_keyexpr(&pkh_policy->key_placeholder), + r_policy_node_keyexpr(&pkh_policy->key), compressed_pubkey)) { return -1; } @@ -1039,7 +1037,7 @@ int get_wallet_script(dispatcher_context_t *dispatcher_context, policy_node_with_key_t *wpkh_policy = (policy_node_with_key_t *) policy; if (0 > get_derived_pubkey(dispatcher_context, wdi, - r_policy_node_keyexpr(&wpkh_policy->key_placeholder), + r_policy_node_keyexpr(&wpkh_policy->key), compressed_pubkey)) { return -1; } @@ -1118,7 +1116,7 @@ int get_wallet_script(dispatcher_context_t *dispatcher_context, if (0 > get_derived_pubkey(dispatcher_context, wdi, - r_policy_node_keyexpr(&tr_policy->key_placeholder), + r_policy_node_keyexpr(&tr_policy->key), compressed_pubkey)) { return -1; } @@ -1350,13 +1348,13 @@ static int get_bip44_purpose(const policy_node_t *descriptor_template) { int purpose = -1; switch (descriptor_template->type) { case TOKEN_PKH: - kp = r_policy_node_keyexpr( - &((const policy_node_with_key_t *) descriptor_template)->key_placeholder); + kp = + r_policy_node_keyexpr(&((const policy_node_with_key_t *) descriptor_template)->key); purpose = 44; // legacy break; case TOKEN_WPKH: - kp = r_policy_node_keyexpr( - &((const policy_node_with_key_t *) descriptor_template)->key_placeholder); + kp = + r_policy_node_keyexpr(&((const policy_node_with_key_t *) descriptor_template)->key); purpose = 84; // native segwit break; case TOKEN_SH: { @@ -1366,7 +1364,7 @@ static int get_bip44_purpose(const policy_node_t *descriptor_template) { return -1; } - kp = r_policy_node_keyexpr(&((const policy_node_with_key_t *) inner)->key_placeholder); + kp = r_policy_node_keyexpr(&((const policy_node_with_key_t *) inner)->key); purpose = 49; // nested segwit break; } @@ -1376,8 +1374,7 @@ static int get_bip44_purpose(const policy_node_t *descriptor_template) { return -1; } - kp = r_policy_node_keyexpr( - &((const policy_node_tr_t *) descriptor_template)->key_placeholder); + kp = r_policy_node_keyexpr(&((const policy_node_tr_t *) descriptor_template)->key); purpose = 86; // standard single-key P2TR break; } @@ -1514,44 +1511,47 @@ bool check_wallet_hmac(const uint8_t wallet_id[static 32], const uint8_t wallet_ // make sure that the compiler gives an error if any PolicyNodeType is missed #pragma GCC diagnostic error "-Wswitch-enum" -static int get_key_placeholder_by_index_in_tree(const policy_node_tree_t *tree, - unsigned int i, - const policy_node_t **out_tapleaf_ptr, - policy_node_keyexpr_t *out_placeholder) { +static int get_keyexpr_by_index_in_tree(const policy_node_tree_t *tree, + unsigned int i, + const policy_node_t **out_tapleaf_ptr, + policy_node_keyexpr_t *out_keyexpr) { if (tree->is_leaf) { - int ret = - get_key_placeholder_by_index(r_policy_node(&tree->script), i, NULL, out_placeholder); + int ret = get_keyexpr_by_index(r_policy_node(&tree->script), i, NULL, out_keyexpr); if (ret >= 0 && out_tapleaf_ptr != NULL && i < (unsigned) ret) { *out_tapleaf_ptr = r_policy_node(&tree->script); } return ret; } else { - int ret1 = get_key_placeholder_by_index_in_tree(r_policy_node_tree(&tree->left_tree), - i, - out_tapleaf_ptr, - out_placeholder); + int ret1 = get_keyexpr_by_index_in_tree(r_policy_node_tree(&tree->left_tree), + i, + out_tapleaf_ptr, + out_keyexpr); if (ret1 < 0) return -1; bool found = i < (unsigned int) ret1; - int ret2 = get_key_placeholder_by_index_in_tree(r_policy_node_tree(&tree->right_tree), - found ? 0 : i - ret1, - found ? NULL : out_tapleaf_ptr, - found ? NULL : out_placeholder); + int ret2 = get_keyexpr_by_index_in_tree(r_policy_node_tree(&tree->right_tree), + found ? 0 : i - ret1, + found ? NULL : out_tapleaf_ptr, + found ? NULL : out_keyexpr); if (ret2 < 0) return -1; return ret1 + ret2; } } -int get_key_placeholder_by_index(const policy_node_t *policy, - unsigned int i, - const policy_node_t **out_tapleaf_ptr, - policy_node_keyexpr_t *out_placeholder) { - // make sure that out_placeholder is a valid pointer, if the output is not needed +// TODO: generalize for musig. Note that this is broken for musig, as out_keyexpr +// can't be filled in for musig key expressions (as it's dynamic and contains +// relative pointers). We should probably refactor to return the pointer to the +// key expression and removing the out_keyexpr argument. +int get_keyexpr_by_index(const policy_node_t *policy, + unsigned int i, + const policy_node_t **out_tapleaf_ptr, + policy_node_keyexpr_t *out_keyexpr) { + // make sure that out_keyexpr is a valid pointer, if the output is not needed policy_node_keyexpr_t tmp; - if (out_placeholder == NULL) { - out_placeholder = &tmp; + if (out_keyexpr == NULL) { + out_keyexpr = &tmp; } switch (policy->type) { @@ -1574,8 +1574,8 @@ int get_key_placeholder_by_index(const policy_node_t *policy, case TOKEN_WPKH: { if (i == 0) { policy_node_with_key_t *wpkh = (policy_node_with_key_t *) policy; - memcpy(out_placeholder, - r_policy_node_keyexpr(&wpkh->key_placeholder), + memcpy(out_keyexpr, + r_policy_node_keyexpr(&wpkh->key), sizeof(policy_node_keyexpr_t)); } return 1; @@ -1583,17 +1583,15 @@ int get_key_placeholder_by_index(const policy_node_t *policy, case TOKEN_TR: { policy_node_tr_t *tr = (policy_node_tr_t *) policy; if (i == 0) { - memcpy(out_placeholder, - r_policy_node_keyexpr(&tr->key_placeholder), - sizeof(policy_node_keyexpr_t)); + memcpy(out_keyexpr, r_policy_node_keyexpr(&tr->key), sizeof(policy_node_keyexpr_t)); } if (!isnull_policy_node_tree(&tr->tree)) { - int ret_tree = get_key_placeholder_by_index_in_tree( + int ret_tree = get_keyexpr_by_index_in_tree( r_policy_node_tree(&tr->tree), i == 0 ? 0 : i - 1, i == 0 ? NULL : out_tapleaf_ptr, - i == 0 ? NULL : out_placeholder); // if i == 0, we already found it; so we - // recur with out_placeholder set to NULL + i == 0 ? NULL : out_keyexpr); // if i == 0, we already found it; so we + // recur with out_keyexpr set to NULL if (ret_tree < 0) { return -1; } @@ -1611,9 +1609,8 @@ int get_key_placeholder_by_index(const policy_node_t *policy, const policy_node_multisig_t *node = (const policy_node_multisig_t *) policy; if (i < (unsigned int) node->n) { - policy_node_keyexpr_t *placeholders = - r_policy_node_keyexpr(&node->key_placeholders); - memcpy(out_placeholder, &placeholders[i], sizeof(policy_node_keyexpr_t)); + policy_node_keyexpr_t *key_expressions = r_policy_node_keyexpr(&node->keys); + memcpy(out_keyexpr, &key_expressions[i], sizeof(policy_node_keyexpr_t)); } return node->n; @@ -1632,11 +1629,11 @@ int get_key_placeholder_by_index(const policy_node_t *policy, case TOKEN_N: case TOKEN_L: case TOKEN_U: { - return get_key_placeholder_by_index( + return get_keyexpr_by_index( r_policy_node(&((const policy_node_with_script_t *) policy)->script), i, out_tapleaf_ptr, - out_placeholder); + out_keyexpr); } // nodes with exactly two child scripts @@ -1648,17 +1645,17 @@ int get_key_placeholder_by_index(const policy_node_t *policy, case TOKEN_OR_D: case TOKEN_OR_I: { const policy_node_with_script2_t *node = (const policy_node_with_script2_t *) policy; - int ret1 = get_key_placeholder_by_index(r_policy_node(&node->scripts[0]), - i, - out_tapleaf_ptr, - out_placeholder); + int ret1 = get_keyexpr_by_index(r_policy_node(&node->scripts[0]), + i, + out_tapleaf_ptr, + out_keyexpr); if (ret1 < 0) return -1; bool found = i < (unsigned int) ret1; - int ret2 = get_key_placeholder_by_index(r_policy_node(&node->scripts[1]), - found ? 0 : i - ret1, - found ? NULL : out_tapleaf_ptr, - found ? NULL : out_placeholder); + int ret2 = get_keyexpr_by_index(r_policy_node(&node->scripts[1]), + found ? 0 : i - ret1, + found ? NULL : out_tapleaf_ptr, + found ? NULL : out_keyexpr); if (ret2 < 0) return -1; return ret1 + ret2; @@ -1667,24 +1664,24 @@ int get_key_placeholder_by_index(const policy_node_t *policy, // nodes with exactly three child scripts case TOKEN_ANDOR: { const policy_node_with_script3_t *node = (const policy_node_with_script3_t *) policy; - int ret1 = get_key_placeholder_by_index(r_policy_node(&node->scripts[0]), - i, - out_tapleaf_ptr, - out_placeholder); + int ret1 = get_keyexpr_by_index(r_policy_node(&node->scripts[0]), + i, + out_tapleaf_ptr, + out_keyexpr); if (ret1 < 0) return -1; bool found = i < (unsigned int) ret1; - int ret2 = get_key_placeholder_by_index(r_policy_node(&node->scripts[1]), - found ? 0 : i - ret1, - found ? NULL : out_tapleaf_ptr, - found ? NULL : out_placeholder); + int ret2 = get_keyexpr_by_index(r_policy_node(&node->scripts[1]), + found ? 0 : i - ret1, + found ? NULL : out_tapleaf_ptr, + found ? NULL : out_keyexpr); if (ret2 < 0) return -1; found = i < (unsigned int) (ret1 + ret2); - int ret3 = get_key_placeholder_by_index(r_policy_node(&node->scripts[2]), - found ? 0 : i - ret1 - ret2, - found ? NULL : out_tapleaf_ptr, - found ? NULL : out_placeholder); + int ret3 = get_keyexpr_by_index(r_policy_node(&node->scripts[2]), + found ? 0 : i - ret1 - ret2, + found ? NULL : out_tapleaf_ptr, + found ? NULL : out_keyexpr); if (ret3 < 0) return -1; return ret1 + ret2 + ret3; } @@ -1700,10 +1697,10 @@ int get_key_placeholder_by_index(const policy_node_t *policy, "The script should always have exactly n child scripts"); found = i < (unsigned int) ret; - int ret_partial = get_key_placeholder_by_index(r_policy_node(&cur_child->script), - found ? 0 : i - ret, - found ? NULL : out_tapleaf_ptr, - found ? NULL : out_placeholder); + int ret_partial = get_keyexpr_by_index(r_policy_node(&cur_child->script), + found ? 0 : i - ret, + found ? NULL : out_tapleaf_ptr, + found ? NULL : out_keyexpr); if (ret_partial < 0) return -1; ret += ret_partial; @@ -1726,17 +1723,17 @@ int get_key_placeholder_by_index(const policy_node_t *policy, int count_distinct_keys_info(const policy_node_t *policy) { int ret = -1; - int n_placeholders = get_key_placeholder_by_index(policy, 0, NULL, NULL); - if (n_placeholders < 0) { + int n_key_expressions = get_keyexpr_by_index(policy, 0, NULL, NULL); + if (n_key_expressions < 0) { return -1; } - for (int cur = 0; cur < n_placeholders; ++cur) { - policy_node_keyexpr_t placeholder; - if (0 > get_key_placeholder_by_index(policy, cur, NULL, &placeholder)) { + for (int cur = 0; cur < n_key_expressions; ++cur) { + policy_node_keyexpr_t key_expression; + if (0 > get_keyexpr_by_index(policy, cur, NULL, &key_expression)) { return -1; } - ret = MAX(ret, placeholder.key_index + 1); + ret = MAX(ret, key_expression.key_index + 1); } return ret; } @@ -1910,35 +1907,36 @@ int is_policy_sane(dispatcher_context_t *dispatcher_context, } } - // check that all the key placeholders for the same xpub do indeed have different + // check that all the key expressions for the same xpub do indeed have different // derivations - int n_placeholders = get_key_placeholder_by_index(policy, 0, NULL, NULL); - if (n_placeholders < 0) { - return WITH_ERROR(-1, "Unexpected error while counting placeholders"); + int n_key_expressions = get_keyexpr_by_index(policy, 0, NULL, NULL); + if (n_key_expressions < 0) { + return WITH_ERROR(-1, "Unexpected error while counting key expressions"); } // The following loop computationally very inefficient (quadratic in the number of - // placeholders), but more efficient solutions likely require a substantial amount of RAM - // (proportional to the number of key placeholders). Instead, this only requires stack depth + // key expressions), but more efficient solutions likely require a substantial amount of RAM + // (proportional to the number of key expressions). Instead, this only requires stack depth // proportional to the depth of the wallet policy's abstract syntax tree. - for (int i = 0; i < n_placeholders - 1; - i++) { // no point in running this for the last placeholder + for (int i = 0; i < n_key_expressions - 1; + i++) { // no point in running this for the last key expression policy_node_keyexpr_t kp_i; - if (0 > get_key_placeholder_by_index(policy, i, NULL, &kp_i)) { - return WITH_ERROR(-1, "Unexpected error retrieving placeholders from the policy"); + if (0 > get_keyexpr_by_index(policy, i, NULL, &kp_i)) { + return WITH_ERROR(-1, "Unexpected error retrieving key expressions from the policy"); } - for (int j = i + 1; j < n_placeholders; j++) { + for (int j = i + 1; j < n_key_expressions; j++) { policy_node_keyexpr_t kp_j; - if (0 > get_key_placeholder_by_index(policy, j, NULL, &kp_j)) { - return WITH_ERROR(-1, "Unexpected error retrieving placeholders from the policy"); + if (0 > get_keyexpr_by_index(policy, j, NULL, &kp_j)) { + return WITH_ERROR(-1, + "Unexpected error retrieving key expressions from the policy"); } - // placeholders for the same key must have disjoint derivation options + // key expressions for the same key must have disjoint derivation options if (kp_i.key_index == kp_j.key_index) { if (kp_i.num_first == kp_j.num_first || kp_i.num_first == kp_j.num_second || kp_i.num_second == kp_j.num_first || kp_i.num_second == kp_j.num_second) { return WITH_ERROR(-1, - "Key placeholders with repeated derivations in miniscript"); + "Key expressions with repeated derivations in miniscript"); } } } diff --git a/src/handler/lib/policy.h b/src/handler/lib/policy.h index 68ac71d5a..e5bce4bdc 100644 --- a/src/handler/lib/policy.h +++ b/src/handler/lib/policy.h @@ -46,7 +46,7 @@ typedef struct { // WALLET_POLICY_VERSION_V2 const uint8_t *keys_merkle_root; // The Merkle root of the tree of key informations in the policy - uint32_t n_keys; // The number of key information placeholders in the policy + uint32_t n_keys; // The number of key information elements in the policy size_t address_index; // The address index to use in the derivation bool change; // whether a change address or a receive address is derived sign_psbt_cache_t @@ -179,31 +179,30 @@ bool compute_wallet_hmac(const uint8_t wallet_id[static 32], uint8_t wallet_hmac bool check_wallet_hmac(const uint8_t wallet_id[static 32], const uint8_t wallet_hmac[static 32]); /** - * Copies the i-th placeholder (indexing from 0) of the given policy into `out_placeholder` (if not + * Copies the i-th key expression (indexing from 0) of the given policy into `out_keyexpr` (if not * null). * * @param[in] policy * Pointer to the root node of the policy * @param[in] i - * Index of the wanted placeholder. Ignored if out_placeholder is NULL. + * Index of the wanted key expression. Ignored if out_keyexpr is NULL. * @param[out] out_tapleaf_ptr - * If not NULL, and if the i-th placeholder is in a tapleaf of the policy, receives the pointer to - * the tapleaf's script. - * @param[out] out_placeholder - * If not NULL, it is a pointer that will receive the i-th placeholder of the policy. - * @return the number of placeholders in the policy on success; -1 in case of error. + * If not NULL, and if the i-th key expression is in a tapleaf of the policy, receives the pointer + * to the tapleaf's script. + * @param[out] out_keyexpr + * If not NULL, it is a pointer that will receive the i-th key expression of the policy. + * @return the number of key expressions in the policy on success; -1 in case of error. */ -__attribute__((warn_unused_result)) int get_key_placeholder_by_index( - const policy_node_t *policy, - unsigned int i, - const policy_node_t **out_tapleaf_ptr, - policy_node_keyexpr_t *out_placeholder); +__attribute__((warn_unused_result)) int get_keyexpr_by_index(const policy_node_t *policy, + unsigned int i, + const policy_node_t **out_tapleaf_ptr, + policy_node_keyexpr_t *out_keyexpr); /** * Determines the expected number of unique keys in the provided policy's key information. - * The function calculates this by finding the maximum key index from placeholders and increments it - * by 1. For instance, if the maximum key index found in the placeholders is `n`, then the result - * would be `n + 1`. + * The function calculates this by finding the maximum key index from key expressions and increments + * it by 1. For instance, if the maximum key index found in the key expressions is `n`, then the + * result would be `n + 1`. * * @param[in] policy * Pointer to the root node of the policy diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 1b8a4ae62..da8b860f3 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -65,7 +65,8 @@ typedef struct { // PSBT_{IN,OUT}_BIP32_DERIVATION or // PSBT_{IN,OUT}_TAP_BIP32_DERIVATION is not the correct length. - bool placeholder_found; // Set to true if a matching placeholder is found in the input info + bool key_expression_found; // Set to true if the input/output info in the psbt was correctly + // matched with the current key expression in the signing flow bool is_change; int address_index; @@ -106,7 +107,7 @@ typedef struct { } output_info_t; typedef struct { - policy_node_keyexpr_t placeholder; + policy_node_keyexpr_t key_expression; int cur_index; uint32_t fingerprint; uint8_t key_derivation_length; @@ -114,7 +115,7 @@ typedef struct { serialized_extended_pubkey_t pubkey; bool is_tapscript; // true if signing with a BIP342 tapleaf script path spend uint8_t tapleaf_hash[32]; // only used for tapscripts -} placeholder_info_t; +} keyexpr_info_t; // Cache for partial hashes during segwit signing (avoid quadratic hashing for segwit transactions) typedef struct { @@ -371,9 +372,10 @@ static int get_amount_scriptpubkey_from_psbt( // Convenience function to share common logic when processing all the // PSBT_{IN|OUT}_{TAP}?_BIP32_DERIVATION fields. +// TODO: not generalized for musig2 static int read_change_and_index_from_psbt_bip32_derivation( dispatcher_context_t *dc, - placeholder_info_t *placeholder_info, + keyexpr_info_t *keyexpr_info, in_out_info_t *in_out, sign_psbt_cache_t *sign_psbt_cache, int psbt_key_type, @@ -416,13 +418,13 @@ static int read_change_and_index_from_psbt_bip32_derivation( return -1; } - // if this derivation path matches the internal placeholder, + // if this derivation path matches the internal key expression, // we use it to detect whether the current input is change or not, // and store its address index - if (fpt_der[0] == placeholder_info->fingerprint && - der_len == placeholder_info->key_derivation_length + 2) { - for (int i = 0; i < placeholder_info->key_derivation_length; i++) { - if (placeholder_info->key_derivation[i] != fpt_der[1 + i]) { + if (fpt_der[0] == keyexpr_info->fingerprint && + der_len == keyexpr_info->key_derivation_length + 2) { + for (int i = 0; i < keyexpr_info->key_derivation_length; i++) { + if (keyexpr_info->key_derivation[i] != fpt_der[1 + i]) { return 0; } } @@ -430,21 +432,21 @@ static int read_change_and_index_from_psbt_bip32_derivation( uint32_t change_step = fpt_der[1 + der_len - 2]; uint32_t addr_index = fpt_der[1 + der_len - 1]; - // check if the 'change' derivation step is indeed coherent with placeholder - if (change_step == placeholder_info->placeholder.num_first) { + // check if the 'change' derivation step is indeed coherent with key expression + if (change_step == keyexpr_info->key_expression.num_first) { in_out->is_change = false; in_out->address_index = addr_index; - } else if (change_step == placeholder_info->placeholder.num_second) { + } else if (change_step == keyexpr_info->key_expression.num_second) { in_out->is_change = true; in_out->address_index = addr_index; } else { return 0; } - // check that we can indeed derive the same key from the current placeholder + // check that we can indeed derive the same key from the current key expression serialized_extended_pubkey_t pubkey; - if (0 > derive_first_step_for_pubkey(&placeholder_info->pubkey, - &placeholder_info->placeholder, + if (0 > derive_first_step_for_pubkey(&keyexpr_info->pubkey, + &keyexpr_info->key_expression, sign_psbt_cache, in_out->is_change, &pubkey)) @@ -456,7 +458,7 @@ static int read_change_and_index_from_psbt_bip32_derivation( return 0; } - in_out->placeholder_found = true; + in_out->key_expression_found = true; return 1; } return 0; @@ -474,9 +476,9 @@ static int is_in_out_internal(dispatcher_context_t *dispatcher_context, sign_psbt_cache_t *sign_psbt_cache, const in_out_info_t *in_out_info, bool is_input) { - // If we did not find any info about the pubkey associated to the placeholder we're considering, - // then it's external - if (!in_out_info->placeholder_found) { + // If we did not find any info about the pubkey associated to the key expression we're + // considering, then it's external + if (!in_out_info->key_expression_found) { return 0; } @@ -661,17 +663,16 @@ init_global_state(dispatcher_context_t *dc, sign_psbt_state_t *st) { return true; } -static bool __attribute__((noinline)) -fill_placeholder_info_if_internal(dispatcher_context_t *dc, - sign_psbt_state_t *st, - placeholder_info_t *placeholder_info) { +static bool __attribute__((noinline)) fill_keyexpr_info_if_internal(dispatcher_context_t *dc, + sign_psbt_state_t *st, + keyexpr_info_t *keyexpr_info) { policy_map_key_info_t key_info; { uint8_t key_info_str[MAX_POLICY_KEY_INFO_LEN]; int key_info_len = call_get_merkle_leaf_element(dc, st->wallet_header.keys_info_merkle_root, st->wallet_header.n_keys, - placeholder_info->placeholder.key_index, + keyexpr_info->key_expression.key_index, key_info_str, sizeof(key_info_str)); @@ -701,56 +702,55 @@ fill_placeholder_info_if_internal(dispatcher_context_t *dc, if (0 > get_extended_pubkey_at_path(key_info.master_key_derivation, key_info.master_key_derivation_len, BIP32_PUBKEY_VERSION, - &placeholder_info->pubkey)) { + &keyexpr_info->pubkey)) { SEND_SW(dc, SW_BAD_STATE); return false; } - if (memcmp(&key_info.ext_pubkey, - &placeholder_info->pubkey, - sizeof(placeholder_info->pubkey)) != 0) { + if (memcmp(&key_info.ext_pubkey, &keyexpr_info->pubkey, sizeof(keyexpr_info->pubkey)) != + 0) { return false; } - placeholder_info->key_derivation_length = key_info.master_key_derivation_len; + keyexpr_info->key_derivation_length = key_info.master_key_derivation_len; for (int i = 0; i < key_info.master_key_derivation_len; i++) { - placeholder_info->key_derivation[i] = key_info.master_key_derivation[i]; + keyexpr_info->key_derivation[i] = key_info.master_key_derivation[i]; } - placeholder_info->fingerprint = read_u32_be(key_info.master_key_fingerprint, 0); + keyexpr_info->fingerprint = read_u32_be(key_info.master_key_fingerprint, 0); } return true; } -// finds the first placeholder that corresponds to an internal key -static bool find_first_internal_key_placeholder(dispatcher_context_t *dc, - sign_psbt_state_t *st, - placeholder_info_t *placeholder_info) { - placeholder_info->cur_index = 0; +// finds the first key expression that corresponds to an internal key +static bool find_first_internal_keyexpr(dispatcher_context_t *dc, + sign_psbt_state_t *st, + keyexpr_info_t *keyexpr_info) { + keyexpr_info->cur_index = 0; // find and parse our registered key info in the wallet while (true) { - int n_key_placeholders = get_key_placeholder_by_index(st->wallet_policy_map, - placeholder_info->cur_index, - NULL, - &placeholder_info->placeholder); - if (n_key_placeholders < 0) { + int n_key_expressions = get_keyexpr_by_index(st->wallet_policy_map, + keyexpr_info->cur_index, + NULL, + &keyexpr_info->key_expression); + if (n_key_expressions < 0) { SEND_SW(dc, SW_BAD_STATE); // should never happen return false; } - if (placeholder_info->cur_index >= n_key_placeholders) { + if (keyexpr_info->cur_index >= n_key_expressions) { // all keys have been processed break; } - if (fill_placeholder_info_if_internal(dc, st, placeholder_info)) { + if (fill_keyexpr_info_if_internal(dc, st, keyexpr_info)) { return true; } // Not an internal key, move on - ++placeholder_info->cur_index; + ++keyexpr_info->cur_index; } PRINTF("No internal key found in wallet policy"); @@ -759,7 +759,7 @@ static bool find_first_internal_key_placeholder(dispatcher_context_t *dc, } typedef struct { - placeholder_info_t *placeholder_info; + keyexpr_info_t *keyexpr_info; input_info_t *input; sign_psbt_cache_t *sign_psbt_cache; } input_keys_callback_data_t; @@ -787,16 +787,15 @@ static void input_keys_callback(dispatcher_context_t *dc, callback_data->input->has_sighash_type = true; } else if ((key_type == PSBT_IN_BIP32_DERIVATION || key_type == PSBT_IN_TAP_BIP32_DERIVATION) && - !callback_data->input->in_out.placeholder_found) { - if (0 > - read_change_and_index_from_psbt_bip32_derivation(dc, - callback_data->placeholder_info, - &callback_data->input->in_out, - callback_data->sign_psbt_cache, - key_type, - data, - map_commitment, - i)) { + !callback_data->input->in_out.key_expression_found) { + if (0 > read_change_and_index_from_psbt_bip32_derivation(dc, + callback_data->keyexpr_info, + &callback_data->input->in_out, + callback_data->sign_psbt_cache, + key_type, + data, + map_commitment, + i)) { callback_data->input->in_out.unexpected_pubkey_error = true; } } @@ -812,10 +811,10 @@ preprocess_inputs(dispatcher_context_t *dc, memset(internal_inputs, 0, BITVECTOR_REAL_SIZE(MAX_N_INPUTS_CAN_SIGN)); - placeholder_info_t placeholder_info; - memset(&placeholder_info, 0, sizeof(placeholder_info)); + keyexpr_info_t keyexpr_info; + memset(&keyexpr_info, 0, sizeof(keyexpr_info)); - if (!find_first_internal_key_placeholder(dc, st, &placeholder_info)) return false; + if (!find_first_internal_keyexpr(dc, st, &keyexpr_info)) return false; // process each input for (unsigned int cur_input_index = 0; cur_input_index < st->n_inputs; cur_input_index++) { @@ -823,7 +822,7 @@ preprocess_inputs(dispatcher_context_t *dc, memset(&input, 0, sizeof(input)); input_keys_callback_data_t callback_data = {.input = &input, - .placeholder_info = &placeholder_info, + .keyexpr_info = &keyexpr_info, .sign_psbt_cache = sign_psbt_cache}; int res = call_get_merkleized_map_with_callback( dc, @@ -1025,7 +1024,7 @@ preprocess_inputs(dispatcher_context_t *dc, } typedef struct { - placeholder_info_t *placeholder_info; + keyexpr_info_t *keyexpr_info; output_info_t *output; sign_psbt_cache_t *sign_psbt_cache; } output_keys_callback_data_t; @@ -1045,16 +1044,15 @@ static void output_keys_callback(dispatcher_context_t *dc, buffer_read_u8(data, &key_type); if ((key_type == PSBT_OUT_BIP32_DERIVATION || key_type == PSBT_OUT_TAP_BIP32_DERIVATION) && - !callback_data->output->in_out.placeholder_found) { - if (0 > - read_change_and_index_from_psbt_bip32_derivation(dc, - callback_data->placeholder_info, - &callback_data->output->in_out, - callback_data->sign_psbt_cache, - key_type, - data, - map_commitment, - i)) { + !callback_data->output->in_out.key_expression_found) { + if (0 > read_change_and_index_from_psbt_bip32_derivation(dc, + callback_data->keyexpr_info, + &callback_data->output->in_out, + callback_data->sign_psbt_cache, + key_type, + data, + map_commitment, + i)) { callback_data->output->in_out.unexpected_pubkey_error = true; } } @@ -1074,10 +1072,10 @@ preprocess_outputs(dispatcher_context_t *dc, LOG_PROCESSOR(__FILE__, __LINE__, __func__); - placeholder_info_t placeholder_info; - memset(&placeholder_info, 0, sizeof(placeholder_info)); + keyexpr_info_t keyexpr_info; + memset(&keyexpr_info, 0, sizeof(keyexpr_info)); - if (!find_first_internal_key_placeholder(dc, st, &placeholder_info)) return false; + if (!find_first_internal_keyexpr(dc, st, &keyexpr_info)) return false; memset(&st->outputs, 0, sizeof(st->outputs)); @@ -1090,7 +1088,7 @@ preprocess_outputs(dispatcher_context_t *dc, memset(&output, 0, sizeof(output)); output_keys_callback_data_t callback_data = {.output = &output, - .placeholder_info = &placeholder_info, + .keyexpr_info = &keyexpr_info, .sign_psbt_cache = sign_psbt_cache}; int res = call_get_merkleized_map_with_callback( dc, @@ -1978,7 +1976,7 @@ static bool __attribute__((noinline)) compute_sighash_segwitv1(dispatcher_contex segwit_hashes_t *hashes, input_info_t *input, unsigned int cur_input_index, - placeholder_info_t *placeholder_info, + keyexpr_info_t *keyexpr_info, uint8_t sighash[static 32]) { LOG_PROCESSOR(__FILE__, __LINE__, __func__); @@ -2013,7 +2011,7 @@ static bool __attribute__((noinline)) compute_sighash_segwitv1(dispatcher_contex } // ext_flag - uint8_t ext_flag = placeholder_info->is_tapscript ? 1 : 0; + uint8_t ext_flag = keyexpr_info->is_tapscript ? 1 : 0; // annex is not supported const uint8_t annex_present = 0; uint8_t spend_type = ext_flag * 2 + annex_present; @@ -2097,9 +2095,9 @@ static bool __attribute__((noinline)) compute_sighash_segwitv1(dispatcher_contex crypto_hash_update(&sighash_context.header, tmp, 32); } - if (placeholder_info->is_tapscript) { + if (keyexpr_info->is_tapscript) { // If spending a tapscript, append the Common Signature Message Extension per BIP-0342 - crypto_hash_update(&sighash_context.header, placeholder_info->tapleaf_hash, 32); + crypto_hash_update(&sighash_context.header, keyexpr_info->tapleaf_hash, 32); crypto_hash_update_u8(&sighash_context.header, 0x00); // key_version crypto_hash_update_u32(&sighash_context.header, 0xffffffff); // no OP_CODESEPARATOR } @@ -2151,25 +2149,24 @@ static bool __attribute__((noinline)) yield_signature(dispatcher_context_t *dc, return true; } -static bool __attribute__((noinline)) -sign_sighash_ecdsa_and_yield(dispatcher_context_t *dc, - sign_psbt_state_t *st, - placeholder_info_t *placeholder_info, - input_info_t *input, - unsigned int cur_input_index, - uint8_t sighash[static 32]) { +static bool __attribute__((noinline)) sign_sighash_ecdsa_and_yield(dispatcher_context_t *dc, + sign_psbt_state_t *st, + keyexpr_info_t *keyexpr_info, + input_info_t *input, + unsigned int cur_input_index, + uint8_t sighash[static 32]) { LOG_PROCESSOR(__FILE__, __LINE__, __func__); uint32_t sign_path[MAX_BIP32_PATH_STEPS]; - for (int i = 0; i < placeholder_info->key_derivation_length; i++) { - sign_path[i] = placeholder_info->key_derivation[i]; + for (int i = 0; i < keyexpr_info->key_derivation_length; i++) { + sign_path[i] = keyexpr_info->key_derivation[i]; } - sign_path[placeholder_info->key_derivation_length] = - input->in_out.is_change ? placeholder_info->placeholder.num_second - : placeholder_info->placeholder.num_first; - sign_path[placeholder_info->key_derivation_length + 1] = input->in_out.address_index; + sign_path[keyexpr_info->key_derivation_length] = input->in_out.is_change + ? keyexpr_info->key_expression.num_second + : keyexpr_info->key_expression.num_first; + sign_path[keyexpr_info->key_derivation_length + 1] = input->in_out.address_index; - int sign_path_len = placeholder_info->key_derivation_length + 2; + int sign_path_len = keyexpr_info->key_derivation_length + 2; uint8_t sig[MAX_DER_SIG_LEN + 1]; // extra byte for the appended sighash-type @@ -2196,13 +2193,12 @@ sign_sighash_ecdsa_and_yield(dispatcher_context_t *dc, return true; } -static bool __attribute__((noinline)) -sign_sighash_schnorr_and_yield(dispatcher_context_t *dc, - sign_psbt_state_t *st, - placeholder_info_t *placeholder_info, - input_info_t *input, - unsigned int cur_input_index, - uint8_t sighash[static 32]) { +static bool __attribute__((noinline)) sign_sighash_schnorr_and_yield(dispatcher_context_t *dc, + sign_psbt_state_t *st, + keyexpr_info_t *keyexpr_info, + input_info_t *input, + unsigned int cur_input_index, + uint8_t sighash[static 32]) { LOG_PROCESSOR(__FILE__, __LINE__, __func__); if (st->wallet_policy_map->type != TOKEN_TR) { @@ -2230,15 +2226,15 @@ sign_sighash_schnorr_and_yield(dispatcher_context_t *dc, uint32_t sign_path[MAX_BIP32_PATH_STEPS]; - for (int i = 0; i < placeholder_info->key_derivation_length; i++) { - sign_path[i] = placeholder_info->key_derivation[i]; + for (int i = 0; i < keyexpr_info->key_derivation_length; i++) { + sign_path[i] = keyexpr_info->key_derivation[i]; } - sign_path[placeholder_info->key_derivation_length] = - input->in_out.is_change ? placeholder_info->placeholder.num_second - : placeholder_info->placeholder.num_first; - sign_path[placeholder_info->key_derivation_length + 1] = input->in_out.address_index; + sign_path[keyexpr_info->key_derivation_length] = + input->in_out.is_change ? keyexpr_info->key_expression.num_second + : keyexpr_info->key_expression.num_first; + sign_path[keyexpr_info->key_derivation_length + 1] = input->in_out.address_index; - int sign_path_len = placeholder_info->key_derivation_length + 2; + int sign_path_len = keyexpr_info->key_derivation_length + 2; if (bip32_derive_init_privkey_256(CX_CURVE_256K1, sign_path, @@ -2251,7 +2247,7 @@ sign_sighash_schnorr_and_yield(dispatcher_context_t *dc, policy_node_tr_t *policy = (policy_node_tr_t *) st->wallet_policy_map; - if (!placeholder_info->is_tapscript) { + if (!keyexpr_info->is_tapscript) { if (isnull_policy_node_tree(&policy->tree)) { // tweak as specified in BIP-86 and BIP-386 crypto_tr_tweak_seckey(seckey, (uint8_t[]){}, 0, seckey); @@ -2263,7 +2259,7 @@ sign_sighash_schnorr_and_yield(dispatcher_context_t *dc, } } else { // tapscript, we need to yield the tapleaf hash together with the pubkey - tapleaf_hash = placeholder_info->tapleaf_hash; + tapleaf_hash = keyexpr_info->tapleaf_hash; } // generate corresponding public key @@ -2451,7 +2447,7 @@ static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_ sign_psbt_state_t *st, sign_psbt_cache_t *sign_psbt_cache, segwit_hashes_t *hashes, - placeholder_info_t *placeholder_info, + keyexpr_info_t *keyexpr_info, input_info_t *input, unsigned int cur_input_index) { LOG_PROCESSOR(__FILE__, __LINE__, __func__); @@ -2497,12 +2493,7 @@ static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_ uint8_t sighash[32]; if (!compute_sighash_legacy(dc, st, input, cur_input_index, sighash)) return false; - if (!sign_sighash_ecdsa_and_yield(dc, - st, - placeholder_info, - input, - cur_input_index, - sighash)) + if (!sign_sighash_ecdsa_and_yield(dc, st, keyexpr_info, input, cur_input_index, sighash)) return false; } else { { @@ -2569,7 +2560,7 @@ static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_ if (!sign_sighash_ecdsa_and_yield(dc, st, - placeholder_info, + keyexpr_info, input, cur_input_index, sighash)) @@ -2585,12 +2576,12 @@ static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_ hashes, input, cur_input_index, - placeholder_info, + keyexpr_info, sighash)) return false; policy_node_tr_t *policy = (policy_node_tr_t *) st->wallet_policy_map; - if (!placeholder_info->is_tapscript && !isnull_policy_node_tree(&policy->tree)) { + if (!keyexpr_info->is_tapscript && !isnull_policy_node_tree(&policy->tree)) { // keypath spend, we compute the taptree hash so that we find it ready // later in sign_sighash_schnorr_and_yield (which has less available stack). if (0 > compute_taptree_hash( @@ -2612,7 +2603,7 @@ static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_ if (!sign_sighash_schnorr_and_yield(dc, st, - placeholder_info, + keyexpr_info, input, cur_input_index, sighash)) @@ -2627,12 +2618,12 @@ static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_ } static bool __attribute__((noinline)) -fill_taproot_placeholder_info(dispatcher_context_t *dc, - sign_psbt_state_t *st, - const input_info_t *input, - const policy_node_t *tapleaf_ptr, - placeholder_info_t *placeholder_info, - sign_psbt_cache_t *sign_psbt_cache) { +fill_taproot_keyexpr_info(dispatcher_context_t *dc, + sign_psbt_state_t *st, + const input_info_t *input, + const policy_node_t *tapleaf_ptr, + keyexpr_info_t *keyexpr_info, + sign_psbt_cache_t *sign_psbt_cache) { cx_sha256_t hash_context; crypto_tr_tapleaf_hash_init(&hash_context); @@ -2663,7 +2654,7 @@ fill_taproot_placeholder_info(dispatcher_context_t *dc, &hash_context.header)) { return false; // should never happen! } - crypto_hash_digest(&hash_context.header, placeholder_info->tapleaf_hash, 32); + crypto_hash_digest(&hash_context.header, keyexpr_info->tapleaf_hash, 32); return true; } @@ -2675,7 +2666,7 @@ sign_transaction(dispatcher_context_t *dc, const uint8_t internal_inputs[static BITVECTOR_REAL_SIZE(MAX_N_INPUTS_CAN_SIGN)]) { LOG_PROCESSOR(__FILE__, __LINE__, __func__); - int placeholder_index = 0; + int key_expression_index = 0; segwit_hashes_t hashes; @@ -2687,42 +2678,41 @@ sign_transaction(dispatcher_context_t *dc, return false; } - // Iterate over all the placeholders that correspond to keys owned by us + // Iterate over all the key expressions that correspond to keys owned by us while (true) { - placeholder_info_t placeholder_info; - memset(&placeholder_info, 0, sizeof(placeholder_info)); + keyexpr_info_t keyexpr_info; + memset(&keyexpr_info, 0, sizeof(keyexpr_info)); const policy_node_t *tapleaf_ptr = NULL; - int n_key_placeholders = get_key_placeholder_by_index(st->wallet_policy_map, - placeholder_index, - &tapleaf_ptr, - &placeholder_info.placeholder); + int n_key_expressions = get_keyexpr_by_index(st->wallet_policy_map, + key_expression_index, + &tapleaf_ptr, + &keyexpr_info.key_expression); - if (n_key_placeholders < 0) { + if (n_key_expressions < 0) { SEND_SW(dc, SW_BAD_STATE); // should never happen return false; } - if (placeholder_index >= n_key_placeholders) { - // all placeholders were processed + if (key_expression_index >= n_key_expressions) { + // all key expressions were processed break; } if (tapleaf_ptr != NULL) { - // get_key_placeholder_by_index returns the pointer to the tapleaf only if the key being + // get_keyexpr_by_index returns the pointer to the tapleaf only if the key being // spent is indeed in a tapleaf - placeholder_info.is_tapscript = true; + keyexpr_info.is_tapscript = true; } - if (fill_placeholder_info_if_internal(dc, st, &placeholder_info) == true) { + if (fill_keyexpr_info_if_internal(dc, st, &keyexpr_info) == true) { for (unsigned int i = 0; i < st->n_inputs; i++) if (bitvector_get(internal_inputs, i)) { input_info_t input; memset(&input, 0, sizeof(input)); - input_keys_callback_data_t callback_data = { - .input = &input, - .placeholder_info = &placeholder_info}; + input_keys_callback_data_t callback_data = {.input = &input, + .keyexpr_info = &keyexpr_info}; int res = call_get_merkleized_map_with_callback( dc, (void *) &callback_data, @@ -2736,19 +2726,19 @@ sign_transaction(dispatcher_context_t *dc, return false; } - if (tapleaf_ptr != NULL && !fill_taproot_placeholder_info(dc, - st, - &input, - tapleaf_ptr, - &placeholder_info, - sign_psbt_cache)) + if (tapleaf_ptr != NULL && !fill_taproot_keyexpr_info(dc, + st, + &input, + tapleaf_ptr, + &keyexpr_info, + sign_psbt_cache)) return false; if (!sign_transaction_input(dc, st, sign_psbt_cache, &hashes, - &placeholder_info, + &keyexpr_info, &input, i)) { // we do not send a status word, since sign_transaction_input @@ -2758,7 +2748,7 @@ sign_transaction(dispatcher_context_t *dc, } } - ++placeholder_index; + ++key_expression_index; } return true; @@ -2824,7 +2814,7 @@ void handler_sign_psbt(dispatcher_context_t *dc, uint8_t protocol_version) { /** SIGNING FLOW * - * For each internal placeholder, and for each internal input, sign using the + * For each internal key expression, and for each internal input, sign using the * appropriate algorithm. */ int sign_result = sign_transaction(dc, &st, &cache, internal_inputs); diff --git a/src/handler/sign_psbt/sign_psbt_cache.c b/src/handler/sign_psbt/sign_psbt_cache.c index 30803afaa..00bf8b027 100644 --- a/src/handler/sign_psbt/sign_psbt_cache.c +++ b/src/handler/sign_psbt/sign_psbt_cache.c @@ -1,34 +1,32 @@ #include "sign_psbt_cache.h" int derive_first_step_for_pubkey(const serialized_extended_pubkey_t *base_key, - const policy_node_keyexpr_t *placeholder, + const policy_node_keyexpr_t *keyexpr, sign_psbt_cache_t *cache, bool is_change, serialized_extended_pubkey_t *out_pubkey) { - uint32_t change_step = is_change ? placeholder->num_second : placeholder->num_first; + uint32_t change_step = is_change ? keyexpr->num_second : keyexpr->num_first; // make sure a cache was provided, and the index is less than the size of the cache - if (placeholder->placeholder_index >= MAX_CACHED_KEY_EXPRESSIONS || !cache) { + if (keyexpr->keyexpr_index >= MAX_CACHED_KEY_EXPRESSIONS || !cache) { // do not use the cache, derive the key directly return bip32_CKDpub(base_key, change_step, out_pubkey); } - if (!cache->derived_child[placeholder->placeholder_index] - .is_child_pubkey_initialized[is_change]) { + if (!cache->derived_child[keyexpr->keyexpr_index].is_child_pubkey_initialized[is_change]) { // key not in cache; compute it and store it in the cache - if (0 > bip32_CKDpub( - base_key, - change_step, - &cache->derived_child[placeholder->placeholder_index].child_pubkeys[is_change])) + if (0 > + bip32_CKDpub(base_key, + change_step, + &cache->derived_child[keyexpr->keyexpr_index].child_pubkeys[is_change])) return -1; - cache->derived_child[placeholder->placeholder_index] - .is_child_pubkey_initialized[is_change] = true; + cache->derived_child[keyexpr->keyexpr_index].is_child_pubkey_initialized[is_change] = true; } // now that we are guaranteed that the key is in cache, we just copy it memcpy(out_pubkey, - &cache->derived_child[placeholder->placeholder_index].child_pubkeys[is_change], + &cache->derived_child[keyexpr->keyexpr_index].child_pubkeys[is_change], sizeof(serialized_extended_pubkey_t)); return 0; diff --git a/src/handler/sign_psbt/sign_psbt_cache.h b/src/handler/sign_psbt/sign_psbt_cache.h index 5baf44ecd..fb87c73da 100644 --- a/src/handler/sign_psbt/sign_psbt_cache.h +++ b/src/handler/sign_psbt/sign_psbt_cache.h @@ -39,12 +39,12 @@ number of BIP-32 derivations is cut almost by half when using the cache. */ /** - * Derives the first step for a public key in a placeholder, using a precomputed value from the + * Derives the first step for a public key in a key expression, using a precomputed value from the * cache if available. If the key is not in the cache, it is computed and stored in the cache, - * unless the index is placeholder index is too large. + * unless the key expression index is too large. * * @param[in] base_key Pointer to the base serialized extended public key. - * @param[in] placeholder Pointer to the policy node key placeholder, which contains derivation + * @param[in] keyexpr Pointer to the policy node key expression, which contains derivation * information. * @param[in] cache Pointer to the cache structure used to store derived child keys. * @param[in] is_change true if deriving the change address, false otherwise. @@ -53,7 +53,7 @@ number of BIP-32 derivations is cut almost by half when using the cache. * @return 0 on success, -1 on failure. */ int derive_first_step_for_pubkey(const serialized_extended_pubkey_t *base_key, - const policy_node_keyexpr_t *placeholder, + const policy_node_keyexpr_t *keyexpr, sign_psbt_cache_t *cache, bool is_change, - serialized_extended_pubkey_t *out_pubkey); \ No newline at end of file + serialized_extended_pubkey_t *out_pubkey); diff --git a/unit-tests/test_wallet.c b/unit-tests/test_wallet.c index c330f430e..406c4a609 100644 --- a/unit-tests/test_wallet.c +++ b/unit-tests/test_wallet.c @@ -33,7 +33,7 @@ static int parse_policy(const char *descriptor_template, uint8_t *out, size_t ou #define MAX_WALLET_POLICY_MEMORY_SIZE 512 // convenience function to compactly check common assertions on a pointer to a key expression with a -// single placeholder +// single key static void check_key_expr_plain(const policy_node_keyexpr_t *ptr, int key_index, uint32_t num_first, @@ -72,7 +72,7 @@ static void test_parse_policy_map_singlesig_1(void **state) { policy_node_with_key_t *node_1 = (policy_node_with_key_t *) out; assert_int_equal(node_1->base.type, TOKEN_PKH); - check_key_expr_plain(r_policy_node_keyexpr(&node_1->key_placeholder), 0, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&node_1->key), 0, 0, 1); } static void test_parse_policy_map_singlesig_2(void **state) { @@ -90,7 +90,7 @@ static void test_parse_policy_map_singlesig_2(void **state) { policy_node_with_key_t *inner = (policy_node_with_key_t *) r_policy_node(&root->script); assert_int_equal(inner->base.type, TOKEN_WPKH); - check_key_expr_plain(r_policy_node_keyexpr(&inner->key_placeholder), 0, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&inner->key), 0, 0, 1); } static void test_parse_policy_map_singlesig_3(void **state) { @@ -112,7 +112,7 @@ static void test_parse_policy_map_singlesig_3(void **state) { policy_node_with_key_t *inner = (policy_node_with_key_t *) r_policy_node(&mid->script); assert_int_equal(inner->base.type, TOKEN_PKH); - check_key_expr_plain(r_policy_node_keyexpr(&inner->key_placeholder), 0, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&inner->key), 0, 0, 1); } static void test_parse_policy_map_multisig_1(void **state) { @@ -128,9 +128,9 @@ static void test_parse_policy_map_multisig_1(void **state) { assert_int_equal(node_1->base.type, TOKEN_SORTEDMULTI); assert_int_equal(node_1->k, 2); assert_int_equal(node_1->n, 3); - check_key_expr_plain(&r_policy_node_keyexpr(&node_1->key_placeholders)[0], 0, 0, 1); - check_key_expr_plain(&r_policy_node_keyexpr(&node_1->key_placeholders)[1], 1, 0, 1); - check_key_expr_plain(&r_policy_node_keyexpr(&node_1->key_placeholders)[2], 2, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&node_1->keys)[0], 0, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&node_1->keys)[1], 1, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&node_1->keys)[2], 2, 0, 1); } static void test_parse_policy_map_multisig_2(void **state) { @@ -151,7 +151,7 @@ static void test_parse_policy_map_multisig_2(void **state) { assert_int_equal(inner->k, 3); assert_int_equal(inner->n, 5); for (int i = 0; i < 5; i++) { - check_key_expr_plain(&r_policy_node_keyexpr(&inner->key_placeholders)[i], i, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&inner->keys)[i], i, 0, 1); } } @@ -177,7 +177,7 @@ static void test_parse_policy_map_multisig_3(void **state) { assert_int_equal(inner->k, 3); assert_int_equal(inner->n, 5); for (int i = 0; i < 5; i++) { - check_key_expr_plain(&r_policy_node_keyexpr(&inner->key_placeholders)[i], i, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&inner->keys)[i], i, 0, 1); } } @@ -194,7 +194,7 @@ static void test_parse_policy_tr(void **state) { policy_node_tr_t *root = (policy_node_tr_t *) out; assert_true(isnull_policy_node_tree(&root->tree)); - check_key_expr_plain(r_policy_node_keyexpr(&root->key_placeholder), 0, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&root->key), 0, 0, 1); // Simple tr with a TREE that is a simple script res = parse_policy("tr(@0/**,pk(@1/**))", out, sizeof(out)); @@ -202,7 +202,7 @@ static void test_parse_policy_tr(void **state) { assert_true(res >= 0); root = (policy_node_tr_t *) out; - check_key_expr_plain(r_policy_node_keyexpr(&root->key_placeholder), 0, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&root->key), 0, 0, 1); assert_int_equal(r_policy_node_tree(&root->tree)->is_leaf, true); @@ -210,7 +210,7 @@ static void test_parse_policy_tr(void **state) { (policy_node_with_key_t *) r_policy_node(&r_policy_node_tree(&root->tree)->script); assert_int_equal(tapscript->base.type, TOKEN_PK); - check_key_expr_plain(r_policy_node_keyexpr(&tapscript->key_placeholder), 1, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&tapscript->key), 1, 0, 1); // Simple tr with a TREE with two tapleaves res = parse_policy("tr(@0/**,{pk(@1/**),pk(@2/<5;7>/*)})", out, sizeof(out)); @@ -218,7 +218,7 @@ static void test_parse_policy_tr(void **state) { assert_true(res >= 0); root = (policy_node_tr_t *) out; - check_key_expr_plain(r_policy_node_keyexpr(&root->key_placeholder), 0, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&root->key), 0, 0, 1); policy_node_tree_t *taptree = r_policy_node_tree(&root->tree); @@ -231,7 +231,7 @@ static void test_parse_policy_tr(void **state) { (policy_node_with_key_t *) r_policy_node(&taptree_left->script); assert_int_equal(tapscript_left->base.type, TOKEN_PK); - check_key_expr_plain(r_policy_node_keyexpr(&tapscript_left->key_placeholder), 1, 0, 1); + check_key_expr_plain(r_policy_node_keyexpr(&tapscript_left->key), 1, 0, 1); policy_node_tree_t *taptree_right = (policy_node_tree_t *) r_policy_node_tree(&taptree->right_tree); @@ -240,7 +240,7 @@ static void test_parse_policy_tr(void **state) { (policy_node_with_key_t *) r_policy_node(&taptree_right->script); assert_int_equal(tapscript_right->base.type, TOKEN_PK); - check_key_expr_plain(r_policy_node_keyexpr(&tapscript_right->key_placeholder), 2, 5, 7); + check_key_expr_plain(r_policy_node_keyexpr(&tapscript_right->key), 2, 5, 7); } static void test_parse_policy_tr_multisig(void **state) { @@ -258,9 +258,9 @@ static void test_parse_policy_tr_multisig(void **state) { policy_node_tr_t *root = (policy_node_tr_t *) out; - assert_int_equal(r_policy_node_keyexpr(&root->key_placeholder)->key_index, 0); - assert_int_equal(r_policy_node_keyexpr(&root->key_placeholder)->num_first, 0); - assert_int_equal(r_policy_node_keyexpr(&root->key_placeholder)->num_second, 1); + assert_int_equal(r_policy_node_keyexpr(&root->key)->key_index, 0); + assert_int_equal(r_policy_node_keyexpr(&root->key)->num_first, 0); + assert_int_equal(r_policy_node_keyexpr(&root->key)->num_second, 1); policy_node_tree_t *taptree = r_policy_node_tree(&root->tree); @@ -275,8 +275,8 @@ static void test_parse_policy_tr_multisig(void **state) { assert_int_equal(tapscript_left->base.type, TOKEN_MULTI_A); assert_int_equal(tapscript_left->k, 1); assert_int_equal(tapscript_left->n, 2); - check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_left->key_placeholders)[0], 1, 0, 1); - check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_left->key_placeholders)[1], 2, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_left->keys)[0], 1, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_left->keys)[1], 2, 0, 1); policy_node_tree_t *taptree_right = (policy_node_tree_t *) r_policy_node_tree(&taptree->right_tree); @@ -287,9 +287,9 @@ static void test_parse_policy_tr_multisig(void **state) { assert_int_equal(tapscript_right->base.type, TOKEN_SORTEDMULTI_A); assert_int_equal(tapscript_right->k, 2); assert_int_equal(tapscript_right->n, 3); - check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_right->key_placeholders)[0], 3, 0, 1); - check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_right->key_placeholders)[1], 4, 0, 1); - check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_right->key_placeholders)[2], 5, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_right->keys)[0], 3, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_right->keys)[1], 4, 0, 1); + check_key_expr_plain(&r_policy_node_keyexpr(&tapscript_right->keys)[2], 5, 0, 1); } static void test_parse_policy_tr_musig_keypath(void **state) { @@ -306,11 +306,7 @@ static void test_parse_policy_tr_musig_keypath(void **state) { assert_int_equal(root->base.type, TOKEN_TR); assert_true(isnull_policy_node_tree(&root->tree)); - check_key_expr_musig(r_policy_node_keyexpr(&root->key_placeholder), - 3, - (uint16_t[]){2, 0, 1}, - 3, - 13); + check_key_expr_musig(r_policy_node_keyexpr(&root->key), 3, (uint16_t[]){2, 0, 1}, 3, 13); } static void test_parse_policy_tr_musig_scriptpath(void **state) { @@ -334,11 +330,7 @@ static void test_parse_policy_tr_musig_scriptpath(void **state) { policy_node_with_key_t *script_pk = (policy_node_with_key_t *) r_policy_node(&tree->script); assert_int_equal(script_pk->base.type, TOKEN_PK); - check_key_expr_musig(r_policy_node_keyexpr(&script_pk->key_placeholder), - 3, - (uint16_t[]){2, 0, 3}, - 0, - 1); + check_key_expr_musig(r_policy_node_keyexpr(&script_pk->key), 3, (uint16_t[]){2, 0, 3}, 0, 1); } static void test_get_policy_segwit_version(void **state) { From 8e249947da19fdcaea5edb2c9c3e11bd7cad19f8 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 9 Oct 2024 09:46:34 +0200 Subject: [PATCH 03/57] Refactored policy_node_keyexpr_t to explicitly label which of the union type is used; generalized some parts of the code that are not generalized to musig key expressions, and annotated some others. --- src/common/wallet.c | 4 +-- src/common/wallet.h | 8 ++++-- src/handler/lib/policy.c | 60 +++++++++++++++++++++++++--------------- src/handler/lib/policy.h | 5 ++-- src/handler/sign_psbt.c | 39 ++++++++++++++------------ unit-tests/test_wallet.c | 6 ++-- 6 files changed, 73 insertions(+), 49 deletions(-) diff --git a/src/common/wallet.c b/src/common/wallet.c index 628d1277a..17f41d3a4 100644 --- a/src/common/wallet.c +++ b/src/common/wallet.c @@ -458,7 +458,7 @@ static int parse_keyexpr(buffer_t *in_buf, return WITH_ERROR(-1, "The key index in a placeholder must be at most 32767"); } - out->key_index = (int16_t) k; + out->k.key_index = (int16_t) k; } else if (c == 'm') { // parse a musig(key1,...,keyn) expression, where each key is a key expression if (!consume_characters(in_buf, "usig(", 5)) { @@ -534,7 +534,7 @@ static int parse_keyexpr(buffer_t *in_buf, musig_info->n = n_musig_keys; i_uint16(&musig_info->key_indexes, key_indexes); - i_musig_aggr_key_info(&out->musig_info, musig_info); + i_musig_aggr_key_info(&out->m.musig_info, musig_info); } else { return WITH_ERROR(-1, "Expected key expression starting with '@', or musig"); } diff --git a/src/common/wallet.h b/src/common/wallet.h index 9c0dc1aef..84db3ecf4 100644 --- a/src/common/wallet.h +++ b/src/common/wallet.h @@ -319,9 +319,13 @@ typedef struct { KeyExpressionType type; union { // type == 0 - int16_t key_index; // index of the key (common between V1 and V2) + struct { + int16_t key_index; // index of the key (common between V1 and V2) + } k; // type == 1 - rptr_musig_aggr_key_info_t musig_info; // only used in V2 + struct { + rptr_musig_aggr_key_info_t musig_info; // only used in V2 + } m; }; int16_t keyexpr_index; // index of the key expression in the descriptor template, in parsing order diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index e4875dae3..eb536180b 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -462,7 +462,12 @@ __attribute__((warn_unused_result)) static int get_derived_pubkey( serialized_extended_pubkey_t ext_pubkey; - int ret = get_extended_pubkey(dispatcher_context, wdi, key_expr->key_index, &ext_pubkey); + if (key_expr->type != KEY_EXPRESSION_NORMAL) { + PRINTF("Not implemented\n"); // TODO + return -1; + } + + int ret = get_extended_pubkey(dispatcher_context, wdi, key_expr->k.key_index, &ext_pubkey); if (ret < 0) { return -1; } @@ -1382,7 +1387,12 @@ static int get_bip44_purpose(const policy_node_t *descriptor_template) { return -1; } - if (kp->key_index != 0 || kp->num_first != 0 || kp->num_second != 1) { + if (kp->type != KEY_EXPRESSION_NORMAL) { + // any key expression that is not a plain xpub is not BIP-44 compliant + return -1; + } + + if (kp->k.key_index != 0 || kp->num_first != 0 || kp->num_second != 1) { return -1; } @@ -1514,7 +1524,7 @@ bool check_wallet_hmac(const uint8_t wallet_id[static 32], const uint8_t wallet_ static int get_keyexpr_by_index_in_tree(const policy_node_tree_t *tree, unsigned int i, const policy_node_t **out_tapleaf_ptr, - policy_node_keyexpr_t *out_keyexpr) { + policy_node_keyexpr_t **out_keyexpr) { if (tree->is_leaf) { int ret = get_keyexpr_by_index(r_policy_node(&tree->script), i, NULL, out_keyexpr); if (ret >= 0 && out_tapleaf_ptr != NULL && i < (unsigned) ret) { @@ -1540,16 +1550,12 @@ static int get_keyexpr_by_index_in_tree(const policy_node_tree_t *tree, } } -// TODO: generalize for musig. Note that this is broken for musig, as out_keyexpr -// can't be filled in for musig key expressions (as it's dynamic and contains -// relative pointers). We should probably refactor to return the pointer to the -// key expression and removing the out_keyexpr argument. int get_keyexpr_by_index(const policy_node_t *policy, unsigned int i, const policy_node_t **out_tapleaf_ptr, - policy_node_keyexpr_t *out_keyexpr) { + policy_node_keyexpr_t **out_keyexpr) { // make sure that out_keyexpr is a valid pointer, if the output is not needed - policy_node_keyexpr_t tmp; + policy_node_keyexpr_t *tmp; if (out_keyexpr == NULL) { out_keyexpr = &tmp; } @@ -1574,16 +1580,14 @@ int get_keyexpr_by_index(const policy_node_t *policy, case TOKEN_WPKH: { if (i == 0) { policy_node_with_key_t *wpkh = (policy_node_with_key_t *) policy; - memcpy(out_keyexpr, - r_policy_node_keyexpr(&wpkh->key), - sizeof(policy_node_keyexpr_t)); + *out_keyexpr = r_policy_node_keyexpr(&wpkh->key); } return 1; } case TOKEN_TR: { policy_node_tr_t *tr = (policy_node_tr_t *) policy; if (i == 0) { - memcpy(out_keyexpr, r_policy_node_keyexpr(&tr->key), sizeof(policy_node_keyexpr_t)); + *out_keyexpr = r_policy_node_keyexpr(&tr->key); } if (!isnull_policy_node_tree(&tr->tree)) { int ret_tree = get_keyexpr_by_index_in_tree( @@ -1610,7 +1614,7 @@ int get_keyexpr_by_index(const policy_node_t *policy, if (i < (unsigned int) node->n) { policy_node_keyexpr_t *key_expressions = r_policy_node_keyexpr(&node->keys); - memcpy(out_keyexpr, &key_expressions[i], sizeof(policy_node_keyexpr_t)); + *out_keyexpr = &key_expressions[i]; } return node->n; @@ -1722,18 +1726,28 @@ int get_keyexpr_by_index(const policy_node_t *policy, int count_distinct_keys_info(const policy_node_t *policy) { int ret = -1; - + policy_node_keyexpr_t *key_expression_ptr; int n_key_expressions = get_keyexpr_by_index(policy, 0, NULL, NULL); if (n_key_expressions < 0) { return -1; } for (int cur = 0; cur < n_key_expressions; ++cur) { - policy_node_keyexpr_t key_expression; - if (0 > get_keyexpr_by_index(policy, cur, NULL, &key_expression)) { + if (0 > get_keyexpr_by_index(policy, cur, NULL, &key_expression_ptr)) { return -1; } - ret = MAX(ret, key_expression.key_index + 1); + if (key_expression_ptr->type == KEY_EXPRESSION_NORMAL) { + ret = MAX(ret, key_expression_ptr->k.key_index + 1); + } else if (key_expression_ptr->type == KEY_EXPRESSION_MUSIG) { + musig_aggr_key_info_t *musig_info = + r_musig_aggr_key_info(&key_expression_ptr->m.musig_info); + uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); + for (int i = 0; i < musig_info->n; i++) { + ret = MAX(ret, key_indexes[i] + 1); + } + } else { + LEDGER_ASSERT(false, "Unknown key expression type"); + } } return ret; } @@ -1920,21 +1934,21 @@ int is_policy_sane(dispatcher_context_t *dispatcher_context, // proportional to the depth of the wallet policy's abstract syntax tree. for (int i = 0; i < n_key_expressions - 1; i++) { // no point in running this for the last key expression - policy_node_keyexpr_t kp_i; + policy_node_keyexpr_t *kp_i; if (0 > get_keyexpr_by_index(policy, i, NULL, &kp_i)) { return WITH_ERROR(-1, "Unexpected error retrieving key expressions from the policy"); } for (int j = i + 1; j < n_key_expressions; j++) { - policy_node_keyexpr_t kp_j; + policy_node_keyexpr_t *kp_j; if (0 > get_keyexpr_by_index(policy, j, NULL, &kp_j)) { return WITH_ERROR(-1, "Unexpected error retrieving key expressions from the policy"); } // key expressions for the same key must have disjoint derivation options - if (kp_i.key_index == kp_j.key_index) { - if (kp_i.num_first == kp_j.num_first || kp_i.num_first == kp_j.num_second || - kp_i.num_second == kp_j.num_first || kp_i.num_second == kp_j.num_second) { + if (kp_i->k.key_index == kp_j->k.key_index) { + if (kp_i->num_first == kp_j->num_first || kp_i->num_first == kp_j->num_second || + kp_i->num_second == kp_j->num_first || kp_i->num_second == kp_j->num_second) { return WITH_ERROR(-1, "Key expressions with repeated derivations in miniscript"); } diff --git a/src/handler/lib/policy.h b/src/handler/lib/policy.h index e5bce4bdc..6bcbc105a 100644 --- a/src/handler/lib/policy.h +++ b/src/handler/lib/policy.h @@ -190,13 +190,14 @@ bool check_wallet_hmac(const uint8_t wallet_id[static 32], const uint8_t wallet_ * If not NULL, and if the i-th key expression is in a tapleaf of the policy, receives the pointer * to the tapleaf's script. * @param[out] out_keyexpr - * If not NULL, it is a pointer that will receive the i-th key expression of the policy. + * If not NULL, it is a pointer that will receive a pointer to the i-th key expression of the + * policy. * @return the number of key expressions in the policy on success; -1 in case of error. */ __attribute__((warn_unused_result)) int get_keyexpr_by_index(const policy_node_t *policy, unsigned int i, const policy_node_t **out_tapleaf_ptr, - policy_node_keyexpr_t *out_keyexpr); + policy_node_keyexpr_t **out_keyexpr); /** * Determines the expected number of unique keys in the provided policy's key information. diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index da8b860f3..ac050234c 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -107,7 +107,7 @@ typedef struct { } output_info_t; typedef struct { - policy_node_keyexpr_t key_expression; + policy_node_keyexpr_t *key_expression_ptr; int cur_index; uint32_t fingerprint; uint8_t key_derivation_length; @@ -433,10 +433,10 @@ static int read_change_and_index_from_psbt_bip32_derivation( uint32_t addr_index = fpt_der[1 + der_len - 1]; // check if the 'change' derivation step is indeed coherent with key expression - if (change_step == keyexpr_info->key_expression.num_first) { + if (change_step == keyexpr_info->key_expression_ptr->num_first) { in_out->is_change = false; in_out->address_index = addr_index; - } else if (change_step == keyexpr_info->key_expression.num_second) { + } else if (change_step == keyexpr_info->key_expression_ptr->num_second) { in_out->is_change = true; in_out->address_index = addr_index; } else { @@ -446,7 +446,7 @@ static int read_change_and_index_from_psbt_bip32_derivation( // check that we can indeed derive the same key from the current key expression serialized_extended_pubkey_t pubkey; if (0 > derive_first_step_for_pubkey(&keyexpr_info->pubkey, - &keyexpr_info->key_expression, + keyexpr_info->key_expression_ptr, sign_psbt_cache, in_out->is_change, &pubkey)) @@ -669,12 +669,17 @@ static bool __attribute__((noinline)) fill_keyexpr_info_if_internal(dispatcher_c policy_map_key_info_t key_info; { uint8_t key_info_str[MAX_POLICY_KEY_INFO_LEN]; - int key_info_len = call_get_merkle_leaf_element(dc, - st->wallet_header.keys_info_merkle_root, - st->wallet_header.n_keys, - keyexpr_info->key_expression.key_index, - key_info_str, - sizeof(key_info_str)); + + // TODO: generalize for musig: keyexpr_info->key_expression_ptr->k.key_index is wrong + LEDGER_ASSERT(keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_NORMAL, "TODO"); + + int key_info_len = + call_get_merkle_leaf_element(dc, + st->wallet_header.keys_info_merkle_root, + st->wallet_header.n_keys, + keyexpr_info->key_expression_ptr->k.key_index, + key_info_str, + sizeof(key_info_str)); if (key_info_len < 0) { SEND_SW(dc, SW_BAD_STATE); // should never happen @@ -734,7 +739,7 @@ static bool find_first_internal_keyexpr(dispatcher_context_t *dc, int n_key_expressions = get_keyexpr_by_index(st->wallet_policy_map, keyexpr_info->cur_index, NULL, - &keyexpr_info->key_expression); + &keyexpr_info->key_expression_ptr); if (n_key_expressions < 0) { SEND_SW(dc, SW_BAD_STATE); // should never happen return false; @@ -2161,9 +2166,9 @@ static bool __attribute__((noinline)) sign_sighash_ecdsa_and_yield(dispatcher_co for (int i = 0; i < keyexpr_info->key_derivation_length; i++) { sign_path[i] = keyexpr_info->key_derivation[i]; } - sign_path[keyexpr_info->key_derivation_length] = input->in_out.is_change - ? keyexpr_info->key_expression.num_second - : keyexpr_info->key_expression.num_first; + sign_path[keyexpr_info->key_derivation_length] = + input->in_out.is_change ? keyexpr_info->key_expression_ptr->num_second + : keyexpr_info->key_expression_ptr->num_first; sign_path[keyexpr_info->key_derivation_length + 1] = input->in_out.address_index; int sign_path_len = keyexpr_info->key_derivation_length + 2; @@ -2230,8 +2235,8 @@ static bool __attribute__((noinline)) sign_sighash_schnorr_and_yield(dispatcher_ sign_path[i] = keyexpr_info->key_derivation[i]; } sign_path[keyexpr_info->key_derivation_length] = - input->in_out.is_change ? keyexpr_info->key_expression.num_second - : keyexpr_info->key_expression.num_first; + input->in_out.is_change ? keyexpr_info->key_expression_ptr->num_second + : keyexpr_info->key_expression_ptr->num_first; sign_path[keyexpr_info->key_derivation_length + 1] = input->in_out.address_index; int sign_path_len = keyexpr_info->key_derivation_length + 2; @@ -2687,7 +2692,7 @@ sign_transaction(dispatcher_context_t *dc, int n_key_expressions = get_keyexpr_by_index(st->wallet_policy_map, key_expression_index, &tapleaf_ptr, - &keyexpr_info.key_expression); + &keyexpr_info.key_expression_ptr); if (n_key_expressions < 0) { SEND_SW(dc, SW_BAD_STATE); // should never happen diff --git a/unit-tests/test_wallet.c b/unit-tests/test_wallet.c index 406c4a609..cd66a9253 100644 --- a/unit-tests/test_wallet.c +++ b/unit-tests/test_wallet.c @@ -39,7 +39,7 @@ static void check_key_expr_plain(const policy_node_keyexpr_t *ptr, uint32_t num_first, uint32_t num_second) { assert_int_equal(ptr->type, KEY_EXPRESSION_NORMAL); - assert_int_equal(ptr->key_index, key_index); + assert_int_equal(ptr->k.key_index, key_index); assert_int_equal(ptr->num_first, num_first); assert_int_equal(ptr->num_second, num_second); } @@ -51,7 +51,7 @@ static void check_key_expr_musig(const policy_node_keyexpr_t *ptr, uint32_t num_first, uint32_t num_second) { assert_int_equal(ptr->type, KEY_EXPRESSION_MUSIG); - musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&ptr->musig_info); + musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&ptr->m.musig_info); assert_int_equal(musig_info->n, n_musig_keys); uint16_t *musig_key_indexes = r_uint16(&musig_info->key_indexes); for (int i = 0; i < n_musig_keys; i++) { @@ -258,7 +258,7 @@ static void test_parse_policy_tr_multisig(void **state) { policy_node_tr_t *root = (policy_node_tr_t *) out; - assert_int_equal(r_policy_node_keyexpr(&root->key)->key_index, 0); + assert_int_equal(r_policy_node_keyexpr(&root->key)->k.key_index, 0); assert_int_equal(r_policy_node_keyexpr(&root->key)->num_first, 0); assert_int_equal(r_policy_node_keyexpr(&root->key)->num_second, 1); From 3dbf46411ab0fd52fd0c05bbaf6c36c476df1de4 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 9 Oct 2024 10:01:44 +0200 Subject: [PATCH 04/57] Add PSBT constants related to MuSig2; deleted unused constant --- src/common/psbt.h | 95 ++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/src/common/psbt.h b/src/common/psbt.h index a566cc135..d18ce9d9b 100644 --- a/src/common/psbt.h +++ b/src/common/psbt.h @@ -3,55 +3,58 @@ // clang-format off enum PsbtGlobalType { - PSBT_GLOBAL_UNSIGNED_TX = 0x00, - PSBT_GLOBAL_XPUB = 0x01, - PSBT_GLOBAL_TX_VERSION = 0x02, - PSBT_GLOBAL_FALLBACK_LOCKTIME = 0x03, - PSBT_GLOBAL_INPUT_COUNT = 0x04, - PSBT_GLOBAL_OUTPUT_COUNT = 0x05, - PSBT_GLOBAL_TX_MODIFIABLE = 0x06, - PSBT_GLOBAL_SIGHASH_SINGLE_INPUTS = 0x07, - PSBT_GLOBAL_VERSION = 0xFB, - PSBT_GLOBAL_PROPRIETARY = 0xFC + PSBT_GLOBAL_UNSIGNED_TX = 0x00, + PSBT_GLOBAL_XPUB = 0x01, + PSBT_GLOBAL_TX_VERSION = 0x02, + PSBT_GLOBAL_FALLBACK_LOCKTIME = 0x03, + PSBT_GLOBAL_INPUT_COUNT = 0x04, + PSBT_GLOBAL_OUTPUT_COUNT = 0x05, + PSBT_GLOBAL_TX_MODIFIABLE = 0x06, + PSBT_GLOBAL_VERSION = 0xFB, + PSBT_GLOBAL_PROPRIETARY = 0xFC }; enum PsbtInputType { - PSBT_IN_NON_WITNESS_UTXO = 0x00, - PSBT_IN_WITNESS_UTXO = 0x01, - PSBT_IN_PARTIAL_SIG = 0x02, - PSBT_IN_SIGHASH_TYPE = 0x03, - PSBT_IN_REDEEM_SCRIPT = 0x04, - PSBT_IN_WITNESS_SCRIPT = 0x05, - PSBT_IN_BIP32_DERIVATION = 0x06, - PSBT_IN_FINAL_SCRIPTSIG = 0x07, - PSBT_IN_FINAL_SCRIPTWITNESS = 0x08, - PSBT_IN_POR_COMMITMENT = 0x09, - PSBT_IN_RIPEMD160 = 0x0A, - PSBT_IN_SHA256 = 0x0B, - PSBT_IN_HASH160 = 0x0C, - PSBT_IN_HASH256 = 0x0D, - PSBT_IN_PREVIOUS_TXID = 0x0E, - PSBT_IN_OUTPUT_INDEX = 0x0F, - PSBT_IN_SEQUENCE = 0x10, - PSBT_IN_REQUIRED_TIME_LOCKTIME = 0x11, - PSBT_IN_REQUIRED_HEIGHT_LOCKTIME = 0x12, - PSBT_IN_TAP_KEY_SIG = 0x13, - PSBT_IN_TAP_SCRIPT_SIG = 0x14, - PSBT_IN_TAP_LEAF_SCRIPT = 0x15, - PSBT_IN_TAP_BIP32_DERIVATION = 0x16, - PSBT_IN_TAP_INTERNAL_KEY = 0x17, - PSBT_IN_TAP_MERKLE_ROOT = 0x18, - PSBT_IN_PROPRIETARY = 0xFC + PSBT_IN_NON_WITNESS_UTXO = 0x00, + PSBT_IN_WITNESS_UTXO = 0x01, + PSBT_IN_PARTIAL_SIG = 0x02, + PSBT_IN_SIGHASH_TYPE = 0x03, + PSBT_IN_REDEEM_SCRIPT = 0x04, + PSBT_IN_WITNESS_SCRIPT = 0x05, + PSBT_IN_BIP32_DERIVATION = 0x06, + PSBT_IN_FINAL_SCRIPTSIG = 0x07, + PSBT_IN_FINAL_SCRIPTWITNESS = 0x08, + PSBT_IN_POR_COMMITMENT = 0x09, + PSBT_IN_RIPEMD160 = 0x0A, + PSBT_IN_SHA256 = 0x0B, + PSBT_IN_HASH160 = 0x0C, + PSBT_IN_HASH256 = 0x0D, + PSBT_IN_PREVIOUS_TXID = 0x0E, + PSBT_IN_OUTPUT_INDEX = 0x0F, + PSBT_IN_SEQUENCE = 0x10, + PSBT_IN_REQUIRED_TIME_LOCKTIME = 0x11, + PSBT_IN_REQUIRED_HEIGHT_LOCKTIME = 0x12, + PSBT_IN_TAP_KEY_SIG = 0x13, + PSBT_IN_TAP_SCRIPT_SIG = 0x14, + PSBT_IN_TAP_LEAF_SCRIPT = 0x15, + PSBT_IN_TAP_BIP32_DERIVATION = 0x16, + PSBT_IN_TAP_INTERNAL_KEY = 0x17, + PSBT_IN_TAP_MERKLE_ROOT = 0x18, + PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS = 0x1A, + PSBT_IN_MUSIG2_PUB_NONCE = 0x1B, + PSBT_IN_MUSIG2_PARTIAL_SIG = 0x1C, + PSBT_IN_PROPRIETARY = 0xFC }; enum PsbtOutputType { - PSBT_OUT_REDEEM_SCRIPT = 0x00, - PSBT_OUT_WITNESS_SCRIPT = 0x01, - PSBT_OUT_BIP32_DERIVATION = 0x02, - PSBT_OUT_AMOUNT = 0x03, - PSBT_OUT_SCRIPT = 0x04, - PSBT_OUT_TAP_INTERNAL_KEY = 0x05, - PSBT_OUT_TAP_TREE = 0x06, - PSBT_OUT_TAP_BIP32_DERIVATION = 0x07, - PSBT_OUT_PROPRIETARY = 0xFC -}; \ No newline at end of file + PSBT_OUT_REDEEM_SCRIPT = 0x00, + PSBT_OUT_WITNESS_SCRIPT = 0x01, + PSBT_OUT_BIP32_DERIVATION = 0x02, + PSBT_OUT_AMOUNT = 0x03, + PSBT_OUT_SCRIPT = 0x04, + PSBT_OUT_TAP_INTERNAL_KEY = 0x05, + PSBT_OUT_TAP_TREE = 0x06, + PSBT_OUT_TAP_BIP32_DERIVATION = 0x07, + PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS = 0x08, + PSBT_OUT_PROPRIETARY = 0xFC +}; From 92f1b54fc4951f3bc3d7a6d3bab44ebc6bec439d Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 28 Feb 2024 17:12:10 +0100 Subject: [PATCH 05/57] Moved secp256k1 constants to a separate module --- src/crypto.c | 34 +--------------------------------- src/secp256k1.c | 23 +++++++++++++++++++++++ src/secp256k1.h | 24 ++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 33 deletions(-) create mode 100644 src/secp256k1.c create mode 100644 src/secp256k1.h diff --git a/src/crypto.c b/src/crypto.c index ccb95cfe6..feaf4e7f7 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -39,39 +39,7 @@ #include "crypto.h" -/** - * Generator for secp256k1, value 'g' defined in "Standards for Efficient Cryptography" - * (SEC2) 2.7.1. - */ -// clang-format off -static const uint8_t secp256k1_generator[] = { - 0x04, - 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, - 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, - 0x48, 0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, 0x5D, 0xA4, 0xFB, 0xFC, 0x0E, 0x11, 0x08, 0xA8, - 0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54, 0x19, 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10, 0xD4, 0xB8}; -// clang-format on - -/** - * Modulo for secp256k1 - */ -static const uint8_t secp256k1_p[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}; - -/** - * Curve order for secp256k1 - */ -static const uint8_t secp256k1_n[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41}; - -/** - * (p + 1)/4, used to calculate square roots in secp256k1 - */ -static const uint8_t secp256k1_sqr_exponent[] = { - 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x0c}; +#include "secp256k1.h" /* BIP0341 tags for computing the tagged hashes when tweaking public keys */ static const uint8_t BIP0341_taptweak_tag[] = {'T', 'a', 'p', 'T', 'w', 'e', 'a', 'k'}; diff --git a/src/secp256k1.c b/src/secp256k1.c new file mode 100644 index 000000000..2ddb714a6 --- /dev/null +++ b/src/secp256k1.c @@ -0,0 +1,23 @@ +#include "secp256k1.h" + +// clang-format off +const uint8_t secp256k1_generator[65] = { + 0x04, + 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, + 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, + 0x48, 0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, 0x5D, 0xA4, 0xFB, 0xFC, 0x0E, 0x11, 0x08, 0xA8, + 0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54, 0x19, 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10, 0xD4, 0xB8}; + +const uint8_t secp256k1_p[32] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f}; + +const uint8_t secp256k1_n[32] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41}; + +const uint8_t secp256k1_sqr_exponent[32] = { + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x0c}; + +// clang-format on diff --git a/src/secp256k1.h b/src/secp256k1.h new file mode 100644 index 000000000..c6ead0f33 --- /dev/null +++ b/src/secp256k1.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +/** + * Generator for secp256k1, value 'g' defined in "Standards for Efficient Cryptography" + * (SEC2) 2.7.1. + */ +extern const uint8_t secp256k1_generator[65]; + +/** + * Modulo for secp256k1 + */ +extern const uint8_t secp256k1_p[32]; + +/** + * Curve order for secp256k1 + */ +extern const uint8_t secp256k1_n[32]; + +/** + * (p + 1)/4, used to calculate square roots in secp256k1 + */ +extern const uint8_t secp256k1_sqr_exponent[32]; From 4e6bae5d7541ee8bf276b663b1cdeea372619713 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Thu, 29 Feb 2024 09:49:27 +0100 Subject: [PATCH 06/57] Added address generation tests for musig --- tests/test_get_wallet_address.py | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/test_get_wallet_address.py b/tests/test_get_wallet_address.py index 199b2a82e..5aae1d5c3 100644 --- a/tests/test_get_wallet_address.py +++ b/tests/test_get_wallet_address.py @@ -303,6 +303,41 @@ def test_get_wallet_address_tr_script_sortedmulti(client: RaggerClient): assert res == "tb1pdzk72dnvz3246474p4m5a97u43h6ykt2qcjrrhk6y0fkg8hx2mvswwgvv7" +def test_get_wallet_address_tr_musig_keypath(client: RaggerClient): + wallet = WalletPolicy( + name="Musig in keypath", + descriptor_template="tr(musig(@0,@1)/**)", + keys_info=[ + "[f5acc2fd/44'/1'/0']tpubDCwYjpDhUdPGP5rS3wgNg13mTrrjBuG8V9VpWbyptX6TRPbNoZVXsoVUSkCjmQ8jJycjuDKBb9eataSymXakTTaGifxR6kmVsfFehH1ZgJT", + "tpubDCwYjpDhUdPGQWG6wG6hkBJuWFZEtrn7j3xwG3i8XcQabcGC53xWZm1hSXrUPFS5UvZ3QhdPSjXWNfWmFGTioARHuG5J7XguEjgg7p8PxAm" + ] + ) + + wallet_hmac = bytes.fromhex( + "05b7b4bccd3188effc24de8fd67e83231d8486772800884db0d81bad19f2be3e") + + res = client.get_wallet_address(wallet, wallet_hmac, 0, 3, False) + assert res == "tb1p7j9azx5xwt5fp3t99wnj4885yfcqynhz645ntflxr9dxr2g8ndnq32xa2m" + + +def test_get_wallet_address_tr_musig_scriptpath(client: RaggerClient): + wallet = WalletPolicy( + name="Musig in script path", + descriptor_template="tr(@0/**,pk(musig(@1,@2)/**))", + keys_info=[ + "tpubD6NzVbkrYhZ4WLczPJWReQycCJdd6YVWXubbVUFnJ5KgU5MDQrD998ZJLSmaB7GVcCnJSDWprxmrGkJ6SvgQC6QAffVpqSvonXmeizXcrkN", + "[f5acc2fd/44'/1'/0']tpubDCwYjpDhUdPGP5rS3wgNg13mTrrjBuG8V9VpWbyptX6TRPbNoZVXsoVUSkCjmQ8jJycjuDKBb9eataSymXakTTaGifxR6kmVsfFehH1ZgJT", + "tpubDCwYjpDhUdPGQWG6wG6hkBJuWFZEtrn7j3xwG3i8XcQabcGC53xWZm1hSXrUPFS5UvZ3QhdPSjXWNfWmFGTioARHuG5J7XguEjgg7p8PxAm" + ] + ) + + wallet_hmac = bytes.fromhex( + "b22397b717949ede59c3c9f31c987acda098471211f754b6633c87054c1efb51") + + res = client.get_wallet_address(wallet, wallet_hmac, 0, 3, False) + assert res == "tb1pmx5syrz67lwdy8dsmvlta5h5ahfn6k9pg8qw3y0jn698xj0duxpq3k94zq" + + def test_get_wallet_address_large_addr_index(client: RaggerClient): # 2**31 - 1 is the largest index allowed, per BIP-32 From 654e1e228b2ad86d97fab57a5529d4e4aacc6073 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Thu, 29 Feb 2024 09:50:34 +0100 Subject: [PATCH 07/57] Made crypto_tr_lift_x and crypto_tr_tagged_hash functions public --- src/crypto.c | 16 ++++++++-------- src/crypto.h | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index feaf4e7f7..67578f5f4 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -434,7 +434,7 @@ void crypto_tr_tapleaf_hash_init(cx_sha256_t *hash_context) { crypto_tr_tagged_hash_init(hash_context, BIP0341_tapleaf_tag, sizeof(BIP0341_tapleaf_tag)); } -static int crypto_tr_lift_x(const uint8_t x[static 32], uint8_t out[static 65]) { +int crypto_tr_lift_x(const uint8_t x[static 32], uint8_t out[static 65]) { // save memory by reusing output buffer for intermediate results uint8_t *y = out + 1 + 32; // we use the memory for the x-coordinate of the output as a temporary variable @@ -473,13 +473,13 @@ static int crypto_tr_lift_x(const uint8_t x[static 32], uint8_t out[static 65]) // Computes a tagged hash according to BIP-340. // If data2_len > 0, then data2 must be non-NULL and the `data` and `data2` arrays are concatenated. -static void crypto_tr_tagged_hash(const uint8_t *tag, - uint16_t tag_len, - const uint8_t *data, - uint16_t data_len, - const uint8_t *data2, - uint16_t data2_len, - uint8_t out[static CX_SHA256_SIZE]) { +void crypto_tr_tagged_hash(const uint8_t *tag, + uint16_t tag_len, + const uint8_t *data, + uint16_t data_len, + const uint8_t *data2, + uint16_t data2_len, + uint8_t out[static CX_SHA256_SIZE]) { // First compute hashtag, reuse out buffer for that cx_sha256_hash(tag, tag_len, out); diff --git a/src/crypto.h b/src/crypto.h index cb8394bb5..f56e24350 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -343,6 +343,43 @@ int crypto_ecdsa_sign_sha256_hash_with_key(const uint32_t bip32_path[], */ void crypto_tr_tagged_hash_init(cx_sha256_t *hash_context, const uint8_t *tag, uint16_t tag_len); +/** + * Implementation of the lift_x procedure as defined by BIP-0340. + * + * @param[in] x + * Pointer to a 32-byte array. + * @param[out] out + * Pointer to an array that will received the output as an uncompressed 65-bytes pubkey. + */ +int crypto_tr_lift_x(const uint8_t x[static 32], uint8_t out[static 65]); + +/** + * A tagged hash as defined in BIP-0340. + * + * @param[in] tag + * Pointer to an array containing the tag of the tagged hash. + * @param[in] tag_len + * Length of the tag. + * @param[in] data + * Pointer to an array of data. + * @param[in] data_len + * Length of the array pointed by `data`. + * @param[in] data2 + * If NULL, ignored. If not null, a pointer to an array of data; the tagged hash for the + * concatenation of `data` and `data2` is computed. + * @param[in] data2_len + * If `data2` is NULL, ignored. Otherwise, the length the array pointed by `data2`. + * @param[out] out + * Pointer to a 32-byte array that will receive the result. + */ +void crypto_tr_tagged_hash(const uint8_t *tag, + uint16_t tag_len, + const uint8_t *data, + uint16_t data_len, + const uint8_t *data2, + uint16_t data2_len, + uint8_t out[static CX_SHA256_SIZE]); + /** * Initializes the "tagged" SHA256 hash with tag "TapLeaf", used for tapscript leaves. * From bbde126d9724f29b353393b11f8df306dd720b60 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Thu, 29 Feb 2024 10:25:09 +0100 Subject: [PATCH 08/57] Musig key aggregation and address generation --- src/handler/lib/policy.c | 35 ++++++++-- src/musig/musig.c | 146 +++++++++++++++++++++++++++++++++++++++ src/musig/musig.h | 45 ++++++++++++ 3 files changed, 219 insertions(+), 7 deletions(-) create mode 100644 src/musig/musig.c create mode 100644 src/musig/musig.h diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index eb536180b..d8ec5276a 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -5,6 +5,7 @@ #include "../lib/get_merkle_leaf_element.h" #include "../lib/get_preimage.h" #include "../../crypto.h" +#include "../../musig/musig.h" #include "../../common/base58.h" #include "../../common/bitvector.h" #include "../../common/read.h" @@ -462,14 +463,34 @@ __attribute__((warn_unused_result)) static int get_derived_pubkey( serialized_extended_pubkey_t ext_pubkey; - if (key_expr->type != KEY_EXPRESSION_NORMAL) { - PRINTF("Not implemented\n"); // TODO - return -1; - } + if (key_expr->type == KEY_EXPRESSION_NORMAL) { + if (0 > get_extended_pubkey(dispatcher_context, wdi, key_expr->k.key_index, &ext_pubkey)) { + return -1; + } + } else if (key_expr->type == KEY_EXPRESSION_MUSIG) { + musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); + uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); + plain_pk_t keys[MAX_PUBKEYS_PER_MUSIG]; + for (int i = 0; i < musig_info->n; i++) { + // we use ext_pubkey as a temporary variable; will overwrite later + if (0 > get_extended_pubkey(dispatcher_context, wdi, key_indexes[i], &ext_pubkey)) { + return -1; + } + memcpy(keys[i], ext_pubkey.compressed_pubkey, sizeof(ext_pubkey.compressed_pubkey)); + } - int ret = get_extended_pubkey(dispatcher_context, wdi, key_expr->k.key_index, &ext_pubkey); - if (ret < 0) { - return -1; + musig_keyagg_context_t musig_ctx; + musig_key_agg(keys, musig_info->n, &musig_ctx); + + // compute the aggregated extended pubkey + memset(&ext_pubkey, 0, sizeof(ext_pubkey)); + write_u32_be(ext_pubkey.version, 0, BIP32_PUBKEY_VERSION); + + ext_pubkey.compressed_pubkey[0] = (musig_ctx.Q.y[31] % 2 == 0) ? 2 : 3; + memcpy(&ext_pubkey.compressed_pubkey[1], musig_ctx.Q.x, sizeof(musig_ctx.Q.x)); + memcpy(&ext_pubkey.chain_code, BIP_MUSIG_CHAINCODE, sizeof(BIP_MUSIG_CHAINCODE)); + } else { + LEDGER_ASSERT(false, "Unreachable code"); } // we derive the // child of this pubkey diff --git a/src/musig/musig.c b/src/musig/musig.c new file mode 100644 index 000000000..b4ffb4432 --- /dev/null +++ b/src/musig/musig.c @@ -0,0 +1,146 @@ +#include + +#include "musig.h" + +#include "../crypto.h" +#include "../secp256k1.h" + +static const uint8_t BIP0327_keyagg_coeff_tag[] = + {'K', 'e', 'y', 'A', 'g', 'g', ' ', 'c', 'o', 'e', 'f', 'f', 'i', 'c', 'i', 'e', 'n', 't'}; +static const uint8_t BIP0327_keyagg_list_tag[] = + {'K', 'e', 'y', 'A', 'g', 'g', ' ', 'l', 'i', 's', 't'}; + +static inline bool is_point_infinite(const point_t *P) { + return P->prefix == 0; +} + +static inline void set_point_infinite(point_t *P) { + memset(P->raw, 0, sizeof(point_t)); +} + +static int point_add(const point_t *P1, const point_t *P2, point_t *out) { + if (is_point_infinite(P1)) { + memmove(out->raw, P2->raw, sizeof(point_t)); + return CX_OK; + } + if (is_point_infinite(P2)) { + memmove(out->raw, P1->raw, sizeof(point_t)); + return CX_OK; + } + if (memcmp(P1->x, P2->x, 32) == 0 && memcmp(P1->y, P2->y, 32) != 0) { + memset(out->raw, 0, sizeof(point_t)); + return CX_OK; + } + return cx_ecfp_add_point_no_throw(CX_CURVE_SECP256K1, out->raw, P1->raw, P2->raw); +} + +// out can be equal to P +static int point_negate(const point_t *P, point_t *out) { + if (is_point_infinite(P)) { + set_point_infinite(out); + return 0; + } + memmove(out->x, P->x, 32); + + if (CX_OK != cx_math_sub_no_throw(out->y, secp256k1_p, P->y, 32)) return -1; + + out->prefix = 4; + return 0; +} + +static int cpoint(const uint8_t x[33], point_t *out) { + crypto_tr_lift_x(&x[1], out->raw); + if (is_point_infinite(out)) { + PRINTF("Invalid compressed point\n"); + return -1; + } + if (x[0] == 2) { + return 0; + } else if (x[0] == 3) { + if (0 > point_negate(out, out)) { + return -1; + } + return 0; + } else { + PRINTF("Invalid compressed point: invalid prefix\n"); + return -1; + } +} + +static void musig_get_second_key(const plain_pk_t pubkeys[], size_t n_keys, plain_pk_t out) { + for (size_t i = 0; i < n_keys; i++) { + if (memcmp(pubkeys[0], pubkeys[i], sizeof(plain_pk_t)) != 0) { + memcpy(out, pubkeys[i], sizeof(plain_pk_t)); + return; + } + } + memset(out, 0, sizeof(plain_pk_t)); +} + +static void musig_hash_keys(const plain_pk_t pubkeys[], size_t n_keys, uint8_t out[static 32]) { + cx_sha256_t hash_context; + crypto_tr_tagged_hash_init(&hash_context, + BIP0327_keyagg_list_tag, + sizeof(BIP0327_keyagg_list_tag)); + for (size_t i = 0; i < n_keys; i++) { + crypto_hash_update(&hash_context.header, pubkeys[i], sizeof(plain_pk_t)); + } + crypto_hash_digest(&hash_context.header, out, 32); +} + +static void musig_key_agg_coeff_internal(const plain_pk_t pubkeys[], + size_t n_keys, + const plain_pk_t pk_, + const plain_pk_t pk2, + uint8_t out[static CX_SHA256_SIZE]) { + uint8_t L[CX_SHA256_SIZE]; + musig_hash_keys(pubkeys, n_keys, L); + if (memcmp(pk_, pk2, sizeof(plain_pk_t)) == 0) { + memset(out, 0, CX_SHA256_SIZE); + out[31] = 1; + } else { + crypto_tr_tagged_hash(BIP0327_keyagg_coeff_tag, + sizeof(BIP0327_keyagg_coeff_tag), + L, + sizeof(L), + pk_, + sizeof(plain_pk_t), + out); + + // result modulo secp256k1_n + int res = cx_math_modm_no_throw(out, CX_SHA256_SIZE, secp256k1_n, sizeof(secp256k1_n)); + + LEDGER_ASSERT(res == CX_OK, "Modular reduction failed"); + } +} + +int musig_key_agg(const plain_pk_t pubkeys[], size_t n_keys, musig_keyagg_context_t *ctx) { + plain_pk_t pk2; + musig_get_second_key(pubkeys, n_keys, pk2); + + set_point_infinite(&ctx->Q); + for (size_t i = 0; i < n_keys; i++) { + point_t P; + + // set P := P_i + if (0 > cpoint(pubkeys[i], &P)) { + PRINTF("Invalid pubkey in musig_key_agg\n"); + return -1; + } + + uint8_t a_i[32]; + musig_key_agg_coeff_internal(pubkeys, n_keys, pubkeys[i], pk2, a_i); + + // set P := a_i * P_i + if (CX_OK != cx_ecfp_scalar_mult_no_throw(CX_CURVE_SECP256K1, P.raw, a_i, 32)) { + PRINTF("Scalar multiplication failed in musig_key_agg\n"); + return -1; + } + + point_add(&ctx->Q, &P, &ctx->Q); + } + memset(ctx->tacc, 0, sizeof(ctx->tacc)); + memset(ctx->gacc, 0, sizeof(ctx->gacc)); + ctx->gacc[31] = 1; + return 0; +} diff --git a/src/musig/musig.h b/src/musig/musig.h new file mode 100644 index 000000000..d17f89b67 --- /dev/null +++ b/src/musig/musig.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include + +// TODO: rename once BIP number is assigned +static uint8_t BIP_MUSIG_CHAINCODE[32] = { + 0x86, 0x80, 0x87, 0xCA, 0x02, 0xA6, 0xF9, 0x74, 0xC4, 0x59, 0x89, 0x24, 0xC3, 0x6B, 0x57, 0x76, + 0x2D, 0x32, 0xCB, 0x45, 0x71, 0x71, 0x67, 0xE3, 0x00, 0x62, 0x2C, 0x71, 0x67, 0xE3, 0x89, 0x65}; + +typedef uint8_t plain_pk_t[33]; +typedef uint8_t xonly_pk_t[32]; + +// An uncompressed pubkey, encoded as 04||x||y, where x and y are 32-byte big-endian coordinates. +// If the first byte (prefix) is 0, encodes the point at infinity. +typedef struct { + union { + uint8_t raw[65]; + struct { + uint8_t prefix; // 0 for the point at infinity, otherwise 4. + uint8_t x[32]; + uint8_t y[32]; + }; + }; +} point_t; + +typedef struct musig_keyagg_context_s { + point_t Q; + uint8_t gacc[32]; + uint8_t tacc[32]; +} musig_keyagg_context_t; + +/** + * Computes the KeyAgg Context per BIP-0327. + * + * @param[in] pubkeys + * Pointer to a list of pubkeys. + * @param[in] n_keys + * Number of pubkeys. + * @param[out] musig_keyagg_context_t + * Pointer to receive the musig KeyAgg Context. + * + * @return 0 on success, a negative number in case of error. + */ +int musig_key_agg(const plain_pk_t pubkeys[], size_t n_keys, musig_keyagg_context_t *ctx); From 7b7af767fc5c6f4f96a0f671e76e20eac0b7b969 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Fri, 1 Mar 2024 15:13:28 +0100 Subject: [PATCH 09/57] Compute aggregate xpub for musig() in descriptors in the python client library --- bitcoin_client/ledger_bitcoin/bip0327.py | 177 +++++++++++++++++++++++ bitcoin_client/ledger_bitcoin/client.py | 56 ++++++- 2 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 bitcoin_client/ledger_bitcoin/bip0327.py diff --git a/bitcoin_client/ledger_bitcoin/bip0327.py b/bitcoin_client/ledger_bitcoin/bip0327.py new file mode 100644 index 000000000..8d4680791 --- /dev/null +++ b/bitcoin_client/ledger_bitcoin/bip0327.py @@ -0,0 +1,177 @@ +# extracted from the BIP327 reference implementation: https://github.com/bitcoin/bips/blob/b3701faef2bdb98a0d7ace4eedbeefa2da4c89ed/bip-0327/reference.py + +# Only contains the key aggregation part of the library + +# The code in this source file is distributed under the BSD-3-Clause. + +# autopep8: off + +from typing import List, Optional, Tuple, NewType, NamedTuple +import hashlib + +# +# The following helper functions were copied from the BIP-340 reference implementation: +# https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py +# + +p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F +n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 + +# Points are tuples of X and Y coordinates and the point at infinity is +# represented by the None keyword. +G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8) + +Point = Tuple[int, int] + +# This implementation can be sped up by storing the midstate after hashing +# tag_hash instead of rehashing it all the time. +def tagged_hash(tag: str, msg: bytes) -> bytes: + tag_hash = hashlib.sha256(tag.encode()).digest() + return hashlib.sha256(tag_hash + tag_hash + msg).digest() + +def is_infinite(P: Optional[Point]) -> bool: + return P is None + +def x(P: Point) -> int: + assert not is_infinite(P) + return P[0] + +def y(P: Point) -> int: + assert not is_infinite(P) + return P[1] + +def point_add(P1: Optional[Point], P2: Optional[Point]) -> Optional[Point]: + if P1 is None: + return P2 + if P2 is None: + return P1 + if (x(P1) == x(P2)) and (y(P1) != y(P2)): + return None + if P1 == P2: + lam = (3 * x(P1) * x(P1) * pow(2 * y(P1), p - 2, p)) % p + else: + lam = ((y(P2) - y(P1)) * pow(x(P2) - x(P1), p - 2, p)) % p + x3 = (lam * lam - x(P1) - x(P2)) % p + return (x3, (lam * (x(P1) - x3) - y(P1)) % p) + +def point_mul(P: Optional[Point], n: int) -> Optional[Point]: + R = None + for i in range(256): + if (n >> i) & 1: + R = point_add(R, P) + P = point_add(P, P) + return R + +def bytes_from_int(x: int) -> bytes: + return x.to_bytes(32, byteorder="big") + +def lift_x(b: bytes) -> Optional[Point]: + x = int_from_bytes(b) + if x >= p: + return None + y_sq = (pow(x, 3, p) + 7) % p + y = pow(y_sq, (p + 1) // 4, p) + if pow(y, 2, p) != y_sq: + return None + return (x, y if y & 1 == 0 else p-y) + +def int_from_bytes(b: bytes) -> int: + return int.from_bytes(b, byteorder="big") + +def has_even_y(P: Point) -> bool: + assert not is_infinite(P) + return y(P) % 2 == 0 + +# +# End of helper functions copied from BIP-340 reference implementation. +# + +PlainPk = NewType('PlainPk', bytes) +XonlyPk = NewType('XonlyPk', bytes) + +# There are two types of exceptions that can be raised by this implementation: +# - ValueError for indicating that an input doesn't conform to some function +# precondition (e.g. an input array is the wrong length, a serialized +# representation doesn't have the correct format). +# - InvalidContributionError for indicating that a signer (or the +# aggregator) is misbehaving in the protocol. +# +# Assertions are used to (1) satisfy the type-checking system, and (2) check for +# inconvenient events that can't happen except with negligible probability (e.g. +# output of a hash function is 0) and can't be manually triggered by any +# signer. + +# This exception is raised if a party (signer or nonce aggregator) sends invalid +# values. Actual implementations should not crash when receiving invalid +# contributions. Instead, they should hold the offending party accountable. +class InvalidContributionError(Exception): + def __init__(self, signer, contrib): + self.signer = signer + # contrib is one of "pubkey", "pubnonce", "aggnonce", or "psig". + self.contrib = contrib + +infinity = None + +def xbytes(P: Point) -> bytes: + return bytes_from_int(x(P)) + +def cbytes(P: Point) -> bytes: + a = b'\x02' if has_even_y(P) else b'\x03' + return a + xbytes(P) + +def point_negate(P: Optional[Point]) -> Optional[Point]: + if P is None: + return P + return (x(P), p - y(P)) + +def cpoint(x: bytes) -> Point: + if len(x) != 33: + raise ValueError('x is not a valid compressed point.') + P = lift_x(x[1:33]) + if P is None: + raise ValueError('x is not a valid compressed point.') + if x[0] == 2: + return P + elif x[0] == 3: + P = point_negate(P) + assert P is not None + return P + else: + raise ValueError('x is not a valid compressed point.') + +KeyAggContext = NamedTuple('KeyAggContext', [('Q', Point), + ('gacc', int), + ('tacc', int)]) + +def key_agg(pubkeys: List[PlainPk]) -> KeyAggContext: + pk2 = get_second_key(pubkeys) + u = len(pubkeys) + Q = infinity + for i in range(u): + try: + P_i = cpoint(pubkeys[i]) + except ValueError: + raise InvalidContributionError(i, "pubkey") + a_i = key_agg_coeff_internal(pubkeys, pubkeys[i], pk2) + Q = point_add(Q, point_mul(P_i, a_i)) + # Q is not the point at infinity except with negligible probability. + assert(Q is not None) + gacc = 1 + tacc = 0 + return KeyAggContext(Q, gacc, tacc) + +def hash_keys(pubkeys: List[PlainPk]) -> bytes: + return tagged_hash('KeyAgg list', b''.join(pubkeys)) + +def get_second_key(pubkeys: List[PlainPk]) -> PlainPk: + u = len(pubkeys) + for j in range(1, u): + if pubkeys[j] != pubkeys[0]: + return pubkeys[j] + return PlainPk(b'\x00'*33) + +def key_agg_coeff_internal(pubkeys: List[PlainPk], pk_: PlainPk, pk2: PlainPk) -> int: + L = hash_keys(pubkeys) + if pk_ == pk2: + return 1 + return int_from_bytes(tagged_hash('KeyAgg coefficient', L + pk_)) % n diff --git a/bitcoin_client/ledger_bitcoin/client.py b/bitcoin_client/ledger_bitcoin/client.py index 351370320..94c22aed8 100644 --- a/bitcoin_client/ledger_bitcoin/client.py +++ b/bitcoin_client/ledger_bitcoin/client.py @@ -3,6 +3,7 @@ import base64 from io import BytesIO, BufferedReader +from .embit import base58 from .embit.base import EmbitError from .embit.descriptor import Descriptor from .embit.networks import NETWORKS @@ -17,9 +18,10 @@ from .merkle import get_merkleized_map_commitment from .wallet import WalletPolicy, WalletType from .psbt import PSBT, normalize_psbt -from . import segwit_addr from ._serialize import deser_string +from .bip0327 import key_agg, cbytes + def parse_stream_to_map(f: BufferedReader) -> Mapping[bytes, bytes]: result = {} @@ -39,6 +41,53 @@ def parse_stream_to_map(f: BufferedReader) -> Mapping[bytes, bytes]: return result +def aggr_xpub(pubkeys: List[bytes], chain: Chain) -> str: + BIP_MUSIG_CHAINCODE = bytes.fromhex( + "868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965") + ctx = key_agg(pubkeys) + compressed_pubkey = cbytes(ctx.Q) + + # Serialize according to BIP-32 + if chain == Chain.MAIN: + version = 0x0488B21E + else: + version = 0x043587CF + + return base58.encode_check(b''.join([ + version.to_bytes(4, byteorder='big'), + b'\x00', # depth + b'\x00\x00\x00\x00', # parent fingerprint + b'\x00\x00\x00\x00', # child number + BIP_MUSIG_CHAINCODE, + compressed_pubkey + ])) + + +# Given a valid descriptor, replaces each musig() (if any) with the +# corresponding synthetic xpub/tpub. +def replace_musigs(desc: str, chain: Chain) -> str: + while True: + musig_start = desc.find("musig(") + if musig_start == -1: + break + musig_end = desc.find(")", musig_start) + if musig_end == -1: + raise ValueError("Invalid descriptor template") + + key_and_origs = desc[musig_start+6:musig_end].split(",") + pubkeys = [] + for key_orig in key_and_origs: + orig_end = key_orig.find("]") + xpub = key_orig if orig_end == -1 else key_orig[orig_end+1:] + pubkeys.append(base58.decode_check(xpub)[-33:]) + + # replace with the aggregate xpub + desc = desc[:musig_start] + \ + aggr_xpub(pubkeys, chain) + desc[musig_end+1:] + + return desc + + def _make_partial_signature(pubkey_augm: bytes, signature: bytes) -> PartialSignature: if len(pubkey_augm) == 64: # tapscript spend: pubkey_augm is the concatenation of: @@ -273,6 +322,11 @@ def sign_message(self, message: Union[str, bytes], bip32_path: str) -> str: def _derive_address_for_policy(self, wallet: WalletPolicy, change: bool, address_index: int) -> Optional[str]: desc_str = wallet.get_descriptor(change) + + # Since embit does not support musig() in descriptors, we replace each + # occurrence with the corresponding aggregated xpub + desc_str = replace_musigs(desc_str, self.chain) + try: desc = Descriptor.from_string(desc_str) From 4ebfc259bdd93f60fb99e1e834f398c7a3f471cf Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 9 Apr 2024 11:50:53 +0200 Subject: [PATCH 10/57] Add musig2 fields to PSBT class --- bitcoin_client/ledger_bitcoin/psbt.py | 92 +++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/bitcoin_client/ledger_bitcoin/psbt.py b/bitcoin_client/ledger_bitcoin/psbt.py index 16de47d23..37c4e626b 100644 --- a/bitcoin_client/ledger_bitcoin/psbt.py +++ b/bitcoin_client/ledger_bitcoin/psbt.py @@ -1,6 +1,8 @@ # Original version: https://github.com/bitcoin-core/HWI/blob/3fe369d0379212fae1c72729a179d133b0adc872/hwilib/key.py # Distributed under the MIT License. +# fmt: off + """ PSBT Classes and Utilities ************************** @@ -107,6 +109,9 @@ class PartiallySignedInput: PSBT_IN_TAP_BIP32_DERIVATION = 0x16 PSBT_IN_TAP_INTERNAL_KEY = 0x17 PSBT_IN_TAP_MERKLE_ROOT = 0x18 + PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS = 0x1a + PSBT_IN_MUSIG2_PUB_NONCE = 0x1b + PSBT_IN_MUSIG2_PARTIAL_SIG = 0x1c def __init__(self, version: int) -> None: self.non_witness_utxo: Optional[CTransaction] = None @@ -129,6 +134,9 @@ def __init__(self, version: int) -> None: self.tap_bip32_paths: Dict[bytes, Tuple[Set[bytes], KeyOriginInfo]] = {} self.tap_internal_key = b"" self.tap_merkle_root = b"" + self.musig2_participant_pubkeys: Dict[bytes, List[bytes]] = {} + self.musig2_pub_nonces: Dict[Tuple[bytes, bytes, Optional[bytes]], bytes] = {} + self.musig2_partial_sigs: Dict[Tuple[bytes, bytes, Optional[bytes]], bytes] = {} self.unknown: Dict[bytes, bytes] = {} self.version: int = version @@ -355,6 +363,51 @@ def deserialize(self, f: Readable) -> None: self.tap_merkle_root = deser_string(f) if len(self.tap_merkle_root) != 32: raise PSBTSerializationError("Input Taproot merkle root is not 32 bytes") + elif key_type == PartiallySignedInput.PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS: + if key in key_lookup: + raise PSBTSerializationError("Duplicate key, input Musig2 participant pubkeys already provided") + elif len(key) != 1 + 33: + raise PSBTSerializationError("Input Musig2 aggregate compressed pubkey is not 33 bytes") + + pubkeys_cat = deser_string(f) + if len(pubkeys_cat) == 0: + raise PSBTSerializationError("The list of compressed pubkeys for Musig2 cannot be empty") + if (len(pubkeys_cat) % 33) != 0: + raise PSBTSerializationError("The compressed pubkeys for Musig2 must be exactly 33 bytes long") + pubkeys = [] + for i in range(0, len(pubkeys_cat), 33): + pubkeys.append(pubkeys_cat[i: i + 33]) + + self.musig2_participant_pubkeys[key[1:]] = pubkeys + elif key_type == PartiallySignedInput.PSBT_IN_MUSIG2_PUB_NONCE: + if key in key_lookup: + raise PSBTSerializationError("Duplicate key, Musig2 public nonce already provided") + elif len(key) not in [1 + 33 + 33, 1 + 33 + 33 + 32]: + raise PSBTSerializationError("Invalid key length for Musig2 public nonce") + + providing_pubkey = key[1:1+33] + aggregate_pubkey = key[1+33:1+33+33] + tapleaf_hash = None if len(key) == 1 + 33 + 33 else key[1+33+33:] + + public_nonces = deser_string(f) + if len(public_nonces) != 66: + raise PSBTSerializationError("The length of the public nonces in Musig2 must be exactly 66 bytes") + + self.musig2_pub_nonces[(providing_pubkey, aggregate_pubkey, tapleaf_hash)] = public_nonces + elif key_type == PartiallySignedInput.PSBT_IN_MUSIG2_PARTIAL_SIG: + if key in key_lookup: + raise PSBTSerializationError("Duplicate key, Musig2 partial signature already provided") + elif len(key) not in [1 + 33 + 33, 1 + 33 + 33 + 32]: + raise PSBTSerializationError("Invalid key length for Musig2 partial signature") + + providing_pubkey = key[1:1+33] + aggregate_pubkey = key[1+33:1+33+33] + tapleaf_hash = None if len(key) == 1 + 33 + 33 else key[1+33+33:] + + partial_sig = deser_string(f) + if len(partial_sig) != 32: + raise PSBTSerializationError("The length of the partial signature in Musig2 must be exactly 32 bytes") + self.musig2_partial_sigs[(providing_pubkey, aggregate_pubkey, tapleaf_hash)] = partial_sig else: if key in self.unknown: raise PSBTSerializationError("Duplicate key, key for unknown value already provided") @@ -466,6 +519,20 @@ def serialize(self) -> bytes: r += ser_string(ser_compact_size(PartiallySignedInput.PSBT_IN_REQUIRED_HEIGHT_LOCKTIME)) r += ser_string(struct.pack(" None: self.redeem_script = b"" @@ -497,6 +565,9 @@ def __init__(self, version: int) -> None: self.tap_internal_key = b"" self.tap_tree = b"" self.tap_bip32_paths: Dict[bytes, Tuple[Set[bytes], KeyOriginInfo]] = {} + + self.musig2_participant_pubkeys: Dict[bytes, List[bytes]] = {} + self.unknown: Dict[bytes, bytes] = {} self.version: int = version @@ -593,6 +664,22 @@ def deserialize(self, f: Readable) -> None: for i in range(0, num_hashes): leaf_hashes.add(vs.read(32)) self.tap_bip32_paths[xonly] = (leaf_hashes, KeyOriginInfo.deserialize(vs.read())) + elif key_type == PartiallySignedOutput.PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS: + if key in key_lookup: + raise PSBTSerializationError("Duplicate key, output Musig2 participant pubkeys already provided") + elif len(key) != 1 + 33: + raise PSBTSerializationError("Output Musig2 aggregate compressed pubkey is not 33 bytes") + + pubkeys_cat = deser_string(f) + if len(pubkeys_cat) == 0: + raise PSBTSerializationError("The list of compressed pubkeys for Musig2 cannot be empty") + if (len(pubkeys_cat) % 33) != 0: + raise PSBTSerializationError("The compressed pubkeys for Musig2 must be exactly 33 bytes long") + pubkeys = [] + for i in range(0, len(pubkeys_cat), 33): + pubkeys.append(pubkeys_cat[i: i + 33]) + + self.musig2_participant_pubkeys[key[1:]] = pubkeys else: if key in self.unknown: raise PSBTSerializationError("Duplicate key, key for unknown value already provided") @@ -650,6 +737,11 @@ def serialize(self) -> bytes: value += origin.serialize() r += ser_string(value) + for pk, pubkeys in self.musig2_participant_pubkeys.items(): + r += ser_string(ser_compact_size( + PartiallySignedOutput.PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS) + pk) + r += ser_string(b''.join(pubkeys)) + for key, value in sorted(self.unknown.items()): r += ser_string(key) r += ser_string(value) From 9f48eb8fae323087758b65f867fcc1261e9b4cba Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 17 Apr 2024 16:02:21 +0200 Subject: [PATCH 11/57] Added python standalone implementation of MuSig2 signing, and tests --- test_utils/bip0327.py | 465 +++++++++++++++++++ test_utils/musig2.py | 843 ++++++++++++++++++++++++++++++++++ test_utils/taproot.py | 216 ++++++++- test_utils/taproot_sighash.py | 85 ++++ tests/test_musig2.py | 69 +++ 5 files changed, 1676 insertions(+), 2 deletions(-) create mode 100644 test_utils/bip0327.py create mode 100644 test_utils/musig2.py create mode 100644 test_utils/taproot_sighash.py create mode 100644 tests/test_musig2.py diff --git a/test_utils/bip0327.py b/test_utils/bip0327.py new file mode 100644 index 000000000..79149743f --- /dev/null +++ b/test_utils/bip0327.py @@ -0,0 +1,465 @@ +# from https://github.com/bitcoin/bips/blob/b3701faef2bdb98a0d7ace4eedbeefa2da4c89ed/bip-0327/reference.py +# Distributed as part of BIP-0327 under the BSD-3-Clause license + +# BIP327 reference implementation +# +# WARNING: This implementation is for demonstration purposes only and _not_ to +# be used in production environments. The code is vulnerable to timing attacks, +# for example. + +# fmt: off + +from typing import List, Optional, Tuple, NewType, NamedTuple +import hashlib +import secrets + +# +# The following helper functions were copied from the BIP-340 reference implementation: +# https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py +# + +p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F +n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 + +# Points are tuples of X and Y coordinates and the point at infinity is +# represented by the None keyword. +G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8) + +Point = Tuple[int, int] + +# This implementation can be sped up by storing the midstate after hashing +# tag_hash instead of rehashing it all the time. +def tagged_hash(tag: str, msg: bytes) -> bytes: + tag_hash = hashlib.sha256(tag.encode()).digest() + return hashlib.sha256(tag_hash + tag_hash + msg).digest() + +def is_infinite(P: Optional[Point]) -> bool: + return P is None + +def x(P: Point) -> int: + assert not is_infinite(P) + return P[0] + +def y(P: Point) -> int: + assert not is_infinite(P) + return P[1] + +def point_add(P1: Optional[Point], P2: Optional[Point]) -> Optional[Point]: + if P1 is None: + return P2 + if P2 is None: + return P1 + if (x(P1) == x(P2)) and (y(P1) != y(P2)): + return None + if P1 == P2: + lam = (3 * x(P1) * x(P1) * pow(2 * y(P1), p - 2, p)) % p + else: + lam = ((y(P2) - y(P1)) * pow(x(P2) - x(P1), p - 2, p)) % p + x3 = (lam * lam - x(P1) - x(P2)) % p + return (x3, (lam * (x(P1) - x3) - y(P1)) % p) + +def point_mul(P: Optional[Point], n: int) -> Optional[Point]: + R = None + for i in range(256): + if (n >> i) & 1: + R = point_add(R, P) + P = point_add(P, P) + return R + +def bytes_from_int(x: int) -> bytes: + return x.to_bytes(32, byteorder="big") + +def lift_x(b: bytes) -> Optional[Point]: + x = int_from_bytes(b) + if x >= p: + return None + y_sq = (pow(x, 3, p) + 7) % p + y = pow(y_sq, (p + 1) // 4, p) + if pow(y, 2, p) != y_sq: + return None + return (x, y if y & 1 == 0 else p-y) + +def int_from_bytes(b: bytes) -> int: + return int.from_bytes(b, byteorder="big") + +def has_even_y(P: Point) -> bool: + assert not is_infinite(P) + return y(P) % 2 == 0 + +def schnorr_verify(msg: bytes, pubkey: bytes, sig: bytes) -> bool: + if len(msg) != 32: + raise ValueError('The message must be a 32-byte array.') + if len(pubkey) != 32: + raise ValueError('The public key must be a 32-byte array.') + if len(sig) != 64: + raise ValueError('The signature must be a 64-byte array.') + P = lift_x(pubkey) + r = int_from_bytes(sig[0:32]) + s = int_from_bytes(sig[32:64]) + if (P is None) or (r >= p) or (s >= n): + return False + e = int_from_bytes(tagged_hash("BIP0340/challenge", sig[0:32] + pubkey + msg)) % n + R = point_add(point_mul(G, s), point_mul(P, n - e)) + if (R is None) or (not has_even_y(R)) or (x(R) != r): + return False + return True + +# +# End of helper functions copied from BIP-340 reference implementation. +# + +PlainPk = NewType('PlainPk', bytes) +XonlyPk = NewType('XonlyPk', bytes) + +# There are two types of exceptions that can be raised by this implementation: +# - ValueError for indicating that an input doesn't conform to some function +# precondition (e.g. an input array is the wrong length, a serialized +# representation doesn't have the correct format). +# - InvalidContributionError for indicating that a signer (or the +# aggregator) is misbehaving in the protocol. +# +# Assertions are used to (1) satisfy the type-checking system, and (2) check for +# inconvenient events that can't happen except with negligible probability (e.g. +# output of a hash function is 0) and can't be manually triggered by any +# signer. + +# This exception is raised if a party (signer or nonce aggregator) sends invalid +# values. Actual implementations should not crash when receiving invalid +# contributions. Instead, they should hold the offending party accountable. +class InvalidContributionError(Exception): + def __init__(self, signer, contrib): + self.signer = signer + # contrib is one of "pubkey", "pubnonce", "aggnonce", or "psig". + self.contrib = contrib + +infinity = None + +def xbytes(P: Point) -> bytes: + return bytes_from_int(x(P)) + +def cbytes(P: Point) -> bytes: + a = b'\x02' if has_even_y(P) else b'\x03' + return a + xbytes(P) + +def cbytes_ext(P: Optional[Point]) -> bytes: + if is_infinite(P): + return (0).to_bytes(33, byteorder='big') + assert P is not None + return cbytes(P) + +def point_negate(P: Optional[Point]) -> Optional[Point]: + if P is None: + return P + return (x(P), p - y(P)) + +def cpoint(x: bytes) -> Point: + if len(x) != 33: + raise ValueError('x is not a valid compressed point.') + P = lift_x(x[1:33]) + if P is None: + raise ValueError('x is not a valid compressed point.') + if x[0] == 2: + return P + elif x[0] == 3: + P = point_negate(P) + assert P is not None + return P + else: + raise ValueError('x is not a valid compressed point.') + +def cpoint_ext(x: bytes) -> Optional[Point]: + if x == (0).to_bytes(33, 'big'): + return None + else: + return cpoint(x) + +# Return the plain public key corresponding to a given secret key +def individual_pk(seckey: bytes) -> PlainPk: + d0 = int_from_bytes(seckey) + if not (1 <= d0 <= n - 1): + raise ValueError('The secret key must be an integer in the range 1..n-1.') + P = point_mul(G, d0) + assert P is not None + return PlainPk(cbytes(P)) + +def key_sort(pubkeys: List[PlainPk]) -> List[PlainPk]: + pubkeys.sort() + return pubkeys + +KeyAggContext = NamedTuple('KeyAggContext', [('Q', Point), + ('gacc', int), + ('tacc', int)]) + +def get_xonly_pk(keyagg_ctx: KeyAggContext) -> XonlyPk: + Q, _, _ = keyagg_ctx + return XonlyPk(xbytes(Q)) + +def key_agg(pubkeys: List[PlainPk]) -> KeyAggContext: + pk2 = get_second_key(pubkeys) + u = len(pubkeys) + Q = infinity + for i in range(u): + try: + P_i = cpoint(pubkeys[i]) + except ValueError: + raise InvalidContributionError(i, "pubkey") + a_i = key_agg_coeff_internal(pubkeys, pubkeys[i], pk2) + Q = point_add(Q, point_mul(P_i, a_i)) + # Q is not the point at infinity except with negligible probability. + assert(Q is not None) + gacc = 1 + tacc = 0 + return KeyAggContext(Q, gacc, tacc) + +def hash_keys(pubkeys: List[PlainPk]) -> bytes: + return tagged_hash('KeyAgg list', b''.join(pubkeys)) + +def get_second_key(pubkeys: List[PlainPk]) -> PlainPk: + u = len(pubkeys) + for j in range(1, u): + if pubkeys[j] != pubkeys[0]: + return pubkeys[j] + return PlainPk(b'\x00'*33) + +def key_agg_coeff(pubkeys: List[PlainPk], pk_: PlainPk) -> int: + pk2 = get_second_key(pubkeys) + return key_agg_coeff_internal(pubkeys, pk_, pk2) + +def key_agg_coeff_internal(pubkeys: List[PlainPk], pk_: PlainPk, pk2: PlainPk) -> int: + L = hash_keys(pubkeys) + if pk_ == pk2: + return 1 + return int_from_bytes(tagged_hash('KeyAgg coefficient', L + pk_)) % n + +def apply_tweak(keyagg_ctx: KeyAggContext, tweak: bytes, is_xonly: bool) -> KeyAggContext: + if len(tweak) != 32: + raise ValueError('The tweak must be a 32-byte array.') + Q, gacc, tacc = keyagg_ctx + if is_xonly and not has_even_y(Q): + g = n - 1 + else: + g = 1 + t = int_from_bytes(tweak) + if t >= n: + raise ValueError('The tweak must be less than n.') + Q_ = point_add(point_mul(Q, g), point_mul(G, t)) + if Q_ is None: + raise ValueError('The result of tweaking cannot be infinity.') + gacc_ = g * gacc % n + tacc_ = (t + g * tacc) % n + return KeyAggContext(Q_, gacc_, tacc_) + +def bytes_xor(a: bytes, b: bytes) -> bytes: + return bytes(x ^ y for x, y in zip(a, b)) + +def nonce_hash(rand: bytes, pk: PlainPk, aggpk: XonlyPk, i: int, msg_prefixed: bytes, extra_in: bytes) -> int: + buf = b'' + buf += rand + buf += len(pk).to_bytes(1, 'big') + buf += pk + buf += len(aggpk).to_bytes(1, 'big') + buf += aggpk + buf += msg_prefixed + buf += len(extra_in).to_bytes(4, 'big') + buf += extra_in + buf += i.to_bytes(1, 'big') + return int_from_bytes(tagged_hash('MuSig/nonce', buf)) + +def nonce_gen_internal(rand_: bytes, sk: Optional[bytes], pk: PlainPk, aggpk: Optional[XonlyPk], msg: Optional[bytes], extra_in: Optional[bytes]) -> Tuple[bytearray, bytes]: + if sk is not None: + rand = bytes_xor(sk, tagged_hash('MuSig/aux', rand_)) + else: + rand = rand_ + if aggpk is None: + aggpk = XonlyPk(b'') + if msg is None: + msg_prefixed = b'\x00' + else: + msg_prefixed = b'\x01' + msg_prefixed += len(msg).to_bytes(8, 'big') + msg_prefixed += msg + if extra_in is None: + extra_in = b'' + k_1 = nonce_hash(rand, pk, aggpk, 0, msg_prefixed, extra_in) % n + k_2 = nonce_hash(rand, pk, aggpk, 1, msg_prefixed, extra_in) % n + # k_1 == 0 or k_2 == 0 cannot occur except with negligible probability. + assert k_1 != 0 + assert k_2 != 0 + R_s1 = point_mul(G, k_1) + R_s2 = point_mul(G, k_2) + assert R_s1 is not None + assert R_s2 is not None + pubnonce = cbytes(R_s1) + cbytes(R_s2) + secnonce = bytearray(bytes_from_int(k_1) + bytes_from_int(k_2) + pk) + return secnonce, pubnonce + +def nonce_gen(sk: Optional[bytes], pk: PlainPk, aggpk: Optional[XonlyPk], msg: Optional[bytes], extra_in: Optional[bytes]) -> Tuple[bytearray, bytes]: + if sk is not None and len(sk) != 32: + raise ValueError('The optional byte array sk must have length 32.') + if aggpk is not None and len(aggpk) != 32: + raise ValueError('The optional byte array aggpk must have length 32.') + rand_ = secrets.token_bytes(32) + return nonce_gen_internal(rand_, sk, pk, aggpk, msg, extra_in) + +def nonce_agg(pubnonces: List[bytes]) -> bytes: + u = len(pubnonces) + aggnonce = b'' + for j in (1, 2): + R_j = infinity + for i in range(u): + try: + R_ij = cpoint(pubnonces[i][(j-1)*33:j*33]) + except ValueError: + raise InvalidContributionError(i, "pubnonce") + R_j = point_add(R_j, R_ij) + aggnonce += cbytes_ext(R_j) + return aggnonce + +SessionContext = NamedTuple('SessionContext', [('aggnonce', bytes), + ('pubkeys', List[PlainPk]), + ('tweaks', List[bytes]), + ('is_xonly', List[bool]), + ('msg', bytes)]) + +def key_agg_and_tweak(pubkeys: List[PlainPk], tweaks: List[bytes], is_xonly: List[bool]): + if len(tweaks) != len(is_xonly): + raise ValueError('The `tweaks` and `is_xonly` arrays must have the same length.') + keyagg_ctx = key_agg(pubkeys) + v = len(tweaks) + for i in range(v): + keyagg_ctx = apply_tweak(keyagg_ctx, tweaks[i], is_xonly[i]) + return keyagg_ctx + +def get_session_values(session_ctx: SessionContext) -> Tuple[Point, int, int, int, Point, int]: + (aggnonce, pubkeys, tweaks, is_xonly, msg) = session_ctx + Q, gacc, tacc = key_agg_and_tweak(pubkeys, tweaks, is_xonly) + b = int_from_bytes(tagged_hash('MuSig/noncecoef', aggnonce + xbytes(Q) + msg)) % n + try: + R_1 = cpoint_ext(aggnonce[0:33]) + R_2 = cpoint_ext(aggnonce[33:66]) + except ValueError: + # Nonce aggregator sent invalid nonces + raise InvalidContributionError(None, "aggnonce") + R_ = point_add(R_1, point_mul(R_2, b)) + R = R_ if not is_infinite(R_) else G + assert R is not None + e = int_from_bytes(tagged_hash('BIP0340/challenge', xbytes(R) + xbytes(Q) + msg)) % n + return (Q, gacc, tacc, b, R, e) + +def get_session_key_agg_coeff(session_ctx: SessionContext, P: Point) -> int: + (_, pubkeys, _, _, _) = session_ctx + pk = PlainPk(cbytes(P)) + if pk not in pubkeys: + raise ValueError('The signer\'s pubkey must be included in the list of pubkeys.') + return key_agg_coeff(pubkeys, pk) + +def sign(secnonce: bytearray, sk: bytes, session_ctx: SessionContext) -> bytes: + (Q, gacc, _, b, R, e) = get_session_values(session_ctx) + k_1_ = int_from_bytes(secnonce[0:32]) + k_2_ = int_from_bytes(secnonce[32:64]) + # Overwrite the secnonce argument with zeros such that subsequent calls of + # sign with the same secnonce raise a ValueError. + secnonce[:64] = bytearray(b'\x00'*64) + if not 0 < k_1_ < n: + raise ValueError('first secnonce value is out of range.') + if not 0 < k_2_ < n: + raise ValueError('second secnonce value is out of range.') + k_1 = k_1_ if has_even_y(R) else n - k_1_ + k_2 = k_2_ if has_even_y(R) else n - k_2_ + d_ = int_from_bytes(sk) + if not 0 < d_ < n: + raise ValueError('secret key value is out of range.') + P = point_mul(G, d_) + assert P is not None + pk = cbytes(P) + if not pk == secnonce[64:97]: + raise ValueError('Public key does not match nonce_gen argument') + a = get_session_key_agg_coeff(session_ctx, P) + g = 1 if has_even_y(Q) else n - 1 + d = g * gacc * d_ % n + s = (k_1 + b * k_2 + e * a * d) % n + psig = bytes_from_int(s) + R_s1 = point_mul(G, k_1_) + R_s2 = point_mul(G, k_2_) + assert R_s1 is not None + assert R_s2 is not None + pubnonce = cbytes(R_s1) + cbytes(R_s2) + # Optional correctness check. The result of signing should pass signature verification. + assert partial_sig_verify_internal(psig, pubnonce, pk, session_ctx) + return psig + +def det_nonce_hash(sk_: bytes, aggothernonce: bytes, aggpk: bytes, msg: bytes, i: int) -> int: + buf = b'' + buf += sk_ + buf += aggothernonce + buf += aggpk + buf += len(msg).to_bytes(8, 'big') + buf += msg + buf += i.to_bytes(1, 'big') + return int_from_bytes(tagged_hash('MuSig/deterministic/nonce', buf)) + +def deterministic_sign(sk: bytes, aggothernonce: bytes, pubkeys: List[PlainPk], tweaks: List[bytes], is_xonly: List[bool], msg: bytes, rand: Optional[bytes]) -> Tuple[bytes, bytes]: + if rand is not None: + sk_ = bytes_xor(sk, tagged_hash('MuSig/aux', rand)) + else: + sk_ = sk + aggpk = get_xonly_pk(key_agg_and_tweak(pubkeys, tweaks, is_xonly)) + + k_1 = det_nonce_hash(sk_, aggothernonce, aggpk, msg, 0) % n + k_2 = det_nonce_hash(sk_, aggothernonce, aggpk, msg, 1) % n + # k_1 == 0 or k_2 == 0 cannot occur except with negligible probability. + assert k_1 != 0 + assert k_2 != 0 + + R_s1 = point_mul(G, k_1) + R_s2 = point_mul(G, k_2) + assert R_s1 is not None + assert R_s2 is not None + pubnonce = cbytes(R_s1) + cbytes(R_s2) + secnonce = bytearray(bytes_from_int(k_1) + bytes_from_int(k_2) + individual_pk(sk)) + try: + aggnonce = nonce_agg([pubnonce, aggothernonce]) + except Exception: + raise InvalidContributionError(None, "aggothernonce") + session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) + psig = sign(secnonce, sk, session_ctx) + return (pubnonce, psig) + +def partial_sig_verify(psig: bytes, pubnonces: List[bytes], pubkeys: List[PlainPk], tweaks: List[bytes], is_xonly: List[bool], msg: bytes, i: int) -> bool: + if len(pubnonces) != len(pubkeys): + raise ValueError('The `pubnonces` and `pubkeys` arrays must have the same length.') + if len(tweaks) != len(is_xonly): + raise ValueError('The `tweaks` and `is_xonly` arrays must have the same length.') + aggnonce = nonce_agg(pubnonces) + session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) + return partial_sig_verify_internal(psig, pubnonces[i], pubkeys[i], session_ctx) + +def partial_sig_verify_internal(psig: bytes, pubnonce: bytes, pk: bytes, session_ctx: SessionContext) -> bool: + (Q, gacc, _, b, R, e) = get_session_values(session_ctx) + s = int_from_bytes(psig) + if s >= n: + return False + R_s1 = cpoint(pubnonce[0:33]) + R_s2 = cpoint(pubnonce[33:66]) + Re_s_ = point_add(R_s1, point_mul(R_s2, b)) + Re_s = Re_s_ if has_even_y(R) else point_negate(Re_s_) + P = cpoint(pk) + if P is None: + return False + a = get_session_key_agg_coeff(session_ctx, P) + g = 1 if has_even_y(Q) else n - 1 + g_ = g * gacc % n + return point_mul(G, s) == point_add(Re_s, point_mul(P, e * a * g_ % n)) + +def partial_sig_agg(psigs: List[bytes], session_ctx: SessionContext) -> bytes: + (Q, _, tacc, _, R, e) = get_session_values(session_ctx) + s = 0 + u = len(psigs) + for i in range(u): + s_i = int_from_bytes(psigs[i]) + if s_i >= n: + raise InvalidContributionError(i, "psig") + s = (s + s_i) % n + g = 1 if has_even_y(Q) else n - 1 + s = (s + e * g * tacc) % n + return xbytes(R) + bytes_from_int(s) diff --git a/test_utils/musig2.py b/test_utils/musig2.py new file mode 100644 index 000000000..fc0ce3544 --- /dev/null +++ b/test_utils/musig2.py @@ -0,0 +1,843 @@ +""" +This module contains a complete, minimal, standalone MuSig cosigner implementation. +It is NOT a cryptographically secure implementation, and it is only to be used for +testing purposes. + +In lack of a library for wallet policies in python, a minimal version of it for +the purpose of parsing and processing tr() descriptors is implemented here, using +embit for the the final task of compiling simple miniscript descriptors to Script. + +The main objects and methods exported in this class are: + +- PsbtMusig2Cosigner: an abstract class that represents a cosigner in MuSig2. +- HotMusig2Cosigner: an implementation of PsbtMusig2Cosigner that contains a hot + extended private key. Useful for tests. +- run_musig2_test: tests a full signing cycle for a generic list of PsbtMusig2Cosigners. +""" + + +import hashlib +import hmac +from io import BytesIO +import re +from re import Match + +from dataclasses import dataclass +import secrets +import struct +from typing import Dict, Iterable, Iterator, List, Optional, Set, Tuple, Union +from abc import ABC, abstractmethod + +import base58 + +from test_utils.taproot_sighash import SIGHASH_DEFAULT, TaprootSignatureHash + +from . import bip0327, bip0340, sha256 +from . import taproot + +from bitcoin_client.ledger_bitcoin.embit.descriptor.miniscript import Miniscript +from bitcoin_client.ledger_bitcoin.psbt import PSBT, PartiallySignedInput +from bitcoin_client.ledger_bitcoin.key import G, ExtendedKey, bytes_to_point, point_add, point_mul, point_to_bytes +from bitcoin_client.ledger_bitcoin.wallet import WalletPolicy + + +HARDENED_INDEX = 0x80000000 + + +def tapleaf_hash(script: Optional[bytes], leaf_version=b'\xC0') -> Optional[bytes]: + if script is None: + return None + return taproot.tagged_hash( + "TapLeaf", + leaf_version + taproot.ser_script(script) + ) + + +@dataclass +class PlainKeyPlaceholder: + key_index: int + num1: int + num2: int + + +@dataclass +class Musig2KeyPlaceholder: + key_indexes: List[int] + num1: int + num2: int + + +KeyPlaceholder = Union[PlainKeyPlaceholder, Musig2KeyPlaceholder] + + +def parse_placeholder(placeholder_str: str) -> KeyPlaceholder: + """Parses a placeholder string to create a KeyPlaceholder object.""" + if placeholder_str.startswith('musig'): + key_indexes_str = placeholder_str[6:placeholder_str.index( + ')/<')].split(',') + key_indexes = [int(index.strip('@')) for index in key_indexes_str] + + nums_part = placeholder_str[placeholder_str.index(')/<') + 3:-3] + num1, num2 = map(int, nums_part.split(';')) + + return Musig2KeyPlaceholder(key_indexes, num1, num2) + elif placeholder_str.startswith('@'): + parts = placeholder_str.split('/') + key_index = int(parts[0].strip('@')) + + # Remove '<' from the start and '>' from the end + nums_part = parts[1][1:-1] + num1, num2 = map(int, nums_part.split(';')) + + return PlainKeyPlaceholder(key_index, num1, num2) + else: + raise ValueError("Invalid placeholder string") + + +def extract_placeholders(desc_tmpl: str) -> List[KeyPlaceholder]: + """Extracts and parses all placeholders in a descriptor template, from left to right.""" + + pattern = r'musig\((?:@\d+,)*(?:@\d+)\)/<\d+;\d+>/\*|@\d+/<\d+;\d+>/\*' + matches = [(match.group(), match.start()) + for match in re.finditer(pattern, desc_tmpl)] + sorted_matches = sorted(matches, key=lambda x: x[1]) + return [parse_placeholder(match[0]) for match in sorted_matches] + + +def musig(pubkeys: Iterable[bytes], version_bytes: bytes) -> Tuple[str, bip0327.KeyAggContext]: + """ + Constructs the musig2 aggregated extended public key from a list of + compressed public keys, and the version bytes. + """ + + assert all(len(pk) == 33 for pk in pubkeys) + assert len(version_bytes) == 4 + + depth = b'\x00' + fingerprint = b'\x00\x00\x00\x00' + child_number = b'\x00\x00\x00\x00' + + key_agg_ctx = bip0327.key_agg(pubkeys) + Q = key_agg_ctx.Q + compressed_pubkey = ( + b'\x02' if Q[1] % 2 == 0 else b'\x03') + bip0327.get_xonly_pk(key_agg_ctx) + chaincode = bytes.fromhex( + "868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965") + ext_pubkey = version_bytes + depth + fingerprint + \ + child_number + chaincode + compressed_pubkey + return base58.b58encode_check(ext_pubkey).decode(), key_agg_ctx + + +def aggregate_musig_pubkey(keys_info: Iterable[str]) -> Tuple[str, bip0327.KeyAggContext]: + """ + Constructs the musig2 aggregated extended public key from the list of keys info + of the participating keys. + """ + + pubkeys: list[bytes] = [] + versions: Set[str] = set() + for ki in keys_info: + start = ki.find(']') + xpub = ki[start + 1:] + xpub_bytes = base58.b58decode_check(xpub) + versions.add(xpub_bytes[:4]) + pubkeys.append(xpub_bytes[-33:]) + + if len(versions) > 1: + raise ValueError( + "All the extended public keys should be from the same network") + + return musig(pubkeys, versions.pop()) + + +def derive_from_key_info(key_info: str, steps: List[int]) -> str: + start = key_info.find(']') + pk = ExtendedKey.deserialize(key_info[start + 1:]) + return pk.derive_pub_path(steps).to_string() + + +def derive_plain_descriptor(desc_tmpl: str, keys_info: List[str], is_change: bool, address_index: int): + """ + Given a wallet policy, and the change/address_index combination, computes the corresponding descriptor. + It replaces /** with /<0;1>/* + It also replaces each musig() key expression with the corresponding xpub. + The resulting descriptor can be used with descriptor libraries that do not support musig or wallet policies. + """ + + desc_tmpl = desc_tmpl.replace("/**", "/<0;1>/*") + desc_tmpl = desc_tmpl.replace("*", str(address_index)) + + # Replace each with M if is_change is False, otherwise with N + def replace_m_n(match: Match[str]): + m, n = match.groups() + return m if not is_change else n + + desc_tmpl = re.sub(r'<([^;]+);([^>]+)>', replace_m_n, desc_tmpl) + + # Replace musig(...) expressions + def replace_musig(match: Match[str]): + musig_content = match.group(1) + steps = [int(x) for x in match.group(2).split("/")] + + assert len(steps) == 2 + + key_indexes = [int(i.strip('@')) for i in musig_content.split(',')] + key_infos = [keys_info[i] for i in key_indexes] + agg_xpub = aggregate_musig_pubkey(key_infos)[0] + + return derive_from_key_info(agg_xpub, steps) + + desc_tmpl = re.sub(r'musig\(([^)]+)\)/(\d+/\d+)', replace_musig, desc_tmpl) + + # Replace @i/a/b with the i-th element in keys_info, deriving the key appropriately + # to get a plain xpub + def replace_key_index(match): + index, step1, step2 = [int(x) for x in match.group(1).split('/')] + return derive_from_key_info(keys_info[index], [step1, step2]) + + desc_tmpl = re.sub(r'@(\d+/\d+/\d+)', replace_key_index, desc_tmpl) + + return desc_tmpl + + +class Tree: + """ + Recursive structure that represents a taptree, or one of its subtrees. + It can either contain a single descriptor template (if it's a tapleaf), or exactly two child Trees. + """ + + def __init__(self, content: Union[str, Tuple['Tree', 'Tree']]): + if isinstance(content, str): + self.script = content + self.left, self.right = (None, None) + else: + self.script = None + self.left, self.right = content + + @property + def is_leaf(self) -> bool: + return self.script is not None + + def __str__(self): + if self.is_leaf: + return self.script + else: + return f'{{{str(self.left)},{str(self.right)}}}' + + def placeholders(self) -> Iterator[Tuple[KeyPlaceholder, str]]: + """ + Generates an iterator over the placeholders contained in the scripts of the tree's leaf nodes. + + Yields: + Iterator[Tuple[KeyPlaceholder, str]]: An iterator over tuples containing a KeyPlaceholder and its associated script. + """ + + if self.is_leaf: + assert self.script is not None + for placeholder in extract_placeholders(self.script): + yield (placeholder, self.script) + else: + assert self.left is not None and self.right is not None + for placeholder, script in self.left.placeholders(): + yield (placeholder, script) + for placeholder, script in self.right.placeholders(): + yield (placeholder, script) + + def get_taptree_hash(self, keys_info: List[str], is_change: bool, address_index: int) -> bytes: + if self.is_leaf: + assert self.script is not None + leaf_desc = derive_plain_descriptor( + self.script, keys_info, is_change, address_index) + + s = BytesIO(leaf_desc.encode()) + desc: Miniscript = Miniscript.read_from( + s, taproot=True) + + return tapleaf_hash(desc.compile()) + + else: + assert self.left is not None and self.right is not None + left_h = self.left.get_taptree_hash( + keys_info, is_change, address_index) + right_h = self.left.get_taptree_hash( + keys_info, is_change, address_index) + if left_h <= right_h: + return taproot.tagged_hash("TapBranch", left_h + right_h) + else: + return taproot.tagged_hash("TapBranch", right_h + left_h) + + +class TrDescriptorTemplate: + """ + Represents a descriptor template for a tr(KEY) or a tr(KEY,TREE). + This is minimal implementation in order to enable iterating over the placeholders, + and compile the corresponding leaf scripts. + """ + + def __init__(self, key: KeyPlaceholder, tree=Optional[Tree]): + self.key: KeyPlaceholder = key + self.tree: Optional[Tree] = tree + + @classmethod + def from_string(cls, input_string): + parser = cls.Parser(input_string.replace("/**", "/<0;1>/*")) + return parser.parse() + + class Parser: + def __init__(self, input): + self.input = input + self.index = 0 + self.length = len(input) + + def parse(self): + if self.input.startswith('tr('): + self.consume('tr(') + key = self.parse_keyplaceholder() + tree = None + if self.peek() == ',': + self.consume(',') + tree = self.parse_tree() + self.consume(')') + return TrDescriptorTemplate(key, tree) + else: + raise Exception( + "Syntax error: Input does not start with 'tr('") + + def parse_keyplaceholder(self): + if self.peek() == '@': + self.consume('@') + key_index = self.parse_num() + self.consume('/<') + num1 = self.parse_num() + self.consume(';') + num2 = self.parse_num() + self.consume('>/*') + return PlainKeyPlaceholder(key_index, num1, num2) + elif self.input[self.index:self.index+6] == 'musig(': + self.consume('musig(') + key_indexes = self.parse_key_indexes() + self.consume(')/<') + num1 = self.parse_num() + self.consume(';') + num2 = self.parse_num() + self.consume('>/*') + return Musig2KeyPlaceholder(key_indexes, num1, num2) + else: + raise Exception("Syntax error in key placeholder") + + def parse_tree(self) -> Tree: + if self.peek() == '{': + self.consume('{') + tree1 = self.parse_tree() + self.consume(',') + tree2 = self.parse_tree() + self.consume('}') + return Tree((tree1, tree2)) + else: + return Tree(self.parse_script()) + + def parse_script(self) -> str: + start = self.index + nesting = 0 + while self.index < self.length and (nesting > 0 or self.input[self.index] not in ('}', ',', ')')): + if self.input[self.index] == '(': + nesting = nesting + 1 + elif self.input[self.index] == ')': + nesting = nesting - 1 + + self.index += 1 + return self.input[start:self.index] + + def parse_key_indexes(self): + nums = [] + self.consume('@') + nums.append(self.parse_num()) + while self.peek() == ',': + self.consume(',@') + nums.append(self.parse_num()) + return nums + + def parse_num(self): + start = self.index + while self.index < self.length and self.input[self.index].isdigit(): + self.index += 1 + return int(self.input[start:self.index]) + + def consume(self, char): + if self.input[self.index:self.index+len(char)] == char: + self.index += len(char) + else: + raise Exception( + f"Syntax error: Expected '{char}'; rest: {self.input[self.index:]}") + + def peek(self): + return self.input[self.index] if self.index < self.length else None + + def placeholders(self) -> Iterator[Tuple[KeyPlaceholder, Optional[str]]]: + """ + Generates an iterator over the placeholders contained in the template and its tree, also + yielding the corresponding leaf script descriptor (or None for the keypath placeholder). + + Yields: + Iterator[Tuple[KeyPlaceholder, Optional[str]]]: An iterator over tuples containing a KeyPlaceholder and an optional associated script. + """ + + yield (self.key, None) + + if self.tree is not None: + for placeholder, script in self.tree.placeholders(): + yield (placeholder, script) + + def get_taptree_hash(self, is_change: bool, address_index: int) -> bytes: + if self.tree is None: + raise ValueError("There is no taptree") + return self.tree.get_taptree_hash(is_change, address_index) + + +class PsbtMusig2Cosigner(ABC): + @abstractmethod + def get_participant_pubkey(self) -> bip0327.Point: + """ + This method should returns this cosigner's public key. + """ + pass + + @abstractmethod + def generate_public_nonces(self, psbt: PSBT) -> None: + """ + This method should generate public nonces and modify the given Psbt object in-place. + It should raise an exception in case of failure. + """ + pass + + @abstractmethod + def generate_partial_signatures(self, psbt: PSBT) -> None: + """ + Receives a PSBT that contains all the participants' public nonces, and adds this participant's partial signature. + It should raise an exception in case of failure. + """ + pass + + +def find_change_and_addr_index_for_musig(input_psbt: PartiallySignedInput, placeholder: Musig2KeyPlaceholder, agg_xpub: ExtendedKey): + num1, num2 = placeholder.num1, placeholder.num2 + + # Iterate through tap key origins in the input + # TODO: this might be made more precise (e.g. use the leaf_hash from the tap_bip32_paths items) + for xonly, (_, key_origin) in input_psbt.tap_bip32_paths.items(): + der_path = key_origin.path + # Check if the fingerprint matches the expected pattern and the derivation path has the correct structure + if key_origin.fingerprint == b'\x00\x00\x00\x00' and len(der_path) == 2 and der_path[0] < HARDENED_INDEX and der_path[1] < HARDENED_INDEX and (der_path[0] == num1 or der_path[0] == num2): + if xonly != agg_xpub.derive_pub_path(der_path).pubkey[1:]: + continue + + # Determine if the address is a change address and extract the address index + is_change = (der_path[0] == num2) + addr_index = int(der_path[1]) + return is_change, addr_index + + return None + + +def get_bip32_tweaks(ext_key: ExtendedKey, steps: List[int]) -> List[bytes]: + """ + Generate BIP32 tweaks for a series of derivation steps on an extended key. + + Args: + ext_key (ExtendedKey): The extended public key. + steps (List[int]): A list of derivation steps (must be unhardened). + + Returns: + List[bytes]: The list of additive tweaks for those derivation steps. + """ + + result = [] + + cur_pubkey = ext_key.pubkey + cur_chaincode = ext_key.chaincode + + for step in steps: + if step < 0 or step >= HARDENED_INDEX: + raise ValueError("Invalid unhardened derivation step") + + data = cur_pubkey + struct.pack(">L", step) + Ihmac = hmac.new(cur_chaincode, data, hashlib.sha512).digest() + Il = Ihmac[:32] + Ir = Ihmac[32:] + + result.append(Il) + + Il_int = int.from_bytes(Il, 'big') + child_pubkey_point = point_add(point_mul(G, Il_int), + bytes_to_point(cur_pubkey)) + child_pubkey = point_to_bytes(child_pubkey_point) + + cur_pubkey = child_pubkey + cur_chaincode = Ir + + return result + + +def process_placeholder( + wallet_policy: WalletPolicy, + psbt_input: PartiallySignedInput, + placeholder: Musig2KeyPlaceholder, + keyagg_ctx: bip0327.KeyAggContext, + agg_xpub: ExtendedKey, + tapleaf_desc: Optional[str], + desc_tmpl: TrDescriptorTemplate +) -> Optional[Tuple[List[bytes], List[bool], Optional[bytes], bytes]]: + """ + This method encapsulates all the precomputations that are done for a certain + wallet policy, psbt input and musig() placeholder that are common to both the + nonce generation and the partial signature generation flows. + + Returs a tuple containing: + - tweaks: a list of tweaks to be applied to the aggregate musig key + - is_xonly_tweak: a list of boolean of the same length of tweaks, specifying for + each of them if it's a plain tweak or an x-only tweak + - leaf_script: the compiled leaf script, or None for a taproot keypath spend + - aggpk_tweaked: the value of the aggregate pubkey after applying the tweaks + """ + res = find_change_and_addr_index_for_musig( + psbt_input, placeholder, agg_xpub) + if res is None: + return None + is_change, address_index = res + + leaf_script = None + if tapleaf_desc is not None: + leaf_desc = derive_plain_descriptor( + tapleaf_desc, wallet_policy.keys_info, is_change, address_index) + s = BytesIO(leaf_desc.encode()) + desc: Miniscript = Miniscript.read_from(s, taproot=True) + leaf_script = desc.compile() + + tweaks = [] + is_xonly_tweak = [] + + # Compute bip32 tweaks + bip32_steps = [ + placeholder.num2 if is_change else placeholder.num1, + address_index + ] + bip32_tweaks = get_bip32_tweaks(agg_xpub, bip32_steps) + for tweak in bip32_tweaks: + tweaks.append(tweak) + is_xonly_tweak.append(False) + + # aggregate key after the bip_32 derivations (but before the taptweak, if any) + der_key = agg_xpub.derive_pub_path(bip32_steps) + + # x-only tweak, only if spending the keypath + if tapleaf_desc is None: + t = der_key.pubkey[-32:] + if desc_tmpl.tree is not None: + t += desc_tmpl.get_taptree_hash(is_change, address_index) + tweaks.append(taproot.tagged_hash("TapTweak", t)) + is_xonly_tweak.append(True) + + keyagg_ctx = aggregate_musig_pubkey( + wallet_policy.keys_info[i] for i in placeholder.key_indexes)[1] + + for tweak, is_xonly in zip(tweaks, is_xonly_tweak): + keyagg_ctx = bip0327.apply_tweak(keyagg_ctx, tweak, is_xonly) + + aggpk_tweaked = bip0327.cbytes(keyagg_ctx.Q) + + return (tweaks, is_xonly_tweak, leaf_script, aggpk_tweaked) + + +class HotMusig2Cosigner(PsbtMusig2Cosigner): + """ + Implements a PsbtMusig2Cosigner for a given wallet policy and a private + that appears as one of the key in a musig() key expression. + """ + + def __init__(self, wallet_policy: WalletPolicy, privkey: str) -> None: + super().__init__() + + self.wallet_policy = wallet_policy + self.privkey = ExtendedKey.deserialize(privkey) + + assert self.privkey.to_string() == privkey + + self.musig_psbt_sessions: Dict[bytes, bytes] = {} + + assert self.privkey.is_private + + def compute_psbt_session_id(self, psbt: PSBT) -> bytes: + psbt.tx.rehash() + return sha256(psbt.tx.hash + self.wallet_policy.id) + + def get_participant_pubkey(self) -> bip0327.Point: + return bip0327.cpoint(self.privkey.pubkey) + + def generate_public_nonces(self, psbt: PSBT) -> None: + desc_tmpl = TrDescriptorTemplate.from_string( + self.wallet_policy.descriptor_template) + + psbt_session_id = self.compute_psbt_session_id(psbt) + + # root of all pseudorandomness for this psbt session + rand_seed = secrets.token_bytes(32) + + for placeholder_index, (placeholder, tapleaf_desc) in enumerate(desc_tmpl.placeholders()): + if not isinstance(placeholder, Musig2KeyPlaceholder): + continue + + agg_xpub_str, keyagg_ctx = aggregate_musig_pubkey( + self.wallet_policy.keys_info[i] for i in placeholder.key_indexes) + agg_xpub = ExtendedKey.deserialize(agg_xpub_str) + + for input_index, input in enumerate(psbt.inputs): + result = process_placeholder( + self.wallet_policy, input, placeholder, keyagg_ctx, agg_xpub, tapleaf_desc, desc_tmpl) + if result is None: + continue + + (_, _, leaf_script, aggpk_tweaked) = result + + rand_i_j = sha256( + rand_seed + + input_index.to_bytes(4, byteorder='big') + + placeholder_index.to_bytes(4, byteorder='big') + ) + + # secnonce: bytearray + # pubnonce: bytes + _, pubnonce = bip0327.nonce_gen_internal( + rand_=rand_i_j, + sk=None, + pk=self.privkey.pubkey, + aggpk=aggpk_tweaked, + msg=None, + extra_in=None + ) + + pubnonce_identifier = ( + self.privkey.pubkey, + aggpk_tweaked, + tapleaf_hash(leaf_script) + ) + + assert len(aggpk_tweaked) == 33 + + input.musig2_pub_nonces[pubnonce_identifier] = pubnonce + + self.musig_psbt_sessions[psbt_session_id] = rand_seed + + def generate_partial_signatures(self, psbt: PSBT) -> None: + desc_tmpl = TrDescriptorTemplate.from_string( + self.wallet_policy.descriptor_template) + + psbt_session_id = self.compute_psbt_session_id(psbt) + + # Get the session's randomness seed, while simultaneously deleting it from the open sessions + rand_seed = self.musig_psbt_sessions.pop(psbt_session_id, None) + + if rand_seed is None: + raise ValueError( + "No musig signing session for this psbt") + + for placeholder_index, (placeholder, tapleaf_desc) in enumerate(desc_tmpl.placeholders()): + if not isinstance(placeholder, Musig2KeyPlaceholder): + continue + + agg_xpub_str, keyagg_ctx = aggregate_musig_pubkey( + self.wallet_policy.keys_info[i] for i in placeholder.key_indexes) + agg_xpub = ExtendedKey.deserialize(agg_xpub_str) + + for input_index, input in enumerate(psbt.inputs): + result = process_placeholder( + self.wallet_policy, input, placeholder, keyagg_ctx, agg_xpub, tapleaf_desc, desc_tmpl) + if result is None: + continue + + (tweaks, is_xonly_tweak, leaf_script, aggpk_tweaked) = result + + rand_i_j = sha256( + rand_seed + + input_index.to_bytes(4, byteorder='big') + + placeholder_index.to_bytes(4, byteorder='big') + ) + + secnonce, pubnonce = bip0327.nonce_gen_internal( + rand_=rand_i_j, + sk=None, + pk=self.privkey.pubkey, + aggpk=aggpk_tweaked, + msg=None, + extra_in=None + ) + + pubkeys_in_musig: List[ExtendedKey] = [] + my_key_index_in_musig: Optional[int] = None + for i in placeholder.key_indexes: + k_i = self.wallet_policy.keys_info[i] + xpub_i = k_i[k_i.find(']') + 1:] + pubkeys_in_musig.append(ExtendedKey.deserialize(xpub_i)) + + if xpub_i == self.privkey.neutered().to_string(): + my_key_index_in_musig = i + + if my_key_index_in_musig is None: + raise ValueError("No internal key found in musig") + + nonces: List[bytes] = [] + for participant_key in pubkeys_in_musig: + participant_pubnonce_identifier = ( + participant_key.pubkey, + aggpk_tweaked, + tapleaf_hash(leaf_script) + ) + + if participant_key.pubkey == self.privkey.pubkey and input.musig2_pub_nonces[participant_pubnonce_identifier] != pubnonce: + raise ValueError( + f"Public nonce in psbt didn't match the expected one for cosigner {self.privkey.pubkey}") + + assert len(aggpk_tweaked) == 33 + + if participant_pubnonce_identifier in input.musig2_pub_nonces: + nonces.append( + input.musig2_pub_nonces[participant_pubnonce_identifier]) + else: + raise ValueError( + f"Missing pubnonce for pubkey {participant_key.pubkey.hex()} in psbt") + + if leaf_script is None: + sighash = TaprootSignatureHash( + txTo=psbt.tx, + spent_utxos=[ + psbt.inputs[i].witness_utxo for i in range(len(psbt.inputs))], + hash_type=input.sighash or SIGHASH_DEFAULT, + input_index=input_index, + ) + else: + sighash = TaprootSignatureHash( + txTo=psbt.tx, + spent_utxos=[ + psbt.inputs[i].witness_utxo for i in range(len(psbt.inputs))], + hash_type=input.sighash or SIGHASH_DEFAULT, + input_index=input_index, + scriptpath=True, + script=leaf_script + ) + + aggnonce = bip0327.nonce_agg(nonces) + + session_ctx = bip0327.SessionContext( + aggnonce=aggnonce, + pubkeys=[pk.pubkey for pk in pubkeys_in_musig], + tweaks=tweaks, + is_xonly=is_xonly_tweak, + msg=sighash) + + partial_sig = bip0327.sign( + secnonce, self.privkey.privkey, session_ctx) + + pubnonce_identifier = ( + self.privkey.pubkey, + aggpk_tweaked, + tapleaf_hash(leaf_script) + ) + + input.musig2_partial_sigs[pubnonce_identifier] = partial_sig + + +def run_musig2_test(wallet_policy: WalletPolicy, psbt: PSBT, cosigners: List[PsbtMusig2Cosigner], sighashes: list[bytes]): + """ + This performs the following steps: + - go through all the cosigners to let them add their pubnonce; + - go through all the cosigners to let them add their partial signature; + - aggregate the partial signatures to produce the final Schnorr signature; + - verify that the produced signature is valid for the provided sighash. + + The sighashes (one per input) are given as argument and are assumed to be correct. + """ + + if len(psbt.inputs) != len(sighashes): + raise ValueError("The length of the sighashes array is incorrect") + + for signer in cosigners: + signer.generate_public_nonces(psbt) + + for signer in cosigners: + signer.generate_partial_signatures(psbt) + + desc_tmpl = TrDescriptorTemplate.from_string( + wallet_policy.descriptor_template) + + for placeholder, tapleaf_desc in desc_tmpl.placeholders(): + if not isinstance(placeholder, Musig2KeyPlaceholder): + continue + + agg_xpub_str, keyagg_ctx = aggregate_musig_pubkey( + wallet_policy.keys_info[i] for i in placeholder.key_indexes) + agg_xpub = ExtendedKey.deserialize(agg_xpub_str) + + for input_index, input in enumerate(psbt.inputs): + result = process_placeholder( + wallet_policy, input, placeholder, keyagg_ctx, agg_xpub, tapleaf_desc, desc_tmpl) + + if result is None: + raise RuntimeError( + "Unexpected: processing the musig placeholder failed") + + (tweaks, is_xonly_tweak, leaf_script, aggpk_tweaked) = result + + assert len(aggpk_tweaked) == 33 + + pubkeys_in_musig: List[ExtendedKey] = [] + for i in placeholder.key_indexes: + k_i = wallet_policy.keys_info[i] + xpub_i = k_i[k_i.find(']') + 1:] + pubkeys_in_musig.append(ExtendedKey.deserialize(xpub_i)) + + nonces: List[bytes] = [] + for participant_key in pubkeys_in_musig: + pubnonce_identifier = ( + participant_key.pubkey, + aggpk_tweaked, + tapleaf_hash(leaf_script) + ) + + if pubnonce_identifier in input.musig2_pub_nonces: + nonces.append( + input.musig2_pub_nonces[pubnonce_identifier]) + else: + raise ValueError( + f"Missing pubnonce for pubkey {participant_key.pubkey.hex()} in psbt") + + aggnonce = bip0327.nonce_agg(nonces) + + sighash = sighashes[input_index] + + session_ctx = bip0327.SessionContext( + aggnonce=aggnonce, + pubkeys=[pk.pubkey for pk in pubkeys_in_musig], + tweaks=tweaks, + is_xonly=is_xonly_tweak, + msg=sighash) + + # collect partial signatures + psigs: List[bytes] = [] + + for participant_key in pubkeys_in_musig: + pubnonce_identifier = ( + participant_key.pubkey, + bytes(aggpk_tweaked), + tapleaf_hash(leaf_script) + ) + + if pubnonce_identifier in input.musig2_partial_sigs: + psigs.append( + input.musig2_partial_sigs[pubnonce_identifier]) + else: + raise ValueError( + f"Missing partial signature for pubkey {participant_key.pubkey.hex()} in psbt") + + sig = bip0327.partial_sig_agg(psigs, session_ctx) + + aggpk_tweaked_xonly = aggpk_tweaked[1:] + assert (bip0340.schnorr_verify(sighash, aggpk_tweaked_xonly, sig)) diff --git a/test_utils/taproot.py b/test_utils/taproot.py index 0ba25a2ae..3f84ab56e 100644 --- a/test_utils/taproot.py +++ b/test_utils/taproot.py @@ -1,14 +1,32 @@ -# from portions of BIP-0341 +# from BIP-0340 and BIP-0341 +# - https://github.com/bitcoin/bips/blob/b3701faef2bdb98a0d7ace4eedbeefa2da4c89ed/bip-0340.mediawiki # - https://github.com/bitcoin/bips/blob/b3701faef2bdb98a0d7ace4eedbeefa2da4c89ed/bip-0341.mediawiki # Distributed under the BSD-3-Clause license # fmt: off +# Set DEBUG to True to get a detailed debug output including +# intermediate values during key generation, signing, and +# verification. This is implemented via calls to the +# debug_print_vars() function. +# # If you want to print values on an individual basis, use # the pretty() function, e.g., print(pretty(foo)). import hashlib -import struct +from typing import Any, Optional, Tuple + + +DEBUG = False + +p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F +n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 +SECP256K1_ORDER = n + +# Points are tuples of X and Y coordinates and the point at infinity is +# represented by the None keyword. +G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8) +Point = Tuple[int, int] # This implementation can be sped up by storing the midstate after hashing # tag_hash instead of rehashing it all the time. @@ -16,6 +34,140 @@ def tagged_hash(tag: str, msg: bytes) -> bytes: tag_hash = hashlib.sha256(tag.encode()).digest() return hashlib.sha256(tag_hash + tag_hash + msg).digest() +def is_infinite(P: Optional[Point]) -> bool: + return P is None + +def x(P: Point) -> int: + assert not is_infinite(P) + return P[0] + +def y(P: Point) -> int: + assert not is_infinite(P) + return P[1] + +def point_add(P1: Optional[Point], P2: Optional[Point]) -> Optional[Point]: + if P1 is None: + return P2 + if P2 is None: + return P1 + if (x(P1) == x(P2)) and (y(P1) != y(P2)): + return None + if P1 == P2: + lam = (3 * x(P1) * x(P1) * pow(2 * y(P1), p - 2, p)) % p + else: + lam = ((y(P2) - y(P1)) * pow(x(P2) - x(P1), p - 2, p)) % p + x3 = (lam * lam - x(P1) - x(P2)) % p + return (x3, (lam * (x(P1) - x3) - y(P1)) % p) + +def point_mul(P: Optional[Point], n: int) -> Optional[Point]: + R = None + for i in range(256): + if (n >> i) & 1: + R = point_add(R, P) + P = point_add(P, P) + return R + +def bytes_from_int(x: int) -> bytes: + return x.to_bytes(32, byteorder="big") + +def bytes_from_point(P: Point) -> bytes: + return bytes_from_int(x(P)) + +def xor_bytes(b0: bytes, b1: bytes) -> bytes: + return bytes(x ^ y for (x, y) in zip(b0, b1)) + +def lift_x(x: int) -> Optional[Point]: + if x >= p: + return None + y_sq = (pow(x, 3, p) + 7) % p + y = pow(y_sq, (p + 1) // 4, p) + if pow(y, 2, p) != y_sq: + return None + return (x, y if y & 1 == 0 else p-y) + +def int_from_bytes(b: bytes) -> int: + return int.from_bytes(b, byteorder="big") + +def hash_sha256(b: bytes) -> bytes: + return hashlib.sha256(b).digest() + +def has_even_y(P: Point) -> bool: + assert not is_infinite(P) + return y(P) % 2 == 0 + +def pubkey_gen(seckey: bytes) -> bytes: + d0 = int_from_bytes(seckey) + if not (1 <= d0 <= n - 1): + raise ValueError('The secret key must be an integer in the range 1..n-1.') + P = point_mul(G, d0) + assert P is not None + return bytes_from_point(P) + +def schnorr_sign(msg: bytes, seckey: bytes, aux_rand: bytes) -> bytes: + d0 = int_from_bytes(seckey) + if not (1 <= d0 <= n - 1): + raise ValueError('The secret key must be an integer in the range 1..n-1.') + if len(aux_rand) != 32: + raise ValueError('aux_rand must be 32 bytes instead of %i.' % len(aux_rand)) + P = point_mul(G, d0) + assert P is not None + d = d0 if has_even_y(P) else n - d0 + t = xor_bytes(bytes_from_int(d), tagged_hash("BIP0340/aux", aux_rand)) + k0 = int_from_bytes(tagged_hash("BIP0340/nonce", t + bytes_from_point(P) + msg)) % n + if k0 == 0: + raise RuntimeError('Failure. This happens only with negligible probability.') + R = point_mul(G, k0) + assert R is not None + k = n - k0 if not has_even_y(R) else k0 + e = int_from_bytes(tagged_hash("BIP0340/challenge", bytes_from_point(R) + bytes_from_point(P) + msg)) % n + sig = bytes_from_point(R) + bytes_from_int((k + e * d) % n) + debug_print_vars() + if not schnorr_verify(msg, bytes_from_point(P), sig): + raise RuntimeError('The created signature does not pass verification.') + return sig + +def schnorr_verify(msg: bytes, pubkey: bytes, sig: bytes) -> bool: + if len(pubkey) != 32: + raise ValueError('The public key must be a 32-byte array.') + if len(sig) != 64: + raise ValueError('The signature must be a 64-byte array.') + P = lift_x(int_from_bytes(pubkey)) + r = int_from_bytes(sig[0:32]) + s = int_from_bytes(sig[32:64]) + if (P is None) or (r >= p) or (s >= n): + debug_print_vars() + return False + e = int_from_bytes(tagged_hash("BIP0340/challenge", sig[0:32] + pubkey + msg)) % n + R = point_add(point_mul(G, s), point_mul(P, n - e)) + if (R is None) or (not has_even_y(R)) or (x(R) != r): + debug_print_vars() + return False + debug_print_vars() + return True + +import inspect + +def pretty(v: Any) -> Any: + if isinstance(v, bytes): + return '0x' + v.hex() + if isinstance(v, int): + return pretty(bytes_from_int(v)) + if isinstance(v, tuple): + return tuple(map(pretty, v)) + return v + +def debug_print_vars() -> None: + if DEBUG: + current_frame = inspect.currentframe() + assert current_frame is not None + frame = current_frame.f_back + assert frame is not None + print(' Variables in function ', frame.f_code.co_name, ' at line ', frame.f_lineno, ':', sep='') + for var_name, var_val in frame.f_locals.items(): + print(' ' + var_name.rjust(11, ' '), '==', pretty(var_val)) + + +import struct def ser_compact_size(l): r = b"" @@ -48,3 +200,63 @@ def ser_string(s): def ser_script(s): return ser_string(s) + + +# BIP-0341 +def taproot_tweak_pubkey(pubkey, h): + t = int_from_bytes(tagged_hash("TapTweak", pubkey + h)) + if t >= SECP256K1_ORDER: + raise ValueError + P = lift_x(int_from_bytes(pubkey)) + if P is None: + raise ValueError + Q = point_add(P, point_mul(G, t)) + return 0 if has_even_y(Q) else 1, bytes_from_int(x(Q)) + +def taproot_tweak_seckey(seckey0, h): + seckey0 = int_from_bytes(seckey0) + P = point_mul(G, seckey0) + seckey = seckey0 if has_even_y(P) else SECP256K1_ORDER - seckey0 + t = int_from_bytes(tagged_hash("TapTweak", bytes_from_int(x(P)) + h)) + if t >= SECP256K1_ORDER: + raise ValueError + return bytes_from_int((seckey + t) % SECP256K1_ORDER) + +def taproot_tree_helper(script_tree): + if isinstance(script_tree, tuple): + leaf_version, script = script_tree + h = tagged_hash("TapLeaf", bytes([leaf_version]) + ser_script(script)) + return ([((leaf_version, script), bytes())], h) + left, left_h = taproot_tree_helper(script_tree[0]) + right, right_h = taproot_tree_helper(script_tree[1]) + ret = [(l, c + right_h) for l, c in left] + [(l, c + left_h) for l, c in right] + if right_h < left_h: + left_h, right_h = right_h, left_h + return (ret, tagged_hash("TapBranch", left_h + right_h)) + +def taproot_output_script(internal_pubkey, script_tree): + """Given a internal public key and a tree of scripts, compute the output script. + script_tree is either: + - a (leaf_version, script) tuple (leaf_version is 0xc0 for [[bip-0342.mediawiki|BIP342]] scripts) + - a list of two elements, each with the same structure as script_tree itself + - None + """ + if script_tree is None: + h = bytes() + else: + _, h = taproot_tree_helper(script_tree) + _, output_pubkey = taproot_tweak_pubkey(internal_pubkey, h) + return bytes([0x51, 0x20]) + output_pubkey + + +# Tweak without tag +def tweak_pubkey(pubkey, data: bytes): + assert len(data) == 32 + t = int_from_bytes(data) + if t >= SECP256K1_ORDER: + raise ValueError + P = lift_x(int_from_bytes(pubkey)) + if P is None: + raise ValueError + Q = point_add(P, point_mul(G, t)) + return 0 if has_even_y(Q) else 1, bytes_from_int(x(Q)) diff --git a/test_utils/taproot_sighash.py b/test_utils/taproot_sighash.py new file mode 100644 index 000000000..073be97e2 --- /dev/null +++ b/test_utils/taproot_sighash.py @@ -0,0 +1,85 @@ +# Based on code from the bitcoin's functional test framework, extracted from: +# https://github.com/bitcoin/bitcoin/blob/58446e1d92c7da46da1fc48e1eb5eefe2e0748cb/test/functional/feature_taproot.py +# +# Copyright (c) 2015-2022 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying + + +import struct +from test_utils import sha256 +from test_utils.taproot import ser_string, tagged_hash + + +def BIP341_sha_prevouts(txTo): + return sha256(b"".join(i.prevout.serialize() for i in txTo.vin)) + + +def BIP341_sha_amounts(spent_utxos): + return sha256(b"".join(struct.pack(" Date: Wed, 9 Oct 2024 10:18:21 +0200 Subject: [PATCH 12/57] Add 'tweak' output parameter to bip32_CKDpub; exposed BIP341 constants --- src/crypto.c | 13 +++++++++---- src/crypto.h | 13 +++++++++++-- src/handler/lib/policy.c | 2 +- src/handler/sign_psbt.c | 2 +- src/handler/sign_psbt/sign_psbt_cache.c | 10 +++++----- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index 67578f5f4..5b5440269 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -42,9 +42,9 @@ #include "secp256k1.h" /* BIP0341 tags for computing the tagged hashes when tweaking public keys */ -static const uint8_t BIP0341_taptweak_tag[] = {'T', 'a', 'p', 'T', 'w', 'e', 'a', 'k'}; -static const uint8_t BIP0341_tapbranch_tag[] = {'T', 'a', 'p', 'B', 'r', 'a', 'n', 'c', 'h'}; -static const uint8_t BIP0341_tapleaf_tag[] = {'T', 'a', 'p', 'L', 'e', 'a', 'f'}; +const uint8_t BIP0341_taptweak_tag[] = {'T', 'a', 'p', 'T', 'w', 'e', 'a', 'k'}; +const uint8_t BIP0341_tapbranch_tag[] = {'T', 'a', 'p', 'B', 'r', 'a', 'n', 'c', 'h'}; +const uint8_t BIP0341_tapleaf_tag[] = {'T', 'a', 'p', 'L', 'e', 'a', 'f'}; // Copy of cx_ecfp_scalar_mult_no_throw, but without using randomization for the scalar // multiplication. Therefore, it is faster, but not safe to use on private data, as it is vulnerable @@ -90,7 +90,8 @@ static int secp256k1_point_unsafe(const uint8_t k[static 32], uint8_t out[static int bip32_CKDpub(const serialized_extended_pubkey_t *parent, uint32_t index, - serialized_extended_pubkey_t *child) { + serialized_extended_pubkey_t *child, + uint8_t *tweak) { PRINT_STACK_POINTER(); if (index >= BIP32_FIRST_HARDENED_CHILD) { @@ -115,6 +116,10 @@ int bip32_CKDpub(const serialized_extended_pubkey_t *parent, uint8_t *I_L = &I[0]; uint8_t *I_R = &I[32]; + if (tweak != NULL) { + memcpy(tweak, I_L, 32); + } + // fail if I_L is not smaller than the group order n, but the probability is < 1/2^128 int diff; if (CX_OK != cx_math_cmp_no_throw(I_L, secp256k1_n, 32, &diff) || diff >= 0) { diff --git a/src/crypto.h b/src/crypto.h index f56e24350..466824caf 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -36,18 +36,22 @@ typedef struct { * * @param[in] parent * Pointer to the extended serialized pubkey of the parent. - * @param[out] index + * @param[in] index * Index of the child to derive. It MUST be not hardened, that is, strictly less than 0x80000000. * @param[out] child * Pointer to the output struct for the child's serialized pubkey. It can equal parent, which in * that case is overwritten. + * @param[out] tweak + * If not NULL, pointer to a 32-byte array that will receive the 32-byte tweak used during the + * child key derivation. * * @return 0 if success, a negative number on failure. * */ int bip32_CKDpub(const serialized_extended_pubkey_t *parent, uint32_t index, - serialized_extended_pubkey_t *child); + serialized_extended_pubkey_t *child, + uint8_t *tweak); /** * Convenience wrapper for cx_hash_no_throw to add some data to an initialized hash context. @@ -331,6 +335,11 @@ int crypto_ecdsa_sign_sha256_hash_with_key(const uint32_t bip32_path[], uint8_t out[static MAX_DER_SIG_LEN], uint32_t *info); +// Constants defined in BIP-0341 +extern const uint8_t BIP0341_taptweak_tag[8]; +extern const uint8_t BIP0341_tapbranch_tag[9]; +extern const uint8_t BIP0341_tapleaf_tag[7]; + /** * Initializes the "tagged" SHA256 hash with the given tag, as defined by BIP-0340. * diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index d8ec5276a..0ce9cefaa 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -502,7 +502,7 @@ __attribute__((warn_unused_result)) static int get_derived_pubkey( &ext_pubkey)) { return -1; } - if (0 > bip32_CKDpub(&ext_pubkey, wdi->address_index, &ext_pubkey)) { + if (0 > bip32_CKDpub(&ext_pubkey, wdi->address_index, &ext_pubkey, NULL)) { return -1; } diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index ac050234c..f6843f7d3 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -451,7 +451,7 @@ static int read_change_and_index_from_psbt_bip32_derivation( in_out->is_change, &pubkey)) return -1; - if (0 > bip32_CKDpub(&pubkey, addr_index, &pubkey)) return -1; + if (0 > bip32_CKDpub(&pubkey, addr_index, &pubkey, NULL)) return -1; int pk_offset = is_tap ? 1 : 0; if (memcmp(pubkey.compressed_pubkey + pk_offset, bip32_derivation_pubkey, key_len) != 0) { diff --git a/src/handler/sign_psbt/sign_psbt_cache.c b/src/handler/sign_psbt/sign_psbt_cache.c index 00bf8b027..6eab0819e 100644 --- a/src/handler/sign_psbt/sign_psbt_cache.c +++ b/src/handler/sign_psbt/sign_psbt_cache.c @@ -10,15 +10,15 @@ int derive_first_step_for_pubkey(const serialized_extended_pubkey_t *base_key, // make sure a cache was provided, and the index is less than the size of the cache if (keyexpr->keyexpr_index >= MAX_CACHED_KEY_EXPRESSIONS || !cache) { // do not use the cache, derive the key directly - return bip32_CKDpub(base_key, change_step, out_pubkey); + return bip32_CKDpub(base_key, change_step, out_pubkey, NULL); } if (!cache->derived_child[keyexpr->keyexpr_index].is_child_pubkey_initialized[is_change]) { // key not in cache; compute it and store it in the cache - if (0 > - bip32_CKDpub(base_key, - change_step, - &cache->derived_child[keyexpr->keyexpr_index].child_pubkeys[is_change])) + if (0 > bip32_CKDpub(base_key, + change_step, + &cache->derived_child[keyexpr->keyexpr_index].child_pubkeys[is_change], + NULL)) return -1; cache->derived_child[keyexpr->keyexpr_index].is_child_pubkey_initialized[is_change] = true; From acc0530c23fcd0fa84f428968fae7ede3c1b0742 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Fri, 17 May 2024 17:37:32 +0200 Subject: [PATCH 13/57] Add parsing of Musig2 pubnonces and partial signatures as yielded values in sign_psbt in the python client --- bitcoin_client/ledger_bitcoin/client.py | 73 +++++++++++++++---- bitcoin_client/ledger_bitcoin/client_base.py | 53 ++++++++++++-- .../ledger_bitcoin/client_command.py | 4 + 3 files changed, 112 insertions(+), 18 deletions(-) diff --git a/bitcoin_client/ledger_bitcoin/client.py b/bitcoin_client/ledger_bitcoin/client.py index 94c22aed8..b032c3ea1 100644 --- a/bitcoin_client/ledger_bitcoin/client.py +++ b/bitcoin_client/ledger_bitcoin/client.py @@ -10,8 +10,8 @@ from .command_builder import BitcoinCommandBuilder, BitcoinInsType from .common import Chain, read_uint, read_varint -from .client_command import ClientCommandInterpreter -from .client_base import Client, TransportClient, PartialSignature +from .client_command import ClientCommandInterpreter, CCMD_YIELD_MUSIG_PARTIALSIGNATURE_TAG, CCMD_YIELD_MUSIG_PUBNONCE_TAG +from .client_base import Client, MusigPartialSignature, MusigPubNonce, SignPsbtYieldedObject, TransportClient, PartialSignature from .client_legacy import LegacyClient from .exception import DeviceException from .errors import UnknownDeviceError @@ -105,6 +105,60 @@ def _make_partial_signature(pubkey_augm: bytes, signature: bytes) -> PartialSign return PartialSignature(signature=signature, pubkey=pubkey_augm) +def _decode_signpsbt_yielded_value(res: bytes) -> Tuple[int, SignPsbtYieldedObject]: + res_buffer = BytesIO(res) + input_index_or_tag = read_varint(res_buffer) + if input_index_or_tag == CCMD_YIELD_MUSIG_PUBNONCE_TAG: + input_index = read_varint(res_buffer) + pubnonce = res_buffer.read(66) + participant_pk = res_buffer.read(33) + agg_xonlykey = res_buffer.read(32) + tapleaf_hash = res_buffer.read() + if len(tapleaf_hash) == 0: + tapleaf_hash = None + + return ( + input_index, + MusigPubNonce( + participant_pubkey=participant_pk, + agg_xonlykey=agg_xonlykey, + tapleaf_hash=tapleaf_hash, + pubnonce=pubnonce + ) + ) + elif input_index_or_tag == CCMD_YIELD_MUSIG_PARTIALSIGNATURE_TAG: + input_index = read_varint(res_buffer) + partial_signature = res_buffer.read(32) + participant_pk = res_buffer.read(33) + agg_xonlykey = res_buffer.read(32) + tapleaf_hash = res_buffer.read() + if len(tapleaf_hash) == 0: + tapleaf_hash = None + + return ( + input_index, + MusigPartialSignature( + participant_pubkey=participant_pk, + agg_xonlykey=agg_xonlykey, + tapleaf_hash=tapleaf_hash, + partial_signature=partial_signature + ) + ) + else: + # other values follow an encoding without an explicit tag, where the + # first element is the input index. All the signature types are implemented + # by the PartialSignature type (not to be confused with the musig Partial Signature). + input_index = input_index_or_tag + + pubkey_augm_len = read_uint(res_buffer, 8) + pubkey_augm = res_buffer.read(pubkey_augm_len) + + signature = res_buffer.read() + + return((input_index, _make_partial_signature(pubkey_augm, signature))) + + + class NewClient(Client): # internal use for testing: if set to True, sign_psbt will not clone the psbt before converting to psbt version 2 _no_clone_psbt: bool = False @@ -211,7 +265,7 @@ def get_wallet_address( return result - def sign_psbt(self, psbt: Union[PSBT, bytes, str], wallet: WalletPolicy, wallet_hmac: Optional[bytes]) -> List[Tuple[int, PartialSignature]]: + def sign_psbt(self, psbt: Union[PSBT, bytes, str], wallet: WalletPolicy, wallet_hmac: Optional[bytes]) -> List[Tuple[int, SignPsbtYieldedObject]]: psbt = normalize_psbt(psbt) @@ -280,17 +334,10 @@ def sign_psbt(self, psbt: Union[PSBT, bytes, str], wallet: WalletPolicy, wallet_ if any(len(x) <= 1 for x in results): raise RuntimeError("Invalid response") - results_list: List[Tuple[int, PartialSignature]] = [] + results_list: List[Tuple[int, SignPsbtYieldedObject]] = [] for res in results: - res_buffer = BytesIO(res) - input_index = read_varint(res_buffer) - - pubkey_augm_len = read_uint(res_buffer, 8) - pubkey_augm = res_buffer.read(pubkey_augm_len) - - signature = res_buffer.read() - - results_list.append((input_index, _make_partial_signature(pubkey_augm, signature))) + input_index, obj = _decode_signpsbt_yielded_value(res) + results_list.append((input_index, obj)) return results_list diff --git a/bitcoin_client/ledger_bitcoin/client_base.py b/bitcoin_client/ledger_bitcoin/client_base.py index 5130bf7ef..3e69ee14f 100644 --- a/bitcoin_client/ledger_bitcoin/client_base.py +++ b/bitcoin_client/ledger_bitcoin/client_base.py @@ -28,7 +28,8 @@ def __init__(self, sw: int, data: bytes) -> None: class TransportClient: def __init__(self, interface: Literal['hid', 'tcp'] = "tcp", *, server: str = "127.0.0.1", port: int = 9999, path: Optional[str] = None, hid: Optional[HID] = None, debug: bool = False): - self.transport = Transport('hid', path=path, hid=hid, debug=debug) if interface == 'hid' else Transport(interface, server=server, port=port, debug=debug) + self.transport = Transport('hid', path=path, hid=hid, debug=debug) if interface == 'hid' else Transport( + interface, server=server, port=port, debug=debug) def apdu_exchange( self, cla: int, ins: int, data: bytes = b"", p1: int = 0, p2: int = 0 @@ -67,18 +68,60 @@ def print_response(sw: int, data: bytes) -> None: @dataclass(frozen=True) class PartialSignature: - """Represents a partial signature returned by sign_psbt. + """Represents a partial signature returned by sign_psbt. Such objects can be added to the PSBT. It always contains a pubkey and a signature. - The pubkey + The pubkey is a compressed 33-byte for legacy and segwit Scripts, or 32-byte x-only key for taproot. + The signature is in the format it would be pushed on the scriptSig or the witness stack, therefore of + variable length, and possibly concatenated with the SIGHASH flag byte if appropriate. - The tapleaf_hash is also filled if signing a for a tapscript. + The tapleaf_hash is also filled if signing for a tapscript. + + Note: not to be confused with 'partial signature' of protocols like MuSig2; """ pubkey: bytes signature: bytes tapleaf_hash: Optional[bytes] = None +@dataclass(frozen=True) +class MusigPubNonce: + """Represents a pubnonce returned by sign_psbt during the first round of a Musig2 signing session. + + It always contains + - the participant_pubkey, a 33-byte compressed pubkey; + - agg_xonlykey, the 32-byte xonly key that is the aggregate and tweaked key present in the script; + - the 66-byte pubnonce. + + The tapleaf_hash is also filled if signing for a tapscript; `None` otherwise. + """ + participant_pubkey: bytes + agg_xonlykey: bytes + tapleaf_hash: Optional[bytes] + pubnonce: bytes + + +@dataclass(frozen=True) +class MusigPartialSignature: + """Represents a partial signature returned by sign_psbt during the second round of a Musig2 signing session. + + It always contains + - the participant_pubkey, a 33-byte compressed pubkey; + - agg_xonlykey, the 32-byte xonly key that is the aggregate and tweaked key present in the script; + - the partial_signature, the 32-byte partial signature for this participant. + + The tapleaf_hash is also filled if signing for a tapscript; `None` otherwise + """ + participant_pubkey: bytes + agg_xonlykey: bytes + tapleaf_hash: Optional[bytes] + partial_signature: bytes + + +SignPsbtYieldedObject = Union[PartialSignature, + MusigPubNonce, MusigPartialSignature] + + class Client: def __init__(self, transport_client: TransportClient, chain: Chain = Chain.MAIN, debug: bool = False) -> None: self.transport_client = transport_client @@ -218,7 +261,7 @@ def get_wallet_address( raise NotImplementedError - def sign_psbt(self, psbt: Union[PSBT, bytes, str], wallet: WalletPolicy, wallet_hmac: Optional[bytes]) -> List[Tuple[int, PartialSignature]]: + def sign_psbt(self, psbt: Union[PSBT, bytes, str], wallet: WalletPolicy, wallet_hmac: Optional[bytes]) -> List[Tuple[int, SignPsbtYieldedObject]]: """Signs a PSBT using a registered wallet (or a standard wallet that does not need registration). Signature requires explicit approval from the user. diff --git a/bitcoin_client/ledger_bitcoin/client_command.py b/bitcoin_client/ledger_bitcoin/client_command.py index 9e32a56ba..8495ec1c4 100644 --- a/bitcoin_client/ledger_bitcoin/client_command.py +++ b/bitcoin_client/ledger_bitcoin/client_command.py @@ -15,6 +15,10 @@ class ClientCommandCode(IntEnum): GET_MORE_ELEMENTS = 0xA0 +CCMD_YIELD_MUSIG_PUBNONCE_TAG = 0xFFFFFFFF +CCMD_YIELD_MUSIG_PARTIALSIGNATURE_TAG = 0xFFFFFFFE + + class ClientCommand: def execute(self, request: bytes) -> bytes: raise NotImplementedError("Subclasses should implement this method.") From 3327a8e60b1de3ebc7ce68af5e5bd9ea3fb9f941 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:02:20 +0200 Subject: [PATCH 14/57] MuSig2 signing, rounds 1 and 2 --- src/commands.h | 4 + src/handler/lib/policy.c | 2 +- src/handler/lib/policy.h | 23 ++ src/handler/sign_psbt.c | 615 ++++++++++++++++++++++++++++++---- src/musig/musig.c | 459 ++++++++++++++++++++++++- src/musig/musig.h | 84 +++++ src/musig/musig_sessions.c | 64 ++++ src/musig/musig_sessions.h | 20 ++ tests/test_sign_psbt_musig.py | 162 +++++++++ 9 files changed, 1360 insertions(+), 73 deletions(-) create mode 100644 src/musig/musig_sessions.c create mode 100644 src/musig/musig_sessions.h create mode 100644 tests/test_sign_psbt_musig.py diff --git a/src/commands.h b/src/commands.h index 63b3b4d10..4de0d4910 100644 --- a/src/commands.h +++ b/src/commands.h @@ -11,3 +11,7 @@ typedef enum { GET_MASTER_FINGERPRINT = 0x05, SIGN_MESSAGE = 0x10, } command_e; + +// Tags used when yielding different objects with the YIELD client command. +#define CCMD_YIELD_MUSIG_PUBNONCE_TAG 0xffffffff +#define CCMD_YIELD_MUSIG_PARTIALSIGNATURE_TAG 0xfffffffe diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index 0ce9cefaa..18b527f6d 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -420,7 +420,7 @@ execute_processor(policy_parser_state_t *state, policy_parser_processor_t proc, // convenience function, split from get_derived_pubkey only to improve stack usage // returns -1 on error, 0 if the returned key info has no wildcard (**), 1 if it has the wildcard -__attribute__((noinline, warn_unused_result)) static int get_extended_pubkey( +__attribute__((noinline, warn_unused_result)) int get_extended_pubkey( dispatcher_context_t *dispatcher_context, const wallet_derivation_info_t *wdi, int key_index, diff --git a/src/handler/lib/policy.h b/src/handler/lib/policy.h index 6bcbc105a..25f0e564d 100644 --- a/src/handler/lib/policy.h +++ b/src/handler/lib/policy.h @@ -53,6 +53,29 @@ typedef struct { *sign_psbt_cache; // If not NULL, the cache for key derivations used during signing } wallet_derivation_info_t; +/** + * Computes the a derived compressed pubkey for one of the key of the wallet policy, + * for a given change/address_index combination. + * + * This function computes the extended public key (xpub) based on the provided + * BIP32 derivation path. It supports both standard BIP32 derivation and + * the derivation of Musig (multi-signature) keys. + * + * @param[in] dispatcher_context Pointer to the dispatcher content + * @param[in] wdi Pointer to a `wallet_derivation_info_t` struct with the details of the + * necessary details of the wallet policy, and the desired change/address_index pair. + * @param[in] key_index Index of the pubkey in the vector of keys of the wallet policy. + * @param[out] out Pointer to a `serialized_extended_pubkey_t` that will contain the requested + * extended pubkey. + * + * @return -1 on error, 0 if the returned key info has no wildcard (**), 1 if it has the wildcard. + */ +__attribute__((warn_unused_result)) int get_extended_pubkey( + dispatcher_context_t *dispatcher_context, + const wallet_derivation_info_t *wdi, + int key_index, + serialized_extended_pubkey_t *out); + /** * Computes the hash of a taptree, to be used as tweak for the internal key per BIP-0341; * The returned hash is the second value in the tuple returned by taproot_tree_helper in diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index f6843f7d3..d4a3bb26a 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -56,6 +56,8 @@ #include "../swap/swap_globals.h" #include "../swap/handle_swap_sign_transaction.h" +#include "../musig/musig.h" +#include "../musig/musig_sessions.h" // common info that applies to either the current input or the current output typedef struct { @@ -372,7 +374,6 @@ static int get_amount_scriptpubkey_from_psbt( // Convenience function to share common logic when processing all the // PSBT_{IN|OUT}_{TAP}?_BIP32_DERIVATION fields. -// TODO: not generalized for musig2 static int read_change_and_index_from_psbt_bip32_derivation( dispatcher_context_t *dc, keyexpr_info_t *keyexpr_info, @@ -443,20 +444,23 @@ static int read_change_and_index_from_psbt_bip32_derivation( return 0; } - // check that we can indeed derive the same key from the current key expression - serialized_extended_pubkey_t pubkey; - if (0 > derive_first_step_for_pubkey(&keyexpr_info->pubkey, - keyexpr_info->key_expression_ptr, - sign_psbt_cache, - in_out->is_change, - &pubkey)) - return -1; - if (0 > bip32_CKDpub(&pubkey, addr_index, &pubkey, NULL)) return -1; - - int pk_offset = is_tap ? 1 : 0; - if (memcmp(pubkey.compressed_pubkey + pk_offset, bip32_derivation_pubkey, key_len) != 0) { - return 0; - } + // TODO: safe to remove this check? It should be, since we later re-derive + // the script independently. + // // check that we can indeed derive the same key from the current key expression + // serialized_extended_pubkey_t pubkey; + // if (0 > derive_first_step_for_pubkey(&keyexpr_info->pubkey, + // keyexpr_info->key_expression_ptr, + // sign_psbt_cache, + // in_out->is_change, + // &pubkey)) + // return -1; + // if (0 > bip32_CKDpub(&pubkey, addr_index, &pubkey, NULL)) return -1; + + // int pk_offset = is_tap ? 1 : 0; + // if (memcmp(pubkey.compressed_pubkey + pk_offset, bip32_derivation_pubkey, key_len) != 0) + // { + // return 0; + // } in_out->key_expression_found = true; return 1; @@ -663,37 +667,28 @@ init_global_state(dispatcher_context_t *dc, sign_psbt_state_t *st) { return true; } -static bool __attribute__((noinline)) fill_keyexpr_info_if_internal(dispatcher_context_t *dc, - sign_psbt_state_t *st, - keyexpr_info_t *keyexpr_info) { +static bool __attribute__((noinline)) get_and_verify_key_info(dispatcher_context_t *dc, + sign_psbt_state_t *st, + uint16_t key_index, + keyexpr_info_t *keyexpr_info) { policy_map_key_info_t key_info; - { - uint8_t key_info_str[MAX_POLICY_KEY_INFO_LEN]; - - // TODO: generalize for musig: keyexpr_info->key_expression_ptr->k.key_index is wrong - LEDGER_ASSERT(keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_NORMAL, "TODO"); + uint8_t key_info_str[MAX_POLICY_KEY_INFO_LEN]; - int key_info_len = - call_get_merkle_leaf_element(dc, - st->wallet_header.keys_info_merkle_root, - st->wallet_header.n_keys, - keyexpr_info->key_expression_ptr->k.key_index, - key_info_str, - sizeof(key_info_str)); - - if (key_info_len < 0) { - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } + int key_info_len = call_get_merkle_leaf_element(dc, + st->wallet_header.keys_info_merkle_root, + st->wallet_header.n_keys, + key_index, + key_info_str, + sizeof(key_info_str)); + if (key_info_len < 0) { + return false; // should never happen + } - // Make a sub-buffer for the pubkey info - buffer_t key_info_buffer = buffer_create(key_info_str, key_info_len); + // Make a sub-buffer for the pubkey info + buffer_t key_info_buffer = buffer_create(key_info_str, key_info_len); - if (parse_policy_map_key_info(&key_info_buffer, &key_info, st->wallet_header.version) == - -1) { - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } + if (parse_policy_map_key_info(&key_info_buffer, &key_info, st->wallet_header.version) == -1) { + return false; // should never happen } uint32_t fpr = read_u32_be(key_info.master_key_fingerprint, 0); @@ -701,33 +696,62 @@ static bool __attribute__((noinline)) fill_keyexpr_info_if_internal(dispatcher_c return false; } - { - // it could be a collision on the fingerprint; we verify that we can actually generate - // the same pubkey - if (0 > get_extended_pubkey_at_path(key_info.master_key_derivation, - key_info.master_key_derivation_len, - BIP32_PUBKEY_VERSION, - &keyexpr_info->pubkey)) { - SEND_SW(dc, SW_BAD_STATE); - return false; - } - - if (memcmp(&key_info.ext_pubkey, &keyexpr_info->pubkey, sizeof(keyexpr_info->pubkey)) != - 0) { - return false; - } + // it could be a collision on the fingerprint; we verify that we can actually generate + // the same pubkey + if (0 > get_extended_pubkey_at_path(key_info.master_key_derivation, + key_info.master_key_derivation_len, + BIP32_PUBKEY_VERSION, + &keyexpr_info->pubkey)) { + return false; + } - keyexpr_info->key_derivation_length = key_info.master_key_derivation_len; - for (int i = 0; i < key_info.master_key_derivation_len; i++) { - keyexpr_info->key_derivation[i] = key_info.master_key_derivation[i]; - } + if (memcmp(&key_info.ext_pubkey, &keyexpr_info->pubkey, sizeof(keyexpr_info->pubkey)) != 0) { + return false; + } - keyexpr_info->fingerprint = read_u32_be(key_info.master_key_fingerprint, 0); + keyexpr_info->key_derivation_length = key_info.master_key_derivation_len; + for (int i = 0; i < key_info.master_key_derivation_len; i++) { + keyexpr_info->key_derivation[i] = key_info.master_key_derivation[i]; } + keyexpr_info->fingerprint = read_u32_be(key_info.master_key_fingerprint, 0); + return true; } +static bool fill_keyexpr_info_if_internal(dispatcher_context_t *dc, + sign_psbt_state_t *st, + keyexpr_info_t *keyexpr_info) { + if (keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_NORMAL) { + return get_and_verify_key_info(dc, + st, + keyexpr_info->key_expression_ptr->k.key_index, + keyexpr_info); + + } else if (keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_MUSIG) { + // iterate through the keys of the musig() placeholder to find if a key is internal + musig_aggr_key_info_t *musig_info = + r_musig_aggr_key_info(&keyexpr_info->key_expression_ptr->m.musig_info); + uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); + + for (int idx_in_musig = 0; idx_in_musig < musig_info->n; idx_in_musig++) { + if (get_and_verify_key_info(dc, st, key_indexes[idx_in_musig], keyexpr_info)) { + // For musig2, we expect 0 as the fingerprint for the aggregate key, + // and its derivation length is 0 (as it's not derived from the BIP32 hierarchy) + // TODO: refactor, it's ugly to do it here + keyexpr_info->key_derivation_length = 0; + keyexpr_info->fingerprint = 0; + return true; + } + } + + return false; // no internal key found in musig placeholder + } else { + LEDGER_ASSERT(false, "Unreachable code"); + return false; + } +} + // finds the first key expression that corresponds to an internal key static bool find_first_internal_keyexpr(dispatcher_context_t *dc, sign_psbt_state_t *st, @@ -2321,6 +2345,443 @@ static bool __attribute__((noinline)) sign_sighash_schnorr_and_yield(dispatcher_ return true; } +static bool __attribute__((noinline)) yield_musig_data(dispatcher_context_t *dc, + sign_psbt_state_t *st, + unsigned int cur_input_index, + const uint8_t *data, + size_t data_len, + uint32_t tag, + const uint8_t participant_pk[static 33], + const uint8_t aggregate_pubkey[static 33], + const uint8_t *tapleaf_hash) { + LOG_PROCESSOR(__FILE__, __LINE__, __func__); + + if (st->protocol_version == 0) { + // Only support version 1 of the protocol + return false; + } + + // bytes: 1 5 varint data_len 33 33 0 or 32 + // CMD_YIELD + // + + // Yield signature + uint8_t cmd = CCMD_YIELD; + dc->add_to_response(&cmd, 1); + + uint8_t buf[9]; + + // Add tag + int tag_varint_len = varint_write(buf, 0, tag); + dc->add_to_response(buf, tag_varint_len); + + // Add input index + int input_index_varint_len = varint_write(buf, 0, cur_input_index); + dc->add_to_response(buf, input_index_varint_len); + + // Add data (pubnonce or partial signature) + dc->add_to_response(data, data_len); + + // Add participant public key + dc->add_to_response(participant_pk, 33); + + // Add aggregate public key + dc->add_to_response(aggregate_pubkey, 33); + + // Add tapleaf hash if provided + if (tapleaf_hash != NULL) { + dc->add_to_response(tapleaf_hash, 32); + } + + dc->finalize_response(SW_INTERRUPTED_EXECUTION); + + if (dc->process_interruption(dc) < 0) { + return false; + } + return true; +} + +static bool yield_musig_pubnonce(dispatcher_context_t *dc, + sign_psbt_state_t *st, + unsigned int cur_input_index, + const musig_pubnonce_t *pubnonce, + const uint8_t participant_pk[static 33], + const uint8_t aggregate_pubkey[static 33], + const uint8_t *tapleaf_hash) { + return yield_musig_data(dc, + st, + cur_input_index, + (const uint8_t *) pubnonce, + sizeof(musig_pubnonce_t), + CCMD_YIELD_MUSIG_PUBNONCE_TAG, + participant_pk, + aggregate_pubkey, + tapleaf_hash); +} + +static bool yield_musig_partial_signature(dispatcher_context_t *dc, + sign_psbt_state_t *st, + unsigned int cur_input_index, + const uint8_t psig[static 32], + const uint8_t participant_pk[static 33], + const uint8_t aggregate_pubkey[static 33], + const uint8_t *tapleaf_hash) { + return yield_musig_data(dc, + st, + cur_input_index, + psig, + 32, + CCMD_YIELD_MUSIG_PARTIALSIGNATURE_TAG, + participant_pk, + aggregate_pubkey, + tapleaf_hash); +} + +static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_context_t *dc, + sign_psbt_state_t *st, + keyexpr_info_t *keyexpr_info, + input_info_t *input, + unsigned int cur_input_index, + uint8_t sighash[static 32]) { + LOG_PROCESSOR(__FILE__, __LINE__, __func__); + + if (st->wallet_policy_map->type != TOKEN_TR) { + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + const policy_node_tr_t *tr_policy = (policy_node_tr_t *) st->wallet_policy_map; + + // plan: + // 1) compute aggregate pubkey + // 2) compute musig2 tweaks + // 3) compute taproot tweak (if keypath spend) + // if my pubnonce is in the psbt: + // 5) generate and yield pubnonce + // else: + // 6) generate and yield partial signature + + // 1) compute aggregate pubkey + + // TODO: we should compute the aggregate pubkey just once for the placeholder, instead of + // repeating for each input + wallet_derivation_info_t wdi = {.n_keys = st->wallet_header.n_keys, + .wallet_version = st->wallet_header.version, + .keys_merkle_root = st->wallet_header.keys_info_merkle_root, + .change = input->in_out.is_change, + .address_index = input->in_out.address_index}; + + // TODO: code duplication with policy.c::get_derived_pubkey; worth extracting a common method? + + serialized_extended_pubkey_t ext_pubkey; + + const policy_node_keyexpr_t *key_expr = keyexpr_info->key_expression_ptr; + musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); + uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); + plain_pk_t keys[MAX_PUBKEYS_PER_MUSIG]; + for (int i = 0; i < musig_info->n; i++) { + // we use ext_pubkey as a temporary variable; will overwrite later + if (0 > get_extended_pubkey(dc, &wdi, key_indexes[i], &ext_pubkey)) { + return -1; + } + memcpy(keys[i], ext_pubkey.compressed_pubkey, sizeof(ext_pubkey.compressed_pubkey)); + } + + musig_keyagg_context_t musig_ctx; + musig_key_agg(keys, musig_info->n, &musig_ctx); + + // compute the aggregated extended pubkey + memset(&ext_pubkey, 0, sizeof(ext_pubkey)); + write_u32_be(ext_pubkey.version, 0, BIP32_PUBKEY_VERSION); + + ext_pubkey.compressed_pubkey[0] = (musig_ctx.Q.y[31] % 2 == 0) ? 2 : 3; + memcpy(&ext_pubkey.compressed_pubkey[1], musig_ctx.Q.x, sizeof(musig_ctx.Q.x)); + memcpy(&ext_pubkey.chain_code, BIP_MUSIG_CHAINCODE, sizeof(BIP_MUSIG_CHAINCODE)); + + // 2) compute musig2 tweaks + // We always have exactly 2 BIP32 tweaks in wallet policies; if the musig is in the keypath + // spend, we also have an x-only taptweak with the taproot tree hash (or BIP-86/BIP-386 style if + // there is no taproot tree). + + uint32_t change_step = input->in_out.is_change ? keyexpr_info->key_expression_ptr->num_second + : keyexpr_info->key_expression_ptr->num_first; + uint32_t addr_index_step = input->in_out.address_index; + + // in wallet policies, we always have at least two bip32-tweaks, and we might have + // one x-only tweak per BIP-0341 (if spending from the keypath). + uint8_t tweaks[3][32]; + uint8_t *tweaks_ptrs[3] = {tweaks[0], tweaks[1], tweaks[2]}; + bool is_xonly[] = {false, false, true}; + size_t n_tweaks = 2; // might be changed to 3 below + + serialized_extended_pubkey_t agg_key_tweaked; + if (0 > bip32_CKDpub(&ext_pubkey, change_step, &agg_key_tweaked, tweaks[0])) { + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + if (0 > bip32_CKDpub(&agg_key_tweaked, addr_index_step, &agg_key_tweaked, tweaks[1])) { + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + // 3) compute taproot tweak (if keypath spend) + memset(tweaks[2], 0, 32); + if (!keyexpr_info->is_tapscript) { + n_tweaks = 3; + + crypto_tr_tagged_hash( + BIP0341_taptweak_tag, + sizeof(BIP0341_taptweak_tag), + agg_key_tweaked.compressed_pubkey + 1, // xonly key, after BIP-32 tweaks + 32, + input->taptree_hash, + // BIP-86 compliant tweak if there's no taptree, otherwise use the taptree hash + isnull_policy_node_tree(&tr_policy->tree) ? 0 : 32, + tweaks[2]); + + // also apply the taptweak to agg_key_tweaked + + uint8_t parity = 0; + crypto_tr_tweak_pubkey(agg_key_tweaked.compressed_pubkey + 1, + input->taptree_hash, + isnull_policy_node_tree(&tr_policy->tree) ? 0 : 32, + &parity, + agg_key_tweaked.compressed_pubkey + 1); + agg_key_tweaked.compressed_pubkey[0] = 0x02 + parity; + } + + // we will no longer use the other fields of the extended pubkey, so we zero them for sanity + memset(agg_key_tweaked.chain_code, 0, sizeof(agg_key_tweaked.chain_code)); + memset(agg_key_tweaked.child_number, 0, sizeof(agg_key_tweaked.child_number)); + agg_key_tweaked.depth = 0; + memset(agg_key_tweaked.parent_fingerprint, 0, sizeof(agg_key_tweaked.parent_fingerprint)); + memset(agg_key_tweaked.version, 0, sizeof(agg_key_tweaked.version)); + + // Compute musig_my_psbt_id. It is the psbt key that this signer uses to find pubnonces and + // partial signatures (PSBT_IN_MUSIG2_PUB_NONCE and PSBT_IN_MUSIG2_PARTIAL_SIG fields). The + // length is either 33+33 (keypath spend), or 33+33+32 bytes (tapscript spend). It's the + // concatenation of: + // - the 33-byte compressed pubkey of this participant + // - the 33-byte aggregate compressed pubkey (after all the tweaks) + // - (tapscript only) the 32-byte tapleaf hash + uint8_t musig_my_psbt_id_key[1 + 33 + 33 + 32]; + musig_my_psbt_id_key[0] = PSBT_IN_MUSIG2_PUB_NONCE; + + uint8_t *musig_my_psbt_id = musig_my_psbt_id_key + 1; + size_t psbt_id_len = keyexpr_info->is_tapscript ? 33 + 33 + 32 : 33 + 33; + memcpy(musig_my_psbt_id, keyexpr_info->pubkey.compressed_pubkey, 33); + memcpy(musig_my_psbt_id + 33, agg_key_tweaked.compressed_pubkey, 33); + if (keyexpr_info->is_tapscript) { + memcpy(musig_my_psbt_id + 33 + 33, keyexpr_info->tapleaf_hash, 32); + } + + // compute psbt session id + uint8_t psbt_session_id[32]; + // TODO: for now we use simply a hash that depends on the keys of the wallet policy; this is not + // good enough. It should be a hash that depends on: + // - the wallet policy id + // - the tx being signed + // - the input index + // - the index of the placeholder we're signing for + memcpy(psbt_session_id, st->wallet_header.keys_info_merkle_root, sizeof(psbt_session_id)); + + // 4) check if my pubnonce is in the psbt + musig_pubnonce_t my_pubnonce; + if (sizeof(musig_pubnonce_t) != call_get_merkleized_map_value(dc, + &input->in_out.map, + musig_my_psbt_id_key, + 1 + psbt_id_len, + my_pubnonce.raw, + sizeof(musig_pubnonce_t))) { + // 5) generate and yield pubnonce + + // if an existing session for psbt_session_id exists, delete it + if (musigsession_pop(psbt_session_id, NULL)) { + // We wouldn't expect this: probably the client sent the same psbt for + // round 1 twice, without adding the pubnonces to the psbt after the first round. + // We delete the old session and start a fresh one, but we print a + // warning if in debug mode. + PRINTF("Session with the same id already existing\n"); + } + + musig_session_t psbt_session; + memcpy(psbt_session.id, psbt_session_id, sizeof(psbt_session_id)); + + // TODO: the "session" should be initialized once for all the (inputs, placeholder) pairs; + // this is wrong! + musigsession_init_randomness(&psbt_session); + + uint8_t rand_i_j[32]; + compute_rand_i_j(psbt_session.rand_root, + cur_input_index, + keyexpr_info->cur_index, + rand_i_j); + + musig_secnonce_t secnonce; + musig_pubnonce_t pubnonce; + if (0 > musig_nonce_gen(rand_i_j, + keyexpr_info->pubkey.compressed_pubkey, + agg_key_tweaked.compressed_pubkey + 1, + &secnonce, + &pubnonce)) { + PRINTF("MuSig2 nonce generation failed\n"); + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + if (!yield_musig_pubnonce(dc, + st, + cur_input_index, + &pubnonce, + keyexpr_info->pubkey.compressed_pubkey, + agg_key_tweaked.compressed_pubkey, + keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) { + PRINTF("Failed yielding MuSig2 pubnonce\n"); + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + // TODO: wrong if we have multiple inputs! + musigsession_store(psbt_session_id, &psbt_session); + } else { + // 6) generate and yield partial signature + musig_session_t psbt_session; + // get and delete the musig session from permanent storage + if (!musigsession_pop(psbt_session_id, &psbt_session)) { + // The PSBT contains a partial nonce, but we do not have the corresponding psbt session + // in storage. Either it was deleted, or the pubnonces were not real. Either way, we + // cannot continue. + PRINTF("Missing MuSig2 session\n"); + SEND_SW(dc, SW_BAD_STATE); + return false; + } + + musig_pubnonce_t nonces[MAX_PUBKEYS_PER_MUSIG]; + + for (int i = 0; i < musig_info->n; i++) { + uint8_t musig_ith_psbt_id_key[1 + 33 + 33 + 32]; + uint8_t *musig_ith_psbt_id = musig_ith_psbt_id_key + 1; + // copy from musig_my_psbt_id_key, but replace the corresponding pubkey + memcpy(musig_ith_psbt_id_key, musig_my_psbt_id_key, sizeof(musig_my_psbt_id_key)); + memcpy(musig_ith_psbt_id, keys[i], sizeof(plain_pk_t)); + + // TODO: could avoid fetching again our own pubnonce + if (sizeof(musig_pubnonce_t) != + call_get_merkleized_map_value(dc, + &input->in_out.map, + musig_ith_psbt_id_key, + 1 + psbt_id_len, + nonces[i].raw, + sizeof(musig_pubnonce_t))) { + PRINTF("Missing or incorrect pubnonce for a MuSig2 cosigner\n"); + SEND_SW(dc, SW_INCORRECT_DATA); + return false; + } + } + + // compute aggregate nonce + musig_pubnonce_t aggnonce; + int res = musig_nonce_agg(nonces, musig_info->n, &aggnonce); + if (res < 0) { + PRINTF("Musig aggregation failed; disruptive signer has index %d\n", -res); + SEND_SW(dc, SW_INCORRECT_DATA); + } + + // recompute secnonce from psbt_session randomness + uint8_t rand_i_j[32]; + compute_rand_i_j(psbt_session.rand_root, + cur_input_index, + keyexpr_info->cur_index, + rand_i_j); + + musig_secnonce_t secnonce; + musig_pubnonce_t pubnonce; + + if (0 > musig_nonce_gen(rand_i_j, + keyexpr_info->pubkey.compressed_pubkey, + agg_key_tweaked.compressed_pubkey + 1, + &secnonce, + &pubnonce)) { + PRINTF("MuSig2 nonce generation failed\n"); + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + // derive secret key + + cx_ecfp_private_key_t private_key = {0}; + uint8_t psig[32]; + bool err = false; + do { // block executed once, only to allow safely breaking out on error + + // derive secret key + uint32_t sign_path[MAX_BIP32_PATH_STEPS]; + + // TODO: wrong, this should be based on the internal key derivation length + for (int i = 0; i < keyexpr_info->key_derivation_length; i++) { + sign_path[i] = keyexpr_info->key_derivation[i]; + } + sign_path[keyexpr_info->key_derivation_length] = change_step; + sign_path[keyexpr_info->key_derivation_length + 1] = addr_index_step; + + int sign_path_len = keyexpr_info->key_derivation_length + 2; + + // TODO: hardcoded for the current tests. Fix this! + sign_path[0] = 0x80000000 + 44; + sign_path[1] = 0x80000000 + 1; + sign_path[2] = 0x80000000 + 0; + sign_path_len = 3; + + if (bip32_derive_init_privkey_256(CX_CURVE_256K1, + sign_path, + sign_path_len, + &private_key, + NULL) != CX_OK) { + err = true; + break; + } + + // Create partial signature + musig_session_context_t musig_session_context = {.aggnonce = &aggnonce, + .n_keys = musig_info->n, + .pubkeys = keys, + .n_tweaks = n_tweaks, + .tweaks = tweaks_ptrs, + .is_xonly = is_xonly, + .msg = sighash, + .msg_len = 32}; + + if (0 > musig_sign(&secnonce, private_key.d, &musig_session_context, psig)) { + PRINTF("Musig2 signature failed\n"); + err = true; + break; + } + } while (false); + + explicit_bzero(&private_key, sizeof(private_key)); + + if (err) { + PRINTF("Partial signature generation failed\n"); + return false; + } + + if (!yield_musig_partial_signature( + dc, + st, + cur_input_index, + psig, + keyexpr_info->pubkey.compressed_pubkey, + agg_key_tweaked.compressed_pubkey, + keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) { + PRINTF("Failed yielding MuSig2 partial signature\n"); + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + } + + return true; +} + static bool __attribute__((noinline)) compute_segwit_hashes(dispatcher_context_t *dc, sign_psbt_state_t *st, segwit_hashes_t *hashes) { { @@ -2475,6 +2936,8 @@ static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_ // Sign as segwit input iff it has a witness utxo if (!input->has_witnessUtxo) { + LEDGER_ASSERT(keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_NORMAL, + "Only plain key expressions are valid for legacy inputs"); // sign legacy P2PKH or P2SH // sign_non_witness(non_witness_utxo.vout[psbt.tx.input_[i].prevout.n].scriptPubKey, i) @@ -2555,6 +3018,8 @@ static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_ int segwit_version = get_policy_segwit_version(st->wallet_policy_map); uint8_t sighash[32]; if (segwit_version == 0) { + LEDGER_ASSERT(keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_NORMAL, + "Only plain key expressions are valid for SegwitV0 inputs"); if (!input->has_sighash_type) { // segwitv0 inputs default to SIGHASH_ALL input->sighash_type = SIGHASH_ALL; @@ -2606,13 +3071,25 @@ static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_ } } - if (!sign_sighash_schnorr_and_yield(dc, - st, - keyexpr_info, - input, - cur_input_index, - sighash)) - return false; + if (keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_NORMAL) { + if (!sign_sighash_schnorr_and_yield(dc, + st, + keyexpr_info, + input, + cur_input_index, + sighash)) + return false; + } else if (keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_MUSIG) { + if (!sign_sighash_musig_and_yield(dc, + st, + keyexpr_info, + input, + cur_input_index, + sighash)) + return false; + } else { + LEDGER_ASSERT(false, "Unreachable"); + } } else { SEND_SW(dc, SW_BAD_STATE); // can't happen diff --git a/src/musig/musig.c b/src/musig/musig.c index b4ffb4432..752e54e45 100644 --- a/src/musig/musig.c +++ b/src/musig/musig.c @@ -1,5 +1,7 @@ #include +#include "cx_errors.h" + #include "musig.h" #include "../crypto.h" @@ -9,6 +11,12 @@ static const uint8_t BIP0327_keyagg_coeff_tag[] = {'K', 'e', 'y', 'A', 'g', 'g', ' ', 'c', 'o', 'e', 'f', 'f', 'i', 'c', 'i', 'e', 'n', 't'}; static const uint8_t BIP0327_keyagg_list_tag[] = {'K', 'e', 'y', 'A', 'g', 'g', ' ', 'l', 'i', 's', 't'}; +static const uint8_t BIP0327_nonce_tag[] = {'M', 'u', 'S', 'i', 'g', '/', 'n', 'o', 'n', 'c', 'e'}; +static const uint8_t BIP0327_noncecoef_tag[] = + {'M', 'u', 'S', 'i', 'g', '/', 'n', 'o', 'n', 'c', 'e', 'c', 'o', 'e', 'f'}; + +static const uint8_t BIP0340_challenge_tag[] = + {'B', 'I', 'P', '0', '3', '4', '0', '/', 'c', 'h', 'a', 'l', 'l', 'e', 'n', 'g', 'e'}; static inline bool is_point_infinite(const point_t *P) { return P->prefix == 0; @@ -18,7 +26,9 @@ static inline void set_point_infinite(point_t *P) { memset(P->raw, 0, sizeof(point_t)); } -static int point_add(const point_t *P1, const point_t *P2, point_t *out) { +#define G ((const point_t *) secp256k1_generator) + +static cx_err_t point_add(const point_t *P1, const point_t *P2, point_t *out) { if (is_point_infinite(P1)) { memmove(out->raw, P2->raw, sizeof(point_t)); return CX_OK; @@ -31,7 +41,30 @@ static int point_add(const point_t *P1, const point_t *P2, point_t *out) { memset(out->raw, 0, sizeof(point_t)); return CX_OK; } - return cx_ecfp_add_point_no_throw(CX_CURVE_SECP256K1, out->raw, P1->raw, P2->raw); + + cx_err_t res = cx_ecfp_add_point_no_throw(CX_CURVE_SECP256K1, out->raw, P1->raw, P2->raw); + if (res == CX_EC_INFINITE_POINT) { + set_point_infinite(out); + return CX_OK; + } + + return res; +} + +static cx_err_t point_mul(const point_t *P, const uint8_t scalar[static 32], point_t *out) { + if (is_point_infinite(P)) { + set_point_infinite(out); + return CX_OK; + } + point_t Q; // result + memcpy(&Q, P, sizeof(point_t)); + cx_err_t res = cx_ecfp_scalar_mult_no_throw(CX_CURVE_SECP256K1, Q.raw, scalar, 32); + if (res == CX_EC_INFINITE_POINT) { + set_point_infinite(out); + return CX_OK; + } + memcpy(out, &Q, sizeof(point_t)); + return res; } // out can be equal to P @@ -48,6 +81,12 @@ static int point_negate(const point_t *P, point_t *out) { return 0; } +static bool has_even_y(const point_t *P) { + LEDGER_ASSERT(!is_point_infinite(P), "has_even_y called with an infinite point"); + + return P->y[31] % 2 == 0; +} + static int cpoint(const uint8_t x[33], point_t *out) { crypto_tr_lift_x(&x[1], out->raw); if (is_point_infinite(out)) { @@ -67,6 +106,25 @@ static int cpoint(const uint8_t x[33], point_t *out) { } } +static bool is_array_zero(const uint8_t buffer[], size_t buffer_len) { + uint8_t acc = 0; + for (size_t i = 0; i < buffer_len; i++) { + acc |= buffer[i]; + } + return acc == 0; +} + +int cpoint_ext(const uint8_t x[static 33], point_t *out) { + // Check if the point is at infinity (all bytes zero) + if (is_array_zero(x, 33)) { + set_point_infinite(out); + return 0; + } + + // Otherwise, handle as a regular compressed point + return cpoint(x, out); +} + static void musig_get_second_key(const plain_pk_t pubkeys[], size_t n_keys, plain_pk_t out) { for (size_t i = 0; i < n_keys; i++) { if (memcmp(pubkeys[0], pubkeys[i], sizeof(plain_pk_t)) != 0) { @@ -114,6 +172,16 @@ static void musig_key_agg_coeff_internal(const plain_pk_t pubkeys[], } } +static void musig_key_agg_coeff(const plain_pk_t pubkeys[], + size_t n_keys, + const plain_pk_t pk_, + uint8_t out[static CX_SHA256_SIZE]) { + plain_pk_t pk2; + musig_get_second_key(pubkeys, n_keys, pk2); + + musig_key_agg_coeff_internal(pubkeys, n_keys, pk_, pk2, out); +} + int musig_key_agg(const plain_pk_t pubkeys[], size_t n_keys, musig_keyagg_context_t *ctx) { plain_pk_t pk2; musig_get_second_key(pubkeys, n_keys, pk2); @@ -132,7 +200,7 @@ int musig_key_agg(const plain_pk_t pubkeys[], size_t n_keys, musig_keyagg_contex musig_key_agg_coeff_internal(pubkeys, n_keys, pubkeys[i], pk2, a_i); // set P := a_i * P_i - if (CX_OK != cx_ecfp_scalar_mult_no_throw(CX_CURVE_SECP256K1, P.raw, a_i, 32)) { + if (CX_OK != point_mul(&P, a_i, &P)) { PRINTF("Scalar multiplication failed in musig_key_agg\n"); return -1; } @@ -144,3 +212,388 @@ int musig_key_agg(const plain_pk_t pubkeys[], size_t n_keys, musig_keyagg_contex ctx->gacc[31] = 1; return 0; } + +static void musig_nonce_hash(const uint8_t *rand, + const plain_pk_t pk, + const xonly_pk_t aggpk, + uint8_t i, + const uint8_t *msg_prefixed, + size_t msg_prefixed_len, + const uint8_t *extra_in, + size_t extra_in_len, + uint8_t out[static CX_SHA256_SIZE]) { + cx_sha256_t hash_context; + crypto_tr_tagged_hash_init(&hash_context, BIP0327_nonce_tag, sizeof(BIP0327_nonce_tag)); + + // rand + crypto_hash_update(&hash_context.header, rand, 32); + + // len(pk) + pk + crypto_hash_update_u8(&hash_context.header, sizeof(plain_pk_t)); + crypto_hash_update(&hash_context.header, pk, sizeof(plain_pk_t)); + + // len(aggpk) + aggpk + crypto_hash_update_u8(&hash_context.header, sizeof(xonly_pk_t)); + crypto_hash_update(&hash_context.header, aggpk, sizeof(xonly_pk_t)); + + // msg_prefixed + crypto_hash_update(&hash_context.header, msg_prefixed, msg_prefixed_len); + + // len(extra_in) (4 bytes) + extra_in + crypto_hash_update_u32(&hash_context.header, extra_in_len); + if (extra_in_len > 0) { + crypto_hash_update(&hash_context.header, extra_in, extra_in_len); + } + + crypto_hash_update_u8(&hash_context.header, i); + + crypto_hash_digest(&hash_context.header, out, CX_SHA256_SIZE); +} + +// same as nonce_gen_internal from the reference, removing the optional arguments sk, msg and +// extra_in, and making aggpk compulsory +int musig_nonce_gen(const uint8_t rand[32], + const plain_pk_t pk, + const xonly_pk_t aggpk, + musig_secnonce_t *secnonce, + musig_pubnonce_t *pubnonce) { + uint8_t msg[] = {0x00}; + + musig_nonce_hash(rand, pk, aggpk, 0, msg, 1, NULL, 0, secnonce->k_1); + if (CX_OK != cx_math_modm_no_throw(secnonce->k_1, 32, secp256k1_n, 32)) return -1; + musig_nonce_hash(rand, pk, aggpk, 1, msg, 1, NULL, 0, secnonce->k_2); + if (CX_OK != cx_math_modm_no_throw(secnonce->k_2, 32, secp256k1_n, 32)) return -1; + + memcpy(secnonce->pk, pk, 33); + + point_t R_s1, R_s2; + + if (CX_OK != point_mul(G, secnonce->k_1, &R_s1)) return -1; + if (CX_OK != point_mul(G, secnonce->k_2, &R_s2)) return -1; + + if (0 > crypto_get_compressed_pubkey(R_s1.raw, pubnonce->R_s1)) return -1; + if (0 > crypto_get_compressed_pubkey(R_s2.raw, pubnonce->R_s2)) return -1; + + return 0; +} + +int musig_nonce_agg(const musig_pubnonce_t pubnonces[], size_t n_keys, musig_pubnonce_t *out) { + for (size_t j = 1; j <= 2; j++) { + point_t R_j; + set_point_infinite(&R_j); + for (size_t i = 0; i < n_keys; i++) { + point_t R_ij; + if (0 > cpoint(&pubnonces[i].raw[(j - 1) * 33], &R_ij)) { + PRINTF("Musig2 nonce aggregation: invalid contribution from cosigner %d\n", i); + return -i - 1; + } + point_add(&R_j, &R_ij, &R_j); + } + + if (is_point_infinite(&R_j)) { + memset(&out->raw[(j - 1) * 33], 0, 33); + } else { + crypto_get_compressed_pubkey(R_j.raw, &out->raw[(j - 1) * 33]); + } + } + return 0; +} + +static int apply_tweak(musig_keyagg_context_t *ctx, const uint8_t tweak[static 32], bool is_xonly) { + if (tweak == NULL || ctx == NULL) { + return -1; + } + + uint8_t g[32]; + memset(g, 0, 31); + g[31] = 1; // g = 1 + + if (is_xonly && !has_even_y(&ctx->Q)) { + // g = n - 1 + if (CX_OK != cx_math_sub_no_throw(g, secp256k1_n, g, 32)) { + return -1; + }; + } + + int diff; + if (CX_OK != cx_math_cmp_no_throw(tweak, secp256k1_n, 32, &diff)) { + return -1; + } + if (diff >= 0) { + PRINTF("The tweak must be less than n\n"); + return -1; + } + + // compute Q * g (in place) + + if (point_mul(&ctx->Q, g, &ctx->Q) != CX_OK) { + return -1; + } + + point_t T; // compute T = tweak * G + if (point_mul(G, tweak, &T) != CX_OK) { + return -1; + } + + // compute the resulting tweaked point g * Q + tweak * G + point_add(&ctx->Q, &T, &ctx->Q); + if (is_point_infinite(&ctx->Q)) { + PRINTF("The result of tweaking cannot be infinity\n"); + return -1; + } + + // gacc := g * gacc % n + if (CX_OK != cx_math_multm_no_throw(ctx->gacc, g, ctx->gacc, secp256k1_n, 32)) { + return -1; + } + + // tacc := (g * tacc + t) % n + if (CX_OK != cx_math_multm_no_throw(ctx->tacc, g, ctx->tacc, secp256k1_n, 32)) { + return -1; + } + if (CX_OK != cx_math_addm_no_throw(ctx->tacc, ctx->tacc, tweak, secp256k1_n, 32)) { + return -1; + } + + return 0; +} + +static int musig_get_session_values(const musig_session_context_t *session_ctx, + point_t *Q, + uint8_t gacc[static 32], + uint8_t tacc[static 32], + uint8_t b[static 32], + point_t *R, + uint8_t e[static 32]) { + cx_sha256_t hash_context; + + // Perform key aggregation and tweaking + musig_keyagg_context_t keyagg_ctx; + musig_key_agg(session_ctx->pubkeys, session_ctx->n_keys, &keyagg_ctx); + for (size_t i = 0; i < session_ctx->n_tweaks; i++) { + if (0 > apply_tweak(&keyagg_ctx, session_ctx->tweaks[i], session_ctx->is_xonly[i])) { + return -1; + }; + } + + // Copy Q, gacc, tacc from keyagg_ctx + memcpy(Q, &keyagg_ctx.Q, sizeof(point_t)); + memcpy(gacc, keyagg_ctx.gacc, 32); + memcpy(tacc, keyagg_ctx.tacc, 32); + + // Calculate b + crypto_tr_tagged_hash_init(&hash_context, BIP0327_noncecoef_tag, sizeof(BIP0327_noncecoef_tag)); + crypto_hash_update(&hash_context.header, session_ctx->aggnonce->raw, 66); + crypto_hash_update(&hash_context.header, Q->x, 32); + crypto_hash_update(&hash_context.header, session_ctx->msg, session_ctx->msg_len); + crypto_hash_digest(&hash_context.header, b, 32); + + // Calculate R + point_t R_1, R_2; + if (0 > cpoint_ext(session_ctx->aggnonce->R_s1, &R_1)) { + return -1; + }; + if (0 > cpoint_ext(session_ctx->aggnonce->R_s2, &R_2)) { + return -1; + }; + + // R2 := b*R2 + if (point_mul(&R_2, b, &R_2) != CX_OK) { + return -1; + } + + if (CX_OK != point_add(&R_1, &R_2, R)) { + return -1; + }; + if (is_point_infinite(R)) { + memcpy(R->raw, G, sizeof(point_t)); + } + + // Calculate e + crypto_tr_tagged_hash_init(&hash_context, BIP0340_challenge_tag, sizeof(BIP0340_challenge_tag)); + crypto_hash_update(&hash_context.header, R->x, 32); + crypto_hash_update(&hash_context.header, Q->x, 32); + crypto_hash_update(&hash_context.header, session_ctx->msg, session_ctx->msg_len); + crypto_hash_digest(&hash_context.header, e, 32); + return 0; +} + +int musig_get_session_key_agg_coeff(const musig_session_context_t *session_ctx, + const point_t *P, + uint8_t out[static 32]) { + // Convert point to compressed public key + plain_pk_t pk; + crypto_get_compressed_pubkey(P->raw, pk); + + // Check if pk is in pubkeys + bool found = false; + for (size_t i = 0; i < session_ctx->n_keys; i++) { + if (memcmp(pk, session_ctx->pubkeys[i], sizeof(plain_pk_t)) == 0) { + found = true; + break; + } + } + if (!found) { + return -1; // Public key not found in the list of pubkeys + } + + musig_key_agg_coeff(session_ctx->pubkeys, session_ctx->n_keys, pk, out); + return 0; +} + +int musig_sign(musig_secnonce_t *secnonce, + const uint8_t sk[static 32], + const musig_session_context_t *session_ctx, + uint8_t psig[static 32]) { + point_t Q; + uint8_t gacc[32]; + uint8_t tacc[32]; + uint8_t b[32]; + point_t R; + uint8_t e[32]; + + int diff; + + if (0 > musig_get_session_values(session_ctx, &Q, gacc, tacc, b, &R, e)) { + return -1; + } + + uint8_t k_1[32]; + uint8_t k_2[32]; + memcpy(k_1, secnonce->k_1, 32); + memcpy(k_2, secnonce->k_2, 32); + + // paranoia: since reusing nonces is catastrophic, we make sure that they are zeroed out and + // work with a local copy instead + explicit_bzero(secnonce->k_1, sizeof(secnonce->k_1)); + explicit_bzero(secnonce->k_2, sizeof(secnonce->k_2)); + + if (CX_OK != cx_math_cmp_no_throw(k_1, secp256k1_n, 32, &diff)) { + return -1; + } + if (is_array_zero(k_1, sizeof(k_1)) || diff >= 0) { + PRINTF("first secnonce value is out of range\n"); + return -1; + } + if (CX_OK != cx_math_cmp_no_throw(k_2, secp256k1_n, 32, &diff)) { + return -1; + } + if (is_array_zero(k_2, sizeof(k_2)) || diff >= 0) { + PRINTF("second secnonce value is out of range\n"); + return -1; + } + + if (!has_even_y(&R)) { + if (CX_OK != cx_math_sub_no_throw(k_1, secp256k1_n, k_1, 32)) { + return -1; + }; + if (CX_OK != cx_math_sub_no_throw(k_2, secp256k1_n, k_2, 32)) { + return -1; + }; + } + + if (CX_OK != cx_math_cmp_no_throw(sk, secp256k1_n, 32, &diff)) { + return -1; + } + if (is_array_zero(sk, 32) || diff >= 0) { + PRINTF("secret key value is out of range\n"); + return -1; + } + + bool err = false; + + // Put together all the variables that we want to always zero out before returning. + // As an excess of safety, we put here any variable that is (directly or indirectly) derived + // from the secret during the computation of the signature + struct { + uint8_t d[32]; + point_t P; + uint8_t ead[32]; + uint8_t s[32]; + } secrets; + + do { // executed only once, to allow for an easy way to break out of the block + // P = d_ * G + if (point_mul(G, sk, &secrets.P) != CX_OK) { + err = true; + break; + } + + plain_pk_t pk; + crypto_get_compressed_pubkey(secrets.P.raw, pk); + + if (memcmp(pk, secnonce->pk, 33) != 0) { + err = true; + PRINTF("Public key does not match nonce_gen argument\n"); + break; + } + + uint8_t a[32]; + if (0 > musig_get_session_key_agg_coeff(session_ctx, &secrets.P, a)) { + err = true; + break; + } + + // g = 1 if has_even_y(Q) else n - 1 + uint8_t g[32]; + memset(g, 0, 31); + g[31] = 1; // g = 1 + if (!has_even_y(&Q)) { + // g = n - 1 + if (CX_OK != cx_math_sub_no_throw(g, secp256k1_n, g, 32)) { + err = true; + break; + }; + } + + // d_ in the reference implementation is just sk + // d = g * gacc % n + if (CX_OK != cx_math_multm_no_throw(secrets.d, g, gacc, secp256k1_n, 32)) { + err = true; + break; + } + // d = g * gacc * d_ % n + if (CX_OK != cx_math_multm_no_throw(secrets.d, secrets.d, sk, secp256k1_n, 32)) { + err = true; + break; + } + + uint8_t bk_2[32]; // b * k_2 + if (CX_OK != cx_math_multm_no_throw(bk_2, b, k_2, secp256k1_n, 32)) { + err = true; + break; + } + + // e * a * d + if (CX_OK != cx_math_multm_no_throw(secrets.ead, e, a, secp256k1_n, 32)) { + err = true; + break; + } + if (CX_OK != cx_math_multm_no_throw(secrets.ead, secrets.ead, secrets.d, secp256k1_n, 32)) { + err = true; + break; + } + + // s = k_1 + b * k_2 + e * a * d + memcpy(secrets.s, k_1, 32); + if (CX_OK != cx_math_addm_no_throw(secrets.s, secrets.s, bk_2, secp256k1_n, 32)) { + err = true; + break; + } + if (CX_OK != cx_math_addm_no_throw(secrets.s, secrets.s, secrets.ead, secp256k1_n, 32)) { + err = true; + break; + } + + memcpy(psig, secrets.s, 32); + } while (false); + + // make sure to zero out any variable derived from secrets before returning + explicit_bzero(&secrets, sizeof(secrets)); + + if (err) { + return -1; + } + + return 0; +} diff --git a/src/musig/musig.h b/src/musig/musig.h index d17f89b67..1a70334a7 100644 --- a/src/musig/musig.h +++ b/src/musig/musig.h @@ -3,6 +3,8 @@ #include #include +#define MUSIG_PUBNONCE_SIZE 66 + // TODO: rename once BIP number is assigned static uint8_t BIP_MUSIG_CHAINCODE[32] = { 0x86, 0x80, 0x87, 0xCA, 0x02, 0xA6, 0xF9, 0x74, 0xC4, 0x59, 0x89, 0x24, 0xC3, 0x6B, 0x57, 0x76, @@ -30,6 +32,33 @@ typedef struct musig_keyagg_context_s { uint8_t tacc[32]; } musig_keyagg_context_t; +typedef struct musig_secnonce_s { + uint8_t k_1[32]; + uint8_t k_2[32]; + uint8_t pk[33]; +} musig_secnonce_t; + +typedef struct musig_pubnonce_s { + union { + struct { + uint8_t R_s1[33]; + uint8_t R_s2[33]; + }; + uint8_t raw[66]; + }; +} musig_pubnonce_t; + +typedef struct musig_session_context_s { + musig_pubnonce_t *aggnonce; + size_t n_keys; + plain_pk_t *pubkeys; + size_t n_tweaks; + uint8_t **tweaks; + bool *is_xonly; + uint8_t *msg; + size_t msg_len; +} musig_session_context_t; + /** * Computes the KeyAgg Context per BIP-0327. * @@ -43,3 +72,58 @@ typedef struct musig_keyagg_context_s { * @return 0 on success, a negative number in case of error. */ int musig_key_agg(const plain_pk_t pubkeys[], size_t n_keys, musig_keyagg_context_t *ctx); + +/** + * Generates secret and public nonces (round 1 of MuSig per BIP-0327). + * + * @param[in] rand + * The randomness to use. + * @param[in] pk + * The 33-byte public key of the signer. + * @param[in] aggpk + * The 32-byte x-only aggregate public key. + * @param[out] secnonce + * Pointer to receive the secret nonce. + * @param[out] pubnonce + * Pointer to receive the public nonce. + * + * @return 0 on success, a negative number in case of error. + */ +int musig_nonce_gen(const uint8_t rand[32], + const plain_pk_t pk, + const xonly_pk_t aggpk, + musig_secnonce_t *secnonce, + musig_pubnonce_t *pubnonce); + +/** + * Generates the aggregate nonce (nonce_agg in the reference implementation). + * + * @param[in] rand + * A list of musig_pubnonce_t, the pubnonces of all the participants. + * @param[in] n_keys + * Number of pubkeys. + * @param[out] out + * Pointer to receive the aggregate nonce. + * + * @return 0 on success, a negative number in case of error. On error, `-i - 1` is returned if the + * nonce provided by the cosigner with index `i` is invalid, in order to allow blaming for a + * disruptive signer. + */ +int musig_nonce_agg(const musig_pubnonce_t pubnonces[], size_t n_keys, musig_pubnonce_t *out); + +/** + * Computes the partial signature (round 2 of MuSig per BIP-0327). + * + * @param[in] secnonce + * The secret nonce. + * @param[in] session_ctx + * The session context. + * @param[out] psig + * Pointer to receive the partial signature. + * + * @return 0 on success, a negative number in case of error. + */ +int musig_sign(musig_secnonce_t *secnonce, + const uint8_t sk[static 32], + const musig_session_context_t *session_ctx, + uint8_t psig[static 32]); diff --git a/src/musig/musig_sessions.c b/src/musig/musig_sessions.c new file mode 100644 index 000000000..4d38117b7 --- /dev/null +++ b/src/musig/musig_sessions.c @@ -0,0 +1,64 @@ +#include + +#include "cx.h" + +#include "musig_sessions.h" +#include "../crypto.h" + +// TODO: persist in NVRAM instead +musig_session_t musig_sessions[MAX_N_MUSIG_SESSIONS]; + +bool musigsession_pop(uint8_t psbt_session_id[static 32], musig_session_t *out) { + for (int i = 0; i < MAX_N_MUSIG_SESSIONS; i++) { + if (memcmp(psbt_session_id, musig_sessions[i].id, 32) == 0) { + if (out != NULL) { + memcpy(out, &musig_sessions[i], sizeof(musig_session_t)); + } + explicit_bzero(&musig_sessions[i], sizeof(musig_session_t)); + return true; + } + } + return false; +} + +static bool is_all_zeros(const uint8_t *array, size_t size) { + for (size_t i = 0; i < size; ++i) { + if (array[i] != 0) { + return false; + } + } + return true; +} + +void musigsession_init_randomness(musig_session_t *session) { + cx_get_random_bytes(session->rand_root, 32); +} + +void musigsession_store(uint8_t psbt_session_id[static 32], const musig_session_t *session) { + // make sure that no session with the same id exists; delete it otherwise + musigsession_pop(psbt_session_id, NULL); + + int i; + for (i = 0; i < MAX_N_MUSIG_SESSIONS; i++) { + if (is_all_zeros((uint8_t *) &musig_sessions[i], sizeof(musig_session_t))) { + break; + } + } + if (i >= MAX_N_MUSIG_SESSIONS) { + // no free slot found, delete the first by default + // TODO: should we use a LIFO structure? Could add a counter to musig_session_t + i = 0; + } + // no free slot; replace the first slot + explicit_bzero(&musig_sessions[i], sizeof(musig_session_t)); + memcpy(&musig_sessions[i], session, sizeof(musig_session_t)); +} + +void compute_rand_i_j(const uint8_t rand_root[static 32], int i, int j, uint8_t out[static 32]) { + cx_sha256_t hash_context; + cx_sha256_init(&hash_context); + crypto_hash_update(&hash_context.header, rand_root, CX_SHA256_SIZE); + crypto_hash_update_u32(&hash_context.header, (uint32_t) i); + crypto_hash_update_u32(&hash_context.header, (uint32_t) j); + crypto_hash_digest(&hash_context.header, out, 32); +} diff --git a/src/musig/musig_sessions.h b/src/musig/musig_sessions.h new file mode 100644 index 000000000..b708d6fb9 --- /dev/null +++ b/src/musig/musig_sessions.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include "musig.h" + +#define MAX_N_MUSIG_SESSIONS 8 + +typedef struct { + uint8_t id[32]; + uint8_t rand_root[32]; +} musig_session_t; + +extern musig_session_t musig_sessions[MAX_N_MUSIG_SESSIONS]; + +// TODO: docs +bool musigsession_pop(uint8_t psbt_session_id[static 32], musig_session_t *out); +void musigsession_init_randomness(musig_session_t *session); +void musigsession_store(uint8_t psbt_session_id[static 32], const musig_session_t *session); + +void compute_rand_i_j(const uint8_t rand_root[static 32], int i, int j, uint8_t out[static 32]); diff --git a/tests/test_sign_psbt_musig.py b/tests/test_sign_psbt_musig.py new file mode 100644 index 000000000..1baf41443 --- /dev/null +++ b/tests/test_sign_psbt_musig.py @@ -0,0 +1,162 @@ + +from pathlib import Path + +from hashlib import sha256 +import hmac + + +from ledger_bitcoin.client_base import Client, MusigPartialSignature, MusigPubNonce +from ledger_bitcoin.key import ExtendedKey +from ledger_bitcoin.psbt import PSBT +from ragger.navigator import Navigator +from ragger.firmware import Firmware + +from ledger_bitcoin.wallet import WalletPolicy +from ragger_bitcoin import RaggerClient +from test_utils import SpeculosGlobals, bip0327 +from test_utils.musig2 import HotMusig2Cosigner, Musig2KeyPlaceholder, PsbtMusig2Cosigner, TrDescriptorTemplate, run_musig2_test +from .instructions import * + +tests_root: Path = Path(__file__).parent + + +# for now, we assume that there's a single internal musig placeholder, with a single internal key +class LedgerMusig2Cosigner(PsbtMusig2Cosigner): + """ + Implements a PsbtMusig2Cosigner that uses a BitcoinClient + """ + + def __init__(self, client: Client, wallet_policy: WalletPolicy, wallet_hmac: bytes) -> None: + super().__init__() + + self.client = client + self.wallet_policy = wallet_policy + self.wallet_hmac = wallet_hmac + + self.fingerprint = client.get_master_fingerprint() + + desc_tmpl = TrDescriptorTemplate.from_string( + wallet_policy.descriptor_template) + + self.pubkey = None + for _, (placeholder, _) in enumerate(desc_tmpl.placeholders()): + if not isinstance(placeholder, Musig2KeyPlaceholder): + continue + + for i in placeholder.key_indexes: + key_info = self.wallet_policy.keys_info[i] + if key_info[0] == "[" and key_info[1:9] == self.fingerprint.hex(): + xpub = key_info[key_info.find(']') + 1:] + self.pubkey = ExtendedKey.deserialize(xpub) + break + + if self.pubkey is not None: + break + + if self.pubkey is None: + raise ValueError("no musig with an internal key in wallet policy") + + def get_participant_pubkey(self) -> bip0327.Point: + return bip0327.cpoint(self.pubkey.pubkey) + + def generate_public_nonces(self, psbt: PSBT) -> None: + print("PSBT before nonce generation:", psbt.serialize()) + res = self.client.sign_psbt(psbt, self.wallet_policy, self.wallet_hmac) + print("Pubnonces:", res) + for (input_index, yielded) in res: + if isinstance(yielded, MusigPubNonce): + psbt_key = ( + yielded.participant_pubkey, + yielded.aggregate_pubkey, + yielded.tapleaf_hash + ) + print("Adding pubnonce to psbt for Ledger input", input_index) + print("Key:", psbt_key) + print("Value:", yielded.pubnonce) + + assert len(yielded.aggregate_pubkey) == 33 + + psbt.inputs[input_index].musig2_pub_nonces[psbt_key] = yielded.pubnonce + + def generate_partial_signatures(self, psbt: PSBT) -> None: + print("PSBT before partial signature generation:", psbt.serialize()) + res = self.client.sign_psbt(psbt, self.wallet_policy, self.wallet_hmac) + print("Ledger result of second round:", res) + for (input_index, yielded) in res: + if isinstance(yielded, MusigPartialSignature): + psbt_key = ( + yielded.participant_pubkey, + yielded.aggregate_pubkey, + yielded.tapleaf_hash + ) + + print("Adding partial signature to psbt for Ledger input", input_index) + print("Key:", psbt_key) + print("Value:", yielded.partial_signature) + + psbt.inputs[input_index].musig2_partial_sigs[psbt_key] = yielded.partial_signature + elif isinstance(yielded, MusigPubNonce): + raise ValueError("Expected partial signatures, got a pubnonce") + + +def test_sign_psbt_musig2_keypath(client: RaggerClient, speculos_globals: SpeculosGlobals): + cosigner_1_xpub = "[f5acc2fd/44'/1'/0']tpubDCwYjpDhUdPGP5rS3wgNg13mTrrjBuG8V9VpWbyptX6TRPbNoZVXsoVUSkCjmQ8jJycjuDKBb9eataSymXakTTaGifxR6kmVsfFehH1ZgJT" + + cosigner_2_xpriv = "tprv8gFWbQBTLFhbX3EK3cS7LmenwE3JjXbD9kN9yXfq7LcBm81RSf8vPGPqGPjZSeX41LX9ZN14St3z8YxW48aq5Yhr9pQZVAyuBthfi6quTCf" + cosigner_2_xpub = "tpubDCwYjpDhUdPGQWG6wG6hkBJuWFZEtrn7j3xwG3i8XcQabcGC53xWZm1hSXrUPFS5UvZ3QhdPSjXWNfWmFGTioARHuG5J7XguEjgg7p8PxAm" + + wallet_policy = WalletPolicy( + name="Musig for my ears", + descriptor_template="tr(musig(@0,@1)/**)", + keys_info=[cosigner_1_xpub, cosigner_2_xpub] + ) + wallet_hmac = hmac.new( + speculos_globals.wallet_registration_key, wallet_policy.id, sha256).digest() + + psbt_b64 = "cHNidP8BAIACAAAAAWbcwfJ78yV/+Jn0waX9pBWhDp2pZCm0GuTEXe2wXcP2AQAAAAD9////AQAAAAAAAAAARGpCVGhpcyBpbnB1dHMgaGFzIHR3byBwdWJrZXlzIGJ1dCB5b3Ugb25seSBzZWUgb25lLiAjbXBjZ2FuZyByZXZlbmdlAAAAAAABASuf/gQAAAAAACJRIPSL0RqGcuiQxWUrpyqc9CJwAk7i1Wk1p+YZWmGpB5tmIRbGANErPozSP7sjGM7KD11/WcKOe0InwGoEZz9MPQ7Bxg0AAAAAAAAAAAADAAAAAAA=" + psbt = PSBT() + psbt.deserialize(psbt_b64) + + sighashes = [ + bytes.fromhex( + "f3f6d4ae955af42665667ccff4edc9244d9143ada53ba26aee036258e0ffeda9") + ] + + signer_1 = LedgerMusig2Cosigner(client, wallet_policy, wallet_hmac) + signer_2 = HotMusig2Cosigner(wallet_policy, cosigner_2_xpriv) + + run_musig2_test(wallet_policy, psbt, [signer_1, signer_2], sighashes) + + +def test_sign_psbt_musig2_scriptpath(client: RaggerClient, speculos_globals: SpeculosGlobals): + cosigner_1_xpub = "[f5acc2fd/44'/1'/0']tpubDCwYjpDhUdPGP5rS3wgNg13mTrrjBuG8V9VpWbyptX6TRPbNoZVXsoVUSkCjmQ8jJycjuDKBb9eataSymXakTTaGifxR6kmVsfFehH1ZgJT" + + cosigner_2_xpriv = "tprv8gFWbQBTLFhbX3EK3cS7LmenwE3JjXbD9kN9yXfq7LcBm81RSf8vPGPqGPjZSeX41LX9ZN14St3z8YxW48aq5Yhr9pQZVAyuBthfi6quTCf" + cosigner_2_xpub = ExtendedKey.deserialize( + cosigner_2_xpriv).neutered().to_string() + + wallet_policy = WalletPolicy( + name="Musig2 in the scriptpath", + descriptor_template="tr(@0/**,pk(musig(@1,@2)/**))", + keys_info=[ + "tpubD6NzVbkrYhZ4WLczPJWReQycCJdd6YVWXubbVUFnJ5KgU5MDQrD998ZJLSmaB7GVcCnJSDWprxmrGkJ6SvgQC6QAffVpqSvonXmeizXcrkN", + cosigner_1_xpub, + cosigner_2_xpub + ] + ) + wallet_hmac = hmac.new( + speculos_globals.wallet_registration_key, wallet_policy.id, sha256).digest() + + psbt_b64 = "cHNidP8BAFoCAAAAAeyfHxrwzXffQqF9egw6KMS7RwCLP4rW95dxtXUKYJGFAQAAAAD9////AQAAAAAAAAAAHmocTXVzaWcyLiBOb3cgZXZlbiBpbiBTY3JpcHRzLgAAAAAAAQErOTAAAAAAAAAiUSDZqQIMWvfc0h2w2z6+0vTt0z1YoUHA6JHynopzSe3hgiIVwethFsEeXf/x51pIczoAIsj9RoVePIBTyk/rOMW8B6uIIyDGANErPozSP7sjGM7KD11/WcKOe0InwGoEZz9MPQ7BxqzAIRbGANErPozSP7sjGM7KD11/WcKOe0InwGoEZz9MPQ7Bxi0BkW61VIaT9Qaz/k0SzoZ1UBsjkrXzPqXQbCbBjbNZP/kAAAAAAAAAAAMAAAABFyDrYRbBHl3/8edaSHM6ACLI/UaFXjyAU8pP6zjFvAeriAEYIJFutVSGk/UGs/5NEs6GdVAbI5K18z6l0GwmwY2zWT/5AAA=" + psbt = PSBT() + psbt.deserialize(psbt_b64) + + sighashes = [ + bytes.fromhex( + "ba6d1d859dbc471999fff1fc5b8740fdacadd64a10c8d62de76e39a1c8dcd835") + ] + + signer_1 = LedgerMusig2Cosigner(client, wallet_policy, wallet_hmac) + signer_2 = HotMusig2Cosigner(wallet_policy, cosigner_2_xpriv) + + run_musig2_test(wallet_policy, psbt, [signer_1, signer_2], sighashes) From 41be6f1e4beb90b36fcc4ba3fee40d0256a844d7 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:37:44 +0200 Subject: [PATCH 15/57] Update musig() specs, and fix psbt processing - musig() now sorts the keys, as per the BIP draft - correctly compute fingerprint for musig() aggregate key - added both the aggregate and the internal key in keyexpr_info_t struct - fixed psbt parsing logic to detect change/addr_index for musig - updated musig tests --- bitcoin_client/ledger_bitcoin/client.py | 11 +- bitcoin_client/ledger_bitcoin/client_base.py | 10 +- src/handler/lib/policy.c | 12 ++ src/handler/sign_psbt.c | 163 ++++++++++++++----- test_utils/musig2.py | 27 ++- tests/test_get_wallet_address.py | 4 +- tests/test_musig2.py | 8 +- tests/test_sign_psbt_musig.py | 8 +- 8 files changed, 178 insertions(+), 65 deletions(-) diff --git a/bitcoin_client/ledger_bitcoin/client.py b/bitcoin_client/ledger_bitcoin/client.py index b032c3ea1..89279df36 100644 --- a/bitcoin_client/ledger_bitcoin/client.py +++ b/bitcoin_client/ledger_bitcoin/client.py @@ -44,7 +44,8 @@ def parse_stream_to_map(f: BufferedReader) -> Mapping[bytes, bytes]: def aggr_xpub(pubkeys: List[bytes], chain: Chain) -> str: BIP_MUSIG_CHAINCODE = bytes.fromhex( "868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965") - ctx = key_agg(pubkeys) + # sort the pubkeys prior to aggregation + ctx = key_agg(list(sorted(pubkeys))) compressed_pubkey = cbytes(ctx.Q) # Serialize according to BIP-32 @@ -112,7 +113,7 @@ def _decode_signpsbt_yielded_value(res: bytes) -> Tuple[int, SignPsbtYieldedObje input_index = read_varint(res_buffer) pubnonce = res_buffer.read(66) participant_pk = res_buffer.read(33) - agg_xonlykey = res_buffer.read(32) + aggregate_pubkey = res_buffer.read(33) tapleaf_hash = res_buffer.read() if len(tapleaf_hash) == 0: tapleaf_hash = None @@ -121,7 +122,7 @@ def _decode_signpsbt_yielded_value(res: bytes) -> Tuple[int, SignPsbtYieldedObje input_index, MusigPubNonce( participant_pubkey=participant_pk, - agg_xonlykey=agg_xonlykey, + aggregate_pubkey=aggregate_pubkey, tapleaf_hash=tapleaf_hash, pubnonce=pubnonce ) @@ -130,7 +131,7 @@ def _decode_signpsbt_yielded_value(res: bytes) -> Tuple[int, SignPsbtYieldedObje input_index = read_varint(res_buffer) partial_signature = res_buffer.read(32) participant_pk = res_buffer.read(33) - agg_xonlykey = res_buffer.read(32) + aggregate_pubkey = res_buffer.read(33) tapleaf_hash = res_buffer.read() if len(tapleaf_hash) == 0: tapleaf_hash = None @@ -139,7 +140,7 @@ def _decode_signpsbt_yielded_value(res: bytes) -> Tuple[int, SignPsbtYieldedObje input_index, MusigPartialSignature( participant_pubkey=participant_pk, - agg_xonlykey=agg_xonlykey, + aggregate_pubkey=aggregate_pubkey, tapleaf_hash=tapleaf_hash, partial_signature=partial_signature ) diff --git a/bitcoin_client/ledger_bitcoin/client_base.py b/bitcoin_client/ledger_bitcoin/client_base.py index 3e69ee14f..d7b9461db 100644 --- a/bitcoin_client/ledger_bitcoin/client_base.py +++ b/bitcoin_client/ledger_bitcoin/client_base.py @@ -90,13 +90,14 @@ class MusigPubNonce: It always contains - the participant_pubkey, a 33-byte compressed pubkey; - - agg_xonlykey, the 32-byte xonly key that is the aggregate and tweaked key present in the script; + - aggregate_pubkey, the 33-byte compressed pubkey key that is the aggregate of all the participant + pubkeys, with the necessary tweaks; its x-only version is the key present in the Script; - the 66-byte pubnonce. The tapleaf_hash is also filled if signing for a tapscript; `None` otherwise. """ participant_pubkey: bytes - agg_xonlykey: bytes + aggregate_pubkey: bytes tapleaf_hash: Optional[bytes] pubnonce: bytes @@ -107,13 +108,14 @@ class MusigPartialSignature: It always contains - the participant_pubkey, a 33-byte compressed pubkey; - - agg_xonlykey, the 32-byte xonly key that is the aggregate and tweaked key present in the script; + - aggregate_pubkey, the 33-byte compressed pubkey key that is the aggregate of all the participant + pubkeys, with the necessary tweaks; its x-only version is the key present in the Script; - the partial_signature, the 32-byte partial signature for this participant. The tapleaf_hash is also filled if signing for a tapscript; `None` otherwise """ participant_pubkey: bytes - agg_xonlykey: bytes + aggregate_pubkey: bytes tapleaf_hash: Optional[bytes] partial_signature: bytes diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index 18b527f6d..ea9b66201 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -479,6 +479,18 @@ __attribute__((warn_unused_result)) static int get_derived_pubkey( memcpy(keys[i], ext_pubkey.compressed_pubkey, sizeof(ext_pubkey.compressed_pubkey)); } + // sort the keys in ascending order using bubble sort + for (int i = 0; i < musig_info->n; i++) { + for (int j = 0; j < musig_info->n - 1; j++) { + if (memcmp(keys[j], keys[j + 1], sizeof(plain_pk_t)) > 0) { + uint8_t tmp[sizeof(plain_pk_t)]; + memcpy(tmp, keys[j], sizeof(plain_pk_t)); + memcpy(keys[j], keys[j + 1], sizeof(plain_pk_t)); + memcpy(keys[j + 1], tmp, sizeof(plain_pk_t)); + } + } + } + musig_keyagg_context_t musig_ctx; musig_key_agg(keys, musig_info->n, &musig_ctx); diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index d4a3bb26a..1a3946d39 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -112,9 +112,25 @@ typedef struct { policy_node_keyexpr_t *key_expression_ptr; int cur_index; uint32_t fingerprint; - uint8_t key_derivation_length; + + // info about the internal key of this key expression + // used at signing time to derive the correct key uint32_t key_derivation[MAX_BIP32_PATH_STEPS]; + uint8_t key_derivation_length; + + // same as key_derivation_length for internal key + // expressions; 0 for musig, as the key derivation in + // the PSBT use the aggregate key as the root + // used to identify the correct change/address_index from the psbt + uint8_t psbt_root_key_derivation_length; + + // the root pubkey of this key expression serialized_extended_pubkey_t pubkey; + // the pubkey of the internal key of this key expression. + // same as `pubkey` for simple key expressions, but it's the actual + // internal key for musig key expressions + serialized_extended_pubkey_t internal_pubkey; + bool is_tapscript; // true if signing with a BIP342 tapleaf script path spend uint8_t tapleaf_hash[32]; // only used for tapscripts } keyexpr_info_t; @@ -423,8 +439,8 @@ static int read_change_and_index_from_psbt_bip32_derivation( // we use it to detect whether the current input is change or not, // and store its address index if (fpt_der[0] == keyexpr_info->fingerprint && - der_len == keyexpr_info->key_derivation_length + 2) { - for (int i = 0; i < keyexpr_info->key_derivation_length; i++) { + der_len == keyexpr_info->psbt_root_key_derivation_length + 2) { + for (int i = 0; i < keyexpr_info->psbt_root_key_derivation_length; i++) { if (keyexpr_info->key_derivation[i] != fpt_der[1 + i]) { return 0; } @@ -691,6 +707,16 @@ static bool __attribute__((noinline)) get_and_verify_key_info(dispatcher_context return false; // should never happen } + keyexpr_info->key_derivation_length = key_info.master_key_derivation_len; + for (int i = 0; i < key_info.master_key_derivation_len; i++) { + keyexpr_info->key_derivation[i] = key_info.master_key_derivation[i]; + } + + keyexpr_info->fingerprint = read_u32_be(key_info.master_key_fingerprint, 0); + + memcpy(&keyexpr_info->pubkey, &key_info.ext_pubkey, sizeof(serialized_extended_pubkey_t)); + + // the rest of the function verifies if the key is indeed internal, if it has our fingerprint uint32_t fpr = read_u32_be(key_info.master_key_fingerprint, 0); if (fpr != st->master_key_fingerprint) { return false; @@ -698,54 +724,104 @@ static bool __attribute__((noinline)) get_and_verify_key_info(dispatcher_context // it could be a collision on the fingerprint; we verify that we can actually generate // the same pubkey + serialized_extended_pubkey_t derived_pubkey; if (0 > get_extended_pubkey_at_path(key_info.master_key_derivation, key_info.master_key_derivation_len, BIP32_PUBKEY_VERSION, - &keyexpr_info->pubkey)) { + &derived_pubkey)) { return false; } - if (memcmp(&key_info.ext_pubkey, &keyexpr_info->pubkey, sizeof(keyexpr_info->pubkey)) != 0) { + if (memcmp(&key_info.ext_pubkey, &derived_pubkey, sizeof(derived_pubkey)) != 0) { return false; } - keyexpr_info->key_derivation_length = key_info.master_key_derivation_len; - for (int i = 0; i < key_info.master_key_derivation_len; i++) { - keyexpr_info->key_derivation[i] = key_info.master_key_derivation[i]; - } - - keyexpr_info->fingerprint = read_u32_be(key_info.master_key_fingerprint, 0); - return true; } static bool fill_keyexpr_info_if_internal(dispatcher_context_t *dc, sign_psbt_state_t *st, keyexpr_info_t *keyexpr_info) { - if (keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_NORMAL) { - return get_and_verify_key_info(dc, - st, - keyexpr_info->key_expression_ptr->k.key_index, - keyexpr_info); + keyexpr_info_t tmp_keyexpr_info; + // preserve the fields that are already computed outside of this function + memcpy(&tmp_keyexpr_info, keyexpr_info, sizeof(keyexpr_info_t)); + if (keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_NORMAL) { + bool result = get_and_verify_key_info(dc, + st, + keyexpr_info->key_expression_ptr->k.key_index, + &tmp_keyexpr_info); + if (result) { + memcpy(keyexpr_info, &tmp_keyexpr_info, sizeof(keyexpr_info_t)); + memcpy(&keyexpr_info->internal_pubkey, + &keyexpr_info->pubkey, + sizeof(serialized_extended_pubkey_t)); + keyexpr_info->psbt_root_key_derivation_length = keyexpr_info->key_derivation_length; + } + return result; } else if (keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_MUSIG) { // iterate through the keys of the musig() placeholder to find if a key is internal musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&keyexpr_info->key_expression_ptr->m.musig_info); uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); + bool has_internal_key = false; + + // collect the keys of the musig, and fill the info related to the internal key (if any) + uint8_t keys[MAX_PUBKEYS_PER_MUSIG][33]; for (int idx_in_musig = 0; idx_in_musig < musig_info->n; idx_in_musig++) { - if (get_and_verify_key_info(dc, st, key_indexes[idx_in_musig], keyexpr_info)) { - // For musig2, we expect 0 as the fingerprint for the aggregate key, - // and its derivation length is 0 (as it's not derived from the BIP32 hierarchy) - // TODO: refactor, it's ugly to do it here - keyexpr_info->key_derivation_length = 0; - keyexpr_info->fingerprint = 0; - return true; + if (get_and_verify_key_info(dc, st, key_indexes[idx_in_musig], &tmp_keyexpr_info)) { + memcpy(keyexpr_info->key_derivation, + tmp_keyexpr_info.key_derivation, + sizeof(tmp_keyexpr_info.key_derivation)); + keyexpr_info->key_derivation_length = tmp_keyexpr_info.key_derivation_length; + + // keep track of the actual internal key of this key expression + memcpy(&keyexpr_info->internal_pubkey, + &tmp_keyexpr_info.pubkey, + sizeof(serialized_extended_pubkey_t)); + + has_internal_key = true; } + + memcpy(keys[idx_in_musig], tmp_keyexpr_info.pubkey.compressed_pubkey, 33); + } + + if (has_internal_key) { + keyexpr_info->psbt_root_key_derivation_length = 0; + + // sort the keys in ascending order using bubble sort + for (int i = 0; i < musig_info->n; i++) { + for (int j = 0; j < musig_info->n - 1; j++) { + if (memcmp(keys[j], keys[j + 1], sizeof(plain_pk_t)) > 0) { + uint8_t tmp[sizeof(plain_pk_t)]; + memcpy(tmp, keys[j], sizeof(plain_pk_t)); + memcpy(keys[j], keys[j + 1], sizeof(plain_pk_t)); + memcpy(keys[j + 1], tmp, sizeof(plain_pk_t)); + } + } + } + + musig_keyagg_context_t musig_ctx; + musig_key_agg(keys, musig_info->n, &musig_ctx); + + // compute the aggregated extended pubkey + memset(&keyexpr_info->pubkey, 0, sizeof(keyexpr_info->pubkey)); + write_u32_be(keyexpr_info->pubkey.version, 0, BIP32_PUBKEY_VERSION); + + keyexpr_info->pubkey.compressed_pubkey[0] = (musig_ctx.Q.y[31] % 2 == 0) ? 2 : 3; + memcpy(&keyexpr_info->pubkey.compressed_pubkey[1], + musig_ctx.Q.x, + sizeof(musig_ctx.Q.x)); + memcpy(&keyexpr_info->pubkey.chain_code, + BIP_MUSIG_CHAINCODE, + sizeof(BIP_MUSIG_CHAINCODE)); + + keyexpr_info->fingerprint = + crypto_get_key_fingerprint(keyexpr_info->pubkey.compressed_pubkey); } - return false; // no internal key found in musig placeholder + return has_internal_key; // no internal key found in musig placeholder } else { LEDGER_ASSERT(false, "Unreachable code"); return false; @@ -2487,6 +2563,18 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co memcpy(keys[i], ext_pubkey.compressed_pubkey, sizeof(ext_pubkey.compressed_pubkey)); } + // sort the keys in ascending order using bubble sort + for (int i = 0; i < musig_info->n; i++) { + for (int j = 0; j < musig_info->n - 1; j++) { + if (memcmp(keys[j], keys[j + 1], sizeof(plain_pk_t)) > 0) { + uint8_t tmp[sizeof(plain_pk_t)]; + memcpy(tmp, keys[j], sizeof(plain_pk_t)); + memcpy(keys[j], keys[j + 1], sizeof(plain_pk_t)); + memcpy(keys[j + 1], tmp, sizeof(plain_pk_t)); + } + } + } + musig_keyagg_context_t musig_ctx; musig_key_agg(keys, musig_info->n, &musig_ctx); @@ -2569,7 +2657,7 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co uint8_t *musig_my_psbt_id = musig_my_psbt_id_key + 1; size_t psbt_id_len = keyexpr_info->is_tapscript ? 33 + 33 + 32 : 33 + 33; - memcpy(musig_my_psbt_id, keyexpr_info->pubkey.compressed_pubkey, 33); + memcpy(musig_my_psbt_id, keyexpr_info->internal_pubkey.compressed_pubkey, 33); memcpy(musig_my_psbt_id + 33, agg_key_tweaked.compressed_pubkey, 33); if (keyexpr_info->is_tapscript) { memcpy(musig_my_psbt_id + 33 + 33, keyexpr_info->tapleaf_hash, 32); @@ -2620,7 +2708,7 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co musig_secnonce_t secnonce; musig_pubnonce_t pubnonce; if (0 > musig_nonce_gen(rand_i_j, - keyexpr_info->pubkey.compressed_pubkey, + keyexpr_info->internal_pubkey.compressed_pubkey, agg_key_tweaked.compressed_pubkey + 1, &secnonce, &pubnonce)) { @@ -2633,7 +2721,7 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co st, cur_input_index, &pubnonce, - keyexpr_info->pubkey.compressed_pubkey, + keyexpr_info->internal_pubkey.compressed_pubkey, agg_key_tweaked.compressed_pubkey, keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) { PRINTF("Failed yielding MuSig2 pubnonce\n"); @@ -2698,7 +2786,7 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co musig_pubnonce_t pubnonce; if (0 > musig_nonce_gen(rand_i_j, - keyexpr_info->pubkey.compressed_pubkey, + keyexpr_info->internal_pubkey.compressed_pubkey, agg_key_tweaked.compressed_pubkey + 1, &secnonce, &pubnonce)) { @@ -2717,20 +2805,10 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co // derive secret key uint32_t sign_path[MAX_BIP32_PATH_STEPS]; - // TODO: wrong, this should be based on the internal key derivation length for (int i = 0; i < keyexpr_info->key_derivation_length; i++) { sign_path[i] = keyexpr_info->key_derivation[i]; } - sign_path[keyexpr_info->key_derivation_length] = change_step; - sign_path[keyexpr_info->key_derivation_length + 1] = addr_index_step; - - int sign_path_len = keyexpr_info->key_derivation_length + 2; - - // TODO: hardcoded for the current tests. Fix this! - sign_path[0] = 0x80000000 + 44; - sign_path[1] = 0x80000000 + 1; - sign_path[2] = 0x80000000 + 0; - sign_path_len = 3; + int sign_path_len = keyexpr_info->key_derivation_length; if (bip32_derive_init_privkey_256(CX_CURVE_256K1, sign_path, @@ -2770,7 +2848,7 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co st, cur_input_index, psig, - keyexpr_info->pubkey.compressed_pubkey, + keyexpr_info->internal_pubkey.compressed_pubkey, agg_key_tweaked.compressed_pubkey, keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) { PRINTF("Failed yielding MuSig2 partial signature\n"); @@ -3213,8 +3291,9 @@ sign_transaction(dispatcher_context_t *dc, &input, tapleaf_ptr, &keyexpr_info, - sign_psbt_cache)) + sign_psbt_cache)) { return false; + } if (!sign_transaction_input(dc, st, diff --git a/test_utils/musig2.py b/test_utils/musig2.py index fc0ce3544..5f9a98bc1 100644 --- a/test_utils/musig2.py +++ b/test_utils/musig2.py @@ -32,7 +32,7 @@ from test_utils.taproot_sighash import SIGHASH_DEFAULT, TaprootSignatureHash -from . import bip0327, bip0340, sha256 +from . import bip0327, bip0340, hash160, sha256 from . import taproot from bitcoin_client.ledger_bitcoin.embit.descriptor.miniscript import Miniscript @@ -104,9 +104,9 @@ def extract_placeholders(desc_tmpl: str) -> List[KeyPlaceholder]: return [parse_placeholder(match[0]) for match in sorted_matches] -def musig(pubkeys: Iterable[bytes], version_bytes: bytes) -> Tuple[str, bip0327.KeyAggContext]: +def unsorted_musig(pubkeys: Iterable[bytes], version_bytes: bytes) -> Tuple[str, bip0327.KeyAggContext]: """ - Constructs the musig2 aggregated extended public key from a list of + Constructs the musig2 aggregated extended public key from an unsorted list of compressed public keys, and the version bytes. """ @@ -128,6 +128,15 @@ def musig(pubkeys: Iterable[bytes], version_bytes: bytes) -> Tuple[str, bip0327. return base58.b58encode_check(ext_pubkey).decode(), key_agg_ctx +def musig(pubkeys: Iterable[bytes], version_bytes: bytes) -> Tuple[str, bip0327.KeyAggContext]: + """ + Constructs the musig2 aggregated extended public key from a list of compressed public keys, + and the version bytes. The keys are sorted, as required by the `the musig()` key expression + in descriptors. + """ + return unsorted_musig(sorted(pubkeys), version_bytes) + + def aggregate_musig_pubkey(keys_info: Iterable[str]) -> Tuple[str, bip0327.KeyAggContext]: """ Constructs the musig2 aggregated extended public key from the list of keys info @@ -422,12 +431,14 @@ def generate_partial_signatures(self, psbt: PSBT) -> None: def find_change_and_addr_index_for_musig(input_psbt: PartiallySignedInput, placeholder: Musig2KeyPlaceholder, agg_xpub: ExtendedKey): num1, num2 = placeholder.num1, placeholder.num2 + agg_xpub_fingerprint = hash160(agg_xpub.pubkey)[0:4] + # Iterate through tap key origins in the input # TODO: this might be made more precise (e.g. use the leaf_hash from the tap_bip32_paths items) for xonly, (_, key_origin) in input_psbt.tap_bip32_paths.items(): der_path = key_origin.path # Check if the fingerprint matches the expected pattern and the derivation path has the correct structure - if key_origin.fingerprint == b'\x00\x00\x00\x00' and len(der_path) == 2 and der_path[0] < HARDENED_INDEX and der_path[1] < HARDENED_INDEX and (der_path[0] == num1 or der_path[0] == num2): + if key_origin.fingerprint == agg_xpub_fingerprint and len(der_path) == 2 and der_path[0] < HARDENED_INDEX and der_path[1] < HARDENED_INDEX and (der_path[0] == num1 or der_path[0] == num2): if xonly != agg_xpub.derive_pub_path(der_path).pubkey[1:]: continue @@ -684,6 +695,10 @@ def generate_partial_signatures(self, psbt: PSBT) -> None: if my_key_index_in_musig is None: raise ValueError("No internal key found in musig") + # sort the keys in ascending order + pubkeys_in_musig = list( + sorted(pubkeys_in_musig, key=lambda x: x.pubkey)) + nonces: List[bytes] = [] for participant_key in pubkeys_in_musig: participant_pubnonce_identifier = ( @@ -794,6 +809,10 @@ def run_musig2_test(wallet_policy: WalletPolicy, psbt: PSBT, cosigners: List[Psb xpub_i = k_i[k_i.find(']') + 1:] pubkeys_in_musig.append(ExtendedKey.deserialize(xpub_i)) + # sort the keys in ascending order + pubkeys_in_musig = list( + sorted(pubkeys_in_musig, key=lambda x: x.pubkey)) + nonces: List[bytes] = [] for participant_key in pubkeys_in_musig: pubnonce_identifier = ( diff --git a/tests/test_get_wallet_address.py b/tests/test_get_wallet_address.py index 5aae1d5c3..36df27d9a 100644 --- a/tests/test_get_wallet_address.py +++ b/tests/test_get_wallet_address.py @@ -317,7 +317,7 @@ def test_get_wallet_address_tr_musig_keypath(client: RaggerClient): "05b7b4bccd3188effc24de8fd67e83231d8486772800884db0d81bad19f2be3e") res = client.get_wallet_address(wallet, wallet_hmac, 0, 3, False) - assert res == "tb1p7j9azx5xwt5fp3t99wnj4885yfcqynhz645ntflxr9dxr2g8ndnq32xa2m" + assert res == "tb1pc87la0ksvw4pfq6qc3gn9en33kx7s9rx4c4epy578kfjsdjv6mks7u7dgn" def test_get_wallet_address_tr_musig_scriptpath(client: RaggerClient): @@ -335,7 +335,7 @@ def test_get_wallet_address_tr_musig_scriptpath(client: RaggerClient): "b22397b717949ede59c3c9f31c987acda098471211f754b6633c87054c1efb51") res = client.get_wallet_address(wallet, wallet_hmac, 0, 3, False) - assert res == "tb1pmx5syrz67lwdy8dsmvlta5h5ahfn6k9pg8qw3y0jn698xj0duxpq3k94zq" + assert res == "tb1pa423acwcjc8jgt36muavyun8e2hz3t5qwptsr3wr8afmdfk3wchswf9ntp" def test_get_wallet_address_large_addr_index(client: RaggerClient): diff --git a/tests/test_musig2.py b/tests/test_musig2.py index d4c5b8862..2cc80aaba 100644 --- a/tests/test_musig2.py +++ b/tests/test_musig2.py @@ -20,13 +20,13 @@ def test_musig2_hotsigner_keypath(): keys_info=[cosigner_1_xpub, cosigner_2_xpub] ) - psbt_b64 = "cHNidP8BAIACAAAAAWbcwfJ78yV/+Jn0waX9pBWhDp2pZCm0GuTEXe2wXcP2AQAAAAD9////AQAAAAAAAAAARGpCVGhpcyBpbnB1dHMgaGFzIHR3byBwdWJrZXlzIGJ1dCB5b3Ugb25seSBzZWUgb25lLiAjbXBjZ2FuZyByZXZlbmdlAAAAAAABASuf/gQAAAAAACJRIPSL0RqGcuiQxWUrpyqc9CJwAk7i1Wk1p+YZWmGpB5tmIRbGANErPozSP7sjGM7KD11/WcKOe0InwGoEZz9MPQ7Bxg0AAAAAAAAAAAADAAAAAAA=" + psbt_b64 = "cHNidP8BAIACAAAAAdF2HhQ2XCgTpd3Sel7VkS5FvESbwo1rgeuG4tBt9GICAAAAAAD9////AQAAAAAAAAAARGpCVGhpcyBpbnB1dHMgaGFzIHR3byBwdWJrZXlzIGJ1dCB5b3Ugb25seSBzZWUgb25lLiAjbXBjZ2FuZyByZXZlbmdlAAAAAAABASuf/gQAAAAAACJRIMH9/r7QY6oUg0DEUTLmcY2N6BRmriuQkp49kyg2TNbtIRaQZkYWUCCfi7xZsFr10WFcUPX3nBiNe+dC/ZMiUvaPDA0AW4+8kwAAAAADAAAAAAA=" psbt = PSBT() psbt.deserialize(psbt_b64) sighashes = [ bytes.fromhex( - "f3f6d4ae955af42665667ccff4edc9244d9143ada53ba26aee036258e0ffeda9") + "a3aeecb6c236b4a7e72c95fa138250d449b97a75c573f8ab612356279ff64046") ] signer_1 = HotMusig2Cosigner(wallet_policy, cosigner_1_xpriv) @@ -54,13 +54,13 @@ def test_musig2_hotsigner_scriptpath(): ] ) - psbt_b64 = "cHNidP8BAFoCAAAAAeyfHxrwzXffQqF9egw6KMS7RwCLP4rW95dxtXUKYJGFAQAAAAD9////AQAAAAAAAAAAHmocTXVzaWcyLiBOb3cgZXZlbiBpbiBTY3JpcHRzLgAAAAAAAQErOTAAAAAAAAAiUSDZqQIMWvfc0h2w2z6+0vTt0z1YoUHA6JHynopzSe3hgiIVwethFsEeXf/x51pIczoAIsj9RoVePIBTyk/rOMW8B6uIIyDGANErPozSP7sjGM7KD11/WcKOe0InwGoEZz9MPQ7BxqzAIRbGANErPozSP7sjGM7KD11/WcKOe0InwGoEZz9MPQ7Bxi0BkW61VIaT9Qaz/k0SzoZ1UBsjkrXzPqXQbCbBjbNZP/kAAAAAAAAAAAMAAAABFyDrYRbBHl3/8edaSHM6ACLI/UaFXjyAU8pP6zjFvAeriAEYIJFutVSGk/UGs/5NEs6GdVAbI5K18z6l0GwmwY2zWT/5AAA=" + psbt_b64 = "cHNidP8BAFoCAAAAAdOnEESfpXpBe9X59Q4jxz1u9E4Wovn2bkAuuyqUUY0mAAAAAAD9////AQAAAAAAAAAAHmocTXVzaWcyLiBOb3cgZXZlbiBpbiBTY3JpcHRzLgAAAAAAAQErOTAAAAAAAAAiUSDtVR7h2JYPJC463zrCcmfKriiugHBXAcXDP1O2ptF2LyIVwethFsEeXf/x51pIczoAIsj9RoVePIBTyk/rOMW8B6uIIyCQZkYWUCCfi7xZsFr10WFcUPX3nBiNe+dC/ZMiUvaPDKzAIRaQZkYWUCCfi7xZsFr10WFcUPX3nBiNe+dC/ZMiUvaPDC0BuYMCXh1wIlpyBMdMaCFPSwOeOyvhqg+FJ+fOMoWlJsRbj7yTAAAAAAMAAAABFyDrYRbBHl3/8edaSHM6ACLI/UaFXjyAU8pP6zjFvAeriAEYILmDAl4dcCJacgTHTGghT0sDnjsr4aoPhSfnzjKFpSbEAAA=" psbt = PSBT() psbt.deserialize(psbt_b64) sighashes = [ bytes.fromhex( - "ba6d1d859dbc471999fff1fc5b8740fdacadd64a10c8d62de76e39a1c8dcd835") + "28f86cd95c144ed4a877701ae7166867e8805b654c43d9f44da45d7b0070c313") ] signer_1 = HotMusig2Cosigner(wallet_policy, cosigner_1_xpriv) diff --git a/tests/test_sign_psbt_musig.py b/tests/test_sign_psbt_musig.py index 1baf41443..eaff3b320 100644 --- a/tests/test_sign_psbt_musig.py +++ b/tests/test_sign_psbt_musig.py @@ -113,13 +113,13 @@ def test_sign_psbt_musig2_keypath(client: RaggerClient, speculos_globals: Specul wallet_hmac = hmac.new( speculos_globals.wallet_registration_key, wallet_policy.id, sha256).digest() - psbt_b64 = "cHNidP8BAIACAAAAAWbcwfJ78yV/+Jn0waX9pBWhDp2pZCm0GuTEXe2wXcP2AQAAAAD9////AQAAAAAAAAAARGpCVGhpcyBpbnB1dHMgaGFzIHR3byBwdWJrZXlzIGJ1dCB5b3Ugb25seSBzZWUgb25lLiAjbXBjZ2FuZyByZXZlbmdlAAAAAAABASuf/gQAAAAAACJRIPSL0RqGcuiQxWUrpyqc9CJwAk7i1Wk1p+YZWmGpB5tmIRbGANErPozSP7sjGM7KD11/WcKOe0InwGoEZz9MPQ7Bxg0AAAAAAAAAAAADAAAAAAA=" + psbt_b64 = "cHNidP8BAIACAAAAAdF2HhQ2XCgTpd3Sel7VkS5FvESbwo1rgeuG4tBt9GICAAAAAAD9////AQAAAAAAAAAARGpCVGhpcyBpbnB1dHMgaGFzIHR3byBwdWJrZXlzIGJ1dCB5b3Ugb25seSBzZWUgb25lLiAjbXBjZ2FuZyByZXZlbmdlAAAAAAABASuf/gQAAAAAACJRIMH9/r7QY6oUg0DEUTLmcY2N6BRmriuQkp49kyg2TNbtIRaQZkYWUCCfi7xZsFr10WFcUPX3nBiNe+dC/ZMiUvaPDA0AW4+8kwAAAAADAAAAAAA=" psbt = PSBT() psbt.deserialize(psbt_b64) sighashes = [ bytes.fromhex( - "f3f6d4ae955af42665667ccff4edc9244d9143ada53ba26aee036258e0ffeda9") + "a3aeecb6c236b4a7e72c95fa138250d449b97a75c573f8ab612356279ff64046") ] signer_1 = LedgerMusig2Cosigner(client, wallet_policy, wallet_hmac) @@ -147,13 +147,13 @@ def test_sign_psbt_musig2_scriptpath(client: RaggerClient, speculos_globals: Spe wallet_hmac = hmac.new( speculos_globals.wallet_registration_key, wallet_policy.id, sha256).digest() - psbt_b64 = "cHNidP8BAFoCAAAAAeyfHxrwzXffQqF9egw6KMS7RwCLP4rW95dxtXUKYJGFAQAAAAD9////AQAAAAAAAAAAHmocTXVzaWcyLiBOb3cgZXZlbiBpbiBTY3JpcHRzLgAAAAAAAQErOTAAAAAAAAAiUSDZqQIMWvfc0h2w2z6+0vTt0z1YoUHA6JHynopzSe3hgiIVwethFsEeXf/x51pIczoAIsj9RoVePIBTyk/rOMW8B6uIIyDGANErPozSP7sjGM7KD11/WcKOe0InwGoEZz9MPQ7BxqzAIRbGANErPozSP7sjGM7KD11/WcKOe0InwGoEZz9MPQ7Bxi0BkW61VIaT9Qaz/k0SzoZ1UBsjkrXzPqXQbCbBjbNZP/kAAAAAAAAAAAMAAAABFyDrYRbBHl3/8edaSHM6ACLI/UaFXjyAU8pP6zjFvAeriAEYIJFutVSGk/UGs/5NEs6GdVAbI5K18z6l0GwmwY2zWT/5AAA=" + psbt_b64 = "cHNidP8BAFoCAAAAAdOnEESfpXpBe9X59Q4jxz1u9E4Wovn2bkAuuyqUUY0mAAAAAAD9////AQAAAAAAAAAAHmocTXVzaWcyLiBOb3cgZXZlbiBpbiBTY3JpcHRzLgAAAAAAAQErOTAAAAAAAAAiUSDtVR7h2JYPJC463zrCcmfKriiugHBXAcXDP1O2ptF2LyIVwethFsEeXf/x51pIczoAIsj9RoVePIBTyk/rOMW8B6uIIyCQZkYWUCCfi7xZsFr10WFcUPX3nBiNe+dC/ZMiUvaPDKzAIRaQZkYWUCCfi7xZsFr10WFcUPX3nBiNe+dC/ZMiUvaPDC0BuYMCXh1wIlpyBMdMaCFPSwOeOyvhqg+FJ+fOMoWlJsRbj7yTAAAAAAMAAAABFyDrYRbBHl3/8edaSHM6ACLI/UaFXjyAU8pP6zjFvAeriAEYILmDAl4dcCJacgTHTGghT0sDnjsr4aoPhSfnzjKFpSbEAAA=" psbt = PSBT() psbt.deserialize(psbt_b64) sighashes = [ bytes.fromhex( - "ba6d1d859dbc471999fff1fc5b8740fdacadd64a10c8d62de76e39a1c8dcd835") + "28f86cd95c144ed4a877701ae7166867e8805b654c43d9f44da45d7b0070c313") ] signer_1 = LedgerMusig2Cosigner(client, wallet_policy, wallet_hmac) From c15335cdf5386c9baa1bd2fb3d71be4ea3a0b32a Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 15 Jul 2024 17:46:42 +0200 Subject: [PATCH 16/57] Fix psbt-level musig signing session logic --- src/handler/sign_psbt.c | 110 +++++++++++++++++++++++-------------- src/musig/musig_sessions.h | 12 ++++ 2 files changed, 82 insertions(+), 40 deletions(-) diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 1a3946d39..068a90dea 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -135,14 +135,20 @@ typedef struct { uint8_t tapleaf_hash[32]; // only used for tapscripts } keyexpr_info_t; -// Cache for partial hashes during segwit signing (avoid quadratic hashing for segwit transactions) -typedef struct { +// Cache for partial hashes during signing (avoid quadratic hashing for segwit transactions) +typedef struct tx_hashes_s { uint8_t sha_prevouts[32]; uint8_t sha_amounts[32]; uint8_t sha_scriptpubkeys[32]; uint8_t sha_sequences[32]; uint8_t sha_outputs[32]; -} segwit_hashes_t; +} tx_hashes_t; + +// the signing state for the current transaction; it does not contain any per-input state +typedef struct signing_state_s { + tx_hashes_t tx_hashes; + musig_signing_state_t musig; +} signing_state_t; // We cache the first 2 external outputs; that's needed for the swap checks // Moreover, this helps the code for the simplified UX for transactions that @@ -1893,7 +1899,7 @@ static bool __attribute__((noinline)) compute_sighash_legacy(dispatcher_context_ static bool __attribute__((noinline)) compute_sighash_segwitv0(dispatcher_context_t *dc, sign_psbt_state_t *st, - segwit_hashes_t *hashes, + tx_hashes_t *hashes, input_info_t *input, unsigned int cur_input_index, uint8_t sighash[static 32]) { @@ -2078,7 +2084,7 @@ static bool __attribute__((noinline)) compute_sighash_segwitv0(dispatcher_contex static bool __attribute__((noinline)) compute_sighash_segwitv1(dispatcher_context_t *dc, sign_psbt_state_t *st, - segwit_hashes_t *hashes, + tx_hashes_t *hashes, input_info_t *input, unsigned int cur_input_index, keyexpr_info_t *keyexpr_info, @@ -2515,6 +2521,7 @@ static bool yield_musig_partial_signature(dispatcher_context_t *dc, static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_context_t *dc, sign_psbt_state_t *st, + signing_state_t *signing_state, keyexpr_info_t *keyexpr_info, input_info_t *input, unsigned int cur_input_index, @@ -2663,14 +2670,23 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co memcpy(musig_my_psbt_id + 33 + 33, keyexpr_info->tapleaf_hash, 32); } - // compute psbt session id + // The psbt_session_id identifies the musig signing session for the entire (psbt, wallet_policy) + // pair, in both rounds 1 and 2 of the protocol; it is the same for all the musig placeholders + // in the policy (if more than one), and it is the same for all the inputs in the psbt. By + // making the hash depend on both the wallet policy and the transaction hashes, we make sure + // that an accidental collision is impossible, allowing for independent, parallel MuSig2 signing + // sessions for different transactions or wallet policies. + // Malicious collisions are not a concern, as they would only result in a signing failure (since + // the nonces would be incorrectly regenerated during round 2 of MuSig2). uint8_t psbt_session_id[32]; - // TODO: for now we use simply a hash that depends on the keys of the wallet policy; this is not - // good enough. It should be a hash that depends on: - // - the wallet policy id - // - the tx being signed - // - the input index - // - the index of the placeholder we're signing for + crypto_tr_tagged_hash( + (uint8_t[]){'P', 's', 'b', 't', 'S', 'e', 's', 's', 'i', 'o', 'n', 'I', 'd'}, + 13, + st->wallet_header.keys_info_merkle_root, // TODO: wallet policy id would be more precise + 32, + (uint8_t *) &signing_state->tx_hashes, + sizeof(signing_state->tx_hashes), + psbt_session_id); memcpy(psbt_session_id, st->wallet_header.keys_info_merkle_root, sizeof(psbt_session_id)); // 4) check if my pubnonce is in the psbt @@ -2692,15 +2708,14 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co PRINTF("Session with the same id already existing\n"); } - musig_session_t psbt_session; - memcpy(psbt_session.id, psbt_session_id, sizeof(psbt_session_id)); - - // TODO: the "session" should be initialized once for all the (inputs, placeholder) pairs; - // this is wrong! - musigsession_init_randomness(&psbt_session); + if (memcmp(signing_state->musig.round1.id, psbt_session_id, sizeof(psbt_session_id)) != 0) { + // first input/placeholder pair using this session: initialize the session + memcpy(signing_state->musig.round1.id, psbt_session_id, sizeof(psbt_session_id)); + musigsession_init_randomness(&signing_state->musig.round1); + } uint8_t rand_i_j[32]; - compute_rand_i_j(psbt_session.rand_root, + compute_rand_i_j(signing_state->musig.round1.rand_root, cur_input_index, keyexpr_info->cur_index, rand_i_j); @@ -2728,20 +2743,19 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co SEND_SW(dc, SW_BAD_STATE); // should never happen return false; } - - // TODO: wrong if we have multiple inputs! - musigsession_store(psbt_session_id, &psbt_session); } else { // 6) generate and yield partial signature - musig_session_t psbt_session; - // get and delete the musig session from permanent storage - if (!musigsession_pop(psbt_session_id, &psbt_session)) { - // The PSBT contains a partial nonce, but we do not have the corresponding psbt session - // in storage. Either it was deleted, or the pubnonces were not real. Either way, we - // cannot continue. - PRINTF("Missing MuSig2 session\n"); - SEND_SW(dc, SW_BAD_STATE); - return false; + // If the session is not already initialized, we pop it from persistent storage + if (memcmp(signing_state->musig.round2.id, psbt_session_id, sizeof(psbt_session_id)) != 0) { + // get and delete the musig session from permanent storage + if (!musigsession_pop(psbt_session_id, &signing_state->musig.round2)) { + // The PSBT contains a partial nonce, but we do not have the corresponding psbt + // session in storage. Either it was deleted, or the pubnonces were not real. Either + // way, we cannot continue. + PRINTF("Missing MuSig2 session\n"); + SEND_SW(dc, SW_BAD_STATE); + return false; + } } musig_pubnonce_t nonces[MAX_PUBKEYS_PER_MUSIG]; @@ -2777,7 +2791,7 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co // recompute secnonce from psbt_session randomness uint8_t rand_i_j[32]; - compute_rand_i_j(psbt_session.rand_root, + compute_rand_i_j(signing_state->musig.round2.rand_root, cur_input_index, keyexpr_info->cur_index, rand_i_j); @@ -2861,7 +2875,7 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co } static bool __attribute__((noinline)) -compute_segwit_hashes(dispatcher_context_t *dc, sign_psbt_state_t *st, segwit_hashes_t *hashes) { +compute_tx_hashes(dispatcher_context_t *dc, sign_psbt_state_t *st, tx_hashes_t *hashes) { { // compute sha_prevouts and sha_sequences cx_sha256_t sha_prevouts_context, sha_sequences_context; @@ -2990,7 +3004,7 @@ compute_segwit_hashes(dispatcher_context_t *dc, sign_psbt_state_t *st, segwit_ha static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_t *dc, sign_psbt_state_t *st, sign_psbt_cache_t *sign_psbt_cache, - segwit_hashes_t *hashes, + signing_state_t *signing_state, keyexpr_info_t *keyexpr_info, input_info_t *input, unsigned int cur_input_index) { @@ -3103,7 +3117,12 @@ static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_ input->sighash_type = SIGHASH_ALL; } - if (!compute_sighash_segwitv0(dc, st, hashes, input, cur_input_index, sighash)) + if (!compute_sighash_segwitv0(dc, + st, + &signing_state->tx_hashes, + input, + cur_input_index, + sighash)) return false; if (!sign_sighash_ecdsa_and_yield(dc, @@ -3121,7 +3140,7 @@ static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_ if (!compute_sighash_segwitv1(dc, st, - hashes, + &signing_state->tx_hashes, input, cur_input_index, keyexpr_info, @@ -3160,6 +3179,7 @@ static bool __attribute__((noinline)) sign_transaction_input(dispatcher_context_ } else if (keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_MUSIG) { if (!sign_sighash_musig_and_yield(dc, st, + signing_state, keyexpr_info, input, cur_input_index, @@ -3228,13 +3248,13 @@ sign_transaction(dispatcher_context_t *dc, int key_expression_index = 0; - segwit_hashes_t hashes; + signing_state_t signing_state; // compute all the tx-wide hashes // while this is redundant for legacy transactions, we do it here in order to // avoid doing it in places that have more stack limitations - if (!compute_segwit_hashes(dc, st, &hashes)) { - // we do not send a status word, since compute_segwit_hashes already does it on failure + if (!compute_tx_hashes(dc, st, &signing_state.tx_hashes)) { + // we do not send a status word, since compute_tx_hashes already does it on failure return false; } @@ -3298,7 +3318,7 @@ sign_transaction(dispatcher_context_t *dc, if (!sign_transaction_input(dc, st, sign_psbt_cache, - &hashes, + &signing_state, &keyexpr_info, &input, i)) { @@ -3312,6 +3332,16 @@ sign_transaction(dispatcher_context_t *dc, ++key_expression_index; } + // MuSig2: if there is an active session at the end of round 1, we move it to persistent + // storage. It is important that this is only done at the very end of the signing process. + uint8_t acc = 0; + for (size_t i = 0; i < sizeof(signing_state.musig.round1); i++) { + acc |= signing_state.musig.round1.id[i]; + } + if (acc != 0) { + musigsession_store(signing_state.musig.round1.id, &signing_state.musig.round1); + } + return true; } diff --git a/src/musig/musig_sessions.h b/src/musig/musig_sessions.h index b708d6fb9..8236693c9 100644 --- a/src/musig/musig_sessions.h +++ b/src/musig/musig_sessions.h @@ -3,13 +3,25 @@ #include #include "musig.h" +// the maximum number of musig sessions that are stored in permanent memory #define MAX_N_MUSIG_SESSIONS 8 +// TODO: rename to musig_psbt_session_t to avoid confusion with musig_session_context_t typedef struct { uint8_t id[32]; uint8_t rand_root[32]; } musig_session_t; +// volatile state for musig signing +typedef struct musig_signing_state_s { + // a session created during round 1; if signing completes (and in no other case), it is moved to + // the persistent storage + musig_session_t round1; + // a session that was removed from the persistent storage before any partial signature is + // returned during round 2. It is deleted at the end of signing, and must _never_ be used again. + musig_session_t round2; +} musig_signing_state_t; + extern musig_session_t musig_sessions[MAX_N_MUSIG_SESSIONS]; // TODO: docs From b0e02d0fa9b4b87c5c460e145c4b7e59f37dbc67 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 15 Jul 2024 17:54:09 +0200 Subject: [PATCH 17/57] Modularize and extract the musig session handling from sign_psbt.c --- src/handler/sign_psbt.c | 72 ++++++++++++---------------- src/musig/musig_sessions.c | 98 +++++++++++++++++++++++++++++--------- src/musig/musig_sessions.h | 79 ++++++++++++++++++++++++------ 3 files changed, 171 insertions(+), 78 deletions(-) diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 068a90dea..6efecb36d 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -2697,28 +2697,23 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co 1 + psbt_id_len, my_pubnonce.raw, sizeof(musig_pubnonce_t))) { - // 5) generate and yield pubnonce - - // if an existing session for psbt_session_id exists, delete it - if (musigsession_pop(psbt_session_id, NULL)) { - // We wouldn't expect this: probably the client sent the same psbt for - // round 1 twice, without adding the pubnonces to the psbt after the first round. - // We delete the old session and start a fresh one, but we print a - // warning if in debug mode. - PRINTF("Session with the same id already existing\n"); + /** + * Round 1 of the MuSig2 protocol + **/ + + const musig_psbt_session_t *psbt_session = + musigsession_round1_initialize(psbt_session_id, &signing_state->musig); + if (psbt_session == NULL) { + // This should never happen + PRINTF("Unexpected: failed to initialize MuSig2 round 1\n"); + SEND_SW(dc, SW_BAD_STATE); + return false; } - if (memcmp(signing_state->musig.round1.id, psbt_session_id, sizeof(psbt_session_id)) != 0) { - // first input/placeholder pair using this session: initialize the session - memcpy(signing_state->musig.round1.id, psbt_session_id, sizeof(psbt_session_id)); - musigsession_init_randomness(&signing_state->musig.round1); - } + // 5) generate and yield pubnonce uint8_t rand_i_j[32]; - compute_rand_i_j(signing_state->musig.round1.rand_root, - cur_input_index, - keyexpr_info->cur_index, - rand_i_j); + compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->cur_index, rand_i_j); musig_secnonce_t secnonce; musig_pubnonce_t pubnonce; @@ -2744,20 +2739,24 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co return false; } } else { - // 6) generate and yield partial signature - // If the session is not already initialized, we pop it from persistent storage - if (memcmp(signing_state->musig.round2.id, psbt_session_id, sizeof(psbt_session_id)) != 0) { - // get and delete the musig session from permanent storage - if (!musigsession_pop(psbt_session_id, &signing_state->musig.round2)) { - // The PSBT contains a partial nonce, but we do not have the corresponding psbt - // session in storage. Either it was deleted, or the pubnonces were not real. Either - // way, we cannot continue. - PRINTF("Missing MuSig2 session\n"); - SEND_SW(dc, SW_BAD_STATE); - return false; - } + /** + * Round 2 of the MuSig2 protocol + **/ + + const musig_psbt_session_t *psbt_session = + musigsession_round2_initialize(psbt_session_id, &signing_state->musig); + + if (psbt_session == NULL) { + // The PSBT contains a partial nonce, but we do not have the corresponding psbt + // session in storage. Either it was deleted, or the pubnonces were not real. Either + // way, we cannot continue. + PRINTF("Missing MuSig2 session\n"); + SEND_SW(dc, SW_BAD_STATE); + return false; } + // 6) generate and yield partial signature + musig_pubnonce_t nonces[MAX_PUBKEYS_PER_MUSIG]; for (int i = 0; i < musig_info->n; i++) { @@ -2791,10 +2790,7 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co // recompute secnonce from psbt_session randomness uint8_t rand_i_j[32]; - compute_rand_i_j(signing_state->musig.round2.rand_root, - cur_input_index, - keyexpr_info->cur_index, - rand_i_j); + compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->cur_index, rand_i_j); musig_secnonce_t secnonce; musig_pubnonce_t pubnonce; @@ -3334,13 +3330,7 @@ sign_transaction(dispatcher_context_t *dc, // MuSig2: if there is an active session at the end of round 1, we move it to persistent // storage. It is important that this is only done at the very end of the signing process. - uint8_t acc = 0; - for (size_t i = 0; i < sizeof(signing_state.musig.round1); i++) { - acc |= signing_state.musig.round1.id[i]; - } - if (acc != 0) { - musigsession_store(signing_state.musig.round1.id, &signing_state.musig.round1); - } + musigsession_commit(&signing_state.musig); return true; } diff --git a/src/musig/musig_sessions.c b/src/musig/musig_sessions.c index 4d38117b7..be8e714fe 100644 --- a/src/musig/musig_sessions.c +++ b/src/musig/musig_sessions.c @@ -6,20 +6,7 @@ #include "../crypto.h" // TODO: persist in NVRAM instead -musig_session_t musig_sessions[MAX_N_MUSIG_SESSIONS]; - -bool musigsession_pop(uint8_t psbt_session_id[static 32], musig_session_t *out) { - for (int i = 0; i < MAX_N_MUSIG_SESSIONS; i++) { - if (memcmp(psbt_session_id, musig_sessions[i].id, 32) == 0) { - if (out != NULL) { - memcpy(out, &musig_sessions[i], sizeof(musig_session_t)); - } - explicit_bzero(&musig_sessions[i], sizeof(musig_session_t)); - return true; - } - } - return false; -} +musig_psbt_session_t musig_sessions[MAX_N_MUSIG_SESSIONS]; static bool is_all_zeros(const uint8_t *array, size_t size) { for (size_t i = 0; i < size; ++i) { @@ -30,35 +17,100 @@ static bool is_all_zeros(const uint8_t *array, size_t size) { return true; } -void musigsession_init_randomness(musig_session_t *session) { - cx_get_random_bytes(session->rand_root, 32); +static bool musigsession_pop(const uint8_t psbt_session_id[static 32], musig_psbt_session_t *out) { + for (int i = 0; i < MAX_N_MUSIG_SESSIONS; i++) { + if (memcmp(psbt_session_id, musig_sessions[i]._id, 32) == 0) { + if (out != NULL) { + memcpy(out, &musig_sessions[i], sizeof(musig_psbt_session_t)); + } + explicit_bzero(&musig_sessions[i], sizeof(musig_psbt_session_t)); + return true; + } + } + return false; } -void musigsession_store(uint8_t psbt_session_id[static 32], const musig_session_t *session) { +static void musigsession_init_randomness(musig_psbt_session_t *session) { + cx_get_random_bytes(session->_rand_root, 32); +} + +static void musigsession_store(const uint8_t psbt_session_id[static 32], + const musig_psbt_session_t *session) { // make sure that no session with the same id exists; delete it otherwise musigsession_pop(psbt_session_id, NULL); int i; for (i = 0; i < MAX_N_MUSIG_SESSIONS; i++) { - if (is_all_zeros((uint8_t *) &musig_sessions[i], sizeof(musig_session_t))) { + if (is_all_zeros((uint8_t *) &musig_sessions[i], sizeof(musig_psbt_session_t))) { break; } } if (i >= MAX_N_MUSIG_SESSIONS) { // no free slot found, delete the first by default - // TODO: should we use a LIFO structure? Could add a counter to musig_session_t + // TODO: should we use a LIFO structure? Could add a counter to musig_psbt_session_t i = 0; } // no free slot; replace the first slot - explicit_bzero(&musig_sessions[i], sizeof(musig_session_t)); - memcpy(&musig_sessions[i], session, sizeof(musig_session_t)); + explicit_bzero(&musig_sessions[i], sizeof(musig_psbt_session_t)); + memcpy(&musig_sessions[i], session, sizeof(musig_psbt_session_t)); } -void compute_rand_i_j(const uint8_t rand_root[static 32], int i, int j, uint8_t out[static 32]) { +void compute_rand_i_j(const musig_psbt_session_t *psbt_session, + int i, + int j, + uint8_t out[static 32]) { cx_sha256_t hash_context; cx_sha256_init(&hash_context); - crypto_hash_update(&hash_context.header, rand_root, CX_SHA256_SIZE); + crypto_hash_update(&hash_context.header, psbt_session->_rand_root, CX_SHA256_SIZE); crypto_hash_update_u32(&hash_context.header, (uint32_t) i); crypto_hash_update_u32(&hash_context.header, (uint32_t) j); crypto_hash_digest(&hash_context.header, out, 32); } + +const musig_psbt_session_t *musigsession_round1_initialize( + uint8_t psbt_session_id[static 32], + musig_signing_state_t *musig_signing_state) { + // if an existing session for psbt_session_id exists, delete it + if (musigsession_pop(psbt_session_id, NULL)) { + // We wouldn't expect this: probably the client sent the same psbt for + // round 1 twice, without adding the pubnonces to the psbt after the first round. + // We delete the old session and start a fresh one, but we print a + // warning if in debug mode. + PRINTF("Session with the same id already existing\n"); + } + + if (memcmp(musig_signing_state->_round1._id, psbt_session_id, 32) != 0) { + // first input/placeholder pair using this session: initialize the session + memcpy(musig_signing_state->_round1._id, psbt_session_id, 32); + musigsession_init_randomness(&musig_signing_state->_round1); + } + + return &musig_signing_state->_round1; +} + +const musig_psbt_session_t *musigsession_round2_initialize( + uint8_t psbt_session_id[static 32], + musig_signing_state_t *musig_signing_state) { + if (memcmp(musig_signing_state->_round2._id, psbt_session_id, 32) != 0) { + // get and delete the musig session from permanent storage + if (!musigsession_pop(psbt_session_id, &musig_signing_state->_round2)) { + // The PSBT contains a partial nonce, but we do not have the corresponding psbt + // session in storage. Either it was deleted, or the pubnonces were not real. Either + // way, we cannot continue. + PRINTF("Missing MuSig2 session\n"); + return NULL; + } + } + + return &musig_signing_state->_round2; +} + +void musigsession_commit(musig_signing_state_t *musig_signing_state) { + uint8_t acc = 0; + for (size_t i = 0; i < sizeof(musig_signing_state->_round1); i++) { + acc |= musig_signing_state->_round1._id[i]; + } + if (acc != 0) { + musigsession_store(musig_signing_state->_round1._id, &musig_signing_state->_round1); + } +} diff --git a/src/musig/musig_sessions.h b/src/musig/musig_sessions.h index 8236693c9..0ef41cb0e 100644 --- a/src/musig/musig_sessions.h +++ b/src/musig/musig_sessions.h @@ -6,27 +6,78 @@ // the maximum number of musig sessions that are stored in permanent memory #define MAX_N_MUSIG_SESSIONS 8 -// TODO: rename to musig_psbt_session_t to avoid confusion with musig_session_context_t -typedef struct { - uint8_t id[32]; - uint8_t rand_root[32]; -} musig_session_t; +// state of a musig_psbt_session. Members are private and must not be accessed directly by any +// code outside of musig_sessions.c. +typedef struct musig_psbt_session_s { + uint8_t _id[32]; + uint8_t _rand_root[32]; +} musig_psbt_session_t; -// volatile state for musig signing +// volatile state for musig signing. Members are private and must not be accessed directly by any +// code outside of musig_sessions.c. typedef struct musig_signing_state_s { // a session created during round 1; if signing completes (and in no other case), it is moved to // the persistent storage - musig_session_t round1; + musig_psbt_session_t _round1; // a session that was removed from the persistent storage before any partial signature is // returned during round 2. It is deleted at the end of signing, and must _never_ be used again. - musig_session_t round2; + musig_psbt_session_t _round2; } musig_signing_state_t; -extern musig_session_t musig_sessions[MAX_N_MUSIG_SESSIONS]; +/** + * Given a musig psbt session, computes the synthetic randomness for a given + * (input_index, placeholder_index) pair. + */ +void compute_rand_i_j(const musig_psbt_session_t *psbt_session, + int input_index, + int placeholder_index, + uint8_t out[static 32]); -// TODO: docs -bool musigsession_pop(uint8_t psbt_session_id[static 32], musig_session_t *out); -void musigsession_init_randomness(musig_session_t *session); -void musigsession_store(uint8_t psbt_session_id[static 32], const musig_session_t *session); +/** + * Handles the creation of a new musig psbt session into the volatile memory, or its retrieval (if + * the session already exists). + * It must be called when starting MuSig2 round 1 for a fixed input/placeholder pair, during the + * signing process. + * + * @param[in] psbt_session_id + * Pointer to the musig psbt session id. + * @param[in] musig_signing_state + * Pointer to the musig signing state. + * + * @return a musig_psbt_session_t on success, NULL on failure. + */ +__attribute__((warn_unused_result)) const musig_psbt_session_t *musigsession_round1_initialize( + uint8_t psbt_session_id[static 32], + musig_signing_state_t *musig_signing_state); -void compute_rand_i_j(const uint8_t rand_root[static 32], int i, int j, uint8_t out[static 32]); +/** + * Handles the retrieval of a musig psbt session from volatile memory (if it exists already) or its + * retrieval from the persistent memory otherwise. The session is guaranteed to be deleted from the + * persistent memory prior to returning. + * It must be called when starting MuSig2 round 2 for a fixed input/placeholder pair, during the + * signing process. + * + * @param[in] psbt_session_id + * Pointer to the musig psbt session id. + * @param[in] musig_signing_state + * Pointer to the musig signing state. + * + * @return a musig_psbt_session_t on success, NULL on failure. + */ +__attribute__((warn_unused_result)) const musig_psbt_session_t *musigsession_round2_initialize( + uint8_t psbt_session_id[static 32], + musig_signing_state_t *musig_signing_state); + +/** + * If a session produced in round 1 is active in volatile memory, it is stored in the persistent + * memory. + * This must be called at the end of a successful signing flow, after all the public nonces have + * been returned to the client. It must _not_ be called if any error occurs, or if the signing + * process is aborted for any reason. + * + * @param[in] psbt_session_id + * Pointer to the musig psbt session id. + * @param[in] musig_signing_state + * Pointer to the musig signing state. + */ +void musigsession_commit(musig_signing_state_t *musig_signing_state); From 1b3061b69a46d3047a04e098bb2b01b56aa733b9 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Thu, 30 May 2024 17:32:14 +0200 Subject: [PATCH 18/57] Persistent storage for musig psbt signing sessions --- src/musig/musig_sessions.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/musig/musig_sessions.c b/src/musig/musig_sessions.c index be8e714fe..174e111b3 100644 --- a/src/musig/musig_sessions.c +++ b/src/musig/musig_sessions.c @@ -5,8 +5,15 @@ #include "musig_sessions.h" #include "../crypto.h" -// TODO: persist in NVRAM instead -musig_psbt_session_t musig_sessions[MAX_N_MUSIG_SESSIONS]; +typedef struct { + // Aligning by 4 is necessary due to platform limitations. + // Aligning by 64 further guarantees that each session occupies exactly + // a single NVRAM page, minimizing the number of writes. + __attribute__((aligned(64))) musig_psbt_session_t sessions[MAX_N_MUSIG_SESSIONS]; +} musig_persistent_storage_t; + +const musig_persistent_storage_t N_musig_storage_real; +#define N_musig_storage (*(const volatile musig_persistent_storage_t *) PIC(&N_musig_storage_real)) static bool is_all_zeros(const uint8_t *array, size_t size) { for (size_t i = 0; i < size; ++i) { @@ -19,11 +26,17 @@ static bool is_all_zeros(const uint8_t *array, size_t size) { static bool musigsession_pop(const uint8_t psbt_session_id[static 32], musig_psbt_session_t *out) { for (int i = 0; i < MAX_N_MUSIG_SESSIONS; i++) { - if (memcmp(psbt_session_id, musig_sessions[i]._id, 32) == 0) { + if (memcmp(psbt_session_id, (const void *) N_musig_storage.sessions[i]._id, 32) == 0) { if (out != NULL) { - memcpy(out, &musig_sessions[i], sizeof(musig_psbt_session_t)); + memcpy(out, + (const void *) &N_musig_storage.sessions[i], + sizeof(musig_psbt_session_t)); } - explicit_bzero(&musig_sessions[i], sizeof(musig_psbt_session_t)); + uint8_t zeros[sizeof(musig_psbt_session_t)] = {0}; + nvm_write((void *) &N_musig_storage.sessions[i], + (void *) zeros, + sizeof(musig_psbt_session_t)); + return true; } } @@ -31,6 +44,8 @@ static bool musigsession_pop(const uint8_t psbt_session_id[static 32], musig_psb } static void musigsession_init_randomness(musig_psbt_session_t *session) { + // it is extremely important that the randomness is initialized with a cryptographically strong + // random number generator cx_get_random_bytes(session->_rand_root, 32); } @@ -41,7 +56,7 @@ static void musigsession_store(const uint8_t psbt_session_id[static 32], int i; for (i = 0; i < MAX_N_MUSIG_SESSIONS; i++) { - if (is_all_zeros((uint8_t *) &musig_sessions[i], sizeof(musig_psbt_session_t))) { + if (is_all_zeros((uint8_t *) &N_musig_storage.sessions[i], sizeof(musig_psbt_session_t))) { break; } } @@ -50,9 +65,10 @@ static void musigsession_store(const uint8_t psbt_session_id[static 32], // TODO: should we use a LIFO structure? Could add a counter to musig_psbt_session_t i = 0; } - // no free slot; replace the first slot - explicit_bzero(&musig_sessions[i], sizeof(musig_psbt_session_t)); - memcpy(&musig_sessions[i], session, sizeof(musig_psbt_session_t)); + // replace the chosen slot + nvm_write((void *) &N_musig_storage.sessions[i], + (void *) session, + sizeof(musig_psbt_session_t)); } void compute_rand_i_j(const musig_psbt_session_t *psbt_session, From 27c95dcfe064a1521bf0933597388a32bef6f807 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Fri, 31 May 2024 14:17:53 +0200 Subject: [PATCH 19/57] Add ragger navigation to musig sign_psbt tests --- tests/test_sign_psbt_musig.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/tests/test_sign_psbt_musig.py b/tests/test_sign_psbt_musig.py index eaff3b320..bde7ac2a7 100644 --- a/tests/test_sign_psbt_musig.py +++ b/tests/test_sign_psbt_musig.py @@ -3,6 +3,7 @@ from hashlib import sha256 import hmac +from typing import Optional from ledger_bitcoin.client_base import Client, MusigPartialSignature, MusigPubNonce @@ -26,13 +27,18 @@ class LedgerMusig2Cosigner(PsbtMusig2Cosigner): Implements a PsbtMusig2Cosigner that uses a BitcoinClient """ - def __init__(self, client: Client, wallet_policy: WalletPolicy, wallet_hmac: bytes) -> None: + def __init__(self, client: Client, wallet_policy: WalletPolicy, wallet_hmac: bytes, *, navigator: Optional[Navigator] = None, + testname: str = "", instructions: Instructions = None) -> None: super().__init__() self.client = client self.wallet_policy = wallet_policy self.wallet_hmac = wallet_hmac + self.navigator = navigator + self.testname = testname + self.instructions = instructions + self.fingerprint = client.get_master_fingerprint() desc_tmpl = TrDescriptorTemplate.from_string( @@ -61,7 +67,8 @@ def get_participant_pubkey(self) -> bip0327.Point: def generate_public_nonces(self, psbt: PSBT) -> None: print("PSBT before nonce generation:", psbt.serialize()) - res = self.client.sign_psbt(psbt, self.wallet_policy, self.wallet_hmac) + res = self.client.sign_psbt( + psbt, self.wallet_policy, self.wallet_hmac, navigator=self.navigator, testname=self.testname, instructions=self.instructions) print("Pubnonces:", res) for (input_index, yielded) in res: if isinstance(yielded, MusigPubNonce): @@ -80,7 +87,8 @@ def generate_public_nonces(self, psbt: PSBT) -> None: def generate_partial_signatures(self, psbt: PSBT) -> None: print("PSBT before partial signature generation:", psbt.serialize()) - res = self.client.sign_psbt(psbt, self.wallet_policy, self.wallet_hmac) + res = self.client.sign_psbt( + psbt, self.wallet_policy, self.wallet_hmac, navigator=self.navigator, testname=self.testname, instructions=self.instructions) print("Ledger result of second round:", res) for (input_index, yielded) in res: if isinstance(yielded, MusigPartialSignature): @@ -99,7 +107,7 @@ def generate_partial_signatures(self, psbt: PSBT) -> None: raise ValueError("Expected partial signatures, got a pubnonce") -def test_sign_psbt_musig2_keypath(client: RaggerClient, speculos_globals: SpeculosGlobals): +def test_sign_psbt_musig2_keypath(navigator: Navigator, firmware: Firmware, client: RaggerClient, test_name: str, speculos_globals: SpeculosGlobals): cosigner_1_xpub = "[f5acc2fd/44'/1'/0']tpubDCwYjpDhUdPGP5rS3wgNg13mTrrjBuG8V9VpWbyptX6TRPbNoZVXsoVUSkCjmQ8jJycjuDKBb9eataSymXakTTaGifxR6kmVsfFehH1ZgJT" cosigner_2_xpriv = "tprv8gFWbQBTLFhbX3EK3cS7LmenwE3JjXbD9kN9yXfq7LcBm81RSf8vPGPqGPjZSeX41LX9ZN14St3z8YxW48aq5Yhr9pQZVAyuBthfi6quTCf" @@ -122,13 +130,14 @@ def test_sign_psbt_musig2_keypath(client: RaggerClient, speculos_globals: Specul "a3aeecb6c236b4a7e72c95fa138250d449b97a75c573f8ab612356279ff64046") ] - signer_1 = LedgerMusig2Cosigner(client, wallet_policy, wallet_hmac) + signer_1 = LedgerMusig2Cosigner(client, wallet_policy, wallet_hmac, + navigator=navigator, instructions=sign_psbt_instruction_approve(firmware, save_screenshot=False, has_spend_from_wallet=True, has_feewarning=True), testname=test_name) signer_2 = HotMusig2Cosigner(wallet_policy, cosigner_2_xpriv) run_musig2_test(wallet_policy, psbt, [signer_1, signer_2], sighashes) -def test_sign_psbt_musig2_scriptpath(client: RaggerClient, speculos_globals: SpeculosGlobals): +def test_sign_psbt_musig2_scriptpath(navigator: Navigator, firmware: Firmware, client: RaggerClient, test_name: str, speculos_globals: SpeculosGlobals): cosigner_1_xpub = "[f5acc2fd/44'/1'/0']tpubDCwYjpDhUdPGP5rS3wgNg13mTrrjBuG8V9VpWbyptX6TRPbNoZVXsoVUSkCjmQ8jJycjuDKBb9eataSymXakTTaGifxR6kmVsfFehH1ZgJT" cosigner_2_xpriv = "tprv8gFWbQBTLFhbX3EK3cS7LmenwE3JjXbD9kN9yXfq7LcBm81RSf8vPGPqGPjZSeX41LX9ZN14St3z8YxW48aq5Yhr9pQZVAyuBthfi6quTCf" @@ -156,7 +165,8 @@ def test_sign_psbt_musig2_scriptpath(client: RaggerClient, speculos_globals: Spe "28f86cd95c144ed4a877701ae7166867e8805b654c43d9f44da45d7b0070c313") ] - signer_1 = LedgerMusig2Cosigner(client, wallet_policy, wallet_hmac) + signer_1 = LedgerMusig2Cosigner(client, wallet_policy, wallet_hmac, + navigator=navigator, instructions=sign_psbt_instruction_approve(firmware, save_screenshot=False, has_spend_from_wallet=True), testname=test_name) signer_2 = HotMusig2Cosigner(wallet_policy, cosigner_2_xpriv) run_musig2_test(wallet_policy, psbt, [signer_1, signer_2], sighashes) From 16261f546215010da8fe2266119bc5608ceee67e Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 15 Jul 2024 18:03:05 +0200 Subject: [PATCH 20/57] Update sanity checks for musig key expressions --- src/handler/lib/policy.c | 89 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index ea9b66201..3ea11a5d4 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -1897,6 +1897,19 @@ static int is_taptree_miniscript_sane(const policy_node_tree_t *taptree) { return 0; } +// sort an array of uint16_t in place using bubble sort +static void sort_uint16_array(uint16_t *array, size_t n) { + for (size_t i = 0; i < n; i++) { + for (size_t j = i + 1; j < n; j++) { + if (array[i] > array[j]) { + uint16_t tmp = array[i]; + array[i] = array[j]; + array[j] = tmp; + } + } + } +} + int is_policy_sane(dispatcher_context_t *dispatcher_context, const policy_node_t *policy, int wallet_version, @@ -1961,7 +1974,30 @@ int is_policy_sane(dispatcher_context_t *dispatcher_context, return WITH_ERROR(-1, "Unexpected error while counting key expressions"); } - // The following loop computationally very inefficient (quadratic in the number of + // for each MuSig key expression, checks that the key indices are all distinct + for (int i = 0; i < n_key_expressions; i++) { + policy_node_keyexpr_t *kp_i; + if (0 > get_keyexpr_by_index(policy, i, NULL, &kp_i)) { + return WITH_ERROR(-1, "Unexpected error retrieving key expressions from the policy"); + } + if (kp_i->type == KEY_EXPRESSION_MUSIG) { + musig_aggr_key_info_t *musig_info_i = r_musig_aggr_key_info(&kp_i->m.musig_info); + uint16_t *key_indexes_i = r_uint16(&musig_info_i->key_indexes); + + uint16_t key_indexes_i_sorted[MAX_PUBKEYS_PER_MUSIG]; + memcpy(key_indexes_i_sorted, key_indexes_i, musig_info_i->n * sizeof(uint16_t)); + + // sort the arrays + sort_uint16_array(key_indexes_i_sorted, musig_info_i->n); + for (int j = 0; j < musig_info_i->n - 1; j++) { + if (key_indexes_i_sorted[j] == key_indexes_i_sorted[j + 1]) { + return WITH_ERROR(-1, "Repeated key in musig key expression"); + } + } + } + } + + // The following loop is computationally very inefficient (quadratic in the number of // key expressions), but more efficient solutions likely require a substantial amount of RAM // (proportional to the number of key expressions). Instead, this only requires stack depth // proportional to the depth of the wallet policy's abstract syntax tree. @@ -1978,13 +2014,60 @@ int is_policy_sane(dispatcher_context_t *dispatcher_context, "Unexpected error retrieving key expressions from the policy"); } - // key expressions for the same key must have disjoint derivation options - if (kp_i->k.key_index == kp_j->k.key_index) { + if ((kp_i->type == KEY_EXPRESSION_NORMAL && kp_j->type == KEY_EXPRESSION_MUSIG) || + (kp_i->type == KEY_EXPRESSION_MUSIG && kp_j->type == KEY_EXPRESSION_NORMAL)) { + // if one is a key and the other is a musig, there's nothing else to check + continue; + } else if (kp_i->type == KEY_EXPRESSION_NORMAL && kp_j->type == KEY_EXPRESSION_NORMAL) { + // key expressions for the same key must have disjoint derivation options + if (kp_i->k.key_index == kp_j->k.key_index) { + if (kp_i->num_first == kp_j->num_first || kp_i->num_first == kp_j->num_second || + kp_i->num_second == kp_j->num_first || + kp_i->num_second == kp_j->num_second) { + return WITH_ERROR( + -1, + "Key expressions with repeated derivations in miniscript"); + } + } + } else if (kp_i->type == KEY_EXPRESSION_MUSIG && kp_j->type == KEY_EXPRESSION_MUSIG) { + musig_aggr_key_info_t *musig_info_i = r_musig_aggr_key_info(&kp_i->m.musig_info); + uint16_t *key_indexes_i = r_uint16(&musig_info_i->key_indexes); + musig_aggr_key_info_t *musig_info_j = r_musig_aggr_key_info(&kp_j->m.musig_info); + uint16_t *key_indexes_j = r_uint16(&musig_info_j->key_indexes); + // if two musigs have exactly the same set of keys, then the derivation options must + // be disjoint + + // make sure that there is no repeated key in the first musig + + if (musig_info_i->n != musig_info_j->n) { + continue; // cannot be the same set if the size is different + } + + uint16_t key_indexes_i_sorted[MAX_PUBKEYS_PER_MUSIG]; + uint16_t key_indexes_j_sorted[MAX_PUBKEYS_PER_MUSIG]; + memcpy(key_indexes_i_sorted, key_indexes_i, musig_info_i->n * sizeof(uint16_t)); + memcpy(key_indexes_j_sorted, key_indexes_j, musig_info_j->n * sizeof(uint16_t)); + + // sort the arrays + sort_uint16_array(key_indexes_i_sorted, musig_info_i->n); + sort_uint16_array(key_indexes_j_sorted, musig_info_j->n); + + if (memcmp(key_indexes_i_sorted, + key_indexes_j_sorted, + musig_info_i->n * sizeof(uint16_t)) != 0) { + continue; // different set of keys + } + + // same set of keys; therefore, we need to check that the derivation options are + // disjoint if (kp_i->num_first == kp_j->num_first || kp_i->num_first == kp_j->num_second || kp_i->num_second == kp_j->num_first || kp_i->num_second == kp_j->num_second) { return WITH_ERROR(-1, "Key expressions with repeated derivations in miniscript"); } + + } else { + LEDGER_ASSERT(false, "Unexpected key expression type"); } } } From 5b51ab8ce24d815c2075fd1358b37958bdb7e0e7 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:05:48 +0200 Subject: [PATCH 21/57] Add architecture docs for MuSig2 --- doc/musig.md | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 doc/musig.md diff --git a/doc/musig.md b/doc/musig.md new file mode 100644 index 000000000..f3356aa89 --- /dev/null +++ b/doc/musig.md @@ -0,0 +1,87 @@ +# MuSig2 + +The Ledger Bitcoin app supports wallet policies with `musig()` key expressions. + +MuSig2 is a 2-round multi-signature scheme compatible with the public keys and signatures used in taproot transactions. The implementation is compliant with [BIP-0327](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki). + +## Specs + +`musig()` key expressions are supported for all taproot policies, including taproot keypaths and miniscript. + +- At most 16 keys are allowed in the musig expression; performance limitations, however, might apply in practice. +- At most 8 parallel MuSig signing sessions are supported, due to the need to persist state in the device's memory. +- Only `musig(...)/**` or `musig(...)//*` key expressions are supported; the public keys must be xpubs aggregated without any further derivation. Schemes where each pubkey is derived prior to aggregation (for example descriptors similar to `musig(xpub1/<0;1>/*,xpub2/<0;1>/*,...)`) are not supported. + +## State minimization + +This section describes implementation details that allow to minimize the amount of statefor each MuSig2 signing session, allowing secure support for multiple parallel MuSig2 on embedded device with limited storage. + +### Introduction + +BIP-0327 discusses at length the necessity to keep some state during a signing session. However, a "signing session" in BIP-0327 only refers to the production of a single signature. + +In the typical signing flow of a wallet, it's more logical to consider a _session_ at the level of an entire transaction. All transaction inputs are likely obtained from the same [descriptor containing musig()](https://github.com/bitcoin/bips/pull/1540), with the signer producing the pubnonce/signature for all the inputs at once. + +Therefore, in the flow of BIP-0327, you would expect at least _one MuSig2 signing session per input_ to be active at the same time. In the context of hardware signing device support, that's somewhat problematic: it would require to persist state for an unbounded number of signing sessions, for example for a wallet that received a large number of small UTXOs. Persistent storage is often a scarce resource in embedded signing devices, and a naive approach would likely impose a maximum limit on the number of inputs of the transactions, depending on the hardware limitations. + +This document describes an approach that is compatible with and builds on top of BIP-0327 to define a _psbt-level session_ with only a small amount of state persisted on the device. Each psbt-level session allows to manage in parallel all the MuSig2 sessions involved in signing a transaction (typically, at least one for each input). Each psbt-level session only requires 64 bytes of storage for the entire transaction, regardless of the amount of inputs. + +### Signing flow with synthetic randomness + +#### Synthetic generation of BIP-0327 state + +This section presents the core idea, while the next section makes it more precise in the context of signing devices. + +In BIP-0327, the internal state that is kept by the signing device is essentially the *secnonce*, which in turn is computed from a random number _rand'_, and optionally from other parameters of _NonceGen_ which depend on the transaction being signed. + +The core idea for state minimization is to compute a global random `rand_root`; then, for the *i*-th input and for the *j*-th `musig()` key that the device is signing for in the [wallet policy](https://github.com/bitcoin/bips/pull/1389), one defines the *rand'* in _NonceGen_ as: + +$\qquad rand_{i,j} = SHA256(rand\_root || i || j)$ + +In the concatenation, a fixed-length encoding of $i$ and $j$ is used in order to avoid collisions. That is used as the *rand'* value in the *NonceGen* algorithm for that input/KEY pair. + +The *j* parameter allows to handle wallet policies that contain more than one `musig()` key expression involving the signing device. + +#### Signing flow in detail + +This section describes the handling of the psbt-level sessions, plugging on top of the default signing flow of BIP-0327. + +We assume that the signing device handles a single psbt-level session; this can be generalized to multiple parallel psbt-level sessions, where each session computes and stores a different `rand_root`. + +In the following, a _session_ always refers to the psbt-level signing session; it contains `rand_root`, and possibly any other auxiliary data that the device wishes to save while signing is in progress. + +The term *persistent memory* refers to secure storage that is not wiped out when the device is turned off. The term *volatile memory* refers to the working memory available while the device is involved in the signing process. In Ledger signing devices, the persistent storage is flash memory, and the volatile memory is the RAM of the app. Both are contained in the Secure Element. + +**Phase 1: pubnonce generation:** A PSBT is sent to the signing device, and it does not contain any pubnonce. +- If a session already exists, it is deleted from the persistent memory. +- A new session is created in volatile memory. +- The device produces a fresh random number $rand\_root$, and saves it in the current session. +- The device generates the randomness for the $i$-th input and for the $j$-th key as: $rand_{i,j} = SHA256(rand\_root || i || j)$. +- Compute each *(secnonce, pubnonce)* as per the `NonceGen` algorithm. +- At completion (after all the pubnonces are returned), the session secret $rand\_root$ is copied into the persistent memory. + +**Phase 2: partial signature generation:** A PSBT containing all the pubnonces is sent to the device. +- *A copy of the session is stored in the volatile memory, and the session is deleted from the persistent memory*. +- For each input/musig-key pair $(i, j)$: + - Recompute the pubnonce/secnonce pair using `NonceGen` with the synthetic randomness $rand_{i,j}$ as above. + - Verify that the pubnonce contained in the PSBT matches the one synthetically recomputed. + - Continue the signing flow as per BIP-0327, generating the partial signature. + +### Security considerations +#### State reuse avoidance +Storing the session in persistent memory only at the end of Phase 1, and deleting it before beginning Phase 2 simplifies auditing and making sure that there is no reuse of state across signing sessions. + +#### Security of synthetic randomness + +Generating $rand_{i, j}$ synthetically is not a problem, since the $rand\_root$ value is kept secret and never leaves the device. This ensures that all the values produced for different $i$ and $j$ not predictable for an attacker. + +#### Malleability of the PSBT +If the optional parameters are passed to the _NonceGen_ function, they will depend on the transaction data present in the PSBT. Therefore, there is no guarantee that they will be unchanged the next time the PSBT is provided. + +However, that does not constitute a security risk, as those parameters are only used as additional sources of entropy in _NonceGen_. A malicious software wallet can't affect the _secnonce_/_pubnonce_ pairs in any predictable way. Changing any of the parameters used in _NonceGen_ would cause a failure during Phase 2, as the recomputed _pubnonce_ would not match the one in the psbt. + +### Generalization to multiple PSBT signing sessions + +The approach described above assumes that no attempt to sign a PSBT containing for a wallet policy containing `musig()` keys is initiated while a session is already in progress. + +It is possible to generalize this to an arbitrary number of parallel signing sessions. Each session could be identified by a `psbt_session_id` computed by hashing together the transaction hashes, \ No newline at end of file From 3418b6041ee8653c09baeb5d3494b28dc3588500 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:07:36 +0200 Subject: [PATCH 22/57] Reference musig docs in musig session module --- src/musig/musig_sessions.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/musig/musig_sessions.h b/src/musig/musig_sessions.h index 0ef41cb0e..0cda21301 100644 --- a/src/musig/musig_sessions.h +++ b/src/musig/musig_sessions.h @@ -3,6 +3,11 @@ #include #include "musig.h" +/** + * This module encapsulates the logic to manage the psbt-level MuSig2 sessions. See the + * documentation in docs/musig.md for more information. + */ + // the maximum number of musig sessions that are stored in permanent memory #define MAX_N_MUSIG_SESSIONS 8 From 8e131012cf732a49c4aa9cdd6dfe97e1b83a2d5f Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:10:25 +0200 Subject: [PATCH 23/57] Add const qualifiers, and asserts guarding against overflows --- src/handler/lib/policy.c | 22 ++++++++++-------- src/handler/sign_psbt.c | 49 +++++++++++++++++++++++----------------- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index 3ea11a5d4..a1285f4c9 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -468,8 +468,8 @@ __attribute__((warn_unused_result)) static int get_derived_pubkey( return -1; } } else if (key_expr->type == KEY_EXPRESSION_MUSIG) { - musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); - uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); + const musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); + const uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); plain_pk_t keys[MAX_PUBKEYS_PER_MUSIG]; for (int i = 0; i < musig_info->n; i++) { // we use ext_pubkey as a temporary variable; will overwrite later @@ -1772,9 +1772,9 @@ int count_distinct_keys_info(const policy_node_t *policy) { if (key_expression_ptr->type == KEY_EXPRESSION_NORMAL) { ret = MAX(ret, key_expression_ptr->k.key_index + 1); } else if (key_expression_ptr->type == KEY_EXPRESSION_MUSIG) { - musig_aggr_key_info_t *musig_info = + const musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expression_ptr->m.musig_info); - uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); + const uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); for (int i = 0; i < musig_info->n; i++) { ret = MAX(ret, key_indexes[i] + 1); } @@ -1981,8 +1981,8 @@ int is_policy_sane(dispatcher_context_t *dispatcher_context, return WITH_ERROR(-1, "Unexpected error retrieving key expressions from the policy"); } if (kp_i->type == KEY_EXPRESSION_MUSIG) { - musig_aggr_key_info_t *musig_info_i = r_musig_aggr_key_info(&kp_i->m.musig_info); - uint16_t *key_indexes_i = r_uint16(&musig_info_i->key_indexes); + const musig_aggr_key_info_t *musig_info_i = r_musig_aggr_key_info(&kp_i->m.musig_info); + const uint16_t *key_indexes_i = r_uint16(&musig_info_i->key_indexes); uint16_t key_indexes_i_sorted[MAX_PUBKEYS_PER_MUSIG]; memcpy(key_indexes_i_sorted, key_indexes_i, musig_info_i->n * sizeof(uint16_t)); @@ -2030,10 +2030,12 @@ int is_policy_sane(dispatcher_context_t *dispatcher_context, } } } else if (kp_i->type == KEY_EXPRESSION_MUSIG && kp_j->type == KEY_EXPRESSION_MUSIG) { - musig_aggr_key_info_t *musig_info_i = r_musig_aggr_key_info(&kp_i->m.musig_info); - uint16_t *key_indexes_i = r_uint16(&musig_info_i->key_indexes); - musig_aggr_key_info_t *musig_info_j = r_musig_aggr_key_info(&kp_j->m.musig_info); - uint16_t *key_indexes_j = r_uint16(&musig_info_j->key_indexes); + const musig_aggr_key_info_t *musig_info_i = + r_musig_aggr_key_info(&kp_i->m.musig_info); + const uint16_t *key_indexes_i = r_uint16(&musig_info_i->key_indexes); + const musig_aggr_key_info_t *musig_info_j = + r_musig_aggr_key_info(&kp_j->m.musig_info); + const uint16_t *key_indexes_j = r_uint16(&musig_info_j->key_indexes); // if two musigs have exactly the same set of keys, then the derivation options must // be disjoint diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 6efecb36d..6fb3de7df 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -398,7 +398,7 @@ static int get_amount_scriptpubkey_from_psbt( // PSBT_{IN|OUT}_{TAP}?_BIP32_DERIVATION fields. static int read_change_and_index_from_psbt_bip32_derivation( dispatcher_context_t *dc, - keyexpr_info_t *keyexpr_info, + const keyexpr_info_t *keyexpr_info, in_out_info_t *in_out, sign_psbt_cache_t *sign_psbt_cache, int psbt_key_type, @@ -767,14 +767,17 @@ static bool fill_keyexpr_info_if_internal(dispatcher_context_t *dc, return result; } else if (keyexpr_info->key_expression_ptr->type == KEY_EXPRESSION_MUSIG) { // iterate through the keys of the musig() placeholder to find if a key is internal - musig_aggr_key_info_t *musig_info = + const musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&keyexpr_info->key_expression_ptr->m.musig_info); - uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); + const uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); bool has_internal_key = false; // collect the keys of the musig, and fill the info related to the internal key (if any) uint8_t keys[MAX_PUBKEYS_PER_MUSIG][33]; + + LEDGER_ASSERT(musig_info->n <= MAX_PUBKEYS_PER_MUSIG, "Too many keys in musig placeholder"); + for (int idx_in_musig = 0; idx_in_musig < musig_info->n; idx_in_musig++) { if (get_and_verify_key_info(dc, st, key_indexes[idx_in_musig], &tmp_keyexpr_info)) { memcpy(keyexpr_info->key_derivation, @@ -1899,7 +1902,7 @@ static bool __attribute__((noinline)) compute_sighash_legacy(dispatcher_context_ static bool __attribute__((noinline)) compute_sighash_segwitv0(dispatcher_context_t *dc, sign_psbt_state_t *st, - tx_hashes_t *hashes, + const tx_hashes_t *hashes, input_info_t *input, unsigned int cur_input_index, uint8_t sighash[static 32]) { @@ -2084,10 +2087,10 @@ static bool __attribute__((noinline)) compute_sighash_segwitv0(dispatcher_contex static bool __attribute__((noinline)) compute_sighash_segwitv1(dispatcher_context_t *dc, sign_psbt_state_t *st, - tx_hashes_t *hashes, + const tx_hashes_t *hashes, input_info_t *input, unsigned int cur_input_index, - keyexpr_info_t *keyexpr_info, + const keyexpr_info_t *keyexpr_info, uint8_t sighash[static 32]) { LOG_PROCESSOR(__FILE__, __LINE__, __func__); @@ -2260,12 +2263,13 @@ static bool __attribute__((noinline)) yield_signature(dispatcher_context_t *dc, return true; } -static bool __attribute__((noinline)) sign_sighash_ecdsa_and_yield(dispatcher_context_t *dc, - sign_psbt_state_t *st, - keyexpr_info_t *keyexpr_info, - input_info_t *input, - unsigned int cur_input_index, - uint8_t sighash[static 32]) { +static bool __attribute__((noinline)) +sign_sighash_ecdsa_and_yield(dispatcher_context_t *dc, + sign_psbt_state_t *st, + const keyexpr_info_t *keyexpr_info, + input_info_t *input, + unsigned int cur_input_index, + uint8_t sighash[static 32]) { LOG_PROCESSOR(__FILE__, __LINE__, __func__); uint32_t sign_path[MAX_BIP32_PATH_STEPS]; @@ -2519,13 +2523,14 @@ static bool yield_musig_partial_signature(dispatcher_context_t *dc, tapleaf_hash); } -static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_context_t *dc, - sign_psbt_state_t *st, - signing_state_t *signing_state, - keyexpr_info_t *keyexpr_info, - input_info_t *input, - unsigned int cur_input_index, - uint8_t sighash[static 32]) { +static bool __attribute__((noinline)) +sign_sighash_musig_and_yield(dispatcher_context_t *dc, + sign_psbt_state_t *st, + signing_state_t *signing_state, + const keyexpr_info_t *keyexpr_info, + const input_info_t *input, + unsigned int cur_input_index, + uint8_t sighash[static 32]) { LOG_PROCESSOR(__FILE__, __LINE__, __func__); if (st->wallet_policy_map->type != TOKEN_TR) { @@ -2559,9 +2564,11 @@ static bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_co serialized_extended_pubkey_t ext_pubkey; const policy_node_keyexpr_t *key_expr = keyexpr_info->key_expression_ptr; - musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); - uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); + const musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); + const uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); plain_pk_t keys[MAX_PUBKEYS_PER_MUSIG]; + + LEDGER_ASSERT(musig_info->n <= MAX_PUBKEYS_PER_MUSIG, "Too many keys in musig key expression"); for (int i = 0; i < musig_info->n; i++) { // we use ext_pubkey as a temporary variable; will overwrite later if (0 > get_extended_pubkey(dc, &wdi, key_indexes[i], &ext_pubkey)) { From ad377fbba5cd1b60145a5e558479bbc165d78df4 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 4 Jun 2024 15:03:37 +0200 Subject: [PATCH 24/57] Expose new types in python client --- bitcoin_client/ledger_bitcoin/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bitcoin_client/ledger_bitcoin/__init__.py b/bitcoin_client/ledger_bitcoin/__init__.py index 4c4bd82be..5777dfb37 100644 --- a/bitcoin_client/ledger_bitcoin/__init__.py +++ b/bitcoin_client/ledger_bitcoin/__init__.py @@ -1,7 +1,7 @@ """Ledger Nano Bitcoin app client""" -from .client_base import Client, TransportClient, PartialSignature +from .client_base import Client, TransportClient, PartialSignature, MusigPubNonce, MusigPartialSignature, SignPsbtYieldedObject from .client import createClient from .common import Chain @@ -13,6 +13,9 @@ "Client", "TransportClient", "PartialSignature", + "MusigPubNonce", + "MusigPartialSignature", + "SignPsbtYieldedObject", "createClient", "Chain", "AddressType", From 38a9e80f2c85cc27d02497ffae76d73917776bdd Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 9 Oct 2024 14:37:09 +0200 Subject: [PATCH 25/57] Update BIP_MUSIG_CHAINCODE ==> BIP_328_CHAINCODE --- bitcoin_client/ledger_bitcoin/client.py | 4 ++-- src/handler/lib/policy.c | 2 +- src/handler/sign_psbt.c | 6 ++---- src/musig/musig.h | 3 +-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/bitcoin_client/ledger_bitcoin/client.py b/bitcoin_client/ledger_bitcoin/client.py index 89279df36..6fe983152 100644 --- a/bitcoin_client/ledger_bitcoin/client.py +++ b/bitcoin_client/ledger_bitcoin/client.py @@ -42,7 +42,7 @@ def parse_stream_to_map(f: BufferedReader) -> Mapping[bytes, bytes]: def aggr_xpub(pubkeys: List[bytes], chain: Chain) -> str: - BIP_MUSIG_CHAINCODE = bytes.fromhex( + BIP_328_CHAINCODE = bytes.fromhex( "868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965") # sort the pubkeys prior to aggregation ctx = key_agg(list(sorted(pubkeys))) @@ -59,7 +59,7 @@ def aggr_xpub(pubkeys: List[bytes], chain: Chain) -> str: b'\x00', # depth b'\x00\x00\x00\x00', # parent fingerprint b'\x00\x00\x00\x00', # child number - BIP_MUSIG_CHAINCODE, + BIP_328_CHAINCODE, compressed_pubkey ])) diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index a1285f4c9..a889cc898 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -500,7 +500,7 @@ __attribute__((warn_unused_result)) static int get_derived_pubkey( ext_pubkey.compressed_pubkey[0] = (musig_ctx.Q.y[31] % 2 == 0) ? 2 : 3; memcpy(&ext_pubkey.compressed_pubkey[1], musig_ctx.Q.x, sizeof(musig_ctx.Q.x)); - memcpy(&ext_pubkey.chain_code, BIP_MUSIG_CHAINCODE, sizeof(BIP_MUSIG_CHAINCODE)); + memcpy(&ext_pubkey.chain_code, BIP_328_CHAINCODE, sizeof(BIP_328_CHAINCODE)); } else { LEDGER_ASSERT(false, "Unreachable code"); } diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 6fb3de7df..80f2ec5d2 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -822,9 +822,7 @@ static bool fill_keyexpr_info_if_internal(dispatcher_context_t *dc, memcpy(&keyexpr_info->pubkey.compressed_pubkey[1], musig_ctx.Q.x, sizeof(musig_ctx.Q.x)); - memcpy(&keyexpr_info->pubkey.chain_code, - BIP_MUSIG_CHAINCODE, - sizeof(BIP_MUSIG_CHAINCODE)); + memcpy(&keyexpr_info->pubkey.chain_code, BIP_328_CHAINCODE, sizeof(BIP_328_CHAINCODE)); keyexpr_info->fingerprint = crypto_get_key_fingerprint(keyexpr_info->pubkey.compressed_pubkey); @@ -2598,7 +2596,7 @@ sign_sighash_musig_and_yield(dispatcher_context_t *dc, ext_pubkey.compressed_pubkey[0] = (musig_ctx.Q.y[31] % 2 == 0) ? 2 : 3; memcpy(&ext_pubkey.compressed_pubkey[1], musig_ctx.Q.x, sizeof(musig_ctx.Q.x)); - memcpy(&ext_pubkey.chain_code, BIP_MUSIG_CHAINCODE, sizeof(BIP_MUSIG_CHAINCODE)); + memcpy(&ext_pubkey.chain_code, BIP_328_CHAINCODE, sizeof(BIP_328_CHAINCODE)); // 2) compute musig2 tweaks // We always have exactly 2 BIP32 tweaks in wallet policies; if the musig is in the keypath diff --git a/src/musig/musig.h b/src/musig/musig.h index 1a70334a7..ed28d3b77 100644 --- a/src/musig/musig.h +++ b/src/musig/musig.h @@ -5,8 +5,7 @@ #define MUSIG_PUBNONCE_SIZE 66 -// TODO: rename once BIP number is assigned -static uint8_t BIP_MUSIG_CHAINCODE[32] = { +static uint8_t BIP_328_CHAINCODE[32] = { 0x86, 0x80, 0x87, 0xCA, 0x02, 0xA6, 0xF9, 0x74, 0xC4, 0x59, 0x89, 0x24, 0xC3, 0x6B, 0x57, 0x76, 0x2D, 0x32, 0xCB, 0x45, 0x71, 0x71, 0x67, 0xE3, 0x00, 0x62, 0x2C, 0x71, 0x67, 0xE3, 0x89, 0x65}; From aea89fd0cd8365276774d32e99e07062b85e1da2 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:22:10 +0000 Subject: [PATCH 26/57] Fix read_change_and_index_from_psbt_bip32_derivation incorrectly aborting prematurely for some PSBTs. Added explanatory comment --- src/handler/sign_psbt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 80f2ec5d2..ae2b77018 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -396,6 +396,9 @@ static int get_amount_scriptpubkey_from_psbt( // Convenience function to share common logic when processing all the // PSBT_{IN|OUT}_{TAP}?_BIP32_DERIVATION fields. +// Note: This function must return -1 only on errors (causing signing to abort). +// It should return 1 if a derivation that makes sense for this input/output is found. +// It should return 0 otherwise (no match found, but continue the signing flow). static int read_change_and_index_from_psbt_bip32_derivation( dispatcher_context_t *dc, const keyexpr_info_t *keyexpr_info, @@ -438,7 +441,7 @@ static int read_change_and_index_from_psbt_bip32_derivation( if (der_len < 2 || der_len > MAX_BIP32_PATH_STEPS) { PRINTF("BIP32_DERIVATION path too long\n"); - return -1; + return 0; } // if this derivation path matches the internal key expression, From 13abab865e90f318fa517a2aab626b8f9365e70c Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 6 Nov 2024 08:32:15 +0000 Subject: [PATCH 27/57] Removed unused argument; deleted commented out check The check doesn't serve a security purpose, since direct derivation of each input/change script is used to check if they are internal. --- src/handler/sign_psbt.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index ae2b77018..c09637aa4 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -403,7 +403,6 @@ static int read_change_and_index_from_psbt_bip32_derivation( dispatcher_context_t *dc, const keyexpr_info_t *keyexpr_info, in_out_info_t *in_out, - sign_psbt_cache_t *sign_psbt_cache, int psbt_key_type, buffer_t *data, const merkleized_map_commitment_t *map_commitment, @@ -469,24 +468,6 @@ static int read_change_and_index_from_psbt_bip32_derivation( return 0; } - // TODO: safe to remove this check? It should be, since we later re-derive - // the script independently. - // // check that we can indeed derive the same key from the current key expression - // serialized_extended_pubkey_t pubkey; - // if (0 > derive_first_step_for_pubkey(&keyexpr_info->pubkey, - // keyexpr_info->key_expression_ptr, - // sign_psbt_cache, - // in_out->is_change, - // &pubkey)) - // return -1; - // if (0 > bip32_CKDpub(&pubkey, addr_index, &pubkey, NULL)) return -1; - - // int pk_offset = is_tap ? 1 : 0; - // if (memcmp(pubkey.compressed_pubkey + pk_offset, bip32_derivation_pubkey, key_len) != 0) - // { - // return 0; - // } - in_out->key_expression_found = true; return 1; } @@ -876,7 +857,6 @@ static bool find_first_internal_keyexpr(dispatcher_context_t *dc, typedef struct { keyexpr_info_t *keyexpr_info; input_info_t *input; - sign_psbt_cache_t *sign_psbt_cache; } input_keys_callback_data_t; /** @@ -906,7 +886,6 @@ static void input_keys_callback(dispatcher_context_t *dc, if (0 > read_change_and_index_from_psbt_bip32_derivation(dc, callback_data->keyexpr_info, &callback_data->input->in_out, - callback_data->sign_psbt_cache, key_type, data, map_commitment, @@ -936,9 +915,7 @@ preprocess_inputs(dispatcher_context_t *dc, input_info_t input; memset(&input, 0, sizeof(input)); - input_keys_callback_data_t callback_data = {.input = &input, - .keyexpr_info = &keyexpr_info, - .sign_psbt_cache = sign_psbt_cache}; + input_keys_callback_data_t callback_data = {.input = &input, .keyexpr_info = &keyexpr_info}; int res = call_get_merkleized_map_with_callback( dc, (void *) &callback_data, @@ -1141,7 +1118,6 @@ preprocess_inputs(dispatcher_context_t *dc, typedef struct { keyexpr_info_t *keyexpr_info; output_info_t *output; - sign_psbt_cache_t *sign_psbt_cache; } output_keys_callback_data_t; /** @@ -1163,7 +1139,6 @@ static void output_keys_callback(dispatcher_context_t *dc, if (0 > read_change_and_index_from_psbt_bip32_derivation(dc, callback_data->keyexpr_info, &callback_data->output->in_out, - callback_data->sign_psbt_cache, key_type, data, map_commitment, @@ -1203,8 +1178,7 @@ preprocess_outputs(dispatcher_context_t *dc, memset(&output, 0, sizeof(output)); output_keys_callback_data_t callback_data = {.output = &output, - .keyexpr_info = &keyexpr_info, - .sign_psbt_cache = sign_psbt_cache}; + .keyexpr_info = &keyexpr_info}; int res = call_get_merkleized_map_with_callback( dc, (void *) &callback_data, From 5fcdcdf80754be4c6c039109ef09f3ee8b6ef7f4 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 5 Nov 2024 11:40:31 +0000 Subject: [PATCH 28/57] Generalized count_internal_keys in the test suite to count_internal_key_placeholders, with musig placeholder support --- test_utils/__init__.py | 39 +++++++++++++++++++++++++++++------- tests/test_e2e_miniscript.py | 4 ++-- tests/test_e2e_multisig.py | 4 ++-- tests/test_e2e_tapscripts.py | 4 ++-- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/test_utils/__init__.py b/test_utils/__init__.py index f7867407a..013d9e2e3 100644 --- a/test_utils/__init__.py +++ b/test_utils/__init__.py @@ -1,10 +1,12 @@ +import re + import hashlib from typing import Literal, Union from mnemonic import Mnemonic from bip32 import BIP32 -from bitcoin_client.ledger_bitcoin.wallet import WalletPolicy +from bitcoin_client.ledger_bitcoin.wallet import WalletPolicy, WalletType from .slip21 import Slip21Node @@ -89,14 +91,16 @@ def get_internal_xpub(seed: str, path: str) -> str: return bip32.get_xpub_from_path(f"m/{path}") if path else bip32.get_xpub_from_path("m") -def count_internal_keys(seed: str, network: Union[Literal['main'], Literal['test']], wallet_policy: WalletPolicy) -> int: - """Count how many of the keys in wallet_policy are indeed internal""" +def count_internal_key_placeholders(seed: str, network: Union[Literal['main'], Literal['test']], wallet_policy: WalletPolicy) -> int: + """Count how many of the key placeholders in wallet_policy are indeed internal. + musig() placeholders are counted as many times as there are internal keys in them.""" bip32 = BIP32.from_seed(seed, network) master_key_fingerprint = hash160(bip32.pubkey)[0:4] - count = 0 + is_key_internal = [] for key_index, key_info in enumerate(wallet_policy.keys_info): + is_this_key_internal = False if "]" in key_info: key_orig_end_pos = key_info.index("]") fpr = key_info[1:9] @@ -110,8 +114,29 @@ def count_internal_keys(seed: str, network: Union[Literal['main'], Literal['test if fpr == master_key_fingerprint.hex(): computed_xpub = get_internal_xpub(seed, path) if computed_xpub == xpub: - # there could be multiple placeholders using the same key; we must count all of them - count += wallet_policy.descriptor_template.count( - f"@{key_index}/") + is_this_key_internal = True + is_key_internal.append(is_this_key_internal) + + # enumerate all the key placeholders + # for simplicity, we look for all the following patterns using regular expressions: + # - Simple keys: @/ (always with additional derivations, hence the final '/') + # - Musig expressions: musig(@k1, @k2, ...) + + count = 0 + + simple_key_placeholders = re.findall( + r'@(\d+)/', wallet_policy.descriptor_template) + # for each match, count it if the corresponding key is internal + for key_index in simple_key_placeholders: + if is_key_internal[int(key_index)]: + count += 1 + + if wallet_policy.version != WalletType.WALLET_POLICY_V1: # no musig in V1 policies + musig_key_placeholders = re.findall( + r'musig\(([^)]*)\)', wallet_policy.descriptor_template) + for musig_expr in musig_key_placeholders: + musig_keys_indices = [int(k[1:]) for k in musig_expr.split(",")] + # We count each musig placeholder as many times are there are internal keys in it + count += sum(int(is_key_internal[k]) for k in musig_keys_indices) return count diff --git a/tests/test_e2e_miniscript.py b/tests/test_e2e_miniscript.py index ab6be201a..3470421f4 100644 --- a/tests/test_e2e_miniscript.py +++ b/tests/test_e2e_miniscript.py @@ -11,7 +11,7 @@ from ledger_bitcoin.psbt import PSBT from ledger_bitcoin.wallet import WalletPolicy -from test_utils import SpeculosGlobals, get_internal_xpub, count_internal_keys +from test_utils import SpeculosGlobals, get_internal_xpub, count_internal_key_placeholders from ragger_bitcoin import RaggerClient from ragger_bitcoin.ragger_instructions import Instructions @@ -106,7 +106,7 @@ def run_test_e2e(navigator: Navigator, client: RaggerClient, wallet_policy: Wall instructions=instructions_sign_psbt, testname=f"{test_name}_sign") - n_internal_keys = count_internal_keys(speculos_globals.seed, "test", wallet_policy) + n_internal_keys = count_internal_key_placeholders(speculos_globals.seed, "test", wallet_policy) assert len(hww_sigs) == n_internal_keys * len(psbt.inputs) # should be true as long as all inputs are internal for i, part_sig in hww_sigs: diff --git a/tests/test_e2e_multisig.py b/tests/test_e2e_multisig.py index f0a35fddf..094c29e1a 100644 --- a/tests/test_e2e_multisig.py +++ b/tests/test_e2e_multisig.py @@ -11,7 +11,7 @@ from ledger_bitcoin.psbt import PSBT from ledger_bitcoin.wallet import WalletPolicy -from test_utils import SpeculosGlobals, get_internal_xpub, count_internal_keys +from test_utils import SpeculosGlobals, get_internal_xpub, count_internal_key_placeholders from speculos.client import SpeculosClient @@ -112,7 +112,7 @@ def run_test(navigator: Navigator, client: RaggerClient, wallet_policy: WalletPo instructions=instructions_sign_psbt, testname=f"{test_name}_sign") - n_internal_keys = count_internal_keys( + n_internal_keys = count_internal_key_placeholders( speculos_globals.seed, "test", wallet_policy) # should be true as long as all inputs are internal assert len(hww_sigs) == n_internal_keys * len(psbt.inputs) diff --git a/tests/test_e2e_tapscripts.py b/tests/test_e2e_tapscripts.py index 1ef95a31a..1b813f2ee 100644 --- a/tests/test_e2e_tapscripts.py +++ b/tests/test_e2e_tapscripts.py @@ -13,7 +13,7 @@ from ledger_bitcoin.psbt import PSBT from ledger_bitcoin.wallet import WalletPolicy -from test_utils import SpeculosGlobals, get_internal_xpub, count_internal_keys +from test_utils import SpeculosGlobals, get_internal_xpub, count_internal_key_placeholders from ragger_bitcoin import RaggerClient from ragger_bitcoin.ragger_instructions import Instructions @@ -119,7 +119,7 @@ def run_test_e2e(navigator: Navigator, client: RaggerClient, wallet_policy: Wall signed_psbt_hww_b64 = psbt.serialize() - n_internal_keys = count_internal_keys(speculos_globals.seed, "test", wallet_policy) + n_internal_keys = count_internal_key_placeholders(speculos_globals.seed, "test", wallet_policy) assert len(hww_sigs) == n_internal_keys * len(psbt.inputs) # should be true as long as all inputs are internal # ==> sign it with bitcoin-core From 1192d105a1402ae4dab7077cf8b12ca7fb8671ea Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 5 Nov 2024 14:26:13 +0000 Subject: [PATCH 29/57] Support BIP-389 multipath descriptors in get_descriptor --- bitcoin_client/ledger_bitcoin/wallet.py | 35 +++++++++++++++++++------ 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/bitcoin_client/ledger_bitcoin/wallet.py b/bitcoin_client/ledger_bitcoin/wallet.py index d6ccf4390..326d7e52f 100644 --- a/bitcoin_client/ledger_bitcoin/wallet.py +++ b/bitcoin_client/ledger_bitcoin/wallet.py @@ -1,13 +1,14 @@ import re from enum import IntEnum -from typing import List +from typing import List, Union from hashlib import sha256 from .common import serialize_str, AddressType, write_varint from .merkle import MerkleTree, element_hash + class WalletType(IntEnum): WALLET_POLICY_V1 = 1 WALLET_POLICY_V2 = 2 @@ -58,34 +59,52 @@ def n_keys(self) -> int: return len(self.keys_info) def serialize(self) -> bytes: - keys_info_hashes = map(lambda k: element_hash(k.encode()), self.keys_info) + keys_info_hashes = map( + lambda k: element_hash(k.encode()), self.keys_info) - descriptor_template_sha256 = sha256(self.descriptor_template.encode()).digest() + descriptor_template_sha256 = sha256( + self.descriptor_template.encode()).digest() return b"".join([ super().serialize(), write_varint(len(self.descriptor_template.encode())), - self.descriptor_template.encode() if self.version == WalletType.WALLET_POLICY_V1 else descriptor_template_sha256, + self.descriptor_template.encode( + ) if self.version == WalletType.WALLET_POLICY_V1 else descriptor_template_sha256, write_varint(len(self.keys_info)), MerkleTree(keys_info_hashes).root ]) - def get_descriptor(self, change: bool) -> str: + def get_descriptor(self, change: Union[bool, None]) -> str: + """ + Generates a descriptor string based on the wallet's descriptor template and keys. + Args: + change (bool | None): Indicates whether the descriptor is for a change address. + - If None, returns the BIP-389 multipath address for both the receive and change address. + - If True, the descriptor is for a change address. + - If False, the descriptor is for a non-change address. + Returns: + str: The generated descriptor. + """ + desc = self.descriptor_template for i in reversed(range(self.n_keys)): key = self.keys_info[i] desc = desc.replace(f"@{i}", key) # in V1, /** is part of the key; in V2, it's part of the policy map. This handles either - desc = desc.replace("/**", f"/{1 if change else 0}/*") + if change is not None: + desc = desc.replace("/**", f"/{1 if change else 0}/*") + else: + desc = desc.replace("/**", f"/<0;1>/*") if self.version == WalletType.WALLET_POLICY_V2: # V2, the / syntax is supported. Replace with M if not change, or with N if change - regex = r"/<(\d+);(\d+)>" - desc = re.sub(regex, "/\\2" if change else "/\\1", desc) + if change is not None: + desc = re.sub(r"/<(\d+);(\d+)>", "/\\2" if change else "/\\1", desc) return desc + class MultisigWallet(WalletPolicy): def __init__(self, name: str, address_type: AddressType, threshold: int, keys_info: List[str], sorted: bool = True, version: WalletType = WalletType.WALLET_POLICY_V2) -> None: n_keys = len(keys_info) From 6c8fb7e867004e06099c9e0411563ca0f8ed3820 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 5 Nov 2024 17:02:59 +0000 Subject: [PATCH 30/57] Updated e2e tests to use deterministic xprivs in bitcoin-core --- tests/conftest.py | 107 +++++++++++++++++++++++------------ tests/test_e2e_miniscript.py | 38 +++++++++---- tests/test_e2e_multisig.py | 16 +++--- tests/test_e2e_tapscripts.py | 13 +++-- 4 files changed, 114 insertions(+), 60 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index cffd00cf6..23693c417 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,32 +1,32 @@ -import sys -import os -absolute_path = os.path.dirname(os.path.abspath(__file__)) -relative_bitcoin_path = ('../bitcoin_client') -absolute_bitcoin_client_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../') -sys.path.append(os.path.join(absolute_path, relative_bitcoin_path)) +import sys # noqa: E402 +import os # noqa: E402 -import random -from typing import Tuple - -from test_utils.fixtures import * -from test_utils.authproxy import AuthServiceProxy, JSONRPCException -from test_utils import segwit_addr - -import shutil -import subprocess -from time import sleep -from decimal import Decimal -from pathlib import Path +absolute_path = os.path.dirname(os.path.abspath(__file__)) # noqa: E402 +relative_bitcoin_path = ('../bitcoin_client') # noqa: E402 +absolute_bitcoin_client_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), '../') # noqa: E402 +sys.path.append(os.path.join(absolute_path, relative_bitcoin_path)) # noqa: E402 -from ledger_bitcoin import Chain -from ledger_bitcoin.common import sha256 +from ragger_bitcoin import createRaggerClient, RaggerClient +from ragger.backend import RaisePolicy +from ragger.backend.interface import BackendInterface +from ragger.conftest import configuration import ledger_bitcoin._base58 as base58 +from ledger_bitcoin.common import sha256 +from ledger_bitcoin import Chain +from pathlib import Path +from decimal import Decimal +from time import sleep +import subprocess +import shutil +from test_utils import segwit_addr +from test_utils.authproxy import AuthServiceProxy, JSONRPCException +from test_utils.fixtures import * +from typing import Tuple +import random +from bip32 import BIP32 -from ragger.conftest import configuration -from ragger.backend.interface import BackendInterface -from ragger.backend import RaisePolicy -from ragger_bitcoin import createRaggerClient, RaggerClient ########################### ### CONFIGURATION START ### @@ -105,7 +105,8 @@ def run_bitcoind(): bitcoind = os.getenv("BITCOIND", "/bitcoin/bin/bitcoind") - shutil.copy(os.path.join(os.path.dirname(__file__), "bitcoin.conf"), BITCOIN_DIRNAME) + shutil.copy(os.path.join(os.path.dirname(__file__), + "bitcoin.conf"), BITCOIN_DIRNAME) subprocess.Popen([bitcoind, f"--datadir={BITCOIN_DIRNAME}"]) # Make sure the node is ready, and generate some initial blocks @@ -165,29 +166,63 @@ def get_unique_wallet_name() -> str: return result +def get_pseudorandom_keypair(wallet_name: str) -> Tuple[str, str]: + """ + Generates a tpub and tpriv deterministically from the wallet name + Used in tests to have deterministic wallets in bitcoin-core instances. + """ + + bip32 = BIP32.from_seed(wallet_name.encode(), network="test") + + xpub = bip32.get_xpub_from_path("m") + xpriv = bip32.get_xpriv_from_path("m") + + return xpub, xpriv + + def create_new_wallet() -> Tuple[str, str]: """Creates a new descriptor-enabled wallet in bitcoin-core. Each new wallet has an increasing counter as - part of it's name in order to avoid conflicts. Returns the wallet name and the xpub (dropping the key origin + part of it's name in order to avoid conflicts. Returns the wallet name and the xpub (with no key origin information).""" wallet_name = get_unique_wallet_name() - # TODO: derive seed from wallet_count, and use it to create a descriptor wallet (how?) - # this would help to have repeatable tests, generating always the same seeds - get_rpc().createwallet(wallet_name=wallet_name, descriptors=True) - wallet_rpc = get_wallet_rpc(wallet_name) - - all_descriptors = wallet_rpc.listdescriptors()["descriptors"] - descriptor: str = next(filter(lambda d: d["desc"].startswith( - "pkh") and "/0/*" in d["desc"], all_descriptors))["desc"] - core_xpub_orig = descriptor[descriptor.index("(")+1: descriptor.index("/0/*")] - core_xpub = core_xpub_orig[core_xpub_orig.find("]") + 1:] + core_xpub, _ = get_pseudorandom_keypair(wallet_name) return wallet_name, core_xpub +def recompute_checksum(rpc: AuthServiceProxy, descriptor: str) -> str: + # remove "#" and everything after it, if present + if '#' in descriptor: + descriptor = descriptor[:descriptor.index('#')] + descriptor_info = rpc.getdescriptorinfo(descriptor) + return descriptor + '#' + descriptor_info["checksum"] + + +def import_descriptors_with_privkeys(core_wallet_name: str, receive_desc: str, change_desc: str): + wallet = get_wallet_rpc(core_wallet_name) + wallet_xpub, wallet_xpriv = get_pseudorandom_keypair(core_wallet_name) + + assert wallet_xpub in receive_desc and wallet_xpub in change_desc + + import_desc = [{ + "desc": recompute_checksum(wallet, receive_desc.replace(wallet_xpub, wallet_xpriv)), + "active": True, + "internal": False, + "timestamp": "now" + }, { + "desc": recompute_checksum(wallet, change_desc.replace(wallet_xpub, wallet_xpriv)), + "active": True, + "internal": True, + "timestamp": "now" + }] + import_res = wallet.importdescriptors(import_desc) + assert import_res[0]["success"] and import_res[1]["success"] + + def generate_blocks(n): return get_rpc().generatetoaddress(n, btc_addr) diff --git a/tests/test_e2e_miniscript.py b/tests/test_e2e_miniscript.py index 3470421f4..aa5b34856 100644 --- a/tests/test_e2e_miniscript.py +++ b/tests/test_e2e_miniscript.py @@ -1,6 +1,6 @@ import pytest -from typing import List, Union +from typing import List import hmac from hashlib import sha256 @@ -15,13 +15,13 @@ from ragger_bitcoin import RaggerClient from ragger_bitcoin.ragger_instructions import Instructions -from ragger.navigator import Navigator, NavInsID +from ragger.navigator import Navigator from ragger.firmware import Firmware from ragger.error import ExceptionRAPDU from .instructions import e2e_register_wallet_instruction, e2e_sign_psbt_instruction -from .conftest import create_new_wallet, generate_blocks, get_unique_wallet_name, get_wallet_rpc, testnet_to_regtest_addr as T +from .conftest import create_new_wallet, generate_blocks, get_unique_wallet_name, get_wallet_rpc, import_descriptors_with_privkeys, testnet_to_regtest_addr as T from .conftest import AuthServiceProxy @@ -34,11 +34,13 @@ def run_test_e2e(navigator: Navigator, client: RaggerClient, wallet_policy: Wall assert wallet_id == wallet_policy.id assert hmac.compare_digest( - hmac.new(speculos_globals.wallet_registration_key, wallet_id, sha256).digest(), + hmac.new(speculos_globals.wallet_registration_key, + wallet_id, sha256).digest(), wallet_hmac, ) - address_hww = client.get_wallet_address(wallet_policy, wallet_hmac, 0, 3, False) + address_hww = client.get_wallet_address( + wallet_policy, wallet_hmac, 0, 3, False) # ==> verify the address matches what bitcoin-core computes receive_descriptor = wallet_policy.get_descriptor(change=False) @@ -91,7 +93,8 @@ def run_test_e2e(navigator: Navigator, client: RaggerClient, wallet_policy: Wall out_address: Decimal("0.01") }, options={ - "changePosition": 1 # We need a fixed position to be able to know how to navigate in the flows + # We need a fixed position to be able to know how to navigate in the flows + "changePosition": 1 } ) @@ -106,19 +109,27 @@ def run_test_e2e(navigator: Navigator, client: RaggerClient, wallet_policy: Wall instructions=instructions_sign_psbt, testname=f"{test_name}_sign") - n_internal_keys = count_internal_key_placeholders(speculos_globals.seed, "test", wallet_policy) - assert len(hww_sigs) == n_internal_keys * len(psbt.inputs) # should be true as long as all inputs are internal + n_internal_keys = count_internal_key_placeholders( + speculos_globals.seed, "test", wallet_policy) + # should be true as long as all inputs are internal + assert len(hww_sigs) == n_internal_keys * len(psbt.inputs) for i, part_sig in hww_sigs: psbt.inputs[i].partial_sigs[part_sig.pubkey] = part_sig.signature signed_psbt_hww_b64 = psbt.serialize() + # ==> import descriptor for each bitcoin-core wallet + for core_wallet_name in core_wallet_names: + import_descriptors_with_privkeys( + core_wallet_name, receive_descriptor_chk, change_descriptor_chk) + # ==> sign it with bitcoin-core partial_psbts = [signed_psbt_hww_b64] for core_wallet_name in core_wallet_names: - partial_psbts.append(get_wallet_rpc(core_wallet_name).walletprocesspsbt(psbt_b64)["psbt"]) + partial_psbts.append(get_wallet_rpc( + core_wallet_name).walletprocesspsbt(psbt_b64)["psbt"]) # ==> finalize the psbt, extract tx and broadcast combined_psbt = rpc.combinepsbt(partial_psbts) @@ -404,15 +415,18 @@ def test_invalid_miniscript(navigator: Navigator, firmware: Firmware, client: Ra run_test_invalid(client, "wsh(wsh(pkh(@0/**)))", [internal_xpub_orig]) # sh(wsh(...)) is meaningful with valid miniscript, but current implementation of miniscript assumes wsh(...) - run_test_invalid(client, "sh(wsh(or_d(pk(@0/**),pkh(@1/**))))", [internal_xpub_orig, core_xpub_orig1]) + run_test_invalid(client, "sh(wsh(or_d(pk(@0/**),pkh(@1/**))))", + [internal_xpub_orig, core_xpub_orig1]) # tr must be top-level run_test_invalid(client, "wsh(tr(pk(@0/**)))", [internal_xpub_orig]) run_test_invalid(client, "sh(tr(pk(@0/**)))", [internal_xpub_orig]) # valid miniscript must be inside wsh() - run_test_invalid(client, "or_d(pk(@0/**),pkh(@1/**))", [internal_xpub_orig, core_xpub_orig1]) - run_test_invalid(client, "sh(or_d(pk(@0/**),pkh(@1/**)))", [internal_xpub_orig, core_xpub_orig1]) + run_test_invalid(client, "or_d(pk(@0/**),pkh(@1/**))", + [internal_xpub_orig, core_xpub_orig1]) + run_test_invalid(client, "sh(or_d(pk(@0/**),pkh(@1/**)))", + [internal_xpub_orig, core_xpub_orig1]) # sortedmulti is not valid miniscript, can only be used as a descriptor inside sh or wsh run_test_invalid(client, "wsh(or_d(pk(@0/**),sortedmulti(3,@1/**,@2/**,@3/**,@4/**,@5/**)))", diff --git a/tests/test_e2e_multisig.py b/tests/test_e2e_multisig.py index 094c29e1a..d1738c4f0 100644 --- a/tests/test_e2e_multisig.py +++ b/tests/test_e2e_multisig.py @@ -1,28 +1,25 @@ import pytest -from typing import List, Union +from typing import List import hmac from hashlib import sha256 from decimal import Decimal -from ledger_bitcoin import Client, MultisigWallet, AddressType -from ledger_bitcoin.client_base import TransportClient +from ledger_bitcoin import MultisigWallet, AddressType from ledger_bitcoin.psbt import PSBT from ledger_bitcoin.wallet import WalletPolicy from test_utils import SpeculosGlobals, get_internal_xpub, count_internal_key_placeholders -from speculos.client import SpeculosClient - from ragger_bitcoin import RaggerClient from ragger_bitcoin.ragger_instructions import Instructions -from ragger.navigator import Navigator, NavInsID +from ragger.navigator import Navigator from ragger.firmware import Firmware from .instructions import e2e_register_wallet_instruction, e2e_sign_psbt_instruction -from .conftest import create_new_wallet, generate_blocks, get_unique_wallet_name, get_wallet_rpc, testnet_to_regtest_addr as T +from .conftest import create_new_wallet, generate_blocks, get_unique_wallet_name, get_wallet_rpc, import_descriptors_with_privkeys, testnet_to_regtest_addr as T from .conftest import AuthServiceProxy @@ -122,6 +119,11 @@ def run_test(navigator: Navigator, client: RaggerClient, wallet_policy: WalletPo signed_psbt_hww_b64 = psbt.serialize() + # ==> import descriptor for each bitcoin-core wallet + for core_wallet_name in core_wallet_names: + import_descriptors_with_privkeys( + core_wallet_name, receive_descriptor_chk, change_descriptor_chk) + # ==> sign it with bitcoin-core partial_psbts = [signed_psbt_hww_b64] diff --git a/tests/test_e2e_tapscripts.py b/tests/test_e2e_tapscripts.py index 1b813f2ee..23f27f1eb 100644 --- a/tests/test_e2e_tapscripts.py +++ b/tests/test_e2e_tapscripts.py @@ -1,13 +1,11 @@ import pytest -from typing import List, Union +from typing import List import hmac from hashlib import sha256 from decimal import Decimal -from ledger_bitcoin import Client -from ledger_bitcoin.client_base import TransportClient from ledger_bitcoin.exception.errors import IncorrectDataError, NotSupportedError from ledger_bitcoin.exception.device_exception import DeviceException from ledger_bitcoin.psbt import PSBT @@ -17,12 +15,12 @@ from ragger_bitcoin import RaggerClient from ragger_bitcoin.ragger_instructions import Instructions -from ragger.navigator import Navigator, NavInsID +from ragger.navigator import Navigator from ragger.firmware import Firmware from ragger.error import ExceptionRAPDU from .instructions import e2e_register_wallet_instruction, e2e_sign_psbt_instruction -from .conftest import AuthServiceProxy +from .conftest import AuthServiceProxy, import_descriptors_with_privkeys from .conftest import create_new_wallet, generate_blocks, get_unique_wallet_name, get_wallet_rpc, testnet_to_regtest_addr as T @@ -122,6 +120,11 @@ def run_test_e2e(navigator: Navigator, client: RaggerClient, wallet_policy: Wall n_internal_keys = count_internal_key_placeholders(speculos_globals.seed, "test", wallet_policy) assert len(hww_sigs) == n_internal_keys * len(psbt.inputs) # should be true as long as all inputs are internal + # ==> import descriptor for each bitcoin-core wallet + for core_wallet_name in core_wallet_names: + import_descriptors_with_privkeys( + core_wallet_name, receive_descriptor_chk, change_descriptor_chk) + # ==> sign it with bitcoin-core partial_psbts = [signed_psbt_hww_b64] From 41898234ff76179e6d3a6f19909912ee33967dec Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 6 Nov 2024 17:07:45 +0000 Subject: [PATCH 31/57] Refactor code of is_policy_sane for clarity; improved comments --- src/handler/lib/policy.c | 104 ++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index a889cc898..7af8280f0 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -1910,6 +1910,48 @@ static void sort_uint16_array(uint16_t *array, size_t n) { } } +static bool are_key_placeholders_identical(const policy_node_keyexpr_t *kp1, + const policy_node_keyexpr_t *kp2) { + if (kp1->type != kp2->type) { + return false; + } + if (kp1->type == KEY_EXPRESSION_NORMAL && kp2->type == KEY_EXPRESSION_NORMAL) { + return kp1->k.key_index == kp2->k.key_index; + } else if (kp1->type == KEY_EXPRESSION_MUSIG && kp2->type == KEY_EXPRESSION_MUSIG) { + const musig_aggr_key_info_t *musig_info_i = r_musig_aggr_key_info(&kp1->m.musig_info); + const uint16_t *key_indexes_i = r_uint16(&musig_info_i->key_indexes); + const musig_aggr_key_info_t *musig_info_j = r_musig_aggr_key_info(&kp2->m.musig_info); + const uint16_t *key_indexes_j = r_uint16(&musig_info_j->key_indexes); + + // two musig key expressions have identical placeholders if and only if they have + // exactly the same set of key indexes + + if (musig_info_i->n != musig_info_j->n) { + return false; // cannot be the same set if the size is different + } + + uint16_t key_indexes_i_sorted[MAX_PUBKEYS_PER_MUSIG]; + uint16_t key_indexes_j_sorted[MAX_PUBKEYS_PER_MUSIG]; + memcpy(key_indexes_i_sorted, key_indexes_i, musig_info_i->n * sizeof(uint16_t)); + memcpy(key_indexes_j_sorted, key_indexes_j, musig_info_j->n * sizeof(uint16_t)); + + // sort the arrays + sort_uint16_array(key_indexes_i_sorted, musig_info_i->n); + sort_uint16_array(key_indexes_j_sorted, musig_info_j->n); + + if (memcmp(key_indexes_i_sorted, + key_indexes_j_sorted, + musig_info_i->n * sizeof(uint16_t)) != 0) { + return false; // different set of keys + } + return true; + } else { + LEDGER_ASSERT(false, "Unknown key expression type"); + return false; + } + LEDGER_ASSERT(false, "Unreachable code"); +} + int is_policy_sane(dispatcher_context_t *dispatcher_context, const policy_node_t *policy, int wallet_version, @@ -1997,10 +2039,10 @@ int is_policy_sane(dispatcher_context_t *dispatcher_context, } } - // The following loop is computationally very inefficient (quadratic in the number of - // key expressions), but more efficient solutions likely require a substantial amount of RAM - // (proportional to the number of key expressions). Instead, this only requires stack depth - // proportional to the depth of the wallet policy's abstract syntax tree. + // The following loop is computationally very inefficient, but more efficient solutions likely + // require a substantial amount of RAM and/or more complex code. + // As it's unlikely that the number of keys in a wallet policy will be large enough for this to, + // matther, we rather keep the code as simple as possible. for (int i = 0; i < n_key_expressions - 1; i++) { // no point in running this for the last key expression policy_node_keyexpr_t *kp_i; @@ -2014,12 +2056,13 @@ int is_policy_sane(dispatcher_context_t *dispatcher_context, "Unexpected error retrieving key expressions from the policy"); } - if ((kp_i->type == KEY_EXPRESSION_NORMAL && kp_j->type == KEY_EXPRESSION_MUSIG) || - (kp_i->type == KEY_EXPRESSION_MUSIG && kp_j->type == KEY_EXPRESSION_NORMAL)) { - // if one is a key and the other is a musig, there's nothing else to check - continue; - } else if (kp_i->type == KEY_EXPRESSION_NORMAL && kp_j->type == KEY_EXPRESSION_NORMAL) { - // key expressions for the same key must have disjoint derivation options + // There is nothing to check for two placeholders that are not identical. + // If they are identical, we make sure that the derivations are disjoint, as per + // BIP-388. Note that this means that we do not enforce that _all_ the keys in different + // musig placeholders are disjoint, as long as they are not exactly the same set of + // keys. Similarly, a key used in a normal placeholder could also be part of the set of + // keys in a musig placeholder. + if (are_key_placeholders_identical(kp_i, kp_j)) { if (kp_i->k.key_index == kp_j->k.key_index) { if (kp_i->num_first == kp_j->num_first || kp_i->num_first == kp_j->num_second || kp_i->num_second == kp_j->num_first || @@ -2029,47 +2072,6 @@ int is_policy_sane(dispatcher_context_t *dispatcher_context, "Key expressions with repeated derivations in miniscript"); } } - } else if (kp_i->type == KEY_EXPRESSION_MUSIG && kp_j->type == KEY_EXPRESSION_MUSIG) { - const musig_aggr_key_info_t *musig_info_i = - r_musig_aggr_key_info(&kp_i->m.musig_info); - const uint16_t *key_indexes_i = r_uint16(&musig_info_i->key_indexes); - const musig_aggr_key_info_t *musig_info_j = - r_musig_aggr_key_info(&kp_j->m.musig_info); - const uint16_t *key_indexes_j = r_uint16(&musig_info_j->key_indexes); - // if two musigs have exactly the same set of keys, then the derivation options must - // be disjoint - - // make sure that there is no repeated key in the first musig - - if (musig_info_i->n != musig_info_j->n) { - continue; // cannot be the same set if the size is different - } - - uint16_t key_indexes_i_sorted[MAX_PUBKEYS_PER_MUSIG]; - uint16_t key_indexes_j_sorted[MAX_PUBKEYS_PER_MUSIG]; - memcpy(key_indexes_i_sorted, key_indexes_i, musig_info_i->n * sizeof(uint16_t)); - memcpy(key_indexes_j_sorted, key_indexes_j, musig_info_j->n * sizeof(uint16_t)); - - // sort the arrays - sort_uint16_array(key_indexes_i_sorted, musig_info_i->n); - sort_uint16_array(key_indexes_j_sorted, musig_info_j->n); - - if (memcmp(key_indexes_i_sorted, - key_indexes_j_sorted, - musig_info_i->n * sizeof(uint16_t)) != 0) { - continue; // different set of keys - } - - // same set of keys; therefore, we need to check that the derivation options are - // disjoint - if (kp_i->num_first == kp_j->num_first || kp_i->num_first == kp_j->num_second || - kp_i->num_second == kp_j->num_first || kp_i->num_second == kp_j->num_second) { - return WITH_ERROR(-1, - "Key expressions with repeated derivations in miniscript"); - } - - } else { - LEDGER_ASSERT(false, "Unexpected key expression type"); } } } From 712bfa703d3369b1aae6d063af50dd8a7e36552b Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 5 Nov 2024 18:29:43 +0000 Subject: [PATCH 32/57] [WIP] Musig2 e2e tests --- tests/test_e2e_musig2.py | 385 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 385 insertions(+) create mode 100644 tests/test_e2e_musig2.py diff --git a/tests/test_e2e_musig2.py b/tests/test_e2e_musig2.py new file mode 100644 index 000000000..1cda4d8e4 --- /dev/null +++ b/tests/test_e2e_musig2.py @@ -0,0 +1,385 @@ +import pytest + +from typing import Dict, List, Tuple + +import hmac +from hashlib import sha256 +from decimal import Decimal + +from ledger_bitcoin.exception.errors import IncorrectDataError, NotSupportedError +from ledger_bitcoin.exception.device_exception import DeviceException +from ledger_bitcoin.psbt import PSBT +from ledger_bitcoin.wallet import WalletPolicy +from ledger_bitcoin import MusigPubNonce, MusigPartialSignature, PartialSignature, SignPsbtYieldedObject + +from test_utils import SpeculosGlobals, bip0327, get_internal_xpub, count_internal_key_placeholders +from test_utils.musig2 import PsbtMusig2Cosigner + +from ragger_bitcoin import RaggerClient +from ragger_bitcoin.ragger_instructions import Instructions +from ragger.navigator import Navigator +from ragger.firmware import Firmware +from ragger.error import ExceptionRAPDU + +from .instructions import e2e_register_wallet_instruction, e2e_sign_psbt_instruction + +from .conftest import AuthServiceProxy, create_new_wallet, generate_blocks, get_unique_wallet_name, get_wallet_rpc, import_descriptors_with_privkeys, testnet_to_regtest_addr as T + + +class BitcoinCoreMusig2Cosigner(PsbtMusig2Cosigner): + """ + Implements a PsbtMusig2Cosigner for a given wallet policy using bitcoin-core. + """ + + def __init__(self, wallet_policy: WalletPolicy, rpc) -> None: + super().__init__() + + self.wallet_policy = wallet_policy + self.rpc = rpc + + self.musig_psbt_sessions: Dict[bytes, bytes] = {} + + def compute_psbt_session_id(self, psbt: PSBT) -> bytes: + psbt.tx.rehash() + return sha256(psbt.tx.hash + self.wallet_policy.id) + + def get_participant_pubkey(self) -> bip0327.Point: + raise NotImplementedError() + + def generate_public_nonces(self, psbt: PSBT) -> None: + raise NotImplementedError() + + def generate_partial_signatures(self, psbt: PSBT) -> None: + raise NotImplementedError() + + +def run_test_e2e_musig2(navigator: Navigator, client: RaggerClient, wallet_policy: WalletPolicy, core_wallet_names: List[str], rpc: AuthServiceProxy, rpc_test_wallet: AuthServiceProxy, speculos_globals: SpeculosGlobals, + instructions_register_wallet: Instructions, + instructions_sign_psbt: Instructions, test_name: str): + # TODO: delete + def printb(*args): + print('\033[94m', end='') + print(*args) + print('\033[0m', end='') + + wallet_id, wallet_hmac = client.register_wallet(wallet_policy, navigator, + instructions=instructions_register_wallet, testname=f"{test_name}_register") + + assert wallet_id == wallet_policy.id + + assert hmac.compare_digest( + hmac.new(speculos_globals.wallet_registration_key, + wallet_id, sha256).digest(), + wallet_hmac, + ) + + # TODO: reenable registration above and delete this + wallet_hmac = hmac.new(speculos_globals.wallet_registration_key, + wallet_policy.id, sha256).digest() + + address_hww = client.get_wallet_address( + wallet_policy, wallet_hmac, 0, 3, False) + + # ==> verify the address matches what bitcoin-core computes + receive_descriptor = wallet_policy.get_descriptor(change=False) + receive_descriptor_info = rpc.getdescriptorinfo(receive_descriptor) + # bitcoin-core adds the checksum, and requires it for other calls + receive_descriptor_chk: str = receive_descriptor_info["descriptor"] + address_core = rpc.deriveaddresses(receive_descriptor_chk, [3, 3])[0] + + assert T(address_hww) == address_core + + # also get the change descriptor for later + change_descriptor = wallet_policy.get_descriptor(change=True) + change_descriptor_info = rpc.getdescriptorinfo(change_descriptor) + change_descriptor_chk: str = change_descriptor_info["descriptor"] + + printb("Receive descriptor:", receive_descriptor_chk) # TODO: remove + printb("Change descriptor:", change_descriptor_chk) # TODO: remove + + # ==> import wallet in bitcoin-core + + new_core_wallet_name = get_unique_wallet_name() + rpc.createwallet( + wallet_name=new_core_wallet_name, + disable_private_keys=True, + descriptors=True, + ) + core_wallet_rpc = get_wallet_rpc(new_core_wallet_name) + + core_wallet_rpc.importdescriptors([{ + "desc": receive_descriptor_chk, + "active": True, + "internal": False, + "timestamp": "now" + }, { + "desc": change_descriptor_chk, + "active": True, + "internal": True, + "timestamp": "now" + }]) + + # ==> fund the wallet and get prevout info + + rpc_test_wallet.sendtoaddress(T(address_hww), "0.1") + generate_blocks(1) + + assert core_wallet_rpc.getwalletinfo()["balance"] == Decimal("0.1") + + # ==> prepare a psbt spending from the wallet + + out_address = rpc_test_wallet.getnewaddress() + + result = core_wallet_rpc.walletcreatefundedpsbt( + outputs={ + out_address: Decimal("0.01") + }, + options={ + # We need a fixed position to be able to know how to navigate in the flows + "changePosition": 1 + } + ) + + # ==> import descriptor for each bitcoin-core wallet + for core_wallet_name in core_wallet_names: + import_descriptors_with_privkeys( + core_wallet_name, receive_descriptor_chk, change_descriptor_chk) + + psbt_b64 = result["psbt"] + + printb("PSBT before the first round:") + printb(psbt_b64) + + # Round 1: get nonces + + # ==> get nonce from the hww + + n_internal_keys = count_internal_key_placeholders( + speculos_globals.seed, "test", wallet_policy) + + psbt = PSBT() + psbt.deserialize(psbt_b64) + + hww_yielded: List[Tuple[int, SignPsbtYieldedObject]] = client.sign_psbt(psbt, wallet_policy, wallet_hmac, navigator, + instructions=instructions_sign_psbt, + testname=f"{test_name}_sign") + + printb("SignPsbt yielded:", hww_yielded) + for (input_index, yielded) in hww_yielded: + if isinstance(yielded, MusigPubNonce): + printb(f"Yielded MusigPubNonce for input {input_index}:") + printb(yielded.participant_pubkey.hex(), yielded.aggregate_pubkey.hex( + ), None if yielded.tapleaf_hash is None else yielded.tapleaf_hash.hex()) + psbt_key = ( + yielded.participant_pubkey, + yielded.aggregate_pubkey, + yielded.tapleaf_hash + ) + + assert len(yielded.aggregate_pubkey) == 33 + + psbt.inputs[input_index].musig2_pub_nonces[psbt_key] = yielded.pubnonce + elif isinstance(yielded, PartialSignature): + # depending on the policy, a PartialSignature might be returned + pass + else: + # We don't expect a MusigPartialSignature here + raise ValueError( + f"sign_psbt yielded an unexpected object for input {input_index}:", yielded) + + # should be true as long as all inputs are internal + assert len(hww_yielded) == n_internal_keys * len(psbt.inputs) + + signed_psbt_hww_b64 = psbt.serialize() + + printb("PSBT after the first round for the hww:", signed_psbt_hww_b64) + + # ==> Process it with bitcoin-core to get the musig pubnonces + partial_psbts = [signed_psbt_hww_b64] + + # partial_psbts = [] + + for core_wallet_name in core_wallet_names: + printb("Processing for:", core_wallet_name) + psbt_res = get_wallet_rpc( + core_wallet_name).walletprocesspsbt(psbt_b64)["psbt"] + printb("PSBT processed by core:") + printb(psbt_res) + partial_psbts.append(psbt_res) + + combined_psbt = rpc.combinepsbt(partial_psbts) + + # Round 2: get Musig Partial Signatures + + printb(wallet_policy.get_descriptor(None)) + + # TODO: should now do the second round + printb("PSBT after the first round:", combined_psbt) + + printb("Starting round 2") + + psbt = PSBT() + psbt.deserialize(combined_psbt) + + hww_yielded: List[Tuple[int, SignPsbtYieldedObject]] = client.sign_psbt(psbt, wallet_policy, wallet_hmac, navigator, + instructions=instructions_sign_psbt, + testname=f"{test_name}_sign") + + printb("SignPsbt yielded:", hww_yielded) + for (input_index, yielded) in hww_yielded: + if isinstance(yielded, MusigPartialSignature): + psbt_key = ( + yielded.participant_pubkey, + yielded.aggregate_pubkey, + yielded.tapleaf_hash + ) + + assert len(yielded.aggregate_pubkey) == 33 + + psbt.inputs[input_index].musig2_partial_sigs[psbt_key] = yielded.partial_signature + elif isinstance(yielded, PartialSignature): + # depending on the policy, a PartialSignature might be returned + pass + else: + # We don't expect a MusigPubNonce here, we should be in the second round + raise ValueError( + f"sign_psbt yielded an unexpected object for input {input_index}:", yielded) + + # should be true as long as all inputs are internal + assert len(hww_yielded) == n_internal_keys * len(psbt.inputs) + + signed_psbt_hww_b64 = psbt.serialize() + + printb("PSBT after the second round for the hww:", signed_psbt_hww_b64) + + # ==> Get Musig partial signatures with each bitcoin-core wallet + + partial_psbts = [signed_psbt_hww_b64] + for core_wallet_name in core_wallet_names: + printb("Processing for:", core_wallet_name) + psbt_res = get_wallet_rpc( + core_wallet_name).walletprocesspsbt(combined_psbt)["psbt"] + printb("PSBT processed by core:") + printb(psbt_res) + partial_psbts.append(psbt_res) + + # ==> finalize the psbt, extract tx and broadcast + combined_psbt = rpc.combinepsbt(partial_psbts) + result = rpc.finalizepsbt(combined_psbt) + + assert result["complete"] == True + rawtx = result["hex"] + + # make sure the transaction is valid by broadcasting it (would fail if rejected) + rpc.sendrawtransaction(rawtx) + + +def run_test_invalid(client: RaggerClient, descriptor_template: str, keys_info: List[str]): + wallet_policy = WalletPolicy( + name="Invalid wallet", + descriptor_template=descriptor_template, + keys_info=keys_info) + + with pytest.raises(ExceptionRAPDU) as e: + client.register_wallet(wallet_policy) + assert DeviceException.exc.get(e.value.status) == IncorrectDataError or DeviceException.exc.get( + e.value.status) == NotSupportedError + + +def test_e2e_musig2_keypath(navigator: Navigator, firmware: Firmware, client: RaggerClient, + test_name: str, rpc, rpc_test_wallet, speculos_globals: SpeculosGlobals): + path = "48'/1'/0'/2'" + internal_xpub = get_internal_xpub(speculos_globals.seed, path) + + core_wallet_name, core_xpub_orig = create_new_wallet() + wallet_policy = WalletPolicy( + name="Musig 2 my ears", + descriptor_template="tr(musig(@0,@1)/**)", + keys_info=[ + f"[{speculos_globals.master_key_fingerprint.hex()}/{path}]{internal_xpub}", + f"{core_xpub_orig}", + ]) + + run_test_e2e_musig2(navigator, client, wallet_policy, [core_wallet_name], rpc, rpc_test_wallet, speculos_globals, + e2e_register_wallet_instruction(firmware, wallet_policy.n_keys), e2e_sign_psbt_instruction(firmware), test_name) + + +def test_e2e_musig2_scriptpath(navigator: Navigator, firmware: Firmware, client: RaggerClient, + test_name: str, rpc, rpc_test_wallet, speculos_globals: SpeculosGlobals): + path = "48'/1'/0'/2'" + internal_xpub = get_internal_xpub(speculos_globals.seed, path) + + core_wallet_name, core_xpub_orig = create_new_wallet() + + # In this policy, the keypath is unspendable + + wallet_policy = WalletPolicy( + name="Musig 2 my ears", + descriptor_template="tr(@0/**,pk(musig(@1,@2)/**))", + keys_info=[ + "tpubD6NzVbkrYhZ4WLczPJWReQycCJdd6YVWXubbVUFnJ5KgU5MDQrD998ZJLSmaB7GVcCnJSDWprxmrGkJ6SvgQC6QAffVpqSvonXmeizXcrkN", + f"[{speculos_globals.master_key_fingerprint.hex()}/{path}]{internal_xpub}", + f"{core_xpub_orig}", + ]) + + run_test_e2e_musig2(navigator, client, wallet_policy, [core_wallet_name], rpc, rpc_test_wallet, speculos_globals, + e2e_register_wallet_instruction(firmware, wallet_policy.n_keys), e2e_sign_psbt_instruction(firmware), test_name) + + +def test_e2e_musig2_3of3keypath_decaying_scriptpath(navigator: Navigator, firmware: Firmware, client: RaggerClient, + test_name: str, rpc, rpc_test_wallet, speculos_globals: SpeculosGlobals): + path = "48'/1'/0'/2'" + internal_xpub = get_internal_xpub(speculos_globals.seed, path) + + core_wallet_name_1, core_xpub_orig_1 = create_new_wallet() + core_wallet_name_2, core_xpub_orig_2 = create_new_wallet() + + wallet_policy = WalletPolicy( + name="3-of-3-to-2-of-3", + descriptor_template="tr(musig(@0,@1,@2)/**,and_v(v:multi_a(2,@0/**,@1/**,@2/**),older(12960)))", + keys_info=[ + f"{core_xpub_orig_1}", + f"[{speculos_globals.master_key_fingerprint.hex()}/{path}]{internal_xpub}", + f"{core_xpub_orig_2}", + ]) + + run_test_e2e_musig2(navigator, client, wallet_policy, [core_wallet_name_1, core_wallet_name_2], rpc, rpc_test_wallet, speculos_globals, + e2e_register_wallet_instruction(firmware, wallet_policy.n_keys), e2e_sign_psbt_instruction(firmware), test_name) + + +def test_e2e_musig_invalid(client: RaggerClient, speculos_globals: SpeculosGlobals): + path = "48'/1'/0'/2'" + text_xpub_1 = "tpubDCwYjpDhUdPGP5rS3wgNg13mTrrjBuG8V9VpWbyptX6TRPbNoZVXsoVUSkCjmQ8jJycjuDKBb9eataSymXakTTaGifxR6kmVsfFehH1ZgJT" + internal_xpub = get_internal_xpub(speculos_globals.seed, path) + internal_xpub_orig = f"[{speculos_globals.master_key_fingerprint.hex()}/{path}]{internal_xpub}" + + # Some of these tests are for script syntax that is not currently supported in wallet policies. + # Still worth adding the tests, as they should stay invalid even if such syntax is supported in the future. + + two_keys = [internal_xpub_orig, text_xpub_1] + + # no musig solo + run_test_invalid(client, "tr(musig(@0)/**))", [internal_xpub_orig]) + + # Invalid per BIP-390 + run_test_invalid(client, "pk(musig(@0,@1)/**)", two_keys) + run_test_invalid(client, "pkh(musig(@0,@1)/**)", two_keys) + run_test_invalid(client, "wpkh(musig(@0,@1)/**)", two_keys) + run_test_invalid(client, "combo(musig(@0,@1)/**)", two_keys) + run_test_invalid(client, "sh(wpkh(musig(@0,@1)/**))", two_keys) + run_test_invalid(client, "sh(wsh(musig(@0,@1)/**))", two_keys) + run_test_invalid(client, "wsh(musig(@0,@1)/**)", two_keys) + run_test_invalid(client, "sh(musig(@0,@1)/**)", two_keys) + run_test_invalid(client, "sh(musig(@0/**,@1/**)/**)", two_keys) + + # nonsensical + run_test_invalid(client, "musig(@0,@1)/**", two_keys) + + # Invalid per BIP-388 + run_test_invalid(client, "tr(musig(@0,@0,@1)/**))", two_keys) + run_test_invalid( # repeated musig() placeholders + client, "tr(musig(@0,@1)/**,pk(musig(@1,@0)/**))", two_keys) + run_test_invalid(client, "tr(musig(@0,@1))", two_keys) + + # supported in BIP-390, not in BIP-388 + run_test_invalid(client, "tr(musig(@0/**,@1/**))", two_keys) From 34f27463471f280b0b8b5eb529ce15bd40f102e6 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:26:32 +0000 Subject: [PATCH 33/57] [CI] Use custom image for bitcoin from achow101's branch with MuSig2 support --- .github/workflows/build_and_functional_tests.yml | 2 +- tests/conftest.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_and_functional_tests.yml b/.github/workflows/build_and_functional_tests.yml index 7e57e5c65..785c546a5 100644 --- a/.github/workflows/build_and_functional_tests.yml +++ b/.github/workflows/build_and_functional_tests.yml @@ -31,4 +31,4 @@ jobs: uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_ragger_tests.yml@v1 with: download_app_binaries_artifact: "compiled_app_binaries" - + container_image: "ghcr.io/ledgerhq/app-bitcoin-new/speculos-bitcoin-musig2:latest" diff --git a/tests/conftest.py b/tests/conftest.py index 23693c417..ab40a51e7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -103,7 +103,7 @@ def run_bitcoind(): # Run bitcoind in a separate folder os.makedirs(BITCOIN_DIRNAME, exist_ok=True) - bitcoind = os.getenv("BITCOIND", "/bitcoin/bin/bitcoind") + bitcoind = os.getenv("BITCOIND", "bitcoind") shutil.copy(os.path.join(os.path.dirname(__file__), "bitcoin.conf"), BITCOIN_DIRNAME) From ce066d7ee9442244d074aacd620ed771933cf233 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:44:58 +0000 Subject: [PATCH 34/57] Reduce maximum supported number of keys in musig to 5 --- src/common/wallet.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/common/wallet.h b/src/common/wallet.h index 84db3ecf4..e50584805 100644 --- a/src/common/wallet.h +++ b/src/common/wallet.h @@ -21,7 +21,10 @@ // The maximum number of keys supported in a musig() key expression // It is basically unlimited in theory, but we need to set a practical limit. -#define MAX_PUBKEYS_PER_MUSIG MAX_PUBKEYS_PER_MULTISIG +// The implementation of MuSig2 requires quite a few large arrays (for example, the pubnonces are +// 66 bytes each, and there is one for each cosigner), therefore we keep this quite small. +// Increasing this might require optimizing the memory management in the MuSig2 implementation. +#define MAX_PUBKEYS_PER_MUSIG 5 #define WALLET_POLICY_VERSION_V1 1 // the legacy version of the first release #define WALLET_POLICY_VERSION_V2 2 // the current full version From ac4a48c564e60d33bf036b7df8c84d2dc7f4d71f Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 18 Nov 2024 14:10:22 +0000 Subject: [PATCH 35/57] Move sign_psbt_cache to global space to reduce stack usage --- src/handler/sign_psbt.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index c09637aa4..0686ab998 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -3317,6 +3317,13 @@ sign_transaction(dispatcher_context_t *dc, return true; } +// We declare this in the global space in order to use less stack space, since BOLOS enforces on +// some device a 8kb stack limit. +// Once this is resolved in BOLOS, we should move this to the function scope to avoid unnecessarily +// reserving RAM that can only be used for the signing flow (which, at time of writing, is the most +// RAM-intensive operation command of the app). +sign_psbt_cache_t G_sign_psbt_cache; + void handler_sign_psbt(dispatcher_context_t *dc, uint8_t protocol_version) { LOG_PROCESSOR(__FILE__, __LINE__, __func__); @@ -3328,8 +3335,8 @@ void handler_sign_psbt(dispatcher_context_t *dc, uint8_t protocol_version) { // read APDU inputs, intialize global state and read global PSBT map if (!init_global_state(dc, &st)) return; - sign_psbt_cache_t cache; - init_sign_psbt_cache(&cache); + sign_psbt_cache_t *cache = &G_sign_psbt_cache; + init_sign_psbt_cache(cache); // bitmap to keep track of which inputs are internal uint8_t internal_inputs[BITVECTOR_REAL_SIZE(MAX_N_INPUTS_CAN_SIGN)]; @@ -3347,14 +3354,14 @@ void handler_sign_psbt(dispatcher_context_t *dc, uint8_t protocol_version) { * - detect internal inputs that should be signed, and if there are external inputs or unusual * sighashes */ - if (!preprocess_inputs(dc, &st, &cache, internal_inputs)) return; + if (!preprocess_inputs(dc, &st, cache, internal_inputs)) return; /** OUTPUTS VERIFICATION FLOW * * For each output, check if it's a change address. * Check if it's an acceptable output. */ - if (!preprocess_outputs(dc, &st, &cache, internal_outputs)) return; + if (!preprocess_outputs(dc, &st, cache, internal_outputs)) return; if (G_swap_state.called_from_swap) { /** SWAP CHECKS @@ -3380,7 +3387,7 @@ void handler_sign_psbt(dispatcher_context_t *dc, uint8_t protocol_version) { * For each internal key expression, and for each internal input, sign using the * appropriate algorithm. */ - int sign_result = sign_transaction(dc, &st, &cache, internal_inputs); + int sign_result = sign_transaction(dc, &st, cache, internal_inputs); if (!G_swap_state.called_from_swap) { ui_post_processing_confirm_transaction(dc, sign_result); From 9645d2577223e1f1856f9195abd55c6756bc9e4b Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:40:23 +0000 Subject: [PATCH 36/57] Add array of all internal key expressions in sign_psbt_state_t --- src/constants.h | 7 +++ src/error_codes.h | 3 + src/handler/sign_psbt.c | 118 +++++++++++++++++++++++----------------- 3 files changed, 78 insertions(+), 50 deletions(-) diff --git a/src/constants.h b/src/constants.h index 4fd326a10..cd4f88aa1 100644 --- a/src/constants.h +++ b/src/constants.h @@ -51,6 +51,13 @@ */ #define MAX_N_OUTPUTS_CAN_SIGN 512 +/** + * Maximum supported number of internal key expressions in a wallet policy. + * A key expression is internal if we can sign for it (either as an individual key, + * or as part of a MuSig key expression). + */ +#define MAX_INTERNAL_KEY_EXPRESSIONS 8 + // SIGHASH flags #define SIGHASH_DEFAULT 0x00000000 #define SIGHASH_ALL 0x00000001 diff --git a/src/error_codes.h b/src/error_codes.h index feb283670..9782a491f 100644 --- a/src/error_codes.h +++ b/src/error_codes.h @@ -56,6 +56,9 @@ // The redeem Script in the PSBT is incorrect. #define EC_SIGN_PSBT_MISMATCHING_REDEEM_SCRIPT 0x000b +// The wallet policy has too many internal keys. +#define EC_SIGN_PSBT_WALLET_POLICY_TOO_MANY_INTERNAL_KEYS 0x000c + /** * Swap */ diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 0686ab998..d90d6ed8e 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -110,7 +110,8 @@ typedef struct { typedef struct { policy_node_keyexpr_t *key_expression_ptr; - int cur_index; + // index of this key expression in the descriptor template, in parsing order + int index; uint32_t fingerprint; // info about the internal key of this key expression @@ -160,6 +161,9 @@ typedef struct { uint32_t tx_version; uint32_t locktime; + unsigned int n_internal_key_expressions; + keyexpr_info_t internal_key_expressions[MAX_INTERNAL_KEY_EXPRESSIONS]; + unsigned int n_inputs; uint8_t inputs_root[32]; // merkle root of the vector of input maps commitments unsigned int n_outputs; @@ -819,41 +823,6 @@ static bool fill_keyexpr_info_if_internal(dispatcher_context_t *dc, } } -// finds the first key expression that corresponds to an internal key -static bool find_first_internal_keyexpr(dispatcher_context_t *dc, - sign_psbt_state_t *st, - keyexpr_info_t *keyexpr_info) { - keyexpr_info->cur_index = 0; - - // find and parse our registered key info in the wallet - while (true) { - int n_key_expressions = get_keyexpr_by_index(st->wallet_policy_map, - keyexpr_info->cur_index, - NULL, - &keyexpr_info->key_expression_ptr); - if (n_key_expressions < 0) { - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } - - if (keyexpr_info->cur_index >= n_key_expressions) { - // all keys have been processed - break; - } - - if (fill_keyexpr_info_if_internal(dc, st, keyexpr_info)) { - return true; - } - - // Not an internal key, move on - ++keyexpr_info->cur_index; - } - - PRINTF("No internal key found in wallet policy"); - SEND_SW_EC(dc, SW_INCORRECT_DATA, EC_SIGN_PSBT_WALLET_POLICY_HAS_NO_INTERNAL_KEY); - return false; -} - typedef struct { keyexpr_info_t *keyexpr_info; input_info_t *input; @@ -896,6 +865,58 @@ static void input_keys_callback(dispatcher_context_t *dc, } } +static bool fill_internal_key_expressions(dispatcher_context_t *dc, sign_psbt_state_t *st) { + size_t cur_index = 0; + + st->n_internal_key_expressions = 0; + memset(st->internal_key_expressions, 0, sizeof(st->internal_key_expressions)); + + // find and parse our registered key info in the wallet + keyexpr_info_t keyexpr_info; + while (true) { + int n_key_expressions = get_keyexpr_by_index(st->wallet_policy_map, + cur_index, + NULL, + &keyexpr_info.key_expression_ptr); + if (n_key_expressions < 0) { + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + if (cur_index >= (size_t) n_key_expressions) { + // all keys have been processed + break; + } + + if (fill_keyexpr_info_if_internal(dc, st, &keyexpr_info)) { + if (st->n_internal_key_expressions >= MAX_INTERNAL_KEY_EXPRESSIONS) { + PRINTF("Too many internal key expressions. The maximum supported is %d\n", + MAX_INTERNAL_KEY_EXPRESSIONS); + SEND_SW_EC(dc, SW_NOT_SUPPORTED, EC_SIGN_PSBT_WALLET_POLICY_TOO_MANY_INTERNAL_KEYS); + return false; + } + + // store this key info, as it's internal + memcpy(&st->internal_key_expressions[st->n_internal_key_expressions], + &keyexpr_info, + sizeof(keyexpr_info_t)); + ++st->n_internal_key_expressions; + keyexpr_info.index = 0; + } + + // Not an internal key, move on + ++cur_index; + } + + if (st->n_internal_key_expressions == 0) { + PRINTF("No internal key found in wallet policy"); + SEND_SW_EC(dc, SW_INCORRECT_DATA, EC_SIGN_PSBT_WALLET_POLICY_HAS_NO_INTERNAL_KEY); + return false; + } + + return true; +} + static bool __attribute__((noinline)) preprocess_inputs(dispatcher_context_t *dc, sign_psbt_state_t *st, @@ -905,17 +926,17 @@ preprocess_inputs(dispatcher_context_t *dc, memset(internal_inputs, 0, BITVECTOR_REAL_SIZE(MAX_N_INPUTS_CAN_SIGN)); - keyexpr_info_t keyexpr_info; - memset(&keyexpr_info, 0, sizeof(keyexpr_info)); - - if (!find_first_internal_keyexpr(dc, st, &keyexpr_info)) return false; + if (!fill_internal_key_expressions(dc, st)) return false; // process each input for (unsigned int cur_input_index = 0; cur_input_index < st->n_inputs; cur_input_index++) { input_info_t input; memset(&input, 0, sizeof(input)); - input_keys_callback_data_t callback_data = {.input = &input, .keyexpr_info = &keyexpr_info}; + input_keys_callback_data_t callback_data = { + .input = &input, + // it doesn't matter which key expression we use here + .keyexpr_info = &st->internal_key_expressions[0]}; int res = call_get_merkleized_map_with_callback( dc, (void *) &callback_data, @@ -1162,11 +1183,6 @@ preprocess_outputs(dispatcher_context_t *dc, LOG_PROCESSOR(__FILE__, __LINE__, __func__); - keyexpr_info_t keyexpr_info; - memset(&keyexpr_info, 0, sizeof(keyexpr_info)); - - if (!find_first_internal_keyexpr(dc, st, &keyexpr_info)) return false; - memset(&st->outputs, 0, sizeof(st->outputs)); // the counter used when showing outputs to the user, which ignores change outputs @@ -1177,8 +1193,10 @@ preprocess_outputs(dispatcher_context_t *dc, output_info_t output; memset(&output, 0, sizeof(output)); - output_keys_callback_data_t callback_data = {.output = &output, - .keyexpr_info = &keyexpr_info}; + output_keys_callback_data_t callback_data = { + .output = &output, + // any internal key expression is good here + .keyexpr_info = &st->internal_key_expressions[0]}; int res = call_get_merkleized_map_with_callback( dc, (void *) &callback_data, @@ -2695,7 +2713,7 @@ sign_sighash_musig_and_yield(dispatcher_context_t *dc, // 5) generate and yield pubnonce uint8_t rand_i_j[32]; - compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->cur_index, rand_i_j); + compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->index, rand_i_j); musig_secnonce_t secnonce; musig_pubnonce_t pubnonce; @@ -2772,7 +2790,7 @@ sign_sighash_musig_and_yield(dispatcher_context_t *dc, // recompute secnonce from psbt_session randomness uint8_t rand_i_j[32]; - compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->cur_index, rand_i_j); + compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->index, rand_i_j); musig_secnonce_t secnonce; musig_pubnonce_t pubnonce; From 6184d44feca297007e599e50c6f05d81ecfd8063 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:29:34 +0000 Subject: [PATCH 37/57] Refactor input_keys_callback output_keys_callback to match against all the internal key expressions, instead of only the first --- src/handler/sign_psbt.c | 291 ++++++++++++++++++++++------------------ 1 file changed, 164 insertions(+), 127 deletions(-) diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index d90d6ed8e..f8001021b 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -114,6 +114,10 @@ typedef struct { int index; uint32_t fingerprint; + // we only sign for keys expressions for which we find a matching key derivation in the PSBT, + // at least for one of the inputs + bool to_sign; + // info about the internal key of this key expression // used at signing time to derive the correct key uint32_t key_derivation[MAX_BIP32_PATH_STEPS]; @@ -132,8 +136,10 @@ typedef struct { // internal key for musig key expressions serialized_extended_pubkey_t internal_pubkey; - bool is_tapscript; // true if signing with a BIP342 tapleaf script path spend - uint8_t tapleaf_hash[32]; // only used for tapscripts + bool is_tapscript; // true if signing with a BIP342 tapleaf script path spend + // only used for tapscripts + const policy_node_t *tapleaf_ptr; + uint8_t tapleaf_hash[32]; } keyexpr_info_t; // Cache for partial hashes during signing (avoid quadratic hashing for segwit transactions) @@ -398,19 +404,24 @@ static int get_amount_scriptpubkey_from_psbt( NULL); } -// Convenience function to share common logic when processing all the -// PSBT_{IN|OUT}_{TAP}?_BIP32_DERIVATION fields. +typedef struct { + uint32_t fingerprint; + size_t derivation_len; + uint32_t key_origin[MAX_BIP32_PATH_STEPS]; +} derivation_info_t; + +// Convenience function to share common logic when parsing the +// PSBT_{IN|OUT}_{TAP}?_BIP32_DERIVATION fields from inputs or outputs. // Note: This function must return -1 only on errors (causing signing to abort). -// It should return 1 if a derivation that makes sense for this input/output is found. -// It should return 0 otherwise (no match found, but continue the signing flow). +// It returns 1 if a that might match the wallet policy is found. +// It returns 0 otherwise (not a match, but continue the signing flow). static int read_change_and_index_from_psbt_bip32_derivation( dispatcher_context_t *dc, - const keyexpr_info_t *keyexpr_info, - in_out_info_t *in_out, int psbt_key_type, buffer_t *data, const merkleized_map_commitment_t *map_commitment, - int index) { + int index, + derivation_info_t *derivation_info) { uint8_t bip32_derivation_pubkey[33]; bool is_tap = psbt_key_type == PSBT_IN_TAP_BIP32_DERIVATION || @@ -423,7 +434,6 @@ static int read_change_and_index_from_psbt_bip32_derivation( || buffer_can_read(data, 1) // ...but should not be able to read more ) { PRINTF("Unexpected pubkey length\n"); - in_out->unexpected_pubkey_error = true; return -1; } @@ -447,35 +457,34 @@ static int read_change_and_index_from_psbt_bip32_derivation( return 0; } - // if this derivation path matches the internal key expression, - // we use it to detect whether the current input is change or not, - // and store its address index - if (fpt_der[0] == keyexpr_info->fingerprint && - der_len == keyexpr_info->psbt_root_key_derivation_length + 2) { - for (int i = 0; i < keyexpr_info->psbt_root_key_derivation_length; i++) { - if (keyexpr_info->key_derivation[i] != fpt_der[1 + i]) { - return 0; - } - } + derivation_info->fingerprint = fpt_der[0]; + for (int i = 0; i < der_len; i++) { + derivation_info->key_origin[i] = fpt_der[i + 1]; + } + derivation_info->derivation_len = der_len; - uint32_t change_step = fpt_der[1 + der_len - 2]; - uint32_t addr_index = fpt_der[1 + der_len - 1]; + return 1; +} - // check if the 'change' derivation step is indeed coherent with key expression - if (change_step == keyexpr_info->key_expression_ptr->num_first) { - in_out->is_change = false; - in_out->address_index = addr_index; - } else if (change_step == keyexpr_info->key_expression_ptr->num_second) { - in_out->is_change = true; - in_out->address_index = addr_index; - } else { - return 0; +bool is_keyexpr_compatible_with_derivation_info(const keyexpr_info_t *keyexpr_info, + const derivation_info_t *derivation_info) { + if (keyexpr_info->fingerprint != derivation_info->fingerprint) { + return false; + } + if (keyexpr_info->psbt_root_key_derivation_length + 2 != derivation_info->derivation_len) { + return false; + } + for (int i = 0; i < keyexpr_info->psbt_root_key_derivation_length; i++) { + if (keyexpr_info->key_derivation[i] != derivation_info->key_origin[i]) { + return false; } - - in_out->key_expression_found = true; - return 1; } - return 0; + uint32_t change_step = derivation_info->key_origin[derivation_info->derivation_len - 2]; + if (change_step != keyexpr_info->key_expression_ptr->num_first && + change_step != keyexpr_info->key_expression_ptr->num_second) { + return false; + } + return true; } /** @@ -824,7 +833,7 @@ static bool fill_keyexpr_info_if_internal(dispatcher_context_t *dc, } typedef struct { - keyexpr_info_t *keyexpr_info; + sign_psbt_state_t *state; input_info_t *input; } input_keys_callback_data_t; @@ -835,7 +844,7 @@ typedef struct { static void input_keys_callback(dispatcher_context_t *dc, input_keys_callback_data_t *callback_data, const merkleized_map_commitment_t *map_commitment, - int i, + int index, buffer_t *data) { size_t data_len = data->size - data->offset; if (data_len >= 1) { @@ -849,17 +858,39 @@ static void input_keys_callback(dispatcher_context_t *dc, callback_data->input->has_redeemScript = true; } else if (key_type == PSBT_IN_SIGHASH_TYPE) { callback_data->input->has_sighash_type = true; - } else if ((key_type == PSBT_IN_BIP32_DERIVATION || - key_type == PSBT_IN_TAP_BIP32_DERIVATION) && - !callback_data->input->in_out.key_expression_found) { - if (0 > read_change_and_index_from_psbt_bip32_derivation(dc, - callback_data->keyexpr_info, - &callback_data->input->in_out, - key_type, - data, - map_commitment, - i)) { + } else if (key_type == PSBT_IN_BIP32_DERIVATION || + key_type == PSBT_IN_TAP_BIP32_DERIVATION) { + derivation_info_t derivation_info; + int res = read_change_and_index_from_psbt_bip32_derivation(dc, + key_type, + data, + map_commitment, + index, + &derivation_info); + if (res < 0) { + // there was an error; we keep track of it so an error SW is sent later callback_data->input->in_out.unexpected_pubkey_error = true; + } else if (res == 0) { + // nothing to do + } else if (res == 1) { + in_out_info_t *in_out = &callback_data->input->in_out; + for (size_t i = 0; i < callback_data->state->n_internal_key_expressions; i++) { + keyexpr_info_t *key_expr = &callback_data->state->internal_key_expressions[i]; + if (is_keyexpr_compatible_with_derivation_info(key_expr, &derivation_info)) { + key_expr->to_sign = true; + + bool is_change = + key_expr->key_expression_ptr->num_second == + derivation_info.key_origin[derivation_info.derivation_len - 2]; + + in_out->key_expression_found = true; + in_out->is_change = is_change; + in_out->address_index = + derivation_info.key_origin[derivation_info.derivation_len - 1]; + } + } + } else { + LEDGER_ASSERT(false, "Unreachable code"); } } } @@ -873,11 +904,20 @@ static bool fill_internal_key_expressions(dispatcher_context_t *dc, sign_psbt_st // find and parse our registered key info in the wallet keyexpr_info_t keyexpr_info; + memset(&keyexpr_info, 0, sizeof(keyexpr_info_t)); while (true) { + keyexpr_info.index = cur_index; + const policy_node_t *tapleaf_ptr = NULL; int n_key_expressions = get_keyexpr_by_index(st->wallet_policy_map, cur_index, - NULL, + &tapleaf_ptr, &keyexpr_info.key_expression_ptr); + if (tapleaf_ptr != NULL) { + // get_keyexpr_by_index returns the pointer to the tapleaf only if the key being + // spent is indeed in a tapleaf + keyexpr_info.tapleaf_ptr = tapleaf_ptr; + keyexpr_info.is_tapscript = true; + } if (n_key_expressions < 0) { SEND_SW(dc, SW_BAD_STATE); // should never happen return false; @@ -901,7 +941,6 @@ static bool fill_internal_key_expressions(dispatcher_context_t *dc, sign_psbt_st &keyexpr_info, sizeof(keyexpr_info_t)); ++st->n_internal_key_expressions; - keyexpr_info.index = 0; } // Not an internal key, move on @@ -933,10 +972,7 @@ preprocess_inputs(dispatcher_context_t *dc, input_info_t input; memset(&input, 0, sizeof(input)); - input_keys_callback_data_t callback_data = { - .input = &input, - // it doesn't matter which key expression we use here - .keyexpr_info = &st->internal_key_expressions[0]}; + input_keys_callback_data_t callback_data = {.input = &input, .state = st}; int res = call_get_merkleized_map_with_callback( dc, (void *) &callback_data, @@ -1137,7 +1173,7 @@ preprocess_inputs(dispatcher_context_t *dc, } typedef struct { - keyexpr_info_t *keyexpr_info; + sign_psbt_state_t *state; output_info_t *output; } output_keys_callback_data_t; @@ -1148,7 +1184,7 @@ typedef struct { static void output_keys_callback(dispatcher_context_t *dc, output_keys_callback_data_t *callback_data, const merkleized_map_commitment_t *map_commitment, - int i, + int index, buffer_t *data) { size_t data_len = data->size - data->offset; if (data_len >= 1) { @@ -1157,14 +1193,36 @@ static void output_keys_callback(dispatcher_context_t *dc, if ((key_type == PSBT_OUT_BIP32_DERIVATION || key_type == PSBT_OUT_TAP_BIP32_DERIVATION) && !callback_data->output->in_out.key_expression_found) { - if (0 > read_change_and_index_from_psbt_bip32_derivation(dc, - callback_data->keyexpr_info, - &callback_data->output->in_out, - key_type, - data, - map_commitment, - i)) { + derivation_info_t derivation_info; + int res = read_change_and_index_from_psbt_bip32_derivation(dc, + key_type, + data, + map_commitment, + index, + &derivation_info); + if (res < 0) { + // there was an error; we keep track of it so an error SW is sent later callback_data->output->in_out.unexpected_pubkey_error = true; + } else if (res == 1) { + in_out_info_t *in_out = &callback_data->output->in_out; + for (size_t i = 0; i < callback_data->state->n_internal_key_expressions; i++) { + const keyexpr_info_t *key_expr = + &callback_data->state->internal_key_expressions[i]; + if (is_keyexpr_compatible_with_derivation_info(key_expr, &derivation_info)) { + bool is_change = + key_expr->key_expression_ptr->num_second == + derivation_info.key_origin[derivation_info.derivation_len - 2]; + + in_out->key_expression_found = true; + in_out->is_change = is_change; + in_out->address_index = + derivation_info.key_origin[derivation_info.derivation_len - 1]; + // unlike for inputs, where we want to keep track of all the key expressions + // we want to sign for, here we only care about finding the relevant info + // for this output. Therefore, we're done as soon as we have a match. + break; + } + } } } } @@ -1193,10 +1251,7 @@ preprocess_outputs(dispatcher_context_t *dc, output_info_t output; memset(&output, 0, sizeof(output)); - output_keys_callback_data_t callback_data = { - .output = &output, - // any internal key expression is good here - .keyexpr_info = &st->internal_key_expressions[0]}; + output_keys_callback_data_t callback_data = {.output = &output, .state = st}; int res = call_get_merkleized_map_with_callback( dc, (void *) &callback_data, @@ -3255,74 +3310,56 @@ sign_transaction(dispatcher_context_t *dc, } // Iterate over all the key expressions that correspond to keys owned by us - while (true) { - keyexpr_info_t keyexpr_info; - memset(&keyexpr_info, 0, sizeof(keyexpr_info)); - - const policy_node_t *tapleaf_ptr = NULL; - int n_key_expressions = get_keyexpr_by_index(st->wallet_policy_map, - key_expression_index, - &tapleaf_ptr, - &keyexpr_info.key_expression_ptr); - - if (n_key_expressions < 0) { - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } - - if (key_expression_index >= n_key_expressions) { - // all key expressions were processed - break; + for (size_t i_keyexpr = 0; i_keyexpr < st->n_internal_key_expressions; i_keyexpr++) { + keyexpr_info_t *keyexpr_info = &st->internal_key_expressions[i_keyexpr]; + if (!keyexpr_info->to_sign) { + continue; } - if (tapleaf_ptr != NULL) { - // get_keyexpr_by_index returns the pointer to the tapleaf only if the key being - // spent is indeed in a tapleaf - keyexpr_info.is_tapscript = true; + if (!fill_keyexpr_info_if_internal(dc, st, keyexpr_info) == true) { + continue; } - if (fill_keyexpr_info_if_internal(dc, st, &keyexpr_info) == true) { - for (unsigned int i = 0; i < st->n_inputs; i++) - if (bitvector_get(internal_inputs, i)) { - input_info_t input; - memset(&input, 0, sizeof(input)); - - input_keys_callback_data_t callback_data = {.input = &input, - .keyexpr_info = &keyexpr_info}; - int res = call_get_merkleized_map_with_callback( - dc, - (void *) &callback_data, - st->inputs_root, - st->n_inputs, - i, - (merkle_tree_elements_callback_t) input_keys_callback, - &input.in_out.map); - if (res < 0) { - SEND_SW(dc, SW_INCORRECT_DATA); - return false; - } + for (unsigned int i = 0; i < st->n_inputs; i++) { + if (bitvector_get(internal_inputs, i)) { + input_info_t input; + memset(&input, 0, sizeof(input)); - if (tapleaf_ptr != NULL && !fill_taproot_keyexpr_info(dc, - st, - &input, - tapleaf_ptr, - &keyexpr_info, - sign_psbt_cache)) { - return false; - } + input_keys_callback_data_t callback_data = {.input = &input, .state = st}; + int res = call_get_merkleized_map_with_callback( + dc, + (void *) &callback_data, + st->inputs_root, + st->n_inputs, + i, + (merkle_tree_elements_callback_t) input_keys_callback, + &input.in_out.map); + if (res < 0) { + SEND_SW(dc, SW_INCORRECT_DATA); + return false; + } + if (keyexpr_info->tapleaf_ptr != NULL && + !fill_taproot_keyexpr_info(dc, + st, + &input, + keyexpr_info->tapleaf_ptr, + keyexpr_info, + sign_psbt_cache)) { + return false; + } - if (!sign_transaction_input(dc, - st, - sign_psbt_cache, - &signing_state, - &keyexpr_info, - &input, - i)) { - // we do not send a status word, since sign_transaction_input - // already does it on failure - return false; - } + if (!sign_transaction_input(dc, + st, + sign_psbt_cache, + &signing_state, + keyexpr_info, + &input, + i)) { + // we do not send a status word, since sign_transaction_input + // already does it on failure + return false; } + } } ++key_expression_index; From c5a3b9240511da4fe9e71440e61d18a55d5f5f8d Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:33:41 +0000 Subject: [PATCH 38/57] Added test for incomplete matching of BIP32 derivation paths in policies with multiple internal keys --- tests/test_sign_psbt.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_sign_psbt.py b/tests/test_sign_psbt.py index 1a9296e1a..2336155e5 100644 --- a/tests/test_sign_psbt.py +++ b/tests/test_sign_psbt.py @@ -964,3 +964,26 @@ def test_sign_psbt_against_wrong_tapleaf_hash(navigator: Navigator, firmware: Fi "9e646fb9e0452460944e49f8869f9ab9da90820da5d53841af9e1271a3bcf9ce") assert part_sig_2.tapleaf_hash == bytes.fromhex( "5b82996fe6cf1bf43868511181c64c965b7bf5f16f007acec52dede5288f9225") + + +def test_sign_psbt_multiple_derivation_paths(navigator: Navigator, firmware: Firmware, client: RaggerClient, test_name: str): + # A previous implementation of the app incompletely checked the derivation paths of keys in certain + # transactions when multiple internal in the policy; that wasn't detected in other tests, so this + # was added in order to avoid regressions. + wallet = WalletPolicy( + name="Cold storage", + descriptor_template="wsh(or_d(multi(4,@0/<0;1>/*,@1/<0;1>/*,@2/<0;1>/*,@3/<0;1>/*),and_v(v:thresh(3,pkh(@0/<2;3>/*),a:pkh(@1/<2;3>/*),a:pkh(@2/<2;3>/*),a:pkh(@3/<2;3>/*)),older(65535))))", + keys_info=["[f5acc2fd/48'/1'/0'/2']tpubDFAqEGNyad35aBCKUAXbQGDjdVhNueno5ZZVEn3sQbW5ci457gLR7HyTmHBg93oourBssgUxuWz1jX5uhc1qaqFo9VsybY1J5FuedLfm4dK", 'tpubDE7NQymr4AFtewpAsWtnreyq9ghkzQBXpCZjWLFVRAvnbf7vya2eMTvT2fPapNqL8SuVvLQdbUbMfWLVDCZKnsEBqp6UK93QEzL8Ck23AwF', + 'tpubDF4kujkh5dAhC1pFgBToZybXdvJFXXGX4BWdDxWqP7EUpG8gxkfMQeDjGPDnTr9e4NrkFmDM1ocav3Jz6x79CRZbxGr9dzFokJLuvDDnyRh', 'tpubDD3ULTdBbyuMMMs8BCsJKgZgEnZjjbsbtV6ig3xtkQnaSc1gu9kNhmDDEW49HoLzDNA4y2TMqRzj4BugrrtcpXkjoHSoMVhJwfZLUFmv6yn'] + ) + wallet_hmac = bytes.fromhex( + "8a0e67be3697449e4d1b19d6aaec634ce747cbcf35287887588028c9da250ab3") + + psbt_b64 = "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" + + result = client.sign_psbt(psbt_b64, wallet, wallet_hmac, navigator, + instructions=sign_psbt_instruction_approve( + firmware, has_spend_from_wallet=True, save_screenshot=False), + testname=test_name) + + assert len(result) == 2 From 1d25a27440017b93420e37eb611d89c71a2406d5 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:08:45 +0000 Subject: [PATCH 39/57] Test that only paths for which a key is present are indeed signed --- tests/test_sign_psbt.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/test_sign_psbt.py b/tests/test_sign_psbt.py index 2336155e5..f37237ff6 100644 --- a/tests/test_sign_psbt.py +++ b/tests/test_sign_psbt.py @@ -987,3 +987,44 @@ def test_sign_psbt_multiple_derivation_paths(navigator: Navigator, firmware: Fir testname=test_name) assert len(result) == 2 + + +def test_sign_psbt_multiple_derivation_paths(navigator: Navigator, firmware: Firmware, client: RaggerClient, test_name: str): + # A previous implementation of the app incompletely checked the derivation paths of keys in certain + # transactions when multiple internal in the policy; that wasn't detected in other tests, so this + # was added in order to avoid regressions. + wallet = WalletPolicy( + name="Cold storage", + descriptor_template="wsh(or_d(multi(4,@0/<0;1>/*,@1/<0;1>/*,@2/<0;1>/*,@3/<0;1>/*),and_v(v:thresh(3,pkh(@0/<2;3>/*),a:pkh(@1/<2;3>/*),a:pkh(@2/<2;3>/*),a:pkh(@3/<2;3>/*)),older(65535))))", + keys_info=["[f5acc2fd/48'/1'/0'/2']tpubDFAqEGNyad35aBCKUAXbQGDjdVhNueno5ZZVEn3sQbW5ci457gLR7HyTmHBg93oourBssgUxuWz1jX5uhc1qaqFo9VsybY1J5FuedLfm4dK", 'tpubDE7NQymr4AFtewpAsWtnreyq9ghkzQBXpCZjWLFVRAvnbf7vya2eMTvT2fPapNqL8SuVvLQdbUbMfWLVDCZKnsEBqp6UK93QEzL8Ck23AwF', + 'tpubDF4kujkh5dAhC1pFgBToZybXdvJFXXGX4BWdDxWqP7EUpG8gxkfMQeDjGPDnTr9e4NrkFmDM1ocav3Jz6x79CRZbxGr9dzFokJLuvDDnyRh', 'tpubDD3ULTdBbyuMMMs8BCsJKgZgEnZjjbsbtV6ig3xtkQnaSc1gu9kNhmDDEW49HoLzDNA4y2TMqRzj4BugrrtcpXkjoHSoMVhJwfZLUFmv6yn'] + ) + wallet_hmac = bytes.fromhex( + "8a0e67be3697449e4d1b19d6aaec634ce747cbcf35287887588028c9da250ab3") + + psbt_b64 = "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" + psbt = PSBT() + psbt.deserialize(psbt_b64) + + assert len(psbt.inputs) == 1 + + result = client.sign_psbt(psbt, wallet, wallet_hmac, navigator, + instructions=sign_psbt_instruction_approve( + firmware, has_spend_from_wallet=True, save_screenshot=False), + testname=test_name) + + assert len(result) == 2 + + # Removing all the PSBT_IN_BIP32_DERIVATION fields for that don't end in /<0;1>/*, the app should + # no longer sign for those keys (therefore we only expect one signature) + for input in psbt.inputs: + for pk, key_orig in list(input.hd_keypaths.items()): + if key_orig.path[-2] not in [0, 1]: + del input.hd_keypaths[pk] + + result = client.sign_psbt(psbt, wallet, wallet_hmac, navigator, + instructions=sign_psbt_instruction_approve( + firmware, has_spend_from_wallet=True, save_screenshot=False), + testname=test_name) + + assert len(result) == 1 From 6d858b4bc7542e7915f52d989ccdb84c9c87fcff Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:40:45 +0000 Subject: [PATCH 40/57] Fixup: musig e2e tests --- tests/test_e2e_musig2.py | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/tests/test_e2e_musig2.py b/tests/test_e2e_musig2.py index 1cda4d8e4..8e402e9c2 100644 --- a/tests/test_e2e_musig2.py +++ b/tests/test_e2e_musig2.py @@ -26,33 +26,6 @@ from .conftest import AuthServiceProxy, create_new_wallet, generate_blocks, get_unique_wallet_name, get_wallet_rpc, import_descriptors_with_privkeys, testnet_to_regtest_addr as T -class BitcoinCoreMusig2Cosigner(PsbtMusig2Cosigner): - """ - Implements a PsbtMusig2Cosigner for a given wallet policy using bitcoin-core. - """ - - def __init__(self, wallet_policy: WalletPolicy, rpc) -> None: - super().__init__() - - self.wallet_policy = wallet_policy - self.rpc = rpc - - self.musig_psbt_sessions: Dict[bytes, bytes] = {} - - def compute_psbt_session_id(self, psbt: PSBT) -> bytes: - psbt.tx.rehash() - return sha256(psbt.tx.hash + self.wallet_policy.id) - - def get_participant_pubkey(self) -> bip0327.Point: - raise NotImplementedError() - - def generate_public_nonces(self, psbt: PSBT) -> None: - raise NotImplementedError() - - def generate_partial_signatures(self, psbt: PSBT) -> None: - raise NotImplementedError() - - def run_test_e2e_musig2(navigator: Navigator, client: RaggerClient, wallet_policy: WalletPolicy, core_wallet_names: List[str], rpc: AuthServiceProxy, rpc_test_wallet: AuthServiceProxy, speculos_globals: SpeculosGlobals, instructions_register_wallet: Instructions, instructions_sign_psbt: Instructions, test_name: str): @@ -73,10 +46,6 @@ def printb(*args): wallet_hmac, ) - # TODO: reenable registration above and delete this - wallet_hmac = hmac.new(speculos_globals.wallet_registration_key, - wallet_policy.id, sha256).digest() - address_hww = client.get_wallet_address( wallet_policy, wallet_hmac, 0, 3, False) From 3f556d8f52cb4c4e41421e6a7992ec220e046201 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:17:17 +0000 Subject: [PATCH 41/57] Detect if the PSBT has at least a PSBT_IN_MUSIG2_PUB_NONCE field It will be needed in order to enable silently participating to Round 1 of the MuSig2 protocol, which should only happen if no such fields are found (which would indicate that Round 1 was already executed). --- src/handler/sign_psbt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index f8001021b..664edbb1d 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -182,6 +182,9 @@ typedef struct { unsigned int n_external_inputs; unsigned int n_external_outputs; + // set to true if at least a PSBT_IN_MUSIG2_PUB_NONCES field is present in the PSBT + bool has_musig2_pub_nonces; + // aggregate info on outputs struct { uint64_t total_amount; // amount of all the outputs (external + change) @@ -892,6 +895,8 @@ static void input_keys_callback(dispatcher_context_t *dc, } else { LEDGER_ASSERT(false, "Unreachable code"); } + } else if (key_type == PSBT_IN_MUSIG2_PUB_NONCE) { + callback_data->state->has_musig2_pub_nonces = true; } } } From b6ce98c3d5735727dac99b4c0903254138a92135 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Thu, 21 Nov 2024 10:46:44 +0000 Subject: [PATCH 42/57] Moved MuSig2 Round 1 out of the signing flow. Allow it without user confirmation. The first round of MuSig does not involve access to the private keys and does not complete authorizing a transaction. Therefore, it is safe to do it without user confirmation, which allows software wallets to possibly do it in background. In cases when the other cosigners are online, this allows to get a single-sig user experience, as the user would only have to plug the device once, and confirm a single action. --- src/handler/sign_psbt.c | 753 ++++++++++++++++++++++++--------------- test_utils/__init__.py | 15 +- tests/test_e2e_musig2.py | 45 ++- 3 files changed, 507 insertions(+), 306 deletions(-) diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 664edbb1d..d5b5f2b5e 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -182,7 +182,7 @@ typedef struct { unsigned int n_external_inputs; unsigned int n_external_outputs; - // set to true if at least a PSBT_IN_MUSIG2_PUB_NONCES field is present in the PSBT + // set to true if at least a PSBT_IN_MUSIG2_PUB_NONCE field is present in the PSBT bool has_musig2_pub_nonces; // aggregate info on outputs @@ -948,7 +948,6 @@ static bool fill_internal_key_expressions(dispatcher_context_t *dc, sign_psbt_st ++st->n_internal_key_expressions; } - // Not an internal key, move on ++cur_index; } @@ -2540,50 +2539,22 @@ static bool __attribute__((noinline)) yield_musig_data(dispatcher_context_t *dc, return true; } -static bool yield_musig_pubnonce(dispatcher_context_t *dc, - sign_psbt_state_t *st, - unsigned int cur_input_index, - const musig_pubnonce_t *pubnonce, - const uint8_t participant_pk[static 33], - const uint8_t aggregate_pubkey[static 33], - const uint8_t *tapleaf_hash) { - return yield_musig_data(dc, - st, - cur_input_index, - (const uint8_t *) pubnonce, - sizeof(musig_pubnonce_t), - CCMD_YIELD_MUSIG_PUBNONCE_TAG, - participant_pk, - aggregate_pubkey, - tapleaf_hash); -} - -static bool yield_musig_partial_signature(dispatcher_context_t *dc, - sign_psbt_state_t *st, - unsigned int cur_input_index, - const uint8_t psig[static 32], - const uint8_t participant_pk[static 33], - const uint8_t aggregate_pubkey[static 33], - const uint8_t *tapleaf_hash) { - return yield_musig_data(dc, - st, - cur_input_index, - psig, - 32, - CCMD_YIELD_MUSIG_PARTIALSIGNATURE_TAG, - participant_pk, - aggregate_pubkey, - tapleaf_hash); -} - -static bool __attribute__((noinline)) -sign_sighash_musig_and_yield(dispatcher_context_t *dc, - sign_psbt_state_t *st, - signing_state_t *signing_state, - const keyexpr_info_t *keyexpr_info, - const input_info_t *input, - unsigned int cur_input_index, - uint8_t sighash[static 32]) { +// Struct to hold the info computed for a given input in either of the two rounds +typedef struct { + plain_pk_t keys[MAX_PUBKEYS_PER_MUSIG]; + serialized_extended_pubkey_t agg_key_tweaked; + uint8_t psbt_session_id[32]; + uint8_t tweaks[3][32]; // 2 or three tweaks + size_t n_tweaks; + bool is_xonly[3]; // 2 or 3 elements +} musig_per_input_info_t; + +static bool compute_musig_per_input_info(dispatcher_context_t *dc, + sign_psbt_state_t *st, + signing_state_t *signing_state, + const input_info_t *input, + const keyexpr_info_t *keyexpr_info, + musig_per_input_info_t *out) { LOG_PROCESSOR(__FILE__, __LINE__, __func__); if (st->wallet_policy_map->type != TOKEN_TR) { @@ -2597,20 +2568,14 @@ sign_sighash_musig_and_yield(dispatcher_context_t *dc, // 1) compute aggregate pubkey // 2) compute musig2 tweaks // 3) compute taproot tweak (if keypath spend) - // if my pubnonce is in the psbt: - // 5) generate and yield pubnonce - // else: - // 6) generate and yield partial signature + // 4) compute the psbt_session_id that identifies the psbt-level signing session - // 1) compute aggregate pubkey - - // TODO: we should compute the aggregate pubkey just once for the placeholder, instead of - // repeating for each input wallet_derivation_info_t wdi = {.n_keys = st->wallet_header.n_keys, .wallet_version = st->wallet_header.version, .keys_merkle_root = st->wallet_header.keys_info_merkle_root, .change = input->in_out.is_change, - .address_index = input->in_out.address_index}; + .address_index = input->in_out.address_index, + .sign_psbt_cache = NULL}; // TODO: code duplication with policy.c::get_derived_pubkey; worth extracting a common method? @@ -2619,7 +2584,6 @@ sign_sighash_musig_and_yield(dispatcher_context_t *dc, const policy_node_keyexpr_t *key_expr = keyexpr_info->key_expression_ptr; const musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); const uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); - plain_pk_t keys[MAX_PUBKEYS_PER_MUSIG]; LEDGER_ASSERT(musig_info->n <= MAX_PUBKEYS_PER_MUSIG, "Too many keys in musig key expression"); for (int i = 0; i < musig_info->n; i++) { @@ -2627,23 +2591,23 @@ sign_sighash_musig_and_yield(dispatcher_context_t *dc, if (0 > get_extended_pubkey(dc, &wdi, key_indexes[i], &ext_pubkey)) { return -1; } - memcpy(keys[i], ext_pubkey.compressed_pubkey, sizeof(ext_pubkey.compressed_pubkey)); + memcpy(out->keys[i], ext_pubkey.compressed_pubkey, sizeof(ext_pubkey.compressed_pubkey)); } // sort the keys in ascending order using bubble sort for (int i = 0; i < musig_info->n; i++) { for (int j = 0; j < musig_info->n - 1; j++) { - if (memcmp(keys[j], keys[j + 1], sizeof(plain_pk_t)) > 0) { + if (memcmp(out->keys[j], out->keys[j + 1], sizeof(plain_pk_t)) > 0) { uint8_t tmp[sizeof(plain_pk_t)]; - memcpy(tmp, keys[j], sizeof(plain_pk_t)); - memcpy(keys[j], keys[j + 1], sizeof(plain_pk_t)); - memcpy(keys[j + 1], tmp, sizeof(plain_pk_t)); + memcpy(tmp, out->keys[j], sizeof(plain_pk_t)); + memcpy(out->keys[j], out->keys[j + 1], sizeof(plain_pk_t)); + memcpy(out->keys[j + 1], tmp, sizeof(plain_pk_t)); } } } musig_keyagg_context_t musig_ctx; - musig_key_agg(keys, musig_info->n, &musig_ctx); + musig_key_agg(out->keys, musig_info->n, &musig_ctx); // compute the aggregated extended pubkey memset(&ext_pubkey, 0, sizeof(ext_pubkey)); @@ -2664,71 +2628,58 @@ sign_sighash_musig_and_yield(dispatcher_context_t *dc, // in wallet policies, we always have at least two bip32-tweaks, and we might have // one x-only tweak per BIP-0341 (if spending from the keypath). - uint8_t tweaks[3][32]; - uint8_t *tweaks_ptrs[3] = {tweaks[0], tweaks[1], tweaks[2]}; - bool is_xonly[] = {false, false, true}; - size_t n_tweaks = 2; // might be changed to 3 below + out->is_xonly[0] = false; + out->is_xonly[1] = false; + out->n_tweaks = 2; // might be changed to 3 below - serialized_extended_pubkey_t agg_key_tweaked; - if (0 > bip32_CKDpub(&ext_pubkey, change_step, &agg_key_tweaked, tweaks[0])) { + if (0 > bip32_CKDpub(&ext_pubkey, change_step, &out->agg_key_tweaked, out->tweaks[0])) { SEND_SW(dc, SW_BAD_STATE); // should never happen return false; } - if (0 > bip32_CKDpub(&agg_key_tweaked, addr_index_step, &agg_key_tweaked, tweaks[1])) { + + if (0 > bip32_CKDpub(&out->agg_key_tweaked, + addr_index_step, + &out->agg_key_tweaked, + out->tweaks[1])) { SEND_SW(dc, SW_BAD_STATE); // should never happen return false; } // 3) compute taproot tweak (if keypath spend) - memset(tweaks[2], 0, 32); + memset(out->tweaks[2], 0, 32); if (!keyexpr_info->is_tapscript) { - n_tweaks = 3; + out->n_tweaks = 3; + out->is_xonly[2] = true; crypto_tr_tagged_hash( BIP0341_taptweak_tag, sizeof(BIP0341_taptweak_tag), - agg_key_tweaked.compressed_pubkey + 1, // xonly key, after BIP-32 tweaks + out->agg_key_tweaked.compressed_pubkey + 1, // xonly key, after BIP-32 tweaks 32, input->taptree_hash, // BIP-86 compliant tweak if there's no taptree, otherwise use the taptree hash isnull_policy_node_tree(&tr_policy->tree) ? 0 : 32, - tweaks[2]); + out->tweaks[2]); // also apply the taptweak to agg_key_tweaked uint8_t parity = 0; - crypto_tr_tweak_pubkey(agg_key_tweaked.compressed_pubkey + 1, + crypto_tr_tweak_pubkey(out->agg_key_tweaked.compressed_pubkey + 1, input->taptree_hash, isnull_policy_node_tree(&tr_policy->tree) ? 0 : 32, &parity, - agg_key_tweaked.compressed_pubkey + 1); - agg_key_tweaked.compressed_pubkey[0] = 0x02 + parity; + out->agg_key_tweaked.compressed_pubkey + 1); + out->agg_key_tweaked.compressed_pubkey[0] = 0x02 + parity; } // we will no longer use the other fields of the extended pubkey, so we zero them for sanity - memset(agg_key_tweaked.chain_code, 0, sizeof(agg_key_tweaked.chain_code)); - memset(agg_key_tweaked.child_number, 0, sizeof(agg_key_tweaked.child_number)); - agg_key_tweaked.depth = 0; - memset(agg_key_tweaked.parent_fingerprint, 0, sizeof(agg_key_tweaked.parent_fingerprint)); - memset(agg_key_tweaked.version, 0, sizeof(agg_key_tweaked.version)); - - // Compute musig_my_psbt_id. It is the psbt key that this signer uses to find pubnonces and - // partial signatures (PSBT_IN_MUSIG2_PUB_NONCE and PSBT_IN_MUSIG2_PARTIAL_SIG fields). The - // length is either 33+33 (keypath spend), or 33+33+32 bytes (tapscript spend). It's the - // concatenation of: - // - the 33-byte compressed pubkey of this participant - // - the 33-byte aggregate compressed pubkey (after all the tweaks) - // - (tapscript only) the 32-byte tapleaf hash - uint8_t musig_my_psbt_id_key[1 + 33 + 33 + 32]; - musig_my_psbt_id_key[0] = PSBT_IN_MUSIG2_PUB_NONCE; - - uint8_t *musig_my_psbt_id = musig_my_psbt_id_key + 1; - size_t psbt_id_len = keyexpr_info->is_tapscript ? 33 + 33 + 32 : 33 + 33; - memcpy(musig_my_psbt_id, keyexpr_info->internal_pubkey.compressed_pubkey, 33); - memcpy(musig_my_psbt_id + 33, agg_key_tweaked.compressed_pubkey, 33); - if (keyexpr_info->is_tapscript) { - memcpy(musig_my_psbt_id + 33 + 33, keyexpr_info->tapleaf_hash, 32); - } + memset(out->agg_key_tweaked.chain_code, 0, sizeof(out->agg_key_tweaked.chain_code)); + memset(out->agg_key_tweaked.child_number, 0, sizeof(out->agg_key_tweaked.child_number)); + out->agg_key_tweaked.depth = 0; + memset(out->agg_key_tweaked.parent_fingerprint, + 0, + sizeof(out->agg_key_tweaked.parent_fingerprint)); + memset(out->agg_key_tweaked.version, 0, sizeof(out->agg_key_tweaked.version)); // The psbt_session_id identifies the musig signing session for the entire (psbt, wallet_policy) // pair, in both rounds 1 and 2 of the protocol; it is the same for all the musig placeholders @@ -2738,18 +2689,92 @@ sign_sighash_musig_and_yield(dispatcher_context_t *dc, // sessions for different transactions or wallet policies. // Malicious collisions are not a concern, as they would only result in a signing failure (since // the nonces would be incorrectly regenerated during round 2 of MuSig2). - uint8_t psbt_session_id[32]; crypto_tr_tagged_hash( (uint8_t[]){'P', 's', 'b', 't', 'S', 'e', 's', 's', 'i', 'o', 'n', 'I', 'd'}, 13, st->wallet_header.keys_info_merkle_root, // TODO: wallet policy id would be more precise 32, (uint8_t *) &signing_state->tx_hashes, - sizeof(signing_state->tx_hashes), - psbt_session_id); - memcpy(psbt_session_id, st->wallet_header.keys_info_merkle_root, sizeof(psbt_session_id)); + sizeof(tx_hashes_t), + out->psbt_session_id); + + return true; +} + +static bool yield_musig_pubnonce(dispatcher_context_t *dc, + sign_psbt_state_t *st, + unsigned int cur_input_index, + const musig_pubnonce_t *pubnonce, + const uint8_t participant_pk[static 33], + const uint8_t aggregate_pubkey[static 33], + const uint8_t *tapleaf_hash) { + return yield_musig_data(dc, + st, + cur_input_index, + (const uint8_t *) pubnonce, + sizeof(musig_pubnonce_t), + CCMD_YIELD_MUSIG_PUBNONCE_TAG, + participant_pk, + aggregate_pubkey, + tapleaf_hash); +} + +static bool yield_musig_partial_signature(dispatcher_context_t *dc, + sign_psbt_state_t *st, + unsigned int cur_input_index, + const uint8_t psig[static 32], + const uint8_t participant_pk[static 33], + const uint8_t aggregate_pubkey[static 33], + const uint8_t *tapleaf_hash) { + return yield_musig_data(dc, + st, + cur_input_index, + psig, + 32, + CCMD_YIELD_MUSIG_PARTIALSIGNATURE_TAG, + participant_pk, + aggregate_pubkey, + tapleaf_hash); +} + +static bool __attribute__((noinline)) +sign_sighash_musig_and_yield(dispatcher_context_t *dc, + sign_psbt_state_t *st, + signing_state_t *signing_state, + const keyexpr_info_t *keyexpr_info, + const input_info_t *input, + unsigned int cur_input_index, + uint8_t sighash[static 32]) { + LOG_PROCESSOR(__FILE__, __LINE__, __func__); + + musig_per_input_info_t musig_per_input_info; + if (!compute_musig_per_input_info(dc, + st, + signing_state, + input, + keyexpr_info, + &musig_per_input_info)) { + return false; + } // 4) check if my pubnonce is in the psbt + // Compute musig_my_psbt_id. It is the psbt key that this signer uses to find pubnonces and + // partial signatures (PSBT_IN_MUSIG2_PUB_NONCE and PSBT_IN_MUSIG2_PARTIAL_SIG fields). The + // length is either 33+33 (keypath spend), or 33+33+32 bytes (tapscript spend). It's the + // concatenation of: + // - the 33-byte compressed pubkey of this participant + // - the 33-byte aggregate compressed pubkey (after all the tweaks) + // - (tapscript only) the 32-byte tapleaf hash + uint8_t musig_my_psbt_id_key[1 + 33 + 33 + 32]; + musig_my_psbt_id_key[0] = PSBT_IN_MUSIG2_PUB_NONCE; + + uint8_t *musig_my_psbt_id = musig_my_psbt_id_key + 1; + size_t psbt_id_len = keyexpr_info->is_tapscript ? 33 + 33 + 32 : 33 + 33; + memcpy(musig_my_psbt_id, keyexpr_info->internal_pubkey.compressed_pubkey, 33); + memcpy(musig_my_psbt_id + 33, musig_per_input_info.agg_key_tweaked.compressed_pubkey, 33); + if (keyexpr_info->is_tapscript) { + memcpy(musig_my_psbt_id + 33 + 33, keyexpr_info->tapleaf_hash, 32); + } musig_pubnonce_t my_pubnonce; if (sizeof(musig_pubnonce_t) != call_get_merkleized_map_value(dc, &input->in_out.map, @@ -2757,174 +2782,141 @@ sign_sighash_musig_and_yield(dispatcher_context_t *dc, 1 + psbt_id_len, my_pubnonce.raw, sizeof(musig_pubnonce_t))) { - /** - * Round 1 of the MuSig2 protocol - **/ - - const musig_psbt_session_t *psbt_session = - musigsession_round1_initialize(psbt_session_id, &signing_state->musig); - if (psbt_session == NULL) { - // This should never happen - PRINTF("Unexpected: failed to initialize MuSig2 round 1\n"); - SEND_SW(dc, SW_BAD_STATE); - return false; - } - - // 5) generate and yield pubnonce - - uint8_t rand_i_j[32]; - compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->index, rand_i_j); - - musig_secnonce_t secnonce; - musig_pubnonce_t pubnonce; - if (0 > musig_nonce_gen(rand_i_j, - keyexpr_info->internal_pubkey.compressed_pubkey, - agg_key_tweaked.compressed_pubkey + 1, - &secnonce, - &pubnonce)) { - PRINTF("MuSig2 nonce generation failed\n"); - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } + PRINTF("Missing pubnonce in PSBT\n"); + SEND_SW(dc, SW_BAD_STATE); + return false; + } + /** + * Round 2 of the MuSig2 protocol + **/ - if (!yield_musig_pubnonce(dc, - st, - cur_input_index, - &pubnonce, - keyexpr_info->internal_pubkey.compressed_pubkey, - agg_key_tweaked.compressed_pubkey, - keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) { - PRINTF("Failed yielding MuSig2 pubnonce\n"); - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } - } else { - /** - * Round 2 of the MuSig2 protocol - **/ - - const musig_psbt_session_t *psbt_session = - musigsession_round2_initialize(psbt_session_id, &signing_state->musig); - - if (psbt_session == NULL) { - // The PSBT contains a partial nonce, but we do not have the corresponding psbt - // session in storage. Either it was deleted, or the pubnonces were not real. Either - // way, we cannot continue. - PRINTF("Missing MuSig2 session\n"); - SEND_SW(dc, SW_BAD_STATE); - return false; - } + const musig_psbt_session_t *psbt_session = + musigsession_round2_initialize(musig_per_input_info.psbt_session_id, &signing_state->musig); - // 6) generate and yield partial signature + if (psbt_session == NULL) { + // The PSBT contains a partial nonce, but we do not have the corresponding psbt + // session in storage. Either it was deleted, or the pubnonces were not real. Either + // way, we cannot continue. + PRINTF("Missing MuSig2 session\n"); + SEND_SW(dc, SW_BAD_STATE); + return false; + } - musig_pubnonce_t nonces[MAX_PUBKEYS_PER_MUSIG]; + // 6) generate and yield partial signature - for (int i = 0; i < musig_info->n; i++) { - uint8_t musig_ith_psbt_id_key[1 + 33 + 33 + 32]; - uint8_t *musig_ith_psbt_id = musig_ith_psbt_id_key + 1; - // copy from musig_my_psbt_id_key, but replace the corresponding pubkey - memcpy(musig_ith_psbt_id_key, musig_my_psbt_id_key, sizeof(musig_my_psbt_id_key)); - memcpy(musig_ith_psbt_id, keys[i], sizeof(plain_pk_t)); + const policy_node_keyexpr_t *key_expr = keyexpr_info->key_expression_ptr; + const musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); - // TODO: could avoid fetching again our own pubnonce - if (sizeof(musig_pubnonce_t) != - call_get_merkleized_map_value(dc, - &input->in_out.map, - musig_ith_psbt_id_key, - 1 + psbt_id_len, - nonces[i].raw, - sizeof(musig_pubnonce_t))) { - PRINTF("Missing or incorrect pubnonce for a MuSig2 cosigner\n"); - SEND_SW(dc, SW_INCORRECT_DATA); - return false; - } - } + musig_pubnonce_t nonces[MAX_PUBKEYS_PER_MUSIG]; - // compute aggregate nonce - musig_pubnonce_t aggnonce; - int res = musig_nonce_agg(nonces, musig_info->n, &aggnonce); - if (res < 0) { - PRINTF("Musig aggregation failed; disruptive signer has index %d\n", -res); + for (int i = 0; i < musig_info->n; i++) { + uint8_t musig_ith_psbt_id_key[1 + 33 + 33 + 32]; + uint8_t *musig_ith_psbt_id = musig_ith_psbt_id_key + 1; + // copy from musig_my_psbt_id_key, but replace the corresponding pubkey + memcpy(musig_ith_psbt_id_key, musig_my_psbt_id_key, sizeof(musig_my_psbt_id_key)); + memcpy(musig_ith_psbt_id, musig_per_input_info.keys[i], sizeof(plain_pk_t)); + + if (sizeof(musig_pubnonce_t) != call_get_merkleized_map_value(dc, + &input->in_out.map, + musig_ith_psbt_id_key, + 1 + psbt_id_len, + nonces[i].raw, + sizeof(musig_pubnonce_t))) { + PRINTF("Missing or incorrect pubnonce for a MuSig2 cosigner\n"); SEND_SW(dc, SW_INCORRECT_DATA); + return false; } + } - // recompute secnonce from psbt_session randomness - uint8_t rand_i_j[32]; - compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->index, rand_i_j); - - musig_secnonce_t secnonce; - musig_pubnonce_t pubnonce; + // compute aggregate nonce + musig_pubnonce_t aggnonce; + int res = musig_nonce_agg(nonces, musig_info->n, &aggnonce); + if (res < 0) { + PRINTF("Musig aggregation failed; disruptive signer has index %d\n", -res); + SEND_SW(dc, SW_INCORRECT_DATA); + } - if (0 > musig_nonce_gen(rand_i_j, - keyexpr_info->internal_pubkey.compressed_pubkey, - agg_key_tweaked.compressed_pubkey + 1, - &secnonce, - &pubnonce)) { - PRINTF("MuSig2 nonce generation failed\n"); - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } + // recompute secnonce from psbt_session randomness + uint8_t rand_i_j[32]; + compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->index, rand_i_j); - // derive secret key + musig_secnonce_t secnonce; + musig_pubnonce_t pubnonce; - cx_ecfp_private_key_t private_key = {0}; - uint8_t psig[32]; - bool err = false; - do { // block executed once, only to allow safely breaking out on error + if (0 > musig_nonce_gen(rand_i_j, + keyexpr_info->internal_pubkey.compressed_pubkey, + musig_per_input_info.agg_key_tweaked.compressed_pubkey + 1, + &secnonce, + &pubnonce)) { + PRINTF("MuSig2 nonce generation failed\n"); + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } - // derive secret key - uint32_t sign_path[MAX_BIP32_PATH_STEPS]; + // derive secret key - for (int i = 0; i < keyexpr_info->key_derivation_length; i++) { - sign_path[i] = keyexpr_info->key_derivation[i]; - } - int sign_path_len = keyexpr_info->key_derivation_length; - - if (bip32_derive_init_privkey_256(CX_CURVE_256K1, - sign_path, - sign_path_len, - &private_key, - NULL) != CX_OK) { - err = true; - break; - } + cx_ecfp_private_key_t private_key = {0}; + uint8_t psig[32]; + bool err = false; + do { // block executed once, only to allow safely breaking out on error - // Create partial signature - musig_session_context_t musig_session_context = {.aggnonce = &aggnonce, - .n_keys = musig_info->n, - .pubkeys = keys, - .n_tweaks = n_tweaks, - .tweaks = tweaks_ptrs, - .is_xonly = is_xonly, - .msg = sighash, - .msg_len = 32}; - - if (0 > musig_sign(&secnonce, private_key.d, &musig_session_context, psig)) { - PRINTF("Musig2 signature failed\n"); - err = true; - break; - } - } while (false); + // derive secret key + uint32_t sign_path[MAX_BIP32_PATH_STEPS]; - explicit_bzero(&private_key, sizeof(private_key)); + for (int i = 0; i < keyexpr_info->key_derivation_length; i++) { + sign_path[i] = keyexpr_info->key_derivation[i]; + } + int sign_path_len = keyexpr_info->key_derivation_length; - if (err) { - PRINTF("Partial signature generation failed\n"); - return false; + if (bip32_derive_init_privkey_256(CX_CURVE_256K1, + sign_path, + sign_path_len, + &private_key, + NULL) != CX_OK) { + err = true; + break; } - if (!yield_musig_partial_signature( - dc, - st, - cur_input_index, - psig, - keyexpr_info->internal_pubkey.compressed_pubkey, - agg_key_tweaked.compressed_pubkey, - keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) { - PRINTF("Failed yielding MuSig2 partial signature\n"); - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; + // Create partial signature + uint8_t *tweaks_ptrs[3] = { + musig_per_input_info.tweaks[0], + musig_per_input_info.tweaks[1], + musig_per_input_info.tweaks[2] // the last element is ignored if n_tweaks == 2 + }; + musig_session_context_t musig_session_context = {.aggnonce = &aggnonce, + .n_keys = musig_info->n, + .pubkeys = musig_per_input_info.keys, + .n_tweaks = musig_per_input_info.n_tweaks, + .tweaks = tweaks_ptrs, + .is_xonly = musig_per_input_info.is_xonly, + .msg = sighash, + .msg_len = 32}; + + if (0 > musig_sign(&secnonce, private_key.d, &musig_session_context, psig)) { + PRINTF("Musig2 signature failed\n"); + err = true; + break; } + } while (false); + + explicit_bzero(&private_key, sizeof(private_key)); + + if (err) { + PRINTF("Partial signature generation failed\n"); + return false; + } + + if (!yield_musig_partial_signature( + dc, + st, + cur_input_index, + psig, + keyexpr_info->internal_pubkey.compressed_pubkey, + musig_per_input_info.agg_key_tweaked.compressed_pubkey, + keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) { + PRINTF("Failed yielding MuSig2 partial signature\n"); + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; } return true; @@ -3295,25 +3287,163 @@ fill_taproot_keyexpr_info(dispatcher_context_t *dc, return true; } +static bool produce_and_yield_pubnonce(dispatcher_context_t *dc, + sign_psbt_state_t *st, + signing_state_t *signing_state, + const keyexpr_info_t *keyexpr_info, + const input_info_t *input, + unsigned int cur_input_index) { + LOG_PROCESSOR(__FILE__, __LINE__, __func__); + + musig_per_input_info_t musig_per_input_info; + if (!compute_musig_per_input_info(dc, + st, + signing_state, + input, + keyexpr_info, + &musig_per_input_info)) { + return false; + } + + /** + * Round 1 of the MuSig2 protocol + **/ + + const musig_psbt_session_t *psbt_session = + musigsession_round1_initialize(musig_per_input_info.psbt_session_id, &signing_state->musig); + if (psbt_session == NULL) { + // This should never happen + PRINTF("Unexpected: failed to initialize MuSig2 round 1\n"); + SEND_SW(dc, SW_BAD_STATE); + return false; + } + + // 5) generate and yield pubnonce + + uint8_t rand_i_j[32]; + compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->index, rand_i_j); + + musig_secnonce_t secnonce; + musig_pubnonce_t pubnonce; + if (0 > musig_nonce_gen(rand_i_j, + keyexpr_info->internal_pubkey.compressed_pubkey, + musig_per_input_info.agg_key_tweaked.compressed_pubkey + 1, + &secnonce, + &pubnonce)) { + PRINTF("MuSig2 nonce generation failed\n"); + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + if (!yield_musig_pubnonce(dc, + st, + cur_input_index, + &pubnonce, + keyexpr_info->internal_pubkey.compressed_pubkey, + musig_per_input_info.agg_key_tweaked.compressed_pubkey, + keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) { + PRINTF("Failed yielding MuSig2 pubnonce\n"); + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + return true; +} + +static bool __attribute__((noinline)) produce_musig2_pubnonces( + dispatcher_context_t *dc, + sign_psbt_state_t *st, + signing_state_t *signing_state, + sign_psbt_cache_t *sign_psbt_cache, + const uint8_t internal_inputs[static BITVECTOR_REAL_SIZE(MAX_N_INPUTS_CAN_SIGN)]) { + LOG_PROCESSOR(__FILE__, __LINE__, __func__); + + if (st->wallet_policy_map->type != TOKEN_TR) { + return true; // nothing to do + } + + // Iterate over all the key expressions that correspond to keys owned by us + for (size_t i_keyexpr = 0; i_keyexpr < st->n_internal_key_expressions; i_keyexpr++) { + keyexpr_info_t *keyexpr_info = &st->internal_key_expressions[i_keyexpr]; + if (!keyexpr_info->to_sign || + keyexpr_info->key_expression_ptr->type != KEY_EXPRESSION_MUSIG) { + continue; + } + + if (!fill_keyexpr_info_if_internal(dc, st, keyexpr_info) == true) { + continue; + } + + for (unsigned int i = 0; i < st->n_inputs; i++) { + if (bitvector_get(internal_inputs, i)) { + input_info_t input; + memset(&input, 0, sizeof(input)); + + input_keys_callback_data_t callback_data = {.input = &input, .state = st}; + int res = call_get_merkleized_map_with_callback( + dc, + (void *) &callback_data, + st->inputs_root, + st->n_inputs, + i, + (merkle_tree_elements_callback_t) input_keys_callback, + &input.in_out.map); + if (res < 0) { + SEND_SW(dc, SW_INCORRECT_DATA); + return false; + } + + // TODO: code duplication with sign_transaction_input + if (keyexpr_info->tapleaf_ptr != NULL) { + if (!fill_taproot_keyexpr_info(dc, + st, + &input, + keyexpr_info->tapleaf_ptr, + keyexpr_info, + sign_psbt_cache)) { + return false; + } + } + + policy_node_tr_t *policy = (policy_node_tr_t *) st->wallet_policy_map; + if (!isnull_policy_node_tree(&policy->tree)) { + if (0 > compute_taptree_hash( + dc, + &(wallet_derivation_info_t){ + .address_index = input.in_out.address_index, + .change = input.in_out.is_change ? 1 : 0, + .keys_merkle_root = st->wallet_header.keys_info_merkle_root, + .n_keys = st->wallet_header.n_keys, + .wallet_version = st->wallet_header.version, + .sign_psbt_cache = sign_psbt_cache}, + r_policy_node_tree(&policy->tree), + input.taptree_hash)) { + PRINTF("Error while computing taptree hash\n"); + SEND_SW(dc, SW_BAD_STATE); + return false; + } + } + + if (!produce_and_yield_pubnonce(dc, st, signing_state, keyexpr_info, &input, i)) { + return false; + } + } + } + } + + return true; +} + static bool __attribute__((noinline)) sign_transaction(dispatcher_context_t *dc, sign_psbt_state_t *st, sign_psbt_cache_t *sign_psbt_cache, + signing_state_t *signing_state, const uint8_t internal_inputs[static BITVECTOR_REAL_SIZE(MAX_N_INPUTS_CAN_SIGN)]) { LOG_PROCESSOR(__FILE__, __LINE__, __func__); int key_expression_index = 0; - signing_state_t signing_state; - - // compute all the tx-wide hashes - // while this is redundant for legacy transactions, we do it here in order to - // avoid doing it in places that have more stack limitations - if (!compute_tx_hashes(dc, st, &signing_state.tx_hashes)) { - // we do not send a status word, since compute_tx_hashes already does it on failure - return false; - } - // Iterate over all the key expressions that correspond to keys owned by us for (size_t i_keyexpr = 0; i_keyexpr < st->n_internal_key_expressions; i_keyexpr++) { keyexpr_info_t *keyexpr_info = &st->internal_key_expressions[i_keyexpr]; @@ -3356,7 +3486,7 @@ sign_transaction(dispatcher_context_t *dc, if (!sign_transaction_input(dc, st, sign_psbt_cache, - &signing_state, + signing_state, keyexpr_info, &input, i)) { @@ -3370,10 +3500,6 @@ sign_transaction(dispatcher_context_t *dc, ++key_expression_index; } - // MuSig2: if there is an active session at the end of round 1, we move it to persistent - // storage. It is important that this is only done at the very end of the signing process. - musigsession_commit(&signing_state.musig); - return true; } @@ -3423,44 +3549,79 @@ void handler_sign_psbt(dispatcher_context_t *dc, uint8_t protocol_version) { */ if (!preprocess_outputs(dc, &st, cache, internal_outputs)) return; - if (G_swap_state.called_from_swap) { - /** SWAP CHECKS - * - * If called from the exchange app, perform the necessary additional checks. - */ - - // During swaps, the user approval was already obtained in the exchange app - if (!execute_swap_checks(dc, &st)) return; - } else { - /** TRANSACTION CONFIRMATION - * - * Display each non-change output, and transaction fees, and acquire user confirmation, - */ - if (!display_transaction(dc, &st, internal_outputs)) return; + // check if we're only executing the MuSig2 Round 1 + bool only_signing_for_musig = true; + for (size_t i = 0; i < st.n_internal_key_expressions; i++) { + if (st.internal_key_expressions[i].to_sign && + st.internal_key_expressions[i].key_expression_ptr->type != KEY_EXPRESSION_MUSIG) { + // at least one of the key expressions we're signing for is not a MuSig + only_signing_for_musig = false; + } } - // Signing always takes some time, so we rather not wait before showing the spinner - io_show_processing_screen(); - - /** SIGNING FLOW - * - * For each internal key expression, and for each internal input, sign using the - * appropriate algorithm. - */ - int sign_result = sign_transaction(dc, &st, cache, internal_inputs); + signing_state_t signing_state; + memset(&signing_state, 0, sizeof(signing_state)); - if (!G_swap_state.called_from_swap) { - ui_post_processing_confirm_transaction(dc, sign_result); + // compute all the tx-wide hashes + if (!compute_tx_hashes(dc, &st, &signing_state.tx_hashes)) { + return; } - if (!sign_result) { - return; + if (!st.has_musig2_pub_nonces) { + // We execute the first round of MuSig for any musig2 key expression.produce the pubnonces; + // this does not involve the private keys, therefore we can do it without user confirmation + + if (!produce_musig2_pubnonces(dc, &st, &signing_state, cache, internal_inputs)) { + return; + } } - // Only if called from swap, the app should terminate after sending the response - if (G_swap_state.called_from_swap) { - G_swap_state.should_exit = true; + // we execute the signing flow only if we're producing any signature + // (or any MuSig partial signature) + if (!only_signing_for_musig || st.has_musig2_pub_nonces) { + if (G_swap_state.called_from_swap) { + /** SWAP CHECKS + * + * If called from the exchange app, perform the necessary additional checks. + */ + + // During swaps, the user approval was already obtained in the exchange app + if (!execute_swap_checks(dc, &st)) return; + } else { + /** TRANSACTION CONFIRMATION + * + * Display each non-change output, and transaction fees, and acquire user confirmation, + */ + if (!display_transaction(dc, &st, internal_outputs)) return; + } + + // Signing always takes some time, so we rather not wait before showing the spinner + io_show_processing_screen(); + + /** SIGNING FLOW + * + * For each internal key expression, and for each internal input, sign using the + * appropriate algorithm. + */ + int sign_result = sign_transaction(dc, &st, cache, &signing_state, internal_inputs); + + if (!G_swap_state.called_from_swap) { + ui_post_processing_confirm_transaction(dc, sign_result); + } + + if (!sign_result) { + return; + } + + // Only if called from swap, the app should terminate after sending the response + if (G_swap_state.called_from_swap) { + G_swap_state.should_exit = true; + } } + // MuSig2: if there is an active session at the end of round 1, we move it to persistent + // storage. It is important that this is only done at the very end of the signing process. + musigsession_commit(&signing_state.musig); + SEND_SW(dc, SW_OK); } diff --git a/test_utils/__init__.py b/test_utils/__init__.py index 013d9e2e3..d0bb333f4 100644 --- a/test_utils/__init__.py +++ b/test_utils/__init__.py @@ -91,7 +91,7 @@ def get_internal_xpub(seed: str, path: str) -> str: return bip32.get_xpub_from_path(f"m/{path}") if path else bip32.get_xpub_from_path("m") -def count_internal_key_placeholders(seed: str, network: Union[Literal['main'], Literal['test']], wallet_policy: WalletPolicy) -> int: +def count_internal_key_placeholders(seed: str, network: Union[Literal['main'], Literal['test']], wallet_policy: WalletPolicy, *, only_musig=False) -> int: """Count how many of the key placeholders in wallet_policy are indeed internal. musig() placeholders are counted as many times as there are internal keys in them.""" @@ -124,12 +124,13 @@ def count_internal_key_placeholders(seed: str, network: Union[Literal['main'], L count = 0 - simple_key_placeholders = re.findall( - r'@(\d+)/', wallet_policy.descriptor_template) - # for each match, count it if the corresponding key is internal - for key_index in simple_key_placeholders: - if is_key_internal[int(key_index)]: - count += 1 + if not only_musig: + simple_key_placeholders = re.findall( + r'@(\d+)/', wallet_policy.descriptor_template) + # for each match, count it if the corresponding key is internal + for key_index in simple_key_placeholders: + if is_key_internal[int(key_index)]: + count += 1 if wallet_policy.version != WalletType.WALLET_POLICY_V1: # no musig in V1 policies musig_key_placeholders = re.findall( diff --git a/tests/test_e2e_musig2.py b/tests/test_e2e_musig2.py index 8e402e9c2..ef14479e4 100644 --- a/tests/test_e2e_musig2.py +++ b/tests/test_e2e_musig2.py @@ -6,6 +6,7 @@ from hashlib import sha256 from decimal import Decimal +from ledger_bitcoin._script import is_p2tr from ledger_bitcoin.exception.errors import IncorrectDataError, NotSupportedError from ledger_bitcoin.exception.device_exception import DeviceException from ledger_bitcoin.psbt import PSBT @@ -26,6 +27,20 @@ from .conftest import AuthServiceProxy, create_new_wallet, generate_blocks, get_unique_wallet_name, get_wallet_rpc, import_descriptors_with_privkeys, testnet_to_regtest_addr as T +# Removes all the BIP_IN_TAP_BIP32_DERIVATION entries that are not for the musig aggregate keys +# Returns a new PSBT without modifying the original +def strip_non_musig2_derivations(psbt: PSBT) -> PSBT: + psbt_clone = PSBT() + psbt_clone.deserialize(psbt.serialize()) + for input in psbt_clone.inputs: + if input.witness_utxo is not None and is_p2tr(input.witness_utxo.scriptPubKey): + for key, (_, deriv) in list(input.tap_bip32_paths.items()): + # a bit hacky, but musig key derivations in wallet policies are always 2 steps + if len(deriv.path) != 2: + del input.tap_bip32_paths[key] + return psbt_clone + + def run_test_e2e_musig2(navigator: Navigator, client: RaggerClient, wallet_policy: WalletPolicy, core_wallet_names: List[str], rpc: AuthServiceProxy, rpc_test_wallet: AuthServiceProxy, speculos_globals: SpeculosGlobals, instructions_register_wallet: Instructions, instructions_sign_psbt: Instructions, test_name: str): @@ -124,12 +139,13 @@ def printb(*args): # ==> get nonce from the hww n_internal_keys = count_internal_key_placeholders( - speculos_globals.seed, "test", wallet_policy) + speculos_globals.seed, "test", wallet_policy, only_musig=True) psbt = PSBT() psbt.deserialize(psbt_b64) - hww_yielded: List[Tuple[int, SignPsbtYieldedObject]] = client.sign_psbt(psbt, wallet_policy, wallet_hmac, navigator, + psbt_stripped = strip_non_musig2_derivations(psbt) + hww_yielded: List[Tuple[int, SignPsbtYieldedObject]] = client.sign_psbt(psbt_stripped, wallet_policy, wallet_hmac, navigator, instructions=instructions_sign_psbt, testname=f"{test_name}_sign") @@ -190,7 +206,8 @@ def printb(*args): psbt = PSBT() psbt.deserialize(combined_psbt) - hww_yielded: List[Tuple[int, SignPsbtYieldedObject]] = client.sign_psbt(psbt, wallet_policy, wallet_hmac, navigator, + psbt_stripped = strip_non_musig2_derivations(psbt) + hww_yielded: List[Tuple[int, SignPsbtYieldedObject]] = client.sign_psbt(psbt_stripped, wallet_policy, wallet_hmac, navigator, instructions=instructions_sign_psbt, testname=f"{test_name}_sign") @@ -273,6 +290,28 @@ def test_e2e_musig2_keypath(navigator: Navigator, firmware: Firmware, client: Ra e2e_register_wallet_instruction(firmware, wallet_policy.n_keys), e2e_sign_psbt_instruction(firmware), test_name) +def test_e2e_musig2_keypath2(navigator: Navigator, firmware: Firmware, client: RaggerClient, + test_name: str, rpc, rpc_test_wallet, speculos_globals: SpeculosGlobals): + # We spend with the musig2 in the keypath, but there is a taptree + + path = "48'/1'/0'/2'" + internal_xpub = get_internal_xpub(speculos_globals.seed, path) + + core_wallet_name, core_xpub_orig = create_new_wallet() + _, core_xpub_orig_2 = create_new_wallet() + wallet_policy = WalletPolicy( + name="Musig 2 my ears", + descriptor_template="tr(musig(@0,@1)/**,pk(@2/**))", + keys_info=[ + f"[{speculos_globals.master_key_fingerprint.hex()}/{path}]{internal_xpub}", + f"{core_xpub_orig}", + f"{core_xpub_orig_2}", + ]) + + run_test_e2e_musig2(navigator, client, wallet_policy, [core_wallet_name], rpc, rpc_test_wallet, speculos_globals, + e2e_register_wallet_instruction(firmware, wallet_policy.n_keys), e2e_sign_psbt_instruction(firmware), test_name) + + def test_e2e_musig2_scriptpath(navigator: Navigator, firmware: Firmware, client: RaggerClient, test_name: str, rpc, rpc_test_wallet, speculos_globals: SpeculosGlobals): path = "48'/1'/0'/2'" From 392b9422bd1aafd6ef717ca4cea16e33fbfdd784 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Thu, 21 Nov 2024 11:22:33 +0000 Subject: [PATCH 43/57] Only compute the aggregate key once for each key expression --- src/handler/sign_psbt.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index d5b5f2b5e..88d96a5b5 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -2606,16 +2606,8 @@ static bool compute_musig_per_input_info(dispatcher_context_t *dc, } } - musig_keyagg_context_t musig_ctx; - musig_key_agg(out->keys, musig_info->n, &musig_ctx); - - // compute the aggregated extended pubkey - memset(&ext_pubkey, 0, sizeof(ext_pubkey)); - write_u32_be(ext_pubkey.version, 0, BIP32_PUBKEY_VERSION); - - ext_pubkey.compressed_pubkey[0] = (musig_ctx.Q.y[31] % 2 == 0) ? 2 : 3; - memcpy(&ext_pubkey.compressed_pubkey[1], musig_ctx.Q.x, sizeof(musig_ctx.Q.x)); - memcpy(&ext_pubkey.chain_code, BIP_328_CHAINCODE, sizeof(BIP_328_CHAINCODE)); + // we already computed the aggregate (pre-tweaks) xpub in the keyexpr_info + memcpy(&ext_pubkey, &keyexpr_info->pubkey, sizeof(serialized_extended_pubkey_t)); // 2) compute musig2 tweaks // We always have exactly 2 BIP32 tweaks in wallet policies; if the musig is in the keypath From 752aaa8aa6ef07228a02af760af62b400c1b4013 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:37:56 +0000 Subject: [PATCH 44/57] Fix wrong documentation for get_extended_pubkey; renamed to get_extended_pubkey_from_client --- src/handler/lib/policy.c | 12 +++++++++--- src/handler/lib/policy.h | 11 +++-------- src/handler/sign_psbt.c | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index 7af8280f0..9ecf54281 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -420,7 +420,7 @@ execute_processor(policy_parser_state_t *state, policy_parser_processor_t proc, // convenience function, split from get_derived_pubkey only to improve stack usage // returns -1 on error, 0 if the returned key info has no wildcard (**), 1 if it has the wildcard -__attribute__((noinline, warn_unused_result)) int get_extended_pubkey( +__attribute__((noinline, warn_unused_result)) int get_extended_pubkey_from_client( dispatcher_context_t *dispatcher_context, const wallet_derivation_info_t *wdi, int key_index, @@ -464,7 +464,10 @@ __attribute__((warn_unused_result)) static int get_derived_pubkey( serialized_extended_pubkey_t ext_pubkey; if (key_expr->type == KEY_EXPRESSION_NORMAL) { - if (0 > get_extended_pubkey(dispatcher_context, wdi, key_expr->k.key_index, &ext_pubkey)) { + if (0 > get_extended_pubkey_from_client(dispatcher_context, + wdi, + key_expr->k.key_index, + &ext_pubkey)) { return -1; } } else if (key_expr->type == KEY_EXPRESSION_MUSIG) { @@ -473,7 +476,10 @@ __attribute__((warn_unused_result)) static int get_derived_pubkey( plain_pk_t keys[MAX_PUBKEYS_PER_MUSIG]; for (int i = 0; i < musig_info->n; i++) { // we use ext_pubkey as a temporary variable; will overwrite later - if (0 > get_extended_pubkey(dispatcher_context, wdi, key_indexes[i], &ext_pubkey)) { + if (0 > get_extended_pubkey_from_client(dispatcher_context, + wdi, + key_indexes[i], + &ext_pubkey)) { return -1; } memcpy(keys[i], ext_pubkey.compressed_pubkey, sizeof(ext_pubkey.compressed_pubkey)); diff --git a/src/handler/lib/policy.h b/src/handler/lib/policy.h index 25f0e564d..e5cd24189 100644 --- a/src/handler/lib/policy.h +++ b/src/handler/lib/policy.h @@ -54,23 +54,18 @@ typedef struct { } wallet_derivation_info_t; /** - * Computes the a derived compressed pubkey for one of the key of the wallet policy, - * for a given change/address_index combination. - * - * This function computes the extended public key (xpub) based on the provided - * BIP32 derivation path. It supports both standard BIP32 derivation and - * the derivation of Musig (multi-signature) keys. + * Requests and parses the serialized extended public key from the client. * * @param[in] dispatcher_context Pointer to the dispatcher content * @param[in] wdi Pointer to a `wallet_derivation_info_t` struct with the details of the - * necessary details of the wallet policy, and the desired change/address_index pair. + * necessary details of the wallet policy. The change/addr_index pairs are not * @param[in] key_index Index of the pubkey in the vector of keys of the wallet policy. * @param[out] out Pointer to a `serialized_extended_pubkey_t` that will contain the requested * extended pubkey. * * @return -1 on error, 0 if the returned key info has no wildcard (**), 1 if it has the wildcard. */ -__attribute__((warn_unused_result)) int get_extended_pubkey( +__attribute__((warn_unused_result)) int get_extended_pubkey_from_client( dispatcher_context_t *dispatcher_context, const wallet_derivation_info_t *wdi, int key_index, diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 88d96a5b5..67f969bd1 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -2588,7 +2588,7 @@ static bool compute_musig_per_input_info(dispatcher_context_t *dc, LEDGER_ASSERT(musig_info->n <= MAX_PUBKEYS_PER_MUSIG, "Too many keys in musig key expression"); for (int i = 0; i < musig_info->n; i++) { // we use ext_pubkey as a temporary variable; will overwrite later - if (0 > get_extended_pubkey(dc, &wdi, key_indexes[i], &ext_pubkey)) { + if (0 > get_extended_pubkey_from_client(dc, &wdi, key_indexes[i], &ext_pubkey)) { return -1; } memcpy(out->keys[i], ext_pubkey.compressed_pubkey, sizeof(ext_pubkey.compressed_pubkey)); From e6b07cebd91efe0f8c58f59f3066b21f4bd5b943 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Thu, 21 Nov 2024 15:38:17 +0000 Subject: [PATCH 45/57] Refactor most of the MuSig2-related code out of sign_psbt.c --- src/handler/sign_psbt.c | 645 +------------------------- src/handler/sign_psbt.h | 152 ++++++ src/handler/sign_psbt/musig_signing.c | 490 +++++++++++++++++++ src/handler/sign_psbt/musig_signing.h | 60 +++ 4 files changed, 705 insertions(+), 642 deletions(-) create mode 100644 src/handler/sign_psbt.h create mode 100644 src/handler/sign_psbt/musig_signing.c create mode 100644 src/handler/sign_psbt/musig_signing.h diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 67f969bd1..de8337786 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -48,10 +48,12 @@ #include "lib/psbt_parse_rawtx.h" #include "handlers.h" +#include "sign_psbt.h" -#include "sign_psbt/sign_psbt_cache.h" #include "sign_psbt/compare_wallet_script_at_path.h" #include "sign_psbt/extract_bip32_derivation.h" +#include "sign_psbt/musig_signing.h" +#include "sign_psbt/sign_psbt_cache.h" #include "sign_psbt/update_hashes_with_map_value.h" #include "../swap/swap_globals.h" @@ -59,153 +61,6 @@ #include "../musig/musig.h" #include "../musig/musig_sessions.h" -// common info that applies to either the current input or the current output -typedef struct { - merkleized_map_commitment_t map; - - bool unexpected_pubkey_error; // Set to true if the pubkey in the keydata of - // PSBT_{IN,OUT}_BIP32_DERIVATION or - // PSBT_{IN,OUT}_TAP_BIP32_DERIVATION is not the correct length. - - bool key_expression_found; // Set to true if the input/output info in the psbt was correctly - // matched with the current key expression in the signing flow - - bool is_change; - int address_index; - - // For an output, its scriptPubKey - // for an input, the prevout's scriptPubKey (either from the non-witness-utxo, or from the - // witness-utxo) - - uint8_t scriptPubKey[MAX_OUTPUT_SCRIPTPUBKEY_LEN]; - size_t scriptPubKey_len; -} in_out_info_t; - -typedef struct { - in_out_info_t in_out; - bool has_witnessUtxo; - bool has_nonWitnessUtxo; - bool has_redeemScript; - bool has_sighash_type; - - uint64_t prevout_amount; // the value of the prevout of the current input - - // we no longer need the script when we compute the taptree hash right before a taproot key-path - // spending; therefore, we reuse the same memory - union { - // the script used when signing, either from the witness utxo or the redeem script - uint8_t script[MAX_PREVOUT_SCRIPTPUBKEY_LEN]; - uint8_t taptree_hash[32]; - }; - - size_t script_len; - - uint32_t sighash_type; -} input_info_t; - -typedef struct { - in_out_info_t in_out; - uint64_t value; -} output_info_t; - -typedef struct { - policy_node_keyexpr_t *key_expression_ptr; - // index of this key expression in the descriptor template, in parsing order - int index; - uint32_t fingerprint; - - // we only sign for keys expressions for which we find a matching key derivation in the PSBT, - // at least for one of the inputs - bool to_sign; - - // info about the internal key of this key expression - // used at signing time to derive the correct key - uint32_t key_derivation[MAX_BIP32_PATH_STEPS]; - uint8_t key_derivation_length; - - // same as key_derivation_length for internal key - // expressions; 0 for musig, as the key derivation in - // the PSBT use the aggregate key as the root - // used to identify the correct change/address_index from the psbt - uint8_t psbt_root_key_derivation_length; - - // the root pubkey of this key expression - serialized_extended_pubkey_t pubkey; - // the pubkey of the internal key of this key expression. - // same as `pubkey` for simple key expressions, but it's the actual - // internal key for musig key expressions - serialized_extended_pubkey_t internal_pubkey; - - bool is_tapscript; // true if signing with a BIP342 tapleaf script path spend - // only used for tapscripts - const policy_node_t *tapleaf_ptr; - uint8_t tapleaf_hash[32]; -} keyexpr_info_t; - -// Cache for partial hashes during signing (avoid quadratic hashing for segwit transactions) -typedef struct tx_hashes_s { - uint8_t sha_prevouts[32]; - uint8_t sha_amounts[32]; - uint8_t sha_scriptpubkeys[32]; - uint8_t sha_sequences[32]; - uint8_t sha_outputs[32]; -} tx_hashes_t; - -// the signing state for the current transaction; it does not contain any per-input state -typedef struct signing_state_s { - tx_hashes_t tx_hashes; - musig_signing_state_t musig; -} signing_state_t; - -// We cache the first 2 external outputs; that's needed for the swap checks -// Moreover, this helps the code for the simplified UX for transactions that -// have a single external output. -#define N_CACHED_EXTERNAL_OUTPUTS 2 - -typedef struct { - uint32_t master_key_fingerprint; - uint32_t tx_version; - uint32_t locktime; - - unsigned int n_internal_key_expressions; - keyexpr_info_t internal_key_expressions[MAX_INTERNAL_KEY_EXPRESSIONS]; - - unsigned int n_inputs; - uint8_t inputs_root[32]; // merkle root of the vector of input maps commitments - unsigned int n_outputs; - uint8_t outputs_root[32]; // merkle root of the vector of output maps commitments - - uint64_t inputs_total_amount; - - policy_map_wallet_header_t wallet_header; - - unsigned int n_external_inputs; - unsigned int n_external_outputs; - - // set to true if at least a PSBT_IN_MUSIG2_PUB_NONCE field is present in the PSBT - bool has_musig2_pub_nonces; - - // aggregate info on outputs - struct { - uint64_t total_amount; // amount of all the outputs (external + change) - uint64_t change_total_amount; // total amount of all change outputs - int n_change; // count of outputs compatible with change outputs - size_t output_script_lengths[N_CACHED_EXTERNAL_OUTPUTS]; - uint8_t output_scripts[N_CACHED_EXTERNAL_OUTPUTS][MAX_OUTPUT_SCRIPTPUBKEY_LEN]; - uint64_t output_amounts[N_CACHED_EXTERNAL_OUTPUTS]; - } outputs; - - bool is_wallet_default; - - uint8_t protocol_version; - - __attribute__((aligned(4))) uint8_t wallet_policy_map_bytes[MAX_WALLET_POLICY_BYTES]; - policy_node_t *wallet_policy_map; - - tx_ux_warning_t warnings; - -} sign_psbt_state_t; - /* BIP0341 tags for computing the tagged hashes when computing he sighash */ static const uint8_t BIP0341_sighash_tag[] = {'T', 'a', 'p', 'S', 'i', 'g', 'h', 'a', 's', 'h'}; @@ -2483,437 +2338,6 @@ static bool __attribute__((noinline)) sign_sighash_schnorr_and_yield(dispatcher_ return true; } -static bool __attribute__((noinline)) yield_musig_data(dispatcher_context_t *dc, - sign_psbt_state_t *st, - unsigned int cur_input_index, - const uint8_t *data, - size_t data_len, - uint32_t tag, - const uint8_t participant_pk[static 33], - const uint8_t aggregate_pubkey[static 33], - const uint8_t *tapleaf_hash) { - LOG_PROCESSOR(__FILE__, __LINE__, __func__); - - if (st->protocol_version == 0) { - // Only support version 1 of the protocol - return false; - } - - // bytes: 1 5 varint data_len 33 33 0 or 32 - // CMD_YIELD - // - - // Yield signature - uint8_t cmd = CCMD_YIELD; - dc->add_to_response(&cmd, 1); - - uint8_t buf[9]; - - // Add tag - int tag_varint_len = varint_write(buf, 0, tag); - dc->add_to_response(buf, tag_varint_len); - - // Add input index - int input_index_varint_len = varint_write(buf, 0, cur_input_index); - dc->add_to_response(buf, input_index_varint_len); - - // Add data (pubnonce or partial signature) - dc->add_to_response(data, data_len); - - // Add participant public key - dc->add_to_response(participant_pk, 33); - - // Add aggregate public key - dc->add_to_response(aggregate_pubkey, 33); - - // Add tapleaf hash if provided - if (tapleaf_hash != NULL) { - dc->add_to_response(tapleaf_hash, 32); - } - - dc->finalize_response(SW_INTERRUPTED_EXECUTION); - - if (dc->process_interruption(dc) < 0) { - return false; - } - return true; -} - -// Struct to hold the info computed for a given input in either of the two rounds -typedef struct { - plain_pk_t keys[MAX_PUBKEYS_PER_MUSIG]; - serialized_extended_pubkey_t agg_key_tweaked; - uint8_t psbt_session_id[32]; - uint8_t tweaks[3][32]; // 2 or three tweaks - size_t n_tweaks; - bool is_xonly[3]; // 2 or 3 elements -} musig_per_input_info_t; - -static bool compute_musig_per_input_info(dispatcher_context_t *dc, - sign_psbt_state_t *st, - signing_state_t *signing_state, - const input_info_t *input, - const keyexpr_info_t *keyexpr_info, - musig_per_input_info_t *out) { - LOG_PROCESSOR(__FILE__, __LINE__, __func__); - - if (st->wallet_policy_map->type != TOKEN_TR) { - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } - - const policy_node_tr_t *tr_policy = (policy_node_tr_t *) st->wallet_policy_map; - - // plan: - // 1) compute aggregate pubkey - // 2) compute musig2 tweaks - // 3) compute taproot tweak (if keypath spend) - // 4) compute the psbt_session_id that identifies the psbt-level signing session - - wallet_derivation_info_t wdi = {.n_keys = st->wallet_header.n_keys, - .wallet_version = st->wallet_header.version, - .keys_merkle_root = st->wallet_header.keys_info_merkle_root, - .change = input->in_out.is_change, - .address_index = input->in_out.address_index, - .sign_psbt_cache = NULL}; - - // TODO: code duplication with policy.c::get_derived_pubkey; worth extracting a common method? - - serialized_extended_pubkey_t ext_pubkey; - - const policy_node_keyexpr_t *key_expr = keyexpr_info->key_expression_ptr; - const musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); - const uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); - - LEDGER_ASSERT(musig_info->n <= MAX_PUBKEYS_PER_MUSIG, "Too many keys in musig key expression"); - for (int i = 0; i < musig_info->n; i++) { - // we use ext_pubkey as a temporary variable; will overwrite later - if (0 > get_extended_pubkey_from_client(dc, &wdi, key_indexes[i], &ext_pubkey)) { - return -1; - } - memcpy(out->keys[i], ext_pubkey.compressed_pubkey, sizeof(ext_pubkey.compressed_pubkey)); - } - - // sort the keys in ascending order using bubble sort - for (int i = 0; i < musig_info->n; i++) { - for (int j = 0; j < musig_info->n - 1; j++) { - if (memcmp(out->keys[j], out->keys[j + 1], sizeof(plain_pk_t)) > 0) { - uint8_t tmp[sizeof(plain_pk_t)]; - memcpy(tmp, out->keys[j], sizeof(plain_pk_t)); - memcpy(out->keys[j], out->keys[j + 1], sizeof(plain_pk_t)); - memcpy(out->keys[j + 1], tmp, sizeof(plain_pk_t)); - } - } - } - - // we already computed the aggregate (pre-tweaks) xpub in the keyexpr_info - memcpy(&ext_pubkey, &keyexpr_info->pubkey, sizeof(serialized_extended_pubkey_t)); - - // 2) compute musig2 tweaks - // We always have exactly 2 BIP32 tweaks in wallet policies; if the musig is in the keypath - // spend, we also have an x-only taptweak with the taproot tree hash (or BIP-86/BIP-386 style if - // there is no taproot tree). - - uint32_t change_step = input->in_out.is_change ? keyexpr_info->key_expression_ptr->num_second - : keyexpr_info->key_expression_ptr->num_first; - uint32_t addr_index_step = input->in_out.address_index; - - // in wallet policies, we always have at least two bip32-tweaks, and we might have - // one x-only tweak per BIP-0341 (if spending from the keypath). - out->is_xonly[0] = false; - out->is_xonly[1] = false; - out->n_tweaks = 2; // might be changed to 3 below - - if (0 > bip32_CKDpub(&ext_pubkey, change_step, &out->agg_key_tweaked, out->tweaks[0])) { - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } - - if (0 > bip32_CKDpub(&out->agg_key_tweaked, - addr_index_step, - &out->agg_key_tweaked, - out->tweaks[1])) { - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } - - // 3) compute taproot tweak (if keypath spend) - memset(out->tweaks[2], 0, 32); - if (!keyexpr_info->is_tapscript) { - out->n_tweaks = 3; - out->is_xonly[2] = true; - - crypto_tr_tagged_hash( - BIP0341_taptweak_tag, - sizeof(BIP0341_taptweak_tag), - out->agg_key_tweaked.compressed_pubkey + 1, // xonly key, after BIP-32 tweaks - 32, - input->taptree_hash, - // BIP-86 compliant tweak if there's no taptree, otherwise use the taptree hash - isnull_policy_node_tree(&tr_policy->tree) ? 0 : 32, - out->tweaks[2]); - - // also apply the taptweak to agg_key_tweaked - - uint8_t parity = 0; - crypto_tr_tweak_pubkey(out->agg_key_tweaked.compressed_pubkey + 1, - input->taptree_hash, - isnull_policy_node_tree(&tr_policy->tree) ? 0 : 32, - &parity, - out->agg_key_tweaked.compressed_pubkey + 1); - out->agg_key_tweaked.compressed_pubkey[0] = 0x02 + parity; - } - - // we will no longer use the other fields of the extended pubkey, so we zero them for sanity - memset(out->agg_key_tweaked.chain_code, 0, sizeof(out->agg_key_tweaked.chain_code)); - memset(out->agg_key_tweaked.child_number, 0, sizeof(out->agg_key_tweaked.child_number)); - out->agg_key_tweaked.depth = 0; - memset(out->agg_key_tweaked.parent_fingerprint, - 0, - sizeof(out->agg_key_tweaked.parent_fingerprint)); - memset(out->agg_key_tweaked.version, 0, sizeof(out->agg_key_tweaked.version)); - - // The psbt_session_id identifies the musig signing session for the entire (psbt, wallet_policy) - // pair, in both rounds 1 and 2 of the protocol; it is the same for all the musig placeholders - // in the policy (if more than one), and it is the same for all the inputs in the psbt. By - // making the hash depend on both the wallet policy and the transaction hashes, we make sure - // that an accidental collision is impossible, allowing for independent, parallel MuSig2 signing - // sessions for different transactions or wallet policies. - // Malicious collisions are not a concern, as they would only result in a signing failure (since - // the nonces would be incorrectly regenerated during round 2 of MuSig2). - crypto_tr_tagged_hash( - (uint8_t[]){'P', 's', 'b', 't', 'S', 'e', 's', 's', 'i', 'o', 'n', 'I', 'd'}, - 13, - st->wallet_header.keys_info_merkle_root, // TODO: wallet policy id would be more precise - 32, - (uint8_t *) &signing_state->tx_hashes, - sizeof(tx_hashes_t), - out->psbt_session_id); - - return true; -} - -static bool yield_musig_pubnonce(dispatcher_context_t *dc, - sign_psbt_state_t *st, - unsigned int cur_input_index, - const musig_pubnonce_t *pubnonce, - const uint8_t participant_pk[static 33], - const uint8_t aggregate_pubkey[static 33], - const uint8_t *tapleaf_hash) { - return yield_musig_data(dc, - st, - cur_input_index, - (const uint8_t *) pubnonce, - sizeof(musig_pubnonce_t), - CCMD_YIELD_MUSIG_PUBNONCE_TAG, - participant_pk, - aggregate_pubkey, - tapleaf_hash); -} - -static bool yield_musig_partial_signature(dispatcher_context_t *dc, - sign_psbt_state_t *st, - unsigned int cur_input_index, - const uint8_t psig[static 32], - const uint8_t participant_pk[static 33], - const uint8_t aggregate_pubkey[static 33], - const uint8_t *tapleaf_hash) { - return yield_musig_data(dc, - st, - cur_input_index, - psig, - 32, - CCMD_YIELD_MUSIG_PARTIALSIGNATURE_TAG, - participant_pk, - aggregate_pubkey, - tapleaf_hash); -} - -static bool __attribute__((noinline)) -sign_sighash_musig_and_yield(dispatcher_context_t *dc, - sign_psbt_state_t *st, - signing_state_t *signing_state, - const keyexpr_info_t *keyexpr_info, - const input_info_t *input, - unsigned int cur_input_index, - uint8_t sighash[static 32]) { - LOG_PROCESSOR(__FILE__, __LINE__, __func__); - - musig_per_input_info_t musig_per_input_info; - if (!compute_musig_per_input_info(dc, - st, - signing_state, - input, - keyexpr_info, - &musig_per_input_info)) { - return false; - } - - // 4) check if my pubnonce is in the psbt - // Compute musig_my_psbt_id. It is the psbt key that this signer uses to find pubnonces and - // partial signatures (PSBT_IN_MUSIG2_PUB_NONCE and PSBT_IN_MUSIG2_PARTIAL_SIG fields). The - // length is either 33+33 (keypath spend), or 33+33+32 bytes (tapscript spend). It's the - // concatenation of: - // - the 33-byte compressed pubkey of this participant - // - the 33-byte aggregate compressed pubkey (after all the tweaks) - // - (tapscript only) the 32-byte tapleaf hash - uint8_t musig_my_psbt_id_key[1 + 33 + 33 + 32]; - musig_my_psbt_id_key[0] = PSBT_IN_MUSIG2_PUB_NONCE; - - uint8_t *musig_my_psbt_id = musig_my_psbt_id_key + 1; - size_t psbt_id_len = keyexpr_info->is_tapscript ? 33 + 33 + 32 : 33 + 33; - memcpy(musig_my_psbt_id, keyexpr_info->internal_pubkey.compressed_pubkey, 33); - memcpy(musig_my_psbt_id + 33, musig_per_input_info.agg_key_tweaked.compressed_pubkey, 33); - if (keyexpr_info->is_tapscript) { - memcpy(musig_my_psbt_id + 33 + 33, keyexpr_info->tapleaf_hash, 32); - } - musig_pubnonce_t my_pubnonce; - if (sizeof(musig_pubnonce_t) != call_get_merkleized_map_value(dc, - &input->in_out.map, - musig_my_psbt_id_key, - 1 + psbt_id_len, - my_pubnonce.raw, - sizeof(musig_pubnonce_t))) { - PRINTF("Missing pubnonce in PSBT\n"); - SEND_SW(dc, SW_BAD_STATE); - return false; - } - /** - * Round 2 of the MuSig2 protocol - **/ - - const musig_psbt_session_t *psbt_session = - musigsession_round2_initialize(musig_per_input_info.psbt_session_id, &signing_state->musig); - - if (psbt_session == NULL) { - // The PSBT contains a partial nonce, but we do not have the corresponding psbt - // session in storage. Either it was deleted, or the pubnonces were not real. Either - // way, we cannot continue. - PRINTF("Missing MuSig2 session\n"); - SEND_SW(dc, SW_BAD_STATE); - return false; - } - - // 6) generate and yield partial signature - - const policy_node_keyexpr_t *key_expr = keyexpr_info->key_expression_ptr; - const musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); - - musig_pubnonce_t nonces[MAX_PUBKEYS_PER_MUSIG]; - - for (int i = 0; i < musig_info->n; i++) { - uint8_t musig_ith_psbt_id_key[1 + 33 + 33 + 32]; - uint8_t *musig_ith_psbt_id = musig_ith_psbt_id_key + 1; - // copy from musig_my_psbt_id_key, but replace the corresponding pubkey - memcpy(musig_ith_psbt_id_key, musig_my_psbt_id_key, sizeof(musig_my_psbt_id_key)); - memcpy(musig_ith_psbt_id, musig_per_input_info.keys[i], sizeof(plain_pk_t)); - - if (sizeof(musig_pubnonce_t) != call_get_merkleized_map_value(dc, - &input->in_out.map, - musig_ith_psbt_id_key, - 1 + psbt_id_len, - nonces[i].raw, - sizeof(musig_pubnonce_t))) { - PRINTF("Missing or incorrect pubnonce for a MuSig2 cosigner\n"); - SEND_SW(dc, SW_INCORRECT_DATA); - return false; - } - } - - // compute aggregate nonce - musig_pubnonce_t aggnonce; - int res = musig_nonce_agg(nonces, musig_info->n, &aggnonce); - if (res < 0) { - PRINTF("Musig aggregation failed; disruptive signer has index %d\n", -res); - SEND_SW(dc, SW_INCORRECT_DATA); - } - - // recompute secnonce from psbt_session randomness - uint8_t rand_i_j[32]; - compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->index, rand_i_j); - - musig_secnonce_t secnonce; - musig_pubnonce_t pubnonce; - - if (0 > musig_nonce_gen(rand_i_j, - keyexpr_info->internal_pubkey.compressed_pubkey, - musig_per_input_info.agg_key_tweaked.compressed_pubkey + 1, - &secnonce, - &pubnonce)) { - PRINTF("MuSig2 nonce generation failed\n"); - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } - - // derive secret key - - cx_ecfp_private_key_t private_key = {0}; - uint8_t psig[32]; - bool err = false; - do { // block executed once, only to allow safely breaking out on error - - // derive secret key - uint32_t sign_path[MAX_BIP32_PATH_STEPS]; - - for (int i = 0; i < keyexpr_info->key_derivation_length; i++) { - sign_path[i] = keyexpr_info->key_derivation[i]; - } - int sign_path_len = keyexpr_info->key_derivation_length; - - if (bip32_derive_init_privkey_256(CX_CURVE_256K1, - sign_path, - sign_path_len, - &private_key, - NULL) != CX_OK) { - err = true; - break; - } - - // Create partial signature - uint8_t *tweaks_ptrs[3] = { - musig_per_input_info.tweaks[0], - musig_per_input_info.tweaks[1], - musig_per_input_info.tweaks[2] // the last element is ignored if n_tweaks == 2 - }; - musig_session_context_t musig_session_context = {.aggnonce = &aggnonce, - .n_keys = musig_info->n, - .pubkeys = musig_per_input_info.keys, - .n_tweaks = musig_per_input_info.n_tweaks, - .tweaks = tweaks_ptrs, - .is_xonly = musig_per_input_info.is_xonly, - .msg = sighash, - .msg_len = 32}; - - if (0 > musig_sign(&secnonce, private_key.d, &musig_session_context, psig)) { - PRINTF("Musig2 signature failed\n"); - err = true; - break; - } - } while (false); - - explicit_bzero(&private_key, sizeof(private_key)); - - if (err) { - PRINTF("Partial signature generation failed\n"); - return false; - } - - if (!yield_musig_partial_signature( - dc, - st, - cur_input_index, - psig, - keyexpr_info->internal_pubkey.compressed_pubkey, - musig_per_input_info.agg_key_tweaked.compressed_pubkey, - keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) { - PRINTF("Failed yielding MuSig2 partial signature\n"); - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } - - return true; -} - static bool __attribute__((noinline)) compute_tx_hashes(dispatcher_context_t *dc, sign_psbt_state_t *st, tx_hashes_t *hashes) { { @@ -3279,69 +2703,6 @@ fill_taproot_keyexpr_info(dispatcher_context_t *dc, return true; } -static bool produce_and_yield_pubnonce(dispatcher_context_t *dc, - sign_psbt_state_t *st, - signing_state_t *signing_state, - const keyexpr_info_t *keyexpr_info, - const input_info_t *input, - unsigned int cur_input_index) { - LOG_PROCESSOR(__FILE__, __LINE__, __func__); - - musig_per_input_info_t musig_per_input_info; - if (!compute_musig_per_input_info(dc, - st, - signing_state, - input, - keyexpr_info, - &musig_per_input_info)) { - return false; - } - - /** - * Round 1 of the MuSig2 protocol - **/ - - const musig_psbt_session_t *psbt_session = - musigsession_round1_initialize(musig_per_input_info.psbt_session_id, &signing_state->musig); - if (psbt_session == NULL) { - // This should never happen - PRINTF("Unexpected: failed to initialize MuSig2 round 1\n"); - SEND_SW(dc, SW_BAD_STATE); - return false; - } - - // 5) generate and yield pubnonce - - uint8_t rand_i_j[32]; - compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->index, rand_i_j); - - musig_secnonce_t secnonce; - musig_pubnonce_t pubnonce; - if (0 > musig_nonce_gen(rand_i_j, - keyexpr_info->internal_pubkey.compressed_pubkey, - musig_per_input_info.agg_key_tweaked.compressed_pubkey + 1, - &secnonce, - &pubnonce)) { - PRINTF("MuSig2 nonce generation failed\n"); - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } - - if (!yield_musig_pubnonce(dc, - st, - cur_input_index, - &pubnonce, - keyexpr_info->internal_pubkey.compressed_pubkey, - musig_per_input_info.agg_key_tweaked.compressed_pubkey, - keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) { - PRINTF("Failed yielding MuSig2 pubnonce\n"); - SEND_SW(dc, SW_BAD_STATE); // should never happen - return false; - } - - return true; -} - static bool __attribute__((noinline)) produce_musig2_pubnonces( dispatcher_context_t *dc, sign_psbt_state_t *st, diff --git a/src/handler/sign_psbt.h b/src/handler/sign_psbt.h new file mode 100644 index 000000000..c132b17f2 --- /dev/null +++ b/src/handler/sign_psbt.h @@ -0,0 +1,152 @@ +#pragma once + +#include "../musig/musig_sessions.h" +#include "../common/merkle.h" +#include "../ui/display.h" + +// common info that applies to either the current input or the current output +typedef struct { + merkleized_map_commitment_t map; + + bool unexpected_pubkey_error; // Set to true if the pubkey in the keydata of + // PSBT_{IN,OUT}_BIP32_DERIVATION or + // PSBT_{IN,OUT}_TAP_BIP32_DERIVATION is not the correct length. + + bool key_expression_found; // Set to true if the input/output info in the psbt was correctly + // matched with the current key expression in the signing flow + + bool is_change; + int address_index; + + // For an output, its scriptPubKey + // for an input, the prevout's scriptPubKey (either from the non-witness-utxo, or from the + // witness-utxo) + + uint8_t scriptPubKey[MAX_OUTPUT_SCRIPTPUBKEY_LEN]; + size_t scriptPubKey_len; +} in_out_info_t; + +typedef struct { + in_out_info_t in_out; + bool has_witnessUtxo; + bool has_nonWitnessUtxo; + bool has_redeemScript; + bool has_sighash_type; + + uint64_t prevout_amount; // the value of the prevout of the current input + + // we no longer need the script when we compute the taptree hash right before a taproot key-path + // spending; therefore, we reuse the same memory + union { + // the script used when signing, either from the witness utxo or the redeem script + uint8_t script[MAX_PREVOUT_SCRIPTPUBKEY_LEN]; + uint8_t taptree_hash[32]; + }; + + size_t script_len; + + uint32_t sighash_type; +} input_info_t; + +typedef struct { + in_out_info_t in_out; + uint64_t value; +} output_info_t; + +typedef struct { + policy_node_keyexpr_t *key_expression_ptr; + // index of this key expression in the descriptor template, in parsing order + int index; + uint32_t fingerprint; + + // we only sign for keys expressions for which we find a matching key derivation in the PSBT, + // at least for one of the inputs + bool to_sign; + + // info about the internal key of this key expression + // used at signing time to derive the correct key + uint32_t key_derivation[MAX_BIP32_PATH_STEPS]; + uint8_t key_derivation_length; + + // same as key_derivation_length for internal key + // expressions; 0 for musig, as the key derivation in + // the PSBT use the aggregate key as the root + // used to identify the correct change/address_index from the psbt + uint8_t psbt_root_key_derivation_length; + + // the root pubkey of this key expression + serialized_extended_pubkey_t pubkey; + // the pubkey of the internal key of this key expression. + // same as `pubkey` for simple key expressions, but it's the actual + // internal key for musig key expressions + serialized_extended_pubkey_t internal_pubkey; + + bool is_tapscript; // true if signing with a BIP342 tapleaf script path spend + // only used for tapscripts + const policy_node_t *tapleaf_ptr; + uint8_t tapleaf_hash[32]; +} keyexpr_info_t; + +// Cache for partial hashes during signing (avoid quadratic hashing for segwit transactions) +typedef struct tx_hashes_s { + uint8_t sha_prevouts[32]; + uint8_t sha_amounts[32]; + uint8_t sha_scriptpubkeys[32]; + uint8_t sha_sequences[32]; + uint8_t sha_outputs[32]; +} tx_hashes_t; + +// the signing state for the current transaction; it does not contain any per-input state +typedef struct signing_state_s { + tx_hashes_t tx_hashes; + musig_signing_state_t musig; +} signing_state_t; + +// We cache the first 2 external outputs; that's needed for the swap checks +// Moreover, this helps the code for the simplified UX for transactions that +// have a single external output. +#define N_CACHED_EXTERNAL_OUTPUTS 2 + +typedef struct { + uint32_t master_key_fingerprint; + uint32_t tx_version; + uint32_t locktime; + + unsigned int n_internal_key_expressions; + keyexpr_info_t internal_key_expressions[MAX_INTERNAL_KEY_EXPRESSIONS]; + + unsigned int n_inputs; + uint8_t inputs_root[32]; // merkle root of the vector of input maps commitments + unsigned int n_outputs; + uint8_t outputs_root[32]; // merkle root of the vector of output maps commitments + + uint64_t inputs_total_amount; + + policy_map_wallet_header_t wallet_header; + + unsigned int n_external_inputs; + unsigned int n_external_outputs; + + // set to true if at least a PSBT_IN_MUSIG2_PUB_NONCE field is present in the PSBT + bool has_musig2_pub_nonces; + + // aggregate info on outputs + struct { + uint64_t total_amount; // amount of all the outputs (external + change) + uint64_t change_total_amount; // total amount of all change outputs + int n_change; // count of outputs compatible with change outputs + size_t output_script_lengths[N_CACHED_EXTERNAL_OUTPUTS]; + uint8_t output_scripts[N_CACHED_EXTERNAL_OUTPUTS][MAX_OUTPUT_SCRIPTPUBKEY_LEN]; + uint64_t output_amounts[N_CACHED_EXTERNAL_OUTPUTS]; + } outputs; + + bool is_wallet_default; + + uint8_t protocol_version; + + __attribute__((aligned(4))) uint8_t wallet_policy_map_bytes[MAX_WALLET_POLICY_BYTES]; + policy_node_t *wallet_policy_map; + + tx_ux_warning_t warnings; + +} sign_psbt_state_t; diff --git a/src/handler/sign_psbt/musig_signing.c b/src/handler/sign_psbt/musig_signing.c new file mode 100644 index 000000000..068b320b7 --- /dev/null +++ b/src/handler/sign_psbt/musig_signing.c @@ -0,0 +1,490 @@ +#include "musig_signing.h" +#include "lib_standard_app/crypto_helpers.h" +#include "../boilerplate/sw.h" +#include "../common/psbt.h" +#include "../client_commands.h" +#include "../lib/get_merkleized_map_value.h" +#include "../lib/policy.h" + +bool compute_musig_per_input_info(dispatcher_context_t *dc, + sign_psbt_state_t *st, + signing_state_t *signing_state, + const input_info_t *input, + const keyexpr_info_t *keyexpr_info, + musig_per_input_info_t *out) { + LOG_PROCESSOR(__FILE__, __LINE__, __func__); + + if (st->wallet_policy_map->type != TOKEN_TR) { + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + const policy_node_tr_t *tr_policy = (policy_node_tr_t *) st->wallet_policy_map; + + // plan: + // 1) compute aggregate pubkey + // 2) compute musig2 tweaks + // 3) compute taproot tweak (if keypath spend) + // 4) compute the psbt_session_id that identifies the psbt-level signing session + + wallet_derivation_info_t wdi = {.n_keys = st->wallet_header.n_keys, + .wallet_version = st->wallet_header.version, + .keys_merkle_root = st->wallet_header.keys_info_merkle_root, + .change = input->in_out.is_change, + .address_index = input->in_out.address_index, + .sign_psbt_cache = NULL}; + + // TODO: code duplication with policy.c::get_derived_pubkey; worth extracting a common method? + + serialized_extended_pubkey_t ext_pubkey; + + const policy_node_keyexpr_t *key_expr = keyexpr_info->key_expression_ptr; + const musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); + const uint16_t *key_indexes = r_uint16(&musig_info->key_indexes); + + LEDGER_ASSERT(musig_info->n <= MAX_PUBKEYS_PER_MUSIG, "Too many keys in musig key expression"); + for (int i = 0; i < musig_info->n; i++) { + // we use ext_pubkey as a temporary variable; will overwrite later + if (0 > get_extended_pubkey_from_client(dc, &wdi, key_indexes[i], &ext_pubkey)) { + return -1; + } + memcpy(out->keys[i], ext_pubkey.compressed_pubkey, sizeof(ext_pubkey.compressed_pubkey)); + } + + // sort the keys in ascending order using bubble sort + for (int i = 0; i < musig_info->n; i++) { + for (int j = 0; j < musig_info->n - 1; j++) { + if (memcmp(out->keys[j], out->keys[j + 1], sizeof(plain_pk_t)) > 0) { + uint8_t tmp[sizeof(plain_pk_t)]; + memcpy(tmp, out->keys[j], sizeof(plain_pk_t)); + memcpy(out->keys[j], out->keys[j + 1], sizeof(plain_pk_t)); + memcpy(out->keys[j + 1], tmp, sizeof(plain_pk_t)); + } + } + } + + // we already computed the aggregate (pre-tweaks) xpub in the keyexpr_info + memcpy(&ext_pubkey, &keyexpr_info->pubkey, sizeof(serialized_extended_pubkey_t)); + + // 2) compute musig2 tweaks + // We always have exactly 2 BIP32 tweaks in wallet policies; if the musig is in the keypath + // spend, we also have an x-only taptweak with the taproot tree hash (or BIP-86/BIP-386 style if + // there is no taproot tree). + + uint32_t change_step = input->in_out.is_change ? keyexpr_info->key_expression_ptr->num_second + : keyexpr_info->key_expression_ptr->num_first; + uint32_t addr_index_step = input->in_out.address_index; + + // in wallet policies, we always have at least two bip32-tweaks, and we might have + // one x-only tweak per BIP-0341 (if spending from the keypath). + out->is_xonly[0] = false; + out->is_xonly[1] = false; + out->n_tweaks = 2; // might be changed to 3 below + + if (0 > bip32_CKDpub(&ext_pubkey, change_step, &out->agg_key_tweaked, out->tweaks[0])) { + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + if (0 > bip32_CKDpub(&out->agg_key_tweaked, + addr_index_step, + &out->agg_key_tweaked, + out->tweaks[1])) { + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + // 3) compute taproot tweak (if keypath spend) + memset(out->tweaks[2], 0, 32); + if (!keyexpr_info->is_tapscript) { + out->n_tweaks = 3; + out->is_xonly[2] = true; + + crypto_tr_tagged_hash( + BIP0341_taptweak_tag, + sizeof(BIP0341_taptweak_tag), + out->agg_key_tweaked.compressed_pubkey + 1, // xonly key, after BIP-32 tweaks + 32, + input->taptree_hash, + // BIP-86 compliant tweak if there's no taptree, otherwise use the taptree hash + isnull_policy_node_tree(&tr_policy->tree) ? 0 : 32, + out->tweaks[2]); + + // also apply the taptweak to agg_key_tweaked + + uint8_t parity = 0; + crypto_tr_tweak_pubkey(out->agg_key_tweaked.compressed_pubkey + 1, + input->taptree_hash, + isnull_policy_node_tree(&tr_policy->tree) ? 0 : 32, + &parity, + out->agg_key_tweaked.compressed_pubkey + 1); + out->agg_key_tweaked.compressed_pubkey[0] = 0x02 + parity; + } + + // we will no longer use the other fields of the extended pubkey, so we zero them for sanity + memset(out->agg_key_tweaked.chain_code, 0, sizeof(out->agg_key_tweaked.chain_code)); + memset(out->agg_key_tweaked.child_number, 0, sizeof(out->agg_key_tweaked.child_number)); + out->agg_key_tweaked.depth = 0; + memset(out->agg_key_tweaked.parent_fingerprint, + 0, + sizeof(out->agg_key_tweaked.parent_fingerprint)); + memset(out->agg_key_tweaked.version, 0, sizeof(out->agg_key_tweaked.version)); + + // The psbt_session_id identifies the musig signing session for the entire (psbt, wallet_policy) + // pair, in both rounds 1 and 2 of the protocol; it is the same for all the musig placeholders + // in the policy (if more than one), and it is the same for all the inputs in the psbt. By + // making the hash depend on both the wallet policy and the transaction hashes, we make sure + // that an accidental collision is impossible, allowing for independent, parallel MuSig2 signing + // sessions for different transactions or wallet policies. + // Malicious collisions are not a concern, as they would only result in a signing failure (since + // the nonces would be incorrectly regenerated during round 2 of MuSig2). + crypto_tr_tagged_hash( + (uint8_t[]){'P', 's', 'b', 't', 'S', 'e', 's', 's', 'i', 'o', 'n', 'I', 'd'}, + 13, + st->wallet_header.keys_info_merkle_root, // TODO: wallet policy id would be more precise + 32, + (uint8_t *) &signing_state->tx_hashes, + sizeof(tx_hashes_t), + out->psbt_session_id); + + return true; +} + +static bool __attribute__((noinline)) yield_musig_data(dispatcher_context_t *dc, + sign_psbt_state_t *st, + unsigned int cur_input_index, + const uint8_t *data, + size_t data_len, + uint32_t tag, + const uint8_t participant_pk[static 33], + const uint8_t aggregate_pubkey[static 33], + const uint8_t *tapleaf_hash) { + LOG_PROCESSOR(__FILE__, __LINE__, __func__); + + if (st->protocol_version == 0) { + // Only support version 1 of the protocol + return false; + } + + // bytes: 1 5 varint data_len 33 33 0 or 32 + // CMD_YIELD + // + + // Yield signature + uint8_t cmd = CCMD_YIELD; + dc->add_to_response(&cmd, 1); + + uint8_t buf[9]; + + // Add tag + int tag_varint_len = varint_write(buf, 0, tag); + dc->add_to_response(buf, tag_varint_len); + + // Add input index + int input_index_varint_len = varint_write(buf, 0, cur_input_index); + dc->add_to_response(buf, input_index_varint_len); + + // Add data (pubnonce or partial signature) + dc->add_to_response(data, data_len); + + // Add participant public key + dc->add_to_response(participant_pk, 33); + + // Add aggregate public key + dc->add_to_response(aggregate_pubkey, 33); + + // Add tapleaf hash if provided + if (tapleaf_hash != NULL) { + dc->add_to_response(tapleaf_hash, 32); + } + + dc->finalize_response(SW_INTERRUPTED_EXECUTION); + + if (dc->process_interruption(dc) < 0) { + return false; + } + return true; +} + +static bool yield_musig_pubnonce(dispatcher_context_t *dc, + sign_psbt_state_t *st, + unsigned int cur_input_index, + const musig_pubnonce_t *pubnonce, + const uint8_t participant_pk[static 33], + const uint8_t aggregate_pubkey[static 33], + const uint8_t *tapleaf_hash) { + return yield_musig_data(dc, + st, + cur_input_index, + (const uint8_t *) pubnonce, + sizeof(musig_pubnonce_t), + CCMD_YIELD_MUSIG_PUBNONCE_TAG, + participant_pk, + aggregate_pubkey, + tapleaf_hash); +} + +static bool yield_musig_partial_signature(dispatcher_context_t *dc, + sign_psbt_state_t *st, + unsigned int cur_input_index, + const uint8_t psig[static 32], + const uint8_t participant_pk[static 33], + const uint8_t aggregate_pubkey[static 33], + const uint8_t *tapleaf_hash) { + return yield_musig_data(dc, + st, + cur_input_index, + psig, + 32, + CCMD_YIELD_MUSIG_PARTIALSIGNATURE_TAG, + participant_pk, + aggregate_pubkey, + tapleaf_hash); +} + +bool produce_and_yield_pubnonce(dispatcher_context_t *dc, + sign_psbt_state_t *st, + signing_state_t *signing_state, + const keyexpr_info_t *keyexpr_info, + const input_info_t *input, + unsigned int cur_input_index) { + LOG_PROCESSOR(__FILE__, __LINE__, __func__); + + musig_per_input_info_t musig_per_input_info; + if (!compute_musig_per_input_info(dc, + st, + signing_state, + input, + keyexpr_info, + &musig_per_input_info)) { + return false; + } + + /** + * Round 1 of the MuSig2 protocol + **/ + + const musig_psbt_session_t *psbt_session = + musigsession_round1_initialize(musig_per_input_info.psbt_session_id, &signing_state->musig); + if (psbt_session == NULL) { + // This should never happen + PRINTF("Unexpected: failed to initialize MuSig2 round 1\n"); + SEND_SW(dc, SW_BAD_STATE); + return false; + } + + // 5) generate and yield pubnonce + + uint8_t rand_i_j[32]; + compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->index, rand_i_j); + + musig_secnonce_t secnonce; + musig_pubnonce_t pubnonce; + if (0 > musig_nonce_gen(rand_i_j, + keyexpr_info->internal_pubkey.compressed_pubkey, + musig_per_input_info.agg_key_tweaked.compressed_pubkey + 1, + &secnonce, + &pubnonce)) { + PRINTF("MuSig2 nonce generation failed\n"); + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + if (!yield_musig_pubnonce(dc, + st, + cur_input_index, + &pubnonce, + keyexpr_info->internal_pubkey.compressed_pubkey, + musig_per_input_info.agg_key_tweaked.compressed_pubkey, + keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) { + PRINTF("Failed yielding MuSig2 pubnonce\n"); + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + return true; +} + +bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_context_t *dc, + sign_psbt_state_t *st, + signing_state_t *signing_state, + const keyexpr_info_t *keyexpr_info, + const input_info_t *input, + unsigned int cur_input_index, + uint8_t sighash[static 32]) { + LOG_PROCESSOR(__FILE__, __LINE__, __func__); + + musig_per_input_info_t musig_per_input_info; + if (!compute_musig_per_input_info(dc, + st, + signing_state, + input, + keyexpr_info, + &musig_per_input_info)) { + return false; + } + + // 4) check if my pubnonce is in the psbt + // Compute musig_my_psbt_id. It is the psbt key that this signer uses to find pubnonces and + // partial signatures (PSBT_IN_MUSIG2_PUB_NONCE and PSBT_IN_MUSIG2_PARTIAL_SIG fields). The + // length is either 33+33 (keypath spend), or 33+33+32 bytes (tapscript spend). It's the + // concatenation of: + // - the 33-byte compressed pubkey of this participant + // - the 33-byte aggregate compressed pubkey (after all the tweaks) + // - (tapscript only) the 32-byte tapleaf hash + uint8_t musig_my_psbt_id_key[1 + 33 + 33 + 32]; + musig_my_psbt_id_key[0] = PSBT_IN_MUSIG2_PUB_NONCE; + + uint8_t *musig_my_psbt_id = musig_my_psbt_id_key + 1; + size_t psbt_id_len = keyexpr_info->is_tapscript ? 33 + 33 + 32 : 33 + 33; + memcpy(musig_my_psbt_id, keyexpr_info->internal_pubkey.compressed_pubkey, 33); + memcpy(musig_my_psbt_id + 33, musig_per_input_info.agg_key_tweaked.compressed_pubkey, 33); + if (keyexpr_info->is_tapscript) { + memcpy(musig_my_psbt_id + 33 + 33, keyexpr_info->tapleaf_hash, 32); + } + musig_pubnonce_t my_pubnonce; + if (sizeof(musig_pubnonce_t) != call_get_merkleized_map_value(dc, + &input->in_out.map, + musig_my_psbt_id_key, + 1 + psbt_id_len, + my_pubnonce.raw, + sizeof(musig_pubnonce_t))) { + PRINTF("Missing pubnonce in PSBT\n"); + SEND_SW(dc, SW_BAD_STATE); + return false; + } + /** + * Round 2 of the MuSig2 protocol + **/ + + const musig_psbt_session_t *psbt_session = + musigsession_round2_initialize(musig_per_input_info.psbt_session_id, &signing_state->musig); + + if (psbt_session == NULL) { + // The PSBT contains a partial nonce, but we do not have the corresponding psbt + // session in storage. Either it was deleted, or the pubnonces were not real. Either + // way, we cannot continue. + PRINTF("Missing MuSig2 session\n"); + SEND_SW(dc, SW_BAD_STATE); + return false; + } + + // 6) generate and yield partial signature + + const policy_node_keyexpr_t *key_expr = keyexpr_info->key_expression_ptr; + const musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); + + musig_pubnonce_t nonces[MAX_PUBKEYS_PER_MUSIG]; + + for (int i = 0; i < musig_info->n; i++) { + uint8_t musig_ith_psbt_id_key[1 + 33 + 33 + 32]; + uint8_t *musig_ith_psbt_id = musig_ith_psbt_id_key + 1; + // copy from musig_my_psbt_id_key, but replace the corresponding pubkey + memcpy(musig_ith_psbt_id_key, musig_my_psbt_id_key, sizeof(musig_my_psbt_id_key)); + memcpy(musig_ith_psbt_id, musig_per_input_info.keys[i], sizeof(plain_pk_t)); + + if (sizeof(musig_pubnonce_t) != call_get_merkleized_map_value(dc, + &input->in_out.map, + musig_ith_psbt_id_key, + 1 + psbt_id_len, + nonces[i].raw, + sizeof(musig_pubnonce_t))) { + PRINTF("Missing or incorrect pubnonce for a MuSig2 cosigner\n"); + SEND_SW(dc, SW_INCORRECT_DATA); + return false; + } + } + + // compute aggregate nonce + musig_pubnonce_t aggnonce; + int res = musig_nonce_agg(nonces, musig_info->n, &aggnonce); + if (res < 0) { + PRINTF("Musig aggregation failed; disruptive signer has index %d\n", -res); + SEND_SW(dc, SW_INCORRECT_DATA); + } + + // recompute secnonce from psbt_session randomness + uint8_t rand_i_j[32]; + compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->index, rand_i_j); + + musig_secnonce_t secnonce; + musig_pubnonce_t pubnonce; + + if (0 > musig_nonce_gen(rand_i_j, + keyexpr_info->internal_pubkey.compressed_pubkey, + musig_per_input_info.agg_key_tweaked.compressed_pubkey + 1, + &secnonce, + &pubnonce)) { + PRINTF("MuSig2 nonce generation failed\n"); + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + // derive secret key + + cx_ecfp_private_key_t private_key = {0}; + uint8_t psig[32]; + bool err = false; + do { // block executed once, only to allow safely breaking out on error + + // derive secret key + uint32_t sign_path[MAX_BIP32_PATH_STEPS]; + + for (int i = 0; i < keyexpr_info->key_derivation_length; i++) { + sign_path[i] = keyexpr_info->key_derivation[i]; + } + int sign_path_len = keyexpr_info->key_derivation_length; + + if (bip32_derive_init_privkey_256(CX_CURVE_256K1, + sign_path, + sign_path_len, + &private_key, + NULL) != CX_OK) { + err = true; + break; + } + + // Create partial signature + uint8_t *tweaks_ptrs[3] = { + musig_per_input_info.tweaks[0], + musig_per_input_info.tweaks[1], + musig_per_input_info.tweaks[2] // the last element is ignored if n_tweaks == 2 + }; + musig_session_context_t musig_session_context = {.aggnonce = &aggnonce, + .n_keys = musig_info->n, + .pubkeys = musig_per_input_info.keys, + .n_tweaks = musig_per_input_info.n_tweaks, + .tweaks = tweaks_ptrs, + .is_xonly = musig_per_input_info.is_xonly, + .msg = sighash, + .msg_len = 32}; + + if (0 > musig_sign(&secnonce, private_key.d, &musig_session_context, psig)) { + PRINTF("Musig2 signature failed\n"); + err = true; + break; + } + } while (false); + + explicit_bzero(&private_key, sizeof(private_key)); + + if (err) { + PRINTF("Partial signature generation failed\n"); + return false; + } + + if (!yield_musig_partial_signature( + dc, + st, + cur_input_index, + psig, + keyexpr_info->internal_pubkey.compressed_pubkey, + musig_per_input_info.agg_key_tweaked.compressed_pubkey, + keyexpr_info->is_tapscript ? keyexpr_info->tapleaf_hash : NULL)) { + PRINTF("Failed yielding MuSig2 partial signature\n"); + SEND_SW(dc, SW_BAD_STATE); // should never happen + return false; + } + + return true; +} diff --git a/src/handler/sign_psbt/musig_signing.h b/src/handler/sign_psbt/musig_signing.h new file mode 100644 index 000000000..ae20c484b --- /dev/null +++ b/src/handler/sign_psbt/musig_signing.h @@ -0,0 +1,60 @@ +#include +#include "../common/wallet.h" +#include "../musig/musig.h" +#include "../boilerplate/dispatcher.h" +#include "../sign_psbt.h" + +// Struct to hold the info computed for a given input in either of the two rounds +typedef struct { + plain_pk_t keys[MAX_PUBKEYS_PER_MUSIG]; + serialized_extended_pubkey_t agg_key_tweaked; + uint8_t psbt_session_id[32]; + uint8_t tweaks[3][32]; // 2 or three tweaks + size_t n_tweaks; // always 2 or 3 for supported BIP-388 wallet policies + bool is_xonly[3]; // 2 or 3 elements +} musig_per_input_info_t; + +/** + * Computes the MuSig2 per-input, per-key-expression information. + * + * This function calculates the necessary information for each input in the MuSig protocol. + * It is the shared logic that is common between both rounds of the MuSig2 protocol. + * + * Returns true if the computation is successful, false otherwise. In case of failure, it already + * sends an error status word. + */ +bool compute_musig_per_input_info(dispatcher_context_t *dc, + sign_psbt_state_t *st, + signing_state_t *signing_state, + const input_info_t *input, + const keyexpr_info_t *keyexpr_info, + musig_per_input_info_t *out); + +/** + * Computes and yields the pubnonce for the current input and placeholder, during Round 1 of the + * MuSig2 protocol. + * + * Returns true if the computation is successful, false otherwise. In case of failure, it already + * sends an error status word. + */ +bool produce_and_yield_pubnonce(dispatcher_context_t *dc, + sign_psbt_state_t *st, + signing_state_t *signing_state, + const keyexpr_info_t *keyexpr_info, + const input_info_t *input, + unsigned int cur_input_index); + +/** + * Computes and yields the partial signature for a certain sighash, during Round 2 of the MuSig2 + * protocol. + * + * Returns true if the computation is successful, false otherwise. In case of failure, it already + * sends an error status word. + */ +bool sign_sighash_musig_and_yield(dispatcher_context_t *dc, + sign_psbt_state_t *st, + signing_state_t *signing_state, + const keyexpr_info_t *keyexpr_info, + const input_info_t *input, + unsigned int cur_input_index, + uint8_t sighash[static 32]); From 568153facbaf23fc19602d1868d84402aee477d9 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Fri, 29 Nov 2024 09:34:31 +0000 Subject: [PATCH 46/57] Use qsort for sorting In the past, while the app was deployed on Nano S, we preferred avoiding the use of Nano S in order to reduce the binary size. Now, using qsort makes the code more readable and succinct. --- src/handler/lib/policy.c | 36 ++++++++------------------- src/handler/sign_psbt.c | 14 +++-------- src/handler/sign_psbt/musig_signing.c | 15 +++-------- src/musig/musig.h | 6 +++++ 4 files changed, 24 insertions(+), 47 deletions(-) diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c index 9ecf54281..ad348cc9f 100644 --- a/src/handler/lib/policy.c +++ b/src/handler/lib/policy.c @@ -485,17 +485,8 @@ __attribute__((warn_unused_result)) static int get_derived_pubkey( memcpy(keys[i], ext_pubkey.compressed_pubkey, sizeof(ext_pubkey.compressed_pubkey)); } - // sort the keys in ascending order using bubble sort - for (int i = 0; i < musig_info->n; i++) { - for (int j = 0; j < musig_info->n - 1; j++) { - if (memcmp(keys[j], keys[j + 1], sizeof(plain_pk_t)) > 0) { - uint8_t tmp[sizeof(plain_pk_t)]; - memcpy(tmp, keys[j], sizeof(plain_pk_t)); - memcpy(keys[j], keys[j + 1], sizeof(plain_pk_t)); - memcpy(keys[j + 1], tmp, sizeof(plain_pk_t)); - } - } - } + // sort the keys in ascending order + qsort(keys, musig_info->n, sizeof(plain_pk_t), compare_plain_pk); musig_keyagg_context_t musig_ctx; musig_key_agg(keys, musig_info->n, &musig_ctx); @@ -1903,17 +1894,11 @@ static int is_taptree_miniscript_sane(const policy_node_tree_t *taptree) { return 0; } -// sort an array of uint16_t in place using bubble sort -static void sort_uint16_array(uint16_t *array, size_t n) { - for (size_t i = 0; i < n; i++) { - for (size_t j = i + 1; j < n; j++) { - if (array[i] > array[j]) { - uint16_t tmp = array[i]; - array[i] = array[j]; - array[j] = tmp; - } - } - } +static int compare_uint16(const void *a, const void *b) { + uint16_t num1 = *(const uint16_t *) a; + uint16_t num2 = *(const uint16_t *) b; + + return (num1 > num2) - (num1 < num2); } static bool are_key_placeholders_identical(const policy_node_keyexpr_t *kp1, @@ -1942,8 +1927,8 @@ static bool are_key_placeholders_identical(const policy_node_keyexpr_t *kp1, memcpy(key_indexes_j_sorted, key_indexes_j, musig_info_j->n * sizeof(uint16_t)); // sort the arrays - sort_uint16_array(key_indexes_i_sorted, musig_info_i->n); - sort_uint16_array(key_indexes_j_sorted, musig_info_j->n); + qsort(key_indexes_i_sorted, musig_info_i->n, sizeof(uint16_t), compare_uint16); + qsort(key_indexes_j_sorted, musig_info_j->n, sizeof(uint16_t), compare_uint16); if (memcmp(key_indexes_i_sorted, key_indexes_j_sorted, @@ -2036,7 +2021,8 @@ int is_policy_sane(dispatcher_context_t *dispatcher_context, memcpy(key_indexes_i_sorted, key_indexes_i, musig_info_i->n * sizeof(uint16_t)); // sort the arrays - sort_uint16_array(key_indexes_i_sorted, musig_info_i->n); + qsort(key_indexes_i_sorted, musig_info_i->n, sizeof(uint16_t), compare_uint16); + for (int j = 0; j < musig_info_i->n - 1; j++) { if (key_indexes_i_sorted[j] == key_indexes_i_sorted[j + 1]) { return WITH_ERROR(-1, "Repeated key in musig key expression"); diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index de8337786..6bbc07846 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -16,6 +16,7 @@ *****************************************************************************/ #include +#include #include "lib_standard_app/crypto_helpers.h" @@ -654,17 +655,8 @@ static bool fill_keyexpr_info_if_internal(dispatcher_context_t *dc, if (has_internal_key) { keyexpr_info->psbt_root_key_derivation_length = 0; - // sort the keys in ascending order using bubble sort - for (int i = 0; i < musig_info->n; i++) { - for (int j = 0; j < musig_info->n - 1; j++) { - if (memcmp(keys[j], keys[j + 1], sizeof(plain_pk_t)) > 0) { - uint8_t tmp[sizeof(plain_pk_t)]; - memcpy(tmp, keys[j], sizeof(plain_pk_t)); - memcpy(keys[j], keys[j + 1], sizeof(plain_pk_t)); - memcpy(keys[j + 1], tmp, sizeof(plain_pk_t)); - } - } - } + // sort the keys in ascending order + qsort(keys, musig_info->n, sizeof(plain_pk_t), compare_plain_pk); musig_keyagg_context_t musig_ctx; musig_key_agg(keys, musig_info->n, &musig_ctx); diff --git a/src/handler/sign_psbt/musig_signing.c b/src/handler/sign_psbt/musig_signing.c index 068b320b7..e2404eac1 100644 --- a/src/handler/sign_psbt/musig_signing.c +++ b/src/handler/sign_psbt/musig_signing.c @@ -1,3 +1,5 @@ +#include + #include "musig_signing.h" #include "lib_standard_app/crypto_helpers.h" #include "../boilerplate/sw.h" @@ -51,17 +53,8 @@ bool compute_musig_per_input_info(dispatcher_context_t *dc, memcpy(out->keys[i], ext_pubkey.compressed_pubkey, sizeof(ext_pubkey.compressed_pubkey)); } - // sort the keys in ascending order using bubble sort - for (int i = 0; i < musig_info->n; i++) { - for (int j = 0; j < musig_info->n - 1; j++) { - if (memcmp(out->keys[j], out->keys[j + 1], sizeof(plain_pk_t)) > 0) { - uint8_t tmp[sizeof(plain_pk_t)]; - memcpy(tmp, out->keys[j], sizeof(plain_pk_t)); - memcpy(out->keys[j], out->keys[j + 1], sizeof(plain_pk_t)); - memcpy(out->keys[j + 1], tmp, sizeof(plain_pk_t)); - } - } - } + // sort the keys in ascending order + qsort(out->keys, musig_info->n, sizeof(plain_pk_t), compare_plain_pk); // we already computed the aggregate (pre-tweaks) xpub in the keyexpr_info memcpy(&ext_pubkey, &keyexpr_info->pubkey, sizeof(serialized_extended_pubkey_t)); diff --git a/src/musig/musig.h b/src/musig/musig.h index ed28d3b77..b914f2c7c 100644 --- a/src/musig/musig.h +++ b/src/musig/musig.h @@ -58,6 +58,12 @@ typedef struct musig_session_context_s { size_t msg_len; } musig_session_context_t; +// Comparator for 33-byte compressed public key, in order to sort according to the KeySort +// algorithm of BIP-327. +static inline int compare_plain_pk(const void *a, const void *b) { + return memcmp(a, b, sizeof(plain_pk_t)); +} + /** * Computes the KeyAgg Context per BIP-0327. * From 715b2beba2b522fc82cae8873e39f09010348696 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:23:39 +0000 Subject: [PATCH 47/57] Update protocol documentation for the YIELD client command of sign_psbt --- doc/bitcoin.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/doc/bitcoin.md b/doc/bitcoin.md index dc3dc5d3b..77d5531fa 100644 --- a/doc/bitcoin.md +++ b/doc/bitcoin.md @@ -229,17 +229,33 @@ No output data; the signature are returned using the YIELD client command. Using the information in the PSBT and the wallet description, this command verifies what inputs are internal and what outputs match the pattern for a change address. After validating all the external outputs and the transaction fee with the user, it signs each of the internal inputs; each signature is sent to the client using the YIELD command, in the format described below. If multiple key placeholders of the wallet policy are internal, the process is repeated for each of them. +For a registered wallet, the hmac must be correct. + +For a default wallet, `hmac` must be equal to 32 bytes `0`. + +The data yielded has with a ``, represented as a bitcoin-style varint; the rest of the message depends on the value of ``, as specified in the following subsections. + +##### If `` is at most 65535 + +If `` is at most 65535, then it is an `` and a partial_signature is being yielded. + The results yielded via the YIELD command respect the following format: ` `, where: - `input_index` is a Bitcoin style varint, the index input of the input being signed (starting from 0); - `pubkey_augm_len` is an unsigned byte equal to the length of `pubkey_augm`; -- `pubkey_augm` is the `pubkey` used for signing for legacy, segwit or taproot script path spends (a compressed pubkey if non-taproot, a 32-byte x-only pubkey if taproot); for taproot script path spends, it is the concatenation of the `x-only` pubkey and the 32-byte *tapleaf hash* as defined in [BIP-0341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki); +- `pubkey_augm` is the `pubkey` used for signing for legacy, segwit or taproot keypath spends (a compressed pubkey if non-taproot, a 32-byte x-only pubkey if taproot); for taproot script path spends, it is the concatenation of the `x-only` pubkey and the 32-byte *tapleaf hash* as defined in [BIP-0341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki); - `signature` is the returned signature, possibly concatenated with the sighash byte (as it would be pushed on the stack). -If `P2` is `0` (version `0` of the protocol), `pubkey_augm_len` and `pubkey_augm` are omitted in the YIELD messages. +##### If `` is more than 65535 -For a registered wallet, the hmac must be correct. +In this case `` is a `` that specifies what the rest of the data contains. + +- If `` equals `0xFFFFFFFF`: a pubnonce is being yielded during Round 1 of the MuSig2 protocol. The format is: ` `. +- If `` equals `0xFFFFFFFE`: a partial signature is being yielded, completing Round 2 of the MuSig2 protocol. The format is: ` ` + +In both cases, the `tapleaf_hash` is only present for a Script path spend. + +Other values of the `` are undefined and reserved for future use. -For a default wallet, `hmac` must be equal to 32 bytes `0`. #### Client commands @@ -249,7 +265,7 @@ The client must respond to the `GET_PREIMAGE`, `GET_MERKLE_LEAF_PROOF` and `GET_ The `GET_MORE_ELEMENTS` command must be handled. -The `YIELD` command must be processed in order to receive the signatures. +The `YIELD` command must be processed in order to receive the signatures, or the MuSig2 partial nonces or partial signatures. ### GET_MASTER_FINGERPRINT From bd286b3c583a0ac20ac9304af89aa651a2f8f3f6 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:52:53 +0000 Subject: [PATCH 48/57] Nits and code comment improvements --- src/common/wallet.c | 2 +- src/handler/sign_psbt.c | 14 ++++++++------ src/handler/sign_psbt/musig_signing.c | 17 +++++++---------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/common/wallet.c b/src/common/wallet.c index 17f41d3a4..8954af963 100644 --- a/src/common/wallet.c +++ b/src/common/wallet.c @@ -466,7 +466,7 @@ static int parse_keyexpr(buffer_t *in_buf, } if (!is_taproot) { - return WITH_ERROR(-1, "musig is only allows in taproot"); + return WITH_ERROR(-1, "musig is only allowed in taproot"); } out->type = KEY_EXPRESSION_MUSIG; diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 6bbc07846..ac5facd70 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -2849,7 +2849,7 @@ sign_transaction(dispatcher_context_t *dc, } // We declare this in the global space in order to use less stack space, since BOLOS enforces on -// some device a 8kb stack limit. +// some devices an 8kb stack limit. // Once this is resolved in BOLOS, we should move this to the function scope to avoid unnecessarily // reserving RAM that can only be used for the signing flow (which, at time of writing, is the most // RAM-intensive operation command of the app). @@ -2913,16 +2913,17 @@ void handler_sign_psbt(dispatcher_context_t *dc, uint8_t protocol_version) { } if (!st.has_musig2_pub_nonces) { - // We execute the first round of MuSig for any musig2 key expression.produce the pubnonces; - // this does not involve the private keys, therefore we can do it without user confirmation + // We execute the first round of MuSig for any musig2 key expression, producing the + // pubnonces; this does not involve the private keys, therefore we can do it without user + // confirmation if (!produce_musig2_pubnonces(dc, &st, &signing_state, cache, internal_inputs)) { return; } } - // we execute the signing flow only if we're producing any signature - // (or any MuSig partial signature) + // we execute the signing flow only if we're expected to produce any signature + // (including, possibly, any MuSig2 partial signature from Round 2 of MuSig2) if (!only_signing_for_musig || st.has_musig2_pub_nonces) { if (G_swap_state.called_from_swap) { /** SWAP CHECKS @@ -2965,7 +2966,8 @@ void handler_sign_psbt(dispatcher_context_t *dc, uint8_t protocol_version) { } // MuSig2: if there is an active session at the end of round 1, we move it to persistent - // storage. It is important that this is only done at the very end of the signing process. + // storage. It is important that this is only done at the very end of the signing process, + // end only if everything is successful. musigsession_commit(&signing_state.musig); SEND_SW(dc, SW_OK); diff --git a/src/handler/sign_psbt/musig_signing.c b/src/handler/sign_psbt/musig_signing.c index e2404eac1..61a00cc1c 100644 --- a/src/handler/sign_psbt/musig_signing.c +++ b/src/handler/sign_psbt/musig_signing.c @@ -36,8 +36,6 @@ bool compute_musig_per_input_info(dispatcher_context_t *dc, .address_index = input->in_out.address_index, .sign_psbt_cache = NULL}; - // TODO: code duplication with policy.c::get_derived_pubkey; worth extracting a common method? - serialized_extended_pubkey_t ext_pubkey; const policy_node_keyexpr_t *key_expr = keyexpr_info->key_expression_ptr; @@ -254,7 +252,7 @@ bool produce_and_yield_pubnonce(dispatcher_context_t *dc, } /** - * Round 1 of the MuSig2 protocol + * Round 1 of the MuSig2 protocol: generate and yield pubnonce **/ const musig_psbt_session_t *psbt_session = @@ -266,8 +264,6 @@ bool produce_and_yield_pubnonce(dispatcher_context_t *dc, return false; } - // 5) generate and yield pubnonce - uint8_t rand_i_j[32]; compute_rand_i_j(psbt_session, cur_input_index, keyexpr_info->index, rand_i_j); @@ -317,7 +313,8 @@ bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_context_t return false; } - // 4) check if my pubnonce is in the psbt + // Find my pubnonce is in the psbt. + // // Compute musig_my_psbt_id. It is the psbt key that this signer uses to find pubnonces and // partial signatures (PSBT_IN_MUSIG2_PUB_NONCE and PSBT_IN_MUSIG2_PARTIAL_SIG fields). The // length is either 33+33 (keypath spend), or 33+33+32 bytes (tapscript spend). It's the @@ -342,8 +339,8 @@ bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_context_t 1 + psbt_id_len, my_pubnonce.raw, sizeof(musig_pubnonce_t))) { - PRINTF("Missing pubnonce in PSBT\n"); - SEND_SW(dc, SW_BAD_STATE); + PRINTF("Missing or erroneous pubnonce in PSBT\n"); + SEND_SW(dc, SW_INCORRECT_DATA); return false; } /** @@ -362,7 +359,7 @@ bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_context_t return false; } - // 6) generate and yield partial signature + // collect all pubnonces const policy_node_keyexpr_t *key_expr = keyexpr_info->key_expression_ptr; const musig_aggr_key_info_t *musig_info = r_musig_aggr_key_info(&key_expr->m.musig_info); @@ -413,7 +410,7 @@ bool __attribute__((noinline)) sign_sighash_musig_and_yield(dispatcher_context_t return false; } - // derive secret key + // generate and yield partial signature cx_ecfp_private_key_t private_key = {0}; uint8_t psig[32]; From b551ed48e1b1e0eddd0f9c8ad977f178d5fa4dfe Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Fri, 29 Nov 2024 12:02:18 +0000 Subject: [PATCH 49/57] Add an explicit initializer for the musigsession signing state. This is redundant with the current implementation. However, the musigsession module is written in such a way that the calling code has no knowledge about its internal working. Therefore, it should not assume that zeroing out is the correct way of initializing it. --- src/handler/sign_psbt.c | 3 +++ src/musig/musig_sessions.c | 7 +++++++ src/musig/musig_sessions.h | 16 ++++++++++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index ac5facd70..622cc97c3 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -2907,6 +2907,9 @@ void handler_sign_psbt(dispatcher_context_t *dc, uint8_t protocol_version) { signing_state_t signing_state; memset(&signing_state, 0, sizeof(signing_state)); + // Make sure that the signing state for MuSig2 is initialized correctly + musigsession_initialize_signing_state(&signing_state.musig); + // compute all the tx-wide hashes if (!compute_tx_hashes(dc, &st, &signing_state.tx_hashes)) { return; diff --git a/src/musig/musig_sessions.c b/src/musig/musig_sessions.c index 174e111b3..32aa03507 100644 --- a/src/musig/musig_sessions.c +++ b/src/musig/musig_sessions.c @@ -83,6 +83,10 @@ void compute_rand_i_j(const musig_psbt_session_t *psbt_session, crypto_hash_digest(&hash_context.header, out, 32); } +void musigsession_initialize_signing_state(musig_signing_state_t *musig_signing_state) { + memset(musig_signing_state, 0, sizeof(musig_signing_state_t)); +} + const musig_psbt_session_t *musigsession_round1_initialize( uint8_t psbt_session_id[static 32], musig_signing_state_t *musig_signing_state) { @@ -126,6 +130,9 @@ void musigsession_commit(musig_signing_state_t *musig_signing_state) { for (size_t i = 0; i < sizeof(musig_signing_state->_round1); i++) { acc |= musig_signing_state->_round1._id[i]; } + // If round 1 was not executed, then there is nothing to store. + // This assumes that musigsession_initialize_signing_state, therefore the field is zeroed out + // if it wasn't used. if (acc != 0) { musigsession_store(musig_signing_state->_round1._id, &musig_signing_state->_round1); } diff --git a/src/musig/musig_sessions.h b/src/musig/musig_sessions.h index 0cda21301..eb28bf76e 100644 --- a/src/musig/musig_sessions.h +++ b/src/musig/musig_sessions.h @@ -38,6 +38,20 @@ void compute_rand_i_j(const musig_psbt_session_t *psbt_session, int placeholder_index, uint8_t out[static 32]); +/** + * Make sure that the musig signing state is initialized correctly. + * + * This method must be called before musigsession_round1_initialize or + * musigsession_round2_initialize are called in the code. + * + * This allows the calling code to not make any assumption about how + * the inialization of the musig signing state is done. + * + * @param[in] musig_signing_state + * Pointer to the musig signing state. + */ +void musigsession_initialize_signing_state(musig_signing_state_t *musig_signing_state); + /** * Handles the creation of a new musig psbt session into the volatile memory, or its retrieval (if * the session already exists). @@ -80,8 +94,6 @@ __attribute__((warn_unused_result)) const musig_psbt_session_t *musigsession_rou * been returned to the client. It must _not_ be called if any error occurs, or if the signing * process is aborted for any reason. * - * @param[in] psbt_session_id - * Pointer to the musig psbt session id. * @param[in] musig_signing_state * Pointer to the musig signing state. */ From 4a2a3c52a50948b8fac3974aa10b8aec0dbf6a3d Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Fri, 29 Nov 2024 13:53:46 +0000 Subject: [PATCH 50/57] Update ragger snapshots for NanoS+ and NanoX --- .../snapshots/nanosp/test_dashboard/00000.png | Bin 537 -> 536 bytes .../00000.png | Bin 493 -> 492 bytes .../00001.png | Bin 404 -> 401 bytes .../00003.png | Bin 488 -> 496 bytes .../00004.png | Bin 1009 -> 1010 bytes .../00005.png | Bin 963 -> 970 bytes .../00006.png | Bin 490 -> 496 bytes .../00000.png | Bin 493 -> 492 bytes .../00001.png | Bin 404 -> 401 bytes .../00003.png | Bin 488 -> 496 bytes .../00000.png | Bin 976 -> 981 bytes .../00001.png | Bin 972 -> 992 bytes .../00002.png | Bin 477 -> 513 bytes .../00004.png | Bin 366 -> 367 bytes .../00000.png | Bin 493 -> 492 bytes .../00001.png | Bin 404 -> 401 bytes .../00003.png | Bin 488 -> 496 bytes .../44'/1'/0'_0_0/00000.png | Bin 395 -> 393 bytes .../44'/1'/0'_0_0/00002.png | Bin 960 -> 967 bytes .../44'/1'/0'_0_0/00003.png | Bin 1016 -> 1022 bytes .../44'/1'/0'_0_0/00004.png | Bin 500 -> 531 bytes .../44'/1'/10'_0_0/00000.png | Bin 395 -> 393 bytes .../44'/1'/10'_0_0/00002.png | Bin 975 -> 982 bytes .../44'/1'/10'_0_0/00003.png | Bin 953 -> 959 bytes .../44'/1'/10'_0_0/00004.png | Bin 517 -> 526 bytes .../44'/1'/2'/1/42_0_0/00000.png | Bin 395 -> 393 bytes .../44'/1'/2'/1/42_0_0/00002.png | Bin 949 -> 953 bytes .../44'/1'/2'/1/42_0_0/00003.png | Bin 984 -> 983 bytes .../44'/1'/2'/1/42_0_0/00004.png | Bin 473 -> 497 bytes .../48'/1'/4'/1'/0/7_0_0/00000.png | Bin 395 -> 393 bytes .../48'/1'/4'/1'/0/7_0_0/00002.png | Bin 974 -> 985 bytes .../48'/1'/4'/1'/0/7_0_0/00003.png | Bin 993 -> 999 bytes .../48'/1'/4'/1'/0/7_0_0/00004.png | Bin 520 -> 530 bytes .../49'/1'/1'/1/3_0_0/00000.png | Bin 395 -> 393 bytes .../49'/1'/1'/1/3_0_0/00002.png | Bin 959 -> 961 bytes .../49'/1'/1'/1/3_0_0/00003.png | Bin 989 -> 998 bytes .../49'/1'/1'/1/3_0_0/00004.png | Bin 517 -> 524 bytes .../84'/1'/2'/0/10_0_0/00000.png | Bin 395 -> 393 bytes .../84'/1'/2'/0/10_0_0/00002.png | Bin 959 -> 958 bytes .../84'/1'/2'/0/10_0_0/00003.png | Bin 1012 -> 1012 bytes .../84'/1'/2'/0/10_0_0/00004.png | Bin 462 -> 484 bytes .../86'/1'/4'/1/12_0_0/00000.png | Bin 395 -> 393 bytes .../86'/1'/4'/1/12_0_0/00002.png | Bin 967 -> 967 bytes .../86'/1'/4'/1/12_0_0/00003.png | Bin 991 -> 994 bytes .../86'/1'/4'/1/12_0_0/00004.png | Bin 520 -> 524 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 734 -> 731 bytes .../00000.png | Bin 758 -> 763 bytes .../00000.png | Bin 678 -> 681 bytes .../00001.png | Bin 443 -> 444 bytes .../00002.png | Bin 865 -> 869 bytes .../00003.png | Bin 891 -> 893 bytes .../00004.png | Bin 953 -> 955 bytes .../00005.png | Bin 858 -> 862 bytes .../00006.png | Bin 968 -> 968 bytes .../00007.png | Bin 985 -> 988 bytes .../00008.png | Bin 479 -> 479 bytes .../00000.png | Bin 1018 -> 1019 bytes .../00001.png | Bin 1017 -> 1028 bytes .../00002.png | Bin 732 -> 732 bytes .../00000.png | Bin 1067 -> 1073 bytes .../00001.png | Bin 1034 -> 1038 bytes .../00002.png | Bin 593 -> 596 bytes .../00000.png | Bin 1059 -> 1070 bytes .../00001.png | Bin 1072 -> 1080 bytes .../00002.png | Bin 620 -> 622 bytes .../00001.png | Bin 478 -> 478 bytes .../00002.png | Bin 491 -> 495 bytes .../00000.png | Bin 1013 -> 1022 bytes .../00001.png | Bin 1012 -> 1019 bytes .../00002.png | Bin 725 -> 725 bytes .../00001.png | Bin 572 -> 572 bytes .../00002.png | Bin 511 -> 522 bytes .../00000.png | Bin 1013 -> 1022 bytes .../00001.png | Bin 1012 -> 1019 bytes .../00002.png | Bin 725 -> 725 bytes .../00001.png | Bin 567 -> 567 bytes .../00002.png | Bin 540 -> 549 bytes .../00000.png | Bin 1013 -> 1022 bytes .../00001.png | Bin 1012 -> 1019 bytes .../00002.png | Bin 725 -> 725 bytes .../00001.png | Bin 463 -> 461 bytes .../00002.png | Bin 474 -> 488 bytes .../00000.png | Bin 1013 -> 1022 bytes .../00001.png | Bin 1012 -> 1019 bytes .../00002.png | Bin 725 -> 725 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 686 -> 691 bytes .../00000.png | Bin 1009 -> 1022 bytes .../00001.png | Bin 990 -> 997 bytes .../00002.png | Bin 749 -> 757 bytes .../00000.png | Bin 1013 -> 1025 bytes .../00001.png | Bin 1027 -> 1040 bytes .../00002.png | Bin 755 -> 768 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 622 -> 630 bytes .../00000.png | Bin 1009 -> 1022 bytes .../00001.png | Bin 990 -> 997 bytes .../00002.png | Bin 782 -> 788 bytes .../00000.png | Bin 1013 -> 1025 bytes .../00001.png | Bin 1027 -> 1040 bytes .../00002.png | Bin 773 -> 793 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 683 -> 692 bytes .../00000.png | Bin 1023 -> 1033 bytes .../00001.png | Bin 1047 -> 1051 bytes .../00002.png | Bin 750 -> 754 bytes .../00000.png | Bin 1005 -> 1015 bytes .../00001.png | Bin 1058 -> 1069 bytes .../00002.png | Bin 773 -> 791 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 644 -> 651 bytes .../00000.png | Bin 1023 -> 1033 bytes .../00001.png | Bin 1047 -> 1051 bytes .../00002.png | Bin 779 -> 783 bytes .../00000.png | Bin 1005 -> 1015 bytes .../00001.png | Bin 1058 -> 1069 bytes .../00002.png | Bin 793 -> 817 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 683 -> 693 bytes .../00000.png | Bin 1041 -> 1051 bytes .../00001.png | Bin 1035 -> 1042 bytes .../00002.png | Bin 784 -> 786 bytes .../00000.png | Bin 1019 -> 1026 bytes .../00001.png | Bin 1026 -> 1031 bytes .../00002.png | Bin 734 -> 746 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 633 -> 641 bytes .../00000.png | Bin 1041 -> 1051 bytes .../00001.png | Bin 1035 -> 1042 bytes .../00002.png | Bin 812 -> 814 bytes .../00000.png | Bin 1019 -> 1026 bytes .../00001.png | Bin 1026 -> 1031 bytes .../00002.png | Bin 760 -> 775 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 683 -> 693 bytes .../00004.png | Bin 366 -> 367 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 633 -> 641 bytes .../00004.png | Bin 366 -> 367 bytes .../00001.png | Bin 725 -> 726 bytes .../00002.png | Bin 544 -> 554 bytes .../00000.png | Bin 1041 -> 1051 bytes .../00001.png | Bin 1035 -> 1042 bytes .../00002.png | Bin 784 -> 786 bytes .../00000.png | Bin 1019 -> 1026 bytes .../00001.png | Bin 1026 -> 1031 bytes .../00002.png | Bin 734 -> 746 bytes .../00001.png | Bin 656 -> 656 bytes .../00002.png | Bin 728 -> 737 bytes .../00000.png | Bin 1002 -> 1009 bytes .../00001.png | Bin 1055 -> 1055 bytes .../00002.png | Bin 769 -> 791 bytes .../00000.png | Bin 1047 -> 1052 bytes .../00001.png | Bin 1041 -> 1047 bytes .../00002.png | Bin 796 -> 801 bytes .../00000.png | Bin 1028 -> 1029 bytes .../00001.png | Bin 1030 -> 1028 bytes .../00002.png | Bin 737 -> 741 bytes .../00001.png | Bin 584 -> 585 bytes .../00002.png | Bin 544 -> 554 bytes .../00000.png | Bin 1004 -> 1015 bytes .../00001.png | Bin 1034 -> 1033 bytes .../00002.png | Bin 543 -> 550 bytes .../00000.png | Bin 1019 -> 1026 bytes .../00001.png | Bin 1026 -> 1031 bytes .../00002.png | Bin 734 -> 746 bytes .../00001.png | Bin 861 -> 861 bytes .../00002.png | Bin 493 -> 494 bytes .../00003.png | Bin 683 -> 693 bytes .../00000.png | Bin 1041 -> 1051 bytes .../00001.png | Bin 1035 -> 1042 bytes .../00002.png | Bin 784 -> 786 bytes .../00000.png | Bin 1019 -> 1026 bytes .../00001.png | Bin 1026 -> 1031 bytes .../00002.png | Bin 734 -> 746 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../test_sighash_all_sign_psbt_0_0/00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../test_sighash_none_sign_psbt_0_0/00000.png | Bin 467 -> 467 bytes .../test_sighash_none_sign_psbt_0_0/00001.png | Bin 488 -> 496 bytes .../test_sighash_none_sign_psbt_0_1/00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../test_sighash_unsupported_0_0/00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../nanosp/test_sign_message_0_1/00000.png | Bin 698 -> 701 bytes .../nanosp/test_sign_message_0_1/00001.png | Bin 576 -> 576 bytes .../00000.png | Bin 753 -> 760 bytes .../00001.png | Bin 810 -> 807 bytes .../00000.png | Bin 720 -> 721 bytes .../00001.png | Bin 790 -> 786 bytes .../00001.png | Bin 766 -> 762 bytes .../00000.png | Bin 750 -> 750 bytes .../00001.png | Bin 778 -> 779 bytes .../00002.png | Bin 479 -> 479 bytes .../00005.png | Bin 366 -> 367 bytes .../test_sign_message_reject_0_0/00004.png | Bin 366 -> 367 bytes .../00001.png | Bin 635 -> 636 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 707 -> 735 bytes .../test_sign_psbt_highfee_0_0/00000.png | Bin 418 -> 417 bytes .../test_sign_psbt_highfee_0_0/00002.png | Bin 767 -> 775 bytes .../test_sign_psbt_highfee_0_1/00000.png | Bin 526 -> 527 bytes .../00001.png | Bin 534 -> 534 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 781 -> 778 bytes .../00001.png | Bin 465 -> 465 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 689 -> 682 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 438 -> 438 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 689 -> 682 bytes .../test_sign_psbt_multisig_wsh_0_0/00001.png | Bin 465 -> 465 bytes .../test_sign_psbt_multisig_wsh_0_1/00000.png | Bin 418 -> 417 bytes .../test_sign_psbt_multisig_wsh_0_1/00002.png | Bin 767 -> 775 bytes .../00001.png | Bin 465 -> 465 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 767 -> 775 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 937 -> 937 bytes .../00003.png | Bin 464 -> 463 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 767 -> 775 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 767 -> 775 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 917 -> 915 bytes .../00003.png | Bin 504 -> 503 bytes .../00002.png | Bin 438 -> 438 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 917 -> 915 bytes .../00003.png | Bin 504 -> 503 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 917 -> 915 bytes .../00003.png | Bin 504 -> 503 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 955 -> 945 bytes .../00003.png | Bin 425 -> 422 bytes .../00000.png | Bin 426 -> 427 bytes .../00002.png | Bin 928 -> 925 bytes .../00003.png | Bin 471 -> 469 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00001.png | Bin 725 -> 726 bytes .../00000.png | Bin 418 -> 417 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 426 -> 427 bytes .../00002.png | Bin 898 -> 901 bytes .../00003.png | Bin 521 -> 522 bytes .../00000.png | Bin 427 -> 427 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 425 -> 424 bytes .../00002.png | Bin 751 -> 752 bytes .../00000.png | Bin 430 -> 428 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 426 -> 427 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 427 -> 427 bytes .../00002.png | Bin 751 -> 752 bytes .../00000.png | Bin 425 -> 424 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 426 -> 427 bytes .../00002.png | Bin 898 -> 901 bytes .../00003.png | Bin 521 -> 522 bytes .../00000.png | Bin 427 -> 427 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 425 -> 424 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 414 -> 416 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 841 -> 828 bytes .../00003.png | Bin 833 -> 831 bytes .../00004.png | Bin 845 -> 846 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 841 -> 828 bytes .../00003.png | Bin 833 -> 831 bytes .../00004.png | Bin 845 -> 846 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 519 -> 519 bytes .../00003.png | Bin 471 -> 469 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 519 -> 519 bytes .../00003.png | Bin 471 -> 469 bytes .../snapshots/nanox/test_dashboard/00000.png | Bin 537 -> 536 bytes .../00000.png | Bin 493 -> 492 bytes .../00001.png | Bin 404 -> 401 bytes .../00003.png | Bin 488 -> 496 bytes .../00004.png | Bin 1009 -> 1010 bytes .../00005.png | Bin 963 -> 970 bytes .../00006.png | Bin 490 -> 496 bytes .../00000.png | Bin 493 -> 492 bytes .../00001.png | Bin 404 -> 401 bytes .../00003.png | Bin 488 -> 496 bytes .../00000.png | Bin 976 -> 981 bytes .../00001.png | Bin 972 -> 992 bytes .../00002.png | Bin 477 -> 513 bytes .../00004.png | Bin 366 -> 367 bytes .../00000.png | Bin 493 -> 492 bytes .../00001.png | Bin 404 -> 401 bytes .../00003.png | Bin 488 -> 496 bytes .../44'/1'/0'_0_0/00000.png | Bin 395 -> 393 bytes .../44'/1'/0'_0_0/00002.png | Bin 960 -> 967 bytes .../44'/1'/0'_0_0/00003.png | Bin 1016 -> 1022 bytes .../44'/1'/0'_0_0/00004.png | Bin 500 -> 531 bytes .../44'/1'/10'_0_0/00000.png | Bin 395 -> 393 bytes .../44'/1'/10'_0_0/00002.png | Bin 975 -> 982 bytes .../44'/1'/10'_0_0/00003.png | Bin 953 -> 959 bytes .../44'/1'/10'_0_0/00004.png | Bin 517 -> 526 bytes .../44'/1'/2'/1/42_0_0/00000.png | Bin 395 -> 393 bytes .../44'/1'/2'/1/42_0_0/00002.png | Bin 949 -> 953 bytes .../44'/1'/2'/1/42_0_0/00003.png | Bin 984 -> 983 bytes .../44'/1'/2'/1/42_0_0/00004.png | Bin 473 -> 497 bytes .../48'/1'/4'/1'/0/7_0_0/00000.png | Bin 395 -> 393 bytes .../48'/1'/4'/1'/0/7_0_0/00002.png | Bin 974 -> 985 bytes .../48'/1'/4'/1'/0/7_0_0/00003.png | Bin 993 -> 999 bytes .../48'/1'/4'/1'/0/7_0_0/00004.png | Bin 520 -> 530 bytes .../49'/1'/1'/1/3_0_0/00000.png | Bin 395 -> 393 bytes .../49'/1'/1'/1/3_0_0/00002.png | Bin 959 -> 961 bytes .../49'/1'/1'/1/3_0_0/00003.png | Bin 989 -> 998 bytes .../49'/1'/1'/1/3_0_0/00004.png | Bin 517 -> 524 bytes .../84'/1'/2'/0/10_0_0/00000.png | Bin 395 -> 393 bytes .../84'/1'/2'/0/10_0_0/00002.png | Bin 959 -> 958 bytes .../84'/1'/2'/0/10_0_0/00003.png | Bin 1012 -> 1012 bytes .../84'/1'/2'/0/10_0_0/00004.png | Bin 462 -> 484 bytes .../86'/1'/4'/1/12_0_0/00000.png | Bin 395 -> 393 bytes .../86'/1'/4'/1/12_0_0/00002.png | Bin 967 -> 967 bytes .../86'/1'/4'/1/12_0_0/00003.png | Bin 991 -> 994 bytes .../86'/1'/4'/1/12_0_0/00004.png | Bin 520 -> 524 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 734 -> 731 bytes .../00000.png | Bin 758 -> 763 bytes .../00000.png | Bin 678 -> 681 bytes .../00001.png | Bin 443 -> 444 bytes .../00002.png | Bin 865 -> 869 bytes .../00003.png | Bin 891 -> 893 bytes .../00004.png | Bin 953 -> 955 bytes .../00005.png | Bin 858 -> 862 bytes .../00006.png | Bin 968 -> 968 bytes .../00007.png | Bin 985 -> 988 bytes .../00008.png | Bin 479 -> 479 bytes .../00000.png | Bin 1018 -> 1019 bytes .../00001.png | Bin 1017 -> 1028 bytes .../00002.png | Bin 732 -> 732 bytes .../00000.png | Bin 1067 -> 1073 bytes .../00001.png | Bin 1034 -> 1038 bytes .../00002.png | Bin 593 -> 596 bytes .../00000.png | Bin 1059 -> 1070 bytes .../00001.png | Bin 1072 -> 1080 bytes .../00002.png | Bin 620 -> 622 bytes .../00001.png | Bin 478 -> 478 bytes .../00002.png | Bin 491 -> 495 bytes .../00000.png | Bin 1013 -> 1022 bytes .../00001.png | Bin 1012 -> 1019 bytes .../00002.png | Bin 725 -> 725 bytes .../00001.png | Bin 572 -> 572 bytes .../00002.png | Bin 511 -> 522 bytes .../00000.png | Bin 1013 -> 1022 bytes .../00001.png | Bin 1012 -> 1019 bytes .../00002.png | Bin 725 -> 725 bytes .../00001.png | Bin 567 -> 567 bytes .../00002.png | Bin 540 -> 549 bytes .../00000.png | Bin 1013 -> 1022 bytes .../00001.png | Bin 1012 -> 1019 bytes .../00002.png | Bin 725 -> 725 bytes .../00001.png | Bin 463 -> 461 bytes .../00002.png | Bin 474 -> 488 bytes .../00000.png | Bin 1013 -> 1022 bytes .../00001.png | Bin 1012 -> 1019 bytes .../00002.png | Bin 725 -> 725 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 686 -> 691 bytes .../00000.png | Bin 1009 -> 1022 bytes .../00001.png | Bin 990 -> 997 bytes .../00002.png | Bin 749 -> 757 bytes .../00000.png | Bin 1013 -> 1025 bytes .../00001.png | Bin 1027 -> 1040 bytes .../00002.png | Bin 755 -> 768 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 622 -> 630 bytes .../00000.png | Bin 1009 -> 1022 bytes .../00001.png | Bin 990 -> 997 bytes .../00002.png | Bin 782 -> 788 bytes .../00000.png | Bin 1013 -> 1025 bytes .../00001.png | Bin 1027 -> 1040 bytes .../00002.png | Bin 773 -> 793 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 683 -> 692 bytes .../00000.png | Bin 1023 -> 1033 bytes .../00001.png | Bin 1047 -> 1051 bytes .../00002.png | Bin 750 -> 754 bytes .../00000.png | Bin 1005 -> 1015 bytes .../00001.png | Bin 1058 -> 1069 bytes .../00002.png | Bin 773 -> 791 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 644 -> 651 bytes .../00000.png | Bin 1023 -> 1033 bytes .../00001.png | Bin 1047 -> 1051 bytes .../00002.png | Bin 779 -> 783 bytes .../00000.png | Bin 1005 -> 1015 bytes .../00001.png | Bin 1058 -> 1069 bytes .../00002.png | Bin 793 -> 817 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 683 -> 693 bytes .../00000.png | Bin 1041 -> 1051 bytes .../00001.png | Bin 1035 -> 1042 bytes .../00002.png | Bin 784 -> 786 bytes .../00000.png | Bin 1019 -> 1026 bytes .../00001.png | Bin 1026 -> 1031 bytes .../00002.png | Bin 734 -> 746 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 633 -> 641 bytes .../00000.png | Bin 1041 -> 1051 bytes .../00001.png | Bin 1035 -> 1042 bytes .../00002.png | Bin 812 -> 814 bytes .../00000.png | Bin 1019 -> 1026 bytes .../00001.png | Bin 1026 -> 1031 bytes .../00002.png | Bin 760 -> 775 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 683 -> 693 bytes .../00004.png | Bin 366 -> 367 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 633 -> 641 bytes .../00004.png | Bin 366 -> 367 bytes .../00001.png | Bin 725 -> 726 bytes .../00002.png | Bin 544 -> 554 bytes .../00000.png | Bin 1041 -> 1051 bytes .../00001.png | Bin 1035 -> 1042 bytes .../00002.png | Bin 784 -> 786 bytes .../00000.png | Bin 1019 -> 1026 bytes .../00001.png | Bin 1026 -> 1031 bytes .../00002.png | Bin 734 -> 746 bytes .../00001.png | Bin 656 -> 656 bytes .../00002.png | Bin 728 -> 737 bytes .../00000.png | Bin 1002 -> 1009 bytes .../00001.png | Bin 1055 -> 1055 bytes .../00002.png | Bin 769 -> 791 bytes .../00000.png | Bin 1047 -> 1052 bytes .../00001.png | Bin 1041 -> 1047 bytes .../00002.png | Bin 796 -> 801 bytes .../00000.png | Bin 1028 -> 1029 bytes .../00001.png | Bin 1030 -> 1028 bytes .../00002.png | Bin 737 -> 741 bytes .../00001.png | Bin 584 -> 585 bytes .../00002.png | Bin 544 -> 554 bytes .../00000.png | Bin 1004 -> 1015 bytes .../00001.png | Bin 1034 -> 1033 bytes .../00002.png | Bin 543 -> 550 bytes .../00000.png | Bin 1019 -> 1026 bytes .../00001.png | Bin 1026 -> 1031 bytes .../00002.png | Bin 734 -> 746 bytes .../00001.png | Bin 861 -> 861 bytes .../00002.png | Bin 493 -> 494 bytes .../00003.png | Bin 683 -> 693 bytes .../00000.png | Bin 1041 -> 1051 bytes .../00001.png | Bin 1035 -> 1042 bytes .../00002.png | Bin 784 -> 786 bytes .../00000.png | Bin 1019 -> 1026 bytes .../00001.png | Bin 1026 -> 1031 bytes .../00002.png | Bin 734 -> 746 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../test_sighash_all_sign_psbt_0_0/00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../test_sighash_none_sign_psbt_0_0/00000.png | Bin 467 -> 467 bytes .../test_sighash_none_sign_psbt_0_0/00001.png | Bin 488 -> 496 bytes .../test_sighash_none_sign_psbt_0_1/00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 467 -> 467 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../test_sighash_unsupported_0_0/00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../nanox/test_sign_message_0_1/00000.png | Bin 698 -> 701 bytes .../nanox/test_sign_message_0_1/00001.png | Bin 576 -> 576 bytes .../00000.png | Bin 753 -> 760 bytes .../00001.png | Bin 810 -> 807 bytes .../00000.png | Bin 720 -> 721 bytes .../00001.png | Bin 790 -> 786 bytes .../00001.png | Bin 766 -> 762 bytes .../00000.png | Bin 750 -> 750 bytes .../00001.png | Bin 778 -> 779 bytes .../00002.png | Bin 479 -> 479 bytes .../00005.png | Bin 366 -> 367 bytes .../test_sign_message_reject_0_0/00004.png | Bin 366 -> 367 bytes .../00001.png | Bin 635 -> 636 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 707 -> 735 bytes .../test_sign_psbt_highfee_0_0/00000.png | Bin 418 -> 417 bytes .../test_sign_psbt_highfee_0_0/00002.png | Bin 767 -> 775 bytes .../test_sign_psbt_highfee_0_1/00000.png | Bin 526 -> 527 bytes .../00001.png | Bin 534 -> 534 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 781 -> 778 bytes .../00001.png | Bin 465 -> 465 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 689 -> 682 bytes .../00001.png | Bin 465 -> 465 bytes .../00002.png | Bin 438 -> 438 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 689 -> 682 bytes .../test_sign_psbt_multisig_wsh_0_0/00001.png | Bin 465 -> 465 bytes .../test_sign_psbt_multisig_wsh_0_1/00000.png | Bin 418 -> 417 bytes .../test_sign_psbt_multisig_wsh_0_1/00002.png | Bin 767 -> 775 bytes .../00001.png | Bin 465 -> 465 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 767 -> 775 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 937 -> 937 bytes .../00003.png | Bin 464 -> 463 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 767 -> 775 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 767 -> 775 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 917 -> 915 bytes .../00003.png | Bin 504 -> 503 bytes .../00002.png | Bin 438 -> 438 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 917 -> 915 bytes .../00003.png | Bin 504 -> 503 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 917 -> 915 bytes .../00003.png | Bin 504 -> 503 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 955 -> 945 bytes .../00003.png | Bin 425 -> 422 bytes .../00000.png | Bin 426 -> 427 bytes .../00002.png | Bin 928 -> 925 bytes .../00003.png | Bin 471 -> 469 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 418 -> 417 bytes .../00001.png | Bin 725 -> 726 bytes .../00000.png | Bin 418 -> 417 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 426 -> 427 bytes .../00002.png | Bin 898 -> 901 bytes .../00003.png | Bin 521 -> 522 bytes .../00000.png | Bin 427 -> 427 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 425 -> 424 bytes .../00002.png | Bin 751 -> 752 bytes .../00000.png | Bin 430 -> 428 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 426 -> 427 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 427 -> 427 bytes .../00002.png | Bin 751 -> 752 bytes .../00000.png | Bin 425 -> 424 bytes .../00001.png | Bin 488 -> 496 bytes .../00000.png | Bin 418 -> 417 bytes .../00000.png | Bin 426 -> 427 bytes .../00002.png | Bin 898 -> 901 bytes .../00003.png | Bin 521 -> 522 bytes .../00000.png | Bin 427 -> 427 bytes .../00002.png | Bin 724 -> 728 bytes .../00000.png | Bin 425 -> 424 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 414 -> 416 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 841 -> 828 bytes .../00003.png | Bin 833 -> 831 bytes .../00004.png | Bin 845 -> 846 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 841 -> 828 bytes .../00003.png | Bin 833 -> 831 bytes .../00004.png | Bin 845 -> 846 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 519 -> 519 bytes .../00003.png | Bin 471 -> 469 bytes .../00000.png | Bin 418 -> 417 bytes .../00002.png | Bin 519 -> 519 bytes .../00003.png | Bin 471 -> 469 bytes 718 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/snapshots/nanosp/test_dashboard/00000.png b/tests/snapshots/nanosp/test_dashboard/00000.png index d73deb1de6696efb1f398bb50d9617696cc2590f..9967ac0e0c102e7dc1c2e304b84c554d547561b9 100644 GIT binary patch delta 510 zcmV;ZNogD_N5xsXiFa++z&wn6QfF`$~0GkZ#1SGI} zjsPhEtvN2XW0eBrH6Vu=eGw4g)&b$X5Q{OU&%76F`Uk`Wgl9<+kO@dYPkcfMAw&Us zH;sZ0?@R0+yqypOBx|?Lb{<$A)Gf`EnlkrGBii87^15pLhBLGLFYUbZrgamiT(6eT zPlS-EbQQp1%y^w zuA}GgE~-87l1nRkrtsmUhR(`?6RI-xr4yVU3O%}f9`Kmxw-6ow??)F~=06XxPcL7@ z%0TF!<8Ek!)r-6_T-7D?moNw+gb+f=30FEDnT+QIcz1a*OADW3v16~Qs&b}Q--Oc1 z_0)&2isM&#)!4O8*Br-71(fv6O+#D8!d(J7HA}r$_aX?Kz8$?tvrJ}Pb$@pi(4&bO zI%V}g#1Y=I;k2O?e-AcPP?2qA{x0x|&!=!s7VA%rME z@1{}E;eCkRgSQi6fMo5q+0Fy2gSw@8Qd8!BX+#@bT3%O;-*9G@|D~O0-n4Gwl< z`H2uRwXT`Hx_@`eZ`c>kwCo#)box*wui@+Njt~p9Wurdq@7slC8>|{JY#IkHtbou; z%XRep-9@zrUUF$g&lEnK)X-Tua6(n4zI1}qL!n2P&jY?D`YlAq|NQ7;%lzj7_UYw| zSQ!ZY@3A8PM<(Mr0eD_s%+kWASnSxVs;Zo+)iXArUNv^D(>2HOQUN7BbJNh4v2d4wPR&y9)x8J;cL_)=>dskT^V9v^C7?$W zHFV1AcZegrWd-R68U!2hssJH`5JCtcgb+eD@DG_;bg&84X#xNM002ovPDHLkV1n(h B^iu!; diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_0_0/00000.png b/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_0_0/00000.png index 8583e39efd65ff8275a2f940b088b17a1e4c9b3e..e903d67eedf83e52187d7ec93055cea0f3f9a586 100644 GIT binary patch delta 443 zcmV;s0Yv`o1MCBkB!9C>L_t(|ob8)YZiXNXfd4JK3HLt|ciDppVTDzM0#?88!9;{o zC-q2ZRvZ^|-*90Zu1+cYiCv&u#^VaM#@c0002* zWW{S+{L6U7jb*#5So|)#s5--N@eGakZXoj7*KNd7t$FaEnkXJALh{=fW4h+~kHnOc zZjY-dQtBhhwzpTI)YBft1Il@+?CZw--D35Er-_5?@qj8SKYAN zZN-$ei*n}i9TkkLl4kiEMygAdb{ZgG9))INjqh_S!f0awGY zJ8Z?2wTp7*@qe9+tCD8<8)m9Ym3BHHUmk^KV&y!of69OBK`v)RJ^%m!0C+;*8ExM; zRk77-!?Be14!q%I+;SsUO&sc($h<-|A*$CAiOe$JP~KIB6ZXHP?!^ygI+?zxp^yge`EayS z3F!-L2mk;8000000001RnU{3{dNIcIe%m&~NX~HC05bKG$7b-?04e)2-PJ-D-qryq zWr=o|cdufMa{lRmbiwNgfSFb|_t^b|-w}}I+GFZ>{_cXpvwvu%{E-T*CBU*o5492ilw>|mbV{$S52GCWX z<)f%mec~^-M9MA0y<~q)CGxAiJgeB+Y^iQZrXMWdw}Kx$taGF+&kmdKus2nQc5A%% z5AIY{pR_DIoNtR{zfu24i)IA;p|VrYnwMyRA>}+XYm(9I2ds5haF=Xxs(!1O{eK<- z=}hTk=q{C)s-CpJN_D~;zY44CUCU|%Q5TQbEy>4V5uQLk*#H0l00000003YyU)xnV U6SX>Qxc~qF07*qoM6N<$g0C2{O#lD@ delta 377 zcmV-<0fzpO1C#@hB!62;L_t(|obB0Lj>0euK+%BMN%y~`?1hg?k(D=YTG!>Cj}e51 zI?k(1LI3~&000000001h)4Z$$(2Fsq*W0!kMskG94v?vrJa&V>4oKOT>8=*K@U{*> zDND4wyn7X6l9^Y;`Ko`3ZinsYRiqF^1%tU;)b zTH;qT$z=aBl~j}ci_r&`ScNRH4_hL=k8tn-TvohhM6~{OF&V?XhV8*0J|>OncYvM#ECNTfV6+)MVqsYHIXmuD4Qhb`43$@GQg>sIiSmvyd`<=JKH4M$UTYPaTl z|Kd(X^-asd;c{9e$Bp_+S~N4@50!&@)w)CnOexoyRf~+~Jm6kW1y{*7r|PGQ)&J)i zknWV;hVE8*s_ISqyHqE<)QVvftlE1ocbka1c)T7-J_eic0+S0D000000000004#g~ X+>kjF+=kPs00000NkvXXu0mjf_y4vI diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_0_0/00003.png b/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_0_0/00003.png index 2b51f30cfe212df5691953efe741325df2f02f56..61f34db33cfd1a4ec7ac68277a6a3bb82f0406cd 100644 GIT binary patch delta 470 zcmV;{0V)3I1MmZoB!9O_L_t(|obB6Pj)Wi(Mp1g=PTc>J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_0_0/00004.png b/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_0_0/00004.png index e16fbcdd90518fa678f3ee818c9a8ac09c9d1677..5a97706b86befbe64484a24ea121c79487251857 100644 GIT binary patch delta 988 zcmV<210($L2l5AyB!9U{L_t(|ob8)icHJNhMM+m@;`tAWx%9&+i|Bbk!f_kzuf_%; zOEQmh-PVetD2k#eisErTg8h5%^Pkss*)2(f`J&hWw6jg`eKy67k1O+&js~Rr2EQVm z2PxsWt}837Af$T8pM%@0>o26G)(hl!q_YO88eULM${A@aR(~AcUcBqRpvc8sa^3(O zu*OHcwAVr`-nl~OQgvs)hP{8icixLTvqVk;Hasx8;MU0Vj{v2>(D-K>RVra{V{# zfEpjlUVkJCn#YZa3dnBVux41$`hx9Uhu!EoQUnpRW^ zr!(wm4fp}`zOq-TP6Buo@ZTbqezicd6(3rA7Ew6|hkq0AiUvjAau5^MV6m*`2ObT; z90vs`aG)iFZ%M!d#Klo@@@dlouwnnmFJg(1sNn@@SW7$@8}l0oO@L@+p3cO{+TM6* zE$u0IZZ_8!F)POOoCp!L>?Fy3gQ8p7!iXUf+)6+SLKwlwRsyov&p{CY zj*=5zTz~E3+94Md#j~z!pIgQ)7&0HXNnGXrbIW*qHrW`!h_ZM~jFElX*cgt-%T9nX zqBe>f9RDOtOdzt9dnR-nXi}(gUORXAa*5P9Bt?K>Jqn^C*jk&BJZ+#3=*(SF;KAWC z#khM^Q5e|JOc3pCsU|e94t>E0ItIM~U^2D7aeu`MvAkzNypGpzoP{aKg|7j@7#X#h zl1M&vJkP=#(7p(HAd%&v4>drHgq0o!*9`JTe(Yl$HjSx z&yz+SaD&<@dPDfy{4x$PEmm2g1_1h|C4TNQ=R+(qvZR5Jk384TN%*=hL;$&)A=VNV z4qWTz?ky?XSw8y-&{Y1}3Bw!GOnk_!=T&)fTSC@C5+dA_ohe8ZN8M$uOJ8;l#(OO; z@{LUbP06~u6KyPZhF3P)Tx37#4kdz~qtwuMBObDfq9}@@NZ=2Wm0|GR{G;mt0000< KMNUMnLSTX?DBolN delta 987 zcmV<110?+N2k{4xB!9R`L_t(|ob8)icHS@ugq5D|#QR^8_tFP9ItmOh60+kqd{3<{ zAq-fT`JL8^q9}@@D2n27K9c><^Bn(s9EaahG#D?!2Be)e&hs4YXv_V|_?W$c=)T6U zWdDmT;W&R6{uvjelX$@$KPVE5R_1`QS3_ zc>{RJ8t?J4UJF>iW08*4>dY`B0a6HXW2ng~IUQ68N$I0fa|GX*_4 zcRL6-#Nzo*o}Pj_PR^Kg@*Ah+UDGpFbz=hHE{!b79^bIN*vOKzkUyE|>!W3IVJ}*9 zQ z>(4~N^0=w>li9F4)*K5~U$TAZa2UNniV$MfXb#Ha;@_g>6xVQ2Ne#_9L!V!DI>(OH zKp!x#D{GY+BtS=j|2bmnhYKcK`Jt_6fyy~K9J~t+LVwdjm4ZNdbx+ zXv*MQ67T?daTHEIZCC&n?BDW>*hWOu_yTmSZPX8(`He&-09qNRGdNlM8xO0cKLwA? z#`+RwVN8?jzeCb;kfiVpDrqH;8AB$xm4GdPFp`n21ngox2SuLLEL0>3f?PScl|A9* z)jq8qYJWiyo^?a}+A?p!k@>Vu;i~puTjt}l$ie_ll;JHHBmcCqFr1E;p8#h>Ym_iJ z@kv;iU}UNAOc*w>q)_L)cHiMEBva#*6hVgdRu~n**V>%qSp%Jf&U_jQJUQG>G42`_ z3Ihw838S4&)r95MOfZD7h`ReP8{pGo3xLv34Q$B`ENh93LM-IjM8&P#fp zbm~AGv`*0r!q?)Lag1qLWg9gB(l;ydW0x@>u*k%cMm|3CTq`Hx<2V=rCsem3Vl5OQ;yqcJf}l7WE^88$>)}qcsn|JQ`B-z2|D-FF2zno-hQ1qk$SR7WD2ieOe*op=XQsNnv-JP~002ov JPDHLkV1mHqE(EJB9N8dhzT4K}pJ;eUpg7ymUnSoCW+`#n>Ieg$v*i{@UA~4xdJSIVjOQ? z?4H8cM!OgbhT&VFSLS8-NF3<^v6*t6*2U;o?G2*MM~-auZ^Qy*M$i+eTmx1UTavmc zAKJxg!>xI{-UpX77dKgHQ_$(5k{4BtjT*`P=C=V6g6YP$JD`?GA2d}2vrtol6XfoL zOX12dix}HYyU{YO0v8U!se_A-wvmh-+kfPV zhy!3-BK0rjV*>BQwlmD3w^lI>CJ`Or&4Cn45uiNz`a!<>LoC?Q4;b8aRf~RD3UfMO zYQ>~sF^J%!f}z7ZRo@4 z4rrRDX>_>65feSCoDnZe{Lzf_wh9CCWsC5-;|`oow!)Nb3nY6ICg)X6GSc907f2PN z#(x~g0iKVD*?DKyHVuETa)Za_4HgzOB!$D<~s zgmuIu5BVGq?SM<&-4fH0)KP`eR#iZX*8tHoWBA)PFXhgTG`RfZT#_Q!n?oA=r2M+- zu2lw;X|+{%ybn@)*os>K-j;!=jNZ)?)Gf^?_<-3v1hG)>cd2Y&%; WVHeI0iKy%V00007 z2mq%~w^kHIQ4~c{6qoaFvwrV=emsuDE=dZ^FU102J286iqn+^~nuYV1&b2lz`Pr#F zNO8w;94YO9%ns#wKnxq^@iM&p690E9Ymls&-Kr&8W2r4>9DiP3{I3>Z?fs^65pqTV z4w&P^U)r!Bu9?fXX=Zr6*YaR>!1dlqMQzaF=5tu5ETxNJsdWI#NU+-vbJlD3{JDznMOU z1PfNQ>(1KWY8O@jx^!P5A{GNb`=!`$6%+Xqq!>{~mw#+)@1N%0-UNt0D{Tlm5yJO{MHtnS`TP*)l zJ|^%E>~@-&dUF+{!A(R1cy}PlQUoYZzWyM;`a@c6>+PkySP>bM}Q`X?xdSbe}BIhAw4EJ(*MJ$^5TJfafF9 z?0hhDeVcx#b6o(5S{L%gcc{B=$C6`(gn{o}d`*IzkHAvVU0eC)YLP}Ui+~grY z$3p{fs<}&IIx=-+Vf2;dkmNN$w9H6k)dh|1{IJVD)jf(-~Cb|wz^KJqW++ui$$q9}@@_zZplZwMWPP%|)t P00000NkvXXu0mjfn9R4J diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_0_0/00006.png b/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_0_0/00006.png index 80dbc0c24bff313d7adbf76fd6eaa262eb471db8..41f9333b1e827ea9d27f2f847214d4568db224fd 100644 GIT binary patch delta 470 zcmV;{0V)3K1MmZoB!9O_L_t(|obA~`a>F1DKvB}^O?>|&ahEPKWf%#B0vJg0->P+F zj0Khn2>}2A09fuZa&n9@|M$8sJ5mJX2a5sDcDltF^Q%AAI$4ZKEp+=CIa%~(u#s75 zbrK0p9T2lB{NG?LM#sP8cjV+EF=g_!roQT2i(q3)dg6m&M{*`W-O7EFStE za5!Vp6=vjaN`E7JO3+HR?93`JgYA6m6JSq&06^IF4#*d&d9l`u*V=|@QPDHQ8T`G1!SJv=i^)ok%YL000000000000000003~CKOt49#$s@6umAu6 M07*qoM6N<$f|=&nOaK4? delta 464 zcmV;>0WbdW1L^~iB!96++`0{5wbCHfdESX?`caN zk{H(^X$SxS0KjrTgZrnH%70^w?MM+&Zmb44$LW(&Di8f)onbX5kI?ORWan&3I%14d z#&Hq}%|{m{72a28#pw8t{Eh5v5mi&BHJ`4|wFquhr6<1n>3^paJeXXMIo|+3X9{w@ ztgnSgO&K3lZ?Wn?Y`L5y9bZqt!_bCW6nI&>0daFteO@S){PTTU7|TlGUxX)UMystU8vf-^qN>4NZ$h{u8E(i zF&`s0jERG6Ykxu8%_>{U-!!Gh0pP(#--h-nSE%LNA-!_7URYX@&aj|Xkp9=YPaq!m zs~?4{cMMjfKdc?R#w~9{EhCpVw;Z$U>q34e2`9x(wP-||d*>vg7r*m8Lqdf#fKGfAv*6!+EixETLis%$GW$z*?- zN~+2JV$8u#bfKNN5AQ^J0RR9100000000000001h+x!D0{H}bYO*k$90000L_t(|ob8)YZiXNXfd4JK3HLt|ciDppVTDzM0#?88!9;{o zC-q2ZRvZ^|-*90Zu1+cYiCv&u#^VaM#@c0002* zWW{S+{L6U7jb*#5So|)#s5--N@eGakZXoj7*KNd7t$FaEnkXJALh{=fW4h+~kHnOc zZjY-dQtBhhwzpTI)YBft1Il@+?CZw--D35Er-_5?@qj8SKYAN zZN-$ei*n}i9TkkLl4kiEMygAdb{ZgG9))INjqh_S!f0awGY zJ8Z?2wTp7*@qe9+tCD8<8)m9Ym3BHHUmk^KV&y!of69OBK`v)RJ^%m!0C+;*8ExM; zRk77-!?Be14!q%I+;SsUO&sc($h<-|A*$CAiOe$JP~KIB6ZXHP?!^ygI+?zxp^yge`EayS z3F!-L2mk;8000000001RnU{3{dNIcIe%m&~NX~HC05bKG$7b-?04e)2-PJ-D-qryq zWr=o|cdufMa{lRmbiwNgfSFb|_t^b|-w}}I+GFZ>{_cXpvwvu%{E-T*CBU*o5492ilw>|mbV{$S52GCWX z<)f%mec~^-M9MA0y<~q)CGxAiJgeB+Y^iQZrXMWdw}Kx$taGF+&kmdKus2nQc5A%% z5AIY{pR_DIoNtR{zfu24i)IA;p|VrYnwMyRA>}+XYm(9I2ds5haF=Xxs(!1O{eK<- z=}hTk=q{C)s-CpJN_D~;zY44CUCU|%Q5TQbEy>4V5uQLk*#H0l00000003YyU)xnV U6SX>Qxc~qF07*qoM6N<$g0C2{O#lD@ delta 377 zcmV-<0fzpO1C#@hB!62;L_t(|obB0Lj>0euK+%BMN%y~`?1hg?k(D=YTG!>Cj}e51 zI?k(1LI3~&000000001h)4Z$$(2Fsq*W0!kMskG94v?vrJa&V>4oKOT>8=*K@U{*> zDND4wyn7X6l9^Y;`Ko`3ZinsYRiqF^1%tU;)b zTH;qT$z=aBl~j}ci_r&`ScNRH4_hL=k8tn-TvohhM6~{OF&V?XhV8*0J|>OncYvM#ECNTfV6+)MVqsYHIXmuD4Qhb`43$@GQg>sIiSmvyd`<=JKH4M$UTYPaTl z|Kd(X^-asd;c{9e$Bp_+S~N4@50!&@)w)CnOexoyRf~+~Jm6kW1y{*7r|PGQ)&J)i zknWV;hVE8*s_ISqyHqE<)QVvftlE1ocbka1c)T7-J_eic0+S0D000000000004#g~ X+>kjF+=kPs00000NkvXXu0mjf_y4vI diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_reject_0_0/00003.png b/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_reject_0_0/00003.png index 2b51f30cfe212df5691953efe741325df2f02f56..61f34db33cfd1a4ec7ac68277a6a3bb82f0406cd 100644 GIT binary patch delta 470 zcmV;{0V)3I1MmZoB!9O_L_t(|obB6Pj)Wi(Mp1g=PTc>J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_reject_0_1/00000.png b/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_reject_0_1/00000.png index 82b81902809ae5ed03f6834423e44535ebf07d74..8a9432bd653ce307c5490a95da12872eb8a43a99 100644 GIT binary patch delta 959 zcmV;w13>)H2h|6VB!8SqL_t(|ob8)ia^xTkMVZv>#QR?od&x&vC`!+ZgdIAq^EK@t z5FoI)cv>rpq9}@@D2m7Vm$dJ_&p)s0vP+Tz^Fy%!SWlSV`&<>Td_0+ZItmc;0ACs7 z!It5;u4~t@f{^GTKL;Y$Ui_=OK#_-g*|P$0 zz!)Fnr7a6Fc;^V6L)G2=8n*s=@7#(zv&5bW2zX$a;I)zdj{({OpEhv|O0s7QdU)^F zAa0O1=b1dc1r3ZjL#7i?oHAL{1A%qp1c)gb7?NXr-CczwviL4!ZzlZtTsi)3cgdau z4#!Bk+K%DN*MIP9ThNne1GMY-k}?0wE5Hu_q9}^uE;MOnM*EXkgZqRLTt=lB1Y6`iL+*+`2aTRhBNP}VPceAT`2wv2&>9=dGRY+*A1i2 z{LTRO4ww0m5xYx_3oPxtzIK#C_j1Oaq+2Fn*MG)pF!Z}~MqI?51L#gT(1864GV)Yj zOj8ySSH;{H_ewP3#l%6_^AcWSZ+>=Kb0Di;opK@bvApq>t4g*>g!5 zEzvYGLR@7Og%?pB(k{gD9*MosJO}gLHD*=I_0>p+wTFmwLu}nvM5zbycF9S^RipkF zet#OOomn(B%^+DmaJ0b>%&{Kj3Chu2apj9TpDgkZG;OcK4Uyf+ZHN@G_gkCbIe^C| zA0~U?Y&9Yf@XqfX8C4WyA+02=bX3&eH0I=p_$l! hgQZ;*MNt$1z5yTK9t@0F9E1P>002ovPDHLkV1l&d&)@(6 delta 954 zcmV;r14aDR2hazQB!8DlL_t(|ob6gka>OtQbW-_=|NkWaC5Ne~R4lC)!pmgnQ{n-H z1VX6oZ7UQCg+ifFC=@Qo*P{M$9R0uhzGF!t&_6T+Z5{smu0fdAEIhs1+t6DtBO zhAi=pYxgFc!nK;ig9&526oq4&-_~@{T~}h0C={>*AULcc8!rA9l8lSz;TDRUAJh&2 zNVMV3SbtwJm92p}gCY8f&u$$(U&gmn-UlqgtnzJoB7ZqzY=?J{K^zV@?@+R@9z9zCR#qQKqLsparod}POaYH=9h{3i zJzHp)T^v^)7^(o62$Ow=7B*A?NXK*x3WwGHD1f?sR(&&dFY##IXVngfF#~1IXi#^PA>hD1Y5%|n-~j2 zkV(q3d$H}6_Hpj)*z2^~qlmeeGl8^72tZb01%GI?-E&slL?8xpCCD29H;$lB)nb}c z^Z+b~UrDb_6)k2i!g}jGjf<~r&%7b7d-b{BhCT#u@JjNAD`lZjD0~Ly*icc9%}x$< zfjqNlk}W19q#v5DlB0lm31^szgqhTVxmj|Np=*S0fUV>y8s169RbZbHLv5%ap%zDC z9wycSkQU59-W-Rt8d>y)GWSpsf^pMD{F%(p z8E|)iW+n9*a1sT$hrSuz{SQXX=>VIaZZqJBx|$`8W$x$XyGF60HzV_%a9FFD&O)J3 cD10J*0cyn$RBliB~0yq7*iwJ2aX7?N~Gd=J$$ z#X$Un?K3@&rfHg{X_}_Foqw6eV+{K1>-DlNnE`#M8i0Pb8DmUW^IcX+(wC*JlF58! z8nbMYPO7>Ugm$Q$3M{wdCqro??L+*}G*)3#hIZ>}mK|bhtAEoCw^#pa4Djkt$<9S6 zSOGZT9H0HQS{AHdsQp38!ui~-emG+c)^N3Ga0&)sBfQZB_r_j+_Rco$x=~9|l7bR+ zbM0Qi(qP-B%MH~=<<=53*(k@-1}P)aQX@wZY`D!;1E8MIz*#o?*R3k-^nzC*S-$26 zx^u8tau3KKi+@x1fIp6L=sGI;uEfbRCFo98y;D_Ql72pR1=!QSX_}@v_VxfN)Y#HZ zMlxh=L05=O>&i`_A7;$tkWkuT{78QzBXw7l! z4~-6bPNs*$SAfh?%|=#F_5^TnSp`>rm3~+zM%xum{&$Z2dr{ak zOIO|dHhiVeSy>G&EQ!%!E z%Bk1Ohpal?Fq0bqP17`&^HuDB90&cn@4MfUHJ}&O2B4iej^h}1#z3qH=}2j>VkG}6 zod-*%W8e2Bc0lNa%5}g38{x?|vVDs0N@okUYUs3D3vCliTYp_~czgA~R)VeT#mPlj zvjcFzH9qFc+7@hTX#0&+hSzm#9b`A$aU86pwP|qHBw!)}rweY4jektg9O0%>OHh$D zCFsi9?ZCodC#TN^)kfv&5;SmfhNKg}aY|JinL?yjg%cB?-lBmEZOm`jp54HJRY=yZ z@qr#2%#l0;7JuFozb8&UiU-CjBe#{H+gY`2d-sL9G;d6xhWdg`MGItoK~sqM z8j47u9oCqM95ihIhP!l1`-fQZh?BSBm0<8@>OFqg82K;}&x{nI4nV44s%TEvg{oPG zpZ#F`J(1dEsg*mu-s1!?)9P%3gmq?YXZhFZB8|)Gz<*WPP;OIYb|(zqb({cDnYs9( z+}S#682E986ev*UQ;!YCDL=@7sPzgYrF5peSbE$^&veUv51=)@0`8Hr3$p zP-J^VB#?v8P6QGj%T^ekW7B*Rw#E>y3-+j`wwDXpa-9VieAr4y);kzmDt=Q7nh+*& zn21I#`!2@V9N}{!0LP0HTNpEc+yU9j%W{Bp2g`lR)M&;I-mJm*;z6^%1&Fcj5tB>_%fKf<~A zeSa4r^IA~qIR#g5hU(|{wG2wVY$Dn)HtR*i#2Y9-T=8Zci;`a7u-9hfAT5KAxF*}r zf#}4zGI8gtiPP^TZpJ*Snhd+5?vJ&kM)aU3;c=+Q(?#Va*2{~mI$i%pV#?!#60j4t zLe*B^JY1WDP$$McCQ1-;kg9FeXzItKGcQ6~nk!!Ldxt+mYd(wzm7ve06VNnG(=<2n YAAXW$y%NWlz5oCK07*qoM6N<$f^z@Y@&Et; diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_reject_0_1/00002.png b/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_reject_0_1/00002.png index 258f26fa84720804c631c5d73b0ddfd790250f68..dd9c4698480087fc7a7bbf924f466537b0e4e335 100644 GIT binary patch delta 487 zcmV1AzpPB!9?BL_t(|obB0BZo?o9fMGW6Cb|ESxXT`*A!K9XU_w~+e-G2z z5lRg)#7hYP003C-D{^tpxqf*ZN57?LP`}x1;Ou8u&bj{dlQqa@o6^Iu@5sesG{H`0 zh1E#}vV|04a^U+CD!zQGl#kt!e zh9S1iZ7oefMQ6@D)9F7r1y4;2*49%K&^(_xmt=|WWmXXfS$`I4rZ0Ug7N4c}fcUXE z^c=9c&Y>&Kh=1LbPTomDD_PN*m0p7VeC!?2U;Y4qw8I`SP*4>4-6}dY50ttlVVx=C zl}?ZO#ki;4jf*G{>AzZ!ENgb}6~|Dkc-yS0rRtHVRMUcWp5~CI_qnyYFj@c9FRkA@ zMYqci`!7A0KWB>+bnAY<^&hnTZSf>LP`T8hKRa2LyI^NoGy(Nq*WCABtR9Q;SljYL zMR@m*{s%CFO!Sv&gqr9t#vHtfEc7P!;WrUp000000000000000 d0002sF~8KYth)4m7ey+Pk+xQxG}gMeVzb6X9!Zf zYLA5oP2PS}wWT%>#5;#c(rs!FjbEPxT(|?Hi+?on{ZoK0(B(zv!zfdi^(jFkYqvq% zhFCeDX>EAfD?3xBltQ!+h+@d+BWQy-$d$EyqR-t0;(tBcYA-x84+!L?K z$Vbb9(Q%MzC4XqTUelK8U)5!f1Hi&sPebn}&W`Lu1^Z|=-xllLBx`9wZ8LuO&f$Q0 zuel5LEvKP=#UsqE>)!5;G1pN%ST_#W^3zTIQjb}@gx!6x$xndo)IVh}^@3l*I`n(7 zT4UvWK>|A3GnfCJGChkj0gw9ao(>=vnCZKN@IET~t30X(ndlEw2sP0kj2z5F6`F~4 tcqYON0000000000000000002o<_mBwbH9I)JB0uM002ovPDHLkV1kXS)~Emg diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_reject_0_1/00004.png b/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_reject_0_1/00004.png index e90cd9db37ed7e4c669da0b1abe6e4a823770f3c..c4c84cf4c1fba26083e9bc251f7411d894424174 100644 GIT binary patch delta 340 zcmaFI^qy&gO1+tx7xZO zaQ6d?FngJFheD0*nO_f^H{34ZP1wSDdm~T6{?~o==UnyvFlC&#xh5&YEbyOqvGDSI zHhIRBWk(Aa-S+IBH-DqF^>(MP*Oi;Uo=C7YI#4gTOM2J*8sqd+m+t-hvU0Iqz@NL5 zT@R*DTYpt{#-+J3?UDtTmQ|ZhT$wCzU|(D+$M&tSw`FqchW>KWYq+?>?!U3iZMWQ& zk`uWX^xP?%ah}KbcG-s4!TV+Z=HA`^YZ24V`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPL_t(|ob8)YZiXNXfd4JK3HLt|ciDppVTDzM0#?88!9;{o zC-q2ZRvZ^|-*90Zu1+cYiCv&u#^VaM#@c0002* zWW{S+{L6U7jb*#5So|)#s5--N@eGakZXoj7*KNd7t$FaEnkXJALh{=fW4h+~kHnOc zZjY-dQtBhhwzpTI)YBft1Il@+?CZw--D35Er-_5?@qj8SKYAN zZN-$ei*n}i9TkkLl4kiEMygAdb{ZgG9))INjqh_S!f0awGY zJ8Z?2wTp7*@qe9+tCD8<8)m9Ym3BHHUmk^KV&y!of69OBK`v)RJ^%m!0C+;*8ExM; zRk77-!?Be14!q%I+;SsUO&sc($h<-|A*$CAiOe$JP~KIB6ZXHP?!^ygI+?zxp^yge`EayS z3F!-L2mk;8000000001RnU{3{dNIcIe%m&~NX~HC05bKG$7b-?04e)2-PJ-D-qryq zWr=o|cdufMa{lRmbiwNgfSFb|_t^b|-w}}I+GFZ>{_cXpvwvu%{E-T*CBU*o5492ilw>|mbV{$S52GCWX z<)f%mec~^-M9MA0y<~q)CGxAiJgeB+Y^iQZrXMWdw}Kx$taGF+&kmdKus2nQc5A%% z5AIY{pR_DIoNtR{zfu24i)IA;p|VrYnwMyRA>}+XYm(9I2ds5haF=Xxs(!1O{eK<- z=}hTk=q{C)s-CpJN_D~;zY44CUCU|%Q5TQbEy>4V5uQLk*#H0l00000003YyU)xnV U6SX>Qxc~qF07*qoM6N<$g0C2{O#lD@ delta 377 zcmV-<0fzpO1C#@hB!62;L_t(|obB0Lj>0euK+%BMN%y~`?1hg?k(D=YTG!>Cj}e51 zI?k(1LI3~&000000001h)4Z$$(2Fsq*W0!kMskG94v?vrJa&V>4oKOT>8=*K@U{*> zDND4wyn7X6l9^Y;`Ko`3ZinsYRiqF^1%tU;)b zTH;qT$z=aBl~j}ci_r&`ScNRH4_hL=k8tn-TvohhM6~{OF&V?XhV8*0J|>OncYvM#ECNTfV6+)MVqsYHIXmuD4Qhb`43$@GQg>sIiSmvyd`<=JKH4M$UTYPaTl z|Kd(X^-asd;c{9e$Bp_+S~N4@50!&@)w)CnOexoyRf~+~Jm6kW1y{*7r|PGQ)&J)i zknWV;hVE8*s_ISqyHqE<)QVvftlE1ocbka1c)T7-J_eic0+S0D000000000004#g~ X+>kjF+=kPs00000NkvXXu0mjf_y4vI diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_reject_early_0_0/00003.png b/tests/snapshots/nanosp/test_get_extended_pubkey_non_standard_reject_early_0_0/00003.png index 2b51f30cfe212df5691953efe741325df2f02f56..61f34db33cfd1a4ec7ac68277a6a3bb82f0406cd 100644 GIT binary patch delta 470 zcmV;{0V)3I1MmZoB!9O_L_t(|obB6Pj)Wi(Mp1g=PTc>J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/0'_0_0/00000.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/0'_0_0/00000.png index f6ee4a8956a7975a25b4fe925af3f11b06b663bc..024f0601e0fb2f0fe36aff41953e679dfe349f67 100644 GIT binary patch delta 366 zcmV-!0g?WT1BnBWB!5szL_t(|obB3M5`r)cK+)>B6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000@y^?k{z{txX&&Hf zrg3A*be!k8YFa@^_K-gtAFs}Dh^5vFn>2_;9AzK z030yK+k9!uLQLL1L;F;9tKWgGzw5eqEAGq?YXT7Pz-WT^My|h2&=Ppq#1b^gni90R zc54tf$elAMyGu~Rh#3-2eB(5;Yub=lHwHl5qJb&d=GUz%WFw1LA-kCH<9+A&z1?N@ zIUqU4rt4TSeSh;kJXV5sqD|1M$CsJrKY0b%>0cB@QQUG5KsKPFKy(0`deV?+4_Yg6 zXw6S?2+>CK92bclVo#EYuoc!1`i3!o>>dz_RO}((*kMZ%M9Fdmaq>H{G~hCs+dp^J zPDza+KOYb_G~pXh0WB|(G~_?qS){k2q34a)uYk0qQh(VdAGTi^fK=GE%gvP(QUrJL z<9B-(Xm4^}4P62JQiCp>z-lhWD+9$<|K9ld<5d* zSAXKCF7s57_3=Ld@16b8=eP{WHR^Sj@m|!at{7~QDXmy!0C=S;vj7@+I)c&F)An;N~f4g z;*&799F;Ts;gEL;+}>S|h>jZx0QcLj5`AT8v&nzr*M?hiEsRf!o3mnbaUjD$!wG;f z*P`Fz2W$A8YJ}yW`Jsmf3XJ6hApAvNcsJ$hw|@c4%se1R+e)YL5!GFrjYk;{0P_Cf zkSf*aUXa_97`QzzR9Ic+cVEw=y$hVNyp<*6rg$Oqo5}TUDE`_6x4eU$#jPlc;y$2z zfVKfA@9VV>+(0uvs5nqNwdDEMP+K)wS38Ic#=|b!$3>ykIE!nCeG|K%QCy+dz3Rz+ z8h=?n%!*}=El+ZVwNKl&s!r)Y`nM4ez;eGeJ*zKeWGvF8uS;BE70nFx>@~*%AXalO z?C=@vJJHOt0gBaPobcd{1t1`E+VXVW^)vS=xY2z$(FY@*!v5&B6keL@Fxk|arz+xaut{y2{M=5N?Rgb4~6pK?RUACY}7jsr%G)&#byI0p=-@wcT$1?Fylq5;=k&LRLCd>iU6o@wBP;d4es<66$rYmgY zxy>uYF@2jDqiuET2X(^^XK-^yA~kzx^{RlR2%%(!nz;C1SOWA*g0O$no?l5FPCj#> z^0aS$7I;&GnTh&uxjT2D~YzK{)wS-}uyJ zz7%4K{7=A3qyJL9(=JnQ{3b8O4Rz+=27(}G4lYH97pbA1_@ghHt-#5Zhmj}6(0zK; zrlLdYvVSwRPv8)F)Wb*MJ|8?i%Iu%fIKvTJ9CYO}k_l2otELE)PIESyPr}-=Rne@6 zV_qkS-@h##N&ByF^p}t-E55#bh9adpa)Rv^AUSQM|jDAORrOrr+id z*7%rubjv~GL-V8b4HP7x&+iern2~T>Em!6NIe!`}onAn_9pddYCxCecv00U>^(?6E zMGnHAXDO^9<43P0@LmUwSYF4hL6>+T^UYlHyP$6PHz&O1bZ)C`Ns=U2L+t_H0UT>1 z;#og5(}S7=m0MGuZ-LtC$-3S}UNCNU5nnfjQgD}-59=nlpH@PlH~iLv{S;RDVOHO) z(SMUvPiNh8EnJ^6>Vv9Ae*&ia?MYg7DHCIfCUsrX3ae=bxaYXpmH@MwYhg!6u-p#}UwSrd4vvdji1|wE^4w%As6^$fGlH~3D1D}WmX$<&xlmGw# M07*qoM6N<$f~P6TSpWb4 diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/0'_0_0/00003.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/0'_0_0/00003.png index da12b9ef3c30cf369d132b68a5172904f5118693..977159b3f0b657c5c0253fc0de28fd52d9671f77 100644 GIT binary patch delta 1000 zcmV?$^F~*pz=3Fc#>164sq%yxV zgPAr-CRJtyK@BQhf$4UAX((wV{TBXY2CHB$L(OV=*(F?Cb$>UUUVZB z00-#f(_YrLV0NMO7YPgZ^JVnIF~(p6txbcYU;zT+ogp|kHu-6tFqZp94M9m1grJ9G zw*{sKJ2sbiAlj&SGz3iq!m*@5!pLr@k*f#}4CB-SsQDS_Wz)XPsKT-rJPOJ1HGiQe z2a_ewfP7kb1-M`UjG#YEDS)JMma5&He z&PwlahCZb#h4s#;L~DXFsol~_zoroYhP`tf9rkVU9RNSRd;N#kv)trW1Fe z@041y`Q>LLVE6P~ZbLP+>IT^eq79FjO6vu{FCWIg_kSBz_XM^4Ex*~~Ce;XUns_0G zce~j1=0IfHOA%Y#?sldOp>M1ej#t9q^lmbF^S9g7M3C&8)*`h4-@6ei-y_26fK zbXfn8VW*HvEFZEnoE?BNu+CdqFe8vV37HEW8$Md4yI9AVf;aBO&qu&GRuW$(;71{5 zA9M}c`hN~;YFfb)c+@z9jzaIm!pOY_MusrvWf!_~XvnvQervuLSMsNYF5V2g0pWyrLi;YI(e?jp716UgFWaaXe ztbbyxhZaM1ILjj)eN-tdq1>u7)HxnM3BaZY*tbGhl@lPnAP`$wIE9x5F=t^uqLyY( z0TpnHWjV%}57NS9jvRJLwcPVdOR2v@vq(di7a$HjQ>ChVPBrEys#!PTB?kDrb=;$asuL;ITZ`ud<#Di@O?xzShUJQ-QCY*g*T z@X)`h<|h+_C2IRj;;jhQQ{0W$xFGuHp@l4Ip{wy{zDjD?Xfzs)Mx)VaRN^l= WJ$5&jw~=E20000iEO delta 994 zcmV<810DSS2lxk&B!9n2L_t(|ob6gmvfLmHbW*vA?|&rUB@0(5MW3cYvL|^@y_&&7 z2q6SC97m(kXfzs)Mx*gMekAK(*Cqd+=ZPhifGl(cNIiSFu50KS9f>TIJ(abRmi)|A z9w>3gd7dSDNJxj;I8cTS^Q?@OU&60U?nHWl%E% zc#ttZ{1r_LLa`$FoMl;cyj>%y z(@1|F(n7aimIabj$F@E50pKqmuD|a$sxAp?^+$2TYk#vgWKzxkL5!!mRQES|+UZ8P%0nfQ-m!!uEpP*r;$V9z-VW6<7@PnNyEk`NhlrhIS$x%|1IZA zL+YRT0m>O+ciP!aVbVPO37bUDS3Gsl4A{u{g@16b9G19oT(X*Q__ugVc;tC{6{2e& zrsDkrXA;cjM=O8rVvrpG_a>_l+hgzoO8SllV6OpC3n$sAA(tO@H2~JrT@s@-<+k}Pc+T^Elok}cuT6Fzm1%N$ek8{g; zS`tx|kS3Lwolz2|AUU(tysLHe(}cTHn;{R}{4+i!Eo?LzjYgx~A8Ziy= zv-wy{OHg9u%#%+4#%XZZv|w%Bm4M>@%()~}e4AB8Y-Igas93)AwpiRt{|1b2i--OX zcsOIz6=uY4%6}kxO3+HR=*%iFgX6sR39y$x03a;>4KVh3wT((~FDs4^YMa95fsz=( zf4KXRiU&BCy4d67CqJHXMkY4V{L|1P<6KNP3#C=uT#vN|`Vnb%S!q!M&Xbwuv4Qb= z#E9e7nS@Gl+hS1yigcha9VF;Minn-3plfy}K!;{-uyTy^sOMy5X9Bi(PUufE0UMv$ z`~-jEYj-i=-Xn@ect7F|MmKx^x@#Ja58gs2VDK&GteI3Uy;00;pNZoV?(u)C&=WL* vOb%{EcmV(a000000000000000fZO~6hRBIqohpF1DKvB2Tov{BUv6p^i%20to1{s*-p073m zj3r(}t_uJF09fv8vVM#)|2KrtE-4D+A65$(+ZhvM%pd)t^{`qdwJ_{^rgGvEju3)N zJ4Pa)>FHufU4L(%*iPE892)`JPC9?^_LGR3!BUL0hNt59|AD$m5?LFFFccqV>N zjeN{(7>TYrMK^BT4cf0fG^2Y@#=dmHLYJGqKG1ML*py*|pT+wXBdNOjMwUi+j! zELAM6?efTNs9kwE+PE$ix?}vZ&56BsCZPR$h!)4Y+^^4koiYR3s=p{`4W2pDHJcOQ z8?46d)3I6EoPY(64gHHuz{)9{-`9IRbY@pypcCF>cT=h{cTcEms2$keGk4{Y|B!dA zbmNeoxr>?Iefj5ua&VvzT7?eO2{Ji&6yXH`0000000000000000018I3u|0)B6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000{YmN8f&Pm^=V z^HaQp*hcdl7l|EWJ4r;?3hM`B$Cy911wX{wFOBxJ>5S=dRiz zsWIi}2ZRkx_{Kv(iwh(S`QLsPu{L$-^~U)buq|7uY=4WJ?N?5~R@iHo8!KB#5!}Vg z@BS{(E^=NC%>aI@L~gte8YLGw=$4z;_$JB*_@za(asyxYjFwI$A;RyT#2$bjfq3|P zJn^k*z7-@t{!PGpM}Kx7w*>^}5@5FX~X&96W$C$TbJI!iRTS4K<29xuH2TUYe_6h>#V8RDLNXtR_8$y>d@2Dm?a8kmA@^LocR2OC!6cTxw{inI3`1zUq2sQMp inB5Z=MNt$*A@dhTqd{d!aU{9`0000^`zrp@0EO2B@ZQ7i%#(!$i;qBG4y$M#waeQzQ z=41d47~?cvy|hr{w++%ZT8*`Zyh4^f*-Ls7WzGa7oG`lJ*4Plx7>y(6OkIM;nX?4l zxpo^cH`v2-P3~TT2xHEW>BI}Cbk%fER9!d$YLy0tB#p1zo)xm-Dr7Gv@_1_*e6SbW zW=`Sw17pe~=YO#!=y7K4UB-=kEE9{Oq9}@wWK<1RK?+b+AliVUUbXD1u+lza%5Kwh z8&`;Zat|>?+e+&PZO4Q&c6US~RV_rlA}lF_DOs*2&i-dD4dhD#*S^{w&!mKt&lFTW z?HiARUT7eZDF4#gxz`D3zeqGz{sBFVnSBFnBM{Q!If=Hz#K;#1Rn zDOig9PQXh?|D}4TzD&LGPF_lPsA~>xz!~J4gG-Ua8&*S&IuH3e!Dyydz@ZPhRIdp8 zo4fN`J%1kz8H(&kDa=)|hG50tloGZlJ*B;JPsxM0!ed_oERKCO^d$5dPcQTm#%0R` zknFEu)>e_>XhG>DV&7=07C_@NuUq~3w(1#I-9zpr#kll*Y+f?SH5Xrt2A>&*4~D}b z4<(riKs-~&IxQn3_Zf|c&(mUL>&wu|{7*m!vNE$g4V3&8ut8hd{Z4dTp zLEBGhO=eptKfv_|slW3K7J{~s!5v?yduaY{W{DRvSL15*53XSIUrF}fY0M&*^`U)C zQ4~di)-!aL6ey-=NqI}Y$x{2aKaU36rIC6@+E=fO*a2Pg_W|H%du}ZcS~H}ctG8XG zKz}fQScAD2b;?lbP$(^O(1$AE-1qXyIH;x(KDf-j{0ApohV~-V4taT2+R4qO>VP~r zJ$OMi%*CGoWM2-7or5Go^*Ror`D{W{X&d+K%-o1YqqwJ~xX*ycnV40O6d^aa?i!uY z1z!gZ%Xw?LRTRwtS5Bd3Q4gf4@oAI(v@-sO-lDL`>)F4XD~g}L$)8X|KZ@v{uqcY6 bC<>h)ZZJd}03QjV00000NkvXXu0mjf@fy(E diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/10'_0_0/00003.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/10'_0_0/00003.png index c06925f25fdba30025a0c3cba9e0c720458f26b3..8d9b03344603e98f8a2629092f7206c5923161e3 100644 GIT binary patch delta 937 zcmV;a16KUG2fqi9B!7lUL_t(|ob8)ik{clmMM)|<@&1?8d&!4uD2<*ML_>Q<=OZ<4 z^AwVR+fHjmQ4~c{6h*O}Kbgwcbmsh`a7TEeKXz!M4qi4cSIzYYOU2q+?kINh71FMy?`QahkgpKs}#d?EXv% z=vacH(=Y4MI{t$f0wz>AefjOMDGW_21v@ocCvJJTcFGL(sCJEX7j}(bgVp=NL_3`s zDFPA5KvWge>cV+$HLD8uPE0#hhP>MkI101?VT`NOLw^c4ZNk(Rh>|RCr@rCTZ*g0% zJ>WtM04}B^pC3a_4fnMrsD37w1aX}=>tD!FGTYq;k`Z-h|FSA zw?fo^*)MZU`B8n&o>5qHeHk-v;+dR!mk5hZjnrd$#Tm<5B*uf{d_U$Q)z?U>K=prM=~oFaayp@*pjD2k#eibMPdG%?%=0Wyba00000 LNkvXXu0mjfW^KY( delta 931 zcmV;U16=&S2e}83B!7TOL_t(|ob8)ilH4E+MM)|<@&1?Oz2w7H6w&j7Waysgd`$It zcnV3tbx&(WQ4~c{6h*O}U%~qKeUHCh*JYO^1;&SB0kEAl?)&cT^oeLA9A`S#3XbG= zq;e<49M^TFv;#64l=}f0SRWoQ!^=(BR}Oz`_WODtK#T{@p-pxIrVPpddLZ zXlL#=Aj2R#r_F|JBeFXMb&NGbmJ>fXO=TOtgh;IjFD`(1L<1eI+t)2m4lrOA;<>AT z7`F}55#Iw6&ws=}6JtGs8%9SO;9xY zB|U0qfABUyR0^XnyB#uxsY!((r)J}LM?M&3rg{{+M!Ivmj$D|7%IJy|fv963qJ*h+ zVLaEG6@_~vrj067-faim2($ohjEmDl3O8xOqb=O7MStblHk|lZ+}5s_OaUzbxR{)H zesl#j+}BbN{fsXO;yMqnypZWcw!1GPqEY|9Qbamqus(i<=;1U1xQ8MsZ%TR3g$KL4 znS+~flbkxZ0XPYul#>mpMlS1bLojt&e>1fPC#fuS635832Cu@+JE4X){YuP*PopXD zi*m@ovVZP$q7XC|Fut#+skS+YZ}rv`K|{#=95ij!&|I~WAifk4S;o~HEJ1pBsXzW>@}MNv@D7&hMTY2zYA}VCv5>1q;v5N z7xx{csd(lEB~@cH;Lj1>RYMVM9SJe(PB}UqUw;kVxm8Atcu)`&dBzicBi38#zdj$t z)0kM7R2&gESh8;;TO}#OYq?`{rO-WF_m}Ze{w{)yuwKX<=KLnSz_<8*rKzGQKAgq> zlHl(AQ3aBXLeanlj_MA#w2Wl4ZOt5Q7Q4 z&3`rJN~K-OW~I|>=G)!N@olwbYvP(my9&GAg&S?N?SKvPpWwW-Vj5}xsJ#%0YuEbO zjzj}R^h>*oS${uy5nK35r6Iw)RY<4&J;XAR7JMlJRP~nOy4VI`*$CNjC*a4tbY6*o zL}eI}E%E9NkWO>Qe4Y;)$_d=*ml}GQS{#6)D2k#u#9!Xw;lA=cc_9D*002ovPDHLk FV1i`4wNL;6 diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/10'_0_0/00004.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/10'_0_0/00004.png index 44531783a31c4ead6e7755cb6271096b7a1ea2e2..9460013ce93716b48b17b4eb9e72df63bd061835 100644 GIT binary patch delta 500 zcmV8}fKv8BiJIVf+#9rp3DnjOEz(5k+^VJ6s zYKS4!IRF3vV7s50%HI3onhYl`05{}PG-x57KZ)KR2IFNY{V+8 zN+O`417cRW?++}MNy~Tno2i^7rc4~x(APB9qHtwOYRYH79e)_$$>3@j+yQ#Z5QKP@ zZVM5YxV%deOEde0PnzSDmMPsddIke9aQR9VeQV;!hvrpsBx&VQtlGbw1NQgp1+%VayRy#wmg9{}KXt^xX^(`*%SY+#t#ORd>n<*>1b zQo}>X$|XuI?|G26KMn1YJ;ij2=iB-@e%y|j$no3H>+I3q+h}H)I0Y+x+bp1Y(RG!j z4%`7hvu76$PD(kv5=D}m|0&mDd&(#PrW3UwA q1poj5000000000000000miY$-n42&wk#^7k00008}fK+()-cEbLb#9rp3DnjPvfPoO*^VJ6s zY6wv0x&QzGfaQJ$>wE9xx6ZkGNl_sFFk3*`P9N`meCdx;53^-L3*CN4DhDRvaL$>u zqa*?vt}dq3_5F3FGHLl+{zfX7h*=YdHFP(PwJ2Pfm74O|Z-4I&@L+H?Z0-O(We7sN zO1FgwOFZTg5N|DK1e;b-ZeK?b{3ula8hK zD~D9`%VkZ;hU#Tgm{%(!R!`!`jfjaHzx}+Zt$# diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/2'/1/42_0_0/00000.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/2'/1/42_0_0/00000.png index f6ee4a8956a7975a25b4fe925af3f11b06b663bc..024f0601e0fb2f0fe36aff41953e679dfe349f67 100644 GIT binary patch delta 366 zcmV-!0g?WT1BnBWB!5szL_t(|obB3M5`r)cK+)>B6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000}5VuL#g$=fFSOS&R0x8 z$RLCezOJGuilQirqBzdiV*Az_eZ246ugNOVLbU=YXPVX;6(xoD68fgS0&70O_e$eV z%5dEGoi(f=%zD^k=cU#C4_4D^1@dR5u?4dlX;7CoXRNYnaesJy_1|!TB89o+tN#wyYTS;Yx$eDl%4V)&pH1_^|fKrgtrn;a-a$L}1-)+Iv zU_0kCIqiZv&YU6Bi3d(AQPTm#+BgAfhz6QuAK%ccus{~~LcTMR*(4N#^otxaLRN&BsR)+F3bWztH>-ID{Bok#x7LBPEUcjb zJ7t&?@EUZMiVBq*t+|4l?p8gF+FZV!<)9GB6BGGj%YS{q9N~R{97-hJX6-l9!kp&& zl6nuC0L#&_M?5tI_PB42BElau0V#}*CY=M-r|pJMfOKJ(ScXmz$qJq2-+zoo8c6av ztVVIxft-@XJBDCQq})=y3oGJ0*5h2OZ~8|itq!2Cp>Q&vzXC3DXL3f{MPHODt{B1` z>Y9TC1b>5EbFdXTyg@e9KaNgp+H$LZm1KngNIJ+$UJj)YPUEB}S44qX$vNScSgTM~ zY&QufVVSN{AFuHI4P~k?>?}(fU zB~{+=SxUE~$N5>~l(bdP*acbJ<|c)nPj15Q(|@v|>##*2tu5F1k|%)eidOCrk2@!_ zo5%*}i=|FdR%VY@ATXi%UM2#&r=1G%ge$K3fAMYTlc_ym0RPgoD2n2vu(on~;Ff^_ z3!;Z28SqLA%r}6_%!Ox;d_QwD){S58Pk@zIS?OB+7kS~7kkM(2B*9dIC@B3jAqDzf z41Yx(*5QsCrk}EPzDNv}%uP}JP{R7nR-F0>{uu3-p;oYD;;&{k_l5X>G4`GV(!8O- z|2T}A?X*d@g*&pIYYAH=On~)8-`wrQ(0hW4&9$YTEU%-E=X=% zGI5CCDK2(BT7PI0R@wOJb-EQ4DArk~C>)BSD2n2@@fT|rL{CGTSpEP2002ovPDHLk FV1jB9&Wiv5 delta 927 zcmV;Q17Q5Q2ek)~B!7HKL_t(|ob8%ha_k@sM150tC*J>(yqA2qLNR(Y4G6}W=zQ52 z1V-Z3_HiUhk|arzB*}LEO_sl|tG+$Y6Xz5e>O?aGX=jYNB z2;d=Oy!4khEX??=gS3uTFt?OeF;kx|rCZWVi~|N50gCX}L>H7knn(N0oPy?wnSyrC z-2l-Hv3Nd{-BVBj_>6HUzi}GgHSLM2g$^)xX=F&2{%z(L8(DG|!jp+kuPu`cdvYAm zh4TwW$ddE6DSzngM4escjeIPDo1!F1l8E=BiV!kZQxF%|BIh3Xj}s-oHx9tC@VbJm zRNy+`?sTC>H5=EPa|ToHHfI>KxPCitf?_NWIPzx6_kVyfu)cp-UCGF8-g=`W3>05? zo_LT0yopZSG7~O2>_{IB!x(>%148KS&Dsa%oVFV206m2rY8Zk|q(}tAzg+b0G#K%@ znXLwl1MQN@Zw!qw!SClDh_~b1R^wQyulhl1dmFIF5c%EX;anAas*5c9E4uhIaJxEv zuz^M=r+*KYqPw@DhT`Msz@n{}`a30R3&6-ho_N_MA?yaolQX7BRdUR@XVyzJ8@8H& zldzVn%-f^?425;a<8@2dW!x;K2cjNN<_IHOJ`N6l5ID_X4^Q+O&}{Hk$?uGvfkv9V z;kT3$M~|Clom0}%cDAP=Z`oYbpyv}S*nOHBI)9HC1UlMcgD=UBH(%+u6q}8>P zAwOx6dIQ;*vF#bKkCmJ5nm{6UfTybr*XuoHUN~gS2+A@dmlzs@GW`KtW=Z|m>E2qWEG$|Hi91s)}8|*XTw+U&tY}g z4u|A5@r|r#EzME^4)Ffy8~ZxZ^`2zI#>&=>F@KE?X=h3i2z~U88o`ByQ;=S`v~b9O zQ=F{2H-Fb6Y_jmz>+mQ@SiG}Lk|arzBpAtW;~SPyN(ECT6TAQb002ovPDHLkV1nLn By^jC@ diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/2'/1/42_0_0/00003.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/2'/1/42_0_0/00003.png index 5a41bfd00461e885cc8a7f6cf9bfdbdf6f94830a..9a441e9e2e3685cc2994fb0659fa8ae5446eff9f 100644 GIT binary patch delta 961 zcmV;y13vuN2iFIXB!8YsL_t(|ob8)imgFD^hMhURliL51+{--VbPmP!S4m9O@I7@U z2t);yq+2VBq9}@@D2m(pv(mWtPJg~$FJF=g(2J@7sArnq`>E=D7RyQcu(Z{pGk;ea zGjA4^WOXYD?NB)tm~ZXZLn$NWhxl1(tiq-Y?N)1+H8Hi->3@dHt9P9Nwr(wUEC z;DB@d>@O=USieyDM$*D@J3)yXNCK%551~WnG%U6qB?Wd`Ko8iY0p6n700heyD`X94r42pwoS*U1XC)XHU%4+w@_Wd18(*FsX z9?yG&g%*|iFgB`mT(*VY(sP0`XVZ{wQJFm=VbNd9Quz&0Iu;wt;_fK(#24zReeJ1 z-2)Xkly|L&BJF}fV7&|&oe)7WPR$96K`LEjUw<|G&U_F^N6nO@7fWofUvkwZa;GOj z1R#FkYbKi!G!L-mYPOkXBGt$$CcP!=(zy>DW1BdRvFt22g1$~ouTh~yN0)hiQf=}%wb=!s++P)SyYn7bfa zG=H`R)~|$spNgo58Za#I;}4ZY^jk7u%}So7XMzKdfUwSPH9W6`VFAkc4}vuDWtczI zD>`LWg(@F&4p6_;be;{DWUWSPy=-_!SIYeZFcjS^w2{mfN=i?rnJ5+S9{`onuQ1p3 zTh+QzALtk$g8@}TosAd$IRSOipFYx-Tsq{fGBUUw74m1MhHmDe jYrq4kB5P3;MUl)u1yqL~QA48F00000NkvXXu0mjfuZYh{ delta 962 zcmV;z13moL2iOOYB!8btL_t(|ob8)ia_b-rhB=+H6YqaX?4=KxGKy~e2#lRr-&0LM z5=h)+x0EDFk|arzB-zft$@aBY`gk0NUz1g!g=z&*PK;V>lhZn4Sx9?ITTNQ>Gt;=S zWH^rFSRx064ycR+W>_;%){*sx_&?Lwf<+A-Rx8ko2yHdu@PGR1ua<+Y^2xzPSTh4~ zz!-1iWlak*O}ptbSs)@KJ8a21kkSNnr* z8%&Yh0~Vf%zkd_QACnu#Dj}CGL6@^CY%}~#mc)3HB*}BB?-U~kFe-D#3|6>YkyJV) ze|~&CgRDQoGQ({VAu|pL%a>8&3yGv6)HEkmrlvoOxWA|+ zONvMtsh7|Q>fA5F&!sn4<_oPlYZcKyEER|-d?xj0z<?^T$zHWUV?f@BUaw(+mgW99Ip)H&x{%(nHr%Tj<$nJNh@~KP8 zw)JX;4Mv(O&enZ%2XwD>Yjpud8?-){YkZKrxNH?lN_UXc2dA=Nc%_K?j#blt1Xbf& zSW18ik$;6a*Ih<8=9H3@#3*5b-7`Hx(>gu{=-;!5l_43>`eqaXRLK|vozP@KKhO(_{C#}~H z?bny&swGjRQg9Mj?*m4o0Zm74(OAAfw-M>xnR1wYK1%(DG`cFv94nc{ZX zX-0nrAg17ZCJPF>6tL#%Y7--{)G!~g4$9Q@LThiqd;s2ICLuic+t8cvg>S?@CH9jf zNiGNaPkDJ<3tYt5(kxGbzD(qtCsmBv<_ov-R7kR9_;~81eASYGSo-J-9KDN#i7A>< zt$&|_Xu8;Pou38)zY|e!G~l$r?>@99A|EeQ>jb8VXLRZLyqjdV8n%+|v;gb)9YLBP zl`Db%gh-Qo#yvp&Qq$=bUX!&#;#3tI-X<@00NvS;3^15V!Z diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/2'/1/42_0_0/00004.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/44'/1'/2'/1/42_0_0/00004.png index f497f8005629d357793a9b3edb73f43e804a4d56..9ac39103a5d4ed2ecf7057d055a80045ff884cfe 100644 GIT binary patch delta 471 zcmV;|0Vw|21MvfpB!9R`L_t(|obB0LZp0uAKv7zCC)xj!*h@dEB4qRMUlX@8T?KxSD#@WfN zuo{VgrU8gq75;Cq)<(Dg$dBjbA~9w1u%@xJ!Oq}XOn3t9j3G$z zsy!AWE_wT)3QM>8r6b)u={B{8#%@9a1}@(?#on8^`4pWoy1eLoG|JSl2_@*}+Fc`t zAzquuy0ru)jhtE1X=V$Q{s4e*!aG3h9O%8H6-C^>kGtCZ&A3l( zxp}c`w9)%Ja7(4kw?06BY(FdhMw98`_m>`>l1tyQQSAzEJ3C?}_Sob`A7x2?)g@?V9_} zA99UXS=#@YQ*!W5$5o+M=>(Y^EJb($000000000000000004kxegQm5XC9=|CLI6( N002ovPDHLkV1j^i>#qO+ delta 447 zcmV;w0YLuo1K9(RB!8euL_t(|obB0Bl7k=&fML6{H{t$A;x7BpS%xNnsYH$Xe^0HA z3IQWSmjwU-065%h^8B20{WYaDjuZj)!DfK*I@{!&>s!C|TG)&!SJ>=l=H$X99VsQ3 z>llfImb;57wfy(47o+39@;h^KkC-)eT1#_vu0`-*R$Ahlzkhx^z>~?f@Oc94j43Gj z>OB@BHFf-=YD;e(h$E|mq+@yyjh)W`Y-qvY6#Lag|4V{4(B(ys$DmAY=2L=>tla~m z8RE?u)6pfU7>t=^IPD9knN`yP6Klr-XfDx=Q?lfDHC`-aja8^wyY!k^+(^Fz9M{D6 zG#HPW7lz|SPJb&wr}LV&O#d#IISv3fHoF_@!m?H1d#~d3SLiOAagmA5qSIYq0D2qo z^^rQEmR){)sP`=OR}nV;uzIlh^+XqY0>%fgD9`{j|G+6fEjKMG&)td$LOua;mIpPx zcGQ1ujw@A=POYT(Hih*qW_P-+irL&5VSChQSlG7Ch&bG-r;I^N52``|tt6Q-*cIso p0000000000000000001X^9M98R^jTyv)2Fs002ovPDHLkV1iY3)Vlxx diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/48'/1'/4'/1'/0/7_0_0/00000.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/48'/1'/4'/1'/0/7_0_0/00000.png index f6ee4a8956a7975a25b4fe925af3f11b06b663bc..024f0601e0fb2f0fe36aff41953e679dfe349f67 100644 GIT binary patch delta 366 zcmV-!0g?WT1BnBWB!5szL_t(|obB3M5`r)cK+)>B6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000{AFllQ=Q4~c{6h*O}e~b0c^BjL3$6-qnfw52&0QH19&vR78mG_eINxJ~49^hxC zawlatj^oH0RuJMnqs-v=lKZZ7FR6qw=~USx!Y~G zIqezw^SX_qeOj+2W^cp``>tr1*cg%iXiDr>G;Lr9tYzrvTut{f?Rv@u&gH~9*b2Ew zX`MeTuFc8?UAYvJjp|L>ZA=|ma2YX`JxV4T%ut0iH-Fv=^y-%LfLXYu0|VV1P&|HU zuUw{R*EjMA12oA70S#c`2np7EBH_qW4A49qkh?L1@rfl)yR7CAr~!C0TyzS_1yYhVZzLxN4s1=c&MXbp$V||AuR7W(H0TKz?phzJeg^G2Y zK`tBI3V$D7^+ZftGES`yxe{%e+hxekzF}Dnz7RA@kp7dA8auCT+C?StWwf1N1Sbj? zGb)O$B(^v;xwRzYluo3@)kArbBArcwrZgH>;$CZ2u6e*GtER-znUIR$Awql}_wy+* z@u@vF5*x?P^kBmOPW8OYARXpd2EY>!cF(5d!+*FBuX(Gjkn5bnt!ss#%T0Jm`j{@g zthTG|nh)UHQ&+}+2O!PllAHJh8%oKClNZBSuGN}*2TX-Ut;*DLkRv{i9W9MiF4A*e zz9CKh8GOOE@lSjk`ee!gMNt%g7wG>3kd+pmxtwZ(Cm6&$<*cxl>`W2H^AHd{%jU|s zVt3v{tOU@V7tVG-Rja9LS8rbg&OM z+iM){cL0*A1WR}-)G(wiY_Gd)&4w^(^gR83W~>D@fw1N*;hlVNGH&XmX#cSi$nF0r lFRn43HA#!2D2n1O`~r6YP@u4Hmj?g<002ovPDHLkV1j$W)OG*> delta 952 zcmV;p14sPX2hInOB!87jL_t(|ob8-j(%T>mg=wcd@&1?Oz4XBohSBvPy~ z{ezU@*tRXj4+xn$`rsnu ztNmW4Qf$4NTQRwK9cULmQE*Wx{yB_{xZP8d~iZ)6Di7_Gx&CZ?cua#GNh zx!ZtrgKVD9<6F)eGPfgd%suKesp3=Z6*~izlCkI(D3)#tpmye#ojlF2i z4B`5Qk+S97mVbh7C+ps2-O1OIcql50q9`WN)Rhs@n0y}Za>ergljd10ce`ygXIvmL z$k~BnUJ!YUU#%Dk@xyFgu+N$kyE)Mn*t&BJ9Vb`QXPNeSY8LDn@;cHA`LNzPzf#euObqH*A^k=vJWcR+7@KC4~r|wgJne{s?p*rZX0+2;K2E{r{S*TdV8RUw=sqo=d z-woByi+@u`L+*s1!-x&Jvu~KB!4HB)3DSQuQe)?}J9g1Y{0wc2i{VY%s3^9Q*y7aU z))dAmpGb?V59NtII;()DG#Yl|e%7iS>wqs-&57YNL5kohLcAXL^(j#G)Giyzjbmqe zGU0!xdfsi24s)yk;Hrb&vnl&9?!{}f)pp2zPJiLnwNlVAO?XNAm@aKrm%HtrH{jh< z*T&xikY;kpRXxFmQp9kwF^uI}t+_p5DlKYNrjCOg@p|lRY3R5}&w2UT8ue@Vg4@R5 zeK+(WQ~-*iD1H~{U& zUW=S}uX}O4HT)GI4#9el5&3>rKz<{B08Sc(m!|A=oCh-FFm3Fu&Gs2bdk;XQO0a}W zp++EWWBc4?dp3+oqxa7<<1DBdggs{&Uopvx#ki>_Mb|%80$Ke(<6Oiu#TnB!8|+L_t(|ob8)iaw8!OMVYDDiTA%G_A(z`p@<%r3!-Vq(fLTl zG)O|w0)$;kk|arzBuSDS=TD?@t+oI7dcAN>QK2t1E0A)QskJsytuLODeP{btL1X?# z8VhTJLUy^8q<5&E3c|MXWudO4>re47(%3{yncl75EGuein}5@duWvpD1MEEtI+tO? z8^A-(@#Zh@wGe*k>z6JpT;;>)$5U$+4ZW9!XTtz2s0U4WX`=JZJIf5;8#4q2*${#b z$8HZ{hFCU-9Edh1M?+9!Asp*EOcA&5FMJfz;j8`A zuN*>`UIXIW;(yRN;LQP>uCl{-TZB9lf==RjXIFR$%K6wg08jrUNsxSP&g^hx7j)S$l|wW&@paRD_G6dniFopO% zSUiY{AvMQ56am9v3$Ler!cLd8hUU;-FjsiE&PoVk6o2;dXDYjg-8KCNtc0_#h6}BF zL}x(XmW>2@Z)z^zfNI@S7y4#Vt85pleNdXZ0%R6p-5l%E*OulTs@WqG-DS^0)RAYS z_AkM8a({aN7>29U`-jOfc#@1lPcm?Fj=`;H_o5pyZyRdXWOkN#gR65vTC!KJ#SU%u z>hl`C=D2Gs3||XSVK#H(Jq2}0BN+<|mjq?>lJ<;G!g@wDu*x-$>^;PKW67VYwwocC z%LRGo-h%1(-HqIeeNHbJur6JfMA`CchpGn4z2LNB|^!@aDsOvL`b;V02o544j72gH34n>o3 zSh|_=G?So@a5<&22ADiGPfEQV)JZ1RfQGkZ>8OpbVtQ#_+I4tcW1^eK zmsxXfDoVB}`h4EXL7)Fi`8OvAAW4!WNgm=q!ZLLstL`nK00000NkvXXu0mjfRHxQb delta 971 zcmV;+12p{S2jK^hB!8$$L_t(|ob8)ilH4E+MLntP#QR?od&!3@Dq4@rq$Yo6 z8VgIzah~TAIV80~tsf}GL_J%_*6-r)OydaUHMLnIM>~vbyMG?X*LR;r6C9OK8kb?s z3g97qTldK6r zJ7YIMsiAgG%!X*=vO5F`V9uE73| z+lK1M?g0zW#DAX&n2*T~W0jD{LeS%^a@%zOkR?8zBuVm(lvixI{8X(NfvS+yCu)Ty zL>k(zu~^lRKOzs(w5)rG2GW28QVrL3Wbb2tM7@(kUdyI81e^wIcs;GNb+$wrx>I|>yuZVBMnVwN@n_!;`O!6lSoaDT31|Ns4z#LKg8^e3 zRuc4kQ**rniua!SpkFK6F6D)49hACW0WzDgZI1i0?=0OHsP2ed?2sc3(LkP!+FwFw zi zuepISJ2HW#3sK4bJ1mod@1i{c^Xj^Hbhps8j(^*V>2ceefEgMgXo(W?O{*<*%a^3> zCMC?!WwgZ~W=Ya*#cDr0VoD}?DBlNja7-4T zf?Vlu;SRr(*$J>ml$;D9gF%ucZ%#)x^a#?KN1O;exQzj4Ox+`?n^drA5`II9QY>Am z(0}HmZYJ}B%_c|i2^TJj#Nxy%z|{fE;nTF3yS@#LaGib6!6~{%$zs}|gQfc>JXtvk zV#EEqa_mPwQG@~a?LEo3_5`?N5bAM8BeeAy)V>lWlilDunH66Jvk%QC@9t zAK@~PYyjlS;9(@}-UD2o^3&)9wUdrLKtzbPEE~1)tC(6^lyhyqu5q!==eJq+Y^q9@ tboBYWm4UwZf6BiJIRQzMBuVlR{{V2sde_xAy$k>V002ovPDHLkV1n^+)QkWC diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/48'/1'/4'/1'/0/7_0_0/00004.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/48'/1'/4'/1'/0/7_0_0/00004.png index 82e479d2223ea535f80166141a79e81f932372b9..bbf5a2c3b44481bf0a5918b4dd99afd85ddb28e2 100644 GIT binary patch delta 504 zcmVF1DMQNuy$^MtbUi#rF!$<;To=$qsS4)IU zu0SYq2mk;8007(h8krnp%>RA8UUf@hkPn&$PCwnm81tuJlon~)BoEzuk4zS;8FVsB zRwqKxv;eWI!rvDx*=YM){ESRC5nCpgHLX=^EsQH$(qnIa+J6z?L2*4yI01f~5+uD! z$3p0m+Xt0cn%OUnG~=XgN{7bJgaC9rzB0w{O?>&JP9HkG=y+7pR5ue+(B|A-LM%gE zn~!B{3QAOB<_V|2a2l+dHtelc0Wj+`=ax+RHnWN-Wc^vlOkcVz7SGamz<60a^gH0; zREn-JL%S(X&VQt!os`s>m0kw@eC!FRZ+`#)2z%~;Qq#0qs+z4Hb6j^CM4Lerm!-O> z*&Ka8%!0ZyV*cG6yk+Je-0)j^emB(5wc{!+v%B7MKW00&GVv5A18{LE<(H|{-*)=Z zZcB-7{AG)W^8wJ9TAMdVUvF}cvQC~DfGO(aH>!CdJ8`G4=JQ(-Igi@=7xDy5U!v~I z_qE1!o^ihQ6nBF#*!Y=8Demf!&&H`(-4^$ECqQ1 u0000000000000000000000000mhlTlMx6bha?e`;0000F1DKvCN1PT2pFyqA7>$}mC#nP-~Z^VK>s zaU_fxIRpRz0ARbX!Sk={%Kwcq)+0qgeozf?j??G5uKcTS))lHTX@qXyBPS?BrNZB@vtr8lM}9_5wuo7ir!`$}nQIYTnU$V+^?%c+1s+VU$DBLB&zXXh zFYC4tsmbF*v9?(AKpbfnsf@918oxOO=(vK)DgM#K?@tNpP%bZJJu1sow>eAD&b7Nj zT!wgZzNXzvP*SOxr=0$c)5xxA!^B!x0CkJzoRTTO&3Lhqb*@6{+Ewm}#TS*&fQftJ z_f)CJ$OB{IAb-b}pyOsuTc*Eh${YuPH#XW0^{_go&3&rc=TVQBElkm75SvS@z0qur z{y*x5x^hJQyLs?YnE&90XZVtCsM9^;tbSR?X!$s5FSc^xDJKhXyEElalhxdIj#Cb6 zEp#2DbvR#ulA3Gv$=?SS1iEv*Ny4}*?IbEpJ&yIc&WL6lXt-MODvo6p7)DZ zfI4#hm8W<%h=9%S3>xWOeJONiLL~`%vO^7mngsH)88tZR@GA7-8cC)GOOajx00000 k0000000000003Z_UrFtvvm284-~a#s07*qoM6N<$f;5izGXMYp diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/49'/1'/1'/1/3_0_0/00000.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/49'/1'/1'/1/3_0_0/00000.png index f6ee4a8956a7975a25b4fe925af3f11b06b663bc..024f0601e0fb2f0fe36aff41953e679dfe349f67 100644 GIT binary patch delta 366 zcmV-!0g?WT1BnBWB!5szL_t(|obB3M5`r)cK+)>B6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000@$i(UBe0AF( zWDqi3+*(l-MNt$*Q5@%EvwrV={(D`QU6K@-FNy^~J7Ie7vng(TT$!JA6d=_DeC|{p zq;$u1U0K}9og;J(RX6)JZ2tA$c`feD5;+49@W7~oTO-duIw%D`Y+?%9Bqs$O&fOZs z4f5uECZ|)-z!)=RIPrzk&Z_A^VBI(X;t~xE$hC-Q?C>v&qA2p;0m$l8REPMjn;Zk3A*u#3B~}!L zsTO{y*ftVTwPx`k(1hKVTi9?$T>gt!L_rjkS7%fyg2-5|8cu$blB;M^=xo{cFy;fk z3C}_ufY&n+DeCpZJ%va)ui!>V4naITqXmh=JIF2P0e>-YVdrV^5W#uS03hP!`)#TI zgcN~ueumK*(Dg%V@wH~JdF&NlTa@g@S8FW!8qR1(ku=#x6* z?P$G>Xn&3104!ZW`sWrF@Ffw01R5=^pa_7m%&wSGTSw0VNvrzar zkS7r1;gKf9GUVc_tFcFmld@t-H}y``fy`40zX@+ORTM>0B(nT%sId;~-p7|nUEBw; zJlRrcZoAEic8qp;6KQB7j9t?GOK#zBY1{`0ISor_| N002ovPDHLkV1mG3!Oj2x delta 937 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 diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/49'/1'/1'/1/3_0_0/00004.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/49'/1'/1'/1/3_0_0/00004.png index dd175d24f6ee3e71908c16a8c909d586d2f0971a..fac83d5c2ad0574cdcf9c59418bea7b61cbfff54 100644 GIT binary patch delta 498 zcmVF1DMQNuy@&1>@Ui#rF!w3Wl;^BJE`AQst z$(4|W90C9U006*tzC43tjQQ8=y4se)Air2OFwQefj4{9ajkd_DO`2htZ_i+{8s{Xl zWHllLO$!iF75@I9W>eaK#E)li6%jJItZA*K*21_Ek{0{wuYUs$c8Y6Z!Va)wlpyJ) zZ404GZXb%o(#?M9O4m=Njkam*OmM)!?Hfbvvxz^S)ET2pFQq>kX=<1WDQI)<))31O zkIl!jH3cOaKC`&fUN||crVX*R$^q5-%ovhM-)>eBg{(abRnu2l7K?k8&j5c}>^cWL zoJP?VW@tBMl7BNPXeXLFv(k%mp4aYxcK8DTKsfRY5EbhEb*!yej?x;mmNr9m;5!k= z{ov?lSQ?X-$xj`dmzSZ{#+hcBpQJQpKUFIEsXTUdPkGM%(o@hh?Mj@-xEAjNJD_o| z#;8RcJBay@py@qHRjGmCHSUbL%zq)XjkZh!-OwWs-fJBWsJAKZp8pP@Bk#jk{|;1;M1&07*qoM6N<$f?Ad1`Tzg` delta 491 zcmV1cd~UB!A3FL_t(|obB0da)clZfMK`On{fXlahLvZ$}oY%$fxVP&#&$l z&`lyD9tQvb0I=Mrvww^+{}@8BTZ#txm(>Q&aoWTf^FyDsGpx2rBQ*Qz>6{D+M+jla zI8Gv<>FA=Qj{je$wJF=*^4rr{BdR73YdYOB)}padm7ez1|9{?1aA$Bm##{k@&Jd({ zX_tivP2T<}<`%6E#5b2oD%)rmjo+9AG@OCa#Xp+({V6~V%IT%dhcQhx8#4v1oVyL; zG{l|rnO09hiIFo;I{gc$o>kL=!kUJrUak}1BI?ZraYISW*>qT>aLmAGGDi7k-ZzKl&A8s%O1-ASod^VOfN&6*SJ>i4Of71ETh*X zPuvUgNVC7Tx*-ph+joZmeE1;9mkAAa`lpaz-fFH;FM(O--l?8Gdz(?yWU!Bm770000000000 h000000001(<_{92xs8lYb*}&b002ovPDHLkV1m8*_hB6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000@Ui#n(Lv{T@z#*x=hfM5) zge(C@!lfihk|arzB*}4p1?6k4{pIsKc1zNrzbQ5V^-NQ1?NxE*?N0xstpO3A;CDp0 zvBVwE^Q>|!2pK)(vhiB=d_h`jQXqdK!Wv}M@Bvk%n32Zfh=0S|i@&-P6uG&UH8TJQ z9OKPj+O!Y{Z$Co&q3W)F1)G1hRxZVj8DdQUCM+;SaBbxIn}e3X!zM04LDnomhu3Zm zVg`A0-pT1DsA0qm2`9dBitL&W46Ka-5VvUHkZk^SR~536#aAJFG2!=n<@meZC7K6Z zjqhR;4cy@t-^c?BSmzNs{bBE3Nb(KlPVj?Tjd#kkyoE8o13v zz4%6~lG423ZpMv&z}_bU;IYJ_bpg&?=M!ah#kn*a~;AePM1ZOHdtZZD$FNO?+Ny3}Ln0Xubzn*Duy&u3JSa8tPw zTj%F%L1aQ08B+-imUrkO1tKHObPW)DF|uE9#zO(Hb6R_9liCh%h7^Hq+llmELA9V(6e9zc+-#S@H#sTJL{t%We5@$y#D4>}ehFIgkVA=Kzt9Kg(`YYRd%WxG z&I4YI^8m3~fggKfe7LUhVZQznd?Yb^R=QvgOs)v`?3PCdYU zM1RbWMDeN@--C%8*ssBm)S3W@>8ogp(Z;BxR^{lU07Z*FR7Affg7muzGytwc32u4B z@QZ7S`%M^bB(7(N_Y3}M;ypDD@l@o1c{@tk<(qyR3i{$%@$KeBzsp|2Mt|f@HBnRK z?*Og@)VX6|x@g-3awK)n$}!AG+XDBMQx`$$^Mt*Uiy)#;{aZ-N{sW$`RMc| zhy;uxCZ!+3gnXO5h6tw(DvSL(+s0;2gG-;3>U zT-vTsZYfqVQ=e|7Eg8ip024-lCcHM`g5slfbj-{tXdRy^Xy@Dw z5N3$Q^GtS6K?M*qCY*fYG@Ui=8C4Gkz|7LfAzA#}l^2ODISb**L|?BplM8#05)9$` zg5k2{yfy{Bj(^wQWnIa~;+PZ#K@fZ-tJP2elX{w^A#qD2m!e6x<~rB5r9|AqX{e}z z=tpCjTfUg8R$V#3O29v4?_|kyNXD#uU{irkyA&a6Slw#49vA816s=n;#cjJ!(duqr z-q{Kuj&S!PxZc&qn1qMC(5(ORN=#K+Pd62Q!=V~RrNz~{Gkx)-qH_1p=!3@S!|UPV1ei!sG1Yz8P7 zGaq-7JK>$*I#9KsQXQ)!asOOgv_(N?MU}u^VSh^}9u{32mWpvMBPIXQ6-(74i5b~z z%z|E8@}O(Rs`t+Wz!`ukmS~Spyae4|++VD*H9%ik8G7Og7wftvV%l^uTf{)=!i86|KA7r$CS!RQ->cDGymQCv5uSp#Wh2 zl7D;YnVm4+&X9W?bAMzu&+X#-;>L~a7XVt3h7AY6+`i)ew2XeX?$JjgiWYUKg#K0& zrr$?#s0DR5-@q>z?UWTGc|F^_pAP>t(L5E|;F_KFoTCGfXkT2e-)r*yuE(iA1&Nhv zqNb?V0Ih`7`AVU&l_rQIsh#I&&iv>4?IP(@(8m)22!bF8f|vLO+_E>C*^Ehy00000 LNkvXXu0mjfNtDPW diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/84'/1'/2'/0/10_0_0/00003.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/84'/1'/2'/0/10_0_0/00003.png index 5d1f60c03f078366e2af817933c797694ff865f4..6fc974a5999e95d21fbf6c6e60c167ffb65a26bb 100644 GIT binary patch delta 982 zcmV;{11bFU2lNM!EPq^Ea^xTkB&og0-2X`2B_FP(h@LG0b}~_ac^MFTA>^LPwpJ(< z3WY+UP$=AvkCnx}_xYc%*UO$sCd`B41W-;Iz4sw%*rF*p8#}LBROWMKG0|pG$S${n zm>tSff#}x$YslyD`62vUSuBF2%~ zZm2dQZY@CriE_;6AY~+4YIqdEg=w4$fY_gbSvLIZRu$5{;8lp1ukkS79Aqzk2duZn zOYZ?c97faCc7OP8i;!nZ(4Ek{v#Y!;%6Z!pV5fhfP$(3ddk1KIPL#BnCuj^JmrVBE zUd_dOf)Az@!`Wg>Kau(458|$3V=lJpuH>U{s)#un=dnnuSX4wJ<2e6iAB$X4Yf0*k z*hdh@#dC-RAKBE!1}0L z!2rt|*HfdW3FX<8=#pvtG7#+|k_ln~$OU;jxFzW%*n78gvf34XoQilhR5LDL&ouR- z_oIxr2zml+ouYl)r6O|WhDxngri~HMBCdw57>R)!4=3b5CtKebs*}t6w?S}qdH-fq z44y<)p?@dgIJshQ6x_WQ8!D1{NP8!~iMR_zcEu$c#Wzw=H&7Y!OctJ?X=Po-k#h?} zETchZf)WscC(6TSGA^+SS?F$|ad}9d8V3l;ZcYU@RxJ$W^JE;SsNADUMnF473pXD8 zxrn*mw^M>X~a& z{v6Vwigv&RRe~PI{=X6Xbx3zpMcWh#g||ij4sDJ$LRJ|P_)Kk~D8$y#)mb#bB@)iGQE%;MIoe)49$fyM&R`_)H+Im#RcI9xIiYST#~<9nO_q@23lFR#_Z3@%mDZyWK)TB+HuPas01Aadp-^}TUv*-ZGgQ}}NdN!<07*qoM6N<$ Eg33MHCjbBd delta 982 zcmV;{11bFU2lNM!EPq>DawQ=Mb*5$~z5gY-m-*<#vUnbme$>63FJll95cPD@TA@%V z6bgkxp>R9?Y>w}}&p#f=VM`K$xlyG#$$w)d=y7DFZKc18lpHS<3WX1b!-mHAnOQ*N3%O=O6{H_-A`Qhm!-jEU z7^jLIi+MwwRXp^>W6;%n>EVeiN252E7!+g`TT}$6y6kNcOKL4i-5z@j;y80z{7yh7 z4PZF{^HN32IJi@6rkYI0U#(hCTX#2!oM@Q4D115&Cw~B3d+w*G*<{5pxHM?21b?iZ4>oHqaR3BEIyJ*rh_b3S2BOFvc>5EkqQi6a!bu z78w__!yV{Op>cT#C1-3PH^Dg%*rv@vEHw1YK*>112kkdA?*Z2-E;5nBnTwd~eIpgf zz%U)_1V9Y0Van>j(_EWqoK+=KX__(G)CdBJ@_)v^3p##5I!BumZCUf)e+hhJ0ItR$ z4aLF|jzO$WI^P2{vaosOeu?blpFU=V#yLcWr{wR@X|F;wGIm4xM#Mt3di_Q4jV0(+ zxa5Dt-i+97su-F=q44dnNil@R>c1d8;y_Ue*RW)>xCEC>>=W#{#MLbs>_Bu7xdJ!c zcYj)s(LgL>2yxCbl!FJ5ap^ael_&CJiG3PZEt9LcSJ|oByakpVL2B6Nf;ZN2jM2sV5@bV4_yT;&FMQ!3l{JiDtDW{aX zM7VOkQxg;C6|V+6SC7I15^q_>hCYl6K%r156bcXFKd3UABJfNwqW}N^07*qoM6N<$ Ef|%6GYybcN diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/84'/1'/2'/0/10_0_0/00004.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/84'/1'/2'/0/10_0_0/00004.png index 1676c3c5ddb30d711eb659c599b105ba4d58e5fc..98137f1dd3cde824ccd0dc162ba2b62b9f8f0166 100644 GIT binary patch delta 458 zcmV;*0X6>41LOmcB!8<(L_t(|obB0Lj>8}fKv6oHon-$@VlVSi4MMg77YLyAp074_ z9<{-xNeBP{0Kjsuk)30V`P=Kd>X9NK-)IInkJBy2n4kTvbdhFEIzqRfk)6fW3?5`w zTAf5f(*=l875=|qDMrVC;%iwVyI|J&&9{_NKn8~;3nDkn_$ivLHrR^u!zY40{ z^C`u5oW)G~36+$9fH5wckv_Kg1TshN6~ z*x*6IIRF3vV7s5e^Fs*fNAG<-QUs(2vjN8I^a&xPxBgRl!fZ^uLbun*$94(}H&P?h5f3 z;>~%d-7P4p)XY*&`@(5t)wE$?Ei6EGiDn#8cm0Kg8qWv55-t^%xZ`A>37He^O*w{afq`7^-XJqhFtSk!sv z(%ZSs{Yw#ZYLYe5d+jiJl46p{{x+FZll{%8!AW$XlPwxarUpxqUH||90000000000 e00000V3{`sq(B6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000N z=PTI$x~~4~d7gGnQlT#tD}Z*Uxvr}>#f`U;{z+Q}(tLtHk;aXb;W*DTYgj?Z>>*zp zw^!$XNKLI3$lpj~4Ki!^ggT^{k;>wX!|RKGbr&d7m`lzIz<&YfcpEQmS%{OjpP~I! zb$7o5TYuMe@mAcKA#wsR;epWvw?>}74NwX^Y~mIaBxeiSymxC5H^|BPPIhlW4I^eq zIPt_Ok~M9ZSPKInrfA@lY~$vk}Y4EMAup4DD%7MB_}N45fx#e58kIH6sr2;vNK#b7CXc$cW5Jm&+Y#J)0~FB;Mf@dT7t5iLmU zMYFIKQGa)IOUR!_lWXy-E2Dz$AxbLPH3w2dZ~CiUmgLE&r12I(lVdm2%XYjRDeUpJ zATDb5agGboL!zVTj{)cj?(opwf>d52#-;y&a zDaP&RM-2T9_?oP*pKu1a9T4ZZHp%CLsE=j|zkh}&8k)R{JGM@3O{RY^H{1IJ9{3NL z&m3rthkqOThP=KgisEBY&j2nhfEoao65D4(t8fKK+lSn%98X@2bXLo-hXi2DkK?=e zXXh|n%N&wIZ6n)KST1&I@~7rini{H+J^^tt&b31t+Dq_Iu9ILd@nz=+pcg@nUsVpd zyMOfFD0i&*oF%qgz&i@LvI;T$X<2=vN4!7J}#@p;2$nZ7(1jk>bgyT4l6gwbf>X5IU z%cbK#q^C9t=WlSl2$?v1PBkfKq_a5b@c!aowFHZCj0YDXXMY9YfOEXZOIsG={2eFh zI9rXqrF(^JeS8%6WR{!+EI45d!L5-H^ccnAITN>_I5}I;oqM+daf2M5@8s?+sAJ>| zNhe-7EmuwV%&LtE5UVtBO7{4={YfDU?n3rv!rMp7;K5$BW~MNHV5A&5k8MGZllANp zH}Y#qEQ*SvD1Uw>Q8iQpsX;Yakq8N-za~sJQ*7X)+##UzMz@?JdhHxT+|qD}&?pc75Xb!)a~iz!^9 z?rmIRlrzWeZnQ(%jY|jp-|{|S0r8!IhH++S!HP#p^MAx>MApPx5`crOCme9~*cO_8 z$h&;56k&5ECX#GW45ur=C?82;-A%*oxqNTLGBS(zRRmLenv>CZ5mvaUF+_q}2}nT* zBN*9AKo;vcDB^^6p(2PAzoFdfNqjN!Sc9p0UW^NBUU$;ZCvs4U{x6Dg_wyq{ ze*wNG8~Z1m0qzBeb6lI`b3xQcvxHy66AevX#eW^!r?w_D-k4kMeF6{shse z5@<)mN&pe_#IM9ftqhp*IAY<)Jx-^s0J1suY$0-~ZGm6QP%C$zH~fzHM7eMO%(_g9 z9kDij|3UKn8?g^({W+i|y-E#Q=q$WNDI1ESD2gZf2d2o{jIzy_;s5{u07*qoM6N<$ Ef~H5u`2YX_ diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/86'/1'/4'/1/12_0_0/00003.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/86'/1'/4'/1/12_0_0/00003.png index 61c42641553a5c82a7f4c180bfb9a470444b3187..18383665ef26d3f0f2fe0a19ad65bfcbe99564d2 100644 GIT binary patch delta 972 zcmV;-12g>J2jT~iB!8(%L_t(|ob6gmvKt``B&poQ_dgPM$-)(i=-Yq*`;B_#VFVHq z2+`wG5{X12kw_#GiR1XS(z({!KfYcsTapO$jiLZJ&NOPRZKyUE&B%VTeXm7hey?;U z)+`PZ4R_y&DQFP^Dd=$S z)E5;*306hdw;-(!zj8+gzrKIxs!rULi0{kdRZLj$L;`o`6m*IM4}u!141&gTh$m; zlGqY^Ja9gW@L<4cDT%l~fiJ-Y-x1 zW7dab_><%!CbkY}1EDR49!d9J7m?&_F~YVU=E()vY4rMea1q0+*HS$q$i~wOI#^<0PiqE#iDdbwqdobM(&i2u82I1tevS zAAi%@HM*2oBFY=u2X4ZKDIz7Qb?+bR|1jiN(Cg|OdCOceHcChK*n1D)mru^3AY7&h zgOnvX%E(Ku{k!YqfdFWkS2Ix~@?4NHoBM{`F+q~A_*yg%x#cYFfRF{kgNpk)ij)=A ztXuZxL9B9TaZFa81@b5o|+BTI4s0000#q9`p*1G1gOdS8jd zA`2m)?Ua%vNs=Trq&K84uH8uBLl7ZcUWF*V8|?_b65M& zFB_sGy#@sCiGRNnFdmx=MpPrWrJ&o13fl~Smyj4wk|gDY}Shue$u?Ekgj2l&7xCN z_!9&^A+UQg2NMr9(8#>6xEyjyzV5db=?pppg;kqFM0MFxYorLGr*%Q0OqqZvW52f`fWx?k8%L|M)exI23X0# zGs1;hvz>}9gV`zGXm~$?XPn6R8-s^(r3_vk&_TJckl=ok}*BCsFH_bv1 zVc_H(gMU-e?xoaFeTXfVT4KI4qtC8->oz4=-g2PD#Z1e^l`Z4+hoR!ZC^meLpyd#T zf{*@*v~6hZohRWJIHJv?4RdkoD>kn$2@dW0MwrREH~_tjTxm79nbjIGe-)~czOFCg z9Kxgy&(!dD5e3u$#CCu7Eio*F%dpr&_!njXOn>F1z{$AGWr7;ti|1CctyuGZdGd={ zZ^C#6gb1RI*?B|uE;P%jucCV2mnf;FVn%AcSR}V$Hg?bC^lfPPI`L&(^j?t3dri_L zNs{M*)&S--0VK>dMQ|ug_R5E;$YSBa(?9fGfGfq4L(J|(;W?%@hzmmCLOY})3qCCO z4uAAr&qB~_W9}pjtnm~J&xqQ+Q`G?Fcj)`-FX}66p*p2S3eG(T=<}x*QW!bY1Sqm1 zM}fRFwEyfa^4tJ;$=9@UI43+rgUx+Y?wF0rO<$YlF$bO98L%HCdPI3&M=7#qcl);% zBS-g`Ib_Np)7@Ul&pIKmtpw~JGzxs*(LyXhDh*7r@bS=sC}YOZ8#}9U7`z4NZF@e5 rd?0f(k!t9Ix*2d>Op+u?k`Lt{IRRN*^da&b00000NkvXXu0mjf9a7jC diff --git a/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/86'/1'/4'/1/12_0_0/00004.png b/tests/snapshots/nanosp/test_get_extended_pubkey_standard_display_m/86'/1'/4'/1/12_0_0/00004.png index 05fe79b7023b46de897d71559eb7a0424c2314d4..aac9bab3771e6d68ae5a5792a8c943f354ed4b57 100644 GIT binary patch delta 498 zcmVF1DKxwBp$^DPSUHXv;!$>SL$Uy7&z7j_W ztj)3#0ssI20Kjs-W){a7^RKVht1T%6@{2_Qqn=@6jQQ?wYKJV!Bn`uS&nyQ_C!siBSGFtu;KQoJqh>*$6n$D_iErc5(X^}7fI)C8cN#j~@$N)P=6C``p z(n8oJmk+A2bgN&w()E*;sU?ja2L}vn-&kVTCT>1iXAE6lv_BeUY8ZzSw77QH5XTUY z&0|?wf)Wj%S=?!FoF==b1+jIP1B(5bF(i|HyH!Orvi2%eEMK}U7JKPuz`Co_`XwlA3kA%FCplf13gA@CN{ZaON|>G6*U*i`{W-P+g`TRq@Q|&l<(F z;F7{gRqpstL%ZbBC*IfE<8_OTy4llM^^^=K&N7Q1E?sPk)!uAtr&`8_3NXfAwf!!Hezvapr zI_BLKZjSq&pE1=FZan&<91x0!+!*`5TmK0Mgrj`$Ku)Ye&!J;vd~hq67XSbN00000 o0000000000000000N^%$0iXMwI}gVQy8r+H07*qoM6N<$g75X@dH?_b delta 494 zcmVF1DKvB}^O}PJ&e3vdVWf%cMHZqX-zg6pC zOe7#g2>}2A0GRGIc>i%6`M)tny`^Z7U#vDT_H)f~9QmW)S|hBsNj+TlGjem{5{?+7 zOFu>;py}yiN`?P-*J@L?KjnAi<`yw)^021ima!I%m04+NUw?h|Y=Q@aYvHp3?2I8u z@oFs#5t_VxDE5}tJP=p9Nh;g47LA=x0xpa|xy9a_c>gIt7nIvenGa=~y3A(_nz?r? z#4yAs=bmP7L5Y$xOFHcbr;$_Bgo$-y0;)$erBL-Mh*&v3OAV8Q^#( z{!U6hMm{hcJAYZW1uf?_ZJGW}E^{0JzSw9r^bVFPQ1!6bt;L4ol&RMz9;#bw6xD)L z9S(No?v`q(E}wnk%bH$Zx5TKsdX&4KvI44w%<3PfF6zx%-)vi>nr6WY2!MR)-K00000 k00000000000D#;40i&X#@iA6hyZ`_I07*qoM6N<$g6+%YumAu6 diff --git a/tests/snapshots/nanosp/test_get_wallet_address_multisig_legacy_v1_ui_0_0/00001.png b/tests/snapshots/nanosp/test_get_wallet_address_multisig_legacy_v1_ui_0_0/00001.png index 87b4dfa0fcd79dd1870bdc60c0d92e4f4b667964..cc2d012b6709decb341536a534fae2f5468252e5 100644 GIT binary patch delta 429 zcmV;e0aE_a1JMJJE`N4}APhiJ+tZz}|0S`Pet1gL1R^*Ab^7j?6A=(JI=F2B006+# z<(zZQSNGycJ_GA2L%(qSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_get_wallet_address_multisig_legacy_v1_ui_0_0/00002.png b/tests/snapshots/nanosp/test_get_wallet_address_multisig_legacy_v1_ui_0_0/00002.png index 877ce1d16400ee0bf175ca456993b030385ed78f..5c60da26e6d173a9db5ea219d5b126d25e64a837 100644 GIT binary patch delta 707 zcmV;!0zCcR1=|IXB!8kwL_t(|ob8)kcElhEg>6rFlKn5qz4Rfc9*c0rpG1?n-&5)! zA}Eeb8Ui7N5JCtcpGk}{#_0bD$Ulzn)dqy*%Gda`iJ#R5n5gkkcf)ZUXZvv+LdM^+ zip4uXI8^Kg;TpA3C`mG^qeb7c<$ku<0m50%wcn>9_qY|&JAYY!280U^)gvR+oWAz# zSs8#d^E?%tIlUD2tWzMfXZ{Hxd@URs=LGefw2o72MelzI6G8|fgphy4KSWC@Goqxb z)4JT2N-Sf*_4sVb1ynu$KP}^j5cY|Wz!=tq`*eb;5w^kdh|_WrBy5R)h{Uv;Fj#0) z)B>!Vly#}bLw`7X`OPSY$Z0FaorT|YnM`%y>cF^2;MCa^+HOBOmCv%I5&-`+L{UC9 zhW1?vh8Wb7f^E%9w5LBs7r!M{2ciI|omEFWQA;|5I#tTk)tQU%j}0AwV4s))Xx+jh zjWk&~NI9aqiudD~MfrB=Oi4i(S@qcT^?#T5BvFcj(P|+~=3(OQY zG-(iXMte?mPpbw|Cbi)_)l2DXct#A~%EPkI%cwY+F}Rdb_p0?ZTqf%-*o|Wq^;E;K zwV*muPTz9K9Mrl(`2e0h3a3zYrC2N7s<0n0^;*#RfG;4N%lmd&HS4(Ht6lP5Q%YFP?}kB^ikj pLI@#*5JCtcgb+dqA%u_tegW{vL^xql&es3{002ovPDHLkV1j6$Sl<8u delta 710 zcmV;%0y+KL1>OaaB!8tzL_t(|ob8)ga>F1DhH0la@%@kFyY#^mhSBmPmIUnl-;+x~ zXkm#IHzh&{A%qY@zLWDj&-09b1p42O-_;7F?8?XZw28mf3b>f@Fn7ao99R2s9HLLW zWfhBefN-eT4Z<~MqY#q&n2r`>b<5}3Vh0Fk1=oI`gwo?)M1McY`a2-K;Zi*cQqAdW z@1B(b$d;E!!F8tV&XIKr`s{iBq?CRZ&W+Cm^PcpsQ*TA@e+d&p2qAI2QAA`bYX;KeB+!9fj z&yA^lV|wxjh2%(kMv3YiE+Vi>idon}({814~+r*gAX=wVcx%ox0t3GOw^WVlk+U9cO+D`}XD zVQoFFO!KE?{w}6;{Q#aL0;f=QrC2N7qOczTp<2-OfOC*wEkP%G)tpGkFO?B3dPrP< zuLIbi!GENzzZ4+`Pbo0y!YA%rb_40O&bM{pOxPkmH8F>jqsB{EJ@1BAYlPWfA9N1xpxivn?Lm`O~%2>Z}I;D-^|L_(=q1PzI*YI sO7EMM)|*@%@j)U9xbBBAO7wHqicWk?N)y zWB~%cNlE|!00000ypx=B&e{Kyk$*eBXB&`;D?i4kUHr^8Kt=2iaW)*sai$-~LGt)h zW-)mN5Qmc4KwKjxl1fS*(b1$VPkEjtW&m-PbL_`zs6DRr=zo*UUjxz&i|SF4T27z4 z_RQ>n^5k_WIAc1`>=~y!&dgXl7EYL;sJZyYX*kj;uUEkmpDDOBHHXG8N~c{9y_>+e~Hba<+ky4C3fpZ z@iY>G>Tx7W1?wXU7$piBVW*VUDm_o^-8AO)c=)YKsS&Ra`SL2nr6C$HGlk|alIJlj8x)#g<^Nt%(&JtvEY4isU3oH>#Y#MuX)APv8%jK;wm4)Tx@R= z2-mmVj=r!DVk;0qY=U1Ewe#OZqXV)c7n1-oVs1b&=1XpK5e^io&5M@4a_lZ^EC2ui0000h@(cg6 VOjnpaTWA0P002ovPDHLkV1ltmUI73A delta 734 zcmV<40wMkT1@;AyB!9h0L_t(|ob8)Ya_t}phP|EcB>P{Id+CESju!zDP1NN79y&cK zA_0ZSNkaet00000;G4u4V~qAcDe}khv)X`=UHKZHcJaH~01-AG>~6TOD_y^?i^$lo ztYYyFAPyzFfw+dfNR(t5*3o2aedT$!*a5^@#r87!^gd0e4jS9oaX*-sjX590s{FfT)rhqTF#zPKQl47L z9X6flwzAiib$|1YJz$S}O+oRSUy;=0Vz;L>MB3d%fR)!}^yJ3=BsQ~_>&BN#^x2i+ zVI&2W>xgX?><`<($XQ59J9(_s4zaUEH?)`Jom(@BK6~?u9p?^c-aPr1N|7nI(R81d zI`7awjwb*lnc7PYDNy<>gU>S~)S;4$>8-IFu7J;RR)3j%Cy2p%5QCM#`zwL>S7P

?NXs-v)3V@{3VyH0yy*lRxplN4DJcwD2 zvaC&YUr1?EHkH&mr3Q}0w(=vP-M z?~8Jbu!!}l9cPPw(3rwt%38(B*V7+nBzb-)hgSdqzQkcQpzB!>Oy-&1z{8yV7%KI} zus?2r?Z4N*pS4j=+5u&2{xxg-ymv!iF1DMQNuy@&1>@Ui#q~hU&#N21Dw5z7iq} zAwUAfDG@>lA%qa}PIAsUXZ)u?{^R&wZ9pon{5L+m#LsF2T+I0}cf)ZUXZvv+LI!VH z#o`?x94dB$aE;k0loT1$(c)R%@;qDY0O2ff?e}S@J?_oulYgww0ck=~Jt|Vm>1%V( z$_XeVuS3BZ)3q?NP6L@e<4;QIYhmAUOfd7LmrlJEy?+uWgb+dqc_+h;q2f9dod3j; zQA-Ao>%O$wrp~i=r0X1|rexX>+~%~5H_VBEMdP^m12zU~%}1IBH|;dL0L_Rkac{!8 zqW*eG`=n|2)PEuiZMUL#RE+aBb-jfLZZ31PUwV9?CHGZp722gxfyvXjE zROG>Z)2!bK8L-|rasp-q95bB;!hsh+y!@bY?SZV zAD5W;hfJBI@--<3b=2iewORlyUth}G&4a0Fk5Dx%PJirnoB&yFwlH9ef5cwJfFNmJ zh4!bu$}DFSGhPb4zY=rYqVPvB0yUNT*A6eQIN2P4Ia0e$>1b#*O!v9dr{$-kS1$YSyj97(|`5 zOsZ*sr+>#Z9v_`hTR!8BIQ^vv{JLL1(%qfz@oM$4$m6w&2k4xDc>~a^ejpnj0k?QN z8X;c(AkBF7Jhwv7`9X{dFGF7K%R6f#J?eNRP7t-8+Psd;{9&wJjQ7*hO#@gBT?{9H r5JCtcgb+dqA%qY@2qAZL#03Kfq4015yANkvXXu0mjfr0_eu delta 654 zcmV;90&)GR1*Qd%B!6v5L_t(|ob8%Xa>O7AhHa-e$^DPyUHXt2#{%LXqrq+d?`hX1 zh^U}!QX+&9LI@$`o#dQz&iGG`{KxSfZ9pon{5L+m#80#VP0aZ)cf)ZUXZvv+LI!V% zB6tS~hl<@GTw^v0B}K+`w0KsxJkJ(8KsXCr`(qkvkGE#@Nq^#VKw6MgkBZcDdTj2A zoPaX&Iux8ST?-@Y)REaU{-l(?0{ix3f|(~<>9na4}|ZKJL!nFctwIW5x~<66MFv0wiI8y&UgBfhm=BTfCF4Za!PO*mK7 zUoUmAXy#jLyMJqKx1x8a7}wg=^)8;czs&u9>G3I+Owj|*^yF&j%`3hcL-AQ@1$XoD zB8<3O$MmiYSnr!W0V@KInW7zG#}Npv{Hzs43IHLGjXJViq*dLcz z`-e=Kr1CW>2Mv_wO|@EJEM#d!N6x|2G)AbJ86Ll+N;A;@^N}M2SJ+*lQnfb$rU5xkB(oF+c4Go49KnNj( o5JCtcgb+dqA%qY@2wBK4RHLOo!0z%G00000Ne4wvM6N<$f(_0*F#rGn diff --git a/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_0/00001.png b/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_0/00001.png index 8c84865fd6dc5fb2ef9c893eace3c2b6dc414c15..36414494d2259bc9b27c05a99417c248cc103f66 100644 GIT binary patch delta 418 zcmV;T0bTyP1H1!}B!7cRL_t(|obB0dl7k=&fMKSyH{t$A;x7H+l+6T4u^Ya+@AIpT zNDveiLjV8(08W=uN-3>w#YrBHb>*&~JO)RP`p<+MvUg&PcI5h-BQeJO;|k`8+$zh< zysB_DwJKTeVl-H$`;6Napw7XvUoLi}tf!ht9(MknYcmR0^M9(6b%7 M07*qoM6N<$f&?AL`Tzg` delta 417 zcmV;S0bc&R1G@u|B!7ZQL_t(|obB0dl7k=&fMKSyH{t$A;x7H+l+6T8p&P!s@AIog zBoP!9LjV8(08W=uN-3?*;v^5pwsO}`9)qJt{bxc9**h^tyX5+tOJa=q$5oh1J=9mGP(Dmx;+Z=iTrhN># z7Ost3<=wv3o2uH>*m73_F5YzSRu9OTot1CS6M8^}c*qUkH^Xj7UUt9sJomFCl$#tw zxHQ!muAvBH+;%l%Fu|KnW(F1DK;2Gm;`<+oyY#~|D$x!Ij1#?&j%^kR z2?SQ$<4BSuNs=Tcg!xzkg`wXf3k+)5=mm{srxM z*ov_N5UhT+^G%&#oOF>&GZ#H%qoPL~Qqmtn72R|^N(Qe0XU)F3BTd7mX)DocU)Fye zk=b^@6(#DyNGsPr;Hew3DLQb!8K*4-4KiqVHV!C#Dn;ym)9RRzY2zdA*tbe#BJ=s!4PyN_RG2R32Wzq|TeuxT`?&)D^2-*tg>X|L&>l`rkXcXH# zNs{Da3D2%HwOuC2%RvX z08K9GL5bFv9-5uZ6VyTE3NZ2fLIgEuE3;UT#JWA;N`Iv_WlYz+$Sf1Y66}D>#PBN} zo$|M2gCV27;j1YQLG!dUQ((wp9zXTDbD1EDVcy#V;x~kTB>GhsY`8*OVShZ>3N|v| zKli^4#^C9LWr(IuA1uHya{6E@_n5a^Ds4#f88x&>YVPT|Pv=&arXpgYX9;*hFWCA! z5bOXY^?%3~)s})HHaV);T52U}h%RW6`Kg^Jp?e!j>d_eiq#l$6s#H_TVtPWBnZ9KQ z(#q~X$V9~rx)#s(53^fyg;DJ8fEh+XpY^d9%ZT5E!DQ?QjZ%@>p&6I+0R0b&r%Ldx z%|}m@N=!G+U3b;t8)+9&hPE#rEuAA_&A}e|2Y*?%u!ceqQf_eoT_A4HSBEJ)V=X61 zk|ZPOvEGxUlukbES;(3EFcq7}ld_@oOj6#np46uMpJ7%w0PLcFl!=-&r9aJoh&|Z50ilN~?`nbFfGL#fn7{{4YxNZFqRi^k*cGU&~37BuO&J YAE{~DsgXNFG5`Po07*qoM6N<$f?p$?RR910 delta 842 zcmV-Q1GW6+2H^&fB!4JLL_t(|ob8)kZtNfog}GIClKn4h zfQ^Acwbv8Y9(EmVJ_!fH^Q4OcS>Y#iW?Rm ze(+-wdf?3ya?aeuFxPdtL?3*tZ54~$sHIcCqaMm;EIlXX%YR30it)zDS`^#og|&8y z4|p|OZVu2`0R+*-diQvqlbJZkO}7H4{^h?oWdbi2%b zV;}1B;<=Wi9e?sf$1LXTPFnn_Z{lO?dH5bryPAD&+StO<6m$?SGxzN2pXRK9NvkRd zf*|O?U0@mbLO#`skvIjtjDr?bsAU;`%_U4AYI22D(_HbCF?TuN6iMCc{xtc{~`GlB;PuG z{4@!2dNbU0Qv+k8?INIS`(p9Z*b^}v;*tL$D}NW(cnTuUEl!{d%x(MC!JjkMau5VT z@C2OeEh43M@)6HMM)9NR*i?>DL;0B`f2y85rbnD%rVl`g3w|k+ROymGoBs`&;37C% z{=|T<#QZvs%AdSEuii{qxVl)zg}uZ$ue^~rmOlx54Zt_ZpM<>zAhpJzq>ddX?-|sm z#zQ&@0C5pqU_hQ|XP77!L8szt}NH+>W8db@%id@~0=qujL>Jf*^R#AEVFY Uy31^j=Kufz07*qoM6N<$f_i_Z7XSbN diff --git a/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_0/00003.png b/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_0/00003.png index 1c32a0ec6d59b92f9ffb7a6c0f2338e9f6ad24c5..658b8fe6ddeb94a6ee6094103e7a9d3ab87c1763 100644 GIT binary patch delta 870 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 Hu0mjfv`oQY delta 931 zcmV;U16=&O2e}83B!7TOL_t(|ob6g$lH?!^W2W{dx&M*4%Y1Y##UNYAge2WH)>n68 zYz3Q_l2Q_hL?V$$Boc|+@x^b~T1zR%akSsV-`8)Yp=Y@TSA?sz4iAoQTddxuXELSn z&2J-vAuw+)qSlHbmT?@%mfjy6dR_6l-rIP7O#C}Z6uCz2+kan7s##VA#-iyTjXgh& zLo{t$ie@qb2AC9ifedJmii6avTyNAz!wn=!r<iIe?q&QZiCxiwuUL_Q0x21p4YkKK<= z-BtaM;iB2Z+kfGi#FTJ4$wpvU1H8$wz{;VJd|&L{o`&3R39UG}bqe|*>?+$2F8^}P z2)JleB@&6mp8y`p_$E)BaM6i*`qTL+WVTrHw$UB1>KcD2Y;>F2$u-0ensJ||L(y^} z0ZNmJ6fvBYq72Lz35sW;krg-wij+hV0xh}7eDXNW5`R$PjfAP(Vs{UWdy1Zol4ybpMD=yTE9taTD&0_yKqRKpa8Yk;{hP8Z?9Mtmu#tP}dKVQqhb&6^V(4Q6+- zaND-434b4MCui^92BWL9_isk#;7Q~x^du&ooH@7@*uB!Xp~d=|Y_JJ!4ZYnMafN4n zQ=-B1k$#1TixS&#k_d^EA=Q)XmkW0};RQdU!b%*9b4lzZtfZ7z7Mh8Nul}!h7~BF; zHw_V69169A7n>B6Sbca=G$S?&CG+V>6fe*Mv40+t7#Aur&v?U}xD}xRv~5}kT=HEI zenWVF?_I(Vb&I_kJ*EH^Vn-wS`k9bRz7^C`P=(<8)5xB@{ zS%2}!OBoc||@dNXP@_B;9%0U1C002ovPDHLk FV1me2w>$s< diff --git a/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_0/00005.png b/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_0/00005.png index 621f3009e1395f745026eb02278160fe238c21d3..5916ffb9cbd596c1d7dd6ef67f9770d6234f2169 100644 GIT binary patch delta 839 zcmV-N1GxO!2HpmcB!4AIL_t(|ob8%h667EVMKe>glk9&q?R&Ns=T$>l|{w9Avzda4Lnp0S$u9QOLh{9`O9ik7_9&F5C z@Qe&Swqux53Rf}Aec!W2-z;gBR@GcP?%lsp3kB((o|F3ZFMpp@(V;FDi=up9S(6it zo4D(s2q1{|wbO1|Q~SxoQ}bM~2z03%yI<~bHTk#uRG4sQ3{GDIzk!%wF z9B<$XemTd_#^SG1U%R2cM)*71Of3XJ{?%3kpBHmJQVm?OLoaUr1r4BI4)6q{NiwQTJv# zT3mU|IS6K}oL^Qu<(Q%-e;p0-Wu8=;Uj_K)`P|I2NGJk=gQcyW&Q{v1o4A6u9Uzsl zCBqwp<>#s+4sJUesYU?zl=a3WNs=VVFJWgx&3~NVz}}qi3wv{lo?RfflQ$9Tm=#(% zV)v(IvCQP(HMGeKiuGvp5`ZsOrn6h-n7PIYF!Z=%`G+~UG)=&Zb> zQ$SQ)oj;5w<^}TG(3hFB4Xuxc3&-S-)d4rDq=IIi*b3`Pk|arzBuSEu_zxfsqKxEc Rqxt{<002ovPDHLkV1nD1pRxb| delta 835 zcmV-J1HAm+2HFOYB!3}EL_t(|ob8%RvfLmHMM)|<@&1>@UNU%96w&u0%9{pqU2FH#^;A&jBCkn z;~5!x+mtZ9cdjDLbzLc=@0QFOhhDDQ?b@G^g|Y&q=cNAl%YP?T^r^;TQIyXsYjTDS zfoV(e8!G|`qKWg&y9SM}@(9&D*H{OZ)Da_%K^I*i7FCFynGpcij5&_j$`~44OKfoM zR{}1_i2y!_;u~*CC2`455?*IEy~ki-3EE_HxWx%GWEzj$_XO8FFO`T29Df3gZjU$s z{bH^!?rS;P_J2+^3{i(0Y1Gly!^U17h@CGbcYC@dHcK@k=W|QYK_vR@sqWwIiGZ7; zswj%0NPw)-ePWcPXxSI?g&3p!#S^fb3wj)$j@1&huNwC^qPe;K*KTeXzJafbfD?K9 zNf^n+KayC@;_Vag_0T0KeEYKxayvN8o9#qaA%1WE2!GD-zQIJB`z}U4hHCi{T_X2W zha%X2dY6u)=HN-rUWHD_8RVLSTj9fNeH)61bN8&VeXZDv+~c=@`=fn22O2PMaBYEe z;lo$(NVvp83j8R+$eXSjup~~Pt{h*$Ax1Y@>A zm&6nOcz-K?V>6eCxPAttyDz(c9@j7(m-{OrK81_ z$DM=CR2BGHH7LgwmHc(Ikt{>cv^#ogKuWsTB+IE0cwk-*7 z5NeG&bNlEX+>ls$nE4!#5!(;S&rEK zv_zJh|7)Rr-lkYYBa)ud&LW60VE0{9b5aq;QAH~Z2yePW1yYZ5wr5tNjkcaCFID=mKd}RRJ7%<>UwN?~G zQ4~c{6u0vSzwW)a){f&iuf^@>nyKiOOyMGRy?4=eA^Frb78orF&G?I7YxP2L)C7v& zyH>HxaU5CRXC!}~96y9Y1poGolscG}i}L5K?o@MFH8mGa`G2~wCue!yqzsy11_(_1 z#?B9II@_rysW)=PLo+He>V%Pe2pu0zIh`>wc?OUr*T#-n3&hz4XW_S_K(B{FQG&Pw zK2gHcJvAOjnY@X)=mqmx=0eaWn|=pt;H)}xy_xNplwm}50BH6(_DSo<@_JwE1sPL< zX&9q!%FfdU9e)E%JIzfhP!ya4p5>wg1l~j?YG)+e8iHO0IeV_w@^u}MxHY=EdQlX` z)x^6XeluY1Es_R9+@yss~C% zm`N+XtC^e^!)&%ySHu%;)2eH?I-&#dt$uC}D{-V0$A462NNPEzWMB_gHznL`g(<`& zAsZ^d!Pm?}H^*P*?N}XL0Q15oEC|=FAni%+0DkH7Fn>sy&9*Y~Uqa?dc;EY9h}?z> zCu*O9ML3**%nr}nm6{J3Ic6~+irj{pe!xPsLnJA4yui3lF7Mxl;p+1K%~T&eNkyS2 z37lMgaDOSq__77|)$Yd0L#Rrl&72%yJurjiiIr^Ayr$YJOE2biYK7o>Fu|+lBL-U%!IlpZ^6u3>pW5V;b{q8mPJKfi(KCMy~&r1q@pN_q9}?S$dlew#%fkw|3N=7A8Jv! zq$kj{$}0nOfxHY16rJsi%!Gh{egNyg1q@oIH0;nUTJq|F+G zq+uzERWhtGOn1Pt-Dczo9kJ;thBXyoASHSDUy}I8uN%DoICG1z&I0z;@50FiN~`ls z8nc@_8A|2{(Z)3=eOrO-*xmN#@g7SUaw0;|H^hpfD2k#eei#1%{IS)Qoh-WK00000 LNkvXXu0mjf@Akh0 delta 937 zcmV;a16KUV2gnDIEq`6I%C76pTwSu#sZ@mj17PBYiYrx+f~5O zdzUJfIgTU6`;6Gvlj8?hh~(dfk%}6o8WkCJlaavb>Z|B9B`r*z0c6Rw;iJ|9p_bQz$G&u>)kCf* ziQfUQ8EUByjmJ@D$jU_In)xiT5VXmr-@!5%Rp+h~j4{zFDpUu6W}jo9Y{OVy-PcO2 zO`d8PqmDQ7G=D$_0M$r!lS(RmM{>8PA+h_aNeQ=xpbsKtZ`aI#i)K|(6vZdv zWJ6nIJEf**Kt9!~#b|W5ePl9Ht%zFzgf!UF6*hAQ?$+MQvtre<47gY}m6yqwYJpM_ zYSN1DYB%RaGPYqYVTmW)rd8MOHKz{5xAM6*62OR&%-Q*;y85>9PgDNHywY;MRaxOm-sS^dHaYDtcEDEk@ zrFWvnkjW_giVq}yD#AKbU}a=2b@VacPPy`}S4>3)c>*QRVvB05hw3$%Sp!2%O*fKC z8I7TfETt;>+0ZLU46ICW$ST7S?tmRH;JQ=DzJF*PBR{5VViZpmvut~#8Gw_3zZItg z#`RG3h_zs5t#y_t`S2kAXCa#-Ymv)4zc=}kkyI2#Q4~dy19{R5Wvrs=`VaDn`cR6( zB`txfRaP0G3l#QwhYpZ$8Ff=(*R#L?pw}%)`oaG;w8g)zlx0S1tdC05PcAzt6L~wH z*MDSlu$&c3_~c(G5xAB<9BavdGd^*Lwi-z+?e1^}o*~20N-{25#j4f0gijYAk~VD& zl7^)uR>`o&5bl6wyVc0!I%3mP3~MUfKuYrP-&FCBUpILFabk)zj{@oHMy00000 LNkvXXu0mjf4`R&x diff --git a/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_0/00007.png b/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_0/00007.png index 36f9c90a03f5bf39d0b9935253c251e72378e9b7..ea568ba344f2e0a893be0be0a179cc6da1c34587 100644 GIT binary patch delta 966 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 delta 443 zcmV;s0Yv`a1K$IXE`PFvAPj(EPUq}|{V$2V^uZa12?3&jg8jcITPcJ~km?)&003~i zzxwSEf^*J$AFsv7Et(K zie1f-t9w+X&dROkbHW(UgxLHdi{~sexIV zvj-_+s83kw5P$Jty7wA;JUvzIkftq_+`0vAWYn_Vc=@|I889iU006Uy6JdTpG+r!d zvs2LV;$gLavpoj93!3LOqr4^KK2yKD{w}n12B?-D%4;^8fX>%v3)<`<{C-QVtdJ1j zq-E?Ek84D-PM~&sO@PaS`J^}Yes#AA{ZGtNYvdO&2Q*JA4mERdgBL!BH^T4&00000 l00000000000002fd;$8MhECL#lFtAD002ovPDHLkV1lt|(*pni diff --git a/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_1/00000.png b/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_1/00000.png index e7a9ab02a0ad59792a85b4ae9be4693d63098ebd..3a3a1b402e1af2dfe28d3e6b487306407f7a3181 100644 GIT binary patch delta 997 zcmVP{IdpQ@G&mjV@fF`Cb&(#-$ zh~O{jw3H-Ck|arzBzc@Kqg<`ElyV$L``sSHG(B7!eKpxifLbdzMl2ES?5bn_g{@rT z{o_L+PN%O5i__h7&1tQlwu$zGTAc5gePFb90$jdGBk26?8h<-o>%7Ho*3uH=3={ph zc0l-M0GN!lpRL^D{h660E{s^1(##eWiUOiqUdv+7Nn{D?)(UEbmwE5w65d=ldc0=y zK{L5j`U0T&>mUFzk%yP~6Kx579`_8O(Z-Ip%h-kS+U*LwWqHvm25M=zH{r&)+_%m1 zEVLLm+;4%-u73)Z-P5o!Brc#S#*6SH!{(+zHkm4Ym>9mfygn z<*w?t%z#x_H&oIMm(H@)0z zm3`I#9pFvSN6o*Y&Lw%)Rfw*m1XB^By90W#aWVNyQsVXzFeBsb1ttDPjN?sj&DdS8 z+hB=~fO#f+5l_ZVGHG{VDdjB-&V0MU0EpXZHwKUE7su{VQzBMx`t8|PZku;)G3vp+ zpfbb#K!2{5!~h2e`Z(AF)?6t57}#mULv!*38H1gq_ji)s-wF5r$}eK#8H=Ayhvk;@ zqETVsGOV?z9i2sE_8?9!EsY9RbSBa?B<%;z=JKY+6n}uG3a~8~RM<$NzOYAHQ_GVISfPEe zTOwyvRrUs8xMPRa#`JXC?4%7wRXYQ~nOuCaWO=G0(#w^iuAMpSHA6^+f*d|ukhSy>rL%uzrYXIyGS~^qwR?hd{ zZY$#r@g9O#Vn@WlYjwR_D>mb|G2hR>;;H+X^x(z--1WaAehPQrFp?xml0@Y{QM9y- T_0RXT00000NkvXXu0mjfh>ZE7 delta 996 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 RA^QLT002ovPDHLkV1fjm_bvbc diff --git a/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_1/00002.png b/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_1/00002.png index e82fc9df1a36eff8cff84d77347bdd9216132c23..1ad82f78e2402c9e8270db5e6e0c3b5b45aaba5f 100644 GIT binary patch delta 690 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 W1+nOSo8zef0000 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 JPDHLkV1fW%5KRC8 delta 568 zcmV-80>}N-1knVLB!3u5L_t(|ob8!WlEWYfK;50aN$!87++{y9bu1u)X>8MZ?<*S# zA_`Kr6aWAK0D$HE_{00Ymr}NEtIze%IjRy-`zDqrGou%zRej%$PN-x6Q)f-o@TizRddo0AJ6GtDu%)o5ie3hfOE*L#HF8C4)7IxX<2O zlFbnBujw~_Q^C>f3%9MRA!`bXbUS*Q{h9cOsb3XYlYfTKH>T%qea!V&T3BmvhD=rF zhwU3Ndi!mNIH)(8+N9u&=G6WM%!O=?)p&m~?7=%B z3%!$plQG$YOToPW0000000000000000000000000m+=o|?r80VZ=O>C0000M!GHIqxBAE zIO2E8nl0Wxo@j&9-C(;C$X$Z2alzo|>nOYh&qYR^_@mq5&VSZ61b+;BgJ|JQIj_$- zqR(QKkEw%`(FAz3*`2vW`?N8Ic?OWA8=t4QE8btrq&~_7EYd~t2^(<|7*my5(i3zX z71?k?%76x5=0Z89v+T-3r<=#!t?R<6(9>EGG7o@BQlo6z&Bcq-+1R7^9K&{TpUXnp zgmD>-p!bP7n}4+~8a){ondC?}!ZN`}q zm7&}Qb`Howd1iO_BRy|k5VqTJ>r*Tj>7R^?Pc$9AEdzEPl?#PJp>P{^RzWA+x-B9> z-FB3K=WzFkkB32>m26%eNovrj(CkE$InbDRotUg5CK)i+Snm4EYo4g5((bN5DY~00 zI=;Rf<$oNi=}fd^|F&gQ{CO!J#D z*TbW-5%UZ%jbak?;2SPsIvjlw4bi=Z3pY{)*E3tmGX&#;7U*&_HfvDi(jb!rA@2!T}FZH6`|PU z%8W|bOFYMT{7LnXhLek|VW{i6aFrBj7QcM9Xv#-&kbt zreRDZ7V}1wgBK={<^n&bU%A2AbmS9)$bToDPt3`2%`v)B!B8jL_t(|ob6j%lH)K4)Naj9eE%c)F8kq%N<%}d^@#IW`eVwG z5g-tHbTXwR5{X12kw_#Gx8o0geV%72mGnZKJHV#3m020l1NVUBi{kbx#y-dQ4HuNnTkx?G$i3D7=*emkk zf?5FuqRjOYbZ6O?J*Mj$54Ua$r$Q}jMTwLEQ>VsWR}Ar_ayHKBl6y@LLEVILC5_OP ziI(!#kdf3ey??kZu8PwbSb{FpJ+nQKbp2@e+emHu5Q(*R6&b}ha<(BpW3T8K%6;hE z14f}w{|cUx^(nT3U3=1fqnJLYzbzJrb89rdFZzi@BJthWdQEHZl`r{3zJ8ibGloVn!-nef zg-ag2-z!F{CL*Qyym5!q(fLNKK9jd1lw&9tGuuWhhWTe4YRhleqvr^C(%PfEH@_(%W@8#}AUsw1NjBX?fCds%(tH%S2da5?F z)Lb~5e`(%mXp5?f5BP0pd!*Sy8k=mn`HKR*JqK(F!W{`)IBBYDjvA+dA=cH_lyv00000Ne4wv IM6N<$f^YKmT>t<8 diff --git a/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_3/00001.png b/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_3/00001.png index 1ee8b13fba48cdd80652197eb77890dc8bd90ef5..34e9322bb2dfa17044c8306f3289a868cbbf384c 100644 GIT binary patch delta 1059 zcmV+;1l;?u2)GE4B!B-&L_t(|ob6m&vfMfdR8rZ=?0-q#OFmptF+igh()idD`pefw zs3ky;K9k#8p-?Ck3WY+Ua5;Vj-;U#Gt-W5a{@njFjqb;KOLQR_?y|HEdn?4SJC~!A zt%81kPqEoD`>%g!Vn}YVT@S(60KLZqVTR%P-W{52-|>g%;eTdp6OmV$GE9^6`AiT# zi>-f~m^KsD^hwTc+FGDbxrFE#R{)xQ8EQF5X7+QH)LW^5p}vB8a#I-jnIhS1RI)`h z8d(9&%yQsyh+s%7;gKF1K`%Gm!&>jN6fgZ9;{d24RXq*OT##A00zQh8c|2=-8J?gv zVY`eX@HWU;t$%g1V@@w_QvqA=v4dTLPV@~^P7T9A?zhOZd{7Ih^%L|vOAl?rinC>C zlLH+?0~*miU>3}n(E$!wF6P%Fws5#^An8N;ov}Wm*u%C8*mYGd6bgmHU4S-_Lx8d5 z8xA+U*ueIsJ{|9f-J+MS2Yv_>2pEu-=wbLZ;6uj14SzF=H#wCI!(m({#uqX7c;g;* z(gz_|q(k>3)M>73*Ohg0aKg?Zbk_EsE~q)B1(77I<%<02YRiG8q9<>#WbbICQ?sue z4%^O25wmb-fh-ia{AFCPxo`v>rE^Q-vjK2n^>LJ~uBCOjWg-H$CkNv;@t6n1+3zlhnhpuMKs z_tFFUAq6^Z^9ez{kfz=w?+4Bj+OFeYehb!dmID+sWiw~GVagHNpQbS!(CFy8!}2y z<+cF@c?894}nUCP-sI8P~#f-)ecvzReyr;Y5?MDP?gT`BWq&nk{K(qyd|TL4w);g z24GzyvU!9ITzLxlY(G~(Q}XJDC5VZE(rV&`+iI4xJE8kmOfo7L3pjhkxM2(y*UDUV zUx4*!W&U3gv8+EU_I6`t=LjObMbnO9sa}n{CEym2gSyMu@4{mTrtVqaH1J2F0vu2% d6bgmS_zU#fBDE}Oui*dy002ovPDHLkV1iSf{(Jxc delta 1051 zcmV+$1myd;2(So{B!BlwL_t(|ob6muvfCgGq@CU*_dk;F(vQqz6iF)G%^oJC38Z_INz{b^m7$-HCOT@Gt4@va}6*E5xunm!p%d z;(q^55n7-9#}Aqqk{fB)L+~^}?=eA`Vfei74$ZZf_{URm6Mwde;HzY@_A*VL*Utpu zv)DSfiD@%YO`jy}rmY2fluHPSaRmgkDTmbW4`)ADM!l5^7+Mg5dU8`3`I#cwYgDpD zG@hU;pqW{YodyVov=SagX~-=%-NQofQ#4%qJH`P}b*efWnpu!pxdJ|li?r84y@c&b ziZHZ6OS$YwS%30KFK$x-TklbVU4owI?@YNN8Iq9iTjW+=AT!x7W5aMmVOE?iL)#E- zLt`4zIbari`gg=3Sv=S|4>&3>U!DExMyW&IFfEcu4R7fEbj z`%;gNSHy17P1gfIgb4%;NK14vd>Zf}W8j7v#haW;hJWEOt`g&en0u&kH@5uoN5R$U z+;dIPX|8M6m34A(+Rh=Q*7lk%s5zwtktD3;iUR7&%Ymh$cZfqQ**hBP)a)yV!?tr$ z#4OxdAPdDUe;LD-cdZvb3ai5z9CYiS*BnTUWbiUC?}+DzFc1F)Wexh!_q zrMU3d%YTLOkXW*w&;hWG?TUdEM`YPXZ&5T^Zk1Te*_S^G9^;4q{Xn^;UPwDPu%`g+ zDX$Dj@)qnB?ihgP^1KUmi}+A_S$tItZila0g>HwzBv%aH3Ol|2Z^CvjXpiakzVv`T zq(FPJuAWC&|B=sr5DsIY7%?S?eWpg zfPY8wB)sw5pG!J)T6CZ0SSfF|R^&yx$3Xy)N`s6g<9@B21n1i{+$DuPA*1wEKJ7qU z{`O!W6WA%n@xrxif;0w{aV=c;t(K<@>?736I+*l5Lk*1+ffUO&7Rvi}dWnLD--d42 z6n_IG6fTR|vP*Q)RmhF=u(JYICQ$}B5p1<7%BiF|42%2S1b!E`FJE(iBUUJU47U?p z3xz^q4~|#J`|dS=({+nDAh$~UQx17SFfb#LkoKrg69c&e-61I=HQVLj9u%h3staPn zLClRuU}>Ma3R=6;`NgubQdN%aY5?MDP=D(NLy@eBsY7P0$dYD^I69V-x#pND&8Y8+3P7PyC=~YNKNLx= V9(l70_Xhv~002ovPDHLkV1lVx0>c0R diff --git a/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_3/00002.png b/tests/snapshots/nanosp/test_register_miniscript_long_policy_0_3/00002.png index f4ab6a9287d68719a252d0760fc5ace5964e5683..dce83e05e7d046b636e482436e78066191d2ca4b 100644 GIT binary patch delta 582 zcmV-M0=fO{1nvZoB!4wYL_t(|ob8!Wa>O7AKy9Zt$^DPCcj-r_3?o8NW0LK@_mvof z2q=b>0ssI20B|{9!L!%vRZ7{mO|Ip37?ES84Gf_*JgcXDv9f@bBf^_~L_(AAE^SV+ z{`N;vvuZlKDIs_oAR`VatR;9F?(JTmKlDt(p%o{6MPt6ea9p zQ`KI^QuNG-LVqd=3z9IkX)+qz^lgea9KZU+>^bDR$#4ei2v44`$Y71O)ds)0+=Kv|Wyi_$< zPgUvx&8o83aslx-{3Ly)h%P2~Pg{V>m!z7?h>+^Kl4fn)%r|GT&;bKBvTxZUYggIT z%0KLLak5?L0E>;j;J?a>(f12me7@f9LhXPXRk24*ecNo=az7NUr!#fg701v6^WIfT z^G=ih5+iqZH%|Mb98j7QynW6megwP)PxQg(@Wfr{b2u=FH9vn U!e&kOt^fc407*qoM6N<$f~5o=tpET3 delta 595 zcmV-Z0<8V+1ndNmB!4qWL_t(|ob8!ia)clZfN7^U@%~5JyY#_nCPPSwAZmBN?@8Gh zLw*3Wr2qf`003OhSMb~G^(v)o+a}j?JBBE+ss{9H^UjjA4_4E+dPI3sMl^VQA2Mj( z``aHy&8ivcriS3x0D0qp!CHf7;Xdxk#5VurO=%`(Zx9?ytbl36)JK8ks>7m=y}yOMfjiZqb)wwWZu zi`#J7&D85oYJU?JWY5$!+ciS(x1L&k;fd+@W@Iw9d10<>_BM7;Rd61uh`s}kl23mj z4#|9e&2Wkhmri8(oc>tmr*oY{-p~600B_Hkry$K_kEK%Lb$+U&t-fs@KZ2vMXLkNX z`z-S9z>J3ENcBC@{B`(qebEu)SUY+KFC^j@&E&h1*?(#qTylF^zF!vr>AJjBLs(B$ zS^~|+vNv)8@n`%b$667Gm|Q(=11jH=Y8oR-s_ROd^>uT81RvO%62P<`u zO}-`W>`ZQ)_D2PvG$(lboKO4+_!m4e2A{(dSE0|L<78s66x<5{000000000000000 h0000000026j9oe^R zP}g9(E`eQ=wv+8hPCI^%tr@}DepO^zMGm-TgiR*j0cwcpSbr-^#;>fB*5xbBW!4BM zZ@|sZ;-*_oS#(XzIfCS&sSZ{Z*;jI*(qLvi`DgwLlE<+s^ndJg@6jC?7qqj4$CKCQ_3+wQdi zK{$>#oUpB3sDIB*p*LV;=B4LYiE;R5pMge2J0>K_jmAseWowN%S>6Zzd>+*O$}+x0 zs)d*Q;Q{v&lxynWBLA9jahaF zs5O|6OJtYi^%N7yZl}+wHY2#0S4HNR$OgBxu*>2*Ks7OMYky1J!79=-KwXv$mv62s}HD=Y5f90gRKNn1KsDXkrS z5&50j*m3MedalZspLI}GRLUVW7tQ+X!mWBD=8fA7P|WK~|9`~lty20~%9lD@cdpuL zX2p@_)J2A7s%0}^u;jIbW1e*k;pGbx??`wC;F%?kooUV7@eVJ{(Z{40Cn^QqbaULz z9M!3_bI5$&I0nW!0G)1^dw=likLBz4+E$V=YcMZtq`3*)z5~_@dQSFVqFij6g0>R+ z93lWsGZPU2e1ECd`dxo#epMf8oqpQf14n&$1Xm)@C6rehz;*h8F+;00000000000000000{F3ey_Gi+qnHi00000 LNkvXXu0mjfCqLt+ delta 465 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 delta 538 zcmV+#0_FX@1iS>0Eq_6Bg&+(-ZKpT!{zu|2T`-@?BoF}+aQ=IXj;26D0#Ran8~^|S z003_%gb+elZN;1T9XM8U{p1+DI_iHDbV%=<=jlu0ZIYblnJ%I*N#t*3d#P77&Z<@| zZ5PL2sjiPz9ZxvEyVF$!VwSG@8>mt5>zOU8KP^7JoJ|cn2sGt*w=k`zxzN ztNTiG8D-(%0BoL%o3@(bp*1lk1<9nT602(2Cs|0zm{Cvuk#9jV9V=n@;7blO;hJ<* zzoMn;)_F;T0RR91U@uAqiOG7qEt&t8Ir1E^8y!xce+HZsfFO`Ud##%JZG0EYx@O6e z^i$ocE?L`#Fn^;Q9q~&P*_Jg!-7(|%1j$xRZE;jyv?_I&7l3*$BUJAK>)$)>d*TVP zT>wf&`BJkxD*8H(Wz&anHhs?=D)xHx%S1%)fSW4SY%hm$ULXBL-&)QrJ^ZEQa?e@Y zTDfp9wbls~os9RVk#RNNpA0cr30Y_*7fvPykMbJ#wtrS#)LW)~>3q%1cc9N%s$^Cg zYPU#iSBfa14nfL~H7CAwlBzj&eKj`u*cDy6@NW-xKn>Zy)7s5(qu4P3k;}3YndEU= zpQWY5*AgUt8vv)X`8nm+pg000000000000000 cz$*R$bQ3HhL|X!p!2kdN07*qoM6N<$f(sY-e*gdg diff --git a/tests/snapshots/nanosp/test_register_unusual_singlesig_accounts_Unusual_Native_Segwit_0_0/00002.png b/tests/snapshots/nanosp/test_register_unusual_singlesig_accounts_Unusual_Native_Segwit_0_0/00002.png index 2ca9ffae4a68aa4c1468f77d4bf0b475d9fc22e8..558f45a8f3c5097cea3f0b999fc0c772f2a18fb4 100644 GIT binary patch delta 496 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 Ef;uSf2mk;8 diff --git a/tests/snapshots/nanosp/test_register_unusual_singlesig_accounts_Unusual_Nested_Segwit_0_1/00000.png b/tests/snapshots/nanosp/test_register_unusual_singlesig_accounts_Unusual_Nested_Segwit_0_1/00000.png index cd47be1a7055dff53b47488973f06a8952d8def5..8ed992b5f16cd1083b3e224aa6875aeeb6ac0606 100644 GIT binary patch delta 1000 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 delta 405 zcmV;G0c!ru1J47HBmtI@B_w}#1Bwnh2LJ#7JY5JOgs?k{C;1qjD-QkQIe7G}|15|h zN5^|#FS-7VCEojZa23W9`CnOI##NQGp;gVaNhM(!ZjRXvfJ@E zo~=?j8&}m#o5+NFG8|%j2dEU&Tsuqte`S@74qvG+Rv8*kz~O80(5-)_+;mOYEJ1S7 zR12%BIajh#DH*FLzvWwyT#i*?_){-&Nr!uuqy8&eh92#gOc($F0GpL|AQs1U;x+MI zFN^0)z~Tg~V%@bHTG@0|$LVfmrH&i?o!qk#o6RAOm91m7Cpxdb2|8L>s?%&$X)>MI zXy$WPd=F@9?l(+#_56Q_f#qJ%oNNECIa1l}{{Hh%rMANU3Apsk!B^5t(CEhyHE_+g zm1RBq{jbunQ%^)G`$;le=*Azyjp2R6HMqTx#RRrzw#EtF%;a!FT5BBA(^t>Ic5h#W z_G%0=b8st$7XSbN000000000000000xXmx5l$<<`Xt$gI000R9NkvXXu0mjf206Yk diff --git a/tests/snapshots/nanosp/test_register_unusual_singlesig_accounts_Unusual_Taproot_0_0/00002.png b/tests/snapshots/nanosp/test_register_unusual_singlesig_accounts_Unusual_Taproot_0_0/00002.png index f0ce5be134b07045fad55549cdf66a0c92d1373c..55b6b899bba508e3c0b0330ed7f7a2b00814877e 100644 GIT binary patch delta 462 zcmV;<0WtpC1Ly;gB!90-L_t(|obB0Lc7z}dfZ?>KJ7NDzVlRF045c9;DiFu{zb8kL zs|0040001h<-SH`6k`;T5JEauKeywa8*3>i)pKfbyS_(dq`E#C+sGJWS;T1}1mE5l zk)M@?<$c%Fa+N;)EC*GMO1h-xqM3i0xR%e1c{6MVC}#b_i+@;nW`&@OF7~?_ zqZ)ZOE}84iz=0V&0F7p+XTP)ddHV9bwiaZ}9L$RK6t}>z?*Lzu*2(ru)DSlfLANq> z9by2gRt6#fz<(bVf8&4UrP}R{OSJ@_rPluPbK1OWc68^x?FuZjbT3FzTV3W$ciO-? z`byq23EcOh{h3c|c~V_EGy`@+mhU8Z+IK*{<+&ZJKN8d#cTXFDoZ5ym58QdK0f$`t zhv022ZeIRoxw{@Ta_CHK-hT9!D|U*z&%;$Nq?0y^*GD(GTH<|rUlvxzrPW5Ex9a^* zz!-RXk0|t1Z?g_R65R^`000000000000000002z$3-fi8fY={iiU0rr07*qoM6N<$ Ef_6gKz5oCK delta 448 zcmV;x0YCoe1KIoH><&i#FJhp9jBm+F7~@Q zM-}ocTuRr8hEZuBfI_pwvtQYOIKBB^n=+T;${E}&4z)Vld~nR)B7^8GE-V@6gj$7@4o>tnCTv~&{N%J9eyOb q7XSbN000000000000000=;jYa&y_?87W1e80000ElmLjnmzT=DgM~+f4gGEzO^tePFf<0WIIG8Gm$r4$U3Wx^7Xd+OdRO zVWuDVPKekF0E=<#XD?^Gzp|3dz=(xMy4j{eQ@~WKYccj*WI~XL6{8VR*1eBQbaP_% zM9tQdW-(O82Eg;zF#yC&9uDyrUI=}j@Cq158#|hp;e~PR4h=jLUc8ElS{~s|xO0X3 zzIk4SjB(Tb7JujzRYpl2&BbObel>Ms+i=js=ME3{9uS2Y5_4C?!VlaD_8tvhBfTwu z0*jW1s^78#c3qW=q9}@6arXcb$GuB`F3Ovmgm-w*xk>XbGKz^aXjEpgcc$5y`sQc- zbp@T(AT1elO;c57?u3`g^_Q$Qzledfn%S71N@CrZbAMbnfjf}91}9{MZC+2k&wRTQ zyaGC2EppK?^3k=(BNrU#Q8XBJ>ES7ilzY$0Uc%oCGKliS&obKM@l|b6d}J z_${~cY#V?O<^4`31c5_jN1X8Vfe&v`I+2-1^_eeDC%0od+^Srv{)XilT@E4jwvT=Ox;N zB!4M`6N2XeUyJMupT#rH*omiCJ5ijbwUt02_;qSPs1{I_9ss5Z_9E8c{~zNUN8%b1 zO4Q`q(l+Z7oG9ILy+Q*p%>^!+VyY!8cJufLIAg5~@1YH&iZPhE2~%%JNBz4u>S=8_ zGu)h>Piyh^khK`GZO;RAt6PR4rwv3)EnyQKgS~0g$xV1;OCvY~8pW&2Bs*6!xY1fB z^G$eM&St|RLC6F?p6OPpjm+suTP}PujfCI9U1#Udqmpqivwss_i(yrfHg{X`0*lgNq)=F~)ekUi0tyvBp#)Rnf0jOw>4zLpr0DsD85QK7Usn zU620jmqCI~zZ#;Su7;Vjte?KA{yViKKV=u40m}rC5p@2Y8h<;?v^2-2EG+?Nm>S2u z10p>GoM_Uf&hjw&Tc*(f;vxm6&#FRIKvgSiA^w~cmms!WP(M;^+(Oh6X^strtj}`L zEH0Jl4zNP@A~<4_o0s^L`!{xr$_$_#?zbeAksEKQjk)2MI3UZ5Rk2XZqOu83&gFjY zpJ!p{U%21m3V*4jT+P{L%f2o6<}Z5Ap~E3@56FTK|4Ar(!_u+$Xz(PpZTTHobo(t@ z{khR^nx^?4%u^6M1zMN>+Fq|7F|EUc%uT8n5h}*cpjny4)~Rk+>Z^atk1NQO2IvV* zG=-|v#0f4_YcE(UzKB^lHOrVBN^IV!V_cf>8&JCj7k^}!Z&pjKzj3=9e+EpfTHvHX zq_dt>Xq0b3FHV5zBhe7)b8_1>E5m)p|?N*Cy01 zZMgGF(SOA3ie2}?lXUc-q@({NGWu~g^u#)HS&!E;e`%c&t+(uzQ@rYcBQV_dmI(ue zR;C}36M|FMDWsZL<|$2|S=z#qEei#rWGNRUE$zK|I$6ezFBAChHmr*nEy;#r>32cW zxk+{e(U?wEbK#Qz4$&nApTkv7?Q(TY$m||-%zrYpEf*vQ%Y+ur_2Hr{&D0#;cW@ud z-pU9__RN51GrA0LHmK)<`>D(TtA({oHVcIF5eykJ?r?{%?j&yps9W4i`{5?O^K2Y< zVaAkg7_?kfC}r4zN=@rJTy!>hM?Uv@`OJe%GwBX!nx<*;I0p}zu(J|vYHH6BIDYX> zXMbyf4Z%}*svDcJRLelK)3kKdQiy!zl;gD=Rpkxk6&cipYL4hVCBi{7Yeky_I?{Pl*`Ic_xK&CIYkJCVvw(yv;b(B++4=qGWZc8---K8As;pD-q!GO@DHq*Wb9~@ZNckWccP5 zaD{1)Hu^+t1!$u`yTI%V$mp-EB-=wp;hAB!s4!#(c@bZ`nGi%`#cV;8_0hLmcz48m z5VPGiy%H^B6QGUPHDQQ}+#KRxXd#qy+Pv@zn5WtvXj}#twqti_;(7eBh0`6`Y&eE$ z=P=TuX*0UxI)C{q+9urI+l=Tj#zY$XinwnXUmuw#bONFvxq^1EGlXx*3AS`}o3)k& zj|BHEtXqz2II;qErOHK76vdN}&4d)2=AG7+)N~SU+V+K18n_1gYafSq=)SWiaqMD`FeZ_LfQVTRig9t%O-zU?tY zto*e2Rm9QYmcNp8A+96_jV%%2#V$QJLstM8Sn;}`Ms8gb{lkXqeWS^rhPudYExaRb zkvYnLsecnaLVB#!7i;uGES^4gs{3n*iE%;+&{UkEqR^8#gIsfP6h6HEjTlc0k-K=( zj+>=j;v3iT+yH(!7GJl`cGLb#|ApPote$K*xq>LJUz4#L!Fs3LXm@J2;1$prC=*`H zSG9_+<|h3oq%m#Atp9T^tCwm);6fusF0tT6~h)6veKHq1MCA(Qy&gTs`wA$s3%gi7e1r{6MS>ks$$Py8e3K86^$7D;}` zGhxz~_|eU(&gP76>6|YSd(qe~Z>%#{8(#sM26tI&);9fuguDgT&+oVoIKe1j@cl`v zmu&1B8IbFZEw)sS=A5g6gsRhnjYoz5VDCn==YGz7WU8UYfo#im zlu$xEW4?C_sdDAHfY!_1)!fi&@tRly87S!XO8ZKyBaUeRFUJp?_R0)q`fu7P)83g zf75}^xBm4-8yj16Et^vc0^Ky!R_^9y0Ghpm(`$=3IzVN!V zR~t4uxQa=}>A_~o#SlGg*g|dS&QpC*6h%=K7BMyShCg>f&@@O;_;jO9#G`4k&D{5D zw|^j(P*~jQ!Z#dOgN$BH$L4CT(MS-`jhMJueg1Gie&RpD;bWMAbCK-t_)eJACH{1G zReSf0u5`|)h&^fSA#cnx*BhS!ng@4UYtc6SfP~xy>gR8q2kf8=7<_%w^pb^DBMowW zVVh0K(VTr6NJyRTEPQ3yL|6@V4@0Iyf>#jN0DCnWNABnJM@9`bUdWa#M+qlnWQ^x- zAy=+FH_&Q%Tg?r`PPyy4N-4G0_S}AkX?mnK`q$zp0j}#}Zz|1b4pC*AhD@8oBS zH%42S(#%#Bww9rtQpRagnGFE7l0C#G#k%+H7CD^iTu&GF)>My_@iP~Ip1&%=5L4N_ z#lPrnq5GL$0W{RMqx~{|VSDeM3cTEZruxP@N)nEty>l3A>1i{DlR9OWUJ@?vG^5TK z&-qdn8=gU&FMrtZ24EJ?T|v!?w(y2KLCQeethFro?B2RU$}Pt!dCLm$On(3X03T`sTNz6tzT8e z#Au8B%T_fM8=5p-4P|aR5|btGCmX>ZZTDD$ER1 z?PND(wqtC*zKjE4R|2GDV5ZnKh17BKr$>VaXPr)F3#P$2XmAU<1HLx@{rn{%BT`9yVD>aj9Ij154`WrqNWS#I9q zFYXWQfZ-J&M;rGfvUr1%#SE1d9&)SQe}=xzedsbAge%u}U*qRh*)^^kZ{rH3q}|O` zuvKp(w%J&X_kTTb?f^vZ0i(pHf2AvY!`88+q1&wO81a_?+{9Qd)lrPiHr$RvNdbv`GkFS6CV5 z+Ij5~Hd!ruaSx#ZaQgrx6O#o~6-vk1$B2dqAY!!?b^}<8{1)^IfYCUClNj$~;-7?V z(M?80RAv4Lyak!=wy(N}f`uz`tv0;^@c9xGPhqN>u38m)+zHt7i#k3n@m)k)>rjpi zxH*CItbcsbDr=j1-r|l2jln`w9aRr<#QmIqtkoH)BClbuUFg&3IGJPcQmlJl^-nm5 zx=(_{r2Hz9Iwc`MX0)4nRB`etOL?zU#3b%@OkRlAUdNWO-2f;b&17sUZW4DB_R0mh z2_Jmj$A6>tXRiSmWw+^^;MoJ<@~lO$R}9GIQ!R5cgb+dqA%qY@2qAqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_legacy_0_0/00002.png b/tests/snapshots/nanosp/test_register_wallet_accept_legacy_0_0/00002.png index f9e9870f1d0928e55a323c1751fc68239dcd5d86..09dbe4844e7cf8fec97d517ea7cecbc26126b141 100644 GIT binary patch delta 667 zcmV;M0%ZNJ1+xW^B!7BIL_t(|ob8%ha=;)6MQx`$asNxoUiy)#V*wE(sA=!{G6_Br zL?$T#000000I-}7uZFJcN-5=>OPM_0WlP1DWY9Q6yX*4l)eu?wg6|}+>*8HJCg;3& z^;1e;D?6*#&N6c%Umm$qiB`%dVvAz?T)5Rvgx$DV06`pI{(m7!vn7;y7WvXVl3U^c;c$ znyhq0003}0mVd}^S-&%N`8B&6eO|xepSoQ*;H!WKX^EL$jDsH)6Wec+1KKRxw zxUl%BPfa(1&OKnr{3m_I_PBeKk!ceFDjYiS%#6Ls{81 zDO`6ft6yx?cY@Rchy~q+*5K*`jR^BYl2cAaF8oZ9dX@UjPwX^Sj&x-TWt>I_&=GK- z^Wo@$e_d`}0z5l?*7ToLK=h=9_Fuh@Zv;BniL)01Lv$7yItb;&qKHGD1<00000000000000000000000E?4HQO*-p+a}1Rwwa002ovPDHLkV1iFE BI3fT5 delta 662 zcmV;H0%`rT1+E2(^b0001%^X1sqbzLc?oO3CY$GdE)*pdtyXJ~gi-;QmOsW12{d0iLp;xRer zjkBLp`dQpxJ$Dw(iF|qFMkQ7$uZS;-?Q`K)J7o-BX7ls_f`2%~{31!(5{jxtzO>m| zx#UMNDq6ZDgN%z*J3YWC`7GdwwQ3VS9+5(>FP>{T;#O>o;9_^cO3Jddbk7A?Yj?Id=w zQWBG`%qUOQk(>`ns3{pCP7&6#s$xY_7(Pvj^HrA>Q;V;<%S4x)siF_Qr3DujA9dAq zC+OS*hTMNLR&2lh4|#^Ak-MyC^t2GfUE52zRed8avwu$@NidQAO?W6JyC8oXfo1lK zkNPS|J%D)7U1$xi-q46J-y}I@SLDLa45?SC_x!|mV`WQMR3QIQb`9APaM$^8^n-t0 zZe0RAJAKylzcfI!QbPN0J&*4QY_JpOCuY0%}xXGHAqsJN*c2J8BbE3;O*=bNb7c^ry=Vf#YaoXIwT71 zq`O+}1`x|iLGOJTn?FmjyTSpWb4 diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_legacy_0_1/00000.png b/tests/snapshots/nanosp/test_register_wallet_accept_legacy_0_1/00000.png index 31fa5daac554daf1cc9fdeb7cc96ab9d850e0b38..481024b040269adcf552800fcb6ea14ff7e473d1 100644 GIT binary patch delta 1000 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 delta 968 zcmV;(12_ET2i^yeB!8tzL_t(|ob8-jlH4E+MM)|<@&1?Oz2w6+L_x1Bfw8+w=VPkd zriBm^nAx`e+HoBHb$^?q8{wwtExZfr;i{JWgZ)!l5V~=3 z6x0IecgUOh=pR2cG9G%Xv3VMd7yO#^MTkAbaU~&5sFcj&~liQ3lS+gMcOh4;6vboMoLq&4wtr}zd5Io7=n`~sl~vzAK@Z&h7B@&+&Re_Crg?Cirw;$1_84loVVwh_ z;OXCS8{fTW*evm3-$2q2>2GF!M4MvrmC-MXqWEr-PeH>oC3xyXp3;VmX_G+>Zkp+Whdx3P>y|Gfp61li}YQ zYM-Jx6n`=jrH@7H%L(td=JKmhgIv+yh7jtC{$^?po}^ZxCvk#Yb8ss>yp9@b=$G_5 zZzdjbCq1@x814Xf8&_#UZgW9*nS2|S{Sb9ivyXccYJh8;Gme465ofm)(G>se+~heW zHcR^>CaiXn>aY9xZl?E@6M)y6Ep*$acz_Ilntu`?dW)(ov|n-U($-M$?aRT9Ac0Vx~|E8PFfxSgNyWgmlR>>w+oX|6pHQkgNF&rpdt-=wNH!# zOJ{=*JNt6yAolNSL_#sWThBUx-)G&4J3-#r3OJ-cOJBR%@G)?CGS^Ygvil8{(d^^7 quX@18isFGe$fHe|B3W z{7slRX9sPbaewpferxD#E;T!NSr2=guyDJ#vAe2lZ@c$^ERha3w?13=;)Jlnhl@J0 z`$&El^PRFatXTo6j06Ax;2|tK1uelX%LEUF;))x*nuvGxi=yTFTibR9jvTs7VmwDI zHWgA!TyqfTA{LowdIs^SVa(YQI6eu1$w@bVS`)p~E`K#kc!oK@7R2@HMt+HRN2e*- ztU>a2`?8j*X2)HP!$V>`^hm4#S8}XN&0vhJ?rW|idJ)Xv*Md^T)hsiKMZfiqTVkRZ zXD~S<*3PL5sOmeKNd3B{hYUdT>}9Js*tf7^t{9yndT;FrMt%JtsvEUw<5-;f1i}?s zUE5ksTYsW_=A61i`ARFhYnj&vV4y%d>}1xlWrnA$CSQMM#e2-Fdtv}iZp%WTxPy!s zY~|6ztCQ*R3UBXe2pZ}cee?irMb{uxbxOP4Hs`9{%9@*S7UP1G)zJHFK)-IP!L8zk z0EiJeAL4g+lGoar0ufJc3{2>MLoa|T+n<(&pH>opkL5!HAohkE%dt1?0nI#PRCKuv zJ*VoXpO)4V44mBO#lRn{YQ@j2)4c&0H2?qr0000000000000000RA_>&ASkhYCHA@ P00000NkvXXu0mjftaM|? delta 725 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 N002ovPDHLkV1fvEXlMWc diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_legacy_v1_0_0/00001.png b/tests/snapshots/nanosp/test_register_wallet_accept_legacy_v1_0_0/00001.png index 87b4dfa0fcd79dd1870bdc60c0d92e4f4b667964..cc2d012b6709decb341536a534fae2f5468252e5 100644 GIT binary patch delta 429 zcmV;e0aE_a1JMJJE`N4}APhiJ+tZz}|0S`Pet1gL1R^*Ab^7j?6A=(JI=F2B006+# z<(zZQSNGycJ_GA2L%(qSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_legacy_v1_0_0/00002.png b/tests/snapshots/nanosp/test_register_wallet_accept_legacy_v1_0_0/00002.png index 524252318d3bcf668f0168ec2beb7bbf2390bc4d..4bae739fda23efb460facb6abacd53c22b584fcd 100644 GIT binary patch delta 605 zcmV-j0;2uy1oi}wB!4|gL_t(|ob8%Xk^~V9hV9ng#Ql%tF8eUGDVq>M(7OKbX}SfG z5M(+800000006f0<<(G1DTEMXq~GlE^V?FfCb>w@rQJ38_G*Zkp70%HN=bGxOpNiY z^+O0hJ3Gs5XBjz@r$^~j<`pVpYq8kA6t1y-n%CKqf8@12n<+-*NWQr{m6|;1=0k?a=Sr+Y+`XS1NhlZd>v2-7T z1FGx{L;wJA4S$v+;I@8e>dO0e^B9``Ba4PL?7-In1Nn)WUX053iVf#ZOsNQY999m< z7GXJeg2+-RNy=K5RHp4%{)Z*kl00000NkvXXu0mjfCGQww delta 597 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 delta 968 zcmV;(12_ET2i^yeB!8tzL_t(|ob8-jlH4E+MM)|<@&1?Oz2w6+L_x1Bfw8+w=VPkd zriBm^nAx`e+HoBHb$^?q8{wwtExZfr;i{JWgZ)!l5V~=3 z6x0IecgUOh=pR2cG9G%Xv3VMd7yO#^MTkAbaU~&5sFcj&~liQ3lS+gMcOh4;6vboMoLq&4wtr}zd5Io7=n`~sl~vzAK@Z&h7B@&+&Re_Crg?Cirw;$1_84loVVwh_ z;OXCS8{fTW*evm3-$2q2>2GF!M4MvrmC-MXqWEr-PeH>oC3xyXp3;VmX_G+>Zkp+Whdx3P>y|Gfp61li}YQ zYM-Jx6n`=jrH@7H%L(td=JKmhgIv+yh7jtC{$^?po}^ZxCvk#Yb8ss>yp9@b=$G_5 zZzdjbCq1@x814Xf8&_#UZgW9*nS2|S{Sb9ivyXccYJh8;Gme465ofm)(G>se+~heW zHcR^>CaiXn>aY9xZl?E@6M)y6Ep*$acz_Ilntu`?dW)(ov|n-U($-M$?aRT9Ac0Vx~|E8PFfxSgNyWgmlR>>w+oX|6pHQkgNF&rpdt-=wNH!# zOJ{=*JNt6yAolNSL_#sWThBUx-)G&4J3-#r3OJ-cOJBR%@G)?CGS^Ygvil8{(d^^7 quX@18isFGe$fFnPMb%DsqWv$)d+A4JC;@>$uQ=&FUy6bO z2|ck(0RR91007`PU)CSjb(KGy3pN_NoHuPc2S-^rhd6U7~^LZCU;^cZ=RQ=@}7Nq<{x)|BT-Ol9u&*yPh* zjqx4Pu6w`M${R!Vk=`F($LK+_F6u20t#%3JmL6WyZGx6@+$h}u2zTcfrO92SOWZ@z zWH`N18i7xM5Dvp8ps2y?6yes zH(}y2I%xBZn}6@_w~o%{RP%$E_0Zach1=G~-c{v$Yu*F0L>k=O`h4NT3&IW`4mD)= zk^EK6H_F$rW(K5IBme*aH(}W+XbIi4Oz==BuDHRgiFj5&C~D5%+O{)r(%|SXBvB*HvBZvlVFB^E+~~;%`&sF=%?OsOH3r= z941G^+A(#2s@|iCrC--r$N)6YUcQQpy$dVujL}Pk_0*1F)aMtXx>B2Vj>V~0AY7r> zw5{2+C4b6i&Z#?;ue7o|mw7$_0}0w;C$o+%GdyKA`S?9E-eX?9CI;Za%T^&!x}A&| zY~>c+s~64d8D4K`2pY1CHp@<8?sL$sP30r~df!}Atsn0L0a$Yrws0;oSq;|f0s40) z*A^KKn=a}b10Z_jQHbBsNnUGf3Pe2dm1xIOu62$P`ZjbS7yG*FuxZN~Uasmh#oex+ z4!~{EDe=e)iFrOe0Ag>rVcK=$9?+b;PUe=&P&u^+W)m{Eio{+9PVVz!;Ez=~;d|!e u-T?F(00000000000000000000|C3+BR6xvX1I~dC6m3kZ9$X}-&MGe@lfz+PH$g3QR4u3i%u5MUU?kl*Jsm-~? z$F0ioQIn{+&_-kkmPCe}JO)m^=0o;0XVxFmC`3_twfN!G`o)zkBSyHabtuVg-?AF+D z9m0**cHhoVr+)?JdFvNQTh2>+A-TCTTRPY!QOcEsqP+v6_`|c(L|#5}RaT!_=35R4$(oy<9( z*a{tBaes3%eZ|HHQfVh0kVp=u&0C=8Od@kK${v_-O`G&KAAs`ST?iPH3?FReDbvfh z&U%N|54$_HNE)4)yQj?8TKIrNSxKqV)HRf;JNtkGmc4`}l;=!Tg7QL?@~=@9iVrru z()T)`o0L}}^inVPH#6_z5n`q%rC*+f?9Ac)ZExs8D*1KSdF|X1$*MDUzQF;{gy+M} zuMtc5atCy0!vk}!d(VL3`c?9`v`s7fkHKhC>`|WBPU7-DDGJk-~ULyOFmpf(dZmnI{1#Ngt1N4a6u*Ge-?;Bg>K0pt49t6niF8+@A zIwktoFWTpLkg?eVVpQ|t@pg*mKWQ)dqyXoLfH;x)JbK#C41WrK17C9F!FmC8b?II(+ zEuY1p&%Lj&S^=|4m2QX#6=K+3qf&)7sY=>s@hmD4O+<#-u79~SbGbq~A>)QFGyu;RimE{` zkJ`;{HjEG8Ch(&cUs0z)vhIf%I*cS0A%;7l$966!e-ar(_OZpVy7#QBxwm4*KI%EBCE8w?y;=_ZyJun*4ILS2JS5Ptd0cK#W3>Tzj&q%TE{>q3`1reSg0(ayR zI5Pn5j-6JU(?hn|ojAsZ60A$UJj<`Ut|1F9vi_U_h_IePN#ib4Od8sBCWa!j-jy+U zT+Oc7Ga2ux+2(rkp6_aNZ^Q}-yk!sAgLT=zP$(3>5k4ELk(cmS``oFO?~z0t=RWz1 zy?;NDAv$}>RE>TZC1z~)(V#FzUQp|aSl7r!(Zk+@rfsN8o9iCIl2cH8*u@&P4IESm z!RgYUhAr)9DdLOinZDx~$~j1z=pNzjNfbo-v!V2uC~IBbx6A+h0B98EEIJyrJ&o0e z_lf?yv<=4SzZ2#?qW5VEEG|zrBs-1~XJoo){WOLKVE_G*0WBkoWB;CF*uN1Iw=9jq zY+I5>gk%kB(B@DttGokmnC9c?JtpSV#?irsrtg~y1{VHb5wFE~1{1ZN&ryX!p-}iP Z`~wPfgrS-1Q2GD>002ovPDHLkV1l$#?hMi7#!v2@UUiv_zQFOOt3}>S635bzo z`Tld-F`A}nnx<)*W;M3Xs=b{uINl zXaD$S{A>@>HhUmWwHU5wmqh+I6QwjPsE;U7uuUKc7Mueb7Lhp_BKXT_M~TQH*Dt40kg!rKVVdT!_-lC^vKyoCATa;OEKUV z)%O##-!x6r{O9}z-;zJ2XL<2;%^)x47Qj!$>-)+SGxMVw;x)fr;>ECOL^AX=xfi*& z(ibA3gBT7sa#AIylEEY@ZbWnuX=eM(rMb%;q!VS_)PIE<;Hsf$8tn3{o$SkoQ337( z-)i|4Z5kr$e#F#al2U}2?t~pXxLo-YiQ(}cu(nK`>K8H0tin~S35;$&p??rnF)mHL zAIGnd>MYI;dZQv2nn+&Kj`h zK=I44lYi!JnwuST8$3y8|4BOgPr|dm=9{p%yW+c2_jzQe7&MqT25TO*O*09GYbR4x zDRKtveG(kzVhXF?3wbulQs!?>V!r zjpRM`8f(9ZH3{Cb2JGR!*}rL;<`W62p_+aPf3>%s+6g`~7susK{^IO!WQffvJynw* z7Jmpcwg73Un4&bOJ&AbN^hGhk*}bOiC~nP-jd0g4DBkkoF?AI7Dn#RS6;Q*M_RAFh zV!Eeq+J9)s$%5oAo38OGWj{x?0rr1FGFZ^IA7b0TSilQirq9`8c4=#G1XKU>^j{dp-nWm4Ujz(vEjPpGEjMg%{VpM;67q0W) z8C{oH|9H{<_XqRMGe`xbVi(u-dF6l7T2kw?KwtuDAj=@SK7U`~11>;DC>yq$hF(#_ zR$_g%HZq2v0L%I`5NJdo)|X4|qk)=)Mo~j}NyfW^hTaIObdgL!eRTRE7aF-dCg%!g zXBGz)4xeT<1>p=kz_QmtaKuy|PWM*wlsuqV<_Vw<_YIB9gu*Of)vOh2PK9xKCb{-h zmf3_mSGw<;=YMq((U0!8_;k_`GXGM=toXGY$+VJ@;paX7&|xu92aJNa#5&%oVhvIm=Hnuk+9dcRc~CO68&`iee{nFFjwdKP@q5HqC>OH_E%zh*1Z3lxJid;Jkm>TgNtSwW`Uk4|rGZ zKBjs>9lsxozhGIViJYDFe8L;q=4U-apqRrN2V8_XefbpNj0wfm%$62&;0_2!ab9Do zV$O9dGk>&KyLj}uaR$HXMr1%rVBTGM@K<3Pxvc*fimA)`4^uwaNoAp(1V%0&+=?`> z_ePAJ3;RX4DeJr(w`3Z2`g9r$w^TnvO;=9`NLIqC|0io17GH^f@S4PG?e)*0xqsQyi5MhsfHj1)lxn`VB1S-D!v{=3 zYGcD%PKat5N8WQlXhg6NL*@HLYd=7ccBD&X7Gx%tw?Emel}!CUU>C;=c|A9p^KIXR zILp^4%dSyy-%S#!p9 zHYNNks~_p~DIH-|KAd7mPegubWQW;S1il7V(_1o~P&lnBts>bJbav~CHEbKPdnc{~ z)W^L4X>|}KGLxtc%h4WWx;jxao7E*99do?F`o|8CJykGchJc>yld28WRmy;XnH}%5 zeq=XvBWf4c5e{V*IN(VA>iVNW-j0F9KhVf^5Rns`x(9^H_;0wFX&%l?j$*}|_HkU&BZ z8HB(B9XG8NMNt$*Q53~;{>4qt^K7jh$I(CcKXdd()TU^6%Q(-o_h^l=J4XGdcMbXc zbI0BL(LWxv=lNiBvj*vabnN1~KE?U}X-8@F*;-%*mOWiW*MH}0`2+_bS1445unH~Mm@y{VuZZcx-EJSF2@i-z79bg7d}LA?X|A+b7gNlbR+ zcFiIl^wxcp)f6`> z_1n>2BNMpaN*|k>0JbSOgN@ywzL_5Pk`GBc$1}?f$LUgXb;7B z^tl0zzkle)NP`q7yu0$?pTZ1sMSmGes4M!5sX5q5WucuoL9RJ?DKfmyJ7IP-Y=fs= zRVoNp^UMdevR6x4@P6E~X|dBM5Ex!n{a`h5^mbLhjOd`2JrG1y0TsK4QT5LI2_snv ztMh-emSO8_^dG$LV@Z4cvm0*qbVdT=Pk`ErjDM6GzBXfx1d)PIFa@c?hBX`)H8Q|H z`aU32SUph=UM~b_Dx9cMpMYEp|2J` zw;&VOeZ3RoOaN9c>9?bTqIDjPx$XO@hSECGe$q<%`bur_00&ag-p#7`e$-N{D2n2X z34i@UMlBs1+>n7-sGbF_ruw&*hKkjNrj^7}DG3U_mJo}L?;cygz7+q;k|cpt35->H zw~L|nUHgcL8)1SJF*;y;*fCQ&uZ zQ5iBP#M?2I;AYJAPE`$cmNOB8nLVzvexw?@5mki+#;(nr z2{>l__WFZ}yd4YTr=YZm7&)}5dw}Z`WimT2Y-++B6HhALtC7oJ=EzG zhTi}y`g9=B5s`_$j6(O8R1yY79l~M7y9R`+(6LEMx+s>Q?wwxLhDNQ9$-ctgS;RAf zWqFbLaLQDM;RIOmItY%L%I0!!70*Ygya6=fexUOD4CR4%RALEAm5BB zq?T6DDzFETClG#n=+J6Z9je!s5~tDfnb&MB@YE9;-+%e7<7l;eDo#H6&@n(bc36*6 zz>sqFqtsxjqV4&e=F9~2Q=r-zFAH2oJ?pV7fNq=pes9$ijax?%Lpait#grOM*{p_s z^5HHgW>W%c`eY7fjlPT@EB*3aamrNq;QQWy8tQwnuA}DWX4=|@z!M-xoWJ;!?H0~k z?-zt^Ie(DkD;~9!v$0%K2VVB@X-9Q?^q9Tu563$bpm(%?>=#z+>)0>m`5e5N52`{h zBnUEcu$0~5J-;JG_=4yy(hvPgy(_8Ey6ZQLMK#vWGiUtVbQQ{TT2}DbPT1L=&d{4;aGv%eDQ`qZ{jD5sxLH+5a5yprrlmn*&txC!K6YrMI{7ar(kcSGd2p{Cu7) zL7;u?FJf;P`v3p{0000000000000000K9?!$l*}!9c~&300000NkvXXu0mjfY0ZVo delta 749 zcmVF1DMQNuy@&1>@Ui#q)qo4;u*diI<^W|Vg z5)z0<+EM@j00000Nax2dT5Bz(9LLd~+s7D9iKvR2OQY7>bNbnwF0Cjx4Vt|Fl`Y22aqHYk=UtF3)_F)JwTK1j`oM1>?DnBT zyG6TV9J*mNYC5MJwhj5CQ5LVGMGvTdyz}C~(X@Gv*?-L(w?5^z_>uddc}3f&PMTLH zfZmc%eX+ivEuIrKH5ax{kIlB-)p{babQLj$=Do9+Qh`ejt3y5haIYjLDFFc&c@C}` zeI7kp`uSWj%9N+qc{3n@I1lbKRLtC5xwj$o3E+dy-v9A-4Q=Av1tBd59Dl{5l6*Cu z$Xw>_&3~ue6s7s28cL4HV-q0TN;V(Zt>4EMXEx{H;e1LJdM1M)BL}y#A-we+?uX$M zmFG(6D~~o?zxL|u5u;=De5hna&(JZW)HOiFdEePBs`R^Ma;QEn$8i=nmtVo=5(GZ<7qKUdeEqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_0_0/00002.png b/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_0_0/00002.png index e2cc15b3384b9fccdbc715a1ee68ff0c82fba204..55818a74a1fef21a131cb8f4f9078d52899713c5 100644 GIT binary patch delta 650 zcmV;50(JeX1+)c_B!7EJL_t(|ob8%HlEfegMVYC&iT6KJ?lOz6wroH|gBrX3TP0CJ zB_fg#0RR91006L@pD01sbrDfYDPObO*R`i%t>&bDPF2_BH%btj`b_K~uj`U3hDj;y zoqZzuTdAy^JI}~j{d_Bp%B+%$*jiNO%gQx5GuBPm3Sg-HOMh=j8!aP`GuO{DYi}-l zsCq?@I@Zalo@(0)aMm1iIBKiXgu@-9XiG#I;N>OC!PHi+f501kbm{cwG0O$r}AqEX$MguJk$j}imCe$ z3{YjIBLV<`1Ap)Ye=FsL=)Kccp4fW>*>Bi{7w?vKN-?LBoV{wKB4i+33ysT6i@f&B zaVllQGrmU1$|NRH9`w|)@>%#HoBOewu-qS;1pk)ar!}_KJULr1I&Z`jUJ=8(x5(K-t@GXh z>FB|q2yC#EcrOI}G$t7~n9928y*`mewVv5|o0W>}B*dff47-`kF`oDpdD2R?CuO7AhHa-e@%~5hE`8Xk;{qZYlw|vVPf1h| ziKrwg0RR91003~DFGpFWl$27=xn7go*R`c#ujZzHZdIrA?I?>3eZ|+vQVLhGOwKuQ z^ixVdhxN5%XR(~rueaQ(#4ELk%tcW?uiTSU`{3m^&lx}vyMLJfNRqXLYHF=tW%k}& z@=%P57ImbP`yy533^3MQ3piq{)`iO*^L2x>170(}&%D50s$sv`+ zHC&WWwjaE?9lZ%jQIJ8fFX?kyeOv956N1utWlv!hv8+2pP6)luTQ^9LHvWmg2a)(k zAz)`P$ne2d&JAyQhZpsFrsr)=D$x5i@jFqxw~u`9Bqm3mLkIKcnUxZZin(vV#6 zB63Jn6n_o>^RX*>806IxZ<9I$ERkfWh)Z5jbYK$1e~{rP_5A)9^wjr_J1CkW-T^J- zA3E{kS&D{i{5$&C=HYp}l&uU$p$)YQLpIgcSJ5+eK|GA|uL8XyUqvY{uzV~hgUo{u tVgLXD000000000000000008jf7Y{fW+{c#hBMbll002ovPDHLkV1mdBJo5km diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_0_1/00000.png b/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_0_1/00000.png index 1b89108a028718cd05e5c1a736cce5096dc42bc1..e78d4f6d5fc0af76d50187d885790d50f59926d6 100644 GIT binary patch delta 1011 zcmVyZxktICpx z2rAe!M2$wH(P%UpjmG8p6?{96gNR|P(fKD*^CXxAUjq#01)aTD&YYZ~1yn@zg)0$wtAFTV`kHo=_jBwZrY2g1 z4p8lkBA~h2VDOoCta-yg9sxnb@xhFC#QNn(8ic}~J#j%i=|&wQLR%z;Mu2iEPX_`c zfRvR3jwu$`u@tz5vAJ5pd}R@chlLdSvApL zMQ(papP@!^UyMsA!R8(xkPGCv6yB&+^&Vf zEfeOiQ^GivC>E0AK4!r+Rcz2cA(e}<6al7D(sdcJss5Bo(cmJ4-{7>1eNs$JKusrv zD)w&P#}i6F*W4$&yui*qpl1Db%zF2uP@e#Eg-y?$=C&bxUvqw`i%h%(t7Xl`ahXrb zIqy9ypnsvEcQ5{$T*!QCf%6)e)|#-hv6XPBVmS=PZ##JI5FKEQhxJr{u|U*trL z&_7KNk=m*$nwZf{&I0ZP=rNnN_GrPLo{B3K1%IwN=i^f zD!!&1YB1}g!R07@|JrxkdF0{w+u29b^Dy@}Vvoh=ml*${;dKeU(P%XGK$oBBXOhAj z^?&O?z}zDjOb|Uce$pxtHYm+`X+zSsjt~CcR3ZEW5wY~NeU{3UICauZ6&^q{;VnPS zsFh7b?QEzaavVJ6(O$ARsNlL{XZ~e|r1xOHdW7DqsYBs8?FlZb@hHRtxbkeP1tIbZ ztKo_h9Zvmningo(D75mg3N%x^N`?FkRBQ_^V`&3i1~LaXS3`x0+l&67XRK6DWAb!F z=)bFpZB*U>5z&G(XsN@gUxHO5ZPRk`b;+yl4dE*>HPWdgX%YB7{uwBTW{te@7mKd; hzj%C=B!9+9L_t(|ob8-jnj9erg-yQfr1!t1+DjfPV+cp!h*npnhySTA z3W(x`>Y3Jxq9}@@D2n3k{BYhK$I)7QyTNvPT{h6h?Fc`4tjv;7rix*5q` zke@|ymRx_2oT$!gkq^;S>mpZcR?d*QgV+_2BPEQ9Lx1ErEwC>0xb6@pGu^mdS~RIZj`78r;J;DbKVG=0Qvy*Q(?q{Nbw^5u@x6kB3Zdb*Q=t zrwt`5%nrad4}ERbB}-Z+u4ELXp<$p9r&i&s5$fiyO!4-7v=;dA}Vcz{6 zfZXorCfw?*`6r8}KCuHV_(^%?Q;ahg`8|;%=zwrN@%KDd$@FJ6OpB_wp@ba6{HXJB zw0-^HciVpC;pexjx1`rG_cvmXK({n)z1+D3s4qF+T%ErD>KHz-5>|xMDdQs!ZIT^e0EgO7_&R9=3@6cQw9`(hDG? zT1h57br|_eGHZlBO($QMM%BF`{7$A?I<+ND!ms0>K{_;Z)r-F@4z=$#Qj4M}if#M` X$LH>;hxxN*00000NkvXXu0mjfi9hld diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_0_1/00001.png b/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_0_1/00001.png index ef7366d45cc9ca2bbb546b582f1dd444b28e7b18..9de81fc3f71783b90b06b80d21de2d35373da8e6 100644 GIT binary patch delta 1029 zcmV+g1p51z2%89yB!A*bL_t(|ob6m&lH4E+B&poQ_dk;Fk`GrXqDQNRvB%y~e|ZKW z3B3S~cUvnI3WY+UP$(2`$1iVS-}lzqwr%~nf1F0=qq&Vkyp&PNRg`*SpXJ%1GdEW; za?tqAtFpxU+ds5nJ>yVQeiBT;C_raEp|eoZ)bRM;T%AeZ@qdR@0z|7IFk?-}$nlJ$ z!_-8J(1EEVQJ8O3n@m1$Xf7Z+f(-DiKl*uGA!GgNOzIOwID6tiKA9ox@kuG!b9B_! zQ=>5%(3F({yAUVqSO{LjIdg~U-VH@2ci;e#p`P|0nTeA*OM>_Gs64jX6`IGJu&$vV zcp9EKyXLtJOMh+AI`}3ec2Fhgz!4pN^W?>c`z_#UrW$r$Rzq(S7HaFz(ZS&zLxCFZ zJs=Ba!QSZ&5MRA#U@Xz$riDzO&>xQTi^3e%WWcJca-mQt6z;^SJpgn!JAu~}1YJh& zz#1MWOc9}yfP+Uva=QuME-%hSf(-NwaQ6luDl{3;!GD|^(yTq~1s5^l?bPii)t~U> zlJ{yxC83-5(WD${%qEghgEv%s6V^2(G%MMM8tH{BuW)%%Mh?1C3H}ESE_Xak`!M<+ zNVFoZ1MgRon^*T4caHAiTj6MUAgbIetVSzY|*c_ zeoN~AgwFX7^udepGpo>B5E!|9a4F83S65Haahoo+`v7y46yde`^b*2}cxeA0%qk|q zJ3v3Aq%fn52&@|>%jyRF3TC-C;hk<7GSC{B7k^72g>mG*uEi!K;!EOH@M6vTsGmWs zjdL|yoz9F1oE+H<;J*w%&Sbzzn88Q}CfRq>B6L@yHx;mGk}L}*S7sc*H)+2dOq(6O z8@ffW6sEBI4X;(9w+}B*o@BKUSf8s(kjN5I<;fo!apRLrMAN%^gT-W@*@Rn^KIiG5 zjDLI9vMd8?S6Gb2SGX7A%a>m$6utq}yP>)-)Stnwi+d?}qWN2PsyzkzLRvBAWGS`; z+_PGF7{LvnaH4ny4HM?=eh74jQoDEJUlm~J4%*cdM-JklC9U8w3|V!Hdx0M= zZSo!2E2gY~U= zNCWk;`6{sN7+RRaBmP2WE#4CQg+ifF_;&mSQTz2aa?l8K00000NkvXXu0mjf`se$u delta 1025 zcmV+c1pfP*2$u+uB!AvXL_t(|ob6m$a;z{6bW*tq_dgPM$p;meqovhefMG`cMX)T% z+H7lhuarb0kw_#GiA3UZe1Wlj-%Bamw$$A?1w=)h0l=E=dg}Yo`on2dCyH?P3IfO{GlV@pT}sv*ZMF5( zC}ai{Wo5t-W2T5P;ME&5cbMzdN@Q}!4iHHyB!y%elQ~O*_w>D*Q=70ZqaH#Uua0A4 z9%C8SwMFa58-I{k!Iq!{M_SeWlhh#GZ+V6-{6- z8j{;Z@b+G@EekTxGr-*&ywz(mpo2L#q*;5`2rgp6+kaiR8~%z9Xe58oZ&XUXa!XPa*qIExnNC6)sOo%RyHv!T+Ga<&KAGA4dNJeXWR-!26Zt=GA@1 zovnNL7W%Lw*E>K|()kcOpo4umZn;RVcK}&l?}ZuK+Q(#7nOUZEzhoT-?dm*?sKhQ9_0XA^rNj`I`w~r#_b#W;6ZrL zD)bZtMou4`idpmO>e;>#ZLcw5djoTn6yf#wwEp2lJhcA@vx;$$4lrH9i(p0>5yD#@ zy-C)q8}KXU>E48Qx@8zbYhd0gfe6Nt`?~&`kbj78h$q4eH~eRP2C>#o)J$|bYYtij zPLAFT;9rJ+4rag%%wQw~lWe+a5xS*OI|^7dN!AN8S4JGbH)%f^WRD$v8ybF6$Yb}r zU8_QGZ$6uxWVH~XKBtr*ks_kXlfN?Jt|ys=rg!xQi^*==gbR^D!^AI+%hs|c19D4P zkAL;IxJTiW*PciuJ_ppdp}H?rpTWk9+bMXW`CB&Mo&tR#trc^!6k7uBSuH+{h*P}Q z22T{vpeMu6<<-EQpWz|U9qQe^`~Ir}0Nq48dt%GMdzj%CvZ@yM0-sse;5|U3t!TP| ziQyMf7hEQA&EdZsWtu4Aa^kO}&C5DzCVIWp-nB6<>1__0WY_p!BhG-CbbiX+_%7?0 z-p|udR%Q@nR)y0muI#rX2Y?>3s4aXGnEVp7SQS=C=`Dk$*|7wN-jit8srqURoPuuG v;YKVwh9<`F68}PGAs!U_i9{li_;maN2O{wL6lwLK00000NkvXXu0mjf!mjzZ diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_0_1/00002.png b/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_0_1/00002.png index 267b42fbe156bd1376d882c68b26eb21bc63d419..6bdd9ea6a81d58cac5b3c2a828e8c9560f368a32 100644 GIT binary patch delta 730 zcmV<00ww+K1@Z-uB!9U{L_t(|ob8)ia>F1DMQNuyVgF0=Ui#swhDbt4yiC%2zFY^y z00002McD`yKT-TLS$~n_B{n-uKk=DwO{H>HCXO)x{*&s+eWLzyn7Qzja zx$?OiW~64{Zp$#T0@c2JX_v7@{&++rbG5Pp>ROX)W2S^`U!(YZ!zcaE z>K2K15GL-`L4U#1-+VLP8aCCfW=~#JVJ!$V*|oslG-a!;-UFg|I;@61yYOa*utLM8 zj;ubCKgD>bYzuRCK*%Ej0020Ib_`(torM&ZkWi~PlQwD&C%s0LW|*;aR(3^J%SeAl z1&;=~=TMa;myt$$2E8p(ARZG!Em`_82r>C^A8 z;z~z{@+wrTX)2T-E$f!8^d*qHGZxctRqbS4G990q!gZP|_l@19nv979p>6^rJj`m^ zm5!DP8A2^=h#S$p`IfgQGwPav16eUTp``jOxC@e-?tbw1);Mf1Q>sff4u9#@7unk6 zXv%hFU4K?fjny8(H5%(?;t}&Gj*?duGotdS9;zIrP!Th-_CGZdy_A`A0HQ4MLcmF5 zkTC~KdCTE75?=BnyN3sct9QMKb+G4V8)Z&5v>PLPIyhd^jheq8! z&%-}zqt>6=91rgR$*h#`iq!E6j+=leg9H8eBvTzX0qbIb%H#Xv$q8_#fAjGFP#AQi zdq0!?$Mf3tVl)5f9&jed#ei)r^=tqD000000000000000004lSUo`sbQ}DF6Tf M07*qoM6N<$g2HKLGynhq delta 726 zcmV;{0xA9S1?~lqB!9I@L_t(|ob8)ka>XDBg>9!h$^Ms=z4RedhYLcEzwzFl?lA%qaJoUh>Bd7dey<2dqj{;`cL#EO!y@F}E*qk7tbY6q;GEWFq!OQ_~N z&n!_sx1l6>!sCeoAu}k-w~cY1Sjityj}(5es)N^Gek0d&)qmF^mt?0awxm}N&d*Zk zHs`Ziweby3P~1(qp4@)B`^`Zt56n}mc27NTQA)TcN4DH9!S)H%NQeQH#+^Z_=LkW- z)l)l;EXNwv+9Ni+cUZOvt=bUcT~*HpLoFdd(be)5^GD6%SOSg7Rmr!UK|@ zINKc}$3DdEo^aU>S6ihIReHt>BO6tB5%Y*|E5lP@`+wclPNDqix^oqUwCRrzLCevg zM9(*ia;oa1a;%)Ct$^HIu^4`}R1i|qzYHG9`ZEK&N z^+F&Yg zxxGQb%f5*$=SDwnr0ona?@tUU^0_hVU~ zo_p7e#r>z@BV(1}tN0WFv$SLI@#*5JCtcgb+dqA%tA~0yh}vKn|}{8~^|S07*qo IM6N<$f@u(96aWAK diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_0_2/00000.png b/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_0_2/00000.png index 0c08224ff40aba010fa253cafe1604d9e2bdf501..200aa589375b20b044f90d4bda54df2b72fce72c 100644 GIT binary patch delta 993 zcmV<710MYC2loe%B!9k1L_t(|ob6g$vg9BLb*Ao4vi~JzFY}SQ77d4oXlr*3=gZgx z5DLA~W=+lu*L0teH&$D}M*Ix}cO zVHqwk1r1@?0h+xo0)q@Emw0&oZETJuVk4+xZ_Fp z{qTGyBP!DKHh(UT5mUJ`n;R#&=15yBJL%as4g&*qz$hXvfoG#ewxJ-H7j&d{!AKv= zXECYs=d>}%F7!_kws(s9=lJ;6WLncr}#LafirGJUb719YluIWM!cvc8mcfQhU zxA?MQEK-V~kD7fUPov4YAJB9Z$yNk3cY=?tT#o)G{qT4Mtfh%#>Wdh|XoqWZC4G0x zMEpgVYR1iAK8{AC`!kVr06b1v3|_CF8`-1A1is$+$6KvZx6#~^<^wsmz3pMsqLCg&im#oJ3jwB+B|HA+5jQix|9G$t$TlAGsz58769AO`>*V zX3DIRm;u~VTKCi-cK0UigKCs^12qUk;?Pe9)Iv-PH*L%)=K&Rn!;MPWMjh(HMxbqX z3ab*1=ZB$85`oqVo$)kvNgvovTqzn>{+*SifqyBH;y^D*%bt-+-TjM^>?PO?@?dPA9l>Hh5KdVST~endGe*4VT5kGqPT)A2Si$)K}zF8CQKSyIBRLw zfJ_1t`6bgmHyWw<0jdsdA zQh%y_Bect4sOM0VawuhQ%I|JdbK4!!z01RvQSdG(e{~nQYT;{cK`?S@3~HT7w^v2! zp}0Oj`lpXbiA4M4@^3X7!w7MQ?*Qm(R@1xP&>?fX`pma3w7xonbgIz}ZO9I;hQ0%! zNN7zuj&xlhjg0QN!$voOM7(pbs(DNG^#)C(?eA>$(3Ha#mNTfq*TFg zE&r-AL6LPos_Qt(QiSU6gdA*KuKmr5;qei$woRPb6EV(cg=?}W^mWTb{6WkXEJ zqtVg*o=hD{Hv3eviQ~rZ))Jz=PV$3OrJMs2xg{+}mD~dJf&N;N11uc)tuqI#*--p4 zu+!W{bAPdeior?B`zI;ypG10p!I`kSw316w_jzQQ7!;V;16vxc6?13IDvcS`Z_28k zg2wK*sn$WQmbic#1ZW)k31Du-tl?%|cP-~p4T$58N?Ar7s=`LFK6eh<3CHupP$r3B zl|pAC%|k*LxQHuNt2=)ZCEKVek#nFHWM$9DPJi9~i;=7)V1e<$?nbVqHdzM(;Lg}- zu{k;2G`kk}Wa3ygl(Rhfa>?ol-L^z=6`=q`N}j=%;2={?8rE>O(k{Sl1B$qoUiAqU zJ{5Dr1VSLtLSE*{~VJZMcQ4~dSh<~qDbd8AA$N2yN002ovPDHLk FV1lE4>vsSE diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_0_2/00001.png b/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_0_2/00001.png index 91a9f0afa436c3feccf439cffc0b700b15b0c5d9..a2d186809dc864a4a99d06fefa6f1a7262a07e51 100644 GIT binary patch delta 1048 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 delta 749 zcmV6rFlKn3!d+9^Ycqrf%f0LQs?lA%qaJov*m)d7dey<2dqlzU?D-;&vs~ZR0#oH9%mPE0cQ&@;zeixc842 z>F=1;-0VR))HN*s3S^p$|LHbVdS98Y1WNKUh_34^e1Ze8tA9{+n_VMYKxj89okjBs z0N#`X&h1t2TQB6Uf@V~m;)ZZF<6QyaS_ouI-;X5iCINe)ym@$Yi)Y5 z^8wOSkmd;}x$F=CG0Wz3zj;@$(z62Ooa6CCmT*K8pO>m;SmEwzm_C0!n{ehz_j&)k z8mlJC{kB`RRDWu-IoQcd?aC^piwG6yx)9yyhQss>QkIt1B+w8|E^+~cq9YR8GltxQy9u)M29 ziOClGQ_y(#5nO9=JMXK?pf_Q6NUoI=v04TdoiF6Ix_=!s*mg24>TzhRYdkk9KwSB1 z3|4Q!^ElUi`ZO(pJJwzlAc3l0ydAf^o?wT zYHX7H-V!k>o`rM@>g(Np-m>8gPN=hx-Ol>dgK<|aC=XZMyTLDe9(*#zK`k9^U*{h= z0m&WL(|?9Kems9TZ!iZR%sp9%TvVLQIarEy@4|1wLF~z_bbeJQUDeWY26a!0u2r|c zjw}RJjnu8(ncclQxQMG_eYKrd=G1~Lr3eCXIz7r%fP;8<<=>uCIn!+{)hvOeeGv3h zs(qH8Ey+yh5yiMY8CH4I{-rFHx1V*aNqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_v1_0_0/00002.png b/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_v1_0_0/00002.png index e1a0c89386f78c06d8fdd74723bdca2d13016e34..1c0c2cf17b570d33128971ac78b095462f5eb36c 100644 GIT binary patch delta 626 zcmV-&0*(EI1&alcB!5y#L_t(|ob8%Xa>O7AhHa-e@%~53UHXuz;{YNmO0xaGr)(mK z7=h@f1ONa4006*ozPuD&*OgMrIhSkl^S-tSwpwnob8B~9zP%I?*B5*Td0iLpVw#+D ztoKt&KPNk@ePgSDHdUmWEw-rDT?SIREBx$sSGS1Sz=xn{Y z-M~^Z3P)ogJ_tgy92m=2gI@|PwGXK3l9xJk78>c z!UQxq8HfM?;C}^JiocV3T>4#+1FNk*$WTM@hvZk5LMP7A-b z>oImphNqlH@WzQbk$>okV=02AJ7s^#2XUO-6n=+1ozSB+R@#d(!6-icbS0wpLy*@3 zAJVfJtiwxq`^xBqAigB$7}B%YY4{=6kmaT%Y)mP2On(&Pqq? z+OL%{5e?}fjl~=;>L=v~7q_E}ki9?R1ba#!>(y6kpPmpD5ABBLOj*~G5TjB0~%9${+jF-a3zw{`Ab(!n+f%zdQn`N!tB%`2xS0{?2 z|BMr9eQSR$3clsle#&{k?ac|V*#*ldF~11pDHHH-!2|>op92chx$#j+^?h``Mh;kp z+>I)z56^`B6k$$Kkp+`19#yt3000000000000000000000N^wE1=sU=_w3`#e*gdg M07*qoM6N<$f;P7#EC2ui delta 619 zcmV-x0+juW1%w5VB!5duL_t(|ob8%HlEfegMV+a+iT6KJ?lOy1TNWUqVo1{etTV97t`dN z1FfG@`n$Nl+IE(illJ8&cPjBpxkc8ZsGm1(=_zCIa+~K0Ab*HM%pa08TSA#?Xlah`lA{2y|6LXXl|X)neEqxkgQm5AC8L0$`dNY7%h4lg9w zS4JlU@g+IOkeoTiO&Ir>D+j$r20I%RwFN1hRls!P#>NN z`CEiJK}8l!viPd9bpZeX0000000000000000002*yZxktICpx z2rAe!M2$wH(P%UpjmG8p6?{96gNR|P(fKD*^CXxAUjq#01)aTD&YYZ~1yn@zg)0$wtAFTV`kHo=_jBwZrY2g1 z4p8lkBA~h2VDOoCta-yg9sxnb@xhFC#QNn(8ic}~J#j%i=|&wQLR%z;Mu2iEPX_`c zfRvR3jwu$`u@tz5vAJ5pd}R@chlLdSvApL zMQ(papP@!^UyMsA!R8(xkPGCv6yB&+^&Vf zEfeOiQ^GivC>E0AK4!r+Rcz2cA(e}<6al7D(sdcJss5Bo(cmJ4-{7>1eNs$JKusrv zD)w&P#}i6F*W4$&yui*qpl1Db%zF2uP@e#Eg-y?$=C&bxUvqw`i%h%(t7Xl`ahXrb zIqy9ypnsvEcQ5{$T*!QCf%6)e)|#-hv6XPBVmS=PZ##JI5FKEQhxJr{u|U*trL z&_7KNk=m*$nwZf{&I0ZP=rNnN_GrPLo{B3K1%IwN=i^f zD!!&1YB1}g!R07@|JrxkdF0{w+u29b^Dy@}Vvoh=ml*${;dKeU(P%XGK$oBBXOhAj z^?&O?z}zDjOb|Uce$pxtHYm+`X+zSsjt~CcR3ZEW5wY~NeU{3UICauZ6&^q{;VnPS zsFh7b?QEzaavVJ6(O$ARsNlL{XZ~e|r1xOHdW7DqsYBs8?FlZb@hHRtxbkeP1tIbZ ztKo_h9Zvmningo(D75mg3N%x^N`?FkRBQ_^V`&3i1~LaXS3`x0+l&67XRK6DWAb!F z=)bFpZB*U>5z&G(XsN@gUxHO5ZPRk`b;+yl4dE*>HPWdgX%YB7{uwBTW{te@7mKd; hzj%C=B!9+9L_t(|ob8-jnj9erg-yQfr1!t1+DjfPV+cp!h*npnhySTA z3W(x`>Y3Jxq9}@@D2n3k{BYhK$I)7QyTNvPT{h6h?Fc`4tjv;7rix*5q` zke@|ymRx_2oT$!gkq^;S>mpZcR?d*QgV+_2BPEQ9Lx1ErEwC>0xb6@pGu^mdS~RIZj`78r;J;DbKVG=0Qvy*Q(?q{Nbw^5u@x6kB3Zdb*Q=t zrwt`5%nrad4}ERbB}-Z+u4ELXp<$p9r&i&s5$fiyO!4-7v=;dA}Vcz{6 zfZXorCfw?*`6r8}KCuHV_(^%?Q;ahg`8|;%=zwrN@%KDd$@FJ6OpB_wp@ba6{HXJB zw0-^HciVpC;pexjx1`rG_cvmXK({n)z1+D3s4qF+T%ErD>KHz-5>|xMDdQs!ZIT^e0EgO7_&R9=3@6cQw9`(hDG? zT1h57br|_eGHZlBO($QMM%BF`{7$A?I<+ND!ms0>K{_;Z)r-F@4z=$#Qj4M}if#M` X$LH>;hxxN*00000NkvXXu0mjfi9hld diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_v1_0_1/00001.png b/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_v1_0_1/00001.png index ef7366d45cc9ca2bbb546b582f1dd444b28e7b18..9de81fc3f71783b90b06b80d21de2d35373da8e6 100644 GIT binary patch delta 1029 zcmV+g1p51z2%89yB!A*bL_t(|ob6m&lH4E+B&poQ_dk;Fk`GrXqDQNRvB%y~e|ZKW z3B3S~cUvnI3WY+UP$(2`$1iVS-}lzqwr%~nf1F0=qq&Vkyp&PNRg`*SpXJ%1GdEW; za?tqAtFpxU+ds5nJ>yVQeiBT;C_raEp|eoZ)bRM;T%AeZ@qdR@0z|7IFk?-}$nlJ$ z!_-8J(1EEVQJ8O3n@m1$Xf7Z+f(-DiKl*uGA!GgNOzIOwID6tiKA9ox@kuG!b9B_! zQ=>5%(3F({yAUVqSO{LjIdg~U-VH@2ci;e#p`P|0nTeA*OM>_Gs64jX6`IGJu&$vV zcp9EKyXLtJOMh+AI`}3ec2Fhgz!4pN^W?>c`z_#UrW$r$Rzq(S7HaFz(ZS&zLxCFZ zJs=Ba!QSZ&5MRA#U@Xz$riDzO&>xQTi^3e%WWcJca-mQt6z;^SJpgn!JAu~}1YJh& zz#1MWOc9}yfP+Uva=QuME-%hSf(-NwaQ6luDl{3;!GD|^(yTq~1s5^l?bPii)t~U> zlJ{yxC83-5(WD${%qEghgEv%s6V^2(G%MMM8tH{BuW)%%Mh?1C3H}ESE_Xak`!M<+ zNVFoZ1MgRon^*T4caHAiTj6MUAgbIetVSzY|*c_ zeoN~AgwFX7^udepGpo>B5E!|9a4F83S65Haahoo+`v7y46yde`^b*2}cxeA0%qk|q zJ3v3Aq%fn52&@|>%jyRF3TC-C;hk<7GSC{B7k^72g>mG*uEi!K;!EOH@M6vTsGmWs zjdL|yoz9F1oE+H<;J*w%&Sbzzn88Q}CfRq>B6L@yHx;mGk}L}*S7sc*H)+2dOq(6O z8@ffW6sEBI4X;(9w+}B*o@BKUSf8s(kjN5I<;fo!apRLrMAN%^gT-W@*@Rn^KIiG5 zjDLI9vMd8?S6Gb2SGX7A%a>m$6utq}yP>)-)Stnwi+d?}qWN2PsyzkzLRvBAWGS`; z+_PGF7{LvnaH4ny4HM?=eh74jQoDEJUlm~J4%*cdM-JklC9U8w3|V!Hdx0M= zZSo!2E2gY~U= zNCWk;`6{sN7+RRaBmP2WE#4CQg+ifF_;&mSQTz2aa?l8K00000NkvXXu0mjf`se$u delta 1025 zcmV+c1pfP*2$u+uB!AvXL_t(|ob6m$a;z{6bW*tq_dgPM$p;meqovhefMG`cMX)T% z+H7lhuarb0kw_#GiA3UZe1Wlj-%Bamw$$A?1w=)h0l=E=dg}Yo`on2dCyH?P3IfO{GlV@pT}sv*ZMF5( zC}ai{Wo5t-W2T5P;ME&5cbMzdN@Q}!4iHHyB!y%elQ~O*_w>D*Q=70ZqaH#Uua0A4 z9%C8SwMFa58-I{k!Iq!{M_SeWlhh#GZ+V6-{6- z8j{;Z@b+G@EekTxGr-*&ywz(mpo2L#q*;5`2rgp6+kaiR8~%z9Xe58oZ&XUXa!XPa*qIExnNC6)sOo%RyHv!T+Ga<&KAGA4dNJeXWR-!26Zt=GA@1 zovnNL7W%Lw*E>K|()kcOpo4umZn;RVcK}&l?}ZuK+Q(#7nOUZEzhoT-?dm*?sKhQ9_0XA^rNj`I`w~r#_b#W;6ZrL zD)bZtMou4`idpmO>e;>#ZLcw5djoTn6yf#wwEp2lJhcA@vx;$$4lrH9i(p0>5yD#@ zy-C)q8}KXU>E48Qx@8zbYhd0gfe6Nt`?~&`kbj78h$q4eH~eRP2C>#o)J$|bYYtij zPLAFT;9rJ+4rag%%wQw~lWe+a5xS*OI|^7dN!AN8S4JGbH)%f^WRD$v8ybF6$Yb}r zU8_QGZ$6uxWVH~XKBtr*ks_kXlfN?Jt|ys=rg!xQi^*==gbR^D!^AI+%hs|c19D4P zkAL;IxJTiW*PciuJ_ppdp}H?rpTWk9+bMXW`CB&Mo&tR#trc^!6k7uBSuH+{h*P}Q z22T{vpeMu6<<-EQpWz|U9qQe^`~Ir}0Nq48dt%GMdzj%CvZ@yM0-sse;5|U3t!TP| ziQyMf7hEQA&EdZsWtu4Aa^kO}&C5DzCVIWp-nB6<>1__0WY_p!BhG-CbbiX+_%7?0 z-p|udR%Q@nR)y0muI#rX2Y?>3s4aXGnEVp7SQS=C=`Dk$*|7wN-jit8srqURoPuuG v;YKVwh9<`F68}PGAs!U_i9{li_;maN2O{wL6lwLK00000NkvXXu0mjf!mjzZ diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_v1_0_1/00002.png b/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_v1_0_1/00002.png index 2d97537687559bdc2c2a653c12f9b853680affe7..915dfc2726af6c8f5ba6ff79d66be5324e6930ac 100644 GIT binary patch delta 759 zcmV9!hx%*$z-AfBA>$->PxSwi!` zSzKA}MhL0N$72B@D=_8jO56r3`4>?l!QCnvn0rm{k*D0WJAcY4=@HGE^m>SMxm3IF z@M*33_>D-{tAAZrIhkA^S^aK5mOJLrMSV@f+PsADnw+x6oq}!y)JU!Ygu3HSX)ubo z#5EKv9+{Cgs=#U=~DU5fH{DF0<;gU5pNT3+-j}9<D*) z;nARoue!5D=>o2=2``()H5d1{COxsjk+o`ghyn0xWqpl0 z>1dsh$(W6SawB?ge&y}SjD`$wAS+g4Nm3dkXQ{g3E>wWx7;w`Ae_922nFPZUNcL@8sZV`~0fKL|Jr7-%IoVJbkR=^l2rWlTi+s%h4#848 z?J&S?eJ9gInJK%ApVl@>NS3k9G@n_sh)pLzGjJ=l+b2itiQ1vu;HKVYfK~<#2Kwr+ z8FXPCZ!^HU7+`WjyfxWjfS}91hW}RrP)5{4?mzEg|4XFyyf}m}dGgW$a{gx@S%?-TKjA}24QI8~9g7vva&RD*rI{gUha{*+<&w?OJ+mNfp99IkKiY1>Gi4BOwMTG#(5}BS#1V zu3oX?$aJ((wLN0PYw97Wa8g;1G}A1N+8Nx^xaKQ>JV1w055z;kmZ{5BeIBOc&*~8~ z&>@_;!+kzKL4OUZ=PfQ!wj7ss=HeG^%I zD}RLX8EsmVuUvgX2>EWHTTpSOGcRP`DK9^HNgFeVliqI*)oW#(u!=hty@K>-tHKj5 zKk;pMiX2^t>pkJJ8LoD5eQ44%Rv1~RwuhKU{92iQ1%KB2u62mQpYAu8DWp$-ybGF+ z1|@pFY07EJkIKGsl)eOVcgAA+s|rfSB_IV~)FX1F-^5e$beOmhrV|9m!>pmvbhOTW zdX66lgb}?rrzKVdPYr5-(^#=OkL0Dx5M;XHT>vK>Ts8_hW=IV#f9X9I#fs_G)Z^;D zMKANLMt>CcsO+0=`yZYKI!ZlPnGr3InxV;28XC%s?0x1zJD6z$(#n!3L_jKwOdBla z=;aL(Tl!Nx6Yy9Hl6~7&>Qf(L0pJ^L&qKG$oNQ>7AWJ&95L%9whWyMBIKfgo?J&S) z{U+0d%#>Z?PivbbB+J-ln$N6R#3m2W%u4O{$!sb1gy)nS!qj61Xl2k~L0|ndgD$M& zF$1hS158dhZ%uX>01Vl$;r}ZUAWzgo?my44|0Uu*FAm`g-vOV+#~i}lERAf05JCtc lgb+dqA%qY@2qA=!n17r|8$|Nf^O67n002ovPDHLkV1lbUVRHZg diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_v1_0_2/00000.png b/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_v1_0_2/00000.png index 0c08224ff40aba010fa253cafe1604d9e2bdf501..200aa589375b20b044f90d4bda54df2b72fce72c 100644 GIT binary patch delta 993 zcmV<710MYC2loe%B!9k1L_t(|ob6g$vg9BLb*Ao4vi~JzFY}SQ77d4oXlr*3=gZgx z5DLA~W=+lu*L0teH&$D}M*Ix}cO zVHqwk1r1@?0h+xo0)q@Emw0&oZETJuVk4+xZ_Fp z{qTGyBP!DKHh(UT5mUJ`n;R#&=15yBJL%as4g&*qz$hXvfoG#ewxJ-H7j&d{!AKv= zXECYs=d>}%F7!_kws(s9=lJ;6WLncr}#LafirGJUb719YluIWM!cvc8mcfQhU zxA?MQEK-V~kD7fUPov4YAJB9Z$yNk3cY=?tT#o)G{qT4Mtfh%#>Wdh|XoqWZC4G0x zMEpgVYR1iAK8{AC`!kVr06b1v3|_CF8`-1A1is$+$6KvZx6#~^<^wsmz3pMsqLCg&im#oJ3jwB+B|HA+5jQix|9G$t$TlAGsz58769AO`>*V zX3DIRm;u~VTKCi-cK0UigKCs^12qUk;?Pe9)Iv-PH*L%)=K&Rn!;MPWMjh(HMxbqX z3ab*1=ZB$85`oqVo$)kvNgvovTqzn>{+*SifqyBH;y^D*%bt-+-TjM^>?PO?@?dPA9l>Hh5KdVST~endGe*4VT5kGqPT)A2Si$)K}zF8CQKSyIBRLw zfJ_1t`6bgmHyWw<0jdsdA zQh%y_Bect4sOM0VawuhQ%I|JdbK4!!z01RvQSdG(e{~nQYT;{cK`?S@3~HT7w^v2! zp}0Oj`lpXbiA4M4@^3X7!w7MQ?*Qm(R@1xP&>?fX`pma3w7xonbgIz}ZO9I;hQ0%! zNN7zuj&xlhjg0QN!$voOM7(pbs(DNG^#)C(?eA>$(3Ha#mNTfq*TFg zE&r-AL6LPos_Qt(QiSU6gdA*KuKmr5;qei$woRPb6EV(cg=?}W^mWTb{6WkXEJ zqtVg*o=hD{Hv3eviQ~rZ))Jz=PV$3OrJMs2xg{+}mD~dJf&N;N11uc)tuqI#*--p4 zu+!W{bAPdeior?B`zI;ypG10p!I`kSw316w_jzQQ7!;V;16vxc6?13IDvcS`Z_28k zg2wK*sn$WQmbic#1ZW)k31Du-tl?%|cP-~p4T$58N?Ar7s=`LFK6eh<3CHupP$r3B zl|pAC%|k*LxQHuNt2=)ZCEKVek#nFHWM$9DPJi9~i;=7)V1e<$?nbVqHdzM(;Lg}- zu{k;2G`kk}Wa3ygl(Rhfa>?ol-L^z=6`=q`N}j=%;2={?8rE>O(k{Sl1B$qoUiAqU zJ{5Dr1VSLtLSE*{~VJZMcQ4~dSh<~qDbd8AA$N2yN002ovPDHLk FV1lE4>vsSE diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_v1_0_2/00001.png b/tests/snapshots/nanosp/test_register_wallet_accept_sh_wit_v1_0_2/00001.png index 91a9f0afa436c3feccf439cffc0b700b15b0c5d9..a2d186809dc864a4a99d06fefa6f1a7262a07e51 100644 GIT binary patch delta 1048 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 YV-wP<-Xc(yuK)l507*qoM6N<$g5X<>oB#j- delta 769 zcmV+c1OEK62AKwsB!A#ZL_t(|ob8%jcElhEg>6rFlKn3!d+9^Ycqrh7sAFt z01^MlltKt0gb+f=az65+=XsV=j^n7;^=BVdiK|MQTgG{ws)4{USEg!6@;Tz}c=V4K zg9e)OD;r1v0ms|LS&BMqjzE1X}VkiLUD_eUc5ZqkmATt)Y>3Kx*GII*Z#Q z07O$ZxZV$=Z=+CECEW;v;-+vo<6Q~idI)5aE>$|GplU!~bYw^0BxVhTrd7l<-rDKK z_6L}zlHBfqR>%$k5VI_v?ia7>Aw45N_Bn1(W(a2_@qQ_E!wPqI!}R{^S%fRsbYIuc z>t^VpTyMKgOMjzwHU}$t>%Q{JuGM(n13M1PjdQ?V^66i3g_j)&rWktU_~O&IEI-S* z!@D&3H%6ZjLjD`mc0ss6RLn+A-OubwK~)2oyW0e*L3(8iT<-SQs#>ulaw`*|43>AT zC^31*K1w?8zJhBluJXRB3_1zBO>(`Qh_y0k=zJls)ql@Hhpm!nS&vg&UE{t{3F69! zIT-!~uV?g!jsc^$MssDT6d`Trr}EO6Nt5rsmG#aHeG!{W@>9%|Qqn#I9k95yt#4!t zOk272u-)-TLlbx?RuUx zy%AwEREX81?kI#}xUl1DnAicMwIFq}ICK9lo_n}eM;`YC1mrWCK_5I{5wTu^febRM zC23y-dR%9~yBV3}i0or&F>ZS9x2&k~r)mSm^m+mQwpBH>?u;;}9GxUt$&$jw8{=4s z`$(1fLM2ukxENu=2)I?YoRv7^Y~smVMnJx8V67fE-CC3J`nhJFoD2x}4q3J{8+{S` zpG-IhlpXfMgb+dqA%qY@2qAqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_wit_0_0/00002.png b/tests/snapshots/nanosp/test_register_wallet_accept_wit_0_0/00002.png index b18a7f9dac53d0afd50bc877aa1b998bdaa595fc..fc56072c49e7bed1425067411b16e4c32bfea72e 100644 GIT binary patch delta 669 zcmV;O0%HBE1+@i`B!7HKL_t(|ob8%ha>XDBhHa-iasNwlFMY_=v4Dt*n&kZ7Lno)f z8wetk5C8xG0002k&X-q5DWwoXj4?lxpVzacVNG(;JeLmF zF-9qUDzC)z#?dg&22hrr_r7uVr997TYe7crL7bRnxDB}71J1JOoYa#j7j7DYZpG4b z2nMLKGY|m)z<-0WB!%0?ooUN&;LXG|{fECAo?!>R1{kPV%#323e6N_Xno=!Al$8_y z%oAiKWwr?Oy%Sj7LMdC;>ZZJqM=C<3+@{ovI9Yhrb)lSG`8QPb#akJL6?uI_8UNY) zwrjJKetJD%{2tKd{*$rdcuL;o8C?ukL%C~v3D=q*WPhFZgYE%kOcdi|SHX5qb=Mt> z_Op);ERcGD(b~;pr!*K57SC|8|EsF3G`FKSA+SQe;53vB8!Y86>Q%1k&3v(zb%=S0eIR4y zz@4ohW`A7_Uo3gU@~Xk_2TO0TUK}vMg=KGwR~Yea^TQtdK<|fNWXM~k7+EVl@}36< zIu(VsLX^^cAi{P73=DL{04G07As@|&56>ECfMaLCFdq>p7BN%Bw6vYE%}1o6GycxA z%;tx{V3wVm5s?i50000000000000000002+LKc1j5P|ZOsL`>r00000NkvXXu0mjf DB>+4Y delta 659 zcmV;E0&M-Y1*-*+B!6;AL_t(|ob8%za>O7AhHa-e@%~5hF8z_IV*wErb(6f$kDcs_ zU!W*#LI3~&0001BJ711%rIbPlF~Xvw$FuY?c_0dnay(t5P!rW#y^5ITSA^{md|b0 zRxbHb^oo}5$RO8ws*^jwC^_bE#9E~ZhX>|s24@3YJG7ik?Zi7Z;Vw$2w}^!BTtsUNK`TrJ9N;(+YuZ{*db_NXd3P-VsnJlKI?u>0-aSff>@BEh8dTyX3FV6=8 zD}Yp#1C1#b=dl#HhjF-ZTRIi+%FYKsRH(3&ikVm}TM&3Cx${#~;yR#3SkIvza2Z^9 zcC>2Yt1Z!GbAJQq6m;OojxP)kBYl*tAJfc*q%|Qj(S+`cv>Klzz{-x1@Z{?#?w}OGXqho84!iY_~oD<_w$eJI!T7h% z)-k9DmY!ohwYvbat!Ftm5v+#0B}DUr@zX)S=@y(aejY1=qyPU?j^>P0pP|!!@-5^oBf}+__M>k zcV|=@7`%&j=TpE^1?ctAqzv&zn5!+2qp6JNdC-Ws$~#`i(cZAb#W1_G)a|=I4bk%< zZ0IwAaI}BvMl8k3?2jL7W;O3p)o3&tjZecj>D0^4kcBN400000NkvXXu0mjfAMW>B delta 1019 zcmVEFkB8<8T+vk0b@-lA zMuDLCgWataMNt$*Q5417`EuU9Ua!{LaUA`*|IE>apeXr@S0OFjRTCScox_shC#dGg zpDAnBy?^|t38%|f4f;t5ao##~;R&0qpHg@;KFw)$@|U;68Go><0y9j`=Wu|a87Lp4 z69=P;W@$4Sd_zCxMuQ}d0LPp1dwO~3{d5@hhH5w~flNGMA%=*umWiPrpt6-^!wD4u z4ZQ3Nby%6i7`m9nrJvL3b!yeoOjuYg*FaT>J<>sa%+UzsNt zVYwwbtxm#DL4PM_WcBrvG$LGYd4aO#y0jB#Z{wJat*mXRZ-aLZn1vtyov`xNYlhFd z4R8I5^d|kuEPm1Z9P*LgFN&i0Y~pNab5nh?#L3AxC827+8Xjn!&+yz?~LuG_f3yW8pd0 z61xjB+j^A&xnS{gsOl$^6Ag2mzUnl%hjCJ;X&cOgm{jK62UyRl<|6#zs~Hia><^EJ zOm20kx(TNZB`eGhz;7P<+GZTtU~4 zUhZ|m#Sgi^1CZMt-Gt+uHUEU13@o150T%qEymA%e%td}r}y`BC2{GBFpXU}cFqmkrOc zjH$yjon!ehUAq4yC_REn5>*YG;9E-$DK;$hLu#tN)6f~_vk|cQAf{4=q!Ei6bHY~| zZu|ql{mD4|s^QJzF4Bqn^8rUmC~$9LJap&)sf<+YT-d(E|9PuFJKTGB)>0kAH?i(~ z5-ddku7|^vA-@Pqv5DkpSjV#5DP&BQ4d0ieynWXfzs)Mx)VaG#VY)M^8*Ptt>6+g ze&eca@&5IV!R+CWhKiFA5!~r2 z3K+`Efw&Zl>sSh0!+@(KMf$GTCmggq6o>#E#nG#ZU35$yq*yc9>t^s?u1GQ5T4 zXx=gCU}`wjCd6rqsiytcm4QW6n|4Rd~7gd++q&YzYFIakY9@1 zZ%kaoZkU`}aF_9PnyRE{U~1)=CJuf)mQ%JQ0l?3fV!6OIFeepM>oef19G}`WO*EP- z_$v99Dj=gRb8A^`O=}diu8lLZ-!SoWen4a5B1*Ms!{OPMZV(i2#$(jaJ{Y5fv z&rQ9i3x6Ior9&tU?VCiIY19N1@%j?VYfmW9ogc$0G)E%x>oF zyGY6@3hVs@S4@TK8%FJ#nsShV*x7OyO2)%M;eRd_Vcy7ave46}mK0_76eKCN6#>8N zk#1)HCFmsb(kgE8et3UPfk;Nr_D6J1)s8!-m?q-{0{a6><22IM`Tn8V5d?b~s?`7t zt7f%+rn=_4opq$%@st_wI0Qxk&<;Xec4+qpqxH<$tYJe11S=_jnejNgGk-Q7BZkkukZGit`#gR0*Po3>qw$}>qs(HKEo}+fUq2BKOizAD=a>_u zzh)zsoDw9{$0~&Xi3i3*rr4xdv0%tb00L2nb3i{V9Ybrrt{t(>vPdg(rSq^Nv>k2$ z%ukeR+VG3wYvFr3@e$QvUsfTCnVmh|=yeV+W+Y8^1;!14o{9d(bJLKTuRjK$AEuX} z&-3Z?pCfW?Amb1mVxFJGb>_QOHvrmYd@Z7G=5hooC)Q%Uuxc9Ili>9 delta 1013 zcmVWWm$a{?(hd%-nm z{!Ur5?)~eV!TQ7h8fu(`lHlI}QeLoG7-?E~mz%va<%uucj(;Fvg@7l|W8{90qr)^q z>(_y)BT=}I+YC-V@2^@w5cv!Uyvh4R<*E0}(}*gHaP}62U_O~4?CF^@lIAG4)-z*( zGhiq$2O48m7BK|eyqdeyxlUdJCwD#oVv>rMQZdcqoCU#0`n{Gzo3LI+JyIEO9gl@^ zYBOwVi`J1>Xn&DFm!O+_TG9RqT9EFyxI!+uuI9};d^X7`NarubX)?XMIJQG z8*WF=fPeI;7dS{yb1yN8?ET%Weae_x7m`+1rsTWo{yN;wE_$H{0LSR> zyOOT2Zx&nsbsQOk2ISN#)F32I?lCxucJI!2!lI3-_q|>oG0xjvjH^s#lVZbyDk}pJs6w0r`eEr9TJv@7h;2@bbVjZS4{Lb_F@S!UUV=W)r_Xd=2Cuy2`Cbq%}M?NObN(yprR=I00000NkvXXu0mjfwj1!P diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_wit_0_1/00002.png b/tests/snapshots/nanosp/test_register_wallet_accept_wit_0_1/00002.png index d283f94fd46f0eba7bd3ab5c99f3fcdc3de5cdc7..76ea889910f94559f6cccba804ce377b46a84f65 100644 GIT binary patch delta 762 zcmVVRE_twuV&}I3F`DY{$weF* z1_m6r6ha6ggb+e*=gYfs97ido*4nPy&uN++ZLPnBx6+Hes-}KW41%`PjGJ|uh2e&q zx&C?@VZ^f^w-p%KfoWeC#&u$mKZuAD&Q?*uoNIcHoYzCMqkr#`ZqY0$pNqI%_p;{} zpH?-;H)36neyz3dOe;r5e>#q}2V3i++*9cFOBna;^d)H*be%v(NgW{Mt_P*XT_gop zC`KIVk#?%~N9=e_5`x4E?aPsBCR?L+1NU?z#@%T(bg(A`&5lkcW`(0b&n{Q3^dXvJfY@CoQq$01&e$<{CHi zktKAJ4iQKNiu>m8t_pYQZwe}X(jafTHK&r_P3y*K%lwF0H1aXcwVy0j&l zu9Y-RRo`k>a&{g|4j39NaB!dOgB{2aWKLl-wt7j&AkN0I2#olqO~hJNpXBr$*LIp_ zM4lECAAd$%(Jy8C$h!kigRAWcq8E9T1ImyO9-?@Wr#T?t-}>Mc{O2h2e3C(?54NI* z_p)!oabxD$D>(9|IoFA#MbK!f-|NDoNf#56Ry1?2NEX&CIj_N0eorvCI293ae1bnX z^f!x9N$K^A@rFA-EQvP?J43Kws$Vp&}X4A0)=9cUbcYF`n zflezSyX)vUzHj60NjJ~+O&AFm@d^O1_px^c^k+e_z|C)mUc%BlQ+jQgKlT4U-#x(z sA%qY@2qAKezvBf&c&j07*qoM6N<$g6eT_sQ>@~ delta 760 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 TUC*>T00000NkvXXu0mjfPmtvp diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_wit_0_2/00001.png b/tests/snapshots/nanosp/test_register_wallet_accept_wit_0_2/00001.png index 795449674900bb3acc2e98507c9f69fa56a3cb5d..0254f586a604700fba05a771a38dba93f485f39c 100644 GIT binary patch delta 1009 zcmVwlU)-~f1r60yxS{Sz^5 zIkcbFX2$Rg(7fL#LZ1)DPjsQsdzPM`i`JU6~PkJr1uxG)QHtFuFKU< zJPsP{&StR$;TR5p=C7-R(M-hQa<3Injsu28Wz?$P|JOLd4JZ2h<*M07FWj|!Rv2tn3lg;p!DghX53iOmjd z2$m>%Wcwo9@yJ?!67x0>N!T?5R&A9Ni9{l?4;xoO9DLE{KH*DMzQjaUS@=rKAT>Er zN*aS!JqBZWU@WmkmT`2gg6s(p6(aQ#wyM}0F%obR{C}cnvDge$q&;!5a8AS;$Ak>; zg!x9XNYfS!-VC@XLnGPof-1CfBo0%w%FU$sc|ZU>3rvMXS2&MEY#m`+ zZj3_i|9_b{GkjIchkL)`u^6QH4z>tCwbuI z1VC(BfZIt!X@9$NCv2!RJ{T!%1Ibyl*p?mKnSX;SMAp_2PM(hriW9LMQy*pp$UhBW zKH9;UgeDxMQN`qNdqDxHqWdyu+abPV5zq2M{1VQRgA6L1i%l-NoCrbdWfZp=jB{i9iHX zR0Ixtx`?;99^<92{#qBz6KD{8kn;xr25VJhNc|0?MxGJclp9@SmuH=Pgi z-s%hx5AC#*Ja^vl2BT~u57m%5w=vG_icyTY<)t{rp$=h_8Oeq|jHCaO#PKS+@fAla fi9{li_??H)_?cQ9J&xu)Tr(3#a zWA427xBqCL@gT9e2HXH{*n#8z6661-4IRBta)Auc#*ayK{C_^u2b=)UP$IUwX1pV& zEr<4}<(Uz#0K=Q(g!_Hh`+TZh6ljL)6fuRDbi5;J#s@)@I+87@D;R$yvLn~TxFT0I z@i=I$TgqY!3LzW-&1KsFV;IN9?fz+oWh!8dxji3u45=ir^NL-|HG3S4k0&FSugWqn z;f|x-_xI;<(|9_21FI( zB}f5j!~-abbEUX;6y%gK#B>^evSn(#qg$z=Qr3h==WEYS1o~MDr@z6c#>?eoK&~vn zt)-!KyqugAO2!!1H$UGKTe;0Iy{EN%{yIN?WP$=Aw z{eKf_A;u;CEXXQ~!wlMPa(3qeq!n=?2|2`Bwh+U$8{NBlz@A0&;~02np^R?xu4wdZ;<%qT2e@yNGMu{WFig0)W4~QV3&({ ziA!FxA(-)gnvc6K030L}#R_ZB+w6!nlx4>KRK&*q&t$A+{6yD1u-nY9Jnv$^tqKs2 z?zHnfxAgdcD5uCn6;kI8Mw+-5!kkZ@i_4f)94Faue+zm!&SgVq@Ep?d5vMDKLZMLj aefS5%t5294MdwEV0000HROM_mU4Q7K4D-N9#=Lo-fm( z5fM@8Nr@0b2qA=!?R?>)_kE|7uIno8^5-x`kEu=exQ+Y1)ffZAOqrqq;d{o`CEmaO zNUvj7bF&BKP}8vT-#`X8{%6=q>3wCl5-ij(X2#0_VOki-fF@-IQ&7<^8)Km{mdEP8n!PKJBL>&$ zrJj!BKNdHkX}l?MNk2IHe>+Xu?5 zI`H(C;p#@0F{Y%aTnU?9_ZrZ?h?(aZ`7k)S%NK(?OMk5&u>nE87>9PO{McE}468V5 zf_9(>jHV#)5pDRoF)uNJwt_bbkEv2b7h`DwzeSfA_aeOu{F_8_7Bo1DeG`!Uii#-) z%Ea2dEqViBk5iu{KLzzU?8tn0=oNq%cfEc`j0Kc(L=5T9G{DS1ft|Qa46dQ!-Y05j zy~oO@S%28km@4OaaB!8tzL_t(|ob8%jcElhEh0~tyB>P`d_R@!(au`9p{)A+v_j^iH z6a+;jvu%VBLI@#*r1OP~9>=k5+rIDeEPsw6ow!|Tb!i;OQ4BCJ%$1QIK)z?po%jC! z$M!nrA~rb`4s{Ka{{}K$#{Uc(s=Z&BUI^6W^&~o<&*=jWz<;j7qFZr|eiKaXE~TsJ zUIBqO^?>Dl)BDy7(iLb%(<$y0Zf3l5Lbw(NGN4JqUlA`r7Ar~Bkxy~)T5&@qq4gDhc0GCnUg&9K75VOSo&kxf`Q)4lAU z=gX#vdcPf3t$&r;Y#!|7wfBWpcCU`}UU1@w>9_~ zx^DcR7k_}sQlr!M(!oC`0MDt>X2*bNZpcDJXgHZMxRiHtZ?o(%Fqm4C$#UKd**D=O zj9sI;9GZ4hOA3G3*sU7`v3p{ diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_wit_v1_0_0/00001.png b/tests/snapshots/nanosp/test_register_wallet_accept_wit_v1_0_0/00001.png index 87b4dfa0fcd79dd1870bdc60c0d92e4f4b667964..cc2d012b6709decb341536a534fae2f5468252e5 100644 GIT binary patch delta 429 zcmV;e0aE_a1JMJJE`N4}APhiJ+tZz}|0S`Pet1gL1R^*Ab^7j?6A=(JI=F2B006+# z<(zZQSNGycJ_GA2L%(qSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_wit_v1_0_0/00002.png b/tests/snapshots/nanosp/test_register_wallet_accept_wit_v1_0_0/00002.png index 1507a4c67504057de0f3ca685565a1d88e207125..5cc6b9240d53b472455430eeba51bba9817b6a5b 100644 GIT binary patch delta 616 zcmV-u0+;>y1c3#RB!5UrL_t(|ob8%has(j=MNKL@asNwlFZq}n%YY&(Xgj&*W2ztc z0zqXu1ONa40002C^JP_0N-2a8W6am&_I0f(*phVWr)zUvzO5=Es?XRCGNr_um?p+} zR{J4@pPh}By3>rD$md&bRAQCIZx zF-oXYcvW3*3=Ly!0Abj9?kjs=%JY3~E67x9sCG=#+y>0f0cUYqC*@6)2@efHkHU2w zf&rTB3`76`aDOqHP2sk7SIY7ecz0u({=#2P_izAP159KrR$5VZepF1EO=+eg%FGGB z<{M;T%d8RRb0@I8g^;#v1~3^^rIM?abtACBN%ln{!09L%HgJWj_p<+l$pCm(hv$4;k5T`N zZtAg{CSiIYTfdB3K~6nlj=LkL9?OUP_Q_6wuObcu103d>H6U|EVEG(|)Qw$`BRmT| z^!+oKVeya5^-2H$0000000000000000002sZhisgigp{|ekR!f0000F1DMQNuyVgE~FFa7XTLnR>#5GEw|d}N$h zyd)6j#wh^+00000@Hk(Ab(K<5N;zk`W?!#sPr;VuqJA!I&gMI?F6Me7c95kM*~Bn8 z=Z)S^Dg8X$UhO;2$eBHTl|f}up<8S%s`X3bRz1{*sIWz@0Dp$s#r#LoM$4d~l0DVg znz`&pH7k0WW1U==sdlaar{!3}QA^b!9PU_b7=iOC%@B(uWNZtrs9f4n#;xKTS?B#^uYfuys(<;hORarC+FgOi`?N*}2FO={ zGupS?P8~32tnT4z{gv3_<<#^2WWfGxWsyPS_9r^>ynI&|P!5 zzuqzcA%jvXIoeq#f*9=Nxhw=EH%>+jmLlC7`EKX~umMO_M`}Jxk5Qk+t@L;+6TKi$ zzZo}-Em=KcjxWcS9_t_F*H>Nycq?Kv2*75J*#n3p63hG0TyX3FV6=8 zD}Yp#1C1#b=dl#HhjF-ZTRIi+%FYKsRH(3&ikVm}TM&3Cx${#~;yR#3SkIvza2Z^9 zcC>2Yt1Z!GbAJQq6m;OojxP)kBYl*tAJfc*q%|Qj(S+`cv>Klzz{-x1@Z{?#?w}OGXqho84!iY_~oD<_w$eJI!T7h% z)-k9DmY!ohwYvbat!Ftm5v+#0B}DUr@zX)S=@y(aejY1=qyPU?j^>P0pP|!!@-5^oBf}+__M>k zcV|=@7`%&j=TpE^1?ctAqzv&zn5!+2qp6JNdC-Ws$~#`i(cZAb#W1_G)a|=I4bk%< zZ0IwAaI}BvMl8k3?2jL7W;O3p)o3&tjZecj>D0^4kcBN400000NkvXXu0mjfAMW>B delta 1019 zcmVEFkB8<8T+vk0b@-lA zMuDLCgWataMNt$*Q5417`EuU9Ua!{LaUA`*|IE>apeXr@S0OFjRTCScox_shC#dGg zpDAnBy?^|t38%|f4f;t5ao##~;R&0qpHg@;KFw)$@|U;68Go><0y9j`=Wu|a87Lp4 z69=P;W@$4Sd_zCxMuQ}d0LPp1dwO~3{d5@hhH5w~flNGMA%=*umWiPrpt6-^!wD4u z4ZQ3Nby%6i7`m9nrJvL3b!yeoOjuYg*FaT>J<>sa%+UzsNt zVYwwbtxm#DL4PM_WcBrvG$LGYd4aO#y0jB#Z{wJat*mXRZ-aLZn1vtyov`xNYlhFd z4R8I5^d|kuEPm1Z9P*LgFN&i0Y~pNab5nh?#L3AxC827+8Xjn!&+yz?~LuG_f3yW8pd0 z61xjB+j^A&xnS{gsOl$^6Ag2mzUnl%hjCJ;X&cOgm{jK62UyRl<|6#zs~Hia><^EJ zOm20kx(TNZB`eGhz;7P<+GZTtU~4 zUhZ|m#Sgi^1CZMt-Gt+uHUEU13@o150T%qEymA%e%td}r}y`BC2{GBFpXU}cFqmkrOc zjH$yjon!ehUAq4yC_REn5>*YG;9E-$DK;$hLu#tN)6f~_vk|cQAf{4=q!Ei6bHY~| zZu|ql{mD4|s^QJzF4Bqn^8rUmC~$9LJap&)sf<+YT-d(E|9PuFJKTGB)>0kAH?i(~ z5-ddku7|^vA-@Pqv5DkpSjV#5DP&BQ4d0ieynWXfzs)Mx)VaG#VY)M^8*Ptt>6+g ze&eca@&5IV!R+CWhKiFA5!~r2 z3K+`Efw&Zl>sSh0!+@(KMf$GTCmggq6o>#E#nG#ZU35$yq*yc9>t^s?u1GQ5T4 zXx=gCU}`wjCd6rqsiytcm4QW6n|4Rd~7gd++q&YzYFIakY9@1 zZ%kaoZkU`}aF_9PnyRE{U~1)=CJuf)mQ%JQ0l?3fV!6OIFeepM>oef19G}`WO*EP- z_$v99Dj=gRb8A^`O=}diu8lLZ-!SoWen4a5B1*Ms!{OPMZV(i2#$(jaJ{Y5fv z&rQ9i3x6Ior9&tU?VCiIY19N1@%j?VYfmW9ogc$0G)E%x>oF zyGY6@3hVs@S4@TK8%FJ#nsShV*x7OyO2)%M;eRd_Vcy7ave46}mK0_76eKCN6#>8N zk#1)HCFmsb(kgE8et3UPfk;Nr_D6J1)s8!-m?q-{0{a6><22IM`Tn8V5d?b~s?`7t zt7f%+rn=_4opq$%@st_wI0Qxk&<;Xec4+qpqxH<$tYJe11S=_jnejNgGk-Q7BZkkukZGit`#gR0*Po3>qw$}>qs(HKEo}+fUq2BKOizAD=a>_u zzh)zsoDw9{$0~&Xi3i3*rr4xdv0%tb00L2nb3i{V9Ybrrt{t(>vPdg(rSq^Nv>k2$ z%ukeR+VG3wYvFr3@e$QvUsfTCnVmh|=yeV+W+Y8^1;!14o{9d(bJLKTuRjK$AEuX} z&-3Z?pCfW?Amb1mVxFJGb>_QOHvrmYd@Z7G=5hooC)Q%Uuxc9Ili>9 delta 1013 zcmVWWm$a{?(hd%-nm z{!Ur5?)~eV!TQ7h8fu(`lHlI}QeLoG7-?E~mz%va<%uucj(;Fvg@7l|W8{90qr)^q z>(_y)BT=}I+YC-V@2^@w5cv!Uyvh4R<*E0}(}*gHaP}62U_O~4?CF^@lIAG4)-z*( zGhiq$2O48m7BK|eyqdeyxlUdJCwD#oVv>rMQZdcqoCU#0`n{Gzo3LI+JyIEO9gl@^ zYBOwVi`J1>Xn&DFm!O+_TG9RqT9EFyxI!+uuI9};d^X7`NarubX)?XMIJQG z8*WF=fPeI;7dS{yb1yN8?ET%Weae_x7m`+1rsTWo{yN;wE_$H{0LSR> zyOOT2Zx&nsbsQOk2ISN#)F32I?lCxucJI!2!lI3-_q|>oG0xjvjH^s#lVZbyDk}pJs6w0r`eEr9TJv@7h;2@bbVjZS4{Lb_F@S!UUV=W)r_Xd=2Cuy2`Cbq%}M?NObN(yprR=I00000NkvXXu0mjfwj1!P diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_wit_v1_0_1/00002.png b/tests/snapshots/nanosp/test_register_wallet_accept_wit_v1_0_1/00002.png index 96d456c54569dac68b6d75c0740c66b90a5e0bf5..8ecc1841238a07d6b07376cb92afbb3a647074bd 100644 GIT binary patch delta 791 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 TUC*>T00000NkvXXu0mjfPmtvp diff --git a/tests/snapshots/nanosp/test_register_wallet_accept_wit_v1_0_2/00001.png b/tests/snapshots/nanosp/test_register_wallet_accept_wit_v1_0_2/00001.png index 795449674900bb3acc2e98507c9f69fa56a3cb5d..0254f586a604700fba05a771a38dba93f485f39c 100644 GIT binary patch delta 1009 zcmVwlU)-~f1r60yxS{Sz^5 zIkcbFX2$Rg(7fL#LZ1)DPjsQsdzPM`i`JU6~PkJr1uxG)QHtFuFKU< zJPsP{&StR$;TR5p=C7-R(M-hQa<3Injsu28Wz?$P|JOLd4JZ2h<*M07FWj|!Rv2tn3lg;p!DghX53iOmjd z2$m>%Wcwo9@yJ?!67x0>N!T?5R&A9Ni9{l?4;xoO9DLE{KH*DMzQjaUS@=rKAT>Er zN*aS!JqBZWU@WmkmT`2gg6s(p6(aQ#wyM}0F%obR{C}cnvDge$q&;!5a8AS;$Ak>; zg!x9XNYfS!-VC@XLnGPof-1CfBo0%w%FU$sc|ZU>3rvMXS2&MEY#m`+ zZj3_i|9_b{GkjIchkL)`u^6QH4z>tCwbuI z1VC(BfZIt!X@9$NCv2!RJ{T!%1Ibyl*p?mKnSX;SMAp_2PM(hriW9LMQy*pp$UhBW zKH9;UgeDxMQN`qNdqDxHqWdyu+abPV5zq2M{1VQRgA6L1i%l-NoCrbdWfZp=jB{i9iHX zR0Ixtx`?;99^<92{#qBz6KD{8kn;xr25VJhNc|0?MxGJclp9@SmuH=Pgi z-s%hx5AC#*Ja^vl2BT~u57m%5w=vG_icyTY<)t{rp$=h_8Oeq|jHCaO#PKS+@fAla fi9{li_??H)_?cQ9J&xu)Tr(3#a zWA427xBqCL@gT9e2HXH{*n#8z6661-4IRBta)Auc#*ayK{C_^u2b=)UP$IUwX1pV& zEr<4}<(Uz#0K=Q(g!_Hh`+TZh6ljL)6fuRDbi5;J#s@)@I+87@D;R$yvLn~TxFT0I z@i=I$TgqY!3LzW-&1KsFV;IN9?fz+oWh!8dxji3u45=ir^NL-|HG3S4k0&FSugWqn z;f|x-_xI;<(|9_21FI( zB}f5j!~-abbEUX;6y%gK#B>^evSn(#qg$z=Qr3h==WEYS1o~MDr@z6c#>?eoK&~vn zt)-!KyqugAO2!!1H$UGKTe;0Iy{EN%{yIN?WP$=Aw z{eKf_A;u;CEXXQ~!wlMPa(3qeq!n=?2|2`Bwh+U$8{NBlz@A0&;~02np^R?xu4wdZ;<%qT2e@yNGMu{WFig0)W4~QV3&({ ziA!FxA(-)gnvc6K030L}#R_ZB+w6!nlx4>KRK&*q&t$A+{6yD1u-nY9Jnv$^tqKs2 z?zHnfxAgdcD5uCn6;kI8Mw+-5!kkZ@i_4f)94Faue+zm!&SgVq@Ep?d5vMDKLZMLj aefS5%t5294MdwEV0000({_n|2 z6GTK*y5~3uA%qY@2-(gbT=crG<2cUqtnK>eG*yqOP4>8r>$=n!1H(+2ssZ8e9a~ep zfBtfOj#9ZD*<6z7|4Jo6(&Ja#lL(-l?$Yi6ykR_x-p&>UG-MiCZ4Os7|H9N77(?6n*jleddiis+4ZOa{fn4+o{H|xPP;>`Vkuti#E#}vxo<6U!GAdcHw(SSyX(gPo(Z_=wOqE&0a5JELPXMWGUs3^Z**_B z!ZBgA_X<+EODVD8Y`qDOGIwJda#Kp(;tt6ZAP1n@r2&=@szANLs#m|SbZ2YQh4KW#0e* delta 736 zcmV<60w4W{2KWV#B!9n2L_t(|ob8)ka>XDBh0{)VlKn3!d+9^wGG0J9{>0?A=X zi|u{R$~S9J26Yva-v%;G%KvmLT3TPJt^{iGQ+os)&xttY0z0T z?|{IX<%Fd^wZ652bOoxB8pU10X~a7hgsWj71F9r+h9DWBEOe}nz941?N{3b!N3^x! z#rh)%Qy|R_sF`dp2*fOl!~Nn@J*8&{ls=E=gKS|$GQKaRYFOcJH%#|m&mkEa1w;=GoIPvsPZ~g9|R!>~>xS_h6+QesiXB{#Na+a29pK)4~akkK; zj4N5|+#RALH6lO{G53*GRtER?vSILYvHc@Dv??Dj?SHuQ+phMY&ufydaJ**Y1r;oO zq&IxuxHswA5JGJVHHK0Vt@MQj{4FhOytdMtz`snmyBVCqQU`2sx*V~WJMCb^#W4gN zZs?Qb2cbTSt@lR_y#qka_V=%ev4H9y5krP^6>#HEpeHU9fHzOfdr|hL^;&r~i?7RQ ztLx_f_kSEPm}+#|UOM^bIN&)s+SNWFB{xJNA|ytp4=&}2=1tQZ9ZJ`lAZfcPDK?zd zFX1Noo=Z(;nv%2_VX_0t38?Z}0P_bTAkSCTr1la#yuV2aHbk7q4K~3;9@3hLX-iv^ zwn7q|Qb-@_R_2OZ?4n%Ib1vY5yHV8kEoE%Y6j>IX0n7fZO4%#bswO6tL17AyK7^a- zJ4*u}tYN+b><+aDCXy?iWt22%?DhXtAcPP?2qA(I SJpwfV0000qSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_register_wallet_reject_header_0_0/00002.png b/tests/snapshots/nanosp/test_register_wallet_reject_header_0_0/00002.png index b18a7f9dac53d0afd50bc877aa1b998bdaa595fc..fc56072c49e7bed1425067411b16e4c32bfea72e 100644 GIT binary patch delta 669 zcmV;O0%HBE1+@i`B!7HKL_t(|ob8%ha>XDBhHa-iasNwlFMY_=v4Dt*n&kZ7Lno)f z8wetk5C8xG0002k&X-q5DWwoXj4?lxpVzacVNG(;JeLmF zF-9qUDzC)z#?dg&22hrr_r7uVr997TYe7crL7bRnxDB}71J1JOoYa#j7j7DYZpG4b z2nMLKGY|m)z<-0WB!%0?ooUN&;LXG|{fECAo?!>R1{kPV%#323e6N_Xno=!Al$8_y z%oAiKWwr?Oy%Sj7LMdC;>ZZJqM=C<3+@{ovI9Yhrb)lSG`8QPb#akJL6?uI_8UNY) zwrjJKetJD%{2tKd{*$rdcuL;o8C?ukL%C~v3D=q*WPhFZgYE%kOcdi|SHX5qb=Mt> z_Op);ERcGD(b~;pr!*K57SC|8|EsF3G`FKSA+SQe;53vB8!Y86>Q%1k&3v(zb%=S0eIR4y zz@4ohW`A7_Uo3gU@~Xk_2TO0TUK}vMg=KGwR~Yea^TQtdK<|fNWXM~k7+EVl@}36< zIu(VsLX^^cAi{P73=DL{04G07As@|&56>ECfMaLCFdq>p7BN%Bw6vYE%}1o6GycxA z%;tx{V3wVm5s?i50000000000000000002+LKc1j5P|ZOsL`>r00000NkvXXu0mjf DB>+4Y delta 659 zcmV;E0&M-Y1*-*+B!6;AL_t(|ob8%za>O7AhHa-e@%~5hF8z_IV*wErb(6f$kDcs_ zU!W*#LI3~&0001BJ711%rIbPlF~Xvw$FuY?c_0dnay(t5P!rW#y^5ITSA^{md|b0 zRxbHb^oo}5$RO8ws*^jwC^_bE#9E~ZhX>|s24@3YJG7ik?Zi7Z;Vw$2w}^!BTtsUNK`TrJ9N;(+YuZ{*db_NXd3P-VsnJlKI?u>0-aSff>@BEh8dx7xZO zaQ6d?FngJFheD0*nO_f^H{34ZP1wSDdm~T6{?~o==UnyvFlC&#xh5&YEbyOqvGDSI zHhIRBWk(Aa-S+IBH-DqF^>(MP*Oi;Uo=C7YI#4gTOM2J*8sqd+m+t-hvU0Iqz@NL5 zT@R*DTYpt{#-+J3?UDtTmQ|ZhT$wCzU|(D+$M&tSw`FqchW>KWYq+?>?!U3iZMWQ& zk`uWX^xP?%ah}KbcG-s4!TV+Z=HA`^YZ24V`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_register_wallet_reject_header_v1_0_0/00002.png b/tests/snapshots/nanosp/test_register_wallet_reject_header_v1_0_0/00002.png index 1507a4c67504057de0f3ca685565a1d88e207125..5cc6b9240d53b472455430eeba51bba9817b6a5b 100644 GIT binary patch delta 616 zcmV-u0+;>y1c3#RB!5UrL_t(|ob8%has(j=MNKL@asNwlFZq}n%YY&(Xgj&*W2ztc z0zqXu1ONa40002C^JP_0N-2a8W6am&_I0f(*phVWr)zUvzO5=Es?XRCGNr_um?p+} zR{J4@pPh}By3>rD$md&bRAQCIZx zF-oXYcvW3*3=Ly!0Abj9?kjs=%JY3~E67x9sCG=#+y>0f0cUYqC*@6)2@efHkHU2w zf&rTB3`76`aDOqHP2sk7SIY7ecz0u({=#2P_izAP159KrR$5VZepF1EO=+eg%FGGB z<{M;T%d8RRb0@I8g^;#v1~3^^rIM?abtACBN%ln{!09L%HgJWj_p<+l$pCm(hv$4;k5T`N zZtAg{CSiIYTfdB3K~6nlj=LkL9?OUP_Q_6wuObcu103d>H6U|EVEG(|)Qw$`BRmT| z^!+oKVeya5^-2H$0000000000000000002sZhisgigp{|ekR!f0000F1DMQNuyVgE~FFa7XTLnR>#5GEw|d}N$h zyd)6j#wh^+00000@Hk(Ab(K<5N;zk`W?!#sPr;VuqJA!I&gMI?F6Me7c95kM*~Bn8 z=Z)S^Dg8X$UhO;2$eBHTl|f}up<8S%s`X3bRz1{*sIWz@0Dp$s#r#LoM$4d~l0DVg znz`&pH7k0WW1U==sdlaar{!3}QA^b!9PU_b7=iOC%@B(uWNZtrs9f4n#;xKTS?B#^uYfuys(<;hORarC+FgOi`?N*}2FO={ zGupS?P8~32tnT4z{gv3_<<#^2WWfGxWsyPS_9r^>ynI&|P!5 zzuqzcA%jvXIoeq#f*9=Nxhw=EH%>+jmLlC7`EKX~umMO_M`}Jxk5Qk+t@L;+6TKi$ zzZo}-Em=KcjxWcS9_t_F*H>Nycq?Kv2*75J*#n3p63hG0x7xZO zaQ6d?FngJFheD0*nO_f^H{34ZP1wSDdm~T6{?~o==UnyvFlC&#xh5&YEbyOqvGDSI zHhIRBWk(Aa-S+IBH-DqF^>(MP*Oi;Uo=C7YI#4gTOM2J*8sqd+m+t-hvU0Iqz@NL5 zT@R*DTYpt{#-+J3?UDtTmQ|ZhT$wCzU|(D+$M&tSw`FqchW>KWYq+?>?!U3iZMWQ& zk`uWX^xP?%ah}KbcG-s4!TV+Z=HA`^YZ24V`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPD13?t`U!{kww=+B*Bb>nZ2Yl(O%8x;PV4 z3cXA7Q@dGa(R7xR7f~Fh=Gt(Z0ofSj?Q){0@Onf;^s&=*s(($%EZWU-@*>n>i-(tR zo&lMQ+*f1D{gGATYV(zz#mhtI4wyU^Uz%zeL1V%v1ks?G1=cKQTgpI6&Un4~J->oz zIL;D}KlGH1J+LJl(F(nCmP$=N#Q^{S0036u%d4WGg<`WO%?^aF!^7$MnJn5`?mOLW z2ApKW$D)I7?|%zv{!`B*)}vHjHAhuB`e;-o-6mVE|5F-(qNJrKUMf{`prJO)Mag;t zvHJl_1cb3phHuD3Xz0Eu!NhCVMWM%z*t&EG^mzxke}pMJFrp!GM^H@M3?sBu(3n9l z+d!pxI|PcEV-ZDpnfuoKqBkb}w0aiV=j<=t2IeX=V1FY!FcChF>;q72YV<(|DvgXj z2&JWYJ9mlY;7~U@n696S&_9hZV{TGk35)6=O%YE!@t=16vg!%1nI8!ii;Mnq>-wk? zt>YWxvmRq@_p*|UX>2y~_W^kw_}@F3*K;_E5lz2<3rGg k^SOT?V2N4)002NBKP$ZK_XWKD3jhEB07*qoM6N<$f_v6YN&o-= delta 701 zcmV;u0z&=P1=R(RB!8SqL_t(|ob8-jnu8z=g`Ix06ZgL)_c9O8FewQkV#39q|H)D$ z;TGXwyKMjf00000tj=*9$8n7IVkKUVWu>O?+y_hd`gaE#v~~7<*Hg}qDP`aHba5u8 z6#6aAPwi%zMblYMev9HTHP?pQ49LbHZ1dR!w5JZD!7Fe^KZ7BmOIpg)@_gn?h zaGWI`f9NS2tFR>;*+(=reYIZHVE_OC003~4FRy}vHj2%jG&>Nw4-cp3GFh~>+&bND z2ApKW$D)I7?|&O<{!z~(mZKD2HAhuBS~aSYZj)`-|0xYXQPR>AFWpsgprJI&Mag;t zvF8Cx1cb3ph9Ag8Xz0Eu!Nlv-MWM%u*t&EG^mzxkFT#`)7}1b;A}A(Wye-{m%%I=f zK*iw>fnw%ZL{T2*z9qlt7n3fno<+8t{iWN$TxAAqu*KqOC!vfo78v0qB=-Z#J8RJN4tJm^@Nvf*_|1s*{wFJM0u58 zyKUkcgiO24sTW97u1c7`HPUNg7i&3#UrjXT=YzT-^vxM9Ltf5pxJ7Rr9%tI-^@P%_ z=c|dK$bUQd_itBJQygYMdI(pgN9FcQSPY4sVXNL|Sv7_@{SugnIIsmKf&@zd z002|)n0@av5!-r|4jB1fkSHsr6jATAD6-tj9S!x#=v$|ox}&>>8pL2ND75CHhB{kl z8X1C0|IOf7zKez$%6K(Y7r#OapFu;N=pk$rQ#MOtq~!O7EMM)|*@%@j)U9xb6qJ@NIjIf=0Z{=nX z9|U6PlmGw#005TrHOo-WIi<91Tlp40_is-{t7MSQ(B=;Lo@Gc3ePM1VbIxrO!))7j z@93wLepWVCkDaIIqI~(;I#qb3WQnz?+HVV6b|Tizv=tyw^?z-DB(1lC($7-9*tBM@ zNK~Vur#T@qG*aER0-Pns0*+d%cHywFG}{w19k54_Hj7+nXwIHE$(MJ|rJ z8lyTkJ6Y;}Gtn`V9nk4^nfp%lb@}#OYXuqAf-20@+ybWE1MVegpX?u^rtr`Z^e962 zAsk?`G7td(ynh%GF7qdCmQ}rzH6UZ9u!~oBFP8Q8_N(TqDxG!5%_qD{1BmS+WcB12!vfUvgwfUvPe zaPvK&o~rw|c=s16rwl$yn8kxGV&c_E{qPu>z70+hW`7a&f54(sfyVBG!>9lC!d&!a z)d#r4{h(vPS-2xlJxz8t8&6xagn5b$W&0}TPsR)$HsrMYKw)NqE1K3UXY1_btP;xD zQtKu?o7V{z{0ASrmyjp~PNMc<@WAi_0000000000000000000000000gz*bd({H#t T0XD<{015yANkvXXu0mjf!?yeD delta 499 zcmVF1DMQNuyVgE~FFa7X@AwtM9Mz+(Q^W_*> zTo8yyQUU+~006k0uZ6x!DJi9#bA1*+w`b3XBg-J2q1D-ZFZ3n4zOuHFrIfykX>!gt z_I^s~=i>U>zVozP*w>$ZP(@T~k(i6B|K51yr)pRgwv{tLpnpotFOt?;L2YWauRcd3 zSG-iSqNh3`GA>iyIRl)Qa|uWNstw_^u(e@W9Dr?xwv8FBcy~4U5N*;6A}|G=)TbU{(*Zbe6(O#r#L1}IsQ(8z zohP%Yqr1<(ivG^W7Pfl~_6v(e9Tfe`(a7@508eJHl}rfh?I(oIO@f=x0qs!Tp2elV zcyq|%qlArk&_PUG8L1B*C(Dg=vDkR(S|!Y5HdXBVu)H(paJM3-=LZTK8l2H|&2%2^ot&S9GB?%CSI_3-1PlH` p3_h2TECf!X)?x5K_mlns7!;!(aeT4JulE1|002ovPDHLkV1kqg{B{5U diff --git a/tests/snapshots/nanosp/test_register_wallet_tr_script_pk_0_1/00000.png b/tests/snapshots/nanosp/test_register_wallet_tr_script_pk_0_1/00000.png index 6c7223c002da8b2599323f0c550579fc0c277a7d..8d101dd800357da2984f26b9b23ae755be7d8ec3 100644 GIT binary patch delta 1029 zcmV+g1p51t2%89yB!A*bL_t(|ob6j#a_le&TyX3FV6=8 zD}Yp#1C1#b=dl#HhjF-ZTRIi+%FYKsRH(3&ikVm}TM&3Cx${#~;yR#3SkIvza2Z^9 zcC>2Yt1Z!GbAJQq6m;OojxP)kBYl*tAJfc*q%|Qj(S+`cv>Klzz{-x1@Z{?#?w}OGXqho84!iY_~oD<_w$eJI!T7h% z)-k9DmY!ohwYvbat!Ftm5v+#0B}DUr@zX)S=@y(aejY1=qyPU?j^>P0pP|!!@-5^oBf}+__M>k zcV|=@7`%&j=TpE^1?ctAqzv&zn5!+2qp6JNdC-Ws$~#`i(cZAb#W1_G)a|=I4bk%< zZ0IwAaI}BvMl8k3?2jL7W;O3p)o3&tjZecj>D0^4kcBN400000NkvXXu0mjfAMW>B delta 1019 zcmVEFkB8<8T+vk0b@-lA zMuDLCgWataMNt$*Q5417`EuU9Ua!{LaUA`*|IE>apeXr@S0OFjRTCScox_shC#dGg zpDAnBy?^|t38%|f4f;t5ao##~;R&0qpHg@;KFw)$@|U;68Go><0y9j`=Wu|a87Lp4 z69=P;W@$4Sd_zCxMuQ}d0LPp1dwO~3{d5@hhH5w~flNGMA%=*umWiPrpt6-^!wD4u z4ZQ3Nby%6i7`m9nrJvL3b!yeoOjuYg*FaT>J<>sa%+UzsNt zVYwwbtxm#DL4PM_WcBrvG$LGYd4aO#y0jB#Z{wJat*mXRZ-aLZn1vtyov`xNYlhFd z4R8I5^d|kuEPm1Z9P*LgFN&i0Y~pNab5nh?#L3AxC827+8Xjn!&+yz?~LuG_f3yW8pd0 z61xjB+j^A&xnS{gsOl$^6Ag2mzUnl%hjCJ;X&cOgm{jK62UyRl<|6#zs~Hia><^EJ zOm20kx(TNZB`eGhz;7P<+GZTtU~4 zUhZ|m#Sgi^1CZMt-Gt+uHUEU13@o150T%qEymA%e%td}r}y`BC2{GBFpXU}cFqmkrOc zjH$yjon!ehUAq4yC_REn5>*YG;9E-$DK;$hLu#tN)6f~_vk|cQAf{4=q!Ei6bHY~| zZu|ql{mD4|s^QJzF4Bqn^8rUmC~$9LJap&)sf<+YT-d(E|9PuFJKTGB)>0kAH?i(~ z5-ddku7|^vA-@Pqv5DkpSjV#5DP&BQ4d0ieynWXfzs)Mx)VaG#VY)M^8*Ptt>6+g ze&eca@&5IV!R+CWhKiFA5!~r2 z3K+`Efw&Zl>sSh0!+@(KMf$GTCmggq6o>#E#nG#ZU35$yq*yc9>t^s?u1GQ5T4 zXx=gCU}`wjCd6rqsiytcm4QW6n|4Rd~7gd++q&YzYFIakY9@1 zZ%kaoZkU`}aF_9PnyRE{U~1)=CJuf)mQ%JQ0l?3fV!6OIFeepM>oef19G}`WO*EP- z_$v99Dj=gRb8A^`O=}diu8lLZ-!SoWen4a5B1*Ms!{OPMZV(i2#$(jaJ{Y5fv z&rQ9i3x6Ior9&tU?VCiIY19N1@%j?VYfmW9ogc$0G)E%x>oF zyGY6@3hVs@S4@TK8%FJ#nsShV*x7OyO2)%M;eRd_Vcy7ave46}mK0_76eKCN6#>8N zk#1)HCFmsb(kgE8et3UPfk;Nr_D6J1)s8!-m?q-{0{a6><22IM`Tn8V5d?b~s?`7t zt7f%+rn=_4opq$%@st_wI0Qxk&<;Xec4+qpqxH<$tYJe11S=_jnejNgGk-Q7BZkkukZGit`#gR0*Po3>qw$}>qs(HKEo}+fUq2BKOizAD=a>_u zzh)zsoDw9{$0~&Xi3i3*rr4xdv0%tb00L2nb3i{V9Ybrrt{t(>vPdg(rSq^Nv>k2$ z%ukeR+VG3wYvFr3@e$QvUsfTCnVmh|=yeV+W+Y8^1;!14o{9d(bJLKTuRjK$AEuX} z&-3Z?pCfW?Amb1mVxFJGb>_QOHvrmYd@Z7G=5hooC)Q%Uuxc9Ili>9 delta 1013 zcmVWWm$a{?(hd%-nm z{!Ur5?)~eV!TQ7h8fu(`lHlI}QeLoG7-?E~mz%va<%uucj(;Fvg@7l|W8{90qr)^q z>(_y)BT=}I+YC-V@2^@w5cv!Uyvh4R<*E0}(}*gHaP}62U_O~4?CF^@lIAG4)-z*( zGhiq$2O48m7BK|eyqdeyxlUdJCwD#oVv>rMQZdcqoCU#0`n{Gzo3LI+JyIEO9gl@^ zYBOwVi`J1>Xn&DFm!O+_TG9RqT9EFyxI!+uuI9};d^X7`NarubX)?XMIJQG z8*WF=fPeI;7dS{yb1yN8?ET%Weae_x7m`+1rsTWo{yN;wE_$H{0LSR> zyOOT2Zx&nsbsQOk2ISN#)F32I?lCxucJI!2!lI3-_q|>oG0xjvjH^s#lVZbyDk}pJs6w0r`eEr9TJv@7h;2@bbVjZS4{Lb_F@S!UUV=W)r_Xd=2Cuy2`Cbq%}M?NObN(yprR=I00000NkvXXu0mjfwj1!P diff --git a/tests/snapshots/nanosp/test_register_wallet_tr_script_pk_0_1/00002.png b/tests/snapshots/nanosp/test_register_wallet_tr_script_pk_0_1/00002.png index d283f94fd46f0eba7bd3ab5c99f3fcdc3de5cdc7..76ea889910f94559f6cccba804ce377b46a84f65 100644 GIT binary patch delta 762 zcmVVRE_twuV&}I3F`DY{$weF* z1_m6r6ha6ggb+e*=gYfs97ido*4nPy&uN++ZLPnBx6+Hes-}KW41%`PjGJ|uh2e&q zx&C?@VZ^f^w-p%KfoWeC#&u$mKZuAD&Q?*uoNIcHoYzCMqkr#`ZqY0$pNqI%_p;{} zpH?-;H)36neyz3dOe;r5e>#q}2V3i++*9cFOBna;^d)H*be%v(NgW{Mt_P*XT_gop zC`KIVk#?%~N9=e_5`x4E?aPsBCR?L+1NU?z#@%T(bg(A`&5lkcW`(0b&n{Q3^dXvJfY@CoQq$01&e$<{CHi zktKAJ4iQKNiu>m8t_pYQZwe}X(jafTHK&r_P3y*K%lwF0H1aXcwVy0j&l zu9Y-RRo`k>a&{g|4j39NaB!dOgB{2aWKLl-wt7j&AkN0I2#olqO~hJNpXBr$*LIp_ zM4lECAAd$%(Jy8C$h!kigRAWcq8E9T1ImyO9-?@Wr#T?t-}>Mc{O2h2e3C(?54NI* z_p)!oabxD$D>(9|IoFA#MbK!f-|NDoNf#56Ry1?2NEX&CIj_N0eorvCI293ae1bnX z^f!x9N$K^A@rFA-EQvP?J43Kws$Vp&}X4A0)=9cUbcYF`n zflezSyX)vUzHj60NjJ~+O&AFm@d^O1_px^c^k+e_z|C)mUc%BlQ+jQgKlT4U-#x(z sA%qY@2qAKezvBf&c&j07*qoM6N<$g6eT_sQ>@~ delta 760 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 TUC*>T00000NkvXXu0mjfPmtvp diff --git a/tests/snapshots/nanosp/test_register_wallet_tr_script_pk_0_2/00001.png b/tests/snapshots/nanosp/test_register_wallet_tr_script_pk_0_2/00001.png index 795449674900bb3acc2e98507c9f69fa56a3cb5d..0254f586a604700fba05a771a38dba93f485f39c 100644 GIT binary patch delta 1009 zcmVwlU)-~f1r60yxS{Sz^5 zIkcbFX2$Rg(7fL#LZ1)DPjsQsdzPM`i`JU6~PkJr1uxG)QHtFuFKU< zJPsP{&StR$;TR5p=C7-R(M-hQa<3Injsu28Wz?$P|JOLd4JZ2h<*M07FWj|!Rv2tn3lg;p!DghX53iOmjd z2$m>%Wcwo9@yJ?!67x0>N!T?5R&A9Ni9{l?4;xoO9DLE{KH*DMzQjaUS@=rKAT>Er zN*aS!JqBZWU@WmkmT`2gg6s(p6(aQ#wyM}0F%obR{C}cnvDge$q&;!5a8AS;$Ak>; zg!x9XNYfS!-VC@XLnGPof-1CfBo0%w%FU$sc|ZU>3rvMXS2&MEY#m`+ zZj3_i|9_b{GkjIchkL)`u^6QH4z>tCwbuI z1VC(BfZIt!X@9$NCv2!RJ{T!%1Ibyl*p?mKnSX;SMAp_2PM(hriW9LMQy*pp$UhBW zKH9;UgeDxMQN`qNdqDxHqWdyu+abPV5zq2M{1VQRgA6L1i%l-NoCrbdWfZp=jB{i9iHX zR0Ixtx`?;99^<92{#qBz6KD{8kn;xr25VJhNc|0?MxGJclp9@SmuH=Pgi z-s%hx5AC#*Ja^vl2BT~u57m%5w=vG_icyTY<)t{rp$=h_8Oeq|jHCaO#PKS+@fAla fi9{li_??H)_?cQ9J&xu)Tr(3#a zWA427xBqCL@gT9e2HXH{*n#8z6661-4IRBta)Auc#*ayK{C_^u2b=)UP$IUwX1pV& zEr<4}<(Uz#0K=Q(g!_Hh`+TZh6ljL)6fuRDbi5;J#s@)@I+87@D;R$yvLn~TxFT0I z@i=I$TgqY!3LzW-&1KsFV;IN9?fz+oWh!8dxji3u45=ir^NL-|HG3S4k0&FSugWqn z;f|x-_xI;<(|9_21FI( zB}f5j!~-abbEUX;6y%gK#B>^evSn(#qg$z=Qr3h==WEYS1o~MDr@z6c#>?eoK&~vn zt)-!KyqugAO2!!1H$UGKTe;0Iy{EN%{yIN?WP$=Aw z{eKf_A;u;CEXXQ~!wlMPa(3qeq!n=?2|2`Bwh+U$8{NBlz@A0&;~02np^R?xu4wdZ;<%qT2e@yNGMu{WFig0)W4~QV3&({ ziA!FxA(-)gnvc6K030L}#R_ZB+w6!nlx4>KRK&*q&t$A+{6yD1u-nY9Jnv$^tqKs2 z?zHnfxAgdcD5uCn6;kI8Mw+-5!kkZ@i_4f)94Faue+zm!&SgVq@Ep?d5vMDKLZMLj aefS5%t5294MdwEV0000HROM_mU4Q7K4D-N9#=Lo-fm( z5fM@8Nr@0b2qA=!?R?>)_kE|7uIno8^5-x`kEu=exQ+Y1)ffZAOqrqq;d{o`CEmaO zNUvj7bF&BKP}8vT-#`X8{%6=q>3wCl5-ij(X2#0_VOki-fF@-IQ&7<^8)Km{mdEP8n!PKJBL>&$ zrJj!BKNdHkX}l?MNk2IHe>+Xu?5 zI`H(C;p#@0F{Y%aTnU?9_ZrZ?h?(aZ`7k)S%NK(?OMk5&u>nE87>9PO{McE}468V5 zf_9(>jHV#)5pDRoF)uNJwt_bbkEv2b7h`DwzeSfA_aeOu{F_8_7Bo1DeG`!Uii#-) z%Ea2dEqViBk5iu{KLzzU?8tn0=oNq%cfEc`j0Kc(L=5T9G{DS1ft|Qa46dQ!-Y05j zy~oO@S%28km@4OaaB!8tzL_t(|ob8%jcElhEh0~tyB>P`d_R@!(au`9p{)A+v_j^iH z6a+;jvu%VBLI@#*r1OP~9>=k5+rIDeEPsw6ow!|Tb!i;OQ4BCJ%$1QIK)z?po%jC! z$M!nrA~rb`4s{Ka{{}K$#{Uc(s=Z&BUI^6W^&~o<&*=jWz<;j7qFZr|eiKaXE~TsJ zUIBqO^?>Dl)BDy7(iLb%(<$y0Zf3l5Lbw(NGN4JqUlA`r7Ar~Bkxy~)T5&@qq4gDhc0GCnUg&9K75VOSo&kxf`Q)4lAU z=gX#vdcPf3t$&r;Y#!|7wfBWpcCU`}UU1@w>9_~ zx^DcR7k_}sQlr!M(!oC`0MDt>X2*bNZpcDJXgHZMxRiHtZ?o(%Fqm4C$#UKd**D=O zj9sI;9GZ4hOA3G3*sU7`v3p{ diff --git a/tests/snapshots/nanosp/test_register_wallet_tr_script_sortedmulti_0_0/00001.png b/tests/snapshots/nanosp/test_register_wallet_tr_script_sortedmulti_0_0/00001.png index edbf49818dfa556f8c3f45462e4b8fba1dc9f1f8..2a069273e65ec0f78a66a0ed3dbd8a42a9eac36b 100644 GIT binary patch delta 622 zcmV-!0+IcY1&{@hEq_aP!!QU%)tv6c`(Kjw(t%r-fWSxrSx(*^B^U$xI(kki00000 z007*bT5GNK>MHKUBQVy{^^?co)}#JCAqVZ9ZQE?i{`IhI+je}|jfaI^rT#Q8b8e<) zp7Iu>V47}>uob}OpzN0&+alvM6VYZLpO0vUb2BgVl(*1=J%1H;5xfFeiLzFw<@K4R z(c67mTcRoq9)QL7;;yB}NSYHdTM*qe*~ZE|$1E436%+O3kNg!xw_|3kf7q5H8tmDQ zXuv2>?XJa_H~;_u0Ko03&s<&3FT>~9*s$}MSy@J|^#`C&ity-~<@sPNzZyPGMU%OC z^2&5t8M1-RR)4VbpeEQEoiKe7jI1J zRJzsB3{BjV&N&86L5YUaJmo$!M-!a!M(lND?--u`m|a=eySXU%0Gzhd*a5Y9Cmou` z(we`$k21|)%c#-i?{_}w-hqu}onO$}<2o-zNRS7;uz%E>kavYHmw$%GcAXVao=@)? zkz)foOdtoft1$)>IO$}JK`M)OuSbM9wKJcAU0b^)>AA8Hz52;OVpi={%sym^8IN&WboS#eu7yyNqI-6&hr$fXF{)eKAtpg6P<#US-sd_MuGB zKId?chwvNob#(#bumi`1l>h($000000000000000001<80Pzf|&=x;}vH$=807*qo IM6N<$g2gH@LjV8( delta 622 zcmV-!0+IcY1&{@hEq`5>gD?n%Gd;5t_rIj>=5I*L2-2()!{{p2yY^{9VO@IiZL+csOW|2!nywjCF{@Q~2ERG<1~%1zfy zQ$At@Ox=wUwgT83l>M?}OQfBqBiiia`mkmwH~lhA`3Mcz6MtbB!7G4;C}VX>UY}VS zz1^p^B`U(;0a!d2cP%wW(wvA%K{RQy#L6_sBp0Fu6Seb4z6H^A%!Kt1TT(=WJ?Y3l zqp9oOcF}+V00000Ko<3xtHb$a_#7K+b{;b$%kZ`S0Q8k2Jax_Td@z8^%m)WkjRoMX@|C{a_Irpz;QYJxMqh`o;N9YfP^v&#$nHWvjSfYWvw8Bm*dQlTkq zdhgxJG=0sZMwh-{`J{UX63aSo(AsvL=OV<&gWg!`OMl3_LYK=w!(+S73MkK~_YBLi z1|1@hgWA;?g9)5;GR7d4MZ4EiggBKmoq?>aJ(9GqEJSbpWWaKWX2uxApM+VRQY&W` z@#4!0qO$O56huqs0aeC`mb8P)>1U;s`(j1=>$WYbjFt=`J0ZS6yO zo44|NY{GBM*VO@x!wwu5Mgjl;000000000000000007YV0d#PrqA%VflK=n!07*qo IM6N<$g6obTV*mgE diff --git a/tests/snapshots/nanosp/test_register_wallet_tr_script_sortedmulti_0_0/00002.png b/tests/snapshots/nanosp/test_register_wallet_tr_script_sortedmulti_0_0/00002.png index 071d74207921de223cf91a0a7f474823370155ae..559a4847f2fe73f73bc5b0e75514f39aa0f5d532 100644 GIT binary patch delta 713 zcmV;)0yh2F1>psdB!8$$L_t(|ob8%ha>F1DMb%Ds;{7j)z4Rj!hU$e30^-g+UycEZ zha^BT5dZ)H0002n`N|ShN+F`_y6Q9g`Ff5tv}!Ku=TdcDzOw|esjuV?vXmlK40B!A z+1V$epPkCuxr>aP)vrJ0qOw(~Ma&mf`LePlXNBLSc>qK0-+%Rnw9zu^IBWeX)3RLl zQjLlcb*z(1Bh@hv2-X}6IBKhQ35PpI*(;H`0Iw*~4#x7__<#?_=r-uBV^s*6WOCls z80E-xiq!okabc1dz!`S6{b29g`tn?B1sPR>+Odeb4W!)z&a!Bq^bb)fd}s*zD3-r++(aYp8J*@yeF)Jqs|Eif9$bFIm?0sw*dAn@5th=TXhJEpjS%O`e2dMnYCl zkraMQ(YzC+d4N@6-cpK|i+3L8g|AR#F`JCDK2)acj#hQuhd53Ta}_zPN=HX#f7>ZS zRkXrBb|a5>?SoSkksPl))|T~fog$wp4;cI2SVCrlyPxz9ch6D8BtPC8URbuU?W(f# vPP8qA0ssI20000000000000000Kg!>d5(QY!NPHX00000NkvXXu0mjf;#gUI delta 704 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 delta 1025 zcmV+c1pfP<2%iX$EPtC>aw8!SL>b52r0;*EzKcKFB2X<^3(%6~dLI)~Hx$VZDNk!f zQ4~c{6h(16|D5U0^K7jh$I(CcuQ_@U9%_6wQ$&vQJbR&9O?zvIQpX4;UumK9t$#dd zLsiFDjrG%R#^S^=*SVgHRS?r_{Le`Q1C}Jv(vQRE`WzZKqj16EjscL2bMq2^@mBJ}Ghpm(ToW@5-+0YvL@!7)@jijgN`C{Pv; zsD;wXB^we?!+&LfeMQ{2K;51Fy6W?$rSW?h!Y7G%DS>NZGm;L&R|K8Rw zilX>a*ry=#08SE%31$pV9+Nx~{Yz4o_*{#lB?eVU7+GG3n#tWYkzLHf?GP~~PKK+d zNfk>;H%r(J6{Ya&61a#pHfFVP+LWtbTV&@Y(555lV1IFjiR3##Ys3zir~R7B{}too zg8YKHu=xo+IRd6;0A{kWmJe;Q7ek%lR27Qydudqo+y?APGb2z0Gp0Y+6J4l+-t8eWHf31E0HmFKt>CXt+l^Mh9qDc@osw zMuhX(GK_XAZ#Ye!nK2~W=~+1|l3aq02O!O98J07STW)1*l1>B#T91pN{A{v!4P z)PFKk6vYRF{x)=6{>(eq_|dlk>>MJk5;3R2)3d}HM8VqS5y(s50Y#EG;VuP>;3+lF zvPJ3>>IvT8Gqx*#rQLy@XTyn4a(w+f|Ilzj88rzzypX-s(dGf^Ys>SWk9xnn-M5v#gp5i8#?Lq2uhU vC^z)Qyub~;VeDU!mFm7#q9}@@C_H=vnsK+@ZoAjB00000NkvXXu0mjfCMN0e diff --git a/tests/snapshots/nanosp/test_register_wallet_tr_script_sortedmulti_0_1/00002.png b/tests/snapshots/nanosp/test_register_wallet_tr_script_sortedmulti_0_1/00002.png index d705c90af9583278f755999a9d2b4ab154848d1d..f504291f4fc4439a83d9e9c969bdca33e59864a8 100644 GIT binary patch delta 767 zcmV;_=u^#=POAQ zK*Sg6lmGw#0002k&W}?r=bTcyuB%*^+b~6s)JA_Av=Sia%vvhlC;?GriiVj!6-)Gb zib6yG6k8*X)gIb1ez*Su{v|V8nShi}TKc@M1BoMtBU4^-nSVYR9AOi4;x}MeM*q4l z+RpOa6aA5)s!oiyFr~PyDlAW$eo7gqOR2X5sF&;_mK5XBx1UIJYH&TTuvSw&QpQhT z2h`$q5ezYv%~Sk~+7!BZ)i9Z#WZ7F|^HF%Y%F8))A(ha-5P& zMt~>%0RRBpPIV2Sdp@~`3mmnKvyZwvOl0TRG-uRE40F9rpc=a36R2^0SY>s-u#%bv z^`|b2a?@q_9N6U8jy26to%k3B?vWp||{4BY>^- z>TTL}+@;nxoA$UQZ=LWC7)&3Tr!rVFoi|kHsoGcrdmU3pZ6myk8gCG`xZl-TR6W0| zNin<6?SFuzI{%>djBn3R;MslfbdH;azKTYW(FaSB;a&ShEcO3IMg2rBwaIe;eG+h> zyrO>hXNHbG=#4CrMwy7+N-L^erzcIZT3KnFCAA>C8lHXsJ)WCoEWwR@SLL6Cnj^LP zrTWmQBRb2UhKZUp#=A9{DI8af+cU$mXukd>r+8MIsmuybmY1V@=_+X%RXJOU`qTCK zcloB0DJ&TQwUV6wlfWUn;SHY59|3GE*COt3+jt?lFY1000000000000000007_?{sD!ikq)<2oA&?!002ovPDHLkV1mWPajyUX delta 745 zcmVXDBhHa-i$^Mt*Uiy%!!vG@UC7$&Eo{R?( z715BB5&!@I0002n`EttToKs5Ib(L~?j8T+GRrIHkE@I@I*)XLUWj0iqqG7UGr88O{ z*Jdam?`Y7lTBR-1W%f_N#AG@w6R62k_qodf$B}!HDKEZEYkvlJ*j%6Z4)m?gCLL<2 zZ_fUB5R>7;5T+EHRfVOdX{VHNnsn2*0Mt-c2>8XsBSfu{-Kmr7X~Kp~^+=g6`WB!z zWf#E^lWY$0H~SBEgYF$bSKA(mXY)EGlUOP#+%>H-{&cmCHB{+7gbR1LFX!i7*)*-XTy8)GC?dQt!S})sE|snw)6L*z#&GOpMmZ zpPa_4P3&}wsyvpMvEGE$A*ohQMD{Y+QT~IL+2f$WQh&)bueV*BmF=}*4x-98eX#jx zH23Il8fJ9bwVMm^R0JiH*LTn2tC7^%b}9RfiKL?!VPtQl*a@pOg~kGG9_^IRWGhUf zA6q;o`J)gIK{4&}3zu|f}hy1)j=&CZA|$q7a*zQ zI&G-q*MIZF`G7TeG0#LHaMPG%tie*`^sf3Q>_^_rYWG)m(`7Y*JE(e7RIPgabz~t% z)`&gIlUY5hotwBR7R&AQGA9=#sdT|u00000NkvXXu0mjfrl@jD diff --git a/tests/snapshots/nanosp/test_register_wallet_tr_script_sortedmulti_0_2/00000.png b/tests/snapshots/nanosp/test_register_wallet_tr_script_sortedmulti_0_2/00000.png index bd5a55fcb507062f79991f9022b19984eaf2f6e4..1dd0daa25573497622f4889f8f85788d00e59389 100644 GIT binary patch delta 1030 zcmV+h1o``y2%HFzB!A;cL_t(|ob6j#a_k@sTyX3!W`4r0e*zi+Yky!qkZojQeewFhQ%S?d6SoU!5tcit z1zaW+E|lC_`hRLAy6lc3u>~DC=Ey9bcpS9e;_lQ%<_}voHmeBx0n3?TeTMom1m}P( zkZ!95&=R|NL)ad})x9Wxr#}{p-3irqu7F)fec^nJRv6k6g0NK{F0;nw(pF?Fo5l%GZIDOY;$Zr^jIxWXw9>l0K=RUxC zW|E7*4`0JrF)aS@c!+STs_Q|Lrdnn&2SD~&&40C}3rboct}qHTa%#uAX4&YSB`qXz z#}n=Yz^LJ!3DMM9Y{7wPFk8VVYjtv`q0bj*Ch&g1Z#gFq93NT}+W&WT*5OZT4yX+|VT!o;MCd~4YO&4!Ksl1j-tiq168u7J%4 zF-94JK`eT#8DCM{_y>Ud$vD|7^=5Gw%74WD@gQeOXmBqv9t;3=20C^wY~SRcyxE@} z?!7x3rGdd!tUI3qmR5kQhbm==7h!6)K#qnoR^(125-L@^j-$Qd3l~H7%Tl)Q>KbC_ zL)g$~0^w-?(v4V%mE9jd)?_X3GSz4_8jVlGHz}dT&bR5{z5oCK07*qoM6N<$f{gs` Ac>n+a delta 1025 zcmV+c1pfP+2$u+uB!AvXL_t(|ob8)ilH(u@MVYDDiTA&x>}5V&O(}X_2^_mqI$sF^ zNxb3GJx0?sP17_@(|nvi{?D)1Ym9Lm$NW6M)|f_AQ`8-33dx)@%L>v`(#}kw^_m%2 zah1Q>nAThW_+h;F2kRTPc$i0Jx=X=)S*}mZ1Dw{RwVLT+>&vQ!gLMANa$1X+9E>cF@14bo%%M3!X(=m) z2|5FYXywqf#mXY)g9o;<_gF<{;~-1_1nK~5iC}J!mE>g0rw=q4-|Q;RT< zwVGSmaB6d_wtq#J-7ykN(8)Q!=KcwWLigKBnD0g$kJ-SSvyBt5EM*--!x(~lKo)%X zPn;TFw_6~r$8bX}%18BQvRIc-H^rB=e$zC~*W;anm}oQ8Egi;@Wt^1IwVzGiX&wEN z{>m=)i+K=9Dvd9sIQy-COfD41z0gD%s`a5(%8DV(Lw`wM#I}>wBb}Rbs4J)l~ zspT2j4p1jJ?u?dVlHo9hp{llqfz7f{xX}45%>cDg!gU#GQ~6WqMM7P$af6plRS+^KFGZ0t+Rhj_>Yw?Q?+ z>^uhTAb&ezuAf@i*@E1?=-1#uruDTI)YiNG4XzoZSC@O~*1wZ({X3DZzxhpg7$+@x z(3I)&Iu_nzEwj4-)z+&5s7)4MLuFqPO*GUveb;5=8OD)L%Q2W2G3v~D53oM7oQvR> zuVKs>7Jqm>M6^}a^&pL=T4tCXAnUBQwN)0(X@7;dqA1YFsU7Q?Wutf2XrYKZp70(3 zRy8#Vu3&nXtvvIDo1f(V4v^g5(1SFbv*(|Hi-E-xJHP^8lvkc&oVCdBi5fu%g!_qq z=CN{?pVg!+%6<(k)KK+N%iU}=x!W&AuvGqHu0E1pNBV!np2_!1jK8RQEul9})7%Ln zv40I)W%~@_R)MIBj^#-`#2QjER5OhCCP4Jjjilt*FwxK87x6A)j@W7Gqkc@FFc(U& zG=<&E)O#!vs(Pn$B3I?o{Wn3{B2pw_*<=yDlu z)G>Gw>&>UY(hQLMp(+{Tn=mz75J$s2R^(115-KhDIgR#)6D~&fWGT~kRSmK8C2Ht1 vK{VRm^dc6rvijrKnylqrrkbW{ns4JjOOU~mfBTTZ00000NkvXXu0mjf6G033 diff --git a/tests/snapshots/nanosp/test_register_wallet_tr_script_sortedmulti_0_2/00001.png b/tests/snapshots/nanosp/test_register_wallet_tr_script_sortedmulti_0_2/00001.png index d5b4078d1f4ae62eecf2642d5926adde0ca0f816..585af26510e6b5efc8b0e1b56dfebc9701b26551 100644 GIT binary patch delta 1025 zcmV+c1pfPx2$u+uB!AvXL_t(|ob6g$lH(u@WVhxfzW>`vXcLx| z)B-LO3KzEA+JD+gZP7CA3NuomCFsVTBXje_m7x1AKApPA{IF$pvo>L-uuK}69M&<^ zSHrspWPzA%o#9lmbGrqCEjm1ENco)pYq4%lIKs9Su ze`uF-Mj1-#(GgHJ9AXEOM3XAum|)oz9^OEfDVRn+ocHLj!vzb z#v0WMIRF!a0Bm$Cu2Xij`Ai)l(|O7;H7wsfgLDa6OwaA6f}^Rt{ONl;Vr=e}WI=ADlxf2S|DdTBy3Ee5b2r~!7Sw^xww`; zjKcF_8oT0!4nPWuy+7r_*Ed#X{~xhG1`QlXs!#(&;N*_MQAqdhd?(E22;U6L^R9Yb zatI|Urp~^Lq)bs*KTmM^RH(dR)UK%^2k8u(U4QOONxwTdxJgB*H!_?ow6v)uMVUPX zNlIyj!|z(8n<~EqnM77v`7PFi^-~=X$>^*+qI0OWFB~FG#xXedJCw$0gw^?ekn9M8 zy$scA0EV_^rGBcq>bsqFgx;}~89#9d^a3Cqgt+X`?hi)mnX|{GeVSOqh85scQu@Y& zwtpN&nWs#R!;Dhnadv0^Y&=E`pM4?I2$3j3CpOGRqtR&mQdpFk&$5LrPW$T}e#h|S zhY0(e;QXmJ(vd@gBz>$x_#eNc-zCK+`HDGRRs!G*g*XTF!_qOd=Ih!KTU{36id+#M zT7gU4qC>r00000NkvXXu0mjfTGI35 delta 1019 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 diff --git a/tests/snapshots/nanosp/test_register_wallet_tr_script_sortedmulti_0_3/00001.png b/tests/snapshots/nanosp/test_register_wallet_tr_script_sortedmulti_0_3/00001.png index 3e2e8b443efb79e6b93f62d46b3e9f8a3b8b49af..68378a5a6038534be86fc3f82fc2c8fb164f30a8 100644 GIT binary patch delta 1006 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 v=K&#v5JCtcgb+dqA%qY@2qAM5XH=Yt29AD zRMNqO00000006-0q?A%hyS+GxAH%*%=oiny(X;-$zy^&@j8T{5pG6X5EEic=B=j!T zr*@gLXqsu(O%#WzxjD>s09%7~Tr#?(?ng94hh45qZ;G;Lmw##2O{l{?9u8r=1DK1o zubq?m3DXB% z5~>0Bq$Ap)m1e7z^DPbl0002+2GTdX-PwjRcJY>RtX78J=QKY$0mG$;p3-LcemAav zDmtyACc7Ro+J9qLQB%g=8d}TN46XSTt5mvhsMY=Ey3U;cLv8hOWp3>NhxC*#riU=m z@UqEFHS~$HxCyO-zNmK7#E`y%WiieP^hnD;dJVf|4f9`cF8(v^57bxGY}zg@*= z-4mrZ@jz4y@7%(1yWD&_*7R!SqiGE%Id;d_lg8-=<9|5-L)d2_(9cDXF$a(0I=suA za}|XbzKDsq3OZ%Qx1po3@@KxtFEz@ipP~IJXI*DCC{n%;8YU{~ya>`V@2}48!q*O{ z-_&3Ba$e(W0_r?7og&gSzI@|v03hH~zBBJNVq yf5UYOVksbp00000000000000000000a2$VKQApl;i4%qZ0000O7AhBKYs#QPt~yY#`SLqSz1vY4OQcAj{{H&6cQoSg`Dxr6& zKDEn~o2HqjY@#?!&CTJq0@xgsaVh8$`JAR9+UpQb1`?SC>&*@QZ5@o)&|6~J7S zz8WR>XI78V@b&uQ<)QNc1kc4oOO5f+obX9OG-O-+yXi#iMd000009wh%|w>#TV`rf?d9IKU~k2%bb4#03J!cyA2{_c(C zPerF!)MVE~Mt?1K6*Z;ry{`3a&CnaqW|c}84z;@9T-TZNf2ghAufnYr5D-i0V!8_x z4L>%SsfIpL7I&dn&~K{UG%=*F;8~0d0zJ}-4_^UuOIUx^G!OZj!kz=hfXWBj?J7R& zo+wXi9*An;otrper&~&bu?0g6^#^6yxhj*EC zp`!4@jaZXVL8q+vHgptL{wx<|Q=@$PdG$Z#lyz2zBIWy_VWJY_#nqbT_Uh~|VyytV zQ-9g!ToP*lWS*H$5n)TVjBqbuy_Q+-S}KO85Nic6jFn6Mypu^@GjiKd&K*xATnhSc xgib*WO7EMM)|*@%@j)U9xb6qJ@NIjIf=0Z{=nX z9|U6PlmGw#005TrHOo-WIi<91Tlp40_is-{t7MSQ(B=;Lo@Gc3ePM1VbIxrO!))7j z@93wLepWVCkDaIIqI~(;I#qb3WQnz?+HVV6b|Tizv=tyw^?z-DB(1lC($7-9*tBM@ zNK~Vur#T@qG*aER0-Pns0*+d%cHywFG}{w19k54_Hj7+nXwIHE$(MJ|rJ z8lyTkJ6Y;}Gtn`V9nk4^nfp%lb@}#OYXuqAf-20@+ybWE1MVegpX?u^rtr`Z^e962 zAsk?`G7td(ynh%GF7qdCmQ}rzH6UZ9u!~oBFP8Q8_N(TqDxG!5%_qD{1BmS+WcB12!vfUvgwfUvPe zaPvK&o~rw|c=s16rwl$yn8kxGV&c_E{qPu>z70+hW`7a&f54(sfyVBG!>9lC!d&!a z)d#r4{h(vPS-2xlJxz8t8&6xagn5b$W&0}TPsR)$HsrMYKw)NqE1K3UXY1_btP;xD zQtKu?o7V{z{0ASrmyjp~PNMc<@WAi_0000000000000000000000000gz*bd({H#t T0XD<{015yANkvXXu0mjf!?yeD delta 499 zcmVF1DMQNuyVgE~FFa7X@AwtM9Mz+(Q^W_*> zTo8yyQUU+~006k0uZ6x!DJi9#bA1*+w`b3XBg-J2q1D-ZFZ3n4zOuHFrIfykX>!gt z_I^s~=i>U>zVozP*w>$ZP(@T~k(i6B|K51yr)pRgwv{tLpnpotFOt?;L2YWauRcd3 zSG-iSqNh3`GA>iyIRl)Qa|uWNstw_^u(e@W9Dr?xwv8FBcy~4U5N*;6A}|G=)TbU{(*Zbe6(O#r#L1}IsQ(8z zohP%Yqr1<(ivG^W7Pfl~_6v(e9Tfe`(a7@508eJHl}rfh?I(oIO@f=x0qs!Tp2elV zcyq|%qlArk&_PUG8L1B*C(Dg=vDkR(S|!Y5HdXBVu)H(paJM3-=LZTK8l2H|&2%2^ot&S9GB?%CSI_3-1PlH` p3_h2TECf!X)?x5K_mlns7!;!(aeT4JulE1|002ovPDHLkV1kqg{B{5U diff --git a/tests/snapshots/nanosp/test_register_wallet_tr_with_nums_keypath_0_1/00000.png b/tests/snapshots/nanosp/test_register_wallet_tr_with_nums_keypath_0_1/00000.png index 2cd5813c4bbc7652c57a9bdc7690cf5093a0fc0e..a5f80d7c6d64bc7213cdf1fde41db4d3c111e97f 100644 GIT binary patch delta 993 zcmV<710MYB2loe%B!9k1L_t(|ob6muvLhh~bhq{_pi(7dbBqAh_NEwy9MWYYX8j^b7({N z*4p2x$t}@8e$YhF<)fzZ^gs+AdJeyaV-8vO`iG5y**XZAbAMA$hu3F45vI_i9hCQ> z%9ddfgQv`Jus>cShP?v7%911L?M(DDD=DNw`lh>hPx;|=`KdpzsW$X#?|DKcXs8uZ zV-)%5KOZ`6Om(#r;Kl0@0Aj$uC*zjA-CY4Pb=Wgrh8K>Wjy57wFc*5co3M1~HRWYo z7)#Ur7U&$h41bc^y$hBX9*%cL=zV3Q)G*!yqF_>@otp~Zb<)Sfx%f1}YJ7fi=P?~l zavczR^>V=P;O65)(GGpIg0ah4*=o41eKe&Ld*6T44HoClG-iPe9+o z^4CB&0Xhoct%B}LN;WQAdDGrlOtO|V2cDjgk(Ef@1Gd2AbU}$Q0k^osB&0>uY9-bsF!BR}luR*Oj zw&eZ~uzyAK`Xop$;X=n^Br5?Maowe?;GyDqCo1}PqN0B%boAYK!qEehdCKg1G*dKO z_r31e&{UXl(j4iuQJzXo=4#3#1$>RlW2(}m2}$PGP_F>NORN1T?izAU#g6f5Q#Pofvf`|6Mv?;_CAqyW3y5VuJiyYF34l;*A@g% zbvyxjX6T(v?|&LQ$+#^)*~sj%zY*(nbaa7}G~qIJd=P(m@WAziR=}{JbZ9mDOQI;ItBYIdar-2#$9?1)Zz zlUU9W2ByLg))TOO4_Ls)bz@ec%!(&9AX+w*C#6BnBTkr<<@&vkuLg z&z?oo^dRZ^u>BnIod^}^B*7QOvo_)FNS5*oko{i~Ux{56uTUry3I&A!lt!mLtHCxo P00000NkvXXu0mjfFP`OC delta 982 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 P0000XDBKxwBt$^Ms=z4Rkf%Lt+|J~DUC`AU=^ zq9_^>00000faQE;@8@}n$Z;I$IlcCglvq`|s-+2S+j`FP%-mv)Nfx>?NrUFQ+VFGl zAAg9lURQ}3r?-(gG%))rFUeT>pSa0j!e#;`c|9GjXLlmRSbw`S<*BQ>B#Ypnw%V6I zBU|tzAn>N{Oe(K>e@GZL3TGC!)He1-msG8?GH%dBOHj64Xr;FpxP`ogU_}jNT>Jqj zx$IB`VwQLMQL}4rFGheKz1X;xU~H5WGgOQH@?^p6`>MDJC$8l(?VpW}RrlL=g_)$a zZFYENeX%KKDSt=MGEx}b{2XwX_UUg8>d-cop!Fe!xk~C0@Q_pSajsJ3OyCZPb6rtbQj*$sfAU{d~b?M!=p3h#7MA zU(!qj^fSbF?tI@E1bGB(pCG}`DP{xLpQK+D?N_#?cIQ!XFNyF1icZG+%Wzzc_ZPz$ z?1WWlClx0%22;Vk00000000000000000000000000MqydT4~$bTGa{200000NkvXX Hu0mjf=t1{e diff --git a/tests/snapshots/nanosp/test_register_wallet_tr_with_nums_keypath_0_2/00000.png b/tests/snapshots/nanosp/test_register_wallet_tr_with_nums_keypath_0_2/00000.png index 3641bc0da371aa5eaabfbd599efcb1f56f0f8d68..18500ea70927c6ccf07f0ab947be57adeb9fbc8d 100644 GIT binary patch delta 1004 zcmV`{*waIe}o;QHz+zvD@GZgLytT<~8J*UFHH*fit%(DnL z&gs4_o@XQCB7a?PadVw8waaI7VR<1bv=;{H`}()loS~k|fzf{XlQKpWI89__(H!iwy;6i+H_6hW8>KnM*gsYks@L zilNi+r08K9UihBUe87b%&_Rs4Yn)Wub$2Q$*Tb`@M1M4aq}e`mY36(fX@|@(bWj4$ z9*U})ULLi|zHAsB;3nv;7GF`PQDl7{F?1AXDMAdlLyzs8Prj0RI6eX*GPAv)guaM% z%vQJ}ewXVqSiB=3POulDVqAov--T6`w@f&3yUqlN%V{?TkL%~g?p9MGKHl`>rB?3S z?A!wCv449(Wrpj4{8-|{*f`MJ!5XmUK=H@0gErhWCr^+$*hxlzCmH>n@aV7nA|~#! z_}+Bbj_emfg^t6pW>MQZi_Yvpe7UqTsv$glNsVG8Z?`L{AV~Ss$M_(o4L9w&lZ+D_ zVs@FY-6C(*9S)<_(5BkfI5m?XXf@GDrfEvrg@0Ym<)+0FfTqe|TP>)tkwRmEXIfLs ziwd?ve6S;#167s12^g-}ZnZu=-7*{W0aUd!0i59EYis5&T-m;FnffGIfWIpqN*Z4@ z#YsaO&V1S(=4>cqRC6`EVhdLl;yov~wVu4BUn{?eB@W)T20X({X8$Bfk{>|5BDS{{ z`hP2Lv~Q=%c7|ixPqw_MU;IgHw|nPD3#+k5M#5U8o*){uMkHaj21KE4g^y9&M2YNz zz$4YHPH~GO9(EQ|mAc#TDel$m-=6qS!kXkAFN7TKhyE zaUf2WvosIEKu`5({YiK#2Yk{5GmSg5L}kx?_!D5n2#jERvD`kq7JLlNtpS|@V{OpN znc}x{zV>!Y88^gxX#6C0L`=N)?CjENyYbtI_w%nr>OO)I+?aqH|5wD1;O-Mfk|arz asQd?+ny!r3nWu{Y0000S<+B!9w5L_t(|ob8-#65JpNhHa-e$^DPyUHT(khX}kNxJlab{7PH{ z2!7(swpJ8HQ4~c{6u0wZsdn$ZwRRlGcpk4Yh7eH{Rd*Y`cdC)wFiNQLqr&vL$2-#eD)w`8-MsHoWu_A&=Rrd0^w$1 zhR6s2-lPp4<)-(!7ltUO8Kz%&1+HQ;#%Tlp%45$UJ_QXO^dZneVv`tGWU8JV8nBjk z7jX(&A`$@2Wd{LN&m-@K}0f+K*29k<7lQ6QCa|RGZZaQY zUuib@D^pwtF>0>oq&l5S8cR`eA)*RTn7bo;>Nz%hc7N`HI;QJf0XSPIiXL*g*E+k| z01ebD;Roz)mwa&BYy544$OC|0L!8C*j`Tc_%FHvH0H9EcfgeodN@g zVNIj9bry|z261p{X;e_z9Hbx_$;)vj)rlwl8N)t^Y28hGo@(Yvb}^jh8?T;G^$ml) z+0Y>xOI(^sJZL%5Or&W@#skjga@ArAKobRcEPof&SWlt8@JCt`%aaONpue+wBIgv< zo(+JxVu!`XlsS>r%E37^eLM z8h;`R7k|>q&6dW|+zPhF9=A5BF&+t8p(kKif+-EF@Wd6cybE%kq*i5$I}`DYvx~0e z+RU%GNn)<4D+%KX6aatwGu{Vm&#j6qMPj>2=pc4{@R;T7ME#ob^c%W_I8`n&%yT+A z+?;JE;iVYxdD9tbzcE|n+`w`GfRCIW99{!!RrSk>bs*OoFzEnmgO#mz-noa26JHX5@BUZBJNfGIq9}@@D7^dz&+W5N TUC*>T00000NkvXXu0mjfPmtvp diff --git a/tests/snapshots/nanosp/test_register_wallet_tr_with_nums_keypath_0_2/00001.png b/tests/snapshots/nanosp/test_register_wallet_tr_with_nums_keypath_0_2/00001.png index 795449674900bb3acc2e98507c9f69fa56a3cb5d..0254f586a604700fba05a771a38dba93f485f39c 100644 GIT binary patch delta 1009 zcmVwlU)-~f1r60yxS{Sz^5 zIkcbFX2$Rg(7fL#LZ1)DPjsQsdzPM`i`JU6~PkJr1uxG)QHtFuFKU< zJPsP{&StR$;TR5p=C7-R(M-hQa<3Injsu28Wz?$P|JOLd4JZ2h<*M07FWj|!Rv2tn3lg;p!DghX53iOmjd z2$m>%Wcwo9@yJ?!67x0>N!T?5R&A9Ni9{l?4;xoO9DLE{KH*DMzQjaUS@=rKAT>Er zN*aS!JqBZWU@WmkmT`2gg6s(p6(aQ#wyM}0F%obR{C}cnvDge$q&;!5a8AS;$Ak>; zg!x9XNYfS!-VC@XLnGPof-1CfBo0%w%FU$sc|ZU>3rvMXS2&MEY#m`+ zZj3_i|9_b{GkjIchkL)`u^6QH4z>tCwbuI z1VC(BfZIt!X@9$NCv2!RJ{T!%1Ibyl*p?mKnSX;SMAp_2PM(hriW9LMQy*pp$UhBW zKH9;UgeDxMQN`qNdqDxHqWdyu+abPV5zq2M{1VQRgA6L1i%l-NoCrbdWfZp=jB{i9iHX zR0Ixtx`?;99^<92{#qBz6KD{8kn;xr25VJhNc|0?MxGJclp9@SmuH=Pgi z-s%hx5AC#*Ja^vl2BT~u57m%5w=vG_icyTY<)t{rp$=h_8Oeq|jHCaO#PKS+@fAla fi9{li_??H)_?cQ9J&xu)Tr(3#a zWA427xBqCL@gT9e2HXH{*n#8z6661-4IRBta)Auc#*ayK{C_^u2b=)UP$IUwX1pV& zEr<4}<(Uz#0K=Q(g!_Hh`+TZh6ljL)6fuRDbi5;J#s@)@I+87@D;R$yvLn~TxFT0I z@i=I$TgqY!3LzW-&1KsFV;IN9?fz+oWh!8dxji3u45=ir^NL-|HG3S4k0&FSugWqn z;f|x-_xI;<(|9_21FI( zB}f5j!~-abbEUX;6y%gK#B>^evSn(#qg$z=Qr3h==WEYS1o~MDr@z6c#>?eoK&~vn zt)-!KyqugAO2!!1H$UGKTe;0Iy{EN%{yIN?WP$=Aw z{eKf_A;u;CEXXQ~!wlMPa(3qeq!n=?2|2`Bwh+U$8{NBlz@A0&;~02np^R?xu4wdZ;<%qT2e@yNGMu{WFig0)W4~QV3&({ ziA!FxA(-)gnvc6K030L}#R_ZB+w6!nlx4>KRK&*q&t$A+{6yD1u-nY9Jnv$^tqKs2 z?zHnfxAgdcD5uCn6;kI8Mw+-5!kkZ@i_4f)94Faue+zm!&SgVq@Ep?d5vMDKLZMLj aefS5%t5294MdwEV0000HROM_mU4Q7K4D-N9#=Lo-fm( z5fM@8Nr@0b2qA=!?R?>)_kE|7uIno8^5-x`kEu=exQ+Y1)ffZAOqrqq;d{o`CEmaO zNUvj7bF&BKP}8vT-#`X8{%6=q>3wCl5-ij(X2#0_VOki-fF@-IQ&7<^8)Km{mdEP8n!PKJBL>&$ zrJj!BKNdHkX}l?MNk2IHe>+Xu?5 zI`H(C;p#@0F{Y%aTnU?9_ZrZ?h?(aZ`7k)S%NK(?OMk5&u>nE87>9PO{McE}468V5 zf_9(>jHV#)5pDRoF)uNJwt_bbkEv2b7h`DwzeSfA_aeOu{F_8_7Bo1DeG`!Uii#-) z%Ea2dEqViBk5iu{KLzzU?8tn0=oNq%cfEc`j0Kc(L=5T9G{DS1ft|Qa46dQ!-Y05j zy~oO@S%28km@4OaaB!8tzL_t(|ob8%jcElhEh0~tyB>P`d_R@!(au`9p{)A+v_j^iH z6a+;jvu%VBLI@#*r1OP~9>=k5+rIDeEPsw6ow!|Tb!i;OQ4BCJ%$1QIK)z?po%jC! z$M!nrA~rb`4s{Ka{{}K$#{Uc(s=Z&BUI^6W^&~o<&*=jWz<;j7qFZr|eiKaXE~TsJ zUIBqO^?>Dl)BDy7(iLb%(<$y0Zf3l5Lbw(NGN4JqUlA`r7Ar~Bkxy~)T5&@qq4gDhc0GCnUg&9K75VOSo&kxf`Q)4lAU z=gX#vdcPf3t$&r;Y#!|7wfBWpcCU`}UU1@w>9_~ zx^DcR7k_}sQlr!M(!oC`0MDt>X2*bNZpcDJXgHZMxRiHtZ?o(%Fqm4C$#UKd**D=O zj9sI;9GZ4hOA3G3*sU7`v3p{ diff --git a/tests/snapshots/nanosp/test_register_wallet_with_long_name_0_0/00001.png b/tests/snapshots/nanosp/test_register_wallet_with_long_name_0_0/00001.png index ebf33f0d95ede9658de5ad71e41c592ef734e5c2..eaeea2b42033ea1400e3799ba9aa72054809d9a4 100644 GIT binary patch delta 829 zcmV-D1H$~>2HggbEq`6I+aL^u-A;Fs{V$2V^uco(RYC^=vJt7ihm1o&7JmYco$E@H zBuSDaNs@q+Qc5Yiz1Rk;yKD`bQhv~iOMV+~|8gG$>2=xG&1|2~r~XQ>ajBa>>z>J5 zvXuKPb&>g6Q|Pa(N;QRLZr+;ZltqBU^mba6K|73sW`NfJ)ql|&oT9nTEK~36b+raE zH}A`G$|BTZ%|q57O=r4vTcAG!m9Zcb>6&1_HAMMo zao#edj7&ZcaKxfaXaya!Ei!$V%^jfW^`pgWiqu|S(|=*+6xog#CwXE(v4Fm4%GlyH z*0bxE;WGgHaXZS^qUHlXRzx$XEwgt!;+ThOJdv+ac08F z^?JS30lQ|XUCFr_RW#S@wf}hl<@4`f2V4xg*m(}04!~;>SiZn3q#8p4=jb9i6jIiu zRv&!hyO*_7w7EU!fTR*=4RDYC&CPz2BuVl(5r1|a>ppfn(M{NN#&MIk8TZG-U@h>FeR%DP=LpPHhkR(ZxB%AmPQ%SePmhBj=00000NkvXX Hu0mjfex8&p delta 829 zcmV-D1H$~>2HggbEq`0G+aL^v-A;Fs{V$2V^uco&RYDhpY(%Q>A>$B`#ZAC(=emlb zD2k#eiXtJcwbt5hFSdc|PFn+}v>&+Ql;6hNzuX5&dY!iQFx%(z>A%8jxzx>{bnZ2^4-AQRMlu`mT+Vr(eT!4W}ynRJ_vyq zZA`CZDJluDi<)kx)zIOY zf@+P!U*&@L^-x-%5+)QlY5rj%RaLobsHDpN4D0ydu}dA-ROgZh5hu8+W{0IL7pN5d zv^Z}WQbwH50|Idir7OWO9QR!|cL1l?&lc|~RC{?%hkx-YvWgf-d164JfWBzT*y26b zqwAN!GeGv^b`-5e!v}t-2xpL6X76^C*Y-45MnUI&U3_cfV>t7%a`y9DaVw+IlD+sg_L!v zHHO&u9%b!_Rp;7u4k$W_)`0NnKiupWMNt%wlYe0ovhIWMd@Vx-F%FG0V>Nz|U*?GN zJZu-#z}tQ5o1GW)GAPPsv~v-y6eY?A9f!5R7nveaHBOqM&TgZUx>AH|O7Mi=q}Td* z^&H@HI()1R2ZZpC-$w`g+Xpd6mBPo8S&m6x`p_{1=D2k#eicS0lQ~9j_iF4Nj00000NkvXX Hu0mjfQV)&f diff --git a/tests/snapshots/nanosp/test_register_wallet_with_long_name_0_0/00002.png b/tests/snapshots/nanosp/test_register_wallet_with_long_name_0_0/00002.png index 1ca829c527b8ab1e36c02e9b37de5ebf9bfe242b..6a0c933130d0cd7d976bf74d14f7a59809ba8450 100644 GIT binary patch delta 453 zcmV;$0XqKe1MUNmB!9I@L_t(|ob8!WlEWYfK;50aN$!6n@3J46W*iX2G*Q#O_thc_ zLPTRy0ssI209cTmbIy6T7t<)`o?mF4L#TE9==}!G56;0NS=Vvgwk_47QOdQBGnc>j zJ=6AtWdB?GCmcN_WviIaArZ<|(?U~saU3qqm00qs^*G)N5Px~oaoO=DdYr1E()Hu_ zF`A=XwJS7rm(pR&Lq8vJ{2;VffaqVXfDy_2GqLC`R@Pi19*V3~lhl>Db^=zY#SUFd zP0;&HM8@y+!7M>#(G-PMXr7Zy#Hr?y@aX~=H=${qg359%gynh5k!Wus<)|F+Dov}G z)zPZGM;E8|ihqM?TI>;g440gS7dcWtl}i$Ei6;O60Jrg-n^ogI;OVTN)StQLtCyfD zaAz6p;`FtK`l2@`>$X)lrP>>5q_sL`Re9E0Ir%+c7=Bz%--BAM;~)Rk6OdXron7~! zPJFE|2Y2(~n{Y2;Um1X00V5xQ;MUhwg{%*j`=z>LZX(Pk+z9Xbhqe#E3^LIlMkUll ve=y`=CRCxBG=fYHZiVmylfeNL7u?1_n@zt0yYH-+00000NkvXXu0mjff4Sas delta 467 zcmV;^0WALR1MLHlB!9F?L_t(|ob8!WlEWYfK;50aN$-Co@3J46&9H!oZKJk*@2f== zgowtJ0ssI20I(so)>`XoFP0(aUjMKR06{33!Sp0001&@tK=d=RM%n**~dYYt6ftpe1o< znd}nuZ4LE7Z%nP*R@+p(H_}Y2JEp6=YOUP)JzyGfT<*RHZMDvS{C7`4>D>zr-Gc`4 zZGAbonm6BsM^XFA1oR4+`3NMpzM(4A`e1onst4xgY)rzP@a}(Tdjpz5Ci>HGLQV81 zLk?C#6XDBhHa-iasNwlFMY_=v4Dt*n&kZ7Lno)f z8wetk5C8xG0002k&X-q5DWwoXj4?lxpVzacVNG(;JeLmF zF-9qUDzC)z#?dg&22hrr_r7uVr997TYe7crL7bRnxDB}71J1JOoYa#j7j7DYZpG4b z2nMLKGY|m)z<-0WB!%0?ooUN&;LXG|{fECAo?!>R1{kPV%#323e6N_Xno=!Al$8_y z%oAiKWwr?Oy%Sj7LMdC;>ZZJqM=C<3+@{ovI9Yhrb)lSG`8QPb#akJL6?uI_8UNY) zwrjJKetJD%{2tKd{*$rdcuL;o8C?ukL%C~v3D=q*WPhFZgYE%kOcdi|SHX5qb=Mt> z_Op);ERcGD(b~;pr!*K57SC|8|EsF3G`FKSA+SQe;53vB8!Y86>Q%1k&3v(zb%=S0eIR4y zz@4ohW`A7_Uo3gU@~Xk_2TO0TUK}vMg=KGwR~Yea^TQtdK<|fNWXM~k7+EVl@}36< zIu(VsLX^^cAi{P73=DL{04G07As@|&56>ECfMaLCFdq>p7BN%Bw6vYE%}1o6GycxA z%;tx{V3wVm5s?i50000000000000000002+LKc1j5P|ZOsL`>r00000NkvXXu0mjf DB>+4Y delta 659 zcmV;E0&M-Y1*-*+B!6;AL_t(|ob8%za>O7AhHa-e@%~5hF8z_IV*wErb(6f$kDcs_ zU!W*#LI3~&0001BJ711%rIbPlF~Xvw$FuY?c_0dnay(t5P!rW#y^5ITSA^{md|b0 zRxbHb^oo}5$RO8ws*^jwC^_bE#9E~ZhX>|s24@3YJG7ik?Zi7Z;Vw$2w}^!BTtsUNK`TrJ9N;(+YuZ{*db_NXd3P-VsnJlKI?u>0-aSff>@BEh8dTyX3FV6=8 zD}Yp#1C1#b=dl#HhjF-ZTRIi+%FYKsRH(3&ikVm}TM&3Cx${#~;yR#3SkIvza2Z^9 zcC>2Yt1Z!GbAJQq6m;OojxP)kBYl*tAJfc*q%|Qj(S+`cv>Klzz{-x1@Z{?#?w}OGXqho84!iY_~oD<_w$eJI!T7h% z)-k9DmY!ohwYvbat!Ftm5v+#0B}DUr@zX)S=@y(aejY1=qyPU?j^>P0pP|!!@-5^oBf}+__M>k zcV|=@7`%&j=TpE^1?ctAqzv&zn5!+2qp6JNdC-Ws$~#`i(cZAb#W1_G)a|=I4bk%< zZ0IwAaI}BvMl8k3?2jL7W;O3p)o3&tjZecj>D0^4kcBN400000NkvXXu0mjfAMW>B delta 1019 zcmVEFkB8<8T+vk0b@-lA zMuDLCgWataMNt$*Q5417`EuU9Ua!{LaUA`*|IE>apeXr@S0OFjRTCScox_shC#dGg zpDAnBy?^|t38%|f4f;t5ao##~;R&0qpHg@;KFw)$@|U;68Go><0y9j`=Wu|a87Lp4 z69=P;W@$4Sd_zCxMuQ}d0LPp1dwO~3{d5@hhH5w~flNGMA%=*umWiPrpt6-^!wD4u z4ZQ3Nby%6i7`m9nrJvL3b!yeoOjuYg*FaT>J<>sa%+UzsNt zVYwwbtxm#DL4PM_WcBrvG$LGYd4aO#y0jB#Z{wJat*mXRZ-aLZn1vtyov`xNYlhFd z4R8I5^d|kuEPm1Z9P*LgFN&i0Y~pNab5nh?#L3AxC827+8Xjn!&+yz?~LuG_f3yW8pd0 z61xjB+j^A&xnS{gsOl$^6Ag2mzUnl%hjCJ;X&cOgm{jK62UyRl<|6#zs~Hia><^EJ zOm20kx(TNZB`eGhz;7P<+GZTtU~4 zUhZ|m#Sgi^1CZMt-Gt+uHUEU13@o150T%qEymA%e%td}r}y`BC2{GBFpXU}cFqmkrOc zjH$yjon!ehUAq4yC_REn5>*YG;9E-$DK;$hLu#tN)6f~_vk|cQAf{4=q!Ei6bHY~| zZu|ql{mD4|s^QJzF4Bqn^8rUmC~$9LJap&)sf<+YT-d(E|9PuFJKTGB)>0kAH?i(~ z5-ddku7|^vA-@Pqv5DkpSjV#5DP&BQ4d0ieynWXfzs)Mx)VaG#VY)M^8*Ptt>6+g ze&eca@&5IV!R+CWhKiFA5!~r2 z3K+`Efw&Zl>sSh0!+@(KMf$GTCmggq6o>#E#nG#ZU35$yq*yc9>t^s?u1GQ5T4 zXx=gCU}`wjCd6rqsiytcm4QW6n|4Rd~7gd++q&YzYFIakY9@1 zZ%kaoZkU`}aF_9PnyRE{U~1)=CJuf)mQ%JQ0l?3fV!6OIFeepM>oef19G}`WO*EP- z_$v99Dj=gRb8A^`O=}diu8lLZ-!SoWen4a5B1*Ms!{OPMZV(i2#$(jaJ{Y5fv z&rQ9i3x6Ior9&tU?VCiIY19N1@%j?VYfmW9ogc$0G)E%x>oF zyGY6@3hVs@S4@TK8%FJ#nsShV*x7OyO2)%M;eRd_Vcy7ave46}mK0_76eKCN6#>8N zk#1)HCFmsb(kgE8et3UPfk;Nr_D6J1)s8!-m?q-{0{a6><22IM`Tn8V5d?b~s?`7t zt7f%+rn=_4opq$%@st_wI0Qxk&<;Xec4+qpqxH<$tYJe11S=_jnejNgGk-Q7BZkkukZGit`#gR0*Po3>qw$}>qs(HKEo}+fUq2BKOizAD=a>_u zzh)zsoDw9{$0~&Xi3i3*rr4xdv0%tb00L2nb3i{V9Ybrrt{t(>vPdg(rSq^Nv>k2$ z%ukeR+VG3wYvFr3@e$QvUsfTCnVmh|=yeV+W+Y8^1;!14o{9d(bJLKTuRjK$AEuX} z&-3Z?pCfW?Amb1mVxFJGb>_QOHvrmYd@Z7G=5hooC)Q%Uuxc9Ili>9 delta 1013 zcmVWWm$a{?(hd%-nm z{!Ur5?)~eV!TQ7h8fu(`lHlI}QeLoG7-?E~mz%va<%uucj(;Fvg@7l|W8{90qr)^q z>(_y)BT=}I+YC-V@2^@w5cv!Uyvh4R<*E0}(}*gHaP}62U_O~4?CF^@lIAG4)-z*( zGhiq$2O48m7BK|eyqdeyxlUdJCwD#oVv>rMQZdcqoCU#0`n{Gzo3LI+JyIEO9gl@^ zYBOwVi`J1>Xn&DFm!O+_TG9RqT9EFyxI!+uuI9};d^X7`NarubX)?XMIJQG z8*WF=fPeI;7dS{yb1yN8?ET%Weae_x7m`+1rsTWo{yN;wE_$H{0LSR> zyOOT2Zx&nsbsQOk2ISN#)F32I?lCxucJI!2!lI3-_q|>oG0xjvjH^s#lVZbyDk}pJs6w0r`eEr9TJv@7h;2@bbVjZS4{Lb_F@S!UUV=W)r_Xd=2Cuy2`Cbq%}M?NObN(yprR=I00000NkvXXu0mjfwj1!P diff --git a/tests/snapshots/nanosp/test_register_wallet_with_long_name_0_1/00002.png b/tests/snapshots/nanosp/test_register_wallet_with_long_name_0_1/00002.png index d283f94fd46f0eba7bd3ab5c99f3fcdc3de5cdc7..76ea889910f94559f6cccba804ce377b46a84f65 100644 GIT binary patch delta 762 zcmVVRE_twuV&}I3F`DY{$weF* z1_m6r6ha6ggb+e*=gYfs97ido*4nPy&uN++ZLPnBx6+Hes-}KW41%`PjGJ|uh2e&q zx&C?@VZ^f^w-p%KfoWeC#&u$mKZuAD&Q?*uoNIcHoYzCMqkr#`ZqY0$pNqI%_p;{} zpH?-;H)36neyz3dOe;r5e>#q}2V3i++*9cFOBna;^d)H*be%v(NgW{Mt_P*XT_gop zC`KIVk#?%~N9=e_5`x4E?aPsBCR?L+1NU?z#@%T(bg(A`&5lkcW`(0b&n{Q3^dXvJfY@CoQq$01&e$<{CHi zktKAJ4iQKNiu>m8t_pYQZwe}X(jafTHK&r_P3y*K%lwF0H1aXcwVy0j&l zu9Y-RRo`k>a&{g|4j39NaB!dOgB{2aWKLl-wt7j&AkN0I2#olqO~hJNpXBr$*LIp_ zM4lECAAd$%(Jy8C$h!kigRAWcq8E9T1ImyO9-?@Wr#T?t-}>Mc{O2h2e3C(?54NI* z_p)!oabxD$D>(9|IoFA#MbK!f-|NDoNf#56Ry1?2NEX&CIj_N0eorvCI293ae1bnX z^f!x9N$K^A@rFA-EQvP?J43Kws$Vp&}X4A0)=9cUbcYF`n zflezSyX)vUzHj60NjJ~+O&AFm@d^O1_px^c^k+e_z|C)mUc%BlQ+jQgKlT4U-#x(z sA%qY@2qAKezvBf&c&j07*qoM6N<$g6eT_sQ>@~ delta 760 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 TUC*>T00000NkvXXu0mjfPmtvp diff --git a/tests/snapshots/nanosp/test_register_wallet_with_long_name_0_2/00001.png b/tests/snapshots/nanosp/test_register_wallet_with_long_name_0_2/00001.png index 795449674900bb3acc2e98507c9f69fa56a3cb5d..0254f586a604700fba05a771a38dba93f485f39c 100644 GIT binary patch delta 1009 zcmVwlU)-~f1r60yxS{Sz^5 zIkcbFX2$Rg(7fL#LZ1)DPjsQsdzPM`i`JU6~PkJr1uxG)QHtFuFKU< zJPsP{&StR$;TR5p=C7-R(M-hQa<3Injsu28Wz?$P|JOLd4JZ2h<*M07FWj|!Rv2tn3lg;p!DghX53iOmjd z2$m>%Wcwo9@yJ?!67x0>N!T?5R&A9Ni9{l?4;xoO9DLE{KH*DMzQjaUS@=rKAT>Er zN*aS!JqBZWU@WmkmT`2gg6s(p6(aQ#wyM}0F%obR{C}cnvDge$q&;!5a8AS;$Ak>; zg!x9XNYfS!-VC@XLnGPof-1CfBo0%w%FU$sc|ZU>3rvMXS2&MEY#m`+ zZj3_i|9_b{GkjIchkL)`u^6QH4z>tCwbuI z1VC(BfZIt!X@9$NCv2!RJ{T!%1Ibyl*p?mKnSX;SMAp_2PM(hriW9LMQy*pp$UhBW zKH9;UgeDxMQN`qNdqDxHqWdyu+abPV5zq2M{1VQRgA6L1i%l-NoCrbdWfZp=jB{i9iHX zR0Ixtx`?;99^<92{#qBz6KD{8kn;xr25VJhNc|0?MxGJclp9@SmuH=Pgi z-s%hx5AC#*Ja^vl2BT~u57m%5w=vG_icyTY<)t{rp$=h_8Oeq|jHCaO#PKS+@fAla fi9{li_??H)_?cQ9J&xu)Tr(3#a zWA427xBqCL@gT9e2HXH{*n#8z6661-4IRBta)Auc#*ayK{C_^u2b=)UP$IUwX1pV& zEr<4}<(Uz#0K=Q(g!_Hh`+TZh6ljL)6fuRDbi5;J#s@)@I+87@D;R$yvLn~TxFT0I z@i=I$TgqY!3LzW-&1KsFV;IN9?fz+oWh!8dxji3u45=ir^NL-|HG3S4k0&FSugWqn z;f|x-_xI;<(|9_21FI( zB}f5j!~-abbEUX;6y%gK#B>^evSn(#qg$z=Qr3h==WEYS1o~MDr@z6c#>?eoK&~vn zt)-!KyqugAO2!!1H$UGKTe;0Iy{EN%{yIN?WP$=Aw z{eKf_A;u;CEXXQ~!wlMPa(3qeq!n=?2|2`Bwh+U$8{NBlz@A0&;~02np^R?xu4wdZ;<%qT2e@yNGMu{WFig0)W4~QV3&({ ziA!FxA(-)gnvc6K030L}#R_ZB+w6!nlx4>KRK&*q&t$A+{6yD1u-nY9Jnv$^tqKs2 z?zHnfxAgdcD5uCn6;kI8Mw+-5!kkZ@i_4f)94Faue+zm!&SgVq@Ep?d5vMDKLZMLj aefS5%t5294MdwEV0000HROM_mU4Q7K4D-N9#=Lo-fm( z5fM@8Nr@0b2qA=!?R?>)_kE|7uIno8^5-x`kEu=exQ+Y1)ffZAOqrqq;d{o`CEmaO zNUvj7bF&BKP}8vT-#`X8{%6=q>3wCl5-ij(X2#0_VOki-fF@-IQ&7<^8)Km{mdEP8n!PKJBL>&$ zrJj!BKNdHkX}l?MNk2IHe>+Xu?5 zI`H(C;p#@0F{Y%aTnU?9_ZrZ?h?(aZ`7k)S%NK(?OMk5&u>nE87>9PO{McE}468V5 zf_9(>jHV#)5pDRoF)uNJwt_bbkEv2b7h`DwzeSfA_aeOu{F_8_7Bo1DeG`!Uii#-) z%Ea2dEqViBk5iu{KLzzU?8tn0=oNq%cfEc`j0Kc(L=5T9G{DS1ft|Qa46dQ!-Y05j zy~oO@S%28km@4OaaB!8tzL_t(|ob8%jcElhEh0~tyB>P`d_R@!(au`9p{)A+v_j^iH z6a+;jvu%VBLI@#*r1OP~9>=k5+rIDeEPsw6ow!|Tb!i;OQ4BCJ%$1QIK)z?po%jC! z$M!nrA~rb`4s{Ka{{}K$#{Uc(s=Z&BUI^6W^&~o<&*=jWz<;j7qFZr|eiKaXE~TsJ zUIBqO^?>Dl)BDy7(iLb%(<$y0Zf3l5Lbw(NGN4JqUlA`r7Ar~Bkxy~)T5&@qq4gDhc0GCnUg&9K75VOSo&kxf`Q)4lAU z=gX#vdcPf3t$&r;Y#!|7wfBWpcCU`}UU1@w>9_~ zx^DcR7k_}sQlr!M(!oC`0MDt>X2*bNZpcDJXgHZMxRiHtZ?o(%Fqm4C$#UKd**D=O zj9sI;9GZ4hOA3G3*sU7`v3p{ diff --git a/tests/snapshots/nanosp/test_sighash_all_anyone_input_changed_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_all_anyone_input_changed_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_all_anyone_input_changed_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_all_anyone_input_changed_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_all_anyone_output_changed_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_all_anyone_output_changed_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_all_anyone_output_changed_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_all_anyone_output_changed_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_all_anyone_sign_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_all_anyone_sign_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_all_anyone_sign_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_all_anyone_sign_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_all_input_modified_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_all_input_modified_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_all_output_modified_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_all_output_modified_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_all_sign_psbt_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_all_sign_psbt_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_none_anyone_input_changed_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_none_anyone_input_changed_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_none_anyone_input_changed_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_none_anyone_input_changed_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_none_anyone_output_changed_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_none_anyone_output_changed_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_none_anyone_output_changed_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_none_anyone_output_changed_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_none_anyone_sign_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_none_anyone_sign_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_none_anyone_sign_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_none_anyone_sign_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_none_input_modified_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_none_input_modified_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_none_input_modified_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_none_input_modified_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_none_output_modified_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_none_output_modified_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_none_output_modified_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_none_output_modified_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_none_sign_psbt_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_none_sign_psbt_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_none_sign_psbt_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_none_sign_psbt_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_segwitv0_sighash1_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_segwitv0_sighash1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_segwitv0_sighash2_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_segwitv0_sighash2_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_segwitv0_sighash2_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_segwitv0_sighash2_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_segwitv0_sighash3_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_segwitv0_sighash3_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_segwitv0_sighash3_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_segwitv0_sighash3_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_segwitv0_sighash81_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_segwitv0_sighash81_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_segwitv0_sighash81_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_segwitv0_sighash81_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_segwitv0_sighash82_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_segwitv0_sighash82_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_segwitv0_sighash82_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_segwitv0_sighash82_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_segwitv0_sighash83_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_segwitv0_sighash83_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_segwitv0_sighash83_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_segwitv0_sighash83_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_single_anyone_input_changed_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_single_anyone_input_changed_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_single_anyone_input_changed_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_single_anyone_input_changed_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_single_anyone_output_changed_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_single_anyone_output_changed_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_single_anyone_output_changed_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_single_anyone_output_changed_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_single_anyone_sign_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_single_anyone_sign_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_single_anyone_sign_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_single_anyone_sign_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_single_input_modified_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_single_input_modified_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_single_input_modified_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_single_input_modified_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_single_output_different_index_modified_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_single_output_different_index_modified_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_single_output_different_index_modified_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_single_output_different_index_modified_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_single_output_same_index_modified_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_single_output_same_index_modified_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_single_output_same_index_modified_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_single_output_same_index_modified_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_single_sign_psbt_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_single_sign_psbt_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sighash_single_sign_psbt_0_1/00000.png b/tests/snapshots/nanosp/test_sighash_single_sign_psbt_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_unsupported_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_unsupported_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sighash_unsupported_for_segwitv0_0_0/00000.png b/tests/snapshots/nanosp/test_sighash_unsupported_for_segwitv0_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_message_0_1/00000.png b/tests/snapshots/nanosp/test_sign_message_0_1/00000.png index 04bb6f43c46cbcb9c9891a601782329fd9257adf..7cf2be4c4aa5e21c47c850c802226503be368faf 100644 GIT binary patch delta 677 zcmV;W0$TmL1-%83B!7fSL_t(|ob8)icElhEhHX!G;{KQ9Uiy&J)PsnC@s|0&r`Ay< z7*H7|1ONa40001{^JN{7Qo8<#G1gjup6}HP>_tlHexK$H^m{-EA;w7lW&5~WNMo~e zP03Jk++2V1EV7=Ofl8kDfJ>VgBl`eExx6L*5emEKedH;~r+=hB>3o@zokgCgIZ)4! zsdtlH#oDL2iZ#=8PSI@9m`R@KDVz%+`(P;CFz<6cKWWKF)r?rm^eJy;=tNy1sA+fd zkr01mNTiZ`I$D&XM&R6pSr2${6P6p<;iZzS93nwbUe>cY@C}f&o%^V_Gq?vV#vFns z({scI001DfV1Ey&9XCz!{ShG_4V%E}6mlXD=Yo1*FEXav&FulTlx_32^+66KctDvW zs=etoAxdd;(rq#uc>v2G)3{TlkF)y%3^EFvSY5IPNJad^=G8|-Jz%So9J_yx5Ib!X zZkYE4r@H;A8X4A~24iYie==Bul^_bOq+w*N!BEzlmw)}5S19J`Nz$>xeJw9RFe{tA zVSDOl5$4?|L9}}+;zm>0aw6*&fUSBfkt>3>y1<)QzW^i=Rx_nCAe6%$Ycq2LSib;z zOf|e04(qe7HjX!ELyw3{Q$0Xah$)z?`AV|!CzoF;@DU}RJ-qWgegv<*4FLcE03K4t z-7<8#34gPc)A>61lr-D}lu4TxGve887cn_YWBQREJ63ZE5~h=HVS*Y;;i*!4S_&ER znzAk?=kD1UQVT5B9K9T%nmv`@Nmv`LfoMo7!X2_tzj-;{{ZY9fN9Hn|zro~TN{KBS zdionW0c(M&!2>SQ%4DHN2~wk}sRY$mi~8zHksb;K0000003X3GRPoW>JzW@r00000 LNkvXXu0mjf3;;HV delta 674 zcmV;T0$u&R1-b>0B!7WPL_t(|ob8%ja>XDBg>9!hasNwlFMY@~br29pG{$?rr`9ME z4E~&JN&o-=0000?=gZrmlydx$bCybgo$sd|Sc_81`8~~P7|(!|QqGzD%hm~(kiu?d z$;l)nZtXvL7u`=wLnHTRz~N2KnSBA`TwRj?NKM@9I(ir6DSxR?Dj%U_d(k`UHnj8O zs@atD23)?7u^y|nDmbBA~*ng4yGmz>pI8#lajiX6vWnM%y}mJR zDf5pGnW^-effA#s5d;@uHUn;4g!MwUdFv!=hgeXY*Zu4^+ySz;3vcyS2Iqi>aZf>$ zxw6Fu005x#z<(MbZ8u%>`z=O38dku$XylFDtOZ?xJ;=CDH)jS&l5O|2^+5@wWI(GC zNng5T#At1f+@`Zo2CxhYO;{qmoz(|mP*7N5^^q}v6!8zMtB;0ez*0LocKsY-cG@D` z3GW8Gy7du*jOb5;2{ocW8H~Y`U>16kPLMGMLs=rc?0+x4MzO)(g=9HavJZ;x_kHF|x5>edYWAYm!=PDDebi13vC_LEoO+aIL`1(eJ5{spF;02=@R0DzC+7iJ63Mz=_xwg3PC07*qo IM6N<$g8uqEWB>pF diff --git a/tests/snapshots/nanosp/test_sign_message_0_1/00001.png b/tests/snapshots/nanosp/test_sign_message_0_1/00001.png index 098d70fca69784d7f95018ff1a808513fb6032da..f94a8eb635bdd317ad9c142e65aecafb453ecfc1 100644 GIT binary patch delta 516 zcmV+f0{i{I1i%E4Eq_sR#2^SjZKpT!{zuAP`jKhI0YNlwG@bXpb_pP2G)j^Z00000 zz~g-N8XU)Q{>V975{UD?I)J@6j^nzYo-rJs0V$=Nv-n%p8I}lPQ`rhK856gRU-ZR~ zGh!HI{tP&y$vIa$Ac89;`H!UXUh4Qwh^s{4AHt;hG?bc zW)n?GBu#!pvltuze-0)!4NIM~|3Xq)SxMAB$Aa(WqYd3!f|_|3mz?#-N32x7=71#V z>Jtn;gsU@P;zQUMR?T&gRX@Um6TBa1(~}1Q9)E8*G4eHeSi1`x9)Mwe%Vc66yj@W9 zNMdP5B#wgcA8FV3a}|HeDv(tlEq@372Q$!zI00#)rCimw6f7NI==+I;F&2Q;R#&bB z)2gAO#JF&=de>=r&H(5MzV^h_Ro`CA%u+F?lDPBcpjQ1f z?|%a;fZ%(iptq_kPl5aQ0n8+m{l}=Jn(RLeW3Uodp_Md}%ou!>7o_)2h%e}#f_K7; znfztk6e5Mv=4UBZ%@rE-7C5!g_plo~&Hzn3kNT|NIQ_5YHP3+HcZ~Wi%H}1)*9<@$ zo$;N=V8HzlQIF9Rndd6^k2Beg7&f;%VXILVHuCf+nQYLO0zvzn{ zXT&hb{26dYlXGr%Km=Dx@*kJtn;gqt&9;zQULHqGlGn|_1`BX~Pb*OLbU9)E2(G4eHeSi1`x9)Mwe&17O8tX+_M zB+)b@5<@}wkF;z1xr#q!6-cX(mcN7kgBj>UoPcVfrrgxm6f_-MX#0tTF&2Q=r&H&UCeC>&;tG>OKnWczkT^elU47l!MQSY?92+i77NaD`jL2deR z?|%a=0ByyO2We|MuDE|6Kut2)e~d<|$^OGI1}k9|T8Wcn#^9s8AiZ}&d_ngrcqhD= z$zR4zAyO!HKTFYSuHevH;H-tVhuzq52Gqp!SfBOXLc&^J^9%@n$5_8b*}O#fngNJY zXME=|*l`IOD{w|!ZN3}<00000000000384T0002MM1BE1`8*BekA z9AI$3p$!2500000fa&}zHMp+pzKAhuDZtOqY5{w3UDxw_nqyc$140NfM)pP)RHT(i>ZCAb2+ZpTw7E|nk zCeyOS1^@ssiht|Plekt@DbDTmzKC&{$(435YUTiRjs*o}Kca0?v|W#3dw8E&MT#G4vgO_!o)@&<`Y)&QxmB+_r2YAdRDw{;x=00000SVP6S&>2V= zwBr2Qv6Q}hu?frkJ{vK*a}lGYEW>lnZiRQ7vqwK^6-JGs)by6vD7sTCJ=HRa>L{j| z!E^Z1a2o!=q+NB3>>}0&Xe?p#-?g73T@YBw?fqA)00000n)wA8fi{G1 SJ{)rZ0000hq2t8_ z4j>4Th5!Hn0002MbiQgGQcBlFj8RJge!f==*o&0X=Xsjr*ggV62r)+XQ?zMLVTna! zO=M68F4fQKV(aucI_WwpSO^JVmtlg=NT?D(!?0=c@)s$i>c0ol)KR;F0 zMW{sWE|sV?&BG#!DV}Ds3+hE<2iRjUWW$i!T=i!u)Jto`JkK`qwG1uj(G*l{cXrE| ze{9%HWm`6+II|i-<4af^0Uck$cB1H>ixl%=IT+$?okhntz}9xnOTC@JK43A`Q_y6d zEU^Iq0E{Bt`F|v?RaJ{~JH0Pr9ABXta@j(@<|fyW^bKCNg<6ZXFwC4x3dYT6!gSZAh}U+&oT;Gd zSh2{X4u7CiC!0oRlAjVhh#4cm**Yxr_#_hP_sz9cmAl)z4gdfE0069^VO{79Bn(<{ zzU^2_-@Vv`WqzNH7~Q#uQBr2`xn{S*z0Sp>pR@?0L{VyfORN;#snwopnM89GQ#9}# zzBDEce_+xs`ibl+)(7Lp4RbLzwZlgk%K8o%G*WVnFC@=Hn0ao^tnYvZ{Nd02O7AhHa-e@%~53UHXt|#zjCtG1=|^J#H(Lq-000000NeTUHaL#syr{KGCBV-2-2ps{<2bI*)1HR$8Bj{8wUU3?I^hyh zIIJuMS%it(#!vd9$7yM3Wc>^{qp7vB9U#HACH0Te<-M(=yMG{eNqtiJOeO0@cQkBh z=f_ohNE@Pbw+&HB&7_NAi6u?Cqg4b4K%ax9n}%(jv;U-|Z6zhKw;2oGORA%(C1{v; za!Xl%bjV7j*9?>xO=S?=gxMLea1+)G+2(zatQ}%O30{wL*zgk|&vxNQy(fcnz|FXq zpv}xYVgmpGcz-7X4>^0Di}C_rt@`3 zrleDqer9Al!dkExTnsrG>DR1I88E1ul`IdV8piBxqQ}p&SPktlN{_mQRgRXgUGoNW z2cVzSlXfN@EngGn4epR4SiSnK9W8{;0Q*GNHAqs@Yk!aygG0+MC6YWf6nVgmqi8qS zTGrD0b|0UGZ0oz|=s#z_?Cn0|>z`-8Y|jA3;7+g#-N_)y7=u(EmtI#udC^-eAFpJG zM14QX@{NjuMcr~SmLg6c?ZHPm^(b;_f0s10NSl|<{vf7bE3zedQ_rg|NOssR1PKV1 z?e$RCjDNLa@AiK!_WLj-lo_ClqY~+AXp59MNyOjDykbbK8EbAGfFi6#hw!rT=D-$? zf!)p{Ud&peVzwEKW%Cv>)j9*NO|RctT?~6@v_BM312&2M@NAe&5dZ)H0078ES2E_U zWwXR%*6)NrjJ!?_4q}p=ssDiOIwiIB6)9BlsDF5oOzGkhtI=BCYGsdpxl*X4{CQPI z$*fUKHM&p~O}l0(#WrbH!6(MuvPQeUEm^B*#;mz|>KlOUS3D;hE>tvU-fDFH5lv-PV#&_8ZGvt!+7^Pyhe`008g?`~qxnuEg@7wSNEr O00{s|MNUMnLSTa5ba{FJ delta 787 zcmV+u1MK{#2C4>-B!BTqL_t(|ob8)ga>O7EL`f<);r>VRUGm|IixH@i#A45+-$%;9 zAPL!Q9VaD12qAHx$7yM3Wc~;^qscipJ0OB9OY$G7%6nM{yMGXOMSW5EOl8vxcGPWX z=f_pMOBteew+vBB&7g~Ji6u?g(JX=w0FS{`4a2g|*?&<|w$hSV+l&S8WvQc~DX5!w zaSO~p7%@}fnt>9dsTBkl;pPaKxCrCIX7f78rX67c1drqFHv9y{-Y&e=donx++>Cn) z+RVrnn-D_CJAV<_H z(oR+Q%-HNm(}Km|WW>n`UpIBifI)0lv)qlU8?(0wj=#xdHMGVkJz@*998I6Q#tp80 z0QI0Av@_^v`kXLsaEBDp)T>e%jmphOd8~{j@y;dVKNCR?WNhPmBFJ3=J>>usEu*Tn#PJ5~qpyI~i9Dg*9W%tq&k6bJ3xEY`i(J ziO;}p=Mf)fO_58>492p#O|>ntj(}^?tCv<6-5wh4yYd@|d1N#Uric(i2qA>51uGfj z)>bpcwSXu32ia4Vne`#JF4LXxCp$<|>*oYp$O99>D5PJO>+2R5VAvYIQYv zgc>@Lxr*ineH4uVv0m9lzUF$BZ0|l^))oQQ8_QR%Wi?8ngb+dqA>O7EMM)|*;r>VBE?KyeqGU-3G0E=#R^1qc z5N7(eQvv`00001BJ72v8N-5WmoU@by?0lbgAQq*R|NCiALH`IyDdn8WUp9|Bg(NmJ zOHL+X;MV?=w&;FZ3L2S_j30kdv!I=yuG~#(7p1GUi&AI?t7xWJ!lYL;3ug!DV=&!@ zVV&n{KS`-eNkP2Z^f}+l(u#(rpl003C1w86Av2Yp(~)8{wF2iN%#MJGi?E)^7QZ{m z+94Jc=XF1u1>XSK+qt)Tk-<6OFx^woW=6Ky0002qhO!Y_x<^`MeA9m}$S4~`V}plF zc0tXv44bGQWOO5g6|q%Ybl;}i2OvkMd!n9`&8*vGYf+4_>Z!fnX4PFxRzo*qX|~k& z(#^iY2Zd*MK$om`pRbGp-xMDtK39rhRrLMPMcDqZg4{=S!QNFa<|0heNdtW%Xd}E4 z?ugeT1{u-c1`}#Te=~pRgOgwuI!PnQ=!2zvR(L12c3t2;_aIhtP^_J%hBnVE?2BBI zNbqk~ktgf)uCp8YZ8^S0mqI0dvHtB-79A3%!wsKUJ1&K$AY$Bem!@&gLv%otM;ZN$ zdmf?#9Ngawd?<4|Kv`EEWqsM$rMUU5ktDKesN|K=^Vg!R{9u0v`V(NVkWvaF4gdhr zIVf_m^-BIs5fviR)t;q|myFvhUF6={FJyE*lGR6(AdyPe5_bf1%d2{mxyRr z9~C3^Y)v1G76v)21vOq&I>)xf;N%mr>+|cd>z@5P@)6EIlJxb#RVwTNvU73@l9pLA zGI~QiOQe+6gQqEX`82}LU0s}?g23~D8VUda;0^o&t5F#&0k%)Z00000NkvXXu0mjf Dc+Wnf delta 668 zcmV;N0%QHr1<(bMBxsjOL_t(|ob8)Qa>O7EMM)|*;r>VBE?KyeqGU~o(eD3N-57)r zX8N{M0ssI2003Y)U#$g7Dc6sjvy=k-eD8MPEJ`W=_tTn!@ezW=ze+%IvJ6TAAgZq(9cg(Zj;(Y>1yqw6q?Q|%oI;QcXrrR*A z^IYvGDRn6+hxpdfyOXRP zVnK0U_tPx+2FTtnywy7yoC7w~JOwSLXNwI00N`yX8=qvH!)ZZU5uyMQr}BA z`wSlxp4|aWvf6#VateGye31BDDS}ne*FzU!|HBG$AJqjF>5&+zvz@jGlXTL+m8%<+v!rMq%YRLW6EMc!VI_(6KngW&~%6x_uQqa-}56n;FL!h z?eu$oL5fx6PsXbF0FB$h&I?27cU&!csB&&}m$IBzhQbWV?>fJZVy=TxQBKp-w z#fU$f>4VckC!4h(<3*)?EL#kAJ`uYpDW&z`=_y@4jAQ4nCiYK3;CVm|1pol>27Upp#~Ccs%0z?3VUIEccmJ|4%DrP z^Ur17rA)E)ZJA=LYX(DfOOS4|1I;2h0QMYA)if+^?)Hn4vR11TYoD>?y(|qhv;=kg zU3_J%KQ>~evMmE8psN)GH(_-KOx%R+LbZCGr0Pd_Fp{_P>{fgO;%pZ_>OC3W0}kU} zf;Ka9#3qCg@&*P1haaR$lPCcnf4U(IZ)J7E;4TzORNV@^6I7q8P}N8ASuIozy4CGk zt%nXb@Ft0;jd0*1Hn>XG)w|xFyeLnWqY(zDr>cn>i$>SrEH9BFR7u=ra0)pCkSE31 zSG&}8U1r@ay#^O4T_XfGqz+*jKl2%R8O=^+?{7otYWDtSI0h%-Ds+-ge1@6{hi5TZv9F3OQbV_C zlXakpp*OSwodKTXJzqVv zkOY|5Z6_%aLI@#*5VD;=y%nzOxOC3W0}j)@ z1Z`&Ih)oC~ z>!HI9dXvP{MmTU08(byp>aMpZFUphUXoSJ(scNFeqTw2xdKsV)z=8qa6iZ^Ejm8PGvh88x+q()v#|D^Phg;vzOD!8K7s zS&S)^h~619?#edCRxz$u#RUDNEn3^6jbZBmwB8czZCkG(I*VAgHt*SlAF&YkGjj&m z>Yyqgil+&Y7;!(%@Ln4(RBBO#W-Qi-zYh^wwDtJKh} z{r?4f0!`e{H?#ts0j-VH_`yg>p5kdWJhTeIB-K2@iiRsY`EnM{--HPvgb+dqnah7D Wr+8qa@%ShJ0000O7EMM)|*;r>VRU9xbcixwI|#-#n$Qwjh800000%lV3CIF94IsI^Kdz|Z&H4(!Eo9IxkTO~&yNP)ez_lAo;2a0*E@ zjU^|GFmPM{Nn3P3JsF+kkATygS}WTC;#`|j|0rGDTN}L!a(|cD6XP?KY%O|4W=20h zA#0P?Md@zqq7<6RD$Ep5nDmOW80-Lj43=&fwl-(`NlKeb3SwX8nDbFCt!QcrGUHBe zDf5pGnW=QkffQ#^S1`B;vm+pJ5!Msg?7fq0Iiv)|dEHMl<0nA&cEek}oxwTaX2Mg@ zVrI730000MF@L{5nJK|@08S*a@Z^KoJ}7ct2sV4-USNC|jtLPoj8>Kt82y#m5uRRx`TxOzf=JeK|UH8F5vKrbm=GM-WTP~M(z}Uci&VlRl z4j}Xz*2AG4;Cxxp+7~&RL^O4l>CDBxhj2P6RpES(G=Gc{-ZeAtbLMvzvH8p5^6(BQ zYy_4)`-uL@ZG8aB4ztjcF@lUfxRghPH+Q93^L5bYkRGP1h3@2c!o8r_UiSj3E-^}9 zl(bn`OVik_g8dprmsfY;bg}>2+e9yJyA}Fi2>UFVYI`3vV-?LhZP*^X5`ddAT8u;0$1J;Y6rZZBY6J6SU5$<)d zklMN!zqtEib`dVZV-j72{UT_{RZm`jqa;_sMnso~-KQV`yqvTD-Ch6y0Qf)r0_R|3 U?Dto8^8f$<07*qoM6N<$f)!|T0RR91 delta 742 zcmV!ocnIlWWm+dK{g^kAO=}t(Cn1BCao~|0zS$t%SDI?K{Omt} zf>uiIhGAwOcM4~dplr5PZ;P$dc{WP?NOmehAzwcU>Q^#r;OC$Y$WMZrVx&L^N;;?m zSlIt__h(y^S@`mGcM&eaZ8EzE`;(wkQa!%@i;|>*gP2_&K58ETUQKK57i|Cm002DC YKP@_0l*u_2j{pDw07*qoM6N<$g7bG`y#N3J diff --git a/tests/snapshots/nanosp/test_sign_message_accept_long_3_0/00000.png b/tests/snapshots/nanosp/test_sign_message_accept_long_3_0/00000.png index 9403307a587a49a9de3eeea17ba698e049dc3512..cb25550f4d523c4cacc98971dd9c5c308e195a7c 100644 GIT binary patch delta 40 ucmaFI`i^zON=CLWzAVEG&duu?wHZbJsQT;kY;!YV00K`}KbLh*2~7YJJq%j_ delta 40 vcmaFI`i^zON=CLde5-cIaco}CsLd$y|C+zP(Y#mH3_#%N>gTe~DWM4fKmQJ< diff --git a/tests/snapshots/nanosp/test_sign_message_accept_long_3_0/00001.png b/tests/snapshots/nanosp/test_sign_message_accept_long_3_0/00001.png index 3da5a411a4b92699fb34d5ddaa516a742f4e8eeb..e6471d399cba1c8ea0787f6aefe62c91b8b0d812 100644 GIT binary patch delta 385 zcmV-{0e=3928#xeBmvT~C3FFQ{GG7@dIM|)n)UBA0>zGS_D-l1Z81ELRzz&CD9lOc z1|Ofwj|7~x34_x8=XRrIu16xnruRp&6`Xo~gN zPuxUT)%h%k1o&N5gRNfB**E;enR;SFcAIg7-r;!MDfeLF4D($FvpnY7W?~~idz<-N z#aDZ6h4y7SoM?ZhpW=~MIsgCw006j)gUjH6eQo1cFXWcDyrwJN0K0{t(+O5=#(ooQZ+savG#)*Qo$1_*kxSmjvMGyNz zH`JJF_@$?+aWR8MR#>^aU&8!My=c#kn`OV{JMF>|pbg>Z*E_>~bQ+Th|57YsSh)ZI f00000{3iYbA5M_$0ih7_00000NkvXXu0mjfif+I7 delta 384 zcmV-`0e}9B28srdBmvQ}C3FFQM;;@31MH_jv;Lh%px6=4-tl*0R}9ai6%pGj3UksK zWXGrS;{rCIw(*9>-=JXwLNkxI{3E@7gB$O`_i*(r^zn2$8TVi*ynAo|BDM|fNPzPM z(N$Z~TS$y%Qe?w?5Z(!k=R5dsacdKDQjOyzMmSRNy?t|T6+P`0MRr|()j5nfnqocn z6F1RSbw0}>0e)B2V5=8&_6c4-DcdNcQ_t*$~~Ak!+h7lERVUinb-)>-e&$* z@zq{ip?#SSC)%Isr+DO*4gdfE008dd;PQM*=yWBwY{b5HL7lfEhykg&m^?+h^dIFE zWr#a0tp?Arlx~a4S$E5GX@W+L&yd%cb}KcbG!!)9wsKaPaiSpY@yyjWt|wGv(Zjyb z4K=13e(9-dT+CpR6;|%?TzdZD#u3v0000k-3IaZN+ZLEq@sIb1Jv1?PBk4+r?gJ zE;iw&M8ae@beF*gV2{Cc7=~@0`ujynTdEhtW1VB2KkLzkE=@sh+{G(yhClUo#y()N(^Jr7S3a=;0Qk4z zN7TMwK^q3^34b@A1sQr99Cag8uhmVTTBn-L*sQh3K`-1u9jOPF;yRMYsMa_;6Ssn; z=9o7EB8+p&;1Q-M5~*kHT({8!X#d?2zZI;rP3fKHFR|SstR8N=x9)0UJ~;vg-m(a> zLaOVkdtjN)zpZYd)up?4ah+4uKJUegb%RXwr%^&p^ff2r8LY%Cw2~8Kp24FCF8}}l m000000000000000@R(oUqojI%NDE9uQ~<0002M za$mg#QcC$E##l>%-}mkgoF%37`8};EI6eYG2r)+Sr|*V1*~MCD zZZ^?O@r224=qZCQz#fC)G7QT+`T0dkS*jMqYn@}A?=`idTT@Uo?&6j)|JcM#W#=47 zaaJ|M;3BM!fCm?0J5eou?W9_dsKMyG-OpyhHxS=;!=HL5V;`_t_Y}0)olk540RA2L z5q0iY(1F34;eX+?AVY0~qi$sKwYuq3>r}HDo3-*d=!F}oEA_xqTzm2u)f#7K;+C`2 z8tX=YhjC8nJi-)3JoW6I>kfJW<-a@px14pBDYeu5Esk4+)x+)2t=UbiCr7}*ugpWN zkm|bHJg^M?@1PlIb?L5M+}Eh;oZrQZRfA0Qmr+7Z^fedb9qhy`v{NIx7xZO zaQ6d?FngJFheD0*nO_f^H{34ZP1wSDdm~T6{?~o==UnyvFlC&#xh5&YEbyOqvGDSI zHhIRBWk(Aa-S+IBH-DqF^>(MP*Oi;Uo=C7YI#4gTOM2J*8sqd+m+t-hvU0Iqz@NL5 zT@R*DTYpt{#-+J3?UDtTmQ|ZhT$wCzU|(D+$M&tSw`FqchW>KWYq+?>?!U3iZMWQ& zk`uWX^xP?%ah}KbcG-s4!TV+Z=HA`^YZ24V`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPx7xZO zaQ6d?FngJFheD0*nO_f^H{34ZP1wSDdm~T6{?~o==UnyvFlC&#xh5&YEbyOqvGDSI zHhIRBWk(Aa-S+IBH-DqF^>(MP*Oi;Uo=C7YI#4gTOM2J*8sqd+m+t-hvU0Iqz@NL5 zT@R*DTYpt{#-+J3?UDtTmQ|ZhT$wCzU|(D+$M&tSw`FqchW>KWYq+?>?!U3iZMWQ& zk`uWX^xP?%ah}KbcG-s4!TV+Z=HA`^YZ24V`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPC;kmeLsWBGKiI@~blO{{7tmatBL9EV1?fj8XK{Oq+ z!u*F{a)}#mNk`ORR86bZ!dJJC*b;_9@>6jg;S@qIhK@zp9mY)YOEn!bKSm!0& z^4gP60T+K_?Okkdl&5{w*wE7`XA`zMBM&&Q>B&3OyfVC)ryDQ_8Kb`qWvDUwn?Vdt zf-H2B${-^KOZo8O9r)%aTx{rV^;|V{^<=pp$&U+aU+q;@9kKj&^vF`Jn6ji$tFmls zS+m{&s|MBkt#+*HNVPl;m3HZ0=D1yPv~*LoWWax#W45}&8ueG_Fsfw{@Ax`;o`G}} za!A+MlQI3~=6nFCO5@Ng<5*uj&PT$^JYzBF+l1+f5<6WQ<_SCDJj06bk`>UdTwVR{8ajgLJXUgh-!z&@(;xFjbAAta0@l;;20GpYRxte39J2iY000000000000000 f000>P09Nx05b|e@pnC0o00000NkvXXu0mjfu1gp` delta 592 zcmV-W0XDBh0{)V;{KQ9Uiy%^4g-Rys7ZUiht920 zApT%-%yj_(00000@OE;}Ip@<+yov8XTcztakHM=){bz#@+B+#FyX5}2l%$l(kGrsx z(5tjQ^~)+(U9+09i4ib$H%8bBU~^FR%Z*(k?NlAn+b+M0HGiXW)i0|lo6vwg5q1&0 z0$7MLR%gll%+l!XKJ8wjA`BjYhv(w1rN&q^Ct^|%O`0sRvYKNh2hoCw+W8}&f@nHs zh53VBa)}%Eq$B@~rmlPMiv|n;000009)YGq%ozD6M7{@v6E!4H9@@2Ps39v>g+|%7 zDjrltH+o6Rr7cwHl<(?QdDV7Qy?P8=3N^}^9%+~zsM+-5uONw9Rm;x@QNgADuF<8nU@7{rLerzRbbpY3s)zHundBRRO$&B2)WCi$@%gb@l zsLfoXp&^J)qGh&M&Y?+NH!zZeoZkbEqdf}mq2oPZ1;Y={A=?iC000000000000000 e0000NU^Ty>m118x-~@mG0000kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_against_wrong_tapleaf_hash_0_1/00002.png b/tests/snapshots/nanosp/test_sign_psbt_against_wrong_tapleaf_hash_0_1/00002.png index 317b8b9ff8094162ea10dcf319976a4fbbdcb084..6db885b65f13533ca86f93831b1cd8b83301d511 100644 GIT binary patch delta 711 zcmV;&0yzD{1>XgbB!8w!L_t(|ob8)ia^xTkMM-LQ;{7kld&!40E=rG!1jg8%d%ik6 zgj#?EqEiYXgb+dqA%By7-}ilwSAq7g<9oFN&B6F3fer=|CCa`7LJX5f*B{haO$n-=Lcaz2qA=!ze(a4>YdPo z_es$GJQ{*iqnVZvZJND0nnez&L76@1G>h5blFKAWBmnuKG1e+ITu@Z7eGSS5)y5U8 z?3`Y(Cqx6iz<)ayOLk>t7c%%dryYcGvESdHW2Pq!bn< zrUK&%YaWpe6_|;K%e<CY5K3AiKHzhR33d(%V1eCm)<_QmG zQX?{@3-S(pUJ&jZ6_bjbGZ1f_wN~CaqW%-m*f*E2uYcw#cE+Gn0l~aa!gpQ4%=irm z5Ao}QW}h)q>hE`YvZxKwS3;CinU zfx1cvG=INXb3cJ{JX~rZTo|c}+&ydBxggJEb%P@}5^+IhOW}_7h`?WKfk2Jfm(7$i z2W=NL`+BU6GBV=DFM^7c_6?04po5;y6q>n1EKMI_wfy?C z7tM4zZfVw<2I|P^#+4y1_uoU`^dR$*Z~_P+gg_9|!3Vrvto$dvLB`)^$tWMN19%Tu t3@2bQoPfo=egc~BMT8JS2qAF1DMQNuyVgE~FFa1b|p?V?lFm`g!R|bTT zg+NA5N&o-=0001dCZ&{8ioeT{e;nVZ4M^3MZ{yPtKc@{)5!XZ94LRpmd(N52_*+hK zcn1)NlHEXDBQ_ExRYr6)8OvL)=N3DFILjIPV;WkIYb$ys=YMlR+K^OpL+UyGZ0b74=M8Z!4he^N?c2j{lW1Tjx)=~Rp8`zK)l0001h&&2f_s=b?gZj$2I z+SvZ6y`+mwM`XIA2E;rsrcRyX@B)h{FnNtMiU)>fL)f+_G@VnGQ(i-^1+~s4u~rw^ z*b}V)iSdD8iGM~`G?0x4sWubm`Zs;Z7{LPjw?|A2IsBPas+no}Zh{+tt4n@?EpFO7uX~A+EQNg|TMmpMQNpy#phe&ujZ`J5U+F0CGtHZuwl+7l zMYQUmzkdd4-^H|DVzk@Sg(k8aJzXJVI3u;7*AeL{JZO^SIOdCFoY!2TVaD#;Wylzj z1LbJ3FgdJk%jdv`kmdnnuC9i9j2rN#xE)UwS3*U}{tn<}La}h@9Gh4kBWbqHU3?1O zZcB>2qJsuXxgKK{B;ohw_{HkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_highfee_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_highfee_0_0/00002.png index fda030d56c962bf18cefd5b175cf5f284825a115..e7482655c77dd6da49ee88968605960861ea4eaf 100644 GIT binary patch delta 751 zcmVP`d_A(#zM96O-!Bpj*k5-8y z#+ZlUrn(dW000000N%-Yp67YSzcT8796#9(lq-~96VopKW;>uFj)%A!j^n81$8nH4 z@scc(R{#kpSq&sKVj(ed)e!?tp5-O$*=r`n9(KM4Z>00000hc3bL3ots> zcKQ5|_~2}0TwAs9RRiFbcSXa}g4*Dc`^$BC5pOZ##i#v1uDh;E)7EcI@m5F)FBDB_ zW{HJMc8!Zj+JD79N^oVl)n-2Mziuns!@JCimb=^_EK);>WWSPIwnuj&56|>1)X=Ay z)ZOaic1|9)zi0)J98jb+p_R1tZ&^TNX0@7=UeN*I=IkV_IXdi6kgitZHAS;-uOnf( zYFc$}58RsL>CT5>V>l~6?H5qS7eE%-?*JhBw_^wd@_+uh^FsbI)KFs#7T^RKWAG?E zypOz;=f|@6OK{^zXUI535srx2u{;+~kld?ET7K;n2<_WuugVlL8*wS_e3uGTac;t7 zJ_ZHI2-{uVUJ=2LA<+B!9+9L_t(|ob8)ia>F1DMQNuy@&1>@Uiy*NqtOEi3`TM8`RF)A z2#^q9k(L4g00000z-Llxt+mF#YRJDG-@7|dPE$U{rd|B(?tqEv4>cN&<9L-H$H8Rc zCA-)h0nDH*8klL+LZ;-DQ4P)N%98s@5dq9t!MQ)Cfm+=1=zpE;-vi2mP4yrY&**#i zo}CUjM^2Z5*P1ScBlEN&lXLwkrF?B{yS*l;`=qsA)7pfM;q zs@8Y;MDyKqJWYEDZm(MO<2U^RneiK7q4wthSbu*Ok?erJilzh`kuJqM z-_Aira8ePKV3h>v>g(94jAhx>KFgl7j;X<<)(S?p`mtj??AfxToDR}+sx~=1w~G4E zaBwhsu74L=LvC1qS}sT?eB8EK#dup%cr0Run^TDonUdnixfC{?rDY@cEtXnWKy8=R za(mcCItQ@ZvG~~9K9F8yE{V6>CFwf8<$!qJ@f2&{!%1xe*EOo#K`i?O;g`#7S~Syn*bepsHO7uv3jJVUeUN zNkTdYM9zrqI}p`RX-Ve*IcFtrVc8(>`X+qwN1u6kR|hm7X>(T-P56E~fJs?H zn`?KgLI~;n)Bk9K)jI%>X$^CW!{6Dx1G2WZ*z}RTw;;!B=zk&p$3hGM007u-b-@_^ zQi@8!zF^8L9c~B?D_n|ZzVJ?)0*lpF+c!HXa}KMGezc-=$#OJHY5iJKE@h_+wlbF$ zX5aQtv}u9uz0V?%Dtov!BB}?&YWrhtrQk}O!aE>4=vcY~I>WY_=SnF%e0sW6pKul{ zj8_+%J{}A+UwRL=00000NkvXXu0mjf;1KKK delta 500 zcmVwVu|gt-Gb!*o~ku! z7fKb~#sB~S0002sulP6}z&PhzIJVXvjAX`>9S}Et?8R<)uLDBs$IYEhe8Rue0SrnS z`nh(0m2)nhf9fBf@ai3aV@kvP#o=$>y#tcAezEDj_uhgGuYaMJ_#F!|0001ByV(V! z`)*NG3+xLwp+gh7Mq9uE{G$OJG&1&moZKmK%oXR^OIjESr11iHdnfL$b14h82n^H|M>6)-9L2=O(g;mV#lRQYt8LKpycNCO zw4RZD^&fzERU(FzRqi8dcg)B|VA+g=4rB(5Cw2BV73*)(kR=^08C5*d{j8@+&ztam zSY_CgVvvdcGBTki`itQVo`fp&ByWPu8BFD)!dq$^G;F;+e>@^bc0)_d>x$1~mjkeB zlAT}qI%Xq4Wg$}2+v p000000000000000008(u`~teS+u_oPj`jcm002ovPDHLkV1nsz>!$z! delta 499 zcmVL>N)nO~00000 z0G`fyp67Yq?ZuP$cGML^zjzHEz3M*;Y{=*w$6-sZzfp1=NBnUKqeQmK{?e}MoHea_ zrb7&erMW)bPJr5jX*nEF~N8Q)nY zTEkbGi+7!^JucS}Y#foCxeI?yLz{7`2vQ&NAEhAe4o$*AFp?PonrdftTh z!!pC36oX9kmyroI(O(Q}a3^G;J9!gi)?g|h72Zw`Rx&TWHq$JysG#-c3A+g zLaF`eSNaYW{unHjc5A+i9Z$ehG`p}-F)sUg^X8hz*=PY=*nGdI?2>|lN1^m;HC`D4 p000000000000000006-M;THyb*-AddCKvz!002ovPDHLkV1mK(;DP`E diff --git a/tests/snapshots/nanosp/test_sign_psbt_miniscript_multikey_0_1/00000.png b/tests/snapshots/nanosp/test_sign_psbt_miniscript_multikey_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_miniscript_multikey_0_1/00002.png b/tests/snapshots/nanosp/test_sign_psbt_miniscript_multikey_0_1/00002.png index f67a3aa62b644f4617ca3a0f703564e326a57401..766cd2f4a48dc8ebcbf27a7f45e63eca70ccfc16 100644 GIT binary patch delta 754 zcmVaW3h-rq=pN8t3MimQ1 z70esu1#KltHh(%U`=Wa7sU{9{aS7@WW#?11@+Lc*6nTuKgk?k7@L|^@XzvWPpM9{G z5TafWivr+D{Fc+UPgGTcQ&9)vl54Xl0M6ceT+`|}Q6N=Rj^!q?hQS`mJOJfvP5LHm zs4T_OwjNO$tS!}eWthuNctl;FZAJylhPh8#;zR0`XMfglQOhv4=!{WzG_HH}>i;IQ$Va`ZG{njTkJT;$+0&R_3^up0LY|0xO)Na^ka7^_EtD zqoL`^ei)TK0%sv+oc#5x<>OTT7gUbuK8!3|J}$6xgWbfQcDcMfR2s8WdlW3ona1-! zhVjjaf`9B8pe;evGLNtALQkCR3eMgcy>?c%127>MLl<=95}zVN0ci4mnSitx+>y|>X8*PNemULN)&r1(Y`=gUOmo`H zPKG5rlb(MaROFOHuQgXpQxk~Oj8z>%0DvHV0UN}YO+Q2)*Z=?k07*qoM6N<$f}nb3fB*mh delta 757 zcmVD?m6@tOns4wNWU^GOD9R-@0W#k5~c1S6@Ss4#P0#=hE4S-NG+$w z?mdwK$ah|*f-9%j!k&2wWS*ISQcC{0Cxt z8&wm+8}&umOMlf2Zd~_8^V%b(PIEN{4XDEPRI9yfoLz=IgDeTFhKlJUu4k}*Gq666 zA%28V?RwZ008in!UbbVZni`yj22fKjW>Wy1ck6LYuj5pOrJ;H*cc}#f_Gp#?s8?&U zH(_A1R$KP9x!#0l%#Do=2%s^nebQ1NQh%2`v(Bs92H2u6zRE9H8Q*|N z5VH5P)WE@KC#i@%=i5n*mr;3o56{WOXpLN+|bb11DB6#?B=R z0x)cQ43DjPd4XP*FiF484&U9nMM~@os*=C-aCmWB_-}(}&D`LI@%2smnxx zgZV^o0q1E%zNFWr^q~3&I&obJt9?ly{_3W)WcxsP5DSI@2!;U&<~5}V>s|Q#?JF|= n%lHJJG6e<001!e5AwhftB>0oI3NkF600000NkvXXu0mjfl+I(C diff --git a/tests/snapshots/nanosp/test_sign_psbt_multisig_sh_wsh_0_0/00001.png b/tests/snapshots/nanosp/test_sign_psbt_multisig_sh_wsh_0_0/00001.png index 87b4dfa0fcd79dd1870bdc60c0d92e4f4b667964..cc2d012b6709decb341536a534fae2f5468252e5 100644 GIT binary patch delta 429 zcmV;e0aE_a1JMJJE`N4}APhiJ+tZz}|0S`Pet1gL1R^*Ab^7j?6A=(JI=F2B006+# z<(zZQSNGycJ_GA2L%(qSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_sign_psbt_multisig_sh_wsh_0_1/00000.png b/tests/snapshots/nanosp/test_sign_psbt_multisig_sh_wsh_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_multisig_sh_wsh_0_1/00002.png b/tests/snapshots/nanosp/test_sign_psbt_multisig_sh_wsh_0_1/00002.png index fdc5b5dc540cd13f6e39cd311ca9844f1f6043ff..3371075a7baac302e626a97afa1af3b319901198 100644 GIT binary patch delta 658 zcmV;D0&V@V1*!#*B!6*9L_t(|ob8%ha^xTkMafil!v2@UUgpCUis+4P5Ho$xS3(1p zB?RJjmjVC)0002MXVO}0t;Ihw`u}tM$u^*LSN=CXo#H#&02MJFVm8!Tul8Ci=@W0s zA~^$yLrFFe*NBZ|lHNyjG#SfV_H#rA5N8F~{=FGSk82U#Nq_zsP!=4jb)a}o&pmrG z1JK`m+zPHeop+9`Q=`wB`%fw5EAiR(o*1NWpJh#ccwZ-Y1yIdyH8zGu?t_UsybrUF>r^ zGH@I#ddJ>mUWA-{{a>wMvCLS#5ogsZN7Uv&sK#utGJnw#r^jH!+BdGRA4ozBKqqq- z0*;drgQalyI$z3@LMmQy1|_2inl2=kq`iIJ?P1EEN5&Z0U?+;9M2am_v&~ACE3lt3 zWz178NE74SQAP3~xjntIiur_wzROp4Vd*uh4r_1eV&O;{wPnbcEvZD^3?Q?`XVB{1 z+0?NYvVZ#&yIaS~0P&Yk5sBCyXgpEt5SJ<&6R{J^3T_O?7vpYc*^`06vGs?yCJfRP z`7^!=caHdV^ilBred&&G1t3^T8WoQH4r2@d`yLO!?TXM8`7>w?@Y#86oco0g_(a^Q s5dZ)H00000000000000005HX0e+&8=Pw@--01E&B07*qoM6N<$g7HW#;Q#;t delta 665 zcmV;K0%rZH1+fK?B!75GL_t(|ob8%da>FnTM43!(qWd37cgcq`8Vnkjv{)SP`*LU& z5CGdcr4T|0A%qa}nVjc&o+tiQQvdDvUTr|RUHNZ(+QiRl147(*xU1nfj;s7Q4pj#) zS;gWNpd6}JgK~{qs5-gpxQ~MQ))h)m1+v?`jJ<`sSKX zb=l4|X7ng}3j!za9?LoTp^Y?@ZC&r=o6Li#WAFY`xqqeUO7i#h2wNZTbLVlZgoX{W zc%dWSDF%ab|MA}%{|%F3KwM_;LPSz=GGj0l>t09=#c!OTWCRWhs+Dq}aSw!|3Kl>t$?eQr_r(3J^(>cy^N5fyEQD_ zao`T{cqAgv;+wE#i~o+^0lUA?+3}$OxL3*KhLg`hme|jIy!e9`!Wk%_pfRM*l4E19 zA7sdfg5MemA%qY@2qAqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_sign_psbt_multisig_sh_wsh_missing_nonwitnessutxo_0_1/00002.png b/tests/snapshots/nanosp/test_sign_psbt_multisig_sh_wsh_missing_nonwitnessutxo_0_1/00002.png index c6b820aa9ea685e7571ff9c9d6abeec5df7452ef..1e798bb2a48988837e7c091787b148b163276ec9 100644 GIT binary patch delta 403 zcmV;E0c`%Z1GWQ@Eq_~b!ypVmQPSy7*#DB)OF!r^gr~5Pt;F|yVHYrn2F9{;00000 z000000002sF+vE!n@bgJ`nh`m|EA&d-dh;Pb}#J*q$#Bc4(`O8#bv4!%SH2M;MnJlKep&RL)dgsG`+d=O=Oz_G zP>sn`*1)C*?Lr1kg3KDIG8A6z7k%wb{NqU$;BW+shL%@i+naFyicyybIm@DxR410} z*P>~9wP=`Mx_?%Bbuh?Y=G9In<4r!*V%kNW)k3p}`m)!suCqGG>8K97C>JCgw7iej z-LnZfxcq&1`GfODwT5o|cW=Bq{fjZxL$!Ib_0MHHbV`dNP2PvSYm>bzqq?^*Y~H`L zR~x5(Dr%j%J?fgxukgQ%b^qLG{dV$p*uzx*9l`ZI7tdFH+7aInceB?g-P`ZLy}Qfq z1x`=&?+JTzWATiIHv_+yIp zd)o2UixO)ktLl%hp6u7>7x#Bg%Aa8VP@d>3mQgR!>OzO}3E_>|k{<kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_multisig_sh_wsh_missing_nonwitnessutxo_0_2/00002.png b/tests/snapshots/nanosp/test_sign_psbt_multisig_sh_wsh_missing_nonwitnessutxo_0_2/00002.png index fdc5b5dc540cd13f6e39cd311ca9844f1f6043ff..3371075a7baac302e626a97afa1af3b319901198 100644 GIT binary patch delta 658 zcmV;D0&V@V1*!#*B!6*9L_t(|ob8%ha^xTkMafil!v2@UUgpCUis+4P5Ho$xS3(1p zB?RJjmjVC)0002MXVO}0t;Ihw`u}tM$u^*LSN=CXo#H#&02MJFVm8!Tul8Ci=@W0s zA~^$yLrFFe*NBZ|lHNyjG#SfV_H#rA5N8F~{=FGSk82U#Nq_zsP!=4jb)a}o&pmrG z1JK`m+zPHeop+9`Q=`wB`%fw5EAiR(o*1NWpJh#ccwZ-Y1yIdyH8zGu?t_UsybrUF>r^ zGH@I#ddJ>mUWA-{{a>wMvCLS#5ogsZN7Uv&sK#utGJnw#r^jH!+BdGRA4ozBKqqq- z0*;drgQalyI$z3@LMmQy1|_2inl2=kq`iIJ?P1EEN5&Z0U?+;9M2am_v&~ACE3lt3 zWz178NE74SQAP3~xjntIiur_wzROp4Vd*uh4r_1eV&O;{wPnbcEvZD^3?Q?`XVB{1 z+0?NYvVZ#&yIaS~0P&Yk5sBCyXgpEt5SJ<&6R{J^3T_O?7vpYc*^`06vGs?yCJfRP z`7^!=caHdV^ilBred&&G1t3^T8WoQH4r2@d`yLO!?TXM8`7>w?@Y#86oco0g_(a^Q s5dZ)H00000000000000005HX0e+&8=Pw@--01E&B07*qoM6N<$g7HW#;Q#;t delta 665 zcmV;K0%rZH1+fK?B!75GL_t(|ob8%da>FnTM43!(qWd37cgcq`8Vnkjv{)SP`*LU& z5CGdcr4T|0A%qa}nVjc&o+tiQQvdDvUTr|RUHNZ(+QiRl147(*xU1nfj;s7Q4pj#) zS;gWNpd6}JgK~{qs5-gpxQ~MQ))h)m1+v?`jJ<`sSKX zb=l4|X7ng}3j!za9?LoTp^Y?@ZC&r=o6Li#WAFY`xqqeUO7i#h2wNZTbLVlZgoX{W zc%dWSDF%ab|MA}%{|%F3KwM_;LPSz=GGj0l>t09=#c!OTWCRWhs+Dq}aSw!|3Kl>t$?eQr_r(3J^(>cy^N5fyEQD_ zao`T{cqAgv;+wE#i~o+^0lUA?+3}$OxL3*KhLg`hme|jIy!e9`!Wk%_pfRM*l4E19 zA7sdfg5MemA%qY@2qAqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_sign_psbt_multisig_wsh_0_1/00000.png b/tests/snapshots/nanosp/test_sign_psbt_multisig_wsh_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_multisig_wsh_0_1/00002.png b/tests/snapshots/nanosp/test_sign_psbt_multisig_wsh_0_1/00002.png index fda030d56c962bf18cefd5b175cf5f284825a115..e7482655c77dd6da49ee88968605960861ea4eaf 100644 GIT binary patch delta 751 zcmVP`d_A(#zM96O-!Bpj*k5-8y z#+ZlUrn(dW000000N%-Yp67YSzcT8796#9(lq-~96VopKW;>uFj)%A!j^n81$8nH4 z@scc(R{#kpSq&sKVj(ed)e!?tp5-O$*=r`n9(KM4Z>00000hc3bL3ots> zcKQ5|_~2}0TwAs9RRiFbcSXa}g4*Dc`^$BC5pOZ##i#v1uDh;E)7EcI@m5F)FBDB_ zW{HJMc8!Zj+JD79N^oVl)n-2Mziuns!@JCimb=^_EK);>WWSPIwnuj&56|>1)X=Ay z)ZOaic1|9)zi0)J98jb+p_R1tZ&^TNX0@7=UeN*I=IkV_IXdi6kgitZHAS;-uOnf( zYFc$}58RsL>CT5>V>l~6?H5qS7eE%-?*JhBw_^wd@_+uh^FsbI)KFs#7T^RKWAG?E zypOz;=f|@6OK{^zXUI535srx2u{;+~kld?ET7K;n2<_WuugVlL8*wS_e3uGTac;t7 zJ_ZHI2-{uVUJ=2LA<+B!9+9L_t(|ob8)ia>F1DMQNuy@&1>@Uiy*NqtOEi3`TM8`RF)A z2#^q9k(L4g00000z-Llxt+mF#YRJDG-@7|dPE$U{rd|B(?tqEv4>cN&<9L-H$H8Rc zCA-)h0nDH*8klL+LZ;-DQ4P)N%98s@5dq9t!MQ)Cfm+=1=zpE;-vi2mP4yrY&**#i zo}CUjM^2Z5*P1ScBlEN&lXLwkrF?B{yS*l;`=qsA)7pfM;q zs@8Y;MDyKqJWYEDZm(MO<2U^RneiK7q4wthSbu*Ok?erJilzh`kuJqM z-_Aira8ePKV3h>v>g(94jAhx>KFgl7j;X<<)(S?p`mtj??AfxToDR}+sx~=1w~G4E zaBwhsu74L=LvC1qS}sT?eB8EK#dup%cr0Run^TDonUdnixfC{?rDY@cEtXnWKy8=R za(mcCItQ@ZvG~~9K9F8yE{V6>CFwf8<$!qJ@f2&{!%1xe*EOo#K`i?O;g`#7S~Syn*bepsHO7uv3jJVUeUN zNkTdYM9zrqI}p`RX-Ve*IcFtrVc8(>`X+qwN1u6kR|hqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanosp/test_sign_psbt_multisig_wsh_v1_0_1/00000.png b/tests/snapshots/nanosp/test_sign_psbt_multisig_wsh_v1_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_multisig_wsh_v1_0_1/00002.png b/tests/snapshots/nanosp/test_sign_psbt_multisig_wsh_v1_0_1/00002.png index fda030d56c962bf18cefd5b175cf5f284825a115..e7482655c77dd6da49ee88968605960861ea4eaf 100644 GIT binary patch delta 751 zcmVP`d_A(#zM96O-!Bpj*k5-8y z#+ZlUrn(dW000000N%-Yp67YSzcT8796#9(lq-~96VopKW;>uFj)%A!j^n81$8nH4 z@scc(R{#kpSq&sKVj(ed)e!?tp5-O$*=r`n9(KM4Z>00000hc3bL3ots> zcKQ5|_~2}0TwAs9RRiFbcSXa}g4*Dc`^$BC5pOZ##i#v1uDh;E)7EcI@m5F)FBDB_ zW{HJMc8!Zj+JD79N^oVl)n-2Mziuns!@JCimb=^_EK);>WWSPIwnuj&56|>1)X=Ay z)ZOaic1|9)zi0)J98jb+p_R1tZ&^TNX0@7=UeN*I=IkV_IXdi6kgitZHAS;-uOnf( zYFc$}58RsL>CT5>V>l~6?H5qS7eE%-?*JhBw_^wd@_+uh^FsbI)KFs#7T^RKWAG?E zypOz;=f|@6OK{^zXUI535srx2u{;+~kld?ET7K;n2<_WuugVlL8*wS_e3uGTac;t7 zJ_ZHI2-{uVUJ=2LA<+B!9+9L_t(|ob8)ia>F1DMQNuy@&1>@Uiy*NqtOEi3`TM8`RF)A z2#^q9k(L4g00000z-Llxt+mF#YRJDG-@7|dPE$U{rd|B(?tqEv4>cN&<9L-H$H8Rc zCA-)h0nDH*8klL+LZ;-DQ4P)N%98s@5dq9t!MQ)Cfm+=1=zpE;-vi2mP4yrY&**#i zo}CUjM^2Z5*P1ScBlEN&lXLwkrF?B{yS*l;`=qsA)7pfM;q zs@8Y;MDyKqJWYEDZm(MO<2U^RneiK7q4wthSbu*Ok?erJilzh`kuJqM z-_Aira8ePKV3h>v>g(94jAhx>KFgl7j;X<<)(S?p`mtj??AfxToDR}+sx~=1w~G4E zaBwhsu74L=LvC1qS}sT?eB8EK#dup%cr0Run^TDonUdnixfC{?rDY@cEtXnWKy8=R za(mcCItQ@ZvG~~9K9F8yE{V6>CFwf8<$!qJ@f2&{!%1xe*EOo#K`i?O;g`#7S~Syn*bepsHO7uv3jJVUeUN zNkTdYM9zrqI}p`RX-Ve*IcFtrVc8(>`X+qwN1u6kR|hkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_large_amount_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_large_amount_0_0/00002.png index 20efb47d7c4d92952734bb580a7ce4bcd2fd9c84..c4e98a69ea34ddff4a0edcf0eba6a9707cebd3a4 100644 GIT binary patch delta 906 zcmV;519kkV2dM{;Eq_^(-5?A_sjlqA`(Kjxl8;w$R2nW95VrH8^U>wTLK0#!YPz+e zD2k#eilX=?&htFalYa%|v;4v4WXbu5sCpJZJCruz?$(&{*jT$_$8lV5>e*TqRp(u)?C=5fX&D%V& zX-lShy2CiPx__kCeO84}b-;w(9cfytledC$K{B}NEaRTDtVuUFU{zh`WceVKSi4=f zBh6OWJ+4QdG!xUkN3&=KMETC>8OXb0ScyFhcMWwP>`&f}%ad-yEqDJtz(uA0N9#8D z2NtV&#|D7s8Q>Kia3^w+nO2gR7kWhptc;*_&2p=d&wqeKCv^u{^LP_>arbIjIJ&P! z*cGO$dC0ER29y9dY%r1Cl*RE|lUD8r_sVzhhadT(lHE7p&#E1#k}m^%`>tq%Ma3S% zP*)$^Kqtu62V2Pr@6ZYe#O7Agp(?J4NCQYMw4fmmjMpKPWUz(;I^hOc5odc``SlLy zWJ6U71%D?LUHNDnMW4JAv(ybM_K^i4B z+h;}+RF6DS%;bXHgnpaqYCCn@*e&KVqq*CaAFVjSmSmiq>20tXSaKqlnI6QI)>%3o zz>ID?UYMPOA1C9_&BUoB;#4a8wC+J1QRuq&QE) zXP*@P&rmS3qzx%HJ-Q?Pjh;qI9vihWQb#|lDt!+1Pr~lqRr@P*t<~0A0jqMaSdrG< zTYtUXG}Ki-)WFGPTvi;XW5g?DAX8plC5)J2@+2Hx85`o}=&ui&&z-&%4VL*-#9|-3 zWbDhjHWiq-U`9N7IoB?lpu}R6qfzz5U8n0z_j+jYm&Na0QU+7m(1&@&{|DR;Gxo_V g_(f3^MKQ^5vy|0ua)xs=00000NkvXXt^-0~f~`@&rT_o{ delta 906 zcmV;519kkV2dM{;Eq_~%-Y^J8tx_jQ&p~^TI2)^^XtrbO4 z6h%=K#g{nG^E^-gDm_j&R?wRS^TU}+K9VLW9mo7S`|Bv<9G)M(5$X3VSgs1fCp(hg@q%4dF<@_ zV;X2ctri7@dPXh_8z8;2$evEy=IYm3Mz<|p`BTvCIvwd(fTXaee*qcK{NrTUy-8N> zg6M?H3R&m!%&oVKwNq3DoF>#Q05w4icdpN$V*Ze^`k3;4<{Kc(lcFe!q6iX7ZEo|# z+Ir&Z=?>%E>VK48^_dku)c^x_SEOmBPQMkDilD(|XBqXJB~8i{jjHNCC({S2MB44T zZE2Rm>T%ujq=}fWJ(^h~z{+=8&p=)k!%E~~xNE5UApiBdaeLDJaLMl915{Y*KU%lJ zA6TU36$=0!XMk5Uz)t8SGpr;rFZ7BAnCU_Dn(0zOpML>~PVxqj=J6t|qOR4nFuJZ< z$Qh=qIb_%Rfq^LjZpdIFyD5|7SCdxihI?ioeDOnHRI+;m`lwoQD)|^-?>nOn78PqS zLtSmKfliRC4VID?-q0in#KtDmP!-jLrNNV3u;ljf*Cib05UmDaqMI@TY~`2%vTfHm=qFf(vO$x0dCG z)2LIkds0$NJsao>~SvIKB-kU<#(d+zy=uo+w!RRZ2d2} z=ezjxP7>EP6!a`=iHZ&PZcBf24aAX!gSrd%T}{l2<5-MB3cEP-U06d`MrHgYY~30Qu{rva%C9?p!_`%$QW2AF z@P@umE6O}z;%sU0@a0@Nb%GL!OpaRBvt~=|M)z)L@ef&>-5Dwy`Y^Bf{{j2)^!?!- gQBf2{QMmXE8`{)1<1!*w00000NkvXXt^-0~f@3zxc>n+a diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_large_amount_0_0/00003.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_large_amount_0_0/00003.png index bd1388feddbdc00a984d19e7779e8bb856f0c8be..bb17102ab65b352d80ed383be5903b24e140feca 100644 GIT binary patch delta 437 zcmV;m0ZRVR1J47HB!8AkL_t(|obB0dl7k=&fMK@Nn{fXlahLt!Oos^xL?ue?`~2EP ziZOf@n-Ty30Pq;4lv0ZSQm6i`c*MQ>F|>7p!h1zDT0cfa`+K!{%sD45yt=%t6Y)6j z=`D7s51@|3oU@e$e~HSvhj9E3&;(xPkiFJ#;tVwfH)C>^e zI>-L87V6|W(=Dp)8XR+l>;WlYQ_Yn$N_zj+p1>~Ky(V|SC+>PF*w*y6vS)DhSM%Ze z<8S$JgeU#YZLYs2s2iQNomwOMz$V=J<|B6d_I919;5B7Ej6SJ6+>{QO5(xkR>j~QB z4jjU-6m=3_(0@8fuU+~!R5cu-+gV8*ls*S2QLX;BZBRXt{q)&NecRqI^!(w!n(m$% zKePm`>Ha0?j0e1*`I-(;-Nm0jtXIcD+P%~&RJ9vve`~#c#thQC;1@M3B=v{S z1>GONpvC|2xRECvT^G$v5JZ7rtgDwjUl1v|jBE0|r0000000000 f0000006>_3M$dq4G;uXj00000NkvXXu0mjf5%k!m delta 438 zcmV;n0ZIPP1JDDIB!8DlL_t(|obB0dj)Wi#fMIsBH{t$A;x7BcWJB5lRjH!$KEEc& zU@adGOiBO%0KjXMQc5ZQOP%_&;t}`i$Dr#3h4+bQw0?|;_V?0x%sD43yt-W1iFlmf z=`D7c4`7bOoO3G+{t{E`lJo1+&7T1xp<*_OXEO^^W6YX~7JuK>C9PZR)tWRXMa=*a zu5;`kYoSiAGu@)vuE8-^R0m8SDSD*WeX|XG=S@A;E_-`TUV{GPu9t!>LAtVMaP?R7 z;riom`EZ0M{mgByzb2S3y4LGdH=^tGONKF|Y9_UA*NF;VQ#KjVJC&E4(g9N<0RUh< zL2tPOoA4`zoPUO{X`Q6kE!K+yDRo diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png index 9d8efd1df120d50b84cd15a7884717514b7c131c..b88fc1e2a203f8a8b7ad211d8d9bbf40e13586b4 100644 GIT binary patch delta 704 zcmV;x0zduK1=t0UB!8btL_t(|ob8)!j>I4chTYBH#QPtqciA6JjNwaEtaj#o{?%Hb zpjenpN&o-=0001dC)agd*X6%u%zqufyA4Ril^^5NF8+2Kpd!XY+zmPBdpze%=J-c; zv3Um&hmzeuTq6z=A!Ux}X!0x{d7dM70CARc?T<;QJ+4LcNq_dA0cpXZnk!Pv>3h$f zodGCsUZ;XPr}N34b!yBxGykNNem3g1bAotIYR9RzqR&5s0RR9106-tjdevxfih~7h z#3_o4^~}+#X!1tkRokjogjP>!7+?C6HrOun+v$-ufE57Zi@IO^w#_r^)BxZ zqkY;g($#nOOJZ;WACiS$O2f&B!BU=Zuh>o?BQrAjrN@i`MYiSq(y8J(w5HHx0GvX^ z{!Evy+QoJgX~z5BUeF~q|7zWyT0R%_Jk)NV!9Tt#Mm8QkHpmxDM>TpHTW zH5Qb;1AqM5Jt~O&flE=o#%wp#&@|I%)V5I>7kjSUfaaX-xqCJMP0tSW;7a70Da#|u z6Q^FW24f4ZLwfV*w-ZQmWDh>l%yrH|;}r}`{Feh!oZ10)57Kj%iu*%*kgVl;b=z-l z?}OMZ)cXZ7D1CBH?}LFpT9@?gjiPbHA2bZsra9CD=%@pd`?roj0$sm4mf=+e00000 m000000000000000AHYAp*j2v4I}w%u0000`S1=IzQB!8PpL_t(|ob8)Qj>I4gMd?=GB=(16<5_n7iRPj;sAR4lyR) zvWv|-KsZ$F2H_gBQ3%OnOh=1%b<6!cVh0Fk1=oI`gwo?)M1SvO{~3@L9I8h_syTh{ z*|ReMdFEv*xN^E499gGe%ro;(O6g~#Zk!X$bJ9Cby%qiZLzoak2qA>DQN6E%0;k!S z@meBsw9LpD?+PuZv*OCOsubbfr#!%y{)hqCWpN`T()vIF5WXlcu3~_$nwdAF>Wgt> zyx!b}Yj#bl^?zVJLE)b{%gD?p=57^v1IY1SG`q|c6tpBb1u(utT4aub`6=j%KVC9% zQKF?!4wk>SCc2~;r}tnafzEZVr$TG_%yP8$`1m0<9-)a9&}%y5Cdm{uaT(@Z)N$ly zV@grUNf&VyVwib!Py7tiLMrZE@tL)bCTsEOIvpV2?SFca_dD)H&k2Ct`y%gm<9*jI z($zfR8)EPfJ|PRemx_}agQeWzUbCDaTDk@5$A}Fbim=)GF{t8JyrR%Z0D=Ec$Z^DOkbX5G26%<^$bg##}N{li=x-sbhz z6y5=z1b=V;Y5BTqixYjcF6rZq0(it9G(7G|sk>>r2Q?(!)Ke!g;}kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_other_encodings_0_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_other_encodings_0_0_0/00002.png index 9d8efd1df120d50b84cd15a7884717514b7c131c..b88fc1e2a203f8a8b7ad211d8d9bbf40e13586b4 100644 GIT binary patch delta 704 zcmV;x0zduK1=t0UB!8btL_t(|ob8)!j>I4chTYBH#QPtqciA6JjNwaEtaj#o{?%Hb zpjenpN&o-=0001dC)agd*X6%u%zqufyA4Ril^^5NF8+2Kpd!XY+zmPBdpze%=J-c; zv3Um&hmzeuTq6z=A!Ux}X!0x{d7dM70CARc?T<;QJ+4LcNq_dA0cpXZnk!Pv>3h$f zodGCsUZ;XPr}N34b!yBxGykNNem3g1bAotIYR9RzqR&5s0RR9106-tjdevxfih~7h z#3_o4^~}+#X!1tkRokjogjP>!7+?C6HrOun+v$-ufE57Zi@IO^w#_r^)BxZ zqkY;g($#nOOJZ;WACiS$O2f&B!BU=Zuh>o?BQrAjrN@i`MYiSq(y8J(w5HHx0GvX^ z{!Evy+QoJgX~z5BUeF~q|7zWyT0R%_Jk)NV!9Tt#Mm8QkHpmxDM>TpHTW zH5Qb;1AqM5Jt~O&flE=o#%wp#&@|I%)V5I>7kjSUfaaX-xqCJMP0tSW;7a70Da#|u z6Q^FW24f4ZLwfV*w-ZQmWDh>l%yrH|;}r}`{Feh!oZ10)57Kj%iu*%*kgVl;b=z-l z?}OMZ)cXZ7D1CBH?}LFpT9@?gjiPbHA2bZsra9CD=%@pd`?roj0$sm4mf=+e00000 m000000000000000AHYAp*j2v4I}w%u0000`S1=IzQB!8PpL_t(|ob8)Qj>I4gMd?=GB=(16<5_n7iRPj;sAR4lyR) zvWv|-KsZ$F2H_gBQ3%OnOh=1%b<6!cVh0Fk1=oI`gwo?)M1SvO{~3@L9I8h_syTh{ z*|ReMdFEv*xN^E499gGe%ro;(O6g~#Zk!X$bJ9Cby%qiZLzoak2qA>DQN6E%0;k!S z@meBsw9LpD?+PuZv*OCOsubbfr#!%y{)hqCWpN`T()vIF5WXlcu3~_$nwdAF>Wgt> zyx!b}Yj#bl^?zVJLE)b{%gD?p=57^v1IY1SG`q|c6tpBb1u(utT4aub`6=j%KVC9% zQKF?!4wk>SCc2~;r}tnafzEZVr$TG_%yP8$`1m0<9-)a9&}%y5Cdm{uaT(@Z)N$ly zV@grUNf&VyVwib!Py7tiLMrZE@tL)bCTsEOIvpV2?SFca_dD)H&k2Ct`y%gm<9*jI z($zfR8)EPfJ|PRemx_}agQeWzUbCDaTDk@5$A}Fbim=)GF{t8JyrR%Z0D=Ec$Z^DOkbX5G26%<^$bg##}N{li=x-sbhz z6y5=z1b=V;Y5BTqixYjcF6rZq0(it9G(7G|sk>>r2Q?(!)Ke!g;}kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_other_encodings_1_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_other_encodings_1_0_0/00002.png index 9d8efd1df120d50b84cd15a7884717514b7c131c..b88fc1e2a203f8a8b7ad211d8d9bbf40e13586b4 100644 GIT binary patch delta 704 zcmV;x0zduK1=t0UB!8btL_t(|ob8)!j>I4chTYBH#QPtqciA6JjNwaEtaj#o{?%Hb zpjenpN&o-=0001dC)agd*X6%u%zqufyA4Ril^^5NF8+2Kpd!XY+zmPBdpze%=J-c; zv3Um&hmzeuTq6z=A!Ux}X!0x{d7dM70CARc?T<;QJ+4LcNq_dA0cpXZnk!Pv>3h$f zodGCsUZ;XPr}N34b!yBxGykNNem3g1bAotIYR9RzqR&5s0RR9106-tjdevxfih~7h z#3_o4^~}+#X!1tkRokjogjP>!7+?C6HrOun+v$-ufE57Zi@IO^w#_r^)BxZ zqkY;g($#nOOJZ;WACiS$O2f&B!BU=Zuh>o?BQrAjrN@i`MYiSq(y8J(w5HHx0GvX^ z{!Evy+QoJgX~z5BUeF~q|7zWyT0R%_Jk)NV!9Tt#Mm8QkHpmxDM>TpHTW zH5Qb;1AqM5Jt~O&flE=o#%wp#&@|I%)V5I>7kjSUfaaX-xqCJMP0tSW;7a70Da#|u z6Q^FW24f4ZLwfV*w-ZQmWDh>l%yrH|;}r}`{Feh!oZ10)57Kj%iu*%*kgVl;b=z-l z?}OMZ)cXZ7D1CBH?}LFpT9@?gjiPbHA2bZsra9CD=%@pd`?roj0$sm4mf=+e00000 m000000000000000AHYAp*j2v4I}w%u0000`S1=IzQB!8PpL_t(|ob8)Qj>I4gMd?=GB=(16<5_n7iRPj;sAR4lyR) zvWv|-KsZ$F2H_gBQ3%OnOh=1%b<6!cVh0Fk1=oI`gwo?)M1SvO{~3@L9I8h_syTh{ z*|ReMdFEv*xN^E499gGe%ro;(O6g~#Zk!X$bJ9Cby%qiZLzoak2qA>DQN6E%0;k!S z@meBsw9LpD?+PuZv*OCOsubbfr#!%y{)hqCWpN`T()vIF5WXlcu3~_$nwdAF>Wgt> zyx!b}Yj#bl^?zVJLE)b{%gD?p=57^v1IY1SG`q|c6tpBb1u(utT4aub`6=j%KVC9% zQKF?!4wk>SCc2~;r}tnafzEZVr$TG_%yP8$`1m0<9-)a9&}%y5Cdm{uaT(@Z)N$ly zV@grUNf&VyVwib!Py7tiLMrZE@tL)bCTsEOIvpV2?SFca_dD)H&k2Ct`y%gm<9*jI z($zfR8)EPfJ|PRemx_}agQeWzUbCDaTDk@5$A}Fbim=)GF{t8JyrR%Z0D=Ec$Z^DOkbX5G26%<^$bg##}N{li=x-sbhz z6y5=z1b=V;Y5BTqixYjcF6rZq0(it9G(7G|sk>>r2Q?(!)Ke!g;}kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_v1_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_v1_0_0/00002.png index 9d8efd1df120d50b84cd15a7884717514b7c131c..b88fc1e2a203f8a8b7ad211d8d9bbf40e13586b4 100644 GIT binary patch delta 704 zcmV;x0zduK1=t0UB!8btL_t(|ob8)!j>I4chTYBH#QPtqciA6JjNwaEtaj#o{?%Hb zpjenpN&o-=0001dC)agd*X6%u%zqufyA4Ril^^5NF8+2Kpd!XY+zmPBdpze%=J-c; zv3Um&hmzeuTq6z=A!Ux}X!0x{d7dM70CARc?T<;QJ+4LcNq_dA0cpXZnk!Pv>3h$f zodGCsUZ;XPr}N34b!yBxGykNNem3g1bAotIYR9RzqR&5s0RR9106-tjdevxfih~7h z#3_o4^~}+#X!1tkRokjogjP>!7+?C6HrOun+v$-ufE57Zi@IO^w#_r^)BxZ zqkY;g($#nOOJZ;WACiS$O2f&B!BU=Zuh>o?BQrAjrN@i`MYiSq(y8J(w5HHx0GvX^ z{!Evy+QoJgX~z5BUeF~q|7zWyT0R%_Jk)NV!9Tt#Mm8QkHpmxDM>TpHTW zH5Qb;1AqM5Jt~O&flE=o#%wp#&@|I%)V5I>7kjSUfaaX-xqCJMP0tSW;7a70Da#|u z6Q^FW24f4ZLwfV*w-ZQmWDh>l%yrH|;}r}`{Feh!oZ10)57Kj%iu*%*kgVl;b=z-l z?}OMZ)cXZ7D1CBH?}LFpT9@?gjiPbHA2bZsra9CD=%@pd`?roj0$sm4mf=+e00000 m000000000000000AHYAp*j2v4I}w%u0000`S1=IzQB!8PpL_t(|ob8)Qj>I4gMd?=GB=(16<5_n7iRPj;sAR4lyR) zvWv|-KsZ$F2H_gBQ3%OnOh=1%b<6!cVh0Fk1=oI`gwo?)M1SvO{~3@L9I8h_syTh{ z*|ReMdFEv*xN^E499gGe%ro;(O6g~#Zk!X$bJ9Cby%qiZLzoak2qA>DQN6E%0;k!S z@meBsw9LpD?+PuZv*OCOsubbfr#!%y{)hqCWpN`T()vIF5WXlcu3~_$nwdAF>Wgt> zyx!b}Yj#bl^?zVJLE)b{%gD?p=57^v1IY1SG`q|c6tpBb1u(utT4aub`6=j%KVC9% zQKF?!4wk>SCc2~;r}tnafzEZVr$TG_%yP8$`1m0<9-)a9&}%y5Cdm{uaT(@Z)N$ly zV@grUNf&VyVwib!Py7tiLMrZE@tL)bCTsEOIvpV2?SFca_dD)H&k2Ct`y%gm<9*jI z($zfR8)EPfJ|PRemx_}agQeWzUbCDaTDk@5$A}Fbim=)GF{t8JyrR%Z0D=Ec$Z^DOkbX5G26%<^$bg##}N{li=x-sbhz z6y5=z1b=V;Y5BTqixYjcF6rZq0(it9G(7G|sk>>r2Q?(!)Ke!g;}kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png index fda030d56c962bf18cefd5b175cf5f284825a115..e7482655c77dd6da49ee88968605960861ea4eaf 100644 GIT binary patch delta 751 zcmVP`d_A(#zM96O-!Bpj*k5-8y z#+ZlUrn(dW000000N%-Yp67YSzcT8796#9(lq-~96VopKW;>uFj)%A!j^n81$8nH4 z@scc(R{#kpSq&sKVj(ed)e!?tp5-O$*=r`n9(KM4Z>00000hc3bL3ots> zcKQ5|_~2}0TwAs9RRiFbcSXa}g4*Dc`^$BC5pOZ##i#v1uDh;E)7EcI@m5F)FBDB_ zW{HJMc8!Zj+JD79N^oVl)n-2Mziuns!@JCimb=^_EK);>WWSPIwnuj&56|>1)X=Ay z)ZOaic1|9)zi0)J98jb+p_R1tZ&^TNX0@7=UeN*I=IkV_IXdi6kgitZHAS;-uOnf( zYFc$}58RsL>CT5>V>l~6?H5qS7eE%-?*JhBw_^wd@_+uh^FsbI)KFs#7T^RKWAG?E zypOz;=f|@6OK{^zXUI535srx2u{;+~kld?ET7K;n2<_WuugVlL8*wS_e3uGTac;t7 zJ_ZHI2-{uVUJ=2LA<+B!9+9L_t(|ob8)ia>F1DMQNuy@&1>@Uiy*NqtOEi3`TM8`RF)A z2#^q9k(L4g00000z-Llxt+mF#YRJDG-@7|dPE$U{rd|B(?tqEv4>cN&<9L-H$H8Rc zCA-)h0nDH*8klL+LZ;-DQ4P)N%98s@5dq9t!MQ)Cfm+=1=zpE;-vi2mP4yrY&**#i zo}CUjM^2Z5*P1ScBlEN&lXLwkrF?B{yS*l;`=qsA)7pfM;q zs@8Y;MDyKqJWYEDZm(MO<2U^RneiK7q4wthSbu*Ok?erJilzh`kuJqM z-_Aira8ePKV3h>v>g(94jAhx>KFgl7j;X<<)(S?p`mtj??AfxToDR}+sx~=1w~G4E zaBwhsu74L=LvC1qS}sT?eB8EK#dup%cr0Run^TDonUdnixfC{?rDY@cEtXnWKy8=R za(mcCItQ@ZvG~~9K9F8yE{V6>CFwf8<$!qJ@f2&{!%1xe*EOo#K`i?O;g`#7S~Syn*bepsHO7uv3jJVUeUN zNkTdYM9zrqI}p`RX-Ve*IcFtrVc8(>`X+qwN1u6kR|hkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_v1_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_v1_0_0/00002.png index fda030d56c962bf18cefd5b175cf5f284825a115..e7482655c77dd6da49ee88968605960861ea4eaf 100644 GIT binary patch delta 751 zcmVP`d_A(#zM96O-!Bpj*k5-8y z#+ZlUrn(dW000000N%-Yp67YSzcT8796#9(lq-~96VopKW;>uFj)%A!j^n81$8nH4 z@scc(R{#kpSq&sKVj(ed)e!?tp5-O$*=r`n9(KM4Z>00000hc3bL3ots> zcKQ5|_~2}0TwAs9RRiFbcSXa}g4*Dc`^$BC5pOZ##i#v1uDh;E)7EcI@m5F)FBDB_ zW{HJMc8!Zj+JD79N^oVl)n-2Mziuns!@JCimb=^_EK);>WWSPIwnuj&56|>1)X=Ay z)ZOaic1|9)zi0)J98jb+p_R1tZ&^TNX0@7=UeN*I=IkV_IXdi6kgitZHAS;-uOnf( zYFc$}58RsL>CT5>V>l~6?H5qS7eE%-?*JhBw_^wd@_+uh^FsbI)KFs#7T^RKWAG?E zypOz;=f|@6OK{^zXUI535srx2u{;+~kld?ET7K;n2<_WuugVlL8*wS_e3uGTac;t7 zJ_ZHI2-{uVUJ=2LA<+B!9+9L_t(|ob8)ia>F1DMQNuy@&1>@Uiy*NqtOEi3`TM8`RF)A z2#^q9k(L4g00000z-Llxt+mF#YRJDG-@7|dPE$U{rd|B(?tqEv4>cN&<9L-H$H8Rc zCA-)h0nDH*8klL+LZ;-DQ4P)N%98s@5dq9t!MQ)Cfm+=1=zpE;-vi2mP4yrY&**#i zo}CUjM^2Z5*P1ScBlEN&lXLwkrF?B{yS*l;`=qsA)7pfM;q zs@8Y;MDyKqJWYEDZm(MO<2U^RneiK7q4wthSbu*Ok?erJilzh`kuJqM z-_Aira8ePKV3h>v>g(94jAhx>KFgl7j;X<<)(S?p`mtj??AfxToDR}+sx~=1w~G4E zaBwhsu74L=LvC1qS}sT?eB8EK#dup%cr0Run^TDonUdnixfC{?rDY@cEtXnWKy8=R za(mcCItQ@ZvG~~9K9F8yE{V6>CFwf8<$!qJ@f2&{!%1xe*EOo#K`i?O;g`#7S~Syn*bepsHO7uv3jJVUeUN zNkTdYM9zrqI}p`RX-Ve*IcFtrVc8(>`X+qwN1u6kR|hkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_v1_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_v1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png index 6c57d4dd591edcb595d432c52143dba70d3e23c6..a1c75c5517bae0139dfadc7e1ddb513613ca0748 100644 GIT binary patch delta 892 zcmV-?1B3jP2a^YoB!5~-L_t(|ob8%Pve+ODM4ex`3HLt|cgezui)f+|0uQCPa$yic z%xxb>k|arzBuSEdiCSx|6@O*qkMhT^u1%@`(27U#v%=`nxVto_I6T&3wo=OVwtcos z&G0+iqK()FaW<4vv_Rk~J|B#-;VhW}+Hh+FO5XA|^PyKt5q|?s%JLLa1Z|q{rOYOuZOFzDc|QUyF!vANs=&z zq|I)&+F+!B{(nU6kVAHMoQt}RJQKTq7%@d&b$yEhw+W7tE|wP52AAAr#CsNZPRlS# zdy&@0!Kt2#ckkM0tHdkbA|u6a4#~#tc+h45i2{;MoUq+R2{+D*XtR?KUU4{siFjF& zP2U5q@mLj6=uk$Sk>BA1n7EVOA7omP;F5)9lA-T5dw*CcM@K=HZzS`jR|j_9BIpd@ z9^0ERM~oNwz9`~0jzh}gTcvpV=(b3-W91KD5Vx(cODl>sPOSa3FCIQyzX6%Ve>>p4 z(cf_$jYeKbU)PNHqJ}#AU;~{XXCExZ6JD~&f+jRwVKtM7RK(}e2)OlN+Op5X znePC+v40*Zg4{~T3CcK7@#_pXb!8TBNo|U#D72!JVG36xjGJ1OG}_?99FN{V&6AvZd}v2&)gaCXWmW+;BoZP)u_SZQT~9Q zaGB4&^2Dg2r$aMwe9;zt66JGe2DtYYu;7q=dw(yz5$>2zE1lvYv3Q6ZI4}4h^KAk? zN$#F&rW;9;Bni&1ZjSjSo@*xa5(;8xRC+olu7s-?6+uBGlUgZaXQ+yhX8IUD1!)?j zo#-%r=#uAZYVRLY?QQEes1WyE(H;(X0Fq~}K91S}X8@ODMTN2}c@p^(bP1eQF={9{ z*mbM)hbT`$#*0{^D3FN@J>u;sKC@wJ=uUAa@HgJTUDs#l&YyEdZja;1{6D6k9v7yD z+WV*GlXx!F4vRyFPF`1_LTNND#QuYLwZelqpK9pMJZ=y81`kn)lO#!!NAm|(QjM3o S_rX5^0000CeD9I&ZR%nouUD8qi7z*`Z{G4 z5#KvG$B`sSk|arzBwwP|T5H808Tq69v8$sg^&hR`QT(hhdJuP)#uP`!TFq8Uxt`MB zcBvVDhg-B!+n~;dQc5cjc*>X$M%i$d%z)N#qXA`4Wt-*DD}SY^fo5f83adh9K#*03 zuy6)2kHN7&W`PE@)uRTkkrB(n4hSDCa-`F~ImdNWrQ5cy_$BCaozC<#Kr%BjzKlG` z`U5iT-XyC|L3F`oiEMBoYwMM#by8F_fK{kR09pl2+_^u0iup^%>TAmPneTuoPm&}_ zlEjZo-Rx$o1b-t1@#mKN*QRq(R}MTAyRI0)LLPN}3jsG6)%P7Kf(DmeXVj~f^skk{ z3%yIL{dDRO>fO5%ZI!tsn`5NdZDHA@ok3bNfJFhxrq0>!qJ$V%^S7pEt5nzcWLcGc z?*pzOSsS|0(HL|_ey;;y;!bwIkYOOfWoyd}uJ<;3SbrtP#e(b1w6_9#ZXJ9Es2<_br!VJ(iN66Qw8X-xB0{V@cO)Qv}KNczXd0y6oHA>0L;##(%WZS)LG!C-~sv9WP`)Ow23E8>U;s zha^do1m{;b$Nc&(HIsP>1+nARosNn7;3~WdC}?C-C`IhJst9T3817S$sv~w22aF#L zy>kP#_l;@mDRmo^hx@LyejM-sWWS~Q=(PjR0I9{Q3T0RFWb!BI5;&_IQp9AQu9q zRt_=t!Ouh0b7AYS=sI-Dx&jqSqiG@bAH=H_9>n=nLvQABd%!n%f;^lgNs>IBKOHiR UUeIgjH~;_u07*qoM6N<$f-*F_VE_OC diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png index 562b8c3a7d73de03a021e86dd7b6a40d2558ecef..ecf2346df930b5f6b40ebfc49af92e28a2869d42 100644 GIT binary patch delta 477 zcmV<30V4kR1NQ@vB!9k1L_t(|obA~`j>8}fKvAZen{fXlahF-NijV=vq&7jB{}x>& zln?`k(v$!I0D#9RrIb?ax0Lc;?Gew?+t8K?YThfN()u+b>YvrdG3T6m&8x4sWg=eZ z*S$tX_XWBmG3Pvrg8fR@=$7&8?)+zf2&kA1;@!Fz(_qYY1Ai^P+g=$xV%BKVd?{)M zh~^r{{8_8A4dODc{rC2aA^qu06Xa( z2U*IOit)R8wSVikI!h1ZBD5RxYg_fvuf=FlM-e0XP#qokOpVR%{7`1ez5C0JW@LnsN^{47N3@?g6z@(*D`?KH`i)gJRw%6ppoND#@9RZ?0kT;O9!NwJ`m@l zb~-aQs|cM{&s&zq)pK~|#hKCdQP@~Us#J|F)BF{eK% z=o!%$|H&wS(cG)Q{OmJHA8#0H`e1>RAkzn-2rmEt00000000000000001)O6QERM# TmN?)=00000NkvXXu0mjfz>elY delta 478 zcmV<40U`eP1NZ}wB!9n2L_t(|obB0Bj)Wi#fMI5`H{t$A;x6;xWKMGARK70056sN-3rI4;l4m^+#OG?n7HAsC(~-M(f*%X#cD>jydO~b+0aO>qOkn z-}Dv@>J6wfG3VTig1daX+(0}6GwxoB7vwDl>M^P(4 zbk{leueDGI*BNe6?bPI$D{26y&y;qi*JE=`eCI_y)s{WICa0ipzw1O^Cx6;)-twNabTcl3=X+|X_o=u*$ab{B-renO`1q%%x;TuT{o7wIH(CMe zG^`8l9liG4?-y+SPy2V+PN-c5;93%}$L2y)>lei86x8G2%k(=k&*r-~y9_`I7z436 zTIU>*e{LjG(1LEAin2W_cH;J@b#+fP!XUi2zY^H|Z&yL0=2rJ5I`gg%?64#sPps+x z6!d`Tiyvf+-)C;8KY_Mdr_a_6HDj>AAjphCD8dT>000000000000000004yf0DNPs UuoA`kCjbBd07*qoM6N<$f-L6l&Hw-a diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_missing_nonwitnessutxo_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_missing_nonwitnessutxo_0_0/00002.png index c6b820aa9ea685e7571ff9c9d6abeec5df7452ef..1e798bb2a48988837e7c091787b148b163276ec9 100644 GIT binary patch delta 403 zcmV;E0c`%Z1GWQ@Eq_~b!ypVmQPSy7*#DB)OF!r^gr~5Pt;F|yVHYrn2F9{;00000 z000000002sF+vE!n@bgJ`nh`m|EA&d-dh;Pb}#J*q$#Bc4(`O8#bv4!%SH2M;MnJlKep&RL)dgsG`+d=O=Oz_G zP>sn`*1)C*?Lr1kg3KDIG8A6z7k%wb{NqU$;BW+shL%@i+naFyicyybIm@DxR410} z*P>~9wP=`Mx_?%Bbuh?Y=G9In<4r!*V%kNW)k3p}`m)!suCqGG>8K97C>JCgw7iej z-LnZfxcq&1`GfODwT5o|cW=Bq{fjZxL$!Ib_0MHHbV`dNP2PvSYm>bzqq?^*Y~H`L zR~x5(Dr%j%J?fgxukgQ%b^qLG{dV$p*uzx*9l`ZI7tdFH+7aInceB?g-P`ZLy}Qfq z1x`=&?+JTzWATiIHv_+yIp zd)o2UixO)ktLl%hp6u7>7x#Bg%Aa8VP@d>3mQgR!>OzO}3E_>|k{<kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_missing_nonwitnessutxo_0_1/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_missing_nonwitnessutxo_0_1/00002.png index 6c57d4dd591edcb595d432c52143dba70d3e23c6..a1c75c5517bae0139dfadc7e1ddb513613ca0748 100644 GIT binary patch delta 892 zcmV-?1B3jP2a^YoB!5~-L_t(|ob8%Pve+ODM4ex`3HLt|cgezui)f+|0uQCPa$yic z%xxb>k|arzBuSEdiCSx|6@O*qkMhT^u1%@`(27U#v%=`nxVto_I6T&3wo=OVwtcos z&G0+iqK()FaW<4vv_Rk~J|B#-;VhW}+Hh+FO5XA|^PyKt5q|?s%JLLa1Z|q{rOYOuZOFzDc|QUyF!vANs=&z zq|I)&+F+!B{(nU6kVAHMoQt}RJQKTq7%@d&b$yEhw+W7tE|wP52AAAr#CsNZPRlS# zdy&@0!Kt2#ckkM0tHdkbA|u6a4#~#tc+h45i2{;MoUq+R2{+D*XtR?KUU4{siFjF& zP2U5q@mLj6=uk$Sk>BA1n7EVOA7omP;F5)9lA-T5dw*CcM@K=HZzS`jR|j_9BIpd@ z9^0ERM~oNwz9`~0jzh}gTcvpV=(b3-W91KD5Vx(cODl>sPOSa3FCIQyzX6%Ve>>p4 z(cf_$jYeKbU)PNHqJ}#AU;~{XXCExZ6JD~&f+jRwVKtM7RK(}e2)OlN+Op5X znePC+v40*Zg4{~T3CcK7@#_pXb!8TBNo|U#D72!JVG36xjGJ1OG}_?99FN{V&6AvZd}v2&)gaCXWmW+;BoZP)u_SZQT~9Q zaGB4&^2Dg2r$aMwe9;zt66JGe2DtYYu;7q=dw(yz5$>2zE1lvYv3Q6ZI4}4h^KAk? zN$#F&rW;9;Bni&1ZjSjSo@*xa5(;8xRC+olu7s-?6+uBGlUgZaXQ+yhX8IUD1!)?j zo#-%r=#uAZYVRLY?QQEes1WyE(H;(X0Fq~}K91S}X8@ODMTN2}c@p^(bP1eQF={9{ z*mbM)hbT`$#*0{^D3FN@J>u;sKC@wJ=uUAa@HgJTUDs#l&YyEdZja;1{6D6k9v7yD z+WV*GlXx!F4vRyFPF`1_LTNND#QuYLwZelqpK9pMJZ=y81`kn)lO#!!NAm|(QjM3o S_rX5^0000CeD9I&ZR%nouUD8qi7z*`Z{G4 z5#KvG$B`sSk|arzBwwP|T5H808Tq69v8$sg^&hR`QT(hhdJuP)#uP`!TFq8Uxt`MB zcBvVDhg-B!+n~;dQc5cjc*>X$M%i$d%z)N#qXA`4Wt-*DD}SY^fo5f83adh9K#*03 zuy6)2kHN7&W`PE@)uRTkkrB(n4hSDCa-`F~ImdNWrQ5cy_$BCaozC<#Kr%BjzKlG` z`U5iT-XyC|L3F`oiEMBoYwMM#by8F_fK{kR09pl2+_^u0iup^%>TAmPneTuoPm&}_ zlEjZo-Rx$o1b-t1@#mKN*QRq(R}MTAyRI0)LLPN}3jsG6)%P7Kf(DmeXVj~f^skk{ z3%yIL{dDRO>fO5%ZI!tsn`5NdZDHA@ok3bNfJFhxrq0>!qJ$V%^S7pEt5nzcWLcGc z?*pzOSsS|0(HL|_ey;;y;!bwIkYOOfWoyd}uJ<;3SbrtP#e(b1w6_9#ZXJ9Es2<_br!VJ(iN66Qw8X-xB0{V@cO)Qv}KNczXd0y6oHA>0L;##(%WZS)LG!C-~sv9WP`)Ow23E8>U;s zha^do1m{;b$Nc&(HIsP>1+nARosNn7;3~WdC}?C-C`IhJst9T3817S$sv~w22aF#L zy>kP#_l;@mDRmo^hx@LyejM-sWWS~Q=(PjR0I9{Q3T0RFWb!BI5;&_IQp9AQu9q zRt_=t!Ouh0b7AYS=sI-Dx&jqSqiG@bAH=H_9>n=nLvQABd%!n%f;^lgNs>IBKOHiR UUeIgjH~;_u07*qoM6N<$f-*F_VE_OC diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_missing_nonwitnessutxo_0_1/00003.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_missing_nonwitnessutxo_0_1/00003.png index 562b8c3a7d73de03a021e86dd7b6a40d2558ecef..ecf2346df930b5f6b40ebfc49af92e28a2869d42 100644 GIT binary patch delta 477 zcmV<30V4kR1NQ@vB!9k1L_t(|obA~`j>8}fKvAZen{fXlahF-NijV=vq&7jB{}x>& zln?`k(v$!I0D#9RrIb?ax0Lc;?Gew?+t8K?YThfN()u+b>YvrdG3T6m&8x4sWg=eZ z*S$tX_XWBmG3Pvrg8fR@=$7&8?)+zf2&kA1;@!Fz(_qYY1Ai^P+g=$xV%BKVd?{)M zh~^r{{8_8A4dODc{rC2aA^qu06Xa( z2U*IOit)R8wSVikI!h1ZBD5RxYg_fvuf=FlM-e0XP#qokOpVR%{7`1ez5C0JW@LnsN^{47N3@?g6z@(*D`?KH`i)gJRw%6ppoND#@9RZ?0kT;O9!NwJ`m@l zb~-aQs|cM{&s&zq)pK~|#hKCdQP@~Us#J|F)BF{eK% z=o!%$|H&wS(cG)Q{OmJHA8#0H`e1>RAkzn-2rmEt00000000000000001)O6QERM# TmN?)=00000NkvXXu0mjfz>elY delta 478 zcmV<40U`eP1NZ}wB!9n2L_t(|obB0Bj)Wi#fMI5`H{t$A;x6;xWKMGARK70056sN-3rI4;l4m^+#OG?n7HAsC(~-M(f*%X#cD>jydO~b+0aO>qOkn z-}Dv@>J6wfG3VTig1daX+(0}6GwxoB7vwDl>M^P(4 zbk{leueDGI*BNe6?bPI$D{26y&y;qi*JE=`eCI_y)s{WICa0ipzw1O^Cx6;)-twNabTcl3=X+|X_o=u*$ab{B-renO`1q%%x;TuT{o7wIH(CMe zG^`8l9liG4?-y+SPy2V+PN-c5;93%}$L2y)>lei86x8G2%k(=k&*r-~y9_`I7z436 zTIU>*e{LjG(1LEAin2W_cH;J@b#+fP!XUi2zY^H|Z&yL0=2rJ5I`gg%?64#sPps+x z6!d`Tiyvf+-)C;8KY_Mdr_a_6HDj>AAjphCD8dT>000000000000000004yf0DNPs UuoA`kCjbBd07*qoM6N<$f-L6l&Hw-a diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_v1_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_v1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_v1_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_v1_0_0/00002.png index 6c57d4dd591edcb595d432c52143dba70d3e23c6..a1c75c5517bae0139dfadc7e1ddb513613ca0748 100644 GIT binary patch delta 892 zcmV-?1B3jP2a^YoB!5~-L_t(|ob8%Pve+ODM4ex`3HLt|cgezui)f+|0uQCPa$yic z%xxb>k|arzBuSEdiCSx|6@O*qkMhT^u1%@`(27U#v%=`nxVto_I6T&3wo=OVwtcos z&G0+iqK()FaW<4vv_Rk~J|B#-;VhW}+Hh+FO5XA|^PyKt5q|?s%JLLa1Z|q{rOYOuZOFzDc|QUyF!vANs=&z zq|I)&+F+!B{(nU6kVAHMoQt}RJQKTq7%@d&b$yEhw+W7tE|wP52AAAr#CsNZPRlS# zdy&@0!Kt2#ckkM0tHdkbA|u6a4#~#tc+h45i2{;MoUq+R2{+D*XtR?KUU4{siFjF& zP2U5q@mLj6=uk$Sk>BA1n7EVOA7omP;F5)9lA-T5dw*CcM@K=HZzS`jR|j_9BIpd@ z9^0ERM~oNwz9`~0jzh}gTcvpV=(b3-W91KD5Vx(cODl>sPOSa3FCIQyzX6%Ve>>p4 z(cf_$jYeKbU)PNHqJ}#AU;~{XXCExZ6JD~&f+jRwVKtM7RK(}e2)OlN+Op5X znePC+v40*Zg4{~T3CcK7@#_pXb!8TBNo|U#D72!JVG36xjGJ1OG}_?99FN{V&6AvZd}v2&)gaCXWmW+;BoZP)u_SZQT~9Q zaGB4&^2Dg2r$aMwe9;zt66JGe2DtYYu;7q=dw(yz5$>2zE1lvYv3Q6ZI4}4h^KAk? zN$#F&rW;9;Bni&1ZjSjSo@*xa5(;8xRC+olu7s-?6+uBGlUgZaXQ+yhX8IUD1!)?j zo#-%r=#uAZYVRLY?QQEes1WyE(H;(X0Fq~}K91S}X8@ODMTN2}c@p^(bP1eQF={9{ z*mbM)hbT`$#*0{^D3FN@J>u;sKC@wJ=uUAa@HgJTUDs#l&YyEdZja;1{6D6k9v7yD z+WV*GlXx!F4vRyFPF`1_LTNND#QuYLwZelqpK9pMJZ=y81`kn)lO#!!NAm|(QjM3o S_rX5^0000CeD9I&ZR%nouUD8qi7z*`Z{G4 z5#KvG$B`sSk|arzBwwP|T5H808Tq69v8$sg^&hR`QT(hhdJuP)#uP`!TFq8Uxt`MB zcBvVDhg-B!+n~;dQc5cjc*>X$M%i$d%z)N#qXA`4Wt-*DD}SY^fo5f83adh9K#*03 zuy6)2kHN7&W`PE@)uRTkkrB(n4hSDCa-`F~ImdNWrQ5cy_$BCaozC<#Kr%BjzKlG` z`U5iT-XyC|L3F`oiEMBoYwMM#by8F_fK{kR09pl2+_^u0iup^%>TAmPneTuoPm&}_ zlEjZo-Rx$o1b-t1@#mKN*QRq(R}MTAyRI0)LLPN}3jsG6)%P7Kf(DmeXVj~f^skk{ z3%yIL{dDRO>fO5%ZI!tsn`5NdZDHA@ok3bNfJFhxrq0>!qJ$V%^S7pEt5nzcWLcGc z?*pzOSsS|0(HL|_ey;;y;!bwIkYOOfWoyd}uJ<;3SbrtP#e(b1w6_9#ZXJ9Es2<_br!VJ(iN66Qw8X-xB0{V@cO)Qv}KNczXd0y6oHA>0L;##(%WZS)LG!C-~sv9WP`)Ow23E8>U;s zha^do1m{;b$Nc&(HIsP>1+nARosNn7;3~WdC}?C-C`IhJst9T3817S$sv~w22aF#L zy>kP#_l;@mDRmo^hx@LyejM-sWWS~Q=(PjR0I9{Q3T0RFWb!BI5;&_IQp9AQu9q zRt_=t!Ouh0b7AYS=sI-Dx&jqSqiG@bAH=H_9>n=nLvQABd%!n%f;^lgNs>IBKOHiR UUeIgjH~;_u07*qoM6N<$f-*F_VE_OC diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_v1_0_0/00003.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_v1_0_0/00003.png index 562b8c3a7d73de03a021e86dd7b6a40d2558ecef..ecf2346df930b5f6b40ebfc49af92e28a2869d42 100644 GIT binary patch delta 477 zcmV<30V4kR1NQ@vB!9k1L_t(|obA~`j>8}fKvAZen{fXlahF-NijV=vq&7jB{}x>& zln?`k(v$!I0D#9RrIb?ax0Lc;?Gew?+t8K?YThfN()u+b>YvrdG3T6m&8x4sWg=eZ z*S$tX_XWBmG3Pvrg8fR@=$7&8?)+zf2&kA1;@!Fz(_qYY1Ai^P+g=$xV%BKVd?{)M zh~^r{{8_8A4dODc{rC2aA^qu06Xa( z2U*IOit)R8wSVikI!h1ZBD5RxYg_fvuf=FlM-e0XP#qokOpVR%{7`1ez5C0JW@LnsN^{47N3@?g6z@(*D`?KH`i)gJRw%6ppoND#@9RZ?0kT;O9!NwJ`m@l zb~-aQs|cM{&s&zq)pK~|#hKCdQP@~Us#J|F)BF{eK% z=o!%$|H&wS(cG)Q{OmJHA8#0H`e1>RAkzn-2rmEt00000000000000001)O6QERM# TmN?)=00000NkvXXu0mjfz>elY delta 478 zcmV<40U`eP1NZ}wB!9n2L_t(|obB0Bj)Wi#fMI5`H{t$A;x6;xWKMGARK70056sN-3rI4;l4m^+#OG?n7HAsC(~-M(f*%X#cD>jydO~b+0aO>qOkn z-}Dv@>J6wfG3VTig1daX+(0}6GwxoB7vwDl>M^P(4 zbk{leueDGI*BNe6?bPI$D{26y&y;qi*JE=`eCI_y)s{WICa0ipzw1O^Cx6;)-twNabTcl3=X+|X_o=u*$ab{B-renO`1q%%x;TuT{o7wIH(CMe zG^`8l9liG4?-y+SPy2V+PN-c5;93%}$L2y)>lei86x8G2%k(=k&*r-~y9_`I7z436 zTIU>*e{LjG(1LEAin2W_cH;J@b#+fP!XUi2zY^H|Z&yL0=2rJ5I`gg%?64#sPps+x z6!d`Tiyvf+-)C;8KY_Mdr_a_6HDj>AAjphCD8dT>000000000000000004yf0DNPs UuoA`kCjbBd07*qoM6N<$f-L6l&Hw-a diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_4to3_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_4to3_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_4to3_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_4to3_0_0/00002.png index 75380d48cf25b3a97c481feebf61f660a84b513a..799eebf325c03dedf2eeef5853b65a1fae4f5c5a 100644 GIT binary patch delta 923 zcmV;M17!TW2eAi`B!75GL_t(|ob8%hcHJ-tMb)g%MDrh#=hBbcdQky~qnGVC?5_k# zfL=)Ax|AeIk|arzBzY6ZaU93N7lHb#{K4j=(%s!aAq1NgR1TPu$0kmDtmL1?NH#wk9sqV90dVjT6bD*2HTGE)%6&SSX zC2ZUQjmPBLAJZTQ)SFR2*UDJSt}~!)I8>{kM1wwQ`m&>I{REt@%bos->AEtrzCax& z{*Vm2H_5IYAOmhAY!(+2ThBV)O;J|}?Vgxd0BJ%BuRNb$#e6*6{Y-g3-{n+Dk|arf z3cr|2-YuTFnSTxBXP9d8h0!!Lz4f|KR4;I+fS$#KS-_7lyc_gh9?1Im@;+=XRB}-+ zNDglEiZNeU+Bv+6!xu8I4WJE?*(A>sZz#+j&HC@{0FYQW|2_os+D?U`w?K2_9+op6 z@prU54+fy4ee$4eA5lRXcHo{t$)|>pb1zDi1?36sI?)eIZujz z@|b{Y;y|*V)W*{s58xgl?;4CzaJ(1ixMsERtc{*e);43Yk$=g8NA1nG(!|EU6Y%2E ze_$TpKA)cE<%@BLI_Ka5fzDHpT4(ljI25Ly6SMi4nCcmvcSv5X4WJ5n)9e>UkFVU|{H~ACJtGfgARGUK6Z_u_k z;o$|-F+JeZf>7sxC(U^?o9wwa7QL0%{vh*R$O%Z2B>A~e--ZIrBngvU8L$#w`0#Jv z-jy8RP@n!oA$SA;$(RXG51E+6!kJ`)2h%*xhRVe|mELnaYrgwnOz@AO5?4?{>dS%a2LJDMmzzx zpF-YAes=XCiQA$aW9WVfUvM!XP3+63l6)M{-gY?_>;Q1E=+Z_ABml;Q-U>|x9^kE6 xjd5PPdV3Uk6>GO$CgW}0ZBuQ@K4-}HYzG8mNF2Vo+002ovPDHLkV1m*@(tQ8` delta 933 zcmV;W16usC2fGK5B!7ZQL_t(|ob8%jcHJNhglSH9!v2@!z4YNGJ}MHU0fg{5~>Ns=ToTlF@J-(8fvY*j^In?VgPN!*|Gw9(@l10^Hl$4J%9CTt!76zZFNcGLRVnW zu0zL&8 z)M54?lIidk*_8#!4Yw(5CKt1}o^^VeqFI4-VWt4mg)F@Ce0~+{myF%ll=rhf08x=7 zNs=TwonUc_ulVkZ71{@{-Xs)Y10hFX|`YUj*#L;|hVFLN`4a%^%46IDen> z|>V}G{^K2r+*vHDWmm=i5TX1)&Rs}j=`mA z3_-gEHSys?*aW1B+Oi92jifmnKoTJn4aOrl-b?4WW~~enyMYE;yIx8o6WK5M;8APy ztu!0s_W-=O_aCU^+X=$cqI@ykuFf&I0H>3447M`Xy`#IQ)*j}3frh54G33sz#)sWF z4W7G9cYpMnj2Z!Yi|bY#6bqTQqk>0oGo7;ozAJETPDIk2H>+aLy?fDHdGiaIe}Wu7sA|B$)sr{T4C57hD`Su*5ex+Y&3-d6u>GOz+BT4i^2iDFh_| z#)V!AO$8nhtyzr;UWa=7F7hg3mtBf+Hy)D%kR(ZxBscK~Hk-XEpF`Uv00000NkvXX Hu0mjfP!z`( diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_4to3_0_0/00003.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_4to3_0_0/00003.png index c2d8654a780149bb739ecc980c06e43e1df01431..3864b4f0429283b45c8cd67f17e721d8fbd64f42 100644 GIT binary patch delta 396 zcmV;70dxMT1EvFzB!6v5L_t(|obB0Lj>8}fKv7!FPT2pF*vov36d{9&Lu^Vj_k2}^ z5My3#ni2p20Pq;4lv0ZQ(xARqJmOj77}`2P;k_dot-BG?{#9)rbIz$3UR~bSiRjLc zdy50z4s>T?&RNTXy`)RKWW3#-{|XQZ6{|t?ty`FsIonONxPP}T(H?P?wrFmOS^*+l zA&H3`hZoYObWSq>mqM32fQv<{9_EjoL zdBG>@)R#oH_J3ZCbQ3!GU@zP-`%y3BV8j4?*wTN*?&!WXTX1hQIRM(LkD!Y-<{$70^Ypul!PnP#}GP?5$ zZ*juxfH@Out)ndXOH89f&eOxiuK<-$wHj34%)&C5vu2{zxqp4h=n{L47R^anD?o+o zocqUGkjZtXTUFaNIbvlEK=@4QXSy7l_r!Nz)Kl%UyI1fQ^od(;1@8p)l|7SdzMF6E zKmL{vM|jdBwz>J9VBY9Px6{6nzRtX4Gln8o(&%!NsNfaykdghQa&sXA5E2Oh007q2 zgfe)+r|QTvT;;@{|X@KKK6vdws7nK@|Cy|8NTn_U@O);C_awW(+Q{kz~do t73l>4000000000000000007eb0VhFbT7-&N`Tzg`00>D%PDHLkV1i6uz)%1H diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_4to3_0_1/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_4to3_0_1/00000.png index b0e1548fa41115c7d06c960e2af409d9c09f2a1c..02aa2d99e3c3a17d379a32839437cafc86717128 100644 GIT binary patch delta 401 zcmV;C0dD@P1FHj&B!6;AL_t(|obB3Ma>F1DKvAdDov{BUv6p@@<7mXggBv3$-1E_) zuBnN5#K=Al00000008XbW!-@La?WQtrDWKW{|MOuGW1f!Ziv?bXY^&bn+HSqv2MUk zD$wEL9#zg+u0P{nLx?&9V5T?BBM$!~?hH_|ju`qP-d)haZGWf}-?0$`0000U=Y7MN zh1rS^HRF{dC=p%*try<#ZU&D4Z zjh{G9{Rf|N&hn$V>wwZY6~w7ro9D!wioQGJB}kn)b#k-pfx8({lV4ev!)NMb0001B zDYz&B_pdtvhg& z3Us)*N0oDy>(BVl5TecinCYG75l{ak?hH_|ju`qP-c``SWq+s>-?0$`0000U=Y7MN zh1rG=b?M_=cU7e}4SVt^`PE|Ng5@R=p%*t)sXDK%dj6! z<2#O1|G}r6v;1oA2B36K1#v3Z<~cE^qVLXl2~tN+9o#H?;BE%gy;Aw`Z|1JZdZqcZDW4QS2G5{sSDW$Ve>dlvan`~$=XE|7%)qR3@TJ<8U u>dBtI>npF;cUgkmVgLXD0002MLVrv5Mhv_a3RD0900{s|MNUMnLSTYrz%AU$L%YUKQdsh?9>dHIJg)D#| zU2h?A2C#_1u|H>lCe-RthoOm{&M*!-A-aNTKzZL82VfJgv`}13Ng`y~m z;;--lma`7>2Y(J{j^;D%*J{pQR+AG7f%nbqaL*9dWTfFO`Oc*AvCmGPJ+h#JUJpgwAkt+=VgwE_}nSGJ+|VHV`pj}M z6p|XD?_vVp0dlu#gNHv>jE%dAVWs*-g2BBwXS`{wu)XZ9FMOp~g_tQiw(S&3mUbns zIshcG4~mf7RjBX@l3aa|icBx6h9XAspQj;ZQn8MM@}%#d{pDGc9o*Af=W8z$)z9D` z{6Re@Y=1k_I`d~KsssiKOo%C2MqWHsqyW9WR~~0m{PGG<@#N zscE!gsH;%*f?deJL#=b7VlA~46yN@s7NqJSmQXP?U3{fQT1Zl6Mpx8OSqXdhkQyoj zof~(ldxkZGSNw*;;@D3UZ(Hokpe>AAmgVnjwtvW6u)>;$->B6YAeRC;eA!EBy9^;2Id2UAM|L#hltnr2i&Nb)}6bb}P( z4`->7ITo7n_Ah^ViO(Tbn`4jYQyGaBp|sGx&wyP_~Uo{cmD>R7J$m{VEJ>8X1Xf$jKm)*{p3W3kf>f?c9Kj!+(ffCe%O(}wQu9bJb zf@ZyT(d>IwPxYM{%u`m3DycF~`Be4Dsv|D;=cUrH>2;u(T854{n^-r&iqJ_n$K5n$ z--T~^cLwCLv*yzD#BF}UYZqeV^cON&AS0@(+4Q4tVSn=r04r}8Ck6oQthbn4bEgK` z*JqZCrI6GJeHQ`v0La~DEFS(?F_w3Mv{L;d!Qft;GhP@gY_IqB7rs`krkGuHY};v+ zUdrmY9srQSF=(dLu0oB^q?3CLN|D`*s-cKc{O4&%nNqCdpgigOXMcItWC!>1*7@2? zp!ym7gMUA$=S(}Gkz#1bl&ri-t%NDD>E%<76dRaT~> zdq@qHfyVN#bkDG6@Q&Z9u(LC~ah7bVUg$^5rW(L8reiP}fX&{oqev6X1qsp{fRx^^ z6Hv!YXtV;@R7qE-)Rr2`wh^iS1-3_3L|omkrh$c#k;pcNO?@bzvyz;Tr0Rb~G$1_y gP17_@^N;uq&8L*qO3J-M00000NkvXXt^-0~g6rnaivR!s diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_4to3_0_1/00003.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_4to3_0_1/00003.png index e09d96c504ac3628513a64e1a1f35b06790e1477..dd04309d22f96f70b64caef01938076722a7cbab 100644 GIT binary patch delta 443 zcmV;s0Yv`S1JwhNB!8SqL_t(|obA|Al7k=&fMIrLZ^HeL#9j8GoemR7j2Oh~|2PPiQJj?DwTW3=DerGgV4`W9Ad$n=QIj3It>hiYEjN$x+ zw`k}Npqq&~XDtf;k}mBh=ikG{uK*EHu^PnKx`j!}*>0f4e}CH&?Gbxvi{_wND?oJD znfqfc)WLOzTU6VX9I>XH0cpaank#85==P&M9Xsvx3Z8&Zzw52wwWqh0J;`P7=9~ME zzvbZ`9`qC2oV_P>4?68Q)iQeE5H{X?#A)9?&gd1qLiWSiUn(~jG65ky0RZ4F_%-yP z`ZMBSBhD5=o_}~l!>=5}7qP2ea!$Ps6+9P^qK-(|&o{RAvAx;CbJ_Ro-9&B+wQ5@9 zp86+SxdJpsIt%SZf@e*%jqIu)Yu0V(uvLLrri delta 445 zcmV;u0Yd)O1J?tPB!8YsL_t(|obA~`a>F1DKvCN1O}PJ&xJwu5WEcryVT5tx|CWTv zSO^@GlmGw#fR9m1DW&*7>hzBqkGNKU47$&v;eD?NTHnTs_@i_lbIz$Xyt-ZYS#di* z;SoEUH_)uaoU@e$e@m0~k@M@};#Yu3s8|i+-kOccsM%(s#ea8oi*<=n)}ooTY6Xbl zI&1%2ggUv-bc=37#Sv@O1cXXqe zfBcb8k8sjgY`FfO(0tHYk5e5)_vyDBjv-Ym$+}!;RPYLU$yoiS^5H@zAY>!}0Q?F5 z89J$cjhGDLjDHYv#Se7)C&%f7*j+zzE-LvjnctN^X7O+F-> zr<)xYKa&sAyQ_}=Z~dNN-t5LKJZb_`^M3cH;As<(ZZkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_taproot_1to2_sighash_default_0_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_taproot_1to2_sighash_default_0_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_taproot_1to2_sighash_default_1_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_taproot_1to2_sighash_default_1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_taproot_1to2_v1_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_taproot_1to2_v1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_tr_script_pk_sighash_all_0_0/00001.png b/tests/snapshots/nanosp/test_sign_psbt_tr_script_pk_sighash_all_0_0/00001.png index 7fced877156fe169e24050b375b4a0fd4c8d17dc..debbaafc6933e147f678febce60efaef3be1b076 100644 GIT binary patch delta 702 zcmV;v0zv)N1=aD13?t`U!{kww=+B*Bb>nZ2Yl(O%8x;PV4 z3cXA7Q@dGa(R7xR7f~Fh=Gt(Z0ofSj?Q){0@Onf;^s&=*s(($%EZWU-@*>n>i-(tR zo&lMQ+*f1D{gGATYV(zz#mhtI4wyU^Uz%zeL1V%v1ks?G1=cKQTgpI6&Un4~J->oz zIL;D}KlGH1J+LJl(F(nCmP$=N#Q^{S0036u%d4WGg<`WO%?^aF!^7$MnJn5`?mOLW z2ApKW$D)I7?|%zv{!`B*)}vHjHAhuB`e;-o-6mVE|5F-(qNJrKUMf{`prJO)Mag;t zvHJl_1cb3phHuD3Xz0Eu!NhCVMWM%z*t&EG^mzxke}pMJFrp!GM^H@M3?sBu(3n9l z+d!pxI|PcEV-ZDpnfuoKqBkb}w0aiV=j<=t2IeX=V1FY!FcChF>;q72YV<(|DvgXj z2&JWYJ9mlY;7~U@n696S&_9hZV{TGk35)6=O%YE!@t=16vg!%1nI8!ii;Mnq>-wk? zt>YWxvmRq@_p*|UX>2y~_W^kw_}@F3*K;_E5lz2<3rGg k^SOT?V2N4)002NBKP$ZK_XWKD3jhEB07*qoM6N<$f_v6YN&o-= delta 701 zcmV;u0z&=P1=R(RB!8SqL_t(|ob8-jnu8z=g`Ix06ZgL)_c9O8FewQkV#39q|H)D$ z;TGXwyKMjf00000tj=*9$8n7IVkKUVWu>O?+y_hd`gaE#v~~7<*Hg}qDP`aHba5u8 z6#6aAPwi%zMblYMev9HTHP?pQ49LbHZ1dR!w5JZD!7Fe^KZ7BmOIpg)@_gn?h zaGWI`f9NS2tFR>;*+(=reYIZHVE_OC003~4FRy}vHj2%jG&>Nw4-cp3GFh~>+&bND z2ApKW$D)I7?|&O<{!z~(mZKD2HAhuBS~aSYZj)`-|0xYXQPR>AFWpsgprJI&Mag;t zvF8Cx1cb3ph9Ag8Xz0Eu!Nlv-MWM%u*t&EG^mzxkFT#`)7}1b;A}A(Wye-{m%%I=f zK*iw>fnw%ZL{T2*z9qlt7n3fno<+8t{iWN$TxAAqu*KqOC!vfo78v0qB=-Z#J8RJN4tJm^@Nvf*_|1s*{wFJM0u58 zyKUkcgiO24sTW97u1c7`HPUNg7i&3#UrjXT=YzT-^vxM9Ltf5pxJ7Rr9%tI-^@P%_ z=c|dK$bUQd_itBJQygYMdI(pgN9FcQSPY4sVXNL|Sv7_@{SugnIIsmKf&@zd z002|)n0@av5!-r|4jB1fkSHsr6jATAD6-tj9S!x#=v$|ox}&>>8pL2ND75CHhB{kl z8X1C0|IOf7zKez$%6K(Y7r#OapFu;N=pk$rQ#MOtq~!kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_0_0/00001.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_0_0/00001.png index 2b51f30cfe212df5691953efe741325df2f02f56..61f34db33cfd1a4ec7ac68277a6a3bb82f0406cd 100644 GIT binary patch delta 470 zcmV;{0V)3I1MmZoB!9O_L_t(|obB6Pj)Wi(Mp1g=PTc>J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_0_1/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_0_2/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_0_2/00000.png index b0e1548fa41115c7d06c960e2af409d9c09f2a1c..02aa2d99e3c3a17d379a32839437cafc86717128 100644 GIT binary patch delta 401 zcmV;C0dD@P1FHj&B!6;AL_t(|obB3Ma>F1DKvAdDov{BUv6p@@<7mXggBv3$-1E_) zuBnN5#K=Al00000008XbW!-@La?WQtrDWKW{|MOuGW1f!Ziv?bXY^&bn+HSqv2MUk zD$wEL9#zg+u0P{nLx?&9V5T?BBM$!~?hH_|ju`qP-d)haZGWf}-?0$`0000U=Y7MN zh1rS^HRF{dC=p%*try<#ZU&D4Z zjh{G9{Rf|N&hn$V>wwZY6~w7ro9D!wioQGJB}kn)b#k-pfx8({lV4ev!)NMb0001B zDYz&B_pdtvhg& z3Us)*N0oDy>(BVl5TecinCYG75l{ak?hH_|ju`qP-c``SWq+s>-?0$`0000U=Y7MN zh1rG=b?M_=cU7e}4SVt^`PE|Ng5@R=p%*t)sXDK%dj6! z<2#O1|G}r6v;1oA2B36K1#v3Z<~cE^qVLXl2~tN+9o#H?;BE%gy;Aw`Z|1JZdZqcZDW4QS2G5{sSDW$Ve>dlvan`~$=XE|7%)qR3@TJ<8U u>dBtI>npF;cUgkmVgLXD0002MLVrv5Mhv_a3RD0900{s|MNUMnLSTYXDBg)^P*#QiVHz4RfiV-fI(U~X^u9`0lk zM1ub(_qviKNs=T4J0r&kwlXijm)T(f4Sl=ig0 z)=Ta1>F!a7eFt_llv1Qb;CE~>C}rIV839sv>k~?zj_*8ny?;^)n`lyYyhExO4G_kv zT?iZjBx11d+dT9Mm0DC`sb}~SwFX=Pi)!h(W=Y?y`qUEMVt*nI-GYnsDORB90q${(B7|}QI*bT%$LCxN>XS=OH0)`sFGZfR`Xzf> zmQK!iY-3ct!m8BBUf@1;dn3{aP%37xm7C*ld#X=3E-|nMh9b(f#Odz=OX$5aNEIO8 zA)*OXLtlqBupHMaFQ3nkfV;;vg*l>Y6Pa4~4-T>=pMMIp0VH4gBFw^?fn}QwnGKNn zVW|qR=i)xcHJSL)JUDLAl-+75FSX4_lJL<#NU{3>WQcq>KxY3W{4{l7en@V_RA(C; zV3Oo)gHU$UyHj4;5;XR!*e_0^+OJ}2yl@Z;8XS&`zgL8cCg`37v;kNtv0e9%6a{hV zh%|L_aev2A5+O+?N#9iL9OKcGz}|PjrVAovl_|)kJA%UG)IK5xmMAR<>;i1Rjs`sR zoH-lK)ljqSXa1MqD&`1vpW~F`TgAl_PnlZjnf!N z|Gmekv_F;tn_8|0`3KN*6k3aW5yHRtBKFE;1Ain*k|Z2U`$)5gt2^KUHoOAMM2e`tbr1G`QS~{2h<&$dJay#{rlYa%pGPNC z5N9H5JScsXAKIM^T%UkXo3f(?H)bTu;bh#tR# zUYs^L-dU;70!-k-2U+k~C;$Ke07*qoM6N<$ Eg2w}<)c^nh delta 875 zcmV-x1C;!Q2Z9HXB!5XsL_t(|ob8-ZuH_&IhMURk#QiVHz05=B8V3P?5ZaS7d=EEG zi$D>ra?HK1q9}@@D2k%^CVKC^cl?neALWm3ZobohkeWyFD?{luxtkhOoHf?0SZi%O zov-y)C;SfAsKdSkI~rPRQXudz zq9_U%rUGY(Ie$|X6HyrET&7OZfKm?#_hT(WC>Nl@3@1-??n@DKaLJB_-EGaS$Wyj{ z$?le=oipy+>eXCfRV=a>xK3T(i8KNf!|b(kbNxG>>Jv_g53GQriE=IR^zQ*C^sG#( z3XtC+vdO9ieH3G01%9idbiO|V?u@(BZN82*F|N1z!GA$!(y2f@K+>gugjrZIuXlh|}s;1W$)t)}u(%X}mVzvc&3?0x_;ME-U_MgK|oY3hObp|}x4 zU48HXn;=&oq;eYGllIb*U~q2YygBje+{9Mcun|id9DyJIC=ZpIV0aMF4q!`(<9dFi zR1i&Dq<^iFi`$M84@oFV_)I5CB@>b}`m5RS)di8Z$`s_QJA#GDt$cUo$HhmYvN`<0;0-(dH9N*CYih-ynH%Z`7E>hb?fub1YiU#6_o}PU|kukZq?GjSA@UzxE zq@LKm!z@OcfawFuBdRW8(qr9|gdMNIvMELMf9oFXxv2hLfrx##tv}szz;qRkJv_RZ zf@F}g#*3wo_QSaIVmA2Le*+ru9|5*~aDD*vZlyPLN8jY06a*jf)ljQv?h(EI4tjC5 z$@PxOA|fo!%%F*H=B>FAr;2eeQyowgMNt$l@dxIlz|MU8>zn`p002ovPDHLkV1i&} BtkM7g diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_0_2/00003.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_0_2/00003.png index 0da504c40e39d62c7a04781782b22bbef2f85b48..062405d8cbdf2b70c5cc134a2368c2c49c851ede 100644 GIT binary patch delta 496 zcmVEos?fnBzHId{MwcfAyBYr4MKGPuU8`QiFw zulaO@i++5o8?On?jjp$y_D1xHO?dFnN9^{xxj|I0a#;_fzf@k%r2||d0RZ4C`h0Qf zsBZSZNAIMw7k|~^<1gHM?H#aks(RvM_?BEp9YySBzx&5SxHpFet>~F&X=p0`6_*}I zr`EAVT_UbFKT}V9i#F?T7S=~8v#p#HJ_E*j$3*qjy&Lwz{r7fh+^JKhPLo_*+5tK* zBDsfje^^@i&u*RpX}%BYNAwhVR`!$L1MYo+I+b;1r)kz`eUEWvZ*Doh4$>R386@KxWGY@>4Q+D7XSbN m0000000000000002=fQyyW01*J%0000RAdMV*(~N%y~`?qxnYc_E?{7232p=hLF% z6|_%0CfwZwFxa`yX^!)LU zJni8kKe5BvXF~I$>s_aM5N%_(ocd5iCiSK>yaF#FkBsb>%F7AafDlgr006E+*B6IM zb))|ty-H`#D}THDJ1<`U@>YbfyG)cul1M2>OGe-Qb_n+()R;wQo@XMz^NU)WC9F8b9Hg$-hYElT7Zh+RsU&8#_ zpLUs6{}yh}fHJ-ZvWrfUXQ^NG9dPdgq?A(Gp)*?BIA~Ay=9Lr6iM$z?{_VfgD-K*B z$VYy7R`NcS>d5^+f-=;`wpy diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_1_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_1_0/00000.png index 311e4672e3bbe08e11e17c17ac61df44067da8c2..4597e471d1700326cdfcad462519cef8e9c0cab6 100644 GIT binary patch delta 393 zcmV;40e1eY1FHj&EPvWjZo?o9fMGW6CcgiXe3v~SRTdB;vLv?0|2^li9@8&ml9ZooxNpwq=YD^<1g z&-`r)S;TDLJR-^0DpK~^aZ0Ds}&z=((OVw zwMlI{w&YRvr{%~6+0$Z}1?rR1!|lWJ`$Qz@@EXSGmO}sP$Tr}|u^mJ6JB~}=5Ryhclmonmw0x9+o2rcLwzACF^wfEbR;c006wot{aj*(e;vR zp*gBGS+9BZfq&a`LH%;cF4JqddGcrYAkb;8{)k7PZnSVa%_7V*0000BFL%1!|Mh-R<4-^K#BkhgUa7mlWDZL%IRKhVAH@UvXS|2cJYl ze>Hadv3;jX;OB+D{z4y3xYzFpDtXxKykC+%}I4chTYBH#QPtqciA6JjNwaEtaj#o{?%Hb zpjenpN&o-=0001dC)agd*X6%u%zqufyA4Ril^^5NF8+2Kpd!XY+zmPBdpze%=J-c; zv3Um&hmzeuTq6z=A!Ux}X!0x{d7dM70CARc?T<;QJ+4LcNq_dA0cpXZnk!Pv>3h$f zodGCsUZ;XPr}N34b!yBxGykNNem3g1bAotIYR9RzqR&5s0RR9106-tjdevxfih~7h z#3_o4^~}+#X!1tkRokjogjP>!7+?C6HrOun+v$-ufE57Zi@IO^w#_r^)BxZ zqkY;g($#nOOJZ;WACiS$O2f&B!BU=Zuh>o?BQrAjrN@i`MYiSq(y8J(w5HHx0GvX^ z{!Evy+QoJgX~z5BUeF~q|7zWyT0R%_Jk)NV!9Tt#Mm8QkHpmxDM>TpHTW zH5Qb;1AqM5Jt~O&flE=o#%wp#&@|I%)V5I>7kjSUfaaX-xqCJMP0tSW;7a70Da#|u z6Q^FW24f4ZLwfV*w-ZQmWDh>l%yrH|;}r}`{Feh!oZ10)57Kj%iu*%*kgVl;b=z-l z?}OMZ)cXZ7D1CBH?}LFpT9@?gjiPbHA2bZsra9CD=%@pd`?roj0$sm4mf=+e00000 m000000000000000AHYAp*j2v4I}w%u0000`S1=IzQB!8PpL_t(|ob8)Qj>I4gMd?=GB=(16<5_n7iRPj;sAR4lyR) zvWv|-KsZ$F2H_gBQ3%OnOh=1%b<6!cVh0Fk1=oI`gwo?)M1SvO{~3@L9I8h_syTh{ z*|ReMdFEv*xN^E499gGe%ro;(O6g~#Zk!X$bJ9Cby%qiZLzoak2qA>DQN6E%0;k!S z@meBsw9LpD?+PuZv*OCOsubbfr#!%y{)hqCWpN`T()vIF5WXlcu3~_$nwdAF>Wgt> zyx!b}Yj#bl^?zVJLE)b{%gD?p=57^v1IY1SG`q|c6tpBb1u(utT4aub`6=j%KVC9% zQKF?!4wk>SCc2~;r}tnafzEZVr$TG_%yP8$`1m0<9-)a9&}%y5Cdm{uaT(@Z)N$ly zV@grUNf&VyVwib!Py7tiLMrZE@tL)bCTsEOIvpV2?SFca_dD)H&k2Ct`y%gm<9*jI z($zfR8)EPfJ|PRemx_}agQeWzUbCDaTDk@5$A}Fbim=)GF{t8JyrR%Z0D=Ec$Z^DOkbX5G26%<^$bg##}N{li=x-sbhz z6y5=z1b=V;Y5BTqixYjcF6rZq0(it9G(7G|sk>>r2Q?(!)Ke!g;}R#B!6#7L_t(|obB3Mj)O1^Kv6pCPO|?cc`x&UR9Vggg#xyldp<@P zL?Cq_5Ql98000000Kh6<-VHcUL_XzGiepQ@k+K7H=(UX9kgo$i(bwT_ZcO3Ny8$Pe zK&Oj)RwAOupYgvbWW596rgxcVy!^MkcYuj?#?bHby#;N&hJOa}8xt`A007{2(I!^v&j0`b delta 399 zcmV;A0dW4P1E~X$B!6&8L_t(|obB3Mj)O1^Kv6oHon-$@@?Pcxsj{306B@8x?)j)v z1T=LZAr9LH000000Dz}>c~{^(5qXzODULPyM9K!xq1Q4tL%s%hM_-4#xiN(w?+Tn` z0-Y}IS&4}5f5u-^$a)9BP46<#c=>O6?*J3)jG^D&+nHG6py_KrdlAcsewT1phgz7tN=P tw97@yD%PDHLkV1fj4w#oni diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_2_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_2_0/00002.png index dd90178a3abae7252f095f924cd857191d1dfad7..ef5789d72f0ab1a0bf58ff5892201616d3a9226d 100644 GIT binary patch delta 728 zcmV;}0w?|N1@HxsB!9O_L_t(|ob8)ia^xTkMVZv>#QR^8_mU5%D54jVEgl`;^VM<7 zLP#J$O-ca(00000;GLZ3d7h{LD?|R{_*!j1sjmDpJ`M4IwE-$(JjB^>9LM$iI1VD? zf3k|jGk`dh%m(5b@gY%CWkg4lclnd~Y%v3fvz%l9o`%-rT7N`mvVILH0~Xbzq4b=- zcI{aifZFpm6=6ra@PR;{hy}QAu*oZ8olg8f z9`aroU3j90JAW{Y<`mI`U9n=iN$aQQ+w@nuJ-XoyjTzO@aXG3&eiDc>!9tBmpXRUdMvnSP)YzoO?RtrDSB?uISG^FMq3G}OF8+o z${R->O~2M+@tt>w0XJl{(=|7epUFw@xI?=3TefQB&R;l;YV#=6GK}%W(5bcV?3Xb$ zjd`>FZhz>LBZ%ipsI!R?Cm~P1T6{P3x*wRBSowuRr)N{lxTa&DQ(or6%zLC#eCBQ}NP~u!qRZ@JhWc-LU zh`naOIMSF1DMQNrx@&1?Oz4XHwh6=sF;*t2CuM}e; zBoH9elmGw#0001ZCg*vc=jnf>)c-hMs})GulwV`hCVp2dAj0~CoejrvT;<1ckUIX7 zRV%=Vd6kVtQTKGftH{d&ZxX($B)S^_ak}lhSf3jp+RsVE_OC005xTl&y?yS7~}e zE3HC^s9Tcj91B}voCB29LZIWr)3Hqg#glM0ZYhp*n?1tR1A&yV2{_Z)uiouzwlJD69p|YDqPd)KAaT@K?+pby!1UMmBU@jLMKt0Yv*vq1_kblyw>pO!;*yzA2apbwX37IZ&-$|C$TPU=IwJy0-3zl{ zPB~7MwED53aA9DTh*If}9P;j~eDGP5_d_8;;_U!fe}5)?px!WId@G`<;e!bnMurcD z(q>+%_O1Lziyr2V){~I&XscvR%))_ql<3nb!~soBo7uPfLi#XH!sNJ7W&-k3PX5gG zl_QTNUurS=&O1bbjym;;n$@sAkdv;})-aVfbd|=PKXKS9%_C5XFiMFc)6`Julrk^% zd9(g*=zpCfi04YEvx)GNkTYH_z8iYo4-Aa0^@T&HW$&wT&Bd}U&+W%8F6YMjprmPB z`_;H=c9^>+AOz(_Sg*!*k1TQQ(rpUVuR5FSd=#Ed2MF77O1lq#6Bk>ApeM6_7qlDB zu}`9Zz^)$v0H(9@UzDaXXx|B%*>GdN*EUp7?NE{I8~JSt0WL~|661OjlkAHr;v>=^ z_L>3X2+#UO@e~Ju20Q^>k4s62{u|DKN2DUK4Fv!I0002sAAc++gZM&ZE06#H002ov JPDHLkV1nYuVa)&l diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_3_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_0_3_0/00000.png index e1fa952d66f880e523c9ad565a12d49c77bdd726..5f0e1a383e40c7fba09ba94c6254684aa7070d6b 100644 GIT binary patch delta 402 zcmV;D0d4-S1FQp(B!6>BL_t(|obB3Mj)O1^KvAZeon-$@@?QGED6*Uo6kfK6dp@cZ zk>ci6V!A8<000000Cv3*UpII6U&!05b@WF9e>C6O23O2Hp8~>Xxx|n>Mb3xj`UJWEqF)t$7c!J%2^JQ$>y$cs#bgT wwr-p*i7U>!aiO;?L1EDW000000N_DiJJUmWU3#Ua01E&B07*qoM6N<$g2oEDkpKVy delta 404 zcmV;F0c-xO1Fi#*B!6{DL_t(|obB6Na)U4oKvA0MPQ3pmX)pPprcp?^Vq$3_eQ006jM^bMmZ zvlreJ(&a*jYD$}qk=#muv>de{JuSLbptdO8J>G49UMVH$@apF1l1BT}kq+S3F^;bB z6UV7nh)G2BM+?^hYj7rsQ?<6pg*lV`aK=lJIdkgdZaac-GoYpaWbF>0sgnT!0N^F@ zw<6A{8zR11v47*(zG>^KLCMIA+YD&8OM08Ww$1SDj@I3)+IKXs`NV<0TSXWjoVu!g z-)`;NYbqotMchiy9+v=eJdiohJfd-5`m3jOz&g@PDYfAp(I1~BXsc#9C?=b`#{XQk ymF4gF=Q0Oz){P52WeEz44gdfE0000V^aec+LwG0zj}7Yp0000J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_1_0_1/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_1_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_1_0_2/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_1_0_2/00000.png index b0e1548fa41115c7d06c960e2af409d9c09f2a1c..02aa2d99e3c3a17d379a32839437cafc86717128 100644 GIT binary patch delta 401 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 JPDHLkV1nYuVa)&l diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_1_2_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_1_2_0/00000.png index 2ed1dca4462885177fde18bdc869cd18cac94b65..8c48ca209d6aab766f08131aaeffc6d8a2e6c25e 100644 GIT binary patch delta 398 zcmV;90dfAR1E>R#B!6#7L_t(|obB3Mj)O1^Kv6pCPO|?cc`x&UR9Vggg#xyldp<@P zL?Cq_5Ql98000000Kh6<-VHcUL_XzGiepQ@k+K7H=(UX9kgo$i(bwT_ZcO3Ny8$Pe zK&Oj)RwAOupYgvbWW596rgxcVy!^MkcYuj?#?bHby#;N&hJOa}8xt`A007{2(I!^v&j0`b delta 399 zcmV;A0dW4P1E~X$B!6&8L_t(|obB3Mj)O1^Kv6oHon-$@@?Pcxsj{306B@8x?)j)v z1T=LZAr9LH000000Dz}>c~{^(5qXzODULPyM9K!xq1Q4tL%s%hM_-4#xiN(w?+Tn` z0-Y}IS&4}5f5u-^$a)9BP46<#c=>O6?*J3)jG^D&+nHG6py_KrdlAcsewT1phgz7tN=P tw97@yD%PDHLkV1fj4w#oni diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_2_0_0/00001.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_2_0_0/00001.png index 2b51f30cfe212df5691953efe741325df2f02f56..61f34db33cfd1a4ec7ac68277a6a3bb82f0406cd 100644 GIT binary patch delta 470 zcmV;{0V)3I1MmZoB!9O_L_t(|obB6Pj)Wi(Mp1g=PTc>J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_2_0_1/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_2_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_2_0_2/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_2_0_2/00000.png index b0e1548fa41115c7d06c960e2af409d9c09f2a1c..02aa2d99e3c3a17d379a32839437cafc86717128 100644 GIT binary patch delta 401 zcmV;C0dD@P1FHj&B!6;AL_t(|obB3Ma>F1DKvAdDov{BUv6p@@<7mXggBv3$-1E_) zuBnN5#K=Al00000008XbW!-@La?WQtrDWKW{|MOuGW1f!Ziv?bXY^&bn+HSqv2MUk zD$wEL9#zg+u0P{nLx?&9V5T?BBM$!~?hH_|ju`qP-d)haZGWf}-?0$`0000U=Y7MN zh1rS^HRF{dC=p%*try<#ZU&D4Z zjh{G9{Rf|N&hn$V>wwZY6~w7ro9D!wioQGJB}kn)b#k-pfx8({lV4ev!)NMb0001B zDYz&B_pdtvhg& z3Us)*N0oDy>(BVl5TecinCYG75l{ak?hH_|ju`qP-c``SWq+s>-?0$`0000U=Y7MN zh1rG=b?M_=cU7e}4SVt^`PE|Ng5@R=p%*t)sXDK%dj6! z<2#O1|G}r6v;1oA2B36K1#v3Z<~cE^qVLXl2~tN+9o#H?;BE%gy;Aw`Z|1JZdZqcZDW4QS2G5{sSDW$Ve>dlvan`~$=XE|7%)qR3@TJ<8U u>dBtI>npF;cUgkmVgLXD0002MLVrv5Mhv_a3RD0900{s|MNUMnLSTYXDBg)^P*#QiVHz4RfiV-fI(U~X^u9`0lk zM1ub(_qviKNs=T4J0r&kwlXijm)T(f4Sl=ig0 z)=Ta1>F!a7eFt_llv1Qb;CE~>C}rIV839sv>k~?zj_*8ny?;^)n`lyYyhExO4G_kv zT?iZjBx11d+dT9Mm0DC`sb}~SwFX=Pi)!h(W=Y?y`qUEMVt*nI-GYnsDORB90q${(B7|}QI*bT%$LCxN>XS=OH0)`sFGZfR`Xzf> zmQK!iY-3ct!m8BBUf@1;dn3{aP%37xm7C*ld#X=3E-|nMh9b(f#Odz=OX$5aNEIO8 zA)*OXLtlqBupHMaFQ3nkfV;;vg*l>Y6Pa4~4-T>=pMMIp0VH4gBFw^?fn}QwnGKNn zVW|qR=i)xcHJSL)JUDLAl-+75FSX4_lJL<#NU{3>WQcq>KxY3W{4{l7en@V_RA(C; zV3Oo)gHU$UyHj4;5;XR!*e_0^+OJ}2yl@Z;8XS&`zgL8cCg`37v;kNtv0e9%6a{hV zh%|L_aev2A5+O+?N#9iL9OKcGz}|PjrVAovl_|)kJA%UG)IK5xmMAR<>;i1Rjs`sR zoH-lK)ljqSXa1MqD&`1vpW~F`TgAl_PnlZjnf!N z|Gmekv_F;tn_8|0`3KN*6k3aW5yHRtBKFE;1Ain*k|Z2U`$)5gt2^KUHoOAMM2e`tbr1G`QS~{2h<&$dJay#{rlYa%pGPNC z5N9H5JScsXAKIM^T%UkXo3f(?H)bTu;bh#tR# zUYs^L-dU;70!-k-2U+k~C;$Ke07*qoM6N<$ Eg2w}<)c^nh delta 875 zcmV-x1C;!Q2Z9HXB!5XsL_t(|ob8-ZuH_&IhMURk#QiVHz05=B8V3P?5ZaS7d=EEG zi$D>ra?HK1q9}@@D2k%^CVKC^cl?neALWm3ZobohkeWyFD?{luxtkhOoHf?0SZi%O zov-y)C;SfAsKdSkI~rPRQXudz zq9_U%rUGY(Ie$|X6HyrET&7OZfKm?#_hT(WC>Nl@3@1-??n@DKaLJB_-EGaS$Wyj{ z$?le=oipy+>eXCfRV=a>xK3T(i8KNf!|b(kbNxG>>Jv_g53GQriE=IR^zQ*C^sG#( z3XtC+vdO9ieH3G01%9idbiO|V?u@(BZN82*F|N1z!GA$!(y2f@K+>gugjrZIuXlh|}s;1W$)t)}u(%X}mVzvc&3?0x_;ME-U_MgK|oY3hObp|}x4 zU48HXn;=&oq;eYGllIb*U~q2YygBje+{9Mcun|id9DyJIC=ZpIV0aMF4q!`(<9dFi zR1i&Dq<^iFi`$M84@oFV_)I5CB@>b}`m5RS)di8Z$`s_QJA#GDt$cUo$HhmYvN`<0;0-(dH9N*CYih-ynH%Z`7E>hb?fub1YiU#6_o}PU|kukZq?GjSA@UzxE zq@LKm!z@OcfawFuBdRW8(qr9|gdMNIvMELMf9oFXxv2hLfrx##tv}szz;qRkJv_RZ zf@F}g#*3wo_QSaIVmA2Le*+ru9|5*~aDD*vZlyPLN8jY06a*jf)ljQv?h(EI4tjC5 z$@PxOA|fo!%%F*H=B>FAr;2eeQyowgMNt$l@dxIlz|MU8>zn`p002ovPDHLkV1i&} BtkM7g diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_2_0_2/00003.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_2_0_2/00003.png index 0da504c40e39d62c7a04781782b22bbef2f85b48..062405d8cbdf2b70c5cc134a2368c2c49c851ede 100644 GIT binary patch delta 496 zcmVEos?fnBzHId{MwcfAyBYr4MKGPuU8`QiFw zulaO@i++5o8?On?jjp$y_D1xHO?dFnN9^{xxj|I0a#;_fzf@k%r2||d0RZ4C`h0Qf zsBZSZNAIMw7k|~^<1gHM?H#aks(RvM_?BEp9YySBzx&5SxHpFet>~F&X=p0`6_*}I zr`EAVT_UbFKT}V9i#F?T7S=~8v#p#HJ_E*j$3*qjy&Lwz{r7fh+^JKhPLo_*+5tK* zBDsfje^^@i&u*RpX}%BYNAwhVR`!$L1MYo+I+b;1r)kz`eUEWvZ*Doh4$>R386@KxWGY@>4Q+D7XSbN m0000000000000002=fQyyW01*J%0000RAdMV*(~N%y~`?qxnYc_E?{7232p=hLF% z6|_%0CfwZwFxa`yX^!)LU zJni8kKe5BvXF~I$>s_aM5N%_(ocd5iCiSK>yaF#FkBsb>%F7AafDlgr006E+*B6IM zb))|ty-H`#D}THDJ1<`U@>YbfyG)cul1M2>OGe-Qb_n+()R;wQo@XMz^NU)WC9F8b9Hg$-hYElT7Zh+RsU&8#_ zpLUs6{}yh}fHJ-ZvWrfUXQ^NG9dPdgq?A(Gp)*?BIA~Ay=9Lr6iM$z?{_VfgD-K*B z$VYy7R`NcS>d5^+f-=;`wpy diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_2_1_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_external_inputs_2_1_0/00000.png index 311e4672e3bbe08e11e17c17ac61df44067da8c2..4597e471d1700326cdfcad462519cef8e9c0cab6 100644 GIT binary patch delta 393 zcmV;40e1eY1FHj&EPvWjZo?o9fMGW6CcgiXe3v~SRTdB;vLv?0|2^li9@8&ml9ZooxNpwq=YD^<1g z&-`r)S;TDLJR-^0DpK~^aZ0Ds}&z=((OVw zwMlI{w&YRvr{%~6+0$Z}1?rR1!|lWJ`$Qz@@EXSGmO}sP$Tr}|u^mJ6JB~}=5Ryhclmonmw0x9+o2rcLwzACF^wfEbR;c006wot{aj*(e;vR zp*gBGS+9BZfq&a`LH%;cF4JqddGcrYAkb;8{)k7PZnSVa%_7V*0000BFL%1!|Mh-R<4-^K#BkhgUa7mlWDZL%IRKhVAH@UvXS|2cJYl ze>Hadv3;jX;OB+D{z4y3xYzFpDtXxKykC+%}I4chTYBH#QPtqciA6JjNwaEtaj#o{?%Hb zpjenpN&o-=0001dC)agd*X6%u%zqufyA4Ril^^5NF8+2Kpd!XY+zmPBdpze%=J-c; zv3Um&hmzeuTq6z=A!Ux}X!0x{d7dM70CARc?T<;QJ+4LcNq_dA0cpXZnk!Pv>3h$f zodGCsUZ;XPr}N34b!yBxGykNNem3g1bAotIYR9RzqR&5s0RR9106-tjdevxfih~7h z#3_o4^~}+#X!1tkRokjogjP>!7+?C6HrOun+v$-ufE57Zi@IO^w#_r^)BxZ zqkY;g($#nOOJZ;WACiS$O2f&B!BU=Zuh>o?BQrAjrN@i`MYiSq(y8J(w5HHx0GvX^ z{!Evy+QoJgX~z5BUeF~q|7zWyT0R%_Jk)NV!9Tt#Mm8QkHpmxDM>TpHTW zH5Qb;1AqM5Jt~O&flE=o#%wp#&@|I%)V5I>7kjSUfaaX-xqCJMP0tSW;7a70Da#|u z6Q^FW24f4ZLwfV*w-ZQmWDh>l%yrH|;}r}`{Feh!oZ10)57Kj%iu*%*kgVl;b=z-l z?}OMZ)cXZ7D1CBH?}LFpT9@?gjiPbHA2bZsra9CD=%@pd`?roj0$sm4mf=+e00000 m000000000000000AHYAp*j2v4I}w%u0000`S1=IzQB!8PpL_t(|ob8)Qj>I4gMd?=GB=(16<5_n7iRPj;sAR4lyR) zvWv|-KsZ$F2H_gBQ3%OnOh=1%b<6!cVh0Fk1=oI`gwo?)M1SvO{~3@L9I8h_syTh{ z*|ReMdFEv*xN^E499gGe%ro;(O6g~#Zk!X$bJ9Cby%qiZLzoak2qA>DQN6E%0;k!S z@meBsw9LpD?+PuZv*OCOsubbfr#!%y{)hqCWpN`T()vIF5WXlcu3~_$nwdAF>Wgt> zyx!b}Yj#bl^?zVJLE)b{%gD?p=57^v1IY1SG`q|c6tpBb1u(utT4aub`6=j%KVC9% zQKF?!4wk>SCc2~;r}tnafzEZVr$TG_%yP8$`1m0<9-)a9&}%y5Cdm{uaT(@Z)N$ly zV@grUNf&VyVwib!Py7tiLMrZE@tL)bCTsEOIvpV2?SFca_dD)H&k2Ct`y%gm<9*jI z($zfR8)EPfJ|PRemx_}agQeWzUbCDaTDk@5$A}Fbim=)GF{t8JyrR%Z0D=Ec$Z^DOkbX5G26%<^$bg##}N{li=x-sbhz z6y5=z1b=V;Y5BTqixYjcF6rZq0(it9G(7G|sk>>r2Q?(!)Ke!g;}R#B!6#7L_t(|obB3Mj)O1^Kv6pCPO|?cc`x&UR9Vggg#xyldp<@P zL?Cq_5Ql98000000Kh6<-VHcUL_XzGiepQ@k+K7H=(UX9kgo$i(bwT_ZcO3Ny8$Pe zK&Oj)RwAOupYgvbWW596rgxcVy!^MkcYuj?#?bHby#;N&hJOa}8xt`A007{2(I!^v&j0`b delta 399 zcmV;A0dW4P1E~X$B!6&8L_t(|obB3Mj)O1^Kv6oHon-$@@?Pcxsj{306B@8x?)j)v z1T=LZAr9LH000000Dz}>c~{^(5qXzODULPyM9K!xq1Q4tL%s%hM_-4#xiN(w?+Tn` z0-Y}IS&4}5f5u-^$a)9BP46<#c=>O6?*J3)jG^D&+nHG6py_KrdlAcsewT1phgz7tN=P tw97@yD%PDHLkV1fj4w#oni diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_naked_opreturn_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_naked_opreturn_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_naked_opreturn_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_with_naked_opreturn_0_0/00002.png index 8b83bf20399ab3b347242d79a3166ba42f65dd6e..e0ee426052691c1662a178c82048b03406ee92a1 100644 GIT binary patch delta 389 zcmV;00eb$P1E2$tB!6c~L_t(|obB0dl7k=&fML3`H{t$A;x7Bc8HWi0vQ`pW-{)Tu zMHBgurUU>006bGErIcbnG^qb^exh$6ouT}inEuOe^bK^W`A~a9&iN?MIg2{>k|@DF zKm=6u1`!&yP+a7!qXt@>+m`s-q6dgz8Q=YDSEwW2%c!ULIe#E6m{fBm&4L~~_e3V( zeDZoIIL7q0vgJJ;)Y)_VNh!So+a8Yz>O9$-PJ3_k{*y2O0KhXjEknh}&R|(NJ$dlPUJGm@A z0mdMz)!vMIuYT#H6Zj-GJ^{w(RHxZnnttwX=mjeVX!V+IGlA>@E4p6$Fn2X!8NNj8 z_NG_lU=rSE{w?lI1o>4T*kLWPsIP2A2{rG&GbP~Uz)d&QT7?`B}0tNU1I3* zaVO>AAiUxA_yi)zulhpxc49`MEJz78-@Y>?;N-wfH`L_7!9kG8!Bm770000000000 h000000001(<{!=99LOmyw0!^o002ovPDHLkV1lMdvkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_opreturn_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_with_opreturn_0_0/00002.png index 85912cd4e6af442822c849a271270875e37e00ad..4c3ce0a58ed3d2c607f32b59818fe865b6c8e7b5 100644 GIT binary patch delta 805 zcmV+=1KRw_2D}E4B!2@*L_t(|ob8%hZtWlpMd?*%lKBrQbGaW;BZ?nv3?@0%ULTdp zaj-GZY*Gp#gb+dqA%BVUJkRsQe{$?s#pAoXOU?@G@m2iGsI*k!rsfn!=2|s7j^p}! z(O71*<$HOJK584(*>D`kRW1{Om(0Ylhm;v$4YxX>&95?Fa)0Qlqw+3vN*Wi^Ky8A2 zN;Ykt#2L^;92j?a4Ru1T9(9n9+^(;=h*vdA)*et2Hr1n|^pgIPy{F6i4!B!h&va`X zA%n}YLDnCT)M4)MwY)}uO;GnqYdf_@bYK&9qC$MBHIM=3*Td}Bl)uk>2ds*O5JCtk zCF2;X((GW)0e`gnc=zxs3!5XRe;`(kKO0qRlRr7f4Asohx{-gaIyXqrHHlKhhjPD~ z?P0eZy_Q<`cs7zS&vyWrMAd9E@0ROp671>J=Q{vwXNDY~B=HaNVS7Nv0 zFXSoYRk=p}o={zR!s4Z+gIdEJ`NYxe08ocg<)E(Du85@C#C%EA79rv#qLq$@G`0jG zRqvFyd|!_032Mb%0=s>~`U{ztWWPM2dIr3h9S~R()k1l1BcDQS5MMaW*jMl48q^CY jFdj}q2qAXHBf<}H00000NkvXXu0mjf*lvzn delta 818 zcmV-21I_%r2FV7HB!3V|L_t(|ob8%hlHDK-M441};{7kld&!4u9D*J+0%6}tpO2{; zu0XN`7`I&tA%qY@2q8a-^E}V<#D8+^SHZIGL=+Fi}EdIXRc64=?uU*;b&vL91^ zKJx`w6$v4P5PwoiDPMcs$fKuhw@!G@p|EaLT{K6}`(JBJ)%fFa4%&#;sM;XL&cD`} z8}#RfEIIl^*)L}7mZKNaJQ#l{&ldp6qiQpmcgyd!2(}gV`2yg2+}h0{N#7sklkNc- z8?-v+&O1T70y0*gyq+a4kiDyMjr&ciK_|VBugCv^CV$Ca^$(99Co&ew3sF+dxxX1D z;jFx9<{v62_gq;eaby7}fbrpzmTWNL|AI*Eq-b2g%4{kFD!)RLE%R zwu6TnFMohcnHq=Fz5Kh3q^y?o8$s}bR-)Lx*92b$%op_hA^<+UzG$Hb!=Dqf6u z0n|C$ko}4^Hs-5d{Kk)=vH1EZhTbV}`Mw<06V!^k1n%|?>tD#cB>UwF)idD5EI?pSR2$`c8`%r7 wK`VUWG;?2lAJ?G1fCA$rgb+dqA>>{B0l1^X1`lXDBMQx`$$^Ms=z4Rk}8Ak-Jh~~Au=d1M* zK{SNiltKt0gb+f=c0Lx(d!A=0kmHj(qnFr+=kjUL2K`tLHk4p9>PZF(>(1pcipH6N=iLUFRK5G zlnqFUgb+dq`G3J_L#1$tj1=WnbB|3EKXR>fF>jMhS2EK^4E}xnagxkESc*)q|50AP zWY_=NHpS~i4M&JU-TWc_@lYqKIZ9azig80Anj$h!*g(5vQn+<5A1V?FTF^RX&QYy5 zEPdAn9e;(7JgSBk^UZVUC00}Ah72y*vb!-UVyf*ZtbIxb)KEF1>4k`HfjAm9=+aG} zy-9&c!m90)B`6&v*Nf!2@V)qFzlfEM*+*P!pl#@+t|@J#*{Fe=U%LRhk2Kp65~@rB zA%qY@2)VG@P`ufSeX^Gqx*xT>5!Svm)u=o9q<;d6>%@^x6p;y~F)}iwO(GE*BcPXn z0y?A<8^*s$iU`~jGmbV$tz~orz~#9w;xpx?D}gn#AQFS&4pBhCRk)08KvyP2mfF}L zYGTX=3_uc4K*QOnnJqyn0%Z3YZkWvnxrl(HDK#{3_V@G7*)Op+)Mz?o9Ebp!-YJ5E mDIp5zs3SrMA%qY@p646qM@Wsu(PNze0000 delta 810 zcmV+_1J(S$2Ehi9B!37=L_t(|ob8!WcI_YtMQvASlKBrQbLmHVvs@x@L^QYU*g0myZp`FUxA#S*|7O(&q@NUd((Aps4nFAgP2Nlw z$t9?6Fx>tDIazi!ck2&6^U`B(klcpaH9>3dnn7(6X=9JLF_h{i+3vbg5tRFl`uHUO zmy``iiG&bB2!Hv(X+x!Oh>R5FQ*)0^6F>5-bTMy}Ojk0~MhyL6vyCl*%(%`{Ntejc z@4z|@2b}hNVVn6{5b_1M(*{AyzFRu%4`U;+#^w$nVFQ{OZ+~6w&=ulGZL}H^+ax)^ z)LdN~d*(VwB&3KMx>}*V>28DTy{XaLqHO@34sXCy>wm$$8#nb0Y1>d)YOa5{;$<;g z!i)Fd{V; zyLm#o4DmP?s$(G%XNfA?RM`7(#GN6Xa5lt^dbPL4Ms6m%* z`s_^#L=skQpDaP?Ah}*7&xP;epZ!IwY|K95S_5rECv{C}Bh5w)-2B=F(0!%Zj*w7g z5(puL5JJd>)rR8DR_rHx`Jnrwb~nP>m!=wZCx4$*KyjTo(upE6p)^KDhO|i}LSqE< z5>P;gbYjE!H%SqJJ2B&EgVb6^Hvn9o`yoD4Ub+%kBMTxi814`S6kLVN*amcELS(6p z4WcH-Y`_2{0R=RijhfjKlp;WO-{FSYe2|L>IGR#J1809f@0|S-YeS8uQ^tV^km;Qw oI3t*%fQ~vMgb+dqA>?_!0sekRy{YE-qW}N^07*qoM6N<$g1Oa$LI3~& diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_opreturn_0_0/00004.png b/tests/snapshots/nanosp/test_sign_psbt_with_opreturn_0_0/00004.png index 9770af436e63184368199bcc977791ee38ace56b..2f97e7fed71de7bb6585f2d180b468882bcb070b 100644 GIT binary patch delta 823 zcmV-71IYZ%2F?bMB!3l2L_t(|ob8)ImfRo=M3ubU#P>gv?~;Wlegs6R02xmw^;a`A z7D9k5m%Gh`5JCtcgxJoHhwPr`X=cZ9kRO5mS^iwcuYoRlKDd2u3%UGEw`j#A%bC1L z70?Uw+`HO)eV&-kuXKw5cLHtWwb#ls(QZkmW!<+8wDev(m127^8MA+w}lxDwn4gfCa>x1%R+!p!{~59f9hEGhXgJ*oa* zq%1&+Cqf7z#D5oY843zMw{&AFPTr0+^`CoH&u3TUz@|V|y5e>Mt`ZP_1X?ESFr^3{ z2#X@%59X@sBgWgOq=*#mY2cZhe+aE@dyL`-V&&+{`|z9&we;**8k|7~8TpQO~b=9izmHl1Kl7i`rB|q zt>|w?Yw#w@LT?fTS!?hpZFmDUbW}W;FhV{mS1pzOMS*juC3JE~xJ5AXCnJG{Exb+F z+Pc6w*MG8ptv&bUTpSlhyd($OqmksgT@pwU6G9-?FI|DNy{eZ|NWGZ`4&TRX(&%(2?Q7BT)LNl4ULD3l*>CQC`&S1c^@#Uzpe}ic;WW}FAA1C+nn52 zhA_JC5U9-MWe@^bpK20Ui_%`APLC>0(JD=FJ)*5 z0n+q!MuZST2qA=!?Yu3rd!DC=9LE8E~mYl34&RhhmCm@GfT;w8A2}@pc92rUAIKL) zoIjAOs*ezFS7|{h+|%%9a()w9+x8fR4}@w#mG|K}?P_V+x#S)5u~v$N;0X6AuTv(I zp3k5dS502p`4LnRaMc%iPtql1hHGP5tF9WBPN4l%TUw0c>@r)dQ0qsyy2?sI3=K2hWgjG+zv-Ho%a@xdea7)L1y%~VT78| z-wfB_NtlJ6BnUFsU@1Dhfg0K?9t;=(AC;??%KoIl+0_y{*(Kb1Ao3?7frTx&P1D-E zz&X}3e}Ap4`*N-y7eu@S2il{Nl` z_9}(uLw^?o0w>ZkHni_dpBOhE8WUt6nMWj1;2Z#nb?D5is-d|8X9@$+7k>ecpTCk2 zD^cn`NAWG?J9|n`DK=TXRhK&+cD0OoK3jeIkB(p|s(|Z~UCpsf z{oww4m5})qU2{x)TFtyT)c~Ht{+WRA4 zTMb7aljnSPEP&~EHGgDoDbj3cJY1w)o=HJjlG)7rfL{G|W;lljejo6lV2QKM$$e$0 z`7bWPDLMs6(_!&yj@7aZI;s66gb+dqA>_sQ1fB5zB`W9kumAu607*qoM6N<$f(MU? ACIA2c diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_opreturn_v1_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_opreturn_v1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_opreturn_v1_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_with_opreturn_v1_0_0/00002.png index 85912cd4e6af442822c849a271270875e37e00ad..4c3ce0a58ed3d2c607f32b59818fe865b6c8e7b5 100644 GIT binary patch delta 805 zcmV+=1KRw_2D}E4B!2@*L_t(|ob8%hZtWlpMd?*%lKBrQbGaW;BZ?nv3?@0%ULTdp zaj-GZY*Gp#gb+dqA%BVUJkRsQe{$?s#pAoXOU?@G@m2iGsI*k!rsfn!=2|s7j^p}! z(O71*<$HOJK584(*>D`kRW1{Om(0Ylhm;v$4YxX>&95?Fa)0Qlqw+3vN*Wi^Ky8A2 zN;Ykt#2L^;92j?a4Ru1T9(9n9+^(;=h*vdA)*et2Hr1n|^pgIPy{F6i4!B!h&va`X zA%n}YLDnCT)M4)MwY)}uO;GnqYdf_@bYK&9qC$MBHIM=3*Td}Bl)uk>2ds*O5JCtk zCF2;X((GW)0e`gnc=zxs3!5XRe;`(kKO0qRlRr7f4Asohx{-gaIyXqrHHlKhhjPD~ z?P0eZy_Q<`cs7zS&vyWrMAd9E@0ROp671>J=Q{vwXNDY~B=HaNVS7Nv0 zFXSoYRk=p}o={zR!s4Z+gIdEJ`NYxe08ocg<)E(Du85@C#C%EA79rv#qLq$@G`0jG zRqvFyd|!_032Mb%0=s>~`U{ztWWPM2dIr3h9S~R()k1l1BcDQS5MMaW*jMl48q^CY jFdj}q2qAXHBf<}H00000NkvXXu0mjf*lvzn delta 818 zcmV-21I_%r2FV7HB!3V|L_t(|ob8%hlHDK-M441};{7kld&!4u9D*J+0%6}tpO2{; zu0XN`7`I&tA%qY@2q8a-^E}V<#D8+^SHZIGL=+Fi}EdIXRc64=?uU*;b&vL91^ zKJx`w6$v4P5PwoiDPMcs$fKuhw@!G@p|EaLT{K6}`(JBJ)%fFa4%&#;sM;XL&cD`} z8}#RfEIIl^*)L}7mZKNaJQ#l{&ldp6qiQpmcgyd!2(}gV`2yg2+}h0{N#7sklkNc- z8?-v+&O1T70y0*gyq+a4kiDyMjr&ciK_|VBugCv^CV$Ca^$(99Co&ew3sF+dxxX1D z;jFx9<{v62_gq;eaby7}fbrpzmTWNL|AI*Eq-b2g%4{kFD!)RLE%R zwu6TnFMohcnHq=Fz5Kh3q^y?o8$s}bR-)Lx*92b$%op_hA^<+UzG$Hb!=Dqf6u z0n|C$ko}4^Hs-5d{Kk)=vH1EZhTbV}`Mw<06V!^k1n%|?>tD#cB>UwF)idD5EI?pSR2$`c8`%r7 wK`VUWG;?2lAJ?G1fCA$rgb+dqA>>{B0l1^X1`lXDBMQx`$$^Ms=z4Rk}8Ak-Jh~~Au=d1M* zK{SNiltKt0gb+f=c0Lx(d!A=0kmHj(qnFr+=kjUL2K`tLHk4p9>PZF(>(1pcipH6N=iLUFRK5G zlnqFUgb+dq`G3J_L#1$tj1=WnbB|3EKXR>fF>jMhS2EK^4E}xnagxkESc*)q|50AP zWY_=NHpS~i4M&JU-TWc_@lYqKIZ9azig80Anj$h!*g(5vQn+<5A1V?FTF^RX&QYy5 zEPdAn9e;(7JgSBk^UZVUC00}Ah72y*vb!-UVyf*ZtbIxb)KEF1>4k`HfjAm9=+aG} zy-9&c!m90)B`6&v*Nf!2@V)qFzlfEM*+*P!pl#@+t|@J#*{Fe=U%LRhk2Kp65~@rB zA%qY@2)VG@P`ufSeX^Gqx*xT>5!Svm)u=o9q<;d6>%@^x6p;y~F)}iwO(GE*BcPXn z0y?A<8^*s$iU`~jGmbV$tz~orz~#9w;xpx?D}gn#AQFS&4pBhCRk)08KvyP2mfF}L zYGTX=3_uc4K*QOnnJqyn0%Z3YZkWvnxrl(HDK#{3_V@G7*)Op+)Mz?o9Ebp!-YJ5E mDIp5zs3SrMA%qY@p646qM@Wsu(PNze0000 delta 810 zcmV+_1J(S$2Ehi9B!37=L_t(|ob8!WcI_YtMQvASlKBrQbLmHVvs@x@L^QYU*g0myZp`FUxA#S*|7O(&q@NUd((Aps4nFAgP2Nlw z$t9?6Fx>tDIazi!ck2&6^U`B(klcpaH9>3dnn7(6X=9JLF_h{i+3vbg5tRFl`uHUO zmy``iiG&bB2!Hv(X+x!Oh>R5FQ*)0^6F>5-bTMy}Ojk0~MhyL6vyCl*%(%`{Ntejc z@4z|@2b}hNVVn6{5b_1M(*{AyzFRu%4`U;+#^w$nVFQ{OZ+~6w&=ulGZL}H^+ax)^ z)LdN~d*(VwB&3KMx>}*V>28DTy{XaLqHO@34sXCy>wm$$8#nb0Y1>d)YOa5{;$<;g z!i)Fd{V; zyLm#o4DmP?s$(G%XNfA?RM`7(#GN6Xa5lt^dbPL4Ms6m%* z`s_^#L=skQpDaP?Ah}*7&xP;epZ!IwY|K95S_5rECv{C}Bh5w)-2B=F(0!%Zj*w7g z5(puL5JJd>)rR8DR_rHx`Jnrwb~nP>m!=wZCx4$*KyjTo(upE6p)^KDhO|i}LSqE< z5>P;gbYjE!H%SqJJ2B&EgVb6^Hvn9o`yoD4Ub+%kBMTxi814`S6kLVN*amcELS(6p z4WcH-Y`_2{0R=RijhfjKlp;WO-{FSYe2|L>IGR#J1809f@0|S-YeS8uQ^tV^km;Qw oI3t*%fQ~vMgb+dqA>?_!0sekRy{YE-qW}N^07*qoM6N<$g1Oa$LI3~& diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_opreturn_v1_0_0/00004.png b/tests/snapshots/nanosp/test_sign_psbt_with_opreturn_v1_0_0/00004.png index 9770af436e63184368199bcc977791ee38ace56b..2f97e7fed71de7bb6585f2d180b468882bcb070b 100644 GIT binary patch delta 823 zcmV-71IYZ%2F?bMB!3l2L_t(|ob8)ImfRo=M3ubU#P>gv?~;Wlegs6R02xmw^;a`A z7D9k5m%Gh`5JCtcgxJoHhwPr`X=cZ9kRO5mS^iwcuYoRlKDd2u3%UGEw`j#A%bC1L z70?Uw+`HO)eV&-kuXKw5cLHtWwb#ls(QZkmW!<+8wDev(m127^8MA+w}lxDwn4gfCa>x1%R+!p!{~59f9hEGhXgJ*oa* zq%1&+Cqf7z#D5oY843zMw{&AFPTr0+^`CoH&u3TUz@|V|y5e>Mt`ZP_1X?ESFr^3{ z2#X@%59X@sBgWgOq=*#mY2cZhe+aE@dyL`-V&&+{`|z9&we;**8k|7~8TpQO~b=9izmHl1Kl7i`rB|q zt>|w?Yw#w@LT?fTS!?hpZFmDUbW}W;FhV{mS1pzOMS*juC3JE~xJ5AXCnJG{Exb+F z+Pc6w*MG8ptv&bUTpSlhyd($OqmksgT@pwU6G9-?FI|DNy{eZ|NWGZ`4&TRX(&%(2?Q7BT)LNl4ULD3l*>CQC`&S1c^@#Uzpe}ic;WW}FAA1C+nn52 zhA_JC5U9-MWe@^bpK20Ui_%`APLC>0(JD=FJ)*5 z0n+q!MuZST2qA=!?Yu3rd!DC=9LE8E~mYl34&RhhmCm@GfT;w8A2}@pc92rUAIKL) zoIjAOs*ezFS7|{h+|%%9a()w9+x8fR4}@w#mG|K}?P_V+x#S)5u~v$N;0X6AuTv(I zp3k5dS502p`4LnRaMc%iPtql1hHGP5tF9WBPN4l%TUw0c>@r)dQ0qsyy2?sI3=K2hWgjG+zv-Ho%a@xdea7)L1y%~VT78| z-wfB_NtlJ6BnUFsU@1Dhfg0K?9t;=(AC;??%KoIl+0_y{*(Kb1Ao3?7frTx&P1D-E zz&X}3e}Ap4`*N-y7eu@S2il{Nl` z_9}(uLw^?o0w>ZkHni_dpBOhE8WUt6nMWj1;2Z#nb?D5is-d|8X9@$+7k>ecpTCk2 zD^cn`NAWG?J9|n`DK=TXRhK&+cD0OoK3jeIkB(p|s(|Z~UCpsf z{oww4m5})qU2{x)TFtyT)c~Ht{+WRA4 zTMb7aljnSPEP&~EHGgDoDbj3cJY1w)o=HJjlG)7rfL{G|W;lljejo6lV2QKM$$e$0 z`7bWPDLMs6(_!&yj@7aZI;s66gb+dqA>_sQ1fB5zB`W9kumAu607*qoM6N<$f(MU? ACIA2c diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_segwit_v16_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_with_segwit_v16_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_segwit_v16_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_with_segwit_v16_0_0/00002.png index 687e6d5cde9fae2b37cb3b9d50328181b295fed0..1a48535878132236f1f5958aea84af65af8d8307 100644 GIT binary patch delta 485 zcmVVK#9ijW87dtXqY`lWzo)KC)w$zRu}+W6Stzw6V-TMu#u& zB(FO_PPi(l2A5@SO>JsVig|<0^Crbd0C@@-9JxL}%K7=w`!(hH?y@QX0Pty7T@!Y# z_khiwt-W5s?tiPcK^43j#X^||`5Ih24#6F2rSL{=-LmP;!JK0)2o{|au-3xJft^b+ zjvUzOA7s>njjA=SLCddwsbrsL;?2R0=SJ6ITRiv+gQ~%|+`vQq0P4>8O8~t;QhAMJ z*&L?Y)#PA+jZP*9uIOIiQ?(kpx?nZ&*1>%)SWUcjuwKaVuZgfA0h5t{$ykJk29LW= zHSrn2gehn;5&!@I-ia5np}~DFSWvumu!#47$wKA&7=ju00000NkvXXu0mjfa}M$J delta 485 zcmZo?X=j)dsBT7JuS?oN4lWT`>q4WWvP{HtFNHmDk&+^fR?0{%+J zB$BU)o4$(fU4D0N$Rqi!$JhR-Fxl1daM!I6|Gd{pTLlhDgznt1=Xfn_Acq-eKL%vcbnrH7@^6wRJx_IH_=ADyDCf0{vm{6YE^q9xPZB5VL zWL=NuYc{tQXdC4emNZmucrsD1cJr~Vq00|%)BCNOA-!wP%hipaPR;s}b>-q3doMoz z_bPGA6?Q&QOA?BiwY7A0u(hU`w#IG^ImQ(6Aeo)^_FbQ+^SsYK_1W@0!|I7ZUwpYR z^*W2~+Uf)AQnRmXU-%qauk9fe*PF7iq_+Cr#HadX{}ZYWa&!^KR?sZr3;Hn*DP!T=`)ltIR9*31@oZ z*%SUwobugc+u6hr-(G&U4aq4r54fJO{_r=I-c@uk=h51uc6u{>_iT+g^144Rasdmw z4;#Brn{UO6iaD=Sgy$>fZD8?bV+XqSfb~NqvyeBBn>dd~cf0NYtAi`$RujqBg)8-W Z#D2eh_0cCCQo*3u@^tlcS?83{1ONq)-YftB diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_segwit_v16_0_0/00003.png b/tests/snapshots/nanosp/test_sign_psbt_with_segwit_v16_0_0/00003.png index 72bc053e6fffbe3224264056405dd988f1dc2ea6..ec98cabb58fc74b78d370364e4cb6e8338d7d0c3 100644 GIT binary patch delta 443 zcmV;s0Yv`S1JwhNB!8SqL_t(|obB0La>F1DKvA0MPT2pF*h@c>@en{*fP@qGo==Pc zi&r2a00000w~{j1sH@+GI*(KH9v+3}pW#vds5*`@#?WeBo?hqi_?%z! z5<8k7&>V>|MkxyVlqTts@^y3eGoT1)F&m0+YbFL^%r*mEynkD#NL7rICe0$R8BjD= zIrisD$b+j4cad#qaM*I$1A@b*8Z+T6=>4iS4coSR8F#?Z?tCeDuIY7V&EV><=BMkA zzU1i^F8Z-8uD>QUH#%uMl}7Z$CfxbuQ|$J2b)8m0%Va(DKB?TCNe7s;1OR}4VD27G zx+}$)^~>ZveSffe7o-Mqt?;B^~%m1j_nA^iD!>D^{Py%RW9WVHvB9WYc}z0qBsII1q8-m9g=x$1f) ztbC9DKd)_xR%{C|N_*rFxa{7bn7FSFAo@GC7thcC!8C9iVyNkZ4NihgAGjjC00000 l00000000000001hn?JVB+}-l=J7WL<002ovPDHLkV1j?Y)ms1n delta 445 zcmV;u0Yd)O1J?tPB!8YsL_t(|obB0La>F1DKvA0MPT2pF*h@d0@lYhN0D)8Yo=<`W z<{5AZ0002MW2BT)O7@=``Mv5>l+~_-%(JL^uN6V_*H{t1mu$xvW6-LXr^`GmUgz6A zVuShu>PU<+)>^@yqN@F5eB7P?3@943m<`3dsfnR7X4Qr+o`01owIX`eCe5T(GoYxh zaqN#p$Q#$#+(ovo!QpFF2e^+EInwjKIR?J5P)oLLyO;A4bk;jx3XTSnnJt5>y_#RH zKlaGOHJtS28?L=3s2g2vJC#9Xo_5M*9YQvfYQ;5b1uK_B#_E&G!?|>TOHBX(_y@-B z(Q0?4=rezrynm+;X0IZQXRDow;rD&2tg3oMuN~JLMV|+>+fHZd5W6?gD}(*n$%(S{ zd%#~|8QSU{#(*VX#BOvn$~lBTe=mL743Im)qJq5kfU*O+!l_sA_a^p|5#(N7OB^e% z6=CLm?BBe$C3^7kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_segwit_v16_v1_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_with_segwit_v16_v1_0_0/00002.png index 687e6d5cde9fae2b37cb3b9d50328181b295fed0..1a48535878132236f1f5958aea84af65af8d8307 100644 GIT binary patch delta 485 zcmVVK#9ijW87dtXqY`lWzo)KC)w$zRu}+W6Stzw6V-TMu#u& zB(FO_PPi(l2A5@SO>JsVig|<0^Crbd0C@@-9JxL}%K7=w`!(hH?y@QX0Pty7T@!Y# z_khiwt-W5s?tiPcK^43j#X^||`5Ih24#6F2rSL{=-LmP;!JK0)2o{|au-3xJft^b+ zjvUzOA7s>njjA=SLCddwsbrsL;?2R0=SJ6ITRiv+gQ~%|+`vQq0P4>8O8~t;QhAMJ z*&L?Y)#PA+jZP*9uIOIiQ?(kpx?nZ&*1>%)SWUcjuwKaVuZgfA0h5t{$ykJk29LW= zHSrn2gehn;5&!@I-ia5np}~DFSWvumu!#47$wKA&7=ju00000NkvXXu0mjfa}M$J delta 485 zcmZo?X=j)dsBT7JuS?oN4lWT`>q4WWvP{HtFNHmDk&+^fR?0{%+J zB$BU)o4$(fU4D0N$Rqi!$JhR-Fxl1daM!I6|Gd{pTLlhDgznt1=Xfn_Acq-eKL%vcbnrH7@^6wRJx_IH_=ADyDCf0{vm{6YE^q9xPZB5VL zWL=NuYc{tQXdC4emNZmucrsD1cJr~Vq00|%)BCNOA-!wP%hipaPR;s}b>-q3doMoz z_bPGA6?Q&QOA?BiwY7A0u(hU`w#IG^ImQ(6Aeo)^_FbQ+^SsYK_1W@0!|I7ZUwpYR z^*W2~+Uf)AQnRmXU-%qauk9fe*PF7iq_+Cr#HadX{}ZYWa&!^KR?sZr3;Hn*DP!T=`)ltIR9*31@oZ z*%SUwobugc+u6hr-(G&U4aq4r54fJO{_r=I-c@uk=h51uc6u{>_iT+g^144Rasdmw z4;#Brn{UO6iaD=Sgy$>fZD8?bV+XqSfb~NqvyeBBn>dd~cf0NYtAi`$RujqBg)8-W Z#D2eh_0cCCQo*3u@^tlcS?83{1ONq)-YftB diff --git a/tests/snapshots/nanosp/test_sign_psbt_with_segwit_v16_v1_0_0/00003.png b/tests/snapshots/nanosp/test_sign_psbt_with_segwit_v16_v1_0_0/00003.png index 72bc053e6fffbe3224264056405dd988f1dc2ea6..ec98cabb58fc74b78d370364e4cb6e8338d7d0c3 100644 GIT binary patch delta 443 zcmV;s0Yv`S1JwhNB!8SqL_t(|obB0La>F1DKvA0MPT2pF*h@c>@en{*fP@qGo==Pc zi&r2a00000w~{j1sH@+GI*(KH9v+3}pW#vds5*`@#?WeBo?hqi_?%z! z5<8k7&>V>|MkxyVlqTts@^y3eGoT1)F&m0+YbFL^%r*mEynkD#NL7rICe0$R8BjD= zIrisD$b+j4cad#qaM*I$1A@b*8Z+T6=>4iS4coSR8F#?Z?tCeDuIY7V&EV><=BMkA zzU1i^F8Z-8uD>QUH#%uMl}7Z$CfxbuQ|$J2b)8m0%Va(DKB?TCNe7s;1OR}4VD27G zx+}$)^~>ZveSffe7o-Mqt?;B^~%m1j_nA^iD!>D^{Py%RW9WVHvB9WYc}z0qBsII1q8-m9g=x$1f) ztbC9DKd)_xR%{C|N_*rFxa{7bn7FSFAo@GC7thcC!8C9iVyNkZ4NihgAGjjC00000 l00000000000001hn?JVB+}-l=J7WL<002ovPDHLkV1j?Y)ms1n delta 445 zcmV;u0Yd)O1J?tPB!8YsL_t(|obB0La>F1DKvA0MPT2pF*h@d0@lYhN0D)8Yo=<`W z<{5AZ0002MW2BT)O7@=``Mv5>l+~_-%(JL^uN6V_*H{t1mu$xvW6-LXr^`GmUgz6A zVuShu>PU<+)>^@yqN@F5eB7P?3@943m<`3dsfnR7X4Qr+o`01owIX`eCe5T(GoYxh zaqN#p$Q#$#+(ovo!QpFF2e^+EInwjKIR?J5P)oLLyO;A4bk;jx3XTSnnJt5>y_#RH zKlaGOHJtS28?L=3s2g2vJC#9Xo_5M*9YQvfYQ;5b1uK_B#_E&G!?|>TOHBX(_y@-B z(Q0?4=rezrynm+;X0IZQXRDow;rD&2tg3oMuN~JLMV|+>+fHZd5W6?gD}(*n$%(S{ zd%#~|8QSU{#(*VX#BOvn$~lBTe=mL743Im)qJq5kfU*O+!l_sA_a^p|5#(N7OB^e% z6=CLm?BBe$C3^7;ZNogD_N5xsXiFa++z&wn6QfF`$~0GkZ#1SGI} zjsPhEtvN2XW0eBrH6Vu=eGw4g)&b$X5Q{OU&%76F`Uk`Wgl9<+kO@dYPkcfMAw&Us zH;sZ0?@R0+yqypOBx|?Lb{<$A)Gf`EnlkrGBii87^15pLhBLGLFYUbZrgamiT(6eT zPlS-EbQQp1%y^w zuA}GgE~-87l1nRkrtsmUhR(`?6RI-xr4yVU3O%}f9`Kmxw-6ow??)F~=06XxPcL7@ z%0TF!<8Ek!)r-6_T-7D?moNw+gb+f=30FEDnT+QIcz1a*OADW3v16~Qs&b}Q--Oc1 z_0)&2isM&#)!4O8*Br-71(fv6O+#D8!d(J7HA}r$_aX?Kz8$?tvrJ}Pb$@pi(4&bO zI%V}g#1Y=I;k2O?e-AcPP?2qA{x0x|&!=!s7VA%rME z@1{}E;eCkRgSQi6fMo5q+0Fy2gSw@8Qd8!BX+#@bT3%O;-*9G@|D~O0-n4Gwl< z`H2uRwXT`Hx_@`eZ`c>kwCo#)box*wui@+Njt~p9Wurdq@7slC8>|{JY#IkHtbou; z%XRep-9@zrUUF$g&lEnK)X-Tua6(n4zI1}qL!n2P&jY?D`YlAq|NQ7;%lzj7_UYw| zSQ!ZY@3A8PM<(Mr0eD_s%+kWASnSxVs;Zo+)iXArUNv^D(>2HOQUN7BbJNh4v2d4wPR&y9)x8J;cL_)=>dskT^V9v^C7?$W zHFV1AcZegrWd-R68U!2hssJH`5JCtcgb+eD@DG_;bg&84X#xNM002ovPDHLkV1n(h B^iu!; diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_0_0/00000.png b/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_0_0/00000.png index 8583e39efd65ff8275a2f940b088b17a1e4c9b3e..e903d67eedf83e52187d7ec93055cea0f3f9a586 100644 GIT binary patch delta 443 zcmV;s0Yv`o1MCBkB!9C>L_t(|ob8)YZiXNXfd4JK3HLt|ciDppVTDzM0#?88!9;{o zC-q2ZRvZ^|-*90Zu1+cYiCv&u#^VaM#@c0002* zWW{S+{L6U7jb*#5So|)#s5--N@eGakZXoj7*KNd7t$FaEnkXJALh{=fW4h+~kHnOc zZjY-dQtBhhwzpTI)YBft1Il@+?CZw--D35Er-_5?@qj8SKYAN zZN-$ei*n}i9TkkLl4kiEMygAdb{ZgG9))INjqh_S!f0awGY zJ8Z?2wTp7*@qe9+tCD8<8)m9Ym3BHHUmk^KV&y!of69OBK`v)RJ^%m!0C+;*8ExM; zRk77-!?Be14!q%I+;SsUO&sc($h<-|A*$CAiOe$JP~KIB6ZXHP?!^ygI+?zxp^yge`EayS z3F!-L2mk;8000000001RnU{3{dNIcIe%m&~NX~HC05bKG$7b-?04e)2-PJ-D-qryq zWr=o|cdufMa{lRmbiwNgfSFb|_t^b|-w}}I+GFZ>{_cXpvwvu%{E-T*CBU*o5492ilw>|mbV{$S52GCWX z<)f%mec~^-M9MA0y<~q)CGxAiJgeB+Y^iQZrXMWdw}Kx$taGF+&kmdKus2nQc5A%% z5AIY{pR_DIoNtR{zfu24i)IA;p|VrYnwMyRA>}+XYm(9I2ds5haF=Xxs(!1O{eK<- z=}hTk=q{C)s-CpJN_D~;zY44CUCU|%Q5TQbEy>4V5uQLk*#H0l00000003YyU)xnV U6SX>Qxc~qF07*qoM6N<$g0C2{O#lD@ delta 377 zcmV-<0fzpO1C#@hB!62;L_t(|obB0Lj>0euK+%BMN%y~`?1hg?k(D=YTG!>Cj}e51 zI?k(1LI3~&000000001h)4Z$$(2Fsq*W0!kMskG94v?vrJa&V>4oKOT>8=*K@U{*> zDND4wyn7X6l9^Y;`Ko`3ZinsYRiqF^1%tU;)b zTH;qT$z=aBl~j}ci_r&`ScNRH4_hL=k8tn-TvohhM6~{OF&V?XhV8*0J|>OncYvM#ECNTfV6+)MVqsYHIXmuD4Qhb`43$@GQg>sIiSmvyd`<=JKH4M$UTYPaTl z|Kd(X^-asd;c{9e$Bp_+S~N4@50!&@)w)CnOexoyRf~+~Jm6kW1y{*7r|PGQ)&J)i zknWV;hVE8*s_ISqyHqE<)QVvftlE1ocbka1c)T7-J_eic0+S0D000000000004#g~ X+>kjF+=kPs00000NkvXXu0mjf_y4vI diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_0_0/00003.png b/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_0_0/00003.png index 2b51f30cfe212df5691953efe741325df2f02f56..61f34db33cfd1a4ec7ac68277a6a3bb82f0406cd 100644 GIT binary patch delta 470 zcmV;{0V)3I1MmZoB!9O_L_t(|obB6Pj)Wi(Mp1g=PTc>J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_0_0/00004.png b/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_0_0/00004.png index e16fbcdd90518fa678f3ee818c9a8ac09c9d1677..5a97706b86befbe64484a24ea121c79487251857 100644 GIT binary patch delta 988 zcmV<210($L2l5AyB!9U{L_t(|ob8)icHJNhMM+m@;`tAWx%9&+i|Bbk!f_kzuf_%; zOEQmh-PVetD2k#eisErTg8h5%^Pkss*)2(f`J&hWw6jg`eKy67k1O+&js~Rr2EQVm z2PxsWt}837Af$T8pM%@0>o26G)(hl!q_YO88eULM${A@aR(~AcUcBqRpvc8sa^3(O zu*OHcwAVr`-nl~OQgvs)hP{8icixLTvqVk;Hasx8;MU0Vj{v2>(D-K>RVra{V{# zfEpjlUVkJCn#YZa3dnBVux41$`hx9Uhu!EoQUnpRW^ zr!(wm4fp}`zOq-TP6Buo@ZTbqezicd6(3rA7Ew6|hkq0AiUvjAau5^MV6m*`2ObT; z90vs`aG)iFZ%M!d#Klo@@@dlouwnnmFJg(1sNn@@SW7$@8}l0oO@L@+p3cO{+TM6* zE$u0IZZ_8!F)POOoCp!L>?Fy3gQ8p7!iXUf+)6+SLKwlwRsyov&p{CY zj*=5zTz~E3+94Md#j~z!pIgQ)7&0HXNnGXrbIW*qHrW`!h_ZM~jFElX*cgt-%T9nX zqBe>f9RDOtOdzt9dnR-nXi}(gUORXAa*5P9Bt?K>Jqn^C*jk&BJZ+#3=*(SF;KAWC z#khM^Q5e|JOc3pCsU|e94t>E0ItIM~U^2D7aeu`MvAkzNypGpzoP{aKg|7j@7#X#h zl1M&vJkP=#(7p(HAd%&v4>drHgq0o!*9`JTe(Yl$HjSx z&yz+SaD&<@dPDfy{4x$PEmm2g1_1h|C4TNQ=R+(qvZR5Jk384TN%*=hL;$&)A=VNV z4qWTz?ky?XSw8y-&{Y1}3Bw!GOnk_!=T&)fTSC@C5+dA_ohe8ZN8M$uOJ8;l#(OO; z@{LUbP06~u6KyPZhF3P)Tx37#4kdz~qtwuMBObDfq9}@@NZ=2Wm0|GR{G;mt0000< KMNUMnLSTX?DBolN delta 987 zcmV<110?+N2k{4xB!9R`L_t(|ob8)icHS@ugq5D|#QR^8_tFP9ItmOh60+kqd{3<{ zAq-fT`JL8^q9}@@D2n27K9c><^Bn(s9EaahG#D?!2Be)e&hs4YXv_V|_?W$c=)T6U zWdDmT;W&R6{uvjelX$@$KPVE5R_1`QS3_ zc>{RJ8t?J4UJF>iW08*4>dY`B0a6HXW2ng~IUQ68N$I0fa|GX*_4 zcRL6-#Nzo*o}Pj_PR^Kg@*Ah+UDGpFbz=hHE{!b79^bIN*vOKzkUyE|>!W3IVJ}*9 zQ z>(4~N^0=w>li9F4)*K5~U$TAZa2UNniV$MfXb#Ha;@_g>6xVQ2Ne#_9L!V!DI>(OH zKp!x#D{GY+BtS=j|2bmnhYKcK`Jt_6fyy~K9J~t+LVwdjm4ZNdbx+ zXv*MQ67T?daTHEIZCC&n?BDW>*hWOu_yTmSZPX8(`He&-09qNRGdNlM8xO0cKLwA? z#`+RwVN8?jzeCb;kfiVpDrqH;8AB$xm4GdPFp`n21ngox2SuLLEL0>3f?PScl|A9* z)jq8qYJWiyo^?a}+A?p!k@>Vu;i~puTjt}l$ie_ll;JHHBmcCqFr1E;p8#h>Ym_iJ z@kv;iU}UNAOc*w>q)_L)cHiMEBva#*6hVgdRu~n**V>%qSp%Jf&U_jQJUQG>G42`_ z3Ihw838S4&)r95MOfZD7h`ReP8{pGo3xLv34Q$B`ENh93LM-IjM8&P#fp zbm~AGv`*0r!q?)Lag1qLWg9gB(l;ydW0x@>u*k%cMm|3CTq`Hx<2V=rCsem3Vl5OQ;yqcJf}l7WE^88$>)}qcsn|JQ`B-z2|D-FF2zno-hQ1qk$SR7WD2ieOe*op=XQsNnv-JP~002ov JPDHLkV1mHqE(EJB9N8dhzT4K}pJ;eUpg7ymUnSoCW+`#n>Ieg$v*i{@UA~4xdJSIVjOQ? z?4H8cM!OgbhT&VFSLS8-NF3<^v6*t6*2U;o?G2*MM~-auZ^Qy*M$i+eTmx1UTavmc zAKJxg!>xI{-UpX77dKgHQ_$(5k{4BtjT*`P=C=V6g6YP$JD`?GA2d}2vrtol6XfoL zOX12dix}HYyU{YO0v8U!se_A-wvmh-+kfPV zhy!3-BK0rjV*>BQwlmD3w^lI>CJ`Or&4Cn45uiNz`a!<>LoC?Q4;b8aRf~RD3UfMO zYQ>~sF^J%!f}z7ZRo@4 z4rrRDX>_>65feSCoDnZe{Lzf_wh9CCWsC5-;|`oow!)Nb3nY6ICg)X6GSc907f2PN z#(x~g0iKVD*?DKyHVuETa)Za_4HgzOB!$D<~s zgmuIu5BVGq?SM<&-4fH0)KP`eR#iZX*8tHoWBA)PFXhgTG`RfZT#_Q!n?oA=r2M+- zu2lw;X|+{%ybn@)*os>K-j;!=jNZ)?)Gf^?_<-3v1hG)>cd2Y&%; WVHeI0iKy%V00007 z2mq%~w^kHIQ4~c{6qoaFvwrV=emsuDE=dZ^FU102J286iqn+^~nuYV1&b2lz`Pr#F zNO8w;94YO9%ns#wKnxq^@iM&p690E9Ymls&-Kr&8W2r4>9DiP3{I3>Z?fs^65pqTV z4w&P^U)r!Bu9?fXX=Zr6*YaR>!1dlqMQzaF=5tu5ETxNJsdWI#NU+-vbJlD3{JDznMOU z1PfNQ>(1KWY8O@jx^!P5A{GNb`=!`$6%+Xqq!>{~mw#+)@1N%0-UNt0D{Tlm5yJO{MHtnS`TP*)l zJ|^%E>~@-&dUF+{!A(R1cy}PlQUoYZzWyM;`a@c6>+PkySP>bM}Q`X?xdSbe}BIhAw4EJ(*MJ$^5TJfafF9 z?0hhDeVcx#b6o(5S{L%gcc{B=$C6`(gn{o}d`*IzkHAvVU0eC)YLP}Ui+~grY z$3p{fs<}&IIx=-+Vf2;dkmNN$w9H6k)dh|1{IJVD)jf(-~Cb|wz^KJqW++ui$$q9}@@_zZplZwMWPP%|)t P00000NkvXXu0mjfn9R4J diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_0_0/00006.png b/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_0_0/00006.png index 80dbc0c24bff313d7adbf76fd6eaa262eb471db8..41f9333b1e827ea9d27f2f847214d4568db224fd 100644 GIT binary patch delta 470 zcmV;{0V)3K1MmZoB!9O_L_t(|obA~`a>F1DKvB}^O?>|&ahEPKWf%#B0vJg0->P+F zj0Khn2>}2A09fuZa&n9@|M$8sJ5mJX2a5sDcDltF^Q%AAI$4ZKEp+=CIa%~(u#s75 zbrK0p9T2lB{NG?LM#sP8cjV+EF=g_!roQT2i(q3)dg6m&M{*`W-O7EFStE za5!Vp6=vjaN`E7JO3+HR?93`JgYA6m6JSq&06^IF4#*d&d9l`u*V=|@QPDHQ8T`G1!SJv=i^)ok%YL000000000000000003~CKOt49#$s@6umAu6 M07*qoM6N<$f|=&nOaK4? delta 464 zcmV;>0WbdW1L^~iB!96++`0{5wbCHfdESX?`caN zk{H(^X$SxS0KjrTgZrnH%70^w?MM+&Zmb44$LW(&Di8f)onbX5kI?ORWan&3I%14d z#&Hq}%|{m{72a28#pw8t{Eh5v5mi&BHJ`4|wFquhr6<1n>3^paJeXXMIo|+3X9{w@ ztgnSgO&K3lZ?Wn?Y`L5y9bZqt!_bCW6nI&>0daFteO@S){PTTU7|TlGUxX)UMystU8vf-^qN>4NZ$h{u8E(i zF&`s0jERG6Ykxu8%_>{U-!!Gh0pP(#--h-nSE%LNA-!_7URYX@&aj|Xkp9=YPaq!m zs~?4{cMMjfKdc?R#w~9{EhCpVw;Z$U>q34e2`9x(wP-||d*>vg7r*m8Lqdf#fKGfAv*6!+EixETLis%$GW$z*?- zN~+2JV$8u#bfKNN5AQ^J0RR9100000000000001h+x!D0{H}bYO*k$90000L_t(|ob8)YZiXNXfd4JK3HLt|ciDppVTDzM0#?88!9;{o zC-q2ZRvZ^|-*90Zu1+cYiCv&u#^VaM#@c0002* zWW{S+{L6U7jb*#5So|)#s5--N@eGakZXoj7*KNd7t$FaEnkXJALh{=fW4h+~kHnOc zZjY-dQtBhhwzpTI)YBft1Il@+?CZw--D35Er-_5?@qj8SKYAN zZN-$ei*n}i9TkkLl4kiEMygAdb{ZgG9))INjqh_S!f0awGY zJ8Z?2wTp7*@qe9+tCD8<8)m9Ym3BHHUmk^KV&y!of69OBK`v)RJ^%m!0C+;*8ExM; zRk77-!?Be14!q%I+;SsUO&sc($h<-|A*$CAiOe$JP~KIB6ZXHP?!^ygI+?zxp^yge`EayS z3F!-L2mk;8000000001RnU{3{dNIcIe%m&~NX~HC05bKG$7b-?04e)2-PJ-D-qryq zWr=o|cdufMa{lRmbiwNgfSFb|_t^b|-w}}I+GFZ>{_cXpvwvu%{E-T*CBU*o5492ilw>|mbV{$S52GCWX z<)f%mec~^-M9MA0y<~q)CGxAiJgeB+Y^iQZrXMWdw}Kx$taGF+&kmdKus2nQc5A%% z5AIY{pR_DIoNtR{zfu24i)IA;p|VrYnwMyRA>}+XYm(9I2ds5haF=Xxs(!1O{eK<- z=}hTk=q{C)s-CpJN_D~;zY44CUCU|%Q5TQbEy>4V5uQLk*#H0l00000003YyU)xnV U6SX>Qxc~qF07*qoM6N<$g0C2{O#lD@ delta 377 zcmV-<0fzpO1C#@hB!62;L_t(|obB0Lj>0euK+%BMN%y~`?1hg?k(D=YTG!>Cj}e51 zI?k(1LI3~&000000001h)4Z$$(2Fsq*W0!kMskG94v?vrJa&V>4oKOT>8=*K@U{*> zDND4wyn7X6l9^Y;`Ko`3ZinsYRiqF^1%tU;)b zTH;qT$z=aBl~j}ci_r&`ScNRH4_hL=k8tn-TvohhM6~{OF&V?XhV8*0J|>OncYvM#ECNTfV6+)MVqsYHIXmuD4Qhb`43$@GQg>sIiSmvyd`<=JKH4M$UTYPaTl z|Kd(X^-asd;c{9e$Bp_+S~N4@50!&@)w)CnOexoyRf~+~Jm6kW1y{*7r|PGQ)&J)i zknWV;hVE8*s_ISqyHqE<)QVvftlE1ocbka1c)T7-J_eic0+S0D000000000004#g~ X+>kjF+=kPs00000NkvXXu0mjf_y4vI diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_reject_0_0/00003.png b/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_reject_0_0/00003.png index 2b51f30cfe212df5691953efe741325df2f02f56..61f34db33cfd1a4ec7ac68277a6a3bb82f0406cd 100644 GIT binary patch delta 470 zcmV;{0V)3I1MmZoB!9O_L_t(|obB6Pj)Wi(Mp1g=PTc>J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_reject_0_1/00000.png b/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_reject_0_1/00000.png index 82b81902809ae5ed03f6834423e44535ebf07d74..8a9432bd653ce307c5490a95da12872eb8a43a99 100644 GIT binary patch delta 959 zcmV;w13>)H2h|6VB!8SqL_t(|ob8)ia^xTkMVZv>#QR?od&x&vC`!+ZgdIAq^EK@t z5FoI)cv>rpq9}@@D2m7Vm$dJ_&p)s0vP+Tz^Fy%!SWlSV`&<>Td_0+ZItmc;0ACs7 z!It5;u4~t@f{^GTKL;Y$Ui_=OK#_-g*|P$0 zz!)Fnr7a6Fc;^V6L)G2=8n*s=@7#(zv&5bW2zX$a;I)zdj{({OpEhv|O0s7QdU)^F zAa0O1=b1dc1r3ZjL#7i?oHAL{1A%qp1c)gb7?NXr-CczwviL4!ZzlZtTsi)3cgdau z4#!Bk+K%DN*MIP9ThNne1GMY-k}?0wE5Hu_q9}^uE;MOnM*EXkgZqRLTt=lB1Y6`iL+*+`2aTRhBNP}VPceAT`2wv2&>9=dGRY+*A1i2 z{LTRO4ww0m5xYx_3oPxtzIK#C_j1Oaq+2Fn*MG)pF!Z}~MqI?51L#gT(1864GV)Yj zOj8ySSH;{H_ewP3#l%6_^AcWSZ+>=Kb0Di;opK@bvApq>t4g*>g!5 zEzvYGLR@7Og%?pB(k{gD9*MosJO}gLHD*=I_0>p+wTFmwLu}nvM5zbycF9S^RipkF zet#OOomn(B%^+DmaJ0b>%&{Kj3Chu2apj9TpDgkZG;OcK4Uyf+ZHN@G_gkCbIe^C| zA0~U?Y&9Yf@XqfX8C4WyA+02=bX3&eH0I=p_$l! hgQZ;*MNt$1z5yTK9t@0F9E1P>002ovPDHLkV1l&d&)@(6 delta 954 zcmV;r14aDR2hazQB!8DlL_t(|ob6gka>OtQbW-_=|NkWaC5Ne~R4lC)!pmgnQ{n-H z1VX6oZ7UQCg+ifFC=@Qo*P{M$9R0uhzGF!t&_6T+Z5{smu0fdAEIhs1+t6DtBO zhAi=pYxgFc!nK;ig9&526oq4&-_~@{T~}h0C={>*AULcc8!rA9l8lSz;TDRUAJh&2 zNVMV3SbtwJm92p}gCY8f&u$$(U&gmn-UlqgtnzJoB7ZqzY=?J{K^zV@?@+R@9z9zCR#qQKqLsparod}POaYH=9h{3i zJzHp)T^v^)7^(o62$Ow=7B*A?NXK*x3WwGHD1f?sR(&&dFY##IXVngfF#~1IXi#^PA>hD1Y5%|n-~j2 zkV(q3d$H}6_Hpj)*z2^~qlmeeGl8^72tZb01%GI?-E&slL?8xpCCD29H;$lB)nb}c z^Z+b~UrDb_6)k2i!g}jGjf<~r&%7b7d-b{BhCT#u@JjNAD`lZjD0~Ly*icc9%}x$< zfjqNlk}W19q#v5DlB0lm31^szgqhTVxmj|Np=*S0fUV>y8s169RbZbHLv5%ap%zDC z9wycSkQU59-W-Rt8d>y)GWSpsf^pMD{F%(p z8E|)iW+n9*a1sT$hrSuz{SQXX=>VIaZZqJBx|$`8W$x$XyGF60HzV_%a9FFD&O)J3 cD10J*0cyn$RBliB~0yq7*iwJ2aX7?N~Gd=J$$ z#X$Un?K3@&rfHg{X_}_Foqw6eV+{K1>-DlNnE`#M8i0Pb8DmUW^IcX+(wC*JlF58! z8nbMYPO7>Ugm$Q$3M{wdCqro??L+*}G*)3#hIZ>}mK|bhtAEoCw^#pa4Djkt$<9S6 zSOGZT9H0HQS{AHdsQp38!ui~-emG+c)^N3Ga0&)sBfQZB_r_j+_Rco$x=~9|l7bR+ zbM0Qi(qP-B%MH~=<<=53*(k@-1}P)aQX@wZY`D!;1E8MIz*#o?*R3k-^nzC*S-$26 zx^u8tau3KKi+@x1fIp6L=sGI;uEfbRCFo98y;D_Ql72pR1=!QSX_}@v_VxfN)Y#HZ zMlxh=L05=O>&i`_A7;$tkWkuT{78QzBXw7l! z4~-6bPNs*$SAfh?%|=#F_5^TnSp`>rm3~+zM%xum{&$Z2dr{ak zOIO|dHhiVeSy>G&EQ!%!E z%Bk1Ohpal?Fq0bqP17`&^HuDB90&cn@4MfUHJ}&O2B4iej^h}1#z3qH=}2j>VkG}6 zod-*%W8e2Bc0lNa%5}g38{x?|vVDs0N@okUYUs3D3vCliTYp_~czgA~R)VeT#mPlj zvjcFzH9qFc+7@hTX#0&+hSzm#9b`A$aU86pwP|qHBw!)}rweY4jektg9O0%>OHh$D zCFsi9?ZCodC#TN^)kfv&5;SmfhNKg}aY|JinL?yjg%cB?-lBmEZOm`jp54HJRY=yZ z@qr#2%#l0;7JuFozb8&UiU-CjBe#{H+gY`2d-sL9G;d6xhWdg`MGItoK~sqM z8j47u9oCqM95ihIhP!l1`-fQZh?BSBm0<8@>OFqg82K;}&x{nI4nV44s%TEvg{oPG zpZ#F`J(1dEsg*mu-s1!?)9P%3gmq?YXZhFZB8|)Gz<*WPP;OIYb|(zqb({cDnYs9( z+}S#682E986ev*UQ;!YCDL=@7sPzgYrF5peSbE$^&veUv51=)@0`8Hr3$p zP-J^VB#?v8P6QGj%T^ekW7B*Rw#E>y3-+j`wwDXpa-9VieAr4y);kzmDt=Q7nh+*& zn21I#`!2@V9N}{!0LP0HTNpEc+yU9j%W{Bp2g`lR)M&;I-mJm*;z6^%1&Fcj5tB>_%fKf<~A zeSa4r^IA~qIR#g5hU(|{wG2wVY$Dn)HtR*i#2Y9-T=8Zci;`a7u-9hfAT5KAxF*}r zf#}4zGI8gtiPP^TZpJ*Snhd+5?vJ&kM)aU3;c=+Q(?#Va*2{~mI$i%pV#?!#60j4t zLe*B^JY1WDP$$McCQ1-;kg9FeXzItKGcQ6~nk!!Ldxt+mYd(wzm7ve06VNnG(=<2n YAAXW$y%NWlz5oCK07*qoM6N<$f^z@Y@&Et; diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_reject_0_1/00002.png b/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_reject_0_1/00002.png index 258f26fa84720804c631c5d73b0ddfd790250f68..dd9c4698480087fc7a7bbf924f466537b0e4e335 100644 GIT binary patch delta 487 zcmV1AzpPB!9?BL_t(|obB0BZo?o9fMGW6Cb|ESxXT`*A!K9XU_w~+e-G2z z5lRg)#7hYP003C-D{^tpxqf*ZN57?LP`}x1;Ou8u&bj{dlQqa@o6^Iu@5sesG{H`0 zh1E#}vV|04a^U+CD!zQGl#kt!e zh9S1iZ7oefMQ6@D)9F7r1y4;2*49%K&^(_xmt=|WWmXXfS$`I4rZ0Ug7N4c}fcUXE z^c=9c&Y>&Kh=1LbPTomDD_PN*m0p7VeC!?2U;Y4qw8I`SP*4>4-6}dY50ttlVVx=C zl}?ZO#ki;4jf*G{>AzZ!ENgb}6~|Dkc-yS0rRtHVRMUcWp5~CI_qnyYFj@c9FRkA@ zMYqci`!7A0KWB>+bnAY<^&hnTZSf>LP`T8hKRa2LyI^NoGy(Nq*WCABtR9Q;SljYL zMR@m*{s%CFO!Sv&gqr9t#vHtfEc7P!;WrUp000000000000000 d0002sF~8KYth)4m7ey+Pk+xQxG}gMeVzb6X9!Zf zYLA5oP2PS}wWT%>#5;#c(rs!FjbEPxT(|?Hi+?on{ZoK0(B(zv!zfdi^(jFkYqvq% zhFCeDX>EAfD?3xBltQ!+h+@d+BWQy-$d$EyqR-t0;(tBcYA-x84+!L?K z$Vbb9(Q%MzC4XqTUelK8U)5!f1Hi&sPebn}&W`Lu1^Z|=-xllLBx`9wZ8LuO&f$Q0 zuel5LEvKP=#UsqE>)!5;G1pN%ST_#W^3zTIQjb}@gx!6x$xndo)IVh}^@3l*I`n(7 zT4UvWK>|A3GnfCJGChkj0gw9ao(>=vnCZKN@IET~t30X(ndlEw2sP0kj2z5F6`F~4 tcqYON0000000000000000002o<_mBwbH9I)JB0uM002ovPDHLkV1kXS)~Emg diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_reject_0_1/00004.png b/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_reject_0_1/00004.png index e90cd9db37ed7e4c669da0b1abe6e4a823770f3c..c4c84cf4c1fba26083e9bc251f7411d894424174 100644 GIT binary patch delta 340 zcmaFI^qy&gO1+tx7xZO zaQ6d?FngJFheD0*nO_f^H{34ZP1wSDdm~T6{?~o==UnyvFlC&#xh5&YEbyOqvGDSI zHhIRBWk(Aa-S+IBH-DqF^>(MP*Oi;Uo=C7YI#4gTOM2J*8sqd+m+t-hvU0Iqz@NL5 zT@R*DTYpt{#-+J3?UDtTmQ|ZhT$wCzU|(D+$M&tSw`FqchW>KWYq+?>?!U3iZMWQ& zk`uWX^xP?%ah}KbcG-s4!TV+Z=HA`^YZ24V`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPL_t(|ob8)YZiXNXfd4JK3HLt|ciDppVTDzM0#?88!9;{o zC-q2ZRvZ^|-*90Zu1+cYiCv&u#^VaM#@c0002* zWW{S+{L6U7jb*#5So|)#s5--N@eGakZXoj7*KNd7t$FaEnkXJALh{=fW4h+~kHnOc zZjY-dQtBhhwzpTI)YBft1Il@+?CZw--D35Er-_5?@qj8SKYAN zZN-$ei*n}i9TkkLl4kiEMygAdb{ZgG9))INjqh_S!f0awGY zJ8Z?2wTp7*@qe9+tCD8<8)m9Ym3BHHUmk^KV&y!of69OBK`v)RJ^%m!0C+;*8ExM; zRk77-!?Be14!q%I+;SsUO&sc($h<-|A*$CAiOe$JP~KIB6ZXHP?!^ygI+?zxp^yge`EayS z3F!-L2mk;8000000001RnU{3{dNIcIe%m&~NX~HC05bKG$7b-?04e)2-PJ-D-qryq zWr=o|cdufMa{lRmbiwNgfSFb|_t^b|-w}}I+GFZ>{_cXpvwvu%{E-T*CBU*o5492ilw>|mbV{$S52GCWX z<)f%mec~^-M9MA0y<~q)CGxAiJgeB+Y^iQZrXMWdw}Kx$taGF+&kmdKus2nQc5A%% z5AIY{pR_DIoNtR{zfu24i)IA;p|VrYnwMyRA>}+XYm(9I2ds5haF=Xxs(!1O{eK<- z=}hTk=q{C)s-CpJN_D~;zY44CUCU|%Q5TQbEy>4V5uQLk*#H0l00000003YyU)xnV U6SX>Qxc~qF07*qoM6N<$g0C2{O#lD@ delta 377 zcmV-<0fzpO1C#@hB!62;L_t(|obB0Lj>0euK+%BMN%y~`?1hg?k(D=YTG!>Cj}e51 zI?k(1LI3~&000000001h)4Z$$(2Fsq*W0!kMskG94v?vrJa&V>4oKOT>8=*K@U{*> zDND4wyn7X6l9^Y;`Ko`3ZinsYRiqF^1%tU;)b zTH;qT$z=aBl~j}ci_r&`ScNRH4_hL=k8tn-TvohhM6~{OF&V?XhV8*0J|>OncYvM#ECNTfV6+)MVqsYHIXmuD4Qhb`43$@GQg>sIiSmvyd`<=JKH4M$UTYPaTl z|Kd(X^-asd;c{9e$Bp_+S~N4@50!&@)w)CnOexoyRf~+~Jm6kW1y{*7r|PGQ)&J)i zknWV;hVE8*s_ISqyHqE<)QVvftlE1ocbka1c)T7-J_eic0+S0D000000000004#g~ X+>kjF+=kPs00000NkvXXu0mjf_y4vI diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_reject_early_0_0/00003.png b/tests/snapshots/nanox/test_get_extended_pubkey_non_standard_reject_early_0_0/00003.png index 2b51f30cfe212df5691953efe741325df2f02f56..61f34db33cfd1a4ec7ac68277a6a3bb82f0406cd 100644 GIT binary patch delta 470 zcmV;{0V)3I1MmZoB!9O_L_t(|obB6Pj)Wi(Mp1g=PTc>J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/0'_0_0/00000.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/0'_0_0/00000.png index f6ee4a8956a7975a25b4fe925af3f11b06b663bc..024f0601e0fb2f0fe36aff41953e679dfe349f67 100644 GIT binary patch delta 366 zcmV-!0g?WT1BnBWB!5szL_t(|obB3M5`r)cK+)>B6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000@y^?k{z{txX&&Hf zrg3A*be!k8YFa@^_K-gtAFs}Dh^5vFn>2_;9AzK z030yK+k9!uLQLL1L;F;9tKWgGzw5eqEAGq?YXT7Pz-WT^My|h2&=Ppq#1b^gni90R zc54tf$elAMyGu~Rh#3-2eB(5;Yub=lHwHl5qJb&d=GUz%WFw1LA-kCH<9+A&z1?N@ zIUqU4rt4TSeSh;kJXV5sqD|1M$CsJrKY0b%>0cB@QQUG5KsKPFKy(0`deV?+4_Yg6 zXw6S?2+>CK92bclVo#EYuoc!1`i3!o>>dz_RO}((*kMZ%M9Fdmaq>H{G~hCs+dp^J zPDza+KOYb_G~pXh0WB|(G~_?qS){k2q34a)uYk0qQh(VdAGTi^fK=GE%gvP(QUrJL z<9B-(Xm4^}4P62JQiCp>z-lhWD+9$<|K9ld<5d* zSAXKCF7s57_3=Ld@16b8=eP{WHR^Sj@m|!at{7~QDXmy!0C=S;vj7@+I)c&F)An;N~f4g z;*&799F;Ts;gEL;+}>S|h>jZx0QcLj5`AT8v&nzr*M?hiEsRf!o3mnbaUjD$!wG;f z*P`Fz2W$A8YJ}yW`Jsmf3XJ6hApAvNcsJ$hw|@c4%se1R+e)YL5!GFrjYk;{0P_Cf zkSf*aUXa_97`QzzR9Ic+cVEw=y$hVNyp<*6rg$Oqo5}TUDE`_6x4eU$#jPlc;y$2z zfVKfA@9VV>+(0uvs5nqNwdDEMP+K)wS38Ic#=|b!$3>ykIE!nCeG|K%QCy+dz3Rz+ z8h=?n%!*}=El+ZVwNKl&s!r)Y`nM4ez;eGeJ*zKeWGvF8uS;BE70nFx>@~*%AXalO z?C=@vJJHOt0gBaPobcd{1t1`E+VXVW^)vS=xY2z$(FY@*!v5&B6keL@Fxk|arz+xaut{y2{M=5N?Rgb4~6pK?RUACY}7jsr%G)&#byI0p=-@wcT$1?Fylq5;=k&LRLCd>iU6o@wBP;d4es<66$rYmgY zxy>uYF@2jDqiuET2X(^^XK-^yA~kzx^{RlR2%%(!nz;C1SOWA*g0O$no?l5FPCj#> z^0aS$7I;&GnTh&uxjT2D~YzK{)wS-}uyJ zz7%4K{7=A3qyJL9(=JnQ{3b8O4Rz+=27(}G4lYH97pbA1_@ghHt-#5Zhmj}6(0zK; zrlLdYvVSwRPv8)F)Wb*MJ|8?i%Iu%fIKvTJ9CYO}k_l2otELE)PIESyPr}-=Rne@6 zV_qkS-@h##N&ByF^p}t-E55#bh9adpa)Rv^AUSQM|jDAORrOrr+id z*7%rubjv~GL-V8b4HP7x&+iern2~T>Em!6NIe!`}onAn_9pddYCxCecv00U>^(?6E zMGnHAXDO^9<43P0@LmUwSYF4hL6>+T^UYlHyP$6PHz&O1bZ)C`Ns=U2L+t_H0UT>1 z;#og5(}S7=m0MGuZ-LtC$-3S}UNCNU5nnfjQgD}-59=nlpH@PlH~iLv{S;RDVOHO) z(SMUvPiNh8EnJ^6>Vv9Ae*&ia?MYg7DHCIfCUsrX3ae=bxaYXpmH@MwYhg!6u-p#}UwSrd4vvdji1|wE^4w%As6^$fGlH~3D1D}WmX$<&xlmGw# M07*qoM6N<$f~P6TSpWb4 diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/0'_0_0/00003.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/0'_0_0/00003.png index da12b9ef3c30cf369d132b68a5172904f5118693..977159b3f0b657c5c0253fc0de28fd52d9671f77 100644 GIT binary patch delta 1000 zcmV?$^F~*pz=3Fc#>164sq%yxV zgPAr-CRJtyK@BQhf$4UAX((wV{TBXY2CHB$L(OV=*(F?Cb$>UUUVZB z00-#f(_YrLV0NMO7YPgZ^JVnIF~(p6txbcYU;zT+ogp|kHu-6tFqZp94M9m1grJ9G zw*{sKJ2sbiAlj&SGz3iq!m*@5!pLr@k*f#}4CB-SsQDS_Wz)XPsKT-rJPOJ1HGiQe z2a_ewfP7kb1-M`UjG#YEDS)JMma5&He z&PwlahCZb#h4s#;L~DXFsol~_zoroYhP`tf9rkVU9RNSRd;N#kv)trW1Fe z@041y`Q>LLVE6P~ZbLP+>IT^eq79FjO6vu{FCWIg_kSBz_XM^4Ex*~~Ce;XUns_0G zce~j1=0IfHOA%Y#?sldOp>M1ej#t9q^lmbF^S9g7M3C&8)*`h4-@6ei-y_26fK zbXfn8VW*HvEFZEnoE?BNu+CdqFe8vV37HEW8$Md4yI9AVf;aBO&qu&GRuW$(;71{5 zA9M}c`hN~;YFfb)c+@z9jzaIm!pOY_MusrvWf!_~XvnvQervuLSMsNYF5V2g0pWyrLi;YI(e?jp716UgFWaaXe ztbbyxhZaM1ILjj)eN-tdq1>u7)HxnM3BaZY*tbGhl@lPnAP`$wIE9x5F=t^uqLyY( z0TpnHWjV%}57NS9jvRJLwcPVdOR2v@vq(di7a$HjQ>ChVPBrEys#!PTB?kDrb=;$asuL;ITZ`ud<#Di@O?xzShUJQ-QCY*g*T z@X)`h<|h+_C2IRj;;jhQQ{0W$xFGuHp@l4Ip{wy{zDjD?Xfzs)Mx)VaRN^l= WJ$5&jw~=E20000iEO delta 994 zcmV<810DSS2lxk&B!9n2L_t(|ob6gmvfLmHbW*vA?|&rUB@0(5MW3cYvL|^@y_&&7 z2q6SC97m(kXfzs)Mx*gMekAK(*Cqd+=ZPhifGl(cNIiSFu50KS9f>TIJ(abRmi)|A z9w>3gd7dSDNJxj;I8cTS^Q?@OU&60U?nHWl%E% zc#ttZ{1r_LLa`$FoMl;cyj>%y z(@1|F(n7aimIabj$F@E50pKqmuD|a$sxAp?^+$2TYk#vgWKzxkL5!!mRQES|+UZ8P%0nfQ-m!!uEpP*r;$V9z-VW6<7@PnNyEk`NhlrhIS$x%|1IZA zL+YRT0m>O+ciP!aVbVPO37bUDS3Gsl4A{u{g@16b9G19oT(X*Q__ugVc;tC{6{2e& zrsDkrXA;cjM=O8rVvrpG_a>_l+hgzoO8SllV6OpC3n$sAA(tO@H2~JrT@s@-<+k}Pc+T^Elok}cuT6Fzm1%N$ek8{g; zS`tx|kS3Lwolz2|AUU(tysLHe(}cTHn;{R}{4+i!Eo?LzjYgx~A8Ziy= zv-wy{OHg9u%#%+4#%XZZv|w%Bm4M>@%()~}e4AB8Y-Igas93)AwpiRt{|1b2i--OX zcsOIz6=uY4%6}kxO3+HR=*%iFgX6sR39y$x03a;>4KVh3wT((~FDs4^YMa95fsz=( zf4KXRiU&BCy4d67CqJHXMkY4V{L|1P<6KNP3#C=uT#vN|`Vnb%S!q!M&Xbwuv4Qb= z#E9e7nS@Gl+hS1yigcha9VF;Minn-3plfy}K!;{-uyTy^sOMy5X9Bi(PUufE0UMv$ z`~-jEYj-i=-Xn@ect7F|MmKx^x@#Ja58gs2VDK&GteI3Uy;00;pNZoV?(u)C&=WL* vOb%{EcmV(a000000000000000fZO~6hRBIqohpF1DKvB2Tov{BUv6p^i%20to1{s*-p073m zj3r(}t_uJF09fv8vVM#)|2KrtE-4D+A65$(+ZhvM%pd)t^{`qdwJ_{^rgGvEju3)N zJ4Pa)>FHufU4L(%*iPE892)`JPC9?^_LGR3!BUL0hNt59|AD$m5?LFFFccqV>N zjeN{(7>TYrMK^BT4cf0fG^2Y@#=dmHLYJGqKG1ML*py*|pT+wXBdNOjMwUi+j! zELAM6?efTNs9kwE+PE$ix?}vZ&56BsCZPR$h!)4Y+^^4koiYR3s=p{`4W2pDHJcOQ z8?46d)3I6EoPY(64gHHuz{)9{-`9IRbY@pypcCF>cT=h{cTcEms2$keGk4{Y|B!dA zbmNeoxr>?Iefj5ua&VvzT7?eO2{Ji&6yXH`0000000000000000018I3u|0)B6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000{YmN8f&Pm^=V z^HaQp*hcdl7l|EWJ4r;?3hM`B$Cy911wX{wFOBxJ>5S=dRiz zsWIi}2ZRkx_{Kv(iwh(S`QLsPu{L$-^~U)buq|7uY=4WJ?N?5~R@iHo8!KB#5!}Vg z@BS{(E^=NC%>aI@L~gte8YLGw=$4z;_$JB*_@za(asyxYjFwI$A;RyT#2$bjfq3|P zJn^k*z7-@t{!PGpM}Kx7w*>^}5@5FX~X&96W$C$TbJI!iRTS4K<29xuH2TUYe_6h>#V8RDLNXtR_8$y>d@2Dm?a8kmA@^LocR2OC!6cTxw{inI3`1zUq2sQMp inB5Z=MNt$*A@dhTqd{d!aU{9`0000^`zrp@0EO2B@ZQ7i%#(!$i;qBG4y$M#waeQzQ z=41d47~?cvy|hr{w++%ZT8*`Zyh4^f*-Ls7WzGa7oG`lJ*4Plx7>y(6OkIM;nX?4l zxpo^cH`v2-P3~TT2xHEW>BI}Cbk%fER9!d$YLy0tB#p1zo)xm-Dr7Gv@_1_*e6SbW zW=`Sw17pe~=YO#!=y7K4UB-=kEE9{Oq9}@wWK<1RK?+b+AliVUUbXD1u+lza%5Kwh z8&`;Zat|>?+e+&PZO4Q&c6US~RV_rlA}lF_DOs*2&i-dD4dhD#*S^{w&!mKt&lFTW z?HiARUT7eZDF4#gxz`D3zeqGz{sBFVnSBFnBM{Q!If=Hz#K;#1Rn zDOig9PQXh?|D}4TzD&LGPF_lPsA~>xz!~J4gG-Ua8&*S&IuH3e!Dyydz@ZPhRIdp8 zo4fN`J%1kz8H(&kDa=)|hG50tloGZlJ*B;JPsxM0!ed_oERKCO^d$5dPcQTm#%0R` zknFEu)>e_>XhG>DV&7=07C_@NuUq~3w(1#I-9zpr#kll*Y+f?SH5Xrt2A>&*4~D}b z4<(riKs-~&IxQn3_Zf|c&(mUL>&wu|{7*m!vNE$g4V3&8ut8hd{Z4dTp zLEBGhO=eptKfv_|slW3K7J{~s!5v?yduaY{W{DRvSL15*53XSIUrF}fY0M&*^`U)C zQ4~di)-!aL6ey-=NqI}Y$x{2aKaU36rIC6@+E=fO*a2Pg_W|H%du}ZcS~H}ctG8XG zKz}fQScAD2b;?lbP$(^O(1$AE-1qXyIH;x(KDf-j{0ApohV~-V4taT2+R4qO>VP~r zJ$OMi%*CGoWM2-7or5Go^*Ror`D{W{X&d+K%-o1YqqwJ~xX*ycnV40O6d^aa?i!uY z1z!gZ%Xw?LRTRwtS5Bd3Q4gf4@oAI(v@-sO-lDL`>)F4XD~g}L$)8X|KZ@v{uqcY6 bC<>h)ZZJd}03QjV00000NkvXXu0mjf@fy(E diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/10'_0_0/00003.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/10'_0_0/00003.png index c06925f25fdba30025a0c3cba9e0c720458f26b3..8d9b03344603e98f8a2629092f7206c5923161e3 100644 GIT binary patch delta 937 zcmV;a16KUG2fqi9B!7lUL_t(|ob8)ik{clmMM)|<@&1?8d&!4uD2<*ML_>Q<=OZ<4 z^AwVR+fHjmQ4~c{6h*O}Kbgwcbmsh`a7TEeKXz!M4qi4cSIzYYOU2q+?kINh71FMy?`QahkgpKs}#d?EXv% z=vacH(=Y4MI{t$f0wz>AefjOMDGW_21v@ocCvJJTcFGL(sCJEX7j}(bgVp=NL_3`s zDFPA5KvWge>cV+$HLD8uPE0#hhP>MkI101?VT`NOLw^c4ZNk(Rh>|RCr@rCTZ*g0% zJ>WtM04}B^pC3a_4fnMrsD37w1aX}=>tD!FGTYq;k`Z-h|FSA zw?fo^*)MZU`B8n&o>5qHeHk-v;+dR!mk5hZjnrd$#Tm<5B*uf{d_U$Q)z?U>K=prM=~oFaayp@*pjD2k#eibMPdG%?%=0Wyba00000 LNkvXXu0mjfW^KY( delta 931 zcmV;U16=&S2e}83B!7TOL_t(|ob8)ilH4E+MM)|<@&1?Oz2w7H6w&j7Waysgd`$It zcnV3tbx&(WQ4~c{6h*O}U%~qKeUHCh*JYO^1;&SB0kEAl?)&cT^oeLA9A`S#3XbG= zq;e<49M^TFv;#64l=}f0SRWoQ!^=(BR}Oz`_WODtK#T{@p-pxIrVPpddLZ zXlL#=Aj2R#r_F|JBeFXMb&NGbmJ>fXO=TOtgh;IjFD`(1L<1eI+t)2m4lrOA;<>AT z7`F}55#Iw6&ws=}6JtGs8%9SO;9xY zB|U0qfABUyR0^XnyB#uxsY!((r)J}LM?M&3rg{{+M!Ivmj$D|7%IJy|fv963qJ*h+ zVLaEG6@_~vrj067-faim2($ohjEmDl3O8xOqb=O7MStblHk|lZ+}5s_OaUzbxR{)H zesl#j+}BbN{fsXO;yMqnypZWcw!1GPqEY|9Qbamqus(i<=;1U1xQ8MsZ%TR3g$KL4 znS+~flbkxZ0XPYul#>mpMlS1bLojt&e>1fPC#fuS635832Cu@+JE4X){YuP*PopXD zi*m@ovVZP$q7XC|Fut#+skS+YZ}rv`K|{#=95ij!&|I~WAifk4S;o~HEJ1pBsXzW>@}MNv@D7&hMTY2zYA}VCv5>1q;v5N z7xx{csd(lEB~@cH;Lj1>RYMVM9SJe(PB}UqUw;kVxm8Atcu)`&dBzicBi38#zdj$t z)0kM7R2&gESh8;;TO}#OYq?`{rO-WF_m}Ze{w{)yuwKX<=KLnSz_<8*rKzGQKAgq> zlHl(AQ3aBXLeanlj_MA#w2Wl4ZOt5Q7Q4 z&3`rJN~K-OW~I|>=G)!N@olwbYvP(my9&GAg&S?N?SKvPpWwW-Vj5}xsJ#%0YuEbO zjzj}R^h>*oS${uy5nK35r6Iw)RY<4&J;XAR7JMlJRP~nOy4VI`*$CNjC*a4tbY6*o zL}eI}E%E9NkWO>Qe4Y;)$_d=*ml}GQS{#6)D2k#u#9!Xw;lA=cc_9D*002ovPDHLk FV1i`4wNL;6 diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/10'_0_0/00004.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/10'_0_0/00004.png index 44531783a31c4ead6e7755cb6271096b7a1ea2e2..9460013ce93716b48b17b4eb9e72df63bd061835 100644 GIT binary patch delta 500 zcmV8}fKv8BiJIVf+#9rp3DnjOEz(5k+^VJ6s zYKS4!IRF3vV7s50%HI3onhYl`05{}PG-x57KZ)KR2IFNY{V+8 zN+O`417cRW?++}MNy~Tno2i^7rc4~x(APB9qHtwOYRYH79e)_$$>3@j+yQ#Z5QKP@ zZVM5YxV%deOEde0PnzSDmMPsddIke9aQR9VeQV;!hvrpsBx&VQtlGbw1NQgp1+%VayRy#wmg9{}KXt^xX^(`*%SY+#t#ORd>n<*>1b zQo}>X$|XuI?|G26KMn1YJ;ij2=iB-@e%y|j$no3H>+I3q+h}H)I0Y+x+bp1Y(RG!j z4%`7hvu76$PD(kv5=D}m|0&mDd&(#PrW3UwA q1poj5000000000000000miY$-n42&wk#^7k00008}fK+()-cEbLb#9rp3DnjPvfPoO*^VJ6s zY6wv0x&QzGfaQJ$>wE9xx6ZkGNl_sFFk3*`P9N`meCdx;53^-L3*CN4DhDRvaL$>u zqa*?vt}dq3_5F3FGHLl+{zfX7h*=YdHFP(PwJ2Pfm74O|Z-4I&@L+H?Z0-O(We7sN zO1FgwOFZTg5N|DK1e;b-ZeK?b{3ula8hK zD~D9`%VkZ;hU#Tgm{%(!R!`!`jfjaHzx}+Zt$# diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/2'/1/42_0_0/00000.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/2'/1/42_0_0/00000.png index f6ee4a8956a7975a25b4fe925af3f11b06b663bc..024f0601e0fb2f0fe36aff41953e679dfe349f67 100644 GIT binary patch delta 366 zcmV-!0g?WT1BnBWB!5szL_t(|obB3M5`r)cK+)>B6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000}5VuL#g$=fFSOS&R0x8 z$RLCezOJGuilQirqBzdiV*Az_eZ246ugNOVLbU=YXPVX;6(xoD68fgS0&70O_e$eV z%5dEGoi(f=%zD^k=cU#C4_4D^1@dR5u?4dlX;7CoXRNYnaesJy_1|!TB89o+tN#wyYTS;Yx$eDl%4V)&pH1_^|fKrgtrn;a-a$L}1-)+Iv zU_0kCIqiZv&YU6Bi3d(AQPTm#+BgAfhz6QuAK%ccus{~~LcTMR*(4N#^otxaLRN&BsR)+F3bWztH>-ID{Bok#x7LBPEUcjb zJ7t&?@EUZMiVBq*t+|4l?p8gF+FZV!<)9GB6BGGj%YS{q9N~R{97-hJX6-l9!kp&& zl6nuC0L#&_M?5tI_PB42BElau0V#}*CY=M-r|pJMfOKJ(ScXmz$qJq2-+zoo8c6av ztVVIxft-@XJBDCQq})=y3oGJ0*5h2OZ~8|itq!2Cp>Q&vzXC3DXL3f{MPHODt{B1` z>Y9TC1b>5EbFdXTyg@e9KaNgp+H$LZm1KngNIJ+$UJj)YPUEB}S44qX$vNScSgTM~ zY&QufVVSN{AFuHI4P~k?>?}(fU zB~{+=SxUE~$N5>~l(bdP*acbJ<|c)nPj15Q(|@v|>##*2tu5F1k|%)eidOCrk2@!_ zo5%*}i=|FdR%VY@ATXi%UM2#&r=1G%ge$K3fAMYTlc_ym0RPgoD2n2vu(on~;Ff^_ z3!;Z28SqLA%r}6_%!Ox;d_QwD){S58Pk@zIS?OB+7kS~7kkM(2B*9dIC@B3jAqDzf z41Yx(*5QsCrk}EPzDNv}%uP}JP{R7nR-F0>{uu3-p;oYD;;&{k_l5X>G4`GV(!8O- z|2T}A?X*d@g*&pIYYAH=On~)8-`wrQ(0hW4&9$YTEU%-E=X=% zGI5CCDK2(BT7PI0R@wOJb-EQ4DArk~C>)BSD2n2@@fT|rL{CGTSpEP2002ovPDHLk FV1jB9&Wiv5 delta 927 zcmV;Q17Q5Q2ek)~B!7HKL_t(|ob8%ha_k@sM150tC*J>(yqA2qLNR(Y4G6}W=zQ52 z1V-Z3_HiUhk|arzB*}LEO_sl|tG+$Y6Xz5e>O?aGX=jYNB z2;d=Oy!4khEX??=gS3uTFt?OeF;kx|rCZWVi~|N50gCX}L>H7knn(N0oPy?wnSyrC z-2l-Hv3Nd{-BVBj_>6HUzi}GgHSLM2g$^)xX=F&2{%z(L8(DG|!jp+kuPu`cdvYAm zh4TwW$ddE6DSzngM4escjeIPDo1!F1l8E=BiV!kZQxF%|BIh3Xj}s-oHx9tC@VbJm zRNy+`?sTC>H5=EPa|ToHHfI>KxPCitf?_NWIPzx6_kVyfu)cp-UCGF8-g=`W3>05? zo_LT0yopZSG7~O2>_{IB!x(>%148KS&Dsa%oVFV206m2rY8Zk|q(}tAzg+b0G#K%@ znXLwl1MQN@Zw!qw!SClDh_~b1R^wQyulhl1dmFIF5c%EX;anAas*5c9E4uhIaJxEv zuz^M=r+*KYqPw@DhT`Msz@n{}`a30R3&6-ho_N_MA?yaolQX7BRdUR@XVyzJ8@8H& zldzVn%-f^?425;a<8@2dW!x;K2cjNN<_IHOJ`N6l5ID_X4^Q+O&}{Hk$?uGvfkv9V z;kT3$M~|Clom0}%cDAP=Z`oYbpyv}S*nOHBI)9HC1UlMcgD=UBH(%+u6q}8>P zAwOx6dIQ;*vF#bKkCmJ5nm{6UfTybr*XuoHUN~gS2+A@dmlzs@GW`KtW=Z|m>E2qWEG$|Hi91s)}8|*XTw+U&tY}g z4u|A5@r|r#EzME^4)Ffy8~ZxZ^`2zI#>&=>F@KE?X=h3i2z~U88o`ByQ;=S`v~b9O zQ=F{2H-Fb6Y_jmz>+mQ@SiG}Lk|arzBpAtW;~SPyN(ECT6TAQb002ovPDHLkV1nLn By^jC@ diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/2'/1/42_0_0/00003.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/2'/1/42_0_0/00003.png index 5a41bfd00461e885cc8a7f6cf9bfdbdf6f94830a..9a441e9e2e3685cc2994fb0659fa8ae5446eff9f 100644 GIT binary patch delta 961 zcmV;y13vuN2iFIXB!8YsL_t(|ob8)imgFD^hMhURliL51+{--VbPmP!S4m9O@I7@U z2t);yq+2VBq9}@@D2m(pv(mWtPJg~$FJF=g(2J@7sArnq`>E=D7RyQcu(Z{pGk;ea zGjA4^WOXYD?NB)tm~ZXZLn$NWhxl1(tiq-Y?N)1+H8Hi->3@dHt9P9Nwr(wUEC z;DB@d>@O=USieyDM$*D@J3)yXNCK%551~WnG%U6qB?Wd`Ko8iY0p6n700heyD`X94r42pwoS*U1XC)XHU%4+w@_Wd18(*FsX z9?yG&g%*|iFgB`mT(*VY(sP0`XVZ{wQJFm=VbNd9Quz&0Iu;wt;_fK(#24zReeJ1 z-2)Xkly|L&BJF}fV7&|&oe)7WPR$96K`LEjUw<|G&U_F^N6nO@7fWofUvkwZa;GOj z1R#FkYbKi!G!L-mYPOkXBGt$$CcP!=(zy>DW1BdRvFt22g1$~ouTh~yN0)hiQf=}%wb=!s++P)SyYn7bfa zG=H`R)~|$spNgo58Za#I;}4ZY^jk7u%}So7XMzKdfUwSPH9W6`VFAkc4}vuDWtczI zD>`LWg(@F&4p6_;be;{DWUWSPy=-_!SIYeZFcjS^w2{mfN=i?rnJ5+S9{`onuQ1p3 zTh+QzALtk$g8@}TosAd$IRSOipFYx-Tsq{fGBUUw74m1MhHmDe jYrq4kB5P3;MUl)u1yqL~QA48F00000NkvXXu0mjfuZYh{ delta 962 zcmV;z13moL2iOOYB!8btL_t(|ob8)ia_b-rhB=+H6YqaX?4=KxGKy~e2#lRr-&0LM z5=h)+x0EDFk|arzB-zft$@aBY`gk0NUz1g!g=z&*PK;V>lhZn4Sx9?ITTNQ>Gt;=S zWH^rFSRx064ycR+W>_;%){*sx_&?Lwf<+A-Rx8ko2yHdu@PGR1ua<+Y^2xzPSTh4~ zz!-1iWlak*O}ptbSs)@KJ8a21kkSNnr* z8%&Yh0~Vf%zkd_QACnu#Dj}CGL6@^CY%}~#mc)3HB*}BB?-U~kFe-D#3|6>YkyJV) ze|~&CgRDQoGQ({VAu|pL%a>8&3yGv6)HEkmrlvoOxWA|+ zONvMtsh7|Q>fA5F&!sn4<_oPlYZcKyEER|-d?xj0z<?^T$zHWUV?f@BUaw(+mgW99Ip)H&x{%(nHr%Tj<$nJNh@~KP8 zw)JX;4Mv(O&enZ%2XwD>Yjpud8?-){YkZKrxNH?lN_UXc2dA=Nc%_K?j#blt1Xbf& zSW18ik$;6a*Ih<8=9H3@#3*5b-7`Hx(>gu{=-;!5l_43>`eqaXRLK|vozP@KKhO(_{C#}~H z?bny&swGjRQg9Mj?*m4o0Zm74(OAAfw-M>xnR1wYK1%(DG`cFv94nc{ZX zX-0nrAg17ZCJPF>6tL#%Y7--{)G!~g4$9Q@LThiqd;s2ICLuic+t8cvg>S?@CH9jf zNiGNaPkDJ<3tYt5(kxGbzD(qtCsmBv<_ov-R7kR9_;~81eASYGSo-J-9KDN#i7A>< zt$&|_Xu8;Pou38)zY|e!G~l$r?>@99A|EeQ>jb8VXLRZLyqjdV8n%+|v;gb)9YLBP zl`Db%gh-Qo#yvp&Qq$=bUX!&#;#3tI-X<@00NvS;3^15V!Z diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/2'/1/42_0_0/00004.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/44'/1'/2'/1/42_0_0/00004.png index f497f8005629d357793a9b3edb73f43e804a4d56..9ac39103a5d4ed2ecf7057d055a80045ff884cfe 100644 GIT binary patch delta 471 zcmV;|0Vw|21MvfpB!9R`L_t(|obB0LZp0uAKv7zCC)xj!*h@dEB4qRMUlX@8T?KxSD#@WfN zuo{VgrU8gq75;Cq)<(Dg$dBjbA~9w1u%@xJ!Oq}XOn3t9j3G$z zsy!AWE_wT)3QM>8r6b)u={B{8#%@9a1}@(?#on8^`4pWoy1eLoG|JSl2_@*}+Fc`t zAzquuy0ru)jhtE1X=V$Q{s4e*!aG3h9O%8H6-C^>kGtCZ&A3l( zxp}c`w9)%Ja7(4kw?06BY(FdhMw98`_m>`>l1tyQQSAzEJ3C?}_Sob`A7x2?)g@?V9_} zA99UXS=#@YQ*!W5$5o+M=>(Y^EJb($000000000000000004kxegQm5XC9=|CLI6( N002ovPDHLkV1j^i>#qO+ delta 447 zcmV;w0YLuo1K9(RB!8euL_t(|obB0Bl7k=&fML6{H{t$A;x7BpS%xNnsYH$Xe^0HA z3IQWSmjwU-065%h^8B20{WYaDjuZj)!DfK*I@{!&>s!C|TG)&!SJ>=l=H$X99VsQ3 z>llfImb;57wfy(47o+39@;h^KkC-)eT1#_vu0`-*R$Ahlzkhx^z>~?f@Oc94j43Gj z>OB@BHFf-=YD;e(h$E|mq+@yyjh)W`Y-qvY6#Lag|4V{4(B(ys$DmAY=2L=>tla~m z8RE?u)6pfU7>t=^IPD9knN`yP6Klr-XfDx=Q?lfDHC`-aja8^wyY!k^+(^Fz9M{D6 zG#HPW7lz|SPJb&wr}LV&O#d#IISv3fHoF_@!m?H1d#~d3SLiOAagmA5qSIYq0D2qo z^^rQEmR){)sP`=OR}nV;uzIlh^+XqY0>%fgD9`{j|G+6fEjKMG&)td$LOua;mIpPx zcGQ1ujw@A=POYT(Hih*qW_P-+irL&5VSChQSlG7Ch&bG-r;I^N52``|tt6Q-*cIso p0000000000000000001X^9M98R^jTyv)2Fs002ovPDHLkV1iY3)Vlxx diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/48'/1'/4'/1'/0/7_0_0/00000.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/48'/1'/4'/1'/0/7_0_0/00000.png index f6ee4a8956a7975a25b4fe925af3f11b06b663bc..024f0601e0fb2f0fe36aff41953e679dfe349f67 100644 GIT binary patch delta 366 zcmV-!0g?WT1BnBWB!5szL_t(|obB3M5`r)cK+)>B6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000{AFllQ=Q4~c{6h*O}e~b0c^BjL3$6-qnfw52&0QH19&vR78mG_eINxJ~49^hxC zawlatj^oH0RuJMnqs-v=lKZZ7FR6qw=~USx!Y~G zIqezw^SX_qeOj+2W^cp``>tr1*cg%iXiDr>G;Lr9tYzrvTut{f?Rv@u&gH~9*b2Ew zX`MeTuFc8?UAYvJjp|L>ZA=|ma2YX`JxV4T%ut0iH-Fv=^y-%LfLXYu0|VV1P&|HU zuUw{R*EjMA12oA70S#c`2np7EBH_qW4A49qkh?L1@rfl)yR7CAr~!C0TyzS_1yYhVZzLxN4s1=c&MXbp$V||AuR7W(H0TKz?phzJeg^G2Y zK`tBI3V$D7^+ZftGES`yxe{%e+hxekzF}Dnz7RA@kp7dA8auCT+C?StWwf1N1Sbj? zGb)O$B(^v;xwRzYluo3@)kArbBArcwrZgH>;$CZ2u6e*GtER-znUIR$Awql}_wy+* z@u@vF5*x?P^kBmOPW8OYARXpd2EY>!cF(5d!+*FBuX(Gjkn5bnt!ss#%T0Jm`j{@g zthTG|nh)UHQ&+}+2O!PllAHJh8%oKClNZBSuGN}*2TX-Ut;*DLkRv{i9W9MiF4A*e zz9CKh8GOOE@lSjk`ee!gMNt%g7wG>3kd+pmxtwZ(Cm6&$<*cxl>`W2H^AHd{%jU|s zVt3v{tOU@V7tVG-Rja9LS8rbg&OM z+iM){cL0*A1WR}-)G(wiY_Gd)&4w^(^gR83W~>D@fw1N*;hlVNGH&XmX#cSi$nF0r lFRn43HA#!2D2n1O`~r6YP@u4Hmj?g<002ovPDHLkV1j$W)OG*> delta 952 zcmV;p14sPX2hInOB!87jL_t(|ob8-j(%T>mg=wcd@&1?Oz4XBohSBvPy~ z{ezU@*tRXj4+xn$`rsnu ztNmW4Qf$4NTQRwK9cULmQE*Wx{yB_{xZP8d~iZ)6Di7_Gx&CZ?cua#GNh zx!ZtrgKVD9<6F)eGPfgd%suKesp3=Z6*~izlCkI(D3)#tpmye#ojlF2i z4B`5Qk+S97mVbh7C+ps2-O1OIcql50q9`WN)Rhs@n0y}Za>ergljd10ce`ygXIvmL z$k~BnUJ!YUU#%Dk@xyFgu+N$kyE)Mn*t&BJ9Vb`QXPNeSY8LDn@;cHA`LNzPzf#euObqH*A^k=vJWcR+7@KC4~r|wgJne{s?p*rZX0+2;K2E{r{S*TdV8RUw=sqo=d z-woByi+@u`L+*s1!-x&Jvu~KB!4HB)3DSQuQe)?}J9g1Y{0wc2i{VY%s3^9Q*y7aU z))dAmpGb?V59NtII;()DG#Yl|e%7iS>wqs-&57YNL5kohLcAXL^(j#G)Giyzjbmqe zGU0!xdfsi24s)yk;Hrb&vnl&9?!{}f)pp2zPJiLnwNlVAO?XNAm@aKrm%HtrH{jh< z*T&xikY;kpRXxFmQp9kwF^uI}t+_p5DlKYNrjCOg@p|lRY3R5}&w2UT8ue@Vg4@R5 zeK+(WQ~-*iD1H~{U& zUW=S}uX}O4HT)GI4#9el5&3>rKz<{B08Sc(m!|A=oCh-FFm3Fu&Gs2bdk;XQO0a}W zp++EWWBc4?dp3+oqxa7<<1DBdggs{&Uopvx#ki>_Mb|%80$Ke(<6Oiu#TnB!8|+L_t(|ob8)iaw8!OMVYDDiTA%G_A(z`p@<%r3!-Vq(fLTl zG)O|w0)$;kk|arzBuSDS=TD?@t+oI7dcAN>QK2t1E0A)QskJsytuLODeP{btL1X?# z8VhTJLUy^8q<5&E3c|MXWudO4>re47(%3{yncl75EGuein}5@duWvpD1MEEtI+tO? z8^A-(@#Zh@wGe*k>z6JpT;;>)$5U$+4ZW9!XTtz2s0U4WX`=JZJIf5;8#4q2*${#b z$8HZ{hFCU-9Edh1M?+9!Asp*EOcA&5FMJfz;j8`A zuN*>`UIXIW;(yRN;LQP>uCl{-TZB9lf==RjXIFR$%K6wg08jrUNsxSP&g^hx7j)S$l|wW&@paRD_G6dniFopO% zSUiY{AvMQ56am9v3$Ler!cLd8hUU;-FjsiE&PoVk6o2;dXDYjg-8KCNtc0_#h6}BF zL}x(XmW>2@Z)z^zfNI@S7y4#Vt85pleNdXZ0%R6p-5l%E*OulTs@WqG-DS^0)RAYS z_AkM8a({aN7>29U`-jOfc#@1lPcm?Fj=`;H_o5pyZyRdXWOkN#gR65vTC!KJ#SU%u z>hl`C=D2Gs3||XSVK#H(Jq2}0BN+<|mjq?>lJ<;G!g@wDu*x-$>^;PKW67VYwwocC z%LRGo-h%1(-HqIeeNHbJur6JfMA`CchpGn4z2LNB|^!@aDsOvL`b;V02o544j72gH34n>o3 zSh|_=G?So@a5<&22ADiGPfEQV)JZ1RfQGkZ>8OpbVtQ#_+I4tcW1^eK zmsxXfDoVB}`h4EXL7)Fi`8OvAAW4!WNgm=q!ZLLstL`nK00000NkvXXu0mjfRHxQb delta 971 zcmV;+12p{S2jK^hB!8$$L_t(|ob8)ilH4E+MLntP#QR?od&!3@Dq4@rq$Yo6 z8VgIzah~TAIV80~tsf}GL_J%_*6-r)OydaUHMLnIM>~vbyMG?X*LR;r6C9OK8kb?s z3g97qTldK6r zJ7YIMsiAgG%!X*=vO5F`V9uE73| z+lK1M?g0zW#DAX&n2*T~W0jD{LeS%^a@%zOkR?8zBuVm(lvixI{8X(NfvS+yCu)Ty zL>k(zu~^lRKOzs(w5)rG2GW28QVrL3Wbb2tM7@(kUdyI81e^wIcs;GNb+$wrx>I|>yuZVBMnVwN@n_!;`O!6lSoaDT31|Ns4z#LKg8^e3 zRuc4kQ**rniua!SpkFK6F6D)49hACW0WzDgZI1i0?=0OHsP2ed?2sc3(LkP!+FwFw zi zuepISJ2HW#3sK4bJ1mod@1i{c^Xj^Hbhps8j(^*V>2ceefEgMgXo(W?O{*<*%a^3> zCMC?!WwgZ~W=Ya*#cDr0VoD}?DBlNja7-4T zf?Vlu;SRr(*$J>ml$;D9gF%ucZ%#)x^a#?KN1O;exQzj4Ox+`?n^drA5`II9QY>Am z(0}HmZYJ}B%_c|i2^TJj#Nxy%z|{fE;nTF3yS@#LaGib6!6~{%$zs}|gQfc>JXtvk zV#EEqa_mPwQG@~a?LEo3_5`?N5bAM8BeeAy)V>lWlilDunH66Jvk%QC@9t zAK@~PYyjlS;9(@}-UD2o^3&)9wUdrLKtzbPEE~1)tC(6^lyhyqu5q!==eJq+Y^q9@ tboBYWm4UwZf6BiJIRQzMBuVlR{{V2sde_xAy$k>V002ovPDHLkV1n^+)QkWC diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/48'/1'/4'/1'/0/7_0_0/00004.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/48'/1'/4'/1'/0/7_0_0/00004.png index 82e479d2223ea535f80166141a79e81f932372b9..bbf5a2c3b44481bf0a5918b4dd99afd85ddb28e2 100644 GIT binary patch delta 504 zcmVF1DMQNuy$^MtbUi#rF!$<;To=$qsS4)IU zu0SYq2mk;8007(h8krnp%>RA8UUf@hkPn&$PCwnm81tuJlon~)BoEzuk4zS;8FVsB zRwqKxv;eWI!rvDx*=YM){ESRC5nCpgHLX=^EsQH$(qnIa+J6z?L2*4yI01f~5+uD! z$3p0m+Xt0cn%OUnG~=XgN{7bJgaC9rzB0w{O?>&JP9HkG=y+7pR5ue+(B|A-LM%gE zn~!B{3QAOB<_V|2a2l+dHtelc0Wj+`=ax+RHnWN-Wc^vlOkcVz7SGamz<60a^gH0; zREn-JL%S(X&VQt!os`s>m0kw@eC!FRZ+`#)2z%~;Qq#0qs+z4Hb6j^CM4Lerm!-O> z*&Ka8%!0ZyV*cG6yk+Je-0)j^emB(5wc{!+v%B7MKW00&GVv5A18{LE<(H|{-*)=Z zZcB-7{AG)W^8wJ9TAMdVUvF}cvQC~DfGO(aH>!CdJ8`G4=JQ(-Igi@=7xDy5U!v~I z_qE1!o^ihQ6nBF#*!Y=8Demf!&&H`(-4^$ECqQ1 u0000000000000000000000000mhlTlMx6bha?e`;0000F1DKvCN1PT2pFyqA7>$}mC#nP-~Z^VK>s zaU_fxIRpRz0ARbX!Sk={%Kwcq)+0qgeozf?j??G5uKcTS))lHTX@qXyBPS?BrNZB@vtr8lM}9_5wuo7ir!`$}nQIYTnU$V+^?%c+1s+VU$DBLB&zXXh zFYC4tsmbF*v9?(AKpbfnsf@918oxOO=(vK)DgM#K?@tNpP%bZJJu1sow>eAD&b7Nj zT!wgZzNXzvP*SOxr=0$c)5xxA!^B!x0CkJzoRTTO&3Lhqb*@6{+Ewm}#TS*&fQftJ z_f)CJ$OB{IAb-b}pyOsuTc*Eh${YuPH#XW0^{_go&3&rc=TVQBElkm75SvS@z0qur z{y*x5x^hJQyLs?YnE&90XZVtCsM9^;tbSR?X!$s5FSc^xDJKhXyEElalhxdIj#Cb6 zEp#2DbvR#ulA3Gv$=?SS1iEv*Ny4}*?IbEpJ&yIc&WL6lXt-MODvo6p7)DZ zfI4#hm8W<%h=9%S3>xWOeJONiLL~`%vO^7mngsH)88tZR@GA7-8cC)GOOajx00000 k0000000000003Z_UrFtvvm284-~a#s07*qoM6N<$f;5izGXMYp diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/49'/1'/1'/1/3_0_0/00000.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/49'/1'/1'/1/3_0_0/00000.png index f6ee4a8956a7975a25b4fe925af3f11b06b663bc..024f0601e0fb2f0fe36aff41953e679dfe349f67 100644 GIT binary patch delta 366 zcmV-!0g?WT1BnBWB!5szL_t(|obB3M5`r)cK+)>B6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000@$i(UBe0AF( zWDqi3+*(l-MNt$*Q5@%EvwrV={(D`QU6K@-FNy^~J7Ie7vng(TT$!JA6d=_DeC|{p zq;$u1U0K}9og;J(RX6)JZ2tA$c`feD5;+49@W7~oTO-duIw%D`Y+?%9Bqs$O&fOZs z4f5uECZ|)-z!)=RIPrzk&Z_A^VBI(X;t~xE$hC-Q?C>v&qA2p;0m$l8REPMjn;Zk3A*u#3B~}!L zsTO{y*ftVTwPx`k(1hKVTi9?$T>gt!L_rjkS7%fyg2-5|8cu$blB;M^=xo{cFy;fk z3C}_ufY&n+DeCpZJ%va)ui!>V4naITqXmh=JIF2P0e>-YVdrV^5W#uS03hP!`)#TI zgcN~ueumK*(Dg%V@wH~JdF&NlTa@g@S8FW!8qR1(ku=#x6* z?P$G>Xn&3104!ZW`sWrF@Ffw01R5=^pa_7m%&wSGTSw0VNvrzar zkS7r1;gKf9GUVc_tFcFmld@t-H}y``fy`40zX@+ORTM>0B(nT%sId;~-p7|nUEBw; zJlRrcZoAEic8qp;6KQB7j9t?GOK#zBY1{`0ISor_| N002ovPDHLkV1mG3!Oj2x delta 937 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 diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/49'/1'/1'/1/3_0_0/00004.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/49'/1'/1'/1/3_0_0/00004.png index dd175d24f6ee3e71908c16a8c909d586d2f0971a..fac83d5c2ad0574cdcf9c59418bea7b61cbfff54 100644 GIT binary patch delta 498 zcmVF1DMQNuy@&1>@Ui#rF!w3Wl;^BJE`AQst z$(4|W90C9U006*tzC43tjQQ8=y4se)Air2OFwQefj4{9ajkd_DO`2htZ_i+{8s{Xl zWHllLO$!iF75@I9W>eaK#E)li6%jJItZA*K*21_Ek{0{wuYUs$c8Y6Z!Va)wlpyJ) zZ404GZXb%o(#?M9O4m=Njkam*OmM)!?Hfbvvxz^S)ET2pFQq>kX=<1WDQI)<))31O zkIl!jH3cOaKC`&fUN||crVX*R$^q5-%ovhM-)>eBg{(abRnu2l7K?k8&j5c}>^cWL zoJP?VW@tBMl7BNPXeXLFv(k%mp4aYxcK8DTKsfRY5EbhEb*!yej?x;mmNr9m;5!k= z{ov?lSQ?X-$xj`dmzSZ{#+hcBpQJQpKUFIEsXTUdPkGM%(o@hh?Mj@-xEAjNJD_o| z#;8RcJBay@py@qHRjGmCHSUbL%zq)XjkZh!-OwWs-fJBWsJAKZp8pP@Bk#jk{|;1;M1&07*qoM6N<$f?Ad1`Tzg` delta 491 zcmV1cd~UB!A3FL_t(|obB0da)clZfMK`On{fXlahLvZ$}oY%$fxVP&#&$l z&`lyD9tQvb0I=Mrvww^+{}@8BTZ#txm(>Q&aoWTf^FyDsGpx2rBQ*Qz>6{D+M+jla zI8Gv<>FA=Qj{je$wJF=*^4rr{BdR73YdYOB)}padm7ez1|9{?1aA$Bm##{k@&Jd({ zX_tivP2T<}<`%6E#5b2oD%)rmjo+9AG@OCa#Xp+({V6~V%IT%dhcQhx8#4v1oVyL; zG{l|rnO09hiIFo;I{gc$o>kL=!kUJrUak}1BI?ZraYISW*>qT>aLmAGGDi7k-ZzKl&A8s%O1-ASod^VOfN&6*SJ>i4Of71ETh*X zPuvUgNVC7Tx*-ph+joZmeE1;9mkAAa`lpaz-fFH;FM(O--l?8Gdz(?yWU!Bm770000000000 h000000001(<_{92xs8lYb*}&b002ovPDHLkV1m8*_hB6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000@Ui#n(Lv{T@z#*x=hfM5) zge(C@!lfihk|arzB*}4p1?6k4{pIsKc1zNrzbQ5V^-NQ1?NxE*?N0xstpO3A;CDp0 zvBVwE^Q>|!2pK)(vhiB=d_h`jQXqdK!Wv}M@Bvk%n32Zfh=0S|i@&-P6uG&UH8TJQ z9OKPj+O!Y{Z$Co&q3W)F1)G1hRxZVj8DdQUCM+;SaBbxIn}e3X!zM04LDnomhu3Zm zVg`A0-pT1DsA0qm2`9dBitL&W46Ka-5VvUHkZk^SR~536#aAJFG2!=n<@meZC7K6Z zjqhR;4cy@t-^c?BSmzNs{bBE3Nb(KlPVj?Tjd#kkyoE8o13v zz4%6~lG423ZpMv&z}_bU;IYJ_bpg&?=M!ah#kn*a~;AePM1ZOHdtZZD$FNO?+Ny3}Ln0Xubzn*Duy&u3JSa8tPw zTj%F%L1aQ08B+-imUrkO1tKHObPW)DF|uE9#zO(Hb6R_9liCh%h7^Hq+llmELA9V(6e9zc+-#S@H#sTJL{t%We5@$y#D4>}ehFIgkVA=Kzt9Kg(`YYRd%WxG z&I4YI^8m3~fggKfe7LUhVZQznd?Yb^R=QvgOs)v`?3PCdYU zM1RbWMDeN@--C%8*ssBm)S3W@>8ogp(Z;BxR^{lU07Z*FR7Affg7muzGytwc32u4B z@QZ7S`%M^bB(7(N_Y3}M;ypDD@l@o1c{@tk<(qyR3i{$%@$KeBzsp|2Mt|f@HBnRK z?*Og@)VX6|x@g-3awK)n$}!AG+XDBMQx`$$^Mt*Uiy)#;{aZ-N{sW$`RMc| zhy;uxCZ!+3gnXO5h6tw(DvSL(+s0;2gG-;3>U zT-vTsZYfqVQ=e|7Eg8ip024-lCcHM`g5slfbj-{tXdRy^Xy@Dw z5N3$Q^GtS6K?M*qCY*fYG@Ui=8C4Gkz|7LfAzA#}l^2ODISb**L|?BplM8#05)9$` zg5k2{yfy{Bj(^wQWnIa~;+PZ#K@fZ-tJP2elX{w^A#qD2m!e6x<~rB5r9|AqX{e}z z=tpCjTfUg8R$V#3O29v4?_|kyNXD#uU{irkyA&a6Slw#49vA816s=n;#cjJ!(duqr z-q{Kuj&S!PxZc&qn1qMC(5(ORN=#K+Pd62Q!=V~RrNz~{Gkx)-qH_1p=!3@S!|UPV1ei!sG1Yz8P7 zGaq-7JK>$*I#9KsQXQ)!asOOgv_(N?MU}u^VSh^}9u{32mWpvMBPIXQ6-(74i5b~z z%z|E8@}O(Rs`t+Wz!`ukmS~Spyae4|++VD*H9%ik8G7Og7wftvV%l^uTf{)=!i86|KA7r$CS!RQ->cDGymQCv5uSp#Wh2 zl7D;YnVm4+&X9W?bAMzu&+X#-;>L~a7XVt3h7AY6+`i)ew2XeX?$JjgiWYUKg#K0& zrr$?#s0DR5-@q>z?UWTGc|F^_pAP>t(L5E|;F_KFoTCGfXkT2e-)r*yuE(iA1&Nhv zqNb?V0Ih`7`AVU&l_rQIsh#I&&iv>4?IP(@(8m)22!bF8f|vLO+_E>C*^Ehy00000 LNkvXXu0mjfNtDPW diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/84'/1'/2'/0/10_0_0/00003.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/84'/1'/2'/0/10_0_0/00003.png index 5d1f60c03f078366e2af817933c797694ff865f4..6fc974a5999e95d21fbf6c6e60c167ffb65a26bb 100644 GIT binary patch delta 982 zcmV;{11bFU2lNM!EPq^Ea^xTkB&og0-2X`2B_FP(h@LG0b}~_ac^MFTA>^LPwpJ(< z3WY+UP$=AvkCnx}_xYc%*UO$sCd`B41W-;Iz4sw%*rF*p8#}LBROWMKG0|pG$S${n zm>tSff#}x$YslyD`62vUSuBF2%~ zZm2dQZY@CriE_;6AY~+4YIqdEg=w4$fY_gbSvLIZRu$5{;8lp1ukkS79Aqzk2duZn zOYZ?c97faCc7OP8i;!nZ(4Ek{v#Y!;%6Z!pV5fhfP$(3ddk1KIPL#BnCuj^JmrVBE zUd_dOf)Az@!`Wg>Kau(458|$3V=lJpuH>U{s)#un=dnnuSX4wJ<2e6iAB$X4Yf0*k z*hdh@#dC-RAKBE!1}0L z!2rt|*HfdW3FX<8=#pvtG7#+|k_ln~$OU;jxFzW%*n78gvf34XoQilhR5LDL&ouR- z_oIxr2zml+ouYl)r6O|WhDxngri~HMBCdw57>R)!4=3b5CtKebs*}t6w?S}qdH-fq z44y<)p?@dgIJshQ6x_WQ8!D1{NP8!~iMR_zcEu$c#Wzw=H&7Y!OctJ?X=Po-k#h?} zETchZf)WscC(6TSGA^+SS?F$|ad}9d8V3l;ZcYU@RxJ$W^JE;SsNADUMnF473pXD8 zxrn*mw^M>X~a& z{v6Vwigv&RRe~PI{=X6Xbx3zpMcWh#g||ij4sDJ$LRJ|P_)Kk~D8$y#)mb#bB@)iGQE%;MIoe)49$fyM&R`_)H+Im#RcI9xIiYST#~<9nO_q@23lFR#_Z3@%mDZyWK)TB+HuPas01Aadp-^}TUv*-ZGgQ}}NdN!<07*qoM6N<$ Eg33MHCjbBd delta 982 zcmV;{11bFU2lNM!EPq>DawQ=Mb*5$~z5gY-m-*<#vUnbme$>63FJll95cPD@TA@%V z6bgkxp>R9?Y>w}}&p#f=VM`K$xlyG#$$w)d=y7DFZKc18lpHS<3WX1b!-mHAnOQ*N3%O=O6{H_-A`Qhm!-jEU z7^jLIi+MwwRXp^>W6;%n>EVeiN252E7!+g`TT}$6y6kNcOKL4i-5z@j;y80z{7yh7 z4PZF{^HN32IJi@6rkYI0U#(hCTX#2!oM@Q4D115&Cw~B3d+w*G*<{5pxHM?21b?iZ4>oHqaR3BEIyJ*rh_b3S2BOFvc>5EkqQi6a!bu z78w__!yV{Op>cT#C1-3PH^Dg%*rv@vEHw1YK*>112kkdA?*Z2-E;5nBnTwd~eIpgf zz%U)_1V9Y0Van>j(_EWqoK+=KX__(G)CdBJ@_)v^3p##5I!BumZCUf)e+hhJ0ItR$ z4aLF|jzO$WI^P2{vaosOeu?blpFU=V#yLcWr{wR@X|F;wGIm4xM#Mt3di_Q4jV0(+ zxa5Dt-i+97su-F=q44dnNil@R>c1d8;y_Ue*RW)>xCEC>>=W#{#MLbs>_Bu7xdJ!c zcYj)s(LgL>2yxCbl!FJ5ap^ael_&CJiG3PZEt9LcSJ|oByakpVL2B6Nf;ZN2jM2sV5@bV4_yT;&FMQ!3l{JiDtDW{aX zM7VOkQxg;C6|V+6SC7I15^q_>hCYl6K%r156bcXFKd3UABJfNwqW}N^07*qoM6N<$ Ef|%6GYybcN diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/84'/1'/2'/0/10_0_0/00004.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/84'/1'/2'/0/10_0_0/00004.png index 1676c3c5ddb30d711eb659c599b105ba4d58e5fc..98137f1dd3cde824ccd0dc162ba2b62b9f8f0166 100644 GIT binary patch delta 458 zcmV;*0X6>41LOmcB!8<(L_t(|obB0Lj>8}fKv6oHon-$@VlVSi4MMg77YLyAp074_ z9<{-xNeBP{0Kjsuk)30V`P=Kd>X9NK-)IInkJBy2n4kTvbdhFEIzqRfk)6fW3?5`w zTAf5f(*=l875=|qDMrVC;%iwVyI|J&&9{_NKn8~;3nDkn_$ivLHrR^u!zY40{ z^C`u5oW)G~36+$9fH5wckv_Kg1TshN6~ z*x*6IIRF3vV7s5e^Fs*fNAG<-QUs(2vjN8I^a&xPxBgRl!fZ^uLbun*$94(}H&P?h5f3 z;>~%d-7P4p)XY*&`@(5t)wE$?Ei6EGiDn#8cm0Kg8qWv55-t^%xZ`A>37He^O*w{afq`7^-XJqhFtSk!sv z(%ZSs{Yw#ZYLYe5d+jiJl46p{{x+FZll{%8!AW$XlPwxarUpxqUH||90000000000 e00000V3{`sq(B6ZXHP?8OgeI+?z}SWJWWd^k|3 zl=K0$rUU>00000000000mw9*>z)nQ+_O@+~CHY3k3ecg~B347Z3dqsd;cg~|@boT# zQ4#2HagRzw^!PL04Iyd|fSX=3kJ$WE+#XQGI%4Q|@!oYh0oNPN~P4S%ZvaJz%Z3f?p{fPR*l+(f{Kfkgt??)9_Jw zsqsG~4$mx{zYDMXUCU}6(N>w?!F05iR2?y>m?zdfLcwa3s${@#KDuYaMN@Hi0@5ido(Ex)7X zeNYGXr~^wx-xATcMD%Y#GV1JUduh?SR~#fx%dl6o{qiRllbab=fG+zgFGZf_T&`Xc zsb{J&C4Q!q{7_6UGWHf*nls^is#$FJ3V-sn!I{PU_S)(0v^6!mcCWvWPab4cU$jn~ zjzxL9QGZE~rfCQKp}JA88keYmQ|fVM)gYr;57_Ii;8%)=Q}d`|^#8aAq${P}Fnm;A zYWxq0>6wLe7t>p?y5GI*))95(@wy~=8$5&;I5}_u0000000000z``55xF7)3dO>~w O0000N z=PTI$x~~4~d7gGnQlT#tD}Z*Uxvr}>#f`U;{z+Q}(tLtHk;aXb;W*DTYgj?Z>>*zp zw^!$XNKLI3$lpj~4Ki!^ggT^{k;>wX!|RKGbr&d7m`lzIz<&YfcpEQmS%{OjpP~I! zb$7o5TYuMe@mAcKA#wsR;epWvw?>}74NwX^Y~mIaBxeiSymxC5H^|BPPIhlW4I^eq zIPt_Ok~M9ZSPKInrfA@lY~$vk}Y4EMAup4DD%7MB_}N45fx#e58kIH6sr2;vNK#b7CXc$cW5Jm&+Y#J)0~FB;Mf@dT7t5iLmU zMYFIKQGa)IOUR!_lWXy-E2Dz$AxbLPH3w2dZ~CiUmgLE&r12I(lVdm2%XYjRDeUpJ zATDb5agGboL!zVTj{)cj?(opwf>d52#-;y&a zDaP&RM-2T9_?oP*pKu1a9T4ZZHp%CLsE=j|zkh}&8k)R{JGM@3O{RY^H{1IJ9{3NL z&m3rthkqOThP=KgisEBY&j2nhfEoao65D4(t8fKK+lSn%98X@2bXLo-hXi2DkK?=e zXXh|n%N&wIZ6n)KST1&I@~7rini{H+J^^tt&b31t+Dq_Iu9ILd@nz=+pcg@nUsVpd zyMOfFD0i&*oF%qgz&i@LvI;T$X<2=vN4!7J}#@p;2$nZ7(1jk>bgyT4l6gwbf>X5IU z%cbK#q^C9t=WlSl2$?v1PBkfKq_a5b@c!aowFHZCj0YDXXMY9YfOEXZOIsG={2eFh zI9rXqrF(^JeS8%6WR{!+EI45d!L5-H^ccnAITN>_I5}I;oqM+daf2M5@8s?+sAJ>| zNhe-7EmuwV%&LtE5UVtBO7{4={YfDU?n3rv!rMp7;K5$BW~MNHV5A&5k8MGZllANp zH}Y#qEQ*SvD1Uw>Q8iQpsX;Yakq8N-za~sJQ*7X)+##UzMz@?JdhHxT+|qD}&?pc75Xb!)a~iz!^9 z?rmIRlrzWeZnQ(%jY|jp-|{|S0r8!IhH++S!HP#p^MAx>MApPx5`crOCme9~*cO_8 z$h&;56k&5ECX#GW45ur=C?82;-A%*oxqNTLGBS(zRRmLenv>CZ5mvaUF+_q}2}nT* zBN*9AKo;vcDB^^6p(2PAzoFdfNqjN!Sc9p0UW^NBUU$;ZCvs4U{x6Dg_wyq{ ze*wNG8~Z1m0qzBeb6lI`b3xQcvxHy66AevX#eW^!r?w_D-k4kMeF6{shse z5@<)mN&pe_#IM9ftqhp*IAY<)Jx-^s0J1suY$0-~ZGm6QP%C$zH~fzHM7eMO%(_g9 z9kDij|3UKn8?g^({W+i|y-E#Q=q$WNDI1ESD2gZf2d2o{jIzy_;s5{u07*qoM6N<$ Ef~H5u`2YX_ diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/86'/1'/4'/1/12_0_0/00003.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/86'/1'/4'/1/12_0_0/00003.png index 61c42641553a5c82a7f4c180bfb9a470444b3187..18383665ef26d3f0f2fe0a19ad65bfcbe99564d2 100644 GIT binary patch delta 972 zcmV;-12g>J2jT~iB!8(%L_t(|ob6gmvKt``B&poQ_dgPM$-)(i=-Yq*`;B_#VFVHq z2+`wG5{X12kw_#GiR1XS(z({!KfYcsTapO$jiLZJ&NOPRZKyUE&B%VTeXm7hey?;U z)+`PZ4R_y&DQFP^Dd=$S z)E5;*306hdw;-(!zj8+gzrKIxs!rULi0{kdRZLj$L;`o`6m*IM4}u!141&gTh$m; zlGqY^Ja9gW@L<4cDT%l~fiJ-Y-x1 zW7dab_><%!CbkY}1EDR49!d9J7m?&_F~YVU=E()vY4rMea1q0+*HS$q$i~wOI#^<0PiqE#iDdbwqdobM(&i2u82I1tevS zAAi%@HM*2oBFY=u2X4ZKDIz7Qb?+bR|1jiN(Cg|OdCOceHcChK*n1D)mru^3AY7&h zgOnvX%E(Ku{k!YqfdFWkS2Ix~@?4NHoBM{`F+q~A_*yg%x#cYFfRF{kgNpk)ij)=A ztXuZxL9B9TaZFa81@b5o|+BTI4s0000#q9`p*1G1gOdS8jd zA`2m)?Ua%vNs=Trq&K84uH8uBLl7ZcUWF*V8|?_b65M& zFB_sGy#@sCiGRNnFdmx=MpPrWrJ&o13fl~Smyj4wk|gDY}Shue$u?Ekgj2l&7xCN z_!9&^A+UQg2NMr9(8#>6xEyjyzV5db=?pppg;kqFM0MFxYorLGr*%Q0OqqZvW52f`fWx?k8%L|M)exI23X0# zGs1;hvz>}9gV`zGXm~$?XPn6R8-s^(r3_vk&_TJckl=ok}*BCsFH_bv1 zVc_H(gMU-e?xoaFeTXfVT4KI4qtC8->oz4=-g2PD#Z1e^l`Z4+hoR!ZC^meLpyd#T zf{*@*v~6hZohRWJIHJv?4RdkoD>kn$2@dW0MwrREH~_tjTxm79nbjIGe-)~czOFCg z9Kxgy&(!dD5e3u$#CCu7Eio*F%dpr&_!njXOn>F1z{$AGWr7;ti|1CctyuGZdGd={ zZ^C#6gb1RI*?B|uE;P%jucCV2mnf;FVn%AcSR}V$Hg?bC^lfPPI`L&(^j?t3dri_L zNs{M*)&S--0VK>dMQ|ug_R5E;$YSBa(?9fGfGfq4L(J|(;W?%@hzmmCLOY})3qCCO z4uAAr&qB~_W9}pjtnm~J&xqQ+Q`G?Fcj)`-FX}66p*p2S3eG(T=<}x*QW!bY1Sqm1 zM}fRFwEyfa^4tJ;$=9@UI43+rgUx+Y?wF0rO<$YlF$bO98L%HCdPI3&M=7#qcl);% zBS-g`Ib_Np)7@Ul&pIKmtpw~JGzxs*(LyXhDh*7r@bS=sC}YOZ8#}9U7`z4NZF@e5 rd?0f(k!t9Ix*2d>Op+u?k`Lt{IRRN*^da&b00000NkvXXu0mjf9a7jC diff --git a/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/86'/1'/4'/1/12_0_0/00004.png b/tests/snapshots/nanox/test_get_extended_pubkey_standard_display_m/86'/1'/4'/1/12_0_0/00004.png index 05fe79b7023b46de897d71559eb7a0424c2314d4..aac9bab3771e6d68ae5a5792a8c943f354ed4b57 100644 GIT binary patch delta 498 zcmVF1DKxwBp$^DPSUHXv;!$>SL$Uy7&z7j_W ztj)3#0ssI20Kjs-W){a7^RKVht1T%6@{2_Qqn=@6jQQ?wYKJV!Bn`uS&nyQ_C!siBSGFtu;KQoJqh>*$6n$D_iErc5(X^}7fI)C8cN#j~@$N)P=6C``p z(n8oJmk+A2bgN&w()E*;sU?ja2L}vn-&kVTCT>1iXAE6lv_BeUY8ZzSw77QH5XTUY z&0|?wf)Wj%S=?!FoF==b1+jIP1B(5bF(i|HyH!Orvi2%eEMK}U7JKPuz`Co_`XwlA3kA%FCplf13gA@CN{ZaON|>G6*U*i`{W-P+g`TRq@Q|&l<(F z;F7{gRqpstL%ZbBC*IfE<8_OTy4llM^^^=K&N7Q1E?sPk)!uAtr&`8_3NXfAwf!!Hezvapr zI_BLKZjSq&pE1=FZan&<91x0!+!*`5TmK0Mgrj`$Ku)Ye&!J;vd~hq67XSbN00000 o0000000000000000N^%$0iXMwI}gVQy8r+H07*qoM6N<$g75X@dH?_b delta 494 zcmVF1DKvB}^O}PJ&e3vdVWf%cMHZqX-zg6pC zOe7#g2>}2A0GRGIc>i%6`M)tny`^Z7U#vDT_H)f~9QmW)S|hBsNj+TlGjem{5{?+7 zOFu>;py}yiN`?P-*J@L?KjnAi<`yw)^021ima!I%m04+NUw?h|Y=Q@aYvHp3?2I8u z@oFs#5t_VxDE5}tJP=p9Nh;g47LA=x0xpa|xy9a_c>gIt7nIvenGa=~y3A(_nz?r? z#4yAs=bmP7L5Y$xOFHcbr;$_Bgo$-y0;)$erBL-Mh*&v3OAV8Q^#( z{!U6hMm{hcJAYZW1uf?_ZJGW}E^{0JzSw9r^bVFPQ1!6bt;L4ol&RMz9;#bw6xD)L z9S(No?v`q(E}wnk%bH$Zx5TKsdX&4KvI44w%<3PfF6zx%-)vi>nr6WY2!MR)-K00000 k00000000000D#;40i&X#@iA6hyZ`_I07*qoM6N<$g6+%YumAu6 diff --git a/tests/snapshots/nanox/test_get_wallet_address_multisig_legacy_v1_ui_0_0/00001.png b/tests/snapshots/nanox/test_get_wallet_address_multisig_legacy_v1_ui_0_0/00001.png index 87b4dfa0fcd79dd1870bdc60c0d92e4f4b667964..cc2d012b6709decb341536a534fae2f5468252e5 100644 GIT binary patch delta 429 zcmV;e0aE_a1JMJJE`N4}APhiJ+tZz}|0S`Pet1gL1R^*Ab^7j?6A=(JI=F2B006+# z<(zZQSNGycJ_GA2L%(qSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_get_wallet_address_multisig_legacy_v1_ui_0_0/00002.png b/tests/snapshots/nanox/test_get_wallet_address_multisig_legacy_v1_ui_0_0/00002.png index 877ce1d16400ee0bf175ca456993b030385ed78f..5c60da26e6d173a9db5ea219d5b126d25e64a837 100644 GIT binary patch delta 707 zcmV;!0zCcR1=|IXB!8kwL_t(|ob8)kcElhEg>6rFlKn5qz4Rfc9*c0rpG1?n-&5)! zA}Eeb8Ui7N5JCtcpGk}{#_0bD$Ulzn)dqy*%Gda`iJ#R5n5gkkcf)ZUXZvv+LdM^+ zip4uXI8^Kg;TpA3C`mG^qeb7c<$ku<0m50%wcn>9_qY|&JAYY!280U^)gvR+oWAz# zSs8#d^E?%tIlUD2tWzMfXZ{Hxd@URs=LGefw2o72MelzI6G8|fgphy4KSWC@Goqxb z)4JT2N-Sf*_4sVb1ynu$KP}^j5cY|Wz!=tq`*eb;5w^kdh|_WrBy5R)h{Uv;Fj#0) z)B>!Vly#}bLw`7X`OPSY$Z0FaorT|YnM`%y>cF^2;MCa^+HOBOmCv%I5&-`+L{UC9 zhW1?vh8Wb7f^E%9w5LBs7r!M{2ciI|omEFWQA;|5I#tTk)tQU%j}0AwV4s))Xx+jh zjWk&~NI9aqiudD~MfrB=Oi4i(S@qcT^?#T5BvFcj(P|+~=3(OQY zG-(iXMte?mPpbw|Cbi)_)l2DXct#A~%EPkI%cwY+F}Rdb_p0?ZTqf%-*o|Wq^;E;K zwV*muPTz9K9Mrl(`2e0h3a3zYrC2N7s<0n0^;*#RfG;4N%lmd&HS4(Ht6lP5Q%YFP?}kB^ikj pLI@#*5JCtcgb+dqA%u_tegW{vL^xql&es3{002ovPDHLkV1j6$Sl<8u delta 710 zcmV;%0y+KL1>OaaB!8tzL_t(|ob8)ga>F1DhH0la@%@kFyY#^mhSBmPmIUnl-;+x~ zXkm#IHzh&{A%qY@zLWDj&-09b1p42O-_;7F?8?XZw28mf3b>f@Fn7ao99R2s9HLLW zWfhBefN-eT4Z<~MqY#q&n2r`>b<5}3Vh0Fk1=oI`gwo?)M1McY`a2-K;Zi*cQqAdW z@1B(b$d;E!!F8tV&XIKr`s{iBq?CRZ&W+Cm^PcpsQ*TA@e+d&p2qAI2QAA`bYX;KeB+!9fj z&yA^lV|wxjh2%(kMv3YiE+Vi>idon}({814~+r*gAX=wVcx%ox0t3GOw^WVlk+U9cO+D`}XD zVQoFFO!KE?{w}6;{Q#aL0;f=QrC2N7qOczTp<2-OfOC*wEkP%G)tpGkFO?B3dPrP< zuLIbi!GENzzZ4+`Pbo0y!YA%rb_40O&bM{pOxPkmH8F>jqsB{EJ@1BAYlPWfA9N1xpxivn?Lm`O~%2>Z}I;D-^|L_(=q1PzI*YI sO7EMM)|*@%@j)U9xbBBAO7wHqicWk?N)y zWB~%cNlE|!00000ypx=B&e{Kyk$*eBXB&`;D?i4kUHr^8Kt=2iaW)*sai$-~LGt)h zW-)mN5Qmc4KwKjxl1fS*(b1$VPkEjtW&m-PbL_`zs6DRr=zo*UUjxz&i|SF4T27z4 z_RQ>n^5k_WIAc1`>=~y!&dgXl7EYL;sJZyYX*kj;uUEkmpDDOBHHXG8N~c{9y_>+e~Hba<+ky4C3fpZ z@iY>G>Tx7W1?wXU7$piBVW*VUDm_o^-8AO)c=)YKsS&Ra`SL2nr6C$HGlk|alIJlj8x)#g<^Nt%(&JtvEY4isU3oH>#Y#MuX)APv8%jK;wm4)Tx@R= z2-mmVj=r!DVk;0qY=U1Ewe#OZqXV)c7n1-oVs1b&=1XpK5e^io&5M@4a_lZ^EC2ui0000h@(cg6 VOjnpaTWA0P002ovPDHLkV1ltmUI73A delta 734 zcmV<40wMkT1@;AyB!9h0L_t(|ob8)Ya_t}phP|EcB>P{Id+CESju!zDP1NN79y&cK zA_0ZSNkaet00000;G4u4V~qAcDe}khv)X`=UHKZHcJaH~01-AG>~6TOD_y^?i^$lo ztYYyFAPyzFfw+dfNR(t5*3o2aedT$!*a5^@#r87!^gd0e4jS9oaX*-sjX590s{FfT)rhqTF#zPKQl47L z9X6flwzAiib$|1YJz$S}O+oRSUy;=0Vz;L>MB3d%fR)!}^yJ3=BsQ~_>&BN#^x2i+ zVI&2W>xgX?><`<($XQ59J9(_s4zaUEH?)`Jom(@BK6~?u9p?^c-aPr1N|7nI(R81d zI`7awjwb*lnc7PYDNy<>gU>S~)S;4$>8-IFu7J;RR)3j%Cy2p%5QCM#`zwL>S7P

?NXs-v)3V@{3VyH0yy*lRxplN4DJcwD2 zvaC&YUr1?EHkH&mr3Q}0w(=vP-M z?~8Jbu!!}l9cPPw(3rwt%38(B*V7+nBzb-)hgSdqzQkcQpzB!>Oy-&1z{8yV7%KI} zus?2r?Z4N*pS4j=+5u&2{xxg-ymv!iF1DMQNuy@&1>@Ui#q~hU&#N21Dw5z7iq} zAwUAfDG@>lA%qa}PIAsUXZ)u?{^R&wZ9pon{5L+m#LsF2T+I0}cf)ZUXZvv+LI!VH z#o`?x94dB$aE;k0loT1$(c)R%@;qDY0O2ff?e}S@J?_oulYgww0ck=~Jt|Vm>1%V( z$_XeVuS3BZ)3q?NP6L@e<4;QIYhmAUOfd7LmrlJEy?+uWgb+dqc_+h;q2f9dod3j; zQA-Ao>%O$wrp~i=r0X1|rexX>+~%~5H_VBEMdP^m12zU~%}1IBH|;dL0L_Rkac{!8 zqW*eG`=n|2)PEuiZMUL#RE+aBb-jfLZZ31PUwV9?CHGZp722gxfyvXjE zROG>Z)2!bK8L-|rasp-q95bB;!hsh+y!@bY?SZV zAD5W;hfJBI@--<3b=2iewORlyUth}G&4a0Fk5Dx%PJirnoB&yFwlH9ef5cwJfFNmJ zh4!bu$}DFSGhPb4zY=rYqVPvB0yUNT*A6eQIN2P4Ia0e$>1b#*O!v9dr{$-kS1$YSyj97(|`5 zOsZ*sr+>#Z9v_`hTR!8BIQ^vv{JLL1(%qfz@oM$4$m6w&2k4xDc>~a^ejpnj0k?QN z8X;c(AkBF7Jhwv7`9X{dFGF7K%R6f#J?eNRP7t-8+Psd;{9&wJjQ7*hO#@gBT?{9H r5JCtcgb+dqA%qY@2qAZL#03Kfq4015yANkvXXu0mjfr0_eu delta 654 zcmV;90&)GR1*Qd%B!6v5L_t(|ob8%Xa>O7AhHa-e$^DPyUHXt2#{%LXqrq+d?`hX1 zh^U}!QX+&9LI@$`o#dQz&iGG`{KxSfZ9pon{5L+m#80#VP0aZ)cf)ZUXZvv+LI!V% zB6tS~hl<@GTw^v0B}K+`w0KsxJkJ(8KsXCr`(qkvkGE#@Nq^#VKw6MgkBZcDdTj2A zoPaX&Iux8ST?-@Y)REaU{-l(?0{ix3f|(~<>9na4}|ZKJL!nFctwIW5x~<66MFv0wiI8y&UgBfhm=BTfCF4Za!PO*mK7 zUoUmAXy#jLyMJqKx1x8a7}wg=^)8;czs&u9>G3I+Owj|*^yF&j%`3hcL-AQ@1$XoD zB8<3O$MmiYSnr!W0V@KInW7zG#}Npv{Hzs43IHLGjXJViq*dLcz z`-e=Kr1CW>2Mv_wO|@EJEM#d!N6x|2G)AbJ86Ll+N;A;@^N}M2SJ+*lQnfb$rU5xkB(oF+c4Go49KnNj( o5JCtcgb+dqA%qY@2wBK4RHLOo!0z%G00000Ne4wvM6N<$f(_0*F#rGn diff --git a/tests/snapshots/nanox/test_register_miniscript_long_policy_0_0/00001.png b/tests/snapshots/nanox/test_register_miniscript_long_policy_0_0/00001.png index 8c84865fd6dc5fb2ef9c893eace3c2b6dc414c15..36414494d2259bc9b27c05a99417c248cc103f66 100644 GIT binary patch delta 418 zcmV;T0bTyP1H1!}B!7cRL_t(|obB0dl7k=&fMKSyH{t$A;x7H+l+6T4u^Ya+@AIpT zNDveiLjV8(08W=uN-3>w#YrBHb>*&~JO)RP`p<+MvUg&PcI5h-BQeJO;|k`8+$zh< zysB_DwJKTeVl-H$`;6Napw7XvUoLi}tf!ht9(MknYcmR0^M9(6b%7 M07*qoM6N<$f&?AL`Tzg` delta 417 zcmV;S0bc&R1G@u|B!7ZQL_t(|obB0dl7k=&fMKSyH{t$A;x7H+l+6T8p&P!s@AIog zBoP!9LjV8(08W=uN-3?*;v^5pwsO}`9)qJt{bxc9**h^tyX5+tOJa=q$5oh1J=9mGP(Dmx;+Z=iTrhN># z7Ost3<=wv3o2uH>*m73_F5YzSRu9OTot1CS6M8^}c*qUkH^Xj7UUt9sJomFCl$#tw zxHQ!muAvBH+;%l%Fu|KnW(F1DK;2Gm;`<+oyY#~|D$x!Ij1#?&j%^kR z2?SQ$<4BSuNs=Tcg!xzkg`wXf3k+)5=mm{srxM z*ov_N5UhT+^G%&#oOF>&GZ#H%qoPL~Qqmtn72R|^N(Qe0XU)F3BTd7mX)DocU)Fye zk=b^@6(#DyNGsPr;Hew3DLQb!8K*4-4KiqVHV!C#Dn;ym)9RRzY2zdA*tbe#BJ=s!4PyN_RG2R32Wzq|TeuxT`?&)D^2-*tg>X|L&>l`rkXcXH# zNs{Da3D2%HwOuC2%RvX z08K9GL5bFv9-5uZ6VyTE3NZ2fLIgEuE3;UT#JWA;N`Iv_WlYz+$Sf1Y66}D>#PBN} zo$|M2gCV27;j1YQLG!dUQ((wp9zXTDbD1EDVcy#V;x~kTB>GhsY`8*OVShZ>3N|v| zKli^4#^C9LWr(IuA1uHya{6E@_n5a^Ds4#f88x&>YVPT|Pv=&arXpgYX9;*hFWCA! z5bOXY^?%3~)s})HHaV);T52U}h%RW6`Kg^Jp?e!j>d_eiq#l$6s#H_TVtPWBnZ9KQ z(#q~X$V9~rx)#s(53^fyg;DJ8fEh+XpY^d9%ZT5E!DQ?QjZ%@>p&6I+0R0b&r%Ldx z%|}m@N=!G+U3b;t8)+9&hPE#rEuAA_&A}e|2Y*?%u!ceqQf_eoT_A4HSBEJ)V=X61 zk|ZPOvEGxUlukbES;(3EFcq7}ld_@oOj6#np46uMpJ7%w0PLcFl!=-&r9aJoh&|Z50ilN~?`nbFfGL#fn7{{4YxNZFqRi^k*cGU&~37BuO&J YAE{~DsgXNFG5`Po07*qoM6N<$f?p$?RR910 delta 842 zcmV-Q1GW6+2H^&fB!4JLL_t(|ob8)kZtNfog}GIClKn4h zfQ^Acwbv8Y9(EmVJ_!fH^Q4OcS>Y#iW?Rm ze(+-wdf?3ya?aeuFxPdtL?3*tZ54~$sHIcCqaMm;EIlXX%YR30it)zDS`^#og|&8y z4|p|OZVu2`0R+*-diQvqlbJZkO}7H4{^h?oWdbi2%b zV;}1B;<=Wi9e?sf$1LXTPFnn_Z{lO?dH5bryPAD&+StO<6m$?SGxzN2pXRK9NvkRd zf*|O?U0@mbLO#`skvIjtjDr?bsAU;`%_U4AYI22D(_HbCF?TuN6iMCc{xtc{~`GlB;PuG z{4@!2dNbU0Qv+k8?INIS`(p9Z*b^}v;*tL$D}NW(cnTuUEl!{d%x(MC!JjkMau5VT z@C2OeEh43M@)6HMM)9NR*i?>DL;0B`f2y85rbnD%rVl`g3w|k+ROymGoBs`&;37C% z{=|T<#QZvs%AdSEuii{qxVl)zg}uZ$ue^~rmOlx54Zt_ZpM<>zAhpJzq>ddX?-|sm z#zQ&@0C5pqU_hQ|XP77!L8szt}NH+>W8db@%id@~0=qujL>Jf*^R#AEVFY Uy31^j=Kufz07*qoM6N<$f_i_Z7XSbN diff --git a/tests/snapshots/nanox/test_register_miniscript_long_policy_0_0/00003.png b/tests/snapshots/nanox/test_register_miniscript_long_policy_0_0/00003.png index 1c32a0ec6d59b92f9ffb7a6c0f2338e9f6ad24c5..658b8fe6ddeb94a6ee6094103e7a9d3ab87c1763 100644 GIT binary patch delta 870 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 Hu0mjfv`oQY delta 931 zcmV;U16=&O2e}83B!7TOL_t(|ob6g$lH?!^W2W{dx&M*4%Y1Y##UNYAge2WH)>n68 zYz3Q_l2Q_hL?V$$Boc|+@x^b~T1zR%akSsV-`8)Yp=Y@TSA?sz4iAoQTddxuXELSn z&2J-vAuw+)qSlHbmT?@%mfjy6dR_6l-rIP7O#C}Z6uCz2+kan7s##VA#-iyTjXgh& zLo{t$ie@qb2AC9ifedJmii6avTyNAz!wn=!r<iIe?q&QZiCxiwuUL_Q0x21p4YkKK<= z-BtaM;iB2Z+kfGi#FTJ4$wpvU1H8$wz{;VJd|&L{o`&3R39UG}bqe|*>?+$2F8^}P z2)JleB@&6mp8y`p_$E)BaM6i*`qTL+WVTrHw$UB1>KcD2Y;>F2$u-0ensJ||L(y^} z0ZNmJ6fvBYq72Lz35sW;krg-wij+hV0xh}7eDXNW5`R$PjfAP(Vs{UWdy1Zol4ybpMD=yTE9taTD&0_yKqRKpa8Yk;{hP8Z?9Mtmu#tP}dKVQqhb&6^V(4Q6+- zaND-434b4MCui^92BWL9_isk#;7Q~x^du&ooH@7@*uB!Xp~d=|Y_JJ!4ZYnMafN4n zQ=-B1k$#1TixS&#k_d^EA=Q)XmkW0};RQdU!b%*9b4lzZtfZ7z7Mh8Nul}!h7~BF; zHw_V69169A7n>B6Sbca=G$S?&CG+V>6fe*Mv40+t7#Aur&v?U}xD}xRv~5}kT=HEI zenWVF?_I(Vb&I_kJ*EH^Vn-wS`k9bRz7^C`P=(<8)5xB@{ zS%2}!OBoc||@dNXP@_B;9%0U1C002ovPDHLk FV1me2w>$s< diff --git a/tests/snapshots/nanox/test_register_miniscript_long_policy_0_0/00005.png b/tests/snapshots/nanox/test_register_miniscript_long_policy_0_0/00005.png index 621f3009e1395f745026eb02278160fe238c21d3..5916ffb9cbd596c1d7dd6ef67f9770d6234f2169 100644 GIT binary patch delta 839 zcmV-N1GxO!2HpmcB!4AIL_t(|ob8%h667EVMKe>glk9&q?R&Ns=T$>l|{w9Avzda4Lnp0S$u9QOLh{9`O9ik7_9&F5C z@Qe&Swqux53Rf}Aec!W2-z;gBR@GcP?%lsp3kB((o|F3ZFMpp@(V;FDi=up9S(6it zo4D(s2q1{|wbO1|Q~SxoQ}bM~2z03%yI<~bHTk#uRG4sQ3{GDIzk!%wF z9B<$XemTd_#^SG1U%R2cM)*71Of3XJ{?%3kpBHmJQVm?OLoaUr1r4BI4)6q{NiwQTJv# zT3mU|IS6K}oL^Qu<(Q%-e;p0-Wu8=;Uj_K)`P|I2NGJk=gQcyW&Q{v1o4A6u9Uzsl zCBqwp<>#s+4sJUesYU?zl=a3WNs=VVFJWgx&3~NVz}}qi3wv{lo?RfflQ$9Tm=#(% zV)v(IvCQP(HMGeKiuGvp5`ZsOrn6h-n7PIYF!Z=%`G+~UG)=&Zb> zQ$SQ)oj;5w<^}TG(3hFB4Xuxc3&-S-)d4rDq=IIi*b3`Pk|arzBuSEu_zxfsqKxEc Rqxt{<002ovPDHLkV1nD1pRxb| delta 835 zcmV-J1HAm+2HFOYB!3}EL_t(|ob8%RvfLmHMM)|<@&1>@UNU%96w&u0%9{pqU2FH#^;A&jBCkn z;~5!x+mtZ9cdjDLbzLc=@0QFOhhDDQ?b@G^g|Y&q=cNAl%YP?T^r^;TQIyXsYjTDS zfoV(e8!G|`qKWg&y9SM}@(9&D*H{OZ)Da_%K^I*i7FCFynGpcij5&_j$`~44OKfoM zR{}1_i2y!_;u~*CC2`455?*IEy~ki-3EE_HxWx%GWEzj$_XO8FFO`T29Df3gZjU$s z{bH^!?rS;P_J2+^3{i(0Y1Gly!^U17h@CGbcYC@dHcK@k=W|QYK_vR@sqWwIiGZ7; zswj%0NPw)-ePWcPXxSI?g&3p!#S^fb3wj)$j@1&huNwC^qPe;K*KTeXzJafbfD?K9 zNf^n+KayC@;_Vag_0T0KeEYKxayvN8o9#qaA%1WE2!GD-zQIJB`z}U4hHCi{T_X2W zha%X2dY6u)=HN-rUWHD_8RVLSTj9fNeH)61bN8&VeXZDv+~c=@`=fn22O2PMaBYEe z;lo$(NVvp83j8R+$eXSjup~~Pt{h*$Ax1Y@>A zm&6nOcz-K?V>6eCxPAttyDz(c9@j7(m-{OrK81_ z$DM=CR2BGHH7LgwmHc(Ikt{>cv^#ogKuWsTB+IE0cwk-*7 z5NeG&bNlEX+>ls$nE4!#5!(;S&rEK zv_zJh|7)Rr-lkYYBa)ud&LW60VE0{9b5aq;QAH~Z2yePW1yYZ5wr5tNjkcaCFID=mKd}RRJ7%<>UwN?~G zQ4~c{6u0vSzwW)a){f&iuf^@>nyKiOOyMGRy?4=eA^Frb78orF&G?I7YxP2L)C7v& zyH>HxaU5CRXC!}~96y9Y1poGolscG}i}L5K?o@MFH8mGa`G2~wCue!yqzsy11_(_1 z#?B9II@_rysW)=PLo+He>V%Pe2pu0zIh`>wc?OUr*T#-n3&hz4XW_S_K(B{FQG&Pw zK2gHcJvAOjnY@X)=mqmx=0eaWn|=pt;H)}xy_xNplwm}50BH6(_DSo<@_JwE1sPL< zX&9q!%FfdU9e)E%JIzfhP!ya4p5>wg1l~j?YG)+e8iHO0IeV_w@^u}MxHY=EdQlX` z)x^6XeluY1Es_R9+@yss~C% zm`N+XtC^e^!)&%ySHu%;)2eH?I-&#dt$uC}D{-V0$A462NNPEzWMB_gHznL`g(<`& zAsZ^d!Pm?}H^*P*?N}XL0Q15oEC|=FAni%+0DkH7Fn>sy&9*Y~Uqa?dc;EY9h}?z> zCu*O9ML3**%nr}nm6{J3Ic6~+irj{pe!xPsLnJA4yui3lF7Mxl;p+1K%~T&eNkyS2 z37lMgaDOSq__77|)$Yd0L#Rrl&72%yJurjiiIr^Ayr$YJOE2biYK7o>Fu|+lBL-U%!IlpZ^6u3>pW5V;b{q8mPJKfi(KCMy~&r1q@pN_q9}?S$dlew#%fkw|3N=7A8Jv! zq$kj{$}0nOfxHY16rJsi%!Gh{egNyg1q@oIH0;nUTJq|F+G zq+uzERWhtGOn1Pt-Dczo9kJ;thBXyoASHSDUy}I8uN%DoICG1z&I0z;@50FiN~`ls z8nc@_8A|2{(Z)3=eOrO-*xmN#@g7SUaw0;|H^hpfD2k#eei#1%{IS)Qoh-WK00000 LNkvXXu0mjf@Akh0 delta 937 zcmV;a16KUV2gnDIEq`6I%C76pTwSu#sZ@mj17PBYiYrx+f~5O zdzUJfIgTU6`;6Gvlj8?hh~(dfk%}6o8WkCJlaavb>Z|B9B`r*z0c6Rw;iJ|9p_bQz$G&u>)kCf* ziQfUQ8EUByjmJ@D$jU_In)xiT5VXmr-@!5%Rp+h~j4{zFDpUu6W}jo9Y{OVy-PcO2 zO`d8PqmDQ7G=D$_0M$r!lS(RmM{>8PA+h_aNeQ=xpbsKtZ`aI#i)K|(6vZdv zWJ6nIJEf**Kt9!~#b|W5ePl9Ht%zFzgf!UF6*hAQ?$+MQvtre<47gY}m6yqwYJpM_ zYSN1DYB%RaGPYqYVTmW)rd8MOHKz{5xAM6*62OR&%-Q*;y85>9PgDNHywY;MRaxOm-sS^dHaYDtcEDEk@ zrFWvnkjW_giVq}yD#AKbU}a=2b@VacPPy`}S4>3)c>*QRVvB05hw3$%Sp!2%O*fKC z8I7TfETt;>+0ZLU46ICW$ST7S?tmRH;JQ=DzJF*PBR{5VViZpmvut~#8Gw_3zZItg z#`RG3h_zs5t#y_t`S2kAXCa#-Ymv)4zc=}kkyI2#Q4~dy19{R5Wvrs=`VaDn`cR6( zB`txfRaP0G3l#QwhYpZ$8Ff=(*R#L?pw}%)`oaG;w8g)zlx0S1tdC05PcAzt6L~wH z*MDSlu$&c3_~c(G5xAB<9BavdGd^*Lwi-z+?e1^}o*~20N-{25#j4f0gijYAk~VD& zl7^)uR>`o&5bl6wyVc0!I%3mP3~MUfKuYrP-&FCBUpILFabk)zj{@oHMy00000 LNkvXXu0mjf4`R&x diff --git a/tests/snapshots/nanox/test_register_miniscript_long_policy_0_0/00007.png b/tests/snapshots/nanox/test_register_miniscript_long_policy_0_0/00007.png index 36f9c90a03f5bf39d0b9935253c251e72378e9b7..ea568ba344f2e0a893be0be0a179cc6da1c34587 100644 GIT binary patch delta 966 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 delta 443 zcmV;s0Yv`a1K$IXE`PFvAPj(EPUq}|{V$2V^uZa12?3&jg8jcITPcJ~km?)&003~i zzxwSEf^*J$AFsv7Et(K zie1f-t9w+X&dROkbHW(UgxLHdi{~sexIV zvj-_+s83kw5P$Jty7wA;JUvzIkftq_+`0vAWYn_Vc=@|I889iU006Uy6JdTpG+r!d zvs2LV;$gLavpoj93!3LOqr4^KK2yKD{w}n12B?-D%4;^8fX>%v3)<`<{C-QVtdJ1j zq-E?Ek84D-PM~&sO@PaS`J^}Yes#AA{ZGtNYvdO&2Q*JA4mERdgBL!BH^T4&00000 l00000000000002fd;$8MhECL#lFtAD002ovPDHLkV1lt|(*pni diff --git a/tests/snapshots/nanox/test_register_miniscript_long_policy_0_1/00000.png b/tests/snapshots/nanox/test_register_miniscript_long_policy_0_1/00000.png index e7a9ab02a0ad59792a85b4ae9be4693d63098ebd..3a3a1b402e1af2dfe28d3e6b487306407f7a3181 100644 GIT binary patch delta 997 zcmVP{IdpQ@G&mjV@fF`Cb&(#-$ zh~O{jw3H-Ck|arzBzc@Kqg<`ElyV$L``sSHG(B7!eKpxifLbdzMl2ES?5bn_g{@rT z{o_L+PN%O5i__h7&1tQlwu$zGTAc5gePFb90$jdGBk26?8h<-o>%7Ho*3uH=3={ph zc0l-M0GN!lpRL^D{h660E{s^1(##eWiUOiqUdv+7Nn{D?)(UEbmwE5w65d=ldc0=y zK{L5j`U0T&>mUFzk%yP~6Kx579`_8O(Z-Ip%h-kS+U*LwWqHvm25M=zH{r&)+_%m1 zEVLLm+;4%-u73)Z-P5o!Brc#S#*6SH!{(+zHkm4Ym>9mfygn z<*w?t%z#x_H&oIMm(H@)0z zm3`I#9pFvSN6o*Y&Lw%)Rfw*m1XB^By90W#aWVNyQsVXzFeBsb1ttDPjN?sj&DdS8 z+hB=~fO#f+5l_ZVGHG{VDdjB-&V0MU0EpXZHwKUE7su{VQzBMx`t8|PZku;)G3vp+ zpfbb#K!2{5!~h2e`Z(AF)?6t57}#mULv!*38H1gq_ji)s-wF5r$}eK#8H=Ayhvk;@ zqETVsGOV?z9i2sE_8?9!EsY9RbSBa?B<%;z=JKY+6n}uG3a~8~RM<$NzOYAHQ_GVISfPEe zTOwyvRrUs8xMPRa#`JXC?4%7wRXYQ~nOuCaWO=G0(#w^iuAMpSHA6^+f*d|ukhSy>rL%uzrYXIyGS~^qwR?hd{ zZY$#r@g9O#Vn@WlYjwR_D>mb|G2hR>;;H+X^x(z--1WaAehPQrFp?xml0@Y{QM9y- T_0RXT00000NkvXXu0mjfh>ZE7 delta 996 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 RA^QLT002ovPDHLkV1fjm_bvbc diff --git a/tests/snapshots/nanox/test_register_miniscript_long_policy_0_1/00002.png b/tests/snapshots/nanox/test_register_miniscript_long_policy_0_1/00002.png index e82fc9df1a36eff8cff84d77347bdd9216132c23..1ad82f78e2402c9e8270db5e6e0c3b5b45aaba5f 100644 GIT binary patch delta 690 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 W1+nOSo8zef0000 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 JPDHLkV1fW%5KRC8 delta 568 zcmV-80>}N-1knVLB!3u5L_t(|ob8!WlEWYfK;50aN$!87++{y9bu1u)X>8MZ?<*S# zA_`Kr6aWAK0D$HE_{00Ymr}NEtIze%IjRy-`zDqrGou%zRej%$PN-x6Q)f-o@TizRddo0AJ6GtDu%)o5ie3hfOE*L#HF8C4)7IxX<2O zlFbnBujw~_Q^C>f3%9MRA!`bXbUS*Q{h9cOsb3XYlYfTKH>T%qea!V&T3BmvhD=rF zhwU3Ndi!mNIH)(8+N9u&=G6WM%!O=?)p&m~?7=%B z3%!$plQG$YOToPW0000000000000000000000000m+=o|?r80VZ=O>C0000M!GHIqxBAE zIO2E8nl0Wxo@j&9-C(;C$X$Z2alzo|>nOYh&qYR^_@mq5&VSZ61b+;BgJ|JQIj_$- zqR(QKkEw%`(FAz3*`2vW`?N8Ic?OWA8=t4QE8btrq&~_7EYd~t2^(<|7*my5(i3zX z71?k?%76x5=0Z89v+T-3r<=#!t?R<6(9>EGG7o@BQlo6z&Bcq-+1R7^9K&{TpUXnp zgmD>-p!bP7n}4+~8a){ondC?}!ZN`}q zm7&}Qb`Howd1iO_BRy|k5VqTJ>r*Tj>7R^?Pc$9AEdzEPl?#PJp>P{^RzWA+x-B9> z-FB3K=WzFkkB32>m26%eNovrj(CkE$InbDRotUg5CK)i+Snm4EYo4g5((bN5DY~00 zI=;Rf<$oNi=}fd^|F&gQ{CO!J#D z*TbW-5%UZ%jbak?;2SPsIvjlw4bi=Z3pY{)*E3tmGX&#;7U*&_HfvDi(jb!rA@2!T}FZH6`|PU z%8W|bOFYMT{7LnXhLek|VW{i6aFrBj7QcM9Xv#-&kbt zreRDZ7V}1wgBK={<^n&bU%A2AbmS9)$bToDPt3`2%`v)B!B8jL_t(|ob6j%lH)K4)Naj9eE%c)F8kq%N<%}d^@#IW`eVwG z5g-tHbTXwR5{X12kw_#Gx8o0geV%72mGnZKJHV#3m020l1NVUBi{kbx#y-dQ4HuNnTkx?G$i3D7=*emkk zf?5FuqRjOYbZ6O?J*Mj$54Ua$r$Q}jMTwLEQ>VsWR}Ar_ayHKBl6y@LLEVILC5_OP ziI(!#kdf3ey??kZu8PwbSb{FpJ+nQKbp2@e+emHu5Q(*R6&b}ha<(BpW3T8K%6;hE z14f}w{|cUx^(nT3U3=1fqnJLYzbzJrb89rdFZzi@BJthWdQEHZl`r{3zJ8ibGloVn!-nef zg-ag2-z!F{CL*Qyym5!q(fLNKK9jd1lw&9tGuuWhhWTe4YRhleqvr^C(%PfEH@_(%W@8#}AUsw1NjBX?fCds%(tH%S2da5?F z)Lb~5e`(%mXp5?f5BP0pd!*Sy8k=mn`HKR*JqK(F!W{`)IBBYDjvA+dA=cH_lyv00000Ne4wv IM6N<$f^YKmT>t<8 diff --git a/tests/snapshots/nanox/test_register_miniscript_long_policy_0_3/00001.png b/tests/snapshots/nanox/test_register_miniscript_long_policy_0_3/00001.png index 1ee8b13fba48cdd80652197eb77890dc8bd90ef5..34e9322bb2dfa17044c8306f3289a868cbbf384c 100644 GIT binary patch delta 1059 zcmV+;1l;?u2)GE4B!B-&L_t(|ob6m&vfMfdR8rZ=?0-q#OFmptF+igh()idD`pefw zs3ky;K9k#8p-?Ck3WY+Ua5;Vj-;U#Gt-W5a{@njFjqb;KOLQR_?y|HEdn?4SJC~!A zt%81kPqEoD`>%g!Vn}YVT@S(60KLZqVTR%P-W{52-|>g%;eTdp6OmV$GE9^6`AiT# zi>-f~m^KsD^hwTc+FGDbxrFE#R{)xQ8EQF5X7+QH)LW^5p}vB8a#I-jnIhS1RI)`h z8d(9&%yQsyh+s%7;gKF1K`%Gm!&>jN6fgZ9;{d24RXq*OT##A00zQh8c|2=-8J?gv zVY`eX@HWU;t$%g1V@@w_QvqA=v4dTLPV@~^P7T9A?zhOZd{7Ih^%L|vOAl?rinC>C zlLH+?0~*miU>3}n(E$!wF6P%Fws5#^An8N;ov}Wm*u%C8*mYGd6bgmHU4S-_Lx8d5 z8xA+U*ueIsJ{|9f-J+MS2Yv_>2pEu-=wbLZ;6uj14SzF=H#wCI!(m({#uqX7c;g;* z(gz_|q(k>3)M>73*Ohg0aKg?Zbk_EsE~q)B1(77I<%<02YRiG8q9<>#WbbICQ?sue z4%^O25wmb-fh-ia{AFCPxo`v>rE^Q-vjK2n^>LJ~uBCOjWg-H$CkNv;@t6n1+3zlhnhpuMKs z_tFFUAq6^Z^9ez{kfz=w?+4Bj+OFeYehb!dmID+sWiw~GVagHNpQbS!(CFy8!}2y z<+cF@c?894}nUCP-sI8P~#f-)ecvzReyr;Y5?MDP?gT`BWq&nk{K(qyd|TL4w);g z24GzyvU!9ITzLxlY(G~(Q}XJDC5VZE(rV&`+iI4xJE8kmOfo7L3pjhkxM2(y*UDUV zUx4*!W&U3gv8+EU_I6`t=LjObMbnO9sa}n{CEym2gSyMu@4{mTrtVqaH1J2F0vu2% d6bgmS_zU#fBDE}Oui*dy002ovPDHLkV1iSf{(Jxc delta 1051 zcmV+$1myd;2(So{B!BlwL_t(|ob6muvfCgGq@CU*_dk;F(vQqz6iF)G%^oJC38Z_INz{b^m7$-HCOT@Gt4@va}6*E5xunm!p%d z;(q^55n7-9#}Aqqk{fB)L+~^}?=eA`Vfei74$ZZf_{URm6Mwde;HzY@_A*VL*Utpu zv)DSfiD@%YO`jy}rmY2fluHPSaRmgkDTmbW4`)ADM!l5^7+Mg5dU8`3`I#cwYgDpD zG@hU;pqW{YodyVov=SagX~-=%-NQofQ#4%qJH`P}b*efWnpu!pxdJ|li?r84y@c&b ziZHZ6OS$YwS%30KFK$x-TklbVU4owI?@YNN8Iq9iTjW+=AT!x7W5aMmVOE?iL)#E- zLt`4zIbari`gg=3Sv=S|4>&3>U!DExMyW&IFfEcu4R7fEbj z`%;gNSHy17P1gfIgb4%;NK14vd>Zf}W8j7v#haW;hJWEOt`g&en0u&kH@5uoN5R$U z+;dIPX|8M6m34A(+Rh=Q*7lk%s5zwtktD3;iUR7&%Ymh$cZfqQ**hBP)a)yV!?tr$ z#4OxdAPdDUe;LD-cdZvb3ai5z9CYiS*BnTUWbiUC?}+DzFc1F)Wexh!_q zrMU3d%YTLOkXW*w&;hWG?TUdEM`YPXZ&5T^Zk1Te*_S^G9^;4q{Xn^;UPwDPu%`g+ zDX$Dj@)qnB?ihgP^1KUmi}+A_S$tItZila0g>HwzBv%aH3Ol|2Z^CvjXpiakzVv`T zq(FPJuAWC&|B=sr5DsIY7%?S?eWpg zfPY8wB)sw5pG!J)T6CZ0SSfF|R^&yx$3Xy)N`s6g<9@B21n1i{+$DuPA*1wEKJ7qU z{`O!W6WA%n@xrxif;0w{aV=c;t(K<@>?736I+*l5Lk*1+ffUO&7Rvi}dWnLD--d42 z6n_IG6fTR|vP*Q)RmhF=u(JYICQ$}B5p1<7%BiF|42%2S1b!E`FJE(iBUUJU47U?p z3xz^q4~|#J`|dS=({+nDAh$~UQx17SFfb#LkoKrg69c&e-61I=HQVLj9u%h3staPn zLClRuU}>Ma3R=6;`NgubQdN%aY5?MDP=D(NLy@eBsY7P0$dYD^I69V-x#pND&8Y8+3P7PyC=~YNKNLx= V9(l70_Xhv~002ovPDHLkV1lVx0>c0R diff --git a/tests/snapshots/nanox/test_register_miniscript_long_policy_0_3/00002.png b/tests/snapshots/nanox/test_register_miniscript_long_policy_0_3/00002.png index f4ab6a9287d68719a252d0760fc5ace5964e5683..dce83e05e7d046b636e482436e78066191d2ca4b 100644 GIT binary patch delta 582 zcmV-M0=fO{1nvZoB!4wYL_t(|ob8!Wa>O7AKy9Zt$^DPCcj-r_3?o8NW0LK@_mvof z2q=b>0ssI20B|{9!L!%vRZ7{mO|Ip37?ES84Gf_*JgcXDv9f@bBf^_~L_(AAE^SV+ z{`N;vvuZlKDIs_oAR`VatR;9F?(JTmKlDt(p%o{6MPt6ea9p zQ`KI^QuNG-LVqd=3z9IkX)+qz^lgea9KZU+>^bDR$#4ei2v44`$Y71O)ds)0+=Kv|Wyi_$< zPgUvx&8o83aslx-{3Ly)h%P2~Pg{V>m!z7?h>+^Kl4fn)%r|GT&;bKBvTxZUYggIT z%0KLLak5?L0E>;j;J?a>(f12me7@f9LhXPXRk24*ecNo=az7NUr!#fg701v6^WIfT z^G=ih5+iqZH%|Mb98j7QynW6megwP)PxQg(@Wfr{b2u=FH9vn U!e&kOt^fc407*qoM6N<$f~5o=tpET3 delta 595 zcmV-Z0<8V+1ndNmB!4qWL_t(|ob8!ia)clZfN7^U@%~5JyY#_nCPPSwAZmBN?@8Gh zLw*3Wr2qf`003OhSMb~G^(v)o+a}j?JBBE+ss{9H^UjjA4_4E+dPI3sMl^VQA2Mj( z``aHy&8ivcriS3x0D0qp!CHf7;Xdxk#5VurO=%`(Zx9?ytbl36)JK8ks>7m=y}yOMfjiZqb)wwWZu zi`#J7&D85oYJU?JWY5$!+ciS(x1L&k;fd+@W@Iw9d10<>_BM7;Rd61uh`s}kl23mj z4#|9e&2Wkhmri8(oc>tmr*oY{-p~600B_Hkry$K_kEK%Lb$+U&t-fs@KZ2vMXLkNX z`z-S9z>J3ENcBC@{B`(qebEu)SUY+KFC^j@&E&h1*?(#qTylF^zF!vr>AJjBLs(B$ zS^~|+vNv)8@n`%b$667Gm|Q(=11jH=Y8oR-s_ROd^>uT81RvO%62P<`u zO}-`W>`ZQ)_D2PvG$(lboKO4+_!m4e2A{(dSE0|L<78s66x<5{000000000000000 h0000000026j9oe^R zP}g9(E`eQ=wv+8hPCI^%tr@}DepO^zMGm-TgiR*j0cwcpSbr-^#;>fB*5xbBW!4BM zZ@|sZ;-*_oS#(XzIfCS&sSZ{Z*;jI*(qLvi`DgwLlE<+s^ndJg@6jC?7qqj4$CKCQ_3+wQdi zK{$>#oUpB3sDIB*p*LV;=B4LYiE;R5pMge2J0>K_jmAseWowN%S>6Zzd>+*O$}+x0 zs)d*Q;Q{v&lxynWBLA9jahaF zs5O|6OJtYi^%N7yZl}+wHY2#0S4HNR$OgBxu*>2*Ks7OMYky1J!79=-KwXv$mv62s}HD=Y5f90gRKNn1KsDXkrS z5&50j*m3MedalZspLI}GRLUVW7tQ+X!mWBD=8fA7P|WK~|9`~lty20~%9lD@cdpuL zX2p@_)J2A7s%0}^u;jIbW1e*k;pGbx??`wC;F%?kooUV7@eVJ{(Z{40Cn^QqbaULz z9M!3_bI5$&I0nW!0G)1^dw=likLBz4+E$V=YcMZtq`3*)z5~_@dQSFVqFij6g0>R+ z93lWsGZPU2e1ECd`dxo#epMf8oqpQf14n&$1Xm)@C6rehz;*h8F+;00000000000000000{F3ey_Gi+qnHi00000 LNkvXXu0mjfCqLt+ delta 465 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 delta 538 zcmV+#0_FX@1iS>0Eq_6Bg&+(-ZKpT!{zu|2T`-@?BoF}+aQ=IXj;26D0#Ran8~^|S z003_%gb+elZN;1T9XM8U{p1+DI_iHDbV%=<=jlu0ZIYblnJ%I*N#t*3d#P77&Z<@| zZ5PL2sjiPz9ZxvEyVF$!VwSG@8>mt5>zOU8KP^7JoJ|cn2sGt*w=k`zxzN ztNTiG8D-(%0BoL%o3@(bp*1lk1<9nT602(2Cs|0zm{Cvuk#9jV9V=n@;7blO;hJ<* zzoMn;)_F;T0RR91U@uAqiOG7qEt&t8Ir1E^8y!xce+HZsfFO`Ud##%JZG0EYx@O6e z^i$ocE?L`#Fn^;Q9q~&P*_Jg!-7(|%1j$xRZE;jyv?_I&7l3*$BUJAK>)$)>d*TVP zT>wf&`BJkxD*8H(Wz&anHhs?=D)xHx%S1%)fSW4SY%hm$ULXBL-&)QrJ^ZEQa?e@Y zTDfp9wbls~os9RVk#RNNpA0cr30Y_*7fvPykMbJ#wtrS#)LW)~>3q%1cc9N%s$^Cg zYPU#iSBfa14nfL~H7CAwlBzj&eKj`u*cDy6@NW-xKn>Zy)7s5(qu4P3k;}3YndEU= zpQWY5*AgUt8vv)X`8nm+pg000000000000000 cz$*R$bQ3HhL|X!p!2kdN07*qoM6N<$f(sY-e*gdg diff --git a/tests/snapshots/nanox/test_register_unusual_singlesig_accounts_Unusual_Native_Segwit_0_0/00002.png b/tests/snapshots/nanox/test_register_unusual_singlesig_accounts_Unusual_Native_Segwit_0_0/00002.png index 2ca9ffae4a68aa4c1468f77d4bf0b475d9fc22e8..558f45a8f3c5097cea3f0b999fc0c772f2a18fb4 100644 GIT binary patch delta 496 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 Ef;uSf2mk;8 diff --git a/tests/snapshots/nanox/test_register_unusual_singlesig_accounts_Unusual_Nested_Segwit_0_1/00000.png b/tests/snapshots/nanox/test_register_unusual_singlesig_accounts_Unusual_Nested_Segwit_0_1/00000.png index cd47be1a7055dff53b47488973f06a8952d8def5..8ed992b5f16cd1083b3e224aa6875aeeb6ac0606 100644 GIT binary patch delta 1000 zcmVElmLjnmzT=DgM~+f4gGEzO^tePFf<0WIIG8Gm$r4$U3Wx^7Xd+OdRO zVWuDVPKekF0E=<#XD?^Gzp|3dz=(xMy4j{eQ@~WKYccj*WI~XL6{8VR*1eBQbaP_% zM9tQdW-(O82Eg;zF#yC&9uDyrUI=}j@Cq158#|hp;e~PR4h=jLUc8ElS{~s|xO0X3 zzIk4SjB(Tb7JujzRYpl2&BbObel>Ms+i=js=ME3{9uS2Y5_4C?!VlaD_8tvhBfTwu z0*jW1s^78#c3qW=q9}@6arXcb$GuB`F3Ovmgm-w*xk>XbGKz^aXjEpgcc$5y`sQc- zbp@T(AT1elO;c57?u3`g^_Q$Qzledfn%S71N@CrZbAMbnfjf}91}9{MZC+2k&wRTQ zyaGC2EppK?^3k=(BNrU#Q8XBJ>ES7ilzY$0Uc%oCGKliS&obKM@l|b6d}J z_${~cY#V?O<^4`31c5_jN1X8Vfe&v`I+2-1^_eeDC%0od+^Srv{)XilT@E4jwvT=Ox;N zB!4M`6N2XeUyJMupT#rH*omiCJ5ijbwUt02_;qSPs1{I_9ss5Z_9E8c{~zNUN8%b1 zO4Q`q(l+Z7oG9ILy+Q*p%>^!+VyY!8cJufLIAg5~@1YH&iZPhE2~%%JNBz4u>S=8_ zGu)h>Piyh^khK`GZO;RAt6PR4rwv3)EnyQKgS~0g$xV1;OCvY~8pW&2Bs*6!xY1fB z^G$eM&St|RLC6F?p6OPpjm+suTP}PujfCI9U1#Udqmpqivwss_i(yrfHg{X`0*lgNq)=F~)ekUi0tyvBp#)Rnf0jOw>4zLpr0DsD85QK7Usn zU620jmqCI~zZ#;Su7;Vjte?KA{yViKKV=u40m}rC5p@2Y8h<;?v^2-2EG+?Nm>S2u z10p>GoM_Uf&hjw&Tc*(f;vxm6&#FRIKvgSiA^w~cmms!WP(M;^+(Oh6X^strtj}`L zEH0Jl4zNP@A~<4_o0s^L`!{xr$_$_#?zbeAksEKQjk)2MI3UZ5Rk2XZqOu83&gFjY zpJ!p{U%21m3V*4jT+P{L%f2o6<}Z5Ap~E3@56FTK|4Ar(!_u+$Xz(PpZTTHobo(t@ z{khR^nx^?4%u^6M1zMN>+Fq|7F|EUc%uT8n5h}*cpjny4)~Rk+>Z^atk1NQO2IvV* zG=-|v#0f4_YcE(UzKB^lHOrVBN^IV!V_cf>8&JCj7k^}!Z&pjKzj3=9e+EpfTHvHX zq_dt>Xq0b3FHV5zBhe7)b8_1>E5m)p|?N*Cy01 zZMgGF(SOA3ie2}?lXUc-q@({NGWu~g^u#)HS&!E;e`%c&t+(uzQ@rYcBQV_dmI(ue zR;C}36M|FMDWsZL<|$2|S=z#qEei#rWGNRUE$zK|I$6ezFBAChHmr*nEy;#r>32cW zxk+{e(U?wEbK#Qz4$&nApTkv7?Q(TY$m||-%zrYpEf*vQ%Y+ur_2Hr{&D0#;cW@ud z-pU9__RN51GrA0LHmK)<`>D(TtA({oHVcIF5eykJ?r?{%?j&yps9W4i`{5?O^K2Y< zVaAkg7_?kfC}r4zN=@rJTy!>hM?Uv@`OJe%GwBX!nx<*;I0p}zu(J|vYHH6BIDYX> zXMbyf4Z%}*svDcJRLelK)3kKdQiy!zl;gD=Rpkxk6&cipYL4hVCBi{7Yeky_I?{Pl*`Ic_xK&CIYkJCVvw(yv;b(B++4=qGWZc8---K8As;pD-q!GO@DHq*Wb9~@ZNckWccP5 zaD{1)Hu^+t1!$u`yTI%V$mp-EB-=wp;hAB!s4!#(c@bZ`nGi%`#cV;8_0hLmcz48m z5VPGiy%H^B6QGUPHDQQ}+#KRxXd#qy+Pv@zn5WtvXj}#twqti_;(7eBh0`6`Y&eE$ z=P=TuX*0UxI)C{q+9urI+l=Tj#zY$XinwnXUmuw#bONFvxq^1EGlXx*3AS`}o3)k& zj|BHEtXqz2II;qErOHK76vdN}&4d)2=AG7+)N~SU+V+K18n_1gYafSq=)SWiaqMD`FeZ_LfQVTRig9t%O-zU?tY zto*e2Rm9QYmcNp8A+96_jV%%2#V$QJLstM8Sn;}`Ms8gb{lkXqeWS^rhPudYExaRb zkvYnLsecnaLVB#!7i;uGES^4gs{3n*iE%;+&{UkEqR^8#gIsfP6h6HEjTlc0k-K=( zj+>=j;v3iT+yH(!7GJl`cGLb#|ApPote$K*xq>LJUz4#L!Fs3LXm@J2;1$prC=*`H zSG9_+<|h3oq%m#Atp9T^tCwm);6fusF0tT6~h)6veKHq1MCA(Qy&gTs`wA$s3%gi7e1r{6MS>ks$$Py8e3K86^$7D;}` zGhxz~_|eU(&gP76>6|YSd(qe~Z>%#{8(#sM26tI&);9fuguDgT&+oVoIKe1j@cl`v zmu&1B8IbFZEw)sS=A5g6gsRhnjYoz5VDCn==YGz7WU8UYfo#im zlu$xEW4?C_sdDAHfY!_1)!fi&@tRly87S!XO8ZKyBaUeRFUJp?_R0)q`fu7P)83g zf75}^xBm4-8yj16Et^vc0^Ky!R_^9y0Ghpm(`$=3IzVN!V zR~t4uxQa=}>A_~o#SlGg*g|dS&QpC*6h%=K7BMyShCg>f&@@O;_;jO9#G`4k&D{5D zw|^j(P*~jQ!Z#dOgN$BH$L4CT(MS-`jhMJueg1Gie&RpD;bWMAbCK-t_)eJACH{1G zReSf0u5`|)h&^fSA#cnx*BhS!ng@4UYtc6SfP~xy>gR8q2kf8=7<_%w^pb^DBMowW zVVh0K(VTr6NJyRTEPQ3yL|6@V4@0Iyf>#jN0DCnWNABnJM@9`bUdWa#M+qlnWQ^x- zAy=+FH_&Q%Tg?r`PPyy4N-4G0_S}AkX?mnK`q$zp0j}#}Zz|1b4pC*AhD@8oBS zH%42S(#%#Bww9rtQpRagnGFE7l0C#G#k%+H7CD^iTu&GF)>My_@iP~Ip1&%=5L4N_ z#lPrnq5GL$0W{RMqx~{|VSDeM3cTEZruxP@N)nEty>l3A>1i{DlR9OWUJ@?vG^5TK z&-qdn8=gU&FMrtZ24EJ?T|v!?w(y2KLCQeethFro?B2RU$}Pt!dCLm$On(3X03T`sTNz6tzT8e z#Au8B%T_fM8=5p-4P|aR5|btGCmX>ZZTDD$ER1 z?PND(wqtC*zKjE4R|2GDV5ZnKh17BKr$>VaXPr)F3#P$2XmAU<1HLx@{rn{%BT`9yVD>aj9Ij154`WrqNWS#I9q zFYXWQfZ-J&M;rGfvUr1%#SE1d9&)SQe}=xzedsbAge%u}U*qRh*)^^kZ{rH3q}|O` zuvKp(w%J&X_kTTb?f^vZ0i(pHf2AvY!`88+q1&wO81a_?+{9Qd)lrPiHr$RvNdbv`GkFS6CV5 z+Ij5~Hd!ruaSx#ZaQgrx6O#o~6-vk1$B2dqAY!!?b^}<8{1)^IfYCUClNj$~;-7?V z(M?80RAv4Lyak!=wy(N}f`uz`tv0;^@c9xGPhqN>u38m)+zHt7i#k3n@m)k)>rjpi zxH*CItbcsbDr=j1-r|l2jln`w9aRr<#QmIqtkoH)BClbuUFg&3IGJPcQmlJl^-nm5 zx=(_{r2Hz9Iwc`MX0)4nRB`etOL?zU#3b%@OkRlAUdNWO-2f;b&17sUZW4DB_R0mh z2_Jmj$A6>tXRiSmWw+^^;MoJ<@~lO$R}9GIQ!R5cgb+dqA%qY@2qAB_w~+fTGhn2LJ#7JY5JOgs?k`C;1qjD^C65HF)%@|19W3 z&W`uKUUK~zOT72-;3|wI^1rga>{nIJcCBirO)3G)?&g@?0qPn|=jBo_Nzaq*NDez5 z$Fo%`XZuw((eJam7nDK}jcHd~O~ zG}XqcYR;8xR0_uG$#3}cPg zT`!C0EWqLbtophu8(K*^s^c_US*ha&e<$}OVzV)%eP!!d=4l_t}H zjYd9a#rJ@wX1-y1sONt_3@md&bFTbdPa0?LPM>bL#{LDk^sK>G(p%8z#}GAf&9;?o zJ^THy(y&uck5cxNWVXY>#Y>6NZ_I;e@c(IAo-+UW4u4z6(A^-pY07(Z$PDHLkV1k>7!z=&* delta 405 zcmV;G0c!ru1J47HBmtI@B_w}#1Bwnh2LJ#7JY5JOgs?k{C;1qjD-QkQIe7G}|15|h zN5^|#FS-7VCEojZa23W9`CnOI##NQGp;gVaNhM(!ZjRXvfJ@E zo~=?j8&}m#o5+NFG8|%j2dEU&Tsuqte`S@74qvG+Rv8*kz~O80(5-)_+;mOYEJ1S7 zR12%BIajh#DH*FLzvWwyT#i*?_){-&Nr!uuqy8&eh92#gOc($F0GpL|AQs1U;x+MI zFN^0)z~Tg~V%@bHTG@0|$LVfmrH&i?o!qk#o6RAOm91m7Cpxdb2|8L>s?%&$X)>MI zXy$WPd=F@9?l(+#_56Q_f#qJ%oNNECIa1l}{{Hh%rMANU3Apsk!B^5t(CEhyHE_+g zm1RBq{jbunQ%^)G`$;le=*Azyjp2R6HMqTx#RRrzw#EtF%;a!FT5BBA(^t>Ic5h#W z_G%0=b8st$7XSbN000000000000000xXmx5l$<<`Xt$gI000R9NkvXXu0mjf206Yk diff --git a/tests/snapshots/nanox/test_register_unusual_singlesig_accounts_Unusual_Taproot_0_0/00002.png b/tests/snapshots/nanox/test_register_unusual_singlesig_accounts_Unusual_Taproot_0_0/00002.png index f0ce5be134b07045fad55549cdf66a0c92d1373c..55b6b899bba508e3c0b0330ed7f7a2b00814877e 100644 GIT binary patch delta 462 zcmV;<0WtpC1Ly;gB!90-L_t(|obB0Lc7z}dfZ?>KJ7NDzVlRF045c9;DiFu{zb8kL zs|0040001h<-SH`6k`;T5JEauKeywa8*3>i)pKfbyS_(dq`E#C+sGJWS;T1}1mE5l zk)M@?<$c%Fa+N;)EC*GMO1h-xqM3i0xR%e1c{6MVC}#b_i+@;nW`&@OF7~?_ zqZ)ZOE}84iz=0V&0F7p+XTP)ddHV9bwiaZ}9L$RK6t}>z?*Lzu*2(ru)DSlfLANq> z9by2gRt6#fz<(bVf8&4UrP}R{OSJ@_rPluPbK1OWc68^x?FuZjbT3FzTV3W$ciO-? z`byq23EcOh{h3c|c~V_EGy`@+mhU8Z+IK*{<+&ZJKN8d#cTXFDoZ5ym58QdK0f$`t zhv022ZeIRoxw{@Ta_CHK-hT9!D|U*z&%;$Nq?0y^*GD(GTH<|rUlvxzrPW5Ex9a^* zz!-RXk0|t1Z?g_R65R^`000000000000000002z$3-fi8fY={iiU0rr07*qoM6N<$ Ef_6gKz5oCK delta 448 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 Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_register_wallet_accept_legacy_0_0/00002.png b/tests/snapshots/nanox/test_register_wallet_accept_legacy_0_0/00002.png index f9e9870f1d0928e55a323c1751fc68239dcd5d86..09dbe4844e7cf8fec97d517ea7cecbc26126b141 100644 GIT binary patch delta 667 zcmV;M0%ZNJ1+xW^B!7BIL_t(|ob8%ha=;)6MQx`$asNxoUiy)#V*wE(sA=!{G6_Br zL?$T#000000I-}7uZFJcN-5=>OPM_0WlP1DWY9Q6yX*4l)eu?wg6|}+>*8HJCg;3& z^;1e;D?6*#&N6c%Umm$qiB`%dVvAz?T)5Rvgx$DV06`pI{(m7!vn7;y7WvXVl3U^c;c$ znyhq0003}0mVd}^S-&%N`8B&6eO|xepSoQ*;H!WKX^EL$jDsH)6Wec+1KKRxw zxUl%BPfa(1&OKnr{3m_I_PBeKk!ceFDjYiS%#6Ls{81 zDO`6ft6yx?cY@Rchy~q+*5K*`jR^BYl2cAaF8oZ9dX@UjPwX^Sj&x-TWt>I_&=GK- z^Wo@$e_d`}0z5l?*7ToLK=h=9_Fuh@Zv;BniL)01Lv$7yItb;&qKHGD1<00000000000000000000000E?4HQO*-p+a}1Rwwa002ovPDHLkV1iFE BI3fT5 delta 662 zcmV;H0%`rT1+E2(^b0001%^X1sqbzLc?oO3CY$GdE)*pdtyXJ~gi-;QmOsW12{d0iLp;xRer zjkBLp`dQpxJ$Dw(iF|qFMkQ7$uZS;-?Q`K)J7o-BX7ls_f`2%~{31!(5{jxtzO>m| zx#UMNDq6ZDgN%z*J3YWC`7GdwwQ3VS9+5(>FP>{T;#O>o;9_^cO3Jddbk7A?Yj?Id=w zQWBG`%qUOQk(>`ns3{pCP7&6#s$xY_7(Pvj^HrA>Q;V;<%S4x)siF_Qr3DujA9dAq zC+OS*hTMNLR&2lh4|#^Ak-MyC^t2GfUE52zRed8avwu$@NidQAO?W6JyC8oXfo1lK zkNPS|J%D)7U1$xi-q46J-y}I@SLDLa45?SC_x!|mV`WQMR3QIQb`9APaM$^8^n-t0 zZe0RAJAKylzcfI!QbPN0J&*4QY_JpOCuY0%}xXGHAqsJN*c2J8BbE3;O*=bNb7c^ry=Vf#YaoXIwT71 zq`O+}1`x|iLGOJTn?FmjyTSpWb4 diff --git a/tests/snapshots/nanox/test_register_wallet_accept_legacy_0_1/00000.png b/tests/snapshots/nanox/test_register_wallet_accept_legacy_0_1/00000.png index 31fa5daac554daf1cc9fdeb7cc96ab9d850e0b38..481024b040269adcf552800fcb6ea14ff7e473d1 100644 GIT binary patch delta 1000 zcmVCRns=Kdb%ano0`3C3@CluxpHg@W9u2f=t^MJZ0Dq%ZRdC0e9VX{B9w4qJ zwhJ4eb}*`dmTHs1=h|^@G<5O^01+o2rk69;pN^#7Pz~p(I}lH{(1wW8mWiPrpt4n@ zLn9-g87l*cDHrFl6kbDYZoV%&6!^%_9iSpq^^{g~xfr%2yeXyfLsQ~)s72V$p%Hu? zzVfKI=FB&@M1N0r*I}oilXG^M$;=k|whfT$wZBG+h`Pj;nf`#`upF#XWTy0DuGQ#;%h*9ok?wp}ZGVkOr>5x;s|HiT$eF9th8&=* z8J!Ph{WQ66ag*C_lG*JGi+Ulf15y*Xx1wpprXj7lv4d0h15rb5FV;!9GzCe(n-B@M z{v2u^Ut*VSEOP+E9oBE=Wzm0R{WkPM=Dd(EdSqc*A(Ep??8I%CR?^Du8Za@pFmlNC zW^8=SZ+~D50Y1AVFJvyABYr%t^@d&@7I#rTc#^XIla%$J#9DvlJK^4kd;XF?@u@AU zycw%TbfS(nmsb-ZbHS2kG38G(d+`Vp*;cptWHwZu?+@a;UpHm8cJNvq(j*er$~{P8 z&21b+!bw60*q+>{irSJj8?8E%6Xl!BW42OzE`OO}g_CFFt+^nVH-8u8#(fk7wk_k) z=N$mpd}y@(-r)OJJ76=sxfhO%!~t?pxRW*B07Nz2ay4}-qH?m(P0ccDM<{(jGI&iG zy=QmWZcqj%EN^A(KVrplY7J;DKIjxhQG9R0Y$(X^fdd{+*SM0UK-IRH4T&nZ+gTtg zeSb#K7r83fe943mUmLOlliiGRinavbvU^9jVI)mv8$l~q4S=g5kbrhU(Rpev>#0&; zX@spsC3mMKbim1_eJ;~+Mgza5p_roJ+NNnvtjQ!2upA2w&3ZSN<16K06mkeYuVFtNgn zHo-YX>!FL`@2aQP65LiwU^1-hd1}l)7%MNCtp4$%3}H_j%Nh7C=z(x6ilQirZ_Hmg W#I6~zK5btB0000mg=wcd$^Mt*z4XET8I3MS2e5IP=zDUo z5VAmAWT&;FD2k#eilW%gFL3WTj@H`i_3GFC=Nw&$RV8onO-Ku`lC%}Aooi{&X1iifTA3g-krzLK`B=S|)~ifXZ5t4JT9t zG~;Eg6tFUhG4SSLck^x8p)eHLc?YN{WzwXAHG?T(^nc9Bw4n}A-aN8=(_!*=3~qAU z%`>}gVO4Jk+X1Ny+*{E!Vl$D}-ME9(?gy%d>MqKpEKNZY@G?Y#y+4PV$1m~AHZJP` zhC969%*&tu$op;Rh0J*&-}T7CR3Or$O6%C`Rz!m?fK6sMy{*#pVpTv6q%6G!O4fp&df8tYHB)l1GMs%W%HkYf3 zkhx$ zpDLQqGKWTBgyWz3FH_JCyYHDUBVyTf*aF*sp) zD`Wo=D=w$jfY#!JPEi!aXOsL>9(-4lW<4V@kW*B3o7s@4a=V=cs?rB^+u}15Hd!*1 zl7I0vj^1Umn^8{Dmf%}<@90*Hw8?BEUkl@!H<=ApmDjVLDg_2|=yz;FRC0H&dIy|L zM@c#W2NB;Zceqvd;*ous%V*HKysF*>aMC-HiMaS2;LhDq=cUWT3V3*`q_NFTHXs`N)u0etB7&xoPfIk)p>w(M^a^YU00)1?SCtNlO#a4b_Qy$$sD;p zZqJZBoc``5nKbhJtcYSV|HoX zl6CF&0&S7t^-D{PduG||_B^9o1t}N+38A~PcCV#IF@MBiQl2pnV&_jCTz;0hSww1V z-5t4YF<0Css%N~Nmo^JxZ=JS(t*?bk4fz!pll3@mE5OZ)4u^nUsS&jpkRl}1A{at@ z&D`^z&pXnf;(`>0N^Q$Q4rgUq^OB) z$YorbeT@A6PL`|o#4&pn>nq@qLU!>^R*7$%=NU-ncUE~Kkx1~E{r3TKiz&BmLnmjs zT7Rlyr)A9WlvEkdss!@zs*cw#RS;!1f~0;)3a+jn((_PrJXkHL7$=}`3aELsK^a=S1YRf!necMM~mNjaJ% zc9R%Kmd*_vZf?#UgMt69M#WH{?pCr6;z-A=H^U8i!OzpX>1FL~BLk4aWUQgEXZIx) xF#BxmtDe|K_J719V-S<-5{X12kx0B7e*lD+S2j#=r{(|v002ovPDHLkV1gwS(k=i1 delta 968 zcmV;(12_ET2i^yeB!8tzL_t(|ob8-jlH4E+MM)|<@&1?Oz2w6+L_x1Bfw8+w=VPkd zriBm^nAx`e+HoBHb$^?q8{wwtExZfr;i{JWgZ)!l5V~=3 z6x0IecgUOh=pR2cG9G%Xv3VMd7yO#^MTkAbaU~&5sFcj&~liQ3lS+gMcOh4;6vboMoLq&4wtr}zd5Io7=n`~sl~vzAK@Z&h7B@&+&Re_Crg?Cirw;$1_84loVVwh_ z;OXCS8{fTW*evm3-$2q2>2GF!M4MvrmC-MXqWEr-PeH>oC3xyXp3;VmX_G+>Zkp+Whdx3P>y|Gfp61li}YQ zYM-Jx6n`=jrH@7H%L(td=JKmhgIv+yh7jtC{$^?po}^ZxCvk#Yb8ss>yp9@b=$G_5 zZzdjbCq1@x814Xf8&_#UZgW9*nS2|S{Sb9ivyXccYJh8;Gme465ofm)(G>se+~heW zHcR^>CaiXn>aY9xZl?E@6M)y6Ep*$acz_Ilntu`?dW)(ov|n-U($-M$?aRT9Ac0Vx~|E8PFfxSgNyWgmlR>>w+oX|6pHQkgNF&rpdt-=wNH!# zOJ{=*JNt6yAolNSL_#sWThBUx-)G&4J3-#r3OJ-cOJBR%@G)?CGS^Ygvil8{(d^^7 quX@18isFGe$fHe|B3W z{7slRX9sPbaewpferxD#E;T!NSr2=guyDJ#vAe2lZ@c$^ERha3w?13=;)Jlnhl@J0 z`$&El^PRFatXTo6j06Ax;2|tK1uelX%LEUF;))x*nuvGxi=yTFTibR9jvTs7VmwDI zHWgA!TyqfTA{LowdIs^SVa(YQI6eu1$w@bVS`)p~E`K#kc!oK@7R2@HMt+HRN2e*- ztU>a2`?8j*X2)HP!$V>`^hm4#S8}XN&0vhJ?rW|idJ)Xv*Md^T)hsiKMZfiqTVkRZ zXD~S<*3PL5sOmeKNd3B{hYUdT>}9Js*tf7^t{9yndT;FrMt%JtsvEUw<5-;f1i}?s zUE5ksTYsW_=A61i`ARFhYnj&vV4y%d>}1xlWrnA$CSQMM#e2-Fdtv}iZp%WTxPy!s zY~|6ztCQ*R3UBXe2pZ}cee?irMb{uxbxOP4Hs`9{%9@*S7UP1G)zJHFK)-IP!L8zk z0EiJeAL4g+lGoar0ufJc3{2>MLoa|T+n<(&pH>opkL5!HAohkE%dt1?0nI#PRCKuv zJ*VoXpO)4V44mBO#lRn{YQ@j2)4c&0H2?qr0000000000000000RA_>&ASkhYCHA@ P00000NkvXXu0mjftaM|? delta 725 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 N002ovPDHLkV1fvEXlMWc diff --git a/tests/snapshots/nanox/test_register_wallet_accept_legacy_v1_0_0/00001.png b/tests/snapshots/nanox/test_register_wallet_accept_legacy_v1_0_0/00001.png index 87b4dfa0fcd79dd1870bdc60c0d92e4f4b667964..cc2d012b6709decb341536a534fae2f5468252e5 100644 GIT binary patch delta 429 zcmV;e0aE_a1JMJJE`N4}APhiJ+tZz}|0S`Pet1gL1R^*Ab^7j?6A=(JI=F2B006+# z<(zZQSNGycJ_GA2L%(qSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_register_wallet_accept_legacy_v1_0_0/00002.png b/tests/snapshots/nanox/test_register_wallet_accept_legacy_v1_0_0/00002.png index 524252318d3bcf668f0168ec2beb7bbf2390bc4d..4bae739fda23efb460facb6abacd53c22b584fcd 100644 GIT binary patch delta 605 zcmV-j0;2uy1oi}wB!4|gL_t(|ob8%Xk^~V9hV9ng#Ql%tF8eUGDVq>M(7OKbX}SfG z5M(+800000006f0<<(G1DTEMXq~GlE^V?FfCb>w@rQJ38_G*Zkp70%HN=bGxOpNiY z^+O0hJ3Gs5XBjz@r$^~j<`pVpYq8kA6t1y-n%CKqf8@12n<+-*NWQr{m6|;1=0k?a=Sr+Y+`XS1NhlZd>v2-7T z1FGx{L;wJA4S$v+;I@8e>dO0e^B9``Ba4PL?7-In1Nn)WUX053iVf#ZOsNQY999m< z7GXJeg2+-RNy=K5RHp4%{)Z*kl00000NkvXXu0mjfCGQww delta 597 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 delta 968 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 delta 749 zcmVF1DMQNuy@&1>@Ui#q)qo4;u*diI<^W|Vg z5)z0<+EM@j00000Nax2dT5Bz(9LLd~+s7D9iKvR2OQY7>bNbnwF0Cjx4Vt|Fl`Y22aqHYk=UtF3)_F)JwTK1j`oM1>?DnBT zyG6TV9J*mNYC5MJwhj5CQ5LVGMGvTdyz}C~(X@Gv*?-L(w?5^z_>uddc}3f&PMTLH zfZmc%eX+ivEuIrKH5ax{kIlB-)p{babQLj$=Do9+Qh`ejt3y5haIYjLDFFc&c@C}` zeI7kp`uSWj%9N+qc{3n@I1lbKRLtC5xwj$o3E+dy-v9A-4Q=Av1tBd59Dl{5l6*Cu z$Xw>_&3~ue6s7s28cL4HV-q0TN;V(Zt>4EMXEx{H;e1LJdM1M)BL}y#A-we+?uX$M zmFG(6D~~o?zxL|u5u;=De5hna&(JZW)HOiFdEePBs`R^Ma;QEn$8i=nmtVo=5(GZ<7qKUdeEqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_0_0/00002.png b/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_0_0/00002.png index e2cc15b3384b9fccdbc715a1ee68ff0c82fba204..55818a74a1fef21a131cb8f4f9078d52899713c5 100644 GIT binary patch delta 650 zcmV;50(JeX1+)c_B!7EJL_t(|ob8%HlEfegMVYC&iT6KJ?lOz6wroH|gBrX3TP0CJ zB_fg#0RR91006L@pD01sbrDfYDPObO*R`i%t>&bDPF2_BH%btj`b_K~uj`U3hDj;y zoqZzuTdAy^JI}~j{d_Bp%B+%$*jiNO%gQx5GuBPm3Sg-HOMh=j8!aP`GuO{DYi}-l zsCq?@I@Zalo@(0)aMm1iIBKiXgu@-9XiG#I;N>OC!PHi+f501kbm{cwG0O$r}AqEX$MguJk$j}imCe$ z3{YjIBLV<`1Ap)Ye=FsL=)Kccp4fW>*>Bi{7w?vKN-?LBoV{wKB4i+33ysT6i@f&B zaVllQGrmU1$|NRH9`w|)@>%#HoBOewu-qS;1pk)ar!}_KJULr1I&Z`jUJ=8(x5(K-t@GXh z>FB|q2yC#EcrOI}G$t7~n9928y*`mewVv5|o0W>}B*dff47-`kF`oDpdD2R?CuO7AhHa-e@%~5hE`8Xk;{qZYlw|vVPf1h| ziKrwg0RR91003~DFGpFWl$27=xn7go*R`c#ujZzHZdIrA?I?>3eZ|+vQVLhGOwKuQ z^ixVdhxN5%XR(~rueaQ(#4ELk%tcW?uiTSU`{3m^&lx}vyMLJfNRqXLYHF=tW%k}& z@=%P57ImbP`yy533^3MQ3piq{)`iO*^L2x>170(}&%D50s$sv`+ zHC&WWwjaE?9lZ%jQIJ8fFX?kyeOv956N1utWlv!hv8+2pP6)luTQ^9LHvWmg2a)(k zAz)`P$ne2d&JAyQhZpsFrsr)=D$x5i@jFqxw~u`9Bqm3mLkIKcnUxZZin(vV#6 zB63Jn6n_o>^RX*>806IxZ<9I$ERkfWh)Z5jbYK$1e~{rP_5A)9^wjr_J1CkW-T^J- zA3E{kS&D{i{5$&C=HYp}l&uU$p$)YQLpIgcSJ5+eK|GA|uL8XyUqvY{uzV~hgUo{u tVgLXD000000000000000008jf7Y{fW+{c#hBMbll002ovPDHLkV1mdBJo5km diff --git a/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_0_1/00000.png b/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_0_1/00000.png index 1b89108a028718cd05e5c1a736cce5096dc42bc1..e78d4f6d5fc0af76d50187d885790d50f59926d6 100644 GIT binary patch delta 1011 zcmVyZxktICpx z2rAe!M2$wH(P%UpjmG8p6?{96gNR|P(fKD*^CXxAUjq#01)aTD&YYZ~1yn@zg)0$wtAFTV`kHo=_jBwZrY2g1 z4p8lkBA~h2VDOoCta-yg9sxnb@xhFC#QNn(8ic}~J#j%i=|&wQLR%z;Mu2iEPX_`c zfRvR3jwu$`u@tz5vAJ5pd}R@chlLdSvApL zMQ(papP@!^UyMsA!R8(xkPGCv6yB&+^&Vf zEfeOiQ^GivC>E0AK4!r+Rcz2cA(e}<6al7D(sdcJss5Bo(cmJ4-{7>1eNs$JKusrv zD)w&P#}i6F*W4$&yui*qpl1Db%zF2uP@e#Eg-y?$=C&bxUvqw`i%h%(t7Xl`ahXrb zIqy9ypnsvEcQ5{$T*!QCf%6)e)|#-hv6XPBVmS=PZ##JI5FKEQhxJr{u|U*trL z&_7KNk=m*$nwZf{&I0ZP=rNnN_GrPLo{B3K1%IwN=i^f zD!!&1YB1}g!R07@|JrxkdF0{w+u29b^Dy@}Vvoh=ml*${;dKeU(P%XGK$oBBXOhAj z^?&O?z}zDjOb|Uce$pxtHYm+`X+zSsjt~CcR3ZEW5wY~NeU{3UICauZ6&^q{;VnPS zsFh7b?QEzaavVJ6(O$ARsNlL{XZ~e|r1xOHdW7DqsYBs8?FlZb@hHRtxbkeP1tIbZ ztKo_h9Zvmningo(D75mg3N%x^N`?FkRBQ_^V`&3i1~LaXS3`x0+l&67XRK6DWAb!F z=)bFpZB*U>5z&G(XsN@gUxHO5ZPRk`b;+yl4dE*>HPWdgX%YB7{uwBTW{te@7mKd; hzj%C=B!9+9L_t(|ob8-jnj9erg-yQfr1!t1+DjfPV+cp!h*npnhySTA z3W(x`>Y3Jxq9}@@D2n3k{BYhK$I)7QyTNvPT{h6h?Fc`4tjv;7rix*5q` zke@|ymRx_2oT$!gkq^;S>mpZcR?d*QgV+_2BPEQ9Lx1ErEwC>0xb6@pGu^mdS~RIZj`78r;J;DbKVG=0Qvy*Q(?q{Nbw^5u@x6kB3Zdb*Q=t zrwt`5%nrad4}ERbB}-Z+u4ELXp<$p9r&i&s5$fiyO!4-7v=;dA}Vcz{6 zfZXorCfw?*`6r8}KCuHV_(^%?Q;ahg`8|;%=zwrN@%KDd$@FJ6OpB_wp@ba6{HXJB zw0-^HciVpC;pexjx1`rG_cvmXK({n)z1+D3s4qF+T%ErD>KHz-5>|xMDdQs!ZIT^e0EgO7_&R9=3@6cQw9`(hDG? zT1h57br|_eGHZlBO($QMM%BF`{7$A?I<+ND!ms0>K{_;Z)r-F@4z=$#Qj4M}if#M` X$LH>;hxxN*00000NkvXXu0mjfi9hld diff --git a/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_0_1/00001.png b/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_0_1/00001.png index ef7366d45cc9ca2bbb546b582f1dd444b28e7b18..9de81fc3f71783b90b06b80d21de2d35373da8e6 100644 GIT binary patch delta 1029 zcmV+g1p51z2%89yB!A*bL_t(|ob6m&lH4E+B&poQ_dk;Fk`GrXqDQNRvB%y~e|ZKW z3B3S~cUvnI3WY+UP$(2`$1iVS-}lzqwr%~nf1F0=qq&Vkyp&PNRg`*SpXJ%1GdEW; za?tqAtFpxU+ds5nJ>yVQeiBT;C_raEp|eoZ)bRM;T%AeZ@qdR@0z|7IFk?-}$nlJ$ z!_-8J(1EEVQJ8O3n@m1$Xf7Z+f(-DiKl*uGA!GgNOzIOwID6tiKA9ox@kuG!b9B_! zQ=>5%(3F({yAUVqSO{LjIdg~U-VH@2ci;e#p`P|0nTeA*OM>_Gs64jX6`IGJu&$vV zcp9EKyXLtJOMh+AI`}3ec2Fhgz!4pN^W?>c`z_#UrW$r$Rzq(S7HaFz(ZS&zLxCFZ zJs=Ba!QSZ&5MRA#U@Xz$riDzO&>xQTi^3e%WWcJca-mQt6z;^SJpgn!JAu~}1YJh& zz#1MWOc9}yfP+Uva=QuME-%hSf(-NwaQ6luDl{3;!GD|^(yTq~1s5^l?bPii)t~U> zlJ{yxC83-5(WD${%qEghgEv%s6V^2(G%MMM8tH{BuW)%%Mh?1C3H}ESE_Xak`!M<+ zNVFoZ1MgRon^*T4caHAiTj6MUAgbIetVSzY|*c_ zeoN~AgwFX7^udepGpo>B5E!|9a4F83S65Haahoo+`v7y46yde`^b*2}cxeA0%qk|q zJ3v3Aq%fn52&@|>%jyRF3TC-C;hk<7GSC{B7k^72g>mG*uEi!K;!EOH@M6vTsGmWs zjdL|yoz9F1oE+H<;J*w%&Sbzzn88Q}CfRq>B6L@yHx;mGk}L}*S7sc*H)+2dOq(6O z8@ffW6sEBI4X;(9w+}B*o@BKUSf8s(kjN5I<;fo!apRLrMAN%^gT-W@*@Rn^KIiG5 zjDLI9vMd8?S6Gb2SGX7A%a>m$6utq}yP>)-)Stnwi+d?}qWN2PsyzkzLRvBAWGS`; z+_PGF7{LvnaH4ny4HM?=eh74jQoDEJUlm~J4%*cdM-JklC9U8w3|V!Hdx0M= zZSo!2E2gY~U= zNCWk;`6{sN7+RRaBmP2WE#4CQg+ifF_;&mSQTz2aa?l8K00000NkvXXu0mjf`se$u delta 1025 zcmV+c1pfP*2$u+uB!AvXL_t(|ob6m$a;z{6bW*tq_dgPM$p;meqovhefMG`cMX)T% z+H7lhuarb0kw_#GiA3UZe1Wlj-%Bamw$$A?1w=)h0l=E=dg}Yo`on2dCyH?P3IfO{GlV@pT}sv*ZMF5( zC}ai{Wo5t-W2T5P;ME&5cbMzdN@Q}!4iHHyB!y%elQ~O*_w>D*Q=70ZqaH#Uua0A4 z9%C8SwMFa58-I{k!Iq!{M_SeWlhh#GZ+V6-{6- z8j{;Z@b+G@EekTxGr-*&ywz(mpo2L#q*;5`2rgp6+kaiR8~%z9Xe58oZ&XUXa!XPa*qIExnNC6)sOo%RyHv!T+Ga<&KAGA4dNJeXWR-!26Zt=GA@1 zovnNL7W%Lw*E>K|()kcOpo4umZn;RVcK}&l?}ZuK+Q(#7nOUZEzhoT-?dm*?sKhQ9_0XA^rNj`I`w~r#_b#W;6ZrL zD)bZtMou4`idpmO>e;>#ZLcw5djoTn6yf#wwEp2lJhcA@vx;$$4lrH9i(p0>5yD#@ zy-C)q8}KXU>E48Qx@8zbYhd0gfe6Nt`?~&`kbj78h$q4eH~eRP2C>#o)J$|bYYtij zPLAFT;9rJ+4rag%%wQw~lWe+a5xS*OI|^7dN!AN8S4JGbH)%f^WRD$v8ybF6$Yb}r zU8_QGZ$6uxWVH~XKBtr*ks_kXlfN?Jt|ys=rg!xQi^*==gbR^D!^AI+%hs|c19D4P zkAL;IxJTiW*PciuJ_ppdp}H?rpTWk9+bMXW`CB&Mo&tR#trc^!6k7uBSuH+{h*P}Q z22T{vpeMu6<<-EQpWz|U9qQe^`~Ir}0Nq48dt%GMdzj%CvZ@yM0-sse;5|U3t!TP| ziQyMf7hEQA&EdZsWtu4Aa^kO}&C5DzCVIWp-nB6<>1__0WY_p!BhG-CbbiX+_%7?0 z-p|udR%Q@nR)y0muI#rX2Y?>3s4aXGnEVp7SQS=C=`Dk$*|7wN-jit8srqURoPuuG v;YKVwh9<`F68}PGAs!U_i9{li_;maN2O{wL6lwLK00000NkvXXu0mjf!mjzZ diff --git a/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_0_1/00002.png b/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_0_1/00002.png index 267b42fbe156bd1376d882c68b26eb21bc63d419..6bdd9ea6a81d58cac5b3c2a828e8c9560f368a32 100644 GIT binary patch delta 730 zcmV<00ww+K1@Z-uB!9U{L_t(|ob8)ia>F1DMQNuyVgF0=Ui#swhDbt4yiC%2zFY^y z00002McD`yKT-TLS$~n_B{n-uKk=DwO{H>HCXO)x{*&s+eWLzyn7Qzja zx$?OiW~64{Zp$#T0@c2JX_v7@{&++rbG5Pp>ROX)W2S^`U!(YZ!zcaE z>K2K15GL-`L4U#1-+VLP8aCCfW=~#JVJ!$V*|oslG-a!;-UFg|I;@61yYOa*utLM8 zj;ubCKgD>bYzuRCK*%Ej0020Ib_`(torM&ZkWi~PlQwD&C%s0LW|*;aR(3^J%SeAl z1&;=~=TMa;myt$$2E8p(ARZG!Em`_82r>C^A8 z;z~z{@+wrTX)2T-E$f!8^d*qHGZxctRqbS4G990q!gZP|_l@19nv979p>6^rJj`m^ zm5!DP8A2^=h#S$p`IfgQGwPav16eUTp``jOxC@e-?tbw1);Mf1Q>sff4u9#@7unk6 zXv%hFU4K?fjny8(H5%(?;t}&Gj*?duGotdS9;zIrP!Th-_CGZdy_A`A0HQ4MLcmF5 zkTC~KdCTE75?=BnyN3sct9QMKb+G4V8)Z&5v>PLPIyhd^jheq8! z&%-}zqt>6=91rgR$*h#`iq!E6j+=leg9H8eBvTzX0qbIb%H#Xv$q8_#fAjGFP#AQi zdq0!?$Mf3tVl)5f9&jed#ei)r^=tqD000000000000000004lSUo`sbQ}DF6Tf M07*qoM6N<$g2HKLGynhq delta 726 zcmV;{0xA9S1?~lqB!9I@L_t(|ob8)ka>XDBg>9!h$^Ms=z4RedhYLcEzwzFl?lA%qaJoUh>Bd7dey<2dqj{;`cL#EO!y@F}E*qk7tbY6q;GEWFq!OQ_~N z&n!_sx1l6>!sCeoAu}k-w~cY1Sjityj}(5es)N^Gek0d&)qmF^mt?0awxm}N&d*Zk zHs`Ziweby3P~1(qp4@)B`^`Zt56n}mc27NTQA)TcN4DH9!S)H%NQeQH#+^Z_=LkW- z)l)l;EXNwv+9Ni+cUZOvt=bUcT~*HpLoFdd(be)5^GD6%SOSg7Rmr!UK|@ zINKc}$3DdEo^aU>S6ihIReHt>BO6tB5%Y*|E5lP@`+wclPNDqix^oqUwCRrzLCevg zM9(*ia;oa1a;%)Ct$^HIu^4`}R1i|qzYHG9`ZEK&N z^+F&Yg zxxGQb%f5*$=SDwnr0ona?@tUU^0_hVU~ zo_p7e#r>z@BV(1}tN0WFv$SLI@#*5JCtcgb+dqA%tA~0yh}vKn|}{8~^|S07*qo IM6N<$f@u(96aWAK diff --git a/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_0_2/00000.png b/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_0_2/00000.png index 0c08224ff40aba010fa253cafe1604d9e2bdf501..200aa589375b20b044f90d4bda54df2b72fce72c 100644 GIT binary patch delta 993 zcmV<710MYC2loe%B!9k1L_t(|ob6g$vg9BLb*Ao4vi~JzFY}SQ77d4oXlr*3=gZgx z5DLA~W=+lu*L0teH&$D}M*Ix}cO zVHqwk1r1@?0h+xo0)q@Emw0&oZETJuVk4+xZ_Fp z{qTGyBP!DKHh(UT5mUJ`n;R#&=15yBJL%as4g&*qz$hXvfoG#ewxJ-H7j&d{!AKv= zXECYs=d>}%F7!_kws(s9=lJ;6WLncr}#LafirGJUb719YluIWM!cvc8mcfQhU zxA?MQEK-V~kD7fUPov4YAJB9Z$yNk3cY=?tT#o)G{qT4Mtfh%#>Wdh|XoqWZC4G0x zMEpgVYR1iAK8{AC`!kVr06b1v3|_CF8`-1A1is$+$6KvZx6#~^<^wsmz3pMsqLCg&im#oJ3jwB+B|HA+5jQix|9G$t$TlAGsz58769AO`>*V zX3DIRm;u~VTKCi-cK0UigKCs^12qUk;?Pe9)Iv-PH*L%)=K&Rn!;MPWMjh(HMxbqX z3ab*1=ZB$85`oqVo$)kvNgvovTqzn>{+*SifqyBH;y^D*%bt-+-TjM^>?PO?@?dPA9l>Hh5KdVST~endGe*4VT5kGqPT)A2Si$)K}zF8CQKSyIBRLw zfJ_1t`6bgmHyWw<0jdsdA zQh%y_Bect4sOM0VawuhQ%I|JdbK4!!z01RvQSdG(e{~nQYT;{cK`?S@3~HT7w^v2! zp}0Oj`lpXbiA4M4@^3X7!w7MQ?*Qm(R@1xP&>?fX`pma3w7xonbgIz}ZO9I;hQ0%! zNN7zuj&xlhjg0QN!$voOM7(pbs(DNG^#)C(?eA>$(3Ha#mNTfq*TFg zE&r-AL6LPos_Qt(QiSU6gdA*KuKmr5;qei$woRPb6EV(cg=?}W^mWTb{6WkXEJ zqtVg*o=hD{Hv3eviQ~rZ))Jz=PV$3OrJMs2xg{+}mD~dJf&N;N11uc)tuqI#*--p4 zu+!W{bAPdeior?B`zI;ypG10p!I`kSw316w_jzQQ7!;V;16vxc6?13IDvcS`Z_28k zg2wK*sn$WQmbic#1ZW)k31Du-tl?%|cP-~p4T$58N?Ar7s=`LFK6eh<3CHupP$r3B zl|pAC%|k*LxQHuNt2=)ZCEKVek#nFHWM$9DPJi9~i;=7)V1e<$?nbVqHdzM(;Lg}- zu{k;2G`kk}Wa3ygl(Rhfa>?ol-L^z=6`=q`N}j=%;2={?8rE>O(k{Sl1B$qoUiAqU zJ{5Dr1VSLtLSE*{~VJZMcQ4~dSh<~qDbd8AA$N2yN002ovPDHLk FV1lE4>vsSE diff --git a/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_0_2/00001.png b/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_0_2/00001.png index 91a9f0afa436c3feccf439cffc0b700b15b0c5d9..a2d186809dc864a4a99d06fefa6f1a7262a07e51 100644 GIT binary patch delta 1048 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 delta 749 zcmV6rFlKn3!d+9^Ycqrf%f0LQs?lA%qaJov*m)d7dey<2dqlzU?D-;&vs~ZR0#oH9%mPE0cQ&@;zeixc842 z>F=1;-0VR))HN*s3S^p$|LHbVdS98Y1WNKUh_34^e1Ze8tA9{+n_VMYKxj89okjBs z0N#`X&h1t2TQB6Uf@V~m;)ZZF<6QyaS_ouI-;X5iCINe)ym@$Yi)Y5 z^8wOSkmd;}x$F=CG0Wz3zj;@$(z62Ooa6CCmT*K8pO>m;SmEwzm_C0!n{ehz_j&)k z8mlJC{kB`RRDWu-IoQcd?aC^piwG6yx)9yyhQss>QkIt1B+w8|E^+~cq9YR8GltxQy9u)M29 ziOClGQ_y(#5nO9=JMXK?pf_Q6NUoI=v04TdoiF6Ix_=!s*mg24>TzhRYdkk9KwSB1 z3|4Q!^ElUi`ZO(pJJwzlAc3l0ydAf^o?wT zYHX7H-V!k>o`rM@>g(Np-m>8gPN=hx-Ol>dgK<|aC=XZMyTLDe9(*#zK`k9^U*{h= z0m&WL(|?9Kems9TZ!iZR%sp9%TvVLQIarEy@4|1wLF~z_bbeJQUDeWY26a!0u2r|c zjw}RJjnu8(ncclQxQMG_eYKrd=G1~Lr3eCXIz7r%fP;8<<=>uCIn!+{)hvOeeGv3h zs(qH8Ey+yh5yiMY8CH4I{-rFHx1V*aNqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_v1_0_0/00002.png b/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_v1_0_0/00002.png index e1a0c89386f78c06d8fdd74723bdca2d13016e34..1c0c2cf17b570d33128971ac78b095462f5eb36c 100644 GIT binary patch delta 626 zcmV-&0*(EI1&alcB!5y#L_t(|ob8%Xa>O7AhHa-e@%~53UHXuz;{YNmO0xaGr)(mK z7=h@f1ONa4006*ozPuD&*OgMrIhSkl^S-tSwpwnob8B~9zP%I?*B5*Td0iLpVw#+D ztoKt&KPNk@ePgSDHdUmWEw-rDT?SIREBx$sSGS1Sz=xn{Y z-M~^Z3P)ogJ_tgy92m=2gI@|PwGXK3l9xJk78>c z!UQxq8HfM?;C}^JiocV3T>4#+1FNk*$WTM@hvZk5LMP7A-b z>oImphNqlH@WzQbk$>okV=02AJ7s^#2XUO-6n=+1ozSB+R@#d(!6-icbS0wpLy*@3 zAJVfJtiwxq`^xBqAigB$7}B%YY4{=6kmaT%Y)mP2On(&Pqq? z+OL%{5e?}fjl~=;>L=v~7q_E}ki9?R1ba#!>(y6kpPmpD5ABBLOj*~G5TjB0~%9${+jF-a3zw{`Ab(!n+f%zdQn`N!tB%`2xS0{?2 z|BMr9eQSR$3clsle#&{k?ac|V*#*ldF~11pDHHH-!2|>op92chx$#j+^?h``Mh;kp z+>I)z56^`B6k$$Kkp+`19#yt3000000000000000000000N^wE1=sU=_w3`#e*gdg M07*qoM6N<$f;P7#EC2ui delta 619 zcmV-x0+juW1%w5VB!5duL_t(|ob8%HlEfegMV+a+iT6KJ?lOy1TNWUqVo1{etTV97t`dN z1FfG@`n$Nl+IE(illJ8&cPjBpxkc8ZsGm1(=_zCIa+~K0Ab*HM%pa08TSA#?Xlah`lA{2y|6LXXl|X)neEqxkgQm5AC8L0$`dNY7%h4lg9w zS4JlU@g+IOkeoTiO&Ir>D+j$r20I%RwFN1hRls!P#>NN z`CEiJK}8l!viPd9bpZeX0000000000000000002*yZxktICpx z2rAe!M2$wH(P%UpjmG8p6?{96gNR|P(fKD*^CXxAUjq#01)aTD&YYZ~1yn@zg)0$wtAFTV`kHo=_jBwZrY2g1 z4p8lkBA~h2VDOoCta-yg9sxnb@xhFC#QNn(8ic}~J#j%i=|&wQLR%z;Mu2iEPX_`c zfRvR3jwu$`u@tz5vAJ5pd}R@chlLdSvApL zMQ(papP@!^UyMsA!R8(xkPGCv6yB&+^&Vf zEfeOiQ^GivC>E0AK4!r+Rcz2cA(e}<6al7D(sdcJss5Bo(cmJ4-{7>1eNs$JKusrv zD)w&P#}i6F*W4$&yui*qpl1Db%zF2uP@e#Eg-y?$=C&bxUvqw`i%h%(t7Xl`ahXrb zIqy9ypnsvEcQ5{$T*!QCf%6)e)|#-hv6XPBVmS=PZ##JI5FKEQhxJr{u|U*trL z&_7KNk=m*$nwZf{&I0ZP=rNnN_GrPLo{B3K1%IwN=i^f zD!!&1YB1}g!R07@|JrxkdF0{w+u29b^Dy@}Vvoh=ml*${;dKeU(P%XGK$oBBXOhAj z^?&O?z}zDjOb|Uce$pxtHYm+`X+zSsjt~CcR3ZEW5wY~NeU{3UICauZ6&^q{;VnPS zsFh7b?QEzaavVJ6(O$ARsNlL{XZ~e|r1xOHdW7DqsYBs8?FlZb@hHRtxbkeP1tIbZ ztKo_h9Zvmningo(D75mg3N%x^N`?FkRBQ_^V`&3i1~LaXS3`x0+l&67XRK6DWAb!F z=)bFpZB*U>5z&G(XsN@gUxHO5ZPRk`b;+yl4dE*>HPWdgX%YB7{uwBTW{te@7mKd; hzj%C=B!9+9L_t(|ob8-jnj9erg-yQfr1!t1+DjfPV+cp!h*npnhySTA z3W(x`>Y3Jxq9}@@D2n3k{BYhK$I)7QyTNvPT{h6h?Fc`4tjv;7rix*5q` zke@|ymRx_2oT$!gkq^;S>mpZcR?d*QgV+_2BPEQ9Lx1ErEwC>0xb6@pGu^mdS~RIZj`78r;J;DbKVG=0Qvy*Q(?q{Nbw^5u@x6kB3Zdb*Q=t zrwt`5%nrad4}ERbB}-Z+u4ELXp<$p9r&i&s5$fiyO!4-7v=;dA}Vcz{6 zfZXorCfw?*`6r8}KCuHV_(^%?Q;ahg`8|;%=zwrN@%KDd$@FJ6OpB_wp@ba6{HXJB zw0-^HciVpC;pexjx1`rG_cvmXK({n)z1+D3s4qF+T%ErD>KHz-5>|xMDdQs!ZIT^e0EgO7_&R9=3@6cQw9`(hDG? zT1h57br|_eGHZlBO($QMM%BF`{7$A?I<+ND!ms0>K{_;Z)r-F@4z=$#Qj4M}if#M` X$LH>;hxxN*00000NkvXXu0mjfi9hld diff --git a/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_v1_0_1/00001.png b/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_v1_0_1/00001.png index ef7366d45cc9ca2bbb546b582f1dd444b28e7b18..9de81fc3f71783b90b06b80d21de2d35373da8e6 100644 GIT binary patch delta 1029 zcmV+g1p51z2%89yB!A*bL_t(|ob6m&lH4E+B&poQ_dk;Fk`GrXqDQNRvB%y~e|ZKW z3B3S~cUvnI3WY+UP$(2`$1iVS-}lzqwr%~nf1F0=qq&Vkyp&PNRg`*SpXJ%1GdEW; za?tqAtFpxU+ds5nJ>yVQeiBT;C_raEp|eoZ)bRM;T%AeZ@qdR@0z|7IFk?-}$nlJ$ z!_-8J(1EEVQJ8O3n@m1$Xf7Z+f(-DiKl*uGA!GgNOzIOwID6tiKA9ox@kuG!b9B_! zQ=>5%(3F({yAUVqSO{LjIdg~U-VH@2ci;e#p`P|0nTeA*OM>_Gs64jX6`IGJu&$vV zcp9EKyXLtJOMh+AI`}3ec2Fhgz!4pN^W?>c`z_#UrW$r$Rzq(S7HaFz(ZS&zLxCFZ zJs=Ba!QSZ&5MRA#U@Xz$riDzO&>xQTi^3e%WWcJca-mQt6z;^SJpgn!JAu~}1YJh& zz#1MWOc9}yfP+Uva=QuME-%hSf(-NwaQ6luDl{3;!GD|^(yTq~1s5^l?bPii)t~U> zlJ{yxC83-5(WD${%qEghgEv%s6V^2(G%MMM8tH{BuW)%%Mh?1C3H}ESE_Xak`!M<+ zNVFoZ1MgRon^*T4caHAiTj6MUAgbIetVSzY|*c_ zeoN~AgwFX7^udepGpo>B5E!|9a4F83S65Haahoo+`v7y46yde`^b*2}cxeA0%qk|q zJ3v3Aq%fn52&@|>%jyRF3TC-C;hk<7GSC{B7k^72g>mG*uEi!K;!EOH@M6vTsGmWs zjdL|yoz9F1oE+H<;J*w%&Sbzzn88Q}CfRq>B6L@yHx;mGk}L}*S7sc*H)+2dOq(6O z8@ffW6sEBI4X;(9w+}B*o@BKUSf8s(kjN5I<;fo!apRLrMAN%^gT-W@*@Rn^KIiG5 zjDLI9vMd8?S6Gb2SGX7A%a>m$6utq}yP>)-)Stnwi+d?}qWN2PsyzkzLRvBAWGS`; z+_PGF7{LvnaH4ny4HM?=eh74jQoDEJUlm~J4%*cdM-JklC9U8w3|V!Hdx0M= zZSo!2E2gY~U= zNCWk;`6{sN7+RRaBmP2WE#4CQg+ifF_;&mSQTz2aa?l8K00000NkvXXu0mjf`se$u delta 1025 zcmV+c1pfP*2$u+uB!AvXL_t(|ob6m$a;z{6bW*tq_dgPM$p;meqovhefMG`cMX)T% z+H7lhuarb0kw_#GiA3UZe1Wlj-%Bamw$$A?1w=)h0l=E=dg}Yo`on2dCyH?P3IfO{GlV@pT}sv*ZMF5( zC}ai{Wo5t-W2T5P;ME&5cbMzdN@Q}!4iHHyB!y%elQ~O*_w>D*Q=70ZqaH#Uua0A4 z9%C8SwMFa58-I{k!Iq!{M_SeWlhh#GZ+V6-{6- z8j{;Z@b+G@EekTxGr-*&ywz(mpo2L#q*;5`2rgp6+kaiR8~%z9Xe58oZ&XUXa!XPa*qIExnNC6)sOo%RyHv!T+Ga<&KAGA4dNJeXWR-!26Zt=GA@1 zovnNL7W%Lw*E>K|()kcOpo4umZn;RVcK}&l?}ZuK+Q(#7nOUZEzhoT-?dm*?sKhQ9_0XA^rNj`I`w~r#_b#W;6ZrL zD)bZtMou4`idpmO>e;>#ZLcw5djoTn6yf#wwEp2lJhcA@vx;$$4lrH9i(p0>5yD#@ zy-C)q8}KXU>E48Qx@8zbYhd0gfe6Nt`?~&`kbj78h$q4eH~eRP2C>#o)J$|bYYtij zPLAFT;9rJ+4rag%%wQw~lWe+a5xS*OI|^7dN!AN8S4JGbH)%f^WRD$v8ybF6$Yb}r zU8_QGZ$6uxWVH~XKBtr*ks_kXlfN?Jt|ys=rg!xQi^*==gbR^D!^AI+%hs|c19D4P zkAL;IxJTiW*PciuJ_ppdp}H?rpTWk9+bMXW`CB&Mo&tR#trc^!6k7uBSuH+{h*P}Q z22T{vpeMu6<<-EQpWz|U9qQe^`~Ir}0Nq48dt%GMdzj%CvZ@yM0-sse;5|U3t!TP| ziQyMf7hEQA&EdZsWtu4Aa^kO}&C5DzCVIWp-nB6<>1__0WY_p!BhG-CbbiX+_%7?0 z-p|udR%Q@nR)y0muI#rX2Y?>3s4aXGnEVp7SQS=C=`Dk$*|7wN-jit8srqURoPuuG v;YKVwh9<`F68}PGAs!U_i9{li_;maN2O{wL6lwLK00000NkvXXu0mjf!mjzZ diff --git a/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_v1_0_1/00002.png b/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_v1_0_1/00002.png index 2d97537687559bdc2c2a653c12f9b853680affe7..915dfc2726af6c8f5ba6ff79d66be5324e6930ac 100644 GIT binary patch delta 759 zcmV9!hx%*$z-AfBA>$->PxSwi!` zSzKA}MhL0N$72B@D=_8jO56r3`4>?l!QCnvn0rm{k*D0WJAcY4=@HGE^m>SMxm3IF z@M*33_>D-{tAAZrIhkA^S^aK5mOJLrMSV@f+PsADnw+x6oq}!y)JU!Ygu3HSX)ubo z#5EKv9+{Cgs=#U=~DU5fH{DF0<;gU5pNT3+-j}9<D*) z;nARoue!5D=>o2=2``()H5d1{COxsjk+o`ghyn0xWqpl0 z>1dsh$(W6SawB?ge&y}SjD`$wAS+g4Nm3dkXQ{g3E>wWx7;w`Ae_922nFPZUNcL@8sZV`~0fKL|Jr7-%IoVJbkR=^l2rWlTi+s%h4#848 z?J&S?eJ9gInJK%ApVl@>NS3k9G@n_sh)pLzGjJ=l+b2itiQ1vu;HKVYfK~<#2Kwr+ z8FXPCZ!^HU7+`WjyfxWjfS}91hW}RrP)5{4?mzEg|4XFyyf}m}dGgW$a{gx@S%?-TKjA}24QI8~9g7vva&RD*rI{gUha{*+<&w?OJ+mNfp99IkKiY1>Gi4BOwMTG#(5}BS#1V zu3oX?$aJ((wLN0PYw97Wa8g;1G}A1N+8Nx^xaKQ>JV1w055z;kmZ{5BeIBOc&*~8~ z&>@_;!+kzKL4OUZ=PfQ!wj7ss=HeG^%I zD}RLX8EsmVuUvgX2>EWHTTpSOGcRP`DK9^HNgFeVliqI*)oW#(u!=hty@K>-tHKj5 zKk;pMiX2^t>pkJJ8LoD5eQ44%Rv1~RwuhKU{92iQ1%KB2u62mQpYAu8DWp$-ybGF+ z1|@pFY07EJkIKGsl)eOVcgAA+s|rfSB_IV~)FX1F-^5e$beOmhrV|9m!>pmvbhOTW zdX66lgb}?rrzKVdPYr5-(^#=OkL0Dx5M;XHT>vK>Ts8_hW=IV#f9X9I#fs_G)Z^;D zMKANLMt>CcsO+0=`yZYKI!ZlPnGr3InxV;28XC%s?0x1zJD6z$(#n!3L_jKwOdBla z=;aL(Tl!Nx6Yy9Hl6~7&>Qf(L0pJ^L&qKG$oNQ>7AWJ&95L%9whWyMBIKfgo?J&S) z{U+0d%#>Z?PivbbB+J-ln$N6R#3m2W%u4O{$!sb1gy)nS!qj61Xl2k~L0|ndgD$M& zF$1hS158dhZ%uX>01Vl$;r}ZUAWzgo?my44|0Uu*FAm`g-vOV+#~i}lERAf05JCtc lgb+dqA%qY@2qA=!n17r|8$|Nf^O67n002ovPDHLkV1lbUVRHZg diff --git a/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_v1_0_2/00000.png b/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_v1_0_2/00000.png index 0c08224ff40aba010fa253cafe1604d9e2bdf501..200aa589375b20b044f90d4bda54df2b72fce72c 100644 GIT binary patch delta 993 zcmV<710MYC2loe%B!9k1L_t(|ob6g$vg9BLb*Ao4vi~JzFY}SQ77d4oXlr*3=gZgx z5DLA~W=+lu*L0teH&$D}M*Ix}cO zVHqwk1r1@?0h+xo0)q@Emw0&oZETJuVk4+xZ_Fp z{qTGyBP!DKHh(UT5mUJ`n;R#&=15yBJL%as4g&*qz$hXvfoG#ewxJ-H7j&d{!AKv= zXECYs=d>}%F7!_kws(s9=lJ;6WLncr}#LafirGJUb719YluIWM!cvc8mcfQhU zxA?MQEK-V~kD7fUPov4YAJB9Z$yNk3cY=?tT#o)G{qT4Mtfh%#>Wdh|XoqWZC4G0x zMEpgVYR1iAK8{AC`!kVr06b1v3|_CF8`-1A1is$+$6KvZx6#~^<^wsmz3pMsqLCg&im#oJ3jwB+B|HA+5jQix|9G$t$TlAGsz58769AO`>*V zX3DIRm;u~VTKCi-cK0UigKCs^12qUk;?Pe9)Iv-PH*L%)=K&Rn!;MPWMjh(HMxbqX z3ab*1=ZB$85`oqVo$)kvNgvovTqzn>{+*SifqyBH;y^D*%bt-+-TjM^>?PO?@?dPA9l>Hh5KdVST~endGe*4VT5kGqPT)A2Si$)K}zF8CQKSyIBRLw zfJ_1t`6bgmHyWw<0jdsdA zQh%y_Bect4sOM0VawuhQ%I|JdbK4!!z01RvQSdG(e{~nQYT;{cK`?S@3~HT7w^v2! zp}0Oj`lpXbiA4M4@^3X7!w7MQ?*Qm(R@1xP&>?fX`pma3w7xonbgIz}ZO9I;hQ0%! zNN7zuj&xlhjg0QN!$voOM7(pbs(DNG^#)C(?eA>$(3Ha#mNTfq*TFg zE&r-AL6LPos_Qt(QiSU6gdA*KuKmr5;qei$woRPb6EV(cg=?}W^mWTb{6WkXEJ zqtVg*o=hD{Hv3eviQ~rZ))Jz=PV$3OrJMs2xg{+}mD~dJf&N;N11uc)tuqI#*--p4 zu+!W{bAPdeior?B`zI;ypG10p!I`kSw316w_jzQQ7!;V;16vxc6?13IDvcS`Z_28k zg2wK*sn$WQmbic#1ZW)k31Du-tl?%|cP-~p4T$58N?Ar7s=`LFK6eh<3CHupP$r3B zl|pAC%|k*LxQHuNt2=)ZCEKVek#nFHWM$9DPJi9~i;=7)V1e<$?nbVqHdzM(;Lg}- zu{k;2G`kk}Wa3ygl(Rhfa>?ol-L^z=6`=q`N}j=%;2={?8rE>O(k{Sl1B$qoUiAqU zJ{5Dr1VSLtLSE*{~VJZMcQ4~dSh<~qDbd8AA$N2yN002ovPDHLk FV1lE4>vsSE diff --git a/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_v1_0_2/00001.png b/tests/snapshots/nanox/test_register_wallet_accept_sh_wit_v1_0_2/00001.png index 91a9f0afa436c3feccf439cffc0b700b15b0c5d9..a2d186809dc864a4a99d06fefa6f1a7262a07e51 100644 GIT binary patch delta 1048 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 YV-wP<-Xc(yuK)l507*qoM6N<$g5X<>oB#j- delta 769 zcmV+c1OEK62AKwsB!A#ZL_t(|ob8%jcElhEg>6rFlKn3!d+9^Ycqrh7sAFt z01^MlltKt0gb+f=az65+=XsV=j^n7;^=BVdiK|MQTgG{ws)4{USEg!6@;Tz}c=V4K zg9e)OD;r1v0ms|LS&BMqjzE1X}VkiLUD_eUc5ZqkmATt)Y>3Kx*GII*Z#Q z07O$ZxZV$=Z=+CECEW;v;-+vo<6Q~idI)5aE>$|GplU!~bYw^0BxVhTrd7l<-rDKK z_6L}zlHBfqR>%$k5VI_v?ia7>Aw45N_Bn1(W(a2_@qQ_E!wPqI!}R{^S%fRsbYIuc z>t^VpTyMKgOMjzwHU}$t>%Q{JuGM(n13M1PjdQ?V^66i3g_j)&rWktU_~O&IEI-S* z!@D&3H%6ZjLjD`mc0ss6RLn+A-OubwK~)2oyW0e*L3(8iT<-SQs#>ulaw`*|43>AT zC^31*K1w?8zJhBluJXRB3_1zBO>(`Qh_y0k=zJls)ql@Hhpm!nS&vg&UE{t{3F69! zIT-!~uV?g!jsc^$MssDT6d`Trr}EO6Nt5rsmG#aHeG!{W@>9%|Qqn#I9k95yt#4!t zOk272u-)-TLlbx?RuUx zy%AwEREX81?kI#}xUl1DnAicMwIFq}ICK9lo_n}eM;`YC1mrWCK_5I{5wTu^febRM zC23y-dR%9~yBV3}i0or&F>ZS9x2&k~r)mSm^m+mQwpBH>?u;;}9GxUt$&$jw8{=4s z`$(1fLM2ukxENu=2)I?YoRv7^Y~smVMnJx8V67fE-CC3J`nhJFoD2x}4q3J{8+{S` zpG-IhlpXfMgb+dqA%qY@2qAqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_register_wallet_accept_wit_0_0/00002.png b/tests/snapshots/nanox/test_register_wallet_accept_wit_0_0/00002.png index b18a7f9dac53d0afd50bc877aa1b998bdaa595fc..fc56072c49e7bed1425067411b16e4c32bfea72e 100644 GIT binary patch delta 669 zcmV;O0%HBE1+@i`B!7HKL_t(|ob8%ha>XDBhHa-iasNwlFMY_=v4Dt*n&kZ7Lno)f z8wetk5C8xG0002k&X-q5DWwoXj4?lxpVzacVNG(;JeLmF zF-9qUDzC)z#?dg&22hrr_r7uVr997TYe7crL7bRnxDB}71J1JOoYa#j7j7DYZpG4b z2nMLKGY|m)z<-0WB!%0?ooUN&;LXG|{fECAo?!>R1{kPV%#323e6N_Xno=!Al$8_y z%oAiKWwr?Oy%Sj7LMdC;>ZZJqM=C<3+@{ovI9Yhrb)lSG`8QPb#akJL6?uI_8UNY) zwrjJKetJD%{2tKd{*$rdcuL;o8C?ukL%C~v3D=q*WPhFZgYE%kOcdi|SHX5qb=Mt> z_Op);ERcGD(b~;pr!*K57SC|8|EsF3G`FKSA+SQe;53vB8!Y86>Q%1k&3v(zb%=S0eIR4y zz@4ohW`A7_Uo3gU@~Xk_2TO0TUK}vMg=KGwR~Yea^TQtdK<|fNWXM~k7+EVl@}36< zIu(VsLX^^cAi{P73=DL{04G07As@|&56>ECfMaLCFdq>p7BN%Bw6vYE%}1o6GycxA z%;tx{V3wVm5s?i50000000000000000002+LKc1j5P|ZOsL`>r00000NkvXXu0mjf DB>+4Y delta 659 zcmV;E0&M-Y1*-*+B!6;AL_t(|ob8%za>O7AhHa-e@%~5hF8z_IV*wErb(6f$kDcs_ zU!W*#LI3~&0001BJ711%rIbPlF~Xvw$FuY?c_0dnay(t5P!rW#y^5ITSA^{md|b0 zRxbHb^oo}5$RO8ws*^jwC^_bE#9E~ZhX>|s24@3YJG7ik?Zi7Z;Vw$2w}^!BTtsUNK`TrJ9N;(+YuZ{*db_NXd3P-VsnJlKI?u>0-aSff>@BEh8dTyX3FV6=8 zD}Yp#1C1#b=dl#HhjF-ZTRIi+%FYKsRH(3&ikVm}TM&3Cx${#~;yR#3SkIvza2Z^9 zcC>2Yt1Z!GbAJQq6m;OojxP)kBYl*tAJfc*q%|Qj(S+`cv>Klzz{-x1@Z{?#?w}OGXqho84!iY_~oD<_w$eJI!T7h% z)-k9DmY!ohwYvbat!Ftm5v+#0B}DUr@zX)S=@y(aejY1=qyPU?j^>P0pP|!!@-5^oBf}+__M>k zcV|=@7`%&j=TpE^1?ctAqzv&zn5!+2qp6JNdC-Ws$~#`i(cZAb#W1_G)a|=I4bk%< zZ0IwAaI}BvMl8k3?2jL7W;O3p)o3&tjZecj>D0^4kcBN400000NkvXXu0mjfAMW>B delta 1019 zcmVEFkB8<8T+vk0b@-lA zMuDLCgWataMNt$*Q5417`EuU9Ua!{LaUA`*|IE>apeXr@S0OFjRTCScox_shC#dGg zpDAnBy?^|t38%|f4f;t5ao##~;R&0qpHg@;KFw)$@|U;68Go><0y9j`=Wu|a87Lp4 z69=P;W@$4Sd_zCxMuQ}d0LPp1dwO~3{d5@hhH5w~flNGMA%=*umWiPrpt6-^!wD4u z4ZQ3Nby%6i7`m9nrJvL3b!yeoOjuYg*FaT>J<>sa%+UzsNt zVYwwbtxm#DL4PM_WcBrvG$LGYd4aO#y0jB#Z{wJat*mXRZ-aLZn1vtyov`xNYlhFd z4R8I5^d|kuEPm1Z9P*LgFN&i0Y~pNab5nh?#L3AxC827+8Xjn!&+yz?~LuG_f3yW8pd0 z61xjB+j^A&xnS{gsOl$^6Ag2mzUnl%hjCJ;X&cOgm{jK62UyRl<|6#zs~Hia><^EJ zOm20kx(TNZB`eGhz;7P<+GZTtU~4 zUhZ|m#Sgi^1CZMt-Gt+uHUEU13@o150T%qEymA%e%td}r}y`BC2{GBFpXU}cFqmkrOc zjH$yjon!ehUAq4yC_REn5>*YG;9E-$DK;$hLu#tN)6f~_vk|cQAf{4=q!Ei6bHY~| zZu|ql{mD4|s^QJzF4Bqn^8rUmC~$9LJap&)sf<+YT-d(E|9PuFJKTGB)>0kAH?i(~ z5-ddku7|^vA-@Pqv5DkpSjV#5DP&BQ4d0ieynWXfzs)Mx)VaG#VY)M^8*Ptt>6+g ze&eca@&5IV!R+CWhKiFA5!~r2 z3K+`Efw&Zl>sSh0!+@(KMf$GTCmggq6o>#E#nG#ZU35$yq*yc9>t^s?u1GQ5T4 zXx=gCU}`wjCd6rqsiytcm4QW6n|4Rd~7gd++q&YzYFIakY9@1 zZ%kaoZkU`}aF_9PnyRE{U~1)=CJuf)mQ%JQ0l?3fV!6OIFeepM>oef19G}`WO*EP- z_$v99Dj=gRb8A^`O=}diu8lLZ-!SoWen4a5B1*Ms!{OPMZV(i2#$(jaJ{Y5fv z&rQ9i3x6Ior9&tU?VCiIY19N1@%j?VYfmW9ogc$0G)E%x>oF zyGY6@3hVs@S4@TK8%FJ#nsShV*x7OyO2)%M;eRd_Vcy7ave46}mK0_76eKCN6#>8N zk#1)HCFmsb(kgE8et3UPfk;Nr_D6J1)s8!-m?q-{0{a6><22IM`Tn8V5d?b~s?`7t zt7f%+rn=_4opq$%@st_wI0Qxk&<;Xec4+qpqxH<$tYJe11S=_jnejNgGk-Q7BZkkukZGit`#gR0*Po3>qw$}>qs(HKEo}+fUq2BKOizAD=a>_u zzh)zsoDw9{$0~&Xi3i3*rr4xdv0%tb00L2nb3i{V9Ybrrt{t(>vPdg(rSq^Nv>k2$ z%ukeR+VG3wYvFr3@e$QvUsfTCnVmh|=yeV+W+Y8^1;!14o{9d(bJLKTuRjK$AEuX} z&-3Z?pCfW?Amb1mVxFJGb>_QOHvrmYd@Z7G=5hooC)Q%Uuxc9Ili>9 delta 1013 zcmVWWm$a{?(hd%-nm z{!Ur5?)~eV!TQ7h8fu(`lHlI}QeLoG7-?E~mz%va<%uucj(;Fvg@7l|W8{90qr)^q z>(_y)BT=}I+YC-V@2^@w5cv!Uyvh4R<*E0}(}*gHaP}62U_O~4?CF^@lIAG4)-z*( zGhiq$2O48m7BK|eyqdeyxlUdJCwD#oVv>rMQZdcqoCU#0`n{Gzo3LI+JyIEO9gl@^ zYBOwVi`J1>Xn&DFm!O+_TG9RqT9EFyxI!+uuI9};d^X7`NarubX)?XMIJQG z8*WF=fPeI;7dS{yb1yN8?ET%Weae_x7m`+1rsTWo{yN;wE_$H{0LSR> zyOOT2Zx&nsbsQOk2ISN#)F32I?lCxucJI!2!lI3-_q|>oG0xjvjH^s#lVZbyDk}pJs6w0r`eEr9TJv@7h;2@bbVjZS4{Lb_F@S!UUV=W)r_Xd=2Cuy2`Cbq%}M?NObN(yprR=I00000NkvXXu0mjfwj1!P diff --git a/tests/snapshots/nanox/test_register_wallet_accept_wit_0_1/00002.png b/tests/snapshots/nanox/test_register_wallet_accept_wit_0_1/00002.png index d283f94fd46f0eba7bd3ab5c99f3fcdc3de5cdc7..76ea889910f94559f6cccba804ce377b46a84f65 100644 GIT binary patch delta 762 zcmVVRE_twuV&}I3F`DY{$weF* z1_m6r6ha6ggb+e*=gYfs97ido*4nPy&uN++ZLPnBx6+Hes-}KW41%`PjGJ|uh2e&q zx&C?@VZ^f^w-p%KfoWeC#&u$mKZuAD&Q?*uoNIcHoYzCMqkr#`ZqY0$pNqI%_p;{} zpH?-;H)36neyz3dOe;r5e>#q}2V3i++*9cFOBna;^d)H*be%v(NgW{Mt_P*XT_gop zC`KIVk#?%~N9=e_5`x4E?aPsBCR?L+1NU?z#@%T(bg(A`&5lkcW`(0b&n{Q3^dXvJfY@CoQq$01&e$<{CHi zktKAJ4iQKNiu>m8t_pYQZwe}X(jafTHK&r_P3y*K%lwF0H1aXcwVy0j&l zu9Y-RRo`k>a&{g|4j39NaB!dOgB{2aWKLl-wt7j&AkN0I2#olqO~hJNpXBr$*LIp_ zM4lECAAd$%(Jy8C$h!kigRAWcq8E9T1ImyO9-?@Wr#T?t-}>Mc{O2h2e3C(?54NI* z_p)!oabxD$D>(9|IoFA#MbK!f-|NDoNf#56Ry1?2NEX&CIj_N0eorvCI293ae1bnX z^f!x9N$K^A@rFA-EQvP?J43Kws$Vp&}X4A0)=9cUbcYF`n zflezSyX)vUzHj60NjJ~+O&AFm@d^O1_px^c^k+e_z|C)mUc%BlQ+jQgKlT4U-#x(z sA%qY@2qAKezvBf&c&j07*qoM6N<$g6eT_sQ>@~ delta 760 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 TUC*>T00000NkvXXu0mjfPmtvp diff --git a/tests/snapshots/nanox/test_register_wallet_accept_wit_0_2/00001.png b/tests/snapshots/nanox/test_register_wallet_accept_wit_0_2/00001.png index 795449674900bb3acc2e98507c9f69fa56a3cb5d..0254f586a604700fba05a771a38dba93f485f39c 100644 GIT binary patch delta 1009 zcmVwlU)-~f1r60yxS{Sz^5 zIkcbFX2$Rg(7fL#LZ1)DPjsQsdzPM`i`JU6~PkJr1uxG)QHtFuFKU< zJPsP{&StR$;TR5p=C7-R(M-hQa<3Injsu28Wz?$P|JOLd4JZ2h<*M07FWj|!Rv2tn3lg;p!DghX53iOmjd z2$m>%Wcwo9@yJ?!67x0>N!T?5R&A9Ni9{l?4;xoO9DLE{KH*DMzQjaUS@=rKAT>Er zN*aS!JqBZWU@WmkmT`2gg6s(p6(aQ#wyM}0F%obR{C}cnvDge$q&;!5a8AS;$Ak>; zg!x9XNYfS!-VC@XLnGPof-1CfBo0%w%FU$sc|ZU>3rvMXS2&MEY#m`+ zZj3_i|9_b{GkjIchkL)`u^6QH4z>tCwbuI z1VC(BfZIt!X@9$NCv2!RJ{T!%1Ibyl*p?mKnSX;SMAp_2PM(hriW9LMQy*pp$UhBW zKH9;UgeDxMQN`qNdqDxHqWdyu+abPV5zq2M{1VQRgA6L1i%l-NoCrbdWfZp=jB{i9iHX zR0Ixtx`?;99^<92{#qBz6KD{8kn;xr25VJhNc|0?MxGJclp9@SmuH=Pgi z-s%hx5AC#*Ja^vl2BT~u57m%5w=vG_icyTY<)t{rp$=h_8Oeq|jHCaO#PKS+@fAla fi9{li_??H)_?cQ9J&xu)Tr(3#a zWA427xBqCL@gT9e2HXH{*n#8z6661-4IRBta)Auc#*ayK{C_^u2b=)UP$IUwX1pV& zEr<4}<(Uz#0K=Q(g!_Hh`+TZh6ljL)6fuRDbi5;J#s@)@I+87@D;R$yvLn~TxFT0I z@i=I$TgqY!3LzW-&1KsFV;IN9?fz+oWh!8dxji3u45=ir^NL-|HG3S4k0&FSugWqn z;f|x-_xI;<(|9_21FI( zB}f5j!~-abbEUX;6y%gK#B>^evSn(#qg$z=Qr3h==WEYS1o~MDr@z6c#>?eoK&~vn zt)-!KyqugAO2!!1H$UGKTe;0Iy{EN%{yIN?WP$=Aw z{eKf_A;u;CEXXQ~!wlMPa(3qeq!n=?2|2`Bwh+U$8{NBlz@A0&;~02np^R?xu4wdZ;<%qT2e@yNGMu{WFig0)W4~QV3&({ ziA!FxA(-)gnvc6K030L}#R_ZB+w6!nlx4>KRK&*q&t$A+{6yD1u-nY9Jnv$^tqKs2 z?zHnfxAgdcD5uCn6;kI8Mw+-5!kkZ@i_4f)94Faue+zm!&SgVq@Ep?d5vMDKLZMLj aefS5%t5294MdwEV0000HROM_mU4Q7K4D-N9#=Lo-fm( z5fM@8Nr@0b2qA=!?R?>)_kE|7uIno8^5-x`kEu=exQ+Y1)ffZAOqrqq;d{o`CEmaO zNUvj7bF&BKP}8vT-#`X8{%6=q>3wCl5-ij(X2#0_VOki-fF@-IQ&7<^8)Km{mdEP8n!PKJBL>&$ zrJj!BKNdHkX}l?MNk2IHe>+Xu?5 zI`H(C;p#@0F{Y%aTnU?9_ZrZ?h?(aZ`7k)S%NK(?OMk5&u>nE87>9PO{McE}468V5 zf_9(>jHV#)5pDRoF)uNJwt_bbkEv2b7h`DwzeSfA_aeOu{F_8_7Bo1DeG`!Uii#-) z%Ea2dEqViBk5iu{KLzzU?8tn0=oNq%cfEc`j0Kc(L=5T9G{DS1ft|Qa46dQ!-Y05j zy~oO@S%28km@4OaaB!8tzL_t(|ob8%jcElhEh0~tyB>P`d_R@!(au`9p{)A+v_j^iH z6a+;jvu%VBLI@#*r1OP~9>=k5+rIDeEPsw6ow!|Tb!i;OQ4BCJ%$1QIK)z?po%jC! z$M!nrA~rb`4s{Ka{{}K$#{Uc(s=Z&BUI^6W^&~o<&*=jWz<;j7qFZr|eiKaXE~TsJ zUIBqO^?>Dl)BDy7(iLb%(<$y0Zf3l5Lbw(NGN4JqUlA`r7Ar~Bkxy~)T5&@qq4gDhc0GCnUg&9K75VOSo&kxf`Q)4lAU z=gX#vdcPf3t$&r;Y#!|7wfBWpcCU`}UU1@w>9_~ zx^DcR7k_}sQlr!M(!oC`0MDt>X2*bNZpcDJXgHZMxRiHtZ?o(%Fqm4C$#UKd**D=O zj9sI;9GZ4hOA3G3*sU7`v3p{ diff --git a/tests/snapshots/nanox/test_register_wallet_accept_wit_v1_0_0/00001.png b/tests/snapshots/nanox/test_register_wallet_accept_wit_v1_0_0/00001.png index 87b4dfa0fcd79dd1870bdc60c0d92e4f4b667964..cc2d012b6709decb341536a534fae2f5468252e5 100644 GIT binary patch delta 429 zcmV;e0aE_a1JMJJE`N4}APhiJ+tZz}|0S`Pet1gL1R^*Ab^7j?6A=(JI=F2B006+# z<(zZQSNGycJ_GA2L%(qSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_register_wallet_accept_wit_v1_0_0/00002.png b/tests/snapshots/nanox/test_register_wallet_accept_wit_v1_0_0/00002.png index 1507a4c67504057de0f3ca685565a1d88e207125..5cc6b9240d53b472455430eeba51bba9817b6a5b 100644 GIT binary patch delta 616 zcmV-u0+;>y1c3#RB!5UrL_t(|ob8%has(j=MNKL@asNwlFZq}n%YY&(Xgj&*W2ztc z0zqXu1ONa40002C^JP_0N-2a8W6am&_I0f(*phVWr)zUvzO5=Es?XRCGNr_um?p+} zR{J4@pPh}By3>rD$md&bRAQCIZx zF-oXYcvW3*3=Ly!0Abj9?kjs=%JY3~E67x9sCG=#+y>0f0cUYqC*@6)2@efHkHU2w zf&rTB3`76`aDOqHP2sk7SIY7ecz0u({=#2P_izAP159KrR$5VZepF1EO=+eg%FGGB z<{M;T%d8RRb0@I8g^;#v1~3^^rIM?abtACBN%ln{!09L%HgJWj_p<+l$pCm(hv$4;k5T`N zZtAg{CSiIYTfdB3K~6nlj=LkL9?OUP_Q_6wuObcu103d>H6U|EVEG(|)Qw$`BRmT| z^!+oKVeya5^-2H$0000000000000000002sZhisgigp{|ekR!f0000F1DMQNuyVgE~FFa7XTLnR>#5GEw|d}N$h zyd)6j#wh^+00000@Hk(Ab(K<5N;zk`W?!#sPr;VuqJA!I&gMI?F6Me7c95kM*~Bn8 z=Z)S^Dg8X$UhO;2$eBHTl|f}up<8S%s`X3bRz1{*sIWz@0Dp$s#r#LoM$4d~l0DVg znz`&pH7k0WW1U==sdlaar{!3}QA^b!9PU_b7=iOC%@B(uWNZtrs9f4n#;xKTS?B#^uYfuys(<;hORarC+FgOi`?N*}2FO={ zGupS?P8~32tnT4z{gv3_<<#^2WWfGxWsyPS_9r^>ynI&|P!5 zzuqzcA%jvXIoeq#f*9=Nxhw=EH%>+jmLlC7`EKX~umMO_M`}Jxk5Qk+t@L;+6TKi$ zzZo}-Em=KcjxWcS9_t_F*H>Nycq?Kv2*75J*#n3p63hG0TyX3FV6=8 zD}Yp#1C1#b=dl#HhjF-ZTRIi+%FYKsRH(3&ikVm}TM&3Cx${#~;yR#3SkIvza2Z^9 zcC>2Yt1Z!GbAJQq6m;OojxP)kBYl*tAJfc*q%|Qj(S+`cv>Klzz{-x1@Z{?#?w}OGXqho84!iY_~oD<_w$eJI!T7h% z)-k9DmY!ohwYvbat!Ftm5v+#0B}DUr@zX)S=@y(aejY1=qyPU?j^>P0pP|!!@-5^oBf}+__M>k zcV|=@7`%&j=TpE^1?ctAqzv&zn5!+2qp6JNdC-Ws$~#`i(cZAb#W1_G)a|=I4bk%< zZ0IwAaI}BvMl8k3?2jL7W;O3p)o3&tjZecj>D0^4kcBN400000NkvXXu0mjfAMW>B delta 1019 zcmVEFkB8<8T+vk0b@-lA zMuDLCgWataMNt$*Q5417`EuU9Ua!{LaUA`*|IE>apeXr@S0OFjRTCScox_shC#dGg zpDAnBy?^|t38%|f4f;t5ao##~;R&0qpHg@;KFw)$@|U;68Go><0y9j`=Wu|a87Lp4 z69=P;W@$4Sd_zCxMuQ}d0LPp1dwO~3{d5@hhH5w~flNGMA%=*umWiPrpt6-^!wD4u z4ZQ3Nby%6i7`m9nrJvL3b!yeoOjuYg*FaT>J<>sa%+UzsNt zVYwwbtxm#DL4PM_WcBrvG$LGYd4aO#y0jB#Z{wJat*mXRZ-aLZn1vtyov`xNYlhFd z4R8I5^d|kuEPm1Z9P*LgFN&i0Y~pNab5nh?#L3AxC827+8Xjn!&+yz?~LuG_f3yW8pd0 z61xjB+j^A&xnS{gsOl$^6Ag2mzUnl%hjCJ;X&cOgm{jK62UyRl<|6#zs~Hia><^EJ zOm20kx(TNZB`eGhz;7P<+GZTtU~4 zUhZ|m#Sgi^1CZMt-Gt+uHUEU13@o150T%qEymA%e%td}r}y`BC2{GBFpXU}cFqmkrOc zjH$yjon!ehUAq4yC_REn5>*YG;9E-$DK;$hLu#tN)6f~_vk|cQAf{4=q!Ei6bHY~| zZu|ql{mD4|s^QJzF4Bqn^8rUmC~$9LJap&)sf<+YT-d(E|9PuFJKTGB)>0kAH?i(~ z5-ddku7|^vA-@Pqv5DkpSjV#5DP&BQ4d0ieynWXfzs)Mx)VaG#VY)M^8*Ptt>6+g ze&eca@&5IV!R+CWhKiFA5!~r2 z3K+`Efw&Zl>sSh0!+@(KMf$GTCmggq6o>#E#nG#ZU35$yq*yc9>t^s?u1GQ5T4 zXx=gCU}`wjCd6rqsiytcm4QW6n|4Rd~7gd++q&YzYFIakY9@1 zZ%kaoZkU`}aF_9PnyRE{U~1)=CJuf)mQ%JQ0l?3fV!6OIFeepM>oef19G}`WO*EP- z_$v99Dj=gRb8A^`O=}diu8lLZ-!SoWen4a5B1*Ms!{OPMZV(i2#$(jaJ{Y5fv z&rQ9i3x6Ior9&tU?VCiIY19N1@%j?VYfmW9ogc$0G)E%x>oF zyGY6@3hVs@S4@TK8%FJ#nsShV*x7OyO2)%M;eRd_Vcy7ave46}mK0_76eKCN6#>8N zk#1)HCFmsb(kgE8et3UPfk;Nr_D6J1)s8!-m?q-{0{a6><22IM`Tn8V5d?b~s?`7t zt7f%+rn=_4opq$%@st_wI0Qxk&<;Xec4+qpqxH<$tYJe11S=_jnejNgGk-Q7BZkkukZGit`#gR0*Po3>qw$}>qs(HKEo}+fUq2BKOizAD=a>_u zzh)zsoDw9{$0~&Xi3i3*rr4xdv0%tb00L2nb3i{V9Ybrrt{t(>vPdg(rSq^Nv>k2$ z%ukeR+VG3wYvFr3@e$QvUsfTCnVmh|=yeV+W+Y8^1;!14o{9d(bJLKTuRjK$AEuX} z&-3Z?pCfW?Amb1mVxFJGb>_QOHvrmYd@Z7G=5hooC)Q%Uuxc9Ili>9 delta 1013 zcmVWWm$a{?(hd%-nm z{!Ur5?)~eV!TQ7h8fu(`lHlI}QeLoG7-?E~mz%va<%uucj(;Fvg@7l|W8{90qr)^q z>(_y)BT=}I+YC-V@2^@w5cv!Uyvh4R<*E0}(}*gHaP}62U_O~4?CF^@lIAG4)-z*( zGhiq$2O48m7BK|eyqdeyxlUdJCwD#oVv>rMQZdcqoCU#0`n{Gzo3LI+JyIEO9gl@^ zYBOwVi`J1>Xn&DFm!O+_TG9RqT9EFyxI!+uuI9};d^X7`NarubX)?XMIJQG z8*WF=fPeI;7dS{yb1yN8?ET%Weae_x7m`+1rsTWo{yN;wE_$H{0LSR> zyOOT2Zx&nsbsQOk2ISN#)F32I?lCxucJI!2!lI3-_q|>oG0xjvjH^s#lVZbyDk}pJs6w0r`eEr9TJv@7h;2@bbVjZS4{Lb_F@S!UUV=W)r_Xd=2Cuy2`Cbq%}M?NObN(yprR=I00000NkvXXu0mjfwj1!P diff --git a/tests/snapshots/nanox/test_register_wallet_accept_wit_v1_0_1/00002.png b/tests/snapshots/nanox/test_register_wallet_accept_wit_v1_0_1/00002.png index 96d456c54569dac68b6d75c0740c66b90a5e0bf5..8ecc1841238a07d6b07376cb92afbb3a647074bd 100644 GIT binary patch delta 791 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 TUC*>T00000NkvXXu0mjfPmtvp diff --git a/tests/snapshots/nanox/test_register_wallet_accept_wit_v1_0_2/00001.png b/tests/snapshots/nanox/test_register_wallet_accept_wit_v1_0_2/00001.png index 795449674900bb3acc2e98507c9f69fa56a3cb5d..0254f586a604700fba05a771a38dba93f485f39c 100644 GIT binary patch delta 1009 zcmVwlU)-~f1r60yxS{Sz^5 zIkcbFX2$Rg(7fL#LZ1)DPjsQsdzPM`i`JU6~PkJr1uxG)QHtFuFKU< zJPsP{&StR$;TR5p=C7-R(M-hQa<3Injsu28Wz?$P|JOLd4JZ2h<*M07FWj|!Rv2tn3lg;p!DghX53iOmjd z2$m>%Wcwo9@yJ?!67x0>N!T?5R&A9Ni9{l?4;xoO9DLE{KH*DMzQjaUS@=rKAT>Er zN*aS!JqBZWU@WmkmT`2gg6s(p6(aQ#wyM}0F%obR{C}cnvDge$q&;!5a8AS;$Ak>; zg!x9XNYfS!-VC@XLnGPof-1CfBo0%w%FU$sc|ZU>3rvMXS2&MEY#m`+ zZj3_i|9_b{GkjIchkL)`u^6QH4z>tCwbuI z1VC(BfZIt!X@9$NCv2!RJ{T!%1Ibyl*p?mKnSX;SMAp_2PM(hriW9LMQy*pp$UhBW zKH9;UgeDxMQN`qNdqDxHqWdyu+abPV5zq2M{1VQRgA6L1i%l-NoCrbdWfZp=jB{i9iHX zR0Ixtx`?;99^<92{#qBz6KD{8kn;xr25VJhNc|0?MxGJclp9@SmuH=Pgi z-s%hx5AC#*Ja^vl2BT~u57m%5w=vG_icyTY<)t{rp$=h_8Oeq|jHCaO#PKS+@fAla fi9{li_??H)_?cQ9J&xu)Tr(3#a zWA427xBqCL@gT9e2HXH{*n#8z6661-4IRBta)Auc#*ayK{C_^u2b=)UP$IUwX1pV& zEr<4}<(Uz#0K=Q(g!_Hh`+TZh6ljL)6fuRDbi5;J#s@)@I+87@D;R$yvLn~TxFT0I z@i=I$TgqY!3LzW-&1KsFV;IN9?fz+oWh!8dxji3u45=ir^NL-|HG3S4k0&FSugWqn z;f|x-_xI;<(|9_21FI( zB}f5j!~-abbEUX;6y%gK#B>^evSn(#qg$z=Qr3h==WEYS1o~MDr@z6c#>?eoK&~vn zt)-!KyqugAO2!!1H$UGKTe;0Iy{EN%{yIN?WP$=Aw z{eKf_A;u;CEXXQ~!wlMPa(3qeq!n=?2|2`Bwh+U$8{NBlz@A0&;~02np^R?xu4wdZ;<%qT2e@yNGMu{WFig0)W4~QV3&({ ziA!FxA(-)gnvc6K030L}#R_ZB+w6!nlx4>KRK&*q&t$A+{6yD1u-nY9Jnv$^tqKs2 z?zHnfxAgdcD5uCn6;kI8Mw+-5!kkZ@i_4f)94Faue+zm!&SgVq@Ep?d5vMDKLZMLj aefS5%t5294MdwEV0000({_n|2 z6GTK*y5~3uA%qY@2-(gbT=crG<2cUqtnK>eG*yqOP4>8r>$=n!1H(+2ssZ8e9a~ep zfBtfOj#9ZD*<6z7|4Jo6(&Ja#lL(-l?$Yi6ykR_x-p&>UG-MiCZ4Os7|H9N77(?6n*jleddiis+4ZOa{fn4+o{H|xPP;>`Vkuti#E#}vxo<6U!GAdcHw(SSyX(gPo(Z_=wOqE&0a5JELPXMWGUs3^Z**_B z!ZBgA_X<+EODVD8Y`qDOGIwJda#Kp(;tt6ZAP1n@r2&=@szANLs#m|SbZ2YQh4KW#0e* delta 736 zcmV<60w4W{2KWV#B!9n2L_t(|ob8)ka>XDBh0{)VlKn3!d+9^wGG0J9{>0?A=X zi|u{R$~S9J26Yva-v%;G%KvmLT3TPJt^{iGQ+os)&xttY0z0T z?|{IX<%Fd^wZ652bOoxB8pU10X~a7hgsWj71F9r+h9DWBEOe}nz941?N{3b!N3^x! z#rh)%Qy|R_sF`dp2*fOl!~Nn@J*8&{ls=E=gKS|$GQKaRYFOcJH%#|m&mkEa1w;=GoIPvsPZ~g9|R!>~>xS_h6+QesiXB{#Na+a29pK)4~akkK; zj4N5|+#RALH6lO{G53*GRtER?vSILYvHc@Dv??Dj?SHuQ+phMY&ufydaJ**Y1r;oO zq&IxuxHswA5JGJVHHK0Vt@MQj{4FhOytdMtz`snmyBVCqQU`2sx*V~WJMCb^#W4gN zZs?Qb2cbTSt@lR_y#qka_V=%ev4H9y5krP^6>#HEpeHU9fHzOfdr|hL^;&r~i?7RQ ztLx_f_kSEPm}+#|UOM^bIN&)s+SNWFB{xJNA|ytp4=&}2=1tQZ9ZJ`lAZfcPDK?zd zFX1Noo=Z(;nv%2_VX_0t38?Z}0P_bTAkSCTr1la#yuV2aHbk7q4K~3;9@3hLX-iv^ zwn7q|Qb-@_R_2OZ?4n%Ib1vY5yHV8kEoE%Y6j>IX0n7fZO4%#bswO6tL17AyK7^a- zJ4*u}tYN+b><+aDCXy?iWt22%?DhXtAcPP?2qA(I SJpwfV0000qSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_register_wallet_reject_header_0_0/00002.png b/tests/snapshots/nanox/test_register_wallet_reject_header_0_0/00002.png index b18a7f9dac53d0afd50bc877aa1b998bdaa595fc..fc56072c49e7bed1425067411b16e4c32bfea72e 100644 GIT binary patch delta 669 zcmV;O0%HBE1+@i`B!7HKL_t(|ob8%ha>XDBhHa-iasNwlFMY_=v4Dt*n&kZ7Lno)f z8wetk5C8xG0002k&X-q5DWwoXj4?lxpVzacVNG(;JeLmF zF-9qUDzC)z#?dg&22hrr_r7uVr997TYe7crL7bRnxDB}71J1JOoYa#j7j7DYZpG4b z2nMLKGY|m)z<-0WB!%0?ooUN&;LXG|{fECAo?!>R1{kPV%#323e6N_Xno=!Al$8_y z%oAiKWwr?Oy%Sj7LMdC;>ZZJqM=C<3+@{ovI9Yhrb)lSG`8QPb#akJL6?uI_8UNY) zwrjJKetJD%{2tKd{*$rdcuL;o8C?ukL%C~v3D=q*WPhFZgYE%kOcdi|SHX5qb=Mt> z_Op);ERcGD(b~;pr!*K57SC|8|EsF3G`FKSA+SQe;53vB8!Y86>Q%1k&3v(zb%=S0eIR4y zz@4ohW`A7_Uo3gU@~Xk_2TO0TUK}vMg=KGwR~Yea^TQtdK<|fNWXM~k7+EVl@}36< zIu(VsLX^^cAi{P73=DL{04G07As@|&56>ECfMaLCFdq>p7BN%Bw6vYE%}1o6GycxA z%;tx{V3wVm5s?i50000000000000000002+LKc1j5P|ZOsL`>r00000NkvXXu0mjf DB>+4Y delta 659 zcmV;E0&M-Y1*-*+B!6;AL_t(|ob8%za>O7AhHa-e@%~5hF8z_IV*wErb(6f$kDcs_ zU!W*#LI3~&0001BJ711%rIbPlF~Xvw$FuY?c_0dnay(t5P!rW#y^5ITSA^{md|b0 zRxbHb^oo}5$RO8ws*^jwC^_bE#9E~ZhX>|s24@3YJG7ik?Zi7Z;Vw$2w}^!BTtsUNK`TrJ9N;(+YuZ{*db_NXd3P-VsnJlKI?u>0-aSff>@BEh8dx7xZO zaQ6d?FngJFheD0*nO_f^H{34ZP1wSDdm~T6{?~o==UnyvFlC&#xh5&YEbyOqvGDSI zHhIRBWk(Aa-S+IBH-DqF^>(MP*Oi;Uo=C7YI#4gTOM2J*8sqd+m+t-hvU0Iqz@NL5 zT@R*DTYpt{#-+J3?UDtTmQ|ZhT$wCzU|(D+$M&tSw`FqchW>KWYq+?>?!U3iZMWQ& zk`uWX^xP?%ah}KbcG-s4!TV+Z=HA`^YZ24V`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_register_wallet_reject_header_v1_0_0/00002.png b/tests/snapshots/nanox/test_register_wallet_reject_header_v1_0_0/00002.png index 1507a4c67504057de0f3ca685565a1d88e207125..5cc6b9240d53b472455430eeba51bba9817b6a5b 100644 GIT binary patch delta 616 zcmV-u0+;>y1c3#RB!5UrL_t(|ob8%has(j=MNKL@asNwlFZq}n%YY&(Xgj&*W2ztc z0zqXu1ONa40002C^JP_0N-2a8W6am&_I0f(*phVWr)zUvzO5=Es?XRCGNr_um?p+} zR{J4@pPh}By3>rD$md&bRAQCIZx zF-oXYcvW3*3=Ly!0Abj9?kjs=%JY3~E67x9sCG=#+y>0f0cUYqC*@6)2@efHkHU2w zf&rTB3`76`aDOqHP2sk7SIY7ecz0u({=#2P_izAP159KrR$5VZepF1EO=+eg%FGGB z<{M;T%d8RRb0@I8g^;#v1~3^^rIM?abtACBN%ln{!09L%HgJWj_p<+l$pCm(hv$4;k5T`N zZtAg{CSiIYTfdB3K~6nlj=LkL9?OUP_Q_6wuObcu103d>H6U|EVEG(|)Qw$`BRmT| z^!+oKVeya5^-2H$0000000000000000002sZhisgigp{|ekR!f0000F1DMQNuyVgE~FFa7XTLnR>#5GEw|d}N$h zyd)6j#wh^+00000@Hk(Ab(K<5N;zk`W?!#sPr;VuqJA!I&gMI?F6Me7c95kM*~Bn8 z=Z)S^Dg8X$UhO;2$eBHTl|f}up<8S%s`X3bRz1{*sIWz@0Dp$s#r#LoM$4d~l0DVg znz`&pH7k0WW1U==sdlaar{!3}QA^b!9PU_b7=iOC%@B(uWNZtrs9f4n#;xKTS?B#^uYfuys(<;hORarC+FgOi`?N*}2FO={ zGupS?P8~32tnT4z{gv3_<<#^2WWfGxWsyPS_9r^>ynI&|P!5 zzuqzcA%jvXIoeq#f*9=Nxhw=EH%>+jmLlC7`EKX~umMO_M`}Jxk5Qk+t@L;+6TKi$ zzZo}-Em=KcjxWcS9_t_F*H>Nycq?Kv2*75J*#n3p63hG0x7xZO zaQ6d?FngJFheD0*nO_f^H{34ZP1wSDdm~T6{?~o==UnyvFlC&#xh5&YEbyOqvGDSI zHhIRBWk(Aa-S+IBH-DqF^>(MP*Oi;Uo=C7YI#4gTOM2J*8sqd+m+t-hvU0Iqz@NL5 zT@R*DTYpt{#-+J3?UDtTmQ|ZhT$wCzU|(D+$M&tSw`FqchW>KWYq+?>?!U3iZMWQ& zk`uWX^xP?%ah}KbcG-s4!TV+Z=HA`^YZ24V`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPD13?t`U!{kww=+B*Bb>nZ2Yl(O%8x;PV4 z3cXA7Q@dGa(R7xR7f~Fh=Gt(Z0ofSj?Q){0@Onf;^s&=*s(($%EZWU-@*>n>i-(tR zo&lMQ+*f1D{gGATYV(zz#mhtI4wyU^Uz%zeL1V%v1ks?G1=cKQTgpI6&Un4~J->oz zIL;D}KlGH1J+LJl(F(nCmP$=N#Q^{S0036u%d4WGg<`WO%?^aF!^7$MnJn5`?mOLW z2ApKW$D)I7?|%zv{!`B*)}vHjHAhuB`e;-o-6mVE|5F-(qNJrKUMf{`prJO)Mag;t zvHJl_1cb3phHuD3Xz0Eu!NhCVMWM%z*t&EG^mzxke}pMJFrp!GM^H@M3?sBu(3n9l z+d!pxI|PcEV-ZDpnfuoKqBkb}w0aiV=j<=t2IeX=V1FY!FcChF>;q72YV<(|DvgXj z2&JWYJ9mlY;7~U@n696S&_9hZV{TGk35)6=O%YE!@t=16vg!%1nI8!ii;Mnq>-wk? zt>YWxvmRq@_p*|UX>2y~_W^kw_}@F3*K;_E5lz2<3rGg k^SOT?V2N4)002NBKP$ZK_XWKD3jhEB07*qoM6N<$f_v6YN&o-= delta 701 zcmV;u0z&=P1=R(RB!8SqL_t(|ob8-jnu8z=g`Ix06ZgL)_c9O8FewQkV#39q|H)D$ z;TGXwyKMjf00000tj=*9$8n7IVkKUVWu>O?+y_hd`gaE#v~~7<*Hg}qDP`aHba5u8 z6#6aAPwi%zMblYMev9HTHP?pQ49LbHZ1dR!w5JZD!7Fe^KZ7BmOIpg)@_gn?h zaGWI`f9NS2tFR>;*+(=reYIZHVE_OC003~4FRy}vHj2%jG&>Nw4-cp3GFh~>+&bND z2ApKW$D)I7?|&O<{!z~(mZKD2HAhuBS~aSYZj)`-|0xYXQPR>AFWpsgprJI&Mag;t zvF8Cx1cb3ph9Ag8Xz0Eu!Nlv-MWM%u*t&EG^mzxkFT#`)7}1b;A}A(Wye-{m%%I=f zK*iw>fnw%ZL{T2*z9qlt7n3fno<+8t{iWN$TxAAqu*KqOC!vfo78v0qB=-Z#J8RJN4tJm^@Nvf*_|1s*{wFJM0u58 zyKUkcgiO24sTW97u1c7`HPUNg7i&3#UrjXT=YzT-^vxM9Ltf5pxJ7Rr9%tI-^@P%_ z=c|dK$bUQd_itBJQygYMdI(pgN9FcQSPY4sVXNL|Sv7_@{SugnIIsmKf&@zd z002|)n0@av5!-r|4jB1fkSHsr6jATAD6-tj9S!x#=v$|ox}&>>8pL2ND75CHhB{kl z8X1C0|IOf7zKez$%6K(Y7r#OapFu;N=pk$rQ#MOtq~!O7EMM)|*@%@j)U9xb6qJ@NIjIf=0Z{=nX z9|U6PlmGw#005TrHOo-WIi<91Tlp40_is-{t7MSQ(B=;Lo@Gc3ePM1VbIxrO!))7j z@93wLepWVCkDaIIqI~(;I#qb3WQnz?+HVV6b|Tizv=tyw^?z-DB(1lC($7-9*tBM@ zNK~Vur#T@qG*aER0-Pns0*+d%cHywFG}{w19k54_Hj7+nXwIHE$(MJ|rJ z8lyTkJ6Y;}Gtn`V9nk4^nfp%lb@}#OYXuqAf-20@+ybWE1MVegpX?u^rtr`Z^e962 zAsk?`G7td(ynh%GF7qdCmQ}rzH6UZ9u!~oBFP8Q8_N(TqDxG!5%_qD{1BmS+WcB12!vfUvgwfUvPe zaPvK&o~rw|c=s16rwl$yn8kxGV&c_E{qPu>z70+hW`7a&f54(sfyVBG!>9lC!d&!a z)d#r4{h(vPS-2xlJxz8t8&6xagn5b$W&0}TPsR)$HsrMYKw)NqE1K3UXY1_btP;xD zQtKu?o7V{z{0ASrmyjp~PNMc<@WAi_0000000000000000000000000gz*bd({H#t T0XD<{015yANkvXXu0mjf!?yeD delta 499 zcmVF1DMQNuyVgE~FFa7X@AwtM9Mz+(Q^W_*> zTo8yyQUU+~006k0uZ6x!DJi9#bA1*+w`b3XBg-J2q1D-ZFZ3n4zOuHFrIfykX>!gt z_I^s~=i>U>zVozP*w>$ZP(@T~k(i6B|K51yr)pRgwv{tLpnpotFOt?;L2YWauRcd3 zSG-iSqNh3`GA>iyIRl)Qa|uWNstw_^u(e@W9Dr?xwv8FBcy~4U5N*;6A}|G=)TbU{(*Zbe6(O#r#L1}IsQ(8z zohP%Yqr1<(ivG^W7Pfl~_6v(e9Tfe`(a7@508eJHl}rfh?I(oIO@f=x0qs!Tp2elV zcyq|%qlArk&_PUG8L1B*C(Dg=vDkR(S|!Y5HdXBVu)H(paJM3-=LZTK8l2H|&2%2^ot&S9GB?%CSI_3-1PlH` p3_h2TECf!X)?x5K_mlns7!;!(aeT4JulE1|002ovPDHLkV1kqg{B{5U diff --git a/tests/snapshots/nanox/test_register_wallet_tr_script_pk_0_1/00000.png b/tests/snapshots/nanox/test_register_wallet_tr_script_pk_0_1/00000.png index 6c7223c002da8b2599323f0c550579fc0c277a7d..8d101dd800357da2984f26b9b23ae755be7d8ec3 100644 GIT binary patch delta 1029 zcmV+g1p51t2%89yB!A*bL_t(|ob6j#a_le&TyX3FV6=8 zD}Yp#1C1#b=dl#HhjF-ZTRIi+%FYKsRH(3&ikVm}TM&3Cx${#~;yR#3SkIvza2Z^9 zcC>2Yt1Z!GbAJQq6m;OojxP)kBYl*tAJfc*q%|Qj(S+`cv>Klzz{-x1@Z{?#?w}OGXqho84!iY_~oD<_w$eJI!T7h% z)-k9DmY!ohwYvbat!Ftm5v+#0B}DUr@zX)S=@y(aejY1=qyPU?j^>P0pP|!!@-5^oBf}+__M>k zcV|=@7`%&j=TpE^1?ctAqzv&zn5!+2qp6JNdC-Ws$~#`i(cZAb#W1_G)a|=I4bk%< zZ0IwAaI}BvMl8k3?2jL7W;O3p)o3&tjZecj>D0^4kcBN400000NkvXXu0mjfAMW>B delta 1019 zcmVEFkB8<8T+vk0b@-lA zMuDLCgWataMNt$*Q5417`EuU9Ua!{LaUA`*|IE>apeXr@S0OFjRTCScox_shC#dGg zpDAnBy?^|t38%|f4f;t5ao##~;R&0qpHg@;KFw)$@|U;68Go><0y9j`=Wu|a87Lp4 z69=P;W@$4Sd_zCxMuQ}d0LPp1dwO~3{d5@hhH5w~flNGMA%=*umWiPrpt6-^!wD4u z4ZQ3Nby%6i7`m9nrJvL3b!yeoOjuYg*FaT>J<>sa%+UzsNt zVYwwbtxm#DL4PM_WcBrvG$LGYd4aO#y0jB#Z{wJat*mXRZ-aLZn1vtyov`xNYlhFd z4R8I5^d|kuEPm1Z9P*LgFN&i0Y~pNab5nh?#L3AxC827+8Xjn!&+yz?~LuG_f3yW8pd0 z61xjB+j^A&xnS{gsOl$^6Ag2mzUnl%hjCJ;X&cOgm{jK62UyRl<|6#zs~Hia><^EJ zOm20kx(TNZB`eGhz;7P<+GZTtU~4 zUhZ|m#Sgi^1CZMt-Gt+uHUEU13@o150T%qEymA%e%td}r}y`BC2{GBFpXU}cFqmkrOc zjH$yjon!ehUAq4yC_REn5>*YG;9E-$DK;$hLu#tN)6f~_vk|cQAf{4=q!Ei6bHY~| zZu|ql{mD4|s^QJzF4Bqn^8rUmC~$9LJap&)sf<+YT-d(E|9PuFJKTGB)>0kAH?i(~ z5-ddku7|^vA-@Pqv5DkpSjV#5DP&BQ4d0ieynWXfzs)Mx)VaG#VY)M^8*Ptt>6+g ze&eca@&5IV!R+CWhKiFA5!~r2 z3K+`Efw&Zl>sSh0!+@(KMf$GTCmggq6o>#E#nG#ZU35$yq*yc9>t^s?u1GQ5T4 zXx=gCU}`wjCd6rqsiytcm4QW6n|4Rd~7gd++q&YzYFIakY9@1 zZ%kaoZkU`}aF_9PnyRE{U~1)=CJuf)mQ%JQ0l?3fV!6OIFeepM>oef19G}`WO*EP- z_$v99Dj=gRb8A^`O=}diu8lLZ-!SoWen4a5B1*Ms!{OPMZV(i2#$(jaJ{Y5fv z&rQ9i3x6Ior9&tU?VCiIY19N1@%j?VYfmW9ogc$0G)E%x>oF zyGY6@3hVs@S4@TK8%FJ#nsShV*x7OyO2)%M;eRd_Vcy7ave46}mK0_76eKCN6#>8N zk#1)HCFmsb(kgE8et3UPfk;Nr_D6J1)s8!-m?q-{0{a6><22IM`Tn8V5d?b~s?`7t zt7f%+rn=_4opq$%@st_wI0Qxk&<;Xec4+qpqxH<$tYJe11S=_jnejNgGk-Q7BZkkukZGit`#gR0*Po3>qw$}>qs(HKEo}+fUq2BKOizAD=a>_u zzh)zsoDw9{$0~&Xi3i3*rr4xdv0%tb00L2nb3i{V9Ybrrt{t(>vPdg(rSq^Nv>k2$ z%ukeR+VG3wYvFr3@e$QvUsfTCnVmh|=yeV+W+Y8^1;!14o{9d(bJLKTuRjK$AEuX} z&-3Z?pCfW?Amb1mVxFJGb>_QOHvrmYd@Z7G=5hooC)Q%Uuxc9Ili>9 delta 1013 zcmVWWm$a{?(hd%-nm z{!Ur5?)~eV!TQ7h8fu(`lHlI}QeLoG7-?E~mz%va<%uucj(;Fvg@7l|W8{90qr)^q z>(_y)BT=}I+YC-V@2^@w5cv!Uyvh4R<*E0}(}*gHaP}62U_O~4?CF^@lIAG4)-z*( zGhiq$2O48m7BK|eyqdeyxlUdJCwD#oVv>rMQZdcqoCU#0`n{Gzo3LI+JyIEO9gl@^ zYBOwVi`J1>Xn&DFm!O+_TG9RqT9EFyxI!+uuI9};d^X7`NarubX)?XMIJQG z8*WF=fPeI;7dS{yb1yN8?ET%Weae_x7m`+1rsTWo{yN;wE_$H{0LSR> zyOOT2Zx&nsbsQOk2ISN#)F32I?lCxucJI!2!lI3-_q|>oG0xjvjH^s#lVZbyDk}pJs6w0r`eEr9TJv@7h;2@bbVjZS4{Lb_F@S!UUV=W)r_Xd=2Cuy2`Cbq%}M?NObN(yprR=I00000NkvXXu0mjfwj1!P diff --git a/tests/snapshots/nanox/test_register_wallet_tr_script_pk_0_1/00002.png b/tests/snapshots/nanox/test_register_wallet_tr_script_pk_0_1/00002.png index d283f94fd46f0eba7bd3ab5c99f3fcdc3de5cdc7..76ea889910f94559f6cccba804ce377b46a84f65 100644 GIT binary patch delta 762 zcmVVRE_twuV&}I3F`DY{$weF* z1_m6r6ha6ggb+e*=gYfs97ido*4nPy&uN++ZLPnBx6+Hes-}KW41%`PjGJ|uh2e&q zx&C?@VZ^f^w-p%KfoWeC#&u$mKZuAD&Q?*uoNIcHoYzCMqkr#`ZqY0$pNqI%_p;{} zpH?-;H)36neyz3dOe;r5e>#q}2V3i++*9cFOBna;^d)H*be%v(NgW{Mt_P*XT_gop zC`KIVk#?%~N9=e_5`x4E?aPsBCR?L+1NU?z#@%T(bg(A`&5lkcW`(0b&n{Q3^dXvJfY@CoQq$01&e$<{CHi zktKAJ4iQKNiu>m8t_pYQZwe}X(jafTHK&r_P3y*K%lwF0H1aXcwVy0j&l zu9Y-RRo`k>a&{g|4j39NaB!dOgB{2aWKLl-wt7j&AkN0I2#olqO~hJNpXBr$*LIp_ zM4lECAAd$%(Jy8C$h!kigRAWcq8E9T1ImyO9-?@Wr#T?t-}>Mc{O2h2e3C(?54NI* z_p)!oabxD$D>(9|IoFA#MbK!f-|NDoNf#56Ry1?2NEX&CIj_N0eorvCI293ae1bnX z^f!x9N$K^A@rFA-EQvP?J43Kws$Vp&}X4A0)=9cUbcYF`n zflezSyX)vUzHj60NjJ~+O&AFm@d^O1_px^c^k+e_z|C)mUc%BlQ+jQgKlT4U-#x(z sA%qY@2qAKezvBf&c&j07*qoM6N<$g6eT_sQ>@~ delta 760 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 TUC*>T00000NkvXXu0mjfPmtvp diff --git a/tests/snapshots/nanox/test_register_wallet_tr_script_pk_0_2/00001.png b/tests/snapshots/nanox/test_register_wallet_tr_script_pk_0_2/00001.png index 795449674900bb3acc2e98507c9f69fa56a3cb5d..0254f586a604700fba05a771a38dba93f485f39c 100644 GIT binary patch delta 1009 zcmVwlU)-~f1r60yxS{Sz^5 zIkcbFX2$Rg(7fL#LZ1)DPjsQsdzPM`i`JU6~PkJr1uxG)QHtFuFKU< zJPsP{&StR$;TR5p=C7-R(M-hQa<3Injsu28Wz?$P|JOLd4JZ2h<*M07FWj|!Rv2tn3lg;p!DghX53iOmjd z2$m>%Wcwo9@yJ?!67x0>N!T?5R&A9Ni9{l?4;xoO9DLE{KH*DMzQjaUS@=rKAT>Er zN*aS!JqBZWU@WmkmT`2gg6s(p6(aQ#wyM}0F%obR{C}cnvDge$q&;!5a8AS;$Ak>; zg!x9XNYfS!-VC@XLnGPof-1CfBo0%w%FU$sc|ZU>3rvMXS2&MEY#m`+ zZj3_i|9_b{GkjIchkL)`u^6QH4z>tCwbuI z1VC(BfZIt!X@9$NCv2!RJ{T!%1Ibyl*p?mKnSX;SMAp_2PM(hriW9LMQy*pp$UhBW zKH9;UgeDxMQN`qNdqDxHqWdyu+abPV5zq2M{1VQRgA6L1i%l-NoCrbdWfZp=jB{i9iHX zR0Ixtx`?;99^<92{#qBz6KD{8kn;xr25VJhNc|0?MxGJclp9@SmuH=Pgi z-s%hx5AC#*Ja^vl2BT~u57m%5w=vG_icyTY<)t{rp$=h_8Oeq|jHCaO#PKS+@fAla fi9{li_??H)_?cQ9J&xu)Tr(3#a zWA427xBqCL@gT9e2HXH{*n#8z6661-4IRBta)Auc#*ayK{C_^u2b=)UP$IUwX1pV& zEr<4}<(Uz#0K=Q(g!_Hh`+TZh6ljL)6fuRDbi5;J#s@)@I+87@D;R$yvLn~TxFT0I z@i=I$TgqY!3LzW-&1KsFV;IN9?fz+oWh!8dxji3u45=ir^NL-|HG3S4k0&FSugWqn z;f|x-_xI;<(|9_21FI( zB}f5j!~-abbEUX;6y%gK#B>^evSn(#qg$z=Qr3h==WEYS1o~MDr@z6c#>?eoK&~vn zt)-!KyqugAO2!!1H$UGKTe;0Iy{EN%{yIN?WP$=Aw z{eKf_A;u;CEXXQ~!wlMPa(3qeq!n=?2|2`Bwh+U$8{NBlz@A0&;~02np^R?xu4wdZ;<%qT2e@yNGMu{WFig0)W4~QV3&({ ziA!FxA(-)gnvc6K030L}#R_ZB+w6!nlx4>KRK&*q&t$A+{6yD1u-nY9Jnv$^tqKs2 z?zHnfxAgdcD5uCn6;kI8Mw+-5!kkZ@i_4f)94Faue+zm!&SgVq@Ep?d5vMDKLZMLj aefS5%t5294MdwEV0000HROM_mU4Q7K4D-N9#=Lo-fm( z5fM@8Nr@0b2qA=!?R?>)_kE|7uIno8^5-x`kEu=exQ+Y1)ffZAOqrqq;d{o`CEmaO zNUvj7bF&BKP}8vT-#`X8{%6=q>3wCl5-ij(X2#0_VOki-fF@-IQ&7<^8)Km{mdEP8n!PKJBL>&$ zrJj!BKNdHkX}l?MNk2IHe>+Xu?5 zI`H(C;p#@0F{Y%aTnU?9_ZrZ?h?(aZ`7k)S%NK(?OMk5&u>nE87>9PO{McE}468V5 zf_9(>jHV#)5pDRoF)uNJwt_bbkEv2b7h`DwzeSfA_aeOu{F_8_7Bo1DeG`!Uii#-) z%Ea2dEqViBk5iu{KLzzU?8tn0=oNq%cfEc`j0Kc(L=5T9G{DS1ft|Qa46dQ!-Y05j zy~oO@S%28km@4OaaB!8tzL_t(|ob8%jcElhEh0~tyB>P`d_R@!(au`9p{)A+v_j^iH z6a+;jvu%VBLI@#*r1OP~9>=k5+rIDeEPsw6ow!|Tb!i;OQ4BCJ%$1QIK)z?po%jC! z$M!nrA~rb`4s{Ka{{}K$#{Uc(s=Z&BUI^6W^&~o<&*=jWz<;j7qFZr|eiKaXE~TsJ zUIBqO^?>Dl)BDy7(iLb%(<$y0Zf3l5Lbw(NGN4JqUlA`r7Ar~Bkxy~)T5&@qq4gDhc0GCnUg&9K75VOSo&kxf`Q)4lAU z=gX#vdcPf3t$&r;Y#!|7wfBWpcCU`}UU1@w>9_~ zx^DcR7k_}sQlr!M(!oC`0MDt>X2*bNZpcDJXgHZMxRiHtZ?o(%Fqm4C$#UKd**D=O zj9sI;9GZ4hOA3G3*sU7`v3p{ diff --git a/tests/snapshots/nanox/test_register_wallet_tr_script_sortedmulti_0_0/00001.png b/tests/snapshots/nanox/test_register_wallet_tr_script_sortedmulti_0_0/00001.png index edbf49818dfa556f8c3f45462e4b8fba1dc9f1f8..2a069273e65ec0f78a66a0ed3dbd8a42a9eac36b 100644 GIT binary patch delta 622 zcmV-!0+IcY1&{@hEq_aP!!QU%)tv6c`(Kjw(t%r-fWSxrSx(*^B^U$xI(kki00000 z007*bT5GNK>MHKUBQVy{^^?co)}#JCAqVZ9ZQE?i{`IhI+je}|jfaI^rT#Q8b8e<) zp7Iu>V47}>uob}OpzN0&+alvM6VYZLpO0vUb2BgVl(*1=J%1H;5xfFeiLzFw<@K4R z(c67mTcRoq9)QL7;;yB}NSYHdTM*qe*~ZE|$1E436%+O3kNg!xw_|3kf7q5H8tmDQ zXuv2>?XJa_H~;_u0Ko03&s<&3FT>~9*s$}MSy@J|^#`C&ity-~<@sPNzZyPGMU%OC z^2&5t8M1-RR)4VbpeEQEoiKe7jI1J zRJzsB3{BjV&N&86L5YUaJmo$!M-!a!M(lND?--u`m|a=eySXU%0Gzhd*a5Y9Cmou` z(we`$k21|)%c#-i?{_}w-hqu}onO$}<2o-zNRS7;uz%E>kavYHmw$%GcAXVao=@)? zkz)foOdtoft1$)>IO$}JK`M)OuSbM9wKJcAU0b^)>AA8Hz52;OVpi={%sym^8IN&WboS#eu7yyNqI-6&hr$fXF{)eKAtpg6P<#US-sd_MuGB zKId?chwvNob#(#bumi`1l>h($000000000000000001<80Pzf|&=x;}vH$=807*qo IM6N<$g2gH@LjV8( delta 622 zcmV-!0+IcY1&{@hEq`5>gD?n%Gd;5t_rIj>=5I*L2-2()!{{p2yY^{9VO@IiZL+csOW|2!nywjCF{@Q~2ERG<1~%1zfy zQ$At@Ox=wUwgT83l>M?}OQfBqBiiia`mkmwH~lhA`3Mcz6MtbB!7G4;C}VX>UY}VS zz1^p^B`U(;0a!d2cP%wW(wvA%K{RQy#L6_sBp0Fu6Seb4z6H^A%!Kt1TT(=WJ?Y3l zqp9oOcF}+V00000Ko<3xtHb$a_#7K+b{;b$%kZ`S0Q8k2Jax_Td@z8^%m)WkjRoMX@|C{a_Irpz;QYJxMqh`o;N9YfP^v&#$nHWvjSfYWvw8Bm*dQlTkq zdhgxJG=0sZMwh-{`J{UX63aSo(AsvL=OV<&gWg!`OMl3_LYK=w!(+S73MkK~_YBLi z1|1@hgWA;?g9)5;GR7d4MZ4EiggBKmoq?>aJ(9GqEJSbpWWaKWX2uxApM+VRQY&W` z@#4!0qO$O56huqs0aeC`mb8P)>1U;s`(j1=>$WYbjFt=`J0ZS6yO zo44|NY{GBM*VO@x!wwu5Mgjl;000000000000000007YV0d#PrqA%VflK=n!07*qo IM6N<$g6obTV*mgE diff --git a/tests/snapshots/nanox/test_register_wallet_tr_script_sortedmulti_0_0/00002.png b/tests/snapshots/nanox/test_register_wallet_tr_script_sortedmulti_0_0/00002.png index 071d74207921de223cf91a0a7f474823370155ae..559a4847f2fe73f73bc5b0e75514f39aa0f5d532 100644 GIT binary patch delta 713 zcmV;)0yh2F1>psdB!8$$L_t(|ob8%ha>F1DMb%Ds;{7j)z4Rj!hU$e30^-g+UycEZ zha^BT5dZ)H0002n`N|ShN+F`_y6Q9g`Ff5tv}!Ku=TdcDzOw|esjuV?vXmlK40B!A z+1V$epPkCuxr>aP)vrJ0qOw(~Ma&mf`LePlXNBLSc>qK0-+%Rnw9zu^IBWeX)3RLl zQjLlcb*z(1Bh@hv2-X}6IBKhQ35PpI*(;H`0Iw*~4#x7__<#?_=r-uBV^s*6WOCls z80E-xiq!okabc1dz!`S6{b29g`tn?B1sPR>+Odeb4W!)z&a!Bq^bb)fd}s*zD3-r++(aYp8J*@yeF)Jqs|Eif9$bFIm?0sw*dAn@5th=TXhJEpjS%O`e2dMnYCl zkraMQ(YzC+d4N@6-cpK|i+3L8g|AR#F`JCDK2)acj#hQuhd53Ta}_zPN=HX#f7>ZS zRkXrBb|a5>?SoSkksPl))|T~fog$wp4;cI2SVCrlyPxz9ch6D8BtPC8URbuU?W(f# vPP8qA0ssI20000000000000000Kg!>d5(QY!NPHX00000NkvXXu0mjf;#gUI delta 704 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 delta 1025 zcmV+c1pfP<2%iX$EPtC>aw8!SL>b52r0;*EzKcKFB2X<^3(%6~dLI)~Hx$VZDNk!f zQ4~c{6h(16|D5U0^K7jh$I(CcuQ_@U9%_6wQ$&vQJbR&9O?zvIQpX4;UumK9t$#dd zLsiFDjrG%R#^S^=*SVgHRS?r_{Le`Q1C}Jv(vQRE`WzZKqj16EjscL2bMq2^@mBJ}Ghpm(ToW@5-+0YvL@!7)@jijgN`C{Pv; zsD;wXB^we?!+&LfeMQ{2K;51Fy6W?$rSW?h!Y7G%DS>NZGm;L&R|K8Rw zilX>a*ry=#08SE%31$pV9+Nx~{Yz4o_*{#lB?eVU7+GG3n#tWYkzLHf?GP~~PKK+d zNfk>;H%r(J6{Ya&61a#pHfFVP+LWtbTV&@Y(555lV1IFjiR3##Ys3zir~R7B{}too zg8YKHu=xo+IRd6;0A{kWmJe;Q7ek%lR27Qydudqo+y?APGb2z0Gp0Y+6J4l+-t8eWHf31E0HmFKt>CXt+l^Mh9qDc@osw zMuhX(GK_XAZ#Ye!nK2~W=~+1|l3aq02O!O98J07STW)1*l1>B#T91pN{A{v!4P z)PFKk6vYRF{x)=6{>(eq_|dlk>>MJk5;3R2)3d}HM8VqS5y(s50Y#EG;VuP>;3+lF zvPJ3>>IvT8Gqx*#rQLy@XTyn4a(w+f|Ilzj88rzzypX-s(dGf^Ys>SWk9xnn-M5v#gp5i8#?Lq2uhU vC^z)Qyub~;VeDU!mFm7#q9}@@C_H=vnsK+@ZoAjB00000NkvXXu0mjfCMN0e diff --git a/tests/snapshots/nanox/test_register_wallet_tr_script_sortedmulti_0_1/00002.png b/tests/snapshots/nanox/test_register_wallet_tr_script_sortedmulti_0_1/00002.png index d705c90af9583278f755999a9d2b4ab154848d1d..f504291f4fc4439a83d9e9c969bdca33e59864a8 100644 GIT binary patch delta 767 zcmV;_=u^#=POAQ zK*Sg6lmGw#0002k&W}?r=bTcyuB%*^+b~6s)JA_Av=Sia%vvhlC;?GriiVj!6-)Gb zib6yG6k8*X)gIb1ez*Su{v|V8nShi}TKc@M1BoMtBU4^-nSVYR9AOi4;x}MeM*q4l z+RpOa6aA5)s!oiyFr~PyDlAW$eo7gqOR2X5sF&;_mK5XBx1UIJYH&TTuvSw&QpQhT z2h`$q5ezYv%~Sk~+7!BZ)i9Z#WZ7F|^HF%Y%F8))A(ha-5P& zMt~>%0RRBpPIV2Sdp@~`3mmnKvyZwvOl0TRG-uRE40F9rpc=a36R2^0SY>s-u#%bv z^`|b2a?@q_9N6U8jy26to%k3B?vWp||{4BY>^- z>TTL}+@;nxoA$UQZ=LWC7)&3Tr!rVFoi|kHsoGcrdmU3pZ6myk8gCG`xZl-TR6W0| zNin<6?SFuzI{%>djBn3R;MslfbdH;azKTYW(FaSB;a&ShEcO3IMg2rBwaIe;eG+h> zyrO>hXNHbG=#4CrMwy7+N-L^erzcIZT3KnFCAA>C8lHXsJ)WCoEWwR@SLL6Cnj^LP zrTWmQBRb2UhKZUp#=A9{DI8af+cU$mXukd>r+8MIsmuybmY1V@=_+X%RXJOU`qTCK zcloB0DJ&TQwUV6wlfWUn;SHY59|3GE*COt3+jt?lFY1000000000000000007_?{sD!ikq)<2oA&?!002ovPDHLkV1mWPajyUX delta 745 zcmVXDBhHa-i$^Mt*Uiy%!!vG@UC7$&Eo{R?( z715BB5&!@I0002n`EttToKs5Ib(L~?j8T+GRrIHkE@I@I*)XLUWj0iqqG7UGr88O{ z*Jdam?`Y7lTBR-1W%f_N#AG@w6R62k_qodf$B}!HDKEZEYkvlJ*j%6Z4)m?gCLL<2 zZ_fUB5R>7;5T+EHRfVOdX{VHNnsn2*0Mt-c2>8XsBSfu{-Kmr7X~Kp~^+=g6`WB!z zWf#E^lWY$0H~SBEgYF$bSKA(mXY)EGlUOP#+%>H-{&cmCHB{+7gbR1LFX!i7*)*-XTy8)GC?dQt!S})sE|snw)6L*z#&GOpMmZ zpPa_4P3&}wsyvpMvEGE$A*ohQMD{Y+QT~IL+2f$WQh&)bueV*BmF=}*4x-98eX#jx zH23Il8fJ9bwVMm^R0JiH*LTn2tC7^%b}9RfiKL?!VPtQl*a@pOg~kGG9_^IRWGhUf zA6q;o`J)gIK{4&}3zu|f}hy1)j=&CZA|$q7a*zQ zI&G-q*MIZF`G7TeG0#LHaMPG%tie*`^sf3Q>_^_rYWG)m(`7Y*JE(e7RIPgabz~t% z)`&gIlUY5hotwBR7R&AQGA9=#sdT|u00000NkvXXu0mjfrl@jD diff --git a/tests/snapshots/nanox/test_register_wallet_tr_script_sortedmulti_0_2/00000.png b/tests/snapshots/nanox/test_register_wallet_tr_script_sortedmulti_0_2/00000.png index bd5a55fcb507062f79991f9022b19984eaf2f6e4..1dd0daa25573497622f4889f8f85788d00e59389 100644 GIT binary patch delta 1030 zcmV+h1o``y2%HFzB!A;cL_t(|ob6j#a_k@sTyX3!W`4r0e*zi+Yky!qkZojQeewFhQ%S?d6SoU!5tcit z1zaW+E|lC_`hRLAy6lc3u>~DC=Ey9bcpS9e;_lQ%<_}voHmeBx0n3?TeTMom1m}P( zkZ!95&=R|NL)ad})x9Wxr#}{p-3irqu7F)fec^nJRv6k6g0NK{F0;nw(pF?Fo5l%GZIDOY;$Zr^jIxWXw9>l0K=RUxC zW|E7*4`0JrF)aS@c!+STs_Q|Lrdnn&2SD~&&40C}3rboct}qHTa%#uAX4&YSB`qXz z#}n=Yz^LJ!3DMM9Y{7wPFk8VVYjtv`q0bj*Ch&g1Z#gFq93NT}+W&WT*5OZT4yX+|VT!o;MCd~4YO&4!Ksl1j-tiq168u7J%4 zF-94JK`eT#8DCM{_y>Ud$vD|7^=5Gw%74WD@gQeOXmBqv9t;3=20C^wY~SRcyxE@} z?!7x3rGdd!tUI3qmR5kQhbm==7h!6)K#qnoR^(125-L@^j-$Qd3l~H7%Tl)Q>KbC_ zL)g$~0^w-?(v4V%mE9jd)?_X3GSz4_8jVlGHz}dT&bR5{z5oCK07*qoM6N<$f{gs` Ac>n+a delta 1025 zcmV+c1pfP+2$u+uB!AvXL_t(|ob8)ilH(u@MVYDDiTA&x>}5V&O(}X_2^_mqI$sF^ zNxb3GJx0?sP17_@(|nvi{?D)1Ym9Lm$NW6M)|f_AQ`8-33dx)@%L>v`(#}kw^_m%2 zah1Q>nAThW_+h;F2kRTPc$i0Jx=X=)S*}mZ1Dw{RwVLT+>&vQ!gLMANa$1X+9E>cF@14bo%%M3!X(=m) z2|5FYXywqf#mXY)g9o;<_gF<{;~-1_1nK~5iC}J!mE>g0rw=q4-|Q;RT< zwVGSmaB6d_wtq#J-7ykN(8)Q!=KcwWLigKBnD0g$kJ-SSvyBt5EM*--!x(~lKo)%X zPn;TFw_6~r$8bX}%18BQvRIc-H^rB=e$zC~*W;anm}oQ8Egi;@Wt^1IwVzGiX&wEN z{>m=)i+K=9Dvd9sIQy-COfD41z0gD%s`a5(%8DV(Lw`wM#I}>wBb}Rbs4J)l~ zspT2j4p1jJ?u?dVlHo9hp{llqfz7f{xX}45%>cDg!gU#GQ~6WqMM7P$af6plRS+^KFGZ0t+Rhj_>Yw?Q?+ z>^uhTAb&ezuAf@i*@E1?=-1#uruDTI)YiNG4XzoZSC@O~*1wZ({X3DZzxhpg7$+@x z(3I)&Iu_nzEwj4-)z+&5s7)4MLuFqPO*GUveb;5=8OD)L%Q2W2G3v~D53oM7oQvR> zuVKs>7Jqm>M6^}a^&pL=T4tCXAnUBQwN)0(X@7;dqA1YFsU7Q?Wutf2XrYKZp70(3 zRy8#Vu3&nXtvvIDo1f(V4v^g5(1SFbv*(|Hi-E-xJHP^8lvkc&oVCdBi5fu%g!_qq z=CN{?pVg!+%6<(k)KK+N%iU}=x!W&AuvGqHu0E1pNBV!np2_!1jK8RQEul9})7%Ln zv40I)W%~@_R)MIBj^#-`#2QjER5OhCCP4Jjjilt*FwxK87x6A)j@W7Gqkc@FFc(U& zG=<&E)O#!vs(Pn$B3I?o{Wn3{B2pw_*<=yDlu z)G>Gw>&>UY(hQLMp(+{Tn=mz75J$s2R^(115-KhDIgR#)6D~&fWGT~kRSmK8C2Ht1 vK{VRm^dc6rvijrKnylqrrkbW{ns4JjOOU~mfBTTZ00000NkvXXu0mjf6G033 diff --git a/tests/snapshots/nanox/test_register_wallet_tr_script_sortedmulti_0_2/00001.png b/tests/snapshots/nanox/test_register_wallet_tr_script_sortedmulti_0_2/00001.png index d5b4078d1f4ae62eecf2642d5926adde0ca0f816..585af26510e6b5efc8b0e1b56dfebc9701b26551 100644 GIT binary patch delta 1025 zcmV+c1pfPx2$u+uB!AvXL_t(|ob6g$lH(u@WVhxfzW>`vXcLx| z)B-LO3KzEA+JD+gZP7CA3NuomCFsVTBXje_m7x1AKApPA{IF$pvo>L-uuK}69M&<^ zSHrspWPzA%o#9lmbGrqCEjm1ENco)pYq4%lIKs9Su ze`uF-Mj1-#(GgHJ9AXEOM3XAum|)oz9^OEfDVRn+ocHLj!vzb z#v0WMIRF!a0Bm$Cu2Xij`Ai)l(|O7;H7wsfgLDa6OwaA6f}^Rt{ONl;Vr=e}WI=ADlxf2S|DdTBy3Ee5b2r~!7Sw^xww`; zjKcF_8oT0!4nPWuy+7r_*Ed#X{~xhG1`QlXs!#(&;N*_MQAqdhd?(E22;U6L^R9Yb zatI|Urp~^Lq)bs*KTmM^RH(dR)UK%^2k8u(U4QOONxwTdxJgB*H!_?ow6v)uMVUPX zNlIyj!|z(8n<~EqnM77v`7PFi^-~=X$>^*+qI0OWFB~FG#xXedJCw$0gw^?ekn9M8 zy$scA0EV_^rGBcq>bsqFgx;}~89#9d^a3Cqgt+X`?hi)mnX|{GeVSOqh85scQu@Y& zwtpN&nWs#R!;Dhnadv0^Y&=E`pM4?I2$3j3CpOGRqtR&mQdpFk&$5LrPW$T}e#h|S zhY0(e;QXmJ(vd@gBz>$x_#eNc-zCK+`HDGRRs!G*g*XTF!_qOd=Ih!KTU{36id+#M zT7gU4qC>r00000NkvXXu0mjfTGI35 delta 1019 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 diff --git a/tests/snapshots/nanox/test_register_wallet_tr_script_sortedmulti_0_3/00001.png b/tests/snapshots/nanox/test_register_wallet_tr_script_sortedmulti_0_3/00001.png index 3e2e8b443efb79e6b93f62d46b3e9f8a3b8b49af..68378a5a6038534be86fc3f82fc2c8fb164f30a8 100644 GIT binary patch delta 1006 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 v=K&#v5JCtcgb+dqA%qY@2qAM5XH=Yt29AD zRMNqO00000006-0q?A%hyS+GxAH%*%=oiny(X;-$zy^&@j8T{5pG6X5EEic=B=j!T zr*@gLXqsu(O%#WzxjD>s09%7~Tr#?(?ng94hh45qZ;G;Lmw##2O{l{?9u8r=1DK1o zubq?m3DXB% z5~>0Bq$Ap)m1e7z^DPbl0002+2GTdX-PwjRcJY>RtX78J=QKY$0mG$;p3-LcemAav zDmtyACc7Ro+J9qLQB%g=8d}TN46XSTt5mvhsMY=Ey3U;cLv8hOWp3>NhxC*#riU=m z@UqEFHS~$HxCyO-zNmK7#E`y%WiieP^hnD;dJVf|4f9`cF8(v^57bxGY}zg@*= z-4mrZ@jz4y@7%(1yWD&_*7R!SqiGE%Id;d_lg8-=<9|5-L)d2_(9cDXF$a(0I=suA za}|XbzKDsq3OZ%Qx1po3@@KxtFEz@ipP~IJXI*DCC{n%;8YU{~ya>`V@2}48!q*O{ z-_&3Ba$e(W0_r?7og&gSzI@|v03hH~zBBJNVq yf5UYOVksbp00000000000000000000a2$VKQApl;i4%qZ0000O7AhBKYs#QPt~yY#`SLqSz1vY4OQcAj{{H&6cQoSg`Dxr6& zKDEn~o2HqjY@#?!&CTJq0@xgsaVh8$`JAR9+UpQb1`?SC>&*@QZ5@o)&|6~J7S zz8WR>XI78V@b&uQ<)QNc1kc4oOO5f+obX9OG-O-+yXi#iMd000009wh%|w>#TV`rf?d9IKU~k2%bb4#03J!cyA2{_c(C zPerF!)MVE~Mt?1K6*Z;ry{`3a&CnaqW|c}84z;@9T-TZNf2ghAufnYr5D-i0V!8_x z4L>%SsfIpL7I&dn&~K{UG%=*F;8~0d0zJ}-4_^UuOIUx^G!OZj!kz=hfXWBj?J7R& zo+wXi9*An;otrper&~&bu?0g6^#^6yxhj*EC zp`!4@jaZXVL8q+vHgptL{wx<|Q=@$PdG$Z#lyz2zBIWy_VWJY_#nqbT_Uh~|VyytV zQ-9g!ToP*lWS*H$5n)TVjBqbuy_Q+-S}KO85Nic6jFn6Mypu^@GjiKd&K*xATnhSc xgib*WO7EMM)|*@%@j)U9xb6qJ@NIjIf=0Z{=nX z9|U6PlmGw#005TrHOo-WIi<91Tlp40_is-{t7MSQ(B=;Lo@Gc3ePM1VbIxrO!))7j z@93wLepWVCkDaIIqI~(;I#qb3WQnz?+HVV6b|Tizv=tyw^?z-DB(1lC($7-9*tBM@ zNK~Vur#T@qG*aER0-Pns0*+d%cHywFG}{w19k54_Hj7+nXwIHE$(MJ|rJ z8lyTkJ6Y;}Gtn`V9nk4^nfp%lb@}#OYXuqAf-20@+ybWE1MVegpX?u^rtr`Z^e962 zAsk?`G7td(ynh%GF7qdCmQ}rzH6UZ9u!~oBFP8Q8_N(TqDxG!5%_qD{1BmS+WcB12!vfUvgwfUvPe zaPvK&o~rw|c=s16rwl$yn8kxGV&c_E{qPu>z70+hW`7a&f54(sfyVBG!>9lC!d&!a z)d#r4{h(vPS-2xlJxz8t8&6xagn5b$W&0}TPsR)$HsrMYKw)NqE1K3UXY1_btP;xD zQtKu?o7V{z{0ASrmyjp~PNMc<@WAi_0000000000000000000000000gz*bd({H#t T0XD<{015yANkvXXu0mjf!?yeD delta 499 zcmVF1DMQNuyVgE~FFa7X@AwtM9Mz+(Q^W_*> zTo8yyQUU+~006k0uZ6x!DJi9#bA1*+w`b3XBg-J2q1D-ZFZ3n4zOuHFrIfykX>!gt z_I^s~=i>U>zVozP*w>$ZP(@T~k(i6B|K51yr)pRgwv{tLpnpotFOt?;L2YWauRcd3 zSG-iSqNh3`GA>iyIRl)Qa|uWNstw_^u(e@W9Dr?xwv8FBcy~4U5N*;6A}|G=)TbU{(*Zbe6(O#r#L1}IsQ(8z zohP%Yqr1<(ivG^W7Pfl~_6v(e9Tfe`(a7@508eJHl}rfh?I(oIO@f=x0qs!Tp2elV zcyq|%qlArk&_PUG8L1B*C(Dg=vDkR(S|!Y5HdXBVu)H(paJM3-=LZTK8l2H|&2%2^ot&S9GB?%CSI_3-1PlH` p3_h2TECf!X)?x5K_mlns7!;!(aeT4JulE1|002ovPDHLkV1kqg{B{5U diff --git a/tests/snapshots/nanox/test_register_wallet_tr_with_nums_keypath_0_1/00000.png b/tests/snapshots/nanox/test_register_wallet_tr_with_nums_keypath_0_1/00000.png index 2cd5813c4bbc7652c57a9bdc7690cf5093a0fc0e..a5f80d7c6d64bc7213cdf1fde41db4d3c111e97f 100644 GIT binary patch delta 993 zcmV<710MYB2loe%B!9k1L_t(|ob6muvLhh~bhq{_pi(7dbBqAh_NEwy9MWYYX8j^b7({N z*4p2x$t}@8e$YhF<)fzZ^gs+AdJeyaV-8vO`iG5y**XZAbAMA$hu3F45vI_i9hCQ> z%9ddfgQv`Jus>cShP?v7%911L?M(DDD=DNw`lh>hPx;|=`KdpzsW$X#?|DKcXs8uZ zV-)%5KOZ`6Om(#r;Kl0@0Aj$uC*zjA-CY4Pb=Wgrh8K>Wjy57wFc*5co3M1~HRWYo z7)#Ur7U&$h41bc^y$hBX9*%cL=zV3Q)G*!yqF_>@otp~Zb<)Sfx%f1}YJ7fi=P?~l zavczR^>V=P;O65)(GGpIg0ah4*=o41eKe&Ld*6T44HoClG-iPe9+o z^4CB&0Xhoct%B}LN;WQAdDGrlOtO|V2cDjgk(Ef@1Gd2AbU}$Q0k^osB&0>uY9-bsF!BR}luR*Oj zw&eZ~uzyAK`Xop$;X=n^Br5?Maowe?;GyDqCo1}PqN0B%boAYK!qEehdCKg1G*dKO z_r31e&{UXl(j4iuQJzXo=4#3#1$>RlW2(}m2}$PGP_F>NORN1T?izAU#g6f5Q#Pofvf`|6Mv?;_CAqyW3y5VuJiyYF34l;*A@g% zbvyxjX6T(v?|&LQ$+#^)*~sj%zY*(nbaa7}G~qIJd=P(m@WAziR=}{JbZ9mDOQI;ItBYIdar-2#$9?1)Zz zlUU9W2ByLg))TOO4_Ls)bz@ec%!(&9AX+w*C#6BnBTkr<<@&vkuLg z&z?oo^dRZ^u>BnIod^}^B*7QOvo_)FNS5*oko{i~Ux{56uTUry3I&A!lt!mLtHCxo P00000NkvXXu0mjfFP`OC delta 982 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 P0000XDBKxwBt$^Ms=z4Rkf%Lt+|J~DUC`AU=^ zq9_^>00000faQE;@8@}n$Z;I$IlcCglvq`|s-+2S+j`FP%-mv)Nfx>?NrUFQ+VFGl zAAg9lURQ}3r?-(gG%))rFUeT>pSa0j!e#;`c|9GjXLlmRSbw`S<*BQ>B#Ypnw%V6I zBU|tzAn>N{Oe(K>e@GZL3TGC!)He1-msG8?GH%dBOHj64Xr;FpxP`ogU_}jNT>Jqj zx$IB`VwQLMQL}4rFGheKz1X;xU~H5WGgOQH@?^p6`>MDJC$8l(?VpW}RrlL=g_)$a zZFYENeX%KKDSt=MGEx}b{2XwX_UUg8>d-cop!Fe!xk~C0@Q_pSajsJ3OyCZPb6rtbQj*$sfAU{d~b?M!=p3h#7MA zU(!qj^fSbF?tI@E1bGB(pCG}`DP{xLpQK+D?N_#?cIQ!XFNyF1icZG+%Wzzc_ZPz$ z?1WWlClx0%22;Vk00000000000000000000000000MqydT4~$bTGa{200000NkvXX Hu0mjf=t1{e diff --git a/tests/snapshots/nanox/test_register_wallet_tr_with_nums_keypath_0_2/00000.png b/tests/snapshots/nanox/test_register_wallet_tr_with_nums_keypath_0_2/00000.png index 3641bc0da371aa5eaabfbd599efcb1f56f0f8d68..18500ea70927c6ccf07f0ab947be57adeb9fbc8d 100644 GIT binary patch delta 1004 zcmV`{*waIe}o;QHz+zvD@GZgLytT<~8J*UFHH*fit%(DnL z&gs4_o@XQCB7a?PadVw8waaI7VR<1bv=;{H`}()loS~k|fzf{XlQKpWI89__(H!iwy;6i+H_6hW8>KnM*gsYks@L zilNi+r08K9UihBUe87b%&_Rs4Yn)Wub$2Q$*Tb`@M1M4aq}e`mY36(fX@|@(bWj4$ z9*U})ULLi|zHAsB;3nv;7GF`PQDl7{F?1AXDMAdlLyzs8Prj0RI6eX*GPAv)guaM% z%vQJ}ewXVqSiB=3POulDVqAov--T6`w@f&3yUqlN%V{?TkL%~g?p9MGKHl`>rB?3S z?A!wCv449(Wrpj4{8-|{*f`MJ!5XmUK=H@0gErhWCr^+$*hxlzCmH>n@aV7nA|~#! z_}+Bbj_emfg^t6pW>MQZi_Yvpe7UqTsv$glNsVG8Z?`L{AV~Ss$M_(o4L9w&lZ+D_ zVs@FY-6C(*9S)<_(5BkfI5m?XXf@GDrfEvrg@0Ym<)+0FfTqe|TP>)tkwRmEXIfLs ziwd?ve6S;#167s12^g-}ZnZu=-7*{W0aUd!0i59EYis5&T-m;FnffGIfWIpqN*Z4@ z#YsaO&V1S(=4>cqRC6`EVhdLl;yov~wVu4BUn{?eB@W)T20X({X8$Bfk{>|5BDS{{ z`hP2Lv~Q=%c7|ixPqw_MU;IgHw|nPD3#+k5M#5U8o*){uMkHaj21KE4g^y9&M2YNz zz$4YHPH~GO9(EQ|mAc#TDel$m-=6qS!kXkAFN7TKhyE zaUf2WvosIEKu`5({YiK#2Yk{5GmSg5L}kx?_!D5n2#jERvD`kq7JLlNtpS|@V{OpN znc}x{zV>!Y88^gxX#6C0L`=N)?CjENyYbtI_w%nr>OO)I+?aqH|5wD1;O-Mfk|arz asQd?+ny!r3nWu{Y0000S<+B!9w5L_t(|ob8-#65JpNhHa-e$^DPyUHT(khX}kNxJlab{7PH{ z2!7(swpJ8HQ4~c{6u0wZsdn$ZwRRlGcpk4Yh7eH{Rd*Y`cdC)wFiNQLqr&vL$2-#eD)w`8-MsHoWu_A&=Rrd0^w$1 zhR6s2-lPp4<)-(!7ltUO8Kz%&1+HQ;#%Tlp%45$UJ_QXO^dZneVv`tGWU8JV8nBjk z7jX(&A`$@2Wd{LN&m-@K}0f+K*29k<7lQ6QCa|RGZZaQY zUuib@D^pwtF>0>oq&l5S8cR`eA)*RTn7bo;>Nz%hc7N`HI;QJf0XSPIiXL*g*E+k| z01ebD;Roz)mwa&BYy544$OC|0L!8C*j`Tc_%FHvH0H9EcfgeodN@g zVNIj9bry|z261p{X;e_z9Hbx_$;)vj)rlwl8N)t^Y28hGo@(Yvb}^jh8?T;G^$ml) z+0Y>xOI(^sJZL%5Or&W@#skjga@ArAKobRcEPof&SWlt8@JCt`%aaONpue+wBIgv< zo(+JxVu!`XlsS>r%E37^eLM z8h;`R7k|>q&6dW|+zPhF9=A5BF&+t8p(kKif+-EF@Wd6cybE%kq*i5$I}`DYvx~0e z+RU%GNn)<4D+%KX6aatwGu{Vm&#j6qMPj>2=pc4{@R;T7ME#ob^c%W_I8`n&%yT+A z+?;JE;iVYxdD9tbzcE|n+`w`GfRCIW99{!!RrSk>bs*OoFzEnmgO#mz-noa26JHX5@BUZBJNfGIq9}@@D7^dz&+W5N TUC*>T00000NkvXXu0mjfPmtvp diff --git a/tests/snapshots/nanox/test_register_wallet_tr_with_nums_keypath_0_2/00001.png b/tests/snapshots/nanox/test_register_wallet_tr_with_nums_keypath_0_2/00001.png index 795449674900bb3acc2e98507c9f69fa56a3cb5d..0254f586a604700fba05a771a38dba93f485f39c 100644 GIT binary patch delta 1009 zcmVwlU)-~f1r60yxS{Sz^5 zIkcbFX2$Rg(7fL#LZ1)DPjsQsdzPM`i`JU6~PkJr1uxG)QHtFuFKU< zJPsP{&StR$;TR5p=C7-R(M-hQa<3Injsu28Wz?$P|JOLd4JZ2h<*M07FWj|!Rv2tn3lg;p!DghX53iOmjd z2$m>%Wcwo9@yJ?!67x0>N!T?5R&A9Ni9{l?4;xoO9DLE{KH*DMzQjaUS@=rKAT>Er zN*aS!JqBZWU@WmkmT`2gg6s(p6(aQ#wyM}0F%obR{C}cnvDge$q&;!5a8AS;$Ak>; zg!x9XNYfS!-VC@XLnGPof-1CfBo0%w%FU$sc|ZU>3rvMXS2&MEY#m`+ zZj3_i|9_b{GkjIchkL)`u^6QH4z>tCwbuI z1VC(BfZIt!X@9$NCv2!RJ{T!%1Ibyl*p?mKnSX;SMAp_2PM(hriW9LMQy*pp$UhBW zKH9;UgeDxMQN`qNdqDxHqWdyu+abPV5zq2M{1VQRgA6L1i%l-NoCrbdWfZp=jB{i9iHX zR0Ixtx`?;99^<92{#qBz6KD{8kn;xr25VJhNc|0?MxGJclp9@SmuH=Pgi z-s%hx5AC#*Ja^vl2BT~u57m%5w=vG_icyTY<)t{rp$=h_8Oeq|jHCaO#PKS+@fAla fi9{li_??H)_?cQ9J&xu)Tr(3#a zWA427xBqCL@gT9e2HXH{*n#8z6661-4IRBta)Auc#*ayK{C_^u2b=)UP$IUwX1pV& zEr<4}<(Uz#0K=Q(g!_Hh`+TZh6ljL)6fuRDbi5;J#s@)@I+87@D;R$yvLn~TxFT0I z@i=I$TgqY!3LzW-&1KsFV;IN9?fz+oWh!8dxji3u45=ir^NL-|HG3S4k0&FSugWqn z;f|x-_xI;<(|9_21FI( zB}f5j!~-abbEUX;6y%gK#B>^evSn(#qg$z=Qr3h==WEYS1o~MDr@z6c#>?eoK&~vn zt)-!KyqugAO2!!1H$UGKTe;0Iy{EN%{yIN?WP$=Aw z{eKf_A;u;CEXXQ~!wlMPa(3qeq!n=?2|2`Bwh+U$8{NBlz@A0&;~02np^R?xu4wdZ;<%qT2e@yNGMu{WFig0)W4~QV3&({ ziA!FxA(-)gnvc6K030L}#R_ZB+w6!nlx4>KRK&*q&t$A+{6yD1u-nY9Jnv$^tqKs2 z?zHnfxAgdcD5uCn6;kI8Mw+-5!kkZ@i_4f)94Faue+zm!&SgVq@Ep?d5vMDKLZMLj aefS5%t5294MdwEV0000HROM_mU4Q7K4D-N9#=Lo-fm( z5fM@8Nr@0b2qA=!?R?>)_kE|7uIno8^5-x`kEu=exQ+Y1)ffZAOqrqq;d{o`CEmaO zNUvj7bF&BKP}8vT-#`X8{%6=q>3wCl5-ij(X2#0_VOki-fF@-IQ&7<^8)Km{mdEP8n!PKJBL>&$ zrJj!BKNdHkX}l?MNk2IHe>+Xu?5 zI`H(C;p#@0F{Y%aTnU?9_ZrZ?h?(aZ`7k)S%NK(?OMk5&u>nE87>9PO{McE}468V5 zf_9(>jHV#)5pDRoF)uNJwt_bbkEv2b7h`DwzeSfA_aeOu{F_8_7Bo1DeG`!Uii#-) z%Ea2dEqViBk5iu{KLzzU?8tn0=oNq%cfEc`j0Kc(L=5T9G{DS1ft|Qa46dQ!-Y05j zy~oO@S%28km@4OaaB!8tzL_t(|ob8%jcElhEh0~tyB>P`d_R@!(au`9p{)A+v_j^iH z6a+;jvu%VBLI@#*r1OP~9>=k5+rIDeEPsw6ow!|Tb!i;OQ4BCJ%$1QIK)z?po%jC! z$M!nrA~rb`4s{Ka{{}K$#{Uc(s=Z&BUI^6W^&~o<&*=jWz<;j7qFZr|eiKaXE~TsJ zUIBqO^?>Dl)BDy7(iLb%(<$y0Zf3l5Lbw(NGN4JqUlA`r7Ar~Bkxy~)T5&@qq4gDhc0GCnUg&9K75VOSo&kxf`Q)4lAU z=gX#vdcPf3t$&r;Y#!|7wfBWpcCU`}UU1@w>9_~ zx^DcR7k_}sQlr!M(!oC`0MDt>X2*bNZpcDJXgHZMxRiHtZ?o(%Fqm4C$#UKd**D=O zj9sI;9GZ4hOA3G3*sU7`v3p{ diff --git a/tests/snapshots/nanox/test_register_wallet_with_long_name_0_0/00001.png b/tests/snapshots/nanox/test_register_wallet_with_long_name_0_0/00001.png index ebf33f0d95ede9658de5ad71e41c592ef734e5c2..eaeea2b42033ea1400e3799ba9aa72054809d9a4 100644 GIT binary patch delta 829 zcmV-D1H$~>2HggbEq`6I+aL^u-A;Fs{V$2V^uco(RYC^=vJt7ihm1o&7JmYco$E@H zBuSDaNs@q+Qc5Yiz1Rk;yKD`bQhv~iOMV+~|8gG$>2=xG&1|2~r~XQ>ajBa>>z>J5 zvXuKPb&>g6Q|Pa(N;QRLZr+;ZltqBU^mba6K|73sW`NfJ)ql|&oT9nTEK~36b+raE zH}A`G$|BTZ%|q57O=r4vTcAG!m9Zcb>6&1_HAMMo zao#edj7&ZcaKxfaXaya!Ei!$V%^jfW^`pgWiqu|S(|=*+6xog#CwXE(v4Fm4%GlyH z*0bxE;WGgHaXZS^qUHlXRzx$XEwgt!;+ThOJdv+ac08F z^?JS30lQ|XUCFr_RW#S@wf}hl<@4`f2V4xg*m(}04!~;>SiZn3q#8p4=jb9i6jIiu zRv&!hyO*_7w7EU!fTR*=4RDYC&CPz2BuVl(5r1|a>ppfn(M{NN#&MIk8TZG-U@h>FeR%DP=LpPHhkR(ZxB%AmPQ%SePmhBj=00000NkvXX Hu0mjfex8&p delta 829 zcmV-D1H$~>2HggbEq`0G+aL^v-A;Fs{V$2V^uco&RYDhpY(%Q>A>$B`#ZAC(=emlb zD2k#eiXtJcwbt5hFSdc|PFn+}v>&+Ql;6hNzuX5&dY!iQFx%(z>A%8jxzx>{bnZ2^4-AQRMlu`mT+Vr(eT!4W}ynRJ_vyq zZA`CZDJluDi<)kx)zIOY zf@+P!U*&@L^-x-%5+)QlY5rj%RaLobsHDpN4D0ydu}dA-ROgZh5hu8+W{0IL7pN5d zv^Z}WQbwH50|Idir7OWO9QR!|cL1l?&lc|~RC{?%hkx-YvWgf-d164JfWBzT*y26b zqwAN!GeGv^b`-5e!v}t-2xpL6X76^C*Y-45MnUI&U3_cfV>t7%a`y9DaVw+IlD+sg_L!v zHHO&u9%b!_Rp;7u4k$W_)`0NnKiupWMNt%wlYe0ovhIWMd@Vx-F%FG0V>Nz|U*?GN zJZu-#z}tQ5o1GW)GAPPsv~v-y6eY?A9f!5R7nveaHBOqM&TgZUx>AH|O7Mi=q}Td* z^&H@HI()1R2ZZpC-$w`g+Xpd6mBPo8S&m6x`p_{1=D2k#eicS0lQ~9j_iF4Nj00000NkvXX Hu0mjfQV)&f diff --git a/tests/snapshots/nanox/test_register_wallet_with_long_name_0_0/00002.png b/tests/snapshots/nanox/test_register_wallet_with_long_name_0_0/00002.png index 1ca829c527b8ab1e36c02e9b37de5ebf9bfe242b..6a0c933130d0cd7d976bf74d14f7a59809ba8450 100644 GIT binary patch delta 453 zcmV;$0XqKe1MUNmB!9I@L_t(|ob8!WlEWYfK;50aN$!6n@3J46W*iX2G*Q#O_thc_ zLPTRy0ssI209cTmbIy6T7t<)`o?mF4L#TE9==}!G56;0NS=Vvgwk_47QOdQBGnc>j zJ=6AtWdB?GCmcN_WviIaArZ<|(?U~saU3qqm00qs^*G)N5Px~oaoO=DdYr1E()Hu_ zF`A=XwJS7rm(pR&Lq8vJ{2;VffaqVXfDy_2GqLC`R@Pi19*V3~lhl>Db^=zY#SUFd zP0;&HM8@y+!7M>#(G-PMXr7Zy#Hr?y@aX~=H=${qg359%gynh5k!Wus<)|F+Dov}G z)zPZGM;E8|ihqM?TI>;g440gS7dcWtl}i$Ei6;O60Jrg-n^ogI;OVTN)StQLtCyfD zaAz6p;`FtK`l2@`>$X)lrP>>5q_sL`Re9E0Ir%+c7=Bz%--BAM;~)Rk6OdXron7~! zPJFE|2Y2(~n{Y2;Um1X00V5xQ;MUhwg{%*j`=z>LZX(Pk+z9Xbhqe#E3^LIlMkUll ve=y`=CRCxBG=fYHZiVmylfeNL7u?1_n@zt0yYH-+00000NkvXXu0mjff4Sas delta 467 zcmV;^0WALR1MLHlB!9F?L_t(|ob8!WlEWYfK;50aN$-Co@3J46&9H!oZKJk*@2f== zgowtJ0ssI20I(so)>`XoFP0(aUjMKR06{33!Sp0001&@tK=d=RM%n**~dYYt6ftpe1o< znd}nuZ4LE7Z%nP*R@+p(H_}Y2JEp6=YOUP)JzyGfT<*RHZMDvS{C7`4>D>zr-Gc`4 zZGAbonm6BsM^XFA1oR4+`3NMpzM(4A`e1onst4xgY)rzP@a}(Tdjpz5Ci>HGLQV81 zLk?C#6XDBhHa-iasNwlFMY_=v4Dt*n&kZ7Lno)f z8wetk5C8xG0002k&X-q5DWwoXj4?lxpVzacVNG(;JeLmF zF-9qUDzC)z#?dg&22hrr_r7uVr997TYe7crL7bRnxDB}71J1JOoYa#j7j7DYZpG4b z2nMLKGY|m)z<-0WB!%0?ooUN&;LXG|{fECAo?!>R1{kPV%#323e6N_Xno=!Al$8_y z%oAiKWwr?Oy%Sj7LMdC;>ZZJqM=C<3+@{ovI9Yhrb)lSG`8QPb#akJL6?uI_8UNY) zwrjJKetJD%{2tKd{*$rdcuL;o8C?ukL%C~v3D=q*WPhFZgYE%kOcdi|SHX5qb=Mt> z_Op);ERcGD(b~;pr!*K57SC|8|EsF3G`FKSA+SQe;53vB8!Y86>Q%1k&3v(zb%=S0eIR4y zz@4ohW`A7_Uo3gU@~Xk_2TO0TUK}vMg=KGwR~Yea^TQtdK<|fNWXM~k7+EVl@}36< zIu(VsLX^^cAi{P73=DL{04G07As@|&56>ECfMaLCFdq>p7BN%Bw6vYE%}1o6GycxA z%;tx{V3wVm5s?i50000000000000000002+LKc1j5P|ZOsL`>r00000NkvXXu0mjf DB>+4Y delta 659 zcmV;E0&M-Y1*-*+B!6;AL_t(|ob8%za>O7AhHa-e@%~5hF8z_IV*wErb(6f$kDcs_ zU!W*#LI3~&0001BJ711%rIbPlF~Xvw$FuY?c_0dnay(t5P!rW#y^5ITSA^{md|b0 zRxbHb^oo}5$RO8ws*^jwC^_bE#9E~ZhX>|s24@3YJG7ik?Zi7Z;Vw$2w}^!BTtsUNK`TrJ9N;(+YuZ{*db_NXd3P-VsnJlKI?u>0-aSff>@BEh8dTyX3FV6=8 zD}Yp#1C1#b=dl#HhjF-ZTRIi+%FYKsRH(3&ikVm}TM&3Cx${#~;yR#3SkIvza2Z^9 zcC>2Yt1Z!GbAJQq6m;OojxP)kBYl*tAJfc*q%|Qj(S+`cv>Klzz{-x1@Z{?#?w}OGXqho84!iY_~oD<_w$eJI!T7h% z)-k9DmY!ohwYvbat!Ftm5v+#0B}DUr@zX)S=@y(aejY1=qyPU?j^>P0pP|!!@-5^oBf}+__M>k zcV|=@7`%&j=TpE^1?ctAqzv&zn5!+2qp6JNdC-Ws$~#`i(cZAb#W1_G)a|=I4bk%< zZ0IwAaI}BvMl8k3?2jL7W;O3p)o3&tjZecj>D0^4kcBN400000NkvXXu0mjfAMW>B delta 1019 zcmVEFkB8<8T+vk0b@-lA zMuDLCgWataMNt$*Q5417`EuU9Ua!{LaUA`*|IE>apeXr@S0OFjRTCScox_shC#dGg zpDAnBy?^|t38%|f4f;t5ao##~;R&0qpHg@;KFw)$@|U;68Go><0y9j`=Wu|a87Lp4 z69=P;W@$4Sd_zCxMuQ}d0LPp1dwO~3{d5@hhH5w~flNGMA%=*umWiPrpt6-^!wD4u z4ZQ3Nby%6i7`m9nrJvL3b!yeoOjuYg*FaT>J<>sa%+UzsNt zVYwwbtxm#DL4PM_WcBrvG$LGYd4aO#y0jB#Z{wJat*mXRZ-aLZn1vtyov`xNYlhFd z4R8I5^d|kuEPm1Z9P*LgFN&i0Y~pNab5nh?#L3AxC827+8Xjn!&+yz?~LuG_f3yW8pd0 z61xjB+j^A&xnS{gsOl$^6Ag2mzUnl%hjCJ;X&cOgm{jK62UyRl<|6#zs~Hia><^EJ zOm20kx(TNZB`eGhz;7P<+GZTtU~4 zUhZ|m#Sgi^1CZMt-Gt+uHUEU13@o150T%qEymA%e%td}r}y`BC2{GBFpXU}cFqmkrOc zjH$yjon!ehUAq4yC_REn5>*YG;9E-$DK;$hLu#tN)6f~_vk|cQAf{4=q!Ei6bHY~| zZu|ql{mD4|s^QJzF4Bqn^8rUmC~$9LJap&)sf<+YT-d(E|9PuFJKTGB)>0kAH?i(~ z5-ddku7|^vA-@Pqv5DkpSjV#5DP&BQ4d0ieynWXfzs)Mx)VaG#VY)M^8*Ptt>6+g ze&eca@&5IV!R+CWhKiFA5!~r2 z3K+`Efw&Zl>sSh0!+@(KMf$GTCmggq6o>#E#nG#ZU35$yq*yc9>t^s?u1GQ5T4 zXx=gCU}`wjCd6rqsiytcm4QW6n|4Rd~7gd++q&YzYFIakY9@1 zZ%kaoZkU`}aF_9PnyRE{U~1)=CJuf)mQ%JQ0l?3fV!6OIFeepM>oef19G}`WO*EP- z_$v99Dj=gRb8A^`O=}diu8lLZ-!SoWen4a5B1*Ms!{OPMZV(i2#$(jaJ{Y5fv z&rQ9i3x6Ior9&tU?VCiIY19N1@%j?VYfmW9ogc$0G)E%x>oF zyGY6@3hVs@S4@TK8%FJ#nsShV*x7OyO2)%M;eRd_Vcy7ave46}mK0_76eKCN6#>8N zk#1)HCFmsb(kgE8et3UPfk;Nr_D6J1)s8!-m?q-{0{a6><22IM`Tn8V5d?b~s?`7t zt7f%+rn=_4opq$%@st_wI0Qxk&<;Xec4+qpqxH<$tYJe11S=_jnejNgGk-Q7BZkkukZGit`#gR0*Po3>qw$}>qs(HKEo}+fUq2BKOizAD=a>_u zzh)zsoDw9{$0~&Xi3i3*rr4xdv0%tb00L2nb3i{V9Ybrrt{t(>vPdg(rSq^Nv>k2$ z%ukeR+VG3wYvFr3@e$QvUsfTCnVmh|=yeV+W+Y8^1;!14o{9d(bJLKTuRjK$AEuX} z&-3Z?pCfW?Amb1mVxFJGb>_QOHvrmYd@Z7G=5hooC)Q%Uuxc9Ili>9 delta 1013 zcmVWWm$a{?(hd%-nm z{!Ur5?)~eV!TQ7h8fu(`lHlI}QeLoG7-?E~mz%va<%uucj(;Fvg@7l|W8{90qr)^q z>(_y)BT=}I+YC-V@2^@w5cv!Uyvh4R<*E0}(}*gHaP}62U_O~4?CF^@lIAG4)-z*( zGhiq$2O48m7BK|eyqdeyxlUdJCwD#oVv>rMQZdcqoCU#0`n{Gzo3LI+JyIEO9gl@^ zYBOwVi`J1>Xn&DFm!O+_TG9RqT9EFyxI!+uuI9};d^X7`NarubX)?XMIJQG z8*WF=fPeI;7dS{yb1yN8?ET%Weae_x7m`+1rsTWo{yN;wE_$H{0LSR> zyOOT2Zx&nsbsQOk2ISN#)F32I?lCxucJI!2!lI3-_q|>oG0xjvjH^s#lVZbyDk}pJs6w0r`eEr9TJv@7h;2@bbVjZS4{Lb_F@S!UUV=W)r_Xd=2Cuy2`Cbq%}M?NObN(yprR=I00000NkvXXu0mjfwj1!P diff --git a/tests/snapshots/nanox/test_register_wallet_with_long_name_0_1/00002.png b/tests/snapshots/nanox/test_register_wallet_with_long_name_0_1/00002.png index d283f94fd46f0eba7bd3ab5c99f3fcdc3de5cdc7..76ea889910f94559f6cccba804ce377b46a84f65 100644 GIT binary patch delta 762 zcmVVRE_twuV&}I3F`DY{$weF* z1_m6r6ha6ggb+e*=gYfs97ido*4nPy&uN++ZLPnBx6+Hes-}KW41%`PjGJ|uh2e&q zx&C?@VZ^f^w-p%KfoWeC#&u$mKZuAD&Q?*uoNIcHoYzCMqkr#`ZqY0$pNqI%_p;{} zpH?-;H)36neyz3dOe;r5e>#q}2V3i++*9cFOBna;^d)H*be%v(NgW{Mt_P*XT_gop zC`KIVk#?%~N9=e_5`x4E?aPsBCR?L+1NU?z#@%T(bg(A`&5lkcW`(0b&n{Q3^dXvJfY@CoQq$01&e$<{CHi zktKAJ4iQKNiu>m8t_pYQZwe}X(jafTHK&r_P3y*K%lwF0H1aXcwVy0j&l zu9Y-RRo`k>a&{g|4j39NaB!dOgB{2aWKLl-wt7j&AkN0I2#olqO~hJNpXBr$*LIp_ zM4lECAAd$%(Jy8C$h!kigRAWcq8E9T1ImyO9-?@Wr#T?t-}>Mc{O2h2e3C(?54NI* z_p)!oabxD$D>(9|IoFA#MbK!f-|NDoNf#56Ry1?2NEX&CIj_N0eorvCI293ae1bnX z^f!x9N$K^A@rFA-EQvP?J43Kws$Vp&}X4A0)=9cUbcYF`n zflezSyX)vUzHj60NjJ~+O&AFm@d^O1_px^c^k+e_z|C)mUc%BlQ+jQgKlT4U-#x(z sA%qY@2qAKezvBf&c&j07*qoM6N<$g6eT_sQ>@~ delta 760 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 TUC*>T00000NkvXXu0mjfPmtvp diff --git a/tests/snapshots/nanox/test_register_wallet_with_long_name_0_2/00001.png b/tests/snapshots/nanox/test_register_wallet_with_long_name_0_2/00001.png index 795449674900bb3acc2e98507c9f69fa56a3cb5d..0254f586a604700fba05a771a38dba93f485f39c 100644 GIT binary patch delta 1009 zcmVwlU)-~f1r60yxS{Sz^5 zIkcbFX2$Rg(7fL#LZ1)DPjsQsdzPM`i`JU6~PkJr1uxG)QHtFuFKU< zJPsP{&StR$;TR5p=C7-R(M-hQa<3Injsu28Wz?$P|JOLd4JZ2h<*M07FWj|!Rv2tn3lg;p!DghX53iOmjd z2$m>%Wcwo9@yJ?!67x0>N!T?5R&A9Ni9{l?4;xoO9DLE{KH*DMzQjaUS@=rKAT>Er zN*aS!JqBZWU@WmkmT`2gg6s(p6(aQ#wyM}0F%obR{C}cnvDge$q&;!5a8AS;$Ak>; zg!x9XNYfS!-VC@XLnGPof-1CfBo0%w%FU$sc|ZU>3rvMXS2&MEY#m`+ zZj3_i|9_b{GkjIchkL)`u^6QH4z>tCwbuI z1VC(BfZIt!X@9$NCv2!RJ{T!%1Ibyl*p?mKnSX;SMAp_2PM(hriW9LMQy*pp$UhBW zKH9;UgeDxMQN`qNdqDxHqWdyu+abPV5zq2M{1VQRgA6L1i%l-NoCrbdWfZp=jB{i9iHX zR0Ixtx`?;99^<92{#qBz6KD{8kn;xr25VJhNc|0?MxGJclp9@SmuH=Pgi z-s%hx5AC#*Ja^vl2BT~u57m%5w=vG_icyTY<)t{rp$=h_8Oeq|jHCaO#PKS+@fAla fi9{li_??H)_?cQ9J&xu)Tr(3#a zWA427xBqCL@gT9e2HXH{*n#8z6661-4IRBta)Auc#*ayK{C_^u2b=)UP$IUwX1pV& zEr<4}<(Uz#0K=Q(g!_Hh`+TZh6ljL)6fuRDbi5;J#s@)@I+87@D;R$yvLn~TxFT0I z@i=I$TgqY!3LzW-&1KsFV;IN9?fz+oWh!8dxji3u45=ir^NL-|HG3S4k0&FSugWqn z;f|x-_xI;<(|9_21FI( zB}f5j!~-abbEUX;6y%gK#B>^evSn(#qg$z=Qr3h==WEYS1o~MDr@z6c#>?eoK&~vn zt)-!KyqugAO2!!1H$UGKTe;0Iy{EN%{yIN?WP$=Aw z{eKf_A;u;CEXXQ~!wlMPa(3qeq!n=?2|2`Bwh+U$8{NBlz@A0&;~02np^R?xu4wdZ;<%qT2e@yNGMu{WFig0)W4~QV3&({ ziA!FxA(-)gnvc6K030L}#R_ZB+w6!nlx4>KRK&*q&t$A+{6yD1u-nY9Jnv$^tqKs2 z?zHnfxAgdcD5uCn6;kI8Mw+-5!kkZ@i_4f)94Faue+zm!&SgVq@Ep?d5vMDKLZMLj aefS5%t5294MdwEV0000HROM_mU4Q7K4D-N9#=Lo-fm( z5fM@8Nr@0b2qA=!?R?>)_kE|7uIno8^5-x`kEu=exQ+Y1)ffZAOqrqq;d{o`CEmaO zNUvj7bF&BKP}8vT-#`X8{%6=q>3wCl5-ij(X2#0_VOki-fF@-IQ&7<^8)Km{mdEP8n!PKJBL>&$ zrJj!BKNdHkX}l?MNk2IHe>+Xu?5 zI`H(C;p#@0F{Y%aTnU?9_ZrZ?h?(aZ`7k)S%NK(?OMk5&u>nE87>9PO{McE}468V5 zf_9(>jHV#)5pDRoF)uNJwt_bbkEv2b7h`DwzeSfA_aeOu{F_8_7Bo1DeG`!Uii#-) z%Ea2dEqViBk5iu{KLzzU?8tn0=oNq%cfEc`j0Kc(L=5T9G{DS1ft|Qa46dQ!-Y05j zy~oO@S%28km@4OaaB!8tzL_t(|ob8%jcElhEh0~tyB>P`d_R@!(au`9p{)A+v_j^iH z6a+;jvu%VBLI@#*r1OP~9>=k5+rIDeEPsw6ow!|Tb!i;OQ4BCJ%$1QIK)z?po%jC! z$M!nrA~rb`4s{Ka{{}K$#{Uc(s=Z&BUI^6W^&~o<&*=jWz<;j7qFZr|eiKaXE~TsJ zUIBqO^?>Dl)BDy7(iLb%(<$y0Zf3l5Lbw(NGN4JqUlA`r7Ar~Bkxy~)T5&@qq4gDhc0GCnUg&9K75VOSo&kxf`Q)4lAU z=gX#vdcPf3t$&r;Y#!|7wfBWpcCU`}UU1@w>9_~ zx^DcR7k_}sQlr!M(!oC`0MDt>X2*bNZpcDJXgHZMxRiHtZ?o(%Fqm4C$#UKd**D=O zj9sI;9GZ4hOA3G3*sU7`v3p{ diff --git a/tests/snapshots/nanox/test_sighash_all_anyone_input_changed_0_0/00000.png b/tests/snapshots/nanox/test_sighash_all_anyone_input_changed_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_all_anyone_input_changed_0_1/00000.png b/tests/snapshots/nanox/test_sighash_all_anyone_input_changed_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_all_anyone_output_changed_0_0/00000.png b/tests/snapshots/nanox/test_sighash_all_anyone_output_changed_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_all_anyone_output_changed_0_1/00000.png b/tests/snapshots/nanox/test_sighash_all_anyone_output_changed_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_all_anyone_sign_0_0/00000.png b/tests/snapshots/nanox/test_sighash_all_anyone_sign_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_all_anyone_sign_0_1/00000.png b/tests/snapshots/nanox/test_sighash_all_anyone_sign_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_all_input_modified_0_0/00000.png b/tests/snapshots/nanox/test_sighash_all_input_modified_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_all_output_modified_0_0/00000.png b/tests/snapshots/nanox/test_sighash_all_output_modified_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_all_sign_psbt_0_0/00000.png b/tests/snapshots/nanox/test_sighash_all_sign_psbt_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_none_anyone_input_changed_0_0/00000.png b/tests/snapshots/nanox/test_sighash_none_anyone_input_changed_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_none_anyone_input_changed_0_1/00000.png b/tests/snapshots/nanox/test_sighash_none_anyone_input_changed_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_none_anyone_output_changed_0_0/00000.png b/tests/snapshots/nanox/test_sighash_none_anyone_output_changed_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_none_anyone_output_changed_0_1/00000.png b/tests/snapshots/nanox/test_sighash_none_anyone_output_changed_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_none_anyone_sign_0_0/00000.png b/tests/snapshots/nanox/test_sighash_none_anyone_sign_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_none_anyone_sign_0_1/00000.png b/tests/snapshots/nanox/test_sighash_none_anyone_sign_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_none_input_modified_0_0/00000.png b/tests/snapshots/nanox/test_sighash_none_input_modified_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_none_input_modified_0_1/00000.png b/tests/snapshots/nanox/test_sighash_none_input_modified_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_none_output_modified_0_0/00000.png b/tests/snapshots/nanox/test_sighash_none_output_modified_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_none_output_modified_0_1/00000.png b/tests/snapshots/nanox/test_sighash_none_output_modified_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_none_sign_psbt_0_0/00000.png b/tests/snapshots/nanox/test_sighash_none_sign_psbt_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_none_sign_psbt_0_1/00000.png b/tests/snapshots/nanox/test_sighash_none_sign_psbt_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_segwitv0_sighash1_0_0/00000.png b/tests/snapshots/nanox/test_sighash_segwitv0_sighash1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_segwitv0_sighash2_0_0/00000.png b/tests/snapshots/nanox/test_sighash_segwitv0_sighash2_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_segwitv0_sighash2_0_1/00000.png b/tests/snapshots/nanox/test_sighash_segwitv0_sighash2_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_segwitv0_sighash3_0_0/00000.png b/tests/snapshots/nanox/test_sighash_segwitv0_sighash3_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_segwitv0_sighash3_0_1/00000.png b/tests/snapshots/nanox/test_sighash_segwitv0_sighash3_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_segwitv0_sighash81_0_0/00000.png b/tests/snapshots/nanox/test_sighash_segwitv0_sighash81_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_segwitv0_sighash81_0_1/00000.png b/tests/snapshots/nanox/test_sighash_segwitv0_sighash81_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_segwitv0_sighash82_0_0/00000.png b/tests/snapshots/nanox/test_sighash_segwitv0_sighash82_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_segwitv0_sighash82_0_1/00000.png b/tests/snapshots/nanox/test_sighash_segwitv0_sighash82_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_segwitv0_sighash83_0_0/00000.png b/tests/snapshots/nanox/test_sighash_segwitv0_sighash83_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_segwitv0_sighash83_0_1/00000.png b/tests/snapshots/nanox/test_sighash_segwitv0_sighash83_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_single_anyone_input_changed_0_0/00000.png b/tests/snapshots/nanox/test_sighash_single_anyone_input_changed_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_single_anyone_input_changed_0_1/00000.png b/tests/snapshots/nanox/test_sighash_single_anyone_input_changed_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_single_anyone_output_changed_0_0/00000.png b/tests/snapshots/nanox/test_sighash_single_anyone_output_changed_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_single_anyone_output_changed_0_1/00000.png b/tests/snapshots/nanox/test_sighash_single_anyone_output_changed_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_single_anyone_sign_0_0/00000.png b/tests/snapshots/nanox/test_sighash_single_anyone_sign_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_single_anyone_sign_0_1/00000.png b/tests/snapshots/nanox/test_sighash_single_anyone_sign_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_single_input_modified_0_0/00000.png b/tests/snapshots/nanox/test_sighash_single_input_modified_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_single_input_modified_0_1/00000.png b/tests/snapshots/nanox/test_sighash_single_input_modified_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_single_output_different_index_modified_0_0/00000.png b/tests/snapshots/nanox/test_sighash_single_output_different_index_modified_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_single_output_different_index_modified_0_1/00000.png b/tests/snapshots/nanox/test_sighash_single_output_different_index_modified_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_single_output_same_index_modified_0_0/00000.png b/tests/snapshots/nanox/test_sighash_single_output_same_index_modified_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_single_output_same_index_modified_0_1/00000.png b/tests/snapshots/nanox/test_sighash_single_output_same_index_modified_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_single_sign_psbt_0_0/00000.png b/tests/snapshots/nanox/test_sighash_single_sign_psbt_0_0/00000.png index 43b3c1533a2373ecc20ec829517720492d3eca16..4d8139d8df960738fc53187ed84d609fbea5b6b9 100644 GIT binary patch delta 430 zcmV;f0a5)iVl^bp@zF&s&461$c~<1!&Iqq>CVB z0iNV1I)UB#GhIY(%j6QdSAdA58*wFB0frm>ho1yCy<`PY(tlk=h)Ax4pNSg8qXv-} z{YZ>{Bu4+^w7-P6Lam=U>yMXw^2~%%yUBTn;f}~>q zRjrasx>LbBoq9pMtY(5MgEK%~9@)DjFH3Jz?u5F{a5p|I;sa^SC^dS9AP)b3{X zp|@Fgt~}M@Ka;0-PO7l|23}S(!Qrw8-VJLs{tWnX`6vEQ_^l>SH~;_u000000089i Y517?7B@UBNNB{r;07*qoM6N<$g3x8kF#rGn delta 430 zcmV;f0a55NlS|}Y0V0xa#FbMo66?;BT?7Q@!0HqY0 zpPiv=v;NE-USZY|>fuvuRD-J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sighash_single_sign_psbt_0_1/00000.png b/tests/snapshots/nanox/test_sighash_single_sign_psbt_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_unsupported_0_0/00000.png b/tests/snapshots/nanox/test_sighash_unsupported_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sighash_unsupported_for_segwitv0_0_0/00000.png b/tests/snapshots/nanox/test_sighash_unsupported_for_segwitv0_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_message_0_1/00000.png b/tests/snapshots/nanox/test_sign_message_0_1/00000.png index 04bb6f43c46cbcb9c9891a601782329fd9257adf..7cf2be4c4aa5e21c47c850c802226503be368faf 100644 GIT binary patch delta 677 zcmV;W0$TmL1-%83B!7fSL_t(|ob8)icElhEhHX!G;{KQ9Uiy&J)PsnC@s|0&r`Ay< z7*H7|1ONa40001{^JN{7Qo8<#G1gjup6}HP>_tlHexK$H^m{-EA;w7lW&5~WNMo~e zP03Jk++2V1EV7=Ofl8kDfJ>VgBl`eExx6L*5emEKedH;~r+=hB>3o@zokgCgIZ)4! zsdtlH#oDL2iZ#=8PSI@9m`R@KDVz%+`(P;CFz<6cKWWKF)r?rm^eJy;=tNy1sA+fd zkr01mNTiZ`I$D&XM&R6pSr2${6P6p<;iZzS93nwbUe>cY@C}f&o%^V_Gq?vV#vFns z({scI001DfV1Ey&9XCz!{ShG_4V%E}6mlXD=Yo1*FEXav&FulTlx_32^+66KctDvW zs=etoAxdd;(rq#uc>v2G)3{TlkF)y%3^EFvSY5IPNJad^=G8|-Jz%So9J_yx5Ib!X zZkYE4r@H;A8X4A~24iYie==Bul^_bOq+w*N!BEzlmw)}5S19J`Nz$>xeJw9RFe{tA zVSDOl5$4?|L9}}+;zm>0aw6*&fUSBfkt>3>y1<)QzW^i=Rx_nCAe6%$Ycq2LSib;z zOf|e04(qe7HjX!ELyw3{Q$0Xah$)z?`AV|!CzoF;@DU}RJ-qWgegv<*4FLcE03K4t z-7<8#34gPc)A>61lr-D}lu4TxGve887cn_YWBQREJ63ZE5~h=HVS*Y;;i*!4S_&ER znzAk?=kD1UQVT5B9K9T%nmv`@Nmv`LfoMo7!X2_tzj-;{{ZY9fN9Hn|zro~TN{KBS zdionW0c(M&!2>SQ%4DHN2~wk}sRY$mi~8zHksb;K0000003X3GRPoW>JzW@r00000 LNkvXXu0mjf3;;HV delta 674 zcmV;T0$u&R1-b>0B!7WPL_t(|ob8%ja>XDBg>9!hasNwlFMY@~br29pG{$?rr`9ME z4E~&JN&o-=0000?=gZrmlydx$bCybgo$sd|Sc_81`8~~P7|(!|QqGzD%hm~(kiu?d z$;l)nZtXvL7u`=wLnHTRz~N2KnSBA`TwRj?NKM@9I(ir6DSxR?Dj%U_d(k`UHnj8O zs@atD23)?7u^y|nDmbBA~*ng4yGmz>pI8#lajiX6vWnM%y}mJR zDf5pGnW^-effA#s5d;@uHUn;4g!MwUdFv!=hgeXY*Zu4^+ySz;3vcyS2Iqi>aZf>$ zxw6Fu005x#z<(MbZ8u%>`z=O38dku$XylFDtOZ?xJ;=CDH)jS&l5O|2^+5@wWI(GC zNng5T#At1f+@`Zo2CxhYO;{qmoz(|mP*7N5^^q}v6!8zMtB;0ez*0LocKsY-cG@D` z3GW8Gy7du*jOb5;2{ocW8H~Y`U>16kPLMGMLs=rc?0+x4MzO)(g=9HavJZ;x_kHF|x5>edYWAYm!=PDDebi13vC_LEoO+aIL`1(eJ5{spF;02=@R0DzC+7iJ63Mz=_xwg3PC07*qo IM6N<$g8uqEWB>pF diff --git a/tests/snapshots/nanox/test_sign_message_0_1/00001.png b/tests/snapshots/nanox/test_sign_message_0_1/00001.png index 098d70fca69784d7f95018ff1a808513fb6032da..f94a8eb635bdd317ad9c142e65aecafb453ecfc1 100644 GIT binary patch delta 516 zcmV+f0{i{I1i%E4Eq_sR#2^SjZKpT!{zuAP`jKhI0YNlwG@bXpb_pP2G)j^Z00000 zz~g-N8XU)Q{>V975{UD?I)J@6j^nzYo-rJs0V$=Nv-n%p8I}lPQ`rhK856gRU-ZR~ zGh!HI{tP&y$vIa$Ac89;`H!UXUh4Qwh^s{4AHt;hG?bc zW)n?GBu#!pvltuze-0)!4NIM~|3Xq)SxMAB$Aa(WqYd3!f|_|3mz?#-N32x7=71#V z>Jtn;gsU@P;zQUMR?T&gRX@Um6TBa1(~}1Q9)E8*G4eHeSi1`x9)Mwe%Vc66yj@W9 zNMdP5B#wgcA8FV3a}|HeDv(tlEq@372Q$!zI00#)rCimw6f7NI==+I;F&2Q;R#&bB z)2gAO#JF&=de>=r&H(5MzV^h_Ro`CA%u+F?lDPBcpjQ1f z?|%a;fZ%(iptq_kPl5aQ0n8+m{l}=Jn(RLeW3Uodp_Md}%ou!>7o_)2h%e}#f_K7; znfztk6e5Mv=4UBZ%@rE-7C5!g_plo~&Hzn3kNT|NIQ_5YHP3+HcZ~Wi%H}1)*9<@$ zo$;N=V8HzlQIF9Rndd6^k2Beg7&f;%VXILVHuCf+nQYLO0zvzn{ zXT&hb{26dYlXGr%Km=Dx@*kJtn;gqt&9;zQULHqGlGn|_1`BX~Pb*OLbU9)E2(G4eHeSi1`x9)Mwe&17O8tX+_M zB+)b@5<@}wkF;z1xr#q!6-cX(mcN7kgBj>UoPcVfrrgxm6f_-MX#0tTF&2Q=r&H&UCeC>&;tG>OKnWczkT^elU47l!MQSY?92+i77NaD`jL2deR z?|%a=0ByyO2We|MuDE|6Kut2)e~d<|$^OGI1}k9|T8Wcn#^9s8AiZ}&d_ngrcqhD= z$zR4zAyO!HKTFYSuHevH;H-tVhuzq52Gqp!SfBOXLc&^J^9%@n$5_8b*}O#fngNJY zXME=|*l`IOD{w|!ZN3}<00000000000384T0002MM1BE1`8*BekA z9AI$3p$!2500000fa&}zHMp+pzKAhuDZtOqY5{w3UDxw_nqyc$140NfM)pP)RHT(i>ZCAb2+ZpTw7E|nk zCeyOS1^@ssiht|Plekt@DbDTmzKC&{$(435YUTiRjs*o}Kca0?v|W#3dw8E&MT#G4vgO_!o)@&<`Y)&QxmB+_r2YAdRDw{;x=00000SVP6S&>2V= zwBr2Qv6Q}hu?frkJ{vK*a}lGYEW>lnZiRQ7vqwK^6-JGs)by6vD7sTCJ=HRa>L{j| z!E^Z1a2o!=q+NB3>>}0&Xe?p#-?g73T@YBw?fqA)00000n)wA8fi{G1 SJ{)rZ0000hq2t8_ z4j>4Th5!Hn0002MbiQgGQcBlFj8RJge!f==*o&0X=Xsjr*ggV62r)+XQ?zMLVTna! zO=M68F4fQKV(aucI_WwpSO^JVmtlg=NT?D(!?0=c@)s$i>c0ol)KR;F0 zMW{sWE|sV?&BG#!DV}Ds3+hE<2iRjUWW$i!T=i!u)Jto`JkK`qwG1uj(G*l{cXrE| ze{9%HWm`6+II|i-<4af^0Uck$cB1H>ixl%=IT+$?okhntz}9xnOTC@JK43A`Q_y6d zEU^Iq0E{Bt`F|v?RaJ{~JH0Pr9ABXta@j(@<|fyW^bKCNg<6ZXFwC4x3dYT6!gSZAh}U+&oT;Gd zSh2{X4u7CiC!0oRlAjVhh#4cm**Yxr_#_hP_sz9cmAl)z4gdfE0069^VO{79Bn(<{ zzU^2_-@Vv`WqzNH7~Q#uQBr2`xn{S*z0Sp>pR@?0L{VyfORN;#snwopnM89GQ#9}# zzBDEce_+xs`ibl+)(7Lp4RbLzwZlgk%K8o%G*WVnFC@=Hn0ao^tnYvZ{Nd02O7AhHa-e@%~53UHXt|#zjCtG1=|^J#H(Lq-000000NeTUHaL#syr{KGCBV-2-2ps{<2bI*)1HR$8Bj{8wUU3?I^hyh zIIJuMS%it(#!vd9$7yM3Wc>^{qp7vB9U#HACH0Te<-M(=yMG{eNqtiJOeO0@cQkBh z=f_ohNE@Pbw+&HB&7_NAi6u?Cqg4b4K%ax9n}%(jv;U-|Z6zhKw;2oGORA%(C1{v; za!Xl%bjV7j*9?>xO=S?=gxMLea1+)G+2(zatQ}%O30{wL*zgk|&vxNQy(fcnz|FXq zpv}xYVgmpGcz-7X4>^0Di}C_rt@`3 zrleDqer9Al!dkExTnsrG>DR1I88E1ul`IdV8piBxqQ}p&SPktlN{_mQRgRXgUGoNW z2cVzSlXfN@EngGn4epR4SiSnK9W8{;0Q*GNHAqs@Yk!aygG0+MC6YWf6nVgmqi8qS zTGrD0b|0UGZ0oz|=s#z_?Cn0|>z`-8Y|jA3;7+g#-N_)y7=u(EmtI#udC^-eAFpJG zM14QX@{NjuMcr~SmLg6c?ZHPm^(b;_f0s10NSl|<{vf7bE3zedQ_rg|NOssR1PKV1 z?e$RCjDNLa@AiK!_WLj-lo_ClqY~+AXp59MNyOjDykbbK8EbAGfFi6#hw!rT=D-$? zf!)p{Ud&peVzwEKW%Cv>)j9*NO|RctT?~6@v_BM312&2M@NAe&5dZ)H0078ES2E_U zWwXR%*6)NrjJ!?_4q}p=ssDiOIwiIB6)9BlsDF5oOzGkhtI=BCYGsdpxl*X4{CQPI z$*fUKHM&p~O}l0(#WrbH!6(MuvPQeUEm^B*#;mz|>KlOUS3D;hE>tvU-fDFH5lv-PV#&_8ZGvt!+7^Pyhe`008g?`~qxnuEg@7wSNEr O00{s|MNUMnLSTa5ba{FJ delta 787 zcmV+u1MK{#2C4>-B!BTqL_t(|ob8)ga>O7EL`f<);r>VRUGm|IixH@i#A45+-$%;9 zAPL!Q9VaD12qAHx$7yM3Wc~;^qscipJ0OB9OY$G7%6nM{yMGXOMSW5EOl8vxcGPWX z=f_pMOBteew+vBB&7g~Ji6u?g(JX=w0FS{`4a2g|*?&<|w$hSV+l&S8WvQc~DX5!w zaSO~p7%@}fnt>9dsTBkl;pPaKxCrCIX7f78rX67c1drqFHv9y{-Y&e=donx++>Cn) z+RVrnn-D_CJAV<_H z(oR+Q%-HNm(}Km|WW>n`UpIBifI)0lv)qlU8?(0wj=#xdHMGVkJz@*998I6Q#tp80 z0QI0Av@_^v`kXLsaEBDp)T>e%jmphOd8~{j@y;dVKNCR?WNhPmBFJ3=J>>usEu*Tn#PJ5~qpyI~i9Dg*9W%tq&k6bJ3xEY`i(J ziO;}p=Mf)fO_58>492p#O|>ntj(}^?tCv<6-5wh4yYd@|d1N#Uric(i2qA>51uGfj z)>bpcwSXu32ia4Vne`#JF4LXxCp$<|>*oYp$O99>D5PJO>+2R5VAvYIQYv zgc>@Lxr*ineH4uVv0m9lzUF$BZ0|l^))oQQ8_QR%Wi?8ngb+dqA>O7EMM)|*;r>VBE?KyeqGU-3G0E=#R^1qc z5N7(eQvv`00001BJ72v8N-5WmoU@by?0lbgAQq*R|NCiALH`IyDdn8WUp9|Bg(NmJ zOHL+X;MV?=w&;FZ3L2S_j30kdv!I=yuG~#(7p1GUi&AI?t7xWJ!lYL;3ug!DV=&!@ zVV&n{KS`-eNkP2Z^f}+l(u#(rpl003C1w86Av2Yp(~)8{wF2iN%#MJGi?E)^7QZ{m z+94Jc=XF1u1>XSK+qt)Tk-<6OFx^woW=6Ky0002qhO!Y_x<^`MeA9m}$S4~`V}plF zc0tXv44bGQWOO5g6|q%Ybl;}i2OvkMd!n9`&8*vGYf+4_>Z!fnX4PFxRzo*qX|~k& z(#^iY2Zd*MK$om`pRbGp-xMDtK39rhRrLMPMcDqZg4{=S!QNFa<|0heNdtW%Xd}E4 z?ugeT1{u-c1`}#Te=~pRgOgwuI!PnQ=!2zvR(L12c3t2;_aIhtP^_J%hBnVE?2BBI zNbqk~ktgf)uCp8YZ8^S0mqI0dvHtB-79A3%!wsKUJ1&K$AY$Bem!@&gLv%otM;ZN$ zdmf?#9Ngawd?<4|Kv`EEWqsM$rMUU5ktDKesN|K=^Vg!R{9u0v`V(NVkWvaF4gdhr zIVf_m^-BIs5fviR)t;q|myFvhUF6={FJyE*lGR6(AdyPe5_bf1%d2{mxyRr z9~C3^Y)v1G76v)21vOq&I>)xf;N%mr>+|cd>z@5P@)6EIlJxb#RVwTNvU73@l9pLA zGI~QiOQe+6gQqEX`82}LU0s}?g23~D8VUda;0^o&t5F#&0k%)Z00000NkvXXu0mjf Dc+Wnf delta 668 zcmV;N0%QHr1<(bMBxsjOL_t(|ob8)Qa>O7EMM)|*;r>VBE?KyeqGU~o(eD3N-57)r zX8N{M0ssI2003Y)U#$g7Dc6sjvy=k-eD8MPEJ`W=_tTn!@ezW=ze+%IvJ6TAAgZq(9cg(Zj;(Y>1yqw6q?Q|%oI;QcXrrR*A z^IYvGDRn6+hxpdfyOXRP zVnK0U_tPx+2FTtnywy7yoC7w~JOwSLXNwI00N`yX8=qvH!)ZZU5uyMQr}BA z`wSlxp4|aWvf6#VateGye31BDDS}ne*FzU!|HBG$AJqjF>5&+zvz@jGlXTL+m8%<+v!rMq%YRLW6EMc!VI_(6KngW&~%6x_uQqa-}56n;FL!h z?eu$oL5fx6PsXbF0FB$h&I?27cU&!csB&&}m$IBzhQbWV?>fJZVy=TxQBKp-w z#fU$f>4VckC!4h(<3*)?EL#kAJ`uYpDW&z`=_y@4jAQ4nCiYK3;CVm|1pol>27Upp#~Ccs%0z?3VUIEccmJ|4%DrP z^Ur17rA)E)ZJA=LYX(DfOOS4|1I;2h0QMYA)if+^?)Hn4vR11TYoD>?y(|qhv;=kg zU3_J%KQ>~evMmE8psN)GH(_-KOx%R+LbZCGr0Pd_Fp{_P>{fgO;%pZ_>OC3W0}kU} zf;Ka9#3qCg@&*P1haaR$lPCcnf4U(IZ)J7E;4TzORNV@^6I7q8P}N8ASuIozy4CGk zt%nXb@Ft0;jd0*1Hn>XG)w|xFyeLnWqY(zDr>cn>i$>SrEH9BFR7u=ra0)pCkSE31 zSG&}8U1r@ay#^O4T_XfGqz+*jKl2%R8O=^+?{7otYWDtSI0h%-Ds+-ge1@6{hi5TZv9F3OQbV_C zlXakpp*OSwodKTXJzqVv zkOY|5Z6_%aLI@#*5VD;=y%nzOxOC3W0}j)@ z1Z`&Ih)oC~ z>!HI9dXvP{MmTU08(byp>aMpZFUphUXoSJ(scNFeqTw2xdKsV)z=8qa6iZ^Ejm8PGvh88x+q()v#|D^Phg;vzOD!8K7s zS&S)^h~619?#edCRxz$u#RUDNEn3^6jbZBmwB8czZCkG(I*VAgHt*SlAF&YkGjj&m z>Yyqgil+&Y7;!(%@Ln4(RBBO#W-Qi-zYh^wwDtJKh} z{r?4f0!`e{H?#ts0j-VH_`yg>p5kdWJhTeIB-K2@iiRsY`EnM{--HPvgb+dqnah7D Wr+8qa@%ShJ0000O7EMM)|*;r>VRU9xbcixwI|#-#n$Qwjh800000%lV3CIF94IsI^Kdz|Z&H4(!Eo9IxkTO~&yNP)ez_lAo;2a0*E@ zjU^|GFmPM{Nn3P3JsF+kkATygS}WTC;#`|j|0rGDTN}L!a(|cD6XP?KY%O|4W=20h zA#0P?Md@zqq7<6RD$Ep5nDmOW80-Lj43=&fwl-(`NlKeb3SwX8nDbFCt!QcrGUHBe zDf5pGnW=QkffQ#^S1`B;vm+pJ5!Msg?7fq0Iiv)|dEHMl<0nA&cEek}oxwTaX2Mg@ zVrI730000MF@L{5nJK|@08S*a@Z^KoJ}7ct2sV4-USNC|jtLPoj8>Kt82y#m5uRRx`TxOzf=JeK|UH8F5vKrbm=GM-WTP~M(z}Uci&VlRl z4j}Xz*2AG4;Cxxp+7~&RL^O4l>CDBxhj2P6RpES(G=Gc{-ZeAtbLMvzvH8p5^6(BQ zYy_4)`-uL@ZG8aB4ztjcF@lUfxRghPH+Q93^L5bYkRGP1h3@2c!o8r_UiSj3E-^}9 zl(bn`OVik_g8dprmsfY;bg}>2+e9yJyA}Fi2>UFVYI`3vV-?LhZP*^X5`ddAT8u;0$1J;Y6rZZBY6J6SU5$<)d zklMN!zqtEib`dVZV-j72{UT_{RZm`jqa;_sMnso~-KQV`yqvTD-Ch6y0Qf)r0_R|3 U?Dto8^8f$<07*qoM6N<$f)!|T0RR91 delta 742 zcmV!ocnIlWWm+dK{g^kAO=}t(Cn1BCao~|0zS$t%SDI?K{Omt} zf>uiIhGAwOcM4~dplr5PZ;P$dc{WP?NOmehAzwcU>Q^#r;OC$Y$WMZrVx&L^N;;?m zSlIt__h(y^S@`mGcM&eaZ8EzE`;(wkQa!%@i;|>*gP2_&K58ETUQKK57i|Cm002DC YKP@_0l*u_2j{pDw07*qoM6N<$g7bG`y#N3J diff --git a/tests/snapshots/nanox/test_sign_message_accept_long_3_0/00000.png b/tests/snapshots/nanox/test_sign_message_accept_long_3_0/00000.png index 9403307a587a49a9de3eeea17ba698e049dc3512..cb25550f4d523c4cacc98971dd9c5c308e195a7c 100644 GIT binary patch delta 40 ucmaFI`i^zON=CLWzAVEG&duu?wHZbJsQT;kY;!YV00K`}KbLh*2~7YJJq%j_ delta 40 vcmaFI`i^zON=CLde5-cIaco}CsLd$y|C+zP(Y#mH3_#%N>gTe~DWM4fKmQJ< diff --git a/tests/snapshots/nanox/test_sign_message_accept_long_3_0/00001.png b/tests/snapshots/nanox/test_sign_message_accept_long_3_0/00001.png index 3da5a411a4b92699fb34d5ddaa516a742f4e8eeb..e6471d399cba1c8ea0787f6aefe62c91b8b0d812 100644 GIT binary patch delta 385 zcmV-{0e=3928#xeBmvT~C3FFQ{GG7@dIM|)n)UBA0>zGS_D-l1Z81ELRzz&CD9lOc z1|Ofwj|7~x34_x8=XRrIu16xnruRp&6`Xo~gN zPuxUT)%h%k1o&N5gRNfB**E;enR;SFcAIg7-r;!MDfeLF4D($FvpnY7W?~~idz<-N z#aDZ6h4y7SoM?ZhpW=~MIsgCw006j)gUjH6eQo1cFXWcDyrwJN0K0{t(+O5=#(ooQZ+savG#)*Qo$1_*kxSmjvMGyNz zH`JJF_@$?+aWR8MR#>^aU&8!My=c#kn`OV{JMF>|pbg>Z*E_>~bQ+Th|57YsSh)ZI f00000{3iYbA5M_$0ih7_00000NkvXXu0mjfif+I7 delta 384 zcmV-`0e}9B28srdBmvQ}C3FFQM;;@31MH_jv;Lh%px6=4-tl*0R}9ai6%pGj3UksK zWXGrS;{rCIw(*9>-=JXwLNkxI{3E@7gB$O`_i*(r^zn2$8TVi*ynAo|BDM|fNPzPM z(N$Z~TS$y%Qe?w?5Z(!k=R5dsacdKDQjOyzMmSRNy?t|T6+P`0MRr|()j5nfnqocn z6F1RSbw0}>0e)B2V5=8&_6c4-DcdNcQ_t*$~~Ak!+h7lERVUinb-)>-e&$* z@zq{ip?#SSC)%Isr+DO*4gdfE008dd;PQM*=yWBwY{b5HL7lfEhykg&m^?+h^dIFE zWr#a0tp?Arlx~a4S$E5GX@W+L&yd%cb}KcbG!!)9wsKaPaiSpY@yyjWt|wGv(Zjyb z4K=13e(9-dT+CpR6;|%?TzdZD#u3v0000k-3IaZN+ZLEq@sIb1Jv1?PBk4+r?gJ zE;iw&M8ae@beF*gV2{Cc7=~@0`ujynTdEhtW1VB2KkLzkE=@sh+{G(yhClUo#y()N(^Jr7S3a=;0Qk4z zN7TMwK^q3^34b@A1sQr99Cag8uhmVTTBn-L*sQh3K`-1u9jOPF;yRMYsMa_;6Ssn; z=9o7EB8+p&;1Q-M5~*kHT({8!X#d?2zZI;rP3fKHFR|SstR8N=x9)0UJ~;vg-m(a> zLaOVkdtjN)zpZYd)up?4ah+4uKJUegb%RXwr%^&p^ff2r8LY%Cw2~8Kp24FCF8}}l m000000000000000@R(oUqojI%NDE9uQ~<0002M za$mg#QcC$E##l>%-}mkgoF%37`8};EI6eYG2r)+Sr|*V1*~MCD zZZ^?O@r224=qZCQz#fC)G7QT+`T0dkS*jMqYn@}A?=`idTT@Uo?&6j)|JcM#W#=47 zaaJ|M;3BM!fCm?0J5eou?W9_dsKMyG-OpyhHxS=;!=HL5V;`_t_Y}0)olk540RA2L z5q0iY(1F34;eX+?AVY0~qi$sKwYuq3>r}HDo3-*d=!F}oEA_xqTzm2u)f#7K;+C`2 z8tX=YhjC8nJi-)3JoW6I>kfJW<-a@px14pBDYeu5Esk4+)x+)2t=UbiCr7}*ugpWN zkm|bHJg^M?@1PlIb?L5M+}Eh;oZrQZRfA0Qmr+7Z^fedb9qhy`v{NIx7xZO zaQ6d?FngJFheD0*nO_f^H{34ZP1wSDdm~T6{?~o==UnyvFlC&#xh5&YEbyOqvGDSI zHhIRBWk(Aa-S+IBH-DqF^>(MP*Oi;Uo=C7YI#4gTOM2J*8sqd+m+t-hvU0Iqz@NL5 zT@R*DTYpt{#-+J3?UDtTmQ|ZhT$wCzU|(D+$M&tSw`FqchW>KWYq+?>?!U3iZMWQ& zk`uWX^xP?%ah}KbcG-s4!TV+Z=HA`^YZ24V`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPx7xZO zaQ6d?FngJFheD0*nO_f^H{34ZP1wSDdm~T6{?~o==UnyvFlC&#xh5&YEbyOqvGDSI zHhIRBWk(Aa-S+IBH-DqF^>(MP*Oi;Uo=C7YI#4gTOM2J*8sqd+m+t-hvU0Iqz@NL5 zT@R*DTYpt{#-+J3?UDtTmQ|ZhT$wCzU|(D+$M&tSw`FqchW>KWYq+?>?!U3iZMWQ& zk`uWX^xP?%ah}KbcG-s4!TV+Z=HA`^YZ24V`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPC;kmeLsWBGKiI@~blO{{7tmatBL9EV1?fj8XK{Oq+ z!u*F{a)}#mNk`ORR86bZ!dJJC*b;_9@>6jg;S@qIhK@zp9mY)YOEn!bKSm!0& z^4gP60T+K_?Okkdl&5{w*wE7`XA`zMBM&&Q>B&3OyfVC)ryDQ_8Kb`qWvDUwn?Vdt zf-H2B${-^KOZo8O9r)%aTx{rV^;|V{^<=pp$&U+aU+q;@9kKj&^vF`Jn6ji$tFmls zS+m{&s|MBkt#+*HNVPl;m3HZ0=D1yPv~*LoWWax#W45}&8ueG_Fsfw{@Ax`;o`G}} za!A+MlQI3~=6nFCO5@Ng<5*uj&PT$^JYzBF+l1+f5<6WQ<_SCDJj06bk`>UdTwVR{8ajgLJXUgh-!z&@(;xFjbAAta0@l;;20GpYRxte39J2iY000000000000000 f000>P09Nx05b|e@pnC0o00000NkvXXu0mjfu1gp` delta 592 zcmV-W0XDBh0{)V;{KQ9Uiy%^4g-Rys7ZUiht920 zApT%-%yj_(00000@OE;}Ip@<+yov8XTcztakHM=){bz#@+B+#FyX5}2l%$l(kGrsx z(5tjQ^~)+(U9+09i4ib$H%8bBU~^FR%Z*(k?NlAn+b+M0HGiXW)i0|lo6vwg5q1&0 z0$7MLR%gll%+l!XKJ8wjA`BjYhv(w1rN&q^Ct^|%O`0sRvYKNh2hoCw+W8}&f@nHs zh53VBa)}%Eq$B@~rmlPMiv|n;000009)YGq%ozD6M7{@v6E!4H9@@2Ps39v>g+|%7 zDjrltH+o6Rr7cwHl<(?QdDV7Qy?P8=3N^}^9%+~zsM+-5uONw9Rm;x@QNgADuF<8nU@7{rLerzRbbpY3s)zHundBRRO$&B2)WCi$@%gb@l zsLfoXp&^J)qGh&M&Y?+NH!zZeoZkbEqdf}mq2oPZ1;Y={A=?iC000000000000000 e0000NU^Ty>m118x-~@mG0000kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_against_wrong_tapleaf_hash_0_1/00002.png b/tests/snapshots/nanox/test_sign_psbt_against_wrong_tapleaf_hash_0_1/00002.png index 317b8b9ff8094162ea10dcf319976a4fbbdcb084..6db885b65f13533ca86f93831b1cd8b83301d511 100644 GIT binary patch delta 711 zcmV;&0yzD{1>XgbB!8w!L_t(|ob8)ia^xTkMM-LQ;{7kld&!40E=rG!1jg8%d%ik6 zgj#?EqEiYXgb+dqA%By7-}ilwSAq7g<9oFN&B6F3fer=|CCa`7LJX5f*B{haO$n-=Lcaz2qA=!ze(a4>YdPo z_es$GJQ{*iqnVZvZJND0nnez&L76@1G>h5blFKAWBmnuKG1e+ITu@Z7eGSS5)y5U8 z?3`Y(Cqx6iz<)ayOLk>t7c%%dryYcGvESdHW2Pq!bn< zrUK&%YaWpe6_|;K%e<CY5K3AiKHzhR33d(%V1eCm)<_QmG zQX?{@3-S(pUJ&jZ6_bjbGZ1f_wN~CaqW%-m*f*E2uYcw#cE+Gn0l~aa!gpQ4%=irm z5Ao}QW}h)q>hE`YvZxKwS3;CinU zfx1cvG=INXb3cJ{JX~rZTo|c}+&ydBxggJEb%P@}5^+IhOW}_7h`?WKfk2Jfm(7$i z2W=NL`+BU6GBV=DFM^7c_6?04po5;y6q>n1EKMI_wfy?C z7tM4zZfVw<2I|P^#+4y1_uoU`^dR$*Z~_P+gg_9|!3Vrvto$dvLB`)^$tWMN19%Tu t3@2bQoPfo=egc~BMT8JS2qAF1DMQNuyVgE~FFa1b|p?V?lFm`g!R|bTT zg+NA5N&o-=0001dCZ&{8ioeT{e;nVZ4M^3MZ{yPtKc@{)5!XZ94LRpmd(N52_*+hK zcn1)NlHEXDBQ_ExRYr6)8OvL)=N3DFILjIPV;WkIYb$ys=YMlR+K^OpL+UyGZ0b74=M8Z!4he^N?c2j{lW1Tjx)=~Rp8`zK)l0001h&&2f_s=b?gZj$2I z+SvZ6y`+mwM`XIA2E;rsrcRyX@B)h{FnNtMiU)>fL)f+_G@VnGQ(i-^1+~s4u~rw^ z*b}V)iSdD8iGM~`G?0x4sWubm`Zs;Z7{LPjw?|A2IsBPas+no}Zh{+tt4n@?EpFO7uX~A+EQNg|TMmpMQNpy#phe&ujZ`J5U+F0CGtHZuwl+7l zMYQUmzkdd4-^H|DVzk@Sg(k8aJzXJVI3u;7*AeL{JZO^SIOdCFoY!2TVaD#;Wylzj z1LbJ3FgdJk%jdv`kmdnnuC9i9j2rN#xE)UwS3*U}{tn<}La}h@9Gh4kBWbqHU3?1O zZcB>2qJsuXxgKK{B;ohw_{HkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_highfee_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_highfee_0_0/00002.png index fda030d56c962bf18cefd5b175cf5f284825a115..e7482655c77dd6da49ee88968605960861ea4eaf 100644 GIT binary patch delta 751 zcmVP`d_A(#zM96O-!Bpj*k5-8y z#+ZlUrn(dW000000N%-Yp67YSzcT8796#9(lq-~96VopKW;>uFj)%A!j^n81$8nH4 z@scc(R{#kpSq&sKVj(ed)e!?tp5-O$*=r`n9(KM4Z>00000hc3bL3ots> zcKQ5|_~2}0TwAs9RRiFbcSXa}g4*Dc`^$BC5pOZ##i#v1uDh;E)7EcI@m5F)FBDB_ zW{HJMc8!Zj+JD79N^oVl)n-2Mziuns!@JCimb=^_EK);>WWSPIwnuj&56|>1)X=Ay z)ZOaic1|9)zi0)J98jb+p_R1tZ&^TNX0@7=UeN*I=IkV_IXdi6kgitZHAS;-uOnf( zYFc$}58RsL>CT5>V>l~6?H5qS7eE%-?*JhBw_^wd@_+uh^FsbI)KFs#7T^RKWAG?E zypOz;=f|@6OK{^zXUI535srx2u{;+~kld?ET7K;n2<_WuugVlL8*wS_e3uGTac;t7 zJ_ZHI2-{uVUJ=2LA<+B!9+9L_t(|ob8)ia>F1DMQNuy@&1>@Uiy*NqtOEi3`TM8`RF)A z2#^q9k(L4g00000z-Llxt+mF#YRJDG-@7|dPE$U{rd|B(?tqEv4>cN&<9L-H$H8Rc zCA-)h0nDH*8klL+LZ;-DQ4P)N%98s@5dq9t!MQ)Cfm+=1=zpE;-vi2mP4yrY&**#i zo}CUjM^2Z5*P1ScBlEN&lXLwkrF?B{yS*l;`=qsA)7pfM;q zs@8Y;MDyKqJWYEDZm(MO<2U^RneiK7q4wthSbu*Ok?erJilzh`kuJqM z-_Aira8ePKV3h>v>g(94jAhx>KFgl7j;X<<)(S?p`mtj??AfxToDR}+sx~=1w~G4E zaBwhsu74L=LvC1qS}sT?eB8EK#dup%cr0Run^TDonUdnixfC{?rDY@cEtXnWKy8=R za(mcCItQ@ZvG~~9K9F8yE{V6>CFwf8<$!qJ@f2&{!%1xe*EOo#K`i?O;g`#7S~Syn*bepsHO7uv3jJVUeUN zNkTdYM9zrqI}p`RX-Ve*IcFtrVc8(>`X+qwN1u6kR|hm7X>(T-P56E~fJs?H zn`?KgLI~;n)Bk9K)jI%>X$^CW!{6Dx1G2WZ*z}RTw;;!B=zk&p$3hGM007u-b-@_^ zQi@8!zF^8L9c~B?D_n|ZzVJ?)0*lpF+c!HXa}KMGezc-=$#OJHY5iJKE@h_+wlbF$ zX5aQtv}u9uz0V?%Dtov!BB}?&YWrhtrQk}O!aE>4=vcY~I>WY_=SnF%e0sW6pKul{ zj8_+%J{}A+UwRL=00000NkvXXu0mjf;1KKK delta 500 zcmVwVu|gt-Gb!*o~ku! z7fKb~#sB~S0002sulP6}z&PhzIJVXvjAX`>9S}Et?8R<)uLDBs$IYEhe8Rue0SrnS z`nh(0m2)nhf9fBf@ai3aV@kvP#o=$>y#tcAezEDj_uhgGuYaMJ_#F!|0001ByV(V! z`)*NG3+xLwp+gh7Mq9uE{G$OJG&1&moZKmK%oXR^OIjESr11iHdnfL$b14h82n^H|M>6)-9L2=O(g;mV#lRQYt8LKpycNCO zw4RZD^&fzERU(FzRqi8dcg)B|VA+g=4rB(5Cw2BV73*)(kR=^08C5*d{j8@+&ztam zSY_CgVvvdcGBTki`itQVo`fp&ByWPu8BFD)!dq$^G;F;+e>@^bc0)_d>x$1~mjkeB zlAT}qI%Xq4Wg$}2+v p000000000000000008(u`~teS+u_oPj`jcm002ovPDHLkV1nsz>!$z! delta 499 zcmVL>N)nO~00000 z0G`fyp67Yq?ZuP$cGML^zjzHEz3M*;Y{=*w$6-sZzfp1=NBnUKqeQmK{?e}MoHea_ zrb7&erMW)bPJr5jX*nEF~N8Q)nY zTEkbGi+7!^JucS}Y#foCxeI?yLz{7`2vQ&NAEhAe4o$*AFp?PonrdftTh z!!pC36oX9kmyroI(O(Q}a3^G;J9!gi)?g|h72Zw`Rx&TWHq$JysG#-c3A+g zLaF`eSNaYW{unHjc5A+i9Z$ehG`p}-F)sUg^X8hz*=PY=*nGdI?2>|lN1^m;HC`D4 p000000000000000006-M;THyb*-AddCKvz!002ovPDHLkV1mK(;DP`E diff --git a/tests/snapshots/nanox/test_sign_psbt_miniscript_multikey_0_1/00000.png b/tests/snapshots/nanox/test_sign_psbt_miniscript_multikey_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_miniscript_multikey_0_1/00002.png b/tests/snapshots/nanox/test_sign_psbt_miniscript_multikey_0_1/00002.png index f67a3aa62b644f4617ca3a0f703564e326a57401..766cd2f4a48dc8ebcbf27a7f45e63eca70ccfc16 100644 GIT binary patch delta 754 zcmVaW3h-rq=pN8t3MimQ1 z70esu1#KltHh(%U`=Wa7sU{9{aS7@WW#?11@+Lc*6nTuKgk?k7@L|^@XzvWPpM9{G z5TafWivr+D{Fc+UPgGTcQ&9)vl54Xl0M6ceT+`|}Q6N=Rj^!q?hQS`mJOJfvP5LHm zs4T_OwjNO$tS!}eWthuNctl;FZAJylhPh8#;zR0`XMfglQOhv4=!{WzG_HH}>i;IQ$Va`ZG{njTkJT;$+0&R_3^up0LY|0xO)Na^ka7^_EtD zqoL`^ei)TK0%sv+oc#5x<>OTT7gUbuK8!3|J}$6xgWbfQcDcMfR2s8WdlW3ona1-! zhVjjaf`9B8pe;evGLNtALQkCR3eMgcy>?c%127>MLl<=95}zVN0ci4mnSitx+>y|>X8*PNemULN)&r1(Y`=gUOmo`H zPKG5rlb(MaROFOHuQgXpQxk~Oj8z>%0DvHV0UN}YO+Q2)*Z=?k07*qoM6N<$f}nb3fB*mh delta 757 zcmVD?m6@tOns4wNWU^GOD9R-@0W#k5~c1S6@Ss4#P0#=hE4S-NG+$w z?mdwK$ah|*f-9%j!k&2wWS*ISQcC{0Cxt z8&wm+8}&umOMlf2Zd~_8^V%b(PIEN{4XDEPRI9yfoLz=IgDeTFhKlJUu4k}*Gq666 zA%28V?RwZ008in!UbbVZni`yj22fKjW>Wy1ck6LYuj5pOrJ;H*cc}#f_Gp#?s8?&U zH(_A1R$KP9x!#0l%#Do=2%s^nebQ1NQh%2`v(Bs92H2u6zRE9H8Q*|N z5VH5P)WE@KC#i@%=i5n*mr;3o56{WOXpLN+|bb11DB6#?B=R z0x)cQ43DjPd4XP*FiF484&U9nMM~@os*=C-aCmWB_-}(}&D`LI@%2smnxx zgZV^o0q1E%zNFWr^q~3&I&obJt9?ly{_3W)WcxsP5DSI@2!;U&<~5}V>s|Q#?JF|= n%lHJJG6e<001!e5AwhftB>0oI3NkF600000NkvXXu0mjfl+I(C diff --git a/tests/snapshots/nanox/test_sign_psbt_multisig_sh_wsh_0_0/00001.png b/tests/snapshots/nanox/test_sign_psbt_multisig_sh_wsh_0_0/00001.png index 87b4dfa0fcd79dd1870bdc60c0d92e4f4b667964..cc2d012b6709decb341536a534fae2f5468252e5 100644 GIT binary patch delta 429 zcmV;e0aE_a1JMJJE`N4}APhiJ+tZz}|0S`Pet1gL1R^*Ab^7j?6A=(JI=F2B006+# z<(zZQSNGycJ_GA2L%(qSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_sign_psbt_multisig_sh_wsh_0_1/00000.png b/tests/snapshots/nanox/test_sign_psbt_multisig_sh_wsh_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_multisig_sh_wsh_0_1/00002.png b/tests/snapshots/nanox/test_sign_psbt_multisig_sh_wsh_0_1/00002.png index fdc5b5dc540cd13f6e39cd311ca9844f1f6043ff..3371075a7baac302e626a97afa1af3b319901198 100644 GIT binary patch delta 658 zcmV;D0&V@V1*!#*B!6*9L_t(|ob8%ha^xTkMafil!v2@UUgpCUis+4P5Ho$xS3(1p zB?RJjmjVC)0002MXVO}0t;Ihw`u}tM$u^*LSN=CXo#H#&02MJFVm8!Tul8Ci=@W0s zA~^$yLrFFe*NBZ|lHNyjG#SfV_H#rA5N8F~{=FGSk82U#Nq_zsP!=4jb)a}o&pmrG z1JK`m+zPHeop+9`Q=`wB`%fw5EAiR(o*1NWpJh#ccwZ-Y1yIdyH8zGu?t_UsybrUF>r^ zGH@I#ddJ>mUWA-{{a>wMvCLS#5ogsZN7Uv&sK#utGJnw#r^jH!+BdGRA4ozBKqqq- z0*;drgQalyI$z3@LMmQy1|_2inl2=kq`iIJ?P1EEN5&Z0U?+;9M2am_v&~ACE3lt3 zWz178NE74SQAP3~xjntIiur_wzROp4Vd*uh4r_1eV&O;{wPnbcEvZD^3?Q?`XVB{1 z+0?NYvVZ#&yIaS~0P&Yk5sBCyXgpEt5SJ<&6R{J^3T_O?7vpYc*^`06vGs?yCJfRP z`7^!=caHdV^ilBred&&G1t3^T8WoQH4r2@d`yLO!?TXM8`7>w?@Y#86oco0g_(a^Q s5dZ)H00000000000000005HX0e+&8=Pw@--01E&B07*qoM6N<$g7HW#;Q#;t delta 665 zcmV;K0%rZH1+fK?B!75GL_t(|ob8%da>FnTM43!(qWd37cgcq`8Vnkjv{)SP`*LU& z5CGdcr4T|0A%qa}nVjc&o+tiQQvdDvUTr|RUHNZ(+QiRl147(*xU1nfj;s7Q4pj#) zS;gWNpd6}JgK~{qs5-gpxQ~MQ))h)m1+v?`jJ<`sSKX zb=l4|X7ng}3j!za9?LoTp^Y?@ZC&r=o6Li#WAFY`xqqeUO7i#h2wNZTbLVlZgoX{W zc%dWSDF%ab|MA}%{|%F3KwM_;LPSz=GGj0l>t09=#c!OTWCRWhs+Dq}aSw!|3Kl>t$?eQr_r(3J^(>cy^N5fyEQD_ zao`T{cqAgv;+wE#i~o+^0lUA?+3}$OxL3*KhLg`hme|jIy!e9`!Wk%_pfRM*l4E19 zA7sdfg5MemA%qY@2qAqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_sign_psbt_multisig_sh_wsh_missing_nonwitnessutxo_0_1/00002.png b/tests/snapshots/nanox/test_sign_psbt_multisig_sh_wsh_missing_nonwitnessutxo_0_1/00002.png index c6b820aa9ea685e7571ff9c9d6abeec5df7452ef..1e798bb2a48988837e7c091787b148b163276ec9 100644 GIT binary patch delta 403 zcmV;E0c`%Z1GWQ@Eq_~b!ypVmQPSy7*#DB)OF!r^gr~5Pt;F|yVHYrn2F9{;00000 z000000002sF+vE!n@bgJ`nh`m|EA&d-dh;Pb}#J*q$#Bc4(`O8#bv4!%SH2M;MnJlKep&RL)dgsG`+d=O=Oz_G zP>sn`*1)C*?Lr1kg3KDIG8A6z7k%wb{NqU$;BW+shL%@i+naFyicyybIm@DxR410} z*P>~9wP=`Mx_?%Bbuh?Y=G9In<4r!*V%kNW)k3p}`m)!suCqGG>8K97C>JCgw7iej z-LnZfxcq&1`GfODwT5o|cW=Bq{fjZxL$!Ib_0MHHbV`dNP2PvSYm>bzqq?^*Y~H`L zR~x5(Dr%j%J?fgxukgQ%b^qLG{dV$p*uzx*9l`ZI7tdFH+7aInceB?g-P`ZLy}Qfq z1x`=&?+JTzWATiIHv_+yIp zd)o2UixO)ktLl%hp6u7>7x#Bg%Aa8VP@d>3mQgR!>OzO}3E_>|k{<kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_multisig_sh_wsh_missing_nonwitnessutxo_0_2/00002.png b/tests/snapshots/nanox/test_sign_psbt_multisig_sh_wsh_missing_nonwitnessutxo_0_2/00002.png index fdc5b5dc540cd13f6e39cd311ca9844f1f6043ff..3371075a7baac302e626a97afa1af3b319901198 100644 GIT binary patch delta 658 zcmV;D0&V@V1*!#*B!6*9L_t(|ob8%ha^xTkMafil!v2@UUgpCUis+4P5Ho$xS3(1p zB?RJjmjVC)0002MXVO}0t;Ihw`u}tM$u^*LSN=CXo#H#&02MJFVm8!Tul8Ci=@W0s zA~^$yLrFFe*NBZ|lHNyjG#SfV_H#rA5N8F~{=FGSk82U#Nq_zsP!=4jb)a}o&pmrG z1JK`m+zPHeop+9`Q=`wB`%fw5EAiR(o*1NWpJh#ccwZ-Y1yIdyH8zGu?t_UsybrUF>r^ zGH@I#ddJ>mUWA-{{a>wMvCLS#5ogsZN7Uv&sK#utGJnw#r^jH!+BdGRA4ozBKqqq- z0*;drgQalyI$z3@LMmQy1|_2inl2=kq`iIJ?P1EEN5&Z0U?+;9M2am_v&~ACE3lt3 zWz178NE74SQAP3~xjntIiur_wzROp4Vd*uh4r_1eV&O;{wPnbcEvZD^3?Q?`XVB{1 z+0?NYvVZ#&yIaS~0P&Yk5sBCyXgpEt5SJ<&6R{J^3T_O?7vpYc*^`06vGs?yCJfRP z`7^!=caHdV^ilBred&&G1t3^T8WoQH4r2@d`yLO!?TXM8`7>w?@Y#86oco0g_(a^Q s5dZ)H00000000000000005HX0e+&8=Pw@--01E&B07*qoM6N<$g7HW#;Q#;t delta 665 zcmV;K0%rZH1+fK?B!75GL_t(|ob8%da>FnTM43!(qWd37cgcq`8Vnkjv{)SP`*LU& z5CGdcr4T|0A%qa}nVjc&o+tiQQvdDvUTr|RUHNZ(+QiRl147(*xU1nfj;s7Q4pj#) zS;gWNpd6}JgK~{qs5-gpxQ~MQ))h)m1+v?`jJ<`sSKX zb=l4|X7ng}3j!za9?LoTp^Y?@ZC&r=o6Li#WAFY`xqqeUO7i#h2wNZTbLVlZgoX{W zc%dWSDF%ab|MA}%{|%F3KwM_;LPSz=GGj0l>t09=#c!OTWCRWhs+Dq}aSw!|3Kl>t$?eQr_r(3J^(>cy^N5fyEQD_ zao`T{cqAgv;+wE#i~o+^0lUA?+3}$OxL3*KhLg`hme|jIy!e9`!Wk%_pfRM*l4E19 zA7sdfg5MemA%qY@2qAqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_sign_psbt_multisig_wsh_0_1/00000.png b/tests/snapshots/nanox/test_sign_psbt_multisig_wsh_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_multisig_wsh_0_1/00002.png b/tests/snapshots/nanox/test_sign_psbt_multisig_wsh_0_1/00002.png index fda030d56c962bf18cefd5b175cf5f284825a115..e7482655c77dd6da49ee88968605960861ea4eaf 100644 GIT binary patch delta 751 zcmVP`d_A(#zM96O-!Bpj*k5-8y z#+ZlUrn(dW000000N%-Yp67YSzcT8796#9(lq-~96VopKW;>uFj)%A!j^n81$8nH4 z@scc(R{#kpSq&sKVj(ed)e!?tp5-O$*=r`n9(KM4Z>00000hc3bL3ots> zcKQ5|_~2}0TwAs9RRiFbcSXa}g4*Dc`^$BC5pOZ##i#v1uDh;E)7EcI@m5F)FBDB_ zW{HJMc8!Zj+JD79N^oVl)n-2Mziuns!@JCimb=^_EK);>WWSPIwnuj&56|>1)X=Ay z)ZOaic1|9)zi0)J98jb+p_R1tZ&^TNX0@7=UeN*I=IkV_IXdi6kgitZHAS;-uOnf( zYFc$}58RsL>CT5>V>l~6?H5qS7eE%-?*JhBw_^wd@_+uh^FsbI)KFs#7T^RKWAG?E zypOz;=f|@6OK{^zXUI535srx2u{;+~kld?ET7K;n2<_WuugVlL8*wS_e3uGTac;t7 zJ_ZHI2-{uVUJ=2LA<+B!9+9L_t(|ob8)ia>F1DMQNuy@&1>@Uiy*NqtOEi3`TM8`RF)A z2#^q9k(L4g00000z-Llxt+mF#YRJDG-@7|dPE$U{rd|B(?tqEv4>cN&<9L-H$H8Rc zCA-)h0nDH*8klL+LZ;-DQ4P)N%98s@5dq9t!MQ)Cfm+=1=zpE;-vi2mP4yrY&**#i zo}CUjM^2Z5*P1ScBlEN&lXLwkrF?B{yS*l;`=qsA)7pfM;q zs@8Y;MDyKqJWYEDZm(MO<2U^RneiK7q4wthSbu*Ok?erJilzh`kuJqM z-_Aira8ePKV3h>v>g(94jAhx>KFgl7j;X<<)(S?p`mtj??AfxToDR}+sx~=1w~G4E zaBwhsu74L=LvC1qS}sT?eB8EK#dup%cr0Run^TDonUdnixfC{?rDY@cEtXnWKy8=R za(mcCItQ@ZvG~~9K9F8yE{V6>CFwf8<$!qJ@f2&{!%1xe*EOo#K`i?O;g`#7S~Syn*bepsHO7uv3jJVUeUN zNkTdYM9zrqI}p`RX-Ve*IcFtrVc8(>`X+qwN1u6kR|hqSR!(-EHB$tg{w`glJ*d% z!?L+^!tMZd4cc+p`4L-BwIO-hWxLeo6t1?bO4>tYhkJTBB!Bo0P+hcr?ToyBWwneB zU+Y|=dKf$bH_ydGx0*8Pnutk3GHI&Bs!E=VT&UHVs3(8qTaZl0Dwu!xk{ zZTV{Oxl{Y=Fn_Vw1+VJfR-{$f|32X~y7I%uqB|hm>9o^1rpq2YkDP$k!u{ysC1Rga z%Q8>oVw_{f1*H=Di&b5f>p#@*NpBRb4}mt~d8yu5>WS%)wL)FD3v000000000000000005Hur Xpq7$MZ9l@v00000NkvXXu0mjf0~ya7 delta 429 zcmV;e0aE_a1JMJJE`M@_APj(E+v!cX|B<*$ADE>X0ukJRvi-j&HzFWtbn!R<004m9 z#Ta9ZclTl^-;Qf;Qyngb?gV`k5mkguIc0IU@JU^0M8caJA{8q&~#x zux#!cw>zM?2KBfkc0|`xZAhMW-p;idg{$orCG{b)!#zD5;(vSx6kXJP?ToyCWwneB zU+Y}Fdgwd>56{Izw_0J+HQ|$jWYR1WYfUI}-G;1~fTJ<`deO1E*FG?9SJxQyTBcm- z)a9$eeW&)%X@6qT3trW|tw^h|{e8k{bmfPQMR$O^%W0=`OqV@)ww!?0!u{ysIijCZ z%QBDWVw_>d1yv;UH>P(7bnB}*>Buc#`Anl zi%Z*np!E|_Z{>fEe$x3b-M!I{5au8Y-RWeInS-eqUM2tl0000000000000000AQM5 X>`RZeLDH?e00000NkvXXu0mjfJ{8sW diff --git a/tests/snapshots/nanox/test_sign_psbt_multisig_wsh_v1_0_1/00000.png b/tests/snapshots/nanox/test_sign_psbt_multisig_wsh_v1_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_multisig_wsh_v1_0_1/00002.png b/tests/snapshots/nanox/test_sign_psbt_multisig_wsh_v1_0_1/00002.png index fda030d56c962bf18cefd5b175cf5f284825a115..e7482655c77dd6da49ee88968605960861ea4eaf 100644 GIT binary patch delta 751 zcmVP`d_A(#zM96O-!Bpj*k5-8y z#+ZlUrn(dW000000N%-Yp67YSzcT8796#9(lq-~96VopKW;>uFj)%A!j^n81$8nH4 z@scc(R{#kpSq&sKVj(ed)e!?tp5-O$*=r`n9(KM4Z>00000hc3bL3ots> zcKQ5|_~2}0TwAs9RRiFbcSXa}g4*Dc`^$BC5pOZ##i#v1uDh;E)7EcI@m5F)FBDB_ zW{HJMc8!Zj+JD79N^oVl)n-2Mziuns!@JCimb=^_EK);>WWSPIwnuj&56|>1)X=Ay z)ZOaic1|9)zi0)J98jb+p_R1tZ&^TNX0@7=UeN*I=IkV_IXdi6kgitZHAS;-uOnf( zYFc$}58RsL>CT5>V>l~6?H5qS7eE%-?*JhBw_^wd@_+uh^FsbI)KFs#7T^RKWAG?E zypOz;=f|@6OK{^zXUI535srx2u{;+~kld?ET7K;n2<_WuugVlL8*wS_e3uGTac;t7 zJ_ZHI2-{uVUJ=2LA<+B!9+9L_t(|ob8)ia>F1DMQNuy@&1>@Uiy*NqtOEi3`TM8`RF)A z2#^q9k(L4g00000z-Llxt+mF#YRJDG-@7|dPE$U{rd|B(?tqEv4>cN&<9L-H$H8Rc zCA-)h0nDH*8klL+LZ;-DQ4P)N%98s@5dq9t!MQ)Cfm+=1=zpE;-vi2mP4yrY&**#i zo}CUjM^2Z5*P1ScBlEN&lXLwkrF?B{yS*l;`=qsA)7pfM;q zs@8Y;MDyKqJWYEDZm(MO<2U^RneiK7q4wthSbu*Ok?erJilzh`kuJqM z-_Aira8ePKV3h>v>g(94jAhx>KFgl7j;X<<)(S?p`mtj??AfxToDR}+sx~=1w~G4E zaBwhsu74L=LvC1qS}sT?eB8EK#dup%cr0Run^TDonUdnixfC{?rDY@cEtXnWKy8=R za(mcCItQ@ZvG~~9K9F8yE{V6>CFwf8<$!qJ@f2&{!%1xe*EOo#K`i?O;g`#7S~Syn*bepsHO7uv3jJVUeUN zNkTdYM9zrqI}p`RX-Ve*IcFtrVc8(>`X+qwN1u6kR|hkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_large_amount_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_large_amount_0_0/00002.png index 20efb47d7c4d92952734bb580a7ce4bcd2fd9c84..c4e98a69ea34ddff4a0edcf0eba6a9707cebd3a4 100644 GIT binary patch delta 906 zcmV;519kkV2dM{;Eq_^(-5?A_sjlqA`(Kjxl8;w$R2nW95VrH8^U>wTLK0#!YPz+e zD2k#eilX=?&htFalYa%|v;4v4WXbu5sCpJZJCruz?$(&{*jT$_$8lV5>e*TqRp(u)?C=5fX&D%V& zX-lShy2CiPx__kCeO84}b-;w(9cfytledC$K{B}NEaRTDtVuUFU{zh`WceVKSi4=f zBh6OWJ+4QdG!xUkN3&=KMETC>8OXb0ScyFhcMWwP>`&f}%ad-yEqDJtz(uA0N9#8D z2NtV&#|D7s8Q>Kia3^w+nO2gR7kWhptc;*_&2p=d&wqeKCv^u{^LP_>arbIjIJ&P! z*cGO$dC0ER29y9dY%r1Cl*RE|lUD8r_sVzhhadT(lHE7p&#E1#k}m^%`>tq%Ma3S% zP*)$^Kqtu62V2Pr@6ZYe#O7Agp(?J4NCQYMw4fmmjMpKPWUz(;I^hOc5odc``SlLy zWJ6U71%D?LUHNDnMW4JAv(ybM_K^i4B z+h;}+RF6DS%;bXHgnpaqYCCn@*e&KVqq*CaAFVjSmSmiq>20tXSaKqlnI6QI)>%3o zz>ID?UYMPOA1C9_&BUoB;#4a8wC+J1QRuq&QE) zXP*@P&rmS3qzx%HJ-Q?Pjh;qI9vihWQb#|lDt!+1Pr~lqRr@P*t<~0A0jqMaSdrG< zTYtUXG}Ki-)WFGPTvi;XW5g?DAX8plC5)J2@+2Hx85`o}=&ui&&z-&%4VL*-#9|-3 zWbDhjHWiq-U`9N7IoB?lpu}R6qfzz5U8n0z_j+jYm&Na0QU+7m(1&@&{|DR;Gxo_V g_(f3^MKQ^5vy|0ua)xs=00000NkvXXt^-0~f~`@&rT_o{ delta 906 zcmV;519kkV2dM{;Eq_~%-Y^J8tx_jQ&p~^TI2)^^XtrbO4 z6h%=K#g{nG^E^-gDm_j&R?wRS^TU}+K9VLW9mo7S`|Bv<9G)M(5$X3VSgs1fCp(hg@q%4dF<@_ zV;X2ctri7@dPXh_8z8;2$evEy=IYm3Mz<|p`BTvCIvwd(fTXaee*qcK{NrTUy-8N> zg6M?H3R&m!%&oVKwNq3DoF>#Q05w4icdpN$V*Ze^`k3;4<{Kc(lcFe!q6iX7ZEo|# z+Ir&Z=?>%E>VK48^_dku)c^x_SEOmBPQMkDilD(|XBqXJB~8i{jjHNCC({S2MB44T zZE2Rm>T%ujq=}fWJ(^h~z{+=8&p=)k!%E~~xNE5UApiBdaeLDJaLMl915{Y*KU%lJ zA6TU36$=0!XMk5Uz)t8SGpr;rFZ7BAnCU_Dn(0zOpML>~PVxqj=J6t|qOR4nFuJZ< z$Qh=qIb_%Rfq^LjZpdIFyD5|7SCdxihI?ioeDOnHRI+;m`lwoQD)|^-?>nOn78PqS zLtSmKfliRC4VID?-q0in#KtDmP!-jLrNNV3u;ljf*Cib05UmDaqMI@TY~`2%vTfHm=qFf(vO$x0dCG z)2LIkds0$NJsao>~SvIKB-kU<#(d+zy=uo+w!RRZ2d2} z=ezjxP7>EP6!a`=iHZ&PZcBf24aAX!gSrd%T}{l2<5-MB3cEP-U06d`MrHgYY~30Qu{rva%C9?p!_`%$QW2AF z@P@umE6O}z;%sU0@a0@Nb%GL!OpaRBvt~=|M)z)L@ef&>-5Dwy`Y^Bf{{j2)^!?!- gQBf2{QMmXE8`{)1<1!*w00000NkvXXt^-0~f@3zxc>n+a diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_large_amount_0_0/00003.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_large_amount_0_0/00003.png index bd1388feddbdc00a984d19e7779e8bb856f0c8be..bb17102ab65b352d80ed383be5903b24e140feca 100644 GIT binary patch delta 437 zcmV;m0ZRVR1J47HB!8AkL_t(|obB0dl7k=&fMK@Nn{fXlahLt!Oos^xL?ue?`~2EP ziZOf@n-Ty30Pq;4lv0ZSQm6i`c*MQ>F|>7p!h1zDT0cfa`+K!{%sD45yt=%t6Y)6j z=`D7s51@|3oU@e$e~HSvhj9E3&;(xPkiFJ#;tVwfH)C>^e zI>-L87V6|W(=Dp)8XR+l>;WlYQ_Yn$N_zj+p1>~Ky(V|SC+>PF*w*y6vS)DhSM%Ze z<8S$JgeU#YZLYs2s2iQNomwOMz$V=J<|B6d_I919;5B7Ej6SJ6+>{QO5(xkR>j~QB z4jjU-6m=3_(0@8fuU+~!R5cu-+gV8*ls*S2QLX;BZBRXt{q)&NecRqI^!(w!n(m$% zKePm`>Ha0?j0e1*`I-(;-Nm0jtXIcD+P%~&RJ9vve`~#c#thQC;1@M3B=v{S z1>GONpvC|2xRECvT^G$v5JZ7rtgDwjUl1v|jBE0|r0000000000 f0000006>_3M$dq4G;uXj00000NkvXXu0mjf5%k!m delta 438 zcmV;n0ZIPP1JDDIB!8DlL_t(|obB0dj)Wi#fMIsBH{t$A;x7BcWJB5lRjH!$KEEc& zU@adGOiBO%0KjXMQc5ZQOP%_&;t}`i$Dr#3h4+bQw0?|;_V?0x%sD43yt-W1iFlmf z=`D7c4`7bOoO3G+{t{E`lJo1+&7T1xp<*_OXEO^^W6YX~7JuK>C9PZR)tWRXMa=*a zu5;`kYoSiAGu@)vuE8-^R0m8SDSD*WeX|XG=S@A;E_-`TUV{GPu9t!>LAtVMaP?R7 z;riom`EZ0M{mgByzb2S3y4LGdH=^tGONKF|Y9_UA*NF;VQ#KjVJC&E4(g9N<0RUh< zL2tPOoA4`zoPUO{X`Q6kE!K+yDRo diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png index 9d8efd1df120d50b84cd15a7884717514b7c131c..b88fc1e2a203f8a8b7ad211d8d9bbf40e13586b4 100644 GIT binary patch delta 704 zcmV;x0zduK1=t0UB!8btL_t(|ob8)!j>I4chTYBH#QPtqciA6JjNwaEtaj#o{?%Hb zpjenpN&o-=0001dC)agd*X6%u%zqufyA4Ril^^5NF8+2Kpd!XY+zmPBdpze%=J-c; zv3Um&hmzeuTq6z=A!Ux}X!0x{d7dM70CARc?T<;QJ+4LcNq_dA0cpXZnk!Pv>3h$f zodGCsUZ;XPr}N34b!yBxGykNNem3g1bAotIYR9RzqR&5s0RR9106-tjdevxfih~7h z#3_o4^~}+#X!1tkRokjogjP>!7+?C6HrOun+v$-ufE57Zi@IO^w#_r^)BxZ zqkY;g($#nOOJZ;WACiS$O2f&B!BU=Zuh>o?BQrAjrN@i`MYiSq(y8J(w5HHx0GvX^ z{!Evy+QoJgX~z5BUeF~q|7zWyT0R%_Jk)NV!9Tt#Mm8QkHpmxDM>TpHTW zH5Qb;1AqM5Jt~O&flE=o#%wp#&@|I%)V5I>7kjSUfaaX-xqCJMP0tSW;7a70Da#|u z6Q^FW24f4ZLwfV*w-ZQmWDh>l%yrH|;}r}`{Feh!oZ10)57Kj%iu*%*kgVl;b=z-l z?}OMZ)cXZ7D1CBH?}LFpT9@?gjiPbHA2bZsra9CD=%@pd`?roj0$sm4mf=+e00000 m000000000000000AHYAp*j2v4I}w%u0000`S1=IzQB!8PpL_t(|ob8)Qj>I4gMd?=GB=(16<5_n7iRPj;sAR4lyR) zvWv|-KsZ$F2H_gBQ3%OnOh=1%b<6!cVh0Fk1=oI`gwo?)M1SvO{~3@L9I8h_syTh{ z*|ReMdFEv*xN^E499gGe%ro;(O6g~#Zk!X$bJ9Cby%qiZLzoak2qA>DQN6E%0;k!S z@meBsw9LpD?+PuZv*OCOsubbfr#!%y{)hqCWpN`T()vIF5WXlcu3~_$nwdAF>Wgt> zyx!b}Yj#bl^?zVJLE)b{%gD?p=57^v1IY1SG`q|c6tpBb1u(utT4aub`6=j%KVC9% zQKF?!4wk>SCc2~;r}tnafzEZVr$TG_%yP8$`1m0<9-)a9&}%y5Cdm{uaT(@Z)N$ly zV@grUNf&VyVwib!Py7tiLMrZE@tL)bCTsEOIvpV2?SFca_dD)H&k2Ct`y%gm<9*jI z($zfR8)EPfJ|PRemx_}agQeWzUbCDaTDk@5$A}Fbim=)GF{t8JyrR%Z0D=Ec$Z^DOkbX5G26%<^$bg##}N{li=x-sbhz z6y5=z1b=V;Y5BTqixYjcF6rZq0(it9G(7G|sk>>r2Q?(!)Ke!g;}kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_other_encodings_0_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_other_encodings_0_0_0/00002.png index 9d8efd1df120d50b84cd15a7884717514b7c131c..b88fc1e2a203f8a8b7ad211d8d9bbf40e13586b4 100644 GIT binary patch delta 704 zcmV;x0zduK1=t0UB!8btL_t(|ob8)!j>I4chTYBH#QPtqciA6JjNwaEtaj#o{?%Hb zpjenpN&o-=0001dC)agd*X6%u%zqufyA4Ril^^5NF8+2Kpd!XY+zmPBdpze%=J-c; zv3Um&hmzeuTq6z=A!Ux}X!0x{d7dM70CARc?T<;QJ+4LcNq_dA0cpXZnk!Pv>3h$f zodGCsUZ;XPr}N34b!yBxGykNNem3g1bAotIYR9RzqR&5s0RR9106-tjdevxfih~7h z#3_o4^~}+#X!1tkRokjogjP>!7+?C6HrOun+v$-ufE57Zi@IO^w#_r^)BxZ zqkY;g($#nOOJZ;WACiS$O2f&B!BU=Zuh>o?BQrAjrN@i`MYiSq(y8J(w5HHx0GvX^ z{!Evy+QoJgX~z5BUeF~q|7zWyT0R%_Jk)NV!9Tt#Mm8QkHpmxDM>TpHTW zH5Qb;1AqM5Jt~O&flE=o#%wp#&@|I%)V5I>7kjSUfaaX-xqCJMP0tSW;7a70Da#|u z6Q^FW24f4ZLwfV*w-ZQmWDh>l%yrH|;}r}`{Feh!oZ10)57Kj%iu*%*kgVl;b=z-l z?}OMZ)cXZ7D1CBH?}LFpT9@?gjiPbHA2bZsra9CD=%@pd`?roj0$sm4mf=+e00000 m000000000000000AHYAp*j2v4I}w%u0000`S1=IzQB!8PpL_t(|ob8)Qj>I4gMd?=GB=(16<5_n7iRPj;sAR4lyR) zvWv|-KsZ$F2H_gBQ3%OnOh=1%b<6!cVh0Fk1=oI`gwo?)M1SvO{~3@L9I8h_syTh{ z*|ReMdFEv*xN^E499gGe%ro;(O6g~#Zk!X$bJ9Cby%qiZLzoak2qA>DQN6E%0;k!S z@meBsw9LpD?+PuZv*OCOsubbfr#!%y{)hqCWpN`T()vIF5WXlcu3~_$nwdAF>Wgt> zyx!b}Yj#bl^?zVJLE)b{%gD?p=57^v1IY1SG`q|c6tpBb1u(utT4aub`6=j%KVC9% zQKF?!4wk>SCc2~;r}tnafzEZVr$TG_%yP8$`1m0<9-)a9&}%y5Cdm{uaT(@Z)N$ly zV@grUNf&VyVwib!Py7tiLMrZE@tL)bCTsEOIvpV2?SFca_dD)H&k2Ct`y%gm<9*jI z($zfR8)EPfJ|PRemx_}agQeWzUbCDaTDk@5$A}Fbim=)GF{t8JyrR%Z0D=Ec$Z^DOkbX5G26%<^$bg##}N{li=x-sbhz z6y5=z1b=V;Y5BTqixYjcF6rZq0(it9G(7G|sk>>r2Q?(!)Ke!g;}kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_other_encodings_1_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_other_encodings_1_0_0/00002.png index 9d8efd1df120d50b84cd15a7884717514b7c131c..b88fc1e2a203f8a8b7ad211d8d9bbf40e13586b4 100644 GIT binary patch delta 704 zcmV;x0zduK1=t0UB!8btL_t(|ob8)!j>I4chTYBH#QPtqciA6JjNwaEtaj#o{?%Hb zpjenpN&o-=0001dC)agd*X6%u%zqufyA4Ril^^5NF8+2Kpd!XY+zmPBdpze%=J-c; zv3Um&hmzeuTq6z=A!Ux}X!0x{d7dM70CARc?T<;QJ+4LcNq_dA0cpXZnk!Pv>3h$f zodGCsUZ;XPr}N34b!yBxGykNNem3g1bAotIYR9RzqR&5s0RR9106-tjdevxfih~7h z#3_o4^~}+#X!1tkRokjogjP>!7+?C6HrOun+v$-ufE57Zi@IO^w#_r^)BxZ zqkY;g($#nOOJZ;WACiS$O2f&B!BU=Zuh>o?BQrAjrN@i`MYiSq(y8J(w5HHx0GvX^ z{!Evy+QoJgX~z5BUeF~q|7zWyT0R%_Jk)NV!9Tt#Mm8QkHpmxDM>TpHTW zH5Qb;1AqM5Jt~O&flE=o#%wp#&@|I%)V5I>7kjSUfaaX-xqCJMP0tSW;7a70Da#|u z6Q^FW24f4ZLwfV*w-ZQmWDh>l%yrH|;}r}`{Feh!oZ10)57Kj%iu*%*kgVl;b=z-l z?}OMZ)cXZ7D1CBH?}LFpT9@?gjiPbHA2bZsra9CD=%@pd`?roj0$sm4mf=+e00000 m000000000000000AHYAp*j2v4I}w%u0000`S1=IzQB!8PpL_t(|ob8)Qj>I4gMd?=GB=(16<5_n7iRPj;sAR4lyR) zvWv|-KsZ$F2H_gBQ3%OnOh=1%b<6!cVh0Fk1=oI`gwo?)M1SvO{~3@L9I8h_syTh{ z*|ReMdFEv*xN^E499gGe%ro;(O6g~#Zk!X$bJ9Cby%qiZLzoak2qA>DQN6E%0;k!S z@meBsw9LpD?+PuZv*OCOsubbfr#!%y{)hqCWpN`T()vIF5WXlcu3~_$nwdAF>Wgt> zyx!b}Yj#bl^?zVJLE)b{%gD?p=57^v1IY1SG`q|c6tpBb1u(utT4aub`6=j%KVC9% zQKF?!4wk>SCc2~;r}tnafzEZVr$TG_%yP8$`1m0<9-)a9&}%y5Cdm{uaT(@Z)N$ly zV@grUNf&VyVwib!Py7tiLMrZE@tL)bCTsEOIvpV2?SFca_dD)H&k2Ct`y%gm<9*jI z($zfR8)EPfJ|PRemx_}agQeWzUbCDaTDk@5$A}Fbim=)GF{t8JyrR%Z0D=Ec$Z^DOkbX5G26%<^$bg##}N{li=x-sbhz z6y5=z1b=V;Y5BTqixYjcF6rZq0(it9G(7G|sk>>r2Q?(!)Ke!g;}kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_v1_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_v1_0_0/00002.png index 9d8efd1df120d50b84cd15a7884717514b7c131c..b88fc1e2a203f8a8b7ad211d8d9bbf40e13586b4 100644 GIT binary patch delta 704 zcmV;x0zduK1=t0UB!8btL_t(|ob8)!j>I4chTYBH#QPtqciA6JjNwaEtaj#o{?%Hb zpjenpN&o-=0001dC)agd*X6%u%zqufyA4Ril^^5NF8+2Kpd!XY+zmPBdpze%=J-c; zv3Um&hmzeuTq6z=A!Ux}X!0x{d7dM70CARc?T<;QJ+4LcNq_dA0cpXZnk!Pv>3h$f zodGCsUZ;XPr}N34b!yBxGykNNem3g1bAotIYR9RzqR&5s0RR9106-tjdevxfih~7h z#3_o4^~}+#X!1tkRokjogjP>!7+?C6HrOun+v$-ufE57Zi@IO^w#_r^)BxZ zqkY;g($#nOOJZ;WACiS$O2f&B!BU=Zuh>o?BQrAjrN@i`MYiSq(y8J(w5HHx0GvX^ z{!Evy+QoJgX~z5BUeF~q|7zWyT0R%_Jk)NV!9Tt#Mm8QkHpmxDM>TpHTW zH5Qb;1AqM5Jt~O&flE=o#%wp#&@|I%)V5I>7kjSUfaaX-xqCJMP0tSW;7a70Da#|u z6Q^FW24f4ZLwfV*w-ZQmWDh>l%yrH|;}r}`{Feh!oZ10)57Kj%iu*%*kgVl;b=z-l z?}OMZ)cXZ7D1CBH?}LFpT9@?gjiPbHA2bZsra9CD=%@pd`?roj0$sm4mf=+e00000 m000000000000000AHYAp*j2v4I}w%u0000`S1=IzQB!8PpL_t(|ob8)Qj>I4gMd?=GB=(16<5_n7iRPj;sAR4lyR) zvWv|-KsZ$F2H_gBQ3%OnOh=1%b<6!cVh0Fk1=oI`gwo?)M1SvO{~3@L9I8h_syTh{ z*|ReMdFEv*xN^E499gGe%ro;(O6g~#Zk!X$bJ9Cby%qiZLzoak2qA>DQN6E%0;k!S z@meBsw9LpD?+PuZv*OCOsubbfr#!%y{)hqCWpN`T()vIF5WXlcu3~_$nwdAF>Wgt> zyx!b}Yj#bl^?zVJLE)b{%gD?p=57^v1IY1SG`q|c6tpBb1u(utT4aub`6=j%KVC9% zQKF?!4wk>SCc2~;r}tnafzEZVr$TG_%yP8$`1m0<9-)a9&}%y5Cdm{uaT(@Z)N$ly zV@grUNf&VyVwib!Py7tiLMrZE@tL)bCTsEOIvpV2?SFca_dD)H&k2Ct`y%gm<9*jI z($zfR8)EPfJ|PRemx_}agQeWzUbCDaTDk@5$A}Fbim=)GF{t8JyrR%Z0D=Ec$Z^DOkbX5G26%<^$bg##}N{li=x-sbhz z6y5=z1b=V;Y5BTqixYjcF6rZq0(it9G(7G|sk>>r2Q?(!)Ke!g;}kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png index fda030d56c962bf18cefd5b175cf5f284825a115..e7482655c77dd6da49ee88968605960861ea4eaf 100644 GIT binary patch delta 751 zcmVP`d_A(#zM96O-!Bpj*k5-8y z#+ZlUrn(dW000000N%-Yp67YSzcT8796#9(lq-~96VopKW;>uFj)%A!j^n81$8nH4 z@scc(R{#kpSq&sKVj(ed)e!?tp5-O$*=r`n9(KM4Z>00000hc3bL3ots> zcKQ5|_~2}0TwAs9RRiFbcSXa}g4*Dc`^$BC5pOZ##i#v1uDh;E)7EcI@m5F)FBDB_ zW{HJMc8!Zj+JD79N^oVl)n-2Mziuns!@JCimb=^_EK);>WWSPIwnuj&56|>1)X=Ay z)ZOaic1|9)zi0)J98jb+p_R1tZ&^TNX0@7=UeN*I=IkV_IXdi6kgitZHAS;-uOnf( zYFc$}58RsL>CT5>V>l~6?H5qS7eE%-?*JhBw_^wd@_+uh^FsbI)KFs#7T^RKWAG?E zypOz;=f|@6OK{^zXUI535srx2u{;+~kld?ET7K;n2<_WuugVlL8*wS_e3uGTac;t7 zJ_ZHI2-{uVUJ=2LA<+B!9+9L_t(|ob8)ia>F1DMQNuy@&1>@Uiy*NqtOEi3`TM8`RF)A z2#^q9k(L4g00000z-Llxt+mF#YRJDG-@7|dPE$U{rd|B(?tqEv4>cN&<9L-H$H8Rc zCA-)h0nDH*8klL+LZ;-DQ4P)N%98s@5dq9t!MQ)Cfm+=1=zpE;-vi2mP4yrY&**#i zo}CUjM^2Z5*P1ScBlEN&lXLwkrF?B{yS*l;`=qsA)7pfM;q zs@8Y;MDyKqJWYEDZm(MO<2U^RneiK7q4wthSbu*Ok?erJilzh`kuJqM z-_Aira8ePKV3h>v>g(94jAhx>KFgl7j;X<<)(S?p`mtj??AfxToDR}+sx~=1w~G4E zaBwhsu74L=LvC1qS}sT?eB8EK#dup%cr0Run^TDonUdnixfC{?rDY@cEtXnWKy8=R za(mcCItQ@ZvG~~9K9F8yE{V6>CFwf8<$!qJ@f2&{!%1xe*EOo#K`i?O;g`#7S~Syn*bepsHO7uv3jJVUeUN zNkTdYM9zrqI}p`RX-Ve*IcFtrVc8(>`X+qwN1u6kR|hkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_v1_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_v1_0_0/00002.png index fda030d56c962bf18cefd5b175cf5f284825a115..e7482655c77dd6da49ee88968605960861ea4eaf 100644 GIT binary patch delta 751 zcmVP`d_A(#zM96O-!Bpj*k5-8y z#+ZlUrn(dW000000N%-Yp67YSzcT8796#9(lq-~96VopKW;>uFj)%A!j^n81$8nH4 z@scc(R{#kpSq&sKVj(ed)e!?tp5-O$*=r`n9(KM4Z>00000hc3bL3ots> zcKQ5|_~2}0TwAs9RRiFbcSXa}g4*Dc`^$BC5pOZ##i#v1uDh;E)7EcI@m5F)FBDB_ zW{HJMc8!Zj+JD79N^oVl)n-2Mziuns!@JCimb=^_EK);>WWSPIwnuj&56|>1)X=Ay z)ZOaic1|9)zi0)J98jb+p_R1tZ&^TNX0@7=UeN*I=IkV_IXdi6kgitZHAS;-uOnf( zYFc$}58RsL>CT5>V>l~6?H5qS7eE%-?*JhBw_^wd@_+uh^FsbI)KFs#7T^RKWAG?E zypOz;=f|@6OK{^zXUI535srx2u{;+~kld?ET7K;n2<_WuugVlL8*wS_e3uGTac;t7 zJ_ZHI2-{uVUJ=2LA<+B!9+9L_t(|ob8)ia>F1DMQNuy@&1>@Uiy*NqtOEi3`TM8`RF)A z2#^q9k(L4g00000z-Llxt+mF#YRJDG-@7|dPE$U{rd|B(?tqEv4>cN&<9L-H$H8Rc zCA-)h0nDH*8klL+LZ;-DQ4P)N%98s@5dq9t!MQ)Cfm+=1=zpE;-vi2mP4yrY&**#i zo}CUjM^2Z5*P1ScBlEN&lXLwkrF?B{yS*l;`=qsA)7pfM;q zs@8Y;MDyKqJWYEDZm(MO<2U^RneiK7q4wthSbu*Ok?erJilzh`kuJqM z-_Aira8ePKV3h>v>g(94jAhx>KFgl7j;X<<)(S?p`mtj??AfxToDR}+sx~=1w~G4E zaBwhsu74L=LvC1qS}sT?eB8EK#dup%cr0Run^TDonUdnixfC{?rDY@cEtXnWKy8=R za(mcCItQ@ZvG~~9K9F8yE{V6>CFwf8<$!qJ@f2&{!%1xe*EOo#K`i?O;g`#7S~Syn*bepsHO7uv3jJVUeUN zNkTdYM9zrqI}p`RX-Ve*IcFtrVc8(>`X+qwN1u6kR|hkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_v1_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_v1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png index 6c57d4dd591edcb595d432c52143dba70d3e23c6..a1c75c5517bae0139dfadc7e1ddb513613ca0748 100644 GIT binary patch delta 892 zcmV-?1B3jP2a^YoB!5~-L_t(|ob8%Pve+ODM4ex`3HLt|cgezui)f+|0uQCPa$yic z%xxb>k|arzBuSEdiCSx|6@O*qkMhT^u1%@`(27U#v%=`nxVto_I6T&3wo=OVwtcos z&G0+iqK()FaW<4vv_Rk~J|B#-;VhW}+Hh+FO5XA|^PyKt5q|?s%JLLa1Z|q{rOYOuZOFzDc|QUyF!vANs=&z zq|I)&+F+!B{(nU6kVAHMoQt}RJQKTq7%@d&b$yEhw+W7tE|wP52AAAr#CsNZPRlS# zdy&@0!Kt2#ckkM0tHdkbA|u6a4#~#tc+h45i2{;MoUq+R2{+D*XtR?KUU4{siFjF& zP2U5q@mLj6=uk$Sk>BA1n7EVOA7omP;F5)9lA-T5dw*CcM@K=HZzS`jR|j_9BIpd@ z9^0ERM~oNwz9`~0jzh}gTcvpV=(b3-W91KD5Vx(cODl>sPOSa3FCIQyzX6%Ve>>p4 z(cf_$jYeKbU)PNHqJ}#AU;~{XXCExZ6JD~&f+jRwVKtM7RK(}e2)OlN+Op5X znePC+v40*Zg4{~T3CcK7@#_pXb!8TBNo|U#D72!JVG36xjGJ1OG}_?99FN{V&6AvZd}v2&)gaCXWmW+;BoZP)u_SZQT~9Q zaGB4&^2Dg2r$aMwe9;zt66JGe2DtYYu;7q=dw(yz5$>2zE1lvYv3Q6ZI4}4h^KAk? zN$#F&rW;9;Bni&1ZjSjSo@*xa5(;8xRC+olu7s-?6+uBGlUgZaXQ+yhX8IUD1!)?j zo#-%r=#uAZYVRLY?QQEes1WyE(H;(X0Fq~}K91S}X8@ODMTN2}c@p^(bP1eQF={9{ z*mbM)hbT`$#*0{^D3FN@J>u;sKC@wJ=uUAa@HgJTUDs#l&YyEdZja;1{6D6k9v7yD z+WV*GlXx!F4vRyFPF`1_LTNND#QuYLwZelqpK9pMJZ=y81`kn)lO#!!NAm|(QjM3o S_rX5^0000CeD9I&ZR%nouUD8qi7z*`Z{G4 z5#KvG$B`sSk|arzBwwP|T5H808Tq69v8$sg^&hR`QT(hhdJuP)#uP`!TFq8Uxt`MB zcBvVDhg-B!+n~;dQc5cjc*>X$M%i$d%z)N#qXA`4Wt-*DD}SY^fo5f83adh9K#*03 zuy6)2kHN7&W`PE@)uRTkkrB(n4hSDCa-`F~ImdNWrQ5cy_$BCaozC<#Kr%BjzKlG` z`U5iT-XyC|L3F`oiEMBoYwMM#by8F_fK{kR09pl2+_^u0iup^%>TAmPneTuoPm&}_ zlEjZo-Rx$o1b-t1@#mKN*QRq(R}MTAyRI0)LLPN}3jsG6)%P7Kf(DmeXVj~f^skk{ z3%yIL{dDRO>fO5%ZI!tsn`5NdZDHA@ok3bNfJFhxrq0>!qJ$V%^S7pEt5nzcWLcGc z?*pzOSsS|0(HL|_ey;;y;!bwIkYOOfWoyd}uJ<;3SbrtP#e(b1w6_9#ZXJ9Es2<_br!VJ(iN66Qw8X-xB0{V@cO)Qv}KNczXd0y6oHA>0L;##(%WZS)LG!C-~sv9WP`)Ow23E8>U;s zha^do1m{;b$Nc&(HIsP>1+nARosNn7;3~WdC}?C-C`IhJst9T3817S$sv~w22aF#L zy>kP#_l;@mDRmo^hx@LyejM-sWWS~Q=(PjR0I9{Q3T0RFWb!BI5;&_IQp9AQu9q zRt_=t!Ouh0b7AYS=sI-Dx&jqSqiG@bAH=H_9>n=nLvQABd%!n%f;^lgNs>IBKOHiR UUeIgjH~;_u07*qoM6N<$f-*F_VE_OC diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png index 562b8c3a7d73de03a021e86dd7b6a40d2558ecef..ecf2346df930b5f6b40ebfc49af92e28a2869d42 100644 GIT binary patch delta 477 zcmV<30V4kR1NQ@vB!9k1L_t(|obA~`j>8}fKvAZen{fXlahF-NijV=vq&7jB{}x>& zln?`k(v$!I0D#9RrIb?ax0Lc;?Gew?+t8K?YThfN()u+b>YvrdG3T6m&8x4sWg=eZ z*S$tX_XWBmG3Pvrg8fR@=$7&8?)+zf2&kA1;@!Fz(_qYY1Ai^P+g=$xV%BKVd?{)M zh~^r{{8_8A4dODc{rC2aA^qu06Xa( z2U*IOit)R8wSVikI!h1ZBD5RxYg_fvuf=FlM-e0XP#qokOpVR%{7`1ez5C0JW@LnsN^{47N3@?g6z@(*D`?KH`i)gJRw%6ppoND#@9RZ?0kT;O9!NwJ`m@l zb~-aQs|cM{&s&zq)pK~|#hKCdQP@~Us#J|F)BF{eK% z=o!%$|H&wS(cG)Q{OmJHA8#0H`e1>RAkzn-2rmEt00000000000000001)O6QERM# TmN?)=00000NkvXXu0mjfz>elY delta 478 zcmV<40U`eP1NZ}wB!9n2L_t(|obB0Bj)Wi#fMI5`H{t$A;x6;xWKMGARK70056sN-3rI4;l4m^+#OG?n7HAsC(~-M(f*%X#cD>jydO~b+0aO>qOkn z-}Dv@>J6wfG3VTig1daX+(0}6GwxoB7vwDl>M^P(4 zbk{leueDGI*BNe6?bPI$D{26y&y;qi*JE=`eCI_y)s{WICa0ipzw1O^Cx6;)-twNabTcl3=X+|X_o=u*$ab{B-renO`1q%%x;TuT{o7wIH(CMe zG^`8l9liG4?-y+SPy2V+PN-c5;93%}$L2y)>lei86x8G2%k(=k&*r-~y9_`I7z436 zTIU>*e{LjG(1LEAin2W_cH;J@b#+fP!XUi2zY^H|Z&yL0=2rJ5I`gg%?64#sPps+x z6!d`Tiyvf+-)C;8KY_Mdr_a_6HDj>AAjphCD8dT>000000000000000004yf0DNPs UuoA`kCjbBd07*qoM6N<$f-L6l&Hw-a diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_missing_nonwitnessutxo_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_missing_nonwitnessutxo_0_0/00002.png index c6b820aa9ea685e7571ff9c9d6abeec5df7452ef..1e798bb2a48988837e7c091787b148b163276ec9 100644 GIT binary patch delta 403 zcmV;E0c`%Z1GWQ@Eq_~b!ypVmQPSy7*#DB)OF!r^gr~5Pt;F|yVHYrn2F9{;00000 z000000002sF+vE!n@bgJ`nh`m|EA&d-dh;Pb}#J*q$#Bc4(`O8#bv4!%SH2M;MnJlKep&RL)dgsG`+d=O=Oz_G zP>sn`*1)C*?Lr1kg3KDIG8A6z7k%wb{NqU$;BW+shL%@i+naFyicyybIm@DxR410} z*P>~9wP=`Mx_?%Bbuh?Y=G9In<4r!*V%kNW)k3p}`m)!suCqGG>8K97C>JCgw7iej z-LnZfxcq&1`GfODwT5o|cW=Bq{fjZxL$!Ib_0MHHbV`dNP2PvSYm>bzqq?^*Y~H`L zR~x5(Dr%j%J?fgxukgQ%b^qLG{dV$p*uzx*9l`ZI7tdFH+7aInceB?g-P`ZLy}Qfq z1x`=&?+JTzWATiIHv_+yIp zd)o2UixO)ktLl%hp6u7>7x#Bg%Aa8VP@d>3mQgR!>OzO}3E_>|k{<kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_missing_nonwitnessutxo_0_1/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_missing_nonwitnessutxo_0_1/00002.png index 6c57d4dd591edcb595d432c52143dba70d3e23c6..a1c75c5517bae0139dfadc7e1ddb513613ca0748 100644 GIT binary patch delta 892 zcmV-?1B3jP2a^YoB!5~-L_t(|ob8%Pve+ODM4ex`3HLt|cgezui)f+|0uQCPa$yic z%xxb>k|arzBuSEdiCSx|6@O*qkMhT^u1%@`(27U#v%=`nxVto_I6T&3wo=OVwtcos z&G0+iqK()FaW<4vv_Rk~J|B#-;VhW}+Hh+FO5XA|^PyKt5q|?s%JLLa1Z|q{rOYOuZOFzDc|QUyF!vANs=&z zq|I)&+F+!B{(nU6kVAHMoQt}RJQKTq7%@d&b$yEhw+W7tE|wP52AAAr#CsNZPRlS# zdy&@0!Kt2#ckkM0tHdkbA|u6a4#~#tc+h45i2{;MoUq+R2{+D*XtR?KUU4{siFjF& zP2U5q@mLj6=uk$Sk>BA1n7EVOA7omP;F5)9lA-T5dw*CcM@K=HZzS`jR|j_9BIpd@ z9^0ERM~oNwz9`~0jzh}gTcvpV=(b3-W91KD5Vx(cODl>sPOSa3FCIQyzX6%Ve>>p4 z(cf_$jYeKbU)PNHqJ}#AU;~{XXCExZ6JD~&f+jRwVKtM7RK(}e2)OlN+Op5X znePC+v40*Zg4{~T3CcK7@#_pXb!8TBNo|U#D72!JVG36xjGJ1OG}_?99FN{V&6AvZd}v2&)gaCXWmW+;BoZP)u_SZQT~9Q zaGB4&^2Dg2r$aMwe9;zt66JGe2DtYYu;7q=dw(yz5$>2zE1lvYv3Q6ZI4}4h^KAk? zN$#F&rW;9;Bni&1ZjSjSo@*xa5(;8xRC+olu7s-?6+uBGlUgZaXQ+yhX8IUD1!)?j zo#-%r=#uAZYVRLY?QQEes1WyE(H;(X0Fq~}K91S}X8@ODMTN2}c@p^(bP1eQF={9{ z*mbM)hbT`$#*0{^D3FN@J>u;sKC@wJ=uUAa@HgJTUDs#l&YyEdZja;1{6D6k9v7yD z+WV*GlXx!F4vRyFPF`1_LTNND#QuYLwZelqpK9pMJZ=y81`kn)lO#!!NAm|(QjM3o S_rX5^0000CeD9I&ZR%nouUD8qi7z*`Z{G4 z5#KvG$B`sSk|arzBwwP|T5H808Tq69v8$sg^&hR`QT(hhdJuP)#uP`!TFq8Uxt`MB zcBvVDhg-B!+n~;dQc5cjc*>X$M%i$d%z)N#qXA`4Wt-*DD}SY^fo5f83adh9K#*03 zuy6)2kHN7&W`PE@)uRTkkrB(n4hSDCa-`F~ImdNWrQ5cy_$BCaozC<#Kr%BjzKlG` z`U5iT-XyC|L3F`oiEMBoYwMM#by8F_fK{kR09pl2+_^u0iup^%>TAmPneTuoPm&}_ zlEjZo-Rx$o1b-t1@#mKN*QRq(R}MTAyRI0)LLPN}3jsG6)%P7Kf(DmeXVj~f^skk{ z3%yIL{dDRO>fO5%ZI!tsn`5NdZDHA@ok3bNfJFhxrq0>!qJ$V%^S7pEt5nzcWLcGc z?*pzOSsS|0(HL|_ey;;y;!bwIkYOOfWoyd}uJ<;3SbrtP#e(b1w6_9#ZXJ9Es2<_br!VJ(iN66Qw8X-xB0{V@cO)Qv}KNczXd0y6oHA>0L;##(%WZS)LG!C-~sv9WP`)Ow23E8>U;s zha^do1m{;b$Nc&(HIsP>1+nARosNn7;3~WdC}?C-C`IhJst9T3817S$sv~w22aF#L zy>kP#_l;@mDRmo^hx@LyejM-sWWS~Q=(PjR0I9{Q3T0RFWb!BI5;&_IQp9AQu9q zRt_=t!Ouh0b7AYS=sI-Dx&jqSqiG@bAH=H_9>n=nLvQABd%!n%f;^lgNs>IBKOHiR UUeIgjH~;_u07*qoM6N<$f-*F_VE_OC diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_missing_nonwitnessutxo_0_1/00003.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_missing_nonwitnessutxo_0_1/00003.png index 562b8c3a7d73de03a021e86dd7b6a40d2558ecef..ecf2346df930b5f6b40ebfc49af92e28a2869d42 100644 GIT binary patch delta 477 zcmV<30V4kR1NQ@vB!9k1L_t(|obA~`j>8}fKvAZen{fXlahF-NijV=vq&7jB{}x>& zln?`k(v$!I0D#9RrIb?ax0Lc;?Gew?+t8K?YThfN()u+b>YvrdG3T6m&8x4sWg=eZ z*S$tX_XWBmG3Pvrg8fR@=$7&8?)+zf2&kA1;@!Fz(_qYY1Ai^P+g=$xV%BKVd?{)M zh~^r{{8_8A4dODc{rC2aA^qu06Xa( z2U*IOit)R8wSVikI!h1ZBD5RxYg_fvuf=FlM-e0XP#qokOpVR%{7`1ez5C0JW@LnsN^{47N3@?g6z@(*D`?KH`i)gJRw%6ppoND#@9RZ?0kT;O9!NwJ`m@l zb~-aQs|cM{&s&zq)pK~|#hKCdQP@~Us#J|F)BF{eK% z=o!%$|H&wS(cG)Q{OmJHA8#0H`e1>RAkzn-2rmEt00000000000000001)O6QERM# TmN?)=00000NkvXXu0mjfz>elY delta 478 zcmV<40U`eP1NZ}wB!9n2L_t(|obB0Bj)Wi#fMI5`H{t$A;x6;xWKMGARK70056sN-3rI4;l4m^+#OG?n7HAsC(~-M(f*%X#cD>jydO~b+0aO>qOkn z-}Dv@>J6wfG3VTig1daX+(0}6GwxoB7vwDl>M^P(4 zbk{leueDGI*BNe6?bPI$D{26y&y;qi*JE=`eCI_y)s{WICa0ipzw1O^Cx6;)-twNabTcl3=X+|X_o=u*$ab{B-renO`1q%%x;TuT{o7wIH(CMe zG^`8l9liG4?-y+SPy2V+PN-c5;93%}$L2y)>lei86x8G2%k(=k&*r-~y9_`I7z436 zTIU>*e{LjG(1LEAin2W_cH;J@b#+fP!XUi2zY^H|Z&yL0=2rJ5I`gg%?64#sPps+x z6!d`Tiyvf+-)C;8KY_Mdr_a_6HDj>AAjphCD8dT>000000000000000004yf0DNPs UuoA`kCjbBd07*qoM6N<$f-L6l&Hw-a diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_v1_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_v1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_v1_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_v1_0_0/00002.png index 6c57d4dd591edcb595d432c52143dba70d3e23c6..a1c75c5517bae0139dfadc7e1ddb513613ca0748 100644 GIT binary patch delta 892 zcmV-?1B3jP2a^YoB!5~-L_t(|ob8%Pve+ODM4ex`3HLt|cgezui)f+|0uQCPa$yic z%xxb>k|arzBuSEdiCSx|6@O*qkMhT^u1%@`(27U#v%=`nxVto_I6T&3wo=OVwtcos z&G0+iqK()FaW<4vv_Rk~J|B#-;VhW}+Hh+FO5XA|^PyKt5q|?s%JLLa1Z|q{rOYOuZOFzDc|QUyF!vANs=&z zq|I)&+F+!B{(nU6kVAHMoQt}RJQKTq7%@d&b$yEhw+W7tE|wP52AAAr#CsNZPRlS# zdy&@0!Kt2#ckkM0tHdkbA|u6a4#~#tc+h45i2{;MoUq+R2{+D*XtR?KUU4{siFjF& zP2U5q@mLj6=uk$Sk>BA1n7EVOA7omP;F5)9lA-T5dw*CcM@K=HZzS`jR|j_9BIpd@ z9^0ERM~oNwz9`~0jzh}gTcvpV=(b3-W91KD5Vx(cODl>sPOSa3FCIQyzX6%Ve>>p4 z(cf_$jYeKbU)PNHqJ}#AU;~{XXCExZ6JD~&f+jRwVKtM7RK(}e2)OlN+Op5X znePC+v40*Zg4{~T3CcK7@#_pXb!8TBNo|U#D72!JVG36xjGJ1OG}_?99FN{V&6AvZd}v2&)gaCXWmW+;BoZP)u_SZQT~9Q zaGB4&^2Dg2r$aMwe9;zt66JGe2DtYYu;7q=dw(yz5$>2zE1lvYv3Q6ZI4}4h^KAk? zN$#F&rW;9;Bni&1ZjSjSo@*xa5(;8xRC+olu7s-?6+uBGlUgZaXQ+yhX8IUD1!)?j zo#-%r=#uAZYVRLY?QQEes1WyE(H;(X0Fq~}K91S}X8@ODMTN2}c@p^(bP1eQF={9{ z*mbM)hbT`$#*0{^D3FN@J>u;sKC@wJ=uUAa@HgJTUDs#l&YyEdZja;1{6D6k9v7yD z+WV*GlXx!F4vRyFPF`1_LTNND#QuYLwZelqpK9pMJZ=y81`kn)lO#!!NAm|(QjM3o S_rX5^0000CeD9I&ZR%nouUD8qi7z*`Z{G4 z5#KvG$B`sSk|arzBwwP|T5H808Tq69v8$sg^&hR`QT(hhdJuP)#uP`!TFq8Uxt`MB zcBvVDhg-B!+n~;dQc5cjc*>X$M%i$d%z)N#qXA`4Wt-*DD}SY^fo5f83adh9K#*03 zuy6)2kHN7&W`PE@)uRTkkrB(n4hSDCa-`F~ImdNWrQ5cy_$BCaozC<#Kr%BjzKlG` z`U5iT-XyC|L3F`oiEMBoYwMM#by8F_fK{kR09pl2+_^u0iup^%>TAmPneTuoPm&}_ zlEjZo-Rx$o1b-t1@#mKN*QRq(R}MTAyRI0)LLPN}3jsG6)%P7Kf(DmeXVj~f^skk{ z3%yIL{dDRO>fO5%ZI!tsn`5NdZDHA@ok3bNfJFhxrq0>!qJ$V%^S7pEt5nzcWLcGc z?*pzOSsS|0(HL|_ey;;y;!bwIkYOOfWoyd}uJ<;3SbrtP#e(b1w6_9#ZXJ9Es2<_br!VJ(iN66Qw8X-xB0{V@cO)Qv}KNczXd0y6oHA>0L;##(%WZS)LG!C-~sv9WP`)Ow23E8>U;s zha^do1m{;b$Nc&(HIsP>1+nARosNn7;3~WdC}?C-C`IhJst9T3817S$sv~w22aF#L zy>kP#_l;@mDRmo^hx@LyejM-sWWS~Q=(PjR0I9{Q3T0RFWb!BI5;&_IQp9AQu9q zRt_=t!Ouh0b7AYS=sI-Dx&jqSqiG@bAH=H_9>n=nLvQABd%!n%f;^lgNs>IBKOHiR UUeIgjH~;_u07*qoM6N<$f-*F_VE_OC diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_v1_0_0/00003.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_v1_0_0/00003.png index 562b8c3a7d73de03a021e86dd7b6a40d2558ecef..ecf2346df930b5f6b40ebfc49af92e28a2869d42 100644 GIT binary patch delta 477 zcmV<30V4kR1NQ@vB!9k1L_t(|obA~`j>8}fKvAZen{fXlahF-NijV=vq&7jB{}x>& zln?`k(v$!I0D#9RrIb?ax0Lc;?Gew?+t8K?YThfN()u+b>YvrdG3T6m&8x4sWg=eZ z*S$tX_XWBmG3Pvrg8fR@=$7&8?)+zf2&kA1;@!Fz(_qYY1Ai^P+g=$xV%BKVd?{)M zh~^r{{8_8A4dODc{rC2aA^qu06Xa( z2U*IOit)R8wSVikI!h1ZBD5RxYg_fvuf=FlM-e0XP#qokOpVR%{7`1ez5C0JW@LnsN^{47N3@?g6z@(*D`?KH`i)gJRw%6ppoND#@9RZ?0kT;O9!NwJ`m@l zb~-aQs|cM{&s&zq)pK~|#hKCdQP@~Us#J|F)BF{eK% z=o!%$|H&wS(cG)Q{OmJHA8#0H`e1>RAkzn-2rmEt00000000000000001)O6QERM# TmN?)=00000NkvXXu0mjfz>elY delta 478 zcmV<40U`eP1NZ}wB!9n2L_t(|obB0Bj)Wi#fMI5`H{t$A;x6;xWKMGARK70056sN-3rI4;l4m^+#OG?n7HAsC(~-M(f*%X#cD>jydO~b+0aO>qOkn z-}Dv@>J6wfG3VTig1daX+(0}6GwxoB7vwDl>M^P(4 zbk{leueDGI*BNe6?bPI$D{26y&y;qi*JE=`eCI_y)s{WICa0ipzw1O^Cx6;)-twNabTcl3=X+|X_o=u*$ab{B-renO`1q%%x;TuT{o7wIH(CMe zG^`8l9liG4?-y+SPy2V+PN-c5;93%}$L2y)>lei86x8G2%k(=k&*r-~y9_`I7z436 zTIU>*e{LjG(1LEAin2W_cH;J@b#+fP!XUi2zY^H|Z&yL0=2rJ5I`gg%?64#sPps+x z6!d`Tiyvf+-)C;8KY_Mdr_a_6HDj>AAjphCD8dT>000000000000000004yf0DNPs UuoA`kCjbBd07*qoM6N<$f-L6l&Hw-a diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_4to3_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_4to3_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_4to3_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_4to3_0_0/00002.png index 75380d48cf25b3a97c481feebf61f660a84b513a..799eebf325c03dedf2eeef5853b65a1fae4f5c5a 100644 GIT binary patch delta 923 zcmV;M17!TW2eAi`B!75GL_t(|ob8%hcHJ-tMb)g%MDrh#=hBbcdQky~qnGVC?5_k# zfL=)Ax|AeIk|arzBzY6ZaU93N7lHb#{K4j=(%s!aAq1NgR1TPu$0kmDtmL1?NH#wk9sqV90dVjT6bD*2HTGE)%6&SSX zC2ZUQjmPBLAJZTQ)SFR2*UDJSt}~!)I8>{kM1wwQ`m&>I{REt@%bos->AEtrzCax& z{*Vm2H_5IYAOmhAY!(+2ThBV)O;J|}?Vgxd0BJ%BuRNb$#e6*6{Y-g3-{n+Dk|arf z3cr|2-YuTFnSTxBXP9d8h0!!Lz4f|KR4;I+fS$#KS-_7lyc_gh9?1Im@;+=XRB}-+ zNDglEiZNeU+Bv+6!xu8I4WJE?*(A>sZz#+j&HC@{0FYQW|2_os+D?U`w?K2_9+op6 z@prU54+fy4ee$4eA5lRXcHo{t$)|>pb1zDi1?36sI?)eIZujz z@|b{Y;y|*V)W*{s58xgl?;4CzaJ(1ixMsERtc{*e);43Yk$=g8NA1nG(!|EU6Y%2E ze_$TpKA)cE<%@BLI_Ka5fzDHpT4(ljI25Ly6SMi4nCcmvcSv5X4WJ5n)9e>UkFVU|{H~ACJtGfgARGUK6Z_u_k z;o$|-F+JeZf>7sxC(U^?o9wwa7QL0%{vh*R$O%Z2B>A~e--ZIrBngvU8L$#w`0#Jv z-jy8RP@n!oA$SA;$(RXG51E+6!kJ`)2h%*xhRVe|mELnaYrgwnOz@AO5?4?{>dS%a2LJDMmzzx zpF-YAes=XCiQA$aW9WVfUvM!XP3+63l6)M{-gY?_>;Q1E=+Z_ABml;Q-U>|x9^kE6 xjd5PPdV3Uk6>GO$CgW}0ZBuQ@K4-}HYzG8mNF2Vo+002ovPDHLkV1m*@(tQ8` delta 933 zcmV;W16usC2fGK5B!7ZQL_t(|ob8%jcHJNhglSH9!v2@!z4YNGJ}MHU0fg{5~>Ns=ToTlF@J-(8fvY*j^In?VgPN!*|Gw9(@l10^Hl$4J%9CTt!76zZFNcGLRVnW zu0zL&8 z)M54?lIidk*_8#!4Yw(5CKt1}o^^VeqFI4-VWt4mg)F@Ce0~+{myF%ll=rhf08x=7 zNs=TwonUc_ulVkZ71{@{-Xs)Y10hFX|`YUj*#L;|hVFLN`4a%^%46IDen> z|>V}G{^K2r+*vHDWmm=i5TX1)&Rs}j=`mA z3_-gEHSys?*aW1B+Oi92jifmnKoTJn4aOrl-b?4WW~~enyMYE;yIx8o6WK5M;8APy ztu!0s_W-=O_aCU^+X=$cqI@ykuFf&I0H>3447M`Xy`#IQ)*j}3frh54G33sz#)sWF z4W7G9cYpMnj2Z!Yi|bY#6bqTQqk>0oGo7;ozAJETPDIk2H>+aLy?fDHdGiaIe}Wu7sA|B$)sr{T4C57hD`Su*5ex+Y&3-d6u>GOz+BT4i^2iDFh_| z#)V!AO$8nhtyzr;UWa=7F7hg3mtBf+Hy)D%kR(ZxBscK~Hk-XEpF`Uv00000NkvXX Hu0mjfP!z`( diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_4to3_0_0/00003.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_4to3_0_0/00003.png index c2d8654a780149bb739ecc980c06e43e1df01431..3864b4f0429283b45c8cd67f17e721d8fbd64f42 100644 GIT binary patch delta 396 zcmV;70dxMT1EvFzB!6v5L_t(|obB0Lj>8}fKv7!FPT2pF*vov36d{9&Lu^Vj_k2}^ z5My3#ni2p20Pq;4lv0ZQ(xARqJmOj77}`2P;k_dot-BG?{#9)rbIz$3UR~bSiRjLc zdy50z4s>T?&RNTXy`)RKWW3#-{|XQZ6{|t?ty`FsIonONxPP}T(H?P?wrFmOS^*+l zA&H3`hZoYObWSq>mqM32fQv<{9_EjoL zdBG>@)R#oH_J3ZCbQ3!GU@zP-`%y3BV8j4?*wTN*?&!WXTX1hQIRM(LkD!Y-<{$70^Ypul!PnP#}GP?5$ zZ*juxfH@Out)ndXOH89f&eOxiuK<-$wHj34%)&C5vu2{zxqp4h=n{L47R^anD?o+o zocqUGkjZtXTUFaNIbvlEK=@4QXSy7l_r!Nz)Kl%UyI1fQ^od(;1@8p)l|7SdzMF6E zKmL{vM|jdBwz>J9VBY9Px6{6nzRtX4Gln8o(&%!NsNfaykdghQa&sXA5E2Oh007q2 zgfe)+r|QTvT;;@{|X@KKK6vdws7nK@|Cy|8NTn_U@O);C_awW(+Q{kz~do t73l>4000000000000000007eb0VhFbT7-&N`Tzg`00>D%PDHLkV1i6uz)%1H diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_4to3_0_1/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_4to3_0_1/00000.png index b0e1548fa41115c7d06c960e2af409d9c09f2a1c..02aa2d99e3c3a17d379a32839437cafc86717128 100644 GIT binary patch delta 401 zcmV;C0dD@P1FHj&B!6;AL_t(|obB3Ma>F1DKvAdDov{BUv6p@@<7mXggBv3$-1E_) zuBnN5#K=Al00000008XbW!-@La?WQtrDWKW{|MOuGW1f!Ziv?bXY^&bn+HSqv2MUk zD$wEL9#zg+u0P{nLx?&9V5T?BBM$!~?hH_|ju`qP-d)haZGWf}-?0$`0000U=Y7MN zh1rS^HRF{dC=p%*try<#ZU&D4Z zjh{G9{Rf|N&hn$V>wwZY6~w7ro9D!wioQGJB}kn)b#k-pfx8({lV4ev!)NMb0001B zDYz&B_pdtvhg& z3Us)*N0oDy>(BVl5TecinCYG75l{ak?hH_|ju`qP-c``SWq+s>-?0$`0000U=Y7MN zh1rG=b?M_=cU7e}4SVt^`PE|Ng5@R=p%*t)sXDK%dj6! z<2#O1|G}r6v;1oA2B36K1#v3Z<~cE^qVLXl2~tN+9o#H?;BE%gy;Aw`Z|1JZdZqcZDW4QS2G5{sSDW$Ve>dlvan`~$=XE|7%)qR3@TJ<8U u>dBtI>npF;cUgkmVgLXD0002MLVrv5Mhv_a3RD0900{s|MNUMnLSTYrz%AU$L%YUKQdsh?9>dHIJg)D#| zU2h?A2C#_1u|H>lCe-RthoOm{&M*!-A-aNTKzZL82VfJgv`}13Ng`y~m z;;--lma`7>2Y(J{j^;D%*J{pQR+AG7f%nbqaL*9dWTfFO`Oc*AvCmGPJ+h#JUJpgwAkt+=VgwE_}nSGJ+|VHV`pj}M z6p|XD?_vVp0dlu#gNHv>jE%dAVWs*-g2BBwXS`{wu)XZ9FMOp~g_tQiw(S&3mUbns zIshcG4~mf7RjBX@l3aa|icBx6h9XAspQj;ZQn8MM@}%#d{pDGc9o*Af=W8z$)z9D` z{6Re@Y=1k_I`d~KsssiKOo%C2MqWHsqyW9WR~~0m{PGG<@#N zscE!gsH;%*f?deJL#=b7VlA~46yN@s7NqJSmQXP?U3{fQT1Zl6Mpx8OSqXdhkQyoj zof~(ldxkZGSNw*;;@D3UZ(Hokpe>AAmgVnjwtvW6u)>;$->B6YAeRC;eA!EBy9^;2Id2UAM|L#hltnr2i&Nb)}6bb}P( z4`->7ITo7n_Ah^ViO(Tbn`4jYQyGaBp|sGx&wyP_~Uo{cmD>R7J$m{VEJ>8X1Xf$jKm)*{p3W3kf>f?c9Kj!+(ffCe%O(}wQu9bJb zf@ZyT(d>IwPxYM{%u`m3DycF~`Be4Dsv|D;=cUrH>2;u(T854{n^-r&iqJ_n$K5n$ z--T~^cLwCLv*yzD#BF}UYZqeV^cON&AS0@(+4Q4tVSn=r04r}8Ck6oQthbn4bEgK` z*JqZCrI6GJeHQ`v0La~DEFS(?F_w3Mv{L;d!Qft;GhP@gY_IqB7rs`krkGuHY};v+ zUdrmY9srQSF=(dLu0oB^q?3CLN|D`*s-cKc{O4&%nNqCdpgigOXMcItWC!>1*7@2? zp!ym7gMUA$=S(}Gkz#1bl&ri-t%NDD>E%<76dRaT~> zdq@qHfyVN#bkDG6@Q&Z9u(LC~ah7bVUg$^5rW(L8reiP}fX&{oqev6X1qsp{fRx^^ z6Hv!YXtV;@R7qE-)Rr2`wh^iS1-3_3L|omkrh$c#k;pcNO?@bzvyz;Tr0Rb~G$1_y gP17_@^N;uq&8L*qO3J-M00000NkvXXt^-0~g6rnaivR!s diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_4to3_0_1/00003.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_4to3_0_1/00003.png index e09d96c504ac3628513a64e1a1f35b06790e1477..dd04309d22f96f70b64caef01938076722a7cbab 100644 GIT binary patch delta 443 zcmV;s0Yv`S1JwhNB!8SqL_t(|obA|Al7k=&fMIrLZ^HeL#9j8GoemR7j2Oh~|2PPiQJj?DwTW3=DerGgV4`W9Ad$n=QIj3It>hiYEjN$x+ zw`k}Npqq&~XDtf;k}mBh=ikG{uK*EHu^PnKx`j!}*>0f4e}CH&?Gbxvi{_wND?oJD znfqfc)WLOzTU6VX9I>XH0cpaank#85==P&M9Xsvx3Z8&Zzw52wwWqh0J;`P7=9~ME zzvbZ`9`qC2oV_P>4?68Q)iQeE5H{X?#A)9?&gd1qLiWSiUn(~jG65ky0RZ4F_%-yP z`ZMBSBhD5=o_}~l!>=5}7qP2ea!$Ps6+9P^qK-(|&o{RAvAx;CbJ_Ro-9&B+wQ5@9 zp86+SxdJpsIt%SZf@e*%jqIu)Yu0V(uvLLrri delta 445 zcmV;u0Yd)O1J?tPB!8YsL_t(|obA~`a>F1DKvCN1O}PJ&xJwu5WEcryVT5tx|CWTv zSO^@GlmGw#fR9m1DW&*7>hzBqkGNKU47$&v;eD?NTHnTs_@i_lbIz$Xyt-ZYS#di* z;SoEUH_)uaoU@e$e@m0~k@M@};#Yu3s8|i+-kOccsM%(s#ea8oi*<=n)}ooTY6Xbl zI&1%2ggUv-bc=37#Sv@O1cXXqe zfBcb8k8sjgY`FfO(0tHYk5e5)_vyDBjv-Ym$+}!;RPYLU$yoiS^5H@zAY>!}0Q?F5 z89J$cjhGDLjDHYv#Se7)C&%f7*j+zzE-LvjnctN^X7O+F-> zr<)xYKa&sAyQ_}=Z~dNN-t5LKJZb_`^M3cH;As<(ZZkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_taproot_1to2_sighash_default_0_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_taproot_1to2_sighash_default_0_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_taproot_1to2_sighash_default_1_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_taproot_1to2_sighash_default_1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_taproot_1to2_v1_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_taproot_1to2_v1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_tr_script_pk_sighash_all_0_0/00001.png b/tests/snapshots/nanox/test_sign_psbt_tr_script_pk_sighash_all_0_0/00001.png index 7fced877156fe169e24050b375b4a0fd4c8d17dc..debbaafc6933e147f678febce60efaef3be1b076 100644 GIT binary patch delta 702 zcmV;v0zv)N1=aD13?t`U!{kww=+B*Bb>nZ2Yl(O%8x;PV4 z3cXA7Q@dGa(R7xR7f~Fh=Gt(Z0ofSj?Q){0@Onf;^s&=*s(($%EZWU-@*>n>i-(tR zo&lMQ+*f1D{gGATYV(zz#mhtI4wyU^Uz%zeL1V%v1ks?G1=cKQTgpI6&Un4~J->oz zIL;D}KlGH1J+LJl(F(nCmP$=N#Q^{S0036u%d4WGg<`WO%?^aF!^7$MnJn5`?mOLW z2ApKW$D)I7?|%zv{!`B*)}vHjHAhuB`e;-o-6mVE|5F-(qNJrKUMf{`prJO)Mag;t zvHJl_1cb3phHuD3Xz0Eu!NhCVMWM%z*t&EG^mzxke}pMJFrp!GM^H@M3?sBu(3n9l z+d!pxI|PcEV-ZDpnfuoKqBkb}w0aiV=j<=t2IeX=V1FY!FcChF>;q72YV<(|DvgXj z2&JWYJ9mlY;7~U@n696S&_9hZV{TGk35)6=O%YE!@t=16vg!%1nI8!ii;Mnq>-wk? zt>YWxvmRq@_p*|UX>2y~_W^kw_}@F3*K;_E5lz2<3rGg k^SOT?V2N4)002NBKP$ZK_XWKD3jhEB07*qoM6N<$f_v6YN&o-= delta 701 zcmV;u0z&=P1=R(RB!8SqL_t(|ob8-jnu8z=g`Ix06ZgL)_c9O8FewQkV#39q|H)D$ z;TGXwyKMjf00000tj=*9$8n7IVkKUVWu>O?+y_hd`gaE#v~~7<*Hg}qDP`aHba5u8 z6#6aAPwi%zMblYMev9HTHP?pQ49LbHZ1dR!w5JZD!7Fe^KZ7BmOIpg)@_gn?h zaGWI`f9NS2tFR>;*+(=reYIZHVE_OC003~4FRy}vHj2%jG&>Nw4-cp3GFh~>+&bND z2ApKW$D)I7?|&O<{!z~(mZKD2HAhuBS~aSYZj)`-|0xYXQPR>AFWpsgprJI&Mag;t zvF8Cx1cb3ph9Ag8Xz0Eu!Nlv-MWM%u*t&EG^mzxkFT#`)7}1b;A}A(Wye-{m%%I=f zK*iw>fnw%ZL{T2*z9qlt7n3fno<+8t{iWN$TxAAqu*KqOC!vfo78v0qB=-Z#J8RJN4tJm^@Nvf*_|1s*{wFJM0u58 zyKUkcgiO24sTW97u1c7`HPUNg7i&3#UrjXT=YzT-^vxM9Ltf5pxJ7Rr9%tI-^@P%_ z=c|dK$bUQd_itBJQygYMdI(pgN9FcQSPY4sVXNL|Sv7_@{SugnIIsmKf&@zd z002|)n0@av5!-r|4jB1fkSHsr6jATAD6-tj9S!x#=v$|ox}&>>8pL2ND75CHhB{kl z8X1C0|IOf7zKez$%6K(Y7r#OapFu;N=pk$rQ#MOtq~!kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_0_0/00001.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_0_0/00001.png index 2b51f30cfe212df5691953efe741325df2f02f56..61f34db33cfd1a4ec7ac68277a6a3bb82f0406cd 100644 GIT binary patch delta 470 zcmV;{0V)3I1MmZoB!9O_L_t(|obB6Pj)Wi(Mp1g=PTc>J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_0_1/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_0_2/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_0_2/00000.png index b0e1548fa41115c7d06c960e2af409d9c09f2a1c..02aa2d99e3c3a17d379a32839437cafc86717128 100644 GIT binary patch delta 401 zcmV;C0dD@P1FHj&B!6;AL_t(|obB3Ma>F1DKvAdDov{BUv6p@@<7mXggBv3$-1E_) zuBnN5#K=Al00000008XbW!-@La?WQtrDWKW{|MOuGW1f!Ziv?bXY^&bn+HSqv2MUk zD$wEL9#zg+u0P{nLx?&9V5T?BBM$!~?hH_|ju`qP-d)haZGWf}-?0$`0000U=Y7MN zh1rS^HRF{dC=p%*try<#ZU&D4Z zjh{G9{Rf|N&hn$V>wwZY6~w7ro9D!wioQGJB}kn)b#k-pfx8({lV4ev!)NMb0001B zDYz&B_pdtvhg& z3Us)*N0oDy>(BVl5TecinCYG75l{ak?hH_|ju`qP-c``SWq+s>-?0$`0000U=Y7MN zh1rG=b?M_=cU7e}4SVt^`PE|Ng5@R=p%*t)sXDK%dj6! z<2#O1|G}r6v;1oA2B36K1#v3Z<~cE^qVLXl2~tN+9o#H?;BE%gy;Aw`Z|1JZdZqcZDW4QS2G5{sSDW$Ve>dlvan`~$=XE|7%)qR3@TJ<8U u>dBtI>npF;cUgkmVgLXD0002MLVrv5Mhv_a3RD0900{s|MNUMnLSTYXDBg)^P*#QiVHz4RfiV-fI(U~X^u9`0lk zM1ub(_qviKNs=T4J0r&kwlXijm)T(f4Sl=ig0 z)=Ta1>F!a7eFt_llv1Qb;CE~>C}rIV839sv>k~?zj_*8ny?;^)n`lyYyhExO4G_kv zT?iZjBx11d+dT9Mm0DC`sb}~SwFX=Pi)!h(W=Y?y`qUEMVt*nI-GYnsDORB90q${(B7|}QI*bT%$LCxN>XS=OH0)`sFGZfR`Xzf> zmQK!iY-3ct!m8BBUf@1;dn3{aP%37xm7C*ld#X=3E-|nMh9b(f#Odz=OX$5aNEIO8 zA)*OXLtlqBupHMaFQ3nkfV;;vg*l>Y6Pa4~4-T>=pMMIp0VH4gBFw^?fn}QwnGKNn zVW|qR=i)xcHJSL)JUDLAl-+75FSX4_lJL<#NU{3>WQcq>KxY3W{4{l7en@V_RA(C; zV3Oo)gHU$UyHj4;5;XR!*e_0^+OJ}2yl@Z;8XS&`zgL8cCg`37v;kNtv0e9%6a{hV zh%|L_aev2A5+O+?N#9iL9OKcGz}|PjrVAovl_|)kJA%UG)IK5xmMAR<>;i1Rjs`sR zoH-lK)ljqSXa1MqD&`1vpW~F`TgAl_PnlZjnf!N z|Gmekv_F;tn_8|0`3KN*6k3aW5yHRtBKFE;1Ain*k|Z2U`$)5gt2^KUHoOAMM2e`tbr1G`QS~{2h<&$dJay#{rlYa%pGPNC z5N9H5JScsXAKIM^T%UkXo3f(?H)bTu;bh#tR# zUYs^L-dU;70!-k-2U+k~C;$Ke07*qoM6N<$ Eg2w}<)c^nh delta 875 zcmV-x1C;!Q2Z9HXB!5XsL_t(|ob8-ZuH_&IhMURk#QiVHz05=B8V3P?5ZaS7d=EEG zi$D>ra?HK1q9}@@D2k%^CVKC^cl?neALWm3ZobohkeWyFD?{luxtkhOoHf?0SZi%O zov-y)C;SfAsKdSkI~rPRQXudz zq9_U%rUGY(Ie$|X6HyrET&7OZfKm?#_hT(WC>Nl@3@1-??n@DKaLJB_-EGaS$Wyj{ z$?le=oipy+>eXCfRV=a>xK3T(i8KNf!|b(kbNxG>>Jv_g53GQriE=IR^zQ*C^sG#( z3XtC+vdO9ieH3G01%9idbiO|V?u@(BZN82*F|N1z!GA$!(y2f@K+>gugjrZIuXlh|}s;1W$)t)}u(%X}mVzvc&3?0x_;ME-U_MgK|oY3hObp|}x4 zU48HXn;=&oq;eYGllIb*U~q2YygBje+{9Mcun|id9DyJIC=ZpIV0aMF4q!`(<9dFi zR1i&Dq<^iFi`$M84@oFV_)I5CB@>b}`m5RS)di8Z$`s_QJA#GDt$cUo$HhmYvN`<0;0-(dH9N*CYih-ynH%Z`7E>hb?fub1YiU#6_o}PU|kukZq?GjSA@UzxE zq@LKm!z@OcfawFuBdRW8(qr9|gdMNIvMELMf9oFXxv2hLfrx##tv}szz;qRkJv_RZ zf@F}g#*3wo_QSaIVmA2Le*+ru9|5*~aDD*vZlyPLN8jY06a*jf)ljQv?h(EI4tjC5 z$@PxOA|fo!%%F*H=B>FAr;2eeQyowgMNt$l@dxIlz|MU8>zn`p002ovPDHLkV1i&} BtkM7g diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_0_2/00003.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_0_2/00003.png index 0da504c40e39d62c7a04781782b22bbef2f85b48..062405d8cbdf2b70c5cc134a2368c2c49c851ede 100644 GIT binary patch delta 496 zcmVEos?fnBzHId{MwcfAyBYr4MKGPuU8`QiFw zulaO@i++5o8?On?jjp$y_D1xHO?dFnN9^{xxj|I0a#;_fzf@k%r2||d0RZ4C`h0Qf zsBZSZNAIMw7k|~^<1gHM?H#aks(RvM_?BEp9YySBzx&5SxHpFet>~F&X=p0`6_*}I zr`EAVT_UbFKT}V9i#F?T7S=~8v#p#HJ_E*j$3*qjy&Lwz{r7fh+^JKhPLo_*+5tK* zBDsfje^^@i&u*RpX}%BYNAwhVR`!$L1MYo+I+b;1r)kz`eUEWvZ*Doh4$>R386@KxWGY@>4Q+D7XSbN m0000000000000002=fQyyW01*J%0000RAdMV*(~N%y~`?qxnYc_E?{7232p=hLF% z6|_%0CfwZwFxa`yX^!)LU zJni8kKe5BvXF~I$>s_aM5N%_(ocd5iCiSK>yaF#FkBsb>%F7AafDlgr006E+*B6IM zb))|ty-H`#D}THDJ1<`U@>YbfyG)cul1M2>OGe-Qb_n+()R;wQo@XMz^NU)WC9F8b9Hg$-hYElT7Zh+RsU&8#_ zpLUs6{}yh}fHJ-ZvWrfUXQ^NG9dPdgq?A(Gp)*?BIA~Ay=9Lr6iM$z?{_VfgD-K*B z$VYy7R`NcS>d5^+f-=;`wpy diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_1_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_1_0/00000.png index 311e4672e3bbe08e11e17c17ac61df44067da8c2..4597e471d1700326cdfcad462519cef8e9c0cab6 100644 GIT binary patch delta 393 zcmV;40e1eY1FHj&EPvWjZo?o9fMGW6CcgiXe3v~SRTdB;vLv?0|2^li9@8&ml9ZooxNpwq=YD^<1g z&-`r)S;TDLJR-^0DpK~^aZ0Ds}&z=((OVw zwMlI{w&YRvr{%~6+0$Z}1?rR1!|lWJ`$Qz@@EXSGmO}sP$Tr}|u^mJ6JB~}=5Ryhclmonmw0x9+o2rcLwzACF^wfEbR;c006wot{aj*(e;vR zp*gBGS+9BZfq&a`LH%;cF4JqddGcrYAkb;8{)k7PZnSVa%_7V*0000BFL%1!|Mh-R<4-^K#BkhgUa7mlWDZL%IRKhVAH@UvXS|2cJYl ze>Hadv3;jX;OB+D{z4y3xYzFpDtXxKykC+%}I4chTYBH#QPtqciA6JjNwaEtaj#o{?%Hb zpjenpN&o-=0001dC)agd*X6%u%zqufyA4Ril^^5NF8+2Kpd!XY+zmPBdpze%=J-c; zv3Um&hmzeuTq6z=A!Ux}X!0x{d7dM70CARc?T<;QJ+4LcNq_dA0cpXZnk!Pv>3h$f zodGCsUZ;XPr}N34b!yBxGykNNem3g1bAotIYR9RzqR&5s0RR9106-tjdevxfih~7h z#3_o4^~}+#X!1tkRokjogjP>!7+?C6HrOun+v$-ufE57Zi@IO^w#_r^)BxZ zqkY;g($#nOOJZ;WACiS$O2f&B!BU=Zuh>o?BQrAjrN@i`MYiSq(y8J(w5HHx0GvX^ z{!Evy+QoJgX~z5BUeF~q|7zWyT0R%_Jk)NV!9Tt#Mm8QkHpmxDM>TpHTW zH5Qb;1AqM5Jt~O&flE=o#%wp#&@|I%)V5I>7kjSUfaaX-xqCJMP0tSW;7a70Da#|u z6Q^FW24f4ZLwfV*w-ZQmWDh>l%yrH|;}r}`{Feh!oZ10)57Kj%iu*%*kgVl;b=z-l z?}OMZ)cXZ7D1CBH?}LFpT9@?gjiPbHA2bZsra9CD=%@pd`?roj0$sm4mf=+e00000 m000000000000000AHYAp*j2v4I}w%u0000`S1=IzQB!8PpL_t(|ob8)Qj>I4gMd?=GB=(16<5_n7iRPj;sAR4lyR) zvWv|-KsZ$F2H_gBQ3%OnOh=1%b<6!cVh0Fk1=oI`gwo?)M1SvO{~3@L9I8h_syTh{ z*|ReMdFEv*xN^E499gGe%ro;(O6g~#Zk!X$bJ9Cby%qiZLzoak2qA>DQN6E%0;k!S z@meBsw9LpD?+PuZv*OCOsubbfr#!%y{)hqCWpN`T()vIF5WXlcu3~_$nwdAF>Wgt> zyx!b}Yj#bl^?zVJLE)b{%gD?p=57^v1IY1SG`q|c6tpBb1u(utT4aub`6=j%KVC9% zQKF?!4wk>SCc2~;r}tnafzEZVr$TG_%yP8$`1m0<9-)a9&}%y5Cdm{uaT(@Z)N$ly zV@grUNf&VyVwib!Py7tiLMrZE@tL)bCTsEOIvpV2?SFca_dD)H&k2Ct`y%gm<9*jI z($zfR8)EPfJ|PRemx_}agQeWzUbCDaTDk@5$A}Fbim=)GF{t8JyrR%Z0D=Ec$Z^DOkbX5G26%<^$bg##}N{li=x-sbhz z6y5=z1b=V;Y5BTqixYjcF6rZq0(it9G(7G|sk>>r2Q?(!)Ke!g;}R#B!6#7L_t(|obB3Mj)O1^Kv6pCPO|?cc`x&UR9Vggg#xyldp<@P zL?Cq_5Ql98000000Kh6<-VHcUL_XzGiepQ@k+K7H=(UX9kgo$i(bwT_ZcO3Ny8$Pe zK&Oj)RwAOupYgvbWW596rgxcVy!^MkcYuj?#?bHby#;N&hJOa}8xt`A007{2(I!^v&j0`b delta 399 zcmV;A0dW4P1E~X$B!6&8L_t(|obB3Mj)O1^Kv6oHon-$@@?Pcxsj{306B@8x?)j)v z1T=LZAr9LH000000Dz}>c~{^(5qXzODULPyM9K!xq1Q4tL%s%hM_-4#xiN(w?+Tn` z0-Y}IS&4}5f5u-^$a)9BP46<#c=>O6?*J3)jG^D&+nHG6py_KrdlAcsewT1phgz7tN=P tw97@yD%PDHLkV1fj4w#oni diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_2_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_2_0/00002.png index dd90178a3abae7252f095f924cd857191d1dfad7..ef5789d72f0ab1a0bf58ff5892201616d3a9226d 100644 GIT binary patch delta 728 zcmV;}0w?|N1@HxsB!9O_L_t(|ob8)ia^xTkMVZv>#QR^8_mU5%D54jVEgl`;^VM<7 zLP#J$O-ca(00000;GLZ3d7h{LD?|R{_*!j1sjmDpJ`M4IwE-$(JjB^>9LM$iI1VD? zf3k|jGk`dh%m(5b@gY%CWkg4lclnd~Y%v3fvz%l9o`%-rT7N`mvVILH0~Xbzq4b=- zcI{aifZFpm6=6ra@PR;{hy}QAu*oZ8olg8f z9`aroU3j90JAW{Y<`mI`U9n=iN$aQQ+w@nuJ-XoyjTzO@aXG3&eiDc>!9tBmpXRUdMvnSP)YzoO?RtrDSB?uISG^FMq3G}OF8+o z${R->O~2M+@tt>w0XJl{(=|7epUFw@xI?=3TefQB&R;l;YV#=6GK}%W(5bcV?3Xb$ zjd`>FZhz>LBZ%ipsI!R?Cm~P1T6{P3x*wRBSowuRr)N{lxTa&DQ(or6%zLC#eCBQ}NP~u!qRZ@JhWc-LU zh`naOIMSF1DMQNrx@&1?Oz4XHwh6=sF;*t2CuM}e; zBoH9elmGw#0001ZCg*vc=jnf>)c-hMs})GulwV`hCVp2dAj0~CoejrvT;<1ckUIX7 zRV%=Vd6kVtQTKGftH{d&ZxX($B)S^_ak}lhSf3jp+RsVE_OC005xTl&y?yS7~}e zE3HC^s9Tcj91B}voCB29LZIWr)3Hqg#glM0ZYhp*n?1tR1A&yV2{_Z)uiouzwlJD69p|YDqPd)KAaT@K?+pby!1UMmBU@jLMKt0Yv*vq1_kblyw>pO!;*yzA2apbwX37IZ&-$|C$TPU=IwJy0-3zl{ zPB~7MwED53aA9DTh*If}9P;j~eDGP5_d_8;;_U!fe}5)?px!WId@G`<;e!bnMurcD z(q>+%_O1Lziyr2V){~I&XscvR%))_ql<3nb!~soBo7uPfLi#XH!sNJ7W&-k3PX5gG zl_QTNUurS=&O1bbjym;;n$@sAkdv;})-aVfbd|=PKXKS9%_C5XFiMFc)6`Julrk^% zd9(g*=zpCfi04YEvx)GNkTYH_z8iYo4-Aa0^@T&HW$&wT&Bd}U&+W%8F6YMjprmPB z`_;H=c9^>+AOz(_Sg*!*k1TQQ(rpUVuR5FSd=#Ed2MF77O1lq#6Bk>ApeM6_7qlDB zu}`9Zz^)$v0H(9@UzDaXXx|B%*>GdN*EUp7?NE{I8~JSt0WL~|661OjlkAHr;v>=^ z_L>3X2+#UO@e~Ju20Q^>k4s62{u|DKN2DUK4Fv!I0002sAAc++gZM&ZE06#H002ov JPDHLkV1nYuVa)&l diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_3_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_0_3_0/00000.png index e1fa952d66f880e523c9ad565a12d49c77bdd726..5f0e1a383e40c7fba09ba94c6254684aa7070d6b 100644 GIT binary patch delta 402 zcmV;D0d4-S1FQp(B!6>BL_t(|obB3Mj)O1^KvAZeon-$@@?QGED6*Uo6kfK6dp@cZ zk>ci6V!A8<000000Cv3*UpII6U&!05b@WF9e>C6O23O2Hp8~>Xxx|n>Mb3xj`UJWEqF)t$7c!J%2^JQ$>y$cs#bgT wwr-p*i7U>!aiO;?L1EDW000000N_DiJJUmWU3#Ua01E&B07*qoM6N<$g2oEDkpKVy delta 404 zcmV;F0c-xO1Fi#*B!6{DL_t(|obB6Na)U4oKvA0MPQ3pmX)pPprcp?^Vq$3_eQ006jM^bMmZ zvlreJ(&a*jYD$}qk=#muv>de{JuSLbptdO8J>G49UMVH$@apF1l1BT}kq+S3F^;bB z6UV7nh)G2BM+?^hYj7rsQ?<6pg*lV`aK=lJIdkgdZaac-GoYpaWbF>0sgnT!0N^F@ zw<6A{8zR11v47*(zG>^KLCMIA+YD&8OM08Ww$1SDj@I3)+IKXs`NV<0TSXWjoVu!g z-)`;NYbqotMchiy9+v=eJdiohJfd-5`m3jOz&g@PDYfAp(I1~BXsc#9C?=b`#{XQk ymF4gF=Q0Oz){P52WeEz44gdfE0000V^aec+LwG0zj}7Yp0000J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_1_0_1/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_1_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_1_0_2/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_1_0_2/00000.png index b0e1548fa41115c7d06c960e2af409d9c09f2a1c..02aa2d99e3c3a17d379a32839437cafc86717128 100644 GIT binary patch delta 401 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 JPDHLkV1nYuVa)&l diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_1_2_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_1_2_0/00000.png index 2ed1dca4462885177fde18bdc869cd18cac94b65..8c48ca209d6aab766f08131aaeffc6d8a2e6c25e 100644 GIT binary patch delta 398 zcmV;90dfAR1E>R#B!6#7L_t(|obB3Mj)O1^Kv6pCPO|?cc`x&UR9Vggg#xyldp<@P zL?Cq_5Ql98000000Kh6<-VHcUL_XzGiepQ@k+K7H=(UX9kgo$i(bwT_ZcO3Ny8$Pe zK&Oj)RwAOupYgvbWW596rgxcVy!^MkcYuj?#?bHby#;N&hJOa}8xt`A007{2(I!^v&j0`b delta 399 zcmV;A0dW4P1E~X$B!6&8L_t(|obB3Mj)O1^Kv6oHon-$@@?Pcxsj{306B@8x?)j)v z1T=LZAr9LH000000Dz}>c~{^(5qXzODULPyM9K!xq1Q4tL%s%hM_-4#xiN(w?+Tn` z0-Y}IS&4}5f5u-^$a)9BP46<#c=>O6?*J3)jG^D&+nHG6py_KrdlAcsewT1phgz7tN=P tw97@yD%PDHLkV1fj4w#oni diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_2_0_0/00001.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_2_0_0/00001.png index 2b51f30cfe212df5691953efe741325df2f02f56..61f34db33cfd1a4ec7ac68277a6a3bb82f0406cd 100644 GIT binary patch delta 470 zcmV;{0V)3I1MmZoB!9O_L_t(|obB6Pj)Wi(Mp1g=PTc>J*vmYS7y<|grSh43p8N%- zN|2^|oC5#=0000$nfKm%KX!Iae{VNnL@~;8p%26ouCj7?cki5^y%- z)Xjld0)pb4M|UCw0034XH;vQM2=9FKePpUB9Tg>&&XiUu+}vs5CbcGUnJ=(e&K<$J zdl-nz{~d=+KFGx7B->%5|7>1(+`@2sd|7@r-)%M{xhuZd_G_O)!0+n;`9}S0&r0Xn z#lyAN>upwdNq=0(c5H9Fy^`YnsQY2-;4*&g&W_+;!vV4K_)}>8({p*xH|4$n;S=z%s@{ms zoVqy>OF&Ru^XM*w006)WPN{+)pIMcY~Dj|q_7``4C%dh4iiwzZziyh7z8deDS)DbXt(CApLa8J{h zCp*gziz_+KqknKiS*7=^v)F2*L(4L}LF2F-@inU)Bx5!{*(krbNi$En8D|)aWR8AV zXx;GHW+Ly*Q7kv3;l@sKaw$J!H7@VYjXnKW^}yhec(h2q57@~=Q&8-&dw-L;0sw#| zNUSVxS>msw8=IQ($^K&b2IthRO?mzMls*3&^J8rf+ehSw*xgW?zeF4M!VfWX1N%km z%siWn0QdIh>#%i4Kx6YVxqmy~XkOL~00000003ZT|0YLsifqpX#Q*>R07*qoM6N<$ Eg0t4#jsO4v diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_2_0_1/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_2_0_1/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_2_0_2/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_2_0_2/00000.png index b0e1548fa41115c7d06c960e2af409d9c09f2a1c..02aa2d99e3c3a17d379a32839437cafc86717128 100644 GIT binary patch delta 401 zcmV;C0dD@P1FHj&B!6;AL_t(|obB3Ma>F1DKvAdDov{BUv6p@@<7mXggBv3$-1E_) zuBnN5#K=Al00000008XbW!-@La?WQtrDWKW{|MOuGW1f!Ziv?bXY^&bn+HSqv2MUk zD$wEL9#zg+u0P{nLx?&9V5T?BBM$!~?hH_|ju`qP-d)haZGWf}-?0$`0000U=Y7MN zh1rS^HRF{dC=p%*try<#ZU&D4Z zjh{G9{Rf|N&hn$V>wwZY6~w7ro9D!wioQGJB}kn)b#k-pfx8({lV4ev!)NMb0001B zDYz&B_pdtvhg& z3Us)*N0oDy>(BVl5TecinCYG75l{ak?hH_|ju`qP-c``SWq+s>-?0$`0000U=Y7MN zh1rG=b?M_=cU7e}4SVt^`PE|Ng5@R=p%*t)sXDK%dj6! z<2#O1|G}r6v;1oA2B36K1#v3Z<~cE^qVLXl2~tN+9o#H?;BE%gy;Aw`Z|1JZdZqcZDW4QS2G5{sSDW$Ve>dlvan`~$=XE|7%)qR3@TJ<8U u>dBtI>npF;cUgkmVgLXD0002MLVrv5Mhv_a3RD0900{s|MNUMnLSTYXDBg)^P*#QiVHz4RfiV-fI(U~X^u9`0lk zM1ub(_qviKNs=T4J0r&kwlXijm)T(f4Sl=ig0 z)=Ta1>F!a7eFt_llv1Qb;CE~>C}rIV839sv>k~?zj_*8ny?;^)n`lyYyhExO4G_kv zT?iZjBx11d+dT9Mm0DC`sb}~SwFX=Pi)!h(W=Y?y`qUEMVt*nI-GYnsDORB90q${(B7|}QI*bT%$LCxN>XS=OH0)`sFGZfR`Xzf> zmQK!iY-3ct!m8BBUf@1;dn3{aP%37xm7C*ld#X=3E-|nMh9b(f#Odz=OX$5aNEIO8 zA)*OXLtlqBupHMaFQ3nkfV;;vg*l>Y6Pa4~4-T>=pMMIp0VH4gBFw^?fn}QwnGKNn zVW|qR=i)xcHJSL)JUDLAl-+75FSX4_lJL<#NU{3>WQcq>KxY3W{4{l7en@V_RA(C; zV3Oo)gHU$UyHj4;5;XR!*e_0^+OJ}2yl@Z;8XS&`zgL8cCg`37v;kNtv0e9%6a{hV zh%|L_aev2A5+O+?N#9iL9OKcGz}|PjrVAovl_|)kJA%UG)IK5xmMAR<>;i1Rjs`sR zoH-lK)ljqSXa1MqD&`1vpW~F`TgAl_PnlZjnf!N z|Gmekv_F;tn_8|0`3KN*6k3aW5yHRtBKFE;1Ain*k|Z2U`$)5gt2^KUHoOAMM2e`tbr1G`QS~{2h<&$dJay#{rlYa%pGPNC z5N9H5JScsXAKIM^T%UkXo3f(?H)bTu;bh#tR# zUYs^L-dU;70!-k-2U+k~C;$Ke07*qoM6N<$ Eg2w}<)c^nh delta 875 zcmV-x1C;!Q2Z9HXB!5XsL_t(|ob8-ZuH_&IhMURk#QiVHz05=B8V3P?5ZaS7d=EEG zi$D>ra?HK1q9}@@D2k%^CVKC^cl?neALWm3ZobohkeWyFD?{luxtkhOoHf?0SZi%O zov-y)C;SfAsKdSkI~rPRQXudz zq9_U%rUGY(Ie$|X6HyrET&7OZfKm?#_hT(WC>Nl@3@1-??n@DKaLJB_-EGaS$Wyj{ z$?le=oipy+>eXCfRV=a>xK3T(i8KNf!|b(kbNxG>>Jv_g53GQriE=IR^zQ*C^sG#( z3XtC+vdO9ieH3G01%9idbiO|V?u@(BZN82*F|N1z!GA$!(y2f@K+>gugjrZIuXlh|}s;1W$)t)}u(%X}mVzvc&3?0x_;ME-U_MgK|oY3hObp|}x4 zU48HXn;=&oq;eYGllIb*U~q2YygBje+{9Mcun|id9DyJIC=ZpIV0aMF4q!`(<9dFi zR1i&Dq<^iFi`$M84@oFV_)I5CB@>b}`m5RS)di8Z$`s_QJA#GDt$cUo$HhmYvN`<0;0-(dH9N*CYih-ynH%Z`7E>hb?fub1YiU#6_o}PU|kukZq?GjSA@UzxE zq@LKm!z@OcfawFuBdRW8(qr9|gdMNIvMELMf9oFXxv2hLfrx##tv}szz;qRkJv_RZ zf@F}g#*3wo_QSaIVmA2Le*+ru9|5*~aDD*vZlyPLN8jY06a*jf)ljQv?h(EI4tjC5 z$@PxOA|fo!%%F*H=B>FAr;2eeQyowgMNt$l@dxIlz|MU8>zn`p002ovPDHLkV1i&} BtkM7g diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_2_0_2/00003.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_2_0_2/00003.png index 0da504c40e39d62c7a04781782b22bbef2f85b48..062405d8cbdf2b70c5cc134a2368c2c49c851ede 100644 GIT binary patch delta 496 zcmVEos?fnBzHId{MwcfAyBYr4MKGPuU8`QiFw zulaO@i++5o8?On?jjp$y_D1xHO?dFnN9^{xxj|I0a#;_fzf@k%r2||d0RZ4C`h0Qf zsBZSZNAIMw7k|~^<1gHM?H#aks(RvM_?BEp9YySBzx&5SxHpFet>~F&X=p0`6_*}I zr`EAVT_UbFKT}V9i#F?T7S=~8v#p#HJ_E*j$3*qjy&Lwz{r7fh+^JKhPLo_*+5tK* zBDsfje^^@i&u*RpX}%BYNAwhVR`!$L1MYo+I+b;1r)kz`eUEWvZ*Doh4$>R386@KxWGY@>4Q+D7XSbN m0000000000000002=fQyyW01*J%0000RAdMV*(~N%y~`?qxnYc_E?{7232p=hLF% z6|_%0CfwZwFxa`yX^!)LU zJni8kKe5BvXF~I$>s_aM5N%_(ocd5iCiSK>yaF#FkBsb>%F7AafDlgr006E+*B6IM zb))|ty-H`#D}THDJ1<`U@>YbfyG)cul1M2>OGe-Qb_n+()R;wQo@XMz^NU)WC9F8b9Hg$-hYElT7Zh+RsU&8#_ zpLUs6{}yh}fHJ-ZvWrfUXQ^NG9dPdgq?A(Gp)*?BIA~Ay=9Lr6iM$z?{_VfgD-K*B z$VYy7R`NcS>d5^+f-=;`wpy diff --git a/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_2_1_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_external_inputs_2_1_0/00000.png index 311e4672e3bbe08e11e17c17ac61df44067da8c2..4597e471d1700326cdfcad462519cef8e9c0cab6 100644 GIT binary patch delta 393 zcmV;40e1eY1FHj&EPvWjZo?o9fMGW6CcgiXe3v~SRTdB;vLv?0|2^li9@8&ml9ZooxNpwq=YD^<1g z&-`r)S;TDLJR-^0DpK~^aZ0Ds}&z=((OVw zwMlI{w&YRvr{%~6+0$Z}1?rR1!|lWJ`$Qz@@EXSGmO}sP$Tr}|u^mJ6JB~}=5Ryhclmonmw0x9+o2rcLwzACF^wfEbR;c006wot{aj*(e;vR zp*gBGS+9BZfq&a`LH%;cF4JqddGcrYAkb;8{)k7PZnSVa%_7V*0000BFL%1!|Mh-R<4-^K#BkhgUa7mlWDZL%IRKhVAH@UvXS|2cJYl ze>Hadv3;jX;OB+D{z4y3xYzFpDtXxKykC+%}I4chTYBH#QPtqciA6JjNwaEtaj#o{?%Hb zpjenpN&o-=0001dC)agd*X6%u%zqufyA4Ril^^5NF8+2Kpd!XY+zmPBdpze%=J-c; zv3Um&hmzeuTq6z=A!Ux}X!0x{d7dM70CARc?T<;QJ+4LcNq_dA0cpXZnk!Pv>3h$f zodGCsUZ;XPr}N34b!yBxGykNNem3g1bAotIYR9RzqR&5s0RR9106-tjdevxfih~7h z#3_o4^~}+#X!1tkRokjogjP>!7+?C6HrOun+v$-ufE57Zi@IO^w#_r^)BxZ zqkY;g($#nOOJZ;WACiS$O2f&B!BU=Zuh>o?BQrAjrN@i`MYiSq(y8J(w5HHx0GvX^ z{!Evy+QoJgX~z5BUeF~q|7zWyT0R%_Jk)NV!9Tt#Mm8QkHpmxDM>TpHTW zH5Qb;1AqM5Jt~O&flE=o#%wp#&@|I%)V5I>7kjSUfaaX-xqCJMP0tSW;7a70Da#|u z6Q^FW24f4ZLwfV*w-ZQmWDh>l%yrH|;}r}`{Feh!oZ10)57Kj%iu*%*kgVl;b=z-l z?}OMZ)cXZ7D1CBH?}LFpT9@?gjiPbHA2bZsra9CD=%@pd`?roj0$sm4mf=+e00000 m000000000000000AHYAp*j2v4I}w%u0000`S1=IzQB!8PpL_t(|ob8)Qj>I4gMd?=GB=(16<5_n7iRPj;sAR4lyR) zvWv|-KsZ$F2H_gBQ3%OnOh=1%b<6!cVh0Fk1=oI`gwo?)M1SvO{~3@L9I8h_syTh{ z*|ReMdFEv*xN^E499gGe%ro;(O6g~#Zk!X$bJ9Cby%qiZLzoak2qA>DQN6E%0;k!S z@meBsw9LpD?+PuZv*OCOsubbfr#!%y{)hqCWpN`T()vIF5WXlcu3~_$nwdAF>Wgt> zyx!b}Yj#bl^?zVJLE)b{%gD?p=57^v1IY1SG`q|c6tpBb1u(utT4aub`6=j%KVC9% zQKF?!4wk>SCc2~;r}tnafzEZVr$TG_%yP8$`1m0<9-)a9&}%y5Cdm{uaT(@Z)N$ly zV@grUNf&VyVwib!Py7tiLMrZE@tL)bCTsEOIvpV2?SFca_dD)H&k2Ct`y%gm<9*jI z($zfR8)EPfJ|PRemx_}agQeWzUbCDaTDk@5$A}Fbim=)GF{t8JyrR%Z0D=Ec$Z^DOkbX5G26%<^$bg##}N{li=x-sbhz z6y5=z1b=V;Y5BTqixYjcF6rZq0(it9G(7G|sk>>r2Q?(!)Ke!g;}R#B!6#7L_t(|obB3Mj)O1^Kv6pCPO|?cc`x&UR9Vggg#xyldp<@P zL?Cq_5Ql98000000Kh6<-VHcUL_XzGiepQ@k+K7H=(UX9kgo$i(bwT_ZcO3Ny8$Pe zK&Oj)RwAOupYgvbWW596rgxcVy!^MkcYuj?#?bHby#;N&hJOa}8xt`A007{2(I!^v&j0`b delta 399 zcmV;A0dW4P1E~X$B!6&8L_t(|obB3Mj)O1^Kv6oHon-$@@?Pcxsj{306B@8x?)j)v z1T=LZAr9LH000000Dz}>c~{^(5qXzODULPyM9K!xq1Q4tL%s%hM_-4#xiN(w?+Tn` z0-Y}IS&4}5f5u-^$a)9BP46<#c=>O6?*J3)jG^D&+nHG6py_KrdlAcsewT1phgz7tN=P tw97@yD%PDHLkV1fj4w#oni diff --git a/tests/snapshots/nanox/test_sign_psbt_with_naked_opreturn_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_naked_opreturn_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_with_naked_opreturn_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_with_naked_opreturn_0_0/00002.png index 8b83bf20399ab3b347242d79a3166ba42f65dd6e..e0ee426052691c1662a178c82048b03406ee92a1 100644 GIT binary patch delta 389 zcmV;00eb$P1E2$tB!6c~L_t(|obB0dl7k=&fML3`H{t$A;x7Bc8HWi0vQ`pW-{)Tu zMHBgurUU>006bGErIcbnG^qb^exh$6ouT}inEuOe^bK^W`A~a9&iN?MIg2{>k|@DF zKm=6u1`!&yP+a7!qXt@>+m`s-q6dgz8Q=YDSEwW2%c!ULIe#E6m{fBm&4L~~_e3V( zeDZoIIL7q0vgJJ;)Y)_VNh!So+a8Yz>O9$-PJ3_k{*y2O0KhXjEknh}&R|(NJ$dlPUJGm@A z0mdMz)!vMIuYT#H6Zj-GJ^{w(RHxZnnttwX=mjeVX!V+IGlA>@E4p6$Fn2X!8NNj8 z_NG_lU=rSE{w?lI1o>4T*kLWPsIP2A2{rG&GbP~Uz)d&QT7?`B}0tNU1I3* zaVO>AAiUxA_yi)zulhpxc49`MEJz78-@Y>?;N-wfH`L_7!9kG8!Bm770000000000 h000000001(<{!=99LOmyw0!^o002ovPDHLkV1lMdvkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_with_opreturn_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_with_opreturn_0_0/00002.png index 85912cd4e6af442822c849a271270875e37e00ad..4c3ce0a58ed3d2c607f32b59818fe865b6c8e7b5 100644 GIT binary patch delta 805 zcmV+=1KRw_2D}E4B!2@*L_t(|ob8%hZtWlpMd?*%lKBrQbGaW;BZ?nv3?@0%ULTdp zaj-GZY*Gp#gb+dqA%BVUJkRsQe{$?s#pAoXOU?@G@m2iGsI*k!rsfn!=2|s7j^p}! z(O71*<$HOJK584(*>D`kRW1{Om(0Ylhm;v$4YxX>&95?Fa)0Qlqw+3vN*Wi^Ky8A2 zN;Ykt#2L^;92j?a4Ru1T9(9n9+^(;=h*vdA)*et2Hr1n|^pgIPy{F6i4!B!h&va`X zA%n}YLDnCT)M4)MwY)}uO;GnqYdf_@bYK&9qC$MBHIM=3*Td}Bl)uk>2ds*O5JCtk zCF2;X((GW)0e`gnc=zxs3!5XRe;`(kKO0qRlRr7f4Asohx{-gaIyXqrHHlKhhjPD~ z?P0eZy_Q<`cs7zS&vyWrMAd9E@0ROp671>J=Q{vwXNDY~B=HaNVS7Nv0 zFXSoYRk=p}o={zR!s4Z+gIdEJ`NYxe08ocg<)E(Du85@C#C%EA79rv#qLq$@G`0jG zRqvFyd|!_032Mb%0=s>~`U{ztWWPM2dIr3h9S~R()k1l1BcDQS5MMaW*jMl48q^CY jFdj}q2qAXHBf<}H00000NkvXXu0mjf*lvzn delta 818 zcmV-21I_%r2FV7HB!3V|L_t(|ob8%hlHDK-M441};{7kld&!4u9D*J+0%6}tpO2{; zu0XN`7`I&tA%qY@2q8a-^E}V<#D8+^SHZIGL=+Fi}EdIXRc64=?uU*;b&vL91^ zKJx`w6$v4P5PwoiDPMcs$fKuhw@!G@p|EaLT{K6}`(JBJ)%fFa4%&#;sM;XL&cD`} z8}#RfEIIl^*)L}7mZKNaJQ#l{&ldp6qiQpmcgyd!2(}gV`2yg2+}h0{N#7sklkNc- z8?-v+&O1T70y0*gyq+a4kiDyMjr&ciK_|VBugCv^CV$Ca^$(99Co&ew3sF+dxxX1D z;jFx9<{v62_gq;eaby7}fbrpzmTWNL|AI*Eq-b2g%4{kFD!)RLE%R zwu6TnFMohcnHq=Fz5Kh3q^y?o8$s}bR-)Lx*92b$%op_hA^<+UzG$Hb!=Dqf6u z0n|C$ko}4^Hs-5d{Kk)=vH1EZhTbV}`Mw<06V!^k1n%|?>tD#cB>UwF)idD5EI?pSR2$`c8`%r7 wK`VUWG;?2lAJ?G1fCA$rgb+dqA>>{B0l1^X1`lXDBMQx`$$^Ms=z4Rk}8Ak-Jh~~Au=d1M* zK{SNiltKt0gb+f=c0Lx(d!A=0kmHj(qnFr+=kjUL2K`tLHk4p9>PZF(>(1pcipH6N=iLUFRK5G zlnqFUgb+dq`G3J_L#1$tj1=WnbB|3EKXR>fF>jMhS2EK^4E}xnagxkESc*)q|50AP zWY_=NHpS~i4M&JU-TWc_@lYqKIZ9azig80Anj$h!*g(5vQn+<5A1V?FTF^RX&QYy5 zEPdAn9e;(7JgSBk^UZVUC00}Ah72y*vb!-UVyf*ZtbIxb)KEF1>4k`HfjAm9=+aG} zy-9&c!m90)B`6&v*Nf!2@V)qFzlfEM*+*P!pl#@+t|@J#*{Fe=U%LRhk2Kp65~@rB zA%qY@2)VG@P`ufSeX^Gqx*xT>5!Svm)u=o9q<;d6>%@^x6p;y~F)}iwO(GE*BcPXn z0y?A<8^*s$iU`~jGmbV$tz~orz~#9w;xpx?D}gn#AQFS&4pBhCRk)08KvyP2mfF}L zYGTX=3_uc4K*QOnnJqyn0%Z3YZkWvnxrl(HDK#{3_V@G7*)Op+)Mz?o9Ebp!-YJ5E mDIp5zs3SrMA%qY@p646qM@Wsu(PNze0000 delta 810 zcmV+_1J(S$2Ehi9B!37=L_t(|ob8!WcI_YtMQvASlKBrQbLmHVvs@x@L^QYU*g0myZp`FUxA#S*|7O(&q@NUd((Aps4nFAgP2Nlw z$t9?6Fx>tDIazi!ck2&6^U`B(klcpaH9>3dnn7(6X=9JLF_h{i+3vbg5tRFl`uHUO zmy``iiG&bB2!Hv(X+x!Oh>R5FQ*)0^6F>5-bTMy}Ojk0~MhyL6vyCl*%(%`{Ntejc z@4z|@2b}hNVVn6{5b_1M(*{AyzFRu%4`U;+#^w$nVFQ{OZ+~6w&=ulGZL}H^+ax)^ z)LdN~d*(VwB&3KMx>}*V>28DTy{XaLqHO@34sXCy>wm$$8#nb0Y1>d)YOa5{;$<;g z!i)Fd{V; zyLm#o4DmP?s$(G%XNfA?RM`7(#GN6Xa5lt^dbPL4Ms6m%* z`s_^#L=skQpDaP?Ah}*7&xP;epZ!IwY|K95S_5rECv{C}Bh5w)-2B=F(0!%Zj*w7g z5(puL5JJd>)rR8DR_rHx`Jnrwb~nP>m!=wZCx4$*KyjTo(upE6p)^KDhO|i}LSqE< z5>P;gbYjE!H%SqJJ2B&EgVb6^Hvn9o`yoD4Ub+%kBMTxi814`S6kLVN*amcELS(6p z4WcH-Y`_2{0R=RijhfjKlp;WO-{FSYe2|L>IGR#J1809f@0|S-YeS8uQ^tV^km;Qw oI3t*%fQ~vMgb+dqA>?_!0sekRy{YE-qW}N^07*qoM6N<$g1Oa$LI3~& diff --git a/tests/snapshots/nanox/test_sign_psbt_with_opreturn_0_0/00004.png b/tests/snapshots/nanox/test_sign_psbt_with_opreturn_0_0/00004.png index 9770af436e63184368199bcc977791ee38ace56b..2f97e7fed71de7bb6585f2d180b468882bcb070b 100644 GIT binary patch delta 823 zcmV-71IYZ%2F?bMB!3l2L_t(|ob8)ImfRo=M3ubU#P>gv?~;Wlegs6R02xmw^;a`A z7D9k5m%Gh`5JCtcgxJoHhwPr`X=cZ9kRO5mS^iwcuYoRlKDd2u3%UGEw`j#A%bC1L z70?Uw+`HO)eV&-kuXKw5cLHtWwb#ls(QZkmW!<+8wDev(m127^8MA+w}lxDwn4gfCa>x1%R+!p!{~59f9hEGhXgJ*oa* zq%1&+Cqf7z#D5oY843zMw{&AFPTr0+^`CoH&u3TUz@|V|y5e>Mt`ZP_1X?ESFr^3{ z2#X@%59X@sBgWgOq=*#mY2cZhe+aE@dyL`-V&&+{`|z9&we;**8k|7~8TpQO~b=9izmHl1Kl7i`rB|q zt>|w?Yw#w@LT?fTS!?hpZFmDUbW}W;FhV{mS1pzOMS*juC3JE~xJ5AXCnJG{Exb+F z+Pc6w*MG8ptv&bUTpSlhyd($OqmksgT@pwU6G9-?FI|DNy{eZ|NWGZ`4&TRX(&%(2?Q7BT)LNl4ULD3l*>CQC`&S1c^@#Uzpe}ic;WW}FAA1C+nn52 zhA_JC5U9-MWe@^bpK20Ui_%`APLC>0(JD=FJ)*5 z0n+q!MuZST2qA=!?Yu3rd!DC=9LE8E~mYl34&RhhmCm@GfT;w8A2}@pc92rUAIKL) zoIjAOs*ezFS7|{h+|%%9a()w9+x8fR4}@w#mG|K}?P_V+x#S)5u~v$N;0X6AuTv(I zp3k5dS502p`4LnRaMc%iPtql1hHGP5tF9WBPN4l%TUw0c>@r)dQ0qsyy2?sI3=K2hWgjG+zv-Ho%a@xdea7)L1y%~VT78| z-wfB_NtlJ6BnUFsU@1Dhfg0K?9t;=(AC;??%KoIl+0_y{*(Kb1Ao3?7frTx&P1D-E zz&X}3e}Ap4`*N-y7eu@S2il{Nl` z_9}(uLw^?o0w>ZkHni_dpBOhE8WUt6nMWj1;2Z#nb?D5is-d|8X9@$+7k>ecpTCk2 zD^cn`NAWG?J9|n`DK=TXRhK&+cD0OoK3jeIkB(p|s(|Z~UCpsf z{oww4m5})qU2{x)TFtyT)c~Ht{+WRA4 zTMb7aljnSPEP&~EHGgDoDbj3cJY1w)o=HJjlG)7rfL{G|W;lljejo6lV2QKM$$e$0 z`7bWPDLMs6(_!&yj@7aZI;s66gb+dqA>_sQ1fB5zB`W9kumAu607*qoM6N<$f(MU? ACIA2c diff --git a/tests/snapshots/nanox/test_sign_psbt_with_opreturn_v1_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_opreturn_v1_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_with_opreturn_v1_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_with_opreturn_v1_0_0/00002.png index 85912cd4e6af442822c849a271270875e37e00ad..4c3ce0a58ed3d2c607f32b59818fe865b6c8e7b5 100644 GIT binary patch delta 805 zcmV+=1KRw_2D}E4B!2@*L_t(|ob8%hZtWlpMd?*%lKBrQbGaW;BZ?nv3?@0%ULTdp zaj-GZY*Gp#gb+dqA%BVUJkRsQe{$?s#pAoXOU?@G@m2iGsI*k!rsfn!=2|s7j^p}! z(O71*<$HOJK584(*>D`kRW1{Om(0Ylhm;v$4YxX>&95?Fa)0Qlqw+3vN*Wi^Ky8A2 zN;Ykt#2L^;92j?a4Ru1T9(9n9+^(;=h*vdA)*et2Hr1n|^pgIPy{F6i4!B!h&va`X zA%n}YLDnCT)M4)MwY)}uO;GnqYdf_@bYK&9qC$MBHIM=3*Td}Bl)uk>2ds*O5JCtk zCF2;X((GW)0e`gnc=zxs3!5XRe;`(kKO0qRlRr7f4Asohx{-gaIyXqrHHlKhhjPD~ z?P0eZy_Q<`cs7zS&vyWrMAd9E@0ROp671>J=Q{vwXNDY~B=HaNVS7Nv0 zFXSoYRk=p}o={zR!s4Z+gIdEJ`NYxe08ocg<)E(Du85@C#C%EA79rv#qLq$@G`0jG zRqvFyd|!_032Mb%0=s>~`U{ztWWPM2dIr3h9S~R()k1l1BcDQS5MMaW*jMl48q^CY jFdj}q2qAXHBf<}H00000NkvXXu0mjf*lvzn delta 818 zcmV-21I_%r2FV7HB!3V|L_t(|ob8%hlHDK-M441};{7kld&!4u9D*J+0%6}tpO2{; zu0XN`7`I&tA%qY@2q8a-^E}V<#D8+^SHZIGL=+Fi}EdIXRc64=?uU*;b&vL91^ zKJx`w6$v4P5PwoiDPMcs$fKuhw@!G@p|EaLT{K6}`(JBJ)%fFa4%&#;sM;XL&cD`} z8}#RfEIIl^*)L}7mZKNaJQ#l{&ldp6qiQpmcgyd!2(}gV`2yg2+}h0{N#7sklkNc- z8?-v+&O1T70y0*gyq+a4kiDyMjr&ciK_|VBugCv^CV$Ca^$(99Co&ew3sF+dxxX1D z;jFx9<{v62_gq;eaby7}fbrpzmTWNL|AI*Eq-b2g%4{kFD!)RLE%R zwu6TnFMohcnHq=Fz5Kh3q^y?o8$s}bR-)Lx*92b$%op_hA^<+UzG$Hb!=Dqf6u z0n|C$ko}4^Hs-5d{Kk)=vH1EZhTbV}`Mw<06V!^k1n%|?>tD#cB>UwF)idD5EI?pSR2$`c8`%r7 wK`VUWG;?2lAJ?G1fCA$rgb+dqA>>{B0l1^X1`lXDBMQx`$$^Ms=z4Rk}8Ak-Jh~~Au=d1M* zK{SNiltKt0gb+f=c0Lx(d!A=0kmHj(qnFr+=kjUL2K`tLHk4p9>PZF(>(1pcipH6N=iLUFRK5G zlnqFUgb+dq`G3J_L#1$tj1=WnbB|3EKXR>fF>jMhS2EK^4E}xnagxkESc*)q|50AP zWY_=NHpS~i4M&JU-TWc_@lYqKIZ9azig80Anj$h!*g(5vQn+<5A1V?FTF^RX&QYy5 zEPdAn9e;(7JgSBk^UZVUC00}Ah72y*vb!-UVyf*ZtbIxb)KEF1>4k`HfjAm9=+aG} zy-9&c!m90)B`6&v*Nf!2@V)qFzlfEM*+*P!pl#@+t|@J#*{Fe=U%LRhk2Kp65~@rB zA%qY@2)VG@P`ufSeX^Gqx*xT>5!Svm)u=o9q<;d6>%@^x6p;y~F)}iwO(GE*BcPXn z0y?A<8^*s$iU`~jGmbV$tz~orz~#9w;xpx?D}gn#AQFS&4pBhCRk)08KvyP2mfF}L zYGTX=3_uc4K*QOnnJqyn0%Z3YZkWvnxrl(HDK#{3_V@G7*)Op+)Mz?o9Ebp!-YJ5E mDIp5zs3SrMA%qY@p646qM@Wsu(PNze0000 delta 810 zcmV+_1J(S$2Ehi9B!37=L_t(|ob8!WcI_YtMQvASlKBrQbLmHVvs@x@L^QYU*g0myZp`FUxA#S*|7O(&q@NUd((Aps4nFAgP2Nlw z$t9?6Fx>tDIazi!ck2&6^U`B(klcpaH9>3dnn7(6X=9JLF_h{i+3vbg5tRFl`uHUO zmy``iiG&bB2!Hv(X+x!Oh>R5FQ*)0^6F>5-bTMy}Ojk0~MhyL6vyCl*%(%`{Ntejc z@4z|@2b}hNVVn6{5b_1M(*{AyzFRu%4`U;+#^w$nVFQ{OZ+~6w&=ulGZL}H^+ax)^ z)LdN~d*(VwB&3KMx>}*V>28DTy{XaLqHO@34sXCy>wm$$8#nb0Y1>d)YOa5{;$<;g z!i)Fd{V; zyLm#o4DmP?s$(G%XNfA?RM`7(#GN6Xa5lt^dbPL4Ms6m%* z`s_^#L=skQpDaP?Ah}*7&xP;epZ!IwY|K95S_5rECv{C}Bh5w)-2B=F(0!%Zj*w7g z5(puL5JJd>)rR8DR_rHx`Jnrwb~nP>m!=wZCx4$*KyjTo(upE6p)^KDhO|i}LSqE< z5>P;gbYjE!H%SqJJ2B&EgVb6^Hvn9o`yoD4Ub+%kBMTxi814`S6kLVN*amcELS(6p z4WcH-Y`_2{0R=RijhfjKlp;WO-{FSYe2|L>IGR#J1809f@0|S-YeS8uQ^tV^km;Qw oI3t*%fQ~vMgb+dqA>?_!0sekRy{YE-qW}N^07*qoM6N<$g1Oa$LI3~& diff --git a/tests/snapshots/nanox/test_sign_psbt_with_opreturn_v1_0_0/00004.png b/tests/snapshots/nanox/test_sign_psbt_with_opreturn_v1_0_0/00004.png index 9770af436e63184368199bcc977791ee38ace56b..2f97e7fed71de7bb6585f2d180b468882bcb070b 100644 GIT binary patch delta 823 zcmV-71IYZ%2F?bMB!3l2L_t(|ob8)ImfRo=M3ubU#P>gv?~;Wlegs6R02xmw^;a`A z7D9k5m%Gh`5JCtcgxJoHhwPr`X=cZ9kRO5mS^iwcuYoRlKDd2u3%UGEw`j#A%bC1L z70?Uw+`HO)eV&-kuXKw5cLHtWwb#ls(QZkmW!<+8wDev(m127^8MA+w}lxDwn4gfCa>x1%R+!p!{~59f9hEGhXgJ*oa* zq%1&+Cqf7z#D5oY843zMw{&AFPTr0+^`CoH&u3TUz@|V|y5e>Mt`ZP_1X?ESFr^3{ z2#X@%59X@sBgWgOq=*#mY2cZhe+aE@dyL`-V&&+{`|z9&we;**8k|7~8TpQO~b=9izmHl1Kl7i`rB|q zt>|w?Yw#w@LT?fTS!?hpZFmDUbW}W;FhV{mS1pzOMS*juC3JE~xJ5AXCnJG{Exb+F z+Pc6w*MG8ptv&bUTpSlhyd($OqmksgT@pwU6G9-?FI|DNy{eZ|NWGZ`4&TRX(&%(2?Q7BT)LNl4ULD3l*>CQC`&S1c^@#Uzpe}ic;WW}FAA1C+nn52 zhA_JC5U9-MWe@^bpK20Ui_%`APLC>0(JD=FJ)*5 z0n+q!MuZST2qA=!?Yu3rd!DC=9LE8E~mYl34&RhhmCm@GfT;w8A2}@pc92rUAIKL) zoIjAOs*ezFS7|{h+|%%9a()w9+x8fR4}@w#mG|K}?P_V+x#S)5u~v$N;0X6AuTv(I zp3k5dS502p`4LnRaMc%iPtql1hHGP5tF9WBPN4l%TUw0c>@r)dQ0qsyy2?sI3=K2hWgjG+zv-Ho%a@xdea7)L1y%~VT78| z-wfB_NtlJ6BnUFsU@1Dhfg0K?9t;=(AC;??%KoIl+0_y{*(Kb1Ao3?7frTx&P1D-E zz&X}3e}Ap4`*N-y7eu@S2il{Nl` z_9}(uLw^?o0w>ZkHni_dpBOhE8WUt6nMWj1;2Z#nb?D5is-d|8X9@$+7k>ecpTCk2 zD^cn`NAWG?J9|n`DK=TXRhK&+cD0OoK3jeIkB(p|s(|Z~UCpsf z{oww4m5})qU2{x)TFtyT)c~Ht{+WRA4 zTMb7aljnSPEP&~EHGgDoDbj3cJY1w)o=HJjlG)7rfL{G|W;lljejo6lV2QKM$$e$0 z`7bWPDLMs6(_!&yj@7aZI;s66gb+dqA>_sQ1fB5zB`W9kumAu607*qoM6N<$f(MU? ACIA2c diff --git a/tests/snapshots/nanox/test_sign_psbt_with_segwit_v16_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_with_segwit_v16_0_0/00000.png index 73cd118fdd24fc9be59f2356f1e8ca08df127b43..3b28fab15c51a907779197735828281c06650c22 100644 GIT binary patch delta 390 zcmV;10eSwS1EB+uB!6g0L_t(|obB3CZi6rkfMGWECb|ESe3v~?AkNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_with_segwit_v16_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_with_segwit_v16_0_0/00002.png index 687e6d5cde9fae2b37cb3b9d50328181b295fed0..1a48535878132236f1f5958aea84af65af8d8307 100644 GIT binary patch delta 485 zcmVVK#9ijW87dtXqY`lWzo)KC)w$zRu}+W6Stzw6V-TMu#u& zB(FO_PPi(l2A5@SO>JsVig|<0^Crbd0C@@-9JxL}%K7=w`!(hH?y@QX0Pty7T@!Y# z_khiwt-W5s?tiPcK^43j#X^||`5Ih24#6F2rSL{=-LmP;!JK0)2o{|au-3xJft^b+ zjvUzOA7s>njjA=SLCddwsbrsL;?2R0=SJ6ITRiv+gQ~%|+`vQq0P4>8O8~t;QhAMJ z*&L?Y)#PA+jZP*9uIOIiQ?(kpx?nZ&*1>%)SWUcjuwKaVuZgfA0h5t{$ykJk29LW= zHSrn2gehn;5&!@I-ia5np}~DFSWvumu!#47$wKA&7=ju00000NkvXXu0mjfa}M$J delta 485 zcmZo?X=j)dsBT7JuS?oN4lWT`>q4WWvP{HtFNHmDk&+^fR?0{%+J zB$BU)o4$(fU4D0N$Rqi!$JhR-Fxl1daM!I6|Gd{pTLlhDgznt1=Xfn_Acq-eKL%vcbnrH7@^6wRJx_IH_=ADyDCf0{vm{6YE^q9xPZB5VL zWL=NuYc{tQXdC4emNZmucrsD1cJr~Vq00|%)BCNOA-!wP%hipaPR;s}b>-q3doMoz z_bPGA6?Q&QOA?BiwY7A0u(hU`w#IG^ImQ(6Aeo)^_FbQ+^SsYK_1W@0!|I7ZUwpYR z^*W2~+Uf)AQnRmXU-%qauk9fe*PF7iq_+Cr#HadX{}ZYWa&!^KR?sZr3;Hn*DP!T=`)ltIR9*31@oZ z*%SUwobugc+u6hr-(G&U4aq4r54fJO{_r=I-c@uk=h51uc6u{>_iT+g^144Rasdmw z4;#Brn{UO6iaD=Sgy$>fZD8?bV+XqSfb~NqvyeBBn>dd~cf0NYtAi`$RujqBg)8-W Z#D2eh_0cCCQo*3u@^tlcS?83{1ONq)-YftB diff --git a/tests/snapshots/nanox/test_sign_psbt_with_segwit_v16_0_0/00003.png b/tests/snapshots/nanox/test_sign_psbt_with_segwit_v16_0_0/00003.png index 72bc053e6fffbe3224264056405dd988f1dc2ea6..ec98cabb58fc74b78d370364e4cb6e8338d7d0c3 100644 GIT binary patch delta 443 zcmV;s0Yv`S1JwhNB!8SqL_t(|obB0La>F1DKvA0MPT2pF*h@c>@en{*fP@qGo==Pc zi&r2a00000w~{j1sH@+GI*(KH9v+3}pW#vds5*`@#?WeBo?hqi_?%z! z5<8k7&>V>|MkxyVlqTts@^y3eGoT1)F&m0+YbFL^%r*mEynkD#NL7rICe0$R8BjD= zIrisD$b+j4cad#qaM*I$1A@b*8Z+T6=>4iS4coSR8F#?Z?tCeDuIY7V&EV><=BMkA zzU1i^F8Z-8uD>QUH#%uMl}7Z$CfxbuQ|$J2b)8m0%Va(DKB?TCNe7s;1OR}4VD27G zx+}$)^~>ZveSffe7o-Mqt?;B^~%m1j_nA^iD!>D^{Py%RW9WVHvB9WYc}z0qBsII1q8-m9g=x$1f) ztbC9DKd)_xR%{C|N_*rFxa{7bn7FSFAo@GC7thcC!8C9iVyNkZ4NihgAGjjC00000 l00000000000001hn?JVB+}-l=J7WL<002ovPDHLkV1j?Y)ms1n delta 445 zcmV;u0Yd)O1J?tPB!8YsL_t(|obB0La>F1DKvA0MPT2pF*h@d0@lYhN0D)8Yo=<`W z<{5AZ0002MW2BT)O7@=``Mv5>l+~_-%(JL^uN6V_*H{t1mu$xvW6-LXr^`GmUgz6A zVuShu>PU<+)>^@yqN@F5eB7P?3@943m<`3dsfnR7X4Qr+o`01owIX`eCe5T(GoYxh zaqN#p$Q#$#+(ovo!QpFF2e^+EInwjKIR?J5P)oLLyO;A4bk;jx3XTSnnJt5>y_#RH zKlaGOHJtS28?L=3s2g2vJC#9Xo_5M*9YQvfYQ;5b1uK_B#_E&G!?|>TOHBX(_y@-B z(Q0?4=rezrynm+;X0IZQXRDow;rD&2tg3oMuN~JLMV|+>+fHZd5W6?gD}(*n$%(S{ zd%#~|8QSU{#(*VX#BOvn$~lBTe=mL743Im)qJq5kfU*O+!l_sA_a^p|5#(N7OB^e% z6=CLm?BBe$C3^7kNRKy~{k~<-g>e0VdZOQ@_ghD`??oXnzpzxDf*Y003?m{f1GL z(T+ETbh*%>n$o6YB)8J1mZKJ=r$w_0R2QY2+nep@l~RIUUdapzLA*MFl*_ kEJ0y000000007`Ye`^#qNsXCx1^@s607*qoM6N<$f?wOSy8r+H delta 392 zcmV;30eAkP1EK?vB!6j1L_t(|obB3Cl7k=&fML6{H_82vl)LPMJ5B}=i&c}9|9j|A zN7@*K*66YT000000ALm`?*PtI)vYZej*)yKR0*x1ugsy4S(W0F2n!;0D#*?zhG2j zwBt=7T`qK}MQPJ9l3UqB%TWum)1p}gs*BRi?alV{L?r0x)y&Z)jr!G*4dB-?j;8({ z$DvP%NmcEkg&Tl1xFU%|wYJEGxgz`F^p~Jw&!L^0?FhonfSUcuIy`-bb_M_d03H?R zfyU^?xO1u5>wi^mcfT}sdoHNHT(Y@X+r^VV%?E)Fd)43A|BxvhRuTFehkDiD+nfhu z2XLL}OVHPwWdMp>G;vCDvkbtx#EZz*@Q&!8Pc?L}X4xqw7xxL?>9v>TIN47o&bo1- mS(c!%7ytkO0002+pg(L+HA&JYB>eyY002ovPDHLkU;%=Hpus=@ diff --git a/tests/snapshots/nanox/test_sign_psbt_with_segwit_v16_v1_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_with_segwit_v16_v1_0_0/00002.png index 687e6d5cde9fae2b37cb3b9d50328181b295fed0..1a48535878132236f1f5958aea84af65af8d8307 100644 GIT binary patch delta 485 zcmVVK#9ijW87dtXqY`lWzo)KC)w$zRu}+W6Stzw6V-TMu#u& zB(FO_PPi(l2A5@SO>JsVig|<0^Crbd0C@@-9JxL}%K7=w`!(hH?y@QX0Pty7T@!Y# z_khiwt-W5s?tiPcK^43j#X^||`5Ih24#6F2rSL{=-LmP;!JK0)2o{|au-3xJft^b+ zjvUzOA7s>njjA=SLCddwsbrsL;?2R0=SJ6ITRiv+gQ~%|+`vQq0P4>8O8~t;QhAMJ z*&L?Y)#PA+jZP*9uIOIiQ?(kpx?nZ&*1>%)SWUcjuwKaVuZgfA0h5t{$ykJk29LW= zHSrn2gehn;5&!@I-ia5np}~DFSWvumu!#47$wKA&7=ju00000NkvXXu0mjfa}M$J delta 485 zcmZo?X=j)dsBT7JuS?oN4lWT`>q4WWvP{HtFNHmDk&+^fR?0{%+J zB$BU)o4$(fU4D0N$Rqi!$JhR-Fxl1daM!I6|Gd{pTLlhDgznt1=Xfn_Acq-eKL%vcbnrH7@^6wRJx_IH_=ADyDCf0{vm{6YE^q9xPZB5VL zWL=NuYc{tQXdC4emNZmucrsD1cJr~Vq00|%)BCNOA-!wP%hipaPR;s}b>-q3doMoz z_bPGA6?Q&QOA?BiwY7A0u(hU`w#IG^ImQ(6Aeo)^_FbQ+^SsYK_1W@0!|I7ZUwpYR z^*W2~+Uf)AQnRmXU-%qauk9fe*PF7iq_+Cr#HadX{}ZYWa&!^KR?sZr3;Hn*DP!T=`)ltIR9*31@oZ z*%SUwobugc+u6hr-(G&U4aq4r54fJO{_r=I-c@uk=h51uc6u{>_iT+g^144Rasdmw z4;#Brn{UO6iaD=Sgy$>fZD8?bV+XqSfb~NqvyeBBn>dd~cf0NYtAi`$RujqBg)8-W Z#D2eh_0cCCQo*3u@^tlcS?83{1ONq)-YftB diff --git a/tests/snapshots/nanox/test_sign_psbt_with_segwit_v16_v1_0_0/00003.png b/tests/snapshots/nanox/test_sign_psbt_with_segwit_v16_v1_0_0/00003.png index 72bc053e6fffbe3224264056405dd988f1dc2ea6..ec98cabb58fc74b78d370364e4cb6e8338d7d0c3 100644 GIT binary patch delta 443 zcmV;s0Yv`S1JwhNB!8SqL_t(|obB0La>F1DKvA0MPT2pF*h@c>@en{*fP@qGo==Pc zi&r2a00000w~{j1sH@+GI*(KH9v+3}pW#vds5*`@#?WeBo?hqi_?%z! z5<8k7&>V>|MkxyVlqTts@^y3eGoT1)F&m0+YbFL^%r*mEynkD#NL7rICe0$R8BjD= zIrisD$b+j4cad#qaM*I$1A@b*8Z+T6=>4iS4coSR8F#?Z?tCeDuIY7V&EV><=BMkA zzU1i^F8Z-8uD>QUH#%uMl}7Z$CfxbuQ|$J2b)8m0%Va(DKB?TCNe7s;1OR}4VD27G zx+}$)^~>ZveSffe7o-Mqt?;B^~%m1j_nA^iD!>D^{Py%RW9WVHvB9WYc}z0qBsII1q8-m9g=x$1f) ztbC9DKd)_xR%{C|N_*rFxa{7bn7FSFAo@GC7thcC!8C9iVyNkZ4NihgAGjjC00000 l00000000000001hn?JVB+}-l=J7WL<002ovPDHLkV1j?Y)ms1n delta 445 zcmV;u0Yd)O1J?tPB!8YsL_t(|obB0La>F1DKvA0MPT2pF*h@d0@lYhN0D)8Yo=<`W z<{5AZ0002MW2BT)O7@=``Mv5>l+~_-%(JL^uN6V_*H{t1mu$xvW6-LXr^`GmUgz6A zVuShu>PU<+)>^@yqN@F5eB7P?3@943m<`3dsfnR7X4Qr+o`01owIX`eCe5T(GoYxh zaqN#p$Q#$#+(ovo!QpFF2e^+EInwjKIR?J5P)oLLyO;A4bk;jx3XTSnnJt5>y_#RH zKlaGOHJtS28?L=3s2g2vJC#9Xo_5M*9YQvfYQ;5b1uK_B#_E&G!?|>TOHBX(_y@-B z(Q0?4=rezrynm+;X0IZQXRDow;rD&2tg3oMuN~JLMV|+>+fHZd5W6?gD}(*n$%(S{ zd%#~|8QSU{#(*VX#BOvn$~lBTe=mL743Im)qJq5kfU*O+!l_sA_a^p|5#(N7OB^e% z6=CLm?BBe$C3^7 Date: Fri, 29 Nov 2024 13:55:23 +0000 Subject: [PATCH 51/57] Cleanup some tests; remove debug prints --- test_utils/taproot_sighash.py | 1 + tests/test_e2e_musig2.py | 39 ++--------------------------------- tests/test_sign_psbt.py | 23 --------------------- 3 files changed, 3 insertions(+), 60 deletions(-) diff --git a/test_utils/taproot_sighash.py b/test_utils/taproot_sighash.py index 073be97e2..47dfe8dfd 100644 --- a/test_utils/taproot_sighash.py +++ b/test_utils/taproot_sighash.py @@ -3,6 +3,7 @@ # # Copyright (c) 2015-2022 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. import struct diff --git a/tests/test_e2e_musig2.py b/tests/test_e2e_musig2.py index ef14479e4..b9a45d264 100644 --- a/tests/test_e2e_musig2.py +++ b/tests/test_e2e_musig2.py @@ -1,6 +1,6 @@ import pytest -from typing import Dict, List, Tuple +from typing import List, Tuple import hmac from hashlib import sha256 @@ -13,8 +13,7 @@ from ledger_bitcoin.wallet import WalletPolicy from ledger_bitcoin import MusigPubNonce, MusigPartialSignature, PartialSignature, SignPsbtYieldedObject -from test_utils import SpeculosGlobals, bip0327, get_internal_xpub, count_internal_key_placeholders -from test_utils.musig2 import PsbtMusig2Cosigner +from test_utils import SpeculosGlobals, get_internal_xpub, count_internal_key_placeholders from ragger_bitcoin import RaggerClient from ragger_bitcoin.ragger_instructions import Instructions @@ -44,12 +43,6 @@ def strip_non_musig2_derivations(psbt: PSBT) -> PSBT: def run_test_e2e_musig2(navigator: Navigator, client: RaggerClient, wallet_policy: WalletPolicy, core_wallet_names: List[str], rpc: AuthServiceProxy, rpc_test_wallet: AuthServiceProxy, speculos_globals: SpeculosGlobals, instructions_register_wallet: Instructions, instructions_sign_psbt: Instructions, test_name: str): - # TODO: delete - def printb(*args): - print('\033[94m', end='') - print(*args) - print('\033[0m', end='') - wallet_id, wallet_hmac = client.register_wallet(wallet_policy, navigator, instructions=instructions_register_wallet, testname=f"{test_name}_register") @@ -78,9 +71,6 @@ def printb(*args): change_descriptor_info = rpc.getdescriptorinfo(change_descriptor) change_descriptor_chk: str = change_descriptor_info["descriptor"] - printb("Receive descriptor:", receive_descriptor_chk) # TODO: remove - printb("Change descriptor:", change_descriptor_chk) # TODO: remove - # ==> import wallet in bitcoin-core new_core_wallet_name = get_unique_wallet_name() @@ -131,9 +121,6 @@ def printb(*args): psbt_b64 = result["psbt"] - printb("PSBT before the first round:") - printb(psbt_b64) - # Round 1: get nonces # ==> get nonce from the hww @@ -149,12 +136,8 @@ def printb(*args): instructions=instructions_sign_psbt, testname=f"{test_name}_sign") - printb("SignPsbt yielded:", hww_yielded) for (input_index, yielded) in hww_yielded: if isinstance(yielded, MusigPubNonce): - printb(f"Yielded MusigPubNonce for input {input_index}:") - printb(yielded.participant_pubkey.hex(), yielded.aggregate_pubkey.hex( - ), None if yielded.tapleaf_hash is None else yielded.tapleaf_hash.hex()) psbt_key = ( yielded.participant_pubkey, yielded.aggregate_pubkey, @@ -177,32 +160,20 @@ def printb(*args): signed_psbt_hww_b64 = psbt.serialize() - printb("PSBT after the first round for the hww:", signed_psbt_hww_b64) - # ==> Process it with bitcoin-core to get the musig pubnonces partial_psbts = [signed_psbt_hww_b64] # partial_psbts = [] for core_wallet_name in core_wallet_names: - printb("Processing for:", core_wallet_name) psbt_res = get_wallet_rpc( core_wallet_name).walletprocesspsbt(psbt_b64)["psbt"] - printb("PSBT processed by core:") - printb(psbt_res) partial_psbts.append(psbt_res) combined_psbt = rpc.combinepsbt(partial_psbts) # Round 2: get Musig Partial Signatures - printb(wallet_policy.get_descriptor(None)) - - # TODO: should now do the second round - printb("PSBT after the first round:", combined_psbt) - - printb("Starting round 2") - psbt = PSBT() psbt.deserialize(combined_psbt) @@ -211,7 +182,6 @@ def printb(*args): instructions=instructions_sign_psbt, testname=f"{test_name}_sign") - printb("SignPsbt yielded:", hww_yielded) for (input_index, yielded) in hww_yielded: if isinstance(yielded, MusigPartialSignature): psbt_key = ( @@ -236,17 +206,12 @@ def printb(*args): signed_psbt_hww_b64 = psbt.serialize() - printb("PSBT after the second round for the hww:", signed_psbt_hww_b64) - # ==> Get Musig partial signatures with each bitcoin-core wallet partial_psbts = [signed_psbt_hww_b64] for core_wallet_name in core_wallet_names: - printb("Processing for:", core_wallet_name) psbt_res = get_wallet_rpc( core_wallet_name).walletprocesspsbt(combined_psbt)["psbt"] - printb("PSBT processed by core:") - printb(psbt_res) partial_psbts.append(psbt_res) # ==> finalize the psbt, extract tx and broadcast diff --git a/tests/test_sign_psbt.py b/tests/test_sign_psbt.py index f37237ff6..2b251e89e 100644 --- a/tests/test_sign_psbt.py +++ b/tests/test_sign_psbt.py @@ -966,29 +966,6 @@ def test_sign_psbt_against_wrong_tapleaf_hash(navigator: Navigator, firmware: Fi "5b82996fe6cf1bf43868511181c64c965b7bf5f16f007acec52dede5288f9225") -def test_sign_psbt_multiple_derivation_paths(navigator: Navigator, firmware: Firmware, client: RaggerClient, test_name: str): - # A previous implementation of the app incompletely checked the derivation paths of keys in certain - # transactions when multiple internal in the policy; that wasn't detected in other tests, so this - # was added in order to avoid regressions. - wallet = WalletPolicy( - name="Cold storage", - descriptor_template="wsh(or_d(multi(4,@0/<0;1>/*,@1/<0;1>/*,@2/<0;1>/*,@3/<0;1>/*),and_v(v:thresh(3,pkh(@0/<2;3>/*),a:pkh(@1/<2;3>/*),a:pkh(@2/<2;3>/*),a:pkh(@3/<2;3>/*)),older(65535))))", - keys_info=["[f5acc2fd/48'/1'/0'/2']tpubDFAqEGNyad35aBCKUAXbQGDjdVhNueno5ZZVEn3sQbW5ci457gLR7HyTmHBg93oourBssgUxuWz1jX5uhc1qaqFo9VsybY1J5FuedLfm4dK", 'tpubDE7NQymr4AFtewpAsWtnreyq9ghkzQBXpCZjWLFVRAvnbf7vya2eMTvT2fPapNqL8SuVvLQdbUbMfWLVDCZKnsEBqp6UK93QEzL8Ck23AwF', - 'tpubDF4kujkh5dAhC1pFgBToZybXdvJFXXGX4BWdDxWqP7EUpG8gxkfMQeDjGPDnTr9e4NrkFmDM1ocav3Jz6x79CRZbxGr9dzFokJLuvDDnyRh', 'tpubDD3ULTdBbyuMMMs8BCsJKgZgEnZjjbsbtV6ig3xtkQnaSc1gu9kNhmDDEW49HoLzDNA4y2TMqRzj4BugrrtcpXkjoHSoMVhJwfZLUFmv6yn'] - ) - wallet_hmac = bytes.fromhex( - "8a0e67be3697449e4d1b19d6aaec634ce747cbcf35287887588028c9da250ab3") - - psbt_b64 = "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" - - result = client.sign_psbt(psbt_b64, wallet, wallet_hmac, navigator, - instructions=sign_psbt_instruction_approve( - firmware, has_spend_from_wallet=True, save_screenshot=False), - testname=test_name) - - assert len(result) == 2 - - def test_sign_psbt_multiple_derivation_paths(navigator: Navigator, firmware: Firmware, client: RaggerClient, test_name: str): # A previous implementation of the app incompletely checked the derivation paths of keys in certain # transactions when multiple internal in the policy; that wasn't detected in other tests, so this From 44646bcf7a0a4aaaaa356357d4b5cc1a33ebd8b7 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Fri, 29 Nov 2024 14:47:10 +0000 Subject: [PATCH 52/57] Add missing python test dependencies --- bitcoin_client/tests/requirements.txt | 9 +++++---- tests/requirements.txt | 3 ++- tests_mainnet/requirements.txt | 9 +++++---- tests_perf/requirements.txt | 2 ++ 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/bitcoin_client/tests/requirements.txt b/bitcoin_client/tests/requirements.txt index 23a57de0e..e7c7ab739 100644 --- a/bitcoin_client/tests/requirements.txt +++ b/bitcoin_client/tests/requirements.txt @@ -1,8 +1,9 @@ -pytest>=6.1.1,<7.0.0 -pytest-timeout>=2.1.0,<3.0.0 +bip32>=3.4,<4.0 ledgercomm>=1.1.0,<1.2.0 ecdsa>=0.16.1,<0.17.0 -typing-extensions>=3.7,<4.0 embit>=0.7.0,<0.8.0 mnemonic==0.20 -bip32>=3.4,<4.0 \ No newline at end of file +pytest>=6.1.1,<7.0.0 +pytest-timeout>=2.1.0,<3.0.0 +speculos>=0.12.0,<0.13.0 +typing-extensions>=3.7,<4.0 diff --git a/tests/requirements.txt b/tests/requirements.txt index d8554a27a..9fa0510eb 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -6,4 +6,5 @@ typing-extensions>=3.7,<4.0 embit>=0.7.0,<0.8.0 mnemonic==0.20 bip32>=3.4,<4.0 -ragger[speculos, ledgerwallet]>=1.6.0 \ No newline at end of file +speculos>=0.12.0,<0.13.0 +ragger[speculos, ledgerwallet]>=1.6.0 diff --git a/tests_mainnet/requirements.txt b/tests_mainnet/requirements.txt index 23a57de0e..e7c7ab739 100644 --- a/tests_mainnet/requirements.txt +++ b/tests_mainnet/requirements.txt @@ -1,8 +1,9 @@ -pytest>=6.1.1,<7.0.0 -pytest-timeout>=2.1.0,<3.0.0 +bip32>=3.4,<4.0 ledgercomm>=1.1.0,<1.2.0 ecdsa>=0.16.1,<0.17.0 -typing-extensions>=3.7,<4.0 embit>=0.7.0,<0.8.0 mnemonic==0.20 -bip32>=3.4,<4.0 \ No newline at end of file +pytest>=6.1.1,<7.0.0 +pytest-timeout>=2.1.0,<3.0.0 +speculos>=0.12.0,<0.13.0 +typing-extensions>=3.7,<4.0 diff --git a/tests_perf/requirements.txt b/tests_perf/requirements.txt index b4588b87c..4b2d380ac 100644 --- a/tests_perf/requirements.txt +++ b/tests_perf/requirements.txt @@ -1,6 +1,8 @@ bip32>=3.4,<4.0 embit>=0.8.0,<0.9.0 ledgercomm>=1.2.1,<2.0.0 +mnemonic==0.20 pytest>=8.2.2,<9.0.0 pytest-benchmark>=4.0.0,<5.0.0 +speculos>=0.12.0,<0.13.0 typing-extensions>=3.7,<4.0 From 5ffb64d93d9f66ebf07cf9929a816501c5e224a4 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 2 Dec 2024 13:18:52 +0100 Subject: [PATCH 53/57] Simplify CI: only e2e tests need a custom image compiled with bitcoin-core --- .github/workflows/ci-workflow.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index 73f454609..66feefd13 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -136,7 +136,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/ledgerhq/app-bitcoin-new/speculos-bitcoin:latest + image: ghcr.io/ledgerhq/speculos:latest ports: - 1234:1234 - 9999:9999 @@ -168,7 +168,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/ledgerhq/app-bitcoin-new/speculos-bitcoin:latest + image: ghcr.io/ledgerhq/speculos:latest ports: - 1234:1234 - 9999:9999 @@ -195,7 +195,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/ledgerhq/app-bitcoin-new/speculos-bitcoin:latest + image: ghcr.io/ledgerhq/speculos:latest ports: - 1234:1234 - 9999:9999 @@ -232,7 +232,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/ledgerhq/app-bitcoin-new/speculos-bitcoin:latest + image: ghcr.io/ledgerhq/speculos:latest ports: - 1234:1234 - 9999:9999 From f2b0f90ed0347cbcdc8cc19bdec196cbf52b0347 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 2 Dec 2024 16:37:30 +0100 Subject: [PATCH 54/57] Bump version to 2.4.0-rc; add changelog entry for release 2.4.0 --- CHANGELOG.md | 10 ++++++++++ Makefile | 4 ++-- tests/snapshots/flex/test_dashboard/00001.png | Bin 11835 -> 12050 bytes .../snapshots/nanosp/test_dashboard/00001.png | Bin 351 -> 387 bytes .../snapshots/nanox/test_dashboard/00001.png | Bin 351 -> 387 bytes tests/snapshots/stax/test_dashboard/00001.png | Bin 10535 -> 10765 bytes 6 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f9e6992b..666c1066f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Dates are in `dd-mm-yyyy` format. +## [2.4.0] - TBD + +### Added + +- Support for `musig()` key expressions in taproot wallet policies. + +### Changed + +- For wallet policies with multiple internal spending paths, the app will only sign for key expressions for which the corresponding `PSBT_IN_BIP32_DERIVATION` or `PSBT_IN_TAP_BIP32_DERIVATION` is present in the PSBT. This improves performance when signing for certain spending paths is not desired. + ## [2.3.0] - 26-08-2024 ### Added diff --git a/Makefile b/Makefile index 6f06e339a..59b691b90 100644 --- a/Makefile +++ b/Makefile @@ -46,9 +46,9 @@ PATH_SLIP21_APP_LOAD_PARAMS = "LEDGER-Wallet policy" # Application version APPVERSION_M = 2 -APPVERSION_N = 3 +APPVERSION_N = 4 APPVERSION_P = 0 -APPVERSION_SUFFIX = # if not empty, appended at the end. Do not add a dash. +APPVERSION_SUFFIX = rc # if not empty, appended at the end. Do not add a dash. ifeq ($(APPVERSION_SUFFIX),) APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" diff --git a/tests/snapshots/flex/test_dashboard/00001.png b/tests/snapshots/flex/test_dashboard/00001.png index c7f25acbe7df3c67e8df9fbae86717958f38d582..f8cc9c440101b0d7e27fc69544631ecaf9b039dc 100644 GIT binary patch literal 12050 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×G=1`uJpw9u>)GPsobzGkUjz+3FB1{xb&Lp(Mw*{h zAmAAtX2!;hF_`Cx`HG2F*eWTpgtwH;$)Qg=NFU6FUYov3t_plD7wPL?y=%KGVTgiv zZcRaB9g&%!O)!_{){5CEJwD(CBUvLtuaJNG>wvWoM+q#Bp~!}J|CloWW3x;uphDve zA1By+cZLOgaTMQ7jKENXiVbSHZ8OY@^`&a^gQPP~FI*d!;fy?n0OdQ^h`%oXxc2Z! z|JT6m!(G7!{YD*~6M6B-*=wGcb7sM=AX``BvP)UQlx?o8c+5TmGm~Vw)KH;P2o^C@^$HNk?FNA*;>*hX0c*XeQtP=+3aGoy5&EOXL$K$ z-Qrok4;gzp8GNPNi+T5=CUAOPI2dS!{4WV@{)voGNgANjX_N$F-kNk~C|J8v1c6o& zuu%Qa*Qo!Z9)8b76rbz8zy45!+g|j5S%sZu&RnE%uXwQZV~;ITC$N zTWH*@hi8^8f~BnRX~C7*OiU`|le%=&uAZB_wU_|H#b+_I;ib&aN`lQ|BfZfs`J%m+ zTkj_x^3A2Lw@tr1BpT(O1ES{=Cngt17AEv^lqS#gZiLG;-4u=@Avn+p%FnvU=VXqD!~H^EnxhN68bIslvo6nUQ3AZ__XMO8nT~k z&E4qOuDlAe+`3=oia1#1p?$pTyYG1(>D7O~zE32~SsgbVk_EyQ`R5il?mm4Fzng+< zlS%N%nYFN=3Zr|!CX44B4A(7OHEh8pzK%gc#JJ7SUKaLuU^B_@>r3xLyriCE;F*}X z3M8uJ;k!0E6V$kaQ~>bJQ_L$&92xjK-}mYm{-r|q9D=87%}}l%=UkF;&{yiSnMghK zR=E@N{h-b3{pj;x>{PG$k&-S8uXsxoj6B-NNlJLCI)fDBHSdgbqD)$+eQ9gcOOUBV zJfI~jVK~DvYsMSJ5k+Qx@%syLLOJ`#fC2N4KVC`FlLSza!%-K#ZH{{`ZGALI$!A2c zY7Jr{+{D&OwL5E4wXe8Lv@4HkBvF)8v*Jz1qjK>1GG#c%}Njo@fnytC+`oa8d4!?v1hAr+)I( zm>k|}Q;OWY=5WF{1ycU~Uh7dQLDOm?p6&tAsnglxi!|jD@of7jcxY1JuZQ;hbym3cdh$G1@1}HjAh$oM< zGqkj1XAOmlS!g^_LLJEwJs@l-%eZ9!g2dqq_?bO%7disVM@kp(H~gH`T+5r( z!&Vo9$t!sfIlE@`&D{|LP&-H*Mi4=Bl(?`iDM`aR?G6m>^;*i+K^ejmS5a{E8KdNr zs+>h?6k`2a+@TY?^}K6&(*m$b-Jw-ysmrEZ)YSYKS(W?;Lf8}u2^H~>1{>b~CH_X| z5()o!joQ@?-4>h9x$C|yS&@Em2Yts4!h=nF*IEq;?BumpP%m@^6ewn4E0blr>?9(;i=O7zABTwdT^oDUTGGdr_z z<_GvHr=#mpV-@hs*VXv4Heh|=e1Bkr*s)JWm5DeAVo22c7%!(uS|S_?0CN9N;C*LG z#qD{-$}baZxnfS_xvBASGOyHg#&n4A{J+EjRRGTJ2DE-o)A|3d&7l-p1o>XLL<0ND|$jp$i*w64ro1ic;k zUDg;k(1IR2kzAz`ipvi1oYb>RySQ4W(n~{|7Al65i^|a>BU_(7) z=-AkN9+F&QI~4NkTphLtS@Zr>%kmh9siKgtq=D>Ib_GXx!>uK=d318J?3b+sH(Zi` zpOc2(^swVdOwREa95Ir|AM5Sl%NI!!FJ>F|?@D(adFch~IgGm;Toajz+4~S{NX;tx zgqjQWD;ed9+;Kk&L>}k5dH<@Vzm>q3;DcVyV-lL$KJ6xfS6&yNv>oDg_S(K8%He+S z+0fFvdt?N~yIN9Jo-nuc!0?>O+HydRfnoUWkOLZQP_pkd@&Yy$Y~hq5%ajpmoN{cr+_MC9YSCdMCOd789IbI$JT(-Z@D^&yF;LlM^>=0u zoSC-b+IeW0EPT!8qg;xWNs!fIa{&}se*Q|lxMpZ{75PRt*)w$Bij2jcUCg=NduVv6 z`;C|6z;b%`Py45O$yW-8=0kd_E(>3Zyi%%g>!*^WVE5W?rS73tNbOxy>bm_ewFcq# zAobNnU2>VkOZQq$tu%$#B$avaB-v$`72jQWnROFXHV^;mJRy7n*VFys4A z|Le@mDb&f$hlaAkkGD-cA3Br(`yqqn{G4Mh0tbyNOJ@Q}Ib+2m!LOm+Xx=`5UYLM*;j7ro_Y+ z|9P$}GiEj?aZ}qT$bWG@d`l(A>2ywoMK|2yVQF^-znR_M2=|KQYW0gsfk^|)0_+7@ zEx_0E-$DI0x+EOX(_-%)N;@7q#qZRT%UWr1bmp{#y&wJ!{`^Sl7418~oZIB64O*}|b z+5_vHtF7I-o(=Ni2+Vob9>c_eaRKNbUNj5+4G(wlbymNbUaQ2A)-xkl;znQ{7}eD# zM5U?=lCh z-6Rs=nRumaj>u5ujl7huf+z*Wc|*nL3f2+{pa4MU9!~zFX$qU^2g9`aVz(=2Fz|QF-)Z&L zRtt^jGtb6kfcJ^{TU+6Qu{8k(&_1E*-s$rXYZduX7%NeWJ=K~3KLLrJ9oN%j;0A~D_Bp+Y3<9h zC1>r&Or^Utxm4mJD&2fwGk7Tv2{qWeqg|CO4o$tMVTjf%t3sO-6_doy?t#Hmf!2N@ z=&XLwIr)ER;H72M8lc+CT~y?@U7{flyX4@M3I^};i;pq`p$booyzWM47#WAJ46cV9 zBE=x(+(~6+`!KPgzXI=arP31MvrEp=KdE-g$8E@+rqEx)_TljqRLq zlKq|53q>o>Sdrlnpu*A=M}eZkUzfl$DJD8SCjHbaMF?@yJls*PuFb!^+gxzaHpT1u@svJGE>*x%ByBi$+B0 z#_ z!5Zxqw^xO;{OU5|!DWx$ZYccALyu&KniOv7+jW!znVe2fP+{t2)$1#Z_aS;)fxJoK1D7Nc=tjoztfx-|hlgJA;8Sa7&77dx$A_xgEy-91!bF;aWE5gyEAJYL zH>tQ7;~gc)Z^AAQvatV-E%k3Zq0Hsg+gwNp29XHGm#l8Xz2!KTnE!BR_pkV+>sV*q zbLgW!$jkJ`!0M4NM7rZe+o8xtLKUbJ(!8oXJ6EwrUxt;7*dKdICms$r0MswN;4nm( zyL~6+teP};oii(I)<`y_+m*G~BOVIdexNISI{gu2?iEMrGjMSfZdf)l+_a^+xm(-| z);M`6ib^)21h}q;dUJgE!*su;{g?WUi!WxkhgdoA%$}v@#Y+CA_1Y!BL%l85v;%^1d_4^M~)H`b@ILYc&j0?DPi>hDpK7CONS z#3(Agcc$OrQva0hinGn<*!3=d)4>5`tO)5W@y1a9{%<2>3kNtT%qSP43y~5UPDFUY z#-j9rNO9C~`6`>;T(($T{7Jou#s5!YfFsKvrXpM<62PID;NAIiwnHzyMwn3|+#V7b z_>P5G!#@d#b=pPynqAsLV;TIo=jAj7T_{u3h4=#@lklrlSHS&)Vq%II6zcUmc}#u! zryj_;48E!+p5%*d%M#%>gF+n&LAx;c@%6n{8L{mpu__hkXh*cyHR7s6&RmFoa|Lqz zEDXmB4*#4Elx_Gk6EnNE9i*qS)OqtCvMvS2u79Q}2%1Z(&$FWI$RJKS{uvBq7!jVA zrMv7!H=-bgUz(G!zwn7XU`qO3U_AY1HLogVws5^PU$L=vg}4X}ykI-jW^*LHK&ZNa zJH5BVq{AdS)PgI3+(cE7kbe!)>{;`!GCjhXOf zJF(>g9qY8B)zt^}P3+$W9BhztB}df4a#*}R3F7ZkYSBn`S5>mvar=-XXR=yh)`8mR60Z%529og?+KEro9A$FWR~<-ea!i4(n?4SvsuxfWL@ff{Z`rGCO&H zg<*dCR}H-=@#Esg0<+wSZ|*h0PAZRH_>!i=nx;J%G^5>jTZ0PPHPk|N@_g`at;{N< zX^OD;7s8M0HsH*Y%cw^+t1ZFS>#@+>>j$U##d+2*|9Nmb?>INriFduQMNyDvg4Wgd zJy8l?;fyo#D&{vB4h}6b_KpBrb!*48a7EhU$YY=TY94RTbEJHn0a@^Q-Bua;E`P4$ zb@cltF*iyY$Lj|tPhkrVOx5?LR!sM|yiPXWum623R9YYSwDd6(;Hqyk9OL!|pZ1uSrbL+Ns$*E!G{mpwjD@EYT2Owg|c~Uyf~_k+4VCqP>w= zR9r6J#-UK*lw)$FgJZL!#vnu6p*#lRK?GOI4g_JUmN*p5WsM61X){LSu@P*KZWh12#zVRkEzPkH~|@Ya-?O>b+5xP;J< zm&b%5TghDoe|hK3uJ!ia`Qhe5EKok^)lu+TcrIRSg!x(6oCQX!9aIZ@!%+B}C@yi~ z(#U^V)$#A{sWR{IxZn31Gyha1j}6v*WeZlBNMlyE3a*BU@qXzQrYD`G5tf5$EXt{| zMZT44ehH$6*ufZlQNAxJukUPKr~$d0>2Uug`(q}FucIZo^b@u2^Dg-xe{1q0;niO@ zGiEFZMPt9uHDLRW$~i{)%gPtamQq1h77mUXyhdw#sL05_z)66&to`n}5L1t?0p42j z4d&U|5f#}t_x(zy3c|gGjFxF1#Rrh;gKk#tXPd$Ky)uq!4c*4H<>5mTxJI*0RK|I| z-m<13rwb&b(->?@eL?=Y6z=s;BwF1W&@PV!ld(ER6bJw9woD^yACzoOMZvLP>0CR| zEWh-6E&XyU=caXi1(aJWItR*(L+5r5)+*7{+~%bl_SbtMuo>N(tfs-%?44==JOOG2 z^|*ZdP~P>XHfGcen<;?O%XOYsC;|qvGVa(d8<<6<-c1B|H`W$4?OknrEA*CekGpbX**XZ z?>0y;maJP4yDX7Ge%`kk!Y?PYl{S^6JKkiPr5n!Z_Hw)H;(UhaFvV|A?wUO-O%OKI zPvPs$n-)`jplJJ->5K0<>|gcezst7pNr(_(NSMTKEBEP_rSIZakf^7tpUXO@geCy- ChNKYy delta 324 zcmZo>zRxs4rC!a`#WAE}&fA;Oe9a01tq(IV&)x7}^=#ZP2d@dM_rBoy_J3Yamtwkr zrYIu=0*EhNwJJ)!{^yENn>E%SycJnq>+Lz4&-iJh%;eCk0!}vb`MRW4w4HY;+D|tB z60l)+Df_LUDV3Wxt@WDn?xpR*4AJZYpY`^M|Jmw~D9-FZ<#;EE_jb~i?^0E#Z8z#4 zIAF19QHb5=xt}ap-}Y}Z|9?gO?zH7P4JVECmIlkb@ZKC+w{?2O`&Cmt_ng*U6n=$w z<`@6V9kagpyYcE6az{S0&RN;_J?&EeU$)<7k9B49xi38BjXV47*x@Zxh2`ow|BGI) zb__matS)(8#mCn1cvSiFV*dB6JIa1-x?mKtt=`8gTXI%-_jzW7cNyy6ah?-7>OJA# Q|9Ft7r>mdKI;Vst033&ppa1{> diff --git a/tests/snapshots/nanox/test_dashboard/00001.png b/tests/snapshots/nanox/test_dashboard/00001.png index be36adcfaa71ccd4c37fcd464033d9b75c2a2e01..9ef3efce75208c53769482d9a68de0f4c47e9bda 100644 GIT binary patch delta 360 zcmcc5)XY3VrQXZa#WAE}&fA-Tn+_@Pv?d-aRDVsC;|qvGVa(d8<<6<-c1B|H`W$4?OknrEA*CekGpbX**XZ z?>0y;maJP4yDX7Ge%`kk!Y?PYl{S^6JKkiPr5n!Z_Hw)H;(UhaFvV|A?wUO-O%OKI zPvPs$n-)`jplJJ->5K0<>|gcezst7pNr(_(NSMTKEBEP_rSIZakf^7tpUXO@geCy- ChNKYy delta 324 zcmZo>zRxs4rC!a`#WAE}&fA;Oe9a01tq(IV&)x7}^=#ZP2d@dM_rBoy_J3Yamtwkr zrYIu=0*EhNwJJ)!{^yENn>E%SycJnq>+Lz4&-iJh%;eCk0!}vb`MRW4w4HY;+D|tB z60l)+Df_LUDV3Wxt@WDn?xpR*4AJZYpY`^M|Jmw~D9-FZ<#;EE_jb~i?^0E#Z8z#4 zIAF19QHb5=xt}ap-}Y}Z|9?gO?zH7P4JVECmIlkb@ZKC+w{?2O`&Cmt_ng*U6n=$w z<`@6V9kagpyYcE6az{S0&RN;_J?&EeU$)<7k9B49xi38BjXV47*x@Zxh2`ow|BGI) zb__matS)(8#mCn1cvSiFV*dB6JIa1-x?mKtt=`8gTXI%-_jzW7cNyy6ah?-7>OJA# Q|9Ft7r>mdKI;Vst033&ppa1{> diff --git a/tests/snapshots/stax/test_dashboard/00001.png b/tests/snapshots/stax/test_dashboard/00001.png index eecc459e996fdaf2cbd6fc8954cdcfa8dd89258a..78347efca84d6a4adc805736dfd97832267c7ab9 100644 GIT binary patch delta 7922 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 V))Ra076^D*n%UmO|LOMR{{U{ND^LIc From 6f50e7a18c20b067345498a68a925b1f2c03d53c Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 3 Dec 2024 18:06:34 +0100 Subject: [PATCH 55/57] Add note about nonce reuse in the implementation of compute_rand_i_j --- src/musig/musig_sessions.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/musig/musig_sessions.c b/src/musig/musig_sessions.c index 32aa03507..60bd10fb8 100644 --- a/src/musig/musig_sessions.c +++ b/src/musig/musig_sessions.c @@ -75,6 +75,11 @@ void compute_rand_i_j(const musig_psbt_session_t *psbt_session, int i, int j, uint8_t out[static 32]) { + // It is extremely important that different choices of the root of randomness, i and j always + // produce a different result in out. + // Failure would be catastrophic as it would cause nonce reuse, which in MuSig2 allows attackers + // to recover the private key. + cx_sha256_t hash_context; cx_sha256_init(&hash_context); crypto_hash_update(&hash_context.header, psbt_session->_rand_root, CX_SHA256_SIZE); From 64897008ab6643c1cb698fcc6b9abb771f9e4540 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 9 Dec 2024 13:58:57 +0100 Subject: [PATCH 56/57] Nits from PR review --- doc/bitcoin.md | 2 +- doc/musig.md | 6 +++--- src/common/wallet.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/bitcoin.md b/doc/bitcoin.md index 77d5531fa..099ef316b 100644 --- a/doc/bitcoin.md +++ b/doc/bitcoin.md @@ -233,7 +233,7 @@ For a registered wallet, the hmac must be correct. For a default wallet, `hmac` must be equal to 32 bytes `0`. -The data yielded has with a ``, represented as a bitcoin-style varint; the rest of the message depends on the value of ``, as specified in the following subsections. +The data yielded begins with ``, represented as a bitcoin-style varint; the rest of the message depends on the value of ``, as specified in the following subsections. ##### If `` is at most 65535 diff --git a/doc/musig.md b/doc/musig.md index f3356aa89..f2dbdbdaf 100644 --- a/doc/musig.md +++ b/doc/musig.md @@ -73,7 +73,7 @@ Storing the session in persistent memory only at the end of Phase 1, and deletin #### Security of synthetic randomness -Generating $rand_{i, j}$ synthetically is not a problem, since the $rand\_root$ value is kept secret and never leaves the device. This ensures that all the values produced for different $i$ and $j$ not predictable for an attacker. +Generating $rand_{i, j}$ synthetically is not a problem, since the $rand\_root$ value is kept secret and never leaves the device. This ensures that all the values produced for different $i$ and $j$ are not predictable for an attacker. #### Malleability of the PSBT If the optional parameters are passed to the _NonceGen_ function, they will depend on the transaction data present in the PSBT. Therefore, there is no guarantee that they will be unchanged the next time the PSBT is provided. @@ -82,6 +82,6 @@ However, that does not constitute a security risk, as those parameters are only ### Generalization to multiple PSBT signing sessions -The approach described above assumes that no attempt to sign a PSBT containing for a wallet policy containing `musig()` keys is initiated while a session is already in progress. +The approach described above assumes that no attempt to sign a PSBT for a wallet policy containing `musig()` keys is initiated while a session is already in progress. -It is possible to generalize this to an arbitrary number of parallel signing sessions. Each session could be identified by a `psbt_session_id` computed by hashing together the transaction hashes, \ No newline at end of file +In order to generalize this to an arbitrary number of parallel signing sessions, one can identify each signing session with a `psbt_session_id`. Such `psbt_session_id` should deterministically depend on the transaction being signed (ignoring all the other PSBT fields), and the wallet policy being signed. In praticular, the computed `psbt_session_id` should be identical between Round 1 and Round 2 of the protocol. Note that malicious collisions of the `psbt_session_id` (for example by tampering with some details of the PSBT, like the SIGHASH flags) _are_ possible, but they do not constitute a security risk. diff --git a/src/common/wallet.c b/src/common/wallet.c index 8954af963..1f9434dd9 100644 --- a/src/common/wallet.c +++ b/src/common/wallet.c @@ -511,9 +511,9 @@ static int parse_keyexpr(buffer_t *in_buf, if (n_musig_keys < 2) { return WITH_ERROR(-1, "musig must have at least 2 key indexes"); } - if (n_musig_keys > MAX_PUBKEYS_PER_MUSIG) { - return WITH_ERROR(-1, "Too many keys in musig"); - } + + // sanity check; the loop above should never exit with too many keys + LEDGER_ASSERT(n_musig_keys <= MAX_PUBKEYS_PER_MUSIG, "Too many keys in musig"); // allocate musig structures From 2d22ebe381616864d7e0c1515424eee244cf5f4a Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 10 Dec 2024 13:38:52 +0100 Subject: [PATCH 57/57] Apply suggestions from code review Co-authored-by: lpascal-ledger --- test_utils/musig2.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test_utils/musig2.py b/test_utils/musig2.py index 5f9a98bc1..0de229573 100644 --- a/test_utils/musig2.py +++ b/test_utils/musig2.py @@ -288,7 +288,7 @@ def __init__(self, key: KeyPlaceholder, tree=Optional[Tree]): self.tree: Optional[Tree] = tree @classmethod - def from_string(cls, input_string): + def from_string(cls, input_string: str) -> "TrDescriptorTemplate": parser = cls.Parser(input_string.replace("/**", "/<0;1>/*")) return parser.parse() @@ -298,7 +298,7 @@ def __init__(self, input): self.index = 0 self.length = len(input) - def parse(self): + def parse(self) -> "TrDescriptorTemplate": if self.input.startswith('tr('): self.consume('tr(') key = self.parse_keyplaceholder() @@ -312,7 +312,7 @@ def parse(self): raise Exception( "Syntax error: Input does not start with 'tr('") - def parse_keyplaceholder(self): + def parse_keyplaceholder(self) -> KeyPlaceholder: if self.peek() == '@': self.consume('@') key_index = self.parse_num() @@ -357,7 +357,7 @@ def parse_script(self) -> str: self.index += 1 return self.input[start:self.index] - def parse_key_indexes(self): + def parse_key_indexes(self) -> List[int]: nums = [] self.consume('@') nums.append(self.parse_num()) @@ -366,13 +366,13 @@ def parse_key_indexes(self): nums.append(self.parse_num()) return nums - def parse_num(self): + def parse_num(self) -> int: start = self.index while self.index < self.length and self.input[self.index].isdigit(): self.index += 1 return int(self.input[start:self.index]) - def consume(self, char): + def consume(self, char: str) -> None: if self.input[self.index:self.index+len(char)] == char: self.index += len(char) else: