From 308ee267da4bc7069118180b661034df78101ba9 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 18 Dec 2023 09:48:25 +0100 Subject: [PATCH 01/38] fri_formulas --- src/fri.cairo | 4 ++ src/fri/fri_formula.cairo | 57 ++++++++++++++++++++++++++++ src/fri/tests.cairo | 1 + src/fri/tests/calc.py | 11 ++++++ src/fri/tests/test_fri_formula.cairo | 0 src/lib.cairo | 1 + 6 files changed, 74 insertions(+) create mode 100644 src/fri.cairo create mode 100644 src/fri/fri_formula.cairo create mode 100644 src/fri/tests.cairo create mode 100644 src/fri/tests/calc.py create mode 100644 src/fri/tests/test_fri_formula.cairo diff --git a/src/fri.cairo b/src/fri.cairo new file mode 100644 index 000000000..f92c4da20 --- /dev/null +++ b/src/fri.cairo @@ -0,0 +1,4 @@ +mod fri_formula; + +#[cfg(test)] +mod tests; diff --git a/src/fri/fri_formula.cairo b/src/fri/fri_formula.cairo new file mode 100644 index 000000000..63c48b1cd --- /dev/null +++ b/src/fri/fri_formula.cairo @@ -0,0 +1,57 @@ +use core::array::SpanTrait; + +// Constants representing primitive roots of unity for orders 2, 4, 8, and 16. +// These are calculated based on the formula 1 / 3^((PRIME - 1) / 16) where 3 is a generator. +const OMEGA_16: felt252 = 0x5c3ed0c6f6ac6dd647c9ba3e4721c1eb14011ea3d174c52d7981c5b8145aa75; +const OMEGA_8: felt252 = 0x446ed3ce295dda2b5ea677394813e6eab8bfbc55397aacac8e6df6f4bc9ca34; +const OMEGA_4: felt252 = 0x1dafdc6d65d66b5accedf99bcd607383ad971a9537cdf25d59e99d90becc81e; +const OMEGA_2: felt252 = 0x800000000000011000000000000000000000000000000000000000000000000; + +// Function to fold 2 elements into one using one layer of FRI (Fast Reed-Solomon Interactive Oracle Proofs). +fn fri_formula2(f_x: felt252, f_minus_x: felt252, eval_point: felt252, x_inv: felt252) -> felt252 { + f_x + f_minus_x + eval_point * x_inv * (f_x - f_minus_x) +} + +// Function to fold 4 elements into one using 2 layers of FRI. +fn fri_formula4(values: Span, eval_point: felt252, x_inv: felt252) -> felt252 { + // Applying the first layer of folding. + let g0 = fri_formula2(*values[0], *values[1], eval_point, x_inv); + let g1 = fri_formula2(*values[2], *values[3], eval_point, x_inv * OMEGA_4); + + // Last layer, combining the results of the first layer. + fri_formula2(g0, g1, eval_point * eval_point, x_inv * x_inv) +} + +// Function to fold 8 elements into one using 3 layers of FRI. +fn fri_formula8(values: Span, eval_point: felt252, x_inv: felt252) -> felt252 { + // Applying the first two layers of folding. + let g0 = fri_formula4(values.slice(0, 4), eval_point, x_inv); + let g1 = fri_formula4(values.slice(4, 4), eval_point, x_inv * OMEGA_8); + + // Preparing variables for the last layer. + let eval_point2 = eval_point * eval_point; + let eval_point4 = eval_point2 * eval_point2; + let x_inv2 = x_inv * x_inv; + let x_inv4 = x_inv2 * x_inv2; + + // Last layer, combining the results of the previous layers. + fri_formula2(g0, g1, eval_point4, x_inv4) +} + +// Function to fold 16 elements into one using 4 layers of FRI. +fn fri_formula16(values: Span, eval_point: felt252, x_inv: felt252) -> felt252 { + // Applying the first three layers of folding. + let g0 = fri_formula8(values.slice(0, 8), eval_point, x_inv); + let g1 = fri_formula8(values.slice(8, 8), eval_point, x_inv * OMEGA_16); + + // Preparing variables for the last layer. + let eval_point2 = eval_point * eval_point; + let eval_point4 = eval_point2 * eval_point2; + let eval_point8 = eval_point4 * eval_point4; + let x_inv2 = x_inv * x_inv; + let x_inv4 = x_inv2 * x_inv2; + let x_inv8 = x_inv4 * x_inv4; + + // Last layer, combining the results of the previous layers. + fri_formula2(g0, g1, eval_point8, x_inv8) +} diff --git a/src/fri/tests.cairo b/src/fri/tests.cairo new file mode 100644 index 000000000..553cc68a2 --- /dev/null +++ b/src/fri/tests.cairo @@ -0,0 +1 @@ +mod test_fri_formula; diff --git a/src/fri/tests/calc.py b/src/fri/tests/calc.py new file mode 100644 index 000000000..94bf6b2b3 --- /dev/null +++ b/src/fri/tests/calc.py @@ -0,0 +1,11 @@ +DEFAULT_PRIME = 2**251 + 17 * 2**192 + 1 + +OMEGA16 = 2607735469685256064975697808597423000021425046638838630471627721324227832437 + +# Printing the values in hexadecimal format directly +print("DEFAULT_PRIME in hexadecimal:", hex(DEFAULT_PRIME)) +print(hex(pow(OMEGA16, 1, DEFAULT_PRIME))) +print(hex(pow(OMEGA16, 2, DEFAULT_PRIME))) +print(hex(pow(OMEGA16, 4, DEFAULT_PRIME))) +print(hex(pow(OMEGA16, 8, DEFAULT_PRIME))) +print(hex(pow(OMEGA16, 16, DEFAULT_PRIME))) diff --git a/src/fri/tests/test_fri_formula.cairo b/src/fri/tests/test_fri_formula.cairo new file mode 100644 index 000000000..e69de29bb diff --git a/src/lib.cairo b/src/lib.cairo index 3e032ff8d..120a0c95d 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,3 +1,4 @@ mod channel; mod common; mod structs; +mod fri; From 859c72c510ebabe8fd2f69e18713f89e500026fe Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 18 Dec 2023 09:48:58 +0100 Subject: [PATCH 02/38] fri_formulas --- src/fri/tests/calc.py | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 src/fri/tests/calc.py diff --git a/src/fri/tests/calc.py b/src/fri/tests/calc.py deleted file mode 100644 index 94bf6b2b3..000000000 --- a/src/fri/tests/calc.py +++ /dev/null @@ -1,11 +0,0 @@ -DEFAULT_PRIME = 2**251 + 17 * 2**192 + 1 - -OMEGA16 = 2607735469685256064975697808597423000021425046638838630471627721324227832437 - -# Printing the values in hexadecimal format directly -print("DEFAULT_PRIME in hexadecimal:", hex(DEFAULT_PRIME)) -print(hex(pow(OMEGA16, 1, DEFAULT_PRIME))) -print(hex(pow(OMEGA16, 2, DEFAULT_PRIME))) -print(hex(pow(OMEGA16, 4, DEFAULT_PRIME))) -print(hex(pow(OMEGA16, 8, DEFAULT_PRIME))) -print(hex(pow(OMEGA16, 16, DEFAULT_PRIME))) From 6139744ab1ae748d98be494848d02bd56ffa5b85 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 18 Dec 2023 14:15:56 +0100 Subject: [PATCH 03/38] fri_formula finished --- src/fri/fri_formula.cairo | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/fri/fri_formula.cairo b/src/fri/fri_formula.cairo index 63c48b1cd..be4dc7eae 100644 --- a/src/fri/fri_formula.cairo +++ b/src/fri/fri_formula.cairo @@ -14,6 +14,7 @@ fn fri_formula2(f_x: felt252, f_minus_x: felt252, eval_point: felt252, x_inv: fe // Function to fold 4 elements into one using 2 layers of FRI. fn fri_formula4(values: Span, eval_point: felt252, x_inv: felt252) -> felt252 { + assert(values.len() == 4, 'Values length not equal 4'); // Applying the first layer of folding. let g0 = fri_formula2(*values[0], *values[1], eval_point, x_inv); let g1 = fri_formula2(*values[2], *values[3], eval_point, x_inv * OMEGA_4); @@ -24,6 +25,7 @@ fn fri_formula4(values: Span, eval_point: felt252, x_inv: felt252) -> f // Function to fold 8 elements into one using 3 layers of FRI. fn fri_formula8(values: Span, eval_point: felt252, x_inv: felt252) -> felt252 { + assert(values.len() == 8, 'Values length not equal 8'); // Applying the first two layers of folding. let g0 = fri_formula4(values.slice(0, 4), eval_point, x_inv); let g1 = fri_formula4(values.slice(4, 4), eval_point, x_inv * OMEGA_8); @@ -40,6 +42,7 @@ fn fri_formula8(values: Span, eval_point: felt252, x_inv: felt252) -> f // Function to fold 16 elements into one using 4 layers of FRI. fn fri_formula16(values: Span, eval_point: felt252, x_inv: felt252) -> felt252 { + assert(values.len() == 16, 'Values length not equal 16'); // Applying the first three layers of folding. let g0 = fri_formula8(values.slice(0, 8), eval_point, x_inv); let g1 = fri_formula8(values.slice(8, 8), eval_point, x_inv * OMEGA_16); @@ -55,3 +58,22 @@ fn fri_formula16(values: Span, eval_point: felt252, x_inv: felt252) -> // Last layer, combining the results of the previous layers. fri_formula2(g0, g1, eval_point8, x_inv8) } + +// Folds 'coset_size' elements into one using log2(coset_size) layers of FRI. +// 'coset_size' can be 2, 4, 8, or 16. +fn fri_formula(values: Span, eval_point: felt252, x_inv: felt252, coset_size: felt252) -> felt252 { + // Sort by usage frequency. + if (coset_size == 8) { + return fri_formula8(values, eval_point, x_inv); + } + else if (coset_size == 4) { + return fri_formula4(values, eval_point, x_inv); + } + else if (coset_size == 16) { + return fri_formula16(values, eval_point, x_inv); + } + else { + assert(values.len() == 2, 'Values length not equal 2'); + return fri_formula2(*values[0], *values[1], eval_point, x_inv); + } +} From 1d574e504c88183bb719750418d4af8860b84643 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 18 Dec 2023 14:30:58 +0100 Subject: [PATCH 04/38] fri_group --- src/fri.cairo | 1 + src/fri/fri_group.cairo | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 src/fri/fri_group.cairo diff --git a/src/fri.cairo b/src/fri.cairo index f92c4da20..4cafa5e60 100644 --- a/src/fri.cairo +++ b/src/fri.cairo @@ -1,4 +1,5 @@ mod fri_formula; +mod fri_group; #[cfg(test)] mod tests; diff --git a/src/fri/fri_group.cairo b/src/fri/fri_group.cairo new file mode 100644 index 000000000..c4a3133da --- /dev/null +++ b/src/fri/fri_group.cairo @@ -0,0 +1,20 @@ +fn get_fri_group() -> Array { + array![ + 0x1, + 0x800000000000011000000000000000000000000000000000000000000000000, + 0x625023929a2995b533120664329f8c7c5268e56ac8320da2a616626f41337e3, + 0x1dafdc6d65d66b5accedf99bcd607383ad971a9537cdf25d59e99d90becc81e, + 0x63365fe0de874d9c90adb1e2f9c676e98c62155e4412e873ada5e1dee6feebb, + 0x1cc9a01f2178b3736f524e1d06398916739deaa1bbed178c525a1e211901146, + 0x3b912c31d6a226e4a15988c6b7ec1915474043aac68553537192090b43635cd, + 0x446ed3ce295dda2b5ea677394813e6eab8bfbc55397aacac8e6df6f4bc9ca34, + 0x5ec467b88826aba4537602d514425f3b0bdf467bbf302458337c45f6021e539, + 0x213b984777d9556bac89fd2aebbda0c4f420b98440cfdba7cc83ba09fde1ac8, + 0x5ce3fa16c35cb4da537753675ca3276ead24059dddea2ca47c36587e5a538d1, + 0x231c05e93ca34c35ac88ac98a35cd89152dbfa622215d35b83c9a781a5ac730, + 0x00b54759e8c46e1258dc80f091e6f3be387888015452ce5f0ca09ce9e571f52, + 0x7f4ab8a6173b92fda7237f0f6e190c41c78777feabad31a0f35f63161a8e0af, + 0x23c12f3909539339b83645c1b8de3e14ebfee15c2e8b3ad2867e3a47eba558c, + 0x5c3ed0c6f6ac6dd647c9ba3e4721c1eb14011ea3d174c52d7981c5b8145aa75, + ] +} From 4a6194cad4846093c1012c3b2b262c556ad14475 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 18 Dec 2023 16:48:26 +0100 Subject: [PATCH 05/38] fri verify config --- src/fri.cairo | 2 + src/fri/fri_config.cairo | 59 ++++++++++++++++++++++ src/fri/fri_layer.cairo | 12 +++++ src/structs.cairo | 1 - src/structs/fri_config.cairo | 15 ------ src/structs/stark_config.cairo | 2 +- src/structs/table_commitment_config.cairo | 1 + src/structs/vector_commitment_config.cairo | 1 + 8 files changed, 76 insertions(+), 17 deletions(-) create mode 100644 src/fri/fri_config.cairo create mode 100644 src/fri/fri_layer.cairo delete mode 100644 src/structs/fri_config.cairo diff --git a/src/fri.cairo b/src/fri.cairo index 4cafa5e60..93bcc141f 100644 --- a/src/fri.cairo +++ b/src/fri.cairo @@ -1,5 +1,7 @@ mod fri_formula; mod fri_group; +mod fri_layer; +mod fri_config; #[cfg(test)] mod tests; diff --git a/src/fri/fri_config.cairo b/src/fri/fri_config.cairo new file mode 100644 index 000000000..c5e89ac07 --- /dev/null +++ b/src/fri/fri_config.cairo @@ -0,0 +1,59 @@ +use core::option::OptionTrait; +use core::array::SpanTrait; +use core::traits::Into; +use cairo_verifier::structs::table_commitment_config::TableCommitmentConfig; + +const MAX_LAST_LAYER_LOG_DEGREE_BOUND: u32 = 15; +const MAX_FRI_LAYERS: u32 = 15; +const MAX_FRI_STEP: u32 = 4; + +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: Span, + // 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: Span, + log_last_layer_degree_bound: felt252, +} + +fn fri_config_validate( + config: FriConfig, log_n_cosets: felt252, n_verifier_friendly_commitment_layers: felt252 +) -> felt252 { + assert(0_u256 <= config.log_last_layer_degree_bound.into(), ''); + assert(config.log_last_layer_degree_bound.try_into().unwrap() <= MAX_LAST_LAYER_LOG_DEGREE_BOUND, ''); + + assert(2_u256 <= config.n_layers.into(), ''); + assert(config.n_layers.try_into().unwrap() <= MAX_FRI_LAYERS + 1, ''); + + assert(*(config.fri_step_sizes[0]) == 0, ''); + + let len: u32 = config.n_layers.try_into().unwrap(); + let mut i = 0_u32; + let mut sum_of_step_sizes: felt252 = 0; + let mut log_input_size = config.log_input_size; + loop { + if i == len { break; } + let fri_step: felt252 = *(config.fri_step_sizes.at(i)); + assert(1_u32 <= fri_step.try_into().unwrap(), ''); + assert(fri_step.try_into().unwrap() <= MAX_FRI_STEP + 1, ''); + assert((*(config.inner_layers.at(i))).columns == fri_step * fri_step, ''); + i += 1; + log_input_size -= fri_step; + sum_of_step_sizes += fri_step; + // validate_vector_commitment( + // config=layers[0].vector, + // expected_height=log_input_size, + // n_verifier_friendly_commitment_layers=n_verifier_friendly_commitment_layers, + // ); + }; + + + 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, ''); + log_expected_input_degree +} \ No newline at end of file diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo new file mode 100644 index 000000000..e70e3687d --- /dev/null +++ b/src/fri/fri_layer.cairo @@ -0,0 +1,12 @@ +// Constant parameters for computing the next FRI layer. +struct FriLayerComputationParams { + coset_size: felt252, + fri_group: Span, + eval_point: felt252, +} + +struct FriLayerQuery { + index: felt252, + y_value: felt252, + x_inv_value: felt252, +} \ No newline at end of file diff --git a/src/structs.cairo b/src/structs.cairo index b978c4505..000d62f6e 100644 --- a/src/structs.cairo +++ b/src/structs.cairo @@ -1,4 +1,3 @@ -mod fri_config; mod proof_of_work_config; mod stark_config; mod stark_proof; diff --git a/src/structs/fri_config.cairo b/src/structs/fri_config.cairo deleted file mode 100644 index 35ebe0816..000000000 --- a/src/structs/fri_config.cairo +++ /dev/null @@ -1,15 +0,0 @@ -use cairo_verifier::structs::table_commitment_config::TableCommitmentConfig; - -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, -} diff --git a/src/structs/stark_config.cairo b/src/structs/stark_config.cairo index af63fec11..9e960da6b 100644 --- a/src/structs/stark_config.cairo +++ b/src/structs/stark_config.cairo @@ -1,6 +1,6 @@ use cairo_verifier::structs::traces_config::TracesConfig; use cairo_verifier::structs::table_commitment_config::TableCommitmentConfig; -use cairo_verifier::structs::fri_config::FriConfig; +use cairo_verifier::fri::fri_config::FriConfig; use cairo_verifier::structs::proof_of_work_config::ProofOfWorkConfig; struct StarkConfig { diff --git a/src/structs/table_commitment_config.cairo b/src/structs/table_commitment_config.cairo index 45ed8906b..30238bfed 100644 --- a/src/structs/table_commitment_config.cairo +++ b/src/structs/table_commitment_config.cairo @@ -1,5 +1,6 @@ use cairo_verifier::structs::vector_commitment_config::VectorCommitmentConfig; +#[derive(Drop, Copy)] struct TableCommitmentConfig { columns: felt252, vector: VectorCommitmentConfig diff --git a/src/structs/vector_commitment_config.cairo b/src/structs/vector_commitment_config.cairo index 578cd82ec..b7079ed6a 100644 --- a/src/structs/vector_commitment_config.cairo +++ b/src/structs/vector_commitment_config.cairo @@ -1,3 +1,4 @@ +#[derive(Drop, Copy)] struct VectorCommitmentConfig { height: felt252, verifier_friendly_commitment_layers: felt252, From 4a10e1bf11ca789aa9f867d63f32066d0842edeb Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 18 Dec 2023 18:51:47 +0100 Subject: [PATCH 06/38] fri_config_validate fixes --- src/fri/fri_config.cairo | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/fri/fri_config.cairo b/src/fri/fri_config.cairo index c5e89ac07..2a4f4af70 100644 --- a/src/fri/fri_config.cairo +++ b/src/fri/fri_config.cairo @@ -2,6 +2,7 @@ use core::option::OptionTrait; use core::array::SpanTrait; use core::traits::Into; use cairo_verifier::structs::table_commitment_config::TableCommitmentConfig; +use cairo_verifier::structs::vector_commitment_config::VectorCommitmentConfig; const MAX_LAST_LAYER_LOG_DEGREE_BOUND: u32 = 15; const MAX_FRI_LAYERS: u32 = 15; @@ -33,27 +34,39 @@ fn fri_config_validate( assert(*(config.fri_step_sizes[0]) == 0, ''); let len: u32 = config.n_layers.try_into().unwrap(); - let mut i = 0_u32; + let mut i: u32 = 1; let mut sum_of_step_sizes: felt252 = 0; let mut log_input_size = config.log_input_size; loop { if i == len { break; } + let fri_step: felt252 = *(config.fri_step_sizes.at(i)); - assert(1_u32 <= fri_step.try_into().unwrap(), ''); - assert(fri_step.try_into().unwrap() <= MAX_FRI_STEP + 1, ''); - assert((*(config.inner_layers.at(i))).columns == fri_step * fri_step, ''); + let table_commitment = *(config.inner_layers.at(i)); + + let fri_step_u32: u32 = fri_step.try_into().unwrap(); + assert(1_u32 <= fri_step_u32, ''); + assert(fri_step_u32 <= MAX_FRI_STEP + 1, ''); + assert(table_commitment.columns == fri_step * fri_step, ''); + i += 1; log_input_size -= fri_step; sum_of_step_sizes += fri_step; - // validate_vector_commitment( - // config=layers[0].vector, - // expected_height=log_input_size, - // n_verifier_friendly_commitment_layers=n_verifier_friendly_commitment_layers, - // ); - }; + validate_vector_commitment( + table_commitment.vector, + log_input_size, + n_verifier_friendly_commitment_layers, + ); + }; 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, ''); log_expected_input_degree -} \ No newline at end of file +} + +// ghost functions +fn validate_vector_commitment( + config: VectorCommitmentConfig, + expected_height: felt252, + n_verifier_friendly_commitment_layers: felt252, +) {} \ No newline at end of file From e3c9791a781b7caf5b063ae48235eace616c617a Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 18 Dec 2023 18:55:30 +0100 Subject: [PATCH 07/38] error msgs --- src/fri/fri_config.cairo | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/fri/fri_config.cairo b/src/fri/fri_config.cairo index 2a4f4af70..85a908f88 100644 --- a/src/fri/fri_config.cairo +++ b/src/fri/fri_config.cairo @@ -25,13 +25,13 @@ struct FriConfig { fn fri_config_validate( config: FriConfig, log_n_cosets: felt252, n_verifier_friendly_commitment_layers: felt252 ) -> felt252 { - assert(0_u256 <= config.log_last_layer_degree_bound.into(), ''); - assert(config.log_last_layer_degree_bound.try_into().unwrap() <= MAX_LAST_LAYER_LOG_DEGREE_BOUND, ''); + assert(0_u256 <= config.log_last_layer_degree_bound.into(), 'Invalid value'); + assert(config.log_last_layer_degree_bound.try_into().unwrap() <= MAX_LAST_LAYER_LOG_DEGREE_BOUND, 'Invalid value'); - assert(2_u256 <= config.n_layers.into(), ''); - assert(config.n_layers.try_into().unwrap() <= MAX_FRI_LAYERS + 1, ''); + assert(2_u256 <= config.n_layers.into(), 'Invalid value'); + assert(config.n_layers.try_into().unwrap() <= MAX_FRI_LAYERS + 1, 'Invalid value'); - assert(*(config.fri_step_sizes[0]) == 0, ''); + assert(*(config.fri_step_sizes[0]) == 0, 'Invalid value'); let len: u32 = config.n_layers.try_into().unwrap(); let mut i: u32 = 1; @@ -44,9 +44,9 @@ fn fri_config_validate( let table_commitment = *(config.inner_layers.at(i)); let fri_step_u32: u32 = fri_step.try_into().unwrap(); - assert(1_u32 <= fri_step_u32, ''); - assert(fri_step_u32 <= MAX_FRI_STEP + 1, ''); - assert(table_commitment.columns == fri_step * fri_step, ''); + assert(1_u32 <= fri_step_u32, 'Invalid value'); + assert(fri_step_u32 <= MAX_FRI_STEP + 1, 'Invalid value'); + assert(table_commitment.columns == fri_step * fri_step, 'Invalid value'); i += 1; log_input_size -= fri_step; From dd2b9ef7c43e7c4a50dff52607cf74dd7423e586 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 18 Dec 2023 18:56:08 +0100 Subject: [PATCH 08/38] fmt --- src/fri/fri_config.cairo | 15 +++++++++------ src/fri/fri_formula.cairo | 13 ++++++------- src/fri/fri_layer.cairo | 2 +- src/fri/tests/test_fri_formula.cairo | 1 + 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/fri/fri_config.cairo b/src/fri/fri_config.cairo index 85a908f88..fa1fccf53 100644 --- a/src/fri/fri_config.cairo +++ b/src/fri/fri_config.cairo @@ -26,7 +26,10 @@ fn fri_config_validate( config: FriConfig, log_n_cosets: felt252, n_verifier_friendly_commitment_layers: felt252 ) -> felt252 { assert(0_u256 <= config.log_last_layer_degree_bound.into(), 'Invalid value'); - assert(config.log_last_layer_degree_bound.try_into().unwrap() <= MAX_LAST_LAYER_LOG_DEGREE_BOUND, 'Invalid value'); + assert( + config.log_last_layer_degree_bound.try_into().unwrap() <= MAX_LAST_LAYER_LOG_DEGREE_BOUND, + 'Invalid value' + ); assert(2_u256 <= config.n_layers.into(), 'Invalid value'); assert(config.n_layers.try_into().unwrap() <= MAX_FRI_LAYERS + 1, 'Invalid value'); @@ -38,7 +41,9 @@ fn fri_config_validate( let mut sum_of_step_sizes: felt252 = 0; let mut log_input_size = config.log_input_size; loop { - if i == len { break; } + if i == len { + break; + } let fri_step: felt252 = *(config.fri_step_sizes.at(i)); let table_commitment = *(config.inner_layers.at(i)); @@ -53,9 +58,7 @@ fn fri_config_validate( sum_of_step_sizes += fri_step; validate_vector_commitment( - table_commitment.vector, - log_input_size, - n_verifier_friendly_commitment_layers, + table_commitment.vector, log_input_size, n_verifier_friendly_commitment_layers, ); }; @@ -69,4 +72,4 @@ fn validate_vector_commitment( config: VectorCommitmentConfig, expected_height: felt252, n_verifier_friendly_commitment_layers: felt252, -) {} \ No newline at end of file +) {} diff --git a/src/fri/fri_formula.cairo b/src/fri/fri_formula.cairo index be4dc7eae..4f2698178 100644 --- a/src/fri/fri_formula.cairo +++ b/src/fri/fri_formula.cairo @@ -61,18 +61,17 @@ fn fri_formula16(values: Span, eval_point: felt252, x_inv: felt252) -> // Folds 'coset_size' elements into one using log2(coset_size) layers of FRI. // 'coset_size' can be 2, 4, 8, or 16. -fn fri_formula(values: Span, eval_point: felt252, x_inv: felt252, coset_size: felt252) -> felt252 { +fn fri_formula( + values: Span, eval_point: felt252, x_inv: felt252, coset_size: felt252 +) -> felt252 { // Sort by usage frequency. if (coset_size == 8) { return fri_formula8(values, eval_point, x_inv); - } - else if (coset_size == 4) { + } else if (coset_size == 4) { return fri_formula4(values, eval_point, x_inv); - } - else if (coset_size == 16) { + } else if (coset_size == 16) { return fri_formula16(values, eval_point, x_inv); - } - else { + } else { assert(values.len() == 2, 'Values length not equal 2'); return fri_formula2(*values[0], *values[1], eval_point, x_inv); } diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index e70e3687d..7b3a54068 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -9,4 +9,4 @@ struct FriLayerQuery { index: felt252, y_value: felt252, x_inv_value: felt252, -} \ No newline at end of file +} diff --git a/src/fri/tests/test_fri_formula.cairo b/src/fri/tests/test_fri_formula.cairo index e69de29bb..8b1378917 100644 --- a/src/fri/tests/test_fri_formula.cairo +++ b/src/fri/tests/test_fri_formula.cairo @@ -0,0 +1 @@ + From 48b6073e4b9dc40f241aae2994117da725054e0c Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 18 Dec 2023 19:32:58 +0100 Subject: [PATCH 09/38] cleanup --- calc.py | 3 +++ src/fri/fri_config.cairo | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 calc.py diff --git a/calc.py b/calc.py new file mode 100644 index 000000000..61fce91fe --- /dev/null +++ b/calc.py @@ -0,0 +1,3 @@ +DEFAULT_PRIME = 2**251 + 17 * 2**192 + 1 + +print(hex(pow(1934568044210770965733097210694395167600009938751278224656090409051406060084, 41, DEFAULT_PRIME))) \ No newline at end of file diff --git a/src/fri/fri_config.cairo b/src/fri/fri_config.cairo index fa1fccf53..1bb8011df 100644 --- a/src/fri/fri_config.cairo +++ b/src/fri/fri_config.cairo @@ -1,3 +1,4 @@ +use core::array::ArrayTrait; use core::option::OptionTrait; use core::array::SpanTrait; use core::traits::Into; @@ -15,7 +16,7 @@ struct FriConfig { 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: Span, + inner_layers: Array, // 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: Span, From b14e69a5a1fa12a1b841cea27d63df08808c2962 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 18 Dec 2023 21:39:52 +0100 Subject: [PATCH 10/38] compute_coset_elements --- src/fri/fri_layer.cairo | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index 7b3a54068..2d9432d39 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -1,3 +1,6 @@ +use core::array::SpanTrait; +use core::array::ArrayTrait; + // Constant parameters for computing the next FRI layer. struct FriLayerComputationParams { coset_size: felt252, @@ -10,3 +13,53 @@ struct FriLayerQuery { y_value: felt252, x_inv_value: felt252, } + +// Computes the elements of the coset starting at coset_start_index. +// +// Inputs: +// - n_queries: the number of input queries. +// - queries: an iterator over the input queries. +// - sibling_witness: a list of all the query's siblings. +// - coset_size: the number of elements in the coset. +// - coset_start_index: the index of the first element of the coset being calculated. +// - offset_within_coset: the offset of the current processed element within the coset. +// - fri_group: holds the group in bit reversed order, where g is the generator of the coset. +// +// Outputs: +// - coset_elements: the values of the coset elements. +// - coset_x_inv: x_inv of the first element in the coset. This value is set only if at least one +// query was consumed by this function. + +fn compute_coset_elements( + mut n_queries: felt252, + queries: Span, + sibling_witness: Span, + coset_size: felt252, + coset_start_index: felt252, + mut offset_within_coset: felt252, + fri_group: Span, +) -> (Array, felt252) { + let mut coset_elements = ArrayTrait::::new(); + let mut coset_x_inv: felt252 = 1; + + let mut i: u32 = 0; + let mut j: u32 = 0; + + loop { + if offset_within_coset == coset_size { + break; + } + + if n_queries != 0 && *(queries.at(i)).index == coset_start_index + offset_within_coset { + coset_elements.append(*(queries.at(i)).y_value); + coset_x_inv = (*(queries.at(i)).x_inv_value) * (*(fri_group.at(i))); + n_queries -= 1; + i += 1; + } else { + coset_elements.append(*(sibling_witness.at(j))); + j += 1; + } + }; + + (coset_elements, coset_x_inv) +} From 649b733e87f702bc702799eed86dd5a7d03ef5de Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Tue, 19 Dec 2023 12:23:04 +0100 Subject: [PATCH 11/38] compute_next_layer --- src/common.cairo | 1 + src/common/math.cairo | 22 +++++++++ src/common/tests.cairo | 1 + src/common/tests/test_math.cairo | 27 ++++++++++ src/fri/fri_config.cairo | 1 + src/fri/fri_layer.cairo | 84 +++++++++++++++++++++++++++++++- 6 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 src/common/math.cairo create mode 100644 src/common/tests/test_math.cairo diff --git a/src/common.cairo b/src/common.cairo index 95b44e817..8083003bd 100644 --- a/src/common.cairo +++ b/src/common.cairo @@ -3,6 +3,7 @@ mod flip_endiannes; mod from_span; mod horner_eval; mod to_array; +mod math; #[cfg(test)] mod tests; diff --git a/src/common/math.cairo b/src/common/math.cairo new file mode 100644 index 000000000..b81f22ccb --- /dev/null +++ b/src/common/math.cairo @@ -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 +} diff --git a/src/common/tests.cairo b/src/common/tests.cairo index d944d16ca..c59c48eb2 100644 --- a/src/common/tests.cairo +++ b/src/common/tests.cairo @@ -3,3 +3,4 @@ mod test_flip_endiannes; mod test_from_span; mod test_horner_eval; mod test_to_array; +mod test_math; diff --git a/src/common/tests/test_math.cairo b/src/common/tests/test_math.cairo new file mode 100644 index 000000000..9801bea41 --- /dev/null +++ b/src/common/tests/test_math.cairo @@ -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' + ); +} diff --git a/src/fri/fri_config.cairo b/src/fri/fri_config.cairo index 1bb8011df..a6e942811 100644 --- a/src/fri/fri_config.cairo +++ b/src/fri/fri_config.cairo @@ -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, diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index 2d9432d39..c0037dfbd 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -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, eval_point: felt252, } +#[derive(Drop, Copy)] struct FriLayerQuery { index: felt252, y_value: felt252, @@ -40,7 +44,7 @@ fn compute_coset_elements( fri_group: Span, ) -> (Array, felt252) { let mut coset_elements = ArrayTrait::::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; @@ -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, + sibling_witness: Span, + params: FriLayerComputationParams, +) -> (Array, Array, Array) { + let mut next_queries = ArrayTrait::::new(); + let mut verify_indices = ArrayTrait::::new(); + let mut verify_y_values = ArrayTrait::::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) +} From a3d6ddda7f34e5d3f30830bab108ac178c3482bf Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Tue, 19 Dec 2023 13:16:47 +0100 Subject: [PATCH 12/38] cleanup --- Scarb.toml | 2 +- calc.py | 2 +- src/fri/fri_layer.cairo | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index 73d345695..5a9b990fd 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -1,3 +1,3 @@ [package] name = "cairo_verifier" -version = "0.1.0" +version = "0.1.0" \ No newline at end of file diff --git a/calc.py b/calc.py index 61fce91fe..26506aed1 100644 --- a/calc.py +++ b/calc.py @@ -1,3 +1,3 @@ DEFAULT_PRIME = 2**251 + 17 * 2**192 + 1 -print(hex(pow(1934568044210770965733097210694395167600009938751278224656090409051406060084, 41, DEFAULT_PRIME))) \ No newline at end of file +print((pow(193456804421077096570009938751278224656090409051406060084, 193456804421077096570009938751278224656090409051406060084, DEFAULT_PRIME))) \ No newline at end of file diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index c0037dfbd..05a8b8f9b 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -3,7 +3,6 @@ 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, From 9fcec24fbe64f49fe64319155212e388314ec5c8 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Tue, 19 Dec 2023 14:40:01 +0100 Subject: [PATCH 13/38] verify_last_layer --- src/common/horner_eval.cairo | 2 +- src/common/math.cairo | 7 ++++- src/common/tests/test_horner_eval.cairo | 9 +++--- src/common/tests/test_math.cairo | 42 ++++++++++++++++++++++++- src/fri.cairo | 2 ++ src/fri/fri.cairo | 0 src/fri/fri_last_layer.cairo | 26 +++++++++++++++ 7 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 src/fri/fri.cairo create mode 100644 src/fri/fri_last_layer.cairo diff --git a/src/common/horner_eval.cairo b/src/common/horner_eval.cairo index 48b8f60d4..44af52857 100644 --- a/src/common/horner_eval.cairo +++ b/src/common/horner_eval.cairo @@ -3,7 +3,7 @@ // `point` is the value at which the polynomial will be evaluated. // The function returns the polynomial evaluation as `felt252`. -fn horner_eval(coefs: Array, point: felt252) -> felt252 { +fn horner_eval(coefs: Span, point: felt252) -> felt252 { let mut res = 0; let mut i = coefs.len(); loop { diff --git a/src/common/math.cairo b/src/common/math.cairo index b81f22ccb..e268fdd08 100644 --- a/src/common/math.cairo +++ b/src/common/math.cairo @@ -17,6 +17,11 @@ fn pow(base: felt252, exp: felt252) -> felt252 { exp = exp / 2; // Divide exponent by 2 } }; - res } + +fn mul_inverse(x: felt252) -> felt252 { + // From Fermat's little theorem, a ^ (p - 1) = 1 when p is prime and a != 0. Since a ^ (p - 1) = a · a ^ (p - 2) we have that + // a ^ (p - 2) is the multiplicative inverse of a modulo p. + pow(x, 3618502788666131213697322783095070105623107215331596699973092056135872020479) +} \ No newline at end of file diff --git a/src/common/tests/test_horner_eval.cairo b/src/common/tests/test_horner_eval.cairo index 674bc06ef..c543a79c1 100644 --- a/src/common/tests/test_horner_eval.cairo +++ b/src/common/tests/test_horner_eval.cairo @@ -1,10 +1,11 @@ +use core::array::ArrayTrait; use cairo_verifier::common::horner_eval::horner_eval; #[test] #[available_gas(9999999999)] fn test_horner_eval_0() { let mut coefs = ArrayTrait::::new(); - let eval = horner_eval(coefs, 1); + let eval = horner_eval(coefs.span(), 1); assert(eval == 0, 'invalid evaluation result'); } @@ -13,7 +14,7 @@ fn test_horner_eval_0() { fn test_horner_eval_1() { let mut coefs = ArrayTrait::::new(); coefs.append(1); - let eval = horner_eval(coefs, 7); + let eval = horner_eval(coefs.span(), 7); assert(eval == 1, 'invalid evaluation result'); } @@ -26,7 +27,7 @@ fn test_horner_eval_2() { coefs.append(19); coefs.append(1); coefs.append(9); - let eval = horner_eval(coefs, 13); + let eval = horner_eval(coefs.span(), 13); assert(eval == 262591, 'invalid evaluation result'); } @@ -48,6 +49,6 @@ fn test_horner_eval_3() { coefs.append(7); coefs.append(111); coefs.append(1); - let eval = horner_eval(coefs, 19); + let eval = horner_eval(coefs.span(), 19); assert(eval == 288577899334361215, 'invalid evaluation result'); } diff --git a/src/common/tests/test_math.cairo b/src/common/tests/test_math.cairo index 9801bea41..5a0541ecb 100644 --- a/src/common/tests/test_math.cairo +++ b/src/common/tests/test_math.cairo @@ -1,4 +1,4 @@ -use cairo_verifier::common::math::pow; +use cairo_verifier::common::math::{pow, mul_inverse}; #[test] #[available_gas(9999999999)] @@ -25,3 +25,43 @@ fn test_pow_2() { 'Invalid value' ); } + +#[test] +#[available_gas(9999999999)] +fn test_mul_inverse_1() { + let x = 9751091999414713; + let inv_x = mul_inverse(x); + assert(x * inv_x == 1, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_mul_inverse_2() { + let x = 97199414713; + let inv_x = mul_inverse(x); + assert(x * inv_x == 1, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_mul_inverse_3() { + let x = 92011457780; + let inv_x = mul_inverse(x); + assert(x * inv_x == 1, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_mul_inverse_4() { + let x = 193456804421077096570009938751278224656090409051406060084; + let inv_inv_x = mul_inverse(mul_inverse(x)); + assert(x == inv_inv_x, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_mul_inverse_5() { + let x = 19345680409051406060084; + let inv_inv_x = mul_inverse(mul_inverse(x)); + assert(x == inv_inv_x, 'Invalid value'); +} diff --git a/src/fri.cairo b/src/fri.cairo index 93bcc141f..b13fe562a 100644 --- a/src/fri.cairo +++ b/src/fri.cairo @@ -2,6 +2,8 @@ mod fri_formula; mod fri_group; mod fri_layer; mod fri_config; +mod fri_last_layer; +mod fri; #[cfg(test)] mod tests; diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo new file mode 100644 index 000000000..e69de29bb diff --git a/src/fri/fri_last_layer.cairo b/src/fri/fri_last_layer.cairo new file mode 100644 index 000000000..429433a81 --- /dev/null +++ b/src/fri/fri_last_layer.cairo @@ -0,0 +1,26 @@ +use core::option::OptionTrait; +use core::traits::TryInto; + +use cairo_verifier::common::horner_eval; +use cairo_verifier::common::math; +use cairo_verifier::fri::fri_layer::FriLayerQuery; +// Verifies FRI last layer by evaluating the given polynomial on the given points (=inverses of +// x_inv_values), and comparing the results to the given values. +fn verify_last_layer( + n_queries: felt252, + queries: Span, + coefficients: Span +) { + let mut i: u32 = 0; + let len: u32 = n_queries.try_into().unwrap(); + loop { + if i == len { + break; + } + let value = horner_eval::horner_eval( + coefficients, math::mul_inverse(*(queries.at(i)).x_inv_value) + ); + assert(value == *(queries.at(i)).y_value, ''); + i += 1; + } +} From c483e4c84ab7f4c32045b5e3faaba688ae6c816c Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Tue, 19 Dec 2023 14:41:48 +0100 Subject: [PATCH 14/38] cleanup --- src/common/math.cairo | 14 +++++++------- src/fri/fri.cairo | 1 + src/fri/fri_last_layer.cairo | 4 +--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/common/math.cairo b/src/common/math.cairo index e268fdd08..a7725c167 100644 --- a/src/common/math.cairo +++ b/src/common/math.cairo @@ -1,20 +1,20 @@ fn pow(base: felt252, exp: felt252) -> felt252 { if exp == 0 { - return 1; // Return 1 for zero exponent + return 1; } let mut exp: u256 = exp.into(); - let mut res = 1; // Initialize result as 1 - let mut curr_base = base; // Current base value + let mut res = 1; + let mut curr_base = base; loop { if exp == 0 { break; } else { if exp % 2 == 1 { - res = res * curr_base; // Multiply result only when exp is odd + res = res * curr_base; } - curr_base = curr_base * curr_base; // Square the base for next iteration - exp = exp / 2; // Divide exponent by 2 + curr_base = curr_base * curr_base; + exp = exp / 2; } }; res @@ -24,4 +24,4 @@ fn mul_inverse(x: felt252) -> felt252 { // From Fermat's little theorem, a ^ (p - 1) = 1 when p is prime and a != 0. Since a ^ (p - 1) = a · a ^ (p - 2) we have that // a ^ (p - 2) is the multiplicative inverse of a modulo p. pow(x, 3618502788666131213697322783095070105623107215331596699973092056135872020479) -} \ No newline at end of file +} diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo index e69de29bb..8b1378917 100644 --- a/src/fri/fri.cairo +++ b/src/fri/fri.cairo @@ -0,0 +1 @@ + diff --git a/src/fri/fri_last_layer.cairo b/src/fri/fri_last_layer.cairo index 429433a81..d50e79ecb 100644 --- a/src/fri/fri_last_layer.cairo +++ b/src/fri/fri_last_layer.cairo @@ -7,9 +7,7 @@ use cairo_verifier::fri::fri_layer::FriLayerQuery; // Verifies FRI last layer by evaluating the given polynomial on the given points (=inverses of // x_inv_values), and comparing the results to the given values. fn verify_last_layer( - n_queries: felt252, - queries: Span, - coefficients: Span + n_queries: felt252, queries: Span, coefficients: Span ) { let mut i: u32 = 0; let len: u32 = n_queries.try_into().unwrap(); From 008ebd5618f4480c9613c4b48eee5ba30a435ea9 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Wed, 20 Dec 2023 08:26:35 +0100 Subject: [PATCH 15/38] gather_first_layer_queries --- calc.py | 2 +- src/common/tests/test_math.cairo | 13 ++++++++++-- src/fri.cairo | 1 + src/fri/fri_first_layer.cairo | 34 ++++++++++++++++++++++++++++++++ src/lib.cairo | 3 +++ 5 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 src/fri/fri_first_layer.cairo diff --git a/calc.py b/calc.py index 26506aed1..242e6604b 100644 --- a/calc.py +++ b/calc.py @@ -1,3 +1,3 @@ DEFAULT_PRIME = 2**251 + 17 * 2**192 + 1 -print((pow(193456804421077096570009938751278224656090409051406060084, 193456804421077096570009938751278224656090409051406060084, DEFAULT_PRIME))) \ No newline at end of file +print((pow(3, DEFAULT_PRIME-2, DEFAULT_PRIME))) \ No newline at end of file diff --git a/src/common/tests/test_math.cairo b/src/common/tests/test_math.cairo index 5a0541ecb..61d0066ac 100644 --- a/src/common/tests/test_math.cairo +++ b/src/common/tests/test_math.cairo @@ -53,6 +53,15 @@ fn test_mul_inverse_3() { #[test] #[available_gas(9999999999)] fn test_mul_inverse_4() { + let x = 3; + let inv_x = mul_inverse(x); + assert(inv_x == 1206167596222043737899107594365023368541035738443865566657697352045290673494, 'Invalid value'); + assert(x * inv_x == 1, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_mul_inverse_5() { let x = 193456804421077096570009938751278224656090409051406060084; let inv_inv_x = mul_inverse(mul_inverse(x)); assert(x == inv_inv_x, 'Invalid value'); @@ -60,8 +69,8 @@ fn test_mul_inverse_4() { #[test] #[available_gas(9999999999)] -fn test_mul_inverse_5() { +fn test_mul_inverse_6() { let x = 19345680409051406060084; let inv_inv_x = mul_inverse(mul_inverse(x)); assert(x == inv_inv_x, 'Invalid value'); -} +} \ No newline at end of file diff --git a/src/fri.cairo b/src/fri.cairo index b13fe562a..7f57a0e6c 100644 --- a/src/fri.cairo +++ b/src/fri.cairo @@ -2,6 +2,7 @@ mod fri_formula; mod fri_group; mod fri_layer; mod fri_config; +mod fri_first_layer; mod fri_last_layer; mod fri; diff --git a/src/fri/fri_first_layer.cairo b/src/fri/fri_first_layer.cairo new file mode 100644 index 000000000..302e41128 --- /dev/null +++ b/src/fri/fri_first_layer.cairo @@ -0,0 +1,34 @@ +use core::array::SpanTrait; +use core::option::OptionTrait; +use core::array::ArrayTrait; +use core::traits::TryInto; + +use cairo_verifier::common::math; +use cairo_verifier::fri::fri_layer::FriLayerQuery; +use cairo_verifier::FIELD_GENERATOR_INV; + +fn gather_first_layer_queries( + n_queries: felt252, queries: Span, evaluations: Span, x_values: Span +) { + let mut fri_queries = ArrayTrait::::new(); + + let len: u32 = n_queries.try_into().unwrap(); + let mut i: u32 = 0; + loop { + if i == len { + break; + } + + // Translate the coset to the homogenous group to have simple FRI equations. + let shifted_x_value = *(x_values.at(i)) * FIELD_GENERATOR_INV; + + fri_queries + .append( + FriLayerQuery { + index: *(queries.at(i)), + y_value: *(evaluations.at(i)), + x_inv_value: math::mul_inverse(shifted_x_value), + } + ) + } +} diff --git a/src/lib.cairo b/src/lib.cairo index 120a0c95d..4e77912d0 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,3 +1,6 @@ +const FIELD_GENERATOR: felt252 = 3; +const FIELD_GENERATOR_INV: felt252 = 1206167596222043737899107594365023368541035738443865566657697352045290673494; + mod channel; mod common; mod structs; From b994efa1bef72fe977fd88635814a90940ae72ba Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Wed, 20 Dec 2023 10:06:20 +0100 Subject: [PATCH 16/38] fri_commit_rounds --- src/channel/channel.cairo | 25 +++++++++++----- src/fri/fri.cairo | 55 +++++++++++++++++++++++++++++++++++ src/fri/fri_first_layer.cairo | 4 ++- src/lib.cairo | 2 ++ src/table_commitment.cairo | 23 +++++++++++++++ src/vector_commitment.cairo | 19 ++++++++++++ 6 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 src/table_commitment.cairo create mode 100644 src/vector_commitment.cairo diff --git a/src/channel/channel.cairo b/src/channel/channel.cairo index 1a4997130..b7542dbe0 100644 --- a/src/channel/channel.cairo +++ b/src/channel/channel.cairo @@ -1,3 +1,4 @@ +use core::array::ArrayTrait; use cairo_verifier::common::{ flip_endiannes::FlipEndiannessTrait, to_array::ToArrayTrait, blake2s::blake2s }; @@ -30,21 +31,29 @@ impl ChannelImpl of ChannelTrait { blake2s(hash_data).flip_endiannes() } - fn random_felts_to_prover(ref self: Channel, mut n: felt252) -> Array { - let mut res = ArrayTrait::::new(); + fn random_felt_to_prover(ref self: Channel) -> felt252 { + let mut res: felt252 = 0; // To ensure a uniform distribution over field elements, if the generated 256-bit number x is in // range [0, C * PRIME), take x % PRIME. Otherwise, regenerate. // The maximal possible C is 2**256//PRIME = 31. + loop { + let rand = self.random_uint256_to_prover(); + if (rand < u256 { low: C_PRIME_AS_UINT256_LOW, high: C_PRIME_AS_UINT256_HIGH }) { + let to_append = (rand % STARK_PRIME).try_into().unwrap(); + res = to_append * INVERSE_2_TO_256_MOD_STARK_PRIME; + break; + } + }; + res + } + + fn random_felts_to_prover(ref self: Channel, mut n: felt252) -> Array { + let mut res = ArrayTrait::::new(); loop { if n != 0 { - let rand = self.random_uint256_to_prover(); - if (rand < u256 { low: C_PRIME_AS_UINT256_LOW, high: C_PRIME_AS_UINT256_HIGH }) { - n -= 1; - let to_append = (rand % STARK_PRIME).try_into().unwrap(); - res.append(to_append * INVERSE_2_TO_256_MOD_STARK_PRIME); - } + res.append(self.random_felt_to_prover()) } else { break; } diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo index 8b1378917..6a7e95ead 100644 --- a/src/fri/fri.cairo +++ b/src/fri/fri.cairo @@ -1 +1,56 @@ +use core::traits::Destruct; +use cairo_verifier::channel::channel::ChannelTrait; +use cairo_verifier::table_commitment::{ + TableCommitment, TableCommitmentConfig, TableUnsentCommitment +}; +use core::array::ArrayTrait; +use cairo_verifier::table_commitment::table_commit; +use cairo_verifier::channel::channel::Channel; +// A FRI phase with N layers starts with a single input layer. +// Afterwards, there are N - 1 inner layers resulting from FRI-folding each preceding layer. +// Each such layer has a separate table commitment, for a total of N - 1 commitments. +// Lastly, there is another FRI-folding resulting in the last FRI layer, that is commited by +// sending the polynomial coefficients, instead of a table commitment. +// Each folding has a step size. +// Illustration: +// InputLayer, no commitment. +// fold step 0 +// InnerLayer 0, Table commitment +// fold step 1 +// ... +// InnerLayer N - 2, Table commitment +// fold step N - 1 +// LastLayer, Polynomial coefficients +// +// N steps. +// N - 1 inner layers. + +// Performs FRI commitment phase rounds. Each round reads a commitment on a layer, and sends an +// evaluation point for the next round. +fn fri_commit_rounds( + ref channel: Channel, + n_layers: felt252, + configs: Span, + unsent_commitments: Span, + step_sizes: Span, + commitments: Span, +) -> (Array, Array) { + let mut commitments = ArrayTrait::::new(); + let mut eval_points = ArrayTrait::::new(); + + let mut i: u32 = 0; + let len: u32 = n_layers.try_into().unwrap(); + loop { + if i == len { + break; + } + + commitments.append(table_commit(*(unsent_commitments.at(i)), *(configs.at(i)))); + eval_points.append(channel.random_felt_to_prover()); + + i += 1; + }; + + (commitments, eval_points) +} diff --git a/src/fri/fri_first_layer.cairo b/src/fri/fri_first_layer.cairo index 302e41128..39d6e02fe 100644 --- a/src/fri/fri_first_layer.cairo +++ b/src/fri/fri_first_layer.cairo @@ -29,6 +29,8 @@ fn gather_first_layer_queries( y_value: *(evaluations.at(i)), x_inv_value: math::mul_inverse(shifted_x_value), } - ) + ); + + i += 1; } } diff --git a/src/lib.cairo b/src/lib.cairo index 4e77912d0..904271d9d 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -5,3 +5,5 @@ mod channel; mod common; mod structs; mod fri; +mod table_commitment; +mod vector_commitment; diff --git a/src/table_commitment.cairo b/src/table_commitment.cairo new file mode 100644 index 000000000..0930add4b --- /dev/null +++ b/src/table_commitment.cairo @@ -0,0 +1,23 @@ +// Commitment values for a table commitment protocol. Used to generate a commitment by "reading" +// these values from the channel. +#[derive(Drop, Copy)] +struct TableUnsentCommitment { + // vector: VectorUnsentCommitment, +} + +// Commitment for a table (n_rows x n_columns) of field elements in montgomery form. +#[derive(Drop, Copy)] +struct TableCommitment { + // config: TableCommitmentConfig*, + // vector_commitment: VectorCommitment*, +} + +#[derive(Drop, Copy)] +struct TableCommitmentConfig { + // n_columns: felt, + // vector: VectorCommitmentConfig*, +} + +fn table_commit(unsent_commitment: TableUnsentCommitment, config: TableCommitmentConfig) -> TableCommitment{ + TableCommitment{} +} \ No newline at end of file diff --git a/src/vector_commitment.cairo b/src/vector_commitment.cairo new file mode 100644 index 000000000..605431ed9 --- /dev/null +++ b/src/vector_commitment.cairo @@ -0,0 +1,19 @@ +// Commitment values for a vector commitment. Used to generate a commitment by "reading" these +// values from the channel. +#[derive(Drop)] +struct VectorUnsentCommitment { + // commitment_hash: ChannelUnsentFelt, +} + +// Commitment for a vector of field elements. +#[derive(Drop)] +struct VectorCommitment { + // config: VectorCommitmentConfig*, + // commitment_hash: ChannelSentFelt, +} + +#[derive(Drop)] +struct VectorCommitmentConfig { + // height: felt, + // n_verifier_friendly_commitment_layers: felt, +} From 0cd73e9b60d3ae227e406b062a1eae7f42308dd7 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Wed, 20 Dec 2023 10:10:32 +0100 Subject: [PATCH 17/38] channel bug fix --- src/channel/channel.cairo | 3 ++- src/common/tests/test_math.cairo | 7 +++++-- src/lib.cairo | 3 ++- src/table_commitment.cairo | 11 ++++++++--- src/vector_commitment.cairo | 3 +++ 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/channel/channel.cairo b/src/channel/channel.cairo index b7542dbe0..120fbbeeb 100644 --- a/src/channel/channel.cairo +++ b/src/channel/channel.cairo @@ -53,7 +53,8 @@ impl ChannelImpl of ChannelTrait { let mut res = ArrayTrait::::new(); loop { if n != 0 { - res.append(self.random_felt_to_prover()) + res.append(self.random_felt_to_prover()); + n -= 1; } else { break; } diff --git a/src/common/tests/test_math.cairo b/src/common/tests/test_math.cairo index 61d0066ac..0ddceec9e 100644 --- a/src/common/tests/test_math.cairo +++ b/src/common/tests/test_math.cairo @@ -55,7 +55,10 @@ fn test_mul_inverse_3() { fn test_mul_inverse_4() { let x = 3; let inv_x = mul_inverse(x); - assert(inv_x == 1206167596222043737899107594365023368541035738443865566657697352045290673494, 'Invalid value'); + assert( + inv_x == 1206167596222043737899107594365023368541035738443865566657697352045290673494, + 'Invalid value' + ); assert(x * inv_x == 1, 'Invalid value'); } @@ -73,4 +76,4 @@ fn test_mul_inverse_6() { let x = 19345680409051406060084; let inv_inv_x = mul_inverse(mul_inverse(x)); assert(x == inv_inv_x, 'Invalid value'); -} \ No newline at end of file +} diff --git a/src/lib.cairo b/src/lib.cairo index 904271d9d..d6e811a6c 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,5 +1,6 @@ const FIELD_GENERATOR: felt252 = 3; -const FIELD_GENERATOR_INV: felt252 = 1206167596222043737899107594365023368541035738443865566657697352045290673494; +const FIELD_GENERATOR_INV: felt252 = + 1206167596222043737899107594365023368541035738443865566657697352045290673494; mod channel; mod common; diff --git a/src/table_commitment.cairo b/src/table_commitment.cairo index 0930add4b..38b38deda 100644 --- a/src/table_commitment.cairo +++ b/src/table_commitment.cairo @@ -2,22 +2,27 @@ // these values from the channel. #[derive(Drop, Copy)] struct TableUnsentCommitment { + a: felt252, // dummy // vector: VectorUnsentCommitment, } // Commitment for a table (n_rows x n_columns) of field elements in montgomery form. #[derive(Drop, Copy)] struct TableCommitment { + a: felt252, // dummy // config: TableCommitmentConfig*, // vector_commitment: VectorCommitment*, } #[derive(Drop, Copy)] struct TableCommitmentConfig { + a: felt252, // dummy // n_columns: felt, // vector: VectorCommitmentConfig*, } -fn table_commit(unsent_commitment: TableUnsentCommitment, config: TableCommitmentConfig) -> TableCommitment{ - TableCommitment{} -} \ No newline at end of file +fn table_commit( + unsent_commitment: TableUnsentCommitment, config: TableCommitmentConfig +) -> TableCommitment { + TableCommitment {a: 0} +} diff --git a/src/vector_commitment.cairo b/src/vector_commitment.cairo index 605431ed9..10ee68797 100644 --- a/src/vector_commitment.cairo +++ b/src/vector_commitment.cairo @@ -2,18 +2,21 @@ // values from the channel. #[derive(Drop)] struct VectorUnsentCommitment { + a: felt252, // dummy // commitment_hash: ChannelUnsentFelt, } // Commitment for a vector of field elements. #[derive(Drop)] struct VectorCommitment { + a: felt252, // dummy // config: VectorCommitmentConfig*, // commitment_hash: ChannelSentFelt, } #[derive(Drop)] struct VectorCommitmentConfig { + a: felt252, // dummy // height: felt, // n_verifier_friendly_commitment_layers: felt, } From da9c2d37b53cccc912fa9d723d90d5d579bf53d7 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Wed, 20 Dec 2023 10:11:02 +0100 Subject: [PATCH 18/38] fmt --- src/table_commitment.cairo | 12 ++++++------ src/vector_commitment.cairo | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/table_commitment.cairo b/src/table_commitment.cairo index 38b38deda..58703ed65 100644 --- a/src/table_commitment.cairo +++ b/src/table_commitment.cairo @@ -3,26 +3,26 @@ #[derive(Drop, Copy)] struct TableUnsentCommitment { a: felt252, // dummy - // vector: VectorUnsentCommitment, +// vector: VectorUnsentCommitment, } // Commitment for a table (n_rows x n_columns) of field elements in montgomery form. #[derive(Drop, Copy)] struct TableCommitment { a: felt252, // dummy - // config: TableCommitmentConfig*, - // vector_commitment: VectorCommitment*, +// config: TableCommitmentConfig*, +// vector_commitment: VectorCommitment*, } #[derive(Drop, Copy)] struct TableCommitmentConfig { a: felt252, // dummy - // n_columns: felt, - // vector: VectorCommitmentConfig*, +// n_columns: felt, +// vector: VectorCommitmentConfig*, } fn table_commit( unsent_commitment: TableUnsentCommitment, config: TableCommitmentConfig ) -> TableCommitment { - TableCommitment {a: 0} + TableCommitment { a: 0 } } diff --git a/src/vector_commitment.cairo b/src/vector_commitment.cairo index 10ee68797..e4f29a321 100644 --- a/src/vector_commitment.cairo +++ b/src/vector_commitment.cairo @@ -3,20 +3,20 @@ #[derive(Drop)] struct VectorUnsentCommitment { a: felt252, // dummy - // commitment_hash: ChannelUnsentFelt, +// commitment_hash: ChannelUnsentFelt, } // Commitment for a vector of field elements. #[derive(Drop)] struct VectorCommitment { a: felt252, // dummy - // config: VectorCommitmentConfig*, - // commitment_hash: ChannelSentFelt, +// config: VectorCommitmentConfig*, +// commitment_hash: ChannelSentFelt, } #[derive(Drop)] struct VectorCommitmentConfig { a: felt252, // dummy - // height: felt, - // n_verifier_friendly_commitment_layers: felt, +// height: felt, +// n_verifier_friendly_commitment_layers: felt, } From 20a720d777b1a3c465f52d0112c02ddc5e6086d8 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Wed, 20 Dec 2023 12:33:33 +0100 Subject: [PATCH 19/38] refactor --- src/fri/fri_config.cairo | 10 ++-------- src/structs.cairo | 2 -- src/structs/stark_config.cairo | 2 +- src/structs/table_commitment_config.cairo | 7 ------- src/structs/traces_config.cairo | 2 +- src/structs/vector_commitment_config.cairo | 5 ----- src/table_commitment.cairo | 7 ++++--- src/vector_commitment.cairo | 17 +++++++++++------ 8 files changed, 19 insertions(+), 33 deletions(-) delete mode 100644 src/structs/table_commitment_config.cairo delete mode 100644 src/structs/vector_commitment_config.cairo diff --git a/src/fri/fri_config.cairo b/src/fri/fri_config.cairo index a6e942811..4f4fb4e60 100644 --- a/src/fri/fri_config.cairo +++ b/src/fri/fri_config.cairo @@ -2,8 +2,8 @@ use core::array::ArrayTrait; use core::option::OptionTrait; use core::array::SpanTrait; use core::traits::Into; -use cairo_verifier::structs::table_commitment_config::TableCommitmentConfig; -use cairo_verifier::structs::vector_commitment_config::VectorCommitmentConfig; +use cairo_verifier::table_commitment::TableCommitmentConfig; +use cairo_verifier::vector_commitment::{validate_vector_commitment, VectorCommitmentConfig}; const MAX_LAST_LAYER_LOG_DEGREE_BOUND: u32 = 15; const MAX_FRI_LAYERS: u32 = 15; @@ -69,9 +69,3 @@ fn fri_config_validate( log_expected_input_degree } -// ghost functions -fn validate_vector_commitment( - config: VectorCommitmentConfig, - expected_height: felt252, - n_verifier_friendly_commitment_layers: felt252, -) {} diff --git a/src/structs.cairo b/src/structs.cairo index 000d62f6e..b421df63d 100644 --- a/src/structs.cairo +++ b/src/structs.cairo @@ -1,8 +1,6 @@ mod proof_of_work_config; mod stark_config; mod stark_proof; -mod table_commitment_config; mod traces_config; mod unsent_commitment; -mod vector_commitment_config; mod witness; diff --git a/src/structs/stark_config.cairo b/src/structs/stark_config.cairo index 9e960da6b..68cae99dd 100644 --- a/src/structs/stark_config.cairo +++ b/src/structs/stark_config.cairo @@ -1,5 +1,5 @@ use cairo_verifier::structs::traces_config::TracesConfig; -use cairo_verifier::structs::table_commitment_config::TableCommitmentConfig; +use cairo_verifier::table_commitment::TableCommitmentConfig; use cairo_verifier::fri::fri_config::FriConfig; use cairo_verifier::structs::proof_of_work_config::ProofOfWorkConfig; diff --git a/src/structs/table_commitment_config.cairo b/src/structs/table_commitment_config.cairo deleted file mode 100644 index 30238bfed..000000000 --- a/src/structs/table_commitment_config.cairo +++ /dev/null @@ -1,7 +0,0 @@ -use cairo_verifier::structs::vector_commitment_config::VectorCommitmentConfig; - -#[derive(Drop, Copy)] -struct TableCommitmentConfig { - columns: felt252, - vector: VectorCommitmentConfig -} diff --git a/src/structs/traces_config.cairo b/src/structs/traces_config.cairo index f3c741fed..7cbf55fe7 100644 --- a/src/structs/traces_config.cairo +++ b/src/structs/traces_config.cairo @@ -1,4 +1,4 @@ -use cairo_verifier::structs::table_commitment_config::TableCommitmentConfig; +use cairo_verifier::table_commitment::TableCommitmentConfig; struct TracesConfig { original: TableCommitmentConfig, diff --git a/src/structs/vector_commitment_config.cairo b/src/structs/vector_commitment_config.cairo deleted file mode 100644 index b7079ed6a..000000000 --- a/src/structs/vector_commitment_config.cairo +++ /dev/null @@ -1,5 +0,0 @@ -#[derive(Drop, Copy)] -struct VectorCommitmentConfig { - height: felt252, - verifier_friendly_commitment_layers: felt252, -} diff --git a/src/table_commitment.cairo b/src/table_commitment.cairo index 58703ed65..2fb6b4a06 100644 --- a/src/table_commitment.cairo +++ b/src/table_commitment.cairo @@ -1,3 +1,5 @@ +use cairo_verifier::vector_commitment::VectorCommitmentConfig; + // Commitment values for a table commitment protocol. Used to generate a commitment by "reading" // these values from the channel. #[derive(Drop, Copy)] @@ -16,9 +18,8 @@ struct TableCommitment { #[derive(Drop, Copy)] struct TableCommitmentConfig { - a: felt252, // dummy -// n_columns: felt, -// vector: VectorCommitmentConfig*, + columns: felt252, + vector: VectorCommitmentConfig } fn table_commit( diff --git a/src/vector_commitment.cairo b/src/vector_commitment.cairo index e4f29a321..485207203 100644 --- a/src/vector_commitment.cairo +++ b/src/vector_commitment.cairo @@ -1,22 +1,27 @@ // Commitment values for a vector commitment. Used to generate a commitment by "reading" these // values from the channel. -#[derive(Drop)] +#[derive(Drop, Copy)] struct VectorUnsentCommitment { a: felt252, // dummy // commitment_hash: ChannelUnsentFelt, } // Commitment for a vector of field elements. -#[derive(Drop)] +#[derive(Drop, Copy)] struct VectorCommitment { a: felt252, // dummy // config: VectorCommitmentConfig*, // commitment_hash: ChannelSentFelt, } -#[derive(Drop)] +#[derive(Drop, Copy)] struct VectorCommitmentConfig { - a: felt252, // dummy -// height: felt, -// n_verifier_friendly_commitment_layers: felt, + height: felt252, + verifier_friendly_commitment_layers: felt252, } + +fn validate_vector_commitment( + config: VectorCommitmentConfig, + expected_height: felt252, + n_verifier_friendly_commitment_layers: felt252, +) {} From 4370950eb5a06c767140f4c27e1798487b01c063 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Wed, 20 Dec 2023 19:27:38 +0100 Subject: [PATCH 20/38] fri_commit --- src/channel/channel.cairo | 23 +++++++++++++++++ src/fri/fri.cairo | 54 ++++++++++++++++++++++++++++++++++++++- src/fri/fri_config.cairo | 4 +-- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/channel/channel.cairo b/src/channel/channel.cairo index 120fbbeeb..7e3375ef7 100644 --- a/src/channel/channel.cairo +++ b/src/channel/channel.cairo @@ -17,6 +17,20 @@ struct Channel { counter: u256, } +// A wrapper around felt with a guarantee that the felt must be read from the channel before +// use. +#[derive(Drop)] +struct ChannelUnsentFelt { + value: felt252, +} + +// A wrapper around felt with a guarantee that the felt was read from the channel as data from the +// prover. +#[derive(Drop)] +struct ChannelSentFelt { + value: felt252, +} + #[generate_trait] impl ChannelImpl of ChannelTrait { fn new(digest: u256) -> Channel { @@ -61,4 +75,13 @@ impl ChannelImpl of ChannelTrait { }; res } + + // Reads a field element vector from the prover. Unlike read_felts_from_prover, this hashes all the + // field elements at once. See Channel. + fn read_felt_vector_from_prover( + ref self: Channel, values: Span + ) -> Array { + let sent_felts = ArrayTrait::::new(); + sent_felts + } } diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo index 6a7e95ead..2400653be 100644 --- a/src/fri/fri.cairo +++ b/src/fri/fri.cairo @@ -1,3 +1,4 @@ +use core::array::SpanTrait; use core::traits::Destruct; use cairo_verifier::channel::channel::ChannelTrait; use cairo_verifier::table_commitment::{ @@ -6,6 +7,32 @@ use cairo_verifier::table_commitment::{ use core::array::ArrayTrait; use cairo_verifier::table_commitment::table_commit; use cairo_verifier::channel::channel::Channel; +use cairo_verifier::channel::channel::{ChannelUnsentFelt, ChannelSentFelt}; +use cairo_verifier::fri::fri_config::FriConfig; +use cairo_verifier::common::math; + +// Commitment values for FRI. Used to generate a commitment by "reading" these values +// from the channel. +#[derive(Drop, Copy)] +struct FriUnsentCommitment { + // Array of size n_layers - 1 containing unsent table commitments for each inner layer. + inner_layers: Span, + // Array of size 2**log_last_layer_degree_bound containing coefficients for the last layer + // polynomial. + last_layer_coefficients: Span, +} + +#[derive(Drop, Copy)] +struct FriCommitment { + config: FriConfig, + // Array of size n_layers - 1 containing table commitments for each inner layer. + inner_layers: Span, + // Array of size n_layers, of one evaluation point for each layer. + eval_points: Span, + // Array of size 2**log_last_layer_degree_bound containing coefficients for the last layer + // polynomial. + last_layer_coefficients: Span, +} // A FRI phase with N layers starts with a single input layer. // Afterwards, there are N - 1 inner layers resulting from FRI-folding each preceding layer. @@ -34,7 +61,6 @@ fn fri_commit_rounds( configs: Span, unsent_commitments: Span, step_sizes: Span, - commitments: Span, ) -> (Array, Array) { let mut commitments = ArrayTrait::::new(); let mut eval_points = ArrayTrait::::new(); @@ -54,3 +80,29 @@ fn fri_commit_rounds( (commitments, eval_points) } + +fn fri_commit( + ref channel: Channel, unsent_commitment: FriUnsentCommitment, config: FriConfig +) -> FriCommitment { + assert((*config.fri_step_sizes.at(0)) == 0, 'Invalid value'); + + let (commitments, eval_points) = fri_commit_rounds( + ref channel, + config.n_layers, + config.inner_layers, + unsent_commitment.inner_layers, + config.fri_step_sizes, + ); + + // Read last layer coefficients. + let n_coefficients = math::pow(2, config.log_last_layer_degree_bound); + let coefficients = channel + .read_felt_vector_from_prover(unsent_commitment.last_layer_coefficients); + + FriCommitment { + config: config, + inner_layers: commitments.span(), + eval_points: eval_points.span(), + last_layer_coefficients: coefficients.span() + } +} diff --git a/src/fri/fri_config.cairo b/src/fri/fri_config.cairo index 4f4fb4e60..e101a5dd9 100644 --- a/src/fri/fri_config.cairo +++ b/src/fri/fri_config.cairo @@ -9,7 +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)] +#[derive(Drop, Copy)] struct FriConfig { // Log2 of the size of the input layer to FRI. log_input_size: felt252, @@ -17,7 +17,7 @@ struct FriConfig { 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, + inner_layers: Span, // 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: Span, From c20d5d389fca6f00d7f5c2421a703d4ab493c16f Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Thu, 21 Dec 2023 08:49:28 +0100 Subject: [PATCH 21/38] refactor&fri development --- src/channel/channel.cairo | 4 +- src/fri/fri.cairo | 76 +++++++++++++++++++++++++++++++++++ src/fri/fri_config.cairo | 2 +- src/fri/fri_first_layer.cairo | 10 +++-- src/table_commitment.cairo | 67 +++++++++++++++++++++++++----- src/vector_commitment.cairo | 21 +++++++--- 6 files changed, 158 insertions(+), 22 deletions(-) diff --git a/src/channel/channel.cairo b/src/channel/channel.cairo index 7e3375ef7..01fa04967 100644 --- a/src/channel/channel.cairo +++ b/src/channel/channel.cairo @@ -19,14 +19,14 @@ struct Channel { // A wrapper around felt with a guarantee that the felt must be read from the channel before // use. -#[derive(Drop)] +#[derive(Drop, Copy)] struct ChannelUnsentFelt { value: felt252, } // A wrapper around felt with a guarantee that the felt was read from the channel as data from the // prover. -#[derive(Drop)] +#[derive(Drop, Copy)] struct ChannelSentFelt { value: felt252, } diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo index 2400653be..3b0baa559 100644 --- a/src/fri/fri.cairo +++ b/src/fri/fri.cairo @@ -1,3 +1,5 @@ +use core::option::OptionTrait; +use core::traits::TryInto; use core::array::SpanTrait; use core::traits::Destruct; use cairo_verifier::channel::channel::ChannelTrait; @@ -10,6 +12,10 @@ use cairo_verifier::channel::channel::Channel; use cairo_verifier::channel::channel::{ChannelUnsentFelt, ChannelSentFelt}; use cairo_verifier::fri::fri_config::FriConfig; use cairo_verifier::common::math; +use cairo_verifier::table_commitment::TableCommitmentWitness; +use cairo_verifier::fri::fri_first_layer::gather_first_layer_queries; +use cairo_verifier::fri::fri_group::get_fri_group; +use cairo_verifier::fri::fri_layer::FriLayerQuery; // Commitment values for FRI. Used to generate a commitment by "reading" these values // from the channel. @@ -34,6 +40,35 @@ struct FriCommitment { last_layer_coefficients: Span, } +#[derive(Drop, Copy)] +struct FriDecommitment { + // Number of queries. + n_values: felt252, + // Array of size n_values, containing the values of the input layer at query indices. + values: Span, + // Array of size n_values, containing the field elements that correspond to the query indices + // (See queries_to_points). + points: Span, +} + +// A witness for the decommitment of the FRI layers over queries. +#[derive(Drop, Copy)] +struct FriWitness { + // An array of size n_layers - 1, containing a witness for each inner layer. + layers: Span, +} + +// A witness for a single FRI layer. This witness is required to verify the transition from an +// inner layer to the following layer. +#[derive(Drop, Copy)] +struct FriLayerWitness { + // Values for the sibling leaves required for decommitment. + n_leaves: felt252, + leaves: Span, + // Table commitment witnesses for decommiting all the leaves. + table_witness: TableCommitmentWitness, +} + // A FRI phase with N layers starts with a single input layer. // Afterwards, there are N - 1 inner layers resulting from FRI-folding each preceding layer. // Each such layer has a separate table commitment, for a total of N - 1 commitments. @@ -106,3 +141,44 @@ fn fri_commit( last_layer_coefficients: coefficients.span() } } + +fn fri_decommit_layers( + fri_group: Span, + n_layers: felt252, + commitment: Span, + layer_witness: Span, + eval_points: Span, + step_sizes: Span, + queries: Span, +) -> Array { + let last_queries = ArrayTrait::::new(); + let len: u32 = n_layers.try_into().unwrap(); + let mut i: u32 = 0; + + loop { + if i == len { + break; + } + // + + }; + + last_queries +} + +// FRI protocol component decommitment. +fn fri_decommit( + queries: Span, + commitment: FriCommitment, + decommitment: FriDecommitment, + witness: FriWitness, +) { + assert(queries.len().into() == decommitment.n_values, 'Invalid value'); + let fri_first_layer_evaluations = decommitment.values; + + let fri_queries = gather_first_layer_queries( + queries, decommitment.values, decommitment.points, + ); + + let fri_group = get_fri_group(); +} diff --git a/src/fri/fri_config.cairo b/src/fri/fri_config.cairo index e101a5dd9..1f4016216 100644 --- a/src/fri/fri_config.cairo +++ b/src/fri/fri_config.cairo @@ -53,7 +53,7 @@ fn fri_config_validate( let fri_step_u32: u32 = fri_step.try_into().unwrap(); assert(1_u32 <= fri_step_u32, 'Invalid value'); assert(fri_step_u32 <= MAX_FRI_STEP + 1, 'Invalid value'); - assert(table_commitment.columns == fri_step * fri_step, 'Invalid value'); + assert(table_commitment.n_columns == fri_step * fri_step, 'Invalid value'); i += 1; log_input_size -= fri_step; diff --git a/src/fri/fri_first_layer.cairo b/src/fri/fri_first_layer.cairo index 39d6e02fe..0253d56e0 100644 --- a/src/fri/fri_first_layer.cairo +++ b/src/fri/fri_first_layer.cairo @@ -8,11 +8,11 @@ use cairo_verifier::fri::fri_layer::FriLayerQuery; use cairo_verifier::FIELD_GENERATOR_INV; fn gather_first_layer_queries( - n_queries: felt252, queries: Span, evaluations: Span, x_values: Span -) { + queries: Span, evaluations: Span, x_values: Span +) -> Array { let mut fri_queries = ArrayTrait::::new(); - let len: u32 = n_queries.try_into().unwrap(); + let len: u32 = queries.len(); let mut i: u32 = 0; loop { if i == len { @@ -32,5 +32,7 @@ fn gather_first_layer_queries( ); i += 1; - } + }; + + fri_queries } diff --git a/src/table_commitment.cairo b/src/table_commitment.cairo index 2fb6b4a06..a0189fccb 100644 --- a/src/table_commitment.cairo +++ b/src/table_commitment.cairo @@ -1,29 +1,78 @@ -use cairo_verifier::vector_commitment::VectorCommitmentConfig; +use cairo_verifier::vector_commitment::{VectorCommitmentConfig, VectorUnsentCommitment, VectorCommitment, VectorCommitmentWitness}; +use cairo_verifier::channel::channel::ChannelSentFelt; // Commitment values for a table commitment protocol. Used to generate a commitment by "reading" // these values from the channel. #[derive(Drop, Copy)] struct TableUnsentCommitment { - a: felt252, // dummy -// vector: VectorUnsentCommitment, + vector: VectorUnsentCommitment, } // Commitment for a table (n_rows x n_columns) of field elements in montgomery form. #[derive(Drop, Copy)] struct TableCommitment { - a: felt252, // dummy -// config: TableCommitmentConfig*, -// vector_commitment: VectorCommitment*, + config: TableCommitmentConfig, + vector_commitment: VectorCommitment, } #[derive(Drop, Copy)] struct TableCommitmentConfig { - columns: felt252, - vector: VectorCommitmentConfig + n_columns: felt252, + vector: VectorCommitmentConfig, +} + +// Responses for queries to the table commitment. +// Each query corresponds to a full row of the table. +#[derive(Drop, Copy)] +struct TableDecommitment { + // n_columns * n_queries values to decommit. + n_values: felt252, + values: Span, +} + +// Witness for a decommitment over queries. +#[derive(Drop, Copy)] +struct TableCommitmentWitness { + vector: VectorCommitmentWitness, } fn table_commit( unsent_commitment: TableUnsentCommitment, config: TableCommitmentConfig ) -> TableCommitment { - TableCommitment { a: 0 } + TableCommitment { + config: TableCommitmentConfig { + n_columns: 0, + vector: VectorCommitmentConfig { + height: 0, + n_verifier_friendly_commitment_layers: 0, + } + }, + vector_commitment: VectorCommitment { + config: VectorCommitmentConfig { + height: 0, + n_verifier_friendly_commitment_layers: 0, + }, + commitment_hash: ChannelSentFelt { + value: 0, + } + } + } } + +// Decommits a TableCommitment at multiple indices. +// rows must be sorted and unique. +// Args: +// commitment - the table commitment. +// n_queries - number of queries to decommit. +// queries - the claimed indices. +// decommitment - the claimed values at those indices. +// witness - the decommitment witness. +fn table_decommit( + commitment: TableCommitment, + n_queries: felt252, + queries: felt252, + decommitment: TableDecommitment, + witness: TableCommitmentWitness, +) { + +} \ No newline at end of file diff --git a/src/vector_commitment.cairo b/src/vector_commitment.cairo index 485207203..a6c9e6ed7 100644 --- a/src/vector_commitment.cairo +++ b/src/vector_commitment.cairo @@ -1,23 +1,32 @@ +use cairo_verifier::channel::channel::{ChannelSentFelt, ChannelUnsentFelt}; + // Commitment values for a vector commitment. Used to generate a commitment by "reading" these // values from the channel. #[derive(Drop, Copy)] struct VectorUnsentCommitment { - a: felt252, // dummy -// commitment_hash: ChannelUnsentFelt, + commitment_hash: ChannelUnsentFelt, } // Commitment for a vector of field elements. #[derive(Drop, Copy)] struct VectorCommitment { - a: felt252, // dummy -// config: VectorCommitmentConfig*, -// commitment_hash: ChannelSentFelt, + config: VectorCommitmentConfig, + commitment_hash: ChannelSentFelt, } #[derive(Drop, Copy)] struct VectorCommitmentConfig { height: felt252, - verifier_friendly_commitment_layers: felt252, + n_verifier_friendly_commitment_layers: felt252, +} + +// Witness for a decommitment over queries. +#[derive(Drop, Copy)] +struct VectorCommitmentWitness { + // The authentication values: all the siblings of the subtree generated by the queried indices, + // bottom layer up, left to right. + n_authentications: felt252, + authentications: Span, } fn validate_vector_commitment( From 0d2d9ec0e8546cffe2bf405e7128b3cc4de8f15d Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Thu, 21 Dec 2023 09:35:46 +0100 Subject: [PATCH 22/38] fri_decommit skaffold --- src/fri/fri.cairo | 40 +++++++++++++++++++++++++++++++++----- src/fri/fri_layer.cairo | 21 ++++++-------------- src/table_commitment.cairo | 26 ++++++++----------------- 3 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo index 3b0baa559..83627c040 100644 --- a/src/fri/fri.cairo +++ b/src/fri/fri.cairo @@ -7,15 +7,15 @@ use cairo_verifier::table_commitment::{ TableCommitment, TableCommitmentConfig, TableUnsentCommitment }; use core::array::ArrayTrait; -use cairo_verifier::table_commitment::table_commit; +use cairo_verifier::table_commitment::{table_commit, table_decommit}; use cairo_verifier::channel::channel::Channel; use cairo_verifier::channel::channel::{ChannelUnsentFelt, ChannelSentFelt}; use cairo_verifier::fri::fri_config::FriConfig; use cairo_verifier::common::math; -use cairo_verifier::table_commitment::TableCommitmentWitness; +use cairo_verifier::table_commitment::{TableCommitmentWitness, TableDecommitment}; use cairo_verifier::fri::fri_first_layer::gather_first_layer_queries; use cairo_verifier::fri::fri_group::get_fri_group; -use cairo_verifier::fri::fri_layer::FriLayerQuery; +use cairo_verifier::fri::fri_layer::{FriLayerQuery, FriLayerComputationParams, compute_next_layer}; // Commitment values for FRI. Used to generate a commitment by "reading" these values // from the channel. @@ -149,7 +149,7 @@ fn fri_decommit_layers( layer_witness: Span, eval_points: Span, step_sizes: Span, - queries: Span, + mut queries: Span, ) -> Array { let last_queries = ArrayTrait::::new(); let len: u32 = n_layers.try_into().unwrap(); @@ -159,8 +159,28 @@ fn fri_decommit_layers( if i == len { break; } - // + // Params. + let coset_size = math::pow(2, *(step_sizes.at(i))); + let params = FriLayerComputationParams { + coset_size: coset_size, fri_group: fri_group, eval_point: *(eval_points.at(i)) + }; + + // Compute next layer queries. + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries, *(layer_witness.at(i)).leaves, params + ); + queries = next_queries.span(); + + // Table decommitment. + table_decommit( + *commitment.at(i), + verify_indices.span(), + TableDecommitment { values: verify_y_values.span() }, + *layer_witness.at(i).table_witness + ); + + i += 1; }; last_queries @@ -181,4 +201,14 @@ fn fri_decommit( ); let fri_group = get_fri_group(); + + let last_queries = fri_decommit_layers( + fri_group.span(), + commitment.config.n_layers - 1, + commitment.inner_layers, + witness.layers, + commitment.eval_points.slice(1, commitment.eval_points.len() - 1), + commitment.config.fri_step_sizes.slice(1, commitment.config.fri_step_sizes.len() - 1), + fri_queries.span(), + ); } diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index 05a8b8f9b..37cce1f08 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -34,7 +34,6 @@ struct FriLayerQuery { // query was consumed by this function. fn compute_coset_elements( - mut n_queries: felt252, queries: Span, sibling_witness: Span, coset_size: felt252, @@ -45,6 +44,7 @@ fn compute_coset_elements( let mut coset_elements = ArrayTrait::::new(); let mut coset_x_inv: felt252 = 0; + let len = queries.len(); let mut i: u32 = 0; let mut j: u32 = 0; @@ -53,10 +53,9 @@ fn compute_coset_elements( break; } - if n_queries != 0 && *(queries.at(i)).index == coset_start_index + offset_within_coset { + if i != len && *(queries.at(i)).index == coset_start_index + offset_within_coset { coset_elements.append(*(queries.at(i)).y_value); coset_x_inv = (*(queries.at(i)).x_inv_value) * (*(fri_group.at(i))); - n_queries -= 1; i += 1; } else { coset_elements.append(*(sibling_witness.at(j))); @@ -81,10 +80,7 @@ fn compute_coset_elements( // - 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, - sibling_witness: Span, - params: FriLayerComputationParams, + queries: Span, sibling_witness: Span, params: FriLayerComputationParams, ) -> (Array, Array, Array) { let mut next_queries = ArrayTrait::::new(); let mut verify_indices = ArrayTrait::::new(); @@ -92,9 +88,10 @@ fn compute_next_layer( let coset_size = params.coset_size; + let len = queries.len(); let mut i: u32 = 0; loop { - if n_queries == 0 { + if i == len { break; } @@ -104,13 +101,7 @@ fn compute_next_layer( 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 + queries, sibling_witness, coset_size, coset_index * coset_size, 0, params.fri_group ); let coset_elements_len = coset_elements.len(); diff --git a/src/table_commitment.cairo b/src/table_commitment.cairo index a0189fccb..d5dbf77eb 100644 --- a/src/table_commitment.cairo +++ b/src/table_commitment.cairo @@ -1,4 +1,6 @@ -use cairo_verifier::vector_commitment::{VectorCommitmentConfig, VectorUnsentCommitment, VectorCommitment, VectorCommitmentWitness}; +use cairo_verifier::vector_commitment::{ + VectorCommitmentConfig, VectorUnsentCommitment, VectorCommitment, VectorCommitmentWitness +}; use cairo_verifier::channel::channel::ChannelSentFelt; // Commitment values for a table commitment protocol. Used to generate a commitment by "reading" @@ -26,7 +28,6 @@ struct TableCommitmentConfig { #[derive(Drop, Copy)] struct TableDecommitment { // n_columns * n_queries values to decommit. - n_values: felt252, values: Span, } @@ -42,19 +43,11 @@ fn table_commit( TableCommitment { config: TableCommitmentConfig { n_columns: 0, - vector: VectorCommitmentConfig { - height: 0, - n_verifier_friendly_commitment_layers: 0, - } + vector: VectorCommitmentConfig { height: 0, n_verifier_friendly_commitment_layers: 0, } }, vector_commitment: VectorCommitment { - config: VectorCommitmentConfig { - height: 0, - n_verifier_friendly_commitment_layers: 0, - }, - commitment_hash: ChannelSentFelt { - value: 0, - } + config: VectorCommitmentConfig { height: 0, n_verifier_friendly_commitment_layers: 0, }, + commitment_hash: ChannelSentFelt { value: 0, } } } } @@ -69,10 +62,7 @@ fn table_commit( // witness - the decommitment witness. fn table_decommit( commitment: TableCommitment, - n_queries: felt252, - queries: felt252, + queries: Span, decommitment: TableDecommitment, witness: TableCommitmentWitness, -) { - -} \ No newline at end of file +) {} From d4a870ab66fecc75ed70baa43268e80812f11e8f Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Thu, 21 Dec 2023 09:50:07 +0100 Subject: [PATCH 23/38] fri_decommit developed -> audit --- src/common/horner_eval.cairo | 6 ++- src/common/tests/test_horner_eval.cairo | 49 +++++++++++++------------ src/fri/fri.cairo | 16 +++++++- src/fri/fri_last_layer.cairo | 9 +++-- 4 files changed, 49 insertions(+), 31 deletions(-) diff --git a/src/common/horner_eval.cairo b/src/common/horner_eval.cairo index 44af52857..2e05dd81a 100644 --- a/src/common/horner_eval.cairo +++ b/src/common/horner_eval.cairo @@ -1,15 +1,17 @@ +use cairo_verifier::channel::channel::ChannelSentFelt; + // `horner_eval` is a function that evaluates a polynomial at a given point using Horner's method. // `coefs` is an array of coefficients representing the polynomial in the format a0, a1, a2, ... an. // `point` is the value at which the polynomial will be evaluated. // The function returns the polynomial evaluation as `felt252`. -fn horner_eval(coefs: Span, point: felt252) -> felt252 { +fn horner_eval(coefs: Span, point: felt252) -> felt252 { let mut res = 0; let mut i = coefs.len(); loop { if i != 0 { i -= 1; - res = *coefs.at(i) + point * res; + res = (*(coefs.at(i))).value + point * res; } else { break; } diff --git a/src/common/tests/test_horner_eval.cairo b/src/common/tests/test_horner_eval.cairo index c543a79c1..adca05150 100644 --- a/src/common/tests/test_horner_eval.cairo +++ b/src/common/tests/test_horner_eval.cairo @@ -1,10 +1,11 @@ use core::array::ArrayTrait; +use cairo_verifier::channel::channel::ChannelSentFelt; use cairo_verifier::common::horner_eval::horner_eval; #[test] #[available_gas(9999999999)] fn test_horner_eval_0() { - let mut coefs = ArrayTrait::::new(); + let mut coefs = ArrayTrait::::new(); let eval = horner_eval(coefs.span(), 1); assert(eval == 0, 'invalid evaluation result'); } @@ -12,8 +13,8 @@ fn test_horner_eval_0() { #[test] #[available_gas(9999999999)] fn test_horner_eval_1() { - let mut coefs = ArrayTrait::::new(); - coefs.append(1); + let mut coefs = ArrayTrait::::new(); + coefs.append(ChannelSentFelt { value: 1 }); let eval = horner_eval(coefs.span(), 7); assert(eval == 1, 'invalid evaluation result'); } @@ -21,12 +22,12 @@ fn test_horner_eval_1() { #[test] #[available_gas(9999999999)] fn test_horner_eval_2() { - let mut coefs = ArrayTrait::::new(); - coefs.append(4); - coefs.append(10); - coefs.append(19); - coefs.append(1); - coefs.append(9); + let mut coefs = ArrayTrait::::new(); + coefs.append(ChannelSentFelt { value: 4 }); + coefs.append(ChannelSentFelt { value: 10 }); + coefs.append(ChannelSentFelt { value: 19 }); + coefs.append(ChannelSentFelt { value: 1 }); + coefs.append(ChannelSentFelt { value: 9 }); let eval = horner_eval(coefs.span(), 13); assert(eval == 262591, 'invalid evaluation result'); } @@ -34,21 +35,21 @@ fn test_horner_eval_2() { #[test] #[available_gas(9999999999)] fn test_horner_eval_3() { - let mut coefs = ArrayTrait::::new(); - coefs.append(4); - coefs.append(10); - coefs.append(19); - coefs.append(1); - coefs.append(9); - coefs.append(99); - coefs.append(1); - coefs.append(7); - coefs.append(13); - coefs.append(2); - coefs.append(5); - coefs.append(7); - coefs.append(111); - coefs.append(1); + let mut coefs = ArrayTrait::::new(); + coefs.append(ChannelSentFelt { value: 4 }); + coefs.append(ChannelSentFelt { value: 10 }); + coefs.append(ChannelSentFelt { value: 19 }); + coefs.append(ChannelSentFelt { value: 1 }); + coefs.append(ChannelSentFelt { value: 9 }); + coefs.append(ChannelSentFelt { value: 99 }); + coefs.append(ChannelSentFelt { value: 1 }); + coefs.append(ChannelSentFelt { value: 7 }); + coefs.append(ChannelSentFelt { value: 13 }); + coefs.append(ChannelSentFelt { value: 2 }); + coefs.append(ChannelSentFelt { value: 5 }); + coefs.append(ChannelSentFelt { value: 7 }); + coefs.append(ChannelSentFelt { value: 111 }); + coefs.append(ChannelSentFelt { value: 1 }); let eval = horner_eval(coefs.span(), 19); assert(eval == 288577899334361215, 'invalid evaluation result'); } diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo index 83627c040..047a91f15 100644 --- a/src/fri/fri.cairo +++ b/src/fri/fri.cairo @@ -16,6 +16,7 @@ use cairo_verifier::table_commitment::{TableCommitmentWitness, TableDecommitment use cairo_verifier::fri::fri_first_layer::gather_first_layer_queries; use cairo_verifier::fri::fri_group::get_fri_group; use cairo_verifier::fri::fri_layer::{FriLayerQuery, FriLayerComputationParams, compute_next_layer}; +use cairo_verifier::fri::fri_last_layer::verify_last_layer; // Commitment values for FRI. Used to generate a commitment by "reading" these values // from the channel. @@ -194,14 +195,16 @@ fn fri_decommit( witness: FriWitness, ) { assert(queries.len().into() == decommitment.n_values, 'Invalid value'); - let fri_first_layer_evaluations = decommitment.values; + // Compute first FRI layer queries. let fri_queries = gather_first_layer_queries( queries, decommitment.values, decommitment.points, ); + // Compute fri_group. let fri_group = get_fri_group(); + // Decommit inner layers. let last_queries = fri_decommit_layers( fri_group.span(), commitment.config.n_layers - 1, @@ -211,4 +214,15 @@ fn fri_decommit( commitment.config.fri_step_sizes.slice(1, commitment.config.fri_step_sizes.len() - 1), fri_queries.span(), ); + + // Last layer. + assert( + commitment + .last_layer_coefficients + .len() == math::pow(2, commitment.config.log_last_layer_degree_bound) + .try_into() + .unwrap(), + 'Invlid value' + ); + verify_last_layer(last_queries.span(), commitment.last_layer_coefficients); } diff --git a/src/fri/fri_last_layer.cairo b/src/fri/fri_last_layer.cairo index d50e79ecb..133e0c883 100644 --- a/src/fri/fri_last_layer.cairo +++ b/src/fri/fri_last_layer.cairo @@ -4,13 +4,14 @@ use core::traits::TryInto; use cairo_verifier::common::horner_eval; use cairo_verifier::common::math; use cairo_verifier::fri::fri_layer::FriLayerQuery; +use cairo_verifier::channel::channel::ChannelSentFelt; + // Verifies FRI last layer by evaluating the given polynomial on the given points (=inverses of // x_inv_values), and comparing the results to the given values. -fn verify_last_layer( - n_queries: felt252, queries: Span, coefficients: Span -) { + +fn verify_last_layer(queries: Span, coefficients: Span) { let mut i: u32 = 0; - let len: u32 = n_queries.try_into().unwrap(); + let len: u32 = queries.len(); loop { if i == len { break; From cc7b5c5685d5ee3712c181ba6c2c9f1d06301f08 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Thu, 21 Dec 2023 10:31:19 +0100 Subject: [PATCH 24/38] imports cleanup --- src/fri/fri.cairo | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo index 047a91f15..2eb1d66ac 100644 --- a/src/fri/fri.cairo +++ b/src/fri/fri.cairo @@ -1,22 +1,19 @@ use core::option::OptionTrait; use core::traits::TryInto; use core::array::SpanTrait; -use core::traits::Destruct; -use cairo_verifier::channel::channel::ChannelTrait; -use cairo_verifier::table_commitment::{ - TableCommitment, TableCommitmentConfig, TableUnsentCommitment -}; use core::array::ArrayTrait; -use cairo_verifier::table_commitment::{table_commit, table_decommit}; -use cairo_verifier::channel::channel::Channel; -use cairo_verifier::channel::channel::{ChannelUnsentFelt, ChannelSentFelt}; -use cairo_verifier::fri::fri_config::FriConfig; +use core::traits::Destruct; use cairo_verifier::common::math; -use cairo_verifier::table_commitment::{TableCommitmentWitness, TableDecommitment}; +use cairo_verifier::channel::channel::{ChannelUnsentFelt, ChannelSentFelt, Channel, ChannelTrait}; +use cairo_verifier::fri::fri_config::FriConfig; use cairo_verifier::fri::fri_first_layer::gather_first_layer_queries; use cairo_verifier::fri::fri_group::get_fri_group; use cairo_verifier::fri::fri_layer::{FriLayerQuery, FriLayerComputationParams, compute_next_layer}; use cairo_verifier::fri::fri_last_layer::verify_last_layer; +use cairo_verifier::table_commitment::{ + TableCommitmentWitness, TableDecommitment, TableCommitment, TableCommitmentConfig, + TableUnsentCommitment, table_commit, table_decommit +}; // Commitment values for FRI. Used to generate a commitment by "reading" these values // from the channel. From 7d07c4c5c5b590a71403699b53837a0f2e567075 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Thu, 21 Dec 2023 14:25:39 +0100 Subject: [PATCH 25/38] code checked for correctness 1/2 --- src/fri/fri.cairo | 32 +++++++++++++++----------------- src/fri/fri_group.cairo | 2 ++ src/fri/fri_last_layer.cairo | 1 - src/fri/fri_layer.cairo | 13 ++++++++----- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo index 2eb1d66ac..e55ef361c 100644 --- a/src/fri/fri.cairo +++ b/src/fri/fri.cairo @@ -1,3 +1,4 @@ +use core::traits::Into; use core::option::OptionTrait; use core::traits::TryInto; use core::array::SpanTrait; @@ -40,8 +41,6 @@ struct FriCommitment { #[derive(Drop, Copy)] struct FriDecommitment { - // Number of queries. - n_values: felt252, // Array of size n_values, containing the values of the input layer at query indices. values: Span, // Array of size n_values, containing the field elements that correspond to the query indices @@ -61,7 +60,6 @@ struct FriWitness { #[derive(Drop, Copy)] struct FriLayerWitness { // Values for the sibling leaves required for decommitment. - n_leaves: felt252, leaves: Span, // Table commitment witnesses for decommiting all the leaves. table_witness: TableCommitmentWitness, @@ -104,8 +102,9 @@ fn fri_commit_rounds( if i == len { break; } - - commitments.append(table_commit(*(unsent_commitments.at(i)), *(configs.at(i)))); + // Read commitments. + commitments.append(table_commit(*unsent_commitments.at(i), *configs.at(i))); + // Send the next eval_points. eval_points.append(channel.random_felt_to_prover()); i += 1; @@ -131,6 +130,7 @@ fn fri_commit( let n_coefficients = math::pow(2, config.log_last_layer_degree_bound); let coefficients = channel .read_felt_vector_from_prover(unsent_commitment.last_layer_coefficients); + assert(n_coefficients == coefficients.len().into(), 'Invalid value'); FriCommitment { config: config, @@ -147,9 +147,8 @@ fn fri_decommit_layers( layer_witness: Span, eval_points: Span, step_sizes: Span, - mut queries: Span, + mut queries: Array, ) -> Array { - let last_queries = ArrayTrait::::new(); let len: u32 = n_layers.try_into().unwrap(); let mut i: u32 = 0; @@ -159,16 +158,15 @@ fn fri_decommit_layers( } // Params. - let coset_size = math::pow(2, *(step_sizes.at(i))); + let coset_size = math::pow(2, *step_sizes.at(i)); let params = FriLayerComputationParams { - coset_size: coset_size, fri_group: fri_group, eval_point: *(eval_points.at(i)) + coset_size, fri_group, eval_point: *eval_points.at(i) }; // Compute next layer queries. let (next_queries, verify_indices, verify_y_values) = compute_next_layer( - queries, *(layer_witness.at(i)).leaves, params + queries.span(), *layer_witness.at(i).leaves, params ); - queries = next_queries.span(); // Table decommitment. table_decommit( @@ -178,10 +176,11 @@ fn fri_decommit_layers( *layer_witness.at(i).table_witness ); + queries = next_queries; i += 1; }; - last_queries + queries } // FRI protocol component decommitment. @@ -191,7 +190,7 @@ fn fri_decommit( decommitment: FriDecommitment, witness: FriWitness, ) { - assert(queries.len().into() == decommitment.n_values, 'Invalid value'); + assert(queries.len() == decommitment.values.len(), 'Invalid value'); // Compute first FRI layer queries. let fri_queries = gather_first_layer_queries( @@ -209,16 +208,15 @@ fn fri_decommit( witness.layers, commitment.eval_points.slice(1, commitment.eval_points.len() - 1), commitment.config.fri_step_sizes.slice(1, commitment.config.fri_step_sizes.len() - 1), - fri_queries.span(), + fri_queries, ); // Last layer. assert( commitment .last_layer_coefficients - .len() == math::pow(2, commitment.config.log_last_layer_degree_bound) - .try_into() - .unwrap(), + .len() + .into() == math::pow(2, commitment.config.log_last_layer_degree_bound), 'Invlid value' ); verify_last_layer(last_queries.span(), commitment.last_layer_coefficients); diff --git a/src/fri/fri_group.cairo b/src/fri/fri_group.cairo index c4a3133da..0cbfd8bc3 100644 --- a/src/fri/fri_group.cairo +++ b/src/fri/fri_group.cairo @@ -1,3 +1,5 @@ +// Returns the elements of the multiplicative subgroup of order 16, in bit-reversed order for the +// cairo prime field. Note that the first 2^k elements correspond to the group of size 2^k. fn get_fri_group() -> Array { array![ 0x1, diff --git a/src/fri/fri_last_layer.cairo b/src/fri/fri_last_layer.cairo index 133e0c883..7d7e768c3 100644 --- a/src/fri/fri_last_layer.cairo +++ b/src/fri/fri_last_layer.cairo @@ -8,7 +8,6 @@ use cairo_verifier::channel::channel::ChannelSentFelt; // Verifies FRI last layer by evaluating the given polynomial on the given points (=inverses of // x_inv_values), and comparing the results to the given values. - fn verify_last_layer(queries: Span, coefficients: Span) { let mut i: u32 = 0; let len: u32 = queries.len(); diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index 37cce1f08..a4fc946db 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -44,7 +44,7 @@ fn compute_coset_elements( let mut coset_elements = ArrayTrait::::new(); let mut coset_x_inv: felt252 = 0; - let len = queries.len(); + let i_len = queries.len(); let mut i: u32 = 0; let mut j: u32 = 0; @@ -53,14 +53,16 @@ fn compute_coset_elements( break; } - if i != len && *(queries.at(i)).index == coset_start_index + offset_within_coset { - coset_elements.append(*(queries.at(i)).y_value); - coset_x_inv = (*(queries.at(i)).x_inv_value) * (*(fri_group.at(i))); + if i != i_len && *queries.at(i).index == coset_start_index + offset_within_coset { + coset_elements.append(*queries.at(i).y_value); + coset_x_inv = (*queries.at(i).x_inv_value) * (*fri_group.at(i + j)); i += 1; } else { coset_elements.append(*(sibling_witness.at(j))); j += 1; } + + offset_within_coset += 1; }; (coset_elements, coset_x_inv) @@ -104,6 +106,7 @@ fn compute_next_layer( queries, sibling_witness, coset_size, coset_index * coset_size, 0, params.fri_group ); + // Verify that at least one query was consumed. let coset_elements_len = coset_elements.len(); assert(0 <= coset_elements_len, 'Invalid value'); @@ -121,8 +124,8 @@ fn compute_next_layer( coset_elements_span, params.eval_point, coset_x_inv, coset_size, ); + // Write next layer query. let next_x_inv = math::pow(coset_x_inv, params.coset_size); - next_queries .append( FriLayerQuery { From fdf4c7665bf934b92a3b7179834eea53542c80ab Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Thu, 21 Dec 2023 14:27:31 +0100 Subject: [PATCH 26/38] fmt --- src/fri/fri_layer.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index a4fc946db..fe4491304 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -61,7 +61,7 @@ fn compute_coset_elements( coset_elements.append(*(sibling_witness.at(j))); j += 1; } - + offset_within_coset += 1; }; From f49f8b0ee83f30eeb71dee3146bf8570d5ea978d Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Fri, 22 Dec 2023 08:12:01 +0100 Subject: [PATCH 27/38] naming changes --- src/fri/fri.cairo | 8 ++++---- src/fri/fri_first_layer.cairo | 4 ++-- src/fri/fri_last_layer.cairo | 4 ++-- src/fri/fri_layer.cairo | 2 +- src/lib.cairo | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo index e55ef361c..db957c969 100644 --- a/src/fri/fri.cairo +++ b/src/fri/fri.cairo @@ -140,7 +140,7 @@ fn fri_commit( } } -fn fri_decommit_layers( +fn fri_verify_layers( fri_group: Span, n_layers: felt252, commitment: Span, @@ -184,7 +184,7 @@ fn fri_decommit_layers( } // FRI protocol component decommitment. -fn fri_decommit( +fn fri_verify( queries: Span, commitment: FriCommitment, decommitment: FriDecommitment, @@ -200,8 +200,8 @@ fn fri_decommit( // Compute fri_group. let fri_group = get_fri_group(); - // Decommit inner layers. - let last_queries = fri_decommit_layers( + // Verify inner layers. + let last_queries = fri_verify_layers( fri_group.span(), commitment.config.n_layers - 1, commitment.inner_layers, diff --git a/src/fri/fri_first_layer.cairo b/src/fri/fri_first_layer.cairo index 0253d56e0..7b7a625f0 100644 --- a/src/fri/fri_first_layer.cairo +++ b/src/fri/fri_first_layer.cairo @@ -5,7 +5,7 @@ use core::traits::TryInto; use cairo_verifier::common::math; use cairo_verifier::fri::fri_layer::FriLayerQuery; -use cairo_verifier::FIELD_GENERATOR_INV; +use cairo_verifier::FIELD_GENERATOR_INVERSE; fn gather_first_layer_queries( queries: Span, evaluations: Span, x_values: Span @@ -20,7 +20,7 @@ fn gather_first_layer_queries( } // Translate the coset to the homogenous group to have simple FRI equations. - let shifted_x_value = *(x_values.at(i)) * FIELD_GENERATOR_INV; + let shifted_x_value = *(x_values.at(i)) * FIELD_GENERATOR_INVERSE; fri_queries .append( diff --git a/src/fri/fri_last_layer.cairo b/src/fri/fri_last_layer.cairo index 7d7e768c3..316c78d6e 100644 --- a/src/fri/fri_last_layer.cairo +++ b/src/fri/fri_last_layer.cairo @@ -16,9 +16,9 @@ fn verify_last_layer(queries: Span, coefficients: Span Date: Fri, 22 Dec 2023 08:29:34 +0100 Subject: [PATCH 28/38] code checked for correctness 2/2 --- src/fri/fri_config.cairo | 27 +++++++++++++-------------- src/fri/fri_first_layer.cairo | 2 +- src/fri/fri_formula.cairo | 8 ++++---- src/fri/fri_last_layer.cairo | 2 +- src/fri/fri_layer.cairo | 4 ++-- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/fri/fri_config.cairo b/src/fri/fri_config.cairo index 1f4016216..63fb9d379 100644 --- a/src/fri/fri_config.cairo +++ b/src/fri/fri_config.cairo @@ -27,32 +27,31 @@ struct FriConfig { fn fri_config_validate( config: FriConfig, log_n_cosets: felt252, n_verifier_friendly_commitment_layers: felt252 ) -> felt252 { - assert(0_u256 <= config.log_last_layer_degree_bound.into(), 'Invalid value'); - assert( - config.log_last_layer_degree_bound.try_into().unwrap() <= MAX_LAST_LAYER_LOG_DEGREE_BOUND, - 'Invalid value' - ); + let n_layers = config.n_layers.try_into().unwrap(); + let log_last_layer_degree_bound = config.log_last_layer_degree_bound.try_into().unwrap(); - assert(2_u256 <= config.n_layers.into(), 'Invalid value'); - assert(config.n_layers.try_into().unwrap() <= MAX_FRI_LAYERS + 1, 'Invalid value'); + assert(log_last_layer_degree_bound >= 0, 'Must be non negative value'); + assert(log_last_layer_degree_bound <= MAX_LAST_LAYER_LOG_DEGREE_BOUND, 'Value too big'); - assert(*(config.fri_step_sizes[0]) == 0, 'Invalid value'); + 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 len: u32 = config.n_layers.try_into().unwrap(); let mut i: u32 = 1; let mut sum_of_step_sizes: felt252 = 0; let mut log_input_size = config.log_input_size; loop { - if i == len { + 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: 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(1_u32 <= fri_step_u32, 'Invalid value'); - assert(fri_step_u32 <= MAX_FRI_STEP + 1, 'Invalid value'); + 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; diff --git a/src/fri/fri_first_layer.cairo b/src/fri/fri_first_layer.cairo index 7b7a625f0..e00de97d8 100644 --- a/src/fri/fri_first_layer.cairo +++ b/src/fri/fri_first_layer.cairo @@ -20,7 +20,7 @@ fn gather_first_layer_queries( } // Translate the coset to the homogenous group to have simple FRI equations. - let shifted_x_value = *(x_values.at(i)) * FIELD_GENERATOR_INVERSE; + let shifted_x_value = (*x_values.at(i)) * FIELD_GENERATOR_INVERSE; fri_queries .append( diff --git a/src/fri/fri_formula.cairo b/src/fri/fri_formula.cairo index 4f2698178..9702c438f 100644 --- a/src/fri/fri_formula.cairo +++ b/src/fri/fri_formula.cairo @@ -14,7 +14,7 @@ fn fri_formula2(f_x: felt252, f_minus_x: felt252, eval_point: felt252, x_inv: fe // Function to fold 4 elements into one using 2 layers of FRI. fn fri_formula4(values: Span, eval_point: felt252, x_inv: felt252) -> felt252 { - assert(values.len() == 4, 'Values length not equal 4'); + assert(values.len() == 4, 'Values length invalid'); // Applying the first layer of folding. let g0 = fri_formula2(*values[0], *values[1], eval_point, x_inv); let g1 = fri_formula2(*values[2], *values[3], eval_point, x_inv * OMEGA_4); @@ -25,7 +25,7 @@ fn fri_formula4(values: Span, eval_point: felt252, x_inv: felt252) -> f // Function to fold 8 elements into one using 3 layers of FRI. fn fri_formula8(values: Span, eval_point: felt252, x_inv: felt252) -> felt252 { - assert(values.len() == 8, 'Values length not equal 8'); + assert(values.len() == 8, 'Values length invalid'); // Applying the first two layers of folding. let g0 = fri_formula4(values.slice(0, 4), eval_point, x_inv); let g1 = fri_formula4(values.slice(4, 4), eval_point, x_inv * OMEGA_8); @@ -42,7 +42,7 @@ fn fri_formula8(values: Span, eval_point: felt252, x_inv: felt252) -> f // Function to fold 16 elements into one using 4 layers of FRI. fn fri_formula16(values: Span, eval_point: felt252, x_inv: felt252) -> felt252 { - assert(values.len() == 16, 'Values length not equal 16'); + assert(values.len() == 16, 'Values length invalid'); // Applying the first three layers of folding. let g0 = fri_formula8(values.slice(0, 8), eval_point, x_inv); let g1 = fri_formula8(values.slice(8, 8), eval_point, x_inv * OMEGA_16); @@ -72,7 +72,7 @@ fn fri_formula( } else if (coset_size == 16) { return fri_formula16(values, eval_point, x_inv); } else { - assert(values.len() == 2, 'Values length not equal 2'); + assert(values.len() == 2, 'Values length invalid'); return fri_formula2(*values[0], *values[1], eval_point, x_inv); } } diff --git a/src/fri/fri_last_layer.cairo b/src/fri/fri_last_layer.cairo index 316c78d6e..577a710f2 100644 --- a/src/fri/fri_last_layer.cairo +++ b/src/fri/fri_last_layer.cairo @@ -18,7 +18,7 @@ fn verify_last_layer(queries: Span, coefficients: Span= 0_u256, 'Must be non negative value'); verify_indices.append(coset_index); @@ -108,7 +108,7 @@ fn compute_next_layer( // Verify that at least one query was consumed. let coset_elements_len = coset_elements.len(); - assert(0 <= coset_elements_len, 'Invalid value'); + assert(coset_elements_len >= 0, 'Must be non negative value'); let coset_elements_span = coset_elements.span(); From de341fbe45107a1b014cdd92014a857e6644496c Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Fri, 22 Dec 2023 13:20:43 +0100 Subject: [PATCH 29/38] minor fixes --- src/fri/fri_last_layer.cairo | 4 ++-- src/fri/fri_layer.cairo | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/fri/fri_last_layer.cairo b/src/fri/fri_last_layer.cairo index 577a710f2..4b87586c4 100644 --- a/src/fri/fri_last_layer.cairo +++ b/src/fri/fri_last_layer.cairo @@ -6,8 +6,8 @@ use cairo_verifier::common::math; use cairo_verifier::fri::fri_layer::FriLayerQuery; use cairo_verifier::channel::channel::ChannelSentFelt; -// Verifies FRI last layer by evaluating the given polynomial on the given points (=inverses of -// x_inv_values), and comparing the results to the given values. +// Verifies FRI last layer by evaluating the given polynomial on the given points +// (=inverses of x_inv_values), and comparing the results to the given values. fn verify_last_layer(queries: Span, coefficients: Span) { let mut i: u32 = 0; let len: u32 = queries.len(); diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index ef099ba86..bcdd03c4c 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -20,7 +20,6 @@ struct FriLayerQuery { // Computes the elements of the coset starting at coset_start_index. // // Inputs: -// - n_queries: the number of input queries. // - queries: an iterator over the input queries. // - sibling_witness: a list of all the query's siblings. // - coset_size: the number of elements in the coset. @@ -72,7 +71,6 @@ fn compute_coset_elements( // 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. From eaef5f41df98bebe533065dcbd4cd244b21aa7e1 Mon Sep 17 00:00:00 2001 From: Filip Krawczyk Date: Fri, 22 Dec 2023 18:32:23 +0100 Subject: [PATCH 30/38] Run fmt --- src/common/tests.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/tests.cairo b/src/common/tests.cairo index e48afbcad..c851fcf18 100644 --- a/src/common/tests.cairo +++ b/src/common/tests.cairo @@ -3,4 +3,4 @@ mod test_flip_endianness; mod test_from_span; mod test_horner_eval; mod test_array_append; -mod test_math; \ No newline at end of file +mod test_math; From 45fee2c3e76324a06f7da3f0e63e6be058438d9c Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 25 Dec 2023 08:21:07 +0100 Subject: [PATCH 31/38] fri_formula tests --- src/fri/tests/test_fri_formula.cairo | 84 ++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/src/fri/tests/test_fri_formula.cairo b/src/fri/tests/test_fri_formula.cairo index 8b1378917..365681bec 100644 --- a/src/fri/tests/test_fri_formula.cairo +++ b/src/fri/tests/test_fri_formula.cairo @@ -1 +1,85 @@ +use core::array::ArrayTrait; +use cairo_verifier::fri::fri_formula::{fri_formula}; +#[test] +#[available_gas(9999999999)] +fn test_fri_formula2() { + let coset_values = array![ + 256174450386745647456273661147162555580494518861153534647088465922575117334, + 1671405167398496013166151137317583376038528401232344909132875285960291311268 + ]; + let eval_point = 990499144245737974799008890724836248213916208950349459587583338754726831595; + let x_inv = 2562983180373163585382777096151079646715274516289060915516104360308560206742; + let coset_size = 2; + let expected_res = 198440420437625747101596759055022522005259320860955022036987094429833877178; + let result = fri_formula(coset_values.span(), eval_point, x_inv, coset_size); + assert(result == expected_res, 'Invald value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_fri_formula4() { + let coset_values = array![ + 2918451960196183950799272371389606628523370484646741980148988314056840633012, + 1828256075401704910953535512167992927476841764512113836321405179977451944658, + 443990580507814779714721735425307372556191581217364203603052790273043374812, + 478993815713421978957120397192722702770323426746719771295955120433436796180 + ]; + let eval_point = 457249448999073095464130886760235558440510604838488179928102756356962280192; + let x_inv = 3107440215033843359186594841583230014816092994120559276037011692468583562476; + let coset_size = 4; + let expected_res = 76986752687751524725198345383694178215277147555245625873131732095927140782; + + let result = fri_formula(coset_values.span(), eval_point, x_inv, coset_size); + assert(result == expected_res, 'Invald value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_fri_formula8() { + let coset_values = array![ + 1661166871144478583893094416262059281826151442139016862759341228313773098756, + 1888790466376987171231396642956380917904535958666125046539466878395173202690, + 561547484995955011602324598416005224996941805793915162906443532252891702660, + 1438536576067352528859853732647697550807339377747523085134808764166756865377, + 2000528913550216347590830479340601949879559709495641913127193800231287027181, + 968156013310731486938436114466792427269789175801786475032517169685274987637, + 3250035871629077170491947405374956034621884547926979323876970138934589005216, + 897157052540850732712732450079850389056926113695526376358380698632562487485 + ]; + let eval_point = 117094530326216229550146135028366305396570718736487726300139051888760830677; + let x_inv = 2178676743740509795000995476125961580296168609656535469725486531798699196988; + let coset_size = 8; + let expected_res = 2928957534120406763150873305661822742897260412260280822311358109399058652974; + let result = fri_formula(coset_values.span(), eval_point, x_inv, coset_size); + assert(result == expected_res, 'Invald value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_fri_formula16() { + let coset_values = array![ + 1830360260767246179429152250672367365974293880197306063642359322652473418653, + 3085926493110094076710734930449361058123224813481795388167668581174293228771, + 1607299987054925237445217024334446849543150875865699114944096686437897111753, + 3148344452919029631974324531259422322638996981447765405256284693722148271843, + 1414363463551123164953744364899158768001534820947118677192316453629493426683, + 1251170352249480221675546930249156874640792574829086684030680899472214442049, + 2829586349239053936105008951381321968848749767788105077608267975888347183105, + 2479853112422483406409872764151260737242741372650754304755385651924864953187, + 741627624943133398165028231006534361126520291848732128447460710235965240797, + 948446534062965329061639422673810116395745120783172282454806953649972082412, + 740451231596130847381847379108542578609096119014292221334060186112880662077, + 2832402624341247112280268990275716678963627285493925393692446990112722001079, + 3136851806033301474120777392426720795558868125196843704074663617779378457446, + 1587406744973581680114122359205653339457720336912159943930529946020104828453, + 1405784999711145104568440705151178765262609426103481131577188329447712092445, + 2526225071480351877750250312060682153979427353331663476892300511344908692936 + ]; + let eval_point = 611757761827218372659316980928600090155368845034029583212395428142956808164; + let x_inv = 2747636755771078955150747981212578469605285885376168668689388042479636251975; + let coset_size = 16; + let expected_res = 624048098022519532611213501847456835806953670583267764150309668941596037474; + let result = fri_formula(coset_values.span(), eval_point, x_inv, coset_size); + assert(result == expected_res, 'Invald value'); +} From a8aad09c956eeff305b9830e5324567186439535 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 25 Dec 2023 09:03:01 +0100 Subject: [PATCH 32/38] last_layer_tests --- src/fri/tests.cairo | 1 + src/fri/tests/test_last_layer.cairo | 656 ++++++++++++++++++++++++++++ 2 files changed, 657 insertions(+) create mode 100644 src/fri/tests/test_last_layer.cairo diff --git a/src/fri/tests.cairo b/src/fri/tests.cairo index 553cc68a2..1ae9a8e07 100644 --- a/src/fri/tests.cairo +++ b/src/fri/tests.cairo @@ -1 +1,2 @@ mod test_fri_formula; +mod test_last_layer; diff --git a/src/fri/tests/test_last_layer.cairo b/src/fri/tests/test_last_layer.cairo new file mode 100644 index 000000000..813a46185 --- /dev/null +++ b/src/fri/tests/test_last_layer.cairo @@ -0,0 +1,656 @@ +use core::array::ArrayTrait; +use cairo_verifier::fri::fri_last_layer::verify_last_layer; +use cairo_verifier::fri::fri_layer::FriLayerQuery; + +#[test] +#[available_gas(9999999999)] +fn test_verify_last_layer1() { + let queries = array![ + FriLayerQuery { + index: 0, + y_value: 2079129405561620208087077895401073393365548266683640775208900575472382109824, + x_inv_value: 1025200915594184200313698913014916492712823017977023269060618978800032187220 + }, + FriLayerQuery { + index: 0, + y_value: 3393322956210468285165331333162707202834898699898049190152720955395767718796, + x_inv_value: 1122187072723254225962628178169851337055839455052122783532867692861890824980 + }, + FriLayerQuery { + index: 0, + y_value: 774658394404375667069053053780760505339136849546403700110016309956817889723, + x_inv_value: 3523496338085130181348257946285311374370953078793932160256947210226520443021 + }, + FriLayerQuery { + index: 0, + y_value: 1540595761698447925811667139221348041976282862801600548986133753032241611666, + x_inv_value: 2405254460431699228440085592461078086000237395142668534627506859073068861835 + }, + FriLayerQuery { + index: 0, + y_value: 2375818020905191665174059219621958843578191707263505707808931476471770468721, + x_inv_value: 1586129732899109811846311412740924349890132466584764773677662219972426860210 + }, + FriLayerQuery { + index: 0, + y_value: 427607608639344818356730590175870246773395941237044155986562999884021276776, + x_inv_value: 1640049332764903875546586759150487638050083510098376464536986443432378599707 + }, + FriLayerQuery { + index: 0, + y_value: 2850086244202783478756254096889060252878398514669981939839198213505105677022, + x_inv_value: 734414869129084189608580973230821029766816902559046453978063257349178461650 + }, + FriLayerQuery { + index: 0, + y_value: 1920671448998228135836254663634037531675602477535881837097102450902739293735, + x_inv_value: 3190584962170961049287869885415010412220996646943132110310786111368665853201 + }, + FriLayerQuery { + index: 0, + y_value: 2079129405561620208087077895401073393365548266683640775208900575472382109824, + x_inv_value: 1025200915594184200313698913014916492712823017977023269060618978800032187220 + }, + FriLayerQuery { + index: 0, + y_value: 3393322956210468285165331333162707202834898699898049190152720955395767718796, + x_inv_value: 1122187072723254225962628178169851337055839455052122783532867692861890824980 + }, + FriLayerQuery { + index: 0, + y_value: 774658394404375667069053053780760505339136849546403700110016309956817889723, + x_inv_value: 3523496338085130181348257946285311374370953078793932160256947210226520443021 + }, + FriLayerQuery { + index: 0, + y_value: 1540595761698447925811667139221348041976282862801600548986133753032241611666, + x_inv_value: 2405254460431699228440085592461078086000237395142668534627506859073068861835 + }, + FriLayerQuery { + index: 0, + y_value: 2375818020905191665174059219621958843578191707263505707808931476471770468721, + x_inv_value: 1586129732899109811846311412740924349890132466584764773677662219972426860210 + }, + FriLayerQuery { + index: 0, + y_value: 427607608639344818356730590175870246773395941237044155986562999884021276776, + x_inv_value: 1640049332764903875546586759150487638050083510098376464536986443432378599707 + }, + FriLayerQuery { + index: 0, + y_value: 2850086244202783478756254096889060252878398514669981939839198213505105677022, + x_inv_value: 734414869129084189608580973230821029766816902559046453978063257349178461650 + }, + FriLayerQuery { + index: 0, + y_value: 1920671448998228135836254663634037531675602477535881837097102450902739293735, + x_inv_value: 3190584962170961049287869885415010412220996646943132110310786111368665853201 + } + ]; + let coefficients = array![ + 2392461143815077320697693846111481235203067221193351858024888568343343862087, + 784392009524607857816729347695510970078731534546649545712669767170815932325, + 3168746641018789250002196503058931463036853991579975319087975816109858240309, + 2997124515340217133887649666924355193095935148598960405989458172244750240772, + 2256838578502294604071550394844398858476699681187555240798332849904657961349, + 2100441454387399175759506457421980589777025276192803613687421616499198487087, + 90309800893313593992968850368468911697044383046075018874867043545455291839, + 2980723519508710243207222625595631956174508106180694879961683924462214174087, + 1467230737924187613823077129380895920422321202735301143198077287255415501265, + 1949562520663380243643468923253735443370454282668236414040028240835044926139, + 2278244522082812176533190018813566570919137060795359353399823198613199924401, + 1685428054409712361853066130969019754479314911281215083640082525533311387304, + 981262236064875156195513446841989471757407109803217660217235170540793762100, + 3555412294739506638981185597067995739755549929225903888369646062001884730722, + 2103703391154737997659947664830898835229387514993026413156823944471806748045, + 2996736960304657821227842732347676809204367166265528201598017136385919762750, + 22478277030852384415455263869155917591575790012869536721308064792442255926, + 2488482979818923449170636965824869033760704129208651715585265176767411289727, + 88446472683913130918497998962351925093009256826963180161264071986332267046, + 1309062932890077830176816659124888770141403227013736526409686038924619824688, + 2067891375250240116290855501869912459503035923650894589509015541515580063249, + 3417964157940318346029326854457551386698154918628660536488616037592690951763, + 475659378307779665193842970746908308816715656609194558481172786910773251979, + 698633389569762053756632588269743603762123411346891754397879290642309061021, + 1829561657510074437477776531817529159548373285828037788023682284224066717907, + 2208482197578393584417647498116811359451086224302236706916379789566171985916, + 1476814762705073937869070166395100588506098950588596112712893557317587045337, + 3356348992758108388087875249396728439355196762386185334393732596908371779760, + 3277427931709527600444863657051281245325828400006753070860411115422624866681, + 141046663742952098480209058671338685620080001574807359127826806145978423127, + 1433431353251140444676482237883205125764274218400160764298687817276656713017, + 3279665538402462082209229212866760747258793677161083813939201388081852264371, + 3362381697767982579711627977011247010147066558123776540799771348077051759574, + 729570215316447614050900194659246479398948824282224587030279101697413230312, + 804519572967767376555515603262029065711113911660558597095488402848213692548, + 1263067001187434041212270910593043812805420509808359690523946904428825808853, + 1513126208894012512829825226158939013556679361403209411089454591093935014635, + 2022994639317234694623423148772115669219465498632321168429134056278090410713, + 1106121543058216731932678666576175280610396390878769620202174715914211252526, + 1357387457005024454258399739732799174902698557881165718700198977210242022888, + 1647497474321056070214111708144056870933837301544146866998947532665485325362, + 3538120495114609814303648328537268878373906565820428377711514212918870837034, + 1501473333538573484499525260624649042315502706844282172575790845082689154804, + 129861036017135518685330585557086878530694976637845920584554909821072030071, + 1179181045520509850222127418862355566031563390660703108885108977143496522817, + 1208425813637766131525276750631623347299227264131099567798939455424718869528, + 1030552440694948682212735494936923546436611910739272061824877842259775766989, + 2608254133585618991771219894467091168927253787609858206490327064917003288996, + 1705388347927946337578401233132557866870561234959890530973989878629510521776, + 1033356576879224307726001222309686355636428790067401081329459646581464394920, + 1528458430964219335306390308812145741394156980266800381485374742629165160554, + 304659623379444472574771947958404692536333940772068168558966538112219785560, + 2999455936544146875266441803768358949442521625110628146963251404851064734225, + 1843253973957773981977251009502517645313009808535069785668007226987328151671, + 2372650174980057021152940146096345020969937874410609985029419963956463761821, + 3604855222568696643606379263274387061980620010426299713438106537325459715844, + 1785273095475268904862046923217893918964362520175068357041169095840018795833, + 3177155878992488537713410736995098106680697326384179556373594287894038383159, + 3171386059349932144871830927932040009432186420897936049165086871821671561157, + 2166799643216309630956555884263981782494366553360736970619704551039816088872, + 690773977199207793680903911661714213288195088351034615875501359702844324928, + 2538557067052612164201023888278181968647205976067113733791200147576098728206, + 564612669301225419807449437133056754401372857593003898188171984350133780779, + 3522475948536402420514230082222875104646478616404384619375622859023235263462, + 1783711786942135104695971747877073093672924504855239718433738150261783351887, + 2145778662434152346143877671800992953138374099355555265318919059618252428443, + 3555078412927530123877556770667890486916017227614199690346982815110292767746, + 650567982175500331093374067628131979069335425594694211078126225504443154010, + 2814121860779719572746779164812593305824026294385656285072741193502585821143, + 3430470382489149242928594925791126079852609612501106248695110939914765211726, + 2451402400712734408502340772196909984728849592100277972121638796157761264903, + 144822547383835119759800797371325816927384973248883942510678054459139722242, + 2257583813540244917540033948978553166756572414407804229220389457721692233933, + 3547944866631259598709383847689748359066066756557551766078585806617587254488, + 2478516376318173464955788002632084130448243113421606928204613632037347842734, + 669790521168028275986744746429732277004989392659084584000743009388579576605, + 3607606376948579460960081562567811390949195203128409968508851906875537085037, + 370000449089695166095710743740197253392217973279939520152662997412357222873, + 3195543422659824838757571773825552481725577926715664410159589064806193535204, + 3397169530683551502310046123309169618540290192273690262005628561885413126412, + 2381556335713148716957565083258063000105970735561392479442926344496617230091, + 3488073762699272252396891803020620307088294673728905578251530016269876817384, + 3388153087516953227328620540665823853457419289739829669759823566034220335556, + 1088552068508855977393893751155157955678474795861402714840982931565799000845, + 1527295699623796729993444736938202055455614858707960083888314931038082921947, + 2818374410004213552520223671664008290826708834836015938935420104484982860419, + 994190335132439066150294601518305862134005850632190467985121355679421794645, + 2237066343784986085668182075159792280188959605682305723364725527162679161367, + 3232611626861149441844877561433016171144725278039678619911018099134758421283, + 1328224929677784018502706160523719490925625036443772810076369800738821920734, + 3118975896295146314405862201130726168824709109817013491888026031562373863041, + 1411459085556064583684589772537128007568463894180041035951657318169688962026, + 1192897673217984435319866389478973004100085689601391371533642411134911334429, + 2438981059418137295961265954947456289489446224421228169443973812996110872895, + 2137018509213931179611233183020937650792847466431948225826561076212072890264, + 3351898479968096667605949287370891866950026313029391383525577902763919713705, + 3543026592654554180936676690906814945251976268909750830211916784189903280874, + 2396566495770805509481246837645100986657782959842868571019203876404054898520, + 1671570630339737496625134847620621833756176963886573137480474821276034984889, + 622453481736769588187985406149276510130764088821045892432824816426931327540, + 156609269257963468734140667472162762946832057320548049703873428520197860647, + 536467187458591531688465689128651789954897504613183324110364072836891416819, + 1905414712501991912488990637678663059012630142133877894304569449031552887267, + 1626401525983843916244368162816625382312435090383181940517416207937144258420, + 2988371029266055049650026783987426354595888622925379570430165122024729113854, + 1467438687309928342005502668874977832988638975670917359819506623800286183057, + 2987265628257210332402974341614356700214670421064573249705407325673972490093, + 2884236104531109001076608495514437425136020227603016109208839128500825838924, + 2813815126622130066420580010172925375493182467831940575775357324666179592455, + 2096761004881152489625749598242983358260146405091272189244957439355177332107, + 1884723079694950643650279707403654483956445752038318415340029532300993880262, + 2421903994850697320171204478715303872929988228469378756056356822145252176334, + 2360776848845560468909284917218566633468165809785697515165947555399388743318, + 2652340065930789753689543337604797851654371483341936505143631938387987928041, + 3035979586598477181778688090169479800516400962178125740280920479894144703251, + 3115532564708013997916422328574816139556316501603023649438172990478291454112, + 1766343547115717658948820917427363240599869385281026027634366078197613845831, + 2468738856558624099108403683036519657767528652782935563133677212367495445702, + 3009548420929041713176225573122357526338389909329043716179271458535258397111, + 2161169342069393251410691785298668473603335271359745688876775772152073008933, + 2565832767706636051490315619194957819330600658484876636761787522259631463371, + 3154351606468569998801231969052975210665068721749004664665921811608485751942, + 1546649997731731815271363236521774914988129933835049133360093484961388110443, + 2744328610375345472396018534844328934870381158820088183781572781971555959268, + 1722445640025035987026925926960665944171253695368738833057142685885530910485, + 148035619135347691010485437423691126336888940476520405258499988316713477330, + 2034584518404021609816941970521076374442520399138637703889443453715759967669, + 1919544532462204818355587664143735420673503811973521316734479633498445703861, + 3522533211454357787492208462844781988821867461164228947135581567948821226106, + 47081234212684725314434881555029982273134454651722778188454136816599273752, + 548075678279611524632754144371268597508980050645619009831407614046208418647, + 1151144665060618688463204684576493308825925743833808162224968722083729470744, + 306530449937824764767897242255702056544962631870830021498099007994044236708, + 2191526672707611271332253169273995249521613960886080126381302433408550852202, + 247262871241497444041579252318708169146661662039041568677758494201143268531, + 3475852579432530263709856161715469216787108297873830804498576925583058180847, + 2259513115249610651347251275769260458632823538359295376046765629168600340796, + 26039256838786652418885563231790544858458967702663786588929061691035202988, + 1630330983335205557691441939497441573835395417173233677642026952825135703750, + 3615391124765563544451014418587774264029553631470274140893555721935363278784, + 2671690402033545197118979558922821356600994761554817021137195484270496228648, + 52279850394575256146027674616547956574787101227542189547999141698127299003, + 257840318738710997305121161024240231293297110539714528215864564191057174795, + 592611663236450052183985297826510626379172629470771846679548568436701187441, + 12858494134738705209049157639156887290812292556421899591437768907707338926, + 3146693810354497823337402256973787118474484733209066947470123270431989980807, + 1538933337397979441756299599431124984707805240126260690702113855832250375934, + 414323751287804332023864659007048558870724832641587007179651932360963984977, + 2552081696921574807138727603343654172739735717292990938194623937705272963105, + 2265024862552608245030711616560421515655883252305797004311137936701006979722, + 2170161591930473264731630484153288943319267203878430953679829232656088769071, + 2307985959043905313227969338772812892412362538121308593983485823490610905141, + 1147869997773384778349034398317924820161490402641398253159082074109603198062, + 1907043595771761687718094361026446274181028657396009372926520277218951945094, + 674998636004702329086662072098366638548138407671680358034941305188795669135, + 1568106171499809080205748380831021132984193297953930582935437689111524203886, + 3278999124569632042604379453594392248322115533001165040428756141669071227392, + 2740034905090941923754126747919731475286607893868282106219154401925595344711, + 2549978538740621008311059662339622962211708624494930426282609196621035084228, + 2665853181238657357571656639400224328825494066903714777517175136078287138216, + 1673900724116840155721905048754407583070213186172126928993568316874249088518, + 750975350735172207174133385517795508637359646406199389687823269422919513063, + 1693810092522319429509622484005740456490313183952453821511423075257454701056, + 3501431480577128167325060720586271552714653084831466516375671599518508686148, + 1553596711544045097153429420022781900210465313502389221408923020706377248112, + 3542803383805687782689960498846031088052214035645184579408887674047609428130, + 3063274475986673605006311773847406570190701160606583696238290695527684443214, + 2834823365085461017694361483443601352593023077241361091485845783497833817120, + 2465186665793948647296317148203491190080194416877059867660418858468628862353, + 2053557874012251887857568930771609266087648377530674892142341639287661926914, + 1951658748156793371697250421224464539981037226952513173253024880071823168723, + 1844400637395511815936906861855917698403102975793286177134778451552705154192, + 2335633487115723946433692827545583371842729986473528619135917421002778056060, + 3026230615605413208035668809828387761954600729450384092344106378557583727373, + 3610638454355908184742338225001318605493996546002622201707027668438929038361, + 1521940942170705649826971093048582294213505984982244893464044870068610595900, + 1876773609432146712424720225748196680850939597295032441388526180373999574191, + 2593382058182437069452769162263034493665737894075981402115466952415042863081, + 1853036071891115449242823909629877338248255970702609014052860708894985355844, + 3278929517363101596127151780175948893415674455860019299276082847359127314387, + 3256410818943923827741405739931636826988641730878666112867296531302396700087, + 801078395980902786731463812807668196955469415888778509688206624656541665852, + 2301488670988272666475618465769550300013464551778596584448381454420649394699, + 1959029098420360025902010962585522008566821918596812236672461955045525081270, + 2288313712925234626044569746464880064440336621023653467115517370901371509406, + 627176279938106727827870168706215389885846085625106561812839033669736138385, + 1428640878860361823324568932446551711031776544841330484325941238987786304771, + 2570161707942145513026884429744883655501651136513093632037657151521268189736, + 1175423917661307441369270774389747244169211245186187606861797545587951782205, + 1458462253423156979987880423613319494005346721789508489488154924968202450479, + 164657593901416579735998968232840523226583298239967284583069397214088563427, + 1342132818191904076533006056789082304460757048468085728323173907074357256787, + 1107072954029994015887790068150305394345498587687731620647771043818571399523, + 2353463082751710579162777806687866722529397193830706015903329139867605526842, + 1745782652446130169039861018950057557068794707082482239382995047333481585578, + 2497374171361474809272561349294572604909756028992491760514602211286349400932, + 2359748131052970999921016292886969978601615217498678596298211688355648856153, + 2083939956286063954119099510885056976034015762114481947659198557018361214407, + 313787886922389983781730961354724992149148261192097323595808278617302065244, + 1935749472928824721020762529695785689053948552113778050233824151403322452246, + 2734908967603184243400942844783411399699526844325360348371371804275976611705, + 2366353112892143209556023268707951007693098317560121241666138654868236281429, + 188394736908349540176126184846549228585884042416922306172700869186207154000, + 1758472328327227538230969822956091278767696843188472958822582638940007887230, + 76149940974020364844896731463003864655439763119208584536219372257272973702, + 2735805992380220619408719438797734156314194632723469386467739938043831117002, + 2331362706328781334957371839739893506195996877898869633134156508305308708518, + 1455665639486532147284174915154359779433169449405320445424557626911228033779, + 2347682682435125964470328207695792897673868738435686946243462062578425068460, + 1675433797519718606473603849770578263501309736124045686780842085441121145032, + 1871165968318898488944314708216193154531208856325529335550528617342173863754, + 57554343049851127486291884374855752785698885129517430225914083386487019003, + 2896706797988118188529344804022257222458109811568366439055707303489485457253, + 2995768073565314551074110905896534142610302621545112037735459656071688275634, + 3305605349225587714508577774409742534345648527541587842890993562804500888382, + 3026034211718636557295383533220837097343659629686131086169933326394606290383, + 489955259445109412326894216281880413278092766916405578478970825705998210259, + 906725161519107072159883677711429680707884659218937179204213117881623856607, + 2340656787754172147965323944302056005050957621301891273693073235697530007511, + 1769069892635208820016916883784582521447776930613191629914094767698207305203, + 882486344429996270776716057144121318306669834056424452803709879040816837412, + 1831380929974959962776086039112541255127153547491455870391293137044996390617, + 431030631155477082788954716795001748054712053097413682247442656296243997316, + 2715661608515434343474163371782274930139611731182671460526837170519698977558, + 1651249283227317674214804913601514843156003788725319546161176585045408502642, + 475811979652116540968464139875853548695934097778344752169405362111017387021, + 2593947009000492455566258698710784281375453479504887615637541730873440832901, + 88840326922904836856817268809990630008051530454118774072904226609093391206, + 1516177993701102679686884120858625954403924756766320470463789216641880132146, + 1526074521999617450383895552503426389845907745075404202509449937027253406631, + 2697576158762092275285397322237838504850427567343632346889427821050972231423, + 519589989729543653499716832245101006403311708310864570555531651374891391483, + 1090178760286433627796084941408061817631874013834573127489253195916136737245, + 1646079497961091498126522168056654064734692780013069363322594261900992636669, + 952983182971225109145489571658770606434221720682780944762770070602895001140, + 447774812079341587267211820423096915904443422733981754976106963710868525062, + 2486674226075264328965058892094182858036066251322647870272357619909983978062, + 608879970730470188664450958507771859754396173186372443615893483307719822060, + 288957473259857722939717526242005223813969242144038984280826365142995690557, + 1239042315558343564414631050765437932574552532064080375299676339225775525032, + 1447270481654648608121671134074809496523841577686052157097557908499235890479, + 1827298398941081347356158444107177615783328691208139768933673183403111685102, + 2979535605424555540126484705703290180448222020431914639674704500184774517813, + 2710028213720233019761356221616354067891102326715057629593113435316967234588, + 3062536585683358613482927975039382866374096445302331514984316952550129877553, + 1810509690491145622558609311268076568779637007752474224006171600704035746381, + 2746148528102114739815720896355730957765080869129769194415865043622823478307, + 954587750515914175246374698370465585670684114100698466457404698905117757508, + 3156535495179250351459089847606158911375212809607368259040193414889157337025, + 1551313049232537311113908525871843709378665605725293926927340516198250429043, + 3561980109785417103601412546377151856079919629047812372374994282614848621437, + 1328689129489960321700932143121349020001937971591795762042449985817583633499, + 1373986494651822153370271094873500681762649025140914795849798157911646870213, + 1738371563205679072642066133691189728281960601898948284519761121629425710832, + 821149419388664457210039727183868832647539893624021908488509826452956715624, + 3039275610411515805655267711065095119968040147613881706651796604857471126655 + ]; + verify_last_layer(queries.span(), coefficients.span()); +} + +#[test] +#[should_panic] +#[available_gas(9999999999)] +fn test_verify_last_layer2() { + let queries = array![ + FriLayerQuery { + index: 0, + y_value: 658321961196538499071727543513760083690111269972877446426634252344691191289, + x_inv_value: 2163238211795908974316003271296609453501829793986314085333708297507343998630 + }, + FriLayerQuery { + index: 0, + y_value: 227508471404491932488808905754064674914767635770123391447879022920950166178, + x_inv_value: 1281170383120882780545268551400979581414525883711243043891591303817233324914 + }, + FriLayerQuery { + index: 0, + y_value: 202713457923558393769620871486818880763979782942581765233088844520839863907, + x_inv_value: 3528796316240649018153502613187355479453371358645062568865026278899999672386 + }, + FriLayerQuery { + index: 0, + y_value: 1098312266638356860362970394040927545462785198670297622592615162109213638726, + x_inv_value: 1774619121576985850595401212321651873158516895845864952256073950753219318265 + }, + FriLayerQuery { + index: 0, + y_value: 3401308477101229818178277544291567307104991785356208476361126944320377543827, + x_inv_value: 3364081184805240783239076870401210349211407701849066501056404933343422520465 + }, + FriLayerQuery { + index: 0, + y_value: 953533918560692514651698075891680377446500019173942833049503983352319209671, + x_inv_value: 1198257737377526939694785697696602706177609035475062236517198505472728121254 + }, + FriLayerQuery { + index: 0, + y_value: 3376680096977705594293323916903343600436602652586611494763517586751811350613, + x_inv_value: 1289065457262991290708803547491156734832123912153446472771774926514030335120 + }, + FriLayerQuery { + index: 0, + y_value: 218730271760308617273014223453978552249369546455721401640834240789998201580, + x_inv_value: 289419604979857442071093777562000605116085366573463463573115235909034257695 + } + ]; + let coefficients = array![ + 172899125269878760298391979702400523264587808452545341271505234947901375038, + 3350634106031085936830353769071135584595900986687883318439998610164238376843, + 2400936724985037126564670702365840488803444778908910724427329416221741030961, + 635192040927323068491253334226544498781829833411114123984496527946111967398, + 87758663111118685889813045794876462105380647015738497869226623616950274647, + 2978864150705734811583882757595071048663360652130306270460684880128302044166, + 3485939982491478748472981326241000016280203863943917680219782737183188877473, + 836805962306288195736677266341533899640129882529125421810136886197921215576, + 3413036231598145889450138472873357075241664355001910994747866813987610892580, + 2506946892984863598675678903114427147576767646201713340789330839412609507268, + 2476745451535638279427420366036488690617708433832451796106232785289735480340, + 912350852875579501725008622908282466257427457047691576924188556742262543486, + 3361620140726952731845910028888646916756125852599959747033820662606302330838, + 305772069167448799494663222883579113712647586889589583682765468985341668819, + 3133795939616064257433820167007814473576979417901597786125307833766554688785, + 3232836692322280622557738564793320633044433610666643285763013846933126988393, + 1968987808463695765486858971092418967209917024286197763480585804013213811519, + 1660172255797827511554792421826393320522537324167591614207989974032289156290, + 244336998724889913310148002009162240024241511396552207896763238387485129923, + 699257078739143393391231505795997204693082066727804831164160259649960811300, + 1998200634994994013615873740809909505416327592977759689029410272247382912509, + 2905488937521028861917827384137070990330892842369136802704151762549075225151, + 643925186834043057576161465719187181026267566646994174560747619409759135164, + 458371602823134880891382945307298403005113294643680522760252962792296676070, + 1642968561712455100295582955242551553571776330659071284302738383930163306972, + 1722386801332888663126953669446712613137948711943861318290059677254303104360, + 1062586208191938446476166124681167439772436048341332681543064327481282142361, + 616223280979509295031949802238560494344621785054634932185688474324708651770, + 2875594040929440296924103094101915591483410781066735067493478517716748253851, + 406097607882643894570167597539096884508876728783505215187052633791373010539, + 1166929363527460210094421691191132962158757377722223995656827616770149077190, + 1006251410732872229385524815837753307422625657566110360032029500964539196027, + 210076340391707461168022986723524940689943724876780773049655939865719618919, + 50948953922568812990340535344671877550613562489480858588016182545896426917, + 3484463807079417914091893255153768462467372065255355567728716085589907026944, + 3436302951262452693300917554026182982250580268441578744200433413975908378885, + 2007315458853760996963313353865864625050008071303473637642200598484983917707, + 254156771117394779348843353836944808693145128811086232435755870926867153401, + 1239740199799683406577102630987138109573359094350993723676154962299005017985, + 258580688545867277635518560904741273952141332391036776913437792810597320803, + 1444657423970432030592707299144027110023719613968808051876026926240358058507, + 2367707006564185269263722474756660665557083364293475150813141346557101600042, + 2259543740959719907579610510026804401755194199608118509985132541785476937453, + 2159740301863650343355005459918743753523743345955456183790051049430489052016, + 2289517288971308344366428759052544594965350611381579526925519239697949997449, + 412783658325461248362095372545054152605889313547022152474002730696950628662, + 698494682807080614614510515628307704900589830942554131137279427175741763921, + 2698288446873557130106031325804394729262125302382420991355795348964761796671, + 352564570797599549670145857866325481291872383030361089500023678456481666154, + 785105842970958989970769388066367276625684942620743799275288890145381275498, + 3033992666499815261952028575172460017313796137447634596223269261538568350995, + 638857758169361390885013232516585103604473651781447458193400858684580877004, + 3494844191404971367624125956857782787530596419977234564545789119898907409772, + 1028547067976030668593475841943847699458624811468028149815128683074231537162, + 1327230683327641745530046918388764648951419225079531133535445503248844467668, + 454368626226171922428397271042446861729183402958051824615595627760527954207, + 946545580161101829266381947955751108779961267677454616646280680265533387751, + 2242097043846794805300929794199894663591189336184136385145099631113499174772, + 1386190096710546565463775070894284841637061467614004478240046716292821277696, + 2816874966377679501973737603936032540176708457485082336607370929612778089136, + 1478752622159543028211509150528093194034004312967359248182132430869818376336, + 3094690077264770665712892769331994678614769801107405900992789113305717410807, + 2556882057482318054270972776642508778233001279498839396867344822153826688012, + 2900121489403016707340855807566856198720058598038213131863868675535522403887, + 1073234234664905531811846691342685080930664936516225603161661094671678870815, + 1461226934604604866049769114719746564759883992929957544966480638933340287983, + 2702327468700227285978504914080938264140216891996890749465211774204450706647, + 2254736724319845643552194415243345921832668421370830806557800441682065030139, + 307523160297428780257977976491786906885850405622504065339306336048146099304, + 422159138206799602982820123448013268011982795766168707433310101309347447729, + 1879416164403286717204965632777931526119484245534871287892219973989494830794, + 713373375624412264028950925259572728325077111554426294138251774609135282381, + 564379673688277702835078004838672312789138812029648029074443487134350226833, + 1902209758606586399649428877053138849433654205067840993182841357992785940872, + 3048489349522331596112004605363507661564438561431884106102834832513881795732, + 3572406443172630622088701640863740255307743452693839609671564971609836595811, + 2289737826612346853183415773439077852569472652025838606585005707967089861260, + 993023199285981054941489031107931403028879947648558620443171875476117867435, + 3142463185489089828976244234856898105118735391221594231503006154805806148182, + 1169586780474428689507773529732330327731650910162423831533302680567835366961, + 3021558742045087425819531409847068787382713203411378652199060469430776350939, + 2878922626504605244555456671052486619427079144437462960590015140573295479764, + 1848132057457818496747916148451071034888363886849777734731437598979340137820, + 3046601294796517026903132427073883042157926876785463206312164163310789387587, + 3408537833025166968092152150240545745538524910189066469505538616471936842233, + 1034217701490475721774660515864269037343365735401730585591990662876696373225, + 2103537537340208362483662214271510340595702639477797735783725655964704136319, + 654310605680934863857450467617995866738906809773178399963931756303053976934, + 615598798296654873690785950864460044585753557362683195016108375820670801987, + 166817591382939709321381203246709645587167866326062029119837797500029165674, + 1860502055751523027078118224145752798815926782125567290022414982505845070555, + 1313293764698269996243959981676607343263304058633138510656269318850261077879, + 1707782333270327443969893569439168617667241623918425665418131694624484372111, + 670434148642834192556868733921856866793639458597560698867767756776587890736, + 188242989941728250966477903155726996125706593992200192215515746608031486747, + 718718409907380131086657892295942899618277866802106233874319197501329413311, + 710798329677363171436661699451329193410540207406138221006134261680570846412, + 1363513353361360989726222830986944279827119089726550556815487083187802128348, + 1633832794352508356428566539430807594311214188144380822932898322613701291664, + 1230150166548439665353874015119898248515956515968152170043892516855682596389, + 3539960684505379522176888401747891087612008839035294268345909141471830513090, + 3034264781001074513931349575491139119335776603637210242802558569287406699086, + 1962970594120493685364126245476583814377309928023489518895211083824292898067, + 66257002606391580215697568789962651022188977136915196770748696544788950601, + 1136092261952763398242781328017419384269118810686033506695865103547039325175, + 1321949754831082148957286240494392725112809972605433623114681037202699669159, + 3533600789431368418754466363696601128572042027837635371715527425652239503575, + 557084783001737153136723550807345866052698019311542999464649161153609646654, + 2192131584737432417949265381265430905344354922087571541076185033804105810365, + 2470150128530019869862053003991954172540370381601214946332908987440922890330, + 3374214861147789270979671083664488617000845974529874885490268061788993187605, + 2568318632302494048816657285466646103872820327803956338440258664024639093891, + 3437223361861585497437547848067230010567845882355933931536114149154060120665, + 2233297882390323756596883051372198983026140745352753569854625180831721236764, + 765892200008500178277842615606057855423019678664144825554595299510351184635, + 2326172403945615731982891803850129929261618680254146076838135121224413594990, + 970439399130880949564918989881697860952637624795537621397940144495676201583, + 3053089687189756628117664386448674176807822911573351172739954172703052712319, + 997441537995696564967709214291142970832277595585604304042044384463573336954, + 2182579188307520396706194714450722433298507349045044569005268928790642140831, + 1325476512345098396614341148479092129898584087997384813973188469789766443041, + 2411763194192548449468293150975453052774409469417732497026086239992441602628, + 1690771537735943150487624172876967216658397462582033751745837480841486560673, + 2342101350761245017655473493907861461405770116307618905322303929637183915603, + 230358809061963231401958775352193238777783082038557497169495409042531718191, + 1561107809968565617060099350319044149367719931037700431996894111813108449592, + 2558448114696620908410954691835115002255978906560904643065519848434134221519, + 1521249993337632366746192976901818549835490621316263499162651387520944167614, + 108633509189940646464027260408196695484331736308564932682316655881000370534, + 1514293734544071862670121307119151092737094252090375409732477635036964906876, + 1937264647903184969157657251865843300184869664672143640487039722327750153308, + 332033886025004419117857743702450455721426131844867630044262876436233021295, + 73340798692851351533939196278412171751337608832923189728849090004144303440, + 2203766556007431492982485418046507610979308146497976955899456817381598804802, + 2652235548391664852722592294163278194914206509780379859794068131229400933196, + 1305885346129649061938201764261574196506967065829688302066133731226438909656, + 3583403442760551239493538854826859270773086092140714914633709421722270573940, + 293410215994225935432787644965938405179872799977665320442540251604508911891, + 587058786190033130884653734672206204939724636459011462929023794635187083100, + 2150407520184546282987817223879811837701867796319658479173135531950682036584, + 2471338144488254111587190895918209293333896705234302825090389208606953807110, + 2594655757900265732690503218916851016547156215924817993614362731285197430050, + 2303718040973810105246527940333501766398527493580772048197238330525586572451, + 1811286124402587670900176414833802010066713266712333043421251274337855375411, + 999584655563485780656192567084217050135896965220771251357731089535973116303, + 1943800266122350747899924198170917953231394259093776867953009689735528718918, + 2847532554769094055506272986614630230794338162695020439057020610472063292363, + 2075229886729513571118617154643159728083581632580354029730750605453255558984, + 2346202529270524216704020236878563230116876348504511621997426335850224657885, + 2658661829294768150719084132401493415001461155551831628579412540940086437800, + 1464956643321079088566305731511406350911024525668204422249859418741379747918, + 1602039619026516795796432071811491263684535866487946755268542208855359145626, + 1095888452062249163109276452875053820208104076153099956561523707394112967313, + 3434210686143637450703059954914110840567929825381744984690514827017055677062, + 1006325254473693469236597071921346926080327502422586121519735776013447920225, + 827159557092058469120638115858948697333972264860090532973382688649169795460, + 301921821497968166198395338745536534666171779060147231752200174179201877272, + 1475735166407801880848934771653830575706713827001089038317321506089352392407, + 750253251796062152934185469599347093841646961605318864072192489993825047586, + 2516003277884236049875114558560239687915854160032491569235600049995795338533, + 882056314624010496254654062786056063260785682632634889217244866762699430233, + 1218302028230099660968808853824309726386145904562772667387103324937649240030, + 47410441678019385179680692273883000968396468472446464714671401275022077331, + 3507704123131005254379611582046185150886432486056826978517862124419227922336, + 3083201329980269665652440240511996677165604977154234276386465436679255473001, + 3536560974148870550060087089226193864923123700375639572060050172620641217211, + 864024911575408198976271672656137231030452800857497155257979679773171247764, + 678234274894813463011468754202776267439357125900410547880645613359683683011, + 904352154545810606255833411550292241908128196747568748267946808289231852823, + 529063883579889460199724594562518676982188098307303006128438931095871407454, + 169492493515015112360193213920703353379644584760064066129621414297807458466, + 1642198729697454597989493354198431533788084465357271568492922091292061255360, + 746975804785436625451775059536161434437159239635129865696680040039055644047, + 2137920974942687073519947196935766367848539731821606292678922707832548177739, + 2586234449530276766976459318600061691246735074161267293071559906130664582951, + 2839005011034331389013320728910413926062215155213111515770037403032406003009, + 1971465039015895709022403825629042804352824946569549395953116581659513370708, + 3006138323649353267827332258497531510804249476917111851155708018939579570409, + 2442095697868483564914996847176974894647146088980699463352528368218218170008, + 469647599172146712177827089995981964705440477759397106450968380889435069914, + 3032852495736164739889792712199502303166643379218011726069615626405739435868, + 3544545631445127837211638802435426220193351340816642825277438748044680411924, + 2570745165138696516016541531659900787331203110438474704633300605321321997369, + 1290081573964307542372121738468010286763375699287809321445165051560050574388, + 2847969567506181096652080073556266970138948635315014788991605611422168512348, + 2547101439733322682049508793411643627382324919698377673613751833387295061383, + 3447634605771980051801147445082455907013341658055810836558291999518362544418, + 1258009981626009823520960281183667502181809826868994016821662884337984092560, + 2760954768550921764497194228393330477017584820185248732778295496241376149439, + 523169225193455123114452921159961094219199498077390196191320179361246991520, + 1294596883396776203060941054363429032088557477437155960403585221412687287182, + 288800468688278864896470050765671639129700086955108504054020768116052707090, + 2468978336071725302848658679400789864465811780780728557977456906685888788877, + 3317024347708092036476239032248803309774338814275541910856206800771571503112, + 2780085434370427249308344692653920464750631354967346805479909800210463937206, + 486026077041799563185429314965670971298614486069533188522289730577568951657, + 2970951898577375164617494450094923626475817534856401390346445489341187510652, + 2147246402335260204351966111452001438912001217103644504354162011215547281389, + 3105358873598779688136269890148610063243460168642951565500614657107261301155, + 1597845195336670304375995901527160786140234425066429241920337046365622634383, + 79158809849126032453909331890585247935997148192097869824350567345309087442, + 1089853365138175072990678408013823356881932386038708461016708403459299112358, + 1828730528862225994575045470435311572832603679535003009201956241379545595908, + 2423122771446695210338915299514531096260510040117280315549154218032840196954, + 2042362543768565837424487924749480326247814715537793357448525524129472651807, + 1241088350685107046926140119828729070131646609606115344136301427749148538936, + 526853293679232049622062050203329866924700206348643482413957577843535846603, + 16904833609592933878519785550117878618285498162435789619575308844196414105, + 2595985460780321632500145099405204679692603086780827773753306548261044099403, + 3343052391865166912379279489580278591777254875619981911966424379312846835404, + 844269780887986730080164860819518091750658423040990097905701442931092846612, + 2210428610068070737940561358130031752057024621537978119418458198889815264724, + 3289823310007963315400699386831226779385028915192239950443884290820684431266, + 1456524018669269927356774584176032722919391117248068741711388803536812069214, + 1062302182823756748536903298901432905808157008923021738870879386332742721265, + 2620924264708634446836813808133803064590036120583265521038797933501396422112, + 1283804179030223827121559392708417905149303000718015706569871342604416864168, + 3253588522586053070559956711843914262406207113989826302099046619494523438403, + 3290480612754761306548955172865740112872178547552558020890688662383125084768, + 1533332531630466167352699922672288212852248610629117741378329648447938745772, + 1947096354423020739624303585222396741145953378167789653032080404174154427446, + 1658313302134441307025235957407244624123766921618947615066847654466370582441, + 3048956323510244596210586066398807852908152327567141462962017156527808807855, + 1609460951786842039880973475728635027441935418429390426285163637814243450758, + 271294684213433231433201144509536601188147812087397475203706166338925472031, + 3517293987817830543135889807460362211024217384284220990520901209950409375714, + 1130382079332166849201608015745457085070899781987806571831063234763802986037, + 2451378486632308351747834573561461020229773908553120693423142311093697249958, + 2801306157054196285613455484004268515056206279180046386351332939812847402215, + 761966980109770963059284556206631099404840865484422764230671820803410568253, + 1415832235751652985068862965539557276462800915107460865143067462748428437462, + 1230205903081981106307527935788097792715801761939337416289860980321291932719, + 779063135519097382416659381010727001113002814074703007031749972296267870097, + 2771578477105867799518735035412425951793966189480503130096112275835239671145, + 747166523398871957058823380709301608891389458651053874391265076826672645072, + 2009302245367057041339612549391577132819405419649993552068743377026381329381, + 297648642788530450181074284758935572509177032195479842989657894085594643698, + 1844741628168105483086731205606776328241869199734782481149141770423849922642, + 2294724932662546198762557370644890433609184347461828260732537113468881203576, + 3083250685656704566419498045532557696273844944350520447383434278833899719352, + 1191636465954155060827876251749615917768182312580213555566515324056753534455, + 2324604955732769741785520239635529530416426122946914934495064533683067725578, + 1163503616080812514505809482223548187688141254885935976223361692117901243991, + 1610730230301103413758336771030429455409670251592805061259232855775647026663, + 3085508393947463058452423066106900398549735498745486676782599323500520667122, + 2285188801711740880446401178565166053849951495141877937215895091136495374780, + 1848411173302705561038319501302068754972800232497302807920279065074086321972, + 1250984099040930707876880131382857048738532014182887515658005429433082113532, + 721900092220495471731473133237517561817004316409844743934354901709604340533, + 1079980865741637903126235489052730574535979418630602440296244386786152496182, + 2230898128352923696703791400754489060212021615073090874029859730143129537041, + 2857413068228132386494715115171770743640669310207302251107296167462110756239, + 1504789471693524462611439894370612072128624422967184627911276899833974141739, + 816511396673062660268968292929183740444295323937538885450187927777061459087, + 2082441976691688352350310436004624009406143617909030079046806193850777238428, + 2167140723175373200170628228500397714678264688514353023411309431377754202099 + ]; + verify_last_layer(queries.span(), coefficients.span()); +} From 083728dcc7708ff8d4675834466e8f2ad3502170 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 25 Dec 2023 17:39:01 +0100 Subject: [PATCH 33/38] test_next_layer --- src/fri/fri_layer.cairo | 43 +- src/fri/tests.cairo | 1 + src/fri/tests/test_next_layer.cairo | 1221 +++++++++++++++++++++++++++ 3 files changed, 1249 insertions(+), 16 deletions(-) create mode 100644 src/fri/tests/test_next_layer.cairo diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index bcdd03c4c..740a469c6 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -1,3 +1,7 @@ +use core::debug::PrintTrait; +use core::option::OptionTrait; +use core::traits::TryInto; +use core::traits::Into; use core::array::SpanTrait; use core::array::ArrayTrait; use cairo_verifier::fri::fri_formula::fri_formula; @@ -10,7 +14,7 @@ struct FriLayerComputationParams { eval_point: felt252, } -#[derive(Drop, Copy)] +#[derive(Drop, Copy, PartialEq)] struct FriLayerQuery { index: felt252, y_value: felt252, @@ -33,8 +37,8 @@ struct FriLayerQuery { // query was consumed by this function. fn compute_coset_elements( - queries: Span, - sibling_witness: Span, + ref queries: Span, + ref sibling_witness: Span, coset_size: felt252, coset_start_index: felt252, mut offset_within_coset: felt252, @@ -52,12 +56,13 @@ fn compute_coset_elements( break; } - if i != i_len && *queries.at(i).index == coset_start_index + offset_within_coset { - coset_elements.append(*queries.at(i).y_value); - coset_x_inv = (*queries.at(i).x_inv_value) * (*fri_group.at(i + j)); + if i != i_len && (*queries.at(0)).index == coset_start_index + offset_within_coset { + let query = *queries.pop_front().unwrap(); + coset_elements.append(query.y_value); + coset_x_inv = (query.x_inv_value) * (*fri_group.at(i + j)); i += 1; } else { - coset_elements.append(*sibling_witness.at(j)); + coset_elements.append(*sibling_witness.pop_front().unwrap()); j += 1; } @@ -80,28 +85,35 @@ fn compute_coset_elements( // - 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( - queries: Span, sibling_witness: Span, params: FriLayerComputationParams, + mut queries: Span, + mut sibling_witness: Span, + params: FriLayerComputationParams, ) -> (Array, Array, Array) { let mut next_queries = ArrayTrait::::new(); let mut verify_indices = ArrayTrait::::new(); let mut verify_y_values = ArrayTrait::::new(); let coset_size = params.coset_size; - - let len = queries.len(); - let mut i: u32 = 0; loop { - if i == len { + if queries.len() == 0 { break; } - let coset_index = *(queries.at(i)).index; + let index_u256: u256 = (*queries.at(0).index).into(); + let coset_size_u256: u256 = coset_size.into(); + + let coset_index = (index_u256 / coset_size_u256).low.into(); assert(coset_index.into() >= 0_u256, 'Must be non negative value'); verify_indices.append(coset_index); let (coset_elements, coset_x_inv) = compute_coset_elements( - queries, sibling_witness, coset_size, coset_index * coset_size, 0, params.fri_group + ref queries, + ref sibling_witness, + coset_size, + coset_index * coset_size, + 0, + params.fri_group ); // Verify that at least one query was consumed. @@ -116,6 +128,7 @@ fn compute_next_layer( break; } verify_y_values.append(*(coset_elements_span.at(j))); + j += 1; }; let fri_formula_res = fri_formula( @@ -130,8 +143,6 @@ fn compute_next_layer( index: coset_index, y_value: fri_formula_res, x_inv_value: next_x_inv } ); - - i += 1; }; (next_queries, verify_indices, verify_y_values) diff --git a/src/fri/tests.cairo b/src/fri/tests.cairo index 1ae9a8e07..4433cd527 100644 --- a/src/fri/tests.cairo +++ b/src/fri/tests.cairo @@ -1,2 +1,3 @@ mod test_fri_formula; mod test_last_layer; +mod test_next_layer; diff --git a/src/fri/tests/test_next_layer.cairo b/src/fri/tests/test_next_layer.cairo new file mode 100644 index 000000000..565edcec8 --- /dev/null +++ b/src/fri/tests/test_next_layer.cairo @@ -0,0 +1,1221 @@ +use core::debug::PrintTrait; +use core::array::ArrayTrait; +use cairo_verifier::fri::fri_layer::{FriLayerQuery, FriLayerComputationParams, compute_next_layer}; +use cairo_verifier::fri::fri_group::get_fri_group; + +#[test] +#[available_gas(9999999999)] +fn test_next_layer1() { + let queries = array![ + FriLayerQuery { + index: 19, + y_value: 3009640132648008425771663319959959262486220333099664427328058765768842449250, + x_inv_value: 54553547539894122403827046258314152559223416585866015792288871627619859008 + } + ]; + let sibling_witness = array![ + 1123008634785466227765787920403783137942925653310144335875674694591276473192 + ]; + let params = FriLayerComputationParams { + coset_size: 2, + fri_group: get_fri_group().span(), + eval_point: 2443479172752326919986485065418726216145528469562787664528210275186695390471 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 9, + y_value: 2185991974161515735589370697017442079762615282775874094325294026252936541583, + x_inv_value: 1697286867097833219836294983908733326167501326977247172278435262719557593504 + } + ]; + let expected_verify_indices = array![9]; + let expected_verify_y_values = array![ + 1123008634785466227765787920403783137942925653310144335875674694591276473192, + 3009640132648008425771663319959959262486220333099664427328058765768842449250 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer2() { + let queries = array![ + FriLayerQuery { + index: 17, + y_value: 2759623090142790690855098103901650892631267048724128835098128315349419136695, + x_inv_value: 108072969398534483334507045980403840714691619221758030761568305841993401905 + } + ]; + let sibling_witness = array![ + 522165234549733937327724288257767164912068272740875848443122078655609268368, + 62652482029070998724738900051279388447617017224333293756545714721568375652, + 2828526802429981059567341974328690206758626003655409262291038410023069024668 + ]; + let params = FriLayerComputationParams { + coset_size: 4, + fri_group: get_fri_group().span(), + eval_point: 1982585344331058375026005306471531766707340420809531025829328268083147325627 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 4, + y_value: 1077998794348284354598652343293562698049252500211550192464629080328316673698, + x_inv_value: 2633238744713263728019330547123200367032740465948237927517365901877698129956 + } + ]; + let expected_verify_indices = array![4]; + let expected_verify_y_values = array![ + 522165234549733937327724288257767164912068272740875848443122078655609268368, + 2759623090142790690855098103901650892631267048724128835098128315349419136695, + 62652482029070998724738900051279388447617017224333293756545714721568375652, + 2828526802429981059567341974328690206758626003655409262291038410023069024668 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer3() { + let queries = array![ + FriLayerQuery { + index: 22, + y_value: 1231175216455939321078564173742303628142533875402290207354372253959167512307, + x_inv_value: 3549719361548528048410263413791561966844406610277484802193762821339412459253 + } + ]; + let sibling_witness = array![ + 1195728970024453214596842786271366866852813595571023478251747255080180444356, + 3555912416221887452080706698058141424221979180551367818897445190733400868353, + 34862776383371782462703678371984446188640175125871204165516625259686550614, + 696195716834231608288788009791330705738847261355229689955205457557899136571, + 2406075573647619823270675912178389603227671840135528066638010667847181325236, + 1443348866565840245319023638700994949540305260981210463118495875007167932493, + 534188447380076871805292320071703806717768188674590858686911614529936239219 + ]; + let params = FriLayerComputationParams { + coset_size: 8, + fri_group: get_fri_group().span(), + eval_point: 2996681160573045082893848544757424160476352714075260471151952365319051355220 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 2, + y_value: 1177504462272530471841134041622641579704605903617132590626888326120254257690, + x_inv_value: 1047036369304219502363557810404294786592772605083308486097044742656766540637 + } + ]; + let expected_verify_indices = array![2]; + let expected_verify_y_values = array![ + 1195728970024453214596842786271366866852813595571023478251747255080180444356, + 3555912416221887452080706698058141424221979180551367818897445190733400868353, + 34862776383371782462703678371984446188640175125871204165516625259686550614, + 696195716834231608288788009791330705738847261355229689955205457557899136571, + 2406075573647619823270675912178389603227671840135528066638010667847181325236, + 1443348866565840245319023638700994949540305260981210463118495875007167932493, + 1231175216455939321078564173742303628142533875402290207354372253959167512307, + 534188447380076871805292320071703806717768188674590858686911614529936239219 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer4() { + let queries = array![ + FriLayerQuery { + index: 17, + y_value: 107634985777525198719457933516612993333665001206557081850887267601999593307, + x_inv_value: 2917507526425378062891209641407297049970803804883101888033200410523468508223 + } + ]; + let sibling_witness = array![ + 1614105094820940547932979114275805368596980954610062272415295623855966399938, + 693587070670384874498002073212674337957886491570174639651952635034011361113, + 2182054027909863057980719290814912799438309188705871708423148386048500700847, + 579245916215486054657055829208838661465548354405390013595741995516616171747, + 206723450099456388370132180591200306073574204819219299553175570756285822026, + 3524319317286904222424614883191482747595752362299160824591033064099431860213, + 1615763850381464616809768799515161240452636705929717067365888125718637628955, + 2729371020733114790122637155341724770739308317400814921599877096616014204365, + 1806835039103743571152839213406116029435349363650311405025412410058267953618, + 2334207046869053906415701809206802130396448163287773354046680229797406108795, + 846585632776363760500914046737920171446148160923054894684140117835211041704, + 3583160895940362754785449698054871358616520492881184046653896695508292242503, + 594594828186152981815670652237875899521490193148447582824261477355572427969, + 382626503505367944553110895981418673385282307671448132202545565018242767288, + 3476983551724853290554915215874670223757771126370434051488495793846971603388 + ]; + let params = FriLayerComputationParams { + coset_size: 16, + fri_group: get_fri_group().span(), + eval_point: 3246137206661909741808114726375056135951563790002136626674903353340777908146 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 1, + y_value: 1441275254889998903858094604425484342000396355353206424417863045484990540435, + x_inv_value: 1829818947064372678210995598394063122549682555566012270431529834421656963592 + } + ]; + let expected_verify_indices = array![1]; + let expected_verify_y_values = array![ + 1614105094820940547932979114275805368596980954610062272415295623855966399938, + 107634985777525198719457933516612993333665001206557081850887267601999593307, + 693587070670384874498002073212674337957886491570174639651952635034011361113, + 2182054027909863057980719290814912799438309188705871708423148386048500700847, + 579245916215486054657055829208838661465548354405390013595741995516616171747, + 206723450099456388370132180591200306073574204819219299553175570756285822026, + 3524319317286904222424614883191482747595752362299160824591033064099431860213, + 1615763850381464616809768799515161240452636705929717067365888125718637628955, + 2729371020733114790122637155341724770739308317400814921599877096616014204365, + 1806835039103743571152839213406116029435349363650311405025412410058267953618, + 2334207046869053906415701809206802130396448163287773354046680229797406108795, + 846585632776363760500914046737920171446148160923054894684140117835211041704, + 3583160895940362754785449698054871358616520492881184046653896695508292242503, + 594594828186152981815670652237875899521490193148447582824261477355572427969, + 382626503505367944553110895981418673385282307671448132202545565018242767288, + 3476983551724853290554915215874670223757771126370434051488495793846971603388 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer5() { + let queries = array![ + FriLayerQuery { + index: 0, + y_value: 746591562936821030835715747889843595163396575226181906015101280529866617133, + x_inv_value: 2839890473743673236434239057700432645437719700778360715637471771392219034326 + }, + FriLayerQuery { + index: 9, + y_value: 432934865743208963457432082990566669321350335050040579267198873031828688172, + x_inv_value: 2944384488565703107562664215590005833661704434344191167631969776808729729163 + } + ]; + let sibling_witness = array![ + 2207292640602765987605417203853603264378518893482237233873998269956850458932, + 288897229768628159275046633516552015154393884429636644820405109361062428074 + ]; + let params = FriLayerComputationParams { + coset_size: 2, + fri_group: get_fri_group().span(), + eval_point: 2185465603412249558871549627667757930155426034864563482170756257080076225958 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 0, + y_value: 1960029025666243333485194840332621335802675978036586078469434126072698208300, + x_inv_value: 3009148876954521410390276225740133816385634755252667189136222755512973018079 + }, + FriLayerQuery { + index: 4, + y_value: 501258974496117438650836974499861760052921694630156096214408435425138801490, + x_inv_value: 1715280836225574219633496220661969295029181757403817732538849012006942881738 + } + ]; + let expected_verify_indices = array![0, 4]; + let expected_verify_y_values = array![ + 746591562936821030835715747889843595163396575226181906015101280529866617133, + 2207292640602765987605417203853603264378518893482237233873998269956850458932, + 288897229768628159275046633516552015154393884429636644820405109361062428074, + 432934865743208963457432082990566669321350335050040579267198873031828688172 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer6() { + let queries = array![ + FriLayerQuery { + index: 5, + y_value: 1096892199810651185152195112986319610579001690328932435764292779877576915121, + x_inv_value: 3279544897416438008064089022127475409847685010480359106267514969650981832082 + }, + FriLayerQuery { + index: 19, + y_value: 1641855356491365833554692237319212189801903876432464673866647716719043041465, + x_inv_value: 2293250085048948415112043044736231472430743506786581498262287561751356762014 + } + ]; + let sibling_witness = array![ + 804399642855128535722354372618913360973130781887293769086134887025287828450, + 1987605673743133585231493245929792399393204021630711397835563456074854788026, + 1233031324852744699980974111822491085958694791795843758111112233603894427238, + 1810994839619816704905050921987428341202461226961859918732361321793970914107, + 1892124182925365936167405294153806740491710255246363205322154303233181243718, + 1337441648818842689794955442935277091168720593363441772344593529889075124973 + ]; + let params = FriLayerComputationParams { + coset_size: 4, + fri_group: get_fri_group().span(), + eval_point: 2167335350971787138507326388801205881447440912920817749862011161467677463940 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 1, + y_value: 1181712651684323748024837749719027006506698122447393260787788152426027849043, + x_inv_value: 1653115732351104701033693337462649968391138809812222376293178295401862046874 + }, + FriLayerQuery { + index: 4, + y_value: 1268308829684608985195972079707177792876762551009734230680402124542318187648, + x_inv_value: 1164447905508868651636386487771626691241643134212100820768777787963076904518 + } + ]; + let expected_verify_indices = array![1, 4]; + let expected_verify_y_values = array![ + 804399642855128535722354372618913360973130781887293769086134887025287828450, + 1096892199810651185152195112986319610579001690328932435764292779877576915121, + 1987605673743133585231493245929792399393204021630711397835563456074854788026, + 1233031324852744699980974111822491085958694791795843758111112233603894427238, + 1810994839619816704905050921987428341202461226961859918732361321793970914107, + 1892124182925365936167405294153806740491710255246363205322154303233181243718, + 1337441648818842689794955442935277091168720593363441772344593529889075124973, + 1641855356491365833554692237319212189801903876432464673866647716719043041465 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer7() { + let queries = array![ + FriLayerQuery { + index: 7, + y_value: 3075517878492540103040166847866926446865777778640852962190520816632339596145, + x_inv_value: 608694432915418906087773663985135750833888921733668764639429291959306418477 + }, + FriLayerQuery { + index: 27, + y_value: 131983826742021719455910211379866988384811584925288184480272187873636838108, + x_inv_value: 1974198664155436145837620318999161049479840212206498623330601633289848275514 + } + ]; + let sibling_witness = array![ + 1381946771663536271686283445165923669245048036336685207435678635918790010415, + 987192345921964650774860449076993743666953560925616837171412357893248515453, + 1894120995282262673257341015927038862976390070699798006337306824994818751092, + 1538484798885111384061490573014877696930911320706092642348929689059341036045, + 2831036501176131779443820825633947566967253654306554236912113528745500638916, + 2795762391236757584469537519991014507421060627124928065640245513052288926693, + 2962264866957003315891979312858498756904185604349911432280048675808497143212, + 1274615238507625446045782756423380204591533819608003040326255896608966494630, + 2433725008144059202602710302459177343649577363035970221093985127914132732545, + 3615760742796657913769142930324341926341661354106616058377178459338456365110, + 876491878808193133805417604582642436856178348784148668921521578336602541775, + 1681379446663085402254280534212103014447726541607694761283737523967486068323, + 2765034771912257979612046850994949532603486328163588398162583894664641390299, + 2828844164871944409923044279501485001881689120102902225098373010416437899881 + ]; + let params = FriLayerComputationParams { + coset_size: 8, + fri_group: get_fri_group().span(), + eval_point: 384372973063416357441038011066619352380639619775069754153768649812098431519 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 0, + y_value: 3519382920442250662715268714283575071860170073120425261766286332519433463480, + x_inv_value: 266451709395649792495102217411295552361654455242989832116307089851296053314 + }, + FriLayerQuery { + index: 3, + y_value: 3413008593626981122050040132687328477275093156117246104307650363140459009419, + x_inv_value: 1107290807486481817999551113742590485010425323783882499076376127930136554678 + } + ]; + let expected_verify_indices = array![0, 3]; + let expected_verify_y_values = array![ + 1381946771663536271686283445165923669245048036336685207435678635918790010415, + 987192345921964650774860449076993743666953560925616837171412357893248515453, + 1894120995282262673257341015927038862976390070699798006337306824994818751092, + 1538484798885111384061490573014877696930911320706092642348929689059341036045, + 2831036501176131779443820825633947566967253654306554236912113528745500638916, + 2795762391236757584469537519991014507421060627124928065640245513052288926693, + 2962264866957003315891979312858498756904185604349911432280048675808497143212, + 3075517878492540103040166847866926446865777778640852962190520816632339596145, + 1274615238507625446045782756423380204591533819608003040326255896608966494630, + 2433725008144059202602710302459177343649577363035970221093985127914132732545, + 3615760742796657913769142930324341926341661354106616058377178459338456365110, + 131983826742021719455910211379866988384811584925288184480272187873636838108, + 876491878808193133805417604582642436856178348784148668921521578336602541775, + 1681379446663085402254280534212103014447726541607694761283737523967486068323, + 2765034771912257979612046850994949532603486328163588398162583894664641390299, + 2828844164871944409923044279501485001881689120102902225098373010416437899881 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer8() { + let queries = array![ + FriLayerQuery { + index: 14, + y_value: 2812191291368465400252368036784849631295311044099688251864335547264648760929, + x_inv_value: 3327960025629984902906808973965115139132894388720619540209395295175202435223 + }, + FriLayerQuery { + index: 28, + y_value: 945312106572582053105339715798467543580544183072055346899673660213540546488, + x_inv_value: 1982376188084661049306441397930389303876068734739596367142474139857967005184 + } + ]; + let sibling_witness = array![ + 2949257002824431099820924461178954292967579447203636252898226318072740386824, + 2109770268208121078753001053403331765076608697772559113071033136250869504473, + 2388297558783464615628997798028262325218009201379703050956169802493581047973, + 3525692657203325625152712276222448417400555150313331588381183925321722344670, + 1770128582224668658932820753069082677343177339697504686745994727405384368826, + 2277509151931760256130277827415848713946907170081107197539171861875808782840, + 553506533886672046972094815070428061413496218667260813272218476397542394126, + 1325795902063165511059838253657321320005294114487993699345770044761244463890, + 669828035369528580542389024653781788264954760854641450329504420359621694341, + 3390712226968146726780043862598840971254869615115905720403199256814995219514, + 1826681158268766190323480513465452190809042283119310757871839564743833787919, + 1145304238778090805545988213888864245409497800124759254791897692806774757770, + 1397068525986579081352897876232234437189969937826283879172500553676064940439, + 2104875872195729864851606343399273464419019953918563072841629145823575557945, + 1158938700019692875943299533882908302674841511080317290819608130684595336457, + 2365573810001212351939469441049776991978930374259229467362964834664954075464, + 224204551411584072281213703508765114269364171685297633020108282783402412102, + 1136885745908677333683443250622936914218130194199188396198410064853784245116, + 2577202183647129179972590136619634609575314391523504634933521339842505024250, + 1218879808821400330218160186881430073477575542748635158557783902419507248023, + 1492583771642768717317176274379006337265687706897820888128354257084402032954, + 1147051782978409736537631164196473096558884903070473339936475019730892606292, + 1170923665353223025390644385475570698017370798971415401329877009135901058934, + 2714965104434656612067886463451103798146458879447249983304400313485321454858, + 3029036750822909179098438143195941816494025920675957101572384069330532165665, + 18409245281450708426000590154856732233696909859426757887349330897284752834, + 1903399152209210559959462040157108438124673941817349364218680564081568770298, + 2260002643446022813142304377372681801652650136648130581924766564336949881263, + 3155765214842786052334914920203360592720185878259088994232602983562348781025, + 3485201017653558756685420512495162933189527567610822904102000763401993219662 + ]; + let params = FriLayerComputationParams { + coset_size: 16, + fri_group: get_fri_group().span(), + eval_point: 52871414864247307776012409456547680662415039421837737271534775961443350705 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 0, + y_value: 2731422975982182882081741213504406076248280179242291132508067217003010322490, + x_inv_value: 3183581941728587291517385359778659637268454365590489450398239584747532037461 + }, + FriLayerQuery { + index: 1, + y_value: 3228016798076912219844600739928191932167567203345640315464632263570697784005, + x_inv_value: 434920846937543922179937423316410468354652849741107249574852471388339983020 + } + ]; + let expected_verify_indices = array![0, 1]; + let expected_verify_y_values = array![ + 2949257002824431099820924461178954292967579447203636252898226318072740386824, + 2109770268208121078753001053403331765076608697772559113071033136250869504473, + 2388297558783464615628997798028262325218009201379703050956169802493581047973, + 3525692657203325625152712276222448417400555150313331588381183925321722344670, + 1770128582224668658932820753069082677343177339697504686745994727405384368826, + 2277509151931760256130277827415848713946907170081107197539171861875808782840, + 553506533886672046972094815070428061413496218667260813272218476397542394126, + 1325795902063165511059838253657321320005294114487993699345770044761244463890, + 669828035369528580542389024653781788264954760854641450329504420359621694341, + 3390712226968146726780043862598840971254869615115905720403199256814995219514, + 1826681158268766190323480513465452190809042283119310757871839564743833787919, + 1145304238778090805545988213888864245409497800124759254791897692806774757770, + 1397068525986579081352897876232234437189969937826283879172500553676064940439, + 2104875872195729864851606343399273464419019953918563072841629145823575557945, + 2812191291368465400252368036784849631295311044099688251864335547264648760929, + 1158938700019692875943299533882908302674841511080317290819608130684595336457, + 2365573810001212351939469441049776991978930374259229467362964834664954075464, + 224204551411584072281213703508765114269364171685297633020108282783402412102, + 1136885745908677333683443250622936914218130194199188396198410064853784245116, + 2577202183647129179972590136619634609575314391523504634933521339842505024250, + 1218879808821400330218160186881430073477575542748635158557783902419507248023, + 1492583771642768717317176274379006337265687706897820888128354257084402032954, + 1147051782978409736537631164196473096558884903070473339936475019730892606292, + 1170923665353223025390644385475570698017370798971415401329877009135901058934, + 2714965104434656612067886463451103798146458879447249983304400313485321454858, + 3029036750822909179098438143195941816494025920675957101572384069330532165665, + 18409245281450708426000590154856732233696909859426757887349330897284752834, + 1903399152209210559959462040157108438124673941817349364218680564081568770298, + 945312106572582053105339715798467543580544183072055346899673660213540546488, + 2260002643446022813142304377372681801652650136648130581924766564336949881263, + 3155765214842786052334914920203360592720185878259088994232602983562348781025, + 3485201017653558756685420512495162933189527567610822904102000763401993219662 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer9() { + let queries = array![ + FriLayerQuery { + index: 10, + y_value: 3301979551015115642776773522833072926462865561144560488920209857718769165321, + x_inv_value: 2447768544415408676335928447643487449650900913681401829424717259768986472741 + }, + FriLayerQuery { + index: 28, + y_value: 260750552966409642499431036714653525048800120747768231293468725416260188565, + x_inv_value: 3563529224071196680374798485546840836554333985312746699506733128078602078641 + }, + FriLayerQuery { + index: 29, + y_value: 1823311453035327473280509270574026429844738895506436406781130453908277513530, + x_inv_value: 54973564594934533322524297548229269068773230018850000466358928057269941840 + } + ]; + let sibling_witness = array![ + 3176532942878567276526900338617699157909586755721347090315239907293123933092 + ]; + let params = FriLayerComputationParams { + coset_size: 2, + fri_group: get_fri_group().span(), + eval_point: 581747590720875793993157628416105910892274340828581484518962213541176928984 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 5, + y_value: 3275133527488003020272254384265923882734156428348855484827341126286781354142, + x_inv_value: 2615309274026883345480537437370039939583535394834355181916645336586036374461 + }, + FriLayerQuery { + index: 14, + y_value: 2611221225089844146967129398570862707600738146407577663333768748170096584339, + x_inv_value: 1675506256769046824455009524724840487217963849380458734340688061164470257879 + } + ]; + let expected_verify_indices = array![5, 14]; + let expected_verify_y_values = array![ + 3301979551015115642776773522833072926462865561144560488920209857718769165321, + 3176532942878567276526900338617699157909586755721347090315239907293123933092, + 260750552966409642499431036714653525048800120747768231293468725416260188565, + 1823311453035327473280509270574026429844738895506436406781130453908277513530 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer10() { + let queries = array![ + FriLayerQuery { + index: 5, + y_value: 2302109513041081253191847726874632617695812467358434547038386746651006842380, + x_inv_value: 2637474160357003981779699526943464856611941641202539833636026322990388707333 + }, + FriLayerQuery { + index: 13, + y_value: 2421144434847175762056784279666434264733454757381019920618274713336842008821, + x_inv_value: 3087662183041901605559596075538966726399103482477428404944198306175727302850 + }, + FriLayerQuery { + index: 22, + y_value: 1359842048097095741378484164247564983223481090058269548624795715692521460139, + x_inv_value: 185282605276538732396669144005696787636433561792146384397375513028006583411 + } + ]; + let sibling_witness = array![ + 3354395884762193735774972945190699549697221284699421903066644213798392549402, + 2286699216817078029209012960176095129558820839353213366512757899588073849784, + 1807058458070289484044641026995619421272336800548938509837361700372957815942, + 2613264906789519132611022617468068727030402878438205130898569384174203487539, + 1731512844646762096812644150851970912816865225259598591671476871772161992367, + 2809244789545431804862877174186922907097032744568338981087812219597365747358, + 3584511590009863696665267819675356849136392492253578574053929941069778312453, + 2319520140453873363680878801076253902750880806504432226644283646473284304066, + 3403040452882679612874283723507253802829979450632690322212356915241676774155 + ]; + let params = FriLayerComputationParams { + coset_size: 4, + fri_group: get_fri_group().span(), + eval_point: 842716418594610507165719701550798710728706432825705961415071015594374037783 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 1, + y_value: 738283733844654320656593304955937814018241368923162576526604344171964798523, + x_inv_value: 473662685190715868134016058090152279944149415440903111962958772704259767472 + }, + FriLayerQuery { + index: 3, + y_value: 969134386771919091675706269957962126061036556734351502037905523368628343664, + x_inv_value: 2176451726708652476016850844470876509775490912344006510026083913284976867308 + }, + FriLayerQuery { + index: 5, + y_value: 2830771694438643841398564545385741940324054273824824277829790639217160649922, + x_inv_value: 2650304629722060934084881169738268161214211940849246175729038797083499024587 + } + ]; + let expected_verify_indices = array![1, 3, 5]; + let expected_verify_y_values = array![ + 3354395884762193735774972945190699549697221284699421903066644213798392549402, + 2302109513041081253191847726874632617695812467358434547038386746651006842380, + 2286699216817078029209012960176095129558820839353213366512757899588073849784, + 1807058458070289484044641026995619421272336800548938509837361700372957815942, + 2613264906789519132611022617468068727030402878438205130898569384174203487539, + 2421144434847175762056784279666434264733454757381019920618274713336842008821, + 1731512844646762096812644150851970912816865225259598591671476871772161992367, + 2809244789545431804862877174186922907097032744568338981087812219597365747358, + 3584511590009863696665267819675356849136392492253578574053929941069778312453, + 2319520140453873363680878801076253902750880806504432226644283646473284304066, + 1359842048097095741378484164247564983223481090058269548624795715692521460139, + 3403040452882679612874283723507253802829979450632690322212356915241676774155 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer11() { + let queries = array![ + FriLayerQuery { + index: 13, + y_value: 2012970895874678511212757784953971039384348922302933461566125878983543084374, + x_inv_value: 2973904717437488251876439033512297970752041300850017169618797599259028370719 + }, + FriLayerQuery { + index: 27, + y_value: 931874247810412416165687814293757020658355126150232036748630683953363661570, + x_inv_value: 584004069736012205202772085193423872545377990373199751488130188652560879737 + }, + FriLayerQuery { + index: 29, + y_value: 1239648551389298716869809742099762563284007154271743710729395207873328754095, + x_inv_value: 325989084577145299562436609653878858069349249438264163435312273435225996502 + } + ]; + let sibling_witness = array![ + 3132112378686662059596343294646770786600609238470988213583095363604854334582, + 2461092923487112471463153426310804127458685592080740231075091398736912158061, + 2998509969357752287758672740593580020870026463294812456319673321073443088049, + 555035695605537330949170393875380217638990235130626619093741676287189098559, + 72018361044517802373614267173646257173391950275613610500963681187632366491, + 1356567855831745726697989920693118254887070010792127324660019977162220321572, + 3428903427156557890470369121770217952589955280129158495181620864445963618926, + 393083682526902362021532263518007213667960307630114380176309035415220154175, + 228421633383768634897088966132917335392548875057781107304223464921146078457, + 924492636261377530436326039939616684788498986913092833064848468110206034446, + 3215569544372428665026066156374535625549998775193271484978178438432055593239, + 89314992381896491523088980471634454610386898184975529899102140430198625686, + 3187985426015104063712461074067156374723555157039404691369397066532053540037 + ]; + let params = FriLayerComputationParams { + coset_size: 8, + fri_group: get_fri_group().span(), + eval_point: 1891358614242486301056439669334692072313573517224693441784224259774268368657 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 1, + y_value: 3517289172167603711982011298083512014029690033243282325518726512433806986800, + x_inv_value: 1116757482133226363159883558057382197314289333955735205211445722872102609428 + }, + FriLayerQuery { + index: 3, + y_value: 2418454055988269773691328349827589783726829031083650466961892768926964470890, + x_inv_value: 3351334608504925878396027162037002984645156260554050897526626427695988305073 + } + ]; + let expected_verify_indices = array![1, 3]; + let expected_verify_y_values = array![ + 3132112378686662059596343294646770786600609238470988213583095363604854334582, + 2461092923487112471463153426310804127458685592080740231075091398736912158061, + 2998509969357752287758672740593580020870026463294812456319673321073443088049, + 555035695605537330949170393875380217638990235130626619093741676287189098559, + 72018361044517802373614267173646257173391950275613610500963681187632366491, + 2012970895874678511212757784953971039384348922302933461566125878983543084374, + 1356567855831745726697989920693118254887070010792127324660019977162220321572, + 3428903427156557890470369121770217952589955280129158495181620864445963618926, + 393083682526902362021532263518007213667960307630114380176309035415220154175, + 228421633383768634897088966132917335392548875057781107304223464921146078457, + 924492636261377530436326039939616684788498986913092833064848468110206034446, + 931874247810412416165687814293757020658355126150232036748630683953363661570, + 3215569544372428665026066156374535625549998775193271484978178438432055593239, + 1239648551389298716869809742099762563284007154271743710729395207873328754095, + 89314992381896491523088980471634454610386898184975529899102140430198625686, + 3187985426015104063712461074067156374723555157039404691369397066532053540037 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer12() { + let queries = array![ + FriLayerQuery { + index: 5, + y_value: 2526228053058749206268429435387221189473358598063225073128406154185646521246, + x_inv_value: 1904544901132915451045519411426603084952282873219697946725409068121461435004 + }, + FriLayerQuery { + index: 10, + y_value: 56624383172680154199608666479407795256819238702017594377613749554501152230, + x_inv_value: 452303108377316774348461853687416241963542162729446056484774660062242979361 + }, + FriLayerQuery { + index: 24, + y_value: 1280082646894980092283175931172370782094547118060861067319301021219059720426, + x_inv_value: 1283983430867922805177012513424768198429485865021963916551986827081913277268 + } + ]; + let sibling_witness = array![ + 1207893144587700365996195575736463898273419338985626305569288268445097779644, + 2244256048781475345139004549522339295154791205888023180969037471373425748676, + 2069264725168743411785330201111662550546590368977254922367543245881704417747, + 2864977467356832391348646806785103978401083442575260061290007107264804853079, + 1325712426074588175917681992103732871167152828323026211822367996559374693557, + 2745372160223581791751573454111775902550163309272572637725014391432686289207, + 1320182822597119196092123925679279513597289598101660045113845839455396381186, + 1828837204612824183172629382430137641454111146716139406496680083213113449672, + 292771243849180566793969674638485939456931783058705700530152077256182516555, + 1853053340162949476690287745899899731365283998192199761639837549720376161302, + 1574074654377970680494400284298138511458092739287721401853756095832679820400, + 2335171727126212848311914093154862343081383022742695905218809639842417219817, + 2863649483928914851504502227815214384723946227670079391139882735736574369209, + 571166807018491507338190454242538460726521500111329536305196032242467546663, + 279676987357461165576086433526354394307231660381247697037076852152283263764, + 1820353294888025422326570312212231640999665549085940467004134021672860083252, + 3576296452710656809610107747368507751192095749903159933998981729702492446131, + 2977633414996464546697934803671958245149887856183204553980665750247071075567, + 2931793682328107871478505893552517312756205124678921541595857767372940804931, + 464386720247382905224805039346212896127582735570572085216056963406710498311, + 320998635952014724145801465653830965824810643722569630652595245633304892795, + 1243869209783079566950644774574351067214583308693372604207122773753028835268, + 795578854620635938716799656591963466893104246779506304831287216577244839240, + 1440443221627670879258141142737734281315365036204707421342557494403242698702, + 3165759076703708074008026693496870920949483211566514118299181265520560275163, + 847013164052415708297030782851092001846349937526001161676656062025695141455, + 2724562613651009432547305409080600001190207517487511534234627332461422211487, + 2777023644004316843919492669885675696223519793380600665738536014905002789857, + 2553559058682947159814270185638032697395233101874392167746095003347085031030 + ]; + let params = FriLayerComputationParams { + coset_size: 16, + fri_group: get_fri_group().span(), + eval_point: 3595973390675465639794922899086636220512672666972909183802502305051197462034 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 0, + y_value: 1088705866760295650273261822438240192516309122056858821372288964395003420702, + x_inv_value: 616315024773588042326990745933816118347080550260649970905916351058572263364 + }, + FriLayerQuery { + index: 1, + y_value: 2860448070944891293646997797340290664354871085123970576706463496050069457334, + x_inv_value: 3002187763892543171370332037161253987276026665070946729067175705077299757117 + } + ]; + let expected_verify_indices = array![0, 1]; + let expected_verify_y_values = array![ + 1207893144587700365996195575736463898273419338985626305569288268445097779644, + 2244256048781475345139004549522339295154791205888023180969037471373425748676, + 2069264725168743411785330201111662550546590368977254922367543245881704417747, + 2864977467356832391348646806785103978401083442575260061290007107264804853079, + 1325712426074588175917681992103732871167152828323026211822367996559374693557, + 2526228053058749206268429435387221189473358598063225073128406154185646521246, + 2745372160223581791751573454111775902550163309272572637725014391432686289207, + 1320182822597119196092123925679279513597289598101660045113845839455396381186, + 1828837204612824183172629382430137641454111146716139406496680083213113449672, + 292771243849180566793969674638485939456931783058705700530152077256182516555, + 56624383172680154199608666479407795256819238702017594377613749554501152230, + 1853053340162949476690287745899899731365283998192199761639837549720376161302, + 1574074654377970680494400284298138511458092739287721401853756095832679820400, + 2335171727126212848311914093154862343081383022742695905218809639842417219817, + 2863649483928914851504502227815214384723946227670079391139882735736574369209, + 571166807018491507338190454242538460726521500111329536305196032242467546663, + 279676987357461165576086433526354394307231660381247697037076852152283263764, + 1820353294888025422326570312212231640999665549085940467004134021672860083252, + 3576296452710656809610107747368507751192095749903159933998981729702492446131, + 2977633414996464546697934803671958245149887856183204553980665750247071075567, + 2931793682328107871478505893552517312756205124678921541595857767372940804931, + 464386720247382905224805039346212896127582735570572085216056963406710498311, + 320998635952014724145801465653830965824810643722569630652595245633304892795, + 1243869209783079566950644774574351067214583308693372604207122773753028835268, + 1280082646894980092283175931172370782094547118060861067319301021219059720426, + 795578854620635938716799656591963466893104246779506304831287216577244839240, + 1440443221627670879258141142737734281315365036204707421342557494403242698702, + 3165759076703708074008026693496870920949483211566514118299181265520560275163, + 847013164052415708297030782851092001846349937526001161676656062025695141455, + 2724562613651009432547305409080600001190207517487511534234627332461422211487, + 2777023644004316843919492669885675696223519793380600665738536014905002789857, + 2553559058682947159814270185638032697395233101874392167746095003347085031030 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer13() { + let queries = array![ + FriLayerQuery { + index: 4, + y_value: 1627753637108195107008717260643443556440896293952766167989244332362025128955, + x_inv_value: 165072171847702776025005442077416581427717054356960489404605508780869429109 + }, + FriLayerQuery { + index: 6, + y_value: 1907069019505532596977567890050857167624794813827113677169100094032312679860, + x_inv_value: 2838405280269567641797768141989974821924250514269469085547129106678089679276 + }, + FriLayerQuery { + index: 17, + y_value: 2667758142751156730750479133927958256743897982548140807600266277386132227210, + x_inv_value: 3170021172787255616470538597751371781796787498724713449478272545829880462903 + }, + FriLayerQuery { + index: 19, + y_value: 3054802752625116251242176575121855863384552134692463894146326808649779880106, + x_inv_value: 538689680560493478426594143215819266234245765733410283169873364502317472115 + } + ]; + let sibling_witness = array![ + 2050030406567804179442000347699156712126697950069244167305023529960957405037, + 725479814115011831742735395574739712735192127192219676877319469925485638090, + 2004541427256438610478116272570683095787443576788754802866420921854549452311, + 724963531516986282530869066191617872380337840104897443636827319336363047197 + ]; + let params = FriLayerComputationParams { + coset_size: 2, + fri_group: get_fri_group().span(), + eval_point: 2421848930253683544491204126387682224910511646695020603828594542121930160761 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 2, + y_value: 660153636442127173118975536965070819250293153948896357172872743794635105879, + x_inv_value: 2960686226227640912988100104315064357312831954878333460443552280409792680793 + }, + FriLayerQuery { + index: 3, + y_value: 2583053251813978881353554001887300235615403361797918894623762263894051653781, + x_inv_value: 657816562438490300709222678780005748310275260453263239529539775726079339688 + }, + FriLayerQuery { + index: 8, + y_value: 1527581375610259013472640819070111909856582743637749080241681873891116651023, + x_inv_value: 826108911032960435877720672246591828237630390247901639819313714416153942305 + }, + FriLayerQuery { + index: 9, + y_value: 1314190719421472944202120326036610156945162999618119049307656001213352574130, + x_inv_value: 2792393877633170777819602110848478277385476825083695060153778341719718078176 + } + ]; + let expected_verify_indices = array![2, 3, 8, 9]; + let expected_verify_y_values = array![ + 1627753637108195107008717260643443556440896293952766167989244332362025128955, + 2050030406567804179442000347699156712126697950069244167305023529960957405037, + 1907069019505532596977567890050857167624794813827113677169100094032312679860, + 725479814115011831742735395574739712735192127192219676877319469925485638090, + 2004541427256438610478116272570683095787443576788754802866420921854549452311, + 2667758142751156730750479133927958256743897982548140807600266277386132227210, + 724963531516986282530869066191617872380337840104897443636827319336363047197, + 3054802752625116251242176575121855863384552134692463894146326808649779880106 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer14() { + let queries = array![ + FriLayerQuery { + index: 2, + y_value: 182467674097091120329927235354242737842583201410388016740324890375633361201, + x_inv_value: 3491761957940661772609725505931396483010302121714589766865821416607388552712 + }, + FriLayerQuery { + index: 25, + y_value: 2616059464280392748910374974435988073072322805525536233200957037367537266460, + x_inv_value: 684891698656108367482980392386620006607736687746727332990606560885224142016 + }, + FriLayerQuery { + index: 27, + y_value: 3135591753368679100635971158548683977259260369951862071333071709354788461451, + x_inv_value: 2829608587555461287847580972434362343728163236965816816408509779854673967295 + }, + FriLayerQuery { + index: 31, + y_value: 1881803943157720418027631826401286341924988674799418842326383947191741229239, + x_inv_value: 2061424207875745497330105211998005177924219095698929972788852026216611005243 + } + ]; + let sibling_witness = array![ + 2950872026957754570520920887716695721163885794330469237821164944724213529559, + 3423399715507542415471039424968021876507440780439723595312075313832351840846, + 2639813652387298633797735255709274903535060839700134996978742006377284413899, + 1866933437322184733125022551051704017619697979136971899039533691287199399223, + 1087261690083259210579547894957300747894789483945777051521564331303669475417, + 436336765556821905445300240111094908104143701663353530995130936976271217967, + 2644311112046094225531959222370965947710384802579881971227807342025597482888, + 1909838974457498375031773317733557605709575892255791166978664386630300826462 + ]; + let params = FriLayerComputationParams { + coset_size: 4, + fri_group: get_fri_group().span(), + eval_point: 2890900194451389976335809017939659452822058660721403378521723434210041554982 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 0, + y_value: 513745185270294796896505867131039914974805394897382564034555988323441608939, + x_inv_value: 1753073989277535228300597420267756302718024776814145631761631058811620119022 + }, + FriLayerQuery { + index: 6, + y_value: 283244066499690934004140803318372542853976737301814474763000225147488436044, + x_inv_value: 1256084241920925162306077224918612704241015140814843222329579692894372909657 + }, + FriLayerQuery { + index: 7, + y_value: 1478347218723203537312908341948591806836150726532123973049689074479535567310, + x_inv_value: 2362418546745206051391245558176457401382092074516753477643512363241499110824 + } + ]; + let expected_verify_indices = array![0, 6, 7]; + let expected_verify_y_values = array![ + 2950872026957754570520920887716695721163885794330469237821164944724213529559, + 3423399715507542415471039424968021876507440780439723595312075313832351840846, + 182467674097091120329927235354242737842583201410388016740324890375633361201, + 2639813652387298633797735255709274903535060839700134996978742006377284413899, + 1866933437322184733125022551051704017619697979136971899039533691287199399223, + 2616059464280392748910374974435988073072322805525536233200957037367537266460, + 1087261690083259210579547894957300747894789483945777051521564331303669475417, + 3135591753368679100635971158548683977259260369951862071333071709354788461451, + 436336765556821905445300240111094908104143701663353530995130936976271217967, + 2644311112046094225531959222370965947710384802579881971227807342025597482888, + 1909838974457498375031773317733557605709575892255791166978664386630300826462, + 1881803943157720418027631826401286341924988674799418842326383947191741229239 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer15() { + let queries = array![ + FriLayerQuery { + index: 3, + y_value: 2126554718777799703033176385657191458683095484702936419714937401273860792353, + x_inv_value: 1498130324693628615611301376349242190235092933171848743274310007433732048452 + }, + FriLayerQuery { + index: 5, + y_value: 2623153453096109592554970794864647942540496513967038379132519508620543736052, + x_inv_value: 2473811350240372293912485302342835893407435625813517542082770273218894953613 + }, + FriLayerQuery { + index: 12, + y_value: 476298806093907467850716043392398955442830603875308728637021317685049559197, + x_inv_value: 1481295585313502890247351662356421852619129386517592950611879579091145907681 + }, + FriLayerQuery { + index: 18, + y_value: 827426677652387725852612551358849344643252701184675574276305695934461070547, + x_inv_value: 3157568619914630228245585045460462037899356804058727670743639396696895096810 + } + ]; + let sibling_witness = array![ + 568564974606148495952068697014394313795111623433425386734413188543473055716, + 1366545704922978306211848519149545128599600491849509699095648209057270124351, + 3369664267451368476598912507893714750893169206881535467940070393280111122875, + 2280690314598724729426820296417461067959633041888159626217181865005729013915, + 1750406421129806494718048253683602965979894789354393453635402726451304469664, + 2762059256797157000850865553676819078171564555367687766234376453546016309128, + 1218810442314639785763927242813711233967407489681286827599146696588183167351, + 3326413784838410331909308251183472448929379765135431872331756106367645912341, + 1497242645745261449252794444194366044893668463373511650329130666278071978545, + 3579089221531285967409202767297183219472499898936595220293050125486208286184, + 3248438492701918352940278480328128482078022776384561858577313420268927328253, + 1829392959076920522810136108754859101764285908550319866368605180895886400941, + 1381649411086887915153209392042891444342882236335347987981943536021221116597, + 1150216390794862013836421555089501298848998425400784049969031535552014025785, + 1610452974374564984104668996356443832855149971648247845305553807032081001945, + 2666891792376495085372824878310585447372725714703557465061678456052996142622, + 89033365488533857651117114777253473905400110863108967855831738586614375331, + 839735918399761087418547466208562598085415116825419145221721101951385977007, + 3138433960204460263441142084968507058529045412551667347395974042720099964096, + 3100876726267232844173520141766067628776170322055721109835889787928561738493 + ]; + let params = FriLayerComputationParams { + coset_size: 8, + fri_group: get_fri_group().span(), + eval_point: 2667333039062326164983120557556866577383303469424551586689009383516583846698 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 0, + y_value: 1298128010820835131249075641691464534391873438592600861436220192788480487820, + x_inv_value: 563971957663528375029493660386013764689221643789293540378813704450327788085 + }, + FriLayerQuery { + index: 1, + y_value: 2490084159237398684739244273076602421488849852729557450096588072753038507064, + x_inv_value: 3054530831002602838667829122709056340933885571542303159594278351685544232396 + }, + FriLayerQuery { + index: 2, + y_value: 2291510120351370467822435604782665914711862794940021614151971912092308989788, + x_inv_value: 2933968264282979779366267770342785547048665384117568818848464375193300665318 + } + ]; + let expected_verify_indices = array![0, 1, 2]; + let expected_verify_y_values = array![ + 568564974606148495952068697014394313795111623433425386734413188543473055716, + 1366545704922978306211848519149545128599600491849509699095648209057270124351, + 3369664267451368476598912507893714750893169206881535467940070393280111122875, + 2126554718777799703033176385657191458683095484702936419714937401273860792353, + 2280690314598724729426820296417461067959633041888159626217181865005729013915, + 2623153453096109592554970794864647942540496513967038379132519508620543736052, + 1750406421129806494718048253683602965979894789354393453635402726451304469664, + 2762059256797157000850865553676819078171564555367687766234376453546016309128, + 1218810442314639785763927242813711233967407489681286827599146696588183167351, + 3326413784838410331909308251183472448929379765135431872331756106367645912341, + 1497242645745261449252794444194366044893668463373511650329130666278071978545, + 3579089221531285967409202767297183219472499898936595220293050125486208286184, + 476298806093907467850716043392398955442830603875308728637021317685049559197, + 3248438492701918352940278480328128482078022776384561858577313420268927328253, + 1829392959076920522810136108754859101764285908550319866368605180895886400941, + 1381649411086887915153209392042891444342882236335347987981943536021221116597, + 1150216390794862013836421555089501298848998425400784049969031535552014025785, + 1610452974374564984104668996356443832855149971648247845305553807032081001945, + 827426677652387725852612551358849344643252701184675574276305695934461070547, + 2666891792376495085372824878310585447372725714703557465061678456052996142622, + 89033365488533857651117114777253473905400110863108967855831738586614375331, + 839735918399761087418547466208562598085415116825419145221721101951385977007, + 3138433960204460263441142084968507058529045412551667347395974042720099964096, + 3100876726267232844173520141766067628776170322055721109835889787928561738493 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} + +#[test] +#[available_gas(9999999999)] +fn test_next_layer16() { + let queries = array![ + FriLayerQuery { + index: 7, + y_value: 2970618271957846642342346764466826063381003093310142263411672089332794267936, + x_inv_value: 696367657482296552349796637489145592059647766092429860960056113503758236140 + }, + FriLayerQuery { + index: 15, + y_value: 3617920250969127201709777488707208906453088850534187183520682603094272928673, + x_inv_value: 2310133886796103194691263229141735996023430718973315327189200842370523874475 + }, + FriLayerQuery { + index: 20, + y_value: 2813510573038804010549182461227254081026726929362216457735799917295807557921, + x_inv_value: 3136912033480025440798126631316085964287892167044727093790915521436523583198 + }, + FriLayerQuery { + index: 27, + y_value: 2277310758645048528057712942822918302585095765258964079440830614234208634453, + x_inv_value: 1870747205314942372902696401365132965517762966704042444182117300433681492666 + } + ]; + let sibling_witness = array![ + 180909023427284908087068954735501773245381309706885307634112035720217679110, + 3516180717011553731559375883606897325832921300415665629181132188828019272220, + 595855061896376529488642887156753604023810348347280472583907714516066828172, + 3191235363083292632152220281591154669252475323788852857089686800728410534498, + 1813822547938332577999867038562586426023262706228694365068812860876915662240, + 1680128694077508680748055866477369978665203502934465079629899601611040128864, + 2254538912986936078053356255795224792937407530312557714459538221668304707673, + 1146541571666156127290331652094519929859911664578484739484350628703870274239, + 2676242402429982706240946875896463048455086361143114665112503727666130770278, + 1535606142568082504153083317992489160493054337756138059888305406164806817367, + 2327833743689290796289689852734820784384652608694315731354512839605195535594, + 704019990774920412035974507851267537536910401523746675504830418223883704486, + 819141808945878073660426874084155050645640426465236632642039400376831935514, + 916452161521954486046652431769043932403407207121236049985828805160129320470, + 2783827343576601773044240366051443811775748296762833339085024659475074755650, + 711792960833666366752081806111336906962181709004718383889531208840309577986, + 380931428319285290225787627529471042566157302138735167253381618771362729861, + 2856797988975711654276161369071199892749361894922820391361113510391706048304, + 3482933488692241523840784131023860208574894633803191769610254610727766442033, + 1264899078355765869100614221263650222437429703885704857993771751181043986946, + 1400484696922187703290919818865394595993978084275297840720974996479598720354, + 107842594321822547920522338615937431539676850957901523579287900994294462578, + 1660688899193255147418136637041572395267277578278543414089972502504493135495, + 2203031443746817593668322965414946570177702172611895846085976472340779485221, + 2587809142332512931520259907768113553396624721896300372775193299798500202556, + 3589911342720590439499798061492779810823748230816082995862628665524054571607, + 2213453230887497720575673069515446618971622145035522840843819369864164611166, + 2117829586952619081545500943334082335605420332616462445739700555609069867362 + ]; + let params = FriLayerComputationParams { + coset_size: 16, + fri_group: get_fri_group().span(), + eval_point: 2131161197067646908062806238455827830521701314225315670510309581734422726318 + }; + let expected_next_queries = array![ + FriLayerQuery { + index: 0, + y_value: 1673087752917740433456711006621617791163224131325431924340953404769449739057, + x_inv_value: 3563079260215329529465469507049655514938826357303290347407524859824127636176 + }, + FriLayerQuery { + index: 1, + y_value: 411308955591734803942114330163581819505644029281528997154872777951395903682, + x_inv_value: 55423528450801684231853276045414590684280858028306352565567196311744384305 + } + ]; + let expected_verify_indices = array![0, 1]; + let expected_verify_y_values = array![ + 180909023427284908087068954735501773245381309706885307634112035720217679110, + 3516180717011553731559375883606897325832921300415665629181132188828019272220, + 595855061896376529488642887156753604023810348347280472583907714516066828172, + 3191235363083292632152220281591154669252475323788852857089686800728410534498, + 1813822547938332577999867038562586426023262706228694365068812860876915662240, + 1680128694077508680748055866477369978665203502934465079629899601611040128864, + 2254538912986936078053356255795224792937407530312557714459538221668304707673, + 2970618271957846642342346764466826063381003093310142263411672089332794267936, + 1146541571666156127290331652094519929859911664578484739484350628703870274239, + 2676242402429982706240946875896463048455086361143114665112503727666130770278, + 1535606142568082504153083317992489160493054337756138059888305406164806817367, + 2327833743689290796289689852734820784384652608694315731354512839605195535594, + 704019990774920412035974507851267537536910401523746675504830418223883704486, + 819141808945878073660426874084155050645640426465236632642039400376831935514, + 916452161521954486046652431769043932403407207121236049985828805160129320470, + 3617920250969127201709777488707208906453088850534187183520682603094272928673, + 2783827343576601773044240366051443811775748296762833339085024659475074755650, + 711792960833666366752081806111336906962181709004718383889531208840309577986, + 380931428319285290225787627529471042566157302138735167253381618771362729861, + 2856797988975711654276161369071199892749361894922820391361113510391706048304, + 2813510573038804010549182461227254081026726929362216457735799917295807557921, + 3482933488692241523840784131023860208574894633803191769610254610727766442033, + 1264899078355765869100614221263650222437429703885704857993771751181043986946, + 1400484696922187703290919818865394595993978084275297840720974996479598720354, + 107842594321822547920522338615937431539676850957901523579287900994294462578, + 1660688899193255147418136637041572395267277578278543414089972502504493135495, + 2203031443746817593668322965414946570177702172611895846085976472340779485221, + 2277310758645048528057712942822918302585095765258964079440830614234208634453, + 2587809142332512931520259907768113553396624721896300372775193299798500202556, + 3589911342720590439499798061492779810823748230816082995862628665524054571607, + 2213453230887497720575673069515446618971622145035522840843819369864164611166, + 2117829586952619081545500943334082335605420332616462445739700555609069867362 + ]; + + let (next_queries, verify_indices, verify_y_values) = compute_next_layer( + queries.span(), sibling_witness.span(), params + ); + + assert(verify_indices == expected_verify_indices, 'Invalid value'); + assert(verify_y_values == expected_verify_y_values, 'Invalid value'); + assert(next_queries == expected_next_queries, 'Invalid value'); +} From 77bb7922772c4fc53441b80fb6728eee45c00dfb Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Tue, 26 Dec 2023 08:01:51 +0100 Subject: [PATCH 34/38] array_extend & refactor --- src/common.cairo | 1 + src/common/array_extend.cairo | 16 ++++++++++++++++ src/fri/fri_layer.cairo | 35 +++++++++++++++-------------------- 3 files changed, 32 insertions(+), 20 deletions(-) create mode 100644 src/common/array_extend.cairo diff --git a/src/common.cairo b/src/common.cairo index 2d9a87ae9..0e28c54fc 100644 --- a/src/common.cairo +++ b/src/common.cairo @@ -5,6 +5,7 @@ mod horner_eval; mod array_append; mod math; mod array_print; +mod array_extend; #[cfg(test)] mod tests; diff --git a/src/common/array_extend.cairo b/src/common/array_extend.cairo new file mode 100644 index 000000000..d8cc703c6 --- /dev/null +++ b/src/common/array_extend.cairo @@ -0,0 +1,16 @@ +trait ArrayExtendTrait { + fn extend(ref self: Array, span: Span); +} + +impl ArrayExtend, +Drop> of ArrayExtendTrait { + fn extend(ref self: Array, span: Span) { + let mut i = 0; + loop { + if i == span.len() { + break; + }; + self.append(*span.at(i)); + i += 1; + }; + } +} diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index 740a469c6..f8794b251 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -1,3 +1,5 @@ +use cairo_verifier::common::array_extend::ArrayExtendTrait; +use core::box::BoxTrait; use core::debug::PrintTrait; use core::option::OptionTrait; use core::traits::TryInto; @@ -46,26 +48,26 @@ fn compute_coset_elements( ) -> (Array, felt252) { let mut coset_elements = ArrayTrait::::new(); let mut coset_x_inv: felt252 = 0; - - let i_len = queries.len(); let mut i: u32 = 0; - let mut j: u32 = 0; - loop { if offset_within_coset == coset_size { break; } - if i != i_len && (*queries.at(0)).index == coset_start_index + offset_within_coset { - let query = *queries.pop_front().unwrap(); - coset_elements.append(query.y_value); - coset_x_inv = (query.x_inv_value) * (*fri_group.at(i + j)); - i += 1; - } else { - coset_elements.append(*sibling_witness.pop_front().unwrap()); - j += 1; + match queries.get(0) { + Option::Some(q) => { + if *q.unbox().index == coset_start_index + offset_within_coset { + let query = *queries.pop_front().unwrap(); + coset_elements.append(query.y_value); + coset_x_inv = (query.x_inv_value) * (*fri_group.at(i)); + } else { + coset_elements.append(*sibling_witness.pop_front().unwrap()); + } + }, + Option::None => { coset_elements.append(*sibling_witness.pop_front().unwrap()); }, } + i += 1; offset_within_coset += 1; }; @@ -122,14 +124,7 @@ fn compute_next_layer( 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))); - j += 1; - }; + verify_y_values.extend(coset_elements_span); let fri_formula_res = fri_formula( coset_elements_span, params.eval_point, coset_x_inv, coset_size, From 02b604d86b029080cc729a0ce15a5f65f5a096e1 Mon Sep 17 00:00:00 2001 From: Filip Krawczyk Date: Wed, 27 Dec 2023 11:56:48 +0100 Subject: [PATCH 35/38] Refactor compute_coset_elements --- src/fri/fri_layer.cairo | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index f8794b251..2136b27de 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -54,17 +54,13 @@ fn compute_coset_elements( break; } - match queries.get(0) { - Option::Some(q) => { - if *q.unbox().index == coset_start_index + offset_within_coset { - let query = *queries.pop_front().unwrap(); - coset_elements.append(query.y_value); - coset_x_inv = (query.x_inv_value) * (*fri_group.at(i)); - } else { - coset_elements.append(*sibling_witness.pop_front().unwrap()); - } - }, - Option::None => { coset_elements.append(*sibling_witness.pop_front().unwrap()); }, + let q = queries.get(0); + if q.is_some() && *q.unwrap().unbox().index == coset_start_index + offset_within_coset { + let query = *queries.pop_front().unwrap(); + coset_elements.append(query.y_value); + coset_x_inv = (query.x_inv_value) * (*fri_group.at(i)); + } else { + coset_elements.append(*sibling_witness.pop_front().unwrap()); } i += 1; From 1f64cdf8b2856feb24c015155699bcb98b4d5007 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Wed, 27 Dec 2023 19:04:25 +0100 Subject: [PATCH 36/38] review fixes --- calc.py | 3 --- src/common.cairo | 1 + src/common/array_extend.cairo | 5 +---- src/common/consts.cairo | 2 ++ src/common/math.cairo | 4 +++- src/fri/fri_config.cairo | 5 ++--- src/fri/fri_layer.cairo | 3 +-- 7 files changed, 10 insertions(+), 13 deletions(-) delete mode 100644 calc.py create mode 100644 src/common/consts.cairo diff --git a/calc.py b/calc.py deleted file mode 100644 index 242e6604b..000000000 --- a/calc.py +++ /dev/null @@ -1,3 +0,0 @@ -DEFAULT_PRIME = 2**251 + 17 * 2**192 + 1 - -print((pow(3, DEFAULT_PRIME-2, DEFAULT_PRIME))) \ No newline at end of file diff --git a/src/common.cairo b/src/common.cairo index 0e28c54fc..cf165c02e 100644 --- a/src/common.cairo +++ b/src/common.cairo @@ -6,6 +6,7 @@ mod array_append; mod math; mod array_print; mod array_extend; +mod consts; #[cfg(test)] mod tests; diff --git a/src/common/array_extend.cairo b/src/common/array_extend.cairo index d8cc703c6..08fbe6607 100644 --- a/src/common/array_extend.cairo +++ b/src/common/array_extend.cairo @@ -1,7 +1,4 @@ -trait ArrayExtendTrait { - fn extend(ref self: Array, span: Span); -} - +#[generate_trait] impl ArrayExtend, +Drop> of ArrayExtendTrait { fn extend(ref self: Array, span: Span) { let mut i = 0; diff --git a/src/common/consts.cairo b/src/common/consts.cairo new file mode 100644 index 000000000..195fba4cd --- /dev/null +++ b/src/common/consts.cairo @@ -0,0 +1,2 @@ +const STARK_PRIME_MINUS_TWO: felt252 = + 3618502788666131213697322783095070105623107215331596699973092056135872020479; diff --git a/src/common/math.cairo b/src/common/math.cairo index a7725c167..978aacc95 100644 --- a/src/common/math.cairo +++ b/src/common/math.cairo @@ -1,3 +1,5 @@ +use cairo_verifier::common::consts::STARK_PRIME_MINUS_TWO; + fn pow(base: felt252, exp: felt252) -> felt252 { if exp == 0 { return 1; @@ -23,5 +25,5 @@ fn pow(base: felt252, exp: felt252) -> felt252 { fn mul_inverse(x: felt252) -> felt252 { // From Fermat's little theorem, a ^ (p - 1) = 1 when p is prime and a != 0. Since a ^ (p - 1) = a · a ^ (p - 2) we have that // a ^ (p - 2) is the multiplicative inverse of a modulo p. - pow(x, 3618502788666131213697322783095070105623107215331596699973092056135872020479) + pow(x, STARK_PRIME_MINUS_TWO) } diff --git a/src/fri/fri_config.cairo b/src/fri/fri_config.cairo index 63fb9d379..02ff63a0c 100644 --- a/src/fri/fri_config.cairo +++ b/src/fri/fri_config.cairo @@ -27,10 +27,9 @@ struct FriConfig { fn fri_config_validate( config: FriConfig, log_n_cosets: felt252, n_verifier_friendly_commitment_layers: felt252 ) -> felt252 { - let n_layers = config.n_layers.try_into().unwrap(); - let log_last_layer_degree_bound = config.log_last_layer_degree_bound.try_into().unwrap(); + 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 >= 0, 'Must be non negative value'); assert(log_last_layer_degree_bound <= MAX_LAST_LAYER_LOG_DEGREE_BOUND, 'Value too big'); assert(*config.fri_step_sizes.at(0) == 0, 'Invalid value'); diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index 2136b27de..74842a20e 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -101,7 +101,6 @@ fn compute_next_layer( let coset_size_u256: u256 = coset_size.into(); let coset_index = (index_u256 / coset_size_u256).low.into(); - assert(coset_index.into() >= 0_u256, 'Must be non negative value'); verify_indices.append(coset_index); @@ -116,7 +115,7 @@ fn compute_next_layer( // Verify that at least one query was consumed. let coset_elements_len = coset_elements.len(); - assert(coset_elements_len >= 0, 'Must be non negative value'); + assert(coset_elements_len > 0, 'Must be non negative value'); let coset_elements_span = coset_elements.span(); From e40ff63fdabe8b21ea3f89f13dfae34729866ac9 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Wed, 27 Dec 2023 19:22:38 +0100 Subject: [PATCH 37/38] consts and imports refactor --- src/channel/channel.cairo | 17 ++++---------- src/common/consts.cairo | 15 ++++++++++++ src/fri/fri.cairo | 34 ++++++++++++---------------- src/fri/fri_config.cairo | 10 ++++---- src/fri/fri_first_layer.cairo | 13 ++++------- src/fri/fri_formula.cairo | 2 -- src/fri/fri_last_layer.cairo | 7 +----- src/fri/fri_layer.cairo | 15 ++++-------- src/fri/tests/test_fri_formula.cairo | 1 - src/fri/tests/test_last_layer.cairo | 4 +--- src/fri/tests/test_next_layer.cairo | 8 +++---- src/lib.cairo | 4 ---- src/structs/stark_config.cairo | 8 +++---- 13 files changed, 57 insertions(+), 81 deletions(-) diff --git a/src/channel/channel.cairo b/src/channel/channel.cairo index 88d5c2b72..1fefccfec 100644 --- a/src/channel/channel.cairo +++ b/src/channel/channel.cairo @@ -1,20 +1,13 @@ -use core::array::ArrayTrait; use cairo_verifier::common::{ - flip_endianness::FlipEndiannessTrait, array_append::ArrayAppendTrait, blake2s::blake2s + flip_endianness::FlipEndiannessTrait, array_append::ArrayAppendTrait, blake2s::blake2s, + consts::{ + C_PRIME_AS_UINT256_LOW, C_PRIME_AS_UINT256_HIGH, STARK_PRIME, MONTGOMERY_R, + MONTGOMERY_R_INVERSE + } }; use poseidon::poseidon_hash_span; use core::integer::BoundedU128; -const C_PRIME_AS_UINT256_LOW: u128 = 31; -const C_PRIME_AS_UINT256_HIGH: u128 = - 329648542954659146201578277794459156480; // 31 * 0x8000000000000110000000000000000; -const STARK_PRIME: u256 = - 3618502788666131213697322783095070105623107215331596699973092056135872020481; -const MONTGOMERY_R: felt252 = - 3618502788666127798953978732740734578953660990361066340291730267701097005025; // 2**256 % STARK_PRIME -const MONTGOMERY_R_INVERSE: felt252 = - 113078212145816603762751633895895194930089271709401121343797004406777446400; - #[derive(Drop)] struct Channel { digest: u256, diff --git a/src/common/consts.cairo b/src/common/consts.cairo index 195fba4cd..56ffa41ea 100644 --- a/src/common/consts.cairo +++ b/src/common/consts.cairo @@ -1,2 +1,17 @@ +const STARK_PRIME: u256 = + 3618502788666131213697322783095070105623107215331596699973092056135872020481; const STARK_PRIME_MINUS_TWO: felt252 = 3618502788666131213697322783095070105623107215331596699973092056135872020479; + +const FIELD_GENERATOR: felt252 = 3; +const FIELD_GENERATOR_INVERSE: felt252 = + 1206167596222043737899107594365023368541035738443865566657697352045290673494; + +const MONTGOMERY_R: felt252 = + 3618502788666127798953978732740734578953660990361066340291730267701097005025; // 2**256 % STARK_PRIME +const MONTGOMERY_R_INVERSE: felt252 = + 113078212145816603762751633895895194930089271709401121343797004406777446400; + +const C_PRIME_AS_UINT256_LOW: u128 = 31; +const C_PRIME_AS_UINT256_HIGH: u128 = + 329648542954659146201578277794459156480; // 31 * 0x8000000000000110000000000000000; diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo index cef7868fb..d78683403 100644 --- a/src/fri/fri.cairo +++ b/src/fri/fri.cairo @@ -1,19 +1,15 @@ -use core::traits::Into; -use core::option::OptionTrait; -use core::traits::TryInto; -use core::array::SpanTrait; -use core::array::ArrayTrait; -use core::traits::Destruct; -use cairo_verifier::common::math; -use cairo_verifier::channel::channel::{Channel, ChannelTrait}; -use cairo_verifier::fri::fri_config::FriConfig; -use cairo_verifier::fri::fri_first_layer::gather_first_layer_queries; -use cairo_verifier::fri::fri_group::get_fri_group; -use cairo_verifier::fri::fri_layer::{FriLayerQuery, FriLayerComputationParams, compute_next_layer}; -use cairo_verifier::fri::fri_last_layer::verify_last_layer; -use cairo_verifier::table_commitment::{ - TableCommitmentWitness, TableDecommitment, TableCommitment, TableCommitmentConfig, - TableUnsentCommitment, table_commit, table_decommit +use cairo_verifier::{ + common::math::pow, channel::channel::{Channel, ChannelTrait}, + fri::{ + fri_config::FriConfig, fri_first_layer::gather_first_layer_queries, + fri_group::get_fri_group, + fri_layer::{FriLayerQuery, FriLayerComputationParams, compute_next_layer}, + fri_last_layer::verify_last_layer, + }, + table_commitment::{ + TableCommitmentWitness, TableDecommitment, TableCommitment, TableCommitmentConfig, + TableUnsentCommitment, table_commit, table_decommit + } }; // Commitment values for FRI. Used to generate a commitment by "reading" these values @@ -130,7 +126,7 @@ fn fri_commit( channel.read_felt_vector_from_prover(unsent_commitment.last_layer_coefficients); let coefficients = unsent_commitment.last_layer_coefficients; - let n_coefficients = math::pow(2, config.log_last_layer_degree_bound); + let n_coefficients = pow(2, config.log_last_layer_degree_bound); assert(n_coefficients == coefficients.len().into(), 'Invalid value'); FriCommitment { @@ -159,7 +155,7 @@ fn fri_verify_layers( } // Params. - let coset_size = math::pow(2, *step_sizes.at(i)); + let coset_size = pow(2, *step_sizes.at(i)); let params = FriLayerComputationParams { coset_size, fri_group, eval_point: *eval_points.at(i) }; @@ -217,7 +213,7 @@ fn fri_verify( commitment .last_layer_coefficients .len() - .into() == math::pow(2, commitment.config.log_last_layer_degree_bound), + .into() == pow(2, commitment.config.log_last_layer_degree_bound), 'Invlid value' ); verify_last_layer(last_queries.span(), commitment.last_layer_coefficients); diff --git a/src/fri/fri_config.cairo b/src/fri/fri_config.cairo index 02ff63a0c..be7e6f34a 100644 --- a/src/fri/fri_config.cairo +++ b/src/fri/fri_config.cairo @@ -1,9 +1,7 @@ -use core::array::ArrayTrait; -use core::option::OptionTrait; -use core::array::SpanTrait; -use core::traits::Into; -use cairo_verifier::table_commitment::TableCommitmentConfig; -use cairo_verifier::vector_commitment::{validate_vector_commitment, VectorCommitmentConfig}; +use cairo_verifier::{ + table_commitment::TableCommitmentConfig, + vector_commitment::{validate_vector_commitment, VectorCommitmentConfig}, +}; const MAX_LAST_LAYER_LOG_DEGREE_BOUND: u32 = 15; const MAX_FRI_LAYERS: u32 = 15; diff --git a/src/fri/fri_first_layer.cairo b/src/fri/fri_first_layer.cairo index e00de97d8..e75733212 100644 --- a/src/fri/fri_first_layer.cairo +++ b/src/fri/fri_first_layer.cairo @@ -1,11 +1,6 @@ -use core::array::SpanTrait; -use core::option::OptionTrait; -use core::array::ArrayTrait; -use core::traits::TryInto; - -use cairo_verifier::common::math; -use cairo_verifier::fri::fri_layer::FriLayerQuery; -use cairo_verifier::FIELD_GENERATOR_INVERSE; +use cairo_verifier::{ + common::{math::mul_inverse, consts::FIELD_GENERATOR_INVERSE}, fri::fri_layer::FriLayerQuery, +}; fn gather_first_layer_queries( queries: Span, evaluations: Span, x_values: Span @@ -27,7 +22,7 @@ fn gather_first_layer_queries( FriLayerQuery { index: *(queries.at(i)), y_value: *(evaluations.at(i)), - x_inv_value: math::mul_inverse(shifted_x_value), + x_inv_value: mul_inverse(shifted_x_value), } ); diff --git a/src/fri/fri_formula.cairo b/src/fri/fri_formula.cairo index 9702c438f..8ecbea891 100644 --- a/src/fri/fri_formula.cairo +++ b/src/fri/fri_formula.cairo @@ -1,5 +1,3 @@ -use core::array::SpanTrait; - // Constants representing primitive roots of unity for orders 2, 4, 8, and 16. // These are calculated based on the formula 1 / 3^((PRIME - 1) / 16) where 3 is a generator. const OMEGA_16: felt252 = 0x5c3ed0c6f6ac6dd647c9ba3e4721c1eb14011ea3d174c52d7981c5b8145aa75; diff --git a/src/fri/fri_last_layer.cairo b/src/fri/fri_last_layer.cairo index 9444ed628..fce00a9a7 100644 --- a/src/fri/fri_last_layer.cairo +++ b/src/fri/fri_last_layer.cairo @@ -1,9 +1,4 @@ -use core::option::OptionTrait; -use core::traits::TryInto; - -use cairo_verifier::common::horner_eval; -use cairo_verifier::common::math; -use cairo_verifier::fri::fri_layer::FriLayerQuery; +use cairo_verifier::{common::{horner_eval, math}, fri::fri_layer::FriLayerQuery,}; // Verifies FRI last layer by evaluating the given polynomial on the given points // (=inverses of x_inv_values), and comparing the results to the given values. diff --git a/src/fri/fri_layer.cairo b/src/fri/fri_layer.cairo index 74842a20e..c637dec95 100644 --- a/src/fri/fri_layer.cairo +++ b/src/fri/fri_layer.cairo @@ -1,13 +1,6 @@ -use cairo_verifier::common::array_extend::ArrayExtendTrait; -use core::box::BoxTrait; -use core::debug::PrintTrait; -use core::option::OptionTrait; -use core::traits::TryInto; -use core::traits::Into; -use core::array::SpanTrait; -use core::array::ArrayTrait; -use cairo_verifier::fri::fri_formula::fri_formula; -use cairo_verifier::common::math; +use cairo_verifier::{ + common::{array_extend::ArrayExtendTrait, math::pow}, fri::fri_formula::fri_formula +}; #[derive(Drop, Copy)] struct FriLayerComputationParams { @@ -126,7 +119,7 @@ fn compute_next_layer( ); // Write next layer query. - let next_x_inv = math::pow(coset_x_inv, params.coset_size); + let next_x_inv = pow(coset_x_inv, params.coset_size); next_queries .append( FriLayerQuery { diff --git a/src/fri/tests/test_fri_formula.cairo b/src/fri/tests/test_fri_formula.cairo index 365681bec..36e0cb00c 100644 --- a/src/fri/tests/test_fri_formula.cairo +++ b/src/fri/tests/test_fri_formula.cairo @@ -1,4 +1,3 @@ -use core::array::ArrayTrait; use cairo_verifier::fri::fri_formula::{fri_formula}; #[test] diff --git a/src/fri/tests/test_last_layer.cairo b/src/fri/tests/test_last_layer.cairo index 813a46185..36f09a2bb 100644 --- a/src/fri/tests/test_last_layer.cairo +++ b/src/fri/tests/test_last_layer.cairo @@ -1,6 +1,4 @@ -use core::array::ArrayTrait; -use cairo_verifier::fri::fri_last_layer::verify_last_layer; -use cairo_verifier::fri::fri_layer::FriLayerQuery; +use cairo_verifier::fri::{fri_last_layer::verify_last_layer, fri_layer::FriLayerQuery,}; #[test] #[available_gas(9999999999)] diff --git a/src/fri/tests/test_next_layer.cairo b/src/fri/tests/test_next_layer.cairo index 565edcec8..0a9a3a37f 100644 --- a/src/fri/tests/test_next_layer.cairo +++ b/src/fri/tests/test_next_layer.cairo @@ -1,7 +1,7 @@ -use core::debug::PrintTrait; -use core::array::ArrayTrait; -use cairo_verifier::fri::fri_layer::{FriLayerQuery, FriLayerComputationParams, compute_next_layer}; -use cairo_verifier::fri::fri_group::get_fri_group; +use cairo_verifier::fri::{ + fri_layer::{FriLayerQuery, FriLayerComputationParams, compute_next_layer}, + fri_group::get_fri_group, +}; #[test] #[available_gas(9999999999)] diff --git a/src/lib.cairo b/src/lib.cairo index 8c165325a..dfc2d5fa7 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,7 +1,3 @@ -const FIELD_GENERATOR: felt252 = 3; -const FIELD_GENERATOR_INVERSE: felt252 = - 1206167596222043737899107594365023368541035738443865566657697352045290673494; - mod channel; mod common; mod structs; diff --git a/src/structs/stark_config.cairo b/src/structs/stark_config.cairo index 68cae99dd..49e29d814 100644 --- a/src/structs/stark_config.cairo +++ b/src/structs/stark_config.cairo @@ -1,7 +1,7 @@ -use cairo_verifier::structs::traces_config::TracesConfig; -use cairo_verifier::table_commitment::TableCommitmentConfig; -use cairo_verifier::fri::fri_config::FriConfig; -use cairo_verifier::structs::proof_of_work_config::ProofOfWorkConfig; +use cairo_verifier::{ + structs::traces_config::TracesConfig, table_commitment::TableCommitmentConfig, + fri::fri_config::FriConfig, structs::proof_of_work_config::ProofOfWorkConfig +}; struct StarkConfig { traces: TracesConfig, From 64405d9ad91f0bf3981e3ef01bdc32a964aaba2c Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Thu, 28 Dec 2023 13:10:16 +0100 Subject: [PATCH 38/38] remove unnecessary binding --- src/fri/fri.cairo | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo index d78683403..0cabc102f 100644 --- a/src/fri/fri.cairo +++ b/src/fri/fri.cairo @@ -126,8 +126,9 @@ fn fri_commit( channel.read_felt_vector_from_prover(unsent_commitment.last_layer_coefficients); let coefficients = unsent_commitment.last_layer_coefficients; - let n_coefficients = pow(2, config.log_last_layer_degree_bound); - assert(n_coefficients == coefficients.len().into(), 'Invalid value'); + assert( + pow(2, config.log_last_layer_degree_bound) == coefficients.len().into(), 'Invalid value' + ); FriCommitment { config: config,