diff --git a/Cargo.toml b/Cargo.toml index 95cdb125f..6e81e1913 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["runner", "benches", "examples/starknet"] +members = ["runner", "benches", "serializer"] [workspace.package] edition = "2021" diff --git a/README.md b/README.md index 50205f928..0b092aa31 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,32 @@ ## Using Verifier contracts on Starknet +Integrity verifier is deployed on Starknet and can be used for verifying proofs onchain. The intended way of using the verifier is through FactRegistry contract, which besides running the verification process, also stores data for all verified proofs. (For more information see [FactRegistry and Proxy contract](#factregistry-and-proxy-contract)) + +There are two ways of serializing proof into calldata: monolith and split proof. The former should be used if possible, because it's easier and more efficient. The latter should only be used if monolith proof did not fit in a single transaction, either because of calldata limit or steps limit. + +### Monolith proof + +Calldata for monolith proof can be generated with the following command: + +```bash +cargo run --release --bin proof_serializer < examples/proofs/recursive/cairo0_example_proof.json > examples/calldata +``` + +Then make sure that you have `sncast` installed and `snfoundry.toml` is configured correctly. + +After that, you can use `verify-on-starknet.sh` script to send the transaction to FactRegistry contract. Remember to select appropriate settings for your proof. For more information on supported settings, see [Verifier settings](TODO). + +For example, run: + +```bash +./verify-on-starknet.sh 0x7a5340bf1a500d94185cde6fc9cdc4b32c1159d1db5c056841d21bfb0d9c2bd examples/calldata recursive keccak_248_lsb stone5 cairo0 +``` + +### Split proof + +TODO: check if below is valid + 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](https://github.com/HerodotusDev/integrity-calldata-generator). It also provides script for automatic transaction sending (proof verification is split into multiple transactions, for more information see [Split Verifier Architecture](#split-verifier-architecture)). ## Running locally @@ -91,3 +117,5 @@ After proof is verified, `FactRegistered` event is emitted which contains `fact_ - `get_all_verifications_for_fact_hash(fact_hash)` - returns list of all verification hashes, security bits and settings for given `fact_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. + +TODO: how to read FactRegistered event diff --git a/Scarb.toml b/Scarb.toml index 2d2286ff8..556bdd9ab 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -32,4 +32,4 @@ blake2s = [] monolith = [] split = [] -default = ["recursive", "keccak"] +default = ["recursive", "keccak", "monolith"] diff --git a/examples/starknet/.gitignore b/examples/starknet/.gitignore deleted file mode 100644 index a209cfe63..000000000 --- a/examples/starknet/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -calldata -target -.snfoundry_cache/ \ No newline at end of file diff --git a/examples/starknet/1-verify-proof.sh b/examples/starknet/1-verify-proof.sh deleted file mode 100755 index af4268329..000000000 --- a/examples/starknet/1-verify-proof.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -# Check if the arguments are provided -if [ $# -ne 2 ]; then - echo "Usage: $0 " - exit 1 -fi - -# Assign arguments to variables -contract_address=$1 -calldata_file=$2 - -# Check if the file exists -if [ ! -f "$calldata_file" ]; then - echo "Error: File '$calldata_file' not found." - exit 1 -fi - -# Read calldata from the specified file -calldata=$(<$calldata_file) - -# Pass the calldata to the sncast command -sncast \ - --wait \ - invoke \ - --contract-address "$contract_address" \ - --function "verify_proof_full_and_register_fact" \ - --calldata $calldata \ - --fee-token eth diff --git a/examples/starknet/Scarb.toml b/examples/starknet/Scarb.toml deleted file mode 100644 index 57c04d648..000000000 --- a/examples/starknet/Scarb.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "starknet" -version = "0.1.0" -edition = "2023_10" - -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html - -[dependencies] -cairo_verifier = { path = ".." } -snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.20.1" } - -[[target.starknet-contract]] -casm = true \ No newline at end of file diff --git a/examples/starknet/Cargo.toml b/serializer/Cargo.toml similarity index 84% rename from examples/starknet/Cargo.toml rename to serializer/Cargo.toml index dd0a6f7d8..de0ae99ec 100644 --- a/examples/starknet/Cargo.toml +++ b/serializer/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "snfoundry_proof_serializer" +name = "proof_serializer" version = "0.1.0" edition = "2021" @@ -7,7 +7,6 @@ edition = "2021" [dependencies] anyhow.workspace = true -clap.workspace = true itertools.workspace = true runner.workspace = true serde_json.workspace = true diff --git a/examples/starknet/src/main.rs b/serializer/src/main.rs similarity index 69% rename from examples/starknet/src/main.rs rename to serializer/src/main.rs index 019221106..d7c11b552 100644 --- a/examples/starknet/src/main.rs +++ b/serializer/src/main.rs @@ -1,19 +1,9 @@ -use clap::Parser; use itertools::chain; -use runner::{transform::StarkProofExprs, CairoVersion, VecFelt252}; +use runner::{transform::StarkProofExprs, VecFelt252}; use std::io::{stdin, Read}; use swiftness_proof_parser::parse; -#[derive(Parser)] -#[command(author, version, about)] -struct Cli { - /// Cairo version - public memory pattern - #[clap(value_enum, short, long, default_value_t=CairoVersion::Cairo0)] - cairo_version: CairoVersion, -} - fn main() -> anyhow::Result<()> { - let cli = Cli::parse(); let mut input = String::new(); stdin().read_to_string(&mut input)?; @@ -32,7 +22,7 @@ fn main() -> anyhow::Result<()> { witness.into_iter() ); - let calldata_string = chain!(proof, vec![cli.cairo_version.into()].into_iter()) + let calldata_string = proof.into_iter() .map(|f| f.to_string()) .collect::>() .join(" "); diff --git a/verify-on-starknet.sh b/verify-on-starknet.sh new file mode 100755 index 000000000..8fe696e34 --- /dev/null +++ b/verify-on-starknet.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# Check if the arguments are provided +if [ $# -ne 6 ]; then + echo "Usage: $0 " + exit 1 +fi + +string_to_hex() { + input_string="$1" + hex_string="0x" + for ((i = 0; i < ${#input_string}; i++)); do + hex_char=$(printf "%x" "'${input_string:$i:1}") + hex_string+=$hex_char + done + echo "$hex_string" +} + +# Assign arguments to variables +contract_address=$1 +calldata_file=$2 +layout=$(string_to_hex $3) +hasher=$(string_to_hex $4) +stone_version=$(string_to_hex $5) +cairo_version=$(string_to_hex $6) + +# Check if the file exists +if [ ! -f "$calldata_file" ]; then + echo "Error: File '$calldata_file' not found." + exit 1 +fi + +# Read calldata from the specified file +calldata=$(<$calldata_file) + +# Pass the calldata to the sncast command +sncast \ + --wait \ + invoke \ + --contract-address "$contract_address" \ + --function "verify_proof_full_and_register_fact" \ + --calldata $layout $hasher $stone_version $cairo_version $calldata \ + --fee-token eth