
Bitvm
- 4 installs
- 4 repo stars
- Updated February 25, 2026
- hairyf/blockchain-master
Explore BitVM2: a Groth16 SNARK verifier executable on Bitcoin without soft forks, plus its trust-minimized bridge CLI and chunk API.
About
A reference for the BitVM2 optimistic paradigm covering the on-Bitcoin SNARK verifier, chunked Groth16 verification, and peg-in/peg-out bridge flows. A developer uses it to experiment with Bitcoin scripting of arithmetic, hashes, and proofs (not for production).
- Groth16 verifier via u32/u4 arithmetic, SHA256/BLAKE3, bigint, and BN254
- Bridge CLI, chunk instructions, header-chain, and final-SPV components
Bitvm by the numbers
- 4 all-time installs (skills.sh)
- Ranked #347 of 479 Web3 & Blockchain skills by installs in the Skillselion catalog
- Data as of Jul 13, 2026 (Skillselion catalog sync)
npx skills add https://github.com/hairyf/blockchain-master --skill bitvmAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 4 |
| Last updated | February 25, 2026 |
| Repository | hairyf/blockchain-master ↗ |
What it does
Explore BitVM2: a Groth16 SNARK verifier executable on Bitcoin without soft forks, plus its trust-minimized bridge CLI and chunk API.
Files
Skill based on BitVM (BitVM/BitVM), generated fromsources/bitvm. Doc path:README.md,docs/chunk_instructions.md,DEMO_INSTRUCTIONS.md,prover/README.md,header-chain/README.md,final-spv/README.md,regtest/README.md.
BitVM implements the BitVM2 optimistic paradigm: a Groth16 SNARK verifier executable on Bitcoin without soft forks, plus a trust-minimized bridge. Use for scripting u32/u4 arithmetic, hashes (SHA256, BLAKE3), bigint, BN254, chunked Groth16 verification, and peg-in/peg-out flows. Do not use in production.
Core References
| Topic | Description | Reference |
|---|---|---|
| Overview | BitVM2 paradigm, SNARK verifier, component map, capabilities | core-overview |
| Components | u32, u4, hash, bigint, BN254, Groth16, chunk, signatures, bridge | core-components |
Features
| Topic | Description | Reference |
|---|---|---|
| Bridge CLI | Keys, addresses, UTXOs, peg-in/peg-out, MuSig2, broadcast, env and config | features-bridge-cli |
| Chunk API | Tapscripts, disprove logic, DataType/ElementType, hashing, tests | features-chunk-api |
| Header chain | Risc0 header chain circuit and prover binary, data and proving | features-header-chain |
| Final SPV | Header verification, tx inclusion proof, 32-byte Blake3 digest | features-final-spv |
Best Practices
| Topic | Description | Reference |
|---|---|---|
| Demo flows | Funding UTXOs, happy peg-out, successful disprove, environment setup | best-practices-demo-flows |
Generation Info
- Source:
sources/bitvm(https://github.com/BitVM/BitVM) - Doc path:
README.md,docs/chunk_instructions.md,DEMO_INSTRUCTIONS.md,prover/README.md,header-chain/README.md,final-spv/README.md,regtest/README.md - Git SHA:
7d1ca3660cac08aab62e76f3aa4daec0d7403ecc - Generated: 2026-02-24
Demo Flows and Environment
Practical sequences for testing peg-in, peg-out, and disprove without production use. Use get-funding-amounts for current minimum sats; values below are illustrative.
Funding UTXOs (Demo Prep)
Three funding UTXOs (prepare once for all demos):
1. Peg-in deposit: ~2,097,447 sats — spendable by depositor (get-depositor-address, keys with -d). 2. Peg-out confirm: ~3,607,030 sats — spendable by operator (get-operator-address, -o). 3. Withdrawer peg-out: ~2,097,274 sats — spendable by operator.
Happy Path (Rejected Disprove)
Operator asserts correctly; verifier's disprove should fail.
1. Depositor: initiate-peg-in -n -u <TXID>:<VOUT> -d <EVM_ADDRESS> (UTXO #1). 2. Operator: create-peg-out -t -u <TXID>:<VOUT> -i <PEG_IN_GRAPH_ID> (UTXO #2). 3. Verifiers: push-nonces -c -i <GRAPH_ID> then push-signatures -g -i <GRAPH_ID> for peg-in and peg-out graphs. 4. Any: broadcast pegin -g <PEG_IN_GRAPH_ID> confirm; record peg-in confirm txid. 5. Operator: In interactive mode, mock-l2-pegout-event -x -u <PEG_IN_CONFIRM_TXID>:0. 6. Operator: broadcast tx -g <GRAPH_ID> -u <TXID>:<VOUT> peg_out (UTXO #3), then peg_out_confirm, kick_off_1, kick_off_2, assert_initial, assert_commit_1, assert_commit_2, assert_final. 7. Verifier: broadcast tx -g <GRAPH_ID> -a <BTC_ADDRESS> disprove (should fail). 8. Operator: broadcast tx -g <GRAPH_ID> take_2.
Successful Disprove Path
Operator commits invalid proof; verifier disproves and gets reward.
Same as happy path through kick-off and assert_initial; then:
- Use invalid assert commits:
assert_commit_1_invalid,assert_commit_2_invalid, thenassert_final. - Verifier:
broadcast tx -g <GRAPH_ID> -a <BTC_ADDRESS> disprove(succeeds).
No take_2; operator loses the challenge.
Environment Setup
- bridge.toml: In
~/.bitvm-bridge/(orKEY_DIR), with[keys]:depositor,operator,verifier,withdrawer,verifying_key. - .env: Same directory as CLI (e.g. repo root). Set
BRIDGE_DATA_STORE_CLIENT_DATA_SUFFIX, AWS vars if used, andVERIFIERS(comma-separated verifier pubkeys). For a second verifier instance use a different dir andKEY_DIR/separatebridge.tomlso keys and data don't mix.
Use testnet/regtest and demo funding amounts only; do not use mainnet or production keys.
<!-- Source references:
- sources/bitvm/DEMO_INSTRUCTIONS.md
- sources/bitvm/README.md
-->
BitVM Core Components
Reusable Bitcoin script building blocks under bitvm/src/. Use these when generating or reasoning about Taproot scripts for arithmetic, hashing, and curve operations.
u32 and u4
- u32 (
bitvm/src/u32/): 32-bit operations for hash functions—add, sub, or, xor, rotation, shift. Entry for SHA256 and other word-based hashes. - u4 (
bitvm/src/u4/): 4-bit arithmetic; more script-efficient for constructing hashes (e.g. BLAKE3 in chunker).
Hash Functions
- SHA256: Block header comparison and Bitcoin difficulty checks.
- BLAKE3: Compressing intermediate states in the chunker; used with u4 for smaller scripts.
Big Integer
- bigint (
bitvm/src/bigint/): Variable-length big integers—add, sub, mul, div, inverse. Used for field and scalar arithmetic in curve operations.
BN254
- bn254 (
bitvm/src/bn254/): BN254 elliptic curve in script. - Field chain: Fq, Fr, Fq2, Fq6, Fq12.
- G1/G2 point ops, MSM, line evaluations.
- Pairing per "On Proving Pairings" (Algorithm 9).
Groth16
- groth16 (
bitvm/src/groth16/): Groth16 verifier over BN254. Script size ~1 GB; uses precomputed hints. Offchain checker and verifier entry points.
Chunk
- chunk (
bitvm/src/chunk/): Splits the Groth16 verifier into chunks so that: (1) no chunk succeeds on a valid proof alone, and (2) some chunks succeed when the proof is invalid (enabling disprove). Subdirs:api,api_compiletime_utils,api_runtime_utils,elements,g16_runner_core,g16_runner_utils, tapscripts for MSM/mul/point_ops,wrap_hasher,wrap_wots.
Signatures
- signatures (
bitvm/src/signatures/): Bit commitment using Winternitz (Lamport-style) short keys/signatures.
Bridge
- bridge (
bridge/): Context (roles), connectors, Bitcoin transaction construction, and client wrapper—used by the CLI for peg-in/peg-out and assert/disprove flows.
<!-- Source references:
- sources/bitvm/README.md
- bitvm/src/{u32,u4,hash,bigint,bn254,groth16,chunk,signatures}
-->
BitVM Overview
BitVM is the official implementation of BitVM2: an optimistic paradigm to run a Groth16 SNARK verifier on Bitcoin without soft forks. The codebase follows Arkworks and implements a trust-minimized Bitcoin bridge.
Warning: Do not use in production.
Capabilities
- Groth16 on Bitcoin: Verify ZK proofs (BN254, Groth16) via Bitcoin script in an optimistic challenge game.
- Modular Bitcoin scripts: Reusable Taproot scripts for u32/u4 arithmetic, hashes (SHA256, BLAKE3), big integers, and BN254 curve operations.
- Bridge CLI: Manage keys (depositor, operator, verifier, withdrawer), peg-in/peg-out flows, MuSig2 signing, and broadcast of assert/disprove transactions.
- Chunked verifier: Groth16 verifier split into chunks with deterministic I/O; verifiers can disprove invalid operator assertions.
- Header chain & SPV: Risc0-based header chain prover and final-SPV circuit for proving tx inclusion and compressing public values (Blake3).
Component Map
| Component | Path | Purpose |
|---|---|---|
| u32 | bitvm/src/u32/ | add, sub, or, xor, rotation, shift for hashes |
| u4 | bitvm/src/u4/ | 4-bit arithmetic (efficient hash construction) |
| hash | bitvm/src/hash/ | SHA256 (headers, difficulty), BLAKE3 (chunker state) |
| bigint | bitvm/src/bigint/ | Variable-length add, sub, mul, div, inverse |
| bn254 | bitvm/src/bn254/ | Fq/Fr/Fq2/Fq6/Fq12, G1/G2, pairing (Algorithm 9) |
| groth16 | bitvm/src/groth16/ | Verifier (~1 GB script), precomputed hints |
| chunk | bitvm/src/chunk/ | Chunking, tapscripts (MSM, mul, point ops), disprove API |
| signatures | bitvm/src/signatures/ | Bit commitment via Winternitz |
| bridge | bridge/ | Roles, connectors, tx construction, Bitcoin client |
BitVM1
Deprecated BitVM1 lives on branch 1dce989d1963b90c35391b77b451c6823302d503; this skill covers BitVM2 only.
<!-- Source references:
- sources/bitvm/README.md
- https://bitvm.org/bitvm2
- https://bitvm.org/snark
-->
BitVM Bridge CLI
The BitVM CLI (bridge binary) manages Bitcoin keys, peg-ins, peg-outs, and assert/disprove transaction flow. Supports mainnet, testnet, and regtest.
Invocation
./target/release/bridge [OPTIONS] <SUBCOMMAND>Build: cargo build --release; run from repo root or with cargo run --bin bridge --.
Global Options
-r, --verifiers <VERIFIER_PUBKEYS>: Comma-separated verifier public keys (max 1000). Or setVERIFIERSenv.-e, --environment <ENVIRONMENT>:mainnet\|testnet\|regtest. Default: testnet. OrENVIRONMENT.--key-dir <DIRECTORY>: Directory for private keys. OrKEY_DIR.-p, --user-profile <USER_PROFILE>: User namespace (e.g.operator_one,verifier_0) for local client data. OrUSER_PROFILE.
Key and Address Commands
# Manage keys (depositor, operator, verifier, withdrawer, vk)
bridge keys -d <SECRET_KEY> -o <SECRET_KEY> -v <SECRET_KEY> -w <SECRET_KEY> -k <VK>
# Minimum funding amounts (testing)
bridge get-funding-amounts
# Operator / depositor addresses and UTXOs
bridge get-operator-address
bridge get-operator-utxos
bridge get-depositor-address
bridge get-depositor-utxosPeg-In and Peg-Out
# [DEPOSITOR] Start peg-in (UTXO = TXID:VOUT, spendable by depositor)
bridge initiate-peg-in -n -u <TXID>:<VOUT> -d <EVM_ADDRESS>
# [OPERATOR] Create peg-out graph from peg-in graph id
bridge create-peg-out -t -u <TXID>:<VOUT> -i <PEG_IN_GRAPH_ID>
# MuSig2: push nonces then signatures for a graph
bridge push-nonces --id <GRAPH_ID>
bridge push-signatures --id <GRAPH_ID>Broadcast Subcommands
bridge broadcast [COMMAND] [OPTIONS]
# Examples:
bridge broadcast pegin -g <PEG_IN_GRAPH_ID> confirm
bridge broadcast tx -g <GRAPH_ID> -u <TXID>:<VOUT> peg_out
bridge broadcast tx -g <GRAPH_ID> peg_out_confirm
bridge broadcast tx -g <GRAPH_ID> kick_off_1
bridge broadcast tx -g <GRAPH_ID> kick_off_2
bridge broadcast tx -g <GRAPH_ID> assert_initial
bridge broadcast tx -g <GRAPH_ID> assert_commit_1
bridge broadcast tx -g <GRAPH_ID> assert_commit_2
bridge broadcast tx -g <GRAPH_ID> assert_final
bridge broadcast tx -g <GRAPH_ID> -a <BTC_ADDRESS> disprove
bridge broadcast tx -g <GRAPH_ID> take_2For invalid-assert demos: assert_commit_1_invalid, assert_commit_2_invalid.
Other Commands
# Mock L2 peg-out (testing only)
bridge mock-l2-pegout-event -x -u <TXID>:<VOUT>
# Poll and handle tx automatically
bridge automatic
# Interactive prompt
bridge interactive
# Current client status
bridge statusConfiguration
- Keys:
bridge.tomlin key directory (default~/.bitvm-bridge/). Sections:[keys]withdepositor,operator,verifier,withdrawer,verifying_key. - Env:
KEY_DIR,VERIFIERS,ENVIRONMENT,USER_PROFILE. AWS:BRIDGE_AWS_ACCESS_KEY_ID,BRIDGE_AWS_SECRET_ACCESS_KEY,BRIDGE_AWS_REGION,BRIDGE_AWS_BUCKET. Data suffix:BRIDGE_DATA_STORE_CLIENT_DATA_SUFFIX. FTP/SFTP/FTPS:BRIDGE_SFTP_*,BRIDGE_FTP_*,BRIDGE_FTPS_*, with*_BASE_PATHdefault/bitvm.
<!-- Source references:
- sources/bitvm/README.md (BitVM CLI section)
-->
Chunk API and Tapscripts
The chunk layer splits the Groth16 verifier into executable Taproot scripts with defined inputs/outputs. Verifiers validate assertions and can disprove invalid operator claims.
API Layout
- api: Interface between verifier and external modules (e.g. bridge).
- api_compiletime_utils: Presigning and compile-time interfacing.
- api_runtime_utils: Assertion and disprove at runtime.
- elements: Data structures for chunk inputs/outputs.
- g16_runner_core: Execute chunked Groth16 verifier and collect results.
- g16_runner_utils: Tapscript wrappers used by g16_runner_core.
- wrap_hasher: BLAKE3 u4 hasher wrapper. wrap_wots: Winternitz wrapper.
Data Types
Runtime chunk I/O:
pub enum DataType {
Fp6Data(ark_bn254::Fq6), // Fp12 second coeff: a in (1 + a*J)
G2EvalData(ElemG2Eval), // G2 accumulator + line eval + partial mul
G1Data(ark_bn254::G1Affine),
U256Data(ark_ff::BigInt<4>), // 256-bit field/curve inputs
}Element role (for Merkle commitment representation):
pub(crate) enum ElementType {
Fp6, G2EvalPoint, G2EvalMul, G2Eval, FieldElem, ScalarElem, G1,
}G2EvalPoint = input to step_1 (only T4); G2EvalMul = input to step_2 (all but T4); G2Eval = base output of both tapscripts.
Fp12 Multiplication in Tapscripts
Dense-dense mul: for f = 1 + c*J, g = 1 + d*J verify h = f*g as e == (c+d)/(1+c*d*V) (with hint c). Three-element mul (1+a*J)(1+b*J)(1+d*J) is done in two segments (partial then final), used in point-op line evaluation chunks.
Point Ops and Line Evaluations
Two fragments:
1. chunk_point_ops_and_multiply_line_evals_step_1: T4 += Q4; compute le_4, le_3, le_2; output partial mul (a+b), (1+ab*V) plus updated T4 and le_2. 2. chunk_point_ops_and_multiply_line_evals_step_2: Completes lev = le_2*le_3*le_4; checks e*[(1+ab*V)+(a+b)*d*V] ?= (a+b)+d*(1+ab*V); output lev.
Merkle Bitcommitments
To avoid two bitcommitments per step_1, A (= T4) and B (= a+b, ab, le_2) are Merkle leaves; root is committed. Each tapscript receives one preimage and the sibling hash as hint to recompute root.
Disprove Logic (Pseudocode)
fn disprove_core(input, Option<output>, operator_claimed_input_hash, operator_claimed_output_hash) {
let input_is_valid = input.is_valid();
if input_is_valid {
output = output.or_else(|| fn(input)); fn_valid(input, output);
} else {
push mock_output;
}
assert(Hash_fn(input), operator_claimed_input_hash);
can_disprove = !input_is_valid || Hash_fn(output) != operator_claimed_output_hash;
}Stack: [input, output, input_is_valid]; altstack: claimed hashes. Verifier wins if can_disprove is true.
Hashing
blake3_u4 hasher: message on stack only; use main/alt stack for preimages vs hashes. blake3compiled::hash_messages() adds hashing layer: check Hash(input)==claimed_input_hash and, when input valid, Hash(output)!=claimed_output_hash.
Security and Tests
- 20-byte hashes for 160-bit second-preimage resistance (collision resistance not required in BitVM).
- Full E2E:
cargo test --package bitvm --lib -- chunk::api::test::full_e2e_execution --exact --nocapture. - Step-wise: compile partial scripts, generate signed assertions, validate, then corrupt assertions and run disprove test (
test_fn_compile,test_fn_generate_signatures,test_fn_validate_assertions,test_fn_disprove_invalid_assertionswith--ignored).
<!-- Source references:
- sources/bitvm/docs/chunk_instructions.md
- sources/bitvm/bitvm/src/chunk/
-->
Final SPV Circuit
The final-spv library verifies the Bitcoin header chain, proves inclusion of a transaction in that chain, and compresses the public values to 32 bytes using Blake3. Built with Risc0.
Prerequisites
- Risc0 toolchain installed.
Building
From repository root:
REPR_GUEST_BUILD=1 BITCOIN_NETWORK=<NETWORK> cargo build -p final-spv-circuit --releaseOutput ELF: prover/elfs/<NETWORK>-final-spv-guest.
Role
- Input: Header chain (or its proof) and a Bitcoin transaction.
- Output: A single 32-byte digest (Blake3) that commits to the verified chain and the inclusion claim.
Use this digest downstream (e.g. in contracts or other proofs) instead of passing full chain or inclusion data. Ensure BITCOIN_NETWORK matches the header chain and prover build.
<!-- Source references:
- sources/bitvm/final-spv/README.md
-->
Header Chain (Prover and Library)
BitVM uses Risc0 to prove the Bitcoin header chain. The header-chain library builds the circuit; the prover binary produces proofs over batches of headers.
Prerequisites
- Risc0 toolchain installed.
- For building ELFs: run from repo root with
REPR_GUEST_BUILD=1andBITCOIN_NETWORK=<NETWORK>.
Building the Header Chain Circuit
REPR_GUEST_BUILD=1 BITCOIN_NETWORK=<NETWORK> cargo build -p header-chain-circuit --releaseELF path: prover/elfs/<NETWORK>-header-chain-guest.
Building the Prover
BITCOIN_NETWORK=<NETWORK> cargo build -p prover --releaseData
Download Bitcoin headers and place as prover/data/mainnet-headers.bin (e.g. from zerosync):
cd prover/data
wget https://zerosync.org/chaindata/headers.bin -O mainnet-headers.bin
cd ../..Proving
./target/release/prover <PREV_PROOF_PATH> <OUTPUT_PROOF_PATH> <NUM_HEADERS>- First run (from genesis): use
Noneas previous proof path. - Later runs: pass the previous proof file to verify and extend.
Examples:
# Prove first 10 headers
./target/release/prover None prover/data/first_10.bin 10
# Prove next 90 headers (verifies first_10.bin)
./target/release/prover prover/data/first_10.bin prover/data/first_100.bin 90Use the same <NETWORK> as in the build for consistency.
<!-- Source references:
- sources/bitvm/prover/README.md
- sources/bitvm/header-chain/README.md
-->