Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BIP442: OP_PAIRCOMMIT #1699

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft

BIP442: OP_PAIRCOMMIT #1699

wants to merge 4 commits into from

Conversation

moonsettler
Copy link

@moonsettler moonsettler commented Nov 11, 2024

OP_PAIRCOMMIT is the newest member of the LNhance family of opcodes. It provides limited vector commitment functionality in tapscript.

When evaluated, the OP_PAIRCOMMIT instruction:

  • pops the top two values off the stack,
  • takes the "PairCommit" tagged SHA256 hash of the stack elements,
  • pushes the resulting commitment on the top of the stack.

Discussion: https://delvingbitcoin.org/t/op-paircommit-as-a-candidate-for-addition-to-lnhance/1216/12

Copy link
Contributor

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This document has a few formatting issues, please make sure that the preamble matches the BIP 2 requirements and take a look at the rich diff to see whether it looks the way you intend.

Please note that the BIPs repository also accepts markdown files.

@moonsettler
Copy link
Author

moonsettler commented Nov 13, 2024

Switched back to markdown. Header now in BIP-2 format.

@moonsettler moonsettler force-pushed the paircommit branch 2 times, most recently from 8f11758 to f3f7f91 Compare November 13, 2024 21:35
@moonsettler
Copy link
Author

The original create date of OP_PAIRCOMMIT is 2024-03-15 this is the latest revision based on feedback from Anthony Towns.
https://gist.github.com/moonsettler/d7f1fb88e3e54ee7ecb6d69ff126433b/revisions
What date should go to the header?

@jonatack
Copy link
Member

Added a discussion link to the PR description.

The original create date of OP_PAIRCOMMIT is 2024-03-15 this is the latest revision based on feedback from Anthony Towns.
gist.github.com/moonsettler/d7f1fb88e3e54ee7ecb6d69ff126433b/revisions
What date should go to the header?

Perhaps add a changelog with the revision based on Anthony Towns' feedback followed by the initial version. Or use the date of the current draft revision as your starting point.

@murchandamus
Copy link
Contributor

According to BIP 2:

The Created header records the date that the BIP was assigned a number, […]

@moonsettler moonsettler marked this pull request as ready for review November 14, 2024 15:56
@murchandamus
Copy link
Contributor

Has this proposal been sent to the mailing list?

@moonsettler
Copy link
Author

moonsettler commented Nov 14, 2024

Has this proposal been sent to the mailing list?

Not yet. Wanted to get it into an acceptable shape before I post it there.

Proposed to the mailing list, waiting for feedback.

@moonsettler moonsettler force-pushed the paircommit branch 3 times, most recently from 59249d9 to dfb0670 Compare November 15, 2024 18:24
Copy link
Contributor

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to see this proposal to get more review from other covenant researchers before it moves forward.

@moonsettler
Copy link
Author

moonsettler commented Nov 26, 2024

It looks like we gonna have to amend the PAIRCOMMIT BIP with some new use cases.
Turns out within certain practical limitations any computational function can be proven out in the form of a merkle tree.
The root hash of the merkle tree represents the function the leaves represent the inputs and output.
Any 32 bit arithmetic function can certainly be proven out with this method.
CAT itself with a limited set of inputs or limited input sizes can be proven out.
At this point it's an open question if this enables new behaviors not enabled by taproot MAST itself?

Special thanks to: @JeremyRubin @Ademan @bigspider

edit:
Alternatively could consider imposing specific script limits that make PAIRCOMMIT explicitly less capable than MAST itself.

moonsettler

This comment was marked as off-topic.

@Ademan
Copy link

Ademan commented Nov 27, 2024

I think I've changed my mind a bit. We were talking about computing a merkle tree for f(u32,u32) as if it was trivial but after a quick experiment it seems like that would take hundreds of years to compute (am I being dumb here?) Instead, you can compute mul(u32,u32) -> u32 using 3 mul(u16,u16)s which is feasible to compute. The witness size is worse, ~32 * 32 * 3 = 3072 instead of 32 * 64 * 1 = 2048, but computing the tree for mul(u16,u16) is feasible using a naive algorithm on commodity hardware.

The implication of this is that where a function can be decomposed into operations on smaller inputs, PAIRCOMMIT is massively more feasible to use than encoding things into a tap tree.

@bigspider
Copy link
Contributor

I think I've changed my mind a bit. We were talking about computing a merkle tree for f(u32,u32) as if it was trivial but after a quick experiment it seems like that would take hundreds of years to compute (am I being dumb here?) Instead, you can compute mul(u32,u32) -> u32 using 3 mul(u16,u16)s which is feasible to compute. The witness size is worse, ~32 * 32 * 3 = 3072 instead of 32 * 64 * 1 = 2048, but computing the tree for mul(u16,u16) is feasible using a naive algorithm on commodity hardware.

Arithmetic and bitwise operations where inputs & outputs are small enough, can already be done in Script in cheaper ways. Merkle trees as lookup tables are only interesting for functions that are either extremely complex, or where preimages/images are larger than what Script can work with.
Note that you can already do small indexed lookup tables more efficiently by just hard-coding them in Script (that is: push the table on the stack and use OP_PICK to read its entries), and these techniques are widely used (e.g. in BitVM).

The implication of this is that where a function can be decomposed into operations on smaller inputs, PAIRCOMMIT is massively more feasible to use than encoding things into a tap tree.

I think the only substantial difference is that in a Script where you need several lookups, you can do it with Merkle trees, while you can only do a single lookup with a precomputed taptree.

@moonsettler
Copy link
Author

Proving general computation

Merkle trees can be used to prove out computation where the root of the tree
represents the function and the leaves represent the inputs and output.
There are practical limits to the entropy space for the inputs as it needs
to be iterated over and hashed up.

Currently MAST trees can cover 128 bits of entropy space, which is well over
the practical limits to iterate over and merklize. Therefore we assume this
capability does not materially extend what computations are possible to prove
out in bitcoin script. While OP_PAIRCOMMIT is not limited to a height of 128,
that should not be practically feasible to utilize.

There is a way to reduce the size of the witness for proving out computation,
by eliminating the merkle path inclusion proofs, using OP_CHECKSIGFROMSTACK
together with OP_PAIRCOMMIT. This method involves deleted key assumptions,
most likely using MPC to create an enormous amount of signatures for the stack
elements representing the inputs and the output of the function.

Is this correct? Any suggestions? @Ademan @bigspider

@moonsettler
Copy link
Author

moonsettler commented Nov 27, 2024

The implication of this is that where a function can be decomposed into operations on smaller inputs, PAIRCOMMIT is massively more feasible to use than encoding things into a tap tree.

This is the main open question I believe. does it or does it not practically expand what we can already do?
For example using PC to emulate smolCAT and using traditional methods with lookup tables could make 32 bit or even 64 bit arithmetics more feasible?

edit:
Within the 32 bit realm we can already use OP_ADD, I see little practical diff between <0x1234> <0x5678> CAT and <0x12340000> <0x5678> ADD.
And it sounds like 64 bit smolCAT would be way too expensive to generate (and also to interact with trustlessly).

(actually the above examples are wrong, because internally bitcoin script uses little endian, but should convey the point)

@Ademan
Copy link

Ademan commented Nov 27, 2024

...

Arithmetic and bitwise operations where inputs & outputs are small enough, can already be done in Script in cheaper ways. Merkle trees as lookup tables are only interesting for functions that are either extremely complex, or where preimages/images are larger than what Script can work with. Note that you can already do small indexed lookup tables more efficiently by just hard-coding them in Script (that is: push the table on the stack and use OP_PICK to read its entries), and these techniques are widely used (e.g. in BitVM).

