Purpose
The circuit serves as a cryptographic light client for Bitcoin, enabling:- Chain Continuity Verification: Ensures each block correctly references its predecessor
- Proof-of-Work Validation: Verifies block hashes meet difficulty requirements
- Difficulty Adjustment: Validates Bitcoin’s 2016-block retargeting mechanism
- Accumulative Work Tracking: Maintains total accumulated proof-of-work for chain selection
- Recursive Proving: Enables verification of arbitrarily long chains through proof composition
Core Verification Logic
The circuit performs comprehensive validation for each block header in the input sequence:1. Method ID Consistency
2. Chain Continuity
prev_block_hash field matches the hash of the previous block, ensuring no chain breaks.
3. Proof-of-Work Validation
- Computes the double SHA-256 hash of the block header
- Converts the hash to a 256-bit integer (little-endian to big-endian)
- Verifies the hash is less than or equal to the difficulty target
Technical: Block Hash Calculation
Technical: Block Hash Calculation
4. Difficulty Adjustment
Bitcoin adjusts difficulty every 2016 blocks to maintain ~10 minute block times:- Calculate actual timespan:
last_block_time - epoch_start_time - Clamp to [expected/4, expected*4] to limit adjustment range
- New target = old target × actual_timespan / expected_timespan
- Ensure new target doesn’t exceed network maximum
Network-Specific Difficulty Rules
Network-Specific Difficulty Rules
Mainnet
- Standard 2-week adjustment (1,209,600 seconds)
- Maximum target:
0x1D00FFFF - Adjustment range: ±75% per period
- Standard rules plus emergency difficulty reduction
- If block time > 20 minutes after previous block, maximum difficulty allowed
- Prevents network stalls during low hash rate periods
- Custom 10-second block time
- Adjusted epoch timespan: 20,160 seconds
- Maximum target:
0x1E0377AE
- Always uses maximum difficulty:
0x207FFFFF - No difficulty adjustments
- For local testing only
5. Timestamp Validation
- Block timestamp must be strictly greater than the median of the previous 11 blocks
- Prevents miners from manipulating timestamps to affect difficulty
- The median is calculated by sorting the 11 timestamps and selecting the 6th value
6. MMR Integrity
- Stores only subroots instead of all block hashes
- Enables compact inclusion proofs for any historical block
- Used by Bridge Circuit for SPV verification
Merkle Mountain Range (MMR)
The circuit uses two MMR implementations for different contexts:MMR Guest (zkVM)
circuits-lib/src/header_chain/mmr_guest.rs
Designed for constrained zkVM environment:
- Efficiently verifies inclusion proofs without storing entire chain
- Confirms a block hash is part of the verified chain
- Optimized for proof generation inside zero-knowledge circuits
MMR Native (Host)
circuits-lib/src/header_chain/mmr_native.rs
Used for off-chain data preparation:
- Builds MMR from sequences of block headers
- Generates inclusion proofs for specific blocks
- Proofs are passed to MMRGuest for verification in zkVM
Technical: MMR Structure
Technical: MMR Structure
A Merkle Mountain Range is a binary tree-like structure optimized for append-only operations:
- Each number represents a subroot
- Only the peaks (rightmost nodes at each height) need to be stored
- New blocks are appended efficiently without rebuilding the entire tree
- Inclusion proofs consist of the path from leaf to a peak
Chain State
The circuit maintains aChainState struct with all data needed for the next block verification:
block_height: Current chain height (u32::MAX for uninitialized)total_work: Cumulative proof-of-work as 256-bit big-endian integerbest_block_hash: Hash of most recently validated blockcurrent_target_bits: Current difficulty in compact representationepoch_start_time: Timestamp of first block in current difficulty epochprev_11_timestamps: Rolling array of previous 11 block timestamps for MTP validationblock_hashes_mmr: Merkle Mountain Range of all verified block hashes
Work Calculation
Accumulated work quantifies the computational effort required to produce the chain:work = 2^256 / (target + 1)
Using mathematical identity: 2^256 / (x + 1) == ~x / (x + 1) + 1
Lower targets (higher difficulty) produce more work per block.
Recursive Proving
The circuit supports recursive verification for arbitrary chain lengths:
This enables verification of millions of blocks without proving all blocks in a single circuit execution.
Circuit Input/Output
Input Structure
Output Structure
Key Implementation Files
RISC Zero Guest
risc0-circuits/header-chain/guest/src/main.rs
Core Circuit Logic
circuits-lib/src/header_chain/mod.rs
The main verification function at mod.rs:69-95:
- Reads input from host (line 71)
- Verifies previous proof or initializes from genesis (lines 73-84)
- Applies block headers to chain state (line 87)
- Commits output (lines 90-94)
apply_block_headers method at mod.rs:403-510 performs all validation logic for each header.
Build Configuration
risc0-circuits/header-chain/build.rs
The build script:
- Compiles
header-chain-guestinto RISC Zero ELF binary - Computes unique method ID for the compiled program
- Handles
BITCOIN_NETWORKenvironment variable - Optionally uses Docker for reproducible guest builds
- Copies generated ELF to
elfsfolder
Network Constants
The circuit adapts verification rules based on the Bitcoin network:Usage in Bridge Circuit
The Bridge Circuit consumes Header Chain Proofs to:- Verify the Operator is following the canonical Bitcoin chain
- Extract the MMR for SPV proof verification
- Compare Operator’s
total_workagainst Watchtower challenges - Ensure payout blocks are part of the verified chain
Next Steps
Work Only Circuit
Learn how proof-of-work is extracted for challenges
Bridge Circuit
See how header chain proofs enable secure peg-outs