-
Notifications
You must be signed in to change notification settings - Fork 119
Conversation
e19b7c8
to
73a6f0b
Compare
Fixed up the commit so you can see the code (got rid of the junk changes). |
Amended to include a proof of discrete log equivalence - style commitment. See Defence 2 here. The handshake is now:
Since only messages from taker to maker are affected, the backward compatibility concern only operates in one direction. This code allows the maker to accept old-style takers (if commitment not provided, operates as before). I believe it operates correctly with The "blacklist" aspect is unchanged from the previous version; the commitments (H(P2) values) are added to a blacklist file and requests are rejected when exceeding the value in "LIMITS", "taker_utxo_retries" in the config. |
Just to reflect what was already said on IRC: Please consider wallet providers. This is maybe not an exhaustive perspective but best think of hardware wallets that under no circumstances would share private keys but that might be convinced to blindly sign transactions that make them richer (maker's yielding) if the rules to do so can be embedded in them in a fool proof way. I'm trying to integrate JM in Mycelium without re-implementing JM in Java but even if somebody provided a Java library for that, I would hesitate to put it anywhere near the wallet code and watch over all changes to that library like a hawk, to keep the wallet safe. My current approach is to run joinmarket in an http proxy but for sake of argument, a proxy could also run on the wallet's phone itself, in its own sandbox, which wouldn't change the API requirements although it would make things decentralized and put joinmarket under the sole control of the user. For all the above it would be desirable to require little to no extra round trips and especially little to no extra signing other than the final transaction. The current requirement to sign a NACL key with a private key involved in the UTXO set is already removing hardware wallets from the picture for now, as this would mean yet another step, where the user would have to approve the signing of some "random" string just to kick off the joinmarket "negotiations", to then, seconds later approve of a transaction. |
Well, it's only fair to include the detailed responses I gave on IRC: waxwing> i appreciate Giszmo's concern and would say 2 things: 1/ merging #328 as current would not enforce the PoDLE check, in that code makers will simply continue as before if it's not provided. Enforcing it would be a huge step, so.. I've tried to explain that we cannot simply remove the nacl key signing; it is the only guarantee that the counterparty has that he isn't being MITMed. It's intended (caveat: see above) to ensure that the entire conversation is with one entity - the owner of those bitcoins/utxo. At the same time, I fully understand that PoDLE is not realistic (at least not currently) for a hardware wallet, it requires EC operations with the private key, no less. Hence my thoughts listed above. If an implementation of JM was indeed integrated into a wallet, this might not be an issue. Not to downplay how difficult that would be. If you try to separate JM entirely from the wallet, a desire I totally understand, then this extra signing operation problem occurs, but for good reason. |
@AdamISZ it's not that I don't get what the goal is here but there is more things to consider:
|
Well, that's certainly interesting! I haven't heard such myself (and indeed have made bitpay payments with coinjoins with no problem), but it raises interesting questions if it could happen. As far as I'm aware, people have been using both DarkWallet and SharedCoin with no problems so far? It would be most disappointing if people actively try to degrade Bitcoin's fungibility like that. It is effectively the same as whitelisting (we only accept utxos conforming to X), which is pretty much the worst scenario. But I suspect a long discussion of this veers too far off topic.
I don't understand what you mean here. It's intended to do exactly that.
I agree, I don't see anything wrong with this model if people opt in to it. But it's this model that you're unhappy about, no? Because you don't like needing the extra signature.
That's a very good technical point which I think we overlooked (to be fair to us, it's because we didn't anticipate delegation, instead we thought only of integration).
"Bloat" just seems pejorative here. We created a bare-bones wallet in joinmarket because we understood it would not be easy to integrate this functionality into existing wallets (although on the plus side, you don't need mixing depths if only doing taker side), but however difficult that might be, it is the natural way to expose it to wallet users. |
I gave the example of users exposing their keys to third party banks in order to do JM, if delegation is prevented, putting that bank into the position of an ultimate MITM
Ideally I would pay for the maker revealing their order books and UTXOs factions of a cent, and then pay for signing my tx and then pay for not double spending on me per second. I doubt that the proof-of-good-intentions by requiring the involved UTXO makes any sense as a commitment and for a MITM protection I agree that it might provide some benefit although I'm not convinced. Naively I would rather have some makers with reputation linked to a nacl key that people trust, which allows takers to contact those. If the up-front commitment is an UTXO's signature, then a committed attacker can always query all the makers at no costs and the taker role can't be moved into a module away from the private keys. Of course we also want to do the maker side at some point or in other words, users will want to put their money into wallets, not into mixing scripts. The interface that approves of mixing transactions should be decoupled from all the coin selection logic, communication protocol, order book management etc. I want joinmarket to only do join market and wallets to do transaction approval. At mycelium we are thinking about putting extra stuff into modules but we should actually do the private keys containing stuff into a module with a hardware-wallet like interface. It's pretty insane to have a 10MB app to keep secure against all the attacks. |
Regarding the taker-side-auth-being-optional, this was discussed once before when planning for a protocol update: #90 (comment) There we both seemed to agree that making taker-side-authentication optional was okay. I don't know if your opinion has changed since then (I'm not sure myself) In Mycelium's case (and also Electrum and any other lightweight wallets), the server already knows all the addresses of the user's wallet and that they're linked together, with this information they can already unmix all your coinjoins. However, this PR is about solving issue #156, allowing takers to opt-out from providing a UTXO would stop this PR from working, which could ruin the privacy for every JoinMarket user, not just users of lightweight wallets. Large companies blocking coinjoin is interesting, I hoped JoinMarket would stay under the radar a little longer but seems not. CoinJoins can be quite hard to spot, many large bitcoin institutions that use Bitcoin Core sendmany can sometimes create coinjoin-like transactions. (Look at Adlai's cjhunt to see how many false positives there are out there) Also some wallets like Samourai wallet and Bitcoin Core plan to create coinjoin-like transactions by default (making the change be two outputs where one of them is the same value as the payment output) which might also gunk up the analysis. Finally, coinswaps as in #335 are another way to improve privacy that can be indistinguishable from normal bitcoin payments. |
Re #90 : good point! I don't know whether I was thinking more carefully there, or just glossing over details, but it's true: if we only want to prevent a MITM attack then authentication on one side only is sufficient. I had completely forgotten this rather crucial subtlety. Using a bitcoin key is us trying to get the weakest viable form of "attestation to an identity". Without even that (on either side), then MITM is fully possible in as much as anyone can carry out the protocol with you, and replay your side of the protocol to anyone else. There can even be a huge chain of such MITMs. A one sided authentication is enough to stop that. It doesn't mean that the authenticating side isn't a snooper, but it at least means you're talking to someone who owns that private key. Weak, but not nothing. And that single authentication prevents passing the dialogue on because a MITM needs to be able to fake both sides. Then, there's wanting to have both sides make some kind of commitment/attestation, to prevent partial snooping: learning utxos, principally. For that, a double-sided authentication with btc signatures is a logical choice, but it might not be necessary and probably isn't sufficient (at least, if you allow infinite repeats). So there are the other possibilities: PoDLE, P2CH, perhaps PoW or even what I mentioned on IRC:
i.e. you could replace the authentication-via-bitcoin-signature with trust. And on that topic:
This is a good point which I had also overlooked (although it might not be 100% true that they know all addresses, but let's say, for the sake of argument). It doesn't mean delegation is great, but it strengthens the case that using trust here doesn't lose much.
Minor point, but I wouldn't overplay this; all the false positives seemed to have basically the same pattern. I don't think there are a huge number of txs at the moment which are a good match to our JM txs. For hardware wallets: a "signature from a delegating proxy" doesn't work there. What else is left I wonder, to prevent spam/snooping? If PoW is not practical, I wonder. I can't see how we can have takers propose transactions without either a btc signature or any form of commitment. |
DO NOT MERGE.
(needs rebasing anyway :) )
Idea: every new btc utxo used for signing by taker in !auth is appended to a 'blacklist' file with a counter. the counter is incremented when the utxo is reused. If the counter exceeds the value in "LIMIT","taker_utxo_retries", the !auth is rejected (so no maker utxos are sent across).
There are as I see it two big issues with this (at least).
The first, most important: we currently only send input btc pubkey in the !auth message, not a utxo. So, the taker can send any old pubkey, not necessarily corresponding to a real utxo. In the current model (see the last paragraph of encryption_protocol.txt), the validity of this pubkey is checked only before sending across our transaction signatures, so if a fake pubkey is used, we don't send signatures, but we do send utxos (in !iouath) from maker to taker.
This PR changes that, which means a version change in Joinmarket, so is very disruptive. The taker sends also a utxo along with the pubkey (the latter could be ditched). the maker calls query_utxo_set on it, and ensures that it's a valid utxo. It could easily (I would definitely add this) check the coin age/confirmations of that utxo also. This allows what's described in the first paragraph above.
The other big issue with this is that it makes takers very fragile to disruptive makers. If any maker decides not to cooperate (or just fails), this "uses up" that utxo and the taker cannot use it more than 3 times. If we were to apply this model I think we would also want to add code to allow the taker to choose a different one of his utxos in the next attempt.
The last point to make, I guess, is that this is fairly weak, depending on if we decided to include coin age restriction and coin amount restriction.