Dr. Mark B Lundeberg, 2018 July 13
bitcoincash:qqy9myvyt7qffgye5a2mn2vn8ry95qm6asy40ptgx2
Earlier this year I posted an advisory on a possible attack on certain cross-cryptocurrency atomic swap contracts. This time I'd like to discuss the anonymity problem of atomic swaps and how it can be simply mitigated.
Problem: The standard hash-based atomic swap leaves a very noisy fingerprint on
the blockchain, which 1) is obviously an atomic swap, and 2) includes a unique
unlock value k
. The same unique k
will be identical on both blockchains, so
any future blockchain analysis will be trivially able to link the two sides of
the swap. It would be nice if atomic swaps looked more like ordinary
transactions and did not have such an obvious linkage.
The Lightning payment channel network actually offers a solution to this, in
that the secret k
is unlikely to be published except in fallback. Here I'd
like to simplify this idea to bare-bones and explain how even for direct atomic
swaps, it's better to perform them using purpose-made ordinary payment
channels
(that do not even require a malleability fix). The advantages of these
SwapChannels over regular atomic swaps: more concealed, twice as fast to set
up, and ability for trustless high frequency trades. Disadvantage: ~5% more
blockchain cost.
- Notation
- Review: hash locked atomic swaps
- Review: unidirectional payment channels
- SwapChannels: hidden Atomic swaps in payment channels
- Analysis
- Footnotes
Rather than the bitcoin script in my previous post, it's more appropriate to use a diagrammatic representation this time. Arrows represent transactions, and boxes represent transaction outputs. To avoid cluttering the diagrams, change outputs will be omitted.
When a box has multiple arrows emanating from it, that means multiple alternative transactions that could occur (only one of these alternatives may be actually published onto the blockchain). Dashed arrows and boxes will be used to mark the parts that will not usually be published on chain, and thus remain secret.
The content of the box is the meaning of its script (smart contract), that is, which pieces are required to spend (unlock) the output. The text along an arrow denotes the pieces that are actually used to unlock the output. The following pieces are involved:
A
: a valid signature from a key owned by Alice.B
: a valid signature from a key owned by Bob.k
,k1
,k2
, etc.: a correct unlock value (a preimage of given size that reproduces a given hash).t1
: a fallback time t1 has expired. (this is used for guaranteed refunds)t2
: a fallback time t2 has expired. In all the examples below, t1 < t2 is required for security reasons.
A boolean expression like A & (B | t1)
would mean that Alice's signature is
required to spend, but additionally, either Bob must sign or time t1
must have passed.
For simplicity, a 1:1 exchange rate between cryptocurrencies is taken.
- Alice and Bob provide public keys each other. Alice generates secret
k
. - Alice funds PA.
- PA is published & confirmed on its blockchain.
- Bob funds PB, without yet knowing
k
. - PB is published & confirmed on its blockchain.
- Alice spends PB, thereby revealing
k
. - Bob now knows
k
and spends PA.
If the procedure breaks down before step 6, Bob waits until t1 to get his refund, then Alice gets her refund after t2.
- Bob sends a public key to Alice.
- Alice funds PC.
- PC is published & confirmed on blockchain.
- Alice creates a payment and signs it, then sends this incomplete transaction to Bob. (It cannot be published without Bob's signature.)
- Step 4 may be repeated any number of times, with incremental payments.
- To finalize, Bob takes the most recent payment, then signs and publishes it.
For these unidirectional payment channels, each of the payments must be incrementing in value, as Bob is free to publish the highest-value one he has seen. If Bob stops responding, then Alice can get back a full refund after time t1.
SwapChannels: hidden Atomic swaps in payment channels
*Summary: starts out like two ordinary payment channels but the off-chain payments are now atomic swap contracts.
- Alice and Bob provide public keys to each other.
- Alice and Bob fund payment channels to each other (PCA and PCB), on their respective blockchains.
- PCA and PCB are each published and confirmed on their respective blockchains.
- Alice generates secret
k1
and signs a payment that would produce output PA1, and sends this incomplete transaction to Bob. Bob does not sign yet. - Bob signs a payment that would produce output PB1, and sends this incomplete transaction to Alice. Alice does not sign yet, however she reveals
k1
to Bob, thereby locking in the swap.fn1 - Steps 4,5 may be repeated any number of times, with incrementing payments and new values
k2
,k3
, etc..fn1 - To finalize, Alice and Bob each sign and send each other an ordinary (non-hash-locked) payment with value equal to the previous payment. They then countersign and publish the results.
Under normal completion, the resultant appearance on each blockchain is that of a regular payment channel opening then closing, which makes each side significantly more difficult to link. As a fallback, the participants end up signing then publishing the hash-lock states created in steps 4,5.
(For simplicity: focussing on bitcoin script; neglecting change outputs; 71 byte DER signatures, 33 byte pubkeys, 34 byte txouts)
A regular Alice->Bob transaction costs ~190 bytes.
The normal atomic swap opening and closing costs ~470–510 bytes published onto each blockchain, depending on how efficiently the script is coded.fn2
A normal payment channel opening and closing costs ~500–550 bytes, depending on how efficiently the script is coded.fn2
For normal completion, the SwapChannel costs the same as a normal payment channel, i.e., ~500–550 bytes, per blockchain. If it completes abnormally (with hash locks published), then an additional transaction with cost of ~280–320 bytes will need to happen to move funds out of the hash locks.
Time cost: with SwapChannel, Alice's and Bob's payment channels need to be confirmed before any swaps take place, however both may start their channels at the same time. This is twice as fast as a regular atomic swap, where Alice's funding transaction must be confirmed before Bob can post his side, and Bob's transaction must be confirmed before Alice can complete the swap.
Nakamoto's original proposal for payment channels suggested an application in high-frequency trading. Unfortunately if regular payment channel procedures are used for cross-chain trading, one party could cheat by simply not reciprocating for the last payment and thereby steal some amount of funds.
Regular atomic swaps remove the ability to cheatfn3 but unfortunately are not at all suitable for high frequency trading, since the trading price would be baked in at the setup time -- at least 2 blockchain confirmations before the trade takes place. This is long enough that volatility would invalidate the initial pricing.
SwapChannels allows trustlessfn3 high-frequency atomic cross-cryptocurrency trades between two parties. The reason is that although it does require a setup, the price of trade is not fixed at the start. Actual trades can then occur with the instantaneous trading price.
It is interesting to consider what are the incentives of each party to provide a final exit transaction to the other party, in the last step of SwapChannel. Obviously if both fail to do this, then the punishment is having a publicly visible fingerprint of the atomic swap that directly links the parties, which is undesirable for both.
Let's say that Bob goes first, providing Alice with a normal exit. Alice might simply refuse to reciprocate, which would mean that that Bob would have to publish the version with hash lock and then also pay an additional transaction fee to gain full control (see Costs). There is also a small moral hazard in this case: Alice could demand a tiny ransom for providing Bob a normal exit, by slightly reducing the exit payment offered to him.
That said, a withholding Alice would not be entirely free of penalty: it would be revealed Alice had sent money into an atomic swap, which encourages a search for a correlated payment channel and may reveal her newly acquired funds.
In the SwapChannel protocol, there is not direct linkage, however there is still the possibility of a weaker correlation linkage, due to similar-valued payment channels opening and closing at similar times on different blockchains.
For this purpose it is helpful to introduce atomic multi-swaps. Alice and Bob
can create multiple payment channels to each other (on multiple
cryptocurrencies if they wish). For security, Alice's channels must each expire
after all of Bob's channels would expire. In each swap, Alice can offer a
bouquet of payments of varying value on each channel, but all with the same
hash lock k
. Bob can reply with another bouquet under the same hash lock.
Once Alice provides k
the swap is locked in. The two bouquets do not need to
have identical ratios, only similar-valued totals.
By staggering the opening and closing times, as well as using multi-channel swaps to obfuscate the total value, the channels will become less obviously correlated. If there is a background of many payment channels opening and closing on each blockchain, then it could be made quite difficult to detect that a swap has occurred. Such a multichannel strategy might even be useful for swaps within a single cryptocurrency, being used to break the link in blockchain analysis.
fn1: If Alice used the same k
for all payment states, Bob could
trick her by not reciprocating after her last payment, which forces her to
choose between taking a loss (Alice publishes PBN-1 onto the
blockchain, after which Bob knows k
and gets PAN) or to withhold
k
and wait for a complete refund. Likewise, Bob may play fair but Alice could
decide to undo all the swaps by simply not revealing k
at the end. Instead
Alice should reveal k
after each swap, which locks it in (Bob can now redeem
the payment at any time he wishes). Since it is revealed, Alice must of course
choose a new secret k
for the next round, which also neatly prevents Bob from
playing the aforementioned trick. Fortunately, the participants need only
remember the most recent (highest-valued) locked-in state and its k
value.
fn2: Bitcoin P2SH script sizes can vary depending on whether the address is entered as a 20-byte hash in the P2SH script, or directly as the 33-byte public key. The former option requires three more opcodes (DUP HASH160 EQUALVERIFY) and the 33-byte public key (+1 more byte PUSH) must anyway be placed in the scriptSig, meaning that the former option adds 24 unnecessary bytes. Likewise, the atomic swap secret sizes and hash-secret sizes are completely secure at 16 and 20 bytes respectively but some choose to use 32 and 32 bytes instead -- adding 29 unnecessary bytes (16 + 12 + 1 byte extra in the secret size check).
fn3: With all atomic swap protocols (including SwapChannels), there
appears to be a weaker hazard, in that Alice may request a trade and then fail
to promptly provide k
to Bob, which lets her unilaterally put off the choice
of either taking the trade, or to wait for refund time and not take the trade
at all. In other words, Bob is actually providing Alice a short term financial
option for free (after
t1 she loses the option). With SwapChannels, a distrusting Bob
should take advantage of payment channel structure, by gradually build up the
swap in small increments. At worst she can now only withhold k
on the last
increment, keeping a tiny option value at the cost of locking up all of her
funds in the channel.
Version 2 posted: stressed importance of using a new k value for each swap within a payment channel (and updated figure appropriately), after reddit discussion with Andrew Stone.