Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signing a P2WSH multisig input fails on updated Ledger firmware & Bitcoin app #680

Closed
dspicher opened this issue Jun 20, 2023 · 7 comments
Closed

Comments

@dspicher
Copy link

dspicher commented Jun 20, 2023

HWI version: 2.2.1

I have an application where I am using HWI to sign for P2WSH 4-of-5 multisig inputs.

Under Ledger Firmware 2.0.2 and Bitcoin App 2.0.6 this worked fine.

After updating to Ledger Firmware 2.1.0 and Bitcoin App 2.1.2 I run into the following error:

('0x6a82', 'Error in <BitcoinInsType.REGISTER_WALLET: 2> command', '')

The hardware wallet also warns about an unusual derivation path before the signature is attempted, although it is the standard multisig P2WSH path at 48'/1'/0'/2' (so this is probably caused by the testnet 1' index).

The PSBT I am trying to sign is of the following form (again testnet):

PSBT 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

I am using the embit library to prepare the PSBT, which makes me think that this sounds suspiciously similar: cryptoadvance/specter-desktop#1840. But the issue seems to have been fixed under the versions I am running.

hwilib.commands.enumerate returns the following for the Ledger device:

[{'type': 'ledger',
  'model': 'ledger_nano_x',
  'label': None,
  'path': '3-7:1.0',
  'fingerprint': 'xxxxxxxx',
  'needs_pin_sent': False,
  'needs_passphrase_sent': False}]

The app-bitcoin-new release notes do not contain obvious hints at what could be going wrong.

@prusnak
Copy link
Collaborator

prusnak commented Jun 20, 2023

cc @bigspider

@bigspider
Copy link
Contributor

Hi @dspicher, make sure you install the "Bitcoin Test" app for testnet, not the mainnet one.

Other than that, the issue is probably that the psbt is missing the PSBT_GLOBAL_XPUB fields; HWI uses them to reconstruct the exact multisig policy (it worked with the legacy app because it would essentially blind sign P2SH scripts, which was not very secure particularly because the app would not recognize the change address).

The PSBT_IN_BIP32_DERIVATION also seem incorrect, as they should contain the exact derivations used for that input − it appears indeed that some derivations info that should rather go into the PSBT_GLOBAL_XPUB was instead added in the PSBT_IN_BIP32_DERIVATION field of the input.

@dspicher
Copy link
Author

dspicher commented Jun 21, 2023

Hi @bigspider

Thanks a lot for your answer, I appreciate your input.

make sure you install the "Bitcoin Test" app for testnet, not the mainnet one.

Good reminder, thanks. The error behaviour is the same when I use the BTC Test app (although the warning about the unusal keypath is gone 👍).

the issue is probably that the psbt is missing the PSBT_GLOBAL_XPUB fields

I cannot confirm this for the PSBT I pasted above. When deserializing it with hwilib, I get the following:

from hwilib.psbt import PSBT
psbt = PSBT()
psbt.deserialize("psbt base64 from above")

print(f"Global Xpubs: {len(psbt.xpub)}")
first_key = list(psbt.xpub.keys())[0]
print(f"First item: {first_key.hex()}: {psbt.xpub[first_key]}")

print(f"Per-input HD Keypaths: {len(psbt.inputs[0].hd_keypaths)}")
first_key = list(psbt.inputs[0].hd_keypaths.keys())[0]
print(f"First item: {first_key.hex()}: {psbt.inputs[0].hd_keypaths[first_key]}")

This prints the following:

Global Xpubs: 5
First item: 043587cf040a8de2c2800000023e209ccd513b09e3b390aa4a4919be344d9f86d4fc302e68d0755ea756ff1db1036bebb1cf441ac096baf0ab4fceb6378c4d331949bc6481f41ee5a16185308f74: <hwilib.key.KeyOriginInfo object at 0x7fa566491450>
Per-input HD Keypaths: 5
First item: 02ca60e3cab1caae37bf2c62e449e889cae1d526defc442e9ed1e584bfaeab5a39: <hwilib.key.KeyOriginInfo object at 0x7fa565819150>

This seems to be in line with BIP174 where PSBT_GLOBAL_XPUB has the xpub bytes as keys, and PSBT_IN_BIP32_DERIVATION has the pubkey bytes as keys.

I corrected one mistake I found with the PSBT I pasted above though: All but one PSBT_IN_BIP32_DERIVATION values had the wrong derivatoin path (m/48'/1'/0'/2' instead of m/48'/1'/0'/2'/0/0). I have fixed this, the error remains the same.

@dspicher
Copy link
Author

One other note-worthy thing about my use-case: At the time of creating the first signature, I don't know the fingerprints of the other signers yet. That's why you find all-zero dummy fingerprints in the PSBT for four of the five signers.

@bigspider
Copy link
Contributor

the issue is probably that the psbt is missing the PSBT_GLOBAL_XPUB fields

I cannot confirm this for the PSBT I pasted above. When deserializing it with hwilib, I get the following:

Ah, indeed, sorry for the oversight. I decoded the PSBT with https://bip174.org and I wrongly assumed it would show the global xpubs if present.

I'm not seeing other issues with the PSBT. The missing key origin info for the cosigners shouldn't cause problems, as far as I can tell.

If you're able to produce a similar PSBT for a policy where you can share the seed, I'll be happy to try to reproduce it locally.

@dspicher
Copy link
Author

I decoded the PSBT with https://bip174.org/ and I wrongly assumed it would show the global xpubs if present.

Hehe, same here, I guess it's time for afilini/bip174.org#20 to be implemented.

I'm not seeing other issues with the PSBT.

ACK.

If you're able to produce a similar PSBT for a policy where you can share the seed, I'll be happy to try to reproduce it locally.

That's great, thanks for the offer! I will first try to solve it by comparing against an Electrum PSBT, and post back here afterwards in either case.

@dspicher
Copy link
Author

dspicher commented Jul 5, 2023

Hi @bigspider, I figured out the issue. It turns out that this was the root cause:

all-zero dummy fingerprints in the PSBT for four of the five signers

This conflicted with the way the multisig wallet is parsed for registration, leading to four identical xpubs ending up in the wallet description. Using the encoded fingerprint in each xpub instead solved the problem.

Thanks for your help.

@dspicher dspicher closed this as completed Jul 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants