[WITHDRAWN] Alternate script design for LNHANCE-Symmetry

WITHDRAWN

  • Let t = hashTapTweak(p || km).

You can’t back-calculate the internal key from the SPK and the script tree - would make taproot all in secure if that worked.

Original post

I blame Lisa.

I’m writing my deck for BTC++ and I think that there’s an alternate design for Lightning Symmetry channel scripts when specifically designed for use with LNHANCE instead of APO.

Basic background reading is Greg’s thread.

Scripts

For LNHANCE-Symmetry, we have the following script structures:

Channel outpoint

LNHANCE: tr(musig2(a, b), CTV INTERNALKEY CSFS)

APO: tr(musig(a, b), 1 CHECKSIG)

Update (tapleaves)

LNHANCE: tr(settlement-hash, {<n+1> CLTV DROP CTV musig2(a, b) CSFS, INTERNALKEY CTV})

APO: tr(musig(a, b), {<n+1> CLTV DROP 1 CHECKSIG, <settlement-sig> <G> CHECKSIG})

Update (OP_IF)

LNHANCE: tr(settlement-hash, DEPTH NOTIF INTERNALKEY CTV ELSE <n+1> CLTV DROP CTV musig2(a, b) CSFS ENDIF)

APO: tr(musig(a, b), DEPTH NOTIF <settlement-sig> <G> CHECKSIG ELSE <n+1> CLTV DROP 1 CHECKSIG ENDIF)

Discussion

In Greg’s APO-Symmetry design, the taproot annex is used to store the hash of the settlement transaction which was used to generate the settlement sig for the settlement transaction corresponding to the update transaction being signed. This ensures that if Alice publishes an update and Bob has a later update, he can recover the taproot sibling hash needed to spend Alice’s update.

In LNHANCE-Symmetry, the settlement transaction’s CTV hash can be ground to a valid X on the curve and then used as the internal key for the taproot output. This makes the tapscripts identical from update to update ensuring that either party can store O(1) data and be able to spend any prior update.

Witness sizes

Summary

Variant Initial update Subsequent update Settlement
APO-Symmetry (tapleaves) 137WU 176WU 168WU
APO-Symmetry (OP_IF) 137WU 249WU 149WU
LNHANCE-Symmetry (tapleaves) 136WU 207WU 69WU
LNHANCE-Symmetry (OP_IF) 136WU 149WU 83WU
weight calculations

APO-Symmetry:

Initial update

  • 33-byte annex
  • 33-byte control block
  • 2-byte script
  • 65-byte signature
  • Total: 4+33+33+2+65=137WU

Subsequent update (tapleaves)

  • 33-byte annex
  • 65-byte control block
  • 9-byte script
  • 65-byte signature
  • Total: 4+33+65+9+65=176WU

Settlement (tapleaves)

  • 65-byte control block
  • 66+33+1-byte script
  • Total: 2+65+(65+1+33+1+1)=168WU

Subsequent update (OP_IF)

  • 33-byte annex
  • 33-byte control block
  • 114-byte script
  • 65-byte signature
  • Total: 4+33+33+114+65=249WU

Settlement (OP_IF)

  • 65-byte control block
  • 114-byte script
  • Total: 2+33+114=149WU

LNHANCE-Symmetry

Initial update

  • 33-byte control block
  • 3-byte script
  • 32-byte hash
  • 64-byte signature
  • Total: 4+33+3+64+32=136WU

Subsequent update (tapleaves)

  • 65-byte control block
  • 42-byte script
  • 32-byte hash
  • 64-byte signature
  • Total: 4+65+42+64=207WU

Settlement (tapleaves)

  • 65-byte control block
  • 2-byte script
  • Total: 2+65+2=69WU

Subsequent update (OP_IF)

  • 33-byte control block
  • 48-byte script
  • 32-byte hash
  • 64-byte signature
  • Total: 4+33+48+64=149WU

Settlement (OP_IF)

  • 33-byte control block
  • 48-byte script
  • Total: 2+33+48=83WU

Conclusion?

Where a 32-byte hash can be used for settlement, there is a significant weight saving for Lightning Symmetry channels from overloading the taproot internal key with the settlement hash.

Edit: Added OP_IF variants

The APO-Symmetry OP_IF variant favors force closes that are not challenged significantly. It moderately reduces overall weight when a close is not challenged and significantly increases overall weight when it is challenged.

LNHANCE-Symmetry already favors non-challenged closes significantly, and the OP_IF variant reduces that. It slightly increases overall weight when a close is not challenged, and significantly reduces overall weight when it is challenged.

Which of these variants might be preferred when building production Lightning Symmetry depends on the relative importance they give to unchallenged force close weight vs. the cost of challenge when necessary.

Edit: not as great a savings when i properly include the ctv hash in the update witness stack. Sigh. OP_TEMPLATEHASH (or TXHASH) in tapscript only would improve the gains.

1 Like

Two things:

  • This is missing the <n> CLTV step that makes eltoo work
  • <settlement-sig> <G> CHECKSIG is just a more expensive way of doing <h> CTV; it’s not surprising that changing this to CTV makes it cheaper. I believe you can make it cheaper still by using scriptless scripts to reveal a signature instead of doing the CTV-ish approach.

I don’t think this works at all? If you grind the IPK, the scripts you end up with are something like:

  • <n+1> CLTV DROP musig(A,B) CHECKSIG
  • INTERNALKEY CTV

The scriptPubKey is then calculated as IPK + Hash(IPK, Hash(Hash(S1), Hash(S2))).

But to spend using the first path, you need the witness stack to contain IPK, Hash(S2), S1, signature. But to know what IPK is, you need to know what the settlement tx corresponding to this update tx is, and to redo the grinding. The ln-symmetry approach to solving that is just to stick it into the annex of the update tx that you’re looking to spend.

I think lnhance would be more efficient with an IF than two leafs, namely:

  • IFDUP IF <n> CLTV DROP CTV [musig2(a,b)] CSFS ELSE INTERNALKEY CTV ENDIF

which is always 48 bytes, versus 32+42 bytes (74 bytes) or 32+2 bytes (34 bytes).

I think that makes the comparison:

  • update tx spending funding tx:

    • ln-symmetry: 33B annex, 33B control block, 2B script, 65B signature (133B)
    • lnhance: 33B annex, 33B control block, 3B script, 64B signature, 32B ctv hash (165B)
  • update tx spending prior update tx:

    • ln-symmetry: 33B annex, 65B control block, 8B script, 65B signature (171B)
    • lnhance: 33B annex, 33B control block, 48B script, 64B signature, 32B ctv hash (210B)
  • settlement tx spending update tx:

    • ln-symmetry: 65B control block, 100B script (165B)
    • lnhance: 33B control block, 48B script (81B)

In normal use that’s 298B versus 246B, so a 52B advantage to lnhance. lnhance would be improved by another 32B if TXHASH was available rather than CTV for the “CTV CSFS” construct, equally, just using APO there would also save that much. ln-symmetry would be improved by 64B just by switching to CTV. Switching ln-symmetry to the scriptless script approach would save ~128B I think.

Hey AJ, thanks for your response!

Yep, left it out of both, so doesn’t change the comparison really.

Yeah, CTV+APO is even more efficient, I’m just comparing an APO-only or CTV+CSFS-only world.

Ah, but because the full script content is deterministic, you can compute the settlement hash / IPK by calculating the the taptweak (t) and then IPK=SPK-t*G. By moving the pieces around we solve the data availability problem.

Goddamnit, this doesn’t work at all. My cleverness defeated. You need to know the IPK to calculate the tweak - otherwise the whole taproot construction would be insecure (any script tree could spend any outpoint).

Yeah. That applies equally to both APO-Symmetry and LNHANCE-Symmetry, but in a real implementation it would indeed be advisable to use an IF instead of two tapleaves.

Ohhh!!! It doesn’t apply to both, because the APO settlement leaf is large enough that it makes updates worse. Nice. I’ll update OP.

A stray annex in this line

If it’s any consolation, pretty sure I said the same thing to insta when trying to improve ln-symmetry, for pretty much the same reason. My irc logs confirm: <_aj_> meh, that probably doesn't work, 2022-10-22 :headstone:

If you’re revealing the settlement tx hash via the annex, then that has to be included in the annex of any update tx, whether it spends the funding tx or a previous update tx. Otherwise, you wouldn’t be able to be sure you can spend that update tx to the latest update tx.

(If you restrict your protocol to 2-party channels, you can change the protocol to only be “A spends funding tx to update N; B spends update N to update N+K; A cannot spend update N+K to N+K+L”, in which case you could skip the annex in B’s spend)

1 Like