I’ve been thinking about the replays and aggregators and I think this is another option that is similar to anchors, but without anchors. The idea was described in this gist and below is a paste of its content:
Replay resistance through aggregators
One of the previous protections against replay attacks required the attacker to replay a sequence of payjoin transactions until the attacker was met with an impossible requirement of replaying a transaction that was impossible to replay due to a duplicate output (anchor solution) consensus rule violation.
This is an attempt to not introduce an absolute protection as the anchor solution does, but perhaps something that is for most practical concerns a good enough solution.
Let’s assume we have a daily aggregator
A. Every transaction that gets published on the chain also sends a coinswap for each created output to
Let’s reuse the idea of making every transaction a payjoin. We now have the same first step part of the attack protected in the same way which is that the attacker would need to replay a sequence of payjoin transactions. But we lack the initial condition which would make it impossible to replay the first transaction.
Let’s assume we get an output from a daily aggregator
O1. If a significant aggregation took place in
O1 was created, then we can assume that it is extremely hard to replay the aggregated transaction that created
O1. This is because all the outputs in the aggregated transactions need to be spent and the attacker would also need to know how to generate all the inputs of the aggregated transaction which seems almost impossible to do. The output
O1 can thus play a similar role as an anchor, but can be spent.
All we have to do is know which outputs were ‘coinswapped’ and then use these as inputs for our payjoin transactions.
In order to be able to do simultaneous transactions, the wallet makes sure it has
N “safe” outputs available. We could label a coinswapped output as “safe” by using one of the zero bits in the bulletproof and setting it to 1.
Note: When doing a payjoin with a safe input
B_I', then the output we create
B_O is also safe.
Alice (sender) has an input
A_I and a change output
A_O. After the transaction has been broadcasted,
A_O' is created with a bulletproof coinswap bit set to 1 and
A_O -> A_O' is sent to the daily aggregator.
Bob (receiver) contributes an input
B_I' (coinswapped) to the transaction, making a payjoin. Bob also has an output
B_O and similarly as in the case of Alice, after the transaction has been broadcasted,
B_O' is created with a bulletproof coinswap bit set to 1 and
B_O -> B_O' is sent to the daily aggregator.
It is impossible to contribute a coinswapped input when you don’t own any output. The first receive can be made safe if the received output is coinswapped in the aggregator before doing any other transaction.
This is hard enough to replay as is, but can be made basically impossible if the daily aggregator contributes aggri-1 -> aggri to the daily aggregated transaction
i and then in
i+1 adds aggri -> aggri+1 and so on. This would require the attacker to replay everything from all the daily aggregators which is practically impossible.