From 9554028fc071bfae19762a6daaefa1e07bddb99a Mon Sep 17 00:00:00 2001 From: Neo <128649481+neotheprogramist@users.noreply.github.com> Date: Sat, 30 Dec 2023 12:06:45 +0100 Subject: [PATCH] runner/1 Basic Cairo Verifier Runner Setup (#18) * runner init * copy derive is zero cost abstraction * demo of the runner workflow * running pipeline * rename * working flat * arbitrary nested arrays working * fix display trait * enable sierra running * update readme * adjust readme * swap readmes * delete resources * add resources dir to .gitignore --- .gitignore | 25 ++++++++++- .tool-versions | 2 +- README.md | 40 +++++++++++------ Scarb.toml | 5 ++- run.sh | 5 +++ runner/Cargo.toml | 17 +++++++ runner/README.md | 48 ++++++++++++++++++++ runner/build.rs | 3 ++ runner/src/ast.rs | 66 ++++++++++++++++++++++++++++ runner/src/main.rs | 36 +++++++++++++++ runner/src/parser.lalrpop | 33 ++++++++++++++ src/input_structs.cairo | 2 + src/input_structs/stark_config.cairo | 55 +++++++++++++++++++++++ src/input_structs/stark_proof.cairo | 9 ++++ src/lib.cairo | 7 +++ 15 files changed, 337 insertions(+), 16 deletions(-) create mode 100755 run.sh create mode 100644 runner/Cargo.toml create mode 100644 runner/README.md create mode 100644 runner/build.rs create mode 100644 runner/src/ast.rs create mode 100644 runner/src/main.rs create mode 100644 runner/src/parser.lalrpop create mode 100644 src/input_structs.cairo create mode 100644 src/input_structs/stark_config.cairo create mode 100644 src/input_structs/stark_proof.cairo diff --git a/.gitignore b/.gitignore index 73aa31e60..271728423 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,25 @@ -target .snfoundry_cache/ + +# Generated by Cargo +# will have compiled files and executables +**/debug/ +**/target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +**/Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# Scarb +**/Scarb.lock + +# vscode +**/.vscode/ + +# Resources +runner/resources/ diff --git a/.tool-versions b/.tool-versions index 21cfc8077..5c160e912 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1 @@ -scarb 2.4.0 +scarb 2.4.1 diff --git a/README.md b/README.md index c0816eb2c..d8dfcf789 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,35 @@ -# Cairo1 verifier +# Cairo Verifier -## Build -``` sh -scarb build +This document provides steps to build and run the Cairo Verifier. + +## Building the Verifier + +To build the latest version of the verifier and create a Sierra file, follow these steps: + +1. Navigate to the project root directory: + +```bash +cd . ``` -## Test -``` sh -scarb test +2. Build the project: + +```bash +scarb build ``` -## Format -``` sh -scarb fmt +## Running the Verifier + +After building the verifier, you can run it with the following steps: + +1. Navigate to the runner directory: + +```bash +cd runner ``` -## Clean -``` sh -scarb clean +2. Run the verifier: + +```bash +cargo run --release -- ../target/dev/cairo_verifier.sierra < resources/parserin.txt ``` diff --git a/Scarb.toml b/Scarb.toml index 5a9b990fd..de3a004cb 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -1,3 +1,6 @@ [package] name = "cairo_verifier" -version = "0.1.0" \ No newline at end of file +version = "0.1.0" + +[lib] +sierra-text = true diff --git a/run.sh b/run.sh new file mode 100755 index 000000000..ccb737935 --- /dev/null +++ b/run.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +scarb build +cd runner +cargo run --release -- ../target/dev/cairo_verifier.sierra < resources/parserin.txt diff --git a/runner/Cargo.toml b/runner/Cargo.toml new file mode 100644 index 000000000..707a80401 --- /dev/null +++ b/runner/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "runner" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.76" +cairo-args-runner = "0.1.1" +clap = { version = "4.4.11", features = ["derive"] } +lalrpop-util = { version = "0.20.0", features = ["lexer", "unicode"] } +serde = { version = "1.0.193", features = ["derive"] } +serde_json = "1.0.108" + +[build-dependencies] +lalrpop = "0.20.0" diff --git a/runner/README.md b/runner/README.md new file mode 100644 index 000000000..4140cee06 --- /dev/null +++ b/runner/README.md @@ -0,0 +1,48 @@ +# Cairo1 Verifier + +## Overview + +The Cairo1 Verifier is a tool designed for parsing and utilizing proofs in the Cairo language. This document provides instructions on how to get and use the parsed proof. + +## Getting the Parsed Proof + +To obtain the parsed proof, follow these steps: + +### 1. Download Source Code + +- Access the source code at [Cairo1 Parser Repository](https://github.com/neotheprogramist/cairo-lang/tree/parser). + +### 2. Install Dependencies + +- Execute the command: `pipenv install`. + +### 3. Activate Virtual Environment + +- Activate the virtual environment with: `pipenv shell`. + +### 4. Run the Parser + +- Use the parser by running: + ``` + python src/main.py -l starknet_with_keccak < src/starkware/cairo/stark_verifier/air/example_proof.json > parseout.txt + ``` + +### 5. Access Output File + +- The output will be available in the `parseout.txt` file. + +## Using the Parsed Proof + +Once you have the parsed proof, you can use it as follows: + +### 1. Copy Proof to Input File + +- Copy the entire content or a consistent section of `parseout.txt` to `runner/resources/parsein.txt`. + +### 2. Adjust Input Structures + +- Modify the structures in `src/input_structs` to match the copied content. + +### 3. Execute the Runner Script + +- Run the script using: `./run.sh`. diff --git a/runner/build.rs b/runner/build.rs new file mode 100644 index 000000000..ca5c2836d --- /dev/null +++ b/runner/build.rs @@ -0,0 +1,3 @@ +fn main() { + lalrpop::process_root().unwrap(); +} diff --git a/runner/src/ast.rs b/runner/src/ast.rs new file mode 100644 index 000000000..9085ee2dc --- /dev/null +++ b/runner/src/ast.rs @@ -0,0 +1,66 @@ +use std::{ + fmt::Display, + ops::{Deref, DerefMut}, +}; + +#[derive(Debug, Clone)] +pub enum Expr { + Value(String), + Array(Vec), +} + +impl Display for Expr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Expr::Value(v) => write!(f, "{v}"), + Expr::Array(v) => { + write!(f, "[")?; + + for (i, expr) in v.iter().enumerate() { + if i != 0 { + write!(f, ", ")?; + } + write!(f, "{expr}")?; + } + + write!(f, "]")?; + + Ok(()) + }, + } + } +} + +#[derive(Debug, Clone)] +pub struct Exprs(pub Vec); + +impl Display for Exprs { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "[")?; + + for (i, expr) in self.iter().enumerate() { + if i != 0 { + write!(f, ", ")?; + } + write!(f, "{expr}")?; + } + + write!(f, "]")?; + + Ok(()) + } +} + +impl Deref for Exprs { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Exprs { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} diff --git a/runner/src/main.rs b/runner/src/main.rs new file mode 100644 index 000000000..2da2c038d --- /dev/null +++ b/runner/src/main.rs @@ -0,0 +1,36 @@ +use std::io::{stdin, Read}; + +use cairo_args_runner::{run, WrappedArg}; +use clap::Parser; +use lalrpop_util::lalrpop_mod; + +mod ast; + +lalrpop_mod!(pub parser); + +#[derive(Parser)] +#[command(author, version, about, long_about = None)] +struct Cli { + /// Path to compiled sierra file + target: String, +} + +fn main() -> anyhow::Result<()> { + let cli = Cli::parse(); + let mut input = String::new(); + stdin().read_to_string(&mut input)?; + + let parsed = parser::CairoParserOutputParser::new() + .parse(&input) + .map_err(|e| anyhow::anyhow!("{}", e))?; + let result = format!("{parsed}"); + + let target = cli.target; + let function = "main"; + let args: WrappedArg = serde_json::from_str(&result).unwrap(); + + let result = run(&target, &function, &args)?; + + println!("{result:?}"); + Ok(()) +} diff --git a/runner/src/parser.lalrpop b/runner/src/parser.lalrpop new file mode 100644 index 000000000..daa655768 --- /dev/null +++ b/runner/src/parser.lalrpop @@ -0,0 +1,33 @@ +use crate::ast::{Expr, Exprs}; + +grammar; + +pub CairoParserOutput: Exprs = { + StructName "()" => Exprs(Vec::new()), + StructName "(" > ")" => Exprs(n.iter().flat_map(|x| x.iter().cloned()).collect()), +}; + +CairoParserOutputInner: Exprs = { + => Exprs(vec![Expr::Value(n)]), + "[" > "]" => Exprs(vec![Expr::Array(n.iter().flat_map(|x| x.iter().cloned()).collect())]), + StructName "()" => Exprs(Vec::new()), + StructName "(" > ")" => Exprs(n.iter().flat_map(|x| x.iter().cloned()).collect()), +}; + +Arg: Exprs = { + ArgName "=" => n, +}; + +Comma: Vec = { + ",")*> => match e { + None => v, + Some(e) => { + v.push(e); + v + } + } +}; + +StructName: String = => s.to_string(); +ArgName: String = => s.to_string(); +Num: String = => s.to_string(); diff --git a/src/input_structs.cairo b/src/input_structs.cairo new file mode 100644 index 000000000..a87612e60 --- /dev/null +++ b/src/input_structs.cairo @@ -0,0 +1,2 @@ +mod stark_config; +mod stark_proof; diff --git a/src/input_structs/stark_config.cairo b/src/input_structs/stark_config.cairo new file mode 100644 index 000000000..4e4c27c67 --- /dev/null +++ b/src/input_structs/stark_config.cairo @@ -0,0 +1,55 @@ +#[derive(Copy, Drop)] +struct StarkConfig { + traces: TracesConfig, + composition: TableCommitmentConfig, +// fri: FriConfig, +// proof_of_work: ProofOfWorkConfig, +// // Log2 of the trace domain size. +// log_trace_domain_size: felt252, +// // Number of queries to the last component, FRI. +// n_queries: felt252, +// // Log2 of the number of cosets composing the evaluation domain, where the coset size is the +// // trace length. +// log_n_cosets: felt252, +// // Number of layers that use a verifier friendly hash in each commitment. +// n_verifier_friendly_commitment_layers: felt252, +} + +#[derive(Copy, Drop)] +struct TracesConfig { + original: TableCommitmentConfig, + interaction: TableCommitmentConfig, +} + +#[derive(Copy, Drop)] +struct TableCommitmentConfig { + columns: felt252, + vector: VectorCommitmentConfig +} + +#[derive(Copy, Drop)] +struct VectorCommitmentConfig { + height: felt252, + verifier_friendly_commitment_layers: felt252, +} + +#[derive(Copy, Drop)] +struct FriConfig { + // Log2 of the size of the input layer to FRI. + log_input_size: felt252, + // Number of layers in the FRI. Inner + last layer. + n_layers: felt252, + // Array of size n_layers - 1, each entry is a configuration of a table commitment for the + // corresponding inner layer. + inner_layers: TableCommitmentConfig, + // Array of size n_layers, each entry represents the FRI step size, + // i.e. the number of FRI-foldings between layer i and i+1. + fri_step_sizes: felt252, + log_last_layer_degree_bound: felt252, +} + +#[derive(Copy, Drop)] +struct ProofOfWorkConfig { + // Proof of work difficulty (number of bits required to be 0). + n_bits: felt252, +} diff --git a/src/input_structs/stark_proof.cairo b/src/input_structs/stark_proof.cairo new file mode 100644 index 000000000..01919b43b --- /dev/null +++ b/src/input_structs/stark_proof.cairo @@ -0,0 +1,9 @@ +use cairo_verifier::input_structs::stark_config::StarkConfig; + +#[derive(Copy, Drop)] +struct StarkProof { + config: StarkConfig, +// public_input: PublicInput, +// unsent_commitment: StarkUnsentCommitment, +// witness: StarkWitness, +} diff --git a/src/lib.cairo b/src/lib.cairo index dfc2d5fa7..5ba23f5ea 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,6 +1,13 @@ mod channel; mod common; +mod input_structs; mod structs; mod fri; mod table_commitment; mod vector_commitment; + +use cairo_verifier::input_structs::stark_proof::StarkProof; + +fn main(stark_proof: StarkProof) -> (felt252, felt252) { + (stark_proof.config.traces.original.columns, stark_proof.config.traces.interaction.columns) +}