Skip to content

Commit 010405d

Browse files
committed
Add: PAIRCOMMIT
1 parent c58a428 commit 010405d

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed

bip-PC.mediawiki

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
| BIN-2024-006 | `OP_PAIRCOMMIT`
2+
| :------------ | :-------
3+
| Revision | 006 (2024-11-08)
4+
| Author | moonsettler `<[email protected]>`
5+
| |
6+
| Layer | Consensus (soft fork)
7+
| Status | Draft
8+
| License | BSD-3-CLAUSE
9+
| |
10+
| Discussion | [https://delvingbitcoin.org/t/op-paircommit-as-a-candidate-for-addition-to-lnhance/1216/12]
11+
| Aliases | [BIPs PR#????](https://github.com/bitcoin/bips/pull/?)
12+
13+
## Abstract
14+
15+
This BIP describes a new tapscript opcode `OP_PAIRCOMMIT` which
16+
provide limited vector commitment functionality in tapscript.
17+
18+
When evaluated, the `OP_PAIRCOMMIT` instruction:
19+
* Pops the top two values off the stack,
20+
* takes the "PairCommit" tagged SHA256 hash of the stack elements,
21+
* pushes the resulting commitment on the top of the stack.
22+
23+
## Motivation
24+
25+
To do LN-Symmetry contracts that don't require the nodes to keep old states,
26+
we need to solve the data availability problem presented by unilateral closes.
27+
Channel peers must be able to reconstruct the script that spends an
28+
intermediate state.
29+
30+
Using in sequence `OP_CHECKTEMPLATEVERIFY`, `OP_PAIRCOMMIT`, `OP_INTERNALKEY`
31+
and `OP_CHECKSIGFROMSTACK` we can construct a rebindable channel that is also
32+
optimal.
33+
34+
If `OP_CAT` was available, it could be used to combine multiple stack elements,
35+
that get verified with `OP_CHECKSIGFROMSTACK` as a valid state update.
36+
37+
`OP_PAIRCOMMIT` solves this specific problem without introducing a wide range
38+
of potentially controversial new behaviors, such as novel 2-way peg mechanisms.
39+
40+
The number of SHA256 iterations is minimized in the primary use case we
41+
can optimize for, which is LN-Symmetry. Since the Tag can be pre-computed as
42+
mid-state, it would only take 1 or 2 hash cycles in validation for the
43+
unilateral close scenario.
44+
45+
## Specification
46+
47+
Repurpose opcode 205 (currently `OP_SUCCESS`) as follows:
48+
49+
`OP_PAIRCOMMIT` pops two elements off the stack, then concatenates them along
50+
with their size commitments and takes the tagged SHA256 hash of that
51+
concatenated string, then pushes the resulting hash back on the stack.
52+
53+
Given the stack `[x1, x2]`, where `x2` is at the top of the stack:
54+
55+
`OP_PAIRCOMMIT` will push `SHA256(tagPC|cs(x1)|x1|cs(x2)|x2)` onto the stack.
56+
57+
Where `|` denotes concatenation and `tagPC` is calculated according to BIP-340
58+
tagged hash as `SHA256("PairCommit")|SHA256("PairCommit")` and `cs(x)` means
59+
`CompactSize(x)`.
60+
61+
### Implementation
62+
63+
```c++
64+
case OP_PAIRCOMMIT: {
65+
// OP_PAIRCOMMIT is only available in Tapscript
66+
// ...
67+
// x1 x2 -- hash
68+
if (stack.size() < 2) {
69+
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
70+
}
71+
const valtype& vch1 = stacktop(-2);
72+
const valtype& vch2 = stacktop(-1);
73+
74+
uint256 hash = PairCommitHash(vch1, vch2);
75+
76+
popstack(stack);
77+
popstack(stack);
78+
stack.emplace_back(hash.begin(), hash.end());
79+
break;
80+
}
81+
```
82+
```c++
83+
const HashWriter HASHER_PAIRCOMMIT{TaggedHash("PairCommit")};
84+
85+
uint256 PairCommitHash(const std::vector<unsigned char>& x1, const std::vector<unsigned char>& x2)
86+
{
87+
return (HashWriter{HASHER_PAIRCOMMIT} << x1 << x2).GetSHA256();
88+
}
89+
```
90+
### Use in script
91+
92+
`OP_PAIRCOMMIT` can be used to commit to a vector of stack elements in a way
93+
that is not vulnerable to various forms of witness malleability. It is however,
94+
highly optimized for just 2 stack elements.
95+
96+
```text
97+
# pc-hash = PC(a, PC(b, c))
98+
99+
<a> <b> <c> | PC PC <pc-hash> OP_EQUALVERIFY
100+
```
101+
102+
### Use in LN-Symmetry
103+
104+
The following assembly-like pseudo-code shows a possible LN-Symmetry channel
105+
construction, that provides data availability to spend to the latest state from
106+
an earlier state pushed on-chain with a forced close by channel partner.
107+
108+
109+
```text
110+
# S = 500000000
111+
# IK -> A+B
112+
<sig> <state-n-recovery-data> <state-n-hash> | CTV PC IK CSFS <S+1> CLTV DROP
113+
```
114+
before funding sign first state template:
115+
```text
116+
# state-n-hash { nLockTime(S+n), out(contract, amount(A)+amount(B)) }
117+
# settlement-n-hash { nSequence(2w), out(A, amount(A)), out(B, amount(B)) }
118+
# state-n-recovery-data { settlement-n-hash or state-n-balance }
119+
120+
# contract for state n < m
121+
IF
122+
<sig> <state-m-recovery-data> <state-m-hash> | CTV PC IK CSFS <S+n+1> CLTV DROP
123+
ELSE
124+
<settlement-n-hash> CTV
125+
ENDIF
126+
```
127+
128+
## Reference Implementation
129+
130+
A reference implementation is provided here:
131+
132+
[https://github.com/lnhance/bitcoin/pull/6/files]
133+
134+
## Backward Compatibility
135+
136+
By constraining the behavior of OP_SUCCESS opcodes, deployment of the BIP
137+
can be done in a backwards compatible, soft-fork manner. If anyone were to
138+
rely on the OP_SUCCESS behavior of `OP_SUCCESS205`, `OP_PAIRCOMMIT` would
139+
invalidate their spend.
140+
141+
## Deployment
142+
143+
TBD
144+
145+
## Credits
146+
147+
Jeremy Rubin, Brandon Black, Salvatore Ingala, Anthony Towns
148+
149+
## Copyright
150+
151+
This document is licensed under the 3-clause BSD license.
152+
153+
## References
154+
155+
1. LNhance bitcoin repository ["LNhance"](https://github.com/lnhance/bitcoin)
156+
2. LN-Symmetry ["eltoo"](https://github.com/instagibbs/bolts/blob/eltoo_draft/XX-eltoo-transactions.md)
157+
3. OP_CAT, ["BIN-2024-0001"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0001.md)
158+
4. OP_CHECKTEMPLATEVERIFY, ["BIP 119"](https://github.com/bitcoin/bips/tree/master/bip-0119)
159+
5. OP_CHECKSIGFROMSTACK, ["BIN-2024-0003"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0003.md)
160+
6. OP_INTERNALKEY, ["BIN-2024-0004"](https://github.com/bitcoin-inquisition/binana/blob/master/2024/BIN-2024-0004.md)
161+
7. Tagged hash, ["BIP-340"](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki)

0 commit comments

Comments
 (0)