bankai_verify/
lib.rs

1//! Bankai Verify - Trustless Verification Library
2//!
3//! # Overview
4//!
5//! This library provides trustless verification of blockchain data using Bankai Block proofs.
6//! It works in tandem with the `bankai-sdk` crate, which fetches proofs that this library verifies.
7//!
8//! **Once data is verified through this library, it is cryptographically guaranteed to be valid.
9//! No further checks are needed.** This guarantee is provided by Bankai's stateless light client
10//! architecture, which uses zero-knowledge proofs to establish an unbreakable chain of trust from
11//! the STWO proof down to individual blockchain data elements.
12//!
13//! ## How Verification Works
14//!
15//! The verification process follows a hierarchical trust chain:
16//!
17//! 1. **Verify STWO Block Proof**: First, verify the STWO zero-knowledge proof to establish
18//!    trust in the MMR roots it contains. This proof is cryptographically sound and cannot be forged.
19//! 2. **Verify MMR Proofs**: Use the trusted MMR roots to verify individual header commitments
20//!    through MMR inclusion proofs. Headers are guaranteed to be in the MMR.
21//! 3. **Verify Chain Data**: Once headers are verified, use standard Merkle proofs to verify
22//!    accounts, transactions, and other chain data against the header roots. This establishes
23//!    that the data existed in that specific block.
24//!
25//! ## Stateless Light Client Architecture
26//!
27//! Bankai's architecture enables **stateless verification**: you don't need to maintain any state,
28//! sync any chains, or trust any intermediaries. Each proof bundle is completely self-contained
29//! and can be verified independently. This makes it perfect for:
30//!
31//! - Cross-chain bridges that need to verify data from other chains
32//! - Smart contracts that need trustless access to historical blockchain data
33//! - Applications that need blockchain data without running full nodes
34//! - Zero-knowledge circuits that need verified inputs
35//!
36
37//! ## Usage
38//!
39//! ### Batch Verification (Recommended)
40//!
41//! The simplest way to verify proofs is using the batch verification function:
42//!
43//! ```no_run
44//! use bankai_verify::verify_batch_proof;
45//! use bankai_types::fetch::ProofWrapper;
46//!
47//! # fn example(proof_wrapper: ProofWrapper) -> Result<(), Box<dyn std::error::Error>> {
48//! // Verify an entire batch of proofs at once
49//! let results = verify_batch_proof(proof_wrapper)?;
50//!
51//! // Access verified data
52//! for header in &results.evm.execution_header {
53//!     println!("Verified execution header at block {}", header.number);
54//! }
55//!
56//! for account in &results.evm.account {
57//!     println!("Verified account with balance: {}", account.balance);
58//! }
59//! # Ok(())
60//! # }
61//! ```
62//!
63//! ### Verify Block Proof Only
64//!
65//! If you only need the verified Bankai block (with MMR roots), you can verify just the STWO proof:
66//!
67//! ```no_run
68//! use bankai_verify::bankai::stwo::verify_stwo_proof;
69//! use cairo_air::CairoProof;
70//! use stwo::core::vcs::blake2_merkle::Blake2sMerkleHasher;
71//!
72//! # fn example(block_proof: CairoProof<Blake2sMerkleHasher>) -> Result<(), Box<dyn std::error::Error>> {
73//! // Verify the STWO proof and extract the Bankai block
74//! let bankai_block = verify_stwo_proof(&block_proof)?;
75//!
76//! // Access the verified MMR roots
77//! println!("Execution MMR root (Keccak): {:?}", bankai_block.execution.mmr_root_keccak);
78//! println!("Beacon MMR root (Keccak): {:?}", bankai_block.beacon.mmr_root_keccak);
79//! println!("Block number: {}", bankai_block.block_number);
80//! # Ok(())
81//! # }
82//! ```
83//!
84//! ### Verify MMR Proofs
85//!
86//! Once you have verified MMR roots from a Bankai block, you can verify MMR inclusion proofs:
87//!
88//! ```no_run
89//! use bankai_verify::bankai::mmr::verify_mmr_proof;
90//! use bankai_types::proofs::{MmrProofDto, HashingFunctionDto};
91//! use alloy_primitives::FixedBytes;
92//!
93//! # fn example(
94//! #     mmr_proof: MmrProofDto,
95//! #     trusted_mmr_root: FixedBytes<32>
96//! # ) -> Result<(), Box<dyn std::error::Error>> {
97//! // Verify that a header is committed in the MMR
98//! let header_hash = verify_mmr_proof(&mmr_proof, trusted_mmr_root)?;
99//!
100//! println!("Verified header hash: {:?}", header_hash);
101//! # Ok(())
102//! # }
103//! ```
104//!
105//! ### Verify Header Proofs
106//!
107//! With a verified MMR root, you can verify individual header proofs:
108//!
109//! ```no_run
110//! use bankai_verify::evm::{ExecutionVerifier, BeaconVerifier};
111//! use bankai_types::fetch::evm::execution::ExecutionHeaderProof;
112//! use alloy_primitives::FixedBytes;
113//!
114//! # fn example(
115//! #     proof: ExecutionHeaderProof,
116//! #     mmr_root: FixedBytes<32>
117//! # ) -> Result<(), Box<dyn std::error::Error>> {
118//! // Verify an execution header against a trusted MMR root
119//! let verified_header = ExecutionVerifier::verify_header_proof(&proof, mmr_root)?;
120//! println!("Header number: {}", verified_header.number);
121//! println!("State root: {:?}", verified_header.state_root);
122//!
123//! // Now you can verify accounts against this header's state root
124//! # Ok(())
125//! # }
126//! ```
127//!
128//! ### Verify Account and Transaction Proofs
129//!
130//! Once you have a verified header, you can verify account and transaction proofs against it:
131//!
132//! ```no_run
133//! use bankai_verify::evm::ExecutionVerifier;
134//! use bankai_types::fetch::evm::execution::{AccountProof, TxProof};
135//! use alloy_rpc_types_eth::Header;
136//!
137//! # fn example(
138//! #     account_proof: AccountProof,
139//! #     tx_proof: TxProof,
140//! #     verified_header: Header
141//! # ) -> Result<(), Box<dyn std::error::Error>> {
142//! // Verify an account exists in the header's state
143//! let account = ExecutionVerifier::verify_account_proof(&account_proof, &verified_header)?;
144//! println!("Account balance: {}", account.balance);
145//!
146//! // Verify a transaction is included in the block
147//! let transaction = ExecutionVerifier::verify_tx_proof(&tx_proof, &verified_header)?;
148//! println!("Transaction hash: {:?}", transaction.hash);
149//! # Ok(())
150//! # }
151//! ```
152//!
153//! ## Features
154//!
155//! - **STWO Proof Verification**: Verifies zero-knowledge proofs generated by the STWO prover
156//! - **MMR Proof Verification**: Verifies Merkle Mountain Range inclusion proofs
157//! - **EVM Data Verification**: Verifies execution headers, beacon headers, accounts, and transactions
158//! - **Batch Operations**: Efficiently verify multiple proofs in a single operation
159//! - **No-Std Ready**: Can be compiled for no-std environments (SP1 compatibility planned)
160
161// TODO: Enable for SP1 once async/await is resolved
162// #![no_std]
163// extern crate alloc;
164
165// Keep batch module private
166mod batch;
167
168/// Bankai block proof verification
169///
170/// This module provides functions for verifying STWO zero-knowledge proofs and MMR inclusion proofs.
171/// These are the foundational verification operations that establish trust in the system.
172///
173/// - [`bankai::stwo`] - Verify STWO zero-knowledge proofs to extract trusted Bankai blocks with MMR roots
174/// - [`bankai::mmr`] - Verify MMR inclusion proofs against trusted MMR roots
175pub mod bankai;
176
177/// EVM-specific verification components
178///
179/// This module provides verifiers for individual EVM chain data proofs.
180/// After verification, all returned data is cryptographically guaranteed valid.
181pub mod evm;
182
183// ============================================================================
184// Public API
185// ============================================================================
186
187/// Batch proof verification
188///
189/// The main entry point for verifying complete proof batches generated by the SDK.
190pub use crate::batch::verify_batch_proof;
191
192// Re-export common types from bankai_types for convenience
193pub use bankai_types::verify::{evm::EvmResults, BatchResults};
194
195// ============================================================================
196// Error Types
197// ============================================================================
198
199/// Errors that can occur during proof verification
200///
201/// All verification failures return a specific error indicating what validation failed.
202/// These errors are designed to be informative for debugging while maintaining security.
203#[derive(Debug, Clone, Copy, PartialEq, Eq)]
204#[non_exhaustive]
205pub enum VerifyError {
206    /// The STWO zero-knowledge proof is invalid or malformed
207    InvalidStwoProof,
208
209    /// An MMR inclusion proof failed verification
210    InvalidMmrProof,
211
212    /// The MMR tree structure is invalid
213    InvalidMmrTree,
214
215    /// The MMR root in the proof doesn't match the expected root from the STWO proof
216    InvalidMmrRoot,
217
218    /// The header hash doesn't match the committed value in the MMR
219    InvalidHeaderHash,
220
221    /// A transaction Merkle proof failed verification against the header's transactions root
222    InvalidTxProof,
223
224    /// An account Merkle proof failed verification against the header's state root
225    InvalidAccountProof,
226
227    /// A storage Merkle proof failed verification against the account's storage root
228    InvalidStorageProof,
229
230    /// Referenced execution header not found in the verified headers list
231    InvalidExecutionHeaderProof,
232
233    /// The state root in the account proof doesn't match the header's state root
234    InvalidStateRoot,
235
236    /// A Merkle Patricia Trie proof verification failed
237    InvalidMptProof,
238
239    /// Failed to decode RLP-encoded data
240    InvalidRlpDecode,
241}
242
243impl core::fmt::Display for VerifyError {
244    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
245        match self {
246            Self::InvalidStwoProof => write!(f, "Invalid STWO proof"),
247            Self::InvalidMmrProof => write!(f, "Invalid MMR proof"),
248            Self::InvalidMmrTree => write!(f, "Invalid MMR tree"),
249            Self::InvalidMmrRoot => write!(f, "Invalid MMR root"),
250            Self::InvalidHeaderHash => write!(f, "Invalid header hash"),
251            Self::InvalidTxProof => write!(f, "Invalid transaction proof"),
252            Self::InvalidAccountProof => write!(f, "Invalid account proof"),
253            Self::InvalidStorageProof => write!(f, "Invalid storage proof"),
254            Self::InvalidExecutionHeaderProof => write!(f, "Invalid execution header proof"),
255            Self::InvalidStateRoot => write!(f, "Invalid state root"),
256            Self::InvalidMptProof => write!(f, "Invalid MPT proof"),
257            Self::InvalidRlpDecode => write!(f, "Invalid RLP decode"),
258        }
259    }
260}
261
262impl std::error::Error for VerifyError {}