TeachMeBitcoin

Puzzle Scripts - Hash Collision Bounties

From TeachMeBitcoin, the free encyclopedia Reading time: 2 min

14. Puzzle Scripts — Hash Collision Bounties

Overview

Bitcoin's scripting language supports hash opcodes (OP_SHA1, OP_SHA256, OP_HASH160, OP_HASH256) that enable puzzle-style outputs: funds locked by the requirement to find a pre-image or collision of a hash function. These have been used to fund real cryptographic research incentives on-chain.

Pre-image Puzzle Scripts

A pre-image puzzle locks funds to whoever can find the input to a known hash output:

Locking script (SHA256 puzzle):
OP_SHA256 <known_hash> OP_EQUAL

Unlocking script:
<preimage>   <- any data x such that SHA256(x) == known_hash

Execution:

Stack: []

OP_SHA256: Stack → [SHA256(<preimage>)]
PUSH <known_hash>: Stack → [SHA256(<preimage>), <known_hash>]
OP_EQUAL: checks equality → [1] if match

SHA1 Collision Bounty

Peter Todd created a famous SHA1 collision bounty in 2013 that used Bitcoin's opcodes to lock 2.48 BTC to a script requiring a SHA1 collision:

Locking script:
OP_2DUP OP_EQUAL OP_NOT OP_VERIFY
OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL

Unlocking script to claim:
<x> <y>   <- two DIFFERENT values with the same SHA1 hash

Execution trace:

Initial stack: [<x>, <y>]

OP_2DUP:    [<x>, <y>, <x>, <y>]
OP_EQUAL:   [<x>, <y>, (x==y)]
OP_NOT:     [<x>, <y>, (x!=y)]   ← ensures x ≠ y
OP_VERIFY:  [<x>, <y>]           ← fails if x == y
OP_SHA1:    [<x>, SHA1(<y>)]
OP_SWAP:    [SHA1(<y>), <x>]
OP_SHA1:    [SHA1(<y>), SHA1(<x>)]
OP_EQUAL:   [SHA1(x) == SHA1(y)] ← TRUE if collision found

The bounty was claimed on February 23, 2017, when Google's SHAttered attack produced a SHA1 collision. The claiming transaction can be found at:

TXID: 8d31992805518fd62daa3bdd2a5c4fd2cd3054c9b3dca1d78055e9528cff6adb
Block: 455,702
Amount: 2.48 BTC claimed

Hash-Locked Contracts (HTLCs)

Hash Time-Locked Contracts are a generalized form of puzzle script used in the Lightning Network and atomic swaps:

HTLC script:
OP_IF
    OP_SHA256 <payment_hash> OP_EQUALVERIFY
    <receiver_pubkey> OP_CHECKSIG
OP_ELSE
    <timeout> OP_CHECKLOCKTIMEVERIFY OP_DROP
    <sender_pubkey> OP_CHECKSIG
OP_ENDIF

Spending via hash preimage (success path):
  Witness: <sig> <preimage> OP_1

Spending via timeout (refund path):
  Witness: <sig> OP_0
☕ Help support TeachMeBitcoin

TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation:

Ethereum: 0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin: bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana: 4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J
Address copied to clipboard!