Even u16,u16 is quite a bit larger than I think is practical as a lookup table, but the efficiency for repeated operations is constant, obviously. The lookup table is less efficient for small numbers of operations (a u8,u8 table is 16k vs 1 u8,u8 proof is 0.4k) but the merkle tree loses quickly when those operations are repeated.

The implication of this is that where a function can be decomposed into operations on smaller inputs, PAIRCOMMIT is massively more feasible to use than encoding things into a tap tree.

I think the only substantial difference is that in a Script where you need several lookups, you can do it with Merkle trees, while you can only do a single lookup with a precomputed taptree.

Right, and the key point is these merkle trees and lookup tables rapidly become infeasible to compute as the input size grows, so multiple smaller lookups is significantly more useful.

EDIT: But your point is well taken that for smaller operations they can already be better accomplished by lookup tables.

@Ademan
Copy link

Ademan commented Nov 27, 2024

...
edit: Within the 32 bit realm we can already use OP_ADD, I see little practical diff between <0x1234> <0x5678> CAT and <0x12340000> <0x5678> ADD. And it sounds like 64 bit smolCAT would be way too expensive to generate (and also to interact with trustlessly).

(actually the above examples are wrong, because internally bitcoin script uses little endian, but should convey the point)

Yeah for arbitrary 8 byte strings smolCAT seems infeasible to compute the table or merkle tree for. After a bit of conversation on IRC it could probably be feasible for arbitrary f(b[4],b[4]) -> b[8] with a custom ASIC¹ or maybe a cluster of FPGAs in a span of ~a few years but that would not be very useful for the average person.

Bit shifts over 32 bit integers seems pretty feasible though, that's f(u32,u6)->u32 (maybe save some space by special casing shift = 0). it seems like my incredibly naive, unoptimized, single-core experiment could calculate that merkle tree in ~96 hours. Of course the proof is ~1.2k and users would likely need multiple, but the lookup table for that wouldn't fit in a block anyway so maybe something new is possible?

You can also separate positive and negative shifts, and maybe break it down into multiple rounds of shifts 1-3 or something (or 1k for a proof for a constant shift)

[1]: afaik existing ASICs operate on block headers so couldn't help

Copy link
Contributor

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let’s call this BIP 442.

@jonatack jonatack changed the title OP_PAIRCOMMIT BIP442: OP_PAIRCOMMIT Dec 17, 2024
Copy link
Contributor

@reardencode reardencode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PAIRCOMMIT continues to grow on me.

Getting the primary benefits of OP_CAT without introducing ugly introspection seems like a clear win for bitcoin.

Better introspection should also be added in follow-up forks. Thanks for your work on this!

bip-0442.md Outdated
a 1-byte `OP_TRUE` public key (substituting for the *taproot internal key*) and
can commit to a number of stack elements as a message.

### Behaviors LNhance tries to avoid introducing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this section belong in the PC BIP?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should have an LNhance BIP that depends on the others and move some stuff over?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it may be fine here if this section is moved up next to the Motivation section and the term LNHANCE is introduced clearly, ideally with a link to lnhance.org if that url is viable long-term.

@JeremyRubin
Copy link
Contributor

I get that there is a goal here to avoid introspection...

but it seems that it'd be more generically useful if the function were e.g., a TapBranch function, so then it could be used in the future with some other taproot editing opcodes.

e.g., if OP_TAPBRANCHCOMMIT were to lexicographic sort, then cat, then commit, you could do paircommit like functionality by doing:

<a> <b> TUCK OP_TAPBRANCHCOMMIT OP_TAPBRANCHCOMMIT

this works because while the first commit commits to either a||b or b||a, and also has sliceable errors (e.g., (a||b)[:i] and (a||b)[i:]), the second commit re-commits to <b> and it's length which uniquely determines order and prevents sliceable errors.

One concern: OP_TAPBRANCHCOMMIT is witness "malleable", in that items could show up in the witness stack in either order and get the same result. It'd still be possible to make non-malleable witnesses by requiring the stack elements to be in order with a OP_LEXSORT or equivalent functionality.

