Output linkability is a privacy issue. There are three types of output linkability that exist:
- Linkability between inputs
- Linkability between outputs
- Linkability between an input and an output
On top of that, there are two kinds of actors for each of the types:
- Transacting party - the party you're transacting with
- 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.
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:
- Linked for transacting parties
- 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
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 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.