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

Stark Config Validation #41

Closed
wants to merge 7 commits into from
Closed
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
4 changes: 2 additions & 2 deletions run.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env bash

scarb build
cd runner
scarb build && \
cd runner && \
cargo run --release -- ../target/dev/cairo_verifier.sierra.json < resources/parserin.txt
1 change: 1 addition & 0 deletions src/common.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod array_split;
mod consts;
mod merge_sort;
mod powers_array;
mod asserts;

#[cfg(test)]
mod tests;
6 changes: 6 additions & 0 deletions src/common/asserts.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use cairo_verifier::common::math::Felt252PartialOrd;

fn assert_in_range(x: felt252, min: felt252, max: felt252) {
assert(min <= x, 'Value too small');
assert(x < max, 'Value too large');
}
44 changes: 20 additions & 24 deletions src/fri/fri_config.cairo
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use core::traits::TryInto;
use core::traits::Into;
use cairo_verifier::{
table_commitment::TableCommitmentConfig,
common::math::{pow, Felt252PartialOrd}, table_commitment::TableCommitmentConfig,
structs::stark_config::FriConfig as FriConfigInputStruct, common::asserts::assert_in_range,
vector_commitment::vector_commitment::{validate_vector_commitment, VectorCommitmentConfig},
};

const MAX_LAST_LAYER_LOG_DEGREE_BOUND: u32 = 15;
const MAX_FRI_LAYERS: u32 = 15;
const MAX_FRI_STEP: u32 = 4;
const MAX_LAST_LAYER_LOG_DEGREE_BOUND: felt252 = 15;
const MAX_FRI_LAYERS: felt252 = 15;
const MAX_FRI_STEP: felt252 = 4;