@moonsettler
Copy link
Author

If we did OP_TAPBRANCHCOMMIT then with OP_CHECKCONTRACTVERIFY I believe you get TLUV behavior?
You can verify a tapleaf on the input and can also replace it with an other on the output?

To be honest the OP_PAIRCOMMIT domain separation was aimed to prevent the possibility of such uses as potentially being more controversial.

@JeremyRubin
Copy link
Contributor

I think it's actually less controversial, because if you do OP_TAPBRANCHCOMMIT you're doing something that even once you have OP_CAT, is really handy to have (because sorting two strings is actually still pretty hard with CAT).

Whereas now you're getting a lot of people thinking that paircommit is not so useful if CAT gets in eventually.

@moonsettler
Copy link
Author

moonsettler commented Dec 25, 2024

Right. I did consider something like a sorting merkle operator for lamport stuff for example, however when you need order dependent commitments (which is pretty much everything we are doing with it rn) then you would have to use a dummy value like:
<a> <1> <b> OP_TAPBRANCHCOMMIT OP_TAPBRANCHCOMMIT
or maybe:
<a> <b> OP_SHA256 OP_TAPBRANCHCOMMIT
instead of:
<a> <b> OP_PAIRCOMMIT
So if I wanted to support both of these functionalities I would probably end up with 2 separate opcodes for them.

@moonsettler moonsettler force-pushed the paircommit branch 3 times, most recently from 69d8d97 to 0ad3d24 Compare December 28, 2024 17:50
@moonsettler
Copy link
Author

I think this is ready for a merge from my point of view.
Rebased to latest master and squashed all the changes to 1 commit.

@Ademan
Copy link

Ademan commented Dec 28, 2024

Maybe this is obvious to everyone else and I'm a slowpoke here, but PC+CSFS+CTV enables a kind of "multi-transaction-signature". You sign a merkle root that commits to a bunch of CTV transaction templates, and you can provide an inclusion proof with PC with the signature.

I've been spitballing with someone about a multiparty eltoo scheme and came up with a way to bound the state resolution but without state carrying covenants it requires a possible field of ~2^N transactions (of which, at most N will end up on-chain), and every party shares N*(N+1)/2 signatures.

With PC+CSFS+CTV it still requires ~2^N transactions, but each party only needs to share their 1 signature over the merkle root.

EDIT: Not 100% sure it works for my mutliparty eltoo scheme just yet, but I'm still >50% confident it does...
EDIT EDIT: More confident it works, but it looks like the number of transactions is exponential rather than polynomial... and so my estimate for how many signatures would need to be shared without the "multi-transaction-signature" commitment is probably way low.
EDIT EDIT EDIT: I genuinely have no idea how I decided "multi-signature" was an acceptable term considering it already has a different meaning in Bitcoin... s/"multi-signature"/"multi-transaction-signature"/g

Copy link
Contributor

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this BIP still somewhat hard to read. Many sections seem to expect a lot of prior knowledge from the reader. Overall, it seems to me that several sections could do with a bit more context. Maybe I’m not in the target audience for the BIP, but I would suggest that people who are more invested in this topic proofread this BIP and provide feedback with approachability in mind.

bip-0442.md Outdated
<a> <b> <c> | PC PC <pc-hash> OP_EQUALVERIFY
```

### Use in LN-Symmetry
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a subsection of the Specification section, but does "Use in LN-Symmetry" actually belong to the Specification? Wouldn’t it make more sense for it to be in the Rationale or a section with example uses?

bip-0442.md Outdated
ENDIF
```

### Use with future updates
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, "Use with future updates" doesn’t seem to belong to the Specification.

Copy link
Member

@jonatack jonatack Jan 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using ## instead of ### for this section and for "Use in LN-Symmetry" might suffice (e.g. moving them out of the Specification section).

