Skip to content

Commit 9eedfb1

Browse files
committed
More readeable scripts & fix footnotes
1 parent 6b4b9a0 commit 9eedfb1

File tree

1 file changed

+59
-32
lines changed

1 file changed

+59
-32
lines changed

bip-0442.md

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Stack operation:
3333
- Pop `x2` and `x1` from the stack.
3434
- Push `pc` onto the stack.
3535

36-
[^1]: The number of SHA256 blocks is minimized in typical use cases. The tag can be pre-computed as a SHA256 mid-state, requiring only 2 hash cycles for two 32-byte items, or 1 for two smaller items.
36+
[^1]: The number of SHA256 blocks is minimized in typical use cases. The tag can be precomputed as a SHA256 mid-state, requiring only two hash cycles for two 32-byte items, or one for two smaller items.
3737

3838
## Motivation
3939

@@ -49,65 +49,91 @@ Combined with `OP_CHECKSIGFROMSTACK`, signing commitments to multiple items enab
4949

5050
`OP_PAIRCOMMIT` can commit to a vector of stack elements securely and efficiently.
5151

52-
```text
52+
```shell
5353
# Commit to three elements: a, b, c
5454
# pc-hash = PC(a, PC(b, c))
5555

56-
<a> <b> <c> OP_PAIRCOMMIT OP_PAIRCOMMIT <pc-hash> OP_EQUALVERIFY
56+
# Witness: <a> <b> <c>
57+
OP_PAIRCOMMIT # <a>, PC(b, c)
58+
OP_PAIRCOMMIT # PC(a, PC(b, c))
59+
OP_PUSHBYTES (pc-hash) # PC(a, PC(b, c)), <pc-hash>
60+
OP_EQUALVERIFY #
61+
# ...
5762
```
5863

5964
### Use in Lightning Symmetry
6065

61-
Lightning Symmetry contracts require data availability for contested closes. By forcing parties to include settlement transaction hashes in the witness, later updates can reconstruct scripts using only the latest state.
66+
Lightning Symmetry contracts require data availability for contested closes. [^3] By forcing parties to include settlement transaction hashes in the witness, later updates can reconstruct scripts using only the latest state.
6267
[^3]: 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.
6368

64-
Example channel script (pseudo-code):
65-
66-
```text
67-
# S = 500000000
68-
# internal key = [BIP-327] aggregate key of channel participants
69-
# state-n-hash { nLockTime(S+n), out(contract, amount(A)+amount(B)) }
70-
# settlement-n-hash { nSequence(2w), out(A, amount(A)), out(B, amount(B)) }
71-
# state-n-recovery-data { settlement-n-hash or state-n-balance }
72-
73-
<sig> <state-n-recovery-data> <state-n-hash> OP_CHECKTEMPLATEVERIFY OP_PAIRCOMMIT OP_INTERNALKEY OP_CHECKSIGFROMSTACK <S+1> OP_CLTV OP_DROP
69+
```shell
70+
# S: 500000000
71+
# internal-key: BIP-327 aggregate key of channel participants
72+
# state-n-hash: { nLockTime(S+n), out(contract, amount(A)+amount(B)) }
73+
# settlement-n-hash: { nSequence(2w), out(A, amount(A)), out(B, amount(B)) }
74+
# state-n-recovery-data: { settlement-n-hash or state-n-balance }
75+
```
76+
#### Example channel script (pseudo-code)
77+
78+
```shell
79+
# Witness: <sig> <state-n-recovery-data> <state-n-hash>
80+
OP_CHECKTEMPLATEVERIFY # <sig>, <state-n-recovery-data>, <state-n-hash>
81+
OP_PAIRCOMMIT # <sig>, PC(state-n-recovery-data, state-n-hash)
82+
OP_INTERNALKEY # <sig>, PC(state-n-recovery-data, state-n-hash), <internal-key>
83+
OP_CHECKSIGFROMSTACK # <1>
84+
OP_PUSHBYTES (S+1) # <1>, <S+1>
85+
OP_CHECKLOCKTIMEVERIFY # <1>, <S+1>
86+
OP_DROP # <1>
7487
```
7588

76-
Update script:
77-
78-
```text
79-
IF
80-
<sig> <state-m-recovery-data> <state-m-hash> OP_CHECKTEMPLATEVERIFY OP_PAIRCOMMIT OP_INTERNALKEY OP_CHECKSIGFROMSTACK <S+n+1> OP_CLTV OP_DROP
81-
ELSE
82-
<settlement-n-hash> OP_CHECKTEMPLATEVERIFY
83-
ENDIF
89+
#### Channel update script (pseudo-code) for m > n
90+
91+
```shell
92+
OP_IF
93+
# Witness: <sig> <state-m-recovery-data> <state-m-hash>
94+
OP_CHECKTEMPLATEVERIFY # <sig>, <state-m-recovery-data>, <state-m-hash>
95+
OP_PAIRCOMMIT # <sig>, PC(state-m-recovery-data, state-m-hash)
96+
OP_INTERNALKEY # <sig>, PC(state-m-recovery-data, state-m-hash), <internal-key>
97+
OP_CHECKSIGFROMSTACK # <1>
98+
OP_PUSHBYTES (S+n+1) # <1>, <S+n+1>
99+
OP_CHECKLOCKTIMEVERIFY # <1>, <S+n+1>
100+
OP_DROP # <1>
101+
OP_ELSE
102+
# Empty witness stack
103+
OP_PUSHBYTES (settlement-n-hash) # <settlement-n-hash>
104+
OP_CHECKTEMPLATEVERIFY # <settlement-n-hash>
105+
OP_0NOTEQUAL # <1>
106+
OP_ENDIF
84107
```
85108

86-
These constructions ensure both parties sign the same pair hash, requiring inclusion of both update and settlement hashes in the witness.
109+
These constructions ensure both parties sign the same pair hash, requiring inclusion of both update and settlement hashes in the witness. [^4] [^5]
110+
111+
[^4]: `state-n-hash` commits to a specific `nLockTime` value for the transaction through `OP_CHECKTEMPLATEVERIFY`; `OP_CHECKLOCKTIMEVERIFY` ensures that the state progression can only go forward (the transaction needs to have greater `nLockTime` value than the intermediate state
112+
[^5]: `OP_0NOTEQUAL` can be omitted (any non-zero value left on the stack would be accepted by the script interpreter).
87113

88114
### In MATT
89115

90-
The Merklize All The Things ([MATT]) framework uses `OP_CAT` to combine items for commitments. `OP_PAIRCOMMIT` provides a more ergonomic and secure alternative[^4].
116+
The Merklize All The Things ([MATT]) framework uses `OP_CAT` to combine items for commitments. `OP_PAIRCOMMIT` provides a more ergonomic and secure alternative[^6].
91117

92-
[^4]: Naive use of `OP_CAT` is vulnerable to byte shifting attacks. E.g. `0x0102 || 0x03` equals `0x01 || 0x0203`. Mitigation requires length checking or hashing.
118+
[^6]: Naive use of `OP_CAT` is vulnerable to byte shifting attacks. E.g. `0x0102 || 0x03` equals `0x01 || 0x0203`. Mitigation requires length checking or hashing.
93119

94120
## Alternative approaches
95121

96122
Alternative approaches considered and rejected:
97123

98-
- `OP_CAT`[^4][^7]
99-
- SHA256 streaming opcodes[^7]
124+
- `OP_CAT`[^6][^9]
125+
- SHA256 streaming opcodes[^9]
100126
- Merkle operation opcodes
101127
- 'Kitty' CAT: `OP_CAT` with size limits
102-
- `OP_CHECKTEMPLATEVERIFY` committing to the taproot annex[^5]
128+
- `OP_CHECKTEMPLATEVERIFY` committing to the taproot annex[^7]
103129
- `OP_CHECKSIGFROMSTACK` on n elements
104130
- `OP_VECTORCOMMIT`: generalized for n > 2 elements
105131
- ReKey/Laddering[^2]
106-
- `OP_RETURN`[^6]
132+
- `OP_RETURN`[^8]
107133

108-
[^5]: Committing to the taproot annex allows one additional item, but it is not accessible to script.
109-
[^6]: `OP_RETURN` can commit to additional data, but is costly and not accessible to script.
110-
[^7]: `OP_PAIRCOMMIT` enables useful scripts without the risks of `OP_CAT` (see [CAT-tricks-I], [CAT-tricks-II]).
134+
[^7]: Committing to the taproot annex allows one additional item, but it is not accessible to script.
135+
[^8]: `OP_RETURN` can commit to additional data, but is costly and not accessible to script.
136+
[^9]: `OP_PAIRCOMMIT` enables useful scripts without the risks of `OP_CAT` (see [CAT-tricks-I], [CAT-tricks-II]).
111137

112138
## Reference Implementation
113139

@@ -189,6 +215,7 @@ This document is licensed under the 3-clause BSD license.
189215
6. OP_CHECKCONTRACTVERIFY: [BIP-443]
190216
7. OP_INTERNALKEY: [BIP-349], [BIN-2024-0004]
191217
8. Tagged hash: [BIP-340]
218+
9. MuSig2: [BIP-327]
192219
193220
[lnhance]: https://github.com/lnhance/bitcoin
194221
[eltoo]: https://github.com/instagibbs/bolts/blob/eltoo_draft/XX-eltoo-transactions.md

0 commit comments

Comments
 (0)