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

Hardware wallet support #663

Open
kristapsk opened this issue Aug 6, 2020 · 13 comments
Open

Hardware wallet support #663

kristapsk opened this issue Aug 6, 2020 · 13 comments

Comments

@kristapsk
Copy link
Member

kristapsk commented Aug 6, 2020

There was issue about hardware wallet support for yield generators in old JM github repo - JoinMarket-Org/joinmarket#537, let's move further discussion here. And also extend it also to the taker side.

Trezor has implemented some support for CoinJoins in their firmware, haven't yet carefully looked through details, but at first glance seems to be usable for a single joins as a taker - trezor/trezor-firmware#1127. Which could be useful in cases when you, for example, have tumbled your coins to the hardware wallet first and then after some time want to do some payment from it in a more private way.

@AdamISZ
Copy link
Member

AdamISZ commented Aug 7, 2020

As discussed previously, Joinmarket coinjoins can't be instantiated in current hardware due to the requirement of generating PoDLEs.

See a recent PR by Jonas Nick to secp256k1 that includes these PoDLEs (aka DLEQs), in particular here: https://github.com/jonasnick/secp256k1/pull/14/files#diff-a684b19a811e1813f1ab819b12c97ca0R98

But I see no realistic prospect of this getting into hardware any time soon.

@kristapsk
Copy link
Member Author

Ahh, yes, forgot about PoDLEs. But Trezor and Coldcard firmware's are open source, so that's probably solveable even if they aren't so much interested in this (although, nvk has said on twitter previously that they want to support JoinMarket, see twitter links in related old JM issue).

@AdamISZ
Copy link
Member

AdamISZ commented Sep 3, 2020

I'm closing this because I don't want Issues open that are not actionable, and I see no way of actioning it.

Perhaps if anyone wants they can reopen this with a specific plan to support hardware wallets in some way. An example might be doing "manual" coinjoins, but that thought would need fleshing out.

@AdamISZ AdamISZ closed this as completed Sep 3, 2020
@AdamISZ
Copy link
Member

AdamISZ commented Sep 7, 2020

Someone just raised this on IRC and it may me reflect on it again - in particular, it should be possible to do this without changes to hardware wallets, but - it's going to be tricky and quite limited! :

