Skip to content

Instantly share code, notes, and snippets.

@phyro
Last active August 25, 2020 21:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phyro/fff8ed9ea10461be4364d5a5bb4dd608 to your computer and use it in GitHub Desktop.
Save phyro/fff8ed9ea10461be4364d5a5bb4dd608 to your computer and use it in GitHub Desktop.
MW Privacy Issue

MW linkability

Output linkability is a privacy issue. There are three types of output linkability that exist:

  1. Linkability between inputs
  2. Linkability between outputs
  3. Linkability between an input and an output

On top of that, there are two kinds of actors for each of the types:

  1. Transacting party - the party you're transacting with
  2. Transaction observer - anyone observing the transaction

All these are a problem, so we have 6 combinations in total that we care about. I'll address here linkability between the inputs because they reveal a lot more over time than one might think.

'Linkability between inputs' problem

When Alice is sending money to Bob, she uses multiple inputs to send money to Bob. Since all of the inputs belong to Alice, we know that the outputs I1, I2, ... In are linked. Note that even if I1 (or any other) was completely private in the transaction in which it was created (the transaction did not reveal any links), the privacy of that output does not end here because its linking will likely become leaked at some point later when this output gets used with other outputs on the input side. The end result is the same as if the original transaction linked them. To put it more formally, if transaction T creates an output O2 for the receiver that is later spent with another one of the receiver's outputs O1 in one of the future transactions, then it is no different than revealing the O2, O1 link in transaction T. This means that with time and spending, everyone is revealing a lot of the information and output linkability to all transaction observers even if the transaction that created these outputs had perfect privacy in isolation.

Improvements

Linkability between inputs

First reaction to this would be "be smarter about how you use the inputs", but I don't believe this is actually a good strategy because you will inevitably have to spend multiple inputs eventually even when you're trying to spend the inputs in an optimal way. A simple example of this is when you have two outputs O1 = 5 Grin, O2 = 4 Grin and you need to send 6 Grin to someone. There is no way to do that send without showing the link O1, O2. So we need a better strategy.

I believe PayJoin transactions mitigate this problem. If we contribute our output O1 as an input to a payjoin transaction that creates an output O2 then the two become:

  1. Linked for transacting parties
  2. Probabilistically linked for the transaction observers - probabilistically because the additional input is probabilistically linked to some output in the transaction

This gives much less information to the transaction observers. It is also an improvement because our O1 and O2 are not obviously linked. It's no longer clear whether they belong to the same party.

But what if we are withdrawing from an exchange? We can decide not to do payjoins when transacting with the exchanges and have a separate transaction building flow for such third parties. Let's say we perform a regular MW transaction when withdrawing from an exchange to receive an output O2. If O2 is spent as an input to a payjoin transaction that has O3, O4 inputs, it is still unclear which of the inputs are linked because they don't come from the same party.

PayJoin transactions seem to improve the current situation which makes it very easy to link the outputs together. While payjoins are a privacy tradeoff because the receiver needs to reveal one of their outputs, they bring great benefit because they introduce uncertainty in the input linkability that would likely hit us in one of the future transactions. Another benefit of payjoin transactions is that it makes backwards tracing much harder to do because of the uncertainty on the input side that it creates.

Linkability between outputs & Linkability between inputs and outputs

Once outputs are seen in a regular 1-2 transaction, these two will be linked to the same transaction by everyone that managed to see the transaction. I think it's possible to improve this situation and I've described the idea that does this in the Objective Dandelion thread - the main technique is swapping of the outputs as the transaction is getting passed around, so the people that saw it previously can't tell which outputs are linked.

NOTE: Since outputs are getting replaced for new ones, it means that this also unlinks the inputs and the outputs, so it improves both 2. Linkability between outputs and the 3. Linkability between an input and an output.

@johndavies24
Copy link

I don't think it's the same for me to link my own outputs with the minimal number of outputs of the counter party as it is to link an extra input and a new output of mine as well as link it to all the inputs and outputs of counter party. No data to support this, but it seems like it's not the same. Especially if the counter party is an entity you would like to minimize linkages with.

@phyro
Copy link
Author

phyro commented Aug 25, 2020

I don't think it's the same for me to link my own outputs with the minimal number of outputs of the counter party as it is to link an extra input and a new output of mine as well as link it to all the inputs and outputs of counter party. No data to support this, but it seems like it's not the same. Especially if the counter party is an entity you would like to minimize linkages with.

I'm not sure I understand your first point. The example scenario I gave links both of them in the same way as if they were in a payjoin (actually they get linked quite a bit worse imo) if we take the current setting where no payjoins are happening on the network (even if there are very few, it's still bad imo). PayJoin can be viewed as a public (but with a bit obfuscated linking to the outside observers due to being a part of a payjoin) merge of two of your outputs. One is an existing output that you own that is contributed as an input to the payjoin tx and the other one is the output you receive. This means that with a payjoin tx, you will end with an output that has the sum of the v values of the two that you would use at some point in the future. If you use two inputs to pay and there are no payjoins, you can think of this as a public merge of the two inputs whose link is transparent and visible to everyone.

@johndavies24
Copy link

Without payjoins my outputs are only linked out of necessity. IF that necessity occurs then yes, my outputs are linked as inputs for a future tx. No one knows if this is a regular send or payjoin, but let's just assume that this means anyone can link these two inputs. We end up with 100% certainty that two independent tx graphs are linked to a single user and one of the outputs is to the counter party.
But with a payjoin we link the tx graph history of at least one of my inputs to my output as well as to the sender input and output. We end up with 50% certainty of possession, but with at least 4 outputs being linked (two being UTXOs and two being inputs). This causes more tx graphs to get linked together.
It seems as if you double the linkages of tx graphs but cut in half the ability to assume ownership of outputs

@phyro
Copy link
Author

phyro commented Aug 25, 2020

Without payjoins my outputs are only linked out of necessity. IF that necessity occurs then yes, my outputs are linked as inputs for a future tx. No one knows if this is a regular send or payjoin, but let's just assume that this means anyone can link these two inputs. We end up with 100% certainty that two independent tx graphs are linked to a single user and one of the outputs is to the counter party.

Right now everyone knows if this is a regular send or a payjoin because there are no payjoins. I think you want to have as many payjoins as possible with a some probability of it not being payjoin.

But with a payjoin we link the tx graph history of at least one of my inputs to my output as well as to the sender input and output. We end up with 50% certainty of possession, but with at least 4 outputs being linked (two being UTXOs and two being inputs). This causes more tx graphs to get linked together.

They get linked in the same way if you use both of them as inputs in a future tx. Once they are seen together on the input side of the transaction you can just go back and check in which tx these inputs were created and link them to the inputs and outputs of their parent transactions as well.

It seems as if you double the linkages of tx graphs but cut in half the ability to assume ownership of outputs

I don't think you double the linkages - once linked, I think they show exactly the same links. You just make sure you create a link on your own that:

  1. will have better privacy compared to a link that will be created in the future from multiple inputs
  2. help obfuscate the multiple inputs usage for the whole network by having majority of the txs be payjoins
  3. help the whole network by making backwards tracing much harder

@johndavies24
Copy link

All of your views are based on the threat level of a vanilla block explorer. I think that's a horribly flawed perspective.

We both agree that payjoins should be an option and they are a great tool. I believe all payjoins would be worse than no payjoins, we may disagree here. I believe an unpredictable usage would be best and unfortunately not something that we could accomplish because I'd also need to be sure I'm not forced to payjoin with certain parties that I'd rather leak the minimum information to the counter party

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment