To use the Verifier for verifying proofs on starknet, you need to generate calldata for your proof. The easiest way to do that is to use Calldata Generator. It also provides script for automatic transaction sending (proof verification is split into multiple transactions, for more information see Split Verifier Architecture).
To build the Cairo Verifier, follow these steps:
- Build the project by running the following command in your terminal:
scarb build
If you want to build for other layouts, refer to Configure Verifier
- (Optional) Test the project to ensure everything works correctly:
scarb test
Run the verifier locally using the following command on example proof, followed by the Cairo version (cairo0 or cairo1) used to generate the proof:
cargo run --release --bin runner -- --program target/dev/cairo_verifier.sierra.json -c cairo0 < examples/proofs/recursive/cairo0_example_proof.json
cargo run --release --bin runner -- --program target/dev/cairo_verifier.sierra.json -c cairo1 < examples/proofs/recursive/cairo1_example_proof.json
By default, the verifier is configured for monolith version, recursive layout and keccak hash for verifier unfriendly commitment layers. You can easily change that by using scarb's features:
scarb build --no-default-features --features small,blake2s,monolith
layout types: [dex, recursive, recursive_with_poseidon, small, starknet, starknet_with_keccak]
hash types: [keccak, blake2s]
verifier types: [monolith, split]
In order to launch benchmarking, just run this (it requires recursive layout configuration):
cargo run --release --bin benches -- target/dev/cairo_verifier.sierra.json
For detailed instructions and examples, refer to the Stone Prover documentation.
How to prove Cairo0 program with Stone Prover.
How to prove Cairo1 program with Stone Prover.
Because of great complexity of the verifier compared to standard starknet contracts, we encounter some limitations enforced by starknet. The most important ones are:
- Contract classhash size limit
- Transaction calldata limit
- Transaction steps limit
To overcome these limitations, we split the verifier into multiple contracts and transactions. The biggest part of classhash size is autogenerated (e.g. recursive autogenerated), so we extracted that part into separate contract (or many contracts in case of starknet
and starknet_with_keccak
layout), which is called automatically by the main verifier contract. On the other hand the biggest part of calldata is fri witness, so user can send subsequent chunks of fri witness in separate step transactions.
Since verifier can be configured in many ways and some parts of the logic changes with new stone versions, a contract which routes calls to the correct verifier is needed. This task is handled by FactRegistry contract that also stores data for all verified proofs.
After proof is verified, FactRegistered
event is emitted which contains fact_hash
, verification_hash
, security_bits
and settings
. fact_hash
is a value that represents proven program and its output (formally fact_hash = poseidon_hash(program_hash, output_hash)
). Remember that registration of some fact_hash
doesn't necessary mean that it has been verified by someone with secure enough proof. You always need to check security_bits
and settings
which is part of verification_hash
(formally verification_hash = poseidon_hash(fact_hash, security_bits, settings)
).
FactRegistry
provides two methods for checking verified proofs:
get_verification(verification_hash)
- returns fact hash, security bits and settings for givenverification_hash
.get_all_verifications_for_fact_hash(fact_hash)
- returns list of all verification hashes, security bits and settings for givenfact_hash
. This method is useful for checking if given program has been verified by someone with secure enough proof.
FactRegistry contract is trustless which means that owner of the contract can't override or change any existing behavior, they can only add new verifiers. Proxy contract on the other hand is upgradable, so every function can be changed or removed. It has the advantage of having all future updates of the verifier logic without having to replace the address of FactRegistry contract.