Taker:

  • Prepare external commitments using the methodology of add-utxo.py (or otherwise) from a Joinmarket wallet that is hot, i.e. you hold the keys in Joinmarket itself. These get added to ~/.joinmarket/cmtdata/commitments.json. Note that they will have to fulfill the 20% size rule as outlined somewhere in our documentation (I'm assuming that devs already know this stuff, but you're forgiven if you don't ...).
  • Now you want to do a coinjoin with a wallet held on a hardware wallet (henceforth just HW). We first need a mechanism to select utxos from HW in real time based on the user request. Perhaps a sort of "fake wallet class" into which you inject the utxos that you know HW owns (but it's yucky as our UTXOManager is based around actually owning the keys, so this won't be trivial). You run the Joinmarket taker, getting the utxo list as mentioned, and having your commitments sourced from external, send the !tx message as usual, get back the !sig messages as usual, and only in the last step do you need signing. There, we have the Taker output the PSBT that can be transferred to HW and co-signed and broadcast.

NB external commitments could be prepared from the same BIP49 wallet, in advance, on Joinmarket, and then that wallet is "opened" on HW and the JM wallet could be deleted. I guess that is actually a reasonable idea.

(Maker

I guess it is possible if there some kind of connector between HW and JM which is automatic. My problem with this line of thinking was always: hasn't this effectively made the HW become a hot wallet, if it automatically signs without human intervention?)

(Let's state the obvious - the Maker doesn't have the PoDLE problem ... also it's exactly in this scenario that we have to worry about the now-famous attack on automated coinjoin - what if HW is tricked into signing two different versions of the same transaction, thinking it has spent less than it actually has.)

@AdamISZ AdamISZ reopened this Sep 7, 2020
@AdamISZ
Copy link
Member

AdamISZ commented Sep 7, 2020

I just remembered there is already a "WatchOnly" wallet in jmclient/wallet.py but it's for now specifically just FidelityBondWatchOnlyWallet - this could potentially be useful if someone were trying to code up the "fake wallet class" I was mentioning above.

@AdamISZ
Copy link
Member

AdamISZ commented Oct 5, 2020

For the Maker side:
It's certainly interesting, and is likely to require fairly minimal code patch(es) to Joinmarket itself to support automated signing using existing standards (BIP32, BIP49, BIP84). (Edit: additional thought is the patch would also have to include usage of the PSBTWalletMixin to pass the transaction, so not that small)

So it seems like the biggest issue there would only be for any particular hardware wallet to support the use case - that is, to have a mechanism for signing to be automated via code, without manual verification and input. It's not hard to imagine that most consumer hardware wallets will not and probably should not support such a thing, because its existence might end up creating a backdoor for attackers. On the other hand, certain hardware wallets in certain situations might want to (and for all I know, perhaps they already do) support such automated signing use cases. This line of thinking is of course relevant to Lightning as well as coinjoins.

@xsats
Copy link

xsats commented Oct 6, 2020

Thanks for sharing these insights @AdamISZ, very interesting and helpful for onlookers.

Although I find the idea of JoinMarket hardware wallet integration very interesting and exciting, I share your concerns about how this could defeat the very purpose of using a hardware wallet in the first place (cold-storage becoming hot).

I thought I'd chime in to mention the ColdCard HSM mode, CKBunker in case you're not already aware of it. Perhaps it could be possible to take advantage of the CKBunker (or an equivalent HSM) to create a JoinMarket maker, "constrained" connected hardware wallet, that could potentially be used to mitigate some of the additional risks associated with deploying a hardware wallet as an online maker.

I haven't personally looked into this a great deal yet, but it seems to me as though there could be at least potential for a beneficial CKBunker/JoinMarket combination, for hardware wallet support - perhaps worthy of further exploration.

@xsats
Copy link

xsats commented Oct 6, 2020

CoinKite has detailed some of the functionality of the ColdCard HSM mode here:
https://coldcardwallet.com/docs/ckbunker-hsm

In effect, the setup permits the creation and loading of a "policy file" to the device which cannot be changed or overridden without physical access to the device. This policy file could perhaps be used to narrowly constrain the role of maker and somewhat enhance the security of the always online makers.

While in "HSM Mode", the ColdCard can automatically sign transactions as required for a maker, but only those that satisfy the constraints defined within the policy file. This could fit the bill well.

@kristapsk
Copy link
Member Author

About taker proposal above - usefulness of that would go beyond hardware wallet support, it would also allow integrating JoinMarket with other wallets, for example, sending CoinJoin's from Bitcoin Core wallet or integrating JoinMarket support in Wasabi Wallet.

How I see it:

  1. commitments will be needed to be added using add-utxo.py or some other way as described above (if integrating with some external hot wallet, that can be automated);
  2. proper watch-only wallet support is implemented in JM (could be hardest part?);
  3. support for returning PSBT is added to sendpayment.py for coinjoins (maybe also for sending BIP78 payjoins, but there is that 1 minute timeout when receiver can broadcast original tx, could be not enough when manually signing with hardware wallets);
  4. full signing and broadcast of tx may be handled completely outside JM (for hardware wallets just use hwi?).

Somebody correct me if I'm missing something.

@nopara73
Copy link

In Wasabi I think the transition plan could be:

Add a config entry: UseJmForUnmixedCoins. This would initially default to false. This would attempt to do a 2 participant JM transaction whenever unmixed (red) coins are attempted to be spent.

Then over time it'd turn out if it'd be useful or not and we can default to true from there on.

But before all that, the question that arises for me is that if it even provides any privacy at all or just brainlessly making users spend more on fees. Would the makers yield generation activity be so distinct on the blockchain that Wasabi users who're takers only would be distinguished by their histories and future activities and so get deanonymized easily?

@kristapsk
Copy link
Member Author

@nopara73 This is valid question without a simple answer IMO. It depends on usage patterns of existing JM users, mainly, how often they mix maker and taker roles (there is some hope #487 will improve that) and, if they do, how often they also do non-cj sends and payjoins. One thing that could already de-anonymize Wasabi users is plan for 2 participant JM coinjoins, as they are very rare currently, with default configuration sendpayment.py will refuse to continue if there aren't at least 4 other counterparties.

@kristapsk
Copy link
Member Author

Here's nice approach by Bitcoin Core - bitcoin/bitcoin#16546, probably could steal some ideas. Planning to test and review it.

This PR lets bitcoind call an arbitrary command -signer=<cmd>, e.g. a hardware wallet driver, where it can fetch public keys, ask to display an address, and sign a transaction (using PSBT under the hood).

@AdamISZ
Copy link
Member

AdamISZ commented Jun 2, 2022

This has been sitting in the background as 'something many of people want to have, but almost zero people are going to do anything about it' :)

I think the maker side is the most likely to work. Areas of development are:

  • Improved PSBT support, though what we have right now might be just enough, it'll probably need extending at the UI level
  • The watch-only fidelity bond wallet. This is the key fundamental development. The groundwork was there in the original fidelity bond wallet PR, but it still needs substantial work to make it available to the user.
  • Signing policies as per the ckbunker thing discussed above - it's much easier to recommend that setup than one in which automated signing is occurring on coinjoins without constraints (coinjoins are a much trickier construct even if you don't consider the liveness/hotness of signing automatically, but both combined is something to be very careful about).
  • Careful consideration of the old Greg Sanders attack (the 'make him sign twice' thing) to make sure you don't get exposed to it, somehow. Honestly there's almost no chance of it being a serious issue, but it has to be examined and not ignored, I think.

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

4 participants