bip-0442.md Outdated
Comment on lines 190 to 199
| Method | ChannelSc | UpdateSc | UpdateW | ForceC | Contest | Settle |
| :------------ | --------: | -------: | ------: | ------: | ------: | :----: |
| APO-Annex | 8 WU | 113 WU | 100 WU | 1221 WU | 627 WU | SigOp |
| APO-Return | 8 WU | 113 WU | 66 WU | 1359 WU | 765 WU | SigOp |
| CTV+CSFS+IKEY | 10 WU | 48 WU | 98 WU | 1328 WU | 732 WU | CTV |
| CTV+CSFS | 43 WU | 81 WU | 98 WU | 1394 WU | 765 WU | CTV |
| LNhance | 11 WU | 49 WU | 131 WU | 1191 WU | 594 WU | CTV |

*ChannelSc: channel script, UpdateSc: update script, UpdateW: witness is the
same size for both Force Close and Contest in LN-Symmetry, ForceC: total cost of unilateral close transactions*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these abbreviations are just a few characters shorter than the actual term. How about something along the lines of:

Suggested change
| Method | ChannelSc | UpdateSc | UpdateW | ForceC | Contest | Settle |
| :------------ | --------: | -------: | ------: | ------: | ------: | :----: |
| APO-Annex | 8 WU | 113 WU | 100 WU | 1221 WU | 627 WU | SigOp |
| APO-Return | 8 WU | 113 WU | 66 WU | 1359 WU | 765 WU | SigOp |
| CTV+CSFS+IKEY | 10 WU | 48 WU | 98 WU | 1328 WU | 732 WU | CTV |
| CTV+CSFS | 43 WU | 81 WU | 98 WU | 1394 WU | 765 WU | CTV |
| LNhance | 11 WU | 49 WU | 131 WU | 1191 WU | 594 WU | CTV |
*ChannelSc: channel script, UpdateSc: update script, UpdateW: witness is the
same size for both Force Close and Contest in LN-Symmetry, ForceC: total cost of unilateral close transactions*
| Method | Channel Script | Update Script | Update Witness¹ | Force Close² | Contest | Settlement Mechanism |
| :------------ | --------: | -------: | ------: | ------: | ------: | :----: |
| APO-Annex | 8 WU | 113 WU | 100 WU | 1221 WU | 627 WU | SigOp |
| APO-Return | 8 WU | 113 WU | 66 WU | 1359 WU | 765 WU | SigOp |
| CTV+CSFS+IKEY | 10 WU | 48 WU | 98 WU | 1328 WU | 732 WU | CTV |
| CTV+CSFS | 43 WU | 81 WU | 98 WU | 1394 WU | 765 WU | CTV |
| LNhance | 11 WU | 49 WU | 131 WU | 1191 WU | 594 WU | CTV |
¹ *witness is the same weight for both Force Close and Contest in LN-Symmetry*
² *total cost of unilateral close transactions*

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This table is also provided barren of context. It would probably be useful to link to the compared schemas, or to the source of the table, and to add a couple sentence as to what we are looking at in the first place.

bip-0442.md Outdated
* OP_VECTORCOMMIT: generalized form for n > 2 elements
* ReKey: key delegation and multiple use of OP_CHECKSIGFROMSTACK

### Cost comparison of LN-Symmetry constructions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Cost comparison of LN-Symmetry constructions
### Weight comparison of LN-Symmetry constructions

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment was not addressed in the recent update.

bip-0442.md Outdated
Comment on lines 164 to 166
### Behaviors LNhance tries to avoid introducing

The following behaviors are out of scope for LNhance and should not be enabled
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the first mention of LNHANCE in this BIP, but is not further explained. LNHANCE is not introduced in this repository (except for a cursory mention in BIP 348 OP_CHECKSIGFROMSTACK). It would probably make sense to introduce the term, if this section is retained.

bip-0442.md Outdated
There are practical limits to the entropy space for the *inputs* as they need
to be iterated over and hashed into a Merkle root.

