├── 31-bit_commitment.md ├── README.md ├── atomic-swap.png ├── betcoins.md ├── bitwise_xor.md ├── composite-opcodes.md ├── decaying-multi-signature.md ├── integer-commitments.md ├── is-prime.md ├── maps.md ├── merkle-path-cat.md ├── merkle.md ├── modular-arithmetic.md ├── op_codeseparator.md ├── op_lookup.md ├── op_mul.md ├── op_rotate.md ├── op_rshift.md ├── preimage-sequence.md ├── proof-of-work.md ├── rock-paper-scissors.md ├── schnorr-magic.md ├── script-editor ├── index.html └── readme.md ├── split-into-bits.md ├── tic-tac-toe.md ├── tictactoe.png ├── token_auction.png └── weighted-multi-sig.md /31-bit_commitment.md: -------------------------------------------------------------------------------- 1 | # 31-Bit Commitment 2 | 3 | This is a 31-bit commitment in Bitcoin Script. 4 | 5 | ``` 6 | OP_DUP 7 | OP_TOALTSTACK 8 | 9 | OP_DUP 10 | <1073741824> 11 | OP_GREATERTHANOREQUAL 12 | OP_IF 13 | <1073741824> 14 | OP_SUB 15 | OP_SWAP 16 | OP_HASH256 17 | OP_ELSE 18 | OP_SWAP 19 | OP_ENDIF 20 | OP_HASH160 21 | OP_SWAP 22 | 23 | OP_DUP 24 | <536870912> 25 | OP_GREATERTHANOREQUAL 26 | OP_IF 27 | <536870912> 28 | OP_SUB 29 | OP_SWAP 30 | OP_HASH256 31 | OP_ELSE 32 | OP_SWAP 33 | OP_ENDIF 34 | OP_HASH160 35 | OP_SWAP 36 | 37 | OP_DUP 38 | <268435456> 39 | OP_GREATERTHANOREQUAL 40 | OP_IF 41 | <268435456> 42 | OP_SUB 43 | OP_SWAP 44 | OP_HASH256 45 | OP_ELSE 46 | OP_SWAP 47 | OP_ENDIF 48 | OP_HASH160 49 | OP_SWAP 50 | 51 | OP_DUP 52 | <134217728> 53 | OP_GREATERTHANOREQUAL 54 | OP_IF 55 | <134217728> 56 | OP_SUB 57 | OP_SWAP 58 | OP_HASH256 59 | OP_ELSE 60 | OP_SWAP 61 | OP_ENDIF 62 | OP_HASH160 63 | OP_SWAP 64 | 65 | OP_DUP 66 | <67108864> 67 | OP_GREATERTHANOREQUAL 68 | OP_IF 69 | <67108864> 70 | OP_SUB 71 | OP_SWAP 72 | OP_HASH256 73 | OP_ELSE 74 | OP_SWAP 75 | OP_ENDIF 76 | OP_HASH160 77 | OP_SWAP 78 | 79 | OP_DUP 80 | <33554432> 81 | OP_GREATERTHANOREQUAL 82 | OP_IF 83 | <33554432> 84 | OP_SUB 85 | OP_SWAP 86 | OP_HASH256 87 | OP_ELSE 88 | OP_SWAP 89 | OP_ENDIF 90 | OP_HASH160 91 | OP_SWAP 92 | 93 | OP_DUP 94 | <16777216> 95 | OP_GREATERTHANOREQUAL 96 | OP_IF 97 | <16777216> 98 | OP_SUB 99 | OP_SWAP 100 | OP_HASH256 101 | OP_ELSE 102 | OP_SWAP 103 | OP_ENDIF 104 | OP_HASH160 105 | OP_SWAP 106 | 107 | OP_DUP 108 | <8388608> 109 | OP_GREATERTHANOREQUAL 110 | OP_IF 111 | <8388608> 112 | OP_SUB 113 | OP_SWAP 114 | OP_HASH256 115 | OP_ELSE 116 | OP_SWAP 117 | OP_ENDIF 118 | OP_HASH160 119 | OP_SWAP 120 | 121 | OP_DUP 122 | <4194304> 123 | OP_GREATERTHANOREQUAL 124 | OP_IF 125 | <4194304> 126 | OP_SUB 127 | OP_SWAP 128 | OP_HASH256 129 | OP_ELSE 130 | OP_SWAP 131 | OP_ENDIF 132 | OP_HASH160 133 | OP_SWAP 134 | 135 | OP_DUP 136 | <2097152> 137 | OP_GREATERTHANOREQUAL 138 | OP_IF 139 | <2097152> 140 | OP_SUB 141 | OP_SWAP 142 | OP_HASH256 143 | OP_ELSE 144 | OP_SWAP 145 | OP_ENDIF 146 | OP_HASH160 147 | OP_SWAP 148 | 149 | OP_DUP 150 | <1048576> 151 | OP_GREATERTHANOREQUAL 152 | OP_IF 153 | <1048576> 154 | OP_SUB 155 | OP_SWAP 156 | OP_HASH256 157 | OP_ELSE 158 | OP_SWAP 159 | OP_ENDIF 160 | OP_HASH160 161 | OP_SWAP 162 | 163 | OP_DUP 164 | <524288> 165 | OP_GREATERTHANOREQUAL 166 | OP_IF 167 | <524288> 168 | OP_SUB 169 | OP_SWAP 170 | OP_HASH256 171 | OP_ELSE 172 | OP_SWAP 173 | OP_ENDIF 174 | OP_HASH160 175 | OP_SWAP 176 | 177 | OP_DUP 178 | <262144> 179 | OP_GREATERTHANOREQUAL 180 | OP_IF 181 | <262144> 182 | OP_SUB 183 | OP_SWAP 184 | OP_HASH256 185 | OP_ELSE 186 | OP_SWAP 187 | OP_ENDIF 188 | OP_HASH160 189 | OP_SWAP 190 | 191 | OP_DUP 192 | <131072> 193 | OP_GREATERTHANOREQUAL 194 | OP_IF 195 | <131072> 196 | OP_SUB 197 | OP_SWAP 198 | OP_HASH256 199 | OP_ELSE 200 | OP_SWAP 201 | OP_ENDIF 202 | OP_HASH160 203 | OP_SWAP 204 | 205 | OP_DUP 206 | <65536> 207 | OP_GREATERTHANOREQUAL 208 | OP_IF 209 | <65536> 210 | OP_SUB 211 | OP_SWAP 212 | OP_HASH256 213 | OP_ELSE 214 | OP_SWAP 215 | OP_ENDIF 216 | OP_HASH160 217 | OP_SWAP 218 | 219 | OP_DUP 220 | <32768> 221 | OP_GREATERTHANOREQUAL 222 | OP_IF 223 | <32768> 224 | OP_SUB 225 | OP_SWAP 226 | OP_HASH256 227 | OP_ELSE 228 | OP_SWAP 229 | OP_ENDIF 230 | OP_HASH160 231 | OP_SWAP 232 | 233 | OP_DUP 234 | <16384> 235 | OP_GREATERTHANOREQUAL 236 | OP_IF 237 | <16384> 238 | OP_SUB 239 | OP_SWAP 240 | OP_HASH256 241 | OP_ELSE 242 | OP_SWAP 243 | OP_ENDIF 244 | OP_HASH160 245 | OP_SWAP 246 | 247 | OP_DUP 248 | <8192> 249 | OP_GREATERTHANOREQUAL 250 | OP_IF 251 | <8192> 252 | OP_SUB 253 | OP_SWAP 254 | OP_HASH256 255 | OP_ELSE 256 | OP_SWAP 257 | OP_ENDIF 258 | OP_HASH160 259 | OP_SWAP 260 | 261 | OP_DUP 262 | <4096> 263 | OP_GREATERTHANOREQUAL 264 | OP_IF 265 | <4096> 266 | OP_SUB 267 | OP_SWAP 268 | OP_HASH256 269 | OP_ELSE 270 | OP_SWAP 271 | OP_ENDIF 272 | OP_HASH160 273 | OP_SWAP 274 | 275 | OP_DUP 276 | <2048> 277 | OP_GREATERTHANOREQUAL 278 | OP_IF 279 | <2048> 280 | OP_SUB 281 | OP_SWAP 282 | OP_HASH256 283 | OP_ELSE 284 | OP_SWAP 285 | OP_ENDIF 286 | OP_HASH160 287 | OP_SWAP 288 | 289 | OP_DUP 290 | <1024> 291 | OP_GREATERTHANOREQUAL 292 | OP_IF 293 | <1024> 294 | OP_SUB 295 | OP_SWAP 296 | OP_HASH256 297 | OP_ELSE 298 | OP_SWAP 299 | OP_ENDIF 300 | OP_HASH160 301 | OP_SWAP 302 | 303 | OP_DUP 304 | <512> 305 | OP_GREATERTHANOREQUAL 306 | OP_IF 307 | <512> 308 | OP_SUB 309 | OP_SWAP 310 | OP_HASH256 311 | OP_ELSE 312 | OP_SWAP 313 | OP_ENDIF 314 | OP_HASH160 315 | OP_SWAP 316 | 317 | OP_DUP 318 | <256> 319 | OP_GREATERTHANOREQUAL 320 | OP_IF 321 | <256> 322 | OP_SUB 323 | OP_SWAP 324 | OP_HASH256 325 | OP_ELSE 326 | OP_SWAP 327 | OP_ENDIF 328 | OP_HASH160 329 | OP_SWAP 330 | 331 | OP_DUP 332 | <128> 333 | OP_GREATERTHANOREQUAL 334 | OP_IF 335 | <128> 336 | OP_SUB 337 | OP_SWAP 338 | OP_HASH256 339 | OP_ELSE 340 | OP_SWAP 341 | OP_ENDIF 342 | OP_HASH160 343 | OP_SWAP 344 | 345 | OP_DUP 346 | <64> 347 | OP_GREATERTHANOREQUAL 348 | OP_IF 349 | <64> 350 | OP_SUB 351 | OP_SWAP 352 | OP_HASH256 353 | OP_ELSE 354 | OP_SWAP 355 | OP_ENDIF 356 | OP_HASH160 357 | OP_SWAP 358 | 359 | OP_DUP 360 | <32> 361 | OP_GREATERTHANOREQUAL 362 | OP_IF 363 | <32> 364 | OP_SUB 365 | OP_SWAP 366 | OP_HASH256 367 | OP_ELSE 368 | OP_SWAP 369 | OP_ENDIF 370 | OP_HASH160 371 | OP_SWAP 372 | 373 | OP_DUP 374 | <16> 375 | OP_GREATERTHANOREQUAL 376 | OP_IF 377 | <16> 378 | OP_SUB 379 | OP_SWAP 380 | OP_HASH256 381 | OP_ELSE 382 | OP_SWAP 383 | OP_ENDIF 384 | OP_HASH160 385 | OP_SWAP 386 | 387 | OP_DUP 388 | <8> 389 | OP_GREATERTHANOREQUAL 390 | OP_IF 391 | <8> 392 | OP_SUB 393 | OP_SWAP 394 | OP_HASH256 395 | OP_ELSE 396 | OP_SWAP 397 | OP_ENDIF 398 | OP_HASH160 399 | OP_SWAP 400 | 401 | OP_DUP 402 | <4> 403 | OP_GREATERTHANOREQUAL 404 | OP_IF 405 | <4> 406 | OP_SUB 407 | OP_SWAP 408 | OP_HASH256 409 | OP_ELSE 410 | OP_SWAP 411 | OP_ENDIF 412 | OP_HASH160 413 | OP_SWAP 414 | 415 | OP_DUP 416 | <2> 417 | OP_GREATERTHANOREQUAL 418 | OP_IF 419 | <2> 420 | OP_SUB 421 | OP_SWAP 422 | OP_HASH256 423 | OP_ELSE 424 | OP_SWAP 425 | OP_ENDIF 426 | OP_HASH160 427 | OP_SWAP 428 | 429 | OP_DUP 430 | <1> 431 | OP_GREATERTHANOREQUAL 432 | OP_IF 433 | <1> 434 | OP_SUB 435 | OP_SWAP 436 | OP_HASH256 437 | OP_ELSE 438 | OP_SWAP 439 | OP_ENDIF 440 | OP_HASH160 441 | OP_SWAP 442 | OP_DROP 443 | 444 | <0x8a649c0178523b6dd9de2a15c086067434ee2128> 445 | OP_EQUALVERIFY 446 | 447 | OP_FROMALTSTACK 448 | ``` 449 | 450 | ## Unlocking Script 451 | 452 | ``` 453 | <'preimage'> 454 | <1234567890> 455 | ``` 456 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bitcoin Scripts 2 | What's possible in Bitcoin's transaction scripting language? A random compilation of exotic bitcoin scripts. 3 | 4 | Examples: 5 | - [Betcoins](betcoins.md) 6 | - [Rock Paper Scissors](rock-paper-scissors.md) 7 | - [Composite Opcodes](composite-opcodes.md) 8 | - [Integer Commitments](integer-commitments.md) 9 | - [Nondeterminism in Bitcoin Script](composite-opcodes.md#op_mod-and-op_div) 10 | 11 | and more. 12 | 13 | There's also a primitive [Script Editor](https://coins.github.io/bitcoin-scripts/script-editor). It simplifies editing of Bitcoin Scripts with repeating opcode patterns. 14 | 15 | Note: In many examples we're using the [Bitcoin Script Debugger](https://github.com/bitcoin-core/btcdeb). It's a great tool for debugging bitcoin scripts. 16 | 17 | 18 | 19 | [CoinThx](https://coins.github.io/thx/#1K9zQ8f4iTyhKyHWmiDKt21cYX2QSDckWB?label=Coins%20Project&message=Thank%20you%20for%20your%20contribution!) 20 | 21 | 22 | ## Disclaimer 23 | 24 | > **DO NOT USE IN PRODUCTION! THE SCRIPTS ARE NOT SECURE!** 25 | 26 | 27 | ## Interesting Links 28 | - [List of new opcodes in Liquid](https://github.com/ElementsProject/elements/blob/master/doc/tapscript_opcodes.md) 29 | -------------------------------------------------------------------------------- /atomic-swap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coins/bitcoin-scripts/016f919c82f9e47f7eba4029eddce714ef261fee/atomic-swap.png -------------------------------------------------------------------------------- /betcoins.md: -------------------------------------------------------------------------------- 1 | # Betcoins - A trustless Bitcoin betting protocol 2 | 3 | Betcoins is a protocol for trustless Bitcoin bets like e.g. a coin flip. It uses only opcodes currently supported in Bitcoin Script. It allows any bet sizes, any discrete probability distributions and any payout sizes. It can be generalized to an election of a random leader. 4 | 5 | ## Naive Betting 6 | 7 | ### Simple Number Commitment 8 | A number commitment enforces a spender to reveal some secret number `N`. For a coin flip `N` is simply 0 or 1. 9 | 10 | 1. Choose secret number `N` in `{0,1}` 11 | 2. Choose secret nonce `R` which is `N + 16` bytes of randomness ( so either 16 or 17 bytes of randomness ) 12 | 3. The public commitment is `C = SHA256( R )` 13 | 14 | The following scriptPubKey enforces the spender to reveal `R` and thus `N`: 15 | ``` 16 | OP_DUP 17 | OP_SHA256 18 | 19 | OP_EQUALVERIFY 20 | OP_SIZE 21 | OP_16 22 | OP_SUB 23 | OP_TOALTSTACK 24 | OP_DROP 25 | OP_FROMALTSTACK 26 | ``` 27 | 28 | It leaves `N` on the stack. This is a handy primitive because further processing of `N` is possible using arithmetic operations. 29 | 30 | 31 | Max size of `N` is the max scriptSig size which is 10000 bytes. https://bitcoin.stackexchange.com/questions/35878/is-there-a-maximum-size-of-a-scriptsig-scriptpubkey 32 | We discuss the exact boundaries in a later chapter. 33 | 34 | This preimage length primitive is also handy for mass-interaction with oracles. 35 | 36 | 37 | ### Naive Contract 38 | The obvious idea is that both Alice and Bob create a number commitment `Alice_N`, `Bob_N` and sum up their values to derive a common value `Sum_N = Alice_N + Bob_N`. 39 | ``` 40 | OP_DUP 41 | OP_SHA256 42 | 43 | OP_EQUALVERIFY 44 | OP_SIZE 45 | OP_TOALTSTACK 46 | OP_DROP 47 | 48 | OP_DUP 49 | OP_SHA256 50 | 51 | OP_EQUALVERIFY 52 | OP_SIZE 53 | OP_TOALTSTACK 54 | OP_DROP 55 | 56 | OP_FROMALTSTACK 57 | OP_FROMALTSTACK 58 | OP_ADD 59 | ``` 60 | Spendable with the following scriptSig: 61 | ``` 62 | 63 | 64 | ``` 65 | This script leaves `Sum_N` on the stack. 66 | 67 | ## Coin Flip 68 | We want to simulate a coin flip having as outcome either 0 or 1. Both Alice and Bob provide one bit of entropy. 69 | For Alice to express her choice she commits to either `Alice_N == 16` or `Alice_N != 16`. 70 | The script puts 16 on the stack and `OP_NUMEQUAL` with `Alice_N` to retrieve Alice's choice represented in one bit. 71 | 72 | ``` 73 | OP_DUP 74 | OP_SHA256 75 | 76 | OP_EQUALVERIFY 77 | OP_SIZE 78 | OP_16 79 | OP_NUMEQUAL 80 | OP_TOALTSTACK 81 | OP_DROP 82 | OP_FROMALTSTACK 83 | ``` 84 | 85 | Bob does the same and the result is combined with XOR. There is no opcode `OP_XOR`, so we use a workaround: 86 | 87 | ``` 88 | OP_DUP 89 | OP_SHA256 90 | 91 | OP_EQUALVERIFY 92 | OP_SIZE 93 | OP_TOALTSTACK 94 | OP_DROP 95 | 96 | OP_DUP 97 | OP_SHA256 98 | 99 | OP_EQUALVERIFY 100 | OP_SIZE 101 | OP_TOALTSTACK 102 | OP_DROP 103 | 104 | OP_FROMALTSTACK 105 | OP_16 106 | OP_NUMEQUAL 107 | 108 | OP_FROMALTSTACK 109 | OP_16 110 | OP_NUMEQUAL 111 | 112 | OP_ADD 113 | OP_1 114 | OP_EQUAL 115 | 116 | OP_IF 117 | 118 | OP_ELSE 119 | 120 | OP_ENDIF 121 | OP_CHECKSIGVERIFY 122 | ``` 123 | 124 | In the following we denote the above script with `OP_BET( C1, C2 )` which the winner can spend if he knows both R1 and R2. 125 | 126 | ## Withholding Attacks 127 | 128 | We need to prevent data withholding attacks. We enforce revealing pre-images with timelocks. 129 | We chain transactions such that an attacker has to reveal his pre-image or lose. 130 | 131 | ### Naive Solution with a Collateral 132 | A simple solution is using deposits. 133 | 134 | - Both Alice and Bob bet 1 BTC each. 135 | - They also each deposit 1 BTC each in a separate contract. 136 | 137 | Alice's collateral contract executes the following conditional: 138 | 139 | - Alice can have her deposit back if she reveals her pre-image in time 140 | - Bob can take her deposit after the lock timer runs out 141 | 142 | Bob creates the inverse contract with Alice to mutually enforce revelation of their pre-images. 143 | This is secure and simple but requires a 1:1 deposit. Can we achieve the same without a deposit ? 144 | 145 | ### Solution without Collateral 146 | We discuss a solution without collaterals. 147 | 148 | - Alice and Bob can play the coin flip contract ( cooperative case ) 149 | - After some lock time: 150 | - Alice can execute her penalty transaction by revealing her pre-image 151 | - Bob can execute his penalty transaction by revealing his pre-image 152 | 153 | Alice's penalty transaction implements: 154 | - Alice can take all the money after some lock time 155 | - Bob can finish the game by revealing his pre-image ( cooperative case ) 156 | 157 | Alice's penalty transaction is pre-signed by Bob and vice versa. This requires two more rounds of communication during setup. 158 | 159 | 160 | ### Solution with only one on-chain TX 161 | We want to construct a solution with only one on-chain TX. We can use replace-by-fee and `nSequence` to remove the false-penalty case from the chain. 162 | 163 | - Alice and Bob can play the coin flip contract ( cooperative case ) 164 | - After some lock time: 165 | - Alice can execute her penalty transaction by revealing her pre-image 166 | - Bob can execute his penalty transaction by revealing his pre-image 167 | 168 | Alice's penalty transaction implements: 169 | - Alice can take all the money 170 | - Bob can replace her transaction and finish the game by revealing his pre-image 171 | 172 | #### Limitations 173 | - If Alice is a miner she can execute her transaction without revealing her pre-image first to Bob 174 | 175 | ## Varying Payouts 176 | It is trivial to change the probability distribution and payouts. Instead of a 50:50 chance we can implement 75:25 simply by changing 177 | ``` 178 | OP_ADD 179 | OP_1 180 | OP_EQUAL 181 | ``` 182 | 183 | to 184 | 185 | ``` 186 | OP_ADD 187 | OP_2 188 | OP_EQUAL 189 | ``` 190 | 191 | It is also trivial to take the three outcomes of the algorithm 0,1,2 with respective probabilities 25 : 50 : 25, and map them to three different code branches to implement different games like flipping a coin twice. 192 | 193 | 194 | # Further Research 195 | 196 | ## Multi-Party Betting 197 | We want to construct bets between 3 or more people. 198 | 199 | ## Dice Roll 200 | We want to construct a regular dice with the outcomes 1 to 6. 201 | 202 | ## Betting in Payment Channels 203 | - HTLCs can work as number commitments 204 | - repetitive bets 205 | - chaining bets across inputs 206 | 207 | 208 | # References 209 | "Pre-Image Length Probabilistic Payments" 210 | - [Lightning Network as a Directed Graph: Single-Funded Channel Network Topology 211 | ](https://www.youtube.com/watch?v=-lgYYz3y_hY) 212 | -------------------------------------------------------------------------------- /bitwise_xor.md: -------------------------------------------------------------------------------- 1 | # Bitwise XOR 2 | 3 | 4 | ## Bitwise XOR of Byte-sized Words 5 | 6 | Bitwise XOR of byte-sized words. Once the 512 elements of the reusable lookup table are on the stack, a bitwise XOR of a byte costs only 26 instructions. 7 | 8 | 9 | ```sh 10 | btcdeb "[ 11 | 12 | # Lookup table for 9-bit inputs f(x) = x & 0b01010101 13 | 85 84 85 84 81 80 81 80 85 84 85 84 81 80 81 80 14 | 69 68 69 68 65 64 65 64 69 68 69 68 65 64 65 64 15 | 85 84 85 84 81 80 81 80 85 84 85 84 81 80 81 80 16 | 69 68 69 68 65 64 65 64 69 68 69 68 65 64 65 64 17 | 21 20 21 20 17 16 17 16 21 20 21 20 17 16 17 16 18 | 05 04 05 04 01 00 01 00 05 04 05 04 01 00 01 00 19 | 21 20 21 20 17 16 17 16 21 20 21 20 17 16 17 16 20 | 05 04 05 04 01 00 01 00 05 04 05 04 01 00 01 00 21 | 85 84 85 84 81 80 81 80 85 84 85 84 81 80 81 80 22 | 69 68 69 68 65 64 65 64 69 68 69 68 65 64 65 64 23 | 85 84 85 84 81 80 81 80 85 84 85 84 81 80 81 80 24 | 69 68 69 68 65 64 65 64 69 68 69 68 65 64 65 64 25 | 21 20 21 20 17 16 17 16 21 20 21 20 17 16 17 16 26 | 05 04 05 04 01 00 01 00 05 04 05 04 01 00 01 00 27 | 21 20 21 20 17 16 17 16 21 20 21 20 17 16 17 16 28 | 05 04 05 04 01 00 01 00 05 04 05 04 01 00 01 00 29 | 85 84 85 84 81 80 81 80 85 84 85 84 81 80 81 80 30 | 69 68 69 68 65 64 65 64 69 68 69 68 65 64 65 64 31 | 85 84 85 84 81 80 81 80 85 84 85 84 81 80 81 80 32 | 69 68 69 68 65 64 65 64 69 68 69 68 65 64 65 64 33 | 21 20 21 20 17 16 17 16 21 20 21 20 17 16 17 16 34 | 05 04 05 04 01 00 01 00 05 04 05 04 01 00 01 00 35 | 21 20 21 20 17 16 17 16 21 20 21 20 17 16 17 16 36 | 05 04 05 04 01 00 01 00 05 04 05 04 01 00 01 00 37 | 85 84 85 84 81 80 81 80 85 84 85 84 81 80 81 80 38 | 69 68 69 68 65 64 65 64 69 68 69 68 65 64 65 64 39 | 85 84 85 84 81 80 81 80 85 84 85 84 81 80 81 80 40 | 69 68 69 68 65 64 65 64 69 68 69 68 65 64 65 64 41 | 21 20 21 20 17 16 17 16 21 20 21 20 17 16 17 16 42 | 05 04 05 04 01 00 01 00 05 04 05 04 01 00 01 00 43 | 21 20 21 20 17 16 17 16 21 20 21 20 17 16 17 16 44 | 05 04 05 04 01 00 01 00 05 04 05 04 01 00 01 00 45 | 46 | 47 | 48 | 49 | 0xAA00 # Input A 50 | 51 | DUP 52 | 1ADD 53 | PICK 54 | DUP 55 | ROT 56 | SWAP 57 | SUB 58 | 59 | 0x55 # Input B 60 | 61 | DUP 62 | 3 ADD 63 | PICK 64 | DUP 65 | ROT 66 | SWAP 67 | SUB 68 | 69 | ROT 70 | 71 | ADD 72 | DUP 73 | 1ADD 74 | PICK 75 | SUB 76 | 77 | TOALTSTACK 78 | ADD 79 | PICK 80 | 81 | FROMALTSTACK 82 | ADD 83 | 84 | # ]" 85 | ``` 86 | 87 | ### Python Implementation 88 | 89 | Here's a simplified Python implementation, which demonstrates the idea behind the above implementation: 90 | 91 | ```python 92 | # Inputs 93 | A = 0b00101010 94 | B = 0b10100100 95 | 96 | # Algorithm 97 | A_even = A & 0b01010101 98 | A_odd = A & 0b10101010 99 | B_even = B & 0b01010101 100 | B_odd = B & 0b10101010 101 | A_andxor_B_even = A_even + B_even 102 | A_andxor_B_odd = A_odd + B_odd 103 | A_xor_B_even = A_andxor_B_even & 0b01010101 104 | A_xor_B_odd = A_andxor_B_odd & 0b10101010 105 | A_xor_B = A_xor_B_odd + A_xor_B_even 106 | print(bin(A_xor_B)) 107 | ``` 108 | 109 | 110 | ### Bitwise XOR with 2 Lookup Tables 111 | We can use two lookup tables, each with 256 elements, one for `f(x) = (x & 0b10101010) >> 1` and one for `g(x) = x & 0b01010101`, to reduce the number of instructions per call down to 24. 112 | 113 | ``` 114 | btcdeb "[ 115 | 116 | # Lookup table for 8-bit inputs f(x) = (x & 0b10101010) >> 1 117 | 85 84 85 84 81 80 81 80 85 84 85 84 81 80 81 80 118 | 69 68 69 68 65 64 65 64 69 68 69 68 65 64 65 64 119 | 85 84 85 84 81 80 81 80 85 84 85 84 81 80 81 80 120 | 69 68 69 68 65 64 65 64 69 68 69 68 65 64 65 64 121 | 21 20 21 20 17 16 17 16 21 20 21 20 17 16 17 16 122 | 05 04 05 04 01 00 01 00 05 04 05 04 01 00 01 00 123 | 21 20 21 20 17 16 17 16 21 20 21 20 17 16 17 16 124 | 05 04 05 04 01 00 01 00 05 04 05 04 01 00 01 00 125 | 85 84 85 84 81 80 81 80 85 84 85 84 81 80 81 80 126 | 69 68 69 68 65 64 65 64 69 68 69 68 65 64 65 64 127 | 85 84 85 84 81 80 81 80 85 84 85 84 81 80 81 80 128 | 69 68 69 68 65 64 65 64 69 68 69 68 65 64 65 64 129 | 21 20 21 20 17 16 17 16 21 20 21 20 17 16 17 16 130 | 05 04 05 04 01 00 01 00 05 04 05 04 01 00 01 00 131 | 21 20 21 20 17 16 17 16 21 20 21 20 17 16 17 16 132 | 05 04 05 04 01 00 01 00 05 04 05 04 01 00 01 00 133 | 134 | 135 | # Lookup table for 8-bit inputs g(x) = x & 0b01010101 136 | 85 85 84 84 85 85 84 84 81 81 80 80 81 81 80 80 137 | 85 85 84 84 85 85 84 84 81 81 80 80 81 81 80 80 138 | 69 69 68 68 69 69 68 68 65 65 64 64 65 65 64 64 139 | 69 69 68 68 69 69 68 68 65 65 64 64 65 65 64 64 140 | 85 85 84 84 85 85 84 84 81 81 80 80 81 81 80 80 141 | 85 85 84 84 85 85 84 84 81 81 80 80 81 81 80 80 142 | 69 69 68 68 69 69 68 68 65 65 64 64 65 65 64 64 143 | 69 69 68 68 69 69 68 68 65 65 64 64 65 65 64 64 144 | 21 21 20 20 21 21 20 20 17 17 16 16 17 17 16 16 145 | 21 21 20 20 21 21 20 20 17 17 16 16 17 17 16 16 146 | 05 05 04 04 05 05 04 04 01 01 00 00 01 01 00 00 147 | 05 05 04 04 05 05 04 04 01 01 00 00 01 01 00 00 148 | 21 21 20 20 21 21 20 20 17 17 16 16 17 17 16 16 149 | 21 21 20 20 21 21 20 20 17 17 16 16 17 17 16 16 150 | 05 05 04 04 05 05 04 04 01 01 00 00 01 01 00 00 151 | 05 05 04 04 05 05 04 04 01 01 00 00 01 01 00 00 152 | 153 | 154 | 155 | 0xAA00 # Input A 156 | 0x55 # Input B 157 | 158 | 2DUP 159 | 160 | 259 ADD PICK 161 | SWAP 162 | 259 ADD PICK 163 | 164 | ADD 165 | 166 | 258 ADD PICK 167 | 168 | TOALTSTACK 169 | 170 | 1ADD PICK 171 | SWAP 172 | 1ADD PICK 173 | 174 | ADD 175 | 176 | PICK 177 | 178 | DUP ADD 179 | 180 | FROMALTSTACK 181 | ADD 182 | 183 | # ]" 184 | ``` 185 | -------------------------------------------------------------------------------- /composite-opcodes.md: -------------------------------------------------------------------------------- 1 | # Composite Opcodes 2 | 3 | We can define custom opcodes by chaining existing opcodes. 4 | 5 | > DISCLAIMER: DO NOT USE IN PRODUCTION! THE CODE IS INSECURE! 6 | 7 | 8 | 9 | ## OP_MUL 10 | 11 | You can find a [full implementation of `OP_MUL` here](op_mul.md). 12 | 13 | ### OP_2MUL 14 | Multiplies the top stack item by 2. 15 | ``` 16 | OP_DUP OP_ADD 17 | ``` 18 | 19 | ### OP_4MUL 20 | Multiplies the top stack item by 4. 21 | ``` 22 | OP_2MUL OP_2MUL 23 | = OP_DUP OP_ADD OP_DUP OP_ADD 24 | ``` 25 | 26 | ### OP_8MUL 27 | Multiplies the top stack item by 8. 28 | ``` 29 | OP_4MUL OP_2MUL 30 | = OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 31 | ``` 32 | 33 | ... 34 | 35 | ### OP_5MUL 36 | Multiplies the top stack item by 5. It uses that `x * 5 = x * 4 + x` 37 | ``` 38 | OP_DUP 39 | OP_4MUL 40 | OP_ADD 41 | ``` 42 | 43 | ### OP_13MUL 44 | Multiplies the top stack item by 13. 45 | ``` 46 | OP_DUP 47 | OP_TOALTSTACK 48 | 49 | OP_8MUL 50 | 51 | OP_FROMALTSTACK 52 | OP_DUP 53 | OP_TOALTSTACK 54 | 55 | OP_4MUL 56 | 57 | OP_FROMALTSTACK 58 | OP_DUP 59 | OP_TOALTSTACK 60 | 61 | OP_ADD 62 | OP_ADD 63 | OP_ADD 64 | ``` 65 | 66 | ## OP_MOD and OP_DIV 67 | 68 | ### OP_2DIV 69 | Integer division by 2 implemented with a _"hint"_. That means the result of the operation is given to us in the unlocking script and we just _verify_ the correctness of the result. This is more efficient than computing the result ourselves. 70 | 71 | ``` 72 | # Integer division by 2 with the help of a hint 73 | # In this example, we divide 119 by 2. 74 | # In the unlocking script the prover provides the result 75 | # as a hint 119//2 = 59, which we verify. 76 | 77 | btcdeb "[ 78 | 79 | 119 # Some arbitrary input is on the stack 80 | OP_OVER # Copy the hint to the top of the stack 81 | 82 | OP_DUP OP_ADD # Multiply the hint by 2 83 | OP_SUB # Subtract that from the 119 84 | 85 | 86 | # Now the remainder should be on the stack 87 | # We verify that it is exactly 0 or 1 88 | 89 | OP_DUP # Make a copy 90 | OP_0NOTEQUAL # Returns 0 if the input is 0. 1 otherwise. 91 | OP_EQUALVERIFY 92 | 93 | ]" 59 # The hint provided is 59 = 119/2 94 | ``` 95 | 96 | We can use our OP_MUL implementations to generalise this for other divisors than 2. 97 | 98 | 99 | ### OP_2MOD 100 | Modulo 2 implemented with _"hints"_. The result of the operation is given to us in the unlocking script and we just _verify_ the correctness of the result. This is more efficient than computing the result ourselves. 101 | 102 | ```sh 103 | # Modulo 2 with the help of a hint 104 | # 105 | # In this example, we compute 119 mod 2. 106 | # In the unlocking script the prover provides the quotient 107 | # as a hint 119//2 = 59, which we verify. 108 | 109 | btcdeb "[ 110 | 111 | 119 # Some arbitrary input is on the stack 112 | OP_SWAP # Swap the hint to the top of the stack 113 | 114 | OP_DUP OP_ADD # Multiply the hint by 2 115 | OP_SUB # Subtract that from the 119 116 | 117 | 118 | # Now the remainder should be on the stack 119 | # We verify that it is exactly 0 or 1 120 | 121 | OP_DUP OP_DUP # Make two copies 122 | OP_0NOTEQUAL # Returns 0 if the input is 0. 1 otherwise. 123 | OP_EQUALVERIFY 124 | 125 | # We're done. The result is on the stack 126 | 127 | 128 | ]" 59 # The hint provided is 59 = 119/2 129 | ``` 130 | 131 | 132 | 133 | 134 | 135 | ### OP_8DIV 136 | 137 | This is an integer division by `8`. The number `123459` is divided by `8`. The result is `15432`. It is given to us as a hint from the unlocking script. We only verfiy its correctness because that's what matters and we can do that much more efficiently than calculating it ourselves. 138 | 139 | 140 | ```sh 141 | btcdeb "[ 142 | OP_DUP 143 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 144 | 123459 145 | OP_SWAP 146 | OP_SUB 147 | 0 148 | 8 149 | OP_WITHIN 150 | OP_VERIFY 151 | ]" 15432 152 | ``` 153 | 154 | Here we use `OP_8MUL = OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD`, which is easy to generalise for other divisors. 155 | 156 | ### OP_8DIV_REM 157 | 158 | We can easily modify the above implementation to return both the result of the integer devision _and_ the remainder. 159 | ```sh 160 | btcdeb "[ 161 | 162 | OP_DUP 163 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 164 | 123459 165 | OP_SWAP 166 | OP_SUB 167 | OP_DUP 168 | 0 169 | 8 170 | OP_WITHIN 171 | OP_VERIFY 172 | 173 | ]" 15432 174 | ``` 175 | 176 | 177 | ## Boolean Operators 178 | 179 | ### OP_BOOLXOR 180 | Computes the logical XOR of the top two stack items. 181 | 182 | ``` 183 | OP_2DUP 184 | 185 | OP_NOT 186 | OP_BOOLAND 187 | 188 | OP_TOALTSTACK 189 | 190 | OP_SWAP 191 | OP_NOT 192 | OP_BOOLAND 193 | 194 | OP_FROMALTSTACK 195 | 196 | OP_BOOLOR 197 | ``` 198 | 199 | ### OP_BOOLXOR Alternative (Credits: Brill Saton) 200 | ``` 201 | OP_NUMNOTEQUAL 202 | ``` 203 | 204 | Note: It might actually produce a valid result if the user supplies inputs other than 0 or 1, as long as their inputs are still numbers. So sanitizing inputs here is extra important, otherwise users might lose money by putting bad inputs into the transaction, which still executes, and results in a successful transaction where it really should have failed. 205 | 206 | ### OP_BOOLXNOR 207 | ``` 208 | OP_NUMEQUAL 209 | ``` 210 | 211 | ### Non-Malleable Boolean value 212 | The following scripts ensures an input is either exactly `1` or `0`, represented unambiguously as `01` or `0x` respectively. Any other variations of `1` or `0` results in an error. 213 | 214 | ``` 215 | OP_DUP 216 | OP_SIZE 217 | OP_EQUALVERIFY 218 | ``` 219 | 220 | This prevents malleability of script inputs. 221 | 222 | 223 | ## Bitwise Operators 224 | 225 | ### OP_LSHIFT 226 | Shift all bits of a number one bit to the left. 227 | 228 | ``` 229 | 230 | OP_ABS 231 | OP_DUP 232 | ffffff3f 233 | OP_GREATERTHAN 234 | OP_IF 235 | 00000040 236 | OP_SUB 237 | OP_DUP 238 | OP_ADD 239 | OP_NEGATE 240 | OP_ELSE 241 | OP_DUP 242 | OP_ADD 243 | OP_ENDIF 244 | ``` 245 | 246 | ### Bitwise Complement 247 | 248 | The following flips all bits of a 32-bit word. 249 | 250 | ``` 251 | btcdeb "[ 252 | 253 | OP_DUP 254 | OP_ABS 255 | OP_TUCK 256 | OP_NUMNOTEQUAL 257 | 258 | OP_SWAP 259 | 260 | 0xffffff7f 261 | OP_SWAP 262 | OP_SUB 263 | 264 | OP_SWAP 265 | OP_NOTIF 266 | OP_NEGATE 267 | OP_ENDIF 268 | 269 | ]" 0xAAAAAAAA 270 | ``` 271 | 272 | ### Left rotate by 3 Bits 273 | 274 | Here is an example of using `op_div_rem_8` to rotate all bits three bits to the left. For simplification the rotation is performed over 24 bit words such that we do not have to deal with the sign of the signed 32 bit words used by Bitcoin Script. 275 | 276 | Described in simplified pseudo code: 277 | ``` 278 | 279 | OP_8DIV_REM 280 | OP_MUL( 2^21 ) 281 | OP_ADD 282 | ``` 283 | 284 | 285 | The actual code is 286 | ``` 287 | btcdeb "[ 288 | 289 | OP_DUP 290 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 291 | 12345 292 | OP_SWAP 293 | OP_SUB 294 | OP_DUP 295 | 0 296 | 8 297 | OP_WITHIN 298 | OP_VERIFY 299 | 300 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 301 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 302 | 303 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 304 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 305 | 306 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 307 | OP_DUP OP_ADD 308 | 309 | 310 | OP_ADD 311 | ]" 1543 312 | ``` 313 | 314 | Here you can find a [full implementation of a bitwise rotation of a 32-bit word](op_rotate.md). 315 | 316 | ### Right rotate 317 | 318 | A right rotation by `k` bits can be performed with an integer division by `2^k`. To verify the according hint we require `k` many `OP_2MUL`. 319 | 320 | 321 | 322 | 323 | ### Verify the Binary Representation of a Number 324 | 325 | ``` 326 | btcdeb "[ 327 | 0 328 | OP_SWAP 329 | OP_IF 330 | 1 331 | OP_ADD 332 | OP_ENDIF 333 | 334 | OP_SWAP 335 | OP_IF 336 | 2 337 | OP_ADD 338 | OP_ENDIF 339 | 340 | OP_SWAP 341 | OP_IF 342 | 4 343 | OP_ADD 344 | OP_ENDIF 345 | 346 | OP_SWAP 347 | OP_IF 348 | 8 349 | OP_ADD 350 | OP_ENDIF 351 | 352 | OP_SWAP 353 | OP_IF 354 | 16 355 | OP_ADD 356 | OP_ENDIF 357 | 358 | OP_SWAP 359 | OP_IF 360 | 32 361 | OP_ADD 362 | OP_ENDIF 363 | 364 | OP_SWAP 365 | OP_IF 366 | 64 367 | OP_ADD 368 | OP_ENDIF 369 | 370 | OP_SWAP 371 | OP_IF 372 | 128 373 | OP_ADD 374 | OP_ENDIF 375 | 376 | 147 377 | OP_EQUAL 378 | 379 | ]" 1 0 0 1 0 0 1 1 380 | 381 | ``` 382 | 383 | ### Nullify the First 8 bits of a 32-bit Number 384 | 385 | (This also uses bash syntax for some syntactic sugar in Bitcoin Script) 386 | 387 | ```sh 388 | #!/bin/sh 389 | 390 | btcdeb "[ 391 | 392 | # Input: Some random 32-bit word on the stack 393 | -1173741827 394 | 395 | 396 | ABS 397 | 398 | DUP $((2 ** 30)) GREATERTHANOREQUAL 399 | IF $((2 ** 30)) SUB ENDIF 400 | 401 | DUP $((2 ** 29)) GREATERTHANOREQUAL 402 | IF $((2 ** 29)) SUB ENDIF 403 | 404 | DUP $((2 ** 28)) GREATERTHANOREQUAL 405 | IF $((2 ** 28)) SUB ENDIF 406 | 407 | DUP $((2 ** 27)) GREATERTHANOREQUAL 408 | IF $((2 ** 27)) SUB ENDIF 409 | 410 | DUP $((2 ** 26)) GREATERTHANOREQUAL 411 | IF $((2 ** 26)) SUB ENDIF 412 | 413 | DUP $((2 ** 25)) GREATERTHANOREQUAL 414 | IF $((2 ** 25)) SUB ENDIF 415 | 416 | DUP $((2 ** 24)) GREATERTHANOREQUAL 417 | IF $((2 ** 24)) SUB ENDIF 418 | 419 | # Now the first 8 bits of the input are zero 420 | 421 | #]" 422 | ``` 423 | 424 | 425 | ## Signatures 426 | 427 | 428 | ### OP_IFSIGSIZE 429 | 430 | Controlling the program flow via signature length. 431 | 432 | ``` 433 | OP_DUP 434 | OP_TOALTSTACK 435 | OP_CHECKSIGVERIFY 436 | OP_FROMALTSTACK 437 | OP_SIZE 438 | OP_TOALTSTACK 439 | OP_DROP 440 | 441 | OP_FROMALTSTACK 442 | OP_DUP 443 | OP_TOALTSTACK 444 | OP1 445 | OP_EQUAL 446 | OP_IF 447 | < CASE 1 > 448 | OP_ENDIF 449 | 450 | OP_FROMALTSTACK 451 | OP_DUP 452 | OP_TOALTSTACK 453 | OP2 454 | OP_EQUAL 455 | OP_IF 456 | < CASE 2 > 457 | OP_ENDIF 458 | 459 | ... 460 | ``` 461 | 462 | ### OP_SIGCOMMITMENT 463 | Checks a hash commitment to a signature. 464 | 465 | ``` 466 | OP_DUP 467 | OP_TOALTSTACK 468 | OP_SHA256 469 | 470 | OP_VERIFY 471 | ``` 472 | A signature can't sign itself. Thus, a signature commitment is possible only if the input is not signed. Currently the only way not to sign the input is by misusing `SIGHASH_SINGLE` to use hash `0000...0001` as [discussed here](https://bitcointalk.org/index.php?topic=260595.0). This is not very powerful. Signing the "hash" 0000...0001 is effectively giving away your private key because one could reuse that signature on any of your UTXOs. 473 | 474 | Yet, in future Bitcoin versions with `SIGHASH_NOINPUTS` this opcode enables covenants. We can link transactions with a 2-of-2 MultiSig: 475 | 476 | - The first signature pre-commits to the follow-up transaction with `OP_SIGCOMMITMENT` and `SIGHASH_NOINPUTS` 477 | - The second is a regular signature authorizing the transaction for execution 478 | 479 | 480 | 481 | ## Time and Block Height 482 | 483 | The following script proves a minimum block height. Here the unlocking script provides height `700123` and the script verifies that the block height is at least that high 484 | 485 | ``` 486 | btcdeb "[ 487 | 488 | OP_DUP 0065cd1d OP_LESSTHAN # The input is a block height iff it is less than 500'000'000 489 | OP_CHECKLOCKTIMEVERIFY 490 | 491 | ]" 700123 492 | ``` 493 | 494 | The same technique applies to get a minimum network time. Furthermore, it can be applied to `OP_CHECKSEQUENCEVERIFY` to get a minimum age of the output spent in the TX. In a script where it is advantagous to provide the highest possible block height, the value on the stack would be the current block height. 495 | 496 | ## Lookup Tables and Arrays 497 | 498 | Here you can find implementations of [lookup tables](https://github.com/coins/bitcoin-scripts/blob/master/op_lookup.md) and static maps. 499 | 500 | ## Sorting 501 | 502 | ### OP_2SORT 503 | 504 | Sort the top two stack items 505 | 506 | ``` 507 | 2DUP 508 | MAX 509 | TOALTSTACK 510 | MIN 511 | FROMALTSTACK 512 | ``` 513 | 514 | ## Stack Manipulation and Dynamic Arrays 515 | 516 | We can copy the item at the bottom of the stack 517 | 518 | ``` 519 | OP_DEPTH 520 | OP_1SUB 521 | OP_PICK 522 | ``` 523 | 524 | We can pop the item at the bottom of the stack 525 | ``` 526 | OP_DEPTH 527 | OP_1SUB 528 | OP_ROLL 529 | ``` 530 | 531 | 532 | ## Script Limits 533 | 534 | - [Maximum number of op_codes in script](https://bitcoin.stackexchange.com/questions/38230/maximum-number-of-op-codes-in-script) Limit is 201 non-push opcodes (OP_1 etc, as well as direct pushes are not counted). Non-executed opcodes are also counted and the number of public keys participating in *executed* CHECKMULTISIG and CHDCKMULTISIGVERIFY are also counted towards that limit. the bip-tapscript draft proposes to remove that limit. 535 | - [520-byte limitation on serialized script size](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki#520-byte-limitation-on-serialized-script-size) 536 | - max push is 520 bytes 537 | - In Taproot Script many of these [limitations have been removed](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#Resource_limits) 538 | - The stack and the altstack may contain at most 1000 item together in total. 539 | - There is positive zero `0x` and negative zero `0x80`. Both can have trailing zeros i.e `0x0080`. There are 1041 different encodings for False. 540 | - "The argument of `OP_IF` / `NOTIF` in P2WSH must be minimal" 541 | - See [here](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-August/013014.html), and [here](https://bips.xyz/141#new-script-semantics). 542 | - _"An_ `OP_0NOTEQUAL` _may be used before_ `OP_IF` _or_ `OP_NOTIF` _to imitate the original behaviour (which may also re-enable the malleability vector depending on the exact script)."_ 543 | - You cannot use `op_checkmultisig` in Taproot scripts 544 | 545 | 546 | ## See Also 547 | 548 | [Interesting data artifacts from the Bitcoin blockchain](https://github.com/kristovatlas/interesting-bitcoin-data) 549 | -------------------------------------------------------------------------------- /decaying-multi-signature.md: -------------------------------------------------------------------------------- 1 | # Decaying Multisignature 2 | 3 | A 3-of-5 bitcoin multisig that after 60 months decays into a 2-of-5 and after 66 months decays into a 1-of-5. 4 | 5 | It makes it easy for the user to secure only 5 keys while at the same time allowing the user to lose 4 keys and still recover funds. The downside is you need to move funds every 5 years. 6 | 7 | ## Basic Idea 8 | ``` 9 | IF 10 | 3 11 | ELSE 12 | IF 13 | CHECKLOCKTIMEVERIFY DROP 14 | 2 15 | ELSE 16 | CHECKLOCKTIMEVERIFY DROP 17 | 1 18 | ENDIF 19 | ENDIF 20 | 21 | 5 CHECKMULTISIG 22 | ``` 23 | 24 | ### A Small Optimization 25 | We can optimize the above code a bit to save two opcodes: 26 | ``` 27 | IF 28 | 3 29 | ELSE 30 | IF 31 | 2 32 | 33 | ELSE 34 | 1 35 | 36 | ENDIF 37 | CHECKLOCKTIMEVERIFY DROP 38 | ENDIF 39 | 40 | 5 CHECKMULTISIG 41 | ``` 42 | 43 | ### Non-Malleability 44 | Our script takes up to two booleans as inputs. These should be non-malleable. 45 | 46 | The following primitive ensures an input of expected type "boolean" is exactly either `0x1` or `0x`: 47 | 48 | ``` 49 | DUP SIZE EQUALVERIFY 50 | ``` 51 | 52 | Inserted into our script: 53 | ``` 54 | DUP SIZE EQUALVERIFY 55 | IF 56 | 3 57 | ELSE 58 | DUP SIZE EQUALVERIFY 59 | IF 60 | 2 61 | 62 | ELSE 63 | 1 64 | 65 | ENDIF 66 | CHECKLOCKTIMEVERIFY DROP 67 | ENDIF 68 | 69 | 5 CHECKMULTISIG 70 | ``` 71 | 72 | 73 | ### Multiple UTXOs 74 | All your UTXOs should decay at the same time so that your HD seeds can recover all funds. That's why we use the *absolute* timelock `CHECKLOCKTIMEVERIFY` instead of the *relative* timelock`CHECKSEQUENCEVERIFY`. 75 | 76 | ### Relative Timelocks 77 | If we don't want to move our funds every 5 years we can use a kick-off transaction and relative timelocks. E.g. the presigned kickoff transaction creates a 3-of-5 output that decays into a 2-of-5 one year after it hits the chain. This way we have to reset the MultiSig only in case the kickoff transaction was broadcasted maliciously. Major drawback here is that this requires to sign a kickoff transaction for every output we receive. However, this should be neglectable in the scenario of a longterm hodler who rarely receives new UTXOs which are valuable enough to justify the effort. 78 | 79 | 80 | ## Credits 81 | Our work is an optimisation. The original idea for a decaying multisig was found on Twitter in a thread by [@JWWeatherman_ and @giacomozucco](https://twitter.com/JWWeatherman_/status/1249101431161774080). 82 | 83 | See also Pieter Wuille's Miniscript example ["A 3-of-3 that turns into a 2-of-3 after 90 days"](http://bitcoin.sipa.be/miniscript/). 84 | 85 | 86 | 87 | # Alternative Decaying MultiSig 88 | A decaying MultiSig is also possible using a regular MultiSig. One party creates a TX with a `nLocktime` and signs it using `SIGHASH_NONE`. Such a partially signed transaction makes an UTXO decay into a MultiSig with a threshold decremented by 1. 89 | 90 | ### Drawbacks 91 | - It requires interaction. 92 | - It requires a new TX for every UTXO. 93 | - Each party has to sign such a TX. 94 | - Each party has to store all TXs securely. 95 | 96 | 97 | 98 | 99 | # Decaying MultiSig using nLockTime 100 | 101 | A decaying MultiSig that requires no bitcoin script other than regular MultiSigs. 102 | 103 | A 3-of-3 that decays into a 2-of-3 at block height `x`. 104 | 105 | 1. Alice, Bob, and Carol create a 3-of-3 regular MultiSig output. 106 | 107 | 2. Alice signs the output with `nLocktime = x` and `SIGHASH_NONE`. 108 | 3. She sends this partially signed TX to Bob and Carol. 109 | 4. Bob and Carol do the same and send their transactions to the other two. 110 | 5. They all make their transaction slightly unique, such that Alice cannot combine Bob and Carol's signatures to reduce it to a 1-of-3. 111 | - E.g. by each signing distinct bits of the `nSequence` field, or distinct fees 112 | 6. Now they are ready to receive the output trustlessly. 113 | 114 | 115 | ## Limitations 116 | - For each output this ceremony is required. 117 | - For it to become trustless, the exact spending output has to be known upfront. 118 | - For a Schnorr MuSig the receiving output has to be known, too. E.g., it could be send to an output controlled by the remaining signers. 119 | -------------------------------------------------------------------------------- /integer-commitments.md: -------------------------------------------------------------------------------- 1 | # Integer Commitments 2 | 3 | ## Bit Commitment 4 | 5 | 1. Choose secret number `N` from `{1,2}` 6 | 2. Choose secret nonce `R` which is 31 bytes of randomness 7 | 3. The public commitment `C` is `R` hashed `N` times. 8 | 9 | The following scriptPubKey enforces the spender to reveal `R` and thus `N`: 10 | ``` 11 | OP_SIZE 12 | 32 13 | OP_EQUAL 14 | OP_NOT 15 | OP_VERIFY 16 | 17 | OP_SHA256 18 | OP_DUP 19 | 20 | OP_DUP 21 | OP_TOALTSTACK 22 | OP_EQUAL 23 | OP_IF 24 | OP_DROP 25 | 26 | OP_ELSE 27 | OP_SHA256 28 | OP_FROMALTSTACK 29 | OP_EQUALVERIFY 30 | 31 | OP_ENDIF 32 | 33 | ``` 34 | 35 | ## 4 Bit Commitment 36 | 37 | A commitment to a bitstring using two hash functions. [Here is an example transaction](https://blockstream.info/tx/1ac287e1c6d2121d1efdd79e13055787226b95b3e3647c2b04c825693abbf5a5?expand). 38 | For example, a commitment to the value `1101` expressed with hashA and hashA: 39 | - Choose random `r` 40 | - Commitment `C = hashA( hashA( hashB ( hashA( r )))` 41 | 42 | In the following script we use 43 | - `hashA(x) = OP_HASH160( OP_SHA256(x) )` and 44 | - `hashB = OP_HASH160( x )` 45 | 46 | ``` 47 | OP_SWAP 48 | OP_IF 49 | OP_SHA256 50 | 51 | 1 52 | OP_TOALTSTACK 53 | OP_ENDIF 54 | OP_HASH160 55 | 56 | OP_SWAP 57 | OP_IF 58 | OP_SHA256 59 | 60 | OP_FROMALTSTACK 61 | 2 62 | OP_ADD 63 | OP_TOALTSTACK 64 | OP_ENDIF 65 | OP_HASH160 66 | 67 | OP_SWAP 68 | OP_IF 69 | OP_SHA256 70 | 71 | OP_FROMALTSTACK 72 | 4 73 | OP_ADD 74 | OP_TOALTSTACK 75 | OP_ENDIF 76 | OP_HASH160 77 | 78 | OP_SWAP 79 | OP_IF 80 | OP_SHA256 81 | 82 | OP_FROMALTSTACK 83 | 8 84 | OP_ADD 85 | OP_TOALTSTACK 86 | OP_ENDIF 87 | OP_HASH160 88 | 89 | 32d8c4e2fa54d5c831f2f10d2b30352e9e3c026d 90 | OP_EQUALVERIFY 91 | OP_FROMALTSTACK 92 | ``` 93 | 94 | This output is spendable with `1 1 0 1 aabbccddeeff`, leaving `0x0d` on the stack and `0x0d == 0b1101` which reveals our commitment. 95 | 96 | 97 | ## Limitations 98 | - Note: In this naive implementation the first bit is vulnerable. We can solve that by prepending `OP_SHA1` at the beginning of the script. 99 | - The commitment requires 9 opcodes per bit. That is a maximum of about 21 bits per script. 100 | - 9 opcodes = ( 4 control flow ) + ( 5 logic ) codes. Logic optimizations are application specific. 101 | 102 | ## 7 Bit Commitment 103 | ``` 104 | # Bit Commitment with pre-image hashed with one of two hash functions 105 | 106 | btcdeb "[ 107 | 108 | OP_SWAP 109 | OP_IF 110 | OP_SHA256 111 | 112 | 1 113 | OP_TOALTSTACK 114 | OP_ENDIF 115 | OP_HASH160 116 | 117 | OP_SWAP 118 | OP_IF 119 | OP_SHA256 120 | 121 | OP_FROMALTSTACK 122 | 2 123 | OP_ADD 124 | OP_TOALTSTACK 125 | OP_ENDIF 126 | OP_HASH160 127 | 128 | OP_SWAP 129 | OP_IF 130 | OP_SHA256 131 | 132 | OP_FROMALTSTACK 133 | 4 134 | OP_ADD 135 | OP_TOALTSTACK 136 | OP_ENDIF 137 | OP_HASH160 138 | 139 | OP_SWAP 140 | OP_IF 141 | OP_SHA256 142 | 143 | OP_FROMALTSTACK 144 | 8 145 | OP_ADD 146 | OP_TOALTSTACK 147 | OP_ENDIF 148 | OP_HASH160 149 | 150 | OP_SWAP 151 | OP_IF 152 | OP_SHA256 153 | 154 | OP_FROMALTSTACK 155 | 16 156 | OP_ADD 157 | OP_TOALTSTACK 158 | OP_ENDIF 159 | OP_HASH160 160 | 161 | OP_SWAP 162 | OP_IF 163 | OP_SHA256 164 | 165 | OP_FROMALTSTACK 166 | 32 167 | OP_ADD 168 | OP_TOALTSTACK 169 | OP_ENDIF 170 | OP_HASH160 171 | 172 | OP_SWAP 173 | OP_IF 174 | OP_SHA256 175 | 176 | OP_FROMALTSTACK 177 | 64 178 | OP_ADD 179 | OP_TOALTSTACK 180 | OP_ENDIF 181 | OP_HASH160 182 | 183 | 166be064396607f51495e6cb412c92899edae667 184 | OP_EQUALVERIFY 185 | OP_FROMALTSTACK 186 | 187 | # ]" 1 1 0 0 1 0 1 aabbccddeeff 188 | 189 | 190 | ``` 191 | 192 | 193 | This is a powerful primitive. In combination with other opcodes it allows the computation of arbitrary circuits. 194 | 195 | 196 | ## 2 Party Bit Commitments 197 | 198 | Alice chooses `r` randomly. She creates a bit commitment either: 199 | - Commitment to 0: `A = HASH160(r)` 200 | - Commitment to 1: `A = SHA(HASH160(r))` 201 | 202 | She sends `A` to Bob. 203 | Bob creates a bit commitment either: 204 | - Commitment to 0: `B = HASH160(A)` 205 | - Commitment to 1: `B = SHA(HASH160(A))` 206 | 207 | Bob signs a Transaction and commits `B` to the Blockchain. 208 | Alice learns Bob's commitment value as soon as she sees the signed transaction. 209 | 210 | If Alice reveals `r`, the blockchain learns both Alice's and Bob's value. 211 | 212 | This is a 2-party 2-bit vector commitment in a single hash. 213 | 214 | Using the method from above, we extend this to a 2-party N-bit vector. Alice and Bob can commit to arbitrary bit strings of total length N. 215 | 216 | 217 | -------------------------------------------------------------------------------- /is-prime.md: -------------------------------------------------------------------------------- 1 | # Primitive Primality Test 2 | 3 | Checks if the input is a prime in `[1..37]`. 4 | 5 | ``` 6 | 7 | btcdeb "[ 8 | 9 | OP_DUP 10 | 11 | OP_DUP 2 OP_NUMEQUAL OP_SUB 12 | 13 | OP_DUP 3 OP_NUMEQUAL OP_SUB 14 | 15 | OP_DUP 5 OP_NUMEQUAL OP_SUB 16 | 17 | OP_DUP 7 OP_NUMEQUAL OP_SUB 18 | 19 | OP_DUP 11 OP_NUMEQUAL OP_SUB 20 | 21 | OP_DUP 13 OP_NUMEQUAL OP_SUB 22 | 23 | OP_DUP 17 OP_NUMEQUAL OP_SUB 24 | 25 | OP_DUP 19 OP_NUMEQUAL OP_SUB 26 | 27 | OP_DUP 23 OP_NUMEQUAL OP_SUB 28 | 29 | OP_DUP 29 OP_NUMEQUAL OP_SUB 30 | 31 | OP_DUP 31 OP_NUMEQUAL OP_SUB 32 | 33 | OP_DUP 37 OP_NUMEQUAL OP_SUB 34 | 35 | OP_SUB 36 | 37 | ]" 13 38 | 39 | ``` 40 | -------------------------------------------------------------------------------- /maps.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Selecting an Element from a Map 4 | 5 | ## Selecting from an Map: Solution 1 6 | 7 | ``` 8 | btcdeb "[ 9 | 10 | 11 | 0x02 # On the stack is the index we want to access 12 | TOALTSTACK 13 | 14 | IF 15 | IF 16 | 0x0d 0x04 # Element at index 4 17 | ELSE 18 | 0x11 0x03 # Element at index 3 19 | ENDIF 20 | ELSE 21 | IF 22 | 0x13 0x02 # Element at index 2 23 | ELSE 24 | IF 25 | 0x17 0x01 # Element at index 1 26 | ELSE 27 | 0x1d 0x00 # Element at index 0 28 | ENDIF 29 | ENDIF 30 | ENDIF 31 | 32 | 33 | # Verify that the hint was correct 34 | FROMALTSTACK 35 | EQUALVERIFY 36 | 37 | 38 | # We're done. The corresponding element is on the top stack 39 | 40 | #]" 0x01 0x # The hint provides the binary representation of the index 41 | ``` 42 | 43 | 44 | ## Selecting from an Map: Solution 2 45 | 46 | The following script selects an element from a map. The input can select an element from an array with five elements. In this example, the fourth element (the element at index `0x03`), is selected. So we will have 23 on the stack. 47 | 48 | ``` 49 | btcdeb "[ 50 | 51 | OP_DUP 52 | OP_0NOTEQUAL OP_NOTIF 53 | 13 0 54 | OP_ENDIF 55 | 56 | OP_1SUB 57 | OP_DUP 58 | OP_0NOTEQUAL OP_NOTIF 59 | 17 0 60 | OP_ENDIF 61 | 62 | OP_1SUB 63 | OP_DUP 64 | OP_0NOTEQUAL OP_NOTIF 65 | 19 0 66 | OP_ENDIF 67 | 68 | OP_1SUB 69 | OP_DUP 70 | OP_NOTIF 71 | 23 0 72 | OP_ENDIF 73 | 74 | OP_1SUB 75 | OP_NOTIF 76 | 29 77 | OP_ENDIF 78 | 79 | OP_NIP 80 | 81 | # ]" 0x03 82 | ``` 83 | 84 | This can be easily generalized for maps of tuples. 85 | -------------------------------------------------------------------------------- /merkle-path-cat.md: -------------------------------------------------------------------------------- 1 | # Merkle Path Verification with OP_CAT 2 | 3 | Verify a Merkle inclusion proof in a Merkle tree of depth 4. This implementation requires nothing but OP_CAT. Also no emulation of `OP_DIV` or `OP_MOD` because the index is given by the unlocking script, pre-parsed into a bit string. 4 | 5 | ``` 6 | // 7 | // Inputs 8 | // 9 | 10 | <'sibling-node-hash-3'> 11 | <0> // index[3] 12 | 13 | <'sibling-node-hash-2'> 14 | <0> // index[2] 15 | 16 | <'sibling-node-hash-1'> 17 | <1> // index[1] 18 | 19 | <'sibling-node-hash-0'> 20 | <'leaf-content'> 21 | <1> // index[0] 22 | 23 | 24 | 25 | // 26 | // Merkle Path Verification 27 | // 28 | 29 | OP_OVER 30 | OP_TOALTSTACK 31 | 32 | // Initialize our counter for the index 33 | <0> 34 | OP_TOALTSTACK 35 | 36 | // First Round 37 | OP_IF 38 | <8> 39 | OP_FROMALTSTACK 40 | OP_ADD 41 | OP_TOALTSTACK 42 | OP_SWAP 43 | OP_ENDIF 44 | OP_CAT 45 | OP_HASH160 46 | 47 | OP_SWAP 48 | 49 | // Second Round 50 | OP_IF 51 | <4> 52 | OP_FROMALTSTACK 53 | OP_ADD 54 | OP_TOALTSTACK 55 | OP_SWAP 56 | OP_ENDIF 57 | OP_CAT 58 | OP_HASH160 59 | 60 | OP_SWAP 61 | 62 | // Third Round 63 | OP_IF 64 | <2> 65 | OP_FROMALTSTACK 66 | OP_ADD 67 | OP_TOALTSTACK 68 | OP_SWAP 69 | OP_ENDIF 70 | OP_CAT 71 | OP_HASH160 72 | 73 | 74 | OP_SWAP 75 | 76 | // Fourth Round 77 | OP_IF 78 | <1> 79 | OP_FROMALTSTACK 80 | OP_ADD 81 | OP_TOALTSTACK 82 | OP_SWAP 83 | OP_ENDIF 84 | OP_CAT 85 | OP_HASH160 86 | 87 | 88 | // Ensure the result matches this Merkle root 89 | <0x414253bb057b9c8a209e82d7d4c7a4dcbccf7a95> 90 | OP_EQUALVERIFY 91 | 92 | 93 | OP_FROMALTSTACK 94 | // Now the index is on the stack 95 | 96 | OP_FROMALTSTACK 97 | // Now the leaf content is on the stack 98 | ``` 99 | -------------------------------------------------------------------------------- /merkle.md: -------------------------------------------------------------------------------- 1 | # Merkle Path Verification 2 | 3 | Requires `OP_CAT`, as in Liquid Script. Tested in [Script Wizard](https://ide.scriptwiz.app/) 4 | 5 | ``` 6 | // Computes the Merkle root given by a path 7 | // It assumes there's nothing but the path on the stack. 8 | 9 | // Inclusion proof 10 | <0xb5bf194a812960ba15b6cd0a0d6d9ce1b2b1ea1883abc551fa84ea4a22f2e66c> 11 | <0xe5007cd9c825ae150dacb80e9e3d210e6e0e85f264f92abed0952404ab1d5808> 12 | <0x0257fc3902505dd27a76956b1ceae3878c51824d1df5025533c5efd274caffc2> 13 | <0xf65cb638eaba0fd71eb0c3d1c657094cf917f3f7eb4a26f38a7ac34e200e6068> 14 | <0xe11f21292c2a7f219e4d89fdf2643de7bfc74a6389bf0d602148f3faaa23182d> 15 | <0x8bf845de9cde12824b810e454309c34c112c0ea409e7318c3fc39a4316e8ebfd> 16 | // The leaf we want to prove inclusion for 17 | <'test_data_chunk_47'> 18 | // The index of the leaf 19 | <47> 20 | 21 | 22 | OP_TOALTSTACK 23 | 24 | OP_SHA256 25 | 26 | // Loop begin 27 | OP_DEPTH 28 | OP_1SUB 29 | OP_IF 30 | 31 | OP_FROMALTSTACK 32 | OP_DUP 33 | <2> 34 | OP_DIV 35 | OP_TOALTSTACK 36 | <2> 37 | OP_MOD 38 | 39 | OP_NOTIF 40 | OP_SWAP 41 | OP_ENDIF 42 | 43 | OP_CAT 44 | OP_SHA256 45 | 46 | OP_ENDIF 47 | 48 | 49 | // Loop begin 50 | OP_DEPTH 51 | OP_1SUB 52 | OP_IF 53 | 54 | OP_FROMALTSTACK 55 | OP_DUP 56 | <2> 57 | OP_DIV 58 | OP_TOALTSTACK 59 | <2> 60 | OP_MOD 61 | 62 | OP_NOTIF 63 | OP_SWAP 64 | OP_ENDIF 65 | 66 | OP_CAT 67 | OP_SHA256 68 | 69 | OP_ENDIF 70 | 71 | 72 | // Loop begin 73 | OP_DEPTH 74 | OP_1SUB 75 | OP_IF 76 | 77 | OP_FROMALTSTACK 78 | OP_DUP 79 | <2> 80 | OP_DIV 81 | OP_TOALTSTACK 82 | <2> 83 | OP_MOD 84 | 85 | OP_NOTIF 86 | OP_SWAP 87 | OP_ENDIF 88 | 89 | OP_CAT 90 | OP_SHA256 91 | 92 | OP_ENDIF 93 | 94 | 95 | // Loop begin 96 | OP_DEPTH 97 | OP_1SUB 98 | OP_IF 99 | 100 | OP_FROMALTSTACK 101 | OP_DUP 102 | <2> 103 | OP_DIV 104 | OP_TOALTSTACK 105 | <2> 106 | OP_MOD 107 | 108 | OP_NOTIF 109 | OP_SWAP 110 | OP_ENDIF 111 | 112 | OP_CAT 113 | OP_SHA256 114 | 115 | OP_ENDIF 116 | 117 | 118 | // Loop begin 119 | OP_DEPTH 120 | OP_1SUB 121 | OP_IF 122 | 123 | OP_FROMALTSTACK 124 | OP_DUP 125 | <2> 126 | OP_DIV 127 | OP_TOALTSTACK 128 | <2> 129 | OP_MOD 130 | 131 | OP_NOTIF 132 | OP_SWAP 133 | OP_ENDIF 134 | 135 | OP_CAT 136 | OP_SHA256 137 | 138 | OP_ENDIF 139 | 140 | 141 | // Loop begin 142 | OP_DEPTH 143 | OP_1SUB 144 | OP_IF 145 | 146 | OP_FROMALTSTACK 147 | OP_DUP 148 | <2> 149 | OP_DIV 150 | OP_TOALTSTACK 151 | <2> 152 | OP_MOD 153 | 154 | OP_NOTIF 155 | OP_SWAP 156 | OP_ENDIF 157 | 158 | OP_CAT 159 | OP_SHA256 160 | 161 | OP_ENDIF 162 | 163 | 164 | 165 | 166 | ``` 167 | 168 | 169 | ## Ground-Truth in Python 170 | 171 | ```python 172 | import hashlib 173 | 174 | def hash_data(data): 175 | if isinstance(data, str): 176 | data = data.encode() 177 | return hashlib.sha256(data).digest() 178 | 179 | n = 6 180 | data_chunks = ["test_data_chunk_" + str(i) for i in range(2 ** n)] 181 | 182 | leaves = [hash_data(str(x)) for x in data_chunks] 183 | 184 | index_to_prove = 47 185 | 186 | def merkle_tree(leaves, index, path=None): 187 | if path is None: 188 | path = [] 189 | 190 | if len(leaves) == 1: 191 | return leaves[0], path 192 | 193 | if len(leaves) % 2 != 0: 194 | leaves.append(leaves[-1]) 195 | 196 | new_leaves = [] 197 | for i in range(0, len(leaves), 2): 198 | new_leaves.append(hash_data(leaves[i] + leaves[i+1])) 199 | if i <= index < i + 2: 200 | if index % 2 == 0: 201 | path.append(leaves[i+1].hex()) 202 | else: 203 | path.append(leaves[i].hex()) 204 | index = i // 2 205 | 206 | return merkle_tree(new_leaves, index, path) 207 | 208 | root, path = merkle_tree(leaves, index_to_prove) 209 | path.reverse() 210 | print("Root hash:", root.hex()) 211 | print("Inclusion proof for index", index_to_prove, ":\n") 212 | for p in path: 213 | print(f"<0x{p}>") 214 | print(f"<'{data_chunks[index_to_prove]}'>") # this is the index 215 | print(f"<0x{index_to_prove:02x}>") # this is the index 216 | ``` 217 | -------------------------------------------------------------------------------- /modular-arithmetic.md: -------------------------------------------------------------------------------- 1 | # Modular Arithmetic 2 | 3 | ## OP_2MUL_MOD64 4 | 5 | The following script demonstrates doubling modulo a power of two. In this example the power of 2 is 64 so we compute `x * 2 mod 64`: 6 | 7 | ``` 8 | btcdeb "[ 9 | 10 | # Some random number is on the stack 11 | 42 12 | 13 | # If x > 64/2 then subtract 64/2. This -64/2 will cancel out when doubling. 14 | DUP 32 GREATERTHANOREQUAL 15 | IF 32 SUB ENDIF 16 | 17 | # Perform the doubling 18 | DUP ADD 19 | 20 | ]" 21 | ``` 22 | 23 | This assumes the input to be less than 64. The overhead is 7 instructions. This works up to `mod 2**31` for any positive 31-bit number, without overflow. 24 | 25 | 26 | ## Right Shift by Multiplying the Inverse of 2 27 | The following performs a right shift of a 8-bit word. It uses the multiplicative group mod `n = 2**8 - 1` where `1/2 == 2**7` 28 | 29 | ```sh 30 | btcdeb "[ 31 | 32 | # Input X is on the stack, some random uint8 33 | 142 34 | 35 | # Compute X * 1/2 == X * (2**7) (mod 255) 36 | # With 7 doublings modulo 255 37 | 38 | DUP ADD 39 | DUP 255 GREATERTHANOREQUAL 40 | IF 255 SUB ENDIF 41 | 42 | DUP ADD 43 | DUP 255 GREATERTHANOREQUAL 44 | IF 255 SUB ENDIF 45 | 46 | DUP ADD 47 | DUP 255 GREATERTHANOREQUAL 48 | IF 255 SUB ENDIF 49 | 50 | DUP ADD 51 | DUP 255 GREATERTHANOREQUAL 52 | IF 255 SUB ENDIF 53 | 54 | DUP ADD 55 | DUP 255 GREATERTHANOREQUAL 56 | IF 255 SUB ENDIF 57 | 58 | DUP ADD 59 | DUP 255 GREATERTHANOREQUAL 60 | IF 255 SUB ENDIF 61 | 62 | DUP ADD 63 | DUP 255 GREATERTHANOREQUAL 64 | IF 255 SUB ENDIF 65 | 66 | 67 | # If X was odd we have to subtract 1/2 mod N 68 | DUP 128 GREATERTHANOREQUAL 69 | IF 128 SUB ENDIF 70 | 71 | ]" 72 | 73 | ``` 74 | 75 | The above can be easily generalized for n-bit words. A right shift then requires `9(n-1)+7` instructions. 76 | 77 | #### Right Shift by 3 bits 78 | 79 | A right shift by multiple bits is even cheaper. A right shift by `k` bits requires `9(n-k) + 7k` instructions. Here an example of a shift by 3 bits 80 | 81 | ``` 82 | btcdeb "[ 83 | 84 | # Input X is on the stack, some random uint8 85 | 142 86 | 87 | 88 | # Compute X * 1/8 == X * 2**5 (mod 255) 89 | 90 | DUP ADD 91 | DUP 255 GREATERTHANOREQUAL IF 255 SUB ENDIF 92 | 93 | DUP ADD 94 | DUP 255 GREATERTHANOREQUAL IF 255 SUB ENDIF 95 | 96 | DUP ADD 97 | DUP 255 GREATERTHANOREQUAL IF 255 SUB ENDIF 98 | 99 | DUP ADD 100 | DUP 255 GREATERTHANOREQUAL IF 255 SUB ENDIF 101 | 102 | DUP ADD 103 | DUP 255 GREATERTHANOREQUAL IF 255 SUB ENDIF 104 | 105 | 106 | # If the 1st bit was odd we have to subtract 1/2 mod N 107 | DUP 128 GREATERTHANOREQUAL IF 128 SUB ENDIF 108 | 109 | # If the 2nd bit was odd we have to subtract 1/4 mod N 110 | DUP 64 GREATERTHANOREQUAL IF 64 SUB ENDIF 111 | 112 | # If the 3rd bit was odd we have to subtract 1/8 mod N 113 | DUP 32 GREATERTHANOREQUAL IF 32 SUB ENDIF 114 | 115 | ]" 116 | ``` 117 | -------------------------------------------------------------------------------- /op_codeseparator.md: -------------------------------------------------------------------------------- 1 | Note, this text is mostly copy pasted from a chat history and is totally unstructured and might not make much sense in some places. The overall idea is correct though. 2 | 3 | 4 | # OP_CODESEPARATOR 5 | 6 | OP_CODESEPARATOR let's you sign off on a specific script execution path -- a powerful primitive that we can use for interesting constructions? 7 | 8 | 9 | ## Payment Channels Alternative 10 | 11 | 12 | ### Idea 13 | 14 | Can we use `OP_CODESEPARATOR` like this? 15 | 16 | ``` 17 | OP_IF 18 | OP_CODESEPARATOR 19 | 20 | OP_ELSE 21 | 22 | OP_ENDIF 23 | 24 | 2 25 | 26 | 27 | 2 28 | OP_CHECKMULTISIG 29 | 30 | ``` 31 | Here, `BRANCH_1` is spendable with: 32 | ``` 33 | 1 34 | ``` 35 | 36 | And `BRANCH_2` is spendable with: 37 | ``` 38 | 0 39 | ``` 40 | 41 | Such that Alice and Bob can only execute a branch if they have each other's signatures for that particular branch. 42 | 43 | - [Documentation seem to say yes](https://en.bitcoin.it/wiki/OP_CHECKSIG) 44 | - [Tests seem to say yes](https://github.com/bitcoin/bitcoin/blob/452bb90c718da18a79bfad50ff9b7d1c8f1b4aa3/src/test/data/tx_valid.json#L142) 45 | 46 | ### Usage 47 | 48 | If the idea works, then we can combine it with a time lock: 49 | 50 | ``` 51 | OP_IF 52 | OP_CODESEPARATOR 53 | 10 54 | OP_ELSE 55 | 100 56 | OP_ENDIF 57 | 58 | OP_CHECKSEQUENCEVERIFY 59 | OP_DROP 60 | 61 | 2 62 | 63 | 64 | 2 65 | OP_CHECKMULTISIG 66 | 67 | 68 | ``` 69 | 70 | And multiple states represented by time locks: 71 | 72 | ``` 73 | OP_IF 74 | OP_CODESEPARATOR 75 | 600300 76 | OP_ENDIF 77 | 78 | 79 | OP_IF 80 | OP_CODESEPARATOR 81 | 600200 82 | OP_ENDIF 83 | 84 | 85 | OP_IF 86 | OP_CODESEPARATOR 87 | 600100 88 | OP_ENDIF 89 | 90 | 91 | 92 | OP_CHECKLOCKTIMEVERIFY 93 | OP_DROP 94 | 95 | 2 96 | 97 | 98 | 2 99 | OP_CHECKMULTISIG 100 | ``` 101 | 102 | Spendable with one of the following: 103 | ``` 104 | 105 | 106 | 0 0 1 107 | ``` 108 | 109 | ``` 110 | 111 | 112 | 0 1 0 113 | ``` 114 | 115 | ``` 116 | 117 | 118 | 1 0 0 119 | ``` 120 | 121 | This could work recursively, such that we repeat the same contract in a next transaction authorized by the first branch of the previous transaction. 122 | After some arbitrary recursion depth we can settle the full branch and continue with the next branch of the base transaction. 123 | 124 | 125 | 126 | 127 | ### References 128 | - [[Lightning-dev] We don't need R-Value, how OP_CODESEPARATOR saves the day](https://lists.linuxfoundation.org/pipermail/lightning-dev/2016-March/000455.html) 129 | - [[bitcoin-dev] Making OP_CODESEPARATOR and FindAndDelete in non-segwit scripts non-standard](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-November/015292.html) 130 | - [OP_CODESEPARATOR used in tumblebit](https://github.com/bitcoin/bitcoin/pull/11423) 131 | - [[Policy] Several transaction standardness rules #11423](https://github.com/bitcoin/bitcoin/pull/11423) 132 | - [Eltoo](https://blockstream.com/eltoo.pdf) 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | # Off-chain Updates of Payment Channels 142 | 143 | In today's Bitcoin script `OP_CODESEPARATOR` might be a powerful "non-standard" opcode. It lets you sign off on specific execution paths. With this primitive and 2-of-2 MultiSigs we can build payment channels. The renegotation protocol might simplify existing off-chain protocols, and enable new use cases. 144 | 145 | ## Example: 146 | 147 | ``` 148 | OP_IF 149 | # Case 1 150 | OP_CODESEPARATOR 151 | 600300 152 | OP_ENDIF 153 | 154 | 155 | OP_IF 156 | # Case 2 157 | OP_CODESEPARATOR 158 | 600200 159 | OP_ENDIF 160 | 161 | 162 | OP_IF 163 | # Case 3 164 | OP_CODESEPARATOR 165 | 600100 166 | OP_ENDIF 167 | 168 | 169 | OP_CHECKLOCKTIMEVERIFY 170 | OP_DROP 171 | 172 | 2 173 | 174 | 175 | 2 176 | OP_CHECKMULTISIG 177 | ``` 178 | 179 | Spendable with one of the following witnesses: 180 | 181 | ``` 182 | 183 | 184 | 0 0 1 185 | ``` 186 | 187 | ``` 188 | 189 | 190 | 0 1 0 191 | ``` 192 | 193 | ``` 194 | 195 | 196 | 1 0 0 197 | ``` 198 | 199 | ## Features: 200 | - It is not required to stay online to watch the channel. An attacker cannot cheat until the time lock opens. 201 | - It is possible to chain multiple transactions and settle them all off-chain by opening the next time lock of the on-chain transaction output. 202 | - not required to store any state updates other than the most recent one 203 | - Given the size constraints of Bitcoin scripts, a single transaction can have more than 65 sub-branches. 204 | - Does it allow Eltoo-like channels without any fork? 205 | - Can we build channel factories to on-board new users off-chain? 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /op_lookup.md: -------------------------------------------------------------------------------- 1 | # Lookup Tables and Static Functions 2 | 3 | Using `OP_PICK` to implement lockup tables. `OP_PICK`: _The item n back in the stack is copied to the top._ 4 | 5 | 6 | 7 | This is particularily useful if we want to randomly access multiple elements in sequence, since we can reuse the lockup table without using any more opcodes. 8 | 9 | ## Powers of 2 10 | 11 | This is a lookup table for powers of two. 12 | 13 | ```sh 14 | 15 | btcdeb "[ 16 | 17 | 7 # An arbitrary index is on the stack 18 | TOALTSTACK 19 | 20 | 21 | # The elements of our lookup table are put onto the stack 22 | 524288 23 | 262144 24 | 131072 25 | 65536 26 | 27 | 32768 28 | 16384 29 | 8192 30 | 4096 31 | 32 | 2048 33 | 1024 34 | 512 35 | 256 36 | 37 | 128 38 | 64 39 | 32 40 | 16 41 | 42 | 8 43 | 4 44 | 2 45 | 1 46 | 47 | FROMALTSTACK 48 | 49 | # The magic function call happens here 50 | OP_PICK 51 | 52 | # Now the element at index=7 is on the stack. It is 2^7 = 128 53 | 54 | 55 | TOALTSTACK 56 | 57 | # At the end of the program we have to delete our lookup table 58 | OP_2DROP OP_2DROP 59 | OP_2DROP OP_2DROP 60 | OP_2DROP OP_2DROP 61 | OP_2DROP OP_2DROP 62 | OP_2DROP OP_2DROP 63 | 64 | FROMALTSTACK 65 | # ]" 66 | ``` 67 | 68 | As soon as the lookup table is on the stack, we can efficiently use it from anywhere in the script. Using `OP_DEPTH` we can even handle dynamic stack sizes to perform the required "pointer arithmetic" for the offset to be used with `OP_PICK`. In this example, the address of `pow2` is `24`. 69 | 70 | 71 | 72 | 73 | 74 | 75 | ## Multiple Lookup Tables and Function Calls 76 | 77 | Here is an example of two different lookup tables, which allow to mimic function calls. The position of the lookup table in the stack becomes the function name. 78 | 79 | ```sh 80 | btcdeb "[ 81 | 82 | 7 # An arbitrary index is on the stack 83 | 3 # Annother arbitrary index is on the stack 84 | 85 | # Put them on the altstack for later 86 | TOALTSTACK 87 | TOALTSTACK 88 | 89 | 90 | 91 | ######### Function Definitions ######### 92 | 93 | # The lookup table for pow2 94 | 524288 95 | 262144 96 | 131072 97 | 65536 98 | 99 | 32768 100 | 16384 101 | 8192 102 | 4096 103 | 104 | 2048 105 | 1024 106 | 512 107 | 256 108 | 109 | 128 110 | 64 111 | 32 112 | 16 113 | 114 | 8 115 | 4 116 | 2 117 | 1 118 | 119 | 120 | # The lookup table for get_prime 121 | 89 122 | 83 123 | 79 124 | 73 125 | 126 | 71 127 | 67 128 | 61 129 | 59 130 | 131 | 53 132 | 47 133 | 43 134 | 41 135 | 136 | 37 137 | 31 138 | 29 139 | 23 140 | 141 | 19 142 | 17 143 | 13 144 | 11 145 | 146 | 7 147 | 5 148 | 3 149 | 2 150 | 151 | 152 | ############# Examples of Function Calls ########## 153 | 154 | 155 | # Get the first argument onto the stack 156 | FROMALTSTACK 157 | 158 | # Our first 'function call' is pow2. 24 is its address and 'function name'. 159 | 24 ADD PICK 160 | 161 | # Now the result pow2(7) = 2**7 = 128 is on the stack 162 | 163 | 164 | # Get the second argument onto the stack 165 | FROMALTSTACK 166 | SWAP 167 | TOALTSTACK 168 | 169 | 170 | # Our second 'function call' is get_prime. Its address is 0. So no addition needed for this 'name' 171 | PICK 172 | 173 | # We use the result as an argument for another call of get_prime 174 | PICK 175 | 176 | 177 | # And with that result we call again pow2 178 | 24 ADD PICK 179 | 180 | 181 | # Now we have pow2( get_prime(get_prime( input_b )) ) on the stack 182 | TOALTSTACK 183 | 184 | 185 | 186 | 187 | 188 | ######## Boilerplate to Cleanup ######## 189 | 190 | # At the end of the program we have to drop our lookup table to clean up the stack 191 | 2DROP 2DROP 192 | 2DROP 2DROP 193 | 2DROP 2DROP 194 | 2DROP 2DROP 195 | 2DROP 2DROP 196 | 197 | 2DROP 2DROP 198 | 2DROP 2DROP 199 | 2DROP 2DROP 200 | 2DROP 2DROP 201 | 2DROP 2DROP 202 | 2DROP 2DROP 203 | 204 | 205 | # Push the results of our function calls back on the stack 206 | FROMALTSTACK 207 | FROMALTSTACK 208 | 209 | # ]" 210 | ``` 211 | 212 | ## Dynamic Function Names 213 | In our previous example we assumed to make all function calls at the same stack height, so we could use the same address `` for each call: 214 | ``` 215 | 216 | ADD PICK 217 | ``` 218 | 219 | The following script accounts for calls at dynamic stack heights: 220 | 221 | ``` 222 | 223 | OP_DEPTH SUB ADD PICK 224 | ``` 225 | 226 | A bit more convenient is to use the negative of `` such that it can become the first item of the function call: 227 | ``` 228 | 229 | < -fn_address > OP_DEPTH ADD ADD PICK 230 | ``` 231 | 232 | Note that `` is a number and this allows to even dynamically define the function to be called. 233 | 234 | 235 | 236 | 237 | ## Efficient Cleanup 238 | 239 | Here's a hack using `OP_CHECKMULTISIG` to drop many elements from the stack with a single opcode. The stack we want to delete is interpreted as a 0-of-20 multisig. 240 | 241 | ``` 242 | # Bitwise AND 243 | 244 | btcdeb "[ 245 | 246 | 247 | 0 # Some random stack item that is required because of a quirk in CHECKMULTISIG. Could be anything 248 | 0 # This is the number of signatures required in the 0-of-20 multisig 249 | 250 | 1 # The 20 stack items we want to delete. They are getting interpreted as keys. 251 | 2 252 | 3 253 | 4 254 | 255 | 5 256 | 6 257 | 7 258 | 8 259 | 260 | 9 261 | 10 262 | 11 263 | 12 264 | 265 | 13 266 | 14 267 | 15 268 | 16 269 | 270 | 17 271 | 18 272 | 19 273 | 20 274 | 275 | 276 | 20 277 | OP_CHECKMULTISIG 278 | 279 | 280 | # ]" 281 | ``` 282 | 283 | 284 | ## Multiple Lookup Tables and Limits 285 | Our script can have a few million instructions. But we can have at most 1000 items on the stack. That means we can have thousands of different lookup tables in a script. We only have to build them up, use them and then drop them to always retain the stack size under 1000. 286 | 287 | -------------------------------------------------------------------------------- /op_mul.md: -------------------------------------------------------------------------------- 1 | # OP_MUL 2 | The following is a bitcoin script implementing the opcode `OP_MUL` to multiply `a` by `b`. 3 | 4 | DISCLAIMER: THE CODE IS INSECURE! DO NOT USE IN PRODUCTION!! 5 | 6 | ## OP_2MUL Multiplication by the Constant 2 7 | Multiply by 2 8 | ``` 9 | OP_2MUL = OP_DUP OP_ADD 10 | ``` 11 | 12 | ## OP_MUL(2^k) Multiplication by a Constant Power of 2 13 | Multiply by powers of 2 reduces to the following equation: 14 | ``` 15 | OP_MUL(2^k) = OP_MUL(2^(k-1)) OP_2MUL 16 | ``` 17 | So, to multiply a number by `2^k` we need `k * 2` instructions. 18 | 19 | Examples: 20 | ``` 21 | OP_4MUL = OP_DUP OP_ADD OP_DUP OP_ADD 22 | OP_8MUL = OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 23 | OP_16MUL = OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 24 | ... 25 | ``` 26 | 27 | ## OP_3MUL Multiplication by the Constant 3 28 | 29 | Multiply the top stack item by three 30 | ``` 31 | OP_DUP OP_DUP OP_ADD OP_ADD 32 | ``` 33 | 34 | 35 | ## OP_MUL Multiplication with a 4-bit Variable 36 | Multiply `a` by `b`. The result of `a * b` must fit into a signed 32-bit integer. 37 | Additionally, the following script works only for `b<16` being a 4-bit integer. 38 | 39 | ``` 40 | btcdeb "[ 41 | 42 | 0 43 | OP_TOALTSTACK 44 | 45 | OP_DUP 46 | 8 47 | OP_GREATERTHANOREQUAL 48 | OP_IF 49 | 8 50 | OP_SUB 51 | OP_SWAP 52 | OP_DUP 53 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 54 | OP_FROMALTSTACK 55 | OP_ADD 56 | OP_TOALTSTACK 57 | OP_SWAP 58 | OP_ENDIF 59 | 60 | OP_DUP 61 | 4 62 | OP_GREATERTHANOREQUAL 63 | OP_IF 64 | 4 65 | OP_SUB 66 | OP_SWAP 67 | OP_DUP 68 | OP_DUP OP_ADD OP_DUP OP_ADD 69 | OP_FROMALTSTACK 70 | OP_ADD 71 | OP_TOALTSTACK 72 | OP_SWAP 73 | OP_ENDIF 74 | 75 | OP_DUP 76 | 2 77 | OP_GREATERTHANOREQUAL 78 | OP_IF 79 | 2 80 | OP_SUB 81 | OP_SWAP 82 | OP_DUP 83 | OP_DUP OP_ADD 84 | OP_FROMALTSTACK 85 | OP_ADD 86 | OP_TOALTSTACK 87 | OP_SWAP 88 | OP_ENDIF 89 | 90 | OP_NOT 91 | OP_IF 92 | OP_DROP 93 | 0 94 | OP_ENDIF 95 | 96 | OP_FROMALTSTACK 97 | OP_ADD 98 | 99 | "] 60 14 100 | ``` 101 | 102 | #### Circuit Sizes 103 | The number of required opcodes is linear in bit size of `b`: 104 | - `4 bits -> 52 opcodes` 105 | - `5 bits -> 71 opcodes` 106 | - `6 bits -> 92 opcodes` 107 | - `7 bits -> 115 opcodes` 108 | - `8 bits -> 140 opcodes` 109 | 110 | 111 | ## OP_127MUL Multiplication by a Constant close to a Power of 2 112 | 113 | In this example we multiply the top stack item by `127` which is close to `128 = 2**7`. We use that `x * 127 = x * 128 - x`: 114 | 115 | ``` 116 | btcdeb "[ 117 | 118 | # Input: Some random number on the stack 119 | 42 120 | 121 | # Duplicate it 122 | DUP 123 | 124 | # Multiply it by 128 125 | DUP ADD 126 | DUP ADD 127 | DUP ADD 128 | DUP ADD 129 | DUP ADD 130 | DUP ADD 131 | DUP ADD 132 | 133 | # Subtract the original input to get a multiplication by 127 134 | SWAP 135 | SUB 136 | # ]" 137 | 138 | ``` 139 | 140 | The above can be easily generalized to play all kinds of code golf to find shortest expressions for multiplications by a constant expressed as sums and differences of powers of two. Even mixing in powers of three might sometimes be the most efficient. 141 | 142 | ## OP_1143MUL Multiplication by a Constant by Multiplying its Factors 143 | 144 | The following is a multiplication by `1143`, which uses its factorization `1143 = 127 * 9` and to compute 145 | ``` 146 | `x * 1143 147 | = (x * 127) * 9 = (x * (128-1)) * (8 + 1)` 148 | = (x * 128 - x) * 8 + (x * 128 - x) 149 | ``` 150 | 151 | Here's the implementation 152 | ``` 153 | btcdeb "[ 154 | 155 | # Input: Some random number on the stack 156 | 42 157 | 158 | # 159 | # Multiply by 127 160 | # 161 | 162 | # Duplicate it 163 | DUP 164 | 165 | # Multiply it by 128 166 | DUP ADD 167 | DUP ADD 168 | DUP ADD 169 | DUP ADD 170 | DUP ADD 171 | DUP ADD 172 | DUP ADD 173 | 174 | # Subtract the original input to get a multiplication by 127 175 | SWAP 176 | SUB 177 | 178 | 179 | 180 | # 181 | # Multiply by 9 182 | # 183 | 184 | # Duplicate it 185 | DUP 186 | 187 | # Multiply it by 8 188 | DUP ADD 189 | DUP ADD 190 | DUP ADD 191 | 192 | # Add the original input to get a multiplication by 9 193 | ADD 194 | 195 | 196 | # 197 | # The result is a multiplication by 127 * 9 198 | # 199 | 200 | # ]" 201 | 202 | ``` 203 | 204 | 205 | ## 4-bit OP_MUL using a Lookup Table 206 | ``` 207 | [ 208 | loop(256, i => [ 209 | (i >>> 4) * (i % 16) 210 | ]).reverse(), 211 | 212 | loop(16, i => [ 213 | (i << 4) + 16 214 | ]).reverse(), 215 | 216 | // The factor a 217 | 0x3, 218 | // The factor b 219 | 0x7, 220 | OP_1ADD, 221 | OP_PICK, 222 | OP_ADD, 223 | OP_PICK 224 | // Now there's a*b on the stack 225 | ] 226 | ``` 227 | -------------------------------------------------------------------------------- /op_rotate.md: -------------------------------------------------------------------------------- 1 | # Bitwise Rotation of a 32-bit Integer 2 | 3 | A Bitcoin Script implementing a bitwise rotation of a 32-bit word by 3 bits to the right. If you are unfamiliar with [nondeterminism, check out this simple example first](https://github.com/coins/bitcoin-scripts/blob/master/composite-opcodes.md#op_2div). 4 | 5 | ``` 6 | btcdeb "[ 7 | 8 | # 9 | # We have to start with a bit of gymnastics here 10 | # to deal with the negative zero `0x80` and that it 11 | # cannot be the result of arithmetic opcodes. 12 | # To work around Bitcoin's quirky arithmetic 13 | # we simply return a constant in these cases 14 | # 15 | 16 | # Check if the input is the number that maps to negative zero when shifted 3 bits to the right 17 | OP_DUP 18 | 0x04 19 | OP_EQUAL 20 | OP_IF 21 | # This is the number that maps to negative zero 22 | # So we simply return the byte string of negative zero here 23 | OP_DROP 24 | OP_DROP 25 | OP_x01 [0x80] # We return here the negative zero 26 | 27 | OP_ELSE 28 | # This is not the number that maps to negative zero 29 | 30 | # Check if the number itself is the negative zero 31 | OP_DUP 32 | OP_x01 [0x80] # This pushes the negative zero onto the stack 33 | OP_EQUAL 34 | OP_IF 35 | 36 | # This number is the negative zero. This case is handled by a constant, too. 37 | # We return the negative zero rotated by 3 bits 38 | OP_DROP 39 | OP_DROP 40 | 00000010 # We return here the rotated negative zero 41 | 42 | OP_ELSE 43 | 44 | # Finally we know this is not an edge case but a regular number, 45 | # so we apply our algorithm: 46 | 47 | ################################################################## 48 | 49 | 50 | # Split the number into its sign and the 31-bit value 51 | OP_DUP 52 | OP_ABS 53 | OP_TUCK 54 | OP_NUMNOTEQUAL 55 | 56 | # The sign rotated becomes the bit at index 31-3 = 28 57 | OP_IF 58 | 268435456 # This is 2^28 59 | OP_ELSE 60 | 0 61 | OP_ENDIF 62 | OP_SWAP 63 | OP_ROT 64 | 65 | 66 | # 67 | # Simultaneous integer division and modulus 68 | # 69 | # Computes div_rem of the value divided by 8 == 2^3 70 | # It puts both the quotient and the remainder on the stack 71 | # 72 | 73 | # We compute the result with the help of a "hint" 74 | # provided by the unlocking script. 75 | # We expect that hint to be the quotient `value/8` 76 | # and the following verifies that this is acutally correct: 77 | 78 | # Copy the hint and multiply it by 8 79 | OP_DUP 80 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 81 | 82 | # Subtract the result from the original value and ensure 83 | # the remainder is a number in [0,1,2,...,7] 84 | OP_ROT 85 | OP_SWAP 86 | OP_SUB 87 | OP_DUP 88 | 0 89 | 8 90 | OP_WITHIN 91 | OP_VERIFY 92 | 93 | # Now remainder and quotient is on the stack 94 | 95 | 96 | # 97 | # Most of the following code is juggeling around bits 98 | # to deal with the sign of our result 99 | # 100 | 101 | 102 | # Cut off the highest bit of the remainder because this will be our new sign 103 | # The remainder has 3 bits. So the highest bit is set from 4 = 2**(3-1) upwards 104 | 105 | # Check if the highest bit of the remainder is set 106 | OP_DUP 107 | 4 108 | OP_GREATERTHANOREQUAL 109 | OP_IF 110 | # The bit is set. So cut it off 111 | 4 112 | OP_SUB 113 | 1 # The new sign 114 | OP_ELSE 115 | 0 # The new sign 116 | OP_ENDIF 117 | # Push the new sign in the altstack for later 118 | OP_TOALTSTACK 119 | 120 | 121 | # Shift the unsigned remainder 32-3 = 29 bits to the left 122 | 123 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 124 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 125 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 126 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 127 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 128 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 129 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 130 | OP_DUP OP_ADD 131 | 132 | # Now add up all three values 133 | OP_ADD 134 | OP_ADD 135 | 136 | 137 | # Adjust the new sign 138 | OP_FROMALTSTACK 139 | OP_IF 140 | OP_NEGATE 141 | OP_ENDIF 142 | 143 | # And we're done. The result is on the stack 144 | 145 | OP_ENDIF 146 | OP_ENDIF 147 | 148 | # ]" 0x11111101 0x88888888 149 | 150 | 151 | ``` 152 | 153 | Inputs: 154 | - ``, the value to shift. In our example `0x88888888`. The script produces the result `0x11111111` 155 | - ``, the absolute value of `X` divided by 8. In our example `0x11111101`. This hint allows us to apply the principle "Don't compute. Verify." You can find an explanation of _"hints"_ and _"nondeterministic programming"_ in the section "nondeterminism" in the [the Cairo language white paper](https://eprint.iacr.org/2021/1063.pdf). 156 | 157 | Inputs have to be minimally encoded. E.g.,`0x04000000 -> 0x04`. But the negative zero, `0x80`, is encoded as `0x00` 158 | 159 | The script here rotates three bits to the right. It can easily be modified to perform any other bitwise rotation. All rotations on 32-bit words require the same amount of instructions. In this script 118 instructions. 160 | 161 | 162 | 163 | 164 | ## Optimization 165 | 166 | The following implementation takes advantage of the special case of a rotation by 3 bits, which allows to optimize an expensive multiplication by hard coding 4 cases with constants. This reduces the step count to 78 instructions. 167 | 168 | ``` 169 | btcdeb "[ 170 | 171 | # 172 | # We have to start with a bit of gymnastics here 173 | # to deal with the negative zero `0x80` and that it 174 | # cannot be the result of arithmetic opcodes. 175 | # To work around Bitcoin's quirky arithmetic 176 | # we simply return a constant in these cases 177 | # 178 | 179 | # Check if the input is the number that maps to negative zero when shifted 3 bits to the right 180 | OP_DUP 181 | 0x04 182 | OP_EQUAL 183 | OP_IF 184 | # This is the number that maps to negative zero 185 | # So we simply return the byte string of negative zero here 186 | OP_DROP 187 | OP_DROP 188 | OP_x01 [0x80] # We return here the negative zero 189 | 190 | OP_ELSE 191 | # This is not the number that maps to negative zero 192 | 193 | # Check if the number itself is the negative zero 194 | OP_DUP 195 | OP_x01 [0x80] # This pushes the negative zero onto the stack 196 | OP_EQUAL 197 | OP_IF 198 | 199 | # This number is the negative zero. This case is handled by a constant, too. 200 | # We return the negative zero rotated by 3 bits 201 | OP_DROP 202 | OP_DROP 203 | 00000010 # We return here the rotated negative zero 204 | 205 | OP_ELSE 206 | 207 | # Finally we know this is not an edge case but a regular number, 208 | # so we apply our algorithm: 209 | 210 | ################################################################## 211 | 212 | 213 | # Split the number into its sign and the 31-bit value 214 | OP_DUP 215 | OP_ABS 216 | OP_TUCK 217 | OP_NUMNOTEQUAL 218 | 219 | # The sign rotated becomes the bit at index 31-3 = 28 220 | OP_IF 221 | 268435456 # This is 2^28 222 | OP_ELSE 223 | 0 224 | OP_ENDIF 225 | OP_SWAP 226 | OP_ROT 227 | 228 | 229 | # 230 | # Simultaneous integer division and modulus 231 | # 232 | # Computes div_rem of the value divided by 8 == 2^3 233 | # It puts both the quotient and the remainder on the stack 234 | # 235 | 236 | # We compute the result with the help of a "hint" 237 | # provided by the unlocking script. 238 | # We expect that hint to be the quotient `value/8` 239 | # and the following verifies that this is acutally correct: 240 | 241 | # Copy the hint and multiply it by 8 242 | OP_DUP 243 | OP_DUP OP_ADD OP_DUP OP_ADD OP_DUP OP_ADD 244 | 245 | # Subtract the result from the original value and ensure 246 | # the remainder is a number in [0,1,2,...,7] 247 | OP_ROT 248 | OP_SWAP 249 | OP_SUB 250 | OP_DUP 251 | 0 252 | 8 253 | OP_WITHIN 254 | OP_VERIFY 255 | 256 | # Now remainder and quotient is on the stack 257 | 258 | 259 | # 260 | # Most of the following code is juggeling around bits 261 | # to deal with the sign of our result 262 | # 263 | 264 | 265 | # Cut off the highest bit of the remainder because this will be our new sign 266 | # The remainder has 3 bits. So the highest bit is set from 4 = 2**(3-1) upwards 267 | 268 | # Check if the highest bit of the remainder is set 269 | OP_DUP 270 | 4 271 | OP_GREATERTHANOREQUAL 272 | OP_IF 273 | # The bit is set. So cut it off 274 | 4 275 | OP_SUB 276 | 1 # The new sign 277 | OP_ELSE 278 | 0 # The new sign 279 | OP_ENDIF 280 | # Push the new sign in the altstack for later 281 | OP_TOALTSTACK 282 | 283 | 284 | # Shift the unsigned remainder 32-3 = 29 bits to the left 285 | 286 | # 287 | # The unsigned remainder has only 4 bits here, so we can handle all 4 cases with a constant 288 | # instead of multiplying the remainder by 2^29 289 | # 290 | 291 | OP_DUP 292 | OP_IF # Otherwise, we return 0 * 2^29 293 | # The unsigned remainder was not zero, so we have to add more than a zero 294 | OP_DUP 295 | 1 296 | OP_EQUAL 297 | OP_IF 298 | OP_DROP 299 | 00000020 # This is 1 * 2^29 300 | OP_ELSE 301 | 2 302 | OP_EQUAL 303 | OP_IF 304 | 00000040 # This is 2 * 2^29 305 | OP_ELSE 306 | 00000060 # This is 3 * 2^29 307 | OP_ENDIF 308 | OP_ENDIF 309 | OP_ENDIF 310 | 311 | 312 | # Now add up all three values 313 | OP_ADD 314 | OP_ADD 315 | 316 | 317 | # Adjust the new sign 318 | OP_FROMALTSTACK 319 | OP_IF 320 | OP_NEGATE 321 | OP_ENDIF 322 | 323 | # And we're done. The result is on the stack 324 | 325 | OP_ENDIF 326 | OP_ENDIF 327 | 328 | # ]" 0x11111101 0x88888888 329 | 330 | ``` 331 | 332 | 333 | We can make this even more efficient and generalize it by [using lookup tables](op_lookup.md) 334 | 335 | 336 | ## Generic Implementation 337 | 338 | Here's a [generic implementation using templates for a rotations by any number of bits]( 339 | https://coins.github.io/bitcoin-scripts/script-editor/#JHtrPTd9CgoKIyBDaGVjayBpZiB0aGUgaW5wdXQgaXMgdGhlIG51bWJlciB0aGF0IG1hcHMgdG8gbmVnYXRpdmUgemVybyB3aGVuIHNoaWZ0ZWQgJHtrfSBiaXRzIHRvIHRoZSByaWdodApPUF9EVVAKJHsyKiooay0xKX0KT1BfRVFVQUwKT1BfSUYKCSMgVGhpcyBpcyB0aGUgbnVtYmVyIHRoYXQgbWFwcyB0byBuZWdhdGl2ZSB6ZXJvCQoJIyBTbyB3ZSBzaW1wbHkgcmV0dXJuIHRoZSBieXRlIHN0cmluZyBvZiBuZWdhdGl2ZSB6ZXJvIGhlcmUKCU9QX0RST1AKCU9QX0RST1AKCTB4MDA4MAkJCSMgV2UgcmV0dXJuIGhlcmUgdGhlIG5lZ2F0aXZlIHplcm8KCk9QX0VMU0UKCSMgVGhpcyBpcyBub3QgdGhlIG51bWJlciB0aGF0IG1hcHMgdG8gbmVnYXRpdmUgemVybwoKCSMgQ2hlY2sgaWYgdGhlIG51bWJlciBpdHNlbGYgaXMgdGhlIG5lZ2F0aXZlIHplcm8KCU9QX0RVUAoJMHgwMDgwCQkJIyBUaGlzIHB1c2hlcyB0aGUgbmVnYXRpdmUgemVybyBvbnRvIHRoZSBzdGFjawoJT1BfRVFVQUwKCU9QX0lGCgkJCgkJIyBUaGlzIG51bWJlciBpcyB0aGUgbmVnYXRpdmUgemVyby4gVGhpcyBjYXNlIGlzIGhhbmRsZWQgYnkgYSBjb25zdGFudCwgdG9vLgoJCSMgV2UgcmV0dXJuIHRoZSBuZWdhdGl2ZSB6ZXJvIHJvdGF0ZWQgYnkgMyBiaXRzCgkJT1BfRFJPUAoJCU9QX0RST1AKCQkkezIqKigzMS1rKX0JIyBXZSByZXR1cm4gaGVyZSB0aGUgcm90YXRlZCBuZWdhdGl2ZSB6ZXJvIAoKCU9QX0VMU0UKCgkJIyBGaW5hbGx5IHdlIGtub3cgdGhpcyBpcyBub3QgYW4gZWRnZSBjYXNlIGJ1dCBhIHJlZ3VsYXIgbnVtYmVyLAoJCSMgc28gd2UgYXBwbHkgb3VyIGFsZ29yaXRobToKCQkKCQkjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCgoJCSMgU3BsaXQgdGhlIG51bWJlciBpbnRvIGl0cyBzaWduIGFuZCB0aGUgMzEtYml0IHZhbHVlCgkJT1BfRFVQCgkJT1BfQUJTCgkJT1BfVFVDSwoJCU9QX05VTU5PVEVRVUFMCgoJCSMgVGhlIHNpZ24gcm90YXRlZCBiZWNvbWVzIHRoZSBiaXQgYXQgaW5kZXggMzEtJHtrfSA9ICR7MzEta30KCQlPUF9JRgoJCQkkezIqKigzMS1rKX0gCgkJT1BfRUxTRQoJCQkwCgkJT1BfRU5ESUYKCQlPUF9TV0FQCgkJT1BfUk9UCgoJCQoJCSMKCQkjIFNpbXVsdGFuZW91cyBpbnRlZ2VyIGRpdmlzaW9uIGFuZCBtb2R1bHVzCgkJIwoJCSMgQ29tcHV0ZXMgZGl2X3JlbSBvZiB0aGUgdmFsdWUgZGl2aWRlZCBieSAkezIqKmt9ID09IDJeJHtrfQoJCSMgSXQgcHV0cyBib3RoIHRoZSBxdW90aWVudCBhbmQgdGhlIHJlbWFpbmRlciBvbiB0aGUgc3RhY2sKCQkjCgoJCSMgV2UgY29tcHV0ZSB0aGUgcmVzdWx0IHdpdGggdGhlIGhlbHAgb2YgYSAiaGludCIgCgkJIyBwcm92aWRlZCBieSB0aGUgdW5sb2NraW5nIHNjcmlwdC4KCQkjIFdlIGV4cGVjdCB0aGF0IGhpbnQgdG8gYmUgdGhlIHF1b3RpZW50IHZhbHVlLyR7Mioqa30KCQkjIGFuZCB0aGUgZm9sbG93aW5nIHZlcmlmaWVzIHRoYXQgdGhpcyBpcyBhY3V0YWxseSBjb3JyZWN0OgoKCQkjIENvcHkgdGhlIGhpbnQgYW5kIG11bHRpcGx5IGl0IGJ5IDIqKiR7a30KCQlPUF9EVVAKCQkke2xvb3AoaywgaSA9PiBgCiAgICAgICAgICAgICAgICAgICAgICAgIE9QX0RVUCBPUF9BRERgKX0KCgkJIyBTdWJ0cmFjdCB0aGUgcmVzdWx0IGZyb20gdGhlIG9yaWdpbmFsIHZhbHVlIGFuZCBlbnN1cmUKCQkjIHRoZSByZW1haW5kZXIgaXMgYSBudW1iZXIgaW4gWzAsMSwyLC4uLiwyKioke2t9LTFdCgkJT1BfUk9UCgkJT1BfU1dBUAoJCU9QX1NVQgoJCU9QX0RVUAoJCTAKCQkkezIqKmt9CgkJT1BfV0lUSElOCgkJT1BfVkVSSUZZCgoJCSMgTm93IHJlbWFpbmRlciBhbmQgcXVvdGllbnQgaXMgb24gdGhlIHN0YWNrCgoKCQkjCgkJIyBNb3N0IG9mIHRoZSBmb2xsb3dpbmcgY29kZSBpcyBqdWdnZWxpbmcgYXJvdW5kIGJpdHMKCQkjIHRvIGRlYWwgd2l0aCB0aGUgc2lnbiBvZiBvdXIgcmVzdWx0CgkJIwoKCQkKCQkjIEN1dCBvZmYgdGhlIGhpZ2hlc3QgYml0IG9mIHRoZSByZW1haW5kZXIgYmVjYXVzZSB0aGlzIHdpbGwgYmUgb3VyIG5ldyBzaWduIAoJCSMgVGhlIHJlbWFpbmRlciBoYXMgMyBiaXRzLiBTbyB0aGUgaGlnaGVzdCBiaXQgCiAgICAgICAgICAgICAgICAjIGlzIHNldCBmcm9tICR7MioqKGstMSl9ID0gMioqKCR7a30tMSkgdXB3YXJkcwoKCQkjIENoZWNrIGlmIHRoZSBoaWdoZXN0IGJpdCBvZiB0aGUgcmVtYWluZGVyIGlzIHNldAoJCU9QX0RVUAoJCSR7MioqKGstMSl9CgkJT1BfR1JFQVRFUlRIQU5PUkVRVUFMCgkJT1BfSUYKCQkJIyBUaGUgYml0IGlzIHNldC4gU28gY3V0IGl0IG9mZgoJCQkkezIqKihrLTEpfQoJCQlPUF9TVUIKCQkJMSAJIyBUaGUgbmV3IHNpZ24KCQlPUF9FTFNFCgkJCTAgCSMgVGhlIG5ldyBzaWduCgkJT1BfRU5ESUYKCQkjIFB1c2ggdGhlIG5ldyBzaWduIGluIHRoZSBhbHRzdGFjayBmb3IgbGF0ZXIKCQlPUF9UT0FMVFNUQUNLCgoKCQkjIFNoaWZ0IHRoZSB1bnNpZ25lZCByZW1haW5kZXIgMzItJHtrfSA9ICR7MzIta30gYml0cyB0byB0aGUgbGVmdAoKCQkke2xvb3AoMzItaywgaSA9PiBgCiAgICAgICAgICAgICAgICAgICAgICAgIE9QX0RVUCBPUF9BRERgKX0KCQkKCQkjIE5vdyBhZGQgdXAgYWxsIHRocmVlIHZhbHVlcwoJCU9QX0FERCAKCQlPUF9BREQKCgoJCSMgQWRqdXN0IHRoZSBuZXcgc2lnbgoJCU9QX0ZST01BTFRTVEFDSwoJCU9QX0lGCgkJCU9QX05FR0FURQoJCU9QX0VORElGCgoJCSMgQW5kIHdlJ3JlIGRvbmUuIFRoZSByZXN1bHQgaXMgb24gdGhlIHN0YWNrCgoJT1BfRU5ESUYKT1BfRU5ESUY=) 340 | -------------------------------------------------------------------------------- /op_rshift.md: -------------------------------------------------------------------------------- 1 | # Bitwise Right Shift: OP_RSHIFT 2 | 3 | Bitwise right shifts of 32-bit words. 4 | 5 | 6 | ## Bitwise Right Shift by 3 Bits: OP_3RSHIFT 7 | 8 | ``` 9 | 10 | btcdeb "[ 11 | 12 | # Some random 32-bit word is on the stack 13 | 0x88888888 14 | 15 | 16 | 17 | # Nullify the sign, shift it, and memorize it for later 18 | DUP 0 LESSTHAN 19 | IF 20 | ABS 21 | 268435456 TOALTSTACK 22 | ELSE 23 | 0 TOALTSTACK 24 | ENDIF 25 | 26 | 27 | # Nullify the highest bit, shift it, and memorize it for later 28 | DUP 1073741824 GREATERTHANOREQUAL 29 | IF 30 | 1073741824 SUB 31 | 134217728 TOALTSTACK 32 | ELSE 33 | 0 TOALTSTACK 34 | ENDIF 35 | 36 | 37 | 38 | # 27 doublings modulo 2**30 -1 39 | 40 | DUP ADD 41 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 42 | 43 | DUP ADD 44 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 45 | 46 | DUP ADD 47 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 48 | 49 | DUP ADD 50 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 51 | 52 | DUP ADD 53 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 54 | 55 | DUP ADD 56 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 57 | 58 | DUP ADD 59 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 60 | 61 | DUP ADD 62 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 63 | 64 | DUP ADD 65 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 66 | 67 | DUP ADD 68 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 69 | 70 | DUP ADD 71 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 72 | 73 | DUP ADD 74 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 75 | 76 | DUP ADD 77 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 78 | 79 | DUP ADD 80 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 81 | 82 | DUP ADD 83 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 84 | 85 | DUP ADD 86 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 87 | 88 | DUP ADD 89 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 90 | 91 | DUP ADD 92 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 93 | 94 | DUP ADD 95 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 96 | 97 | DUP ADD 98 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 99 | 100 | DUP ADD 101 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 102 | 103 | DUP ADD 104 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 105 | 106 | DUP ADD 107 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 108 | 109 | DUP ADD 110 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 111 | 112 | DUP ADD 113 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 114 | 115 | DUP ADD 116 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 117 | 118 | DUP ADD 119 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 120 | 121 | 122 | 123 | 124 | # If the 1st bit was odd we have to subtract 1/2 == 2**29 (mod N) 125 | DUP 536870912 GREATERTHANOREQUAL IF 536870912 SUB ENDIF 126 | 127 | # If the 2nd bit was odd we have to subtract 1/4 == 2**28 (mod N) 128 | DUP 268435456 GREATERTHANOREQUAL IF 268435456 SUB ENDIF 129 | 130 | # If the 3rd bit was odd we have to subtract 1/8 == 2**27 (mod N) 131 | DUP 134217728 GREATERTHANOREQUAL IF 134217728 SUB ENDIF 132 | 133 | 134 | # Add the sign and the highest bit 135 | FROMALTSTACK 136 | ADD 137 | FROMALTSTACK 138 | ADD 139 | 140 | 141 | ]" 142 | ``` 143 | 144 | 145 | ## Bitwise Right Shift by 7 Bits: OP_7RSHIFT 146 | 147 | Instruction count: 290 148 | 149 | ``` 150 | 151 | 0x88888888 152 | 153 | 154 | 155 | DUP 0 LESSTHAN 156 | IF 157 | ABS 158 | 16777216 TOALTSTACK 159 | ELSE 160 | 0 TOALTSTACK 161 | ENDIF 162 | 163 | DUP 1073741824 GREATERTHANOREQUAL 164 | IF 165 | 1073741824 SUB 166 | 8388608 TOALTSTACK 167 | ELSE 168 | 0 TOALTSTACK 169 | ENDIF 170 | 171 | 172 | # 23 doublings modulo 2**30 -1 173 | 174 | DUP ADD 175 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 176 | 177 | DUP ADD 178 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 179 | 180 | DUP ADD 181 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 182 | 183 | DUP ADD 184 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 185 | 186 | DUP ADD 187 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 188 | 189 | DUP ADD 190 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 191 | 192 | DUP ADD 193 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 194 | 195 | DUP ADD 196 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 197 | 198 | DUP ADD 199 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 200 | 201 | DUP ADD 202 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 203 | 204 | DUP ADD 205 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 206 | 207 | DUP ADD 208 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 209 | 210 | DUP ADD 211 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 212 | 213 | DUP ADD 214 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 215 | 216 | DUP ADD 217 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 218 | 219 | DUP ADD 220 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 221 | 222 | DUP ADD 223 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 224 | 225 | DUP ADD 226 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 227 | 228 | DUP ADD 229 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 230 | 231 | DUP ADD 232 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 233 | 234 | DUP ADD 235 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 236 | 237 | DUP ADD 238 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 239 | 240 | DUP ADD 241 | DUP 1073741823 GREATERTHANOREQUAL IF 1073741823 SUB ENDIF 242 | 243 | 244 | 245 | 246 | 247 | # If the 1st bit was odd we have to subtract 1/2 mod N 248 | DUP 536870912 GREATERTHANOREQUAL IF 536870912 SUB ENDIF 249 | 250 | # If the 2nd bit was odd we have to subtract 1/4 mod N 251 | DUP 268435456 GREATERTHANOREQUAL IF 268435456 SUB ENDIF 252 | 253 | # If the 3rd bit was odd we have to subtract 1/8 mod N 254 | DUP 134217728 GREATERTHANOREQUAL IF 134217728 SUB ENDIF 255 | 256 | # If the 4rd bit was odd we have to subtract 1/16 mod N 257 | DUP 67108864 GREATERTHANOREQUAL IF 67108864 SUB ENDIF 258 | 259 | # If the 5rd bit was odd we have to subtract 1/32 mod N 260 | DUP 33554432 GREATERTHANOREQUAL IF 33554432 SUB ENDIF 261 | 262 | # If the 6rd bit was odd we have to subtract 1/64 mod N 263 | DUP 16777216 GREATERTHANOREQUAL IF 16777216 SUB ENDIF 264 | 265 | # If the 7rd bit was odd we have to subtract 1/128 mod N 266 | DUP 8388608 GREATERTHANOREQUAL IF 8388608 SUB ENDIF 267 | 268 | 269 | 270 | 271 | 272 | 273 | FROMALTSTACK 274 | ADD 275 | FROMALTSTACK 276 | ADD 277 | 278 | ``` 279 | 280 | ## Generic Implementation 281 | Here's a [generic implementation for any number of bits using templates](https://coins.github.io/bitcoin-scripts/script-editor/#IyBCeSBob3cgbWFueSBiaXRzIGRvIHlvdSB3YW50IHRvIHNoaWZ0Pwoke2sgPSAxMH0KCgoKRFVQIDAgTEVTU1RIQU4gCklGIAogQUJTCiAkezIqKigzMS1rKX0gVE9BTFRTVEFDSwpFTFNFCiAwIFRPQUxUU1RBQ0sKRU5ESUYKCkRVUCAkezIqKjMwfSBHUkVBVEVSVEhBTk9SRVFVQUwgCklGIAogJHsyKiozMH0gU1VCCiAkezIqKigzMS1rKX0gVE9BTFRTVEFDSwpFTFNFCiAwIFRPQUxUU1RBQ0sKRU5ESUYKICAgICAgICAKCiMgJHszMC1rfSBkb3VibGluZ3MgbW9kdWxvIG4KJHtsb29wKCAzMC1rICwgaW5kZXggPT4gYAogICAgRFVQIEFERAogICAgRFVQICR7MioqMzAtMX0gR1JFQVRFUlRIQU5PUkVRVUFMIElGICR7MioqMzAtMX0gU1VCIEVORElGCmApfQoKCgoke2xvb3AoIGsgLCBpbmRleCA9PiBgCiAgICAjIElmIHRoZSAke2luZGV4KzF9cmQgYml0IHdhcyBvZGQgd2UgaGF2ZSB0byBzdWJ0cmFjdCAxLyR7MioqKGluZGV4KzEpfSBtb2QgTgogICAgRFVQICR7MioqKDI5LWluZGV4KX0gR1JFQVRFUlRIQU5PUkVRVUFMIElGICR7MioqKDI5LWluZGV4KX0gU1VCIEVORElGCmApfQoKCgoKCkZST01BTFRTVEFDSwpBREQKRlJPTUFMVFNUQUNLCkFERAo=) 282 | -------------------------------------------------------------------------------- /preimage-sequence.md: -------------------------------------------------------------------------------- 1 | # Hash Pre-Image Sequence Commitment 2 | 3 | 4 | ## Basic Pre-Image Sequence 5 | 6 | Alice commits C into an output such that she can reveal `R_N = HASH( ... HASH( C ))`. 7 | We combine that to create transactions with dynamic lock times. 8 | 9 | ### 1 Bit Commitment 10 | 11 | ``` 12 | OP_HASH256 13 | 14 | 15 | 16 | OP_SWAP 17 | 18 | OP_ROT 19 | OP_IF 20 | OP_EQUALVERIFY 21 | 24 22 | OP_CHECKSEQUENCEVERIFY 23 | OP_ENDIF 24 | OP_HASH256 25 | OP_EQUALVERIFY 26 | ``` 27 | 28 | Spendable with: 29 | ``` 30 | 1 31 | ``` 32 | OR 33 | ``` 34 | 0 35 | ``` 36 | 37 | 38 | ### 4 Bit Commitment 39 | 40 | `COMMITMENT = HASH(HASH(HASH(HASH(PREIMAGE))))` 41 | 42 | ``` 43 | OP_HASH256 44 | 45 | 46 | OP_SWAP 47 | 48 | 49 | OP_ROT 50 | OP_IF 51 | OP_EQUALVERIFY 52 | 24 53 | OP_CHECKSEQUENCEVERIFY 54 | OP_ENDIF 55 | OP_HASH256 56 | 57 | 58 | OP_ROT 59 | OP_IF 60 | OP_EQUALVERIFY 61 | 18 62 | OP_CHECKSEQUENCEVERIFY 63 | OP_ENDIF 64 | OP_HASH256 65 | 66 | 67 | OP_ROT 68 | OP_IF 69 | OP_EQUALVERIFY 70 | 12 71 | OP_CHECKSEQUENCEVERIFY 72 | OP_ENDIF 73 | OP_HASH256 74 | 75 | 76 | OP_ROT 77 | OP_IF 78 | OP_EQUALVERIFY 79 | 6 80 | OP_CHECKSEQUENCEVERIFY 81 | OP_ENDIF 82 | 83 | ``` 84 | 85 | ### Example Input 86 | Hashed three times, spendable after 12 blocks. 87 | ``` 88 | 0 0 1 0 89 | ``` 90 | 91 | Hashed two times, spendable after 6 blocks. 92 | ``` 93 | 0 0 0 1 94 | ``` 95 | 96 | ## 2 Parties 97 | 98 | Alice and Bob create an output in the Blockchain such that they can change its timelock afterwards. 99 | 100 | 101 | 102 | 103 | Using two such time lock commitments in a payment channel with Alice and Bob, they can always execute their most recent state in a single transaction. 104 | 105 | 106 | ``` 107 | 108 | OP_HASH256 109 | 110 | 111 | 112 | 113 | OP_SWAP 114 | 115 | 116 | 117 | OP_ROT 118 | OP_IF 119 | OP_EQUALVERIFY 120 | 24 121 | OP_CODESEPARATOR 122 | OP_ENDIF 123 | OP_HASH256 124 | 125 | 126 | OP_ROT 127 | OP_IF 128 | OP_EQUALVERIFY 129 | 18 130 | OP_CODESEPARATOR 131 | OP_ENDIF 132 | OP_HASH256 133 | 134 | 135 | OP_ROT 136 | OP_IF 137 | OP_EQUALVERIFY 138 | 12 139 | OP_CODESEPARATOR 140 | OP_ENDIF 141 | OP_HASH256 142 | 143 | 144 | OP_ROT 145 | OP_IF 146 | OP_EQUALVERIFY 147 | 6 148 | OP_CODESEPARATOR 149 | OP_ENDIF 150 | 151 | 152 | 153 | OP_CHECKSEQUENCEVERIFY 154 | OP_DROP 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | OP_SWAP 163 | 164 | 165 | 166 | OP_ROT 167 | OP_IF 168 | OP_EQUALVERIFY 169 | 24 170 | OP_CODESEPARATOR 171 | OP_ENDIF 172 | OP_HASH256 173 | 174 | 175 | OP_ROT 176 | OP_IF 177 | OP_EQUALVERIFY 178 | 18 179 | OP_CODESEPARATOR 180 | OP_ENDIF 181 | OP_HASH256 182 | 183 | 184 | OP_ROT 185 | OP_IF 186 | OP_EQUALVERIFY 187 | 12 188 | OP_CODESEPARATOR 189 | OP_ENDIF 190 | OP_HASH256 191 | 192 | 193 | OP_ROT 194 | OP_IF 195 | OP_EQUALVERIFY 196 | 6 197 | OP_CODESEPARATOR 198 | OP_ENDIF 199 | 200 | 201 | 202 | OP_CHECKSEQUENCEVERIFY 203 | OP_DROP 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 2 213 | 214 | 215 | 2 216 | OP_CHECKMULTISIG 217 | 218 | 219 | ``` 220 | 221 | The `OP_CODESEPARATOR` guarantee signatures bind to pre-images. To trigger the N-th case Alice can not use any of Bob's signatures except for his N-th. 222 | 223 | [View in Script Editor](../../apps/script-editor/index.html#T1BfSEFTSDI1NgoKJHtsb29wKDIsIGkgPT4gYAoKPENPTU1JVE1FTlRfJHtpKzF9PgpPUF9TV0FQCgoke2xvb3AoICA0LCAoaW5kZXgsIGxlbmd0aCkgPT4gIGAKCk9QX1JPVApPUF9JRgkKICAgICAgICBPUF9FUVVBTFZFUklGWSAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICR7IChsZW5ndGgtaW5kZXgpICogNiB9CiAgICAgICAgT1BfQ09ERVNFUEVSQVRPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKT1BfRU5ESUYKJHsgaW5kZXggPCBsZW5ndGgtMSA/ICdPUF9IQVNIMjU2JyA6ICcnIH0KYCl9ICAgCiAgIApPUF9DSEVDS1NFUVVFTkNFVkVSSUZZCk9QX0RST1AKCgoKCmApfQoKCgoyCjxBTElDRSBLRVk+CjxCT0IgS0VZPgoyCk9QX0NIRUNLTVVMVElTSUcgIA==) 224 | 225 | 226 | ### Limitations 227 | - 7 bit per party = 14 bit commitment + 2-of-2 signature 228 | 229 | 230 | 231 | ### Multiple Hash Functions 232 | Use multiple hash functions to encode more states. 233 | 234 | ``` 235 | 236 | 237 | OP_SWAP 238 | 239 | 240 | OP_ROT 241 | OP_IF 242 | OP_EQUALVERIFY 243 | 24 244 | OP_CHECKSEQUENCEVERIFY 245 | OP_ENDIF 246 | OP_HASH256 247 | 248 | 249 | OP_ROT 250 | OP_IF 251 | OP_EQUALVERIFY 252 | 18 253 | OP_CHECKSEQUENCEVERIFY 254 | OP_ENDIF 255 | OP_HASH256 256 | 257 | 258 | OP_ROT 259 | OP_IF 260 | OP_EQUALVERIFY 261 | 12 262 | OP_CHECKSEQUENCEVERIFY 263 | OP_ENDIF 264 | OP_HASH256 265 | 266 | 267 | OP_ROT 268 | OP_IF 269 | OP_EQUALVERIFY 270 | 6 271 | OP_CHECKSEQUENCEVERIFY 272 | OP_ENDIF 273 | ``` 274 | 275 | 276 | ## References 277 | - [Reddit discussion of the possible uses OP_CHECKSEQUENCEVERIFY](https://www.reddit.com/r/Bitcoin/comments/4p4klg/bitcoin_core_project_the_csv_soft_fork_has/d4i01he/) 278 | 279 | 280 | 281 | 282 | -------------------------------------------------------------------------------- /proof-of-work.md: -------------------------------------------------------------------------------- 1 | # Proof of Work in Bitcoin Script 2 | 3 | ## Signature Length 4 | The length of the signature can be used as a proof of work committed to the output. Here's a write up of [the ideas of Maxwell and others](https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000344.html) regarding single show signatures. 5 | 6 | `OP_SIZE 57 OP_LESSTHANOREQUAL OP_VERIFY

