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