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

Adding support for importing non-master extended private key #1137

Open
deepsimulation opened this issue Oct 22, 2023 · 19 comments
Open

Adding support for importing non-master extended private key #1137

deepsimulation opened this issue Oct 22, 2023 · 19 comments

Comments

@deepsimulation
Copy link

Hi,

I was trying to import multisig wallet using output descriptors & I realized Sparrow Wallet doesn't natively support BIP32 non-master extended private keys.

If i try to provide non-master tpriv as master private key & 'm' as the path, sparrow wallet shows "incorrect" tpub.

For example: tpub associated with tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK (generated via http://bip32.org/ for this purpose) is tpubDAenfwNu5GyCJWv8oqRAckdKMSUoZjgVF5p8WvQwHQeXjDhAHmGrPa4a4y2Fn7HF2nfCLefJanHV3ny1UY25MRVogizB2zRUdAo7Tr9XAjm

but Sparrow wallet shows tpub as tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B

Upon quick search this could be the issue:

MasterPrivateExtendedKey masterPrivateExtendedKey = new MasterPrivateExtendedKey(xprv.getKey().getPrivKeyBytes(), xprv.getKey().getChainCode());

@craigraw
Copy link
Collaborator

Indeed, this is not currently supported - the import is specifically named Master Private Key (BIP32). Can you describe the need for this use case?

@deepsimulation
Copy link
Author

deepsimulation commented Oct 22, 2023

Yes, our product allow users to create multiple multisig wallets, one of them could be software key. If the key is a hardware device, Sparrow wallet doesn’t have problem signing the psbt. However, for software key, they would import derived xpriv corresponding to their wallet.

After the output descriptor is imported, they would import derived xpriv corresponding to xpub entry in the descriptor string to sign transactions. This allows them keep their other multisig wallets private & secure.

@craigraw
Copy link
Collaborator

In the software key situation, what software is deriving the xpriv from the seed? It seems overly complicated to require two applications for one key, and less secure as well since the attack surface is broader.

@deepsimulation
Copy link
Author

Some background: We've built multi-account collaborative multisig solution (theya.us). We've designed the software in a way, that gives privacy, security & flexibility for the user to manage multiple multisig wallets. Let's say Alice sets up 2 multisig wallets with Theya:

  1. Personal (1 software key owned by Alice + 1 hardware key owned by Alice + 1 Theya key)
  2. Shared (1 software key owned by Alice + 1 software/hardware key owned by Bob + 1 Theya key)

The software keys for both accounts are not same. They are however derived from same seed using separate account_index. So, if Alice wants to export their Personal wallet via Sparrow (at this point their Personal wallet is not secure anymore, we'd recommend them to move funds to another wallet they own), they should do it via their derived xpriv instead of mnemonic or master xpriv, latter is not secure because it impacts Shared wallet.

@deepsimulation
Copy link
Author

@craigraw is this something you are okay supporting? I’m happy to raise a PR.

@craigraw
Copy link
Collaborator

craigraw commented Nov 5, 2023

TBH I'm still struggling to understand this.

at this point their Personal wallet is not secure anymore

Why is it not secure anymore? Is the software key compromised in some way? If so, why is the derived private key compromised, and not the master private key?

Making this change to Sparrow would require fairly extensive changes all the way from the UI through to the persistence layer, for a use case that seems poorly defined to me.

@icy-ux
Copy link

icy-ux commented Dec 30, 2023

As discussed in #1208, this should be extended to include importing and exporting all private key based descriptors. This would allow seamless compatibility between Sparrow and other descriptor based wallets. Right now, working with bdk (which uses private key based descriptors) wallets in Sparrow is a giant pain.

If someone wants to import a non-watch-only-wallet using a descriptor, how are they supposed to do that right now? Import the descriptor and then add the seed phrase manually?

If someone wants to export a non-watch-only-wallet to a descriptor-based wallet (e.g anything using BDK)... how are they supposed to do that right now? Export the descriptor, and then -- break down and cry because they only got a watch-only wallet, and that's the only option?

As it stands building a descriptor wallet that only handles public keys seems fundamentally incomplete, as if Michaelangelo had sculpted David but left off one leg.

@craigraw
Copy link
Collaborator

craigraw commented Jan 4, 2024

@icy-ux I appreciate the use case of working with BDK, but I'm conservative when it comes to exporting private key material. The understanding of protecting seed words is somewhat understood, even if there are constant attempts by scammers to have users enter seed words on many fake Sparrow wallet websites. Offering an export of private key based descriptors will open up another attack vector, but this time with key material that is poorly understood and looks much like public key descriptors. Interoperability is an important goal (and I'll note here that BDK does support importing seed words) but security of funds is critical.

While the current approach seems incomplete to you, it is not by omission - rather it is specifically designed to make it more difficult to lose funds.

That said I'm somewhat okay with this if the wallet was specifically created by pasting in a private key descriptor, since one would assume this would only be done by a technically savvy user. That said, it does create related problems. Such a wallet would not have access to the master secret, and therefore would be a new kind of limited software wallet. It could not, for example, calculate a BIP47 notification address, payment code, or act as a Whirlpool mixing wallet. This increases the support burden, since now should a user experience difficulty with any of the above we must first check whether they have created such a limited wallet. In addition, the software itself must be more complex to handle this situation across a broad range of functionality, which increases the maintenance burden.

All this to point out that there are tradeoffs here, and I need to consider the needs and responsibilities of many before making what is a fairly significant change - creating a new type of software wallet.

@icy-ux
Copy link

icy-ux commented Jan 4, 2024 via email

@craigraw
Copy link
Collaborator

craigraw commented Jan 5, 2024

If the user clicks "Export as Electrum", the resulting JSON file is highly sensitive.

You're right, but I'd argue that exporting an Electrum file is much more buried in the interface than exporting the output descriptor, which is available directly from the Settings tab. In any case, I should look at encrypting that export, so thanks for pointing it out.

Instead, we should be fixing the problem through UX

You are clearly a technically knowledgeable user. Unfortunately I think you overestimate most users understanding of the difference between public and private key material. Many (most?) users do not read, so the solution of "flashing lights and warning sirens" just irritates technical users while doing little to protect less technical ones. I have plenty of experienced evidence of this.

Wouldn't it? As far as I know, a descriptor can contain the master secret, but does not have to.

In general it does not. If you have the master xprv, you can already import it into Sparrow, so this issue is about importing non-master xprvs.

If the user tries to perform an action for which the wallet does not have the necessary key material, we know that is what is going on as soon as the condition happens. The wallet only needs to notify the user with a suitably informative
error message.

Some actions (for example, scanning a BIP47 notification address for transactions) happen without user interaction, making this approach potentially confusing.

In general your approach seems to be "let's solve it by showing more dialogs to the user and relying on support to explain things". I don't mean to criticise - for some applications it may be entirely appropriate - but this philosophy runs pretty much directly counter to the approach I've taken, which is to reduce dialogs and reliance on external tech support.

Rather than debate UX philosophy though, I'd like to hear about specific use cases for this functionality. Substantial changes should be accompanied by substantial motivation, and I've still to hear that in this issue.

@icy-ux
Copy link

icy-ux commented Jan 5, 2024 via email

@craigraw
Copy link
Collaborator

craigraw commented Jan 8, 2024

When I export an Electrum wallet, I get private key material as a JSON file!

Electrum wallet exports are now encrypted as of b5196d1 where a wallet password is present.

That wasn't true when I tried it a few days ago -- I imported a descriptor containing an xprv and got a watch-only wallet.

It's possible to do this via creating a new wallet, selecting Software Wallet, and using the Master Private Key (BIP32) option to input the xprv.

Extending this functionality to support importing the master private key via a descriptor should be possible as well - it's never come up before, so I haven't implemented it. I will look into this.

bdk applications tend to import and export wallet keys (public and private) using descriptors.

Can you provide an example of such an application? I'd like to try it to understand this issue better.

@icy-ux
Copy link

icy-ux commented Jan 8, 2024 via email

@craigraw
Copy link
Collaborator

craigraw commented Jan 9, 2024

Although it does not address the subject of this issue, as of be0ac52 Sparrow supports importing descriptors containing master private extended keys. This solves the use case for importing a wallet created using the swap binary, which exports a master private key.

I'm still looking for specific use cases to motivate the original issue. As noted previously, substantial changes require substantial motivation, especially when they involve importing and exporting of private key material.

@icy-ux
Copy link

icy-ux commented Jan 10, 2024 via email

@craigraw
Copy link
Collaborator

Other BDK-based wallet applications (see the link!) also allow importing wallets.

Obviously I am aware of many of the applications at that link. They don't to my knowledge export wallets using descriptors with xprvs though, at least not exclusively.

I need a way to generate a wallet in Sparrow, before importing the descriptor into the final application.

What makes you want to deviate from the standard practice of using a BIP39 seed or master xprv for this?

@icy-ux
Copy link

icy-ux commented Jan 12, 2024 via email

@craigraw
Copy link
Collaborator

Note it's possible as of be0ac52 to import master xprvs with specific derivation paths.

@icy-ux
Copy link

icy-ux commented Jan 16, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants