Jeremy [ARCHIVE] on Nostr: π Original date posted:2021-07-10 π Original message: Last thought: suppose you ...
π
Original date posted:2021-07-10
π Original message:
Last thought:
suppose you make a Taproot tree with N copies (with different keys) of the
state update protocol.
Then what you can do is use the 1st copy until you hit MAX_STATE, and then
start signing with the 2nd copy back an state 0 but when you sign with the
2nd copy you *remove* the 1st copy from the taproot tree.
e.g.,
{A:0, B:0, C:0} -> {A:1, B:0, C:0} -> {A:MAX, B:0, C:0} -> {B:1, C:0}...
Then the cut-thru transition
{A:0, B:0, C:0} -> {B:1, C:0}
is valid, but the regression:
{B:N, C:0} -> {A:M, B:0, C:0} is not.
You can take a random path through which leaf you are using which, if
you're careful about how you construct your scripts (e.g., keeping the
trees the same size) you can be more private w.r.t. how many state updates
you performed throughout the protocol (i.e., you can see the low order bits
in the CLTV clause, but the high order bits of A, B, C's relationship is
not revealed if you traverse them in a deterministically permuted order).
The space downside of this approach v.s. the approach presented in the
prior email is that the prior approach achieves 64 bits with 2 txns one of
which should be like 150 bytes, a similar amount of data for the script
leaves may only gets you 5 bits of added sequence space.
--
@JeremyRubin <https://twitter.com/JeremyRubin>
<https://twitter.com/JeremyRubin>
On Sat, Jul 10, 2021 at 4:25 PM Jeremy <jlrubin at mit.edu> wrote:
> on further reflection, i think you can get around the restriction of CSV
> by signing a eltoo "trampoline".
>
> essentially, begin a burst session at pk1:N under pk2, but always include
> a third branch to go to any pk1:N+1.
>
> The scripts look like:
>
> Eltoo Layer 1 Regular at state i = N<<32:
> Or(And(After(N+1), Key(PK_u1)), And(Older(2016), Key(PK_s_i))
>
> Eltoo Layer 1 During Burst at state i = (N<<32) + M:
> Or(And(After(N+1), Key(PK_u1)), Key(PK_s_burst_N == PK_s_i))
>
> Eltoo Layer 2 During Burst at state i = (N<<32) + M:
> Or(And(After(N+1), Key(PK_u1)), And(After(M+1), Key(PK_u_burst_N)),
> And(Older(2016), Key(PK_s_i))
>
> i represents the 64 bit concatenation of two 32 bit locktimes, where N is
> MSBs and M is LSBs.
>
> During burst mode resolving on chain, either:
> 1) the published Layer 1 tx is at the tip state N
> a) The tip N is at inner tip state M, wait 2016 to close with
> And(Older(2016), Key(PK_s_i))
> b) The tip N is at inner tip state M - c, use path And(After(M+1),
> Key(PK_u_burst_N)) to jump to case 1.a
> 2) published Layer 1 tx is at non tip state N - c
> a) Layer 2 does not get published: use path And(After(N+1),
> Key(PK_u1)) to jump back to newest state known on parent, repeat from top
> b) Layer 2 gets published: use path And(After(N+1), Key(PK_u1)) to
> jump back to newest state known on parent, repeat from top
>
>
> This trampoline pattern should essentially be repeatable as many times as
> needed, although I think 2 layers is likely enough in practice.
>
> In terms of "state management", it grows at O(layers) but is otherwise
> constant. A node must only store:
>
> Key/Sigs for
> PK_s_i: to allow closing at the highest reachable state
> PK_u1
> During burst:
> PK_u_burst_N: to allow getting to current burst
> PK_s_burst_N: the same as PK_s_i just makes sense to think of it's
> distinct purpose from PK_s_i not requiring a sequence lock
>
> Note that the above scripts can be optimized to remove the Older clause as
> it can be a rule that all PK_s_i must sign with a sequence unless entering
> a burst.
> --
> @JeremyRubin <https://twitter.com/JeremyRubin>
> <https://twitter.com/JeremyRubin>
>
>
> On Sat, Jul 10, 2021 at 2:07 PM Jeremy <jlrubin at mit.edu> wrote:
>
>> Let's say you're about to hit your sequence limits on a Eltoo channel...
>> Do you have to go on chain?
>>
>> No, you could do a continuation where for your *final* update, you sign a
>> move to a new update key. E.g.,
>>
>> start at: IF "N+1" CLTV DROP <pk_u> CHECKSIG ELSE 2016 CSV DROP <pk_s_i>
>> CHECKSIG ENDIF
>>
>> before N+1 = last, sign a txn with pk_s_last that moves coins to
>>
>> IF "1" CLTV DROP <*pk_u**2*> CHECKSIG ELSE 2016 CSV DROP <pk_s_i>
>> CHECKSIG ENDIF
>>
>> This essentially lets you do 32 bits worth of updates and then fwd to a
>> new contract by paying 1x extra transaction.
>>
>> This is potentially better than just directly closing because we keep it
>> off chain for longer. However... this also adds an additional CSV.
>>
>> (We can get around this by modifying the script branch which ends a CLTV
>> domain with:
>> <pk_s_last> CHECKSIG
>> since any updates past that point are done through the continuation
>> state... but let's ignore that for the next part)
>>
>> What if we *always* used this every update? Then we'd essentially have 64
>> bits of sequence space. Each layer of this trick adds 32 bytes.
>>
>> Doing layers like this inherently adds a bunch of CSV layers, so it
>> increases resolution time linearly.
>>
>> One possibility to mitigate this is to do a "semitrusted burst mode" with
>> a counterparty. Suppose you're at sequence M and it's a normal txn.
>>
>> Party A requests to Party B to initiate burst mode. A and B move to
>> sequence M+1 where state M+1 passes through to a 2 step Eltoo update.
>>
>> This burst now has 32 bits of sequences to blow through.
>>
>> B or A then indicates to the other party to terminate the burst at
>> "internal state number" Q. Then B and A sign M+2 where M+2 reflects the
>> last state at internal state number Q. This gets rid of the temporary extra
>> locking time for when parties are offline.
>>
>> This has a benefit for privacy as well because if this protocol is used,
>> then top level state numbers do not reflect the # of payments strongly as
>> they're more akin to how many burst mode payments were done.
>>
>> The semi trusted nature of this is that if a malicious peer induces you
>> into starting this, you double your funds lockup time. There are some
>> mitigations:
>>
>> 1) Only enter burst mode with long lived peers
>> 2) Only enter burst mode when initiator has more funds in the channel
>> than you (or has some ratio) which imposes an opportunity cost for
>> attacking.
>> 3) Only allow a certain % of liquidity to be moved during a burst --
>> e.g., any time the delta in balance goes above a threshold, force a higher
>> order channel state update.
>>
>>
>>
>>
>> Best,
>>
>> Jeremy
>>
>>
>> --
>> @JeremyRubin <https://twitter.com/JeremyRubin>
>> <https://twitter.com/JeremyRubin>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20210710/fcb0610b/attachment.html>
π Original message:
Last thought:
suppose you make a Taproot tree with N copies (with different keys) of the
state update protocol.
Then what you can do is use the 1st copy until you hit MAX_STATE, and then
start signing with the 2nd copy back an state 0 but when you sign with the
2nd copy you *remove* the 1st copy from the taproot tree.
e.g.,
{A:0, B:0, C:0} -> {A:1, B:0, C:0} -> {A:MAX, B:0, C:0} -> {B:1, C:0}...
Then the cut-thru transition
{A:0, B:0, C:0} -> {B:1, C:0}
is valid, but the regression:
{B:N, C:0} -> {A:M, B:0, C:0} is not.
You can take a random path through which leaf you are using which, if
you're careful about how you construct your scripts (e.g., keeping the
trees the same size) you can be more private w.r.t. how many state updates
you performed throughout the protocol (i.e., you can see the low order bits
in the CLTV clause, but the high order bits of A, B, C's relationship is
not revealed if you traverse them in a deterministically permuted order).
The space downside of this approach v.s. the approach presented in the
prior email is that the prior approach achieves 64 bits with 2 txns one of
which should be like 150 bytes, a similar amount of data for the script
leaves may only gets you 5 bits of added sequence space.
--
@JeremyRubin <https://twitter.com/JeremyRubin>
<https://twitter.com/JeremyRubin>
On Sat, Jul 10, 2021 at 4:25 PM Jeremy <jlrubin at mit.edu> wrote:
> on further reflection, i think you can get around the restriction of CSV
> by signing a eltoo "trampoline".
>
> essentially, begin a burst session at pk1:N under pk2, but always include
> a third branch to go to any pk1:N+1.
>
> The scripts look like:
>
> Eltoo Layer 1 Regular at state i = N<<32:
> Or(And(After(N+1), Key(PK_u1)), And(Older(2016), Key(PK_s_i))
>
> Eltoo Layer 1 During Burst at state i = (N<<32) + M:
> Or(And(After(N+1), Key(PK_u1)), Key(PK_s_burst_N == PK_s_i))
>
> Eltoo Layer 2 During Burst at state i = (N<<32) + M:
> Or(And(After(N+1), Key(PK_u1)), And(After(M+1), Key(PK_u_burst_N)),
> And(Older(2016), Key(PK_s_i))
>
> i represents the 64 bit concatenation of two 32 bit locktimes, where N is
> MSBs and M is LSBs.
>
> During burst mode resolving on chain, either:
> 1) the published Layer 1 tx is at the tip state N
> a) The tip N is at inner tip state M, wait 2016 to close with
> And(Older(2016), Key(PK_s_i))
> b) The tip N is at inner tip state M - c, use path And(After(M+1),
> Key(PK_u_burst_N)) to jump to case 1.a
> 2) published Layer 1 tx is at non tip state N - c
> a) Layer 2 does not get published: use path And(After(N+1),
> Key(PK_u1)) to jump back to newest state known on parent, repeat from top
> b) Layer 2 gets published: use path And(After(N+1), Key(PK_u1)) to
> jump back to newest state known on parent, repeat from top
>
>
> This trampoline pattern should essentially be repeatable as many times as
> needed, although I think 2 layers is likely enough in practice.
>
> In terms of "state management", it grows at O(layers) but is otherwise
> constant. A node must only store:
>
> Key/Sigs for
> PK_s_i: to allow closing at the highest reachable state
> PK_u1
> During burst:
> PK_u_burst_N: to allow getting to current burst
> PK_s_burst_N: the same as PK_s_i just makes sense to think of it's
> distinct purpose from PK_s_i not requiring a sequence lock
>
> Note that the above scripts can be optimized to remove the Older clause as
> it can be a rule that all PK_s_i must sign with a sequence unless entering
> a burst.
> --
> @JeremyRubin <https://twitter.com/JeremyRubin>
> <https://twitter.com/JeremyRubin>
>
>
> On Sat, Jul 10, 2021 at 2:07 PM Jeremy <jlrubin at mit.edu> wrote:
>
>> Let's say you're about to hit your sequence limits on a Eltoo channel...
>> Do you have to go on chain?
>>
>> No, you could do a continuation where for your *final* update, you sign a
>> move to a new update key. E.g.,
>>
>> start at: IF "N+1" CLTV DROP <pk_u> CHECKSIG ELSE 2016 CSV DROP <pk_s_i>
>> CHECKSIG ENDIF
>>
>> before N+1 = last, sign a txn with pk_s_last that moves coins to
>>
>> IF "1" CLTV DROP <*pk_u**2*> CHECKSIG ELSE 2016 CSV DROP <pk_s_i>
>> CHECKSIG ENDIF
>>
>> This essentially lets you do 32 bits worth of updates and then fwd to a
>> new contract by paying 1x extra transaction.
>>
>> This is potentially better than just directly closing because we keep it
>> off chain for longer. However... this also adds an additional CSV.
>>
>> (We can get around this by modifying the script branch which ends a CLTV
>> domain with:
>> <pk_s_last> CHECKSIG
>> since any updates past that point are done through the continuation
>> state... but let's ignore that for the next part)
>>
>> What if we *always* used this every update? Then we'd essentially have 64
>> bits of sequence space. Each layer of this trick adds 32 bytes.
>>
>> Doing layers like this inherently adds a bunch of CSV layers, so it
>> increases resolution time linearly.
>>
>> One possibility to mitigate this is to do a "semitrusted burst mode" with
>> a counterparty. Suppose you're at sequence M and it's a normal txn.
>>
>> Party A requests to Party B to initiate burst mode. A and B move to
>> sequence M+1 where state M+1 passes through to a 2 step Eltoo update.
>>
>> This burst now has 32 bits of sequences to blow through.
>>
>> B or A then indicates to the other party to terminate the burst at
>> "internal state number" Q. Then B and A sign M+2 where M+2 reflects the
>> last state at internal state number Q. This gets rid of the temporary extra
>> locking time for when parties are offline.
>>
>> This has a benefit for privacy as well because if this protocol is used,
>> then top level state numbers do not reflect the # of payments strongly as
>> they're more akin to how many burst mode payments were done.
>>
>> The semi trusted nature of this is that if a malicious peer induces you
>> into starting this, you double your funds lockup time. There are some
>> mitigations:
>>
>> 1) Only enter burst mode with long lived peers
>> 2) Only enter burst mode when initiator has more funds in the channel
>> than you (or has some ratio) which imposes an opportunity cost for
>> attacking.
>> 3) Only allow a certain % of liquidity to be moved during a burst --
>> e.g., any time the delta in balance goes above a threshold, force a higher
>> order channel state update.
>>
>>
>>
>>
>> Best,
>>
>> Jeremy
>>
>>
>> --
>> @JeremyRubin <https://twitter.com/JeremyRubin>
>> <https://twitter.com/JeremyRubin>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20210710/fcb0610b/attachment.html>