Taproot MAST trees can currently cover 128 bits of entropy space, which is over
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are "Taproot MAST trees"? The taproot BIPs speaks of "Script Trees" and MAST would be understood as "Merklized Alternative Script Trees" in the context of Taproot. On the other hand, MAST as described in BIP 114 and BIP 117 speaks of Merklized Abstract Syntax Trees where multiple leaves are used in combination.

You mention MAST here in the context taproot, where only a single leaf is ever used at once, but it seems to me that you might be thinking of Abstract Syntax Trees. Either way, it is not clear to me what you are referring to here, when you speak of the "entropy space covered by Taproot MAST trees" while treating leaves as "inputs and outputs".

This section is jumping right in the middle of something. I’m not sure that the scenario is described sufficiently to understand what the supposed concern is, let alone why the supposed concern is not a concern. If this section is relevant to this BIP, I reckon that more context is necessary for the reader to understand why and how, e.g., add aa link to a description of this scheme, or provide a bit more explanation what this section is talking about.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this is a problem in the taproot BIP series, where various individuals decided it pertinent to change a well understood acronym (MAST) to suit taproot, rather than resepcting an existing body of literature including other BIPs.

I'd rather the taproot BIPs get updated to reflect the terminology Merklized Abstract Syntax Trees (or Tap Script Merkle Commitments, TSMC, if we're fond of confusing backronyming but should be less ambiguous in context) rather than Merklized Alternative Script Trees, which was a backronym.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correction: it seems there is no mention of alt script tree in the bips repos, just abstract syntax tree, including in the BIPs for Taproot itself. It's just a confusing rename people have made outside of this repo.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So should it be "Taptrees" instead of "Taproot MAST trees"? Or "Tapscript trees"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "Taproot script tree" or "Taproot Merkle tree" would both be clear, I prefer the former.

Copy link
Contributor

@reardencode reardencode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm gonna spend some time with this BIP today and will either make comments or offer a revision to put the sections of this into a more cohesive sequence.

bip-0442.md Outdated
Comment on lines 26 to 27
Currently, bitcoin lacks a way to hash multiple stack elements together. Which
means building Merkle trees or verifying inclusion in a tree is not supported.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Currently, bitcoin lacks a way to hash multiple stack elements together. Which
means building Merkle trees or verifying inclusion in a tree is not supported.
Currently, bitcoin lacks a way to commit to multiple stack elements together. It is common practice to hash a single item as part of a bitcoin script, either in hash/time locked contracts, or in pay-to-pubkey-hash (P2PKH) scripts, but there is no way to commit to multiple items with a single hash.
In a contrived but demonstrative example, if PAIRCOMMIT existed in legacy script, P2PKH could be extended to pay-to-pubkey-time-hash with scriptPubKey `2DUP PAIRCOMMIT RIPEMD160 <hash> EQUALVERIFY CHECKLOCKTIMEVERIFY DROP CHECKSIG`. This script format for single signature, time-locked bitcoin could be transformed into an address format.
With the ability to commit to pairs of elements, PAIRCOMMIT can be generalized Merklized commitments to a tree of elements with a single hash. On its own, this could enable a hash lock contract where the holder of any pre-image in a Merkle tree can unlock the spend, for example.
If `OP_CHECKSIGFROMSTACK` is combined with PAIRCOMMIT, the ability to sign commitments to multiple items enables both of the above but as a form of delegation. In cases where any single item can be used to unlock an output, additional off chain signatures be simply can be used as an alternative to PAIRCOMMIT. However in cases where multiple items must be used for spending together, PAIRCOMMIT removes the need for complex laddering schemes to ensure that all items were authorized together.

bip-0442.md Outdated
Comment on lines 32 to 34
The number of SHA256 iterations is minimized in the typical use cases we can
optimize for. Since the Tag can be pre-computed as mid-state, it would only
take 1 or 2 hash cycles in validation for the unilateral close scenario.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like something that belongs in a footnote not in the main text.

