From 567537cd034d80842bed2d36ffccf588aa10930c Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Sat, 13 Dec 2014 20:33:49 +0100 Subject: [PATCH] update to new multisig api --- firmware/crypto.c | 16 +++++- firmware/crypto.h | 5 +- firmware/fsm.c | 2 +- firmware/protob/types.options | 4 +- firmware/protob/types.pb.c | 13 +++-- firmware/protob/types.pb.h | 92 ++++++++++++++++++++--------------- firmware/signing.c | 2 +- firmware/transaction.c | 31 ++++-------- trezor-common | 2 +- trezor-crypto | 2 +- 10 files changed, 98 insertions(+), 71 deletions(-) diff --git a/firmware/crypto.c b/firmware/crypto.c index 40c219b4d..04cb9549d 100644 --- a/firmware/crypto.c +++ b/firmware/crypto.c @@ -24,6 +24,7 @@ #include "pbkdf2.h" #include "aes.h" #include "hmac.h" +#include "bip32.h" uint32_t ser_length(uint32_t len, uint8_t *out) { @@ -252,11 +253,22 @@ int cryptoMessageDecrypt(curve_point *nonce, uint8_t *payload, pb_size_t payload return 0; } -int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey, uint32_t pubkey_len) +uint8_t *cryptoHDNodePathToPubkey(const HDNodePathType *hdnodepath) +{ + static HDNode node; + hdnode_from_xpub(hdnodepath->node.depth, hdnodepath->node.fingerprint, hdnodepath->node.child_num, hdnodepath->node.chain_code.bytes, hdnodepath->node.public_key.bytes, &node); + uint32_t i; + for (i = 0; i < hdnodepath->address_n_count; i++) { + hdnode_public_ckd(&node, hdnodepath->address_n[i]); + } + return node.public_key; +} + +int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey) { int i; for (i = 0; i < multisig->pubkeys_count; i++) { - if (multisig->pubkeys[i].size == pubkey_len && memcmp(multisig->pubkeys[i].bytes, pubkey, pubkey_len) == 0) { + if (memcmp(cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])), pubkey, 33) == 0) { return i; } } diff --git a/firmware/crypto.h b/firmware/crypto.h index 9435f0c2f..7afa10545 100644 --- a/firmware/crypto.h +++ b/firmware/crypto.h @@ -39,6 +39,9 @@ int cryptoMessageEncrypt(curve_point *pubkey, const uint8_t *msg, pb_size_t msg_ int cryptoMessageDecrypt(curve_point *nonce, uint8_t *payload, pb_size_t payload_len, const uint8_t *hmac, pb_size_t hmac_len, const uint8_t *privkey, uint8_t *msg, pb_size_t *msg_len, bool *display_only, bool *signing, uint8_t *address_raw); -int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey, uint32_t pubkey_len); +uint8_t *cryptoHDNodePathToPubkey(const HDNodePathType *hdnodepath); + +int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey); + #endif diff --git a/firmware/fsm.c b/firmware/fsm.c index 89c36e799..185160568 100644 --- a/firmware/fsm.c +++ b/firmware/fsm.c @@ -503,7 +503,7 @@ void fsm_msgGetAddress(GetAddress *msg) fsm_deriveKey(node, msg->address_n, msg->address_n_count); if (msg->has_multisig) { - if (cryptoMultisigPubkeyIndex(&(msg->multisig), node->public_key, 33) < 0) { + if (cryptoMultisigPubkeyIndex(&(msg->multisig), node->public_key) < 0) { fsm_sendFailure(FailureType_Failure_Other, "Pubkey not found in multisig script"); layoutHome(); return; diff --git a/firmware/protob/types.options b/firmware/protob/types.options index 8832018ba..ec464a60f 100644 --- a/firmware/protob/types.options +++ b/firmware/protob/types.options @@ -2,6 +2,8 @@ HDNodeType.chain_code max_size:32 HDNodeType.private_key max_size:32 HDNodeType.public_key max_size:33 +HDNodePathType.address_n max_count:8 + CoinType.coin_name max_size:17 CoinType.coin_shortcut max_size:9 @@ -23,5 +25,5 @@ TxRequestDetailsType.tx_hash max_size:32 TxRequestSerializedType.signature max_size:73 TxRequestSerializedType.serialized_tx max_size:2048 -MultisigRedeemScriptType.pubkeys max_count:15 max_size:33 +MultisigRedeemScriptType.pubkeys max_count:15 MultisigRedeemScriptType.signatures max_count:15 max_size:73 diff --git a/firmware/protob/types.pb.c b/firmware/protob/types.pb.c index 5e6e1298a..ab937186c 100644 --- a/firmware/protob/types.pb.c +++ b/firmware/protob/types.pb.c @@ -21,6 +21,12 @@ const pb_field_t HDNodeType_fields[7] = { PB_LAST_FIELD }; +const pb_field_t HDNodePathType_fields[3] = { + PB_FIELD( 1, MESSAGE , REQUIRED, STATIC , FIRST, HDNodePathType, node, node, &HDNodeType_fields), + PB_FIELD( 2, UINT32 , REPEATED, STATIC , OTHER, HDNodePathType, address_n, node, 0), + PB_LAST_FIELD +}; + const pb_field_t CoinType_fields[5] = { PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, CoinType, coin_name, coin_name, 0), PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, CoinType, coin_shortcut, coin_name, 0), @@ -30,7 +36,7 @@ const pb_field_t CoinType_fields[5] = { }; const pb_field_t MultisigRedeemScriptType_fields[4] = { - PB_FIELD( 1, BYTES , REPEATED, STATIC , FIRST, MultisigRedeemScriptType, pubkeys, pubkeys, 0), + PB_FIELD( 1, MESSAGE , REPEATED, STATIC , FIRST, MultisigRedeemScriptType, pubkeys, pubkeys, &HDNodePathType_fields), PB_FIELD( 2, BYTES , REPEATED, STATIC , OTHER, MultisigRedeemScriptType, signatures, pubkeys, 0), PB_FIELD( 3, UINT32 , OPTIONAL, STATIC , OTHER, MultisigRedeemScriptType, m, signatures, 0), PB_LAST_FIELD @@ -47,11 +53,12 @@ const pb_field_t TxInputType_fields[8] = { PB_LAST_FIELD }; -const pb_field_t TxOutputType_fields[5] = { +const pb_field_t TxOutputType_fields[6] = { PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, TxOutputType, address, address, 0), PB_FIELD( 2, UINT32 , REPEATED, STATIC , OTHER, TxOutputType, address_n, address, 0), PB_FIELD( 3, UINT64 , REQUIRED, STATIC , OTHER, TxOutputType, amount, address_n, 0), PB_FIELD( 4, ENUM , REQUIRED, STATIC , OTHER, TxOutputType, script_type, amount, 0), + PB_FIELD( 5, MESSAGE , OPTIONAL, STATIC , OTHER, TxOutputType, multisig, script_type, &MultisigRedeemScriptType_fields), PB_LAST_FIELD }; @@ -147,7 +154,7 @@ const pb_extension_type_t wire_debug_out = { * numbers or field sizes that are larger than what can fit in 8 or 16 bit * field descriptors. */ -PB_STATIC_ASSERT((pb_membersize(TxInputType, multisig) < 65536 && pb_membersize(TransactionType, inputs[0]) < 65536 && pb_membersize(TransactionType, bin_outputs[0]) < 65536 && pb_membersize(TransactionType, outputs[0]) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_HDNodeType_CoinType_MultisigRedeemScriptType_TxInputType_TxOutputType_TxOutputBinType_TransactionType_TxRequestDetailsType_TxRequestSerializedType) +PB_STATIC_ASSERT((pb_membersize(HDNodePathType, node) < 65536 && pb_membersize(MultisigRedeemScriptType, pubkeys[0]) < 65536 && pb_membersize(TxInputType, multisig) < 65536 && pb_membersize(TxOutputType, multisig) < 65536 && pb_membersize(TransactionType, inputs[0]) < 65536 && pb_membersize(TransactionType, bin_outputs[0]) < 65536 && pb_membersize(TransactionType, outputs[0]) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_HDNodeType_HDNodePathType_CoinType_MultisigRedeemScriptType_TxInputType_TxOutputType_TxOutputBinType_TransactionType_TxRequestDetailsType_TxRequestSerializedType) #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) diff --git a/firmware/protob/types.pb.h b/firmware/protob/types.pb.h index d8c4ffbcc..59fea4957 100644 --- a/firmware/protob/types.pb.h +++ b/firmware/protob/types.pb.h @@ -30,7 +30,8 @@ typedef enum _FailureType { typedef enum _OutputScriptType { OutputScriptType_PAYTOADDRESS = 0, - OutputScriptType_PAYTOSCRIPTHASH = 1 + OutputScriptType_PAYTOSCRIPTHASH = 1, + OutputScriptType_PAYTOMULTISIG = 2 } OutputScriptType; typedef enum _InputScriptType { @@ -93,19 +94,6 @@ typedef struct _HDNodeType { HDNodeType_public_key_t public_key; } HDNodeType; -typedef PB_BYTES_ARRAY_T(33) MultisigRedeemScriptType_pubkeys_t; - -typedef PB_BYTES_ARRAY_T(73) MultisigRedeemScriptType_signatures_t; - -typedef struct _MultisigRedeemScriptType { - pb_size_t pubkeys_count; - MultisigRedeemScriptType_pubkeys_t pubkeys[15]; - pb_size_t signatures_count; - MultisigRedeemScriptType_signatures_t signatures[15]; - bool has_m; - uint32_t m; -} MultisigRedeemScriptType; - typedef PB_BYTES_ARRAY_T(520) TxOutputBinType_script_pubkey_t; typedef struct _TxOutputBinType { @@ -113,15 +101,6 @@ typedef struct _TxOutputBinType { TxOutputBinType_script_pubkey_t script_pubkey; } TxOutputBinType; -typedef struct _TxOutputType { - bool has_address; - char address[35]; - pb_size_t address_n_count; - uint32_t address_n[8]; - uint64_t amount; - OutputScriptType script_type; -} TxOutputType; - typedef PB_BYTES_ARRAY_T(32) TxRequestDetailsType_tx_hash_t; typedef struct _TxRequestDetailsType { @@ -144,6 +123,23 @@ typedef struct _TxRequestSerializedType { TxRequestSerializedType_serialized_tx_t serialized_tx; } TxRequestSerializedType; +typedef struct _HDNodePathType { + HDNodeType node; + pb_size_t address_n_count; + uint32_t address_n[8]; +} HDNodePathType; + +typedef PB_BYTES_ARRAY_T(73) MultisigRedeemScriptType_signatures_t; + +typedef struct _MultisigRedeemScriptType { + pb_size_t pubkeys_count; + HDNodePathType pubkeys[15]; + pb_size_t signatures_count; + MultisigRedeemScriptType_signatures_t signatures[15]; + bool has_m; + uint32_t m; +} MultisigRedeemScriptType; + typedef PB_BYTES_ARRAY_T(32) TxInputType_prev_hash_t; typedef PB_BYTES_ARRAY_T(1650) TxInputType_script_sig_t; @@ -163,6 +159,17 @@ typedef struct _TxInputType { MultisigRedeemScriptType multisig; } TxInputType; +typedef struct _TxOutputType { + bool has_address; + char address[35]; + pb_size_t address_n_count; + uint32_t address_n[8]; + uint64_t amount; + OutputScriptType script_type; + bool has_multisig; + MultisigRedeemScriptType multisig; +} TxOutputType; + typedef struct _TransactionType { bool has_version; uint32_t version; @@ -192,19 +199,21 @@ extern const InputScriptType TxInputType_script_type_default; /* Initializer values for message structs */ #define HDNodeType_init_default {0, 0, 0, {0, {0}}, false, {0, {0}}, false, {0, {0}}} +#define HDNodePathType_init_default {HDNodeType_init_default, 0, {0, 0, 0, 0, 0, 0, 0, 0}} #define CoinType_init_default {false, "", false, "", false, 0, false, 0} -#define MultisigRedeemScriptType_init_default {0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, false, 0} +#define MultisigRedeemScriptType_init_default {0, {HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, false, 0} #define TxInputType_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, 0, false, {0, {0}}, false, 4294967295u, false, InputScriptType_SPENDADDRESS, false, MultisigRedeemScriptType_init_default} -#define TxOutputType_init_default {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0} +#define TxOutputType_init_default {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0, false, MultisigRedeemScriptType_init_default} #define TxOutputBinType_init_default {0, {0, {0}}} #define TransactionType_init_default {false, 0, 0, {TxInputType_init_default}, 0, {TxOutputBinType_init_default}, false, 0, 0, {TxOutputType_init_default}, false, 0, false, 0} #define TxRequestDetailsType_init_default {false, 0, false, {0, {0}}} #define TxRequestSerializedType_init_default {false, 0, false, {0, {0}}, false, {0, {0}}} #define HDNodeType_init_zero {0, 0, 0, {0, {0}}, false, {0, {0}}, false, {0, {0}}} +#define HDNodePathType_init_zero {HDNodeType_init_zero, 0, {0, 0, 0, 0, 0, 0, 0, 0}} #define CoinType_init_zero {false, "", false, "", false, 0, false, 0} -#define MultisigRedeemScriptType_init_zero {0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, false, 0} +#define MultisigRedeemScriptType_init_zero {0, {HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, false, 0} #define TxInputType_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, 0, false, {0, {0}}, false, 0, false, (InputScriptType)0, false, MultisigRedeemScriptType_init_zero} -#define TxOutputType_init_zero {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0} +#define TxOutputType_init_zero {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0, false, MultisigRedeemScriptType_init_zero} #define TxOutputBinType_init_zero {0, {0, {0}}} #define TransactionType_init_zero {false, 0, 0, {TxInputType_init_zero}, 0, {TxOutputBinType_init_zero}, false, 0, 0, {TxOutputType_init_zero}, false, 0, false, 0} #define TxRequestDetailsType_init_zero {false, 0, false, {0, {0}}} @@ -221,20 +230,18 @@ extern const InputScriptType TxInputType_script_type_default; #define HDNodeType_chain_code_tag 4 #define HDNodeType_private_key_tag 5 #define HDNodeType_public_key_tag 6 -#define MultisigRedeemScriptType_pubkeys_tag 1 -#define MultisigRedeemScriptType_signatures_tag 2 -#define MultisigRedeemScriptType_m_tag 3 #define TxOutputBinType_amount_tag 1 #define TxOutputBinType_script_pubkey_tag 2 -#define TxOutputType_address_tag 1 -#define TxOutputType_address_n_tag 2 -#define TxOutputType_amount_tag 3 -#define TxOutputType_script_type_tag 4 #define TxRequestDetailsType_request_index_tag 1 #define TxRequestDetailsType_tx_hash_tag 2 #define TxRequestSerializedType_signature_index_tag 1 #define TxRequestSerializedType_signature_tag 2 #define TxRequestSerializedType_serialized_tx_tag 3 +#define HDNodePathType_node_tag 1 +#define HDNodePathType_address_n_tag 2 +#define MultisigRedeemScriptType_pubkeys_tag 1 +#define MultisigRedeemScriptType_signatures_tag 2 +#define MultisigRedeemScriptType_m_tag 3 #define TxInputType_address_n_tag 1 #define TxInputType_prev_hash_tag 2 #define TxInputType_prev_index_tag 3 @@ -242,6 +249,11 @@ extern const InputScriptType TxInputType_script_type_default; #define TxInputType_sequence_tag 5 #define TxInputType_script_type_tag 6 #define TxInputType_multisig_tag 7 +#define TxOutputType_address_tag 1 +#define TxOutputType_address_n_tag 2 +#define TxOutputType_amount_tag 3 +#define TxOutputType_script_type_tag 4 +#define TxOutputType_multisig_tag 5 #define TransactionType_version_tag 1 #define TransactionType_inputs_tag 2 #define TransactionType_bin_outputs_tag 3 @@ -256,10 +268,11 @@ extern const InputScriptType TxInputType_script_type_default; /* Struct field encoding specification for nanopb */ extern const pb_field_t HDNodeType_fields[7]; +extern const pb_field_t HDNodePathType_fields[3]; extern const pb_field_t CoinType_fields[5]; extern const pb_field_t MultisigRedeemScriptType_fields[4]; extern const pb_field_t TxInputType_fields[8]; -extern const pb_field_t TxOutputType_fields[5]; +extern const pb_field_t TxOutputType_fields[6]; extern const pb_field_t TxOutputBinType_fields[3]; extern const pb_field_t TransactionType_fields[8]; extern const pb_field_t TxRequestDetailsType_fields[3]; @@ -267,12 +280,13 @@ extern const pb_field_t TxRequestSerializedType_fields[4]; /* Maximum encoded size of messages (where known) */ #define HDNodeType_size 121 +#define HDNodePathType_size 171 #define CoinType_size 47 -#define MultisigRedeemScriptType_size 1656 -#define TxInputType_size 3412 -#define TxOutputType_size 102 +#define MultisigRedeemScriptType_size 3741 +#define TxInputType_size 5497 +#define TxOutputType_size 3846 #define TxOutputBinType_size 534 -#define TransactionType_size 4080 +#define TransactionType_size 9910 #define TxRequestDetailsType_size 40 #define TxRequestSerializedType_size 2132 diff --git a/firmware/signing.c b/firmware/signing.c index 6b0411468..565cd4f19 100644 --- a/firmware/signing.c +++ b/firmware/signing.c @@ -379,7 +379,7 @@ void signing_txack(TransactionType *tx) return; } // fill in the signature - int pubkey_idx = cryptoMultisigPubkeyIndex(&(input.multisig), pubkey, 33); + int pubkey_idx = cryptoMultisigPubkeyIndex(&(input.multisig), pubkey); if (pubkey_idx < 0) { fsm_sendFailure(FailureType_Failure_Other, "Pubkey not found in multisig script"); signing_abort(); diff --git a/firmware/transaction.c b/firmware/transaction.c index 63be253ce..a3a9103d1 100644 --- a/firmware/transaction.c +++ b/firmware/transaction.c @@ -142,20 +142,13 @@ uint32_t compile_script_multisig(const MultisigRedeemScriptType *multisig, uint8 if (out) { out[r] = 0x50 + m; r++; for (i = 0; i < n; i++) { - r += op_push(multisig->pubkeys[i].size, out + r); - memcpy(out + r, multisig->pubkeys[i].bytes, multisig->pubkeys[i].size); r += multisig->pubkeys[i].size; + out[r] = 33; r++; // OP_PUSH 33 + memcpy(out + r, cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])), 33); r += 33; } out[r] = 0x50 + n; r++; out[r] = 0xAE; r++; // OP_CHECKMULTISIG } else { - r++; - uint8_t dummy[8]; - for (i = 0; i < n; i++) { - r += op_push(multisig->pubkeys[i].size, dummy); - r += multisig->pubkeys[i].size; - } - r++; - r++; + r = 1 + 34 * n + 2; } return r; } @@ -171,19 +164,15 @@ uint32_t compile_script_multisig_hash(const MultisigRedeemScriptType *multisig, SHA256_CTX ctx; sha256_Init(&ctx); - uint8_t d, dummy[8]; - d = 0x50 + m; - sha256_Update(&ctx, &d, 1); - uint32_t i, r; + uint8_t d; + d = 0x50 + m; sha256_Update(&ctx, &d, 1); + uint32_t i; for (i = 0; i < n; i++) { - r = op_push(multisig->pubkeys[i].size, dummy); - sha256_Update(&ctx, dummy, r); - sha256_Update(&ctx, multisig->pubkeys[i].bytes, multisig->pubkeys[i].size); + d = 33; sha256_Update(&ctx, &d, 1); // OP_PUSH 33 + sha256_Update(&ctx, cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])), 33); } - d = 0x50 + n; - sha256_Update(&ctx, &d, 1); - d = 0xAE; - sha256_Update(&ctx, &d, 1); + d = 0x50 + n; sha256_Update(&ctx, &d, 1); + d = 0xAE; sha256_Update(&ctx, &d, 1); sha256_Final(hash, &ctx); diff --git a/trezor-common b/trezor-common index 40b3cb414..94d17ef8b 160000 --- a/trezor-common +++ b/trezor-common @@ -1 +1 @@ -Subproject commit 40b3cb414864f970d627651f8be0669be95c5efc +Subproject commit 94d17ef8bc56d7c0e6ddfed39e84987543259e05 diff --git a/trezor-crypto b/trezor-crypto index b4cdba848..10a92c3c6 160000 --- a/trezor-crypto +++ b/trezor-crypto @@ -1 +1 @@ -Subproject commit b4cdba8489201e623b948469609a48495f2eeed2 +Subproject commit 10a92c3c6276d5b1955331b7a33ebe9d6a32c37e