|
STLC - sign-time-locked-contracts |
|
|
|
In here we use the coinswap scheme from : |
|
https://joinmarket.me/blog/blog/coinswaps | Coinswap - with privacy |
|
|
|
And math from : |
|
https://github.com/oleganza/bitcoin-papers/blob/master/BitcoinBlindSignatures.md | Bitcoin Blind Signatures |
|
|
|
|
|
Two participants in this scheme. They'd like to perform an atomic swap of their coins : |
|
Bob - Blinder |
|
Sarah - Signer |
|
|
|
Setup stage |
|
----------- |
|
|
|
Bob and Sarah exchange pubkeys. Sarah's pubkeys are labeld as S, Bob's pubkeys are labeled as B. |
|
Bob sends three pubkeys to Sarah, (B1, B2, B3) |
|
Sarah sends three pubkeys to Bob, (S1, S2, S3) |
|
They also agree on locktimes to be used for backouts, (L0, L1), where L1 is closer than L0. |
|
Bob's locktime is L0 and Sarah's is L1, which means she gets to back out earlier. |
|
|
|
Sarah generates secret values (p, q) at random and computes two pubkeys : |
|
P = (1/p) * G |
|
Q = (q/p) * G |
|
# provide PoDLE here? |
|
|
|
|
|
Bob generates secret values (b, d) at random and computes two pubkeys : |
|
B = b * G |
|
D = d * G |
|
|
|
Bob and Sarah derive two shared secrets (a, c) together |
|
# ECDH? |
|
|
|
Bob and Sarah exchange the values (P, Q) and (B, D) |
|
|
|
|
|
Backout stage |
|
------------- |
|
|
|
Bob and Sarah will each compute the necessary values to for producing an ECDSA signature over a yet unspecified hash. |
|
|
|
Bob computes the point R, the public point of the nonce where the discrete log would be the value k : |
|
R = ( 1/(a*c) ) * P |
|
r = R_x |
|
|
|
Bob also computes the point T, which will be the pubkey used in the verification of the signature : |
|
T = ( 1/(a*c) ) * ( b*G + Q + (d/c)*P ) |
|
|
|
|
|
Sarah on her end computes the discrete log of R, the point R itself and the x coordinate of it, r : |
|
k = 1/(a*c*p) |
|
R = k * G |
|
r = R_x |
|
|
|
Sarah also computes the point T from her own values : |
|
T = ( k * (1/r) ) * ( (c*p)*B + (q*c)*G + D ) |
|
|
|
|
|
# Neither party does not know the discrete log 't' for T at this stage. |
|
|
|
They are both able to compute the following two scriptpubkeys : |
|
|
|
scr1 : 2 <B1> <S1> <S2 + T> 3 checkmultisig |
|
scr2 : 3 <B2> <B3> <S3> <T> 4 checkmultisig |
|
|
|
# only Sarah knows the private key for S2, her pubkey. |
|
|
|
|
|
Bob computes a backout address 'B_backout' |
|
Bob creates funding tx TX0 that pays scr1 but does not broadcast it, and sends Sarah the txid:index |
|
Bob creates a backout transaction TX2, 'TX0->B_backout', which redeems TX0 by solving scr1 |
|
Bob then asks Sarah for a signature by S1 for payment from TX2, redeeming scr1, nlocktime'd to L0 |
|
|
|
|
|
Sarah computes a backout address 'S_backout' |
|
Sarah creates funding tx TX1 that pays scr2 but does not broadcast it |
|
Sarah creates a backout transaction TX3, 'TX1->S_backout' which redeems TX1 by solving scr2 |
|
Sarah sends Bob a signature by S1 for TX2, nlocktime'd to L0 |
|
Also sends Bob txid:index of TX1 |
|
Sarah then asks Bob for a signature by (B2, B3) for payment from TX3, redeeming scr2, nlocktime'd to L1 |
|
|
|
|
|
Bob verifies the signature by S1. If valid.. |
|
Bob sends Sarah a signature by (B2, B3), for TX3, nlocktime'd to L1 |
|
|
|
|
|
Sarah verifies the signature by (B2, B3). If valid.. |
|
Sarah starts watching for TX0 |
|
Sarah broadcasts TX1 |
|
|
|
|
|
Bob watches the script TX1, if TX1 is spotted.. |
|
Bob broadcast TX0 |
|
|
|
|
|
If Sarah fails to see TX0, she waits for L1 to pass, signs TX3 with S3 and broadcasts |
|
If Sarah spots TX0, continue.. |
|
|
|
|
|
Blinding stage |
|
-------------- |
|
|
|
# At this stage, at any point, each party is able wait out their respective locktimes and back out if needed. |
|
|
|
Bob computes a swap address 'B_swap' |
|
Bob creates a swap transaction TX4 that pays him from Sarah's funding, 'TX1->B_swap' by solving scr2. |
|
Bob computes the sighash h1 : |
|
h1 = sighash(TX4) |
|
|
|
Bob then blinds the value h1 as h2 : |
|
h2 = a*h1 + h1 |
|
|
|
Bob then sends sarah h2 |
|
|
|
|
|
Sarah computes a value 's1', which is the blinded 's' value for a signature '(r, s)' over TX4 : |
|
s1 = p*h2 + q |
|
|
|
Sarah computes the point (h1*G) from known values, without knowledge of 'h1' itself : |
|
h1 * G = (1/a) * (h2*g - B) |
|
|
|
Sarah attempts to check that her blinded signature '(r, s1)' could be used to verify the message h1, using T as the pubkey : |
|
k * ( (c*s1)*G + D ) =? h1*G + r*T |
|
|
|
# At this stage Sarah basically signs "anything". |
|
# This previous check is designed to assure her that the point T, |
|
# the public nonce R, with 'r' and a message that would make for a point 'h1*G' |
|
# can make for a valid signature by a yet unknwon value 's2', where 's2*R', |
|
# which she simulates using 'k * ( (c*s1)*G + D )' |
|
|
|
If this check fails or Bob becomes unresponsive, she backs out using TX3 (same as above) |
|
If the check passes, Sarah continues.. |
|
|
|
Sarah creates a swap transaction TX5 that pays her from Bob's finding, 'TX0->S_swap' by solving scr1 |
|
Sarah then sends Bob the value s1 |
|
|
|
|
|
Swap stage |
|
---------- |
|
|
|
Bob unblinds s1 to produce a value s2 for a valid signature '(r, s2)' over TX4 : |
|
s2 = (c*s1) + d |
|
|
|
Bob then validates the signature using his known values ((r, s2), h1, T) : |
|
s2*R = h1*G + r*T |
|
|
|
If this check fails, he waits for L0 to pass, signs TX2 with B1 and broadcasts |
|
If the check passes, Bob signs TX4 with B2 and broadcasts it immediatelly |
|
|
|
|
|
Sarah is already watching her own TX1. As it is redeemed, she learns (s2, h1) |
|
Sarah then computes the discrete log 't' for the point T : |
|
t = (1/r) * ( s2*k - h1 ) |
|
|
|
Sarah then signs TX5 with (S1, (S2 + T)) and broadcasts it immediatelly |
|
|
|
|
|
# Sarah is unable to redeem her own TX1 at this point even by knowing t, |
|
# because scr2 requires 3 signatures of 4 pubkeys. |