Skip to content

Commit

Permalink
proofs generation and cairo0 programs
Browse files Browse the repository at this point in the history
  • Loading branch information
Okm165 committed Sep 18, 2024
1 parent d008dbb commit 4e2c9d4
Show file tree
Hide file tree
Showing 10 changed files with 457 additions and 0 deletions.
28 changes: 28 additions & 0 deletions examples/proofs/cpu_air_params.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"field": "PrimeField0",
"channel_hash": "poseidon3",
"commitment_hash": "keccak256_masked160_lsb",
"n_verifier_friendly_commitment_layers": 1000,
"pow_hash": "keccak256",
"statement": {
"page_hash": "pedersen"
},
"stark": {
"fri": {
"fri_step_list": [
0,
4,
4,
2
],
"last_layer_degree_bound": 128,
"n_queries": 18,
"proof_of_work_bits": 24
},
"log_n_cosets": 2
},

"use_extension_field": false,
"verifier_friendly_channel_updates": true,
"verifier_friendly_commitment_hash": "poseidon3"
}
9 changes: 9 additions & 0 deletions examples/proofs/cpu_air_prover_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"cached_lde_config": {
"store_full_lde": false,
"use_fft_for_eval": false
},
"constraint_polynomial_task_size": 256,
"n_out_of_memory_merkle_layers": 0,
"table_prover_n_tasks_per_segment": 32
}
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
);
}
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
}
153 changes: 153 additions & 0 deletions examples/proofs/generate,py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
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.")
44 changes: 44 additions & 0 deletions examples/proofs/recursive/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 bitwise
func main(
output_ptr: felt*, pedersen_ptr: felt*, range_check_ptr: felt*, bitwise_ptr: felt*) -> (
output_ptr: felt*, pedersen_ptr: felt*, range_check_ptr: felt*, bitwise_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, bitwise_ptr=bitwise_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
);
}
44 changes: 44 additions & 0 deletions examples/proofs/recursive_with_poseidon/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 bitwise poseidon
func main(
output_ptr: felt*, pedersen_ptr: felt*, range_check_ptr: felt*, bitwise_ptr: felt*, poseidon_ptr: felt*) -> (
output_ptr: felt*, pedersen_ptr: felt*, range_check_ptr: felt*, bitwise_ptr: felt*, poseidon_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, bitwise_ptr=bitwise_ptr, poseidon_ptr=poseidon_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
);
}
44 changes: 44 additions & 0 deletions examples/proofs/small/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
);
}
Loading

0 comments on commit 4e2c9d4

Please sign in to comment.