diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..f2fb620f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,8 @@ +# Checklist + +- [ ] App update process has been followed +- [ ] Target branch is `develop` +- [ ] Application version has been bumped + + diff --git a/.github/workflows/build_and_functional_tests.yml b/.github/workflows/build_and_functional_tests.yml new file mode 100644 index 00000000..927806a0 --- /dev/null +++ b/.github/workflows/build_and_functional_tests.yml @@ -0,0 +1,33 @@ +name: Build and run functional tests using ragger through reusable workflow + +# This workflow will build the app and then run functional tests using the Ragger framework upon Speculos emulation. +# It calls a reusable workflow developed by Ledger's internal developer team to build the application and upload the +# resulting binaries. +# It then calls another reusable workflow to run the Ragger tests on the compiled application binary. +# +# While this workflow is optional, having functional testing on your application is mandatory and this workflow and +# tooling environment is meant to be easy to use and adapt after forking your application + +on: + workflow_dispatch: + push: + branches: + - master + - main + - develop + pull_request: + +jobs: + build_application: + name: Build application using the reusable workflow + uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_build.yml@v1 + with: + upload_app_binaries_artifact: "compiled_app_binaries" + flags: "COIN=bitcoin_testnet_legacy" + + ragger_tests: + name: Run ragger tests using the reusable workflow + needs: build_application + uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_ragger_tests.yml@v1 + with: + download_app_binaries_artifact: "compiled_app_binaries" diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml deleted file mode 100644 index f8d7a9e2..00000000 --- a/.github/workflows/ci-workflow.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: CI - -on: [push, pull_request] - -jobs: - job_build: - name: Compilation - runs-on: ubuntu-latest - - container: - image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest - - steps: - - name: Clone - uses: actions/checkout@v2 - - - name: Build - run: | - make && mv bin/ bitcoin-bin/ - make clean - make COIN=bitcoin_testnet_legacy && mv bin/ bitcoin-testnet-bin/ - - - name: Upload Bitcoin app binary - uses: actions/upload-artifact@v2 - with: - name: bitcoin-app - path: bitcoin-bin - - - name: Upload Bitcoin Testnet app binary - uses: actions/upload-artifact@v2 - with: - name: bitcoin-testnet-app - path: bitcoin-testnet-bin - - job_test: - name: Tests - needs: job_build - runs-on: ubuntu-latest - - container: - image: ghcr.io/ledgerhq/speculos:latest - ports: - - 1234:1234 - - 9999:9999 - - 40000:40000 - - 41000:41000 - - 42000:42000 - - 43000:43000 - options: --entrypoint /bin/bash - - steps: - - name: Clone - uses: actions/checkout@v2 - - - name: Download Bitcoin app binary - uses: actions/download-artifact@v2 - with: - name: bitcoin-app - path: tests/bitcoin-bin - - - name: Download Bitcoin Testnet app binary - uses: actions/download-artifact@v2 - with: - name: bitcoin-testnet-app - path: tests/bitcoin-testnet-bin - - - name: Run tests - run: | - cd tests && pip install -r requirements.txt && SPECULOS=/speculos/speculos.py pytest diff --git a/.github/workflows/guidelines_enforcer.yml b/.github/workflows/guidelines_enforcer.yml new file mode 100644 index 00000000..fdaf9f27 --- /dev/null +++ b/.github/workflows/guidelines_enforcer.yml @@ -0,0 +1,23 @@ +name: Ensure compliance with Ledger guidelines + +# This workflow is mandatory in all applications +# It calls a reusable workflow guidelines_enforcer developed by Ledger's internal developer team. +# The successful completion of the reusable workflow is a mandatory step for an app to be available on the Ledger +# application store. +# +# More information on the guidelines can be found in the repository: +# LedgerHQ/ledger-app-workflows/ + +on: + workflow_dispatch: + push: + branches: + - master + - main + - develop + pull_request: + +jobs: + guidelines_enforcer: + name: Call Ledger guidelines_enforcer + uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_guidelines_enforcer.yml@v1 diff --git a/.github/workflows/swap-ci-workflow.yml b/.github/workflows/swap-ci-workflow.yml new file mode 100644 index 00000000..660a3132 --- /dev/null +++ b/.github/workflows/swap-ci-workflow.yml @@ -0,0 +1,16 @@ +name: Swap functional tests + +on: + workflow_dispatch: + push: + branches: + - master + - develop + pull_request: + +jobs: + job_functional_tests: + uses: LedgerHQ/app-exchange/.github/workflows/reusable_swap_functional_tests.yml@develop + with: + branch_for_bitcoin_legacy: ${{ github.ref }} + test_filter: '"ltc or litecoin or Litecoin"' diff --git a/.gitignore b/.gitignore index 87b3202f..4282af5b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,8 @@ bin debug dep obj -src/glyphs.c -src/glyphs.h *.pyc .idea .vscode +build +tests/snapshots-tmp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..d09ce724 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib-app-bitcoin"] + path = lib-app-bitcoin + url = git@github.com:LedgerHQ/lib-app-bitcoin.git diff --git a/Makefile b/Makefile index e5fc639a..aa9d0c02 100644 --- a/Makefile +++ b/Makefile @@ -1,327 +1,462 @@ -#******************************************************************************* -# Ledger App -# (c) 2017 Ledger +# **************************************************************************** +# Ledger App Bitcoin +# (c) 2023 Ledger SAS. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#******************************************************************************* - -ifeq ($(BOLOS_SDK),) -$(error Environment variable BOLOS_SDK is not set) -endif -include $(BOLOS_SDK)/Makefile.defines +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# **************************************************************************** + +######################################## +# Mandatory configuration # +######################################## + +# Application version +APPVERSION_M = 2 +APPVERSION_N = 4 +APPVERSION_P = 1 -APP_PATH = "" -APP_LOAD_PARAMS= --curve secp256k1 $(COMMON_LOAD_PARAMS) +APPDEVELOPPER="Ledger" +APPCOPYRIGHT="(c) 2024 Ledger" -APPVERSION_M=2 -APPVERSION_N=2 -APPVERSION_P=0 -APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P) -APP_LOAD_FLAGS=--appFlags 0xa50 +VARIANT_VALUES = bitcoin_testnet_legacy bitcoin_legacy bitcoin_cash bitcoin_gold litecoin dogecoin dash horizen komodo stratis peercoin pivx viacoin vertcoin stealth digibyte bitcoin_private firo gamecredits zclassic xsn nix lbry ravencoin hydra hydra_testnet xrhodium + +# Application source files +# There is no additional sources for bitcoin +#APP_SOURCE_PATH += src/ # simplify for tests ifndef COIN COIN=bitcoin_legacy endif +# Enabling DEBUG flag will enable PRINTF and disable optimizations +#DEBUG = 1 + ifeq ($(COIN),bitcoin_testnet_legacy) -# Bitcoin testnet -DEFINES += BIP44_COIN_TYPE=1 BIP44_COIN_TYPE_2=1 COIN_P2PKH_VERSION=111 COIN_P2SH_VERSION=196 COIN_FAMILY=1 COIN_COINID=\"Bitcoin\" COIN_COINID_HEADER=\"BITCOIN\" COIN_COLOR_HDR=0xFCB653 COIN_COLOR_DB=0xFEDBA9 COIN_COINID_NAME=\"Bitcoin\" COIN_COINID_SHORT=\"TEST\" COIN_NATIVE_SEGWIT_PREFIX=\"tb\" COIN_KIND=COIN_KIND_BITCOIN_TESTNET COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT +BIP44_COIN_TYPE=1 +BIP44_COIN_TYPE_2=1 +COIN_P2PKH_VERSION=111 +COIN_P2SH_VERSION=196 +COIN_FAMILY=1 +COIN_COINID=\"Bitcoin\" +COIN_COINID_NAME="Bitcoin Test" +COIN_COINID_SHORT=\"TEST\" +COIN_NATIVE_SEGWIT_PREFIX=\"tb\" +COIN_KIND=COIN_KIND_BITCOIN_TESTNET +COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT APPNAME ="Bitcoin Test Legacy" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),bitcoin_legacy) -# Bitcoin mainnet -DEFINES += BIP44_COIN_TYPE=0 BIP44_COIN_TYPE_2=0 COIN_P2PKH_VERSION=0 COIN_P2SH_VERSION=5 COIN_FAMILY=1 COIN_COINID=\"Bitcoin\" COIN_COINID_HEADER=\"BITCOIN\" COIN_COLOR_HDR=0xFCB653 COIN_COLOR_DB=0xFEDBA9 COIN_COINID_NAME=\"Bitcoin\" COIN_COINID_SHORT=\"BTC\" COIN_NATIVE_SEGWIT_PREFIX=\"bc\" COIN_KIND=COIN_KIND_BITCOIN COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT +# Horizen +BIP44_COIN_TYPE=0 +BIP44_COIN_TYPE_2=0 +COIN_P2PKH_VERSION=0 +COIN_P2SH_VERSION=5 +COIN_FAMILY=1 +COIN_COINID=\"Bitcoin\" +COIN_COINID_NAME="Bitcoin" +COIN_COINID_SHORT=\"BTC\" +COIN_NATIVE_SEGWIT_PREFIX=\"bc\" +COIN_KIND=COIN_KIND_BITCOIN +COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT APPNAME ="Bitcoin Legacy" -APP_LOAD_PARAMS += --path $(APP_PATH) -#LIB and global pin and + else ifeq ($(COIN),bitcoin_cash) # Bitcoin cash # Initial fork from Bitcoin, public key access is authorized. Signature is different thanks to the forkId -DEFINES += BIP44_COIN_TYPE=145 BIP44_COIN_TYPE_2=0 COIN_P2PKH_VERSION=0 COIN_P2SH_VERSION=5 COIN_FAMILY=1 COIN_COINID=\"Bitcoin\" COIN_COINID_HEADER=\"BITCOINCASH\" COIN_COLOR_HDR=0x85bb65 COIN_COLOR_DB=0xc2ddb2 COIN_COINID_NAME=\"BitcoinCash\" COIN_COINID_SHORT=\"BCH\" COIN_KIND=COIN_KIND_BITCOIN_CASH COIN_FORKID=0 +BIP44_COIN_TYPE=145 +BIP44_COIN_TYPE_2=0 +COIN_P2PKH_VERSION=0 +COIN_P2SH_VERSION=5 +COIN_FAMILY=1 +COIN_COINID=\"Bitcoin\" +COIN_COINID_NAME="Bitcoin Cash" +COIN_COINID_SHORT=\"BCH\" +COIN_KIND=COIN_KIND_BITCOIN_CASH +COIN_FORKID=0 APPNAME ="Bitcoin Cash" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),bitcoin_gold) # Bitcoin Gold # Initial fork from Bitcoin, public key access is authorized. Signature is different thanks to the forkId -DEFINES += BIP44_COIN_TYPE=156 BIP44_COIN_TYPE_2=0 COIN_P2PKH_VERSION=38 COIN_P2SH_VERSION=23 COIN_FAMILY=1 COIN_COINID=\"Bitcoin\\x20Gold\" COIN_COINID_HEADER=\"BITCOINGOLD\" COIN_COLOR_HDR=0x85bb65 COIN_COLOR_DB=0xc2ddb2 COIN_COINID_NAME=\"BitcoinGold\" COIN_COINID_SHORT=\"BTG\" COIN_KIND=COIN_KIND_BITCOIN_GOLD COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT COIN_FORKID=79 +BIP44_COIN_TYPE=156 +BIP44_COIN_TYPE_2=0 +COIN_P2PKH_VERSION=38 +COIN_P2SH_VERSION=23 +COIN_FAMILY=1 +COIN_COINID=\"Bitcoin\\x20Gold\" +COIN_COINID_NAME="Bitcoin Gold" +COIN_COINID_SHORT=\"BTG\" +COIN_KIND=COIN_KIND_BITCOIN_GOLD +COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT +COIN_FORKID=79 APPNAME ="Bitcoin Gold" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),litecoin) # Litecoin -DEFINES += BIP44_COIN_TYPE=2 BIP44_COIN_TYPE_2=2 COIN_P2PKH_VERSION=48 COIN_P2SH_VERSION=50 COIN_FAMILY=1 COIN_COINID=\"Litecoin\" COIN_COINID_HEADER=\"LITECOIN\" COIN_COLOR_HDR=0xCCCCCC COIN_COLOR_DB=0xE6E6E6 COIN_COINID_NAME=\"Litecoin\" COIN_COINID_SHORT=\"LTC\" COIN_NATIVE_SEGWIT_PREFIX=\"ltc\" COIN_KIND=COIN_KIND_LITECOIN COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT +BIP44_COIN_TYPE=2 +BIP44_COIN_TYPE_2=2 +COIN_P2PKH_VERSION=48 +COIN_P2SH_VERSION=50 +COIN_FAMILY=1 +COIN_COINID=\"Litecoin\" +COIN_COINID_NAME="Litecoin" +COIN_COINID_SHORT=\"LTC\" +COIN_NATIVE_SEGWIT_PREFIX=\"ltc\" +COIN_KIND=COIN_KIND_LITECOIN +COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT APPNAME ="Litecoin" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),dogecoin) # Doge -DEFINES += BIP44_COIN_TYPE=3 BIP44_COIN_TYPE_2=3 COIN_P2PKH_VERSION=30 COIN_P2SH_VERSION=22 COIN_FAMILY=1 COIN_COINID=\"Dogecoin\" COIN_COINID_HEADER=\"DOGECOIN\" COIN_COLOR_HDR=0x65D196 COIN_COLOR_DB=0xB2E8CB COIN_COINID_NAME=\"Dogecoin\" COIN_COINID_SHORT=\"DOGE\" COIN_KIND=COIN_KIND_DOGE +BIP44_COIN_TYPE=3 +BIP44_COIN_TYPE_2=3 +COIN_P2PKH_VERSION=30 +COIN_P2SH_VERSION=22 +COIN_FAMILY=1 +COIN_COINID=\"Dogecoin\" +COIN_COINID_NAME="Doge" +COIN_COINID_SHORT=\"DOGE\" +COIN_KIND=COIN_KIND_DOGE APPNAME ="Dogecoin" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),dash) # Dash -DEFINES += BIP44_COIN_TYPE=5 BIP44_COIN_TYPE_2=5 COIN_P2PKH_VERSION=76 COIN_P2SH_VERSION=16 COIN_FAMILY=1 COIN_COINID=\"DarkCoin\" COIN_COINID_HEADER=\"DASH\" COIN_COLOR_HDR=0x0E76AA COIN_COLOR_DB=0x87BBD5 COIN_COINID_NAME=\"Dash\" COIN_COINID_SHORT=\"DASH\" COIN_KIND=COIN_KIND_DASH +BIP44_COIN_TYPE=5 +BIP44_COIN_TYPE_2=5 +COIN_P2PKH_VERSION=76 +COIN_P2SH_VERSION=16 +COIN_FAMILY=1 +COIN_COINID=\"DarkCoin\" +COIN_COINID_NAME="Dash" +COIN_COINID_SHORT=\"DASH\" +COIN_KIND=COIN_KIND_DASH APPNAME ="Dash" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),zcash) # Zcash (deprecated, code before the NU5 hard fork) $(error the zcash variant is deprecated and no longer functional since the NU5 hard fork) -DEFINES += BIP44_COIN_TYPE=133 BIP44_COIN_TYPE_2=133 COIN_P2PKH_VERSION=7352 COIN_P2SH_VERSION=7357 COIN_FAMILY=1 COIN_COINID=\"Zcash\" COIN_COINID_HEADER=\"ZCASH\" COIN_COLOR_HDR=0x3790CA COIN_COLOR_DB=0x9BC8E5 COIN_COINID_NAME=\"Zcash\" COIN_COINID_SHORT=\"ZEC\" COIN_KIND=COIN_KIND_ZCASH +BIP44_COIN_TYPE=133 +BIP44_COIN_TYPE_2=133 +COIN_P2PKH_VERSION=7352 +COIN_P2SH_VERSION=7357 +COIN_FAMILY=1 +COIN_COINID=\"Zcash\" +COIN_COINID_NAME="Zcash" +COIN_COINID_SHORT=\"ZEC\" +COIN_KIND=COIN_KIND_ZCASH # Switch to Canopy over Heartwood -DEFINES += COIN_CONSENSUS_BRANCH_ID=0xE9FF75A6 +BRANCH_ID=0xE9FF75A6 APPNAME ="Zcash" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),horizen) # Horizen -DEFINES += BIP44_COIN_TYPE=121 BIP44_COIN_TYPE_2=121 COIN_P2PKH_VERSION=8329 COIN_P2SH_VERSION=8342 COIN_FAMILY=4 COIN_COINID=\"Horizen\" COIN_COINID_HEADER=\"HORIZEN\" COIN_COLOR_HDR=0xFF4300 COIN_COLOR_DB=0xFF8356 COIN_COINID_NAME=\"Horizen\" COINID=$(COIN) COIN_COINID_SHORT=\"ZEN\" COIN_KIND=COIN_KIND_HORIZEN +BIP44_COIN_TYPE=121 +BIP44_COIN_TYPE_2=121 +COIN_P2PKH_VERSION=8329 +COIN_P2SH_VERSION=8342 +COIN_FAMILY=4 +COIN_COINID=\"Horizen\" +COIN_COINID_NAME="Horizen" +COIN_COINID_SHORT=\"ZEN\" +COIN_KIND=COIN_KIND_HORIZEN APPNAME ="Horizen" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),komodo) # Komodo -DEFINES += BIP44_COIN_TYPE=141 BIP44_COIN_TYPE_2=141 COIN_P2PKH_VERSION=60 COIN_P2SH_VERSION=85 COIN_FAMILY=1 COIN_COINID=\"Komodo\" COIN_COINID_HEADER=\"KOMODO\" COIN_COLOR_HDR=0x326464 COIN_COLOR_DB=0x99b2b2 COIN_COINID_NAME=\"Komodo\" COIN_COINID_SHORT=\"KMD\" COIN_KIND=COIN_KIND_KOMODO +BIP44_COIN_TYPE=141 +BIP44_COIN_TYPE_2=141 +COIN_P2PKH_VERSION=60 +COIN_P2SH_VERSION=85 +COIN_FAMILY=1 +COIN_COINID=\"Komodo\" +COIN_COINID_NAME="Komodo" +COIN_COINID_SHORT=\"KMD\" +COIN_KIND=COIN_KIND_KOMODO APPNAME ="Komodo" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),stratis) # Stratis -DEFINES += BIP44_COIN_TYPE=105105 BIP44_COIN_TYPE_2=105105 COIN_P2PKH_VERSION=75 COIN_P2SH_VERSION=140 COIN_FAMILY=2 COIN_COINID=\"Stratis\" COIN_COINID_HEADER=\"STRATIS\" COIN_COLOR_HDR=0x3790CA COIN_COLOR_DB=0x9BC8E5 COIN_COINID_NAME=\"Stratis\" COIN_COINID_SHORT=\"STRAX\" COIN_KIND=COIN_KIND_STRATIS COIN_FLAGS=FLAG_PEERCOIN_SUPPORT +BIP44_COIN_TYPE=105105 +BIP44_COIN_TYPE_2=105105 +COIN_P2PKH_VERSION=75 +COIN_P2SH_VERSION=140 +COIN_FAMILY=2 +COIN_COINID=\"Stratis\" +COIN_COINID_NAME="Stratis" +COIN_COINID_SHORT=\"STRAX\" +COIN_KIND=COIN_KIND_STRATIS +COIN_FLAGS=FLAG_PEERCOIN_SUPPORT APPNAME ="Stratis" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),xrhodium) #Xrhodium -DEFINES += BIP44_COIN_TYPE=10291 BIP44_COIN_TYPE_2=10291 COIN_P2PKH_VERSION=61 COIN_P2SH_VERSION=123 COIN_FAMILY=1 COIN_COINID=\"xrhodium\" COIN_COINID_HEADER=\"XRHODIUM\" COIN_COLOR_HDR=0xFF9900 COIN_COLOR_DB=0xFEEBCE COIN_COINID_NAME=\"xRhodium\" COIN_COINID_SHORT=\"XRC\" COIN_KIND=COIN_KIND_XRHODIUM +BIP44_COIN_TYPE=10291 +BIP44_COIN_TYPE_2=10291 +COIN_P2PKH_VERSION=61 +COIN_P2SH_VERSION=123 +COIN_FAMILY=1 +COIN_COINID=\"xrhodium\" +COIN_COINID_NAME="xRhodium" +COIN_COINID_SHORT=\"XRC\" +COIN_KIND=COIN_KIND_XRHODIUM APPNAME ="xRhodium" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),peercoin) # Peercoin -DEFINES += BIP44_COIN_TYPE=6 BIP44_COIN_TYPE_2=6 COIN_P2PKH_VERSION=55 COIN_P2SH_VERSION=117 COIN_FAMILY=2 COIN_COINID=\"PPCoin\" COIN_COINID_HEADER=\"PEERCOIN\" COIN_COLOR_HDR=0x3790CA COIN_COLOR_DB=0x9BC8E5 COIN_COINID_NAME=\"Peercoin\" COIN_COINID_SHORT=\"PPC\" COIN_KIND=COIN_KIND_PEERCOIN COIN_FLAGS=FLAG_PEERCOIN_UNITS\|FLAG_PEERCOIN_SUPPORT +BIP44_COIN_TYPE=6 +BIP44_COIN_TYPE_2=6 +COIN_P2PKH_VERSION=55 +COIN_P2SH_VERSION=117 +COIN_FAMILY=2 +COIN_COINID=\"PPCoin\" +COIN_COINID_NAME="Peercoin" +COIN_COINID_SHORT=\"PPC\" +COIN_KIND=COIN_KIND_PEERCOIN +COIN_FLAGS=FLAG_PEERCOIN_UNITS\|FLAG_PEERCOIN_SUPPORT APPNAME ="Peercoin" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),pivx) # PivX # 77 was used in the Chrome apps -DEFINES += BIP44_COIN_TYPE=119 BIP44_COIN_TYPE_2=77 COIN_P2PKH_VERSION=30 COIN_P2SH_VERSION=13 COIN_FAMILY=1 COIN_COINID=\"DarkNet\" COIN_COINID_HEADER=\"PIVX\" COIN_COLOR_HDR=0x46385D COIN_COLOR_DB=0x9E96AA COIN_COINID_NAME=\"PivX\" COIN_COINID_SHORT=\"PIVX\" COIN_KIND=COIN_KIND_PIVX +BIP44_COIN_TYPE=119 +BIP44_COIN_TYPE_2=77 +COIN_P2PKH_VERSION=30 +COIN_P2SH_VERSION=13 +COIN_FAMILY=1 +COIN_COINID=\"DarkNet\" +COIN_COINID_NAME="PivX" +COIN_COINID_SHORT=\"PIVX\" +COIN_KIND=COIN_KIND_PIVX APPNAME ="PivX" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),stealth) # Stealth -DEFINES += BIP44_COIN_TYPE=125 BIP44_COIN_TYPE_2=125 COIN_P2PKH_VERSION=62 COIN_P2SH_VERSION=85 COIN_FAMILY=4 COIN_COINID=\"Stealth\" COIN_COINID_HEADER=\"STEALTH\" COIN_COLOR_HDR=0x000000 COIN_COLOR_DB=0x808080 COIN_COINID_NAME=\"Stealth\" COIN_COINID_SHORT=\"XST\" COIN_KIND=COIN_KIND_STEALTH COIN_FLAGS=FLAG_PEERCOIN_UNITS\|FLAG_PEERCOIN_SUPPORT +BIP44_COIN_TYPE=125 +BIP44_COIN_TYPE_2=125 +COIN_P2PKH_VERSION=62 +COIN_P2SH_VERSION=85 +COIN_FAMILY=4 +COIN_COINID=\"Stealth\" +COIN_COINID_NAME="Stealth" +COIN_COINID_SHORT=\"XST\" +COIN_KIND=COIN_KIND_STEALTH +COIN_FLAGS=FLAG_PEERCOIN_UNITS\|FLAG_PEERCOIN_SUPPORT APPNAME ="Stealth" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),viacoin) # Viacoin -DEFINES += BIP44_COIN_TYPE=14 BIP44_COIN_TYPE_2=14 COIN_P2PKH_VERSION=71 COIN_P2SH_VERSION=33 COIN_FAMILY=1 COIN_COINID=\"Viacoin\" COIN_COINID_HEADER=\"VIACOIN\" COIN_COLOR_HDR=0x414141 COIN_COLOR_DB=0xA0A0A0 COIN_COINID_NAME=\"Viacoin\" COIN_COINID_SHORT=\"VIA\" COIN_KIND=COIN_KIND_VIACOIN COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT +BIP44_COIN_TYPE=14 +BIP44_COIN_TYPE_2=14 +COIN_P2PKH_VERSION=71 +COIN_P2SH_VERSION=33 +COIN_FAMILY=1 +COIN_COINID=\"Viacoin\" +COIN_COINID_NAME="Viacoin" +COIN_COINID_SHORT=\"VIA\" +COIN_KIND=COIN_KIND_VIACOIN +COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT APPNAME ="Viacoin" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),vertcoin) # Vertcoin # 128 was used in the Chrome apps -DEFINES += BIP44_COIN_TYPE=28 BIP44_COIN_TYPE_2=128 COIN_P2PKH_VERSION=71 COIN_P2SH_VERSION=5 COIN_FAMILY=1 COIN_COINID=\"Vertcoin\" COIN_COINID_HEADER=\"VERTCOIN\" COIN_COLOR_HDR=0x1B5C2E COIN_COLOR_DB=0x8DAE97 COIN_COINID_NAME=\"Vertcoin\" COIN_COINID_SHORT=\"VTC\" COIN_NATIVE_SEGWIT_PREFIX=\"vtc\" COIN_KIND=COIN_KIND_VERTCOIN COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT +BIP44_COIN_TYPE=28 +BIP44_COIN_TYPE_2=128 +COIN_P2PKH_VERSION=71 +COIN_P2SH_VERSION=5 +COIN_FAMILY=1 +COIN_COINID=\"Vertcoin\" +COIN_COINID_NAME="Vertcoin" +COIN_COINID_SHORT=\"VTC\" +COIN_NATIVE_SEGWIT_PREFIX=\"vtc\" +COIN_KIND=COIN_KIND_VERTCOIN +COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT APPNAME ="Vertcoin" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),digibyte) -DEFINES += BIP44_COIN_TYPE=20 BIP44_COIN_TYPE_2=20 COIN_P2PKH_VERSION=30 COIN_P2SH_VERSION=63 COIN_FAMILY=1 COIN_COINID=\"DigiByte\" COIN_COINID_HEADER=\"DIGIBYTE\" COIN_COLOR_HDR=0x2864AE COIN_COLOR_DB=0x94B2D7 COIN_COINID_NAME=\"DigiByte\" COIN_COINID_SHORT=\"DGB\" COIN_NATIVE_SEGWIT_PREFIX=\"dgb\" COIN_KIND=COIN_KIND_DIGIBYTE COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT +BIP44_COIN_TYPE=20 +BIP44_COIN_TYPE_2=20 +COIN_P2PKH_VERSION=30 +COIN_P2SH_VERSION=63 +COIN_FAMILY=1 +COIN_COINID=\"DigiByte\" +COIN_COINID_NAME="Digibyte" +COIN_COINID_SHORT=\"DGB\" +COIN_NATIVE_SEGWIT_PREFIX=\"dgb\" +COIN_KIND=COIN_KIND_DIGIBYTE +COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT APPNAME ="Digibyte" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),qtum) -# Qtum -# Qtum can run significantly different code paths, thus is locked by the OS -# using APP_LOAD_PARAMS instead of BIP44_COIN_TYPE -DEFINES += BIP44_COIN_TYPE=0 BIP44_COIN_TYPE_2=0 COIN_P2PKH_VERSION=58 COIN_P2SH_VERSION=50 COIN_FAMILY=3 COIN_COINID=\"Qtum\" COIN_COINID_HEADER=\"QTUM\" COIN_COLOR_HDR=0x2E9AD0 COIN_COLOR_DB=0x97CDE8 COIN_COINID_NAME=\"QTUM\" COIN_COINID_SHORT=\"QTUM\" COIN_NATIVE_SEGWIT_PREFIX=\"qc\" COIN_KIND=COIN_KIND_QTUM COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT -APPNAME ="Qtum" -APP_LOAD_PARAMS += --path "44'/88'" --path "49'/88'" --path "84'/88'" --path "0'/45342'" --path "20698'/3053'/12648430'" +$(error the qtum variant is deprecated and has been moved to its dedicated repo) else ifeq ($(COIN),firo) -DEFINES += BIP44_COIN_TYPE=136 BIP44_COIN_TYPE_2=136 COIN_P2PKH_VERSION=82 COIN_P2SH_VERSION=7 COIN_FAMILY=1 COIN_COINID=\"Zcoin\" COIN_COINID_HEADER=\"FIRO\" COIN_COLOR_HDR=0x3EAD54 COIN_COLOR_DB=0xA3DCAE COIN_COINID_NAME=\"Firo\" COIN_COINID_SHORT=\"FIRO\" COIN_KIND=COIN_KIND_FIRO +BIP44_COIN_TYPE=136 +BIP44_COIN_TYPE_2=136 +COIN_P2PKH_VERSION=82 +COIN_P2SH_VERSION=7 +COIN_FAMILY=1 +COIN_COINID=\"Zcoin\" +COIN_COINID_NAME="Firo" +COIN_COINID_SHORT=\"FIRO\" +COIN_KIND=COIN_KIND_FIRO APPNAME ="Firo" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),bitcoin_private) # Bitcoin Private # Initial fork from Bitcoin, public key access is authorized. Signature is different thanks to the forkId # Note : might need a third lock on ZClassic -DEFINES += BIP44_COIN_TYPE=183 BIP44_COIN_TYPE_2=0 COIN_P2PKH_VERSION=4901 COIN_P2SH_VERSION=5039 COIN_FAMILY=1 COIN_COINID=\"BPrivate\" COIN_COINID_HEADER=\"BITCOINPRIVATE\" COIN_COLOR_HDR=0x85bb65 COIN_COLOR_DB=0xc2ddb2 COIN_COINID_NAME=\"BPrivate\" COIN_COINID_SHORT=\"BTCP\" COIN_KIND=COIN_KIND_BITCOIN_PRIVATE COIN_FORKID=42 +BIP44_COIN_TYPE=183 +BIP44_COIN_TYPE_2=0 +COIN_P2PKH_VERSION=4901 +COIN_P2SH_VERSION=5039 +COIN_FAMILY=1 +COIN_COINID=\"BPrivate\" +COIN_COINID_NAME="Bitcoin Private" +COIN_COINID_SHORT=\"BTCP\" +COIN_KIND=COIN_KIND_BITCOIN_PRIVATE +COIN_FORKID=42 APPNAME ="Bitcoin Private" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),gamecredits) # GameCredits -DEFINES += BIP44_COIN_TYPE=101 BIP44_COIN_TYPE_2=101 COIN_P2PKH_VERSION=38 COIN_P2SH_VERSION=62 COIN_FAMILY=1 COIN_COINID=\"GameCredits\" COIN_COINID_HEADER=\"GAMECREDITS\" COIN_COLOR_HDR=0x98C01F COIN_COLOR_DB=0xA1A2A7 COIN_COINID_NAME=\"GameCredits\" COIN_COINID_SHORT=\"GAME\" COIN_KIND=COIN_KIND_GAMECREDITS COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT +BIP44_COIN_TYPE=101 +BIP44_COIN_TYPE_2=101 +COIN_P2PKH_VERSION=38 +COIN_P2SH_VERSION=62 +COIN_FAMILY=1 +COIN_COINID=\"GameCredits\" +COIN_COINID_NAME="GameCredits" +COIN_COINID_SHORT=\"GAME\" +COIN_KIND=COIN_KIND_GAMECREDITS +COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT APPNAME ="GameCredits" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),zclassic) # ZClassic -DEFINES += BIP44_COIN_TYPE=147 BIP44_COIN_TYPE_2=147 COIN_P2PKH_VERSION=7352 COIN_P2SH_VERSION=7357 COIN_FAMILY=1 COIN_COINID=\"ZClassic\" COIN_COINID_HEADER=\"ZCLASSIC\" COIN_COLOR_HDR=0xc87035 COIN_COLOR_DB=0xc78457 COIN_COINID_NAME=\"ZClassic\" COIN_COINID_SHORT=\"ZCL\" COIN_KIND=COIN_KIND_ZCLASSIC +BIP44_COIN_TYPE=147 +BIP44_COIN_TYPE_2=147 +COIN_P2PKH_VERSION=7352 +COIN_P2SH_VERSION=7357 +COIN_FAMILY=1 +COIN_COINID=\"ZClassic\" +COIN_COINID_NAME="ZClassic" +COIN_COINID_SHORT=\"ZCL\" +COIN_KIND=COIN_KIND_ZCLASSIC APPNAME ="ZClassic" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),xsn) # XSN mainnet -DEFINES += BIP44_COIN_TYPE=384 BIP44_COIN_TYPE_2=384 COIN_P2PKH_VERSION=76 COIN_P2SH_VERSION=16 COIN_FAMILY=1 COIN_COINID=\"XSN\" COIN_COINID_HEADER=\"XSN\" COIN_COLOR_HDR=0x2982D1 COIN_COLOR_DB=0x7FB6E6 COIN_COINID_NAME=\"XSN\" COIN_COINID_SHORT=\"XSN\" COIN_NATIVE_SEGWIT_PREFIX=\"xc\" COIN_KIND=COIN_KIND_XSN COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT +BIP44_COIN_TYPE=384 +BIP44_COIN_TYPE_2=384 +COIN_P2PKH_VERSION=76 +COIN_P2SH_VERSION=16 +COIN_FAMILY=1 +COIN_COINID=\"XSN\" +COIN_COINID_NAME="XSN" +COIN_COINID_SHORT=\"XSN\" +COIN_NATIVE_SEGWIT_PREFIX=\"xc\" +COIN_KIND=COIN_KIND_XSN +COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT APPNAME ="XSN" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),nix) # NIX -DEFINES += BIP44_COIN_TYPE=400 BIP44_COIN_TYPE_2=400 COIN_P2PKH_VERSION=38 COIN_P2SH_VERSION=53 COIN_FAMILY=1 COIN_COINID=\"NIX\" COIN_COINID_HEADER=\"NIX\" COIN_COLOR_HDR=0x1685e8 COIN_COLOR_DB=0xffffff COIN_COINID_NAME=\"NIX\" COIN_COINID_SHORT=\"NIX\" COIN_NATIVE_SEGWIT_PREFIX=\"nix\" COIN_KIND=COIN_KIND_NIX COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT +BIP44_COIN_TYPE=400 +BIP44_COIN_TYPE_2=400 +COIN_P2PKH_VERSION=38 +COIN_P2SH_VERSION=53 +COIN_FAMILY=1 +COIN_COINID=\"NIX\" +COIN_COINID_NAME="NIX" +COIN_COINID_SHORT=\"NIX\" +COIN_NATIVE_SEGWIT_PREFIX=\"nix\" +COIN_KIND=COIN_KIND_NIX +COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT APPNAME ="NIX" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),lbry) # LBRY -DEFINES += BIP44_COIN_TYPE=140 BIP44_COIN_TYPE_2=140 COIN_P2PKH_VERSION=85 COIN_P2SH_VERSION=122 COIN_FAMILY=1 COIN_COINID=\"LBRY\" COIN_COINID_HEADER=\"LBRY\" COIN_COLOR_HDR=0x38D9A9 COIN_COLOR_DB=0xFEDBA9 COIN_COINID_NAME=\"LBRY\" COIN_COINID_SHORT=\"LBC\" COIN_KIND=COIN_KIND_LBRY +BIP44_COIN_TYPE=140 +BIP44_COIN_TYPE_2=140 +COIN_P2PKH_VERSION=85 +COIN_P2SH_VERSION=122 +COIN_FAMILY=1 +COIN_COINID=\"LBRY\" +COIN_COINID_NAME="LBRY" +COIN_COINID_SHORT=\"LBC\" +COIN_KIND=COIN_KIND_LBRY APPNAME ="LBRY" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),resistance) # Resistance -DEFINES += BIP44_COIN_TYPE=356 BIP44_COIN_TYPE_2=356 COIN_P2PKH_VERSION=7063 COIN_P2SH_VERSION=7068 COIN_FAMILY=1 COIN_COINID=\"Res\" COIN_COINID_HEADER=\"RES\" COIN_COLOR_HDR=0x3790CA COIN_COLOR_DB=0x9BC8E5 COIN_COINID_NAME=\"Res\" COIN_COINID_SHORT=\"RES\" COIN_KIND=COIN_KIND_RESISTANCE +BIP44_COIN_TYPE=356 +BIP44_COIN_TYPE_2=356 +COIN_P2PKH_VERSION=7063 +COIN_P2SH_VERSION=7068 +COIN_FAMILY=1 +COIN_COINID=\"Res\" +COIN_COINID_NAME="Resistance" +COIN_COINID_SHORT=\"RES\" +COIN_KIND=COIN_KIND_RESISTANCE APPNAME ="Resistance" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),ravencoin) # Ravencoin -DEFINES += BIP44_COIN_TYPE=175 BIP44_COIN_TYPE_2=175 COIN_P2PKH_VERSION=60 COIN_P2SH_VERSION=122 COIN_FAMILY=1 COIN_COINID=\"Ravencoin\" COIN_COINID_HEADER=\"RAVENCOIN\" COIN_COLOR_HDR=0x2E4A80 COIN_COLOR_DB=0x74829E COIN_COINID_NAME=\"Ravencoin\" COIN_COINID_SHORT=\"RVN\" COIN_KIND=COIN_KIND_RAVENCOIN +BIP44_COIN_TYPE=175 +BIP44_COIN_TYPE_2=175 +COIN_P2PKH_VERSION=60 +COIN_P2SH_VERSION=122 +COIN_FAMILY=1 +COIN_COINID=\"Ravencoin\" +COIN_COINID_NAME="Ravencoin" +COIN_COINID_SHORT=\"RVN\" +COIN_KIND=COIN_KIND_RAVENCOIN APPNAME ="Ravencoin" -APP_LOAD_PARAMS += --path $(APP_PATH) + else ifeq ($(COIN),hydra_testnet) # Hydra testnet -DEFINES += BIP44_COIN_TYPE=0 BIP44_COIN_TYPE_2=0 COIN_P2PKH_VERSION=66 COIN_P2SH_VERSION=128 COIN_FAMILY=3 COIN_COINID=\"Hydra\" COIN_COINID_HEADER=\"HYDRA\" COIN_COLOR_HDR=0x2E9AD0 COIN_COLOR_DB=0x97CDE8 COIN_COINID_NAME=\"HYDRA\" COIN_COINID_SHORT=\"HYDRA\" COIN_NATIVE_SEGWIT_PREFIX=\"hc\" COIN_KIND=COIN_KIND_HYDRA COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT +BIP44_COIN_TYPE=0 +BIP44_COIN_TYPE_2=0 +COIN_P2PKH_VERSION=66 +COIN_P2SH_VERSION=128 +COIN_FAMILY=3 +COIN_COINID=\"Hydra\" +COIN_COINID_NAME="Hydra Test" +COIN_COINID_SHORT=\"HYDRA\" +COIN_NATIVE_SEGWIT_PREFIX=\"hc\" +COIN_KIND=COIN_KIND_HYDRA +COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT APPNAME ="Hydra Test" APP_LOAD_PARAMS += --path "44'/609'" + else ifeq ($(COIN),hydra) # Hydra mainnet -DEFINES += BIP44_COIN_TYPE=0 BIP44_COIN_TYPE_2=0 COIN_P2PKH_VERSION=40 COIN_P2SH_VERSION=63 COIN_FAMILY=3 COIN_COINID=\"Hydra\" COIN_COINID_HEADER=\"HYDRA\" COIN_COLOR_HDR=0x2E9AD0 COIN_COLOR_DB=0x97CDE8 COIN_COINID_NAME=\"HYDRA\" COIN_COINID_SHORT=\"HYDRA\" COIN_NATIVE_SEGWIT_PREFIX=\"hc\" COIN_KIND=COIN_KIND_HYDRA COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT +BIP44_COIN_TYPE=0 +BIP44_COIN_TYPE_2=0 +COIN_P2PKH_VERSION=40 +COIN_P2SH_VERSION=63 +COIN_FAMILY=3 +COIN_COINID=\"Hydra\" +COIN_COINID_NAME="Hydra" +COIN_COINID_SHORT=\"HYDRA\" +COIN_NATIVE_SEGWIT_PREFIX=\"hc\" +COIN_KIND=COIN_KIND_HYDRA +COIN_FLAGS=FLAG_SEGWIT_CHANGE_SUPPORT APPNAME ="Hydra" APP_LOAD_PARAMS += --path "44'/609'" -else -ifeq ($(filter clean,$(MAKECMDGOALS)),) -$(error Unsupported COIN - use bitcoin_testnet, bitcoin, bitcoin_cash, bitcoin_gold, litecoin, dogecoin, dash, zcash, horizen, komodo, stratis, peercoin, pivx, viacoin, vertcoin, stealth, digibyte, qtum, bitcoin_private, firo, gamecredits, zclassic, xsn, nix, lbry, resistance, ravencoin, hydra, hydra_testnet, xrhodium) -endif -endif -APP_LOAD_PARAMS += $(APP_LOAD_FLAGS) - -ifeq ($(TARGET_NAME),TARGET_NANOS) -ICONNAME=icons/nanos_app_$(COIN).gif -else -ICONNAME=icons/nanox_app_$(COIN).gif -endif - -################ -# Default rule # -################ -all: default - -############ -# Platform # -############ - -DEFINES += OS_IO_SEPROXYHAL IO_SEPROXYHAL_BUFFER_SIZE_B=300 -DEFINES += HAVE_BAGL HAVE_SPRINTF HAVE_SNPRINTF_FORMAT_U -DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=4 IO_HID_EP_LENGTH=64 HAVE_USB_APDU -DEFINES += LEDGER_MAJOR_VERSION=$(APPVERSION_M) LEDGER_MINOR_VERSION=$(APPVERSION_N) LEDGER_PATCH_VERSION=$(APPVERSION_P) TCS_LOADER_PATCH_VERSION=0 -DEFINES += HAVE_UX_FLOW - -#WEBUSB_URL = www.ledgerwallet.com -#DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=$(shell echo -n $(WEBUSB_URL) | wc -c) WEBUSB_URL=$(shell echo -n $(WEBUSB_URL) | sed -e "s/./\\\'\0\\\',/g") -DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL="" - -DEFINES += UNUSED\(x\)=\(void\)x -DEFINES += APPVERSION=\"$(APPVERSION)\" - -DEFINES += BLAKE_SDK - -ifeq ($(TARGET_NAME),TARGET_NANOX) -DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000 -DEFINES += HAVE_BLE_APDU # basic ledger apdu transport over BLE -endif - -ifeq ($(TARGET_NAME),TARGET_NANOS) -DEFINES += HAVE_WALLET_ID_SDK -else -DEFINES += HAVE_GLO096 -DEFINES += HAVE_BAGL BAGL_WIDTH=128 BAGL_HEIGHT=64 -DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature -DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX -DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX -DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX -endif - -# Enabling debug PRINTF -DEBUG:=0 -ifneq ($(DEBUG),0) - ifeq ($(TARGET_NAME),TARGET_NANOS) - DEFINES += HAVE_PRINTF PRINTF=screen_printf - else - DEFINES += HAVE_PRINTF PRINTF=mcu_usb_printf - endif -else - DEFINES += PRINTF\(...\)= -endif - - - -############## -# Compiler # -############## -ifneq ($(BOLOS_ENV),) -$(info BOLOS_ENV=$(BOLOS_ENV)) -CLANGPATH := $(BOLOS_ENV)/clang-arm-fropi/bin/ -GCCPATH := $(BOLOS_ENV)/gcc-arm-none-eabi-5_3-2016q1/bin/ -else -$(info BOLOS_ENV is not set: falling back to CLANGPATH and GCCPATH) -endif -ifeq ($(CLANGPATH),) -$(info CLANGPATH is not set: clang will be used from PATH) +else ifeq ($(filter clean,$(MAKECMDGOALS)),) +$(error Unsupported COIN - use $(VARIANT_VALUES)) endif -ifeq ($(GCCPATH),) -$(info GCCPATH is not set: arm-none-eabi-* will be used from PATH) -endif - -CC := $(CLANGPATH)clang - -CFLAGS += -Oz -AS := $(GCCPATH)arm-none-eabi-gcc - -LD := $(GCCPATH)arm-none-eabi-gcc -LDFLAGS += -O3 -Os -LDLIBS += -lm -lgcc -lc - -# import rules to compile glyphs(/pone) -include $(BOLOS_SDK)/Makefile.glyphs - -### variables processed by the common makefile.rules of the SDK to grab source files and include dirs -APP_SOURCE_PATH += src -SDK_SOURCE_PATH += lib_stusb lib_stusb_impl lib_u2f qrcode -SDK_SOURCE_PATH += lib_ux - -ifeq ($(TARGET_NAME),TARGET_NANOX) -SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl -endif - -load: all - python -m ledgerblue.loadApp $(APP_LOAD_PARAMS) -delete: - python -m ledgerblue.deleteApp $(COMMON_DELETE_PARAMS) - -# import generic rules from the sdk -include $(BOLOS_SDK)/Makefile.rules - -#add dependency on custom makefile filename -dep/%.d: %.c Makefile - - -# Temporary restriction until we have a Resistance Nano X icon -ifeq ($(TARGET_NAME),TARGET_NANOS) - -listvariants: - @echo VARIANTS COIN bitcoin_testnet_legacy bitcoin_legacy bitcoin_cash bitcoin_gold litecoin dogecoin dash horizen komodo stratis peercoin pivx viacoin vertcoin stealth digibyte qtum bitcoin_private firo gamecredits zclassic xsn nix lbry ravencoin resistance hydra hydra_testnet xrhodium - -else - -listvariants: - @echo VARIANTS COIN bitcoin_testnet_legacy bitcoin_legacy bitcoin_cash bitcoin_gold litecoin dogecoin dash horizen komodo stratis peercoin pivx viacoin vertcoin stealth digibyte qtum bitcoin_private firo gamecredits zclassic xsn nix lbry ravencoin hydra hydra_testnet xrhodium - -endif +include lib-app-bitcoin/Makefile diff --git a/README.md b/README.md index f1fea8a5..357b7c47 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,29 @@ -# ledger-app-btc -Bitcoin wallet application for Ledger Nano S and Nano X, up to version 1.6.5. +# Ledger Legacy Bitcoin Application -This is currently only used in order to support and maintain altcoins cloned from Bitcoin. The last stable version of the app as it was used for Bitcoin is kept in the branch [legacy-1.6.6](https://github.com/LedgerHQ/app-bitcoin/tree/legacy-1.6.6) for future reference. +## Legacy bitcoin application +Bitcoin wallet application for Ledger Nano S, Ledger Nano S+ and Nano X, up to version 1.6.5. -Versions starting from 2.0.0 are at https://github.com/LedgerHQ/app-bitcoin-new. +> **Warning** +> This is currently only used in order to support and maintain altcoins cloned from Bitcoin. +> The last stable version of the app as it was used for Bitcoin is kept in the branch [legacy-1.6.6](https://github.com/LedgerHQ/app-bitcoin/tree/legacy-1.6.6) for future reference and does not support Stax or Flex device. +> +> Versions starting from 2.0.0 are at https://github.com/LedgerHQ/app-bitcoin-new. Ledger Blue is not maintained anymore, but the app can still be compiled for this target using the branch `blue-final-release`. -This follows the beta specification at https://ledgerhq.github.io/btchip-doc/bitcoin-technical-beta.html - with the regular set of APDUs for standard wallet operations enabled. +The original beta specification can be found at https://ledgerhq.github.io/btchip-doc/bitcoin-technical-beta.html - with the regular set of APDUs for standard wallet operations enabled. -To compile and load it on a device, have a look here: https://developers.ledger.com/docs/nano-app/load/ +## How to use -Can be tested quickly tested with the Python API at https://github.com/LedgerHQ/btchip-python and Electrum (force noPin = True in getClient in plugins/ledger/ledger.py) +This application adheres with Ledger latest application guidelines. -## Usage +You can refer to [app-boilerplate Quick start guide](https://github.com/LedgerHQ/app-boilerplate/blob/master/README.md#quick-start-guide) for comprehensive up-to-date instructions. +## Are you developing a Ledger device application? +- See the developers’ documentation on the [Developer Portal](https://developers.ledger.com/) +- [Go on Discord](https://developers.ledger.com/discord-pro/) to chat with developer support and the developer community. + +## Client Library Include the necessary headers (copied from the js/ directory) in your web page ```html @@ -89,3 +98,4 @@ dongle.signP2SHTransaction_async( function(error) { console.log(error); }); ); ``` + diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 39fbe3c6..00000000 --- a/TODO.md +++ /dev/null @@ -1,7 +0,0 @@ -# BTC Application TODOs - - - [X] Sign message support - - [X] Altcoins fixes (signing message format, prompts) - - [ ] Support an arbitrary number of TX outputs - - [ ] Support device / PIN locking in next firmware update - diff --git a/glyphs/bitcoin_64px.gif b/glyphs/bitcoin_64px.gif new file mode 100644 index 00000000..db706c4c Binary files /dev/null and b/glyphs/bitcoin_64px.gif differ diff --git a/glyphs/bitcoin_cash_64px.gif b/glyphs/bitcoin_cash_64px.gif new file mode 100644 index 00000000..db706c4c Binary files /dev/null and b/glyphs/bitcoin_cash_64px.gif differ diff --git a/glyphs/bitcoin_gold_64px.gif b/glyphs/bitcoin_gold_64px.gif new file mode 100644 index 00000000..db706c4c Binary files /dev/null and b/glyphs/bitcoin_gold_64px.gif differ diff --git a/glyphs/bitcoin_legacy_64px.gif b/glyphs/bitcoin_legacy_64px.gif new file mode 100644 index 00000000..db706c4c Binary files /dev/null and b/glyphs/bitcoin_legacy_64px.gif differ diff --git a/glyphs/bitcoin_private_64px.gif b/glyphs/bitcoin_private_64px.gif new file mode 100644 index 00000000..db706c4c Binary files /dev/null and b/glyphs/bitcoin_private_64px.gif differ diff --git a/glyphs/bitcoin_testnet_64px.gif b/glyphs/bitcoin_testnet_64px.gif new file mode 100644 index 00000000..db706c4c Binary files /dev/null and b/glyphs/bitcoin_testnet_64px.gif differ diff --git a/glyphs/bitcoin_testnet_legacy_64px.gif b/glyphs/bitcoin_testnet_legacy_64px.gif new file mode 100644 index 00000000..db706c4c Binary files /dev/null and b/glyphs/bitcoin_testnet_legacy_64px.gif differ diff --git a/glyphs/blue_badge_bitcoin.gif b/glyphs/blue_badge_bitcoin.gif deleted file mode 100644 index df0c7abb..00000000 Binary files a/glyphs/blue_badge_bitcoin.gif and /dev/null differ diff --git a/glyphs/blue_badge_bitcoin_cash.gif b/glyphs/blue_badge_bitcoin_cash.gif deleted file mode 100644 index 9a63e6d8..00000000 Binary files a/glyphs/blue_badge_bitcoin_cash.gif and /dev/null differ diff --git a/glyphs/blue_badge_bitcoin_gold.gif b/glyphs/blue_badge_bitcoin_gold.gif deleted file mode 100644 index 9a63e6d8..00000000 Binary files a/glyphs/blue_badge_bitcoin_gold.gif and /dev/null differ diff --git a/glyphs/blue_badge_bitcoin_testnet.gif b/glyphs/blue_badge_bitcoin_testnet.gif deleted file mode 100644 index df0c7abb..00000000 Binary files a/glyphs/blue_badge_bitcoin_testnet.gif and /dev/null differ diff --git a/glyphs/blue_badge_dash.gif b/glyphs/blue_badge_dash.gif deleted file mode 100644 index 74369f56..00000000 Binary files a/glyphs/blue_badge_dash.gif and /dev/null differ diff --git a/glyphs/blue_badge_digibyte.gif b/glyphs/blue_badge_digibyte.gif deleted file mode 100644 index c485d23c..00000000 Binary files a/glyphs/blue_badge_digibyte.gif and /dev/null differ diff --git a/glyphs/blue_badge_dogecoin.gif b/glyphs/blue_badge_dogecoin.gif deleted file mode 100644 index 41769cc6..00000000 Binary files a/glyphs/blue_badge_dogecoin.gif and /dev/null differ diff --git a/glyphs/blue_badge_komodo.gif b/glyphs/blue_badge_komodo.gif deleted file mode 100644 index 41466b8a..00000000 Binary files a/glyphs/blue_badge_komodo.gif and /dev/null differ diff --git a/glyphs/blue_badge_lbry.gif b/glyphs/blue_badge_lbry.gif deleted file mode 100644 index c20f9382..00000000 Binary files a/glyphs/blue_badge_lbry.gif and /dev/null differ diff --git a/glyphs/blue_badge_litecoin.gif b/glyphs/blue_badge_litecoin.gif deleted file mode 100644 index de0095b6..00000000 Binary files a/glyphs/blue_badge_litecoin.gif and /dev/null differ diff --git a/glyphs/blue_badge_peercoin.gif b/glyphs/blue_badge_peercoin.gif deleted file mode 100644 index 1c39643d..00000000 Binary files a/glyphs/blue_badge_peercoin.gif and /dev/null differ diff --git a/glyphs/blue_badge_pivx.gif b/glyphs/blue_badge_pivx.gif deleted file mode 100644 index 62db7bdd..00000000 Binary files a/glyphs/blue_badge_pivx.gif and /dev/null differ diff --git a/glyphs/blue_badge_qtum.gif b/glyphs/blue_badge_qtum.gif deleted file mode 100644 index d48701d0..00000000 Binary files a/glyphs/blue_badge_qtum.gif and /dev/null differ diff --git a/glyphs/blue_badge_ravencoin.gif b/glyphs/blue_badge_ravencoin.gif deleted file mode 100644 index e02647f6..00000000 Binary files a/glyphs/blue_badge_ravencoin.gif and /dev/null differ diff --git a/glyphs/blue_badge_resistance.gif b/glyphs/blue_badge_resistance.gif deleted file mode 100644 index 0d069101..00000000 Binary files a/glyphs/blue_badge_resistance.gif and /dev/null differ diff --git a/glyphs/blue_badge_stealth.gif b/glyphs/blue_badge_stealth.gif deleted file mode 100644 index c3b2324b..00000000 Binary files a/glyphs/blue_badge_stealth.gif and /dev/null differ diff --git a/glyphs/blue_badge_stratis.gif b/glyphs/blue_badge_stratis.gif deleted file mode 100644 index a01878e4..00000000 Binary files a/glyphs/blue_badge_stratis.gif and /dev/null differ diff --git a/glyphs/blue_badge_transaction.gif b/glyphs/blue_badge_transaction.gif deleted file mode 100644 index 131325d4..00000000 Binary files a/glyphs/blue_badge_transaction.gif and /dev/null differ diff --git a/glyphs/blue_badge_vertcoin.gif b/glyphs/blue_badge_vertcoin.gif deleted file mode 100644 index 2f47fc15..00000000 Binary files a/glyphs/blue_badge_vertcoin.gif and /dev/null differ diff --git a/glyphs/blue_badge_viacoin.gif b/glyphs/blue_badge_viacoin.gif deleted file mode 100644 index 1732c112..00000000 Binary files a/glyphs/blue_badge_viacoin.gif and /dev/null differ diff --git a/glyphs/blue_badge_warning.gif b/glyphs/blue_badge_warning.gif deleted file mode 100644 index 37c7ed5b..00000000 Binary files a/glyphs/blue_badge_warning.gif and /dev/null differ diff --git a/glyphs/blue_badge_xrhodium.gif b/glyphs/blue_badge_xrhodium.gif deleted file mode 100644 index 5a581020..00000000 Binary files a/glyphs/blue_badge_xrhodium.gif and /dev/null differ diff --git a/glyphs/blue_badge_zcash.gif b/glyphs/blue_badge_zcash.gif deleted file mode 100644 index 0d069101..00000000 Binary files a/glyphs/blue_badge_zcash.gif and /dev/null differ diff --git a/glyphs/blue_icon_toggle_reset.gif b/glyphs/blue_icon_toggle_reset.gif deleted file mode 100644 index 450bc869..00000000 Binary files a/glyphs/blue_icon_toggle_reset.gif and /dev/null differ diff --git a/glyphs/blue_icon_toggle_set.gif b/glyphs/blue_icon_toggle_set.gif deleted file mode 100644 index 571264c7..00000000 Binary files a/glyphs/blue_icon_toggle_set.gif and /dev/null differ diff --git a/glyphs/dash_64px.gif b/glyphs/dash_64px.gif new file mode 100644 index 00000000..8460234f Binary files /dev/null and b/glyphs/dash_64px.gif differ diff --git a/glyphs/digibyte_64px.gif b/glyphs/digibyte_64px.gif new file mode 100644 index 00000000..8d29383d Binary files /dev/null and b/glyphs/digibyte_64px.gif differ diff --git a/glyphs/dogecoin_64px.gif b/glyphs/dogecoin_64px.gif new file mode 100644 index 00000000..4bede535 Binary files /dev/null and b/glyphs/dogecoin_64px.gif differ diff --git a/glyphs/firo_64px.gif b/glyphs/firo_64px.gif new file mode 100644 index 00000000..160d9967 Binary files /dev/null and b/glyphs/firo_64px.gif differ diff --git a/glyphs/gamecredits_64px.gif b/glyphs/gamecredits_64px.gif new file mode 100644 index 00000000..ea49953c Binary files /dev/null and b/glyphs/gamecredits_64px.gif differ diff --git a/glyphs/horizen_64px.gif b/glyphs/horizen_64px.gif new file mode 100644 index 00000000..8261774a Binary files /dev/null and b/glyphs/horizen_64px.gif differ diff --git a/glyphs/hydra_64px.gif b/glyphs/hydra_64px.gif new file mode 100644 index 00000000..381b5198 Binary files /dev/null and b/glyphs/hydra_64px.gif differ diff --git a/glyphs/hydra_testnet_64px.gif b/glyphs/hydra_testnet_64px.gif new file mode 100644 index 00000000..381b5198 Binary files /dev/null and b/glyphs/hydra_testnet_64px.gif differ diff --git a/glyphs/icon_back.gif b/glyphs/icon_back.gif deleted file mode 100644 index a2a7e6d4..00000000 Binary files a/glyphs/icon_back.gif and /dev/null differ diff --git a/glyphs/icon_certificate.gif b/glyphs/icon_certificate.gif deleted file mode 100644 index 89b529f7..00000000 Binary files a/glyphs/icon_certificate.gif and /dev/null differ diff --git a/glyphs/icon_coggle.gif b/glyphs/icon_coggle.gif deleted file mode 100644 index 01c43b28..00000000 Binary files a/glyphs/icon_coggle.gif and /dev/null differ diff --git a/glyphs/icon_crossmark.gif b/glyphs/icon_crossmark.gif deleted file mode 100644 index 2dcf9d9e..00000000 Binary files a/glyphs/icon_crossmark.gif and /dev/null differ diff --git a/glyphs/icon_dashboard.gif b/glyphs/icon_dashboard.gif deleted file mode 100644 index 5c305517..00000000 Binary files a/glyphs/icon_dashboard.gif and /dev/null differ diff --git a/glyphs/icon_dashboard_x.gif b/glyphs/icon_dashboard_x.gif deleted file mode 100644 index 33d9b0a7..00000000 Binary files a/glyphs/icon_dashboard_x.gif and /dev/null differ diff --git a/glyphs/icon_down.gif b/glyphs/icon_down.gif deleted file mode 100644 index 4f4e39ee..00000000 Binary files a/glyphs/icon_down.gif and /dev/null differ diff --git a/glyphs/icon_eye.gif b/glyphs/icon_eye.gif deleted file mode 100644 index df4bb829..00000000 Binary files a/glyphs/icon_eye.gif and /dev/null differ diff --git a/glyphs/icon_left.gif b/glyphs/icon_left.gif deleted file mode 100644 index 524226ba..00000000 Binary files a/glyphs/icon_left.gif and /dev/null differ diff --git a/glyphs/icon_right.gif b/glyphs/icon_right.gif deleted file mode 100644 index 15ff3cf5..00000000 Binary files a/glyphs/icon_right.gif and /dev/null differ diff --git a/glyphs/icon_up.gif b/glyphs/icon_up.gif deleted file mode 100644 index 4e13c064..00000000 Binary files a/glyphs/icon_up.gif and /dev/null differ diff --git a/glyphs/icon_validate_14.gif b/glyphs/icon_validate_14.gif deleted file mode 100644 index ccb5cabe..00000000 Binary files a/glyphs/icon_validate_14.gif and /dev/null differ diff --git a/glyphs/icon_warning.gif b/glyphs/icon_warning.gif deleted file mode 100644 index 08bd4a73..00000000 Binary files a/glyphs/icon_warning.gif and /dev/null differ diff --git a/glyphs/komodo_64px.gif b/glyphs/komodo_64px.gif new file mode 100644 index 00000000..fdaf38b4 Binary files /dev/null and b/glyphs/komodo_64px.gif differ diff --git a/glyphs/lbry_64px.gif b/glyphs/lbry_64px.gif new file mode 100644 index 00000000..8ce37e94 Binary files /dev/null and b/glyphs/lbry_64px.gif differ diff --git a/glyphs/litecoin_64px.gif b/glyphs/litecoin_64px.gif new file mode 100644 index 00000000..6f0fc2d0 Binary files /dev/null and b/glyphs/litecoin_64px.gif differ diff --git a/glyphs/nanos_badge_bitcoin.gif b/glyphs/nanos_badge_bitcoin.gif index d43e12f5..7b7a4bbc 100644 Binary files a/glyphs/nanos_badge_bitcoin.gif and b/glyphs/nanos_badge_bitcoin.gif differ diff --git a/glyphs/nanos_badge_bitcoin_cash.gif b/glyphs/nanos_badge_bitcoin_cash.gif index d43e12f5..7b7a4bbc 100644 Binary files a/glyphs/nanos_badge_bitcoin_cash.gif and b/glyphs/nanos_badge_bitcoin_cash.gif differ diff --git a/glyphs/nanos_badge_bitcoin_gold.gif b/glyphs/nanos_badge_bitcoin_gold.gif index d43e12f5..7b7a4bbc 100644 Binary files a/glyphs/nanos_badge_bitcoin_gold.gif and b/glyphs/nanos_badge_bitcoin_gold.gif differ diff --git a/glyphs/nanos_badge_bitcoin_private.gif b/glyphs/nanos_badge_bitcoin_private.gif index 51d45752..3385d581 100644 Binary files a/glyphs/nanos_badge_bitcoin_private.gif and b/glyphs/nanos_badge_bitcoin_private.gif differ diff --git a/glyphs/nanos_badge_bitcoin_testnet.gif b/glyphs/nanos_badge_bitcoin_testnet.gif index d43e12f5..7b7a4bbc 100644 Binary files a/glyphs/nanos_badge_bitcoin_testnet.gif and b/glyphs/nanos_badge_bitcoin_testnet.gif differ diff --git a/glyphs/nanos_badge_dash.gif b/glyphs/nanos_badge_dash.gif index 9d309cdf..ca90ca9c 100644 Binary files a/glyphs/nanos_badge_dash.gif and b/glyphs/nanos_badge_dash.gif differ diff --git a/glyphs/nanos_badge_digibyte.gif b/glyphs/nanos_badge_digibyte.gif index f9446015..9a028fc7 100644 Binary files a/glyphs/nanos_badge_digibyte.gif and b/glyphs/nanos_badge_digibyte.gif differ diff --git a/glyphs/nanos_badge_dogecoin.gif b/glyphs/nanos_badge_dogecoin.gif index 4f97c60c..0082e36f 100644 Binary files a/glyphs/nanos_badge_dogecoin.gif and b/glyphs/nanos_badge_dogecoin.gif differ diff --git a/glyphs/nanos_badge_komodo.gif b/glyphs/nanos_badge_komodo.gif index 2d22e51d..3c8a836e 100644 Binary files a/glyphs/nanos_badge_komodo.gif and b/glyphs/nanos_badge_komodo.gif differ diff --git a/glyphs/nanos_badge_lbry.gif b/glyphs/nanos_badge_lbry.gif index 01d3e10f..5e440b11 100644 Binary files a/glyphs/nanos_badge_lbry.gif and b/glyphs/nanos_badge_lbry.gif differ diff --git a/glyphs/nanos_badge_litecoin.gif b/glyphs/nanos_badge_litecoin.gif index db32a5ce..e630d97c 100644 Binary files a/glyphs/nanos_badge_litecoin.gif and b/glyphs/nanos_badge_litecoin.gif differ diff --git a/glyphs/nanos_badge_nix.gif b/glyphs/nanos_badge_nix.gif index a5918635..4d53396f 100644 Binary files a/glyphs/nanos_badge_nix.gif and b/glyphs/nanos_badge_nix.gif differ diff --git a/glyphs/nanos_badge_peercoin.gif b/glyphs/nanos_badge_peercoin.gif index 89ae64d7..3fa7094f 100644 Binary files a/glyphs/nanos_badge_peercoin.gif and b/glyphs/nanos_badge_peercoin.gif differ diff --git a/glyphs/nanos_badge_pivx.gif b/glyphs/nanos_badge_pivx.gif index 0af1467d..dd63c62b 100644 Binary files a/glyphs/nanos_badge_pivx.gif and b/glyphs/nanos_badge_pivx.gif differ diff --git a/glyphs/nanos_badge_qtum.gif b/glyphs/nanos_badge_qtum.gif index 0559f39d..d138581c 100644 Binary files a/glyphs/nanos_badge_qtum.gif and b/glyphs/nanos_badge_qtum.gif differ diff --git a/glyphs/nanos_badge_ravencoin.gif b/glyphs/nanos_badge_ravencoin.gif index 5fd1e385..934d7ace 100644 Binary files a/glyphs/nanos_badge_ravencoin.gif and b/glyphs/nanos_badge_ravencoin.gif differ diff --git a/glyphs/nanos_badge_resistance.gif b/glyphs/nanos_badge_resistance.gif index 36551ab0..1f0357c4 100644 Binary files a/glyphs/nanos_badge_resistance.gif and b/glyphs/nanos_badge_resistance.gif differ diff --git a/glyphs/nanos_badge_stealth.gif b/glyphs/nanos_badge_stealth.gif index 6c75a7ca..488f28b3 100644 Binary files a/glyphs/nanos_badge_stealth.gif and b/glyphs/nanos_badge_stealth.gif differ diff --git a/glyphs/nanos_badge_stratis.gif b/glyphs/nanos_badge_stratis.gif index bb0841bc..ed974a27 100644 Binary files a/glyphs/nanos_badge_stratis.gif and b/glyphs/nanos_badge_stratis.gif differ diff --git a/glyphs/nanos_badge_vertcoin.gif b/glyphs/nanos_badge_vertcoin.gif index eea49ccc..028881e5 100644 Binary files a/glyphs/nanos_badge_vertcoin.gif and b/glyphs/nanos_badge_vertcoin.gif differ diff --git a/glyphs/nanos_badge_viacoin.gif b/glyphs/nanos_badge_viacoin.gif index 869a399c..c2b1bcf2 100644 Binary files a/glyphs/nanos_badge_viacoin.gif and b/glyphs/nanos_badge_viacoin.gif differ diff --git a/glyphs/nanos_badge_xrhodium.gif b/glyphs/nanos_badge_xrhodium.gif index a15e35c9..f3e4af67 100644 Binary files a/glyphs/nanos_badge_xrhodium.gif and b/glyphs/nanos_badge_xrhodium.gif differ diff --git a/glyphs/nanos_badge_xsn.gif b/glyphs/nanos_badge_xsn.gif index cd3ea5f0..a3a317da 100644 Binary files a/glyphs/nanos_badge_xsn.gif and b/glyphs/nanos_badge_xsn.gif differ diff --git a/glyphs/nanos_badge_zcash.gif b/glyphs/nanos_badge_zcash.gif index 36551ab0..1f0357c4 100644 Binary files a/glyphs/nanos_badge_zcash.gif and b/glyphs/nanos_badge_zcash.gif differ diff --git a/glyphs/nanos_badge_zcoin.gif b/glyphs/nanos_badge_zcoin.gif index 0f1ec3cc..dd34b06a 100644 Binary files a/glyphs/nanos_badge_zcoin.gif and b/glyphs/nanos_badge_zcoin.gif differ diff --git a/glyphs/nanos_badge_zencash.gif b/glyphs/nanos_badge_zencash.gif index d90503dc..77f58c2b 100644 Binary files a/glyphs/nanos_badge_zencash.gif and b/glyphs/nanos_badge_zencash.gif differ diff --git a/glyphs/nanos_icon_back.gif b/glyphs/nanos_icon_back.gif index a2a7e6d4..f52f795d 100644 Binary files a/glyphs/nanos_icon_back.gif and b/glyphs/nanos_icon_back.gif differ diff --git a/glyphs/nanos_icon_dashboard.gif b/glyphs/nanos_icon_dashboard.gif index 5c305517..adceb5ac 100644 Binary files a/glyphs/nanos_icon_dashboard.gif and b/glyphs/nanos_icon_dashboard.gif differ diff --git a/glyphs/nix_64px.gif b/glyphs/nix_64px.gif new file mode 100644 index 00000000..414fcf6c Binary files /dev/null and b/glyphs/nix_64px.gif differ diff --git a/glyphs/peercoin_64px.gif b/glyphs/peercoin_64px.gif new file mode 100644 index 00000000..8a347f53 Binary files /dev/null and b/glyphs/peercoin_64px.gif differ diff --git a/glyphs/pivx_64px.gif b/glyphs/pivx_64px.gif new file mode 100644 index 00000000..bc60554c Binary files /dev/null and b/glyphs/pivx_64px.gif differ diff --git a/glyphs/qtum_64px.gif b/glyphs/qtum_64px.gif new file mode 100644 index 00000000..9520131a Binary files /dev/null and b/glyphs/qtum_64px.gif differ diff --git a/glyphs/ravencoin_64px.gif b/glyphs/ravencoin_64px.gif new file mode 100644 index 00000000..2faf766e Binary files /dev/null and b/glyphs/ravencoin_64px.gif differ diff --git a/glyphs/resistance_64px.gif b/glyphs/resistance_64px.gif new file mode 100644 index 00000000..55d31c21 Binary files /dev/null and b/glyphs/resistance_64px.gif differ diff --git a/glyphs/stealth_64px.gif b/glyphs/stealth_64px.gif new file mode 100644 index 00000000..bc93dceb Binary files /dev/null and b/glyphs/stealth_64px.gif differ diff --git a/glyphs/stratis_64px.gif b/glyphs/stratis_64px.gif new file mode 100644 index 00000000..3dc9e409 Binary files /dev/null and b/glyphs/stratis_64px.gif differ diff --git a/glyphs/vertcoin_64px.gif b/glyphs/vertcoin_64px.gif new file mode 100644 index 00000000..a2a23ad2 Binary files /dev/null and b/glyphs/vertcoin_64px.gif differ diff --git a/glyphs/viacoin_64px.gif b/glyphs/viacoin_64px.gif new file mode 100644 index 00000000..b5c888ac Binary files /dev/null and b/glyphs/viacoin_64px.gif differ diff --git a/glyphs/xrhodium_64px.gif b/glyphs/xrhodium_64px.gif new file mode 100644 index 00000000..947033cb Binary files /dev/null and b/glyphs/xrhodium_64px.gif differ diff --git a/glyphs/xsn_64px.gif b/glyphs/xsn_64px.gif new file mode 100644 index 00000000..9c08fee9 Binary files /dev/null and b/glyphs/xsn_64px.gif differ diff --git a/glyphs/zcash.gif b/glyphs/zcash.gif new file mode 100644 index 00000000..c3578a15 Binary files /dev/null and b/glyphs/zcash.gif differ diff --git a/glyphs/zcash_64px.gif b/glyphs/zcash_64px.gif new file mode 100644 index 00000000..c3578a15 Binary files /dev/null and b/glyphs/zcash_64px.gif differ diff --git a/glyphs/zclassic_64px.gif b/glyphs/zclassic_64px.gif new file mode 100644 index 00000000..7491d7fe Binary files /dev/null and b/glyphs/zclassic_64px.gif differ diff --git a/icons/blue_app_bitcoin.gif b/icons/blue_app_bitcoin.gif deleted file mode 100644 index beec02c6..00000000 Binary files a/icons/blue_app_bitcoin.gif and /dev/null differ diff --git a/icons/blue_app_bitcoin_cash.gif b/icons/blue_app_bitcoin_cash.gif deleted file mode 100644 index adcfbb63..00000000 Binary files a/icons/blue_app_bitcoin_cash.gif and /dev/null differ diff --git a/icons/blue_app_bitcoin_gold.gif b/icons/blue_app_bitcoin_gold.gif deleted file mode 100644 index 00c6c385..00000000 Binary files a/icons/blue_app_bitcoin_gold.gif and /dev/null differ diff --git a/icons/blue_app_bitcoin_private.gif b/icons/blue_app_bitcoin_private.gif deleted file mode 100644 index 3d528fc3..00000000 Binary files a/icons/blue_app_bitcoin_private.gif and /dev/null differ diff --git a/icons/blue_app_bitcoin_testnet.gif b/icons/blue_app_bitcoin_testnet.gif deleted file mode 100644 index beec02c6..00000000 Binary files a/icons/blue_app_bitcoin_testnet.gif and /dev/null differ diff --git a/icons/blue_app_dash.gif b/icons/blue_app_dash.gif deleted file mode 100644 index abf0fd0e..00000000 Binary files a/icons/blue_app_dash.gif and /dev/null differ diff --git a/icons/blue_app_digibyte.gif b/icons/blue_app_digibyte.gif deleted file mode 100644 index 2ec2174e..00000000 Binary files a/icons/blue_app_digibyte.gif and /dev/null differ diff --git a/icons/blue_app_dogecoin.gif b/icons/blue_app_dogecoin.gif deleted file mode 100644 index 880ca163..00000000 Binary files a/icons/blue_app_dogecoin.gif and /dev/null differ diff --git a/icons/blue_app_firo.gif b/icons/blue_app_firo.gif deleted file mode 100644 index 4d11cc86..00000000 Binary files a/icons/blue_app_firo.gif and /dev/null differ diff --git a/icons/blue_app_gamecredits.gif b/icons/blue_app_gamecredits.gif deleted file mode 100644 index 312e3844..00000000 Binary files a/icons/blue_app_gamecredits.gif and /dev/null differ diff --git a/icons/blue_app_horizen.gif b/icons/blue_app_horizen.gif deleted file mode 100644 index 9828e14b..00000000 Binary files a/icons/blue_app_horizen.gif and /dev/null differ diff --git a/icons/blue_app_komodo.gif b/icons/blue_app_komodo.gif deleted file mode 100644 index 57586bbf..00000000 Binary files a/icons/blue_app_komodo.gif and /dev/null differ diff --git a/icons/blue_app_lbry.gif b/icons/blue_app_lbry.gif deleted file mode 100644 index 0360a35e..00000000 Binary files a/icons/blue_app_lbry.gif and /dev/null differ diff --git a/icons/blue_app_litecoin.gif b/icons/blue_app_litecoin.gif deleted file mode 100644 index 62441b87..00000000 Binary files a/icons/blue_app_litecoin.gif and /dev/null differ diff --git a/icons/blue_app_nix.gif b/icons/blue_app_nix.gif deleted file mode 100644 index d258f2d2..00000000 Binary files a/icons/blue_app_nix.gif and /dev/null differ diff --git a/icons/blue_app_peercoin.gif b/icons/blue_app_peercoin.gif deleted file mode 100644 index 337538f9..00000000 Binary files a/icons/blue_app_peercoin.gif and /dev/null differ diff --git a/icons/blue_app_pivx.gif b/icons/blue_app_pivx.gif deleted file mode 100644 index 3f3a94bb..00000000 Binary files a/icons/blue_app_pivx.gif and /dev/null differ diff --git a/icons/blue_app_qtum.gif b/icons/blue_app_qtum.gif deleted file mode 100644 index 4c0194c3..00000000 Binary files a/icons/blue_app_qtum.gif and /dev/null differ diff --git a/icons/blue_app_ravencoin.gif b/icons/blue_app_ravencoin.gif deleted file mode 100644 index 3ff36c21..00000000 Binary files a/icons/blue_app_ravencoin.gif and /dev/null differ diff --git a/icons/blue_app_resistance.gif b/icons/blue_app_resistance.gif deleted file mode 100644 index 6b960987..00000000 Binary files a/icons/blue_app_resistance.gif and /dev/null differ diff --git a/icons/blue_app_stealth.gif b/icons/blue_app_stealth.gif deleted file mode 100644 index 30e1733e..00000000 Binary files a/icons/blue_app_stealth.gif and /dev/null differ diff --git a/icons/blue_app_stratis.gif b/icons/blue_app_stratis.gif deleted file mode 100644 index 3121749c..00000000 Binary files a/icons/blue_app_stratis.gif and /dev/null differ diff --git a/icons/blue_app_vertcoin.gif b/icons/blue_app_vertcoin.gif deleted file mode 100644 index 03a45f0b..00000000 Binary files a/icons/blue_app_vertcoin.gif and /dev/null differ diff --git a/icons/blue_app_viacoin.gif b/icons/blue_app_viacoin.gif deleted file mode 100644 index 26fa445f..00000000 Binary files a/icons/blue_app_viacoin.gif and /dev/null differ diff --git a/icons/blue_app_xrhodium.gif b/icons/blue_app_xrhodium.gif deleted file mode 100644 index 766ab161..00000000 Binary files a/icons/blue_app_xrhodium.gif and /dev/null differ diff --git a/icons/blue_app_xsn.gif b/icons/blue_app_xsn.gif deleted file mode 100644 index 68e9e43a..00000000 Binary files a/icons/blue_app_xsn.gif and /dev/null differ diff --git a/icons/blue_app_zcash.gif b/icons/blue_app_zcash.gif deleted file mode 100644 index 980cded6..00000000 Binary files a/icons/blue_app_zcash.gif and /dev/null differ diff --git a/icons/blue_app_zclassic.gif b/icons/blue_app_zclassic.gif deleted file mode 100644 index 950aad75..00000000 Binary files a/icons/blue_app_zclassic.gif and /dev/null differ diff --git a/icons/nanos_app_bitcoin_cash.gif b/icons/nanos_app_bitcoin_cash.gif index 9fa736b1..fabc8a31 100644 Binary files a/icons/nanos_app_bitcoin_cash.gif and b/icons/nanos_app_bitcoin_cash.gif differ diff --git a/icons/nanos_app_bitcoin_gold.gif b/icons/nanos_app_bitcoin_gold.gif index 9fa736b1..fabc8a31 100644 Binary files a/icons/nanos_app_bitcoin_gold.gif and b/icons/nanos_app_bitcoin_gold.gif differ diff --git a/icons/nanos_app_bitcoin_legacy.gif b/icons/nanos_app_bitcoin_legacy.gif index 9fa736b1..fabc8a31 100644 Binary files a/icons/nanos_app_bitcoin_legacy.gif and b/icons/nanos_app_bitcoin_legacy.gif differ diff --git a/icons/nanos_app_bitcoin_private.gif b/icons/nanos_app_bitcoin_private.gif index 8eae073e..8f33da7b 100644 Binary files a/icons/nanos_app_bitcoin_private.gif and b/icons/nanos_app_bitcoin_private.gif differ diff --git a/icons/nanos_app_bitcoin_testnet_legacy.gif b/icons/nanos_app_bitcoin_testnet_legacy.gif index 9fa736b1..fabc8a31 100644 Binary files a/icons/nanos_app_bitcoin_testnet_legacy.gif and b/icons/nanos_app_bitcoin_testnet_legacy.gif differ diff --git a/icons/nanos_app_dash.gif b/icons/nanos_app_dash.gif index 77813957..fc2ac026 100644 Binary files a/icons/nanos_app_dash.gif and b/icons/nanos_app_dash.gif differ diff --git a/icons/nanos_app_digibyte.gif b/icons/nanos_app_digibyte.gif index 71d41a09..3d876a2d 100644 Binary files a/icons/nanos_app_digibyte.gif and b/icons/nanos_app_digibyte.gif differ diff --git a/icons/nanos_app_dogecoin.gif b/icons/nanos_app_dogecoin.gif index 82596997..71ce21dc 100644 Binary files a/icons/nanos_app_dogecoin.gif and b/icons/nanos_app_dogecoin.gif differ diff --git a/icons/nanos_app_gamecredits.gif b/icons/nanos_app_gamecredits.gif index ce780fc5..e761e02c 100644 Binary files a/icons/nanos_app_gamecredits.gif and b/icons/nanos_app_gamecredits.gif differ diff --git a/icons/nanos_app_horizen.gif b/icons/nanos_app_horizen.gif index c8e2bd00..c5510c68 100644 Binary files a/icons/nanos_app_horizen.gif and b/icons/nanos_app_horizen.gif differ diff --git a/icons/nanos_app_hydra.gif b/icons/nanos_app_hydra.gif index ef5edfa3..29a16ab6 100644 Binary files a/icons/nanos_app_hydra.gif and b/icons/nanos_app_hydra.gif differ diff --git a/icons/nanos_app_hydra_testnet.gif b/icons/nanos_app_hydra_testnet.gif index ef5edfa3..29a16ab6 100644 Binary files a/icons/nanos_app_hydra_testnet.gif and b/icons/nanos_app_hydra_testnet.gif differ diff --git a/icons/nanos_app_komodo.gif b/icons/nanos_app_komodo.gif index c0c2536f..0145d1ec 100644 Binary files a/icons/nanos_app_komodo.gif and b/icons/nanos_app_komodo.gif differ diff --git a/icons/nanos_app_lbry.gif b/icons/nanos_app_lbry.gif index 64a44ae3..01446fcb 100644 Binary files a/icons/nanos_app_lbry.gif and b/icons/nanos_app_lbry.gif differ diff --git a/icons/nanos_app_litecoin.gif b/icons/nanos_app_litecoin.gif index 6b13d811..ea6eca27 100644 Binary files a/icons/nanos_app_litecoin.gif and b/icons/nanos_app_litecoin.gif differ diff --git a/icons/nanos_app_nix.gif b/icons/nanos_app_nix.gif index 12700c59..afae8558 100644 Binary files a/icons/nanos_app_nix.gif and b/icons/nanos_app_nix.gif differ diff --git a/icons/nanos_app_peercoin.gif b/icons/nanos_app_peercoin.gif index 3c32b993..797c839f 100644 Binary files a/icons/nanos_app_peercoin.gif and b/icons/nanos_app_peercoin.gif differ diff --git a/icons/nanos_app_pivx.gif b/icons/nanos_app_pivx.gif index 30ef95a9..530a0c82 100644 Binary files a/icons/nanos_app_pivx.gif and b/icons/nanos_app_pivx.gif differ diff --git a/icons/nanos_app_qtum.gif b/icons/nanos_app_qtum.gif index 7e2c908c..26e7d77d 100644 Binary files a/icons/nanos_app_qtum.gif and b/icons/nanos_app_qtum.gif differ diff --git a/icons/nanos_app_ravencoin.gif b/icons/nanos_app_ravencoin.gif index 630d7c04..9819cd9b 100644 Binary files a/icons/nanos_app_ravencoin.gif and b/icons/nanos_app_ravencoin.gif differ diff --git a/icons/nanos_app_resistance.gif b/icons/nanos_app_resistance.gif index e702f779..0f5ec19e 100644 Binary files a/icons/nanos_app_resistance.gif and b/icons/nanos_app_resistance.gif differ diff --git a/icons/nanos_app_stealth.gif b/icons/nanos_app_stealth.gif index 64106dbe..8c96f9f3 100644 Binary files a/icons/nanos_app_stealth.gif and b/icons/nanos_app_stealth.gif differ diff --git a/icons/nanos_app_stratis.gif b/icons/nanos_app_stratis.gif index a1e85df6..819aedb2 100644 Binary files a/icons/nanos_app_stratis.gif and b/icons/nanos_app_stratis.gif differ diff --git a/icons/nanos_app_vertcoin.gif b/icons/nanos_app_vertcoin.gif index 7b6fa60d..afc8b83f 100644 Binary files a/icons/nanos_app_vertcoin.gif and b/icons/nanos_app_vertcoin.gif differ diff --git a/icons/nanos_app_viacoin.gif b/icons/nanos_app_viacoin.gif index 015bb8bf..a7fe4029 100644 Binary files a/icons/nanos_app_viacoin.gif and b/icons/nanos_app_viacoin.gif differ diff --git a/icons/nanos_app_xrhodium.gif b/icons/nanos_app_xrhodium.gif index 8e9e2318..03a79af9 100644 Binary files a/icons/nanos_app_xrhodium.gif and b/icons/nanos_app_xrhodium.gif differ diff --git a/icons/nanos_app_xsn.gif b/icons/nanos_app_xsn.gif index 8819a7db..b55e0ccf 100644 Binary files a/icons/nanos_app_xsn.gif and b/icons/nanos_app_xsn.gif differ diff --git a/icons/nanos_app_zcash.gif b/icons/nanos_app_zcash.gif index 826a1baa..0980a2e8 100644 Binary files a/icons/nanos_app_zcash.gif and b/icons/nanos_app_zcash.gif differ diff --git a/icons/nanos_app_zclassic.gif b/icons/nanos_app_zclassic.gif index 254c648d..7c0effee 100644 Binary files a/icons/nanos_app_zclassic.gif and b/icons/nanos_app_zclassic.gif differ diff --git a/icons/nanox_app_hydra.gif b/icons/nanox_app_hydra.gif index 169174df..42f6fc35 100644 Binary files a/icons/nanox_app_hydra.gif and b/icons/nanox_app_hydra.gif differ diff --git a/icons/nanox_app_hydra_testnet.gif b/icons/nanox_app_hydra_testnet.gif index 169174df..42f6fc35 100644 Binary files a/icons/nanox_app_hydra_testnet.gif and b/icons/nanox_app_hydra_testnet.gif differ diff --git a/icons/nanox_app_ravencoin.gif b/icons/nanox_app_ravencoin.gif index 13146cff..43866171 100644 Binary files a/icons/nanox_app_ravencoin.gif and b/icons/nanox_app_ravencoin.gif differ diff --git a/icons/nanox_app_xsn.gif b/icons/nanox_app_xsn.gif index 92f4a6a2..2c885ee3 100644 Binary files a/icons/nanox_app_xsn.gif and b/icons/nanox_app_xsn.gif differ diff --git a/icons/stax_app_bitcoin.gif b/icons/stax_app_bitcoin.gif new file mode 100644 index 00000000..99915d7c Binary files /dev/null and b/icons/stax_app_bitcoin.gif differ diff --git a/icons/stax_app_bitcoin_cash.gif b/icons/stax_app_bitcoin_cash.gif new file mode 100644 index 00000000..99915d7c Binary files /dev/null and b/icons/stax_app_bitcoin_cash.gif differ diff --git a/icons/stax_app_bitcoin_gold.gif b/icons/stax_app_bitcoin_gold.gif new file mode 100644 index 00000000..99915d7c Binary files /dev/null and b/icons/stax_app_bitcoin_gold.gif differ diff --git a/icons/stax_app_bitcoin_legacy.gif b/icons/stax_app_bitcoin_legacy.gif new file mode 100644 index 00000000..99915d7c Binary files /dev/null and b/icons/stax_app_bitcoin_legacy.gif differ diff --git a/icons/stax_app_bitcoin_private.gif b/icons/stax_app_bitcoin_private.gif new file mode 100644 index 00000000..99915d7c Binary files /dev/null and b/icons/stax_app_bitcoin_private.gif differ diff --git a/icons/stax_app_bitcoin_testnet.gif b/icons/stax_app_bitcoin_testnet.gif new file mode 100644 index 00000000..99915d7c Binary files /dev/null and b/icons/stax_app_bitcoin_testnet.gif differ diff --git a/icons/stax_app_bitcoin_testnet_legacy.gif b/icons/stax_app_bitcoin_testnet_legacy.gif new file mode 100644 index 00000000..99915d7c Binary files /dev/null and b/icons/stax_app_bitcoin_testnet_legacy.gif differ diff --git a/icons/stax_app_dash.gif b/icons/stax_app_dash.gif new file mode 100644 index 00000000..ff4c19b0 Binary files /dev/null and b/icons/stax_app_dash.gif differ diff --git a/icons/stax_app_digibyte.gif b/icons/stax_app_digibyte.gif new file mode 100644 index 00000000..299de353 Binary files /dev/null and b/icons/stax_app_digibyte.gif differ diff --git a/icons/stax_app_dogecoin.gif b/icons/stax_app_dogecoin.gif new file mode 100644 index 00000000..578c4f18 Binary files /dev/null and b/icons/stax_app_dogecoin.gif differ diff --git a/icons/stax_app_firo.gif b/icons/stax_app_firo.gif new file mode 100644 index 00000000..e81e3790 Binary files /dev/null and b/icons/stax_app_firo.gif differ diff --git a/icons/stax_app_gamecredits.gif b/icons/stax_app_gamecredits.gif new file mode 100644 index 00000000..d36e7a42 Binary files /dev/null and b/icons/stax_app_gamecredits.gif differ diff --git a/icons/stax_app_horizen.gif b/icons/stax_app_horizen.gif new file mode 100644 index 00000000..842858b2 Binary files /dev/null and b/icons/stax_app_horizen.gif differ diff --git a/icons/stax_app_hydra.gif b/icons/stax_app_hydra.gif new file mode 100644 index 00000000..810a8dd9 Binary files /dev/null and b/icons/stax_app_hydra.gif differ diff --git a/icons/stax_app_hydra_testnet.gif b/icons/stax_app_hydra_testnet.gif new file mode 100644 index 00000000..810a8dd9 Binary files /dev/null and b/icons/stax_app_hydra_testnet.gif differ diff --git a/icons/stax_app_komodo.gif b/icons/stax_app_komodo.gif new file mode 100644 index 00000000..17d6adab Binary files /dev/null and b/icons/stax_app_komodo.gif differ diff --git a/icons/stax_app_lbry.gif b/icons/stax_app_lbry.gif new file mode 100644 index 00000000..654b7d35 Binary files /dev/null and b/icons/stax_app_lbry.gif differ diff --git a/icons/stax_app_litecoin.gif b/icons/stax_app_litecoin.gif new file mode 100644 index 00000000..aecc5f2f Binary files /dev/null and b/icons/stax_app_litecoin.gif differ diff --git a/icons/stax_app_nix.gif b/icons/stax_app_nix.gif new file mode 100644 index 00000000..75158fdf Binary files /dev/null and b/icons/stax_app_nix.gif differ diff --git a/icons/stax_app_peercoin.gif b/icons/stax_app_peercoin.gif new file mode 100644 index 00000000..77f755af Binary files /dev/null and b/icons/stax_app_peercoin.gif differ diff --git a/icons/stax_app_pivx.gif b/icons/stax_app_pivx.gif new file mode 100644 index 00000000..b8d93347 Binary files /dev/null and b/icons/stax_app_pivx.gif differ diff --git a/icons/stax_app_qtum.gif b/icons/stax_app_qtum.gif new file mode 100644 index 00000000..c18be61b Binary files /dev/null and b/icons/stax_app_qtum.gif differ diff --git a/icons/stax_app_ravencoin.gif b/icons/stax_app_ravencoin.gif new file mode 100644 index 00000000..4ce3d44f Binary files /dev/null and b/icons/stax_app_ravencoin.gif differ diff --git a/icons/stax_app_resistance.gif b/icons/stax_app_resistance.gif new file mode 100644 index 00000000..2809fd1e Binary files /dev/null and b/icons/stax_app_resistance.gif differ diff --git a/icons/stax_app_stealth.gif b/icons/stax_app_stealth.gif new file mode 100644 index 00000000..345e1242 Binary files /dev/null and b/icons/stax_app_stealth.gif differ diff --git a/icons/stax_app_stratis.gif b/icons/stax_app_stratis.gif new file mode 100644 index 00000000..4902f390 Binary files /dev/null and b/icons/stax_app_stratis.gif differ diff --git a/icons/stax_app_vertcoin.gif b/icons/stax_app_vertcoin.gif new file mode 100644 index 00000000..3cacea66 Binary files /dev/null and b/icons/stax_app_vertcoin.gif differ diff --git a/icons/stax_app_viacoin.gif b/icons/stax_app_viacoin.gif new file mode 100644 index 00000000..567f620a Binary files /dev/null and b/icons/stax_app_viacoin.gif differ diff --git a/icons/stax_app_xrhodium.gif b/icons/stax_app_xrhodium.gif new file mode 100644 index 00000000..a5094347 Binary files /dev/null and b/icons/stax_app_xrhodium.gif differ diff --git a/icons/stax_app_xsn.gif b/icons/stax_app_xsn.gif new file mode 100644 index 00000000..08e35ffd Binary files /dev/null and b/icons/stax_app_xsn.gif differ diff --git a/icons/stax_app_zcash.gif b/icons/stax_app_zcash.gif new file mode 100644 index 00000000..5bef4a5a Binary files /dev/null and b/icons/stax_app_zcash.gif differ diff --git a/icons/stax_app_zclassic.gif b/icons/stax_app_zclassic.gif new file mode 100644 index 00000000..03002f8f Binary files /dev/null and b/icons/stax_app_zclassic.gif differ diff --git a/include/btchip.h b/include/btchip.h deleted file mode 100644 index d303a17a..00000000 --- a/include/btchip.h +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef BTCHIP_H - -#define BTCHIP_H - -#include "btchip_config.h" -#include "os.h" -#include "os_io_seproxyhal.h" - -#include "stdlib.h" -#include "stdbool.h" - -#define L_DEBUG_NOPREFIX(x) - -#define SW_TECHNICAL_DETAILS(x) BTCHIP_SW_TECHNICAL_PROBLEM - -#include "btchip_secure_value.h" - -#endif diff --git a/include/btchip_apdu_constants.h b/include/btchip_apdu_constants.h deleted file mode 100644 index 2a6e258b..00000000 --- a/include/btchip_apdu_constants.h +++ /dev/null @@ -1,158 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef BTCHIP_APDU_CONSTANTS_H - -#define BTCHIP_APDU_CONSTANTS_H - -#define BTCHIP_CLA 0xE0 -#define BTCHIP_ADM_CLA 0xD0 -#define BTCHIP_NFCPAYMENT_CLA 0xF0 - -#define BTCHIP_INS_SETUP 0x20 -#define BTCHIP_INS_VERIFY_PIN 0x22 -#define BTCHIP_INS_GET_OPERATION_MODE 0x24 -#define BTCHIP_INS_SET_OPERATION_MODE 0x26 -#define BTCHIP_INS_SET_KEYBOARD_CFG 0x28 -#define BTCHIP_INS_GET_WALLET_PUBLIC_KEY 0x40 -#define BTCHIP_INS_GET_TRUSTED_INPUT 0x42 -#define BTCHIP_INS_HASH_INPUT_START 0x44 -#define BTCHIP_INS_HASH_INPUT_FINALIZE 0x46 -#define BTCHIP_INS_HASH_SIGN 0x48 -#define BTCHIP_INS_HASH_INPUT_FINALIZE_FULL 0x4A -#define BTCHIP_INS_GET_INTERNAL_CHAIN_INDEX 0x4C -#define BTCHIP_INS_SIGN_MESSAGE 0x4E -#define BTCHIP_INS_GET_TRANSACTION_LIMIT 0xA0 -#define BTCHIP_INS_SET_TRANSACTION_LIMIT 0xA2 -#define BTCHIP_INS_IMPORT_PRIVATE_KEY 0xB0 -#define BTCHIP_INS_GET_PUBLIC_KEY 0xB2 -#define BTCHIP_INS_DERIVE_BIP32_KEY 0xB4 -#define BTCHIP_INS_SIGNVERIFY_IMMEDIATE 0xB6 -#define BTCHIP_INS_GET_RANDOM 0xC0 -#define BTCHIP_INS_GET_ATTESTATION 0xC2 -#define BTCHIP_INS_GET_FIRMWARE_VERSION 0xC4 -#define BTCHIP_INS_COMPOSE_MOFN_ADDRESS 0xC6 -#define BTCHIP_INS_GET_POS_SEED 0xCA -#define BTCHIP_INS_DEBUG 0xD0 - -#define BTCHIP_INS_ADM_INIT_KEYS 0x20 -#define BTCHIP_INS_ADM_INIT_ATTESTATION 0x22 -#define BTCHIP_INS_ADM_GET_UPDATE_ID 0x24 -#define BTCHIP_INS_ADM_SET_KEYCARD_SEED 0x26 -#define BTCHIP_INS_ADM_FIRMWARE_UPDATE 0x42 - -#define BTCHIP_INS_SET_USER_KEYCARD 0x10 -#define BTCHIP_INS_SETUP_SECURE_SCREEN 0x12 -#define BTCHIP_INS_SET_ALTERNATE_COIN_VER 0x14 -#define BTCHIP_INS_GET_COIN_VER 0x16 - -#define BTCHIP_INS_STORE_TRUST_ROOT_BIP70 0x30 -#define BTCHIP_INS_CREATE_CERTIFICATE_BIP70 0x32 -#define BTCHIP_INS_CREATE_PAYMENT_REQ_BIP70 0x34 -#define BTCHIP_INS_PROCESS_CERTIFICATE_BIP70 0x36 -#define BTCHIP_INS_PARSE_PAYMENT_REQ_BIP70 0x38 -#define BTCHIP_INS_HASH_INPUT_FINALIZE_BIP70 0x3A -#define BTCHIP_INS_ADM_SET_ROOT_BIP70 0x28 -#define BTCHIP_INS_ADM_SET_BIP39_SHUFFLE 0x2A - -#define BTCHIP_INS_NFCPAYMENT_SET_CONFIG 0x20 -#define BTCHIP_INS_NFCPAYMENT_GET_CONFIG 0x22 -#define BTCHIP_INS_NFCPAYMENT_STORE_UTXO 0x40 -#define BTCHIP_INS_NFCPAYMENT_STORE_SCRIPT 0x42 -#define BTCHIP_INS_NFCPAYMENT_GET_UTXO 0x44 -#define BTCHIP_INS_NFCPAYMENT_DELETE_UTXO 0x46 -#define BTCHIP_INS_NFCPAYMENT_GET_PAYMENT_TX 0x50 -#define BTCHIP_INS_NFCPAYMENT_GET_LAST_TX 0x52 -#define BTCHIP_INS_NFCPAYMENT_CONFIRM_TX 0x54 -#define BTCHIP_INS_NFCPAYMENT_CONFIRM_CHANGE 0x56 -#define BTCHIP_INS_NFCPAYMENT_GET_LAST_STAT 0x58 -#define BTCHIP_INS_NFCPAYMENT_GET_DATA 0xC0 - -#define BTCHIP_SW_PIN_REMAINING_ATTEMPTS 0x63C0 -#define BTCHIP_SW_INCORRECT_LENGTH 0x6700 -#define BTCHIP_SW_COMMAND_INCOMPATIBLE_FILE_STRUCTURE 0x6981 -#define BTCHIP_SW_SECURITY_STATUS_NOT_SATISFIED 0x6982 -#define BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED 0x6985 -#define BTCHIP_SW_INCORRECT_DATA 0x6A80 -#define BTCHIP_SW_NOT_ENOUGH_MEMORY_SPACE 0x6A84 -#define BTCHIP_SW_REFERENCED_DATA_NOT_FOUND 0x6A88 -#define BTCHIP_SW_FILE_ALREADY_EXISTS 0x6A89 -#define BTCHIP_SW_SWAP_WITHOUT_TRUSTED_INPUTS 0x6A8A -#define BTCHIP_SW_INCORRECT_P1_P2 0x6B00 -#define BTCHIP_SW_INS_NOT_SUPPORTED 0x6D00 -#define BTCHIP_SW_CLA_NOT_SUPPORTED 0x6E00 -#define BTCHIP_SW_TECHNICAL_PROBLEM 0x6F00 -#define BTCHIP_SW_OK 0x9000 -#define BTCHIP_SW_MEMORY_PROBLEM 0x9240 -#define BTCHIP_SW_NO_EF_SELECTED 0x9400 -#define BTCHIP_SW_INVALID_OFFSET 0x9402 -#define BTCHIP_SW_FILE_NOT_FOUND 0x9404 -#define BTCHIP_SW_INCONSISTENT_FILE 0x9408 -#define BTCHIP_SW_ALGORITHM_NOT_SUPPORTED 0x9484 -#define BTCHIP_SW_INVALID_KCV 0x9485 -#define BTCHIP_SW_CODE_NOT_INITIALIZED 0x9802 -#define BTCHIP_SW_ACCESS_CONDITION_NOT_FULFILLED 0x9804 -#define BTCHIP_SW_CONTRADICTION_SECRET_CODE_STATUS 0x9808 -#define BTCHIP_SW_CONTRADICTION_INVALIDATION 0x9810 -#define BTCHIP_SW_CODE_BLOCKED 0x9840 -#define BTCHIP_SW_MAX_VALUE_REACHED 0x9850 -#define BTCHIP_SW_GP_AUTH_FAILED 0x6300 -#define BTCHIP_SW_LICENSING 0x6F42 -#define BTCHIP_SW_HALTED 0x6FAA -#define BTCHIP_SW_APP_HALTED BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED - -#define ISO_OFFSET_CLA 0x00 -#define ISO_OFFSET_INS 0x01 -#define ISO_OFFSET_P1 0x02 -#define ISO_OFFSET_P2 0x03 -#define ISO_OFFSET_LC 0x04 -#define ISO_OFFSET_CDATA 0x05 - -#define BTCHIP_2FA_NONE 0x00 -#define BTCHIP_2FA_KEYBOARD 0x01 -#define BTCHIP_2FA_SECURE_SCREEN 0x02 - -#define BITID_DERIVE 0xB11D -#define BITID_DERIVE_MULTIPLE 0xB11E - -#include "os.h" -#include "btchip_secure_value.h" - -void btchip_commit_operation_mode(secu8 operationMode); - -unsigned short btchip_apdu_setup(void); -unsigned short btchip_apdu_verify_pin(void); -unsigned short btchip_apdu_get_operation_mode(void); -unsigned short btchip_apdu_set_operation_mode(void); -unsigned short btchip_apdu_get_wallet_public_key(void); -unsigned short btchip_apdu_get_trusted_input(void); -unsigned short btchip_apdu_hash_input_start(void); -unsigned short btchip_apdu_hash_input_finalize(void); -unsigned short btchip_apdu_hash_sign(void); -unsigned short btchip_apdu_hash_input_finalize_full(void); -unsigned short btchip_apdu_import_private_key(void); -unsigned short btchip_apdu_get_public_key(void); -unsigned short btchip_apdu_derive_bip32_key(void); -unsigned short btchip_apdu_signverify_immediate(void); -unsigned short btchip_apdu_sign_message(void); - -unsigned short btchip_apdu_get_random(void); -unsigned short btchip_apdu_get_firmware_version(void); - -unsigned short btchip_apdu_get_coin_version(void); - -#endif diff --git a/include/btchip_base58.h b/include/btchip_base58.h deleted file mode 100644 index 38d3f6c5..00000000 --- a/include/btchip_base58.h +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef BTCHIP_BASE58_H - -#define BTCHIP_BASE58_H - -#include - -int btchip_decode_base58(const char *in, size_t length, - unsigned char *out, size_t *outlen); - -int btchip_encode_base58(const unsigned char *in, size_t length, - unsigned char *out, size_t *outlen); - -#endif diff --git a/include/btchip_bcd.h b/include/btchip_bcd.h deleted file mode 100644 index 51fd54c4..00000000 --- a/include/btchip_bcd.h +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef BTCHIP_BCD_H - -#define BTCHIP_BCD_H - -unsigned char -btchip_convert_hex_amount_to_displayable_no_globals(unsigned char *amount, unsigned int config_flag, unsigned char* out); - -unsigned char -btchip_convert_hex_amount_to_displayable(unsigned char *amount); - -#endif diff --git a/include/btchip_config.h b/include/btchip_config.h deleted file mode 100644 index 56b49880..00000000 --- a/include/btchip_config.h +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef BTCHIP_CONFIG_H - -#define BTCHIP_CONFIG_H - -//#define DISABLE_SECURE_VALUE - -#define VERBOSE_6F - -#define os_crc cx_crc16 - -#endif diff --git a/include/btchip_context.h b/include/btchip_context.h deleted file mode 100644 index 2667b9d6..00000000 --- a/include/btchip_context.h +++ /dev/null @@ -1,311 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef BTCHIP_CONTEXT_H - -#define BTCHIP_CONTEXT_H - -#include "os.h" -#include "cx.h" -#include "btchip_secure_value.h" -#include "btchip_filesystem_tx.h" - -#define MAX_OUTPUT_TO_CHECK 100 -#define MAX_COIN_ID 13 -#define MAX_SHORT_COIN_ID 5 - -#define MAGIC_TRUSTED_INPUT 0x32 -#define MAGIC_DEV_KEY 0x01 - -#define ZCASH_USING_OVERWINTER 0x01 -#define ZCASH_USING_OVERWINTER_SAPLING 0x02 - -enum btchip_modes_e { - BTCHIP_MODE_ISSUER = 0x00, - BTCHIP_MODE_SETUP_NEEDED = 0xff, - BTCHIP_MODE_WALLET = 0x01, - BTCHIP_MODE_RELAXED_WALLET = 0x02, - BTCHIP_MODE_SERVER = 0x04, - BTCHIP_MODE_DEVELOPER = 0x08, -}; - -enum btchip_options_e { - BTCHIP_OPTION_UNCOMPRESSED_KEYS = 0x01, - BTCHIP_OPTION_DETERMINISTIC_SIGNATURE = 0x02, - BTCHIP_OPTION_FREE_SIGHASHTYPE = 0x04, - BTCHIP_OPTION_SKIP_2FA_P2SH = 0x08, - BTCHIP_OPTION_ALLOW_ARBITRARY_CHANGE = 0x10 -}; - -/** - * Current state of an untrusted transaction hashing - */ -enum btchip_transaction_state_e { - /** No transaction in progress */ - BTCHIP_TRANSACTION_NONE = 0x00, - /** Transaction defined, waiting for an input to be hashed */ - BTCHIP_TRANSACTION_DEFINED_WAIT_INPUT = 0x01, - /** Transaction defined, input hashing in progress, pending input script - data */ - BTCHIP_TRANSACTION_INPUT_HASHING_IN_PROGRESS_INPUT_SCRIPT = 0x02, - /** Transaction defined, input hashing done, pending output hashing for this - input */ - BTCHIP_TRANSACTION_INPUT_HASHING_DONE = 0x03, - /** Transaction defined, waiting for an output to be hashed */ - BTCHIP_TRANSACTION_DEFINED_WAIT_OUTPUT = 0x04, - /** Transaction defined, output hashing in progress for a complex script, - pending output script data */ - BTCHIP_TRANSACTION_OUTPUT_HASHING_IN_PROGRESS_OUTPUT_SCRIPT = 0x05, - /** Transaction defined, output hashing done, pending finalization */ - BTCHIP_TRANSACTION_OUTPUT_HASHING_DONE = 0x06, - /** Extra data present */ - BTCHIP_TRANSACTION_PROCESS_EXTRA = 0x07, - /** Transaction parsed */ - BTCHIP_TRANSACTION_PARSED = 0x08, - /** Transaction parsed, ready to prepare for signature after validating the - user outputs */ - BTCHIP_TRANSACTION_PRESIGN_READY = 0x09, - /** Transaction fully parsed, ready to be signed */ - BTCHIP_TRANSACTION_SIGN_READY = 0x0a, -}; -typedef enum btchip_transaction_state_e btchip_transaction_state_t; - -enum btchip_output_parsing_state_e { - BTCHIP_OUTPUT_PARSING_NONE = 0x00, - BTCHIP_OUTPUT_PARSING_NUMBER_OUTPUTS = 0x01, - BTCHIP_OUTPUT_PARSING_OUTPUT = 0x02, - BTCHIP_OUTPUT_FINALIZE_TX = 0x03, - BTCHIP_BIP44_CHANGE_PATH_VALIDATION = 0x04 -}; -typedef enum btchip_output_parsing_state_e btchip_output_parsing_state_t; - - -typedef union multi_hash { - cx_sha256_t sha256; - cx_blake2b_t blake2b; -} multi_hash; - -struct segwit_hash_s { - union multi_hash hashPrevouts; -}; -struct segwit_cache_s { - unsigned char hashedPrevouts[32]; - unsigned char hashedSequence[32]; - unsigned char hashedOutputs[32]; -}; - -/** - * Structure defining an operation on a transaction - */ -struct btchip_transaction_context_s { - /** Transient over signing components */ - - /** Remaining number of inputs/outputs to process for this transaction */ - unsigned long int transactionRemainingInputsOutputs; - /** Index of the currently processed input/output for this transaction */ - unsigned long int transactionCurrentInputOutput; - /** Remaining script bytes to process for the current input or output */ - unsigned long int scriptRemaining; - - /** Persistent over signing components */ - - /** State of the transaction, type btchip_transaction_state_t */ - unsigned char transactionState; - /** Computed sum of transaction inputs or value of the output to convert to - * a trusted input */ - unsigned char transactionAmount[8]; - /** Flag indicating if this transaction has been processed before */ - unsigned char firstSigned; - /** If the transaction is relaxed */ - unsigned char relaxed; - /** If the transaction consumes a P2SH input */ - unsigned char consumeP2SH; -}; -typedef struct btchip_transaction_context_s btchip_transaction_context_t; - -struct btchip_tmp_output_s { - /** Change address if initialized */ - unsigned char changeAddress[20]; - /** Flag set if the change address was initialized */ - unsigned char changeInitialized; - /** Flag set if the change address was checked */ - unsigned char changeChecked; - /** Flag set if the change address can be submitted */ - unsigned char changeAccepted; - /** Flag set if the outputs have been fragmented */ - unsigned char multipleOutput; -}; -typedef struct btchip_tmp_output_s btchip_tmp_output_t; - -struct btchip_context_s { - /** Flag if dongle has been halted */ - secu8 halted; - /** Index of the output to convert into a trusted input in a transaction */ - unsigned long int trustedInputIndex; - /** (Integrity protected) transaction context */ - btchip_transaction_context_t transactionContext; - - /** Non protected transaction context */ - - /** Last U2F Token streamed by host to attempt pubkey request */ - unsigned char last_token[4]; - unsigned char has_valid_token; - - /** Full transaction hash context */ - union multi_hash transactionHashFull; - /** Authorization transaction hash context */ - cx_sha256_t transactionHashAuthorization; - /** Current hash to perform (TRANSACTION_HASH_) */ - unsigned char transactionHashOption; - - /* Segregated Witness changes */ - - union { - struct segwit_hash_s hash; - struct segwit_cache_s cache; - } segwit; - unsigned char transactionVersion[4]; - unsigned char inputValue[8]; - unsigned char usingSegwit; - unsigned char usingCashAddr; - unsigned char segwitParsedOnce; - /** Prevents display of segwit input warning at each InputHashStart APDU */ - unsigned char segwitWarningSeen; - - /* /Segregated Witness changes */ - - /** Size currently available to the transaction parser */ - unsigned char transactionDataRemaining; - /** Current pointer to the transaction buffer for the transaction parser */ - unsigned char *transactionBufferPointer; - /** Trusted Input index processed */ - unsigned char trustedInputProcessed; - /** Transaction input to catch for a Trusted Input lookup */ - unsigned long int transactionTargetInput; - - /** Length of the incoming command */ - unsigned short inLength; - /** Length of the outgoing command */ - unsigned short outLength; - - /** IO flags to reply with at the end of an APDU handler */ - unsigned char io_flags; - - /** Status Word of the response */ - unsigned short sw; - - /** Current scratch buffer */ - unsigned char *tmp; - - // was previously in NVRAM - btchip_transaction_summary_t transactionSummary; - - - unsigned short hashedMessageLength; - - union { - btchip_tmp_output_t output; - } tmpCtx; - - unsigned char currentOutput[MAX_OUTPUT_TO_CHECK]; - unsigned short currentOutputOffset; - unsigned int remainingOutputs; - unsigned int totalOutputs; - unsigned int discardSize; - unsigned char outputParsingState; - unsigned char totalOutputAmount[8]; - unsigned char changeOutputFound; - - /* Overwinter */ - unsigned char usingOverwinter; - unsigned char overwinterSignReady; - unsigned char nVersionGroupId[4]; - unsigned char nExpiryHeight[4]; - unsigned char nLockTime[4]; - unsigned char sigHashType[4]; - - /*Is swap mode*/ - unsigned char called_from_swap; -}; -typedef struct btchip_context_s btchip_context_t; - - -/** - * Structure to configure the bitcoin application for a given altcoin - * - */ -typedef enum btchip_coin_flags_e { - FLAG_PEERCOIN_UNITS=1, - FLAG_PEERCOIN_SUPPORT=2, - FLAG_SEGWIT_CHANGE_SUPPORT=4 -} btchip_coin_flags_t; - - -typedef enum btchip_coin_kind_e { - COIN_KIND_BITCOIN_TESTNET, - COIN_KIND_BITCOIN, - COIN_KIND_BITCOIN_CASH, - COIN_KIND_BITCOIN_GOLD, - COIN_KIND_LITECOIN, - COIN_KIND_DOGE, - COIN_KIND_DASH, - COIN_KIND_ZCASH, - COIN_KIND_KOMODO, - COIN_KIND_RFU, - COIN_KIND_STRATIS, - COIN_KIND_PEERCOIN, - COIN_KIND_PIVX, - COIN_KIND_STEALTH, - COIN_KIND_VIACOIN, - COIN_KIND_VERTCOIN, - COIN_KIND_DIGIBYTE, - COIN_KIND_QTUM, - COIN_KIND_BITCOIN_PRIVATE, - COIN_KIND_XRHODIUM, - COIN_KIND_HORIZEN, - COIN_KIND_GAMECREDITS, - COIN_KIND_FIRO, - COIN_KIND_ZCLASSIC, - COIN_KIND_XSN, - COIN_KIND_NIX, - COIN_KIND_LBRY, - COIN_KIND_RESISTANCE, - COIN_KIND_RAVENCOIN, - COIN_KIND_HYDRA -} btchip_coin_kind_t; - -typedef struct btchip_altcoin_config_s { - unsigned short bip44_coin_type; - unsigned short bip44_coin_type2; - unsigned short p2pkh_version; - unsigned short p2sh_version; - unsigned char family; - //unsigned char* iconsuffix;// will use the icon provided on the stack (maybe) - char coinid[14]; // used coind id for message signature prefix - char name[16]; // for ux displays - char name_short[6]; // for unit in ux displays - char native_segwit_prefix_val[5]; - const char* native_segwit_prefix; // null if no segwit prefix - unsigned int forkid; - unsigned int zcash_consensus_branch_id; - btchip_coin_kind_t kind; - unsigned int flags; -} btchip_altcoin_config_t; - -void btchip_context_init(void); - -#endif diff --git a/include/btchip_ecc.h b/include/btchip_ecc.h deleted file mode 100644 index e6ada21c..00000000 --- a/include/btchip_ecc.h +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef BTCHIP_ECC_H - -#define BTCHIP_ECC_H - -#include "os.h" - -#define BTCHIP_CURVE CX_CURVE_256K1 - -void btchip_compress_public_key_value(unsigned char *value); - -#endif diff --git a/include/btchip_filesystem.h b/include/btchip_filesystem.h deleted file mode 100644 index 555953c8..00000000 --- a/include/btchip_filesystem.h +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef BTCHIP_FS_H - -#define BTCHIP_FS_H - -#include "os.h" -#include "btchip_config.h" -#include "btchip_context.h" -#include "btchip_filesystem_tx.h" - -enum btchip_supported_modes_e { - BTCHIP_SUPPORTED_MODE_WALLET = 0x01, - BTCHIP_SUPPORTED_MODE_RELAXED_WALLET = 0x02, - BTCHIP_SUPPORTED_MODE_SERVER = 0x04, - BTCHIP_SUPPORTED_MODE_DEVELOPER = 0x08 -}; - -enum btchip_family_e { - BTCHIP_FAMILY_BITCOIN = 0x01, - BTCHIP_FAMILY_PEERCOIN = 0x02, - BTCHIP_FAMILY_QTUM = 0x03, - BTCHIP_FAMILY_STEALTH = 0x04 -}; - -struct btchip_config_s { - secu8 supportedModes; - secu8 operationMode; - unsigned char options; - // unsigned short payToAddressVersion; - // unsigned short payToScriptHashVersion; - // unsigned char coinFamily; - // /** Current Coin ID */ - // unsigned char coinId[MAX_COIN_ID]; - // /** Current short Coin ID */ - // unsigned char shortCoinId[MAX_SHORT_COIN_ID]; - // /** Current Coin ID length */ - // unsigned char coinIdLength; - // /** Current short Coin ID length */ - // unsigned char shortCoinIdLength; -}; -typedef struct btchip_config_s btchip_config_t; - -typedef struct btchip_backup_area_s { - btchip_config_t config; - uint8_t trustedinput_key[32]; -} btchip_backup_area_t; - -typedef struct btchip_storage_s { - unsigned char storageInitialized; - - unsigned char config_valid; - btchip_backup_area_t bkp; - - unsigned char fidoTransport; - - uint8_t pubKeyRequestRestriction; - -} btchip_storage_t; - -// the global nvram memory variable -#if 0 -extern btchip_storage_t N_btchip_real; -#define N_btchip (*(btchip_storage_t *)PIC(&N_btchip_real)) -#else -extern btchip_storage_t const N_btchip_real; -#define N_btchip (*(volatile btchip_storage_t *)PIC(&N_btchip_real)) -#endif - -void btchip_set_operation_mode(unsigned char operationMode); - -#endif diff --git a/include/btchip_filesystem_tx.h b/include/btchip_filesystem_tx.h deleted file mode 100644 index fce2fe01..00000000 --- a/include/btchip_filesystem_tx.h +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef BTCHIP_FS_TX_H - -#define BTCHIP_FS_TX_H - -#include "os.h" - -#define MAX_BIP32_PATH 10 -#define MAX_BIP32_PATH_LENGTH (4 * MAX_BIP32_PATH) + 1 -#define BIP44_PATH_LEN 5 -#define BIP44_PURPOSE_OFFSET 0 -#define BIP44_COIN_TYPE_OFFSET 1 -#define BIP44_ACCOUNT_OFFSET 2 -#define BIP44_CHANGE_OFFSET 3 -#define BIP44_ADDRESS_INDEX_OFFSET 4 -#define MAX_BIP44_ACCOUNT_RECOMMENDED 100 -#define MAX_BIP44_ADDRESS_INDEX_RECOMMENDED 50000 - -struct btchip_transaction_summary_s { - unsigned char active; - unsigned char payToAddressVersion; - unsigned char payToScriptHashVersion; - unsigned char authorizationHash[32]; - unsigned char keyPath[MAX_BIP32_PATH_LENGTH]; - unsigned char transactionNonce[8]; // used to bind to the current set of inputs - unsigned short messageLength; - unsigned char sighashType; -}; -typedef struct btchip_transaction_summary_s btchip_transaction_summary_t; - -#endif diff --git a/include/btchip_helpers.h b/include/btchip_helpers.h deleted file mode 100644 index a99504b7..00000000 --- a/include/btchip_helpers.h +++ /dev/null @@ -1,98 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef BTCHIP_HELPERS_H - -#define BTCHIP_HELPERS_H - -#include "os.h" -#include "cx.h" -#include "stdbool.h" - -#define OUTPUT_SCRIPT_REGULAR_PRE_LENGTH 4 -#define OUTPUT_SCRIPT_REGULAR_POST_LENGTH 2 -#define OUTPUT_SCRIPT_P2SH_PRE_LENGTH 3 -#define OUTPUT_SCRIPT_P2SH_POST_LENGTH 1 - -#define OUTPUT_SCRIPT_NATIVE_WITNESS_PROGRAM_OFFSET 3 - -unsigned char btchip_output_script_is_regular(unsigned char *buffer); -unsigned char btchip_output_script_is_p2sh(unsigned char *buffer); -unsigned char btchip_output_script_is_op_return(unsigned char *buffer); -unsigned char btchip_output_script_is_native_witness(unsigned char *buffer); - -unsigned char btchip_output_script_is_op_create(unsigned char *buffer, - size_t size); -unsigned char btchip_output_script_is_op_call(unsigned char *buffer, - size_t size); - -void btchip_sleep16(unsigned short delay); -void btchip_sleep32(unsigned long int delayEach, unsigned long int delayRepeat); - -unsigned long int btchip_read_u32(unsigned char *buffer, unsigned char be, - unsigned char skipSign); - -void btchip_write_u32_be(unsigned char *buffer, unsigned long int value); -void btchip_write_u32_le(unsigned char *buffer, unsigned long int value); - -void btchip_perform_double_hash(unsigned char *in, unsigned short inlen, - unsigned char *out, - unsigned char hash1Algorithm, - unsigned char hash2Algorithm); - -void btchip_public_key_hash160(unsigned char *in, unsigned short inlen, - unsigned char *out); -unsigned short btchip_public_key_to_encoded_base58( - unsigned char *in, unsigned short inlen, unsigned char *out, - unsigned short outlen, unsigned short version, unsigned char alreadyHashed); - -unsigned short btchip_decode_base58_address(unsigned char *in, - unsigned short inlen, - unsigned char *out, - unsigned short outlen); - -void btchip_private_derive_keypair(unsigned char *bip32Path, - unsigned char derivePublic, - unsigned char *out_chainCode, - cx_ecfp_private_key_t * private_key, - cx_ecfp_public_key_t* public_key); - -unsigned char bip44_derivation_guard(unsigned char *bip32Path, bool is_change_path); -unsigned char enforce_bip44_coin_type(unsigned char *bip32Path, bool for_pubkey); -unsigned char bip32_print_path(unsigned char *bip32Path, char* out, unsigned char max_out_len); - -// void btchip_set_check_internal_structure_integrity(unsigned char -// setParameter); -#define btchip_set_check_internal_structure_integrity(x) -void btchip_swap_bytes(unsigned char *target, unsigned char *source, - unsigned char size); - -void btchip_sign_finalhash(void *keyContext, - unsigned char *in, unsigned short inlen, - unsigned char *out, unsigned short outlen, - unsigned char rfc6979); - -void btchip_transaction_add_output(unsigned char *hash160Address, - unsigned char *amount, unsigned char p2sh); -unsigned char btchip_rng_u8_modulo(unsigned char modulo); -unsigned char btchip_secure_memcmp(const void *buf1, const void *buf2, - unsigned short length); -unsigned char btchip_decrease_2fa(void); -void btchip_reset_2fa(void); -void btchip_reset_token(void); - -#endif diff --git a/include/btchip_secure_value.h b/include/btchip_secure_value.h deleted file mode 100644 index 0aa5d103..00000000 --- a/include/btchip_secure_value.h +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef BTCHIP_SECURE_VALUE_H - -#define BTCHIP_SECURE_VALUE_H - -#include "os.h" - -typedef unsigned short secu8; -typedef unsigned long int secu16; - -void sbSet(secu8 *target, unsigned char source); -void sbCheck(secu8 source); -void ssSet(secu16 *target, unsigned short source); -void ssCheck(secu16 source); - -#define SB_GET(x) ((unsigned char)x) - -#define SB_SET(x, y) sbSet(&x, y); - -#define SB_CHECK(x) sbCheck(x); - -#define SS_GET(x) ((unsigned short)x) - -#define SS_SET(x, y) ssSet(&x, y); - -#define SS_CHECK(x) ssCheck(x); - -#define SSEC_DEF(x) unsigned char x = 0; -#define SSEC_INC(x) x++; -#define SSEC_CHECK(x, value) \ - if (x != value) \ - reset(); - -#endif diff --git a/include/swap_lib_calls.h b/include/swap_lib_calls.h deleted file mode 100644 index 0f59a452..00000000 --- a/include/swap_lib_calls.h +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -/* This file is the shared API between Exchange and the apps started in Library mode for Exchange - * - * DO NOT MODIFY THIS FILE IN APPLICATIONS OTHER THAN EXCHANGE - * On modification in Exchange, forward the changes to all applications supporting Exchange - */ - -#include "stdbool.h" -#include "stdint.h" -#include "btchip_context.h" - -#define RUN_APPLICATION 1 - -#define SIGN_TRANSACTION 2 - -#define CHECK_ADDRESS 3 - -#define GET_PRINTABLE_AMOUNT 4 - -/* - * Amounts are stored as bytes, with a max size of 16 (see protobuf - * specifications). Max 16B integer is 340282366920938463463374607431768211455 - * in decimal, which is a 32-long char string. - * The printable amount also contains spaces, the ticker symbol (with variable - * size, up to 12 in Ethereum for instance) and a terminating null byte, so 50 - * bytes total should be a fair maximum. - */ -#define MAX_PRINTABLE_AMOUNT_SIZE 50 - -// structure that should be send to specific coin application to get address -typedef struct check_address_parameters_s { - // IN - uint8_t *coin_configuration; - uint8_t coin_configuration_length; - // serialized path, segwit, version prefix, hash used, dictionary etc. - // fields and serialization format depends on specific coin app - uint8_t *address_parameters; - uint8_t address_parameters_length; - char *address_to_check; - char *extra_id_to_check; - // OUT - int result; -} check_address_parameters_t; - -// structure that should be send to specific coin application to get printable amount -typedef struct get_printable_amount_parameters_s { - // IN - uint8_t *coin_configuration; - uint8_t coin_configuration_length; - uint8_t *amount; - uint8_t amount_length; - bool is_fee; - // OUT - char printable_amount[MAX_PRINTABLE_AMOUNT_SIZE]; -} get_printable_amount_parameters_t; - -typedef struct create_transaction_parameters_s { - // IN - uint8_t *coin_configuration; - uint8_t coin_configuration_length; - uint8_t *amount; - uint8_t amount_length; - uint8_t *fee_amount; - uint8_t fee_amount_length; - char *destination_address; - char *destination_address_extra_id; - // OUT - uint8_t result; -} create_transaction_parameters_t; - -typedef struct libargs_s { - unsigned int id; - unsigned int command; - btchip_altcoin_config_t *coin_config; - union { - check_address_parameters_t *check_address; - create_transaction_parameters_t *create_transaction; - get_printable_amount_parameters_t *get_printable_amount; - }; -} libargs_t; diff --git a/ledger_app.toml b/ledger_app.toml new file mode 100644 index 00000000..c264aa9d --- /dev/null +++ b/ledger_app.toml @@ -0,0 +1,7 @@ +[app] +build_directory = "./" +sdk = "C" +devices = ["nanos", "nanox", "nanos+", "stax"] + +[tests] +pytest_directory = "./tests/" diff --git a/lib-app-bitcoin b/lib-app-bitcoin new file mode 160000 index 00000000..824df017 --- /dev/null +++ b/lib-app-bitcoin @@ -0,0 +1 @@ +Subproject commit 824df01726df459b1fd527f96a8ddd4558017fea diff --git a/src/bip32_path.c b/src/bip32_path.c deleted file mode 100644 index a5cc8a5c..00000000 --- a/src/bip32_path.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "bip32_path.h" -#include "btchip_helpers.h" - -bool parse_serialized_path(bip32_path_t* path, unsigned char* serialized_path, unsigned char serialized_path_length) { - if (serialized_path_length < 1 || - serialized_path[0] > MAX_BIP32_PATH || - serialized_path[0] * 4 + 1 > serialized_path_length) - return false; - path->length = serialized_path[0]; - serialized_path++; - for (int i = 0; i < path->length; i += 1, serialized_path += 4) { - path->path[i] = btchip_read_u32(serialized_path, 1, 0); - } - return true; -} diff --git a/src/bip32_path.h b/src/bip32_path.h deleted file mode 100644 index 819ea8c9..00000000 --- a/src/bip32_path.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _BIP32_PATH_H_ -#define _BIP32_PATH_H_ - -#include "stdbool.h" - -#define MAX_BIP32_PATH 10 -#define MAX_BIP32_PATH_LENGTH (4 * MAX_BIP32_PATH) + 1 - -typedef struct bip32_path { - unsigned char length; - unsigned int path[MAX_BIP32_PATH]; -} bip32_path_t; - -bool parse_serialized_path(bip32_path_t* path, unsigned char* serialized_path, unsigned char serialized_path_length); - -#endif \ No newline at end of file diff --git a/src/btchip.c b/src/btchip.c deleted file mode 100644 index 7e7ef173..00000000 --- a/src/btchip.c +++ /dev/null @@ -1,186 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "os.h" - -#include "btchip_internal.h" - -#include "os_io_seproxyhal.h" - -#include "btchip_apdu_constants.h" -#include "btchip_display_variables.h" - -#include "handle_swap_sign_transaction.h" - -#define BTCHIP_TECHNICAL_NOT_IMPLEMENTED 0x99 - -#define COMMON_CLA 0xB0 -#define COMMON_INS_GET_WALLET_ID 0x04 - -#ifndef HAVE_WALLET_ID_SDK - -unsigned int const U_os_perso_seed_cookie[] = { - 0xda7aba5e, - 0xc1a551c5, -}; - -void handleGetWalletId(volatile unsigned short *tx) { - unsigned char t[64]; - cx_ecfp_256_private_key_t priv; - cx_ecfp_256_public_key_t pub; - // seed => priv key - os_perso_derive_node_bip32(CX_CURVE_256K1, U_os_perso_seed_cookie, 2, t, NULL); - // priv key => pubkey - cx_ecdsa_init_private_key(CX_CURVE_256K1, t, 32, &priv); - cx_ecfp_generate_pair(CX_CURVE_256K1, &pub, &priv, 1); - // pubkey -> sha512 - cx_hash_sha512(pub.W, sizeof(pub.W), t, sizeof(t)); - // ! cookie ! - os_memmove(G_io_apdu_buffer, t, 64); - btchip_context_D.sw = 0x9000; - *tx = 64; -} - -#endif // HAVE_WALLET_ID_SDK - -void app_dispatch(void) { - unsigned char cla; - unsigned char ins; - unsigned char dispatched; - - // nothing to reply for now - btchip_context_D.outLength = 0; - btchip_context_D.io_flags = 0; - - BEGIN_TRY { - TRY { - -#ifndef HAVE_WALLET_ID_SDK - - if ((G_io_apdu_buffer[ISO_OFFSET_CLA] == COMMON_CLA) && (G_io_apdu_buffer[ISO_OFFSET_INS] == COMMON_INS_GET_WALLET_ID)) { - handleGetWalletId(&btchip_context_D.outLength); - goto sendSW; - } - -#endif - - // If halted, then notify - SB_CHECK(btchip_context_D.halted); - if (SB_GET(btchip_context_D.halted)) { - btchip_context_D.sw = BTCHIP_SW_HALTED; - goto sendSW; - } - - cla = G_io_apdu_buffer[ISO_OFFSET_CLA]; - ins = G_io_apdu_buffer[ISO_OFFSET_INS]; - for (dispatched = 0; dispatched < DISPATCHER_APDUS; dispatched++) { - if ((cla == DISPATCHER_CLA[dispatched]) && - (ins == DISPATCHER_INS[dispatched])) { - break; - } - } - if (dispatched == DISPATCHER_APDUS) { - btchip_context_D.sw = BTCHIP_SW_INS_NOT_SUPPORTED; - goto sendSW; - } - if (DISPATCHER_DATA_IN[dispatched]) { - if (G_io_apdu_buffer[ISO_OFFSET_LC] == 0x00 || - btchip_context_D.inLength - 5 == 0) { - btchip_context_D.sw = BTCHIP_SW_INCORRECT_LENGTH; - goto sendSW; - } - // notify we need to receive data - // io_exchange(CHANNEL_APDU | IO_RECEIVE_DATA, 0); - } - // call the apdu handler - btchip_context_D.sw = ((apduProcessingFunction)PIC( - DISPATCHER_FUNCTIONS[dispatched]))(); - -// an APDU has been replied. request for power off time extension from the -// common ux -#ifdef IO_APP_ACTIVITY - IO_APP_ACTIVITY(); -#endif // IO_APP_ACTIVITY - - sendSW: - if (btchip_context_D.called_from_swap) { - btchip_context_D.io_flags &= ~IO_ASYNCH_REPLY; - if(btchip_context_D.sw != BTCHIP_SW_OK) { - vars.swap_data.should_exit = 1; - } - } - // prepare SW after replied data - G_io_apdu_buffer[btchip_context_D.outLength] = - (btchip_context_D.sw >> 8); - G_io_apdu_buffer[btchip_context_D.outLength + 1] = - (btchip_context_D.sw & 0xff); - btchip_context_D.outLength += 2; - } - CATCH(EXCEPTION_IO_RESET) { - THROW(EXCEPTION_IO_RESET); - } - CATCH_OTHER(e) { - // uncaught exception detected - G_io_apdu_buffer[0] = 0x6F; - btchip_context_D.outLength = 2; - G_io_apdu_buffer[1] = e; - // we caught something suspicious - SB_SET(btchip_context_D.halted, 1); - } - FINALLY; - } - END_TRY; -} - -void app_main(void) { - os_memset(G_io_apdu_buffer, 0, 255); // paranoia - - // Process the incoming APDUs - - // first exchange, no out length :) only wait the apdu - btchip_context_D.outLength = 0; - btchip_context_D.io_flags = 0; - for (;;) { - - // os_memset(G_io_apdu_buffer, 0, 255); // paranoia - - if (btchip_context_D.called_from_swap && vars.swap_data.should_exit) { - btchip_context_D.io_flags |= IO_RETURN_AFTER_TX; - } - - // receive the whole apdu using the 7 bytes headers (ledger transport) - btchip_context_D.inLength = - io_exchange(CHANNEL_APDU | btchip_context_D.io_flags, - // use the previous outlength as the reply - btchip_context_D.outLength); - - if (btchip_context_D.called_from_swap && vars.swap_data.should_exit) { - finalize_exchange_sign_transaction(btchip_context_D.sw == BTCHIP_SW_OK); - } - - PRINTF("New APDU received:\n%.*H\n", btchip_context_D.inLength, G_io_apdu_buffer); - - app_dispatch(); - - // reply during reception of next apdu - } - - PRINTF("End of main loop\n"); - - // in case reached - reset(); -} diff --git a/src/btchip_apdu_get_coin_version.c b/src/btchip_apdu_get_coin_version.c deleted file mode 100644 index 4da85742..00000000 --- a/src/btchip_apdu_get_coin_version.c +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" - -#define P1_VERSION_ONLY 0x00 -#define P1_VERSION_COINID 0x01 - -unsigned short btchip_apdu_get_coin_version() { - uint8_t offset = 0; - - SB_CHECK(N_btchip.bkp.config.operationMode); - if ((SB_GET(N_btchip.bkp.config.operationMode) == - BTCHIP_MODE_SETUP_NEEDED) || - (SB_GET(N_btchip.bkp.config.operationMode) == BTCHIP_MODE_ISSUER)) { - return BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - } - - G_io_apdu_buffer[offset++] = G_coin_config->p2pkh_version >> 8; - G_io_apdu_buffer[offset++] = G_coin_config->p2pkh_version; - G_io_apdu_buffer[offset++] = G_coin_config->p2sh_version >> 8; - G_io_apdu_buffer[offset++] = G_coin_config->p2sh_version; - G_io_apdu_buffer[offset++] = G_coin_config->family; - G_io_apdu_buffer[offset++] = strlen(G_coin_config->coinid); - os_memmove(G_io_apdu_buffer + offset, G_coin_config->coinid, - strlen(G_coin_config->coinid)); - offset += strlen(G_coin_config->coinid); - G_io_apdu_buffer[offset++] = strlen(G_coin_config->name_short); - os_memmove(G_io_apdu_buffer + offset, G_coin_config->name_short, - strlen(G_coin_config->name_short)); - offset += strlen(G_coin_config->name_short); - btchip_context_D.outLength = offset; - - return BTCHIP_SW_OK; -} diff --git a/src/btchip_apdu_get_firmware_version.c b/src/btchip_apdu_get_firmware_version.c deleted file mode 100644 index 6fc12aac..00000000 --- a/src/btchip_apdu_get_firmware_version.c +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" - -#define FEATURES_COMPRESSED_KEYS 0x01 -#define FEATURES_SELF_SCREEN_BUTTONS 0x02 -#define FEATURES_EXTERNAL_SCREEN_BUTTONS 0x04 -#define FEATURES_NFC 0x08 -#define FEATURES_BLE 0x10 -#define FEATURES_TEE 0x20 - -#define MODE_SETUP 0x01 -#define MODE_OPERATION 0x02 - -#define ARCH_ID 0x30 - -// Java Card is 0x60 - -void get_firmware_version(unsigned char *buffer) { - buffer[0] = ARCH_ID; - buffer[1] = LEDGER_MAJOR_VERSION; - buffer[2] = LEDGER_MINOR_VERSION; - buffer[3] = LEDGER_PATCH_VERSION; - buffer[4] = 1; - buffer[5] = TCS_LOADER_PATCH_VERSION; -} - -unsigned short btchip_apdu_get_firmware_version() { - G_io_apdu_buffer[0] = - (((N_btchip.bkp.config.options & BTCHIP_OPTION_UNCOMPRESSED_KEYS) != 0) - ? 0x00 - : 0x01); - - G_io_apdu_buffer[0] |= FEATURES_NFC; - G_io_apdu_buffer[0] |= FEATURES_BLE; - - G_io_apdu_buffer[0] |= FEATURES_SELF_SCREEN_BUTTONS; - - get_firmware_version(G_io_apdu_buffer + 1); - - G_io_apdu_buffer[7] = 0x00; - G_io_apdu_buffer[7] |= MODE_SETUP; - G_io_apdu_buffer[7] |= MODE_OPERATION; - - btchip_context_D.outLength = 0x08; - - return BTCHIP_SW_OK; -} diff --git a/src/btchip_apdu_get_operation_mode.c b/src/btchip_apdu_get_operation_mode.c deleted file mode 100644 index 6c35a100..00000000 --- a/src/btchip_apdu_get_operation_mode.c +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" - -#define P1_GET_OPERATION_MODE 0x00 -#define P1_GET_SECOND_FACTOR_MODE 0x01 - -unsigned short btchip_apdu_get_operation_mode() { - SB_CHECK(N_btchip.bkp.config.operationMode); - if ((SB_GET(N_btchip.bkp.config.operationMode) == - BTCHIP_MODE_SETUP_NEEDED) || - (SB_GET(N_btchip.bkp.config.operationMode) == BTCHIP_MODE_ISSUER)) { - return BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - } - - switch (G_io_apdu_buffer[ISO_OFFSET_P1]) { - case P1_GET_OPERATION_MODE: - G_io_apdu_buffer[0] = SB_GET(N_btchip.bkp.config.operationMode); - break; - - default: - return BTCHIP_SW_INCORRECT_P1_P2; - } - - btchip_context_D.outLength = 1; - - return BTCHIP_SW_OK; -} diff --git a/src/btchip_apdu_get_random.c b/src/btchip_apdu_get_random.c deleted file mode 100644 index 83a11433..00000000 --- a/src/btchip_apdu_get_random.c +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" - -#define MAX_LENGTH 248 - -unsigned short btchip_apdu_get_random() { - unsigned char length = G_io_apdu_buffer[ISO_OFFSET_LC]; - if (length == 0) { - length = MAX_LENGTH; - } - - if (length > MAX_LENGTH) { - return BTCHIP_SW_INCORRECT_LENGTH; - } - - cx_rng(G_io_apdu_buffer, length); - - btchip_context_D.outLength = length; - - return BTCHIP_SW_OK; -} diff --git a/src/btchip_apdu_get_trusted_input.c b/src/btchip_apdu_get_trusted_input.c deleted file mode 100644 index cc46f4be..00000000 --- a/src/btchip_apdu_get_trusted_input.c +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" - -#define GET_TRUSTED_INPUT_P1_FIRST 0x00 -#define GET_TRUSTED_INPUT_P1_NEXT 0x80 - -unsigned short btchip_apdu_get_trusted_input() { - unsigned char apduLength; - unsigned char dataOffset = 0; - apduLength = G_io_apdu_buffer[ISO_OFFSET_LC]; - - SB_CHECK(N_btchip.bkp.config.operationMode); - switch (SB_GET(N_btchip.bkp.config.operationMode)) { - case BTCHIP_MODE_WALLET: - case BTCHIP_MODE_RELAXED_WALLET: - case BTCHIP_MODE_SERVER: - break; - default: - return BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - } - - if (G_io_apdu_buffer[ISO_OFFSET_P1] == GET_TRUSTED_INPUT_P1_FIRST) { - // Initialize - btchip_context_D.transactionTargetInput = - btchip_read_u32(G_io_apdu_buffer + ISO_OFFSET_CDATA, 1, 0); - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - btchip_context_D.trustedInputProcessed = 0; - btchip_context_D.transactionContext.consumeP2SH = 0; - btchip_set_check_internal_structure_integrity(1); - dataOffset = 4; - btchip_context_D.transactionHashOption = TRANSACTION_HASH_FULL; - btchip_context_D.usingSegwit = 0; - btchip_context_D.usingOverwinter = 0; - } else if (G_io_apdu_buffer[ISO_OFFSET_P1] != GET_TRUSTED_INPUT_P1_NEXT) { - return BTCHIP_SW_INCORRECT_P1_P2; - } - - if (G_io_apdu_buffer[ISO_OFFSET_P2] != 0x00) { - return BTCHIP_SW_INCORRECT_P1_P2; - } - btchip_context_D.transactionBufferPointer = - G_io_apdu_buffer + ISO_OFFSET_CDATA + dataOffset; - btchip_context_D.transactionDataRemaining = apduLength - dataOffset; - - transaction_parse(PARSE_MODE_TRUSTED_INPUT); - - if (btchip_context_D.transactionContext.transactionState == - BTCHIP_TRANSACTION_PARSED) { - - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - btchip_set_check_internal_structure_integrity(1); - if (!btchip_context_D.trustedInputProcessed) { - // Output was not found - return BTCHIP_SW_INCORRECT_DATA; - } - - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, CX_LAST, - (unsigned char *)NULL, 0, G_io_apdu_buffer + TRUSTED_INPUT_SIZE, 32); - - // Otherwise prepare - cx_rng(G_io_apdu_buffer, 8); - G_io_apdu_buffer[0] = MAGIC_TRUSTED_INPUT; - G_io_apdu_buffer[1] = 0x00; - cx_hash_sha256(G_io_apdu_buffer + TRUSTED_INPUT_SIZE, 32, G_io_apdu_buffer + 4, 32); - - btchip_write_u32_le(G_io_apdu_buffer + 4 + 32, - btchip_context_D.transactionTargetInput); - os_memmove(G_io_apdu_buffer + 4 + 32 + 4, - btchip_context_D.transactionContext.transactionAmount, 8); - - cx_hmac_sha256((uint8_t *)N_btchip.bkp.trustedinput_key, - sizeof(N_btchip.bkp.trustedinput_key), G_io_apdu_buffer, - TRUSTED_INPUT_SIZE, G_io_apdu_buffer + TRUSTED_INPUT_SIZE, 32); - btchip_context_D.outLength = TRUSTED_INPUT_TOTAL_SIZE; - } - return BTCHIP_SW_OK; -} diff --git a/src/btchip_apdu_get_wallet_public_key.c b/src/btchip_apdu_get_wallet_public_key.c deleted file mode 100644 index 6ad50418..00000000 --- a/src/btchip_apdu_get_wallet_public_key.c +++ /dev/null @@ -1,226 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" - -#include "btchip_bagl_extensions.h" - -#include "segwit_addr.h" -#include "cashaddr.h" -#include "btchip_apdu_get_wallet_public_key.h" - -int get_public_key_chain_code(unsigned char* keyPath, bool uncompressedPublicKeys, unsigned char* publicKey, unsigned char* chainCode) { - cx_ecfp_private_key_t private_key; - cx_ecfp_public_key_t public_key; - int keyLength = 0; - btchip_private_derive_keypair(keyPath, 1, chainCode, &private_key, &public_key); - // Then encode it - if (uncompressedPublicKeys) { - keyLength = 65; - } else { - btchip_compress_public_key_value(public_key.W); - keyLength = 33; - } - - os_memmove(publicKey, public_key.W, - sizeof(public_key.W)); - return keyLength; -} - -unsigned short btchip_apdu_get_wallet_public_key() { - unsigned char keyLength; - unsigned char uncompressedPublicKeys = - ((N_btchip.bkp.config.options & BTCHIP_OPTION_UNCOMPRESSED_KEYS) != 0); - uint32_t request_token; - unsigned char chainCode[32]; - uint8_t is_derivation_path_unusual; - - bool display = (G_io_apdu_buffer[ISO_OFFSET_P1] == P1_DISPLAY); - bool display_request_token = N_btchip.pubKeyRequestRestriction && (G_io_apdu_buffer[ISO_OFFSET_P1] == P1_REQUEST_TOKEN) && G_io_apdu_media == IO_APDU_MEDIA_U2F; - bool require_user_approval = N_btchip.pubKeyRequestRestriction && !(display_request_token || display) && G_io_apdu_media == IO_APDU_MEDIA_U2F; - bool segwit = (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_SEGWIT); - bool nativeSegwit = (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NATIVE_SEGWIT); - bool cashAddr = (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_CASHADDR); - if (display && btchip_context_D.called_from_swap) { - return BTCHIP_SW_INCORRECT_DATA; - } - switch (G_io_apdu_buffer[ISO_OFFSET_P1]) { - case P1_NO_DISPLAY: - case P1_DISPLAY: - case P1_REQUEST_TOKEN: - break; - default: - return BTCHIP_SW_INCORRECT_P1_P2; - } - - switch (G_io_apdu_buffer[ISO_OFFSET_P2]) { - case P2_NATIVE_SEGWIT: - if (!(G_coin_config->native_segwit_prefix)) { - return BTCHIP_SW_INCORRECT_P1_P2; - } - case P2_LEGACY: - case P2_SEGWIT: - break; - case P2_CASHADDR: - if (G_coin_config->kind != COIN_KIND_BITCOIN_CASH) { - return BTCHIP_SW_INCORRECT_P1_P2; - } - break; - default: - return BTCHIP_SW_INCORRECT_P1_P2; - } - - if (G_io_apdu_buffer[ISO_OFFSET_LC] < 0x01) { - return BTCHIP_SW_INCORRECT_LENGTH; - } - if (display) { - is_derivation_path_unusual = set_key_path_to_display(G_io_apdu_buffer + ISO_OFFSET_CDATA); - } - - if(display_request_token){ - uint8_t request_token_offset = ISO_OFFSET_CDATA + G_io_apdu_buffer[ISO_OFFSET_CDATA]*4 + 1; - request_token = btchip_read_u32(G_io_apdu_buffer + request_token_offset, true, false); - } - - SB_CHECK(N_btchip.bkp.config.operationMode); - switch (SB_GET(N_btchip.bkp.config.operationMode)) { - case BTCHIP_MODE_WALLET: - case BTCHIP_MODE_RELAXED_WALLET: - case BTCHIP_MODE_SERVER: - break; - default: - return BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - } - - if (os_global_pin_is_validated() != BOLOS_UX_OK) { - return BTCHIP_SW_SECURITY_STATUS_NOT_SATISFIED; - } - - PRINTF("pin ok\n"); - - unsigned char bip44_enforced = enforce_bip44_coin_type(G_io_apdu_buffer + ISO_OFFSET_CDATA, true); - - G_io_apdu_buffer[0] = 65; - keyLength = get_public_key_chain_code(G_io_apdu_buffer + ISO_OFFSET_CDATA, uncompressedPublicKeys, G_io_apdu_buffer + 1, chainCode); - - if (cashAddr) { - uint8_t tmp[20]; - btchip_public_key_hash160(G_io_apdu_buffer + 1, // IN - keyLength, // INLEN - tmp); - keyLength = - cashaddr_encode(tmp, 20, G_io_apdu_buffer + 67, 50, CASHADDR_P2PKH); - } else if (!(segwit || nativeSegwit)) { - keyLength = btchip_public_key_to_encoded_base58( - G_io_apdu_buffer + 1, // IN - keyLength, // INLEN - G_io_apdu_buffer + 67, // OUT - 150, // MAXOUTLEN - G_coin_config->p2pkh_version, 0); - } else { - uint8_t tmp[22]; - tmp[0] = 0x00; - tmp[1] = 0x14; - btchip_public_key_hash160(G_io_apdu_buffer + 1, // IN - keyLength, // INLEN - tmp + 2 // OUT - ); - if (!nativeSegwit) { - keyLength = btchip_public_key_to_encoded_base58( - tmp, // IN - 22, // INLEN - G_io_apdu_buffer + 67, // OUT - 150, // MAXOUTLEN - G_coin_config->p2sh_version, 0); - } else { - if (G_coin_config->native_segwit_prefix) { - keyLength = segwit_addr_encode( - (char *)(G_io_apdu_buffer + 67), - (char *)PIC(G_coin_config->native_segwit_prefix), 0, tmp + 2, 20); - if (keyLength == 1) { - keyLength = strlen((char *)(G_io_apdu_buffer + 67)); - } - } - } - } - G_io_apdu_buffer[66] = keyLength; - PRINTF("Length %d\n", keyLength); - if (!uncompressedPublicKeys) { - // Restore for the full key component - G_io_apdu_buffer[1] = 0x04; - } - - // output chain code - os_memmove(G_io_apdu_buffer + 1 + 65 + 1 + keyLength, chainCode, - sizeof(chainCode)); - btchip_context_D.outLength = 1 + 65 + 1 + keyLength + sizeof(chainCode); - - // privacy : force display the address if the path isn't standard - // and could reveal another fork holdings according to BIP 44 rules - if (!display && !bip44_enforced) { - display = true; - } - - if (display) { - if (keyLength > 50) { - return BTCHIP_SW_INCORRECT_DATA; - } - // Hax, avoid wasting space - os_memmove(G_io_apdu_buffer + 200, G_io_apdu_buffer + 67, keyLength); - G_io_apdu_buffer[200 + keyLength] = '\0'; - btchip_context_D.io_flags |= IO_ASYNCH_REPLY; - btchip_bagl_display_public_key(is_derivation_path_unusual); - } - // If the token requested has already been approved in a previous call, the source is trusted so don't ask for approval again - else if(display_request_token && - (!btchip_context_D.has_valid_token || os_memcmp(&request_token, btchip_context_D.last_token, 4))) - { - // disable the has_valid_token flag and store the new token - btchip_context_D.has_valid_token = false; - os_memcpy(btchip_context_D.last_token, &request_token, 4); - // Hax, avoid wasting space - snprintf((char *)G_io_apdu_buffer + 200, 9, "%08X", request_token); - G_io_apdu_buffer[200 + 8] = '\0'; - btchip_context_D.io_flags |= IO_ASYNCH_REPLY; - btchip_bagl_display_token(); - } - else if(require_user_approval) - { - btchip_context_D.io_flags |= IO_ASYNCH_REPLY; - btchip_bagl_request_pubkey_approval(); - } - - return BTCHIP_SW_OK; -} - -void btchip_bagl_user_action_display(unsigned char confirming) { - unsigned short sw = BTCHIP_SW_OK; - // confirm and finish the apdu exchange //spaghetti - if (confirming) { - btchip_context_D.outLength -= - 2; // status was already set by the last call - - } else { - sw = BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - btchip_context_D.outLength = 0; - } - G_io_apdu_buffer[btchip_context_D.outLength++] = sw >> 8; - G_io_apdu_buffer[btchip_context_D.outLength++] = sw; - - io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, btchip_context_D.outLength); -} diff --git a/src/btchip_apdu_get_wallet_public_key.h b/src/btchip_apdu_get_wallet_public_key.h deleted file mode 100644 index c359dda3..00000000 --- a/src/btchip_apdu_get_wallet_public_key.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _BTCHIP_APDU_GET_WALLET_PUBLIC_KEY_H_ -#define _BTCHIP_APDU_GET_WALLET_PUBLIC_KEY_H_ - -#define P1_NO_DISPLAY 0x00 -#define P1_DISPLAY 0x01 -#define P1_REQUEST_TOKEN 0x02 - -#define P2_LEGACY 0x00 -#define P2_SEGWIT 0x01 -#define P2_NATIVE_SEGWIT 0x02 -#define P2_CASHADDR 0x03 - -#endif //_BTCHIP_APDU_GET_WALLET_PUBLIC_KEY_H_ \ No newline at end of file diff --git a/src/btchip_apdu_hash_input_finalize_full.c b/src/btchip_apdu_hash_input_finalize_full.c deleted file mode 100644 index dfb1cd9c..00000000 --- a/src/btchip_apdu_hash_input_finalize_full.c +++ /dev/null @@ -1,627 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -// TODO Trustlet, BAGL : process each output separately. -// review nvm_write policy - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" -#include "btchip_bagl_extensions.h" - -#define FINALIZE_P1_MORE 0x00 -#define FINALIZE_P1_LAST 0x80 -#define FINALIZE_P1_CHANGEINFO 0xFF - -#define FINALIZE_P2_DEFAULT 0x00 - -#define FLAG_SIGNATURE 0x01 -#define FLAG_CHANGE_VALIDATED 0x80 - -void btchip_apdu_hash_input_finalize_full_reset(void) { - btchip_context_D.currentOutputOffset = 0; - btchip_context_D.outputParsingState = BTCHIP_OUTPUT_PARSING_NUMBER_OUTPUTS; - os_memset(btchip_context_D.totalOutputAmount, 0, - sizeof(btchip_context_D.totalOutputAmount)); - btchip_context_D.changeOutputFound = 0; - btchip_set_check_internal_structure_integrity(1); -} - -static bool check_output_displayable() { - bool displayable = true; - unsigned char amount[8], isOpReturn, isP2sh, isNativeSegwit, j, - nullAmount = 1; - unsigned char isOpCreate, isOpCall; - - for (j = 0; j < 8; j++) { - if (btchip_context_D.currentOutput[j] != 0) { - nullAmount = 0; - break; - } - } - if (!nullAmount) { - btchip_swap_bytes(amount, btchip_context_D.currentOutput, 8); - transaction_amount_add_be(btchip_context_D.totalOutputAmount, - btchip_context_D.totalOutputAmount, amount); - } - isOpReturn = - btchip_output_script_is_op_return(btchip_context_D.currentOutput + 8); - isP2sh = btchip_output_script_is_p2sh(btchip_context_D.currentOutput + 8); - isNativeSegwit = btchip_output_script_is_native_witness( - btchip_context_D.currentOutput + 8); - isOpCreate = - btchip_output_script_is_op_create(btchip_context_D.currentOutput + 8, - sizeof(btchip_context_D.currentOutput) - 8); - isOpCall = - btchip_output_script_is_op_call(btchip_context_D.currentOutput + 8, - sizeof(btchip_context_D.currentOutput) - 8); - if (((G_coin_config->kind == COIN_KIND_QTUM || G_coin_config->kind == COIN_KIND_HYDRA) && - !btchip_output_script_is_regular(btchip_context_D.currentOutput + 8) && - !isP2sh && !(nullAmount && isOpReturn) && !isOpCreate && !isOpCall) || - (!(G_coin_config->kind == COIN_KIND_QTUM || G_coin_config->kind == COIN_KIND_HYDRA) && - !btchip_output_script_is_regular(btchip_context_D.currentOutput + 8) && - !isP2sh && !(nullAmount && isOpReturn))) { - PRINTF("Error : Unrecognized output script"); - THROW(EXCEPTION); - } - if (btchip_context_D.tmpCtx.output.changeInitialized && !isOpReturn) { - bool changeFound = false; - unsigned char addressOffset = - (isNativeSegwit ? OUTPUT_SCRIPT_NATIVE_WITNESS_PROGRAM_OFFSET - : isP2sh ? OUTPUT_SCRIPT_P2SH_PRE_LENGTH - : OUTPUT_SCRIPT_REGULAR_PRE_LENGTH); - if (!isP2sh && - os_memcmp(btchip_context_D.currentOutput + 8 + addressOffset, - btchip_context_D.tmpCtx.output.changeAddress, - 20) == 0) { - changeFound = true; - } else if (isP2sh && btchip_context_D.usingSegwit) { - unsigned char changeSegwit[22]; - changeSegwit[0] = 0x00; - changeSegwit[1] = 0x14; - os_memmove(changeSegwit + 2, - btchip_context_D.tmpCtx.output.changeAddress, 20); - btchip_public_key_hash160(changeSegwit, 22, changeSegwit); - if (os_memcmp(btchip_context_D.currentOutput + 8 + addressOffset, - changeSegwit, 20) == 0) { - if (G_coin_config->flags & FLAG_SEGWIT_CHANGE_SUPPORT) { - changeFound = true; - } else { - // Attempt to avoid fatal failures on Bitcoin Cash - PRINTF("Error : Non spendable Segwit change"); - THROW(EXCEPTION); - } - } - } - if (changeFound) { - if (btchip_context_D.changeOutputFound) { - PRINTF("Error : Multiple change output found"); - THROW(EXCEPTION); - } - btchip_context_D.changeOutputFound = true; - displayable = false; - } - } - - return displayable; -} - -bool handle_output_state() { - uint32_t discardSize = 0; - btchip_context_D.discardSize = 0; - bool processed = false; - switch (btchip_context_D.outputParsingState) { - case BTCHIP_OUTPUT_PARSING_NUMBER_OUTPUTS: { - btchip_context_D.totalOutputs = 0; - if (btchip_context_D.currentOutputOffset < 1) { - break; - } - if (btchip_context_D.currentOutput[0] < 0xFD) { - btchip_context_D.totalOutputs = btchip_context_D.remainingOutputs = - btchip_context_D.currentOutput[0]; - discardSize = 1; - btchip_context_D.outputParsingState = BTCHIP_OUTPUT_PARSING_OUTPUT; - processed = true; - break; - } - if (btchip_context_D.currentOutput[0] == 0xFD) { - if (btchip_context_D.currentOutputOffset < 3) { - break; - } - btchip_context_D.totalOutputs = btchip_context_D.remainingOutputs = - (btchip_context_D.currentOutput[2] << 8) | - btchip_context_D.currentOutput[1]; - discardSize = 3; - btchip_context_D.outputParsingState = BTCHIP_OUTPUT_PARSING_OUTPUT; - processed = true; - break; - } else if (btchip_context_D.currentOutput[0] == 0xFE) { - if (btchip_context_D.currentOutputOffset < 5) { - break; - } - btchip_context_D.totalOutputs = btchip_context_D.remainingOutputs = - btchip_read_u32(btchip_context_D.currentOutput + 1, 0, 0); - discardSize = 5; - btchip_context_D.outputParsingState = BTCHIP_OUTPUT_PARSING_OUTPUT; - processed = true; - break; - } else { - THROW(EXCEPTION); - } - } break; - - case BTCHIP_OUTPUT_PARSING_OUTPUT: { - unsigned int scriptSize; - if (btchip_context_D.currentOutputOffset < 9) { - break; - } - if (btchip_context_D.currentOutput[8] < 0xFD) { - scriptSize = btchip_context_D.currentOutput[8]; - discardSize = 1; - } else if (btchip_context_D.currentOutput[8] == 0xFD) { - if (btchip_context_D.currentOutputOffset < 9 + 2) { - break; - } - scriptSize = - btchip_read_u32(btchip_context_D.currentOutput + 9, 0, 0); - discardSize = 3; - } else { - // Unrealistically large script - THROW(EXCEPTION); - } - if (btchip_context_D.currentOutputOffset < - 8 + discardSize + scriptSize) { - discardSize = 0; - break; - } - - processed = true; - - discardSize += 8 + scriptSize; - - if (check_output_displayable()) { - btchip_context_D.io_flags |= IO_ASYNCH_REPLY; - - // The output can be processed by the UI - - btchip_context_D.discardSize = discardSize; - discardSize = 0; - } else { - btchip_context_D.remainingOutputs--; - } - } break; - - default: - THROW(EXCEPTION); - } - - if (discardSize != 0) { - os_memmove(btchip_context_D.currentOutput, - btchip_context_D.currentOutput + discardSize, - btchip_context_D.currentOutputOffset - discardSize); - btchip_context_D.currentOutputOffset -= discardSize; - } - - return processed; -} - -void get_public_key(unsigned char* keyPath, cx_ecfp_public_key_t* public_key) { - cx_ecfp_private_key_t private_key; - btchip_private_derive_keypair(keyPath, 1, NULL, &private_key, public_key); -} - -// out should be 32 bytes, even only 20 bytes is significant for output -void get_pubkey_hash160(unsigned char* keyPath, unsigned char* out) { - cx_ecfp_public_key_t public_key; - int keyLength; - get_public_key(keyPath, &public_key); - if (((N_btchip.bkp.config.options & - BTCHIP_OPTION_UNCOMPRESSED_KEYS) != 0)) { - keyLength = 65; - } else { - btchip_compress_public_key_value(public_key.W); - keyLength = 33; - } - btchip_public_key_hash160( - public_key.W, // IN - keyLength, // INLEN - out // OUT - ); -} - -unsigned short btchip_apdu_hash_input_finalize_full_internal( - btchip_transaction_summary_t *transactionSummary) { - unsigned char authorizationHash[32]; - unsigned char apduLength; - unsigned short sw = BTCHIP_SW_OK; - unsigned char *target = G_io_apdu_buffer; - unsigned char p1 = G_io_apdu_buffer[ISO_OFFSET_P1]; - unsigned char hashOffset = 0; - - apduLength = G_io_apdu_buffer[ISO_OFFSET_LC]; - - if ((p1 != FINALIZE_P1_MORE) && (p1 != FINALIZE_P1_LAST) && - (p1 != FINALIZE_P1_CHANGEINFO)) { - return BTCHIP_SW_INCORRECT_P1_P2; - } - - // See if there is a hashing offset - if (btchip_context_D.usingSegwit && - (btchip_context_D.tmpCtx.output.multipleOutput == 0)) { - unsigned char firstByte = G_io_apdu_buffer[ISO_OFFSET_CDATA]; - if (firstByte < 0xfd) { - hashOffset = 1; - } else if (firstByte == 0xfd) { - hashOffset = 3; - } else if (firstByte == 0xfe) { - hashOffset = 5; - } - } - - // Check state - BEGIN_TRY { - TRY { - btchip_set_check_internal_structure_integrity(0); - if (btchip_context_D.transactionContext.transactionState != - BTCHIP_TRANSACTION_PRESIGN_READY) { - sw = BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - goto discardTransaction; - } - - if (p1 == FINALIZE_P1_CHANGEINFO) { - if (!btchip_context_D.transactionContext.firstSigned) { - // Already validated, should be prevented on the client side - return_OK: - CLOSE_TRY; - return BTCHIP_SW_OK; - } - if (!btchip_context_D.tmpCtx.output.changeAccepted) { - sw = BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - goto discardTransaction; - } - os_memset(transactionSummary, 0, - sizeof(btchip_transaction_summary_t)); - if (G_io_apdu_buffer[ISO_OFFSET_CDATA] == 0x00) { - // Called with no change path, abort, should be prevented on - // the client side - goto return_OK; - } - os_memmove(transactionSummary->keyPath, - G_io_apdu_buffer + ISO_OFFSET_CDATA, - MAX_BIP32_PATH_LENGTH); - - get_pubkey_hash160(transactionSummary->keyPath, btchip_context_D.tmpCtx.output.changeAddress); - PRINTF("Change address = %.*H\n", 20, btchip_context_D.tmpCtx.output.changeAddress); - - btchip_context_D.tmpCtx.output.changeInitialized = 1; - btchip_context_D.tmpCtx.output.changeAccepted = 0; - - // if the bip44 change path provided is not canonical or its index are unsual, ask for user approval - if(bip44_derivation_guard(transactionSummary->keyPath, true)) { - if (btchip_context_D.called_from_swap) { - PRINTF("In swap mode only standart path is allowed\n"); - sw = BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - goto discardTransaction; - } - btchip_context_D.io_flags |= IO_ASYNCH_REPLY; - btchip_context_D.outputParsingState = BTCHIP_BIP44_CHANGE_PATH_VALIDATION; - btchip_bagl_request_change_path_approval(transactionSummary->keyPath); - } - - goto return_OK; - } - - // Always update the transaction & authorization hashes with the - // given data - // For SegWit, this has been reset to hold hashOutputs - if (!btchip_context_D.segwitParsedOnce) { - if ((int)(apduLength - hashOffset) < 0) { - sw = BTCHIP_SW_INCORRECT_DATA; - goto discardTransaction; - } - if (btchip_context_D.usingOverwinter) { - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, G_io_apdu_buffer + ISO_OFFSET_CDATA + hashOffset, apduLength - hashOffset, NULL, 0); - } - else { - PRINTF("--- ADD TO HASH FULL:\n%.*H\n", apduLength - hashOffset, G_io_apdu_buffer + ISO_OFFSET_CDATA + hashOffset); - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, 0, - G_io_apdu_buffer + ISO_OFFSET_CDATA + hashOffset, - apduLength - hashOffset, NULL, 0); - } - } - - if (btchip_context_D.transactionContext.firstSigned) { - if ((btchip_context_D.currentOutputOffset + apduLength) > - sizeof(btchip_context_D.currentOutput)) { - PRINTF("Output is too long to be checked\n"); - sw = BTCHIP_SW_INCORRECT_DATA; - goto discardTransaction; - } - os_memmove(btchip_context_D.currentOutput + - btchip_context_D.currentOutputOffset, - G_io_apdu_buffer + ISO_OFFSET_CDATA, apduLength); - btchip_context_D.currentOutputOffset += apduLength; - - while (handle_output_state() && - (!(btchip_context_D.io_flags & IO_ASYNCH_REPLY))) - ; - - // Finalize the TX if necessary - - if ((btchip_context_D.remainingOutputs == 0) && - (!(btchip_context_D.io_flags & IO_ASYNCH_REPLY))) { - btchip_context_D.io_flags |= IO_ASYNCH_REPLY; - btchip_context_D.outputParsingState = - BTCHIP_OUTPUT_FINALIZE_TX; - } - } - - if (G_io_apdu_buffer[ISO_OFFSET_P1] == FINALIZE_P1_MORE) { - if (!btchip_context_D.usingSegwit) { - PRINTF("--- ADD TO HASH AUTH:\n%.*H\n", apduLength, G_io_apdu_buffer + ISO_OFFSET_CDATA); - cx_hash( - &btchip_context_D.transactionHashAuthorization.header, - 0, G_io_apdu_buffer + ISO_OFFSET_CDATA, apduLength, - NULL, 0); - } - G_io_apdu_buffer[0] = 0x00; - btchip_context_D.outLength = 1; - btchip_context_D.tmpCtx.output.multipleOutput = 1; - goto return_OK; - } - - if (!btchip_context_D.usingSegwit) { - PRINTF("--- ADD TO HASH AUTH:\n%.*H\n", apduLength, G_io_apdu_buffer + ISO_OFFSET_CDATA); - cx_hash(&btchip_context_D.transactionHashAuthorization.header, - CX_LAST, G_io_apdu_buffer + ISO_OFFSET_CDATA, - apduLength, authorizationHash, 32); - } - - if (btchip_context_D.usingSegwit) { - if (!btchip_context_D.segwitParsedOnce) { - if (btchip_context_D.usingOverwinter) { - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, CX_LAST, btchip_context_D.segwit.cache.hashedOutputs, 0, btchip_context_D.segwit.cache.hashedOutputs, 32); - } - else { - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, - CX_LAST, - btchip_context_D.segwit.cache.hashedOutputs, 0, - btchip_context_D.segwit.cache.hashedOutputs, 32); - cx_sha256_init(&btchip_context_D.transactionHashFull.sha256); - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, - CX_LAST, - btchip_context_D.segwit.cache.hashedOutputs, - sizeof(btchip_context_D.segwit.cache.hashedOutputs), - btchip_context_D.segwit.cache.hashedOutputs, 32); - } - PRINTF("hashOutputs\n%.*H\n",32,btchip_context_D.segwit.cache.hashedOutputs); - cx_hash( - &btchip_context_D.transactionHashAuthorization.header, - CX_LAST, G_io_apdu_buffer, 0, authorizationHash, 32); - PRINTF("Auth Hash:\n%.*H\n", 32, authorizationHash); - } else { - cx_hash( - &btchip_context_D.transactionHashAuthorization.header, - CX_LAST, - (unsigned char *)&btchip_context_D.segwit.cache, - sizeof(btchip_context_D.segwit.cache), - authorizationHash, 32); - PRINTF("Auth Hash:\n%.*H\n", 32, authorizationHash); - } - } - - if (btchip_context_D.transactionContext.firstSigned) { - if (!btchip_context_D.tmpCtx.output.changeInitialized) { - os_memset(transactionSummary, 0, - sizeof(btchip_transaction_summary_t)); - } - - transactionSummary->payToAddressVersion = - G_coin_config->p2pkh_version; - transactionSummary->payToScriptHashVersion = - G_coin_config->p2sh_version; - - // Generate new nonce - - cx_rng(transactionSummary->transactionNonce, 8); - } - - G_io_apdu_buffer[0] = 0x00; - target++; - - *target = 0x00; - target++; - - btchip_context_D.outLength = (target - G_io_apdu_buffer); - - // Check that the input being signed is part of the same - // transaction, otherwise abort - // (this is done to keep the transaction counter limit per session - // synchronized) - if (btchip_context_D.transactionContext.firstSigned) { - os_memmove(transactionSummary->authorizationHash, - authorizationHash, - sizeof(transactionSummary->authorizationHash)); - goto return_OK; - } else { - if (btchip_secure_memcmp( - authorizationHash, - transactionSummary->authorizationHash, - sizeof(transactionSummary->authorizationHash))) { - PRINTF("Authorization hash not matching, aborting\n"); - sw = BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - discardTransaction: - CLOSE_TRY; - goto catch_discardTransaction; - } - } - - if (btchip_context_D.usingSegwit && - !btchip_context_D.segwitParsedOnce) { - // This input cannot be signed when using segwit - just restart. - btchip_context_D.segwitParsedOnce = 1; - PRINTF("Segwit parsed once\n"); - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - } else { - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_SIGN_READY; - } - sw = BTCHIP_SW_OK; - } - CATCH_ALL { - sw = SW_TECHNICAL_DETAILS(0x0F); - catch_discardTransaction: - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - btchip_context_D.outLength = 0; - - os_memmove(G_io_apdu_buffer, btchip_context_D.currentOutput, - btchip_context_D.currentOutputOffset); - btchip_context_D.outLength = btchip_context_D.currentOutputOffset; - } - FINALLY { - btchip_apdu_hash_input_finalize_full_reset(); - return sw; - } - } - END_TRY; -} - -unsigned short btchip_apdu_hash_input_finalize_full() { - PRINTF("state=%d\n", btchip_context_D.outputParsingState); - unsigned short sw = btchip_apdu_hash_input_finalize_full_internal( - &btchip_context_D.transactionSummary); - if (btchip_context_D.io_flags & IO_ASYNCH_REPLY) { - // if the UI reject the processing of the request, then reply - // immediately - bool status; - if(btchip_context_D.outputParsingState == BTCHIP_BIP44_CHANGE_PATH_VALIDATION) { - btchip_context_D.outputParsingState = BTCHIP_OUTPUT_PARSING_NUMBER_OUTPUTS; - return sw; - } - else if (btchip_context_D.outputParsingState == BTCHIP_OUTPUT_FINALIZE_TX) { - status = btchip_bagl_finalize_tx(); - } - else { - status = btchip_bagl_confirm_single_output(); - } - if (!status) { - btchip_context_D.io_flags &= ~IO_ASYNCH_REPLY; - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - btchip_context_D.outLength = 0; - sw = BTCHIP_SW_INCORRECT_DATA; - } - } - return sw; -} - -unsigned char btchip_bagl_user_action(unsigned char confirming) { - unsigned short sw = BTCHIP_SW_OK; - - // confirm and finish the apdu exchange //spaghetti - - if (confirming) { - // Check if all inputs have been confirmed - - if (btchip_context_D.outputParsingState == - BTCHIP_OUTPUT_PARSING_OUTPUT) { - btchip_context_D.remainingOutputs--; - } - - while (btchip_context_D.remainingOutputs != 0) { - os_memmove(btchip_context_D.currentOutput, - btchip_context_D.currentOutput + - btchip_context_D.discardSize, - btchip_context_D.currentOutputOffset - - btchip_context_D.discardSize); - btchip_context_D.currentOutputOffset -= - btchip_context_D.discardSize; - btchip_context_D.io_flags &= ~IO_ASYNCH_REPLY; - while (handle_output_state() && - (!(btchip_context_D.io_flags & IO_ASYNCH_REPLY))) - ; - if (btchip_context_D.io_flags & IO_ASYNCH_REPLY) { - if (!btchip_bagl_confirm_single_output()) { - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - sw = BTCHIP_SW_INCORRECT_DATA; - break; - } else { - // Let the UI play - return 1; - } - } else { - // Out of data to process, wait for the next call - break; - } - } - - if ((btchip_context_D.outputParsingState == - BTCHIP_OUTPUT_PARSING_OUTPUT) && - (btchip_context_D.remainingOutputs == 0)) { - btchip_context_D.outputParsingState = BTCHIP_OUTPUT_FINALIZE_TX; - if (!btchip_bagl_finalize_tx()) { - btchip_context_D.outputParsingState = - BTCHIP_OUTPUT_PARSING_NONE; - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - sw = BTCHIP_SW_INCORRECT_DATA; - } else { - // Let the UI play - return 1; - } - } - - if (btchip_context_D.outputParsingState == - BTCHIP_OUTPUT_FINALIZE_TX) { - btchip_context_D.transactionContext.firstSigned = 0; - - if (btchip_context_D.usingSegwit && - !btchip_context_D.segwitParsedOnce) { - // This input cannot be signed when using segwit - just restart. - btchip_context_D.segwitParsedOnce = 1; - PRINTF("Segwit parsed once\n"); - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - } else { - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_SIGN_READY; - } - } - btchip_context_D.outLength -= - 2; // status was already set by the last call - } else { - // Discard transaction - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - sw = BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - btchip_context_D.outLength = 0; - } - G_io_apdu_buffer[btchip_context_D.outLength++] = sw >> 8; - G_io_apdu_buffer[btchip_context_D.outLength++] = sw; - - if ((btchip_context_D.outputParsingState == BTCHIP_OUTPUT_FINALIZE_TX) || - (sw != BTCHIP_SW_OK)) { - // we've finished the processing of the input - btchip_apdu_hash_input_finalize_full_reset(); - } - - io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, btchip_context_D.outLength); - - return 0; -} diff --git a/src/btchip_apdu_hash_input_start.c b/src/btchip_apdu_hash_input_start.c deleted file mode 100644 index a2e7bfb9..00000000 --- a/src/btchip_apdu_hash_input_start.c +++ /dev/null @@ -1,151 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" -#include "btchip_bagl_extensions.h" - -#define P1_FIRST 0x00 -#define P1_NEXT 0x80 -#define P2_NEW 0x00 -#define P2_NEW_SEGWIT 0x02 -#define P2_NEW_SEGWIT_CASHADDR 0x03 -#define P2_NEW_SEGWIT_OVERWINTER 0x04 -#define P2_NEW_SEGWIT_SAPLING 0x05 -#define P2_CONTINUE 0x80 - -#define IS_INPUT() \ - (G_io_apdu_buffer[ISO_OFFSET_LC] - 1 > 8 \ - && G_io_apdu_buffer[ISO_OFFSET_LC] - 1 <= TRUSTED_INPUT_TOTAL_SIZE + 2 \ - && G_io_apdu_buffer[ISO_OFFSET_CDATA] <= 0x02) \ - -#define IS_INPUT_TRUSTED() \ - (G_io_apdu_buffer[ISO_OFFSET_CDATA] == 0x01 \ - && G_io_apdu_buffer[ISO_OFFSET_CDATA + 1] == TRUSTED_INPUT_TOTAL_SIZE \ - && G_io_apdu_buffer[ISO_OFFSET_CDATA + 2] == MAGIC_TRUSTED_INPUT \ - && G_io_apdu_buffer[ISO_OFFSET_CDATA + 3] == 0x00) - -unsigned short btchip_apdu_hash_input_start() { - unsigned char apduLength; - apduLength = G_io_apdu_buffer[ISO_OFFSET_LC]; - - SB_CHECK(N_btchip.bkp.config.operationMode); - switch (SB_GET(N_btchip.bkp.config.operationMode)) { - case BTCHIP_MODE_WALLET: - case BTCHIP_MODE_RELAXED_WALLET: - case BTCHIP_MODE_SERVER: - break; - default: - return BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - } - - if (G_io_apdu_buffer[ISO_OFFSET_P1] == P1_FIRST) { - // Initialize - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - btchip_set_check_internal_structure_integrity(1); - btchip_context_D.transactionHashOption = TRANSACTION_HASH_BOTH; - } else if (G_io_apdu_buffer[ISO_OFFSET_P1] != P1_NEXT) { - return BTCHIP_SW_INCORRECT_P1_P2; - } - - if ((G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NEW) || - (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NEW_SEGWIT) || - (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NEW_SEGWIT_CASHADDR) || - (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NEW_SEGWIT_OVERWINTER) || - (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NEW_SEGWIT_SAPLING)) { - // btchip_context_D.transactionContext.consumeP2SH = - // ((N_btchip.bkp.config.options & BTCHIP_OPTION_SKIP_2FA_P2SH) != 0); - if (G_io_apdu_buffer[ISO_OFFSET_P1] == P1_FIRST) { - unsigned char usingSegwit = - (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NEW_SEGWIT) || - (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NEW_SEGWIT_CASHADDR) || - (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NEW_SEGWIT_OVERWINTER) || - (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NEW_SEGWIT_SAPLING); - unsigned char usingCashAddr = - (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NEW_SEGWIT_CASHADDR); - // Request PIN validation - // Only request PIN validation (user presence) to start a new - // transaction signing flow. - // Thus allowing for numerous output to be processed in the - // background without - // requiring to disable autolock/autopoweroff - if (!btchip_context_D.transactionContext.firstSigned && - os_global_pin_is_validated() != BOLOS_UX_OK) { - return BTCHIP_SW_SECURITY_STATUS_NOT_SATISFIED; - } - // Master transaction reset - btchip_context_D.transactionContext.firstSigned = 1; - btchip_context_D.transactionContext.consumeP2SH = 0; - btchip_context_D.transactionContext.relaxed = 0; - btchip_context_D.usingSegwit = usingSegwit; - btchip_context_D.usingCashAddr = - (G_coin_config->kind == COIN_KIND_BITCOIN_CASH ? usingCashAddr - : 0); - btchip_context_D.usingOverwinter = 0; - if ((G_coin_config->kind == COIN_KIND_ZCASH) || (G_coin_config->kind == COIN_KIND_KOMODO) || (G_coin_config->kind == COIN_KIND_ZCLASSIC) || (G_coin_config->kind == COIN_KIND_RESISTANCE)) { - if (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NEW_SEGWIT_OVERWINTER) { - btchip_context_D.usingOverwinter = ZCASH_USING_OVERWINTER; - } - else - if (G_io_apdu_buffer[ISO_OFFSET_P2] == P2_NEW_SEGWIT_SAPLING) { - btchip_context_D.usingOverwinter = ZCASH_USING_OVERWINTER_SAPLING; - } - } - btchip_context_D.overwinterSignReady = 0; - btchip_context_D.segwitParsedOnce = 0; - btchip_set_check_internal_structure_integrity(1); - // Initialize for screen pairing - os_memset(&btchip_context_D.tmpCtx.output, 0, - sizeof(btchip_context_D.tmpCtx.output)); - btchip_context_D.tmpCtx.output.changeAccepted = 1; - // Reset segwitWarningSeen flag to prevent displaying the warning for each - // segwit input when coontinuing from a previous session (P2=0x80) - btchip_context_D.segwitWarningSeen = 0; - } - } else if (G_io_apdu_buffer[ISO_OFFSET_P2] != P2_CONTINUE) { - return BTCHIP_SW_INCORRECT_P1_P2; - } - - // In segwit mode, warn user one time only to update its client wallet... - if (btchip_context_D.usingSegwit - && !btchip_context_D.segwitWarningSeen - &&(G_io_apdu_buffer[ISO_OFFSET_P1] == P1_NEXT) - && (G_io_apdu_buffer[ISO_OFFSET_P2] != P2_CONTINUE) - // ...if input is not passed as a TrustedInput - && IS_INPUT() - && !IS_INPUT_TRUSTED()) - { - if(btchip_context_D.called_from_swap){ - /* There is no point in displaying a warning when the app is signing - in silent mode, as its UI is hidden behind the exchange app*/ - return BTCHIP_SW_SWAP_WITHOUT_TRUSTED_INPUTS; - } - btchip_context_D.segwitWarningSeen = 1; - btchip_context_D.io_flags |= IO_ASYNCH_REPLY; - btchip_bagl_request_segwit_input_approval(); - } - - // Start parsing of the 1st chunk - btchip_context_D.transactionBufferPointer = - G_io_apdu_buffer + ISO_OFFSET_CDATA; - btchip_context_D.transactionDataRemaining = apduLength; - - transaction_parse(PARSE_MODE_SIGNATURE); - - return BTCHIP_SW_OK; -} diff --git a/src/btchip_apdu_hash_sign.c b/src/btchip_apdu_hash_sign.c deleted file mode 100644 index a9c86d03..00000000 --- a/src/btchip_apdu_hash_sign.c +++ /dev/null @@ -1,217 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" -#include "btchip_bagl_extensions.h" -#include "btchip_display_variables.h" - -#define SIGHASH_ALL 0x01 - -unsigned short btchip_apdu_hash_sign() { - unsigned long int lockTime; - uint32_t sighashType; - unsigned char dataBuffer[8]; - unsigned char authorizationLength; - unsigned char *parameters = G_io_apdu_buffer + ISO_OFFSET_CDATA; - unsigned short sw; - - SB_CHECK(N_btchip.bkp.config.operationMode); - switch (SB_GET(N_btchip.bkp.config.operationMode)) { - case BTCHIP_MODE_WALLET: - case BTCHIP_MODE_RELAXED_WALLET: - case BTCHIP_MODE_SERVER: - break; - default: - return BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - } - - if ((G_io_apdu_buffer[ISO_OFFSET_P1] != 0) || - (G_io_apdu_buffer[ISO_OFFSET_P2] != 0)) { - return BTCHIP_SW_INCORRECT_P1_P2; - } - - if (G_io_apdu_buffer[ISO_OFFSET_LC] < (1 + 1 + 4 + 1)) { - return BTCHIP_SW_INCORRECT_LENGTH; - } - - // Check state - BEGIN_TRY { - TRY { - btchip_set_check_internal_structure_integrity(0); - - // Zcash special - store parameters for later - - if ((btchip_context_D.usingOverwinter) && - (!btchip_context_D.overwinterSignReady) && - (btchip_context_D.segwitParsedOnce) && - (btchip_context_D.transactionContext.transactionState == BTCHIP_TRANSACTION_NONE)) { - unsigned long int expiryHeight; - parameters += (4 * G_io_apdu_buffer[ISO_OFFSET_CDATA]) + 1; - authorizationLength = *(parameters++); - parameters += authorizationLength; - lockTime = btchip_read_u32(parameters, 1, 0); - parameters += 4; - sighashType = *(parameters++); - expiryHeight = btchip_read_u32(parameters, 1, 0); - btchip_write_u32_le(btchip_context_D.nLockTime, lockTime); - btchip_write_u32_le(btchip_context_D.sigHashType, sighashType); - btchip_write_u32_le(btchip_context_D.nExpiryHeight, expiryHeight); - btchip_context_D.overwinterSignReady = 1; - CLOSE_TRY; - return BTCHIP_SW_OK; - } - - if (btchip_context_D.transactionContext.transactionState != - BTCHIP_TRANSACTION_SIGN_READY) { - PRINTF("Invalid transaction state %d\n", btchip_context_D.transactionContext.transactionState); - sw = BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - goto discardTransaction; - } - - if (btchip_context_D.usingOverwinter && !btchip_context_D.overwinterSignReady) { - PRINTF("Overwinter not ready to sign\n"); - sw = BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - goto discardTransaction; - } - - // Read parameters - if (G_io_apdu_buffer[ISO_OFFSET_CDATA] > MAX_BIP32_PATH) { - sw = BTCHIP_SW_INCORRECT_DATA; - discardTransaction: - CLOSE_TRY; - goto catch_discardTransaction; - } - os_memmove(btchip_context_D.transactionSummary.keyPath, - G_io_apdu_buffer + ISO_OFFSET_CDATA, - MAX_BIP32_PATH_LENGTH); - parameters += (4 * G_io_apdu_buffer[ISO_OFFSET_CDATA]) + 1; - authorizationLength = *(parameters++); - parameters += authorizationLength; - lockTime = btchip_read_u32(parameters, 1, 0); - parameters += 4; - sighashType = *(parameters++); - btchip_context_D.transactionSummary.sighashType = sighashType; - - if (((N_btchip.bkp.config.options & - BTCHIP_OPTION_FREE_SIGHASHTYPE) == 0)) { - // if bitcoin cash OR forkid is set, then use the fork id - if (G_coin_config->kind == COIN_KIND_BITCOIN_CASH || - (G_coin_config->forkid)) { -#define SIGHASH_FORKID 0x40 - if (sighashType != (SIGHASH_ALL | SIGHASH_FORKID)) { - sw = BTCHIP_SW_INCORRECT_DATA; - goto discardTransaction; - } - sighashType |= (G_coin_config->forkid << 8); - } else { - if (sighashType != SIGHASH_ALL) { - sw = BTCHIP_SW_INCORRECT_DATA; - goto discardTransaction; - } - } - } - - // Finalize the hash - if (!btchip_context_D.usingOverwinter) { - btchip_write_u32_le(dataBuffer, lockTime); - btchip_write_u32_le(dataBuffer + 4, sighashType); - PRINTF("--- ADD TO HASH FULL:\n%.*H\n", sizeof(dataBuffer), dataBuffer); - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, 0, - dataBuffer, sizeof(dataBuffer), NULL, 0); - } - - // Check if the path needs to be enforced - if (!enforce_bip44_coin_type(btchip_context_D.transactionSummary.keyPath, false)) { - btchip_context_D.io_flags |= IO_ASYNCH_REPLY; - btchip_bagl_request_sign_path_approval(btchip_context_D.transactionSummary.keyPath); - } - else { - // Sign immediately - btchip_bagl_user_action_signtx(1, 1); - } - sw = BTCHIP_SW_OK; - if (btchip_context_D.called_from_swap) { - // if we signed all outputs we should exit, - // but only after sending response, so lets raise the - // vars.swap_data.should_exit flag and check it on timer later - vars.swap_data.alreadySignedInputs++; - if (vars.swap_data.alreadySignedInputs >= vars.swap_data.totalNumberOfInputs) { - vars.swap_data.should_exit = 1; - } - } - - // Then discard the transaction and reply - } - CATCH_ALL { - sw = SW_TECHNICAL_DETAILS(0xF); - catch_discardTransaction: - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - } - FINALLY { - btchip_set_check_internal_structure_integrity(1); - return sw; - } - } - END_TRY; -} - -void btchip_bagl_user_action_signtx(unsigned char confirming, unsigned char direct) { - cx_ecfp_private_key_t private_key; - unsigned short sw = BTCHIP_SW_OK; - // confirm and finish the apdu exchange //spaghetti - if (confirming) { - unsigned char hash[32]; - // Fetch the private key - btchip_private_derive_keypair(btchip_context_D.transactionSummary.keyPath, 0, NULL, &private_key, NULL); - if (btchip_context_D.usingOverwinter) { - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, CX_LAST, hash, 0, hash, 32); - } - else { - cx_sha256_t localHash; - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, CX_LAST, - hash, 0, hash, 32); - PRINTF("Hash1\n%.*H\n", sizeof(hash), hash); - - // Rehash - cx_sha256_init(&localHash); - cx_hash(&localHash.header, CX_LAST, hash, sizeof(hash), hash, 32); - } - PRINTF("Hash2\n%.*H\n", sizeof(hash), hash); - // Sign - btchip_sign_finalhash( - &private_key, hash, sizeof(hash), - G_io_apdu_buffer, sizeof(G_io_apdu_buffer), - ((N_btchip.bkp.config.options & - BTCHIP_OPTION_DETERMINISTIC_SIGNATURE) != 0)); - - btchip_context_D.outLength = G_io_apdu_buffer[1] + 2; - G_io_apdu_buffer[btchip_context_D.outLength++] = btchip_context_D.transactionSummary.sighashType; - } else { - sw = BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - btchip_context_D.outLength = 0; - } - - if (!direct) { - G_io_apdu_buffer[btchip_context_D.outLength++] = sw >> 8; - G_io_apdu_buffer[btchip_context_D.outLength++] = sw; - - io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, btchip_context_D.outLength); - } -} - diff --git a/src/btchip_apdu_set_operation_mode.c b/src/btchip_apdu_set_operation_mode.c deleted file mode 100644 index f5689774..00000000 --- a/src/btchip_apdu_set_operation_mode.c +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -// TODO BAGL : validate operation mode change - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" - -#define P1_DISABLE_KEYCARD 0x00 -#define P1_ENABLE_KEYCARD 0x01 -#define P1_ENABLE_KEYCARD_PERMANENTLY 0x02 - -unsigned short btchip_apdu_set_operation_mode() { - unsigned char operationMode; - - if (G_io_apdu_buffer[ISO_OFFSET_LC] != 0x01) { - return BTCHIP_SW_INCORRECT_LENGTH; - } - - SB_CHECK(N_btchip.bkp.config.operationMode); - if ((SB_GET(N_btchip.bkp.config.operationMode) == - BTCHIP_MODE_SETUP_NEEDED) || - (SB_GET(N_btchip.bkp.config.operationMode) == BTCHIP_MODE_ISSUER)) { - return BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - } - - if (os_global_pin_is_validated() != BOLOS_UX_OK) { - return BTCHIP_SW_SECURITY_STATUS_NOT_SATISFIED; - } - operationMode = G_io_apdu_buffer[ISO_OFFSET_CDATA]; - - if (operationMode == BTCHIP_MODE_WALLET) { - } - - if (operationMode == SB_GET(N_btchip.bkp.config.operationMode)) { - return BTCHIP_SW_OK; - } - - switch (operationMode) { - case BTCHIP_MODE_WALLET: - case BTCHIP_MODE_RELAXED_WALLET: - case BTCHIP_MODE_SERVER: - case BTCHIP_MODE_DEVELOPER: - break; - default: - return BTCHIP_SW_INCORRECT_DATA; - } - - SB_CHECK(N_btchip.bkp.config.supportedModes); - if ((SB_GET(N_btchip.bkp.config.supportedModes) & operationMode) == 0) { - return BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - } - - // commit new operation - btchip_set_operation_mode(operationMode); - - return BTCHIP_SW_OK; -} diff --git a/src/btchip_apdu_setup.c b/src/btchip_apdu_setup.c deleted file mode 100644 index 8d51e933..00000000 --- a/src/btchip_apdu_setup.c +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" - -unsigned short btchip_apdu_setup() { - return BTCHIP_SW_INS_NOT_SUPPORTED; -} - -// Setup with WALLET mode only, deterministic signatures only -void btchip_autosetup() { - btchip_config_t config; - unsigned char i; - unsigned char tmp[32]; - os_memset(&config, 0, sizeof(btchip_config_t)); - config.options |= BTCHIP_OPTION_DETERMINISTIC_SIGNATURE; - config.options |= BTCHIP_OPTION_SKIP_2FA_P2SH; // TODO : remove when - // supporting multi output - SB_SET(config.supportedModes, BTCHIP_MODE_WALLET); - SB_SET(config.operationMode, BTCHIP_MODE_WALLET); - - nvm_write((void *)&N_btchip.bkp.config, &config, sizeof(config)); - cx_rng(tmp, sizeof(tmp)); - nvm_write((void *)&N_btchip.bkp.trustedinput_key, tmp, sizeof(tmp)); - i = 1; - nvm_write((void *)&N_btchip.config_valid, &i, 1); -} diff --git a/src/btchip_apdu_sign_message.c b/src/btchip_apdu_sign_message.c deleted file mode 100644 index 2c28376a..00000000 --- a/src/btchip_apdu_sign_message.c +++ /dev/null @@ -1,287 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" -#include "btchip_bagl_extensions.h" - -#define P1_PREPARE 0x00 -#define P1_SIGN 0x80 -#define P2_LEGACY 0x00 -#define P2_FIRST 0x01 -#define P2_OTHER 0x80 - -#define BITID_NONE 0 -#define BITID_POWERCYCLE 1 -#define BITID_MULTIPLE 2 - -//#define SLIP_13 0x8000000D - -unsigned short btchip_compute_hash(void); - -unsigned char checkBitId(unsigned char *bip32Path) { - unsigned char i; - unsigned char bip32PathLength = bip32Path[0]; - bip32Path++; - /* - if ((bip32PathLength != 0) && (btchip_read_u32(bip32Path, 1, 0) == SLIP_13)) - { - return BITID_MULTIPLE; - } - */ - for (i = 0; i < bip32PathLength; i++) { - unsigned short account = btchip_read_u32(bip32Path, 1, 0); - bip32Path += 4; - - if (account == BITID_DERIVE) { - return BITID_POWERCYCLE; - } - if (account == BITID_DERIVE_MULTIPLE) { - return BITID_MULTIPLE; - } - } - return BITID_NONE; -} - -// TODO : support longer messages - -unsigned short btchip_apdu_sign_message_internal() { - unsigned short sw = BTCHIP_SW_OK; - unsigned char p1 = G_io_apdu_buffer[ISO_OFFSET_P1]; - unsigned char p2 = G_io_apdu_buffer[ISO_OFFSET_P2]; - unsigned char apduLength = G_io_apdu_buffer[ISO_OFFSET_LC]; - unsigned short offset = ISO_OFFSET_CDATA; - - if ((p1 != P1_PREPARE) && (p1 != P1_SIGN)) { - return BTCHIP_SW_INCORRECT_P1_P2; - } - if (p1 == P1_PREPARE) { - if ((p2 != P2_FIRST) && (p2 != P2_OTHER) && (p2 != P2_LEGACY)) { - return BTCHIP_SW_INCORRECT_P1_P2; - } - } - - if (os_global_pin_is_validated() != BOLOS_UX_OK) { - return BTCHIP_SW_SECURITY_STATUS_NOT_SATISFIED; - } - - BEGIN_TRY { - TRY { - if (p1 == P1_PREPARE) { - if ((p2 == P2_FIRST) || (p2 == P2_LEGACY)) { - unsigned char chunkLength; - unsigned char messageLength[3]; - unsigned char messageLengthSize; - os_memset(&btchip_context_D.transactionSummary, 0, - sizeof(btchip_transaction_summary_t)); - if (G_io_apdu_buffer[offset] > MAX_BIP32_PATH) { - PRINTF("Invalid path\n"); - sw = BTCHIP_SW_INCORRECT_DATA; - CLOSE_TRY; - goto discard; - } - btchip_context_D.transactionSummary.payToAddressVersion = - G_coin_config->p2pkh_version; - btchip_context_D.transactionSummary.payToScriptHashVersion = - G_coin_config->p2sh_version; - os_memmove( - btchip_context_D.transactionSummary.keyPath, - G_io_apdu_buffer + offset, MAX_BIP32_PATH_LENGTH); - offset += (4 * G_io_apdu_buffer[offset]) + 1; - if (p2 == P2_LEGACY) { - btchip_context_D.transactionSummary.messageLength = - G_io_apdu_buffer[offset]; - offset++; - } else { - btchip_context_D.transactionSummary.messageLength = - (G_io_apdu_buffer[offset] << 8) | - (G_io_apdu_buffer[offset + 1]); - offset += 2; - } - if (btchip_context_D.transactionSummary.messageLength == - 0) { - PRINTF("Null message length\n"); - sw = BTCHIP_SW_INCORRECT_DATA; - CLOSE_TRY; - goto discard; - } - btchip_context_D.hashedMessageLength = 0; - cx_sha256_init(&btchip_context_D.transactionHashFull.sha256); - cx_sha256_init( - &btchip_context_D.transactionHashAuthorization); - chunkLength = - strlen(G_coin_config->coinid) + SIGNMAGIC_LENGTH; - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, 0, - &chunkLength, 1, NULL, 0); - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, 0, - (uint8_t *)G_coin_config->coinid, - strlen(G_coin_config->coinid), NULL, 0); - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, 0, - (unsigned char *)SIGNMAGIC, SIGNMAGIC_LENGTH, NULL, 0); - if (btchip_context_D.transactionSummary.messageLength < - 0xfd) { - messageLength[0] = - btchip_context_D.transactionSummary.messageLength; - messageLengthSize = 1; - } else { - messageLength[0] = 0xfd; - messageLength[1] = - (btchip_context_D.transactionSummary.messageLength & - 0xff); - messageLength[2] = ((btchip_context_D.transactionSummary - .messageLength >> - 8) & - 0xff); - messageLengthSize = 3; - } - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, 0, - messageLength, messageLengthSize, NULL, 0); - chunkLength = apduLength - (offset - ISO_OFFSET_CDATA); - if ((btchip_context_D.hashedMessageLength + chunkLength) > - btchip_context_D.transactionSummary.messageLength) { - PRINTF("Invalid data length\n"); - sw = BTCHIP_SW_INCORRECT_DATA; - CLOSE_TRY; - goto discard; - } - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, 0, - G_io_apdu_buffer + offset, chunkLength, NULL, 0); - cx_hash( - &btchip_context_D.transactionHashAuthorization.header, - 0, G_io_apdu_buffer + offset, chunkLength, NULL, 0); - btchip_context_D.hashedMessageLength += chunkLength; - G_io_apdu_buffer[0] = 0x00; - if (btchip_context_D.hashedMessageLength == - btchip_context_D.transactionSummary.messageLength) { - G_io_apdu_buffer[1] = 0x00; - btchip_context_D.outLength = 2; - } else { - btchip_context_D.outLength = 1; - } - } else { - if ((btchip_context_D.hashedMessageLength + apduLength) > - btchip_context_D.transactionSummary.messageLength) { - PRINTF("Invalid data length\n"); - sw = BTCHIP_SW_INCORRECT_DATA; - CLOSE_TRY; - goto discard; - } - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, 0, - G_io_apdu_buffer + offset, apduLength, NULL, 0); - cx_hash( - &btchip_context_D.transactionHashAuthorization.header, - 0, G_io_apdu_buffer + offset, apduLength, NULL, 0); - btchip_context_D.hashedMessageLength += apduLength; - G_io_apdu_buffer[0] = 0x00; - if (btchip_context_D.hashedMessageLength == - btchip_context_D.transactionSummary.messageLength) { - G_io_apdu_buffer[1] = 0x00; - btchip_context_D.outLength = 2; - } else { - btchip_context_D.outLength = 1; - } - } - } else { - if ((btchip_context_D.transactionSummary.messageLength == 0) || - (btchip_context_D.hashedMessageLength != - btchip_context_D.transactionSummary.messageLength)) { - PRINTF("Invalid length to sign\n"); - sw = BTCHIP_SW_INCORRECT_DATA; - CLOSE_TRY; - goto discard; - } - if (checkBitId(btchip_context_D.transactionSummary.keyPath) != BITID_NONE) { - sw = btchip_compute_hash(); - } else { - btchip_context_D.io_flags |= IO_ASYNCH_REPLY; - CLOSE_TRY; - return BTCHIP_SW_OK; - } - } - } - CATCH_ALL { - sw = SW_TECHNICAL_DETAILS(0x0F); - } - discard : { - os_memset(&btchip_context_D.transactionSummary, 0, - sizeof(btchip_transaction_summary_t)); - } - FINALLY { - return sw; - } - } - END_TRY; -} - -unsigned short btchip_apdu_sign_message() { - if (btchip_context_D.called_from_swap) { - return BTCHIP_SW_SECURITY_STATUS_NOT_SATISFIED; - } - unsigned short sw = btchip_apdu_sign_message_internal(); - if (btchip_context_D.io_flags & IO_ASYNCH_REPLY) { - btchip_bagl_confirm_message_signature(); - } - return sw; -} - -unsigned short btchip_compute_hash() { - unsigned char hash[32]; - unsigned short sw = BTCHIP_SW_OK; - cx_ecfp_private_key_t private_key; - - btchip_context_D.outLength = 0; - BEGIN_TRY { - TRY { - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, CX_LAST, hash, - 0, hash, 32); - cx_sha256_init(&btchip_context_D.transactionHashFull.sha256); - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, CX_LAST, hash, - 32, hash, 32); - btchip_private_derive_keypair( - btchip_context_D.transactionSummary.keyPath, 0, - NULL, &private_key, NULL); - btchip_sign_finalhash( - &private_key, hash, sizeof(hash), // IN - G_io_apdu_buffer, 100, // OUT - ((N_btchip.bkp.config.options & - BTCHIP_OPTION_DETERMINISTIC_SIGNATURE) != 0)); - btchip_context_D.outLength = G_io_apdu_buffer[1] + 2; - } - CATCH_ALL { - sw = SW_TECHNICAL_DETAILS(0x0F); - } - FINALLY { - os_memset(&btchip_context_D.transactionSummary, 0, - sizeof(btchip_transaction_summary_t)); - } - } - END_TRY; - return sw; -} - -void btchip_bagl_user_action_message_signing(unsigned char confirming) { - unsigned short sw; - if (confirming) { - sw = btchip_compute_hash(); - } else { - sw = BTCHIP_SW_CONDITIONS_OF_USE_NOT_SATISFIED; - } - G_io_apdu_buffer[btchip_context_D.outLength++] = sw >> 8; - G_io_apdu_buffer[btchip_context_D.outLength++] = sw; - - io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, btchip_context_D.outLength); -} diff --git a/src/btchip_apdu_verify_pin.c b/src/btchip_apdu_verify_pin.c deleted file mode 100644 index 33a6c9d9..00000000 --- a/src/btchip_apdu_verify_pin.c +++ /dev/null @@ -1,23 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" - -unsigned short btchip_apdu_verify_pin() { - return BTCHIP_SW_INS_NOT_SUPPORTED; -} diff --git a/src/btchip_bagl_extensions.h b/src/btchip_bagl_extensions.h deleted file mode 100644 index 3e1c1ba7..00000000 --- a/src/btchip_bagl_extensions.h +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef _BTCHIP_BAGL_H_ -#define _BTCHIP_BAGL_H_ - -// btchip asking the per-output UI -unsigned int btchip_bagl_confirm_single_output(void); - -// btchip display token -void btchip_bagl_display_token(void); - -// btchip finalizing the transaction -unsigned int btchip_bagl_finalize_tx(void); - -// UI response to btchip to finish the exchange -unsigned char btchip_bagl_user_action(unsigned char confirming); - -// request the UI to redisplay the idle screen -void btchip_bagl_idle(void); - -// btchip asking message signing confirmation -void btchip_bagl_confirm_message_signature(void); - -// UI response to message signature -void btchip_bagl_user_action_message_signing(unsigned char confirming); - -// Public key display -uint8_t set_key_path_to_display(unsigned char* keyPath); -void btchip_bagl_display_public_key(uint8_t is_derivation_path_unusual); -void btchip_bagl_user_action_display(unsigned char confirming); - -void btchip_bagl_request_pubkey_approval(void); -void btchip_bagl_request_change_path_approval(unsigned char* change_path); - -// UI to confirm processing of tx with segwit inputs -void btchip_bagl_request_segwit_input_approval(void); - -// UI to confirm signing path -void btchip_bagl_request_sign_path_approval(unsigned char *derivation_path); -void btchip_bagl_user_action_signtx(unsigned char confirming, unsigned char direct); - - -#endif /* _BTCHIP_BAGL_H_ */ diff --git a/src/btchip_base58.c b/src/btchip_base58.c deleted file mode 100644 index 8f89417f..00000000 --- a/src/btchip_base58.c +++ /dev/null @@ -1,141 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" - -#define MAX_DEC_INPUT_SIZE 164 -#define MAX_ENC_INPUT_SIZE 120 - -int btchip_decode_base58(const char *in, size_t length, - unsigned char *out, size_t *outlen) { - unsigned char tmp[MAX_DEC_INPUT_SIZE]; - unsigned char buffer[MAX_DEC_INPUT_SIZE] = {0}; - unsigned char i; - unsigned char j; - unsigned char startAt; - unsigned char zeroCount = 0; - if ((length > MAX_DEC_INPUT_SIZE) || (length < 2)) { - return -1; - } - os_memmove(tmp, in, length); - PRINTF("To decode\n%.*H\n",length,tmp); - for (i = 0; i < length; i++) { - if (in[i] >= sizeof(BASE58TABLE)) { - return -1; - } - tmp[i] = BASE58TABLE[(int)in[i]]; - if (tmp[i] == 0xff) { - return -1; - } - } - while ((zeroCount < length) && (tmp[zeroCount] == 0)) { - ++zeroCount; - } - j = length; - startAt = zeroCount; - while (startAt < length) { - unsigned short remainder = 0; - unsigned char divLoop; - for (divLoop = startAt; divLoop < length; divLoop++) { - unsigned short digit256 = (unsigned short)(tmp[divLoop] & 0xff); - unsigned short tmpDiv = remainder * 58 + digit256; - tmp[divLoop] = (unsigned char)(tmpDiv / 256); - remainder = (tmpDiv % 256); - } - if (tmp[startAt] == 0) { - ++startAt; - } - buffer[--j] = (unsigned char)remainder; - } - while ((j < length) && (buffer[j] == 0)) { - ++j; - } - length = length - (j - zeroCount); - if (*outlen < length) { - PRINTF("Decode overflow %d %d\n", length, *outlen); - return -1; - } - - os_memmove(out, buffer + j - zeroCount, length); - PRINTF("Decoded\n%.*H\n",length,out); - *outlen = length; - return 0; -} - -int btchip_encode_base58(const unsigned char *in, size_t length, - unsigned char *out, size_t *outlen) { - size_t i = 0, j; - size_t startAt, stopAt; - size_t zeroCount = 0; - size_t outputSize; - - if (length > MAX_ENC_INPUT_SIZE) { - return -1; - } - - PRINTF("Length to encode %d\n", length); - PRINTF("To encode\n%.*H\n",length,in); - - while ((zeroCount < length) && (in[zeroCount] == 0)) { - ++zeroCount; - } - - outputSize = (length - zeroCount) * 138 / 100 + 1; - if (*outlen < outputSize) { - *outlen = outputSize; - return -1; - } - os_memset(out, 0, outputSize); - stopAt = outputSize - 1; - for (startAt = zeroCount; startAt < length; startAt++) { - int carry = in[startAt]; - for (j = outputSize - 1; (int)j >= 0; j--) { - carry += 256 * out[j]; - out[j] = carry % 58; - carry /= 58; - - if (j <= stopAt - 1 && carry == 0) { - break; - } - } - stopAt = j; - } - - j = 0; - while (j < outputSize && out[j] == 0) { - j += 1; - } - - if (*outlen < zeroCount + outputSize - j) { - *outlen = zeroCount + outputSize - j; - return -1; - } - *outlen = zeroCount + outputSize - j; - int distance = zeroCount - j; - if (distance < 0) { - for (i = zeroCount; i < *outlen; ++i) - out[i] = BASE58ALPHABET[out[i - distance]]; - } - else { - for (i = *outlen - 1; (int)i >= 0; --i) - out[i] = BASE58ALPHABET[out[i - distance]]; - } - os_memset(out, BASE58ALPHABET[0], zeroCount); - // PRINTF("Length encoded %d\n", i); - // PRINTF("Encoded\n%.*H\n",i,out); - return 0; -} diff --git a/src/btchip_bcd.c b/src/btchip_bcd.c deleted file mode 100644 index bbb4ff2e..00000000 --- a/src/btchip_bcd.c +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" - -#define SCRATCH_SIZE 21 - -unsigned char -btchip_convert_hex_amount_to_displayable_no_globals(unsigned char *amount, unsigned int config_flag, unsigned char* out) { - unsigned char LOOP1; - unsigned char LOOP2; - if (!(config_flag & FLAG_PEERCOIN_UNITS)) { - LOOP1 = 13; - LOOP2 = 8; - } else { - LOOP1 = 15; - LOOP2 = 6; - } - unsigned short scratch[SCRATCH_SIZE]; - unsigned char offset = 0; - unsigned char nonZero = 0; - unsigned char i; - unsigned char targetOffset = 0; - unsigned char workOffset; - unsigned char j; - unsigned char nscratch = SCRATCH_SIZE; - unsigned char smin = nscratch - 2; - unsigned char comma = 0; - - for (i = 0; i < SCRATCH_SIZE; i++) { - scratch[i] = 0; - } - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - unsigned char k; - unsigned short shifted_in = - (((amount[i] & 0xff) & ((1 << (7 - j)))) != 0) ? (short)1 - : (short)0; - for (k = smin; k < nscratch; k++) { - scratch[k] += ((scratch[k] >= 5) ? 3 : 0); - } - if (scratch[smin] >= 8) { - smin -= 1; - } - for (k = smin; k < nscratch - 1; k++) { - scratch[k] = - ((scratch[k] << 1) & 0xF) | ((scratch[k + 1] >= 8) ? 1 : 0); - } - scratch[nscratch - 1] = ((scratch[nscratch - 1] << 1) & 0x0F) | - (shifted_in == 1 ? 1 : 0); - } - } - - for (i = 0; i < LOOP1; i++) { - if (!nonZero && (scratch[offset] == 0)) { - offset++; - } else { - nonZero = 1; - out[targetOffset++] = scratch[offset++] + '0'; - } - } - if (targetOffset == 0) { - out[targetOffset++] = '0'; - } - workOffset = offset; - for (i = 0; i < LOOP2; i++) { - unsigned char allZero = 1; - unsigned char j; - for (j = i; j < LOOP2; j++) { - if (scratch[workOffset + j] != 0) { - allZero = 0; - break; - } - } - if (allZero) { - break; - } - if (!comma) { - out[targetOffset++] = '.'; - comma = 1; - } - out[targetOffset++] = scratch[offset++] + '0'; - } - return targetOffset; -} - -unsigned char -btchip_convert_hex_amount_to_displayable(unsigned char *amount) { - return btchip_convert_hex_amount_to_displayable_no_globals(amount, G_coin_config->flags, btchip_context_D.tmp); -} diff --git a/src/btchip_context.c b/src/btchip_context.c deleted file mode 100644 index fc782dfa..00000000 --- a/src/btchip_context.c +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" - -void btchip_autosetup(void); - -/** - * Initialize the application context on boot - */ -void btchip_context_init() { - PRINTF("Context init\n"); - PRINTF("Backup size %d\n", sizeof(N_btchip.bkp)); - os_memset(&btchip_context_D, 0, sizeof(btchip_context_D)); - SB_SET(btchip_context_D.halted, 0); - btchip_context_D.called_from_swap = 0; - btchip_context_D.currentOutputOffset = 0; - btchip_context_D.outputParsingState = BTCHIP_OUTPUT_PARSING_NUMBER_OUTPUTS; - os_memset(btchip_context_D.totalOutputAmount, 0, - sizeof(btchip_context_D.totalOutputAmount)); - btchip_context_D.changeOutputFound = 0; - btchip_context_D.segwitWarningSeen = 0; - - if (N_btchip.config_valid != 0x01) { - btchip_autosetup(); - } - - if (!N_btchip.config_valid) { - unsigned char defaultMode; - PRINTF("No configuration found\n"); - defaultMode = BTCHIP_MODE_SETUP_NEEDED; - - btchip_set_operation_mode(defaultMode); - } else { - SB_CHECK(N_btchip.bkp.config.operationMode); - } - if (!N_btchip.storageInitialized) { - unsigned char initialized = 1, denied=1; - - nvm_write((void *)&N_btchip.pubKeyRequestRestriction, &denied, 1); - nvm_write((void *)&N_btchip.storageInitialized, &initialized, 1); - } -} diff --git a/src/btchip_display_variables.c b/src/btchip_display_variables.c deleted file mode 100644 index 55305669..00000000 --- a/src/btchip_display_variables.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "btchip_display_variables.h" - -union display_variables vars; diff --git a/src/btchip_display_variables.h b/src/btchip_display_variables.h deleted file mode 100644 index f62263cb..00000000 --- a/src/btchip_display_variables.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _BTCHIP_DISPLAY_VARIABLES_H_ -#define _BTCHIP_DISPLAY_VARIABLES_H_ - -// A path contains 10 elements max, which max length in ascii is 1 whitespace + 10 char + optional quote "'" + "/" + \0" -#define MAX_DERIV_PATH_ASCII_LENGTH 1 + 10*(10+2) + 1 -#define MAX_CHAR_PER_LINE 25 - -typedef struct swap_data_s { - int was_address_checked; - // total number of inputs to be signed - int totalNumberOfInputs; - // number of already signed input in the transaction, to compare with - // totalNumberOfInputs and exit properly - int alreadySignedInputs; - unsigned char amount[8]; - unsigned char fees[8]; - char destination_address[65]; - unsigned char should_exit; -} swap_data_t; - -union display_variables { - struct { - // char addressSummary[40]; // beginning of the output address ... end - // of - - char fullAddress[65]; // the address - char fullAmount[20]; // full amount - char feesAmount[20]; // fees - } tmp; - - struct { - char derivation_path [MAX_DERIV_PATH_ASCII_LENGTH]; - } tmp_warning; - - swap_data_t swap_data; -}; - -extern union display_variables vars; - -#endif diff --git a/src/btchip_ecc.c b/src/btchip_ecc.c deleted file mode 100644 index 514fc0aa..00000000 --- a/src/btchip_ecc.c +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" - -void btchip_compress_public_key_value(unsigned char *value) { - value[0] = ((value[64] & 1) ? 0x03 : 0x02); -} diff --git a/src/btchip_filesystem.c b/src/btchip_filesystem.c deleted file mode 100644 index f0b81efc..00000000 --- a/src/btchip_filesystem.c +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" - -#include "btchip_public_ram_variables.h" - -void btchip_set_operation_mode(unsigned char operationMode) { - secu8 opMode; - SB_SET(opMode, operationMode); - - // only modify operation mode - nvm_write((void *)&N_btchip.bkp.config.operationMode, &opMode, - sizeof(opMode)); -} diff --git a/src/btchip_helpers.c b/src/btchip_helpers.c deleted file mode 100644 index a7131b0c..00000000 --- a/src/btchip_helpers.c +++ /dev/null @@ -1,498 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" - -const unsigned char TRANSACTION_OUTPUT_SCRIPT_PRE[] = { - 0x19, 0x76, 0xA9, - 0x14}; // script length, OP_DUP, OP_HASH160, address length -const unsigned char TRANSACTION_OUTPUT_SCRIPT_POST[] = { - 0x88, 0xAC}; // OP_EQUALVERIFY, OP_CHECKSIG - -const unsigned char TRANSACTION_OUTPUT_SCRIPT_P2SH_PRE[] = { - 0x17, 0xA9, 0x14}; // script length, OP_HASH160, address length -const unsigned char TRANSACTION_OUTPUT_SCRIPT_P2SH_POST[] = {0x87}; // OP_EQUAL - -const unsigned char ZEN_TRANSACTION_OUTPUT_SCRIPT_P2SH_PRE[] = { - 0x3D, 0xA9, - 0x14}; // script length, OP_HASH160, address length - -const unsigned char ZEN_TRANSACTION_OUTPUT_SCRIPT_P2SH_POST[] = { - 0x87, // OP_EQUAL - 0x20, 0x9E, 0xC9, 0x84, 0x5A, 0xCB, 0x02, 0xFA, 0XB2, 0X4E, - 0x1C, 0x03, 0x68, 0xB3, 0xB5, 0x17, 0xC1, 0xA4, 0x48, 0x8F, - 0xBA, 0x97, 0xF0, 0xE3, 0x45, 0x9A, 0xC0, 0x53, 0xEA, 0x01, - 0x00, 0x00, 0x00, // ParamHash - 0x03, // Push 3 bytes to stack to make ParamHeight line up properly - 0xC0, 0x1F, 0x02, // ParamHeight (139200) -> hex -> endianness swapped - 0xB4}; // OP_CHECKBLOCKATHEIGHT - -const unsigned char TRANSACTION_OUTPUT_SCRIPT_P2WPKH_PRE[] = {0x16, 0x00, 0x14}; -const unsigned char TRANSACTION_OUTPUT_SCRIPT_P2WSH_PRE[] = {0x22, 0x00, 0x20}; - -const unsigned char ZEN_OUTPUT_SCRIPT_PRE[] = { - 0x3F, 0x76, 0xA9, - 0x14}; // script length, OP_DUP, OP_HASH160, address length -const unsigned char ZEN_OUTPUT_SCRIPT_POST[] = { - 0x88, 0xAC, // OP_EQUALVERIFY, OP_CHECKSIG - 0x20, 0x9e, 0xc9, 0x84, 0x5a, 0xcb, 0x02, 0xfa, 0xb2, 0x4e, 0x1c, 0x03, - 0x68, 0xb3, 0xb5, 0x17, 0xc1, 0xa4, 0x48, 0x8f, 0xba, 0x97, 0xf0, 0xe3, - 0x45, 0x9a, 0xc0, 0x53, 0xea, 0x01, 0x00, 0x00, 0x00, // ParamHash - 0x03, // Push 3 bytes to stack to make ParamHeight line up properly - 0xc0, 0x1f, 0x02, // ParamHeight (139200) -> hex -> endianness swapped - 0xb4 // OP_CHECKBLOCKATHEIGHT -}; // BIP0115 Replay Protection - -unsigned char btchip_output_script_is_regular(unsigned char *buffer) { - if (G_coin_config->native_segwit_prefix) { - if ((os_memcmp(buffer, TRANSACTION_OUTPUT_SCRIPT_P2WPKH_PRE, - sizeof(TRANSACTION_OUTPUT_SCRIPT_P2WPKH_PRE)) == 0) || - (os_memcmp(buffer, TRANSACTION_OUTPUT_SCRIPT_P2WSH_PRE, - sizeof(TRANSACTION_OUTPUT_SCRIPT_P2WSH_PRE)) == 0)) { - return 1; - } - } - if (G_coin_config->kind == COIN_KIND_HORIZEN) { - if ((os_memcmp(buffer, ZEN_OUTPUT_SCRIPT_PRE, - sizeof(ZEN_OUTPUT_SCRIPT_PRE)) == 0) && - (os_memcmp(buffer + sizeof(ZEN_OUTPUT_SCRIPT_PRE) + 20, - ZEN_OUTPUT_SCRIPT_POST, - sizeof(ZEN_OUTPUT_SCRIPT_POST)) == 0)) { - return 1; - } - } else { - if ((os_memcmp(buffer, TRANSACTION_OUTPUT_SCRIPT_PRE, - sizeof(TRANSACTION_OUTPUT_SCRIPT_PRE)) == 0) && - (os_memcmp(buffer + sizeof(TRANSACTION_OUTPUT_SCRIPT_PRE) + 20, - TRANSACTION_OUTPUT_SCRIPT_POST, - sizeof(TRANSACTION_OUTPUT_SCRIPT_POST)) == 0)) { - return 1; - } - } - return 0; -} - -unsigned char btchip_output_script_is_p2sh(unsigned char *buffer) { - if (G_coin_config->kind == COIN_KIND_HORIZEN) { - if ((os_memcmp(buffer, ZEN_TRANSACTION_OUTPUT_SCRIPT_P2SH_PRE, - sizeof(ZEN_TRANSACTION_OUTPUT_SCRIPT_P2SH_PRE)) == 0) && - (os_memcmp(buffer + sizeof(ZEN_TRANSACTION_OUTPUT_SCRIPT_P2SH_PRE) + 20, - ZEN_TRANSACTION_OUTPUT_SCRIPT_P2SH_POST, - sizeof(ZEN_TRANSACTION_OUTPUT_SCRIPT_P2SH_POST)) == 0)) { - return 1; - } - } else { - if ((os_memcmp(buffer, TRANSACTION_OUTPUT_SCRIPT_P2SH_PRE, - sizeof(TRANSACTION_OUTPUT_SCRIPT_P2SH_PRE)) == 0) && - (os_memcmp(buffer + sizeof(TRANSACTION_OUTPUT_SCRIPT_P2SH_PRE) + 20, - TRANSACTION_OUTPUT_SCRIPT_P2SH_POST, - sizeof(TRANSACTION_OUTPUT_SCRIPT_P2SH_POST)) == 0)) { - return 1; - } - } - return 0; -} - -unsigned char btchip_output_script_is_native_witness(unsigned char *buffer) { - if (G_coin_config->native_segwit_prefix) { - if ((os_memcmp(buffer, TRANSACTION_OUTPUT_SCRIPT_P2WPKH_PRE, - sizeof(TRANSACTION_OUTPUT_SCRIPT_P2WPKH_PRE)) == 0) || - (os_memcmp(buffer, TRANSACTION_OUTPUT_SCRIPT_P2WSH_PRE, - sizeof(TRANSACTION_OUTPUT_SCRIPT_P2WSH_PRE)) == 0)) { - return 1; - } - } - return 0; -} - -unsigned char btchip_output_script_is_op_return(unsigned char *buffer) { - if (G_coin_config->kind == COIN_KIND_BITCOIN_CASH) { - return ((buffer[1] == 0x6A) || ((buffer[1] == 0x00) && (buffer[2] == 0x6A))); - } - else { - return (buffer[1] == 0x6A); - } -} - -static unsigned char output_script_is_op_create_or_call(unsigned char *buffer, - size_t size, - unsigned char value) { - return (!btchip_output_script_is_regular(buffer) && - !btchip_output_script_is_p2sh(buffer) && - !btchip_output_script_is_op_return(buffer) && (buffer[0] <= 0xEA) && - (buffer[0] < size) && - (buffer[buffer[0]] == value)); -} - -unsigned char btchip_output_script_is_op_create(unsigned char *buffer, - size_t size) { - return output_script_is_op_create_or_call(buffer, size, 0xC1); -} - -unsigned char btchip_output_script_is_op_call(unsigned char *buffer, - size_t size) { - return output_script_is_op_create_or_call(buffer, size, 0xC2); -} - -unsigned char btchip_rng_u8_modulo(unsigned char modulo) { - unsigned int rng_max = 256 % modulo; - unsigned int rng_limit = 256 - rng_max; - unsigned char candidate; - while ((candidate = cx_rng_u8()) > rng_limit) - ; - return (candidate % modulo); -} - -unsigned char btchip_secure_memcmp(const void *buf1, const void *buf2, - unsigned short length) { - unsigned char error = 0; - while (length--) { - error |= ((unsigned char *)buf1)[length] ^ - ((unsigned char *)buf2)[length]; - } - if (length != 0xffff) { - return 1; - } - return error; -} - -unsigned long int btchip_read_u32(unsigned char *buffer, unsigned char be, - unsigned char skipSign) { - unsigned char i; - unsigned long int result = 0; - unsigned char shiftValue = (be ? 24 : 0); - for (i = 0; i < 4; i++) { - unsigned char x = (unsigned char)buffer[i]; - if ((i == 0) && skipSign) { - x &= 0x7f; - } - result += ((unsigned long int)x) << shiftValue; - if (be) { - shiftValue -= 8; - } else { - shiftValue += 8; - } - } - return result; -} - -void btchip_write_u32_be(unsigned char *buffer, unsigned long int value) { - buffer[0] = ((value >> 24) & 0xff); - buffer[1] = ((value >> 16) & 0xff); - buffer[2] = ((value >> 8) & 0xff); - buffer[3] = (value & 0xff); -} - -void btchip_write_u32_le(unsigned char *buffer, unsigned long int value) { - buffer[0] = (value & 0xff); - buffer[1] = ((value >> 8) & 0xff); - buffer[2] = ((value >> 16) & 0xff); - buffer[3] = ((value >> 24) & 0xff); -} - - - -void btchip_public_key_hash160(unsigned char *in, unsigned short inlen, - unsigned char *out) { - cx_ripemd160_t riprip; - unsigned char buffer[32]; - cx_hash_sha256(in, inlen, buffer, 32); - cx_ripemd160_init(&riprip); - cx_hash(&riprip.header, CX_LAST, buffer, 32, out, 20); -} - -void btchip_compute_checksum(unsigned char* in, unsigned short inlen, unsigned char * output) { - unsigned char checksumBuffer[32]; - cx_hash_sha256(in, inlen, checksumBuffer, 32); - cx_hash_sha256(checksumBuffer, 32, checksumBuffer, 32); - - PRINTF("Checksum\n%.*H\n",4,checksumBuffer); - os_memmove(output, checksumBuffer, 4); -} - -unsigned short btchip_public_key_to_encoded_base58( - unsigned char *in, unsigned short inlen, unsigned char *out, - unsigned short outlen, unsigned short version, - unsigned char alreadyHashed) { - unsigned char tmpBuffer[34]; - - unsigned char versionSize = (version > 255 ? 2 : 1); - size_t outputLen; - - if (!alreadyHashed) { - PRINTF("To hash\n%.*H\n",inlen,in); - btchip_public_key_hash160(in, inlen, tmpBuffer + versionSize); - PRINTF("Hash160\n%.*H\n",20,(tmpBuffer + versionSize)); - if (version > 255) { - tmpBuffer[0] = (version >> 8); - tmpBuffer[1] = version; - } else { - tmpBuffer[0] = version; - } - } else { - os_memmove(tmpBuffer, in, 20 + versionSize); - } - - btchip_compute_checksum(tmpBuffer, 20 + versionSize, tmpBuffer + 20 + versionSize); - - outputLen = outlen; - if (btchip_encode_base58(tmpBuffer, 24 + versionSize, out, &outputLen) < 0) { - THROW(EXCEPTION); - } - return outputLen; -} - -void btchip_swap_bytes(unsigned char *target, unsigned char *source, - unsigned char size) { - unsigned char i; - for (i = 0; i < size; i++) { - target[i] = source[size - 1 - i]; - } -} - -unsigned short btchip_decode_base58_address(unsigned char *in, - unsigned short inlen, - unsigned char *out, - unsigned short outlen) { - unsigned char hashBuffer[32]; - cx_sha256_t hash; - size_t outputLen = outlen; - if (btchip_decode_base58((char *)in, inlen, out, &outputLen) < 0) { - THROW(EXCEPTION); - } - outlen = outputLen; - - // Compute hash to verify address - cx_sha256_init(&hash); - cx_hash(&hash.header, CX_LAST, out, outlen - 4, hashBuffer, 32); - cx_sha256_init(&hash); - cx_hash(&hash.header, CX_LAST, hashBuffer, 32, hashBuffer, 32); - - if (os_memcmp(out + outlen - 4, hashBuffer, 4)) { - PRINTF("Hash checksum mismatch\n%.*H\n",sizeof(hashBuffer),hashBuffer); - THROW(INVALID_CHECKSUM); - } - - return outlen; -} - -void btchip_private_derive_keypair(unsigned char *bip32Path, - unsigned char derivePublic, - unsigned char *out_chainCode, - cx_ecfp_private_key_t * private_key, - cx_ecfp_public_key_t* public_key) { - unsigned char bip32PathLength; - unsigned char i; - union { - unsigned int bip32PathInt[MAX_BIP32_PATH]; - unsigned char privateComponent[32]; - } u; - - bip32PathLength = bip32Path[0]; - if (bip32PathLength > MAX_BIP32_PATH) { - THROW(INVALID_PARAMETER); - } - bip32Path++; - for (i = 0; i < bip32PathLength; i++) { - u.bip32PathInt[i] = btchip_read_u32(bip32Path, 1, 0); - bip32Path += 4; - } - - io_seproxyhal_io_heartbeat(); - - os_perso_derive_node_bip32(CX_CURVE_256K1, u.bip32PathInt, bip32PathLength, - u.privateComponent, out_chainCode); - - cx_ecdsa_init_private_key(BTCHIP_CURVE, u.privateComponent, 32, - private_key); - - if (derivePublic) { - cx_ecfp_generate_pair(BTCHIP_CURVE, public_key, - private_key, 1); - } - - io_seproxyhal_io_heartbeat(); - - os_memset(u.privateComponent, 0, sizeof(u.privateComponent)); -} - -/* -Checks if the values of a derivation path are within "normal" (arbitrary) ranges: -Account < 100, change == 1 or 0, address index < 50000 -Returns 1 if the path is unusual, or not compliant with BIP44*/ -unsigned char bip44_derivation_guard(unsigned char *bip32Path, bool is_change_path) { - - unsigned char i, path_len; - unsigned int bip32PathInt[MAX_BIP32_PATH]; - - path_len = bip32Path[0]; - bip32Path++; - if (path_len > MAX_BIP32_PATH) { - THROW(INVALID_PARAMETER); - } - - for (i = 0; i < path_len; i++) { - bip32PathInt[i] = btchip_read_u32(bip32Path, 1, 0); - bip32Path += 4; - } - - // If the path length is not compliant with BIP44 or if the purpose don't match regular usage, return a warning - if(path_len != BIP44_PATH_LEN || - ((bip32PathInt[BIP44_PURPOSE_OFFSET]^0x80000000) != 44 && - (bip32PathInt[BIP44_PURPOSE_OFFSET]^0x80000000) != 49 && - (bip32PathInt[BIP44_PURPOSE_OFFSET]^0x80000000) != 84)) { - return 1; - } - - // If the coin type doesn't match, return a warning - if ((G_coin_config->bip44_coin_type != 0) && - (((bip32PathInt[BIP44_COIN_TYPE_OFFSET]^0x80000000) != G_coin_config->bip44_coin_type) && - ((bip32PathInt[BIP44_COIN_TYPE_OFFSET]^0x80000000) != G_coin_config->bip44_coin_type2))) { - return 1; - } - - // If the account or address index is very high or if the change isn't 1, return a warning - if((bip32PathInt[BIP44_ACCOUNT_OFFSET]^0x80000000) > MAX_BIP44_ACCOUNT_RECOMMENDED || - bip32PathInt[BIP44_CHANGE_OFFSET] != is_change_path?1:0 || - bip32PathInt[BIP44_ADDRESS_INDEX_OFFSET] > MAX_BIP44_ADDRESS_INDEX_RECOMMENDED) { - return 1; - } - - return 0; -} - -/* -Only enforce the structure or coin type for consumed UTXOs or a public address -Returns 0 if the path is non compliant, or 1 if compliant -*/ -unsigned char enforce_bip44_coin_type(unsigned char *bip32Path, bool for_pubkey) { - unsigned char i, path_len; - unsigned int bip32PathInt[MAX_BIP32_PATH]; - // No enforcement required - if (G_coin_config->bip44_coin_type == 0) { - return 1; - } - // Path is too short - always require a user validation if signing - if (bip32Path[0] < 2) { - return for_pubkey; - } - - path_len = bip32Path[0]; - bip32Path++; - if (path_len > MAX_BIP32_PATH) { - THROW(INVALID_PARAMETER); - } - - for (i = 0; i < path_len; i++) { - bip32PathInt[i] = btchip_read_u32(bip32Path, 1, 0); - bip32Path += 4; - } - - // Path is not compliant with BIP 44 or derivatives - valid if not signing - if (!(((bip32PathInt[BIP44_PURPOSE_OFFSET]^0x80000000) == 44 || - (bip32PathInt[BIP44_PURPOSE_OFFSET]^0x80000000) == 49 || - (bip32PathInt[BIP44_PURPOSE_OFFSET]^0x80000000) == 84))) { - return for_pubkey; - } - - if (((bip32PathInt[BIP44_COIN_TYPE_OFFSET]^0x80000000) == G_coin_config->bip44_coin_type) || - ((bip32PathInt[BIP44_COIN_TYPE_OFFSET]^0x80000000) == G_coin_config->bip44_coin_type2)) { - // Valid BIP 44 path - return 1; - } - // Everything else needs a user validation - return 0; -} - -// Print a BIP32 path as an ascii string to display on the device screen -// On the Ledger Blue, if the string is longer than 30 char, the string will be split in multiple lines -unsigned char bip32_print_path(unsigned char *bip32Path, char* out, unsigned char max_out_len) { - - unsigned char bip32PathLength; - unsigned char i, offset; - unsigned int current_level; - bool hardened; - - bip32PathLength = bip32Path[0]; - if (bip32PathLength > MAX_BIP32_PATH) { - THROW(INVALID_PARAMETER); - } - bip32Path++; - out[0] = ' '; - offset=1; - for (i = 0; i < bip32PathLength; i++) { - current_level = btchip_read_u32(bip32Path, 1, 0); - hardened = (bool)(current_level & 0x80000000); - if(hardened) { - //remove hardening flag - current_level ^= 0x80000000; - } - bip32Path += 4; - snprintf(out+offset, max_out_len-offset, "%u", current_level); - offset = strnlen(out, max_out_len); - if(offset >= max_out_len - 2) THROW(EXCEPTION_OVERFLOW); - if(hardened) out[offset++] = '\''; - - out[offset++] = '/'; - out[offset] = '\0'; - } - // remove last '/' - out[offset-1] = '\0'; - - return offset -1; -} - -void btchip_transaction_add_output(unsigned char *hash160Address, - unsigned char *amount, unsigned char p2sh) { - const unsigned char *pre = (p2sh ? TRANSACTION_OUTPUT_SCRIPT_P2SH_PRE - : TRANSACTION_OUTPUT_SCRIPT_PRE); - const unsigned char *post = (p2sh ? TRANSACTION_OUTPUT_SCRIPT_P2SH_POST - : TRANSACTION_OUTPUT_SCRIPT_POST); - unsigned char sizePre = (p2sh ? sizeof(TRANSACTION_OUTPUT_SCRIPT_P2SH_PRE) - : sizeof(TRANSACTION_OUTPUT_SCRIPT_PRE)); - unsigned char sizePost = (p2sh ? sizeof(TRANSACTION_OUTPUT_SCRIPT_P2SH_POST) - : sizeof(TRANSACTION_OUTPUT_SCRIPT_POST)); - if (amount != NULL) { - btchip_swap_bytes(btchip_context_D.tmp, amount, 8); - btchip_context_D.tmp += 8; - } - os_memmove(btchip_context_D.tmp, (void *)pre, sizePre); - btchip_context_D.tmp += sizePre; - os_memmove(btchip_context_D.tmp, hash160Address, 20); - btchip_context_D.tmp += 20; - os_memmove(btchip_context_D.tmp, (void *)post, sizePost); - btchip_context_D.tmp += sizePost; -} - - -void btchip_sign_finalhash(void *keyContext, - unsigned char *in, unsigned short inlen, - unsigned char *out, unsigned short outlen, - unsigned char rfc6979) { - io_seproxyhal_io_heartbeat(); - - unsigned int info = 0; - cx_ecdsa_sign((cx_ecfp_private_key_t *)keyContext, - CX_LAST | (rfc6979 ? CX_RND_RFC6979 : CX_RND_TRNG), - CX_SHA256, in, inlen, out, outlen, &info); - if (info & CX_ECCINFO_PARITY_ODD) { - out[0] |= 0x01; - } - - io_seproxyhal_io_heartbeat(); -} diff --git a/src/btchip_internal.h b/src/btchip_internal.h deleted file mode 100644 index d6b455dd..00000000 --- a/src/btchip_internal.h +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef BTCHIP_INTERNAL_H -#define BTCHIP_INTERNAL_H - -#include "btchip.h" -#include "btchip_public_ram_variables.h" -#include "btchip_rom_variables.h" -#include "btchip_filesystem.h" -#include "btchip_base58.h" -#include "btchip_bcd.h" -#include "btchip_ecc.h" -#include "btchip_helpers.h" -#include "btchip_transaction.h" - -#endif diff --git a/src/btchip_nvram.c b/src/btchip_nvram.c deleted file mode 100644 index 2f3990b6..00000000 --- a/src/btchip_nvram.c +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" - -#include "btchip_public_ram_variables.h" - -btchip_storage_t const N_btchip_real; diff --git a/src/btchip_public_ram_variables.c b/src/btchip_public_ram_variables.c deleted file mode 100644 index 9ca8a837..00000000 --- a/src/btchip_public_ram_variables.c +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_public_ram_variables.h" - -btchip_context_t btchip_context_D; - -btchip_altcoin_config_t *G_coin_config; \ No newline at end of file diff --git a/src/btchip_public_ram_variables.h b/src/btchip_public_ram_variables.h deleted file mode 100644 index 52522eea..00000000 --- a/src/btchip_public_ram_variables.h +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef _BTCHIP_PUBLIC_RAM_VARIABLES_H_ -#define _BTCHIP_PUBLIC_RAM_VARIABLES_H_ - -#include "btchip_config.h" - -#include "btchip_secure_value.h" -#include "btchip_context.h" - -extern btchip_context_t btchip_context_D; - -extern btchip_altcoin_config_t *G_coin_config; - -#endif /* _BTCHIP_PUBLIC_RAM_VARIABLES_H_ */ diff --git a/src/btchip_rom_variables.c b/src/btchip_rom_variables.c deleted file mode 100644 index 7ca8a8e1..00000000 --- a/src/btchip_rom_variables.c +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" - -unsigned char const HEXDIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - -unsigned char const BASE58TABLE[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, - 0x10, 0xff, 0x11, 0x12, 0x13, 0x14, 0x15, 0xff, 0x16, 0x17, 0x18, 0x19, - 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0xff, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff}; - -unsigned char const BASE58ALPHABET[] = { - '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; - -unsigned char const SIGNMAGIC[] = {' ', 'S', 'i', 'g', 'n', 'e', 'd', ' ', 'M', - 'e', 's', 's', 'a', 'g', 'e', ':', '\n'}; - -unsigned char const TWOPOWER[] = {0x01, 0x02, 0x04, 0x08, - 0x10, 0x20, 0x40, 0x80}; - -unsigned char const OVERWINTER_PARAM_PREVOUTS[16] = { 'Z', 'c', 'a', 's', 'h', 'P', 'r', 'e', 'v', 'o', 'u', 't', 'H', 'a', 's', 'h' }; -unsigned char const OVERWINTER_PARAM_SEQUENCE[16] = { 'Z', 'c', 'a', 's', 'h', 'S', 'e', 'q', 'u', 'e', 'n', 'c', 'H', 'a', 's', 'h' }; -unsigned char const OVERWINTER_PARAM_OUTPUTS[16] = { 'Z', 'c', 'a', 's', 'h', 'O', 'u', 't', 'p', 'u', 't', 's', 'H', 'a', 's', 'h' }; -unsigned char const OVERWINTER_PARAM_SIGHASH[16] = { 'Z', 'c', 'a', 's', 'h', 'S', 'i', 'g', 'H', 'a', 's', 'h', 0, 0, 0, 0 }; -unsigned char const OVERWINTER_NO_JOINSPLITS[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -unsigned char const DISPATCHER_CLA[] = { - BTCHIP_CLA, // btchip_apdu_setup, - BTCHIP_CLA, // btchip_apdu_verify_pin, - BTCHIP_CLA, // btchip_apdu_get_operation_mode, - BTCHIP_CLA, // btchip_apdu_set_operation_mode, - BTCHIP_CLA, // btchip_apdu_get_wallet_public_key, - BTCHIP_CLA, // btchip_apdu_get_trusted_input, - BTCHIP_CLA, // btchip_apdu_hash_input_start, - BTCHIP_CLA, // btchip_apdu_hash_sign, - BTCHIP_CLA, // btchip_apdu_hash_input_finalize_full, - BTCHIP_CLA, // btchip_apdu_sign_message, - BTCHIP_CLA, // btchip_apdu_get_random, - BTCHIP_CLA, // btchip_apdu_get_firmware_version, - BTCHIP_CLA, // btchip_apdu_get_coin_version -}; - -unsigned char const DISPATCHER_INS[] = { - BTCHIP_INS_SETUP, // btchip_apdu_setup, - BTCHIP_INS_VERIFY_PIN, // btchip_apdu_verify_pin, - BTCHIP_INS_GET_OPERATION_MODE, // btchip_apdu_get_operation_mode, - BTCHIP_INS_SET_OPERATION_MODE, // btchip_apdu_set_operation_mode, - BTCHIP_INS_GET_WALLET_PUBLIC_KEY, // btchip_apdu_get_wallet_public_key, - BTCHIP_INS_GET_TRUSTED_INPUT, // btchip_apdu_get_trusted_input, - BTCHIP_INS_HASH_INPUT_START, // btchip_apdu_hash_input_start, - BTCHIP_INS_HASH_SIGN, // btchip_apdu_hash_sign, - BTCHIP_INS_HASH_INPUT_FINALIZE_FULL, // btchip_apdu_hash_input_finalize_full, - BTCHIP_INS_SIGN_MESSAGE, // btchip_apdu_sign_message, - BTCHIP_INS_GET_RANDOM, // btchip_apdu_get_random, - BTCHIP_INS_GET_FIRMWARE_VERSION, // btchip_apdu_get_firmware_version, - BTCHIP_INS_GET_COIN_VER, // btchip_apdu_get_coin_version -}; - -unsigned char const DISPATCHER_DATA_IN[] = { - 1, // btchip_apdu_setup, - 1, // btchip_apdu_verify_pin, - 0, // btchip_apdu_get_operation_mode, - 1, // btchip_apdu_set_operation_mode, - 1, // btchip_apdu_get_wallet_public_key, - 1, // btchip_apdu_get_trusted_input, - 1, // btchip_apdu_hash_input_start, - 1, // btchip_apdu_hash_sign, - 1, // btchip_apdu_hash_input_finalize_full, - 1, // btchip_apdu_sign_message, - 0, // btchip_apdu_get_random, - 0, // btchip_apdu_get_firmware_version, - 0, // btchip_apdu_get_coin_version -}; - -apduProcessingFunction const DISPATCHER_FUNCTIONS[] = { - btchip_apdu_setup, - btchip_apdu_verify_pin, - btchip_apdu_get_operation_mode, - btchip_apdu_set_operation_mode, - btchip_apdu_get_wallet_public_key, - btchip_apdu_get_trusted_input, - btchip_apdu_hash_input_start, - btchip_apdu_hash_sign, - btchip_apdu_hash_input_finalize_full, - btchip_apdu_sign_message, - btchip_apdu_get_random, - btchip_apdu_get_firmware_version, - btchip_apdu_get_coin_version, -}; diff --git a/src/btchip_rom_variables.h b/src/btchip_rom_variables.h deleted file mode 100644 index eae57c22..00000000 --- a/src/btchip_rom_variables.h +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef _BTCHIP_ROM_VARIABLES_ -#define _BTCHIP_ROM_VARIABLES_ - -#include "btchip_internal.h" - -#define SIGNMAGIC_LENGTH 17 - -extern unsigned char const HEXDIGITS[16]; -extern unsigned char const BASE58TABLE[128]; -extern unsigned char const BASE58ALPHABET[58]; - -extern unsigned char const SIGNMAGIC[SIGNMAGIC_LENGTH]; - -extern unsigned char const OVERWINTER_PARAM_PREVOUTS[16]; -extern unsigned char const OVERWINTER_PARAM_SEQUENCE[16]; -extern unsigned char const OVERWINTER_PARAM_OUTPUTS[16]; -extern unsigned char const OVERWINTER_PARAM_SIGHASH[16]; -extern unsigned char const OVERWINTER_NO_JOINSPLITS[32]; - -#define HDKEY_VERSION_LENGTH 4 - -extern unsigned char const TWOPOWER[8]; - -#define APDU_DEBUG_LENGTH 0 - -#define APDU_NFCPAYMENT_LENGTH 0 - -#define APDU_BIP70_LENGTH 0 - -#define APDU_MOFN_LENGTH 0 - -#define APDU_KEYCARD_LENGTH 0 - -#define APDU_PORTABLE_LENGTH 5 - -#define APDU_KEYBOARD_LENGTH 0 - -#define APDU_LEGACY_SETUP_LENGTH 0 - -#define APDU_DEVELOPER_MODE_LENGTH 0 - -#define APDU_BASE_LENGTH 13 - -#define DISPATCHER_APDUS 13 - -typedef unsigned short (*apduProcessingFunction)(void); - -extern unsigned char const DISPATCHER_CLA[DISPATCHER_APDUS]; -extern unsigned char const DISPATCHER_INS[DISPATCHER_APDUS]; -extern unsigned char const DISPATCHER_DATA_IN[DISPATCHER_APDUS]; -extern apduProcessingFunction const DISPATCHER_FUNCTIONS[DISPATCHER_APDUS]; - -#endif /* _BTCHIP_ROM_VARIABLES_ */ \ No newline at end of file diff --git a/src/btchip_secure_value.c b/src/btchip_secure_value.c deleted file mode 100644 index 4fd16228..00000000 --- a/src/btchip_secure_value.c +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" - -void sbSet(secu8 *target, unsigned char source) { - *target = (((unsigned char)~source) << 8) + source; -} - -void sbCheck(secu8 source) { - if (((source >> 8) & 0xff) != (unsigned char)(~(source & 0xff))) { - reset(); - } -} - -void ssSet(secu16 *target, unsigned short source) { - *target = (((unsigned long int)((unsigned short)~source)) << 16) + source; -} - -void ssCheck(secu16 source) { - if (((source >> 16) & 0xffff) != (unsigned short)(~(source & 0xffff))) { - reset(); - } -} diff --git a/src/btchip_transaction.c b/src/btchip_transaction.c deleted file mode 100644 index 63ffc070..00000000 --- a/src/btchip_transaction.c +++ /dev/null @@ -1,935 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "btchip_internal.h" -#include "btchip_apdu_constants.h" -#include "btchip_display_variables.h" - -#define CONSENSUS_BRANCH_ID_OVERWINTER 0x5ba81b19 -#define CONSENSUS_BRANCH_ID_SAPLING 0x76b809bb -#define CONSENSUS_BRANCH_ID_ZCLASSIC 0x930b540d - -// Check if fOverwintered flag is set and if nVersion is >= 0x03 -#define TRUSTED_INPUT_OVERWINTER ( (G_coin_config->kind == COIN_KIND_ZCASH || \ - G_coin_config->kind == COIN_KIND_ZCLASSIC || \ - G_coin_config->kind == COIN_KIND_KOMODO) && \ - (btchip_read_u32(btchip_context_D.transactionVersion, 0, 0) & (1<<31)) && \ - (btchip_read_u32(btchip_context_D.transactionVersion, 0, 0) ^ (1<<31)) >= 0x03 \ - ) - -#define DEBUG_LONG "%d" - -void check_transaction_available(unsigned char x) { - if (btchip_context_D.transactionDataRemaining < x) { - PRINTF("Check transaction available failed %d < %d\n", btchip_context_D.transactionDataRemaining, x); - THROW(EXCEPTION); - } -} - -#define OP_HASH160 0xA9 -#define OP_EQUAL 0x87 -#define OP_CHECKMULTISIG 0xAE - -unsigned char transaction_amount_add_be(unsigned char *target, - unsigned char *a, - unsigned char *b) { - unsigned char carry = 0; - unsigned char i; - for (i = 0; i < 8; i++) { - unsigned short val = a[8 - 1 - i] + b[8 - 1 - i] + (carry ? 1 : 0); - carry = (val > 255); - target[8 - 1 - i] = (val & 255); - } - return carry; -} - -unsigned char transaction_amount_sub_be(unsigned char *target, - unsigned char *a, - unsigned char *b) { - unsigned char borrow = 0; - unsigned char i; - for (i = 0; i < 8; i++) { - unsigned short tmpA = a[8 - 1 - i]; - unsigned short tmpB = b[8 - 1 - i]; - if (borrow) { - if (tmpA <= tmpB) { - tmpA += (255 + 1) - 1; - } else { - borrow = 0; - tmpA--; - } - } - if (tmpA < tmpB) { - borrow = 1; - tmpA += 255 + 1; - } - target[8 - 1 - i] = (unsigned char)(tmpA - tmpB); - } - - return borrow; -} - -void transaction_offset(unsigned char value) { - if ((btchip_context_D.transactionHashOption & TRANSACTION_HASH_FULL) != 0) { - PRINTF("--- ADD TO HASH FULL:\n%.*H\n", value, btchip_context_D.transactionBufferPointer); - if (btchip_context_D.usingOverwinter) { - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, btchip_context_D.transactionBufferPointer, value, NULL, 0); - } - else { - cx_hash(&btchip_context_D.transactionHashFull.sha256.header, 0, - btchip_context_D.transactionBufferPointer, value, NULL, 0); - } - } - if ((btchip_context_D.transactionHashOption & - TRANSACTION_HASH_AUTHORIZATION) != 0) { - PRINTF("--- ADD TO HASH AUTH:\n%.*H\n", value, btchip_context_D.transactionBufferPointer); - cx_hash(&btchip_context_D.transactionHashAuthorization.header, 0, - btchip_context_D.transactionBufferPointer, value, NULL, 0); - } -} - -void transaction_offset_increase(unsigned char value) { - transaction_offset(value); - btchip_context_D.transactionBufferPointer += value; - btchip_context_D.transactionDataRemaining -= value; -} - -unsigned long int transaction_get_varint(void) { - unsigned char firstByte; - check_transaction_available(1); - firstByte = *btchip_context_D.transactionBufferPointer; - if (firstByte < 0xFD) { - transaction_offset_increase(1); - return firstByte; - } else if (firstByte == 0xFD) { - unsigned long int result; - transaction_offset_increase(1); - check_transaction_available(2); - result = - (unsigned long int)(*btchip_context_D.transactionBufferPointer) | - ((unsigned long int)(*(btchip_context_D.transactionBufferPointer + - 1)) - << 8); - transaction_offset_increase(2); - return result; - } else if (firstByte == 0xFE) { - unsigned long int result; - transaction_offset_increase(1); - check_transaction_available(4); - result = - btchip_read_u32(btchip_context_D.transactionBufferPointer, 0, 0); - transaction_offset_increase(4); - return result; - } else { - PRINTF("Varint parsing failed\n"); - THROW(INVALID_PARAMETER); - return 0; - } -} - -void transaction_parse(unsigned char parseMode) { - unsigned char optionP2SHSkip2FA = - ((N_btchip.bkp.config.options & BTCHIP_OPTION_SKIP_2FA_P2SH) != 0); - btchip_set_check_internal_structure_integrity(0); - BEGIN_TRY { - TRY { - for (;;) { - switch (btchip_context_D.transactionContext.transactionState) { - case BTCHIP_TRANSACTION_NONE: { - PRINTF("Init transaction parser\n"); - // Reset transaction state - btchip_context_D.transactionContext - .transactionRemainingInputsOutputs = 0; - btchip_context_D.transactionContext - .transactionCurrentInputOutput = 0; - btchip_context_D.transactionContext.scriptRemaining = 0; - os_memset( - btchip_context_D.transactionContext.transactionAmount, - 0, sizeof(btchip_context_D.transactionContext - .transactionAmount)); - // TODO : transactionControlFid - // Reset hashes - if (btchip_context_D.usingOverwinter) { - if (btchip_context_D.segwitParsedOnce) { - uint8_t parameters[16]; - os_memmove(parameters, OVERWINTER_PARAM_SIGHASH, 16); - if (G_coin_config->kind == COIN_KIND_ZCLASSIC) { - btchip_write_u32_le(parameters + 12, CONSENSUS_BRANCH_ID_ZCLASSIC); - } - else { - btchip_write_u32_le(parameters + 12, - btchip_context_D.usingOverwinter == ZCASH_USING_OVERWINTER_SAPLING ? - (G_coin_config->zcash_consensus_branch_id != 0 ? G_coin_config->zcash_consensus_branch_id : CONSENSUS_BRANCH_ID_SAPLING) : CONSENSUS_BRANCH_ID_OVERWINTER); - } - cx_blake2b_init2(&btchip_context_D.transactionHashFull.blake2b, 256, NULL, 0, parameters, 16); - } - } - else { - cx_sha256_init(&btchip_context_D.transactionHashFull.sha256); - } - cx_sha256_init( - &btchip_context_D.transactionHashAuthorization); - if (btchip_context_D.usingSegwit) { - btchip_context_D.transactionHashOption = 0; - if (!btchip_context_D.segwitParsedOnce) { - if (btchip_context_D.usingOverwinter) { - cx_blake2b_init2(&btchip_context_D.segwit.hash.hashPrevouts.blake2b, 256, NULL, 0, (uint8_t *)OVERWINTER_PARAM_PREVOUTS, 16); - cx_blake2b_init2(&btchip_context_D.transactionHashFull.blake2b, 256, NULL, 0, (uint8_t *)OVERWINTER_PARAM_SEQUENCE, 16); - } - else { - cx_sha256_init( - &btchip_context_D.segwit.hash.hashPrevouts.sha256); - } - } else { - PRINTF("Resume SegWit hash\n"); - PRINTF("SEGWIT Version\n%.*H\n",sizeof(btchip_context_D.transactionVersion),btchip_context_D.transactionVersion); - PRINTF("SEGWIT HashedPrevouts\n%.*H\n",sizeof(btchip_context_D.segwit.cache.hashedPrevouts),btchip_context_D.segwit.cache.hashedPrevouts); - PRINTF("SEGWIT HashedSequence\n%.*H\n",sizeof(btchip_context_D.segwit.cache.hashedSequence),btchip_context_D.segwit.cache.hashedSequence); - if (btchip_context_D.usingOverwinter) { - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, btchip_context_D.transactionVersion, sizeof(btchip_context_D.transactionVersion), NULL, 0); - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, btchip_context_D.nVersionGroupId, sizeof(btchip_context_D.nVersionGroupId), NULL, 0); - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, btchip_context_D.segwit.cache.hashedPrevouts, sizeof(btchip_context_D.segwit.cache.hashedPrevouts), NULL, 0); - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, btchip_context_D.segwit.cache.hashedSequence, sizeof(btchip_context_D.segwit.cache.hashedSequence), NULL, 0); - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, btchip_context_D.segwit.cache.hashedOutputs, sizeof(btchip_context_D.segwit.cache.hashedOutputs), NULL, 0); - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, OVERWINTER_NO_JOINSPLITS, 32, NULL, 0); - if (btchip_context_D.usingOverwinter == ZCASH_USING_OVERWINTER_SAPLING) { - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, OVERWINTER_NO_JOINSPLITS, 32, NULL, 0); // sapling hashShieldedSpends - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, OVERWINTER_NO_JOINSPLITS, 32, NULL, 0); // sapling hashShieldedOutputs - } - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, btchip_context_D.nLockTime, sizeof(btchip_context_D.nLockTime), NULL, 0); - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, btchip_context_D.nExpiryHeight, sizeof(btchip_context_D.nExpiryHeight), NULL, 0); - if (btchip_context_D.usingOverwinter == ZCASH_USING_OVERWINTER_SAPLING) { - unsigned char valueBalance[8]; - os_memset(valueBalance, 0, sizeof(valueBalance)); - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, valueBalance, sizeof(valueBalance), NULL, 0); // sapling valueBalance - } - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, btchip_context_D.sigHashType, sizeof(btchip_context_D.sigHashType), NULL, 0); - } - else { - PRINTF("--- ADD TO HASH FULL:\n%.*H\n", sizeof(btchip_context_D.transactionVersion), btchip_context_D.transactionVersion); - cx_hash( - &btchip_context_D.transactionHashFull.sha256.header, 0, - btchip_context_D.transactionVersion, - sizeof(btchip_context_D.transactionVersion), - NULL, 0); - PRINTF("--- ADD TO HASH FULL:\n%.*H\n", sizeof(btchip_context_D.segwit.cache.hashedPrevouts), btchip_context_D.segwit.cache.hashedPrevouts); - cx_hash( - &btchip_context_D.transactionHashFull.sha256.header, 0, - btchip_context_D.segwit.cache.hashedPrevouts, - sizeof(btchip_context_D.segwit.cache - .hashedPrevouts), - NULL, 0); - PRINTF("--- ADD TO HASH FULL:\n%.*H\n", sizeof(btchip_context_D.segwit.cache.hashedSequence), btchip_context_D.segwit.cache.hashedSequence); - cx_hash( - &btchip_context_D.transactionHashFull.sha256.header, 0, - btchip_context_D.segwit.cache.hashedSequence, - sizeof(btchip_context_D.segwit.cache - .hashedSequence), - NULL, 0); - PRINTF("--- ADD TO HASH AUTH:\n%.*H\n", sizeof(btchip_context_D.segwit.cache), (unsigned char *)&btchip_context_D.segwit.cache); - cx_hash(&btchip_context_D - .transactionHashAuthorization.header, - 0, - (unsigned char *)&btchip_context_D - .segwit.cache, - sizeof(btchip_context_D.segwit.cache), - NULL, 0); - } - } - } - // Parse the beginning of the transaction - // Version - check_transaction_available(4); - os_memmove(btchip_context_D.transactionVersion, - btchip_context_D.transactionBufferPointer, 4); - transaction_offset_increase(4); - - if (btchip_context_D.usingOverwinter || - TRUSTED_INPUT_OVERWINTER) { - // nVersionGroupId - check_transaction_available(4); - os_memmove(btchip_context_D.nVersionGroupId, - btchip_context_D.transactionBufferPointer, 4); - transaction_offset_increase(4); - } - - if (G_coin_config->flags & FLAG_PEERCOIN_SUPPORT) { - if (((G_coin_config->family == - BTCHIP_FAMILY_PEERCOIN && - (btchip_context_D.transactionVersion[0] < 3))) || - ((G_coin_config->family == BTCHIP_FAMILY_STEALTH) && - (btchip_context_D.transactionVersion[0] < 2))) { - // Timestamp - check_transaction_available(4); - transaction_offset_increase(4); - } - } - - // Number of inputs - btchip_context_D.transactionContext - .transactionRemainingInputsOutputs = - transaction_get_varint(); - PRINTF("Number of inputs : " DEBUG_LONG "\n",btchip_context_D.transactionContext.transactionRemainingInputsOutputs); - if (btchip_context_D.called_from_swap && parseMode == PARSE_MODE_SIGNATURE) { - // remember number of inputs to know when to exit from library - // we will count number of already signed inputs and compare with this value - // As there are a lot of different states in which we can have different number of input - // (when for ex. we sign segregated witness) - if (vars.swap_data.totalNumberOfInputs == 0) { - vars.swap_data.totalNumberOfInputs = - btchip_context_D.transactionContext.transactionRemainingInputsOutputs; - } - // Reseting the flag, because we should check address ones for each input - vars.swap_data.was_address_checked = 0; - } - // Ready to proceed - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_DEFINED_WAIT_INPUT; - - // no break is intentional - } - - case BTCHIP_TRANSACTION_DEFINED_WAIT_INPUT: { - unsigned char trustedInputFlag = 1; - PRINTF("Process input\n"); - if (btchip_context_D.transactionContext - .transactionRemainingInputsOutputs == 0) { - // No more inputs to hash, move forward - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_INPUT_HASHING_DONE; - continue; - } - if (btchip_context_D.transactionDataRemaining < 1) { - // No more data to read, ok - goto ok; - } - // Proceed with the next input - if (parseMode == PARSE_MODE_TRUSTED_INPUT) { - check_transaction_available( - 36); // prevout : 32 hash + 4 index - transaction_offset_increase(36); - } - if (parseMode == PARSE_MODE_SIGNATURE) { - unsigned char trustedInputLength; - unsigned char trustedInput[TRUSTED_INPUT_TOTAL_SIZE]; - unsigned char amount[8]; - unsigned char *savePointer; - - // Expect the trusted input flag and trusted input length - check_transaction_available(2); - switch (*btchip_context_D.transactionBufferPointer) { - case 0: - if (btchip_context_D.usingSegwit) { - PRINTF("Non trusted input used in segwit mode\n"); - goto fail; - } - trustedInputFlag = 0; - break; - case 1: - if (btchip_context_D.usingSegwit) { - // Segwit inputs can be passed as TrustedInput also - PRINTF("Trusted input used in segwit mode\n"); - } - trustedInputFlag = 1; - break; - case 2: - if (!btchip_context_D.usingSegwit) { - PRINTF("Segwit input not used in segwit mode\n"); - goto fail; - } - trustedInputFlag = 0; - break; - default: - PRINTF("Invalid trusted input flag\n"); - goto fail; - } - /* - trustedInputLength = - *(btchip_context_D.transactionBufferPointer + 1); - if (trustedInputLength > sizeof(trustedInput)) { - PRINTF("Trusted input too long\n"); - goto fail; - } - */ - // Check TrustedInput (TI) integrity, be it a non-segwit TI or a segwit TI - if (trustedInputFlag) { - trustedInputLength = *( - btchip_context_D.transactionBufferPointer + 1); - if ((trustedInputLength > sizeof(trustedInput)) || - (trustedInputLength < 8)) { - PRINTF("Invalid trusted input size\n"); - goto fail; - } - - check_transaction_available(2 + trustedInputLength); - // Check TrustedInput Hmac - cx_hmac_sha256( - (uint8_t *)N_btchip.bkp.trustedinput_key, - sizeof(N_btchip.bkp.trustedinput_key), - btchip_context_D.transactionBufferPointer + 2, - trustedInputLength - 8, trustedInput, trustedInputLength); - PRINTF("====> Input HMAC: %.*H\n", 8, btchip_context_D.transactionBufferPointer + 2 + trustedInputLength - 8); - PRINTF("====> Computed HMAC: %.*H\n", 8, trustedInput); - - if (btchip_secure_memcmp( - trustedInput, // Contains computed Hmac for now - btchip_context_D.transactionBufferPointer + - 2 + trustedInputLength - 8, - 8) != 0) { - PRINTF("Invalid signature\n"); - goto fail; - } - // Hmac is valid. If TrustedInput contains a segwit input, update data pointer & length - // to fake the parser into believing a normal segwit input was received. Do not use - // transaction_offset_increase() here as it could update the hash being computed. - if (btchip_context_D.usingSegwit) { - // Overwrite the no longer needed HMAC's 1st byte w/ the input script length byte. - *(btchip_context_D.transactionBufferPointer + 1 + TRUSTED_INPUT_SIZE + 1) = - *(btchip_context_D.transactionBufferPointer + 1 + TRUSTED_INPUT_TOTAL_SIZE + 1); - // Set tx data pointer on TI header's (i.e. 0x38||0x32||0x00||Nonce (2B)) last byte - // before prevout tx hash. Also remove HMAC size from remaining data length. - btchip_context_D.transactionBufferPointer += 5; - btchip_context_D.transactionDataRemaining -= (5+8); - } - } - // Handle pure segwit inputs, whether trusted or not (i.e. InputHashStart 1st APDU's P2==02 - // & data[0]=={0x01, 0x02}) - if (btchip_context_D.usingSegwit) { - transaction_offset_increase(1); // Set tx pointer on 1st byte of hash - check_transaction_available( - 36); // prevout : 32 hash + 4 index - if (!btchip_context_D.segwitParsedOnce) { - if (btchip_context_D.usingOverwinter) { - cx_hash(&btchip_context_D.segwit.hash.hashPrevouts.blake2b.header, 0, btchip_context_D.transactionBufferPointer, 36, NULL, 0); - } - else { - cx_hash( - &btchip_context_D.segwit.hash.hashPrevouts - .sha256.header, - 0, - btchip_context_D.transactionBufferPointer, - 36, NULL, 0); - } - transaction_offset_increase(36); - check_transaction_available(8); // update amount - btchip_swap_bytes( - amount, - btchip_context_D.transactionBufferPointer, - 8); - if (transaction_amount_add_be( - btchip_context_D.transactionContext - .transactionAmount, - btchip_context_D.transactionContext - .transactionAmount, - amount)) { - PRINTF("Overflow\n"); - goto fail; - } - PRINTF("Adding amount\n%.*H\n",8,btchip_context_D.transactionBufferPointer); - PRINTF("New amount\n%.*H\n",8,btchip_context_D.transactionContext.transactionAmount); - transaction_offset_increase(8); - } else { - btchip_context_D.transactionHashOption = - TRANSACTION_HASH_FULL; - transaction_offset_increase(36); - btchip_context_D.transactionHashOption = 0; - check_transaction_available(8); // save amount - os_memmove( - btchip_context_D.inputValue, - btchip_context_D.transactionBufferPointer, - 8); - transaction_offset_increase(8); - btchip_context_D.transactionHashOption = - TRANSACTION_HASH_FULL; - } - } - // Handle non-segwit inputs (i.e. InputHashStart 1st APDU's P2==00 && data[0]==0x00) - else if (!trustedInputFlag) { - // Only authorized in relaxed wallet and server - // modes - SB_CHECK(N_btchip.bkp.config.operationMode); - switch (SB_GET(N_btchip.bkp.config.operationMode)) { - case BTCHIP_MODE_WALLET: - if (!optionP2SHSkip2FA) { - PRINTF("Untrusted input not authorized\n"); - goto fail; - } - break; - case BTCHIP_MODE_RELAXED_WALLET: - case BTCHIP_MODE_SERVER: - break; - default: - PRINTF("Untrusted input not authorized\n"); - goto fail; - } - btchip_context_D.transactionBufferPointer++; - btchip_context_D.transactionDataRemaining--; - check_transaction_available( - 36); // prevout : 32 hash + 4 index - transaction_offset_increase(36); - PRINTF("Marking relaxed input\n"); - btchip_context_D.transactionContext.relaxed = 1; - /* - PRINTF("Clearing P2SH consumption\n"); - btchip_context_D.transactionContext.consumeP2SH = 0; - */ - } - // Handle non-segwit TrustedInput (i.e. InputHashStart 1st APDU's P2==00 & data[0]==0x01) - else if (trustedInputFlag && !btchip_context_D.usingSegwit) { - os_memmove( - trustedInput, - btchip_context_D.transactionBufferPointer + 2, - trustedInputLength - 8); - if (trustedInput[0] != MAGIC_TRUSTED_INPUT) { - PRINTF("Failed to verify trusted input signature\n"); - goto fail; - } - // Update the hash with prevout data - savePointer = - btchip_context_D.transactionBufferPointer; - /* - // Check if a P2SH script is used - if ((trustedInput[1] & FLAG_TRUSTED_INPUT_P2SH) == - 0) { - PRINTF("Clearing P2SH consumption\n"); - btchip_context_D.transactionContext.consumeP2SH = - 0; - } - */ - btchip_context_D.transactionBufferPointer = - trustedInput + 4; - PRINTF("Trusted input hash\n%.*H\n",36,btchip_context_D.transactionBufferPointer); - transaction_offset(36); - - btchip_context_D.transactionBufferPointer = - savePointer + (2 + trustedInputLength); - btchip_context_D.transactionDataRemaining -= - (2 + trustedInputLength); - - // Update the amount - - btchip_swap_bytes(amount, trustedInput + 40, 8); - if (transaction_amount_add_be( - btchip_context_D.transactionContext - .transactionAmount, - btchip_context_D.transactionContext - .transactionAmount, - amount)) { - PRINTF("Overflow\n"); - goto fail; - } - - PRINTF("Adding amount\n%.*H\n",8,(trustedInput + 40)); - PRINTF("New amount\n%.*H\n",8,btchip_context_D.transactionContext.transactionAmount); - } - - if (!btchip_context_D.usingSegwit) { - // Do not include the input script length + value in - // the authentication hash - btchip_context_D.transactionHashOption = - TRANSACTION_HASH_FULL; - } - } - // Read the script length - btchip_context_D.transactionContext.scriptRemaining = - transaction_get_varint(); - PRINTF("Script to read " DEBUG_LONG "\n",btchip_context_D.transactionContext.scriptRemaining); - - if ((parseMode == PARSE_MODE_SIGNATURE) && - !trustedInputFlag && !btchip_context_D.usingSegwit) { - // Only proceeds if this is not to be signed - so length - // should be null - if (btchip_context_D.transactionContext - .scriptRemaining != 0) { - PRINTF("Request to sign relaxed input\n"); - if (!optionP2SHSkip2FA) { - goto fail; - } - } - } - // Move on - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_INPUT_HASHING_IN_PROGRESS_INPUT_SCRIPT; - - // no break is intentional - } - case BTCHIP_TRANSACTION_INPUT_HASHING_IN_PROGRESS_INPUT_SCRIPT: { - unsigned char dataAvailable; - PRINTF("Process input script, remaining " DEBUG_LONG "\n",btchip_context_D.transactionContext.scriptRemaining); - if (btchip_context_D.transactionDataRemaining < 1) { - // No more data to read, ok - goto ok; - } - // Scan for P2SH consumption - huge shortcut, but fine - // enough - // Also usable in SegWit mode - if (btchip_context_D.transactionContext.scriptRemaining == - 1) { - if (*btchip_context_D.transactionBufferPointer == - OP_CHECKMULTISIG) { - if (optionP2SHSkip2FA) { - PRINTF("Marking P2SH consumption\n"); - btchip_context_D.transactionContext - .consumeP2SH = 1; - } - } else { - // When using the P2SH shortcut, all inputs must use - // P2SH - PRINTF("Disabling P2SH consumption\n"); - btchip_context_D.transactionContext.consumeP2SH = 0; - } - transaction_offset_increase(1); - btchip_context_D.transactionContext.scriptRemaining--; - } - - if (btchip_context_D.transactionContext.scriptRemaining == - 0) { - if (parseMode == PARSE_MODE_SIGNATURE) { - if (!btchip_context_D.usingSegwit) { - // Restore dual hash for signature + - // authentication - btchip_context_D.transactionHashOption = - TRANSACTION_HASH_BOTH; - } else { - if (btchip_context_D.segwitParsedOnce) { - // Append the saved value - PRINTF("SEGWIT Add value\n%.*H\n",8,btchip_context_D.inputValue); - if (btchip_context_D.usingOverwinter) { - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, btchip_context_D.inputValue, 8, NULL, 0); - } - else { - PRINTF("--- ADD TO HASH FULL:\n%.*H\n", sizeof(btchip_context_D.inputValue), btchip_context_D.inputValue); - cx_hash(&btchip_context_D - .transactionHashFull.sha256.header, - 0, btchip_context_D.inputValue, 8, - NULL, 0); - } - } - } - } - // Sequence - check_transaction_available(4); - if (btchip_context_D.usingSegwit && - !btchip_context_D.segwitParsedOnce) { - if (btchip_context_D.usingOverwinter) { - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, 0, btchip_context_D.transactionBufferPointer, 4, NULL, 0); - } - else { - PRINTF("--- ADD TO HASH FULL:\n%.*H\n", 4, btchip_context_D.transactionBufferPointer); - cx_hash(&btchip_context_D.transactionHashFull - .sha256.header, - 0, - btchip_context_D.transactionBufferPointer, - 4, NULL, 0); - } - } - transaction_offset_increase(4); - // Move to next input - btchip_context_D.transactionContext - .transactionRemainingInputsOutputs--; - btchip_context_D.transactionContext - .transactionCurrentInputOutput++; - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_DEFINED_WAIT_INPUT; - continue; - } - // Save the last script byte for the P2SH check - dataAvailable = - (btchip_context_D.transactionDataRemaining > - btchip_context_D.transactionContext - .scriptRemaining - - 1 - ? btchip_context_D.transactionContext - .scriptRemaining - - 1 - : btchip_context_D.transactionDataRemaining); - if (dataAvailable == 0) { - goto ok; - } - transaction_offset_increase(dataAvailable); - btchip_context_D.transactionContext.scriptRemaining -= - dataAvailable; - break; - } - case BTCHIP_TRANSACTION_INPUT_HASHING_DONE: { - PRINTF("Input hashing done\n"); - if (parseMode == PARSE_MODE_SIGNATURE) { - // inputs have been prepared, stop the parsing here - if (btchip_context_D.usingSegwit && - !btchip_context_D.segwitParsedOnce) { - unsigned char hashedPrevouts[32]; - unsigned char hashedSequence[32]; - // Flush the cache - if (btchip_context_D.usingOverwinter) { - cx_hash(&btchip_context_D.segwit.hash.hashPrevouts.blake2b.header, CX_LAST, hashedPrevouts, 0, hashedPrevouts, 32); - cx_hash(&btchip_context_D.transactionHashFull.blake2b.header, CX_LAST, hashedSequence, 0, hashedSequence, 32); - } - else { - cx_hash(&btchip_context_D.segwit.hash.hashPrevouts - .sha256.header, - CX_LAST, hashedPrevouts, 0, hashedPrevouts, 32); - cx_sha256_init( - &btchip_context_D.segwit.hash.hashPrevouts.sha256); - cx_hash(&btchip_context_D.segwit.hash.hashPrevouts - .sha256.header, - CX_LAST, hashedPrevouts, - sizeof(hashedPrevouts), hashedPrevouts, 32); - cx_hash(&btchip_context_D.transactionHashFull - .sha256.header, - CX_LAST, hashedSequence, 0, hashedSequence, 32); - cx_sha256_init( - &btchip_context_D.transactionHashFull.sha256); - PRINTF("--- ADD TO HASH FULL:\n%.*H\n", sizeof(hashedSequence), hashedSequence); - cx_hash(&btchip_context_D.transactionHashFull - .sha256.header, - CX_LAST, hashedSequence, - sizeof(hashedSequence), hashedSequence, 32); - - } - os_memmove( - btchip_context_D.segwit.cache.hashedPrevouts, - hashedPrevouts, sizeof(hashedPrevouts)); - os_memmove( - btchip_context_D.segwit.cache.hashedSequence, - hashedSequence, sizeof(hashedSequence)); - PRINTF("hashPrevout\n%.*H\n",32,btchip_context_D.segwit.cache.hashedPrevouts); - PRINTF("hashSequence\n%.*H\n",32,btchip_context_D.segwit.cache.hashedSequence); - } - if (btchip_context_D.usingSegwit && - btchip_context_D.segwitParsedOnce) { - if (!btchip_context_D.usingOverwinter) { - PRINTF("SEGWIT hashedOutputs\n%.*H\n",sizeof(btchip_context_D.segwit.cache.hashedOutputs),btchip_context_D.segwit.cache.hashedOutputs); - cx_hash( - &btchip_context_D.transactionHashFull.sha256.header, 0, - btchip_context_D.segwit.cache.hashedOutputs, - sizeof(btchip_context_D.segwit.cache - .hashedOutputs), - NULL, 0); - } - btchip_context_D.transactionContext - .transactionState = - BTCHIP_TRANSACTION_SIGN_READY; - } else { - btchip_context_D.transactionContext - .transactionState = - BTCHIP_TRANSACTION_PRESIGN_READY; - if (btchip_context_D.usingOverwinter) { - cx_blake2b_init2(&btchip_context_D.transactionHashFull.blake2b, 256, NULL, 0, (uint8_t *)OVERWINTER_PARAM_OUTPUTS, 16); - } - else - if (btchip_context_D.usingSegwit) { - cx_sha256_init(&btchip_context_D.transactionHashFull.sha256); - } - } - continue; - } - if (btchip_context_D.transactionDataRemaining < 1) { - // No more data to read, ok - goto ok; - } - // Number of outputs - btchip_context_D.transactionContext - .transactionRemainingInputsOutputs = - transaction_get_varint(); - btchip_context_D.transactionContext - .transactionCurrentInputOutput = 0; - PRINTF("Number of outputs : " DEBUG_LONG "\n", - btchip_context_D.transactionContext.transactionRemainingInputsOutputs); - // Ready to proceed - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_DEFINED_WAIT_OUTPUT; - - // no break is intentional - } - case BTCHIP_TRANSACTION_DEFINED_WAIT_OUTPUT: { - if (btchip_context_D.transactionContext - .transactionRemainingInputsOutputs == 0) { - // No more outputs to hash, move forward - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_OUTPUT_HASHING_DONE; - continue; - } - if (btchip_context_D.transactionDataRemaining < 1) { - // No more data to read, ok - goto ok; - } - // Amount - check_transaction_available(8); - if ((parseMode == PARSE_MODE_TRUSTED_INPUT) && - (btchip_context_D.transactionContext - .transactionCurrentInputOutput == - btchip_context_D.transactionTargetInput)) { - // Save the amount - os_memmove(btchip_context_D.transactionContext - .transactionAmount, - btchip_context_D.transactionBufferPointer, - 8); - btchip_context_D.trustedInputProcessed = 1; - } - transaction_offset_increase(8); - // Read the script length - btchip_context_D.transactionContext.scriptRemaining = - transaction_get_varint(); - - PRINTF("Script to read " DEBUG_LONG "\n",btchip_context_D.transactionContext.scriptRemaining); - // Move on - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_OUTPUT_HASHING_IN_PROGRESS_OUTPUT_SCRIPT; - - // no break is intentional - } - case BTCHIP_TRANSACTION_OUTPUT_HASHING_IN_PROGRESS_OUTPUT_SCRIPT: { - unsigned char dataAvailable; - PRINTF("Process output script, remaining " DEBUG_LONG "\n",btchip_context_D.transactionContext.scriptRemaining); - /* - // Special check if consuming a P2SH script - if (parseMode == PARSE_MODE_TRUSTED_INPUT) { - // Assume the full input script is sent in a single APDU, - then do the ghetto validation - if ((btchip_context_D.transactionBufferPointer[0] == - OP_HASH160) && - (btchip_context_D.transactionBufferPointer[btchip_context_D.transactionDataRemaining - - 1] == OP_EQUAL)) { - PRINTF("Marking P2SH output\n"); - btchip_context_D.transactionContext.consumeP2SH = 1; - } - } - */ - if (btchip_context_D.transactionDataRemaining < 1) { - // No more data to read, ok - goto ok; - } - if (btchip_context_D.transactionContext.scriptRemaining == - 0) { - // Move to next output - btchip_context_D.transactionContext - .transactionRemainingInputsOutputs--; - btchip_context_D.transactionContext - .transactionCurrentInputOutput++; - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_DEFINED_WAIT_OUTPUT; - continue; - } - dataAvailable = - (btchip_context_D.transactionDataRemaining > - btchip_context_D.transactionContext - .scriptRemaining - ? btchip_context_D.transactionContext - .scriptRemaining - : btchip_context_D.transactionDataRemaining); - if (dataAvailable == 0) { - goto ok; - } - transaction_offset_increase(dataAvailable); - btchip_context_D.transactionContext.scriptRemaining -= - dataAvailable; - break; - } - case BTCHIP_TRANSACTION_OUTPUT_HASHING_DONE: { - PRINTF("Output hashing done\n"); - if (btchip_context_D.transactionDataRemaining < 1) { - // No more data to read, ok - goto ok; - } - // Locktime - check_transaction_available(4); - transaction_offset_increase(4); - - if (btchip_context_D.transactionDataRemaining == 0) { - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_PARSED; - continue; - } else { - btchip_context_D.transactionHashOption = 0; - btchip_context_D.transactionContext.scriptRemaining = - transaction_get_varint(); - btchip_context_D.transactionHashOption = - TRANSACTION_HASH_FULL; - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_PROCESS_EXTRA; - continue; - } - } - - case BTCHIP_TRANSACTION_PROCESS_EXTRA: { - unsigned char dataAvailable; - - if (btchip_context_D.transactionContext.scriptRemaining == - 0) { - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_PARSED; - continue; - } - - if (btchip_context_D.transactionDataRemaining < 1) { - // No more data to read, ok - goto ok; - } - - dataAvailable = - (btchip_context_D.transactionDataRemaining > - btchip_context_D.transactionContext - .scriptRemaining - ? btchip_context_D.transactionContext - .scriptRemaining - : btchip_context_D.transactionDataRemaining); - if (dataAvailable == 0) { - goto ok; - } - transaction_offset_increase(dataAvailable); - btchip_context_D.transactionContext.scriptRemaining -= - dataAvailable; - break; - } - - case BTCHIP_TRANSACTION_PARSED: { - PRINTF("Transaction parsed\n"); - goto ok; - } - - case BTCHIP_TRANSACTION_PRESIGN_READY: { - PRINTF("Presign ready\n"); - goto ok; - } - - case BTCHIP_TRANSACTION_SIGN_READY: { - PRINTF("Sign ready\n"); - goto ok; - } - } - } - - fail: - PRINTF("Transaction parse - fail\n"); - THROW(EXCEPTION); - ok : {} - } - CATCH_OTHER(e) { - PRINTF("Transaction parse - surprise fail\n"); - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - btchip_set_check_internal_structure_integrity(1); - THROW(e); - } - // before the finally to restore the surrounding context if an exception - // is raised during finally - FINALLY { - btchip_set_check_internal_structure_integrity(1); - } - } - END_TRY; -} diff --git a/src/btchip_transaction.h b/src/btchip_transaction.h deleted file mode 100644 index bb340140..00000000 --- a/src/btchip_transaction.h +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#ifndef _BTCHIP_TRANSACTION_H_ -#define _BTCHIP_TRANSACTION_H_ - -#include "btchip_secure_value.h" - -#define TRANSACTION_HASH_NONE 0x00 -#define TRANSACTION_HASH_FULL 0x01 -#define TRANSACTION_HASH_AUTHORIZATION 0x02 -#define TRANSACTION_HASH_BOTH 0x03 - -#define PARSE_MODE_TRUSTED_INPUT 0x01 -#define PARSE_MODE_SIGNATURE 0x02 - -#define TRUSTED_INPUT_SIZE 48 -#define TRUSTED_INPUT_TOTAL_SIZE (TRUSTED_INPUT_SIZE + 8) - -void transaction_parse(unsigned char parseMode); - -// target = a + b -unsigned char transaction_amount_add_be(unsigned char *target, - unsigned char *a, - unsigned char *b); - -// target = a - b -unsigned char transaction_amount_sub_be(unsigned char *target, - unsigned char *a, - unsigned char *b); - -#endif /* _BTCHIP_TRANSACTION_H_ */ diff --git a/src/cashaddr.c b/src/cashaddr.c deleted file mode 100644 index 45a95706..00000000 --- a/src/cashaddr.c +++ /dev/null @@ -1,153 +0,0 @@ -/* Copyright (c) 2017 Pieter Wuille - * Modified work Copyright (c) 2018 Jonas Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "os.h" -#include "cx.h" -#include -#include -#include -#include - -#include "cashaddr.h" - -static const char *charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; - -uint64_t cashaddr_polymod_step(uint64_t pre) { - uint8_t b = pre >> 35; - return ((pre & 0x07ffffffff) << 5) ^ (-((b >> 0) & 1) & 0x98f2bc8e61UL) ^ - (-((b >> 1) & 1) & 0x79b76d99e2UL) ^ - (-((b >> 2) & 1) & 0xf33e5fb3c4UL) ^ - (-((b >> 3) & 1) & 0xae2eabe2a8UL) ^ - (-((b >> 4) & 1) & 0x1e4f43e470UL); -} - -uint64_t PolyMod(uint8_t *prefix, uint8_t *payload, size_t payload_length) { - size_t i; - uint64_t c = 1; - while (*prefix != 0) { - c = cashaddr_polymod_step(c) ^ (*prefix++ & 0x1f); // Prefix - } - c = cashaddr_polymod_step(c); // The zero valued separator - for (i = 0; i < payload_length; ++i) { - c = cashaddr_polymod_step(c) ^ (*payload++); // Hash - } - for (i = 0; i < 8; ++i) { - c = cashaddr_polymod_step(c); // 8 zeros for empty checksum - } - return c ^ 1; -} - -static int convert_bits(uint8_t *out, size_t *outlen, int outbits, - const uint8_t *in, size_t inlen, int inbits, int pad) { - uint32_t val = 0; - int bits = 0; - uint32_t maxv = (((uint32_t)1) << outbits) - 1; - while (inlen--) { - val = (val << inbits) | *(in++); - bits += inbits; - while (bits >= outbits) { - bits -= outbits; - out[(*outlen)++] = (val >> bits) & maxv; - } - } - if (pad) { - if (bits) { - out[(*outlen)++] = (val << (outbits - bits)) & maxv; - } - } else if (((val << (outbits - bits)) & maxv) || bits >= inbits) { - return 0; - } - return 1; -} - -void create_checksum(uint8_t *payload, size_t payload_length, - uint8_t *checksum) { - uint8_t *prefix = (uint8_t *)"bitcoincash"; - uint64_t mod = PolyMod(prefix, payload, payload_length); - - for (size_t i = 0; i < 8; ++i) { - // Convert the 5-bit groups in mod to checksum values. - *checksum++ = (mod >> (5 * (7 - i))) & 0x1f; - } -} - -int cashaddr_encode(uint8_t *hash, const size_t hash_length, uint8_t *addr, - const size_t max_addr_len, const unsigned short version) { - uint8_t version_byte; - uint8_t checksum[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // 5-bit bytes. - uint8_t - tmp[40]; // 8-bit bytes. Should be enough for 1 version byte + 160 bit - uint8_t payload[40]; // 5-bit bytes. Should be enough for 1 version byte + - // 160 bit hash - uint8_t *addr_start; - size_t payload_length = 0; - size_t addr_length = 0; - size_t i; - - addr_start = addr; - *addr_start = 0; - - if (hash_length != 20) // Only support 160 bit hash - return 0; - if (version == CASHADDR_P2PKH) { // Support P2PKH = 0, P2SH = 1 - version_byte = 0; - } else if (version == CASHADDR_P2SH) { - version_byte = 8; - } else { - return 0; - } - - tmp[0] = version_byte; - os_memmove(tmp + 1, hash, hash_length); - convert_bits(payload, &payload_length, 5, tmp, hash_length + 1, 8, 1); - - create_checksum(payload, payload_length, - checksum); // Assume prefix is 'bitcoincash' - - for (i = 0; i < payload_length; ++i) { - if (*payload >> 5) { - *addr_start = 0; - return 0; - } - addr_length++; - if (max_addr_len < addr_length) { - *addr_start = 0; - return 0; - } - *(addr++) = charset[payload[i]]; - } - for (i = 0; i < 8; ++i) { - if (*checksum >> 5) { - *addr_start = 0; - return 0; - } - addr_length++; - if (max_addr_len < addr_length) { - *addr_start = 0; - return 0; - } - *(addr++) = charset[checksum[i]]; - } - *addr = 0; - - return addr_length; -} diff --git a/src/cashaddr.h b/src/cashaddr.h deleted file mode 100644 index 16d277d6..00000000 --- a/src/cashaddr.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2017 Pieter Wuille - * Modified work Copyright (c) 2018 Jonas Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef _CASHADDR_H_ -#define _CASHADDR_H_ - -#include - -#define CASHADDR_P2PKH 0 -#define CASHADDR_P2SH 1 - -/** Encode a Bitcoin Cash address - * - * In: hash: Pointer to the hash - * hash_length: Length of hash (bytes). Only 20 bytes (160 bits) - * supported. - * max_addr_len: Maximum length of encoded address - * version: P2PKH = 0, P2SH = 1 - * - * Out: addr: Pointer to a buffer with encoded address. The encoded - * address end with a '\0'. - * - * Returns the length of the address if successful, 0 if unsuccessful. - */ - -int cashaddr_encode(uint8_t *hash, const size_t hash_length, uint8_t *addr, - const size_t max_addr_len, const unsigned short version); - -#endif /* _CASHADDR_H_ */ diff --git a/src/handle_check_address.c b/src/handle_check_address.c deleted file mode 100644 index df4f2e59..00000000 --- a/src/handle_check_address.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "handle_check_address.h" -#include "os.h" -#include "btchip_helpers.h" -#include "bip32_path.h" -#include "btchip_ecc.h" -#include "btchip_apdu_get_wallet_public_key.h" -#include "cashaddr.h" -#include "segwit_addr.h" -#include - -bool derive_private_key(unsigned char* serialized_path, unsigned char serialized_path_length, cx_ecfp_private_key_t* privKey) { - unsigned char privateComponent[32]; - bip32_path_t path; - if (!parse_serialized_path(&path, serialized_path, serialized_path_length)) { - PRINTF("Can't parse path\n"); - return false; - } - os_perso_derive_node_bip32(CX_CURVE_256K1, path.path, path.length, - privateComponent, NULL); - cx_ecdsa_init_private_key(BTCHIP_CURVE, privateComponent, 32, privKey); - return true; -} - - -bool derive_compressed_public_key( - unsigned char* serialized_path, unsigned char serialized_path_length, - unsigned char* public_key, unsigned char public_key_length) { - cx_ecfp_private_key_t privKey; - if (!derive_private_key(serialized_path, serialized_path_length, &privKey)) - return false; - cx_ecfp_public_key_t pubKey; - - cx_ecfp_generate_pair(BTCHIP_CURVE, &pubKey, &privKey, 1); - btchip_compress_public_key_value(pubKey.W); - os_memcpy(public_key, pubKey.W, 33); - return true; -} - -bool get_address_from_compressed_public_key( - unsigned char format, - unsigned char* compressed_pub_key, - unsigned short payToAddressVersion, - unsigned short payToScriptHashVersion, - const char* native_segwit_prefix, - char * address, - unsigned char max_address_length -) { - bool segwit = (format == P2_SEGWIT); - bool nativeSegwit = (format == P2_NATIVE_SEGWIT); - bool cashAddr = (format == P2_CASHADDR); - int address_length; - if (cashAddr) { - uint8_t tmp[20]; - btchip_public_key_hash160(compressed_pub_key, // IN - 33, // INLEN - tmp); - if (!cashaddr_encode(tmp, 20, (uint8_t *)address, max_address_length, CASHADDR_P2PKH)) - return false; - } else if (!(segwit || nativeSegwit)) { - // btchip_public_key_to_encoded_base58 doesn't add terminating 0, - // so we will do this ourself - address_length = btchip_public_key_to_encoded_base58( - compressed_pub_key, // IN - 33, // INLEN - (uint8_t *)address, // OUT - max_address_length - 1, // MAXOUTLEN - payToAddressVersion, 0); - address[address_length] = 0; - } else { - uint8_t tmp[22]; - tmp[0] = 0x00; - tmp[1] = 0x14; - btchip_public_key_hash160(compressed_pub_key, // IN - 33, // INLEN - tmp + 2 // OUT - ); - if (!nativeSegwit) { - address_length = btchip_public_key_to_encoded_base58( - tmp, // IN - 22, // INLEN - (uint8_t *)address, // OUT - 150, // MAXOUTLEN - payToScriptHashVersion, 0); - address[address_length] = 0; - } else { - if (!native_segwit_prefix) - return false; - if (!segwit_addr_encode( - address, - native_segwit_prefix, 0, tmp + 2, 20)) { - return false; - } - } - } - return true; -} - -static int os_strcmp(const char* s1, const char* s2) { - size_t size = strlen(s1) + 1; - return memcmp(s1, s2, size); -} - -int handle_check_address(check_address_parameters_t* params, btchip_altcoin_config_t* coin_config) { - unsigned char compressed_public_key[33]; - PRINTF("Params on the address %d\n",(unsigned int)params); - PRINTF("Address to check %s\n",params->address_to_check); - PRINTF("Inside handle_check_address\n"); - if (params->address_to_check == 0) { - PRINTF("Address to check == 0\n"); - return 0; - } - if (!derive_compressed_public_key( - params->address_parameters + 1, - params->address_parameters_length - 1, - compressed_public_key, - sizeof(compressed_public_key))) { - return 0; - } - - char address[51]; - if (!get_address_from_compressed_public_key( - params->address_parameters[0], - compressed_public_key, - coin_config->p2pkh_version, - coin_config->p2sh_version, - coin_config->native_segwit_prefix, - address, - sizeof(address))) { - PRINTF("Can't create address from given public key\n"); - return 0; - } - if (os_strcmp(address,params->address_to_check) != 0) { - PRINTF("Addresses don't match\n"); - return 0; - } - PRINTF("Addresses match\n"); - return 1; -} \ No newline at end of file diff --git a/src/handle_check_address.h b/src/handle_check_address.h deleted file mode 100644 index b1956900..00000000 --- a/src/handle_check_address.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _HANDLE_CHECK_ADDRESS_H_ -#define _HANDLE_CHECK_ADDRESS_H_ - -#include "swap_lib_calls.h" -#include "btchip_context.h" - -int handle_check_address(check_address_parameters_t* check_address_params, btchip_altcoin_config_t* coin_config); - -#endif // _HANDLE_CHECK_ADDRESS_H_ \ No newline at end of file diff --git a/src/handle_get_printable_amount.c b/src/handle_get_printable_amount.c deleted file mode 100644 index 2bc5a807..00000000 --- a/src/handle_get_printable_amount.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "handle_get_printable_amount.h" -#include "btchip_bcd.h" -#include - -int handle_get_printable_amount( get_printable_amount_parameters_t* params, btchip_altcoin_config_t *config) { - params->printable_amount[0] = 0; - if (params->amount_length > 8) { - PRINTF("Amount is too big"); - return 0; - } - unsigned char amount[8]; - os_memset(amount, 0, 8); - os_memcpy(amount + (8 - params->amount_length), params->amount, params->amount_length); - unsigned char coin_name_length = strlen(config->name_short); - os_memmove(params->printable_amount, config->name_short, coin_name_length); - params->printable_amount[coin_name_length] = ' '; - int res_length = btchip_convert_hex_amount_to_displayable_no_globals(amount, config->flags, (uint8_t *)params->printable_amount + coin_name_length + 1); - params->printable_amount[res_length + coin_name_length + 1] = '\0'; - - return 1; -} \ No newline at end of file diff --git a/src/handle_get_printable_amount.h b/src/handle_get_printable_amount.h deleted file mode 100644 index 9e634cce..00000000 --- a/src/handle_get_printable_amount.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _HANDLE_GET_PRINTABLE_AMOUNT_H_ -#define _HANDLE_GET_PRINTABLE_AMOUNT_H_ - -#include "swap_lib_calls.h" -#include "btchip_context.h" - -int handle_get_printable_amount(get_printable_amount_parameters_t* get_printable_amount_params, btchip_altcoin_config_t *config); - -#endif // _HANDLE_GET_PRINTABLE_AMOUNT_H_ \ No newline at end of file diff --git a/src/handle_swap_sign_transaction.c b/src/handle_swap_sign_transaction.c deleted file mode 100644 index 1c2dc971..00000000 --- a/src/handle_swap_sign_transaction.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "handle_swap_sign_transaction.h" -#include "os_io_seproxyhal.h" -#include "btchip_public_ram_variables.h" -#include "btchip_display_variables.h" -#include "btchip_context.h" -#include "usbd_core.h" -#include "ux.h" - -#ifdef HAVE_NBGL -#include "nbgl_use_case.h" -#endif - -// Save the BSS address where we will write the return value when finished -static uint8_t *G_swap_sign_return_value_address; - -bool copy_transaction_parameters(create_transaction_parameters_t* sign_transaction_params) { - // first copy parameters to stack, and then to global data. - // We need this "trick" as the input data position can overlap with btc-app globals - swap_data_t stack_data; - memset(&stack_data, 0, sizeof(stack_data)); - strncpy(stack_data.destination_address, sign_transaction_params->destination_address, sizeof(stack_data.destination_address) - 1); - if ((stack_data.destination_address[sizeof(stack_data.destination_address) - 1] != '\0') || - (sign_transaction_params->amount_length > 8) || - (sign_transaction_params->fee_amount_length > 8)) { - return false; - } - // store amount as big endian in 8 bytes, so the passed data should be alligned to right - // input {0xEE, 0x00, 0xFF} should be stored like {0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x00, 0xFF} - memcpy(stack_data.amount + 8 - sign_transaction_params->amount_length, sign_transaction_params->amount, sign_transaction_params->amount_length); - memcpy(stack_data.fees + 8 - sign_transaction_params->fee_amount_length, sign_transaction_params->fee_amount, sign_transaction_params->fee_amount_length); - - // Erase values inherited from Exchange app - os_explicit_zero_BSS_segment(); - - // Keep the address at which we'll reply the signing status - G_swap_sign_return_value_address = &sign_transaction_params->result; - - // Copy from stack back to global data segment - memcpy(&vars.swap_data, &stack_data, sizeof(stack_data)); - return true; -} - -void handle_swap_sign_transaction(btchip_altcoin_config_t *config) { - G_coin_config = config; - btchip_context_init(); - btchip_context_D.called_from_swap = 1; - io_seproxyhal_init(); - UX_INIT(); -#ifdef HAVE_NBGL - nbgl_useCaseSpinner("Signing"); -#endif // HAVE_BAGL - USB_power(0); - USB_power(1); - //ui_idle(); - PRINTF("USB power ON/OFF\n"); -#ifdef TARGET_NANOX - // grab the current plane mode setting - G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0); -#endif // TARGET_NANOX -#ifdef HAVE_BLE - BLE_power(0, NULL); - BLE_power(1, "Nano X"); -#endif // HAVE_BLE - app_main(); -} - -void __attribute__((noreturn)) finalize_exchange_sign_transaction(bool is_success) { - *G_swap_sign_return_value_address = is_success; - os_lib_end(); -} diff --git a/src/handle_swap_sign_transaction.h b/src/handle_swap_sign_transaction.h deleted file mode 100644 index 85f5bd86..00000000 --- a/src/handle_swap_sign_transaction.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _HANDLE_SWAP_SIGN_TRANSACTION_H_ -#define _HANDLE_SWAP_SIGN_TRANSACTION_H_ - -#include "swap_lib_calls.h" -#include "btchip_context.h" - -bool copy_transaction_parameters(create_transaction_parameters_t* sign_transaction_params); - -void handle_swap_sign_transaction(btchip_altcoin_config_t *config); - -void __attribute__((noreturn)) finalize_exchange_sign_transaction(bool is_success); - -#endif // _HANDLE_SWAP_SIGN_TRANSACTION_H_ diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 449eea21..00000000 --- a/src/main.c +++ /dev/null @@ -1,1339 +0,0 @@ -/******************************************************************************* - * Ledger App - Bitcoin Wallet - * (c) 2016-2019 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#include "os.h" -#include "cx.h" - -#include "string.h" - -#include "btchip_internal.h" - -#include "btchip_bagl_extensions.h" - -#include "segwit_addr.h" -#include "cashaddr.h" - -#include "ux.h" -#include "btchip_display_variables.h" -#include "swap_lib_calls.h" - -#include "swap_lib_calls.h" -#include "handle_swap_sign_transaction.h" -#include "handle_get_printable_amount.h" -#include "handle_check_address.h" - -#define __NAME3(a, b, c) a##b##c -#define NAME3(a, b, c) __NAME3(a, b, c) - -bagl_element_t tmp_element; - -unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; - -void ui_idle(void); - -ux_state_t G_ux; -bolos_ux_params_t G_ux_params; - -unsigned int io_seproxyhal_touch_verify_cancel(const bagl_element_t *e) { - // user denied the transaction, tell the USB side - if (!btchip_bagl_user_action(0)) { - // redraw ui - ui_idle(); - } - return 0; // DO NOT REDRAW THE BUTTON -} - -unsigned int io_seproxyhal_touch_verify_ok(const bagl_element_t *e) { - // user accepted the transaction, tell the USB side - if (!btchip_bagl_user_action(1)) { - // redraw ui - ui_idle(); - } - return 0; // DO NOT REDRAW THE BUTTON -} - -unsigned int -io_seproxyhal_touch_message_signature_verify_cancel(const bagl_element_t *e) { - // user denied the transaction, tell the USB side - btchip_bagl_user_action_message_signing(0); - // redraw ui - ui_idle(); - return 0; // DO NOT REDRAW THE BUTTON -} - -unsigned int -io_seproxyhal_touch_message_signature_verify_ok(const bagl_element_t *e) { - // user accepted the transaction, tell the USB side - btchip_bagl_user_action_message_signing(1); - // redraw ui - ui_idle(); - return 0; // DO NOT REDRAW THE BUTTON -} - -unsigned int io_seproxyhal_touch_display_cancel(const bagl_element_t *e) { - // user denied the transaction, tell the USB side - btchip_bagl_user_action_display(0); - // redraw ui - ui_idle(); - return 0; // DO NOT REDRAW THE BUTTON -} - -unsigned int io_seproxyhal_touch_display_ok(const bagl_element_t *e) { - // user accepted the transaction, tell the USB side - btchip_bagl_user_action_display(1); - // redraw ui - ui_idle(); - return 0; // DO NOT REDRAW THE BUTTON -} - -unsigned int io_seproxyhal_touch_sign_cancel(const bagl_element_t *e) { - // user denied the transaction, tell the USB side - btchip_bagl_user_action_signtx(0, 0); - // redraw ui - ui_idle(); - return 0; // DO NOT REDRAW THE BUTTON -} - -unsigned int io_seproxyhal_touch_sign_ok(const bagl_element_t *e) { - // user accepted the transaction, tell the USB side - btchip_bagl_user_action_signtx(1, 0); - // redraw ui - ui_idle(); - return 0; // DO NOT REDRAW THE BUTTON -} - - -unsigned int io_seproxyhal_touch_display_token_cancel(const bagl_element_t *e) { - // revoke previous valid token if there was one - btchip_context_D.has_valid_token = false; - // user denied the token, tell the USB side - btchip_bagl_user_action_display(0); - // redraw ui - ui_idle(); - return 0; // DO NOT REDRAW THE BUTTON -} - -unsigned int io_seproxyhal_touch_display_token_ok(const bagl_element_t *e) { - // Set the valid token flag - btchip_context_D.has_valid_token = true; - // user approved the token, tell the USB side - btchip_bagl_user_action_display(1); - // redraw ui - ui_idle(); - return 0; // DO NOT REDRAW THE BUTTON -} - -const char* settings_submenu_getter(unsigned int idx); -void settings_submenu_selector(unsigned int idx); - - -void settings_pubkey_export_change(unsigned int enabled) { - nvm_write((void *)&N_btchip.pubKeyRequestRestriction, &enabled, 1); - ui_idle(); -} -////////////////////////////////////////////////////////////////////////////////////// -// Public keys export submenu: - -const char* const settings_pubkey_export_getter_values[] = { - "Auto Approval", - "Manual Approval", - "Back" -}; - -const char* settings_pubkey_export_getter(unsigned int idx) { - if (idx < ARRAYLEN(settings_pubkey_export_getter_values)) { - return settings_pubkey_export_getter_values[idx]; - } - return NULL; -} - -void settings_pubkey_export_selector(unsigned int idx) { - switch(idx) { - case 0: - settings_pubkey_export_change(0); - break; - case 1: - settings_pubkey_export_change(1); - break; - default: - ux_menulist_init(0, settings_submenu_getter, settings_submenu_selector); - } -} - -////////////////////////////////////////////////////////////////////////////////////// -// Settings menu: - -const char* const settings_submenu_getter_values[] = { - "Public keys export", - "Back", -}; - -const char* settings_submenu_getter(unsigned int idx) { - if (idx < ARRAYLEN(settings_submenu_getter_values)) { - return settings_submenu_getter_values[idx]; - } - return NULL; -} - -void settings_submenu_selector(unsigned int idx) { - switch(idx) { - case 0: - ux_menulist_init_select(0, settings_pubkey_export_getter, settings_pubkey_export_selector, N_btchip.pubKeyRequestRestriction); - break; - default: - ui_idle(); - } -} - -////////////////////////////////////////////////////////////////////// -UX_STEP_NOCB( - ux_idle_flow_1_step, - nn, - { - "Application", - "is ready", - }); -UX_STEP_CB( - ux_idle_flow_2_step, - pb, - ux_menulist_init(0, settings_submenu_getter, settings_submenu_selector), - { - &C_icon_coggle, - "Settings", - }); -UX_STEP_NOCB( - ux_idle_flow_3_step, - bn, - { - "Version", - APPVERSION, - }); -UX_STEP_CB( - ux_idle_flow_4_step, - pb, - os_sched_exit(-1), - { - &C_icon_dashboard_x, - "Quit", - }); -UX_FLOW(ux_idle_flow, - &ux_idle_flow_1_step, - &ux_idle_flow_2_step, - &ux_idle_flow_3_step, - &ux_idle_flow_4_step, - FLOW_LOOP -); - -////////////////////////////////////////////////////////////////////// -UX_STEP_NOCB( - ux_sign_flow_1_step, - pnn, - { - &C_icon_certificate, - "Sign", - "message", - }); -UX_STEP_NOCB( - ux_sign_flow_2_step, - bnnn_paging, - { - .title = "Message hash", - .text = vars.tmp.fullAddress, - }); -UX_STEP_CB( - ux_sign_flow_3_step, - pbb, - io_seproxyhal_touch_message_signature_verify_ok(NULL), - { - &C_icon_validate_14, - "Sign", - "message", - }); -UX_STEP_CB( - ux_sign_flow_4_step, - pbb, - io_seproxyhal_touch_message_signature_verify_cancel(NULL), - { - &C_icon_crossmark, - "Cancel", - "signature", - }); - -UX_FLOW(ux_sign_flow, - &ux_sign_flow_1_step, - &ux_sign_flow_2_step, - &ux_sign_flow_3_step, - &ux_sign_flow_4_step -); - -////////////////////////////////////////////////////////////////////// - -UX_STEP_NOCB(ux_confirm_full_flow_1_step, - pnn, - { - &C_icon_eye, - "Review", - "transaction", - }); -UX_STEP_NOCB( - ux_confirm_full_flow_2_step, - bnnn_paging, - { - .title = "Amount", - .text = vars.tmp.fullAmount - }); -UX_STEP_NOCB( - ux_confirm_full_flow_3_step, - bnnn_paging, - { - .title = "Address", - .text = vars.tmp.fullAddress, - }); -UX_STEP_NOCB( - ux_confirm_full_flow_4_step, - bnnn_paging, - { - .title = "Fees", - .text = vars.tmp.feesAmount, - }); -UX_STEP_CB( - ux_confirm_full_flow_5_step, - pbb, - io_seproxyhal_touch_verify_ok(NULL), - { - &C_icon_validate_14, - "Accept", - "and send", - }); -UX_STEP_CB( - ux_confirm_full_flow_6_step, - pb, - io_seproxyhal_touch_verify_cancel(NULL), - { - &C_icon_crossmark, - "Reject", - }); -// confirm_full: confirm transaction / Amount: fullAmount / Address: fullAddress / Fees: feesAmount -UX_FLOW(ux_confirm_full_flow, - &ux_confirm_full_flow_1_step, - &ux_confirm_full_flow_2_step, - &ux_confirm_full_flow_3_step, - &ux_confirm_full_flow_4_step, - &ux_confirm_full_flow_5_step, - &ux_confirm_full_flow_6_step -); - -////////////////////////////////////////////////////////////////////// - -UX_STEP_NOCB( - ux_confirm_single_flow_1_step, - pnn, - { - &C_icon_eye, - "Review", - vars.tmp.feesAmount, // output # - }); -UX_STEP_NOCB( - ux_confirm_single_flow_2_step, - bnnn_paging, - { - .title = "Amount", - .text = vars.tmp.fullAmount, - }); -UX_STEP_NOCB( - ux_confirm_single_flow_3_step, - bnnn_paging, - { - .title = "Address", - .text = vars.tmp.fullAddress, - }); -UX_STEP_CB( - ux_confirm_single_flow_5_step, - pb, - io_seproxyhal_touch_verify_ok(NULL), - { - &C_icon_validate_14, - "Accept", - }); -UX_STEP_CB( - ux_confirm_single_flow_6_step, - pb, - io_seproxyhal_touch_verify_cancel(NULL), - { - &C_icon_crossmark, - "Reject", - }); -// confirm_single: confirm output #x(feesAmount) / Amount: fullAmount / Address: fullAddress -UX_FLOW(ux_confirm_single_flow, - &ux_confirm_single_flow_1_step, - &ux_confirm_single_flow_2_step, - &ux_confirm_single_flow_3_step, - &ux_confirm_single_flow_5_step, - &ux_confirm_single_flow_6_step -); - -////////////////////////////////////////////////////////////////////// - -UX_STEP_NOCB( - ux_finalize_flow_1_step, - pnn, - { - &C_icon_eye, - "Confirm", - "transaction" - }); -UX_STEP_NOCB( - ux_finalize_flow_4_step, - bnnn_paging, - { - .title = "Fees", - .text = vars.tmp.feesAmount, - }); -UX_STEP_CB( - ux_finalize_flow_5_step, - pbb, - io_seproxyhal_touch_verify_ok(NULL), - { - &C_icon_validate_14, - "Accept", - "and send" - }); -UX_STEP_CB( - ux_finalize_flow_6_step, - pb, - io_seproxyhal_touch_verify_cancel(NULL), - { - &C_icon_crossmark, - "Reject", - }); -// finalize: confirm transaction / Fees: feesAmount -UX_FLOW(ux_finalize_flow, - &ux_finalize_flow_1_step, - &ux_finalize_flow_4_step, - &ux_finalize_flow_5_step, - &ux_finalize_flow_6_step -); - -////////////////////////////////////////////////////////////////////// -UX_STEP_NOCB( - ux_display_public_flow_1_step, - pnn, - { - &C_icon_warning, - "The derivation", - "path is unusual!", - }); -UX_STEP_NOCB( - ux_display_public_flow_2_step, - bnnn_paging, - { - .title = "Derivation path", - .text = vars.tmp_warning.derivation_path, - }); -UX_STEP_CB( - ux_display_public_flow_3_step, - pnn, - io_seproxyhal_touch_display_cancel(NULL), - { - &C_icon_crossmark, - "Reject if you're", - "not sure", - }); -UX_STEP_NOCB( - ux_display_public_flow_4_step, - pnn, - { - &C_icon_validate_14, - "Approve derivation", - "path", - }); -UX_STEP_NOCB( - ux_display_public_flow_5_step, - bnnn_paging, - { - .title = "Address", - .text = (char *)G_io_apdu_buffer+200, - }); -UX_STEP_CB( - ux_display_public_flow_6_step, - pb, - io_seproxyhal_touch_display_ok(NULL), - { - &C_icon_validate_14, - "Approve", - }); -UX_STEP_CB( - ux_display_public_flow_7_step, - pb, - io_seproxyhal_touch_display_cancel(NULL), - { - &C_icon_crossmark, - "Reject", - }); - -UX_FLOW(ux_display_public_with_warning_flow, - &ux_display_public_flow_1_step, - &ux_display_public_flow_2_step, - &ux_display_public_flow_3_step, - &ux_display_public_flow_4_step, - FLOW_BARRIER, - &ux_display_public_flow_5_step, - &ux_display_public_flow_6_step, - &ux_display_public_flow_7_step -); - -UX_FLOW(ux_display_public_flow, - &ux_display_public_flow_5_step, - &ux_display_public_flow_6_step, - &ux_display_public_flow_7_step -); - - -////////////////////////////////////////////////////////////////////// -UX_STEP_CB( - ux_display_token_flow_1_step, - pbb, - io_seproxyhal_touch_display_ok(NULL), - { - &C_icon_validate_14, - "Confirm token", - (char *)G_io_apdu_buffer+200, - }); -UX_STEP_CB( - ux_display_token_flow_2_step, - pb, - io_seproxyhal_touch_display_cancel(NULL), - { - &C_icon_crossmark, - "Reject", - }); - -UX_FLOW(ux_display_token_flow, - &ux_display_token_flow_1_step, - &ux_display_token_flow_2_step -); - -////////////////////////////////////////////////////////////////////// -UX_STEP_CB( - ux_request_pubkey_approval_flow_1_step, - pbb, - io_seproxyhal_touch_display_ok(NULL), - { - &C_icon_validate_14, - "Export", - "public key?", - }); -UX_STEP_CB( - ux_request_pubkey_approval_flow_2_step, - pb, - io_seproxyhal_touch_display_cancel(NULL), - { - &C_icon_crossmark, - "Reject", - }); - -UX_FLOW(ux_request_pubkey_approval_flow, - &ux_request_pubkey_approval_flow_1_step, - &ux_request_pubkey_approval_flow_2_step -); - -////////////////////////////////////////////////////////////////////// -UX_STEP_NOCB( - ux_request_change_path_approval_flow_1_step, - pbb, - { - &C_icon_eye, - "The change path", - "is unusual", - }); -UX_STEP_NOCB( - ux_request_change_path_approval_flow_2_step, - bnnn_paging, - { - .title = "Change path", - .text = vars.tmp_warning.derivation_path, - }); -UX_STEP_CB( - ux_request_change_path_approval_flow_3_step, - pbb, - io_seproxyhal_touch_display_cancel(NULL), - { - &C_icon_crossmark, - "Reject if you're", - "not sure", - }); -UX_STEP_CB( - ux_request_change_path_approval_flow_4_step, - pb, - io_seproxyhal_touch_display_ok(NULL), - { - &C_icon_validate_14, - "Approve", - }); - -UX_FLOW(ux_request_change_path_approval_flow, - &ux_request_change_path_approval_flow_1_step, - &ux_request_change_path_approval_flow_2_step, - &ux_request_change_path_approval_flow_3_step, - &ux_request_change_path_approval_flow_4_step -); - -////////////////////////////////////////////////////////////////////// -UX_STEP_NOCB( - ux_request_sign_path_approval_flow_1_step, - pbb, - { - &C_icon_eye, - "The sign path", - "is unusual", - }); -UX_STEP_NOCB( - ux_request_sign_path_approval_flow_2_step, - bnnn_paging, - { - .title = "Sign path", - .text = vars.tmp_warning.derivation_path, - }); -UX_STEP_CB( - ux_request_sign_path_approval_flow_3_step, - pbb, - io_seproxyhal_touch_sign_cancel(NULL), - { - &C_icon_crossmark, - "Reject if you're", - "not sure", - }); -UX_STEP_CB( - ux_request_sign_path_approval_flow_4_step, - pb, - io_seproxyhal_touch_sign_ok(NULL), - { - &C_icon_validate_14, - "Approve", - }); - -UX_FLOW(ux_request_sign_path_approval_flow, - &ux_request_sign_path_approval_flow_1_step, - &ux_request_sign_path_approval_flow_2_step, - &ux_request_sign_path_approval_flow_3_step, - &ux_request_sign_path_approval_flow_4_step -); - - -////////////////////////////////////////////////////////////////////// -UX_STEP_NOCB( - ux_request_segwit_input_approval_flow_1_step, - pb, - { - .icon = &C_icon_warning, - .line1 = "Unverified inputs" - }); -UX_STEP_NOCB( - ux_request_segwit_input_approval_flow_2_step, - nn, - { - .line1 = "Update", - .line2 = " Ledger Live" - }); -UX_STEP_NOCB( - ux_request_segwit_input_approval_flow_3_step, - nn - , - { - .line1 = "or third party", - .line2 = "wallet software" - }); -UX_STEP_CB( - ux_request_segwit_input_approval_flow_4_step, - pb, - io_seproxyhal_touch_display_cancel(NULL), - { - .icon = &C_icon_crossmark, - .line1 = "Cancel" - }); -UX_STEP_CB( - ux_request_segwit_input_approval_flow_5_step, - pb, - io_seproxyhal_touch_display_ok(NULL), - { - &C_icon_validate_14, - "Continue" - }); - -UX_FLOW(ux_request_segwit_input_approval_flow, - &ux_request_segwit_input_approval_flow_1_step, - &ux_request_segwit_input_approval_flow_2_step, - &ux_request_segwit_input_approval_flow_3_step, - &ux_request_segwit_input_approval_flow_4_step, - &ux_request_segwit_input_approval_flow_5_step -); - - -void ui_idle(void) { - // reserve a display stack slot if none yet - if(G_ux.stack_count == 0) { - ux_stack_push(); - } - ux_flow_init(0, ux_idle_flow, NULL); -} - -// override point, but nothing more to do -void io_seproxyhal_display(const bagl_element_t *element) { - if ((element->component.type & (~BAGL_TYPE_FLAGS_MASK)) != BAGL_NONE) { - io_seproxyhal_display_default((bagl_element_t *)element); - } -} - -unsigned short io_exchange_al(unsigned char channel, unsigned short tx_len) { - switch (channel & ~(IO_FLAGS)) { - case CHANNEL_KEYBOARD: - break; - - // multiplexed io exchange over a SPI channel and TLV encapsulated protocol - case CHANNEL_SPI: - if (tx_len) { - io_seproxyhal_spi_send(G_io_apdu_buffer, tx_len); - - if (channel & IO_RESET_AFTER_REPLIED) { - reset(); - } - return 0; // nothing received from the master so far (it's a tx - // transaction) - } else { - return io_seproxyhal_spi_recv(G_io_apdu_buffer, - sizeof(G_io_apdu_buffer), 0); - } - - default: - THROW(INVALID_PARAMETER); - } - return 0; -} - -unsigned char io_event(unsigned char channel) { - // nothing done with the event, throw an error on the transport layer if - // needed - - // can't have more than one tag in the reply, not supported yet. - switch (G_io_seproxyhal_spi_buffer[0]) { - case SEPROXYHAL_TAG_FINGER_EVENT: - UX_FINGER_EVENT(G_io_seproxyhal_spi_buffer); - break; - - case SEPROXYHAL_TAG_BUTTON_PUSH_EVENT: - UX_BUTTON_PUSH_EVENT(G_io_seproxyhal_spi_buffer); - break; - - case SEPROXYHAL_TAG_STATUS_EVENT: - if (G_io_apdu_media == IO_APDU_MEDIA_USB_HID && - !(U4BE(G_io_seproxyhal_spi_buffer, 3) & - SEPROXYHAL_TAG_STATUS_EVENT_FLAG_USB_POWERED)) { - THROW(EXCEPTION_IO_RESET); - } - // no break is intentional - default: - UX_DEFAULT_EVENT(); - break; - - case SEPROXYHAL_TAG_DISPLAY_PROCESSED_EVENT: - UX_DISPLAYED_EVENT({}); - break; - - case SEPROXYHAL_TAG_TICKER_EVENT: - // TODO: found less hacky way to exit library after sending response - // this mechanism is used for Swap/Exchange functionality - // when application is in silent mode, and should return to caller, - // after responding some APDUs - UX_TICKER_EVENT(G_io_seproxyhal_spi_buffer, {}); - break; - } - - // close the event if not done previously (by a display or whatever) - if (!io_seproxyhal_spi_is_status_sent()) { - io_seproxyhal_general_status(); - } - - // command has been processed, DO NOT reset the current APDU transport - return 1; -} - -uint8_t check_fee_swap() { - unsigned char fees[8]; - unsigned char borrow; - - borrow = transaction_amount_sub_be( - fees, btchip_context_D.transactionContext.transactionAmount, - btchip_context_D.totalOutputAmount); - if ((borrow != 0) || (memcmp(fees, vars.swap_data.fees, 8) != 0)) - return 0; - btchip_context_D.transactionContext.firstSigned = 0; - - if (btchip_context_D.usingSegwit && !btchip_context_D.segwitParsedOnce) { - // This input cannot be signed when using segwit - just restart. - btchip_context_D.segwitParsedOnce = 1; - PRINTF("Segwit parsed once\n"); - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - } else { - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_SIGN_READY; - } - btchip_context_D.sw = 0x9000; - btchip_context_D.outLength = 0; - G_io_apdu_buffer[btchip_context_D.outLength++] = 0x90; - G_io_apdu_buffer[btchip_context_D.outLength++] = 0x00; - - return 1; -} - -uint8_t prepare_fees() { - if (btchip_context_D.transactionContext.relaxed) { - os_memmove(vars.tmp.feesAmount, "UNKNOWN", 7); - vars.tmp.feesAmount[7] = '\0'; - } else { - unsigned char fees[8]; - unsigned short textSize; - unsigned char borrow; - - borrow = transaction_amount_sub_be( - fees, btchip_context_D.transactionContext.transactionAmount, - btchip_context_D.totalOutputAmount); - if (borrow && G_coin_config->kind == COIN_KIND_KOMODO) { - os_memmove(vars.tmp.feesAmount, "REWARD", 6); - vars.tmp.feesAmount[6] = '\0'; - } - else { - if (borrow) { - PRINTF("Error : Fees not consistent"); - goto error; - } - os_memmove(vars.tmp.feesAmount, G_coin_config->name_short, - strlen(G_coin_config->name_short)); - vars.tmp.feesAmount[strlen(G_coin_config->name_short)] = ' '; - btchip_context_D.tmp = - (unsigned char *)(vars.tmp.feesAmount + - strlen(G_coin_config->name_short) + 1); - textSize = btchip_convert_hex_amount_to_displayable(fees); - vars.tmp.feesAmount[textSize + strlen(G_coin_config->name_short) + 1] = - '\0'; - } - } - return 1; -error: - return 0; -} - -#define OMNI_ASSETID 1 -#define MAIDSAFE_ASSETID 3 -#define USDT_ASSETID 31 - -void get_address_from_output_script(unsigned char* script, int script_size, char* out, int out_size) { - if (btchip_output_script_is_op_return(script)) { - strcpy(out, "OP_RETURN"); - return; - } - if ((G_coin_config->kind == COIN_KIND_QTUM || G_coin_config->kind == COIN_KIND_HYDRA) && - btchip_output_script_is_op_create(script, script_size)) { - strcpy(out, "OP_CREATE"); - return; - } - if ((G_coin_config->kind == COIN_KIND_QTUM || G_coin_config->kind == COIN_KIND_HYDRA) && - btchip_output_script_is_op_call(script, script_size)) { - strcpy(out, "OP_CALL"); - return; - } - if (btchip_output_script_is_native_witness(script)) { - if (G_coin_config->native_segwit_prefix) { - segwit_addr_encode( - out, (char *)PIC(G_coin_config->native_segwit_prefix), 0, - script + OUTPUT_SCRIPT_NATIVE_WITNESS_PROGRAM_OFFSET, - script[OUTPUT_SCRIPT_NATIVE_WITNESS_PROGRAM_OFFSET - 1]); - } - return; - } - unsigned char versionSize; - unsigned char address[22]; - unsigned short textSize; - int addressOffset = 3; - unsigned short version = G_coin_config->p2sh_version; - - if (btchip_output_script_is_regular(script)) { - addressOffset = 4; - version = G_coin_config->p2pkh_version; - } - - if (version > 255) { - versionSize = 2; - address[0] = (version >> 8); - address[1] = version; - } else { - versionSize = 1; - address[0] = version; - } - os_memmove(address + versionSize, script + addressOffset, 20); - - // Prepare address - if (btchip_context_D.usingCashAddr) { - cashaddr_encode( - address + versionSize, 20, (uint8_t *)out, out_size, - (version == G_coin_config->p2sh_version - ? CASHADDR_P2SH - : CASHADDR_P2PKH)); - } else { - textSize = btchip_public_key_to_encoded_base58( - address, 20 + versionSize, (unsigned char *)out, - out_size, version, 1); - out[textSize] = '\0'; - } -} - -uint8_t prepare_single_output() { - // TODO : special display for OP_RETURN - unsigned char amount[8]; - unsigned int offset = 0; - unsigned short textSize; - char tmp[80] = {0}; - - btchip_swap_bytes(amount, btchip_context_D.currentOutput + offset, 8); - offset += 8; - - get_address_from_output_script(btchip_context_D.currentOutput + offset, sizeof(btchip_context_D.currentOutput) - offset, tmp, sizeof(tmp)); - strncpy(vars.tmp.fullAddress, tmp, sizeof(vars.tmp.fullAddress) - 1); - - // Prepare amount - - // Handle Omni simple send - if ((btchip_context_D.currentOutput[offset + 2] == 0x14) && - (os_memcmp(btchip_context_D.currentOutput + offset + 3, "omni", 4) == 0) && - (os_memcmp(btchip_context_D.currentOutput + offset + 3 + 4, "\0\0\0\0", 4) == 0)) { - uint8_t headerLength; - uint32_t omniAssetId = btchip_read_u32(btchip_context_D.currentOutput + offset + 3 + 4 + 4, 1, 0); - switch(omniAssetId) { - case OMNI_ASSETID: - strcpy(vars.tmp.fullAmount, "OMNI "); - break; - case USDT_ASSETID: - strcpy(vars.tmp.fullAmount, "USDT "); - break; - case MAIDSAFE_ASSETID: - strcpy(vars.tmp.fullAmount, "MAID "); - break; - default: - snprintf(vars.tmp.fullAmount, sizeof(vars.tmp.fullAmount), "OMNI asset %d ", omniAssetId); - break; - } - headerLength = strlen(vars.tmp.fullAmount); - btchip_context_D.tmp = (uint8_t *)vars.tmp.fullAmount + headerLength; - textSize = btchip_convert_hex_amount_to_displayable(btchip_context_D.currentOutput + offset + 3 + 4 + 4 + 4); - vars.tmp.fullAmount[textSize + headerLength] = '\0'; - } - else { - os_memmove(vars.tmp.fullAmount, G_coin_config->name_short, - strlen(G_coin_config->name_short)); - vars.tmp.fullAmount[strlen(G_coin_config->name_short)] = ' '; - btchip_context_D.tmp = - (unsigned char *)(vars.tmp.fullAmount + - strlen(G_coin_config->name_short) + 1); - textSize = btchip_convert_hex_amount_to_displayable(amount); - vars.tmp.fullAmount[textSize + strlen(G_coin_config->name_short) + 1] = - '\0'; - } - - return 1; -} - -uint8_t prepare_message_signature() { - uint8_t buffer[32]; - - cx_hash(&btchip_context_D.transactionHashAuthorization.header, CX_LAST, - (uint8_t*)vars.tmp.fullAmount, 0, buffer, 32); - - snprintf(vars.tmp.fullAddress, sizeof(vars.tmp.fullAddress), "%.*H", buffer); - return 1; -} - - -extern bool handle_output_state(); -extern void btchip_apdu_hash_input_finalize_full_reset(void); - -// Analog of btchip_bagl_confirm_single_output to work -// in silent mode, when called from SWAP app -unsigned int btchip_silent_confirm_single_output() { - char tmp[80] = {0}; - unsigned char amount[8]; - while (true) { - // in swap operation we can only have 1 "external" output - if (vars.swap_data.was_address_checked) { - PRINTF("Address was already checked\n"); - return 0; - } - vars.swap_data.was_address_checked = 1; - // check amount - btchip_swap_bytes(amount, btchip_context_D.currentOutput, 8); - if (memcmp(amount, vars.swap_data.amount, 8) != 0) { - PRINTF("Amount not matched\n"); - return 0; - } - get_address_from_output_script(btchip_context_D.currentOutput + 8, sizeof(btchip_context_D.currentOutput) - 8, tmp, sizeof(tmp)); - if (strcmp(tmp, vars.swap_data.destination_address) != 0) { - PRINTF("Address not matched\n"); - return 0; - } - - // Check if all inputs have been confirmed - - if (btchip_context_D.outputParsingState == - BTCHIP_OUTPUT_PARSING_OUTPUT) { - btchip_context_D.remainingOutputs--; - if (btchip_context_D.remainingOutputs == 0) - break; - } - - os_memmove(btchip_context_D.currentOutput, - btchip_context_D.currentOutput + - btchip_context_D.discardSize, - btchip_context_D.currentOutputOffset - - btchip_context_D.discardSize); - btchip_context_D.currentOutputOffset -= btchip_context_D.discardSize; - btchip_context_D.io_flags &= ~IO_ASYNCH_REPLY; - while (handle_output_state() && - (!(btchip_context_D.io_flags & IO_ASYNCH_REPLY))) - ; - if (!(btchip_context_D.io_flags & IO_ASYNCH_REPLY)) { - // Out of data to process, wait for the next call - break; - } - } - - if ((btchip_context_D.outputParsingState == BTCHIP_OUTPUT_PARSING_OUTPUT) && - (btchip_context_D.remainingOutputs == 0)) { - btchip_context_D.outputParsingState = BTCHIP_OUTPUT_FINALIZE_TX; - // check fees - unsigned char fees[8]; - - if ((transaction_amount_sub_be(fees, - btchip_context_D.transactionContext.transactionAmount, - btchip_context_D.totalOutputAmount) != 0) || - (memcmp(fees, vars.swap_data.fees, 8) != 0)) { - PRINTF("Fees is not matched\n"); - return 0; - } - } - - if (btchip_context_D.outputParsingState == BTCHIP_OUTPUT_FINALIZE_TX) { - btchip_context_D.transactionContext.firstSigned = 0; - - if (btchip_context_D.usingSegwit && - !btchip_context_D.segwitParsedOnce) { - // This input cannot be signed when using segwit - just restart. - btchip_context_D.segwitParsedOnce = 1; - PRINTF("Segwit parsed once\n"); - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_NONE; - } else { - btchip_context_D.transactionContext.transactionState = - BTCHIP_TRANSACTION_SIGN_READY; - } - } - if (btchip_context_D.outputParsingState == BTCHIP_OUTPUT_FINALIZE_TX) { - // we've finished the processing of the input - btchip_apdu_hash_input_finalize_full_reset(); - } - - return 1; -} - -unsigned int btchip_bagl_confirm_single_output() { - if (btchip_context_D.called_from_swap) { - return btchip_silent_confirm_single_output(); - } - if (!prepare_single_output()) { - return 0; - } - - snprintf(vars.tmp.feesAmount, sizeof(vars.tmp.feesAmount), "output #%d", - btchip_context_D.totalOutputs - btchip_context_D.remainingOutputs + - 1); - - ux_flow_init(0, ux_confirm_single_flow, NULL); - return 1; -} - -unsigned int btchip_bagl_finalize_tx() { - if (btchip_context_D.called_from_swap) { - return check_fee_swap(); - } - - if (!prepare_fees()) { - return 0; - } - - ux_flow_init(0, ux_finalize_flow, NULL); - return 1; -} - -void btchip_bagl_confirm_message_signature() { - if (!prepare_message_signature()) { - return; - } - - ux_flow_init(0, ux_sign_flow, NULL); -} - -uint8_t set_key_path_to_display(unsigned char* keyPath) { - bip32_print_path(keyPath, vars.tmp_warning.derivation_path, MAX_DERIV_PATH_ASCII_LENGTH); - return bip44_derivation_guard(keyPath, false); -} - -void btchip_bagl_display_public_key(uint8_t is_derivation_path_unusual) { - // append a white space at the end of the address to avoid glitch on nano S - strcat((char *)G_io_apdu_buffer + 200, " "); - - ux_flow_init(0, is_derivation_path_unusual?ux_display_public_with_warning_flow:ux_display_public_flow, NULL); -} - -void btchip_bagl_display_token() -{ - ux_flow_init(0, ux_display_token_flow, NULL); -} - -void btchip_bagl_request_pubkey_approval() -{ - ux_flow_init(0, ux_request_pubkey_approval_flow, NULL); -} - -void btchip_bagl_request_change_path_approval(unsigned char* change_path) -{ - bip32_print_path(change_path, vars.tmp_warning.derivation_path, sizeof(vars.tmp_warning.derivation_path)); - ux_flow_init(0, ux_request_change_path_approval_flow, NULL); -} - -void btchip_bagl_request_sign_path_approval(unsigned char* change_path) -{ - bip32_print_path(change_path, vars.tmp_warning.derivation_path, sizeof(vars.tmp_warning.derivation_path)); - ux_flow_init(0, ux_request_sign_path_approval_flow, NULL); -} - -void btchip_bagl_request_segwit_input_approval() -{ - ux_flow_init(0, ux_request_segwit_input_approval_flow, NULL); -} - - - -void app_exit(void) { - BEGIN_TRY_L(exit) { - TRY_L(exit) { - os_sched_exit(-1); - } - FINALLY_L(exit) { - } - } - END_TRY_L(exit); -} - -void init_coin_config(btchip_altcoin_config_t *coin_config) { - os_memset(coin_config, 0, sizeof(btchip_altcoin_config_t)); - coin_config->bip44_coin_type = BIP44_COIN_TYPE; - coin_config->bip44_coin_type2 = BIP44_COIN_TYPE_2; - coin_config->p2pkh_version = COIN_P2PKH_VERSION; - coin_config->p2sh_version = COIN_P2SH_VERSION; - coin_config->family = COIN_FAMILY; - strcpy(coin_config->coinid, COIN_COINID); - strcpy(coin_config->name, COIN_COINID_NAME); - strcpy(coin_config->name_short, COIN_COINID_SHORT); -#ifdef COIN_NATIVE_SEGWIT_PREFIX - strcpy(coin_config->native_segwit_prefix_val, COIN_NATIVE_SEGWIT_PREFIX); - coin_config->native_segwit_prefix = coin_config->native_segwit_prefix_val; -#else - coin_config->native_segwit_prefix = 0; -#endif // #ifdef COIN_NATIVE_SEGWIT_PREFIX -#ifdef COIN_FORKID - coin_config->forkid = COIN_FORKID; -#endif // COIN_FORKID -#ifdef COIN_CONSENSUS_BRANCH_ID - coin_config->zcash_consensus_branch_id = COIN_CONSENSUS_BRANCH_ID; -#endif // COIN_CONSENSUS_BRANCH_ID -#ifdef COIN_FLAGS - coin_config->flags = COIN_FLAGS; -#endif // COIN_FLAGS - coin_config->kind = COIN_KIND; -} - -void coin_main(btchip_altcoin_config_t *coin_config) { - btchip_altcoin_config_t config; - if (coin_config == NULL) { - init_coin_config(&config); - G_coin_config = &config; - } else { - G_coin_config = coin_config; - } - - for (;;) { - UX_INIT(); - BEGIN_TRY { - TRY { - io_seproxyhal_init(); - -#ifdef TARGET_NANOX - // grab the current plane mode setting - G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0); -#endif // TARGET_NANOX - - btchip_context_init(); - - USB_power(0); - USB_power(1); - - ui_idle(); - -#ifdef HAVE_BLE - BLE_power(0, NULL); - BLE_power(1, "Nano X"); -#endif // HAVE_BLE - - app_main(); - } - CATCH(EXCEPTION_IO_RESET) { - // reset IO and UX - CLOSE_TRY; - continue; - } - CATCH_ALL { - CLOSE_TRY; - break; - } - FINALLY { - } - } - END_TRY; - } - app_exit(); -} - -static void library_main_helper(libargs_t *args) { - PRINTF("Inside a library \n"); - switch (args->command) { - case CHECK_ADDRESS: - // ensure result is zero if an exception is thrown - args->check_address->result = 0; - args->check_address->result = - handle_check_address(args->check_address, args->coin_config); - break; - case SIGN_TRANSACTION: - if (copy_transaction_parameters(args->create_transaction)) { - // never returns - handle_swap_sign_transaction(args->coin_config); - } - break; - case GET_PRINTABLE_AMOUNT: - handle_get_printable_amount(args->get_printable_amount, args->coin_config); - break; - default: - break; - } -} - -void library_main(libargs_t *args) { - btchip_altcoin_config_t coin_config; - if (args->coin_config == NULL) { - init_coin_config(&coin_config); - args->coin_config = &coin_config; - } - bool end = false; - /* This loop ensures that library_main_helper and os_lib_end are called - * within a try context, even if an exception is thrown */ - while (1) { - BEGIN_TRY { - TRY { - if (!end) { - library_main_helper(args); - } - os_lib_end(); - } - FINALLY { - end = true; - } - } - END_TRY; - } -} - -__attribute__((section(".boot"))) int main(int arg0) { -#ifdef USE_LIB_BITCOIN - BEGIN_TRY { - TRY { - unsigned int libcall_params[5]; - btchip_altcoin_config_t coin_config; - init_coin_config(&coin_config); - PRINTF("Hello from litecoin\n"); - check_api_level(CX_COMPAT_APILEVEL); - // delegate to bitcoin app/lib - libcall_params[0] = "Bitcoin Legacy"; - libcall_params[1] = 0x100; - libcall_params[2] = RUN_APPLICATION; - libcall_params[3] = &coin_config; - libcall_params[4] = 0; - if (arg0) { - // call as a library - libcall_params[2] = ((unsigned int *)arg0)[1]; - libcall_params[4] = ((unsigned int *)arg0)[3]; // library arguments - os_lib_call(&libcall_params); - ((unsigned int *)arg0)[0] = libcall_params[1]; - os_lib_end(); - } - else { - // launch coin application - os_lib_call(&libcall_params); - } - } - FINALLY {} - } - END_TRY; - // no return -#else - // exit critical section - __asm volatile("cpsie i"); - - // ensure exception will work as planned - os_boot(); - - if (!arg0) { - // Bitcoin application launched from dashboard - coin_main(NULL); - return 0; - } - libargs_t *args = (libargs_t *) arg0; - if (args->id != 0x100) { - app_exit(); - return 0; - } - switch (args->command) { - case RUN_APPLICATION: - // coin application launched from dashboard - if (args->coin_config == NULL) - app_exit(); - else - coin_main(args->coin_config); - break; - default: - // called as bitcoin or altcoin library - library_main(args); - } -#endif // USE_LIB_BITCOIN - return 0; -} diff --git a/src/segwit_addr.c b/src/segwit_addr.c deleted file mode 100644 index 95c37e8e..00000000 --- a/src/segwit_addr.c +++ /dev/null @@ -1,204 +0,0 @@ -/* Copyright (c) 2017 Pieter Wuille - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include - -#include "segwit_addr.h" - -uint32_t bech32_polymod_step(uint32_t pre) { - uint8_t b = pre >> 25; - return ((pre & 0x1FFFFFF) << 5) ^ (-((b >> 0) & 1) & 0x3b6a57b2UL) ^ - (-((b >> 1) & 1) & 0x26508e6dUL) ^ (-((b >> 2) & 1) & 0x1ea119faUL) ^ - (-((b >> 3) & 1) & 0x3d4233ddUL) ^ (-((b >> 4) & 1) & 0x2a1462b3UL); -} - -static const char *charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; - -static const int8_t charset_rev[128] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, 10, 17, 21, 20, 26, 30, 7, - 5, -1, -1, -1, -1, -1, -1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, - 31, 27, 19, -1, 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, - -1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, 1, 0, - 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1}; - -int bech32_encode(char *output, const char *hrp, const uint8_t *data, - size_t data_len) { - uint32_t chk = 1; - size_t i = 0; - while (hrp[i] != 0) { - if (hrp[i] >= 'A' && hrp[i] <= 'Z') - return 0; - if (!(hrp[i] >> 5)) - return 0; - chk = bech32_polymod_step(chk) ^ (hrp[i] >> 5); - ++i; - } - if (i + 7 + data_len > 90) - return 0; - chk = bech32_polymod_step(chk); - while (*hrp != 0) { - chk = bech32_polymod_step(chk) ^ (*hrp & 0x1f); - *(output++) = *(hrp++); - } - *(output++) = '1'; - for (i = 0; i < data_len; ++i) { - if (*data >> 5) - return 0; - chk = bech32_polymod_step(chk) ^ (*data); - *(output++) = charset[*(data++)]; - } - for (i = 0; i < 6; ++i) { - chk = bech32_polymod_step(chk); - } - chk ^= 1; - for (i = 0; i < 6; ++i) { - *(output++) = charset[(chk >> ((5 - i) * 5)) & 0x1f]; - } - *output = 0; - return 1; -} - -int bech32_decode(char *hrp, uint8_t *data, size_t *data_len, - const char *input) { - uint32_t chk = 1; - size_t i; - size_t input_len = strlen(input); - size_t hrp_len; - int have_lower = 0, have_upper = 0; - if (input_len < 8 || input_len > 90) { - return 0; - } - *data_len = 0; - while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') { - ++(*data_len); - } - hrp_len = input_len - (1 + *data_len); - if (hrp_len < 1 || *data_len < 6) { - return 0; - } - *(data_len) -= 6; - for (i = 0; i < hrp_len; ++i) { - int ch = input[i]; - if (ch < 33 || ch > 126) { - return 0; - } - if (ch >= 'a' && ch <= 'z') { - have_lower = 1; - } else if (ch >= 'A' && ch <= 'Z') { - have_upper = 1; - ch = (ch - 'A') + 'a'; - } - hrp[i] = ch; - chk = bech32_polymod_step(chk) ^ (ch >> 5); - } - hrp[i] = 0; - chk = bech32_polymod_step(chk); - for (i = 0; i < hrp_len; ++i) { - chk = bech32_polymod_step(chk) ^ (input[i] & 0x1f); - } - ++i; - while (i < input_len) { - int v = (input[i] & 0x80) ? -1 : charset_rev[(int)input[i]]; - if (input[i] >= 'a' && input[i] <= 'z') - have_lower = 1; - if (input[i] >= 'A' && input[i] <= 'Z') - have_upper = 1; - if (v == -1) { - return 0; - } - chk = bech32_polymod_step(chk) ^ v; - if (i + 6 < input_len) { - data[i - (1 + hrp_len)] = v; - } - ++i; - } - if (have_lower && have_upper) { - return 0; - } - return chk == 1; -} - -static int convert_bits(uint8_t *out, size_t *outlen, int outbits, - const uint8_t *in, size_t inlen, int inbits, int pad) { - uint32_t val = 0; - int bits = 0; - uint32_t maxv = (((uint32_t)1) << outbits) - 1; - while (inlen--) { - val = (val << inbits) | *(in++); - bits += inbits; - while (bits >= outbits) { - bits -= outbits; - out[(*outlen)++] = (val >> bits) & maxv; - } - } - if (pad) { - if (bits) { - out[(*outlen)++] = (val << (outbits - bits)) & maxv; - } - } else if (((val << (outbits - bits)) & maxv) || bits >= inbits) { - return 0; - } - return 1; -} - -int segwit_addr_encode(char *output, const char *hrp, int witver, - const uint8_t *witprog, size_t witprog_len) { - uint8_t data[65]; - size_t datalen = 0; - if (witver > 16) - return 0; - if (witver == 0 && witprog_len != 20 && witprog_len != 32) - return 0; - if (witprog_len < 2 || witprog_len > 40) - return 0; - data[0] = witver; - convert_bits(data + 1, &datalen, 5, witprog, witprog_len, 8, 1); - ++datalen; - return bech32_encode(output, hrp, data, datalen); -} - -int segwit_addr_decode(int *witver, uint8_t *witdata, size_t *witdata_len, - const char *hrp, const char *addr) { - uint8_t data[84]; - char hrp_actual[84]; - size_t data_len; - if (!bech32_decode(hrp_actual, data, &data_len, addr)) - return 0; - if (data_len == 0 || data_len > 65) - return 0; - if (strncmp(hrp, hrp_actual, 84) != 0) - return 0; - if (data[0] > 16) - return 0; - *witdata_len = 0; - if (!convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) - return 0; - if (*witdata_len < 2 || *witdata_len > 40) - return 0; - if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) - return 0; - *witver = data[0]; - return 1; -} diff --git a/src/segwit_addr.h b/src/segwit_addr.h deleted file mode 100644 index d86e203c..00000000 --- a/src/segwit_addr.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2017 Pieter Wuille - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef _SEGWIT_ADDR_H_ -#define _SEGWIT_ADDR_H_ - -#include - -/** Encode a SegWit address - * - * Out: output: Pointer to a buffer of size 73 + strlen(hrp) that will be - * updated to contain the null-terminated address. - * In: hrp: Pointer to the null-terminated human readable part to use - * (chain/network specific). - * ver: Version of the witness program (between 0 and 16 inclusive). - * prog: Data bytes for the witness program (between 2 and 40 bytes). - * prog_len: Number of data bytes in prog. - * Returns 1 if successful. - */ -int segwit_addr_encode(char *output, const char *hrp, int ver, - const uint8_t *prog, size_t prog_len); - -/** Decode a SegWit address - * - * Out: ver: Pointer to an int that will be updated to contain the witness - * program version (between 0 and 16 inclusive). - * prog: Pointer to a buffer of size 40 that will be updated to - * contain the witness program bytes. - * prog_len: Pointer to a size_t that will be updated to contain the - * length - * of bytes in prog. - * hrp: Pointer to the null-terminated human readable part that is - * expected (chain/network specific). - * addr: Pointer to the null-terminated address. - * Returns 1 if successful. - */ -int segwit_addr_decode(int *ver, uint8_t *prog, size_t *prog_len, - const char *hrp, const char *addr); - -/** Encode a Bech32 string - * - * Out: output: Pointer to a buffer of size strlen(hrp) + data_len + 8 that - * will be updated to contain the null-terminated Bech32 string. - * In: hrp : Pointer to the null-terminated human readable part. - * data : Pointer to an array of 5-bit values. - * data_len: Length of the data array. - * Returns 1 if successful. - */ -int bech32_encode(char *output, const char *hrp, const uint8_t *data, - size_t data_len); - -/** Decode a Bech32 string - * - * Out: hrp: Pointer to a buffer of size strlen(input) - 6. Will be - * updated to contain the null-terminated human readable part. - * data: Pointer to a buffer of size strlen(input) - 8 that will - * hold the encoded 5-bit data values. - * data_len: Pointer to a size_t that will be updated to be the number - * of entries in data. - * In: input: Pointer to a null-terminated Bech32 string. - * Returns 1 if succesful. - */ -int bech32_decode(char *hrp, uint8_t *data, size_t *data_len, - const char *input); - -#endif /* _SEGWIT_ADDR_H_ */ diff --git a/tests/README.md b/tests/README.md index 9e6f179f..54a2b9dc 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,8 +1,8 @@ # End-to-end tests using Bitcoin Testnet -These tests are implemented in Python and can be executed either using the [Speculos](https://github.com/LedgerHQ/speculos) emulator or a Ledger Nano S/X. +These tests are implemented in Python and can be executed either using the [Speculos](https://github.com/LedgerHQ/speculos) emulator or a Ledger device -All the commands in this folder are meant to be ran from the `tests` folder, not from the root. +All the commands in this folder are meant to be ran from the root. Python dependencies are listed in [requirements.txt](requirements.txt), install them using [pip](https://pypi.org/project/pip/) @@ -12,38 +12,20 @@ pip install -r requirements.txt ## Launch with Speculos -In order to create the necessary binaries for the Bitcoin Testnet application, you can use the convenience script `prepare_tests.sh`: - -``` -bash ./prepare_tests.sh -``` +In order to create the necessary binaries for the Bitcoin Testnet application, you can must first compile the binairies Then run all the tests using: ``` -pytest -``` - -You can delete the test binaries with - -``` -bash ./clean_tests.sh +pytest --device all ``` ## Launch with your Nano S/X Compile and install the app on your device as normal. -To run the tests on your Ledger Nano S/X you also need to install an optional dependency - -``` -pip install ledgercomm[hid] -``` - Be sure to have you device connected through USB (without any other software interacting with it) and run ``` -pytest --hid -``` - -Please note that tests that require an automation file are meant for speculos, and will currently hang the test suite. \ No newline at end of file +pytest --device `your_device` --backend ledgerblue +``` \ No newline at end of file diff --git a/tests/automations/accept.json b/tests/automations/accept.json deleted file mode 100644 index 150507c2..00000000 --- a/tests/automations/accept.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "version": 1, - "rules": [ - { - "regexp": "Review|Amount|Address|Confirm|Fees", - "actions": [ - ["button", 2, true], - ["button", 2, false] - ] - }, - { - "text": "Accept", - "actions": [ - [ "button", 1, true ], - [ "button", 2, true ], - [ "button", 2, false ], - [ "button", 1, false ] - ] - } - ] -} diff --git a/tests/automations/reject.json b/tests/automations/reject.json deleted file mode 100644 index 50d04f48..00000000 --- a/tests/automations/reject.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "version": 1, - "rules": [ - { - "regexp": "Review|Amount|Address|Confirm|Fees|Accept", - "actions": [ - ["button", 2, true], - ["button", 2, false] - ] - }, - { - "text": "Reject", - "actions": [ - [ "button", 1, true ], - [ "button", 2, true ], - [ "button", 2, false ], - [ "button", 1, false ] - ] - } - ] -} diff --git a/tests/bitcoin_client/__init__.py b/tests/bitcoin_client/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/bitcoin_client/bitcoin_base_cmd.py b/tests/bitcoin_client/bitcoin_base_cmd.py deleted file mode 100644 index 5e71fde5..00000000 --- a/tests/bitcoin_client/bitcoin_base_cmd.py +++ /dev/null @@ -1,345 +0,0 @@ -import struct -from typing import Tuple, List, Optional - -from ledgercomm import Transport - -from bitcoin_client.hwi.serialization import CTransaction, hash256 -from bitcoin_client.exception.device_exception import DeviceException -from bitcoin_client.bitcoin_cmd_builder import AddrType, InsType, BitcoinCommandBuilder - - -class BitcoinBaseCommand: - """Bitcoin Base Command. - - Send APDU command to device and get APDU response. - - Parameters - ---------- - transport : Transport - Transport interface to the device. - debug : bool - Whether you want to see logging or not. - - Attributes - ---------- - transport : Transport - Transport interface to send APDUs. - builder : BitcoinCommandBuilder - Command builder to construct APDUs. - - """ - - def __init__(self, transport: Transport, debug: bool = False) -> None: - """Init constructor.""" - self.transport = transport - self.builder = BitcoinCommandBuilder(debug=debug) - - def get_random(self, n: int = 5) -> bytes: - """Get `n` bytes random value. - - Parameters - ---------- - n : int - Number of bytes (5 <= n <= 248). - - Returns - ------- - bytes - Random bytes of length `n` from the device. - - """ - sw, response = self.transport.exchange_raw( - self.builder.get_random(n=n) - ) - - if sw != 0x9000: - raise DeviceException(error_code=sw, ins=InsType.GET_RANDOM) - - return response - - def get_firmware_version(self) -> Tuple[int, int, int]: - """Get the version of the application. - - Returns - ------- - Tuple[int, int, int] - (MAJOR, MINOR, PATCH) version of the application. - - """ - sw, response = self.transport.exchange_raw( - self.builder.get_firmware_version() - ) - - if sw != 0x9000: - raise DeviceException(error_code=sw, ins=InsType.GET_FIRMWARE_VERSION) - - # response = flag (1) [unused] || - # architecture id (1) [unused] || - # major version of the application (1) || - # minor version of the application (1) || - # patch version of the application (1) || - # loader id major version (1) [unused] || - # loader id minor version (1) [unused] || - # mode (1) [unused] - _, _, major, minor, patch, _, _, _ = struct.unpack( - "BBBBBBBB", - response - ) # type: int, int, int, int, int, int, int, int - - return major, minor, patch - - def get_coin_version(self) -> Tuple[int, int, int, str, str]: - """Get coin information depending on Bitcoin app fork. - - Returns - ------- - Tuple[int, int, int, str, str] - A tuple (p2pkh_pref, p2sh_prefix, coin_family, coin_name, coin_ticker). - - """ - sw, response = self.transport.exchange_raw( - self.builder.get_coin_version() - ) # type: int, bytes - - if sw != 0x9000: - raise DeviceException(error_code=sw, ins=InsType.GET_COIN_VERSION) - - # response = p2pkh_prefix (2) || p2sh_prefix (2) || coin_family (1) || - # len(coin_name) (1) || coin_name (var) || - # len(coin_ticker) (1) || coin_ticker (var) - offset: int = 0 - p2pkh_prefix: int = int.from_bytes(response[offset:offset + 2], byteorder="big") - offset += 2 - p2sh_prefix: int = int.from_bytes(response[offset:offset + 2], byteorder="big") - offset += 2 - coin_family: int = response[offset] - offset += 1 - coin_name_len: int = response[offset] - offset += 1 - coin_name: str = response[offset:offset + coin_name_len].decode("ascii") - offset += coin_name_len - coin_ticker_len: int = response[offset] - offset += 1 - coin_ticker: str = response[offset:offset + coin_ticker_len].decode("ascii") - offset += coin_ticker_len - - assert len(response) == offset - - return p2pkh_prefix, p2sh_prefix, coin_family, coin_name, coin_ticker - - def get_public_key(self, - addr_type: AddrType, - bip32_path: str, - display: bool = False) -> Tuple[bytes, str, bytes]: - """Get public key given address type and BIP32 path. - - Parameters - ---------- - addr_type : AddrType - Type of address. Could be AddrType.Legacy, AddrType.P2SH_P2WPKH, - AddrType.BECH32. - bip32_path : str - BIP32 path of the public key you want. - display : bool - Whether you want to display address and ask confirmation on the device. - - Returns - ------- - - """ - sw, response = self.transport.exchange_raw( - self.builder.get_public_key(addr_type=addr_type, - bip32_path=bip32_path, - display=display) - ) # type: int, bytes - - if sw != 0x9000: - raise DeviceException(error_code=sw, ins=InsType.GET_WALLET_PUBLIC_KEY) - - # response = len(pub_key) (1) || pub_key (var) || - # len(addr) (1) || addr (var) || bip32_chain_code (32) - offset: int = 0 - pub_key_len: int = response[offset] - offset += 1 - pub_key: bytes = response[offset:offset + pub_key_len] - offset += pub_key_len - addr_len: int = response[offset] - offset += 1 - addr: str = response[offset:offset + addr_len].decode("ascii") - offset += addr_len - bip32_chain_code: bytes = response[offset:offset + 32] - offset += 32 - - assert len(response) == offset - - return pub_key, addr, bip32_chain_code - - def get_trusted_input(self, - utxo: CTransaction, - output_index: int) -> bytes: - """Get trusted input given UTXO and output index. - - Parameters - ---------- - utxo : CTransaction - Serialized Bitcoin transaction to extract UTXO. - output_index : int - Index of the UTXO to build the trusted input. - - Returns - ------- - bytes - Serialized trusted input. - - """ - sw: int - response: bytes = b"" - - for chunk in self.builder.get_trusted_input(utxo, output_index): - self.transport.send_raw(chunk) - sw, response = self.transport.recv() # type: int, bytes - - if sw != 0x9000: - raise DeviceException(error_code=sw, ins=InsType.GET_TRUSTED_INPUT) - - # response = 0x32 (1) || 0x00 (1) || random (2) || prev_txid (32) || - # output_index (4) || amount (8) || HMAC (8) - assert len(response) == 56 - - offset: int = 0 - magic_trusted_input: int = response[offset] - assert magic_trusted_input == 0x32 - offset += 1 - zero: int = response[offset] - assert zero == 0x00 - offset += 1 - _: bytes = response[offset:offset + 2] # random - offset += 2 - prev_txid: bytes = response[offset:offset + 32] - assert prev_txid == hash256(utxo.serialize_without_witness()) - offset += 32 - out_index: int = int.from_bytes(response[offset:offset + 4], - byteorder="little") - assert out_index == output_index - offset += 4 - amount: int = int.from_bytes(response[offset:offset + 8], - byteorder="little") - assert amount == utxo.vout[output_index].nValue - offset += 8 - _: bytes = response[offset:offset + 8] # HMAC - offset += 8 - - assert offset == len(response) - - return response - - def untrusted_hash_tx_input_start(self, - tx: CTransaction, - inputs: List[Tuple[CTransaction, bytes]], - input_index: int, - script: bytes, - is_new_transaction: bool) -> None: - """Send trusted inputs to build the new transaction. - - Parameters - ---------- - tx : CTransaction - Serialized Bitcoin transaction to sign. - inputs : List[Tuple[CTransaction, bytes]] - List of inputs with pair of UTXO and trusted input. - input_index : int - Index of the input to process. - script : bytes - The scriptSig to add at `input_index`. - is_new_transaction: bool - First time sending this input. - - Returns - ------- - None - - """ - sw: int - - for chunk in self.builder.untrusted_hash_tx_input_start(tx=tx, - inputs=inputs, - input_index=input_index, - script=script, - is_new_transaction=is_new_transaction): - self.transport.send_raw(chunk) - sw, _ = self.transport.recv() # type: int, bytes - - if sw != 0x9000: - raise DeviceException( - error_code=sw, - ins=InsType.UNTRUSTED_HASH_TRANSACTION_INPUT_START - ) - - def untrusted_hash_tx_input_finalize(self, - tx: CTransaction, - change_path: Optional[str]) -> bytes: - """Send transaction outputs to finalize the new transaciton. - - Parameters - ---------- - tx: CTransaction - Transaction to sign. - change_path: Optional[str] - BIP32 path for the change. - - Returns - ------- - bytes - Two bytes Reserved for Future Use (RFU) and transaction validation flag. - Unused, always 0x00 and 0x00. - - - """ - sw: int - response: bytes = b"" - - for chunk in self.builder.untrusted_hash_tx_input_finalize(tx=tx, - change_path=change_path): - self.transport.send_raw(chunk) - sw, response = self.transport.recv() - - if sw != 0x9000: - raise DeviceException( - error_code=sw, - ins=InsType.UNTRUSTED_HASH_TRANSACTION_INPUT_FINALIZE - ) - # response = RFU (1) || User validation flag (1) - return response - - def untrusted_hash_sign(self, - sign_path: str, - lock_time: int = 0, - sig_hash: int = 1) -> Tuple[int, bytes]: - """Sign input just sent using `sign_path`. - - Parameters - ---------- - sign_path : str - BIP32 path to be used to sign. - lock_time : int - Block height or timestamp when transaction is final. - sig_hash : int - Either SIGHASH_ALL (0x01), SIGHASH_NONE (0x02) or SIGHASH_SINGLE (0x03). - Only SIGHASH_ALL (0x01) is supported. - - Returns - ------- - Tuple[int, bytes] - A pair (v, der_sig) with: - - v: 0x01 if y-coordinate of R is odd, 0x00 otherwise. - - der_sig: DER encoded Bitcoin ECDSA signature (with SIGHASH). - - """ - sw, response = self.transport.exchange_raw( - self.builder.untrusted_hash_sign(sign_path, lock_time, sig_hash) - ) # type: int, bytes - - if sw != 0x9000: - raise DeviceException(error_code=sw, ins=InsType.UNTRUSTED_HASH_SIGN) - - return (1, b"\x30" + response[1:]) if response[0] & 0x01 else (0, response) diff --git a/tests/bitcoin_client/bitcoin_cmd.py b/tests/bitcoin_client/bitcoin_cmd.py deleted file mode 100644 index ec5818fd..00000000 --- a/tests/bitcoin_client/bitcoin_cmd.py +++ /dev/null @@ -1,244 +0,0 @@ -from typing import Tuple, List - -from ledgercomm import Transport - -from bitcoin_client.hwi.serialization import (CTransaction, CTxIn, CTxOut, COutPoint, - is_witness, is_p2wpkh, is_p2pkh, is_p2sh, hash160) -from bitcoin_client.hwi.bech32 import decode as bech32_decode -from bitcoin_client.hwi.base58 import decode as base58_decode -from bitcoin_client.utils import deser_trusted_input -from bitcoin_client.bitcoin_utils import bip143_digest, compress_pub_key -from bitcoin_client.bitcoin_cmd_builder import AddrType -from bitcoin_client.bitcoin_base_cmd import BitcoinBaseCommand - - -class BitcoinCommand(BitcoinBaseCommand): - """Bitcoin Command. - - Inherit from BitcoinBaseCommand and provide a high level - interface to sign Bitcoin transaction. - - Parameters - ---------- - transport : Transport - Transport interface to the device. - debug : bool - Whether you want to see logging or not. - - """ - - def __init__(self, transport: Transport, debug: bool = False) -> None: - """Init constructor.""" - super().__init__(transport, debug) - - def sign_new_tx(self, - address: str, - amount: int, - fees: int, - change_path: str, - sign_paths: List[str], - raw_utxos: List[Tuple[bytes, int]], - lock_time: int = 0) -> List[Tuple[bytes, bytes, Tuple[int, bytes]]]: - """Sign a new transaction with parameters.. - - Parameters - ---------- - address : str - Bitcoin address. - amount : int - Amount to send to address in satoshis. - fees : int - Fees of the new transaction. - change_path : str - BIP32 path for the change. - sign_paths : List[str] - BIP32 paths to sign inputs. - raw_utxos : List[Tuple[bytes, int]] - Pairs of raw hex transaction and output index to use as UTXOs. - lock_time : int - Block height or timestamp when transaction is final. - - Returns - ------- - List[Tuple[bytes, bytes, Tuple[int, bytes]]] - Tuples (tx_hash_digest, sign_pub_key, (v, der_sig)) - - """ - utxos: List[Tuple[CTransaction, int, int]] = [] - amount_available: int = 0 - for raw_tx, output_index in raw_utxos: - utxo = CTransaction.from_bytes(raw_tx) - value = utxo.vout[output_index].nValue - utxos.append((utxo, output_index, value)) - amount_available += value - - sign_pub_keys: List[bytes] = [] - for sign_path in sign_paths: - sign_pub_key, _, _ = self.get_public_key( - addr_type=AddrType.BECH32, - bip32_path=sign_path, - display=False - ) - sign_pub_keys.append(compress_pub_key(sign_pub_key)) - - inputs: List[Tuple[CTransaction, bytes]] = [ - (utxo, self.get_trusted_input(utxo=utxo, output_index=output_index)) - for utxo, output_index, _ in utxos - ] - - # new transaction - tx: CTransaction = CTransaction() - tx.nVersion = 2 - tx.nLockTime = lock_time - # prepare vin - for i, (utxo, trusted_input) in enumerate(inputs): - if utxo.sha256 is None: - utxo.calc_sha256(with_witness=False) - - _, _, _, prev_txid, output_index, _, _ = deser_trusted_input(trusted_input) - assert prev_txid != utxo.sha256 - - script_pub_key: bytes = utxo.vout[output_index].scriptPubKey - # P2WPKH - if is_p2wpkh(script_pub_key): - _, _, wit_prog = is_witness(script_pub_key) - script_pub_key = (b"\x76" + # OP_DUP - b"\xa9" + # OP_HASH160 - b"\x14" + # bytes to push (20) - wit_prog + # hash160(pubkey) - b"\x88" + # OP_EQUALVERIFY - b"\xac") # OP_CHECKSIG - # P2SH-P2WPKH or P2PKH - if (is_p2sh(script_pub_key) and not utxo.wit.is_null()) or is_p2pkh(script_pub_key): - script_pub_key = (b"\x76" + # OP_DUP - b"\xa9" + # OP_HASH160 - b"\x14" + # bytes to push (20) - hash160(sign_pub_keys[i]) + # hash160(pubkey) - b"\x88" + # OP_EQUALVERIFY - b"\xac") # OP_CHECKSIG - tx.vin.append(CTxIn(outpoint=COutPoint(h=utxo.sha256, n=output_index), - scriptSig=script_pub_key, - nSequence=0xfffffffd)) - - if amount_available - fees > amount: - change_pub_key, _, _ = self.get_public_key( - addr_type=AddrType.BECH32, - bip32_path=change_path, - display=False - ) - change_pubkey_hash = hash160(compress_pub_key(change_pub_key)) - change_script_pubkey: bytes - # Bech32 pubkey hash or script hash (mainnet and testnet) - if address.startswith("bc1") or address.startswith("tb1"): - change_script_pubkey = bytes([0, len(change_pubkey_hash)]) + change_pubkey_hash - # P2SH-P2WPKH (mainnet and testnet) - elif address.startswith("3") or address.startswith("2"): - change_script_pubkey = (b"\xa9" + # OP_HASH160 - b"\x14" + # bytes to push (20) - # hash160(redeem_script) - hash160(bytes([0, len(change_pubkey_hash)]) + change_pubkey_hash) + - b"\x87") # OP_EQUAL - # P2PKH address (mainnet and testnet) - elif address.startswith("1") or (address.startswith("m") or address.startswith("n")): - change_script_pubkey = (b"\x76" + # OP_DUP - b"\xa9" + # OP_HASH160 - b"\x14" + # bytes to push (20) - change_pubkey_hash + # hash160(pubkey) - b"\x88" + # OP_EQUALVERIFY - b"\xac") # OP_CHECKSIG - else: - raise Exception(f"Unsupported address: '{address}'") - tx.vout.append( - CTxOut(nValue=amount_available - fees - amount, - scriptPubKey=change_script_pubkey) - ) - - script_pub_key: bytes - # Bech32 pubkey hash or script hash (mainnet and testnet) - if address.startswith("bc1") or address.startswith("tb1"): - witness_version, witness_program = bech32_decode(address[0:2], address) - script_pub_key = bytes( - [witness_version + 0x50 if witness_version else 0, - len(witness_program)] + - witness_program - ) - # P2SH address (mainnet and testnet) - elif address.startswith("3") or address.startswith("2"): - script_pub_key = (b"\xa9" + # OP_HASH160 - b"\x14" + # bytes to push (20) - base58_decode(address)[1:-4] + # hash160(redeem_script) - b"\x87") # OP_EQUAL - # P2PKH address (mainnet and testnet) - elif address.startswith("1") or (address.startswith("m") or address.startswith("n")): - script_pub_key = (b"\x76" + # OP_DUP - b"\xa9" + # OP_HASH160 - b"\x14" + # bytes to push (20) - base58_decode(address)[1:-4] + # hash160(pubkey) - b"\x88" + # OP_EQUALVERIFY - b"\xac") # OP_CHECKSIG - else: - raise Exception(f"Unsupported address: '{address}'") - - tx.vout.append(CTxOut(nValue=amount, - scriptPubKey=script_pub_key)) - - for i in range(len(tx.vin)): - self.untrusted_hash_tx_input_start(tx=tx, - inputs=inputs, - input_index=i, - script=tx.vin[i].scriptSig, - is_new_transaction=(i == 0)) - - self.untrusted_hash_tx_input_finalize(tx=tx, - change_path=change_path) - - sigs: List[Tuple[bytes, bytes, Tuple[int, bytes]]] = [] - for i in range(len(tx.vin)): - self.untrusted_hash_tx_input_start(tx=tx, - inputs=[inputs[i]], - input_index=0, - script=tx.vin[i].scriptSig, - is_new_transaction=False) - _, _, amount = utxos[i] - sigs.append( - (bip143_digest(tx, amount, i), - sign_pub_keys[i], - self.untrusted_hash_sign(sign_path=sign_paths[i], - lock_time=tx.nLockTime, - sig_hash=1)) - ) - - return sigs - - def sign_tx(self, - tx: CTransaction, - change_path: str, - sign_paths: List[str], - utxos: List[Tuple[CTransaction, int, int]]) -> List[Tuple[int, bytes]]: - inputs: List[Tuple[CTransaction, bytes]] = [ - (utxo, self.get_trusted_input(utxo=utxo, output_index=output_index)) - for utxo, output_index, _ in utxos - ] - - for i in range(len(tx.vin)): - self.untrusted_hash_tx_input_start(tx=tx, - inputs=inputs, - input_index=i, - script=tx.vin[i].scriptSig, - is_new_transaction=(i == 0)) - - self.untrusted_hash_tx_input_finalize(tx=tx, - change_path=change_path) - - sigs = [] - for i in range(len(tx.vin)): - self.untrusted_hash_tx_input_start(tx=tx, - inputs=[inputs[i]], - input_index=0, - script=tx.vin[i].scriptSig, - is_new_transaction=False) - sigs.append(self.untrusted_hash_sign(sign_path=sign_paths[i], - lock_time=tx.nLockTime, - sig_hash=1)) - - return sigs diff --git a/tests/bitcoin_client/bitcoin_cmd_builder.py b/tests/bitcoin_client/bitcoin_cmd_builder.py deleted file mode 100644 index baa95404..00000000 --- a/tests/bitcoin_client/bitcoin_cmd_builder.py +++ /dev/null @@ -1,387 +0,0 @@ -import enum -import logging -import struct -from typing import Optional, List, Tuple, Iterator, Union, cast - -from bitcoin_client.hwi.serialization import CTransaction, ser_compact_size -from bitcoin_client.utils import chunkify, MAX_APDU_LEN -from bitcoin_client.bitcoin_utils import bip32_path_from_string - - -class InsType(enum.IntEnum): - """Instruction commands supported.""" - - GET_RANDOM = 0xC0 - GET_FIRMWARE_VERSION = 0xC4 - GET_COIN_VERSION = 0x16 - GET_WALLET_PUBLIC_KEY = 0x40 - GET_TRUSTED_INPUT = 0x42 - UNTRUSTED_HASH_TRANSACTION_INPUT_START = 0x44 - UNTRUSTED_HASH_TRANSACTION_INPUT_FINALIZE = 0x4A - UNTRUSTED_HASH_SIGN = 0x48 - - -class AddrType(enum.IntEnum): - """Type of Bitcoin address.""" - - Legacy = 0x00 - P2SH_P2WPKH = 0x01 - BECH32 = 0x02 - - -class BitcoinCommandBuilder: - """APDU command builder for the Bitcoin application. - - Parameters - ---------- - debug : bool - Whether you want to see logging or not. - - Attributes - ---------- - debug : bool - Whether you want to see logging or not. - - """ - - CLA: int = 0xE0 - - def __init__(self, debug: bool = False): - """Init constructor.""" - self.debug = debug - - def serialize(self, - cla: int, - ins: Union[int, enum.IntEnum], - p1: int = 0, - p2: int = 0, - cdata: bytes = b"") -> bytes: - """Serialize the whole APDU command (header + cdata). - - Parameters - ---------- - cla : int - Instruction class: CLA (1 byte) - ins : Union[int, IntEnum] - Instruction code: INS (1 byte) - p1 : int - Instruction parameter 1: P1 (1 byte). - p2 : int - Instruction parameter 2: P2 (1 byte). - cdata : bytes - Bytes of command data. - - Returns - ------- - bytes - Bytes of a complete APDU command. - - """ - ins = cast(int, ins.value) if isinstance(ins, enum.IntEnum) else cast(int, ins) - - header: bytes = struct.pack("BBBBB", - cla, - ins, - p1, - p2, - len(cdata)) # add Lc to APDU header - - if self.debug: - logging.info("header: %s", header.hex()) - logging.info("cdata: %s", cdata.hex()) - - return header + cdata - - def get_random(self, n: int = 248) -> bytes: - """Command builder for GET_RANDOM. - - Parameters - ---------- - n : int - Number of bytes (1 <= n <= 248). - - Returns - ------- - bytes - APDU command for GET_RANDOM. - - """ - return self.serialize(cla=self.CLA, - ins=InsType.GET_RANDOM, - p1=0x00, - p2=0x00, - cdata=b"\x00" * n) - - def get_firmware_version(self) -> bytes: - """Command builder for GET_FIRMWARE_VERSION. - - Returns - ------- - bytes - APDU command for GET_FIMWARE_VERSION. - - """ - ins: InsType = InsType.GET_FIRMWARE_VERSION - p1: int = 0x00 - p2: int = 0x00 - - return self.serialize(cla=self.CLA, ins=ins, p1=p1, p2=p2, cdata=b"") - - def get_coin_version(self) -> bytes: - """Command builder for GET_COIN_VERSION. - - Returns - ------- - bytes - APDU command for GET_COIN_VERSION. - - """ - ins: InsType = InsType.GET_COIN_VERSION - p1: int = 0x00 - p2: int = 0x00 - - return self.serialize(cla=self.CLA, ins=ins, p1=p1, p2=p2, cdata=b"") - - def get_public_key(self, - addr_type: AddrType, - bip32_path: str, - display: bool = False) -> bytes: - """Command builder for GET_WALLET_PUBLIC_KEY. - - Parameters - ---------- - addr_type : AddrType - The type of address expected in the response. Could be Legacy (0x00), - P2SH-P2WPKH (0x01) or BECH32 encoded P2WPKH (0x02). - bip32_path : str - String representation of BIP32 path (e.g. "m/44'/0'/0'/0" or "44'/0'/0'/0"). - display : bool - Whether you want to display address and ask confirmation on the device. - - Returns - ------- - bytes - APDU command for GET_WALLET_PUBLIC_KEY. - - """ - ins: InsType = InsType.GET_WALLET_PUBLIC_KEY - # P1: - # - 0x00, do not display the address - # - 0x01, display the address - # - 0x02, display the validation token (unused here) - p1: int = 0x01 if display else 0x00 - # P2: type of Bitcoin address in the reponse - p2: int = addr_type.value - - path: List[bytes] = bip32_path_from_string(bip32_path) - - cdata: bytes = b"".join([ - len(path).to_bytes(1, byteorder="big"), - *path - ]) - - return self.serialize(cla=self.CLA, ins=ins, p1=p1, p2=p2, cdata=cdata) - - def get_trusted_input(self, - utxo: CTransaction, - output_index: int) -> Iterator[bytes]: - """Command builder for GET_TRUSTED_INPUT. - - Parameters - ---------- - utxo: CTransaction - Unspent Transaction Output (UTXO) serialized. - output_index: int - Output index owned in the UTXO. - - Yields - ------ - bytes - APDU command chunk for GET_TRUSTED_INPUT. - - """ - ins: InsType = InsType.GET_TRUSTED_INPUT - # P1: - # - 0x00, first transaction data chunk - # - 0x80, other transaction data chunk - p1: int - p2: int = 0x00 - - cdata: bytes = (output_index.to_bytes(4, byteorder="big") + - utxo.serialize_without_witness()) - - for i, (is_last, chunk) in enumerate(chunkify(cdata, MAX_APDU_LEN)): - p1 = 0x00 if i == 0 else 0x80 - if is_last: - yield self.serialize(cla=self.CLA, - ins=ins, - p1=p1, - p2=p2, - cdata=chunk) - return - yield self.serialize(cla=self.CLA, - ins=ins, - p1=p1, - p2=p2, - cdata=chunk) - - def untrusted_hash_tx_input_start(self, - tx: CTransaction, - inputs: List[Tuple[CTransaction, bytes]], - input_index: int, - script: bytes, - is_new_transaction: bool - ) -> Iterator[bytes]: - """Command builder for UNTRUSTED_HASH_TRANSACTION_INPUT_START. - - Parameters - ---------- - tx: CTransaction - Serialized Bitcoin transaction to sign. - inputs: List[Tuple[CTransaction, bytes]] - List of inputs with pair of UTXO and trusted input. - input_index: int - Index of the input to process. - script : bytes - The scriptSig to add at `input_index`. - is_new_transaction: bool - First time sending this input. - - Yields - ------- - bytes - APDU command chunk for UNTRUSTED_HASH_TRANSACTION_INPUT_START. - - """ - ins: InsType = InsType.UNTRUSTED_HASH_TRANSACTION_INPUT_START - # P1: - # - 0x00, first transaction data chunk - # - 0x80, other transaction data chunk - p1: int = 0x00 - # P2: - # - 0x80, new transaction - # - 0x02, new transaction with segwit input - p2: int = 0x02 if is_new_transaction else 0x80 - - cdata: bytes = (tx.nVersion.to_bytes(4, byteorder="little") + - ser_compact_size(len(inputs))) - - yield self.serialize(cla=self.CLA, - ins=ins, - p1=p1, - p2=p2, - cdata=cdata) - - p1 = 0x80 - for i, (_, trusted_input) in enumerate(inputs): - script_sig: bytes = script if i == input_index else b"" - cdata = b"".join([ - b"\x01", # 0x01 for trusted input, 0x02 for witness, 0x00 otherwise - len(trusted_input).to_bytes(1, byteorder="big"), - trusted_input, - ser_compact_size(len(script_sig)) - ]) - - yield self.serialize(cla=self.CLA, - ins=ins, - p1=p1, - p2=p2, - cdata=cdata) - - yield self.serialize(cla=self.CLA, - ins=ins, - p1=p1, - p2=p2, - cdata=(script_sig + - 0xfffffffd.to_bytes(4, byteorder="little"))) - - def untrusted_hash_tx_input_finalize(self, - tx: CTransaction, - change_path: Optional[str] - ) -> Iterator[bytes]: - """Command builder for UNTRUSTED_HASH_TRANSACTION_INPUT_FINALIZE. - - Parameters - ---------- - tx: CTransaction - Transaction to sign. - change_path: Optional[str] - BIP32 path for the change. - - Yields - ------- - bytes - APDU command chunk for UNTRUSTED_HASH_TRANSACTION_INPUT_FINALIZE. - - """ - ins: InsType = InsType.UNTRUSTED_HASH_TRANSACTION_INPUT_FINALIZE - # P1: - # - 0x00, more input chunk to be sent - # - 0x80, last chunk to be sent - # - 0xFF, BIP32 path for the change address - p1: int - p2: int = 0x00 - - p1 = 0xFF - if change_path: - bip32_change_path: List[bytes] = bip32_path_from_string(change_path) - cdata: bytes = b"".join([ - len(bip32_change_path).to_bytes(1, byteorder="big"), - *bip32_change_path - ]) - yield self.serialize(cla=self.CLA, ins=ins, p1=p1, p2=p2, cdata=cdata) - else: - yield self.serialize(cla=self.CLA, ins=ins, p1=p1, p2=p2, cdata=b"\x00") - - vout_num = len(tx.vout) - p1 = 0x00 - yield self.serialize(cla=self.CLA, - ins=ins, - p1=p1, - p2=p2, - cdata=ser_compact_size(vout_num)) - - for i, ctxout in enumerate(tx.vout): - p1 = 0x00 if i < vout_num - 1 else 0x80 - yield self.serialize(cla=self.CLA, - ins=ins, - p1=p1, - p2=p2, - cdata=ctxout.serialize()) - - def untrusted_hash_sign(self, - sign_path: str, - lock_time: int = 0, - sig_hash: int = 1) -> bytes: - """Command builder for UNTRUSTED_HASH_SIGN. - - Parameters - ---------- - sign_path : str - BIP32 path to be used to sign. - lock_time : int - Block height or timestamp when transaction is final. - sig_hash : int - Either SIGHASH_ALL (0x01), SIGHASH_NONE (0x02) or SIGHASH_SINGLE (0x03). - Only SIGHASH_ALL (0x01) is supported. - - Returns - ------- - bytes - APDU command for UNTRUSTED_HASH_SIGN. - - """ - ins: InsType = InsType.UNTRUSTED_HASH_SIGN - p1: int = 0x00 - p2: int = 0x00 - - bip32_path: List[bytes] = bip32_path_from_string(sign_path) - cdata: bytes = b"".join([ - len(bip32_path).to_bytes(1, byteorder="big"), - *bip32_path, - b"\00", # unused (Reserved for Future Use) - lock_time.to_bytes(4, byteorder="big"), # /!\ big instead of little - sig_hash.to_bytes(1, byteorder="big") - ]) - - return self.serialize(cla=self.CLA, ins=ins, p1=p1, p2=p2, cdata=cdata) diff --git a/tests/bitcoin_client/bitcoin_utils.py b/tests/bitcoin_client/bitcoin_utils.py deleted file mode 100644 index 162d23db..00000000 --- a/tests/bitcoin_client/bitcoin_utils.py +++ /dev/null @@ -1,68 +0,0 @@ -import struct -from typing import List - -from bitcoin_client.hwi.serialization import CTransaction, hash256, ser_string - - -def bip143_digest(tx: CTransaction, - amount: int, - input_index: int, - sig_hash: int = 0x01) -> bytes: - hash_prev_outs: bytes = b"".join([ - txin.prevout.serialize() for txin in tx.vin - ]) - - hash_sequence: bytes = b"".join([ - struct.pack(" List[bytes]: - """Convert BIP32 path string to list of bytes.""" - splitted_path: List[str] = path.split("/") - - if "m" in splitted_path and splitted_path[0] == "m": - splitted_path = splitted_path[1:] - - return [int(p).to_bytes(4, byteorder="big") if "'" not in p - else (0x80000000 | int(p[:-1])).to_bytes(4, byteorder="big") - for p in splitted_path] - - -def compress_pub_key(pub_key: bytes) -> bytes: - """Convert uncompressed to compressed public key.""" - if pub_key[-1] & 1: - return b"\x03" + pub_key[1:33] - - return b"\x02" + pub_key[1:33] \ No newline at end of file diff --git a/tests/bitcoin_client/exception/__init__.py b/tests/bitcoin_client/exception/__init__.py deleted file mode 100644 index 4320abeb..00000000 --- a/tests/bitcoin_client/exception/__init__.py +++ /dev/null @@ -1,64 +0,0 @@ -from .device_exception import DeviceException -from .errors import (AccessConditionNotFullfilledError, - AlgorithmNotSupportedError, - ClaNotSupportedError, - CodeBlockedError, - CodeNotInitializedError, - CommandIncompatibleFileStructureError, - ConditionOfUseNotSatisfiedError, - ContradictionInvalidationError, - ContradictionSecretCodeStatusError, - FileAlreadyExistsError, - FileNotFoundError, - GPAuthFailedError, - HaltedError, - InconsistentFileError, - IncorrectDataError, - IncorrectLengthError, - IncorrectP1P2Error, - InsNotSupportedError, - InvalidKCVError, - InvalidOffsetError, - LicensingError, - MaxValueReachedError, - MemoryProblemError, - NoEFSelectedError, - NotEnoughMemorySpaceError, - ReferencedDataNotFoundError, - SecurityStatusNotSatisfiedError, - SwapWithoutTrustedInputsError, - TechnicalProblemError, - UnknownDeviceError) - -__all__ = [ - "AccessConditionNotFullfilledError", - "AlgorithmNotSupportedError", - "ClaNotSupportedError", - "CodeBlockedError", - "CodeNotInitializedError", - "CommandIncompatibleFileStructureError", - "ConditionOfUseNotSatisfiedError", - "ContradictionInvalidationError", - "ContradictionSecretCodeStatusError", - "FileAlreadyExistsError", - "FileNotFoundError", - "GPAuthFailedError", - "HaltedError", - "InconsistentFileError", - "IncorrectDataError", - "IncorrectLengthError", - "IncorrectP1P2Error", - "InsNotSupportedError", - "InvalidKCVError", - "InvalidOffsetError", - "LicensingError", - "MaxValueReachedError", - "MemoryProblemError", - "NoEFSelectedError", - "NotEnoughMemorySpaceError", - "ReferencedDataNotFoundError", - "SecurityStatusNotSatisfiedError", - "SwapWithoutTrustedInputsError", - "TechnicalProblemError", - "UnknownDeviceError" -] diff --git a/tests/bitcoin_client/exception/device_exception.py b/tests/bitcoin_client/exception/device_exception.py deleted file mode 100644 index ce00193f..00000000 --- a/tests/bitcoin_client/exception/device_exception.py +++ /dev/null @@ -1,53 +0,0 @@ -import enum -from typing import Dict, Any, Optional - -from .errors import * - - -class DeviceException(Exception): # pylint: disable=too-few-public-methods - exc: Dict[int, Any] = { - 0x6700: IncorrectLengthError, - 0x6981: CommandIncompatibleFileStructureError, - 0x6982: SecurityStatusNotSatisfiedError, - 0x6985: ConditionOfUseNotSatisfiedError, - 0x6A80: IncorrectDataError, - 0x6A84: NotEnoughMemorySpaceError, - 0x6A88: ReferencedDataNotFoundError, - 0x6A89: FileAlreadyExistsError, - 0x6A8A: SwapWithoutTrustedInputsError, - 0x6B00: IncorrectP1P2Error, - 0x6D00: InsNotSupportedError, - 0x6E00: ClaNotSupportedError, - 0x6F00: TechnicalProblemError, - 0x9240: MemoryProblemError, - 0x9400: NoEFSelectedError, - 0x9402: InvalidOffsetError, - 0x9404: FileNotFoundError, - 0x9408: InconsistentFileError, - 0x9484: AlgorithmNotSupportedError, - 0x9485: InvalidKCVError, - 0x9802: CodeNotInitializedError, - 0x9804: AccessConditionNotFullfilledError, - 0x9808: ContradictionSecretCodeStatusError, - 0x9810: ContradictionInvalidationError, - 0x9840: CodeBlockedError, - 0x9850: MaxValueReachedError, - 0x6300: GPAuthFailedError, - 0x6F42: LicensingError, - 0x6FAA: HaltedError - } - - def __new__(cls, - error_code: int, - ins: Optional[enum.IntEnum] = None, - message: str = "" - ) -> Any: - error_message: str = (f"Error in {ins!r} command" - if ins else "Error in command") - - if error_code in DeviceException.exc: - return DeviceException.exc[error_code](hex(error_code), - error_message, - message) - - return UnknownDeviceError(hex(error_code), error_message, message) diff --git a/tests/bitcoin_client/exception/errors.py b/tests/bitcoin_client/exception/errors.py deleted file mode 100644 index e19f4f73..00000000 --- a/tests/bitcoin_client/exception/errors.py +++ /dev/null @@ -1,118 +0,0 @@ -class UnknownDeviceError(Exception): - pass - - -class IncorrectLengthError(Exception): - pass - - -class CommandIncompatibleFileStructureError(Exception): - pass - - -class SecurityStatusNotSatisfiedError(Exception): - pass - - -class ConditionOfUseNotSatisfiedError(Exception): - pass - - -class IncorrectDataError(Exception): - pass - - -class NotEnoughMemorySpaceError(Exception): - pass - - -class ReferencedDataNotFoundError(Exception): - pass - - -class FileAlreadyExistsError(Exception): - pass - - -class SwapWithoutTrustedInputsError(Exception): - pass - - -class IncorrectP1P2Error(Exception): - pass - - -class InsNotSupportedError(Exception): - pass - - -class ClaNotSupportedError(Exception): - pass - - -class TechnicalProblemError(Exception): - pass - - -class MemoryProblemError(Exception): - pass - - -class NoEFSelectedError(Exception): - pass - - -class InvalidOffsetError(Exception): - pass - - -class FileNotFoundError(Exception): - pass - - -class InconsistentFileError(Exception): - pass - - -class AlgorithmNotSupportedError(Exception): - pass - - -class InvalidKCVError(Exception): - pass - - -class CodeNotInitializedError(Exception): - pass - - -class AccessConditionNotFullfilledError(Exception): - pass - - -class ContradictionSecretCodeStatusError(Exception): - pass - - -class ContradictionInvalidationError(Exception): - pass - - -class CodeBlockedError(Exception): - pass - - -class MaxValueReachedError(Exception): - pass - - -class GPAuthFailedError(Exception): - pass - - -class LicensingError(Exception): - pass - - -class HaltedError(Exception): - pass diff --git a/tests/bitcoin_client/hwi/__init__.py b/tests/bitcoin_client/hwi/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/bitcoin_client/hwi/base58.py b/tests/bitcoin_client/hwi/base58.py deleted file mode 100644 index e0df1152..00000000 --- a/tests/bitcoin_client/hwi/base58.py +++ /dev/null @@ -1,110 +0,0 @@ -"""base58 module. - -Original source: git://github.com/joric/brutus.git -which was forked from git://github.com/samrushing/caesure.git - -Distributed under the MIT/X11 software license, see the accompanying -file COPYING or http://www.opensource.org/licenses/mit-license.php. - -""" - -import hashlib -from binascii import hexlify, unhexlify -from typing import List - - -b58_digits: str = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' - - -def sha256(s: bytes) -> bytes: - return hashlib.new('sha256', s).digest() - - -def hash256(s: bytes) -> bytes: - return sha256(sha256(s)) - - -def encode(b: bytes) -> str: - """Encode bytes to a base58-encoded string""" - - # Convert big-endian bytes to integer - n: int = int('0x0' + hexlify(b).decode('utf8'), 16) - - # Divide that integer into base58 - temp: List[str] = [] - while n > 0: - n, r = divmod(n, 58) - temp.append(b58_digits[r]) - res: str = ''.join(temp[::-1]) - - # Encode leading zeros as base58 zeros - czero: int = 0 - pad: int = 0 - for c in b: - if c == czero: - pad += 1 - else: - break - return b58_digits[0] * pad + res - - -def decode(s: str) -> bytes: - """Decode a base58-encoding string, returning bytes""" - if not s: - return b'' - - # Convert the string to an integer - n: int = 0 - for c in s: - n *= 58 - if c not in b58_digits: - raise ValueError('Character %r is not a valid base58 character' % c) - digit = b58_digits.index(c) - n += digit - - # Convert the integer to bytes - h: str = '%x' % n - if len(h) % 2: - h = '0' + h - res = unhexlify(h.encode('utf8')) - - # Add padding back. - pad = 0 - for c in s[:-1]: - if c == b58_digits[0]: - pad += 1 - else: - break - return b'\x00' * pad + res - - -def get_xpub_fingerprint(s: str) -> bytes: - data = decode(s) - fingerprint = data[5:9] - return fingerprint - - -def get_xpub_fingerprint_hex(xpub: str) -> str: - data = decode(xpub) - fingerprint = data[5:9] - return hexlify(fingerprint).decode() - - -def to_address(b: bytes, version: bytes) -> str: - data = version + b - checksum = hash256(data)[0:4] - data += checksum - return encode(data) - - -def xpub_to_pub_hex(xpub: str) -> str: - data = decode(xpub) - pubkey = data[-37:-4] - return hexlify(pubkey).decode() - - -def xpub_main_2_test(xpub: str) -> str: - data = decode(xpub) - test_data = b'\x04\x35\x87\xCF' + data[4:-4] - checksum = hash256(test_data)[0:4] - return encode(test_data + checksum) diff --git a/tests/bitcoin_client/hwi/bech32.py b/tests/bitcoin_client/hwi/bech32.py deleted file mode 100644 index 68f24687..00000000 --- a/tests/bitcoin_client/hwi/bech32.py +++ /dev/null @@ -1,123 +0,0 @@ -# Copyright (c) 2017 Pieter Wuille -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -"""Reference implementation for Bech32 and segwit addresses.""" - - -CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" - - -def bech32_polymod(values): - """Internal function that computes the Bech32 checksum.""" - generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3] - chk = 1 - for value in values: - top = chk >> 25 - chk = (chk & 0x1ffffff) << 5 ^ value - for i in range(5): - chk ^= generator[i] if ((top >> i) & 1) else 0 - return chk - - -def bech32_hrp_expand(hrp): - """Expand the HRP into values for checksum computation.""" - return [ord(x) >> 5 for x in hrp] + [0] + [ord(x) & 31 for x in hrp] - - -def bech32_verify_checksum(hrp, data): - """Verify a checksum given HRP and converted data characters.""" - return bech32_polymod(bech32_hrp_expand(hrp) + data) == 1 - - -def bech32_create_checksum(hrp, data): - """Compute the checksum values given HRP and data.""" - values = bech32_hrp_expand(hrp) + data - polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ 1 - return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)] - - -def bech32_encode(hrp, data): - """Compute a Bech32 string given HRP and data values.""" - combined = data + bech32_create_checksum(hrp, data) - return hrp + '1' + ''.join([CHARSET[d] for d in combined]) - - -def bech32_decode(bech): - """Validate a Bech32 string, and determine HRP and data.""" - if ((any(ord(x) < 33 or ord(x) > 126 for x in bech)) or - (bech.lower() != bech and bech.upper() != bech)): - return (None, None) - bech = bech.lower() - pos = bech.rfind('1') - if pos < 1 or pos + 7 > len(bech) or len(bech) > 90: - return (None, None) - if not all(x in CHARSET for x in bech[pos + 1:]): - return (None, None) - hrp = bech[:pos] - data = [CHARSET.find(x) for x in bech[pos + 1:]] - if not bech32_verify_checksum(hrp, data): - return (None, None) - return (hrp, data[:-6]) - - -def convertbits(data, frombits, tobits, pad=True): - """General power-of-2 base conversion.""" - acc = 0 - bits = 0 - ret = [] - maxv = (1 << tobits) - 1 - max_acc = (1 << (frombits + tobits - 1)) - 1 - for value in data: - if value < 0 or (value >> frombits): - return None - acc = ((acc << frombits) | value) & max_acc - bits += frombits - while bits >= tobits: - bits -= tobits - ret.append((acc >> bits) & maxv) - if pad: - if bits: - ret.append((acc << (tobits - bits)) & maxv) - elif bits >= frombits or ((acc << (tobits - bits)) & maxv): - return None - return ret - - -def decode(hrp, addr): - """Decode a segwit address.""" - hrpgot, data = bech32_decode(addr) - if hrpgot != hrp: - return (None, None) - decoded = convertbits(data[1:], 5, 8, False) - if decoded is None or len(decoded) < 2 or len(decoded) > 40: - return (None, None) - if data[0] > 16: - return (None, None) - if data[0] == 0 and len(decoded) != 20 and len(decoded) != 32: - return (None, None) - return (data[0], decoded) - - -def encode(hrp, witver, witprog): - """Encode a segwit address.""" - ret = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5)) - if decode(hrp, ret) == (None, None): - return None - return ret diff --git a/tests/bitcoin_client/hwi/serialization.py b/tests/bitcoin_client/hwi/serialization.py deleted file mode 100644 index fc1cc643..00000000 --- a/tests/bitcoin_client/hwi/serialization.py +++ /dev/null @@ -1,524 +0,0 @@ -"""Bitcoin Object Python Serializations. - -Copyright (c) 2010 ArtForz -- public domain half-a-node -Copyright (c) 2012 Jeff Garzik -Copyright (c) 2010-2016 The Bitcoin Core developers - -Distributed under the MIT software license, see the accompanying -file COPYING or http://www.opensource.org/licenses/mit-license.php. - -Modified from the test/test_framework/mininode.py file from the -Bitcoin repository - -CTransaction,CTxIn, CTxOut, etc....: - data structures that should map to corresponding structures in - bitcoin/primitives for transactions only -ser_*, deser_*: functions that handle serialization/deserialization - -""" - -import struct -import binascii -import hashlib -import copy -import base64 -from io import BytesIO -from typing import ( - List, - Optional, - Sequence, - Tuple, - TypeVar, - Callable -) -from typing_extensions import Protocol - - -class Readable(Protocol): - def read(self, n: int = -1) -> bytes: - ... - - -class Deserializable(Protocol): - def deserialize(self, f: Readable) -> None: - ... - - -class Serializable(Protocol): - def serialize(self) -> bytes: - ... - - -def sha256(s: bytes) -> bytes: - return hashlib.new('sha256', s).digest() - - -def ripemd160(s: bytes) -> bytes: - return hashlib.new('ripemd160', s).digest() - - -def hash256(s: bytes) -> bytes: - return sha256(sha256(s)) - - -def hash160(s: bytes) -> bytes: - return ripemd160(sha256(s)) - - -# Serialization/deserialization tools -def ser_compact_size(size: int) -> bytes: - r: bytes - if size < 253: - r = struct.pack("B", size) - elif size < 0x10000: - r = struct.pack(" int: - nit: int = struct.unpack(" bytes: - nit = deser_compact_size(f) - return f.read(nit) - - -def ser_string(s: bytes) -> bytes: - return ser_compact_size(len(s)) + s - - -def deser_uint256(f: Readable) -> int: - r = 0 - for i in range(8): - t = struct.unpack(" bytes: - rs = b"" - for _ in range(8): - rs += struct.pack(">= 32 - return rs - - -def uint256_from_str(s: bytes) -> int: - r = 0 - t = struct.unpack(" List[D]: - nit = deser_compact_size(f) - r = [] - for _ in range(nit): - t = c() - t.deserialize(f) - r.append(t) - return r - - -def ser_vector(v: Sequence[Serializable]) -> bytes: - r = ser_compact_size(len(v)) - for i in v: - r += i.serialize() - return r - - -def deser_string_vector(f: Readable) -> List[bytes]: - nit = deser_compact_size(f) - r = [] - for _ in range(nit): - t = deser_string(f) - r.append(t) - return r - - -def ser_string_vector(v: List[bytes]) -> bytes: - r = ser_compact_size(len(v)) - for sv in v: - r += ser_string(sv) - return r - - -def hex_to_base64(s: str) -> bytes: - return base64.b64encode(binascii.unhexlify(s)) - - -def ser_sig_der(r: bytes, s: bytes) -> bytes: - sig = b"\x30" - - # Make r and s as short as possible - ri = 0 - for b in r: - if b == 0: - ri += 1 - else: - break - r = r[ri:] - si = 0 - for b in s: - if b == 0: - si += 1 - else: - break - s = s[si:] - - # Make positive of neg - first = r[0] - if first & (1 << 7) != 0: - r = b"\x00" + r - first = s[0] - if first & (1 << 7) != 0: - s = b"\x00" + s - - # Write total length - total_len = len(r) + len(s) + 4 - sig += struct.pack("B", total_len) - - # write r - sig += b"\x02" - sig += struct.pack("B", len(r)) - sig += r - - # write s - sig += b"\x02" - sig += struct.pack("B", len(s)) - sig += s - - sig += b"\x01" - return sig - - -def ser_sig_compact(r: bytes, s: bytes, recid: bytes) -> bytes: - rec = struct.unpack("B", recid)[0] - prefix = struct.pack("B", 27 + 4 + rec) - - sig = b"" - sig += prefix - sig += r + s - - return sig - -# Objects that map to bitcoind objects, which can be serialized/deserialized - - -MSG_WITNESS_FLAG = 1 << 30 - - -class COutPoint(object): - def __init__(self, h: int = 0, n: int = 0xffffffff): - self.hash = h - self.n = n - - def deserialize(self, f: Readable) -> None: - self.hash = deser_uint256(f) - self.n = struct.unpack(" bytes: - r = b"" - r += ser_uint256(self.hash) - r += struct.pack(" str: - return "COutPoint(hash=%064x n=%i)" % (self.hash, self.n) - - -class CTxIn(object): - def __init__( - self, - outpoint: Optional[COutPoint] = None, - scriptSig: bytes = b"", - nSequence: int = 0, - ): - if outpoint is None: - self.prevout = COutPoint() - else: - self.prevout = outpoint - self.scriptSig = scriptSig - self.nSequence = nSequence - - def deserialize(self, f: Readable) -> None: - self.prevout = COutPoint() - self.prevout.deserialize(f) - self.scriptSig = deser_string(f) - self.nSequence = struct.unpack(" bytes: - r = b"" - r += self.prevout.serialize() - r += ser_string(self.scriptSig) - r += struct.pack(" str: - return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" \ - % (repr(self.prevout), self.scriptSig.hex(), - self.nSequence) - - -def is_p2sh(script: bytes) -> bool: - return len(script) == 23 and script[0] == 0xa9 and script[1] == 0x14 and script[22] == 0x87 - - -def is_p2pkh(script: bytes) -> bool: - return (len(script) == 25 and - script[0] == 0x76 and - script[1] == 0xa9 and - script[2] == 0x14 and - script[23] == 0x88 and - script[24] == 0xac) - - -def is_p2pk(script: bytes) -> bool: - return ((len(script) == 35 or len(script) == 67) and - (script[0] == 0x21 or script[0] == 0x41) and - script[-1] == 0xac) - - -def is_witness(script: bytes) -> Tuple[bool, int, bytes]: - if len(script) < 4 or len(script) > 42: - return False, 0, b"" - - if script[0] != 0 and (script[0] < 81 or script[0] > 96): - return False, 0, b"" - - if script[1] + 2 == len(script): - return True, script[0] - 0x50 if script[0] else 0, script[2:] - - return False, 0, b"" - - -def is_p2wpkh(script: bytes) -> bool: - is_wit, wit_ver, wit_prog = is_witness(script) - if not is_wit: - return False - elif wit_ver != 0: - return False - return len(wit_prog) == 20 - - -def is_p2wsh(script: bytes) -> bool: - is_wit, wit_ver, wit_prog = is_witness(script) - if not is_wit: - return False - elif wit_ver != 0: - return False - return len(wit_prog) == 32 - - -class CTxOut(object): - def __init__(self, nValue: int = 0, scriptPubKey: bytes = b""): - self.nValue = nValue - self.scriptPubKey = scriptPubKey - - def deserialize(self, f: Readable) -> None: - self.nValue = struct.unpack(" bytes: - r = b"" - r += struct.pack(" bool: - return is_p2sh(self.scriptPubKey) - - def is_p2pkh(self) -> bool: - return is_p2pkh(self.scriptPubKey) - - def is_p2pk(self) -> bool: - return is_p2pk(self.scriptPubKey) - - def is_witness(self) -> Tuple[bool, int, bytes]: - return is_witness(self.scriptPubKey) - - def __repr__(self) -> str: - return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" \ - % (self.nValue, self.nValue, self.scriptPubKey.hex()) - - -class CScriptWitness(object): - def __init__(self) -> None: - # stack is a vector of strings - self.stack: List[bytes] = [] - - def __repr__(self) -> str: - return "CScriptWitness(%s)" % \ - (",".join([x.hex() for x in self.stack])) - - def is_null(self) -> bool: - if self.stack: - return False - return True - - -class CTxInWitness(object): - def __init__(self) -> None: - self.scriptWitness = CScriptWitness() - - def deserialize(self, f: Readable) -> None: - self.scriptWitness.stack = deser_string_vector(f) - - def serialize(self) -> bytes: - return ser_string_vector(self.scriptWitness.stack) - - def __repr__(self) -> str: - return repr(self.scriptWitness) - - def is_null(self) -> bool: - return self.scriptWitness.is_null() - - -class CTxWitness(object): - def __init__(self) -> None: - self.vtxinwit: List[CTxInWitness] = [] - - def deserialize(self, f: Readable) -> None: - for i in range(len(self.vtxinwit)): - self.vtxinwit[i].deserialize(f) - - def serialize(self) -> bytes: - r = b"" - # This is different than the usual vector serialization -- - # we omit the length of the vector, which is required to be - # the same length as the transaction's vin vector. - for x in self.vtxinwit: - r += x.serialize() - return r - - def __repr__(self) -> str: - return "CTxWitness(%s)" % \ - (';'.join([repr(x) for x in self.vtxinwit])) - - def is_null(self) -> bool: - for x in self.vtxinwit: - if not x.is_null(): - return False - return True - - -class CTransaction(object): - def __init__(self, tx: Optional['CTransaction'] = None) -> None: - if tx is None: - self.nVersion = 1 - self.vin: List[CTxIn] = [] - self.vout: List[CTxOut] = [] - self.wit = CTxWitness() - self.nLockTime = 0 - self.sha256: Optional[int] = None - self.hash: Optional[str] = None - else: - self.nVersion = tx.nVersion - self.vin = copy.deepcopy(tx.vin) - self.vout = copy.deepcopy(tx.vout) - self.nLockTime = tx.nLockTime - self.sha256 = tx.sha256 - self.hash = tx.hash - self.wit = copy.deepcopy(tx.wit) - - def deserialize(self, f: Readable) -> None: - self.nVersion = struct.unpack(" bytes: - r = b"" - r += struct.pack(" bytes: - flags = 0 - if not self.wit.is_null(): - flags |= 1 - r = b"" - r += struct.pack(" bytes: - return self.serialize_without_witness() - - # Recalculate the txid (transaction hash without witness) - def rehash(self) -> None: - self.sha256 = None - self.calc_sha256() - - # We will only cache the serialization without witness in - # self.sha256 and self.hash -- those are expected to be the txid. - def calc_sha256(self, with_witness: bool = False) -> Optional[int]: - if with_witness: - # Don't cache the result, just return it - return uint256_from_str(hash256(self.serialize_with_witness())) - - if self.sha256 is None: - self.sha256 = uint256_from_str(hash256(self.serialize_without_witness())) - self.hash = hash256(self.serialize())[::-1].hex() - return None - - def is_null(self) -> bool: - return len(self.vin) == 0 and len(self.vout) == 0 - - @classmethod - def from_bytes(cls, b: bytes): - tx = cls() - tx.deserialize(BytesIO(b)) - - return tx - - def __repr__(self) -> str: - return "CTransaction(nVersion=%i vin=%s vout=%s wit=%s nLockTime=%i)" \ - % (self.nVersion, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime) diff --git a/tests/bitcoin_client/utils.py b/tests/bitcoin_client/utils.py deleted file mode 100644 index 1027127d..00000000 --- a/tests/bitcoin_client/utils.py +++ /dev/null @@ -1,55 +0,0 @@ -from typing import Tuple, Iterator - - -MAX_APDU_LEN: int = 255 - - -def chunkify(data: bytes, chunk_len: int) -> Iterator[Tuple[bool, bytes]]: - """Split `data` into chunk of length `chunk_len`.`""" - size: int = len(data) - - if size <= chunk_len: - yield True, data - return - - chunk: int = size // chunk_len - remaining: int = size % chunk_len - offset: int = 0 - - for i in range(chunk): - yield False, data[offset:offset + chunk_len] - offset += chunk_len - - if remaining: - yield True, data[offset:] - - -def deser_trusted_input(trusted_input: bytes - ) -> Tuple[int, int, bytes, bytes, int, int, bytes]: - """Deserialize trusted input into 7 items.""" - assert len(trusted_input) == 56 - - offset: int = 0 - magic_trusted_input: int = trusted_input[offset] - assert magic_trusted_input == 0x32 - offset += 1 - zero: int = trusted_input[offset] - assert zero == 0x00 - offset += 1 - random: bytes = trusted_input[offset:offset + 2] - offset += 2 - prev_txid: bytes = trusted_input[offset:offset + 32] - offset += 32 - out_index: int = int.from_bytes(trusted_input[offset:offset + 4], - byteorder="little") - offset += 4 - amount: int = int.from_bytes(trusted_input[offset:offset + 8], - byteorder="little") - offset += 8 - hmac: bytes = trusted_input[offset:offset + 8] - offset += 8 - - assert offset == len(trusted_input) - - return (magic_trusted_input, zero, random, - prev_txid, out_index, amount, hmac) diff --git a/tests/clean_tests.sh b/tests/clean_tests.sh deleted file mode 100755 index 83b9187b..00000000 --- a/tests/clean_tests.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -rm -rf bitcoin-bin -rm -rf bitcoin-testnet-bin diff --git a/tests/conftest.py b/tests/conftest.py index ce9311e6..84c0c98a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,82 +1,31 @@ -import subprocess -import os -import socket -import time -import logging import pytest +from pathlib import Path -from ledgercomm import Transport +from ragger.conftest import configuration +from ragger.backend.interface import BackendInterface +from ragger_bitcoin import createRaggerClient, RaggerClient -from bitcoin_client.bitcoin_cmd import BitcoinCommand +########################### +### CONFIGURATION START ### +########################### +# You can configure optional parameters by overriding the value of ragger.configuration.OPTIONAL_CONFIGURATION +# Please refer to ragger/conftest/configuration.py for their descriptions and accepted values -logging.basicConfig(level=logging.INFO) +MNEMONIC = "glory promote mansion idle axis finger extra february uncover one trip resource lawn turtle enact monster seven myth punch hobby comfort wild raise skin" +configuration.OPTIONAL.CUSTOM_SEED = MNEMONIC +configuration.OPTIONAL.BACKEND_SCOPE = "function" -def pytest_addoption(parser): - parser.addoption("--hid", - action="store_true") +######################### +### CONFIGURATION END ### +######################### +TESTS_ROOT_DIR = Path(__file__).parent -@pytest.fixture -def hid(pytestconfig): - return pytestconfig.getoption("hid") - -@pytest.fixture -def device(request, hid): - # If running on real hardware, nothing to do here - if hid: - yield - return - - # Gets the speculos executable from the SPECULOS environment variable, - # or hopes that "speculos.py" is in the $PATH if not set - speculos_executable = os.environ.get("SPECULOS", "speculos.py") - - base_args = [ - speculos_executable, "./bitcoin-testnet-bin/app.elf", - "-l", "Bitcoin Legacy:./bitcoin-bin/app.elf", - "--sdk", "2.0", - "--display", "headless" - ] - - # Look for the automation_file attribute in the test function, if present - try: - automation_args = ["--automation", f"file:{request.function.automation_file}"] - except AttributeError: - automation_args = [] - - speculos_proc = subprocess.Popen([*base_args, *automation_args]) +# Pull all features from the base ragger conftest using the overridden configuration +pytest_plugins = ("ragger.conftest.base_conftest", ) - # Attempts to connect to speculos to make sure that it's ready when the test starts - for _ in range(100): - try: - socket.create_connection(("127.0.0.1", 9999), timeout=1.0) - connected = True - break - except ConnectionRefusedError: - time.sleep(0.1) - connected = False - - if not connected: - raise RuntimeError("Unable to connect to speculos.") - - yield - - speculos_proc.terminate() - speculos_proc.wait() - - -@pytest.fixture -def transport(device, hid): - transport = (Transport(interface="hid", debug=True) - if hid else Transport(interface="tcp", - server="127.0.0.1", - port=9999, - debug=True)) - yield transport - transport.close() - @pytest.fixture -def cmd(transport): - return BitcoinCommand(transport=transport, debug=False) +def client(backend: BackendInterface) -> RaggerClient: + return createRaggerClient(backend, screenshot_dir=TESTS_ROOT_DIR) diff --git a/tests/data/many-to-many/p2pkh/apdu_debug.log b/tests/data/many-to-many/p2pkh/apdu_debug.log deleted file mode 100644 index ac5e51b0..00000000 --- a/tests/data/many-to-many/p2pkh/apdu_debug.log +++ /dev/null @@ -1,446 +0,0 @@ -New APDU received: -E0C4000000 -New APDU received: -F026000000 -New APDU received: -E0C4000000 -New APDU received: -E024000000 -New APDU received: -E02280000130 -New APDU received: -E04000000100 -pin ok -Using private component -34AC5D784EBB4DF4727BCDDF6A6743F5D5D46D83DD74AA825866390C694F2938 -To hash -0251EC84E33A3119486461A44240E906FF94BF40CF807B025B1CA43332B80DC9DB -Hash160 -F5ACC2FD5C60B7263C4A459541C1473BC29E58F4 -Checksum -A21FB2F3 -Length to encode 25 -To encode -6FF5ACC2FD5C60B7263C4A459541C1473BC29E58F4A21FB2F3 -Length encoded 34 -Encoded -6E3375786F6B3843337A566277476A72584476344E544E516A313865335A4D4A426B -Length 34 -New APDU received: -E0400000050180000000 -pin ok -Using private component -C71AE2E616FBCCC325A71600E9C82816505A6373EFCE4CAEDA60400667E0B75C -To hash -02E5646066C2C51CEAEA66F04EC85858D34E2BD285F4A60B1402BFC03CF462E767 -Hash160 -7D825341D36FC1297A41A9839A72975815B1FE61 -Checksum -E01B4FD2 -Length to encode 25 -To encode -6F7D825341D36FC1297A41A9839A72975815B1FE61E01B4FD2 -Length encoded 34 -Encoded -6D727861744272776D555959504E774E4879334A5461567350474750716A4A68674D -Length 34 -New APDU received: -E040000009028000002C80000001 -pin ok -Using private component -D0A20FEE4287C3C34ED5C30030FED4E87A6D4A86C87F8281091482BE76E266AD -To hash -03AC9DC20F0C2E9483FBDF9060E8154A19E38B1A886E0883B1E5E7C5582D56A638 -Hash160 -7CAC5506C90EF8E1F7D8928BDC0E3DC0DA4CD714 -Checksum -0EE9DF4F -Length to encode 25 -To encode -6F7CAC5506C90EF8E1F7D8928BDC0E3DC0DA4CD7140EE9DF4F -Length encoded 34 -Encoded -6D727441586771544634423463736770507972663639336455374C3256766A5A787A -Length 34 -New APDU received: -E04000000D038000002C8000000180000000 -pin ok -Using private component -F2D80B9A6B840D409622DB675EE45A2ED8051029D298F847AA8905BEC7967453 -To hash -03E84C7F4B7662FAED9F5EB2D812D9B7BCF0E0BF2A33B17AC45E38B8459669C321 -Hash160 -0812D36245DAC14478722DB30D66285EB115661A -Checksum -E53861E3 -Length to encode 25 -To encode -6F0812D36245DAC14478722DB30D66285EB115661AE53861E3 -Length encoded 34 -Encoded -6D6746654664344D42345A6B566257644647546156356956693369426668775A617A -Length 34 -New APDU received: -E0C4000000 -New APDU received: -E042000009000000000200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -01 -Number of inputs : 1 -Process input -New APDU received: -E042800025F4C2B478DC9CEA2DF43C8BB94938FF43F3BED5AEB3AF9E36CDB7016104626BF2000000006B -Process input ---- ADD TO HASH FULL: -F4C2B478DC9CEA2DF43C8BB94938FF43F3BED5AEB3AF9E36CDB7016104626BF200000000 ---- ADD TO HASH FULL: -6B -Script to read 107 -Process input script, remaining 107 -New APDU received: -E04280006F483045022100B7B8244B3F83648397FA3C37349ED1827BF40BFCA22D4F87CC019D3FDED63E1D02205434CE222DE35E04AB98BE54AF57D2C8B464F0DA76A0275443B33C7B1DF79344012103462F1E48396CE2A4D7694D107FEF5123FE4D1E394394A370FA4901E744B4884EFDFFFFFF -Process input script, remaining 107 ---- ADD TO HASH FULL: -483045022100B7B8244B3F83648397FA3C37349ED1827BF40BFCA22D4F87CC019D3FDED63E1D02205434CE222DE35E04AB98BE54AF57D2C8B464F0DA76A0275443B33C7B1DF79344012103462F1E48396CE2A4D7694D107FEF5123FE4D1E394394A370FA4901E744B488 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -4E ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -New APDU received: -E04280000102 -Input hashing done ---- ADD TO HASH FULL: -02 -Number of outputs : 2 -New APDU received: -E042800009DCDB06000000000019 ---- ADD TO HASH FULL: -DCDB060000000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process output script, remaining 25 -New APDU received: -E04280001976A914B242BA04B8526B533B17B168D27EAF0DA7BACB8588AC -Process output script, remaining 25 ---- ADD TO HASH FULL: -76A914B242BA04B8526B533B17B168D27EAF0DA7BACB8588AC -Process output script, remaining 0 -New APDU received: -E042800009706408000000000019 -Process output script, remaining 0 ---- ADD TO HASH FULL: -7064080000000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process output script, remaining 25 -New APDU received: -E04280001976A91426C680EC6AC9C0ED760177F92096F1C5571B72EF88AC -Process output script, remaining 25 ---- ADD TO HASH FULL: -76A91426C680EC6AC9C0ED760177F92096F1C5571B72EF88AC -Process output script, remaining 0 -New APDU received: -E04280000420041D00 -Process output script, remaining 0 -Output hashing done ---- ADD TO HASH FULL: -20041D00 -Transaction parsed -New APDU received: -E042000009000000010200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -01 -Number of inputs : 1 -Process input -New APDU received: -E0428000255DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E34010000006B -Process input ---- ADD TO HASH FULL: -5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3401000000 ---- ADD TO HASH FULL: -6B -Script to read 107 -Process input script, remaining 107 -New APDU received: -E04280006F483045022100C806957429935C5D61F548223C3536DC739FE351814BCE9EDC1694E5A5C25ABF022013E307B0B4885ACB64CCFFAF5F4794F205040325EBC36C258787C488B038C2BB0121038BA462D7DD65917ECE454142903BB362A0B412D1841D52087AD881646B6CDCCFFDFFFFFF -Process input script, remaining 107 ---- ADD TO HASH FULL: -483045022100C806957429935C5D61F548223C3536DC739FE351814BCE9EDC1694E5A5C25ABF022013E307B0B4885ACB64CCFFAF5F4794F205040325EBC36C258787C488B038C2BB0121038BA462D7DD65917ECE454142903BB362A0B412D1841D52087AD881646B6CDC -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -CF ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -New APDU received: -E04280000102 -Input hashing done ---- ADD TO HASH FULL: -02 -Number of outputs : 2 -New APDU received: -E042800009140C03000000000019 ---- ADD TO HASH FULL: -140C030000000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process output script, remaining 25 -New APDU received: -E04280001976A914B3E17C4DEF8A39148ED6FAD7DC6FEBE30DD324CB88AC -Process output script, remaining 25 ---- ADD TO HASH FULL: -76A914B3E17C4DEF8A39148ED6FAD7DC6FEBE30DD324CB88AC -Process output script, remaining 0 -New APDU received: -E042800009305705000000000019 -Process output script, remaining 0 ---- ADD TO HASH FULL: -3057050000000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process output script, remaining 25 -New APDU received: -E04280001976A914E0A89380635F18B7EE09546D963232BCB992412B88AC -Process output script, remaining 25 ---- ADD TO HASH FULL: -76A914E0A89380635F18B7EE09546D963232BCB992412B88AC -Process output script, remaining 0 -New APDU received: -E042800004FE041D00 -Process output script, remaining 0 -Output hashing done ---- ADD TO HASH FULL: -FE041D00 -Transaction parsed -New APDU received: -E02601000101 -New APDU received: -E0440000050200000002 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH AUTH: -02000000 ---- ADD TO HASH FULL: -02 ---- ADD TO HASH AUTH: -02 -Number of inputs : 2 -Process input -New APDU received: -E04480003B013832005E0D5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3400000000DCDB060000000000D9A1FF455D570FF519 -Process input -====> Input HMAC: D9A1FF455D570FF5 -====> Computed HMAC: D9A1FF455D570FF5 -Trusted input hash -5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3400000000 ---- ADD TO HASH FULL: -5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3400000000 ---- ADD TO HASH AUTH: -5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3400000000 -Adding amount -DCDB060000000000 -New amount -000000000006DBDC ---- ADD TO HASH FULL: -19 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A914B242BA04B8526B533B17B168D27EAF0DA7BACB8588ACFDFFFFFF -Process input script, remaining 25 ---- ADD TO HASH FULL: -76A914B242BA04B8526B533B17B168D27EAF0DA7BACB8588 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -AC ---- ADD TO HASH FULL: -FDFFFFFF ---- ADD TO HASH AUTH: -FDFFFFFF -Process input -New APDU received: -E04480003B01383200BA0857F891351E60E944718F1DF12B4F77B642CC63146184BEDC6C7BC64A0C0B39DE010000003057050000000000124EAC0C193C39F400 -Process input -====> Input HMAC: 124EAC0C193C39F4 -====> Computed HMAC: 124EAC0C193C39F4 -Trusted input hash -57F891351E60E944718F1DF12B4F77B642CC63146184BEDC6C7BC64A0C0B39DE01000000 ---- ADD TO HASH FULL: -57F891351E60E944718F1DF12B4F77B642CC63146184BEDC6C7BC64A0C0B39DE01000000 ---- ADD TO HASH AUTH: -57F891351E60E944718F1DF12B4F77B642CC63146184BEDC6C7BC64A0C0B39DE01000000 -Adding amount -3057050000000000 -New amount -00000000000C330C ---- ADD TO HASH FULL: -00 -Script to read 0 -Process input script, remaining 0 -New APDU received: -E044800004FDFFFFFF -Process input script, remaining 0 ---- ADD TO HASH FULL: -FDFFFFFF ---- ADD TO HASH AUTH: -FDFFFFFF -Process input -Input hashing done -Presign ready -New APDU received: -E04AFF0015058000002C80000001800000000000000100000002 -state=1 -Using private component -B35419B8D5EE1629A70718308955F5E8B736EC0C843FB2BEDB94940A29ADC18C -New APDU received: -E04A000032025C900400000000001976A914D8BB03D84A3AA993AE6DB1114488488DAB43D6DB88AC20A10700000000001976A914CBAE5B -state=1 ---- ADD TO HASH FULL: -025C900400000000001976A914D8BB03D84A3AA993AE6DB1114488488DAB43D6DB88AC20A10700000000001976A914CBAE5B ---- ADD TO HASH AUTH: -025C900400000000001976A914D8BB03D84A3AA993AE6DB1114488488DAB43D6DB88AC20A10700000000001976A914CBAE5B -New APDU received: -E04A80001350CF939E6F531B8A6B7ABD788FE14B029788AC -state=2 ---- ADD TO HASH FULL: -50CF939E6F531B8A6B7ABD788FE14B029788AC ---- ADD TO HASH AUTH: -50CF939E6F531B8A6B7ABD788FE14B029788AC -Checksum -21F8E07E -Length to encode 25 -To encode -6FCBAE5B50CF939E6F531B8A6B7ABD788FE14B029721F8E07E -Length encoded 34 -Encoded -6D7A35764C57644D3177485647536D58556B684B56765A624A32673465704D58536D -New APDU received: -E04800001B058000002C8000000180000000000000010000000000001D04D901 ---- ADD TO HASH FULL: -D9041D0001000000 -Using private component -AAEAB6598E3F057858A97DBDC8E9291F6EBECBB5D5D68BE0F83B623BA6EA3471 -Hash1 -B7DC3C28B80673141EFF6523DEFC02C054F7E6F8B7D977FB4490BBAEA2613E23 -Hash2 -C16F948104A1637627CD46DDB28D454C65A58B497D725A30081074BC632DD0A7 -New APDU received: -E0440080050200000002 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH AUTH: -02000000 ---- ADD TO HASH FULL: -02 ---- ADD TO HASH AUTH: -02 -Number of inputs : 2 -Process input -New APDU received: -E04480003B013832005E0D5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3400000000DCDB060000000000D9A1FF455D570FF500 -Process input -====> Input HMAC: D9A1FF455D570FF5 -====> Computed HMAC: D9A1FF455D570FF5 -Trusted input hash -5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3400000000 ---- ADD TO HASH FULL: -5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3400000000 ---- ADD TO HASH AUTH: -5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3400000000 -Adding amount -DCDB060000000000 -New amount -000000000006DBDC ---- ADD TO HASH FULL: -00 -Script to read 0 -Process input script, remaining 0 -New APDU received: -E044800004FDFFFFFF -Process input script, remaining 0 ---- ADD TO HASH FULL: -FDFFFFFF ---- ADD TO HASH AUTH: -FDFFFFFF -Process input -New APDU received: -E04480003B01383200BA0857F891351E60E944718F1DF12B4F77B642CC63146184BEDC6C7BC64A0C0B39DE010000003057050000000000124EAC0C193C39F419 -Process input -====> Input HMAC: 124EAC0C193C39F4 -====> Computed HMAC: 124EAC0C193C39F4 -Trusted input hash -57F891351E60E944718F1DF12B4F77B642CC63146184BEDC6C7BC64A0C0B39DE01000000 ---- ADD TO HASH FULL: -57F891351E60E944718F1DF12B4F77B642CC63146184BEDC6C7BC64A0C0B39DE01000000 ---- ADD TO HASH AUTH: -57F891351E60E944718F1DF12B4F77B642CC63146184BEDC6C7BC64A0C0B39DE01000000 -Adding amount -3057050000000000 -New amount -00000000000C330C ---- ADD TO HASH FULL: -19 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A914E0A89380635F18B7EE09546D963232BCB992412B88ACFDFFFFFF -Process input script, remaining 25 ---- ADD TO HASH FULL: -76A914E0A89380635F18B7EE09546D963232BCB992412B88 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -AC ---- ADD TO HASH FULL: -FDFFFFFF ---- ADD TO HASH AUTH: -FDFFFFFF -Process input -Input hashing done -Presign ready -New APDU received: -E04AFF0015058000002C80000001800000000000000100000002 -state=1 -New APDU received: -E04A000032025C900400000000001976A914D8BB03D84A3AA993AE6DB1114488488DAB43D6DB88AC20A10700000000001976A914CBAE5B -state=1 ---- ADD TO HASH FULL: -025C900400000000001976A914D8BB03D84A3AA993AE6DB1114488488DAB43D6DB88AC20A10700000000001976A914CBAE5B ---- ADD TO HASH AUTH: -025C900400000000001976A914D8BB03D84A3AA993AE6DB1114488488DAB43D6DB88AC20A10700000000001976A914CBAE5B -New APDU received: -E04A80001350CF939E6F531B8A6B7ABD788FE14B029788AC -state=1 ---- ADD TO HASH FULL: -50CF939E6F531B8A6B7ABD788FE14B029788AC ---- ADD TO HASH AUTH: -50CF939E6F531B8A6B7ABD788FE14B029788AC -New APDU received: -E04800001B058000002C8000000180000000000000000000000300001D04D901 ---- ADD TO HASH FULL: -D9041D0001000000 -Using private component -BC8CF06B27565698FBD1BEE909B761B17AF6D137D2CAA6ECEA6D45FC60C0DD5A -Hash1 -357754D0F6F0755BBAB62C6567F70A85A46AB5C4C7EE43CE52931B15E9837D69 -Hash2 -3C34D939F56D25E9636E1584D31C6D7E315F5BB28BD6071220978F3B10BD27B0 diff --git a/tests/data/many-to-many/p2pkh/tx.json b/tests/data/many-to-many/p2pkh/tx.json deleted file mode 100644 index ce38b5b4..00000000 --- a/tests/data/many-to-many/p2pkh/tx.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "txid": "6eb7ece9e847574ca460414b6c2db535cec29ba803cd79d2c0718bd66c289fba", - "raw": "02000000025df7b9e20c52d1da2701a244a49754215266f016f6bd77f640a5200cd1fb7e34000000006a4730440220186ec195f04cfedc62d6d383a855e4b0fec550efedd22c177d2031b293556c16022039f05b1b8cc40c48d07323fdf3cc0453909d54409551c7ddc259210b2862bc54012103ed3cf038f00b7ad1c3998e66cf22a688ab5dbaed8400784cbf962d54cd42c2bffdffffff57f891351e60e944718f1df12b4f77b642cc63146184bedc6c7bc64a0c0b39de010000006a47304402201592969826e01baba12c9833584e0e958c1562736192bd1264d079383e8f277902204d5aafb9566a6de419b9446536ccce62f750361530d2a8f9a3bbc5e47af685900121035879ca173a9c1b3f300ec587fb4cc6d54d618e30584e425c1b53b98828708f1dfdffffff025c900400000000001976a914d8bb03d84a3aa993ae6db1114488488dab43d6db88ac20a10700000000001976a914cbae5b50cf939e6f531b8a6b7abd788fe14b029788acd9041d00", - "amount": 500000, - "fees": 400, - "to": "mz5vLWdM1wHVGSmXUkhKVvZbJ2g4epMXSm", - "sign_paths": ["m/84'/1'/0'/1/0", "m/84'/1'/0'/0/3"], - "change_path": "m/84'/1'/0'/1/2", - "lock_time": 1901785, - "utxos": [ - { - "txid": "347efbd10c20a540f677bdf616f06652215497a444a20127dad1520ce2b9f75d", - "raw": "0200000001f4c2b478dc9cea2df43c8bb94938ff43f3bed5aeb3af9e36cdb7016104626bf2000000006b483045022100b7b8244b3f83648397fa3c37349ed1827bf40bfca22d4f87cc019d3fded63e1d02205434ce222de35e04ab98be54af57d2c8b464f0da76a0275443b33c7b1df79344012103462f1e48396ce2a4d7694d107fef5123fe4d1e394394a370fa4901e744b4884efdffffff02dcdb0600000000001976a914b242ba04b8526b533b17b168d27eaf0da7bacb8588ac70640800000000001976a91426c680ec6ac9c0ed760177f92096f1c5571b72ef88ac20041d00", - "output_indexes": [0], - "output_amounts": [449500] - }, - { - "txid": "de390b0c4ac67b6cdcbe84611463cc42b6774f2bf11d8f7144e9601e3591f857", - "raw": "02000000015df7b9e20c52d1da2701a244a49754215266f016f6bd77f640a5200cd1fb7e34010000006b483045022100c806957429935c5d61f548223c3536dc739fe351814bce9edc1694e5a5c25abf022013e307b0b4885acb64ccffaf5f4794f205040325ebc36c258787c488b038c2bb0121038ba462d7dd65917ece454142903bb362a0b412d1841d52087ad881646b6cdccffdffffff02140c0300000000001976a914b3e17c4def8a39148ed6fad7dc6febe30dd324cb88ac30570500000000001976a914e0a89380635f18b7ee09546d963232bcb992412b88acfe041d00", - "output_indexes": [1], - "output_amounts": [350000] - } - ] - -} diff --git a/tests/data/many-to-many/p2sh-p2wpkh/apdu_debug.log b/tests/data/many-to-many/p2sh-p2wpkh/apdu_debug.log deleted file mode 100644 index 053cd54d..00000000 --- a/tests/data/many-to-many/p2sh-p2wpkh/apdu_debug.log +++ /dev/null @@ -1,359 +0,0 @@ -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E042000009000000000200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -01 -Number of inputs : 1 -Process input -New APDU received: -E042800025C3945B596FD88FD0D3031A2DF8963A68ADF9E9F0DFEF4F3C4DD72DF7D80777AE0000000017 -Process input ---- ADD TO HASH FULL: -C3945B596FD88FD0D3031A2DF8963A68ADF9E9F0DFEF4F3C4DD72DF7D80777AE00000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process input script, remaining 23 -New APDU received: -E04280001B16001485D33A279D6AE91E59E0C43DE832FD4C3398252DFDFFFFFF -Process input script, remaining 23 ---- ADD TO HASH FULL: -16001485D33A279D6AE91E59E0C43DE832FD4C339825 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -2D ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -New APDU received: -E04280000102 -Input hashing done ---- ADD TO HASH FULL: -02 -Number of outputs : 2 -New APDU received: -E042800009909F07000000000017 ---- ADD TO HASH FULL: -909F070000000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process output script, remaining 23 -New APDU received: -E042800017A914F0464D9FA0EA42D80E4D5F1457883982E23B8EEC87 -Process output script, remaining 23 ---- ADD TO HASH FULL: -A914F0464D9FA0EA42D80E4D5F1457883982E23B8EEC87 -Process output script, remaining 0 -New APDU received: -E04280000920A107000000000017 -Process output script, remaining 0 ---- ADD TO HASH FULL: -20A1070000000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process output script, remaining 23 -New APDU received: -E042800017A91423E6F63C476F49E8ACF6AA583A0FDEC7B8ACA64587 -Process output script, remaining 23 ---- ADD TO HASH FULL: -A91423E6F63C476F49E8ACF6AA583A0FDEC7B8ACA64587 -Process output script, remaining 0 -New APDU received: -E04280000400041D00 -Process output script, remaining 0 -Output hashing done ---- ADD TO HASH FULL: -00041D00 -Transaction parsed -New APDU received: -E042000009000000010200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -01 -Number of inputs : 1 -Process input -New APDU received: -E042800025C3945B596FD88FD0D3031A2DF8963A68ADF9E9F0DFEF4F3C4DD72DF7D80777AE0000000017 -Process input ---- ADD TO HASH FULL: -C3945B596FD88FD0D3031A2DF8963A68ADF9E9F0DFEF4F3C4DD72DF7D80777AE00000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process input script, remaining 23 -New APDU received: -E04280001B16001485D33A279D6AE91E59E0C43DE832FD4C3398252DFDFFFFFF -Process input script, remaining 23 ---- ADD TO HASH FULL: -16001485D33A279D6AE91E59E0C43DE832FD4C339825 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -2D ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -New APDU received: -E04280000102 -Input hashing done ---- ADD TO HASH FULL: -02 -Number of outputs : 2 -New APDU received: -E042800009909F07000000000017 ---- ADD TO HASH FULL: -909F070000000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process output script, remaining 23 -New APDU received: -E042800017A914F0464D9FA0EA42D80E4D5F1457883982E23B8EEC87 -Process output script, remaining 23 ---- ADD TO HASH FULL: -A914F0464D9FA0EA42D80E4D5F1457883982E23B8EEC87 -Process output script, remaining 0 -New APDU received: -E04280000920A107000000000017 -Process output script, remaining 0 ---- ADD TO HASH FULL: -20A1070000000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process output script, remaining 23 -New APDU received: -E042800017A91423E6F63C476F49E8ACF6AA583A0FDEC7B8ACA64587 -Process output script, remaining 23 ---- ADD TO HASH FULL: -A91423E6F63C476F49E8ACF6AA583A0FDEC7B8ACA64587 -Process output script, remaining 0 -New APDU received: -E04280000400041D00 -Process output script, remaining 0 -Output hashing done ---- ADD TO HASH FULL: -00041D00 -Transaction parsed -New APDU received: -E02601000101 -New APDU received: -E0440002050200000002 -Init transaction parser -Number of inputs : 2 -Process input -New APDU received: -E04480003B01383200F97C53D3C0B27291BFFBF09D6EF5BD4F6051ED911914F55BEF0E3315B258BB13108900000000909F07000000000045E1BEBC7832647019 -Process input -Trusted input used in segwit mode -====> Input HMAC: 45E1BEBC78326470 -====> Computed HMAC: 45E1BEBC78326470 -Adding amount -909F070000000000 -New amount -0000000000079F90 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A914CB078087EFF485AAA2260E94A53D7D6D1C5DD15188ACFDFFFFFF -Process input script, remaining 25 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -FDFFFFFF -Process input -New APDU received: -E04480003B01383200F2B153D3C0B27291BFFBF09D6EF5BD4F6051ED911914F55BEF0E3315B258BB1310890100000020A10700000000005B710DFE9F3F308D00 -Process input -Trusted input used in segwit mode -====> Input HMAC: 5B710DFE9F3F308D -====> Computed HMAC: 5B710DFE9F3F308D -Adding amount -20A1070000000000 -New amount -00000000000F40B0 -Script to read 0 -Process input script, remaining 0 -New APDU received: -E044800004FDFFFFFF -Process input script, remaining 0 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done ---- ADD TO HASH FULL: -82D397CBBCFF87BC5D0C4C70E424F9B830EFBAD7BF0BE479DA5D1D1BAFDB9798 -hashPrevout -4E7FBD6CBE534923DBDC2E194612F7040271013133C736C5AE3DFC0CF1034370 -hashSequence -957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A098 -Presign ready -New APDU received: -E04AFF0015058000003180000001800000000000000100000001 -state=1 -Using private component -B2E6AA60D0137A93FF51ABE4FCA1512EF016222473B454CA9A4B4B9C8AB8402C -New APDU received: -E04A00003202840A03000000000017A914FFC91A30E33FC6D6ECFF42E4D9BD6C7E115D84988700350C000000000017A9142F5864A8ACD2 -state=1 ---- ADD TO HASH FULL: -840A03000000000017A914FFC91A30E33FC6D6ECFF42E4D9BD6C7E115D84988700350C000000000017A9142F5864A8ACD2 -New APDU received: -E04A80000F3FA85977D73E9AC30FD6B341B78C87 -state=2 ---- ADD TO HASH FULL: -3FA85977D73E9AC30FD6B341B78C87 -hashOutputs -B3B2A31981BCC4F256B0851EBE9D7A11BFBFA8559E7795190B4472D7E1E974C9 -Auth Hash: -E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 -Checksum -CD4FBEC6 -Length to encode 25 -To encode -C42F5864A8ACD23FA85977D73E9AC30FD6B341B78CCD4FBEC6 -Length encoded 35 -Encoded -324D775A5A6479336243764568695073427963726543466971774468796B4163574E39 -Segwit parsed once -New APDU received: -E0440080050200000001 -Init transaction parser -Resume SegWit hash -SEGWIT Version -02000000 -SEGWIT HashedPrevouts -4E7FBD6CBE534923DBDC2E194612F7040271013133C736C5AE3DFC0CF1034370 -SEGWIT HashedSequence -957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A098 ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -4E7FBD6CBE534923DBDC2E194612F7040271013133C736C5AE3DFC0CF1034370 ---- ADD TO HASH FULL: -957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A098 ---- ADD TO HASH AUTH: -4E7FBD6CBE534923DBDC2E194612F7040271013133C736C5AE3DFC0CF1034370957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A098B3B2A31981BCC4F256B0851EBE9D7A11BFBFA8559E7795190B4472D7E1E974C9 -Number of inputs : 1 -Process input -New APDU received: -E04480003B01383200F97C53D3C0B27291BFFBF09D6EF5BD4F6051ED911914F55BEF0E3315B258BB13108900000000909F07000000000045E1BEBC7832647019 -Process input -Trusted input used in segwit mode -====> Input HMAC: 45E1BEBC78326470 -====> Computed HMAC: 45E1BEBC78326470 ---- ADD TO HASH FULL: -53D3C0B27291BFFBF09D6EF5BD4F6051ED911914F55BEF0E3315B258BB13108900000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A914CB078087EFF485AAA2260E94A53D7D6D1C5DD15188ACFDFFFFFF -Process input script, remaining 25 ---- ADD TO HASH FULL: -76A914CB078087EFF485AAA2260E94A53D7D6D1C5DD15188 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -AC -SEGWIT Add value -909F070000000000 ---- ADD TO HASH FULL: -909F070000000000 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -SEGWIT hashedOutputs -B3B2A31981BCC4F256B0851EBE9D7A11BFBFA8559E7795190B4472D7E1E974C9 -Sign ready -New APDU received: -E04800001B05800000318000000180000000000000010000000000001D03D001 ---- ADD TO HASH FULL: -D0031D0001000000 -Using private component -E8AE81F93160D032A7AA82BE9B719499A5DE635639D7237B7AB2572DE86F7E52 -Hash1 -01BB2AB227D2D0978E01A7212F1C7C5BC6FA848A8D46446A8242B3B00A7EF9BC -Hash2 -86B03281CD802D9764FFAB2E1F0E4B6825FA001899924C1DB1674C3A1D51054A -New APDU received: -E0440080050200000001 -Init transaction parser -Resume SegWit hash -SEGWIT Version -02000000 -SEGWIT HashedPrevouts -4E7FBD6CBE534923DBDC2E194612F7040271013133C736C5AE3DFC0CF1034370 -SEGWIT HashedSequence -957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A098 ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -4E7FBD6CBE534923DBDC2E194612F7040271013133C736C5AE3DFC0CF1034370 ---- ADD TO HASH FULL: -957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A098 ---- ADD TO HASH AUTH: -4E7FBD6CBE534923DBDC2E194612F7040271013133C736C5AE3DFC0CF1034370957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A098B3B2A31981BCC4F256B0851EBE9D7A11BFBFA8559E7795190B4472D7E1E974C9 -Number of inputs : 1 -Process input -New APDU received: -E04480003B01383200F2B153D3C0B27291BFFBF09D6EF5BD4F6051ED911914F55BEF0E3315B258BB1310890100000020A10700000000005B710DFE9F3F308D19 -Process input -Trusted input used in segwit mode -====> Input HMAC: 5B710DFE9F3F308D -====> Computed HMAC: 5B710DFE9F3F308D ---- ADD TO HASH FULL: -53D3C0B27291BFFBF09D6EF5BD4F6051ED911914F55BEF0E3315B258BB13108901000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A9143F8F2B556915A9306FD92EB5AE72217BE9DD593F88ACFDFFFFFF -Process input script, remaining 25 ---- ADD TO HASH FULL: -76A9143F8F2B556915A9306FD92EB5AE72217BE9DD593F88 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -AC -SEGWIT Add value -20A1070000000000 ---- ADD TO HASH FULL: -20A1070000000000 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -SEGWIT hashedOutputs -B3B2A31981BCC4F256B0851EBE9D7A11BFBFA8559E7795190B4472D7E1E974C9 -Sign ready -New APDU received: -E04800001B05800000318000000180000000000000000000000200001D03D001 ---- ADD TO HASH FULL: -D0031D0001000000 -Using private component -026553901CCECDDF76396E3B3BB2ACC48E68667FB793AAA239AC233AC99CE546 -Hash1 -FAA127DA08393CA5858E158219974145DB64C9C1F70ECB3E8582D6F562A56351 -Hash2 -D1D43A5549457E532745227067826A917150B060F55264615D077F2BA2AF530D diff --git a/tests/data/many-to-many/p2sh-p2wpkh/tx.json b/tests/data/many-to-many/p2sh-p2wpkh/tx.json deleted file mode 100644 index f62e5696..00000000 --- a/tests/data/many-to-many/p2sh-p2wpkh/tx.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "txid": "f5ff97147f8c7cca717536325eb157c696ef9630934271905b3f8c564b18e708", - "raw": "0200000000010253d3c0b27291bffbf09d6ef5bd4f6051ed911914f55bef0e3315b258bb1310890000000017160014cb078087eff485aaa2260e94a53d7d6d1c5dd151fdffffff53d3c0b27291bffbf09d6ef5bd4f6051ed911914f55bef0e3315b258bb13108901000000171600143f8f2b556915a9306fd92eb5ae72217be9dd593ffdffffff02840a03000000000017a914ffc91a30e33fc6d6ecff42e4d9bd6c7e115d84988700350c000000000017a9142f5864a8acd23fa85977d73e9ac30fd6b341b78c8702483045022100a0173bbd3dcdfe51c24386fee905b8197f36c2024f582b1a838e7bf09a1ec16902206bcd803041b13738f7d8896561e6a8ccec9a3f5d243be8645c403e83beb19b340121024ba3b77d933de9fa3f9583348c40f3caaf2effad5b6e244ece8abbfcc7244f6702483045022100ac5701f0cc3cb4b490269674d3463c4fab74f6ee9faf7c29b3d0dea22875dd0002206ba4f4195dce69ffd3e7d832ee5d67ee0d037bad03f4e00f841fbf84649375b5012103a1989dadf0bce57f4c96cfc4d9e6aa9abeba7ac0733e99176f69432e852666f1d0031d00", - "amount": 800000, - "fees": 300, - "to": "2MwZZdy3bCvEhiPsBycreCFiqwDhykAcWN9", - "sign_paths": ["m/49'/1'/0'/1/0", "m/49'/1'/0'/0/2"], - "change_path": "m/49'/1'/0'/1/1", - "lock_time": 1901520, - "utxos": [ - { - "txid": "891013bb58b215330eef5bf5141991ed51604fbdf56e9df0fbbf9172b2c0d353", - "raw": "02000000000101c3945b596fd88fd0d3031a2df8963a68adf9e9f0dfef4f3c4dd72df7d80777ae000000001716001485d33a279d6ae91e59e0c43de832fd4c3398252dfdffffff02909f07000000000017a914f0464d9fa0ea42d80e4d5f1457883982e23b8eec8720a107000000000017a91423e6f63c476f49e8acf6aa583a0fdec7b8aca6458702483045022100da88128e41ae9ea8d6c7fe54a32ab89bbd558993924acf7d86e7039675dd3e0002207228d510d4d8e16f77ef5b82af051a6e5bd5f0263e4464984db8be777dfc6387012102549c187d80a2c8d26760d1646b40e3dce3b9e6042579dcdb9fdeee85208ceb7c00041d00", - "output_indexes": [0, 1], - "output_amounts": [499600, 500000] - } - ] - -} diff --git a/tests/data/many-to-many/p2wpkh/apdu_debug.log b/tests/data/many-to-many/p2wpkh/apdu_debug.log deleted file mode 100644 index be6dcab4..00000000 --- a/tests/data/many-to-many/p2wpkh/apdu_debug.log +++ /dev/null @@ -1,415 +0,0 @@ -New APDU received: -E0C4000000 -New APDU received: -F026000000 -New APDU received: -E0C4000000 -New APDU received: -E024000000 -New APDU received: -E02280000130 -New APDU received: -E04000000100 -pin ok -Using private component -34AC5D784EBB4DF4727BCDDF6A6743F5D5D46D83DD74AA825866390C694F2938 -To hash -0251EC84E33A3119486461A44240E906FF94BF40CF807B025B1CA43332B80DC9DB -Hash160 -F5ACC2FD5C60B7263C4A459541C1473BC29E58F4 -Checksum -A21FB2F3 -Length to encode 25 -To encode -6FF5ACC2FD5C60B7263C4A459541C1473BC29E58F4A21FB2F3 -Length encoded 34 -Encoded -6E3375786F6B3843337A566277476A72584476344E544E516A313865335A4D4A426B -Length 34 -New APDU received: -E0400000050180000000 -pin ok -Using private component -C71AE2E616FBCCC325A71600E9C82816505A6373EFCE4CAEDA60400667E0B75C -To hash -02E5646066C2C51CEAEA66F04EC85858D34E2BD285F4A60B1402BFC03CF462E767 -Hash160 -7D825341D36FC1297A41A9839A72975815B1FE61 -Checksum -E01B4FD2 -Length to encode 25 -To encode -6F7D825341D36FC1297A41A9839A72975815B1FE61E01B4FD2 -Length encoded 34 -Encoded -6D727861744272776D555959504E774E4879334A5461567350474750716A4A68674D -Length 34 -New APDU received: -E040000009028000005480000001 -pin ok -Using private component -ADF229CD64E7ADC0915EA16BA3CD4A6923E65D2B6EA127D23DFE84E2D563D22A -To hash -0331B89176766FA4A6CA844A3A6B0DD301B55197DE3250EF47A9936019CF80CE31 -Hash160 -751B87653B01FC4A355D3E08D22995E02BEA88E4 -Checksum -57CDF1D9 -Length to encode 25 -To encode -6F751B87653B01FC4A355D3E08D22995E02BEA88E457CDF1D9 -Length encoded 34 -Encoded -6D7243414C456F71715961654368444C335233323975387578483651486145597243 -Length 34 -New APDU received: -E04000000D03800000548000000180000000 -pin ok -Using private component -08B5ED5B131552DA3B9CA9869E506420EDF4ABEC8C1BA5D468BE04CCC4EC4A48 -To hash -02668C624FDBF81D0E9D3601D5DA195E0D06E48E3F5021D9269774BD0A9E5F2CBE -Hash160 -DAAEB63EBF9E49ED7F25C491432B01D945E37A7C -Checksum -9B84A352 -Length to encode 25 -To encode -6FDAAEB63EBF9E49ED7F25C491432B01D945E37A7C9B84A352 -Length encoded 34 -Encoded -6E3154457534763756734C59696D575A5775333947553871736E7039694456676F6A -Length 34 -New APDU received: -E0C4000000 -New APDU received: -E042000009000000000200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -01 -Number of inputs : 1 -Process input -New APDU received: -E0428000252C4CA2F29958ECF3E14DDBD449E7DFC716400D7BFEE8A9D7EEC1647C3A14A7100000000000 -Process input ---- ADD TO HASH FULL: -2C4CA2F29958ECF3E14DDBD449E7DFC716400D7BFEE8A9D7EEC1647C3A14A71000000000 ---- ADD TO HASH FULL: -00 -Script to read 0 -Process input script, remaining 0 -New APDU received: -E042800004FDFFFFFF -Process input script, remaining 0 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -New APDU received: -E04280000102 -Input hashing done ---- ADD TO HASH FULL: -02 -Number of outputs : 2 -New APDU received: -E042800009D02CF8000000000016 ---- ADD TO HASH FULL: -D02CF80000000000 ---- ADD TO HASH FULL: -16 -Script to read 22 -Process output script, remaining 22 -New APDU received: -E04280001600142318D66F84FEF5C4875F933B038DC63831F8DA13 -Process output script, remaining 22 ---- ADD TO HASH FULL: -00142318D66F84FEF5C4875F933B038DC63831F8DA13 -Process output script, remaining 0 -New APDU received: -E042800009008793030000000016 -Process output script, remaining 0 ---- ADD TO HASH FULL: -0087930300000000 ---- ADD TO HASH FULL: -16 -Script to read 22 -Process output script, remaining 22 -New APDU received: -E0428000160014EEE49309A5CE45D01F691AEC8E5CE206194F9A9F -Process output script, remaining 22 ---- ADD TO HASH FULL: -0014EEE49309A5CE45D01F691AEC8E5CE206194F9A9F -Process output script, remaining 0 -New APDU received: -E042800004F1F61C00 -Process output script, remaining 0 -Output hashing done ---- ADD TO HASH FULL: -F1F61C00 -Transaction parsed -New APDU received: -E042000009000000010200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -01 -Number of inputs : 1 -Process input -New APDU received: -E0428000252C4CA2F29958ECF3E14DDBD449E7DFC716400D7BFEE8A9D7EEC1647C3A14A7100000000000 -Process input ---- ADD TO HASH FULL: -2C4CA2F29958ECF3E14DDBD449E7DFC716400D7BFEE8A9D7EEC1647C3A14A71000000000 ---- ADD TO HASH FULL: -00 -Script to read 0 -Process input script, remaining 0 -New APDU received: -E042800004FDFFFFFF -Process input script, remaining 0 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -New APDU received: -E04280000102 -Input hashing done ---- ADD TO HASH FULL: -02 -Number of outputs : 2 -New APDU received: -E042800009D02CF8000000000016 ---- ADD TO HASH FULL: -D02CF80000000000 ---- ADD TO HASH FULL: -16 -Script to read 22 -Process output script, remaining 22 -New APDU received: -E04280001600142318D66F84FEF5C4875F933B038DC63831F8DA13 -Process output script, remaining 22 ---- ADD TO HASH FULL: -00142318D66F84FEF5C4875F933B038DC63831F8DA13 -Process output script, remaining 0 -New APDU received: -E042800009008793030000000016 -Process output script, remaining 0 ---- ADD TO HASH FULL: -0087930300000000 ---- ADD TO HASH FULL: -16 -Script to read 22 -Process output script, remaining 22 -New APDU received: -E0428000160014EEE49309A5CE45D01F691AEC8E5CE206194F9A9F -Process output script, remaining 22 ---- ADD TO HASH FULL: -0014EEE49309A5CE45D01F691AEC8E5CE206194F9A9F -Process output script, remaining 0 -New APDU received: -E042800004F1F61C00 -Process output script, remaining 0 -Output hashing done ---- ADD TO HASH FULL: -F1F61C00 -Transaction parsed -New APDU received: -E02601000101 -New APDU received: -E0440002050200000002 -Init transaction parser -Number of inputs : 2 -Process input -New APDU received: -E04480003B0138320034B9AC4F7220317B689845CD25C42F608368B7B92A784169372D3C2CA2612EF1CD0D00000000D02CF800000000005B5ADD428D79EB3C19 -Process input -Trusted input used in segwit mode -====> Input HMAC: 5B5ADD428D79EB3C -====> Computed HMAC: 5B5ADD428D79EB3C -Adding amount -D02CF80000000000 -New amount -0000000000F82CD0 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A9142318D66F84FEF5C4875F933B038DC63831F8DA1388ACFDFFFFFF -Process input script, remaining 25 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -FDFFFFFF -Process input -New APDU received: -E04480003B013832006616AC4F7220317B689845CD25C42F608368B7B92A784169372D3C2CA2612EF1CD0D010000000087930300000000EAA238F5DA4E088C00 -Process input -Trusted input used in segwit mode -====> Input HMAC: EAA238F5DA4E088C -====> Computed HMAC: EAA238F5DA4E088C -Adding amount -0087930300000000 -New amount -00000000048BB3D0 -Script to read 0 -Process input script, remaining 0 -New APDU received: -E044800004FDFFFFFF -Process input script, remaining 0 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done ---- ADD TO HASH FULL: -82D397CBBCFF87BC5D0C4C70E424F9B830EFBAD7BF0BE479DA5D1D1BAFDB9798 -hashPrevout -B2790BC71EE0340E89998B4BEC430CFD8A6847CA49B6EA8185C1D6C368091185 -hashSequence -957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A098 -Presign ready -New APDU received: -E04AFF0015058000005480000001800000000000000100000005 -state=1 -Using private component -6938E6DBEDECC9FF7DF29A2C73BBB8250213D96F4B16B6E947AD5CA9F4160CC7 -New APDU received: -E04A00003202FE2BF80000000000160014C132F90DE4A19728E35D8AF8B3F9EC4E43CF194801879303000000001600143318E04FAE6C12 -state=1 ---- ADD TO HASH FULL: -FE2BF80000000000160014C132F90DE4A19728E35D8AF8B3F9EC4E43CF194801879303000000001600143318E04FAE6C12 -New APDU received: -E04A80000DAFCB009C69CD57E5B2504AE6B4 -state=2 ---- ADD TO HASH FULL: -AFCB009C69CD57E5B2504AE6B4 -hashOutputs -7AB7EB5CB887AE706482C5EF7A0218686D5EECDE5F8F6D6B3565433FB2EECFD6 -Auth Hash: -E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 -Segwit parsed once -New APDU received: -E0440080050200000001 -Init transaction parser -Resume SegWit hash -SEGWIT Version -02000000 -SEGWIT HashedPrevouts -B2790BC71EE0340E89998B4BEC430CFD8A6847CA49B6EA8185C1D6C368091185 -SEGWIT HashedSequence -957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A098 ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -B2790BC71EE0340E89998B4BEC430CFD8A6847CA49B6EA8185C1D6C368091185 ---- ADD TO HASH FULL: -957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A098 ---- ADD TO HASH AUTH: -B2790BC71EE0340E89998B4BEC430CFD8A6847CA49B6EA8185C1D6C368091185957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A0987AB7EB5CB887AE706482C5EF7A0218686D5EECDE5F8F6D6B3565433FB2EECFD6 -Number of inputs : 1 -Process input -New APDU received: -E04480003B0138320034B9AC4F7220317B689845CD25C42F608368B7B92A784169372D3C2CA2612EF1CD0D00000000D02CF800000000005B5ADD428D79EB3C19 -Process input -Trusted input used in segwit mode -====> Input HMAC: 5B5ADD428D79EB3C -====> Computed HMAC: 5B5ADD428D79EB3C ---- ADD TO HASH FULL: -AC4F7220317B689845CD25C42F608368B7B92A784169372D3C2CA2612EF1CD0D00000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A9142318D66F84FEF5C4875F933B038DC63831F8DA1388ACFDFFFFFF -Process input script, remaining 25 ---- ADD TO HASH FULL: -76A9142318D66F84FEF5C4875F933B038DC63831F8DA1388 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -AC -SEGWIT Add value -D02CF80000000000 ---- ADD TO HASH FULL: -D02CF80000000000 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -SEGWIT hashedOutputs -7AB7EB5CB887AE706482C5EF7A0218686D5EECDE5F8F6D6B3565433FB2EECFD6 -Sign ready -New APDU received: -E04800001B05800000548000000180000000000000000000000100001D024301 ---- ADD TO HASH FULL: -43021D0001000000 -Using private component -21E9C06E0D5E169EE7E6C961D2F3F3286666EF74F2CE5EFF6F6108EB6D855DA5 -Hash1 -7F95C240698CB2D4E372B1EFDFB565D9447D4F0706249907AA8D90BF0AD615C0 -Hash2 -45EB814B30BA5E2E6C39A7326290F7DC1548484507CC230B11F84D56FE26800F -New APDU received: -E0440080050200000001 -Init transaction parser -Resume SegWit hash -SEGWIT Version -02000000 -SEGWIT HashedPrevouts -B2790BC71EE0340E89998B4BEC430CFD8A6847CA49B6EA8185C1D6C368091185 -SEGWIT HashedSequence -957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A098 ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -B2790BC71EE0340E89998B4BEC430CFD8A6847CA49B6EA8185C1D6C368091185 ---- ADD TO HASH FULL: -957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A098 ---- ADD TO HASH AUTH: -B2790BC71EE0340E89998B4BEC430CFD8A6847CA49B6EA8185C1D6C368091185957879FDCE4D8AB885E32FF307D54E75884DA52522CC53D3C4FDB60EDB69A0987AB7EB5CB887AE706482C5EF7A0218686D5EECDE5F8F6D6B3565433FB2EECFD6 -Number of inputs : 1 -Process input -New APDU received: -E04480003B013832006616AC4F7220317B689845CD25C42F608368B7B92A784169372D3C2CA2612EF1CD0D010000000087930300000000EAA238F5DA4E088C19 -Process input -Trusted input used in segwit mode -====> Input HMAC: EAA238F5DA4E088C -====> Computed HMAC: EAA238F5DA4E088C ---- ADD TO HASH FULL: -AC4F7220317B689845CD25C42F608368B7B92A784169372D3C2CA2612EF1CD0D01000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A914EEE49309A5CE45D01F691AEC8E5CE206194F9A9F88ACFDFFFFFF -Process input script, remaining 25 ---- ADD TO HASH FULL: -76A914EEE49309A5CE45D01F691AEC8E5CE206194F9A9F88 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -AC -SEGWIT Add value -0087930300000000 ---- ADD TO HASH FULL: -0087930300000000 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -SEGWIT hashedOutputs -7AB7EB5CB887AE706482C5EF7A0218686D5EECDE5F8F6D6B3565433FB2EECFD6 -Sign ready -New APDU received: -E04800001B05800000548000000180000000000000010000000400001D024301 ---- ADD TO HASH FULL: -43021D0001000000 -Using private component -EF8D5CCDB132BA01BAD92AA97B1DF75C7C6914809F2510E91AA1FCE703770625 -Hash1 -7A9AA279B55E743EEFE4B819CB5B6E197B32D2C19DF8A3B6DDF1E0520C3A2180 -Hash2 -94D3EBE11569A69F1A2B948C4275940854CD8ED914377B8ADEE0F2257C6AD925 diff --git a/tests/data/many-to-many/p2wpkh/tx.json b/tests/data/many-to-many/p2wpkh/tx.json deleted file mode 100644 index 1b3bdf2b..00000000 --- a/tests/data/many-to-many/p2wpkh/tx.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "txid": "5c09c82a4efa271adb692917aa35e92b1b360e333fade6cf081952bc7fd16a7a", - "raw": "02000000000102ac4f7220317b689845cd25c42f608368b7b92a784169372d3c2ca2612ef1cd0d0000000000fdffffffac4f7220317b689845cd25c42f608368b7b92a784169372d3c2ca2612ef1cd0d0100000000fdffffff02fe2bf80000000000160014c132f90de4a19728e35d8af8b3f9ec4e43cf194801879303000000001600143318e04fae6c12afcb009c69cd57e5b2504ae6b40247304402203aed260c81d21e36cfdd5a095ad289366103ae3a2690011b20e15001173e44d902206f17e60fc169db8bc21820dfefe51271446a6305284bcfb73738ca38a2715d9f012103455ee7cedc97b0ba435b80066fc92c963a34c600317981d135330c4ee43ac7a3024730440220223a3f37f85ed5e42d6ed463ca36932db28799ff12d0391b5e02bcfef829007302206c42e9cb5817bff184e8854848032867f129814df07a96afc49baa5542ede8a4012103affafaf410b74f019028055618695f89c23478aa5fca3ba531f44d382ad7791a43021d00", - "amount": 60000001, - "fees": 209, - "to": "tb1qxvvwqnawdsf2ljcqn35u64l9kfgy4e45v3uamu", - "sign_paths": ["m/84'/1'/0'/0/1", "m/84'/1'/0'/1/4"], - "change_path": "m/84'/1'/0'/1/5", - "lock_time": 1901123, - "utxos": [ - { - "txid": "0dcdf12e61a22c3c2d376941782ab9b76883602fc425cd4598687b3120724fac", - "raw": "020000000001012c4ca2f29958ecf3e14ddbd449e7dfc716400d7bfee8a9d7eec1647c3a14a7100000000000fdffffff02d02cf800000000001600142318d66f84fef5c4875f933b038dc63831f8da130087930300000000160014eee49309a5ce45d01f691aec8e5ce206194f9a9f02483045022100badae1c06849c8ba6616af3f306e5a2fccd433f23c1fa621e0dc7114f3c84a4002205ca637953d0b6fc2431f3cf6368fa00dbcb328d46c4778d8173cdb51b22a60760121027cb75d34b005c4eb9f62bbf2c457d7638e813e757efcec8fa68677d950b63662f1f61c00", - "output_indexes": [0, 1], - "output_amounts": [16264400, 60000000] - } - ] - -} \ No newline at end of file diff --git a/tests/data/one-to-many/p2pkh/apdu_debug.log b/tests/data/one-to-many/p2pkh/apdu_debug.log deleted file mode 100644 index 74689b25..00000000 --- a/tests/data/one-to-many/p2pkh/apdu_debug.log +++ /dev/null @@ -1,168 +0,0 @@ -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E042000009000000010200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -01 -Number of inputs : 1 -Process input -New APDU received: -E042800025F4C2B478DC9CEA2DF43C8BB94938FF43F3BED5AEB3AF9E36CDB7016104626BF2000000006B -Process input ---- ADD TO HASH FULL: -F4C2B478DC9CEA2DF43C8BB94938FF43F3BED5AEB3AF9E36CDB7016104626BF200000000 ---- ADD TO HASH FULL: -6B -Script to read 107 -Process input script, remaining 107 -New APDU received: -E04280006F483045022100B7B8244B3F83648397FA3C37349ED1827BF40BFCA22D4F87CC019D3FDED63E1D02205434CE222DE35E04AB98BE54AF57D2C8B464F0DA76A0275443B33C7B1DF79344012103462F1E48396CE2A4D7694D107FEF5123FE4D1E394394A370FA4901E744B4884EFDFFFFFF -Process input script, remaining 107 ---- ADD TO HASH FULL: -483045022100B7B8244B3F83648397FA3C37349ED1827BF40BFCA22D4F87CC019D3FDED63E1D02205434CE222DE35E04AB98BE54AF57D2C8B464F0DA76A0275443B33C7B1DF79344012103462F1E48396CE2A4D7694D107FEF5123FE4D1E394394A370FA4901E744B488 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -4E ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -New APDU received: -E04280000102 -Input hashing done ---- ADD TO HASH FULL: -02 -Number of outputs : 2 -New APDU received: -E042800009DCDB06000000000019 ---- ADD TO HASH FULL: -DCDB060000000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process output script, remaining 25 -New APDU received: -E04280001976A914B242BA04B8526B533B17B168D27EAF0DA7BACB8588AC -Process output script, remaining 25 ---- ADD TO HASH FULL: -76A914B242BA04B8526B533B17B168D27EAF0DA7BACB8588AC -Process output script, remaining 0 -New APDU received: -E042800009706408000000000019 -Process output script, remaining 0 ---- ADD TO HASH FULL: -7064080000000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process output script, remaining 25 -New APDU received: -E04280001976A91426C680EC6AC9C0ED760177F92096F1C5571B72EF88AC -Process output script, remaining 25 ---- ADD TO HASH FULL: -76A91426C680EC6AC9C0ED760177F92096F1C5571B72EF88AC -Process output script, remaining 0 -New APDU received: -E04280000420041D00 -Process output script, remaining 0 -Output hashing done ---- ADD TO HASH FULL: -20041D00 -Transaction parsed -New APDU received: -E02601000101 -New APDU received: -E0440000050200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH AUTH: -02000000 ---- ADD TO HASH FULL: -01 ---- ADD TO HASH AUTH: -01 -Number of inputs : 1 -Process input -New APDU received: -E04480003B0138320002AC5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3401000000706408000000000095CF3BF2ACF74FF919 -Process input -====> Input HMAC: 95CF3BF2ACF74FF9 -====> Computed HMAC: 95CF3BF2ACF74FF9 -Trusted input hash -5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3401000000 ---- ADD TO HASH FULL: -5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3401000000 ---- ADD TO HASH AUTH: -5DF7B9E20C52D1DA2701A244A49754215266F016F6BD77F640A5200CD1FB7E3401000000 -Adding amount -7064080000000000 -New amount -0000000000086470 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A91426C680EC6AC9C0ED760177F92096F1C5571B72EF88ACFDFFFFFF -Process input script, remaining 25 ---- ADD TO HASH FULL: -76A91426C680EC6AC9C0ED760177F92096F1C5571B72EF88 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -AC ---- ADD TO HASH FULL: -FDFFFFFF ---- ADD TO HASH AUTH: -FDFFFFFF -Process input -Input hashing done -Presign ready -New APDU received: -E04AFF0015058000002C80000001800000000000000100000001 -state=1 -Using private component -885E2F32C80E1D56DABC55AC271CC3983BF122F771AB45A1C890E0DEB740FAAB -New APDU received: -E04A00003202140C0300000000001976A914B3E17C4DEF8A39148ED6FAD7DC6FEBE30DD324CB88AC30570500000000001976A914E0A893 -state=1 ---- ADD TO HASH FULL: -02140C0300000000001976A914B3E17C4DEF8A39148ED6FAD7DC6FEBE30DD324CB88AC30570500000000001976A914E0A893 ---- ADD TO HASH AUTH: -02140C0300000000001976A914B3E17C4DEF8A39148ED6FAD7DC6FEBE30DD324CB88AC30570500000000001976A914E0A893 -New APDU received: -E04A80001380635F18B7EE09546D963232BCB992412B88AC -state=2 ---- ADD TO HASH FULL: -80635F18B7EE09546D963232BCB992412B88AC ---- ADD TO HASH AUTH: -80635F18B7EE09546D963232BCB992412B88AC -Checksum -62CF1861 -Length to encode 25 -To encode -6FE0A89380635F18B7EE09546D963232BCB992412B62CF1861 -Length encoded 34 -Encoded -6E317A71627548485461746D727359476A5042597953656F4637637250696A326A53 -New APDU received: -E04800001B058000002C8000000180000000000000000000000200001D04FE01 ---- ADD TO HASH FULL: -FE041D0001000000 -Using private component -E116F09653EDEBCCC7AC55622ECFA8DE2EE60C51A5006B6B6153B184B4DA914D -Hash1 -7E0EEB79AFE7BB94A68EB1CB0BCB591C380ADAB2120DB528F2D83EBB0BB9029B -Hash2 -971753A7B93CAB3510D9DAD6D08FB1805E580D8CBE292BF89A68C6CBE3BC8A72 diff --git a/tests/data/one-to-many/p2pkh/tx.json b/tests/data/one-to-many/p2pkh/tx.json deleted file mode 100644 index b68a6564..00000000 --- a/tests/data/one-to-many/p2pkh/tx.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "txid": "de390b0c4ac67b6cdcbe84611463cc42b6774f2bf11d8f7144e9601e3591f857", - "raw": "02000000015df7b9e20c52d1da2701a244a49754215266f016f6bd77f640a5200cd1fb7e34010000006b483045022100c806957429935c5d61f548223c3536dc739fe351814bce9edc1694e5a5c25abf022013e307b0b4885acb64ccffaf5f4794f205040325ebc36c258787c488b038c2bb0121038ba462d7dd65917ece454142903bb362a0b412d1841d52087ad881646b6cdccffdffffff02140c0300000000001976a914b3e17c4def8a39148ed6fad7dc6febe30dd324cb88ac30570500000000001976a914e0a89380635f18b7ee09546d963232bcb992412b88acfe041d00", - "amount": 350000, - "fees": 300, - "to": "n1zqbuHHTatmrsYGjPBYySeoF7crPij2jS", - "sign_paths": ["m/84'/1'/0'/0/2"], - "change_path": "m/84'/1'/0'/1/1", - "lock_time": 1901822, - "utxos": [ - { - "txid": "347efbd10c20a540f677bdf616f06652215497a444a20127dad1520ce2b9f75d", - "raw": "0200000001f4c2b478dc9cea2df43c8bb94938ff43f3bed5aeb3af9e36cdb7016104626bf2000000006b483045022100b7b8244b3f83648397fa3c37349ed1827bf40bfca22d4f87cc019d3fded63e1d02205434ce222de35e04ab98be54af57d2c8b464f0da76a0275443b33c7b1df79344012103462f1e48396ce2a4d7694d107fef5123fe4d1e394394a370fa4901e744b4884efdffffff02dcdb0600000000001976a914b242ba04b8526b533b17b168d27eaf0da7bacb8588ac70640800000000001976a91426c680ec6ac9c0ed760177f92096f1c5571b72ef88ac20041d00", - "output_indexes": [1], - "output_amounts": [550000] - } - ] - -} diff --git a/tests/data/one-to-many/p2sh-p2wpkh/apdu_debug.log b/tests/data/one-to-many/p2sh-p2wpkh/apdu_debug.log deleted file mode 100644 index 2116c1fa..00000000 --- a/tests/data/one-to-many/p2sh-p2wpkh/apdu_debug.log +++ /dev/null @@ -1,191 +0,0 @@ -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E042000009000000000200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -01 -Number of inputs : 1 -Process input -New APDU received: -E042800025167FA3F3D4233D1660B4B3BB62E78FB35C9786B0A96E6B4D61697CA112D9BA4E0100000017 -Process input ---- ADD TO HASH FULL: -167FA3F3D4233D1660B4B3BB62E78FB35C9786B0A96E6B4D61697CA112D9BA4E01000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process input script, remaining 23 -New APDU received: -E04280001B160014E310D044F88DAB1B42769E4A84CAF08363F9ECC1FDFFFFFF -Process input script, remaining 23 ---- ADD TO HASH FULL: -160014E310D044F88DAB1B42769E4A84CAF08363F9EC -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -C1 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -New APDU received: -E04280000101 -Input hashing done ---- ADD TO HASH FULL: -01 -Number of outputs : 1 -New APDU received: -E042800009AA410F000000000017 ---- ADD TO HASH FULL: -AA410F0000000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process output script, remaining 23 -New APDU received: -E042800017A9144D7997B902D0F1A2441A0542C920413B957E8A2287 -Process output script, remaining 23 ---- ADD TO HASH FULL: -A9144D7997B902D0F1A2441A0542C920413B957E8A2287 -Process output script, remaining 0 -New APDU received: -E042800004FD031D00 -Process output script, remaining 0 -Output hashing done ---- ADD TO HASH FULL: -FD031D00 -Transaction parsed -New APDU received: -E02601000101 -New APDU received: -E0440002050200000001 -Init transaction parser -Number of inputs : 1 -Process input -New APDU received: -E04480003B013832006773C3945B596FD88FD0D3031A2DF8963A68ADF9E9F0DFEF4F3C4DD72DF7D80777AE00000000AA410F0000000000F438E5A7C4F7887819 -Process input -Trusted input used in segwit mode -====> Input HMAC: F438E5A7C4F78878 -====> Computed HMAC: F438E5A7C4F78878 -Adding amount -AA410F0000000000 -New amount -00000000000F41AA -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A91485D33A279D6AE91E59E0C43DE832FD4C3398252D88ACFDFFFFFF -Process input script, remaining 25 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done ---- ADD TO HASH FULL: -23E9829BFB4E23FBD3C4848BAA035AF15D73BCB83E510F7F097F90A21A4280D2 -hashPrevout -82C5F725DB8A39C6B9C7B3C0DAF5C67E85DDA91C1F0FE866598ECF64CAF01419 -hashSequence -CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52 -Presign ready -New APDU received: -E04AFF0015058000003180000001800000000000000100000000 -state=1 -Using private component -E8AE81F93160D032A7AA82BE9B719499A5DE635639D7237B7AB2572DE86F7E52 -New APDU received: -E04A00003202909F07000000000017A914F0464D9FA0EA42D80E4D5F1457883982E23B8EEC8720A107000000000017A91423E6F63C476F -state=1 ---- ADD TO HASH FULL: -909F07000000000017A914F0464D9FA0EA42D80E4D5F1457883982E23B8EEC8720A107000000000017A91423E6F63C476F -New APDU received: -E04A80000F49E8ACF6AA583A0FDEC7B8ACA64587 -state=2 ---- ADD TO HASH FULL: -49E8ACF6AA583A0FDEC7B8ACA64587 -hashOutputs -BBC96114CDDD96D506521DFD897A0F946AE5E59CFA4373A8A1AD62B8A5D38E14 -Auth Hash: -E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 -Checksum -BF56514F -Length to encode 25 -To encode -C423E6F63C476F49E8ACF6AA583A0FDEC7B8ACA645BF56514F -Length encoded 35 -Encoded -324D7658344B5756424B344E717A4A766A67517952556841615538503775536B625141 -Segwit parsed once -New APDU received: -E0440080050200000001 -Init transaction parser -Resume SegWit hash -SEGWIT Version -02000000 -SEGWIT HashedPrevouts -82C5F725DB8A39C6B9C7B3C0DAF5C67E85DDA91C1F0FE866598ECF64CAF01419 -SEGWIT HashedSequence -CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52 ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -82C5F725DB8A39C6B9C7B3C0DAF5C67E85DDA91C1F0FE866598ECF64CAF01419 ---- ADD TO HASH FULL: -CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52 ---- ADD TO HASH AUTH: -82C5F725DB8A39C6B9C7B3C0DAF5C67E85DDA91C1F0FE866598ECF64CAF01419CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52BBC96114CDDD96D506521DFD897A0F946AE5E59CFA4373A8A1AD62B8A5D38E14 -Number of inputs : 1 -Process input -New APDU received: -E04480003B013832006773C3945B596FD88FD0D3031A2DF8963A68ADF9E9F0DFEF4F3C4DD72DF7D80777AE00000000AA410F0000000000F438E5A7C4F7887819 -Process input -Trusted input used in segwit mode -====> Input HMAC: F438E5A7C4F78878 -====> Computed HMAC: F438E5A7C4F78878 ---- ADD TO HASH FULL: -C3945B596FD88FD0D3031A2DF8963A68ADF9E9F0DFEF4F3C4DD72DF7D80777AE00000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A91485D33A279D6AE91E59E0C43DE832FD4C3398252D88ACFDFFFFFF -Process input script, remaining 25 ---- ADD TO HASH FULL: -76A91485D33A279D6AE91E59E0C43DE832FD4C3398252D88 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -AC -SEGWIT Add value -AA410F0000000000 ---- ADD TO HASH FULL: -AA410F0000000000 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -SEGWIT hashedOutputs -BBC96114CDDD96D506521DFD897A0F946AE5E59CFA4373A8A1AD62B8A5D38E14 -Sign ready -New APDU received: -E04800001B05800000318000000180000000000000000000000100001D040001 ---- ADD TO HASH FULL: -00041D0001000000 -Using private component -54D5FA61DC01FB1B00C7B2FD7DE49273A859AB47A572BD02E68DFB1F126867ED -Hash1 -AD7ADE5C5390D208BC4992C615545E0C1E379832D9801396C4AD20E8D670381B -Hash2 -97BC0CA93B0530F5EBC5AA69EB214948BF1A28D9637D7B0030F53FA5C951F4A5 diff --git a/tests/data/one-to-many/p2sh-p2wpkh/tx.json b/tests/data/one-to-many/p2sh-p2wpkh/tx.json deleted file mode 100644 index 23898ead..00000000 --- a/tests/data/one-to-many/p2sh-p2wpkh/tx.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "txid": "891013bb58b215330eef5bf5141991ed51604fbdf56e9df0fbbf9172b2c0d353", - "raw": "02000000000101c3945b596fd88fd0d3031a2df8963a68adf9e9f0dfef4f3c4dd72df7d80777ae000000001716001485d33a279d6ae91e59e0c43de832fd4c3398252dfdffffff02909f07000000000017a914f0464d9fa0ea42d80e4d5f1457883982e23b8eec8720a107000000000017a91423e6f63c476f49e8acf6aa583a0fdec7b8aca6458702483045022100da88128e41ae9ea8d6c7fe54a32ab89bbd558993924acf7d86e7039675dd3e0002207228d510d4d8e16f77ef5b82af051a6e5bd5f0263e4464984db8be777dfc6387012102549c187d80a2c8d26760d1646b40e3dce3b9e6042579dcdb9fdeee85208ceb7c00041d00", - "amount": 500000, - "fees": 250, - "to": "2MvX4KWVBK4NqzJvjgQyRUhAaU8P7uSkbQA", - "sign_paths": ["m/49'/1'/0'/0/1"], - "change_path": "m/49'/1'/0'/1/0", - "lock_time": 1901568, - "utxos": [ - { - "txid": "ae7707d8f72dd74d3c4fefdff0e9f9ad683a96f82d1a03d3d08fd86f595b94c3", - "raw": "02000000000101167fa3f3d4233d1660b4b3bb62e78fb35c9786b0a96e6b4d61697ca112d9ba4e0100000017160014e310d044f88dab1b42769e4a84caf08363f9ecc1fdffffff01aa410f000000000017a9144d7997b902d0f1a2441a0542c920413b957e8a228702483045022100b8ab2d40241c406b7e232e98fc99188ed46c062cc3f49ea39cfb77ae9f4918760220078763f7e0078be84ceb939bea8a87934e64ae3502d8636eb249c7ddd97036f7012102a80f007194d53d37f6f99539f635390588c4e1c328b098295f61af40d60cb28afd031d00", - "output_indexes": [0], - "output_amounts": [999850] - } - ] - -} diff --git a/tests/data/one-to-many/p2wpkh/apdu_debug.log b/tests/data/one-to-many/p2wpkh/apdu_debug.log deleted file mode 100644 index 86fa4185..00000000 --- a/tests/data/one-to-many/p2wpkh/apdu_debug.log +++ /dev/null @@ -1,207 +0,0 @@ -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E042000009000000010200000002 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -02 -Number of inputs : 2 -Process input -New APDU received: -E042800025AC4F7220317B689845CD25C42F608368B7B92A784169372D3C2CA2612EF1CD0D0000000000 -Process input ---- ADD TO HASH FULL: -AC4F7220317B689845CD25C42F608368B7B92A784169372D3C2CA2612EF1CD0D00000000 ---- ADD TO HASH FULL: -00 -Script to read 0 -Process input script, remaining 0 -New APDU received: -E042800004FDFFFFFF -Process input script, remaining 0 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -New APDU received: -E042800025AC4F7220317B689845CD25C42F608368B7B92A784169372D3C2CA2612EF1CD0D0100000000 -Process input ---- ADD TO HASH FULL: -AC4F7220317B689845CD25C42F608368B7B92A784169372D3C2CA2612EF1CD0D01000000 ---- ADD TO HASH FULL: -00 -Script to read 0 -Process input script, remaining 0 -New APDU received: -E042800004FDFFFFFF -Process input script, remaining 0 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -New APDU received: -E04280000102 -Input hashing done ---- ADD TO HASH FULL: -02 -Number of outputs : 2 -New APDU received: -E042800009FE2BF8000000000016 ---- ADD TO HASH FULL: -FE2BF80000000000 ---- ADD TO HASH FULL: -16 -Script to read 22 -Process output script, remaining 22 -New APDU received: -E0428000160014C132F90DE4A19728E35D8AF8B3F9EC4E43CF1948 -Process output script, remaining 22 ---- ADD TO HASH FULL: -0014C132F90DE4A19728E35D8AF8B3F9EC4E43CF1948 -Process output script, remaining 0 -New APDU received: -E042800009018793030000000016 -Process output script, remaining 0 ---- ADD TO HASH FULL: -0187930300000000 ---- ADD TO HASH FULL: -16 -Script to read 22 -Process output script, remaining 22 -New APDU received: -E04280001600143318E04FAE6C12AFCB009C69CD57E5B2504AE6B4 -Process output script, remaining 22 ---- ADD TO HASH FULL: -00143318E04FAE6C12AFCB009C69CD57E5B2504AE6B4 -Process output script, remaining 0 -New APDU received: -E04280000443021D00 -Process output script, remaining 0 -Output hashing done ---- ADD TO HASH FULL: -43021D00 -Transaction parsed -New APDU received: -E02601000101 -New APDU received: -E0440002050200000001 -Init transaction parser -Number of inputs : 1 -Process input -New APDU received: -E04480003B0138320001107A6AD17FBC521908CFE6AD3F330E361B2BE935AA172969DB1A27FA4E2AC8095C01000000018793030000000019D862B903E5346019 -Process input -Trusted input used in segwit mode -====> Input HMAC: 19D862B903E53460 -====> Computed HMAC: 19D862B903E53460 -Adding amount -0187930300000000 -New amount -0000000003938701 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A9143318E04FAE6C12AFCB009C69CD57E5B2504AE6B488ACFDFFFFFF -Process input script, remaining 25 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done ---- ADD TO HASH FULL: -23E9829BFB4E23FBD3C4848BAA035AF15D73BCB83E510F7F097F90A21A4280D2 -hashPrevout -0AD0C2779F8B2F0C994FD54CA86701607C7D162C622D8BCAA2DF8A195DE98C63 -hashSequence -CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52 -Presign ready -New APDU received: -E04AFF0015058000005480000001800000000000000100000006 -state=1 -Using private component -422277B0087551BAF831C6F099FADBD0E36048ABD1497E05DC9ECD0BFCF13243 -New APDU received: -E04A00003202B895980000000000160014AE4A9E12C72BAFA7C09DA2D0D924E0552FF68C2580F0FA02000000001600141347E82A037B5D -state=1 ---- ADD TO HASH FULL: -B895980000000000160014AE4A9E12C72BAFA7C09DA2D0D924E0552FF68C2580F0FA02000000001600141347E82A037B5D -New APDU received: -E04A80000DBB38CF8C4759F242B1F5C7E09A -state=2 ---- ADD TO HASH FULL: -BB38CF8C4759F242B1F5C7E09A -hashOutputs -D00F205254FBFFF03E8A8D31FE82421C83271E803EE12B4B0E2BF307E3E8D965 -Auth Hash: -E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 -Segwit parsed once -New APDU received: -E0440080050200000001 -Init transaction parser -Resume SegWit hash -SEGWIT Version -02000000 -SEGWIT HashedPrevouts -0AD0C2779F8B2F0C994FD54CA86701607C7D162C622D8BCAA2DF8A195DE98C63 -SEGWIT HashedSequence -CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52 ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -0AD0C2779F8B2F0C994FD54CA86701607C7D162C622D8BCAA2DF8A195DE98C63 ---- ADD TO HASH FULL: -CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52 ---- ADD TO HASH AUTH: -0AD0C2779F8B2F0C994FD54CA86701607C7D162C622D8BCAA2DF8A195DE98C63CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52D00F205254FBFFF03E8A8D31FE82421C83271E803EE12B4B0E2BF307E3E8D965 -Number of inputs : 1 -Process input -New APDU received: -E04480003B0138320001107A6AD17FBC521908CFE6AD3F330E361B2BE935AA172969DB1A27FA4E2AC8095C01000000018793030000000019D862B903E5346019 -Process input -Trusted input used in segwit mode -====> Input HMAC: 19D862B903E53460 -====> Computed HMAC: 19D862B903E53460 ---- ADD TO HASH FULL: -7A6AD17FBC521908CFE6AD3F330E361B2BE935AA172969DB1A27FA4E2AC8095C01000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A9143318E04FAE6C12AFCB009C69CD57E5B2504AE6B488ACFDFFFFFF -Process input script, remaining 25 ---- ADD TO HASH FULL: -76A9143318E04FAE6C12AFCB009C69CD57E5B2504AE6B488 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -AC -SEGWIT Add value -0187930300000000 ---- ADD TO HASH FULL: -0187930300000000 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -SEGWIT hashedOutputs -D00F205254FBFFF03E8A8D31FE82421C83271E803EE12B4B0E2BF307E3E8D965 -Sign ready -New APDU received: -E04800001B05800000548000000180000000000000000000000300001D02A401 ---- ADD TO HASH FULL: -A4021D0001000000 -Using private component -BB2A3DBCB0FF5B3F483F58A916AC39D6B1D6D6F10CAF148FBB90BC8462214DB5 -Hash1 -D9463068D03E9557C2E47D7C8AC4B9C6651E535FD0F4B6FC955E9597832D07FE -Hash2 -D89635D546800B70DD465E2C89EE6764DD454091EA23D7F936408E8C2460D460 diff --git a/tests/data/one-to-many/p2wpkh/tx.json b/tests/data/one-to-many/p2wpkh/tx.json deleted file mode 100644 index 0c0b45f9..00000000 --- a/tests/data/one-to-many/p2wpkh/tx.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "txid": "2e06df6ac8282f8e93f49285a2dedb5d4d5821427cfd5cbcc8f98b24a925a09c", - "raw": "020000000001017a6ad17fbc521908cfe6ad3f330e361b2be935aa172969db1a27fa4e2ac8095c0100000000fdffffff02b895980000000000160014ae4a9e12c72bafa7c09da2d0d924e0552ff68c2580f0fa02000000001600141347e82a037b5dbb38cf8c4759f242b1f5c7e09a02483045022100f6e4c827b7c0ffc2cc781ea9b64ddacc9a6ac72ad50d08e84f5ae9ee26b6f88f02206441cd69a31563c6e80bd7fd21ba050d6720116330c461a4014ac6164d24e2a401210232804f473db3282d5baca4c53713463645729335b90d738e18e2286b603d3fc5a4021d00", - "amount": 50000000, - "fees": 201, - "to": "tb1qzdr7s2sr0dwmkwx033r4nujzk86u0cy6fmzfjk", - "sign_paths": ["m/84'/1'/0'/0/3"], - "change_path": "m/84'/1'/0'/1/6", - "lock_time": 1901220, - "utxos": [ - { - "txid": "5c09c82a4efa271adb692917aa35e92b1b360e333fade6cf081952bc7fd16a7a", - "raw": "02000000000102ac4f7220317b689845cd25c42f608368b7b92a784169372d3c2ca2612ef1cd0d0000000000fdffffffac4f7220317b689845cd25c42f608368b7b92a784169372d3c2ca2612ef1cd0d0100000000fdffffff02fe2bf80000000000160014c132f90de4a19728e35d8af8b3f9ec4e43cf194801879303000000001600143318e04fae6c12afcb009c69cd57e5b2504ae6b40247304402203aed260c81d21e36cfdd5a095ad289366103ae3a2690011b20e15001173e44d902206f17e60fc169db8bc21820dfefe51271446a6305284bcfb73738ca38a2715d9f012103455ee7cedc97b0ba435b80066fc92c963a34c600317981d135330c4ee43ac7a3024730440220223a3f37f85ed5e42d6ed463ca36932db28799ff12d0391b5e02bcfef829007302206c42e9cb5817bff184e8854848032867f129814df07a96afc49baa5542ede8a4012103affafaf410b74f019028055618695f89c23478aa5fca3ba531f44d382ad7791a43021d00", - "output_indexes": [1], - "output_amounts": [60000001] - } - ] - -} \ No newline at end of file diff --git a/tests/data/one-to-one/p2pkh/apdu_debug.log b/tests/data/one-to-one/p2pkh/apdu_debug.log deleted file mode 100644 index 36ff1307..00000000 --- a/tests/data/one-to-one/p2pkh/apdu_debug.log +++ /dev/null @@ -1,159 +0,0 @@ -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E042000009000000010200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -01 -Number of inputs : 1 -Process input -New APDU received: -E042800025EC230E53095256052A2428270EEC0498944B10F6F1C578F431C23D0098B4AE5A0100000017 -Process input ---- ADD TO HASH FULL: -EC230E53095256052A2428270EEC0498944B10F6F1C578F431C23D0098B4AE5A01000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process input script, remaining 23 -New APDU received: -E04280001B160014281539820E2DE973AE41BA6004B431C921C4D86DFEFFFFFF -Process input script, remaining 23 ---- ADD TO HASH FULL: -160014281539820E2DE973AE41BA6004B431C921C4D8 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -6D ---- ADD TO HASH FULL: -FEFFFFFF -Process input -Input hashing done -New APDU received: -E04280000102 -Input hashing done ---- ADD TO HASH FULL: -02 -Number of outputs : 2 -New APDU received: -E042800009727275000000000017 ---- ADD TO HASH FULL: -7272750000000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process output script, remaining 23 -New APDU received: -E042800017A914C8B906AF298C70E603A28C3EFC2FAE19E6AB280F87 -Process output script, remaining 23 ---- ADD TO HASH FULL: -A914C8B906AF298C70E603A28C3EFC2FAE19E6AB280F87 -Process output script, remaining 0 -New APDU received: -E04280000940420F000000000019 -Process output script, remaining 0 ---- ADD TO HASH FULL: -40420F0000000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process output script, remaining 25 -New APDU received: -E04280001976A914CBAE5B50CF939E6F531B8A6B7ABD788FE14B029788AC -Process output script, remaining 25 ---- ADD TO HASH FULL: -76A914CBAE5B50CF939E6F531B8A6B7ABD788FE14B029788AC -Process output script, remaining 0 -New APDU received: -E04280000484F21C00 -Process output script, remaining 0 -Output hashing done ---- ADD TO HASH FULL: -84F21C00 -Transaction parsed -New APDU received: -E02601000101 -New APDU received: -E0440000050200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH AUTH: -02000000 ---- ADD TO HASH FULL: -01 ---- ADD TO HASH AUTH: -01 -Number of inputs : 1 -Process input -New APDU received: -E04480003B013832007BB65122C2CDE6823E55754175B92C9C57A0A8E1AC83C38E1787FD3A1FF3348E95130100000040420F00000000009AC6444F05C5817019 -Process input -====> Input HMAC: 9AC6444F05C58170 -====> Computed HMAC: 9AC6444F05C58170 -Trusted input hash -5122C2CDE6823E55754175B92C9C57A0A8E1AC83C38E1787FD3A1FF3348E951301000000 ---- ADD TO HASH FULL: -5122C2CDE6823E55754175B92C9C57A0A8E1AC83C38E1787FD3A1FF3348E951301000000 ---- ADD TO HASH AUTH: -5122C2CDE6823E55754175B92C9C57A0A8E1AC83C38E1787FD3A1FF3348E951301000000 -Adding amount -40420F0000000000 -New amount -00000000000F4240 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A914CBAE5B50CF939E6F531B8A6B7ABD788FE14B029788ACFDFFFFFF -Process input script, remaining 25 ---- ADD TO HASH FULL: -76A914CBAE5B50CF939E6F531B8A6B7ABD788FE14B029788 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -AC ---- ADD TO HASH FULL: -FDFFFFFF ---- ADD TO HASH AUTH: -FDFFFFFF -Process input -Input hashing done -Presign ready -New APDU received: -E04AFF000100 -state=1 -New APDU received: -E04A8000230178410F00000000001976A91413D7D58166946C3EC022934066D8C0D111D1BB4188AC -state=1 ---- ADD TO HASH FULL: -0178410F00000000001976A91413D7D58166946C3EC022934066D8C0D111D1BB4188AC ---- ADD TO HASH AUTH: -0178410F00000000001976A91413D7D58166946C3EC022934066D8C0D111D1BB4188AC -Checksum -BA597C35 -Length to encode 25 -To encode -6F13D7D58166946C3EC022934066D8C0D111D1BB41BA597C35 -Length encoded 34 -Encoded -6D684B736837457A4A6F316753553176727079656A533171734A41754B7961575767 -New APDU received: -E04800001B058000002C8000000180000000000000000000000000001D041A01 ---- ADD TO HASH FULL: -1A041D0001000000 -Using private component -4FD5547026D24A120A268D246E90DD23568459A16BCFCB54FCEE86EBCD1834FA -Hash1 -9C12EA3D3E8644284EB010F24F97D5BC1FDA5A8F9B2E11B3D65FBC40BD7089BD -Hash2 -AB3C3430727A430B162A7CD73CE0BDC87A3DAEDDBAAA1A871E232CB0674F9129 diff --git a/tests/data/one-to-one/p2pkh/tx.json b/tests/data/one-to-one/p2pkh/tx.json deleted file mode 100644 index cce076fe..00000000 --- a/tests/data/one-to-one/p2pkh/tx.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "txid": "f26b62046101b7cd369eafb3aed5bef343ff3849b98b3cf42dea9cdc78b4c2f4", - "raw": "02000000015122c2cde6823e55754175b92c9c57a0a8e1ac83c38e1787fd3a1ff3348e9513010000006b483045022100e55b3ca788721aae8def2eadff710e524ffe8c9dec1764fdaa89584f9726e196022012a30fbcf9e1a24df31a1010356b794ab8de438b4250684757ed5772402540f4012102ee8608207e21028426f69e76447d7e3d5e077049f5e683c3136c2314762a4718fdffffff0178410f00000000001976a91413d7d58166946c3ec022934066d8c0d111d1bb4188ac1a041d00", - "amount": 999800, - "fees": 200, - "to": "mhKsh7EzJo1gSU1vrpyejS1qsJAuKyaWWg", - "sign_paths": ["m/84'/1'/0'/0/0"], - "change_path": null, - "lock_time": 1901594, - "utxos": [ - { - "txid": "13958e34f31f3afd87178ec383ace1a8a0579c2cb9754175553e82e6cdc22251", - "raw": "02000000000101ec230e53095256052a2428270eec0498944b10f6f1c578f431c23d0098b4ae5a0100000017160014281539820e2de973ae41ba6004b431c921c4d86dfeffffff02727275000000000017a914c8b906af298c70e603a28c3efc2fae19e6ab280f8740420f00000000001976a914cbae5b50cf939e6f531b8a6b7abd788fe14b029788ac02473044022037ecb4248361aafd4f8c11e705f0fa7a5fbdcd595172fcd5643f3b11beff5d400220020c6d326f6c37d63cecadaf4eb335faedf7c44e05f5ef1d2b68140b023bd13d012103dac82fc0acfcfc36348d4a48a46f01cea77f2b9ece3f8c3b4c99d0b0b2f995d284f21c00", - "output_indexes": [1], - "output_amounts": [999800] - } - ] - -} diff --git a/tests/data/one-to-one/p2sh-p2wpkh/apdu_debug.log b/tests/data/one-to-one/p2sh-p2wpkh/apdu_debug.log deleted file mode 100644 index 8fed7978..00000000 --- a/tests/data/one-to-one/p2sh-p2wpkh/apdu_debug.log +++ /dev/null @@ -1,199 +0,0 @@ -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E042000009000000010200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -01 -Number of inputs : 1 -Process input -New APDU received: -E0428000251AF94AFBD37204AF7C23D6C7B8D41617831555831F72675C4181DB82B8A650410100000017 -Process input ---- ADD TO HASH FULL: -1AF94AFBD37204AF7C23D6C7B8D41617831555831F72675C4181DB82B8A6504101000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process input script, remaining 23 -New APDU received: -E04280001B16001431C162CDDC618B8E80049620FFAF3F9210B10783FEFFFFFF -Process input script, remaining 23 ---- ADD TO HASH FULL: -16001431C162CDDC618B8E80049620FFAF3F9210B107 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -83 ---- ADD TO HASH FULL: -FEFFFFFF -Process input -Input hashing done -New APDU received: -E04280000102 -Input hashing done ---- ADD TO HASH FULL: -02 -Number of outputs : 2 -New APDU received: -E0428000090E19B7000000000017 ---- ADD TO HASH FULL: -0E19B70000000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process output script, remaining 23 -New APDU received: -E042800017A914C9ED58BD29EF20ADC85156DA674A03E478799F1787 -Process output script, remaining 23 ---- ADD TO HASH FULL: -A914C9ED58BD29EF20ADC85156DA674A03E478799F1787 -Process output script, remaining 0 -New APDU received: -E04280000940420F000000000017 -Process output script, remaining 0 ---- ADD TO HASH FULL: -40420F0000000000 ---- ADD TO HASH FULL: -17 -Script to read 23 -Process output script, remaining 23 -New APDU received: -E042800017A914424B246398B68142926AEDC8D85628AC224A54DC87 -Process output script, remaining 23 ---- ADD TO HASH FULL: -A914424B246398B68142926AEDC8D85628AC224A54DC87 -Process output script, remaining 0 -New APDU received: -E04280000475F21C00 -Process output script, remaining 0 -Output hashing done ---- ADD TO HASH FULL: -75F21C00 -Transaction parsed -New APDU received: -E02601000101 -New APDU received: -E0440002050200000001 -Init transaction parser -Number of inputs : 1 -Process input -New APDU received: -E04480003B013832003BEF167FA3F3D4233D1660B4B3BB62E78FB35C9786B0A96E6B4D61697CA112D9BA4E0100000040420F000000000027708A585F4E617B19 -Process input -Trusted input used in segwit mode -====> Input HMAC: 27708A585F4E617B -====> Computed HMAC: 27708A585F4E617B -Adding amount -40420F0000000000 -New amount -00000000000F4240 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A914E310D044F88DAB1B42769E4A84CAF08363F9ECC188ACFDFFFFFF -Process input script, remaining 25 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done ---- ADD TO HASH FULL: -23E9829BFB4E23FBD3C4848BAA035AF15D73BCB83E510F7F097F90A21A4280D2 -hashPrevout -5878F55307FBC6A50458E9470B134440E1EB0AAF19172B45796FE925F031B18C -hashSequence -CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52 -Presign ready -New APDU received: -E04AFF000100 -state=1 -New APDU received: -E04A80002101AA410F000000000017A9144D7997B902D0F1A2441A0542C920413B957E8A2287 -state=1 ---- ADD TO HASH FULL: -AA410F000000000017A9144D7997B902D0F1A2441A0542C920413B957E8A2287 -hashOutputs -056D1137157786D3D8724535C9894AD074D7B1569A5E79B5221641CAB56D1900 -Auth Hash: -E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 -Checksum -FF599171 -Length to encode 25 -To encode -C44D7997B902D0F1A2441A0542C920413B957E8A22FF599171 -Length encoded 35 -Encoded -324D7A4A736754696966747266426B636472766232394E34326273674B3177644A5938 -Segwit parsed once -New APDU received: -E0440080050200000001 -Init transaction parser -Resume SegWit hash -SEGWIT Version -02000000 -SEGWIT HashedPrevouts -5878F55307FBC6A50458E9470B134440E1EB0AAF19172B45796FE925F031B18C -SEGWIT HashedSequence -CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52 ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -5878F55307FBC6A50458E9470B134440E1EB0AAF19172B45796FE925F031B18C ---- ADD TO HASH FULL: -CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52 ---- ADD TO HASH AUTH: -5878F55307FBC6A50458E9470B134440E1EB0AAF19172B45796FE925F031B18CCAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52056D1137157786D3D8724535C9894AD074D7B1569A5E79B5221641CAB56D1900 -Number of inputs : 1 -Process input -New APDU received: -E04480003B013832003BEF167FA3F3D4233D1660B4B3BB62E78FB35C9786B0A96E6B4D61697CA112D9BA4E0100000040420F000000000027708A585F4E617B19 -Process input -Trusted input used in segwit mode -====> Input HMAC: 27708A585F4E617B -====> Computed HMAC: 27708A585F4E617B ---- ADD TO HASH FULL: -167FA3F3D4233D1660B4B3BB62E78FB35C9786B0A96E6B4D61697CA112D9BA4E01000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A914E310D044F88DAB1B42769E4A84CAF08363F9ECC188ACFDFFFFFF -Process input script, remaining 25 ---- ADD TO HASH FULL: -76A914E310D044F88DAB1B42769E4A84CAF08363F9ECC188 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -AC -SEGWIT Add value -40420F0000000000 ---- ADD TO HASH FULL: -40420F0000000000 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -SEGWIT hashedOutputs -056D1137157786D3D8724535C9894AD074D7B1569A5E79B5221641CAB56D1900 -Sign ready -New APDU received: -E04800001B05800000318000000180000000000000000000000000001D03FD01 ---- ADD TO HASH FULL: -FD031D0001000000 -Using private component -C16863B6D7B2B534AB6A7E049731E79907972F4689EBFC5A95398C537D683416 -Hash1 -746039019C2B7F0ACBF215F8DFB139CE369ECD7D463C18975EE588B9109FA971 -Hash2 -1398DE4932EC3444C1C18A8D3D9D5C8FEF5FAA838F45B91AD08D242405718092 diff --git a/tests/data/one-to-one/p2sh-p2wpkh/tx.json b/tests/data/one-to-one/p2sh-p2wpkh/tx.json deleted file mode 100644 index 33ce877b..00000000 --- a/tests/data/one-to-one/p2sh-p2wpkh/tx.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "txid": "ae7707d8f72dd74d3c4fefdff0e9f9ad683a96f82d1a03d3d08fd86f595b94c3", - "raw": "02000000000101167fa3f3d4233d1660b4b3bb62e78fb35c9786b0a96e6b4d61697ca112d9ba4e0100000017160014e310d044f88dab1b42769e4a84caf08363f9ecc1fdffffff01aa410f000000000017a9144d7997b902d0f1a2441a0542c920413b957e8a228702483045022100b8ab2d40241c406b7e232e98fc99188ed46c062cc3f49ea39cfb77ae9f4918760220078763f7e0078be84ceb939bea8a87934e64ae3502d8636eb249c7ddd97036f7012102a80f007194d53d37f6f99539f635390588c4e1c328b098295f61af40d60cb28afd031d00", - "amount": 999850, - "fees": 150, - "to": "2MzJsgTiiftrfBkcdrvb29N42bsgK1wdJY8", - "sign_paths": ["m/49'/1'/0'/0/0"], - "change_path": null, - "lock_time": 1901565, - "utxos": [ - { - "txid": "4ebad912a17c69614d6b6ea9b086975cb38fe762bbb3b460163d23d4f3a37f16", - "raw": "020000000001011af94afbd37204af7c23d6c7b8d41617831555831f72675c4181db82b8a65041010000001716001431c162cddc618b8e80049620ffaf3f9210b10783feffffff020e19b7000000000017a914c9ed58bd29ef20adc85156da674a03e478799f178740420f000000000017a914424b246398b68142926aedc8d85628ac224a54dc8702473044022072190b182ab580404974fc5f569d0497002d0018e2903a00f10d91994d257cd902207973fb20ba684a887c97914079ff6a8a4ea10f0b101e16ebbb2bc7d03b4da971012102193ba58ea7475219eb3eddd0d61ed86b664585bab55d01ef3afdc4b0c1a0dd4575f21c00", - "output_indexes": [1], - "output_amounts": [1000000] - } - ] - -} diff --git a/tests/data/one-to-one/p2wpkh/apdu_debug.log b/tests/data/one-to-one/p2wpkh/apdu_debug.log deleted file mode 100644 index e28db8ab..00000000 --- a/tests/data/one-to-one/p2wpkh/apdu_debug.log +++ /dev/null @@ -1,188 +0,0 @@ -New APDU received: -E04000000D03800000548000000180000000 -pin ok -Using private component -08B5ED5B131552DA3B9CA9869E506420EDF4ABEC8C1BA5D468BE04CCC4EC4A48 -To hash -02668C624FDBF81D0E9D3601D5DA195E0D06E48E3F5021D9269774BD0A9E5F2CBE -Hash160 -DAAEB63EBF9E49ED7F25C491432B01D945E37A7C -Checksum -9B84A352 -Length to encode 25 -To encode -6FDAAEB63EBF9E49ED7F25C491432B01D945E37A7C9B84A352 -Length encoded 34 -Encoded -6E3154457534763756734C59696D575A5775333947553871736E7039694456676F6A -Length 34 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E0C4000000 -New APDU received: -E042000009000000000200000001 -Init transaction parser ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -01 -Number of inputs : 1 -Process input -New APDU received: -E04280002534AB4E0084423B9DA3B7701023A4137C362F742328C5CB6F6D5086130A88B0940000000000 -Process input ---- ADD TO HASH FULL: -34AB4E0084423B9DA3B7701023A4137C362F742328C5CB6F6D5086130A88B09400000000 ---- ADD TO HASH FULL: -00 -Script to read 0 -Process input script, remaining 0 -New APDU received: -E042800004FDFFFFFF -Process input script, remaining 0 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -New APDU received: -E04280000101 -Input hashing done ---- ADD TO HASH FULL: -01 -Number of outputs : 1 -New APDU received: -E0428000095EB58B040000000016 ---- ADD TO HASH FULL: -5EB58B0400000000 ---- ADD TO HASH FULL: -16 -Script to read 22 -Process output script, remaining 22 -New APDU received: -E04280001600142318D66F84FEF5C4875F933B038DC63831F8DA13 -Process output script, remaining 22 ---- ADD TO HASH FULL: -00142318D66F84FEF5C4875F933B038DC63831F8DA13 -Process output script, remaining 0 -New APDU received: -E042800004FBF41C00 -Process output script, remaining 0 -Output hashing done ---- ADD TO HASH FULL: -FBF41C00 -Transaction parsed -New APDU received: -E02601000101 -New APDU received: -E0440002050200000001 -Init transaction parser -Number of inputs : 1 -Process input -New APDU received: -E04480003B013832002BD7F3DB0E87B75A0C4A113F30906230FFAD598BAA37F3AB27FC2C339DE849B9F385000000005EB58B0400000000F926369658DFFF5A19 -Process input -Trusted input used in segwit mode -====> Input HMAC: F926369658DFFF5A -====> Computed HMAC: F926369658DFFF5A -Adding amount -5EB58B0400000000 -New amount -00000000048BB55E -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A9142318D66F84FEF5C4875F933B038DC63831F8DA1388ACFDFFFFFF -Process input script, remaining 25 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done ---- ADD TO HASH FULL: -23E9829BFB4E23FBD3C4848BAA035AF15D73BCB83E510F7F097F90A21A4280D2 -hashPrevout -C7B413870810B6E08F118FBDFA1BF67FAB8F1048FC0F943E8EC91D60733CBCF4 -hashSequence -CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52 -Presign ready -New APDU received: -E04AFF000100 -state=1 -New APDU received: -E04A80002001F0B48B04000000001600141347E82A037B5DBB38CF8C4759F242B1F5C7E09A -state=1 ---- ADD TO HASH FULL: -F0B48B04000000001600141347E82A037B5DBB38CF8C4759F242B1F5C7E09A -hashOutputs -62BBD24C452AAF0705EF8A79E2E3BF9A20A75A587DBFF2753FEB7B99A0FE6DC6 -Auth Hash: -E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 -Segwit parsed once -New APDU received: -E0440080050200000001 -Init transaction parser -Resume SegWit hash -SEGWIT Version -02000000 -SEGWIT HashedPrevouts -C7B413870810B6E08F118FBDFA1BF67FAB8F1048FC0F943E8EC91D60733CBCF4 -SEGWIT HashedSequence -CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52 ---- ADD TO HASH FULL: -02000000 ---- ADD TO HASH FULL: -C7B413870810B6E08F118FBDFA1BF67FAB8F1048FC0F943E8EC91D60733CBCF4 ---- ADD TO HASH FULL: -CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC52 ---- ADD TO HASH AUTH: -C7B413870810B6E08F118FBDFA1BF67FAB8F1048FC0F943E8EC91D60733CBCF4CAF35E5224DE16EFA3CCAF41070F6E7B9432B6F79551E629FCA9D1C03B43BC5262BBD24C452AAF0705EF8A79E2E3BF9A20A75A587DBFF2753FEB7B99A0FE6DC6 -Number of inputs : 1 -Process input -New APDU received: -E04480003B013832002BD7F3DB0E87B75A0C4A113F30906230FFAD598BAA37F3AB27FC2C339DE849B9F385000000005EB58B0400000000F926369658DFFF5A19 -Process input -Trusted input used in segwit mode -====> Input HMAC: F926369658DFFF5A -====> Computed HMAC: F926369658DFFF5A ---- ADD TO HASH FULL: -F3DB0E87B75A0C4A113F30906230FFAD598BAA37F3AB27FC2C339DE849B9F38500000000 ---- ADD TO HASH FULL: -19 -Script to read 25 -Process input script, remaining 25 -New APDU received: -E04480001D76A9142318D66F84FEF5C4875F933B038DC63831F8DA1388ACFDFFFFFF -Process input script, remaining 25 ---- ADD TO HASH FULL: -76A9142318D66F84FEF5C4875F933B038DC63831F8DA1388 -Process input script, remaining 1 -Disabling P2SH consumption ---- ADD TO HASH FULL: -AC -SEGWIT Add value -5EB58B0400000000 ---- ADD TO HASH FULL: -5EB58B0400000000 ---- ADD TO HASH FULL: -FDFFFFFF -Process input -Input hashing done -SEGWIT hashedOutputs -62BBD24C452AAF0705EF8A79E2E3BF9A20A75A587DBFF2753FEB7B99A0FE6DC6 -Sign ready -New APDU received: -E04800001B05800000548000000180000000000000000000000100001CF59001 ---- ADD TO HASH FULL: -90F51C0001000000 -Using private component -21E9C06E0D5E169EE7E6C961D2F3F3286666EF74F2CE5EFF6F6108EB6D855DA5 -Hash1 -773DB7D1831DA4C933BD8DED5563DC5E03EF752CC9601A7423059368355CFE68 -Hash2 -824F6D8B43D99E86750D9F290E26BE16CEA93ACD1B8BC045E940B34704C61D60 diff --git a/tests/data/one-to-one/p2wpkh/tx.json b/tests/data/one-to-one/p2wpkh/tx.json deleted file mode 100644 index a69ba247..00000000 --- a/tests/data/one-to-one/p2wpkh/tx.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "txid": "10a7143a7c64c1eed7a9e8fe7b0d4016c7dfe749d4db4de1f3ec5899f2a24c2c", - "raw": "02000000000101f3db0e87b75a0c4a113f30906230ffad598baa37f3ab27fc2c339de849b9f3850000000000fdffffff01f0b48b04000000001600141347e82a037b5dbb38cf8c4759f242b1f5c7e09a0248304502210087dadcd43ba52983eb19786b20a4a8e6969e1f9330017d1ffc537effad0f7d9102200b293788f2956f6352afad08b6c9f48d213e9e96ff74ffd76a28cf448fb358a1012103455ee7cedc97b0ba435b80066fc92c963a34c600317981d135330c4ee43ac7a390f51c00", - "amount": 76264688, - "fees": 110, - "to": "tb1qzdr7s2sr0dwmkwx033r4nujzk86u0cy6fmzfjk", - "sign_paths": ["m/84'/1'/0'/0/1"], - "change_path": null, - "lock_time": 1897872, - "utxos": [ - { - "txid": "85f3b949e89d332cfc27abf337aa8b59adff306290303f114a0c5ab7870edbf3", - "raw": "0200000000010134ab4e0084423b9da3b7701023a4137c362f742328c5cb6f6d5086130a88b0940000000000fdffffff015eb58b04000000001600142318d66f84fef5c4875f933b038dc63831f8da130248304502210088e618e63f1a908022bb5fc6aaa19b454ac3eec104ffd78319acc0ccfe464378022003ce22f37a945eb2b9e70ebbc321a74c9594efd7c986a4004538b728d30ecb500121027cb75d34b005c4eb9f62bbf2c457d7638e813e757efcec8fa68677d950b63662fbf41c00", - "output_indexes": [0], - "output_amounts": [76264798] - } - ] - -} \ No newline at end of file diff --git a/tests/prepare_tests.sh b/tests/prepare_tests.sh deleted file mode 100755 index 617a4ad4..00000000 --- a/tests/prepare_tests.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -cd .. -make clean -make -j DEBUG=1 # compile optionally with PRINTF -mv bin/ tests/bitcoin-bin -make clean -make -j DEBUG=1 COIN=bitcoin_testnet_legacy -mv bin/ tests/bitcoin-testnet-bin diff --git a/tests/psbt/singlesig/pkh-1to1.psbt b/tests/psbt/singlesig/pkh-1to1.psbt new file mode 100644 index 00000000..a4c0898c --- /dev/null +++ b/tests/psbt/singlesig/pkh-1to1.psbt @@ -0,0 +1 @@ +cHNidP8BAFUCAAAAAVEiws3mgj5VdUF1uSycV6Co4ayDw44Xh/06H/M0jpUTAQAAAAD9////AXhBDwAAAAAAGXapFBPX1YFmlGw+wCKTQGbYwNER0btBiKwaBB0AAAEA+QIAAAAAAQHsIw5TCVJWBSokKCcO7ASYlEsQ9vHFePQxwj0AmLSuWgEAAAAXFgAUKBU5gg4t6XOuQbpgBLQxySHE2G3+////AnJydQAAAAAAF6kUyLkGrymMcOYDoow+/C+uGearKA+HQEIPAAAAAAAZdqkUy65bUM+Tnm9TG4prer14j+FLApeIrAJHMEQCIDfstCSDYar9T4wR5wXw+npfvc1ZUXL81WQ/OxG+/11AAiACDG0yb2w31jzsra9OszX67ffETgX17x0raBQLAjvRPQEhA9rIL8Cs/Pw2NI1KSKRvAc6nfyuezj+MO0yZ0LCy+ZXShPIcACIGAu6GCCB+IQKEJvaedkR9fj1eB3BJ9eaDwxNsIxR2KkcYGPWswv0sAACAAQAAgAAAAIAAAAAAAAAAAAAA diff --git a/tests/psbt/singlesig/sh-wpkh-1to2.psbt b/tests/psbt/singlesig/sh-wpkh-1to2.psbt new file mode 100644 index 00000000..dc54482a --- /dev/null +++ b/tests/psbt/singlesig/sh-wpkh-1to2.psbt @@ -0,0 +1 @@ +cHNidP8BAHICAAAAAXT0yaTajRSLu1boaayjaQ3aDOOsvPgWCcyUbRtvFkrOAQAAAAD9////AlDUEgAAAAAAFgAUMxjgT65sEq/LAJxpzVflslBK5rT1cQgAAAAAABepFG1IUtrzpUCfdyFtu46j1ZIxLX7phwAAAAAAAQCMAgAAAAHQ47WR3EhO23HqtmoOmUcxAH/rfQgqUMdC8CPqCQFNHgEAAAAXFgAU4xDQRPiNqxtCdp5KhMrwg2P57MH9////AmDqAAAAAAAAGXapFEWIHtDTWHVQ95SEe3yLn6A+3Qo8iKx/ZhsAAAAAABepFPBGTZ+g6kLYDk1fFFeIOYLiO47shwAAAAABASB/ZhsAAAAAABepFPBGTZ+g6kLYDk1fFFeIOYLiO47shwEEFgAUyweAh+/0haqiJg6UpT19bRxd0VEiBgJLo7d9kz3p+j+VgzSMQPPKry7/rVtuJE7Oirv8xyRPZxj1rML9MQAAgAEAAIAAAACAAQAAAAAAAAAAAAEAFgAUTLRHxTu3NSNPKxOQ1F2dhksVdtMiAgOKsR70a0i1XwDFPv3fOM3f+dYzW8r1L6n5k4R/LM0vVxj1rML9MQAAgAEAAIAAAACAAQAAAAIAAAAA diff --git a/tests/psbt/singlesig/sh-wpkh-1to2.rawtx b/tests/psbt/singlesig/sh-wpkh-1to2.rawtx new file mode 100644 index 00000000..7d5bdf80 --- /dev/null +++ b/tests/psbt/singlesig/sh-wpkh-1to2.rawtx @@ -0,0 +1 @@ +0200000000010174f4c9a4da8d148bbb56e869aca3690dda0ce3acbcf81609cc946d1b6f164ace0100000017160014cb078087eff485aaa2260e94a53d7d6d1c5dd151fdffffff0250d41200000000001600143318e04fae6c12afcb009c69cd57e5b2504ae6b4f57108000000000017a9146d4852daf3a5409f77216dbb8ea3d592312d7ee987024730440220720722b08489c2a50d10edea8e21880086c8e8f22889a16815e306daeea4665b02203fcf453fa490b76cf4f929714065fc90a519b7b97ab18914f9451b5a4b4524120121024ba3b77d933de9fa3f9583348c40f3caaf2effad5b6e244ece8abbfcc7244f6700000000 diff --git a/tests/psbt/singlesig/tr-1to2-sighash-all.psbt b/tests/psbt/singlesig/tr-1to2-sighash-all.psbt new file mode 100644 index 00000000..8cecafd2 --- /dev/null +++ b/tests/psbt/singlesig/tr-1to2-sighash-all.psbt @@ -0,0 +1 @@ +cHNidP8BAH0CAAAAAaG4I9IzbWlLSTTvm25bfeF6BVE9qKKdsCouy8eppv5tAQAAAAD9////AlX/pwAAAAAAIlEgC450hrwwagrvt6fACvBAVULbGs1z7syoJ3HM9f5etg+ghgEAAAAAABYAFBOZuKCYR6A5sDUvWNISwYC6sX93AAAAAAABASunhqkAAAAAACJRINj08dGJltthuxyvVCPeJdih7unJUNN+b/oCMBLV5i4NAQMEAQAAACEWIS6ihWpc8RDmaivp1zUxR5P9vLOIsrjxPytq3pguevUZAPWswv1WAACAAQAAgAAAAIABAAAAAAAAAAEXICEuooVqXPEQ5mor6dc1MUeT/byziLK48T8rat6YLnr1AAEFIAKQgezlYWqhy5kxn8SHTv7kfwjOul9gBGNsjENAml8KIQcCkIHs5WFqocuZMZ/Eh07+5H8IzrpfYARjbIxDQJpfChkA9azC/VYAAIABAACAAAAAgAEAAAACAAAAAAA= diff --git a/tests/psbt/singlesig/tr-1to2-sighash-default.psbt b/tests/psbt/singlesig/tr-1to2-sighash-default.psbt new file mode 100644 index 00000000..c62b238f --- /dev/null +++ b/tests/psbt/singlesig/tr-1to2-sighash-default.psbt @@ -0,0 +1 @@ +cHNidP8BAH0CAAAAAeFoYcDSl0n1LNLt3hDLzE9ZEhBxD2QOXY4UQM6F2W3GAQAAAAD9////Ao00lwAAAAAAIlEgC450hrwwagrvt6fACvBAVULbGs1z7syoJ3HM9f5etg+ghgEAAAAAABYAFBOZuKCYR6A5sDUvWNISwYC6sX93AAAAAAABASvfu5gAAAAAACJRIImQSmNI1/+aRNSduLaoB8Yi6Gg2TFR9pCbzC1piExhqAQMEAAAAACEW6cabCV7QS1Yq/I1BaRk2ulc+tvaJvCNmAL5Po5JvZBIZAPWswv1WAACAAQAAgAAAAIABAAAAAwAAAAEXIOnGmwle0EtWKvyNQWkZNrpXPrb2ibwjZgC+T6OSb2QSAAEFIAKQgezlYWqhy5kxn8SHTv7kfwjOul9gBGNsjENAml8KIQcCkIHs5WFqocuZMZ/Eh07+5H8IzrpfYARjbIxDQJpfChkA9azC/VYAAIABAACAAAAAgAEAAAACAAAAAAA= diff --git a/tests/psbt/singlesig/tr-1to2-sighash-omitted.psbt b/tests/psbt/singlesig/tr-1to2-sighash-omitted.psbt new file mode 100644 index 00000000..046f8896 --- /dev/null +++ b/tests/psbt/singlesig/tr-1to2-sighash-omitted.psbt @@ -0,0 +1 @@ +cHNidP8BAH0CAAAAAeFoYcDSl0n1LNLt3hDLzE9ZEhBxD2QOXY4UQM6F2W3GAQAAAAD9////Ao00lwAAAAAAIlEgC450hrwwagrvt6fACvBAVULbGs1z7syoJ3HM9f5etg+ghgEAAAAAABYAFBOZuKCYR6A5sDUvWNISwYC6sX93AAAAAAABASvfu5gAAAAAACJRIImQSmNI1/+aRNSduLaoB8Yi6Gg2TFR9pCbzC1piExhqIRbpxpsJXtBLVir8jUFpGTa6Vz629om8I2YAvk+jkm9kEhkA9azC/VYAAIABAACAAAAAgAEAAAADAAAAARcg6cabCV7QS1Yq/I1BaRk2ulc+tvaJvCNmAL5Po5JvZBIAAQUgApCB7OVhaqHLmTGfxIdO/uR/CM66X2AEY2yMQ0CaXwohBwKQgezlYWqhy5kxn8SHTv7kfwjOul9gBGNsjENAml8KGQD1rML9VgAAgAEAAIAAAACAAQAAAAIAAAAAAA== diff --git a/tests/psbt/singlesig/wpkh-1to2.psbt b/tests/psbt/singlesig/wpkh-1to2.psbt new file mode 100644 index 00000000..6e6b84ff --- /dev/null +++ b/tests/psbt/singlesig/wpkh-1to2.psbt @@ -0,0 +1 @@ +cHNidP8BAHQCAAAAAXoqmXlWwJ+Op/0oGcGph7sU4iv5rc2vIKiXY3Is7uJkAQAAAAD9////AqC7DQAAAAAAGXapFDRKD0jKFQ7CuQOBdmC5tosTpnAmiKx0OCMAAAAAABYAFOs4+puBKPgfJule2wxf+uqDaQ/kAAAAAAABAH0CAAAAAa+/rgZZD3Qf8a9ZtqxGESYzakxKgttVPfb++rc3rDPzAQAAAAD9////AnARAQAAAAAAIgAg/e5EHFblsG0N+CwSTHBwFKXKGWWL4LmFa8oW8e0yWfel9DAAAAAAABYAFDr4QprVlUql7oozyYP9ih6GeZJLAAAAAAEBH6X0MAAAAAAAFgAUOvhCmtWVSqXuijPJg/2KHoZ5kksiBgPuLD2Y6x+TwKGqjlpACbcOt7ROrRXxZm8TawEq1Y0waBj1rML9VAAAgAEAAIAAAACAAQAAAAgAAAAAACICAinsR3JxMe0liKIMRu2pq7fapvSf1Quv5wucWqaWHE7MGPWswv1UAACAAQAAgAAAAIABAAAACgAAAAA= diff --git a/tests/psbt/singlesig/wpkh-1to2.rawtx b/tests/psbt/singlesig/wpkh-1to2.rawtx new file mode 100644 index 00000000..a8dbde66 --- /dev/null +++ b/tests/psbt/singlesig/wpkh-1to2.rawtx @@ -0,0 +1,2 @@ +020000000001017a2a997956c09f8ea7fd2819c1a987bb14e22bf9adcdaf20a89763722ceee2640100000000fdffffff02a0bb0d00000000001976a914344a0f48ca150ec2b903817660b9b68b13a6702688ac7438230000000000160014eb38fa9b8128f81f26e95edb0c5ffaea83690fe402483045022100ab44f34dd7e87c9054591297a101e8500a0641d1d591878d0d23cf8096fa79e802205d12d1062d925e27b57bdcf994ecf332ad0a8e67b8fe407bab2101255da632aa012103ee2c3d98eb1f93c0a1aa8e5a4009b70eb7b44ead15f1666f136b012ad58d306800000000 + diff --git a/tests/psbt/singlesig/wpkh-2to2.psbt b/tests/psbt/singlesig/wpkh-2to2.psbt new file mode 100644 index 00000000..51588f88 --- /dev/null +++ b/tests/psbt/singlesig/wpkh-2to2.psbt @@ -0,0 +1 @@ +cHNidP8BAKYCAAAAAp4s/ifwrYe3iiN9XXQF1KMGZso2HVhaRnsN/kImK020AQAAAAD9////r7+uBlkPdB/xr1m2rEYRJjNqTEqC21U99v76tzesM/MAAAAAAP3///8CqDoGAAAAAAAWABTrOPqbgSj4HybpXtsMX/rqg2kP5OCTBAAAAAAAIgAgP6lmyd3Nwv2W5KXhvHZbn69s6LPrTxEEqta993Mk5b4AAAAAAAEAcQIAAAABk2qy4BBy95PP5Ml3VN4bYf4D59tlNsiy8h3QtXQsSEUBAAAAAP7///8C3uHHAAAAAAAWABTreNfEC/EGOw4/zinDVltonIVZqxAnAAAAAAAAFgAUIxjWb4T+9cSHX5M7A43GODH42hP5lx4AAQEfECcAAAAAAAAWABQjGNZvhP71xIdfkzsDjcY4MfjaEyIGA0Ve587cl7C6Q1uABm/JLJY6NMYAMXmB0TUzDE7kOsejGPWswv1UAACAAQAAgAAAAIAAAAAAAQAAAAABAHEBAAAAAQ5HHvTpLBrLUe/IZg+NP2mTbqnJsr/3L/m8gcUe/PRkAQAAAAAAAAAAAmCuCgAAAAAAFgAUNcbg3W08hLFrqIXcpzrIY9C1k+yvBjIAAAAAABYAFNwobgzS5r03zr6ew0n7XwiQVnL8AAAAAAEBH2CuCgAAAAAAFgAUNcbg3W08hLFrqIXcpzrIY9C1k+wiBgJxtbd5rYcIOFh3l7z28MeuxavnanCdck9I0uJs+HTwoBj1rML9VAAAgAEAAIAAAACAAQAAAAAAAAAAIgICKexHcnEx7SWIogxG7amrt9qm9J/VC6/nC5xappYcTswY9azC/VQAAIABAACAAAAAgAEAAAAKAAAAAAA= diff --git a/tests/psbt/singlesig/wpkh-2to2.rawtx b/tests/psbt/singlesig/wpkh-2to2.rawtx new file mode 100644 index 00000000..cb473f9c --- /dev/null +++ b/tests/psbt/singlesig/wpkh-2to2.rawtx @@ -0,0 +1 @@ +020000000001029e2cfe27f0ad87b78a237d5d7405d4a30666ca361d585a467b0dfe42262b4db40100000000fdffffffafbfae06590f741ff1af59b6ac461126336a4c4a82db553df6fefab737ac33f30000000000fdffffff02a83a060000000000160014eb38fa9b8128f81f26e95edb0c5ffaea83690fe4e0930400000000002200203fa966c9ddcdc2fd96e4a5e1bc765b9faf6ce8b3eb4f1104aad6bdf77324e5be0247304402206b3e877655f08c6e7b1b74d6d893a82cdf799f68a5ae7cecae63a71b0339e5ce022019b94aa3fb6635956e109f3d89c996b1bfbbaf3c619134b5a302badfaf52180e012103455ee7cedc97b0ba435b80066fc92c963a34c600317981d135330c4ee43ac7a302483045022100e2e98e4f8c70274f10145c89a5d86e216d0376bdf9f42f829e4315ea67d79d210220743589fd4f55e540540a976a5af58acd610fa5e188a5096dfe7d36baf3afb94001210271b5b779ad870838587797bcf6f0c7aec5abe76a709d724f48d2e26cf874f0a000000000 diff --git a/tests/ragger_bitcoin/README.md b/tests/ragger_bitcoin/README.md new file mode 100644 index 00000000..ae9c2f4c --- /dev/null +++ b/tests/ragger_bitcoin/README.md @@ -0,0 +1 @@ +# Ragger wrapper for Ledger Bitcoin application client \ No newline at end of file diff --git a/tests/ragger_bitcoin/__init__.py b/tests/ragger_bitcoin/__init__.py new file mode 100644 index 00000000..516a775f --- /dev/null +++ b/tests/ragger_bitcoin/__init__.py @@ -0,0 +1,5 @@ +"""Ragger wrapper for Ledger Nano Bitcoin client""" + +from .ragger_bitcoin import createRaggerClient, RaggerClient +from .ragger_instructions import Instructions +__version__ = '0.0.1' diff --git a/tests/ragger_bitcoin/ragger_adaptor.py b/tests/ragger_bitcoin/ragger_adaptor.py new file mode 100644 index 00000000..8cf057ef --- /dev/null +++ b/tests/ragger_bitcoin/ragger_adaptor.py @@ -0,0 +1,79 @@ +from typing import Tuple, Union +from pathlib import Path + +from ragger.navigator import Navigator +from ragger.utils import RAPDU +from ragger_bitcoin.ragger_instructions import Instructions + +# Interface with ledger_bitcoin library + + +class RaggerAdaptor: + def __init__(self, comm_client, screenshot_dir): + self.transport_client = comm_client + self.navigate = False + self.navigator = None + self.testname = "" + self.instructions = None + self.screenshot_dir = screenshot_dir + self.instructions_index = 0 + + def set_navigation(self, navigate, navigator, testname, instructions): + self.navigate = navigate + self.navigator = navigator + self.testname = testname + self.instructions = instructions + self.instructions_index = 0 + + def exchange(self, apdu: Union[bytes, bytearray]) -> bytearray: + if self.navigate: + _, response, self.instructions_index = self.ragger_navigate( + self.navigator, apdu, self.instructions, self.testname, self.instructions_index) + else: + rapdu = self.transport_client.exchange_raw(apdu) + response = rapdu.data + return bytearray(response) + + def last_async_response(self) -> RAPDU: + return self.transport_client.last_async_response + + def ragger_navigate(self, navigator: Navigator, apdu: dict, instructions: Instructions, + testname: str, index: int) -> Tuple[int, bytes, int]: + sub_index = 0 + + if instructions: + text = instructions.data['text'] + instruction_until_text = instructions.data['instruction_until_text'] + instruction_on_text = instructions.data['instruction_on_text'] + save_screenshot = instructions.data['save_screenshot'] + else: + text = [] + instruction_until_text = [] + instruction_on_text = [] + save_screenshot = [] + + try: + response = self.transport_client.exchange_raw(apdu, tick_timeout=2) + except TimeoutError: + with self.transport_client.exchange_async_raw(apdu): + for t, instr_approve, instr_next, compare in zip(text[index], + instruction_on_text[index], + instruction_until_text[index], + save_screenshot[index]): + if compare: + navigator.navigate_until_text_and_compare( + instr_next, [instr_approve], + t, self.screenshot_dir, Path(f"{testname}_{index}_{sub_index}"), + screen_change_after_last_instruction=False, + screen_change_before_first_instruction=True) + else: + navigator.navigate_until_text(instr_next, + [instr_approve], + t, + screen_change_after_last_instruction=False, + screen_change_before_first_instruction=True) + sub_index += 1 + + response = self.last_async_response() + index += 1 + return response.status, response.data, index diff --git a/tests/ragger_bitcoin/ragger_bitcoin.py b/tests/ragger_bitcoin/ragger_bitcoin.py new file mode 100644 index 00000000..ff6c2f10 --- /dev/null +++ b/tests/ragger_bitcoin/ragger_bitcoin.py @@ -0,0 +1,79 @@ +from typing import Tuple, List, Optional, Union +from pathlib import Path +import base64 + +from ledger_bitcoin.client_base import TransportClient, PartialSignature +from ledger_bitcoin.common import Chain +from ledger_bitcoin.wallet import WalletPolicy +from ledger_bitcoin.psbt import PSBT +from ledger_bitcoin.client_legacy import LegacyClient, check_keypath +from ledger_bitcoin.btchip.btchip import btchip + +from ragger.navigator import Navigator +from ragger_bitcoin.ragger_instructions import Instructions +from ragger_bitcoin.ragger_adaptor import RaggerAdaptor + + +TESTS_ROOT_DIR = Path(__file__).parent + + +class RaggerClient(LegacyClient): + def __init__(self, comm_client: TransportClient, screenshot_dir: Path = TESTS_ROOT_DIR) -> None: + self.app = btchip(RaggerAdaptor(comm_client, screenshot_dir)) + self.chain = Chain.TEST + + def get_extended_pubkey( + self, path: str, display: bool = False, navigator: Optional[Navigator] = None, + testname: str = "", instructions: Instructions = None) -> str: + + if navigator: + self.app.dongle.set_navigation(True, navigator, testname, instructions) + + response = LegacyClient.get_extended_pubkey(self, path, display) + + self.app.dongle.set_navigation(False, navigator, testname, instructions) + + return response + + def sign_psbt(self, psbt: Union[PSBT, bytes, str], + wallet: WalletPolicy, wallet_hmac: Optional[bytes], + navigator: Optional[Navigator] = None, testname: str = "", + instructions: Instructions = None) -> List[Tuple[int, PartialSignature]]: + + if navigator: + self.app.dongle.set_navigation(True, navigator, testname, instructions) + + result = LegacyClient.sign_psbt(self, psbt, wallet, wallet_hmac) + + self.app.dongle.set_navigation(False, navigator, testname, instructions) + + return result + + def sign_message(self, message: Union[str, bytes], bip32_path: str, navigator: + Optional[Navigator] = None, + instructions: Instructions = None, + testname: str = "" + ) -> str: + + if navigator: + self.app.dongle.set_navigation(True, navigator, testname, instructions) + + if not check_keypath(bip32_path): + raise ValueError("Invalid bip32_path") + if isinstance(message, str): + message = bytearray(message, 'utf-8') + else: + message = bytearray(message) + bip32_path = bip32_path[2:] + # First display on screen what address you're signing for + self.app.getWalletPublicKey(bip32_path, True) + self.app.signMessagePrepare(bip32_path, message) + signature = self.app.signMessageSign() + + self.app.dongle.set_navigation(False, navigator, testname, instructions) + + return base64.b64encode(signature).decode('utf-8') + + +def createRaggerClient(backend, screenshot_dir: Path = TESTS_ROOT_DIR) -> RaggerClient: + return RaggerClient(backend, screenshot_dir) diff --git a/tests/ragger_bitcoin/ragger_instructions.py b/tests/ragger_bitcoin/ragger_instructions.py new file mode 100644 index 00000000..545902e6 --- /dev/null +++ b/tests/ragger_bitcoin/ragger_instructions.py @@ -0,0 +1,105 @@ +from ragger.navigator import NavInsID + + +class Instructions: + def __init__(self, model): + self.data = { + 'text': [], + 'instruction_until_text': [], + 'instruction_on_text': [], + 'save_screenshot': [] + } + + if not model: + raise Exception("Model must be specified") + + self.model = model + + def __str__(self): + return "Data: {0}\n\t".format(self.data) + + def same_request(self, text, instruction_until_text=NavInsID.RIGHT_CLICK, + instruction_on_text=NavInsID.BOTH_CLICK, save_screenshot=True): + + self.data['text'][-1].append(text) + self.data['instruction_until_text'][-1].append(instruction_until_text) + self.data['instruction_on_text'][-1].append(instruction_on_text) + self.data['save_screenshot'][-1].append(save_screenshot) + + def new_request(self, text, instruction_until_text=NavInsID.RIGHT_CLICK, + instruction_on_text=NavInsID.BOTH_CLICK, save_screenshot=True): + + self.data['text'].append([text]) + self.data['instruction_until_text'].append([instruction_until_text]) + self.data['instruction_on_text'].append([instruction_on_text]) + self.data['save_screenshot'].append([save_screenshot]) + + def nano_skip_screen(self, text, save_screenshot=True): + self.new_request(text, NavInsID.RIGHT_CLICK, NavInsID.RIGHT_CLICK, + save_screenshot=save_screenshot) + + def navigate_end_of_flow(self, save_screenshot=True): + self.new_request("Processing", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP, + save_screenshot=save_screenshot) + + def review_start(self, output_count: int = 1, save_screenshot=True): + self.new_request("Review", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP, + save_screenshot=save_screenshot) + for _ in range(0, output_count): + self.same_request("Amount", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP, + save_screenshot=save_screenshot) + def review_fees(self, fees_on_same_request: bool = True, save_screenshot=True): + if fees_on_same_request: + self.same_request("Fees", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP, + save_screenshot=save_screenshot) + else: + self.new_request("Fees", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP, + save_screenshot=save_screenshot) + + def confirm_transaction(self, save_screenshot=True): + self.same_request("Sign", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_CONFIRM, + save_screenshot=save_screenshot) + self.new_request("Transaction", NavInsID.USE_CASE_REVIEW_TAP, + NavInsID.USE_CASE_STATUS_DISMISS, + save_screenshot=save_screenshot) + + def confirm_message(self, save_screenshot=True): + self.new_request("Sign", NavInsID.USE_CASE_REVIEW_TAP, + NavInsID.USE_CASE_REVIEW_CONFIRM, save_screenshot=save_screenshot) + self.new_request("Message", NavInsID.USE_CASE_REVIEW_TAP, + NavInsID.USE_CASE_STATUS_DISMISS, save_screenshot=save_screenshot) + + def confirm_wallet(self, save_screenshot=True): + self.new_request("Approve", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_CONFIRM, + save_screenshot=save_screenshot) + self.same_request("Wallet", NavInsID.USE_CASE_REVIEW_TAP, + NavInsID.USE_CASE_STATUS_DISMISS, save_screenshot=save_screenshot) + + def reject_message(self, save_screenshot=True): + self.new_request("Sign", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_REJECT, + save_screenshot=save_screenshot) + self.same_request("Reject", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_CHOICE_CONFIRM, + save_screenshot=save_screenshot) + self.new_request("MESSAGE", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_STATUS_DISMISS, + save_screenshot=save_screenshot) + + def warning_accept(self, save_screenshot=True): + self.new_request("Warning", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_CHOICE_CONFIRM, + save_screenshot=save_screenshot) + + def address_confirm(self, save_screenshot=True): + self.new_request("Confirm", NavInsID.USE_CASE_REVIEW_TAP, + NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM, + save_screenshot=save_screenshot) + + def choice_confirm(self, save_screenshot=True): + self.new_request("Approve", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_CHOICE_CONFIRM, + save_screenshot=save_screenshot) + + def choice_reject(self, save_screenshot=True): + self.new_request("Approve", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_CHOICE_REJECT, + save_screenshot=save_screenshot) + + def footer_cancel(self, save_screenshot=True): + self.new_request("Approve", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.CANCEL_FOOTER_TAP, + save_screenshot=save_screenshot) diff --git a/tests/requirements.txt b/tests/requirements.txt index f8181210..030d75cb 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,4 +1,5 @@ -typing-extensions>=3.7.4.3 pytest>=6.2.1 -ledgercomm>=1.1.0 ecdsa>=0.16.1,<0.17.0 +ragger[speculos]>=1.6.0 +ragger[ledgerwallet]>=1.6.0 +ledger-bitcoin diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_0/00000.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_0/00000.png new file mode 100644 index 00000000..5a1a7890 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_1/00000.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_1/00000.png new file mode 100644 index 00000000..c0086b25 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_1/00001.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_1/00001.png new file mode 100644 index 00000000..b89d3ab1 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_1/00001.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_1/00002.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_1/00002.png new file mode 100644 index 00000000..ebd1846f Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_1/00002.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_2/00000.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_2/00000.png new file mode 100644 index 00000000..4321e601 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/0'_0_2/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_0/00000.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_0/00000.png new file mode 100644 index 00000000..5a1a7890 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_1/00000.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_1/00000.png new file mode 100644 index 00000000..c0086b25 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_1/00001.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_1/00001.png new file mode 100644 index 00000000..f90841bd Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_1/00001.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_1/00002.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_1/00002.png new file mode 100644 index 00000000..fa62612f Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_1/00002.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_2/00000.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_2/00000.png new file mode 100644 index 00000000..4321e601 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/10'_0_2/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png new file mode 100644 index 00000000..5a1a7890 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png new file mode 100644 index 00000000..c0086b25 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png new file mode 100644 index 00000000..85e46f7e Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_1/00002.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_1/00002.png new file mode 100644 index 00000000..e15bba2a Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_1/00002.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_2/00000.png b/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_2/00000.png new file mode 100644 index 00000000..4321e601 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/44'/1'/2'/1/42_0_2/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png b/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png new file mode 100644 index 00000000..5a1a7890 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png b/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png new file mode 100644 index 00000000..c0086b25 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png b/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png new file mode 100644 index 00000000..f32007e2 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00002.png b/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00002.png new file mode 100644 index 00000000..7b0858e8 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00002.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_2/00000.png b/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_2/00000.png new file mode 100644 index 00000000..4321e601 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/48'/1'/4'/1'/0/7_0_2/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png b/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png new file mode 100644 index 00000000..5a1a7890 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png b/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png new file mode 100644 index 00000000..c0086b25 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png b/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png new file mode 100644 index 00000000..640745a1 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_1/00002.png b/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_1/00002.png new file mode 100644 index 00000000..18c18d59 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_1/00002.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_2/00000.png b/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_2/00000.png new file mode 100644 index 00000000..4321e601 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/49'/1'/1'/1/3_0_2/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png b/tests/snapshots/flex/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png new file mode 100644 index 00000000..d5b76776 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png b/tests/snapshots/flex/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png new file mode 100644 index 00000000..abbcf4a7 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/84'/1'/2'/0/10_0_1/00000.png b/tests/snapshots/flex/test_get_public_key_m/84'/1'/2'/0/10_0_1/00000.png new file mode 100644 index 00000000..4321e601 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/84'/1'/2'/0/10_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png b/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png new file mode 100644 index 00000000..5a1a7890 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png b/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png new file mode 100644 index 00000000..c0086b25 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png b/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png new file mode 100644 index 00000000..aff137d3 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_1/00002.png b/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_1/00002.png new file mode 100644 index 00000000..53a0208f Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_1/00002.png differ diff --git a/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_2/00000.png b/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_2/00000.png new file mode 100644 index 00000000..4321e601 Binary files /dev/null and b/tests/snapshots/flex/test_get_public_key_m/86'/1'/4'/1/12_0_2/00000.png differ diff --git a/tests/snapshots/flex/test_sign_message_0_0/00000.png b/tests/snapshots/flex/test_sign_message_0_0/00000.png new file mode 100644 index 00000000..d5b76776 Binary files /dev/null and b/tests/snapshots/flex/test_sign_message_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_sign_message_0_0/00001.png b/tests/snapshots/flex/test_sign_message_0_0/00001.png new file mode 100644 index 00000000..4da45ae3 Binary files /dev/null and b/tests/snapshots/flex/test_sign_message_0_0/00001.png differ diff --git a/tests/snapshots/flex/test_sign_message_0_1/00000.png b/tests/snapshots/flex/test_sign_message_0_1/00000.png new file mode 100644 index 00000000..4321e601 Binary files /dev/null and b/tests/snapshots/flex/test_sign_message_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_sign_message_1_0/00000.png b/tests/snapshots/flex/test_sign_message_1_0/00000.png new file mode 100644 index 00000000..26f75545 Binary files /dev/null and b/tests/snapshots/flex/test_sign_message_1_0/00000.png differ diff --git a/tests/snapshots/flex/test_sign_message_1_0/00001.png b/tests/snapshots/flex/test_sign_message_1_0/00001.png new file mode 100644 index 00000000..2f2a9c99 Binary files /dev/null and b/tests/snapshots/flex/test_sign_message_1_0/00001.png differ diff --git a/tests/snapshots/flex/test_sign_message_1_0/00002.png b/tests/snapshots/flex/test_sign_message_1_0/00002.png new file mode 100644 index 00000000..3fdb4fd2 Binary files /dev/null and b/tests/snapshots/flex/test_sign_message_1_0/00002.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png new file mode 100644 index 00000000..764dec92 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png new file mode 100644 index 00000000..1ad645a5 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_pkh_1to1_0_2/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_pkh_1to1_0_2/00000.png new file mode 100644 index 00000000..684bc401 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_pkh_1to1_0_2/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_pkh_1to1_0_3/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_pkh_1to1_0_3/00000.png new file mode 100644 index 00000000..a19a87d4 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_pkh_1to1_0_3/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png new file mode 100644 index 00000000..764dec92 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_sh_wpkh_1to2_0_1/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_sh_wpkh_1to2_0_1/00000.png new file mode 100644 index 00000000..eb68ef02 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_sh_wpkh_1to2_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png new file mode 100644 index 00000000..1487210d Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_sh_wpkh_1to2_1_1/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_sh_wpkh_1to2_1_1/00000.png new file mode 100644 index 00000000..a19a87d4 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_sh_wpkh_1to2_1_1/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png new file mode 100644 index 00000000..764dec92 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_0_1/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_0_1/00000.png new file mode 100644 index 00000000..feb9222b Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png new file mode 100644 index 00000000..645da9d4 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_1_1/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_1_1/00000.png new file mode 100644 index 00000000..a19a87d4 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_1_1/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png new file mode 100644 index 00000000..764dec92 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_2_0_1/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_2_0_1/00000.png new file mode 100644 index 00000000..feb9222b Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_2_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png new file mode 100644 index 00000000..645da9d4 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_2_1_1/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_2_1_1/00000.png new file mode 100644 index 00000000..a19a87d4 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_1to2_2_1_1/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png new file mode 100644 index 00000000..764dec92 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png new file mode 100644 index 00000000..7dbc7163 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_2to2_0_2/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_2to2_0_2/00000.png new file mode 100644 index 00000000..2a2902c5 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_2to2_0_2/00000.png differ diff --git a/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_2to2_0_3/00000.png b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_2to2_0_3/00000.png new file mode 100644 index 00000000..a19a87d4 Binary files /dev/null and b/tests/snapshots/flex/test_sign_psbt_singlesig_wpkh_2to2_0_3/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_0/00000.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_0/00000.png new file mode 100644 index 00000000..547b31a7 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_0/00001.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_0/00001.png new file mode 100644 index 00000000..fcc7b017 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_0/00002.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_0/00002.png new file mode 100644 index 00000000..81fc3c1f Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_0/00003.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_0/00003.png new file mode 100644 index 00000000..72c21b30 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_1/00000.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_1/00000.png new file mode 100644 index 00000000..c6dfcb23 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_1/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_1/00001.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_1/00001.png new file mode 100644 index 00000000..7e85ce5e Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_1/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_1/00002.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_1/00002.png new file mode 100644 index 00000000..14f8d90a Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_1/00002.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_1/00003.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_1/00003.png new file mode 100644 index 00000000..66c411c2 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/0'_0_1/00003.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_0/00000.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_0/00000.png new file mode 100644 index 00000000..547b31a7 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_0/00001.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_0/00001.png new file mode 100644 index 00000000..010681b1 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_0/00002.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_0/00002.png new file mode 100644 index 00000000..81fc3c1f Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_0/00003.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_0/00003.png new file mode 100644 index 00000000..72c21b30 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_1/00000.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_1/00000.png new file mode 100644 index 00000000..406ba3f9 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_1/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_1/00001.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_1/00001.png new file mode 100644 index 00000000..920f7628 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_1/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_1/00002.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_1/00002.png new file mode 100644 index 00000000..87bfec45 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_1/00002.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_1/00003.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_1/00003.png new file mode 100644 index 00000000..66c411c2 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/10'_0_1/00003.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png new file mode 100644 index 00000000..547b31a7 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_0/00001.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_0/00001.png new file mode 100644 index 00000000..0af77d03 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_0/00002.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_0/00002.png new file mode 100644 index 00000000..81fc3c1f Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_0/00003.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_0/00003.png new file mode 100644 index 00000000..72c21b30 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png new file mode 100644 index 00000000..2314a10a Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png new file mode 100644 index 00000000..9bab9d85 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_1/00002.png b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_1/00002.png new file mode 100644 index 00000000..66c411c2 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/44'/1'/2'/1/42_0_1/00002.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png new file mode 100644 index 00000000..547b31a7 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00001.png b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00001.png new file mode 100644 index 00000000..ccad0840 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00002.png b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00002.png new file mode 100644 index 00000000..81fc3c1f Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00003.png b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00003.png new file mode 100644 index 00000000..72c21b30 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png new file mode 100644 index 00000000..5c305f72 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png new file mode 100644 index 00000000..2bc09cc9 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00002.png b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00002.png new file mode 100644 index 00000000..14f8d90a Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00002.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00003.png b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00003.png new file mode 100644 index 00000000..66c411c2 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00003.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png new file mode 100644 index 00000000..547b31a7 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_0/00001.png b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_0/00001.png new file mode 100644 index 00000000..efab9718 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_0/00002.png b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_0/00002.png new file mode 100644 index 00000000..81fc3c1f Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_0/00003.png b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_0/00003.png new file mode 100644 index 00000000..72c21b30 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png new file mode 100644 index 00000000..3f243a25 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png new file mode 100644 index 00000000..3b29bea6 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_1/00002.png b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_1/00002.png new file mode 100644 index 00000000..14f8d90a Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_1/00002.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_1/00003.png b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_1/00003.png new file mode 100644 index 00000000..66c411c2 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/49'/1'/1'/1/3_0_1/00003.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png b/tests/snapshots/nanos/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png new file mode 100644 index 00000000..f1ca3208 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png b/tests/snapshots/nanos/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png new file mode 100644 index 00000000..4365b484 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/84'/1'/2'/0/10_0_0/00002.png b/tests/snapshots/nanos/test_get_public_key_m/84'/1'/2'/0/10_0_0/00002.png new file mode 100644 index 00000000..34353797 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/84'/1'/2'/0/10_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/84'/1'/2'/0/10_0_0/00003.png b/tests/snapshots/nanos/test_get_public_key_m/84'/1'/2'/0/10_0_0/00003.png new file mode 100644 index 00000000..66c411c2 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/84'/1'/2'/0/10_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png new file mode 100644 index 00000000..547b31a7 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_0/00001.png b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_0/00001.png new file mode 100644 index 00000000..d583d89b Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_0/00002.png b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_0/00002.png new file mode 100644 index 00000000..81fc3c1f Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_0/00003.png b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_0/00003.png new file mode 100644 index 00000000..72c21b30 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png new file mode 100644 index 00000000..f1e9d3fc Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png new file mode 100644 index 00000000..b902d8dc Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png differ diff --git a/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_1/00002.png b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_1/00002.png new file mode 100644 index 00000000..66c411c2 Binary files /dev/null and b/tests/snapshots/nanos/test_get_public_key_m/86'/1'/4'/1/12_0_1/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_message_0_0/00000.png b/tests/snapshots/nanos/test_sign_message_0_0/00000.png new file mode 100644 index 00000000..931a29c1 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_message_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_message_0_0/00001.png b/tests/snapshots/nanos/test_sign_message_0_0/00001.png new file mode 100644 index 00000000..b57f67c8 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_message_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_message_0_0/00002.png b/tests/snapshots/nanos/test_sign_message_0_0/00002.png new file mode 100644 index 00000000..e87d669e Binary files /dev/null and b/tests/snapshots/nanos/test_sign_message_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_message_0_0/00003.png b/tests/snapshots/nanos/test_sign_message_0_0/00003.png new file mode 100644 index 00000000..66c411c2 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_message_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_sign_message_1_0/00000.png b/tests/snapshots/nanos/test_sign_message_1_0/00000.png new file mode 100644 index 00000000..ab16f62b Binary files /dev/null and b/tests/snapshots/nanos/test_sign_message_1_0/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_message_1_0/00001.png b/tests/snapshots/nanos/test_sign_message_1_0/00001.png new file mode 100644 index 00000000..25d9ea2a Binary files /dev/null and b/tests/snapshots/nanos/test_sign_message_1_0/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_message_1_1/00000.png b/tests/snapshots/nanos/test_sign_message_1_1/00000.png new file mode 100644 index 00000000..935eb862 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_message_1_1/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_message_1_1/00001.png b/tests/snapshots/nanos/test_sign_message_1_1/00001.png new file mode 100644 index 00000000..bb015fe8 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_message_1_1/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_message_1_1/00002.png b/tests/snapshots/nanos/test_sign_message_1_1/00002.png new file mode 100644 index 00000000..81d325b8 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_message_1_1/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_message_1_1/00003.png b/tests/snapshots/nanos/test_sign_message_1_1/00003.png new file mode 100644 index 00000000..f5c2d677 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_message_1_1/00003.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png new file mode 100644 index 00000000..cd4545e5 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00001.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00001.png new file mode 100644 index 00000000..826adf1f Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png new file mode 100644 index 00000000..2a3a9cfe Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00003.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00003.png new file mode 100644 index 00000000..c86e1f50 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00004.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00004.png new file mode 100644 index 00000000..1e284f08 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_0/00004.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png new file mode 100644 index 00000000..50d6e47a Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_1/00001.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_1/00001.png new file mode 100644 index 00000000..7ba086f8 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_1/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_1/00002.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_1/00002.png new file mode 100644 index 00000000..1c9156c3 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_pkh_1to1_0_1/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png new file mode 100644 index 00000000..cd4545e5 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00001.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00001.png new file mode 100644 index 00000000..e2db0cf3 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png new file mode 100644 index 00000000..67cc27f5 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00003.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00003.png new file mode 100644 index 00000000..54a169e0 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00004.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00004.png new file mode 100644 index 00000000..34ac2789 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00004.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00005.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00005.png new file mode 100644 index 00000000..1e284f08 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00005.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png new file mode 100644 index 00000000..50d6e47a Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00001.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00001.png new file mode 100644 index 00000000..8c609350 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00002.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00002.png new file mode 100644 index 00000000..1c9156c3 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png new file mode 100644 index 00000000..cd4545e5 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00001.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00001.png new file mode 100644 index 00000000..92924def Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00002.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00002.png new file mode 100644 index 00000000..50ddea3a Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00003.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00003.png new file mode 100644 index 00000000..9f3ae167 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00004.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00004.png new file mode 100644 index 00000000..1e284f08 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_0_0/00004.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png new file mode 100644 index 00000000..50d6e47a Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_1_0/00001.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_1_0/00001.png new file mode 100644 index 00000000..8bcd6e61 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_1_0/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_1_0/00002.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_1_0/00002.png new file mode 100644 index 00000000..1c9156c3 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_1_0/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png new file mode 100644 index 00000000..cd4545e5 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00001.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00001.png new file mode 100644 index 00000000..92924def Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00002.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00002.png new file mode 100644 index 00000000..50ddea3a Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00003.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00003.png new file mode 100644 index 00000000..9f3ae167 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00004.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00004.png new file mode 100644 index 00000000..1e284f08 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00004.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png new file mode 100644 index 00000000..50d6e47a Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00001.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00001.png new file mode 100644 index 00000000..8bcd6e61 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00002.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00002.png new file mode 100644 index 00000000..1c9156c3 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png new file mode 100644 index 00000000..a6398249 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00001.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00001.png new file mode 100644 index 00000000..6c697ed8 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png new file mode 100644 index 00000000..cf122072 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png new file mode 100644 index 00000000..a0201ce2 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00004.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00004.png new file mode 100644 index 00000000..f41b1fcf Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00004.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00005.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00005.png new file mode 100644 index 00000000..c6bf2b20 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00005.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00006.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00006.png new file mode 100644 index 00000000..1e284f08 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_0/00006.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png new file mode 100644 index 00000000..50d6e47a Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_1/00001.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_1/00001.png new file mode 100644 index 00000000..82d0ff39 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_1/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_1/00002.png b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_1/00002.png new file mode 100644 index 00000000..1c9156c3 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_psbt_singlesig_wpkh_2to2_0_1/00002.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_0/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_0/00000.png new file mode 100644 index 00000000..6ebf2582 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_0/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_0/00001.png new file mode 100644 index 00000000..ad8a5112 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_0/00002.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_0/00002.png new file mode 100644 index 00000000..2b51f30c Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_0/00003.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_0/00003.png new file mode 100644 index 00000000..86868b1b Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_0/00003.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_1/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_1/00000.png new file mode 100644 index 00000000..adbbfe3e Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_1/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_1/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_1/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/0'_0_1/00001.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_0/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_0/00000.png new file mode 100644 index 00000000..6ebf2582 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_0/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_0/00001.png new file mode 100644 index 00000000..a3fb3f4b Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_0/00002.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_0/00002.png new file mode 100644 index 00000000..2b51f30c Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_0/00003.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_0/00003.png new file mode 100644 index 00000000..86868b1b Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_0/00003.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_1/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_1/00000.png new file mode 100644 index 00000000..4d77a5f3 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_1/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_1/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_1/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/10'_0_1/00001.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png new file mode 100644 index 00000000..6ebf2582 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_0/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_0/00001.png new file mode 100644 index 00000000..1b1aca93 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_0/00002.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_0/00002.png new file mode 100644 index 00000000..2b51f30c Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_0/00003.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_0/00003.png new file mode 100644 index 00000000..86868b1b Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_0/00003.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png new file mode 100644 index 00000000..9f852fe5 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png new file mode 100644 index 00000000..6ebf2582 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00001.png new file mode 100644 index 00000000..f8dbc8d3 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00002.png b/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00002.png new file mode 100644 index 00000000..2b51f30c Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00003.png b/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00003.png new file mode 100644 index 00000000..86868b1b Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00003.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png new file mode 100644 index 00000000..7ff89fe6 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png new file mode 100644 index 00000000..6ebf2582 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_0/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_0/00001.png new file mode 100644 index 00000000..6ad64a52 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_0/00002.png b/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_0/00002.png new file mode 100644 index 00000000..2b51f30c Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_0/00003.png b/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_0/00003.png new file mode 100644 index 00000000..86868b1b Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_0/00003.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png new file mode 100644 index 00000000..bcb6eaba Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png new file mode 100644 index 00000000..2276fc52 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png new file mode 100644 index 00000000..6ebf2582 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_0/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_0/00001.png new file mode 100644 index 00000000..2cef7138 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_0/00002.png b/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_0/00002.png new file mode 100644 index 00000000..2b51f30c Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_0/00003.png b/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_0/00003.png new file mode 100644 index 00000000..86868b1b Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_0/00003.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png b/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png new file mode 100644 index 00000000..596276aa Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png differ diff --git a/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png b/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanosp/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_0_0/00000.png b/tests/snapshots/nanosp/test_sign_message_0_0/00000.png new file mode 100644 index 00000000..264ba440 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_message_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_0_0/00001.png b/tests/snapshots/nanosp/test_sign_message_0_0/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_message_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_1_0/00000.png b/tests/snapshots/nanosp/test_sign_message_1_0/00000.png new file mode 100644 index 00000000..1b271542 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_message_1_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_1_0/00001.png b/tests/snapshots/nanosp/test_sign_message_1_0/00001.png new file mode 100644 index 00000000..4ea64dab Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_message_1_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_1_1/00000.png b/tests/snapshots/nanosp/test_sign_message_1_1/00000.png new file mode 100644 index 00000000..1285e85e Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_message_1_1/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_message_1_1/00001.png b/tests/snapshots/nanosp/test_sign_message_1_1/00001.png new file mode 100644 index 00000000..e7ffedd9 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_message_1_1/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png new file mode 100644 index 00000000..73cd118f Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00001.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00001.png new file mode 100644 index 00000000..05ccaac7 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png new file mode 100644 index 00000000..9d8efd1d Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00003.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00003.png new file mode 100644 index 00000000..0a22ed9c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_0/00003.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png new file mode 100644 index 00000000..ffdae22c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_1/00001.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_1/00001.png new file mode 100644 index 00000000..cc9e51b5 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_1/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_1/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_1/00002.png new file mode 100644 index 00000000..570ce28d Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_pkh_1to1_0_1/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png new file mode 100644 index 00000000..73cd118f Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00001.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00001.png new file mode 100644 index 00000000..76042530 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png new file mode 100644 index 00000000..fda030d5 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00003.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00003.png new file mode 100644 index 00000000..0a22ed9c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00003.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png new file mode 100644 index 00000000..ffdae22c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00001.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00001.png new file mode 100644 index 00000000..0a11ccdf Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00002.png new file mode 100644 index 00000000..570ce28d Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png new file mode 100644 index 00000000..73cd118f Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_0_0/00001.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_0_0/00001.png new file mode 100644 index 00000000..073b4ff5 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_0_0/00002.png new file mode 100644 index 00000000..dcf25e82 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_0_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_0_0/00003.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_0_0/00003.png new file mode 100644 index 00000000..0a22ed9c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_0_0/00003.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png new file mode 100644 index 00000000..ffdae22c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_1_0/00001.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_1_0/00001.png new file mode 100644 index 00000000..18069811 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_1_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_1_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_1_0/00002.png new file mode 100644 index 00000000..570ce28d Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_1_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png new file mode 100644 index 00000000..73cd118f Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00001.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00001.png new file mode 100644 index 00000000..073b4ff5 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00002.png new file mode 100644 index 00000000..dcf25e82 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00003.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00003.png new file mode 100644 index 00000000..0a22ed9c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00003.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png new file mode 100644 index 00000000..ffdae22c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00001.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00001.png new file mode 100644 index 00000000..18069811 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00002.png new file mode 100644 index 00000000..570ce28d Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png new file mode 100644 index 00000000..b0e1548f Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00001.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00001.png new file mode 100644 index 00000000..700453f7 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png new file mode 100644 index 00000000..6c57d4dd Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png new file mode 100644 index 00000000..562b8c3a Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00004.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00004.png new file mode 100644 index 00000000..0a22ed9c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_0/00004.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png new file mode 100644 index 00000000..ffdae22c Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_1/00001.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_1/00001.png new file mode 100644 index 00000000..53d79726 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_1/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_1/00002.png b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_1/00002.png new file mode 100644 index 00000000..570ce28d Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_psbt_singlesig_wpkh_2to2_0_1/00002.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_0/00000.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_0/00000.png new file mode 100644 index 00000000..6ebf2582 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_0/00001.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_0/00001.png new file mode 100644 index 00000000..ad8a5112 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_0/00002.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_0/00002.png new file mode 100644 index 00000000..2b51f30c Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_0/00002.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_0/00003.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_0/00003.png new file mode 100644 index 00000000..86868b1b Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_0/00003.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_1/00000.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_1/00000.png new file mode 100644 index 00000000..adbbfe3e Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_1/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_1/00001.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_1/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/0'_0_1/00001.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_0/00000.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_0/00000.png new file mode 100644 index 00000000..6ebf2582 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_0/00001.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_0/00001.png new file mode 100644 index 00000000..a3fb3f4b Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_0/00002.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_0/00002.png new file mode 100644 index 00000000..2b51f30c Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_0/00002.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_0/00003.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_0/00003.png new file mode 100644 index 00000000..86868b1b Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_0/00003.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_1/00000.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_1/00000.png new file mode 100644 index 00000000..4d77a5f3 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_1/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_1/00001.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_1/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/10'_0_1/00001.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png new file mode 100644 index 00000000..6ebf2582 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_0/00001.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_0/00001.png new file mode 100644 index 00000000..1b1aca93 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_0/00002.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_0/00002.png new file mode 100644 index 00000000..2b51f30c Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_0/00002.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_0/00003.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_0/00003.png new file mode 100644 index 00000000..86868b1b Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_0/00003.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png new file mode 100644 index 00000000..9f852fe5 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png b/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png new file mode 100644 index 00000000..6ebf2582 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00001.png b/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00001.png new file mode 100644 index 00000000..f8dbc8d3 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00002.png b/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00002.png new file mode 100644 index 00000000..2b51f30c Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00002.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00003.png b/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00003.png new file mode 100644 index 00000000..86868b1b Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00003.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png b/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png new file mode 100644 index 00000000..7ff89fe6 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png b/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png b/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png new file mode 100644 index 00000000..6ebf2582 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_0/00001.png b/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_0/00001.png new file mode 100644 index 00000000..6ad64a52 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_0/00002.png b/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_0/00002.png new file mode 100644 index 00000000..2b51f30c Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_0/00002.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_0/00003.png b/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_0/00003.png new file mode 100644 index 00000000..86868b1b Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_0/00003.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png b/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png new file mode 100644 index 00000000..bcb6eaba Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png b/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png b/tests/snapshots/nanox/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png new file mode 100644 index 00000000..2276fc52 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png b/tests/snapshots/nanox/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png b/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png new file mode 100644 index 00000000..6ebf2582 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_0/00001.png b/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_0/00001.png new file mode 100644 index 00000000..2cef7138 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_0/00002.png b/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_0/00002.png new file mode 100644 index 00000000..2b51f30c Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_0/00002.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_0/00003.png b/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_0/00003.png new file mode 100644 index 00000000..86868b1b Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_0/00003.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png b/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png new file mode 100644 index 00000000..596276aa Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png b/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanox/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_message_0_0/00000.png b/tests/snapshots/nanox/test_sign_message_0_0/00000.png new file mode 100644 index 00000000..264ba440 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_message_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_message_0_0/00001.png b/tests/snapshots/nanox/test_sign_message_0_0/00001.png new file mode 100644 index 00000000..53ae6519 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_message_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_message_1_0/00000.png b/tests/snapshots/nanox/test_sign_message_1_0/00000.png new file mode 100644 index 00000000..1b271542 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_message_1_0/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_message_1_0/00001.png b/tests/snapshots/nanox/test_sign_message_1_0/00001.png new file mode 100644 index 00000000..4ea64dab Binary files /dev/null and b/tests/snapshots/nanox/test_sign_message_1_0/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_message_1_1/00000.png b/tests/snapshots/nanox/test_sign_message_1_1/00000.png new file mode 100644 index 00000000..1285e85e Binary files /dev/null and b/tests/snapshots/nanox/test_sign_message_1_1/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_message_1_1/00001.png b/tests/snapshots/nanox/test_sign_message_1_1/00001.png new file mode 100644 index 00000000..e7ffedd9 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_message_1_1/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png new file mode 100644 index 00000000..73cd118f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00001.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00001.png new file mode 100644 index 00000000..05ccaac7 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png new file mode 100644 index 00000000..9d8efd1d Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00003.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00003.png new file mode 100644 index 00000000..0a22ed9c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_0/00003.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png new file mode 100644 index 00000000..ffdae22c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_1/00001.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_1/00001.png new file mode 100644 index 00000000..cc9e51b5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_1/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_1/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_1/00002.png new file mode 100644 index 00000000..570ce28d Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_pkh_1to1_0_1/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png new file mode 100644 index 00000000..73cd118f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00001.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00001.png new file mode 100644 index 00000000..76042530 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png new file mode 100644 index 00000000..fda030d5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00003.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00003.png new file mode 100644 index 00000000..0a22ed9c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00003.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png new file mode 100644 index 00000000..ffdae22c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00001.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00001.png new file mode 100644 index 00000000..0a11ccdf Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00002.png new file mode 100644 index 00000000..570ce28d Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png new file mode 100644 index 00000000..73cd118f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_0_0/00001.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_0_0/00001.png new file mode 100644 index 00000000..073b4ff5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_0_0/00002.png new file mode 100644 index 00000000..dcf25e82 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_0_0/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_0_0/00003.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_0_0/00003.png new file mode 100644 index 00000000..0a22ed9c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_0_0/00003.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png new file mode 100644 index 00000000..ffdae22c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_1_0/00001.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_1_0/00001.png new file mode 100644 index 00000000..18069811 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_1_0/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_1_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_1_0/00002.png new file mode 100644 index 00000000..570ce28d Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_1_0/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png new file mode 100644 index 00000000..73cd118f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00001.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00001.png new file mode 100644 index 00000000..073b4ff5 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00002.png new file mode 100644 index 00000000..dcf25e82 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00003.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00003.png new file mode 100644 index 00000000..0a22ed9c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00003.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png new file mode 100644 index 00000000..ffdae22c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00001.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00001.png new file mode 100644 index 00000000..18069811 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00002.png new file mode 100644 index 00000000..570ce28d Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png new file mode 100644 index 00000000..b0e1548f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00001.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00001.png new file mode 100644 index 00000000..700453f7 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png new file mode 100644 index 00000000..6c57d4dd Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png new file mode 100644 index 00000000..562b8c3a Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00004.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00004.png new file mode 100644 index 00000000..0a22ed9c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_0/00004.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png new file mode 100644 index 00000000..ffdae22c Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_1/00001.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_1/00001.png new file mode 100644 index 00000000..53d79726 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_1/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_1/00002.png b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_1/00002.png new file mode 100644 index 00000000..570ce28d Binary files /dev/null and b/tests/snapshots/nanox/test_sign_psbt_singlesig_wpkh_2to2_0_1/00002.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_0/00000.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_0/00000.png new file mode 100644 index 00000000..538f3218 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_0/00001.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_0/00001.png new file mode 100644 index 00000000..538f3218 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_1/00000.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_1/00000.png new file mode 100644 index 00000000..55a58f0d Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_1/00001.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_1/00001.png new file mode 100644 index 00000000..24a03524 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_1/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_1/00002.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_1/00002.png new file mode 100644 index 00000000..dac62118 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_1/00002.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_2/00000.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_2/00000.png new file mode 100644 index 00000000..3f906b2b Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/0'_0_2/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_0/00000.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_0/00000.png new file mode 100644 index 00000000..538f3218 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_0/00001.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_0/00001.png new file mode 100644 index 00000000..538f3218 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_1/00000.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_1/00000.png new file mode 100644 index 00000000..55a58f0d Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_1/00001.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_1/00001.png new file mode 100644 index 00000000..c6220afd Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_1/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_1/00002.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_1/00002.png new file mode 100644 index 00000000..7c57c16e Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_1/00002.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_2/00000.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_2/00000.png new file mode 100644 index 00000000..3f906b2b Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/10'_0_2/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png new file mode 100644 index 00000000..538f3218 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_0/00001.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_0/00001.png new file mode 100644 index 00000000..538f3218 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png new file mode 100644 index 00000000..55a58f0d Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png new file mode 100644 index 00000000..e84bf60f Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_1/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_1/00002.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_1/00002.png new file mode 100644 index 00000000..878411cf Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_1/00002.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_2/00000.png b/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_2/00000.png new file mode 100644 index 00000000..3f906b2b Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/44'/1'/2'/1/42_0_2/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png b/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png new file mode 100644 index 00000000..538f3218 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00001.png b/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00001.png new file mode 100644 index 00000000..538f3218 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png b/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png new file mode 100644 index 00000000..55a58f0d Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png b/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png new file mode 100644 index 00000000..aa4adfea Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00002.png b/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00002.png new file mode 100644 index 00000000..e06d6335 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_1/00002.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_2/00000.png b/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_2/00000.png new file mode 100644 index 00000000..3f906b2b Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/48'/1'/4'/1'/0/7_0_2/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png b/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png new file mode 100644 index 00000000..538f3218 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_0/00001.png b/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_0/00001.png new file mode 100644 index 00000000..538f3218 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png b/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png new file mode 100644 index 00000000..55a58f0d Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png b/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png new file mode 100644 index 00000000..11533ffc Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_1/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_1/00002.png b/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_1/00002.png new file mode 100644 index 00000000..5b557219 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_1/00002.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_2/00000.png b/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_2/00000.png new file mode 100644 index 00000000..3f906b2b Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/49'/1'/1'/1/3_0_2/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png b/tests/snapshots/stax/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png new file mode 100644 index 00000000..0d6d65ba Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/84'/1'/2'/0/10_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png b/tests/snapshots/stax/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png new file mode 100644 index 00000000..ed29648d Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/84'/1'/2'/0/10_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/84'/1'/2'/0/10_0_1/00000.png b/tests/snapshots/stax/test_get_public_key_m/84'/1'/2'/0/10_0_1/00000.png new file mode 100644 index 00000000..3f906b2b Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/84'/1'/2'/0/10_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png b/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png new file mode 100644 index 00000000..538f3218 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_0/00001.png b/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_0/00001.png new file mode 100644 index 00000000..538f3218 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png b/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png new file mode 100644 index 00000000..55a58f0d Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png b/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png new file mode 100644 index 00000000..4786788f Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_1/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_1/00002.png b/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_1/00002.png new file mode 100644 index 00000000..5d9f15f7 Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_1/00002.png differ diff --git a/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_2/00000.png b/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_2/00000.png new file mode 100644 index 00000000..3f906b2b Binary files /dev/null and b/tests/snapshots/stax/test_get_public_key_m/86'/1'/4'/1/12_0_2/00000.png differ diff --git a/tests/snapshots/stax/test_sign_message_0_0/00000.png b/tests/snapshots/stax/test_sign_message_0_0/00000.png new file mode 100644 index 00000000..0d6d65ba Binary files /dev/null and b/tests/snapshots/stax/test_sign_message_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_sign_message_0_0/00001.png b/tests/snapshots/stax/test_sign_message_0_0/00001.png new file mode 100644 index 00000000..475185ed Binary files /dev/null and b/tests/snapshots/stax/test_sign_message_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_sign_message_0_1/00000.png b/tests/snapshots/stax/test_sign_message_0_1/00000.png new file mode 100644 index 00000000..3f906b2b Binary files /dev/null and b/tests/snapshots/stax/test_sign_message_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_sign_message_1_0/00000.png b/tests/snapshots/stax/test_sign_message_1_0/00000.png new file mode 100644 index 00000000..a78662e3 Binary files /dev/null and b/tests/snapshots/stax/test_sign_message_1_0/00000.png differ diff --git a/tests/snapshots/stax/test_sign_message_1_0/00001.png b/tests/snapshots/stax/test_sign_message_1_0/00001.png new file mode 100644 index 00000000..a08f0e8b Binary files /dev/null and b/tests/snapshots/stax/test_sign_message_1_0/00001.png differ diff --git a/tests/snapshots/stax/test_sign_message_1_0/00002.png b/tests/snapshots/stax/test_sign_message_1_0/00002.png new file mode 100644 index 00000000..97ecbfea Binary files /dev/null and b/tests/snapshots/stax/test_sign_message_1_0/00002.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png new file mode 100644 index 00000000..495e4e67 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_0/00001.png b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_0/00001.png new file mode 100644 index 00000000..467b9403 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png new file mode 100644 index 00000000..3516b6f0 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_0/00002.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_0/00003.png b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_0/00003.png new file mode 100644 index 00000000..e42a0293 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_0/00003.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png new file mode 100644 index 00000000..1bcae3c7 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_2/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_2/00000.png new file mode 100644 index 00000000..3516b6f0 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_2/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_3/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_3/00000.png new file mode 100644 index 00000000..945e95e9 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_pkh_1to1_0_3/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png new file mode 100644 index 00000000..495e4e67 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00001.png b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00001.png new file mode 100644 index 00000000..d8ecabfc Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png new file mode 100644 index 00000000..ddae32d9 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_0_0/00002.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_0_1/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_0_1/00000.png new file mode 100644 index 00000000..bfdf581d Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png new file mode 100644 index 00000000..400d3352 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00001.png b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00001.png new file mode 100644 index 00000000..e42a0293 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_1_0/00001.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_1_1/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_1_1/00000.png new file mode 100644 index 00000000..945e95e9 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_sh_wpkh_1to2_1_1/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png new file mode 100644 index 00000000..495e4e67 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_0_0/00001.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_0_0/00001.png new file mode 100644 index 00000000..b020179e Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_0_0/00002.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_0_0/00002.png new file mode 100644 index 00000000..ddae32d9 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_0_0/00002.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_0_1/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_0_1/00000.png new file mode 100644 index 00000000..74918453 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png new file mode 100644 index 00000000..ed9bb0bd Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_1_0/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_1_0/00001.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_1_0/00001.png new file mode 100644 index 00000000..e42a0293 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_1_0/00001.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_1_1/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_1_1/00000.png new file mode 100644 index 00000000..945e95e9 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_1_1/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png new file mode 100644 index 00000000..495e4e67 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00001.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00001.png new file mode 100644 index 00000000..b020179e Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00002.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00002.png new file mode 100644 index 00000000..ddae32d9 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_0_0/00002.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_0_1/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_0_1/00000.png new file mode 100644 index 00000000..74918453 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png new file mode 100644 index 00000000..ed9bb0bd Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00001.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00001.png new file mode 100644 index 00000000..e42a0293 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_1_0/00001.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_1_1/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_1_1/00000.png new file mode 100644 index 00000000..945e95e9 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_1to2_2_1_1/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png new file mode 100644 index 00000000..495e4e67 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_0/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_0/00001.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_0/00001.png new file mode 100644 index 00000000..402a5312 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_0/00001.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png new file mode 100644 index 00000000..8aadd0e2 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_0/00002.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png new file mode 100644 index 00000000..e42a0293 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_0/00003.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png new file mode 100644 index 00000000..1ee94503 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_1/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_2/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_2/00000.png new file mode 100644 index 00000000..8aadd0e2 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_2/00000.png differ diff --git a/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_3/00000.png b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_3/00000.png new file mode 100644 index 00000000..945e95e9 Binary files /dev/null and b/tests/snapshots/stax/test_sign_psbt_singlesig_wpkh_2to2_0_3/00000.png differ diff --git a/tests/test_get_coin_version.py b/tests/test_get_coin_version.py deleted file mode 100644 index e475a9a5..00000000 --- a/tests/test_get_coin_version.py +++ /dev/null @@ -1,9 +0,0 @@ -def test_get_coin_version(cmd): - (p2pkh_prefix, p2sh_prefix, coin_family, coin_name, coin_ticker) = cmd.get_coin_version() - - # Bitcoin app: (0x00, 0x05, 0x01, "Bitcoin", "BTC") - assert (p2pkh_prefix, - p2sh_prefix, - coin_family, - coin_name, - coin_ticker) == (0x6F, 0xC4, 0x01, "Bitcoin", "TEST") diff --git a/tests/test_get_pubkey.py b/tests/test_get_pubkey.py index 1dfa6939..40c82777 100644 --- a/tests/test_get_pubkey.py +++ b/tests/test_get_pubkey.py @@ -1,42 +1,65 @@ -from bitcoin_client.bitcoin_base_cmd import AddrType - - -def test_get_public_key(cmd): - # legacy address - pub_key, addr, bip32_chain_code = cmd.get_public_key( - addr_type=AddrType.Legacy, - bip32_path="m/44'/1'/0'/0/0", - display=False - ) - - assert pub_key == bytes.fromhex("04" - "ee8608207e21028426f69e76447d7e3d5e077049f5e683c3136c2314762a4718" - "b45f5224b05ebbad09f43594b7bd8dc0eff4519a07cbab37ecc66e0001ab959a") - assert addr == "mz5vLWdM1wHVGSmXUkhKVvZbJ2g4epMXSm" - assert bip32_chain_code == bytes.fromhex("0322c8f681e7274e767cee09b8e41770e6d2afd504fd5f85dfaab3e1ff6cdfcc") - - # P2SH-P2WPKH address - pub_key, addr, bip32_chain_code = cmd.get_public_key( - addr_type=AddrType.P2SH_P2WPKH, - bip32_path="m/49'/1'/0'/0/0", - display=False - ) - - assert pub_key == bytes.fromhex("04" - "a80f007194d53d37f6f99539f635390588c4e1c328b098295f61af40d60cb28a" - "7b5649e8121c89148fbab7d693108654685b4e939d9c1bc55a71b43f389929fe") - assert addr == "2MyHkbusvLomaarGYMqyq7q9pSBYJRwWcsw" - assert bip32_chain_code == bytes.fromhex("dc699bc018541f456df1ebd4dea516a633a6260e0a701eba143449adc2ca63f3") - - # bech32 address - pub_key, addr, bip32_chain_code = cmd.get_public_key( - addr_type=AddrType.BECH32, - bip32_path="m/84'/1'/0'/0/0", - display=False - ) - - assert pub_key == bytes.fromhex("04" - "7cb75d34b005c4eb9f62bbf2c457d7638e813e757efcec8fa68677d950b63662" - "648e4f638cabc4e4383fa3fe8348456e46fa56742dcf500a5b50dc1d403492f0") - assert addr == "tb1qzdr7s2sr0dwmkwx033r4nujzk86u0cy6fmzfjk" - assert bip32_chain_code == bytes.fromhex("efd851020a3827ba0d3fd4375910f0ed55dbe8c5d740b37559e993b1d623a956") +from ragger.navigator import Navigator +from ragger.firmware import Firmware +from ragger_bitcoin import RaggerClient +from ragger_bitcoin.ragger_instructions import Instructions +from ragger.navigator import NavInsID + + +def pubkey_instruction_approve(model: Firmware) -> Instructions: + instructions = Instructions(model) + + if model.name.startswith("nano"): + instructions.new_request("Approve") + else: + instructions.address_confirm() + instructions.same_request("Address", NavInsID.USE_CASE_REVIEW_TAP, + NavInsID.USE_CASE_STATUS_DISMISS) + return instructions + + +def pubkey_instruction_warning_approve(model: Firmware) -> Instructions: + instructions = Instructions(model) + + if model.name.startswith("nano"): + instructions.new_request("Approve") + instructions.same_request("Approve") + else: + instructions.new_request("Unusual", NavInsID.USE_CASE_CHOICE_CONFIRM, + NavInsID.USE_CASE_CHOICE_CONFIRM) + instructions.same_request("Confirm", NavInsID.USE_CASE_ADDRESS_CONFIRMATION_TAP, + NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM) + instructions.same_request("Address", NavInsID.USE_CASE_REVIEW_TAP, + NavInsID.USE_CASE_STATUS_DISMISS) + return instructions + + +def test_get_public_key(navigator: Navigator, firmware: Firmware, + client: RaggerClient, test_name: str): + testcases = { + "m/84'/1'/2'/0/10": + "tpubDG9YpSUwScWJBBSrhnAT47NcT4NZGLcY18cpkaiWHnkUCi19EtCh8Heeox268NaFF6o56nVeSXuTyK6jpzTvV1h68Kr3edA8AZp27MiLUNt"} + for path, pubkey in testcases.items(): + assert pubkey == client.get_extended_pubkey( + path=path, + display=True, + navigator=navigator, + instructions=pubkey_instruction_approve(firmware), + testname=f"{test_name}_{path}" + ) + testcases = { + "m/44'/1'/0'": "tpubDCwYjpDhUdPGP5rS3wgNg13mTrrjBuG8V9VpWbyptX6TRPbNoZVXsoVUSkCjmQ8jJycjuDKBb9eataSymXakTTaGifxR6kmVsfFehH1ZgJT", + "m/44'/1'/10'": "tpubDCwYjpDhUdPGp21gSpVay2QPJVh6WNySWMXPhbcu1DsxH31dF7mY18oibbu5RxCLBc1Szerjscuc3D5HyvfYqfRvc9mesewnFqGmPjney4d", + "m/44'/1'/2'/1/42": "tpubDGF9YgHKv6qh777rcqVhpmDrbNzgophJM9ec7nHiSfrbss7fVBXoqhmZfohmJSvhNakDHAspPHjVVNL657tLbmTXvSeGev2vj5kzjMaeupT", + "m/48'/1'/4'/1'/0/7": "tpubDK8WPFx4WJo1R9mEL7Wq325wBiXvkAe8ipgb9Q1QBDTDUD2YeCfutWtzY88NPokZqJyRPKHLGwTNLT7jBG59aC6VH8q47LDGQitPB6tX2d7", + "m/49'/1'/1'/1/3": "tpubDGnetmJDCL18TyaaoyRAYbkSE9wbHktSdTS4mfsR6inC8c2r6TjdBt3wkqEQhHYPtXpa46xpxDaCXU2PRNUGVvDzAHPG6hHRavYbwAGfnFr", + "m/86'/1'/4'/1/12": "tpubDHTZ815MvTaRmo6Qg1rnU6TEU4ZkWyA56jA1UgpmMcBGomnSsyo34EZLoctzZY9MTJ6j7bhccceUeXZZLxZj5vgkVMYfcZ7DNPsyRdFpS3f", + } + + for path, pubkey in testcases.items(): + assert pubkey == client.get_extended_pubkey( + path=path, + display=True, + navigator=navigator, + instructions=pubkey_instruction_warning_approve(firmware), + testname=f"{test_name}_{path}" + ) diff --git a/tests/test_get_random.py b/tests/test_get_random.py deleted file mode 100644 index 91bb8f9f..00000000 --- a/tests/test_get_random.py +++ /dev/null @@ -1,15 +0,0 @@ -import pytest - -from bitcoin_client.exception import IncorrectLengthError - - -def test_random(cmd): - r: bytes = cmd.get_random(n=5) - assert len(r) == 5 - - r = cmd.get_random(n=32) - assert len(r) == 32 - - # max lenght is 248! - with pytest.raises(IncorrectLengthError): - cmd.get_random(n=249) diff --git a/tests/test_get_trusted_inputs.py b/tests/test_get_trusted_inputs.py deleted file mode 100644 index 7c2ff475..00000000 --- a/tests/test_get_trusted_inputs.py +++ /dev/null @@ -1,174 +0,0 @@ -from io import BytesIO - -from bitcoin_client.hwi.serialization import CTransaction -from bitcoin_client.utils import deser_trusted_input - - -def test_get_trusted_inputs(cmd): - raw_tx: bytes = bytes.fromhex( - # Version no (4 bytes little endian) - "02000000" - # In-counter (varint 1-9 bytes) - "02" - # [1] Previous Transaction hash (32 bytes) - "40d1ae8a596b34f48b303e853c56f8f6f54c483babc16978eb182e2154d5f2ab" - # [1] Previous Txout-index (4 bytes little endian) - "00000000" - # [1] Txin-script length (varint 1-9 bytes) - "6b" - # [1] scriptSig (0x6b = 107 bytes) - "48" - "3045" - "0221" - # r - "00ca145f0694ffaedd333d3724ce3f4e44aabc0ed5128113660d11f917b3c52053" - "0220" - # s - "7bec7c66328bace92bd525f385a9aa1261b83e0f92310ea1850488b40bd25a5d" - # sighash - "01" - "21" - # compressed public key - "032006c64cdd0485e068c1e22ba0fa267ca02ca0c2b34cdc6dd08cba23796b6ee7" - # [1] sequence_no (4 bytes little endian) - "fdffffff" - # [2] Previous Transaction hash (32 bytes) - "40d1ae8a596b34f48b303e853c56f8f6f54c483babc16978eb182e2154d5f2ab" - # [2] Previous Txout-index (4 bytes little endian) - "01000000" - # [2] Txin-script length (varint 1-9 bytes) - "6a" - # [2] scriptSig (0x6a = 106 bytes) - "47" - "3044" - "0220" - # r - "2a5d54a1635a7a0ae22cef76d8144ca2a1c3c035c87e7cd0280ab43d34510906" - "0220" - # s - "0c7e07e384b3620ccd2f97b5c08f5893357c653edc2b8570f099d9ff34a0285c" - "01" - "21" - # compressed public key - "02d82f3fa29d38297db8e1879010c27f27533439c868b1cc6af27dd3d33b243dec" - # [2] sequence_no (4 bytes little endian) - "fdffffff" - # Out-counter (varint 1-9 bytes) - "01" - # [1] Value (8 bytes little endian) - "d7ee7c0100000000" # 0.24964823 BTC - # [1] Txout-script length (varint 1-9 bytes) - "19" - # [1] scriptPubKey (0x19 = 25 bytes) - "76a914" - "0ea263ff8b0da6e8d187de76f6a362beadab7811" - "88ac" - # lock_time (4 bytes little endian) - "e3691900" - ) - - bip141_raw_tx: bytes = bytes.fromhex( - # Version no (4 bytes little endian) - "02000000" - # marker (1 byte) + flag (1 byte) - "0001" - # In-counter (varint 1-9 bytes) - "02" - # [1] Previous Transaction hash (32 bytes) - "e7576f53b5d92f9880b125d0622782fef40b0121eb4555c9d3a7be54e635cd6e" - # [1] Previous Txout-index (4 bytes little endian) - "00000000" - # [1] Txin-script length (varint 1-9 bytes) - "17" - # [1] scriptSig (0x17 = 23 bytes) - "160014" - "4c9fca3fd23ae5cc1f0dfe46b446da611219c020" # hash160(pubkey) - # [1] sequence_no (4 bytes little endian) - "fdffffff" - # [2] Previous Transaction hash (32 bytes) - "4ba91d8e1cedbfecdceda7f3432f618a2f0e122c66a63fe0c53a14de6305e5dc" - # [2] Previous Txout-index (4 bytes little endian) - "01000000" - # [2] Txin-script length (varint 1-9 bytes) - "17" - # [2] scriptSig (0x17 = 23 bytes) - "160014" - "92a9159a0ae40a748c18bd486ea13da85422450c" # hash160(pubkey) - # [2] sequence_no (4 bytes little endian) - "fdffffff" - # Out-counter (varint 1-9 bytes) - "02" - # [1] Value (8 bytes little endian) - "7f19060000000000" - # [1] Txout-script length (varint 1-9 bytes) - "17" - # [1] scriptPubKey (0x17 = 23 bytes) - "a9141a56dea1ff8a3f633916560fed5942400d17080b87" - # [2] Value (8 bytes little endian) - "60ae0a0000000000" - # [2] Txout-script length (varint 1-9 bytes) - "17" - # [2] scriptPubKey (0x17 = 23 bytes) - "a9147c28b075f506d829e2e2bacf897c1b5b0d309c1a87" - # Witnesses - "02" # number of items to push on the stack - "48" # length of 1st stack item - # 1st item - "3045" - "0221" - # r - "00c791ff9a5886903fbd3c1289f281e1d5a3e330f1558ea5df725bcd780b285677" - "0220" - # s - "2d76349a78585ea66df6eef5ab48a0348cc337994a1d6357a6e4e4328a343f6d" - "01" - # 2nd item - "21" # length of 2nd stack item - # compressed public key - "02623ed09f8c192938f7a638fbdd5dd7c297f86e41be8d7dff4f1c904f0685f227" - "02" # number of items to push on the stack - # 1st item - "48" # length of 1st stack item - "3045" - "0221" - # r - "008f2f017f5fa4fdd7dcfe41c83f4a71a726626cdb490d652edcb408b9a4638b7a" - "0220" - # s - "439c15a7f7a03f2876dec5392f2247437b57b227fea294f4019d06462f938b53" - "01" - # 2nd item - "21" # length of 2nd stack item - # compressed public key - "0347e9143aa6457c72a48d85b5065edc40d3a49f319d54fc4979dc3b95de949a41" - # lock_time (4 bytes little endian) - "d7681900" - ) - tx: CTransaction - bip141_tx: CTransaction - output_index: int - trusted_input: bytes - - tx = CTransaction() - tx.deserialize(BytesIO(raw_tx)) - tx.calc_sha256() - - output_index = 0 - trusted_input = cmd.get_trusted_input(utxo=tx, output_index=output_index) - - _, _, _, prev_txid, out_index, amount, _ = deser_trusted_input(trusted_input) - assert out_index == output_index - assert prev_txid == tx.sha256.to_bytes(32, byteorder="little") - assert amount == tx.vout[out_index].nValue - - bip141_tx = CTransaction() - bip141_tx.deserialize(BytesIO(bip141_raw_tx)) - bip141_tx.calc_sha256() - - output_index = 1 - trusted_input = cmd.get_trusted_input(utxo=bip141_tx, output_index=output_index) - - _, _, _, prev_txid, out_index, amount, _ = deser_trusted_input(trusted_input) - assert out_index == output_index - assert prev_txid == bip141_tx.sha256.to_bytes(32, byteorder="little") - assert amount == bip141_tx.vout[out_index].nValue diff --git a/tests/test_sign.py b/tests/test_sign.py index 4fede15c..1a58f3b9 100644 --- a/tests/test_sign.py +++ b/tests/test_sign.py @@ -1,89 +1,171 @@ -from hashlib import sha256 -import json from pathlib import Path -from typing import Tuple, List, Dict, Any -import pytest - -from ecdsa.curves import SECP256k1 -from ecdsa.keys import VerifyingKey -from ecdsa.util import sigdecode_der - -from bitcoin_client.hwi.serialization import CTransaction -from bitcoin_client.exception import ConditionOfUseNotSatisfiedError -from utils import automation - - -def sign_from_json(cmd, filepath: Path): - tx_dct: Dict[str, Any] = json.load(open(filepath, "r")) - - raw_utxos: List[Tuple[bytes, int]] = [ - (bytes.fromhex(utxo_dct["raw"]), output_index) - for utxo_dct in tx_dct["utxos"] - for output_index in utxo_dct["output_indexes"] - ] - to_address: str = tx_dct["to"] - to_amount: int = tx_dct["amount"] - fees: int = tx_dct["fees"] - - sigs = cmd.sign_new_tx(address=to_address, - amount=to_amount, - fees=fees, - change_path=tx_dct["change_path"], - sign_paths=tx_dct["sign_paths"], - raw_utxos=raw_utxos, - lock_time=tx_dct["lock_time"]) - - expected_tx = CTransaction.from_bytes(bytes.fromhex(tx_dct["raw"])) - witnesses = expected_tx.wit.vtxinwit - for witness, (tx_hash_digest, sign_pub_key, (v, der_sig)) in zip(witnesses, sigs): - expected_der_sig, expected_pubkey = witness.scriptWitness.stack - assert expected_pubkey == sign_pub_key - assert expected_der_sig == der_sig - pk: VerifyingKey = VerifyingKey.from_string( - sign_pub_key, - curve=SECP256k1, - hashfunc=sha256 + +from ledger_bitcoin import WalletPolicy, PartialSignature + +from ledger_bitcoin.psbt import PSBT + +from ragger_bitcoin import RaggerClient +from ragger_bitcoin.ragger_instructions import Instructions +from ragger.navigator import Navigator +from ragger.firmware import Firmware +tests_root: Path = Path(__file__).parent + + +CURRENCY_TICKER = "TEST" + + +def sign_psbt_instruction_approve(model: Firmware) -> Instructions: + instructions = Instructions(model) + + if model.name.startswith("nano"): + instructions.new_request("Accept") + instructions.same_request("Accept") + else: + instructions.review_start() + instructions.review_fees() + instructions.confirm_transaction() + return instructions + + +def sign_psbt_instruction_approve_2(model: Firmware) -> Instructions: + instructions = Instructions(model) + + if model.name.startswith("nano"): + instructions.new_request("Accept") + instructions.new_request("Accept") + else: + instructions.review_start() + instructions.review_fees(fees_on_same_request=False) + instructions.confirm_transaction() + return instructions + + +def open_psbt_from_file(filename: str) -> PSBT: + raw_psbt_base64 = open(filename, "r").read() + + psbt = PSBT() + psbt.deserialize(raw_psbt_base64) + return psbt + + +def test_sign_psbt_singlesig_pkh_1to1( + navigator: Navigator, firmware: Firmware, client: RaggerClient, test_name: str): + + # PSBT for a legacy 1-input 1-output spend (no change address) + psbt = open_psbt_from_file(f"{tests_root}/psbt/singlesig/pkh-1to1.psbt") + + wallet = WalletPolicy( + "", + "pkh(@0/**)", + ["[f5acc2fd/44'/1'/0']tpubDCwYjpDhUdPGP5rS3wgNg13mTrrjBuG8V9VpWbyptX6TRPbNoZVXsoVUSkCjmQ8jJycjuDKBb9eataSymXakTTaGifxR6kmVsfFehH1ZgJT"], + ) + + # expected sigs: + # #0: + # "pubkey" : "02ee8608207e21028426f69e76447d7e3d5e077049f5e683c3136c2314762a4718", + # "signature" : "3045022100e55b3ca788721aae8def2eadff710e524ffe8c9dec1764fdaa89584f9726e196022012a30fbcf9e1a24df31a1010356b794ab8de438b4250684757ed5772402540f401" + result = client.sign_psbt(psbt, wallet, None, navigator=navigator, + instructions=sign_psbt_instruction_approve(firmware), + testname=test_name) + + assert result == [(0, PartialSignature(pubkey=bytes.fromhex("02ee8608207e21028426f69e76447d7e3d5e077049f5e683c3136c2314762a4718"), signature=bytes.fromhex( + "3045022100e55b3ca788721aae8def2eadff710e524ffe8c9dec1764fdaa89584f9726e196022012a30fbcf9e1a24df31a1010356b794ab8de438b4250684757ed5772402540f401")))] + + +def test_sign_psbt_singlesig_sh_wpkh_1to2( + navigator: Navigator, firmware: Firmware, client: RaggerClient, test_name: str): + + # PSBT for a wrapped segwit 1-input 2-output spend (1 change address) + psbt = open_psbt_from_file(f"{tests_root}/psbt/singlesig/sh-wpkh-1to2.psbt") + + wallet = WalletPolicy( + "", + "sh(wpkh(@0/**))", + ["[f5acc2fd/49'/1'/0']tpubDC871vGLAiKPcwAw22EjhKVLk5L98UGXBEcGR8gpcigLQVDDfgcYW24QBEyTHTSFEjgJgbaHU8CdRi9vmG4cPm1kPLmZhJEP17FMBdNheh3"], + ) + + # expected sigs: + # #0: + # "pubkey" : "024ba3b77d933de9fa3f9583348c40f3caaf2effad5b6e244ece8abbfcc7244f67", + # "signature" : "30440220720722b08489c2a50d10edea8e21880086c8e8f22889a16815e306daeea4665b02203fcf453fa490b76cf4f929714065fc90a519b7b97ab18914f9451b5a4b45241201" + result = client.sign_psbt(psbt, wallet, None, navigator=navigator, + instructions=sign_psbt_instruction_approve_2(firmware), + testname=test_name) + + assert len(result) == 1 + + assert result == [( + 0, + PartialSignature( + pubkey=bytes.fromhex( + "024ba3b77d933de9fa3f9583348c40f3caaf2effad5b6e244ece8abbfcc7244f67"), + signature=bytes.fromhex( + "30440220720722b08489c2a50d10edea8e21880086c8e8f22889a16815e306daeea4665b02203fcf453fa490b76cf4f929714065fc90a519b7b97ab18914f9451b5a4b45241201" + ) ) - assert pk.verify_digest(signature=der_sig[:-1], # remove sighash - digest=tx_hash_digest, - sigdecode=sigdecode_der) is True + )] -def test_untrusted_hash_sign_fail_nonzero_p1_p2(cmd, transport): - # payloads do not matter, should check and fail before checking it (but non-empty is required) - sw, _ = transport.exchange(0xE0, 0x48, 0x01, 0x01, None, b"\x00") - assert sw == 0x6B00, "should fail with p1 and p2 both non-zero" - sw, _ = transport.exchange(0xE0, 0x48, 0x01, 0x00, None, b"\x00") - assert sw == 0x6B00, "should fail with non-zero p1" - sw, _ = transport.exchange(0xE0, 0x48, 0x00, 0x01, None, b"\x00") - assert sw == 0x6B00, "should fail with non-zero p2" +def test_sign_psbt_singlesig_wpkh_1to2( + navigator: Navigator, firmware: Firmware, client: RaggerClient, test_name: str): + # PSBT for a legacy 1-input 2-output spend (1 change address) + psbt = open_psbt_from_file(f"{tests_root}/psbt/singlesig/wpkh-1to2.psbt") -def test_untrusted_hash_sign_fail_short_payload(cmd, transport): - # should fail if the payload is less than 7 bytes - sw, _ = transport.exchange(0xE0, 0x48, 0x00, 0x00, None, b"\x01\x02\x03\x04\x05\x06") - assert sw == 0x6700 + wallet = WalletPolicy( + "", + "wpkh(@0/**)", + ["[f5acc2fd/84'/1'/0']tpubDCtKfsNyRhULjZ9XMS4VKKtVcPdVDi8MKUbcSD9MJDyjRu1A2ND5MiipozyyspBT9bg8upEp7a8EAgFxNxXn1d7QkdbL52Ty5jiSLcxPt1P"], + ) + result = client.sign_psbt(psbt, wallet, None, navigator=navigator, + instructions=sign_psbt_instruction_approve_2(firmware), + testname=test_name) + result = client.sign_psbt(psbt, wallet, None, navigator=navigator, + instructions=sign_psbt_instruction_approve_2(firmware), + testname=f"{test_name}_2") -@automation("automations/accept.json") -def test_sign_p2wpkh_accept(cmd): - for filepath in Path("data").rglob("p2wpkh/tx.json"): - sign_from_json(cmd, filepath) + # expected sigs + # #0: + # "pubkey" : "03ee2c3d98eb1f93c0a1aa8e5a4009b70eb7b44ead15f1666f136b012ad58d3068", + # "signature" : "3045022100ab44f34dd7e87c9054591297a101e8500a0641d1d591878d0d23cf8096fa79e802205d12d1062d925e27b57bdcf994ecf332ad0a8e67b8fe407bab2101255da632aa01" + assert result == [(0, PartialSignature(pubkey=bytes.fromhex("03ee2c3d98eb1f93c0a1aa8e5a4009b70eb7b44ead15f1666f136b012ad58d3068"), signature=bytes.fromhex( + "3045022100ab44f34dd7e87c9054591297a101e8500a0641d1d591878d0d23cf8096fa79e802205d12d1062d925e27b57bdcf994ecf332ad0a8e67b8fe407bab2101255da632aa01")))] -@automation("automations/accept.json") -def test_sign_p2sh_p2wpkh_accept(cmd): - for filepath in Path("data").rglob("p2sh-p2wpkh/tx.json"): - sign_from_json(cmd, filepath) +def test_sign_psbt_singlesig_wpkh_2to2( + navigator: Navigator, firmware: Firmware, client: RaggerClient, test_name: str): + # PSBT for a legacy 2-input 2-output spend (1 change address) -@automation("automations/accept.json") -def test_sign_p2pkh_accept(cmd): - for filepath in Path("data").rglob("p2pkh/tx.json"): - sign_from_json(cmd, filepath) + psbt = open_psbt_from_file(f"{tests_root}/psbt/singlesig/wpkh-2to2.psbt") + wallet = WalletPolicy( + "", + "wpkh(@0/**)", + ["[f5acc2fd/84'/1'/0']tpubDCtKfsNyRhULjZ9XMS4VKKtVcPdVDi8MKUbcSD9MJDyjRu1A2ND5MiipozyyspBT9bg8upEp7a8EAgFxNxXn1d7QkdbL52Ty5jiSLcxPt1P"], + ) -@automation("automations/reject.json") -def test_sign_fail_p2pkh_reject(cmd): - with pytest.raises(ConditionOfUseNotSatisfiedError): - sign_from_json(cmd, "./data/one-to-one/p2pkh/tx.json") \ No newline at end of file + result = client.sign_psbt(psbt, wallet, None, navigator=navigator, + instructions=sign_psbt_instruction_approve(firmware), + testname=test_name) + + assert result == [( + 0, + PartialSignature( + pubkey=bytes.fromhex( + "03455ee7cedc97b0ba435b80066fc92c963a34c600317981d135330c4ee43ac7a3"), + signature=bytes.fromhex( + "304402206b3e877655f08c6e7b1b74d6d893a82cdf799f68a5ae7cecae63a71b0339e5ce022019b94aa3fb6635956e109f3d89c996b1bfbbaf3c619134b5a302badfaf52180e01" + ) + ) + ), ( + 1, + PartialSignature( + pubkey=bytes.fromhex( + "0271b5b779ad870838587797bcf6f0c7aec5abe76a709d724f48d2e26cf874f0a0"), + signature=bytes.fromhex( + "3045022100e2e98e4f8c70274f10145c89a5d86e216d0376bdf9f42f829e4315ea67d79d210220743589fd4f55e540540a976a5af58acd610fa5e188a5096dfe7d36baf3afb94001" + ) + ) + )] diff --git a/tests/test_sign_message.py b/tests/test_sign_message.py new file mode 100644 index 00000000..aceb59f6 --- /dev/null +++ b/tests/test_sign_message.py @@ -0,0 +1,31 @@ + +from ragger.navigator import Navigator +from ragger.firmware import Firmware +from ragger_bitcoin import RaggerClient +from ragger_bitcoin.ragger_instructions import Instructions +from ragger.navigator import NavInsID + + +def message_instruction_approve(model: Firmware) -> Instructions: + instructions = Instructions(model) + if model.name.startswith("nano"): + instructions.new_request("Approve") + instructions.nano_skip_screen("Message") + instructions.same_request("Sign") + else: + instructions.address_confirm() + instructions.same_request("Address", NavInsID.USE_CASE_REVIEW_TAP, + NavInsID.USE_CASE_STATUS_DISMISS) + instructions.confirm_message() + return instructions + + +def test_sign_message(navigator: Navigator, firmware: Firmware, + client: RaggerClient, test_name: str): + message = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks." + bip32_path = "m/44'/1'/0'/0/0" + result = client.sign_message(message=message, bip32_path=bip32_path, navigator=navigator, + instructions=message_instruction_approve(firmware), + testname=test_name) + + assert result == "MUUCIQDkeGEVZZiRjMfh+z4ELx81gBdBwIK1IIEHkXZ6FiqcqQIgfaAberpvF+XbOCM5Cd/ljogNyU3w2OIL8eYCyZ6Ru2k=" diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py deleted file mode 100644 index 9991db72..00000000 --- a/tests/utils/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ - -def automation(filename): - """Decorator that adds the automation_file attribute to a test function. - - When present, this filename will be used as the --automation file when creating the speculos fixture. - """ - def decorator(func): - func.automation_file = filename - return func - return decorator \ No newline at end of file