#[derive(Drop, Copy)]
struct FriConfig {
Expand All @@ -25,43 +28,36 @@ struct FriConfig {
fn fri_config_validate(
config: FriConfig, log_n_cosets: felt252, n_verifier_friendly_commitment_layers: felt252
) -> felt252 {
let n_layers: u32 = config.n_layers.try_into().unwrap();
let log_last_layer_degree_bound: u32 = config.log_last_layer_degree_bound.try_into().unwrap();

assert(log_last_layer_degree_bound <= MAX_LAST_LAYER_LOG_DEGREE_BOUND, 'Value too big');

assert_in_range(config.n_layers, 2, MAX_FRI_LAYERS + 1);
assert(config.log_last_layer_degree_bound <= MAX_LAST_LAYER_LOG_DEGREE_BOUND, 'Value too big');
assert(*config.fri_step_sizes.at(0) == 0, 'Invalid value');

assert(n_layers >= 2, 'Value too small');
assert(n_layers <= MAX_FRI_LAYERS + 1, 'Value too big');

let mut i: u32 = 1;
let mut sum_of_step_sizes: felt252 = 0;
let n_layers: u32 = config.n_layers.try_into().unwrap();
let mut sum_of_step_sizes = 0;
let mut log_input_size = config.log_input_size;
loop {
if i == n_layers {
break;
}

let fri_step: felt252 = *config.fri_step_sizes.at(i);
let table_commitment = *config.inner_layers.at(i);

let fri_step_u32: u32 = fri_step.try_into().unwrap();
assert(fri_step_u32 >= 1, 'Value too small');
assert(fri_step_u32 <= MAX_FRI_STEP + 1, 'Value too big');
assert(table_commitment.n_columns == fri_step * fri_step, 'Invalid value');

i += 1;
let fri_step = *config.fri_step_sizes.at(i);
let table_commitment = *config.inner_layers.at(i - 1);
log_input_size -= fri_step;
sum_of_step_sizes += fri_step;

assert_in_range(fri_step, 1, MAX_FRI_STEP + 1);
assert(table_commitment.n_columns == pow(2, fri_step), 'Invalid value');
validate_vector_commitment(
table_commitment.vector, log_input_size, n_verifier_friendly_commitment_layers,
);

i += 1;
};

let log_expected_input_degree = sum_of_step_sizes + config.log_last_layer_degree_bound;
assert(log_expected_input_degree + log_n_cosets == config.log_input_size, '');
assert(
log_expected_input_degree + log_n_cosets == config.log_input_size, 'Log input size mismatch'
);
log_expected_input_degree
}

5 changes: 0 additions & 5 deletions src/input_structs.cairo

This file was deleted.

16 changes: 0 additions & 16 deletions src/input_structs/public_input.cairo

This file was deleted.

55 changes: 0 additions & 55 deletions src/input_structs/stark_config.cairo

This file was deleted.

13 changes: 0 additions & 13 deletions src/input_structs/stark_proof.cairo

This file was deleted.

14 changes: 8 additions & 6 deletions src/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
mod air;
mod channel;
mod common;
mod input_structs;
mod fri;
mod structs;
mod air;
mod oods;
mod fri;
mod table_commitment;
mod vector_commitment;
mod queries;
mod proof_of_work;
mod table_commitment;
mod validation;
mod vector_commitment;

use cairo_verifier::{structs::stark_proof::StarkProof, structs::stark_proof::verify_stark_proof};

use cairo_verifier::input_structs::stark_proof::StarkProof;

fn main(x: Array<felt252>) {
let mut x_span = x.span();
let stark_proof: StarkProof = Serde::deserialize(ref x_span).unwrap();
verify_stark_proof(stark_proof);
}
7 changes: 3 additions & 4 deletions src/structs.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
mod proof_of_work_config;
mod public_input;
mod stark_config;
mod stark_proof;
mod traces_config;
mod unsent_commitment;
mod witness;
mod stark_unsent_commitment;
mod stark_witness;
4 changes: 0 additions & 4 deletions src/structs/proof_of_work_config.cairo

This file was deleted.

20 changes: 15 additions & 5 deletions src/structs/public_input.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
struct StarkProof {
config: StarkConfig,
// public_input: PublicInput,
// unsent_commitment: StarkUnsentCommitment,
// witness: StarkWitness,
#[derive(Drop, Serde)]
struct PublicInput {
log_n_steps: felt252,
range_check_min: felt252,
range_check_max: felt252,
layout: felt252,
dynamic_params: Array<felt252>,
n_segments: felt252,
segments: Array<felt252>,
padding_addr: felt252,
padding_value: felt252,
main_page_len: felt252,
main_page: Array<felt252>,
n_continuous_pages: felt252,
continuous_page_headers: Array<felt252>,
}
111 changes: 109 additions & 2 deletions src/structs/stark_config.cairo
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
use cairo_verifier::{
structs::traces_config::TracesConfig, table_commitment::TableCommitmentConfig,
fri::fri_config::FriConfig, structs::proof_of_work_config::ProofOfWorkConfig
common::asserts::assert_in_range,
fri::fri_config::FriConfig as DeserializationUnfriendlyFriConfig,
table_commitment::TableCommitmentConfig,
vector_commitment::vector_commitment::{VectorCommitmentConfig, validate_vector_commitment},
validation::proof_of_work::proof_of_work_config_validate, fri::fri_config::fri_config_validate,
};

const MAX_N_COLUMNS: felt252 = 128;
const AIR_LAYOUT_N_ORIGINAL_COLUMNS: felt252 = 12;
const AIR_LAYOUT_N_INTERACTION_COLUMNS: felt252 = 3;

#[derive(Drop, Serde)]
struct StarkConfig {
traces: TracesConfig,
composition: TableCommitmentConfig,
Expand All @@ -18,3 +26,102 @@ struct StarkConfig {
// Number of layers that use a verifier friendly hash in each commitment.
n_verifier_friendly_commitment_layers: felt252,
}

fn stark_config_validate(stark_config: StarkConfig, security_bits: felt252) {
proof_of_work_config_validate(stark_config.proof_of_work);

let log_eval_domain_size = stark_config.log_trace_domain_size + stark_config.log_n_cosets;
traces_config_validate(stark_config.traces, log_eval_domain_size, security_bits);

validate_vector_commitment(
stark_config.composition.vector,
log_eval_domain_size,
stark_config.n_verifier_friendly_commitment_layers
);
fri_config_validate(
stark_config.fri.into(),
stark_config.log_n_cosets,
stark_config.n_verifier_friendly_commitment_layers
);
}

#[derive(Drop, Serde)]
struct TracesConfig {
original: TableCommitmentConfig,
interaction: TableCommitmentConfig,
}

// Validates the configuration of the traces.
// log_eval_domain_size - Log2 of the evaluation domain size.
fn traces_config_validate(
config: TracesConfig,
log_eval_domain_size: felt252,
n_verifier_friendly_commitment_layers: felt252,
) {
assert_in_range(config.original.n_columns, 1, MAX_N_COLUMNS + 1);
assert_in_range(config.interaction.n_columns, 1, MAX_N_COLUMNS + 1);
assert(config.original.n_columns == AIR_LAYOUT_N_ORIGINAL_COLUMNS, 'Wrong number of columns');
assert(
config.interaction.n_columns == AIR_LAYOUT_N_INTERACTION_COLUMNS, 'Wrong number of columns'
);

validate_vector_commitment(
config.original.vector, log_eval_domain_size, n_verifier_friendly_commitment_layers,
);
validate_vector_commitment(
config.interaction.vector, log_eval_domain_size, n_verifier_friendly_commitment_layers,
);
}

#[derive(Drop, Serde)]
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: Array<felt252>,
// 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: Array<felt252>,
log_last_layer_degree_bound: felt252,
}
Comment on lines +76 to +89
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opt for FRI functionalities & structs to be in fri module.
I think it should be moved to contextually relevant module WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you quite misunderstood the concept behind this struct.
It might be called DeserializationFriendlyFriConfig - when you take a deeper look you can see that there is a implementation of the into trait to the struct with the same name in the fri module.
It is because to support objects (original struct has an array of structs instead of felts) in arrays I would need to modify parser which for our testing purposes is not a priority in my opinion.
The other way would be to modify the fri implementation to support this struct instead of the old one, but I've decided to do it the faster way for now and to implement into to the original struct.
This is only the "proxy" struct that helps in the deserialization from parser output to the FriConfig struct present in the fri module.
In my opinion such a bit "messy" struct used only for deserialization purposes for sure shouldn't be in the fri module which contains clean fri impl.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure let's change its name to DeserializationFriendlyFriConfig then

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @neotheprogramist , if the struct is going to be used for deserialization only it doesn't make sense to be in the fri module


impl IntoDeserializationUnfriendlyFriConfig of Into<FriConfig, DeserializationUnfriendlyFriConfig> {
fn into(self: FriConfig) -> DeserializationUnfriendlyFriConfig {
let mut inner_layers = ArrayTrait::<TableCommitmentConfig>::new();
let mut i = 0;
loop {
if i == self.inner_layers.len() {
break;
}

inner_layers
.append(
TableCommitmentConfig {
n_columns: *self.inner_layers.at(i),
vector: VectorCommitmentConfig {
height: *self.inner_layers.at(i + 1),
n_verifier_friendly_commitment_layers: *self.inner_layers.at(i + 2),
}
}
);
i += 3;
};

DeserializationUnfriendlyFriConfig {
log_input_size: self.log_input_size,
n_layers: self.n_layers,
inner_layers: inner_layers.span(),
fri_step_sizes: self.fri_step_sizes.span(),
log_last_layer_degree_bound: self.log_last_layer_degree_bound,
}
}
}

#[derive(Drop, Serde)]
struct ProofOfWorkConfig {
// Proof of work difficulty (number of bits required to be 0).
n_bits: felt252,
}
Loading