<div dir="ltr"><p class="inbox-inbox-p1"><span class="inbox-inbox-s1">Hi </span><span class="inbox-inbox-s2">ZmnSCPxj,</span><span class="inbox-inbox-s1"><br></span><br>&gt; Can you describe the &quot;encrypted blob&quot; approach to me? Or point me to<br>&gt; materials?<br><br>There&#39;s an awesome watchtower thread on the mailing list from 2016 that starts<br>here [1]. It covers a broader range of possibilities than just the encrypted<br><span class="inbox-inbox-s1">blob approach, and also considers other revocation schemes, e.g. </span><span class="inbox-inbox-s2">elkrem</span><span class="inbox-inbox-s1">.<br><br>Similar to what you described, one encrypted blob approached discussed in<br>that thread is:<br></span><span class="inbox-inbox-s1">1. </span><span class="inbox-inbox-s2">hint</span><span class="inbox-inbox-s1"> = </span><span class="inbox-inbox-s2">tixd</span><span class="inbox-inbox-s1">[:16]<br></span><span class="inbox-inbox-s1">2. </span><span class="inbox-inbox-s2">blob</span><span class="inbox-inbox-s1"> = Enc(data, </span><span class="inbox-inbox-s2">txid</span><span class="inbox-inbox-s1">[16:])<br></span>3. Send (hint, blob) to watchtower.<br><br>Whenever a new block is mined, the watchtower checks if it has an entry for each<br><span class="inbox-inbox-s2">txid</span><span class="inbox-inbox-s1">[:16]. If so, it </span><span class="inbox-inbox-s2">decrypts</span><span class="inbox-inbox-s1"> using </span><span class="inbox-inbox-s2">txid</span><span class="inbox-inbox-s1">[16:], assembles the justice </span><span class="inbox-inbox-s2">txn</span><span class="inbox-inbox-s1">, and<br></span>broadcasts (assuming the reward output matches what was negotiated).<br><span class="inbox-inbox-s1"><br>&gt; Do you have a description of the </span><span class="inbox-inbox-s2">WatchTower</span><span class="inbox-inbox-s1"> protocol used in </span><span class="inbox-inbox-s2">lnd</span><span class="inbox-inbox-s1">? It may be<br></span><span class="inbox-inbox-s1">&gt; useful to be </span><span class="inbox-inbox-s2">intercompatible</span><span class="inbox-inbox-s1">.<br></span><br>We don&#39;t have anything written up formally, though what we have currently<br>operates on the design above.<br><br>There are more complex proposals discussed allowing an encrypted blob to<br>reference data stored in a prior encrypted blob. Primary advantage would be<br><span class="inbox-inbox-s1">reducing the storage costs of </span><span class="inbox-inbox-s2">HTLCs present on multiple successive<br>commitment transactions</span><span class="inbox-inbox-s1">; primary disadvantage is that </span>it&#39;s significantly more<br>complex, in addition to the other points brought up by Laolu.</p><p class="inbox-inbox-p1">I&#39;m not positive as to the extent this approach was implemented/fleshed out, or<br>if any other pros/cons may have been realized in the process. I haven&#39;t done<br>nearly as much research as Tadge on that front, he&#39;s probably got some<br>extensive thoughts on the tradeoffs.</p><p class="inbox-inbox-p1">=======</p><p class="inbox-inbox-p1">I&#39;ll also take this time to brain dump some recent investigations I&#39;ve been doing on<br>watchtowers. TL;DR @ fin.<br></p><p class="inbox-inbox-p1">FWIW, I&#39;ve been thinking about this in the context of the simple encrypted<br>blob approach, though the observations can generalize to other schemes.</p><p class="inbox-inbox-p1"><span class="inbox-inbox-s1">As </span><span class="inbox-inbox-s2">Laolu</span><span class="inbox-inbox-s1"> mentioned, the storage requirement for the watchtower is dominated by<br></span><span class="inbox-inbox-s1">the number of </span><span class="inbox-inbox-s2">HTLC</span><span class="inbox-inbox-s1"> signatures included in the encrypted blob. Due to<br></span><span class="inbox-inbox-s1">independence of the second stage transactions, there is a </span><span class="inbox-inbox-s2">combinatoric</span><span class="inbox-inbox-s1"> blowup in<br></span><span class="inbox-inbox-s1">the number of signatures that would need to be </span><span class="inbox-inbox-s2">pre</span><span class="inbox-inbox-s1">-signed under the revocation<br></span>private key _if sweeping of HTLC outputs is batched_.<br><br>If we want to batch sweep without more liberal sighash flags, I think we&#39;d need to<br>pre-sign n*2^n signatures. There are 2^n <span class="inbox-inbox-s1">possible ways that n HTLCs can straddle<br>the first and second stages, and each permutation would require n distinct signatures<br>since the set of inputs is unique to each permutation. Needless to say, this isn&#39;t feasible<br>with the maximum number of </span><span class="inbox-inbox-s2">HTLCs </span>allowed in the protocol.</p><p class="inbox-inbox-p1">However, I have some observations that might inform an efficient set of<br>signatures we can choose to include in the encrypted blobs.</p><p class="inbox-inbox-p1"><span class="inbox-inbox-s1">The first is that the </span><span class="inbox-inbox-s2">HTLC</span><span class="inbox-inbox-s1"> timeout or </span><span class="inbox-inbox-s2">HTLC</span><span class="inbox-inbox-s1"> success transaction _must_ be<br></span>broadcast before the attacker can move funds back into their wallet. If<br>these transactions are never mined, it is actually fine to do nothing and leave<br>those outputs in the breached state.<br><br>If/when the victim comes back online, they themselves can sign and broadcast<br>a justice transaction that executes the revocation clause of either the offered or<br><span class="inbox-inbox-s1">received </span><span class="inbox-inbox-s2">HTLC</span><span class="inbox-inbox-s1"> scripts, based on the observed </span><span class="inbox-inbox-s2">spentness</span><span class="inbox-inbox-s1"> of the various commitment<br></span><span class="inbox-inbox-s2">HLTC</span><span class="inbox-inbox-s1"> outputs at that time. So, we can save on signature data by only requiring the<br></span>watchtower to act if second stage transactions are confirmed.</p><p class="inbox-inbox-p1"><span class="inbox-inbox-s1"><span class="inbox-inbox-inbox-inbox-s1">One </span><span class="inbox-inbox-inbox-inbox-s2"><span class="inbox-inbox-gr_ inbox-inbox-gr_2835 inbox-inbox-gr-alert inbox-inbox-gr_spell inbox-inbox-gr_inline_cards inbox-inbox-gr_run_anim inbox-inbox-ContextualSpelling inbox-inbox-ins-del inbox-inbox-multiReplace" style="display:inline;border-bottom:2px solid transparent;background-repeat:no-repeat;color:inherit;font-size:inherit">reallyyy</span></span><span class="inbox-inbox-inbox-inbox-s1"> nice thing about not having the watchtower sweep the </span><span class="inbox-inbox-inbox-inbox-s2">HTLC</span><span class="inbox-inbox-inbox-inbox-s1"> outputs<br></span><span class="inbox-inbox-inbox-inbox-s1">on the commitment </span><span class="inbox-inbox-inbox-inbox-s2"><span class="inbox-inbox-gr_ inbox-inbox-gr_77 inbox-inbox-gr-alert inbox-inbox-gr_spell inbox-inbox-gr_inline_cards inbox-inbox-gr_run_anim inbox-inbox-ContextualSpelling" style="display:inline;border-bottom:2px solid transparent;background-repeat:no-repeat;color:inherit;font-size:inherit">txn</span></span><span class="inbox-inbox-inbox-inbox-s1"> directly is that it doesn&#39;t need to know how to<br></span><span class="inbox-inbox-inbox-inbox-s1">reconstruct the more complex </span><span class="inbox-inbox-inbox-inbox-s2">HTLC</span><span class="inbox-inbox-inbox-inbox-s1"> redeem scripts. It only needs to reconstruct<br></span>commitment <span class="inbox-inbox-gr_ inbox-inbox-gr_1315 inbox-inbox-gr-alert inbox-inbox-gr_spell inbox-inbox-gr_inline_cards inbox-inbox-gr_run_anim inbox-inbox-ContextualSpelling inbox-inbox-ins-del" style="display:inline;border-bottom:2px solid transparent;background-repeat:no-repeat">to-local</span> and second-stage to-local scripts and witnesses. This means<br>the blob primarily contains:<br><span class="inbox-inbox-inbox-inbox-s1"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>- 1 revocation </span><span class="inbox-inbox-inbox-inbox-s2"><span class="inbox-inbox-gr_ inbox-inbox-gr_88 inbox-inbox-gr-alert inbox-inbox-gr_spell inbox-inbox-gr_inline_cards inbox-inbox-gr_run_anim inbox-inbox-ContextualSpelling" style="display:inline;border-bottom:2px solid transparent;background-repeat:no-repeat;color:inherit;font-size:inherit">pubkey</span><br></span><span class="inbox-inbox-inbox-inbox-s1"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>- 1 local delay </span><span class="inbox-inbox-inbox-inbox-s2"><span class="inbox-inbox-gr_ inbox-inbox-gr_92 inbox-inbox-gr-alert inbox-inbox-gr_spell inbox-inbox-gr_inline_cards inbox-inbox-gr_run_anim inbox-inbox-ContextualSpelling" style="display:inline;border-bottom:2px solid transparent;background-repeat:no-repeat;color:inherit;font-size:inherit">pubkey</span><br></span><span class="inbox-inbox-inbox-inbox-s1"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>- 1 </span><span class="inbox-inbox-inbox-inbox-s2">CSV</span><span class="inbox-inbox-inbox-inbox-s1"> delay<br> - 2 commitment signatures<br></span><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>- n HTLC signatures<br><span class="inbox-inbox-inbox-inbox-s1">and we don&#39;t have to bother sending </span><span class="inbox-inbox-inbox-inbox-s2">CLTVs, local/remote htlc pubkeys,</span><span class="inbox-inbox-inbox-inbox-s1"> or <br></span></span>payment hashes at all.<br><br>The storage for this ends up being something like ~100 + 64*(2+nhtlcs) when you<br>include other things like the sweep address.</p><p class="inbox-inbox-p1">The second observation is that the second stage transactions could be broadcast<br><span class="inbox-inbox-s1">sequentially such that the </span><span class="inbox-inbox-s2">CSV</span><span class="inbox-inbox-s1"> delays don&#39;t overlap at all. In this event, the<br></span>watchtower needs to sweep the HTLCs iteratively to prevent the attacker from<br>sweeping any of the outputs as the relative timelocks expire.</p><p class="inbox-inbox-p1"><span class="inbox-inbox-s1">One minimal </span>solution could be to send signatures for independent sweep<br>transactions, allowing <span class="inbox-inbox-s1">the watchtower to sweep each </span><span class="inbox-inbox-s2">HTLC</span><span class="inbox-inbox-s1"> output individually.<br>This is nice because it </span><span class="inbox-inbox-s1">permits the watchtower to sweep exactly the subset of<br></span><span class="inbox-inbox-s2">HTLCs</span><span class="inbox-inbox-s1"> that ever transition </span><span class="inbox-inbox-s1">into the second stage, and under any permutation<br></span><span class="inbox-inbox-s2">wrt</span><span class="inbox-inbox-s1">. </span><span class="inbox-inbox-s2">ordering </span>of confirmed second stage transactions.</p><p class="inbox-inbox-p1"><span class="inbox-inbox-s1">With the single transaction per </span><span class="inbox-inbox-s2">HTLC</span><span class="inbox-inbox-s1"> approach, the total number of signatures that<br></span><span class="inbox-inbox-s1">are sent to the watchtower remains linear in the number </span><span class="inbox-inbox-s2">HTLCs</span><span class="inbox-inbox-s1"> on the commitment<br></span>transaction. This approach does have the downside of consuming slightly more<br>fees, since each output is swept with a distinct transaction.</p><p class="inbox-inbox-p1">However, this approach is fairly efficient in preventing the attacker entirely from<br>moving funds from the channel into their wallet wrt. to the amount of data stored.<br>Considering that the majority of the<span class="inbox-inbox-Apple-converted-space"> </span>channel balance is expected to be in<br>the commitment outputs and that hypothetically on-chains fees are offset by the<br>remote balance, this could be an <span class="inbox-inbox-s1">acceptable </span><span class="inbox-inbox-s2">tradeoff</span><span class="inbox-inbox-s1">.</span></p><p class="inbox-inbox-p1">I suspect that in practice, most second stage transactions will be valid by the<span class="inbox-inbox-Apple-converted-space"> <br></span>time an attacker would drop to chain. Because of this, it&#39;s possible that they<br>could be mined in the same block as the breach transaction.<br><br>If everything is mined in the same block or in quick succession, it might be<br><span class="inbox-inbox-s1">worthwhile to also </span><span class="inbox-inbox-s2">pre</span><span class="inbox-inbox-s1">-sign a justice </span><span class="inbox-inbox-s2">txn</span><span class="inbox-inbox-s1"> that batch sweeps all </span><span class="inbox-inbox-s2">HTLCs</span><span class="inbox-inbox-s1"> directly<br></span><span class="inbox-inbox-s1">from the second layer, requiring one additional signature/</span><span class="inbox-inbox-s2">HTLC</span><span class="inbox-inbox-s1">.<span class="inbox-inbox-Apple-converted-space"> <br></span></span><br>This could be a plausible scenario if the offender breached unintentionally, and<span class="inbox-inbox-Apple-converted-space"> <br></span>their implementation tries to proceed normally. However it does require all of the<span class="inbox-inbox-Apple-converted-space"><br></span><span class="inbox-inbox-s2">CSV</span><span class="inbox-inbox-s1"> delays to conincide. If that doesn&#39;t happen, the watchtower can always<br></span>resort to sweeping the outputs individually.<br><span class="inbox-inbox-s1"><br>All in all, I think the ability to sweep each </span><span class="inbox-inbox-s2">HTLC</span><span class="inbox-inbox-s1"> independently is more-or-less<br></span>a requirement just given the complexity of how the on-chain state-space can<span class="inbox-inbox-Apple-converted-space"> <br></span>manifest, especially if CLTVs have already expired. Other scenarios may<br>be worth including on a case by case basis or if we feel they are justified. This<br>could be handled dynamically by including some <span class="inbox-inbox-s2">bitvector</span><span class="inbox-inbox-s1"> or some compact<br>representation of how to reconstruct the transactions </span>for any additional, included<br>signatures.<br><br>TL;DR: We can get away with just sweeping the second stage outputs. Sweeping<br>each in a distinct <span class="inbox-inbox-inbox-inbox-gr_ inbox-inbox-inbox-inbox-gr_12344 inbox-inbox-inbox-inbox-gr-alert inbox-inbox-inbox-inbox-gr_spell inbox-inbox-inbox-inbox-gr_inline_cards inbox-inbox-inbox-inbox-gr_run_anim inbox-inbox-inbox-inbox-ContextualSpelling" style="display:inline;border-bottom:2px solid transparent;background-repeat:no-repeat"><span class="inbox-inbox-gr_ inbox-inbox-gr_12837 inbox-inbox-gr-alert inbox-inbox-gr_spell inbox-inbox-gr_inline_cards inbox-inbox-gr_run_anim inbox-inbox-ContextualSpelling" style="display:inline;border-bottom:2px solid transparent;background-repeat:no-repeat;color:inherit;font-size:inherit">txn</span></span> avoids combinatoric blowup of trying to batch the sweeps. The<br>storage is linear in the number of HTLC outputs, and also reduces the data required<br>to reconstruct the individual redeem scripts.<br><br>Any feedback or additional insights would be greatly appreciated! Let me know if<br>I&#39;ve overlooked anything critical :)</p>
<p class="inbox-inbox-p1"><span class="inbox-inbox-s1">Cheers,<br></span>Conner<br><span class="inbox-inbox-s1"><br>[1] </span><span class="inbox-inbox-s2">https</span><span class="inbox-inbox-s1">://lists.</span><span class="inbox-inbox-s2">linuxfoundation</span><span class="inbox-inbox-s1">.org/</span><span class="inbox-inbox-s2">pipermail</span><span class="inbox-inbox-s1">/lightning-</span><span class="inbox-inbox-s2">dev</span><span class="inbox-inbox-s1">/2016-August/000565</span><span class="inbox-inbox-s3">.</span><span class="inbox-inbox-s4">html</span></p><p class="inbox-inbox-p2"><span class="inbox-inbox-s1"></span></p></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Apr 16, 2018 at 11:30 PM ZmnSCPxj via Lightning-dev &lt;<a href="mailto:lightning-dev@lists.linuxfoundation.org">lightning-dev@lists.linuxfoundation.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Good morning Laolu,<br></div><div><br></div><div> <br></div><blockquote type="cite" class="m_4547236658408903723protonmail_quote"><div dir="ltr"><div>Hi ZmnSCPxj, <br></div><div><br></div><div>&gt; It seems to me, that the only safe way to implement a trustless WatchTower,<br></div><div>&gt; is for the node to generate a fully-signed justice transaction, IMMEDIATELY<br></div><div>&gt; after every commitment transaction is revoked, and transmit it to the<br></div><div>&gt; WatchTower.<br></div><div><br></div><div>No, one doesn&#39;t need to transmit the entire justice transaction. Instead,<br></div><div>the client simply sends out the latest items in the script template, and a<br></div><div>series of _signatures_ for the various breach outputs. The pre-generated<br></div><div>signature means that the server is *forced* to reproduce the justice<br></div><div>transaction that satisfies the latest template and signature. Upfront, free<br></div><div>parameters such as breach bonus (or w/e else) can be negotiated.<br></div></div></blockquote><div><br></div><div>Thank you, I understand.<br></div><div><br></div><blockquote type="cite" class="m_4547236658408903723protonmail_quote"><div dir="ltr"><div>As a result of these downside, our current implementation goes back to the<br></div><div>ol&#39; &quot;encrypted blob&quot; approach. One immediate benefit with this approach is<br></div><div>that the outsourcing protocol isn&#39;t so coupled with the current _commitment<br></div><div>protocol_. Instead, the internal payload can be typed, allowing the server<br></div><div>to dispatch the proper breach protocol based on the commitment type. The<br></div><div>blob approach can also support a &quot;swap&quot; protocol which is required for<br></div><div>commitment designs that allow for O(1) outsourcer state per-client, like the<br></div><div>scheme I presented at the last Scaling Bitcoin.<br></div></div></blockquote><div><br></div><div>Can you describe the &quot;encrypted blob&quot; approach to me? Or point me to materials?<br></div><div><br></div><div>I imagine that in this case, the protected node hands a (txid, blob) pair to the WatchTower.  If the WatchTower sees a transaction that matches the given txid, it gets some information from the actual transaction to decrypt the blob (e.g. use the encrypted commitment index in `nLockTime` and `nSequence` as a decryption key); the blob is the justice transaction (or just a template type and its signatures as you describe above).<br></div><div><br></div><div>Do you have a description of the WatchTower protocol used in lnd? It may be useful to be intercompatible.<br></div><div><br></div><div>Regards,<br></div><div>ZmnSCPxj<br></div>_______________________________________________<br>
Lightning-dev mailing list<br>
<a href="mailto:Lightning-dev@lists.linuxfoundation.org" target="_blank">Lightning-dev@lists.linuxfoundation.org</a><br>
<a href="https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev" rel="noreferrer" target="_blank">https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev</a><br>
</blockquote></div>