bip-0442.md Outdated
There are practical limits to the entropy space for the *inputs* as they need
to be iterated over and hashed into a Merkle root.

Taproot MAST trees can currently cover 128 bits of entropy space, which is over
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "Taproot script tree" or "Taproot Merkle tree" would both be clear, I prefer the former.

Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WIP review.

bip-0442.md Outdated
in a way that makes length redistribution attacks infeasible.

The number of SHA256 iterations is minimized in the typical use cases we can
optimize for. Since the Tag can be pre-computed as mid-state, it would only
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does "Tag" here refer to this, as you are writing elsewhere in this draft?

Suggested change
optimize for. Since the Tag can be pre-computed as mid-state, it would only
optimize for. Since the tagged SHA256 hash can be pre-computed mid-state, it would only
  • drop "as"?
  • s/in validation/to validate/ (line 34)?

bip-0442.md Outdated
ENDIF
```

### Use with future updates
Copy link
Member

@jonatack jonatack Jan 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using ## instead of ### for this section and for "Use in LN-Symmetry" might suffice (e.g. moving them out of the Specification section).

bip-0442.md Outdated
### Use with future updates

Detailed introspection opcodes would also need vector commitments when used
with `OP_CHECKSIGFROMSTACK`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, could link to or mention BIP348 with CHECKSIGFROMSTACK here.

bip-0442.md Outdated
Detailed introspection opcodes would also need vector commitments when used
with `OP_CHECKSIGFROMSTACK`.

`OP_CHECKCONTRACTVERIFY` would also need a way to carry complex data.
Copy link
Member

@jonatack jonatack Jan 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't part of any BIP (number) yet, maybe add it later if that changes.

bip-0442.md Outdated

https://github.com/lnhance/bitcoin/pull/6/files

## Rationale
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest moving this Rationale section up to just after Motivation, before Specification.

bip-0442.md Outdated

## Rationale

If `OP_CAT` was available, it could be used to combine multiple stack elements
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could link to or mention BIP347 with OP_CAT here.

bip-0442.md Outdated
* Merkle operation opcodes
* 'Kitty' CAT: result or inputs arbitrarily limited in size
* OP_CHECKTEMPLATEVERIFY committing to the taproot annex in tapscript
* OP_CHECKSIGFROMSTACK on n elements as message
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could link to or mention BIP348

bip-0442.md Outdated
* SHA256 streaming opcodes
* Merkle operation opcodes
* 'Kitty' CAT: result or inputs arbitrarily limited in size
* OP_CHECKTEMPLATEVERIFY committing to the taproot annex in tapscript
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could link to or mention BIP119

bip-0442.md Outdated
* OP_VECTORCOMMIT: generalized form for n > 2 elements
* ReKey: key delegation and multiple use of OP_CHECKSIGFROMSTACK

### Cost comparison of LN-Symmetry constructions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may make sense to put this section next to (or in) the "Use in LN-Symmetry" section.

bip-0442.md Outdated
a 1-byte `OP_TRUE` public key (substituting for the *taproot internal key*) and
can commit to a number of stack elements as a message.

### Behaviors LNhance tries to avoid introducing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it may be fine here if this section is moved up next to the Motivation section and the term LNHANCE is introduced clearly, ideally with a link to lnhance.org if that url is viable long-term.

bip-0442.md Outdated
Channel peers must be able to reconstruct the script that spends an
intermediate state.

Using in sequence `OP_CHECKTEMPLATEVERIFY`, `OP_PAIRCOMMIT`, `OP_INTERNALKEY`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pseudocode below might be clearer if the acronyms are defined beforehand

Suggested change
Using in sequence `OP_CHECKTEMPLATEVERIFY`, `OP_PAIRCOMMIT`, `OP_INTERNALKEY`
Using in sequence `OP_CHECKTEMPLATEVERIFY` (`CTV`), `OP_PAIRCOMMIT` (`PC`), `OP_INTERNALKEY` (`IK`)

(idem for CSFS on the next line)

@reardencode
Copy link
Contributor

Thanks so much Jon. we have a significant revision coming that does include defining abbreviations. @moonsettler should we move this to draft until we finish workshopping the revisions we're working on?

@moonsettler moonsettler marked this pull request as draft January 4, 2025 13:55
@moonsettler
Copy link
Author

We have a rework of the BIP, the original can be viewed here

Please provide feedback on which approach you think is better! @murchandamus @jonatack

Copy link
Contributor

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I found the new version easier to follow.

Comment on lines +52 to +54
is common practice to hash a single item as part of a bitcoin script. Either
in hash/time locked contracts, or in pay-to-pubkey-hash (P2PKH) scripts, but
there is no way to commit to multiple items with a single hash.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sentence starting with "Either" seems to be missing one or more words.

construction that provides data availability to spend to the latest state from
an earlier state pushed on-chain with a forced close by channel partner.

### Use in Lightning Symmetry
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "LN-Symmetry" is more commonly used to refer to the concept than "Lightning Symmetry". Is there a specific reason why you prefer the latter?

Comment on lines +99 to +101
by contested closes. Specifically, the second to act channel partner must be
able to reconstruct the script that spends the first update transaction
published. This script includes the hash of the corresponding settlement
Copy link
Contributor

@murchandamus murchandamus Feb 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is easier to parse:

Suggested change
by contested closes. Specifically, the second to act channel partner must be
able to reconstruct the script that spends the first update transaction
published. This script includes the hash of the corresponding settlement
by contested closes. Specifically, either channel partner must be
able to spend the output of any prior update transaction.
Those input scripts include the hash of the corresponding settlement

transaction which we do not wish to store for all prior states. By having the
channel and update state scripts force the parties to include the settlement
transaction's hash in the witness to in order to publish the corresponding
update transaction, then a later update can use the settlement hash from the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m stumbling over this "in the witness to in order". Could you please revisit this sentence?

bip-0442.md Outdated
most likely using MPC to create an enormous amount of signatures for the stack
elements representing the *inputs* and the *output* of the *function*.
Taproot trees can be 128 levels deep, therefore including up to 2^128 possible
output values. This is over the practical limits to enumerate and merkelize.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistency nit:

Suggested change
output values. This is over the practical limits to enumerate and merkelize.
output values. This is over the practical limits to enumerate and Merklize.

same size for both Force Close and Contest in Lightning Symmetry, ForceC: total
cost of unilateral close transactions, Contest: The additional cost to contest
a force closure, Settle: Whether a signature operation or CTV operation is
required to validate the settlement transaction*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for expanding on the column titles. As I wrote above, it would be good to provide more context for this table. It would especially help if the compared schemata were at least briefly described and/or sources for details were provided.

bip-0442.md Outdated
* OP_VECTORCOMMIT: generalized form for n > 2 elements
* ReKey: key delegation and multiple use of OP_CHECKSIGFROMSTACK

### Cost comparison of LN-Symmetry constructions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment was not addressed in the recent update.

bip-0442.md Outdated
most likely using MPC to create an enormous amount of signatures for the stack
elements representing the *inputs* and the *output* of the *function*.
Taproot trees can be 128 levels deep, therefore including up to 2^128 possible
output values. This is over the practical limits to enumerate and merkelize.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first time I read this paragraph, I was confused and didn’t realize that you were comparing the expressional power of OP_PAIRCOMMIT and P2TR.
Perhaps it would help if you write "leaf scripts" instead of "output values" here:

Suggested change
output values. This is over the practical limits to enumerate and merkelize.
leaf scripts. This is over the practical limits to enumerate and merkelize.

@murchandamus murchandamus added the PR Author action required Needs updates, has unaddressed review comments, or is otherwise waiting for PR author label Feb 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
New BIP PR Author action required Needs updates, has unaddressed review comments, or is otherwise waiting for PR author
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants