From 1975d2a73ea96599546c983a7a75ec9d58724e59 Mon Sep 17 00:00:00 2001 From: moonsettler Date: Tue, 29 Oct 2024 22:25:03 +0100 Subject: [PATCH 1/9] OP_PAIRCOMMIT --- 2024/BIN-2024-0006.md | 157 ++++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 2 files changed, 158 insertions(+) create mode 100644 2024/BIN-2024-0006.md diff --git a/2024/BIN-2024-0006.md b/2024/BIN-2024-0006.md new file mode 100644 index 0000000..3820cdd --- /dev/null +++ b/2024/BIN-2024-0006.md @@ -0,0 +1,157 @@ +| BIN-2024-006 | `OP_PAIRCOMMIT` +| :------------ | :------- +| Revision | 004 (2024-10-28) +| Author | moonsettler `` +| | +| Layer | Consensus (soft fork) +| Status | Draft +| License | BSD-3-CLAUSE +| | +| Discussion | [https://delvingbitcoin.org/t/op-paircommit-as-a-candidate-for-addition-to-lnhance/1216/12] +| Aliases | [BIPs PR#????(https://github.com/bitcoin/bips/pull/?)] + +## Abstract + +This BIP describes a new tapscript opcode `OP_PAIRCOMMIT` which +provide limited vector committment functionality. + +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 committment on the top of the stack. + +## Specification + +`OP_PAIRCOMMIT` pops two elements off the stack, then concatenates them along with their size committments and takes the tagged SHA256 hash of that concatenated string, then pushes the resulting hash back on the stack. + +Given the stack `[x1, x2]`, where `x2` is at the top of the stack: + +`OP_PAIRCOMMIT` will push `SHA256(tagPC|x1|x2|len(x1)|pad|len(x2)|pad)` onto the stack. + +Where `|` denotes concatenation and `tagPC` is `SHA256("PairCommit")|SHA256("PairCommit")` and `pad` is hex `00|00|00|01`. + +### Implementation + +```c++ +case OP_PAIRCOMMIT: { + // OP_PAIRCOMMIT is only available in Tapscript + if (sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0) return set_error(serror, SCRIPT_ERR_BAD_OPCODE); + if (flags & SCRIPT_VERIFY_DISCOURAGE_LNHANCE) { + return set_error(serror, SCRIPT_ERR_DISCOURAGE_OP_SUCCESS); + } + + // 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); + + popstack(stack); + popstack(stack); + stack.push_back(ToByteVector(hash)); + break; +} +``` +Serialization happens with little endian byte order as per default +```c++ +const HashWriter HASHER_PAIRCOMMIT{TaggedHash("PairCommit")}; + +uint256 PairCommitHash(Span x1, Span x2) +{ + // PAD is 0x00, 0x00, 0x00, 0x01 in little endian serializaton + static const uint32_t PCPAD = 0x01000000u; + + HashWriter ss{HASHER_PAIRCOMMIT}; + ss << x1 + << x2 + << uint32_t(x1.size()) << PCPAD + << uint32_t(x2.size()) << PCPAD; + + return ss.GetSHA256(); +} +``` +See more: https://github.com/lnhance/bitcoin/pull/6/files + +## Motivation + +Pair or vector committments are generally useful in a covenant script toolkit. +Finding the simplest and safest way to do such data committments, and making sure +to the outmost degree possible, that it would not intoduce unintended behavior, +such as novel 2-way peg mechanisms was the primary motivation for this proposal. + +The number of SHA256 iterations is minimized in the most likely use case we can +optimize for, which is LN-Symmetry. 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 for Symmetry channels. + +In case of a 7 byte balance commitment + 32 byte CTV hash (no HTLCs in-flight), +the total preimage size is 55 bytes. Which should make it fit into a single block +with the SHA256 length commitment. + +In case there are 2x 32 byte CTV hash commitments, the first 64 byte block is +comprised of those hashes, and the second block is the vectors’ size and total +length commitment, which would be a largely 0 filled block with a very few bits +set to 1. + +It’s a particular concern for LN-Symmetry with CTV that the concatenation of the two preimages allows for length redistribution attacks, because CTV is only defined for 32 byte templates and will act as NOP for different template sizes for upgradeability. + +### Vector Commitments + +`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 especially when used +in conjunction with `OP_CHECKSIGFROMSTACK`[^CSFS] and `OP_INTERNALKEY`[^IKEY], +since SHA256 implicitly commits to size of the stack elements, making the script +cleaner, and simpler. If `OP_CAT`[^CAT] was used naively, the contract could be easily +broken since `OP_CHECKTEMPLATEVERIFY`[^CTV] is only defined for 32 byte parameters. + +```text +# S = 500000000 +# IK -> A+B + | CTV PC IK CSFSV CLTV +``` +before funding sign first state template: +```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 } + +# contract for state n < m +IF + | CTV PC IK CSFSV CLTV +ELSE + CTV +ENDIF +``` + +## Reference Implementation + +A reference implementation is provided here: + +https://github.com/? + +## 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, Brandon Black, Salvatore Ingala + +## Copyright + +This document is licensed under the 3-clause BSD license. + +[^CAT]: OP_CAT, ["BIN-2024-0001"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0001.md) +[^CTV]: OP_CHECKTEMPLATEVERIFY, ["BIP 119"](https://github.com/bitcoin/bips/tree/master/bip-0119) +[^CSFS]: OP_CHECKSIGFROMSTACK, ["BIN-2024-0003"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0003.md) +[^IKEY]: OP_INTERNALKEY, ["BIN-2024-0004"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0004.md) \ No newline at end of file diff --git a/README.md b/README.md index 72682fe..1cc827b 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ may be identified by appending ".RRR", the three digit revision number. | BIN-2024-0003 | Draft | [`CHECKSIGFROMSTACK`](2024/BIN-2024-0003.md) | BIN-2024-0004 | Draft | [`OP_INTERNALKEY`](2024/BIN-2024-0004.md) | BIN-2024-0005 | Info | [Bitcoin Related Specifications](2024/BIN-2024-0005.md) +| BIN-2024-0006 | Draft | [`OP_PAIRCOMMIT`](2024/BIN-2024-0006.md) ## Notes From 6ece8effa48710435f8f2e7c8a76d34b6c4ace40 Mon Sep 17 00:00:00 2001 From: moonsettler Date: Thu, 31 Oct 2024 23:18:54 +0100 Subject: [PATCH 2/9] Minor corrections, rev5 Use CSFS in Symmetry Omit activation related details from spec --- 2024/BIN-2024-0006.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/2024/BIN-2024-0006.md b/2024/BIN-2024-0006.md index 3820cdd..36dd435 100644 --- a/2024/BIN-2024-0006.md +++ b/2024/BIN-2024-0006.md @@ -1,6 +1,6 @@ | BIN-2024-006 | `OP_PAIRCOMMIT` | :------------ | :------- -| Revision | 004 (2024-10-28) +| Revision | 005 (2024-10-31) | Author | moonsettler `` | | | Layer | Consensus (soft fork) @@ -35,11 +35,7 @@ Where `|` denotes concatenation and `tagPC` is `SHA256("PairCommit")|SHA256("Pai ```c++ case OP_PAIRCOMMIT: { // OP_PAIRCOMMIT is only available in Tapscript - if (sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0) return set_error(serror, SCRIPT_ERR_BAD_OPCODE); - if (flags & SCRIPT_VERIFY_DISCOURAGE_LNHANCE) { - return set_error(serror, SCRIPT_ERR_DISCOURAGE_OP_SUCCESS); - } - + // ... // x1 x2 -- hash if (stack.size() < 2) { return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -96,21 +92,24 @@ comprised of those hashes, and the second block is the vectors’ size and total length commitment, which would be a largely 0 filled block with a very few bits set to 1. -It’s a particular concern for LN-Symmetry with CTV that the concatenation of the two preimages allows for length redistribution attacks, because CTV is only defined for 32 byte templates and will act as NOP for different template sizes for upgradeability. +It’s a particular concern for LN-Symmetry with CTV that the concatenation of the +two preimages allows for length redistribution attacks, because CTV is only defined +for 32 byte templates and will act as NOP for different template sizes for +upgradeability. ### Vector Commitments `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 especially when used in conjunction with `OP_CHECKSIGFROMSTACK`[^CSFS] and `OP_INTERNALKEY`[^IKEY], -since SHA256 implicitly commits to size of the stack elements, making the script -cleaner, and simpler. If `OP_CAT`[^CAT] was used naively, the contract could be easily -broken since `OP_CHECKTEMPLATEVERIFY`[^CTV] is only defined for 32 byte parameters. +making the script cleaner, and simpler. If `OP_CAT`[^CAT] was used naively, the +contract could be easily broken since `OP_CHECKTEMPLATEVERIFY`[^CTV] is only +defined for 32 byte parameters. ```text # S = 500000000 # IK -> A+B - | CTV PC IK CSFSV CLTV + | CTV PC IK CSFS CLTV DROP ``` before funding sign first state template: ```text @@ -120,7 +119,7 @@ before funding sign first state template: # contract for state n < m IF - | CTV PC IK CSFSV CLTV + | CTV PC IK CSFS CLTV DROP ELSE CTV ENDIF From 1374595bc1c08c32a80656f203bcdebaf47b308e Mon Sep 17 00:00:00 2001 From: moonsettler Date: Fri, 8 Nov 2024 18:22:26 +0100 Subject: [PATCH 3/9] rev 6 --- 2024/BIN-2024-0006.md | 114 ++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 55 deletions(-) diff --git a/2024/BIN-2024-0006.md b/2024/BIN-2024-0006.md index 36dd435..f8fe6c9 100644 --- a/2024/BIN-2024-0006.md +++ b/2024/BIN-2024-0006.md @@ -1,6 +1,6 @@ | BIN-2024-006 | `OP_PAIRCOMMIT` | :------------ | :------- -| Revision | 005 (2024-10-31) +| Revision | 006 (2024-11-08) | Author | moonsettler `` | | | Layer | Consensus (soft fork) @@ -8,27 +8,54 @@ | License | BSD-3-CLAUSE | | | Discussion | [https://delvingbitcoin.org/t/op-paircommit-as-a-candidate-for-addition-to-lnhance/1216/12] -| Aliases | [BIPs PR#????(https://github.com/bitcoin/bips/pull/?)] +| Aliases | [BIPs PR#????](https://github.com/bitcoin/bips/pull/?) ## Abstract This BIP describes a new tapscript opcode `OP_PAIRCOMMIT` which -provide limited vector committment functionality. +provide limited vector committment 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 committment on the top of the stack. +## Motivation + +To do LN-Symmetry contracts that don't require the nodes to keep old states, +we need to solve the data avilability problem presented by unilateral closes. +Channel peers must be able to reconstruct the script that spends an +intermediate state. + +Using in sequence `OP_CHECKTEMPLATEVERIFY`, `OP_PAIRCOMMIT`, `OP_INTERNALKEY` +and `OP_CHECKSIGFROMSTACK` we can construct a rebindable channel that is also +optimal. + +If `OP_CAT` was available, it could be used to combine multiple stack elements, +that get verified with `OP_CHECKSIGFROMSTACK` as a valid state update. + +`OP_PAIRCOMMIT` solves this specific problem without introducing a wide range +of potentially controversial new behaviors, such as novel 2-way peg mechanisms. + +The number of SHA256 iterations is minimized in the primary use case we +can optimize for, which is LN-Symmetry. 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. + ## Specification -`OP_PAIRCOMMIT` pops two elements off the stack, then concatenates them along with their size committments and takes the tagged SHA256 hash of that concatenated string, then pushes the resulting hash back on the stack. +Repurpose opcode 205 (currently `OP_SUCCESS`) as follows: + +`OP_PAIRCOMMIT` pops two elements off the stack, then concatenates them along +with their size committments and takes the tagged SHA256 hash of that +concatenated string, then pushes the resulting hash back on the stack. Given the stack `[x1, x2]`, where `x2` is at the top of the stack: -`OP_PAIRCOMMIT` will push `SHA256(tagPC|x1|x2|len(x1)|pad|len(x2)|pad)` onto the stack. +`OP_PAIRCOMMIT` will push `SHA256(tagPC|cs(x1)|x1|cs(x2)|x2)` onto the stack. -Where `|` denotes concatenation and `tagPC` is `SHA256("PairCommit")|SHA256("PairCommit")` and `pad` is hex `00|00|00|01`. +Where `|` denotes concatenation and `tagPC` is generated according to [^BIP340] +as `SHA256("PairCommit")|SHA256("PairCommit")` and `cs(x)` means `CompactSize(x)`. ### Implementation @@ -47,64 +74,36 @@ case OP_PAIRCOMMIT: { popstack(stack); popstack(stack); - stack.push_back(ToByteVector(hash)); + stack.emplace_back(hash.begin(), hash.end()); break; } ``` -Serialization happens with little endian byte order as per default ```c++ const HashWriter HASHER_PAIRCOMMIT{TaggedHash("PairCommit")}; -uint256 PairCommitHash(Span x1, Span x2) +uint256 PairCommitHash(const std::vector& x1, const std::vector& x2) { - // PAD is 0x00, 0x00, 0x00, 0x01 in little endian serializaton - static const uint32_t PCPAD = 0x01000000u; - - HashWriter ss{HASHER_PAIRCOMMIT}; - ss << x1 - << x2 - << uint32_t(x1.size()) << PCPAD - << uint32_t(x2.size()) << PCPAD; - - return ss.GetSHA256(); + return (HashWriter{HASHER_PAIRCOMMIT} << x1 << x2).GetSHA256(); } ``` -See more: https://github.com/lnhance/bitcoin/pull/6/files - -## Motivation +### Use in script -Pair or vector committments are generally useful in a covenant script toolkit. -Finding the simplest and safest way to do such data committments, and making sure -to the outmost degree possible, that it would not intoduce unintended behavior, -such as novel 2-way peg mechanisms was the primary motivation for this proposal. +`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. -The number of SHA256 iterations is minimized in the most likely use case we can -optimize for, which is LN-Symmetry. 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 for Symmetry channels. - -In case of a 7 byte balance commitment + 32 byte CTV hash (no HTLCs in-flight), -the total preimage size is 55 bytes. Which should make it fit into a single block -with the SHA256 length commitment. +```text +# pc-hash = PC(a, PC(b, c)) -In case there are 2x 32 byte CTV hash commitments, the first 64 byte block is -comprised of those hashes, and the second block is the vectors’ size and total -length commitment, which would be a largely 0 filled block with a very few bits -set to 1. + | PC PC OP_EQUALVERIFY +``` -It’s a particular concern for LN-Symmetry with CTV that the concatenation of the -two preimages allows for length redistribution attacks, because CTV is only defined -for 32 byte templates and will act as NOP for different template sizes for -upgradeability. +### Use in LN-Symmetry -### Vector Commitments +The following assembly-like pseudo-code shows a possible LN-Syymetry channel +conctruction, that provides data availability to spend to the latest state from +an earlier state pushed on-chain with a forced close by channel partner. -`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 especially when used -in conjunction with `OP_CHECKSIGFROMSTACK`[^CSFS] and `OP_INTERNALKEY`[^IKEY], -making the script cleaner, and simpler. If `OP_CAT`[^CAT] was used naively, the -contract could be easily broken since `OP_CHECKTEMPLATEVERIFY`[^CTV] is only -defined for 32 byte parameters. ```text # S = 500000000 @@ -129,7 +128,7 @@ ENDIF A reference implementation is provided here: -https://github.com/? +[https://github.com/lnhance/bitcoin/pull/6/files] ## Backward Compatibility @@ -144,13 +143,18 @@ TBD ## Credits -Jeremy Rubin, Brandon Black, Salvatore Ingala +Jeremy Rubin, Brandon Black, Salvatore Ingala, Anthony Towns ## Copyright This document is licensed under the 3-clause BSD license. -[^CAT]: OP_CAT, ["BIN-2024-0001"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0001.md) -[^CTV]: OP_CHECKTEMPLATEVERIFY, ["BIP 119"](https://github.com/bitcoin/bips/tree/master/bip-0119) -[^CSFS]: OP_CHECKSIGFROMSTACK, ["BIN-2024-0003"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0003.md) -[^IKEY]: OP_INTERNALKEY, ["BIN-2024-0004"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0004.md) \ No newline at end of file +## References + +1. LNhance bitcoin repository ["LNhance"](https://github.com/lnhance/bitcoin) +2. LN-Symmetry ["eltoo"](https://github.com/instagibbs/bolts/blob/eltoo_draft/XX-eltoo-transactions.md) +3. OP_CAT, ["BIN-2024-0001"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0001.md) +4. OP_CHECKTEMPLATEVERIFY, ["BIP 119"](https://github.com/bitcoin/bips/tree/master/bip-0119) +5. OP_CHECKSIGFROMSTACK, ["BIN-2024-0003"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0003.md) +6. OP_INTERNALKEY, ["BIN-2024-0004"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0004.md) +7. Tagged hash, ["BIP-340"](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) \ No newline at end of file From c6c35242f59752ca26ef993c48fa78be6a25c3db Mon Sep 17 00:00:00 2001 From: moonsettler Date: Fri, 8 Nov 2024 18:39:18 +0100 Subject: [PATCH 4/9] Fix bip-340 tagged hash reference --- 2024/BIN-2024-0006.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/2024/BIN-2024-0006.md b/2024/BIN-2024-0006.md index f8fe6c9..df74420 100644 --- a/2024/BIN-2024-0006.md +++ b/2024/BIN-2024-0006.md @@ -54,8 +54,9 @@ Given the stack `[x1, x2]`, where `x2` is at the top of the stack: `OP_PAIRCOMMIT` will push `SHA256(tagPC|cs(x1)|x1|cs(x2)|x2)` onto the stack. -Where `|` denotes concatenation and `tagPC` is generated according to [^BIP340] -as `SHA256("PairCommit")|SHA256("PairCommit")` and `cs(x)` means `CompactSize(x)`. +Where `|` denotes concatenation and `tagPC` is calculated according to BIP-340 +tagged hash as `SHA256("PairCommit")|SHA256("PairCommit")` and `cs(x)` means +`CompactSize(x)`. ### Implementation From bd11538247d21809bddd923a6d7cb69693c7e3fc Mon Sep 17 00:00:00 2001 From: moonsettler Date: Mon, 11 Nov 2024 23:52:40 +0100 Subject: [PATCH 5/9] Fix: grammar --- 2024/BIN-2024-0006.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/2024/BIN-2024-0006.md b/2024/BIN-2024-0006.md index df74420..7f5a514 100644 --- a/2024/BIN-2024-0006.md +++ b/2024/BIN-2024-0006.md @@ -13,17 +13,17 @@ ## Abstract This BIP describes a new tapscript opcode `OP_PAIRCOMMIT` which -provide limited vector committment functionality in tapscript. +provide 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 committment on the top of the stack. +* pushes the resulting commitment on the top of the stack. ## Motivation To do LN-Symmetry contracts that don't require the nodes to keep old states, -we need to solve the data avilability problem presented by unilateral closes. +we need to solve the data availability problem presented by unilateral closes. Channel peers must be able to reconstruct the script that spends an intermediate state. @@ -47,7 +47,7 @@ unilateral close scenario. Repurpose opcode 205 (currently `OP_SUCCESS`) as follows: `OP_PAIRCOMMIT` pops two elements off the stack, then concatenates them along -with their size committments and takes the tagged SHA256 hash of that +with their size commitments and takes the tagged SHA256 hash of that concatenated string, then pushes the resulting hash back on the stack. Given the stack `[x1, x2]`, where `x2` is at the top of the stack: @@ -101,8 +101,8 @@ highly optimized for just 2 stack elements. ### Use in LN-Symmetry -The following assembly-like pseudo-code shows a possible LN-Syymetry channel -conctruction, that provides data availability to spend to the latest state from +The following assembly-like pseudo-code shows a possible LN-Symmetry channel +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. From 1a186bb4f474cb0ee4ef929c85ce1ca80bb0371f Mon Sep 17 00:00:00 2001 From: moonsettler Date: Tue, 26 Nov 2024 00:26:22 +0100 Subject: [PATCH 6/9] rev 8 --- 2024/BIN-2024-0006.md | 81 ++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 21 deletions(-) diff --git a/2024/BIN-2024-0006.md b/2024/BIN-2024-0006.md index 7f5a514..2039dcc 100644 --- a/2024/BIN-2024-0006.md +++ b/2024/BIN-2024-0006.md @@ -1,19 +1,19 @@ | BIN-2024-006 | `OP_PAIRCOMMIT` | :------------ | :------- -| Revision | 006 (2024-11-08) +| Revision | 008 (2024-11-26) | Author | moonsettler `` | | | Layer | Consensus (soft fork) | Status | Draft | License | BSD-3-CLAUSE | | -| Discussion | [https://delvingbitcoin.org/t/op-paircommit-as-a-candidate-for-addition-to-lnhance/1216/12] -| Aliases | [BIPs PR#????](https://github.com/bitcoin/bips/pull/?) +| Discussion | [delvingbitcoin](https://delvingbitcoin.org/t/op-paircommit-as-a-candidate-for-addition-to-lnhance/1216/12) +| Aliases | [BIPs PR#1699](https://github.com/bitcoin/bips/pull/1699) ## Abstract This BIP describes a new tapscript opcode `OP_PAIRCOMMIT` which -provide limited vector commitment functionality in tapscript. +provides limited vector commitment functionality in tapscript. When evaluated, the `OP_PAIRCOMMIT` instruction: * Pops the top two values off the stack, @@ -31,12 +31,6 @@ Using in sequence `OP_CHECKTEMPLATEVERIFY`, `OP_PAIRCOMMIT`, `OP_INTERNALKEY` and `OP_CHECKSIGFROMSTACK` we can construct a rebindable channel that is also optimal. -If `OP_CAT` was available, it could be used to combine multiple stack elements, -that get verified with `OP_CHECKSIGFROMSTACK` as a valid state update. - -`OP_PAIRCOMMIT` solves this specific problem without introducing a wide range -of potentially controversial new behaviors, such as novel 2-way peg mechanisms. - The number of SHA256 iterations is minimized in the primary use case we can optimize for, which is LN-Symmetry. Since the Tag can be pre-computed as mid-state, it would only take 1 or 2 hash cycles in validation for the @@ -54,9 +48,9 @@ Given the stack `[x1, x2]`, where `x2` is at the top of the stack: `OP_PAIRCOMMIT` will push `SHA256(tagPC|cs(x1)|x1|cs(x2)|x2)` onto the stack. -Where `|` denotes concatenation and `tagPC` is calculated according to BIP-340 -tagged hash as `SHA256("PairCommit")|SHA256("PairCommit")` and `cs(x)` means -`CompactSize(x)`. +Where `|` denotes concatenation and `tagPC` is calculated according to +[BIP-340] tagged hash as `SHA256("PairCommit")|SHA256("PairCommit")` and +`cs(x)` means `CompactSize(x)`. ### Implementation @@ -129,7 +123,42 @@ ENDIF A reference implementation is provided here: -[https://github.com/lnhance/bitcoin/pull/6/files] +https://github.com/lnhance/bitcoin/pull/6/files + +## Rationale + +If `OP_CAT` was available, it could be used to combine multiple stack elements, +that get verified with `OP_CHECKSIGFROMSTACK` as a valid state update. + +`OP_PAIRCOMMIT` solves this specific problem without introducing a wide range +of potentially controversial new behaviors, such as novel 2-way peg mechanisms. + +`OP_RETURN` could also be used for ensuring the availability of the state +recovery data as `OP_CHECKTEMPLATEVERIFY` naturally commits to all outputs. +However the cost of that would be over 4 times higher in weight units. + +### Behaviours LNhance tries to avoid introducing + +The following behaviors are out of scope for LNhance and should not be enabled +as a side effect without explicit consensus: + +* Fine grained introspection +* State carrying covenants +* Bigint operations +* New arithmetic capabilities using lookup tables + +### 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 +* SHA256 streaming opcodes +* 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 +* OP_VECTORCOMMIT: generalized form for n > 2 elements ## Backward Compatibility @@ -152,10 +181,20 @@ This document is licensed under the 3-clause BSD license. ## References -1. LNhance bitcoin repository ["LNhance"](https://github.com/lnhance/bitcoin) -2. LN-Symmetry ["eltoo"](https://github.com/instagibbs/bolts/blob/eltoo_draft/XX-eltoo-transactions.md) -3. OP_CAT, ["BIN-2024-0001"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0001.md) -4. OP_CHECKTEMPLATEVERIFY, ["BIP 119"](https://github.com/bitcoin/bips/tree/master/bip-0119) -5. OP_CHECKSIGFROMSTACK, ["BIN-2024-0003"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0003.md) -6. OP_INTERNALKEY, ["BIN-2024-0004"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0004.md) -7. Tagged hash, ["BIP-340"](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) \ No newline at end of file +1. LNhance bitcoin repository: [lnhance] +2. LN-Symmetry: [eltoo] +3. OP_CAT: [BIP-347], [BIN-2024-0001] +4. OP_CHECKTEMPLATEVERIFY: [BIP-119] +5. OP_CHECKSIGFROMSTACK: [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 +[BIP-119]: https://github.com/bitcoin/bips/tree/master/bip-0119.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-349]: https://github.com/bitcoin/bips/blob/master/bip-0349.mediawiki +[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 \ No newline at end of file From a7522a67da71c958979ff8d0f1ba7d42df736057 Mon Sep 17 00:00:00 2001 From: moonsettler Date: Wed, 27 Nov 2024 20:45:41 +0100 Subject: [PATCH 7/9] rev 9 - Proving general computation --- 2024/BIN-2024-0006.md | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/2024/BIN-2024-0006.md b/2024/BIN-2024-0006.md index 2039dcc..0128901 100644 --- a/2024/BIN-2024-0006.md +++ b/2024/BIN-2024-0006.md @@ -1,6 +1,6 @@ | BIN-2024-006 | `OP_PAIRCOMMIT` | :------------ | :------- -| Revision | 008 (2024-11-26) +| Revision | 009 (2024-11-26) | Author | moonsettler `` | | | Layer | Consensus (soft fork) @@ -28,8 +28,8 @@ Channel peers must be able to reconstruct the script that spends an intermediate state. Using in sequence `OP_CHECKTEMPLATEVERIFY`, `OP_PAIRCOMMIT`, `OP_INTERNALKEY` -and `OP_CHECKSIGFROMSTACK` we can construct a rebindable channel that is also -optimal. +and `OP_CHECKSIGFROMSTACK` we can construct a [rebindable channel]( +#use-in-ln-symmetry) that is also optimal. The number of SHA256 iterations is minimized in the primary use case we can optimize for, which is LN-Symmetry. Since the Tag can be pre-computed as @@ -118,7 +118,6 @@ ELSE CTV ENDIF ``` - ## Reference Implementation A reference implementation is provided here: @@ -160,6 +159,25 @@ various reasons, either for expanding the scope or for unnecessary complexity: * OP_CHECKSIGFROMSTACK on n elements as message * OP_VECTORCOMMIT: generalized form for n > 2 elements +### 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*. + ## Backward Compatibility By constraining the behavior of OP_SUCCESS opcodes, deployment of the BIP @@ -173,7 +191,7 @@ TBD ## Credits -Jeremy Rubin, Brandon Black, Salvatore Ingala, Anthony Towns +Jeremy Rubin, Brandon Black, Salvatore Ingala, Anthony Towns, Ademan555 ## Copyright @@ -185,7 +203,7 @@ This document is licensed under the 3-clause BSD license. 2. LN-Symmetry: [eltoo] 3. OP_CAT: [BIP-347], [BIN-2024-0001] 4. OP_CHECKTEMPLATEVERIFY: [BIP-119] -5. OP_CHECKSIGFROMSTACK: [BIN-2024-0003] +5. OP_CHECKSIGFROMSTACK: [BIP-348], [BIN-2024-0003] 6. OP_INTERNALKEY: [BIP-349], [BIN-2024-0004] 7. Tagged hash: [BIP-340] @@ -193,8 +211,9 @@ This document is licensed under the 3-clause BSD license. [eltoo]: https://github.com/instagibbs/bolts/blob/eltoo_draft/XX-eltoo-transactions.md [BIP-119]: https://github.com/bitcoin/bips/tree/master/bip-0119.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-349]: https://github.com/bitcoin/bips/blob/master/bip-0349.mediawiki +[BIP-347]: https://github.com/bitcoin/bips/blob/master/bip-0347.md +[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 \ No newline at end of file From 6aa957ce16bf99c7d03f59b9f8761b301113e262 Mon Sep 17 00:00:00 2001 From: moonsettler Date: Wed, 4 Dec 2024 00:53:21 +0100 Subject: [PATCH 8/9] Fix: popstack(stack) -> stack.pop_back() popstack() has a redundant check @Psifour --- 2024/BIN-2024-0006.md | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/2024/BIN-2024-0006.md b/2024/BIN-2024-0006.md index 0128901..19bf380 100644 --- a/2024/BIN-2024-0006.md +++ b/2024/BIN-2024-0006.md @@ -1,6 +1,6 @@ | BIN-2024-006 | `OP_PAIRCOMMIT` | :------------ | :------- -| Revision | 009 (2024-11-26) +| Revision | 010 (2024-12-03) | Author | moonsettler `` | | | Layer | Consensus (soft fork) @@ -22,14 +22,14 @@ When evaluated, the `OP_PAIRCOMMIT` instruction: ## Motivation -To do LN-Symmetry contracts that don't require the nodes to keep old states, +To do [LN-Symmetry] contracts that don't require the nodes to keep old states, we need to solve the data availability problem presented by unilateral closes. Channel peers must be able to reconstruct the script that spends an intermediate state. Using in sequence `OP_CHECKTEMPLATEVERIFY`, `OP_PAIRCOMMIT`, `OP_INTERNALKEY` -and `OP_CHECKSIGFROMSTACK` we can construct a [rebindable channel]( -#use-in-ln-symmetry) that is also optimal. +and `OP_CHECKSIGFROMSTACK` we can construct a [rebindable channel] that is also +optimal. The number of SHA256 iterations is minimized in the primary use case we can optimize for, which is LN-Symmetry. Since the Tag can be pre-computed as @@ -67,8 +67,8 @@ case OP_PAIRCOMMIT: { uint256 hash = PairCommitHash(vch1, vch2); - popstack(stack); - popstack(stack); + stack.pop_back(); + stack.pop_back(); stack.emplace_back(hash.begin(), hash.end()); break; } @@ -118,6 +118,14 @@ ELSE CTV ENDIF ``` + +### Use with future updates + +Detailed introspection opcodes would also need vector commitments when used +with `OP_CHECKSIGFROMSTACK`. + +`OP_CHECKCONTRACTVERIFY` would also need a way to carry complex data. + ## Reference Implementation A reference implementation is provided here: @@ -136,6 +144,11 @@ of potentially controversial new behaviors, such as novel 2-way peg mechanisms. recovery data as `OP_CHECKTEMPLATEVERIFY` naturally commits to all outputs. However the cost of that would be over 4 times higher in weight units. +One way to think about the 3 opcodes (`OP_CHECKSIGFROMSTACK`, `OP_INTERNALKEY`, +`OP_PAIRCOMMIT`) is we decompose a `OP_CHECKSIGFROMSTACK` variant that can use +1 byte `OP_TRUE` public key (substitute for the *taproot internal key*) and can +commit to a number of stack elements as message. + ### Behaviours LNhance tries to avoid introducing The following behaviors are out of scope for LNhance and should not be enabled @@ -209,6 +222,8 @@ This document is licensed under the 3-clause BSD license. [lnhance]: https://github.com/lnhance/bitcoin [eltoo]: https://github.com/instagibbs/bolts/blob/eltoo_draft/XX-eltoo-transactions.md + +[//]: # (BIPs referenced) [BIP-119]: https://github.com/bitcoin/bips/tree/master/bip-0119.mediawiki [BIP-340]: https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki [BIP-347]: https://github.com/bitcoin/bips/blob/master/bip-0347.md @@ -216,4 +231,8 @@ This document is licensed under the 3-clause BSD license. [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 \ No newline at end of file +[BIN-2024-0004]: https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0004.md + +[//]: # (Internal links) +[LN-Symmetry]: #use-in-ln-symmetry +[rebindable channel]: #use-in-ln-symmetry \ No newline at end of file From 7764997a04b62271a2797324ba6c1276d4e73d9a Mon Sep 17 00:00:00 2001 From: moonsettler Date: Wed, 4 Dec 2024 22:08:41 +0100 Subject: [PATCH 9/9] Fix: bip-0347 link --- 2024/BIN-2024-0006.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2024/BIN-2024-0006.md b/2024/BIN-2024-0006.md index 19bf380..3fe7be1 100644 --- a/2024/BIN-2024-0006.md +++ b/2024/BIN-2024-0006.md @@ -226,7 +226,7 @@ This document is licensed under the 3-clause BSD license. [//]: # (BIPs referenced) [BIP-119]: https://github.com/bitcoin/bips/tree/master/bip-0119.mediawiki [BIP-340]: https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki -[BIP-347]: https://github.com/bitcoin/bips/blob/master/bip-0347.md +[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