diff --git a/README.mediawiki b/README.mediawiki index 7950e107d8..90d1bc7507 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1288,6 +1288,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Gloria Zhao | Informational | Draft +|- +| [[bip-0442.md|442]] +| Consensus (soft fork) +| OP_PAIRCOMMIT +| moonsettler +| Standard +| Draft |} diff --git a/bip-0442.md b/bip-0442.md new file mode 100644 index 0000000000..6e6203e37a --- /dev/null +++ b/bip-0442.md @@ -0,0 +1,320 @@ +
+  BIP: 442
+  Layer: Consensus (soft fork)
+  Title: OP_PAIRCOMMIT
+  Author: moonsettler 
+          Brandon Black 
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0442
+  Status: Draft
+  Type: Standards Track
+  Created: 2024-12-09
+  License: BSD-3-Clause
+
+ +## Abstract + +This BIP describes a new tapscript opcode `OP_PAIRCOMMIT`, which +provides limited vector commitment functionality in tapscript. + +## Summary + +When verifying taproot script spends having leaf version 0xc0 (as defined in +[BIP-342]), we propose `OP_PAIRCOMMIT` to replace `OP_SUCCESS205` (0xcd). + +When evaluated, `OP_PAIRCOMMIT`: +* Pops the top two values off the stack, +* takes the "PairCommit" tagged SHA256 hash of the stack elements with size commitments, +* pushes the resulting 32-byte hash to the top of stack. + +## Specification + +The notation below follows that of [BIP-340]. This includes the +$$hash_{tag}(x)$$ notation to refer to +$$SHA256(SHA256(tag) \\| SHA256(tag) \\| x)$$. + +* If fewer than 2 elements are on the stack, the script MUST fail and + terminate immediately. +* The top element ($$x2$$) and second to top element ($$x1$$) are read from the + stack. +* Let $$pc$$ be $$hash_{PairCommit}( + compact\\_size(size\\:of\\:x1) \\| x1 \\| + compact\\_size(size\\:of\\:x2) \\| x2)$$[^1] +* The top two elements are popped from the stack. +* $$pc$$ is pushed to the stack. + +[^1]: The number of SHA256 blocks is minimized in typical use cases. Since the + Tag can be pre-computed as a SHA256 mid-state, it takes only 2 hash cycles + for a commitment to 2 32-byte items or 1 for 2 smaller items. + +## Motivation + +Currently, bitcoin lacks a way to commit to multiple data items 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. + +With the ability to commit to pairs of elements, PAIRCOMMIT can be generalized +to 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 complex delegation. For example, +delegating to $$key1$$ after time $$t1$$ and $$key2$$ after time $$t2$$. +Without PAIRCOMMIT these complex delegations can be achieved using key +laddering[^2], at a much greater validation cost. If the same key is simply used +to sign multiple items, they can be combined arbitrarily, but PAIRCOMMIT or +key laddering[^2] enforces any desired relationships between (both sequence and +combination) items. + +[^2]: `OP_CHECKSIGFROMSTACK` can commit to a sequence of otherwise + undifferentiated items by requiring a key committed to by the output to + sign an initial laddering key (`key0`) and then having `key0` sign a tuple + of `(item1, key1)` and `key1` signing the tuple `(item2, key2)` etc. There + are some details around ensuring that the items cannot be used as keys + depending on the requirements of the protocol. This is costly both in + bytes and sigops and `OP_PAIRCOMMIT` eliminates the need for such + constructions when committing to any sequence of items. For details, see + the [key laddering post] by Jeremy Rubin and Brandon Black. + +## Examples + +### Committing to more than 2 elements + +`OP_PAIRCOMMIT` can be used to commit to a vector of stack elements in a way +that is not vulnerable to various forms of witness malleability. It is, however, +highly optimized for just 2 stack elements. + +```text +# pc-hash = PC(a, PC(b, c)) + + | PC PC OP_EQUALVERIFY +``` + +### Use in Lightning Symmetry + +To create Lightning Symmetry contracts that neither require the nodes to keep +old states nor require additional signing round trips (and corresponding +signature validations), we need to solve a data availability problem presented +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 +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 +first update transaction's witness to recreate the corresponding spend script. + +The following assembly-like pseudo-code shows a possible Lightning Symmetry +channel construction that ensures sufficient data is available on chain in a +force close to reconstruct the corresponding script and update it with a later +state while only knowing the later state.[^3] The opcodes `OP_CHECKTEMPLATEVERIFY`, +`OP_PAIRCOMMIT`, `OP_INTERNALKEY`, and `OP_CHECKSIGFROMSTACK` are abbreviated +as `CTV`, `PC`, `IK`, and `CSFS` respectively. + +[^3]: Concretely the required data is a full CTV hash of the settlement + transaction when there are open HTLCs, or merely the difference in balance + between the channel partners in other cases. Whether the latter + optimization would be used is an implementation detail not further + discussed here. + +```text +# S = 500000000 +# internal key = [BIP-327] aggregate key of channel participants +# channel script: + | CTV PC IK CSFS CLTV DROP +``` + +Before funding, sign the first state. + +```text +# state-n-hash { nLockTime(S+n), out(contract, amount(A)+amount(B)) } +# settlement-n-hash { nSequence(2w), out(A, amount(A)), out(B, amount(B)) } +# state-n-recovery-data { settlement-n-hash or state-n-balance } +# update script: +IF + | CTV PC IK CSFS CLTV DROP +ELSE + CTV +ENDIF +``` + +These scripts ensure the necessary data availability as follows: `CTV` commits +to the update transaction's hash, `PC` combines this hash with the next stack +item, and `CSFS` checks a MuSig 2-party signature against the resulting pair +hash. Both parties must sign the same pair hash to produce a channel update, +and they can therefore require each other to include both the update hash and +settlement hash in the witness stack when initiating a force close. This +Lightning Symmetry channel construction is close to [optimal]. + +### In [MATT] + +The Merkelize All The Things (MATT) framework proposes to use `OP_CAT` to +combine multiple items into a single commitment for use with +`OP_CHECKCONTRACTVERIFY`. `OP_PAIRCOMMIT` provides a more ergonomic way to +accomplish this[^4]. + +[^4]: `OP_CAT` can be used to commit to multiple items, but it is subject to + byte shifting attacks if used naively. + E.g. `0x0102 || 0x03` equals `0x01 || 0x0203`. Mitigating this correctly + requires either length checking, hashing, or both. + +## Alternative approaches + +The following list of alternative approaches were discussed and rejected for +various reasons, either for expanding the scope or for unnecessary complexity: + +* `OP_CAT`[^4][^7] +* SHA256 streaming opcodes[^7] +* Merkle operation opcodes +* 'Kitty' CAT: `OP_CAT` with result or inputs arbitrarily limited in size +* `OP_CHECKTEMPLATEVERIFY` committing to the taproot annex in tapscript[^5] +* `OP_CHECKSIGFROMSTACK` on n elements as message +* `OP_VECTORCOMMIT`: generalized form for n > 2 elements +* ReKey/Laddering[^2] +* `OP_RETURN`[^6] + +[^5]: As seen in Greg Sanders' [Lightning Symmetry write-up], one additional + item can be committed to by a transaction signature by placing that item + in the Taproot annex. This mechanism is limited to a single additional + item and that item is not made accessible to script making it less useful. +[^6]: `OP_RETURN` can also be used to cause a transaction signature or CTV + hash to commit to additional data items. This is both costly for the user, + as this inexpensive to validate data is pushed into transaction data + instead of witness data and not accessible to script making it less useful + like the annex. +[^7]: `OP_PAIRCOMMIT` is intended to enable more useful bitcoin scripts, in + some cases similar to those enabled by `OP_CAT` but without also enabling + unexpected script behaviors such as those described by Andrew Poelstra in + [CAT-tricks-I] and [CAT-tricks-II] or larger numeric operations. + +## Reference Implementation + +### Code + +```c++ +case OP_PAIRCOMMIT: { + // OP_PAIRCOMMIT is only available in Tapscript + // ... + // x1 x2 -- hash + if (stack.size() < 2) { + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + } + const valtype& vch1 = stacktop(-2); + const valtype& vch2 = stacktop(-1); + + uint256 hash = PairCommitHash(vch1, vch2); + + stack.pop_back(); + stack.pop_back(); + stack.emplace_back(hash.begin(), hash.end()); + break; +} +``` +```c++ +const HashWriter HASHER_PAIRCOMMIT{TaggedHash("PairCommit")}; + +uint256 PairCommitHash(const std::vector& x1, const std::vector& x2) +{ + return (HashWriter{HASHER_PAIRCOMMIT} << x1 << x2).GetSHA256(); +} +``` + +### PR + +https://github.com/lnhance/bitcoin/pull/6/files + +## Rationale + +### Cost comparison of Lightning Symmetry constructions + +The following table briefly summarizes the costs associated with force closing +Lightning Symmetry channels enabled by various combinations of proposed script +upgrades. + +| 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 | +| CTV+CSFS+IKEY+PC | 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 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* + +### Proving general computation using trees + +One potential risk of PAIRCOMMIT is that it may enable verification of general +computations on bitcoin. + +Any script change which enables commitment to pairs of items necessarily +enables commitments to Merkle trees. + +Merkle trees can be used to prove computation where the root of the tree +represents the *function* and the leaves represent the *inputs* and *output*. +There are practical limits to the total number of discrete output values that +can be reached by all possible input values (i.e. the input entropy space) as +they must be enumerated and hashed into a Merkle root. + +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. +Therefore, we conclude that enabling Merkle commitments in script does not +materially extend what computations are possible to validate in bitcoin +script. While PAIRCOMMIT is not explicitly limited to a height of 128, greater +heights are not practical to Merkelize. + +## Backward Compatibility + +By constraining the behavior of OP_SUCCESS opcodes, deployment of the BIP +can be done in a backwards-compatible, soft-fork manner. If anyone were to +rely on the OP_SUCCESS behavior of `OP_SUCCESS205`, `OP_PAIRCOMMIT` would +invalidate their spend. + +## Deployment + +TBD + +## Credits + +Jeremy Rubin, Salvatore Ingala, Anthony Towns, Ademan555 + +## Copyright + +This document is licensed under the 3-clause BSD license. + +## References + +1. LNhance bitcoin repository: [lnhance] +2. Lightning Symmetry: [eltoo] +3. OP_CAT: [BIP-347], [BIN-2024-0001] +4. OP_CHECKTEMPLATEVERIFY: [BIP-119] +5. OP_CHECKSIGFROMSTACK: [BIP-348], [BIN-2024-0003] +6. OP_INTERNALKEY: [BIP-349], [BIN-2024-0004] +7. Tagged hash: [BIP-340] + +[lnhance]: https://github.com/lnhance/bitcoin +[eltoo]: https://github.com/instagibbs/bolts/blob/eltoo_draft/XX-eltoo-transactions.md +[CAT-tricks-I]: https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 +[CAT-tricks-II]: https://medium.com/blockstream/cat-and-schnorr-tricks-ii-2f6ede3d7bb5 +[MATT]: https://merkle.fun +[Lightning Symmetry write-up]: https://delvingbitcoin.org/t/ln-symmetry-project-recap/359 +[key laddering post]: https://rubin.io/bitcoin/2024/12/02/csfs-ctv-rekey-symmetry/ + +[//]: # (BIPs referenced) +[BIP-119]: https://github.com/bitcoin/bips/tree/master/bip-0119.mediawiki +[BIP-327]: https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki +[BIP-340]: https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki +[BIP-347]: https://github.com/bitcoin/bips/blob/master/bip-0347.mediawiki +[BIP-348]: https://github.com/bitcoin/bips/blob/master/bip-0348.md +[BIP-349]: https://github.com/bitcoin/bips/blob/master/bip-0349.md +[BIN-2024-0001]: https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0001.md +[BIN-2024-0003]: https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0003.md +[BIN-2024-0004]: https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0004.md + +[//]: # (Internal links) +[optimal]: #cost-comparison-of-ln-symmetry-constructions +