From 2143ccf95ab6bf14f8b235f9f8607527c1dee0af Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Wed, 17 Sep 2025 08:05:10 +0200 Subject: [PATCH 01/25] feat: Add Plonky3 basic backend --- Cargo.toml | 1 + codegen/plonky3/Cargo.toml | 17 +++ codegen/plonky3/README.md | 3 + .../plonky3/src/air/boundary_constraints.rs | 17 +++ codegen/plonky3/src/air/graph.rs | 134 ++++++++++++++++++ codegen/plonky3/src/air/mod.rs | 74 ++++++++++ .../plonky3/src/air/transition_constraints.rs | 18 +++ codegen/plonky3/src/imports.rs | 13 ++ codegen/plonky3/src/lib.rs | 28 ++++ 9 files changed, 305 insertions(+) create mode 100644 codegen/plonky3/Cargo.toml create mode 100644 codegen/plonky3/README.md create mode 100644 codegen/plonky3/src/air/boundary_constraints.rs create mode 100644 codegen/plonky3/src/air/graph.rs create mode 100644 codegen/plonky3/src/air/mod.rs create mode 100644 codegen/plonky3/src/air/transition_constraints.rs create mode 100644 codegen/plonky3/src/imports.rs create mode 100644 codegen/plonky3/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 1278e9126..a3285a70d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "air", "codegen/winterfell", "codegen/ace", + "codegen/plonky3", ] resolver = "2" diff --git a/codegen/plonky3/Cargo.toml b/codegen/plonky3/Cargo.toml new file mode 100644 index 000000000..eb7766ea2 --- /dev/null +++ b/codegen/plonky3/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "air-codegen-plonky3" +version = "0.5.0" +description = "Plonky3 code generator for the AirScript language" +authors.workspace = true +readme = "README.md" +license.workspace = true +repository.workspace = true +categories = ["compilers", "cryptography"] +keywords = ["air", "stark", "plonky3", "zero-knowledge", "zkp"] +edition.workspace = true +rust-version.workspace = true + +[dependencies] +air-ir = { package = "air-ir", path = "../../air", version = "0.5" } +anyhow = { workspace = true } +codegen = "0.2" diff --git a/codegen/plonky3/README.md b/codegen/plonky3/README.md new file mode 100644 index 000000000..8ee666dfd --- /dev/null +++ b/codegen/plonky3/README.md @@ -0,0 +1,3 @@ +# Plonky3 Code Generator + +This crate contains a code generator targeting the [Plonky3 prover](https://github.com/Plonky3/Plonky3) Rust library. diff --git a/codegen/plonky3/src/air/boundary_constraints.rs b/codegen/plonky3/src/air/boundary_constraints.rs new file mode 100644 index 000000000..19a3519d1 --- /dev/null +++ b/codegen/plonky3/src/air/boundary_constraints.rs @@ -0,0 +1,17 @@ +use air_ir::{Air, TraceSegmentId}; +use codegen::Function; + +use super::Codegen; + +/// Adds the main boundary constraints to the generated code. +pub(super) fn add_main_boundary_constraints(eval_func: &mut Function, ir: &Air) { + for constraint in ir.boundary_constraints(TraceSegmentId::Main) { + let expr_root = constraint.node_index(); + + let expr_root_string = expr_root.to_string(ir, TraceSegmentId::Main); + + let assertion = format!("builder.when_first_row().assert_zero::<_>({expr_root_string});"); + + eval_func.line(assertion); + } +} diff --git a/codegen/plonky3/src/air/graph.rs b/codegen/plonky3/src/air/graph.rs new file mode 100644 index 000000000..8aa05a572 --- /dev/null +++ b/codegen/plonky3/src/air/graph.rs @@ -0,0 +1,134 @@ +use air_ir::{ + Air, IntegrityConstraintDegree, NodeIndex, Operation, TraceAccess, TraceSegmentId, Value, +}; + +// RUST STRING GENERATION FOR THE CONSTRAINT GRAPH +// ================================================================================================ + +/// Code generation trait for generating Rust code strings from IR types related to constraints and +/// the [AlgebraicGraph]. +pub trait Codegen { + fn to_string(&self, ir: &Air, trace_segment: TraceSegmentId) -> String; +} + +impl Codegen for IntegrityConstraintDegree { + fn to_string(&self, _ir: &Air, _trace_segment: TraceSegmentId) -> String { + if self.cycles().is_empty() { + format!("TransitionConstraintDegree::new({})", self.base()) + } else { + let cycles = self + .cycles() + .iter() + .map(|cycle_len| cycle_len.to_string()) + .collect::>() + .join(", "); + format!("TransitionConstraintDegree::with_cycles({}, vec![{}])", self.base(), cycles) + } + } +} + +impl Codegen for TraceAccess { + fn to_string(&self, _ir: &Air, trace_segment: TraceSegmentId) -> String { + let frame = self.segment.to_string(); + let row_offset = match self.row_offset { + 0 => { + format!("current[{}]", self.column) + }, + 1 => { + format!("next[{}]", self.column) + }, + _ => panic!("Plonky3 doesn't support row offsets greater than 1."), + }; + if self.segment == TraceSegmentId::Main && self.segment != trace_segment { + format!("E::from({frame}_{row_offset})") + } else { + format!("{frame}_{row_offset}") + } + } +} + +impl Codegen for NodeIndex { + fn to_string(&self, ir: &Air, trace_segment: TraceSegmentId) -> String { + let op = ir.constraint_graph().node(self).op(); + op.to_string(ir, trace_segment) + } +} + +impl Codegen for Operation { + fn to_string(&self, ir: &Air, trace_segment: TraceSegmentId) -> String { + match self { + Operation::Value(value) => value.to_string(ir, trace_segment), + Operation::Add(..) => binary_op_to_string(ir, self, trace_segment), + Operation::Sub(..) => binary_op_to_string(ir, self, trace_segment), + Operation::Mul(..) => binary_op_to_string(ir, self, trace_segment), + } + } +} + +impl Codegen for Value { + fn to_string(&self, ir: &Air, trace_segment: TraceSegmentId) -> String { + match self { + Value::Constant(value) => format!("AB::Expr::from(AB::F::from_u64({value}))"), + Value::TraceAccess(trace_access) => trace_access.to_string(ir, trace_segment), + Value::PublicInput(air_ir::PublicInputAccess { name, index }) => { + let get_public_input_offset = |name: &str| { + ir.public_inputs() + .take_while(|pi| pi.name() != name) + .map(|pi| pi.size()) + .sum::() + }; + format!("public_values[{}].into()", get_public_input_offset(name.as_str()) + index) + }, + _ => todo!(), + /*Value::PeriodicColumn(pc) => { + let index = + ir.periodic_columns.iter().position(|(qid, _)| qid == &pc.name).unwrap(); + format!("periodic_values[{index}]") + }, + Value::PublicInputTable(air_ir::PublicInputTableAccess { + table_name, + bus_type, + num_cols: _, + }) => { + format!("reduced_{table_name}_{bus_type}") + }, + Value::RandomValue(idx) => { + format!("aux_rand_elements.rand_elements()[{idx}]") + },*/ + } + } +} + +/// Returns a string representation of a binary operation. +fn binary_op_to_string(ir: &Air, op: &Operation, trace_segment: TraceSegmentId) -> String { + match op { + Operation::Add(l_idx, r_idx) => { + let lhs = l_idx.to_string(ir, trace_segment); + let rhs = r_idx.to_string(ir, trace_segment); + format!("{lhs} + {rhs}") + }, + Operation::Sub(l_idx, r_idx) => { + let lhs = l_idx.to_string(ir, trace_segment); + let rhs = if ir.constraint_graph().node(r_idx).op().precedence() <= op.precedence() { + format!("({})", r_idx.to_string(ir, trace_segment)) + } else { + r_idx.to_string(ir, trace_segment) + }; + format!("{lhs} - {rhs}") + }, + Operation::Mul(l_idx, r_idx) => { + let lhs = if ir.constraint_graph().node(l_idx).op().precedence() < op.precedence() { + format!("({})", l_idx.to_string(ir, trace_segment)) + } else { + l_idx.to_string(ir, trace_segment) + }; + let rhs = if ir.constraint_graph().node(r_idx).op().precedence() < op.precedence() { + format!("({})", r_idx.to_string(ir, trace_segment)) + } else { + r_idx.to_string(ir, trace_segment) + }; + format!("{lhs} * {rhs}") + }, + _ => panic!("unsupported operation"), + } +} diff --git a/codegen/plonky3/src/air/mod.rs b/codegen/plonky3/src/air/mod.rs new file mode 100644 index 000000000..f19230eb8 --- /dev/null +++ b/codegen/plonky3/src/air/mod.rs @@ -0,0 +1,74 @@ +mod boundary_constraints; +mod graph; +use graph::Codegen; +mod transition_constraints; + +use air_ir::Air; + +use super::Scope; +use crate::air::{ + boundary_constraints::add_main_boundary_constraints, + transition_constraints::add_main_transition_constraints, +}; + +// HELPERS TO GENERATE AN IMPLEMENTATION OF THE PLONKY3 AIR TRAIT +// ================================================================================================ + +/// Updates the provided scope with a new Air struct and Plonky3 Air trait implementation +/// which are equivalent the provided AirIR. +pub(super) fn add_air(scope: &mut Scope, ir: &Air) { + let name = ir.name(); + + // add the Air struct and its base implementation. + add_air_struct(scope, ir, name); + + // add Plonky3 AirBuilder trait implementation for the provided AirIR. + add_air_trait(scope, ir, name); +} + +/// Updates the provided scope with a custom Air struct. +fn add_air_struct(scope: &mut Scope, ir: &Air, name: &str) { + scope.raw(format!("pub const NUM_COLUMNS: usize = {};", ir.trace_segment_widths[0])); + + let num_public_values = + ir.public_inputs().map(|public_input| public_input.size()).sum::(); + scope.raw(format!("pub const NUM_PUBLIC_VALUES: usize = {num_public_values};")); + + // define the custom Air struct. + scope.new_struct(name).vis("pub"); + + // add the custom BaseAir implementation block + let base_air_impl = scope.new_impl(name).generic("F").impl_trait("BaseAir"); + base_air_impl.new_fn("width").arg_ref_self().ret("usize").line("NUM_COLUMNS"); + + // add the custom BaseAirWithPublicValues implementation block + let base_air_with_public_values_impl = + scope.new_impl(name).generic("F").impl_trait("BaseAirWithPublicValues"); + base_air_with_public_values_impl + .new_fn("num_public_values") + .arg_ref_self() + .ret("usize") + .line("NUM_PUBLIC_VALUES"); +} + +/// Updates the provided scope with the custom Air struct and an Air trait implementation based on +/// the provided AirIR. +fn add_air_trait(scope: &mut Scope, ir: &Air, name: &str) { + // add the implementation block for the Air trait. + let air_impl = scope + .new_impl(name) + .generic("AB: AirBuilderWithPublicValues") + .impl_trait("Air"); + + let eval_func = air_impl.new_fn("eval").arg_ref_self().arg("builder", "&mut AB"); + eval_func.line("let main = builder.main();"); + eval_func.line("let public_values = builder.public_values().to_vec();"); + eval_func.line("let (main_current, main_next) = ("); + eval_func.line(" main.row_slice(0).unwrap(),"); + eval_func.line(" main.row_slice(1).unwrap(),"); + eval_func.line(");"); + + add_main_boundary_constraints(eval_func, ir); + + add_main_transition_constraints(eval_func, ir); +} diff --git a/codegen/plonky3/src/air/transition_constraints.rs b/codegen/plonky3/src/air/transition_constraints.rs new file mode 100644 index 000000000..0a0ad92fa --- /dev/null +++ b/codegen/plonky3/src/air/transition_constraints.rs @@ -0,0 +1,18 @@ +use air_ir::{Air, TraceSegmentId}; +use codegen::Function; + +use super::Codegen; + +/// Adds the main transition constraints to the generated code. +pub(super) fn add_main_transition_constraints(eval_func: &mut Function, ir: &Air) { + // add the main integrity constraints + for constraint in ir.integrity_constraints(TraceSegmentId::Main) { + let expr_root = constraint.node_index(); + + let expr_root_string = expr_root.to_string(ir, TraceSegmentId::Main); + + let assertion = format!("builder.when_transition().assert_zero::<_>({expr_root_string});"); + + eval_func.line(assertion); + } +} diff --git a/codegen/plonky3/src/imports.rs b/codegen/plonky3/src/imports.rs new file mode 100644 index 000000000..7663096bb --- /dev/null +++ b/codegen/plonky3/src/imports.rs @@ -0,0 +1,13 @@ +use super::Scope; + +/// Adds the required imports to the provided scope. +pub(super) fn add_imports(scope: &mut Scope) { + // add plonky3 imports + scope.import("p3_air", "Air"); + scope.import("p3_air", "AirBuilder"); + scope.import("p3_air", "AirBuilderWithPublicValues"); + scope.import("p3_air", "BaseAir"); + scope.import("p3_air", "BaseAirWithPublicValues"); + scope.import("p3_matrix", "Matrix"); + scope.import("p3_field", "PrimeCharacteristicRing"); +} diff --git a/codegen/plonky3/src/lib.rs b/codegen/plonky3/src/lib.rs new file mode 100644 index 000000000..703a8ee94 --- /dev/null +++ b/codegen/plonky3/src/lib.rs @@ -0,0 +1,28 @@ +use air_ir::Air; +use codegen::Scope; + +mod air; +mod imports; + +// GENERATE RUST CODE FOR WINTERFELL AIR +// ================================================================================================ + +/// CodeGenerator is used to generate a Rust implementation of the Plonky3 STARK prover library's +/// Air trait. The generated Air expresses the constraints specified by the AirIR used to build the +/// CodeGenerator. +pub struct CodeGenerator; +impl air_ir::CodeGenerator for CodeGenerator { + type Output = String; + + fn generate(&self, ir: &Air) -> anyhow::Result { + let mut scope = Scope::new(); + + // add plonky3 imports. + imports::add_imports(&mut scope); + + // add an Air struct and plonky3 Air trait implementation for the provided AirIR. + air::add_air(&mut scope, ir); + + Ok(scope.to_string()) + } +} From d83b791c8e9dec9b3312716a557c4b87b7677616 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Wed, 17 Sep 2025 08:06:04 +0200 Subject: [PATCH 02/25] feat: Handle plonky3 target --- air-script/Cargo.toml | 1 + air-script/src/cli/transpile.rs | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/air-script/Cargo.toml b/air-script/Cargo.toml index 8d5d5e5ed..3ceafb720 100644 --- a/air-script/Cargo.toml +++ b/air-script/Cargo.toml @@ -18,6 +18,7 @@ path = "src/main.rs" [dependencies] air-codegen-winter = { package = "air-codegen-winter", path = "../codegen/winterfell", version = "0.5" } +air-codegen-plonky3 = { package = "air-codegen-plonky3", path = "../codegen/plonky3", version = "0.5" } air-ir = { package = "air-ir", path = "../air", version = "0.5" } air-parser = { package = "air-parser", path = "../parser", version = "0.5" } air-pass = { package = "air-pass", path = "../pass", version = "0.5" } diff --git a/air-script/src/cli/transpile.rs b/air-script/src/cli/transpile.rs index 3671dd096..48b7b37cd 100644 --- a/air-script/src/cli/transpile.rs +++ b/air-script/src/cli/transpile.rs @@ -9,11 +9,13 @@ use miden_diagnostics::{ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] pub enum Target { Winterfell, + Plonky3, } impl Target { pub fn extension(&self) -> &'static str { match self { Self::Winterfell => "rs", + Self::Plonky3 => "rs", } } } @@ -55,6 +57,7 @@ impl Transpile { let target = self.target.unwrap_or(Target::Winterfell); let backend: Box> = match target { Target::Winterfell => Box::new(air_codegen_winter::CodeGenerator), + Target::Plonky3 => Box::new(air_codegen_plonky3::CodeGenerator), }; // write transpiled output to the output path @@ -62,6 +65,13 @@ impl Transpile { Some(path) => path.clone(), None => { let mut path = input_path.clone(); + if target == Target::Plonky3 { + path.set_file_name(format!( + "{}_plonky3", + path.file_stem().unwrap().display() + )); + path.set_extension("air"); + } path.set_extension(target.extension()); path }, From 98495ba2c9fcb0b8ac443ed3981caabdad8290f0 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Wed, 17 Sep 2025 08:38:38 +0200 Subject: [PATCH 03/25] tests: Add E2E test codegen for binary plonky3 --- air-script/Cargo.toml | 12 ++++++++ air-script/tests/binary/binary.air | 2 +- air-script/tests/binary/binary.rs | 2 +- air-script/tests/binary/binary_plonky3.rs | 35 +++++++++++++++++++++++ air-script/tests/binary/mod.rs | 4 +++ air-script/tests/codegen/helpers.rs | 2 ++ air-script/tests/codegen/mod.rs | 1 + air-script/tests/codegen/plonky3.rs | 15 ++++++++++ 8 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 air-script/tests/binary/binary_plonky3.rs create mode 100644 air-script/tests/codegen/plonky3.rs diff --git a/air-script/Cargo.toml b/air-script/Cargo.toml index 3ceafb720..131e1dbf8 100644 --- a/air-script/Cargo.toml +++ b/air-script/Cargo.toml @@ -30,6 +30,18 @@ mir = { package = "air-mir", path = "../mir", version = "0.5" } [dev-dependencies] expect-test = "1.4" +p3-air = { package = "p3-air", version = "0.3", default-features = false } +p3-challenger = { package = "p3-challenger", version = "0.3", default-features = false } +p3-circle = { package = "p3-circle", version = "0.3", default-features = false } +p3-commit = { package = "p3-commit", version = "0.3", default-features = false } +p3-field = { package = "p3-field", version = "0.3", default-features = false } +p3-fri = { package = "p3-fri", version = "0.3", default-features = false } +p3-matrix = { package = "p3-matrix", version = "0.3", default-features = false } +p3-merkle-tree = { package = "p3-merkle-tree", version = "0.3", default-features = false } +p3-mersenne-31 = { package = "p3-mersenne-31", version = "0.3", default-features = false } +p3-sha256 = { package = "p3-sha256", version = "0.3", default-features = false } +p3-symmetric = { package = "p3-symmetric", version = "0.3", default-features = false } +p3-uni-stark = { package = "p3-uni-stark", version = "0.3", default-features = false } winter-air = { package = "winter-air", version = "0.12", default-features = false } winter-math = { package = "winter-math", version = "0.12", default-features = false } winter-utils = { package = "winter-utils", version = "0.12", default-features = false } diff --git a/air-script/tests/binary/binary.air b/air-script/tests/binary/binary.air index 50e218052..e609a69b3 100644 --- a/air-script/tests/binary/binary.air +++ b/air-script/tests/binary/binary.air @@ -9,7 +9,7 @@ public_inputs { } boundary_constraints { - enf a.first = 0; + enf a.first = stack_inputs[0]; } integrity_constraints { diff --git a/air-script/tests/binary/binary.rs b/air-script/tests/binary/binary.rs index 8b7185bbd..b398843dc 100644 --- a/air-script/tests/binary/binary.rs +++ b/air-script/tests/binary/binary.rs @@ -70,7 +70,7 @@ impl Air for BinaryAir { fn get_assertions(&self) -> Vec> { let mut result = Vec::new(); - result.push(Assertion::single(0, 0, Felt::ZERO)); + result.push(Assertion::single(0, 0, self.stack_inputs[0])); result } diff --git a/air-script/tests/binary/binary_plonky3.rs b/air-script/tests/binary/binary_plonky3.rs new file mode 100644 index 000000000..dc8a32634 --- /dev/null +++ b/air-script/tests/binary/binary_plonky3.rs @@ -0,0 +1,35 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; + +pub const NUM_COLUMNS: usize = 2; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct BinaryAir; + +impl BaseAir for BinaryAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for BinaryAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl Air for BinaryAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values = builder.public_values().to_vec(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[0] - public_values[0].into()); + builder.when_transition().assert_zero::<_>(main_current[0] * main_current[0] - main_current[0]); + builder.when_transition().assert_zero::<_>(main_current[1] * main_current[1] - main_current[1]); + } +} \ No newline at end of file diff --git a/air-script/tests/binary/mod.rs b/air-script/tests/binary/mod.rs index 0582511b7..3aa069368 100644 --- a/air-script/tests/binary/mod.rs +++ b/air-script/tests/binary/mod.rs @@ -2,3 +2,7 @@ #[allow(clippy::all)] mod binary; mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod binary_plonky3; diff --git a/air-script/tests/codegen/helpers.rs b/air-script/tests/codegen/helpers.rs index 3fc9c8aa6..577144d42 100644 --- a/air-script/tests/codegen/helpers.rs +++ b/air-script/tests/codegen/helpers.rs @@ -8,6 +8,7 @@ use miden_diagnostics::{ pub enum Target { Winterfell, + Plonky3, } pub struct Test { @@ -30,6 +31,7 @@ impl Test { let backend: Box> = match target { Target::Winterfell => Box::new(air_codegen_winter::CodeGenerator), + Target::Plonky3 => Box::new(air_codegen_plonky3::CodeGenerator), }; // generate Rust code targeting Winterfell diff --git a/air-script/tests/codegen/mod.rs b/air-script/tests/codegen/mod.rs index d802f40b1..a23676b61 100644 --- a/air-script/tests/codegen/mod.rs +++ b/air-script/tests/codegen/mod.rs @@ -1,2 +1,3 @@ mod helpers; +mod plonky3; mod winterfell; diff --git a/air-script/tests/codegen/plonky3.rs b/air-script/tests/codegen/plonky3.rs new file mode 100644 index 000000000..1c946a90f --- /dev/null +++ b/air-script/tests/codegen/plonky3.rs @@ -0,0 +1,15 @@ +use expect_test::expect_file; + +use super::helpers::{Target, Test}; + +#[test] +fn binary() { + let generated_air = Test::new("tests/binary/binary.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../binary/binary_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +// TODO: add all tests From f15970d9230b02c68526633a23fa1758df06a6e8 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Wed, 17 Sep 2025 08:39:16 +0200 Subject: [PATCH 04/25] tests: Add test of generated code in Plonky3 binary E2E tests --- air-script/tests/binary/mod.rs | 4 +- air-script/tests/binary/test_air_plonky3.rs | 81 +++++++++++++++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 air-script/tests/binary/test_air_plonky3.rs rename air-script/tests/binary/{test_air.rs => test_air_winterfell.rs} (100%) diff --git a/air-script/tests/binary/mod.rs b/air-script/tests/binary/mod.rs index 3aa069368..fa03709f2 100644 --- a/air-script/tests/binary/mod.rs +++ b/air-script/tests/binary/mod.rs @@ -1,7 +1,9 @@ #[rustfmt::skip] #[allow(clippy::all)] mod binary; -mod test_air; +mod test_air_winterfell; + +mod test_air_plonky3; #[rustfmt::skip] #[allow(clippy::all)] #[allow(unused_imports)] diff --git a/air-script/tests/binary/test_air_plonky3.rs b/air-script/tests/binary/test_air_plonky3.rs new file mode 100644 index 000000000..627acde10 --- /dev/null +++ b/air-script/tests/binary/test_air_plonky3.rs @@ -0,0 +1,81 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::{StarkConfig, prove, verify}; + +use crate::binary::binary_plonky3::{BinaryAir, NUM_COLUMNS}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::from_canonical_checked(inputs[0]).unwrap(); + rows[0][1] = F::ONE; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let a_prev = rows[i - 1][0]; + let b_prev = rows[i - 1][1]; + + // Update current row based on previous values + rows[i][0] = F::ONE - a_prev; + rows[i][1] = F::ONE - b_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + let proof = prove(&config, &BinaryAir {}, trace, &inputs_m31); + verify(&config, &BinaryAir {}, &proof, &inputs_m31).expect("Verification failed"); +} diff --git a/air-script/tests/binary/test_air.rs b/air-script/tests/binary/test_air_winterfell.rs similarity index 100% rename from air-script/tests/binary/test_air.rs rename to air-script/tests/binary/test_air_winterfell.rs From 254cdcc0eaa4699aa719e3402ff0e3a827a6d389 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Wed, 17 Sep 2025 08:43:48 +0200 Subject: [PATCH 05/25] fix: Make docs_sync() test work on windows --- air-script/tests/docs_sync.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/air-script/tests/docs_sync.rs b/air-script/tests/docs_sync.rs index c33ea5512..75bfc9898 100644 --- a/air-script/tests/docs_sync.rs +++ b/air-script/tests/docs_sync.rs @@ -3,7 +3,9 @@ use std::{path::Path, process::Command}; #[test] fn docs_sync() { let examples_dir = Path::new("../docs/examples"); - let airc_path = Path::new("target/release/airc"); + // Use CARGO_MANIFEST_DIR to build an absolute path to airc, needed on Windows to correctly use `current_dir`. + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"); + let airc_path = Path::new(&manifest_dir).join("../target/release/airc"); // Build the CLI tool first let build_output = Command::new("cargo") @@ -38,11 +40,11 @@ fn docs_sync() { let file_name = air_file.file_name().unwrap().to_string_lossy(); let output_path = air_file.with_extension("rs"); - let output = Command::new(airc_path) + let output = Command::new(&airc_path) .args(["transpile", air_file.to_str().unwrap(), "-o", output_path.to_str().unwrap()]) .current_dir("../") .output() - .unwrap_or_else(|_| panic!("Failed to transpile {}", file_name)); + .unwrap_or_else(|_| panic!("Failed to transpile {file_name}")); assert!( output.status.success(), @@ -51,7 +53,7 @@ fn docs_sync() { String::from_utf8_lossy(&output.stderr) ); - println!("Successfully transpiled: {}", file_name); + println!("Successfully transpiled: {file_name}"); // Clean up generated Rust files let _ = std::fs::remove_file(output_path); From aaa41ed97d254913505e0cdc5e36100e6bee1490 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Fri, 19 Sep 2025 13:09:16 +0200 Subject: [PATCH 06/25] fix(codegen): differentiate integrity and transition constraints --- air-script/tests/binary/binary_plonky3.rs | 4 ++-- .../plonky3/src/air/integrity_constraints.rs | 22 +++++++++++++++++++ codegen/plonky3/src/air/mod.rs | 6 ++--- .../plonky3/src/air/transition_constraints.rs | 18 --------------- 4 files changed, 27 insertions(+), 23 deletions(-) create mode 100644 codegen/plonky3/src/air/integrity_constraints.rs delete mode 100644 codegen/plonky3/src/air/transition_constraints.rs diff --git a/air-script/tests/binary/binary_plonky3.rs b/air-script/tests/binary/binary_plonky3.rs index dc8a32634..68f620460 100644 --- a/air-script/tests/binary/binary_plonky3.rs +++ b/air-script/tests/binary/binary_plonky3.rs @@ -29,7 +29,7 @@ impl Air for BinaryAir { main.row_slice(1).unwrap(), ); builder.when_first_row().assert_zero::<_>(main_current[0] - public_values[0].into()); - builder.when_transition().assert_zero::<_>(main_current[0] * main_current[0] - main_current[0]); - builder.when_transition().assert_zero::<_>(main_current[1] * main_current[1] - main_current[1]); + builder.assert_zero::<_>(main_current[0] * main_current[0] - main_current[0]); + builder.assert_zero::<_>(main_current[1] * main_current[1] - main_current[1]); } } \ No newline at end of file diff --git a/codegen/plonky3/src/air/integrity_constraints.rs b/codegen/plonky3/src/air/integrity_constraints.rs new file mode 100644 index 000000000..78dae2d55 --- /dev/null +++ b/codegen/plonky3/src/air/integrity_constraints.rs @@ -0,0 +1,22 @@ +use air_ir::{Air, ConstraintDomain, TraceSegmentId}; +use codegen::Function; + +use super::Codegen; + +/// Adds the main integrity constraints to the generated code. +pub(super) fn add_main_integrity_constraints(eval_func: &mut Function, ir: &Air) { + for constraint in ir.integrity_constraints(TraceSegmentId::Main) { + let expr_root = constraint.node_index(); + let expr_root_string = expr_root.to_string(ir, TraceSegmentId::Main); + + // If the constraint is a transition constraint (depends on the next row), we do not + // evaluate it in the last row, with the `when_transition` method. + let assertion = if let ConstraintDomain::EveryFrame(_) = constraint.domain() { + format!("builder.when_transition().assert_zero::<_>({expr_root_string});") + } else { + format!("builder.assert_zero::<_>({expr_root_string});") + }; + + eval_func.line(assertion); + } +} diff --git a/codegen/plonky3/src/air/mod.rs b/codegen/plonky3/src/air/mod.rs index f19230eb8..81a5b4568 100644 --- a/codegen/plonky3/src/air/mod.rs +++ b/codegen/plonky3/src/air/mod.rs @@ -1,14 +1,14 @@ mod boundary_constraints; mod graph; use graph::Codegen; -mod transition_constraints; +mod integrity_constraints; use air_ir::Air; use super::Scope; use crate::air::{ boundary_constraints::add_main_boundary_constraints, - transition_constraints::add_main_transition_constraints, + integrity_constraints::add_main_integrity_constraints, }; // HELPERS TO GENERATE AN IMPLEMENTATION OF THE PLONKY3 AIR TRAIT @@ -70,5 +70,5 @@ fn add_air_trait(scope: &mut Scope, ir: &Air, name: &str) { add_main_boundary_constraints(eval_func, ir); - add_main_transition_constraints(eval_func, ir); + add_main_integrity_constraints(eval_func, ir); } diff --git a/codegen/plonky3/src/air/transition_constraints.rs b/codegen/plonky3/src/air/transition_constraints.rs deleted file mode 100644 index 0a0ad92fa..000000000 --- a/codegen/plonky3/src/air/transition_constraints.rs +++ /dev/null @@ -1,18 +0,0 @@ -use air_ir::{Air, TraceSegmentId}; -use codegen::Function; - -use super::Codegen; - -/// Adds the main transition constraints to the generated code. -pub(super) fn add_main_transition_constraints(eval_func: &mut Function, ir: &Air) { - // add the main integrity constraints - for constraint in ir.integrity_constraints(TraceSegmentId::Main) { - let expr_root = constraint.node_index(); - - let expr_root_string = expr_root.to_string(ir, TraceSegmentId::Main); - - let assertion = format!("builder.when_transition().assert_zero::<_>({expr_root_string});"); - - eval_func.line(assertion); - } -} From 8b3ed7364d2bfac2f5b3c95cd569ad6534f5a37b Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Fri, 19 Sep 2025 13:14:59 +0200 Subject: [PATCH 07/25] refactor(codegen): avoid public_+value Vec allocation --- air-script/tests/binary/binary_plonky3.rs | 2 +- codegen/plonky3/src/air/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/air-script/tests/binary/binary_plonky3.rs b/air-script/tests/binary/binary_plonky3.rs index 68f620460..f06827809 100644 --- a/air-script/tests/binary/binary_plonky3.rs +++ b/air-script/tests/binary/binary_plonky3.rs @@ -23,7 +23,7 @@ impl BaseAirWithPublicValues for BinaryAir { impl Air for BinaryAir { fn eval(&self, builder: &mut AB) { let main = builder.main(); - let public_values = builder.public_values().to_vec(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let (main_current, main_next) = ( main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), diff --git a/codegen/plonky3/src/air/mod.rs b/codegen/plonky3/src/air/mod.rs index 81a5b4568..79c533a73 100644 --- a/codegen/plonky3/src/air/mod.rs +++ b/codegen/plonky3/src/air/mod.rs @@ -62,7 +62,7 @@ fn add_air_trait(scope: &mut Scope, ir: &Air, name: &str) { let eval_func = air_impl.new_fn("eval").arg_ref_self().arg("builder", "&mut AB"); eval_func.line("let main = builder.main();"); - eval_func.line("let public_values = builder.public_values().to_vec();"); + eval_func.line("let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect(\"Wrong number of public values\");"); eval_func.line("let (main_current, main_next) = ("); eval_func.line(" main.row_slice(0).unwrap(),"); eval_func.line(" main.row_slice(1).unwrap(),"); From e628f199d415b9c8fd0402c2c859f706e80bd6cc Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Fri, 19 Sep 2025 13:15:34 +0200 Subject: [PATCH 08/25] chore: changelog, lint fix and removed unused IntegrityConstraintDegree codegen --- CHANGELOG.md | 1 + air-script/tests/docs_sync.rs | 3 ++- codegen/plonky3/src/air/graph.rs | 20 +------------------- 3 files changed, 4 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcdaa45ed..43a1720c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Refactored the unrolling pass in MIR (#434). - Fix regressions on MIR and list_comprehensions (#449). - Update documentation and tests thereof (#437). +- Add Plonky3 codegen backend (#461). ## 0.4.0 (2025-06-20) diff --git a/air-script/tests/docs_sync.rs b/air-script/tests/docs_sync.rs index 75bfc9898..c7fc12e72 100644 --- a/air-script/tests/docs_sync.rs +++ b/air-script/tests/docs_sync.rs @@ -3,7 +3,8 @@ use std::{path::Path, process::Command}; #[test] fn docs_sync() { let examples_dir = Path::new("../docs/examples"); - // Use CARGO_MANIFEST_DIR to build an absolute path to airc, needed on Windows to correctly use `current_dir`. + // Use CARGO_MANIFEST_DIR to build an absolute path to airc, needed on Windows to correctly use + // `current_dir`. let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"); let airc_path = Path::new(&manifest_dir).join("../target/release/airc"); diff --git a/codegen/plonky3/src/air/graph.rs b/codegen/plonky3/src/air/graph.rs index 8aa05a572..3f987b7d3 100644 --- a/codegen/plonky3/src/air/graph.rs +++ b/codegen/plonky3/src/air/graph.rs @@ -1,6 +1,4 @@ -use air_ir::{ - Air, IntegrityConstraintDegree, NodeIndex, Operation, TraceAccess, TraceSegmentId, Value, -}; +use air_ir::{Air, NodeIndex, Operation, TraceAccess, TraceSegmentId, Value}; // RUST STRING GENERATION FOR THE CONSTRAINT GRAPH // ================================================================================================ @@ -11,22 +9,6 @@ pub trait Codegen { fn to_string(&self, ir: &Air, trace_segment: TraceSegmentId) -> String; } -impl Codegen for IntegrityConstraintDegree { - fn to_string(&self, _ir: &Air, _trace_segment: TraceSegmentId) -> String { - if self.cycles().is_empty() { - format!("TransitionConstraintDegree::new({})", self.base()) - } else { - let cycles = self - .cycles() - .iter() - .map(|cycle_len| cycle_len.to_string()) - .collect::>() - .join(", "); - format!("TransitionConstraintDegree::with_cycles({}, vec![{}])", self.base(), cycles) - } - } -} - impl Codegen for TraceAccess { fn to_string(&self, _ir: &Air, trace_segment: TraceSegmentId) -> String { let frame = self.segment.to_string(); From df72ff42c3729c10900fe30d57144b6f3ba37d3f Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Wed, 24 Sep 2025 11:36:42 +0200 Subject: [PATCH 09/25] feat: add periodic_columns --- air-script/Cargo.toml | 2 +- air-script/tests/binary/binary_plonky3.rs | 11 +- air-script/tests/binary/test_air_plonky3.rs | 17 +- air-script/tests/bitwise/bitwise_plonky3.rs | 61 ++++++++ air-script/tests/bitwise/mod.rs | 7 +- air-script/tests/bitwise/test_air_plonky3.rs | 128 +++++++++++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 air-script/tests/helpers/mod.rs | 76 +-------- .../tests/helpers/plonky3_periodic_columns.rs | 146 ++++++++++++++++++ .../tests/helpers/winterfell_test_helpers.rs | 73 +++++++++ .../plonky3/src/air/boundary_constraints.rs | 2 +- codegen/plonky3/src/air/graph.rs | 58 ++++--- .../plonky3/src/air/integrity_constraints.rs | 2 +- codegen/plonky3/src/air/mod.rs | 24 ++- codegen/plonky3/src/imports.rs | 2 + 15 files changed, 496 insertions(+), 113 deletions(-) create mode 100644 air-script/tests/bitwise/bitwise_plonky3.rs create mode 100644 air-script/tests/bitwise/test_air_plonky3.rs rename air-script/tests/bitwise/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/helpers/plonky3_periodic_columns.rs create mode 100644 air-script/tests/helpers/winterfell_test_helpers.rs diff --git a/air-script/Cargo.toml b/air-script/Cargo.toml index 131e1dbf8..883e5b61a 100644 --- a/air-script/Cargo.toml +++ b/air-script/Cargo.toml @@ -41,7 +41,7 @@ p3-merkle-tree = { package = "p3-merkle-tree", version = "0.3", default-features p3-mersenne-31 = { package = "p3-mersenne-31", version = "0.3", default-features = false } p3-sha256 = { package = "p3-sha256", version = "0.3", default-features = false } p3-symmetric = { package = "p3-symmetric", version = "0.3", default-features = false } -p3-uni-stark = { package = "p3-uni-stark", version = "0.3", default-features = false } +p3-uni-stark = { package = "p3-uni-stark", version = "0.3.0", default-features = false } winter-air = { package = "winter-air", version = "0.12", default-features = false } winter-math = { package = "winter-math", version = "0.12", default-features = false } winter-utils = { package = "winter-utils", version = "0.12", default-features = false } diff --git a/air-script/tests/binary/binary_plonky3.rs b/air-script/tests/binary/binary_plonky3.rs index f06827809..4d89ff939 100644 --- a/air-script/tests/binary/binary_plonky3.rs +++ b/air-script/tests/binary/binary_plonky3.rs @@ -1,6 +1,7 @@ use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; use p3_matrix::Matrix; use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; pub const NUM_COLUMNS: usize = 2; @@ -20,10 +21,18 @@ impl BaseAirWithPublicValues for BinaryAir { } } -impl Air for BinaryAir { +impl BaseAirWithPeriodicColumns for BinaryAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for BinaryAir { fn eval(&self, builder: &mut AB) { let main = builder.main(); let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), diff --git a/air-script/tests/binary/test_air_plonky3.rs b/air-script/tests/binary/test_air_plonky3.rs index 627acde10..da7b12a53 100644 --- a/air-script/tests/binary/test_air_plonky3.rs +++ b/air-script/tests/binary/test_air_plonky3.rs @@ -10,9 +10,12 @@ use p3_merkle_tree::MerkleTreeMmcs; use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::{StarkConfig, prove, verify}; +use p3_uni_stark::StarkConfig; -use crate::binary::binary_plonky3::{BinaryAir, NUM_COLUMNS}; +use crate::{ + binary::binary_plonky3::{BinaryAir, NUM_COLUMNS}, + helpers::check_constraints_with_periodic_columns, +}; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; @@ -76,6 +79,12 @@ fn test_air_plonky3() { let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); let trace = generate_trace_rows::(inputs); - let proof = prove(&config, &BinaryAir {}, trace, &inputs_m31); - verify(&config, &BinaryAir {}, &proof, &inputs_m31).expect("Verification failed"); + + check_constraints_with_periodic_columns(&BinaryAir {}, &trace, &inputs_m31); + + /*let prove_with_periodic_columns = prove_with_periodic_columns(&config, &BinaryAir {}, trace, &inputs_m31); + verify_with_periodic_columns(&config, &BinaryAir {}, &prove_with_periodic_columns, &inputs_m31).expect("Verification failed");*/ + + /*let proof = prove(&config, &BinaryAir {}, trace, &inputs_m31); + verify(&config, &BinaryAir {}, &proof, &inputs_m31).expect("Verification failed");*/ } diff --git a/air-script/tests/bitwise/bitwise_plonky3.rs b/air-script/tests/bitwise/bitwise_plonky3.rs new file mode 100644 index 000000000..e67cde192 --- /dev/null +++ b/air-script/tests/bitwise/bitwise_plonky3.rs @@ -0,0 +1,61 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 14; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct BitwiseAir; + +impl BaseAir for BitwiseAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for BitwiseAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for BitwiseAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + vec![F::from_u64(1), F::from_u64(0), F::from_u64(0), F::from_u64(0), F::from_u64(0), F::from_u64(0), F::from_u64(0), F::from_u64(0)], + vec![F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(0)], + ] + } +} + +impl Air for BitwiseAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[13]); + builder.assert_zero::<_>(main_current[0] * main_current[0] - main_current[0]); + builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[0] - main_current[0])); + builder.assert_zero::<_>(main_current[3] * main_current[3] - main_current[3]); + builder.assert_zero::<_>(main_current[4] * main_current[4] - main_current[4]); + builder.assert_zero::<_>(main_current[5] * main_current[5] - main_current[5]); + builder.assert_zero::<_>(main_current[6] * main_current[6] - main_current[6]); + builder.assert_zero::<_>(main_current[7] * main_current[7] - main_current[7]); + builder.assert_zero::<_>(main_current[8] * main_current[8] - main_current[8]); + builder.assert_zero::<_>(main_current[9] * main_current[9] - main_current[9]); + builder.assert_zero::<_>(main_current[10] * main_current[10] - main_current[10]); + builder.assert_zero::<_>(periodic_values[0].into() * (main_current[1] - (main_current[3] + AB::Expr::from(AB::F::from_u64(2)) * main_current[4] + AB::Expr::from(AB::F::from_u64(4)) * main_current[5] + AB::Expr::from(AB::F::from_u64(8)) * main_current[6]))); + builder.assert_zero::<_>(periodic_values[0].into() * (main_current[2] - (main_current[7] + AB::Expr::from(AB::F::from_u64(2)) * main_current[8] + AB::Expr::from(AB::F::from_u64(4)) * main_current[9] + AB::Expr::from(AB::F::from_u64(8)) * main_current[10]))); + builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[1] - (main_current[1] * AB::Expr::from(AB::F::from_u64(16)) + main_current[3] + AB::Expr::from(AB::F::from_u64(2)) * main_current[4] + AB::Expr::from(AB::F::from_u64(4)) * main_current[5] + AB::Expr::from(AB::F::from_u64(8)) * main_current[6]))); + builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[2] - (main_current[2] * AB::Expr::from(AB::F::from_u64(16)) + main_current[7] + AB::Expr::from(AB::F::from_u64(2)) * main_current[8] + AB::Expr::from(AB::F::from_u64(4)) * main_current[9] + AB::Expr::from(AB::F::from_u64(8)) * main_current[10]))); + builder.assert_zero::<_>(periodic_values[0].into() * main_current[11]); + builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_current[12] - main_next[11])); + builder.assert_zero::<_>((AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * (main_current[12] - (main_current[11] * AB::Expr::from(AB::F::from_u64(16)) + main_current[3] * main_current[7] + AB::Expr::from(AB::F::from_u64(2)) * main_current[4] * main_current[8] + AB::Expr::from(AB::F::from_u64(4)) * main_current[5] * main_current[9] + AB::Expr::from(AB::F::from_u64(8)) * main_current[6] * main_current[10])) + main_current[0] * (main_current[12] - (main_current[11] * AB::Expr::from(AB::F::from_u64(16)) + main_current[3] + main_current[7] - AB::Expr::from(AB::F::from_u64(2)) * main_current[3] * main_current[7] + AB::Expr::from(AB::F::from_u64(2)) * (main_current[4] + main_current[8] - AB::Expr::from(AB::F::from_u64(2)) * main_current[4] * main_current[8]) + AB::Expr::from(AB::F::from_u64(4)) * (main_current[5] + main_current[9] - AB::Expr::from(AB::F::from_u64(2)) * main_current[5] * main_current[9]) + AB::Expr::from(AB::F::from_u64(8)) * (main_current[6] + main_current[10] - AB::Expr::from(AB::F::from_u64(2)) * main_current[6] * main_current[10])))); + } +} \ No newline at end of file diff --git a/air-script/tests/bitwise/mod.rs b/air-script/tests/bitwise/mod.rs index 5798d90dc..31fe7ab14 100644 --- a/air-script/tests/bitwise/mod.rs +++ b/air-script/tests/bitwise/mod.rs @@ -1,4 +1,9 @@ #[rustfmt::skip] #[allow(clippy::all)] mod bitwise; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +mod bitwise_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/bitwise/test_air_plonky3.rs b/air-script/tests/bitwise/test_air_plonky3.rs new file mode 100644 index 000000000..c5c30ed7e --- /dev/null +++ b/air-script/tests/bitwise/test_air_plonky3.rs @@ -0,0 +1,128 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + bitwise::bitwise_plonky3::{BitwiseAir, NUM_COLUMNS}, + helpers::check_constraints_with_periodic_columns, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + let first = F::ZERO; + + // Initialize first row + rows[0][0] = first; + rows[0][1] = first; + rows[0][2] = first; + rows[0][3] = first; + rows[0][4] = first; + rows[0][5] = first; + rows[0][6] = first; + rows[0][7] = first; + rows[0][8] = first; + rows[0][9] = first; + rows[0][10] = first; + rows[0][11] = first; + rows[0][12] = first; + rows[0][13] = first; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + let col_3_prev = rows[i - 1][3]; + let col_4_prev = rows[i - 1][4]; + let col_5_prev = rows[i - 1][5]; + let col_6_prev = rows[i - 1][6]; + let col_7_prev = rows[i - 1][7]; + let col_8_prev = rows[i - 1][8]; + let col_9_prev = rows[i - 1][9]; + let col_10_prev = rows[i - 1][10]; + let col_11_prev = rows[i - 1][11]; + let col_12_prev = rows[i - 1][12]; + let col_13_prev = rows[i - 1][13]; + + // Update current row based on previous values + rows[i][0] = col_0_prev; + rows[i][1] = col_1_prev; + rows[i][2] = col_2_prev; + rows[i][3] = col_3_prev; + rows[i][4] = col_4_prev; + rows[i][5] = col_5_prev; + rows[i][6] = col_6_prev; + rows[i][7] = col_7_prev; + rows[i][8] = col_8_prev; + rows[i][9] = col_9_prev; + rows[i][10] = col_10_prev; + rows[i][11] = col_11_prev; + rows[i][12] = col_12_prev; + rows[i][13] = col_13_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&BitwiseAir {}, &trace, &inputs_m31); + + /*let prove_with_periodic_columns = prove_with_periodic_columns(&config, &BitwiseAir {}, trace, &inputs_m31); + verify_with_periodic_columns(&config, &BitwiseAir {}, &prove_with_periodic_columns, &inputs_m31).expect("Verification failed");*/ + + /*let proof = prove(&config, &BitwiseAir {}, trace, &inputs_m31); + verify(&config, &BitwiseAir {}, &proof, &inputs_m31).expect("Verification failed");*/ +} diff --git a/air-script/tests/bitwise/test_air.rs b/air-script/tests/bitwise/test_air_winterfell.rs similarity index 100% rename from air-script/tests/bitwise/test_air.rs rename to air-script/tests/bitwise/test_air_winterfell.rs diff --git a/air-script/tests/helpers/mod.rs b/air-script/tests/helpers/mod.rs index 5f91493d8..e9760c6d8 100644 --- a/air-script/tests/helpers/mod.rs +++ b/air-script/tests/helpers/mod.rs @@ -1,73 +1,5 @@ -use winter_air::{BatchingMethod, EvaluationFrame, FieldExtension, ProofOptions, TraceInfo}; -use winter_math::fields::f64::BaseElement as Felt; -use winterfell::{AuxTraceWithMetadata, Trace, TraceTable, matrix::ColMatrix}; +mod plonky3_periodic_columns; +mod winterfell_test_helpers; -/// We need to encapsulate the trace table in a struct to manually implement the `aux_trace_width` -/// method of the `Table` trait. Otherwise, using only a TraceTable will return an -/// `aux_trace_width` of 0 even if we provide a non-empty aux trace in `Trace::validate`, -/// and it fails the tests. -pub struct MyTraceTable { - pub trace: TraceTable, - pub aux_width: usize, -} - -impl MyTraceTable { - pub fn new(trace: TraceTable, aux_width: usize) -> Self { - Self { trace, aux_width } - } -} - -impl Trace for MyTraceTable { - type BaseField = Felt; - - fn info(&self) -> &TraceInfo { - self.trace.info() - } - - fn main_segment(&self) -> &ColMatrix { - self.trace.main_segment() - } - - fn read_main_frame(&self, row_idx: usize, frame: &mut EvaluationFrame) { - self.trace.read_main_frame(row_idx, frame); - } - - fn aux_trace_width(&self) -> usize { - self.aux_width - } -} - -pub trait AirTester { - type PubInputs; - - fn build_main_trace(&self, length: usize) -> MyTraceTable; - fn public_inputs(&self) -> Self::PubInputs; - fn build_aux_trace(&self, _length: usize) -> Option> { - None - } - fn build_trace_info(&self, length: usize) -> TraceInfo { - match &self.build_aux_trace(length) { - None => TraceInfo::new(self.build_main_trace(length).trace.width(), length), - Some(aux_trace) => TraceInfo::new_multi_segment( - self.build_main_trace(length).trace.width(), - aux_trace.aux_trace.num_cols(), - aux_trace.aux_rand_elements.rand_elements().len(), - length, - vec![], - ), - } - } - fn build_proof_options(&self) -> ProofOptions { - ProofOptions::new( - 32, // number of queries - 8, // blowup factor - 0, // grinding factor - FieldExtension::None, - 8, // FRI folding factor - 31, // FRI max remainder polynomial degree - BatchingMethod::Linear, /* method of batching used in computing constraint - * composition polynomial */ - BatchingMethod::Linear, // method of batching used in computing DEEP polynomial - ) - } -} +pub use plonky3_periodic_columns::*; +pub use winterfell_test_helpers::*; diff --git a/air-script/tests/helpers/plonky3_periodic_columns.rs b/air-script/tests/helpers/plonky3_periodic_columns.rs new file mode 100644 index 000000000..245a8d037 --- /dev/null +++ b/air-script/tests/helpers/plonky3_periodic_columns.rs @@ -0,0 +1,146 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir}; +use p3_field::Field; +use p3_matrix::{ + Matrix, + dense::{RowMajorMatrix, RowMajorMatrixView}, + stack::VerticalPair, +}; + +pub trait BaseAirWithPeriodicColumns: BaseAir { + fn get_periodic_columns(&self) -> Vec> { + vec![] + } +} + +pub trait AirBuilderWithPeriodicColumns: AirBuilder { + type PeriodicColumnsVar: Field + Into; + + fn periodic_columns(&self) -> Vec { + vec![] + } +} + +pub(crate) fn check_constraints_with_periodic_columns( + air: &A, + main: &RowMajorMatrix, + public_values: &Vec, +) where + F: Field, + A: for<'a> Air> + + BaseAirWithPeriodicColumns, +{ + let height = main.height(); + + (0..height).for_each(|i| { + let i_next = (i + 1) % height; + + let local = main.row_slice(i).unwrap(); // i < height so unwrap should never fail. + let next = main.row_slice(i_next).unwrap(); // i_next < height so unwrap should never fail. + let main = VerticalPair::new( + RowMajorMatrixView::new_row(&*local), + RowMajorMatrixView::new_row(&*next), + ); + let periodic_columns = air.get_periodic_columns(); + + let mut builder = DebugConstraintBuilderWithPeriodicColumns { + row_index: i, + main, + public_values, + is_first_row: F::from_bool(i == 0), + is_last_row: F::from_bool(i == height - 1), + is_transition: F::from_bool(i != height - 1), + periodic_columns, + }; + + air.eval(&mut builder); + }); +} + +/// A builder that runs constraint assertions during testing. +/// +/// Used in conjunction with [`check_constraints`] to simulate +/// an execution trace and verify that the AIR logic enforces all constraints. +#[derive(Debug)] +pub struct DebugConstraintBuilderWithPeriodicColumns<'a, F: Field> { + /// The index of the row currently being evaluated. + row_index: usize, + /// A view of the current and next row as a vertical pair. + main: VerticalPair, RowMajorMatrixView<'a, F>>, + /// The public values provided for constraint validation (e.g. inputs or outputs). + public_values: &'a [F], + /// A flag indicating whether this is the first row. + is_first_row: F, + /// A flag indicating whether this is the last row. + is_last_row: F, + /// A flag indicating whether this is a transition row (not the last row). + is_transition: F, + /// The periodic columns provided for constraint validation. + periodic_columns: Vec>, +} + +impl<'a, F> AirBuilderWithPeriodicColumns for DebugConstraintBuilderWithPeriodicColumns<'a, F> +where + F: Field + Into, +{ + type PeriodicColumnsVar = F; + + fn periodic_columns(&self) -> Vec { + self.periodic_columns + .iter() + .map(|col| col[self.row_index % col.len()]) + .collect::>() + } +} + +impl<'a, F> AirBuilder for DebugConstraintBuilderWithPeriodicColumns<'a, F> +where + F: Field, +{ + type F = F; + type Expr = F; + type Var = F; + type M = VerticalPair, RowMajorMatrixView<'a, F>>; + + fn main(&self) -> Self::M { + self.main + } + + fn is_first_row(&self) -> Self::Expr { + self.is_first_row + } + + fn is_last_row(&self) -> Self::Expr { + self.is_last_row + } + + /// # Panics + /// This function panics if `size` is not `2`. + fn is_transition_window(&self, size: usize) -> Self::Expr { + if size == 2 { + self.is_transition + } else { + panic!("only supports a window size of 2") + } + } + + fn assert_zero>(&mut self, x: I) { + assert_eq!(x.into(), F::ZERO, "constraints had nonzero value on row {}", self.row_index); + } + + fn assert_eq, I2: Into>(&mut self, x: I1, y: I2) { + let x = x.into(); + let y = y.into(); + assert_eq!(x, y, "values didn't match on row {}: {} != {}", self.row_index, x, y); + } +} + +impl<'a, F> AirBuilderWithPublicValues for DebugConstraintBuilderWithPeriodicColumns<'a, F> +where + F: Field, +{ + type PublicVar = Self::F; + + fn public_values(&self) -> &[Self::F] { + self.public_values + } +} diff --git a/air-script/tests/helpers/winterfell_test_helpers.rs b/air-script/tests/helpers/winterfell_test_helpers.rs new file mode 100644 index 000000000..5f91493d8 --- /dev/null +++ b/air-script/tests/helpers/winterfell_test_helpers.rs @@ -0,0 +1,73 @@ +use winter_air::{BatchingMethod, EvaluationFrame, FieldExtension, ProofOptions, TraceInfo}; +use winter_math::fields::f64::BaseElement as Felt; +use winterfell::{AuxTraceWithMetadata, Trace, TraceTable, matrix::ColMatrix}; + +/// We need to encapsulate the trace table in a struct to manually implement the `aux_trace_width` +/// method of the `Table` trait. Otherwise, using only a TraceTable will return an +/// `aux_trace_width` of 0 even if we provide a non-empty aux trace in `Trace::validate`, +/// and it fails the tests. +pub struct MyTraceTable { + pub trace: TraceTable, + pub aux_width: usize, +} + +impl MyTraceTable { + pub fn new(trace: TraceTable, aux_width: usize) -> Self { + Self { trace, aux_width } + } +} + +impl Trace for MyTraceTable { + type BaseField = Felt; + + fn info(&self) -> &TraceInfo { + self.trace.info() + } + + fn main_segment(&self) -> &ColMatrix { + self.trace.main_segment() + } + + fn read_main_frame(&self, row_idx: usize, frame: &mut EvaluationFrame) { + self.trace.read_main_frame(row_idx, frame); + } + + fn aux_trace_width(&self) -> usize { + self.aux_width + } +} + +pub trait AirTester { + type PubInputs; + + fn build_main_trace(&self, length: usize) -> MyTraceTable; + fn public_inputs(&self) -> Self::PubInputs; + fn build_aux_trace(&self, _length: usize) -> Option> { + None + } + fn build_trace_info(&self, length: usize) -> TraceInfo { + match &self.build_aux_trace(length) { + None => TraceInfo::new(self.build_main_trace(length).trace.width(), length), + Some(aux_trace) => TraceInfo::new_multi_segment( + self.build_main_trace(length).trace.width(), + aux_trace.aux_trace.num_cols(), + aux_trace.aux_rand_elements.rand_elements().len(), + length, + vec![], + ), + } + } + fn build_proof_options(&self) -> ProofOptions { + ProofOptions::new( + 32, // number of queries + 8, // blowup factor + 0, // grinding factor + FieldExtension::None, + 8, // FRI folding factor + 31, // FRI max remainder polynomial degree + BatchingMethod::Linear, /* method of batching used in computing constraint + * composition polynomial */ + BatchingMethod::Linear, // method of batching used in computing DEEP polynomial + ) + } +} diff --git a/codegen/plonky3/src/air/boundary_constraints.rs b/codegen/plonky3/src/air/boundary_constraints.rs index 19a3519d1..5ae7d1363 100644 --- a/codegen/plonky3/src/air/boundary_constraints.rs +++ b/codegen/plonky3/src/air/boundary_constraints.rs @@ -8,7 +8,7 @@ pub(super) fn add_main_boundary_constraints(eval_func: &mut Function, ir: &Air) for constraint in ir.boundary_constraints(TraceSegmentId::Main) { let expr_root = constraint.node_index(); - let expr_root_string = expr_root.to_string(ir, TraceSegmentId::Main); + let expr_root_string = expr_root.to_string(ir); let assertion = format!("builder.when_first_row().assert_zero::<_>({expr_root_string});"); diff --git a/codegen/plonky3/src/air/graph.rs b/codegen/plonky3/src/air/graph.rs index 3f987b7d3..56d5a90cf 100644 --- a/codegen/plonky3/src/air/graph.rs +++ b/codegen/plonky3/src/air/graph.rs @@ -1,4 +1,4 @@ -use air_ir::{Air, NodeIndex, Operation, TraceAccess, TraceSegmentId, Value}; +use air_ir::{Air, NodeIndex, Operation, TraceAccess, Value}; // RUST STRING GENERATION FOR THE CONSTRAINT GRAPH // ================================================================================================ @@ -6,11 +6,11 @@ use air_ir::{Air, NodeIndex, Operation, TraceAccess, TraceSegmentId, Value}; /// Code generation trait for generating Rust code strings from IR types related to constraints and /// the [AlgebraicGraph]. pub trait Codegen { - fn to_string(&self, ir: &Air, trace_segment: TraceSegmentId) -> String; + fn to_string(&self, ir: &Air) -> String; } impl Codegen for TraceAccess { - fn to_string(&self, _ir: &Air, trace_segment: TraceSegmentId) -> String { + fn to_string(&self, _ir: &Air) -> String { let frame = self.segment.to_string(); let row_offset = match self.row_offset { 0 => { @@ -21,37 +21,33 @@ impl Codegen for TraceAccess { }, _ => panic!("Plonky3 doesn't support row offsets greater than 1."), }; - if self.segment == TraceSegmentId::Main && self.segment != trace_segment { - format!("E::from({frame}_{row_offset})") - } else { - format!("{frame}_{row_offset}") - } + format!("{frame}_{row_offset}") } } impl Codegen for NodeIndex { - fn to_string(&self, ir: &Air, trace_segment: TraceSegmentId) -> String { + fn to_string(&self, ir: &Air) -> String { let op = ir.constraint_graph().node(self).op(); - op.to_string(ir, trace_segment) + op.to_string(ir) } } impl Codegen for Operation { - fn to_string(&self, ir: &Air, trace_segment: TraceSegmentId) -> String { + fn to_string(&self, ir: &Air) -> String { match self { - Operation::Value(value) => value.to_string(ir, trace_segment), - Operation::Add(..) => binary_op_to_string(ir, self, trace_segment), - Operation::Sub(..) => binary_op_to_string(ir, self, trace_segment), - Operation::Mul(..) => binary_op_to_string(ir, self, trace_segment), + Operation::Value(value) => value.to_string(ir), + Operation::Add(..) => binary_op_to_string(ir, self), + Operation::Sub(..) => binary_op_to_string(ir, self), + Operation::Mul(..) => binary_op_to_string(ir, self), } } } impl Codegen for Value { - fn to_string(&self, ir: &Air, trace_segment: TraceSegmentId) -> String { + fn to_string(&self, ir: &Air) -> String { match self { Value::Constant(value) => format!("AB::Expr::from(AB::F::from_u64({value}))"), - Value::TraceAccess(trace_access) => trace_access.to_string(ir, trace_segment), + Value::TraceAccess(trace_access) => trace_access.to_string(ir), Value::PublicInput(air_ir::PublicInputAccess { name, index }) => { let get_public_input_offset = |name: &str| { ir.public_inputs() @@ -61,13 +57,13 @@ impl Codegen for Value { }; format!("public_values[{}].into()", get_public_input_offset(name.as_str()) + index) }, - _ => todo!(), - /*Value::PeriodicColumn(pc) => { + Value::PeriodicColumn(pc) => { let index = ir.periodic_columns.iter().position(|(qid, _)| qid == &pc.name).unwrap(); - format!("periodic_values[{index}]") + format!("periodic_values[{index}].into()") }, - Value::PublicInputTable(air_ir::PublicInputTableAccess { + _ => todo!(), + /*Value::PublicInputTable(air_ir::PublicInputTableAccess { table_name, bus_type, num_cols: _, @@ -82,32 +78,32 @@ impl Codegen for Value { } /// Returns a string representation of a binary operation. -fn binary_op_to_string(ir: &Air, op: &Operation, trace_segment: TraceSegmentId) -> String { +fn binary_op_to_string(ir: &Air, op: &Operation) -> String { match op { Operation::Add(l_idx, r_idx) => { - let lhs = l_idx.to_string(ir, trace_segment); - let rhs = r_idx.to_string(ir, trace_segment); + let lhs = l_idx.to_string(ir); + let rhs = r_idx.to_string(ir); format!("{lhs} + {rhs}") }, Operation::Sub(l_idx, r_idx) => { - let lhs = l_idx.to_string(ir, trace_segment); + let lhs = l_idx.to_string(ir); let rhs = if ir.constraint_graph().node(r_idx).op().precedence() <= op.precedence() { - format!("({})", r_idx.to_string(ir, trace_segment)) + format!("({})", r_idx.to_string(ir)) } else { - r_idx.to_string(ir, trace_segment) + r_idx.to_string(ir) }; format!("{lhs} - {rhs}") }, Operation::Mul(l_idx, r_idx) => { let lhs = if ir.constraint_graph().node(l_idx).op().precedence() < op.precedence() { - format!("({})", l_idx.to_string(ir, trace_segment)) + format!("({})", l_idx.to_string(ir)) } else { - l_idx.to_string(ir, trace_segment) + l_idx.to_string(ir) }; let rhs = if ir.constraint_graph().node(r_idx).op().precedence() < op.precedence() { - format!("({})", r_idx.to_string(ir, trace_segment)) + format!("({})", r_idx.to_string(ir)) } else { - r_idx.to_string(ir, trace_segment) + r_idx.to_string(ir) }; format!("{lhs} * {rhs}") }, diff --git a/codegen/plonky3/src/air/integrity_constraints.rs b/codegen/plonky3/src/air/integrity_constraints.rs index 78dae2d55..0d79dfcf0 100644 --- a/codegen/plonky3/src/air/integrity_constraints.rs +++ b/codegen/plonky3/src/air/integrity_constraints.rs @@ -7,7 +7,7 @@ use super::Codegen; pub(super) fn add_main_integrity_constraints(eval_func: &mut Function, ir: &Air) { for constraint in ir.integrity_constraints(TraceSegmentId::Main) { let expr_root = constraint.node_index(); - let expr_root_string = expr_root.to_string(ir, TraceSegmentId::Main); + let expr_root_string = expr_root.to_string(ir); // If the constraint is a transition constraint (depends on the next row), we do not // evaluate it in the last row, with the `when_transition` method. diff --git a/codegen/plonky3/src/air/mod.rs b/codegen/plonky3/src/air/mod.rs index 79c533a73..a11287f87 100644 --- a/codegen/plonky3/src/air/mod.rs +++ b/codegen/plonky3/src/air/mod.rs @@ -49,6 +49,27 @@ fn add_air_struct(scope: &mut Scope, ir: &Air, name: &str) { .arg_ref_self() .ret("usize") .line("NUM_PUBLIC_VALUES"); + + // add the custom BaseAirWithPeriodicColumns implementation block + let base_air_with_periodic_columns_impl = scope + .new_impl(name) + .generic("F: PrimeCharacteristicRing") + .impl_trait("BaseAirWithPeriodicColumns"); + let base_air_with_periodic_columns_impl_func = base_air_with_periodic_columns_impl + .new_fn("get_periodic_columns") + .arg_ref_self() + .ret("Vec>"); + base_air_with_periodic_columns_impl_func.line("vec!["); + + for col in ir.periodic_columns() { + let values_str = col.values + .iter() + .map(|v| format!("F::from_u64({v})")) // or use a custom formatter if needed + .collect::>() + .join(", "); + base_air_with_periodic_columns_impl_func.line(format!(" vec![{values_str}],")); + } + base_air_with_periodic_columns_impl_func.line("]"); } /// Updates the provided scope with the custom Air struct and an Air trait implementation based on @@ -57,12 +78,13 @@ fn add_air_trait(scope: &mut Scope, ir: &Air, name: &str) { // add the implementation block for the Air trait. let air_impl = scope .new_impl(name) - .generic("AB: AirBuilderWithPublicValues") + .generic("AB: AirBuilderWithPublicValues + AirBuilderWithPeriodicColumns") .impl_trait("Air"); let eval_func = air_impl.new_fn("eval").arg_ref_self().arg("builder", "&mut AB"); eval_func.line("let main = builder.main();"); eval_func.line("let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect(\"Wrong number of public values\");"); + eval_func.line("let periodic_values = builder.periodic_columns();"); eval_func.line("let (main_current, main_next) = ("); eval_func.line(" main.row_slice(0).unwrap(),"); eval_func.line(" main.row_slice(1).unwrap(),"); diff --git a/codegen/plonky3/src/imports.rs b/codegen/plonky3/src/imports.rs index 7663096bb..28ef3501b 100644 --- a/codegen/plonky3/src/imports.rs +++ b/codegen/plonky3/src/imports.rs @@ -10,4 +10,6 @@ pub(super) fn add_imports(scope: &mut Scope) { scope.import("p3_air", "BaseAirWithPublicValues"); scope.import("p3_matrix", "Matrix"); scope.import("p3_field", "PrimeCharacteristicRing"); + scope.import("crate::helpers", "AirBuilderWithPeriodicColumns"); + scope.import("crate::helpers", "BaseAirWithPeriodicColumns"); } From 6c7c7772cc0aba564cbbeadb018d49e17daffda3 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Wed, 24 Sep 2025 13:45:05 +0200 Subject: [PATCH 10/25] fix(codegen): Correctly handle boundary constraints domain --- codegen/plonky3/src/air/boundary_constraints.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/codegen/plonky3/src/air/boundary_constraints.rs b/codegen/plonky3/src/air/boundary_constraints.rs index 5ae7d1363..4c8fd0047 100644 --- a/codegen/plonky3/src/air/boundary_constraints.rs +++ b/codegen/plonky3/src/air/boundary_constraints.rs @@ -10,8 +10,15 @@ pub(super) fn add_main_boundary_constraints(eval_func: &mut Function, ir: &Air) let expr_root_string = expr_root.to_string(ir); - let assertion = format!("builder.when_first_row().assert_zero::<_>({expr_root_string});"); - + let assertion = match constraint.domain() { + air_ir::ConstraintDomain::FirstRow => { + format!("builder.when_first_row().assert_zero::<_>({expr_root_string});") + }, + air_ir::ConstraintDomain::LastRow => { + format!("builder.when_last_row().assert_zero::<_>({expr_root_string});") + }, + _ => unreachable!("Boundary constraints can only be applied to the first or last row"), + }; eval_func.line(assertion); } } From 96e741c8f4e3c6fcfb4f9ac2039fefb2754ec1ae Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Wed, 24 Sep 2025 13:45:29 +0200 Subject: [PATCH 11/25] tests: generate and test all E2E Plonky3 tests --- air-script/tests/binary/mod.rs | 6 +- .../tests/buses/buses_complex_plonky3.rs | 44 +++ .../tests/buses/buses_simple_plonky3.rs | 41 +++ .../buses_varlen_boundary_both_plonky3.rs | 41 +++ .../buses_varlen_boundary_first_plonky3.rs | 41 +++ .../buses_varlen_boundary_last_plonky3.rs | 41 +++ air-script/tests/buses/mod.rs | 25 +- air-script/tests/buses/test_air_plonky3.rs | 84 +++++ .../{test_air.rs => test_air_winterfell.rs} | 0 air-script/tests/codegen/plonky3.rs | 289 +++++++++++++++++- air-script/tests/codegen/winterfell.rs | 3 - .../constant_in_range_plonky3.rs | 43 +++ air-script/tests/constant_in_range/mod.rs | 8 +- .../constant_in_range/test_air_plonky3.rs | 103 +++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 .../tests/constants/constants_plonky3.rs | 52 ++++ air-script/tests/constants/mod.rs | 8 +- .../tests/constants/test_air_plonky3.rs | 99 ++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 .../constraint_comprehension_plonky3.rs | 46 +++ .../tests/constraint_comprehension/mod.rs | 8 +- .../test_air_plonky3.rs | 86 ++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 .../tests/evaluators/evaluators_plonky3.rs | 52 ++++ air-script/tests/evaluators/mod.rs | 8 +- .../tests/evaluators/test_air_plonky3.rs | 99 ++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 .../tests/fibonacci/fibonacci_plonky3.rs | 46 +++ air-script/tests/fibonacci/mod.rs | 8 +- .../tests/fibonacci/test_air_plonky3.rs | 87 ++++++ .../{test_air.rs => test_air_winterfell.rs} | 2 +- .../functions/functions_complex_plonky3.rs | 44 +++ .../functions/functions_simple_plonky3.rs | 50 +++ air-script/tests/functions/mod.rs | 12 +- .../tests/functions/test_air_plonky3.rs | 129 ++++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 .../indexed_trace_access_plonky3.rs | 43 +++ air-script/tests/indexed_trace_access/mod.rs | 8 +- .../indexed_trace_access/test_air_plonky3.rs | 86 ++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 .../list_comprehension_nested_plonky3.rs | 45 +++ .../list_comprehension_plonky3.rs | 48 +++ air-script/tests/list_comprehension/mod.rs | 8 +- .../list_comprehension/test_air_plonky3.rs | 126 ++++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 .../list_folding/list_folding_plonky3.rs | 46 +++ air-script/tests/list_folding/mod.rs | 8 +- .../tests/list_folding/test_air_plonky3.rs | 129 ++++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 air-script/tests/periodic_columns/mod.rs | 8 +- .../periodic_columns_plonky3.rs | 46 +++ .../periodic_columns/test_air_plonky3.rs | 87 ++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 air-script/tests/pub_inputs/mod.rs | 8 +- .../tests/pub_inputs/pub_inputs_plonky3.rs | 50 +++ .../tests/pub_inputs/test_air_plonky3.rs | 90 ++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 air-script/tests/selectors/mod.rs | 16 +- .../selectors_combine_complex_plonky3.rs | 45 +++ .../selectors_combine_simple_plonky3.rs | 44 +++ .../tests/selectors/selectors_plonky3.rs | 44 +++ .../selectors_with_evaluators_plonky3.rs | 44 +++ .../tests/selectors/test_air_plonky3.rs | 90 ++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 air-script/tests/system/mod.rs | 8 +- air-script/tests/system/system_plonky3.rs | 43 +++ air-script/tests/system/test_air_plonky3.rs | 87 ++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 air-script/tests/trace_col_groups/mod.rs | 8 +- .../trace_col_groups/test_air_plonky3.rs | 105 +++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 .../trace_col_groups_plonky3.rs | 44 +++ air-script/tests/variables/mod.rs | 7 +- .../tests/variables/test_air_plonky3.rs | 90 ++++++ .../{test_air.rs => test_air_winterfell.rs} | 0 .../tests/variables/variables_plonky3.rs | 48 +++ 76 files changed, 3140 insertions(+), 24 deletions(-) create mode 100644 air-script/tests/buses/buses_complex_plonky3.rs create mode 100644 air-script/tests/buses/buses_simple_plonky3.rs create mode 100644 air-script/tests/buses/buses_varlen_boundary_both_plonky3.rs create mode 100644 air-script/tests/buses/buses_varlen_boundary_first_plonky3.rs create mode 100644 air-script/tests/buses/buses_varlen_boundary_last_plonky3.rs create mode 100644 air-script/tests/buses/test_air_plonky3.rs rename air-script/tests/buses/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/constant_in_range/constant_in_range_plonky3.rs create mode 100644 air-script/tests/constant_in_range/test_air_plonky3.rs rename air-script/tests/constant_in_range/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/constants/constants_plonky3.rs create mode 100644 air-script/tests/constants/test_air_plonky3.rs rename air-script/tests/constants/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/constraint_comprehension/constraint_comprehension_plonky3.rs create mode 100644 air-script/tests/constraint_comprehension/test_air_plonky3.rs rename air-script/tests/constraint_comprehension/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/evaluators/evaluators_plonky3.rs create mode 100644 air-script/tests/evaluators/test_air_plonky3.rs rename air-script/tests/evaluators/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/fibonacci/fibonacci_plonky3.rs create mode 100644 air-script/tests/fibonacci/test_air_plonky3.rs rename air-script/tests/fibonacci/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/functions/functions_complex_plonky3.rs create mode 100644 air-script/tests/functions/functions_simple_plonky3.rs create mode 100644 air-script/tests/functions/test_air_plonky3.rs rename air-script/tests/functions/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/indexed_trace_access/indexed_trace_access_plonky3.rs create mode 100644 air-script/tests/indexed_trace_access/test_air_plonky3.rs rename air-script/tests/indexed_trace_access/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/list_comprehension/list_comprehension_nested_plonky3.rs create mode 100644 air-script/tests/list_comprehension/list_comprehension_plonky3.rs create mode 100644 air-script/tests/list_comprehension/test_air_plonky3.rs rename air-script/tests/list_comprehension/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/list_folding/list_folding_plonky3.rs create mode 100644 air-script/tests/list_folding/test_air_plonky3.rs rename air-script/tests/list_folding/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/periodic_columns/periodic_columns_plonky3.rs create mode 100644 air-script/tests/periodic_columns/test_air_plonky3.rs rename air-script/tests/periodic_columns/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/pub_inputs/pub_inputs_plonky3.rs create mode 100644 air-script/tests/pub_inputs/test_air_plonky3.rs rename air-script/tests/pub_inputs/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/selectors/selectors_combine_complex_plonky3.rs create mode 100644 air-script/tests/selectors/selectors_combine_simple_plonky3.rs create mode 100644 air-script/tests/selectors/selectors_plonky3.rs create mode 100644 air-script/tests/selectors/selectors_with_evaluators_plonky3.rs create mode 100644 air-script/tests/selectors/test_air_plonky3.rs rename air-script/tests/selectors/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/system/system_plonky3.rs create mode 100644 air-script/tests/system/test_air_plonky3.rs rename air-script/tests/system/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/trace_col_groups/test_air_plonky3.rs rename air-script/tests/trace_col_groups/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/trace_col_groups/trace_col_groups_plonky3.rs create mode 100644 air-script/tests/variables/test_air_plonky3.rs rename air-script/tests/variables/{test_air.rs => test_air_winterfell.rs} (100%) create mode 100644 air-script/tests/variables/variables_plonky3.rs diff --git a/air-script/tests/binary/mod.rs b/air-script/tests/binary/mod.rs index fa03709f2..08cbf3225 100644 --- a/air-script/tests/binary/mod.rs +++ b/air-script/tests/binary/mod.rs @@ -1,10 +1,10 @@ #[rustfmt::skip] #[allow(clippy::all)] mod binary; -mod test_air_winterfell; - -mod test_air_plonky3; #[rustfmt::skip] #[allow(clippy::all)] #[allow(unused_imports)] mod binary_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/buses/buses_complex_plonky3.rs b/air-script/tests/buses/buses_complex_plonky3.rs new file mode 100644 index 000000000..76905b3a8 --- /dev/null +++ b/air-script/tests/buses/buses_complex_plonky3.rs @@ -0,0 +1,44 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 5; + +pub const NUM_PUBLIC_VALUES: usize = 2; + +pub struct BusesAir; + +impl BaseAir for BusesAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for BusesAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for BusesAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for BusesAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[0]); + builder.assert_zero::<_>(main_current[2] * main_current[2] - main_current[2]); + builder.assert_zero::<_>(main_current[3] * main_current[3] - main_current[3]); + } +} \ No newline at end of file diff --git a/air-script/tests/buses/buses_simple_plonky3.rs b/air-script/tests/buses/buses_simple_plonky3.rs new file mode 100644 index 000000000..6ea46ea4b --- /dev/null +++ b/air-script/tests/buses/buses_simple_plonky3.rs @@ -0,0 +1,41 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 1; + +pub const NUM_PUBLIC_VALUES: usize = 2; + +pub struct BusesAir; + +impl BaseAir for BusesAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for BusesAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for BusesAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for BusesAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + } +} \ No newline at end of file diff --git a/air-script/tests/buses/buses_varlen_boundary_both_plonky3.rs b/air-script/tests/buses/buses_varlen_boundary_both_plonky3.rs new file mode 100644 index 000000000..e8f0c1253 --- /dev/null +++ b/air-script/tests/buses/buses_varlen_boundary_both_plonky3.rs @@ -0,0 +1,41 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 1; + +pub const NUM_PUBLIC_VALUES: usize = 6; + +pub struct BusesAir; + +impl BaseAir for BusesAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for BusesAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for BusesAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for BusesAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + } +} \ No newline at end of file diff --git a/air-script/tests/buses/buses_varlen_boundary_first_plonky3.rs b/air-script/tests/buses/buses_varlen_boundary_first_plonky3.rs new file mode 100644 index 000000000..6ea46ea4b --- /dev/null +++ b/air-script/tests/buses/buses_varlen_boundary_first_plonky3.rs @@ -0,0 +1,41 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 1; + +pub const NUM_PUBLIC_VALUES: usize = 2; + +pub struct BusesAir; + +impl BaseAir for BusesAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for BusesAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for BusesAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for BusesAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + } +} \ No newline at end of file diff --git a/air-script/tests/buses/buses_varlen_boundary_last_plonky3.rs b/air-script/tests/buses/buses_varlen_boundary_last_plonky3.rs new file mode 100644 index 000000000..6ea46ea4b --- /dev/null +++ b/air-script/tests/buses/buses_varlen_boundary_last_plonky3.rs @@ -0,0 +1,41 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 1; + +pub const NUM_PUBLIC_VALUES: usize = 2; + +pub struct BusesAir; + +impl BaseAir for BusesAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for BusesAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for BusesAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for BusesAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + } +} \ No newline at end of file diff --git a/air-script/tests/buses/mod.rs b/air-script/tests/buses/mod.rs index 933d13ee5..95eeeb07b 100644 --- a/air-script/tests/buses/mod.rs +++ b/air-script/tests/buses/mod.rs @@ -13,4 +13,27 @@ mod buses_varlen_boundary_first; #[rustfmt::skip] #[allow(clippy::all)] mod buses_varlen_boundary_last; -mod test_air; + +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod buses_complex_plonky3; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod buses_simple_plonky3; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod buses_varlen_boundary_both_plonky3; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod buses_varlen_boundary_first_plonky3; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod buses_varlen_boundary_last_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/buses/test_air_plonky3.rs b/air-script/tests/buses/test_air_plonky3.rs new file mode 100644 index 000000000..e465396df --- /dev/null +++ b/air-script/tests/buses/test_air_plonky3.rs @@ -0,0 +1,84 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + buses::buses_complex_plonky3::{BusesAir, NUM_COLUMNS}, + helpers::check_constraints_with_periodic_columns, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let a_prev = rows[i - 1][0]; + let b_prev = rows[i - 1][1]; + + // Update current row based on previous values + rows[i][0] = F::ONE - a_prev; + rows[i][1] = F::ONE - b_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 2]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&BusesAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/buses/test_air.rs b/air-script/tests/buses/test_air_winterfell.rs similarity index 100% rename from air-script/tests/buses/test_air.rs rename to air-script/tests/buses/test_air_winterfell.rs diff --git a/air-script/tests/codegen/plonky3.rs b/air-script/tests/codegen/plonky3.rs index 1c946a90f..bb7b3a24c 100644 --- a/air-script/tests/codegen/plonky3.rs +++ b/air-script/tests/codegen/plonky3.rs @@ -12,4 +12,291 @@ fn binary() { expected.assert_eq(&generated_air); } -// TODO: add all tests +#[test] +fn buses_simple() { + let generated_air = Test::new("tests/buses/buses_simple.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../buses/buses_simple_plonky3.rs"]; + expected.assert_eq(&generated_air); +} +#[test] +fn buses_simple_with_evaluators() { + let generated_air = Test::new("tests/buses/buses_simple_with_evaluators.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../buses/buses_simple_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_complex() { + let generated_air = Test::new("tests/buses/buses_complex.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../buses/buses_complex_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_varlen_boundary_first() { + let generated_air = Test::new("tests/buses/buses_varlen_boundary_first.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../buses/buses_varlen_boundary_first_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_varlen_boundary_last() { + let generated_air = Test::new("tests/buses/buses_varlen_boundary_last.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../buses/buses_varlen_boundary_last_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_varlen_boundary_both() { + let generated_air = Test::new("tests/buses/buses_varlen_boundary_both.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../buses/buses_varlen_boundary_both_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn periodic_columns() { + let generated_air = Test::new("tests/periodic_columns/periodic_columns.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../periodic_columns/periodic_columns_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn pub_inputs() { + let generated_air = Test::new("tests/pub_inputs/pub_inputs.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../pub_inputs/pub_inputs_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn system() { + let generated_air = Test::new("tests/system/system.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../system/system_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn bitwise() { + let generated_air = Test::new("tests/bitwise/bitwise.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../bitwise/bitwise_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn constants() { + let generated_air = Test::new("tests/constants/constants.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../constants/constants_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn constant_in_range() { + let generated_air = Test::new("tests/constant_in_range/constant_in_range.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../constant_in_range/constant_in_range_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn evaluators() { + let generated_air = Test::new("tests/evaluators/evaluators.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../evaluators/evaluators_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn fibonacci() { + let generated_air = Test::new("tests/fibonacci/fibonacci.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../fibonacci/fibonacci_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn functions_simple() { + let generated_air = Test::new("tests/functions/functions_simple.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../functions/functions_simple_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn functions_simple_inlined() { + // make sure that the constraints generated using inlined functions are the same as the ones + // generated using regular functions + let generated_air = Test::new("tests/functions/inlined_functions_simple.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../functions/functions_simple_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn functions_complex() { + let generated_air = Test::new("tests/functions/functions_complex.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../functions/functions_complex_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn variables() { + let generated_air = Test::new("tests/variables/variables.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../variables/variables_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn trace_col_groups() { + let generated_air = Test::new("tests/trace_col_groups/trace_col_groups.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../trace_col_groups/trace_col_groups_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn indexed_trace_access() { + let generated_air = + Test::new("tests/indexed_trace_access/indexed_trace_access.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../indexed_trace_access/indexed_trace_access_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn list_comprehension() { + let generated_air = Test::new("tests/list_comprehension/list_comprehension.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../list_comprehension/list_comprehension_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn list_comprehension_nested() { + let generated_air = + Test::new("tests/list_comprehension/list_comprehension_nested.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../list_comprehension/list_comprehension_nested_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn list_folding() { + let generated_air = Test::new("tests/list_folding/list_folding.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../list_folding/list_folding_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn selectors() { + let generated_air = Test::new("tests/selectors/selectors.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../selectors/selectors_plonky3.rs"]; + expected.assert_eq(&generated_air); + + let generated_air = Test::new("tests/selectors/selectors_with_evaluators.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../selectors/selectors_with_evaluators_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn selectors_combine_simple() { + let generated_air = Test::new("tests/selectors/selectors_combine_simple.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../selectors/selectors_combine_simple_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn selectors_combine_complex() { + let generated_air = Test::new("tests/selectors/selectors_combine_complex.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../selectors/selectors_combine_complex_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn constraint_comprehension() { + let generated_air = + Test::new("tests/constraint_comprehension/constraint_comprehension.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../constraint_comprehension/constraint_comprehension_plonky3.rs"]; + expected.assert_eq(&generated_air); + + let generated_air = + Test::new("tests/constraint_comprehension/cc_with_evaluators.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../constraint_comprehension/constraint_comprehension_plonky3.rs"]; + expected.assert_eq(&generated_air); +} diff --git a/air-script/tests/codegen/winterfell.rs b/air-script/tests/codegen/winterfell.rs index 1b2348274..aa3f71086 100644 --- a/air-script/tests/codegen/winterfell.rs +++ b/air-script/tests/codegen/winterfell.rs @@ -2,9 +2,6 @@ use expect_test::expect_file; use super::helpers::{Target, Test}; -// tests_wo_mir -// ================================================================================================ - #[test] fn binary() { let generated_air = Test::new("tests/binary/binary.air".to_string()) diff --git a/air-script/tests/constant_in_range/constant_in_range_plonky3.rs b/air-script/tests/constant_in_range/constant_in_range_plonky3.rs new file mode 100644 index 000000000..6b23d4b17 --- /dev/null +++ b/air-script/tests/constant_in_range/constant_in_range_plonky3.rs @@ -0,0 +1,43 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 12; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct ConstantInRangeAir; + +impl BaseAir for ConstantInRangeAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for ConstantInRangeAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for ConstantInRangeAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for ConstantInRangeAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[6]); + builder.assert_zero::<_>(main_current[0] - (main_current[1] - main_current[4] - main_current[8] + AB::Expr::from(AB::F::from_u64(1)) + main_current[2] - main_current[5] - main_current[9] + AB::Expr::from(AB::F::from_u64(2)) + main_current[3] - main_current[6] - main_current[10])); + } +} \ No newline at end of file diff --git a/air-script/tests/constant_in_range/mod.rs b/air-script/tests/constant_in_range/mod.rs index a071cd958..68a0d2cbd 100644 --- a/air-script/tests/constant_in_range/mod.rs +++ b/air-script/tests/constant_in_range/mod.rs @@ -1,4 +1,10 @@ #[rustfmt::skip] #[allow(clippy::all)] mod constant_in_range; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod constant_in_range_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/constant_in_range/test_air_plonky3.rs b/air-script/tests/constant_in_range/test_air_plonky3.rs new file mode 100644 index 000000000..15af390e6 --- /dev/null +++ b/air-script/tests/constant_in_range/test_air_plonky3.rs @@ -0,0 +1,103 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + constant_in_range::constant_in_range_plonky3::{ConstantInRangeAir, NUM_COLUMNS}, + helpers::check_constraints_with_periodic_columns, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::from_canonical_checked(3).unwrap(); + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + let col_3_prev = rows[i - 1][3]; + let col_4_prev = rows[i - 1][4]; + let col_5_prev = rows[i - 1][5]; + let col_6_prev = rows[i - 1][6]; + let col_7_prev = rows[i - 1][7]; + let col_8_prev = rows[i - 1][8]; + let col_9_prev = rows[i - 1][9]; + let col_10_prev = rows[i - 1][10]; + let col_11_prev = rows[i - 1][11]; + + // Update current row based on previous values + rows[i][0] = col_0_prev; + rows[i][1] = col_1_prev; + rows[i][2] = col_2_prev; + rows[i][3] = col_3_prev; + rows[i][4] = col_4_prev; + rows[i][5] = col_5_prev; + rows[i][6] = col_6_prev; + rows[i][7] = col_7_prev; + rows[i][8] = col_8_prev; + rows[i][9] = col_9_prev; + rows[i][10] = col_10_prev; + rows[i][11] = col_11_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&ConstantInRangeAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/constant_in_range/test_air.rs b/air-script/tests/constant_in_range/test_air_winterfell.rs similarity index 100% rename from air-script/tests/constant_in_range/test_air.rs rename to air-script/tests/constant_in_range/test_air_winterfell.rs diff --git a/air-script/tests/constants/constants_plonky3.rs b/air-script/tests/constants/constants_plonky3.rs new file mode 100644 index 000000000..9361c0228 --- /dev/null +++ b/air-script/tests/constants/constants_plonky3.rs @@ -0,0 +1,52 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 7; + +pub const NUM_PUBLIC_VALUES: usize = 32; + +pub struct ConstantsAir; + +impl BaseAir for ConstantsAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for ConstantsAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for ConstantsAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for ConstantsAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[0] - AB::Expr::from(AB::F::from_u64(1))); + builder.when_first_row().assert_zero::<_>(main_current[1] - AB::Expr::from(AB::F::from_u64(1))); + builder.when_first_row().assert_zero::<_>(main_current[2]); + builder.when_first_row().assert_zero::<_>(main_current[3] - AB::Expr::from(AB::F::from_u64(1))); + builder.when_first_row().assert_zero::<_>(main_current[4] - AB::Expr::from(AB::F::from_u64(1))); + builder.when_last_row().assert_zero::<_>(main_current[6]); + builder.when_transition().assert_zero::<_>(main_next[0] - (main_current[0] + AB::Expr::from(AB::F::from_u64(1)))); + builder.when_transition().assert_zero::<_>(main_next[1]); + builder.when_transition().assert_zero::<_>(main_next[2] - main_current[2]); + builder.when_transition().assert_zero::<_>(main_next[5] - (main_current[5] + AB::Expr::from(AB::F::from_u64(1)))); + builder.assert_zero::<_>(main_current[4] - AB::Expr::from(AB::F::from_u64(1))); + } +} \ No newline at end of file diff --git a/air-script/tests/constants/mod.rs b/air-script/tests/constants/mod.rs index 526f76f5e..1540ba337 100644 --- a/air-script/tests/constants/mod.rs +++ b/air-script/tests/constants/mod.rs @@ -1,4 +1,10 @@ #[rustfmt::skip] #[allow(clippy::all)] mod constants; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod constants_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/constants/test_air_plonky3.rs b/air-script/tests/constants/test_air_plonky3.rs new file mode 100644 index 000000000..f4d12edd5 --- /dev/null +++ b/air-script/tests/constants/test_air_plonky3.rs @@ -0,0 +1,99 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + constants::constants_plonky3::{ConstantsAir, NUM_COLUMNS}, + helpers::check_constraints_with_periodic_columns, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ONE; + rows[0][1] = F::ONE; + rows[0][2] = F::ZERO; + rows[0][3] = F::ONE; + rows[0][4] = F::ONE; + rows[0][5] = F::ZERO; + rows[0][6] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + let col_3_prev = rows[i - 1][3]; + let col_4_prev = rows[i - 1][4]; + let col_5_prev = rows[i - 1][5]; + let col_6_prev = rows[i - 1][6]; + + // Update current row based on previous values + rows[i][0] = col_0_prev + F::ONE; + rows[i][1] = F::ZERO; + rows[i][2] = col_2_prev; + rows[i][3] = col_3_prev; + rows[i][4] = col_4_prev; + rows[i][5] = col_5_prev + F::ONE; + rows[i][6] = col_6_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 32]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&ConstantsAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/constants/test_air.rs b/air-script/tests/constants/test_air_winterfell.rs similarity index 100% rename from air-script/tests/constants/test_air.rs rename to air-script/tests/constants/test_air_winterfell.rs diff --git a/air-script/tests/constraint_comprehension/constraint_comprehension_plonky3.rs b/air-script/tests/constraint_comprehension/constraint_comprehension_plonky3.rs new file mode 100644 index 000000000..ef6d701c1 --- /dev/null +++ b/air-script/tests/constraint_comprehension/constraint_comprehension_plonky3.rs @@ -0,0 +1,46 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 14; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct ConstraintComprehensionAir; + +impl BaseAir for ConstraintComprehensionAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for ConstraintComprehensionAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for ConstraintComprehensionAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for ConstraintComprehensionAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[8]); + builder.assert_zero::<_>(main_current[6] - main_current[10]); + builder.assert_zero::<_>(main_current[7] - main_current[11]); + builder.assert_zero::<_>(main_current[8] - main_current[12]); + builder.assert_zero::<_>(main_current[9] - main_current[13]); + } +} \ No newline at end of file diff --git a/air-script/tests/constraint_comprehension/mod.rs b/air-script/tests/constraint_comprehension/mod.rs index 16222fbd1..960d9a5a6 100644 --- a/air-script/tests/constraint_comprehension/mod.rs +++ b/air-script/tests/constraint_comprehension/mod.rs @@ -1,4 +1,10 @@ #[rustfmt::skip] #[allow(clippy::all)] mod constraint_comprehension; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod constraint_comprehension_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/constraint_comprehension/test_air_plonky3.rs b/air-script/tests/constraint_comprehension/test_air_plonky3.rs new file mode 100644 index 000000000..c2243f2ea --- /dev/null +++ b/air-script/tests/constraint_comprehension/test_air_plonky3.rs @@ -0,0 +1,86 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + constraint_comprehension::constraint_comprehension_plonky3::{ + ConstraintComprehensionAir, NUM_COLUMNS, + }, + helpers::check_constraints_with_periodic_columns, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::from_canonical_checked(inputs[0]).unwrap(); + rows[0][1] = F::ONE; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let a_prev = rows[i - 1][0]; + let b_prev = rows[i - 1][1]; + + // Update current row based on previous values + rows[i][0] = F::ONE - a_prev; + rows[i][1] = F::ONE - b_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&ConstraintComprehensionAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/constraint_comprehension/test_air.rs b/air-script/tests/constraint_comprehension/test_air_winterfell.rs similarity index 100% rename from air-script/tests/constraint_comprehension/test_air.rs rename to air-script/tests/constraint_comprehension/test_air_winterfell.rs diff --git a/air-script/tests/evaluators/evaluators_plonky3.rs b/air-script/tests/evaluators/evaluators_plonky3.rs new file mode 100644 index 000000000..046eb2a1f --- /dev/null +++ b/air-script/tests/evaluators/evaluators_plonky3.rs @@ -0,0 +1,52 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 7; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct EvaluatorsAir; + +impl BaseAir for EvaluatorsAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for EvaluatorsAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for EvaluatorsAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for EvaluatorsAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[0]); + builder.when_transition().assert_zero::<_>(main_next[0] - main_current[0]); + builder.when_transition().assert_zero::<_>(main_next[2] - main_current[2]); + builder.when_transition().assert_zero::<_>(main_next[6] - main_current[6]); + builder.assert_zero::<_>(main_current[0] * main_current[0] - main_current[0]); + builder.assert_zero::<_>(main_current[1] * main_current[1] - main_current[1]); + builder.assert_zero::<_>(main_current[2] * main_current[2] - main_current[2]); + builder.assert_zero::<_>(main_current[3] * main_current[3] - main_current[3]); + builder.assert_zero::<_>(main_current[4]); + builder.assert_zero::<_>(main_current[5] - AB::Expr::from(AB::F::from_u64(1))); + builder.assert_zero::<_>(main_current[6] - AB::Expr::from(AB::F::from_u64(4))); + } +} \ No newline at end of file diff --git a/air-script/tests/evaluators/mod.rs b/air-script/tests/evaluators/mod.rs index cf380f979..8513a7ba3 100644 --- a/air-script/tests/evaluators/mod.rs +++ b/air-script/tests/evaluators/mod.rs @@ -1,4 +1,10 @@ #[rustfmt::skip] #[allow(clippy::all)] mod evaluators; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod evaluators_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/evaluators/test_air_plonky3.rs b/air-script/tests/evaluators/test_air_plonky3.rs new file mode 100644 index 000000000..9ba08a264 --- /dev/null +++ b/air-script/tests/evaluators/test_air_plonky3.rs @@ -0,0 +1,99 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + evaluators::evaluators_plonky3::{EvaluatorsAir, NUM_COLUMNS}, + helpers::check_constraints_with_periodic_columns, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::ZERO; + rows[0][2] = F::ZERO; + rows[0][3] = F::ZERO; + rows[0][4] = F::ZERO; + rows[0][5] = F::ONE; + rows[0][6] = F::from_canonical_checked(4).unwrap(); + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + let col_3_prev = rows[i - 1][3]; + let col_4_prev = rows[i - 1][4]; + let col_5_prev = rows[i - 1][5]; + let col_6_prev = rows[i - 1][6]; + + // Update current row based on previous values + rows[i][0] = col_0_prev; + rows[i][1] = col_1_prev; + rows[i][2] = col_2_prev; + rows[i][3] = col_3_prev; + rows[i][4] = col_4_prev; + rows[i][5] = col_5_prev; + rows[i][6] = col_6_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&EvaluatorsAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/evaluators/test_air.rs b/air-script/tests/evaluators/test_air_winterfell.rs similarity index 100% rename from air-script/tests/evaluators/test_air.rs rename to air-script/tests/evaluators/test_air_winterfell.rs diff --git a/air-script/tests/fibonacci/fibonacci_plonky3.rs b/air-script/tests/fibonacci/fibonacci_plonky3.rs new file mode 100644 index 000000000..a00d0c1a1 --- /dev/null +++ b/air-script/tests/fibonacci/fibonacci_plonky3.rs @@ -0,0 +1,46 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 2; + +pub const NUM_PUBLIC_VALUES: usize = 3; + +pub struct FibonacciAir; + +impl BaseAir for FibonacciAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for FibonacciAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for FibonacciAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for FibonacciAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[0] - public_values[0].into()); + builder.when_first_row().assert_zero::<_>(main_current[1] - public_values[1].into()); + builder.when_last_row().assert_zero::<_>(main_current[1] - public_values[2].into()); + builder.when_transition().assert_zero::<_>(main_next[1] - (main_current[0] + main_current[1])); + builder.when_transition().assert_zero::<_>(main_next[0] - main_current[1]); + } +} \ No newline at end of file diff --git a/air-script/tests/fibonacci/mod.rs b/air-script/tests/fibonacci/mod.rs index 8fa9af072..57c53c30e 100644 --- a/air-script/tests/fibonacci/mod.rs +++ b/air-script/tests/fibonacci/mod.rs @@ -1,4 +1,10 @@ #[rustfmt::skip] #[allow(clippy::all)] mod fibonacci; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod fibonacci_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/fibonacci/test_air_plonky3.rs b/air-script/tests/fibonacci/test_air_plonky3.rs new file mode 100644 index 000000000..fdfbd8132 --- /dev/null +++ b/air-script/tests/fibonacci/test_air_plonky3.rs @@ -0,0 +1,87 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + fibonacci::fibonacci_plonky3::{FibonacciAir, NUM_COLUMNS}, + helpers::check_constraints_with_periodic_columns, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 31; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::from_canonical_checked(inputs[0]).unwrap(); + rows[0][1] = F::from_canonical_checked(inputs[1]).unwrap(); + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let cur_a = rows[i - 1][0]; + let cur_b = rows[i - 1][1]; + + // Update current row based on previous values + rows[i][0] = cur_b; + rows[i][1] = cur_a + cur_b; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let one = 1; + let last = 2178309; // 32nd Fibonacci number + let inputs = vec![one, one, last]; + + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&FibonacciAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/fibonacci/test_air.rs b/air-script/tests/fibonacci/test_air_winterfell.rs similarity index 100% rename from air-script/tests/fibonacci/test_air.rs rename to air-script/tests/fibonacci/test_air_winterfell.rs index 4ba4674e2..e71be12d2 100644 --- a/air-script/tests/fibonacci/test_air.rs +++ b/air-script/tests/fibonacci/test_air_winterfell.rs @@ -29,8 +29,8 @@ impl AirTester for FibonacciAirTester { |_, state| { let cur_a = state[0]; let cur_b = state[1]; - state[1] = cur_a + cur_b; state[0] = cur_b; + state[1] = cur_a + cur_b; }, ); diff --git a/air-script/tests/functions/functions_complex_plonky3.rs b/air-script/tests/functions/functions_complex_plonky3.rs new file mode 100644 index 000000000..014020bd9 --- /dev/null +++ b/air-script/tests/functions/functions_complex_plonky3.rs @@ -0,0 +1,44 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 17; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct FunctionsAir; + +impl BaseAir for FunctionsAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for FunctionsAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for FunctionsAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for FunctionsAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[3]); + builder.when_transition().assert_zero::<_>(main_next[16] - main_current[16] * ((main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[1] * main_current[2] + main_current[3] * main_current[3] * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * main_current[2] + main_current[3] * main_current[1] * (AB::Expr::from(AB::F::from_u64(1)) - main_current[2]) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[2])) * main_current[0] - main_current[0] + AB::Expr::from(AB::F::from_u64(1)))); + builder.when_transition().assert_zero::<_>(main_next[3] - (main_current[4] + main_current[5] + main_current[6] + main_current[7] + main_current[8] + main_current[9] + main_current[10] + main_current[11] + main_current[12] + main_current[13] + main_current[14] + main_current[15] + AB::Expr::from(AB::F::from_u64(1))) * AB::Expr::from(AB::F::from_u64(2))); + } +} \ No newline at end of file diff --git a/air-script/tests/functions/functions_simple_plonky3.rs b/air-script/tests/functions/functions_simple_plonky3.rs new file mode 100644 index 000000000..2702a6f56 --- /dev/null +++ b/air-script/tests/functions/functions_simple_plonky3.rs @@ -0,0 +1,50 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 9; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct FunctionsAir; + +impl BaseAir for FunctionsAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for FunctionsAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for FunctionsAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for FunctionsAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[3]); + builder.assert_zero::<_>(main_current[0] * main_current[3] - AB::Expr::from(AB::F::from_u64(1))); + builder.assert_zero::<_>(main_current[4] * main_current[5] * main_current[6] * main_current[7] * main_current[3] - AB::Expr::from(AB::F::from_u64(1))); + builder.assert_zero::<_>((main_current[4] + main_current[5] + main_current[6] + main_current[7]) * main_current[4] * main_current[5] * main_current[6] * main_current[7] - AB::Expr::from(AB::F::from_u64(1))); + builder.assert_zero::<_>(main_current[4] * main_current[5] * main_current[6] * main_current[7] - AB::Expr::from(AB::F::from_u64(1))); + builder.assert_zero::<_>(main_current[0] * main_current[4] * main_current[5] * main_current[6] * main_current[7] - AB::Expr::from(AB::F::from_u64(1))); + builder.assert_zero::<_>(main_current[1] + (main_current[4] + main_current[5] + main_current[6] + main_current[7]) * main_current[4] * main_current[5] * main_current[6] * main_current[7] - AB::Expr::from(AB::F::from_u64(1))); + builder.assert_zero::<_>(main_current[4] + main_current[5] + main_current[6] + main_current[7] - AB::Expr::from(AB::F::from_u64(1))); + builder.assert_zero::<_>((main_current[4] + main_current[5] + main_current[6] + main_current[7]) * AB::Expr::from(AB::F::from_u64(4)) - AB::Expr::from(AB::F::from_u64(1))); + } +} \ No newline at end of file diff --git a/air-script/tests/functions/mod.rs b/air-script/tests/functions/mod.rs index 4a85b16cc..af284a496 100644 --- a/air-script/tests/functions/mod.rs +++ b/air-script/tests/functions/mod.rs @@ -4,4 +4,14 @@ mod functions_complex; #[rustfmt::skip] #[allow(clippy::all)] mod functions_simple; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod functions_complex_plonky3; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod functions_simple_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/functions/test_air_plonky3.rs b/air-script/tests/functions/test_air_plonky3.rs new file mode 100644 index 000000000..84da79962 --- /dev/null +++ b/air-script/tests/functions/test_air_plonky3.rs @@ -0,0 +1,129 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + functions::functions_complex_plonky3::{FunctionsAir, NUM_COLUMNS}, + helpers::check_constraints_with_periodic_columns, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::ZERO; + rows[0][2] = F::ZERO; + rows[0][3] = F::ZERO; + rows[0][4] = F::ZERO; + rows[0][5] = F::ZERO; + rows[0][6] = F::ZERO; + rows[0][7] = F::ZERO; + rows[0][8] = F::ZERO; + rows[0][9] = F::ZERO; + rows[0][10] = F::ZERO; + rows[0][11] = F::ZERO; + rows[0][12] = F::ZERO; + rows[0][13] = F::ZERO; + rows[0][14] = F::ZERO; + rows[0][15] = F::ZERO; + rows[0][16] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + let col_3_prev = rows[i - 1][3]; + let col_4_prev = rows[i - 1][4]; + let col_5_prev = rows[i - 1][5]; + let col_6_prev = rows[i - 1][6]; + let col_7_prev = rows[i - 1][7]; + let col_8_prev = rows[i - 1][8]; + let col_9_prev = rows[i - 1][9]; + let col_10_prev = rows[i - 1][10]; + let col_11_prev = rows[i - 1][11]; + let col_12_prev = rows[i - 1][12]; + let col_13_prev = rows[i - 1][13]; + let col_14_prev = rows[i - 1][14]; + let col_15_prev = rows[i - 1][15]; + let col_16_prev = rows[i - 1][16]; + + // Update current row based on previous values + rows[i][0] = col_0_prev; + rows[i][1] = col_1_prev; + rows[i][2] = col_2_prev; + rows[i][3] = F::from_canonical_checked(2).unwrap(); + rows[i][4] = col_4_prev; + rows[i][5] = col_5_prev; + rows[i][6] = col_6_prev; + rows[i][7] = col_7_prev; + rows[i][8] = col_8_prev; + rows[i][9] = col_9_prev; + rows[i][10] = col_10_prev; + rows[i][11] = col_11_prev; + rows[i][12] = col_12_prev; + rows[i][13] = col_13_prev; + rows[i][14] = col_14_prev; + rows[i][15] = col_15_prev; + rows[i][16] = col_16_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&FunctionsAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/functions/test_air.rs b/air-script/tests/functions/test_air_winterfell.rs similarity index 100% rename from air-script/tests/functions/test_air.rs rename to air-script/tests/functions/test_air_winterfell.rs diff --git a/air-script/tests/indexed_trace_access/indexed_trace_access_plonky3.rs b/air-script/tests/indexed_trace_access/indexed_trace_access_plonky3.rs new file mode 100644 index 000000000..c4fa5cd08 --- /dev/null +++ b/air-script/tests/indexed_trace_access/indexed_trace_access_plonky3.rs @@ -0,0 +1,43 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 4; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct TraceAccessAir; + +impl BaseAir for TraceAccessAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for TraceAccessAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for TraceAccessAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for TraceAccessAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[0]); + builder.when_transition().assert_zero::<_>(main_next[0] - (main_current[1] + AB::Expr::from(AB::F::from_u64(1)))); + } +} \ No newline at end of file diff --git a/air-script/tests/indexed_trace_access/mod.rs b/air-script/tests/indexed_trace_access/mod.rs index 7aee9d4e8..f23106386 100644 --- a/air-script/tests/indexed_trace_access/mod.rs +++ b/air-script/tests/indexed_trace_access/mod.rs @@ -1,4 +1,10 @@ #[rustfmt::skip] #[allow(clippy::all)] mod indexed_trace_access; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod indexed_trace_access_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/indexed_trace_access/test_air_plonky3.rs b/air-script/tests/indexed_trace_access/test_air_plonky3.rs new file mode 100644 index 000000000..8f1f7dfd3 --- /dev/null +++ b/air-script/tests/indexed_trace_access/test_air_plonky3.rs @@ -0,0 +1,86 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + helpers::check_constraints_with_periodic_columns, + indexed_trace_access::indexed_trace_access_plonky3::{NUM_COLUMNS, TraceAccessAir}, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::ZERO; + rows[0][2] = F::ZERO; + rows[0][3] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + #[allow(clippy::needless_range_loop)] + for i in 1..num_rows { + // Update current row + rows[i][0] = F::ONE; + rows[i][1] = F::ZERO; + rows[i][2] = F::ZERO; + rows[i][3] = F::ZERO; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&TraceAccessAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/indexed_trace_access/test_air.rs b/air-script/tests/indexed_trace_access/test_air_winterfell.rs similarity index 100% rename from air-script/tests/indexed_trace_access/test_air.rs rename to air-script/tests/indexed_trace_access/test_air_winterfell.rs diff --git a/air-script/tests/list_comprehension/list_comprehension_nested_plonky3.rs b/air-script/tests/list_comprehension/list_comprehension_nested_plonky3.rs new file mode 100644 index 000000000..990eb5946 --- /dev/null +++ b/air-script/tests/list_comprehension/list_comprehension_nested_plonky3.rs @@ -0,0 +1,45 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 2; + +pub const NUM_PUBLIC_VALUES: usize = 1; + +pub struct ListComprehensionAir; + +impl BaseAir for ListComprehensionAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for ListComprehensionAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for ListComprehensionAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for ListComprehensionAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[0]); + builder.assert_zero::<_>(main_current[0] + main_current[1] * AB::Expr::from(AB::F::from_u64(2)) - AB::Expr::from(AB::F::from_u64(3))); + builder.assert_zero::<_>(main_current[0] * AB::Expr::from(AB::F::from_u64(2)) + main_current[1] * AB::Expr::from(AB::F::from_u64(3)) - AB::Expr::from(AB::F::from_u64(5))); + builder.assert_zero::<_>(main_current[0] * AB::Expr::from(AB::F::from_u64(3)) + main_current[1] * AB::Expr::from(AB::F::from_u64(4)) - AB::Expr::from(AB::F::from_u64(7))); + } +} \ No newline at end of file diff --git a/air-script/tests/list_comprehension/list_comprehension_plonky3.rs b/air-script/tests/list_comprehension/list_comprehension_plonky3.rs new file mode 100644 index 000000000..519559827 --- /dev/null +++ b/air-script/tests/list_comprehension/list_comprehension_plonky3.rs @@ -0,0 +1,48 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 16; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct ListComprehensionAir; + +impl BaseAir for ListComprehensionAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for ListComprehensionAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for ListComprehensionAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for ListComprehensionAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[10]); + builder.assert_zero::<_>(main_current[0] - main_current[2]); + builder.assert_zero::<_>(main_current[4] - main_current[0] * AB::Expr::from(AB::F::from_u64(8)) * main_current[11]); + builder.when_transition().assert_zero::<_>(main_current[4] - main_current[0] * (main_next[8] - main_next[12])); + builder.assert_zero::<_>(main_current[6] - main_current[0] * (main_current[9] - main_current[14])); + builder.assert_zero::<_>(main_current[1] - (main_current[5] - main_current[8] - main_current[12] + AB::Expr::from(AB::F::from_u64(10)) + main_current[6] - main_current[9] - main_current[13] + AB::Expr::from(AB::F::from_u64(20)) + main_current[7] - main_current[10] - main_current[14])); + builder.assert_zero::<_>(main_current[14] - AB::Expr::from(AB::F::from_u64(10))); + } +} \ No newline at end of file diff --git a/air-script/tests/list_comprehension/mod.rs b/air-script/tests/list_comprehension/mod.rs index 5f090bea2..eb8e94340 100644 --- a/air-script/tests/list_comprehension/mod.rs +++ b/air-script/tests/list_comprehension/mod.rs @@ -1,4 +1,10 @@ #[rustfmt::skip] #[allow(clippy::all)] mod list_comprehension; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod list_comprehension_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/list_comprehension/test_air_plonky3.rs b/air-script/tests/list_comprehension/test_air_plonky3.rs new file mode 100644 index 000000000..0f8e6f879 --- /dev/null +++ b/air-script/tests/list_comprehension/test_air_plonky3.rs @@ -0,0 +1,126 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + helpers::check_constraints_with_periodic_columns, + list_comprehension::list_comprehension_plonky3::{ListComprehensionAir, NUM_COLUMNS}, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::from_canonical_checked(20).unwrap(); + rows[0][2] = F::ZERO; + rows[0][3] = F::ZERO; + rows[0][4] = F::ZERO; + rows[0][5] = F::ZERO; + rows[0][6] = F::ZERO; + rows[0][7] = F::ZERO; + rows[0][8] = F::ZERO; + rows[0][9] = F::ZERO; + rows[0][10] = F::ZERO; + rows[0][11] = F::ZERO; + rows[0][12] = F::ZERO; + rows[0][13] = F::ZERO; + rows[0][14] = F::from_canonical_checked(10).unwrap(); + rows[0][15] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + let col_3_prev = rows[i - 1][3]; + let col_4_prev = rows[i - 1][4]; + let col_5_prev = rows[i - 1][5]; + let col_6_prev = rows[i - 1][6]; + let col_7_prev = rows[i - 1][7]; + let col_8_prev = rows[i - 1][8]; + let col_9_prev = rows[i - 1][9]; + let col_10_prev = rows[i - 1][10]; + let col_11_prev = rows[i - 1][11]; + let col_12_prev = rows[i - 1][12]; + let col_13_prev = rows[i - 1][13]; + let col_14_prev = rows[i - 1][14]; + let col_15_prev = rows[i - 1][15]; + + // Update current row based on previous values + rows[i][0] = col_0_prev; + rows[i][1] = col_1_prev; + rows[i][2] = col_2_prev; + rows[i][3] = F::from_canonical_checked(2).unwrap(); + rows[i][4] = col_4_prev; + rows[i][5] = col_5_prev; + rows[i][6] = col_6_prev; + rows[i][7] = col_7_prev; + rows[i][8] = col_8_prev; + rows[i][9] = col_9_prev; + rows[i][10] = col_10_prev; + rows[i][11] = col_11_prev; + rows[i][12] = col_12_prev; + rows[i][13] = col_13_prev; + rows[i][14] = col_14_prev; + rows[i][15] = col_15_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&ListComprehensionAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/list_comprehension/test_air.rs b/air-script/tests/list_comprehension/test_air_winterfell.rs similarity index 100% rename from air-script/tests/list_comprehension/test_air.rs rename to air-script/tests/list_comprehension/test_air_winterfell.rs diff --git a/air-script/tests/list_folding/list_folding_plonky3.rs b/air-script/tests/list_folding/list_folding_plonky3.rs new file mode 100644 index 000000000..1c4f68dca --- /dev/null +++ b/air-script/tests/list_folding/list_folding_plonky3.rs @@ -0,0 +1,46 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 17; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct ListFoldingAir; + +impl BaseAir for ListFoldingAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for ListFoldingAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for ListFoldingAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for ListFoldingAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[11]); + builder.when_transition().assert_zero::<_>(main_next[5] - (main_current[9] + main_current[10] + main_current[11] + main_current[12] + main_current[13] * main_current[14] * main_current[15] * main_current[16])); + builder.when_transition().assert_zero::<_>(main_next[6] - (main_current[9] + main_current[10] + main_current[11] + main_current[12] + main_current[13] * main_current[14] * main_current[15] * main_current[16])); + builder.when_transition().assert_zero::<_>(main_next[7] - (main_current[9] * main_current[13] + main_current[10] * main_current[14] + main_current[11] * main_current[15] + main_current[12] * main_current[16] + (main_current[9] + main_current[13]) * (main_current[10] + main_current[14]) * (main_current[11] + main_current[15]) * (main_current[12] + main_current[16]))); + builder.when_transition().assert_zero::<_>(main_next[8] - (main_current[1] + main_current[9] * main_current[13] + main_current[10] * main_current[14] + main_current[11] * main_current[15] + main_current[12] * main_current[16] + main_current[9] * main_current[13] + main_current[10] * main_current[14] + main_current[11] * main_current[15] + main_current[12] * main_current[16])); + } +} \ No newline at end of file diff --git a/air-script/tests/list_folding/mod.rs b/air-script/tests/list_folding/mod.rs index 5e992bc22..0339dce98 100644 --- a/air-script/tests/list_folding/mod.rs +++ b/air-script/tests/list_folding/mod.rs @@ -1,4 +1,10 @@ #[rustfmt::skip] #[allow(clippy::all)] mod list_folding; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod list_folding_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/list_folding/test_air_plonky3.rs b/air-script/tests/list_folding/test_air_plonky3.rs new file mode 100644 index 000000000..695d3906f --- /dev/null +++ b/air-script/tests/list_folding/test_air_plonky3.rs @@ -0,0 +1,129 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + helpers::check_constraints_with_periodic_columns, + list_folding::list_folding_plonky3::{ListFoldingAir, NUM_COLUMNS}, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::ZERO; + rows[0][2] = F::ZERO; + rows[0][3] = F::ZERO; + rows[0][4] = F::ZERO; + rows[0][5] = F::ZERO; + rows[0][6] = F::ZERO; + rows[0][7] = F::ZERO; + rows[0][8] = F::ZERO; + rows[0][9] = F::ZERO; + rows[0][10] = F::ZERO; + rows[0][11] = F::ZERO; + rows[0][12] = F::ZERO; + rows[0][13] = F::ZERO; + rows[0][14] = F::ZERO; + rows[0][15] = F::ZERO; + rows[0][16] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + let col_3_prev = rows[i - 1][3]; + let col_4_prev = rows[i - 1][4]; + let col_5_prev = rows[i - 1][5]; + let col_6_prev = rows[i - 1][6]; + let col_7_prev = rows[i - 1][7]; + let col_8_prev = rows[i - 1][8]; + let col_9_prev = rows[i - 1][9]; + let col_10_prev = rows[i - 1][10]; + let col_11_prev = rows[i - 1][11]; + let col_12_prev = rows[i - 1][12]; + let col_13_prev = rows[i - 1][13]; + let col_14_prev = rows[i - 1][14]; + let col_15_prev = rows[i - 1][15]; + let col_16_prev = rows[i - 1][16]; + + // Update current row based on previous values + rows[i][0] = col_0_prev; + rows[i][1] = col_1_prev; + rows[i][2] = col_2_prev; + rows[i][3] = F::from_canonical_checked(2).unwrap(); + rows[i][4] = col_4_prev; + rows[i][5] = col_5_prev; + rows[i][6] = col_6_prev; + rows[i][7] = col_7_prev; + rows[i][8] = col_8_prev; + rows[i][9] = col_9_prev; + rows[i][10] = col_10_prev; + rows[i][11] = col_11_prev; + rows[i][12] = col_12_prev; + rows[i][13] = col_13_prev; + rows[i][14] = col_14_prev; + rows[i][15] = col_15_prev; + rows[i][16] = col_16_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&ListFoldingAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/list_folding/test_air.rs b/air-script/tests/list_folding/test_air_winterfell.rs similarity index 100% rename from air-script/tests/list_folding/test_air.rs rename to air-script/tests/list_folding/test_air_winterfell.rs diff --git a/air-script/tests/periodic_columns/mod.rs b/air-script/tests/periodic_columns/mod.rs index fd9a501e7..0053e1aa8 100644 --- a/air-script/tests/periodic_columns/mod.rs +++ b/air-script/tests/periodic_columns/mod.rs @@ -1,4 +1,10 @@ #[rustfmt::skip] #[allow(clippy::all)] mod periodic_columns; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod periodic_columns_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/periodic_columns/periodic_columns_plonky3.rs b/air-script/tests/periodic_columns/periodic_columns_plonky3.rs new file mode 100644 index 000000000..9eb4f5447 --- /dev/null +++ b/air-script/tests/periodic_columns/periodic_columns_plonky3.rs @@ -0,0 +1,46 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 3; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct PeriodicColumnsAir; + +impl BaseAir for PeriodicColumnsAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for PeriodicColumnsAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for PeriodicColumnsAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + vec![F::from_u64(1), F::from_u64(0), F::from_u64(0), F::from_u64(0)], + vec![F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(0)], + ] + } +} + +impl Air for PeriodicColumnsAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[0]); + builder.assert_zero::<_>(periodic_values[0].into() * (main_current[1] + main_current[2])); + builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[0] - main_current[0])); + } +} \ No newline at end of file diff --git a/air-script/tests/periodic_columns/test_air_plonky3.rs b/air-script/tests/periodic_columns/test_air_plonky3.rs new file mode 100644 index 000000000..c380f7e88 --- /dev/null +++ b/air-script/tests/periodic_columns/test_air_plonky3.rs @@ -0,0 +1,87 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + helpers::check_constraints_with_periodic_columns, + periodic_columns::periodic_columns_plonky3::{NUM_COLUMNS, PeriodicColumnsAir}, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::ZERO; + rows[0][2] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + + // Update current row based on previous values + rows[i][0] = col_0_prev; + rows[i][1] = col_1_prev; + rows[i][2] = col_2_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&PeriodicColumnsAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/periodic_columns/test_air.rs b/air-script/tests/periodic_columns/test_air_winterfell.rs similarity index 100% rename from air-script/tests/periodic_columns/test_air.rs rename to air-script/tests/periodic_columns/test_air_winterfell.rs diff --git a/air-script/tests/pub_inputs/mod.rs b/air-script/tests/pub_inputs/mod.rs index afb27e904..139601bc2 100644 --- a/air-script/tests/pub_inputs/mod.rs +++ b/air-script/tests/pub_inputs/mod.rs @@ -1,4 +1,10 @@ #[rustfmt::skip] #[allow(clippy::all)] mod pub_inputs; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod pub_inputs_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/pub_inputs/pub_inputs_plonky3.rs b/air-script/tests/pub_inputs/pub_inputs_plonky3.rs new file mode 100644 index 000000000..a34e8aca4 --- /dev/null +++ b/air-script/tests/pub_inputs/pub_inputs_plonky3.rs @@ -0,0 +1,50 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 4; + +pub const NUM_PUBLIC_VALUES: usize = 32; + +pub struct PubInputsAir; + +impl BaseAir for PubInputsAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for PubInputsAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for PubInputsAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for PubInputsAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[0] - public_values[8].into()); + builder.when_first_row().assert_zero::<_>(main_current[1] - public_values[9].into()); + builder.when_first_row().assert_zero::<_>(main_current[2] - public_values[10].into()); + builder.when_first_row().assert_zero::<_>(main_current[3] - public_values[11].into()); + builder.when_last_row().assert_zero::<_>(main_current[0] - public_values[12].into()); + builder.when_last_row().assert_zero::<_>(main_current[1] - public_values[13].into()); + builder.when_last_row().assert_zero::<_>(main_current[2] - public_values[14].into()); + builder.when_last_row().assert_zero::<_>(main_current[3] - public_values[15].into()); + builder.when_transition().assert_zero::<_>(main_next[0] - (main_current[1] + main_current[2])); + } +} \ No newline at end of file diff --git a/air-script/tests/pub_inputs/test_air_plonky3.rs b/air-script/tests/pub_inputs/test_air_plonky3.rs new file mode 100644 index 000000000..071828dfb --- /dev/null +++ b/air-script/tests/pub_inputs/test_air_plonky3.rs @@ -0,0 +1,90 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + helpers::check_constraints_with_periodic_columns, + pub_inputs::pub_inputs_plonky3::{NUM_COLUMNS, PubInputsAir}, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::ZERO; + rows[0][2] = F::ZERO; + rows[0][3] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + let col_3_prev = rows[i - 1][3]; + + // Update current row based on previous values + rows[i][0] = col_0_prev; + rows[i][1] = col_1_prev; + rows[i][2] = col_2_prev; + rows[i][3] = col_3_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![0; 32]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&PubInputsAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/pub_inputs/test_air.rs b/air-script/tests/pub_inputs/test_air_winterfell.rs similarity index 100% rename from air-script/tests/pub_inputs/test_air.rs rename to air-script/tests/pub_inputs/test_air_winterfell.rs diff --git a/air-script/tests/selectors/mod.rs b/air-script/tests/selectors/mod.rs index ebb9eb59a..88bbcd79d 100644 --- a/air-script/tests/selectors/mod.rs +++ b/air-script/tests/selectors/mod.rs @@ -7,4 +7,18 @@ mod selectors_combine_complex; #[rustfmt::skip] #[allow(clippy::all)] mod selectors_with_evaluators; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod selectors_combine_simple_plonky3; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod selectors_combine_complex_plonky3; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod selectors_with_evaluators_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/selectors/selectors_combine_complex_plonky3.rs b/air-script/tests/selectors/selectors_combine_complex_plonky3.rs new file mode 100644 index 000000000..5db82c3d8 --- /dev/null +++ b/air-script/tests/selectors/selectors_combine_complex_plonky3.rs @@ -0,0 +1,45 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 6; + +pub const NUM_PUBLIC_VALUES: usize = 1; + +pub struct SelectorsAir; + +impl BaseAir for SelectorsAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for SelectorsAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for SelectorsAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for SelectorsAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[5]); + builder.assert_zero::<_>((main_current[0] + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * main_current[1]) * (main_current[3] - AB::Expr::from(AB::F::from_u64(16))) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (main_current[4] - AB::Expr::from(AB::F::from_u64(5)))); + builder.assert_zero::<_>((AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * (main_current[5] - AB::Expr::from(AB::F::from_u64(5))) + main_current[0] * (main_current[4] - AB::Expr::from(AB::F::from_u64(4)))); + builder.assert_zero::<_>(main_current[0] * (main_current[5] - AB::Expr::from(AB::F::from_u64(20))) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * main_current[1] * (main_current[4] - AB::Expr::from(AB::F::from_u64(31)))); + } +} \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_combine_simple_plonky3.rs b/air-script/tests/selectors/selectors_combine_simple_plonky3.rs new file mode 100644 index 000000000..de42005a7 --- /dev/null +++ b/air-script/tests/selectors/selectors_combine_simple_plonky3.rs @@ -0,0 +1,44 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 4; + +pub const NUM_PUBLIC_VALUES: usize = 1; + +pub struct SelectorsAir; + +impl BaseAir for SelectorsAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for SelectorsAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for SelectorsAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for SelectorsAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[3]); + builder.when_transition().assert_zero::<_>(main_next[1] - main_current[2]); + builder.when_transition().assert_zero::<_>(main_current[3] * (main_next[0] - (main_current[0] + main_current[1])) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[3]) * (main_next[0] - main_current[0] * main_current[1])); + } +} \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_plonky3.rs b/air-script/tests/selectors/selectors_plonky3.rs new file mode 100644 index 000000000..9f0ff795b --- /dev/null +++ b/air-script/tests/selectors/selectors_plonky3.rs @@ -0,0 +1,44 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 4; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct SelectorsAir; + +impl BaseAir for SelectorsAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for SelectorsAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for SelectorsAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for SelectorsAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[3]); + builder.when_transition().assert_zero::<_>(main_current[0] * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * main_next[3]); + builder.when_transition().assert_zero::<_>(main_current[0] * main_current[1] * main_current[2] * (main_next[3] - main_current[3]) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[2]) * (main_next[3] - AB::Expr::from(AB::F::from_u64(1)))); + } +} \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_with_evaluators_plonky3.rs b/air-script/tests/selectors/selectors_with_evaluators_plonky3.rs new file mode 100644 index 000000000..1dd734eec --- /dev/null +++ b/air-script/tests/selectors/selectors_with_evaluators_plonky3.rs @@ -0,0 +1,44 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 4; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct SelectorsAir; + +impl BaseAir for SelectorsAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for SelectorsAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for SelectorsAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for SelectorsAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[3]); + builder.when_transition().assert_zero::<_>(main_current[0] * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * main_next[3]); + builder.when_transition().assert_zero::<_>(main_current[1] * main_current[2] * main_current[0] * (main_next[3] - main_current[3]) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[2]) * (main_next[3] - AB::Expr::from(AB::F::from_u64(1)))); + } +} \ No newline at end of file diff --git a/air-script/tests/selectors/test_air_plonky3.rs b/air-script/tests/selectors/test_air_plonky3.rs new file mode 100644 index 000000000..2b2366fe8 --- /dev/null +++ b/air-script/tests/selectors/test_air_plonky3.rs @@ -0,0 +1,90 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + helpers::check_constraints_with_periodic_columns, + selectors::selectors_with_evaluators_plonky3::{NUM_COLUMNS, SelectorsAir}, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::ZERO; + rows[0][2] = F::ZERO; + rows[0][3] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + let col_3_prev = rows[i - 1][3]; + + // Update current row based on previous values + rows[i][0] = col_0_prev; + rows[i][1] = col_1_prev; + rows[i][2] = col_2_prev; + rows[i][3] = F::ONE; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&SelectorsAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/selectors/test_air.rs b/air-script/tests/selectors/test_air_winterfell.rs similarity index 100% rename from air-script/tests/selectors/test_air.rs rename to air-script/tests/selectors/test_air_winterfell.rs diff --git a/air-script/tests/system/mod.rs b/air-script/tests/system/mod.rs index 10cac5f2b..7d8522c99 100644 --- a/air-script/tests/system/mod.rs +++ b/air-script/tests/system/mod.rs @@ -1,4 +1,10 @@ #[rustfmt::skip] #[allow(clippy::all)] mod system; -mod test_air; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod system_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/tests/system/system_plonky3.rs b/air-script/tests/system/system_plonky3.rs new file mode 100644 index 000000000..10af52c3a --- /dev/null +++ b/air-script/tests/system/system_plonky3.rs @@ -0,0 +1,43 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 3; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct SystemAir; + +impl BaseAir for SystemAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for SystemAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for SystemAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for SystemAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[0]); + builder.when_transition().assert_zero::<_>(main_next[0] - (main_current[0] + AB::Expr::from(AB::F::from_u64(1)))); + } +} \ No newline at end of file diff --git a/air-script/tests/system/test_air_plonky3.rs b/air-script/tests/system/test_air_plonky3.rs new file mode 100644 index 000000000..5bee89503 --- /dev/null +++ b/air-script/tests/system/test_air_plonky3.rs @@ -0,0 +1,87 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + helpers::check_constraints_with_periodic_columns, + system::system_plonky3::{NUM_COLUMNS, SystemAir}, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::ZERO; + rows[0][2] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + + // Update current row based on previous values + rows[i][0] = col_0_prev + F::ONE; + rows[i][1] = col_1_prev; + rows[i][2] = col_2_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&SystemAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/system/test_air.rs b/air-script/tests/system/test_air_winterfell.rs similarity index 100% rename from air-script/tests/system/test_air.rs rename to air-script/tests/system/test_air_winterfell.rs diff --git a/air-script/tests/trace_col_groups/mod.rs b/air-script/tests/trace_col_groups/mod.rs index 706feb822..c2bb1aa0a 100644 --- a/air-script/tests/trace_col_groups/mod.rs +++ b/air-script/tests/trace_col_groups/mod.rs @@ -1,4 +1,10 @@ -mod test_air; +mod test_air_plonky3; +mod test_air_winterfell; + #[rustfmt::skip] #[allow(clippy::all)] mod trace_col_groups; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod trace_col_groups_plonky3; diff --git a/air-script/tests/trace_col_groups/test_air_plonky3.rs b/air-script/tests/trace_col_groups/test_air_plonky3.rs new file mode 100644 index 000000000..b1c2c7f67 --- /dev/null +++ b/air-script/tests/trace_col_groups/test_air_plonky3.rs @@ -0,0 +1,105 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + helpers::check_constraints_with_periodic_columns, + trace_col_groups::trace_col_groups_plonky3::{NUM_COLUMNS, TraceColGroupAir}, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::ZERO; + rows[0][2] = F::ZERO; + rows[0][3] = F::ZERO; + rows[0][4] = F::ZERO; + rows[0][5] = F::ZERO; + rows[0][6] = F::ZERO; + rows[0][7] = F::ZERO; + rows[0][8] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + let col_3_prev = rows[i - 1][3]; + let col_4_prev = rows[i - 1][4]; + let col_5_prev = rows[i - 1][5]; + let col_6_prev = rows[i - 1][6]; + let col_7_prev = rows[i - 1][7]; + let col_8_prev = rows[i - 1][8]; + + // Update current row based on previous values + rows[i][0] = col_0_prev; + rows[i][1] = col_1_prev - F::ONE; + rows[i][2] = col_2_prev + F::ONE; + rows[i][3] = col_3_prev; + rows[i][4] = col_4_prev; + rows[i][5] = col_5_prev; + rows[i][6] = col_6_prev; + rows[i][7] = col_7_prev; + rows[i][8] = col_8_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 16]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&TraceColGroupAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/trace_col_groups/test_air.rs b/air-script/tests/trace_col_groups/test_air_winterfell.rs similarity index 100% rename from air-script/tests/trace_col_groups/test_air.rs rename to air-script/tests/trace_col_groups/test_air_winterfell.rs diff --git a/air-script/tests/trace_col_groups/trace_col_groups_plonky3.rs b/air-script/tests/trace_col_groups/trace_col_groups_plonky3.rs new file mode 100644 index 000000000..bb500087e --- /dev/null +++ b/air-script/tests/trace_col_groups/trace_col_groups_plonky3.rs @@ -0,0 +1,44 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 9; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct TraceColGroupAir; + +impl BaseAir for TraceColGroupAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for TraceColGroupAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for TraceColGroupAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for TraceColGroupAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[8]); + builder.when_transition().assert_zero::<_>(main_next[2] - (main_current[2] + AB::Expr::from(AB::F::from_u64(1)))); + builder.when_transition().assert_zero::<_>(main_next[1] - (main_current[1] - AB::Expr::from(AB::F::from_u64(1)))); + } +} \ No newline at end of file diff --git a/air-script/tests/variables/mod.rs b/air-script/tests/variables/mod.rs index 31656aa8c..98685f537 100644 --- a/air-script/tests/variables/mod.rs +++ b/air-script/tests/variables/mod.rs @@ -1,4 +1,9 @@ -mod test_air; +mod test_air_plonky3; +mod test_air_winterfell; #[rustfmt::skip] #[allow(clippy::all)] mod variables; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod variables_plonky3; diff --git a/air-script/tests/variables/test_air_plonky3.rs b/air-script/tests/variables/test_air_plonky3.rs new file mode 100644 index 000000000..e1e615220 --- /dev/null +++ b/air-script/tests/variables/test_air_plonky3.rs @@ -0,0 +1,90 @@ +use std::marker::PhantomData; + +use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_circle::CirclePcs; +use p3_commit::ExtensionMmcs; +use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_fri::create_benchmark_fri_params; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::MerkleTreeMmcs; +use p3_mersenne_31::Mersenne31; +use p3_sha256::Sha256; +use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; +use p3_uni_stark::StarkConfig; + +use crate::{ + helpers::check_constraints_with_periodic_columns, + variables::variables_plonky3::{NUM_COLUMNS, VariablesAir}, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * NUM_COLUMNS; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ONE; + rows[0][1] = F::ZERO; + rows[0][2] = F::ZERO; + rows[0][3] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + let col_3_prev = rows[i - 1][3]; + + // Update current row based on previous values + rows[i][0] = col_0_prev; + rows[i][1] = F::ONE; + rows[i][2] = col_2_prev; + rows[i][3] = col_3_prev; + } + + trace +} + +#[test] +fn test_air_plonky3() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = vec![1; 32]; + let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&VariablesAir {}, &trace, &inputs_m31); +} diff --git a/air-script/tests/variables/test_air.rs b/air-script/tests/variables/test_air_winterfell.rs similarity index 100% rename from air-script/tests/variables/test_air.rs rename to air-script/tests/variables/test_air_winterfell.rs diff --git a/air-script/tests/variables/variables_plonky3.rs b/air-script/tests/variables/variables_plonky3.rs new file mode 100644 index 000000000..73408ce98 --- /dev/null +++ b/air-script/tests/variables/variables_plonky3.rs @@ -0,0 +1,48 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 4; + +pub const NUM_PUBLIC_VALUES: usize = 32; + +pub struct VariablesAir; + +impl BaseAir for VariablesAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for VariablesAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for VariablesAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + vec![F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(0)], + ] + } +} + +impl Air for VariablesAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[1]); + builder.when_last_row().assert_zero::<_>(main_current[1] - AB::Expr::from(AB::F::from_u64(1))); + builder.assert_zero::<_>(main_current[0] * main_current[0] - main_current[0]); + builder.when_transition().assert_zero::<_>(periodic_values[0].into() * (main_next[0] - main_current[0])); + builder.assert_zero::<_>((AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * (main_current[3] - main_current[1] - main_current[2]) - (AB::Expr::from(AB::F::from_u64(6)) - (AB::Expr::from(AB::F::from_u64(7)) - main_current[0]))); + builder.when_transition().assert_zero::<_>(main_current[0] * (main_current[3] - main_current[1] * main_current[2]) - (AB::Expr::from(AB::F::from_u64(1)) - main_next[0])); + } +} \ No newline at end of file From 4875e6c758035a36f342df14aee6a2ad960fb750 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Fri, 26 Sep 2025 08:58:37 +0200 Subject: [PATCH 12/25] tests: add E2E test for selectors combine with list comprehensions --- ...ombine_with_list_comprehensions_plonky3.rs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 air-script/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs diff --git a/air-script/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs b/air-script/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs new file mode 100644 index 000000000..0f5f4f571 --- /dev/null +++ b/air-script/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs @@ -0,0 +1,46 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 6; + +pub const NUM_PUBLIC_VALUES: usize = 1; + +pub struct SelectorsAir; + +impl BaseAir for SelectorsAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for SelectorsAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for SelectorsAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for SelectorsAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[5]); + builder.assert_zero::<_>(main_current[0] * main_current[3] + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * main_current[1] * main_current[3] + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (main_current[4] - AB::Expr::from(AB::F::from_u64(8)))); + builder.assert_zero::<_>(main_current[0] * (main_current[4] - AB::Expr::from(AB::F::from_u64(2))) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * main_current[1] * (main_current[4] - AB::Expr::from(AB::F::from_u64(6))) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (main_current[5] - AB::Expr::from(AB::F::from_u64(8)))); + builder.assert_zero::<_>(main_current[0] * main_current[3] + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * main_current[1] * (main_current[5] - AB::Expr::from(AB::F::from_u64(8)))); + builder.assert_zero::<_>(main_current[0] * (main_current[5] - AB::Expr::from(AB::F::from_u64(4)))); + } +} \ No newline at end of file From d8c60cc63f0f81440094f4cd91bb5c2f944f34a8 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Tue, 14 Oct 2025 09:49:17 +0200 Subject: [PATCH 13/25] refactor(plonky3): use AB::Expr::ZERO, ONE, from_u64 and double --- codegen/plonky3/src/air/graph.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/codegen/plonky3/src/air/graph.rs b/codegen/plonky3/src/air/graph.rs index 56d5a90cf..fb9e816b6 100644 --- a/codegen/plonky3/src/air/graph.rs +++ b/codegen/plonky3/src/air/graph.rs @@ -14,10 +14,10 @@ impl Codegen for TraceAccess { let frame = self.segment.to_string(); let row_offset = match self.row_offset { 0 => { - format!("current[{}]", self.column) + format!("current[{}].into()", self.column) }, 1 => { - format!("next[{}]", self.column) + format!("next[{}].into()", self.column) }, _ => panic!("Plonky3 doesn't support row offsets greater than 1."), }; @@ -46,7 +46,9 @@ impl Codegen for Operation { impl Codegen for Value { fn to_string(&self, ir: &Air) -> String { match self { - Value::Constant(value) => format!("AB::Expr::from(AB::F::from_u64({value}))"), + Value::Constant(0) => format!("AB::Expr::ZERO"), + Value::Constant(1) => format!("AB::Expr::ONE"), + Value::Constant(value) => format!("AB::Expr::from_u64({value})"), Value::TraceAccess(trace_access) => trace_access.to_string(ir), Value::PublicInput(air_ir::PublicInputAccess { name, index }) => { let get_public_input_offset = |name: &str| { @@ -95,17 +97,25 @@ fn binary_op_to_string(ir: &Air, op: &Operation) -> String { format!("{lhs} - {rhs}") }, Operation::Mul(l_idx, r_idx) => { - let lhs = if ir.constraint_graph().node(l_idx).op().precedence() < op.precedence() { + let lhs_op = ir.constraint_graph().node(l_idx).op(); + let rhs_op = ir.constraint_graph().node(r_idx).op(); + + let lhs = if lhs_op.precedence() < op.precedence() { format!("({})", l_idx.to_string(ir)) } else { l_idx.to_string(ir) }; - let rhs = if ir.constraint_graph().node(r_idx).op().precedence() < op.precedence() { + let rhs = if rhs_op.precedence() < op.precedence() { format!("({})", r_idx.to_string(ir)) } else { r_idx.to_string(ir) }; - format!("{lhs} * {rhs}") + + match (lhs_op, rhs_op) { + (_, Operation::Value(Value::Constant(2))) => format!("{lhs}.double()"), + (Operation::Value(Value::Constant(2)), _) => format!("{rhs}.double()"), + _ => format!("{lhs} * {rhs}"), + } }, _ => panic!("unsupported operation"), } From ab4c4e8dd0ea50b8166c0be1d45f8097f0cdc034 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Tue, 14 Oct 2025 09:49:39 +0200 Subject: [PATCH 14/25] tests: update plonky3 E2E tests following codegen refactor --- air-script/tests/binary/binary_plonky3.rs | 6 ++-- air-script/tests/bitwise/bitwise_plonky3.rs | 36 +++++++++---------- .../tests/buses/buses_complex_plonky3.rs | 6 ++-- .../constant_in_range_plonky3.rs | 4 +-- .../tests/constants/constants_plonky3.rs | 22 ++++++------ .../constraint_comprehension_plonky3.rs | 10 +++--- .../tests/evaluators/evaluators_plonky3.rs | 22 ++++++------ .../tests/fibonacci/fibonacci_plonky3.rs | 10 +++--- .../functions/functions_complex_plonky3.rs | 6 ++-- .../functions/functions_simple_plonky3.rs | 18 +++++----- .../indexed_trace_access_plonky3.rs | 4 +-- .../list_comprehension_nested_plonky3.rs | 8 ++--- .../list_comprehension_plonky3.rs | 14 ++++---- .../list_folding/list_folding_plonky3.rs | 10 +++--- .../periodic_columns_plonky3.rs | 6 ++-- .../tests/pub_inputs/pub_inputs_plonky3.rs | 18 +++++----- .../selectors_combine_complex_plonky3.rs | 8 ++--- .../selectors_combine_simple_plonky3.rs | 6 ++-- ...ombine_with_list_comprehensions_plonky3.rs | 9 +++-- .../tests/selectors/selectors_plonky3.rs | 6 ++-- .../selectors_with_evaluators_plonky3.rs | 6 ++-- air-script/tests/system/system_plonky3.rs | 4 +-- .../trace_col_groups_plonky3.rs | 6 ++-- .../tests/variables/variables_plonky3.rs | 12 +++---- 24 files changed, 128 insertions(+), 129 deletions(-) diff --git a/air-script/tests/binary/binary_plonky3.rs b/air-script/tests/binary/binary_plonky3.rs index 4d89ff939..df44bcb6d 100644 --- a/air-script/tests/binary/binary_plonky3.rs +++ b/air-script/tests/binary/binary_plonky3.rs @@ -37,8 +37,8 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[0] - public_values[0].into()); - builder.assert_zero::<_>(main_current[0] * main_current[0] - main_current[0]); - builder.assert_zero::<_>(main_current[1] * main_current[1] - main_current[1]); + builder.when_first_row().assert_zero::<_>(main_current[0].into() - public_values[0].into()); + builder.assert_zero::<_>(main_current[0].into() * main_current[0].into() - main_current[0].into()); + builder.assert_zero::<_>(main_current[1].into() * main_current[1].into() - main_current[1].into()); } } \ No newline at end of file diff --git a/air-script/tests/bitwise/bitwise_plonky3.rs b/air-script/tests/bitwise/bitwise_plonky3.rs index e67cde192..ef5d5d992 100644 --- a/air-script/tests/bitwise/bitwise_plonky3.rs +++ b/air-script/tests/bitwise/bitwise_plonky3.rs @@ -39,23 +39,23 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[13]); - builder.assert_zero::<_>(main_current[0] * main_current[0] - main_current[0]); - builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[0] - main_current[0])); - builder.assert_zero::<_>(main_current[3] * main_current[3] - main_current[3]); - builder.assert_zero::<_>(main_current[4] * main_current[4] - main_current[4]); - builder.assert_zero::<_>(main_current[5] * main_current[5] - main_current[5]); - builder.assert_zero::<_>(main_current[6] * main_current[6] - main_current[6]); - builder.assert_zero::<_>(main_current[7] * main_current[7] - main_current[7]); - builder.assert_zero::<_>(main_current[8] * main_current[8] - main_current[8]); - builder.assert_zero::<_>(main_current[9] * main_current[9] - main_current[9]); - builder.assert_zero::<_>(main_current[10] * main_current[10] - main_current[10]); - builder.assert_zero::<_>(periodic_values[0].into() * (main_current[1] - (main_current[3] + AB::Expr::from(AB::F::from_u64(2)) * main_current[4] + AB::Expr::from(AB::F::from_u64(4)) * main_current[5] + AB::Expr::from(AB::F::from_u64(8)) * main_current[6]))); - builder.assert_zero::<_>(periodic_values[0].into() * (main_current[2] - (main_current[7] + AB::Expr::from(AB::F::from_u64(2)) * main_current[8] + AB::Expr::from(AB::F::from_u64(4)) * main_current[9] + AB::Expr::from(AB::F::from_u64(8)) * main_current[10]))); - builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[1] - (main_current[1] * AB::Expr::from(AB::F::from_u64(16)) + main_current[3] + AB::Expr::from(AB::F::from_u64(2)) * main_current[4] + AB::Expr::from(AB::F::from_u64(4)) * main_current[5] + AB::Expr::from(AB::F::from_u64(8)) * main_current[6]))); - builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[2] - (main_current[2] * AB::Expr::from(AB::F::from_u64(16)) + main_current[7] + AB::Expr::from(AB::F::from_u64(2)) * main_current[8] + AB::Expr::from(AB::F::from_u64(4)) * main_current[9] + AB::Expr::from(AB::F::from_u64(8)) * main_current[10]))); - builder.assert_zero::<_>(periodic_values[0].into() * main_current[11]); - builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_current[12] - main_next[11])); - builder.assert_zero::<_>((AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * (main_current[12] - (main_current[11] * AB::Expr::from(AB::F::from_u64(16)) + main_current[3] * main_current[7] + AB::Expr::from(AB::F::from_u64(2)) * main_current[4] * main_current[8] + AB::Expr::from(AB::F::from_u64(4)) * main_current[5] * main_current[9] + AB::Expr::from(AB::F::from_u64(8)) * main_current[6] * main_current[10])) + main_current[0] * (main_current[12] - (main_current[11] * AB::Expr::from(AB::F::from_u64(16)) + main_current[3] + main_current[7] - AB::Expr::from(AB::F::from_u64(2)) * main_current[3] * main_current[7] + AB::Expr::from(AB::F::from_u64(2)) * (main_current[4] + main_current[8] - AB::Expr::from(AB::F::from_u64(2)) * main_current[4] * main_current[8]) + AB::Expr::from(AB::F::from_u64(4)) * (main_current[5] + main_current[9] - AB::Expr::from(AB::F::from_u64(2)) * main_current[5] * main_current[9]) + AB::Expr::from(AB::F::from_u64(8)) * (main_current[6] + main_current[10] - AB::Expr::from(AB::F::from_u64(2)) * main_current[6] * main_current[10])))); + builder.when_first_row().assert_zero::<_>(main_current[13].into()); + builder.assert_zero::<_>(main_current[0].into() * main_current[0].into() - main_current[0].into()); + builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[0].into() - main_current[0].into())); + builder.assert_zero::<_>(main_current[3].into() * main_current[3].into() - main_current[3].into()); + builder.assert_zero::<_>(main_current[4].into() * main_current[4].into() - main_current[4].into()); + builder.assert_zero::<_>(main_current[5].into() * main_current[5].into() - main_current[5].into()); + builder.assert_zero::<_>(main_current[6].into() * main_current[6].into() - main_current[6].into()); + builder.assert_zero::<_>(main_current[7].into() * main_current[7].into() - main_current[7].into()); + builder.assert_zero::<_>(main_current[8].into() * main_current[8].into() - main_current[8].into()); + builder.assert_zero::<_>(main_current[9].into() * main_current[9].into() - main_current[9].into()); + builder.assert_zero::<_>(main_current[10].into() * main_current[10].into() - main_current[10].into()); + builder.assert_zero::<_>(periodic_values[0].into() * (main_current[1].into() - (main_current[3].into() + main_current[4].into().double() + AB::Expr::from_u64(4) * main_current[5].into() + AB::Expr::from_u64(8) * main_current[6].into()))); + builder.assert_zero::<_>(periodic_values[0].into() * (main_current[2].into() - (main_current[7].into() + main_current[8].into().double() + AB::Expr::from_u64(4) * main_current[9].into() + AB::Expr::from_u64(8) * main_current[10].into()))); + builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[1].into() - (main_current[1].into() * AB::Expr::from_u64(16) + main_current[3].into() + main_current[4].into().double() + AB::Expr::from_u64(4) * main_current[5].into() + AB::Expr::from_u64(8) * main_current[6].into()))); + builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[2].into() - (main_current[2].into() * AB::Expr::from_u64(16) + main_current[7].into() + main_current[8].into().double() + AB::Expr::from_u64(4) * main_current[9].into() + AB::Expr::from_u64(8) * main_current[10].into()))); + builder.assert_zero::<_>(periodic_values[0].into() * main_current[11].into()); + builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_current[12].into() - main_next[11].into())); + builder.assert_zero::<_>((AB::Expr::ONE - main_current[0].into()) * (main_current[12].into() - (main_current[11].into() * AB::Expr::from_u64(16) + main_current[3].into() * main_current[7].into() + main_current[4].into().double() * main_current[8].into() + AB::Expr::from_u64(4) * main_current[5].into() * main_current[9].into() + AB::Expr::from_u64(8) * main_current[6].into() * main_current[10].into())) + main_current[0].into() * (main_current[12].into() - (main_current[11].into() * AB::Expr::from_u64(16) + main_current[3].into() + main_current[7].into() - main_current[3].into().double() * main_current[7].into() + (main_current[4].into() + main_current[8].into() - main_current[4].into().double() * main_current[8].into()).double() + AB::Expr::from_u64(4) * (main_current[5].into() + main_current[9].into() - main_current[5].into().double() * main_current[9].into()) + AB::Expr::from_u64(8) * (main_current[6].into() + main_current[10].into() - main_current[6].into().double() * main_current[10].into())))); } } \ No newline at end of file diff --git a/air-script/tests/buses/buses_complex_plonky3.rs b/air-script/tests/buses/buses_complex_plonky3.rs index 76905b3a8..462ef499a 100644 --- a/air-script/tests/buses/buses_complex_plonky3.rs +++ b/air-script/tests/buses/buses_complex_plonky3.rs @@ -37,8 +37,8 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[0]); - builder.assert_zero::<_>(main_current[2] * main_current[2] - main_current[2]); - builder.assert_zero::<_>(main_current[3] * main_current[3] - main_current[3]); + builder.when_first_row().assert_zero::<_>(main_current[0].into()); + builder.assert_zero::<_>(main_current[2].into() * main_current[2].into() - main_current[2].into()); + builder.assert_zero::<_>(main_current[3].into() * main_current[3].into() - main_current[3].into()); } } \ No newline at end of file diff --git a/air-script/tests/constant_in_range/constant_in_range_plonky3.rs b/air-script/tests/constant_in_range/constant_in_range_plonky3.rs index 6b23d4b17..5f657e987 100644 --- a/air-script/tests/constant_in_range/constant_in_range_plonky3.rs +++ b/air-script/tests/constant_in_range/constant_in_range_plonky3.rs @@ -37,7 +37,7 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[6]); - builder.assert_zero::<_>(main_current[0] - (main_current[1] - main_current[4] - main_current[8] + AB::Expr::from(AB::F::from_u64(1)) + main_current[2] - main_current[5] - main_current[9] + AB::Expr::from(AB::F::from_u64(2)) + main_current[3] - main_current[6] - main_current[10])); + builder.when_first_row().assert_zero::<_>(main_current[6].into()); + builder.assert_zero::<_>(main_current[0].into() - (main_current[1].into() - main_current[4].into() - main_current[8].into() + AB::Expr::ONE + main_current[2].into() - main_current[5].into() - main_current[9].into() + AB::Expr::from_u64(2) + main_current[3].into() - main_current[6].into() - main_current[10].into())); } } \ No newline at end of file diff --git a/air-script/tests/constants/constants_plonky3.rs b/air-script/tests/constants/constants_plonky3.rs index 9361c0228..fa2ffccac 100644 --- a/air-script/tests/constants/constants_plonky3.rs +++ b/air-script/tests/constants/constants_plonky3.rs @@ -37,16 +37,16 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[0] - AB::Expr::from(AB::F::from_u64(1))); - builder.when_first_row().assert_zero::<_>(main_current[1] - AB::Expr::from(AB::F::from_u64(1))); - builder.when_first_row().assert_zero::<_>(main_current[2]); - builder.when_first_row().assert_zero::<_>(main_current[3] - AB::Expr::from(AB::F::from_u64(1))); - builder.when_first_row().assert_zero::<_>(main_current[4] - AB::Expr::from(AB::F::from_u64(1))); - builder.when_last_row().assert_zero::<_>(main_current[6]); - builder.when_transition().assert_zero::<_>(main_next[0] - (main_current[0] + AB::Expr::from(AB::F::from_u64(1)))); - builder.when_transition().assert_zero::<_>(main_next[1]); - builder.when_transition().assert_zero::<_>(main_next[2] - main_current[2]); - builder.when_transition().assert_zero::<_>(main_next[5] - (main_current[5] + AB::Expr::from(AB::F::from_u64(1)))); - builder.assert_zero::<_>(main_current[4] - AB::Expr::from(AB::F::from_u64(1))); + builder.when_first_row().assert_zero::<_>(main_current[0].into() - AB::Expr::ONE); + builder.when_first_row().assert_zero::<_>(main_current[1].into() - AB::Expr::ONE); + builder.when_first_row().assert_zero::<_>(main_current[2].into()); + builder.when_first_row().assert_zero::<_>(main_current[3].into() - AB::Expr::ONE); + builder.when_first_row().assert_zero::<_>(main_current[4].into() - AB::Expr::ONE); + builder.when_last_row().assert_zero::<_>(main_current[6].into()); + builder.when_transition().assert_zero::<_>(main_next[0].into() - (main_current[0].into() + AB::Expr::ONE)); + builder.when_transition().assert_zero::<_>(main_next[1].into()); + builder.when_transition().assert_zero::<_>(main_next[2].into() - main_current[2].into()); + builder.when_transition().assert_zero::<_>(main_next[5].into() - (main_current[5].into() + AB::Expr::ONE)); + builder.assert_zero::<_>(main_current[4].into() - AB::Expr::ONE); } } \ No newline at end of file diff --git a/air-script/tests/constraint_comprehension/constraint_comprehension_plonky3.rs b/air-script/tests/constraint_comprehension/constraint_comprehension_plonky3.rs index ef6d701c1..b501fe9d3 100644 --- a/air-script/tests/constraint_comprehension/constraint_comprehension_plonky3.rs +++ b/air-script/tests/constraint_comprehension/constraint_comprehension_plonky3.rs @@ -37,10 +37,10 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[8]); - builder.assert_zero::<_>(main_current[6] - main_current[10]); - builder.assert_zero::<_>(main_current[7] - main_current[11]); - builder.assert_zero::<_>(main_current[8] - main_current[12]); - builder.assert_zero::<_>(main_current[9] - main_current[13]); + builder.when_first_row().assert_zero::<_>(main_current[8].into()); + builder.assert_zero::<_>(main_current[6].into() - main_current[10].into()); + builder.assert_zero::<_>(main_current[7].into() - main_current[11].into()); + builder.assert_zero::<_>(main_current[8].into() - main_current[12].into()); + builder.assert_zero::<_>(main_current[9].into() - main_current[13].into()); } } \ No newline at end of file diff --git a/air-script/tests/evaluators/evaluators_plonky3.rs b/air-script/tests/evaluators/evaluators_plonky3.rs index 046eb2a1f..becb57b5a 100644 --- a/air-script/tests/evaluators/evaluators_plonky3.rs +++ b/air-script/tests/evaluators/evaluators_plonky3.rs @@ -37,16 +37,16 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[0]); - builder.when_transition().assert_zero::<_>(main_next[0] - main_current[0]); - builder.when_transition().assert_zero::<_>(main_next[2] - main_current[2]); - builder.when_transition().assert_zero::<_>(main_next[6] - main_current[6]); - builder.assert_zero::<_>(main_current[0] * main_current[0] - main_current[0]); - builder.assert_zero::<_>(main_current[1] * main_current[1] - main_current[1]); - builder.assert_zero::<_>(main_current[2] * main_current[2] - main_current[2]); - builder.assert_zero::<_>(main_current[3] * main_current[3] - main_current[3]); - builder.assert_zero::<_>(main_current[4]); - builder.assert_zero::<_>(main_current[5] - AB::Expr::from(AB::F::from_u64(1))); - builder.assert_zero::<_>(main_current[6] - AB::Expr::from(AB::F::from_u64(4))); + builder.when_first_row().assert_zero::<_>(main_current[0].into()); + builder.when_transition().assert_zero::<_>(main_next[0].into() - main_current[0].into()); + builder.when_transition().assert_zero::<_>(main_next[2].into() - main_current[2].into()); + builder.when_transition().assert_zero::<_>(main_next[6].into() - main_current[6].into()); + builder.assert_zero::<_>(main_current[0].into() * main_current[0].into() - main_current[0].into()); + builder.assert_zero::<_>(main_current[1].into() * main_current[1].into() - main_current[1].into()); + builder.assert_zero::<_>(main_current[2].into() * main_current[2].into() - main_current[2].into()); + builder.assert_zero::<_>(main_current[3].into() * main_current[3].into() - main_current[3].into()); + builder.assert_zero::<_>(main_current[4].into()); + builder.assert_zero::<_>(main_current[5].into() - AB::Expr::ONE); + builder.assert_zero::<_>(main_current[6].into() - AB::Expr::from_u64(4)); } } \ No newline at end of file diff --git a/air-script/tests/fibonacci/fibonacci_plonky3.rs b/air-script/tests/fibonacci/fibonacci_plonky3.rs index a00d0c1a1..262dbb610 100644 --- a/air-script/tests/fibonacci/fibonacci_plonky3.rs +++ b/air-script/tests/fibonacci/fibonacci_plonky3.rs @@ -37,10 +37,10 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[0] - public_values[0].into()); - builder.when_first_row().assert_zero::<_>(main_current[1] - public_values[1].into()); - builder.when_last_row().assert_zero::<_>(main_current[1] - public_values[2].into()); - builder.when_transition().assert_zero::<_>(main_next[1] - (main_current[0] + main_current[1])); - builder.when_transition().assert_zero::<_>(main_next[0] - main_current[1]); + builder.when_first_row().assert_zero::<_>(main_current[0].into() - public_values[0].into()); + builder.when_first_row().assert_zero::<_>(main_current[1].into() - public_values[1].into()); + builder.when_last_row().assert_zero::<_>(main_current[1].into() - public_values[2].into()); + builder.when_transition().assert_zero::<_>(main_next[1].into() - (main_current[0].into() + main_current[1].into())); + builder.when_transition().assert_zero::<_>(main_next[0].into() - main_current[1].into()); } } \ No newline at end of file diff --git a/air-script/tests/functions/functions_complex_plonky3.rs b/air-script/tests/functions/functions_complex_plonky3.rs index 014020bd9..cca15366b 100644 --- a/air-script/tests/functions/functions_complex_plonky3.rs +++ b/air-script/tests/functions/functions_complex_plonky3.rs @@ -37,8 +37,8 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[3]); - builder.when_transition().assert_zero::<_>(main_next[16] - main_current[16] * ((main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[1] * main_current[2] + main_current[3] * main_current[3] * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * main_current[2] + main_current[3] * main_current[1] * (AB::Expr::from(AB::F::from_u64(1)) - main_current[2]) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[2])) * main_current[0] - main_current[0] + AB::Expr::from(AB::F::from_u64(1)))); - builder.when_transition().assert_zero::<_>(main_next[3] - (main_current[4] + main_current[5] + main_current[6] + main_current[7] + main_current[8] + main_current[9] + main_current[10] + main_current[11] + main_current[12] + main_current[13] + main_current[14] + main_current[15] + AB::Expr::from(AB::F::from_u64(1))) * AB::Expr::from(AB::F::from_u64(2))); + builder.when_first_row().assert_zero::<_>(main_current[3].into()); + builder.when_transition().assert_zero::<_>(main_next[16].into() - main_current[16].into() * ((main_current[3].into() * main_current[3].into() * main_current[3].into() * main_current[3].into() * main_current[3].into() * main_current[3].into() * main_current[3].into() * main_current[1].into() * main_current[2].into() + main_current[3].into() * main_current[3].into() * (AB::Expr::ONE - main_current[1].into()) * main_current[2].into() + main_current[3].into() * main_current[1].into() * (AB::Expr::ONE - main_current[2].into()) + (AB::Expr::ONE - main_current[1].into()) * (AB::Expr::ONE - main_current[2].into())) * main_current[0].into() - main_current[0].into() + AB::Expr::ONE)); + builder.when_transition().assert_zero::<_>(main_next[3].into() - (main_current[4].into() + main_current[5].into() + main_current[6].into() + main_current[7].into() + main_current[8].into() + main_current[9].into() + main_current[10].into() + main_current[11].into() + main_current[12].into() + main_current[13].into() + main_current[14].into() + main_current[15].into() + AB::Expr::ONE).double()); } } \ No newline at end of file diff --git a/air-script/tests/functions/functions_simple_plonky3.rs b/air-script/tests/functions/functions_simple_plonky3.rs index 2702a6f56..7d19e8a4b 100644 --- a/air-script/tests/functions/functions_simple_plonky3.rs +++ b/air-script/tests/functions/functions_simple_plonky3.rs @@ -37,14 +37,14 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[3]); - builder.assert_zero::<_>(main_current[0] * main_current[3] - AB::Expr::from(AB::F::from_u64(1))); - builder.assert_zero::<_>(main_current[4] * main_current[5] * main_current[6] * main_current[7] * main_current[3] - AB::Expr::from(AB::F::from_u64(1))); - builder.assert_zero::<_>((main_current[4] + main_current[5] + main_current[6] + main_current[7]) * main_current[4] * main_current[5] * main_current[6] * main_current[7] - AB::Expr::from(AB::F::from_u64(1))); - builder.assert_zero::<_>(main_current[4] * main_current[5] * main_current[6] * main_current[7] - AB::Expr::from(AB::F::from_u64(1))); - builder.assert_zero::<_>(main_current[0] * main_current[4] * main_current[5] * main_current[6] * main_current[7] - AB::Expr::from(AB::F::from_u64(1))); - builder.assert_zero::<_>(main_current[1] + (main_current[4] + main_current[5] + main_current[6] + main_current[7]) * main_current[4] * main_current[5] * main_current[6] * main_current[7] - AB::Expr::from(AB::F::from_u64(1))); - builder.assert_zero::<_>(main_current[4] + main_current[5] + main_current[6] + main_current[7] - AB::Expr::from(AB::F::from_u64(1))); - builder.assert_zero::<_>((main_current[4] + main_current[5] + main_current[6] + main_current[7]) * AB::Expr::from(AB::F::from_u64(4)) - AB::Expr::from(AB::F::from_u64(1))); + builder.when_first_row().assert_zero::<_>(main_current[3].into()); + builder.assert_zero::<_>(main_current[0].into() * main_current[3].into() - AB::Expr::ONE); + builder.assert_zero::<_>(main_current[4].into() * main_current[5].into() * main_current[6].into() * main_current[7].into() * main_current[3].into() - AB::Expr::ONE); + builder.assert_zero::<_>((main_current[4].into() + main_current[5].into() + main_current[6].into() + main_current[7].into()) * main_current[4].into() * main_current[5].into() * main_current[6].into() * main_current[7].into() - AB::Expr::ONE); + builder.assert_zero::<_>(main_current[4].into() * main_current[5].into() * main_current[6].into() * main_current[7].into() - AB::Expr::ONE); + builder.assert_zero::<_>(main_current[0].into() * main_current[4].into() * main_current[5].into() * main_current[6].into() * main_current[7].into() - AB::Expr::ONE); + builder.assert_zero::<_>(main_current[1].into() + (main_current[4].into() + main_current[5].into() + main_current[6].into() + main_current[7].into()) * main_current[4].into() * main_current[5].into() * main_current[6].into() * main_current[7].into() - AB::Expr::ONE); + builder.assert_zero::<_>(main_current[4].into() + main_current[5].into() + main_current[6].into() + main_current[7].into() - AB::Expr::ONE); + builder.assert_zero::<_>((main_current[4].into() + main_current[5].into() + main_current[6].into() + main_current[7].into()) * AB::Expr::from_u64(4) - AB::Expr::ONE); } } \ No newline at end of file diff --git a/air-script/tests/indexed_trace_access/indexed_trace_access_plonky3.rs b/air-script/tests/indexed_trace_access/indexed_trace_access_plonky3.rs index c4fa5cd08..0bd768900 100644 --- a/air-script/tests/indexed_trace_access/indexed_trace_access_plonky3.rs +++ b/air-script/tests/indexed_trace_access/indexed_trace_access_plonky3.rs @@ -37,7 +37,7 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[0]); - builder.when_transition().assert_zero::<_>(main_next[0] - (main_current[1] + AB::Expr::from(AB::F::from_u64(1)))); + builder.when_first_row().assert_zero::<_>(main_current[0].into()); + builder.when_transition().assert_zero::<_>(main_next[0].into() - (main_current[1].into() + AB::Expr::ONE)); } } \ No newline at end of file diff --git a/air-script/tests/list_comprehension/list_comprehension_nested_plonky3.rs b/air-script/tests/list_comprehension/list_comprehension_nested_plonky3.rs index 990eb5946..2a8b9181f 100644 --- a/air-script/tests/list_comprehension/list_comprehension_nested_plonky3.rs +++ b/air-script/tests/list_comprehension/list_comprehension_nested_plonky3.rs @@ -37,9 +37,9 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[0]); - builder.assert_zero::<_>(main_current[0] + main_current[1] * AB::Expr::from(AB::F::from_u64(2)) - AB::Expr::from(AB::F::from_u64(3))); - builder.assert_zero::<_>(main_current[0] * AB::Expr::from(AB::F::from_u64(2)) + main_current[1] * AB::Expr::from(AB::F::from_u64(3)) - AB::Expr::from(AB::F::from_u64(5))); - builder.assert_zero::<_>(main_current[0] * AB::Expr::from(AB::F::from_u64(3)) + main_current[1] * AB::Expr::from(AB::F::from_u64(4)) - AB::Expr::from(AB::F::from_u64(7))); + builder.when_first_row().assert_zero::<_>(main_current[0].into()); + builder.assert_zero::<_>(main_current[0].into() + main_current[1].into().double() - AB::Expr::from_u64(3)); + builder.assert_zero::<_>(main_current[0].into().double() + main_current[1].into() * AB::Expr::from_u64(3) - AB::Expr::from_u64(5)); + builder.assert_zero::<_>(main_current[0].into() * AB::Expr::from_u64(3) + main_current[1].into() * AB::Expr::from_u64(4) - AB::Expr::from_u64(7)); } } \ No newline at end of file diff --git a/air-script/tests/list_comprehension/list_comprehension_plonky3.rs b/air-script/tests/list_comprehension/list_comprehension_plonky3.rs index 519559827..b2133e873 100644 --- a/air-script/tests/list_comprehension/list_comprehension_plonky3.rs +++ b/air-script/tests/list_comprehension/list_comprehension_plonky3.rs @@ -37,12 +37,12 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[10]); - builder.assert_zero::<_>(main_current[0] - main_current[2]); - builder.assert_zero::<_>(main_current[4] - main_current[0] * AB::Expr::from(AB::F::from_u64(8)) * main_current[11]); - builder.when_transition().assert_zero::<_>(main_current[4] - main_current[0] * (main_next[8] - main_next[12])); - builder.assert_zero::<_>(main_current[6] - main_current[0] * (main_current[9] - main_current[14])); - builder.assert_zero::<_>(main_current[1] - (main_current[5] - main_current[8] - main_current[12] + AB::Expr::from(AB::F::from_u64(10)) + main_current[6] - main_current[9] - main_current[13] + AB::Expr::from(AB::F::from_u64(20)) + main_current[7] - main_current[10] - main_current[14])); - builder.assert_zero::<_>(main_current[14] - AB::Expr::from(AB::F::from_u64(10))); + builder.when_first_row().assert_zero::<_>(main_current[10].into()); + builder.assert_zero::<_>(main_current[0].into() - main_current[2].into()); + builder.assert_zero::<_>(main_current[4].into() - main_current[0].into() * AB::Expr::from_u64(8) * main_current[11].into()); + builder.when_transition().assert_zero::<_>(main_current[4].into() - main_current[0].into() * (main_next[8].into() - main_next[12].into())); + builder.assert_zero::<_>(main_current[6].into() - main_current[0].into() * (main_current[9].into() - main_current[14].into())); + builder.assert_zero::<_>(main_current[1].into() - (main_current[5].into() - main_current[8].into() - main_current[12].into() + AB::Expr::from_u64(10) + main_current[6].into() - main_current[9].into() - main_current[13].into() + AB::Expr::from_u64(20) + main_current[7].into() - main_current[10].into() - main_current[14].into())); + builder.assert_zero::<_>(main_current[14].into() - AB::Expr::from_u64(10)); } } \ No newline at end of file diff --git a/air-script/tests/list_folding/list_folding_plonky3.rs b/air-script/tests/list_folding/list_folding_plonky3.rs index 1c4f68dca..c1cd5e912 100644 --- a/air-script/tests/list_folding/list_folding_plonky3.rs +++ b/air-script/tests/list_folding/list_folding_plonky3.rs @@ -37,10 +37,10 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[11]); - builder.when_transition().assert_zero::<_>(main_next[5] - (main_current[9] + main_current[10] + main_current[11] + main_current[12] + main_current[13] * main_current[14] * main_current[15] * main_current[16])); - builder.when_transition().assert_zero::<_>(main_next[6] - (main_current[9] + main_current[10] + main_current[11] + main_current[12] + main_current[13] * main_current[14] * main_current[15] * main_current[16])); - builder.when_transition().assert_zero::<_>(main_next[7] - (main_current[9] * main_current[13] + main_current[10] * main_current[14] + main_current[11] * main_current[15] + main_current[12] * main_current[16] + (main_current[9] + main_current[13]) * (main_current[10] + main_current[14]) * (main_current[11] + main_current[15]) * (main_current[12] + main_current[16]))); - builder.when_transition().assert_zero::<_>(main_next[8] - (main_current[1] + main_current[9] * main_current[13] + main_current[10] * main_current[14] + main_current[11] * main_current[15] + main_current[12] * main_current[16] + main_current[9] * main_current[13] + main_current[10] * main_current[14] + main_current[11] * main_current[15] + main_current[12] * main_current[16])); + builder.when_first_row().assert_zero::<_>(main_current[11].into()); + builder.when_transition().assert_zero::<_>(main_next[5].into() - (main_current[9].into() + main_current[10].into() + main_current[11].into() + main_current[12].into() + main_current[13].into() * main_current[14].into() * main_current[15].into() * main_current[16].into())); + builder.when_transition().assert_zero::<_>(main_next[6].into() - (main_current[9].into() + main_current[10].into() + main_current[11].into() + main_current[12].into() + main_current[13].into() * main_current[14].into() * main_current[15].into() * main_current[16].into())); + builder.when_transition().assert_zero::<_>(main_next[7].into() - (main_current[9].into() * main_current[13].into() + main_current[10].into() * main_current[14].into() + main_current[11].into() * main_current[15].into() + main_current[12].into() * main_current[16].into() + (main_current[9].into() + main_current[13].into()) * (main_current[10].into() + main_current[14].into()) * (main_current[11].into() + main_current[15].into()) * (main_current[12].into() + main_current[16].into()))); + builder.when_transition().assert_zero::<_>(main_next[8].into() - (main_current[1].into() + main_current[9].into() * main_current[13].into() + main_current[10].into() * main_current[14].into() + main_current[11].into() * main_current[15].into() + main_current[12].into() * main_current[16].into() + main_current[9].into() * main_current[13].into() + main_current[10].into() * main_current[14].into() + main_current[11].into() * main_current[15].into() + main_current[12].into() * main_current[16].into())); } } \ No newline at end of file diff --git a/air-script/tests/periodic_columns/periodic_columns_plonky3.rs b/air-script/tests/periodic_columns/periodic_columns_plonky3.rs index 9eb4f5447..fb42592e1 100644 --- a/air-script/tests/periodic_columns/periodic_columns_plonky3.rs +++ b/air-script/tests/periodic_columns/periodic_columns_plonky3.rs @@ -39,8 +39,8 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[0]); - builder.assert_zero::<_>(periodic_values[0].into() * (main_current[1] + main_current[2])); - builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[0] - main_current[0])); + builder.when_first_row().assert_zero::<_>(main_current[0].into()); + builder.assert_zero::<_>(periodic_values[0].into() * (main_current[1].into() + main_current[2].into())); + builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[0].into() - main_current[0].into())); } } \ No newline at end of file diff --git a/air-script/tests/pub_inputs/pub_inputs_plonky3.rs b/air-script/tests/pub_inputs/pub_inputs_plonky3.rs index a34e8aca4..cb2ac03b7 100644 --- a/air-script/tests/pub_inputs/pub_inputs_plonky3.rs +++ b/air-script/tests/pub_inputs/pub_inputs_plonky3.rs @@ -37,14 +37,14 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[0] - public_values[8].into()); - builder.when_first_row().assert_zero::<_>(main_current[1] - public_values[9].into()); - builder.when_first_row().assert_zero::<_>(main_current[2] - public_values[10].into()); - builder.when_first_row().assert_zero::<_>(main_current[3] - public_values[11].into()); - builder.when_last_row().assert_zero::<_>(main_current[0] - public_values[12].into()); - builder.when_last_row().assert_zero::<_>(main_current[1] - public_values[13].into()); - builder.when_last_row().assert_zero::<_>(main_current[2] - public_values[14].into()); - builder.when_last_row().assert_zero::<_>(main_current[3] - public_values[15].into()); - builder.when_transition().assert_zero::<_>(main_next[0] - (main_current[1] + main_current[2])); + builder.when_first_row().assert_zero::<_>(main_current[0].into() - public_values[8].into()); + builder.when_first_row().assert_zero::<_>(main_current[1].into() - public_values[9].into()); + builder.when_first_row().assert_zero::<_>(main_current[2].into() - public_values[10].into()); + builder.when_first_row().assert_zero::<_>(main_current[3].into() - public_values[11].into()); + builder.when_last_row().assert_zero::<_>(main_current[0].into() - public_values[12].into()); + builder.when_last_row().assert_zero::<_>(main_current[1].into() - public_values[13].into()); + builder.when_last_row().assert_zero::<_>(main_current[2].into() - public_values[14].into()); + builder.when_last_row().assert_zero::<_>(main_current[3].into() - public_values[15].into()); + builder.when_transition().assert_zero::<_>(main_next[0].into() - (main_current[1].into() + main_current[2].into())); } } \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_combine_complex_plonky3.rs b/air-script/tests/selectors/selectors_combine_complex_plonky3.rs index 5db82c3d8..c8115936b 100644 --- a/air-script/tests/selectors/selectors_combine_complex_plonky3.rs +++ b/air-script/tests/selectors/selectors_combine_complex_plonky3.rs @@ -37,9 +37,9 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[5]); - builder.assert_zero::<_>((main_current[0] + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * main_current[1]) * (main_current[3] - AB::Expr::from(AB::F::from_u64(16))) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (main_current[4] - AB::Expr::from(AB::F::from_u64(5)))); - builder.assert_zero::<_>((AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * (main_current[5] - AB::Expr::from(AB::F::from_u64(5))) + main_current[0] * (main_current[4] - AB::Expr::from(AB::F::from_u64(4)))); - builder.assert_zero::<_>(main_current[0] * (main_current[5] - AB::Expr::from(AB::F::from_u64(20))) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * main_current[1] * (main_current[4] - AB::Expr::from(AB::F::from_u64(31)))); + builder.when_first_row().assert_zero::<_>(main_current[5].into()); + builder.assert_zero::<_>((main_current[0].into() + (AB::Expr::ONE - main_current[0].into()) * main_current[1].into()) * (main_current[3].into() - AB::Expr::from_u64(16)) + (AB::Expr::ONE - main_current[0].into()) * (AB::Expr::ONE - main_current[1].into()) * (main_current[4].into() - AB::Expr::from_u64(5))); + builder.assert_zero::<_>((AB::Expr::ONE - main_current[0].into()) * (main_current[5].into() - AB::Expr::from_u64(5)) + main_current[0].into() * (main_current[4].into() - AB::Expr::from_u64(4))); + builder.assert_zero::<_>(main_current[0].into() * (main_current[5].into() - AB::Expr::from_u64(20)) + (AB::Expr::ONE - main_current[0].into()) * main_current[1].into() * (main_current[4].into() - AB::Expr::from_u64(31))); } } \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_combine_simple_plonky3.rs b/air-script/tests/selectors/selectors_combine_simple_plonky3.rs index de42005a7..c981e950b 100644 --- a/air-script/tests/selectors/selectors_combine_simple_plonky3.rs +++ b/air-script/tests/selectors/selectors_combine_simple_plonky3.rs @@ -37,8 +37,8 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[3]); - builder.when_transition().assert_zero::<_>(main_next[1] - main_current[2]); - builder.when_transition().assert_zero::<_>(main_current[3] * (main_next[0] - (main_current[0] + main_current[1])) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[3]) * (main_next[0] - main_current[0] * main_current[1])); + builder.when_first_row().assert_zero::<_>(main_current[3].into()); + builder.when_transition().assert_zero::<_>(main_next[1].into() - main_current[2].into()); + builder.when_transition().assert_zero::<_>(main_current[3].into() * (main_next[0].into() - (main_current[0].into() + main_current[1].into())) + (AB::Expr::ONE - main_current[3].into()) * (main_next[0].into() - main_current[0].into() * main_current[1].into())); } } \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs b/air-script/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs index 0f5f4f571..1a937a640 100644 --- a/air-script/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs +++ b/air-script/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs @@ -37,10 +37,9 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[5]); - builder.assert_zero::<_>(main_current[0] * main_current[3] + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * main_current[1] * main_current[3] + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (main_current[4] - AB::Expr::from(AB::F::from_u64(8)))); - builder.assert_zero::<_>(main_current[0] * (main_current[4] - AB::Expr::from(AB::F::from_u64(2))) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * main_current[1] * (main_current[4] - AB::Expr::from(AB::F::from_u64(6))) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (main_current[5] - AB::Expr::from(AB::F::from_u64(8)))); - builder.assert_zero::<_>(main_current[0] * main_current[3] + (AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * main_current[1] * (main_current[5] - AB::Expr::from(AB::F::from_u64(8)))); - builder.assert_zero::<_>(main_current[0] * (main_current[5] - AB::Expr::from(AB::F::from_u64(4)))); + builder.when_first_row().assert_zero::<_>(main_current[5].into()); + builder.assert_zero::<_>((main_current[0].into() + (AB::Expr::ONE - main_current[0].into()) * main_current[1].into()) * main_current[3].into() + (AB::Expr::ONE - main_current[0].into()) * (AB::Expr::ONE - main_current[1].into()) * (main_current[4].into() - AB::Expr::from_u64(8))); + builder.assert_zero::<_>((AB::Expr::ONE - main_current[0].into()) * (main_current[5].into() - AB::Expr::from_u64(8)) + main_current[0].into() * (main_current[4].into() - AB::Expr::from_u64(2))); + builder.assert_zero::<_>(main_current[0].into() * (main_current[5].into() - AB::Expr::from_u64(4)) + (AB::Expr::ONE - main_current[0].into()) * main_current[1].into() * (main_current[4].into() - AB::Expr::from_u64(6))); } } \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_plonky3.rs b/air-script/tests/selectors/selectors_plonky3.rs index 9f0ff795b..7b0b2f210 100644 --- a/air-script/tests/selectors/selectors_plonky3.rs +++ b/air-script/tests/selectors/selectors_plonky3.rs @@ -37,8 +37,8 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[3]); - builder.when_transition().assert_zero::<_>(main_current[0] * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * main_next[3]); - builder.when_transition().assert_zero::<_>(main_current[0] * main_current[1] * main_current[2] * (main_next[3] - main_current[3]) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[2]) * (main_next[3] - AB::Expr::from(AB::F::from_u64(1)))); + builder.when_first_row().assert_zero::<_>(main_current[3].into()); + builder.when_transition().assert_zero::<_>(main_current[0].into() * (AB::Expr::ONE - main_current[1].into()) * main_next[3].into()); + builder.when_transition().assert_zero::<_>(main_current[0].into() * main_current[1].into() * main_current[2].into() * (main_next[3].into() - main_current[3].into()) + (AB::Expr::ONE - main_current[1].into()) * (AB::Expr::ONE - main_current[2].into()) * (main_next[3].into() - AB::Expr::ONE)); } } \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_with_evaluators_plonky3.rs b/air-script/tests/selectors/selectors_with_evaluators_plonky3.rs index 1dd734eec..10fd5fb98 100644 --- a/air-script/tests/selectors/selectors_with_evaluators_plonky3.rs +++ b/air-script/tests/selectors/selectors_with_evaluators_plonky3.rs @@ -37,8 +37,8 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[3]); - builder.when_transition().assert_zero::<_>(main_current[0] * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * main_next[3]); - builder.when_transition().assert_zero::<_>(main_current[1] * main_current[2] * main_current[0] * (main_next[3] - main_current[3]) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[2]) * (main_next[3] - AB::Expr::from(AB::F::from_u64(1)))); + builder.when_first_row().assert_zero::<_>(main_current[3].into()); + builder.when_transition().assert_zero::<_>(main_current[0].into() * (AB::Expr::ONE - main_current[1].into()) * main_next[3].into()); + builder.when_transition().assert_zero::<_>(main_current[1].into() * main_current[2].into() * main_current[0].into() * (main_next[3].into() - main_current[3].into()) + (AB::Expr::ONE - main_current[1].into()) * (AB::Expr::ONE - main_current[2].into()) * (main_next[3].into() - AB::Expr::ONE)); } } \ No newline at end of file diff --git a/air-script/tests/system/system_plonky3.rs b/air-script/tests/system/system_plonky3.rs index 10af52c3a..ca2204da0 100644 --- a/air-script/tests/system/system_plonky3.rs +++ b/air-script/tests/system/system_plonky3.rs @@ -37,7 +37,7 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[0]); - builder.when_transition().assert_zero::<_>(main_next[0] - (main_current[0] + AB::Expr::from(AB::F::from_u64(1)))); + builder.when_first_row().assert_zero::<_>(main_current[0].into()); + builder.when_transition().assert_zero::<_>(main_next[0].into() - (main_current[0].into() + AB::Expr::ONE)); } } \ No newline at end of file diff --git a/air-script/tests/trace_col_groups/trace_col_groups_plonky3.rs b/air-script/tests/trace_col_groups/trace_col_groups_plonky3.rs index bb500087e..08bf27975 100644 --- a/air-script/tests/trace_col_groups/trace_col_groups_plonky3.rs +++ b/air-script/tests/trace_col_groups/trace_col_groups_plonky3.rs @@ -37,8 +37,8 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[8]); - builder.when_transition().assert_zero::<_>(main_next[2] - (main_current[2] + AB::Expr::from(AB::F::from_u64(1)))); - builder.when_transition().assert_zero::<_>(main_next[1] - (main_current[1] - AB::Expr::from(AB::F::from_u64(1)))); + builder.when_first_row().assert_zero::<_>(main_current[8].into()); + builder.when_transition().assert_zero::<_>(main_next[2].into() - (main_current[2].into() + AB::Expr::ONE)); + builder.when_transition().assert_zero::<_>(main_next[1].into() - (main_current[1].into() - AB::Expr::ONE)); } } \ No newline at end of file diff --git a/air-script/tests/variables/variables_plonky3.rs b/air-script/tests/variables/variables_plonky3.rs index 73408ce98..48ce365c8 100644 --- a/air-script/tests/variables/variables_plonky3.rs +++ b/air-script/tests/variables/variables_plonky3.rs @@ -38,11 +38,11 @@ impl Air for main.row_slice(0).unwrap(), main.row_slice(1).unwrap(), ); - builder.when_first_row().assert_zero::<_>(main_current[1]); - builder.when_last_row().assert_zero::<_>(main_current[1] - AB::Expr::from(AB::F::from_u64(1))); - builder.assert_zero::<_>(main_current[0] * main_current[0] - main_current[0]); - builder.when_transition().assert_zero::<_>(periodic_values[0].into() * (main_next[0] - main_current[0])); - builder.assert_zero::<_>((AB::Expr::from(AB::F::from_u64(1)) - main_current[0]) * (main_current[3] - main_current[1] - main_current[2]) - (AB::Expr::from(AB::F::from_u64(6)) - (AB::Expr::from(AB::F::from_u64(7)) - main_current[0]))); - builder.when_transition().assert_zero::<_>(main_current[0] * (main_current[3] - main_current[1] * main_current[2]) - (AB::Expr::from(AB::F::from_u64(1)) - main_next[0])); + builder.when_first_row().assert_zero::<_>(main_current[1].into()); + builder.when_last_row().assert_zero::<_>(main_current[1].into() - AB::Expr::ONE); + builder.assert_zero::<_>(main_current[0].into() * main_current[0].into() - main_current[0].into()); + builder.when_transition().assert_zero::<_>(periodic_values[0].into() * (main_next[0].into() - main_current[0].into())); + builder.assert_zero::<_>((AB::Expr::ONE - main_current[0].into()) * (main_current[3].into() - main_current[1].into() - main_current[2].into()) - (AB::Expr::from_u64(6) - (AB::Expr::from_u64(7) - main_current[0].into()))); + builder.when_transition().assert_zero::<_>(main_current[0].into() * (main_current[3].into() - main_current[1].into() * main_current[2].into()) - (AB::Expr::ONE - main_next[0].into())); } } \ No newline at end of file From dee6af7b216e9b3495c7e912166c1370e7f7415b Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Tue, 14 Oct 2025 11:15:17 +0200 Subject: [PATCH 15/25] refactor(tests): Use macro for plonky3 test boilerplate --- air-script/tests/binary/test_air_plonky3.rs | 45 ++------------ .../tests/binary/test_air_winterfell.rs | 9 ++- air-script/tests/bitwise/test_air_plonky3.rs | 45 ++------------ .../tests/bitwise/test_air_winterfell.rs | 9 ++- air-script/tests/buses/test_air_plonky3.rs | 39 ++---------- air-script/tests/buses/test_air_winterfell.rs | 9 ++- .../constant_in_range/test_air_plonky3.rs | 39 ++---------- .../constant_in_range/test_air_winterfell.rs | 4 +- .../tests/constants/test_air_plonky3.rs | 39 ++---------- .../tests/constants/test_air_winterfell.rs | 4 +- .../test_air_plonky3.rs | 39 ++---------- .../test_air_winterfell.rs | 4 +- .../tests/evaluators/test_air_plonky3.rs | 39 ++---------- .../tests/evaluators/test_air_winterfell.rs | 4 +- .../tests/fibonacci/test_air_plonky3.rs | 40 ++---------- .../tests/fibonacci/test_air_winterfell.rs | 4 +- .../tests/functions/test_air_plonky3.rs | 39 ++---------- .../tests/functions/test_air_winterfell.rs | 4 +- air-script/tests/helpers/macros.rs | 61 ++++++++++++++++++- .../indexed_trace_access/test_air_plonky3.rs | 39 ++---------- .../test_air_winterfell.rs | 4 +- .../list_comprehension/test_air_plonky3.rs | 38 ++---------- .../list_comprehension/test_air_winterfell.rs | 4 +- .../tests/list_folding/test_air_plonky3.rs | 39 ++---------- .../tests/list_folding/test_air_winterfell.rs | 4 +- .../periodic_columns/test_air_plonky3.rs | 39 ++---------- .../periodic_columns/test_air_winterfell.rs | 4 +- .../tests/pub_inputs/test_air_plonky3.rs | 39 ++---------- .../tests/pub_inputs/test_air_winterfell.rs | 4 +- .../tests/selectors/test_air_plonky3.rs | 39 ++---------- .../tests/selectors/test_air_winterfell.rs | 4 +- air-script/tests/system/test_air_plonky3.rs | 39 ++---------- .../tests/system/test_air_winterfell.rs | 9 ++- .../trace_col_groups/test_air_plonky3.rs | 39 ++---------- .../trace_col_groups/test_air_winterfell.rs | 4 +- .../tests/variables/test_air_plonky3.rs | 39 ++---------- .../tests/variables/test_air_winterfell.rs | 4 +- 37 files changed, 203 insertions(+), 664 deletions(-) diff --git a/air-script/tests/binary/test_air_plonky3.rs b/air-script/tests/binary/test_air_plonky3.rs index da7b12a53..ac4e20894 100644 --- a/air-script/tests/binary/test_air_plonky3.rs +++ b/air-script/tests/binary/test_air_plonky3.rs @@ -14,6 +14,7 @@ use p3_uni_stark::StarkConfig; use crate::{ binary::binary_plonky3::{BinaryAir, NUM_COLUMNS}, + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, }; @@ -47,44 +48,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&BinaryAir {}, &trace, &inputs_m31); - - /*let prove_with_periodic_columns = prove_with_periodic_columns(&config, &BinaryAir {}, trace, &inputs_m31); - verify_with_periodic_columns(&config, &BinaryAir {}, &prove_with_periodic_columns, &inputs_m31).expect("Verification failed");*/ - - /*let proof = prove(&config, &BinaryAir {}, trace, &inputs_m31); - verify(&config, &BinaryAir {}, &proof, &inputs_m31).expect("Verification failed");*/ +fn generate_inputs() -> Vec { + vec![1; 16] } + +generate_air_plonky3_test!(test_air_plonky3, BinaryAir); diff --git a/air-script/tests/binary/test_air_winterfell.rs b/air-script/tests/binary/test_air_winterfell.rs index 4f40af405..eca996b11 100644 --- a/air-script/tests/binary/test_air_winterfell.rs +++ b/air-script/tests/binary/test_air_winterfell.rs @@ -4,7 +4,7 @@ use winterfell::{Trace, TraceTable}; use crate::{ binary::binary::PublicInputs, - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, }; @@ -39,4 +39,9 @@ impl AirTester for BinaryAirTester { } } -generate_air_test!(test_binary_air, crate::binary::binary::BinaryAir, BinaryAirTester, 1024); +generate_air_winterfell_test!( + test_binary_air, + crate::binary::binary::BinaryAir, + BinaryAirTester, + 1024 +); diff --git a/air-script/tests/bitwise/test_air_plonky3.rs b/air-script/tests/bitwise/test_air_plonky3.rs index c5c30ed7e..1bb3a9f89 100644 --- a/air-script/tests/bitwise/test_air_plonky3.rs +++ b/air-script/tests/bitwise/test_air_plonky3.rs @@ -14,6 +14,7 @@ use p3_uni_stark::StarkConfig; use crate::{ bitwise::bitwise_plonky3::{BitwiseAir, NUM_COLUMNS}, + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, }; @@ -85,44 +86,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&BitwiseAir {}, &trace, &inputs_m31); - - /*let prove_with_periodic_columns = prove_with_periodic_columns(&config, &BitwiseAir {}, trace, &inputs_m31); - verify_with_periodic_columns(&config, &BitwiseAir {}, &prove_with_periodic_columns, &inputs_m31).expect("Verification failed");*/ - - /*let proof = prove(&config, &BitwiseAir {}, trace, &inputs_m31); - verify(&config, &BitwiseAir {}, &proof, &inputs_m31).expect("Verification failed");*/ +fn generate_inputs() -> Vec { + vec![1; 16] } + +generate_air_plonky3_test!(test_air_plonky3, BitwiseAir); diff --git a/air-script/tests/bitwise/test_air_winterfell.rs b/air-script/tests/bitwise/test_air_winterfell.rs index 16daca900..c5166f091 100644 --- a/air-script/tests/bitwise/test_air_winterfell.rs +++ b/air-script/tests/bitwise/test_air_winterfell.rs @@ -6,7 +6,7 @@ use winterfell::{AuxTraceWithMetadata, Trace, TraceTable, matrix::ColMatrix}; use crate::{ bitwise::bitwise::PublicInputs, - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, }; @@ -50,4 +50,9 @@ impl AirTester for BitwiseAirTester { } } -generate_air_test!(test_bitwise_air, crate::bitwise::bitwise::BitwiseAir, BitwiseAirTester, 1024); +generate_air_winterfell_test!( + test_bitwise_air, + crate::bitwise::bitwise::BitwiseAir, + BitwiseAirTester, + 1024 +); diff --git a/air-script/tests/buses/test_air_plonky3.rs b/air-script/tests/buses/test_air_plonky3.rs index e465396df..a6671ba82 100644 --- a/air-script/tests/buses/test_air_plonky3.rs +++ b/air-script/tests/buses/test_air_plonky3.rs @@ -14,6 +14,7 @@ use p3_uni_stark::StarkConfig; use crate::{ buses::buses_complex_plonky3::{BusesAir, NUM_COLUMNS}, + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, }; @@ -47,38 +48,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 2]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&BusesAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 2] } + +generate_air_plonky3_test!(test_air_plonky3, BusesAir); diff --git a/air-script/tests/buses/test_air_winterfell.rs b/air-script/tests/buses/test_air_winterfell.rs index 4c27304a2..7bf2ce5ea 100644 --- a/air-script/tests/buses/test_air_winterfell.rs +++ b/air-script/tests/buses/test_air_winterfell.rs @@ -4,7 +4,7 @@ use winterfell::{AuxTraceWithMetadata, Trace, TraceTable, matrix::ColMatrix}; use crate::{ buses::buses_complex::PublicInputs, - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, }; @@ -57,4 +57,9 @@ impl AirTester for BusesAirTester { } } -generate_air_test!(test_buses_air, crate::buses::buses_complex::BusesAir, BusesAirTester, 1024); +generate_air_winterfell_test!( + test_buses_air, + crate::buses::buses_complex::BusesAir, + BusesAirTester, + 1024 +); diff --git a/air-script/tests/constant_in_range/test_air_plonky3.rs b/air-script/tests/constant_in_range/test_air_plonky3.rs index 15af390e6..2518eaf03 100644 --- a/air-script/tests/constant_in_range/test_air_plonky3.rs +++ b/air-script/tests/constant_in_range/test_air_plonky3.rs @@ -14,6 +14,7 @@ use p3_uni_stark::StarkConfig; use crate::{ constant_in_range::constant_in_range_plonky3::{ConstantInRangeAir, NUM_COLUMNS}, + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, }; @@ -66,38 +67,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&ConstantInRangeAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 16] } + +generate_air_plonky3_test!(test_air_plonky3, ConstantInRangeAir); diff --git a/air-script/tests/constant_in_range/test_air_winterfell.rs b/air-script/tests/constant_in_range/test_air_winterfell.rs index 064e5eb19..3672378c8 100644 --- a/air-script/tests/constant_in_range/test_air_winterfell.rs +++ b/air-script/tests/constant_in_range/test_air_winterfell.rs @@ -4,7 +4,7 @@ use winterfell::{Trace, TraceTable}; use crate::{ constant_in_range::constant_in_range::PublicInputs, - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, }; @@ -46,7 +46,7 @@ impl AirTester for ConstantInRangeAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_constant_in_range_air, crate::constant_in_range::constant_in_range::ConstantInRangeAir, ConstantInRangeAirTester, diff --git a/air-script/tests/constants/test_air_plonky3.rs b/air-script/tests/constants/test_air_plonky3.rs index f4d12edd5..04c4b3e16 100644 --- a/air-script/tests/constants/test_air_plonky3.rs +++ b/air-script/tests/constants/test_air_plonky3.rs @@ -14,6 +14,7 @@ use p3_uni_stark::StarkConfig; use crate::{ constants::constants_plonky3::{ConstantsAir, NUM_COLUMNS}, + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, }; @@ -62,38 +63,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 32]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&ConstantsAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 32] } + +generate_air_plonky3_test!(test_air_plonky3, ConstantsAir); diff --git a/air-script/tests/constants/test_air_winterfell.rs b/air-script/tests/constants/test_air_winterfell.rs index 97a048a31..9459000d7 100644 --- a/air-script/tests/constants/test_air_winterfell.rs +++ b/air-script/tests/constants/test_air_winterfell.rs @@ -4,7 +4,7 @@ use winterfell::{Trace, TraceTable}; use crate::{ constants::constants::PublicInputs, - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, }; @@ -44,7 +44,7 @@ impl AirTester for ConstantsAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_constants_air, crate::constants::constants::ConstantsAir, ConstantsAirTester, diff --git a/air-script/tests/constraint_comprehension/test_air_plonky3.rs b/air-script/tests/constraint_comprehension/test_air_plonky3.rs index c2243f2ea..593107425 100644 --- a/air-script/tests/constraint_comprehension/test_air_plonky3.rs +++ b/air-script/tests/constraint_comprehension/test_air_plonky3.rs @@ -16,6 +16,7 @@ use crate::{ constraint_comprehension::constraint_comprehension_plonky3::{ ConstraintComprehensionAir, NUM_COLUMNS, }, + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, }; @@ -49,38 +50,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&ConstraintComprehensionAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 16] } + +generate_air_plonky3_test!(test_air_plonky3, ConstraintComprehensionAir); diff --git a/air-script/tests/constraint_comprehension/test_air_winterfell.rs b/air-script/tests/constraint_comprehension/test_air_winterfell.rs index 6bdb9cc8d..73a24bf0f 100644 --- a/air-script/tests/constraint_comprehension/test_air_winterfell.rs +++ b/air-script/tests/constraint_comprehension/test_air_winterfell.rs @@ -4,7 +4,7 @@ use winterfell::{Trace, TraceTable}; use crate::{ constraint_comprehension::constraint_comprehension::PublicInputs, - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, }; @@ -48,7 +48,7 @@ impl AirTester for ConstraintComprehensionAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_constraint_comprehension_air, crate::constraint_comprehension::constraint_comprehension::ConstraintComprehensionAir, ConstraintComprehensionAirTester, diff --git a/air-script/tests/evaluators/test_air_plonky3.rs b/air-script/tests/evaluators/test_air_plonky3.rs index 9ba08a264..76e8ffc82 100644 --- a/air-script/tests/evaluators/test_air_plonky3.rs +++ b/air-script/tests/evaluators/test_air_plonky3.rs @@ -14,6 +14,7 @@ use p3_uni_stark::StarkConfig; use crate::{ evaluators::evaluators_plonky3::{EvaluatorsAir, NUM_COLUMNS}, + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, }; @@ -62,38 +63,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&EvaluatorsAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 16] } + +generate_air_plonky3_test!(test_air_plonky3, EvaluatorsAir); diff --git a/air-script/tests/evaluators/test_air_winterfell.rs b/air-script/tests/evaluators/test_air_winterfell.rs index 6bf42ed83..fa8f6f6d8 100644 --- a/air-script/tests/evaluators/test_air_winterfell.rs +++ b/air-script/tests/evaluators/test_air_winterfell.rs @@ -4,7 +4,7 @@ use winterfell::{Trace, TraceTable}; use crate::{ evaluators::evaluators::PublicInputs, - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, }; @@ -41,7 +41,7 @@ impl AirTester for EvaluatorsAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_evaluators_air, crate::evaluators::evaluators::EvaluatorsAir, EvaluatorsAirTester, diff --git a/air-script/tests/fibonacci/test_air_plonky3.rs b/air-script/tests/fibonacci/test_air_plonky3.rs index fdfbd8132..10e671df8 100644 --- a/air-script/tests/fibonacci/test_air_plonky3.rs +++ b/air-script/tests/fibonacci/test_air_plonky3.rs @@ -14,6 +14,7 @@ use p3_uni_stark::StarkConfig; use crate::{ fibonacci::fibonacci_plonky3::{FibonacciAir, NUM_COLUMNS}, + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, }; @@ -47,41 +48,10 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - +fn generate_inputs() -> Vec { let one = 1; let last = 2178309; // 32nd Fibonacci number - let inputs = vec![one, one, last]; - - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&FibonacciAir {}, &trace, &inputs_m31); + vec![one, one, last] } + +generate_air_plonky3_test!(test_air_plonky3, FibonacciAir); diff --git a/air-script/tests/fibonacci/test_air_winterfell.rs b/air-script/tests/fibonacci/test_air_winterfell.rs index 10162f645..5839643d7 100644 --- a/air-script/tests/fibonacci/test_air_winterfell.rs +++ b/air-script/tests/fibonacci/test_air_winterfell.rs @@ -6,7 +6,7 @@ use winterfell::{AuxTraceWithMetadata, Trace, TraceTable, matrix::ColMatrix}; use crate::{ fibonacci::fibonacci::PublicInputs, - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, }; @@ -45,7 +45,7 @@ impl AirTester for FibonacciAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_fibonacci_air, crate::fibonacci::fibonacci::FibonacciAir, FibonacciAirTester, diff --git a/air-script/tests/functions/test_air_plonky3.rs b/air-script/tests/functions/test_air_plonky3.rs index 84da79962..d9a590894 100644 --- a/air-script/tests/functions/test_air_plonky3.rs +++ b/air-script/tests/functions/test_air_plonky3.rs @@ -14,6 +14,7 @@ use p3_uni_stark::StarkConfig; use crate::{ functions::functions_complex_plonky3::{FunctionsAir, NUM_COLUMNS}, + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, }; @@ -92,38 +93,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&FunctionsAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 16] } + +generate_air_plonky3_test!(test_air_plonky3, FunctionsAir); diff --git a/air-script/tests/functions/test_air_winterfell.rs b/air-script/tests/functions/test_air_winterfell.rs index ae578bf0d..0357e9039 100644 --- a/air-script/tests/functions/test_air_winterfell.rs +++ b/air-script/tests/functions/test_air_winterfell.rs @@ -4,7 +4,7 @@ use winterfell::{Trace, TraceTable}; use crate::{ functions::functions_complex::PublicInputs, - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, }; @@ -68,7 +68,7 @@ impl AirTester for FunctionsAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_functions_complex_air, crate::functions::functions_complex::FunctionsAir, FunctionsAirTester, diff --git a/air-script/tests/helpers/macros.rs b/air-script/tests/helpers/macros.rs index e134b8d48..3b4ebad6e 100644 --- a/air-script/tests/helpers/macros.rs +++ b/air-script/tests/helpers/macros.rs @@ -1,6 +1,6 @@ -// Helper macros for test generation +// Helper macros for Winterfell test generation -/// Generates an AIR test function with the standard boilerplate +/// Generates a Winterfell AIR test function with the standard boilerplate /// /// # Arguments /// * `test_name` - The identifier for the test function (e.g., `test_binary_air`) @@ -8,7 +8,7 @@ /// * `tester_name` - The identifier for the `AirTester` struct (e.g., `BinaryAirTester`) /// * `trace_length` - The length of the trace for the test (e.g., `32` or `1024`) #[macro_export] -macro_rules! generate_air_test { +macro_rules! generate_air_winterfell_test { ($test_name:ident, $air_name:path, $tester_name:ident, $trace_length:expr) => { #[test] fn $test_name() { @@ -27,3 +27,58 @@ macro_rules! generate_air_test { } }; } + +// Helper macros for Plonky3 test generation + +/// Generates a Plonky3 AIR test function with the standard boilerplate +/// +/// # Arguments +/// * `test_name` - The identifier for the test function (e.g., `test_binary_air`) +/// * `air_name` - The identifier for the AIR struct (e.g., `BinaryAir`) +#[macro_export] +macro_rules! generate_air_plonky3_test { + ($test_name:ident, $air_name:ident) => { + #[test] + fn $test_name() { + type Val = Mersenne31; + type Challenge = BinomialExtensionField; + + type ByteHash = Sha256; + type FieldHash = SerializingHasher; + type MyCompress = CompressionFunctionFromHasher; + type ValMmcs = MerkleTreeMmcs; + type ChallengeMmcs = ExtensionMmcs; + type Challenger = SerializingChallenger32>; + type Pcs = CirclePcs; + type MyConfig = StarkConfig; + + let byte_hash = ByteHash {}; + let field_hash = FieldHash::new(Sha256); + let compress = MyCompress::new(byte_hash); + let val_mmcs = ValMmcs::new(field_hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + let challenger = Challenger::from_hasher(vec![], byte_hash); + let fri_params = create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs { + mmcs: val_mmcs, + fri_params, + _phantom: PhantomData, + }; + let config = MyConfig::new(pcs, challenger); + + let inputs = generate_inputs(); + let inputs_m31: Vec = + inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + + let trace = generate_trace_rows::(inputs); + + check_constraints_with_periodic_columns(&$air_name {}, &trace, &inputs_m31); + + /*let prove_with_periodic_columns = prove_with_periodic_columns(&config, &BitwiseAir {}, trace, &inputs_m31); + verify_with_periodic_columns(&config, &BitwiseAir {}, &prove_with_periodic_columns, &inputs_m31).expect("Verification failed");*/ + + /*let proof = prove(&config, &BitwiseAir {}, trace, &inputs_m31); + verify(&config, &BitwiseAir {}, &proof, &inputs_m31).expect("Verification failed");*/ + } + }; +} diff --git a/air-script/tests/indexed_trace_access/test_air_plonky3.rs b/air-script/tests/indexed_trace_access/test_air_plonky3.rs index 8f1f7dfd3..cef3b72e8 100644 --- a/air-script/tests/indexed_trace_access/test_air_plonky3.rs +++ b/air-script/tests/indexed_trace_access/test_air_plonky3.rs @@ -13,6 +13,7 @@ use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; use crate::{ + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, indexed_trace_access::indexed_trace_access_plonky3::{NUM_COLUMNS, TraceAccessAir}, }; @@ -49,38 +50,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&TraceAccessAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 16] } + +generate_air_plonky3_test!(test_air_plonky3, TraceAccessAir); diff --git a/air-script/tests/indexed_trace_access/test_air_winterfell.rs b/air-script/tests/indexed_trace_access/test_air_winterfell.rs index 707dbba10..9d7e64bcb 100644 --- a/air-script/tests/indexed_trace_access/test_air_winterfell.rs +++ b/air-script/tests/indexed_trace_access/test_air_winterfell.rs @@ -3,7 +3,7 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, indexed_trace_access::indexed_trace_access::PublicInputs, }; @@ -40,7 +40,7 @@ impl AirTester for TraceAccessAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_indexed_trace_access_air, crate::indexed_trace_access::indexed_trace_access::TraceAccessAir, TraceAccessAirTester, diff --git a/air-script/tests/list_comprehension/test_air_plonky3.rs b/air-script/tests/list_comprehension/test_air_plonky3.rs index 0f8e6f879..70277f2c3 100644 --- a/air-script/tests/list_comprehension/test_air_plonky3.rs +++ b/air-script/tests/list_comprehension/test_air_plonky3.rs @@ -13,6 +13,7 @@ use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; use crate::{ + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, list_comprehension::list_comprehension_plonky3::{ListComprehensionAir, NUM_COLUMNS}, }; @@ -89,38 +90,7 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&ListComprehensionAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 16] } +generate_air_plonky3_test!(test_air_plonky3, ListComprehensionAir); diff --git a/air-script/tests/list_comprehension/test_air_winterfell.rs b/air-script/tests/list_comprehension/test_air_winterfell.rs index c3e9b396f..8fef13b07 100644 --- a/air-script/tests/list_comprehension/test_air_winterfell.rs +++ b/air-script/tests/list_comprehension/test_air_winterfell.rs @@ -3,7 +3,7 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, list_comprehension::list_comprehension::PublicInputs, }; @@ -52,7 +52,7 @@ impl AirTester for ListComprehensionAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_list_comprehension_air, crate::list_comprehension::list_comprehension::ListComprehensionAir, ListComprehensionAirTester, diff --git a/air-script/tests/list_folding/test_air_plonky3.rs b/air-script/tests/list_folding/test_air_plonky3.rs index 695d3906f..45871c969 100644 --- a/air-script/tests/list_folding/test_air_plonky3.rs +++ b/air-script/tests/list_folding/test_air_plonky3.rs @@ -13,6 +13,7 @@ use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; use crate::{ + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, list_folding::list_folding_plonky3::{ListFoldingAir, NUM_COLUMNS}, }; @@ -92,38 +93,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&ListFoldingAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 16] } + +generate_air_plonky3_test!(test_air_plonky3, ListFoldingAir); diff --git a/air-script/tests/list_folding/test_air_winterfell.rs b/air-script/tests/list_folding/test_air_winterfell.rs index 9d79fad28..f8376848d 100644 --- a/air-script/tests/list_folding/test_air_winterfell.rs +++ b/air-script/tests/list_folding/test_air_winterfell.rs @@ -3,7 +3,7 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, list_folding::list_folding::PublicInputs, }; @@ -53,7 +53,7 @@ impl AirTester for ListFoldingAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_list_folding_air, crate::list_folding::list_folding::ListFoldingAir, ListFoldingAirTester, diff --git a/air-script/tests/periodic_columns/test_air_plonky3.rs b/air-script/tests/periodic_columns/test_air_plonky3.rs index c380f7e88..589fab8e8 100644 --- a/air-script/tests/periodic_columns/test_air_plonky3.rs +++ b/air-script/tests/periodic_columns/test_air_plonky3.rs @@ -13,6 +13,7 @@ use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; use crate::{ + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, periodic_columns::periodic_columns_plonky3::{NUM_COLUMNS, PeriodicColumnsAir}, }; @@ -50,38 +51,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&PeriodicColumnsAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 16] } + +generate_air_plonky3_test!(test_air_plonky3, PeriodicColumnsAir); diff --git a/air-script/tests/periodic_columns/test_air_winterfell.rs b/air-script/tests/periodic_columns/test_air_winterfell.rs index f157a98df..0adc8364f 100644 --- a/air-script/tests/periodic_columns/test_air_winterfell.rs +++ b/air-script/tests/periodic_columns/test_air_winterfell.rs @@ -3,7 +3,7 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, periodic_columns::periodic_columns::PublicInputs, }; @@ -37,7 +37,7 @@ impl AirTester for PeriodicColumnsAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_periodic_columns_air, crate::periodic_columns::periodic_columns::PeriodicColumnsAir, PeriodicColumnsAirTester, diff --git a/air-script/tests/pub_inputs/test_air_plonky3.rs b/air-script/tests/pub_inputs/test_air_plonky3.rs index 071828dfb..a29b06143 100644 --- a/air-script/tests/pub_inputs/test_air_plonky3.rs +++ b/air-script/tests/pub_inputs/test_air_plonky3.rs @@ -13,6 +13,7 @@ use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; use crate::{ + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, pub_inputs::pub_inputs_plonky3::{NUM_COLUMNS, PubInputsAir}, }; @@ -53,38 +54,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![0; 32]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&PubInputsAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![0; 32] } + +generate_air_plonky3_test!(test_air_plonky3, PubInputsAir); diff --git a/air-script/tests/pub_inputs/test_air_winterfell.rs b/air-script/tests/pub_inputs/test_air_winterfell.rs index ad929a857..947f4bbac 100644 --- a/air-script/tests/pub_inputs/test_air_winterfell.rs +++ b/air-script/tests/pub_inputs/test_air_winterfell.rs @@ -3,7 +3,7 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, pub_inputs::pub_inputs::PublicInputs, }; @@ -38,7 +38,7 @@ impl AirTester for PubInputsAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_pub_inputs_air, crate::pub_inputs::pub_inputs::PubInputsAir, PubInputsAirTester, diff --git a/air-script/tests/selectors/test_air_plonky3.rs b/air-script/tests/selectors/test_air_plonky3.rs index 2b2366fe8..ad757c2fb 100644 --- a/air-script/tests/selectors/test_air_plonky3.rs +++ b/air-script/tests/selectors/test_air_plonky3.rs @@ -13,6 +13,7 @@ use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; use crate::{ + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, selectors::selectors_with_evaluators_plonky3::{NUM_COLUMNS, SelectorsAir}, }; @@ -53,38 +54,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&SelectorsAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 16] } + +generate_air_plonky3_test!(test_air_plonky3, SelectorsAir); diff --git a/air-script/tests/selectors/test_air_winterfell.rs b/air-script/tests/selectors/test_air_winterfell.rs index 4f2f3378b..19f683ef6 100644 --- a/air-script/tests/selectors/test_air_winterfell.rs +++ b/air-script/tests/selectors/test_air_winterfell.rs @@ -3,7 +3,7 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, selectors::selectors_with_evaluators::PublicInputs, }; @@ -40,7 +40,7 @@ impl AirTester for SelectorsAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_selectors_with_evaluators_air, crate::selectors::selectors_with_evaluators::SelectorsAir, SelectorsAirTester, diff --git a/air-script/tests/system/test_air_plonky3.rs b/air-script/tests/system/test_air_plonky3.rs index 5bee89503..93f0d769e 100644 --- a/air-script/tests/system/test_air_plonky3.rs +++ b/air-script/tests/system/test_air_plonky3.rs @@ -13,6 +13,7 @@ use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; use crate::{ + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, system::system_plonky3::{NUM_COLUMNS, SystemAir}, }; @@ -50,38 +51,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&SystemAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 16] } + +generate_air_plonky3_test!(test_air_plonky3, SystemAir); diff --git a/air-script/tests/system/test_air_winterfell.rs b/air-script/tests/system/test_air_winterfell.rs index 3aa6815c6..9327f6e98 100644 --- a/air-script/tests/system/test_air_winterfell.rs +++ b/air-script/tests/system/test_air_winterfell.rs @@ -3,7 +3,7 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, system::system::PublicInputs, }; @@ -39,4 +39,9 @@ impl AirTester for SystemAirTester { } } -generate_air_test!(test_system_air, crate::system::system::SystemAir, SystemAirTester, 1024); +generate_air_winterfell_test!( + test_system_air, + crate::system::system::SystemAir, + SystemAirTester, + 1024 +); diff --git a/air-script/tests/trace_col_groups/test_air_plonky3.rs b/air-script/tests/trace_col_groups/test_air_plonky3.rs index b1c2c7f67..225222609 100644 --- a/air-script/tests/trace_col_groups/test_air_plonky3.rs +++ b/air-script/tests/trace_col_groups/test_air_plonky3.rs @@ -13,6 +13,7 @@ use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; use crate::{ + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, trace_col_groups::trace_col_groups_plonky3::{NUM_COLUMNS, TraceColGroupAir}, }; @@ -68,38 +69,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 16]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&TraceColGroupAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 16] } + +generate_air_plonky3_test!(test_air_plonky3, TraceColGroupAir); diff --git a/air-script/tests/trace_col_groups/test_air_winterfell.rs b/air-script/tests/trace_col_groups/test_air_winterfell.rs index cb62434e9..92400a4f2 100644 --- a/air-script/tests/trace_col_groups/test_air_winterfell.rs +++ b/air-script/tests/trace_col_groups/test_air_winterfell.rs @@ -3,7 +3,7 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, trace_col_groups::trace_col_groups::PublicInputs, }; @@ -46,7 +46,7 @@ impl AirTester for TraceColGroupAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_trace_col_groups_air, crate::trace_col_groups::trace_col_groups::TraceColGroupAir, TraceColGroupAirTester, diff --git a/air-script/tests/variables/test_air_plonky3.rs b/air-script/tests/variables/test_air_plonky3.rs index e1e615220..7c01c92d5 100644 --- a/air-script/tests/variables/test_air_plonky3.rs +++ b/air-script/tests/variables/test_air_plonky3.rs @@ -13,6 +13,7 @@ use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; use crate::{ + generate_air_plonky3_test, helpers::check_constraints_with_periodic_columns, variables::variables_plonky3::{NUM_COLUMNS, VariablesAir}, }; @@ -53,38 +54,8 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -#[test] -fn test_air_plonky3() { - type Val = Mersenne31; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; - - let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); - let compress = MyCompress::new(byte_hash); - let val_mmcs = ValMmcs::new(field_hash, compress); - let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); - let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; - let config = MyConfig::new(pcs, challenger); - - let inputs = vec![1; 32]; - let inputs_m31: Vec = inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); - - let trace = generate_trace_rows::(inputs); - - check_constraints_with_periodic_columns(&VariablesAir {}, &trace, &inputs_m31); +fn generate_inputs() -> Vec { + vec![1; 32] } + +generate_air_plonky3_test!(test_air_plonky3, VariablesAir); diff --git a/air-script/tests/variables/test_air_winterfell.rs b/air-script/tests/variables/test_air_winterfell.rs index c45e18516..3578f330f 100644 --- a/air-script/tests/variables/test_air_winterfell.rs +++ b/air-script/tests/variables/test_air_winterfell.rs @@ -3,7 +3,7 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - generate_air_test, + generate_air_winterfell_test, helpers::{AirTester, MyTraceTable}, variables::variables::PublicInputs, }; @@ -40,7 +40,7 @@ impl AirTester for VariablesAirTester { } } -generate_air_test!( +generate_air_winterfell_test!( test_variables_air, crate::variables::variables::VariablesAir, VariablesAirTester, From 7b11b116ea06faf0e63302b595decc0b8b37b832 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Tue, 14 Oct 2025 11:52:25 +0200 Subject: [PATCH 16/25] docs: Add documentation for Plonky3 backend --- docs/src/backends.md | 8 +++++--- docs/src/introduction.md | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/src/backends.md b/docs/src/backends.md index ce8b023e7..1a7f883fe 100644 --- a/docs/src/backends.md +++ b/docs/src/backends.md @@ -1,14 +1,16 @@ # Backends -AirScript currently comes bundled with two backends: +AirScript currently comes bundled with three backends: - [Winterfell backend](https://github.com/0xMiden/air-script/tree/main/codegen/winterfell) which outputs `Air` trait implementation for the [Winterfell prover](https://github.com/facebook/winterfell) (Rust). +- [Plonky3 backend](https://github.com/0xMiden/air-script/tree/main/codegen/plonky3) which outputs `Air` trait implementation for the [Plonky3 prover](https://github.com/Plonky3/Plonky3) (Rust). - [ACE backend](https://github.com/0xMiden/air-script/tree/main/codegen/ace) which outputs arithmetic circuits for Miden VM's ACE (Arithmetic Circuit Evaluation) chiplet for recursive STARK proof verification. -These backends can be used programmatically as crates. +These backends can be used programmatically as crates. -The Winterfell backend can also be used via AirScript CLI by specifying `--target` flag. For example, the following will output Winterfell `Air` trait implementation for AIR constraints described in `example.air` file: +The Winterfell and Plonky3 backends can also be used via AirScript CLI by specifying `--target` flag. For example, the following will output Winterfell and Plonky3 `Air` trait implementation for AIR constraints described in `example.air` file: ```bash # Make sure to run from the project root directory ./target/release/airc transpile examples/example.air --target winterfell +./target/release/airc transpile examples/example.air --target plonky3 ``` In both cases we assumed that the CLI has been compiled as described [here](./introduction.md#cli). diff --git a/docs/src/introduction.md b/docs/src/introduction.md index b6b565286..d39ae08d3 100644 --- a/docs/src/introduction.md +++ b/docs/src/introduction.md @@ -7,6 +7,7 @@ Currently, AirScript is on version 0.3, which includes about 95% of features needed to describe Miden VM constraints, and supports generation of constraint evaluation code for the following backends: - **Winterfell**: Generates Rust code implementing the `Air` trait for the [Winterfell prover](https://github.com/facebook/winterfell) +- **Plonky3**: Generates Rust code implementing the `Air` trait implementation for the [Plonky3 prover](https://github.com/Plonky3/Plonky3) - **ACE**: Generates arithmetic circuits for Miden VM's ACE (Arithmetic Circuit Evaluation) chiplet for recursive proof verification AirScript includes the following features: @@ -57,6 +58,8 @@ Then, run the `airc` target with the `transpile` option. For example: ``` This will output constraint evaluation code targeted for the Winterfell prover. +Using the `--target plonky3` argument will output constraint evaluation code targeted for the Plonky3 prover instead. + You can use the `help` option to see other available options. ```ignore @@ -75,6 +78,5 @@ The following changes are some of the improvements under consideration for futur - removing unnecessary nodes from the `AlgebraicGraph` of boundary and integrity constraints. - combining integrity constraints with mutually exclusive selectors to reduce the total number of constraints. - additional language targets for simplifying verifier implementations: - - Plonky3 AirBuilder. - JSON-based constraint syntax. - formal verification From 4409002ec00fc9153eacc71379028fad8b771ddc Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Wed, 15 Oct 2025 17:36:24 +0200 Subject: [PATCH 17/25] tests: Add Plonky3 E2E tests for computed indices --- air-script/tests/codegen/plonky3.rs | 22 ++++++++ .../computed_indices_complex_plonky3.rs | 43 ++++++++++++++++ .../computed_indices_simple_plonky3.rs | 50 +++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 air-script/tests/computed_indices/computed_indices_complex_plonky3.rs create mode 100644 air-script/tests/computed_indices/computed_indices_simple_plonky3.rs diff --git a/air-script/tests/codegen/plonky3.rs b/air-script/tests/codegen/plonky3.rs index bb7b3a24c..aa4de2ed4 100644 --- a/air-script/tests/codegen/plonky3.rs +++ b/air-script/tests/codegen/plonky3.rs @@ -111,6 +111,28 @@ fn bitwise() { expected.assert_eq(&generated_air); } + +#[test] +fn computed_indices_complex() { + let generated_air = + Test::new("tests/computed_indices/computed_indices_complex.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../computed_indices/computed_indices_complex_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn computed_indices_simple() { + let generated_air = Test::new("tests/computed_indices/computed_indices_simple.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["../computed_indices/computed_indices_simple_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + #[test] fn constants() { let generated_air = Test::new("tests/constants/constants.air".to_string()) diff --git a/air-script/tests/computed_indices/computed_indices_complex_plonky3.rs b/air-script/tests/computed_indices/computed_indices_complex_plonky3.rs new file mode 100644 index 000000000..1ded2a430 --- /dev/null +++ b/air-script/tests/computed_indices/computed_indices_complex_plonky3.rs @@ -0,0 +1,43 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 4; + +pub const NUM_PUBLIC_VALUES: usize = 1; + +pub struct ComputedIndicesAir; + +impl BaseAir for ComputedIndicesAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for ComputedIndicesAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for ComputedIndicesAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for ComputedIndicesAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[0].into()); + builder.assert_zero::<_>(main_current[2].into() * AB::Expr::from_u64(3) + main_current[3].into() * AB::Expr::from_u64(4)); + } +} \ No newline at end of file diff --git a/air-script/tests/computed_indices/computed_indices_simple_plonky3.rs b/air-script/tests/computed_indices/computed_indices_simple_plonky3.rs new file mode 100644 index 000000000..3ac8ed33b --- /dev/null +++ b/air-script/tests/computed_indices/computed_indices_simple_plonky3.rs @@ -0,0 +1,50 @@ +use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; +use p3_matrix::Matrix; +use p3_field::PrimeCharacteristicRing; +use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; + +pub const NUM_COLUMNS: usize = 8; + +pub const NUM_PUBLIC_VALUES: usize = 16; + +pub struct ComputedIndicesAir; + +impl BaseAir for ComputedIndicesAir { + fn width(&self) -> usize { + NUM_COLUMNS + } +} + +impl BaseAirWithPublicValues for ComputedIndicesAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl BaseAirWithPeriodicColumns for ComputedIndicesAir { + fn get_periodic_columns(&self) -> Vec> { + vec![ + ] + } +} + +impl Air for ComputedIndicesAir { + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values = builder.periodic_columns(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + builder.when_first_row().assert_zero::<_>(main_current[0].into()); + builder.assert_zero::<_>(main_current[0].into()); + builder.assert_zero::<_>(main_current[1].into() - AB::Expr::from_u64(2)); + builder.assert_zero::<_>(main_current[2].into() - AB::Expr::from_u64(4)); + builder.assert_zero::<_>(main_current[3].into() - AB::Expr::from_u64(6)); + builder.when_transition().assert_zero::<_>(main_next[4].into()); + builder.when_transition().assert_zero::<_>(main_next[5].into() - main_current[5].into().double()); + builder.when_transition().assert_zero::<_>(main_next[6].into() - AB::Expr::from_u64(6) * main_current[6].into()); + builder.when_transition().assert_zero::<_>(main_next[7].into() - AB::Expr::from_u64(12) * main_current[7].into()); + } +} \ No newline at end of file From d0418fed715e9073f7bbbef52bcb1313872b6ea8 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Wed, 15 Oct 2025 17:38:13 +0200 Subject: [PATCH 18/25] chore: fix fmt lint --- air-script/tests/codegen/plonky3.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/air-script/tests/codegen/plonky3.rs b/air-script/tests/codegen/plonky3.rs index aa4de2ed4..8ccbb2d55 100644 --- a/air-script/tests/codegen/plonky3.rs +++ b/air-script/tests/codegen/plonky3.rs @@ -111,7 +111,6 @@ fn bitwise() { expected.assert_eq(&generated_air); } - #[test] fn computed_indices_complex() { let generated_air = From e6aa42181d7e872f6d15e34b0e00aebed8c5213b Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Mon, 20 Oct 2025 13:04:56 +0300 Subject: [PATCH 19/25] tests(plonky3): use Goldilocks instead of Mersenne32 --- air-script/Cargo.toml | 2 +- air-script/tests/binary/test_air_plonky3.rs | 5 +++-- air-script/tests/bitwise/test_air_plonky3.rs | 5 +++-- air-script/tests/buses/test_air_plonky3.rs | 5 +++-- .../constant_in_range/test_air_plonky3.rs | 5 +++-- air-script/tests/constants/test_air_plonky3.rs | 5 +++-- .../test_air_plonky3.rs | 5 +++-- .../tests/evaluators/test_air_plonky3.rs | 5 +++-- air-script/tests/fibonacci/test_air_plonky3.rs | 5 +++-- air-script/tests/functions/test_air_plonky3.rs | 6 ++++-- air-script/tests/helpers/macros.rs | 18 +++++++++--------- .../indexed_trace_access/test_air_plonky3.rs | 5 +++-- .../list_comprehension/test_air_plonky3.rs | 6 ++++-- .../tests/list_folding/test_air_plonky3.rs | 5 +++-- .../tests/periodic_columns/test_air_plonky3.rs | 5 +++-- .../tests/pub_inputs/test_air_plonky3.rs | 5 +++-- air-script/tests/selectors/test_air_plonky3.rs | 5 +++-- air-script/tests/system/test_air_plonky3.rs | 5 +++-- .../tests/trace_col_groups/test_air_plonky3.rs | 6 ++++-- air-script/tests/variables/test_air_plonky3.rs | 6 ++++-- 20 files changed, 68 insertions(+), 46 deletions(-) diff --git a/air-script/Cargo.toml b/air-script/Cargo.toml index 883e5b61a..50ec896f2 100644 --- a/air-script/Cargo.toml +++ b/air-script/Cargo.toml @@ -38,7 +38,7 @@ p3-field = { package = "p3-field", version = "0.3", default-features = false } p3-fri = { package = "p3-fri", version = "0.3", default-features = false } p3-matrix = { package = "p3-matrix", version = "0.3", default-features = false } p3-merkle-tree = { package = "p3-merkle-tree", version = "0.3", default-features = false } -p3-mersenne-31 = { package = "p3-mersenne-31", version = "0.3", default-features = false } +p3-goldilocks = { package = "p3-goldilocks", version = "0.3", default-features = false } p3-sha256 = { package = "p3-sha256", version = "0.3", default-features = false } p3-symmetric = { package = "p3-symmetric", version = "0.3", default-features = false } p3-uni-stark = { package = "p3-uni-stark", version = "0.3.0", default-features = false } diff --git a/air-script/tests/binary/test_air_plonky3.rs b/air-script/tests/binary/test_air_plonky3.rs index ac4e20894..9225aa013 100644 --- a/air-script/tests/binary/test_air_plonky3.rs +++ b/air-script/tests/binary/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -51,5 +51,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, BinaryAir); diff --git a/air-script/tests/bitwise/test_air_plonky3.rs b/air-script/tests/bitwise/test_air_plonky3.rs index 1bb3a9f89..da5fcb341 100644 --- a/air-script/tests/bitwise/test_air_plonky3.rs +++ b/air-script/tests/bitwise/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -89,5 +89,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, BitwiseAir); diff --git a/air-script/tests/buses/test_air_plonky3.rs b/air-script/tests/buses/test_air_plonky3.rs index a6671ba82..080db385e 100644 --- a/air-script/tests/buses/test_air_plonky3.rs +++ b/air-script/tests/buses/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -51,5 +51,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 2] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, BusesAir); diff --git a/air-script/tests/constant_in_range/test_air_plonky3.rs b/air-script/tests/constant_in_range/test_air_plonky3.rs index 2518eaf03..121a97581 100644 --- a/air-script/tests/constant_in_range/test_air_plonky3.rs +++ b/air-script/tests/constant_in_range/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -70,5 +70,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, ConstantInRangeAir); diff --git a/air-script/tests/constants/test_air_plonky3.rs b/air-script/tests/constants/test_air_plonky3.rs index 04c4b3e16..1f6974644 100644 --- a/air-script/tests/constants/test_air_plonky3.rs +++ b/air-script/tests/constants/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -66,5 +66,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 32] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, ConstantsAir); diff --git a/air-script/tests/constraint_comprehension/test_air_plonky3.rs b/air-script/tests/constraint_comprehension/test_air_plonky3.rs index 593107425..23f6e3fa5 100644 --- a/air-script/tests/constraint_comprehension/test_air_plonky3.rs +++ b/air-script/tests/constraint_comprehension/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -53,5 +53,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, ConstraintComprehensionAir); diff --git a/air-script/tests/evaluators/test_air_plonky3.rs b/air-script/tests/evaluators/test_air_plonky3.rs index 76e8ffc82..b65d85753 100644 --- a/air-script/tests/evaluators/test_air_plonky3.rs +++ b/air-script/tests/evaluators/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -66,5 +66,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, EvaluatorsAir); diff --git a/air-script/tests/fibonacci/test_air_plonky3.rs b/air-script/tests/fibonacci/test_air_plonky3.rs index 10e671df8..4ad375779 100644 --- a/air-script/tests/fibonacci/test_air_plonky3.rs +++ b/air-script/tests/fibonacci/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -53,5 +53,6 @@ fn generate_inputs() -> Vec { let last = 2178309; // 32nd Fibonacci number vec![one, one, last] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, FibonacciAir); diff --git a/air-script/tests/functions/test_air_plonky3.rs b/air-script/tests/functions/test_air_plonky3.rs index d9a590894..0388183e2 100644 --- a/air-script/tests/functions/test_air_plonky3.rs +++ b/air-script/tests/functions/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -97,4 +97,6 @@ fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; + generate_air_plonky3_test!(test_air_plonky3, FunctionsAir); diff --git a/air-script/tests/helpers/macros.rs b/air-script/tests/helpers/macros.rs index 3b4ebad6e..6f9586249 100644 --- a/air-script/tests/helpers/macros.rs +++ b/air-script/tests/helpers/macros.rs @@ -40,7 +40,7 @@ macro_rules! generate_air_plonky3_test { ($test_name:ident, $air_name:ident) => { #[test] fn $test_name() { - type Val = Mersenne31; + type Val = Goldilocks; type Challenge = BinomialExtensionField; type ByteHash = Sha256; @@ -48,7 +48,7 @@ macro_rules! generate_air_plonky3_test { type MyCompress = CompressionFunctionFromHasher; type ValMmcs = MerkleTreeMmcs; type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger32>; + type Challenger = SerializingChallenger64>; type Pcs = CirclePcs; type MyConfig = StarkConfig; @@ -67,18 +67,18 @@ macro_rules! generate_air_plonky3_test { let config = MyConfig::new(pcs, challenger); let inputs = generate_inputs(); - let inputs_m31: Vec = - inputs.iter().map(|&x| Val::new_checked(x).unwrap()).collect(); + let inputs_goldilocks: Vec = + inputs.iter().map(|&x| Val::from_u32(x)).collect(); let trace = generate_trace_rows::(inputs); - check_constraints_with_periodic_columns(&$air_name {}, &trace, &inputs_m31); + check_constraints_with_periodic_columns(&$air_name {}, &trace, &inputs_goldilocks); - /*let prove_with_periodic_columns = prove_with_periodic_columns(&config, &BitwiseAir {}, trace, &inputs_m31); - verify_with_periodic_columns(&config, &BitwiseAir {}, &prove_with_periodic_columns, &inputs_m31).expect("Verification failed");*/ + /*let prove_with_periodic_columns = prove_with_periodic_columns(&config, &BitwiseAir {}, trace, &inputs_goldilocks); + verify_with_periodic_columns(&config, &BitwiseAir {}, &prove_with_periodic_columns, &inputs_goldilocks).expect("Verification failed");*/ - /*let proof = prove(&config, &BitwiseAir {}, trace, &inputs_m31); - verify(&config, &BitwiseAir {}, &proof, &inputs_m31).expect("Verification failed");*/ + /*let proof = prove(&config, &BitwiseAir {}, trace, &inputs_goldilocks); + verify(&config, &BitwiseAir {}, &proof, &inputs_goldilocks).expect("Verification failed");*/ } }; } diff --git a/air-script/tests/indexed_trace_access/test_air_plonky3.rs b/air-script/tests/indexed_trace_access/test_air_plonky3.rs index cef3b72e8..bc1a1f736 100644 --- a/air-script/tests/indexed_trace_access/test_air_plonky3.rs +++ b/air-script/tests/indexed_trace_access/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -53,5 +53,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, TraceAccessAir); diff --git a/air-script/tests/list_comprehension/test_air_plonky3.rs b/air-script/tests/list_comprehension/test_air_plonky3.rs index 70277f2c3..3779ba640 100644 --- a/air-script/tests/list_comprehension/test_air_plonky3.rs +++ b/air-script/tests/list_comprehension/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -93,4 +93,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; + generate_air_plonky3_test!(test_air_plonky3, ListComprehensionAir); diff --git a/air-script/tests/list_folding/test_air_plonky3.rs b/air-script/tests/list_folding/test_air_plonky3.rs index 45871c969..106918f4b 100644 --- a/air-script/tests/list_folding/test_air_plonky3.rs +++ b/air-script/tests/list_folding/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -96,5 +96,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, ListFoldingAir); diff --git a/air-script/tests/periodic_columns/test_air_plonky3.rs b/air-script/tests/periodic_columns/test_air_plonky3.rs index 589fab8e8..7bbd3ed5b 100644 --- a/air-script/tests/periodic_columns/test_air_plonky3.rs +++ b/air-script/tests/periodic_columns/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -54,5 +54,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, PeriodicColumnsAir); diff --git a/air-script/tests/pub_inputs/test_air_plonky3.rs b/air-script/tests/pub_inputs/test_air_plonky3.rs index a29b06143..a68427cc2 100644 --- a/air-script/tests/pub_inputs/test_air_plonky3.rs +++ b/air-script/tests/pub_inputs/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -57,5 +57,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![0; 32] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, PubInputsAir); diff --git a/air-script/tests/selectors/test_air_plonky3.rs b/air-script/tests/selectors/test_air_plonky3.rs index ad757c2fb..1f717bac9 100644 --- a/air-script/tests/selectors/test_air_plonky3.rs +++ b/air-script/tests/selectors/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -57,5 +57,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, SelectorsAir); diff --git a/air-script/tests/system/test_air_plonky3.rs b/air-script/tests/system/test_air_plonky3.rs index 93f0d769e..63553c12f 100644 --- a/air-script/tests/system/test_air_plonky3.rs +++ b/air-script/tests/system/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -54,5 +54,6 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, SystemAir); diff --git a/air-script/tests/trace_col_groups/test_air_plonky3.rs b/air-script/tests/trace_col_groups/test_air_plonky3.rs index 225222609..16bf6d313 100644 --- a/air-script/tests/trace_col_groups/test_air_plonky3.rs +++ b/air-script/tests/trace_col_groups/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -73,4 +73,6 @@ fn generate_inputs() -> Vec { vec![1; 16] } +use p3_field::PrimeCharacteristicRing; + generate_air_plonky3_test!(test_air_plonky3, TraceColGroupAir); diff --git a/air-script/tests/variables/test_air_plonky3.rs b/air-script/tests/variables/test_air_plonky3.rs index 7c01c92d5..566d919b7 100644 --- a/air-script/tests/variables/test_air_plonky3.rs +++ b/air-script/tests/variables/test_air_plonky3.rs @@ -1,13 +1,13 @@ use std::marker::PhantomData; -use p3_challenger::{HashChallenger, SerializingChallenger32}; +use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; use p3_field::{PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; +use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; use p3_merkle_tree::MerkleTreeMmcs; -use p3_mersenne_31::Mersenne31; use p3_sha256::Sha256; use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; use p3_uni_stark::StarkConfig; @@ -58,4 +58,6 @@ fn generate_inputs() -> Vec { vec![1; 32] } +use p3_field::PrimeCharacteristicRing; + generate_air_plonky3_test!(test_air_plonky3, VariablesAir); From 1ec834bb07d99918229c964aa5bef100bf86f72b Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Mon, 20 Oct 2025 13:13:45 +0300 Subject: [PATCH 20/25] chore: cleanup import --- air-script/tests/binary/test_air_plonky3.rs | 3 +-- air-script/tests/bitwise/test_air_plonky3.rs | 3 +-- air-script/tests/buses/test_air_plonky3.rs | 3 +-- air-script/tests/constant_in_range/test_air_plonky3.rs | 3 +-- air-script/tests/constants/test_air_plonky3.rs | 3 +-- air-script/tests/constraint_comprehension/test_air_plonky3.rs | 3 +-- air-script/tests/evaluators/test_air_plonky3.rs | 3 +-- air-script/tests/fibonacci/test_air_plonky3.rs | 3 +-- air-script/tests/functions/test_air_plonky3.rs | 4 +--- air-script/tests/indexed_trace_access/test_air_plonky3.rs | 3 +-- air-script/tests/list_comprehension/test_air_plonky3.rs | 3 +-- air-script/tests/list_folding/test_air_plonky3.rs | 3 +-- air-script/tests/periodic_columns/test_air_plonky3.rs | 3 +-- air-script/tests/pub_inputs/test_air_plonky3.rs | 3 +-- air-script/tests/selectors/test_air_plonky3.rs | 3 +-- air-script/tests/system/test_air_plonky3.rs | 3 +-- air-script/tests/trace_col_groups/test_air_plonky3.rs | 4 +--- air-script/tests/variables/test_air_plonky3.rs | 4 +--- 18 files changed, 18 insertions(+), 39 deletions(-) diff --git a/air-script/tests/binary/test_air_plonky3.rs b/air-script/tests/binary/test_air_plonky3.rs index 9225aa013..cb06fb5f4 100644 --- a/air-script/tests/binary/test_air_plonky3.rs +++ b/air-script/tests/binary/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -51,6 +51,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, BinaryAir); diff --git a/air-script/tests/bitwise/test_air_plonky3.rs b/air-script/tests/bitwise/test_air_plonky3.rs index da5fcb341..d3c6efcaa 100644 --- a/air-script/tests/bitwise/test_air_plonky3.rs +++ b/air-script/tests/bitwise/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -89,6 +89,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, BitwiseAir); diff --git a/air-script/tests/buses/test_air_plonky3.rs b/air-script/tests/buses/test_air_plonky3.rs index 080db385e..1b323208b 100644 --- a/air-script/tests/buses/test_air_plonky3.rs +++ b/air-script/tests/buses/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -51,6 +51,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 2] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, BusesAir); diff --git a/air-script/tests/constant_in_range/test_air_plonky3.rs b/air-script/tests/constant_in_range/test_air_plonky3.rs index 121a97581..56e1dcb11 100644 --- a/air-script/tests/constant_in_range/test_air_plonky3.rs +++ b/air-script/tests/constant_in_range/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -70,6 +70,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, ConstantInRangeAir); diff --git a/air-script/tests/constants/test_air_plonky3.rs b/air-script/tests/constants/test_air_plonky3.rs index 1f6974644..6eecb26fa 100644 --- a/air-script/tests/constants/test_air_plonky3.rs +++ b/air-script/tests/constants/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -66,6 +66,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 32] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, ConstantsAir); diff --git a/air-script/tests/constraint_comprehension/test_air_plonky3.rs b/air-script/tests/constraint_comprehension/test_air_plonky3.rs index 23f6e3fa5..ceab24925 100644 --- a/air-script/tests/constraint_comprehension/test_air_plonky3.rs +++ b/air-script/tests/constraint_comprehension/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -53,6 +53,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, ConstraintComprehensionAir); diff --git a/air-script/tests/evaluators/test_air_plonky3.rs b/air-script/tests/evaluators/test_air_plonky3.rs index b65d85753..7fed6ebc2 100644 --- a/air-script/tests/evaluators/test_air_plonky3.rs +++ b/air-script/tests/evaluators/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -66,6 +66,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, EvaluatorsAir); diff --git a/air-script/tests/fibonacci/test_air_plonky3.rs b/air-script/tests/fibonacci/test_air_plonky3.rs index 4ad375779..6a01a91b6 100644 --- a/air-script/tests/fibonacci/test_air_plonky3.rs +++ b/air-script/tests/fibonacci/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -53,6 +53,5 @@ fn generate_inputs() -> Vec { let last = 2178309; // 32nd Fibonacci number vec![one, one, last] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, FibonacciAir); diff --git a/air-script/tests/functions/test_air_plonky3.rs b/air-script/tests/functions/test_air_plonky3.rs index 0388183e2..5ef13dbf9 100644 --- a/air-script/tests/functions/test_air_plonky3.rs +++ b/air-script/tests/functions/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -97,6 +97,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; - generate_air_plonky3_test!(test_air_plonky3, FunctionsAir); diff --git a/air-script/tests/indexed_trace_access/test_air_plonky3.rs b/air-script/tests/indexed_trace_access/test_air_plonky3.rs index bc1a1f736..b01cc0eaa 100644 --- a/air-script/tests/indexed_trace_access/test_air_plonky3.rs +++ b/air-script/tests/indexed_trace_access/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -53,6 +53,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, TraceAccessAir); diff --git a/air-script/tests/list_comprehension/test_air_plonky3.rs b/air-script/tests/list_comprehension/test_air_plonky3.rs index 3779ba640..7cec4aeed 100644 --- a/air-script/tests/list_comprehension/test_air_plonky3.rs +++ b/air-script/tests/list_comprehension/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -93,6 +93,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, ListComprehensionAir); diff --git a/air-script/tests/list_folding/test_air_plonky3.rs b/air-script/tests/list_folding/test_air_plonky3.rs index 106918f4b..83d82e10d 100644 --- a/air-script/tests/list_folding/test_air_plonky3.rs +++ b/air-script/tests/list_folding/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -96,6 +96,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, ListFoldingAir); diff --git a/air-script/tests/periodic_columns/test_air_plonky3.rs b/air-script/tests/periodic_columns/test_air_plonky3.rs index 7bbd3ed5b..6b7b9acce 100644 --- a/air-script/tests/periodic_columns/test_air_plonky3.rs +++ b/air-script/tests/periodic_columns/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -54,6 +54,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, PeriodicColumnsAir); diff --git a/air-script/tests/pub_inputs/test_air_plonky3.rs b/air-script/tests/pub_inputs/test_air_plonky3.rs index a68427cc2..71343872e 100644 --- a/air-script/tests/pub_inputs/test_air_plonky3.rs +++ b/air-script/tests/pub_inputs/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -57,6 +57,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![0; 32] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, PubInputsAir); diff --git a/air-script/tests/selectors/test_air_plonky3.rs b/air-script/tests/selectors/test_air_plonky3.rs index 1f717bac9..289939f0e 100644 --- a/air-script/tests/selectors/test_air_plonky3.rs +++ b/air-script/tests/selectors/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -57,6 +57,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, SelectorsAir); diff --git a/air-script/tests/system/test_air_plonky3.rs b/air-script/tests/system/test_air_plonky3.rs index 63553c12f..9c0eb5004 100644 --- a/air-script/tests/system/test_air_plonky3.rs +++ b/air-script/tests/system/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -54,6 +54,5 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; generate_air_plonky3_test!(test_air_plonky3, SystemAir); diff --git a/air-script/tests/trace_col_groups/test_air_plonky3.rs b/air-script/tests/trace_col_groups/test_air_plonky3.rs index 16bf6d313..b12ab3ac7 100644 --- a/air-script/tests/trace_col_groups/test_air_plonky3.rs +++ b/air-script/tests/trace_col_groups/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -73,6 +73,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -use p3_field::PrimeCharacteristicRing; - generate_air_plonky3_test!(test_air_plonky3, TraceColGroupAir); diff --git a/air-script/tests/variables/test_air_plonky3.rs b/air-script/tests/variables/test_air_plonky3.rs index 566d919b7..8296f2197 100644 --- a/air-script/tests/variables/test_air_plonky3.rs +++ b/air-script/tests/variables/test_air_plonky3.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use p3_challenger::{HashChallenger, SerializingChallenger64}; use p3_circle::CirclePcs; use p3_commit::ExtensionMmcs; -use p3_field::{PrimeField64, extension::BinomialExtensionField}; +use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; use p3_fri::create_benchmark_fri_params; use p3_goldilocks::Goldilocks; use p3_matrix::dense::RowMajorMatrix; @@ -58,6 +58,4 @@ fn generate_inputs() -> Vec { vec![1; 32] } -use p3_field::PrimeCharacteristicRing; - generate_air_plonky3_test!(test_air_plonky3, VariablesAir); From b3a441e51b56cdf1e258f2540fed177ab47c4708 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Thu, 4 Dec 2025 16:10:34 +0100 Subject: [PATCH 21/25] Target 0xMiden Plonky3 repo and use AirScriptAir and AirScriptBuilder traits (#508) --- .github/workflows/book.yml | 2 +- CHANGELOG.md | 2 + air-script/Cargo.toml | 32 +- air-script/src/lib.rs | 5 + .../test_utils/air_tester_macros.rs} | 56 +-- .../helpers.rs => src/test_utils/codegen.rs} | 3 +- .../miden_vm_aux_trace_generator.rs | 116 ++++++ air-script/src/test_utils/mod.rs | 10 + air-script/src/test_utils/plonky3_traits.rs | 189 ++++++++++ .../test_utils/winterfell_traits.rs} | 0 air-script/{ => src}/tests/binary/binary.air | 0 air-script/{ => src}/tests/binary/binary.rs | 0 air-script/src/tests/binary/binary_plonky3.rs | 44 +++ air-script/{ => src}/tests/binary/mod.rs | 0 .../tests/binary/test_air_plonky3.rs | 29 +- .../tests/binary/test_air_winterfell.rs | 6 +- .../{ => src}/tests/bitwise/bitwise.air | 0 air-script/{ => src}/tests/bitwise/bitwise.rs | 0 .../src/tests/bitwise/bitwise_plonky3.rs | 73 ++++ air-script/{ => src}/tests/bitwise/mod.rs | 1 + .../tests/bitwise/test_air_plonky3.rs | 29 +- .../tests/bitwise/test_air_winterfell.rs | 6 +- .../{ => src}/tests/buses/buses_complex.air | 8 +- .../{ => src}/tests/buses/buses_complex.rs | 2 +- .../src/tests/buses/buses_complex_plonky3.rs | 138 +++++++ .../{ => src}/tests/buses/buses_simple.air | 0 .../{ => src}/tests/buses/buses_simple.rs | 0 .../src/tests/buses/buses_simple_plonky3.rs | 133 +++++++ .../buses/buses_simple_with_evaluators.air | 0 .../buses/buses_simple_with_evaluators.rs | 100 ++++++ .../buses_simple_with_evaluators_plonky3.rs | 108 ++++++ .../buses/buses_varlen_boundary_both.air | 0 .../tests/buses/buses_varlen_boundary_both.rs | 0 .../buses_varlen_boundary_both_plonky3.rs | 134 +++++++ .../buses/buses_varlen_boundary_first.air | 0 .../buses/buses_varlen_boundary_first.rs | 0 .../buses_varlen_boundary_first_plonky3.rs | 135 +++++++ .../buses/buses_varlen_boundary_last.air | 0 .../tests/buses/buses_varlen_boundary_last.rs | 0 .../buses_varlen_boundary_last_plonky3.rs | 135 +++++++ air-script/{ => src}/tests/buses/mod.rs | 0 .../src/tests/buses/test_air_plonky3.rs | 59 +++ .../tests/buses/test_air_winterfell.rs | 12 +- .../computed_indices_complex.air | 0 .../computed_indices_complex.rs | 0 .../computed_indices_complex_plonky3.rs | 43 +++ .../computed_indices_simple.air | 0 .../computed_indices_simple.rs | 0 .../computed_indices_simple_plonky3.rs | 50 +++ air-script/src/tests/computed_indices/mod.rs | 18 + .../computed_indices/test_air_plonky3.rs | 62 ++++ .../computed_indices/test_air_winterfell.rs} | 25 +- .../constant_in_range/constant_in_range.air | 0 .../constant_in_range/constant_in_range.rs | 0 .../constant_in_range_module.air | 0 .../constant_in_range_plonky3.rs | 43 +++ .../{ => src}/tests/constant_in_range/mod.rs | 0 .../constant_in_range/test_air_plonky3.rs | 29 +- .../constant_in_range/test_air_winterfell.rs | 6 +- .../{ => src}/tests/constants/constants.air | 0 .../{ => src}/tests/constants/constants.rs | 0 .../src/tests/constants/constants_plonky3.rs | 52 +++ air-script/{ => src}/tests/constants/mod.rs | 0 .../tests/constants/test_air_plonky3.rs | 29 +- .../tests/constants/test_air_winterfell.rs | 6 +- .../cc_with_evaluators.air | 0 .../constraint_comprehension.air | 0 .../constraint_comprehension.rs | 0 .../constraint_comprehension_plonky3.rs | 46 +++ .../tests/constraint_comprehension/mod.rs | 0 .../test_air_plonky3.rs | 46 +++ .../test_air_winterfell.rs | 6 +- air-script/{ => src}/tests/docs_sync.rs | 0 .../{ => src}/tests/evaluators/evaluators.air | 0 .../{ => src}/tests/evaluators/evaluators.rs | 0 .../tests/evaluators/evaluators_plonky3.rs | 52 +++ air-script/{ => src}/tests/evaluators/mod.rs | 0 .../tests/evaluators/test_air_plonky3.rs | 29 +- .../tests/evaluators/test_air_winterfell.rs | 6 +- .../{ => src}/tests/fibonacci/fibonacci.air | 0 .../{ => src}/tests/fibonacci/fibonacci.rs | 0 .../src/tests/fibonacci/fibonacci_plonky3.rs | 46 +++ air-script/{ => src}/tests/fibonacci/mod.rs | 0 .../tests/fibonacci/test_air_plonky3.rs | 29 +- .../tests/fibonacci/test_air_winterfell.rs | 6 +- .../tests/functions/functions_complex.air | 0 .../tests/functions/functions_complex.rs | 0 .../functions/functions_complex_plonky3.rs | 44 +++ .../tests/functions/functions_simple.air | 0 .../tests/functions/functions_simple.rs | 0 .../functions/functions_simple_plonky3.rs | 50 +++ .../functions/inlined_functions_simple.air | 0 air-script/{ => src}/tests/functions/mod.rs | 0 .../tests/functions/test_air_plonky3.rs | 29 +- .../tests/functions/test_air_winterfell.rs | 6 +- .../indexed_trace_access.air | 0 .../indexed_trace_access.rs | 0 .../indexed_trace_access_plonky3.rs | 43 +++ .../tests/indexed_trace_access/mod.rs | 0 .../indexed_trace_access/test_air_plonky3.rs | 29 +- .../test_air_winterfell.rs | 6 +- .../list_comprehension/list_comprehension.air | 0 .../list_comprehension/list_comprehension.rs | 0 .../list_comprehension_nested.air | 0 .../list_comprehension_nested.rs | 0 .../list_comprehension_nested_plonky3.rs | 45 +++ .../list_comprehension_plonky3.rs | 48 +++ .../{ => src}/tests/list_comprehension/mod.rs | 7 + .../list_comprehension/test_air_plonky3.rs | 29 +- .../list_comprehension/test_air_winterfell.rs | 6 +- .../tests/list_folding/list_folding.air | 0 .../tests/list_folding/list_folding.rs | 0 .../list_folding/list_folding_plonky3.rs | 46 +++ .../{ => src}/tests/list_folding/mod.rs | 0 .../tests/list_folding/test_air_plonky3.rs | 29 +- .../tests/list_folding/test_air_winterfell.rs | 6 +- air-script/{ => src}/tests/mod.rs | 6 +- .../{ => src}/tests/periodic_columns/mod.rs | 0 .../periodic_columns/periodic_columns.air | 0 .../periodic_columns/periodic_columns.rs | 0 .../periodic_columns_plonky3.rs | 58 +++ .../periodic_columns/test_air_plonky3.rs | 29 +- .../periodic_columns/test_air_winterfell.rs | 6 +- air-script/src/tests/plonky3.rs | 336 +++++++++++++++++ air-script/{ => src}/tests/pub_inputs/mod.rs | 0 .../{ => src}/tests/pub_inputs/pub_inputs.air | 0 .../{ => src}/tests/pub_inputs/pub_inputs.rs | 0 .../tests/pub_inputs/pub_inputs_plonky3.rs | 50 +++ .../tests/pub_inputs/test_air_plonky3.rs | 29 +- .../tests/pub_inputs/test_air_winterfell.rs | 6 +- air-script/{ => src}/tests/selectors/mod.rs | 4 + .../{ => src}/tests/selectors/selectors.air | 0 .../{ => src}/tests/selectors/selectors.rs | 0 .../selectors/selectors_combine_complex.air | 0 .../selectors/selectors_combine_complex.rs | 0 .../selectors_combine_complex_plonky3.rs | 134 +++++++ .../selectors/selectors_combine_simple.air | 0 .../selectors/selectors_combine_simple.rs | 0 .../selectors_combine_simple_plonky3.rs | 44 +++ ...ctors_combine_with_list_comprehensions.air | 0 ...ectors_combine_with_list_comprehensions.rs | 0 ...ombine_with_list_comprehensions_plonky3.rs | 45 +++ .../src/tests/selectors/selectors_plonky3.rs | 44 +++ .../selectors/selectors_with_evaluators.air | 0 .../selectors/selectors_with_evaluators.rs | 0 .../selectors_with_evaluators_plonky3.rs | 44 +++ .../tests/selectors/test_air_plonky3.rs | 29 +- .../tests/selectors/test_air_winterfell.rs | 6 +- air-script/{ => src}/tests/system/mod.rs | 0 air-script/{ => src}/tests/system/system.air | 0 air-script/{ => src}/tests/system/system.rs | 0 air-script/src/tests/system/system_plonky3.rs | 43 +++ .../tests/system/test_air_plonky3.rs | 29 +- .../tests/system/test_air_winterfell.rs | 6 +- .../{ => src}/tests/trace_col_groups/mod.rs | 0 .../trace_col_groups/test_air_plonky3.rs | 29 +- .../trace_col_groups/test_air_winterfell.rs | 6 +- .../trace_col_groups/trace_col_groups.air | 0 .../trace_col_groups/trace_col_groups.rs | 0 .../trace_col_groups_plonky3.rs | 44 +++ air-script/{ => src}/tests/variables/mod.rs | 0 .../tests/variables/test_air_plonky3.rs | 29 +- .../tests/variables/test_air_winterfell.rs | 6 +- .../{ => src}/tests/variables/variables.air | 0 .../{ => src}/tests/variables/variables.rs | 0 .../src/tests/variables/variables_plonky3.rs | 60 ++++ air-script/src/tests/winterfell.rs | 337 ++++++++++++++++++ air-script/tests/binary/binary_plonky3.rs | 44 --- air-script/tests/bitwise/bitwise_plonky3.rs | 61 ---- .../tests/buses/buses_complex_plonky3.rs | 44 --- .../tests/buses/buses_simple_plonky3.rs | 41 --- .../buses_varlen_boundary_both_plonky3.rs | 41 --- .../buses_varlen_boundary_first_plonky3.rs | 41 --- .../buses_varlen_boundary_last_plonky3.rs | 41 --- air-script/tests/buses/test_air_plonky3.rs | 55 --- air-script/tests/codegen/mod.rs | 3 - air-script/tests/codegen/plonky3.rs | 323 ----------------- air-script/tests/codegen/winterfell.rs | 335 ----------------- .../computed_indices_complex_plonky3.rs | 43 --- .../computed_indices_simple_plonky3.rs | 50 --- air-script/tests/computed_indices/mod.rs | 7 - .../constant_in_range_plonky3.rs | 43 --- .../tests/constants/constants_plonky3.rs | 52 --- .../constraint_comprehension_plonky3.rs | 46 --- .../test_air_plonky3.rs | 57 --- .../tests/evaluators/evaluators_plonky3.rs | 52 --- .../tests/fibonacci/fibonacci_plonky3.rs | 46 --- .../functions/functions_complex_plonky3.rs | 44 --- .../functions/functions_simple_plonky3.rs | 50 --- air-script/tests/helpers/mod.rs | 6 - .../tests/helpers/plonky3_periodic_columns.rs | 146 -------- .../indexed_trace_access_plonky3.rs | 43 --- .../list_comprehension_nested_plonky3.rs | 45 --- .../list_comprehension_plonky3.rs | 48 --- .../list_folding/list_folding_plonky3.rs | 46 --- .../periodic_columns_plonky3.rs | 46 --- .../tests/pub_inputs/pub_inputs_plonky3.rs | 50 --- .../selectors_combine_complex_plonky3.rs | 45 --- .../selectors_combine_simple_plonky3.rs | 44 --- ...ombine_with_list_comprehensions_plonky3.rs | 45 --- .../tests/selectors/selectors_plonky3.rs | 44 --- .../selectors_with_evaluators_plonky3.rs | 44 --- air-script/tests/system/system_plonky3.rs | 43 --- .../trace_col_groups_plonky3.rs | 44 --- .../tests/variables/variables_plonky3.rs | 48 --- air/src/ir/mod.rs | 16 +- .../common_subexpression_elimination.rs | 22 ++ air/src/passes/expand_buses.rs | 47 ++- .../plonky3/src/air/boundary_constraints.rs | 30 +- codegen/plonky3/src/air/graph.rs | 176 +++++++-- .../plonky3/src/air/integrity_constraints.rs | 26 +- codegen/plonky3/src/air/mod.rs | 268 +++++++++++--- codegen/plonky3/src/imports.rs | 16 +- scripts/generate_all_e2e_tests.sh | 72 ++++ 214 files changed, 4180 insertions(+), 2877 deletions(-) rename air-script/{tests/helpers/macros.rs => src/test_utils/air_tester_macros.rs} (57%) rename air-script/{tests/codegen/helpers.rs => src/test_utils/codegen.rs} (99%) create mode 100644 air-script/src/test_utils/miden_vm_aux_trace_generator.rs create mode 100644 air-script/src/test_utils/mod.rs create mode 100644 air-script/src/test_utils/plonky3_traits.rs rename air-script/{tests/helpers/winterfell_test_helpers.rs => src/test_utils/winterfell_traits.rs} (100%) rename air-script/{ => src}/tests/binary/binary.air (100%) rename air-script/{ => src}/tests/binary/binary.rs (100%) create mode 100644 air-script/src/tests/binary/binary_plonky3.rs rename air-script/{ => src}/tests/binary/mod.rs (100%) rename air-script/{ => src}/tests/binary/test_air_plonky3.rs (51%) rename air-script/{ => src}/tests/binary/test_air_winterfell.rs (87%) rename air-script/{ => src}/tests/bitwise/bitwise.air (100%) rename air-script/{ => src}/tests/bitwise/bitwise.rs (100%) create mode 100644 air-script/src/tests/bitwise/bitwise_plonky3.rs rename air-script/{ => src}/tests/bitwise/mod.rs (86%) rename air-script/{ => src}/tests/bitwise/test_air_plonky3.rs (70%) rename air-script/{ => src}/tests/bitwise/test_air_winterfell.rs (90%) rename air-script/{ => src}/tests/buses/buses_complex.air (80%) rename air-script/{ => src}/tests/buses/buses_complex.rs (93%) create mode 100644 air-script/src/tests/buses/buses_complex_plonky3.rs rename air-script/{ => src}/tests/buses/buses_simple.air (100%) rename air-script/{ => src}/tests/buses/buses_simple.rs (100%) create mode 100644 air-script/src/tests/buses/buses_simple_plonky3.rs rename air-script/{ => src}/tests/buses/buses_simple_with_evaluators.air (100%) create mode 100644 air-script/src/tests/buses/buses_simple_with_evaluators.rs create mode 100644 air-script/src/tests/buses/buses_simple_with_evaluators_plonky3.rs rename air-script/{ => src}/tests/buses/buses_varlen_boundary_both.air (100%) rename air-script/{ => src}/tests/buses/buses_varlen_boundary_both.rs (100%) create mode 100644 air-script/src/tests/buses/buses_varlen_boundary_both_plonky3.rs rename air-script/{ => src}/tests/buses/buses_varlen_boundary_first.air (100%) rename air-script/{ => src}/tests/buses/buses_varlen_boundary_first.rs (100%) create mode 100644 air-script/src/tests/buses/buses_varlen_boundary_first_plonky3.rs rename air-script/{ => src}/tests/buses/buses_varlen_boundary_last.air (100%) rename air-script/{ => src}/tests/buses/buses_varlen_boundary_last.rs (100%) create mode 100644 air-script/src/tests/buses/buses_varlen_boundary_last_plonky3.rs rename air-script/{ => src}/tests/buses/mod.rs (100%) create mode 100644 air-script/src/tests/buses/test_air_plonky3.rs rename air-script/{ => src}/tests/buses/test_air_winterfell.rs (84%) rename air-script/{ => src}/tests/computed_indices/computed_indices_complex.air (100%) rename air-script/{ => src}/tests/computed_indices/computed_indices_complex.rs (100%) create mode 100644 air-script/src/tests/computed_indices/computed_indices_complex_plonky3.rs rename air-script/{ => src}/tests/computed_indices/computed_indices_simple.air (100%) rename air-script/{ => src}/tests/computed_indices/computed_indices_simple.rs (100%) create mode 100644 air-script/src/tests/computed_indices/computed_indices_simple_plonky3.rs create mode 100644 air-script/src/tests/computed_indices/mod.rs create mode 100644 air-script/src/tests/computed_indices/test_air_plonky3.rs rename air-script/{tests/computed_indices/test_air.rs => src/tests/computed_indices/test_air_winterfell.rs} (63%) rename air-script/{ => src}/tests/constant_in_range/constant_in_range.air (100%) rename air-script/{ => src}/tests/constant_in_range/constant_in_range.rs (100%) rename air-script/{ => src}/tests/constant_in_range/constant_in_range_module.air (100%) create mode 100644 air-script/src/tests/constant_in_range/constant_in_range_plonky3.rs rename air-script/{ => src}/tests/constant_in_range/mod.rs (100%) rename air-script/{ => src}/tests/constant_in_range/test_air_plonky3.rs (64%) rename air-script/{ => src}/tests/constant_in_range/test_air_winterfell.rs (86%) rename air-script/{ => src}/tests/constants/constants.air (100%) rename air-script/{ => src}/tests/constants/constants.rs (100%) create mode 100644 air-script/src/tests/constants/constants_plonky3.rs rename air-script/{ => src}/tests/constants/mod.rs (100%) rename air-script/{ => src}/tests/constants/test_air_plonky3.rs (61%) rename air-script/{ => src}/tests/constants/test_air_winterfell.rs (88%) rename air-script/{ => src}/tests/constraint_comprehension/cc_with_evaluators.air (100%) rename air-script/{ => src}/tests/constraint_comprehension/constraint_comprehension.air (100%) rename air-script/{ => src}/tests/constraint_comprehension/constraint_comprehension.rs (100%) create mode 100644 air-script/src/tests/constraint_comprehension/constraint_comprehension_plonky3.rs rename air-script/{ => src}/tests/constraint_comprehension/mod.rs (100%) create mode 100644 air-script/src/tests/constraint_comprehension/test_air_plonky3.rs rename air-script/{ => src}/tests/constraint_comprehension/test_air_winterfell.rs (85%) rename air-script/{ => src}/tests/docs_sync.rs (100%) rename air-script/{ => src}/tests/evaluators/evaluators.air (100%) rename air-script/{ => src}/tests/evaluators/evaluators.rs (100%) create mode 100644 air-script/src/tests/evaluators/evaluators_plonky3.rs rename air-script/{ => src}/tests/evaluators/mod.rs (100%) rename air-script/{ => src}/tests/evaluators/test_air_plonky3.rs (61%) rename air-script/{ => src}/tests/evaluators/test_air_winterfell.rs (86%) rename air-script/{ => src}/tests/fibonacci/fibonacci.air (100%) rename air-script/{ => src}/tests/fibonacci/fibonacci.rs (100%) create mode 100644 air-script/src/tests/fibonacci/fibonacci_plonky3.rs rename air-script/{ => src}/tests/fibonacci/mod.rs (100%) rename air-script/{ => src}/tests/fibonacci/test_air_plonky3.rs (53%) rename air-script/{ => src}/tests/fibonacci/test_air_winterfell.rs (88%) rename air-script/{ => src}/tests/functions/functions_complex.air (100%) rename air-script/{ => src}/tests/functions/functions_complex.rs (100%) create mode 100644 air-script/src/tests/functions/functions_complex_plonky3.rs rename air-script/{ => src}/tests/functions/functions_simple.air (100%) rename air-script/{ => src}/tests/functions/functions_simple.rs (100%) create mode 100644 air-script/src/tests/functions/functions_simple_plonky3.rs rename air-script/{ => src}/tests/functions/inlined_functions_simple.air (100%) rename air-script/{ => src}/tests/functions/mod.rs (100%) rename air-script/{ => src}/tests/functions/test_air_plonky3.rs (73%) rename air-script/{ => src}/tests/functions/test_air_winterfell.rs (92%) rename air-script/{ => src}/tests/indexed_trace_access/indexed_trace_access.air (100%) rename air-script/{ => src}/tests/indexed_trace_access/indexed_trace_access.rs (100%) create mode 100644 air-script/src/tests/indexed_trace_access/indexed_trace_access_plonky3.rs rename air-script/{ => src}/tests/indexed_trace_access/mod.rs (100%) rename air-script/{ => src}/tests/indexed_trace_access/test_air_plonky3.rs (50%) rename air-script/{ => src}/tests/indexed_trace_access/test_air_winterfell.rs (83%) rename air-script/{ => src}/tests/list_comprehension/list_comprehension.air (100%) rename air-script/{ => src}/tests/list_comprehension/list_comprehension.rs (100%) rename air-script/{ => src}/tests/list_comprehension/list_comprehension_nested.air (100%) rename air-script/{ => src}/tests/list_comprehension/list_comprehension_nested.rs (100%) create mode 100644 air-script/src/tests/list_comprehension/list_comprehension_nested_plonky3.rs create mode 100644 air-script/src/tests/list_comprehension/list_comprehension_plonky3.rs rename air-script/{ => src}/tests/list_comprehension/mod.rs (54%) rename air-script/{ => src}/tests/list_comprehension/test_air_plonky3.rs (72%) rename air-script/{ => src}/tests/list_comprehension/test_air_winterfell.rs (87%) rename air-script/{ => src}/tests/list_folding/list_folding.air (100%) rename air-script/{ => src}/tests/list_folding/list_folding.rs (100%) create mode 100644 air-script/src/tests/list_folding/list_folding_plonky3.rs rename air-script/{ => src}/tests/list_folding/mod.rs (100%) rename air-script/{ => src}/tests/list_folding/test_air_plonky3.rs (73%) rename air-script/{ => src}/tests/list_folding/test_air_winterfell.rs (89%) rename air-script/{ => src}/tests/mod.rs (97%) rename air-script/{ => src}/tests/periodic_columns/mod.rs (100%) rename air-script/{ => src}/tests/periodic_columns/periodic_columns.air (100%) rename air-script/{ => src}/tests/periodic_columns/periodic_columns.rs (100%) create mode 100644 air-script/src/tests/periodic_columns/periodic_columns_plonky3.rs rename air-script/{ => src}/tests/periodic_columns/test_air_plonky3.rs (51%) rename air-script/{ => src}/tests/periodic_columns/test_air_winterfell.rs (82%) create mode 100644 air-script/src/tests/plonky3.rs rename air-script/{ => src}/tests/pub_inputs/mod.rs (100%) rename air-script/{ => src}/tests/pub_inputs/pub_inputs.air (100%) rename air-script/{ => src}/tests/pub_inputs/pub_inputs.rs (100%) create mode 100644 air-script/src/tests/pub_inputs/pub_inputs_plonky3.rs rename air-script/{ => src}/tests/pub_inputs/test_air_plonky3.rs (55%) rename air-script/{ => src}/tests/pub_inputs/test_air_winterfell.rs (85%) rename air-script/{ => src}/tests/selectors/mod.rs (90%) rename air-script/{ => src}/tests/selectors/selectors.air (100%) rename air-script/{ => src}/tests/selectors/selectors.rs (100%) rename air-script/{ => src}/tests/selectors/selectors_combine_complex.air (100%) rename air-script/{ => src}/tests/selectors/selectors_combine_complex.rs (100%) create mode 100644 air-script/src/tests/selectors/selectors_combine_complex_plonky3.rs rename air-script/{ => src}/tests/selectors/selectors_combine_simple.air (100%) rename air-script/{ => src}/tests/selectors/selectors_combine_simple.rs (100%) create mode 100644 air-script/src/tests/selectors/selectors_combine_simple_plonky3.rs rename air-script/{ => src}/tests/selectors/selectors_combine_with_list_comprehensions.air (100%) rename air-script/{ => src}/tests/selectors/selectors_combine_with_list_comprehensions.rs (100%) create mode 100644 air-script/src/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs create mode 100644 air-script/src/tests/selectors/selectors_plonky3.rs rename air-script/{ => src}/tests/selectors/selectors_with_evaluators.air (100%) rename air-script/{ => src}/tests/selectors/selectors_with_evaluators.rs (100%) create mode 100644 air-script/src/tests/selectors/selectors_with_evaluators_plonky3.rs rename air-script/{ => src}/tests/selectors/test_air_plonky3.rs (54%) rename air-script/{ => src}/tests/selectors/test_air_winterfell.rs (84%) rename air-script/{ => src}/tests/system/mod.rs (100%) rename air-script/{ => src}/tests/system/system.air (100%) rename air-script/{ => src}/tests/system/system.rs (100%) create mode 100644 air-script/src/tests/system/system_plonky3.rs rename air-script/{ => src}/tests/system/test_air_plonky3.rs (53%) rename air-script/{ => src}/tests/system/test_air_winterfell.rs (86%) rename air-script/{ => src}/tests/trace_col_groups/mod.rs (100%) rename air-script/{ => src}/tests/trace_col_groups/test_air_plonky3.rs (64%) rename air-script/{ => src}/tests/trace_col_groups/test_air_winterfell.rs (86%) rename air-script/{ => src}/tests/trace_col_groups/trace_col_groups.air (100%) rename air-script/{ => src}/tests/trace_col_groups/trace_col_groups.rs (100%) create mode 100644 air-script/src/tests/trace_col_groups/trace_col_groups_plonky3.rs rename air-script/{ => src}/tests/variables/mod.rs (100%) rename air-script/{ => src}/tests/variables/test_air_plonky3.rs (54%) rename air-script/{ => src}/tests/variables/test_air_winterfell.rs (86%) rename air-script/{ => src}/tests/variables/variables.air (100%) rename air-script/{ => src}/tests/variables/variables.rs (100%) create mode 100644 air-script/src/tests/variables/variables_plonky3.rs create mode 100644 air-script/src/tests/winterfell.rs delete mode 100644 air-script/tests/binary/binary_plonky3.rs delete mode 100644 air-script/tests/bitwise/bitwise_plonky3.rs delete mode 100644 air-script/tests/buses/buses_complex_plonky3.rs delete mode 100644 air-script/tests/buses/buses_simple_plonky3.rs delete mode 100644 air-script/tests/buses/buses_varlen_boundary_both_plonky3.rs delete mode 100644 air-script/tests/buses/buses_varlen_boundary_first_plonky3.rs delete mode 100644 air-script/tests/buses/buses_varlen_boundary_last_plonky3.rs delete mode 100644 air-script/tests/buses/test_air_plonky3.rs delete mode 100644 air-script/tests/codegen/mod.rs delete mode 100644 air-script/tests/codegen/plonky3.rs delete mode 100644 air-script/tests/codegen/winterfell.rs delete mode 100644 air-script/tests/computed_indices/computed_indices_complex_plonky3.rs delete mode 100644 air-script/tests/computed_indices/computed_indices_simple_plonky3.rs delete mode 100644 air-script/tests/computed_indices/mod.rs delete mode 100644 air-script/tests/constant_in_range/constant_in_range_plonky3.rs delete mode 100644 air-script/tests/constants/constants_plonky3.rs delete mode 100644 air-script/tests/constraint_comprehension/constraint_comprehension_plonky3.rs delete mode 100644 air-script/tests/constraint_comprehension/test_air_plonky3.rs delete mode 100644 air-script/tests/evaluators/evaluators_plonky3.rs delete mode 100644 air-script/tests/fibonacci/fibonacci_plonky3.rs delete mode 100644 air-script/tests/functions/functions_complex_plonky3.rs delete mode 100644 air-script/tests/functions/functions_simple_plonky3.rs delete mode 100644 air-script/tests/helpers/mod.rs delete mode 100644 air-script/tests/helpers/plonky3_periodic_columns.rs delete mode 100644 air-script/tests/indexed_trace_access/indexed_trace_access_plonky3.rs delete mode 100644 air-script/tests/list_comprehension/list_comprehension_nested_plonky3.rs delete mode 100644 air-script/tests/list_comprehension/list_comprehension_plonky3.rs delete mode 100644 air-script/tests/list_folding/list_folding_plonky3.rs delete mode 100644 air-script/tests/periodic_columns/periodic_columns_plonky3.rs delete mode 100644 air-script/tests/pub_inputs/pub_inputs_plonky3.rs delete mode 100644 air-script/tests/selectors/selectors_combine_complex_plonky3.rs delete mode 100644 air-script/tests/selectors/selectors_combine_simple_plonky3.rs delete mode 100644 air-script/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs delete mode 100644 air-script/tests/selectors/selectors_plonky3.rs delete mode 100644 air-script/tests/selectors/selectors_with_evaluators_plonky3.rs delete mode 100644 air-script/tests/system/system_plonky3.rs delete mode 100644 air-script/tests/trace_col_groups/trace_col_groups_plonky3.rs delete mode 100644 air-script/tests/variables/variables_plonky3.rs create mode 100644 scripts/generate_all_e2e_tests.sh diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 8dbe014b7..10a5fdede 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -42,7 +42,7 @@ jobs: - name: Install mdbook and plugins uses: taiki-e/install-action@v2 with: - tool: mdbook, mdbook-linkcheck, mdbook-alerts, mdbook-katex, mdbook-mermaid + tool: mdbook@0.4.48, mdbook-linkcheck, mdbook-alerts, mdbook-katex, mdbook-mermaid - name: Build book run: mdbook build docs/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f5350d29..364bc9045 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ - Fix regressions on MIR and list_comprehensions (#449). - Add Plonky3 codegen backend (#461). - Fixed a vector unrolling issue in nested match evaluations (#491). +- In Plonky3 codegen, use AirScriptAir and AirScriptBuilder traits, and generate aux constraints (#508). +- In Plonky3 codegen, use MidenAir and MidenAirBuilder from 0xMiden's Plonky3 fork instead of AirScriptAir and AirScriptBuilder (#515). ## 0.4.0 (2025-06-20) diff --git a/air-script/Cargo.toml b/air-script/Cargo.toml index 50ec896f2..65813db4e 100644 --- a/air-script/Cargo.toml +++ b/air-script/Cargo.toml @@ -30,18 +30,26 @@ mir = { package = "air-mir", path = "../mir", version = "0.5" } [dev-dependencies] expect-test = "1.4" -p3-air = { package = "p3-air", version = "0.3", default-features = false } -p3-challenger = { package = "p3-challenger", version = "0.3", default-features = false } -p3-circle = { package = "p3-circle", version = "0.3", default-features = false } -p3-commit = { package = "p3-commit", version = "0.3", default-features = false } -p3-field = { package = "p3-field", version = "0.3", default-features = false } -p3-fri = { package = "p3-fri", version = "0.3", default-features = false } -p3-matrix = { package = "p3-matrix", version = "0.3", default-features = false } -p3-merkle-tree = { package = "p3-merkle-tree", version = "0.3", default-features = false } -p3-goldilocks = { package = "p3-goldilocks", version = "0.3", default-features = false } -p3-sha256 = { package = "p3-sha256", version = "0.3", default-features = false } -p3-symmetric = { package = "p3-symmetric", version = "0.3", default-features = false } -p3-uni-stark = { package = "p3-uni-stark", version = "0.3.0", default-features = false } + +# 0xMiden Plonky3 Fork +p3-air = { package = "p3-air", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-challenger = { package = "p3-challenger", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-commit = { package = "p3-commit", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-dft = { package = "p3-dft", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-field = { package = "p3-field", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-fri = { package = "p3-fri", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-matrix = { package = "p3-matrix", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-merkle-tree = { package = "p3-merkle-tree", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-miden-air = { package = "miden-air", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-goldilocks = { package = "p3-goldilocks", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-sha256 = { package = "p3-sha256", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-symmetric = { package = "p3-symmetric", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-uni-stark = { package = "p3-uni-stark", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } + +# MassaLabs fork +miden-processor = { package = "miden-processor", git="https://github.com/massalabs/miden-vm", rev = "bc553af69a2543a0789830e8508b019694528181", default-features = false } +miden-air = { package = "miden-air", git="https://github.com/massalabs/miden-vm", rev = "bc553af69a2543a0789830e8508b019694528181", default-features = false } + winter-air = { package = "winter-air", version = "0.12", default-features = false } winter-math = { package = "winter-math", version = "0.12", default-features = false } winter-utils = { package = "winter-utils", version = "0.12", default-features = false } diff --git a/air-script/src/lib.rs b/air-script/src/lib.rs index 5d477c7d0..67c255f21 100644 --- a/air-script/src/lib.rs +++ b/air-script/src/lib.rs @@ -1,3 +1,8 @@ pub use air_codegen_winter::CodeGenerator as WinterfellCodeGenerator; pub use air_ir::{Air, CompileError, compile}; pub use air_parser::{parse, parse_file, transforms}; + +#[cfg(test)] +pub mod test_utils; +#[cfg(test)] +mod tests; diff --git a/air-script/tests/helpers/macros.rs b/air-script/src/test_utils/air_tester_macros.rs similarity index 57% rename from air-script/tests/helpers/macros.rs rename to air-script/src/test_utils/air_tester_macros.rs index 6f9586249..53a64784e 100644 --- a/air-script/tests/helpers/macros.rs +++ b/air-script/src/test_utils/air_tester_macros.rs @@ -36,49 +36,49 @@ macro_rules! generate_air_winterfell_test { /// * `test_name` - The identifier for the test function (e.g., `test_binary_air`) /// * `air_name` - The identifier for the AIR struct (e.g., `BinaryAir`) #[macro_export] -macro_rules! generate_air_plonky3_test { +macro_rules! generate_air_plonky3_test_with_airscript_traits { ($test_name:ident, $air_name:ident) => { #[test] fn $test_name() { - type Val = Goldilocks; - type Challenge = BinomialExtensionField; - - type ByteHash = Sha256; - type FieldHash = SerializingHasher; - type MyCompress = CompressionFunctionFromHasher; - type ValMmcs = MerkleTreeMmcs; - type ChallengeMmcs = ExtensionMmcs; - type Challenger = SerializingChallenger64>; - type Pcs = CirclePcs; - type MyConfig = StarkConfig; + type Val = p3_goldilocks::Goldilocks; + type Challenge = p3_field::extension::BinomialExtensionField; + type ByteHash = p3_sha256::Sha256; + type FieldHash = p3_symmetric::SerializingHasher; + type MyCompress = p3_symmetric::CompressionFunctionFromHasher; + type ValMmcs = p3_merkle_tree::MerkleTreeMmcs; + type ChallengeMmcs = p3_commit::ExtensionMmcs; + type Challenger = p3_challenger::SerializingChallenger64< + Val, + p3_challenger::HashChallenger, + >; + type Dft = p3_dft::Radix2DitParallel; + type Pcs = p3_fri::TwoAdicFriPcs; + type MyConfig = p3_uni_stark::StarkConfig; let byte_hash = ByteHash {}; - let field_hash = FieldHash::new(Sha256); + let field_hash = FieldHash::new(p3_sha256::Sha256); let compress = MyCompress::new(byte_hash); let val_mmcs = ValMmcs::new(field_hash, compress); let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); let challenger = Challenger::from_hasher(vec![], byte_hash); - let fri_params = create_benchmark_fri_params(challenge_mmcs); - let pcs = Pcs { - mmcs: val_mmcs, - fri_params, - _phantom: PhantomData, - }; + let dft = Dft::default(); + let fri_params = p3_fri::create_benchmark_fri_params(challenge_mmcs); + let pcs = Pcs::new(dft, val_mmcs, fri_params); let config = MyConfig::new(pcs, challenger); let inputs = generate_inputs(); - let inputs_goldilocks: Vec = - inputs.iter().map(|&x| Val::from_u32(x)).collect(); + let inputs_goldilocks: Vec = inputs + .iter() + .map(|&x| ::from_u32(x)) + .collect(); let trace = generate_trace_rows::(inputs); - check_constraints_with_periodic_columns(&$air_name {}, &trace, &inputs_goldilocks); - - /*let prove_with_periodic_columns = prove_with_periodic_columns(&config, &BitwiseAir {}, trace, &inputs_goldilocks); - verify_with_periodic_columns(&config, &BitwiseAir {}, &prove_with_periodic_columns, &inputs_goldilocks).expect("Verification failed");*/ - - /*let proof = prove(&config, &BitwiseAir {}, trace, &inputs_goldilocks); - verify(&config, &BitwiseAir {}, &proof, &inputs_goldilocks).expect("Verification failed");*/ + check_constraints_with_airscript_traits::( + &$air_name {}, + &trace, + &inputs_goldilocks, + ); } }; } diff --git a/air-script/tests/codegen/helpers.rs b/air-script/src/test_utils/codegen.rs similarity index 99% rename from air-script/tests/codegen/helpers.rs rename to air-script/src/test_utils/codegen.rs index 577144d42..9e68ca753 100644 --- a/air-script/tests/codegen/helpers.rs +++ b/air-script/src/test_utils/codegen.rs @@ -1,11 +1,12 @@ use std::sync::Arc; use air_ir::{CodeGenerator, CompileError}; -use air_script::compile; use miden_diagnostics::{ CodeMap, DefaultEmitter, DiagnosticsHandler, term::termcolor::ColorChoice, }; +use crate::compile; + pub enum Target { Winterfell, Plonky3, diff --git a/air-script/src/test_utils/miden_vm_aux_trace_generator.rs b/air-script/src/test_utils/miden_vm_aux_trace_generator.rs new file mode 100644 index 000000000..a6f9517c1 --- /dev/null +++ b/air-script/src/test_utils/miden_vm_aux_trace_generator.rs @@ -0,0 +1,116 @@ +use std::collections::BTreeMap; + +use miden_air::{Felt, FieldElement, trace::main_trace::MainTrace}; +use miden_processor::{ + ColMatrix, Kernel, PrecompileTranscriptState, QuadExtension, + chiplets::{AceHints, AuxTraceBuilder as ChipletsAuxTraceBuilder}, + decoder::AuxTraceBuilder as DecoderAuxTraceBuilder, + range::AuxTraceBuilder as RangeAuxTraceBuilder, + stack::AuxTraceBuilder as StackAuxTraceBuilder, +}; +use p3_field::{ExtensionField, Field, PrimeField64}; +use p3_matrix::Matrix; +use p3_miden_air::RowMajorMatrix; + +pub enum MidenModule { + Chiplets, + Decoder, + Stack, + Range, +} + +impl MidenModule { + fn build_aux_columns>( + &self, + main_trace: &MainTrace, + rand_elements: &[EF], + ) -> Vec> { + match self { + MidenModule::Chiplets => { + let kernel = Kernel::new(&[]).unwrap(); + let ace_hints = AceHints::new(0, vec![]); + let final_transcript_state = PrecompileTranscriptState::default(); + let aux_trace_builder = + ChipletsAuxTraceBuilder::new(kernel, ace_hints, final_transcript_state); + aux_trace_builder.build_aux_columns(main_trace, rand_elements).to_vec() + }, + MidenModule::Decoder => { + let aux_trace_builder = DecoderAuxTraceBuilder {}; + aux_trace_builder.build_aux_columns(main_trace, rand_elements) + }, + MidenModule::Stack => { + let aux_trace_builder = StackAuxTraceBuilder {}; + aux_trace_builder.build_aux_columns(main_trace, rand_elements) + }, + MidenModule::Range => { + let lookup_values = vec![]; + let cycle_lookups = BTreeMap::new(); + let values_start = 0; + let aux_trace_builder = + RangeAuxTraceBuilder::new(lookup_values, cycle_lookups, values_start); + aux_trace_builder.build_aux_columns(main_trace, rand_elements) + }, + } + } +} + +/// Builds the Miden VM auxiliary trace using the provided main trace and challenges. +pub fn build_aux_trace_with_miden_vm( + main: &RowMajorMatrix, + challenges: &[EF], + module: MidenModule, +) -> RowMajorMatrix +where + F: Field + PrimeField64, + EF: ExtensionField, +{ + // Convert main trace to Miden format: transposed to column-major and use `BaseElement` instead + // of `F`` + let main_transposed = main.transpose(); + let mut felt_columns_vec = Vec::new(); + for row in main_transposed.rows() { + let col_felt = row.map(|x| Felt::new(x.as_canonical_u64())).collect::>(); + felt_columns_vec.push(col_felt); + } + let col_matrix = ColMatrix::new(felt_columns_vec); + let last_program_row = main.height().into(); + let main_trace = MainTrace::new(col_matrix, last_program_row); + + // Convert challenges to Miden format + let mut rand_elements = Vec::new(); + for r in challenges { + let coeffs: Vec = r + .as_basis_coefficients_slice() + .iter() + .map(|x| Felt::new(x.as_canonical_u64())) + .collect(); + let r_fe: &[QuadExtension] = FieldElement::slice_from_base_elements(&coeffs); + rand_elements.push(r_fe[0]); + } + + // Build aux trace using Miden VM AuxTraceBuilder + let aux_trace_miden = module.build_aux_columns(&main_trace, &rand_elements); + let aux_width = aux_trace_miden.len(); + + // Convert aux trace back to RowMajorMatrix + let num_rows = main.height(); + let trace_length = num_rows * aux_width; + let long_trace = EF::zero_vec(trace_length); + let mut aux_trace = RowMajorMatrix::new(long_trace, aux_width); + + for j in 0..aux_width { + let col = aux_trace_miden.get(j).unwrap(); + for i in 0..num_rows { + let value_felt = col[i]; + let coeffs_f: Vec = value_felt + .to_base_elements() + .iter() + .map(|x| F::from_canonical_checked(x.as_int()).unwrap()) + .collect(); + let value_ef = EF::from_basis_coefficients_iter(coeffs_f.iter().cloned()).unwrap(); + aux_trace.row_mut(i)[j] = value_ef; + } + } + + aux_trace +} diff --git a/air-script/src/test_utils/mod.rs b/air-script/src/test_utils/mod.rs new file mode 100644 index 000000000..601c64017 --- /dev/null +++ b/air-script/src/test_utils/mod.rs @@ -0,0 +1,10 @@ +/// Macros to generate Air tester structs and tests for both Plonky3 and Winterfell backends. +pub mod air_tester_macros; +/// Code generation for tests/**/*.air files. +pub mod codegen; +/// Miden VM auxiliary trace generator +pub mod miden_vm_aux_trace_generator; +/// Plonky3-specific Debug constraint builder implementation +pub mod plonky3_traits; +/// Winterfell-specific traits +pub mod winterfell_traits; diff --git a/air-script/src/test_utils/plonky3_traits.rs b/air-script/src/test_utils/plonky3_traits.rs new file mode 100644 index 000000000..1985d1558 --- /dev/null +++ b/air-script/src/test_utils/plonky3_traits.rs @@ -0,0 +1,189 @@ +use p3_field::{ExtensionField, Field}; +use p3_matrix::{ + Matrix, + dense::{DenseMatrix, RowMajorMatrix, RowMajorMatrixView}, + stack::VerticalPair, +}; +use p3_miden_air::{MidenAir, MidenAirBuilder, impl_p3_air_builder_traits}; + +/// A builder that runs constraint assertions during testing. +/// +/// Used in conjunction with [`check_constraints`] to simulate an execution trace +/// and verify that the AIR logic enforces all constraints. +#[derive(Debug)] +pub struct DebugConstraintBuilderWithAirScriptTraits<'a, F: Field, EF: ExtensionField> { + /// The index of the row currently being evaluated. + row_index: usize, + /// A view of the current and next main row as a vertical pair. + main: VerticalPair, RowMajorMatrixView<'a, F>>, + /// A view of the current and next preprocessed row as a vertical pair. + preprocessed: VerticalPair, RowMajorMatrixView<'a, F>>, + /// A view of the current and next aux row as a vertical pair. + aux: VerticalPair, RowMajorMatrixView<'a, EF>>, + /// The public values provided for constraint validation (e.g. inputs or outputs). + public_values: &'a [F], + /// A flag indicating whether this is the first row. + is_first_row: F, + /// A flag indicating whether this is the last row. + is_last_row: F, + /// A flag indicating whether this is a transition row (not the last row). + is_transition: F, + /// The periodic columns provided for constraint validation. + periodic_columns: Vec, + /// The permutation randomness in the extension field. + permutation_randomness: Vec, + /// The aux bus boundary values in the extension field. + aux_bus_boundary_values: Vec, +} + +impl<'a, F, EF> MidenAirBuilder for DebugConstraintBuilderWithAirScriptTraits<'a, F, EF> +where + F: Field, + EF: ExtensionField, +{ + type F = F; + type Expr = F; + type Var = F; + type M = VerticalPair, DenseMatrix>; + type PublicVar = F; + type PeriodicVal = EF; + type EF = EF; + type ExprEF = EF; + type VarEF = EF; + type MP = VerticalPair, DenseMatrix>; + type RandomVar = EF; + + fn main(&self) -> Self::M { + self.main + } + + fn is_first_row(&self) -> Self::Expr { + self.is_first_row + } + + fn is_last_row(&self) -> Self::Expr { + self.is_last_row + } + + fn is_transition_window(&self, size: usize) -> Self::Expr { + if size == 2 { + self.is_transition + } else { + panic!("only supports a window size of 2") + } + } + + fn assert_zero>(&mut self, x: I) { + assert_eq!(x.into(), F::ZERO, "constraints had nonzero value on row {}", self.row_index); + } + + fn public_values(&self) -> &[Self::PublicVar] { + self.public_values + } + + fn periodic_evals(&self) -> &[::PeriodicVal] { + self.periodic_columns.as_slice() + } + + fn preprocessed(&self) -> Self::M { + self.preprocessed + } + + fn assert_zero_ext(&mut self, x: I) + where + I: Into, + { + assert_eq!( + x.into(), + EF::ZERO, + "constraints on ext field had nonzero value on row {}", + self.row_index + ); + } + + fn permutation(&self) -> Self::MP { + self.aux + } + + fn permutation_randomness(&self) -> &[Self::RandomVar] { + self.permutation_randomness.as_slice() + } + + fn aux_bus_boundary_values(&self) -> &[::VarEF] { + self.aux_bus_boundary_values.as_slice() + } +} + +impl_p3_air_builder_traits!(DebugConstraintBuilderWithAirScriptTraits<'a, F, EF> where F: Field, EF: ExtensionField); + +pub(crate) fn check_constraints_with_airscript_traits( + air: &A, + main: &RowMajorMatrix, + public_values: &Vec, +) where + F: Field, + EF: ExtensionField, + A: MidenAir, +{ + let height = main.height(); + + let aux_bus_boundary_values: Vec<_> = (0..air.aux_width()).map(|_| EF::GENERATOR).collect(); + let alpha = EF::from_basis_coefficients_iter( + (0..EF::DIMENSION).map(|i| F::from_u64(123456789 * (i as u64 + 1))), + ) + .unwrap(); + let beta = EF::from_u64(987654321); + let beta_powers: Vec = (0..(air.num_randomness().saturating_sub(1))) + .map(|power| beta.exp_u64(power as u64)) + .collect(); + let mut permutation_randomness = Vec::with_capacity(air.num_randomness()); + permutation_randomness.push(alpha); + permutation_randomness.extend_from_slice(beta_powers.as_slice()); + + let aux_trace = air + .build_aux_trace(main, &permutation_randomness) + .unwrap_or(DenseMatrix::default(0, height)); + + (0..height).for_each(|i| { + let i_next = (i + 1) % height; + + let main_local = main.row_slice(i).unwrap(); // i < height so unwrap should never fail. + let main_next = main.row_slice(i_next).unwrap(); // i_next < height so unwrap should never fail. + let main = VerticalPair::new( + RowMajorMatrixView::new_row(&*main_local), + RowMajorMatrixView::new_row(&*main_next), + ); + let aux_local_ref = aux_trace.row_slice(i); + let aux_next_ref = aux_trace.row_slice(i_next); + let aux_local = aux_local_ref.as_deref().unwrap_or_default(); + let aux_next = aux_next_ref.as_deref().unwrap_or_default(); + let aux = VerticalPair::new( + RowMajorMatrixView::new_row(&*aux_local), + RowMajorMatrixView::new_row(&*aux_next), + ); + let preprocessed = VerticalPair::new::( + RowMajorMatrixView::new(&[], 0), + RowMajorMatrixView::new(&[], 0), + ); + + let periodic_columns_base: Vec<_> = + air.periodic_table().iter().map(|col| col[i % col.len()]).collect(); + let periodic_columns: Vec = + periodic_columns_base.iter().map(|&v| EF::from(v)).collect(); + + let mut builder = DebugConstraintBuilderWithAirScriptTraits { + row_index: i, + main, + preprocessed, + aux, + public_values, + is_first_row: F::from_bool(i == 0), + is_last_row: F::from_bool(i == height - 1), + is_transition: F::from_bool(i != height - 1), + periodic_columns, + permutation_randomness: permutation_randomness.clone(), + aux_bus_boundary_values: aux_bus_boundary_values.clone(), + }; + air.eval(&mut builder); + }); +} diff --git a/air-script/tests/helpers/winterfell_test_helpers.rs b/air-script/src/test_utils/winterfell_traits.rs similarity index 100% rename from air-script/tests/helpers/winterfell_test_helpers.rs rename to air-script/src/test_utils/winterfell_traits.rs diff --git a/air-script/tests/binary/binary.air b/air-script/src/tests/binary/binary.air similarity index 100% rename from air-script/tests/binary/binary.air rename to air-script/src/tests/binary/binary.air diff --git a/air-script/tests/binary/binary.rs b/air-script/src/tests/binary/binary.rs similarity index 100% rename from air-script/tests/binary/binary.rs rename to air-script/src/tests/binary/binary.rs diff --git a/air-script/src/tests/binary/binary_plonky3.rs b/air-script/src/tests/binary/binary_plonky3.rs new file mode 100644 index 000000000..0c514ea56 --- /dev/null +++ b/air-script/src/tests/binary/binary_plonky3.rs @@ -0,0 +1,44 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 2; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct BinaryAir; + +impl MidenAir for BinaryAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into() - public_values[0].into()); + + // Main integrity/transition constraints + builder.assert_zero(main_current[0].clone().into() * main_current[0].clone().into() - main_current[0].clone().into()); + builder.assert_zero(main_current[1].clone().into() * main_current[1].clone().into() - main_current[1].clone().into()); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/binary/mod.rs b/air-script/src/tests/binary/mod.rs similarity index 100% rename from air-script/tests/binary/mod.rs rename to air-script/src/tests/binary/mod.rs diff --git a/air-script/tests/binary/test_air_plonky3.rs b/air-script/src/tests/binary/test_air_plonky3.rs similarity index 51% rename from air-script/tests/binary/test_air_plonky3.rs rename to air-script/src/tests/binary/test_air_plonky3.rs index cb06fb5f4..eced0b469 100644 --- a/air-script/tests/binary/test_air_plonky3.rs +++ b/air-script/src/tests/binary/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - binary::binary_plonky3::{BinaryAir, NUM_COLUMNS}, - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::binary::binary_plonky3::{BinaryAir, MAIN_WIDTH}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -52,4 +41,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -generate_air_plonky3_test!(test_air_plonky3, BinaryAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, BinaryAir); diff --git a/air-script/tests/binary/test_air_winterfell.rs b/air-script/src/tests/binary/test_air_winterfell.rs similarity index 87% rename from air-script/tests/binary/test_air_winterfell.rs rename to air-script/src/tests/binary/test_air_winterfell.rs index eca996b11..2135c11b6 100644 --- a/air-script/tests/binary/test_air_winterfell.rs +++ b/air-script/src/tests/binary/test_air_winterfell.rs @@ -3,9 +3,9 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - binary::binary::PublicInputs, generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::binary::binary::PublicInputs, }; #[derive(Clone)] @@ -41,7 +41,7 @@ impl AirTester for BinaryAirTester { generate_air_winterfell_test!( test_binary_air, - crate::binary::binary::BinaryAir, + crate::tests::binary::binary::BinaryAir, BinaryAirTester, 1024 ); diff --git a/air-script/tests/bitwise/bitwise.air b/air-script/src/tests/bitwise/bitwise.air similarity index 100% rename from air-script/tests/bitwise/bitwise.air rename to air-script/src/tests/bitwise/bitwise.air diff --git a/air-script/tests/bitwise/bitwise.rs b/air-script/src/tests/bitwise/bitwise.rs similarity index 100% rename from air-script/tests/bitwise/bitwise.rs rename to air-script/src/tests/bitwise/bitwise.rs diff --git a/air-script/src/tests/bitwise/bitwise_plonky3.rs b/air-script/src/tests/bitwise/bitwise_plonky3.rs new file mode 100644 index 000000000..bfded5b9b --- /dev/null +++ b/air-script/src/tests/bitwise/bitwise_plonky3.rs @@ -0,0 +1,73 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 14; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 2; +pub const PERIOD: usize = 8; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct BitwiseAir; + +impl MidenAir for BitwiseAir +where F: Field, + EF: ExtensionField, +{ + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } + + fn periodic_table(&self) -> Vec> { + vec![ + vec![F::from_u64(1), F::from_u64(0), F::from_u64(0), F::from_u64(0), F::from_u64(0), F::from_u64(0), F::from_u64(0), F::from_u64(0)], + vec![F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(0)], + ] + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[13].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero(main_current[0].clone().into() * main_current[0].clone().into() - main_current[0].clone().into()); + builder.when_transition().assert_zero_ext(AB::ExprEF::from(periodic_values[1].clone().into()) * (AB::ExprEF::from(main_next[0].clone().into()) - AB::ExprEF::from(main_current[0].clone().into()))); + builder.assert_zero(main_current[3].clone().into() * main_current[3].clone().into() - main_current[3].clone().into()); + builder.assert_zero(main_current[4].clone().into() * main_current[4].clone().into() - main_current[4].clone().into()); + builder.assert_zero(main_current[5].clone().into() * main_current[5].clone().into() - main_current[5].clone().into()); + builder.assert_zero(main_current[6].clone().into() * main_current[6].clone().into() - main_current[6].clone().into()); + builder.assert_zero(main_current[7].clone().into() * main_current[7].clone().into() - main_current[7].clone().into()); + builder.assert_zero(main_current[8].clone().into() * main_current[8].clone().into() - main_current[8].clone().into()); + builder.assert_zero(main_current[9].clone().into() * main_current[9].clone().into() - main_current[9].clone().into()); + builder.assert_zero(main_current[10].clone().into() * main_current[10].clone().into() - main_current[10].clone().into()); + builder.assert_zero_ext(AB::ExprEF::from(periodic_values[0].clone().into()) * (AB::ExprEF::from(main_current[1].clone().into()) - (AB::ExprEF::from(main_current[3].clone().into()) + AB::ExprEF::from(main_current[4].clone().into()).double() + AB::ExprEF::from_u64(4) * AB::ExprEF::from(main_current[5].clone().into()) + AB::ExprEF::from_u64(8) * AB::ExprEF::from(main_current[6].clone().into())))); + builder.assert_zero_ext(AB::ExprEF::from(periodic_values[0].clone().into()) * (AB::ExprEF::from(main_current[2].clone().into()) - (AB::ExprEF::from(main_current[7].clone().into()) + AB::ExprEF::from(main_current[8].clone().into()).double() + AB::ExprEF::from_u64(4) * AB::ExprEF::from(main_current[9].clone().into()) + AB::ExprEF::from_u64(8) * AB::ExprEF::from(main_current[10].clone().into())))); + builder.when_transition().assert_zero_ext(AB::ExprEF::from(periodic_values[1].clone().into()) * (AB::ExprEF::from(main_next[1].clone().into()) - (AB::ExprEF::from(main_current[1].clone().into()) * AB::ExprEF::from_u64(16) + AB::ExprEF::from(main_current[3].clone().into()) + AB::ExprEF::from(main_current[4].clone().into()).double() + AB::ExprEF::from_u64(4) * AB::ExprEF::from(main_current[5].clone().into()) + AB::ExprEF::from_u64(8) * AB::ExprEF::from(main_current[6].clone().into())))); + builder.when_transition().assert_zero_ext(AB::ExprEF::from(periodic_values[1].clone().into()) * (AB::ExprEF::from(main_next[2].clone().into()) - (AB::ExprEF::from(main_current[2].clone().into()) * AB::ExprEF::from_u64(16) + AB::ExprEF::from(main_current[7].clone().into()) + AB::ExprEF::from(main_current[8].clone().into()).double() + AB::ExprEF::from_u64(4) * AB::ExprEF::from(main_current[9].clone().into()) + AB::ExprEF::from_u64(8) * AB::ExprEF::from(main_current[10].clone().into())))); + builder.assert_zero_ext(AB::ExprEF::from(periodic_values[0].clone().into()) * AB::ExprEF::from(main_current[11].clone().into())); + builder.when_transition().assert_zero_ext(AB::ExprEF::from(periodic_values[1].clone().into()) * (AB::ExprEF::from(main_current[12].clone().into()) - AB::ExprEF::from(main_next[11].clone().into()))); + builder.assert_zero((AB::Expr::ONE - main_current[0].clone().into()) * (main_current[12].clone().into() - (main_current[11].clone().into() * AB::Expr::from_u64(16) + main_current[3].clone().into() * main_current[7].clone().into() + main_current[4].clone().into().double() * main_current[8].clone().into() + AB::Expr::from_u64(4) * main_current[5].clone().into() * main_current[9].clone().into() + AB::Expr::from_u64(8) * main_current[6].clone().into() * main_current[10].clone().into())) + main_current[0].clone().into() * (main_current[12].clone().into() - (main_current[11].clone().into() * AB::Expr::from_u64(16) + main_current[3].clone().into() + main_current[7].clone().into() - main_current[3].clone().into().double() * main_current[7].clone().into() + (main_current[4].clone().into() + main_current[8].clone().into() - main_current[4].clone().into().double() * main_current[8].clone().into()).double() + AB::Expr::from_u64(4) * (main_current[5].clone().into() + main_current[9].clone().into() - main_current[5].clone().into().double() * main_current[9].clone().into()) + AB::Expr::from_u64(8) * (main_current[6].clone().into() + main_current[10].clone().into() - main_current[6].clone().into().double() * main_current[10].clone().into())))); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/bitwise/mod.rs b/air-script/src/tests/bitwise/mod.rs similarity index 86% rename from air-script/tests/bitwise/mod.rs rename to air-script/src/tests/bitwise/mod.rs index 31fe7ab14..54b732efb 100644 --- a/air-script/tests/bitwise/mod.rs +++ b/air-script/src/tests/bitwise/mod.rs @@ -3,6 +3,7 @@ mod bitwise; #[rustfmt::skip] #[allow(clippy::all)] +#[allow(unused_imports)] mod bitwise_plonky3; mod test_air_plonky3; diff --git a/air-script/tests/bitwise/test_air_plonky3.rs b/air-script/src/tests/bitwise/test_air_plonky3.rs similarity index 70% rename from air-script/tests/bitwise/test_air_plonky3.rs rename to air-script/src/tests/bitwise/test_air_plonky3.rs index d3c6efcaa..d969cb1a6 100644 --- a/air-script/tests/bitwise/test_air_plonky3.rs +++ b/air-script/src/tests/bitwise/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - bitwise::bitwise_plonky3::{BitwiseAir, NUM_COLUMNS}, - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::bitwise::bitwise_plonky3::{BitwiseAir, MAIN_WIDTH}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -90,4 +79,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -generate_air_plonky3_test!(test_air_plonky3, BitwiseAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, BitwiseAir); diff --git a/air-script/tests/bitwise/test_air_winterfell.rs b/air-script/src/tests/bitwise/test_air_winterfell.rs similarity index 90% rename from air-script/tests/bitwise/test_air_winterfell.rs rename to air-script/src/tests/bitwise/test_air_winterfell.rs index c5166f091..e563782ef 100644 --- a/air-script/tests/bitwise/test_air_winterfell.rs +++ b/air-script/src/tests/bitwise/test_air_winterfell.rs @@ -5,9 +5,9 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{AuxTraceWithMetadata, Trace, TraceTable, matrix::ColMatrix}; use crate::{ - bitwise::bitwise::PublicInputs, generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::bitwise::bitwise::PublicInputs, }; #[derive(Clone)] @@ -52,7 +52,7 @@ impl AirTester for BitwiseAirTester { generate_air_winterfell_test!( test_bitwise_air, - crate::bitwise::bitwise::BitwiseAir, + crate::tests::bitwise::bitwise::BitwiseAir, BitwiseAirTester, 1024 ); diff --git a/air-script/tests/buses/buses_complex.air b/air-script/src/tests/buses/buses_complex.air similarity index 80% rename from air-script/tests/buses/buses_complex.air rename to air-script/src/tests/buses/buses_complex.air index 401ca8b67..f27a2745c 100644 --- a/air-script/tests/buses/buses_complex.air +++ b/air-script/src/tests/buses/buses_complex.air @@ -1,7 +1,7 @@ def BusesAir trace_columns { - main: [a, b, s1, s2, d], + main: [a, b, s1, s2, s3, s4, d], } buses { @@ -34,7 +34,7 @@ integrity_constraints { p.insert(2, b) when 1 - s1; p.remove(2, a) when 1 - s2; - q.insert(3, a) when s1; - q.insert(3, a) when s1; - q.remove(4, b) with d; + q.insert(3, a) when s3; + q.insert(3, a) when s4; + q.remove(3, b) with d; } diff --git a/air-script/tests/buses/buses_complex.rs b/air-script/src/tests/buses/buses_complex.rs similarity index 93% rename from air-script/tests/buses/buses_complex.rs rename to air-script/src/tests/buses/buses_complex.rs index d15eeeb8f..33271a2ab 100644 --- a/air-script/tests/buses/buses_complex.rs +++ b/air-script/src/tests/buses/buses_complex.rs @@ -99,6 +99,6 @@ impl Air for BusesAir { let aux_current = aux_frame.current(); let aux_next = aux_frame.next(); result[0] = ((aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + (E::from(Felt::new(3_u64)) + E::from(main_current[1])) * aux_rand_elements.rand_elements()[2] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[3]) * E::from(main_current[2]) + E::ONE - E::from(main_current[2])) * ((aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[1]) * aux_rand_elements.rand_elements()[2]) * (E::ONE - E::from(main_current[2])) + E::from(main_current[2])) * aux_current[0] - ((aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + (E::from(Felt::new(3_u64)) + E::from(main_current[1])) * aux_rand_elements.rand_elements()[2] + E::from(main_current[1]) * aux_rand_elements.rand_elements()[3]) * E::from(main_current[3]) + E::ONE - E::from(main_current[3])) * ((aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (E::ONE - E::from(main_current[3])) + E::from(main_current[3])) * aux_next[0]; - result[1] = (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(4_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[1]) * aux_rand_elements.rand_elements()[2]) * aux_current[1] + (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(4_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[1]) * aux_rand_elements.rand_elements()[2]) * E::from(main_current[2]) + (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(4_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[1]) * aux_rand_elements.rand_elements()[2]) * E::from(main_current[2]) - ((aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(4_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[1]) * aux_rand_elements.rand_elements()[2]) * aux_next[1] + (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * E::from(main_current[4])); + result[1] = (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[1]) * aux_rand_elements.rand_elements()[2]) * aux_current[1] + (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[1]) * aux_rand_elements.rand_elements()[2]) * E::from(main_current[4]) + (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[1]) * aux_rand_elements.rand_elements()[2]) * E::from(main_current[5]) - ((aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[1]) * aux_rand_elements.rand_elements()[2]) * aux_next[1] + (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(3_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * E::from(main_current[6])); } } \ No newline at end of file diff --git a/air-script/src/tests/buses/buses_complex_plonky3.rs b/air-script/src/tests/buses/buses_complex_plonky3.rs new file mode 100644 index 000000000..00d266cf9 --- /dev/null +++ b/air-script/src/tests/buses/buses_complex_plonky3.rs @@ -0,0 +1,138 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 7; +pub const AUX_WIDTH: usize = 2; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 2; +pub const MAX_BETA_CHALLENGE_POWER: usize = 3; + +pub struct BusesAir; + +impl MidenAir for BusesAir +where F: Field, + EF: ExtensionField, +{ + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn num_randomness(&self) -> usize { + 1 + MAX_BETA_CHALLENGE_POWER + } + + fn aux_width(&self) -> usize { + AUX_WIDTH + } + + fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { + // Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders. + + let num_rows = _main.height(); + let trace_length = num_rows * AUX_WIDTH; + let mut long_trace = EF::zero_vec(trace_length); + let mut trace = RowMajorMatrix::new(long_trace, AUX_WIDTH); + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[EF; AUX_WIDTH]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + // Initialize first row + let initial_values = Self::buses_initial_values::(); + for j in 0..AUX_WIDTH { + rows[0][j] = initial_values[j]; + } + // Fill subsequent rows using direct access to the rows array + for i in 0..num_rows-1 { + let i_next = (i + 1) % num_rows; + let main_local = _main.row_slice(i).unwrap(); // i < height so unwrap should never fail. + let main_next = _main.row_slice(i_next).unwrap(); // i_next < height so unwrap should never fail. + let main = VerticalPair::new( + RowMajorMatrixView::new_row(&*main_local), + RowMajorMatrixView::new_row(&*main_next), + ); + let periodic_values: [_; NUM_PERIODIC_VALUES] = >::periodic_table(self).iter().map(|col| col[i % col.len()]).collect::>().try_into().expect("Wrong number of periodic values"); + let prev_row = &rows[i]; + let next_row = Self::buses_transitions::( + &main, + _challenges, + &periodic_values, + prev_row, + ); + for j in 0..AUX_WIDTH { + rows[i+1][j] = next_row[j]; + } + } + Some(trace) + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + let (&alpha, beta_challenges) = builder.permutation_randomness().split_first().expect("Wrong number of randomness"); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); + let aux_bus_boundary_values: [_; AUX_WIDTH] = builder.aux_bus_boundary_values().try_into().expect("Wrong number of aux bus boundary values"); + let aux = builder.permutation(); + let (aux_current, aux_next) = ( + aux.row_slice(0).unwrap(), + aux.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero(main_current[2].clone().into() * main_current[2].clone().into() - main_current[2].clone().into()); + builder.assert_zero(main_current[3].clone().into() * main_current[3].clone().into() - main_current[3].clone().into()); + + // Aux boundary constraints + builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); + builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); + builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); + builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); + + // Aux integrity/transition constraints + builder.when_transition().assert_zero_ext(((alpha.into() + beta_challenges[0].into() + (AB::ExprEF::from_u64(3) + AB::ExprEF::from(main_current[1].clone().into())) * beta_challenges[1].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[2].into()) * AB::ExprEF::from(main_current[2].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[2].clone().into())) * ((alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[1].clone().into()) * beta_challenges[1].into()) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[2].clone().into())) + AB::ExprEF::from(main_current[2].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into() + (AB::ExprEF::from_u64(3) + AB::ExprEF::from(main_current[1].clone().into())) * beta_challenges[1].into() + AB::ExprEF::from(main_current[1].clone().into()) * beta_challenges[2].into()) * AB::ExprEF::from(main_current[3].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[3].clone().into())) * ((alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[3].clone().into())) + AB::ExprEF::from(main_current[3].clone().into())) * AB::ExprEF::from(aux_next[0].clone().into())); + builder.when_transition().assert_zero_ext((alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[1].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(aux_current[1].clone().into()) + (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[1].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(main_current[4].clone().into()) + (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[1].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(main_current[5].clone().into()) - ((alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[1].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(aux_next[1].clone().into()) + (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(main_current[6].clone().into()))); + } +} + +impl BusesAir { + fn buses_initial_values() -> Vec + where F: Field, + EF: ExtensionField, + { + vec![ + EF::ONE, + EF::ZERO, + ] + } + + fn buses_transitions(main: &VerticalPair, RowMajorMatrixView>, challenges: &[EF], periodic_evals: &[F], aux_current: &[EF]) -> Vec + where F: Field, + EF: ExtensionField, + { + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + let (&alpha, beta_challenges) = challenges.split_first().expect("Wrong number of randomness"); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = periodic_evals.try_into().expect("Wrong number of periodic values"); + vec![ + (((alpha + beta_challenges[0] + (EF::from_u64(3) + EF::from(main_current[1].clone())) * beta_challenges[1] + EF::from(main_current[0].clone()) * beta_challenges[2]) * EF::from(main_current[2].clone()) + EF::ONE - EF::from(main_current[2].clone())) * ((alpha + beta_challenges[0].double() + EF::from(main_current[1].clone()) * beta_challenges[1]) * (EF::ONE - EF::from(main_current[2].clone())) + EF::from(main_current[2].clone())) * EF::from(aux_current[0].clone())) * (((alpha + beta_challenges[0] + (EF::from_u64(3) + EF::from(main_current[1].clone())) * beta_challenges[1] + EF::from(main_current[1].clone()) * beta_challenges[2]) * EF::from(main_current[3].clone()) + EF::ONE - EF::from(main_current[3].clone())) * ((alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1]) * (EF::ONE - EF::from(main_current[3].clone())) + EF::from(main_current[3].clone()))).inverse(), + ((alpha + EF::from_u64(3) * beta_challenges[0] + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + EF::from_u64(3) * beta_challenges[0] + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + EF::from_u64(3) * beta_challenges[0] + EF::from(main_current[1].clone()) * beta_challenges[1]) * EF::from(aux_current[1].clone()) + (alpha + EF::from_u64(3) * beta_challenges[0] + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + EF::from_u64(3) * beta_challenges[0] + EF::from(main_current[1].clone()) * beta_challenges[1]) * EF::from(main_current[4].clone()) + (alpha + EF::from_u64(3) * beta_challenges[0] + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + EF::from_u64(3) * beta_challenges[0] + EF::from(main_current[1].clone()) * beta_challenges[1]) * EF::from(main_current[5].clone()) - (alpha + EF::from_u64(3) * beta_challenges[0] + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + EF::from_u64(3) * beta_challenges[0] + EF::from(main_current[0].clone()) * beta_challenges[1]) * EF::from(main_current[6].clone())) * ((alpha + EF::from_u64(3) * beta_challenges[0] + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + EF::from_u64(3) * beta_challenges[0] + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + EF::from_u64(3) * beta_challenges[0] + EF::from(main_current[1].clone()) * beta_challenges[1])).inverse(), + ] + } +} \ No newline at end of file diff --git a/air-script/tests/buses/buses_simple.air b/air-script/src/tests/buses/buses_simple.air similarity index 100% rename from air-script/tests/buses/buses_simple.air rename to air-script/src/tests/buses/buses_simple.air diff --git a/air-script/tests/buses/buses_simple.rs b/air-script/src/tests/buses/buses_simple.rs similarity index 100% rename from air-script/tests/buses/buses_simple.rs rename to air-script/src/tests/buses/buses_simple.rs diff --git a/air-script/src/tests/buses/buses_simple_plonky3.rs b/air-script/src/tests/buses/buses_simple_plonky3.rs new file mode 100644 index 000000000..1ee51d533 --- /dev/null +++ b/air-script/src/tests/buses/buses_simple_plonky3.rs @@ -0,0 +1,133 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 1; +pub const AUX_WIDTH: usize = 2; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 2; +pub const MAX_BETA_CHALLENGE_POWER: usize = 2; + +pub struct BusesAir; + +impl MidenAir for BusesAir +where F: Field, + EF: ExtensionField, +{ + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn num_randomness(&self) -> usize { + 1 + MAX_BETA_CHALLENGE_POWER + } + + fn aux_width(&self) -> usize { + AUX_WIDTH + } + + fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { + // Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders. + + let num_rows = _main.height(); + let trace_length = num_rows * AUX_WIDTH; + let mut long_trace = EF::zero_vec(trace_length); + let mut trace = RowMajorMatrix::new(long_trace, AUX_WIDTH); + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[EF; AUX_WIDTH]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + // Initialize first row + let initial_values = Self::buses_initial_values::(); + for j in 0..AUX_WIDTH { + rows[0][j] = initial_values[j]; + } + // Fill subsequent rows using direct access to the rows array + for i in 0..num_rows-1 { + let i_next = (i + 1) % num_rows; + let main_local = _main.row_slice(i).unwrap(); // i < height so unwrap should never fail. + let main_next = _main.row_slice(i_next).unwrap(); // i_next < height so unwrap should never fail. + let main = VerticalPair::new( + RowMajorMatrixView::new_row(&*main_local), + RowMajorMatrixView::new_row(&*main_next), + ); + let periodic_values: [_; NUM_PERIODIC_VALUES] = >::periodic_table(self).iter().map(|col| col[i % col.len()]).collect::>().try_into().expect("Wrong number of periodic values"); + let prev_row = &rows[i]; + let next_row = Self::buses_transitions::( + &main, + _challenges, + &periodic_values, + prev_row, + ); + for j in 0..AUX_WIDTH { + rows[i+1][j] = next_row[j]; + } + } + Some(trace) + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + let (&alpha, beta_challenges) = builder.permutation_randomness().split_first().expect("Wrong number of randomness"); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); + let aux_bus_boundary_values: [_; AUX_WIDTH] = builder.aux_bus_boundary_values().try_into().expect("Wrong number of aux bus boundary values"); + let aux = builder.permutation(); + let (aux_current, aux_next) = ( + aux.row_slice(0).unwrap(), + aux.row_slice(1).unwrap(), + ); + + // Main boundary constraints + + // Main integrity/transition constraints + + // Aux boundary constraints + builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); + builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); + builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); + + // Aux integrity/transition constraints + builder.when_transition().assert_zero_ext(((alpha.into() + beta_challenges[0].into()) * AB::ExprEF::from(main_current[0].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into()) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) + AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(aux_next[0].clone().into())); + builder.when_transition().assert_zero_ext((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_current[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_next[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()).double())); + } +} + +impl BusesAir { + fn buses_initial_values() -> Vec + where F: Field, + EF: ExtensionField, + { + vec![ + EF::ZERO, + ] + } + + fn buses_transitions(main: &VerticalPair, RowMajorMatrixView>, challenges: &[EF], periodic_evals: &[F], aux_current: &[EF]) -> Vec + where F: Field, + EF: ExtensionField, + { + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + let (&alpha, beta_challenges) = challenges.split_first().expect("Wrong number of randomness"); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = periodic_evals.try_into().expect("Wrong number of periodic values"); + vec![ + (((alpha + beta_challenges[0]) * EF::from(main_current[0].clone()) + EF::ONE - EF::from(main_current[0].clone())) * EF::from(aux_current[0].clone())) * ((alpha + beta_challenges[0]) * (EF::ONE - EF::from(main_current[0].clone())) + EF::from(main_current[0].clone())).inverse(), + ((alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(aux_current[1].clone()) + (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(main_current[0].clone()) - (alpha + beta_challenges[0] + beta_challenges[1].double()).double()) * ((alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double())).inverse(), + ] + } +} \ No newline at end of file diff --git a/air-script/tests/buses/buses_simple_with_evaluators.air b/air-script/src/tests/buses/buses_simple_with_evaluators.air similarity index 100% rename from air-script/tests/buses/buses_simple_with_evaluators.air rename to air-script/src/tests/buses/buses_simple_with_evaluators.air diff --git a/air-script/src/tests/buses/buses_simple_with_evaluators.rs b/air-script/src/tests/buses/buses_simple_with_evaluators.rs new file mode 100644 index 000000000..b0012a15a --- /dev/null +++ b/air-script/src/tests/buses/buses_simple_with_evaluators.rs @@ -0,0 +1,100 @@ +use winter_air::{Air, AirContext, Assertion, AuxRandElements, EvaluationFrame, ProofOptions as WinterProofOptions, TransitionConstraintDegree, TraceInfo}; +use winter_math::fields::f64::BaseElement as Felt; +use winter_math::{ExtensionOf, FieldElement, ToElements}; +use winter_utils::{ByteWriter, Serializable}; + +pub struct PublicInputs { + inputs: [Felt; 2], +} + +impl PublicInputs { + pub fn new(inputs: [Felt; 2]) -> Self { + Self { inputs } + } +} + +impl Serializable for PublicInputs { + fn write_into(&self, target: &mut W) { + self.inputs.write_into(target); + } +} + +impl ToElements for PublicInputs { + fn to_elements(&self) -> Vec { + let mut elements = Vec::new(); + elements.extend_from_slice(&self.inputs); + elements + } +} + +pub struct BusesAir { + context: AirContext, + inputs: [Felt; 2], +} + +impl BusesAir { + pub fn last_step(&self) -> usize { + self.trace_length() - self.context().num_transition_exemptions() + } +} + +impl Air for BusesAir { + type BaseField = Felt; + type PublicInputs = PublicInputs; + + fn context(&self) -> &AirContext { + &self.context + } + + fn new(trace_info: TraceInfo, public_inputs: PublicInputs, options: WinterProofOptions) -> Self { + let main_degrees = vec![]; + let aux_degrees = vec![TransitionConstraintDegree::new(2), TransitionConstraintDegree::new(1)]; + let num_main_assertions = 0; + let num_aux_assertions = 3; + + let context = AirContext::new_multi_segment( + trace_info, + main_degrees, + aux_degrees, + num_main_assertions, + num_aux_assertions, + options, + ) + .set_num_transition_exemptions(2); + Self { context, inputs: public_inputs.inputs } + } + + fn get_periodic_column_values(&self) -> Vec> { + vec![] + } + + fn get_assertions(&self) -> Vec> { + let mut result = Vec::new(); + result + } + + fn get_aux_assertions>(&self, aux_rand_elements: &AuxRandElements) -> Vec> { + let mut result = Vec::new(); + result.push(Assertion::single(0, self.last_step(), E::ONE)); + result.push(Assertion::single(1, 0, E::ZERO)); + result.push(Assertion::single(1, self.last_step(), E::ZERO)); + result + } + + fn evaluate_transition>(&self, frame: &EvaluationFrame, periodic_values: &[E], result: &mut [E]) { + let main_current = frame.current(); + let main_next = frame.next(); + } + + fn evaluate_aux_transition(&self, main_frame: &EvaluationFrame, aux_frame: &EvaluationFrame, _periodic_values: &[F], aux_rand_elements: &AuxRandElements, result: &mut [E]) + where F: FieldElement, + E: FieldElement + ExtensionOf, + { + let main_current = main_frame.current(); + let main_next = main_frame.next(); + let aux_current = aux_frame.current(); + let aux_next = aux_frame.next(); + result[0] = ((aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1]) * E::from(main_current[0]) + E::ONE - E::from(main_current[0])) * aux_current[0] - ((aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1]) * (E::ONE - E::from(main_current[0])) + E::from(main_current[0])) * aux_next[0]; + result[1] = (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * aux_current[1] + (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * E::from(main_current[0]) - ((aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * aux_next[1] + (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * E::from(Felt::new(2_u64))); + } +} \ No newline at end of file diff --git a/air-script/src/tests/buses/buses_simple_with_evaluators_plonky3.rs b/air-script/src/tests/buses/buses_simple_with_evaluators_plonky3.rs new file mode 100644 index 000000000..7ad2d398f --- /dev/null +++ b/air-script/src/tests/buses/buses_simple_with_evaluators_plonky3.rs @@ -0,0 +1,108 @@ +use crate::test_utils::plonky3_traits::{AirScriptAir, AirScriptBuilder}; +use p3_air::{Air, AirBuilder, BaseAir, BaseAirWithPublicValues, ExtensionBuilder}; +use p3_field::{Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; + +pub const MAIN_WIDTH: usize = 1; +pub const AUX_WIDTH: usize = 2; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 2; +pub const MAX_BETA_CHALLENGE_POWER: usize = 2; + +pub struct BusesAir; + +impl BaseAir for BusesAir { + fn width(&self) -> usize { + MAIN_WIDTH + } +} + +impl BaseAirWithPublicValues for BusesAir { + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } +} + +impl> AirScriptAir for BusesAir { + fn aux_width(&self) -> usize { + AUX_WIDTH + } + + fn max_beta_challenge_powers(&self) -> usize { + MAX_BETA_CHALLENGE_POWER + } + + fn periodic_table(&self) -> Vec> { + vec![] + } + + fn eval(&self, builder: &mut AB) { + let public_values: [_; NUM_PUBLIC_VALUES] = + builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = + builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let main = builder.main(); + let (main_current, main_next) = (main.row_slice(0).unwrap(), main.row_slice(1).unwrap()); + let alpha = builder.alpha(); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = + builder.beta_powers().try_into().expect("Wrong number of beta challenges"); + let aux_bus_boundary_values: [_; AUX_WIDTH] = builder + .aux_bus_boundary_values() + .try_into() + .expect("Wrong number of aux bus boundary values"); + let aux = builder.permutation(); + let (aux_current, aux_next) = (aux.row_slice(0).unwrap(), aux.row_slice(1).unwrap()); + + // Main boundary constraints + + // Main integrity/transition constraints + + // Aux boundary constraints + builder + .when_last_row() + .assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); + builder + .when_first_row() + .assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); + builder + .when_last_row() + .assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); + + // Aux integrity/transition constraints + builder.when_transition().assert_zero_ext( + ((alpha.into() + beta_challenges[0].into()) + * AB::ExprEF::from(main_current[0].clone().into()) + + AB::ExprEF::ONE + - AB::ExprEF::from(main_current[0].clone().into())) + * AB::ExprEF::from(aux_current[0].clone().into()) + - ((alpha.into() + beta_challenges[0].into()) + * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) + + AB::ExprEF::from(main_current[0].clone().into())) + * AB::ExprEF::from(aux_next[0].clone().into()), + ); + builder.when_transition().assert_zero_ext( + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) + * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) + * AB::ExprEF::from(aux_current[1].clone().into()) + + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) + * AB::ExprEF::from(main_current[0].clone().into()) + - ((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) + * (alpha.into() + + beta_challenges[0].into() + + beta_challenges[1].into().double()) + * AB::ExprEF::from(aux_next[1].clone().into()) + + (alpha.into() + + beta_challenges[0].into() + + beta_challenges[1].into().double()) + .double()), + ); + } +} + +impl Air for BusesAir { + fn eval(&self, builder: &mut AB) { + >::eval(self, builder); + } +} + diff --git a/air-script/tests/buses/buses_varlen_boundary_both.air b/air-script/src/tests/buses/buses_varlen_boundary_both.air similarity index 100% rename from air-script/tests/buses/buses_varlen_boundary_both.air rename to air-script/src/tests/buses/buses_varlen_boundary_both.air diff --git a/air-script/tests/buses/buses_varlen_boundary_both.rs b/air-script/src/tests/buses/buses_varlen_boundary_both.rs similarity index 100% rename from air-script/tests/buses/buses_varlen_boundary_both.rs rename to air-script/src/tests/buses/buses_varlen_boundary_both.rs diff --git a/air-script/src/tests/buses/buses_varlen_boundary_both_plonky3.rs b/air-script/src/tests/buses/buses_varlen_boundary_both_plonky3.rs new file mode 100644 index 000000000..13ed74cc7 --- /dev/null +++ b/air-script/src/tests/buses/buses_varlen_boundary_both_plonky3.rs @@ -0,0 +1,134 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 1; +pub const AUX_WIDTH: usize = 2; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 6; +pub const MAX_BETA_CHALLENGE_POWER: usize = 2; + +pub struct BusesAir; + +impl MidenAir for BusesAir +where F: Field, + EF: ExtensionField, +{ + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn num_randomness(&self) -> usize { + 1 + MAX_BETA_CHALLENGE_POWER + } + + fn aux_width(&self) -> usize { + AUX_WIDTH + } + + fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { + // Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders. + + let num_rows = _main.height(); + let trace_length = num_rows * AUX_WIDTH; + let mut long_trace = EF::zero_vec(trace_length); + let mut trace = RowMajorMatrix::new(long_trace, AUX_WIDTH); + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[EF; AUX_WIDTH]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + // Initialize first row + let initial_values = Self::buses_initial_values::(); + for j in 0..AUX_WIDTH { + rows[0][j] = initial_values[j]; + } + // Fill subsequent rows using direct access to the rows array + for i in 0..num_rows-1 { + let i_next = (i + 1) % num_rows; + let main_local = _main.row_slice(i).unwrap(); // i < height so unwrap should never fail. + let main_next = _main.row_slice(i_next).unwrap(); // i_next < height so unwrap should never fail. + let main = VerticalPair::new( + RowMajorMatrixView::new_row(&*main_local), + RowMajorMatrixView::new_row(&*main_next), + ); + let periodic_values: [_; NUM_PERIODIC_VALUES] = >::periodic_table(self).iter().map(|col| col[i % col.len()]).collect::>().try_into().expect("Wrong number of periodic values"); + let prev_row = &rows[i]; + let next_row = Self::buses_transitions::( + &main, + _challenges, + &periodic_values, + prev_row, + ); + for j in 0..AUX_WIDTH { + rows[i+1][j] = next_row[j]; + } + } + Some(trace) + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + let (&alpha, beta_challenges) = builder.permutation_randomness().split_first().expect("Wrong number of randomness"); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); + let aux_bus_boundary_values: [_; AUX_WIDTH] = builder.aux_bus_boundary_values().try_into().expect("Wrong number of aux bus boundary values"); + let aux = builder.permutation(); + let (aux_current, aux_next) = ( + aux.row_slice(0).unwrap(), + aux.row_slice(1).unwrap(), + ); + + // Main boundary constraints + + // Main integrity/transition constraints + + // Aux boundary constraints + builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - aux_bus_boundary_values[0].into()); + builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); + builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into()) - aux_bus_boundary_values[1].into()); + + // Aux integrity/transition constraints + builder.when_transition().assert_zero_ext(((alpha.into() + beta_challenges[0].into()) * AB::ExprEF::from(main_current[0].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into()) * (AB::ExprEF::from(main_current[0].clone().into()) - AB::ExprEF::ONE) + AB::ExprEF::ONE - (AB::ExprEF::from(main_current[0].clone().into()) - AB::ExprEF::ONE)) * AB::ExprEF::from(aux_next[0].clone().into())); + builder.when_transition().assert_zero_ext((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_current[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_next[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()).double())); + } +} + +impl BusesAir { + fn buses_initial_values() -> Vec + where F: Field, + EF: ExtensionField, + { + vec![ + EF::ZERO, + EF::ZERO, + ] + } + + fn buses_transitions(main: &VerticalPair, RowMajorMatrixView>, challenges: &[EF], periodic_evals: &[F], aux_current: &[EF]) -> Vec + where F: Field, + EF: ExtensionField, + { + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + let (&alpha, beta_challenges) = challenges.split_first().expect("Wrong number of randomness"); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = periodic_evals.try_into().expect("Wrong number of periodic values"); + vec![ + (((alpha + beta_challenges[0]) * EF::from(main_current[0].clone()) + EF::ONE - EF::from(main_current[0].clone())) * EF::from(aux_current[0].clone())) * ((alpha + beta_challenges[0]) * (EF::from(main_current[0].clone()) - EF::ONE) + EF::ONE - (EF::from(main_current[0].clone()) - EF::ONE)).inverse(), + ((alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(aux_current[1].clone()) + (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(main_current[0].clone()) + (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(main_current[0].clone()) - (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()).double()) * ((alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double())).inverse(), + ] + } +} \ No newline at end of file diff --git a/air-script/tests/buses/buses_varlen_boundary_first.air b/air-script/src/tests/buses/buses_varlen_boundary_first.air similarity index 100% rename from air-script/tests/buses/buses_varlen_boundary_first.air rename to air-script/src/tests/buses/buses_varlen_boundary_first.air diff --git a/air-script/tests/buses/buses_varlen_boundary_first.rs b/air-script/src/tests/buses/buses_varlen_boundary_first.rs similarity index 100% rename from air-script/tests/buses/buses_varlen_boundary_first.rs rename to air-script/src/tests/buses/buses_varlen_boundary_first.rs diff --git a/air-script/src/tests/buses/buses_varlen_boundary_first_plonky3.rs b/air-script/src/tests/buses/buses_varlen_boundary_first_plonky3.rs new file mode 100644 index 000000000..7a8c42bda --- /dev/null +++ b/air-script/src/tests/buses/buses_varlen_boundary_first_plonky3.rs @@ -0,0 +1,135 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 1; +pub const AUX_WIDTH: usize = 2; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 2; +pub const MAX_BETA_CHALLENGE_POWER: usize = 2; + +pub struct BusesAir; + +impl MidenAir for BusesAir +where F: Field, + EF: ExtensionField, +{ + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn num_randomness(&self) -> usize { + 1 + MAX_BETA_CHALLENGE_POWER + } + + fn aux_width(&self) -> usize { + AUX_WIDTH + } + + fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { + // Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders. + + let num_rows = _main.height(); + let trace_length = num_rows * AUX_WIDTH; + let mut long_trace = EF::zero_vec(trace_length); + let mut trace = RowMajorMatrix::new(long_trace, AUX_WIDTH); + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[EF; AUX_WIDTH]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + // Initialize first row + let initial_values = Self::buses_initial_values::(); + for j in 0..AUX_WIDTH { + rows[0][j] = initial_values[j]; + } + // Fill subsequent rows using direct access to the rows array + for i in 0..num_rows-1 { + let i_next = (i + 1) % num_rows; + let main_local = _main.row_slice(i).unwrap(); // i < height so unwrap should never fail. + let main_next = _main.row_slice(i_next).unwrap(); // i_next < height so unwrap should never fail. + let main = VerticalPair::new( + RowMajorMatrixView::new_row(&*main_local), + RowMajorMatrixView::new_row(&*main_next), + ); + let periodic_values: [_; NUM_PERIODIC_VALUES] = >::periodic_table(self).iter().map(|col| col[i % col.len()]).collect::>().try_into().expect("Wrong number of periodic values"); + let prev_row = &rows[i]; + let next_row = Self::buses_transitions::( + &main, + _challenges, + &periodic_values, + prev_row, + ); + for j in 0..AUX_WIDTH { + rows[i+1][j] = next_row[j]; + } + } + Some(trace) + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + let (&alpha, beta_challenges) = builder.permutation_randomness().split_first().expect("Wrong number of randomness"); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); + let aux_bus_boundary_values: [_; AUX_WIDTH] = builder.aux_bus_boundary_values().try_into().expect("Wrong number of aux bus boundary values"); + let aux = builder.permutation(); + let (aux_current, aux_next) = ( + aux.row_slice(0).unwrap(), + aux.row_slice(1).unwrap(), + ); + + // Main boundary constraints + + // Main integrity/transition constraints + + // Aux boundary constraints + builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - aux_bus_boundary_values[0].into()); + builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); + builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into()) - aux_bus_boundary_values[1].into()); + builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); + + // Aux integrity/transition constraints + builder.when_transition().assert_zero_ext(((alpha.into() + beta_challenges[0].into()) * AB::ExprEF::from(main_current[0].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into()) * (AB::ExprEF::from(main_current[0].clone().into()) - AB::ExprEF::ONE) + AB::ExprEF::ONE - (AB::ExprEF::from(main_current[0].clone().into()) - AB::ExprEF::ONE)) * AB::ExprEF::from(aux_next[0].clone().into())); + builder.when_transition().assert_zero_ext((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_current[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_next[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()).double())); + } +} + +impl BusesAir { + fn buses_initial_values() -> Vec + where F: Field, + EF: ExtensionField, + { + vec![ + EF::ZERO, + EF::ZERO, + ] + } + + fn buses_transitions(main: &VerticalPair, RowMajorMatrixView>, challenges: &[EF], periodic_evals: &[F], aux_current: &[EF]) -> Vec + where F: Field, + EF: ExtensionField, + { + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + let (&alpha, beta_challenges) = challenges.split_first().expect("Wrong number of randomness"); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = periodic_evals.try_into().expect("Wrong number of periodic values"); + vec![ + (((alpha + beta_challenges[0]) * EF::from(main_current[0].clone()) + EF::ONE - EF::from(main_current[0].clone())) * EF::from(aux_current[0].clone())) * ((alpha + beta_challenges[0]) * (EF::from(main_current[0].clone()) - EF::ONE) + EF::ONE - (EF::from(main_current[0].clone()) - EF::ONE)).inverse(), + ((alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(aux_current[1].clone()) + (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(main_current[0].clone()) + (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(main_current[0].clone()) - (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()).double()) * ((alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double())).inverse(), + ] + } +} \ No newline at end of file diff --git a/air-script/tests/buses/buses_varlen_boundary_last.air b/air-script/src/tests/buses/buses_varlen_boundary_last.air similarity index 100% rename from air-script/tests/buses/buses_varlen_boundary_last.air rename to air-script/src/tests/buses/buses_varlen_boundary_last.air diff --git a/air-script/tests/buses/buses_varlen_boundary_last.rs b/air-script/src/tests/buses/buses_varlen_boundary_last.rs similarity index 100% rename from air-script/tests/buses/buses_varlen_boundary_last.rs rename to air-script/src/tests/buses/buses_varlen_boundary_last.rs diff --git a/air-script/src/tests/buses/buses_varlen_boundary_last_plonky3.rs b/air-script/src/tests/buses/buses_varlen_boundary_last_plonky3.rs new file mode 100644 index 000000000..fa895389e --- /dev/null +++ b/air-script/src/tests/buses/buses_varlen_boundary_last_plonky3.rs @@ -0,0 +1,135 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 1; +pub const AUX_WIDTH: usize = 2; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 2; +pub const MAX_BETA_CHALLENGE_POWER: usize = 2; + +pub struct BusesAir; + +impl MidenAir for BusesAir +where F: Field, + EF: ExtensionField, +{ + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn num_randomness(&self) -> usize { + 1 + MAX_BETA_CHALLENGE_POWER + } + + fn aux_width(&self) -> usize { + AUX_WIDTH + } + + fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { + // Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders. + + let num_rows = _main.height(); + let trace_length = num_rows * AUX_WIDTH; + let mut long_trace = EF::zero_vec(trace_length); + let mut trace = RowMajorMatrix::new(long_trace, AUX_WIDTH); + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[EF; AUX_WIDTH]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + // Initialize first row + let initial_values = Self::buses_initial_values::(); + for j in 0..AUX_WIDTH { + rows[0][j] = initial_values[j]; + } + // Fill subsequent rows using direct access to the rows array + for i in 0..num_rows-1 { + let i_next = (i + 1) % num_rows; + let main_local = _main.row_slice(i).unwrap(); // i < height so unwrap should never fail. + let main_next = _main.row_slice(i_next).unwrap(); // i_next < height so unwrap should never fail. + let main = VerticalPair::new( + RowMajorMatrixView::new_row(&*main_local), + RowMajorMatrixView::new_row(&*main_next), + ); + let periodic_values: [_; NUM_PERIODIC_VALUES] = >::periodic_table(self).iter().map(|col| col[i % col.len()]).collect::>().try_into().expect("Wrong number of periodic values"); + let prev_row = &rows[i]; + let next_row = Self::buses_transitions::( + &main, + _challenges, + &periodic_values, + prev_row, + ); + for j in 0..AUX_WIDTH { + rows[i+1][j] = next_row[j]; + } + } + Some(trace) + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + let (&alpha, beta_challenges) = builder.permutation_randomness().split_first().expect("Wrong number of randomness"); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); + let aux_bus_boundary_values: [_; AUX_WIDTH] = builder.aux_bus_boundary_values().try_into().expect("Wrong number of aux bus boundary values"); + let aux = builder.permutation(); + let (aux_current, aux_next) = ( + aux.row_slice(0).unwrap(), + aux.row_slice(1).unwrap(), + ); + + // Main boundary constraints + + // Main integrity/transition constraints + + // Aux boundary constraints + builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); + builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - aux_bus_boundary_values[0].into()); + builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); + builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into()) - aux_bus_boundary_values[1].into()); + + // Aux integrity/transition constraints + builder.when_transition().assert_zero_ext(((alpha.into() + beta_challenges[0].into()) * AB::ExprEF::from(main_current[0].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into()) * (AB::ExprEF::from(main_current[0].clone().into()) - AB::ExprEF::ONE) + AB::ExprEF::ONE - (AB::ExprEF::from(main_current[0].clone().into()) - AB::ExprEF::ONE)) * AB::ExprEF::from(aux_next[0].clone().into())); + builder.when_transition().assert_zero_ext((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_current[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_next[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()).double())); + } +} + +impl BusesAir { + fn buses_initial_values() -> Vec + where F: Field, + EF: ExtensionField, + { + vec![ + EF::ONE, + EF::ZERO, + ] + } + + fn buses_transitions(main: &VerticalPair, RowMajorMatrixView>, challenges: &[EF], periodic_evals: &[F], aux_current: &[EF]) -> Vec + where F: Field, + EF: ExtensionField, + { + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + let (&alpha, beta_challenges) = challenges.split_first().expect("Wrong number of randomness"); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = periodic_evals.try_into().expect("Wrong number of periodic values"); + vec![ + (((alpha + beta_challenges[0]) * EF::from(main_current[0].clone()) + EF::ONE - EF::from(main_current[0].clone())) * EF::from(aux_current[0].clone())) * ((alpha + beta_challenges[0]) * (EF::from(main_current[0].clone()) - EF::ONE) + EF::ONE - (EF::from(main_current[0].clone()) - EF::ONE)).inverse(), + ((alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(aux_current[1].clone()) + (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(main_current[0].clone()) + (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(main_current[0].clone()) - (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()).double()) * ((alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double())).inverse(), + ] + } +} \ No newline at end of file diff --git a/air-script/tests/buses/mod.rs b/air-script/src/tests/buses/mod.rs similarity index 100% rename from air-script/tests/buses/mod.rs rename to air-script/src/tests/buses/mod.rs diff --git a/air-script/src/tests/buses/test_air_plonky3.rs b/air-script/src/tests/buses/test_air_plonky3.rs new file mode 100644 index 000000000..20919a31e --- /dev/null +++ b/air-script/src/tests/buses/test_air_plonky3.rs @@ -0,0 +1,59 @@ +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; + +use crate::{ + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::buses::buses_complex_plonky3::{BusesAir, MAIN_WIDTH}, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * MAIN_WIDTH; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::ZERO; + rows[0][2] = F::ZERO; + rows[0][3] = F::ZERO; + rows[0][4] = F::ZERO; + rows[0][5] = F::ZERO; + rows[0][6] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let a_prev = rows[i - 1][0]; + let b_prev = rows[i - 1][1]; + let c_prev = rows[i - 1][2]; + let d_prev = rows[i - 1][3]; + let e_prev = rows[i - 1][4]; + let f_prev = rows[i - 1][5]; + let g_prev = rows[i - 1][6]; + + // Update current row based on previous values + rows[i][0] = F::ZERO; + rows[i][1] = F::ZERO; + rows[i][2] = if i > 3 && i < 8 { F::ONE } else { F::ZERO }; // s1 is true 4 times + rows[i][3] = if i > 5 && i < 10 { F::ONE } else { F::ZERO }; // s2 is true 4 times + rows[i][4] = if i > 4 && i < 10 { F::ONE } else { F::ZERO }; // s3 is true 5 times + rows[i][5] = if i > 5 && i < 13 { F::ONE } else { F::ZERO }; // s4 is true 7 times + rows[i][6] = if i > 15 && i < 20 { F::from_u64(3) } else { F::ZERO }; // d is set to 3 four times + } + + trace +} + +fn generate_inputs() -> Vec { + vec![1; 2] +} + +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, BusesAir); diff --git a/air-script/tests/buses/test_air_winterfell.rs b/air-script/src/tests/buses/test_air_winterfell.rs similarity index 84% rename from air-script/tests/buses/test_air_winterfell.rs rename to air-script/src/tests/buses/test_air_winterfell.rs index 7bf2ce5ea..150617152 100644 --- a/air-script/tests/buses/test_air_winterfell.rs +++ b/air-script/src/tests/buses/test_air_winterfell.rs @@ -3,9 +3,9 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{AuxTraceWithMetadata, Trace, TraceTable, matrix::ColMatrix}; use crate::{ - buses::buses_complex::PublicInputs, generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::buses::buses_complex::PublicInputs, }; #[derive(Clone)] @@ -15,7 +15,7 @@ impl AirTester for BusesAirTester { type PubInputs = PublicInputs; fn build_main_trace(&self, length: usize) -> MyTraceTable { - let trace_width = 5; + let trace_width = 7; let start = Felt::new(0); let mut trace = TraceTable::new(trace_width, length); @@ -26,6 +26,8 @@ impl AirTester for BusesAirTester { state[2] = start; state[3] = start; state[4] = start; + state[5] = start; + state[6] = start; }, |_, state| { state[0] = Felt::new(1) - state[0]; @@ -33,6 +35,8 @@ impl AirTester for BusesAirTester { state[2] = Felt::new(1) - state[2]; state[3] = Felt::new(1) - state[3]; state[4] = Felt::new(1) - state[4]; + state[5] = Felt::new(1) - state[4]; + state[6] = Felt::new(1) - state[4]; }, ); @@ -59,7 +63,7 @@ impl AirTester for BusesAirTester { generate_air_winterfell_test!( test_buses_air, - crate::buses::buses_complex::BusesAir, + crate::tests::buses::buses_complex::BusesAir, BusesAirTester, 1024 ); diff --git a/air-script/tests/computed_indices/computed_indices_complex.air b/air-script/src/tests/computed_indices/computed_indices_complex.air similarity index 100% rename from air-script/tests/computed_indices/computed_indices_complex.air rename to air-script/src/tests/computed_indices/computed_indices_complex.air diff --git a/air-script/tests/computed_indices/computed_indices_complex.rs b/air-script/src/tests/computed_indices/computed_indices_complex.rs similarity index 100% rename from air-script/tests/computed_indices/computed_indices_complex.rs rename to air-script/src/tests/computed_indices/computed_indices_complex.rs diff --git a/air-script/src/tests/computed_indices/computed_indices_complex_plonky3.rs b/air-script/src/tests/computed_indices/computed_indices_complex_plonky3.rs new file mode 100644 index 000000000..ae3ee2903 --- /dev/null +++ b/air-script/src/tests/computed_indices/computed_indices_complex_plonky3.rs @@ -0,0 +1,43 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 4; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 1; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct ComputedIndicesAir; + +impl MidenAir for ComputedIndicesAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero(main_current[2].clone().into() * AB::Expr::from_u64(3) + main_current[3].clone().into() * AB::Expr::from_u64(4)); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/computed_indices/computed_indices_simple.air b/air-script/src/tests/computed_indices/computed_indices_simple.air similarity index 100% rename from air-script/tests/computed_indices/computed_indices_simple.air rename to air-script/src/tests/computed_indices/computed_indices_simple.air diff --git a/air-script/tests/computed_indices/computed_indices_simple.rs b/air-script/src/tests/computed_indices/computed_indices_simple.rs similarity index 100% rename from air-script/tests/computed_indices/computed_indices_simple.rs rename to air-script/src/tests/computed_indices/computed_indices_simple.rs diff --git a/air-script/src/tests/computed_indices/computed_indices_simple_plonky3.rs b/air-script/src/tests/computed_indices/computed_indices_simple_plonky3.rs new file mode 100644 index 000000000..40c374ad3 --- /dev/null +++ b/air-script/src/tests/computed_indices/computed_indices_simple_plonky3.rs @@ -0,0 +1,50 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 8; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct ComputedIndicesAir; + +impl MidenAir for ComputedIndicesAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero(main_current[0].clone().into()); + builder.assert_zero(main_current[1].clone().into() - AB::Expr::from_u64(2)); + builder.assert_zero(main_current[2].clone().into() - AB::Expr::from_u64(4)); + builder.assert_zero(main_current[3].clone().into() - AB::Expr::from_u64(6)); + builder.when_transition().assert_zero(main_next[4].clone().into()); + builder.when_transition().assert_zero(main_next[5].clone().into() - main_current[5].clone().into().double()); + builder.when_transition().assert_zero(main_next[6].clone().into() - AB::Expr::from_u64(6) * main_current[6].clone().into()); + builder.when_transition().assert_zero(main_next[7].clone().into() - AB::Expr::from_u64(12) * main_current[7].clone().into()); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/src/tests/computed_indices/mod.rs b/air-script/src/tests/computed_indices/mod.rs new file mode 100644 index 000000000..948afee49 --- /dev/null +++ b/air-script/src/tests/computed_indices/mod.rs @@ -0,0 +1,18 @@ +#[rustfmt::skip] +#[allow(clippy::all)] +mod computed_indices_complex; +#[rustfmt::skip] +#[allow(clippy::all)] +mod computed_indices_simple; + +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod computed_indices_complex_plonky3; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod computed_indices_simple_plonky3; + +mod test_air_plonky3; +mod test_air_winterfell; diff --git a/air-script/src/tests/computed_indices/test_air_plonky3.rs b/air-script/src/tests/computed_indices/test_air_plonky3.rs new file mode 100644 index 000000000..5f02cc466 --- /dev/null +++ b/air-script/src/tests/computed_indices/test_air_plonky3.rs @@ -0,0 +1,62 @@ +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; + +use crate::{ + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::computed_indices::computed_indices_simple_plonky3::{ComputedIndicesAir, MAIN_WIDTH}, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * MAIN_WIDTH; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ZERO; + rows[0][1] = F::from_canonical_checked(2).unwrap(); + rows[0][2] = F::from_canonical_checked(4).unwrap(); + rows[0][3] = F::from_canonical_checked(6).unwrap(); + rows[0][4] = F::ZERO; + rows[0][5] = F::ZERO; + rows[0][6] = F::ZERO; + rows[0][7] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let col_0_prev = rows[i - 1][0]; + let col_1_prev = rows[i - 1][1]; + let col_2_prev = rows[i - 1][2]; + let col_3_prev = rows[i - 1][3]; + let col_4_prev = rows[i - 1][4]; + let col_5_prev = rows[i - 1][5]; + let col_6_prev = rows[i - 1][6]; + let col_7_prev = rows[i - 1][7]; + + // Update current row based on previous values + rows[i][0] = col_0_prev; + rows[i][1] = col_1_prev; + rows[i][2] = col_2_prev; + rows[i][3] = col_3_prev; + rows[i][4] = col_4_prev * F::ZERO; + rows[i][5] = col_5_prev * F::from_canonical_checked(2).unwrap(); + rows[i][6] = col_6_prev * F::from_canonical_checked(6).unwrap(); + rows[i][7] = col_7_prev * F::from_canonical_checked(12).unwrap(); + } + + trace +} + +fn generate_inputs() -> Vec { + vec![1; 16] +} + +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, ComputedIndicesAir); diff --git a/air-script/tests/computed_indices/test_air.rs b/air-script/src/tests/computed_indices/test_air_winterfell.rs similarity index 63% rename from air-script/tests/computed_indices/test_air.rs rename to air-script/src/tests/computed_indices/test_air_winterfell.rs index 5a953f6e5..1f7e35ed3 100644 --- a/air-script/tests/computed_indices/test_air.rs +++ b/air-script/src/tests/computed_indices/test_air_winterfell.rs @@ -3,8 +3,9 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - computed_indices::computed_indices_simple::{ComputedIndicesAir, PublicInputs}, - helpers::{AirTester, MyTraceTable}, + generate_air_winterfell_test, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::computed_indices::computed_indices_simple::PublicInputs, }; #[derive(Clone)] @@ -45,17 +46,9 @@ impl AirTester for ComputedIndicesAirTester { } } -#[test] -fn test_computed_indices_air() { - let air_tester = Box::new(ComputedIndicesAirTester {}); - let length = 1024; - - let main_trace = air_tester.build_main_trace(length); - let aux_trace = air_tester.build_aux_trace(length); - let pub_inputs = air_tester.public_inputs(); - let trace_info = air_tester.build_trace_info(length); - let options = air_tester.build_proof_options(); - - let air = ComputedIndicesAir::new(trace_info, pub_inputs, options); - main_trace.validate::(&air, aux_trace.as_ref()); -} +generate_air_winterfell_test!( + test_computed_indices_air, + crate::tests::computed_indices::computed_indices_simple::ComputedIndicesAir, + ComputedIndicesAirTester, + 1024 +); diff --git a/air-script/tests/constant_in_range/constant_in_range.air b/air-script/src/tests/constant_in_range/constant_in_range.air similarity index 100% rename from air-script/tests/constant_in_range/constant_in_range.air rename to air-script/src/tests/constant_in_range/constant_in_range.air diff --git a/air-script/tests/constant_in_range/constant_in_range.rs b/air-script/src/tests/constant_in_range/constant_in_range.rs similarity index 100% rename from air-script/tests/constant_in_range/constant_in_range.rs rename to air-script/src/tests/constant_in_range/constant_in_range.rs diff --git a/air-script/tests/constant_in_range/constant_in_range_module.air b/air-script/src/tests/constant_in_range/constant_in_range_module.air similarity index 100% rename from air-script/tests/constant_in_range/constant_in_range_module.air rename to air-script/src/tests/constant_in_range/constant_in_range_module.air diff --git a/air-script/src/tests/constant_in_range/constant_in_range_plonky3.rs b/air-script/src/tests/constant_in_range/constant_in_range_plonky3.rs new file mode 100644 index 000000000..b1238f7cc --- /dev/null +++ b/air-script/src/tests/constant_in_range/constant_in_range_plonky3.rs @@ -0,0 +1,43 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 12; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct ConstantInRangeAir; + +impl MidenAir for ConstantInRangeAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[6].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero(main_current[0].clone().into() - (main_current[1].clone().into() - main_current[4].clone().into() - main_current[8].clone().into() + AB::Expr::ONE + main_current[2].clone().into() - main_current[5].clone().into() - main_current[9].clone().into() + AB::Expr::from_u64(2) + main_current[3].clone().into() - main_current[6].clone().into() - main_current[10].clone().into())); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/constant_in_range/mod.rs b/air-script/src/tests/constant_in_range/mod.rs similarity index 100% rename from air-script/tests/constant_in_range/mod.rs rename to air-script/src/tests/constant_in_range/mod.rs diff --git a/air-script/tests/constant_in_range/test_air_plonky3.rs b/air-script/src/tests/constant_in_range/test_air_plonky3.rs similarity index 64% rename from air-script/tests/constant_in_range/test_air_plonky3.rs rename to air-script/src/tests/constant_in_range/test_air_plonky3.rs index 56e1dcb11..9dd399e1c 100644 --- a/air-script/tests/constant_in_range/test_air_plonky3.rs +++ b/air-script/src/tests/constant_in_range/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - constant_in_range::constant_in_range_plonky3::{ConstantInRangeAir, NUM_COLUMNS}, - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::constant_in_range::constant_in_range_plonky3::{ConstantInRangeAir, MAIN_WIDTH}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -71,4 +60,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -generate_air_plonky3_test!(test_air_plonky3, ConstantInRangeAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, ConstantInRangeAir); diff --git a/air-script/tests/constant_in_range/test_air_winterfell.rs b/air-script/src/tests/constant_in_range/test_air_winterfell.rs similarity index 86% rename from air-script/tests/constant_in_range/test_air_winterfell.rs rename to air-script/src/tests/constant_in_range/test_air_winterfell.rs index 3672378c8..c08fa18ab 100644 --- a/air-script/tests/constant_in_range/test_air_winterfell.rs +++ b/air-script/src/tests/constant_in_range/test_air_winterfell.rs @@ -3,9 +3,9 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - constant_in_range::constant_in_range::PublicInputs, generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::constant_in_range::constant_in_range::PublicInputs, }; #[derive(Clone)] @@ -48,7 +48,7 @@ impl AirTester for ConstantInRangeAirTester { generate_air_winterfell_test!( test_constant_in_range_air, - crate::constant_in_range::constant_in_range::ConstantInRangeAir, + crate::tests::constant_in_range::constant_in_range::ConstantInRangeAir, ConstantInRangeAirTester, 1024 ); diff --git a/air-script/tests/constants/constants.air b/air-script/src/tests/constants/constants.air similarity index 100% rename from air-script/tests/constants/constants.air rename to air-script/src/tests/constants/constants.air diff --git a/air-script/tests/constants/constants.rs b/air-script/src/tests/constants/constants.rs similarity index 100% rename from air-script/tests/constants/constants.rs rename to air-script/src/tests/constants/constants.rs diff --git a/air-script/src/tests/constants/constants_plonky3.rs b/air-script/src/tests/constants/constants_plonky3.rs new file mode 100644 index 000000000..632331aab --- /dev/null +++ b/air-script/src/tests/constants/constants_plonky3.rs @@ -0,0 +1,52 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 7; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 32; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct ConstantsAir; + +impl MidenAir for ConstantsAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into() - AB::Expr::ONE); + builder.when_first_row().assert_zero(main_current[1].clone().into() - AB::Expr::ONE); + builder.when_first_row().assert_zero(main_current[2].clone().into()); + builder.when_first_row().assert_zero(main_current[3].clone().into() - AB::Expr::ONE); + builder.when_first_row().assert_zero(main_current[4].clone().into() - AB::Expr::ONE); + builder.when_last_row().assert_zero(main_current[6].clone().into()); + + // Main integrity/transition constraints + builder.when_transition().assert_zero(main_next[0].clone().into() - (main_current[0].clone().into() + AB::Expr::ONE)); + builder.when_transition().assert_zero(main_next[1].clone().into()); + builder.when_transition().assert_zero(main_next[2].clone().into() - main_current[2].clone().into()); + builder.when_transition().assert_zero(main_next[5].clone().into() - (main_current[5].clone().into() + AB::Expr::ONE)); + builder.assert_zero(main_current[4].clone().into() - AB::Expr::ONE); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/constants/mod.rs b/air-script/src/tests/constants/mod.rs similarity index 100% rename from air-script/tests/constants/mod.rs rename to air-script/src/tests/constants/mod.rs diff --git a/air-script/tests/constants/test_air_plonky3.rs b/air-script/src/tests/constants/test_air_plonky3.rs similarity index 61% rename from air-script/tests/constants/test_air_plonky3.rs rename to air-script/src/tests/constants/test_air_plonky3.rs index 6eecb26fa..cf2c54ebd 100644 --- a/air-script/tests/constants/test_air_plonky3.rs +++ b/air-script/src/tests/constants/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - constants::constants_plonky3::{ConstantsAir, NUM_COLUMNS}, - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::constants::constants_plonky3::{ConstantsAir, MAIN_WIDTH}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -67,4 +56,4 @@ fn generate_inputs() -> Vec { vec![1; 32] } -generate_air_plonky3_test!(test_air_plonky3, ConstantsAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, ConstantsAir); diff --git a/air-script/tests/constants/test_air_winterfell.rs b/air-script/src/tests/constants/test_air_winterfell.rs similarity index 88% rename from air-script/tests/constants/test_air_winterfell.rs rename to air-script/src/tests/constants/test_air_winterfell.rs index 9459000d7..926c8c77c 100644 --- a/air-script/tests/constants/test_air_winterfell.rs +++ b/air-script/src/tests/constants/test_air_winterfell.rs @@ -3,9 +3,9 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - constants::constants::PublicInputs, generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::constants::constants::PublicInputs, }; #[derive(Clone)] @@ -46,7 +46,7 @@ impl AirTester for ConstantsAirTester { generate_air_winterfell_test!( test_constants_air, - crate::constants::constants::ConstantsAir, + crate::tests::constants::constants::ConstantsAir, ConstantsAirTester, 1024 ); diff --git a/air-script/tests/constraint_comprehension/cc_with_evaluators.air b/air-script/src/tests/constraint_comprehension/cc_with_evaluators.air similarity index 100% rename from air-script/tests/constraint_comprehension/cc_with_evaluators.air rename to air-script/src/tests/constraint_comprehension/cc_with_evaluators.air diff --git a/air-script/tests/constraint_comprehension/constraint_comprehension.air b/air-script/src/tests/constraint_comprehension/constraint_comprehension.air similarity index 100% rename from air-script/tests/constraint_comprehension/constraint_comprehension.air rename to air-script/src/tests/constraint_comprehension/constraint_comprehension.air diff --git a/air-script/tests/constraint_comprehension/constraint_comprehension.rs b/air-script/src/tests/constraint_comprehension/constraint_comprehension.rs similarity index 100% rename from air-script/tests/constraint_comprehension/constraint_comprehension.rs rename to air-script/src/tests/constraint_comprehension/constraint_comprehension.rs diff --git a/air-script/src/tests/constraint_comprehension/constraint_comprehension_plonky3.rs b/air-script/src/tests/constraint_comprehension/constraint_comprehension_plonky3.rs new file mode 100644 index 000000000..e333b9626 --- /dev/null +++ b/air-script/src/tests/constraint_comprehension/constraint_comprehension_plonky3.rs @@ -0,0 +1,46 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 14; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct ConstraintComprehensionAir; + +impl MidenAir for ConstraintComprehensionAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[8].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero(main_current[6].clone().into() - main_current[10].clone().into()); + builder.assert_zero(main_current[7].clone().into() - main_current[11].clone().into()); + builder.assert_zero(main_current[8].clone().into() - main_current[12].clone().into()); + builder.assert_zero(main_current[9].clone().into() - main_current[13].clone().into()); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/constraint_comprehension/mod.rs b/air-script/src/tests/constraint_comprehension/mod.rs similarity index 100% rename from air-script/tests/constraint_comprehension/mod.rs rename to air-script/src/tests/constraint_comprehension/mod.rs diff --git a/air-script/src/tests/constraint_comprehension/test_air_plonky3.rs b/air-script/src/tests/constraint_comprehension/test_air_plonky3.rs new file mode 100644 index 000000000..f9fa0d39c --- /dev/null +++ b/air-script/src/tests/constraint_comprehension/test_air_plonky3.rs @@ -0,0 +1,46 @@ +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; + +use crate::{ + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::constraint_comprehension::constraint_comprehension_plonky3::{ + ConstraintComprehensionAir, MAIN_WIDTH, + }, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 32; + let trace_length = num_rows * MAIN_WIDTH; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::from_canonical_checked(inputs[0]).unwrap(); + rows[0][1] = F::ONE; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let a_prev = rows[i - 1][0]; + let b_prev = rows[i - 1][1]; + + // Update current row based on previous values + rows[i][0] = F::ONE - a_prev; + rows[i][1] = F::ONE - b_prev; + } + + trace +} + +fn generate_inputs() -> Vec { + vec![1; 16] +} + +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, ConstraintComprehensionAir); diff --git a/air-script/tests/constraint_comprehension/test_air_winterfell.rs b/air-script/src/tests/constraint_comprehension/test_air_winterfell.rs similarity index 85% rename from air-script/tests/constraint_comprehension/test_air_winterfell.rs rename to air-script/src/tests/constraint_comprehension/test_air_winterfell.rs index 73a24bf0f..d4bec18d1 100644 --- a/air-script/tests/constraint_comprehension/test_air_winterfell.rs +++ b/air-script/src/tests/constraint_comprehension/test_air_winterfell.rs @@ -3,9 +3,9 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - constraint_comprehension::constraint_comprehension::PublicInputs, generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::constraint_comprehension::constraint_comprehension::PublicInputs, }; #[derive(Clone)] @@ -50,7 +50,7 @@ impl AirTester for ConstraintComprehensionAirTester { generate_air_winterfell_test!( test_constraint_comprehension_air, - crate::constraint_comprehension::constraint_comprehension::ConstraintComprehensionAir, + crate::tests::constraint_comprehension::constraint_comprehension::ConstraintComprehensionAir, ConstraintComprehensionAirTester, 1024 ); diff --git a/air-script/tests/docs_sync.rs b/air-script/src/tests/docs_sync.rs similarity index 100% rename from air-script/tests/docs_sync.rs rename to air-script/src/tests/docs_sync.rs diff --git a/air-script/tests/evaluators/evaluators.air b/air-script/src/tests/evaluators/evaluators.air similarity index 100% rename from air-script/tests/evaluators/evaluators.air rename to air-script/src/tests/evaluators/evaluators.air diff --git a/air-script/tests/evaluators/evaluators.rs b/air-script/src/tests/evaluators/evaluators.rs similarity index 100% rename from air-script/tests/evaluators/evaluators.rs rename to air-script/src/tests/evaluators/evaluators.rs diff --git a/air-script/src/tests/evaluators/evaluators_plonky3.rs b/air-script/src/tests/evaluators/evaluators_plonky3.rs new file mode 100644 index 000000000..07f19ea21 --- /dev/null +++ b/air-script/src/tests/evaluators/evaluators_plonky3.rs @@ -0,0 +1,52 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 7; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct EvaluatorsAir; + +impl MidenAir for EvaluatorsAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into()); + + // Main integrity/transition constraints + builder.when_transition().assert_zero(main_next[0].clone().into() - main_current[0].clone().into()); + builder.when_transition().assert_zero(main_next[2].clone().into() - main_current[2].clone().into()); + builder.when_transition().assert_zero(main_next[6].clone().into() - main_current[6].clone().into()); + builder.assert_zero(main_current[0].clone().into() * main_current[0].clone().into() - main_current[0].clone().into()); + builder.assert_zero(main_current[1].clone().into() * main_current[1].clone().into() - main_current[1].clone().into()); + builder.assert_zero(main_current[2].clone().into() * main_current[2].clone().into() - main_current[2].clone().into()); + builder.assert_zero(main_current[3].clone().into() * main_current[3].clone().into() - main_current[3].clone().into()); + builder.assert_zero(main_current[4].clone().into()); + builder.assert_zero(main_current[5].clone().into() - AB::Expr::ONE); + builder.assert_zero(main_current[6].clone().into() - AB::Expr::from_u64(4)); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/evaluators/mod.rs b/air-script/src/tests/evaluators/mod.rs similarity index 100% rename from air-script/tests/evaluators/mod.rs rename to air-script/src/tests/evaluators/mod.rs diff --git a/air-script/tests/evaluators/test_air_plonky3.rs b/air-script/src/tests/evaluators/test_air_plonky3.rs similarity index 61% rename from air-script/tests/evaluators/test_air_plonky3.rs rename to air-script/src/tests/evaluators/test_air_plonky3.rs index 7fed6ebc2..050ba860a 100644 --- a/air-script/tests/evaluators/test_air_plonky3.rs +++ b/air-script/src/tests/evaluators/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - evaluators::evaluators_plonky3::{EvaluatorsAir, NUM_COLUMNS}, - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::evaluators::evaluators_plonky3::{EvaluatorsAir, MAIN_WIDTH}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -67,4 +56,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -generate_air_plonky3_test!(test_air_plonky3, EvaluatorsAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, EvaluatorsAir); diff --git a/air-script/tests/evaluators/test_air_winterfell.rs b/air-script/src/tests/evaluators/test_air_winterfell.rs similarity index 86% rename from air-script/tests/evaluators/test_air_winterfell.rs rename to air-script/src/tests/evaluators/test_air_winterfell.rs index fa8f6f6d8..bbaeb5ecd 100644 --- a/air-script/tests/evaluators/test_air_winterfell.rs +++ b/air-script/src/tests/evaluators/test_air_winterfell.rs @@ -3,9 +3,9 @@ use winter_math::{FieldElement, fields::f64::BaseElement as Felt}; use winterfell::{Trace, TraceTable}; use crate::{ - evaluators::evaluators::PublicInputs, generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::evaluators::evaluators::PublicInputs, }; #[derive(Clone)] @@ -43,7 +43,7 @@ impl AirTester for EvaluatorsAirTester { generate_air_winterfell_test!( test_evaluators_air, - crate::evaluators::evaluators::EvaluatorsAir, + crate::tests::evaluators::evaluators::EvaluatorsAir, EvaluatorsAirTester, 1024 ); diff --git a/air-script/tests/fibonacci/fibonacci.air b/air-script/src/tests/fibonacci/fibonacci.air similarity index 100% rename from air-script/tests/fibonacci/fibonacci.air rename to air-script/src/tests/fibonacci/fibonacci.air diff --git a/air-script/tests/fibonacci/fibonacci.rs b/air-script/src/tests/fibonacci/fibonacci.rs similarity index 100% rename from air-script/tests/fibonacci/fibonacci.rs rename to air-script/src/tests/fibonacci/fibonacci.rs diff --git a/air-script/src/tests/fibonacci/fibonacci_plonky3.rs b/air-script/src/tests/fibonacci/fibonacci_plonky3.rs new file mode 100644 index 000000000..b5476e071 --- /dev/null +++ b/air-script/src/tests/fibonacci/fibonacci_plonky3.rs @@ -0,0 +1,46 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 2; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 3; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct FibonacciAir; + +impl MidenAir for FibonacciAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into() - public_values[0].into()); + builder.when_first_row().assert_zero(main_current[1].clone().into() - public_values[1].into()); + builder.when_last_row().assert_zero(main_current[1].clone().into() - public_values[2].into()); + + // Main integrity/transition constraints + builder.when_transition().assert_zero(main_next[1].clone().into() - (main_current[0].clone().into() + main_current[1].clone().into())); + builder.when_transition().assert_zero(main_next[0].clone().into() - main_current[1].clone().into()); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/fibonacci/mod.rs b/air-script/src/tests/fibonacci/mod.rs similarity index 100% rename from air-script/tests/fibonacci/mod.rs rename to air-script/src/tests/fibonacci/mod.rs diff --git a/air-script/tests/fibonacci/test_air_plonky3.rs b/air-script/src/tests/fibonacci/test_air_plonky3.rs similarity index 53% rename from air-script/tests/fibonacci/test_air_plonky3.rs rename to air-script/src/tests/fibonacci/test_air_plonky3.rs index 6a01a91b6..1d76e60d2 100644 --- a/air-script/tests/fibonacci/test_air_plonky3.rs +++ b/air-script/src/tests/fibonacci/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - fibonacci::fibonacci_plonky3::{FibonacciAir, NUM_COLUMNS}, - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::fibonacci::fibonacci_plonky3::{FibonacciAir, MAIN_WIDTH}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 31; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -54,4 +43,4 @@ fn generate_inputs() -> Vec { vec![one, one, last] } -generate_air_plonky3_test!(test_air_plonky3, FibonacciAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, FibonacciAir); diff --git a/air-script/tests/fibonacci/test_air_winterfell.rs b/air-script/src/tests/fibonacci/test_air_winterfell.rs similarity index 88% rename from air-script/tests/fibonacci/test_air_winterfell.rs rename to air-script/src/tests/fibonacci/test_air_winterfell.rs index 5839643d7..9d2313823 100644 --- a/air-script/tests/fibonacci/test_air_winterfell.rs +++ b/air-script/src/tests/fibonacci/test_air_winterfell.rs @@ -5,9 +5,9 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{AuxTraceWithMetadata, Trace, TraceTable, matrix::ColMatrix}; use crate::{ - fibonacci::fibonacci::PublicInputs, generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::fibonacci::fibonacci::PublicInputs, }; #[derive(Clone)] @@ -47,7 +47,7 @@ impl AirTester for FibonacciAirTester { generate_air_winterfell_test!( test_fibonacci_air, - crate::fibonacci::fibonacci::FibonacciAir, + crate::tests::fibonacci::fibonacci::FibonacciAir, FibonacciAirTester, 32 ); diff --git a/air-script/tests/functions/functions_complex.air b/air-script/src/tests/functions/functions_complex.air similarity index 100% rename from air-script/tests/functions/functions_complex.air rename to air-script/src/tests/functions/functions_complex.air diff --git a/air-script/tests/functions/functions_complex.rs b/air-script/src/tests/functions/functions_complex.rs similarity index 100% rename from air-script/tests/functions/functions_complex.rs rename to air-script/src/tests/functions/functions_complex.rs diff --git a/air-script/src/tests/functions/functions_complex_plonky3.rs b/air-script/src/tests/functions/functions_complex_plonky3.rs new file mode 100644 index 000000000..b42205283 --- /dev/null +++ b/air-script/src/tests/functions/functions_complex_plonky3.rs @@ -0,0 +1,44 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 17; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct FunctionsAir; + +impl MidenAir for FunctionsAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[3].clone().into()); + + // Main integrity/transition constraints + builder.when_transition().assert_zero(main_next[16].clone().into() - main_current[16].clone().into() * ((main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[1].clone().into() * main_current[2].clone().into() + main_current[3].clone().into() * main_current[3].clone().into() * (AB::Expr::ONE - main_current[1].clone().into()) * main_current[2].clone().into() + main_current[3].clone().into() * main_current[1].clone().into() * (AB::Expr::ONE - main_current[2].clone().into()) + (AB::Expr::ONE - main_current[1].clone().into()) * (AB::Expr::ONE - main_current[2].clone().into())) * main_current[0].clone().into() - main_current[0].clone().into() + AB::Expr::ONE)); + builder.when_transition().assert_zero(main_next[3].clone().into() - (main_current[4].clone().into() + main_current[5].clone().into() + main_current[6].clone().into() + main_current[7].clone().into() + main_current[8].clone().into() + main_current[9].clone().into() + main_current[10].clone().into() + main_current[11].clone().into() + main_current[12].clone().into() + main_current[13].clone().into() + main_current[14].clone().into() + main_current[15].clone().into() + AB::Expr::ONE).double()); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/functions/functions_simple.air b/air-script/src/tests/functions/functions_simple.air similarity index 100% rename from air-script/tests/functions/functions_simple.air rename to air-script/src/tests/functions/functions_simple.air diff --git a/air-script/tests/functions/functions_simple.rs b/air-script/src/tests/functions/functions_simple.rs similarity index 100% rename from air-script/tests/functions/functions_simple.rs rename to air-script/src/tests/functions/functions_simple.rs diff --git a/air-script/src/tests/functions/functions_simple_plonky3.rs b/air-script/src/tests/functions/functions_simple_plonky3.rs new file mode 100644 index 000000000..c5b131f49 --- /dev/null +++ b/air-script/src/tests/functions/functions_simple_plonky3.rs @@ -0,0 +1,50 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 9; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct FunctionsAir; + +impl MidenAir for FunctionsAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[3].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero(main_current[0].clone().into() * main_current[3].clone().into() - AB::Expr::ONE); + builder.assert_zero(main_current[4].clone().into() * main_current[5].clone().into() * main_current[6].clone().into() * main_current[7].clone().into() * main_current[3].clone().into() - AB::Expr::ONE); + builder.assert_zero((main_current[4].clone().into() + main_current[5].clone().into() + main_current[6].clone().into() + main_current[7].clone().into()) * main_current[4].clone().into() * main_current[5].clone().into() * main_current[6].clone().into() * main_current[7].clone().into() - AB::Expr::ONE); + builder.assert_zero(main_current[4].clone().into() * main_current[5].clone().into() * main_current[6].clone().into() * main_current[7].clone().into() - AB::Expr::ONE); + builder.assert_zero(main_current[0].clone().into() * main_current[4].clone().into() * main_current[5].clone().into() * main_current[6].clone().into() * main_current[7].clone().into() - AB::Expr::ONE); + builder.assert_zero(main_current[1].clone().into() + (main_current[4].clone().into() + main_current[5].clone().into() + main_current[6].clone().into() + main_current[7].clone().into()) * main_current[4].clone().into() * main_current[5].clone().into() * main_current[6].clone().into() * main_current[7].clone().into() - AB::Expr::ONE); + builder.assert_zero(main_current[4].clone().into() + main_current[5].clone().into() + main_current[6].clone().into() + main_current[7].clone().into() - AB::Expr::ONE); + builder.assert_zero((main_current[4].clone().into() + main_current[5].clone().into() + main_current[6].clone().into() + main_current[7].clone().into()) * AB::Expr::from_u64(4) - AB::Expr::ONE); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/functions/inlined_functions_simple.air b/air-script/src/tests/functions/inlined_functions_simple.air similarity index 100% rename from air-script/tests/functions/inlined_functions_simple.air rename to air-script/src/tests/functions/inlined_functions_simple.air diff --git a/air-script/tests/functions/mod.rs b/air-script/src/tests/functions/mod.rs similarity index 100% rename from air-script/tests/functions/mod.rs rename to air-script/src/tests/functions/mod.rs diff --git a/air-script/tests/functions/test_air_plonky3.rs b/air-script/src/tests/functions/test_air_plonky3.rs similarity index 73% rename from air-script/tests/functions/test_air_plonky3.rs rename to air-script/src/tests/functions/test_air_plonky3.rs index 5ef13dbf9..f52390339 100644 --- a/air-script/tests/functions/test_air_plonky3.rs +++ b/air-script/src/tests/functions/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - functions::functions_complex_plonky3::{FunctionsAir, NUM_COLUMNS}, - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::functions::functions_complex_plonky3::{FunctionsAir, MAIN_WIDTH}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -97,4 +86,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -generate_air_plonky3_test!(test_air_plonky3, FunctionsAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, FunctionsAir); diff --git a/air-script/tests/functions/test_air_winterfell.rs b/air-script/src/tests/functions/test_air_winterfell.rs similarity index 92% rename from air-script/tests/functions/test_air_winterfell.rs rename to air-script/src/tests/functions/test_air_winterfell.rs index 0357e9039..76aa0b6f3 100644 --- a/air-script/tests/functions/test_air_winterfell.rs +++ b/air-script/src/tests/functions/test_air_winterfell.rs @@ -3,9 +3,9 @@ use winter_math::fields::f64::BaseElement as Felt; use winterfell::{Trace, TraceTable}; use crate::{ - functions::functions_complex::PublicInputs, generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::functions::functions_complex::PublicInputs, }; #[derive(Clone)] @@ -70,7 +70,7 @@ impl AirTester for FunctionsAirTester { generate_air_winterfell_test!( test_functions_complex_air, - crate::functions::functions_complex::FunctionsAir, + crate::tests::functions::functions_complex::FunctionsAir, FunctionsAirTester, 1024 ); diff --git a/air-script/tests/indexed_trace_access/indexed_trace_access.air b/air-script/src/tests/indexed_trace_access/indexed_trace_access.air similarity index 100% rename from air-script/tests/indexed_trace_access/indexed_trace_access.air rename to air-script/src/tests/indexed_trace_access/indexed_trace_access.air diff --git a/air-script/tests/indexed_trace_access/indexed_trace_access.rs b/air-script/src/tests/indexed_trace_access/indexed_trace_access.rs similarity index 100% rename from air-script/tests/indexed_trace_access/indexed_trace_access.rs rename to air-script/src/tests/indexed_trace_access/indexed_trace_access.rs diff --git a/air-script/src/tests/indexed_trace_access/indexed_trace_access_plonky3.rs b/air-script/src/tests/indexed_trace_access/indexed_trace_access_plonky3.rs new file mode 100644 index 000000000..d1f6eb420 --- /dev/null +++ b/air-script/src/tests/indexed_trace_access/indexed_trace_access_plonky3.rs @@ -0,0 +1,43 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 4; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct TraceAccessAir; + +impl MidenAir for TraceAccessAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into()); + + // Main integrity/transition constraints + builder.when_transition().assert_zero(main_next[0].clone().into() - (main_current[1].clone().into() + AB::Expr::ONE)); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/indexed_trace_access/mod.rs b/air-script/src/tests/indexed_trace_access/mod.rs similarity index 100% rename from air-script/tests/indexed_trace_access/mod.rs rename to air-script/src/tests/indexed_trace_access/mod.rs diff --git a/air-script/tests/indexed_trace_access/test_air_plonky3.rs b/air-script/src/tests/indexed_trace_access/test_air_plonky3.rs similarity index 50% rename from air-script/tests/indexed_trace_access/test_air_plonky3.rs rename to air-script/src/tests/indexed_trace_access/test_air_plonky3.rs index b01cc0eaa..4b0a31c39 100644 --- a/air-script/tests/indexed_trace_access/test_air_plonky3.rs +++ b/air-script/src/tests/indexed_trace_access/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, - indexed_trace_access::indexed_trace_access_plonky3::{NUM_COLUMNS, TraceAccessAir}, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::indexed_trace_access::indexed_trace_access_plonky3::{MAIN_WIDTH, TraceAccessAir}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -54,4 +43,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -generate_air_plonky3_test!(test_air_plonky3, TraceAccessAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, TraceAccessAir); diff --git a/air-script/tests/indexed_trace_access/test_air_winterfell.rs b/air-script/src/tests/indexed_trace_access/test_air_winterfell.rs similarity index 83% rename from air-script/tests/indexed_trace_access/test_air_winterfell.rs rename to air-script/src/tests/indexed_trace_access/test_air_winterfell.rs index 9d7e64bcb..44b7dfcec 100644 --- a/air-script/tests/indexed_trace_access/test_air_winterfell.rs +++ b/air-script/src/tests/indexed_trace_access/test_air_winterfell.rs @@ -4,8 +4,8 @@ use winterfell::{Trace, TraceTable}; use crate::{ generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, - indexed_trace_access::indexed_trace_access::PublicInputs, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::indexed_trace_access::indexed_trace_access::PublicInputs, }; #[derive(Clone)] @@ -42,7 +42,7 @@ impl AirTester for TraceAccessAirTester { generate_air_winterfell_test!( test_indexed_trace_access_air, - crate::indexed_trace_access::indexed_trace_access::TraceAccessAir, + crate::tests::indexed_trace_access::indexed_trace_access::TraceAccessAir, TraceAccessAirTester, 1024 ); diff --git a/air-script/tests/list_comprehension/list_comprehension.air b/air-script/src/tests/list_comprehension/list_comprehension.air similarity index 100% rename from air-script/tests/list_comprehension/list_comprehension.air rename to air-script/src/tests/list_comprehension/list_comprehension.air diff --git a/air-script/tests/list_comprehension/list_comprehension.rs b/air-script/src/tests/list_comprehension/list_comprehension.rs similarity index 100% rename from air-script/tests/list_comprehension/list_comprehension.rs rename to air-script/src/tests/list_comprehension/list_comprehension.rs diff --git a/air-script/tests/list_comprehension/list_comprehension_nested.air b/air-script/src/tests/list_comprehension/list_comprehension_nested.air similarity index 100% rename from air-script/tests/list_comprehension/list_comprehension_nested.air rename to air-script/src/tests/list_comprehension/list_comprehension_nested.air diff --git a/air-script/tests/list_comprehension/list_comprehension_nested.rs b/air-script/src/tests/list_comprehension/list_comprehension_nested.rs similarity index 100% rename from air-script/tests/list_comprehension/list_comprehension_nested.rs rename to air-script/src/tests/list_comprehension/list_comprehension_nested.rs diff --git a/air-script/src/tests/list_comprehension/list_comprehension_nested_plonky3.rs b/air-script/src/tests/list_comprehension/list_comprehension_nested_plonky3.rs new file mode 100644 index 000000000..734706746 --- /dev/null +++ b/air-script/src/tests/list_comprehension/list_comprehension_nested_plonky3.rs @@ -0,0 +1,45 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 2; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 1; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct ListComprehensionAir; + +impl MidenAir for ListComprehensionAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero(main_current[0].clone().into() + main_current[1].clone().into().double() - AB::Expr::from_u64(3)); + builder.assert_zero(main_current[0].clone().into().double() + main_current[1].clone().into() * AB::Expr::from_u64(3) - AB::Expr::from_u64(5)); + builder.assert_zero(main_current[0].clone().into() * AB::Expr::from_u64(3) + main_current[1].clone().into() * AB::Expr::from_u64(4) - AB::Expr::from_u64(7)); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/src/tests/list_comprehension/list_comprehension_plonky3.rs b/air-script/src/tests/list_comprehension/list_comprehension_plonky3.rs new file mode 100644 index 000000000..727cc9cc0 --- /dev/null +++ b/air-script/src/tests/list_comprehension/list_comprehension_plonky3.rs @@ -0,0 +1,48 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 16; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct ListComprehensionAir; + +impl MidenAir for ListComprehensionAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[10].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero(main_current[0].clone().into() - main_current[2].clone().into()); + builder.assert_zero(main_current[4].clone().into() - main_current[0].clone().into() * AB::Expr::from_u64(8) * main_current[11].clone().into()); + builder.when_transition().assert_zero(main_current[4].clone().into() - main_current[0].clone().into() * (main_next[8].clone().into() - main_next[12].clone().into())); + builder.assert_zero(main_current[6].clone().into() - main_current[0].clone().into() * (main_current[9].clone().into() - main_current[14].clone().into())); + builder.assert_zero(main_current[1].clone().into() - (main_current[5].clone().into() - main_current[8].clone().into() - main_current[12].clone().into() + AB::Expr::from_u64(10) + main_current[6].clone().into() - main_current[9].clone().into() - main_current[13].clone().into() + AB::Expr::from_u64(20) + main_current[7].clone().into() - main_current[10].clone().into() - main_current[14].clone().into())); + builder.assert_zero(main_current[14].clone().into() - AB::Expr::from_u64(10)); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/list_comprehension/mod.rs b/air-script/src/tests/list_comprehension/mod.rs similarity index 54% rename from air-script/tests/list_comprehension/mod.rs rename to air-script/src/tests/list_comprehension/mod.rs index eb8e94340..e33f216df 100644 --- a/air-script/tests/list_comprehension/mod.rs +++ b/air-script/src/tests/list_comprehension/mod.rs @@ -1,5 +1,12 @@ #[rustfmt::skip] #[allow(clippy::all)] +mod list_comprehension_nested; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] +mod list_comprehension_nested_plonky3; +#[rustfmt::skip] +#[allow(clippy::all)] mod list_comprehension; #[rustfmt::skip] #[allow(clippy::all)] diff --git a/air-script/tests/list_comprehension/test_air_plonky3.rs b/air-script/src/tests/list_comprehension/test_air_plonky3.rs similarity index 72% rename from air-script/tests/list_comprehension/test_air_plonky3.rs rename to air-script/src/tests/list_comprehension/test_air_plonky3.rs index 7cec4aeed..a99c57065 100644 --- a/air-script/tests/list_comprehension/test_air_plonky3.rs +++ b/air-script/src/tests/list_comprehension/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, - list_comprehension::list_comprehension_plonky3::{ListComprehensionAir, NUM_COLUMNS}, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::list_comprehension::list_comprehension_plonky3::{ListComprehensionAir, MAIN_WIDTH}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -94,4 +83,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -generate_air_plonky3_test!(test_air_plonky3, ListComprehensionAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, ListComprehensionAir); diff --git a/air-script/tests/list_comprehension/test_air_winterfell.rs b/air-script/src/tests/list_comprehension/test_air_winterfell.rs similarity index 87% rename from air-script/tests/list_comprehension/test_air_winterfell.rs rename to air-script/src/tests/list_comprehension/test_air_winterfell.rs index 8fef13b07..749541299 100644 --- a/air-script/tests/list_comprehension/test_air_winterfell.rs +++ b/air-script/src/tests/list_comprehension/test_air_winterfell.rs @@ -4,8 +4,8 @@ use winterfell::{Trace, TraceTable}; use crate::{ generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, - list_comprehension::list_comprehension::PublicInputs, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::list_comprehension::list_comprehension::PublicInputs, }; #[derive(Clone)] @@ -54,7 +54,7 @@ impl AirTester for ListComprehensionAirTester { generate_air_winterfell_test!( test_list_comprehension_air, - crate::list_comprehension::list_comprehension::ListComprehensionAir, + crate::tests::list_comprehension::list_comprehension::ListComprehensionAir, ListComprehensionAirTester, 1024 ); diff --git a/air-script/tests/list_folding/list_folding.air b/air-script/src/tests/list_folding/list_folding.air similarity index 100% rename from air-script/tests/list_folding/list_folding.air rename to air-script/src/tests/list_folding/list_folding.air diff --git a/air-script/tests/list_folding/list_folding.rs b/air-script/src/tests/list_folding/list_folding.rs similarity index 100% rename from air-script/tests/list_folding/list_folding.rs rename to air-script/src/tests/list_folding/list_folding.rs diff --git a/air-script/src/tests/list_folding/list_folding_plonky3.rs b/air-script/src/tests/list_folding/list_folding_plonky3.rs new file mode 100644 index 000000000..1a455fdd9 --- /dev/null +++ b/air-script/src/tests/list_folding/list_folding_plonky3.rs @@ -0,0 +1,46 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 17; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct ListFoldingAir; + +impl MidenAir for ListFoldingAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[11].clone().into()); + + // Main integrity/transition constraints + builder.when_transition().assert_zero(main_next[5].clone().into() - (main_current[9].clone().into() + main_current[10].clone().into() + main_current[11].clone().into() + main_current[12].clone().into() + main_current[13].clone().into() * main_current[14].clone().into() * main_current[15].clone().into() * main_current[16].clone().into())); + builder.when_transition().assert_zero(main_next[6].clone().into() - (main_current[9].clone().into() + main_current[10].clone().into() + main_current[11].clone().into() + main_current[12].clone().into() + main_current[13].clone().into() * main_current[14].clone().into() * main_current[15].clone().into() * main_current[16].clone().into())); + builder.when_transition().assert_zero(main_next[7].clone().into() - (main_current[9].clone().into() * main_current[13].clone().into() + main_current[10].clone().into() * main_current[14].clone().into() + main_current[11].clone().into() * main_current[15].clone().into() + main_current[12].clone().into() * main_current[16].clone().into() + (main_current[9].clone().into() + main_current[13].clone().into()) * (main_current[10].clone().into() + main_current[14].clone().into()) * (main_current[11].clone().into() + main_current[15].clone().into()) * (main_current[12].clone().into() + main_current[16].clone().into()))); + builder.when_transition().assert_zero(main_next[8].clone().into() - (main_current[1].clone().into() + main_current[9].clone().into() * main_current[13].clone().into() + main_current[10].clone().into() * main_current[14].clone().into() + main_current[11].clone().into() * main_current[15].clone().into() + main_current[12].clone().into() * main_current[16].clone().into() + main_current[9].clone().into() * main_current[13].clone().into() + main_current[10].clone().into() * main_current[14].clone().into() + main_current[11].clone().into() * main_current[15].clone().into() + main_current[12].clone().into() * main_current[16].clone().into())); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/list_folding/mod.rs b/air-script/src/tests/list_folding/mod.rs similarity index 100% rename from air-script/tests/list_folding/mod.rs rename to air-script/src/tests/list_folding/mod.rs diff --git a/air-script/tests/list_folding/test_air_plonky3.rs b/air-script/src/tests/list_folding/test_air_plonky3.rs similarity index 73% rename from air-script/tests/list_folding/test_air_plonky3.rs rename to air-script/src/tests/list_folding/test_air_plonky3.rs index 83d82e10d..a87dae25b 100644 --- a/air-script/tests/list_folding/test_air_plonky3.rs +++ b/air-script/src/tests/list_folding/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, - list_folding::list_folding_plonky3::{ListFoldingAir, NUM_COLUMNS}, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::list_folding::list_folding_plonky3::{ListFoldingAir, MAIN_WIDTH}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -97,4 +86,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -generate_air_plonky3_test!(test_air_plonky3, ListFoldingAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, ListFoldingAir); diff --git a/air-script/tests/list_folding/test_air_winterfell.rs b/air-script/src/tests/list_folding/test_air_winterfell.rs similarity index 89% rename from air-script/tests/list_folding/test_air_winterfell.rs rename to air-script/src/tests/list_folding/test_air_winterfell.rs index f8376848d..a957f18f9 100644 --- a/air-script/tests/list_folding/test_air_winterfell.rs +++ b/air-script/src/tests/list_folding/test_air_winterfell.rs @@ -4,8 +4,8 @@ use winterfell::{Trace, TraceTable}; use crate::{ generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, - list_folding::list_folding::PublicInputs, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::list_folding::list_folding::PublicInputs, }; #[derive(Clone)] @@ -55,7 +55,7 @@ impl AirTester for ListFoldingAirTester { generate_air_winterfell_test!( test_list_folding_air, - crate::list_folding::list_folding::ListFoldingAir, + crate::tests::list_folding::list_folding::ListFoldingAir, ListFoldingAirTester, 1024 ); diff --git a/air-script/tests/mod.rs b/air-script/src/tests/mod.rs similarity index 97% rename from air-script/tests/mod.rs rename to air-script/src/tests/mod.rs index 1f8c0fc09..c3d85e7a0 100644 --- a/air-script/tests/mod.rs +++ b/air-script/src/tests/mod.rs @@ -1,7 +1,3 @@ -mod codegen; - -pub mod helpers; - #[allow(unused_variables, dead_code, unused_mut)] mod binary; #[allow(unused_variables, dead_code, unused_mut)] @@ -42,3 +38,5 @@ mod trace_col_groups; mod variables; mod docs_sync; +mod plonky3; +mod winterfell; diff --git a/air-script/tests/periodic_columns/mod.rs b/air-script/src/tests/periodic_columns/mod.rs similarity index 100% rename from air-script/tests/periodic_columns/mod.rs rename to air-script/src/tests/periodic_columns/mod.rs diff --git a/air-script/tests/periodic_columns/periodic_columns.air b/air-script/src/tests/periodic_columns/periodic_columns.air similarity index 100% rename from air-script/tests/periodic_columns/periodic_columns.air rename to air-script/src/tests/periodic_columns/periodic_columns.air diff --git a/air-script/tests/periodic_columns/periodic_columns.rs b/air-script/src/tests/periodic_columns/periodic_columns.rs similarity index 100% rename from air-script/tests/periodic_columns/periodic_columns.rs rename to air-script/src/tests/periodic_columns/periodic_columns.rs diff --git a/air-script/src/tests/periodic_columns/periodic_columns_plonky3.rs b/air-script/src/tests/periodic_columns/periodic_columns_plonky3.rs new file mode 100644 index 000000000..22acad484 --- /dev/null +++ b/air-script/src/tests/periodic_columns/periodic_columns_plonky3.rs @@ -0,0 +1,58 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 3; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 2; +pub const PERIOD: usize = 8; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct PeriodicColumnsAir; + +impl MidenAir for PeriodicColumnsAir +where F: Field, + EF: ExtensionField, +{ + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } + + fn periodic_table(&self) -> Vec> { + vec![ + vec![F::from_u64(1), F::from_u64(0), F::from_u64(0), F::from_u64(0)], + vec![F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(0)], + ] + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero_ext(AB::ExprEF::from(periodic_values[0].clone().into()) * (AB::ExprEF::from(main_current[1].clone().into()) + AB::ExprEF::from(main_current[2].clone().into()))); + builder.when_transition().assert_zero_ext(AB::ExprEF::from(periodic_values[1].clone().into()) * (AB::ExprEF::from(main_next[0].clone().into()) - AB::ExprEF::from(main_current[0].clone().into()))); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/periodic_columns/test_air_plonky3.rs b/air-script/src/tests/periodic_columns/test_air_plonky3.rs similarity index 51% rename from air-script/tests/periodic_columns/test_air_plonky3.rs rename to air-script/src/tests/periodic_columns/test_air_plonky3.rs index 6b7b9acce..42091fa46 100644 --- a/air-script/tests/periodic_columns/test_air_plonky3.rs +++ b/air-script/src/tests/periodic_columns/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, - periodic_columns::periodic_columns_plonky3::{NUM_COLUMNS, PeriodicColumnsAir}, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::periodic_columns::periodic_columns_plonky3::{MAIN_WIDTH, PeriodicColumnsAir}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -55,4 +44,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -generate_air_plonky3_test!(test_air_plonky3, PeriodicColumnsAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, PeriodicColumnsAir); diff --git a/air-script/tests/periodic_columns/test_air_winterfell.rs b/air-script/src/tests/periodic_columns/test_air_winterfell.rs similarity index 82% rename from air-script/tests/periodic_columns/test_air_winterfell.rs rename to air-script/src/tests/periodic_columns/test_air_winterfell.rs index 0adc8364f..cf92e1101 100644 --- a/air-script/tests/periodic_columns/test_air_winterfell.rs +++ b/air-script/src/tests/periodic_columns/test_air_winterfell.rs @@ -4,8 +4,8 @@ use winterfell::{Trace, TraceTable}; use crate::{ generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, - periodic_columns::periodic_columns::PublicInputs, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::periodic_columns::periodic_columns::PublicInputs, }; #[derive(Clone)] @@ -39,7 +39,7 @@ impl AirTester for PeriodicColumnsAirTester { generate_air_winterfell_test!( test_periodic_columns_air, - crate::periodic_columns::periodic_columns::PeriodicColumnsAir, + crate::tests::periodic_columns::periodic_columns::PeriodicColumnsAir, PeriodicColumnsAirTester, 1024 ); diff --git a/air-script/src/tests/plonky3.rs b/air-script/src/tests/plonky3.rs new file mode 100644 index 000000000..e599d2189 --- /dev/null +++ b/air-script/src/tests/plonky3.rs @@ -0,0 +1,336 @@ +use expect_test::expect_file; + +use crate::test_utils::codegen::{Target, Test}; + +#[test] +fn binary() { + let generated_air = Test::new("src/tests/binary/binary.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["binary/binary_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn bitwise() { + let generated_air = Test::new("src/tests/bitwise/bitwise.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["bitwise/bitwise_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_complex() { + let generated_air = Test::new("src/tests/buses/buses_complex.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["buses/buses_complex_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_simple() { + let generated_air = Test::new("src/tests/buses/buses_simple.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["buses/buses_simple_plonky3.rs"]; + expected.assert_eq(&generated_air); +} +#[test] +fn buses_simple_with_evaluators() { + let generated_air = Test::new("src/tests/buses/buses_simple_with_evaluators.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["buses/buses_simple_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_varlen_boundary_both() { + let generated_air = Test::new("src/tests/buses/buses_varlen_boundary_both.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["buses/buses_varlen_boundary_both_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_varlen_boundary_first() { + let generated_air = Test::new("src/tests/buses/buses_varlen_boundary_first.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["buses/buses_varlen_boundary_first_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_varlen_boundary_last() { + let generated_air = Test::new("src/tests/buses/buses_varlen_boundary_last.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["buses/buses_varlen_boundary_last_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn computed_indices_complex() { + let generated_air = + Test::new("src/tests/computed_indices/computed_indices_complex.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["computed_indices/computed_indices_complex_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn computed_indices_simple() { + let generated_air = + Test::new("src/tests/computed_indices/computed_indices_simple.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["computed_indices/computed_indices_simple_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn constant_in_range() { + let generated_air = Test::new("src/tests/constant_in_range/constant_in_range.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["constant_in_range/constant_in_range_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn constants() { + let generated_air = Test::new("src/tests/constants/constants.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["constants/constants_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn evaluators() { + let generated_air = Test::new("src/tests/evaluators/evaluators.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["evaluators/evaluators_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn fibonacci() { + let generated_air = Test::new("src/tests/fibonacci/fibonacci.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["fibonacci/fibonacci_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn functions_complex() { + let generated_air = Test::new("src/tests/functions/functions_complex.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["functions/functions_complex_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn functions_simple() { + let generated_air = Test::new("src/tests/functions/functions_simple.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["functions/functions_simple_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn functions_simple_inlined() { + // make sure that the constraints generated using inlined functions are the same as the ones + // generated using regular functions + let generated_air = Test::new("src/tests/functions/inlined_functions_simple.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["functions/functions_simple_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn indexed_trace_access() { + let generated_air = + Test::new("src/tests/indexed_trace_access/indexed_trace_access.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["indexed_trace_access/indexed_trace_access_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn list_comprehension_nested() { + let generated_air = + Test::new("src/tests/list_comprehension/list_comprehension_nested.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["list_comprehension/list_comprehension_nested_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn list_comprehension() { + let generated_air = + Test::new("src/tests/list_comprehension/list_comprehension.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["list_comprehension/list_comprehension_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn list_folding() { + let generated_air = Test::new("src/tests/list_folding/list_folding.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["list_folding/list_folding_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn periodic_columns() { + let generated_air = Test::new("src/tests/periodic_columns/periodic_columns.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["periodic_columns/periodic_columns_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn pub_inputs() { + let generated_air = Test::new("src/tests/pub_inputs/pub_inputs.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["pub_inputs/pub_inputs_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn selectors_combine_complex() { + let generated_air = Test::new("src/tests/selectors/selectors_combine_complex.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["selectors/selectors_combine_complex_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn selectors_combine_simple() { + let generated_air = Test::new("src/tests/selectors/selectors_combine_simple.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["selectors/selectors_combine_simple_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn selectors_combine_with_list_comprehensions() { + let generated_air = + Test::new("src/tests/selectors/selectors_combine_with_list_comprehensions.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["selectors/selectors_combine_with_list_comprehensions_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn selectors() { + let generated_air = Test::new("src/tests/selectors/selectors.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["selectors/selectors_plonky3.rs"]; + expected.assert_eq(&generated_air); + + let generated_air = Test::new("src/tests/selectors/selectors_with_evaluators.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["selectors/selectors_with_evaluators_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn system() { + let generated_air = Test::new("src/tests/system/system.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["system/system_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn trace_col_groups() { + let generated_air = Test::new("src/tests/trace_col_groups/trace_col_groups.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["trace_col_groups/trace_col_groups_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn variables() { + let generated_air = Test::new("src/tests/variables/variables.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["variables/variables_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn constraint_comprehension() { + let generated_air = + Test::new("src/tests/constraint_comprehension/constraint_comprehension.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["constraint_comprehension/constraint_comprehension_plonky3.rs"]; + expected.assert_eq(&generated_air); + + let generated_air = + Test::new("src/tests/constraint_comprehension/cc_with_evaluators.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["constraint_comprehension/constraint_comprehension_plonky3.rs"]; + expected.assert_eq(&generated_air); +} diff --git a/air-script/tests/pub_inputs/mod.rs b/air-script/src/tests/pub_inputs/mod.rs similarity index 100% rename from air-script/tests/pub_inputs/mod.rs rename to air-script/src/tests/pub_inputs/mod.rs diff --git a/air-script/tests/pub_inputs/pub_inputs.air b/air-script/src/tests/pub_inputs/pub_inputs.air similarity index 100% rename from air-script/tests/pub_inputs/pub_inputs.air rename to air-script/src/tests/pub_inputs/pub_inputs.air diff --git a/air-script/tests/pub_inputs/pub_inputs.rs b/air-script/src/tests/pub_inputs/pub_inputs.rs similarity index 100% rename from air-script/tests/pub_inputs/pub_inputs.rs rename to air-script/src/tests/pub_inputs/pub_inputs.rs diff --git a/air-script/src/tests/pub_inputs/pub_inputs_plonky3.rs b/air-script/src/tests/pub_inputs/pub_inputs_plonky3.rs new file mode 100644 index 000000000..bbdef9bf9 --- /dev/null +++ b/air-script/src/tests/pub_inputs/pub_inputs_plonky3.rs @@ -0,0 +1,50 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 4; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 32; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct PubInputsAir; + +impl MidenAir for PubInputsAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into() - public_values[8].into()); + builder.when_first_row().assert_zero(main_current[1].clone().into() - public_values[9].into()); + builder.when_first_row().assert_zero(main_current[2].clone().into() - public_values[10].into()); + builder.when_first_row().assert_zero(main_current[3].clone().into() - public_values[11].into()); + builder.when_last_row().assert_zero(main_current[0].clone().into() - public_values[12].into()); + builder.when_last_row().assert_zero(main_current[1].clone().into() - public_values[13].into()); + builder.when_last_row().assert_zero(main_current[2].clone().into() - public_values[14].into()); + builder.when_last_row().assert_zero(main_current[3].clone().into() - public_values[15].into()); + + // Main integrity/transition constraints + builder.when_transition().assert_zero(main_next[0].clone().into() - (main_current[1].clone().into() + main_current[2].clone().into())); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/pub_inputs/test_air_plonky3.rs b/air-script/src/tests/pub_inputs/test_air_plonky3.rs similarity index 55% rename from air-script/tests/pub_inputs/test_air_plonky3.rs rename to air-script/src/tests/pub_inputs/test_air_plonky3.rs index 71343872e..8595358b4 100644 --- a/air-script/tests/pub_inputs/test_air_plonky3.rs +++ b/air-script/src/tests/pub_inputs/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, - pub_inputs::pub_inputs_plonky3::{NUM_COLUMNS, PubInputsAir}, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::pub_inputs::pub_inputs_plonky3::{MAIN_WIDTH, PubInputsAir}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -58,4 +47,4 @@ fn generate_inputs() -> Vec { vec![0; 32] } -generate_air_plonky3_test!(test_air_plonky3, PubInputsAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, PubInputsAir); diff --git a/air-script/tests/pub_inputs/test_air_winterfell.rs b/air-script/src/tests/pub_inputs/test_air_winterfell.rs similarity index 85% rename from air-script/tests/pub_inputs/test_air_winterfell.rs rename to air-script/src/tests/pub_inputs/test_air_winterfell.rs index 947f4bbac..62b8be849 100644 --- a/air-script/tests/pub_inputs/test_air_winterfell.rs +++ b/air-script/src/tests/pub_inputs/test_air_winterfell.rs @@ -4,8 +4,8 @@ use winterfell::{Trace, TraceTable}; use crate::{ generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, - pub_inputs::pub_inputs::PublicInputs, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::pub_inputs::pub_inputs::PublicInputs, }; #[derive(Clone)] @@ -40,7 +40,7 @@ impl AirTester for PubInputsAirTester { generate_air_winterfell_test!( test_pub_inputs_air, - crate::pub_inputs::pub_inputs::PubInputsAir, + crate::tests::pub_inputs::pub_inputs::PubInputsAir, PubInputsAirTester, 1024 ); diff --git a/air-script/tests/selectors/mod.rs b/air-script/src/tests/selectors/mod.rs similarity index 90% rename from air-script/tests/selectors/mod.rs rename to air-script/src/tests/selectors/mod.rs index 39924b2bc..a8007ac23 100644 --- a/air-script/tests/selectors/mod.rs +++ b/air-script/src/tests/selectors/mod.rs @@ -16,6 +16,10 @@ mod selectors_with_evaluators; #[rustfmt::skip] #[allow(clippy::all)] #[allow(unused_imports)] +mod selectors_plonky3; +#[rustfmt::skip] +#[allow(clippy::all)] +#[allow(unused_imports)] mod selectors_combine_simple_plonky3; #[rustfmt::skip] #[allow(clippy::all)] diff --git a/air-script/tests/selectors/selectors.air b/air-script/src/tests/selectors/selectors.air similarity index 100% rename from air-script/tests/selectors/selectors.air rename to air-script/src/tests/selectors/selectors.air diff --git a/air-script/tests/selectors/selectors.rs b/air-script/src/tests/selectors/selectors.rs similarity index 100% rename from air-script/tests/selectors/selectors.rs rename to air-script/src/tests/selectors/selectors.rs diff --git a/air-script/tests/selectors/selectors_combine_complex.air b/air-script/src/tests/selectors/selectors_combine_complex.air similarity index 100% rename from air-script/tests/selectors/selectors_combine_complex.air rename to air-script/src/tests/selectors/selectors_combine_complex.air diff --git a/air-script/tests/selectors/selectors_combine_complex.rs b/air-script/src/tests/selectors/selectors_combine_complex.rs similarity index 100% rename from air-script/tests/selectors/selectors_combine_complex.rs rename to air-script/src/tests/selectors/selectors_combine_complex.rs diff --git a/air-script/src/tests/selectors/selectors_combine_complex_plonky3.rs b/air-script/src/tests/selectors/selectors_combine_complex_plonky3.rs new file mode 100644 index 000000000..7714372f2 --- /dev/null +++ b/air-script/src/tests/selectors/selectors_combine_complex_plonky3.rs @@ -0,0 +1,134 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 6; +pub const AUX_WIDTH: usize = 1; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 1; +pub const MAX_BETA_CHALLENGE_POWER: usize = 2; + +pub struct SelectorsAir; + +impl MidenAir for SelectorsAir +where F: Field, + EF: ExtensionField, +{ + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn num_randomness(&self) -> usize { + 1 + MAX_BETA_CHALLENGE_POWER + } + + fn aux_width(&self) -> usize { + AUX_WIDTH + } + + fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { + // Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders. + + let num_rows = _main.height(); + let trace_length = num_rows * AUX_WIDTH; + let mut long_trace = EF::zero_vec(trace_length); + let mut trace = RowMajorMatrix::new(long_trace, AUX_WIDTH); + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[EF; AUX_WIDTH]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + // Initialize first row + let initial_values = Self::buses_initial_values::(); + for j in 0..AUX_WIDTH { + rows[0][j] = initial_values[j]; + } + // Fill subsequent rows using direct access to the rows array + for i in 0..num_rows-1 { + let i_next = (i + 1) % num_rows; + let main_local = _main.row_slice(i).unwrap(); // i < height so unwrap should never fail. + let main_next = _main.row_slice(i_next).unwrap(); // i_next < height so unwrap should never fail. + let main = VerticalPair::new( + RowMajorMatrixView::new_row(&*main_local), + RowMajorMatrixView::new_row(&*main_next), + ); + let periodic_values: [_; NUM_PERIODIC_VALUES] = >::periodic_table(self).iter().map(|col| col[i % col.len()]).collect::>().try_into().expect("Wrong number of periodic values"); + let prev_row = &rows[i]; + let next_row = Self::buses_transitions::( + &main, + _challenges, + &periodic_values, + prev_row, + ); + for j in 0..AUX_WIDTH { + rows[i+1][j] = next_row[j]; + } + } + Some(trace) + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + let (&alpha, beta_challenges) = builder.permutation_randomness().split_first().expect("Wrong number of randomness"); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); + let aux_bus_boundary_values: [_; AUX_WIDTH] = builder.aux_bus_boundary_values().try_into().expect("Wrong number of aux bus boundary values"); + let aux = builder.permutation(); + let (aux_current, aux_next) = ( + aux.row_slice(0).unwrap(), + aux.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[5].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero((main_current[0].clone().into() + (AB::Expr::ONE - main_current[0].clone().into()) * main_current[1].clone().into()) * (main_current[3].clone().into() - AB::Expr::from_u64(16)) + (AB::Expr::ONE - main_current[0].clone().into()) * (AB::Expr::ONE - main_current[1].clone().into()) * (main_current[4].clone().into() - AB::Expr::from_u64(5))); + builder.assert_zero((AB::Expr::ONE - main_current[0].clone().into()) * (main_current[5].clone().into() - AB::Expr::from_u64(5)) + main_current[0].clone().into() * (main_current[4].clone().into() - AB::Expr::from_u64(4))); + builder.assert_zero(main_current[0].clone().into() * (main_current[5].clone().into() - AB::Expr::from_u64(20)) + (AB::Expr::ONE - main_current[0].clone().into()) * main_current[1].clone().into() * (main_current[4].clone().into() - AB::Expr::from_u64(31))); + + // Aux boundary constraints + builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); + builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); + + // Aux integrity/transition constraints + builder.when_transition().assert_zero_ext(((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) * AB::ExprEF::from(main_current[5].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into()) * AB::ExprEF::from(main_current[5].clone().into())) * ((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(main_current[1].clone().into()) * AB::ExprEF::from(main_current[5].clone().into()) + AB::ExprEF::ONE - (AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(main_current[1].clone().into()) * AB::ExprEF::from(main_current[5].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from_u64(4) * beta_challenges[1].into()) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[1].clone().into())) * AB::ExprEF::from(main_current[4].clone().into()) + AB::ExprEF::ONE - (AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[1].clone().into())) * AB::ExprEF::from(main_current[4].clone().into())) * AB::ExprEF::from(aux_next[0].clone().into())); + } +} + +impl SelectorsAir { + fn buses_initial_values() -> Vec + where F: Field, + EF: ExtensionField, + { + vec![ + EF::ONE, + ] + } + + fn buses_transitions(main: &VerticalPair, RowMajorMatrixView>, challenges: &[EF], periodic_evals: &[F], aux_current: &[EF]) -> Vec + where F: Field, + EF: ExtensionField, + { + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + let (&alpha, beta_challenges) = challenges.split_first().expect("Wrong number of randomness"); + let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = periodic_evals.try_into().expect("Wrong number of periodic values"); + vec![ + (((alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(main_current[0].clone()) * EF::from(main_current[5].clone()) + EF::ONE - EF::from(main_current[0].clone()) * EF::from(main_current[5].clone())) * ((alpha + beta_challenges[0] + beta_challenges[1].double()) * (EF::ONE - EF::from(main_current[0].clone())) * EF::from(main_current[1].clone()) * EF::from(main_current[5].clone()) + EF::ONE - (EF::ONE - EF::from(main_current[0].clone())) * EF::from(main_current[1].clone()) * EF::from(main_current[5].clone())) * EF::from(aux_current[0].clone())) * ((alpha + EF::from_u64(3) * beta_challenges[0] + EF::from_u64(4) * beta_challenges[1]) * (EF::ONE - EF::from(main_current[0].clone())) * (EF::ONE - EF::from(main_current[1].clone())) * EF::from(main_current[4].clone()) + EF::ONE - (EF::ONE - EF::from(main_current[0].clone())) * (EF::ONE - EF::from(main_current[1].clone())) * EF::from(main_current[4].clone())).inverse(), + ] + } +} \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_combine_simple.air b/air-script/src/tests/selectors/selectors_combine_simple.air similarity index 100% rename from air-script/tests/selectors/selectors_combine_simple.air rename to air-script/src/tests/selectors/selectors_combine_simple.air diff --git a/air-script/tests/selectors/selectors_combine_simple.rs b/air-script/src/tests/selectors/selectors_combine_simple.rs similarity index 100% rename from air-script/tests/selectors/selectors_combine_simple.rs rename to air-script/src/tests/selectors/selectors_combine_simple.rs diff --git a/air-script/src/tests/selectors/selectors_combine_simple_plonky3.rs b/air-script/src/tests/selectors/selectors_combine_simple_plonky3.rs new file mode 100644 index 000000000..df958a51e --- /dev/null +++ b/air-script/src/tests/selectors/selectors_combine_simple_plonky3.rs @@ -0,0 +1,44 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 4; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 1; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct SelectorsAir; + +impl MidenAir for SelectorsAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[3].clone().into()); + + // Main integrity/transition constraints + builder.when_transition().assert_zero(main_next[1].clone().into() - main_current[2].clone().into()); + builder.when_transition().assert_zero(main_current[3].clone().into() * (main_next[0].clone().into() - (main_current[0].clone().into() + main_current[1].clone().into())) + (AB::Expr::ONE - main_current[3].clone().into()) * (main_next[0].clone().into() - main_current[0].clone().into() * main_current[1].clone().into())); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_combine_with_list_comprehensions.air b/air-script/src/tests/selectors/selectors_combine_with_list_comprehensions.air similarity index 100% rename from air-script/tests/selectors/selectors_combine_with_list_comprehensions.air rename to air-script/src/tests/selectors/selectors_combine_with_list_comprehensions.air diff --git a/air-script/tests/selectors/selectors_combine_with_list_comprehensions.rs b/air-script/src/tests/selectors/selectors_combine_with_list_comprehensions.rs similarity index 100% rename from air-script/tests/selectors/selectors_combine_with_list_comprehensions.rs rename to air-script/src/tests/selectors/selectors_combine_with_list_comprehensions.rs diff --git a/air-script/src/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs b/air-script/src/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs new file mode 100644 index 000000000..c7c4e3940 --- /dev/null +++ b/air-script/src/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs @@ -0,0 +1,45 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 6; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 1; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct SelectorsAir; + +impl MidenAir for SelectorsAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[5].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero((main_current[0].clone().into() + (AB::Expr::ONE - main_current[0].clone().into()) * main_current[1].clone().into()) * main_current[3].clone().into() + (AB::Expr::ONE - main_current[0].clone().into()) * (AB::Expr::ONE - main_current[1].clone().into()) * (main_current[4].clone().into() - AB::Expr::from_u64(8))); + builder.assert_zero((AB::Expr::ONE - main_current[0].clone().into()) * (main_current[5].clone().into() - AB::Expr::from_u64(8)) + main_current[0].clone().into() * (main_current[4].clone().into() - AB::Expr::from_u64(2))); + builder.assert_zero(main_current[0].clone().into() * (main_current[5].clone().into() - AB::Expr::from_u64(4)) + (AB::Expr::ONE - main_current[0].clone().into()) * main_current[1].clone().into() * (main_current[4].clone().into() - AB::Expr::from_u64(6))); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/src/tests/selectors/selectors_plonky3.rs b/air-script/src/tests/selectors/selectors_plonky3.rs new file mode 100644 index 000000000..51f70004b --- /dev/null +++ b/air-script/src/tests/selectors/selectors_plonky3.rs @@ -0,0 +1,44 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 4; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct SelectorsAir; + +impl MidenAir for SelectorsAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[3].clone().into()); + + // Main integrity/transition constraints + builder.when_transition().assert_zero(main_current[0].clone().into() * (AB::Expr::ONE - main_current[1].clone().into()) * main_next[3].clone().into()); + builder.when_transition().assert_zero(main_current[0].clone().into() * main_current[1].clone().into() * main_current[2].clone().into() * (main_next[3].clone().into() - main_current[3].clone().into()) + (AB::Expr::ONE - main_current[1].clone().into()) * (AB::Expr::ONE - main_current[2].clone().into()) * (main_next[3].clone().into() - AB::Expr::ONE)); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_with_evaluators.air b/air-script/src/tests/selectors/selectors_with_evaluators.air similarity index 100% rename from air-script/tests/selectors/selectors_with_evaluators.air rename to air-script/src/tests/selectors/selectors_with_evaluators.air diff --git a/air-script/tests/selectors/selectors_with_evaluators.rs b/air-script/src/tests/selectors/selectors_with_evaluators.rs similarity index 100% rename from air-script/tests/selectors/selectors_with_evaluators.rs rename to air-script/src/tests/selectors/selectors_with_evaluators.rs diff --git a/air-script/src/tests/selectors/selectors_with_evaluators_plonky3.rs b/air-script/src/tests/selectors/selectors_with_evaluators_plonky3.rs new file mode 100644 index 000000000..1dde4fecf --- /dev/null +++ b/air-script/src/tests/selectors/selectors_with_evaluators_plonky3.rs @@ -0,0 +1,44 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 4; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct SelectorsAir; + +impl MidenAir for SelectorsAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[3].clone().into()); + + // Main integrity/transition constraints + builder.when_transition().assert_zero(main_current[0].clone().into() * (AB::Expr::ONE - main_current[1].clone().into()) * main_next[3].clone().into()); + builder.when_transition().assert_zero(main_current[1].clone().into() * main_current[2].clone().into() * main_current[0].clone().into() * (main_next[3].clone().into() - main_current[3].clone().into()) + (AB::Expr::ONE - main_current[1].clone().into()) * (AB::Expr::ONE - main_current[2].clone().into()) * (main_next[3].clone().into() - AB::Expr::ONE)); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/selectors/test_air_plonky3.rs b/air-script/src/tests/selectors/test_air_plonky3.rs similarity index 54% rename from air-script/tests/selectors/test_air_plonky3.rs rename to air-script/src/tests/selectors/test_air_plonky3.rs index 289939f0e..ef3c01f81 100644 --- a/air-script/tests/selectors/test_air_plonky3.rs +++ b/air-script/src/tests/selectors/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, - selectors::selectors_with_evaluators_plonky3::{NUM_COLUMNS, SelectorsAir}, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::selectors::selectors_with_evaluators_plonky3::{MAIN_WIDTH, SelectorsAir}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -58,4 +47,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -generate_air_plonky3_test!(test_air_plonky3, SelectorsAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, SelectorsAir); diff --git a/air-script/tests/selectors/test_air_winterfell.rs b/air-script/src/tests/selectors/test_air_winterfell.rs similarity index 84% rename from air-script/tests/selectors/test_air_winterfell.rs rename to air-script/src/tests/selectors/test_air_winterfell.rs index 19f683ef6..3bb3ac337 100644 --- a/air-script/tests/selectors/test_air_winterfell.rs +++ b/air-script/src/tests/selectors/test_air_winterfell.rs @@ -4,8 +4,8 @@ use winterfell::{Trace, TraceTable}; use crate::{ generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, - selectors::selectors_with_evaluators::PublicInputs, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::selectors::selectors_with_evaluators::PublicInputs, }; #[derive(Clone)] @@ -42,7 +42,7 @@ impl AirTester for SelectorsAirTester { generate_air_winterfell_test!( test_selectors_with_evaluators_air, - crate::selectors::selectors_with_evaluators::SelectorsAir, + crate::tests::selectors::selectors_with_evaluators::SelectorsAir, SelectorsAirTester, 1024 ); diff --git a/air-script/tests/system/mod.rs b/air-script/src/tests/system/mod.rs similarity index 100% rename from air-script/tests/system/mod.rs rename to air-script/src/tests/system/mod.rs diff --git a/air-script/tests/system/system.air b/air-script/src/tests/system/system.air similarity index 100% rename from air-script/tests/system/system.air rename to air-script/src/tests/system/system.air diff --git a/air-script/tests/system/system.rs b/air-script/src/tests/system/system.rs similarity index 100% rename from air-script/tests/system/system.rs rename to air-script/src/tests/system/system.rs diff --git a/air-script/src/tests/system/system_plonky3.rs b/air-script/src/tests/system/system_plonky3.rs new file mode 100644 index 000000000..574bccd9b --- /dev/null +++ b/air-script/src/tests/system/system_plonky3.rs @@ -0,0 +1,43 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 3; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct SystemAir; + +impl MidenAir for SystemAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into()); + + // Main integrity/transition constraints + builder.when_transition().assert_zero(main_next[0].clone().into() - (main_current[0].clone().into() + AB::Expr::ONE)); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/system/test_air_plonky3.rs b/air-script/src/tests/system/test_air_plonky3.rs similarity index 53% rename from air-script/tests/system/test_air_plonky3.rs rename to air-script/src/tests/system/test_air_plonky3.rs index 9c0eb5004..404ea03d7 100644 --- a/air-script/tests/system/test_air_plonky3.rs +++ b/air-script/src/tests/system/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, - system::system_plonky3::{NUM_COLUMNS, SystemAir}, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::system::system_plonky3::{MAIN_WIDTH, SystemAir}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -55,4 +44,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -generate_air_plonky3_test!(test_air_plonky3, SystemAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, SystemAir); diff --git a/air-script/tests/system/test_air_winterfell.rs b/air-script/src/tests/system/test_air_winterfell.rs similarity index 86% rename from air-script/tests/system/test_air_winterfell.rs rename to air-script/src/tests/system/test_air_winterfell.rs index 9327f6e98..99a717f78 100644 --- a/air-script/tests/system/test_air_winterfell.rs +++ b/air-script/src/tests/system/test_air_winterfell.rs @@ -4,8 +4,8 @@ use winterfell::{Trace, TraceTable}; use crate::{ generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, - system::system::PublicInputs, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::system::system::PublicInputs, }; #[derive(Clone)] @@ -41,7 +41,7 @@ impl AirTester for SystemAirTester { generate_air_winterfell_test!( test_system_air, - crate::system::system::SystemAir, + crate::tests::system::system::SystemAir, SystemAirTester, 1024 ); diff --git a/air-script/tests/trace_col_groups/mod.rs b/air-script/src/tests/trace_col_groups/mod.rs similarity index 100% rename from air-script/tests/trace_col_groups/mod.rs rename to air-script/src/tests/trace_col_groups/mod.rs diff --git a/air-script/tests/trace_col_groups/test_air_plonky3.rs b/air-script/src/tests/trace_col_groups/test_air_plonky3.rs similarity index 64% rename from air-script/tests/trace_col_groups/test_air_plonky3.rs rename to air-script/src/tests/trace_col_groups/test_air_plonky3.rs index b12ab3ac7..1b4522ecf 100644 --- a/air-script/tests/trace_col_groups/test_air_plonky3.rs +++ b/air-script/src/tests/trace_col_groups/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, - trace_col_groups::trace_col_groups_plonky3::{NUM_COLUMNS, TraceColGroupAir}, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::trace_col_groups::trace_col_groups_plonky3::{MAIN_WIDTH, TraceColGroupAir}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -73,4 +62,4 @@ fn generate_inputs() -> Vec { vec![1; 16] } -generate_air_plonky3_test!(test_air_plonky3, TraceColGroupAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, TraceColGroupAir); diff --git a/air-script/tests/trace_col_groups/test_air_winterfell.rs b/air-script/src/tests/trace_col_groups/test_air_winterfell.rs similarity index 86% rename from air-script/tests/trace_col_groups/test_air_winterfell.rs rename to air-script/src/tests/trace_col_groups/test_air_winterfell.rs index 92400a4f2..53a5af721 100644 --- a/air-script/tests/trace_col_groups/test_air_winterfell.rs +++ b/air-script/src/tests/trace_col_groups/test_air_winterfell.rs @@ -4,8 +4,8 @@ use winterfell::{Trace, TraceTable}; use crate::{ generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, - trace_col_groups::trace_col_groups::PublicInputs, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::trace_col_groups::trace_col_groups::PublicInputs, }; #[derive(Clone)] @@ -48,7 +48,7 @@ impl AirTester for TraceColGroupAirTester { generate_air_winterfell_test!( test_trace_col_groups_air, - crate::trace_col_groups::trace_col_groups::TraceColGroupAir, + crate::tests::trace_col_groups::trace_col_groups::TraceColGroupAir, TraceColGroupAirTester, 1024 ); diff --git a/air-script/tests/trace_col_groups/trace_col_groups.air b/air-script/src/tests/trace_col_groups/trace_col_groups.air similarity index 100% rename from air-script/tests/trace_col_groups/trace_col_groups.air rename to air-script/src/tests/trace_col_groups/trace_col_groups.air diff --git a/air-script/tests/trace_col_groups/trace_col_groups.rs b/air-script/src/tests/trace_col_groups/trace_col_groups.rs similarity index 100% rename from air-script/tests/trace_col_groups/trace_col_groups.rs rename to air-script/src/tests/trace_col_groups/trace_col_groups.rs diff --git a/air-script/src/tests/trace_col_groups/trace_col_groups_plonky3.rs b/air-script/src/tests/trace_col_groups/trace_col_groups_plonky3.rs new file mode 100644 index 000000000..026304e2d --- /dev/null +++ b/air-script/src/tests/trace_col_groups/trace_col_groups_plonky3.rs @@ -0,0 +1,44 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 9; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct TraceColGroupAir; + +impl MidenAir for TraceColGroupAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[8].clone().into()); + + // Main integrity/transition constraints + builder.when_transition().assert_zero(main_next[2].clone().into() - (main_current[2].clone().into() + AB::Expr::ONE)); + builder.when_transition().assert_zero(main_next[1].clone().into() - (main_current[1].clone().into() - AB::Expr::ONE)); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/tests/variables/mod.rs b/air-script/src/tests/variables/mod.rs similarity index 100% rename from air-script/tests/variables/mod.rs rename to air-script/src/tests/variables/mod.rs diff --git a/air-script/tests/variables/test_air_plonky3.rs b/air-script/src/tests/variables/test_air_plonky3.rs similarity index 54% rename from air-script/tests/variables/test_air_plonky3.rs rename to air-script/src/tests/variables/test_air_plonky3.rs index 8296f2197..b8d2d88ef 100644 --- a/air-script/tests/variables/test_air_plonky3.rs +++ b/air-script/src/tests/variables/test_air_plonky3.rs @@ -1,32 +1,21 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; use crate::{ - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, - variables::variables_plonky3::{NUM_COLUMNS, VariablesAir}, + generate_air_plonky3_test_with_airscript_traits, + test_utils::plonky3_traits::check_constraints_with_airscript_traits, + tests::variables::variables_plonky3::{MAIN_WIDTH, VariablesAir}, }; pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; + let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; assert!(prefix.is_empty(), "Alignment should match"); assert!(suffix.is_empty(), "Alignment should match"); assert_eq!(rows.len(), num_rows); @@ -58,4 +47,4 @@ fn generate_inputs() -> Vec { vec![1; 32] } -generate_air_plonky3_test!(test_air_plonky3, VariablesAir); +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, VariablesAir); diff --git a/air-script/tests/variables/test_air_winterfell.rs b/air-script/src/tests/variables/test_air_winterfell.rs similarity index 86% rename from air-script/tests/variables/test_air_winterfell.rs rename to air-script/src/tests/variables/test_air_winterfell.rs index 3578f330f..d384975b3 100644 --- a/air-script/tests/variables/test_air_winterfell.rs +++ b/air-script/src/tests/variables/test_air_winterfell.rs @@ -4,8 +4,8 @@ use winterfell::{Trace, TraceTable}; use crate::{ generate_air_winterfell_test, - helpers::{AirTester, MyTraceTable}, - variables::variables::PublicInputs, + test_utils::winterfell_traits::{AirTester, MyTraceTable}, + tests::variables::variables::PublicInputs, }; #[derive(Clone)] @@ -42,7 +42,7 @@ impl AirTester for VariablesAirTester { generate_air_winterfell_test!( test_variables_air, - crate::variables::variables::VariablesAir, + crate::tests::variables::variables::VariablesAir, VariablesAirTester, 1024 ); diff --git a/air-script/tests/variables/variables.air b/air-script/src/tests/variables/variables.air similarity index 100% rename from air-script/tests/variables/variables.air rename to air-script/src/tests/variables/variables.air diff --git a/air-script/tests/variables/variables.rs b/air-script/src/tests/variables/variables.rs similarity index 100% rename from air-script/tests/variables/variables.rs rename to air-script/src/tests/variables/variables.rs diff --git a/air-script/src/tests/variables/variables_plonky3.rs b/air-script/src/tests/variables/variables_plonky3.rs new file mode 100644 index 000000000..bfe0da908 --- /dev/null +++ b/air-script/src/tests/variables/variables_plonky3.rs @@ -0,0 +1,60 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 4; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 1; +pub const PERIOD: usize = 8; +pub const NUM_PUBLIC_VALUES: usize = 32; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct VariablesAir; + +impl MidenAir for VariablesAir +where F: Field, + EF: ExtensionField, +{ + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn num_public_values(&self) -> usize { + NUM_PUBLIC_VALUES + } + + fn periodic_table(&self) -> Vec> { + vec![ + vec![F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(0)], + ] + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[1].clone().into()); + builder.when_last_row().assert_zero(main_current[1].clone().into() - AB::Expr::ONE); + + // Main integrity/transition constraints + builder.assert_zero(main_current[0].clone().into() * main_current[0].clone().into() - main_current[0].clone().into()); + builder.when_transition().assert_zero_ext(AB::ExprEF::from(periodic_values[0].clone().into()) * (AB::ExprEF::from(main_next[0].clone().into()) - AB::ExprEF::from(main_current[0].clone().into()))); + builder.assert_zero((AB::Expr::ONE - main_current[0].clone().into()) * (main_current[3].clone().into() - main_current[1].clone().into() - main_current[2].clone().into()) - (AB::Expr::from_u64(6) - (AB::Expr::from_u64(7) - main_current[0].clone().into()))); + builder.when_transition().assert_zero(main_current[0].clone().into() * (main_current[3].clone().into() - main_current[1].clone().into() * main_current[2].clone().into()) - (AB::Expr::ONE - main_next[0].clone().into())); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/src/tests/winterfell.rs b/air-script/src/tests/winterfell.rs new file mode 100644 index 000000000..2b2683cb6 --- /dev/null +++ b/air-script/src/tests/winterfell.rs @@ -0,0 +1,337 @@ +use expect_test::expect_file; + +use crate::test_utils::codegen::{Target, Test}; + +#[test] +fn binary() { + let generated_air = Test::new("src/tests/binary/binary.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["binary/binary.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn bitwise() { + let generated_air = Test::new("src/tests/bitwise/bitwise.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["bitwise/bitwise.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_complex() { + let generated_air = Test::new("src/tests/buses/buses_complex.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["buses/buses_complex.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_simple() { + let generated_air = Test::new("src/tests/buses/buses_simple.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["buses/buses_simple.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_simple_with_evaluators() { + let generated_air = Test::new("src/tests/buses/buses_simple_with_evaluators.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["buses/buses_simple.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_varlen_boundary_both() { + let generated_air = Test::new("src/tests/buses/buses_varlen_boundary_both.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["buses/buses_varlen_boundary_both.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_varlen_boundary_first() { + let generated_air = Test::new("src/tests/buses/buses_varlen_boundary_first.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["buses/buses_varlen_boundary_first.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn buses_varlen_boundary_last() { + let generated_air = Test::new("src/tests/buses/buses_varlen_boundary_last.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["buses/buses_varlen_boundary_last.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn computed_indices_complex() { + let generated_air = + Test::new("src/tests/computed_indices/computed_indices_complex.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["computed_indices/computed_indices_complex.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn computed_indices_simple() { + let generated_air = + Test::new("src/tests/computed_indices/computed_indices_simple.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["computed_indices/computed_indices_simple.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn constant_in_range() { + let generated_air = Test::new("src/tests/constant_in_range/constant_in_range.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["constant_in_range/constant_in_range.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn constants() { + let generated_air = Test::new("src/tests/constants/constants.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["constants/constants.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn constraint_comprehension() { + let generated_air = + Test::new("src/tests/constraint_comprehension/constraint_comprehension.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["constraint_comprehension/constraint_comprehension.rs"]; + expected.assert_eq(&generated_air); + + let generated_air = + Test::new("src/tests/constraint_comprehension/cc_with_evaluators.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["constraint_comprehension/constraint_comprehension.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn evaluators() { + let generated_air = Test::new("src/tests/evaluators/evaluators.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["evaluators/evaluators.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn fibonacci() { + let generated_air = Test::new("src/tests/fibonacci/fibonacci.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["fibonacci/fibonacci.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn functions_complex() { + let generated_air = Test::new("src/tests/functions/functions_complex.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["functions/functions_complex.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn functions_simple() { + let generated_air = Test::new("src/tests/functions/functions_simple.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["functions/functions_simple.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn functions_simple_inlined() { + // make sure that the constraints generated using inlined functions are the same as the ones + // generated using regular functions + let generated_air = Test::new("src/tests/functions/inlined_functions_simple.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["functions/functions_simple.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn indexed_trace_access() { + let generated_air = + Test::new("src/tests/indexed_trace_access/indexed_trace_access.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["indexed_trace_access/indexed_trace_access.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn list_comprehension() { + let generated_air = + Test::new("src/tests/list_comprehension/list_comprehension.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["list_comprehension/list_comprehension.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn list_comprehension_nested() { + let generated_air = + Test::new("src/tests/list_comprehension/list_comprehension_nested.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["list_comprehension/list_comprehension_nested.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn list_folding() { + let generated_air = Test::new("src/tests/list_folding/list_folding.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["list_folding/list_folding.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn periodic_columns() { + let generated_air = Test::new("src/tests/periodic_columns/periodic_columns.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["periodic_columns/periodic_columns.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn pub_inputs() { + let generated_air = Test::new("src/tests/pub_inputs/pub_inputs.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["pub_inputs/pub_inputs.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn selectors() { + let generated_air = Test::new("src/tests/selectors/selectors.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["selectors/selectors.rs"]; + expected.assert_eq(&generated_air); + + let generated_air = Test::new("src/tests/selectors/selectors_with_evaluators.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["selectors/selectors_with_evaluators.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn selectors_combine_simple() { + let generated_air = Test::new("src/tests/selectors/selectors_combine_simple.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["selectors/selectors_combine_simple.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn selectors_combine_complex() { + let generated_air = Test::new("src/tests/selectors/selectors_combine_complex.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["selectors/selectors_combine_complex.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn selectors_combine_with_list_comprehensions() { + let generated_air = + Test::new("src/tests/selectors/selectors_combine_with_list_comprehensions.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["selectors/selectors_combine_with_list_comprehensions.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn system() { + let generated_air = Test::new("src/tests/system/system.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["system/system.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn trace_col_groups() { + let generated_air = Test::new("src/tests/trace_col_groups/trace_col_groups.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["trace_col_groups/trace_col_groups.rs"]; + expected.assert_eq(&generated_air); +} + +#[test] +fn variables() { + let generated_air = Test::new("src/tests/variables/variables.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["variables/variables.rs"]; + expected.assert_eq(&generated_air); +} diff --git a/air-script/tests/binary/binary_plonky3.rs b/air-script/tests/binary/binary_plonky3.rs deleted file mode 100644 index df44bcb6d..000000000 --- a/air-script/tests/binary/binary_plonky3.rs +++ /dev/null @@ -1,44 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 2; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct BinaryAir; - -impl BaseAir for BinaryAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for BinaryAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for BinaryAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for BinaryAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[0].into() - public_values[0].into()); - builder.assert_zero::<_>(main_current[0].into() * main_current[0].into() - main_current[0].into()); - builder.assert_zero::<_>(main_current[1].into() * main_current[1].into() - main_current[1].into()); - } -} \ No newline at end of file diff --git a/air-script/tests/bitwise/bitwise_plonky3.rs b/air-script/tests/bitwise/bitwise_plonky3.rs deleted file mode 100644 index ef5d5d992..000000000 --- a/air-script/tests/bitwise/bitwise_plonky3.rs +++ /dev/null @@ -1,61 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 14; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct BitwiseAir; - -impl BaseAir for BitwiseAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for BitwiseAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for BitwiseAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - vec![F::from_u64(1), F::from_u64(0), F::from_u64(0), F::from_u64(0), F::from_u64(0), F::from_u64(0), F::from_u64(0), F::from_u64(0)], - vec![F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(0)], - ] - } -} - -impl Air for BitwiseAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[13].into()); - builder.assert_zero::<_>(main_current[0].into() * main_current[0].into() - main_current[0].into()); - builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[0].into() - main_current[0].into())); - builder.assert_zero::<_>(main_current[3].into() * main_current[3].into() - main_current[3].into()); - builder.assert_zero::<_>(main_current[4].into() * main_current[4].into() - main_current[4].into()); - builder.assert_zero::<_>(main_current[5].into() * main_current[5].into() - main_current[5].into()); - builder.assert_zero::<_>(main_current[6].into() * main_current[6].into() - main_current[6].into()); - builder.assert_zero::<_>(main_current[7].into() * main_current[7].into() - main_current[7].into()); - builder.assert_zero::<_>(main_current[8].into() * main_current[8].into() - main_current[8].into()); - builder.assert_zero::<_>(main_current[9].into() * main_current[9].into() - main_current[9].into()); - builder.assert_zero::<_>(main_current[10].into() * main_current[10].into() - main_current[10].into()); - builder.assert_zero::<_>(periodic_values[0].into() * (main_current[1].into() - (main_current[3].into() + main_current[4].into().double() + AB::Expr::from_u64(4) * main_current[5].into() + AB::Expr::from_u64(8) * main_current[6].into()))); - builder.assert_zero::<_>(periodic_values[0].into() * (main_current[2].into() - (main_current[7].into() + main_current[8].into().double() + AB::Expr::from_u64(4) * main_current[9].into() + AB::Expr::from_u64(8) * main_current[10].into()))); - builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[1].into() - (main_current[1].into() * AB::Expr::from_u64(16) + main_current[3].into() + main_current[4].into().double() + AB::Expr::from_u64(4) * main_current[5].into() + AB::Expr::from_u64(8) * main_current[6].into()))); - builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[2].into() - (main_current[2].into() * AB::Expr::from_u64(16) + main_current[7].into() + main_current[8].into().double() + AB::Expr::from_u64(4) * main_current[9].into() + AB::Expr::from_u64(8) * main_current[10].into()))); - builder.assert_zero::<_>(periodic_values[0].into() * main_current[11].into()); - builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_current[12].into() - main_next[11].into())); - builder.assert_zero::<_>((AB::Expr::ONE - main_current[0].into()) * (main_current[12].into() - (main_current[11].into() * AB::Expr::from_u64(16) + main_current[3].into() * main_current[7].into() + main_current[4].into().double() * main_current[8].into() + AB::Expr::from_u64(4) * main_current[5].into() * main_current[9].into() + AB::Expr::from_u64(8) * main_current[6].into() * main_current[10].into())) + main_current[0].into() * (main_current[12].into() - (main_current[11].into() * AB::Expr::from_u64(16) + main_current[3].into() + main_current[7].into() - main_current[3].into().double() * main_current[7].into() + (main_current[4].into() + main_current[8].into() - main_current[4].into().double() * main_current[8].into()).double() + AB::Expr::from_u64(4) * (main_current[5].into() + main_current[9].into() - main_current[5].into().double() * main_current[9].into()) + AB::Expr::from_u64(8) * (main_current[6].into() + main_current[10].into() - main_current[6].into().double() * main_current[10].into())))); - } -} \ No newline at end of file diff --git a/air-script/tests/buses/buses_complex_plonky3.rs b/air-script/tests/buses/buses_complex_plonky3.rs deleted file mode 100644 index 462ef499a..000000000 --- a/air-script/tests/buses/buses_complex_plonky3.rs +++ /dev/null @@ -1,44 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 5; - -pub const NUM_PUBLIC_VALUES: usize = 2; - -pub struct BusesAir; - -impl BaseAir for BusesAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for BusesAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for BusesAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for BusesAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[0].into()); - builder.assert_zero::<_>(main_current[2].into() * main_current[2].into() - main_current[2].into()); - builder.assert_zero::<_>(main_current[3].into() * main_current[3].into() - main_current[3].into()); - } -} \ No newline at end of file diff --git a/air-script/tests/buses/buses_simple_plonky3.rs b/air-script/tests/buses/buses_simple_plonky3.rs deleted file mode 100644 index 6ea46ea4b..000000000 --- a/air-script/tests/buses/buses_simple_plonky3.rs +++ /dev/null @@ -1,41 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 1; - -pub const NUM_PUBLIC_VALUES: usize = 2; - -pub struct BusesAir; - -impl BaseAir for BusesAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for BusesAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for BusesAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for BusesAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - } -} \ No newline at end of file diff --git a/air-script/tests/buses/buses_varlen_boundary_both_plonky3.rs b/air-script/tests/buses/buses_varlen_boundary_both_plonky3.rs deleted file mode 100644 index e8f0c1253..000000000 --- a/air-script/tests/buses/buses_varlen_boundary_both_plonky3.rs +++ /dev/null @@ -1,41 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 1; - -pub const NUM_PUBLIC_VALUES: usize = 6; - -pub struct BusesAir; - -impl BaseAir for BusesAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for BusesAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for BusesAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for BusesAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - } -} \ No newline at end of file diff --git a/air-script/tests/buses/buses_varlen_boundary_first_plonky3.rs b/air-script/tests/buses/buses_varlen_boundary_first_plonky3.rs deleted file mode 100644 index 6ea46ea4b..000000000 --- a/air-script/tests/buses/buses_varlen_boundary_first_plonky3.rs +++ /dev/null @@ -1,41 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 1; - -pub const NUM_PUBLIC_VALUES: usize = 2; - -pub struct BusesAir; - -impl BaseAir for BusesAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for BusesAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for BusesAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for BusesAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - } -} \ No newline at end of file diff --git a/air-script/tests/buses/buses_varlen_boundary_last_plonky3.rs b/air-script/tests/buses/buses_varlen_boundary_last_plonky3.rs deleted file mode 100644 index 6ea46ea4b..000000000 --- a/air-script/tests/buses/buses_varlen_boundary_last_plonky3.rs +++ /dev/null @@ -1,41 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 1; - -pub const NUM_PUBLIC_VALUES: usize = 2; - -pub struct BusesAir; - -impl BaseAir for BusesAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for BusesAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for BusesAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for BusesAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - } -} \ No newline at end of file diff --git a/air-script/tests/buses/test_air_plonky3.rs b/air-script/tests/buses/test_air_plonky3.rs deleted file mode 100644 index 1b323208b..000000000 --- a/air-script/tests/buses/test_air_plonky3.rs +++ /dev/null @@ -1,55 +0,0 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; - -use crate::{ - buses::buses_complex_plonky3::{BusesAir, NUM_COLUMNS}, - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, -}; - -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; - - let mut long_trace = F::zero_vec(trace_length); - - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); - - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; - assert!(prefix.is_empty(), "Alignment should match"); - assert!(suffix.is_empty(), "Alignment should match"); - assert_eq!(rows.len(), num_rows); - - // Initialize first row - rows[0][0] = F::ZERO; - rows[0][1] = F::ZERO; - - // Fill subsequent rows using direct access to the rows array - for i in 1..num_rows { - let a_prev = rows[i - 1][0]; - let b_prev = rows[i - 1][1]; - - // Update current row based on previous values - rows[i][0] = F::ONE - a_prev; - rows[i][1] = F::ONE - b_prev; - } - - trace -} - -fn generate_inputs() -> Vec { - vec![1; 2] -} - -generate_air_plonky3_test!(test_air_plonky3, BusesAir); diff --git a/air-script/tests/codegen/mod.rs b/air-script/tests/codegen/mod.rs deleted file mode 100644 index a23676b61..000000000 --- a/air-script/tests/codegen/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod helpers; -mod plonky3; -mod winterfell; diff --git a/air-script/tests/codegen/plonky3.rs b/air-script/tests/codegen/plonky3.rs deleted file mode 100644 index 8ccbb2d55..000000000 --- a/air-script/tests/codegen/plonky3.rs +++ /dev/null @@ -1,323 +0,0 @@ -use expect_test::expect_file; - -use super::helpers::{Target, Test}; - -#[test] -fn binary() { - let generated_air = Test::new("tests/binary/binary.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../binary/binary_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn buses_simple() { - let generated_air = Test::new("tests/buses/buses_simple.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../buses/buses_simple_plonky3.rs"]; - expected.assert_eq(&generated_air); -} -#[test] -fn buses_simple_with_evaluators() { - let generated_air = Test::new("tests/buses/buses_simple_with_evaluators.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../buses/buses_simple_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn buses_complex() { - let generated_air = Test::new("tests/buses/buses_complex.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../buses/buses_complex_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn buses_varlen_boundary_first() { - let generated_air = Test::new("tests/buses/buses_varlen_boundary_first.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../buses/buses_varlen_boundary_first_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn buses_varlen_boundary_last() { - let generated_air = Test::new("tests/buses/buses_varlen_boundary_last.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../buses/buses_varlen_boundary_last_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn buses_varlen_boundary_both() { - let generated_air = Test::new("tests/buses/buses_varlen_boundary_both.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../buses/buses_varlen_boundary_both_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn periodic_columns() { - let generated_air = Test::new("tests/periodic_columns/periodic_columns.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../periodic_columns/periodic_columns_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn pub_inputs() { - let generated_air = Test::new("tests/pub_inputs/pub_inputs.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../pub_inputs/pub_inputs_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn system() { - let generated_air = Test::new("tests/system/system.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../system/system_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn bitwise() { - let generated_air = Test::new("tests/bitwise/bitwise.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../bitwise/bitwise_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn computed_indices_complex() { - let generated_air = - Test::new("tests/computed_indices/computed_indices_complex.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../computed_indices/computed_indices_complex_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn computed_indices_simple() { - let generated_air = Test::new("tests/computed_indices/computed_indices_simple.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../computed_indices/computed_indices_simple_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn constants() { - let generated_air = Test::new("tests/constants/constants.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../constants/constants_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn constant_in_range() { - let generated_air = Test::new("tests/constant_in_range/constant_in_range.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../constant_in_range/constant_in_range_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn evaluators() { - let generated_air = Test::new("tests/evaluators/evaluators.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../evaluators/evaluators_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn fibonacci() { - let generated_air = Test::new("tests/fibonacci/fibonacci.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../fibonacci/fibonacci_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn functions_simple() { - let generated_air = Test::new("tests/functions/functions_simple.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../functions/functions_simple_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn functions_simple_inlined() { - // make sure that the constraints generated using inlined functions are the same as the ones - // generated using regular functions - let generated_air = Test::new("tests/functions/inlined_functions_simple.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../functions/functions_simple_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn functions_complex() { - let generated_air = Test::new("tests/functions/functions_complex.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../functions/functions_complex_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn variables() { - let generated_air = Test::new("tests/variables/variables.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../variables/variables_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn trace_col_groups() { - let generated_air = Test::new("tests/trace_col_groups/trace_col_groups.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../trace_col_groups/trace_col_groups_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn indexed_trace_access() { - let generated_air = - Test::new("tests/indexed_trace_access/indexed_trace_access.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../indexed_trace_access/indexed_trace_access_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn list_comprehension() { - let generated_air = Test::new("tests/list_comprehension/list_comprehension.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../list_comprehension/list_comprehension_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn list_comprehension_nested() { - let generated_air = - Test::new("tests/list_comprehension/list_comprehension_nested.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../list_comprehension/list_comprehension_nested_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn list_folding() { - let generated_air = Test::new("tests/list_folding/list_folding.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../list_folding/list_folding_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn selectors() { - let generated_air = Test::new("tests/selectors/selectors.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../selectors/selectors_plonky3.rs"]; - expected.assert_eq(&generated_air); - - let generated_air = Test::new("tests/selectors/selectors_with_evaluators.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../selectors/selectors_with_evaluators_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn selectors_combine_simple() { - let generated_air = Test::new("tests/selectors/selectors_combine_simple.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../selectors/selectors_combine_simple_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn selectors_combine_complex() { - let generated_air = Test::new("tests/selectors/selectors_combine_complex.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../selectors/selectors_combine_complex_plonky3.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn constraint_comprehension() { - let generated_air = - Test::new("tests/constraint_comprehension/constraint_comprehension.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../constraint_comprehension/constraint_comprehension_plonky3.rs"]; - expected.assert_eq(&generated_air); - - let generated_air = - Test::new("tests/constraint_comprehension/cc_with_evaluators.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); - - let expected = expect_file!["../constraint_comprehension/constraint_comprehension_plonky3.rs"]; - expected.assert_eq(&generated_air); -} diff --git a/air-script/tests/codegen/winterfell.rs b/air-script/tests/codegen/winterfell.rs deleted file mode 100644 index 28a993cd6..000000000 --- a/air-script/tests/codegen/winterfell.rs +++ /dev/null @@ -1,335 +0,0 @@ -use expect_test::expect_file; - -use super::helpers::{Target, Test}; - -#[test] -fn binary() { - let generated_air = Test::new("tests/binary/binary.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../binary/binary.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn bitwise() { - let generated_air = Test::new("tests/bitwise/bitwise.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../bitwise/bitwise.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn buses_complex() { - let generated_air = Test::new("tests/buses/buses_complex.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../buses/buses_complex.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn buses_simple() { - let generated_air = Test::new("tests/buses/buses_simple.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../buses/buses_simple.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn buses_simple_with_evaluators() { - let generated_air = Test::new("tests/buses/buses_simple_with_evaluators.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../buses/buses_simple.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn buses_varlen_boundary_both() { - let generated_air = Test::new("tests/buses/buses_varlen_boundary_both.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../buses/buses_varlen_boundary_both.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn buses_varlen_boundary_first() { - let generated_air = Test::new("tests/buses/buses_varlen_boundary_first.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../buses/buses_varlen_boundary_first.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn buses_varlen_boundary_last() { - let generated_air = Test::new("tests/buses/buses_varlen_boundary_last.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../buses/buses_varlen_boundary_last.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn computed_indices_complex() { - let generated_air = - Test::new("tests/computed_indices/computed_indices_complex.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../computed_indices/computed_indices_complex.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn computed_indices_simple() { - let generated_air = Test::new("tests/computed_indices/computed_indices_simple.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../computed_indices/computed_indices_simple.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn constant_in_range() { - let generated_air = Test::new("tests/constant_in_range/constant_in_range.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../constant_in_range/constant_in_range.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn constants() { - let generated_air = Test::new("tests/constants/constants.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../constants/constants.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn constraint_comprehension() { - let generated_air = - Test::new("tests/constraint_comprehension/constraint_comprehension.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../constraint_comprehension/constraint_comprehension.rs"]; - expected.assert_eq(&generated_air); - - let generated_air = - Test::new("tests/constraint_comprehension/cc_with_evaluators.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../constraint_comprehension/constraint_comprehension.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn evaluators() { - let generated_air = Test::new("tests/evaluators/evaluators.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../evaluators/evaluators.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn fibonacci() { - let generated_air = Test::new("tests/fibonacci/fibonacci.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../fibonacci/fibonacci.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn functions_complex() { - let generated_air = Test::new("tests/functions/functions_complex.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../functions/functions_complex.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn functions_simple() { - let generated_air = Test::new("tests/functions/functions_simple.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../functions/functions_simple.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn functions_simple_inlined() { - // make sure that the constraints generated using inlined functions are the same as the ones - // generated using regular functions - let generated_air = Test::new("tests/functions/inlined_functions_simple.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../functions/functions_simple.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn indexed_trace_access() { - let generated_air = - Test::new("tests/indexed_trace_access/indexed_trace_access.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../indexed_trace_access/indexed_trace_access.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn list_comprehension() { - let generated_air = Test::new("tests/list_comprehension/list_comprehension.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../list_comprehension/list_comprehension.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn list_comprehension_nested() { - let generated_air = - Test::new("tests/list_comprehension/list_comprehension_nested.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../list_comprehension/list_comprehension_nested.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn list_folding() { - let generated_air = Test::new("tests/list_folding/list_folding.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../list_folding/list_folding.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn periodic_columns() { - let generated_air = Test::new("tests/periodic_columns/periodic_columns.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../periodic_columns/periodic_columns.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn pub_inputs() { - let generated_air = Test::new("tests/pub_inputs/pub_inputs.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../pub_inputs/pub_inputs.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn selectors() { - let generated_air = Test::new("tests/selectors/selectors.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../selectors/selectors.rs"]; - expected.assert_eq(&generated_air); - - let generated_air = Test::new("tests/selectors/selectors_with_evaluators.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../selectors/selectors_with_evaluators.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn selectors_combine_simple() { - let generated_air = Test::new("tests/selectors/selectors_combine_simple.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../selectors/selectors_combine_simple.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn selectors_combine_complex() { - let generated_air = Test::new("tests/selectors/selectors_combine_complex.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../selectors/selectors_combine_complex.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn selectors_combine_with_list_comprehensions() { - let generated_air = - Test::new("tests/selectors/selectors_combine_with_list_comprehensions.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../selectors/selectors_combine_with_list_comprehensions.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn system() { - let generated_air = Test::new("tests/system/system.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../system/system.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn trace_col_groups() { - let generated_air = Test::new("tests/trace_col_groups/trace_col_groups.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../trace_col_groups/trace_col_groups.rs"]; - expected.assert_eq(&generated_air); -} - -#[test] -fn variables() { - let generated_air = Test::new("tests/variables/variables.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); - - let expected = expect_file!["../variables/variables.rs"]; - expected.assert_eq(&generated_air); -} diff --git a/air-script/tests/computed_indices/computed_indices_complex_plonky3.rs b/air-script/tests/computed_indices/computed_indices_complex_plonky3.rs deleted file mode 100644 index 1ded2a430..000000000 --- a/air-script/tests/computed_indices/computed_indices_complex_plonky3.rs +++ /dev/null @@ -1,43 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 4; - -pub const NUM_PUBLIC_VALUES: usize = 1; - -pub struct ComputedIndicesAir; - -impl BaseAir for ComputedIndicesAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for ComputedIndicesAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for ComputedIndicesAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for ComputedIndicesAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[0].into()); - builder.assert_zero::<_>(main_current[2].into() * AB::Expr::from_u64(3) + main_current[3].into() * AB::Expr::from_u64(4)); - } -} \ No newline at end of file diff --git a/air-script/tests/computed_indices/computed_indices_simple_plonky3.rs b/air-script/tests/computed_indices/computed_indices_simple_plonky3.rs deleted file mode 100644 index 3ac8ed33b..000000000 --- a/air-script/tests/computed_indices/computed_indices_simple_plonky3.rs +++ /dev/null @@ -1,50 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 8; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct ComputedIndicesAir; - -impl BaseAir for ComputedIndicesAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for ComputedIndicesAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for ComputedIndicesAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for ComputedIndicesAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[0].into()); - builder.assert_zero::<_>(main_current[0].into()); - builder.assert_zero::<_>(main_current[1].into() - AB::Expr::from_u64(2)); - builder.assert_zero::<_>(main_current[2].into() - AB::Expr::from_u64(4)); - builder.assert_zero::<_>(main_current[3].into() - AB::Expr::from_u64(6)); - builder.when_transition().assert_zero::<_>(main_next[4].into()); - builder.when_transition().assert_zero::<_>(main_next[5].into() - main_current[5].into().double()); - builder.when_transition().assert_zero::<_>(main_next[6].into() - AB::Expr::from_u64(6) * main_current[6].into()); - builder.when_transition().assert_zero::<_>(main_next[7].into() - AB::Expr::from_u64(12) * main_current[7].into()); - } -} \ No newline at end of file diff --git a/air-script/tests/computed_indices/mod.rs b/air-script/tests/computed_indices/mod.rs deleted file mode 100644 index 5f582b136..000000000 --- a/air-script/tests/computed_indices/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -#[rustfmt::skip] -#[allow(clippy::all)] -mod computed_indices_complex; -#[rustfmt::skip] -#[allow(clippy::all)] -mod computed_indices_simple; -mod test_air; diff --git a/air-script/tests/constant_in_range/constant_in_range_plonky3.rs b/air-script/tests/constant_in_range/constant_in_range_plonky3.rs deleted file mode 100644 index 5f657e987..000000000 --- a/air-script/tests/constant_in_range/constant_in_range_plonky3.rs +++ /dev/null @@ -1,43 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 12; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct ConstantInRangeAir; - -impl BaseAir for ConstantInRangeAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for ConstantInRangeAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for ConstantInRangeAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for ConstantInRangeAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[6].into()); - builder.assert_zero::<_>(main_current[0].into() - (main_current[1].into() - main_current[4].into() - main_current[8].into() + AB::Expr::ONE + main_current[2].into() - main_current[5].into() - main_current[9].into() + AB::Expr::from_u64(2) + main_current[3].into() - main_current[6].into() - main_current[10].into())); - } -} \ No newline at end of file diff --git a/air-script/tests/constants/constants_plonky3.rs b/air-script/tests/constants/constants_plonky3.rs deleted file mode 100644 index fa2ffccac..000000000 --- a/air-script/tests/constants/constants_plonky3.rs +++ /dev/null @@ -1,52 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 7; - -pub const NUM_PUBLIC_VALUES: usize = 32; - -pub struct ConstantsAir; - -impl BaseAir for ConstantsAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for ConstantsAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for ConstantsAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for ConstantsAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[0].into() - AB::Expr::ONE); - builder.when_first_row().assert_zero::<_>(main_current[1].into() - AB::Expr::ONE); - builder.when_first_row().assert_zero::<_>(main_current[2].into()); - builder.when_first_row().assert_zero::<_>(main_current[3].into() - AB::Expr::ONE); - builder.when_first_row().assert_zero::<_>(main_current[4].into() - AB::Expr::ONE); - builder.when_last_row().assert_zero::<_>(main_current[6].into()); - builder.when_transition().assert_zero::<_>(main_next[0].into() - (main_current[0].into() + AB::Expr::ONE)); - builder.when_transition().assert_zero::<_>(main_next[1].into()); - builder.when_transition().assert_zero::<_>(main_next[2].into() - main_current[2].into()); - builder.when_transition().assert_zero::<_>(main_next[5].into() - (main_current[5].into() + AB::Expr::ONE)); - builder.assert_zero::<_>(main_current[4].into() - AB::Expr::ONE); - } -} \ No newline at end of file diff --git a/air-script/tests/constraint_comprehension/constraint_comprehension_plonky3.rs b/air-script/tests/constraint_comprehension/constraint_comprehension_plonky3.rs deleted file mode 100644 index b501fe9d3..000000000 --- a/air-script/tests/constraint_comprehension/constraint_comprehension_plonky3.rs +++ /dev/null @@ -1,46 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 14; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct ConstraintComprehensionAir; - -impl BaseAir for ConstraintComprehensionAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for ConstraintComprehensionAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for ConstraintComprehensionAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for ConstraintComprehensionAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[8].into()); - builder.assert_zero::<_>(main_current[6].into() - main_current[10].into()); - builder.assert_zero::<_>(main_current[7].into() - main_current[11].into()); - builder.assert_zero::<_>(main_current[8].into() - main_current[12].into()); - builder.assert_zero::<_>(main_current[9].into() - main_current[13].into()); - } -} \ No newline at end of file diff --git a/air-script/tests/constraint_comprehension/test_air_plonky3.rs b/air-script/tests/constraint_comprehension/test_air_plonky3.rs deleted file mode 100644 index ceab24925..000000000 --- a/air-script/tests/constraint_comprehension/test_air_plonky3.rs +++ /dev/null @@ -1,57 +0,0 @@ -use std::marker::PhantomData; - -use p3_challenger::{HashChallenger, SerializingChallenger64}; -use p3_circle::CirclePcs; -use p3_commit::ExtensionMmcs; -use p3_field::{PrimeCharacteristicRing, PrimeField64, extension::BinomialExtensionField}; -use p3_fri::create_benchmark_fri_params; -use p3_goldilocks::Goldilocks; -use p3_matrix::dense::RowMajorMatrix; -use p3_merkle_tree::MerkleTreeMmcs; -use p3_sha256::Sha256; -use p3_symmetric::{CompressionFunctionFromHasher, SerializingHasher}; -use p3_uni_stark::StarkConfig; - -use crate::{ - constraint_comprehension::constraint_comprehension_plonky3::{ - ConstraintComprehensionAir, NUM_COLUMNS, - }, - generate_air_plonky3_test, - helpers::check_constraints_with_periodic_columns, -}; - -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; - let trace_length = num_rows * NUM_COLUMNS; - - let mut long_trace = F::zero_vec(trace_length); - - let mut trace = RowMajorMatrix::new(long_trace, NUM_COLUMNS); - - let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; NUM_COLUMNS]>() }; - assert!(prefix.is_empty(), "Alignment should match"); - assert!(suffix.is_empty(), "Alignment should match"); - assert_eq!(rows.len(), num_rows); - - // Initialize first row - rows[0][0] = F::from_canonical_checked(inputs[0]).unwrap(); - rows[0][1] = F::ONE; - - // Fill subsequent rows using direct access to the rows array - for i in 1..num_rows { - let a_prev = rows[i - 1][0]; - let b_prev = rows[i - 1][1]; - - // Update current row based on previous values - rows[i][0] = F::ONE - a_prev; - rows[i][1] = F::ONE - b_prev; - } - - trace -} - -fn generate_inputs() -> Vec { - vec![1; 16] -} - -generate_air_plonky3_test!(test_air_plonky3, ConstraintComprehensionAir); diff --git a/air-script/tests/evaluators/evaluators_plonky3.rs b/air-script/tests/evaluators/evaluators_plonky3.rs deleted file mode 100644 index becb57b5a..000000000 --- a/air-script/tests/evaluators/evaluators_plonky3.rs +++ /dev/null @@ -1,52 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 7; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct EvaluatorsAir; - -impl BaseAir for EvaluatorsAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for EvaluatorsAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for EvaluatorsAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for EvaluatorsAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[0].into()); - builder.when_transition().assert_zero::<_>(main_next[0].into() - main_current[0].into()); - builder.when_transition().assert_zero::<_>(main_next[2].into() - main_current[2].into()); - builder.when_transition().assert_zero::<_>(main_next[6].into() - main_current[6].into()); - builder.assert_zero::<_>(main_current[0].into() * main_current[0].into() - main_current[0].into()); - builder.assert_zero::<_>(main_current[1].into() * main_current[1].into() - main_current[1].into()); - builder.assert_zero::<_>(main_current[2].into() * main_current[2].into() - main_current[2].into()); - builder.assert_zero::<_>(main_current[3].into() * main_current[3].into() - main_current[3].into()); - builder.assert_zero::<_>(main_current[4].into()); - builder.assert_zero::<_>(main_current[5].into() - AB::Expr::ONE); - builder.assert_zero::<_>(main_current[6].into() - AB::Expr::from_u64(4)); - } -} \ No newline at end of file diff --git a/air-script/tests/fibonacci/fibonacci_plonky3.rs b/air-script/tests/fibonacci/fibonacci_plonky3.rs deleted file mode 100644 index 262dbb610..000000000 --- a/air-script/tests/fibonacci/fibonacci_plonky3.rs +++ /dev/null @@ -1,46 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 2; - -pub const NUM_PUBLIC_VALUES: usize = 3; - -pub struct FibonacciAir; - -impl BaseAir for FibonacciAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for FibonacciAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for FibonacciAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for FibonacciAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[0].into() - public_values[0].into()); - builder.when_first_row().assert_zero::<_>(main_current[1].into() - public_values[1].into()); - builder.when_last_row().assert_zero::<_>(main_current[1].into() - public_values[2].into()); - builder.when_transition().assert_zero::<_>(main_next[1].into() - (main_current[0].into() + main_current[1].into())); - builder.when_transition().assert_zero::<_>(main_next[0].into() - main_current[1].into()); - } -} \ No newline at end of file diff --git a/air-script/tests/functions/functions_complex_plonky3.rs b/air-script/tests/functions/functions_complex_plonky3.rs deleted file mode 100644 index cca15366b..000000000 --- a/air-script/tests/functions/functions_complex_plonky3.rs +++ /dev/null @@ -1,44 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 17; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct FunctionsAir; - -impl BaseAir for FunctionsAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for FunctionsAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for FunctionsAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for FunctionsAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[3].into()); - builder.when_transition().assert_zero::<_>(main_next[16].into() - main_current[16].into() * ((main_current[3].into() * main_current[3].into() * main_current[3].into() * main_current[3].into() * main_current[3].into() * main_current[3].into() * main_current[3].into() * main_current[1].into() * main_current[2].into() + main_current[3].into() * main_current[3].into() * (AB::Expr::ONE - main_current[1].into()) * main_current[2].into() + main_current[3].into() * main_current[1].into() * (AB::Expr::ONE - main_current[2].into()) + (AB::Expr::ONE - main_current[1].into()) * (AB::Expr::ONE - main_current[2].into())) * main_current[0].into() - main_current[0].into() + AB::Expr::ONE)); - builder.when_transition().assert_zero::<_>(main_next[3].into() - (main_current[4].into() + main_current[5].into() + main_current[6].into() + main_current[7].into() + main_current[8].into() + main_current[9].into() + main_current[10].into() + main_current[11].into() + main_current[12].into() + main_current[13].into() + main_current[14].into() + main_current[15].into() + AB::Expr::ONE).double()); - } -} \ No newline at end of file diff --git a/air-script/tests/functions/functions_simple_plonky3.rs b/air-script/tests/functions/functions_simple_plonky3.rs deleted file mode 100644 index 7d19e8a4b..000000000 --- a/air-script/tests/functions/functions_simple_plonky3.rs +++ /dev/null @@ -1,50 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 9; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct FunctionsAir; - -impl BaseAir for FunctionsAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for FunctionsAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for FunctionsAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for FunctionsAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[3].into()); - builder.assert_zero::<_>(main_current[0].into() * main_current[3].into() - AB::Expr::ONE); - builder.assert_zero::<_>(main_current[4].into() * main_current[5].into() * main_current[6].into() * main_current[7].into() * main_current[3].into() - AB::Expr::ONE); - builder.assert_zero::<_>((main_current[4].into() + main_current[5].into() + main_current[6].into() + main_current[7].into()) * main_current[4].into() * main_current[5].into() * main_current[6].into() * main_current[7].into() - AB::Expr::ONE); - builder.assert_zero::<_>(main_current[4].into() * main_current[5].into() * main_current[6].into() * main_current[7].into() - AB::Expr::ONE); - builder.assert_zero::<_>(main_current[0].into() * main_current[4].into() * main_current[5].into() * main_current[6].into() * main_current[7].into() - AB::Expr::ONE); - builder.assert_zero::<_>(main_current[1].into() + (main_current[4].into() + main_current[5].into() + main_current[6].into() + main_current[7].into()) * main_current[4].into() * main_current[5].into() * main_current[6].into() * main_current[7].into() - AB::Expr::ONE); - builder.assert_zero::<_>(main_current[4].into() + main_current[5].into() + main_current[6].into() + main_current[7].into() - AB::Expr::ONE); - builder.assert_zero::<_>((main_current[4].into() + main_current[5].into() + main_current[6].into() + main_current[7].into()) * AB::Expr::from_u64(4) - AB::Expr::ONE); - } -} \ No newline at end of file diff --git a/air-script/tests/helpers/mod.rs b/air-script/tests/helpers/mod.rs deleted file mode 100644 index 846ff0fd2..000000000 --- a/air-script/tests/helpers/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -mod plonky3_periodic_columns; -mod winterfell_test_helpers; - -pub use plonky3_periodic_columns::*; -pub use winterfell_test_helpers::*; -pub mod macros; diff --git a/air-script/tests/helpers/plonky3_periodic_columns.rs b/air-script/tests/helpers/plonky3_periodic_columns.rs deleted file mode 100644 index 245a8d037..000000000 --- a/air-script/tests/helpers/plonky3_periodic_columns.rs +++ /dev/null @@ -1,146 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir}; -use p3_field::Field; -use p3_matrix::{ - Matrix, - dense::{RowMajorMatrix, RowMajorMatrixView}, - stack::VerticalPair, -}; - -pub trait BaseAirWithPeriodicColumns: BaseAir { - fn get_periodic_columns(&self) -> Vec> { - vec![] - } -} - -pub trait AirBuilderWithPeriodicColumns: AirBuilder { - type PeriodicColumnsVar: Field + Into; - - fn periodic_columns(&self) -> Vec { - vec![] - } -} - -pub(crate) fn check_constraints_with_periodic_columns( - air: &A, - main: &RowMajorMatrix, - public_values: &Vec, -) where - F: Field, - A: for<'a> Air> - + BaseAirWithPeriodicColumns, -{ - let height = main.height(); - - (0..height).for_each(|i| { - let i_next = (i + 1) % height; - - let local = main.row_slice(i).unwrap(); // i < height so unwrap should never fail. - let next = main.row_slice(i_next).unwrap(); // i_next < height so unwrap should never fail. - let main = VerticalPair::new( - RowMajorMatrixView::new_row(&*local), - RowMajorMatrixView::new_row(&*next), - ); - let periodic_columns = air.get_periodic_columns(); - - let mut builder = DebugConstraintBuilderWithPeriodicColumns { - row_index: i, - main, - public_values, - is_first_row: F::from_bool(i == 0), - is_last_row: F::from_bool(i == height - 1), - is_transition: F::from_bool(i != height - 1), - periodic_columns, - }; - - air.eval(&mut builder); - }); -} - -/// A builder that runs constraint assertions during testing. -/// -/// Used in conjunction with [`check_constraints`] to simulate -/// an execution trace and verify that the AIR logic enforces all constraints. -#[derive(Debug)] -pub struct DebugConstraintBuilderWithPeriodicColumns<'a, F: Field> { - /// The index of the row currently being evaluated. - row_index: usize, - /// A view of the current and next row as a vertical pair. - main: VerticalPair, RowMajorMatrixView<'a, F>>, - /// The public values provided for constraint validation (e.g. inputs or outputs). - public_values: &'a [F], - /// A flag indicating whether this is the first row. - is_first_row: F, - /// A flag indicating whether this is the last row. - is_last_row: F, - /// A flag indicating whether this is a transition row (not the last row). - is_transition: F, - /// The periodic columns provided for constraint validation. - periodic_columns: Vec>, -} - -impl<'a, F> AirBuilderWithPeriodicColumns for DebugConstraintBuilderWithPeriodicColumns<'a, F> -where - F: Field + Into, -{ - type PeriodicColumnsVar = F; - - fn periodic_columns(&self) -> Vec { - self.periodic_columns - .iter() - .map(|col| col[self.row_index % col.len()]) - .collect::>() - } -} - -impl<'a, F> AirBuilder for DebugConstraintBuilderWithPeriodicColumns<'a, F> -where - F: Field, -{ - type F = F; - type Expr = F; - type Var = F; - type M = VerticalPair, RowMajorMatrixView<'a, F>>; - - fn main(&self) -> Self::M { - self.main - } - - fn is_first_row(&self) -> Self::Expr { - self.is_first_row - } - - fn is_last_row(&self) -> Self::Expr { - self.is_last_row - } - - /// # Panics - /// This function panics if `size` is not `2`. - fn is_transition_window(&self, size: usize) -> Self::Expr { - if size == 2 { - self.is_transition - } else { - panic!("only supports a window size of 2") - } - } - - fn assert_zero>(&mut self, x: I) { - assert_eq!(x.into(), F::ZERO, "constraints had nonzero value on row {}", self.row_index); - } - - fn assert_eq, I2: Into>(&mut self, x: I1, y: I2) { - let x = x.into(); - let y = y.into(); - assert_eq!(x, y, "values didn't match on row {}: {} != {}", self.row_index, x, y); - } -} - -impl<'a, F> AirBuilderWithPublicValues for DebugConstraintBuilderWithPeriodicColumns<'a, F> -where - F: Field, -{ - type PublicVar = Self::F; - - fn public_values(&self) -> &[Self::F] { - self.public_values - } -} diff --git a/air-script/tests/indexed_trace_access/indexed_trace_access_plonky3.rs b/air-script/tests/indexed_trace_access/indexed_trace_access_plonky3.rs deleted file mode 100644 index 0bd768900..000000000 --- a/air-script/tests/indexed_trace_access/indexed_trace_access_plonky3.rs +++ /dev/null @@ -1,43 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 4; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct TraceAccessAir; - -impl BaseAir for TraceAccessAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for TraceAccessAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for TraceAccessAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for TraceAccessAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[0].into()); - builder.when_transition().assert_zero::<_>(main_next[0].into() - (main_current[1].into() + AB::Expr::ONE)); - } -} \ No newline at end of file diff --git a/air-script/tests/list_comprehension/list_comprehension_nested_plonky3.rs b/air-script/tests/list_comprehension/list_comprehension_nested_plonky3.rs deleted file mode 100644 index 2a8b9181f..000000000 --- a/air-script/tests/list_comprehension/list_comprehension_nested_plonky3.rs +++ /dev/null @@ -1,45 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 2; - -pub const NUM_PUBLIC_VALUES: usize = 1; - -pub struct ListComprehensionAir; - -impl BaseAir for ListComprehensionAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for ListComprehensionAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for ListComprehensionAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for ListComprehensionAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[0].into()); - builder.assert_zero::<_>(main_current[0].into() + main_current[1].into().double() - AB::Expr::from_u64(3)); - builder.assert_zero::<_>(main_current[0].into().double() + main_current[1].into() * AB::Expr::from_u64(3) - AB::Expr::from_u64(5)); - builder.assert_zero::<_>(main_current[0].into() * AB::Expr::from_u64(3) + main_current[1].into() * AB::Expr::from_u64(4) - AB::Expr::from_u64(7)); - } -} \ No newline at end of file diff --git a/air-script/tests/list_comprehension/list_comprehension_plonky3.rs b/air-script/tests/list_comprehension/list_comprehension_plonky3.rs deleted file mode 100644 index b2133e873..000000000 --- a/air-script/tests/list_comprehension/list_comprehension_plonky3.rs +++ /dev/null @@ -1,48 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 16; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct ListComprehensionAir; - -impl BaseAir for ListComprehensionAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for ListComprehensionAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for ListComprehensionAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for ListComprehensionAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[10].into()); - builder.assert_zero::<_>(main_current[0].into() - main_current[2].into()); - builder.assert_zero::<_>(main_current[4].into() - main_current[0].into() * AB::Expr::from_u64(8) * main_current[11].into()); - builder.when_transition().assert_zero::<_>(main_current[4].into() - main_current[0].into() * (main_next[8].into() - main_next[12].into())); - builder.assert_zero::<_>(main_current[6].into() - main_current[0].into() * (main_current[9].into() - main_current[14].into())); - builder.assert_zero::<_>(main_current[1].into() - (main_current[5].into() - main_current[8].into() - main_current[12].into() + AB::Expr::from_u64(10) + main_current[6].into() - main_current[9].into() - main_current[13].into() + AB::Expr::from_u64(20) + main_current[7].into() - main_current[10].into() - main_current[14].into())); - builder.assert_zero::<_>(main_current[14].into() - AB::Expr::from_u64(10)); - } -} \ No newline at end of file diff --git a/air-script/tests/list_folding/list_folding_plonky3.rs b/air-script/tests/list_folding/list_folding_plonky3.rs deleted file mode 100644 index c1cd5e912..000000000 --- a/air-script/tests/list_folding/list_folding_plonky3.rs +++ /dev/null @@ -1,46 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 17; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct ListFoldingAir; - -impl BaseAir for ListFoldingAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for ListFoldingAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for ListFoldingAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for ListFoldingAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[11].into()); - builder.when_transition().assert_zero::<_>(main_next[5].into() - (main_current[9].into() + main_current[10].into() + main_current[11].into() + main_current[12].into() + main_current[13].into() * main_current[14].into() * main_current[15].into() * main_current[16].into())); - builder.when_transition().assert_zero::<_>(main_next[6].into() - (main_current[9].into() + main_current[10].into() + main_current[11].into() + main_current[12].into() + main_current[13].into() * main_current[14].into() * main_current[15].into() * main_current[16].into())); - builder.when_transition().assert_zero::<_>(main_next[7].into() - (main_current[9].into() * main_current[13].into() + main_current[10].into() * main_current[14].into() + main_current[11].into() * main_current[15].into() + main_current[12].into() * main_current[16].into() + (main_current[9].into() + main_current[13].into()) * (main_current[10].into() + main_current[14].into()) * (main_current[11].into() + main_current[15].into()) * (main_current[12].into() + main_current[16].into()))); - builder.when_transition().assert_zero::<_>(main_next[8].into() - (main_current[1].into() + main_current[9].into() * main_current[13].into() + main_current[10].into() * main_current[14].into() + main_current[11].into() * main_current[15].into() + main_current[12].into() * main_current[16].into() + main_current[9].into() * main_current[13].into() + main_current[10].into() * main_current[14].into() + main_current[11].into() * main_current[15].into() + main_current[12].into() * main_current[16].into())); - } -} \ No newline at end of file diff --git a/air-script/tests/periodic_columns/periodic_columns_plonky3.rs b/air-script/tests/periodic_columns/periodic_columns_plonky3.rs deleted file mode 100644 index fb42592e1..000000000 --- a/air-script/tests/periodic_columns/periodic_columns_plonky3.rs +++ /dev/null @@ -1,46 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 3; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct PeriodicColumnsAir; - -impl BaseAir for PeriodicColumnsAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for PeriodicColumnsAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for PeriodicColumnsAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - vec![F::from_u64(1), F::from_u64(0), F::from_u64(0), F::from_u64(0)], - vec![F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(0)], - ] - } -} - -impl Air for PeriodicColumnsAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[0].into()); - builder.assert_zero::<_>(periodic_values[0].into() * (main_current[1].into() + main_current[2].into())); - builder.when_transition().assert_zero::<_>(periodic_values[1].into() * (main_next[0].into() - main_current[0].into())); - } -} \ No newline at end of file diff --git a/air-script/tests/pub_inputs/pub_inputs_plonky3.rs b/air-script/tests/pub_inputs/pub_inputs_plonky3.rs deleted file mode 100644 index cb2ac03b7..000000000 --- a/air-script/tests/pub_inputs/pub_inputs_plonky3.rs +++ /dev/null @@ -1,50 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 4; - -pub const NUM_PUBLIC_VALUES: usize = 32; - -pub struct PubInputsAir; - -impl BaseAir for PubInputsAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for PubInputsAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for PubInputsAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for PubInputsAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[0].into() - public_values[8].into()); - builder.when_first_row().assert_zero::<_>(main_current[1].into() - public_values[9].into()); - builder.when_first_row().assert_zero::<_>(main_current[2].into() - public_values[10].into()); - builder.when_first_row().assert_zero::<_>(main_current[3].into() - public_values[11].into()); - builder.when_last_row().assert_zero::<_>(main_current[0].into() - public_values[12].into()); - builder.when_last_row().assert_zero::<_>(main_current[1].into() - public_values[13].into()); - builder.when_last_row().assert_zero::<_>(main_current[2].into() - public_values[14].into()); - builder.when_last_row().assert_zero::<_>(main_current[3].into() - public_values[15].into()); - builder.when_transition().assert_zero::<_>(main_next[0].into() - (main_current[1].into() + main_current[2].into())); - } -} \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_combine_complex_plonky3.rs b/air-script/tests/selectors/selectors_combine_complex_plonky3.rs deleted file mode 100644 index c8115936b..000000000 --- a/air-script/tests/selectors/selectors_combine_complex_plonky3.rs +++ /dev/null @@ -1,45 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 6; - -pub const NUM_PUBLIC_VALUES: usize = 1; - -pub struct SelectorsAir; - -impl BaseAir for SelectorsAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for SelectorsAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for SelectorsAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for SelectorsAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[5].into()); - builder.assert_zero::<_>((main_current[0].into() + (AB::Expr::ONE - main_current[0].into()) * main_current[1].into()) * (main_current[3].into() - AB::Expr::from_u64(16)) + (AB::Expr::ONE - main_current[0].into()) * (AB::Expr::ONE - main_current[1].into()) * (main_current[4].into() - AB::Expr::from_u64(5))); - builder.assert_zero::<_>((AB::Expr::ONE - main_current[0].into()) * (main_current[5].into() - AB::Expr::from_u64(5)) + main_current[0].into() * (main_current[4].into() - AB::Expr::from_u64(4))); - builder.assert_zero::<_>(main_current[0].into() * (main_current[5].into() - AB::Expr::from_u64(20)) + (AB::Expr::ONE - main_current[0].into()) * main_current[1].into() * (main_current[4].into() - AB::Expr::from_u64(31))); - } -} \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_combine_simple_plonky3.rs b/air-script/tests/selectors/selectors_combine_simple_plonky3.rs deleted file mode 100644 index c981e950b..000000000 --- a/air-script/tests/selectors/selectors_combine_simple_plonky3.rs +++ /dev/null @@ -1,44 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 4; - -pub const NUM_PUBLIC_VALUES: usize = 1; - -pub struct SelectorsAir; - -impl BaseAir for SelectorsAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for SelectorsAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for SelectorsAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for SelectorsAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[3].into()); - builder.when_transition().assert_zero::<_>(main_next[1].into() - main_current[2].into()); - builder.when_transition().assert_zero::<_>(main_current[3].into() * (main_next[0].into() - (main_current[0].into() + main_current[1].into())) + (AB::Expr::ONE - main_current[3].into()) * (main_next[0].into() - main_current[0].into() * main_current[1].into())); - } -} \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs b/air-script/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs deleted file mode 100644 index 1a937a640..000000000 --- a/air-script/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs +++ /dev/null @@ -1,45 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 6; - -pub const NUM_PUBLIC_VALUES: usize = 1; - -pub struct SelectorsAir; - -impl BaseAir for SelectorsAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for SelectorsAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for SelectorsAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for SelectorsAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[5].into()); - builder.assert_zero::<_>((main_current[0].into() + (AB::Expr::ONE - main_current[0].into()) * main_current[1].into()) * main_current[3].into() + (AB::Expr::ONE - main_current[0].into()) * (AB::Expr::ONE - main_current[1].into()) * (main_current[4].into() - AB::Expr::from_u64(8))); - builder.assert_zero::<_>((AB::Expr::ONE - main_current[0].into()) * (main_current[5].into() - AB::Expr::from_u64(8)) + main_current[0].into() * (main_current[4].into() - AB::Expr::from_u64(2))); - builder.assert_zero::<_>(main_current[0].into() * (main_current[5].into() - AB::Expr::from_u64(4)) + (AB::Expr::ONE - main_current[0].into()) * main_current[1].into() * (main_current[4].into() - AB::Expr::from_u64(6))); - } -} \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_plonky3.rs b/air-script/tests/selectors/selectors_plonky3.rs deleted file mode 100644 index 7b0b2f210..000000000 --- a/air-script/tests/selectors/selectors_plonky3.rs +++ /dev/null @@ -1,44 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 4; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct SelectorsAir; - -impl BaseAir for SelectorsAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for SelectorsAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for SelectorsAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for SelectorsAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[3].into()); - builder.when_transition().assert_zero::<_>(main_current[0].into() * (AB::Expr::ONE - main_current[1].into()) * main_next[3].into()); - builder.when_transition().assert_zero::<_>(main_current[0].into() * main_current[1].into() * main_current[2].into() * (main_next[3].into() - main_current[3].into()) + (AB::Expr::ONE - main_current[1].into()) * (AB::Expr::ONE - main_current[2].into()) * (main_next[3].into() - AB::Expr::ONE)); - } -} \ No newline at end of file diff --git a/air-script/tests/selectors/selectors_with_evaluators_plonky3.rs b/air-script/tests/selectors/selectors_with_evaluators_plonky3.rs deleted file mode 100644 index 10fd5fb98..000000000 --- a/air-script/tests/selectors/selectors_with_evaluators_plonky3.rs +++ /dev/null @@ -1,44 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 4; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct SelectorsAir; - -impl BaseAir for SelectorsAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for SelectorsAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for SelectorsAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for SelectorsAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[3].into()); - builder.when_transition().assert_zero::<_>(main_current[0].into() * (AB::Expr::ONE - main_current[1].into()) * main_next[3].into()); - builder.when_transition().assert_zero::<_>(main_current[1].into() * main_current[2].into() * main_current[0].into() * (main_next[3].into() - main_current[3].into()) + (AB::Expr::ONE - main_current[1].into()) * (AB::Expr::ONE - main_current[2].into()) * (main_next[3].into() - AB::Expr::ONE)); - } -} \ No newline at end of file diff --git a/air-script/tests/system/system_plonky3.rs b/air-script/tests/system/system_plonky3.rs deleted file mode 100644 index ca2204da0..000000000 --- a/air-script/tests/system/system_plonky3.rs +++ /dev/null @@ -1,43 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 3; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct SystemAir; - -impl BaseAir for SystemAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for SystemAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for SystemAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for SystemAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[0].into()); - builder.when_transition().assert_zero::<_>(main_next[0].into() - (main_current[0].into() + AB::Expr::ONE)); - } -} \ No newline at end of file diff --git a/air-script/tests/trace_col_groups/trace_col_groups_plonky3.rs b/air-script/tests/trace_col_groups/trace_col_groups_plonky3.rs deleted file mode 100644 index 08bf27975..000000000 --- a/air-script/tests/trace_col_groups/trace_col_groups_plonky3.rs +++ /dev/null @@ -1,44 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 9; - -pub const NUM_PUBLIC_VALUES: usize = 16; - -pub struct TraceColGroupAir; - -impl BaseAir for TraceColGroupAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for TraceColGroupAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for TraceColGroupAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - ] - } -} - -impl Air for TraceColGroupAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[8].into()); - builder.when_transition().assert_zero::<_>(main_next[2].into() - (main_current[2].into() + AB::Expr::ONE)); - builder.when_transition().assert_zero::<_>(main_next[1].into() - (main_current[1].into() - AB::Expr::ONE)); - } -} \ No newline at end of file diff --git a/air-script/tests/variables/variables_plonky3.rs b/air-script/tests/variables/variables_plonky3.rs deleted file mode 100644 index 48ce365c8..000000000 --- a/air-script/tests/variables/variables_plonky3.rs +++ /dev/null @@ -1,48 +0,0 @@ -use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, BaseAirWithPublicValues}; -use p3_matrix::Matrix; -use p3_field::PrimeCharacteristicRing; -use crate::helpers::{AirBuilderWithPeriodicColumns, BaseAirWithPeriodicColumns}; - -pub const NUM_COLUMNS: usize = 4; - -pub const NUM_PUBLIC_VALUES: usize = 32; - -pub struct VariablesAir; - -impl BaseAir for VariablesAir { - fn width(&self) -> usize { - NUM_COLUMNS - } -} - -impl BaseAirWithPublicValues for VariablesAir { - fn num_public_values(&self) -> usize { - NUM_PUBLIC_VALUES - } -} - -impl BaseAirWithPeriodicColumns for VariablesAir { - fn get_periodic_columns(&self) -> Vec> { - vec![ - vec![F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(1), F::from_u64(0)], - ] - } -} - -impl Air for VariablesAir { - fn eval(&self, builder: &mut AB) { - let main = builder.main(); - let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); - let periodic_values = builder.periodic_columns(); - let (main_current, main_next) = ( - main.row_slice(0).unwrap(), - main.row_slice(1).unwrap(), - ); - builder.when_first_row().assert_zero::<_>(main_current[1].into()); - builder.when_last_row().assert_zero::<_>(main_current[1].into() - AB::Expr::ONE); - builder.assert_zero::<_>(main_current[0].into() * main_current[0].into() - main_current[0].into()); - builder.when_transition().assert_zero::<_>(periodic_values[0].into() * (main_next[0].into() - main_current[0].into())); - builder.assert_zero::<_>((AB::Expr::ONE - main_current[0].into()) * (main_current[3].into() - main_current[1].into() - main_current[2].into()) - (AB::Expr::from_u64(6) - (AB::Expr::from_u64(7) - main_current[0].into()))); - builder.when_transition().assert_zero::<_>(main_current[0].into() * (main_current[3].into() - main_current[1].into() * main_current[2].into()) - (AB::Expr::ONE - main_next[0].into())); - } -} \ No newline at end of file diff --git a/air/src/ir/mod.rs b/air/src/ir/mod.rs index 0393558ba..06758392c 100644 --- a/air/src/ir/mod.rs +++ b/air/src/ir/mod.rs @@ -162,7 +162,7 @@ use alloc::collections::BTreeMap; use miden_diagnostics::{SourceSpan, Spanned}; -use crate::graph::AlgebraicGraph; +use crate::{NodeIndex, graph::AlgebraicGraph}; /// The intermediate representation of a complete AirScript program /// @@ -195,6 +195,18 @@ pub struct Air { /// /// Only their name, type, and the first and last boundary constraints are stored here. pub buses: BTreeMap, + /// Buses initial values used for auxiliary trace generation (indexed by bus index) + pub buses_initial_values: BTreeMap, + /// Buses transition expressions used for auxiliary trace generation (indexed by bus index) + /// The tuple contains the numerator and an optional denominator operation (p_prime = numerator + /// if None or numerator / denominator), computed in the `ExpandBuses` Air pass depending on + /// the bus type + /// - for multiset buses: p' = p * columns_inserted_in_bus / columns_removed_from_bus + /// - for logup buses, if u corresponds to the columns inserted when s1 and v to the columns + /// removed when s2 + /// q' = q + s1 / u - s2 / v + /// = (q * u * v + s1 * v - s2 * u) / (u * v) + pub buses_transitions: BTreeMap)>, } impl Default for Air { fn default() -> Self { @@ -217,6 +229,8 @@ impl Air { num_random_values: 0, constraints: Default::default(), buses: Default::default(), + buses_initial_values: Default::default(), + buses_transitions: Default::default(), } } diff --git a/air/src/passes/common_subexpression_elimination.rs b/air/src/passes/common_subexpression_elimination.rs index bc162b0da..38711c81c 100644 --- a/air/src/passes/common_subexpression_elimination.rs +++ b/air/src/passes/common_subexpression_elimination.rs @@ -32,6 +32,28 @@ impl Pass for CommonSubexpressionElimination<'_> { // Update constraints with the new node indices ir.constraints.renumber_and_deduplicate_constraints(&renumbering_map); + // Iterate over all bus transition expression and renumber their node indices + for (_, value) in ir.buses_initial_values.iter_mut() { + let new_value_index = *renumbering_map + .get(value) + .expect("Error: cannot find value index in renumbering map"); + *value = new_value_index; + } + + // Iterate over all bus transition expression and renumber their node indices + for (_, (numerator, denominator)) in ir.buses_transitions.iter_mut() { + let new_numerator_index = *renumbering_map + .get(numerator) + .expect("Error: cannot find numerator index in renumbering map"); + *numerator = new_numerator_index; + if let Some(denominator) = denominator { + let new_denominator_index = *renumbering_map + .get(denominator) + .expect("Error: cannot find denominator index in renumbering map"); + *denominator = new_denominator_index; + } + } + Ok(ir) } } diff --git a/air/src/passes/expand_buses.rs b/air/src/passes/expand_buses.rs index ff02487dd..fb5a33513 100644 --- a/air/src/passes/expand_buses.rs +++ b/air/src/passes/expand_buses.rs @@ -63,6 +63,7 @@ impl Pass for BusOpExpand<'_> { bus_ops, bus_access, bus_access_with_offset, + bus_index, ); }, BusType::Logup => { @@ -71,6 +72,7 @@ impl Pass for BusOpExpand<'_> { bus_ops, bus_access, bus_access_with_offset, + bus_index, ); }, } @@ -139,6 +141,19 @@ impl<'a> BusOpExpand<'a> { }; // Store the generated constraint ir.constraints.insert_constraint(TraceSegmentId::Aux, root, domain); + + // Also store the initial value for auxiliary trace generation + if boundary == Boundary::First { + // TODO: May be invalid? For now, we put its value to zero + if let BusBoundary::PublicInputTable(_) = bus_boundary { + let value = ir + .constraint_graph_mut() + .insert_node(Operation::Value(crate::Value::Constant(0))); + ir.buses_initial_values.insert(bus_index, value); + } else { + ir.buses_initial_values.insert(bus_index, value); + } + } } /// Helper function to expand the integrity constraint of a multiset bus @@ -148,6 +163,7 @@ impl<'a> BusOpExpand<'a> { bus_ops: Vec, bus_access: NodeIndex, bus_access_with_offset: NodeIndex, + bus_index: usize, ) { let graph = ir.constraint_graph_mut(); @@ -234,8 +250,14 @@ impl<'a> BusOpExpand<'a> { // 6. Create the resulting constraint and insert it into the graph let root = graph.insert_node(Operation::Sub(p_prod, p_prime_prod)); - ir.constraints - .insert_constraint(TraceSegmentId::Aux, root, ConstraintDomain::EveryRow); + ir.constraints.insert_constraint( + TraceSegmentId::Aux, + root, + ConstraintDomain::EveryFrame(2), + ); + + // Also store the expression to computed p_prime for auxiliary trace generation + ir.buses_transitions.insert(bus_index, (p_prod, p_prime_factor)); } /// Helper function to expand the integrity constraint of a logup bus @@ -245,6 +267,7 @@ impl<'a> BusOpExpand<'a> { bus_ops: Vec, bus_access: NodeIndex, bus_access_with_offset: NodeIndex, + bus_index: usize, ) { let graph = ir.constraint_graph_mut(); // Example: @@ -372,7 +395,23 @@ impl<'a> BusOpExpand<'a> { // 5. Create the resulting constraint let root = graph.insert_node(Operation::Sub(q_term, q_prime_term)); - ir.constraints - .insert_constraint(TraceSegmentId::Aux, root, ConstraintDomain::EveryRow); + + // Also store the expression to computed q_prime for auxiliary trace generation + // Note: TODO: Potentially adapt CSE to handle this properly, otherwise indices might + // change... + let numerator = match terms_removed_from_bus { + Some(terms_removed_from_bus) => { + graph.insert_node(Operation::Sub(q_term, terms_removed_from_bus)) + }, + None => q_term, + }; + + ir.constraints.insert_constraint( + TraceSegmentId::Aux, + root, + ConstraintDomain::EveryFrame(2), + ); + + ir.buses_transitions.insert(bus_index, (numerator, total_factors)); } } diff --git a/codegen/plonky3/src/air/boundary_constraints.rs b/codegen/plonky3/src/air/boundary_constraints.rs index 4c8fd0047..aba2206b0 100644 --- a/codegen/plonky3/src/air/boundary_constraints.rs +++ b/codegen/plonky3/src/air/boundary_constraints.rs @@ -1,24 +1,28 @@ use air_ir::{Air, TraceSegmentId}; use codegen::Function; -use super::Codegen; +use crate::air::graph::constraint_to_string; /// Adds the main boundary constraints to the generated code. pub(super) fn add_main_boundary_constraints(eval_func: &mut Function, ir: &Air) { + eval_func.line(""); + eval_func.line("// Main boundary constraints"); for constraint in ir.boundary_constraints(TraceSegmentId::Main) { - let expr_root = constraint.node_index(); - - let expr_root_string = expr_root.to_string(ir); + let assertion = constraint_to_string(ir, constraint, true); + eval_func.line(assertion); + } +} - let assertion = match constraint.domain() { - air_ir::ConstraintDomain::FirstRow => { - format!("builder.when_first_row().assert_zero::<_>({expr_root_string});") - }, - air_ir::ConstraintDomain::LastRow => { - format!("builder.when_last_row().assert_zero::<_>({expr_root_string});") - }, - _ => unreachable!("Boundary constraints can only be applied to the first or last row"), - }; +/// Adds the aux boundary constraints to the generated code. +pub(super) fn add_aux_boundary_constraints(eval_func: &mut Function, ir: &Air) { + eval_func.line(""); + eval_func.line("// Aux boundary constraints"); + for constraint in ir.boundary_constraints(TraceSegmentId::Aux) { + let assertion = constraint_to_string(ir, constraint, true); eval_func.line(assertion); + + // TODO: better check assumptions on aux boundary constraints: + // - start only with empty buses, + // - end with values derived from builder.aux_bus_boundary_value() } } diff --git a/codegen/plonky3/src/air/graph.rs b/codegen/plonky3/src/air/graph.rs index fb9e816b6..f9c27ed7c 100644 --- a/codegen/plonky3/src/air/graph.rs +++ b/codegen/plonky3/src/air/graph.rs @@ -1,4 +1,8 @@ -use air_ir::{Air, NodeIndex, Operation, TraceAccess, Value}; +use air_ir::{ + Air, ConstraintDomain, ConstraintRoot, NodeIndex, Operation, TraceAccess, TraceSegmentId, Value, +}; + +use crate::air::ElemType; // RUST STRING GENERATION FOR THE CONSTRAINT GRAPH // ================================================================================================ @@ -6,50 +10,66 @@ use air_ir::{Air, NodeIndex, Operation, TraceAccess, Value}; /// Code generation trait for generating Rust code strings from IR types related to constraints and /// the [AlgebraicGraph]. pub trait Codegen { - fn to_string(&self, ir: &Air) -> String; + fn to_string(&self, ir: &Air, elem_type: ElemType) -> String; } impl Codegen for TraceAccess { - fn to_string(&self, _ir: &Air) -> String { + fn to_string(&self, _ir: &Air, elem_type: ElemType) -> String { let frame = self.segment.to_string(); let row_offset = match self.row_offset { 0 => { - format!("current[{}].into()", self.column) + format!("current[{}]", self.column) }, 1 => { - format!("next[{}].into()", self.column) + format!("next[{}]", self.column) }, _ => panic!("Plonky3 doesn't support row offsets greater than 1."), }; - format!("{frame}_{row_offset}") + match elem_type { + ElemType::Base => format!("{frame}_{row_offset}.clone().into()"), + ElemType::Ext => format!("AB::ExprEF::from({frame}_{row_offset}.clone().into())"), + ElemType::ExtFieldElem => format!("EF::from({frame}_{row_offset}.clone())"), + } } } impl Codegen for NodeIndex { - fn to_string(&self, ir: &Air) -> String { + fn to_string(&self, ir: &Air, elem_type: ElemType) -> String { let op = ir.constraint_graph().node(self).op(); - op.to_string(ir) + op.to_string(ir, elem_type) } } impl Codegen for Operation { - fn to_string(&self, ir: &Air) -> String { + fn to_string(&self, ir: &Air, elem_type: ElemType) -> String { match self { - Operation::Value(value) => value.to_string(ir), - Operation::Add(..) => binary_op_to_string(ir, self), - Operation::Sub(..) => binary_op_to_string(ir, self), - Operation::Mul(..) => binary_op_to_string(ir, self), + Operation::Value(value) => value.to_string(ir, elem_type), + Operation::Add(..) => binary_op_to_string(ir, elem_type, self), + Operation::Sub(..) => binary_op_to_string(ir, elem_type, self), + Operation::Mul(..) => binary_op_to_string(ir, elem_type, self), } } } impl Codegen for Value { - fn to_string(&self, ir: &Air) -> String { + fn to_string(&self, ir: &Air, elem_type: ElemType) -> String { match self { - Value::Constant(0) => format!("AB::Expr::ZERO"), - Value::Constant(1) => format!("AB::Expr::ONE"), - Value::Constant(value) => format!("AB::Expr::from_u64({value})"), - Value::TraceAccess(trace_access) => trace_access.to_string(ir), + Value::Constant(0) => match elem_type { + ElemType::Base => format!("AB::Expr::ZERO"), + ElemType::Ext => format!("AB::ExprEF::ZERO"), + ElemType::ExtFieldElem => format!("EF::ZERO"), + }, + Value::Constant(1) => match elem_type { + ElemType::Base => format!("AB::Expr::ONE"), + ElemType::Ext => format!("AB::ExprEF::ONE"), + ElemType::ExtFieldElem => format!("EF::ONE"), + }, + Value::Constant(value) => match elem_type { + ElemType::Base => format!("AB::Expr::from_u64({value})"), + ElemType::Ext => format!("AB::ExprEF::from_u64({value})"), + ElemType::ExtFieldElem => format!("EF::from_u64({value})"), + }, + Value::TraceAccess(trace_access) => trace_access.to_string(ir, elem_type), Value::PublicInput(air_ir::PublicInputAccess { name, index }) => { let get_public_input_offset = |name: &str| { ir.public_inputs() @@ -62,37 +82,57 @@ impl Codegen for Value { Value::PeriodicColumn(pc) => { let index = ir.periodic_columns.iter().position(|(qid, _)| qid == &pc.name).unwrap(); - format!("periodic_values[{index}].into()") + match elem_type { + ElemType::Base => format!("AB::Expr::from(periodic_values[{index}].clone())"), + ElemType::Ext => { + format!("AB::ExprEF::from(periodic_values[{index}].clone().into())") + }, + ElemType::ExtFieldElem => { + format!("AB::EF::from(periodic_values[{index}].clone())") + }, + } }, - _ => todo!(), - /*Value::PublicInputTable(air_ir::PublicInputTableAccess { - table_name, - bus_type, - num_cols: _, - }) => { - format!("reduced_{table_name}_{bus_type}") + Value::PublicInputTable(public_input_table_access) => { + let idx = ir + .reduced_public_input_table_accesses() + .iter() + .position(|pi| pi == public_input_table_access) + .unwrap(); + format!("aux_bus_boundary_values[{idx}].into()") }, Value::RandomValue(idx) => { - format!("aux_rand_elements.rand_elements()[{idx}]") - },*/ + if *idx == 0 { + if let ElemType::ExtFieldElem = elem_type { + format!("alpha") + } else { + format!("alpha.into()") + } + } else { + if let ElemType::ExtFieldElem = elem_type { + format!("beta_challenges[{}]", idx - 1) + } else { + format!("beta_challenges[{}].into()", idx - 1) + } + } + }, } } } /// Returns a string representation of a binary operation. -fn binary_op_to_string(ir: &Air, op: &Operation) -> String { +fn binary_op_to_string(ir: &Air, elem_type: ElemType, op: &Operation) -> String { match op { Operation::Add(l_idx, r_idx) => { - let lhs = l_idx.to_string(ir); - let rhs = r_idx.to_string(ir); + let lhs = l_idx.to_string(ir, elem_type); + let rhs = r_idx.to_string(ir, elem_type); format!("{lhs} + {rhs}") }, Operation::Sub(l_idx, r_idx) => { - let lhs = l_idx.to_string(ir); + let lhs = l_idx.to_string(ir, elem_type); let rhs = if ir.constraint_graph().node(r_idx).op().precedence() <= op.precedence() { - format!("({})", r_idx.to_string(ir)) + format!("({})", r_idx.to_string(ir, elem_type)) } else { - r_idx.to_string(ir) + r_idx.to_string(ir, elem_type) }; format!("{lhs} - {rhs}") }, @@ -101,14 +141,14 @@ fn binary_op_to_string(ir: &Air, op: &Operation) -> String { let rhs_op = ir.constraint_graph().node(r_idx).op(); let lhs = if lhs_op.precedence() < op.precedence() { - format!("({})", l_idx.to_string(ir)) + format!("({})", l_idx.to_string(ir, elem_type)) } else { - l_idx.to_string(ir) + l_idx.to_string(ir, elem_type) }; let rhs = if rhs_op.precedence() < op.precedence() { - format!("({})", r_idx.to_string(ir)) + format!("({})", r_idx.to_string(ir, elem_type)) } else { - r_idx.to_string(ir) + r_idx.to_string(ir, elem_type) }; match (lhs_op, rhs_op) { @@ -120,3 +160,63 @@ fn binary_op_to_string(ir: &Air, op: &Operation) -> String { _ => panic!("unsupported operation"), } } + +/// Recursively determines if the expression depends on extension field values (i.e., aux trace, +/// random values, periodic columns, or public input tables). +pub fn needs_extension_field(ir: &Air, expr_root: NodeIndex) -> bool { + let op = ir.constraint_graph().node(&expr_root).op(); + match op { + Operation::Value(value) => match value { + Value::TraceAccess(trace_access) => trace_access.segment == TraceSegmentId::Aux, + Value::Constant(_) => false, + Value::PeriodicColumn(_) => true, + Value::PublicInput(_) => false, + Value::PublicInputTable(_) => true, + Value::RandomValue(_) => true, + }, + Operation::Add(lhs, rhs) | Operation::Sub(lhs, rhs) | Operation::Mul(lhs, rhs) => { + needs_extension_field(ir, *lhs) || needs_extension_field(ir, *rhs) + }, + } +} + +/// Returns the appropriate domain flag string for the given [ConstraintDomain]. +fn get_boundary_domain_flag_str(domain: &ConstraintDomain) -> &'static str { + match domain { + ConstraintDomain::FirstRow => ".when_first_row()", + ConstraintDomain::LastRow => ".when_last_row()", + _ => unreachable!("Invalid domain for boundary constraints"), + } +} + +/// Returns the appropriate domain flag string for the given [ConstraintDomain]. +fn get_integrity_domain_flag_str(domain: &ConstraintDomain) -> &'static str { + match domain { + ConstraintDomain::EveryFrame(_) => ".when_transition()", + ConstraintDomain::EveryRow => "", + _ => unreachable!("Invalid domain for integrity constraints"), + } +} + +pub fn constraint_to_string(ir: &Air, constraint: &ConstraintRoot, in_boundary: bool) -> String { + let expr_root = constraint.node_index(); + let needs_extension_field = needs_extension_field(ir, *expr_root); + let elem_type = if needs_extension_field { + ElemType::Ext + } else { + ElemType::Base + }; + let expr_root_string = expr_root.to_string(ir, elem_type); + + // If the constraint is a transition constraint (depends on the next row), we do not + // evaluate it in the last row, with the `when_transition` method. + let domain_flag = if in_boundary { + get_boundary_domain_flag_str(&constraint.domain()) + } else { + get_integrity_domain_flag_str(&constraint.domain()) + }; + let extension_field_flag = if needs_extension_field { "_ext" } else { "" }; + let assertion = + format!("builder{domain_flag}.assert_zero{extension_field_flag}({expr_root_string});"); + assertion +} diff --git a/codegen/plonky3/src/air/integrity_constraints.rs b/codegen/plonky3/src/air/integrity_constraints.rs index 0d79dfcf0..bdcce45e1 100644 --- a/codegen/plonky3/src/air/integrity_constraints.rs +++ b/codegen/plonky3/src/air/integrity_constraints.rs @@ -1,22 +1,24 @@ -use air_ir::{Air, ConstraintDomain, TraceSegmentId}; +use air_ir::{Air, TraceSegmentId}; use codegen::Function; -use super::Codegen; +use crate::air::graph::constraint_to_string; /// Adds the main integrity constraints to the generated code. pub(super) fn add_main_integrity_constraints(eval_func: &mut Function, ir: &Air) { + eval_func.line(""); + eval_func.line("// Main integrity/transition constraints"); for constraint in ir.integrity_constraints(TraceSegmentId::Main) { - let expr_root = constraint.node_index(); - let expr_root_string = expr_root.to_string(ir); - - // If the constraint is a transition constraint (depends on the next row), we do not - // evaluate it in the last row, with the `when_transition` method. - let assertion = if let ConstraintDomain::EveryFrame(_) = constraint.domain() { - format!("builder.when_transition().assert_zero::<_>({expr_root_string});") - } else { - format!("builder.assert_zero::<_>({expr_root_string});") - }; + let assertion = constraint_to_string(ir, constraint, false); + eval_func.line(assertion); + } +} +/// Adds the aux integrity constraints to the generated code. +pub(super) fn add_aux_integrity_constraints(eval_func: &mut Function, ir: &Air) { + eval_func.line(""); + eval_func.line("// Aux integrity/transition constraints"); + for constraint in ir.integrity_constraints(TraceSegmentId::Aux) { + let assertion = constraint_to_string(ir, constraint, false); eval_func.line(assertion); } } diff --git a/codegen/plonky3/src/air/mod.rs b/codegen/plonky3/src/air/mod.rs index a11287f87..98b881f70 100644 --- a/codegen/plonky3/src/air/mod.rs +++ b/codegen/plonky3/src/air/mod.rs @@ -1,16 +1,23 @@ mod boundary_constraints; mod graph; -use graph::Codegen; mod integrity_constraints; use air_ir::Air; use super::Scope; use crate::air::{ - boundary_constraints::add_main_boundary_constraints, - integrity_constraints::add_main_integrity_constraints, + boundary_constraints::{add_aux_boundary_constraints, add_main_boundary_constraints}, + graph::Codegen, + integrity_constraints::{add_aux_integrity_constraints, add_main_integrity_constraints}, }; +#[derive(Debug, Clone, Copy)] +pub enum ElemType { + Base, + Ext, + ExtFieldElem, +} + // HELPERS TO GENERATE AN IMPLEMENTATION OF THE PLONKY3 AIR TRAIT // ================================================================================================ @@ -19,78 +26,233 @@ use crate::air::{ pub(super) fn add_air(scope: &mut Scope, ir: &Air) { let name = ir.name(); + // add the constants needed (outside any traits for object safety). + add_constants(scope, ir); + // add the Air struct and its base implementation. add_air_struct(scope, ir, name); - // add Plonky3 AirBuilder trait implementation for the provided AirIR. - add_air_trait(scope, ir, name); + // add the aux trace generation utils if needed + if ir.num_random_values > 0 { + add_aux_trace_utils(scope, ir, name); + } } -/// Updates the provided scope with a custom Air struct. -fn add_air_struct(scope: &mut Scope, ir: &Air, name: &str) { - scope.raw(format!("pub const NUM_COLUMNS: usize = {};", ir.trace_segment_widths[0])); - +/// Updates the provided scope with constants needed for the custom Air struct and trait +/// implementations. +fn add_constants(scope: &mut Scope, ir: &Air) { + let main_width = ir.trace_segment_widths[0]; + let aux_width = ir.trace_segment_widths.get(1).cloned().unwrap_or(0); + let num_periodic_values = ir.periodic_columns().count(); + let period = ir.periodic_columns().map(|col| col.period()).max().unwrap_or(0); let num_public_values = ir.public_inputs().map(|public_input| public_input.size()).sum::(); - scope.raw(format!("pub const NUM_PUBLIC_VALUES: usize = {num_public_values};")); + let max_beta_challenge_power = ir.num_random_values.saturating_sub(1); + + let constants = [ + format!("pub const MAIN_WIDTH: usize = {main_width};"), + format!("pub const AUX_WIDTH: usize = {aux_width};"), + format!("pub const NUM_PERIODIC_VALUES: usize = {num_periodic_values};"), + format!("pub const PERIOD: usize = {period};"), + format!("pub const NUM_PUBLIC_VALUES: usize = {num_public_values};"), + format!("pub const MAX_BETA_CHALLENGE_POWER: usize = {max_beta_challenge_power};"), + ]; + scope.raw(constants.join("\n")); +} + +/// Updates the provided scope with a custom Air struct. +fn add_air_struct(scope: &mut Scope, ir: &Air, name: &str) { // define the custom Air struct. scope.new_struct(name).vis("pub"); - // add the custom BaseAir implementation block - let base_air_impl = scope.new_impl(name).generic("F").impl_trait("BaseAir"); - base_air_impl.new_fn("width").arg_ref_self().ret("usize").line("NUM_COLUMNS"); + // add the custom MidenAir implementation block + let miden_air_impl = + scope.new_impl(name).generic("F").generic("EF").impl_trait("MidenAir"); - // add the custom BaseAirWithPublicValues implementation block - let base_air_with_public_values_impl = - scope.new_impl(name).generic("F").impl_trait("BaseAirWithPublicValues"); - base_air_with_public_values_impl - .new_fn("num_public_values") - .arg_ref_self() - .ret("usize") - .line("NUM_PUBLIC_VALUES"); - - // add the custom BaseAirWithPeriodicColumns implementation block - let base_air_with_periodic_columns_impl = scope - .new_impl(name) - .generic("F: PrimeCharacteristicRing") - .impl_trait("BaseAirWithPeriodicColumns"); - let base_air_with_periodic_columns_impl_func = base_air_with_periodic_columns_impl - .new_fn("get_periodic_columns") - .arg_ref_self() - .ret("Vec>"); - base_air_with_periodic_columns_impl_func.line("vec!["); - - for col in ir.periodic_columns() { - let values_str = col.values - .iter() - .map(|v| format!("F::from_u64({v})")) // or use a custom formatter if needed - .collect::>() - .join(", "); - base_air_with_periodic_columns_impl_func.line(format!(" vec![{values_str}],")); + if ir.num_random_values > 0 || ir.periodic_columns().count() > 0 { + miden_air_impl.bound("F", "Field").bound("EF", "ExtensionField"); } - base_air_with_periodic_columns_impl_func.line("]"); -} -/// Updates the provided scope with the custom Air struct and an Air trait implementation based on -/// the provided AirIR. -fn add_air_trait(scope: &mut Scope, ir: &Air, name: &str) { - // add the implementation block for the Air trait. - let air_impl = scope - .new_impl(name) - .generic("AB: AirBuilderWithPublicValues + AirBuilderWithPeriodicColumns") - .impl_trait("Air"); + // add the width function + miden_air_impl.new_fn("width").arg_ref_self().ret("usize").line("MAIN_WIDTH"); - let eval_func = air_impl.new_fn("eval").arg_ref_self().arg("builder", "&mut AB"); - eval_func.line("let main = builder.main();"); + // add the num_public_values function if needed + if ir.periodic_columns().count() > 0 { + // add the custom BaseAirWithPublicValues implementation block + miden_air_impl + .new_fn("num_public_values") + .arg_ref_self() + .ret("usize") + .line("NUM_PUBLIC_VALUES"); + } + + // add the periodic_table function if needed + if ir.periodic_columns().count() > 0 { + let periodic_table_func = + miden_air_impl.new_fn("periodic_table").arg_ref_self().ret("Vec>"); + periodic_table_func.line("vec!["); + for col in ir.periodic_columns() { + let values_str = col.values + .iter() + .map(|v| format!("F::from_u64({v})")) // or use a custom formatter if needed + .collect::>() + .join(", "); + periodic_table_func.line(format!(" vec![{values_str}],")); + } + periodic_table_func.line("]"); + } + + // add the num_randomness and aux_width functions if needed + if ir.num_random_values > 0 { + miden_air_impl + .new_fn("num_randomness") + .arg_ref_self() + .ret("usize") + .line("1 + MAX_BETA_CHALLENGE_POWER"); + + miden_air_impl.new_fn("aux_width").arg_ref_self().ret("usize").line("AUX_WIDTH"); + } + + // add the build_aux_trace function if needed + if ir.num_random_values > 0 { + let build_aux_trace_func = miden_air_impl + .new_fn("build_aux_trace") + .arg_ref_self() + .arg("_main", "&RowMajorMatrix") + .arg("_challenges", "&[EF]") + .ret("Option>"); + build_aux_trace_func.line("// Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders."); + build_aux_trace_func.line(""); + build_aux_trace_func.line("let num_rows = _main.height();"); + build_aux_trace_func.line("let trace_length = num_rows * AUX_WIDTH;"); + build_aux_trace_func.line("let mut long_trace = EF::zero_vec(trace_length);"); + build_aux_trace_func.line("let mut trace = RowMajorMatrix::new(long_trace, AUX_WIDTH);"); + build_aux_trace_func.line("let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[EF; AUX_WIDTH]>() };"); + build_aux_trace_func.line("assert!(prefix.is_empty(), \"Alignment should match\");"); + build_aux_trace_func.line("assert!(suffix.is_empty(), \"Alignment should match\");"); + build_aux_trace_func.line("assert_eq!(rows.len(), num_rows);"); + build_aux_trace_func.line("// Initialize first row"); + build_aux_trace_func.line("let initial_values = Self::buses_initial_values::();"); + build_aux_trace_func.line("for j in 0..AUX_WIDTH {"); + build_aux_trace_func.line(" rows[0][j] = initial_values[j];"); + build_aux_trace_func.line("}"); + build_aux_trace_func.line("// Fill subsequent rows using direct access to the rows array"); + build_aux_trace_func.line("for i in 0..num_rows-1 {"); + build_aux_trace_func.line(" let i_next = (i + 1) % num_rows;"); + build_aux_trace_func.line(" let main_local = _main.row_slice(i).unwrap(); // i < height so unwrap should never fail."); + build_aux_trace_func.line(" let main_next = _main.row_slice(i_next).unwrap(); // i_next < height so unwrap should never fail."); + build_aux_trace_func.line(" let main = VerticalPair::new("); + build_aux_trace_func.line(" RowMajorMatrixView::new_row(&*main_local),"); + build_aux_trace_func.line(" RowMajorMatrixView::new_row(&*main_next),"); + build_aux_trace_func.line(" );"); + build_aux_trace_func.line(format!(" let periodic_values: [_; NUM_PERIODIC_VALUES] = <{name} as MidenAir>::periodic_table(self).iter().map(|col| col[i % col.len()]).collect::>().try_into().expect(\"Wrong number of periodic values\");")); + build_aux_trace_func.line(" let prev_row = &rows[i];"); + build_aux_trace_func.line(" let next_row = Self::buses_transitions::("); + build_aux_trace_func.line(" &main,"); + build_aux_trace_func.line(" _challenges,"); + build_aux_trace_func.line(" &periodic_values,"); + build_aux_trace_func.line(" prev_row,"); + build_aux_trace_func.line(" );"); + build_aux_trace_func.line(" for j in 0..AUX_WIDTH {"); + build_aux_trace_func.line(" rows[i+1][j] = next_row[j];"); + build_aux_trace_func.line(" }"); + build_aux_trace_func.line("}"); + build_aux_trace_func.line("Some(trace)"); + } + + // add the eval function + let eval_func = miden_air_impl + .new_fn("eval") + .generic("AB") + .bound("AB", "MidenAirBuilder") + .arg_ref_self() + .arg("builder", "&mut AB"); eval_func.line("let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect(\"Wrong number of public values\");"); - eval_func.line("let periodic_values = builder.periodic_columns();"); + eval_func.line("let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect(\"Wrong number of periodic values\");"); + eval_func.line("let preprocessed = builder.preprocessed();"); + + eval_func.line("let main = builder.main();"); eval_func.line("let (main_current, main_next) = ("); eval_func.line(" main.row_slice(0).unwrap(),"); eval_func.line(" main.row_slice(1).unwrap(),"); eval_func.line(");"); + // Only add aux if there are random values + if ir.num_random_values > 0 { + eval_func.line("let (&alpha, beta_challenges) = builder.permutation_randomness().split_first().expect(\"Wrong number of randomness\");"); + eval_func.line("let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect(\"Wrong number of randomness\");"); + eval_func.line("let aux_bus_boundary_values: [_; AUX_WIDTH] = builder.aux_bus_boundary_values().try_into().expect(\"Wrong number of aux bus boundary values\");"); + eval_func.line("let aux = builder.permutation();"); + eval_func.line("let (aux_current, aux_next) = ("); + eval_func.line(" aux.row_slice(0).unwrap(),"); + eval_func.line(" aux.row_slice(1).unwrap(),"); + eval_func.line(");"); + } + add_main_boundary_constraints(eval_func, ir); add_main_integrity_constraints(eval_func, ir); + + add_aux_boundary_constraints(eval_func, ir); + + add_aux_integrity_constraints(eval_func, ir); +} + +/// Updates the provided scope with aux trace generation utilities. +fn add_aux_trace_utils(scope: &mut Scope, ir: &Air, name: &str) { + let aux_generation_impl = scope.new_impl(name); + + // add the bus_initial_values function + let buses_initial_values_func = aux_generation_impl + .new_fn("buses_initial_values") + .generic("F") + .generic("EF") + .bound("F", "Field") + .bound("EF", "ExtensionField") + .ret("Vec"); + buses_initial_values_func.line("vec!["); + for (_bus_id, value) in ir.buses_initial_values.iter() { + let value_str = value.to_string(ir, ElemType::ExtFieldElem); + + buses_initial_values_func.line(format!(" {},", value_str)); + } + buses_initial_values_func.line("]"); + + // add the bus_transitions function + let buses_transitions_func = aux_generation_impl + .new_fn("buses_transitions") + .generic("F") + .generic("EF") + .bound("F", "Field") + .bound("EF", "ExtensionField") + .arg("main", "&VerticalPair, RowMajorMatrixView>") + .arg("challenges", "&[EF]") + .arg("periodic_evals", "&[F]") + .arg("aux_current", "&[EF]") + .ret("Vec"); + + buses_transitions_func.line("let (main_current, main_next) = ("); + buses_transitions_func.line(" main.row_slice(0).unwrap(),"); + buses_transitions_func.line(" main.row_slice(1).unwrap(),"); + buses_transitions_func.line(");"); + buses_transitions_func.line("let (&alpha, beta_challenges) = challenges.split_first().expect(\"Wrong number of randomness\");"); + buses_transitions_func.line("let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect(\"Wrong number of randomness\");"); + + buses_transitions_func.line("let periodic_values: [_; NUM_PERIODIC_VALUES] = periodic_evals.try_into().expect(\"Wrong number of periodic values\");"); + + buses_transitions_func.line("vec!["); + for (_bus_id, (numerator, denominator)) in ir.buses_transitions.iter() { + let numerator_str = numerator.to_string(ir, ElemType::ExtFieldElem); + + let aux_next_value_str = if let Some(denom) = denominator { + let denominator_str = denom.to_string(ir, ElemType::ExtFieldElem); + format!("({}) * ({}).inverse()", numerator_str, denominator_str) + } else { + numerator_str + }; + + buses_transitions_func.line(format!(" {},", aux_next_value_str)); + } + buses_transitions_func.line("]"); } diff --git a/codegen/plonky3/src/imports.rs b/codegen/plonky3/src/imports.rs index 28ef3501b..8655c7161 100644 --- a/codegen/plonky3/src/imports.rs +++ b/codegen/plonky3/src/imports.rs @@ -3,13 +3,13 @@ use super::Scope; /// Adds the required imports to the provided scope. pub(super) fn add_imports(scope: &mut Scope) { // add plonky3 imports - scope.import("p3_air", "Air"); - scope.import("p3_air", "AirBuilder"); - scope.import("p3_air", "AirBuilderWithPublicValues"); - scope.import("p3_air", "BaseAir"); - scope.import("p3_air", "BaseAirWithPublicValues"); - scope.import("p3_matrix", "Matrix"); + scope.import("p3_field", "ExtensionField"); + scope.import("p3_field", "Field"); scope.import("p3_field", "PrimeCharacteristicRing"); - scope.import("crate::helpers", "AirBuilderWithPeriodicColumns"); - scope.import("crate::helpers", "BaseAirWithPeriodicColumns"); + scope.import("p3_matrix", "Matrix"); + scope.import("p3_matrix::dense", "RowMajorMatrixView"); + scope.import("p3_matrix::stack", "VerticalPair"); + scope.import("p3_miden_air", "MidenAir"); + scope.import("p3_miden_air", "MidenAirBuilder"); + scope.import("p3_miden_air", "RowMajorMatrix"); } diff --git a/scripts/generate_all_e2e_tests.sh b/scripts/generate_all_e2e_tests.sh new file mode 100644 index 000000000..b0808b9ec --- /dev/null +++ b/scripts/generate_all_e2e_tests.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +# Notes: +# - Run from root of repository +# - We avoid looping on all found air-script/src/tests/**/*.air files to make it easier to notice changes + +cargo build --release + +# Winterfell Backend + +./target/release/airc transpile --target winterfell ./air-script/src/tests/binary/binary.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/bitwise/bitwise.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/buses/buses_complex.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/buses/buses_simple.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/buses/buses_simple_with_evaluators.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/buses/buses_varlen_boundary_both.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/buses/buses_varlen_boundary_last.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/buses/buses_varlen_boundary_first.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/constant_in_range/constant_in_range.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/constants/constants.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/constraint_comprehension/constraint_comprehension.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/evaluators/evaluators.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/fibonacci/fibonacci.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/functions/functions_simple.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/functions/functions_complex.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/indexed_trace_access/indexed_trace_access.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/list_comprehension/list_comprehension_nested.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/list_comprehension/list_comprehension.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/list_folding/list_folding.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/periodic_columns/periodic_columns.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/pub_inputs/pub_inputs.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/selectors/selectors_combine_complex.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/selectors/selectors_combine_simple.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/selectors/selectors_combine_with_list_comprehensions.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/selectors/selectors_with_evaluators.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/selectors/selectors.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/system/system.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/trace_col_groups/trace_col_groups.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/variables/variables.air + +# Plonky3 Backend +./target/release/airc transpile --target plonky3 ./air-script/src/tests/binary/binary.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/bitwise/bitwise.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/buses/buses_complex.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/buses/buses_simple.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/buses/buses_simple_with_evaluators.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/buses/buses_varlen_boundary_both.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/buses/buses_varlen_boundary_last.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/buses/buses_varlen_boundary_first.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/computed_indices/computed_indices_complex.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/computed_indices/computed_indices_simple.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/constant_in_range/constant_in_range.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/constants/constants.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/constraint_comprehension/constraint_comprehension.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/evaluators/evaluators.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/fibonacci/fibonacci.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/functions/functions_simple.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/functions/functions_complex.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/indexed_trace_access/indexed_trace_access.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/list_comprehension/list_comprehension_nested.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/list_comprehension/list_comprehension.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/list_folding/list_folding.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/periodic_columns/periodic_columns.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/pub_inputs/pub_inputs.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/selectors/selectors_combine_complex.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/selectors/selectors_combine_simple.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/selectors/selectors_combine_with_list_comprehensions.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/selectors/selectors_with_evaluators.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/selectors/selectors.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/system/system.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/trace_col_groups/trace_col_groups.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/variables/variables.air From 805649ff66baa182138807d4c4acab8297535edf Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Mon, 8 Dec 2025 07:58:32 +0100 Subject: [PATCH 22/25] tests: update tests after merge, add plonky3 E2E tests codegen and update script --- .../evaluators_nested_slice_call_plonky3.rs | 66 +++++++++++++++++++ .../evaluators/evaluators_slice_plonky3.rs | 66 +++++++++++++++++++ air-script/src/tests/plonky3.rs | 32 +++++++++ air-script/src/tests/winterfell.rs | 32 +++++++++ scripts/generate_all_e2e_tests.sh | 4 ++ 5 files changed, 200 insertions(+) create mode 100644 air-script/src/tests/evaluators/evaluators_nested_slice_call_plonky3.rs create mode 100644 air-script/src/tests/evaluators/evaluators_slice_plonky3.rs diff --git a/air-script/src/tests/evaluators/evaluators_nested_slice_call_plonky3.rs b/air-script/src/tests/evaluators/evaluators_nested_slice_call_plonky3.rs new file mode 100644 index 000000000..8dfd1d4bf --- /dev/null +++ b/air-script/src/tests/evaluators/evaluators_nested_slice_call_plonky3.rs @@ -0,0 +1,66 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 20; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct EvaluatorsSliceAir; + +impl MidenAir for EvaluatorsSliceAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into()); + builder.when_first_row().assert_zero(main_current[1].clone().into()); + builder.when_first_row().assert_zero(main_current[2].clone().into()); + builder.when_first_row().assert_zero(main_current[3].clone().into()); + builder.when_first_row().assert_zero(main_current[4].clone().into()); + builder.when_first_row().assert_zero(main_current[5].clone().into()); + builder.when_first_row().assert_zero(main_current[6].clone().into()); + builder.when_first_row().assert_zero(main_current[7].clone().into()); + builder.when_first_row().assert_zero(main_current[8].clone().into()); + builder.when_first_row().assert_zero(main_current[9].clone().into()); + builder.when_first_row().assert_zero(main_current[10].clone().into()); + builder.when_first_row().assert_zero(main_current[11].clone().into()); + builder.when_first_row().assert_zero(main_current[12].clone().into()); + builder.when_first_row().assert_zero(main_current[13].clone().into()); + builder.when_first_row().assert_zero(main_current[14].clone().into()); + builder.when_first_row().assert_zero(main_current[15].clone().into()); + builder.when_first_row().assert_zero(main_current[16].clone().into()); + builder.when_first_row().assert_zero(main_current[17].clone().into()); + builder.when_first_row().assert_zero(main_current[18].clone().into()); + builder.when_first_row().assert_zero(main_current[19].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero(main_current[5].clone().into() * main_current[5].clone().into() - main_current[5].clone().into()); + builder.assert_zero(main_current[5].clone().into() * (main_current[6].clone().into() * main_current[6].clone().into() - main_current[6].clone().into())); + builder.assert_zero(main_current[5].clone().into() * main_current[6].clone().into() * (main_current[7].clone().into() * main_current[7].clone().into() - main_current[7].clone().into())); + builder.assert_zero(main_current[5].clone().into() * main_current[6].clone().into() * main_current[7].clone().into() * (main_current[8].clone().into() * main_current[8].clone().into() - main_current[8].clone().into())); + builder.assert_zero(main_current[5].clone().into() * main_current[6].clone().into() * main_current[7].clone().into() * main_current[8].clone().into() * (main_current[9].clone().into() * main_current[9].clone().into() - main_current[9].clone().into())); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/src/tests/evaluators/evaluators_slice_plonky3.rs b/air-script/src/tests/evaluators/evaluators_slice_plonky3.rs new file mode 100644 index 000000000..62f822ede --- /dev/null +++ b/air-script/src/tests/evaluators/evaluators_slice_plonky3.rs @@ -0,0 +1,66 @@ +use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; +use p3_matrix::Matrix; +use p3_matrix::dense::RowMajorMatrixView; +use p3_matrix::stack::VerticalPair; +use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; + +pub const MAIN_WIDTH: usize = 20; +pub const AUX_WIDTH: usize = 0; +pub const NUM_PERIODIC_VALUES: usize = 0; +pub const PERIOD: usize = 0; +pub const NUM_PUBLIC_VALUES: usize = 16; +pub const MAX_BETA_CHALLENGE_POWER: usize = 0; + +pub struct EvaluatorsSliceAir; + +impl MidenAir for EvaluatorsSliceAir { + fn width(&self) -> usize { + MAIN_WIDTH + } + + fn eval(&self, builder: &mut AB) + where AB: MidenAirBuilder, + { + let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); + let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); + let preprocessed = builder.preprocessed(); + let main = builder.main(); + let (main_current, main_next) = ( + main.row_slice(0).unwrap(), + main.row_slice(1).unwrap(), + ); + + // Main boundary constraints + builder.when_first_row().assert_zero(main_current[0].clone().into()); + builder.when_first_row().assert_zero(main_current[1].clone().into()); + builder.when_first_row().assert_zero(main_current[2].clone().into()); + builder.when_first_row().assert_zero(main_current[3].clone().into()); + builder.when_first_row().assert_zero(main_current[4].clone().into()); + builder.when_first_row().assert_zero(main_current[5].clone().into()); + builder.when_first_row().assert_zero(main_current[6].clone().into()); + builder.when_first_row().assert_zero(main_current[7].clone().into()); + builder.when_first_row().assert_zero(main_current[8].clone().into()); + builder.when_first_row().assert_zero(main_current[9].clone().into()); + builder.when_first_row().assert_zero(main_current[10].clone().into()); + builder.when_first_row().assert_zero(main_current[11].clone().into()); + builder.when_first_row().assert_zero(main_current[12].clone().into()); + builder.when_first_row().assert_zero(main_current[13].clone().into()); + builder.when_first_row().assert_zero(main_current[14].clone().into()); + builder.when_first_row().assert_zero(main_current[15].clone().into()); + builder.when_first_row().assert_zero(main_current[16].clone().into()); + builder.when_first_row().assert_zero(main_current[17].clone().into()); + builder.when_first_row().assert_zero(main_current[18].clone().into()); + builder.when_first_row().assert_zero(main_current[19].clone().into()); + + // Main integrity/transition constraints + builder.assert_zero(main_current[0].clone().into() * main_current[0].clone().into() - main_current[0].clone().into()); + builder.assert_zero(main_current[0].clone().into() * (main_current[1].clone().into() * main_current[1].clone().into() - main_current[1].clone().into())); + builder.assert_zero(main_current[0].clone().into() * main_current[1].clone().into() * (main_current[2].clone().into() * main_current[2].clone().into() - main_current[2].clone().into())); + builder.assert_zero(main_current[0].clone().into() * main_current[1].clone().into() * main_current[2].clone().into() * (main_current[3].clone().into() * main_current[3].clone().into() - main_current[3].clone().into())); + builder.assert_zero(main_current[0].clone().into() * main_current[1].clone().into() * main_current[2].clone().into() * main_current[3].clone().into() * (main_current[4].clone().into() * main_current[4].clone().into() - main_current[4].clone().into())); + + // Aux boundary constraints + + // Aux integrity/transition constraints + } +} \ No newline at end of file diff --git a/air-script/src/tests/plonky3.rs b/air-script/src/tests/plonky3.rs index e599d2189..03fb55e84 100644 --- a/air-script/src/tests/plonky3.rs +++ b/air-script/src/tests/plonky3.rs @@ -123,6 +123,38 @@ fn constants() { expected.assert_eq(&generated_air); } +#[test] +fn evaluators_nested_slice_call() { + let generated_air = Test::new("src/tests/evaluators/evaluators_nested_slice_call.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["evaluators/evaluators_nested_slice_call_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + +// TODO: add support for nested slicing in general expressions. +// +// #[test] +// fn evaluators_slice_slicing() { +// let generated_air = Test::new("src/tests/evaluators/evaluators_slice_slicing.air".to_string()) +// .transpile(Target::Plonky3) +// .unwrap(); +// +// let expected = expect_file!["evaluators/evaluators_slice_slicing_plonky3.rs"]; +// expected.assert_eq(&generated_air); +// } + +#[test] +fn evaluators_slice() { + let generated_air = Test::new("src/tests/evaluators/evaluators_slice.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); + + let expected = expect_file!["evaluators/evaluators_slice_plonky3.rs"]; + expected.assert_eq(&generated_air); +} + #[test] fn evaluators() { let generated_air = Test::new("src/tests/evaluators/evaluators.air".to_string()) diff --git a/air-script/src/tests/winterfell.rs b/air-script/src/tests/winterfell.rs index 2b2683cb6..6a44ea7c8 100644 --- a/air-script/src/tests/winterfell.rs +++ b/air-script/src/tests/winterfell.rs @@ -143,6 +143,38 @@ fn constraint_comprehension() { expected.assert_eq(&generated_air); } +#[test] +fn evaluators_nested_slice_call() { + let generated_air = Test::new("src/tests/evaluators/evaluators_nested_slice_call.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["evaluators/evaluators_nested_slice_call.rs"]; + expected.assert_eq(&generated_air); +} + +// TODO: add support for nested slicing in general expressions. +// +// #[test] +// fn evaluators_slice_slicing() { +// let generated_air = Test::new("src/tests/evaluators/evaluators_slice_slicing.air".to_string()) +// .transpile(Target::Winterfell) +// .unwrap(); +// +// let expected = expect_file!["evaluators/evaluators_slice_slicing.rs"]; +// expected.assert_eq(&generated_air); +// } + +#[test] +fn evaluators_slice() { + let generated_air = Test::new("src/tests/evaluators/evaluators_slice.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); + + let expected = expect_file!["evaluators/evaluators_slice.rs"]; + expected.assert_eq(&generated_air); +} + #[test] fn evaluators() { let generated_air = Test::new("src/tests/evaluators/evaluators.air".to_string()) diff --git a/scripts/generate_all_e2e_tests.sh b/scripts/generate_all_e2e_tests.sh index b0808b9ec..9725910d1 100644 --- a/scripts/generate_all_e2e_tests.sh +++ b/scripts/generate_all_e2e_tests.sh @@ -19,6 +19,8 @@ cargo build --release ./target/release/airc transpile --target winterfell ./air-script/src/tests/constant_in_range/constant_in_range.air ./target/release/airc transpile --target winterfell ./air-script/src/tests/constants/constants.air ./target/release/airc transpile --target winterfell ./air-script/src/tests/constraint_comprehension/constraint_comprehension.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/evaluators/evaluators_nested_slice_call.air +./target/release/airc transpile --target winterfell ./air-script/src/tests/evaluators/evaluators_slice.air ./target/release/airc transpile --target winterfell ./air-script/src/tests/evaluators/evaluators.air ./target/release/airc transpile --target winterfell ./air-script/src/tests/fibonacci/fibonacci.air ./target/release/airc transpile --target winterfell ./air-script/src/tests/functions/functions_simple.air @@ -52,6 +54,8 @@ cargo build --release ./target/release/airc transpile --target plonky3 ./air-script/src/tests/constant_in_range/constant_in_range.air ./target/release/airc transpile --target plonky3 ./air-script/src/tests/constants/constants.air ./target/release/airc transpile --target plonky3 ./air-script/src/tests/constraint_comprehension/constraint_comprehension.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/evaluators/evaluators_nested_slice_call.air +./target/release/airc transpile --target plonky3 ./air-script/src/tests/evaluators/evaluators_slice.air ./target/release/airc transpile --target plonky3 ./air-script/src/tests/evaluators/evaluators.air ./target/release/airc transpile --target plonky3 ./air-script/src/tests/fibonacci/fibonacci.air ./target/release/airc transpile --target plonky3 ./air-script/src/tests/functions/functions_simple.air From 13d2ae0ccb1af7ca24d8633b6404fb2a6fa0d7c3 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Mon, 8 Dec 2025 08:09:05 +0100 Subject: [PATCH 23/25] fix: cargo fmt --- air-script/src/tests/plonky3.rs | 10 ++++++---- air-script/src/tests/winterfell.rs | 10 ++++++---- parser/src/ast/mod.rs | 25 ++++++++++++------------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/air-script/src/tests/plonky3.rs b/air-script/src/tests/plonky3.rs index 03fb55e84..baf9c3453 100644 --- a/air-script/src/tests/plonky3.rs +++ b/air-script/src/tests/plonky3.rs @@ -125,9 +125,10 @@ fn constants() { #[test] fn evaluators_nested_slice_call() { - let generated_air = Test::new("src/tests/evaluators/evaluators_nested_slice_call.air".to_string()) - .transpile(Target::Plonky3) - .unwrap(); + let generated_air = + Test::new("src/tests/evaluators/evaluators_nested_slice_call.air".to_string()) + .transpile(Target::Plonky3) + .unwrap(); let expected = expect_file!["evaluators/evaluators_nested_slice_call_plonky3.rs"]; expected.assert_eq(&generated_air); @@ -137,7 +138,8 @@ fn evaluators_nested_slice_call() { // // #[test] // fn evaluators_slice_slicing() { -// let generated_air = Test::new("src/tests/evaluators/evaluators_slice_slicing.air".to_string()) +// let generated_air = +// Test::new("src/tests/evaluators/evaluators_slice_slicing.air".to_string()) // .transpile(Target::Plonky3) // .unwrap(); // diff --git a/air-script/src/tests/winterfell.rs b/air-script/src/tests/winterfell.rs index 6a44ea7c8..5e9f044df 100644 --- a/air-script/src/tests/winterfell.rs +++ b/air-script/src/tests/winterfell.rs @@ -145,9 +145,10 @@ fn constraint_comprehension() { #[test] fn evaluators_nested_slice_call() { - let generated_air = Test::new("src/tests/evaluators/evaluators_nested_slice_call.air".to_string()) - .transpile(Target::Winterfell) - .unwrap(); + let generated_air = + Test::new("src/tests/evaluators/evaluators_nested_slice_call.air".to_string()) + .transpile(Target::Winterfell) + .unwrap(); let expected = expect_file!["evaluators/evaluators_nested_slice_call.rs"]; expected.assert_eq(&generated_air); @@ -157,7 +158,8 @@ fn evaluators_nested_slice_call() { // // #[test] // fn evaluators_slice_slicing() { -// let generated_air = Test::new("src/tests/evaluators/evaluators_slice_slicing.air".to_string()) +// let generated_air = +// Test::new("src/tests/evaluators/evaluators_slice_slicing.air".to_string()) // .transpile(Target::Winterfell) // .unwrap(); // diff --git a/parser/src/ast/mod.rs b/parser/src/ast/mod.rs index 1686455e7..1447c7b3c 100644 --- a/parser/src/ast/mod.rs +++ b/parser/src/ast/mod.rs @@ -508,19 +508,18 @@ impl Library { // importing module, if it was parsed from disk. If no path is available, // we default to the current working directory. - let (real_path, source_dir) = match codemap - .name(imports.first().unwrap().span().source_id()) - { - // If we have no source span, default to the current working directory - Err(_) => (false, cwd.clone()), - // If the file is virtual, then we've either already parsed imports for this module, - // or we have to fall back to the current working directory, but we have no relative - // path from which to base our search. - Ok(FileName::Virtual(_)) => (false, cwd.clone()), - Ok(FileName::Real(path)) => { - (true, path.parent().unwrap_or_else(|| Path::new(".")).to_path_buf()) - }, - }; + let (real_path, source_dir) = + match codemap.name(imports.first().unwrap().span().source_id()) { + // If we have no source span, default to the current working directory + Err(_) => (false, cwd.clone()), + // If the file is virtual, then we've either already parsed imports for this module, + // or we have to fall back to the current working directory, but we have no relative + // path from which to base our search. + Ok(FileName::Virtual(_)) => (false, cwd.clone()), + Ok(FileName::Real(path)) => { + (true, path.parent().unwrap_or_else(|| Path::new(".")).to_path_buf()) + }, + }; // For each module imported, try to load the module from the library, if it is // unavailable we must do extra work to load it into the library, as From b72ead4dd3fbfd8f1e8a7de82b3e86e3a8d82e6d Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Mon, 8 Dec 2025 08:18:29 +0100 Subject: [PATCH 24/25] fix: prev cargo fmt failed --- parser/src/ast/mod.rs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/parser/src/ast/mod.rs b/parser/src/ast/mod.rs index 1447c7b3c..1686455e7 100644 --- a/parser/src/ast/mod.rs +++ b/parser/src/ast/mod.rs @@ -508,18 +508,19 @@ impl Library { // importing module, if it was parsed from disk. If no path is available, // we default to the current working directory. - let (real_path, source_dir) = - match codemap.name(imports.first().unwrap().span().source_id()) { - // If we have no source span, default to the current working directory - Err(_) => (false, cwd.clone()), - // If the file is virtual, then we've either already parsed imports for this module, - // or we have to fall back to the current working directory, but we have no relative - // path from which to base our search. - Ok(FileName::Virtual(_)) => (false, cwd.clone()), - Ok(FileName::Real(path)) => { - (true, path.parent().unwrap_or_else(|| Path::new(".")).to_path_buf()) - }, - }; + let (real_path, source_dir) = match codemap + .name(imports.first().unwrap().span().source_id()) + { + // If we have no source span, default to the current working directory + Err(_) => (false, cwd.clone()), + // If the file is virtual, then we've either already parsed imports for this module, + // or we have to fall back to the current working directory, but we have no relative + // path from which to base our search. + Ok(FileName::Virtual(_)) => (false, cwd.clone()), + Ok(FileName::Real(path)) => { + (true, path.parent().unwrap_or_else(|| Path::new(".")).to_path_buf()) + }, + }; // For each module imported, try to load the module from the library, if it is // unavailable we must do extra work to load it into the library, as From f4f6c8621a47b93323fc91c9073abc0337613ea3 Mon Sep 17 00:00:00 2001 From: Leo-Besancon Date: Wed, 17 Dec 2025 17:58:24 +0100 Subject: [PATCH 25/25] feat: prove/verify and sync plonky3 (#523) --- CHANGELOG.md | 1 + air-script/Cargo.toml | 34 ++-- air-script/src/lib.rs | 3 + .../miden_vm_aux_trace_generator.rs | 5 +- .../src/test_utils/air_tester_macros.rs | 30 ++- air-script/src/test_utils/mod.rs | 6 +- air-script/src/test_utils/plonky3_traits.rs | 189 ------------------ .../test_utils/pub_inputs_conversion_utils.rs | 46 +++++ air-script/src/tests/binary/binary_plonky3.rs | 9 +- .../src/tests/binary/test_air_plonky3.rs | 11 +- .../src/tests/bitwise/bitwise_plonky3.rs | 9 +- .../src/tests/bitwise/test_air_plonky3.rs | 11 +- .../src/tests/buses/buses_complex_plonky3.rs | 25 ++- .../src/tests/buses/buses_simple_plonky3.rs | 24 ++- .../buses_varlen_boundary_both_plonky3.rs | 26 ++- .../buses_varlen_boundary_first_plonky3.rs | 27 +-- .../buses/buses_varlen_boundary_last.air | 19 +- .../tests/buses/buses_varlen_boundary_last.rs | 32 +-- .../buses_varlen_boundary_last_plonky3.rs | 37 ++-- air-script/src/tests/buses/mod.rs | 1 + .../src/tests/buses/test_air_plonky3.rs | 11 +- .../test_air_plonky3_varlen_boundary_last.rs | 64 ++++++ .../computed_indices_complex_plonky3.rs | 9 +- .../computed_indices_simple_plonky3.rs | 9 +- .../computed_indices/test_air_plonky3.rs | 11 +- .../constant_in_range_plonky3.rs | 9 +- .../constant_in_range/test_air_plonky3.rs | 11 +- .../src/tests/constants/constants_plonky3.rs | 9 +- .../src/tests/constants/test_air_plonky3.rs | 11 +- .../constraint_comprehension_plonky3.rs | 9 +- .../test_air_plonky3.rs | 11 +- .../evaluators_nested_slice_call_plonky3.rs | 9 +- .../tests/evaluators/evaluators_plonky3.rs | 9 +- .../evaluators/evaluators_slice_plonky3.rs | 9 +- .../src/tests/evaluators/test_air_plonky3.rs | 11 +- .../src/tests/fibonacci/fibonacci_plonky3.rs | 9 +- .../src/tests/fibonacci/test_air_plonky3.rs | 45 ++++- .../src/tests/functions/functions_complex.air | 2 +- .../src/tests/functions/functions_complex.rs | 4 +- .../functions/functions_complex_plonky3.rs | 11 +- .../functions/functions_simple_plonky3.rs | 9 +- .../src/tests/functions/test_air_plonky3.rs | 11 +- .../indexed_trace_access_plonky3.rs | 9 +- .../indexed_trace_access/test_air_plonky3.rs | 11 +- .../list_comprehension_nested_plonky3.rs | 9 +- .../list_comprehension_plonky3.rs | 9 +- .../list_comprehension/test_air_plonky3.rs | 11 +- .../list_folding/list_folding_plonky3.rs | 9 +- .../tests/list_folding/test_air_plonky3.rs | 11 +- .../periodic_columns_plonky3.rs | 9 +- .../periodic_columns/test_air_plonky3.rs | 11 +- .../tests/pub_inputs/pub_inputs_plonky3.rs | 9 +- .../src/tests/pub_inputs/test_air_plonky3.rs | 11 +- .../selectors_combine_complex_plonky3.rs | 22 +- .../selectors_combine_simple_plonky3.rs | 9 +- ...ombine_with_list_comprehensions_plonky3.rs | 9 +- .../src/tests/selectors/selectors_plonky3.rs | 9 +- .../selectors_with_evaluators_plonky3.rs | 9 +- .../src/tests/selectors/test_air_plonky3.rs | 11 +- air-script/src/tests/system/system_plonky3.rs | 9 +- .../src/tests/system/test_air_plonky3.rs | 11 +- .../trace_col_groups/test_air_plonky3.rs | 11 +- .../trace_col_groups_plonky3.rs | 9 +- .../src/tests/variables/test_air_plonky3.rs | 11 +- .../src/tests/variables/variables_plonky3.rs | 9 +- .../plonky3/src/air/boundary_constraints.rs | 1 + codegen/plonky3/src/air/mod.rs | 36 +++- codegen/plonky3/src/imports.rs | 1 + parser/src/ast/module.rs | 3 - 69 files changed, 581 insertions(+), 536 deletions(-) rename air-script/src/{test_utils => }/miden_vm_aux_trace_generator.rs (97%) delete mode 100644 air-script/src/test_utils/plonky3_traits.rs create mode 100644 air-script/src/test_utils/pub_inputs_conversion_utils.rs create mode 100644 air-script/src/tests/buses/test_air_plonky3_varlen_boundary_last.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index cf20d327a..19549d087 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - Support importing hierarchical modules (#507). - In Plonky3 codegen, use AirScriptAir and AirScriptBuilder traits, and generate aux constraints (#508). - In Plonky3 codegen, use MidenAir and MidenAirBuilder from 0xMiden's Plonky3 fork instead of AirScriptAir and AirScriptBuilder (#515). +- In Plonky3 codegen, use prove/verify workflow for tests (#523). ## 0.4.0 (2025-06-20) diff --git a/air-script/Cargo.toml b/air-script/Cargo.toml index 65813db4e..ed1709f76 100644 --- a/air-script/Cargo.toml +++ b/air-script/Cargo.toml @@ -28,28 +28,30 @@ log = { version = "0.4", default-features = false } miden-diagnostics = { workspace = true } mir = { package = "air-mir", path = "../mir", version = "0.5" } -[dev-dependencies] -expect-test = "1.4" - # 0xMiden Plonky3 Fork -p3-air = { package = "p3-air", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } -p3-challenger = { package = "p3-challenger", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } -p3-commit = { package = "p3-commit", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } -p3-dft = { package = "p3-dft", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } -p3-field = { package = "p3-field", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } -p3-fri = { package = "p3-fri", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } -p3-matrix = { package = "p3-matrix", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } -p3-merkle-tree = { package = "p3-merkle-tree", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } -p3-miden-air = { package = "miden-air", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } -p3-goldilocks = { package = "p3-goldilocks", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } -p3-sha256 = { package = "p3-sha256", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } -p3-symmetric = { package = "p3-symmetric", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } -p3-uni-stark = { package = "p3-uni-stark", git="https://github.com/0xMiden/Plonky3", rev = "5352d47ee57bd1b5d6008a90b64cbb7fe00aa17e", default-features = false } +p3-matrix = { package = "p3-matrix", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } +p3-field = { package = "p3-field", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } +p3-miden-air = { package = "miden-air", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } # MassaLabs fork miden-processor = { package = "miden-processor", git="https://github.com/massalabs/miden-vm", rev = "bc553af69a2543a0789830e8508b019694528181", default-features = false } miden-air = { package = "miden-air", git="https://github.com/massalabs/miden-vm", rev = "bc553af69a2543a0789830e8508b019694528181", default-features = false } +[dev-dependencies] +expect-test = "1.4" + +# 0xMiden Plonky3 Fork +p3-air = { package = "p3-air", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } +p3-challenger = { package = "p3-challenger", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } +p3-commit = { package = "p3-commit", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } +p3-dft = { package = "p3-dft", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } +p3-fri = { package = "p3-fri", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } +p3-merkle-tree = { package = "p3-merkle-tree", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } +p3-miden-prover = { package = "miden-prover", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } +p3-goldilocks = { package = "p3-goldilocks", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } +p3-sha256 = { package = "p3-sha256", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } +p3-symmetric = { package = "p3-symmetric", git="https://github.com/0xMiden/Plonky3", rev = "632fb26a9141cc70f903e5378035ca8d5855c490", default-features = false } + winter-air = { package = "winter-air", version = "0.12", default-features = false } winter-math = { package = "winter-math", version = "0.12", default-features = false } winter-utils = { package = "winter-utils", version = "0.12", default-features = false } diff --git a/air-script/src/lib.rs b/air-script/src/lib.rs index 67c255f21..d75247b94 100644 --- a/air-script/src/lib.rs +++ b/air-script/src/lib.rs @@ -2,6 +2,9 @@ pub use air_codegen_winter::CodeGenerator as WinterfellCodeGenerator; pub use air_ir::{Air, CompileError, compile}; pub use air_parser::{parse, parse_file, transforms}; +/// Miden VM auxiliary trace generator +pub mod miden_vm_aux_trace_generator; + #[cfg(test)] pub mod test_utils; #[cfg(test)] diff --git a/air-script/src/test_utils/miden_vm_aux_trace_generator.rs b/air-script/src/miden_vm_aux_trace_generator.rs similarity index 97% rename from air-script/src/test_utils/miden_vm_aux_trace_generator.rs rename to air-script/src/miden_vm_aux_trace_generator.rs index a6f9517c1..e233a970a 100644 --- a/air-script/src/test_utils/miden_vm_aux_trace_generator.rs +++ b/air-script/src/miden_vm_aux_trace_generator.rs @@ -59,7 +59,7 @@ pub fn build_aux_trace_with_miden_vm( main: &RowMajorMatrix, challenges: &[EF], module: MidenModule, -) -> RowMajorMatrix +) -> RowMajorMatrix where F: Field + PrimeField64, EF: ExtensionField, @@ -112,5 +112,6 @@ where } } - aux_trace + let aux_trace_f = aux_trace.flatten_to_base(); + aux_trace_f } diff --git a/air-script/src/test_utils/air_tester_macros.rs b/air-script/src/test_utils/air_tester_macros.rs index 53a64784e..7c5e305ee 100644 --- a/air-script/src/test_utils/air_tester_macros.rs +++ b/air-script/src/test_utils/air_tester_macros.rs @@ -53,7 +53,7 @@ macro_rules! generate_air_plonky3_test_with_airscript_traits { >; type Dft = p3_dft::Radix2DitParallel; type Pcs = p3_fri::TwoAdicFriPcs; - type MyConfig = p3_uni_stark::StarkConfig; + type MyConfig = p3_miden_prover::StarkConfig; let byte_hash = ByteHash {}; let field_hash = FieldHash::new(p3_sha256::Sha256); @@ -62,23 +62,35 @@ macro_rules! generate_air_plonky3_test_with_airscript_traits { let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); let challenger = Challenger::from_hasher(vec![], byte_hash); let dft = Dft::default(); - let fri_params = p3_fri::create_benchmark_fri_params(challenge_mmcs); + let mut fri_params = p3_fri::create_recursive_miden_fri_params(challenge_mmcs); let pcs = Pcs::new(dft, val_mmcs, fri_params); let config = MyConfig::new(pcs, challenger); + // Generate public inputs and convert them to Goldilocks field elements let inputs = generate_inputs(); - let inputs_goldilocks: Vec = inputs - .iter() - .map(|&x| ::from_u32(x)) - .collect(); + let inputs_goldilocks = crate::test_utils::pub_inputs_conversion_utils::convert_pub_inputs_to_goldilocks(&inputs); + + // Generate variable-length public inputs as a `Vec>>`. + // The outer `Vec` represents multiple tables (one for each bus in the AIR) + // The middle `Vec` represents the rows of each table + // The innermost `Vec` represents the tuple values contained by the bus, that will be combined with randomness into a single field element. + let var_len_pub_inputs = generate_var_len_pub_inputs(); + // Convert variable-length public inputs to Goldilocks field elements + let var_len_pub_inputs_goldilocks_vec = crate::test_utils::pub_inputs_conversion_utils::convert_var_len_pub_inputs_to_goldilocks(var_len_pub_inputs); + let var_len_pub_inputs_goldilocks_vec_slice = crate::test_utils::pub_inputs_conversion_utils::convert_inner_vec_to_slice(&var_len_pub_inputs_goldilocks_vec); + let var_len_pub_inputs_goldilocks = crate::test_utils::pub_inputs_conversion_utils::convert_mid_vec_to_slice(&var_len_pub_inputs_goldilocks_vec_slice); let trace = generate_trace_rows::(inputs); - check_constraints_with_airscript_traits::( + let proof = p3_miden_prover::prove(&config, &$air_name {}, &trace, &inputs_goldilocks); + p3_miden_prover::verify( + &config, &$air_name {}, - &trace, + &proof, &inputs_goldilocks, - ); + &var_len_pub_inputs_goldilocks, + ) + .expect("Verification failed"); } }; } diff --git a/air-script/src/test_utils/mod.rs b/air-script/src/test_utils/mod.rs index 601c64017..03ce65907 100644 --- a/air-script/src/test_utils/mod.rs +++ b/air-script/src/test_utils/mod.rs @@ -2,9 +2,7 @@ pub mod air_tester_macros; /// Code generation for tests/**/*.air files. pub mod codegen; -/// Miden VM auxiliary trace generator -pub mod miden_vm_aux_trace_generator; -/// Plonky3-specific Debug constraint builder implementation -pub mod plonky3_traits; +/// Conversion utilities for test inputs (both public inputs and variable-length public inputs). +pub mod pub_inputs_conversion_utils; /// Winterfell-specific traits pub mod winterfell_traits; diff --git a/air-script/src/test_utils/plonky3_traits.rs b/air-script/src/test_utils/plonky3_traits.rs deleted file mode 100644 index 1985d1558..000000000 --- a/air-script/src/test_utils/plonky3_traits.rs +++ /dev/null @@ -1,189 +0,0 @@ -use p3_field::{ExtensionField, Field}; -use p3_matrix::{ - Matrix, - dense::{DenseMatrix, RowMajorMatrix, RowMajorMatrixView}, - stack::VerticalPair, -}; -use p3_miden_air::{MidenAir, MidenAirBuilder, impl_p3_air_builder_traits}; - -/// A builder that runs constraint assertions during testing. -/// -/// Used in conjunction with [`check_constraints`] to simulate an execution trace -/// and verify that the AIR logic enforces all constraints. -#[derive(Debug)] -pub struct DebugConstraintBuilderWithAirScriptTraits<'a, F: Field, EF: ExtensionField> { - /// The index of the row currently being evaluated. - row_index: usize, - /// A view of the current and next main row as a vertical pair. - main: VerticalPair, RowMajorMatrixView<'a, F>>, - /// A view of the current and next preprocessed row as a vertical pair. - preprocessed: VerticalPair, RowMajorMatrixView<'a, F>>, - /// A view of the current and next aux row as a vertical pair. - aux: VerticalPair, RowMajorMatrixView<'a, EF>>, - /// The public values provided for constraint validation (e.g. inputs or outputs). - public_values: &'a [F], - /// A flag indicating whether this is the first row. - is_first_row: F, - /// A flag indicating whether this is the last row. - is_last_row: F, - /// A flag indicating whether this is a transition row (not the last row). - is_transition: F, - /// The periodic columns provided for constraint validation. - periodic_columns: Vec, - /// The permutation randomness in the extension field. - permutation_randomness: Vec, - /// The aux bus boundary values in the extension field. - aux_bus_boundary_values: Vec, -} - -impl<'a, F, EF> MidenAirBuilder for DebugConstraintBuilderWithAirScriptTraits<'a, F, EF> -where - F: Field, - EF: ExtensionField, -{ - type F = F; - type Expr = F; - type Var = F; - type M = VerticalPair, DenseMatrix>; - type PublicVar = F; - type PeriodicVal = EF; - type EF = EF; - type ExprEF = EF; - type VarEF = EF; - type MP = VerticalPair, DenseMatrix>; - type RandomVar = EF; - - fn main(&self) -> Self::M { - self.main - } - - fn is_first_row(&self) -> Self::Expr { - self.is_first_row - } - - fn is_last_row(&self) -> Self::Expr { - self.is_last_row - } - - fn is_transition_window(&self, size: usize) -> Self::Expr { - if size == 2 { - self.is_transition - } else { - panic!("only supports a window size of 2") - } - } - - fn assert_zero>(&mut self, x: I) { - assert_eq!(x.into(), F::ZERO, "constraints had nonzero value on row {}", self.row_index); - } - - fn public_values(&self) -> &[Self::PublicVar] { - self.public_values - } - - fn periodic_evals(&self) -> &[::PeriodicVal] { - self.periodic_columns.as_slice() - } - - fn preprocessed(&self) -> Self::M { - self.preprocessed - } - - fn assert_zero_ext(&mut self, x: I) - where - I: Into, - { - assert_eq!( - x.into(), - EF::ZERO, - "constraints on ext field had nonzero value on row {}", - self.row_index - ); - } - - fn permutation(&self) -> Self::MP { - self.aux - } - - fn permutation_randomness(&self) -> &[Self::RandomVar] { - self.permutation_randomness.as_slice() - } - - fn aux_bus_boundary_values(&self) -> &[::VarEF] { - self.aux_bus_boundary_values.as_slice() - } -} - -impl_p3_air_builder_traits!(DebugConstraintBuilderWithAirScriptTraits<'a, F, EF> where F: Field, EF: ExtensionField); - -pub(crate) fn check_constraints_with_airscript_traits( - air: &A, - main: &RowMajorMatrix, - public_values: &Vec, -) where - F: Field, - EF: ExtensionField, - A: MidenAir, -{ - let height = main.height(); - - let aux_bus_boundary_values: Vec<_> = (0..air.aux_width()).map(|_| EF::GENERATOR).collect(); - let alpha = EF::from_basis_coefficients_iter( - (0..EF::DIMENSION).map(|i| F::from_u64(123456789 * (i as u64 + 1))), - ) - .unwrap(); - let beta = EF::from_u64(987654321); - let beta_powers: Vec = (0..(air.num_randomness().saturating_sub(1))) - .map(|power| beta.exp_u64(power as u64)) - .collect(); - let mut permutation_randomness = Vec::with_capacity(air.num_randomness()); - permutation_randomness.push(alpha); - permutation_randomness.extend_from_slice(beta_powers.as_slice()); - - let aux_trace = air - .build_aux_trace(main, &permutation_randomness) - .unwrap_or(DenseMatrix::default(0, height)); - - (0..height).for_each(|i| { - let i_next = (i + 1) % height; - - let main_local = main.row_slice(i).unwrap(); // i < height so unwrap should never fail. - let main_next = main.row_slice(i_next).unwrap(); // i_next < height so unwrap should never fail. - let main = VerticalPair::new( - RowMajorMatrixView::new_row(&*main_local), - RowMajorMatrixView::new_row(&*main_next), - ); - let aux_local_ref = aux_trace.row_slice(i); - let aux_next_ref = aux_trace.row_slice(i_next); - let aux_local = aux_local_ref.as_deref().unwrap_or_default(); - let aux_next = aux_next_ref.as_deref().unwrap_or_default(); - let aux = VerticalPair::new( - RowMajorMatrixView::new_row(&*aux_local), - RowMajorMatrixView::new_row(&*aux_next), - ); - let preprocessed = VerticalPair::new::( - RowMajorMatrixView::new(&[], 0), - RowMajorMatrixView::new(&[], 0), - ); - - let periodic_columns_base: Vec<_> = - air.periodic_table().iter().map(|col| col[i % col.len()]).collect(); - let periodic_columns: Vec = - periodic_columns_base.iter().map(|&v| EF::from(v)).collect(); - - let mut builder = DebugConstraintBuilderWithAirScriptTraits { - row_index: i, - main, - preprocessed, - aux, - public_values, - is_first_row: F::from_bool(i == 0), - is_last_row: F::from_bool(i == height - 1), - is_transition: F::from_bool(i != height - 1), - periodic_columns, - permutation_randomness: permutation_randomness.clone(), - aux_bus_boundary_values: aux_bus_boundary_values.clone(), - }; - air.eval(&mut builder); - }); -} diff --git a/air-script/src/test_utils/pub_inputs_conversion_utils.rs b/air-script/src/test_utils/pub_inputs_conversion_utils.rs new file mode 100644 index 000000000..894ba75d6 --- /dev/null +++ b/air-script/src/test_utils/pub_inputs_conversion_utils.rs @@ -0,0 +1,46 @@ +type Val = p3_goldilocks::Goldilocks; + +/// Converts public inputs from u64 to Goldilocks field elements. +pub(crate) fn convert_pub_inputs_to_goldilocks(pub_inputs: &[u64]) -> Vec { + pub_inputs + .iter() + .map(|&x| ::from_u64(x)) + .collect() +} + +/// Converts variable-length public inputs from u64 to Goldilocks field elements. +/// The input should be a Vec of tables (Vec>) in a RowMajor format. +pub(crate) fn convert_var_len_pub_inputs_to_goldilocks( + var_len_pub_inputs: Vec>>, +) -> Vec>> { + let mut var_len_pub_inputs_goldilocks_vec: Vec>> = vec![]; + for arr in var_len_pub_inputs.iter() { + let mut goldilocks_arr: Vec> = vec![]; + for slice in arr.iter() { + let goldilocks_slice: Vec = slice + .iter() + .map(|&x| ::from_u64(x)) + .collect(); + goldilocks_arr.push(goldilocks_slice); + } + var_len_pub_inputs_goldilocks_vec.push(goldilocks_arr); + } + var_len_pub_inputs_goldilocks_vec +} + +/// Converts the innermost vectors of variable-length public inputs to slices. +pub(crate) fn convert_inner_vec_to_slice<'a>( + var_len_pub_inputs: &'a Vec>>, +) -> Vec> { + var_len_pub_inputs + .iter() + .map(|outer| outer.iter().map(|inner| inner.as_slice()).collect()) + .collect() +} + +/// Converts the middle vectors of variable-length public inputs to slices. +pub(crate) fn convert_mid_vec_to_slice<'a>( + var_len_pub_inputs: &'a Vec>, +) -> Vec<&'a [&'a [Val]]> { + var_len_pub_inputs.iter().map(|v| v.as_slice()).collect() +} diff --git a/air-script/src/tests/binary/binary_plonky3.rs b/air-script/src/tests/binary/binary_plonky3.rs index 0c514ea56..9f64d933c 100644 --- a/air-script/src/tests/binary/binary_plonky3.rs +++ b/air-script/src/tests/binary/binary_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 2; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for BinaryAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -37,8 +38,6 @@ impl MidenAir for BinaryAir { builder.assert_zero(main_current[0].clone().into() * main_current[0].clone().into() - main_current[0].clone().into()); builder.assert_zero(main_current[1].clone().into() * main_current[1].clone().into() - main_current[1].clone().into()); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/binary/test_air_plonky3.rs b/air-script/src/tests/binary/test_air_plonky3.rs index eced0b469..ba508f868 100644 --- a/air-script/src/tests/binary/test_air_plonky3.rs +++ b/air-script/src/tests/binary/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::binary::binary_plonky3::{BinaryAir, MAIN_WIDTH}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -37,8 +36,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, BinaryAir); diff --git a/air-script/src/tests/bitwise/bitwise_plonky3.rs b/air-script/src/tests/bitwise/bitwise_plonky3.rs index bfded5b9b..9811db8cf 100644 --- a/air-script/src/tests/bitwise/bitwise_plonky3.rs +++ b/air-script/src/tests/bitwise/bitwise_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 14; pub const AUX_WIDTH: usize = 0; @@ -33,11 +33,12 @@ where F: Field, } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -66,8 +67,6 @@ where F: Field, builder.when_transition().assert_zero_ext(AB::ExprEF::from(periodic_values[1].clone().into()) * (AB::ExprEF::from(main_current[12].clone().into()) - AB::ExprEF::from(main_next[11].clone().into()))); builder.assert_zero((AB::Expr::ONE - main_current[0].clone().into()) * (main_current[12].clone().into() - (main_current[11].clone().into() * AB::Expr::from_u64(16) + main_current[3].clone().into() * main_current[7].clone().into() + main_current[4].clone().into().double() * main_current[8].clone().into() + AB::Expr::from_u64(4) * main_current[5].clone().into() * main_current[9].clone().into() + AB::Expr::from_u64(8) * main_current[6].clone().into() * main_current[10].clone().into())) + main_current[0].clone().into() * (main_current[12].clone().into() - (main_current[11].clone().into() * AB::Expr::from_u64(16) + main_current[3].clone().into() + main_current[7].clone().into() - main_current[3].clone().into().double() * main_current[7].clone().into() + (main_current[4].clone().into() + main_current[8].clone().into() - main_current[4].clone().into().double() * main_current[8].clone().into()).double() + AB::Expr::from_u64(4) * (main_current[5].clone().into() + main_current[9].clone().into() - main_current[5].clone().into().double() * main_current[9].clone().into()) + AB::Expr::from_u64(8) * (main_current[6].clone().into() + main_current[10].clone().into() - main_current[6].clone().into().double() * main_current[10].clone().into())))); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/bitwise/test_air_plonky3.rs b/air-script/src/tests/bitwise/test_air_plonky3.rs index d969cb1a6..91b2c0637 100644 --- a/air-script/src/tests/bitwise/test_air_plonky3.rs +++ b/air-script/src/tests/bitwise/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::bitwise::bitwise_plonky3::{BitwiseAir, MAIN_WIDTH}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -75,8 +74,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, BitwiseAir); diff --git a/air-script/src/tests/buses/buses_complex_plonky3.rs b/air-script/src/tests/buses/buses_complex_plonky3.rs index 00d266cf9..2d038524d 100644 --- a/air-script/src/tests/buses/buses_complex_plonky3.rs +++ b/air-script/src/tests/buses/buses_complex_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 7; pub const AUX_WIDTH: usize = 2; @@ -29,7 +29,14 @@ where F: Field, AUX_WIDTH } - fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { + fn bus_types(&self) -> Vec { + vec![ + BusType::Multiset, + BusType::Logup, + ] + } + + fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { // Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders. let num_rows = _main.height(); @@ -66,15 +73,17 @@ where F: Field, rows[i+1][j] = next_row[j]; } } - Some(trace) + let trace_f = trace.flatten_to_base(); + Some(trace_f) } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -96,12 +105,6 @@ where F: Field, builder.assert_zero(main_current[2].clone().into() * main_current[2].clone().into() - main_current[2].clone().into()); builder.assert_zero(main_current[3].clone().into() * main_current[3].clone().into() - main_current[3].clone().into()); - // Aux boundary constraints - builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); - builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); - builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); - builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); - // Aux integrity/transition constraints builder.when_transition().assert_zero_ext(((alpha.into() + beta_challenges[0].into() + (AB::ExprEF::from_u64(3) + AB::ExprEF::from(main_current[1].clone().into())) * beta_challenges[1].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[2].into()) * AB::ExprEF::from(main_current[2].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[2].clone().into())) * ((alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[1].clone().into()) * beta_challenges[1].into()) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[2].clone().into())) + AB::ExprEF::from(main_current[2].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into() + (AB::ExprEF::from_u64(3) + AB::ExprEF::from(main_current[1].clone().into())) * beta_challenges[1].into() + AB::ExprEF::from(main_current[1].clone().into()) * beta_challenges[2].into()) * AB::ExprEF::from(main_current[3].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[3].clone().into())) * ((alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[3].clone().into())) + AB::ExprEF::from(main_current[3].clone().into())) * AB::ExprEF::from(aux_next[0].clone().into())); builder.when_transition().assert_zero_ext((alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[1].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(aux_current[1].clone().into()) + (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[1].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(main_current[4].clone().into()) + (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[1].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(main_current[5].clone().into()) - ((alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[1].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(aux_next[1].clone().into()) + (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(main_current[6].clone().into()))); diff --git a/air-script/src/tests/buses/buses_simple_plonky3.rs b/air-script/src/tests/buses/buses_simple_plonky3.rs index 1ee51d533..65efcf8fb 100644 --- a/air-script/src/tests/buses/buses_simple_plonky3.rs +++ b/air-script/src/tests/buses/buses_simple_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 1; pub const AUX_WIDTH: usize = 2; @@ -29,7 +29,14 @@ where F: Field, AUX_WIDTH } - fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { + fn bus_types(&self) -> Vec { + vec![ + BusType::Multiset, + BusType::Logup, + ] + } + + fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { // Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders. let num_rows = _main.height(); @@ -66,15 +73,17 @@ where F: Field, rows[i+1][j] = next_row[j]; } } - Some(trace) + let trace_f = trace.flatten_to_base(); + Some(trace_f) } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -93,11 +102,6 @@ where F: Field, // Main integrity/transition constraints - // Aux boundary constraints - builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); - builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); - builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); - // Aux integrity/transition constraints builder.when_transition().assert_zero_ext(((alpha.into() + beta_challenges[0].into()) * AB::ExprEF::from(main_current[0].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into()) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) + AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(aux_next[0].clone().into())); builder.when_transition().assert_zero_ext((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_current[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_next[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()).double())); diff --git a/air-script/src/tests/buses/buses_varlen_boundary_both_plonky3.rs b/air-script/src/tests/buses/buses_varlen_boundary_both_plonky3.rs index 13ed74cc7..b32d738e1 100644 --- a/air-script/src/tests/buses/buses_varlen_boundary_both_plonky3.rs +++ b/air-script/src/tests/buses/buses_varlen_boundary_both_plonky3.rs @@ -2,13 +2,13 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 1; pub const AUX_WIDTH: usize = 2; pub const NUM_PERIODIC_VALUES: usize = 0; pub const PERIOD: usize = 0; -pub const NUM_PUBLIC_VALUES: usize = 6; +pub const NUM_PUBLIC_VALUES: usize = 0; pub const MAX_BETA_CHALLENGE_POWER: usize = 2; pub struct BusesAir; @@ -29,7 +29,14 @@ where F: Field, AUX_WIDTH } - fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { + fn bus_types(&self) -> Vec { + vec![ + BusType::Multiset, + BusType::Logup, + ] + } + + fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { // Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders. let num_rows = _main.height(); @@ -66,15 +73,17 @@ where F: Field, rows[i+1][j] = next_row[j]; } } - Some(trace) + let trace_f = trace.flatten_to_base(); + Some(trace_f) } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -93,11 +102,6 @@ where F: Field, // Main integrity/transition constraints - // Aux boundary constraints - builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - aux_bus_boundary_values[0].into()); - builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); - builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into()) - aux_bus_boundary_values[1].into()); - // Aux integrity/transition constraints builder.when_transition().assert_zero_ext(((alpha.into() + beta_challenges[0].into()) * AB::ExprEF::from(main_current[0].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into()) * (AB::ExprEF::from(main_current[0].clone().into()) - AB::ExprEF::ONE) + AB::ExprEF::ONE - (AB::ExprEF::from(main_current[0].clone().into()) - AB::ExprEF::ONE)) * AB::ExprEF::from(aux_next[0].clone().into())); builder.when_transition().assert_zero_ext((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_current[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_next[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()).double())); diff --git a/air-script/src/tests/buses/buses_varlen_boundary_first_plonky3.rs b/air-script/src/tests/buses/buses_varlen_boundary_first_plonky3.rs index 7a8c42bda..b32d738e1 100644 --- a/air-script/src/tests/buses/buses_varlen_boundary_first_plonky3.rs +++ b/air-script/src/tests/buses/buses_varlen_boundary_first_plonky3.rs @@ -2,13 +2,13 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 1; pub const AUX_WIDTH: usize = 2; pub const NUM_PERIODIC_VALUES: usize = 0; pub const PERIOD: usize = 0; -pub const NUM_PUBLIC_VALUES: usize = 2; +pub const NUM_PUBLIC_VALUES: usize = 0; pub const MAX_BETA_CHALLENGE_POWER: usize = 2; pub struct BusesAir; @@ -29,7 +29,14 @@ where F: Field, AUX_WIDTH } - fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { + fn bus_types(&self) -> Vec { + vec![ + BusType::Multiset, + BusType::Logup, + ] + } + + fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { // Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders. let num_rows = _main.height(); @@ -66,15 +73,17 @@ where F: Field, rows[i+1][j] = next_row[j]; } } - Some(trace) + let trace_f = trace.flatten_to_base(); + Some(trace_f) } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -93,12 +102,6 @@ where F: Field, // Main integrity/transition constraints - // Aux boundary constraints - builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - aux_bus_boundary_values[0].into()); - builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); - builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into()) - aux_bus_boundary_values[1].into()); - builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); - // Aux integrity/transition constraints builder.when_transition().assert_zero_ext(((alpha.into() + beta_challenges[0].into()) * AB::ExprEF::from(main_current[0].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into()) * (AB::ExprEF::from(main_current[0].clone().into()) - AB::ExprEF::ONE) + AB::ExprEF::ONE - (AB::ExprEF::from(main_current[0].clone().into()) - AB::ExprEF::ONE)) * AB::ExprEF::from(aux_next[0].clone().into())); builder.when_transition().assert_zero_ext((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_current[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_next[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()).double())); diff --git a/air-script/src/tests/buses/buses_varlen_boundary_last.air b/air-script/src/tests/buses/buses_varlen_boundary_last.air index 9819cbc21..39e48144a 100644 --- a/air-script/src/tests/buses/buses_varlen_boundary_last.air +++ b/air-script/src/tests/buses/buses_varlen_boundary_last.air @@ -1,7 +1,7 @@ def BusesAir trace_columns { - main: [a], + main: [a, sp_insert, sp_remove, sq_insert_twice, sq_remove], } buses { @@ -10,20 +10,21 @@ buses { } public_inputs { - outputs: [[2]], + outputs_p: [[2]], + outputs_q: [[2]], } boundary_constraints { enf p.first = null; enf q.first = null; - enf p.last = outputs; - enf q.last = outputs; + enf p.last = outputs_p; + enf q.last = outputs_q; } integrity_constraints { - p.insert(1) when a; - p.remove(1) when (a - 1); - q.insert(1, 2) when a; - q.insert(1, 2) when a; - q.remove(1, 2) with 2; + p.insert(a) when sp_insert; + p.remove(a) when sp_remove; + q.insert(2, a) when sq_insert_twice; + q.insert(2, a) when sq_insert_twice; + q.remove(2, a) with sq_remove; } diff --git a/air-script/src/tests/buses/buses_varlen_boundary_last.rs b/air-script/src/tests/buses/buses_varlen_boundary_last.rs index 686604e08..65dbbda92 100644 --- a/air-script/src/tests/buses/buses_varlen_boundary_last.rs +++ b/air-script/src/tests/buses/buses_varlen_boundary_last.rs @@ -4,32 +4,36 @@ use winter_math::{ExtensionOf, FieldElement, ToElements}; use winter_utils::{ByteWriter, Serializable}; pub struct PublicInputs { - outputs: Vec<[Felt; 2]>, + outputs_p: Vec<[Felt; 2]>, + outputs_q: Vec<[Felt; 2]>, } impl PublicInputs { - pub fn new(outputs: Vec<[Felt; 2]>) -> Self { - Self { outputs } + pub fn new(outputs_p: Vec<[Felt; 2]>, outputs_q: Vec<[Felt; 2]>) -> Self { + Self { outputs_p, outputs_q } } } impl Serializable for PublicInputs { fn write_into(&self, target: &mut W) { - self.outputs.write_into(target); + self.outputs_p.write_into(target); + self.outputs_q.write_into(target); } } impl ToElements for PublicInputs { fn to_elements(&self) -> Vec { let mut elements = Vec::new(); - self.outputs.iter().for_each(|row| elements.extend_from_slice(row)); + self.outputs_p.iter().for_each(|row| elements.extend_from_slice(row)); + self.outputs_q.iter().for_each(|row| elements.extend_from_slice(row)); elements } } pub struct BusesAir { context: AirContext, - outputs: Vec<[Felt; 2]>, + outputs_p: Vec<[Felt; 2]>, + outputs_q: Vec<[Felt; 2]>, } impl BusesAir { @@ -75,7 +79,7 @@ impl Air for BusesAir { fn new(trace_info: TraceInfo, public_inputs: PublicInputs, options: WinterProofOptions) -> Self { let main_degrees = vec![]; - let aux_degrees = vec![TransitionConstraintDegree::new(2), TransitionConstraintDegree::new(1)]; + let aux_degrees = vec![TransitionConstraintDegree::new(3), TransitionConstraintDegree::new(4)]; let num_main_assertions = 0; let num_aux_assertions = 4; @@ -88,7 +92,7 @@ impl Air for BusesAir { options, ) .set_num_transition_exemptions(2); - Self { context, outputs: public_inputs.outputs } + Self { context, outputs_p: public_inputs.outputs_p, outputs_q: public_inputs.outputs_q } } fn get_periodic_column_values(&self) -> Vec> { @@ -102,12 +106,12 @@ impl Air for BusesAir { fn get_aux_assertions>(&self, aux_rand_elements: &AuxRandElements) -> Vec> { let mut result = Vec::new(); - let reduced_outputs_multiset = Self::bus_multiset_boundary_varlen(aux_rand_elements, &self.outputs); - let reduced_outputs_logup = Self::bus_logup_boundary_varlen(aux_rand_elements, &self.outputs); + let reduced_outputs_p_multiset = Self::bus_multiset_boundary_varlen(aux_rand_elements, &self.outputs_p); + let reduced_outputs_q_logup = Self::bus_logup_boundary_varlen(aux_rand_elements, &self.outputs_q); result.push(Assertion::single(0, 0, E::ONE)); - result.push(Assertion::single(0, self.last_step(), reduced_outputs_multiset)); + result.push(Assertion::single(0, self.last_step(), reduced_outputs_p_multiset)); result.push(Assertion::single(1, 0, E::ZERO)); - result.push(Assertion::single(1, self.last_step(), reduced_outputs_logup)); + result.push(Assertion::single(1, self.last_step(), reduced_outputs_q_logup)); result } @@ -124,7 +128,7 @@ impl Air for BusesAir { let main_next = main_frame.next(); let aux_current = aux_frame.current(); let aux_next = aux_frame.next(); - result[0] = ((aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1]) * E::from(main_current[0]) + E::ONE - E::from(main_current[0])) * aux_current[0] - ((aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1]) * (E::from(main_current[0]) - E::ONE) + E::ONE - (E::from(main_current[0]) - E::ONE)) * aux_next[0]; - result[1] = (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * aux_current[1] + (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * E::from(main_current[0]) + (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * E::from(main_current[0]) - ((aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * aux_next[1] + (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + aux_rand_elements.rand_elements()[1] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[2]) * E::from(Felt::new(2_u64))); + result[0] = ((aux_rand_elements.rand_elements()[0] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[1]) * E::from(main_current[1]) + E::ONE - E::from(main_current[1])) * aux_current[0] - ((aux_rand_elements.rand_elements()[0] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[1]) * E::from(main_current[2]) + E::ONE - E::from(main_current[2])) * aux_next[0]; + result[1] = (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * aux_current[1] + (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * E::from(main_current[3]) + (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * E::from(main_current[3]) - ((aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * aux_next[1] + (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * (aux_rand_elements.rand_elements()[0] + E::from(Felt::new(2_u64)) * aux_rand_elements.rand_elements()[1] + E::from(main_current[0]) * aux_rand_elements.rand_elements()[2]) * E::from(main_current[4])); } } \ No newline at end of file diff --git a/air-script/src/tests/buses/buses_varlen_boundary_last_plonky3.rs b/air-script/src/tests/buses/buses_varlen_boundary_last_plonky3.rs index fa895389e..dba927c11 100644 --- a/air-script/src/tests/buses/buses_varlen_boundary_last_plonky3.rs +++ b/air-script/src/tests/buses/buses_varlen_boundary_last_plonky3.rs @@ -2,13 +2,13 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; -pub const MAIN_WIDTH: usize = 1; +pub const MAIN_WIDTH: usize = 5; pub const AUX_WIDTH: usize = 2; pub const NUM_PERIODIC_VALUES: usize = 0; pub const PERIOD: usize = 0; -pub const NUM_PUBLIC_VALUES: usize = 2; +pub const NUM_PUBLIC_VALUES: usize = 0; pub const MAX_BETA_CHALLENGE_POWER: usize = 2; pub struct BusesAir; @@ -29,7 +29,14 @@ where F: Field, AUX_WIDTH } - fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { + fn bus_types(&self) -> Vec { + vec![ + BusType::Multiset, + BusType::Logup, + ] + } + + fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { // Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders. let num_rows = _main.height(); @@ -66,15 +73,17 @@ where F: Field, rows[i+1][j] = next_row[j]; } } - Some(trace) + let trace_f = trace.flatten_to_base(); + Some(trace_f) } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -93,15 +102,9 @@ where F: Field, // Main integrity/transition constraints - // Aux boundary constraints - builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); - builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - aux_bus_boundary_values[0].into()); - builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into())); - builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[1].clone().into()) - aux_bus_boundary_values[1].into()); - // Aux integrity/transition constraints - builder.when_transition().assert_zero_ext(((alpha.into() + beta_challenges[0].into()) * AB::ExprEF::from(main_current[0].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into()) * (AB::ExprEF::from(main_current[0].clone().into()) - AB::ExprEF::ONE) + AB::ExprEF::ONE - (AB::ExprEF::from(main_current[0].clone().into()) - AB::ExprEF::ONE)) * AB::ExprEF::from(aux_next[0].clone().into())); - builder.when_transition().assert_zero_ext((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_current[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) - ((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(aux_next[1].clone().into()) + (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()).double())); + builder.when_transition().assert_zero_ext(((alpha.into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[0].into()) * AB::ExprEF::from(main_current[1].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[1].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[0].into()) * AB::ExprEF::from(main_current[2].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[2].clone().into())) * AB::ExprEF::from(aux_next[0].clone().into())); + builder.when_transition().assert_zero_ext((alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(aux_current[1].clone().into()) + (alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(main_current[3].clone().into()) + (alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(main_current[3].clone().into()) - ((alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(aux_next[1].clone().into()) + (alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * (alpha.into() + beta_challenges[0].into().double() + AB::ExprEF::from(main_current[0].clone().into()) * beta_challenges[1].into()) * AB::ExprEF::from(main_current[4].clone().into()))); } } @@ -128,8 +131,8 @@ impl BusesAir { let beta_challenges: [_; MAX_BETA_CHALLENGE_POWER] = beta_challenges.try_into().expect("Wrong number of randomness"); let periodic_values: [_; NUM_PERIODIC_VALUES] = periodic_evals.try_into().expect("Wrong number of periodic values"); vec![ - (((alpha + beta_challenges[0]) * EF::from(main_current[0].clone()) + EF::ONE - EF::from(main_current[0].clone())) * EF::from(aux_current[0].clone())) * ((alpha + beta_challenges[0]) * (EF::from(main_current[0].clone()) - EF::ONE) + EF::ONE - (EF::from(main_current[0].clone()) - EF::ONE)).inverse(), - ((alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(aux_current[1].clone()) + (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(main_current[0].clone()) + (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * EF::from(main_current[0].clone()) - (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()).double()) * ((alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double()) * (alpha + beta_challenges[0] + beta_challenges[1].double())).inverse(), + (((alpha + EF::from(main_current[0].clone()) * beta_challenges[0]) * EF::from(main_current[1].clone()) + EF::ONE - EF::from(main_current[1].clone())) * EF::from(aux_current[0].clone())) * ((alpha + EF::from(main_current[0].clone()) * beta_challenges[0]) * EF::from(main_current[2].clone()) + EF::ONE - EF::from(main_current[2].clone())).inverse(), + ((alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1]) * EF::from(aux_current[1].clone()) + (alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1]) * EF::from(main_current[3].clone()) + (alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1]) * EF::from(main_current[3].clone()) - (alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1]) * EF::from(main_current[4].clone())) * ((alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1]) * (alpha + beta_challenges[0].double() + EF::from(main_current[0].clone()) * beta_challenges[1])).inverse(), ] } } \ No newline at end of file diff --git a/air-script/src/tests/buses/mod.rs b/air-script/src/tests/buses/mod.rs index 95eeeb07b..5c0ca958c 100644 --- a/air-script/src/tests/buses/mod.rs +++ b/air-script/src/tests/buses/mod.rs @@ -36,4 +36,5 @@ mod buses_varlen_boundary_first_plonky3; mod buses_varlen_boundary_last_plonky3; mod test_air_plonky3; +mod test_air_plonky3_varlen_boundary_last; mod test_air_winterfell; diff --git a/air-script/src/tests/buses/test_air_plonky3.rs b/air-script/src/tests/buses/test_air_plonky3.rs index 20919a31e..676d87701 100644 --- a/air-script/src/tests/buses/test_air_plonky3.rs +++ b/air-script/src/tests/buses/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::buses::buses_complex_plonky3::{BusesAir, MAIN_WIDTH}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -52,8 +51,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 2] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![vec![], vec![], vec![]] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, BusesAir); diff --git a/air-script/src/tests/buses/test_air_plonky3_varlen_boundary_last.rs b/air-script/src/tests/buses/test_air_plonky3_varlen_boundary_last.rs new file mode 100644 index 000000000..6415f669e --- /dev/null +++ b/air-script/src/tests/buses/test_air_plonky3_varlen_boundary_last.rs @@ -0,0 +1,64 @@ +use p3_field::PrimeField64; +use p3_miden_air::RowMajorMatrix; + +use crate::{ + generate_air_plonky3_test_with_airscript_traits, + tests::buses::buses_varlen_boundary_last_plonky3::{BusesAir, MAIN_WIDTH}, +}; + +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; + let trace_length = num_rows * MAIN_WIDTH; + + let mut long_trace = F::zero_vec(trace_length); + + let mut trace = RowMajorMatrix::new(long_trace, MAIN_WIDTH); + + let (prefix, rows, suffix) = unsafe { trace.values.align_to_mut::<[F; MAIN_WIDTH]>() }; + assert!(prefix.is_empty(), "Alignment should match"); + assert!(suffix.is_empty(), "Alignment should match"); + assert_eq!(rows.len(), num_rows); + + // Initialize first row + rows[0][0] = F::ONE; + rows[0][1] = F::ZERO; + rows[0][2] = F::ZERO; + rows[0][3] = F::ZERO; + rows[0][4] = F::ZERO; + + // Fill subsequent rows using direct access to the rows array + for i in 1..num_rows { + let a_prev = rows[i - 1][0]; + let b_prev = rows[i - 1][1]; + let c_prev = rows[i - 1][2]; + let d_prev = rows[i - 1][3]; + let e_prev = rows[i - 1][4]; + + // Update current row based on previous values + rows[i][0] = F::ONE; + rows[i][1] = if i > 3 && i < 8 { F::ONE } else { F::ZERO }; // sp_insert is true 4 times + rows[i][2] = if i > 3 && i < 7 { F::ONE } else { F::ZERO }; // sp_remove is true 3 times + rows[i][3] = if i > 4 && i < 10 { F::ONE } else { F::ZERO }; // sq_insert_twice is true 5 times + rows[i][4] = if i > 5 && i < 10 { + F::from_canonical_checked(2).unwrap() + } else { + F::ZERO + }; // sq_remove has value "2" 4 times + } + + trace +} + +fn generate_inputs() -> Vec { + vec![] +} + +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + // At the end, the bus p will have the tuple (a) (that equals (1)) inserted once + let var_len_p = vec![vec![1]]; + // At the end, the bus q will have the tuple (2, a) (that equals (2, 1)) inserted twice + let var_len_q = vec![vec![2, 1], vec![2, 1]]; + vec![var_len_p, var_len_q] +} + +generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, BusesAir); diff --git a/air-script/src/tests/computed_indices/computed_indices_complex_plonky3.rs b/air-script/src/tests/computed_indices/computed_indices_complex_plonky3.rs index ae3ee2903..6b87e196b 100644 --- a/air-script/src/tests/computed_indices/computed_indices_complex_plonky3.rs +++ b/air-script/src/tests/computed_indices/computed_indices_complex_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 4; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for ComputedIndicesAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -36,8 +37,6 @@ impl MidenAir for ComputedIndicesAir { // Main integrity/transition constraints builder.assert_zero(main_current[2].clone().into() * AB::Expr::from_u64(3) + main_current[3].clone().into() * AB::Expr::from_u64(4)); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/computed_indices/computed_indices_simple_plonky3.rs b/air-script/src/tests/computed_indices/computed_indices_simple_plonky3.rs index 40c374ad3..1ab566b59 100644 --- a/air-script/src/tests/computed_indices/computed_indices_simple_plonky3.rs +++ b/air-script/src/tests/computed_indices/computed_indices_simple_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 8; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for ComputedIndicesAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -43,8 +44,6 @@ impl MidenAir for ComputedIndicesAir { builder.when_transition().assert_zero(main_next[6].clone().into() - AB::Expr::from_u64(6) * main_current[6].clone().into()); builder.when_transition().assert_zero(main_next[7].clone().into() - AB::Expr::from_u64(12) * main_current[7].clone().into()); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/computed_indices/test_air_plonky3.rs b/air-script/src/tests/computed_indices/test_air_plonky3.rs index 5f02cc466..0ebed55a3 100644 --- a/air-script/src/tests/computed_indices/test_air_plonky3.rs +++ b/air-script/src/tests/computed_indices/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::computed_indices::computed_indices_simple_plonky3::{ComputedIndicesAir, MAIN_WIDTH}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -55,8 +54,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, ComputedIndicesAir); diff --git a/air-script/src/tests/constant_in_range/constant_in_range_plonky3.rs b/air-script/src/tests/constant_in_range/constant_in_range_plonky3.rs index b1238f7cc..134d141eb 100644 --- a/air-script/src/tests/constant_in_range/constant_in_range_plonky3.rs +++ b/air-script/src/tests/constant_in_range/constant_in_range_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 12; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for ConstantInRangeAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -36,8 +37,6 @@ impl MidenAir for ConstantInRangeAir { // Main integrity/transition constraints builder.assert_zero(main_current[0].clone().into() - (main_current[1].clone().into() - main_current[4].clone().into() - main_current[8].clone().into() + AB::Expr::ONE + main_current[2].clone().into() - main_current[5].clone().into() - main_current[9].clone().into() + AB::Expr::from_u64(2) + main_current[3].clone().into() - main_current[6].clone().into() - main_current[10].clone().into())); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/constant_in_range/test_air_plonky3.rs b/air-script/src/tests/constant_in_range/test_air_plonky3.rs index 9dd399e1c..e1959450e 100644 --- a/air-script/src/tests/constant_in_range/test_air_plonky3.rs +++ b/air-script/src/tests/constant_in_range/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::constant_in_range::constant_in_range_plonky3::{ConstantInRangeAir, MAIN_WIDTH}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -56,8 +55,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, ConstantInRangeAir); diff --git a/air-script/src/tests/constants/constants_plonky3.rs b/air-script/src/tests/constants/constants_plonky3.rs index 632331aab..72218cfbb 100644 --- a/air-script/src/tests/constants/constants_plonky3.rs +++ b/air-script/src/tests/constants/constants_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 7; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for ConstantsAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -45,8 +46,6 @@ impl MidenAir for ConstantsAir { builder.when_transition().assert_zero(main_next[5].clone().into() - (main_current[5].clone().into() + AB::Expr::ONE)); builder.assert_zero(main_current[4].clone().into() - AB::Expr::ONE); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/constants/test_air_plonky3.rs b/air-script/src/tests/constants/test_air_plonky3.rs index cf2c54ebd..5c906ff3b 100644 --- a/air-script/src/tests/constants/test_air_plonky3.rs +++ b/air-script/src/tests/constants/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::constants::constants_plonky3::{ConstantsAir, MAIN_WIDTH}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -52,8 +51,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 32] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, ConstantsAir); diff --git a/air-script/src/tests/constraint_comprehension/constraint_comprehension_plonky3.rs b/air-script/src/tests/constraint_comprehension/constraint_comprehension_plonky3.rs index e333b9626..b34c6181b 100644 --- a/air-script/src/tests/constraint_comprehension/constraint_comprehension_plonky3.rs +++ b/air-script/src/tests/constraint_comprehension/constraint_comprehension_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 14; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for ConstraintComprehensionAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -39,8 +40,6 @@ impl MidenAir for ConstraintComprehensionAir { builder.assert_zero(main_current[8].clone().into() - main_current[12].clone().into()); builder.assert_zero(main_current[9].clone().into() - main_current[13].clone().into()); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/constraint_comprehension/test_air_plonky3.rs b/air-script/src/tests/constraint_comprehension/test_air_plonky3.rs index f9fa0d39c..09f942eb3 100644 --- a/air-script/src/tests/constraint_comprehension/test_air_plonky3.rs +++ b/air-script/src/tests/constraint_comprehension/test_air_plonky3.rs @@ -3,14 +3,13 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::constraint_comprehension::constraint_comprehension_plonky3::{ ConstraintComprehensionAir, MAIN_WIDTH, }, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -39,8 +38,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, ConstraintComprehensionAir); diff --git a/air-script/src/tests/evaluators/evaluators_nested_slice_call_plonky3.rs b/air-script/src/tests/evaluators/evaluators_nested_slice_call_plonky3.rs index 8dfd1d4bf..45e132b6c 100644 --- a/air-script/src/tests/evaluators/evaluators_nested_slice_call_plonky3.rs +++ b/air-script/src/tests/evaluators/evaluators_nested_slice_call_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 20; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for EvaluatorsSliceAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -59,8 +60,6 @@ impl MidenAir for EvaluatorsSliceAir { builder.assert_zero(main_current[5].clone().into() * main_current[6].clone().into() * main_current[7].clone().into() * (main_current[8].clone().into() * main_current[8].clone().into() - main_current[8].clone().into())); builder.assert_zero(main_current[5].clone().into() * main_current[6].clone().into() * main_current[7].clone().into() * main_current[8].clone().into() * (main_current[9].clone().into() * main_current[9].clone().into() - main_current[9].clone().into())); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/evaluators/evaluators_plonky3.rs b/air-script/src/tests/evaluators/evaluators_plonky3.rs index 07f19ea21..5c0ad3895 100644 --- a/air-script/src/tests/evaluators/evaluators_plonky3.rs +++ b/air-script/src/tests/evaluators/evaluators_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 7; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for EvaluatorsAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -45,8 +46,6 @@ impl MidenAir for EvaluatorsAir { builder.assert_zero(main_current[5].clone().into() - AB::Expr::ONE); builder.assert_zero(main_current[6].clone().into() - AB::Expr::from_u64(4)); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/evaluators/evaluators_slice_plonky3.rs b/air-script/src/tests/evaluators/evaluators_slice_plonky3.rs index 62f822ede..cd19cef43 100644 --- a/air-script/src/tests/evaluators/evaluators_slice_plonky3.rs +++ b/air-script/src/tests/evaluators/evaluators_slice_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 20; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for EvaluatorsSliceAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -59,8 +60,6 @@ impl MidenAir for EvaluatorsSliceAir { builder.assert_zero(main_current[0].clone().into() * main_current[1].clone().into() * main_current[2].clone().into() * (main_current[3].clone().into() * main_current[3].clone().into() - main_current[3].clone().into())); builder.assert_zero(main_current[0].clone().into() * main_current[1].clone().into() * main_current[2].clone().into() * main_current[3].clone().into() * (main_current[4].clone().into() * main_current[4].clone().into() - main_current[4].clone().into())); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/evaluators/test_air_plonky3.rs b/air-script/src/tests/evaluators/test_air_plonky3.rs index 050ba860a..1d70dcb45 100644 --- a/air-script/src/tests/evaluators/test_air_plonky3.rs +++ b/air-script/src/tests/evaluators/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::evaluators::evaluators_plonky3::{EvaluatorsAir, MAIN_WIDTH}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -52,8 +51,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, EvaluatorsAir); diff --git a/air-script/src/tests/fibonacci/fibonacci_plonky3.rs b/air-script/src/tests/fibonacci/fibonacci_plonky3.rs index b5476e071..15e40b79d 100644 --- a/air-script/src/tests/fibonacci/fibonacci_plonky3.rs +++ b/air-script/src/tests/fibonacci/fibonacci_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 2; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for FibonacciAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -39,8 +40,6 @@ impl MidenAir for FibonacciAir { builder.when_transition().assert_zero(main_next[1].clone().into() - (main_current[0].clone().into() + main_current[1].clone().into())); builder.when_transition().assert_zero(main_next[0].clone().into() - main_current[1].clone().into()); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/fibonacci/test_air_plonky3.rs b/air-script/src/tests/fibonacci/test_air_plonky3.rs index 1d76e60d2..e41da1047 100644 --- a/air-script/src/tests/fibonacci/test_air_plonky3.rs +++ b/air-script/src/tests/fibonacci/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::fibonacci::fibonacci_plonky3::{FibonacciAir, MAIN_WIDTH}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 31; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -37,10 +36,44 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { + let zero = 0; let one = 1; - let last = 2178309; // 32nd Fibonacci number - vec![one, one, last] + let last = fibonacci_field::(512).as_canonical_u64(); // 512nd Fibonacci number in Goldilock's field + vec![zero, one, last] +} + +fn fibonacci_field(n: i32) -> F { + if n < 0 { + panic!("{} is negative!", n); + } else if n == 0 { + return F::ZERO; + } else if n == 1 { + return F::ONE; + } + + let mut sum = F::ZERO; + let mut last = F::ZERO; + let mut curr = F::ONE; + for _i in 1..n { + sum = last + curr; + last = curr; + curr = sum; + } + sum +} + +#[test] +fn test_goldilocks_fibonacci_computation() { + type F = p3_goldilocks::Goldilocks; + let f_32 = fibonacci_field::(32); + let f_512 = fibonacci_field::(512); + assert_eq!(f_32, F::new(2178309)); + assert_eq!(f_512, F::new(12556846397060607923)); +} + +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] } generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, FibonacciAir); diff --git a/air-script/src/tests/functions/functions_complex.air b/air-script/src/tests/functions/functions_complex.air index 2b512e262..e427b5b93 100644 --- a/air-script/src/tests/functions/functions_complex.air +++ b/air-script/src/tests/functions/functions_complex.air @@ -29,7 +29,7 @@ boundary_constraints { integrity_constraints { let f = get_multiplicity_flags(s0, s1); - let z = v^7 * f[3] + v^2 * f[2] + v * f[1] + f[0]; + let z = v^5 * f[3] + v^2 * f[2] + v * f[1] + f[0]; enf b_range' = b_range * (z * t - t + 1); let y = fold_scalar_and_vec(v, b); enf v' = y; diff --git a/air-script/src/tests/functions/functions_complex.rs b/air-script/src/tests/functions/functions_complex.rs index f165c2d0e..9a438bb07 100644 --- a/air-script/src/tests/functions/functions_complex.rs +++ b/air-script/src/tests/functions/functions_complex.rs @@ -47,7 +47,7 @@ impl Air for FunctionsAir { } fn new(trace_info: TraceInfo, public_inputs: PublicInputs, options: WinterProofOptions) -> Self { - let main_degrees = vec![TransitionConstraintDegree::new(11), TransitionConstraintDegree::new(1)]; + let main_degrees = vec![TransitionConstraintDegree::new(9), TransitionConstraintDegree::new(1)]; let aux_degrees = vec![]; let num_main_assertions = 1; let num_aux_assertions = 0; @@ -82,7 +82,7 @@ impl Air for FunctionsAir { fn evaluate_transition>(&self, frame: &EvaluationFrame, periodic_values: &[E], result: &mut [E]) { let main_current = frame.current(); let main_next = frame.next(); - result[0] = main_next[16] - main_current[16] * ((main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[1] * main_current[2] + main_current[3] * main_current[3] * (E::ONE - main_current[1]) * main_current[2] + main_current[3] * main_current[1] * (E::ONE - main_current[2]) + (E::ONE - main_current[1]) * (E::ONE - main_current[2])) * main_current[0] - main_current[0] + E::ONE); + result[0] = main_next[16] - main_current[16] * ((main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[1] * main_current[2] + main_current[3] * main_current[3] * (E::ONE - main_current[1]) * main_current[2] + main_current[3] * main_current[1] * (E::ONE - main_current[2]) + (E::ONE - main_current[1]) * (E::ONE - main_current[2])) * main_current[0] - main_current[0] + E::ONE); result[1] = main_next[3] - (main_current[4] + main_current[5] + main_current[6] + main_current[7] + main_current[8] + main_current[9] + main_current[10] + main_current[11] + main_current[12] + main_current[13] + main_current[14] + main_current[15] + E::ONE) * E::from(Felt::new(2_u64)); } diff --git a/air-script/src/tests/functions/functions_complex_plonky3.rs b/air-script/src/tests/functions/functions_complex_plonky3.rs index b42205283..238cc3741 100644 --- a/air-script/src/tests/functions/functions_complex_plonky3.rs +++ b/air-script/src/tests/functions/functions_complex_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 17; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for FunctionsAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -34,11 +35,9 @@ impl MidenAir for FunctionsAir { builder.when_first_row().assert_zero(main_current[3].clone().into()); // Main integrity/transition constraints - builder.when_transition().assert_zero(main_next[16].clone().into() - main_current[16].clone().into() * ((main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[1].clone().into() * main_current[2].clone().into() + main_current[3].clone().into() * main_current[3].clone().into() * (AB::Expr::ONE - main_current[1].clone().into()) * main_current[2].clone().into() + main_current[3].clone().into() * main_current[1].clone().into() * (AB::Expr::ONE - main_current[2].clone().into()) + (AB::Expr::ONE - main_current[1].clone().into()) * (AB::Expr::ONE - main_current[2].clone().into())) * main_current[0].clone().into() - main_current[0].clone().into() + AB::Expr::ONE)); + builder.when_transition().assert_zero(main_next[16].clone().into() - main_current[16].clone().into() * ((main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[3].clone().into() * main_current[1].clone().into() * main_current[2].clone().into() + main_current[3].clone().into() * main_current[3].clone().into() * (AB::Expr::ONE - main_current[1].clone().into()) * main_current[2].clone().into() + main_current[3].clone().into() * main_current[1].clone().into() * (AB::Expr::ONE - main_current[2].clone().into()) + (AB::Expr::ONE - main_current[1].clone().into()) * (AB::Expr::ONE - main_current[2].clone().into())) * main_current[0].clone().into() - main_current[0].clone().into() + AB::Expr::ONE)); builder.when_transition().assert_zero(main_next[3].clone().into() - (main_current[4].clone().into() + main_current[5].clone().into() + main_current[6].clone().into() + main_current[7].clone().into() + main_current[8].clone().into() + main_current[9].clone().into() + main_current[10].clone().into() + main_current[11].clone().into() + main_current[12].clone().into() + main_current[13].clone().into() + main_current[14].clone().into() + main_current[15].clone().into() + AB::Expr::ONE).double()); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/functions/functions_simple_plonky3.rs b/air-script/src/tests/functions/functions_simple_plonky3.rs index c5b131f49..1b72a7dfb 100644 --- a/air-script/src/tests/functions/functions_simple_plonky3.rs +++ b/air-script/src/tests/functions/functions_simple_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 9; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for FunctionsAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -43,8 +44,6 @@ impl MidenAir for FunctionsAir { builder.assert_zero(main_current[4].clone().into() + main_current[5].clone().into() + main_current[6].clone().into() + main_current[7].clone().into() - AB::Expr::ONE); builder.assert_zero((main_current[4].clone().into() + main_current[5].clone().into() + main_current[6].clone().into() + main_current[7].clone().into()) * AB::Expr::from_u64(4) - AB::Expr::ONE); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/functions/test_air_plonky3.rs b/air-script/src/tests/functions/test_air_plonky3.rs index f52390339..d9f6c39d6 100644 --- a/air-script/src/tests/functions/test_air_plonky3.rs +++ b/air-script/src/tests/functions/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::functions::functions_complex_plonky3::{FunctionsAir, MAIN_WIDTH}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -82,8 +81,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, FunctionsAir); diff --git a/air-script/src/tests/indexed_trace_access/indexed_trace_access_plonky3.rs b/air-script/src/tests/indexed_trace_access/indexed_trace_access_plonky3.rs index d1f6eb420..9b1bea28c 100644 --- a/air-script/src/tests/indexed_trace_access/indexed_trace_access_plonky3.rs +++ b/air-script/src/tests/indexed_trace_access/indexed_trace_access_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 4; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for TraceAccessAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -36,8 +37,6 @@ impl MidenAir for TraceAccessAir { // Main integrity/transition constraints builder.when_transition().assert_zero(main_next[0].clone().into() - (main_current[1].clone().into() + AB::Expr::ONE)); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/indexed_trace_access/test_air_plonky3.rs b/air-script/src/tests/indexed_trace_access/test_air_plonky3.rs index 4b0a31c39..74d0b60d4 100644 --- a/air-script/src/tests/indexed_trace_access/test_air_plonky3.rs +++ b/air-script/src/tests/indexed_trace_access/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::indexed_trace_access::indexed_trace_access_plonky3::{MAIN_WIDTH, TraceAccessAir}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -39,8 +38,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, TraceAccessAir); diff --git a/air-script/src/tests/list_comprehension/list_comprehension_nested_plonky3.rs b/air-script/src/tests/list_comprehension/list_comprehension_nested_plonky3.rs index 734706746..5525f2068 100644 --- a/air-script/src/tests/list_comprehension/list_comprehension_nested_plonky3.rs +++ b/air-script/src/tests/list_comprehension/list_comprehension_nested_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 2; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for ListComprehensionAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -38,8 +39,6 @@ impl MidenAir for ListComprehensionAir { builder.assert_zero(main_current[0].clone().into().double() + main_current[1].clone().into() * AB::Expr::from_u64(3) - AB::Expr::from_u64(5)); builder.assert_zero(main_current[0].clone().into() * AB::Expr::from_u64(3) + main_current[1].clone().into() * AB::Expr::from_u64(4) - AB::Expr::from_u64(7)); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/list_comprehension/list_comprehension_plonky3.rs b/air-script/src/tests/list_comprehension/list_comprehension_plonky3.rs index 727cc9cc0..9d13e2e8b 100644 --- a/air-script/src/tests/list_comprehension/list_comprehension_plonky3.rs +++ b/air-script/src/tests/list_comprehension/list_comprehension_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 16; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for ListComprehensionAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -41,8 +42,6 @@ impl MidenAir for ListComprehensionAir { builder.assert_zero(main_current[1].clone().into() - (main_current[5].clone().into() - main_current[8].clone().into() - main_current[12].clone().into() + AB::Expr::from_u64(10) + main_current[6].clone().into() - main_current[9].clone().into() - main_current[13].clone().into() + AB::Expr::from_u64(20) + main_current[7].clone().into() - main_current[10].clone().into() - main_current[14].clone().into())); builder.assert_zero(main_current[14].clone().into() - AB::Expr::from_u64(10)); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/list_comprehension/test_air_plonky3.rs b/air-script/src/tests/list_comprehension/test_air_plonky3.rs index a99c57065..42080ad1f 100644 --- a/air-script/src/tests/list_comprehension/test_air_plonky3.rs +++ b/air-script/src/tests/list_comprehension/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::list_comprehension::list_comprehension_plonky3::{ListComprehensionAir, MAIN_WIDTH}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -79,8 +78,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, ListComprehensionAir); diff --git a/air-script/src/tests/list_folding/list_folding_plonky3.rs b/air-script/src/tests/list_folding/list_folding_plonky3.rs index 1a455fdd9..44f4753a3 100644 --- a/air-script/src/tests/list_folding/list_folding_plonky3.rs +++ b/air-script/src/tests/list_folding/list_folding_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 17; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for ListFoldingAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -39,8 +40,6 @@ impl MidenAir for ListFoldingAir { builder.when_transition().assert_zero(main_next[7].clone().into() - (main_current[9].clone().into() * main_current[13].clone().into() + main_current[10].clone().into() * main_current[14].clone().into() + main_current[11].clone().into() * main_current[15].clone().into() + main_current[12].clone().into() * main_current[16].clone().into() + (main_current[9].clone().into() + main_current[13].clone().into()) * (main_current[10].clone().into() + main_current[14].clone().into()) * (main_current[11].clone().into() + main_current[15].clone().into()) * (main_current[12].clone().into() + main_current[16].clone().into()))); builder.when_transition().assert_zero(main_next[8].clone().into() - (main_current[1].clone().into() + main_current[9].clone().into() * main_current[13].clone().into() + main_current[10].clone().into() * main_current[14].clone().into() + main_current[11].clone().into() * main_current[15].clone().into() + main_current[12].clone().into() * main_current[16].clone().into() + main_current[9].clone().into() * main_current[13].clone().into() + main_current[10].clone().into() * main_current[14].clone().into() + main_current[11].clone().into() * main_current[15].clone().into() + main_current[12].clone().into() * main_current[16].clone().into())); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/list_folding/test_air_plonky3.rs b/air-script/src/tests/list_folding/test_air_plonky3.rs index a87dae25b..144e4f27b 100644 --- a/air-script/src/tests/list_folding/test_air_plonky3.rs +++ b/air-script/src/tests/list_folding/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::list_folding::list_folding_plonky3::{ListFoldingAir, MAIN_WIDTH}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -82,8 +81,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, ListFoldingAir); diff --git a/air-script/src/tests/periodic_columns/periodic_columns_plonky3.rs b/air-script/src/tests/periodic_columns/periodic_columns_plonky3.rs index 22acad484..df36acbd7 100644 --- a/air-script/src/tests/periodic_columns/periodic_columns_plonky3.rs +++ b/air-script/src/tests/periodic_columns/periodic_columns_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 3; pub const AUX_WIDTH: usize = 0; @@ -33,11 +33,12 @@ where F: Field, } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -51,8 +52,6 @@ where F: Field, builder.assert_zero_ext(AB::ExprEF::from(periodic_values[0].clone().into()) * (AB::ExprEF::from(main_current[1].clone().into()) + AB::ExprEF::from(main_current[2].clone().into()))); builder.when_transition().assert_zero_ext(AB::ExprEF::from(periodic_values[1].clone().into()) * (AB::ExprEF::from(main_next[0].clone().into()) - AB::ExprEF::from(main_current[0].clone().into()))); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/periodic_columns/test_air_plonky3.rs b/air-script/src/tests/periodic_columns/test_air_plonky3.rs index 42091fa46..d732ffbed 100644 --- a/air-script/src/tests/periodic_columns/test_air_plonky3.rs +++ b/air-script/src/tests/periodic_columns/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::periodic_columns::periodic_columns_plonky3::{MAIN_WIDTH, PeriodicColumnsAir}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -40,8 +39,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, PeriodicColumnsAir); diff --git a/air-script/src/tests/pub_inputs/pub_inputs_plonky3.rs b/air-script/src/tests/pub_inputs/pub_inputs_plonky3.rs index bbdef9bf9..4cc281a74 100644 --- a/air-script/src/tests/pub_inputs/pub_inputs_plonky3.rs +++ b/air-script/src/tests/pub_inputs/pub_inputs_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 4; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for PubInputsAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -43,8 +44,6 @@ impl MidenAir for PubInputsAir { // Main integrity/transition constraints builder.when_transition().assert_zero(main_next[0].clone().into() - (main_current[1].clone().into() + main_current[2].clone().into())); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/pub_inputs/test_air_plonky3.rs b/air-script/src/tests/pub_inputs/test_air_plonky3.rs index 8595358b4..2a7ad24d0 100644 --- a/air-script/src/tests/pub_inputs/test_air_plonky3.rs +++ b/air-script/src/tests/pub_inputs/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::pub_inputs::pub_inputs_plonky3::{MAIN_WIDTH, PubInputsAir}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -43,8 +42,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![0; 32] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, PubInputsAir); diff --git a/air-script/src/tests/selectors/selectors_combine_complex_plonky3.rs b/air-script/src/tests/selectors/selectors_combine_complex_plonky3.rs index 7714372f2..a89f39d38 100644 --- a/air-script/src/tests/selectors/selectors_combine_complex_plonky3.rs +++ b/air-script/src/tests/selectors/selectors_combine_complex_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 6; pub const AUX_WIDTH: usize = 1; @@ -29,7 +29,13 @@ where F: Field, AUX_WIDTH } - fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { + fn bus_types(&self) -> Vec { + vec![ + BusType::Multiset, + ] + } + + fn build_aux_trace(&self, _main: &RowMajorMatrix, _challenges: &[EF]) -> Option> { // Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders. let num_rows = _main.height(); @@ -66,15 +72,17 @@ where F: Field, rows[i+1][j] = next_row[j]; } } - Some(trace) + let trace_f = trace.flatten_to_base(); + Some(trace_f) } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -97,10 +105,6 @@ where F: Field, builder.assert_zero((AB::Expr::ONE - main_current[0].clone().into()) * (main_current[5].clone().into() - AB::Expr::from_u64(5)) + main_current[0].clone().into() * (main_current[4].clone().into() - AB::Expr::from_u64(4))); builder.assert_zero(main_current[0].clone().into() * (main_current[5].clone().into() - AB::Expr::from_u64(20)) + (AB::Expr::ONE - main_current[0].clone().into()) * main_current[1].clone().into() * (main_current[4].clone().into() - AB::Expr::from_u64(31))); - // Aux boundary constraints - builder.when_first_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); - builder.when_last_row().assert_zero_ext(AB::ExprEF::from(aux_current[0].clone().into()) - AB::ExprEF::ONE); - // Aux integrity/transition constraints builder.when_transition().assert_zero_ext(((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * AB::ExprEF::from(main_current[0].clone().into()) * AB::ExprEF::from(main_current[5].clone().into()) + AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into()) * AB::ExprEF::from(main_current[5].clone().into())) * ((alpha.into() + beta_challenges[0].into() + beta_challenges[1].into().double()) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(main_current[1].clone().into()) * AB::ExprEF::from(main_current[5].clone().into()) + AB::ExprEF::ONE - (AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * AB::ExprEF::from(main_current[1].clone().into()) * AB::ExprEF::from(main_current[5].clone().into())) * AB::ExprEF::from(aux_current[0].clone().into()) - ((alpha.into() + AB::ExprEF::from_u64(3) * beta_challenges[0].into() + AB::ExprEF::from_u64(4) * beta_challenges[1].into()) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[1].clone().into())) * AB::ExprEF::from(main_current[4].clone().into()) + AB::ExprEF::ONE - (AB::ExprEF::ONE - AB::ExprEF::from(main_current[0].clone().into())) * (AB::ExprEF::ONE - AB::ExprEF::from(main_current[1].clone().into())) * AB::ExprEF::from(main_current[4].clone().into())) * AB::ExprEF::from(aux_next[0].clone().into())); } diff --git a/air-script/src/tests/selectors/selectors_combine_simple_plonky3.rs b/air-script/src/tests/selectors/selectors_combine_simple_plonky3.rs index df958a51e..ed223440f 100644 --- a/air-script/src/tests/selectors/selectors_combine_simple_plonky3.rs +++ b/air-script/src/tests/selectors/selectors_combine_simple_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 4; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for SelectorsAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -37,8 +38,6 @@ impl MidenAir for SelectorsAir { builder.when_transition().assert_zero(main_next[1].clone().into() - main_current[2].clone().into()); builder.when_transition().assert_zero(main_current[3].clone().into() * (main_next[0].clone().into() - (main_current[0].clone().into() + main_current[1].clone().into())) + (AB::Expr::ONE - main_current[3].clone().into()) * (main_next[0].clone().into() - main_current[0].clone().into() * main_current[1].clone().into())); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs b/air-script/src/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs index c7c4e3940..d482f2c9d 100644 --- a/air-script/src/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs +++ b/air-script/src/tests/selectors/selectors_combine_with_list_comprehensions_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 6; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for SelectorsAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -38,8 +39,6 @@ impl MidenAir for SelectorsAir { builder.assert_zero((AB::Expr::ONE - main_current[0].clone().into()) * (main_current[5].clone().into() - AB::Expr::from_u64(8)) + main_current[0].clone().into() * (main_current[4].clone().into() - AB::Expr::from_u64(2))); builder.assert_zero(main_current[0].clone().into() * (main_current[5].clone().into() - AB::Expr::from_u64(4)) + (AB::Expr::ONE - main_current[0].clone().into()) * main_current[1].clone().into() * (main_current[4].clone().into() - AB::Expr::from_u64(6))); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/selectors/selectors_plonky3.rs b/air-script/src/tests/selectors/selectors_plonky3.rs index 51f70004b..e16eb2f28 100644 --- a/air-script/src/tests/selectors/selectors_plonky3.rs +++ b/air-script/src/tests/selectors/selectors_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 4; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for SelectorsAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -37,8 +38,6 @@ impl MidenAir for SelectorsAir { builder.when_transition().assert_zero(main_current[0].clone().into() * (AB::Expr::ONE - main_current[1].clone().into()) * main_next[3].clone().into()); builder.when_transition().assert_zero(main_current[0].clone().into() * main_current[1].clone().into() * main_current[2].clone().into() * (main_next[3].clone().into() - main_current[3].clone().into()) + (AB::Expr::ONE - main_current[1].clone().into()) * (AB::Expr::ONE - main_current[2].clone().into()) * (main_next[3].clone().into() - AB::Expr::ONE)); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/selectors/selectors_with_evaluators_plonky3.rs b/air-script/src/tests/selectors/selectors_with_evaluators_plonky3.rs index 1dde4fecf..42affcf13 100644 --- a/air-script/src/tests/selectors/selectors_with_evaluators_plonky3.rs +++ b/air-script/src/tests/selectors/selectors_with_evaluators_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 4; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for SelectorsAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -37,8 +38,6 @@ impl MidenAir for SelectorsAir { builder.when_transition().assert_zero(main_current[0].clone().into() * (AB::Expr::ONE - main_current[1].clone().into()) * main_next[3].clone().into()); builder.when_transition().assert_zero(main_current[1].clone().into() * main_current[2].clone().into() * main_current[0].clone().into() * (main_next[3].clone().into() - main_current[3].clone().into()) + (AB::Expr::ONE - main_current[1].clone().into()) * (AB::Expr::ONE - main_current[2].clone().into()) * (main_next[3].clone().into() - AB::Expr::ONE)); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/selectors/test_air_plonky3.rs b/air-script/src/tests/selectors/test_air_plonky3.rs index ef3c01f81..c8cfbffa2 100644 --- a/air-script/src/tests/selectors/test_air_plonky3.rs +++ b/air-script/src/tests/selectors/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::selectors::selectors_with_evaluators_plonky3::{MAIN_WIDTH, SelectorsAir}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -43,8 +42,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, SelectorsAir); diff --git a/air-script/src/tests/system/system_plonky3.rs b/air-script/src/tests/system/system_plonky3.rs index 574bccd9b..acc5e98be 100644 --- a/air-script/src/tests/system/system_plonky3.rs +++ b/air-script/src/tests/system/system_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 3; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for SystemAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -36,8 +37,6 @@ impl MidenAir for SystemAir { // Main integrity/transition constraints builder.when_transition().assert_zero(main_next[0].clone().into() - (main_current[0].clone().into() + AB::Expr::ONE)); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/system/test_air_plonky3.rs b/air-script/src/tests/system/test_air_plonky3.rs index 404ea03d7..952a7412f 100644 --- a/air-script/src/tests/system/test_air_plonky3.rs +++ b/air-script/src/tests/system/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::system::system_plonky3::{MAIN_WIDTH, SystemAir}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -40,8 +39,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, SystemAir); diff --git a/air-script/src/tests/trace_col_groups/test_air_plonky3.rs b/air-script/src/tests/trace_col_groups/test_air_plonky3.rs index 1b4522ecf..920a7f3db 100644 --- a/air-script/src/tests/trace_col_groups/test_air_plonky3.rs +++ b/air-script/src/tests/trace_col_groups/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::trace_col_groups::trace_col_groups_plonky3::{MAIN_WIDTH, TraceColGroupAir}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -58,8 +57,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 16] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, TraceColGroupAir); diff --git a/air-script/src/tests/trace_col_groups/trace_col_groups_plonky3.rs b/air-script/src/tests/trace_col_groups/trace_col_groups_plonky3.rs index 026304e2d..5a0b38979 100644 --- a/air-script/src/tests/trace_col_groups/trace_col_groups_plonky3.rs +++ b/air-script/src/tests/trace_col_groups/trace_col_groups_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 9; pub const AUX_WIDTH: usize = 0; @@ -19,11 +19,12 @@ impl MidenAir for TraceColGroupAir { } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -37,8 +38,6 @@ impl MidenAir for TraceColGroupAir { builder.when_transition().assert_zero(main_next[2].clone().into() - (main_current[2].clone().into() + AB::Expr::ONE)); builder.when_transition().assert_zero(main_next[1].clone().into() - (main_current[1].clone().into() - AB::Expr::ONE)); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/air-script/src/tests/variables/test_air_plonky3.rs b/air-script/src/tests/variables/test_air_plonky3.rs index b8d2d88ef..356a4d9fb 100644 --- a/air-script/src/tests/variables/test_air_plonky3.rs +++ b/air-script/src/tests/variables/test_air_plonky3.rs @@ -3,12 +3,11 @@ use p3_miden_air::RowMajorMatrix; use crate::{ generate_air_plonky3_test_with_airscript_traits, - test_utils::plonky3_traits::check_constraints_with_airscript_traits, tests::variables::variables_plonky3::{MAIN_WIDTH, VariablesAir}, }; -pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { - let num_rows = 32; +pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix { + let num_rows = 512; let trace_length = num_rows * MAIN_WIDTH; let mut long_trace = F::zero_vec(trace_length); @@ -43,8 +42,12 @@ pub fn generate_trace_rows(inputs: Vec) -> RowMajorMatrix< trace } -fn generate_inputs() -> Vec { +fn generate_inputs() -> Vec { vec![1; 32] } +fn generate_var_len_pub_inputs<'a>() -> Vec>> { + vec![] +} + generate_air_plonky3_test_with_airscript_traits!(test_air_plonky3, VariablesAir); diff --git a/air-script/src/tests/variables/variables_plonky3.rs b/air-script/src/tests/variables/variables_plonky3.rs index bfe0da908..57cbc460d 100644 --- a/air-script/src/tests/variables/variables_plonky3.rs +++ b/air-script/src/tests/variables/variables_plonky3.rs @@ -2,7 +2,7 @@ use p3_field::{ExtensionField, Field, PrimeCharacteristicRing}; use p3_matrix::Matrix; use p3_matrix::dense::RowMajorMatrixView; use p3_matrix::stack::VerticalPair; -use p3_miden_air::{MidenAir, MidenAirBuilder, RowMajorMatrix}; +use p3_miden_air::{BusType, MidenAir, MidenAirBuilder, RowMajorMatrix}; pub const MAIN_WIDTH: usize = 4; pub const AUX_WIDTH: usize = 0; @@ -32,11 +32,12 @@ where F: Field, } fn eval(&self, builder: &mut AB) - where AB: MidenAirBuilder, + where AB: MidenAirBuilder, { let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect("Wrong number of public values"); let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect("Wrong number of periodic values"); - let preprocessed = builder.preprocessed(); + // Note: for now, we do not have any preprocessed values + // let preprocessed = builder.preprocessed(); let main = builder.main(); let (main_current, main_next) = ( main.row_slice(0).unwrap(), @@ -53,8 +54,6 @@ where F: Field, builder.assert_zero((AB::Expr::ONE - main_current[0].clone().into()) * (main_current[3].clone().into() - main_current[1].clone().into() - main_current[2].clone().into()) - (AB::Expr::from_u64(6) - (AB::Expr::from_u64(7) - main_current[0].clone().into()))); builder.when_transition().assert_zero(main_current[0].clone().into() * (main_current[3].clone().into() - main_current[1].clone().into() * main_current[2].clone().into()) - (AB::Expr::ONE - main_next[0].clone().into())); - // Aux boundary constraints - // Aux integrity/transition constraints } } \ No newline at end of file diff --git a/codegen/plonky3/src/air/boundary_constraints.rs b/codegen/plonky3/src/air/boundary_constraints.rs index aba2206b0..79a4f4f7a 100644 --- a/codegen/plonky3/src/air/boundary_constraints.rs +++ b/codegen/plonky3/src/air/boundary_constraints.rs @@ -13,6 +13,7 @@ pub(super) fn add_main_boundary_constraints(eval_func: &mut Function, ir: &Air) } } +#[allow(dead_code)] /// Adds the aux boundary constraints to the generated code. pub(super) fn add_aux_boundary_constraints(eval_func: &mut Function, ir: &Air) { eval_func.line(""); diff --git a/codegen/plonky3/src/air/mod.rs b/codegen/plonky3/src/air/mod.rs index 98b881f70..32a585ce9 100644 --- a/codegen/plonky3/src/air/mod.rs +++ b/codegen/plonky3/src/air/mod.rs @@ -6,7 +6,7 @@ use air_ir::Air; use super::Scope; use crate::air::{ - boundary_constraints::{add_aux_boundary_constraints, add_main_boundary_constraints}, + boundary_constraints::add_main_boundary_constraints, graph::Codegen, integrity_constraints::{add_aux_integrity_constraints, add_main_integrity_constraints}, }; @@ -45,8 +45,13 @@ fn add_constants(scope: &mut Scope, ir: &Air) { let aux_width = ir.trace_segment_widths.get(1).cloned().unwrap_or(0); let num_periodic_values = ir.periodic_columns().count(); let period = ir.periodic_columns().map(|col| col.period()).max().unwrap_or(0); - let num_public_values = - ir.public_inputs().map(|public_input| public_input.size()).sum::(); + let num_public_values = ir + .public_inputs() + .map(|public_input| match public_input { + air_ir::PublicInput::Vector { size, .. } => size, + air_ir::PublicInput::Table { .. } => &0, + }) + .sum::(); let max_beta_challenge_power = ir.num_random_values.saturating_sub(1); let constants = [ @@ -112,6 +117,17 @@ fn add_air_struct(scope: &mut Scope, ir: &Air, name: &str) { .line("1 + MAX_BETA_CHALLENGE_POWER"); miden_air_impl.new_fn("aux_width").arg_ref_self().ret("usize").line("AUX_WIDTH"); + + let bus_types_fn = miden_air_impl.new_fn("bus_types").arg_ref_self().ret("Vec"); + bus_types_fn.line("vec!["); + for (_id, bus) in &ir.buses { + let bus_type_str = match bus.bus_type { + air_ir::BusType::Multiset => "BusType::Multiset", + air_ir::BusType::Logup => "BusType::Logup", + }; + bus_types_fn.line(format!(" {bus_type_str},")); + } + bus_types_fn.line("]"); } // add the build_aux_trace function if needed @@ -121,7 +137,7 @@ fn add_air_struct(scope: &mut Scope, ir: &Air, name: &str) { .arg_ref_self() .arg("_main", "&RowMajorMatrix") .arg("_challenges", "&[EF]") - .ret("Option>"); + .ret("Option>"); build_aux_trace_func.line("// Note: consider using Some(build_aux_trace_with_miden_vm::(_main, _challenges, module)) if you want to build the aux trace using Miden VM aux trace builders."); build_aux_trace_func.line(""); build_aux_trace_func.line("let num_rows = _main.height();"); @@ -158,19 +174,22 @@ fn add_air_struct(scope: &mut Scope, ir: &Air, name: &str) { build_aux_trace_func.line(" rows[i+1][j] = next_row[j];"); build_aux_trace_func.line(" }"); build_aux_trace_func.line("}"); - build_aux_trace_func.line("Some(trace)"); + build_aux_trace_func.line("let trace_f = trace.flatten_to_base();"); + build_aux_trace_func.line("Some(trace_f)"); } // add the eval function let eval_func = miden_air_impl .new_fn("eval") .generic("AB") - .bound("AB", "MidenAirBuilder") + .bound("AB", "MidenAirBuilder") .arg_ref_self() .arg("builder", "&mut AB"); eval_func.line("let public_values: [_; NUM_PUBLIC_VALUES] = builder.public_values().try_into().expect(\"Wrong number of public values\");"); eval_func.line("let periodic_values: [_; NUM_PERIODIC_VALUES] = builder.periodic_evals().try_into().expect(\"Wrong number of periodic values\");"); - eval_func.line("let preprocessed = builder.preprocessed();"); + + eval_func.line("// Note: for now, we do not have any preprocessed values"); + eval_func.line("// let preprocessed = builder.preprocessed();"); eval_func.line("let main = builder.main();"); eval_func.line("let (main_current, main_next) = ("); @@ -194,7 +213,8 @@ fn add_air_struct(scope: &mut Scope, ir: &Air, name: &str) { add_main_integrity_constraints(eval_func, ir); - add_aux_boundary_constraints(eval_func, ir); + // Note: Plonky3 automatically adds aux boundary constraints + //add_aux_boundary_constraints(eval_func, ir); add_aux_integrity_constraints(eval_func, ir); } diff --git a/codegen/plonky3/src/imports.rs b/codegen/plonky3/src/imports.rs index 8655c7161..d96c0dd40 100644 --- a/codegen/plonky3/src/imports.rs +++ b/codegen/plonky3/src/imports.rs @@ -9,6 +9,7 @@ pub(super) fn add_imports(scope: &mut Scope) { scope.import("p3_matrix", "Matrix"); scope.import("p3_matrix::dense", "RowMajorMatrixView"); scope.import("p3_matrix::stack", "VerticalPair"); + scope.import("p3_miden_air", "BusType"); scope.import("p3_miden_air", "MidenAir"); scope.import("p3_miden_air", "MidenAirBuilder"); scope.import("p3_miden_air", "RowMajorMatrix"); diff --git a/parser/src/ast/module.rs b/parser/src/ast/module.rs index 323eaf417..9ffbb41ae 100644 --- a/parser/src/ast/module.rs +++ b/parser/src/ast/module.rs @@ -435,9 +435,6 @@ impl Module { conflicting_declaration(diagnostics, "function", prev.span(), function.name.span()); return Err(SemanticAnalysisError::NameConflict(function.name.span())); } - - println!("Declared function: {:?}", function.name); - self.functions.insert(function.name, function); Ok(())