QBTC is a Cosmos SDK application chain that runs on a forked CometBFT consensus engine using post-quantum signatures. It maintains a mirror of the Bitcoin UTXO set inside its own state and accepts zero-knowledge proofs of BTC ownership as claims against that mirror. For deeper specifications, see the Protocol Specification.Documentation Index
Fetch the complete documentation index at: https://docs.qbtc.net/llms.txt
Use this file to discover all available pages before exploring further.
High-level picture
The four major components
1. The chain daemon (qbtcd)
qbtcd is a Cosmos SDK v0.52-era application binary. It registers the standard SDK modules (auth, bank, staking, slashing, distribution, gov, upgrade, evidence, feegrant, authz, consensus, params, epochs, group, IBC v10, ICS-27 interchain accounts, IBC transfer, CosmWasm, and tokenfactory) and adds one custom module: x/qbtc.
Notable chain parameters:
- Bech32 prefixes:
qbtc(accounts),qbtcvaloper(validators),qbtcvalcons(consensus). - Default bond denom:
qbtc. - Coin type: 118 (standard Cosmos).
2. The post-quantum consensus engine (CometBFT, forked)
QBTC depends on a fork of CometBFT that introduces a newcrypto/mldsa package and routes consensus signing through ML-DSA (CRYSTALS-Dilithium / FIPS 204) instead of Ed25519.
Every validator’s consensus key is an ML-DSA key, every vote is signed with ML-DSA, every block-commit signature is ML-DSA. No wrapper or sidecar layer. The fork is maintained at github.com/btcq-org/cometbft.
ML-DSA-65 signatures are larger than Ed25519 (3309 bytes vs. 64 bytes per FIPS 204), which affects block size and bandwidth. The trade-off is intentional: a chain that exists to be quantum-safe cannot have any ECDSA or Ed25519 dependency in its consensus path.
See Quantum Resistance (ML-DSA) for details.
3. The custom module (x/qbtc)
The single custom module handles everything QBTC-specific:
| Subfolder | Responsibility |
|---|---|
keeper/ | State management and message handlers for claims and UTXO mirror |
types/ | Protobuf-generated types and message validation |
module/ | Cosmos module wiring and genesis state loader |
zk/ | PLONK circuits and the on-chain verifier for claim proofs |
ebifrost/ | ”Enshrined bifrost” — in-chain logic that accepts gossiped Bitcoin blocks from validator sidecars and injects them as special transactions |
4. The validator sidecar (bifrost)
Each validator runs a bifrost process alongside qbtcd. Its job is narrow:
- Connect to a Bitcoin full node via RPC and watch for new blocks.
- When a new BTC block arrives, gzip it and sign it with the validator’s QBTC consensus key (ML-DSA).
- Gossip the signed block to peer validators’
bifrostprocesses via LibP2P.
x/qbtc/ebifrost module receives these signed blocks via gRPC and includes them in QBTC blocks as injected transactions. A Bitcoin block is only considered ingested once more than 2/3 of bonded validator power has attested to it.
QBTC’s view of Bitcoin is itself produced by a Byzantine-fault-tolerant consensus, not by a single oracle or trusted relayer.
5. The proof service (proof-service)
ZK proof generation runs client-side. Wallets handle it natively. On constrained devices, the proof-service is a standalone HTTP service that takes user-constructed proof inputs and computes the cryptographic output.
Anyone can host a proof-service instance. Multiple independent operators will run them. Users (or their wallet) pick by trust, latency, or convenience. The proof service does not see private key material in a form that lets it forge claims; the witness is constructed locally on the user’s side.
A CLI version (zkprover) is available for users who want to generate proofs locally.
Binaries shipped
| Binary | Purpose |
|---|---|
qbtcd | Chain daemon (validators and full nodes run this) |
bifrost | BTC block watcher and gossiper (every validator runs one) |
proof-service | Remote PLONK prover (optional infrastructure, anyone can host) |
zkprover | CLI for local proof generation |
utxo-indexer | Builds the genesis UTXO snapshot from a Bitcoin node |
The data flow for a single claim
- User decides to claim their BTC at address
1A1z...to a QBTC addressqbtc1.... - User opens a quantum-safe wallet, which constructs the proof inputs locally: the BTC private key, the destination QBTC address, and the UTXO reference.
- The wallet either generates the ZK proof locally (
zkprover) or sends the proof inputs to aproof-serviceinstance. - The completed proof is submitted to QBTC as a
MsgClaimWithProoftransaction. A single transaction can claim up to 50 UTXOs at once. - A QBTC validator picks up the transaction, runs the on-chain PLONK verifier, checks each referenced UTXO has an outstanding claim, and checks the destination address is valid.
- The transaction lands in a block. The claim is released to the destination QBTC address and the corresponding entry is marked as exhausted, preventing double-claims.
How Bitcoin’s state stays mirrored
- Bitcoin produces a block.
- Each validator’s
bifrostreads the block from its Bitcoin node. - Each
bifrostgzips the block, signs it with the validator’s ML-DSA consensus key, and gossips it. - The QBTC
ebifrostmodule aggregates signatures. When more than 2/3 of bonded validator power has attested to the same block, it is accepted. - The accepted block is injected as a special transaction in the next QBTC block. The transaction updates the UTXO mirror: new outputs become claims, spent outputs are reconciled.
- Coinbase outputs add new claim entries. Bitcoin miners receive a corresponding QBTC claim as well.