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.
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.
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 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.
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
.
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.