CTV+CSFS: Can we reach consensus on a first step towards covenants?

Also the core-devs has put a “regtest” label on the PR, can I see thr opcodes running on something like mempool.space?

regtest means you can only use it on your own computer on a private blockchain.

lol, atleast let me run on some test net that we all can view through mempool space UI.

Has anyone actually published a branch that has both CTV+CSFS? From skimming through this topic I don’t see one. It would be nice to have one on top of the major latest release of bitcoin core for integration testing the 2 opcodes together.

Good point. Greg has a PR to introduce CSFS to inquisition. This is in effect a branch with both CTV+CSFS. It’s worth noting nobody bothered reviewing it in the past 3 months.

I think the @RobinLinus and @ajtowns interactions on the BitVM & CTV+CSFS thread illustrates the subtle foot guns that come with OP_CTV as an OP_NOP and OP_SUCCESS. I don’t think I would have caught this subtle vulnerability that comes with supporting legacy Script.

This interaction occurred after the posts on this thread arguing about OP_NOP support, so I feel like its worthwhile to highlight it here.

It seems like this could be worked around since OP_CTV does commit to the scriptSig according to instagibbs

However this seems rather unpleasant.

I think Jeremy Rubin is conceding the point that at least for p2sh OP_CTV is broken?

Which leaves us with only spending “raw”/“bare” outputs to be able to commit to meaningful data in the scriptSig with CTV.

Is the juice really worth the squeeze for committing to scriptSig data?

1 Like

I’ve come to see this capability of CTV (committing to other prevouts in very round-about way) as an anti-feature, an unexpected capability that is so sharp-edged that if it’s something we want we should explicitly design for it instead to discourage such bizarre usage.

Alternatively we could remove the capability by making non-empty scriptSigs fail the script execution. This of course only makes sense in a post-segwit world only which I’ve already advocated above as a taproot-only push opcode.

4 Likes

This of course only makes sense in a post-segwit world only which I’ve already advocated above as a taproot-only push opcode.

@instagibbs If a taproot-only push opcode is the way to go, would it make sense to introduce a new witness version for bare tapscript?

That way, you can still make bare CTV commitments (leaving other types of bare scripts non-standard).

I did here CTV+CSFS: Can we reach consensus on a first step towards covenants? - #58 by instagibbs

I find it nice to consider both separately, even if they both end up being adopted.

1 Like

This is a cool patch, thanks for doing it.

I still prefer the existing CTV impl. for a few reasons:

  1. Bare legacy CTV is upgradeable (i.e. >32byte CTV hashes). Though you could make your patch upgradeable by returning true for any witV2 with a program size of over 32 bytes.
  2. In wit v0 CTV, you can have scripts that are more complicated than just a single CTV invocation, but avoid the Taproot control block overhead of 33vB (e.g. in simple-ctv-vault). 33vB may well be worth fretting over in the future.
  3. This is probably fringe, but one “nice” thing about bare CTV legacy scripts is that because they don’t have an associated address, accidental address reuse by a human is impossible (i.e. erroneous send to an already-setup vault). Of course your witV2 scheme doesn’t define an address format, but it would be easy to. Edit: witV2 by default uses bech32m addresses.

@instagibbs Maybe it goes without saying, but I think it’d be totally reasonable to layer on a tapscript-only OP_CHECKTEMPLATE to the existing proposal. If it saves 32 vbytes 8WU for the Lightning case and likely others, I think that’s great.

No other output lengths would be defined for the “P2CTV” case, there’s no difference in this respect.

33WU, or <9vB. I don’t find byte pinching over hypotheticals very persuasive but other’s mileage may vary.

I know we differ on this but I expect very little bare CTV usage vs some form of script. We can’t protect people in script hash land; I think that ship sailed a long time ago.


The proposal is materially different than before with CSFS added. Let’s avoid sunk cost thinking.

1 Like

Another more practical point in favor of making CTV available in witness v0 is that many (or most?) HSMs do not yet natively support Schnorr signatures - and for existing installations, may never. There is likely overlap between companies who currently use such HSMs (making witness v0 the default) and companies who would like to make use of CTV vaults.

3 Likes

That’s a reasonable point, under the restricted set of functionality that encompasses a hash-assertion and a disjoint signature over the transaction itself.

So you could have a “next tx” transition or override with some (non-aggregated) key or require both.

Brief overview of my current thoughts, for whatever they’re worth:

I’d be happy to modify BIP-119 to omit legacy script support for CTV if there’s a 34-byte “witness v2” along the lines of what @instagibbs sketched out.

My hold out here had been that I thought the BitVM “sibling input requirement” trick relies upon legacy use, but it does not. Note that I still think CTV availability in witness v0 is worth preserving for reasons mentioned above.

If there’s demand to introduce a push-style OP_TEMPLATEHASH that puts the CTV digest on the stack, that sounds like a totally reasonable and low-effort/risk enhancement to me.


Do the stakeholders opining here think there could be consensus around this? Namely:

  • BIP-119 modified to remove legacy script support (but retaining wit v0 support),
  • definition of a witness v2 per instagibb’s patch, and
  • inclusion of a tapscript-only OP_TEMPLATEHASH?

Can you clarify the situation with regards to PTLC (without LN Symmetry)? My understanding is that PTLC is an enormous privacy upgrade, since it removes the trail of identical hash pre-images along a (split) route. (especially in a scenario where an adversary is gradually collecting log files through nefarious means)

I guess I’m stuck in 2021 when we thought that just Taproot would do the trick.

Is it merely easier if we add CSFS (plus CTV)? Or is it nearly impossible without that?

Since it tends to take a few years for a soft fork to activate and for a protocol like Lightning to take advantage of it, by that time, could we be in situation where already achieved PTLC the hard way? It would still be a welcome simplification, but not introducing something new. Or do you reckon we’ll have PTLC sooner despite the extra step of activating a soft fork?

Take a look here to see what complications arise from PTLCs on today’s protocols. It’s by no means impossible, but with rebindable signatures it just gets significantly simpler.

I will not try to predict uptake on established protocols however. There’s a long list of improvements that users actually care about, and PTLCs isn’t one of them generally.

I think there’s also a lack of tooling/standardisation for doing a PTLC reveal in combination with a musig 2-of-2 (which would be efficient on-chain), or even general tx signatures (ie x CHECKSIGVERIFY y CHECKSIG).

The efficient way of doing PTLCs would be to have a partially-presigned musig2 signature for the redeem tx, where completing the signature reveals the PTLC secret to the other party. But this would require adaptor signature support for musig2, and that’s not part of the spec and was removed from the secp256k1 implementation see pr#1479. Doing it less efficiently as a separate adaptor signature would work too, but even plain adaptor signatures for schnorr sigs also isn’t available in secp256k1.

These also aren’t included even in the more experimental secp256k1-zkp project, see pr#299, though secp256k1-zkp does have support for ECDSA-based adaptor signatures (pr#117) and adaptor signatures in the old musig scheme that predates musig2 and BIP-327 (see musig.md).

If the tooling were ready, I could see PTLC support being added as a “let’s get it in early so it’s already widely supported when we actually want to enable it”, but I don’t think anyone considers it a high enough priority to put in the work to get the crypto stuff standardised and polished. Making the unhappy path more efficient is something that could be done later on a per-peer basis without too much hassle.

Having CAT+CSFS available would avoid the tooling issue, at a cost in on-chain efficiency (though only in the unhappy path, of course), using 102 witness bytes for a PTLC reveal versus 56/67 witness bytes for a HTLC reveal. In particular, the script <R> CAT <G> DUP CSFS can be satisfied by having <s> on the stack where s*G = R + H(R,G,G)*G, so the preimage of R can be calculated as r = s - H(R,G,G), with straightforward ECC maths, and no need for secret keys. I think with only CSFS available you continue having similar tooling problems, because you need to use adaptor signatures to prevent your counterparty from choosing a different R value for the signature.

EDIT: <R> TUCK SWAP CAT SWAP DUP CSFS, which uses R for the pubkey and message as well as the nonce, probably works better – 73 witness bytes for the reveal is pretty close to the HTLC version, and the calculation is just r = s/(1 + H(R,R,R)) which is only slightly more annoying, in that it requires a modular division. (Maybe OP_0 would be a better “message” in this case)

(These issues are independent of the update complexity and peer protocol updates @instagibbs describes above)

2 Likes

To be clear, does this include per-hop blinding? My PTLC context has completely paged out of memory.

Per-hop blinding just means that you have inbound value R1 and outbound value R2=R1+kG, where k is a per-hop constant known only to you and the person initiating the payment, so when you receive/calculate r2 on your outbound link, you can calculate r1=r2-k to claim the inbound funds. You just need to relate r1/R1 (and r2/R2) on-chain, you don’t need to relate r1/r2 or R1/R2 on-chain (which would remove the privacy benefit anyway).

1 Like