From bde370068efd47f5cdd434026513c55eef3f57e1 Mon Sep 17 00:00:00 2001 From: highlander Date: Fri, 31 Jul 2026 17:08:12 -0300 Subject: [PATCH 1/6] test: GetAddress returns BIP-86 taproot addresses Drives the emulator through the full GetAddress path for SPENDTAPROOT -- fsm_msgGetAddress, path_mismatched's m/86' branch, compute_address, the BIP-86 tweak and bech32m encoding -- none of which the firmware's C unit tests reach. Expected values are the three official BIP-86 vectors. BIP-86 publishes them against the "abandon abandon ... about" mnemonic, which is exactly what setup_mnemonic_abandon loads, so these are the spec's constants and not values our implementation produced. Verified against a locally built emulator: 1 passed. Also mutation checked -- flipping one character of the first expected address makes it fail, so the assertions are not vacuous. NOTE: gated at 7.16.0 via TAPROOT_FIRMWARE_VERSION. develop is currently 7.15.0, so this SKIPS until the project version bumps. A gate that is never reached is a test that is silently green forever -- keep the constant in step with CMakeLists.txt. --- tests/test_msg_getaddress_taproot.py | 68 ++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tests/test_msg_getaddress_taproot.py diff --git a/tests/test_msg_getaddress_taproot.py b/tests/test_msg_getaddress_taproot.py new file mode 100644 index 00000000..1c08b239 --- /dev/null +++ b/tests/test_msg_getaddress_taproot.py @@ -0,0 +1,68 @@ +# This file is part of the KeepKey project. +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the License along with this library. +# If not, see . + +import common +import unittest + +from keepkeylib import types_pb2 as proto +from keepkeylib.tools import parse_path + + +# Version in which SPENDTAPROOT support lands. Keep this in step with +# CMakeLists.txt: if the firmware version is below it these tests SKIP, so a +# value that is never reached makes them silently green forever. +TAPROOT_FIRMWARE_VERSION = "7.16.0" + + +class TestMsgGetaddressTaproot(common.KeepKeyTest): + + def test_taproot_bip86_vectors(self): + """Official BIP-86 test vectors. + + https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki + + BIP-86 publishes these against the "abandon abandon ... about" + mnemonic, which is exactly what setup_mnemonic_abandon loads. The + expected addresses are therefore the spec's own constants, not values + this implementation produced -- the comparison is against independent + ground truth. + """ + self.requires_firmware(TAPROOT_FIRMWARE_VERSION) + self.setup_mnemonic_abandon() + self.client.clear_session() + + # Account 0, first receiving address + self.assertEqual( + self.client.get_address( + "Bitcoin", parse_path("86'/0'/0'/0/0"), False, None, + script_type=proto.SPENDTAPROOT), + 'bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr') + + # Account 0, second receiving address + self.assertEqual( + self.client.get_address( + "Bitcoin", parse_path("86'/0'/0'/0/1"), False, None, + script_type=proto.SPENDTAPROOT), + 'bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh') + + # Account 0, first change address + self.assertEqual( + self.client.get_address( + "Bitcoin", parse_path("86'/0'/0'/1/0"), False, None, + script_type=proto.SPENDTAPROOT), + 'bc1p3qkhfews2uk44qtvauqyr2ttdsw7svhkl9nkm9s9c3x4ax5h60wqwruhk7') + + +if __name__ == '__main__': + unittest.main() From 50b107dd50beae81bc6132a06075b403eb72ef20 Mon Sep 17 00:00:00 2001 From: highlander Date: Fri, 31 Jul 2026 20:51:11 -0300 Subject: [PATCH 2/6] test: cross-check P2TR signing against an independent implementation Spends a P2TR input on the emulator and compares the 64-byte witness byte for byte against a signature computed outside the firmware. The expected value is not a round trip through our own verifier -- that would pass even if the device committed to the wrong transaction. It comes from a standalone Python implementation of BIP-340/341 written from the specs, keyed from BIP-86's own published xprv for m/86'/0'/0'/0/0, and self-checked against BIP-86's published internal and output keys before being used. BIP-340 signing is deterministic given aux_rand, so equality is meaningful. This caught a real bug. BIP-143 hashes prevouts/sequences/outputs with DOUBLE sha256 (hasher_sign is HASHER_SHA2D for Bitcoin) while BIP-341 specifies SINGLE sha256, so reusing the BIP-143 accumulators produced a cryptographically valid signature over the wrong commitment -- exactly the failure a self-consistent test cannot see. Includes a synthetic prev-tx fixture in txcache so the test runs offline. --- tests/test_msg_signtx_taproot.py | 82 +++++++++++++++++++ ...adfd08711293e15085f77cd27628be0a6ee37.json | 24 ++++++ 2 files changed, 106 insertions(+) create mode 100644 tests/test_msg_signtx_taproot.py create mode 100644 tests/txcache/insight_bitcoin_tx_6e32033911982f7550ab1d26232adfd08711293e15085f77cd27628be0a6ee37.json diff --git a/tests/test_msg_signtx_taproot.py b/tests/test_msg_signtx_taproot.py new file mode 100644 index 00000000..369f1e9a --- /dev/null +++ b/tests/test_msg_signtx_taproot.py @@ -0,0 +1,82 @@ +# This file is part of the KeepKey project. +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the License along with this library. +# If not, see . + +import common +import unittest + +from binascii import hexlify, unhexlify + +from common import KeepKeyTest +from keepkeylib import messages_pb2 as proto +from keepkeylib import types_pb2 as proto_types +from keepkeylib.tools import parse_path +from keepkeylib.tx_api import TxApiBitcoin + + +# Keep in step with CMakeLists.txt; see test_msg_getaddress_taproot.py. +TAPROOT_FIRMWARE_VERSION = "7.16.0" + +# Synthetic prev tx paying 100000 sat to the BIP-86 first receiving address of +# the "abandon abandon ... about" mnemonic +# (bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr). +# The fixture lives in tests/txcache and was produced together with the +# expected witness below by an independent Python implementation of +# BIP-340/341, keyed from BIP-86's own published xprv. +PREV_TXID = "6e32033911982f7550ab1d26232adfd08711293e15085f77cd27628be0a6ee37" +IN_AMOUNT = 100000 +OUT_AMOUNT = 90000 +OUT_ADDRESS = "1BitcoinEaterAddressDontSendf59kuE" + +EXPECTED_WITNESS = ( + "afe221b16d648a1ad7329f9765930732380cc67765bd73af7ce13b5991146851" + "2d9ee77e34af56fe1f59f98372011f7cb400ced614d808c690c5ba907fb62de9" +) + + +class TestMsgSigntxTaproot(KeepKeyTest): + + def test_send_p2tr(self): + """Spend a P2TR input and compare the witness byte for byte. + + BIP-340 signing is deterministic given aux_rand, and the firmware + signs with an all-zero aux, so this is an equality check against a + signature computed independently of the firmware -- not a round trip + through our own verifier, which would pass even if the device + committed to the wrong transaction. + """ + self.requires_firmware(TAPROOT_FIRMWARE_VERSION) + self.setup_mnemonic_abandon() + self.client.set_tx_api(TxApiBitcoin) + + inp1 = proto_types.TxInputType( + address_n=parse_path("86'/0'/0'/0/0"), + amount=IN_AMOUNT, + prev_hash=unhexlify(PREV_TXID), + prev_index=0, + script_type=proto_types.SPENDTAPROOT, + ) + out1 = proto_types.TxOutputType( + address=OUT_ADDRESS, + amount=OUT_AMOUNT, + script_type=proto_types.PAYTOADDRESS, + ) + + (signatures, _) = self.client.sign_tx("Bitcoin", [inp1], [out1]) + + self.assertEqual(len(signatures), 1) + self.assertEqual(hexlify(signatures[0]).decode(), EXPECTED_WITNESS) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/txcache/insight_bitcoin_tx_6e32033911982f7550ab1d26232adfd08711293e15085f77cd27628be0a6ee37.json b/tests/txcache/insight_bitcoin_tx_6e32033911982f7550ab1d26232adfd08711293e15085f77cd27628be0a6ee37.json new file mode 100644 index 00000000..5bb8521e --- /dev/null +++ b/tests/txcache/insight_bitcoin_tx_6e32033911982f7550ab1d26232adfd08711293e15085f77cd27628be0a6ee37.json @@ -0,0 +1,24 @@ +{ + "txid": "6e32033911982f7550ab1d26232adfd08711293e15085f77cd27628be0a6ee37", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "0000000000000000000000000000000000000000000000000000000000000000", + "vout": 0, + "sequence": 4294967295, + "scriptSig": { + "hex": "" + } + } + ], + "vout": [ + { + "value": "0.00100000", + "n": 0, + "scriptPubKey": { + "hex": "5120a60869f0dbcf1dc659c9cecbaf8050135ea9e8cdc487053f1dc6880949dc684c" + } + } + ] +} \ No newline at end of file From 24435477e51e6eb53864d95d9b5caa9aaa31a74d Mon Sep 17 00:00:00 2001 From: highlander Date: Sat, 1 Aug 2026 19:26:30 -0300 Subject: [PATCH 3/6] test: gate taproot tests on a capability, not a firmware version Both taproot tests gated on requires_firmware("7.16.0") while CMakeLists said 7.15.0, so they skipped -- and which release taproot ships in is still undecided. A gate that is never reached is a test that is silently green forever, which is the failure mode that looks exactly like passing. Replaces it with requires_taproot(), which asks the device. The tests now run whenever the firmware reports the capability, whichever release that turns out to be, and retargeting the release no longer touches them. - common.py: requires_taproot() helper, alongside requires_firmware and requires_message - regenerated messages_pb2.py for Features.supports_taproot (field 27) - device-protocol bumped to the commit adding it Adds test_taproot_screens.py for Gate-3 OLED capture: the two places a 62-character bech32m address actually reaches the display -- verifying a receive address, and the p2wsh multisig case that shares the length. That capture is what found the address truncation fixed in the firmware repo. --- device-protocol | 2 +- keepkeylib/messages_pb2.py | 455 +++++++++++++++++++-------- tests/common.py | 12 + tests/test_msg_getaddress_taproot.py | 6 +- tests/test_msg_signtx_taproot.py | 4 +- tests/test_taproot_screens.py | 43 +++ 6 files changed, 381 insertions(+), 141 deletions(-) create mode 100644 tests/test_taproot_screens.py diff --git a/device-protocol b/device-protocol index b13391c7..be285490 160000 --- a/device-protocol +++ b/device-protocol @@ -1 +1 @@ -Subproject commit b13391c772e3d46011f9ada8606c770b196e93d8 +Subproject commit be2854903f8795daf42ca7b96d93fc348b886b58 diff --git a/keepkeylib/messages_pb2.py b/keepkeylib/messages_pb2.py index d7b8712a..c004f925 100644 --- a/keepkeylib/messages_pb2.py +++ b/keepkeylib/messages_pb2.py @@ -21,7 +21,7 @@ name='messages.proto', package='', syntax='proto2', - serialized_pb=_b('\n\x0emessages.proto\x1a\x0btypes.proto\"\x0c\n\nInitialize\"\r\n\x0bGetFeatures\"\xaa\x04\n\x08\x46\x65\x61tures\x12\x0e\n\x06vendor\x18\x01 \x01(\t\x12\x15\n\rmajor_version\x18\x02 \x01(\r\x12\x15\n\rminor_version\x18\x03 \x01(\r\x12\x15\n\rpatch_version\x18\x04 \x01(\r\x12\x17\n\x0f\x62ootloader_mode\x18\x05 \x01(\x08\x12\x11\n\tdevice_id\x18\x06 \x01(\t\x12\x16\n\x0epin_protection\x18\x07 \x01(\x08\x12\x1d\n\x15passphrase_protection\x18\x08 \x01(\x08\x12\x10\n\x08language\x18\t \x01(\t\x12\r\n\x05label\x18\n \x01(\t\x12\x18\n\x05\x63oins\x18\x0b \x03(\x0b\x32\t.CoinType\x12\x13\n\x0binitialized\x18\x0c \x01(\x08\x12\x10\n\x08revision\x18\r \x01(\x0c\x12\x17\n\x0f\x62ootloader_hash\x18\x0e \x01(\x0c\x12\x10\n\x08imported\x18\x0f \x01(\x08\x12\x12\n\npin_cached\x18\x10 \x01(\x08\x12\x19\n\x11passphrase_cached\x18\x11 \x01(\x08\x12\x1d\n\x08policies\x18\x12 \x03(\x0b\x32\x0b.PolicyType\x12\r\n\x05model\x18\x15 \x01(\t\x12\x18\n\x10\x66irmware_variant\x18\x16 \x01(\t\x12\x15\n\rfirmware_hash\x18\x17 \x01(\x0c\x12\x11\n\tno_backup\x18\x18 \x01(\x08\x12\x1c\n\x14wipe_code_protection\x18\x19 \x01(\x08\x12\x1a\n\x12\x61uto_lock_delay_ms\x18\x1a \x01(\r\"*\n\x0cGetCoinTable\x12\r\n\x05start\x18\x01 \x01(\r\x12\x0b\n\x03\x65nd\x18\x02 \x01(\r\"L\n\tCoinTable\x12\x18\n\x05table\x18\x01 \x03(\x0b\x32\t.CoinType\x12\x11\n\tnum_coins\x18\x02 \x01(\r\x12\x12\n\nchunk_size\x18\x03 \x01(\r\"\x0e\n\x0c\x43learSession\"y\n\rApplySettings\x12\x10\n\x08language\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x16\n\x0euse_passphrase\x18\x03 \x01(\x08\x12\x1a\n\x12\x61uto_lock_delay_ms\x18\x04 \x01(\r\x12\x13\n\x0bu2f_counter\x18\x05 \x01(\r\"\x1b\n\tChangePin\x12\x0e\n\x06remove\x18\x01 \x01(\x08\"\x87\x01\n\x04Ping\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x19\n\x11\x62utton_protection\x18\x02 \x01(\x08\x12\x16\n\x0epin_protection\x18\x03 \x01(\x08\x12\x1d\n\x15passphrase_protection\x18\x04 \x01(\x08\x12\x1c\n\x14wipe_code_protection\x18\x05 \x01(\x08\"\x1a\n\x07Success\x12\x0f\n\x07message\x18\x01 \x01(\t\"6\n\x07\x46\x61ilure\x12\x1a\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x0c.FailureType\x12\x0f\n\x07message\x18\x02 \x01(\t\"?\n\rButtonRequest\x12 \n\x04\x63ode\x18\x01 \x01(\x0e\x32\x12.ButtonRequestType\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\"\x0b\n\tButtonAck\"7\n\x10PinMatrixRequest\x12#\n\x04type\x18\x01 \x01(\x0e\x32\x15.PinMatrixRequestType\"\x1b\n\x0cPinMatrixAck\x12\x0b\n\x03pin\x18\x01 \x02(\t\"\x08\n\x06\x43\x61ncel\"\x13\n\x11PassphraseRequest\"#\n\rPassphraseAck\x12\x12\n\npassphrase\x18\x01 \x02(\t\"\x1a\n\nGetEntropy\x12\x0c\n\x04size\x18\x01 \x02(\r\"\x1a\n\x07\x45ntropy\x12\x0f\n\x07\x65ntropy\x18\x01 \x02(\x0c\"\xa2\x01\n\x0cGetPublicKey\x12\x11\n\taddress_n\x18\x01 \x03(\r\x12\x18\n\x10\x65\x63\x64sa_curve_name\x18\x02 \x01(\t\x12\x14\n\x0cshow_display\x18\x03 \x01(\x08\x12\x1a\n\tcoin_name\x18\x04 \x01(\t:\x07\x42itcoin\x12\x33\n\x0bscript_type\x18\x05 \x01(\x0e\x32\x10.InputScriptType:\x0cSPENDADDRESS\"4\n\tPublicKey\x12\x19\n\x04node\x18\x01 \x02(\x0b\x32\x0b.HDNodeType\x12\x0c\n\x04xpub\x18\x02 \x01(\t\"\xb3\x01\n\nGetAddress\x12\x11\n\taddress_n\x18\x01 \x03(\r\x12\x1a\n\tcoin_name\x18\x02 \x01(\t:\x07\x42itcoin\x12\x14\n\x0cshow_display\x18\x03 \x01(\x08\x12+\n\x08multisig\x18\x04 \x01(\x0b\x32\x19.MultisigRedeemScriptType\x12\x33\n\x0bscript_type\x18\x05 \x01(\x0e\x32\x10.InputScriptType:\x0cSPENDADDRESS\"\x1a\n\x07\x41\x64\x64ress\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x02(\t\"\x0c\n\nWipeDevice\"\xbb\x01\n\nLoadDevice\x12\x10\n\x08mnemonic\x18\x01 \x01(\t\x12\x19\n\x04node\x18\x02 \x01(\x0b\x32\x0b.HDNodeType\x12\x0b\n\x03pin\x18\x03 \x01(\t\x12\x1d\n\x15passphrase_protection\x18\x04 \x01(\x08\x12\x19\n\x08language\x18\x05 \x01(\t:\x07\x65nglish\x12\r\n\x05label\x18\x06 \x01(\t\x12\x15\n\rskip_checksum\x18\x07 \x01(\x08\x12\x13\n\x0bu2f_counter\x18\x08 \x01(\r\"\xe1\x01\n\x0bResetDevice\x12\x16\n\x0e\x64isplay_random\x18\x01 \x01(\x08\x12\x15\n\x08strength\x18\x02 \x01(\r:\x03\x32\x35\x36\x12\x1d\n\x15passphrase_protection\x18\x03 \x01(\x08\x12\x16\n\x0epin_protection\x18\x04 \x01(\x08\x12\x19\n\x08language\x18\x05 \x01(\t:\x07\x65nglish\x12\r\n\x05label\x18\x06 \x01(\t\x12\x11\n\tno_backup\x18\x07 \x01(\x08\x12\x1a\n\x12\x61uto_lock_delay_ms\x18\x08 \x01(\r\x12\x13\n\x0bu2f_counter\x18\t \x01(\r\"\x10\n\x0e\x45ntropyRequest\"\x1d\n\nEntropyAck\x12\x0f\n\x07\x65ntropy\x18\x01 \x01(\x0c\"\xff\x01\n\x0eRecoveryDevice\x12\x12\n\nword_count\x18\x01 \x01(\r\x12\x1d\n\x15passphrase_protection\x18\x02 \x01(\x08\x12\x16\n\x0epin_protection\x18\x03 \x01(\x08\x12\x19\n\x08language\x18\x04 \x01(\t:\x07\x65nglish\x12\r\n\x05label\x18\x05 \x01(\t\x12\x18\n\x10\x65nforce_wordlist\x18\x06 \x01(\x08\x12\x1c\n\x14use_character_cipher\x18\x07 \x01(\x08\x12\x1a\n\x12\x61uto_lock_delay_ms\x18\x08 \x01(\r\x12\x13\n\x0bu2f_counter\x18\t \x01(\r\x12\x0f\n\x07\x64ry_run\x18\n \x01(\x08\"\r\n\x0bWordRequest\"\x17\n\x07WordAck\x12\x0c\n\x04word\x18\x01 \x02(\t\";\n\x10\x43haracterRequest\x12\x10\n\x08word_pos\x18\x01 \x02(\r\x12\x15\n\rcharacter_pos\x18\x02 \x02(\r\"?\n\x0c\x43haracterAck\x12\x11\n\tcharacter\x18\x01 \x01(\t\x12\x0e\n\x06\x64\x65lete\x18\x02 \x01(\x08\x12\x0c\n\x04\x64one\x18\x03 \x01(\x08\"\x82\x01\n\x0bSignMessage\x12\x11\n\taddress_n\x18\x01 \x03(\r\x12\x0f\n\x07message\x18\x02 \x02(\x0c\x12\x1a\n\tcoin_name\x18\x03 \x01(\t:\x07\x42itcoin\x12\x33\n\x0bscript_type\x18\x04 \x01(\x0e\x32\x10.InputScriptType:\x0cSPENDADDRESS\"`\n\rVerifyMessage\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x11\n\tsignature\x18\x02 \x01(\x0c\x12\x0f\n\x07message\x18\x03 \x01(\x0c\x12\x1a\n\tcoin_name\x18\x04 \x01(\t:\x07\x42itcoin\"6\n\x10MessageSignature\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x11\n\tsignature\x18\x02 \x01(\x0c\"v\n\x0e\x45ncryptMessage\x12\x0e\n\x06pubkey\x18\x01 \x01(\x0c\x12\x0f\n\x07message\x18\x02 \x01(\x0c\x12\x14\n\x0c\x64isplay_only\x18\x03 \x01(\x08\x12\x11\n\taddress_n\x18\x04 \x03(\r\x12\x1a\n\tcoin_name\x18\x05 \x01(\t:\x07\x42itcoin\"@\n\x10\x45ncryptedMessage\x12\r\n\x05nonce\x18\x01 \x01(\x0c\x12\x0f\n\x07message\x18\x02 \x01(\x0c\x12\x0c\n\x04hmac\x18\x03 \x01(\x0c\"Q\n\x0e\x44\x65\x63ryptMessage\x12\x11\n\taddress_n\x18\x01 \x03(\r\x12\r\n\x05nonce\x18\x02 \x01(\x0c\x12\x0f\n\x07message\x18\x03 \x01(\x0c\x12\x0c\n\x04hmac\x18\x04 \x01(\x0c\"4\n\x10\x44\x65\x63ryptedMessage\x12\x0f\n\x07message\x18\x01 \x01(\x0c\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\"\x8c\x01\n\x0e\x43ipherKeyValue\x12\x11\n\taddress_n\x18\x01 \x03(\r\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\x0c\x12\x0f\n\x07\x65ncrypt\x18\x04 \x01(\x08\x12\x16\n\x0e\x61sk_on_encrypt\x18\x05 \x01(\x08\x12\x16\n\x0e\x61sk_on_decrypt\x18\x06 \x01(\x08\x12\n\n\x02iv\x18\x07 \x01(\x0c\"!\n\x10\x43ipheredKeyValue\x12\r\n\x05value\x18\x01 \x01(\x0c\"5\n\x10GetBip85Mnemonic\x12\x12\n\nword_count\x18\x01 \x02(\r\x12\r\n\x05index\x18\x02 \x02(\r\"!\n\rBip85Mnemonic\x12\x10\n\x08mnemonic\x18\x01 \x02(\t\"\xce\x01\n\x06SignTx\x12\x15\n\routputs_count\x18\x01 \x02(\r\x12\x14\n\x0cinputs_count\x18\x02 \x02(\r\x12\x1a\n\tcoin_name\x18\x03 \x01(\t:\x07\x42itcoin\x12\x12\n\x07version\x18\x04 \x01(\r:\x01\x31\x12\x14\n\tlock_time\x18\x05 \x01(\r:\x01\x30\x12\x0e\n\x06\x65xpiry\x18\x06 \x01(\r\x12\x14\n\x0coverwintered\x18\x07 \x01(\x08\x12\x18\n\x10version_group_id\x18\x08 \x01(\r\x12\x11\n\tbranch_id\x18\n \x01(\r\"\x85\x01\n\tTxRequest\x12\"\n\x0crequest_type\x18\x01 \x01(\x0e\x32\x0c.RequestType\x12&\n\x07\x64\x65tails\x18\x02 \x01(\x0b\x32\x15.TxRequestDetailsType\x12,\n\nserialized\x18\x03 \x01(\x0b\x32\x18.TxRequestSerializedType\"%\n\x05TxAck\x12\x1c\n\x02tx\x18\x01 \x01(\x0b\x32\x10.TransactionType\"+\n\x08RawTxAck\x12\x1f\n\x02tx\x18\x01 \x01(\x0b\x32\x13.RawTransactionType\"}\n\x0cSignIdentity\x12\x1f\n\x08identity\x18\x01 \x01(\x0b\x32\r.IdentityType\x12\x18\n\x10\x63hallenge_hidden\x18\x02 \x01(\x0c\x12\x18\n\x10\x63hallenge_visual\x18\x03 \x01(\t\x12\x18\n\x10\x65\x63\x64sa_curve_name\x18\x04 \x01(\t\"H\n\x0eSignedIdentity\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x12\n\npublic_key\x18\x02 \x01(\x0c\x12\x11\n\tsignature\x18\x03 \x01(\x0c\",\n\rApplyPolicies\x12\x1b\n\x06policy\x18\x01 \x03(\x0b\x32\x0b.PolicyType\"?\n\tFlashHash\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\r\x12\x0e\n\x06length\x18\x02 \x01(\r\x12\x11\n\tchallenge\x18\x03 \x01(\x0c\":\n\nFlashWrite\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\r\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\r\n\x05\x65rase\x18\x03 \x01(\x08\"!\n\x11\x46lashHashResponse\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\"5\n\x12\x44\x65\x62ugLinkFlashDump\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\r\x12\x0e\n\x06length\x18\x02 \x01(\r\"*\n\x1a\x44\x65\x62ugLinkFlashDumpResponse\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\"\x0b\n\tSoftReset\"\x0f\n\rFirmwareErase\"7\n\x0e\x46irmwareUpload\x12\x14\n\x0cpayload_hash\x18\x01 \x02(\x0c\x12\x0f\n\x07payload\x18\x02 \x02(\x0c\"#\n\x11\x44\x65\x62ugLinkDecision\x12\x0e\n\x06yes_no\x18\x01 \x02(\x08\"\x13\n\x11\x44\x65\x62ugLinkGetState\"\xd7\x02\n\x0e\x44\x65\x62ugLinkState\x12\x0e\n\x06layout\x18\x01 \x01(\x0c\x12\x0b\n\x03pin\x18\x02 \x01(\t\x12\x0e\n\x06matrix\x18\x03 \x01(\t\x12\x10\n\x08mnemonic\x18\x04 \x01(\t\x12\x19\n\x04node\x18\x05 \x01(\x0b\x32\x0b.HDNodeType\x12\x1d\n\x15passphrase_protection\x18\x06 \x01(\x08\x12\x12\n\nreset_word\x18\x07 \x01(\t\x12\x15\n\rreset_entropy\x18\x08 \x01(\x0c\x12\x1a\n\x12recovery_fake_word\x18\t \x01(\t\x12\x19\n\x11recovery_word_pos\x18\n \x01(\r\x12\x17\n\x0frecovery_cipher\x18\x0b \x01(\t\x12$\n\x1crecovery_auto_completed_word\x18\x0c \x01(\t\x12\x15\n\rfirmware_hash\x18\r \x01(\x0c\x12\x14\n\x0cstorage_hash\x18\x0e \x01(\x0c\"\x0f\n\rDebugLinkStop\";\n\x0c\x44\x65\x62ugLinkLog\x12\r\n\x05level\x18\x01 \x01(\r\x12\x0e\n\x06\x62ucket\x18\x02 \x01(\t\x12\x0c\n\x04text\x18\x03 \x01(\t\"\x15\n\x13\x44\x65\x62ugLinkFillConfig\" \n\x0e\x43hangeWipeCode\x12\x0e\n\x06remove\x18\x01 \x01(\x08*\x87@\n\x0bMessageType\x12 \n\x16MessageType_Initialize\x10\x00\x1a\x04\x90\xb5\x18\x01\x12\x1a\n\x10MessageType_Ping\x10\x01\x1a\x04\x90\xb5\x18\x01\x12\x1d\n\x13MessageType_Success\x10\x02\x1a\x04\x98\xb5\x18\x01\x12\x1d\n\x13MessageType_Failure\x10\x03\x1a\x04\x98\xb5\x18\x01\x12\x1f\n\x15MessageType_ChangePin\x10\x04\x1a\x04\x90\xb5\x18\x01\x12 \n\x16MessageType_WipeDevice\x10\x05\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_FirmwareErase\x10\x06\x1a\x04\x90\xb5\x18\x01\x12$\n\x1aMessageType_FirmwareUpload\x10\x07\x1a\x04\x90\xb5\x18\x01\x12 \n\x16MessageType_GetEntropy\x10\t\x1a\x04\x90\xb5\x18\x01\x12\x1d\n\x13MessageType_Entropy\x10\n\x1a\x04\x98\xb5\x18\x01\x12\"\n\x18MessageType_GetPublicKey\x10\x0b\x1a\x04\x90\xb5\x18\x01\x12\x1f\n\x15MessageType_PublicKey\x10\x0c\x1a\x04\x98\xb5\x18\x01\x12 \n\x16MessageType_LoadDevice\x10\r\x1a\x04\x90\xb5\x18\x01\x12!\n\x17MessageType_ResetDevice\x10\x0e\x1a\x04\x90\xb5\x18\x01\x12\x1c\n\x12MessageType_SignTx\x10\x0f\x1a\x04\x90\xb5\x18\x01\x12\x1e\n\x14MessageType_Features\x10\x11\x1a\x04\x98\xb5\x18\x01\x12&\n\x1cMessageType_PinMatrixRequest\x10\x12\x1a\x04\x98\xb5\x18\x01\x12\"\n\x18MessageType_PinMatrixAck\x10\x13\x1a\x04\x90\xb5\x18\x01\x12\x1c\n\x12MessageType_Cancel\x10\x14\x1a\x04\x90\xb5\x18\x01\x12\x1f\n\x15MessageType_TxRequest\x10\x15\x1a\x04\x98\xb5\x18\x01\x12\x1b\n\x11MessageType_TxAck\x10\x16\x1a\x04\x90\xb5\x18\x01\x12$\n\x1aMessageType_CipherKeyValue\x10\x17\x1a\x04\x90\xb5\x18\x01\x12\"\n\x18MessageType_ClearSession\x10\x18\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_ApplySettings\x10\x19\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_ButtonRequest\x10\x1a\x1a\x04\x98\xb5\x18\x01\x12\x1f\n\x15MessageType_ButtonAck\x10\x1b\x1a\x04\x90\xb5\x18\x01\x12 \n\x16MessageType_GetAddress\x10\x1d\x1a\x04\x90\xb5\x18\x01\x12\x1d\n\x13MessageType_Address\x10\x1e\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_EntropyRequest\x10#\x1a\x04\x98\xb5\x18\x01\x12 \n\x16MessageType_EntropyAck\x10$\x1a\x04\x90\xb5\x18\x01\x12!\n\x17MessageType_SignMessage\x10&\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_VerifyMessage\x10\'\x1a\x04\x90\xb5\x18\x01\x12&\n\x1cMessageType_MessageSignature\x10(\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1dMessageType_PassphraseRequest\x10)\x1a\x04\x98\xb5\x18\x01\x12#\n\x19MessageType_PassphraseAck\x10*\x1a\x04\x90\xb5\x18\x01\x12$\n\x1aMessageType_RecoveryDevice\x10-\x1a\x04\x90\xb5\x18\x01\x12!\n\x17MessageType_WordRequest\x10.\x1a\x04\x98\xb5\x18\x01\x12\x1d\n\x13MessageType_WordAck\x10/\x1a\x04\x90\xb5\x18\x01\x12&\n\x1cMessageType_CipheredKeyValue\x10\x30\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_EncryptMessage\x10\x31\x1a\x04\x90\xb5\x18\x01\x12&\n\x1cMessageType_EncryptedMessage\x10\x32\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_DecryptMessage\x10\x33\x1a\x04\x90\xb5\x18\x01\x12&\n\x1cMessageType_DecryptedMessage\x10\x34\x1a\x04\x98\xb5\x18\x01\x12\"\n\x18MessageType_SignIdentity\x10\x35\x1a\x04\x90\xb5\x18\x01\x12$\n\x1aMessageType_SignedIdentity\x10\x36\x1a\x04\x98\xb5\x18\x01\x12!\n\x17MessageType_GetFeatures\x10\x37\x1a\x04\x90\xb5\x18\x01\x12(\n\x1eMessageType_EthereumGetAddress\x10\x38\x1a\x04\x90\xb5\x18\x01\x12%\n\x1bMessageType_EthereumAddress\x10\x39\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_EthereumSignTx\x10:\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1dMessageType_EthereumTxRequest\x10;\x1a\x04\x98\xb5\x18\x01\x12#\n\x19MessageType_EthereumTxAck\x10<\x1a\x04\x90\xb5\x18\x01\x12&\n\x1cMessageType_CharacterRequest\x10P\x1a\x04\x98\xb5\x18\x01\x12\"\n\x18MessageType_CharacterAck\x10Q\x1a\x04\x90\xb5\x18\x01\x12\x1e\n\x14MessageType_RawTxAck\x10R\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_ApplyPolicies\x10S\x1a\x04\x90\xb5\x18\x01\x12\x1f\n\x15MessageType_FlashHash\x10T\x1a\x04\x90\xb5\x18\x01\x12 \n\x16MessageType_FlashWrite\x10U\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1dMessageType_FlashHashResponse\x10V\x1a\x04\x98\xb5\x18\x01\x12(\n\x1eMessageType_DebugLinkFlashDump\x10W\x1a\x04\xa0\xb5\x18\x01\x12\x30\n&MessageType_DebugLinkFlashDumpResponse\x10X\x1a\x04\xa8\xb5\x18\x01\x12\x1f\n\x15MessageType_SoftReset\x10Y\x1a\x04\xa0\xb5\x18\x01\x12\'\n\x1dMessageType_DebugLinkDecision\x10\x64\x1a\x04\xa0\xb5\x18\x01\x12\'\n\x1dMessageType_DebugLinkGetState\x10\x65\x1a\x04\xa0\xb5\x18\x01\x12$\n\x1aMessageType_DebugLinkState\x10\x66\x1a\x04\xa8\xb5\x18\x01\x12#\n\x19MessageType_DebugLinkStop\x10g\x1a\x04\xa0\xb5\x18\x01\x12\"\n\x18MessageType_DebugLinkLog\x10h\x1a\x04\xa8\xb5\x18\x01\x12)\n\x1fMessageType_DebugLinkFillConfig\x10i\x1a\x04\xa8\xb5\x18\x01\x12\"\n\x18MessageType_GetCoinTable\x10j\x1a\x04\x90\xb5\x18\x01\x12\x1f\n\x15MessageType_CoinTable\x10k\x1a\x04\x98\xb5\x18\x01\x12)\n\x1fMessageType_EthereumSignMessage\x10l\x1a\x04\x90\xb5\x18\x01\x12+\n!MessageType_EthereumVerifyMessage\x10m\x1a\x04\x90\xb5\x18\x01\x12.\n$MessageType_EthereumMessageSignature\x10n\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_ChangeWipeCode\x10o\x1a\x04\x90\xb5\x18\x01\x12+\n!MessageType_EthereumSignTypedHash\x10p\x1a\x04\x90\xb5\x18\x01\x12\x30\n&MessageType_EthereumTypedDataSignature\x10q\x1a\x04\x98\xb5\x18\x01\x12,\n\"MessageType_Ethereum712TypesValues\x10r\x1a\x04\x90\xb5\x18\x01\x12(\n\x1eMessageType_EthereumTxMetadata\x10s\x1a\x04\x90\xb5\x18\x01\x12)\n\x1fMessageType_EthereumMetadataAck\x10t\x1a\x04\x98\xb5\x18\x01\x12)\n\x1fMessageType_LoadClearsignSigner\x10u\x1a\x04\x90\xb5\x18\x01\x12&\n\x1cMessageType_GetBip85Mnemonic\x10x\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_Bip85Mnemonic\x10y\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_RippleGetAddress\x10\x90\x03\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_RippleAddress\x10\x91\x03\x1a\x04\x98\xb5\x18\x01\x12#\n\x18MessageType_RippleSignTx\x10\x92\x03\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_RippleSignedTx\x10\x93\x03\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_ThorchainGetAddress\x10\xf4\x03\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1cMessageType_ThorchainAddress\x10\xf5\x03\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_ThorchainSignTx\x10\xf6\x03\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_ThorchainMsgRequest\x10\xf7\x03\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_ThorchainMsgAck\x10\xf8\x03\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_ThorchainSignedTx\x10\xf9\x03\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_EosGetPublicKey\x10\xd8\x04\x1a\x04\x90\xb5\x18\x01\x12#\n\x18MessageType_EosPublicKey\x10\xd9\x04\x1a\x04\x98\xb5\x18\x01\x12 \n\x15MessageType_EosSignTx\x10\xda\x04\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_EosTxActionRequest\x10\xdb\x04\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMessageType_EosTxActionAck\x10\xdc\x04\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17MessageType_EosSignedTx\x10\xdd\x04\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMessageType_NanoGetAddress\x10\xbc\x05\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17MessageType_NanoAddress\x10\xbd\x05\x1a\x04\x98\xb5\x18\x01\x12!\n\x16MessageType_NanoSignTx\x10\xbe\x05\x1a\x04\x90\xb5\x18\x01\x12#\n\x18MessageType_NanoSignedTx\x10\xbf\x05\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_SolanaGetAddress\x10\xee\x05\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_SolanaAddress\x10\xef\x05\x1a\x04\x98\xb5\x18\x01\x12#\n\x18MessageType_SolanaSignTx\x10\xf0\x05\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_SolanaSignedTx\x10\xf1\x05\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_SolanaSignMessage\x10\xf2\x05\x1a\x04\x90\xb5\x18\x01\x12-\n\"MessageType_SolanaMessageSignature\x10\xf3\x05\x1a\x04\x98\xb5\x18\x01\x12\x30\n%MessageType_SolanaSignOffchainMessage\x10\xf4\x05\x1a\x04\x90\xb5\x18\x01\x12\x35\n*MessageType_SolanaOffchainMessageSignature\x10\xf5\x05\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_BinanceGetAddress\x10\xa0\x06\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_BinanceAddress\x10\xa1\x06\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_BinanceGetPublicKey\x10\xa2\x06\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1cMessageType_BinancePublicKey\x10\xa3\x06\x1a\x04\x98\xb5\x18\x01\x12$\n\x19MessageType_BinanceSignTx\x10\xa4\x06\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1cMessageType_BinanceTxRequest\x10\xa5\x06\x1a\x04\x98\xb5\x18\x01\x12)\n\x1eMessageType_BinanceTransferMsg\x10\xa6\x06\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_BinanceOrderMsg\x10\xa7\x06\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1cMessageType_BinanceCancelMsg\x10\xa8\x06\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_BinanceSignedTx\x10\xa9\x06\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_CosmosGetAddress\x10\x84\x07\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_CosmosAddress\x10\x85\x07\x1a\x04\x98\xb5\x18\x01\x12#\n\x18MessageType_CosmosSignTx\x10\x86\x07\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1cMessageType_CosmosMsgRequest\x10\x87\x07\x1a\x04\x98\xb5\x18\x01\x12#\n\x18MessageType_CosmosMsgAck\x10\x88\x07\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_CosmosSignedTx\x10\x89\x07\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_CosmosMsgDelegate\x10\x8a\x07\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_CosmosMsgUndelegate\x10\x8b\x07\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_CosmosMsgRedelegate\x10\x8c\x07\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_CosmosMsgRewards\x10\x8d\x07\x1a\x04\x98\xb5\x18\x01\x12+\n MessageType_CosmosMsgIBCTransfer\x10\x8e\x07\x1a\x04\x98\xb5\x18\x01\x12+\n MessageType_TendermintGetAddress\x10\xe8\x07\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_TendermintAddress\x10\xe9\x07\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_TendermintSignTx\x10\xea\x07\x1a\x04\x90\xb5\x18\x01\x12+\n MessageType_TendermintMsgRequest\x10\xeb\x07\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_TendermintMsgAck\x10\xec\x07\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_TendermintMsgSend\x10\xed\x07\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_TendermintSignedTx\x10\xee\x07\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_TendermintMsgDelegate\x10\xef\x07\x1a\x04\x98\xb5\x18\x01\x12.\n#MessageType_TendermintMsgUndelegate\x10\xf0\x07\x1a\x04\x98\xb5\x18\x01\x12.\n#MessageType_TendermintMsgRedelegate\x10\xf1\x07\x1a\x04\x98\xb5\x18\x01\x12+\n MessageType_TendermintMsgRewards\x10\xf2\x07\x1a\x04\x98\xb5\x18\x01\x12/\n$MessageType_TendermintMsgIBCTransfer\x10\xf3\x07\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_OsmosisGetAddress\x10\xcc\x08\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_OsmosisAddress\x10\xcd\x08\x1a\x04\x98\xb5\x18\x01\x12$\n\x19MessageType_OsmosisSignTx\x10\xce\x08\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_OsmosisMsgRequest\x10\xcf\x08\x1a\x04\x98\xb5\x18\x01\x12$\n\x19MessageType_OsmosisMsgAck\x10\xd0\x08\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_OsmosisMsgSend\x10\xd1\x08\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_OsmosisMsgDelegate\x10\xd2\x08\x1a\x04\x90\xb5\x18\x01\x12+\n MessageType_OsmosisMsgUndelegate\x10\xd3\x08\x1a\x04\x90\xb5\x18\x01\x12+\n MessageType_OsmosisMsgRedelegate\x10\xd4\x08\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_OsmosisMsgRewards\x10\xd5\x08\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_OsmosisMsgLPAdd\x10\xd6\x08\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_OsmosisMsgLPRemove\x10\xd7\x08\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_OsmosisMsgLPStake\x10\xd8\x08\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_OsmosisMsgLPUnstake\x10\xd9\x08\x1a\x04\x90\xb5\x18\x01\x12,\n!MessageType_OsmosisMsgIBCTransfer\x10\xda\x08\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_OsmosisMsgSwap\x10\xdb\x08\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_OsmosisSignedTx\x10\xdc\x08\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_MayachainGetAddress\x10\xb0\t\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1cMessageType_MayachainAddress\x10\xb1\t\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_MayachainSignTx\x10\xb2\t\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_MayachainMsgRequest\x10\xb3\t\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_MayachainMsgAck\x10\xb4\t\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_MayachainSignedTx\x10\xb5\t\x1a\x04\x98\xb5\x18\x01\x12$\n\x19MessageType_ZcashSignPCZT\x10\x94\n\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_ZcashPCZTAction\x10\x95\n\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_ZcashPCZTActionAck\x10\x96\n\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_ZcashSignedPCZT\x10\x97\n\x1a\x04\x98\xb5\x18\x01\x12)\n\x1eMessageType_ZcashGetOrchardFVK\x10\x98\n\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_ZcashOrchardFVK\x10\x99\n\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_ZcashTransparentInput\x10\x9a\n\x1a\x04\x90\xb5\x18\x01\x12-\n\"MessageType_ZcashTransparentSigned\x10\x9b\n\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_ZcashDisplayAddress\x10\x9c\n\x1a\x04\x90\xb5\x18\x01\x12#\n\x18MessageType_ZcashAddress\x10\x9d\n\x1a\x04\x98\xb5\x18\x01\x12-\n\"MessageType_ZcashTransparentOutput\x10\x9e\n\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_ZcashTransparentAck\x10\x9f\n\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMessageType_TronGetAddress\x10\xf8\n\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17MessageType_TronAddress\x10\xf9\n\x1a\x04\x98\xb5\x18\x01\x12!\n\x16MessageType_TronSignTx\x10\xfa\n\x1a\x04\x90\xb5\x18\x01\x12#\n\x18MessageType_TronSignedTx\x10\xfb\n\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_TronSignMessage\x10\xfc\n\x1a\x04\x90\xb5\x18\x01\x12+\n MessageType_TronMessageSignature\x10\xfd\n\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_TronVerifyMessage\x10\xfe\n\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_TronSignTypedHash\x10\xff\n\x1a\x04\x90\xb5\x18\x01\x12-\n\"MessageType_TronTypedDataSignature\x10\x80\x0b\x1a\x04\x98\xb5\x18\x01\x12$\n\x19MessageType_TonGetAddress\x10\xdc\x0b\x1a\x04\x90\xb5\x18\x01\x12!\n\x16MessageType_TonAddress\x10\xdd\x0b\x1a\x04\x98\xb5\x18\x01\x12 \n\x15MessageType_TonSignTx\x10\xde\x0b\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17MessageType_TonSignedTx\x10\xdf\x0b\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMessageType_TonSignMessage\x10\xe0\x0b\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_TonMessageSignature\x10\xe1\x0b\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_HiveGetPublicKey\x10\xc0\x0c\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_HivePublicKey\x10\xc1\x0c\x1a\x04\x98\xb5\x18\x01\x12!\n\x16MessageType_HiveSignTx\x10\xc2\x0c\x1a\x04\x90\xb5\x18\x01\x12#\n\x18MessageType_HiveSignedTx\x10\xc3\x0c\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_HiveGetPublicKeys\x10\xc4\x0c\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_HivePublicKeys\x10\xc5\x0c\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_HiveSignAccountCreate\x10\xc6\x0c\x1a\x04\x90\xb5\x18\x01\x12.\n#MessageType_HiveSignedAccountCreate\x10\xc7\x0c\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_HiveSignAccountUpdate\x10\xc8\x0c\x1a\x04\x90\xb5\x18\x01\x12.\n#MessageType_HiveSignedAccountUpdate\x10\xc9\x0c\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_HiveSignMessage\x10\xce\x0c\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_HiveSignedMessage\x10\xcf\x0c\x1a\x04\x98\xb5\x18\x01\x12)\n\x1eMessageType_HiveSignOperations\x10\xd0\x0c\x1a\x04\x90\xb5\x18\x01\x12+\n MessageType_HiveSignedOperations\x10\xd1\x0c\x1a\x04\x98\xb5\x18\x01\x42,\n\x1a\x63om.keepkey.deviceprotocolB\x0eKeepKeyMessage') + serialized_pb=_b('\n\x0emessages.proto\x1a\x0btypes.proto\"\x0c\n\nInitialize\"\r\n\x0bGetFeatures\"\xc4\x04\n\x08\x46\x65\x61tures\x12\x0e\n\x06vendor\x18\x01 \x01(\t\x12\x15\n\rmajor_version\x18\x02 \x01(\r\x12\x15\n\rminor_version\x18\x03 \x01(\r\x12\x15\n\rpatch_version\x18\x04 \x01(\r\x12\x17\n\x0f\x62ootloader_mode\x18\x05 \x01(\x08\x12\x11\n\tdevice_id\x18\x06 \x01(\t\x12\x16\n\x0epin_protection\x18\x07 \x01(\x08\x12\x1d\n\x15passphrase_protection\x18\x08 \x01(\x08\x12\x10\n\x08language\x18\t \x01(\t\x12\r\n\x05label\x18\n \x01(\t\x12\x18\n\x05\x63oins\x18\x0b \x03(\x0b\x32\t.CoinType\x12\x13\n\x0binitialized\x18\x0c \x01(\x08\x12\x10\n\x08revision\x18\r \x01(\x0c\x12\x17\n\x0f\x62ootloader_hash\x18\x0e \x01(\x0c\x12\x10\n\x08imported\x18\x0f \x01(\x08\x12\x12\n\npin_cached\x18\x10 \x01(\x08\x12\x19\n\x11passphrase_cached\x18\x11 \x01(\x08\x12\x1d\n\x08policies\x18\x12 \x03(\x0b\x32\x0b.PolicyType\x12\r\n\x05model\x18\x15 \x01(\t\x12\x18\n\x10\x66irmware_variant\x18\x16 \x01(\t\x12\x15\n\rfirmware_hash\x18\x17 \x01(\x0c\x12\x11\n\tno_backup\x18\x18 \x01(\x08\x12\x1c\n\x14wipe_code_protection\x18\x19 \x01(\x08\x12\x1a\n\x12\x61uto_lock_delay_ms\x18\x1a \x01(\r\x12\x18\n\x10supports_taproot\x18\x1b \x01(\x08\"*\n\x0cGetCoinTable\x12\r\n\x05start\x18\x01 \x01(\r\x12\x0b\n\x03\x65nd\x18\x02 \x01(\r\"L\n\tCoinTable\x12\x18\n\x05table\x18\x01 \x03(\x0b\x32\t.CoinType\x12\x11\n\tnum_coins\x18\x02 \x01(\r\x12\x12\n\nchunk_size\x18\x03 \x01(\r\"\x0e\n\x0c\x43learSession\"y\n\rApplySettings\x12\x10\n\x08language\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x16\n\x0euse_passphrase\x18\x03 \x01(\x08\x12\x1a\n\x12\x61uto_lock_delay_ms\x18\x04 \x01(\r\x12\x13\n\x0bu2f_counter\x18\x05 \x01(\r\"\x1b\n\tChangePin\x12\x0e\n\x06remove\x18\x01 \x01(\x08\"\x87\x01\n\x04Ping\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x19\n\x11\x62utton_protection\x18\x02 \x01(\x08\x12\x16\n\x0epin_protection\x18\x03 \x01(\x08\x12\x1d\n\x15passphrase_protection\x18\x04 \x01(\x08\x12\x1c\n\x14wipe_code_protection\x18\x05 \x01(\x08\"\x1a\n\x07Success\x12\x0f\n\x07message\x18\x01 \x01(\t\"6\n\x07\x46\x61ilure\x12\x1a\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x0c.FailureType\x12\x0f\n\x07message\x18\x02 \x01(\t\"?\n\rButtonRequest\x12 \n\x04\x63ode\x18\x01 \x01(\x0e\x32\x12.ButtonRequestType\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\"\x0b\n\tButtonAck\"7\n\x10PinMatrixRequest\x12#\n\x04type\x18\x01 \x01(\x0e\x32\x15.PinMatrixRequestType\"\x1b\n\x0cPinMatrixAck\x12\x0b\n\x03pin\x18\x01 \x02(\t\"\x08\n\x06\x43\x61ncel\"\x13\n\x11PassphraseRequest\"#\n\rPassphraseAck\x12\x12\n\npassphrase\x18\x01 \x02(\t\"\x1a\n\nGetEntropy\x12\x0c\n\x04size\x18\x01 \x02(\r\"\x1a\n\x07\x45ntropy\x12\x0f\n\x07\x65ntropy\x18\x01 \x02(\x0c\"\xa2\x01\n\x0cGetPublicKey\x12\x11\n\taddress_n\x18\x01 \x03(\r\x12\x18\n\x10\x65\x63\x64sa_curve_name\x18\x02 \x01(\t\x12\x14\n\x0cshow_display\x18\x03 \x01(\x08\x12\x1a\n\tcoin_name\x18\x04 \x01(\t:\x07\x42itcoin\x12\x33\n\x0bscript_type\x18\x05 \x01(\x0e\x32\x10.InputScriptType:\x0cSPENDADDRESS\"4\n\tPublicKey\x12\x19\n\x04node\x18\x01 \x02(\x0b\x32\x0b.HDNodeType\x12\x0c\n\x04xpub\x18\x02 \x01(\t\"\xb3\x01\n\nGetAddress\x12\x11\n\taddress_n\x18\x01 \x03(\r\x12\x1a\n\tcoin_name\x18\x02 \x01(\t:\x07\x42itcoin\x12\x14\n\x0cshow_display\x18\x03 \x01(\x08\x12+\n\x08multisig\x18\x04 \x01(\x0b\x32\x19.MultisigRedeemScriptType\x12\x33\n\x0bscript_type\x18\x05 \x01(\x0e\x32\x10.InputScriptType:\x0cSPENDADDRESS\"\x1a\n\x07\x41\x64\x64ress\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x02(\t\"\x0c\n\nWipeDevice\"\xbb\x01\n\nLoadDevice\x12\x10\n\x08mnemonic\x18\x01 \x01(\t\x12\x19\n\x04node\x18\x02 \x01(\x0b\x32\x0b.HDNodeType\x12\x0b\n\x03pin\x18\x03 \x01(\t\x12\x1d\n\x15passphrase_protection\x18\x04 \x01(\x08\x12\x19\n\x08language\x18\x05 \x01(\t:\x07\x65nglish\x12\r\n\x05label\x18\x06 \x01(\t\x12\x15\n\rskip_checksum\x18\x07 \x01(\x08\x12\x13\n\x0bu2f_counter\x18\x08 \x01(\r\"\xe1\x01\n\x0bResetDevice\x12\x16\n\x0e\x64isplay_random\x18\x01 \x01(\x08\x12\x15\n\x08strength\x18\x02 \x01(\r:\x03\x32\x35\x36\x12\x1d\n\x15passphrase_protection\x18\x03 \x01(\x08\x12\x16\n\x0epin_protection\x18\x04 \x01(\x08\x12\x19\n\x08language\x18\x05 \x01(\t:\x07\x65nglish\x12\r\n\x05label\x18\x06 \x01(\t\x12\x11\n\tno_backup\x18\x07 \x01(\x08\x12\x1a\n\x12\x61uto_lock_delay_ms\x18\x08 \x01(\r\x12\x13\n\x0bu2f_counter\x18\t \x01(\r\"\x10\n\x0e\x45ntropyRequest\"\x1d\n\nEntropyAck\x12\x0f\n\x07\x65ntropy\x18\x01 \x01(\x0c\"\xff\x01\n\x0eRecoveryDevice\x12\x12\n\nword_count\x18\x01 \x01(\r\x12\x1d\n\x15passphrase_protection\x18\x02 \x01(\x08\x12\x16\n\x0epin_protection\x18\x03 \x01(\x08\x12\x19\n\x08language\x18\x04 \x01(\t:\x07\x65nglish\x12\r\n\x05label\x18\x05 \x01(\t\x12\x18\n\x10\x65nforce_wordlist\x18\x06 \x01(\x08\x12\x1c\n\x14use_character_cipher\x18\x07 \x01(\x08\x12\x1a\n\x12\x61uto_lock_delay_ms\x18\x08 \x01(\r\x12\x13\n\x0bu2f_counter\x18\t \x01(\r\x12\x0f\n\x07\x64ry_run\x18\n \x01(\x08\"\r\n\x0bWordRequest\"\x17\n\x07WordAck\x12\x0c\n\x04word\x18\x01 \x02(\t\";\n\x10\x43haracterRequest\x12\x10\n\x08word_pos\x18\x01 \x02(\r\x12\x15\n\rcharacter_pos\x18\x02 \x02(\r\"?\n\x0c\x43haracterAck\x12\x11\n\tcharacter\x18\x01 \x01(\t\x12\x0e\n\x06\x64\x65lete\x18\x02 \x01(\x08\x12\x0c\n\x04\x64one\x18\x03 \x01(\x08\"\x82\x01\n\x0bSignMessage\x12\x11\n\taddress_n\x18\x01 \x03(\r\x12\x0f\n\x07message\x18\x02 \x02(\x0c\x12\x1a\n\tcoin_name\x18\x03 \x01(\t:\x07\x42itcoin\x12\x33\n\x0bscript_type\x18\x04 \x01(\x0e\x32\x10.InputScriptType:\x0cSPENDADDRESS\"`\n\rVerifyMessage\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x11\n\tsignature\x18\x02 \x01(\x0c\x12\x0f\n\x07message\x18\x03 \x01(\x0c\x12\x1a\n\tcoin_name\x18\x04 \x01(\t:\x07\x42itcoin\"6\n\x10MessageSignature\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x11\n\tsignature\x18\x02 \x01(\x0c\"v\n\x0e\x45ncryptMessage\x12\x0e\n\x06pubkey\x18\x01 \x01(\x0c\x12\x0f\n\x07message\x18\x02 \x01(\x0c\x12\x14\n\x0c\x64isplay_only\x18\x03 \x01(\x08\x12\x11\n\taddress_n\x18\x04 \x03(\r\x12\x1a\n\tcoin_name\x18\x05 \x01(\t:\x07\x42itcoin\"@\n\x10\x45ncryptedMessage\x12\r\n\x05nonce\x18\x01 \x01(\x0c\x12\x0f\n\x07message\x18\x02 \x01(\x0c\x12\x0c\n\x04hmac\x18\x03 \x01(\x0c\"Q\n\x0e\x44\x65\x63ryptMessage\x12\x11\n\taddress_n\x18\x01 \x03(\r\x12\r\n\x05nonce\x18\x02 \x01(\x0c\x12\x0f\n\x07message\x18\x03 \x01(\x0c\x12\x0c\n\x04hmac\x18\x04 \x01(\x0c\"4\n\x10\x44\x65\x63ryptedMessage\x12\x0f\n\x07message\x18\x01 \x01(\x0c\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\"\x8c\x01\n\x0e\x43ipherKeyValue\x12\x11\n\taddress_n\x18\x01 \x03(\r\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\x0c\x12\x0f\n\x07\x65ncrypt\x18\x04 \x01(\x08\x12\x16\n\x0e\x61sk_on_encrypt\x18\x05 \x01(\x08\x12\x16\n\x0e\x61sk_on_decrypt\x18\x06 \x01(\x08\x12\n\n\x02iv\x18\x07 \x01(\x0c\"!\n\x10\x43ipheredKeyValue\x12\r\n\x05value\x18\x01 \x01(\x0c\"5\n\x10GetBip85Mnemonic\x12\x12\n\nword_count\x18\x01 \x02(\r\x12\r\n\x05index\x18\x02 \x02(\r\"!\n\rBip85Mnemonic\x12\x10\n\x08mnemonic\x18\x01 \x02(\t\"\xce\x01\n\x06SignTx\x12\x15\n\routputs_count\x18\x01 \x02(\r\x12\x14\n\x0cinputs_count\x18\x02 \x02(\r\x12\x1a\n\tcoin_name\x18\x03 \x01(\t:\x07\x42itcoin\x12\x12\n\x07version\x18\x04 \x01(\r:\x01\x31\x12\x14\n\tlock_time\x18\x05 \x01(\r:\x01\x30\x12\x0e\n\x06\x65xpiry\x18\x06 \x01(\r\x12\x14\n\x0coverwintered\x18\x07 \x01(\x08\x12\x18\n\x10version_group_id\x18\x08 \x01(\r\x12\x11\n\tbranch_id\x18\n \x01(\r\"\x85\x01\n\tTxRequest\x12\"\n\x0crequest_type\x18\x01 \x01(\x0e\x32\x0c.RequestType\x12&\n\x07\x64\x65tails\x18\x02 \x01(\x0b\x32\x15.TxRequestDetailsType\x12,\n\nserialized\x18\x03 \x01(\x0b\x32\x18.TxRequestSerializedType\"%\n\x05TxAck\x12\x1c\n\x02tx\x18\x01 \x01(\x0b\x32\x10.TransactionType\"+\n\x08RawTxAck\x12\x1f\n\x02tx\x18\x01 \x01(\x0b\x32\x13.RawTransactionType\"}\n\x0cSignIdentity\x12\x1f\n\x08identity\x18\x01 \x01(\x0b\x32\r.IdentityType\x12\x18\n\x10\x63hallenge_hidden\x18\x02 \x01(\x0c\x12\x18\n\x10\x63hallenge_visual\x18\x03 \x01(\t\x12\x18\n\x10\x65\x63\x64sa_curve_name\x18\x04 \x01(\t\"H\n\x0eSignedIdentity\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x12\n\npublic_key\x18\x02 \x01(\x0c\x12\x11\n\tsignature\x18\x03 \x01(\x0c\",\n\rApplyPolicies\x12\x1b\n\x06policy\x18\x01 \x03(\x0b\x32\x0b.PolicyType\"?\n\tFlashHash\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\r\x12\x0e\n\x06length\x18\x02 \x01(\r\x12\x11\n\tchallenge\x18\x03 \x01(\x0c\":\n\nFlashWrite\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\r\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\r\n\x05\x65rase\x18\x03 \x01(\x08\"!\n\x11\x46lashHashResponse\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\"5\n\x12\x44\x65\x62ugLinkFlashDump\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\r\x12\x0e\n\x06length\x18\x02 \x01(\r\"*\n\x1a\x44\x65\x62ugLinkFlashDumpResponse\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\"\x0b\n\tSoftReset\"\x0f\n\rFirmwareErase\"7\n\x0e\x46irmwareUpload\x12\x14\n\x0cpayload_hash\x18\x01 \x02(\x0c\x12\x0f\n\x07payload\x18\x02 \x02(\x0c\"#\n\x11\x44\x65\x62ugLinkDecision\x12\x0e\n\x06yes_no\x18\x01 \x02(\x08\"\x13\n\x11\x44\x65\x62ugLinkGetState\"\xd7\x02\n\x0e\x44\x65\x62ugLinkState\x12\x0e\n\x06layout\x18\x01 \x01(\x0c\x12\x0b\n\x03pin\x18\x02 \x01(\t\x12\x0e\n\x06matrix\x18\x03 \x01(\t\x12\x10\n\x08mnemonic\x18\x04 \x01(\t\x12\x19\n\x04node\x18\x05 \x01(\x0b\x32\x0b.HDNodeType\x12\x1d\n\x15passphrase_protection\x18\x06 \x01(\x08\x12\x12\n\nreset_word\x18\x07 \x01(\t\x12\x15\n\rreset_entropy\x18\x08 \x01(\x0c\x12\x1a\n\x12recovery_fake_word\x18\t \x01(\t\x12\x19\n\x11recovery_word_pos\x18\n \x01(\r\x12\x17\n\x0frecovery_cipher\x18\x0b \x01(\t\x12$\n\x1crecovery_auto_completed_word\x18\x0c \x01(\t\x12\x15\n\rfirmware_hash\x18\r \x01(\x0c\x12\x14\n\x0cstorage_hash\x18\x0e \x01(\x0c\"\x0f\n\rDebugLinkStop\";\n\x0c\x44\x65\x62ugLinkLog\x12\r\n\x05level\x18\x01 \x01(\r\x12\x0e\n\x06\x62ucket\x18\x02 \x01(\t\x12\x0c\n\x04text\x18\x03 \x01(\t\"\x15\n\x13\x44\x65\x62ugLinkFillConfig\" \n\x0e\x43hangeWipeCode\x12\x0e\n\x06remove\x18\x01 \x01(\x08\"\x1f\n\x1d\x43learsignAttestorGetPublicKey\"0\n\x1a\x43learsignAttestorPublicKey\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\"(\n\x15\x43learsignAttestorSign\x12\x0f\n\x07payload\x18\x01 \x01(\x0c\"C\n\x1a\x43learsignAttestorSignature\x12\x11\n\tsignature\x18\x01 \x01(\x0c\x12\x12\n\npublic_key\x18\x02 \x01(\x0c*\xd1\x41\n\x0bMessageType\x12 \n\x16MessageType_Initialize\x10\x00\x1a\x04\x90\xb5\x18\x01\x12\x1a\n\x10MessageType_Ping\x10\x01\x1a\x04\x90\xb5\x18\x01\x12\x1d\n\x13MessageType_Success\x10\x02\x1a\x04\x98\xb5\x18\x01\x12\x1d\n\x13MessageType_Failure\x10\x03\x1a\x04\x98\xb5\x18\x01\x12\x1f\n\x15MessageType_ChangePin\x10\x04\x1a\x04\x90\xb5\x18\x01\x12 \n\x16MessageType_WipeDevice\x10\x05\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_FirmwareErase\x10\x06\x1a\x04\x90\xb5\x18\x01\x12$\n\x1aMessageType_FirmwareUpload\x10\x07\x1a\x04\x90\xb5\x18\x01\x12 \n\x16MessageType_GetEntropy\x10\t\x1a\x04\x90\xb5\x18\x01\x12\x1d\n\x13MessageType_Entropy\x10\n\x1a\x04\x98\xb5\x18\x01\x12\"\n\x18MessageType_GetPublicKey\x10\x0b\x1a\x04\x90\xb5\x18\x01\x12\x1f\n\x15MessageType_PublicKey\x10\x0c\x1a\x04\x98\xb5\x18\x01\x12 \n\x16MessageType_LoadDevice\x10\r\x1a\x04\x90\xb5\x18\x01\x12!\n\x17MessageType_ResetDevice\x10\x0e\x1a\x04\x90\xb5\x18\x01\x12\x1c\n\x12MessageType_SignTx\x10\x0f\x1a\x04\x90\xb5\x18\x01\x12\x1e\n\x14MessageType_Features\x10\x11\x1a\x04\x98\xb5\x18\x01\x12&\n\x1cMessageType_PinMatrixRequest\x10\x12\x1a\x04\x98\xb5\x18\x01\x12\"\n\x18MessageType_PinMatrixAck\x10\x13\x1a\x04\x90\xb5\x18\x01\x12\x1c\n\x12MessageType_Cancel\x10\x14\x1a\x04\x90\xb5\x18\x01\x12\x1f\n\x15MessageType_TxRequest\x10\x15\x1a\x04\x98\xb5\x18\x01\x12\x1b\n\x11MessageType_TxAck\x10\x16\x1a\x04\x90\xb5\x18\x01\x12$\n\x1aMessageType_CipherKeyValue\x10\x17\x1a\x04\x90\xb5\x18\x01\x12\"\n\x18MessageType_ClearSession\x10\x18\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_ApplySettings\x10\x19\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_ButtonRequest\x10\x1a\x1a\x04\x98\xb5\x18\x01\x12\x1f\n\x15MessageType_ButtonAck\x10\x1b\x1a\x04\x90\xb5\x18\x01\x12 \n\x16MessageType_GetAddress\x10\x1d\x1a\x04\x90\xb5\x18\x01\x12\x1d\n\x13MessageType_Address\x10\x1e\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_EntropyRequest\x10#\x1a\x04\x98\xb5\x18\x01\x12 \n\x16MessageType_EntropyAck\x10$\x1a\x04\x90\xb5\x18\x01\x12!\n\x17MessageType_SignMessage\x10&\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_VerifyMessage\x10\'\x1a\x04\x90\xb5\x18\x01\x12&\n\x1cMessageType_MessageSignature\x10(\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1dMessageType_PassphraseRequest\x10)\x1a\x04\x98\xb5\x18\x01\x12#\n\x19MessageType_PassphraseAck\x10*\x1a\x04\x90\xb5\x18\x01\x12$\n\x1aMessageType_RecoveryDevice\x10-\x1a\x04\x90\xb5\x18\x01\x12!\n\x17MessageType_WordRequest\x10.\x1a\x04\x98\xb5\x18\x01\x12\x1d\n\x13MessageType_WordAck\x10/\x1a\x04\x90\xb5\x18\x01\x12&\n\x1cMessageType_CipheredKeyValue\x10\x30\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_EncryptMessage\x10\x31\x1a\x04\x90\xb5\x18\x01\x12&\n\x1cMessageType_EncryptedMessage\x10\x32\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_DecryptMessage\x10\x33\x1a\x04\x90\xb5\x18\x01\x12&\n\x1cMessageType_DecryptedMessage\x10\x34\x1a\x04\x98\xb5\x18\x01\x12\"\n\x18MessageType_SignIdentity\x10\x35\x1a\x04\x90\xb5\x18\x01\x12$\n\x1aMessageType_SignedIdentity\x10\x36\x1a\x04\x98\xb5\x18\x01\x12!\n\x17MessageType_GetFeatures\x10\x37\x1a\x04\x90\xb5\x18\x01\x12(\n\x1eMessageType_EthereumGetAddress\x10\x38\x1a\x04\x90\xb5\x18\x01\x12%\n\x1bMessageType_EthereumAddress\x10\x39\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_EthereumSignTx\x10:\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1dMessageType_EthereumTxRequest\x10;\x1a\x04\x98\xb5\x18\x01\x12#\n\x19MessageType_EthereumTxAck\x10<\x1a\x04\x90\xb5\x18\x01\x12&\n\x1cMessageType_CharacterRequest\x10P\x1a\x04\x98\xb5\x18\x01\x12\"\n\x18MessageType_CharacterAck\x10Q\x1a\x04\x90\xb5\x18\x01\x12\x1e\n\x14MessageType_RawTxAck\x10R\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_ApplyPolicies\x10S\x1a\x04\x90\xb5\x18\x01\x12\x1f\n\x15MessageType_FlashHash\x10T\x1a\x04\x90\xb5\x18\x01\x12 \n\x16MessageType_FlashWrite\x10U\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1dMessageType_FlashHashResponse\x10V\x1a\x04\x98\xb5\x18\x01\x12(\n\x1eMessageType_DebugLinkFlashDump\x10W\x1a\x04\xa0\xb5\x18\x01\x12\x30\n&MessageType_DebugLinkFlashDumpResponse\x10X\x1a\x04\xa8\xb5\x18\x01\x12\x1f\n\x15MessageType_SoftReset\x10Y\x1a\x04\xa0\xb5\x18\x01\x12\'\n\x1dMessageType_DebugLinkDecision\x10\x64\x1a\x04\xa0\xb5\x18\x01\x12\'\n\x1dMessageType_DebugLinkGetState\x10\x65\x1a\x04\xa0\xb5\x18\x01\x12$\n\x1aMessageType_DebugLinkState\x10\x66\x1a\x04\xa8\xb5\x18\x01\x12#\n\x19MessageType_DebugLinkStop\x10g\x1a\x04\xa0\xb5\x18\x01\x12\"\n\x18MessageType_DebugLinkLog\x10h\x1a\x04\xa8\xb5\x18\x01\x12)\n\x1fMessageType_DebugLinkFillConfig\x10i\x1a\x04\xa8\xb5\x18\x01\x12\"\n\x18MessageType_GetCoinTable\x10j\x1a\x04\x90\xb5\x18\x01\x12\x1f\n\x15MessageType_CoinTable\x10k\x1a\x04\x98\xb5\x18\x01\x12)\n\x1fMessageType_EthereumSignMessage\x10l\x1a\x04\x90\xb5\x18\x01\x12+\n!MessageType_EthereumVerifyMessage\x10m\x1a\x04\x90\xb5\x18\x01\x12.\n$MessageType_EthereumMessageSignature\x10n\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_ChangeWipeCode\x10o\x1a\x04\x90\xb5\x18\x01\x12+\n!MessageType_EthereumSignTypedHash\x10p\x1a\x04\x90\xb5\x18\x01\x12\x30\n&MessageType_EthereumTypedDataSignature\x10q\x1a\x04\x98\xb5\x18\x01\x12,\n\"MessageType_Ethereum712TypesValues\x10r\x1a\x04\x90\xb5\x18\x01\x12(\n\x1eMessageType_EthereumTxMetadata\x10s\x1a\x04\x90\xb5\x18\x01\x12)\n\x1fMessageType_EthereumMetadataAck\x10t\x1a\x04\x98\xb5\x18\x01\x12)\n\x1fMessageType_LoadClearsignSigner\x10u\x1a\x04\x90\xb5\x18\x01\x12&\n\x1cMessageType_GetBip85Mnemonic\x10x\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_Bip85Mnemonic\x10y\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_RippleGetAddress\x10\x90\x03\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_RippleAddress\x10\x91\x03\x1a\x04\x98\xb5\x18\x01\x12#\n\x18MessageType_RippleSignTx\x10\x92\x03\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_RippleSignedTx\x10\x93\x03\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_ThorchainGetAddress\x10\xf4\x03\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1cMessageType_ThorchainAddress\x10\xf5\x03\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_ThorchainSignTx\x10\xf6\x03\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_ThorchainMsgRequest\x10\xf7\x03\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_ThorchainMsgAck\x10\xf8\x03\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_ThorchainSignedTx\x10\xf9\x03\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_EosGetPublicKey\x10\xd8\x04\x1a\x04\x90\xb5\x18\x01\x12#\n\x18MessageType_EosPublicKey\x10\xd9\x04\x1a\x04\x98\xb5\x18\x01\x12 \n\x15MessageType_EosSignTx\x10\xda\x04\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_EosTxActionRequest\x10\xdb\x04\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMessageType_EosTxActionAck\x10\xdc\x04\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17MessageType_EosSignedTx\x10\xdd\x04\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMessageType_NanoGetAddress\x10\xbc\x05\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17MessageType_NanoAddress\x10\xbd\x05\x1a\x04\x98\xb5\x18\x01\x12!\n\x16MessageType_NanoSignTx\x10\xbe\x05\x1a\x04\x90\xb5\x18\x01\x12#\n\x18MessageType_NanoSignedTx\x10\xbf\x05\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_SolanaGetAddress\x10\xee\x05\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_SolanaAddress\x10\xef\x05\x1a\x04\x98\xb5\x18\x01\x12#\n\x18MessageType_SolanaSignTx\x10\xf0\x05\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_SolanaSignedTx\x10\xf1\x05\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_SolanaSignMessage\x10\xf2\x05\x1a\x04\x90\xb5\x18\x01\x12-\n\"MessageType_SolanaMessageSignature\x10\xf3\x05\x1a\x04\x98\xb5\x18\x01\x12\x30\n%MessageType_SolanaSignOffchainMessage\x10\xf4\x05\x1a\x04\x90\xb5\x18\x01\x12\x35\n*MessageType_SolanaOffchainMessageSignature\x10\xf5\x05\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_BinanceGetAddress\x10\xa0\x06\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_BinanceAddress\x10\xa1\x06\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_BinanceGetPublicKey\x10\xa2\x06\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1cMessageType_BinancePublicKey\x10\xa3\x06\x1a\x04\x98\xb5\x18\x01\x12$\n\x19MessageType_BinanceSignTx\x10\xa4\x06\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1cMessageType_BinanceTxRequest\x10\xa5\x06\x1a\x04\x98\xb5\x18\x01\x12)\n\x1eMessageType_BinanceTransferMsg\x10\xa6\x06\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_BinanceOrderMsg\x10\xa7\x06\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1cMessageType_BinanceCancelMsg\x10\xa8\x06\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_BinanceSignedTx\x10\xa9\x06\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_CosmosGetAddress\x10\x84\x07\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_CosmosAddress\x10\x85\x07\x1a\x04\x98\xb5\x18\x01\x12#\n\x18MessageType_CosmosSignTx\x10\x86\x07\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1cMessageType_CosmosMsgRequest\x10\x87\x07\x1a\x04\x98\xb5\x18\x01\x12#\n\x18MessageType_CosmosMsgAck\x10\x88\x07\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_CosmosSignedTx\x10\x89\x07\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_CosmosMsgDelegate\x10\x8a\x07\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_CosmosMsgUndelegate\x10\x8b\x07\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_CosmosMsgRedelegate\x10\x8c\x07\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_CosmosMsgRewards\x10\x8d\x07\x1a\x04\x98\xb5\x18\x01\x12+\n MessageType_CosmosMsgIBCTransfer\x10\x8e\x07\x1a\x04\x98\xb5\x18\x01\x12+\n MessageType_TendermintGetAddress\x10\xe8\x07\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_TendermintAddress\x10\xe9\x07\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_TendermintSignTx\x10\xea\x07\x1a\x04\x90\xb5\x18\x01\x12+\n MessageType_TendermintMsgRequest\x10\xeb\x07\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_TendermintMsgAck\x10\xec\x07\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_TendermintMsgSend\x10\xed\x07\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_TendermintSignedTx\x10\xee\x07\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_TendermintMsgDelegate\x10\xef\x07\x1a\x04\x98\xb5\x18\x01\x12.\n#MessageType_TendermintMsgUndelegate\x10\xf0\x07\x1a\x04\x98\xb5\x18\x01\x12.\n#MessageType_TendermintMsgRedelegate\x10\xf1\x07\x1a\x04\x98\xb5\x18\x01\x12+\n MessageType_TendermintMsgRewards\x10\xf2\x07\x1a\x04\x98\xb5\x18\x01\x12/\n$MessageType_TendermintMsgIBCTransfer\x10\xf3\x07\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_OsmosisGetAddress\x10\xcc\x08\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_OsmosisAddress\x10\xcd\x08\x1a\x04\x98\xb5\x18\x01\x12$\n\x19MessageType_OsmosisSignTx\x10\xce\x08\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_OsmosisMsgRequest\x10\xcf\x08\x1a\x04\x98\xb5\x18\x01\x12$\n\x19MessageType_OsmosisMsgAck\x10\xd0\x08\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_OsmosisMsgSend\x10\xd1\x08\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_OsmosisMsgDelegate\x10\xd2\x08\x1a\x04\x90\xb5\x18\x01\x12+\n MessageType_OsmosisMsgUndelegate\x10\xd3\x08\x1a\x04\x90\xb5\x18\x01\x12+\n MessageType_OsmosisMsgRedelegate\x10\xd4\x08\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_OsmosisMsgRewards\x10\xd5\x08\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_OsmosisMsgLPAdd\x10\xd6\x08\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_OsmosisMsgLPRemove\x10\xd7\x08\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_OsmosisMsgLPStake\x10\xd8\x08\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_OsmosisMsgLPUnstake\x10\xd9\x08\x1a\x04\x90\xb5\x18\x01\x12,\n!MessageType_OsmosisMsgIBCTransfer\x10\xda\x08\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_OsmosisMsgSwap\x10\xdb\x08\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_OsmosisSignedTx\x10\xdc\x08\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_MayachainGetAddress\x10\xb0\t\x1a\x04\x90\xb5\x18\x01\x12\'\n\x1cMessageType_MayachainAddress\x10\xb1\t\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_MayachainSignTx\x10\xb2\t\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_MayachainMsgRequest\x10\xb3\t\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_MayachainMsgAck\x10\xb4\t\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_MayachainSignedTx\x10\xb5\t\x1a\x04\x98\xb5\x18\x01\x12$\n\x19MessageType_ZcashSignPCZT\x10\x94\n\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_ZcashPCZTAction\x10\x95\n\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_ZcashPCZTActionAck\x10\x96\n\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_ZcashSignedPCZT\x10\x97\n\x1a\x04\x98\xb5\x18\x01\x12)\n\x1eMessageType_ZcashGetOrchardFVK\x10\x98\n\x1a\x04\x90\xb5\x18\x01\x12&\n\x1bMessageType_ZcashOrchardFVK\x10\x99\n\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_ZcashTransparentInput\x10\x9a\n\x1a\x04\x90\xb5\x18\x01\x12-\n\"MessageType_ZcashTransparentSigned\x10\x9b\n\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_ZcashDisplayAddress\x10\x9c\n\x1a\x04\x90\xb5\x18\x01\x12#\n\x18MessageType_ZcashAddress\x10\x9d\n\x1a\x04\x98\xb5\x18\x01\x12-\n\"MessageType_ZcashTransparentOutput\x10\x9e\n\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_ZcashTransparentAck\x10\x9f\n\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMessageType_TronGetAddress\x10\xf8\n\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17MessageType_TronAddress\x10\xf9\n\x1a\x04\x98\xb5\x18\x01\x12!\n\x16MessageType_TronSignTx\x10\xfa\n\x1a\x04\x90\xb5\x18\x01\x12#\n\x18MessageType_TronSignedTx\x10\xfb\n\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_TronSignMessage\x10\xfc\n\x1a\x04\x90\xb5\x18\x01\x12+\n MessageType_TronMessageSignature\x10\xfd\n\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_TronVerifyMessage\x10\xfe\n\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_TronSignTypedHash\x10\xff\n\x1a\x04\x90\xb5\x18\x01\x12-\n\"MessageType_TronTypedDataSignature\x10\x80\x0b\x1a\x04\x98\xb5\x18\x01\x12$\n\x19MessageType_TonGetAddress\x10\xdc\x0b\x1a\x04\x90\xb5\x18\x01\x12!\n\x16MessageType_TonAddress\x10\xdd\x0b\x1a\x04\x98\xb5\x18\x01\x12 \n\x15MessageType_TonSignTx\x10\xde\x0b\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17MessageType_TonSignedTx\x10\xdf\x0b\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMessageType_TonSignMessage\x10\xe0\x0b\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMessageType_TonMessageSignature\x10\xe1\x0b\x1a\x04\x98\xb5\x18\x01\x12\'\n\x1cMessageType_HiveGetPublicKey\x10\xc0\x0c\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_HivePublicKey\x10\xc1\x0c\x1a\x04\x98\xb5\x18\x01\x12!\n\x16MessageType_HiveSignTx\x10\xc2\x0c\x1a\x04\x90\xb5\x18\x01\x12#\n\x18MessageType_HiveSignedTx\x10\xc3\x0c\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_HiveGetPublicKeys\x10\xc4\x0c\x1a\x04\x90\xb5\x18\x01\x12%\n\x1aMessageType_HivePublicKeys\x10\xc5\x0c\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_HiveSignAccountCreate\x10\xc6\x0c\x1a\x04\x90\xb5\x18\x01\x12.\n#MessageType_HiveSignedAccountCreate\x10\xc7\x0c\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_HiveSignAccountUpdate\x10\xc8\x0c\x1a\x04\x90\xb5\x18\x01\x12.\n#MessageType_HiveSignedAccountUpdate\x10\xc9\x0c\x1a\x04\x98\xb5\x18\x01\x12&\n\x1bMessageType_HiveSignMessage\x10\xce\x0c\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_HiveSignedMessage\x10\xcf\x0c\x1a\x04\x98\xb5\x18\x01\x12)\n\x1eMessageType_HiveSignOperations\x10\xd0\x0c\x1a\x04\x90\xb5\x18\x01\x12+\n MessageType_HiveSignedOperations\x10\xd1\x0c\x1a\x04\x98\xb5\x18\x01\x12\x34\n)MessageType_ClearsignAttestorGetPublicKey\x10\xa4\r\x1a\x04\x90\xb5\x18\x01\x12\x31\n&MessageType_ClearsignAttestorPublicKey\x10\xa5\r\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_ClearsignAttestorSign\x10\xa6\r\x1a\x04\x90\xb5\x18\x01\x12\x31\n&MessageType_ClearsignAttestorSignature\x10\xa7\r\x1a\x04\x98\xb5\x18\x01\x42,\n\x1a\x63om.keepkey.deviceprotocolB\x0eKeepKeyMessage') , dependencies=[types__pb2.DESCRIPTOR,]) @@ -855,11 +855,27 @@ name='MessageType_HiveSignedOperations', index=205, number=1617, options=_descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\230\265\030\001')), type=None), + _descriptor.EnumValueDescriptor( + name='MessageType_ClearsignAttestorGetPublicKey', index=206, number=1700, + options=_descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\220\265\030\001')), + type=None), + _descriptor.EnumValueDescriptor( + name='MessageType_ClearsignAttestorPublicKey', index=207, number=1701, + options=_descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\230\265\030\001')), + type=None), + _descriptor.EnumValueDescriptor( + name='MessageType_ClearsignAttestorSign', index=208, number=1702, + options=_descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\220\265\030\001')), + type=None), + _descriptor.EnumValueDescriptor( + name='MessageType_ClearsignAttestorSignature', index=209, number=1703, + options=_descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\230\265\030\001')), + type=None), ], containing_type=None, options=None, - serialized_start=5191, - serialized_end=13390, + serialized_start=5411, + serialized_end=13812, ) _sym_db.RegisterEnumDescriptor(_MESSAGETYPE) @@ -1070,6 +1086,10 @@ MessageType_HiveSignedMessage = 1615 MessageType_HiveSignOperations = 1616 MessageType_HiveSignedOperations = 1617 +MessageType_ClearsignAttestorGetPublicKey = 1700 +MessageType_ClearsignAttestorPublicKey = 1701 +MessageType_ClearsignAttestorSign = 1702 +MessageType_ClearsignAttestorSignature = 1703 @@ -1296,6 +1316,13 @@ message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='supports_taproot', full_name='Features.supports_taproot', index=24, + number=27, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), ], extensions=[ ], @@ -1309,7 +1336,7 @@ oneofs=[ ], serialized_start=61, - serialized_end=615, + serialized_end=641, ) @@ -1346,8 +1373,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=617, - serialized_end=659, + serialized_start=643, + serialized_end=685, ) @@ -1391,8 +1418,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=661, - serialized_end=737, + serialized_start=687, + serialized_end=763, ) @@ -1415,8 +1442,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=739, - serialized_end=753, + serialized_start=765, + serialized_end=779, ) @@ -1474,8 +1501,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=755, - serialized_end=876, + serialized_start=781, + serialized_end=902, ) @@ -1505,8 +1532,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=878, - serialized_end=905, + serialized_start=904, + serialized_end=931, ) @@ -1564,8 +1591,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=908, - serialized_end=1043, + serialized_start=934, + serialized_end=1069, ) @@ -1595,8 +1622,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1045, - serialized_end=1071, + serialized_start=1071, + serialized_end=1097, ) @@ -1633,8 +1660,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1073, - serialized_end=1127, + serialized_start=1099, + serialized_end=1153, ) @@ -1671,8 +1698,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1129, - serialized_end=1192, + serialized_start=1155, + serialized_end=1218, ) @@ -1695,8 +1722,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1194, - serialized_end=1205, + serialized_start=1220, + serialized_end=1231, ) @@ -1726,8 +1753,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1207, - serialized_end=1262, + serialized_start=1233, + serialized_end=1288, ) @@ -1757,8 +1784,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1264, - serialized_end=1291, + serialized_start=1290, + serialized_end=1317, ) @@ -1781,8 +1808,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1293, - serialized_end=1301, + serialized_start=1319, + serialized_end=1327, ) @@ -1805,8 +1832,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1303, - serialized_end=1322, + serialized_start=1329, + serialized_end=1348, ) @@ -1836,8 +1863,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1324, - serialized_end=1359, + serialized_start=1350, + serialized_end=1385, ) @@ -1867,8 +1894,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1361, - serialized_end=1387, + serialized_start=1387, + serialized_end=1413, ) @@ -1898,8 +1925,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1389, - serialized_end=1415, + serialized_start=1415, + serialized_end=1441, ) @@ -1957,8 +1984,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1418, - serialized_end=1580, + serialized_start=1444, + serialized_end=1606, ) @@ -1995,8 +2022,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1582, - serialized_end=1634, + serialized_start=1608, + serialized_end=1660, ) @@ -2054,8 +2081,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1637, - serialized_end=1816, + serialized_start=1663, + serialized_end=1842, ) @@ -2085,8 +2112,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1818, - serialized_end=1844, + serialized_start=1844, + serialized_end=1870, ) @@ -2109,8 +2136,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1846, - serialized_end=1858, + serialized_start=1872, + serialized_end=1884, ) @@ -2189,8 +2216,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1861, - serialized_end=2048, + serialized_start=1887, + serialized_end=2074, ) @@ -2276,8 +2303,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2051, - serialized_end=2276, + serialized_start=2077, + serialized_end=2302, ) @@ -2300,8 +2327,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2278, - serialized_end=2294, + serialized_start=2304, + serialized_end=2320, ) @@ -2331,8 +2358,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2296, - serialized_end=2325, + serialized_start=2322, + serialized_end=2351, ) @@ -2425,8 +2452,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2328, - serialized_end=2583, + serialized_start=2354, + serialized_end=2609, ) @@ -2449,8 +2476,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2585, - serialized_end=2598, + serialized_start=2611, + serialized_end=2624, ) @@ -2480,8 +2507,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2600, - serialized_end=2623, + serialized_start=2626, + serialized_end=2649, ) @@ -2518,8 +2545,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2625, - serialized_end=2684, + serialized_start=2651, + serialized_end=2710, ) @@ -2563,8 +2590,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2686, - serialized_end=2749, + serialized_start=2712, + serialized_end=2775, ) @@ -2615,8 +2642,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2752, - serialized_end=2882, + serialized_start=2778, + serialized_end=2908, ) @@ -2667,8 +2694,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2884, - serialized_end=2980, + serialized_start=2910, + serialized_end=3006, ) @@ -2705,8 +2732,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2982, - serialized_end=3036, + serialized_start=3008, + serialized_end=3062, ) @@ -2764,8 +2791,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3038, - serialized_end=3156, + serialized_start=3064, + serialized_end=3182, ) @@ -2809,8 +2836,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3158, - serialized_end=3222, + serialized_start=3184, + serialized_end=3248, ) @@ -2861,8 +2888,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3224, - serialized_end=3305, + serialized_start=3250, + serialized_end=3331, ) @@ -2899,8 +2926,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3307, - serialized_end=3359, + serialized_start=3333, + serialized_end=3385, ) @@ -2972,8 +2999,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3362, - serialized_end=3502, + serialized_start=3388, + serialized_end=3528, ) @@ -3003,8 +3030,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3504, - serialized_end=3537, + serialized_start=3530, + serialized_end=3563, ) @@ -3041,8 +3068,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3539, - serialized_end=3592, + serialized_start=3565, + serialized_end=3618, ) @@ -3072,8 +3099,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3594, - serialized_end=3627, + serialized_start=3620, + serialized_end=3653, ) @@ -3159,8 +3186,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3630, - serialized_end=3836, + serialized_start=3656, + serialized_end=3862, ) @@ -3204,8 +3231,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3839, - serialized_end=3972, + serialized_start=3865, + serialized_end=3998, ) @@ -3235,8 +3262,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3974, - serialized_end=4011, + serialized_start=4000, + serialized_end=4037, ) @@ -3266,8 +3293,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4013, - serialized_end=4056, + serialized_start=4039, + serialized_end=4082, ) @@ -3318,8 +3345,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4058, - serialized_end=4183, + serialized_start=4084, + serialized_end=4209, ) @@ -3363,8 +3390,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4185, - serialized_end=4257, + serialized_start=4211, + serialized_end=4283, ) @@ -3394,8 +3421,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4259, - serialized_end=4303, + serialized_start=4285, + serialized_end=4329, ) @@ -3439,8 +3466,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4305, - serialized_end=4368, + serialized_start=4331, + serialized_end=4394, ) @@ -3484,8 +3511,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4370, - serialized_end=4428, + serialized_start=4396, + serialized_end=4454, ) @@ -3515,8 +3542,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4430, - serialized_end=4463, + serialized_start=4456, + serialized_end=4489, ) @@ -3553,8 +3580,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4465, - serialized_end=4518, + serialized_start=4491, + serialized_end=4544, ) @@ -3584,8 +3611,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4520, - serialized_end=4562, + serialized_start=4546, + serialized_end=4588, ) @@ -3608,8 +3635,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4564, - serialized_end=4575, + serialized_start=4590, + serialized_end=4601, ) @@ -3632,8 +3659,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4577, - serialized_end=4592, + serialized_start=4603, + serialized_end=4618, ) @@ -3670,8 +3697,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4594, - serialized_end=4649, + serialized_start=4620, + serialized_end=4675, ) @@ -3701,8 +3728,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4651, - serialized_end=4686, + serialized_start=4677, + serialized_end=4712, ) @@ -3725,8 +3752,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4688, - serialized_end=4707, + serialized_start=4714, + serialized_end=4733, ) @@ -3847,8 +3874,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4710, - serialized_end=5053, + serialized_start=4736, + serialized_end=5079, ) @@ -3871,8 +3898,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5055, - serialized_end=5070, + serialized_start=5081, + serialized_end=5096, ) @@ -3916,8 +3943,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5072, - serialized_end=5131, + serialized_start=5098, + serialized_end=5157, ) @@ -3940,8 +3967,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5133, - serialized_end=5154, + serialized_start=5159, + serialized_end=5180, ) @@ -3971,8 +3998,132 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5156, - serialized_end=5188, + serialized_start=5182, + serialized_end=5214, +) + + +_CLEARSIGNATTESTORGETPUBLICKEY = _descriptor.Descriptor( + name='ClearsignAttestorGetPublicKey', + full_name='ClearsignAttestorGetPublicKey', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto2', + extension_ranges=[], + oneofs=[ + ], + serialized_start=5216, + serialized_end=5247, +) + + +_CLEARSIGNATTESTORPUBLICKEY = _descriptor.Descriptor( + name='ClearsignAttestorPublicKey', + full_name='ClearsignAttestorPublicKey', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='public_key', full_name='ClearsignAttestorPublicKey.public_key', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto2', + extension_ranges=[], + oneofs=[ + ], + serialized_start=5249, + serialized_end=5297, +) + + +_CLEARSIGNATTESTORSIGN = _descriptor.Descriptor( + name='ClearsignAttestorSign', + full_name='ClearsignAttestorSign', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='payload', full_name='ClearsignAttestorSign.payload', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto2', + extension_ranges=[], + oneofs=[ + ], + serialized_start=5299, + serialized_end=5339, +) + + +_CLEARSIGNATTESTORSIGNATURE = _descriptor.Descriptor( + name='ClearsignAttestorSignature', + full_name='ClearsignAttestorSignature', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='signature', full_name='ClearsignAttestorSignature.signature', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='public_key', full_name='ClearsignAttestorSignature.public_key', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto2', + extension_ranges=[], + oneofs=[ + ], + serialized_start=5341, + serialized_end=5408, ) _FEATURES.fields_by_name['coins'].message_type = types__pb2._COINTYPE @@ -4062,6 +4213,10 @@ DESCRIPTOR.message_types_by_name['DebugLinkLog'] = _DEBUGLINKLOG DESCRIPTOR.message_types_by_name['DebugLinkFillConfig'] = _DEBUGLINKFILLCONFIG DESCRIPTOR.message_types_by_name['ChangeWipeCode'] = _CHANGEWIPECODE +DESCRIPTOR.message_types_by_name['ClearsignAttestorGetPublicKey'] = _CLEARSIGNATTESTORGETPUBLICKEY +DESCRIPTOR.message_types_by_name['ClearsignAttestorPublicKey'] = _CLEARSIGNATTESTORPUBLICKEY +DESCRIPTOR.message_types_by_name['ClearsignAttestorSign'] = _CLEARSIGNATTESTORSIGN +DESCRIPTOR.message_types_by_name['ClearsignAttestorSignature'] = _CLEARSIGNATTESTORSIGNATURE DESCRIPTOR.enum_types_by_name['MessageType'] = _MESSAGETYPE _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -4534,6 +4689,34 @@ )) _sym_db.RegisterMessage(ChangeWipeCode) +ClearsignAttestorGetPublicKey = _reflection.GeneratedProtocolMessageType('ClearsignAttestorGetPublicKey', (_message.Message,), dict( + DESCRIPTOR = _CLEARSIGNATTESTORGETPUBLICKEY, + __module__ = 'messages_pb2' + # @@protoc_insertion_point(class_scope:ClearsignAttestorGetPublicKey) + )) +_sym_db.RegisterMessage(ClearsignAttestorGetPublicKey) + +ClearsignAttestorPublicKey = _reflection.GeneratedProtocolMessageType('ClearsignAttestorPublicKey', (_message.Message,), dict( + DESCRIPTOR = _CLEARSIGNATTESTORPUBLICKEY, + __module__ = 'messages_pb2' + # @@protoc_insertion_point(class_scope:ClearsignAttestorPublicKey) + )) +_sym_db.RegisterMessage(ClearsignAttestorPublicKey) + +ClearsignAttestorSign = _reflection.GeneratedProtocolMessageType('ClearsignAttestorSign', (_message.Message,), dict( + DESCRIPTOR = _CLEARSIGNATTESTORSIGN, + __module__ = 'messages_pb2' + # @@protoc_insertion_point(class_scope:ClearsignAttestorSign) + )) +_sym_db.RegisterMessage(ClearsignAttestorSign) + +ClearsignAttestorSignature = _reflection.GeneratedProtocolMessageType('ClearsignAttestorSignature', (_message.Message,), dict( + DESCRIPTOR = _CLEARSIGNATTESTORSIGNATURE, + __module__ = 'messages_pb2' + # @@protoc_insertion_point(class_scope:ClearsignAttestorSignature) + )) +_sym_db.RegisterMessage(ClearsignAttestorSignature) + DESCRIPTOR.has_options = True DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\032com.keepkey.deviceprotocolB\016KeepKeyMessage')) @@ -4949,4 +5132,12 @@ _MESSAGETYPE.values_by_name["MessageType_HiveSignOperations"]._options = _descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\220\265\030\001')) _MESSAGETYPE.values_by_name["MessageType_HiveSignedOperations"].has_options = True _MESSAGETYPE.values_by_name["MessageType_HiveSignedOperations"]._options = _descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\230\265\030\001')) +_MESSAGETYPE.values_by_name["MessageType_ClearsignAttestorGetPublicKey"].has_options = True +_MESSAGETYPE.values_by_name["MessageType_ClearsignAttestorGetPublicKey"]._options = _descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\220\265\030\001')) +_MESSAGETYPE.values_by_name["MessageType_ClearsignAttestorPublicKey"].has_options = True +_MESSAGETYPE.values_by_name["MessageType_ClearsignAttestorPublicKey"]._options = _descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\230\265\030\001')) +_MESSAGETYPE.values_by_name["MessageType_ClearsignAttestorSign"].has_options = True +_MESSAGETYPE.values_by_name["MessageType_ClearsignAttestorSign"]._options = _descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\220\265\030\001')) +_MESSAGETYPE.values_by_name["MessageType_ClearsignAttestorSignature"].has_options = True +_MESSAGETYPE.values_by_name["MessageType_ClearsignAttestorSignature"]._options = _descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\230\265\030\001')) # @@protoc_insertion_point(module_scope) diff --git a/tests/common.py b/tests/common.py index ed9db0d2..275ef28d 100644 --- a/tests/common.py +++ b/tests/common.py @@ -127,6 +127,18 @@ def requires_firmware(self, ver_required): if semver.VersionInfo.parse(version) < semver.VersionInfo.parse(ver_required): self.skipTest("Firmware version " + ver_required + " or higher is required to run this test") + def requires_taproot(self): + """Skip unless the firmware reports taproot support. + + Gates on a capability rather than a version. Which release taproot + ships in is still open, and a version gate that is never reached makes + these tests silently green forever -- the failure mode that looks + exactly like passing. + """ + self.client.init_device() + if not getattr(self.client.features, 'supports_taproot', False): + self.skipTest("Firmware does not report supports_taproot") + def requires_message(self, msg_name): """Skip if firmware does not handle this message type. Use alongside requires_firmware for per-feature gating: diff --git a/tests/test_msg_getaddress_taproot.py b/tests/test_msg_getaddress_taproot.py index 1c08b239..544c2042 100644 --- a/tests/test_msg_getaddress_taproot.py +++ b/tests/test_msg_getaddress_taproot.py @@ -19,10 +19,6 @@ from keepkeylib.tools import parse_path -# Version in which SPENDTAPROOT support lands. Keep this in step with -# CMakeLists.txt: if the firmware version is below it these tests SKIP, so a -# value that is never reached makes them silently green forever. -TAPROOT_FIRMWARE_VERSION = "7.16.0" class TestMsgGetaddressTaproot(common.KeepKeyTest): @@ -38,7 +34,7 @@ def test_taproot_bip86_vectors(self): this implementation produced -- the comparison is against independent ground truth. """ - self.requires_firmware(TAPROOT_FIRMWARE_VERSION) + self.requires_taproot() self.setup_mnemonic_abandon() self.client.clear_session() diff --git a/tests/test_msg_signtx_taproot.py b/tests/test_msg_signtx_taproot.py index 369f1e9a..ebf86048 100644 --- a/tests/test_msg_signtx_taproot.py +++ b/tests/test_msg_signtx_taproot.py @@ -24,8 +24,6 @@ from keepkeylib.tx_api import TxApiBitcoin -# Keep in step with CMakeLists.txt; see test_msg_getaddress_taproot.py. -TAPROOT_FIRMWARE_VERSION = "7.16.0" # Synthetic prev tx paying 100000 sat to the BIP-86 first receiving address of # the "abandon abandon ... about" mnemonic @@ -55,7 +53,7 @@ def test_send_p2tr(self): through our own verifier, which would pass even if the device committed to the wrong transaction. """ - self.requires_firmware(TAPROOT_FIRMWARE_VERSION) + self.requires_taproot() self.setup_mnemonic_abandon() self.client.set_tx_api(TxApiBitcoin) diff --git a/tests/test_taproot_screens.py b/tests/test_taproot_screens.py new file mode 100644 index 00000000..eff527a1 --- /dev/null +++ b/tests/test_taproot_screens.py @@ -0,0 +1,43 @@ +"""Gate-3 OLED capture: long bech32 addresses on the verification screen.""" +import common +import unittest + +from common import KeepKeyTest +from keepkeylib import ckd_public as bip32 +from keepkeylib import types_pb2 as proto_types +from keepkeylib.tools import parse_path + + +class TestTaprootScreens(KeepKeyTest): + + def test_show_taproot_receive_address(self): + self.requires_taproot() + self.setup_mnemonic_abandon() + self.client.clear_session() + addr = self.client.get_address( + "Bitcoin", parse_path("86'/0'/0'/0/0"), True, None, + script_type=proto_types.SPENDTAPROOT) + self.assertEqual( + addr, + 'bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr') + + def test_show_p2wsh_multisig_address(self): + """Native segwit multisig: 62 chars, same as p2tr. Predates taproot.""" + self.setup_mnemonic_allallall() + self.client.clear_session() + nodes = [self.client.get_public_node(parse_path("999'/1'/%d'" % i)) + for i in range(1, 4)] + multisig = proto_types.MultisigRedeemScriptType( + pubkeys=[proto_types.HDNodePathType( + node=bip32.deserialize(n.xpub), address_n=[2, 0]) for n in nodes], + signatures=[b'', b'', b''], + m=2, + ) + addr = self.client.get_address( + "Testnet", parse_path("999'/1'/1'/2/0"), True, multisig, + script_type=proto_types.SPENDWITNESS) + print("\nP2WSH address (%d chars): %s" % (len(addr), addr)) + + +if __name__ == '__main__': + unittest.main() From 5d7580100f245f18c5ada678e7bdab6073b280f2 Mon Sep 17 00:00:00 2001 From: highlander Date: Sun, 2 Aug 2026 15:43:52 -0300 Subject: [PATCH 4/6] test: cover production Taproot signing paths --- scripts/generate-test-report.py | 49 ++++++-- tests/test_msg_getaddress_taproot.py | 12 ++ tests/test_msg_signtx_taproot.py | 111 ++++++++++++++++++ ...e4f853942c55c4ddbc2771b348413eeeca9a4.json | 29 +++++ 4 files changed, 190 insertions(+), 11 deletions(-) create mode 100644 tests/txcache/insight_bitcoin_tx_3e1fdf082678a8a2f378995ffc0e4f853942c55c4ddbc2771b348413eeeca9a4.json diff --git a/scripts/generate-test-report.py b/scripts/generate-test-report.py index 6726fe16..fcf58a58 100644 --- a/scripts/generate-test-report.py +++ b/scripts/generate-test-report.py @@ -765,25 +765,52 @@ def _arg_shown(a): 'Transaction with both legacy and SegWit inputs in the same transaction.', []), ('B20', 'test_msg_signtx_p2tr', 'test_send_p2tr_only', - 'Sign Taproot P2TR tx', - 'Taproot (BIP-341/342) with Schnorr signatures. Newest address type with improved ' - 'privacy and efficiency.', - ['Taproot confirmation']), - ('B21', 'test_msg_signmessage', 'test_sign', + 'Create a Taproot P2TR output', + 'Pays from SegWit inputs to a P2TR output. This exercises P2TR output parsing and ' + 'display, but does not exercise a Schnorr key-path spend.', + ['Taproot output confirmation']), + ('B21', 'test_msg_signtx_taproot', 'test_send_p2tr', + 'Sign a Taproot key-path spend', + 'Spends a BIP-86 P2TR input using BIP-341 SIGHASH_DEFAULT and a BIP-340 Schnorr ' + 'signature. The 64-byte witness is compared byte-for-byte with an independently ' + 'computed reference value.', + ['P2TR recipient confirmation', 'Fee confirmation']), + ('B22', 'test_msg_signtx_taproot', 'test_send_p2tr_with_change', + 'Sign P2TR with device-derived change', + 'Derives m/86\'/0\'/0\'/1/0 on-device, emits a P2TR change output, and verifies ' + 'the Schnorr witness against an independent BIP-340/341 reference.', + ['P2TR recipient confirmation', 'Fee confirmation']), + ('B23', 'test_msg_signtx_taproot', 'test_send_mixed_p2tr_and_legacy', + 'Sign mixed Taproot and legacy inputs', + 'Commits the P2TR signature to both inputs, including the legacy prevout amount and ' + 'scriptPubKey, while independently verifying the resulting Schnorr witness.', + []), + ('B24', 'test_msg_signtx_taproot', + 'test_mixed_p2tr_requires_every_input_amount', + 'Reject incomplete mixed Taproot commitments', + 'Fails closed when any input amount is absent, preventing the device from producing ' + 'a valid Schnorr signature over an incomplete BIP-341 commitment.', + []), + ('B25', 'test_msg_getaddress_taproot', 'test_show_taproot_address', + 'Show BIP-86 address on OLED', + 'Displays the complete bech32m Taproot receive address and QR code on the trusted ' + 'device screen for host-independent verification.', + ['Taproot address + QR code']), + ('B26', 'test_msg_signmessage', 'test_sign', 'Sign message with BTC key', 'Signs arbitrary text with a BTC address key. Used for proof-of-ownership and login.', ['Sign message on OLED']), - ('B22', 'test_msg_signmessage_segwit', 'test_sign', + ('B27', 'test_msg_signmessage_segwit', 'test_sign', 'Sign message with SegWit key', 'Message signing with P2SH-SegWit address key.', []), - ('B23', 'test_msg_signmessage_segwit_native', 'test_sign', + ('B28', 'test_msg_signmessage_segwit_native', 'test_sign', 'Sign message with bech32 key', 'Message signing with native SegWit address key.', []), - ('B24', 'test_msg_verifymessage', 'test_message_verify', + ('B29', 'test_msg_verifymessage', 'test_message_verify', 'Verify signed message', 'Device verifies a message signature against a BTC address.', []), - ('B25', 'test_msg_signtx_bgold', 'test_send_bitcoin_gold_nochange', + ('B30', 'test_msg_signtx_bgold', 'test_send_bitcoin_gold_nochange', 'Sign Bitcoin Gold tx', 'BTG fork uses same signing code with different chain parameters.', []), - ('B26', 'test_msg_signtx_dash', 'test_send_dash', + ('B31', 'test_msg_signtx_dash', 'test_send_dash', 'Sign Dash transaction', 'Dash special transaction types (InstantSend-compatible).', []), - ('B27', 'test_msg_signtx_grs', 'test_one_one_fee', + ('B32', 'test_msg_signtx_grs', 'test_one_one_fee', 'Sign Groestlcoin tx', 'GRS uses Groestl hash instead of SHA-256d for tx hashing.', []), # Zcash transparent signing moved to its own section Y (Zcash Transparent). ]), diff --git a/tests/test_msg_getaddress_taproot.py b/tests/test_msg_getaddress_taproot.py index 544c2042..650b8de6 100644 --- a/tests/test_msg_getaddress_taproot.py +++ b/tests/test_msg_getaddress_taproot.py @@ -59,6 +59,18 @@ def test_taproot_bip86_vectors(self): script_type=proto.SPENDTAPROOT), 'bc1p3qkhfews2uk44qtvauqyr2ttdsw7svhkl9nkm9s9c3x4ax5h60wqwruhk7') + def test_show_taproot_address(self): + """Display the full BIP-86 address on the trusted OLED.""" + self.requires_taproot() + self.setup_mnemonic_abandon() + self.client.clear_session() + address = self.client.get_address( + "Bitcoin", parse_path("86'/0'/0'/0/0"), True, None, + script_type=proto.SPENDTAPROOT) + self.assertEqual( + address, + 'bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr') + if __name__ == '__main__': unittest.main() diff --git a/tests/test_msg_signtx_taproot.py b/tests/test_msg_signtx_taproot.py index ebf86048..e4191cbd 100644 --- a/tests/test_msg_signtx_taproot.py +++ b/tests/test_msg_signtx_taproot.py @@ -20,6 +20,7 @@ from common import KeepKeyTest from keepkeylib import messages_pb2 as proto from keepkeylib import types_pb2 as proto_types +from keepkeylib.client import CallException from keepkeylib.tools import parse_path from keepkeylib.tx_api import TxApiBitcoin @@ -41,6 +42,22 @@ "2d9ee77e34af56fe1f59f98372011f7cb400ced614d808c690c5ba907fb62de9" ) +EXPECTED_CHANGE_WITNESS = ( + "e3c44408fe61256ad406733f100f1ee856eb31854335efa59e60a61ea5d41ab" + "341802f0cccb55f644042a1ab390f0a406b9d3efe3996d05442b4ee43d5355eab" +) +EXPECTED_CHANGE_SCRIPT = ( + "5120882d74e5d0572d5a816cef0041a96b6c1de832f6f9676d9605c44d5e9a97d3dc" +) + +MIXED_PREV_TXID = ( + "3e1fdf082678a8a2f378995ffc0e4f853942c55c4ddbc2771b348413eeeca9a4" +) +EXPECTED_MIXED_WITNESS = ( + "b596e1bbefb855af9852942797075d4f452b2d186cb17a76226892334a497a62" + "adb9a02f7c1b4573e4d48b92e2307bb0b2282c97e2c5350bb3c21619fab855a2" +) + class TestMsgSigntxTaproot(KeepKeyTest): @@ -75,6 +92,100 @@ def test_send_p2tr(self): self.assertEqual(len(signatures), 1) self.assertEqual(hexlify(signatures[0]).decode(), EXPECTED_WITNESS) + def test_send_p2tr_with_change(self): + """P2TR change is device-derived and omitted from recipient prompts.""" + self.requires_taproot() + self.setup_mnemonic_abandon() + self.client.set_tx_api(TxApiBitcoin) + + inp1 = proto_types.TxInputType( + address_n=parse_path("86'/0'/0'/0/0"), + amount=IN_AMOUNT, + prev_hash=unhexlify(PREV_TXID), + prev_index=0, + script_type=proto_types.SPENDTAPROOT, + ) + recipient = proto_types.TxOutputType( + address=OUT_ADDRESS, + amount=50000, + script_type=proto_types.PAYTOADDRESS, + ) + change = proto_types.TxOutputType( + address_n=parse_path("86'/0'/0'/1/0"), + amount=40000, + script_type=proto_types.PAYTOTAPROOT, + ) + + (signatures, serialized) = self.client.sign_tx( + "Bitcoin", [inp1], [recipient, change]) + + self.assertEqual(hexlify(signatures[0]).decode(), + EXPECTED_CHANGE_WITNESS) + self.assertIn(unhexlify(EXPECTED_CHANGE_SCRIPT), serialized) + + def test_send_mixed_p2tr_and_legacy(self): + """A P2TR signature commits to the legacy input's real prevout.""" + self.requires_taproot() + self.setup_mnemonic_abandon() + self.client.set_tx_api(TxApiBitcoin) + + taproot = proto_types.TxInputType( + address_n=parse_path("86'/0'/0'/0/0"), + amount=100000, + prev_hash=unhexlify(MIXED_PREV_TXID), + prev_index=0, + script_type=proto_types.SPENDTAPROOT, + ) + legacy = proto_types.TxInputType( + address_n=parse_path("44'/0'/0'/0/0"), + amount=50000, + prev_hash=unhexlify(MIXED_PREV_TXID), + prev_index=1, + script_type=proto_types.SPENDADDRESS, + ) + recipient = proto_types.TxOutputType( + address=OUT_ADDRESS, + amount=140000, + script_type=proto_types.PAYTOADDRESS, + ) + + (signatures, _) = self.client.sign_tx( + "Bitcoin", [taproot, legacy], [recipient]) + + self.assertEqual(len(signatures), 2) + self.assertEqual(hexlify(signatures[0]).decode(), + EXPECTED_MIXED_WITNESS) + self.assertTrue(signatures[1]) + + def test_mixed_p2tr_requires_every_input_amount(self): + """Fail closed instead of signing an incomplete BIP-341 commitment.""" + self.requires_taproot() + self.setup_mnemonic_abandon() + self.client.set_tx_api(TxApiBitcoin) + + taproot = proto_types.TxInputType( + address_n=parse_path("86'/0'/0'/0/0"), + amount=100000, + prev_hash=unhexlify(MIXED_PREV_TXID), + prev_index=0, + script_type=proto_types.SPENDTAPROOT, + ) + incomplete_legacy = proto_types.TxInputType( + address_n=parse_path("44'/0'/0'/0/0"), + prev_hash=unhexlify(MIXED_PREV_TXID), + prev_index=1, + script_type=proto_types.SPENDADDRESS, + ) + recipient = proto_types.TxOutputType( + address=OUT_ADDRESS, + amount=140000, + script_type=proto_types.PAYTOADDRESS, + ) + + with self.assertRaises(CallException): + self.client.sign_tx( + "Bitcoin", [taproot, incomplete_legacy], [recipient]) + if __name__ == '__main__': unittest.main() diff --git a/tests/txcache/insight_bitcoin_tx_3e1fdf082678a8a2f378995ffc0e4f853942c55c4ddbc2771b348413eeeca9a4.json b/tests/txcache/insight_bitcoin_tx_3e1fdf082678a8a2f378995ffc0e4f853942c55c4ddbc2771b348413eeeca9a4.json new file mode 100644 index 00000000..7d999532 --- /dev/null +++ b/tests/txcache/insight_bitcoin_tx_3e1fdf082678a8a2f378995ffc0e4f853942c55c4ddbc2771b348413eeeca9a4.json @@ -0,0 +1,29 @@ +{ + "txid": "3e1fdf082678a8a2f378995ffc0e4f853942c55c4ddbc2771b348413eeeca9a4", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "0000000000000000000000000000000000000000000000000000000000000000", + "vout": 0, + "sequence": 4294967295, + "scriptSig": {"hex": ""} + } + ], + "vout": [ + { + "value": "0.00100000", + "n": 0, + "scriptPubKey": { + "hex": "5120a60869f0dbcf1dc659c9cecbaf8050135ea9e8cdc487053f1dc6880949dc684c" + } + }, + { + "value": "0.00050000", + "n": 1, + "scriptPubKey": { + "hex": "76a914d986ed01b7a22225a70edbf2ba7cfb63a15cb3aa88ac" + } + } + ] +} From e11a2a16499cba6445ab8e311383db5adf38fa7b Mon Sep 17 00:00:00 2001 From: highlander Date: Sun, 2 Aug 2026 18:24:09 -0300 Subject: [PATCH 5/6] test(report): bind Taproot release evidence --- scripts/generate-test-report.py | 17 ++++++++++++----- tests/test_msg_signtx_taproot.py | 4 +++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/scripts/generate-test-report.py b/scripts/generate-test-report.py index fcf58a58..914bd615 100644 --- a/scripts/generate-test-report.py +++ b/scripts/generate-test-report.py @@ -387,6 +387,8 @@ def parse_junit(path): ('test_msg_ethereum_clear_signing', 'test_clearsign_erc4337_entrypoint_v0_7_handleops'), ('test_msg_ethereum_clear_signing', 'test_clearsign_safe_exectransaction'), ('test_msg_ethereum_clear_signing', 'test_clearsign_permit2_permit_transfer_from'), + ('test_msg_ethereum_clear_signing', + 'test_v2_calldata_length_mismatch_falls_back_to_raw_review'), # Native THOR/MAYA memo hardening: the raw memo pager (MEMO 1/N .. N/N, # complete memo bytes, sole memo gate) IS the security story — show every # page for every memo variant, not a single best frame. @@ -1371,13 +1373,14 @@ def _arg_shown(a): 'the device decodes.', ['Clearsign warning', 'v2 decoded transfer to/amount', 'Sign transaction']), ('VS6', 'test_msg_ethereum_clear_signing', - 'test_v2_calldata_length_mismatch_falls_back_to_blind_sign_gate', - 'v2 decode-mismatch falls back to blind-sign (fail-closed)', + 'test_v2_calldata_length_mismatch_falls_back_to_raw_review', + 'v2 decode-mismatch falls back to raw review (fail-closed)', 'THE headline v2 security property: schema says 2 words, calldata carries 3. ' 'decode_v2_args\' structural completeness check fails, so the device does NOT ' - 'clear-sign a decode that would not match what it is about to sign — it falls ' - 'through to the ordinary blind-sign gate, and AdvancedMode OFF hard-rejects it.', - ['Blind signing disabled (Failure)']), + 'clear-sign a decode that would not match what it is about to sign. With ' + 'AdvancedMode ON it falls through to the ordinary unverified raw review, and ' + 'the ordered OLED captures prove the decoded ClearSign display was not used.', + ['Unverified transaction warning', 'Raw data review', 'Sign transaction']), ('VS7', 'test_msg_ethereum_clear_signing', 'test_v2_unsupported_arg_format_returns_malformed', 'v2 unsupported arg format rejected at blob load', @@ -1982,6 +1985,7 @@ def render(output_path, fw_version, results, screenshot_dir=None): pdf = PDF(); pb = PB(pdf) _build_frame_census(screenshot_dir) ts = datetime.now().strftime('%Y-%m-%d %H:%M') + build_label = os.environ.get('KK_BUILD_LABEL', '').strip() active = [(l,t,mf,bg,fl,tests) for l,t,mf,bg,fl,tests in SECTIONS if ver_ge(fw_version, mf)] # Separate specs section (no tests) from test sections specs = [s for s in active if not s[5]] @@ -2021,6 +2025,9 @@ def _section_state(s): if skipped: parts.append(f'{skipped} skipped') if missing: parts.append(f'{missing} pending') pb.text(10, f'Firmware {fw_version} | {ts} | {total} tests: {", ".join(parts)}') + if build_label: + for line in _w(f'Candidate: {build_label}', 95): + pb.text(8, line, bold=True) pb.gap(6) pb.text(12, 'Sections', bold=True) _hdr_withheld = _hdr_pending = False diff --git a/tests/test_msg_signtx_taproot.py b/tests/test_msg_signtx_taproot.py index e4191cbd..1c4407b2 100644 --- a/tests/test_msg_signtx_taproot.py +++ b/tests/test_msg_signtx_taproot.py @@ -182,7 +182,9 @@ def test_mixed_p2tr_requires_every_input_amount(self): script_type=proto_types.PAYTOADDRESS, ) - with self.assertRaises(CallException): + with self.assertRaisesRegex( + CallException, + "Taproot transaction input without amount"): self.client.sign_tx( "Bitcoin", [taproot, incomplete_legacy], [recipient]) From eac1ad2cbb1bb5dec5c68f8240d91a4d07e935e6 Mon Sep 17 00:00:00 2001 From: highlander Date: Sun, 2 Aug 2026 18:46:18 -0300 Subject: [PATCH 6/6] chore: pin canonical Taproot protocol staging --- device-protocol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device-protocol b/device-protocol index be285490..674777f6 160000 --- a/device-protocol +++ b/device-protocol @@ -1 +1 @@ -Subproject commit be2854903f8795daf42ca7b96d93fc348b886b58 +Subproject commit 674777f6d4dd16e2b8c4c2df10608976375ee879