Skip to content

Commit

Permalink
compute_next_layer
Browse files Browse the repository at this point in the history
  • Loading branch information
Okm165 committed Dec 19, 2023
1 parent b14e69a commit 649b733
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/common.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod flip_endiannes;
mod from_span;
mod horner_eval;
mod to_array;
mod math;

#[cfg(test)]
mod tests;
22 changes: 22 additions & 0 deletions src/common/math.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
fn pow(base: felt252, exp: felt252) -> felt252 {
if exp == 0 {
return 1; // Return 1 for zero exponent
}
let mut exp: u256 = exp.into();
let mut res = 1; // Initialize result as 1
let mut curr_base = base; // Current base value

loop {
if exp == 0 {
break;
} else {
if exp % 2 == 1 {
res = res * curr_base; // Multiply result only when exp is odd
}
curr_base = curr_base * curr_base; // Square the base for next iteration
exp = exp / 2; // Divide exponent by 2
}
};

res
}
1 change: 1 addition & 0 deletions src/common/tests.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ mod test_flip_endiannes;
mod test_from_span;
mod test_horner_eval;
mod test_to_array;
mod test_math;
27 changes: 27 additions & 0 deletions src/common/tests/test_math.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use cairo_verifier::common::math::pow;

#[test]
#[available_gas(9999999999)]
fn test_pow_1() {
let base = 1934568044210770965733097210694395167600009938751278224656090409051406060084;
let exp = 69439516760000993875127;
assert(
pow(
base, exp
) == 2804690217475462062143361339624939640984649667966511418446363596075299761851,
'Invalid value'
);
}

#[test]
#[available_gas(9999999999)]
fn test_pow_2() {
let base = 193456804421077096570009938751278224656090409051406060084;
let exp = 193456804421077096570009938751278224656090409051406060084;
assert(
pow(
base, exp
) == 2672162222334975109199941471365701890765112108683608796920114577809390903720,
'Invalid value'
);
}
1 change: 1 addition & 0 deletions src/fri/fri_config.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const MAX_LAST_LAYER_LOG_DEGREE_BOUND: u32 = 15;
const MAX_FRI_LAYERS: u32 = 15;
const MAX_FRI_STEP: u32 = 4;

#[derive(Drop)]
struct FriConfig {
// Log2 of the size of the input layer to FRI.
log_input_size: felt252,
Expand Down
84 changes: 83 additions & 1 deletion src/fri/fri_layer.cairo
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
use core::array::SpanTrait;
use core::array::ArrayTrait;
use cairo_verifier::fri::fri_formula::fri_formula;
use cairo_verifier::common::math;

// Constant parameters for computing the next FRI layer.
#[derive(Drop, Copy)]
struct FriLayerComputationParams {
coset_size: felt252,
fri_group: Span<felt252>,
eval_point: felt252,
}

#[derive(Drop, Copy)]
struct FriLayerQuery {
index: felt252,
y_value: felt252,
Expand Down Expand Up @@ -40,7 +44,7 @@ fn compute_coset_elements(
fri_group: Span<felt252>,
) -> (Array<felt252>, felt252) {
let mut coset_elements = ArrayTrait::<felt252>::new();
let mut coset_x_inv: felt252 = 1;
let mut coset_x_inv: felt252 = 0;

let mut i: u32 = 0;
let mut j: u32 = 0;
Expand All @@ -63,3 +67,81 @@ fn compute_coset_elements(

(coset_elements, coset_x_inv)
}

// Computes FRI next layer for the given queries. I.e., takes the given i-th layer queries
// and produces queries for layer i+1 (a single query for each coset in the i-th layer).
//
// Inputs:
// - n_queries: the number of input queries.
// - queries: input queries.
// - sibling_witness: a list of all the query's siblings.
// - params: the parameters to use for the layer computation.
//
// Outputs:
// - next_queries: queries for the next layer.
// - verify_indices: query indices of the given layer for Merkle verification.
// - verify_y_values: query y values of the given layer for Merkle verification.
fn compute_next_layer(
mut n_queries: felt252,
queries: Span<FriLayerQuery>,
sibling_witness: Span<felt252>,
params: FriLayerComputationParams,
) -> (Array<FriLayerQuery>, Array<felt252>, Array<felt252>) {
let mut next_queries = ArrayTrait::<FriLayerQuery>::new();
let mut verify_indices = ArrayTrait::<felt252>::new();
let mut verify_y_values = ArrayTrait::<felt252>::new();

let coset_size = params.coset_size;

let mut i: u32 = 0;
loop {
if n_queries == 0 {
break;
}

let coset_index = *(queries.at(i)).index;
assert(0_u256 <= coset_index.into(), 'Invalid value');

verify_indices.append(coset_index);

let (coset_elements, coset_x_inv) = compute_coset_elements(
n_queries,
queries,
sibling_witness,
coset_size,
coset_index * coset_size,
0,
params.fri_group
);

let coset_elements_len = coset_elements.len();
assert(0 <= coset_elements_len, 'Invalid value');

let coset_elements_span = coset_elements.span();

let mut j: u32 = 0;
loop {
if j == coset_elements_len {
break;
}
verify_y_values.append(*(coset_elements_span.at(j)));
};

let fri_formula_res = fri_formula(
coset_elements_span, params.eval_point, coset_x_inv, coset_size,
);

let next_x_inv = math::pow(coset_x_inv, params.coset_size);

next_queries
.append(
FriLayerQuery {
index: coset_index, y_value: fri_formula_res, x_inv_value: next_x_inv
}
);

i += 1;
};

(next_queries, verify_indices, verify_y_values)
}

0 comments on commit 649b733

Please sign in to comment.