OP_CHECKSIGVERIFY` 7 | 8 | `Using that value reveals the secret key p: p = (2s - h)/r (mod O(g)).` 9 | 10 | The same mechanism can be used to verify a proof of work in script. 11 | 12 | ### Limitations 13 | - The PoW is in ECDSA 14 | - The difficulty granularity is byte size steps 15 | 16 | ## Hash Preimage Challenges 17 | An interactive PoW puzzle is possible with hash pre-images. 18 | A challenger gives a puzzle commitment to a prover. The prover has to bruteforce which hash sequence led to the commitment. We use the mechanism from "7-bit Integer commitments" an reverse it. The challenger commits to A preimage and hash commitment. The prover needs to bruteforce all possible hashs to find the path from preimage to commitment. The prove of knowledge of the puzzle solution is the integer. 19 | [Here is an example transaction.](https://blockstream.info/nojs/tx/a3803be4f3da166096b4408ffe36a07750f31bb2b58bd660f8f1a0c59a99dda6) 20 | 21 | 22 | ### Features 23 | - The difficulty granularity is bit size 24 | 25 | ### Limitations 26 | - Trusted challenger is required 27 | - challenger can cheat by providing an unsolvable puzzle. 28 | - yet, prover can proof challenger cheated by bruteforcing all possible 29 | - A ZKP might help to prove that a solution exists. 30 | - opcodes grows linear with difficulty 31 | - maximum difficulty is 30 bits ~ 5 bytes 32 | 33 | 34 | ## PoW in Private Key 35 | The challenger creates a N-bit commitment with two hash functions. The secret is a private key. N is the Difficulty. He funds the corresponding address. He publishes the address and the pre image. 36 | 37 | Alice challenges Bob for a proof of work. 38 | We use two distinct hash functions `H1` and `H0`. 39 | 40 | 1. Alice chooses a commitment `C` randomly. `C` is about 32 bytes. 41 | 2. Alice chooses a random bit string `x` of length `N`. For example `x = 110101`. 42 | 3. Alice derives a secret key `X`. In our example `C = H1(H1(H0(H1(H0(H1( x ))))))`. 43 | 4. Alice derives the corresponding public key and broadcasts a funding transaction. 44 | 5. Bob starts the race as soon as he learns `C`. 45 | 46 | ### Features 47 | - The granularity of the difficulty is bit size 48 | - No opcodes. Fully off-chain. 49 | - Actually no hash chain is required. It is just a relict from previous ideas. Simply use a nonce as in bitcoin's PoW. Verification time is constant in `N`. 50 | - Any proof of work algorithm can be used. 51 | - ASIC resistance is possible if the algorithm changes drastically for every new challenge. 52 | 53 | ### Limitations 54 | - Trusted dealer is required. He can cheat by providing an unsolvable puzzle. 55 | 56 | ### Zero Knowledge proof 57 | We can staple a zero-knowledge proof to the puzzle to prove a solution exist. 58 | Using [Bulletproofs](https://web.stanford.edu/~buenz/pubs/bulletproofs.pdf) a "SHA256 preimage proof is 1.4 KB and takes 750 ms to verify." and it is trustless. 59 | 60 | 61 | ## Multiple Hash functions 62 | To increase the number of bits in our schemes we can use multiple hash functions in varying orders. This helps to add entropy to committed values with low entropy. 63 | 64 | ``` 65 | OP_RIPEMD160 66 | OP_SHA1 67 | OP_SHA256 68 | OP_HASH160 69 | OP_HASH256 70 | ``` 71 | 72 | 73 | 74 | 75 | # Proof of Work in Bitcoin Script 2 76 | 77 | 78 | The following script allows everyone to spend; the shorter your signature the earlier you can spend. 79 | ``` 80 | OP_SIZE 81 | OP_CHECKSEQUENCEVERIFY OP_DROP 82 | 83 | OP_CHECKSIGVERIFY 84 | ``` 85 | 86 | The point `R = 1/2 G` has the smallest known `x` coordinate -- `x = 0x3b78ce563f89a0ed9414f5aa28ad0d96d6795f9c63`. If the public key is chosen `P = 1 G` then the ECDSA signature becomes `s=2(H(m)+x)`. So, the smaller `H(m)` the smaller `s` (as long as it is bigger than `x ~ 2^165`). Thus, the above output is spendable by the miner mining the lowest TX hash. Also [see the discussion here](https://gist.github.com/RobinLinus/95de641ed1e3d9fde83bdcf5ac289ce9) 87 | 88 | 89 | # Related Work 90 | 91 | - [proof of work via ecdsa signature length (by VzxPLnHqr)](https://github.com/VzxPLnHqr/sig-pow) 92 | -------------------------------------------------------------------------------- /rock-paper-scissors.md: -------------------------------------------------------------------------------- 1 | # Rock Paper Scissors 2 | 3 | Both Alice and Bob make pre-image length commitments as described in [betcoins](betcoins.md). 4 | 5 | 6 | For compact code we use some group theory. 7 | 8 | 9 | ## Solution 1: Additive Group mod 3 10 | 11 | ``` 12 | btcdeb "[ 13 | 14 | OP_DUP 15 | OP_HASH160 16 | 74f36c5e0c6ad544a3279502ae7c9bce698012b1 17 | OP_EQUALVERIFY 18 | 19 | OP_SIZE 20 | OP_NIP 21 | 22 | OP_DUP 23 | 16 24 | 19 25 | OP_WITHIN 26 | OP_VERIFY 27 | 28 | 15 29 | OP_SUB 30 | 31 | OP_SWAP 32 | 33 | OP_DUP 34 | OP_HASH160 35 | 80ad9c03fd4f8d1eebfadc515df7956ddf3c3dc7 36 | OP_EQUALVERIFY 37 | 38 | OP_SIZE 39 | OP_NIP 40 | 41 | OP_DUP 42 | 16 43 | 19 44 | OP_WITHIN 45 | OP_VERIFY 46 | 47 | 15 48 | OP_SUB 49 | 50 | 51 | OP_2DUP 52 | OP_EQUAL 53 | OP_IF 54 | OP_2DROP 55 | cccccccc 56 | OP_ELSE 57 | 58 | OP_1ADD 59 | 60 | OP_DUP 61 | 2 62 | OP_GREATERTHAN 63 | OP_IF 64 | OP_DROP 65 | 1 66 | OP_ENDIF 67 | 68 | OP_EQUAL 69 | OP_IF 70 | aaaaaaaa 71 | OP_ELSE 72 | bbbbbbbb 73 | OP_ENDIF 74 | 75 | OP_ENDIF 76 | 77 | OP_DROP 78 | OP_TRUE 79 | 80 | # ]" bbbbbbb0bbbbbbb0bbbbbbb0bbbbbbb0bbbb aaaaaaa0aaaaaaa0aaaaaaa0aaaaaaa0aaaa 81 | 82 | ``` 83 | 84 | ## Solution 2: Multiplicative Group mod 7 85 | We want a multiplicative group of three elements. 86 | The finite field to the prime 7 has the subgroup `{1,2,4}`. `2` is a generator of this subgroup. 87 | Both Alice and Bob commit to an element of that group; `A` and `B` respectively. 88 | We check if Alice is Bob's "successor" by multiplying her value with the generator `2`. 89 | Three cases: 90 | - `A == B`: That's a tie. 91 | - `A*2 == B`: Alice Won 92 | - `A == B*2`: Bob Won 93 | 94 | 95 | ``` 96 | OP_DUP 97 | OP_HASH160 98 | < Alice's Commitment > 99 | OP_EQUALVERIFY 100 | 101 | OP_SIZE 102 | OP_NIP 103 | 104 | OP_DUP 105 | 16 106 | 20 107 | OP_WITHIN 108 | OP_VERIFY 109 | 110 | 15 111 | OP_SUB 112 | 113 | OP_DUP 114 | 3 115 | OP_NUMNOTEQUAL 116 | OP_VERIFY 117 | 118 | OP_SWAP 119 | 120 | OP_DUP 121 | OP_HASH160 122 | < Bob's Commitment > 123 | OP_EQUALVERIFY 124 | 125 | OP_SIZE 126 | OP_NIP 127 | 128 | OP_DUP 129 | 16 130 | 20 131 | OP_WITHIN 132 | OP_VERIFY 133 | 134 | 15 135 | OP_SUB 136 | 137 | OP_DUP 138 | 3 139 | OP_NUMNOTEQUAL 140 | OP_VERIFY 141 | 142 | 143 | OP_2DUP 144 | OP_EQUAL 145 | OP_IF 146 | OP_2DROP 147 | < Case Tie > 148 | OP_ELSE 149 | 150 | OP_DUP 151 | OP_ADD 152 | 153 | OP_DUP 154 | 7 155 | OP_GREATERTHAN 156 | OP_IF 157 | OP_DROP 158 | 1 159 | OP_ENDIF 160 | 161 | OP_EQUAL 162 | OP_IF 163 | < Case Alice Wins > 164 | OP_ELSE 165 | < Case Bob Wins > 166 | OP_ENDIF 167 | 168 | OP_ENDIF 169 | ``` 170 | 171 | 172 | Here is [an example transaction](https://blockstream.info/nojs/tx/4586f390acbf9c34157f6331ad70dbb8d476edb65d86aa17e6c481a79c97c91c?expand) 173 | 174 | ### Limitations 175 | - Unnecessarily complex: We used the multiplicative group with three elements. That group is isomorphic to the additive group `{0,1,2}`. In that group the algorithm is much simpler. It uses only addition and less opcodes. 176 | 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /schnorr-magic.md: -------------------------------------------------------------------------------- 1 | # Schnorr Magic 2 | 3 | - [MuSig2 Simple Two-Round Schnorr Multi-Signatures](https://eprint.iacr.org/2020/1261.pdf) 4 | - [FROST: Flexible Round-Optimized Schnorr Threshold Signatures](https://eprint.iacr.org/2020/852.pdf) 5 | - [ROAST](https://eprint.iacr.org/2022/550) 6 | - [Scriptless Scripts](https://github.com/ElementsProject/scriptless-scripts) 7 | - [Discrete Log Contracts](https://adiabat.github.io/dlc.pdf) 8 | - [Scriptless Lotteries on Bitcoin from Oblivious Transfer](https://telaviv2019.scalingbitcoin.org/files/scriptless-lotteries-on-bitcoin-from-oblivious-transfer.pdf) 9 | -------------------------------------------------------------------------------- /script-editor/index.html: -------------------------------------------------------------------------------- 1 |

2 | Bitcoin Script Editor 3 |
4 | New Script 5 |
6 |
7 | 10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | 123 | 186 | 220 | 221 | 282 | 314 | 330 | -------------------------------------------------------------------------------- /script-editor/readme.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | -[composed opcodes (hacky)](https://coins.github.io/bitcoin-scripts/script-editor/#JHsgISEobGliID0gd2luZG93KT8nJzonJ30KCiR7IGxpYi5PUF9NVUwyID0gYE9QX0RVUCBPUF9BRERgfQokeyBsaWIuT1BfTVVMNCA9IGAke09QX01VTDJ9ICR7T1BfTVVMMn0gYH0KJHsgbGliLk9QX01VTDggPSBgJHtPUF9NVUw0fSAke09QX01VTDJ9IGB9CiR7IGxpYi5PUF9NVUwxNiA9IGAke09QX01VTDh9ICR7T1BfTVVMMn0gYH0KJHsgbGliLk9QX01VTDMyID0gYCR7T1BfTVVMMTZ9ICR7T1BfTVVMMn0gYH0K) 4 | -------------------------------------------------------------------------------- /split-into-bits.md: -------------------------------------------------------------------------------- 1 | # Split Into Bits 2 | 3 | Algorithms to split a stack item into a string of bits. 4 | 5 | ## Lookup Table 6 | 7 | Here, we use a lookup table to circumvent the `OP_IF, OP_ELSE, OP_ENDIF` branches. This idea can get further optimized and can act as a basis to implement bitwise operations such as XOR. 8 | 9 | ```js 10 | ` 11 | // Lookup table 12 | ${ 2**1 } 13 | 0 14 | ${ 2**2 } 15 | 0 16 | ${ 2**3 } 17 | 0 18 | ${ 2**4 } 19 | 0 20 | ${ 2**5 } 21 | 0 22 | ${ 2**6 } 23 | 0 24 | ${ 2**7 } 25 | 0 26 | 27 | // The input value 28 | // We use a bit string only for debugging 29 | // It's a single item on the stack 30 | ${ 0b01100001 } 31 | 32 | DUP 33 | ${ 2**7 } 34 | GREATERTHANOREQUAL 35 | 1ADD 36 | ROLL 37 | SUB 38 | SWAP 39 | TOALTSTACK 40 | 41 | DUP 42 | ${ 2**6 } 43 | GREATERTHANOREQUAL 44 | 1ADD 45 | ROLL 46 | SUB 47 | SWAP 48 | TOALTSTACK 49 | 50 | DUP 51 | ${ 2**5 } 52 | GREATERTHANOREQUAL 53 | 1ADD 54 | ROLL 55 | SUB 56 | SWAP 57 | TOALTSTACK 58 | 59 | DUP 60 | ${ 2**4 } 61 | GREATERTHANOREQUAL 62 | 1ADD 63 | ROLL 64 | SUB 65 | SWAP 66 | TOALTSTACK 67 | 68 | DUP 69 | ${ 2**3 } 70 | GREATERTHANOREQUAL 71 | 1ADD 72 | ROLL 73 | SUB 74 | SWAP 75 | TOALTSTACK 76 | 77 | DUP 78 | ${ 2**2 } 79 | GREATERTHANOREQUAL 80 | 1ADD 81 | ROLL 82 | SUB 83 | SWAP 84 | TOALTSTACK 85 | 86 | DUP 87 | ${ 2**1 } 88 | GREATERTHANOREQUAL 89 | 1ADD 90 | ROLL 91 | SUB 92 | SWAP 93 | TOALTSTACK 94 | 95 | FROMALTSTACK 96 | FROMALTSTACK 97 | FROMALTSTACK 98 | FROMALTSTACK 99 | FROMALTSTACK 100 | FROMALTSTACK 101 | FROMALTSTACK 102 | 103 | ` 104 | ``` 105 | 106 | #### Generic n-bit Template 107 | 108 | ```js 109 | const N = 30; // The bit length 110 | 111 | [ 112 | 113 | // Push the lookup table onto the stack 114 | loop( N - 1, i => ` 115 | ${ 2 ** (i + 1) } 116 | 0 117 | `), 118 | 119 | // The input value 120 | // We use a bit string for debugging 121 | // It's a single item on the stack 122 | 0b0001000000000001, 123 | 124 | // The loop 125 | loop( N - 1, i => ` 126 | DUP 127 | ${ 2 ** (N - 1 - i) } 128 | GREATERTHANOREQUAL 129 | 1ADD 130 | ROLL 131 | SUB 132 | SWAP 133 | TOALTSTACK 134 | `), 135 | 136 | // Read the result from the altstack 137 | loop( N - 1, _ => `FROMALTSTACK` ), 138 | 139 | ] 140 | ``` 141 | 142 | 143 | ## Nullify Leading Bits 144 | 145 | ```js 146 | const N = 16; // The bit length 147 | const T = 8; // Number of leading bits to nullify 148 | 149 | [ 150 | 151 | // Push the lookup table onto the stack 152 | loop( T, i => ` 153 | ${ 2 ** (N - T + i) } 154 | 0 155 | `), 156 | 157 | // The input value 158 | // We use a bit string for debugging 159 | // It's a single item on the stack 160 | 0b1010110011111111, 161 | 162 | // The loop 163 | loop( T, i => ` 164 | DUP 165 | ${ 2 ** (N - 1 - i) } 166 | GREATERTHANOREQUAL 167 | 1ADD 168 | ROLL 169 | SUB 170 | NIP 171 | `), 172 | 173 | ] 174 | ``` 175 | 176 | ### Reusing the Lookup Table 177 | 178 | ```js 179 | const N = 16; // The bit length 180 | const T = 8; // Number of leading bits to nullify 181 | 182 | // The loop 183 | const nullify_T_bits = loop( T, i => ` 184 | DUP 185 | ${ 2 ** (N - 1 - i) } 186 | GREATERTHANOREQUAL 187 | ${ i * 2 + 1 } 188 | ADD 189 | PICK 190 | SUB 191 | `); 192 | 193 | // The loop which also drops the lookup table 194 | const nullify_T_bits_drop = loop( T, i => ` 195 | DUP 196 | ${ 2 ** (N - 1 - i) } 197 | GREATERTHANOREQUAL 198 | 1ADD 199 | ROLL 200 | SUB 201 | NIP 202 | `); 203 | 204 | 205 | [ 206 | 207 | // Push the lookup table onto the stack 208 | loop( T, i => ` 209 | ${ 2 ** (N - T + i) } 210 | 0 211 | `), 212 | 213 | // First input 214 | 0b1010110011111110, 215 | nullify_T_bits, 216 | 'TOALTSTACK', 217 | 218 | // Second input 219 | 0b1010110011111100, 220 | nullify_T_bits, 221 | 'TOALTSTACK', 222 | 223 | // Third input 224 | 0b1010110011111000, 225 | nullify_T_bits, 226 | 'TOALTSTACK', 227 | 228 | // Fourth input 229 | 0b1010110011110000, 230 | nullify_T_bits_drop, 231 | 232 | 'FROMALTSTACK', 233 | 'FROMALTSTACK', 234 | 'FROMALTSTACK', 235 | 236 | ] 237 | ``` 238 | 239 | 240 | ### Nullifying Trailing Bits 241 | 242 | ```js 243 | const N = 8; // The bit length 244 | const T = N - 6; // Number of trailing bits to nullify 245 | 246 | // The loop 247 | const nullify_T_bits = [ 248 | 'DUP', 249 | loop( T, i => ` 250 | DUP 251 | ${ 2 ** (N - 1 - i) } 252 | GREATERTHANOREQUAL 253 | ${ i * 2 + 2 } 254 | ADD 255 | PICK 256 | SUB 257 | `), 258 | 'SUB' 259 | ]; 260 | 261 | // The loop which also drops the lookup table 262 | const nullify_T_bits_drop = [ 263 | 'DUP', 264 | loop( T, i => ` 265 | DUP 266 | ${ 2 ** (N - 1 - i) } 267 | GREATERTHANOREQUAL 268 | 2 269 | ADD 270 | ROLL 271 | SUB 272 | NIP 273 | `), 274 | 'SUB' 275 | ]; 276 | 277 | 278 | [ 279 | 280 | // Push the lookup table onto the stack 281 | loop( T, i => ` 282 | ${ 2 ** (N - T + i) } 283 | 0 284 | `), 285 | 286 | // First input 287 | 0b11111110, 288 | nullify_T_bits, 289 | 'TOALTSTACK', 290 | 291 | // Second input 292 | 0b11111100, 293 | nullify_T_bits, 294 | 'TOALTSTACK', 295 | 296 | // Third input 297 | 0b11111000, 298 | nullify_T_bits, 299 | 'TOALTSTACK', 300 | 301 | // last input 302 | 0b11110000, 303 | nullify_T_bits_drop, 304 | 305 | 'FROMALTSTACK', 306 | 'FROMALTSTACK', 307 | 'FROMALTSTACK', 308 | 309 | ] 310 | ``` 311 | -------------------------------------------------------------------------------- /tic-tac-toe.md: -------------------------------------------------------------------------------- 1 | # Tic Tac Toe in a Schnorr Signature 2 | 3 | A sketch of some ideas to implement the game [Tic Tac Toe](https://en.wikipedia.org/wiki/Tic-tac-toe) in Bitcoin. This model requires only a single onchain transaction containing a single Schnorr signature. 4 | Scriptless scripts and the replace-by-fee mechanism are used to implement the full game logic. 5 | 6 | Before the game starts the tree of possible moves is scaffolded out. There are 26830 different games. Every possible move is represented by a transaction with a 2-of-2 MuSig splitting the key among both players. 7 | All of these transactions compete to spend the same output. If any transaction hits the chain it gives the bitcoins to the current player (or refunds both players in case of a draw). There are no further scripts. 8 | In the non-cooperative case older transactions are replaced by newer transactions via the replace-by-fee mechanism. 9 | 10 | 11 | 12 | Before the game starts, each player traverses the tree of game states and signs every possible move of their opponent. The player subtracts his signature by his signature of the parent transaction that leads to this particular game state. 13 | These so-called *adapter signatures* form a tree which is exchanged upfront. This ensures a player can execute a transaction exactly if the opponent executed the preceding move, that lead to that particular game situation. The set of transactions that a player can complete at a point in time represents the set of valid moves they can choose from. 14 | 15 | Note that the index of a move is actually represented by the nonce of the signature. The message is always simply one of three possibilities: "Player A takes the money", "Player B takes the money", or "Both players are refunded." 16 | 17 | The game starts once the scaffold is complete. The two players take turns revealing signatures to each other. 18 | - In the cooperative case the players send the signatures to each other privately. 19 | - In this case only a single transaction has to be broadcasted to the bitcoin network. 20 | - In the non-cooperative case players take turns replacing each others' transactions with the replace-by-fee mechanism (RBF). 21 | - There are at most 9 rounds in Tic Tac Toe. 22 | - An honest player can always update to the most recent state without going through intermediate states. 23 | - The fee of a newer transaction is always at least 1 sat/byte higher than in the preceding round. 24 | 25 | Only one last transaction hits the chain and spends the output. 26 | 27 | 28 | ## Shortcomings 29 | - The game must end before an intermediate game state hits the chain. 30 | - Using RBF as consensus mechanism is risky. This update mechanism depends on the mempool of bitcoin miners. We assume no player cooperates with a miner. 31 | - The players have to sign and exchange the whole game tree upfront, which is about 25000 signatures per game. 32 | 33 | -------------------------------------------------------------------------------- /tictactoe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coins/bitcoin-scripts/016f919c82f9e47f7eba4029eddce714ef261fee/tictactoe.png -------------------------------------------------------------------------------- /token_auction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coins/bitcoin-scripts/016f919c82f9e47f7eba4029eddce714ef261fee/token_auction.png -------------------------------------------------------------------------------- /weighted-multi-sig.md: -------------------------------------------------------------------------------- 1 | # Weighted Multi-Signature 2 | 3 | We can express a weighted n-of-m voting by duplicating keys and signatures. 4 | 5 | 6 | ## Regular Multi-Sig 7 | Regular 3-of-5 example: 8 | ``` 9 | 3 10 | 11 | 12 | 13 | 14 | 15 | 5 16 | OP_CHECKMULTISIG 17 | ``` 18 | Redeem example: 19 | ``` 20 | 21 | ``` 22 | 23 | ## Weighted Multi-Sig 3-of-5 24 | Weighted 3-of-5 with `pub_key_1` having up to two votes: 25 | ``` 26 | OP_IF 27 | OP_DUP 28 | OP_ENDIF 29 | 30 | 3 31 | 32 | OP_DUP 33 | 34 | 35 | 36 | 5 37 | OP_CHECKMULTISIG 38 | ``` 39 | 40 | Redeem example: 41 | ``` 42 | 0 43 | ``` 44 | 45 | or 46 | ``` 47 | 1 48 | ``` 49 | 50 | 51 | ## Weighted Multi-Sig 4-of-7 52 | Weighted 4-of-7 with `pub_key_1` having exactly three votes: 53 | 54 | ``` 55 | OP_DUP 56 | OP_DUP 57 | 58 | 4 59 | 60 | OP_DUP 61 | OP_DUP 62 | 63 | 64 | 65 | 7 66 | OP_CHECKMULTISIG 67 | ``` 68 | 69 | Redeem example: 70 | ``` 71 | 72 | ``` 73 | 74 | or 75 | ``` 76 | 77 | ``` 78 | 79 | 80 | # Improved Weighted MultiSig 81 | 82 | Every person of the weighted MultiSig can have an explicit weight. This scripts checks that the sum of the participants is greater than the threshold. 83 | 84 | ``` 85 | IF 86 | 87 | CHECKSIGVERIFY 88 | 89 | ELSE 90 | 0 91 | ENDIF 92 | TOALTSTACK 93 | 94 | IF 95 | 96 | CHECKSIGVERIFY 97 | 98 | ELSE 99 | 0 100 | ENDIF 101 | TOALTSTACK 102 | 103 | IF 104 | 105 | CHECKSIGVERIFY 106 | 107 | ELSE 108 | 0 109 | ENDIF 110 | TOALTSTACK 111 | 112 | ... 113 | 114 | 115 | 116 | FROMALTSTACK 117 | FROMALTSTACK 118 | FROMALTSTACK 119 | 120 | ... 121 | 122 | ADD 123 | ADD 124 | ADD 125 | 126 | GREATEREQUAL 127 | VERIFY 128 | 129 | ``` 130 | --------------------------------------------------------------------------------