Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proofs refactor #152

Merged
merged 5 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*example_proof.json filter=lfs diff=lfs merge=lfs -text
2 changes: 1 addition & 1 deletion .github/workflows/proof_verification_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ jobs:
run: scarb build --no-default-features --features monolith,${{ matrix.layout }},${{ matrix.hash_function }}

- name: Run verification
run: cargo run --release --bin runner -- --program target/dev/cairo_verifier.sierra.json --cairo-version ${{ matrix.cairo_version }} --stone-version ${{ matrix.stone_version }} --hasher-bit-length ${{ matrix.hasher_bit_length }} < examples/proofs/${{ matrix.layout }}/${{ matrix.cairo_version }}_example_proof.json
run: cargo run --release --bin runner -- --program target/dev/cairo_verifier.sierra.json --cairo-version ${{ matrix.cairo_version }} --stone-version ${{ matrix.stone_version }} --hasher-bit-length ${{ matrix.hasher_bit_length }} < examples/proofs/${{ matrix.layout }}/${{ matrix.cairo_version }}_${{ matrix.stone_version }}_${{ matrix.hash_function }}_160_lsb_example_proof.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"field": "PrimeField0",
"channel_hash": "poseidon3",
"commitment_hash": "blake256_masked160_lsb",
"n_verifier_friendly_commitment_layers": 9999,
"pow_hash": "blake256",
"commitment_hash": "keccak256_masked160_lsb",
"n_verifier_friendly_commitment_layers": 1000,
"pow_hash": "keccak256",
"statement": {
"page_hash": "pedersen"
},
Expand All @@ -13,7 +13,7 @@
0,
4,
4,
3
2
],
"last_layer_degree_bound": 128,
"n_queries": 18,
Expand Down
1,740 changes: 0 additions & 1,740 deletions examples/proofs/dex/cairo0_example_proof.json

This file was deleted.

44 changes: 44 additions & 0 deletions examples/proofs/dex/cairo0_fibonacci.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2023 StarkWare Industries Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License").
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.starkware.co/open-source-license/
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions
// and limitations under the License.

%builtins output pedersen range_check ecdsa
func main(
output_ptr: felt*, pedersen_ptr: felt*, range_check_ptr: felt*, ecdsa_ptr: felt*) -> (
output_ptr: felt*, pedersen_ptr: felt*, range_check_ptr: felt*, ecdsa_ptr: felt*
) {
alloc_locals;

// Load fibonacci_claim_index and copy it to the output segment.
local fibonacci_claim_index;
%{ ids.fibonacci_claim_index = program_input['fibonacci_claim_index'] %}

assert output_ptr[0] = fibonacci_claim_index;
let res = fib(1, 1, fibonacci_claim_index);
assert output_ptr[1] = res;

// Return the updated output_ptr.
return (
output_ptr=&output_ptr[2], pedersen_ptr=pedersen_ptr, range_check_ptr=range_check_ptr, ecdsa_ptr=ecdsa_ptr
);
}

func fib(first_element: felt, second_element: felt, n: felt) -> felt {
if (n == 0) {
return second_element;
}

return fib(
first_element=second_element, second_element=first_element + second_element, n=n - 1
);
}
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
1,107 changes: 0 additions & 1,107 deletions examples/proofs/dex/cairo1_example_proof.json

This file was deleted.

Git LFS file not shown
3 changes: 3 additions & 0 deletions examples/proofs/fibonacci_input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"fibonacci_claim_index": 10000
}
203 changes: 203 additions & 0 deletions examples/proofs/generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
import os
import subprocess
import tempfile
import logging
import json
from math import ceil, log

# Setup logging configuration
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)

# List of layouts to process
LAYOUTS = [
"dex",
"recursive",
"recursive_with_poseidon",
"small",
"starknet",
"starknet_with_keccak",
]
# LAYOUTS = ['dynamic']

# Paths for required files
PARAMETER_FILE = "cpu_air_params.json"
PROVER_CONFIG_FILE = "cpu_air_prover_config.json"
PROGRAM_INPUT_FILE = "fibonacci_input.json"


def run_command(command: list):
"""Run a shell command and log the output or errors."""
try:
logging.info(f'Running command: {" ".join(command)}')
subprocess.run(command, check=True)
except subprocess.CalledProcessError as e:
logging.error(f"Command failed: {e}")
raise


def extract_steps(public_input_file: str) -> int:
"""Extract 'n_steps' from the public input JSON file."""
with open(public_input_file, "r") as f:
public_input = json.load(f)
return public_input.get("n_steps", 0)


def compute_fri_step_list(n_steps: int, config: dict) -> list:
"""Compute a new 'fri_step_list' based on the provided n_steps and config template."""
n_steps_log = ceil(log(n_steps, 2))
last_layer_degree_bound_log = ceil(
log(config["stark"]["fri"]["last_layer_degree_bound"], 2)
)
sigma_fri_step_list = n_steps_log + 4 - last_layer_degree_bound_log

q, r = divmod(sigma_fri_step_list, 4)
return [0] + [4] * q + ([r] if r > 0 else [])


def update_parameter_file(parameter_file_path: str, tmpdir: str, n_steps: int) -> str:
"""Update the parameter file with a new 'fri_step_list' and save to a temporary file."""
with open(parameter_file_path, "r") as f:
config = json.load(f)

# Update fri_step_list
config["stark"]["fri"]["fri_step_list"] = compute_fri_step_list(n_steps, config)

# Save updated config to a temporary file
updated_file = os.path.join(tmpdir, "updated_cpu_air_params.json")
with open(updated_file, "w") as f:
json.dump(config, f, indent=4)

logging.info(f"Updated parameter file saved: {updated_file}")
return updated_file


def build_cairo_run_command(
layout: str,
compiled_output: str,
trace_file: str,
memory_file: str,
public_input_file: str,
private_input_file: str,
) -> list:
"""Build the cairo-run command with optional parameters based on the layout."""
base_command = [
"cairo-run",
"--program",
compiled_output,
"--layout",
layout,
"--proof_mode",
"--program_input",
PROGRAM_INPUT_FILE,
"--trace_file",
trace_file,
"--memory_file",
memory_file,
"--air_private_input",
private_input_file,
"--air_public_input",
public_input_file,
"--print_info",
"--print_output",
]

# Add dynamic layout-specific parameter
if layout == "dynamic":
cairo_layout_params_file = os.path.join(layout, "cairo_layout_params.json")
base_command.extend(["--cairo_layout_params_file", cairo_layout_params_file])

return base_command


def process_layout(layout: str):
"""Main process for compiling, running, and proving for a given layout."""
logging.info(f"Processing layout: {layout}")

with tempfile.TemporaryDirectory() as tmpdir:
# Compile the Cairo program
compiled_output = os.path.join(tmpdir, "fibonacci_compiled.json")
run_command(
[
"cairo-compile",
f"{layout}/cairo0_fibonacci.cairo",
"--output",
compiled_output,
"--no_debug_info",
"--proof_mode",
]
)

# Prepare files for the run step
trace_file = os.path.join(tmpdir, "fibonacci_trace.bin")
memory_file = os.path.join(tmpdir, "fibonacci_memory.bin")
public_input_file = os.path.join(tmpdir, "fibonacci_public_input.json")
private_input_file = os.path.join(tmpdir, "fibonacci_private_input.json")

# Build and run the Cairo program command
cairo_run_command = [
"cairo-run",
"--program",
compiled_output,
"--layout",
layout,
"--proof_mode",
"--program_input",
PROGRAM_INPUT_FILE,
"--trace_file",
trace_file,
"--memory_file",
memory_file,
"--air_private_input",
private_input_file,
"--air_public_input",
public_input_file,
"--print_info",
"--print_output",
]

# Add dynamic layout-specific parameter
if layout == "dynamic":
cairo_layout_params_file = os.path.join(layout, "cairo_layout_params.json")
cairo_run_command.extend(
["--cairo_layout_params_file", cairo_layout_params_file]
)

run_command(cairo_run_command)

# Update parameter file with new fri_step_list
n_steps = extract_steps(public_input_file)
updated_parameter_file = update_parameter_file(PARAMETER_FILE, tmpdir, n_steps)

# Run the prover
proof_output = f"{layout}/cairo0_stone6_keccak_160_lsb_example_proof.json"
run_command(
[
"cpu_air_prover",
"--parameter_file",
updated_parameter_file,
"--prover_config_file",
PROVER_CONFIG_FILE,
"--public_input_file",
public_input_file,
"--private_input_file",
private_input_file,
"--out_file",
proof_output,
"--generate_annotations",
]
)

logging.info(f"Proof saved for {layout} in {proof_output}")


# Main execution loop for each layout
for layout in LAYOUTS:
try:
process_layout(layout)
except Exception as e:
logging.error(f"Error processing layout {layout}: {e}")
continue

logging.info("Process completed for all layouts.")
Loading
Loading