diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..0c04c5309 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.configureOnOpen": false +} diff --git a/Cargo.toml b/Cargo.toml index 587b1b7e0..03e3c8f6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] -members = ["math", "crypto", "gpu", "benches", "provers/plonk", "provers/stark", "provers/cairo", "provers/groth16", "provers/groth16/arkworks-adapter", "provers/groth16/circom-adapter", "examples/merkle-tree-cli", "examples/prove-miden", "provers/winterfell_adapter", "examples/shamir_secret_sharing", "examples/prove-verify-circom", "provers/cairo/ffi"] +members = ["math", "crypto", "gpu", "benches", "provers/plonk", "provers/stark", "provers/cairo", "provers/groth16", "provers/groth16/arkworks-adapter", "provers/groth16/circom-adapter", "examples/merkle-tree-cli", "examples/prove-miden", "provers/winterfell_adapter", "examples/shamir_secret_sharing", "examples/prove-verify-circom", "exercises/air_vm_workshop", "provers/cairo/ffi"] exclude = ["ensure-no_std"] resolver = "2" diff --git a/docs/src/starks/api.md b/docs/src/starks/api.md index 275696925..87e811bbe 100644 --- a/docs/src/starks/api.md +++ b/docs/src/starks/api.md @@ -127,7 +127,6 @@ let context = AirContext { }, trace_columns: trace_table.n_cols, transition_degrees: vec![1], - transition_exemptions: vec![2], transition_offsets: vec![0, 1, 2], num_transition_constraints: 1, }; diff --git a/examples/prove-gnark-plonk/go_exporter_example/frontend_precomputed_values.json b/examples/prove-gnark-plonk/go_exporter_example/frontend_precomputed_values.json new file mode 100644 index 000000000..9a3412b82 --- /dev/null +++ b/examples/prove-gnark-plonk/go_exporter_example/frontend_precomputed_values.json @@ -0,0 +1,100 @@ +{ + "N": 5, + "N_Padded": 8, + "Omega": "345766f603fa66e78c0625cd70d77ce2b38b21c28713b7007228fd3397743f7a", + "Input": [ + "3", + "1b" + ], + "Ql": [ + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000", + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000", + "0", + "0", + "1" + ], + "Qr": [ + "0", + "0", + "0", + "0", + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000" + ], + "Qm": [ + "0", + "0", + "1", + "1", + "0" + ], + "Qo": [ + "0", + "0", + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000", + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000", + "0" + ], + "Qc": [ + "0", + "0", + "0", + "0", + "0" + ], + "A": [ + "3", + "1b", + "3", + "9", + "1b", + "3", + "3", + "3" + ], + "B": [ + "3", + "3", + "3", + "3", + "1b", + "3", + "3", + "3" + ], + "C": [ + "3", + "3", + "9", + "1b", + "3", + "3", + "3", + "3" + ], + "Permutation": [ + 23, + 4, + 0, + 18, + 1, + 2, + 5, + 6, + 7, + 8, + 9, + 10, + 19, + 11, + 13, + 14, + 15, + 16, + 3, + 12, + 17, + 20, + 21, + 22 + ] +} \ No newline at end of file diff --git a/examples/prove-gnark-plonk/go_exporter_example/witness.json b/examples/prove-gnark-plonk/go_exporter_example/witness.json new file mode 100644 index 000000000..f3c570a5f --- /dev/null +++ b/examples/prove-gnark-plonk/go_exporter_example/witness.json @@ -0,0 +1 @@ +{"witness":["3","27"]} \ No newline at end of file diff --git a/exercises/air_vm_workshop/Cargo.toml b/exercises/air_vm_workshop/Cargo.toml new file mode 100644 index 000000000..0f54545d2 --- /dev/null +++ b/exercises/air_vm_workshop/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "mini_air_vm" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true + +[[bin]] +name = "mini-air-cli" +path = "src/main.rs" + +[dependencies] +lambdaworks-math = { workspace = true } +lambdaworks-crypto = { workspace = true } +stark-platinum-prover = {workspace = true } diff --git a/exercises/air_vm_workshop/README.md b/exercises/air_vm_workshop/README.md new file mode 100644 index 000000000..327b9ed16 --- /dev/null +++ b/exercises/air_vm_workshop/README.md @@ -0,0 +1,5 @@ +
+ +# Lambdaworks Circom Proving & Verification Example + +This programs converts Circom & SnarkJS generated constraints and witnesses into Lambdaworks-compatible instances, performs trusted setup, generates proof, and finally verifies the integrity of witness assignments. diff --git a/exercises/air_vm_workshop/src/main.rs b/exercises/air_vm_workshop/src/main.rs new file mode 100644 index 000000000..ee0714f0c --- /dev/null +++ b/exercises/air_vm_workshop/src/main.rs @@ -0,0 +1,301 @@ + +use lambdaworks_crypto::fiat_shamir::default_transcript::DefaultTranscript; +use stark_platinum_prover::{ + constraints::{ + boundary::BoundaryConstraints, + transition::TransitionConstraint, + }, context::AirContext, frame::Frame, proof::options::ProofOptions, prover::{IsStarkProver, Prover}, trace::TraceTable, traits::AIR, verifier::{IsStarkVerifier, Verifier} +}; +use lambdaworks_math::field::{element::FieldElement, fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, traits::IsFFTField}; +use std::marker::PhantomData; + + +const STEP_SIZE: usize = 1; +const NUMBER_OF_COLUMNS: usize = 7; + +#[derive(Clone)] +struct FlagIsBinary { + phantom: PhantomData, +} + +impl FlagIsBinary { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl TransitionConstraint for FlagIsBinary +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + todo!() + } + + fn constraint_idx(&self) -> usize { + 0 + } + + fn end_exemptions(&self) -> usize { + todo!() + } + + fn evaluate( + &self, + frame: &Frame, + transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + todo!() + } +} + + +#[derive(Clone)] +struct OperationIsCorrect { + phantom: PhantomData, +} + +impl OperationIsCorrect { + pub fn new() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl TransitionConstraint for OperationIsCorrect +where + F: IsFFTField + Send + Sync, +{ + fn degree(&self) -> usize { + todo!() + } + + fn constraint_idx(&self) -> usize { + 1 + } + + fn end_exemptions(&self) -> usize { + todo!() + } + + fn evaluate( + &self, + _frame: &Frame, + _transition_evaluations: &mut [FieldElement], + _periodic_values: &[FieldElement], + _rap_challenges: &[FieldElement], + ) { + todo!() + } +} + +pub struct VM0Air +where + F: IsFFTField, +{ + context: AirContext, + trace_length: usize, + constraints: Vec>>, + public_inputs: VM0PubInputs +} + + +// We won't use this, but the general AIR assumes there will be public inputs +#[derive(Clone, Debug)] +pub struct VM0PubInputs +where F: IsFFTField { + _dummy: FieldElement +} + +impl VM0PubInputs where F: IsFFTField { + pub fn default() -> Self { + Self { + _dummy: FieldElement::::zero() + } + } + +} + +impl AIR for VM0Air +where + F: IsFFTField + Send + Sync + 'static, +{ + type Field = F; + type FieldExtension = F; + // This is not used in this example + type PublicInputs = VM0PubInputs; + + const STEP_SIZE: usize = 1; + + fn new( + trace_length: usize, + // unused + pub_inputs: &Self::PublicInputs, + proof_options: &ProofOptions, + ) -> Self { + + let constraints: Vec>> = + vec![ + Box::new(OperationIsCorrect::new()), + Box::new(FlagIsBinary::new()) + ]; + + let context = AirContext { + proof_options: proof_options.clone(), + trace_columns: NUMBER_OF_COLUMNS, + // These are the relative indexes of rows needed to evaluate the constraints, in this case we need two consecutives rows so 0 and 1 is good. + transition_offsets: vec![0, 1], + num_transition_constraints: constraints.len(), + }; + + Self { + context, + trace_length, + constraints, + public_inputs: pub_inputs.clone() + } + } + + fn composition_poly_degree_bound(&self) -> usize { + self.trace_length() + } + + fn transition_constraints(&self) -> &Vec>> { + &self.constraints + } + + fn context(&self) -> &AirContext { + &self.context + } + + fn trace_length(&self) -> usize { + self.trace_length + } + + // For the first example + fn trace_layout(&self) -> (usize, usize) { + (NUMBER_OF_COLUMNS, 0) + } + + fn pub_inputs(&self) -> &Self::PublicInputs { + &self.public_inputs + } + + // Rap is not used in this example + fn boundary_constraints( + &self, + _rap_challenges: &[FieldElement], + ) -> BoundaryConstraints { + todo!() + } + + // This function can just call compute_transition_prover for this examples. It will be unified in just one compute_transition in the future. + fn compute_transition_verifier( + &self, + frame: &Frame, + periodic_values: &[FieldElement], + rap_challenges: &[FieldElement], + ) -> Vec> { + self.compute_transition_prover(frame, periodic_values, rap_challenges) + } +} + + +// Flag, A0, V0, A1, V1, A DST, V DST +pub fn vm0_example_trace( +) -> TraceTable { + + let row0: Vec> = vec![ + FieldElement::::from(0), + FieldElement::::from(0), + FieldElement::::from(3), + FieldElement::::from(1), + FieldElement::::from(3), + FieldElement::::from(2), + FieldElement::::from(6) + ]; + + let row1: Vec> = vec![ + FieldElement::::from(1), + FieldElement::::from(4), + FieldElement::::from(3), + FieldElement::::from(5), + FieldElement::::from(3), + FieldElement::::from(6), + FieldElement::::from(9) + ]; + + + let row2: Vec> = vec![ + FieldElement::::from(0), + FieldElement::::from(6), + FieldElement::::from(9), + FieldElement::::from(2), + FieldElement::::from(6), + FieldElement::::from(7), + FieldElement::::from(15) + ]; + + // Trace length needs to be a power of 2 for FFT to work + // We pad it with another equal to the last one + // In a real VM this can be solved by adding a jmp rel 0 for example so the padding is valid, or some extra NOPs + let row3 = row2.clone(); + + let mut trace_data: Vec> = Vec::new(); + trace_data.extend(row0); + trace_data.extend(row1); + trace_data.extend(row2); + trace_data.extend(row3); + + TraceTable::new_main(trace_data, NUMBER_OF_COLUMNS, STEP_SIZE) +} + +fn main() { + let mut trace: TraceTable = vm0_example_trace(); + + let row0_string: Vec = trace.get_column_main(0).iter().map(|x| x.to_string()).collect(); + let row1_string: Vec = trace.get_column_main(1).iter().map(|x| x.to_string()).collect(); + let row6_string: Vec = trace.get_column_main(6).iter().map(|x| x.to_string()).collect(); + + println!("First row of trace: {:?}", row0_string); + println!("Second row of trace: {:?}", row1_string); + println!("..."); + println!("Sixth row row of trace: {:?}", row6_string); + + // This can always be 3 + let coset_offset = 3; + let proof_options = ProofOptions::new_secure(stark_platinum_prover::proof::options::SecurityLevel::Conjecturable100Bits, coset_offset); + + let pub_inputs = VM0PubInputs::default(); + + println!("Generating proof ..."); + let proof_result = Prover::>::prove( + &mut trace, + &pub_inputs, + &proof_options, + DefaultTranscript::default() + ); + + let proof = match proof_result { + Ok(x) => x, + Err(_) => { + println!("Error while generating the proof"); + return + }, + }; + + println!("Done!"); + println!("Verifying proof ..."); + + assert!(Verifier::>::verify( + &proof, + &pub_inputs, + &proof_options, + DefaultTranscript::default() + )); +} diff --git a/objects.py b/objects.py new file mode 100644 index 000000000..8438e1329 --- /dev/null +++ b/objects.py @@ -0,0 +1,395 @@ +import dataclasses +from abc import abstractmethod +from dataclasses import field +from typing import ClassVar, Dict, List, Optional, Type + +import marshmallow +import marshmallow.fields as mfields +import marshmallow_dataclass +from marshmallow_oneofschema import OneOfSchema + +from starkware.cairo.lang.compiler.program import Program, ProgramBase, StrippedProgram +from starkware.cairo.lang.vm.cairo_pie import CairoPie +from starkware.starkware_utils.marshmallow_dataclass_fields import additional_metadata +from starkware.starkware_utils.validated_dataclass import ValidatedMarshmallowDataclass + + +class TaskSpec(ValidatedMarshmallowDataclass): + """ + Contains task's specification. + """ + + @abstractmethod + def load_task(self) -> "Task": + """ + Returns the corresponding task. + """ + + +class Task: + @abstractmethod + def get_program(self) -> ProgramBase: + """ + Returns the task's Cairo program. + """ + + +@marshmallow_dataclass.dataclass(frozen=True) +class RunProgramTask(TaskSpec, Task): + TYPE: ClassVar[str] = "RunProgramTask" + program: Program + program_input: dict + use_poseidon: bool + + def get_program(self) -> Program: + return self.program + + def load_task(self) -> "Task": + return self + + +@marshmallow_dataclass.dataclass(frozen=True) +class CairoPiePath(TaskSpec): + TYPE: ClassVar[str] = "CairoPiePath" + path: str + use_poseidon: bool + + def load_task(self) -> "CairoPieTask": + """ + Loads the PIE to memory. + """ + return CairoPieTask(cairo_pie=CairoPie.from_file(self.path), use_poseidon=self.use_poseidon) + + +class TaskSchema(OneOfSchema): + """ + Schema for Task/CairoPiePath. + OneOfSchema adds a "type" field. + """ + + type_schemas: Dict[str, Type[marshmallow.Schema]] = { + RunProgramTask.TYPE: RunProgramTask.Schema, + CairoPiePath.TYPE: CairoPiePath.Schema, + } + + def get_obj_type(self, obj): + return obj.TYPE + + +@dataclasses.dataclass(frozen=True) +class CairoPieTask(Task): + cairo_pie: CairoPie + use_poseidon: bool + + def get_program(self) -> StrippedProgram: + return self.cairo_pie.program + + +@marshmallow_dataclass.dataclass(frozen=True) +class SimpleBootloaderInput(ValidatedMarshmallowDataclass): + tasks: List[TaskSpec] = field( + metadata=additional_metadata(marshmallow_field=mfields.List(mfields.Nested(TaskSchema))) + ) + fact_topologies_path: Optional[str] + + # If true, the bootloader will put all the outputs in a single page, ignoring the + # tasks' fact topologies. + single_page: bool +295 changes: 295 additions & 0 deletions 295 +src/starkware/cairo/bootloaders/simple_bootloader/utils.py +@@ -0,0 +1,295 @@ +import json +import os +from typing import Any, List, Union + +import aiofiles + +from starkware.cairo.bootloaders.fact_topology import ( + FactTopologiesFile, + FactTopology, + get_fact_topology_from_additional_data, +) +from starkware.cairo.bootloaders.simple_bootloader.objects import CairoPieTask, RunProgramTask, Task +from starkware.cairo.common.hash_state import compute_hash_on_elements +from starkware.cairo.lang.builtins.all_builtins import ALL_BUILTINS +from starkware.cairo.lang.compiler.program import Program +from starkware.cairo.lang.vm.cairo_pie import CairoPie, ExecutionResources +from starkware.cairo.lang.vm.output_builtin_runner import OutputBuiltinRunner +from starkware.cairo.lang.vm.relocatable import MaybeRelocatable, RelocatableValue, relocate_value +from starkware.python.utils import WriteOnceDict, from_bytes + +SIMPLE_BOOTLOADER_COMPILED_PATH = os.path.join( + os.path.dirname(__file__), "simple_bootloader_compiled.json" +) + +# Upper bounds on the numbers of builtin instances and steps that the simple_bootloader uses. +SIMPLE_BOOTLOADER_N_OUTPUT = 2 +SIMPLE_BOOTLOADER_N_PEDERSEN = 20 +SIMPLE_BOOTLOADER_N_RANGE_CHECKS = 20 +SIMPLE_BOOTLOADER_N_STEPS_CONSTANT = 400 +SIMPLE_BOOTLOADER_N_STEPS_RATIO = 8 + + +async def get_simple_bootloader_program_json() -> str: + async with aiofiles.open(SIMPLE_BOOTLOADER_COMPILED_PATH, "r") as file: + return json.loads(await file.read()) + + +async def get_simple_bootloader_program() -> Program: + async with aiofiles.open(SIMPLE_BOOTLOADER_COMPILED_PATH, "r") as file: + return Program.Schema().loads(await file.read()) + + +async def get_simple_bootloader_program_hash() -> int: + """ + Returns the hash of the simple bootloader program. Matches the Cairo verifier's expected simple + bootloader hash. + """ + simple_bootloader_program: Program = await get_simple_bootloader_program() + return compute_hash_on_elements(data=simple_bootloader_program.data) + + +def load_program(task: Task, memory, program_header, builtins_offset): + """ + Fills the memory with the following: + 1. program header. + 2. program code. + Returns the program address and the size of the written program data. + """ + + builtins = task.get_program().builtins + n_builtins = len(builtins) + program_data = task.get_program().data + + # Fill in the program header. + header_address = program_header.address_ + # The program header ends with a list of builtins used by the program. + header_size = builtins_offset + n_builtins + # data_length does not include the data_length header field in the calculation. + program_header.data_length = (header_size - 1) + len(program_data) + program_header.program_main = task.get_program().main + program_header.n_builtins = n_builtins + # Fill in the builtin list in memory. + builtins_address = header_address + builtins_offset + for index, builtin in enumerate(builtins): + assert isinstance(builtin, str) + memory[builtins_address + index] = from_bytes(builtin.encode("ascii")) + + # Fill in the program code in memory. + program_address = header_address + header_size + for index, opcode in enumerate(program_data): + memory[program_address + index] = opcode + + return program_address, header_size + len(program_data) + + +def write_return_builtins( + memory, + return_builtins_addr, + used_builtins, + used_builtins_addr, + pre_execution_builtins_addr, + task, +): + """ + Writes the updated builtin pointers after the program execution to the given return builtins + address. + used_builtins is the list of builtins used by the program and thus updated by it. + """ + + used_builtin_offset = 0 + for index, builtin in enumerate(ALL_BUILTINS): + if builtin in used_builtins: + memory[return_builtins_addr + index] = memory[used_builtins_addr + used_builtin_offset] + used_builtin_offset += 1 + + if isinstance(task, CairoPie): + assert task.metadata.builtin_segments[builtin].size == ( + memory[return_builtins_addr + index] + - memory[pre_execution_builtins_addr + index] + ), "Builtin usage is inconsistent with the CairoPie." + else: + # The builtin is unused, hence its value is the same as before calling the program. + memory[return_builtins_addr + index] = memory[pre_execution_builtins_addr + index] + + +def load_cairo_pie( + task: CairoPie, + memory, + segments, + program_address, + execution_segment_address, + builtin_runners, + ret_fp, + ret_pc, +): + """ + Load memory entries of the inner program. + This replaces executing hints in a non-trusted program. + """ + segment_offsets = WriteOnceDict() + + segment_offsets[task.metadata.program_segment.index] = program_address + segment_offsets[task.metadata.execution_segment.index] = execution_segment_address + segment_offsets[task.metadata.ret_fp_segment.index] = ret_fp + segment_offsets[task.metadata.ret_pc_segment.index] = ret_pc + + def extract_segment(value: MaybeRelocatable, value_name: str): + """ + Returns the segment index for the given value. + Verifies that value is a RelocatableValue with offset 0. + """ + assert isinstance(value, RelocatableValue), f"{value_name} is not relocatable." + assert value.offset == 0, f"{value_name} has a non-zero offset." + return value.segment_index + + orig_execution_segment = RelocatableValue( + segment_index=task.metadata.execution_segment.index, offset=0 + ) + + # Set initial stack relocations. + for idx, name in enumerate(task.program.builtins): + segment_offsets[ + extract_segment( + value=task.memory[orig_execution_segment + idx], + value_name=f"{name} builtin start address", + ) + ] = memory[execution_segment_address + idx] + + for segment_info in task.metadata.extra_segments: + segment_offsets[segment_info.index] = segments.add(size=segment_info.size) + + def local_relocate_value(value): + return relocate_value(value, segment_offsets, task.program.prime) + + # Relocate builtin additional data. + # This should occur before the memory relocation, since the signature builtin assumes that a + # signature is added before the corresponding public key and message are both written to memory. + esdsa_additional_data = task.additional_data.get("ecdsa_builtin") + if esdsa_additional_data is not None: + ecdsa_builtin = builtin_runners.get("ecdsa_builtin") + assert ecdsa_builtin is not None, "The task requires the ecdsa builtin but it is missing." + ecdsa_builtin.extend_additional_data(esdsa_additional_data, local_relocate_value) + + for addr, val in task.memory.items(): + memory[local_relocate_value(addr)] = local_relocate_value(val) + + +def prepare_output_runner( + task: Task, output_builtin: OutputBuiltinRunner, output_ptr: RelocatableValue +): + """ + Prepares the output builtin if the type of task is Task, so that pages of the inner program + will be recorded separately. + If the type of task is CairoPie, nothing should be done, as the program does not contain + hints that may affect the output builtin. + The return value of this function should be later passed to get_task_fact_topology(). + """ + + if isinstance(task, RunProgramTask): + output_state = output_builtin.get_state() + output_builtin.new_state(base=output_ptr) + return output_state + elif isinstance(task, CairoPieTask): + return None + else: + raise NotImplementedError(f"Unexpected task type: {type(task).__name__}.") + + +def get_task_fact_topology( + output_size: int, + task: Union[RunProgramTask, CairoPie], + output_builtin: OutputBuiltinRunner, + output_runner_data: Any, +) -> FactTopology: + """ + Returns the fact_topology that corresponds to 'task'. Restores output builtin state if 'task' is + a RunProgramTask. + """ + + # Obtain the fact_toplogy of 'task'. + if isinstance(task, RunProgramTask): + assert output_runner_data is not None + fact_topology = get_fact_topology_from_additional_data( + output_size=output_size, + output_builtin_additional_data=output_builtin.get_additional_data(), + ) + # Restore the output builtin runner to its original state. + output_builtin.set_state(output_runner_data) + elif isinstance(task, CairoPieTask): + assert output_runner_data is None + fact_topology = get_fact_topology_from_additional_data( + output_size=output_size, + output_builtin_additional_data=task.cairo_pie.additional_data["output_builtin"], + ) + else: + raise NotImplementedError(f"Unexpected task type: {type(task).__name__}.") + + return fact_topology + + +def add_consecutive_output_pages( + fact_topology: FactTopology, + output_builtin: OutputBuiltinRunner, + cur_page_id: int, + output_start: MaybeRelocatable, +) -> int: + offset = 0 + for i, page_size in enumerate(fact_topology.page_sizes): + output_builtin.add_page( + page_id=cur_page_id + i, page_start=output_start + offset, page_size=page_size + ) + offset += page_size + + return len(fact_topology.page_sizes) + + +def configure_fact_topologies( + fact_topologies: List[FactTopology], + output_start: MaybeRelocatable, + output_builtin: OutputBuiltinRunner, +): + """ + Given the fact_topologies of the tasks that were run by bootloader, configure the + corresponding pages in the output builtin. Assumes that the bootloader output 2 words per task. + """ + # Each task may use a few memory pages. Start from page 1 (as page 0 is reserved for the + # bootloader program and arguments). + cur_page_id = 1 + for fact_topology in fact_topologies: + # Skip bootloader output for each task. + output_start += 2 + cur_page_id += add_consecutive_output_pages( + fact_topology=fact_topology, + output_builtin=output_builtin, + cur_page_id=cur_page_id, + output_start=output_start, + ) + output_start += sum(fact_topology.page_sizes) + + +def write_to_fact_topologies_file(fact_topologies_path: str, fact_topologies: List[FactTopology]): + with open(fact_topologies_path, "w") as fp: + json.dump( + FactTopologiesFile.Schema().dump(FactTopologiesFile(fact_topologies=fact_topologies)), + fp, + indent=4, + sort_keys=True, + ) + fp.write("\n") + + +def calc_simple_bootloader_execution_resources(program_length: int) -> ExecutionResources: + """ + Returns an upper bound on the number of steps and builtin instances that the simple bootloader + uses. + """ + n_steps = SIMPLE_BOOTLOADER_N_STEPS_RATIO * program_length + SIMPLE_BOOTLOADER_N_STEPS_CONSTANT + builtin_instance_counter = { + "pedersen_builtin": SIMPLE_BOOTLOADER_N_PEDERSEN + program_length, + "range_check_builtin": SIMPLE_BOOTLOADER_N_RANGE_CHECKS, + "output_builtin": SIMPLE_BOOTLOADER_N_OUTPUT, + } + return ExecutionResources( + n_steps=n_steps, builtin_instance_counter=builtin_instance_counter, n_memory_holes=0 + ) diff --git a/provers/cairo/benches/criterion_prover.rs b/provers/cairo/benches/criterion_prover.rs index 7a8e91308..b908d090a 100644 --- a/provers/cairo/benches/criterion_prover.rs +++ b/provers/cairo/benches/criterion_prover.rs @@ -4,6 +4,7 @@ use cairo_platinum_prover::{ use criterion::{ black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, }; + use stark_platinum_prover::proof::options::{ProofOptions, SecurityLevel}; pub mod functions; @@ -53,12 +54,12 @@ fn run_cairo_bench( ) { let program_content = std::fs::read(program_path).unwrap(); let proof_options = ProofOptions::new_secure(SecurityLevel::Provable80Bits, 3); - let (main_trace, pub_inputs) = generate_prover_args(&program_content, layout).unwrap(); - println!("Generated main trace with {} rows", main_trace.n_rows()); + let (mut main_trace, pub_inputs) = generate_prover_args(&program_content, layout).unwrap(); + println!("Generated main trace with {} rows", main_trace.num_rows()); group.bench_function(benchname, |bench| { bench.iter(|| { - black_box(generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap()) + black_box(generate_cairo_proof(&mut main_trace, &pub_inputs, &proof_options).unwrap()) }); }); } diff --git a/provers/cairo/benches/criterion_prover_70k.rs b/provers/cairo/benches/criterion_prover_70k.rs index 31f73e3a1..216916af0 100644 --- a/provers/cairo/benches/criterion_prover_70k.rs +++ b/provers/cairo/benches/criterion_prover_70k.rs @@ -48,11 +48,11 @@ fn run_cairo_bench( ) { let program_content = std::fs::read(program_path).unwrap(); let proof_options = ProofOptions::new_secure(SecurityLevel::Provable80Bits, 3); - let (main_trace, pub_inputs) = generate_prover_args(&program_content, layout).unwrap(); + let (mut main_trace, pub_inputs) = generate_prover_args(&program_content, layout).unwrap(); group.bench_function(benchname, |bench| { bench.iter(|| { - black_box(generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap()) + black_box(generate_cairo_proof(&mut main_trace, &pub_inputs, &proof_options).unwrap()) }); }); } diff --git a/provers/cairo/benches/criterion_verifier.rs b/provers/cairo/benches/criterion_verifier.rs index f4a82c957..89bf18768 100644 --- a/provers/cairo/benches/criterion_verifier.rs +++ b/provers/cairo/benches/criterion_verifier.rs @@ -5,11 +5,11 @@ use criterion::{ use lambdaworks_math::{ field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, traits::Deserializable, }; + use stark_platinum_prover::proof::{ options::{ProofOptions, SecurityLevel}, stark::StarkProof, }; - pub mod functions; fn load_proof_and_pub_inputs( diff --git a/provers/cairo/benches/criterion_verifier_70k.rs b/provers/cairo/benches/criterion_verifier_70k.rs index 6597d56e3..4442996d0 100644 --- a/provers/cairo/benches/criterion_verifier_70k.rs +++ b/provers/cairo/benches/criterion_verifier_70k.rs @@ -6,6 +6,7 @@ use criterion::{ use lambdaworks_math::{ field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, traits::Deserializable, }; + use stark_platinum_prover::proof::{ options::{ProofOptions, SecurityLevel}, stark::StarkProof, diff --git a/provers/cairo/cairo_programs/cairo0/fibonacci_stone.cairo b/provers/cairo/cairo_programs/cairo0/fibonacci_stone.cairo new file mode 100644 index 000000000..4a32b246d --- /dev/null +++ b/provers/cairo/cairo_programs/cairo0/fibonacci_stone.cairo @@ -0,0 +1,33 @@ +// Copyright 2023 StarkWare Industries Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.starkware.co/open-source-license/ +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions +// and limitations under the License. + +func main() { + alloc_locals; + + let res = fib(1, 1, 10); + + assert res = 144; + // Return the updated output_ptr. + return (); +} + +func fib(first_element: felt, second_element: felt, n: felt) -> felt { + if (n == 0) { + return second_element; + } + + return fib( + first_element=second_element, second_element=first_element + second_element, n=n - 1 + ); +} diff --git a/provers/cairo/ffi/src/lib.rs b/provers/cairo/ffi/src/lib.rs index b5ea7e0a5..468dd9dce 100644 --- a/provers/cairo/ffi/src/lib.rs +++ b/provers/cairo/ffi/src/lib.rs @@ -1,10 +1,11 @@ -use cairo_platinum_prover::air::CairoAIR; +use cairo_platinum_prover::layouts::plain::air::CairoAIR; use stark_platinum_prover::proof::options::ProofOptions; use stark_platinum_prover::proof::options::SecurityLevel; use stark_platinum_prover::transcript::StoneProverTranscript; use stark_platinum_prover::verifier::{IsStarkVerifier, Verifier}; fn verify_cairo_proof_ffi(proof_bytes: &[u8], proof_options: &ProofOptions) -> bool { + let bytes = proof_bytes; // This logic is the same as main verify, with only error handling changing. In ffi, we simply return a false if the proof is invalid, instead of rising an error. @@ -54,6 +55,8 @@ pub extern "C" fn verify_cairo_proof_ffi_100_bits( verify_cairo_proof_ffi(real_proof_bytes, &proof_options) } + +/* #[cfg(test)] mod tests { use super::*; @@ -69,3 +72,4 @@ mod tests { assert!(result) } } +*/ diff --git a/provers/cairo/fibonacci.mem b/provers/cairo/fibonacci.mem new file mode 100644 index 000000000..415476292 Binary files /dev/null and b/provers/cairo/fibonacci.mem differ diff --git a/provers/cairo/fibonacci.trace b/provers/cairo/fibonacci.trace new file mode 100644 index 000000000..ea329514d Binary files /dev/null and b/provers/cairo/fibonacci.trace differ diff --git a/provers/cairo/fibonacci_1000.json b/provers/cairo/fibonacci_1000.json new file mode 100644 index 000000000..8cb0eba04 --- /dev/null +++ b/provers/cairo/fibonacci_1000.json @@ -0,0 +1,626 @@ +{ + "attributes": [], + "builtins": [], + "compiler_version": "0.12.2", + "data": [ + "0x40780017fff7fff", + "0x0", + "0x1104800180018000", + "0x4", + "0x10780017fff7fff", + "0x0", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x1", + "0x48307fff7ffe8000", + "0x480680017fff8000", + "0x2710", + "0x48127ffd7fff8000", + "0x48127ffd7fff8000", + "0x48307fff7ffe8000", + "0x482480017ffc8000", + "0x800000000000011000000000000000000000000000000000000000000000000", + "0x20680017fff7fff", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffffc", + "0x400680017fff7ffe", + "0xd", + "0x208b7fff7fff7ffe" + ], + "debug_info": { + "file_contents": { + "": "__start__:\nap += main.Args.SIZE + main.ImplicitArgs.SIZE;\ncall main;\n\n__end__:\njmp rel 0;\n" + }, + "instruction_locations": { + "0": { + "accessible_scopes": [ + "__main__" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 0, + "offset": 0 + }, + "reference_ids": {} + }, + "hints": [], + "inst": { + "end_col": 46, + "end_line": 2, + "input_file": { + "filename": "" + }, + "start_col": 1, + "start_line": 2 + } + }, + "2": { + "accessible_scopes": [ + "__main__" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 0, + "offset": 0 + }, + "reference_ids": {} + }, + "hints": [], + "inst": { + "end_col": 10, + "end_line": 3, + "input_file": { + "filename": "" + }, + "start_col": 1, + "start_line": 3 + } + }, + "4": { + "accessible_scopes": [ + "__main__" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 1, + "offset": 0 + }, + "reference_ids": {} + }, + "hints": [], + "inst": { + "end_col": 10, + "end_line": 6, + "input_file": { + "filename": "" + }, + "start_col": 1, + "start_line": 6 + } + }, + "6": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 0 + }, + "reference_ids": {} + }, + "hints": [], + "inst": { + "end_col": 19, + "end_line": 8, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "start_col": 18, + "start_line": 8 + } + }, + "8": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 1 + }, + "reference_ids": { + "__main__.main.x0": 0 + } + }, + "hints": [], + "inst": { + "end_col": 19, + "end_line": 9, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "start_col": 18, + "start_line": 9 + } + }, + "10": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 2 + }, + "reference_ids": { + "__main__.main.x0": 0, + "__main__.main.x1": 1 + } + }, + "hints": [], + "inst": { + "end_col": 30, + "end_line": 10, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "start_col": 23, + "start_line": 10 + } + }, + "11": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 3 + }, + "reference_ids": { + "__main__.main.fib_acc": 2, + "__main__.main.x0": 0, + "__main__.main.x1": 1 + } + }, + "hints": [], + "inst": { + "end_col": 22, + "end_line": 11, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "start_col": 17, + "start_line": 11 + } + }, + "13": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 4 + }, + "reference_ids": { + "__main__.main.fib_acc": 2, + "__main__.main.n": 3, + "__main__.main.x0": 0, + "__main__.main.x1": 1 + } + }, + "hints": [], + "inst": { + "end_col": 15, + "end_line": 9, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "parent_location": [ + { + "end_col": 24, + "end_line": 13, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "start_col": 22, + "start_line": 13 + }, + "While expanding the reference 'x1' in:" + ], + "start_col": 13, + "start_line": 9 + } + }, + "14": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 5 + }, + "reference_ids": { + "__main__.main.fib_acc": 2, + "__main__.main.n": 3, + "__main__.main.x0": 4, + "__main__.main.x1": 1 + } + }, + "hints": [], + "inst": { + "end_col": 20, + "end_line": 10, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "parent_location": [ + { + "end_col": 29, + "end_line": 14, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "start_col": 22, + "start_line": 14 + }, + "While expanding the reference 'fib_acc' in:" + ], + "start_col": 13, + "start_line": 10 + } + }, + "15": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 6 + }, + "reference_ids": { + "__main__.main.fib_acc": 2, + "__main__.main.n": 3, + "__main__.main.x0": 4, + "__main__.main.x1": 5 + } + }, + "hints": [], + "inst": { + "end_col": 34, + "end_line": 15, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "start_col": 27, + "start_line": 15 + } + }, + "16": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 7 + }, + "reference_ids": { + "__main__.main.fib_acc": 6, + "__main__.main.n": 3, + "__main__.main.x0": 4, + "__main__.main.x1": 5 + } + }, + "hints": [], + "inst": { + "end_col": 26, + "end_line": 16, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "start_col": 21, + "start_line": 16 + } + }, + "18": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 8 + }, + "reference_ids": { + "__main__.main.fib_acc": 6, + "__main__.main.n": 7, + "__main__.main.x0": 4, + "__main__.main.x1": 5 + } + }, + "hints": [], + "inst": { + "end_col": 27, + "end_line": 17, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "start_col": 9, + "start_line": 17 + } + }, + "20": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 8 + }, + "reference_ids": { + "__main__.main.fib_acc": 6, + "__main__.main.n": 7, + "__main__.main.x0": 4, + "__main__.main.x1": 5 + } + }, + "hints": [], + "inst": { + "end_col": 25, + "end_line": 19, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "start_col": 5, + "start_line": 19 + } + }, + "22": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 8 + }, + "reference_ids": { + "__main__.main.fib_acc": 6, + "__main__.main.n": 7, + "__main__.main.x0": 4, + "__main__.main.x1": 5 + } + }, + "hints": [], + "inst": { + "end_col": 15, + "end_line": 20, + "input_file": { + "filename": "cairo_programs/cairo0/fibonacci_10000_loop.cairo" + }, + "start_col": 5, + "start_line": 20 + } + } + } + }, + "hints": {}, + "identifiers": { + "__main__.__end__": { + "pc": 4, + "type": "label" + }, + "__main__.__start__": { + "pc": 0, + "type": "label" + }, + "__main__.main": { + "decorators": [], + "pc": 6, + "type": "function" + }, + "__main__.main.Args": { + "full_name": "__main__.main.Args", + "members": {}, + "size": 0, + "type": "struct" + }, + "__main__.main.ImplicitArgs": { + "full_name": "__main__.main.ImplicitArgs", + "members": {}, + "size": 0, + "type": "struct" + }, + "__main__.main.Return": { + "cairo_type": "()", + "type": "type_definition" + }, + "__main__.main.SIZEOF_LOCALS": { + "type": "const", + "value": 0 + }, + "__main__.main.fib_acc": { + "cairo_type": "felt", + "full_name": "__main__.main.fib_acc", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 3 + }, + "pc": 11, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 7 + }, + "pc": 16, + "value": "[cast(ap + (-1), felt*)]" + } + ], + "type": "reference" + }, + "__main__.main.loop": { + "pc": 13, + "type": "label" + }, + "__main__.main.n": { + "cairo_type": "felt", + "full_name": "__main__.main.n", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 4 + }, + "pc": 13, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 8 + }, + "pc": 18, + "value": "[cast(ap + (-1), felt*)]" + } + ], + "type": "reference" + }, + "__main__.main.x0": { + "cairo_type": "felt", + "full_name": "__main__.main.x0", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 1 + }, + "pc": 8, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 5 + }, + "pc": 14, + "value": "[cast(ap + (-1), felt*)]" + } + ], + "type": "reference" + }, + "__main__.main.x1": { + "cairo_type": "felt", + "full_name": "__main__.main.x1", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 2 + }, + "pc": 10, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 6 + }, + "pc": 15, + "value": "[cast(ap + (-1), felt*)]" + } + ], + "type": "reference" + } + }, + "main_scope": "__main__", + "prime": "0x800000000000011000000000000000000000000000000000000000000000001", + "reference_manager": { + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 1 + }, + "pc": 8, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 2 + }, + "pc": 10, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 3 + }, + "pc": 11, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 4 + }, + "pc": 13, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 5 + }, + "pc": 14, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 6 + }, + "pc": 15, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 7 + }, + "pc": 16, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 8 + }, + "pc": 18, + "value": "[cast(ap + (-1), felt*)]" + } + ] + } +} diff --git a/provers/cairo/new_proof.proof b/provers/cairo/new_proof.proof new file mode 100644 index 000000000..10202eff7 Binary files /dev/null and b/provers/cairo/new_proof.proof differ diff --git a/provers/cairo/simple.cairo b/provers/cairo/simple.cairo new file mode 100644 index 000000000..455c84525 --- /dev/null +++ b/provers/cairo/simple.cairo @@ -0,0 +1,3 @@ +fn main() -> bool { + 2 == 2 +} diff --git a/provers/cairo/simple.memory b/provers/cairo/simple.memory new file mode 100644 index 000000000..8c57ff3d4 Binary files /dev/null and b/provers/cairo/simple.memory differ diff --git a/provers/cairo/simple.trace b/provers/cairo/simple.trace new file mode 100644 index 000000000..62903d8e4 Binary files /dev/null and b/provers/cairo/simple.trace differ diff --git a/provers/cairo/src/decode/instruction_offsets.rs b/provers/cairo/src/decode/instruction_offsets.rs index 09716045a..f29aeb345 100644 --- a/provers/cairo/src/decode/instruction_offsets.rs +++ b/provers/cairo/src/decode/instruction_offsets.rs @@ -34,12 +34,12 @@ impl InstructionOffsets { i32::from(i16::from_le_bytes(aux)) } - pub fn to_trace_representation(&self) -> [FieldElement; 3] { - [ + pub fn to_trace_representation(&self) -> (Felt252, Felt252, Felt252) { + ( to_unbiased_representation(self.off_dst), to_unbiased_representation(self.off_op0), to_unbiased_representation(self.off_op1), - ] + ) } } diff --git a/provers/cairo/src/execution_trace.rs b/provers/cairo/src/execution_trace.rs index eece1d28d..a9fc47e4f 100644 --- a/provers/cairo/src/execution_trace.rs +++ b/provers/cairo/src/execution_trace.rs @@ -1,3 +1,5 @@ +use std::{collections::VecDeque, iter}; + use super::{ cairo_mem::CairoMemory, decode::{ @@ -9,92 +11,21 @@ use super::{ }, register_states::RegisterStates, }; -use crate::air::{EXTRA_ADDR, RC_HOLES}; -use crate::{ - air::{ - PublicInputs, FRAME_DST_ADDR, FRAME_OP0_ADDR, FRAME_OP1_ADDR, FRAME_PC, OFF_DST, OFF_OP0, - OFF_OP1, - }, - Felt252, -}; +use crate::layouts::plain::air::PublicInputs; use cairo_vm::without_std::collections::HashMap; +use itertools::Itertools; use lambdaworks_math::{ field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, unsigned_integer::element::UnsignedInteger, }; -use stark_platinum_prover::trace::TraceTable; - -type CairoTraceTable = TraceTable; - -// MAIN TRACE LAYOUT -// ----------------------------------------------------------------------------------------- -// A. flags (16) : Decoded instruction flags -// B. res (1) : Res value -// C. mem_p (2) : Temporary memory pointers (ap and fp) -// D. mem_a (4) : Memory addresses (pc, dst_addr, op0_addr, op1_addr) -// E. mem_v (4) : Memory values (inst, dst, op0, op1) -// F. offsets (3) : (off_dst, off_op0, off_op1) -// G. derived (3) : (t0, t1, mul) -// -// A B C D E F G -// ├xxxxxxxxxxxxxxxx|x|xx|xxxx|xxxx|xxx|xxx┤ -// - -/// Builds the Cairo main trace (i.e. the trace without the auxiliary columns). -/// Builds the execution trace, fills the offset range-check holes and memory holes, adds -/// public memory dummy accesses (See section 9.8 of the Cairo whitepaper) and pads the result -/// so that it has a trace length equal to the closest power of two. -pub fn build_main_trace( - register_states: &RegisterStates, - memory: &CairoMemory, - public_input: &mut PublicInputs, -) -> CairoTraceTable { - let mut main_trace = build_cairo_execution_trace(register_states, memory); - - let mut address_cols = - main_trace.merge_columns(&[FRAME_PC, FRAME_DST_ADDR, FRAME_OP0_ADDR, FRAME_OP1_ADDR]); - - address_cols.sort_by_key(|x| x.representative()); - - let (rc_holes, rc_min, rc_max) = get_rc_holes(&main_trace, &[OFF_DST, OFF_OP0, OFF_OP1]); +use stark_platinum_prover::{fri::FieldElement, trace::TraceTable, Felt252}; +pub type CairoTraceTable = TraceTable; - // this will avaluate to true if the public inputs weren't obtained from the run_program() function - if public_input.range_check_min.is_none() && public_input.range_check_max.is_none() { - public_input.range_check_min = Some(rc_min); - public_input.range_check_max = Some(rc_max); - } - fill_rc_holes(&mut main_trace, &rc_holes); - - let memory_holes = get_memory_holes(&address_cols, &public_input.public_memory); - - if !memory_holes.is_empty() { - fill_memory_holes(&mut main_trace, &memory_holes); - } - - add_pub_memory_dummy_accesses( - &mut main_trace, - public_input.public_memory.len(), - memory_holes.len(), - ); - - let trace_len_next_power_of_two = main_trace.n_rows().next_power_of_two(); - let padding_len = trace_len_next_power_of_two - main_trace.n_rows(); - main_trace.pad_with_last_row(padding_len); +// NOTE: This should be deleted and use CairoAIR::STEP_SIZE once it is set to 16 +const CAIRO_STEP: usize = 16; - main_trace -} - -/// Artificial `(0, 0)` dummy memory accesses must be added for the public memory. -/// See section 9.8 of the Cairo whitepaper. -fn add_pub_memory_dummy_accesses( - main_trace: &mut CairoTraceTable, - pub_memory_len: usize, - last_memory_hole_idx: usize, -) { - for i in 0..pub_memory_len { - main_trace.set_or_extend(last_memory_hole_idx + i, EXTRA_ADDR, &Felt252::zero()); - } -} +const PLAIN_LAYOUT_NUM_MAIN_COLUMNS: usize = 6; +const PLAIN_LAYOUT_NUM_AUX_COLUMNS: usize = 2; /// Gets holes from the range-checked columns. These holes must be filled for the /// permutation range-checks, as can be read in section 9.9 of the Cairo whitepaper. @@ -103,52 +34,25 @@ fn add_pub_memory_dummy_accesses( /// values rc_min and rc_max, corresponding to the minimum and maximum values of the range. /// NOTE: These extreme values should be received as public inputs in the future and not /// calculated here. -fn get_rc_holes(trace: &CairoTraceTable, columns_indices: &[usize]) -> (Vec, u16, u16) { - let offset_columns = trace.merge_columns(columns_indices); +fn get_rc_holes(sorted_rc_values: &[u16]) -> VecDeque { + let mut rc_holes = VecDeque::new(); - let mut sorted_offset_representatives: Vec = offset_columns - .iter() - .map(|x| x.representative().into()) - .collect(); - sorted_offset_representatives.sort(); + let mut prev_rc_value = sorted_rc_values[0]; - let mut all_missing_values: Vec = Vec::new(); + for rc_value in sorted_rc_values.iter() { + let rc_diff = rc_value - prev_rc_value; + if rc_diff != 1 && rc_diff != 0 { + let mut rc_hole = prev_rc_value + 1; - for window in sorted_offset_representatives.windows(2) { - if window[1] != window[0] { - let mut missing_range: Vec<_> = ((window[0] + 1)..window[1]) - .map(|x| Felt252::from(x as u64)) - .collect(); - all_missing_values.append(&mut missing_range); + while rc_hole < *rc_value { + rc_holes.push_back(Felt252::from(rc_hole as u64)); + rc_hole += 1; + } } + prev_rc_value = *rc_value; } - let multiple_of_three_padding = - ((all_missing_values.len() + 2) / 3) * 3 - all_missing_values.len(); - let padding_element = Felt252::from(*sorted_offset_representatives.last().unwrap() as u64); - all_missing_values.append(&mut vec![padding_element; multiple_of_three_padding]); - - ( - all_missing_values, - sorted_offset_representatives[0], - sorted_offset_representatives.last().cloned().unwrap(), - ) -} - -/// Fills holes found in the range-checked columns. -fn fill_rc_holes(trace: &mut CairoTraceTable, holes: &[Felt252]) { - holes.iter().enumerate().for_each(|(i, hole)| { - trace.set_or_extend(i, RC_HOLES, hole); - }); - - // Fill the rest of the RC_HOLES column to avoid inexistent zeros - let mut offsets = trace.merge_columns(&[OFF_DST, OFF_OP0, OFF_OP1, RC_HOLES]); - - offsets.sort_by_key(|x| x.representative()); - let greatest_offset = offsets.last().unwrap(); - (holes.len()..trace.n_rows()).for_each(|i| { - trace.set_or_extend(i, RC_HOLES, greatest_offset); - }); + rc_holes } /// Get memory holes from accessed addresses. These memory holes appear @@ -158,13 +62,14 @@ fn fill_rc_holes(trace: &mut CairoTraceTable, holes: &[Felt252]) { /// # Arguments /// /// * `sorted_addrs` - Vector of sorted memory addresses. -/// * `pub_memory` - The public memory of the executed program. +/// * `codelen` - the length of the Cairo program instructions. fn get_memory_holes( sorted_addrs: &[Felt252], pub_memory: &HashMap, -) -> Vec { - let mut memory_holes = Vec::new(); +) -> VecDeque { + let mut memory_holes = VecDeque::new(); let mut prev_addr = &sorted_addrs[0]; + let one = Felt252::one(); for addr in sorted_addrs.iter() { let addr_diff = addr - prev_addr; @@ -172,27 +77,23 @@ fn get_memory_holes( // If the candidate memory hole has an address belonging to the program segment (public // memory), that is not accounted here since public memory is added in a posterior step of // the protocol. - if addr_diff != Felt252::one() && addr_diff != Felt252::zero() { - let mut hole_addr = prev_addr + Felt252::one(); + if addr_diff != one && addr_diff != Felt252::zero() { + let mut hole_addr = prev_addr + one; while hole_addr.representative() < addr.representative() { if !pub_memory.contains_key(&hole_addr) { - memory_holes.push(hole_addr); + memory_holes.push_back(hole_addr); } - hole_addr += Felt252::one(); + hole_addr += one; } } prev_addr = addr; } - memory_holes -} + let max_addr_plus_one = sorted_addrs.last().unwrap() + one; + memory_holes.push_back(max_addr_plus_one); -/// Fill memory holes in the extra address column of the trace with the missing addresses. -fn fill_memory_holes(trace: &mut CairoTraceTable, memory_holes: &[Felt252]) { - memory_holes.iter().enumerate().for_each(|(i, hole)| { - trace.set_or_extend(i, EXTRA_ADDR, hole); - }); + memory_holes } /// Receives the raw Cairo trace and memory as outputted from the Cairo VM and returns @@ -202,24 +103,26 @@ fn fill_memory_holes(trace: &mut CairoTraceTable, memory_holes: &[Felt252]) { pub fn build_cairo_execution_trace( register_states: &RegisterStates, memory: &CairoMemory, + public_input: &mut PublicInputs, ) -> CairoTraceTable { - let n_steps = register_states.steps(); + let num_steps = register_states.steps(); // Instruction flags and offsets are decoded from the raw instructions and represented // by the CairoInstructionFlags and InstructionOffsets as an intermediate representation - let (flags, offsets): (Vec, Vec) = register_states - .flags_and_offsets(memory) - .unwrap() - .into_iter() - .unzip(); + let (flags, biased_offsets): (Vec, Vec) = + register_states + .flags_and_offsets(memory) + .unwrap() + .into_iter() + .unzip(); // dst, op0, op1 and res are computed from flags and offsets let (dst_addrs, mut dsts): (Vec, Vec) = - compute_dst(&flags, &offsets, register_states, memory); + compute_dst(&flags, &biased_offsets, register_states, memory); let (op0_addrs, mut op0s): (Vec, Vec) = - compute_op0(&flags, &offsets, register_states, memory); + compute_op0(&flags, &biased_offsets, register_states, memory); let (op1_addrs, op1s): (Vec, Vec) = - compute_op1(&flags, &offsets, register_states, memory, &op0s); + compute_op1(&flags, &biased_offsets, register_states, memory, &op0s); let mut res = compute_res(&flags, &op0s, &op1s, &dsts); // In some cases op0, dst or res may need to be updated from the already calculated values @@ -227,11 +130,11 @@ pub fn build_cairo_execution_trace( // Flags and offsets are transformed to a bit representation. This is needed since // the flag constraints of the Cairo AIR are defined over bit representations of these - let trace_repr_flags: Vec<[Felt252; 16]> = flags + let bit_prefix_flags: Vec<[Felt252; 16]> = flags .iter() .map(CairoInstructionFlags::to_trace_representation) .collect(); - let trace_repr_offsets: Vec<[Felt252; 3]> = offsets + let unbiased_offsets: Vec<(Felt252, Felt252, Felt252)> = biased_offsets .iter() .map(InstructionOffsets::to_trace_representation) .collect(); @@ -242,16 +145,19 @@ pub fn build_cairo_execution_trace( .iter() .map(|t| Felt252::from(t.ap)) .collect(); + let fps: Vec = register_states .rows .iter() .map(|t| Felt252::from(t.fp)) .collect(); + let pcs: Vec = register_states .rows .iter() .map(|t| Felt252::from(t.pc)) .collect(); + let instructions: Vec = register_states .rows .iter() @@ -261,7 +167,7 @@ pub fn build_cairo_execution_trace( // t0, t1 and mul derived values are constructed. For details reFelt252r to // section 9.1 of the Cairo whitepaper let two = Felt252::from(2); - let t0: Vec = trace_repr_flags + let t0: Vec = bit_prefix_flags .iter() .zip(&dsts) .map(|(repr_flags, dst)| (repr_flags[9] - two * repr_flags[10]) * dst) @@ -269,39 +175,53 @@ pub fn build_cairo_execution_trace( let t1: Vec = t0.iter().zip(&res).map(|(t, r)| t * r).collect(); let mul: Vec = op0s.iter().zip(&op1s).map(|(op0, op1)| op0 * op1).collect(); - // A structure change of the flags and offsets representations to fit into the arguments - // expected by the TraceTable constructor. A vector of columns of the representations - // is obtained from the rows representation. - let trace_repr_flags = rows_to_cols(&trace_repr_flags); - let trace_repr_offsets = rows_to_cols(&trace_repr_offsets); - - let extra_addrs = vec![Felt252::zero(); n_steps]; - let extra_vals = extra_addrs.clone(); - let rc_holes = extra_addrs.clone(); - - // Build Cairo trace columns to instantiate TraceTable struct as defined in the trace layout - let mut trace_cols: Vec> = Vec::new(); - (0..trace_repr_flags.len()).for_each(|n| trace_cols.push(trace_repr_flags[n].clone())); - trace_cols.push(res); - trace_cols.push(aps); - trace_cols.push(fps); - trace_cols.push(pcs); - trace_cols.push(dst_addrs); - trace_cols.push(op0_addrs); - trace_cols.push(op1_addrs); - trace_cols.push(instructions); - trace_cols.push(dsts); - trace_cols.push(op0s); - trace_cols.push(op1s); - (0..trace_repr_offsets.len()).for_each(|n| trace_cols.push(trace_repr_offsets[n].clone())); - trace_cols.push(t0); - trace_cols.push(t1); - trace_cols.push(mul); - trace_cols.push(extra_addrs); - trace_cols.push(extra_vals); - trace_cols.push(rc_holes); - - TraceTable::from_columns_main(trace_cols, 1) + let mut trace: CairoTraceTable = TraceTable::allocate_with_zeros( + num_steps, + PLAIN_LAYOUT_NUM_MAIN_COLUMNS, + PLAIN_LAYOUT_NUM_AUX_COLUMNS, + CAIRO_STEP, + ); + + let rc_values = set_rc_pool(&mut trace, unbiased_offsets); + set_bit_prefix_flags(&mut trace, bit_prefix_flags); + let mut sorted_addrs = set_mem_pool( + &mut trace, + pcs, + instructions, + op0_addrs, + op0s, + dst_addrs, + dsts, + op1_addrs, + op1s, + ); + set_update_pc(&mut trace, aps, t0, t1, mul, fps, res); + + // Sort values in rc pool + let mut sorted_rc_value_representatives: Vec = rc_values + .iter() + .map(|x| x.representative().into()) + .collect(); + sorted_rc_value_representatives.sort(); + let rc_holes = get_rc_holes(&sorted_rc_value_representatives); + let rc_max = Felt252::from(*(sorted_rc_value_representatives.last().unwrap()) as u64); + finalize_rc_pool(&mut trace, rc_holes, rc_max); + + // Get all rc values. + // NOTE: We are sorting these values again, once for finding rc holes and one for the sorted column construction. + // This could be rethinked for better performance + let mut sorted_rc_column = trace.get_column_main(0); + sorted_rc_column.sort_by_key(|x| x.representative()); + set_sorted_rc_pool(&mut trace, sorted_rc_column); + + // Add memory holes + sorted_addrs.sort_by_key(|x| x.representative()); + let memory_holes = get_memory_holes(&sorted_addrs, &public_input.public_memory); + finalize_mem_pool(&mut trace, memory_holes); + // Sort memory and insert to trace + set_sorted_mem_pool(&mut trace, public_input.public_memory.clone()); + + trace } /// Returns the vector of res values. @@ -522,20 +442,6 @@ fn update_values( } } -/// Utility function to change from a rows representation to a columns -/// representation of a slice of arrays. -fn rows_to_cols(rows: &[[Felt252; N]]) -> Vec> { - let n_cols = rows[0].len(); - - (0..n_cols) - .map(|col_idx| { - rows.iter() - .map(|elem| elem[col_idx]) - .collect::>() - }) - .collect::>>() -} - // NOTE: Leaving this function despite not being used anywhere. It could be useful once // we implement layouts with the range-check builtin. #[allow(dead_code)] @@ -561,13 +467,365 @@ fn decompose_rc_values_into_trace_columns(rc_values: &[&Felt252]) -> [Vec) { + for (step_idx, flags) in bit_prefix_flags.into_iter().enumerate() { + for (flag_idx, flag) in flags.into_iter().enumerate() { + trace.set_main(flag_idx + CAIRO_STEP * step_idx, 1, flag); + } + } +} + +// Column 0 +fn set_rc_pool( + trace: &mut CairoTraceTable, + offsets: Vec<(Felt252, Felt252, Felt252)>, +) -> Vec { + // NOTE: We should check that these offsets correspond to the off0, off1 and off2. + const OFF_DST_OFFSET: usize = 0; + const OFF_OP0_OFFSET: usize = 8; + const OFF_OP1_OFFSET: usize = 4; + + let mut rc_values = Vec::new(); + for (step_idx, (off_dst, off_op0, off_op1)) in offsets.into_iter().enumerate() { + trace.set_main(OFF_DST_OFFSET + CAIRO_STEP * step_idx, 0, off_dst); + trace.set_main(OFF_OP0_OFFSET + CAIRO_STEP * step_idx, 0, off_op0); + trace.set_main(OFF_OP1_OFFSET + CAIRO_STEP * step_idx, 0, off_op1); + + rc_values.push(off_dst); + rc_values.push(off_op0); + rc_values.push(off_op1); + } + + rc_values +} + +// Column 3 +#[allow(clippy::too_many_arguments)] +fn set_mem_pool( + trace: &mut CairoTraceTable, + pcs: Vec, + instructions: Vec, + op0_addrs: Vec, + op0_vals: Vec, + dst_addrs: Vec, + dst_vals: Vec, + op1_addrs: Vec, + op1_vals: Vec, +) -> Vec { + const PC_OFFSET: usize = 0; + const INST_OFFSET: usize = 1; + const OP0_ADDR_OFFSET: usize = 4; + const OP0_VAL_OFFSET: usize = 5; + const DST_ADDR_OFFSET: usize = 8; + const DST_VAL_OFFSET: usize = 9; + const OP1_ADDR_OFFSET: usize = 12; + const OP1_VAL_OFFSET: usize = 13; + + let mut addrs: Vec = Vec::new(); + for (step_idx, (pc, inst, op0_addr, op0_val, dst_addr, dst_val, op1_addr, op1_val)) in + itertools::izip!( + pcs, + instructions, + op0_addrs, + op0_vals, + dst_addrs, + dst_vals, + op1_addrs, + op1_vals + ) + .enumerate() + { + trace.set_main(PC_OFFSET + CAIRO_STEP * step_idx, 3, pc); + trace.set_main(INST_OFFSET + CAIRO_STEP * step_idx, 3, inst); + trace.set_main(OP0_ADDR_OFFSET + CAIRO_STEP * step_idx, 3, op0_addr); + trace.set_main(OP0_VAL_OFFSET + CAIRO_STEP * step_idx, 3, op0_val); + trace.set_main(DST_ADDR_OFFSET + CAIRO_STEP * step_idx, 3, dst_addr); + trace.set_main(DST_VAL_OFFSET + CAIRO_STEP * step_idx, 3, dst_val); + trace.set_main(OP1_ADDR_OFFSET + CAIRO_STEP * step_idx, 3, op1_addr); + trace.set_main(OP1_VAL_OFFSET + CAIRO_STEP * step_idx, 3, op1_val); + + addrs.push(pc); + addrs.push(op0_addr); + addrs.push(dst_addr); + addrs.push(op1_addr); + } + + addrs +} + +// Column 5 +fn set_update_pc( + trace: &mut CairoTraceTable, + aps: Vec, + t0s: Vec, + t1s: Vec, + mul: Vec, + fps: Vec, + res: Vec, +) { + const AP_OFFSET: usize = 0; + const TMP0_OFFSET: usize = 2; + const OPS_MUL_OFFSET: usize = 4; + const FP_OFFSET: usize = 8; + const TMP1_OFFSET: usize = 10; + const RES_OFFSET: usize = 12; + + for (step_idx, (ap, tmp0, m, fp, tmp1, res)) in + itertools::izip!(aps, t0s, mul, fps, t1s, res).enumerate() + { + trace.set_main(AP_OFFSET + CAIRO_STEP * step_idx, 5, ap); + trace.set_main(TMP0_OFFSET + CAIRO_STEP * step_idx, 5, tmp0); + trace.set_main(OPS_MUL_OFFSET + CAIRO_STEP * step_idx, 5, m); + trace.set_main(FP_OFFSET + CAIRO_STEP * step_idx, 5, fp); + trace.set_main(TMP1_OFFSET + CAIRO_STEP * step_idx, 5, tmp1); + trace.set_main(RES_OFFSET + CAIRO_STEP * step_idx, 5, res); + } +} + +fn finalize_mem_pool(trace: &mut CairoTraceTable, memory_holes: VecDeque) { + const MEM_POOL_UNUSED_ADDR_OFFSET: usize = 6; + const MEM_POOL_UNUSED_VALUE_OFFSET: usize = 7; + const MEM_POOL_UNUSED_CELL_STEP: usize = 8; + + let mut memory_holes = memory_holes; + + let last_hole_addr = memory_holes.pop_back().unwrap(); + + for step_idx in 0..trace.num_steps() { + if let Some(hole_addr) = memory_holes.pop_front() { + trace.set_main( + MEM_POOL_UNUSED_ADDR_OFFSET + CAIRO_STEP * step_idx, + 3, + hole_addr, + ); + trace.set_main( + MEM_POOL_UNUSED_VALUE_OFFSET + CAIRO_STEP * step_idx, + 3, + Felt252::zero(), + ); + } else { + trace.set_main( + MEM_POOL_UNUSED_ADDR_OFFSET + CAIRO_STEP * step_idx, + 3, + last_hole_addr, + ); + trace.set_main( + MEM_POOL_UNUSED_VALUE_OFFSET + CAIRO_STEP * step_idx, + 3, + Felt252::zero(), + ); + } + + if let Some(hole_addr) = memory_holes.pop_front() { + trace.set_main( + MEM_POOL_UNUSED_ADDR_OFFSET + MEM_POOL_UNUSED_CELL_STEP + CAIRO_STEP * step_idx, + 3, + hole_addr, + ); + trace.set_main( + MEM_POOL_UNUSED_VALUE_OFFSET + MEM_POOL_UNUSED_CELL_STEP + CAIRO_STEP * step_idx, + 3, + Felt252::zero(), + ); + } else { + trace.set_main( + MEM_POOL_UNUSED_ADDR_OFFSET + MEM_POOL_UNUSED_CELL_STEP + CAIRO_STEP * step_idx, + 3, + last_hole_addr, + ); + trace.set_main( + MEM_POOL_UNUSED_VALUE_OFFSET + MEM_POOL_UNUSED_CELL_STEP + CAIRO_STEP * step_idx, + 3, + Felt252::zero(), + ); + } + + assert!(memory_holes.is_empty()); + } +} + +fn set_sorted_rc_pool(trace: &mut CairoTraceTable, sorted_rc_column: Vec) { + for (row_idx, rc_value) in sorted_rc_column.into_iter().enumerate() { + trace.set_main(row_idx, 2, rc_value); + } +} + +fn finalize_rc_pool(trace: &mut CairoTraceTable, rc_holes: VecDeque, rc_max: Felt252) { + let mut rc_holes = rc_holes; + + let reserved_cell_idxs = [4, 8]; + for step_idx in 0..trace.num_steps() { + for step_cell_idx in 1..CAIRO_STEP { + if reserved_cell_idxs.contains(&step_cell_idx) { + continue; + }; + if let Some(rc_hole) = rc_holes.pop_front() { + trace.set_main(step_idx * CAIRO_STEP + step_cell_idx, 0, rc_hole); + } else { + trace.set_main(step_idx * CAIRO_STEP + step_cell_idx, 0, rc_max); + } + } + } + + assert!(rc_holes.is_empty()); +} + +fn set_sorted_mem_pool(trace: &mut CairoTraceTable, pub_memory: HashMap) { + const PUB_MEMORY_ADDR_OFFSET: usize = 2; + const PUB_MEMORY_VALUE_OFFSET: usize = 3; + const PUB_MEMORY_STEP: usize = 8; + + assert!(2 * trace.num_steps() >= pub_memory.len()); + + let mut mem_pool = trace.get_column_main(3); + let first_pub_memory_addr = Felt252::one(); + let first_pub_memory_value = *pub_memory.get(&first_pub_memory_addr).unwrap(); + let first_pub_memory_entry_padding_len = 2 * trace.num_steps() - pub_memory.len(); + + let padding_num_steps = first_pub_memory_entry_padding_len.div_ceil(2); + let mut first_addr_padding = + iter::repeat(first_pub_memory_addr).take(first_pub_memory_entry_padding_len); + let mut padding_step_flag = 0; + + // this loop is for padding with (first_pub_addr, first_pub_value) + for step_idx in 0..padding_num_steps { + if let Some(first_addr) = first_addr_padding.next() { + mem_pool[PUB_MEMORY_ADDR_OFFSET + CAIRO_STEP * step_idx] = first_addr; + mem_pool[PUB_MEMORY_VALUE_OFFSET + CAIRO_STEP * step_idx] = first_pub_memory_value; + } else { + padding_step_flag = 0; + break; + } + if let Some(first_addr) = first_addr_padding.next() { + mem_pool[PUB_MEMORY_STEP + PUB_MEMORY_ADDR_OFFSET + CAIRO_STEP * step_idx] = first_addr; + mem_pool[PUB_MEMORY_STEP + PUB_MEMORY_VALUE_OFFSET + CAIRO_STEP * step_idx] = + first_pub_memory_value; + } else { + padding_step_flag = 1; + break; + } + } + + let mut pub_memory_iter = pub_memory.iter(); + if padding_step_flag == 1 { + let (pub_memory_addr, pub_memory_value) = pub_memory_iter.next().unwrap(); + mem_pool[PUB_MEMORY_STEP + PUB_MEMORY_ADDR_OFFSET + CAIRO_STEP * (padding_num_steps - 1)] = + *pub_memory_addr; + mem_pool + [PUB_MEMORY_STEP + PUB_MEMORY_VALUE_OFFSET + CAIRO_STEP * (padding_num_steps - 1)] = + *pub_memory_value; + } + + for step_idx in padding_num_steps..trace.num_steps() { + let (pub_memory_addr, pub_memory_value) = pub_memory_iter.next().unwrap(); + mem_pool[PUB_MEMORY_ADDR_OFFSET + CAIRO_STEP * step_idx] = *pub_memory_addr; + mem_pool[PUB_MEMORY_VALUE_OFFSET + CAIRO_STEP * step_idx] = *pub_memory_value; + + let (pub_memory_addr, pub_memory_value) = pub_memory_iter.next().unwrap(); + mem_pool[PUB_MEMORY_STEP + PUB_MEMORY_ADDR_OFFSET + CAIRO_STEP * step_idx] = + *pub_memory_addr; + mem_pool[PUB_MEMORY_STEP + PUB_MEMORY_VALUE_OFFSET + CAIRO_STEP * step_idx] = + *pub_memory_value; + } + + let mut addrs = Vec::with_capacity(trace.num_rows() / 2); + let mut values = Vec::with_capacity(trace.num_rows() / 2); + let mut sorted_addrs = Vec::with_capacity(trace.num_rows() / 2); + let mut sorted_values = Vec::with_capacity(trace.num_rows() / 2); + for (idx, mem_cell) in mem_pool.into_iter().enumerate() { + if idx % 2 == 0 { + let addr = mem_cell; + addrs.push(addr); + } else { + let value = mem_cell; + values.push(value); + } + } + + let mut sorted_addr_idxs: Vec = (0..addrs.len()).collect(); + sorted_addr_idxs.sort_by_key(|&idx| addrs[idx]); + for idx in sorted_addr_idxs.iter() { + sorted_addrs.push(addrs[*idx]); + sorted_values.push(values[*idx]); + } + + let mut sorted_addrs_iter = sorted_addrs.into_iter(); + let mut sorted_values_iter = sorted_values.into_iter(); + for row_idx in 0..trace.num_rows() { + if row_idx % 2 == 0 { + let addr = sorted_addrs_iter.next().unwrap(); + trace.set_main(row_idx, 4, addr); + } else { + let value = sorted_values_iter.next().unwrap(); + trace.set_main(row_idx, 4, value); + } + } +} + +pub(crate) fn set_rc_permutation_column(trace: &mut CairoTraceTable, z: &Felt252) { + let mut denominator_evaluations = trace + .get_column_main(2) + .iter() + .map(|a_prime| z - a_prime) + .collect_vec(); + FieldElement::inplace_batch_inverse(&mut denominator_evaluations).unwrap(); + + let rc_cumulative_procuts = trace + .get_column_main(0) + .iter() + .zip(&denominator_evaluations) + .scan(Felt252::one(), |product, (num_i, den_i)| { + let ret = *product; + *product = ret * (z - num_i) * den_i; + Some(*product) + }) + .collect_vec(); + + for (i, rc_perm_i) in rc_cumulative_procuts.into_iter().enumerate() { + trace.set_aux(i, 0, rc_perm_i) + } +} + +pub(crate) fn set_mem_permutation_column( + trace: &mut CairoTraceTable, + alpha_mem: &Felt252, + z_mem: &Felt252, +) { + let sorted_mem_pool = trace.get_column_main(4); + let sorted_addrs = sorted_mem_pool.iter().step_by(2).collect_vec(); + let sorted_values = sorted_mem_pool[1..].iter().step_by(2).collect_vec(); + + let mut denominator = std::iter::zip(sorted_addrs, sorted_values) + .map(|(ap, vp)| z_mem - (ap + alpha_mem * vp)) + .collect_vec(); + FieldElement::inplace_batch_inverse(&mut denominator).unwrap(); + + let mem_pool = trace.get_column_main(3); + let addrs = mem_pool.iter().step_by(2).collect_vec(); + let values = mem_pool[1..].iter().step_by(2).collect_vec(); + + let mem_cumulative_products = itertools::izip!(addrs, values, denominator) + .scan(Felt252::one(), |product, (a_i, v_i, den_i)| { + let ret = *product; + *product = ret * ((z_mem - (a_i + alpha_mem * v_i)) * den_i); + Some(*product) + }) + .collect_vec(); + + for (i, row_idx) in (0..trace.num_rows()).step_by(2).enumerate() { + let mem_cumul_prod = mem_cumulative_products[i]; + trace.set_aux(row_idx, 1, mem_cumul_prod); + } +} + #[cfg(test)] mod test { - use crate::air::EXTRA_VAL; use super::*; - use lambdaworks_math::field::element::FieldElement; - use stark_platinum_prover::table::Table; + use crate::{ + cairo_layout::CairoLayout, runner::run::run_program, tests::utils::cairo0_program_path, + }; #[test] fn test_rc_decompose() { @@ -593,75 +851,13 @@ mod test { assert_eq!(decomposition_columns[7][2], Felt252::from_hex("1").unwrap()); } - #[test] - fn test_fill_range_check_values() { - let columns = vec![ - vec![FieldElement::from(1); 3], - vec![FieldElement::from(4); 3], - vec![FieldElement::from(7); 3], - ]; - let expected_col = vec![ - FieldElement::from(2), - FieldElement::from(3), - FieldElement::from(5), - FieldElement::from(6), - FieldElement::from(7), - FieldElement::from(7), - ]; - let table = TraceTable::::from_columns(columns, 3, 1); - - let (col, rc_min, rc_max) = get_rc_holes(&table, &[0, 1, 2]); - assert_eq!(col, expected_col); - assert_eq!(rc_min, 1); - assert_eq!(rc_max, 7); - } - - #[test] - fn test_add_missing_values_to_rc_holes_column() { - let mut row = vec![Felt252::from(5); 36]; - row[35] = Felt252::zero(); - let data = row.repeat(8); - let table = Table::new(data, 36); - - let mut main_trace = TraceTable:: { - table, - num_main_columns: 36, - num_aux_columns: 23, - step_size: 1, - }; - - let rc_holes = vec![ - Felt252::from(1), - Felt252::from(2), - Felt252::from(3), - Felt252::from(4), - Felt252::from(5), - Felt252::from(6), - ]; - - fill_rc_holes(&mut main_trace, &rc_holes); - - let expected_rc_holes_column = vec![ - Felt252::from(1), - Felt252::from(2), - Felt252::from(3), - Felt252::from(4), - Felt252::from(5), - Felt252::from(6), - Felt252::from(6), - Felt252::from(6), - ]; - - let rc_holes_column = main_trace.columns()[35].clone(); - - assert_eq!(expected_rc_holes_column, rc_holes_column); - } - #[test] fn test_get_memory_holes_empty_pub_memory() { // We construct a sorted addresses list [1, 2, 3, 6, 7, 8, 9, 13, 14, 15], and // an empty public memory. This way, any holes present between // the min and max addresses should be returned by the function. + // NOTE: The memory hole at address 16 will also be returned because the max addr + // +1 is considered a memory hole too. let mut addrs: Vec = (1..4).map(Felt252::from).collect(); let addrs_extension: Vec = (6..10).map(Felt252::from).collect(); addrs.extend_from_slice(&addrs_extension); @@ -669,13 +865,14 @@ mod test { addrs.extend_from_slice(&addrs_extension); let pub_memory = HashMap::new(); - let expected_memory_holes = vec![ + let expected_memory_holes = VecDeque::from([ Felt252::from(4), Felt252::from(5), Felt252::from(10), Felt252::from(11), Felt252::from(12), - ]; + Felt252::from(16), + ]); let calculated_memory_holes = get_memory_holes(&addrs, &pub_memory); assert_eq!(expected_memory_holes, calculated_memory_holes); @@ -692,13 +889,15 @@ mod test { addrs.extend_from_slice(&addrs_extension); let mut pub_memory = HashMap::new(); - (1..=9).for_each(|k| { - let addr = Felt252::from(k); - pub_memory.insert(addr, addr * Felt252::from(2)); - }); + for addr in 1..=9 { + let addr = Felt252::from(addr); + pub_memory.insert(addr, Felt252::zero()); + } let calculated_memory_holes = get_memory_holes(&addrs, &pub_memory); - let expected_memory_holes: Vec = Vec::new(); + + // max_addr + 1 (10, in this case) is always returned by the get_memory_holes function + let expected_memory_holes = VecDeque::from([Felt252::from(10)]); assert_eq!(expected_memory_holes, calculated_memory_holes); } @@ -714,37 +913,252 @@ mod test { addrs.extend_from_slice(&addrs_extension); let mut pub_memory = HashMap::new(); - (1..=6).for_each(|k| { - let addr = Felt252::from(k); - pub_memory.insert(addr, addr * Felt252::from(2)); - }); + for addr in 0..=6 { + let addr = Felt252::from(addr); + pub_memory.insert(addr, Felt252::zero()); + } let calculated_memory_holes = get_memory_holes(&addrs, &pub_memory); - let expected_memory_holes = vec![Felt252::from(7)]; + let expected_memory_holes = VecDeque::from([Felt252::from(7), Felt252::from(10)]); assert_eq!(expected_memory_holes, calculated_memory_holes); } #[test] - fn test_fill_memory_holes() { - const TRACE_COL_LEN: usize = 2; - const NUM_TRACE_COLS: usize = EXTRA_VAL + 1; - - let mut trace_cols = vec![vec![Felt252::zero(); TRACE_COL_LEN]; NUM_TRACE_COLS]; - trace_cols[FRAME_PC][0] = Felt252::one(); - trace_cols[FRAME_DST_ADDR][0] = Felt252::from(2); - trace_cols[FRAME_OP0_ADDR][0] = Felt252::from(3); - trace_cols[FRAME_OP1_ADDR][0] = Felt252::from(5); - trace_cols[FRAME_PC][1] = Felt252::from(6); - trace_cols[FRAME_DST_ADDR][1] = Felt252::from(9); - trace_cols[FRAME_OP0_ADDR][1] = Felt252::from(10); - trace_cols[FRAME_OP1_ADDR][1] = Felt252::from(11); - let mut trace = TraceTable::from_columns(trace_cols, 2, 1); - - let memory_holes = vec![Felt252::from(4), Felt252::from(7), Felt252::from(8)]; - fill_memory_holes(&mut trace, &memory_holes); - - let extra_addr = &trace.columns()[EXTRA_ADDR]; - assert_eq!(extra_addr, &memory_holes); + fn set_rc_pool_works() { + let program_content = std::fs::read(cairo0_program_path("fibonacci_stone.json")).unwrap(); + let mut trace: CairoTraceTable = TraceTable::allocate_with_zeros(128, 6, 2, 16); + let (register_states, memory, _) = + run_program(None, CairoLayout::Plain, &program_content).unwrap(); + + let (_, biased_offsets): (Vec, Vec) = + register_states + .flags_and_offsets(&memory) + .unwrap() + .into_iter() + .unzip(); + + let unbiased_offsets: Vec<(Felt252, Felt252, Felt252)> = biased_offsets + .iter() + .map(InstructionOffsets::to_trace_representation) + .collect(); + + let rc_values = set_rc_pool(&mut trace, unbiased_offsets); + let mut sorted_rc_values: Vec = rc_values + .iter() + .map(|x| x.representative().into()) + .collect(); + sorted_rc_values.sort(); + let rc_holes = get_rc_holes(&sorted_rc_values); + let rc_max = Felt252::from(*(sorted_rc_values.last().unwrap()) as u64); + finalize_rc_pool(&mut trace, rc_holes, rc_max); + + let mut sorted_rc_column = trace.get_column_main(0); + sorted_rc_column.sort_by_key(|x| x.representative()); + set_sorted_rc_pool(&mut trace, sorted_rc_column); + + trace.main_table.columns()[2] + .iter() + .enumerate() + .for_each(|(i, v)| println!("SORTED RC VAL {} - {}", i, v)); + } + + #[test] + fn set_update_pc_works() { + let program_content = std::fs::read(cairo0_program_path("fibonacci_stone.json")).unwrap(); + let mut trace: CairoTraceTable = TraceTable::allocate_with_zeros(128, 6, 2, 16); + let (register_states, memory, _) = + run_program(None, CairoLayout::Plain, &program_content).unwrap(); + + let (flags, biased_offsets): (Vec, Vec) = + register_states + .flags_and_offsets(&memory) + .unwrap() + .into_iter() + .unzip(); + + // dst, op0, op1 and res are computed from flags and offsets + let (_dst_addrs, mut dsts): (Vec, Vec) = + compute_dst(&flags, &biased_offsets, ®ister_states, &memory); + let (_op0_addrs, mut op0s): (Vec, Vec) = + compute_op0(&flags, &biased_offsets, ®ister_states, &memory); + let (_op1_addrs, op1s): (Vec, Vec) = + compute_op1(&flags, &biased_offsets, ®ister_states, &memory, &op0s); + let mut res = compute_res(&flags, &op0s, &op1s, &dsts); + + update_values(&flags, ®ister_states, &mut op0s, &mut dsts, &mut res); + + let aps: Vec = register_states + .rows + .iter() + .map(|t| Felt252::from(t.ap)) + .collect(); + let fps: Vec = register_states + .rows + .iter() + .map(|t| Felt252::from(t.fp)) + .collect(); + + let trace_repr_flags: Vec<[Felt252; 16]> = flags + .iter() + .map(CairoInstructionFlags::to_trace_representation) + .collect(); + + let two = Felt252::from(2); + let t0: Vec = trace_repr_flags + .iter() + .zip(&dsts) + .map(|(repr_flags, dst)| (repr_flags[9] - two * repr_flags[10]) * dst) + .collect(); + let t1: Vec = t0.iter().zip(&res).map(|(t, r)| t * r).collect(); + let mul: Vec = op0s.iter().zip(&op1s).map(|(op0, op1)| op0 * op1).collect(); + + set_update_pc(&mut trace, aps, t0, t1, mul, fps, res); + + trace.main_table.columns()[5][0..50] + .iter() + .enumerate() + .for_each(|(i, v)| println!("ROW {} - VALUE: {}", i, v)); + } + + #[test] + fn set_mem_pool_works() { + let program_content = std::fs::read(cairo0_program_path("fibonacci_stone.json")).unwrap(); + let mut trace: CairoTraceTable = TraceTable::allocate_with_zeros(128, 6, 2, 16); + let (register_states, memory, pub_inputs) = + run_program(None, CairoLayout::Plain, &program_content).unwrap(); + + let (flags, biased_offsets): (Vec, Vec) = + register_states + .flags_and_offsets(&memory) + .unwrap() + .into_iter() + .unzip(); + + // dst, op0, op1 and res are computed from flags and offsets + let (dst_addrs, mut dsts): (Vec, Vec) = + compute_dst(&flags, &biased_offsets, ®ister_states, &memory); + let (op0_addrs, mut op0s): (Vec, Vec) = + compute_op0(&flags, &biased_offsets, ®ister_states, &memory); + let (op1_addrs, op1s): (Vec, Vec) = + compute_op1(&flags, &biased_offsets, ®ister_states, &memory, &op0s); + let mut res = compute_res(&flags, &op0s, &op1s, &dsts); + + update_values(&flags, ®ister_states, &mut op0s, &mut dsts, &mut res); + + let pcs: Vec = register_states + .rows + .iter() + .map(|t| Felt252::from(t.pc)) + .collect(); + let instructions: Vec = register_states + .rows + .iter() + .map(|t| *memory.get(&t.pc).unwrap()) + .collect(); + + let mut sorted_addrs = set_mem_pool( + &mut trace, + pcs, + instructions, + op0_addrs, + op0s, + dst_addrs, + dsts, + op1_addrs, + op1s, + ); + + sorted_addrs.sort_by_key(|x| x.representative()); + let memory_holes = get_memory_holes(&sorted_addrs, &pub_inputs.public_memory); + finalize_mem_pool(&mut trace, memory_holes); + + set_sorted_mem_pool(&mut trace, pub_inputs.public_memory); + + let z = Felt252::from_hex_unchecked( + "0x6896a2e62f03d4d1f625efb97468ef93f31105bb51a83d550bca6fdebd035de", + ); + let alpha = Felt252::from_hex_unchecked( + "0x64de8f5be59594e112d438c13ec4916e138b013e7d388b681c11b03ede7962e", + ); + set_mem_permutation_column(&mut trace, &alpha, &z); + + trace.aux_table.columns()[1] + .iter() + .enumerate() + .for_each(|(i, v)| println!("ROW {} - MEM CUMUL PROD: {}", i, v)); + } + + #[test] + fn set_bit_prefix_flags_works() { + let program_content = std::fs::read(cairo0_program_path("fibonacci_stone.json")).unwrap(); + let mut trace: CairoTraceTable = TraceTable::allocate_with_zeros(128, 6, 2, 16); + let (register_states, memory, _) = + run_program(None, CairoLayout::Plain, &program_content).unwrap(); + + let (flags, _biased_offsets): (Vec, Vec) = + register_states + .flags_and_offsets(&memory) + .unwrap() + .into_iter() + .unzip(); + + let bit_prefix_flags: Vec<[Felt252; 16]> = flags + .iter() + .map(CairoInstructionFlags::to_trace_representation) + .collect(); + + set_bit_prefix_flags(&mut trace, bit_prefix_flags); + + trace.main_table.columns()[1][0..50] + .iter() + .enumerate() + .for_each(|(i, v)| println!("ROW {} - VALUE: {}", i, v)); + } + + #[test] + fn set_rc_permutation_col_works() { + let program_content = std::fs::read(cairo0_program_path("fibonacci_stone.json")).unwrap(); + let mut trace: CairoTraceTable = TraceTable::allocate_with_zeros(128, 6, 2, 16); + let (register_states, memory, _) = + run_program(None, CairoLayout::Plain, &program_content).unwrap(); + + let (_, biased_offsets): (Vec, Vec) = + register_states + .flags_and_offsets(&memory) + .unwrap() + .into_iter() + .unzip(); + + let unbiased_offsets: Vec<(Felt252, Felt252, Felt252)> = biased_offsets + .iter() + .map(InstructionOffsets::to_trace_representation) + .collect(); + + let rc_values = set_rc_pool(&mut trace, unbiased_offsets); + let mut sorted_rc_values: Vec = rc_values + .iter() + .map(|x| x.representative().into()) + .collect(); + sorted_rc_values.sort(); + + let rc_holes = get_rc_holes(&sorted_rc_values); + let rc_max = Felt252::from(*(sorted_rc_values.last().unwrap()) as u64); + finalize_rc_pool(&mut trace, rc_holes, rc_max); + + let mut sorted_rc_column = trace.get_column_main(0); + sorted_rc_column.sort_by_key(|x| x.representative()); + set_sorted_rc_pool(&mut trace, sorted_rc_column); + + let z = Felt252::from_hex_unchecked( + "0x221ee7f99bdf1f11e16445f06fd90f413146e1764a1d16d46525148456cc3eb", + ); + + set_rc_permutation_column(&mut trace, &z); + + trace.aux_table.columns()[0][..20] + .iter() + .enumerate() + .for_each(|(i, v)| println!("RC PERMUTATION ARG {} - {}", i, v)); } } diff --git a/provers/cairo/src/layouts/mod.rs b/provers/cairo/src/layouts/mod.rs new file mode 100644 index 000000000..6c83de882 --- /dev/null +++ b/provers/cairo/src/layouts/mod.rs @@ -0,0 +1 @@ +pub mod plain; diff --git a/provers/cairo/src/air.rs b/provers/cairo/src/layouts/plain/air.rs similarity index 61% rename from provers/cairo/src/air.rs rename to provers/cairo/src/layouts/plain/air.rs index 2d15f5672..9e0436e10 100644 --- a/provers/cairo/src/air.rs +++ b/provers/cairo/src/layouts/plain/air.rs @@ -1,7 +1,10 @@ -use super::{cairo_mem::CairoMemory, register_states::RegisterStates}; -use crate::transition_constraints::*; +use crate::{ + cairo_mem::CairoMemory, + execution_trace::{set_mem_permutation_column, set_rc_permutation_column, CairoTraceTable}, + register_states::RegisterStates, + transition_constraints::*, +}; use cairo_vm::{air_public_input::MemorySegmentAddresses, without_std::collections::HashMap}; -#[cfg(debug_assertions)] use itertools::Itertools; use lambdaworks_crypto::fiat_shamir::is_transcript::IsTranscript; use lambdaworks_math::{ @@ -11,6 +14,7 @@ use lambdaworks_math::{ }, traits::{AsBytes, ByteConversion, Deserializable}, }; +use stark_platinum_prover::constraints::transition::TransitionConstraint; use stark_platinum_prover::{ constraints::boundary::{BoundaryConstraint, BoundaryConstraints}, context::AirContext, @@ -23,63 +27,6 @@ use stark_platinum_prover::{ verifier::{IsStarkVerifier, Verifier}, Felt252, }; -use stark_platinum_prover::{constraints::transition::TransitionConstraint, table::Table}; - -// TODO: These should probably be in the TraceTable module. -pub const FRAME_RES: usize = 16; -pub const FRAME_AP: usize = 17; -pub const FRAME_FP: usize = 18; -pub const FRAME_PC: usize = 19; -pub const FRAME_DST_ADDR: usize = 20; -pub const FRAME_OP0_ADDR: usize = 21; -pub const FRAME_OP1_ADDR: usize = 22; -pub const FRAME_INST: usize = 23; -pub const FRAME_DST: usize = 24; -pub const FRAME_OP0: usize = 25; -pub const FRAME_OP1: usize = 26; -pub const OFF_DST: usize = 27; -pub const OFF_OP0: usize = 28; -pub const OFF_OP1: usize = 29; -pub const FRAME_T0: usize = 30; -pub const FRAME_T1: usize = 31; -pub const FRAME_MUL: usize = 32; -pub const EXTRA_ADDR: usize = 33; -pub const EXTRA_VAL: usize = 34; -pub const RC_HOLES: usize = 35; - -// Auxiliary range check columns -pub const RANGE_CHECK_COL_1: usize = 0; -pub const RANGE_CHECK_COL_2: usize = 1; -pub const RANGE_CHECK_COL_3: usize = 2; -pub const RANGE_CHECK_COL_4: usize = 3; - -// Auxiliary memory columns -pub const MEMORY_ADDR_SORTED_0: usize = 4; -pub const MEMORY_ADDR_SORTED_1: usize = 5; -pub const MEMORY_ADDR_SORTED_2: usize = 6; -pub const MEMORY_ADDR_SORTED_3: usize = 7; -pub const MEMORY_ADDR_SORTED_4: usize = 8; - -pub const MEMORY_VALUES_SORTED_0: usize = 9; -pub const MEMORY_VALUES_SORTED_1: usize = 10; -pub const MEMORY_VALUES_SORTED_2: usize = 11; -pub const MEMORY_VALUES_SORTED_3: usize = 12; -pub const MEMORY_VALUES_SORTED_4: usize = 13; - -pub const PERMUTATION_ARGUMENT_COL_0: usize = 14; -pub const PERMUTATION_ARGUMENT_COL_1: usize = 15; -pub const PERMUTATION_ARGUMENT_COL_2: usize = 16; -pub const PERMUTATION_ARGUMENT_COL_3: usize = 17; -pub const PERMUTATION_ARGUMENT_COL_4: usize = 18; - -pub const PERMUTATION_ARGUMENT_RANGE_CHECK_COL_1: usize = 19; -pub const PERMUTATION_ARGUMENT_RANGE_CHECK_COL_2: usize = 20; -pub const PERMUTATION_ARGUMENT_RANGE_CHECK_COL_3: usize = 21; -pub const PERMUTATION_ARGUMENT_RANGE_CHECK_COL_4: usize = 22; - -// Trace layout -pub const MEM_P_TRACE_OFFSET: usize = 17; -pub const MEM_A_TRACE_OFFSET: usize = 19; #[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] pub enum SegmentName { @@ -435,110 +382,12 @@ pub struct CairoAIR { Vec>>, } -/// Receives two slices corresponding to the accessed addresses and values, filled with -/// the memory holes and with the (0, 0) public memory dummy accesses. -/// Each (address, value) public memory pair is written in a (0, 0) dummy access until -/// there is no one left. -/// -/// NOTE: At the end of this process there might be some additional (0, 0) dummy accesses -/// that were not overwritten. This is not a problem as long as all the public memory pairs -/// have been written. -fn add_pub_memory_in_public_input_section( - addresses: &[Felt252], - values: &[Felt252], - public_input: &PublicInputs, -) -> (Vec, Vec) { - let mut a_aux = addresses.to_owned(); - let mut v_aux = values.to_owned(); - - let mut pub_addrs = public_input.public_memory.iter(); - - // Iterate over addresses - for (i, a) in a_aux.iter_mut().enumerate() { - // When address `0` is found, it means it corresponds to a dummy access. - if a == &Felt252::zero() { - // While there are public memory addresses left, overwrite the dummy - // (addr, value) accesses with the real public memory pairs. - if let Some((pub_addr, pub_value)) = pub_addrs.next() { - *a = *pub_addr; - v_aux[i] = *pub_value; - } else { - // When there are no public memory pairs left to write, break the - // loop and return the (addr, value) pairs with dummy accesses - // overwritten. - break; - } - } - } - - (a_aux, v_aux) -} - -fn sort_columns_by_memory_address( - adresses: Vec, - values: Vec, -) -> (Vec, Vec) { - let mut tuples: Vec<_> = adresses.into_iter().zip(values).collect(); - tuples.sort_by(|(x, _), (y, _)| x.representative().cmp(&y.representative())); - tuples.into_iter().unzip() -} - -fn generate_memory_permutation_argument_column( - addresses_original: Vec, - values_original: Vec, - addresses_sorted: &[Felt252], - values_sorted: &[Felt252], - rap_challenges: &[Felt252], -) -> Vec { - let z = &rap_challenges[1]; - let alpha = &rap_challenges[0]; - - let mut denom: Vec<_> = addresses_sorted - .iter() - .zip(values_sorted) - .map(|(ap, vp)| z - (ap + alpha * vp)) - .collect(); - FieldElement::inplace_batch_inverse(&mut denom).unwrap(); - // Returns the cumulative products of the numerators and denominators - addresses_original - .iter() - .zip(&values_original) - .zip(&denom) - .scan(Felt252::one(), |product, ((a_i, v_i), den_i)| { - let ret = *product; - *product = ret * ((z - (a_i + alpha * v_i)) * den_i); - Some(*product) - }) - .collect::>() -} - -fn generate_range_check_permutation_argument_column( - offset_column_original: &[Felt252], - offset_column_sorted: &[Felt252], - rap_challenges: &[Felt252], -) -> Vec { - let z = rap_challenges[2]; - - let mut denom: Vec<_> = offset_column_sorted.iter().map(|x| z - x).collect(); - FieldElement::inplace_batch_inverse(&mut denom).unwrap(); - - offset_column_original - .iter() - .zip(&denom) - .scan(Felt252::one(), |product, (num_i, den_i)| { - let ret = *product; - *product = ret * (z - num_i) * den_i; - Some(*product) - }) - .collect::>() -} - impl AIR for CairoAIR { type Field = Stark252PrimeField; type FieldExtension = Stark252PrimeField; type PublicInputs = PublicInputs; - const STEP_SIZE: usize = 1; + const STEP_SIZE: usize = 16; /// Creates a new CairoAIR from proof_options /// @@ -553,26 +402,12 @@ impl AIR for CairoAIR { proof_options: &ProofOptions, ) -> Self { debug_assert!(trace_length.is_power_of_two()); - let trace_columns = 59; + let trace_columns = 8; let transition_constraints: Vec< Box>, > = vec![ - Box::new(BitPrefixFlag0::new()), - Box::new(BitPrefixFlag1::new()), - Box::new(BitPrefixFlag2::new()), - Box::new(BitPrefixFlag3::new()), - Box::new(BitPrefixFlag4::new()), - Box::new(BitPrefixFlag5::new()), - Box::new(BitPrefixFlag6::new()), - Box::new(BitPrefixFlag7::new()), - Box::new(BitPrefixFlag8::new()), - Box::new(BitPrefixFlag9::new()), - Box::new(BitPrefixFlag10::new()), - Box::new(BitPrefixFlag11::new()), - Box::new(BitPrefixFlag12::new()), - Box::new(BitPrefixFlag13::new()), - Box::new(BitPrefixFlag14::new()), + Box::new(BitPrefixFlag::new()), Box::new(ZeroFlagConstraint::new()), Box::new(InstructionUnpacking::new()), Box::new(CpuOperandsMemDstAddr::new()), @@ -589,29 +424,11 @@ impl AIR for CairoAIR { Box::new(CpuOpcodesCallPushFp::new()), Box::new(CpuOpcodesCallPushPc::new()), Box::new(CpuOpcodesAssertEq::new()), - Box::new(MemoryDiffIsBit0::new()), - Box::new(MemoryDiffIsBit1::new()), - Box::new(MemoryDiffIsBit2::new()), - Box::new(MemoryDiffIsBit3::new()), - Box::new(MemoryDiffIsBit4::new()), - Box::new(MemoryIsFunc0::new()), - Box::new(MemoryIsFunc1::new()), - Box::new(MemoryIsFunc2::new()), - Box::new(MemoryIsFunc3::new()), - Box::new(MemoryIsFunc4::new()), - Box::new(MemoryMultiColumnPermStep0_0::new()), - Box::new(MemoryMultiColumnPermStep0_1::new()), - Box::new(MemoryMultiColumnPermStep0_2::new()), - Box::new(MemoryMultiColumnPermStep0_3::new()), - Box::new(MemoryMultiColumnPermStep0_4::new()), - Box::new(Rc16DiffIsBit0::new()), - Box::new(Rc16DiffIsBit1::new()), - Box::new(Rc16DiffIsBit2::new()), - Box::new(Rc16DiffIsBit3::new()), - Box::new(Rc16PermStep0_0::new()), - Box::new(Rc16PermStep0_1::new()), - Box::new(Rc16PermStep0_2::new()), - Box::new(Rc16PermStep0_3::new()), + Box::new(MemoryDiffIsBit::new()), + Box::new(MemoryIsFunc::new()), + Box::new(MemoryMultiColumnPermStep0::new()), + Box::new(Rc16DiffIsBit::new()), + Box::new(Rc16PermStep0::new()), Box::new(FlagOp1BaseOp0BitConstraint::new()), Box::new(FlagResOp1BitConstraint::new()), Box::new(FlagPcUpdateRegularBit::new()), @@ -639,30 +456,24 @@ impl AIR for CairoAIR { (0..transition_constraints.len()) .for_each(|idx| debug_assert!(constraints_set.iter().contains(&idx))); - assert_eq!(transition_constraints.len(), 64); + assert_eq!(transition_constraints.len(), 32); } - - assert_eq!(transition_constraints.len(), 64); - - let transition_exemptions = transition_constraints - .iter() - .map(|c| c.end_exemptions()) - .collect(); - + let context = AirContext { proof_options: proof_options.clone(), trace_columns, - transition_exemptions, transition_offsets: vec![0, 1], num_transition_constraints: transition_constraints.len(), }; // The number of the transition constraints // and transition exemptions should be the same always. + /* debug_assert_eq!( context.transition_exemptions.len(), context.num_transition_constraints ); + */ Self { context, @@ -674,92 +485,15 @@ impl AIR for CairoAIR { fn build_auxiliary_trace( &self, - main_trace: &TraceTable, + trace: &mut TraceTable, rap_challenges: &[Felt252], - ) -> TraceTable { - let addresses_original = main_trace.merge_columns(&[ - FRAME_PC, - FRAME_DST_ADDR, - FRAME_OP0_ADDR, - FRAME_OP1_ADDR, - EXTRA_ADDR, - ]); - - let values_original = - main_trace.merge_columns(&[FRAME_INST, FRAME_DST, FRAME_OP0, FRAME_OP1, EXTRA_VAL]); - - let (addresses, values) = add_pub_memory_in_public_input_section( - &addresses_original, - &values_original, - &self.pub_inputs, - ); - - let (addresses, values) = sort_columns_by_memory_address(addresses, values); - - let permutation_col = generate_memory_permutation_argument_column( - addresses_original, - values_original, - &addresses, - &values, - rap_challenges, - ); + ) { + let alpha_mem = rap_challenges[0]; + let z_mem = rap_challenges[1]; + let z_rc = rap_challenges[2]; - // Range Check - let offsets_original = main_trace.merge_columns(&[OFF_DST, OFF_OP0, OFF_OP1, RC_HOLES]); - - let mut offsets_sorted: Vec = offsets_original - .iter() - .map(|x| x.representative().into()) - .collect(); - offsets_sorted.sort(); - let offsets_sorted: Vec<_> = offsets_sorted - .iter() - .map(|x| FieldElement::from(*x as u64)) - .collect(); - - let range_check_permutation_col = generate_range_check_permutation_argument_column( - &offsets_original, - &offsets_sorted, - rap_challenges, - ); - - // Convert from long-format to wide-format again - let mut aux_data = Vec::new(); - for i in 0..main_trace.n_rows() { - aux_data.push(offsets_sorted[4 * i]); - aux_data.push(offsets_sorted[4 * i + 1]); - aux_data.push(offsets_sorted[4 * i + 2]); - aux_data.push(offsets_sorted[4 * i + 3]); - aux_data.push(addresses[5 * i]); - aux_data.push(addresses[5 * i + 1]); - aux_data.push(addresses[5 * i + 2]); - aux_data.push(addresses[5 * i + 3]); - aux_data.push(addresses[5 * i + 4]); - aux_data.push(values[5 * i]); - aux_data.push(values[5 * i + 1]); - aux_data.push(values[5 * i + 2]); - aux_data.push(values[5 * i + 3]); - aux_data.push(values[5 * i + 4]); - aux_data.push(permutation_col[5 * i]); - aux_data.push(permutation_col[5 * i + 1]); - aux_data.push(permutation_col[5 * i + 2]); - aux_data.push(permutation_col[5 * i + 3]); - aux_data.push(permutation_col[5 * i + 4]); - aux_data.push(range_check_permutation_col[4 * i]); - aux_data.push(range_check_permutation_col[4 * i + 1]); - aux_data.push(range_check_permutation_col[4 * i + 2]); - aux_data.push(range_check_permutation_col[4 * i + 3]); - } - - let aux_table = Table::new(aux_data, self.num_auxiliary_rap_columns()); - - let (num_main_columns, num_aux_columns) = self.trace_layout(); - TraceTable { - table: aux_table, - num_main_columns, - num_aux_columns, - step_size: Self::STEP_SIZE, - } + set_rc_permutation_column(trace, &z_rc); + set_mem_permutation_column(trace, &alpha_mem, &z_mem); } fn build_rap_challenges( @@ -774,7 +508,7 @@ impl AIR for CairoAIR { } fn trace_layout(&self) -> (usize, usize) { - (36, 23) + (6, 2) } /// From the Cairo whitepaper, section 9.10. @@ -786,57 +520,60 @@ impl AIR for CairoAIR { /// * pc_0 = pc_i /// * pc_t = pc_f fn boundary_constraints(&self, rap_challenges: &[Felt252]) -> BoundaryConstraints { - let initial_pc = - BoundaryConstraint::new_main(MEM_A_TRACE_OFFSET, 0, self.pub_inputs.pc_init); - let initial_ap = - BoundaryConstraint::new_main(MEM_P_TRACE_OFFSET, 0, self.pub_inputs.ap_init); + let initial_pc = BoundaryConstraint::new_main(3, 0, self.pub_inputs.pc_init); + let initial_ap = BoundaryConstraint::new_main(5, 0, self.pub_inputs.ap_init); let final_pc = BoundaryConstraint::new_main( - MEM_A_TRACE_OFFSET, - self.pub_inputs.num_steps - 1, + 3, + self.trace_length - Self::STEP_SIZE, self.pub_inputs.pc_final, ); let final_ap = BoundaryConstraint::new_main( - MEM_P_TRACE_OFFSET, - self.pub_inputs.num_steps - 1, + 5, + self.trace_length - Self::STEP_SIZE, self.pub_inputs.ap_final, ); - // Auxiliary constraint: permutation argument final value - let final_index = self.trace_length - 1; - let z_memory = rap_challenges[1]; let alpha_memory = rap_challenges[0]; + let one: FieldElement = FieldElement::one(); - let cumulative_product = self + let mem_cumul_prod_denominator_no_padding = self .pub_inputs .public_memory .iter() - .fold(FieldElement::one(), |product, (address, value)| { + .fold(one, |product, (address, value)| { product * (z_memory - (address + alpha_memory * value)) - }) + }); + + const PUB_MEMORY_ADDR_OFFSET: usize = 8; + let pad_addr = Felt252::one(); + let pad_value = self.pub_inputs.public_memory.get(&pad_addr).unwrap(); + let val = z_memory - (pad_addr + alpha_memory * pad_value); + let mem_cumul_prod_denominator_pad = val + .pow(self.trace_length / PUB_MEMORY_ADDR_OFFSET - self.pub_inputs.public_memory.len()); + let mem_cumul_prod_denominator = (mem_cumul_prod_denominator_no_padding + * mem_cumul_prod_denominator_pad) .inv() .unwrap(); + let mem_cumul_prod_final = + z_memory.pow(self.trace_length / PUB_MEMORY_ADDR_OFFSET) * mem_cumul_prod_denominator; - let permutation_final = - z_memory.pow(self.pub_inputs.public_memory.len()) * cumulative_product; - - let permutation_final_constraint = - BoundaryConstraint::new_aux(PERMUTATION_ARGUMENT_COL_4, final_index, permutation_final); + let mem_cumul_prod_final_constraint = + BoundaryConstraint::new_aux(1, self.trace_length - 2, mem_cumul_prod_final); - let one: FieldElement = FieldElement::one(); - let range_check_final_constraint = - BoundaryConstraint::new_aux(PERMUTATION_ARGUMENT_RANGE_CHECK_COL_4, final_index, one); + let rc_cumul_prod_final_constraint = + BoundaryConstraint::new_aux(0, self.trace_length - 1, one); - let range_check_min = BoundaryConstraint::new_aux( - RANGE_CHECK_COL_1, + let rc_min_constraint = BoundaryConstraint::new_main( + 2, 0, FieldElement::from(self.pub_inputs.range_check_min.unwrap() as u64), ); - let range_check_max = BoundaryConstraint::new_aux( - RANGE_CHECK_COL_4, - final_index, + let rc_max_constraint = BoundaryConstraint::new_main( + 2, + self.trace_length - 1, FieldElement::from(self.pub_inputs.range_check_max.unwrap() as u64), ); @@ -845,10 +582,10 @@ impl AIR for CairoAIR { initial_ap, final_pc, final_ap, - permutation_final_constraint, - range_check_final_constraint, - range_check_min, - range_check_max, + mem_cumul_prod_final_constraint, + rc_cumul_prod_final_constraint, + rc_min_constraint, + rc_max_constraint, ]; BoundaryConstraints::from_constraints(constraints) @@ -890,7 +627,7 @@ impl AIR for CairoAIR { /// concrete types. /// The field is set to Stark252PrimeField and the AIR to CairoAIR. pub fn generate_cairo_proof( - trace: &TraceTable, + trace: &mut CairoTraceTable, pub_input: &PublicInputs, proof_options: &ProofOptions, ) -> Result, ProvingError> { @@ -918,93 +655,6 @@ pub fn verify_cairo_proof( ) } -#[cfg(test)] -#[cfg(debug_assertions)] -mod test { - use super::*; - use lambdaworks_math::field::element::FieldElement; - - #[test] - fn test_build_auxiliary_trace_sort_columns_by_memory_address() { - let a = vec![ - FieldElement::from(2), - FieldElement::one(), - FieldElement::from(3), - FieldElement::from(2), - ]; - let v = vec![ - FieldElement::from(6), - FieldElement::from(4), - FieldElement::from(5), - FieldElement::from(6), - ]; - let (ap, vp) = sort_columns_by_memory_address(a, v); - assert_eq!( - ap, - vec![ - FieldElement::one(), - FieldElement::from(2), - FieldElement::from(2), - FieldElement::from(3) - ] - ); - assert_eq!( - vp, - vec![ - FieldElement::from(4), - FieldElement::from(6), - FieldElement::from(6), - FieldElement::from(5), - ] - ); - } - - #[test] - fn test_build_auxiliary_trace_generate_permutation_argument_column() { - let a = vec![ - FieldElement::from(3), - FieldElement::one(), - FieldElement::from(2), - ]; - let v = vec![ - FieldElement::from(5), - FieldElement::one(), - FieldElement::from(2), - ]; - let ap = vec![ - FieldElement::one(), - FieldElement::from(2), - FieldElement::from(3), - ]; - let vp = vec![ - FieldElement::one(), - FieldElement::from(2), - FieldElement::from(5), - ]; - let rap_challenges = vec![ - FieldElement::from(15), - FieldElement::from(10), - FieldElement::zero(), - ]; - - let p = generate_memory_permutation_argument_column(a, v, &ap, &vp, &rap_challenges); - assert_eq!( - p, - vec![ - FieldElement::from_hex( - "2aaaaaaaaaaaab0555555555555555555555555555555555555555555555561" - ) - .unwrap(), - FieldElement::from_hex( - "1745d1745d174602e8ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8ba2ec" - ) - .unwrap(), - FieldElement::one(), - ] - ); - } -} - #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] #[cfg(test)] mod prop_test { @@ -1016,8 +666,8 @@ mod prop_test { use stark_platinum_prover::proof::{options::ProofOptions, stark::StarkProof}; use crate::{ - air::{generate_cairo_proof, verify_cairo_proof}, cairo_layout::CairoLayout, + layouts::plain::air::{generate_cairo_proof, verify_cairo_proof}, runner::run::generate_prover_args, tests::utils::cairo0_program_path, Felt252, @@ -1084,13 +734,13 @@ mod prop_test { #[test] fn deserialize_and_verify() { let program_content = std::fs::read(cairo0_program_path("fibonacci_10.json")).unwrap(); - let (main_trace, pub_inputs) = + let (mut main_trace, pub_inputs) = generate_prover_args(&program_content, CairoLayout::Plain).unwrap(); let proof_options = ProofOptions::default_test_options(); // The proof is generated and serialized. - let proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap(); + let proof = generate_cairo_proof(&mut main_trace, &pub_inputs, &proof_options).unwrap(); let proof_bytes: Vec = serde_cbor::to_vec(&proof).unwrap(); // The trace and original proof are dropped to show that they are decoupled from diff --git a/provers/cairo/src/layouts/plain/mod.rs b/provers/cairo/src/layouts/plain/mod.rs new file mode 100644 index 000000000..83aab11fa --- /dev/null +++ b/provers/cairo/src/layouts/plain/mod.rs @@ -0,0 +1 @@ +pub mod air; diff --git a/provers/cairo/src/lib.rs b/provers/cairo/src/lib.rs index 54384a63c..2013cb087 100644 --- a/provers/cairo/src/lib.rs +++ b/provers/cairo/src/lib.rs @@ -2,12 +2,12 @@ use lambdaworks_math::field::{ element::FieldElement, fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, }; -pub mod air; pub mod cairo_layout; pub mod cairo_mem; pub mod decode; pub mod errors; pub mod execution_trace; +pub mod layouts; pub mod register_states; pub mod runner; pub mod transition_constraints; diff --git a/provers/cairo/src/main.rs b/provers/cairo/src/main.rs index b64a51f26..72f1b827e 100644 --- a/provers/cairo/src/main.rs +++ b/provers/cairo/src/main.rs @@ -3,6 +3,15 @@ use cairo_platinum_prover::cairo_layout::CairoLayout; use cairo_platinum_prover::runner::run::generate_prover_args; use cairo_platinum_prover::runner::run::generate_prover_args_from_trace; use lambdaworks_math::field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField; +<<<<<<< HEAD +use platinum_prover::cairo_layout::CairoLayout; +use platinum_prover::layouts::plain::air::{ + generate_cairo_proof, verify_cairo_proof, PublicInputs, +}; +use platinum_prover::runner::run::generate_prover_args; +use platinum_prover::runner::run::generate_prover_args_from_trace; +======= +>>>>>>> main use stark_platinum_prover::proof::options::{ProofOptions, SecurityLevel}; use stark_platinum_prover::proof::stark::StarkProof; mod commands; @@ -122,7 +131,7 @@ fn generate_proof( // FIXME: We should set this through the CLI in the future let layout = CairoLayout::Plain; - let Ok((main_trace, pub_inputs)) = generate_prover_args(&program_content, layout) else { + let Ok((mut main_trace, pub_inputs)) = generate_prover_args(&program_content, layout) else { eprintln!("Error generating prover args"); return None; }; @@ -131,7 +140,7 @@ fn generate_proof( let timer = Instant::now(); println!("Making proof ..."); - let proof = match generate_cairo_proof(&main_trace, &pub_inputs, proof_options) { + let proof = match generate_cairo_proof(&mut main_trace, &pub_inputs, proof_options) { Ok(p) => p, Err(err) => { eprintln!("Error generating proof: {:?}", err); @@ -154,7 +163,7 @@ fn generate_proof_from_trace( )> { // ## Generating the prover args let timer = Instant::now(); - let Ok((main_trace, pub_inputs)) = + let Ok((mut main_trace, pub_inputs)) = generate_prover_args_from_trace(trace_bin_path, memory_bin_path) else { eprintln!("Error generating prover args"); @@ -165,7 +174,7 @@ fn generate_proof_from_trace( // ## Prove let timer = Instant::now(); println!("Making proof ..."); - let proof = match generate_cairo_proof(&main_trace, &pub_inputs, proof_options) { + let proof = match generate_cairo_proof(&mut main_trace, &pub_inputs, proof_options) { Ok(p) => p, Err(err) => { eprintln!("Error generating proof: {:?}", err); diff --git a/provers/cairo/src/runner/run.rs b/provers/cairo/src/runner/run.rs index 45b22b3c0..a3fd427ff 100644 --- a/provers/cairo/src/runner/run.rs +++ b/provers/cairo/src/runner/run.rs @@ -1,22 +1,16 @@ -use crate::air::{PublicInputs, Segment, SegmentName}; +use super::vec_writer::VecWriter; use crate::cairo_layout::CairoLayout; use crate::cairo_mem::CairoMemory; -use crate::execution_trace::build_main_trace; +use crate::execution_trace::{build_cairo_execution_trace, CairoTraceTable}; +use crate::layouts::plain::air::{PublicInputs, Segment, SegmentName}; use crate::register_states::RegisterStates; use crate::Felt252; - -use super::vec_writer::VecWriter; use cairo_vm::cairo_run::{self, EncodeTraceError}; - use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; - use cairo_vm::vm::errors::{ cairo_run_errors::CairoRunError, trace_errors::TraceError, vm_errors::VirtualMachineError, }; - use cairo_vm::without_std::collections::HashMap; -use lambdaworks_math::field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField; -use stark_platinum_prover::trace::TraceTable; #[derive(Debug)] pub enum Error { @@ -159,18 +153,18 @@ pub fn run_program( pub fn generate_prover_args( program_content: &[u8], layout: CairoLayout, -) -> Result<(TraceTable, PublicInputs), Error> { - let (register_states, memory, mut public_inputs) = run_program(None, layout, program_content)?; +) -> Result<(CairoTraceTable, PublicInputs), Error> { + let (register_states, memory, mut pub_inputs) = run_program(None, layout, program_content)?; - let main_trace = build_main_trace(®ister_states, &memory, &mut public_inputs); + let main_trace = build_cairo_execution_trace(®ister_states, &memory, &mut pub_inputs); - Ok((main_trace, public_inputs)) + Ok((main_trace, pub_inputs)) } pub fn generate_prover_args_from_trace( trace_bin_path: &str, memory_bin_path: &str, -) -> Result<(TraceTable, PublicInputs), Error> { +) -> Result<(CairoTraceTable, PublicInputs), Error> { // ## Generating the prover args let register_states = RegisterStates::from_file(trace_bin_path).expect("Cairo trace bin file not found"); @@ -181,7 +175,7 @@ pub fn generate_prover_args_from_trace( let data_len = 0_usize; let mut pub_inputs = PublicInputs::from_regs_and_mem(®ister_states, &memory, data_len); - let main_trace = build_main_trace(®ister_states, &memory, &mut pub_inputs); + let main_trace = build_cairo_execution_trace(®ister_states, &memory, &mut pub_inputs); Ok((main_trace, pub_inputs)) } diff --git a/provers/cairo/src/tests/integration_tests.rs b/provers/cairo/src/tests/integration_tests.rs index 79f051830..4b0fea0ed 100644 --- a/provers/cairo/src/tests/integration_tests.rs +++ b/provers/cairo/src/tests/integration_tests.rs @@ -1,10 +1,8 @@ use crate::{ - air::{generate_cairo_proof, verify_cairo_proof, CairoAIR}, cairo_layout::CairoLayout, + layouts::plain::air::{generate_cairo_proof, verify_cairo_proof, CairoAIR}, runner::run::generate_prover_args, - tests::utils::{ - cairo0_program_path, test_prove_cairo_program, test_prove_cairo_program_from_trace, - }, + tests::utils::{cairo0_program_path, test_prove_cairo_program}, Felt252, }; use lambdaworks_math::field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField; @@ -31,24 +29,24 @@ fn test_prove_cairo_fibonacci_5() { test_prove_cairo_program(&cairo0_program_path("fibonacci_5.json"), layout); } -#[test_log::test] -fn test_prove_cairo_fibonacci_5_from_trace() { - test_prove_cairo_program_from_trace( - &cairo0_program_path("fibonacci_5_trace.bin"), - &cairo0_program_path("fibonacci_5_memory.bin"), - ); -} +// #[test_log::test] +// fn test_prove_cairo_fibonacci_5_from_trace() { +// test_prove_cairo_program_from_trace( +// &cairo0_program_path("fibonacci_5_trace.bin"), +// &cairo0_program_path("fibonacci_5_memory.bin"), +// ); +// } #[test_log::test] fn test_verifier_rejects_wrong_authentication_paths() { // Setup let proof_options = ProofOptions::default_test_options(); let program_content = std::fs::read(cairo0_program_path("fibonacci_5.json")).unwrap(); - let (main_trace, pub_inputs) = + let (mut main_trace, pub_inputs) = generate_prover_args(&program_content, CairoLayout::Plain).unwrap(); // Generate the proof - let mut proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap(); + let mut proof = generate_cairo_proof(&mut main_trace, &pub_inputs, &proof_options).unwrap(); // Change order of authentication path hashes let query = 0; @@ -70,6 +68,7 @@ fn test_verifier_rejects_wrong_authentication_paths() { assert!(!verify_cairo_proof(&proof, &pub_inputs, &proof_options)); } +#[ignore = "too much time"] #[test_log::test] fn test_prove_cairo_fibonacci_1000() { let layout = CairoLayout::Plain; @@ -86,16 +85,16 @@ fn test_prove_cairo_fibonacci_1000() { #[test_log::test] fn test_verifier_rejects_proof_of_a_slightly_different_program() { let program_content = std::fs::read(cairo0_program_path("simple_program.json")).unwrap(); - let (main_trace, mut pub_input) = + let (mut main_trace, mut pub_input) = generate_prover_args(&program_content, CairoLayout::Plain).unwrap(); let proof_options = ProofOptions::default_test_options(); - let proof = generate_cairo_proof(&main_trace, &pub_input, &proof_options).unwrap(); + let proof = generate_cairo_proof(&mut main_trace, &pub_input, &proof_options).unwrap(); // We modify the original program and verify using this new "corrupted" version let mut corrupted_program = pub_input.public_memory.clone(); - corrupted_program.insert(Felt252::one(), Felt252::from(5)); + corrupted_program.insert(Felt252::one(), Felt252::from(6)); corrupted_program.insert(Felt252::from(3), Felt252::from(5)); // Here we use the corrupted version of the program in the public inputs @@ -106,11 +105,11 @@ fn test_verifier_rejects_proof_of_a_slightly_different_program() { #[test_log::test] fn test_verifier_rejects_proof_with_different_range_bounds() { let program_content = std::fs::read(cairo0_program_path("simple_program.json")).unwrap(); - let (main_trace, mut pub_inputs) = + let (mut main_trace, mut pub_inputs) = generate_prover_args(&program_content, CairoLayout::Plain).unwrap(); let proof_options = ProofOptions::default_test_options(); - let proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap(); + let proof = generate_cairo_proof(&mut main_trace, &pub_inputs, &proof_options).unwrap(); pub_inputs.range_check_min = Some(pub_inputs.range_check_min.unwrap() + 1); assert!(!verify_cairo_proof(&proof, &pub_inputs, &proof_options)); @@ -123,12 +122,12 @@ fn test_verifier_rejects_proof_with_different_range_bounds() { #[test_log::test] fn test_verifier_rejects_proof_with_different_security_params() { let program_content = std::fs::read(cairo0_program_path("fibonacci_5.json")).unwrap(); - let (main_trace, pub_inputs) = + let (mut main_trace, pub_inputs) = generate_prover_args(&program_content, CairoLayout::Plain).unwrap(); let proof_options_prover = ProofOptions::new_secure(SecurityLevel::Conjecturable80Bits, 3); - let proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options_prover).unwrap(); + let proof = generate_cairo_proof(&mut main_trace, &pub_inputs, &proof_options_prover).unwrap(); let proof_options_verifier = ProofOptions::new_secure(SecurityLevel::Conjecturable128Bits, 3); @@ -139,29 +138,28 @@ fn test_verifier_rejects_proof_with_different_security_params() { )); } -#[test] +#[test_log::test] fn check_simple_cairo_trace_evaluates_to_zero() { let program_content = std::fs::read(cairo0_program_path("simple_program.json")).unwrap(); - let (main_trace, public_input) = + let (mut trace, public_input) = generate_prover_args(&program_content, CairoLayout::Plain).unwrap(); - let mut trace_polys = main_trace.compute_trace_polys::(); + let main_trace_polys = trace.compute_trace_polys_main::(); let mut transcript = StoneProverTranscript::new(&[]); let proof_options = ProofOptions::default_test_options(); - let cairo_air = CairoAIR::new(main_trace.n_rows(), &public_input, &proof_options); + let cairo_air = CairoAIR::new(trace.num_rows(), &public_input, &proof_options); let rap_challenges = cairo_air.build_rap_challenges(&mut transcript); - let aux_trace = cairo_air.build_auxiliary_trace(&main_trace, &rap_challenges); - let aux_polys = aux_trace.compute_trace_polys::(); + cairo_air.build_auxiliary_trace(&mut trace, &rap_challenges); - trace_polys.extend_from_slice(&aux_polys); + let aux_trace_polys = trace.compute_trace_polys_aux::(); let domain = Domain::new(&cairo_air); assert!(validate_trace( &cairo_air, - &trace_polys, - &aux_polys, + &main_trace_polys, + &aux_trace_polys, &domain, &rap_challenges )); @@ -170,13 +168,13 @@ fn check_simple_cairo_trace_evaluates_to_zero() { #[test] fn deserialize_and_verify() { let program_content = std::fs::read(cairo0_program_path("fibonacci_10.json")).unwrap(); - let (main_trace, pub_inputs) = + let (mut main_trace, pub_inputs) = generate_prover_args(&program_content, CairoLayout::Plain).unwrap(); let proof_options = ProofOptions::default_test_options(); // The proof is generated and serialized. - let proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap(); + let proof = generate_cairo_proof(&mut main_trace, &pub_inputs, &proof_options).unwrap(); let proof_bytes: Vec = serde_cbor::to_vec(&proof).unwrap(); // The trace and original proof are dropped to show that they are decoupled from diff --git a/provers/cairo/src/tests/utils.rs b/provers/cairo/src/tests/utils.rs index 671d74f94..e4cfdf1b5 100644 --- a/provers/cairo/src/tests/utils.rs +++ b/provers/cairo/src/tests/utils.rs @@ -1,6 +1,6 @@ use crate::{ - air::{generate_cairo_proof, verify_cairo_proof}, cairo_layout::CairoLayout, + layouts::plain::air::{generate_cairo_proof, verify_cairo_proof}, runner::run::generate_prover_args, runner::run::generate_prover_args_from_trace, }; @@ -28,8 +28,8 @@ pub fn test_prove_cairo_program(file_path: &str, layout: CairoLayout) { println!("Making proof ..."); let program_content = std::fs::read(file_path).unwrap(); - let (main_trace, pub_inputs) = generate_prover_args(&program_content, layout).unwrap(); - let proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap(); + let (mut main_trace, pub_inputs) = generate_prover_args(&program_content, layout).unwrap(); + let proof = generate_cairo_proof(&mut main_trace, &pub_inputs, &proof_options).unwrap(); println!(" Time spent in proving: {:?} \n", timer.elapsed()); assert!(verify_cairo_proof(&proof, &pub_inputs, &proof_options)); @@ -37,13 +37,13 @@ pub fn test_prove_cairo_program(file_path: &str, layout: CairoLayout) { pub fn test_prove_cairo_program_from_trace(trace_bin_path: &str, memory_bin_path: &str) { let proof_options = ProofOptions::default_test_options(); - let (main_trace, pub_inputs) = + let (mut main_trace, pub_inputs) = generate_prover_args_from_trace(trace_bin_path, memory_bin_path).unwrap(); // println let timer = Instant::now(); println!("Making proof ..."); - let proof = generate_cairo_proof(&main_trace, &pub_inputs, &proof_options).unwrap(); + let proof = generate_cairo_proof(&mut main_trace, &pub_inputs, &proof_options).unwrap(); println!(" Time spent in proving: {:?} \n", timer.elapsed()); assert!(verify_cairo_proof(&proof, &pub_inputs, &proof_options)); } diff --git a/provers/cairo/src/transition_constraints.rs b/provers/cairo/src/transition_constraints.rs index c5a761622..3de99aa4c 100644 --- a/provers/cairo/src/transition_constraints.rs +++ b/provers/cairo/src/transition_constraints.rs @@ -5,19 +5,19 @@ use stark_platinum_prover::{ }; #[derive(Clone)] -pub struct BitPrefixFlag0; -impl BitPrefixFlag0 { +pub struct BitPrefixFlag; +impl BitPrefixFlag { pub fn new() -> Self { Self } } -impl Default for BitPrefixFlag0 { +impl Default for BitPrefixFlag { fn default() -> Self { Self::new() } } -impl TransitionConstraint for BitPrefixFlag0 { +impl TransitionConstraint for BitPrefixFlag { fn degree(&self) -> usize { 2 } @@ -37,8 +37,8 @@ impl TransitionConstraint for BitPrefixF let constraint_idx = self.constraint_idx(); - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); + let current_flag = current_step.get_main_evaluation_element(0, 1); + let next_flag = current_step.get_main_evaluation_element(1, 1); let one = Felt252::one(); let two = Felt252::from(2); @@ -50,1506 +50,12 @@ impl TransitionConstraint for BitPrefixF transition_evaluations[constraint_idx] = res; } - fn end_exemptions(&self) -> usize { - 0 - } -} - -#[derive(Clone)] -pub struct BitPrefixFlag1; -impl BitPrefixFlag1 { - pub fn new() -> Self { - Self - } -} -impl Default for BitPrefixFlag1 { - fn default() -> Self { - Self::new() - } -} - -impl TransitionConstraint for BitPrefixFlag1 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 1 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -#[derive(Clone)] -pub struct BitPrefixFlag2; -impl BitPrefixFlag2 { - pub fn new() -> Self { - Self - } -} -impl Default for BitPrefixFlag2 { - fn default() -> Self { - Self::new() - } -} - -impl TransitionConstraint for BitPrefixFlag2 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 2 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -#[derive(Clone)] -pub struct BitPrefixFlag3; -impl BitPrefixFlag3 { - pub fn new() -> Self { - Self - } -} -impl Default for BitPrefixFlag3 { - fn default() -> Self { - Self::new() - } -} - -impl TransitionConstraint for BitPrefixFlag3 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 3 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -#[derive(Clone)] -pub struct BitPrefixFlag4; -impl BitPrefixFlag4 { - pub fn new() -> Self { - Self - } -} -impl Default for BitPrefixFlag4 { - fn default() -> Self { - Self::new() - } -} - -impl TransitionConstraint for BitPrefixFlag4 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 4 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -#[derive(Clone)] -pub struct BitPrefixFlag5; -impl BitPrefixFlag5 { - pub fn new() -> Self { - Self - } -} -impl Default for BitPrefixFlag5 { - fn default() -> Self { - Self::new() - } -} - -impl TransitionConstraint for BitPrefixFlag5 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 5 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -#[derive(Clone)] -pub struct BitPrefixFlag6; -impl BitPrefixFlag6 { - pub fn new() -> Self { - Self - } -} -impl Default for BitPrefixFlag6 { - fn default() -> Self { - Self::new() - } -} - -impl TransitionConstraint for BitPrefixFlag6 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 6 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -#[derive(Clone)] -pub struct BitPrefixFlag7; -impl Default for BitPrefixFlag7 { - fn default() -> Self { - Self::new() - } -} - -impl BitPrefixFlag7 { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for BitPrefixFlag7 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 7 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -#[derive(Clone)] -pub struct BitPrefixFlag8; -impl Default for BitPrefixFlag8 { - fn default() -> Self { - Self::new() - } -} - -impl BitPrefixFlag8 { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for BitPrefixFlag8 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 8 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -#[derive(Clone)] -pub struct BitPrefixFlag9; -impl Default for BitPrefixFlag9 { - fn default() -> Self { - Self::new() - } -} - -impl BitPrefixFlag9 { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for BitPrefixFlag9 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 9 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -#[derive(Clone)] -pub struct BitPrefixFlag10; -impl Default for BitPrefixFlag10 { - fn default() -> Self { - Self::new() - } -} - -impl BitPrefixFlag10 { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for BitPrefixFlag10 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 10 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct BitPrefixFlag11; -impl Default for BitPrefixFlag11 { - fn default() -> Self { - Self::new() - } -} - -impl BitPrefixFlag11 { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for BitPrefixFlag11 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 11 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct BitPrefixFlag12; -impl Default for BitPrefixFlag12 { - fn default() -> Self { - Self::new() - } -} - -impl BitPrefixFlag12 { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for BitPrefixFlag12 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 12 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct BitPrefixFlag13; -impl Default for BitPrefixFlag13 { - fn default() -> Self { - Self::new() - } -} - -impl BitPrefixFlag13 { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for BitPrefixFlag13 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 13 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct BitPrefixFlag14; -impl Default for BitPrefixFlag14 { - fn default() -> Self { - Self::new() - } -} - -impl BitPrefixFlag14 { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for BitPrefixFlag14 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 14 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let constraint_idx = self.constraint_idx(); - - let current_flag = current_step.get_main_evaluation_element(0, constraint_idx); - let next_flag = current_step.get_main_evaluation_element(0, constraint_idx + 1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let bit = current_flag - two * next_flag; - - let res = bit * (bit - one); - - transition_evaluations[constraint_idx] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct ZeroFlagConstraint; -impl Default for ZeroFlagConstraint { - fn default() -> Self { - Self::new() - } -} - -impl ZeroFlagConstraint { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for ZeroFlagConstraint { - fn degree(&self) -> usize { - 1 - } - - fn constraint_idx(&self) -> usize { - 15 - } - - fn evaluate( - &self, - frame: &stark_platinum_prover::frame::Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let zero_flag = current_step.get_main_evaluation_element(0, 15); - - transition_evaluations[self.constraint_idx()] = *zero_flag; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct FlagOp1BaseOp0BitConstraint; -impl Default for FlagOp1BaseOp0BitConstraint { - fn default() -> Self { - Self::new() - } -} - -impl FlagOp1BaseOp0BitConstraint { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for FlagOp1BaseOp0BitConstraint { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 54 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let f_op1_imm = current_step.get_main_evaluation_element(0, 2) - - two * current_step.get_main_evaluation_element(0, 3); - let f_op1_fp = current_step.get_main_evaluation_element(0, 3) - - two * current_step.get_main_evaluation_element(0, 4); - let f_op1_ap = current_step.get_main_evaluation_element(0, 4) - - two * current_step.get_main_evaluation_element(0, 5); - - let f_op1_base_op0_bit = one - f_op1_imm - f_op1_fp - f_op1_ap; - - let res = f_op1_base_op0_bit * (f_op1_base_op0_bit - one); - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct FlagResOp1BitConstraint; -impl Default for FlagResOp1BitConstraint { - fn default() -> Self { - Self::new() - } -} - -impl FlagResOp1BitConstraint { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for FlagResOp1BitConstraint { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 55 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let f_res_add = current_step.get_main_evaluation_element(0, 5) - - two * current_step.get_main_evaluation_element(0, 6); - let f_res_mul = current_step.get_main_evaluation_element(0, 6) - - two * current_step.get_main_evaluation_element(0, 7); - let f_pc_jnz = current_step.get_main_evaluation_element(0, 9) - - two * current_step.get_main_evaluation_element(0, 10); - - let f_res_op1_bit = one - f_res_add - f_res_mul - f_pc_jnz; - - let res = f_res_op1_bit * (f_res_op1_bit - one); - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct FlagPcUpdateRegularBit; -impl Default for FlagPcUpdateRegularBit { - fn default() -> Self { - Self::new() - } -} - -impl FlagPcUpdateRegularBit { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for FlagPcUpdateRegularBit { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 56 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let f_jump_abs = current_step.get_main_evaluation_element(0, 7) - - two * current_step.get_main_evaluation_element(0, 8); - let f_jump_rel = current_step.get_main_evaluation_element(0, 8) - - two * current_step.get_main_evaluation_element(0, 9); - let f_pc_jnz = current_step.get_main_evaluation_element(0, 9) - - two * current_step.get_main_evaluation_element(0, 10); - - let flag_pc_update_regular_bit = one - f_jump_abs - f_jump_rel - f_pc_jnz; - - let res = flag_pc_update_regular_bit * (flag_pc_update_regular_bit - one); - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct FlagFpUpdateRegularBit; -impl Default for FlagFpUpdateRegularBit { - fn default() -> Self { - Self::new() - } -} - -impl FlagFpUpdateRegularBit { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for FlagFpUpdateRegularBit { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 57 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let f_opcode_call = current_step.get_main_evaluation_element(0, 12) - - two * current_step.get_main_evaluation_element(0, 13); - let f_opcode_ret = current_step.get_main_evaluation_element(0, 13) - - two * current_step.get_main_evaluation_element(0, 14); - - let flag_fp_update_regular_bit = one - f_opcode_call - f_opcode_ret; - - let res = flag_fp_update_regular_bit * (flag_fp_update_regular_bit - one); - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct InstructionUnpacking; -impl Default for InstructionUnpacking { - fn default() -> Self { - Self::new() - } -} - -impl InstructionUnpacking { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for InstructionUnpacking { - fn degree(&self) -> usize { - 1 - } - - fn constraint_idx(&self) -> usize { - 16 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let two = Felt252::from(2); - let b16 = two.pow(16u32); - let b32 = two.pow(32u32); - let b48 = two.pow(48u32); - - // Named like this to match the Cairo whitepaper's notation. - let f0_squiggle = current_step.get_main_evaluation_element(0, 0); - - let instruction = current_step.get_main_evaluation_element(0, 23); - let off_dst = current_step.get_main_evaluation_element(0, 27); - let off_op0 = current_step.get_main_evaluation_element(0, 28); - let off_op1 = current_step.get_main_evaluation_element(0, 29); - - let res = off_dst + b16 * off_op0 + b32 * off_op1 + b48 * f0_squiggle - instruction; - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct CpuOpcodesCallOff0; -impl Default for CpuOpcodesCallOff0 { - fn default() -> Self { - Self::new() - } -} - -impl CpuOpcodesCallOff0 { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for CpuOpcodesCallOff0 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 58 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - let two = Felt252::from(2); - let b15 = two.pow(15u32); - - let f_opcode_call = current_step.get_main_evaluation_element(0, 12) - - two * current_step.get_main_evaluation_element(0, 13); - - let off_dst = current_step.get_main_evaluation_element(0, 27); - - let res = f_opcode_call * (off_dst - b15); - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct CpuOpcodesCallOff1; -impl Default for CpuOpcodesCallOff1 { - fn default() -> Self { - Self::new() - } -} - -impl CpuOpcodesCallOff1 { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for CpuOpcodesCallOff1 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 59 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let one = Felt252::one(); - let two = Felt252::from(2); - let b15 = two.pow(15u32); - - let f_opcode_call = current_step.get_main_evaluation_element(0, 12) - - two * current_step.get_main_evaluation_element(0, 13); - let off_op0 = current_step.get_main_evaluation_element(0, 28); - - let res = f_opcode_call * (off_op0 - b15 - one); - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct CpuOpcodesCallFlags; -impl Default for CpuOpcodesCallFlags { - fn default() -> Self { - Self::new() - } -} - -impl CpuOpcodesCallFlags { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for CpuOpcodesCallFlags { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 60 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let f_opcode_call = current_step.get_main_evaluation_element(0, 12) - - two * current_step.get_main_evaluation_element(0, 13); - - let bit_flag0 = current_step.get_main_evaluation_element(0, 0) - - two * current_step.get_main_evaluation_element(0, 1); - let bit_flag1 = current_step.get_main_evaluation_element(0, 1) - - two * current_step.get_main_evaluation_element(0, 2); - - let res = - f_opcode_call * (two * f_opcode_call + one + one - bit_flag0 - bit_flag1 - two - two); - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct CpuOpcodesRetOff0; -impl Default for CpuOpcodesRetOff0 { - fn default() -> Self { - Self::new() - } -} - -impl CpuOpcodesRetOff0 { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for CpuOpcodesRetOff0 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 61 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let two = Felt252::from(2); - let b15 = two.pow(15u32); - - let f_opcode_ret = current_step.get_main_evaluation_element(0, 13) - - two * current_step.get_main_evaluation_element(0, 14); - let off_dst = current_step.get_main_evaluation_element(0, 27); - - let res = f_opcode_ret * (off_dst + two - b15); - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct CpuOpcodesRetOff2; -impl Default for CpuOpcodesRetOff2 { - fn default() -> Self { - Self::new() - } -} - -impl CpuOpcodesRetOff2 { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for CpuOpcodesRetOff2 { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 62 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let one = Felt252::one(); - let two = Felt252::from(2); - let b15 = two.pow(15u32); - - let f_opcode_ret = current_step.get_main_evaluation_element(0, 13) - - two * current_step.get_main_evaluation_element(0, 14); - let off_op1 = current_step.get_main_evaluation_element(0, 29); - - let res = f_opcode_ret * (off_op1 + one - b15); - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct CpuOpcodesRetFlags; -impl Default for CpuOpcodesRetFlags { - fn default() -> Self { - Self::new() - } -} - -impl CpuOpcodesRetFlags { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for CpuOpcodesRetFlags { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 63 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let f_opcode_ret = current_step.get_main_evaluation_element(0, 13) - - two * current_step.get_main_evaluation_element(0, 14); - let flag0 = current_step.get_main_evaluation_element(0, 0) - - two * current_step.get_main_evaluation_element(0, 1); - let flag3 = current_step.get_main_evaluation_element(0, 3) - - two * current_step.get_main_evaluation_element(0, 4); - let flag7 = current_step.get_main_evaluation_element(0, 7) - - two * current_step.get_main_evaluation_element(0, 8); - - let f_res_add = current_step.get_main_evaluation_element(0, 5) - - two * current_step.get_main_evaluation_element(0, 6); - let f_res_mul = current_step.get_main_evaluation_element(0, 6) - - two * current_step.get_main_evaluation_element(0, 7); - let f_pc_jnz = current_step.get_main_evaluation_element(0, 9) - - two * current_step.get_main_evaluation_element(0, 10); - - let f_res_op1_bit = one - f_res_add - f_res_mul - f_pc_jnz; - - let res = f_opcode_ret * (flag7 + flag0 + flag3 + f_res_op1_bit - two - two); - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct CpuOperandsMemDstAddr; -impl Default for CpuOperandsMemDstAddr { - fn default() -> Self { - Self::new() - } -} - -impl CpuOperandsMemDstAddr { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for CpuOperandsMemDstAddr { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 17 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let two = Felt252::from(2); - let one = Felt252::one(); - let b15 = two.pow(15u32); - let dst_fp = current_step.get_main_evaluation_element(0, 0) - - two * current_step.get_main_evaluation_element(0, 1); - let ap = current_step.get_main_evaluation_element(0, 17); - let fp = current_step.get_main_evaluation_element(0, 18); - let off_dst = current_step.get_main_evaluation_element(0, 27); - let dst_addr = current_step.get_main_evaluation_element(0, 20); - - let res = dst_fp * fp + (one - dst_fp) * ap + (off_dst - b15) - dst_addr; - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct CpuOperandsMem0Addr; -impl Default for CpuOperandsMem0Addr { - fn default() -> Self { - Self::new() - } -} - -impl CpuOperandsMem0Addr { - pub fn new() -> Self { - Self + fn exemptions_period(&self) -> Option { + Some(16) } -} - -impl TransitionConstraint for CpuOperandsMem0Addr { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 18 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let two = Felt252::from(2); - let one = Felt252::one(); - let b15 = two.pow(15u32); - - let op0_fp = current_step.get_main_evaluation_element(0, 1) - - two * current_step.get_main_evaluation_element(0, 2); - - let ap = current_step.get_main_evaluation_element(0, 17); - let fp = current_step.get_main_evaluation_element(0, 18); - - let off_op0 = current_step.get_main_evaluation_element(0, 28); - let op0_addr = current_step.get_main_evaluation_element(0, 21); - - let res = op0_fp * fp + (one - op0_fp) * ap + (off_op0 - b15) - op0_addr; - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 0 - } -} - -pub struct CpuOperandsMem1Addr; -impl Default for CpuOperandsMem1Addr { - fn default() -> Self { - Self::new() - } -} - -impl CpuOperandsMem1Addr { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for CpuOperandsMem1Addr { - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 19 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - - let one = Felt252::one(); - let two = Felt252::from(2); - let b15 = two.pow(15u32); - - let op1_val = current_step.get_main_evaluation_element(0, 2) - - two * current_step.get_main_evaluation_element(0, 3); - let op1_fp = current_step.get_main_evaluation_element(0, 3) - - two * current_step.get_main_evaluation_element(0, 4); - let op1_ap = current_step.get_main_evaluation_element(0, 4) - - two * current_step.get_main_evaluation_element(0, 5); - - let op0 = current_step.get_main_evaluation_element(0, 25); - let off_op1 = current_step.get_main_evaluation_element(0, 29); - let op1_addr = current_step.get_main_evaluation_element(0, 22); - - let ap = current_step.get_main_evaluation_element(0, 17); - let fp = current_step.get_main_evaluation_element(0, 18); - let pc = current_step.get_main_evaluation_element(0, 19); - - let res = op1_val * pc - + op1_ap * ap - + op1_fp * fp - + (one - op1_val - op1_ap - op1_fp) * op0 - + (off_op1 - b15) - - op1_addr; - transition_evaluations[self.constraint_idx()] = res; + fn periodic_exemptions_offset(&self) -> Option { + Some(15) } fn end_exemptions(&self) -> usize { @@ -1557,255 +63,74 @@ impl TransitionConstraint for CpuOperand } } -// cpu/update_registers/update_ap/ap_update -pub struct CpuUpdateRegistersApUpdate; -impl Default for CpuUpdateRegistersApUpdate { +pub struct ZeroFlagConstraint; +impl Default for ZeroFlagConstraint { fn default() -> Self { Self::new() } } -impl CpuUpdateRegistersApUpdate { +impl ZeroFlagConstraint { pub fn new() -> Self { Self } } -impl TransitionConstraint for CpuUpdateRegistersApUpdate { +impl TransitionConstraint for ZeroFlagConstraint { fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 20 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - let next_step = frame.get_evaluation_step(1); - - let two = Felt252::from(2); - - let ap = current_step.get_main_evaluation_element(0, 17); - let next_ap = next_step.get_main_evaluation_element(0, 17); - let res = current_step.get_main_evaluation_element(0, 16); - - let ap_one = current_step.get_main_evaluation_element(0, 11) - - two * current_step.get_main_evaluation_element(0, 12); - let opc_call = current_step.get_main_evaluation_element(0, 12) - - two * current_step.get_main_evaluation_element(0, 13); - let ap_add = current_step.get_main_evaluation_element(0, 10) - - two * current_step.get_main_evaluation_element(0, 11); - - let res = ap + ap_add * res + ap_one + opc_call * two - next_ap; - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { 1 } -} - -pub struct CpuUpdateRegistersFpUpdate; -impl Default for CpuUpdateRegistersFpUpdate { - fn default() -> Self { - Self::new() - } -} - -impl CpuUpdateRegistersFpUpdate { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint for CpuUpdateRegistersFpUpdate { - fn degree(&self) -> usize { - 2 - } fn constraint_idx(&self) -> usize { - 21 - } - - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - let next_step = frame.get_evaluation_step(1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let ap = current_step.get_main_evaluation_element(0, 17); - let fp = current_step.get_main_evaluation_element(0, 18); - let next_fp = next_step.get_main_evaluation_element(0, 18); - let dst = current_step.get_main_evaluation_element(0, 24); - - let opc_call = current_step.get_main_evaluation_element(0, 12) - - two * current_step.get_main_evaluation_element(0, 13); - let opc_ret = current_step.get_main_evaluation_element(0, 13) - - two * current_step.get_main_evaluation_element(0, 14); - - let res = opc_ret * dst + opc_call * (ap + two) + (one - opc_ret - opc_call) * fp - next_fp; - - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { 1 } -} - -// cpu/update_registers/update_pc/pc_cond_negative: -pub struct CpuUpdateRegistersPcCondNegative; -impl Default for CpuUpdateRegistersPcCondNegative { - fn default() -> Self { - Self::new() - } -} - -impl CpuUpdateRegistersPcCondNegative { - pub fn new() -> Self { - Self - } -} - -impl TransitionConstraint - for CpuUpdateRegistersPcCondNegative -{ - fn degree(&self) -> usize { - 2 - } - - fn constraint_idx(&self) -> usize { - 23 - } fn evaluate( &self, - frame: &Frame, + frame: &stark_platinum_prover::frame::Frame, transition_evaluations: &mut [Felt252], _periodic_values: &[Felt252], _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let next_step = frame.get_evaluation_step(1); - - let one = Felt252::one(); - let two = Felt252::from(2); - - let t0 = current_step.get_main_evaluation_element(0, 30); - let pc = current_step.get_main_evaluation_element(0, 19); - let next_pc = next_step.get_main_evaluation_element(0, 19); - let op1 = current_step.get_main_evaluation_element(0, 26); - - let pc_jnz = current_step.get_main_evaluation_element(0, 9) - - two * current_step.get_main_evaluation_element(0, 10); - let pc_abs = current_step.get_main_evaluation_element(0, 7) - - two * current_step.get_main_evaluation_element(0, 8); - let pc_rel = current_step.get_main_evaluation_element(0, 8) - - two * current_step.get_main_evaluation_element(0, 9); - let res = current_step.get_main_evaluation_element(0, 16); - - let res = t0 * (next_pc - (pc + op1)) + (one - pc_jnz) * next_pc - - ((one - pc_abs - pc_rel - pc_jnz) * (pc + frame_inst_size(current_step)) - + pc_abs * res - + pc_rel * (pc + res)); - transition_evaluations[self.constraint_idx()] = res; - } - - fn end_exemptions(&self) -> usize { - 1 - } -} - -pub struct CpuUpdateRegistersPcCondPositive; -impl Default for CpuUpdateRegistersPcCondPositive { - fn default() -> Self { - Self::new() - } -} - -impl CpuUpdateRegistersPcCondPositive { - pub fn new() -> Self { - Self - } -} -impl TransitionConstraint - for CpuUpdateRegistersPcCondPositive -{ - fn degree(&self) -> usize { - 2 - } + let zero_flag = current_step.get_main_evaluation_element(15, 1); - fn constraint_idx(&self) -> usize { - 22 + transition_evaluations[self.constraint_idx()] = *zero_flag; } - fn evaluate( - &self, - frame: &Frame, - transition_evaluations: &mut [Felt252], - _periodic_values: &[Felt252], - _rap_challenges: &[Felt252], - ) { - let current_step = frame.get_evaluation_step(0); - let next_step = frame.get_evaluation_step(1); - - let two = Felt252::from(2); - - let t1 = current_step.get_main_evaluation_element(0, 31); - let pc_jnz = current_step.get_main_evaluation_element(0, 9) - - two * current_step.get_main_evaluation_element(0, 10); - let pc = current_step.get_main_evaluation_element(0, 19); - let next_pc = next_step.get_main_evaluation_element(0, 19); - - let res = (t1 - pc_jnz) * (next_pc - (pc + frame_inst_size(current_step))); - - transition_evaluations[self.constraint_idx()] = res; + fn period(&self) -> usize { + 16 } - fn end_exemptions(&self) -> usize { - 1 + 0 } } -//cpu/update_registers/update_pc/tmp0 -pub struct CpuUpdateRegistersUpdatePcTmp0; -impl Default for CpuUpdateRegistersUpdatePcTmp0 { +pub struct FlagOp1BaseOp0BitConstraint; +impl Default for FlagOp1BaseOp0BitConstraint { fn default() -> Self { Self::new() } } -impl CpuUpdateRegistersUpdatePcTmp0 { +impl FlagOp1BaseOp0BitConstraint { pub fn new() -> Self { Self } } -impl TransitionConstraint - for CpuUpdateRegistersUpdatePcTmp0 -{ +impl TransitionConstraint for FlagOp1BaseOp0BitConstraint { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 24 + 22 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -1817,13 +142,19 @@ impl TransitionConstraint ) { let current_step = frame.get_evaluation_step(0); + let one = Felt252::one(); let two = Felt252::from(2); - let dst = current_step.get_main_evaluation_element(0, 24); - let t0 = current_step.get_main_evaluation_element(0, 30); - let pc_jnz = current_step.get_main_evaluation_element(0, 9) - - two * current_step.get_main_evaluation_element(0, 10); - let res = pc_jnz * dst - t0; + let f_op1_imm = current_step.get_main_evaluation_element(2, 1) + - two * current_step.get_main_evaluation_element(3, 1); + let f_op1_fp = current_step.get_main_evaluation_element(3, 1) + - two * current_step.get_main_evaluation_element(4, 1); + let f_op1_ap = current_step.get_main_evaluation_element(4, 1) + - two * current_step.get_main_evaluation_element(5, 1); + + let f_op1_base_op0_bit = one - f_op1_imm - f_op1_fp - f_op1_ap; + + let res = f_op1_base_op0_bit * (f_op1_base_op0_bit - one); transition_evaluations[self.constraint_idx()] = res; } @@ -1833,28 +164,30 @@ impl TransitionConstraint } } -pub struct CpuUpdateRegistersUpdatePcTmp1; -impl Default for CpuUpdateRegistersUpdatePcTmp1 { +pub struct FlagResOp1BitConstraint; +impl Default for FlagResOp1BitConstraint { fn default() -> Self { Self::new() } } -impl CpuUpdateRegistersUpdatePcTmp1 { +impl FlagResOp1BitConstraint { pub fn new() -> Self { Self } } -impl TransitionConstraint - for CpuUpdateRegistersUpdatePcTmp1 -{ +impl TransitionConstraint for FlagResOp1BitConstraint { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 25 + 23 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -1866,13 +199,21 @@ impl TransitionConstraint ) { let current_step = frame.get_evaluation_step(0); - let t1 = current_step.get_main_evaluation_element(0, 31); - let t0 = current_step.get_main_evaluation_element(0, 30); - let res = current_step.get_main_evaluation_element(0, 16); + let one = Felt252::one(); + let two = Felt252::from(2); + + let f_res_add = current_step.get_main_evaluation_element(5, 1) + - two * current_step.get_main_evaluation_element(6, 1); + let f_res_mul = current_step.get_main_evaluation_element(6, 1) + - two * current_step.get_main_evaluation_element(7, 1); + let f_pc_jnz = current_step.get_main_evaluation_element(9, 1) + - two * current_step.get_main_evaluation_element(10, 1); - let transition_res = t0 * res - t1; + let f_res_op1_bit = one - f_res_add - f_res_mul - f_pc_jnz; - transition_evaluations[self.constraint_idx()] = transition_res; + let res = f_res_op1_bit * (f_res_op1_bit - one); + + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { @@ -1880,26 +221,30 @@ impl TransitionConstraint } } -pub struct CpuOperandsOpsMul; -impl Default for CpuOperandsOpsMul { +pub struct FlagPcUpdateRegularBit; +impl Default for FlagPcUpdateRegularBit { fn default() -> Self { Self::new() } } -impl CpuOperandsOpsMul { +impl FlagPcUpdateRegularBit { pub fn new() -> Self { Self } } -impl TransitionConstraint for CpuOperandsOpsMul { +impl TransitionConstraint for FlagPcUpdateRegularBit { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 26 + 24 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -1911,11 +256,21 @@ impl TransitionConstraint for CpuOperand ) { let current_step = frame.get_evaluation_step(0); - let mul = current_step.get_main_evaluation_element(0, 32); - let op0 = current_step.get_main_evaluation_element(0, 25); - let op1 = current_step.get_main_evaluation_element(0, 26); + let one = Felt252::one(); + let two = Felt252::from(2); - transition_evaluations[self.constraint_idx()] = mul - op0 * op1; + let f_jump_abs = current_step.get_main_evaluation_element(7, 1) + - two * current_step.get_main_evaluation_element(8, 1); + let f_jump_rel = current_step.get_main_evaluation_element(8, 1) + - two * current_step.get_main_evaluation_element(9, 1); + let f_pc_jnz = current_step.get_main_evaluation_element(9, 1) + - two * current_step.get_main_evaluation_element(10, 1); + + let flag_pc_update_regular_bit = one - f_jump_abs - f_jump_rel - f_pc_jnz; + + let res = flag_pc_update_regular_bit * (flag_pc_update_regular_bit - one); + + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { @@ -1923,27 +278,30 @@ impl TransitionConstraint for CpuOperand } } -// cpu/operands/res -pub struct CpuOperandsRes; -impl Default for CpuOperandsRes { +pub struct FlagFpUpdateRegularBit; +impl Default for FlagFpUpdateRegularBit { fn default() -> Self { Self::new() } } -impl CpuOperandsRes { +impl FlagFpUpdateRegularBit { pub fn new() -> Self { Self } } -impl TransitionConstraint for CpuOperandsRes { +impl TransitionConstraint for FlagFpUpdateRegularBit { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 27 + 25 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -1954,26 +312,20 @@ impl TransitionConstraint for CpuOperand _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); + let one = Felt252::one(); let two = Felt252::from(2); - let mul = current_step.get_main_evaluation_element(0, 32); - let op0 = current_step.get_main_evaluation_element(0, 25); - let op1 = current_step.get_main_evaluation_element(0, 26); - let res = current_step.get_main_evaluation_element(0, 16); + let f_opcode_call = current_step.get_main_evaluation_element(12, 1) + - two * current_step.get_main_evaluation_element(13, 1); + let f_opcode_ret = current_step.get_main_evaluation_element(13, 1) + - two * current_step.get_main_evaluation_element(14, 1); - let res_add = current_step.get_main_evaluation_element(0, 5) - - two * current_step.get_main_evaluation_element(0, 6); - let res_mul = current_step.get_main_evaluation_element(0, 6) - - two * current_step.get_main_evaluation_element(0, 7); - let pc_jnz = current_step.get_main_evaluation_element(0, 9) - - two * current_step.get_main_evaluation_element(0, 10); + let flag_fp_update_regular_bit = one - f_opcode_call - f_opcode_ret; - let transition_res = - res_add * (op0 + op1) + res_mul * mul + (one - res_add - res_mul - pc_jnz) * op1 - - (one - pc_jnz) * res; + let res = flag_fp_update_regular_bit * (flag_fp_update_regular_bit - one); - transition_evaluations[self.constraint_idx()] = transition_res; + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { @@ -1981,27 +333,30 @@ impl TransitionConstraint for CpuOperand } } -// cpu/opcodes/call/push_fp -pub struct CpuOpcodesCallPushFp; -impl Default for CpuOpcodesCallPushFp { +pub struct InstructionUnpacking; +impl Default for InstructionUnpacking { fn default() -> Self { Self::new() } } -impl CpuOpcodesCallPushFp { +impl InstructionUnpacking { pub fn new() -> Self { Self } } -impl TransitionConstraint for CpuOpcodesCallPushFp { +impl TransitionConstraint for InstructionUnpacking { fn degree(&self) -> usize { - 2 + 1 } fn constraint_idx(&self) -> usize { - 28 + 2 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2014,14 +369,21 @@ impl TransitionConstraint for CpuOpcodes let current_step = frame.get_evaluation_step(0); let two = Felt252::from(2); + let b16 = two.pow(16u32); + let b32 = two.pow(32u32); + let b48 = two.pow(48u32); - let opc_call = current_step.get_main_evaluation_element(0, 12) - - two * current_step.get_main_evaluation_element(0, 13); + // Named like this to match the Cairo whitepaper's notation. + let f0_squiggle = current_step.get_main_evaluation_element(0, 1); - let dst = current_step.get_main_evaluation_element(0, 24); - let fp = current_step.get_main_evaluation_element(0, 18); + let instruction = current_step.get_main_evaluation_element(1, 3); + let off_dst = current_step.get_main_evaluation_element(0, 0); + let off_op0 = current_step.get_main_evaluation_element(8, 0); + let off_op1 = current_step.get_main_evaluation_element(4, 0); - transition_evaluations[self.constraint_idx()] = opc_call * (dst - fp); + let res = off_dst + b16 * off_op0 + b32 * off_op1 + b48 * f0_squiggle - instruction; + + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { @@ -2029,26 +391,30 @@ impl TransitionConstraint for CpuOpcodes } } -pub struct CpuOpcodesCallPushPc; -impl Default for CpuOpcodesCallPushPc { +pub struct CpuOpcodesCallOff0; +impl Default for CpuOpcodesCallOff0 { fn default() -> Self { Self::new() } } -impl CpuOpcodesCallPushPc { +impl CpuOpcodesCallOff0 { pub fn new() -> Self { Self } } -impl TransitionConstraint for CpuOpcodesCallPushPc { +impl TransitionConstraint for CpuOpcodesCallOff0 { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 29 + 26 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2059,17 +425,17 @@ impl TransitionConstraint for CpuOpcodes _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let two = Felt252::from(2); + let b15 = two.pow(15u32); - let opc_call = current_step.get_main_evaluation_element(0, 12) - - two * current_step.get_main_evaluation_element(0, 13); + let f_opcode_call = current_step.get_main_evaluation_element(12, 1) + - two * current_step.get_main_evaluation_element(13, 1); - let op0 = current_step.get_main_evaluation_element(0, 25); - let pc = current_step.get_main_evaluation_element(0, 19); + let off_dst = current_step.get_main_evaluation_element(0, 0); - transition_evaluations[self.constraint_idx()] = - opc_call * (op0 - (pc + frame_inst_size(current_step))); + let res = f_opcode_call * (off_dst - b15); + + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { @@ -2077,27 +443,30 @@ impl TransitionConstraint for CpuOpcodes } } -// cpu/opcodes/assert_eq/assert_eq -pub struct CpuOpcodesAssertEq; -impl Default for CpuOpcodesAssertEq { +pub struct CpuOpcodesCallOff1; +impl Default for CpuOpcodesCallOff1 { fn default() -> Self { Self::new() } } -impl CpuOpcodesAssertEq { +impl CpuOpcodesCallOff1 { pub fn new() -> Self { Self } } -impl TransitionConstraint for CpuOpcodesAssertEq { +impl TransitionConstraint for CpuOpcodesCallOff1 { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 30 + 27 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2109,14 +478,18 @@ impl TransitionConstraint for CpuOpcodes ) { let current_step = frame.get_evaluation_step(0); + let one = Felt252::one(); let two = Felt252::from(2); + let b15 = two.pow(15u32); - let opc_aeq = current_step.get_main_evaluation_element(0, 14) - - two * current_step.get_main_evaluation_element(0, 15); - let dst = current_step.get_main_evaluation_element(0, 24); - let res = current_step.get_main_evaluation_element(0, 16); + let f_opcode_call = current_step.get_main_evaluation_element(12, 1) + - two * current_step.get_main_evaluation_element(13, 1); - transition_evaluations[self.constraint_idx()] = opc_aeq * (dst - res) + let off_op0 = current_step.get_main_evaluation_element(8, 0); + + let res = f_opcode_call * (off_op0 - b15 - one); + + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { @@ -2124,27 +497,30 @@ impl TransitionConstraint for CpuOpcodes } } -// memory/diff_is_bit -pub struct MemoryDiffIsBit0; -impl Default for MemoryDiffIsBit0 { +pub struct CpuOpcodesCallFlags; +impl Default for CpuOpcodesCallFlags { fn default() -> Self { Self::new() } } -impl MemoryDiffIsBit0 { +impl CpuOpcodesCallFlags { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryDiffIsBit0 { +impl TransitionConstraint for CpuOpcodesCallFlags { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 31 + 28 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2157,12 +533,20 @@ impl TransitionConstraint for MemoryDiff let current_step = frame.get_evaluation_step(0); let one = Felt252::one(); + let two = Felt252::from(2); - let mem_addr_sorted_0 = current_step.get_aux_evaluation_element(0, 4); - let mem_addr_sorted_1 = current_step.get_aux_evaluation_element(0, 5); + let f_opcode_call = current_step.get_main_evaluation_element(12, 1) + - two * current_step.get_main_evaluation_element(13, 1); - transition_evaluations[self.constraint_idx()] = - (mem_addr_sorted_0 - mem_addr_sorted_1) * (mem_addr_sorted_1 - mem_addr_sorted_0 - one); + let bit_flag0 = current_step.get_main_evaluation_element(0, 1) + - two * current_step.get_main_evaluation_element(1, 1); + let bit_flag1 = current_step.get_main_evaluation_element(1, 1) + - two * current_step.get_main_evaluation_element(2, 1); + + let res = + f_opcode_call * (two * f_opcode_call + one + one - bit_flag0 - bit_flag1 - two - two); + + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { @@ -2170,26 +554,30 @@ impl TransitionConstraint for MemoryDiff } } -pub struct MemoryDiffIsBit1; -impl Default for MemoryDiffIsBit1 { +pub struct CpuOpcodesRetOff0; +impl Default for CpuOpcodesRetOff0 { fn default() -> Self { Self::new() } } -impl MemoryDiffIsBit1 { +impl CpuOpcodesRetOff0 { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryDiffIsBit1 { +impl TransitionConstraint for CpuOpcodesRetOff0 { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 32 + 29 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2201,39 +589,47 @@ impl TransitionConstraint for MemoryDiff ) { let current_step = frame.get_evaluation_step(0); - let one = Felt252::one(); + let two = Felt252::from(2); + let b15 = two.pow(15u32); - let mem_addr_sorted_1 = current_step.get_aux_evaluation_element(0, 5); - let mem_addr_sorted_2 = current_step.get_aux_evaluation_element(0, 6); + let f_opcode_ret = current_step.get_main_evaluation_element(13, 1) + - two * current_step.get_main_evaluation_element(14, 1); + let off_dst = current_step.get_main_evaluation_element(0, 0); - transition_evaluations[self.constraint_idx()] = - (mem_addr_sorted_1 - mem_addr_sorted_2) * (mem_addr_sorted_2 - mem_addr_sorted_1 - one); + let res = f_opcode_ret * (off_dst + two - b15); + + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { 0 } } -pub struct MemoryDiffIsBit2; -impl Default for MemoryDiffIsBit2 { + +pub struct CpuOpcodesRetOff2; +impl Default for CpuOpcodesRetOff2 { fn default() -> Self { Self::new() } } -impl MemoryDiffIsBit2 { +impl CpuOpcodesRetOff2 { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryDiffIsBit2 { +impl TransitionConstraint for CpuOpcodesRetOff2 { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 33 + 30 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2246,38 +642,47 @@ impl TransitionConstraint for MemoryDiff let current_step = frame.get_evaluation_step(0); let one = Felt252::one(); + let two = Felt252::from(2); + let b15 = two.pow(15u32); - let mem_addr_sorted_2 = current_step.get_aux_evaluation_element(0, 6); - let mem_addr_sorted_3 = current_step.get_aux_evaluation_element(0, 7); + let f_opcode_ret = current_step.get_main_evaluation_element(13, 1) + - two * current_step.get_main_evaluation_element(14, 1); + let off_op1 = current_step.get_main_evaluation_element(4, 0); - transition_evaluations[self.constraint_idx()] = - (mem_addr_sorted_2 - mem_addr_sorted_3) * (mem_addr_sorted_3 - mem_addr_sorted_2 - one); + let res = f_opcode_ret * (off_op1 + one - b15); + + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { 0 } } -pub struct MemoryDiffIsBit3; -impl Default for MemoryDiffIsBit3 { + +pub struct CpuOpcodesRetFlags; +impl Default for CpuOpcodesRetFlags { fn default() -> Self { Self::new() } } -impl MemoryDiffIsBit3 { +impl CpuOpcodesRetFlags { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryDiffIsBit3 { +impl TransitionConstraint for CpuOpcodesRetFlags { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 34 + 31 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2290,38 +695,60 @@ impl TransitionConstraint for MemoryDiff let current_step = frame.get_evaluation_step(0); let one = Felt252::one(); + let two = Felt252::from(2); - let mem_addr_sorted_3 = current_step.get_aux_evaluation_element(0, 7); - let mem_addr_sorted_4 = current_step.get_aux_evaluation_element(0, 8); + let f_opcode_ret = current_step.get_main_evaluation_element(13, 1) + - two * current_step.get_main_evaluation_element(14, 1); + let flag0 = current_step.get_main_evaluation_element(0, 1) + - two * current_step.get_main_evaluation_element(1, 1); + let flag3 = current_step.get_main_evaluation_element(3, 1) + - two * current_step.get_main_evaluation_element(4, 1); + let flag7 = current_step.get_main_evaluation_element(7, 1) + - two * current_step.get_main_evaluation_element(8, 1); + + let f_res_add = current_step.get_main_evaluation_element(5, 1) + - two * current_step.get_main_evaluation_element(6, 1); + let f_res_mul = current_step.get_main_evaluation_element(6, 1) + - two * current_step.get_main_evaluation_element(7, 1); + let f_pc_jnz = current_step.get_main_evaluation_element(9, 1) + - two * current_step.get_main_evaluation_element(10, 1); - transition_evaluations[self.constraint_idx()] = - (mem_addr_sorted_3 - mem_addr_sorted_4) * (mem_addr_sorted_4 - mem_addr_sorted_3 - one); + let f_res_op1_bit = one - f_res_add - f_res_mul - f_pc_jnz; + + let res = f_opcode_ret * (flag7 + flag0 + flag3 + f_res_op1_bit - two - two); + + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { 0 } } -pub struct MemoryDiffIsBit4; -impl Default for MemoryDiffIsBit4 { + +pub struct CpuOperandsMemDstAddr; +impl Default for CpuOperandsMemDstAddr { fn default() -> Self { Self::new() } } -impl MemoryDiffIsBit4 { +impl CpuOperandsMemDstAddr { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryDiffIsBit4 { +impl TransitionConstraint for CpuOperandsMemDstAddr { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 35 + 3 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2332,44 +759,52 @@ impl TransitionConstraint for MemoryDiff _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let next_step = frame.get_evaluation_step(1); + let two = Felt252::from(2); let one = Felt252::one(); + let b15 = two.pow(15u32); + + let dst_fp = current_step.get_main_evaluation_element(0, 1) + - two * current_step.get_main_evaluation_element(1, 1); + let ap = current_step.get_main_evaluation_element(0, 5); + let fp = current_step.get_main_evaluation_element(8, 5); + let off_dst = current_step.get_main_evaluation_element(0, 0); + let dst_addr = current_step.get_main_evaluation_element(8, 3); - let next_mem_addr_sorted_0 = next_step.get_aux_evaluation_element(0, 4); - let mem_addr_sorted_4 = current_step.get_aux_evaluation_element(0, 8); + let res = dst_fp * fp + (one - dst_fp) * ap + (off_dst - b15) - dst_addr; - transition_evaluations[self.constraint_idx()] = (mem_addr_sorted_4 - - next_mem_addr_sorted_0) - * (next_mem_addr_sorted_0 - mem_addr_sorted_4 - one); + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { - 1 + 0 } } -// memory/is_func (single-valued) -pub struct MemoryIsFunc0; -impl Default for MemoryIsFunc0 { +pub struct CpuOperandsMem0Addr; +impl Default for CpuOperandsMem0Addr { fn default() -> Self { Self::new() } } -impl MemoryIsFunc0 { +impl CpuOperandsMem0Addr { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryIsFunc0 { +impl TransitionConstraint for CpuOperandsMem0Addr { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 36 + 4 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2381,16 +816,22 @@ impl TransitionConstraint for MemoryIsFu ) { let current_step = frame.get_evaluation_step(0); + let two = Felt252::from(2); let one = Felt252::one(); + let b15 = two.pow(15u32); - let mem_addr_sorted_0 = current_step.get_aux_evaluation_element(0, 4); - let mem_addr_sorted_1 = current_step.get_aux_evaluation_element(0, 5); + let op0_fp = current_step.get_main_evaluation_element(1, 1) + - two * current_step.get_main_evaluation_element(2, 1); - let mem_val_sorted_0 = current_step.get_aux_evaluation_element(0, 9); - let mem_val_sorted_1 = current_step.get_aux_evaluation_element(0, 10); + let ap = current_step.get_main_evaluation_element(0, 5); + let fp = current_step.get_main_evaluation_element(8, 5); - transition_evaluations[self.constraint_idx()] = - (mem_val_sorted_0 - mem_val_sorted_1) * (mem_addr_sorted_1 - mem_addr_sorted_0 - one); + let off_op0 = current_step.get_main_evaluation_element(8, 0); + let op0_addr = current_step.get_main_evaluation_element(4, 3); + + let res = op0_fp * fp + (one - op0_fp) * ap + (off_op0 - b15) - op0_addr; + + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { @@ -2398,26 +839,30 @@ impl TransitionConstraint for MemoryIsFu } } -pub struct MemoryIsFunc1; -impl Default for MemoryIsFunc1 { +pub struct CpuOperandsMem1Addr; +impl Default for CpuOperandsMem1Addr { fn default() -> Self { Self::new() } } -impl MemoryIsFunc1 { +impl CpuOperandsMem1Addr { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryIsFunc1 { +impl TransitionConstraint for CpuOperandsMem1Addr { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 37 + 5 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2430,15 +875,32 @@ impl TransitionConstraint for MemoryIsFu let current_step = frame.get_evaluation_step(0); let one = Felt252::one(); + let two = Felt252::from(2); + let b15 = two.pow(15u32); + + let op1_val = current_step.get_main_evaluation_element(2, 1) + - two * current_step.get_main_evaluation_element(3, 1); + let op1_fp = current_step.get_main_evaluation_element(3, 1) + - two * current_step.get_main_evaluation_element(4, 1); + let op1_ap = current_step.get_main_evaluation_element(4, 1) + - two * current_step.get_main_evaluation_element(5, 1); + + let op0 = current_step.get_main_evaluation_element(5, 3); + let off_op1 = current_step.get_main_evaluation_element(4, 0); + let op1_addr = current_step.get_main_evaluation_element(12, 3); - let mem_addr_sorted_1 = current_step.get_aux_evaluation_element(0, 5); - let mem_addr_sorted_2 = current_step.get_aux_evaluation_element(0, 6); + let ap = current_step.get_main_evaluation_element(0, 5); + let fp = current_step.get_main_evaluation_element(8, 5); + let pc = current_step.get_main_evaluation_element(0, 3); - let mem_val_sorted_1 = current_step.get_aux_evaluation_element(0, 10); - let mem_val_sorted_2 = current_step.get_aux_evaluation_element(0, 11); + let res = op1_val * pc + + op1_ap * ap + + op1_fp * fp + + (one - op1_val - op1_ap - op1_fp) * op0 + + (off_op1 - b15) + - op1_addr; - transition_evaluations[self.constraint_idx()] = - (mem_val_sorted_1 - mem_val_sorted_2) * (mem_addr_sorted_2 - mem_addr_sorted_1 - one); + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { @@ -2446,26 +908,31 @@ impl TransitionConstraint for MemoryIsFu } } -pub struct MemoryIsFunc2; -impl Default for MemoryIsFunc2 { +// cpu/update_registers/update_ap/ap_update +pub struct CpuUpdateRegistersApUpdate; +impl Default for CpuUpdateRegistersApUpdate { fn default() -> Self { Self::new() } } -impl MemoryIsFunc2 { +impl CpuUpdateRegistersApUpdate { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryIsFunc2 { +impl TransitionConstraint for CpuUpdateRegistersApUpdate { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 38 + 6 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2476,44 +943,55 @@ impl TransitionConstraint for MemoryIsFu _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); + let next_step = frame.get_evaluation_step(1); - let one = Felt252::one(); + let two = Felt252::from(2); - let mem_addr_sorted_2 = current_step.get_aux_evaluation_element(0, 6); - let mem_addr_sorted_3 = current_step.get_aux_evaluation_element(0, 7); + let ap = current_step.get_main_evaluation_element(0, 5); + let next_ap = next_step.get_main_evaluation_element(0, 5); + let res = current_step.get_main_evaluation_element(12, 5); - let mem_val_sorted_2 = current_step.get_aux_evaluation_element(0, 11); - let mem_val_sorted_3 = current_step.get_aux_evaluation_element(0, 12); + let ap_one = current_step.get_main_evaluation_element(11, 1) + - two * current_step.get_main_evaluation_element(12, 1); + let opc_call = current_step.get_main_evaluation_element(12, 1) + - two * current_step.get_main_evaluation_element(13, 1); + let ap_add = current_step.get_main_evaluation_element(10, 1) + - two * current_step.get_main_evaluation_element(11, 1); - transition_evaluations[self.constraint_idx()] = - (mem_val_sorted_2 - mem_val_sorted_3) * (mem_addr_sorted_3 - mem_addr_sorted_2 - one); + let res = ap + ap_add * res + ap_one + opc_call * two - next_ap; + + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { - 0 + 1 } } -pub struct MemoryIsFunc3; -impl Default for MemoryIsFunc3 { +pub struct CpuUpdateRegistersFpUpdate; +impl Default for CpuUpdateRegistersFpUpdate { fn default() -> Self { Self::new() } } -impl MemoryIsFunc3 { +impl CpuUpdateRegistersFpUpdate { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryIsFunc3 { +impl TransitionConstraint for CpuUpdateRegistersFpUpdate { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 39 + 7 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2524,43 +1002,58 @@ impl TransitionConstraint for MemoryIsFu _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); + let next_step = frame.get_evaluation_step(1); let one = Felt252::one(); + let two = Felt252::from(2); - let mem_addr_sorted_3 = current_step.get_aux_evaluation_element(0, 7); - let mem_addr_sorted_4 = current_step.get_aux_evaluation_element(0, 8); + let ap = current_step.get_main_evaluation_element(0, 5); + let fp = current_step.get_main_evaluation_element(8, 5); + let next_fp = next_step.get_main_evaluation_element(8, 5); + let dst = current_step.get_main_evaluation_element(9, 3); - let mem_val_sorted_3 = current_step.get_aux_evaluation_element(0, 12); - let mem_val_sorted_4 = current_step.get_aux_evaluation_element(0, 13); + let opc_call = current_step.get_main_evaluation_element(12, 1) + - two * current_step.get_main_evaluation_element(13, 1); + let opc_ret = current_step.get_main_evaluation_element(13, 1) + - two * current_step.get_main_evaluation_element(14, 1); - transition_evaluations[self.constraint_idx()] = - (mem_val_sorted_3 - mem_val_sorted_4) * (mem_addr_sorted_4 - mem_addr_sorted_3 - one); + let res = opc_ret * dst + opc_call * (ap + two) + (one - opc_ret - opc_call) * fp - next_fp; + + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { - 0 + 1 } } -pub struct MemoryIsFunc4; -impl Default for MemoryIsFunc4 { + +// cpu/update_registers/update_pc/pc_cond_negative: +pub struct CpuUpdateRegistersPcCondNegative; +impl Default for CpuUpdateRegistersPcCondNegative { fn default() -> Self { Self::new() } } -impl MemoryIsFunc4 { +impl CpuUpdateRegistersPcCondNegative { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryIsFunc4 { +impl TransitionConstraint + for CpuUpdateRegistersPcCondNegative +{ fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 40 + 9 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2574,15 +1067,26 @@ impl TransitionConstraint for MemoryIsFu let next_step = frame.get_evaluation_step(1); let one = Felt252::one(); + let two = Felt252::from(2); - let next_mem_addr_sorted_0 = next_step.get_aux_evaluation_element(0, 4); - let mem_addr_sorted_4 = current_step.get_aux_evaluation_element(0, 8); + let t0 = current_step.get_main_evaluation_element(2, 5); + let pc = current_step.get_main_evaluation_element(0, 3); + let next_pc = next_step.get_main_evaluation_element(0, 3); + let op1 = current_step.get_main_evaluation_element(13, 3); - let next_mem_val_sorted_0 = next_step.get_aux_evaluation_element(0, 9); - let mem_val_sorted_4 = current_step.get_aux_evaluation_element(0, 13); + let pc_jnz = current_step.get_main_evaluation_element(9, 1) + - two * current_step.get_main_evaluation_element(10, 1); + let pc_abs = current_step.get_main_evaluation_element(7, 1) + - two * current_step.get_main_evaluation_element(8, 1); + let pc_rel = current_step.get_main_evaluation_element(8, 1) + - two * current_step.get_main_evaluation_element(9, 1); + let res = current_step.get_main_evaluation_element(12, 5); - transition_evaluations[self.constraint_idx()] = (mem_val_sorted_4 - next_mem_val_sorted_0) - * (next_mem_addr_sorted_0 - mem_addr_sorted_4 - one); + let res = t0 * (next_pc - (pc + op1)) + (one - pc_jnz) * next_pc + - ((one - pc_abs - pc_rel - pc_jnz) * (pc + frame_inst_size(current_step)) + + pc_abs * res + + pc_rel * (pc + res)); + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { @@ -2590,27 +1094,32 @@ impl TransitionConstraint for MemoryIsFu } } -// memory/multi_column_perm/perm/step0 -pub struct MemoryMultiColumnPermStep0_0; -impl Default for MemoryMultiColumnPermStep0_0 { +pub struct CpuUpdateRegistersPcCondPositive; +impl Default for CpuUpdateRegistersPcCondPositive { fn default() -> Self { Self::new() } } -impl MemoryMultiColumnPermStep0_0 { +impl CpuUpdateRegistersPcCondPositive { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryMultiColumnPermStep0_0 { +impl TransitionConstraint + for CpuUpdateRegistersPcCondPositive +{ fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 41 + 8 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2618,50 +1127,56 @@ impl TransitionConstraint for MemoryMult frame: &Frame, transition_evaluations: &mut [Felt252], _periodic_values: &[Felt252], - rap_challenges: &[Felt252], + _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); + let next_step = frame.get_evaluation_step(1); - let alpha = rap_challenges[0]; - let z = rap_challenges[1]; + let two = Felt252::from(2); - let a1 = current_step.get_main_evaluation_element(0, 20); - let v1 = current_step.get_main_evaluation_element(0, 24); + let t1 = current_step.get_main_evaluation_element(10, 5); + let pc_jnz = current_step.get_main_evaluation_element(9, 1) + - two * current_step.get_main_evaluation_element(10, 1); + let pc = current_step.get_main_evaluation_element(0, 3); + let next_pc = next_step.get_main_evaluation_element(0, 3); - let p0 = current_step.get_aux_evaluation_element(0, 14); - let ap1 = current_step.get_aux_evaluation_element(0, 5); - let vp1 = current_step.get_aux_evaluation_element(0, 10); - let p1 = current_step.get_aux_evaluation_element(0, 15); + let res = (t1 - pc_jnz) * (next_pc - (pc + frame_inst_size(current_step))); - transition_evaluations[self.constraint_idx()] = - (z - (ap1 + alpha * vp1)) * p1 - (z - (a1 + alpha * v1)) * p0; + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { - 0 + 1 } } -pub struct MemoryMultiColumnPermStep0_1; -impl Default for MemoryMultiColumnPermStep0_1 { +//cpu/update_registers/update_pc/tmp0 +pub struct CpuUpdateRegistersUpdatePcTmp0; +impl Default for CpuUpdateRegistersUpdatePcTmp0 { fn default() -> Self { Self::new() } } -impl MemoryMultiColumnPermStep0_1 { +impl CpuUpdateRegistersUpdatePcTmp0 { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryMultiColumnPermStep0_1 { +impl TransitionConstraint + for CpuUpdateRegistersUpdatePcTmp0 +{ fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 42 + 10 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2669,23 +1184,19 @@ impl TransitionConstraint for MemoryMult frame: &Frame, transition_evaluations: &mut [Felt252], _periodic_values: &[Felt252], - rap_challenges: &[Felt252], + _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let alpha = rap_challenges[0]; - let z = rap_challenges[1]; - - let a2 = current_step.get_main_evaluation_element(0, 21); - let v2 = current_step.get_main_evaluation_element(0, 25); + let two = Felt252::from(2); + let dst = current_step.get_main_evaluation_element(9, 3); + let t0 = current_step.get_main_evaluation_element(2, 5); + let pc_jnz = current_step.get_main_evaluation_element(9, 1) + - two * current_step.get_main_evaluation_element(10, 1); - let p1 = current_step.get_aux_evaluation_element(0, 15); - let ap2 = current_step.get_aux_evaluation_element(0, 6); - let vp2 = current_step.get_aux_evaluation_element(0, 11); - let p2 = current_step.get_aux_evaluation_element(0, 16); + let res = pc_jnz * dst - t0; - transition_evaluations[self.constraint_idx()] = - (z - (ap2 + alpha * vp2)) * p2 - (z - (a2 + alpha * v2)) * p1; + transition_evaluations[self.constraint_idx()] = res; } fn end_exemptions(&self) -> usize { @@ -2693,26 +1204,32 @@ impl TransitionConstraint for MemoryMult } } -pub struct MemoryMultiColumnPermStep0_2; -impl Default for MemoryMultiColumnPermStep0_2 { +pub struct CpuUpdateRegistersUpdatePcTmp1; +impl Default for CpuUpdateRegistersUpdatePcTmp1 { fn default() -> Self { Self::new() } } -impl MemoryMultiColumnPermStep0_2 { +impl CpuUpdateRegistersUpdatePcTmp1 { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryMultiColumnPermStep0_2 { +impl TransitionConstraint + for CpuUpdateRegistersUpdatePcTmp1 +{ fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 43 + 11 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2720,22 +1237,17 @@ impl TransitionConstraint for MemoryMult frame: &Frame, transition_evaluations: &mut [Felt252], _periodic_values: &[Felt252], - rap_challenges: &[Felt252], + _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let alpha = rap_challenges[0]; - let z = rap_challenges[1]; - let a3 = current_step.get_main_evaluation_element(0, 22); - let v3 = current_step.get_main_evaluation_element(0, 26); + let t1 = current_step.get_main_evaluation_element(10, 5); + let t0 = current_step.get_main_evaluation_element(2, 5); + let res = current_step.get_main_evaluation_element(12, 5); - let p2 = current_step.get_aux_evaluation_element(0, 16); - let ap3 = current_step.get_aux_evaluation_element(0, 7); - let vp3 = current_step.get_aux_evaluation_element(0, 12); - let p3 = current_step.get_aux_evaluation_element(0, 17); + let transition_res = t0 * res - t1; - transition_evaluations[self.constraint_idx()] = - (z - (ap3 + alpha * vp3)) * p3 - (z - (a3 + alpha * v3)) * p2; + transition_evaluations[self.constraint_idx()] = transition_res; } fn end_exemptions(&self) -> usize { @@ -2743,26 +1255,30 @@ impl TransitionConstraint for MemoryMult } } -pub struct MemoryMultiColumnPermStep0_3; -impl Default for MemoryMultiColumnPermStep0_3 { +pub struct CpuOperandsOpsMul; +impl Default for CpuOperandsOpsMul { fn default() -> Self { Self::new() } } -impl MemoryMultiColumnPermStep0_3 { +impl CpuOperandsOpsMul { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryMultiColumnPermStep0_3 { +impl TransitionConstraint for CpuOperandsOpsMul { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 44 + 12 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2770,22 +1286,15 @@ impl TransitionConstraint for MemoryMult frame: &Frame, transition_evaluations: &mut [Felt252], _periodic_values: &[Felt252], - rap_challenges: &[Felt252], + _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let alpha = rap_challenges[0]; - let z = rap_challenges[1]; - let a4 = current_step.get_main_evaluation_element(0, 33); - let v4 = current_step.get_main_evaluation_element(0, 34); - - let p3 = current_step.get_aux_evaluation_element(0, 17); - let p4 = current_step.get_aux_evaluation_element(0, 18); - let ap4 = current_step.get_aux_evaluation_element(0, 8); - let vp4 = current_step.get_aux_evaluation_element(0, 13); + let mul = current_step.get_main_evaluation_element(4, 5); + let op0 = current_step.get_main_evaluation_element(5, 3); + let op1 = current_step.get_main_evaluation_element(13, 3); - transition_evaluations[self.constraint_idx()] = - (z - (ap4 + alpha * vp4)) * p4 - (z - (a4 + alpha * v4)) * p3; + transition_evaluations[self.constraint_idx()] = mul - op0 * op1; } fn end_exemptions(&self) -> usize { @@ -2793,26 +1302,31 @@ impl TransitionConstraint for MemoryMult } } -pub struct MemoryMultiColumnPermStep0_4; -impl Default for MemoryMultiColumnPermStep0_4 { +// cpu/operands/res +pub struct CpuOperandsRes; +impl Default for CpuOperandsRes { fn default() -> Self { Self::new() } } -impl MemoryMultiColumnPermStep0_4 { +impl CpuOperandsRes { pub fn new() -> Self { Self } } -impl TransitionConstraint for MemoryMultiColumnPermStep0_4 { +impl TransitionConstraint for CpuOperandsRes { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 45 + 13 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2820,51 +1334,61 @@ impl TransitionConstraint for MemoryMult frame: &Frame, transition_evaluations: &mut [Felt252], _periodic_values: &[Felt252], - rap_challenges: &[Felt252], + _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let next_step = frame.get_evaluation_step(1); + let one = Felt252::one(); + let two = Felt252::from(2); - let alpha = rap_challenges[0]; - let z = rap_challenges[1]; - let next_a0 = next_step.get_main_evaluation_element(0, 19); - let next_v0 = next_step.get_main_evaluation_element(0, 23); + let mul = current_step.get_main_evaluation_element(4, 5); + let op0 = current_step.get_main_evaluation_element(5, 3); + let op1 = current_step.get_main_evaluation_element(13, 3); + let res = current_step.get_main_evaluation_element(12, 5); - let next_ap0 = next_step.get_aux_evaluation_element(0, 4); - let next_vp0 = next_step.get_aux_evaluation_element(0, 9); - let next_p0 = next_step.get_aux_evaluation_element(0, 14); - let p4 = current_step.get_aux_evaluation_element(0, 18); + let res_add = current_step.get_main_evaluation_element(5, 1) + - two * current_step.get_main_evaluation_element(6, 1); + let res_mul = current_step.get_main_evaluation_element(6, 1) + - two * current_step.get_main_evaluation_element(7, 1); + let pc_jnz = current_step.get_main_evaluation_element(9, 1) + - two * current_step.get_main_evaluation_element(10, 1); - transition_evaluations[self.constraint_idx()] = - (z - (next_ap0 + alpha * next_vp0)) * next_p0 - (z - (next_a0 + alpha * next_v0)) * p4; + let transition_res = + res_add * (op0 + op1) + res_mul * mul + (one - res_add - res_mul - pc_jnz) * op1 + - (one - pc_jnz) * res; + + transition_evaluations[self.constraint_idx()] = transition_res; } fn end_exemptions(&self) -> usize { - 1 + 0 } } -// rc16/diff_is_bit -pub struct Rc16DiffIsBit0; -impl Default for Rc16DiffIsBit0 { +// cpu/opcodes/call/push_fp +pub struct CpuOpcodesCallPushFp; +impl Default for CpuOpcodesCallPushFp { fn default() -> Self { Self::new() } } -impl Rc16DiffIsBit0 { +impl CpuOpcodesCallPushFp { pub fn new() -> Self { Self } } -impl TransitionConstraint for Rc16DiffIsBit0 { +impl TransitionConstraint for CpuOpcodesCallPushFp { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 46 + 14 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2875,13 +1399,16 @@ impl TransitionConstraint for Rc16DiffIs _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let one = Felt252::one(); - let rc_col_1 = current_step.get_aux_evaluation_element(0, 0); - let rc_col_2 = current_step.get_aux_evaluation_element(0, 1); + let two = Felt252::from(2); - transition_evaluations[self.constraint_idx()] = - (rc_col_1 - rc_col_2) * (rc_col_2 - rc_col_1 - one); + let opc_call = current_step.get_main_evaluation_element(12, 1) + - two * current_step.get_main_evaluation_element(13, 1); + + let dst = current_step.get_main_evaluation_element(9, 3); + let fp = current_step.get_main_evaluation_element(8, 5); + + transition_evaluations[self.constraint_idx()] = opc_call * (dst - fp); } fn end_exemptions(&self) -> usize { @@ -2889,26 +1416,30 @@ impl TransitionConstraint for Rc16DiffIs } } -pub struct Rc16DiffIsBit1; -impl Default for Rc16DiffIsBit1 { +pub struct CpuOpcodesCallPushPc; +impl Default for CpuOpcodesCallPushPc { fn default() -> Self { Self::new() } } -impl Rc16DiffIsBit1 { +impl CpuOpcodesCallPushPc { pub fn new() -> Self { Self } } -impl TransitionConstraint for Rc16DiffIsBit1 { +impl TransitionConstraint for CpuOpcodesCallPushPc { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 47 + 15 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2919,13 +1450,17 @@ impl TransitionConstraint for Rc16DiffIs _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let one = Felt252::one(); - let rc_col_2 = current_step.get_aux_evaluation_element(0, 1); - let rc_col_3 = current_step.get_aux_evaluation_element(0, 2); + let two = Felt252::from(2); + + let opc_call = current_step.get_main_evaluation_element(12, 1) + - two * current_step.get_main_evaluation_element(13, 1); + + let op0 = current_step.get_main_evaluation_element(5, 3); + let pc = current_step.get_main_evaluation_element(0, 3); transition_evaluations[self.constraint_idx()] = - (rc_col_2 - rc_col_3) * (rc_col_3 - rc_col_2 - one); + opc_call * (op0 - (pc + frame_inst_size(current_step))); } fn end_exemptions(&self) -> usize { @@ -2933,26 +1468,31 @@ impl TransitionConstraint for Rc16DiffIs } } -pub struct Rc16DiffIsBit2; -impl Default for Rc16DiffIsBit2 { +// cpu/opcodes/assert_eq/assert_eq +pub struct CpuOpcodesAssertEq; +impl Default for CpuOpcodesAssertEq { fn default() -> Self { Self::new() } } -impl Rc16DiffIsBit2 { +impl CpuOpcodesAssertEq { pub fn new() -> Self { Self } } -impl TransitionConstraint for Rc16DiffIsBit2 { +impl TransitionConstraint for CpuOpcodesAssertEq { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 48 + 16 + } + + fn period(&self) -> usize { + 16 } fn evaluate( @@ -2963,13 +1503,15 @@ impl TransitionConstraint for Rc16DiffIs _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let one = Felt252::one(); - let rc_col_3 = current_step.get_aux_evaluation_element(0, 2); - let rc_col_4 = current_step.get_aux_evaluation_element(0, 3); + let two = Felt252::from(2); + + let opc_aeq = current_step.get_main_evaluation_element(14, 1) + - two * current_step.get_main_evaluation_element(15, 1); + let dst = current_step.get_main_evaluation_element(9, 3); + let res = current_step.get_main_evaluation_element(12, 5); - transition_evaluations[self.constraint_idx()] = - (rc_col_3 - rc_col_4) * (rc_col_4 - rc_col_3 - one); + transition_evaluations[self.constraint_idx()] = opc_aeq * (dst - res) } fn end_exemptions(&self) -> usize { @@ -2977,26 +1519,31 @@ impl TransitionConstraint for Rc16DiffIs } } -pub struct Rc16DiffIsBit3; -impl Default for Rc16DiffIsBit3 { +// memory/diff_is_bit +pub struct MemoryDiffIsBit; +impl Default for MemoryDiffIsBit { fn default() -> Self { Self::new() } } -impl Rc16DiffIsBit3 { +impl MemoryDiffIsBit { pub fn new() -> Self { Self } } -impl TransitionConstraint for Rc16DiffIsBit3 { +impl TransitionConstraint for MemoryDiffIsBit { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 49 + 17 + } + + fn period(&self) -> usize { + 2 } fn evaluate( @@ -3007,14 +1554,14 @@ impl TransitionConstraint for Rc16DiffIs _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let next_step = frame.get_evaluation_step(1); + let one = Felt252::one(); - let rc_col_4 = current_step.get_aux_evaluation_element(0, 3); - let next_rc_col_1 = next_step.get_aux_evaluation_element(0, 0); + let mem_addr_sorted = current_step.get_main_evaluation_element(0, 4); + let mem_addr_sorted_next = current_step.get_main_evaluation_element(2, 4); - transition_evaluations[self.constraint_idx()] = - (rc_col_4 - next_rc_col_1) * (next_rc_col_1 - rc_col_4 - one); + transition_evaluations[self.constraint_idx()] = (mem_addr_sorted - mem_addr_sorted_next) + * (mem_addr_sorted_next - mem_addr_sorted - one); } fn end_exemptions(&self) -> usize { @@ -3022,27 +1569,31 @@ impl TransitionConstraint for Rc16DiffIs } } -// rc16/perm/step0 -pub struct Rc16PermStep0_0; -impl Default for Rc16PermStep0_0 { +// memory/is_func (single-valued) +pub struct MemoryIsFunc; +impl Default for MemoryIsFunc { fn default() -> Self { Self::new() } } -impl Rc16PermStep0_0 { +impl MemoryIsFunc { pub fn new() -> Self { Self } } -impl TransitionConstraint for Rc16PermStep0_0 { +impl TransitionConstraint for MemoryIsFunc { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 50 + 18 + } + + fn period(&self) -> usize { + 2 } fn evaluate( @@ -3050,45 +1601,52 @@ impl TransitionConstraint for Rc16PermSt frame: &Frame, transition_evaluations: &mut [Felt252], _periodic_values: &[Felt252], - rap_challenges: &[Felt252], + _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let z = rap_challenges[2]; - let a1 = current_step.get_main_evaluation_element(0, 28); + let one = Felt252::one(); - let ap1 = current_step.get_aux_evaluation_element(0, 1); - let p1 = current_step.get_aux_evaluation_element(0, 20); - let p0 = current_step.get_aux_evaluation_element(0, 19); + let mem_addr_sorted = current_step.get_main_evaluation_element(0, 4); + let mem_addr_sorted_next = current_step.get_main_evaluation_element(2, 4); - transition_evaluations[self.constraint_idx()] = (z - ap1) * p1 - (z - a1) * p0; + let mem_val_sorted = current_step.get_main_evaluation_element(1, 4); + let mem_val_sorted_next = current_step.get_main_evaluation_element(3, 4); + + transition_evaluations[self.constraint_idx()] = + (mem_val_sorted - mem_val_sorted_next) * (mem_addr_sorted_next - mem_addr_sorted - one); } fn end_exemptions(&self) -> usize { - 0 + 1 } } -pub struct Rc16PermStep0_1; -impl Default for Rc16PermStep0_1 { +// memory/multi_column_perm/perm/step0 +pub struct MemoryMultiColumnPermStep0; +impl Default for MemoryMultiColumnPermStep0 { fn default() -> Self { Self::new() } } -impl Rc16PermStep0_1 { +impl MemoryMultiColumnPermStep0 { pub fn new() -> Self { Self } } -impl TransitionConstraint for Rc16PermStep0_1 { +impl TransitionConstraint for MemoryMultiColumnPermStep0 { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 51 + 19 + } + + fn period(&self) -> usize { + 2 } fn evaluate( @@ -3100,42 +1658,47 @@ impl TransitionConstraint for Rc16PermSt ) { let current_step = frame.get_evaluation_step(0); - let z = rap_challenges[2]; + let alpha = rap_challenges[0]; + let z = rap_challenges[1]; - let a2 = current_step.get_main_evaluation_element(0, 29); + let a1 = current_step.get_main_evaluation_element(2, 3); + let v1 = current_step.get_main_evaluation_element(3, 3); - let ap2 = current_step.get_aux_evaluation_element(0, 2); - let p2 = current_step.get_aux_evaluation_element(0, 21); - let p1 = current_step.get_aux_evaluation_element(0, 20); + let ap1 = current_step.get_main_evaluation_element(2, 4); + let vp1 = current_step.get_main_evaluation_element(3, 4); + let p0 = current_step.get_aux_evaluation_element(0, 1); + let p1 = current_step.get_aux_evaluation_element(2, 1); - transition_evaluations[self.constraint_idx()] = (z - ap2) * p2 - (z - a2) * p1; + transition_evaluations[self.constraint_idx()] = + (z - (ap1 + alpha * vp1)) * p1 - (z - (a1 + alpha * v1)) * p0; } fn end_exemptions(&self) -> usize { - 0 + 1 } } -pub struct Rc16PermStep0_2; -impl Default for Rc16PermStep0_2 { +// rc16/diff_is_bit +pub struct Rc16DiffIsBit; +impl Default for Rc16DiffIsBit { fn default() -> Self { Self::new() } } -impl Rc16PermStep0_2 { +impl Rc16DiffIsBit { pub fn new() -> Self { Self } } -impl TransitionConstraint for Rc16PermStep0_2 { +impl TransitionConstraint for Rc16DiffIsBit { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 52 + 20 } fn evaluate( @@ -3143,45 +1706,44 @@ impl TransitionConstraint for Rc16PermSt frame: &Frame, transition_evaluations: &mut [Felt252], _periodic_values: &[Felt252], - rap_challenges: &[Felt252], + _rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); + let one = Felt252::one(); - let z = rap_challenges[2]; - let a3 = current_step.get_main_evaluation_element(0, 35); - - let ap3 = current_step.get_aux_evaluation_element(0, 3); - let p3 = current_step.get_aux_evaluation_element(0, 22); - let p2 = current_step.get_aux_evaluation_element(0, 21); + let rc_col_1 = current_step.get_main_evaluation_element(0, 2); + let rc_col_2 = current_step.get_main_evaluation_element(1, 2); - transition_evaluations[self.constraint_idx()] = (z - ap3) * p3 - (z - a3) * p2; + transition_evaluations[self.constraint_idx()] = + (rc_col_1 - rc_col_2) * (rc_col_2 - rc_col_1 - one); } fn end_exemptions(&self) -> usize { - 0 + 1 } } -pub struct Rc16PermStep0_3; -impl Default for Rc16PermStep0_3 { +// rc16/perm/step0 +pub struct Rc16PermStep0; +impl Default for Rc16PermStep0 { fn default() -> Self { Self::new() } } -impl Rc16PermStep0_3 { +impl Rc16PermStep0 { pub fn new() -> Self { Self } } -impl TransitionConstraint for Rc16PermStep0_3 { +impl TransitionConstraint for Rc16PermStep0 { fn degree(&self) -> usize { 2 } fn constraint_idx(&self) -> usize { - 53 + 21 } fn evaluate( @@ -3192,19 +1754,15 @@ impl TransitionConstraint for Rc16PermSt rap_challenges: &[Felt252], ) { let current_step = frame.get_evaluation_step(0); - let next_step = frame.get_evaluation_step(1); let z = rap_challenges[2]; + let a1 = current_step.get_main_evaluation_element(1, 0); + let ap1 = current_step.get_main_evaluation_element(1, 2); - let p3 = current_step.get_aux_evaluation_element(0, 22); + let p0 = current_step.get_aux_evaluation_element(0, 0); + let p1 = current_step.get_aux_evaluation_element(1, 0); - let next_a0 = next_step.get_main_evaluation_element(0, 27); - let next_ap0 = next_step.get_aux_evaluation_element(0, 0); - - let next_p0 = next_step.get_aux_evaluation_element(0, 19); - - transition_evaluations[self.constraint_idx()] = - (z - next_ap0) * next_p0 - (z - next_a0) * p3; + transition_evaluations[self.constraint_idx()] = (z - ap1) * p1 - (z - a1) * p0; } fn end_exemptions(&self) -> usize { @@ -3213,7 +1771,7 @@ impl TransitionConstraint for Rc16PermSt } fn frame_inst_size(step: &TableView) -> Felt252 { - let op1_val = step.get_main_evaluation_element(0, 2) - - Felt252::from(2) * step.get_main_evaluation_element(0, 3); + let op1_val = step.get_main_evaluation_element(2, 1) + - Felt252::from(2) * step.get_main_evaluation_element(3, 1); op1_val + Felt252::one() } diff --git a/provers/cairo/src/wasm_wrappers.rs b/provers/cairo/src/wasm_wrappers.rs index 43fd398ae..949612eef 100644 --- a/provers/cairo/src/wasm_wrappers.rs +++ b/provers/cairo/src/wasm_wrappers.rs @@ -1,4 +1,4 @@ -use super::air::CairoAIR; +use super::layouts::plain::air::CairoAIR; use lambdaworks_math::field::element::FieldElement; use lambdaworks_math::field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField; use serde::{Deserialize, Serialize}; diff --git a/provers/fibonacci.mem b/provers/fibonacci.mem new file mode 100644 index 000000000..415476292 Binary files /dev/null and b/provers/fibonacci.mem differ diff --git a/provers/fibonacci.trace b/provers/fibonacci.trace new file mode 100644 index 000000000..ea329514d Binary files /dev/null and b/provers/fibonacci.trace differ diff --git a/provers/stark/src/constraints/evaluator.rs b/provers/stark/src/constraints/evaluator.rs index 140a104ab..2c7d50b35 100644 --- a/provers/stark/src/constraints/evaluator.rs +++ b/provers/stark/src/constraints/evaluator.rs @@ -6,7 +6,7 @@ use crate::trace::LDETraceTable; use crate::traits::AIR; use crate::{frame::Frame, prover::evaluate_polynomial_on_lde_domain}; use itertools::Itertools; -#[cfg(all(debug_assertions, not(feature = "parallel")))] +#[cfg(not(feature = "parallel"))] use lambdaworks_math::polynomial::Polynomial; use lambdaworks_math::{fft::errors::FFTError, field::element::FieldElement, traits::AsBytes}; #[cfg(feature = "parallel")] @@ -14,6 +14,7 @@ use rayon::{ iter::IndexedParallelIterator, prelude::{IntoParallelIterator, ParallelIterator}, }; + #[cfg(feature = "instruments")] use std::time::Instant; @@ -45,6 +46,7 @@ impl ConstraintEvaluator { { let boundary_constraints = &self.boundary_constraints; let number_of_b_constraints = boundary_constraints.constraints.len(); + let boundary_zerofiers_inverse_evaluations: Vec>> = boundary_constraints .constraints diff --git a/provers/stark/src/constraints/transition.rs b/provers/stark/src/constraints/transition.rs index 52fe0ba70..bd2bba191 100644 --- a/provers/stark/src/constraints/transition.rs +++ b/provers/stark/src/constraints/transition.rs @@ -1,3 +1,5 @@ +use std::ops::Div; + use crate::domain::Domain; use crate::frame::Frame; use crate::prover::evaluate_polynomial_on_lde_domain; @@ -6,7 +8,7 @@ use lambdaworks_math::field::element::FieldElement; use lambdaworks_math::field::traits::{IsFFTField, IsField, IsSubFieldOf}; use lambdaworks_math::polynomial::Polynomial; use num_integer::Integer; -use std::ops::Div; + /// TransitionConstraint represents the behaviour that a transition constraint /// over the computation that wants to be proven must comply with. pub trait TransitionConstraint: Send + Sync @@ -144,9 +146,6 @@ where }) .collect(); - // FIXME: Instead of computing this evaluations for each constraint, they can be computed - // once for every constraint with the same end exemptions (combination of end_exemptions() - // and period). let end_exemption_evaluations = evaluate_polynomial_on_lde_domain( &end_exemptions_poly, blowup_factor, @@ -180,9 +179,6 @@ where FieldElement::inplace_batch_inverse(&mut evaluations).unwrap(); - // FIXME: Instead of computing this evaluations for each constraint, they can be computed - // once for every constraint with the same end exemptions (combination of end_exemptions() - // and period). let end_exemption_evaluations = evaluate_polynomial_on_lde_domain( &end_exemptions_poly, blowup_factor, diff --git a/provers/stark/src/context.rs b/provers/stark/src/context.rs index d53159626..e7f164d27 100644 --- a/provers/stark/src/context.rs +++ b/provers/stark/src/context.rs @@ -1,5 +1,3 @@ -use std::collections::HashSet; - use super::proof::options::ProofOptions; #[derive(Clone, Debug)] @@ -13,7 +11,6 @@ pub struct AirContext { /// offsets that are needed to compute EVERY transition constraint, even if some /// constraints don't use all of the indexes in said offsets. pub transition_offsets: Vec, - pub transition_exemptions: Vec, pub num_transition_constraints: usize, } @@ -21,14 +18,4 @@ impl AirContext { pub fn num_transition_constraints(&self) -> usize { self.num_transition_constraints } - - /// Returns the number of non-trivial different - /// transition exemptions. - pub fn num_transition_exemptions(&self) -> usize { - self.transition_exemptions - .iter() - .filter(|&x| *x != 0) - .collect::>() - .len() - } } diff --git a/provers/stark/src/debug.rs b/provers/stark/src/debug.rs index fc62257a4..36bee2922 100644 --- a/provers/stark/src/debug.rs +++ b/provers/stark/src/debug.rs @@ -80,12 +80,10 @@ pub fn validate_trace( // --------- VALIDATE TRANSITION CONSTRAINTS ----------- let n_transition_constraints = air.context().num_transition_constraints(); - let transition_exemptions = &air.context().transition_exemptions; - - let exemption_steps: Vec = vec![lde_trace.num_rows(); n_transition_constraints] - .iter() - .zip(transition_exemptions) - .map(|(trace_steps, exemptions)| trace_steps - exemptions) + let exemption_steps: Vec = std::iter::repeat(lde_trace.num_steps()) + .take(n_transition_constraints) + .zip(air.transition_constraints()) + .map(|(trace_steps, constraint)| trace_steps - constraint.end_exemptions()) .collect(); // Iterate over trace and compute transitions diff --git a/provers/stark/src/examples/bit_flags.rs b/provers/stark/src/examples/bit_flags.rs index bec16ef60..9fcd80343 100644 --- a/provers/stark/src/examples/bit_flags.rs +++ b/provers/stark/src/examples/bit_flags.rs @@ -90,10 +90,6 @@ impl TransitionConstraint for ZeroFlagConstraint { 16 } - fn offset(&self) -> usize { - 15 - } - fn evaluate( &self, frame: &Frame, @@ -130,17 +126,13 @@ impl AIR for BitFlagsAIR { let flag_constraint = Box::new(ZeroFlagConstraint::new()); let constraints: Vec>> = vec![bit_constraint, flag_constraint]; - // vec![flag_constraint]; - // vec![bit_constraint]; let num_transition_constraints = constraints.len(); - let transition_exemptions: Vec<_> = - constraints.iter().map(|c| c.end_exemptions()).collect(); + let context = AirContext { proof_options: proof_options.clone(), - trace_columns: 1, - transition_exemptions, + trace_columns: 2, transition_offsets: vec![0], num_transition_constraints, }; @@ -195,7 +187,7 @@ impl AIR for BitFlagsAIR { } } -pub fn bit_prefix_flag_trace(num_steps: usize) -> TraceTable { +pub fn bit_prefix_flag_trace(num_steps: usize) -> TraceTable { debug_assert!(num_steps.is_power_of_two()); let step: Vec = [ 1031u64, 515, 257, 128, 64, 32, 16, 8, 4, 2, 1, 0, 0, 0, 0, 0, @@ -207,5 +199,10 @@ pub fn bit_prefix_flag_trace(num_steps: usize) -> TraceTable { let mut data: Vec = iter::repeat(step).take(num_steps).flatten().collect(); data[0] = Felt252::from(1030); - TraceTable::new(data, 1, 0, 16) + let mut dummy_column = (0..16).map(Felt252::from).collect(); + dummy_column = iter::repeat(dummy_column) + .take(num_steps) + .flatten() + .collect(); + TraceTable::from_columns_main(vec![data, dummy_column], 16) } diff --git a/provers/stark/src/examples/dummy_air.rs b/provers/stark/src/examples/dummy_air.rs index 1206ed153..7ad45beb0 100644 --- a/provers/stark/src/examples/dummy_air.rs +++ b/provers/stark/src/examples/dummy_air.rs @@ -140,7 +140,6 @@ impl AIR for DummyAIR { let context = AirContext { proof_options: proof_options.clone(), trace_columns: 2, - transition_exemptions: vec![0, 2], transition_offsets: vec![0, 1, 2], num_transition_constraints: 2, }; @@ -198,7 +197,7 @@ impl AIR for DummyAIR { } } -pub fn dummy_trace(trace_length: usize) -> TraceTable { +pub fn dummy_trace(trace_length: usize) -> TraceTable { let mut ret: Vec> = vec![]; let a0 = FieldElement::one(); @@ -211,9 +210,5 @@ pub fn dummy_trace(trace_length: usize) -> TraceTable { ret.push(ret[i - 1].clone() + ret[i - 2].clone()); } - TraceTable::from_columns( - vec![vec![FieldElement::::one(); trace_length], ret], - 2, - 1, - ) + TraceTable::from_columns_main(vec![vec![FieldElement::::one(); trace_length], ret], 1) } diff --git a/provers/stark/src/examples/fibonacci_2_cols_shifted.rs b/provers/stark/src/examples/fibonacci_2_cols_shifted.rs index 6d3eb76d1..d7183bbd0 100644 --- a/provers/stark/src/examples/fibonacci_2_cols_shifted.rs +++ b/provers/stark/src/examples/fibonacci_2_cols_shifted.rs @@ -171,7 +171,6 @@ where let context = AirContext { proof_options: proof_options.clone(), - transition_exemptions: vec![1, 1], transition_offsets: vec![0, 1], num_transition_constraints: 2, trace_columns: 2, @@ -238,7 +237,7 @@ where pub fn compute_trace( initial_value: FieldElement, trace_length: usize, -) -> TraceTable { +) -> TraceTable { let mut x = FieldElement::one(); let mut y = initial_value; let mut col0 = vec![x.clone()]; @@ -250,7 +249,7 @@ pub fn compute_trace( col1.push(y.clone()); } - TraceTable::from_columns(vec![col0, col1], 2, 1) + TraceTable::from_columns_main(vec![col0, col1], 1) } #[cfg(test)] @@ -264,46 +263,9 @@ mod tests { #[test] fn trace_has_expected_rows() { let trace = compute_trace(FieldElement::::one(), 8); - assert_eq!(trace.n_rows(), 8); + assert_eq!(trace.num_rows(), 8); let trace = compute_trace(FieldElement::::one(), 64); - assert_eq!(trace.n_rows(), 64); - } - - #[test] - fn trace_of_8_rows_is_correctly_calculated() { - let trace = compute_trace(FieldElement::::one(), 8); - assert_eq!( - trace.get_row(0), - vec![FieldElement::one(), FieldElement::one()] - ); - assert_eq!( - trace.get_row(1), - vec![FieldElement::one(), FieldElement::from(2)] - ); - assert_eq!( - trace.get_row(2), - vec![FieldElement::from(2), FieldElement::from(3)] - ); - assert_eq!( - trace.get_row(3), - vec![FieldElement::from(3), FieldElement::from(5)] - ); - assert_eq!( - trace.get_row(4), - vec![FieldElement::from(5), FieldElement::from(8)] - ); - assert_eq!( - trace.get_row(5), - vec![FieldElement::from(8), FieldElement::from(13)] - ); - assert_eq!( - trace.get_row(6), - vec![FieldElement::from(13), FieldElement::from(21)] - ); - assert_eq!( - trace.get_row(7), - vec![FieldElement::from(21), FieldElement::from(34)] - ); + assert_eq!(trace.num_rows(), 64); } } diff --git a/provers/stark/src/examples/fibonacci_2_columns.rs b/provers/stark/src/examples/fibonacci_2_columns.rs index 0cd2a789a..0d01efec5 100644 --- a/provers/stark/src/examples/fibonacci_2_columns.rs +++ b/provers/stark/src/examples/fibonacci_2_columns.rs @@ -148,7 +148,6 @@ where let context = AirContext { proof_options: proof_options.clone(), - transition_exemptions: vec![1, 1], transition_offsets: vec![0, 1], num_transition_constraints: constraints.len(), trace_columns: 2, @@ -209,7 +208,7 @@ where pub fn compute_trace( initial_values: [FieldElement; 2], trace_length: usize, -) -> TraceTable { +) -> TraceTable { let mut ret1: Vec> = vec![]; let mut ret2: Vec> = vec![]; @@ -222,5 +221,5 @@ pub fn compute_trace( ret2.push(new_val + ret2[i - 1].clone()); } - TraceTable::from_columns(vec![ret1, ret2], 2, 1) + TraceTable::from_columns_main(vec![ret1, ret2], 1) } diff --git a/provers/stark/src/examples/fibonacci_rap.rs b/provers/stark/src/examples/fibonacci_rap.rs index 18084f86f..1186a7d24 100644 --- a/provers/stark/src/examples/fibonacci_rap.rs +++ b/provers/stark/src/examples/fibonacci_rap.rs @@ -166,13 +166,10 @@ where Box::new(PermutationConstraint::new()), ]; - let exemptions = 3 + trace_length - pub_inputs.steps - 1; - let context = AirContext { proof_options: proof_options.clone(), trace_columns: 3, transition_offsets: vec![0, 1, 2], - transition_exemptions: vec![exemptions, 1], num_transition_constraints: transition_constraints.len(), }; @@ -186,15 +183,15 @@ where fn build_auxiliary_trace( &self, - main_trace: &TraceTable, + trace: &mut TraceTable, challenges: &[FieldElement], - ) -> TraceTable { - let main_segment_cols = main_trace.columns(); + ) { + let main_segment_cols = trace.columns_main(); let not_perm = &main_segment_cols[0]; let perm = &main_segment_cols[1]; let gamma = &challenges[0]; - let trace_len = main_trace.n_rows(); + let trace_len = trace.num_rows(); let mut aux_col = Vec::new(); for i in 0..trace_len { @@ -208,7 +205,10 @@ where aux_col.push(z_i * n_p_term.div(p_term)); } } - TraceTable::from_columns(vec![aux_col], 0, 1) + + for (i, aux_elem) in aux_col.iter().enumerate().take(trace.num_rows()) { + trace.set_aux(i, 0, aux_elem.clone()) + } } fn build_rap_challenges( @@ -236,7 +236,6 @@ where let a0_aux = BoundaryConstraint::new_aux(0, 0, FieldElement::::one()); BoundaryConstraints::from_constraints(vec![a0, a1, a0_aux]) - // BoundaryConstraints::from_constraints(vec![a0, a1]) } fn transition_constraints( @@ -274,9 +273,8 @@ where pub fn fibonacci_rap_trace( initial_values: [FieldElement; 2], trace_length: usize, -) -> TraceTable { +) -> TraceTable { let mut fib_seq: Vec> = vec![]; - fib_seq.push(initial_values[0].clone()); fib_seq.push(initial_values[1].clone()); @@ -294,7 +292,13 @@ pub fn fibonacci_rap_trace( let mut trace_cols = vec![fib_seq, fib_permuted]; resize_to_next_power_of_two(&mut trace_cols); - TraceTable::from_columns(trace_cols, 2, 1) + let mut trace = TraceTable::allocate_with_zeros(trace_cols[0].len(), 2, 1, 1); + for i in 0..trace.num_rows() { + trace.set_main(i, 0, trace_cols[0][i].clone()); + trace.set_main(i, 1, trace_cols[1][i].clone()); + } + + trace } #[cfg(test)] @@ -337,13 +341,13 @@ mod test { ]; resize_to_next_power_of_two(&mut expected_trace); - assert_eq!(trace.columns(), expected_trace); + assert_eq!(trace.columns_main(), expected_trace); } #[test] fn aux_col() { let trace = fibonacci_rap_trace([FE17::from(1), FE17::from(1)], 64); - let trace_cols = trace.columns(); + let trace_cols = trace.columns_main(); let not_perm = trace_cols[0].clone(); let perm = trace_cols[1].clone(); diff --git a/provers/stark/src/examples/quadratic_air.rs b/provers/stark/src/examples/quadratic_air.rs index 3d07d78e3..4ac019043 100644 --- a/provers/stark/src/examples/quadratic_air.rs +++ b/provers/stark/src/examples/quadratic_air.rs @@ -100,7 +100,6 @@ where let context = AirContext { proof_options: proof_options.clone(), trace_columns: 1, - transition_exemptions: vec![1], transition_offsets: vec![0, 1], num_transition_constraints: constraints.len(), }; @@ -161,7 +160,7 @@ where pub fn quadratic_trace( initial_value: FieldElement, trace_length: usize, -) -> TraceTable { +) -> TraceTable { let mut ret: Vec> = vec![]; ret.push(initial_value); @@ -170,5 +169,5 @@ pub fn quadratic_trace( ret.push(ret[i - 1].clone() * ret[i - 1].clone()); } - TraceTable::from_columns(vec![ret], 1, 1) + TraceTable::from_columns_main(vec![ret], 1) } diff --git a/provers/stark/src/examples/simple_fibonacci.rs b/provers/stark/src/examples/simple_fibonacci.rs index 204aa938c..c3b052fca 100644 --- a/provers/stark/src/examples/simple_fibonacci.rs +++ b/provers/stark/src/examples/simple_fibonacci.rs @@ -102,7 +102,6 @@ where let context = AirContext { proof_options: proof_options.clone(), trace_columns: 1, - transition_exemptions: vec![2], transition_offsets: vec![0, 1, 2], num_transition_constraints: constraints.len(), }; @@ -162,7 +161,7 @@ where pub fn fibonacci_trace( initial_values: [FieldElement; 2], trace_length: usize, -) -> TraceTable { +) -> TraceTable { let mut ret: Vec> = vec![]; ret.push(initial_values[0].clone()); @@ -172,5 +171,5 @@ pub fn fibonacci_trace( ret.push(ret[i - 1].clone() + ret[i - 2].clone()); } - TraceTable::from_columns(vec![ret], 1, 1) + TraceTable::from_columns_main(vec![ret], 1) } diff --git a/provers/stark/src/examples/simple_periodic_cols.rs b/provers/stark/src/examples/simple_periodic_cols.rs index 369ff2dd0..c1d14b03a 100644 --- a/provers/stark/src/examples/simple_periodic_cols.rs +++ b/provers/stark/src/examples/simple_periodic_cols.rs @@ -23,6 +23,7 @@ impl PeriodicConstraint { } } } + impl Default for PeriodicConstraint { fn default() -> Self { Self::new() @@ -121,7 +122,6 @@ where let context = AirContext { proof_options: proof_options.clone(), trace_columns: 1, - transition_exemptions: vec![2], transition_offsets: vec![0, 1, 2], num_transition_constraints: transition_constraints.len(), }; @@ -187,7 +187,7 @@ where } } -pub fn simple_periodic_trace(trace_length: usize) -> TraceTable { +pub fn simple_periodic_trace(trace_length: usize) -> TraceTable { let mut ret: Vec> = vec![]; ret.push(FieldElement::one()); diff --git a/provers/stark/src/proof/stark.rs b/provers/stark/src/proof/stark.rs index f593d144d..44fbe7a59 100644 --- a/provers/stark/src/proof/stark.rs +++ b/provers/stark/src/proof/stark.rs @@ -464,761 +464,761 @@ impl StoneCompatibleSerializer { } } -#[cfg(test)] -mod tests { - use lambdaworks_math::{field::element::FieldElement, traits::AsBytes}; - - use crate::{ - examples::fibonacci_2_cols_shifted::{self, Fibonacci2ColsShifted}, - proof::{options::ProofOptions, stark::StoneCompatibleSerializer}, - prover::{IsStarkProver, Prover}, - transcript::StoneProverTranscript, - }; - - #[test] - fn test_serialization_compatible_with_stone_1() { - let trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::one(), 4); - - let claimed_index = 3; - let claimed_value = trace.get_row(claimed_index)[0]; - let proof_options = ProofOptions { - blowup_factor: 4, - coset_offset: 3, - grinding_factor: 0, - fri_number_of_queries: 1, - }; - - let pub_inputs = fibonacci_2_cols_shifted::PublicInputs { - claimed_value, - claimed_index, - }; - - let proof = Prover::>::prove( - &trace, - &pub_inputs, - &proof_options, - StoneProverTranscript::new(&pub_inputs.as_bytes()), - ) - .unwrap(); - - let expected_bytes = [ - 14, 185, 220, 192, 251, 24, 84, 87, 42, 1, 35, 103, 83, 206, 5, 19, 157, 57, 42, 163, - 174, 175, 231, 42, 191, 241, 80, 254, 33, 23, 85, 148, 240, 15, 97, 4, 33, 250, 73, 57, - 153, 20, 91, 112, 71, 103, 155, 245, 134, 85, 150, 224, 103, 5, 176, 183, 152, 52, 190, - 56, 94, 184, 211, 203, 1, 10, 170, 210, 58, 15, 137, 139, 84, 215, 101, 26, 236, 253, - 138, 16, 34, 94, 85, 246, 117, 36, 122, 25, 65, 56, 39, 64, 182, 60, 92, 149, 0, 61, - 238, 22, 79, 89, 52, 136, 161, 125, 245, 232, 111, 27, 91, 235, 0, 112, 73, 52, 122, - 171, 178, 11, 249, 92, 149, 195, 95, 127, 77, 90, 0, 63, 48, 208, 46, 245, 248, 39, - 173, 179, 161, 21, 59, 173, 210, 38, 117, 61, 159, 103, 129, 41, 200, 180, 127, 152, - 136, 37, 52, 131, 168, 143, 7, 71, 166, 221, 33, 179, 43, 105, 109, 45, 26, 161, 194, - 171, 13, 78, 139, 52, 158, 132, 170, 241, 155, 38, 213, 231, 199, 58, 181, 248, 101, - 136, 5, 201, 25, 47, 164, 4, 56, 196, 188, 130, 134, 39, 128, 65, 210, 9, 124, 10, 82, - 253, 146, 34, 57, 37, 92, 71, 2, 44, 3, 248, 124, 227, 206, 179, 238, 69, 200, 177, 31, - 7, 171, 247, 48, 97, 185, 116, 237, 171, 117, 251, 207, 4, 66, 112, 144, 10, 255, 60, - 207, 185, 25, 7, 110, 159, 3, 120, 156, 213, 179, 46, 1, 189, 58, 131, 21, 190, 194, - 176, 219, 255, 172, 68, 21, 117, 44, 122, 177, 139, 62, 111, 251, 21, 15, 81, 246, 120, - 6, 115, 221, 244, 77, 82, 191, 9, 150, 178, 205, 168, 196, 218, 39, 107, 231, 32, 56, - 92, 78, 19, 151, 21, 18, 123, 158, 163, 7, 245, 10, 237, 4, 231, 187, 232, 154, 165, - 106, 226, 45, 101, 155, 81, 137, 180, 78, 215, 206, 64, 112, 184, 156, 39, 46, 42, 36, - 247, 61, 70, 15, 234, 20, 185, 1, 140, 34, 11, 178, 173, 48, 7, 105, 77, 50, 87, 59, - 37, 216, 148, 24, 223, 199, 163, 177, 236, 104, 234, 237, 132, 97, 92, 248, 10, 244, - 20, 3, 24, 68, 23, 101, 90, 108, 206, 210, 154, 100, 174, 118, 75, 177, 40, 49, 191, - 143, 71, 99, 216, 209, 213, 219, 8, 194, 185, 240, 21, 232, 232, 145, 176, 192, 178, - 75, 157, 0, 6, 123, 14, 250, 181, 8, 50, 183, 108, 249, 113, 146, 9, 22, 36, 212, 43, - 134, 116, 6, 102, 197, 211, 105, 230, 153, 59, 4, 77, 178, 36, 68, 192, 192, 235, 241, - 9, 91, 154, 81, 250, 235, 0, 28, 155, 77, 234, 54, 171, 233, 5, 247, 22, 38, 32, 219, - 189, 80, 23, 171, 236, 163, 63, 168, 37, 118, 181, 197, 194, 198, 23, 146, 105, 59, 72, - 201, 212, 65, 74, 64, 126, 239, 102, 182, 2, 157, 174, 7, 234, 6, 40, 218, 216, 248, - 96, 149, 112, 209, 255, 173, 185, 81, 55, 105, 97, 6, 239, 20, 189, 183, 213, 184, 147, - 226, 210, 8, 224, 248, 198, 11, 186, 7, 179, 148, 95, 226, 129, 234, 27, 46, 85, 20, - 182, 118, 241, 2, 69, 184, 39, 231, 81, 9, 28, 60, 114, 120, 53, 252, 192, 115, 40, - 213, 33, 160, 213, 41, 195, 61, 131, 42, 105, 77, 188, 109, 118, 53, 70, 24, 141, 94, - 101, 222, 67, 254, 29, 157, 8, 184, 145, 194, 89, 189, 95, 253, 181, 90, 70, 207, 28, - 53, 40, 246, 178, 129, 178, 83, 109, 24, 202, 136, 140, 211, 4, 167, 36, 253, 29, 66, - 79, 250, 184, 63, 158, 162, 206, 83, 135, 251, 125, 215, 121, 149, 118, 82, 112, 53, - 242, 58, 127, 196, 123, 63, 110, 192, 137, 125, 95, 72, 122, 82, 8, 121, 113, 241, 76, - 255, 36, 96, 225, 5, 158, 234, 196, 65, 220, 82, 70, 244, 90, 62, 85, 201, 169, 9, 104, - 29, 215, 76, 179, 28, 235, 123, 86, 98, 25, 254, 123, 7, 55, 26, 190, 66, 97, 62, 111, - 150, 110, 27, 233, 81, 131, 192, 21, 72, 16, 130, 46, 43, 43, 213, 145, 96, 22, 224, - 211, 5, 253, 114, 94, 164, 190, 87, 143, 69, 128, 1, 253, 103, 213, 139, 7, 35, 132, - 52, 242, 55, 248, 72, 214, 102, 108, 57, 205, 46, 20, 1, 83, 198, 32, 167, 96, 242, - 117, 87, 201, - ]; - - let serialized_proof = StoneCompatibleSerializer::serialize_proof::>( - &proof, - &pub_inputs, - &proof_options, - ); - assert_eq!(serialized_proof, expected_bytes); - } - - #[test] - fn test_serialization_compatible_with_stone_case_2() { - let trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::one(), 4); - - let claimed_index = 2; - let claimed_value = trace.get_row(claimed_index)[0]; - let proof_options = ProofOptions { - blowup_factor: 2, - coset_offset: 3, - grinding_factor: 0, - fri_number_of_queries: 10, - }; - - let pub_inputs = fibonacci_2_cols_shifted::PublicInputs { - claimed_value, - claimed_index, - }; - - let proof = Prover::>::prove( - &trace, - &pub_inputs, - &proof_options, - StoneProverTranscript::new(&pub_inputs.as_bytes()), - ) - .unwrap(); - let expected_bytes = [ - 9, 161, 59, 243, 85, 60, 44, 155, 163, 203, 128, 147, 203, 253, 93, 16, 137, 42, 94, - 225, 173, 254, 120, 1, 43, 167, 254, 15, 49, 148, 2, 50, 47, 159, 254, 83, 209, 26, 91, - 113, 237, 157, 107, 252, 35, 130, 117, 22, 155, 181, 217, 11, 145, 208, 53, 201, 14, - 148, 19, 247, 19, 105, 239, 108, 2, 17, 212, 103, 137, 76, 186, 20, 31, 118, 21, 139, - 122, 39, 100, 197, 112, 11, 188, 227, 236, 15, 127, 186, 231, 187, 158, 137, 41, 180, - 233, 36, 3, 145, 50, 37, 100, 198, 0, 152, 68, 30, 64, 111, 78, 211, 119, 49, 142, 180, - 178, 74, 59, 150, 209, 45, 211, 159, 6, 216, 205, 161, 255, 142, 0, 104, 163, 169, 38, - 160, 79, 95, 195, 96, 46, 20, 45, 189, 161, 181, 95, 133, 26, 124, 224, 44, 153, 119, - 121, 29, 187, 126, 125, 161, 4, 45, 2, 1, 113, 106, 28, 174, 255, 138, 4, 34, 227, 191, - 33, 203, 60, 20, 34, 36, 33, 8, 44, 53, 250, 177, 127, 59, 157, 229, 179, 87, 165, 58, - 0, 0, 83, 98, 7, 41, 90, 187, 198, 80, 159, 250, 57, 252, 211, 64, 233, 110, 223, 155, - 56, 189, 215, 57, 80, 161, 169, 246, 65, 133, 129, 132, 129, 233, 154, 204, 187, 178, - 244, 76, 12, 9, 30, 113, 105, 206, 46, 192, 68, 96, 27, 72, 94, 126, 101, 253, 63, 94, - 10, 89, 116, 120, 31, 123, 5, 224, 161, 148, 232, 99, 202, 108, 45, 218, 145, 93, 103, - 64, 177, 105, 163, 115, 34, 11, 250, 31, 46, 213, 139, 205, 219, 194, 199, 175, 220, - 79, 3, 24, 68, 23, 101, 90, 193, 206, 210, 154, 100, 174, 118, 75, 177, 40, 49, 191, - 143, 71, 99, 216, 209, 213, 219, 8, 194, 185, 240, 21, 237, 232, 4, 164, 102, 35, 24, - 8, 49, 150, 59, 231, 151, 5, 177, 113, 137, 188, 74, 159, 86, 235, 21, 197, 58, 192, - 200, 141, 36, 22, 232, 32, 229, 188, 4, 231, 187, 232, 154, 165, 64, 98, 45, 101, 155, - 81, 137, 180, 78, 215, 206, 64, 112, 184, 156, 39, 46, 42, 36, 247, 61, 70, 15, 234, - 18, 57, 3, 91, 153, 220, 231, 247, 223, 122, 196, 24, 104, 250, 78, 142, 118, 67, 181, - 96, 169, 20, 234, 58, 197, 63, 55, 114, 219, 233, 23, 223, 27, 69, 6, 115, 221, 244, - 77, 82, 191, 9, 150, 178, 205, 168, 196, 218, 39, 107, 231, 32, 56, 92, 78, 19, 151, - 21, 18, 123, 158, 163, 7, 245, 10, 237, 4, 231, 187, 232, 154, 165, 106, 226, 45, 101, - 155, 81, 137, 180, 78, 215, 206, 64, 112, 184, 156, 39, 46, 42, 36, 247, 61, 70, 15, - 234, 20, 185, 1, 140, 34, 11, 178, 173, 48, 7, 105, 77, 50, 87, 59, 37, 216, 148, 24, - 223, 199, 163, 177, 236, 104, 234, 237, 132, 97, 92, 248, 10, 244, 20, 3, 24, 68, 23, - 101, 90, 108, 206, 210, 154, 100, 174, 118, 75, 177, 40, 49, 191, 143, 71, 99, 216, - 209, 213, 219, 8, 194, 185, 240, 21, 232, 232, 7, 51, 41, 162, 227, 93, 103, 1, 119, - 157, 40, 0, 161, 176, 143, 13, 53, 64, 172, 166, 74, 71, 4, 177, 30, 109, 56, 217, 15, - 172, 148, 119, 0, 1, 40, 225, 211, 37, 67, 227, 195, 75, 15, 184, 75, 35, 121, 152, 11, - 206, 130, 181, 93, 52, 26, 222, 54, 225, 164, 206, 119, 98, 49, 127, 1, 245, 239, 229, - 226, 164, 147, 237, 23, 92, 189, 192, 202, 171, 211, 97, 221, 103, 41, 20, 123, 42, 73, - 255, 19, 182, 16, 44, 170, 91, 163, 241, 3, 122, 35, 184, 126, 224, 183, 84, 233, 162, - 161, 139, 249, 241, 173, 181, 44, 40, 254, 122, 243, 31, 209, 50, 95, 136, 54, 66, 182, - 182, 120, 86, 1, 200, 25, 46, 236, 199, 14, 120, 215, 166, 119, 142, 184, 187, 93, 210, - 70, 99, 209, 109, 106, 7, 38, 13, 86, 113, 77, 40, 239, 101, 112, 47, 2, 80, 119, 11, - 163, 93, 205, 89, 30, 136, 45, 112, 44, 157, 216, 11, 39, 148, 121, 29, 189, 236, 115, - 33, 204, 138, 68, 69, 217, 20, 115, 169, 5, 14, 205, 72, 77, 54, 231, 218, 153, 95, - 162, 175, 218, 232, 63, 190, 166, 244, 88, 215, 208, 135, 139, 66, 119, 107, 105, 209, - 86, 146, 86, 139, 2, 52, 60, 90, 10, 156, 32, 31, 52, 138, 33, 75, 142, 77, 0, 167, - 160, 116, 5, 177, 241, 191, 160, 205, 157, 11, 224, 168, 248, 210, 225, 35, 1, 8, 125, - 71, 71, 5, 38, 16, 199, 27, 91, 50, 8, 54, 219, 166, 194, 250, 10, 202, 190, 145, 195, - 160, 218, 188, 29, 73, 184, 247, 42, 44, 3, 221, 45, 93, 101, 219, 38, 37, 3, 232, 2, - 98, 27, 149, 66, 245, 31, 23, 114, 149, 174, 202, 119, 96, 233, 114, 114, 46, 147, 166, - 89, 244, 1, 166, 156, 186, 246, 241, 109, 41, 76, 181, 248, 23, 253, 193, 236, 87, 42, - 52, 162, 91, 167, 141, 227, 164, 162, 247, 95, 64, 90, 59, 117, 210, 1, 143, 44, 156, - 144, 94, 237, 240, 120, 79, 31, 189, 37, 133, 249, 195, 95, 23, 87, 168, 26, 6, 60, - 175, 235, 164, 121, 7, 220, 167, 78, 247, 3, 157, 144, 158, 44, 242, 203, 233, 164, 71, - 98, 98, 68, 87, 50, 103, 230, 182, 72, 240, 222, 223, 129, 196, 249, 204, 56, 77, 80, - 64, 39, 35, 0, 32, 49, 240, 229, 228, 251, 68, 176, 221, 45, 123, 205, 240, 137, 20, - 168, 248, 87, 111, 142, 170, 189, 190, 226, 99, 108, 192, 61, 135, 89, 138, 5, 100, 74, - 55, 89, 173, 9, 154, 231, 111, 119, 138, 82, 126, 3, 197, 143, 28, 74, 78, 198, 99, - 129, 126, 84, 31, 119, 224, 42, 247, 70, 75, 6, 249, 103, 53, 199, 171, 214, 151, 83, - 116, 110, 0, 226, 78, 69, 116, 76, 146, 140, 180, 251, 2, 154, 84, 34, 123, 74, 210, - 202, 193, 129, 242, - ]; - - let serialized_proof = StoneCompatibleSerializer::serialize_proof::>( - &proof, - &pub_inputs, - &proof_options, - ); - assert_eq!(serialized_proof, expected_bytes); - } - - #[test] - fn test_serialization_compatible_with_stone_case_3() { - let trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::from(12345), 512); - - let claimed_index = 420; - let claimed_value = trace.get_row(claimed_index)[0]; - let proof_options = ProofOptions { - blowup_factor: 64, - coset_offset: 3, - grinding_factor: 0, - fri_number_of_queries: 1, - }; - - let pub_inputs = fibonacci_2_cols_shifted::PublicInputs { - claimed_value, - claimed_index, - }; - - let proof = Prover::>::prove( - &trace, - &pub_inputs, - &proof_options, - StoneProverTranscript::new(&pub_inputs.as_bytes()), - ) - .unwrap(); - - let expected_bytes = [ - 109, 49, 221, 0, 3, 137, 116, 189, 229, 254, 12, 94, 58, 118, 95, 141, 220, 130, 42, - 93, 243, 37, 79, 202, 133, 161, 149, 10, 224, 32, 140, 190, 239, 19, 119, 217, 232, 38, - 44, 103, 224, 84, 37, 164, 175, 0, 176, 5, 228, 209, 131, 135, 35, 160, 245, 180, 101, - 20, 17, 193, 139, 244, 214, 182, 4, 75, 226, 131, 251, 225, 219, 95, 239, 73, 57, 144, - 157, 77, 141, 185, 96, 12, 72, 162, 220, 59, 28, 165, 125, 180, 59, 196, 125, 175, 147, - 35, 3, 166, 113, 39, 138, 98, 152, 242, 130, 179, 98, 207, 75, 213, 4, 166, 18, 174, - 48, 180, 163, 178, 171, 151, 243, 160, 172, 30, 19, 10, 81, 246, 7, 162, 17, 184, 194, - 192, 238, 157, 46, 254, 115, 59, 129, 110, 64, 254, 132, 223, 32, 210, 127, 58, 127, - 190, 163, 99, 231, 54, 160, 7, 227, 245, 1, 28, 36, 75, 6, 234, 197, 16, 123, 234, 123, - 154, 110, 86, 44, 23, 105, 219, 66, 35, 196, 86, 208, 208, 157, 109, 255, 213, 31, 138, - 123, 204, 0, 132, 81, 145, 33, 88, 101, 30, 95, 38, 58, 112, 158, 89, 220, 144, 206, - 77, 119, 14, 188, 69, 181, 70, 203, 71, 219, 116, 215, 142, 82, 164, 61, 94, 225, 126, - 73, 242, 43, 24, 127, 130, 247, 244, 127, 165, 142, 63, 223, 61, 62, 47, 58, 50, 239, - 208, 158, 217, 33, 145, 153, 52, 14, 146, 60, 152, 42, 0, 41, 233, 231, 56, 238, 53, - 148, 74, 50, 241, 205, 55, 228, 202, 41, 162, 225, 98, 181, 163, 113, 121, 186, 191, - 251, 237, 32, 214, 95, 103, 181, 76, 217, 46, 234, 0, 133, 191, 106, 153, 5, 56, 85, - 104, 188, 40, 43, 58, 21, 49, 220, 52, 59, 55, 57, 161, 205, 139, 63, 152, 192, 83, - 136, 28, 1, 55, 103, 147, 6, 199, 241, 92, 63, 22, 56, 220, 43, 42, 4, 48, 68, 250, 77, - 111, 227, 149, 14, 210, 133, 198, 182, 114, 56, 21, 64, 202, 15, 57, 86, 25, 159, 1, - 35, 149, 231, 230, 219, 194, 124, 165, 228, 46, 208, 208, 164, 239, 100, 33, 111, 18, - 227, 115, 181, 168, 180, 24, 131, 150, 226, 64, 87, 166, 222, 137, 57, 189, 96, 66, 46, - 148, 142, 4, 142, 243, 124, 107, 115, 149, 111, 232, 87, 214, 39, 169, 76, 71, 189, 27, - 56, 42, 148, 156, 18, 98, 128, 83, 135, 142, 177, 240, 195, 181, 221, 74, 3, 246, 155, - 238, 56, 177, 216, 10, 65, 176, 176, 212, 50, 153, 84, 128, 133, 72, 64, 210, 71, 10, - 48, 15, 164, 237, 45, 117, 5, 187, 184, 110, 119, 11, 176, 88, 244, 33, 128, 177, 152, - 84, 180, 245, 96, 179, 0, 229, 209, 249, 139, 216, 125, 21, 8, 97, 40, 101, 126, 12, - 86, 7, 58, 198, 234, 37, 156, 164, 28, 147, 117, 228, 144, 110, 220, 76, 177, 162, 6, - 197, 149, 26, 240, 74, 208, 137, 170, 135, 203, 150, 205, 215, 51, 209, 52, 226, 185, - 209, 170, 24, 64, 229, 90, 4, 210, 205, 115, 74, 164, 106, 7, 92, 83, 16, 123, 27, 14, - 166, 87, 98, 205, 51, 110, 212, 153, 51, 231, 14, 51, 252, 2, 143, 196, 251, 26, 139, - 172, 22, 53, 159, 102, 132, 0, 72, 76, 107, 117, 128, 25, 180, 198, 189, 189, 5, 45, - 174, 88, 212, 140, 156, 71, 133, 166, 85, 44, 208, 109, 241, 218, 237, 126, 135, 159, - 245, 4, 252, 211, 29, 148, 213, 86, 146, 213, 64, 168, 202, 144, 142, 118, 62, 66, 222, - 252, 200, 165, 10, 226, 2, 159, 80, 239, 120, 74, 233, 33, 183, 135, 240, 9, 224, 18, - 8, 242, 173, 64, 189, 254, 101, 25, 116, 224, 85, 71, 75, 28, 107, 156, 197, 233, 58, - 215, 153, 14, 110, 80, 2, 254, 31, 10, 152, 9, 182, 44, 18, 128, 22, 64, 20, 175, 135, - 117, 227, 111, 88, 148, 211, 188, 21, 233, 222, 56, 64, 219, 219, 57, 0, 242, 47, 240, - 142, 172, 143, 46, 26, 205, 28, 28, 204, 175, 7, 16, 55, 157, 18, 59, 85, 96, 12, 161, - 195, 113, 218, 83, 47, 191, 147, 91, 134, 244, 105, 179, 250, 211, 242, 252, 220, 59, - 165, 146, 120, 202, 78, 196, 59, 169, 9, 10, 215, 21, 233, 236, 62, 126, 42, 108, 101, - 150, 41, 198, 240, 102, 175, 43, 7, 117, 175, 8, 173, 182, 110, 124, 184, 31, 68, 251, - 58, 156, 75, 22, 152, 171, 231, 122, 174, 65, 152, 228, 111, 145, 59, 97, 216, 8, 27, - 170, 190, 95, 60, 179, 225, 115, 7, 87, 179, 156, 39, 151, 104, 248, 150, 153, 45, 198, - 251, 253, 90, 22, 78, 15, 184, 68, 216, 106, 19, 24, 5, 136, 206, 229, 175, 254, 173, - 177, 240, 221, 3, 156, 244, 92, 5, 237, 51, 202, 54, 101, 247, 95, 25, 234, 164, 217, - 81, 5, 98, 193, 159, 81, 27, 161, 210, 195, 10, 61, 163, 168, 196, 190, 166, 31, 153, - 103, 44, 57, 82, 245, 233, 21, 163, 5, 255, 63, 98, 250, 230, 134, 239, 130, 241, 40, - 12, 66, 150, 73, 61, 231, 25, 155, 136, 16, 177, 131, 254, 17, 199, 46, 55, 83, 209, - 203, 148, 20, 253, 89, 194, 121, 212, 156, 46, 42, 211, 13, 209, 251, 66, 136, 118, 51, - 218, 166, 53, 97, 13, 162, 17, 58, 241, 225, 49, 231, 110, 253, 23, 186, 100, 143, 106, - 209, 98, 176, 88, 131, 128, 22, 171, 147, 210, 79, 79, 2, 185, 240, 232, 248, 244, 216, - 102, 170, 223, 42, 221, 209, 223, 88, 168, 52, 161, 250, 144, 138, 51, 57, 14, 225, 94, - 44, 92, 159, 185, 161, 161, 23, 39, 102, 155, 37, 60, 158, 87, 223, 77, 117, 116, 86, - 16, 207, 223, 9, 147, 47, 107, 172, 83, 246, 7, 133, 107, 110, 59, 167, 172, 203, 229, - 114, 13, 183, 168, 172, 135, 192, 136, 80, 119, 67, 14, 254, 168, 56, 252, 111, 46, 13, - 45, 166, 94, 99, 87, 193, 50, 17, 196, 0, 113, 135, 60, 104, 213, 3, 147, 151, 69, 123, - 184, 247, 86, 208, 191, 63, 49, 124, 39, 153, 208, 240, 78, 91, 251, 222, 197, 237, - 101, 221, 226, 189, 61, 1, 223, 152, 242, 135, 190, 30, 33, 118, 28, 134, 96, 255, 2, - 3, 82, 102, 242, 105, 129, 86, 250, 249, 81, 246, 78, 207, 234, 47, 49, 44, 6, 1, 209, - 121, 88, 181, 75, 98, 7, 171, 77, 227, 63, 203, 30, 108, 141, 33, 153, 2, 105, 125, - 163, 197, 212, 90, 23, 87, 50, 97, 60, 102, 158, 230, 76, 9, 115, 86, 216, 215, 16, 41, - 20, 47, 34, 20, 221, 144, 161, 102, 251, 212, 29, 24, 77, 76, 54, 95, 227, 133, 112, - 134, 113, 197, 181, 151, 16, 103, 221, 115, 146, 226, 114, 240, 147, 205, 155, 155, 86, - 216, 168, 102, 56, 73, 115, 164, 174, 76, 140, 62, 82, 221, 172, 69, 127, 175, 68, 15, - 147, 11, 43, 162, 106, 224, 3, 137, 66, 240, 52, 244, 138, 231, 45, 192, 40, 124, 32, - 166, 117, 7, 148, 179, 148, 142, 82, 165, 240, 211, 183, 159, 248, 144, 67, 85, 229, - 10, 202, 39, 181, 181, 102, 190, 31, 198, 67, 124, 154, 3, 253, 122, 78, 56, 107, 195, - 216, 243, 27, 85, 12, 18, 216, 134, 123, 107, 113, 210, 28, 125, 136, 75, 135, 213, - 194, 210, 102, 183, 254, 69, 92, 157, 221, 119, 71, 105, 218, 10, 238, 112, 57, 203, - 249, 35, 19, 39, 97, 37, 188, 192, 242, 83, 199, 255, 0, 117, 70, 193, 4, 85, 195, 164, - 14, 84, 194, 117, 30, 169, 247, 101, 164, 228, 170, 210, 136, 236, 252, 88, 3, 80, 239, - 109, 10, 250, 224, 169, 142, 110, 119, 160, 78, 188, 154, 155, 105, 88, 197, 81, 165, - 90, 33, 139, 91, 31, 183, 236, 204, 100, 17, 183, 214, 33, 104, 243, 8, 25, 251, 149, - 95, 247, 98, 248, 23, 7, 37, 128, 202, 37, 67, 107, 16, 18, 228, 252, 175, 55, 9, 97, - 142, 228, 163, 25, 196, 247, 92, 61, 161, 20, 218, 252, 80, 215, 22, 83, 30, 246, 167, - 75, 109, 44, 118, 81, 74, 26, 27, 180, 35, 115, 206, 175, 229, 90, 242, 120, 74, 164, - 96, 54, 167, 67, 41, 219, 129, 224, 28, 52, 119, 29, 4, 11, 72, 86, 28, 7, 74, 76, 52, - 179, 185, 57, 71, 134, 103, 63, 57, 168, 244, 194, 194, 205, 158, 233, 203, 155, 250, - 118, 18, 146, 84, 173, 87, 201, 49, 146, 135, 113, 254, 63, 199, 36, 227, 189, 241, - 197, 204, 119, 50, 10, 253, 201, 207, 9, 149, 79, 218, 123, 149, 26, 141, 53, 177, 179, - 68, 183, 13, 158, 212, 231, 236, 212, 188, 192, 201, 129, 161, 121, 63, 225, 161, 104, - 154, 203, 221, 53, 171, 235, 154, 137, 254, 247, 95, 215, 23, 109, 83, 148, 46, 160, - 77, 164, 166, 156, 157, 27, 38, 111, 30, 127, 243, 163, 104, 251, 95, 15, 122, 132, 65, - 88, 201, 15, 185, 146, 151, 169, 148, 184, 180, 44, 198, 244, 243, 170, 15, 217, 170, - 157, 126, 163, 201, 71, 221, 97, 138, 4, 2, 178, 39, 118, 28, 107, 55, 24, 8, 38, 127, - 160, 68, 204, 40, 139, 172, 121, 229, 232, 158, 197, 74, 241, 49, 224, 75, 127, 223, - 150, 31, 221, 154, 209, 209, 152, 148, 206, 239, 63, 228, 54, 141, 73, 239, 241, 84, - 43, 141, 223, 155, 160, 240, 208, 129, 125, 152, 209, 191, 84, 11, 5, 187, 0, 170, 82, - 169, 142, 76, 191, 30, 221, 84, 80, 85, 30, 56, 127, 77, 37, 102, 212, 247, 168, 64, - 201, 96, 85, 253, 58, 56, 106, 91, 99, 208, 16, 69, 15, 159, 57, 149, 124, 215, 138, 2, - 143, 145, 0, 84, 233, 123, 126, 237, 240, 60, 107, 148, 1, 101, 199, 24, 180, 211, 147, - 152, 98, 32, 76, 154, 112, 35, 187, 21, 72, 186, 22, 128, 171, 48, 179, 120, 132, 15, - 118, 107, 103, 161, 76, 83, 216, 232, 22, 68, 203, 109, 26, 146, 160, 183, 39, 225, 43, - 187, 121, 209, 176, 223, 62, 117, 154, 70, 218, 179, 56, 226, 186, 133, 203, 244, 25, - 206, 121, 195, 33, 107, 43, 220, 183, 192, 194, 70, 157, 122, 236, 45, 93, 120, 252, - 248, 17, 245, 187, 196, 57, 151, 50, 153, 151, 109, 52, 120, 229, 244, 193, 34, 219, - 251, 244, 167, 245, 195, 171, 248, 100, 9, 126, 141, 121, 16, 126, 134, 105, 107, 129, - 79, 237, 140, 144, 220, 219, 122, 51, 231, 78, 137, 36, 8, 218, 220, 34, 149, 198, 142, - 240, 173, 27, 6, 207, 72, 131, 65, 155, 150, 106, 49, 193, 239, 160, 80, 92, 42, 149, - 182, 43, 176, 230, 27, 245, 49, 83, 131, 61, 194, 116, 24, 215, 79, 48, 230, 78, 165, - 79, 146, 16, 70, 134, 210, 213, 208, 210, 14, 200, 147, 148, 54, 108, 154, 155, 249, - 71, 250, 199, 14, 249, 151, 234, 17, 170, 85, 201, 59, 40, 40, 251, 74, 54, 198, 250, - 57, 221, 230, 132, 25, 201, 197, 205, 137, 200, 153, 255, 44, 79, 241, 83, 195, 206, - 144, 12, 31, 251, 87, 99, 31, 254, 146, 82, 214, 51, 10, 80, 26, 30, 184, 224, 65, 137, - 100, 61, 128, 193, 225, 85, 253, 192, 236, 29, 213, 90, 213, 197, 142, 47, 245, 243, - 93, 192, 159, 235, 203, 206, 90, 231, 62, 52, 59, 254, 134, 213, 179, 164, 196, 239, - 142, 28, 242, 185, 18, 100, 211, 39, 57, 206, 55, 107, 6, 223, 53, 127, 85, 196, 175, - 202, 226, 83, 23, 58, 7, 131, 55, 49, 241, 47, 146, 75, 95, 131, 61, 30, 0, 201, 216, - 226, 73, 15, 46, 156, 255, 3, 186, 188, 131, 118, 74, 228, 112, 156, 31, 41, 182, 25, - 184, 126, 254, 35, 63, 132, 216, 83, 121, 200, 232, 213, 131, 208, 66, 34, 145, 114, - 109, 109, 51, 174, 164, 89, 152, 45, 94, 205, 231, 136, 125, 201, 154, 104, 14, 178, - 68, 126, 116, 246, 165, 127, 2, 175, 198, 98, 187, 95, 66, 220, 190, 132, 223, 75, 145, - 173, 26, 84, 194, 177, 171, 144, 33, 48, 172, 94, 207, 22, 186, 146, 161, 29, 23, 174, - 1, 138, 169, 178, 43, 126, 52, 58, 236, 47, 114, 147, 69, 86, 246, 196, 50, 100, 45, - 94, 179, 93, 17, 115, 166, 83, 229, 220, 206, 83, 221, 235, 89, 247, 239, 177, 38, 235, - 141, 64, 144, 240, 255, 127, 99, 132, 227, 183, 22, 174, 175, 71, 81, 236, 34, 191, 50, - 107, 101, 113, 96, 88, 175, 23, 191, 219, 184, 69, 72, 164, 187, 168, 41, 103, 150, 67, - 9, 153, 217, 25, 156, 235, 69, 144, 44, 180, 171, 70, 193, 209, 127, 10, 60, 203, 125, - 154, 192, 65, 176, 80, 70, 51, 8, 154, 150, 6, 58, 210, 220, 6, 123, 123, 166, 141, 8, - 167, 19, 93, 144, 21, 247, 104, 86, 255, 126, 188, 137, 59, 137, 119, 94, 153, 27, 246, - 192, 11, 87, 153, 232, 34, 126, 167, 245, 15, 69, 188, 36, 41, 183, 230, 216, 179, 195, - 21, 234, 109, 240, 4, 64, 72, 250, 43, 54, 72, 16, 69, 162, 235, 97, 59, 211, 123, 247, - 59, 215, 110, 177, 7, 159, 210, 14, 25, 36, 123, 9, 232, 160, 211, 130, 213, 22, 254, - 43, 151, 90, 14, 118, 78, 108, 248, 31, 118, 90, 243, 203, 163, 20, 109, 35, 30, 110, - 65, 155, 182, 98, 64, 161, 15, 144, 89, 66, 63, 234, 111, 90, 184, 20, 175, 114, 103, - 254, 203, 103, 95, 7, 128, 147, 58, 19, 73, 102, 145, 125, 98, 12, 87, 121, 57, 117, - 114, 53, 170, 232, 50, 35, 228, 145, 21, 3, 152, 118, 250, 78, 24, 6, 140, 15, 125, - 118, 247, 183, 198, 103, 98, 20, 112, 8, 31, 60, 15, 33, 3, 235, 119, 184, 102, 137, - 145, 228, 147, 115, 95, 34, 212, 207, 125, 251, 240, 16, 186, 247, 188, 9, 29, 179, - 176, 194, 250, 115, 71, 59, 197, 244, 199, 142, 19, 25, 14, 254, 109, 182, 160, 10, - 123, 202, 55, 120, 80, 108, 3, 115, 66, 65, 77, 190, 248, 35, 116, 208, 23, 74, 164, - 158, 133, 51, 234, 23, 152, 122, 84, 62, 203, 162, 53, 9, 152, 117, 121, 72, 45, 85, - 191, 236, 150, 54, 238, 150, 171, 151, 166, 214, 67, 91, 104, 42, 119, 51, 168, 168, - 158, 115, 193, 41, 125, 217, 78, 176, 73, 36, 132, 83, 7, 240, 82, 52, 147, 37, 38, - 145, 191, 75, 133, 216, 143, 0, 55, 233, 230, 25, 113, 243, 251, 230, 43, 78, 183, 170, - 250, 145, 168, 234, 180, 68, 55, 233, 53, 166, 80, 174, 43, 137, 157, 46, 107, 90, 154, - 44, 229, 27, 83, 77, 226, 203, 24, 203, 105, 254, 242, 175, 230, 96, 45, 189, 42, 17, - 118, 163, 89, 172, 138, 250, 245, 105, 82, 166, 238, 46, 95, 13, 255, 123, 14, 58, 40, - 103, 179, 52, 94, 41, 32, 249, 39, 36, 83, 198, 144, 205, 114, 103, 219, 159, 78, 10, - 77, 249, 30, 245, 207, 9, 160, 137, 200, 126, 97, 63, 194, 134, 137, 62, 53, 210, 224, - 81, 225, 101, 120, 35, 158, 44, 65, 156, 23, 103, 57, 81, 82, 137, 94, 34, 251, 210, - 238, 81, 25, 227, 16, 142, 230, 220, 255, 225, 98, 206, 238, 189, 54, 231, 80, 148, - 212, 244, 13, 129, 55, 109, 164, 214, 15, 38, 246, 130, 51, 187, 83, 116, 150, 164, 35, - 224, 162, 131, 189, 173, 117, 225, 236, 23, 102, 111, 146, 69, 146, 116, 125, 33, 214, - 232, 112, 241, 169, 247, 80, 150, 27, 38, 179, 32, 107, 245, 170, 93, 32, 204, 243, 13, - 130, 190, 57, 125, 14, 64, 16, 151, 77, 238, 178, 24, 88, 240, 41, 191, 116, 166, 126, - 224, 42, 65, 166, 208, 35, 95, 24, 3, 216, 234, 60, 156, 110, 225, 78, 43, 147, 24, - 103, 154, 220, 185, 7, 5, 4, 61, 222, 22, 83, 143, 156, 15, 78, 144, 46, 252, 193, 225, - 101, 140, 154, 168, 107, 113, 213, 104, 147, 160, 232, 77, 143, 57, 170, 196, 109, 152, - 31, 232, 70, 103, 179, 72, 49, 19, 12, 227, 98, 118, 107, 187, 30, 170, 40, 54, 88, - 202, 222, 242, 54, 96, 28, 57, 147, 131, 105, 103, 68, 147, 6, 189, 201, 222, 223, 135, - 111, 85, 12, 239, 17, 7, 137, 188, 172, 230, 129, 36, 165, 140, 136, 55, 123, 116, 23, - 48, 122, 247, 235, 81, 63, 43, 180, 192, 175, 1, 243, 80, 116, 158, 228, 228, 115, 131, - 124, 1, 7, 236, 97, 3, 168, 220, 43, 95, 118, 146, 51, 156, 84, 0, 24, 131, 237, 83, - 117, 89, 109, 216, 173, 196, 148, 232, 170, 111, 188, 147, 58, 133, 152, 207, 48, 210, - 195, 237, 0, 139, 177, 188, 113, 41, 133, 146, 249, 190, 184, 228, 4, 22, 147, 89, 66, - 50, 77, 59, 179, 215, 87, 234, 166, 211, 186, 154, 125, 151, 100, 206, 176, 84, 65, - 232, 108, 35, 39, 8, 234, 195, 214, 6, 138, 132, 172, 164, 215, 16, 200, 213, 203, 99, - 9, 69, 6, 74, 34, 144, 49, 7, 236, 156, 73, 142, 156, 168, 40, 7, 126, 134, 43, 28, - 148, 255, 94, 170, 23, 20, 228, 114, 165, 152, 148, 184, 159, 58, 214, 66, 118, 106, - 165, 69, 100, 105, 106, 185, 187, 119, 205, 52, 233, 185, 167, 111, 117, 164, 60, 14, - 201, 70, 24, 216, 149, 52, 57, 229, 198, 225, 12, 129, 52, 49, 228, 146, 86, 65, 251, - 215, 61, 91, 104, 1, 141, 148, 5, 230, 212, 21, 96, 107, 220, 252, 150, 128, 37, 34, - 97, 68, 189, 141, 59, 224, 93, 150, 199, 249, 170, 64, 78, 61, 231, 169, 212, 171, 98, - 64, 2, 247, 190, 105, 31, 113, 201, 165, 102, 216, 100, 128, 233, 190, 150, 14, 71, 40, - 142, 37, 45, 213, 56, 212, 229, 59, 42, 88, 175, 9, 231, 220, 37, 28, 230, 171, 14, - 122, 78, 96, 111, 179, 18, 239, 193, 88, 125, 155, 99, 178, 211, 190, 100, 122, 126, - 203, 219, 83, 29, 235, 242, 129, 50, 201, 15, 175, 95, 45, 244, 217, 186, 242, 98, 71, - 197, 169, 155, 63, 107, 59, 155, 88, 5, 224, 20, 238, 113, 147, 11, 93, 228, 112, 180, - 69, 229, 154, 188, 118, 210, 52, 6, 238, 83, 70, 184, 34, 136, 7, 200, 187, 40, 144, - 76, 106, 56, 179, 198, 253, 47, 46, 16, 90, 126, 240, 26, 116, 102, 96, 30, 91, 235, - 120, 183, 80, 62, 102, 111, 191, 241, 184, 129, 55, 79, 142, 204, 46, 70, 196, 8, 228, - 67, 56, 202, 252, 91, 72, 74, 89, 195, 203, 81, 172, 198, 48, 187, 224, 77, 223, 216, - 208, 31, 25, 95, 107, 141, 104, 101, 92, 190, 31, 223, 164, 221, 155, 180, 33, 202, - 248, 217, 182, 253, 56, 132, 220, 212, 10, 18, 53, 192, 155, 232, 22, 68, 74, 62, 180, - 253, 77, 21, 199, 56, 60, 101, 201, 215, 218, 221, 133, 229, 199, 82, 230, 190, 74, 69, - 236, 226, 12, 203, 3, 216, 125, 254, 176, 176, 91, 39, 67, 182, 25, 47, 45, 58, 13, 38, - 229, 130, 162, 255, 117, 80, 141, 188, 23, 87, 96, 101, 35, 128, 124, 112, 124, 29, - 121, 114, 89, 253, 244, 161, 22, 231, 229, 178, 30, 99, 34, 220, 28, 172, 61, 229, 40, - 19, 195, 32, 235, 203, 174, 78, 124, 131, 68, 31, 139, 142, 156, 38, 255, 44, 166, 171, - 9, 196, 173, 49, 156, 16, 208, 244, 227, 30, 83, 150, 82, 61, 109, 200, 237, 163, 171, - 188, 121, 118, 149, 61, 245, 224, 62, 179, 139, 217, 62, 245, 3, 110, 216, 142, 207, - 17, 125, 51, 198, 124, 60, 46, 240, 26, 119, 215, 14, 68, 142, 150, 210, 197, 110, 107, - 204, 128, 43, 214, 90, 187, 142, 60, 51, 56, 227, 239, 17, 13, 80, 199, 101, 8, 50, - 122, 1, 190, 158, 212, 115, 61, 197, 51, 50, 235, 184, 200, 4, 250, 244, 203, 201, 222, - 206, 252, 138, 34, 8, 16, 148, 198, 112, 157, 103, 243, 74, 209, 244, 186, 198, 244, - 21, 229, 168, 246, 211, 151, 87, 7, 71, 253, 147, 109, 108, 78, 62, 148, 129, 220, 1, - 104, 76, 69, 95, 81, 99, 13, 65, 108, 42, 176, 94, 189, 120, 205, 48, 112, 207, 188, - 186, 93, 250, 13, 168, 247, 53, 112, 56, 227, 140, 246, 130, 229, 36, 200, 253, 212, - 189, 217, 128, 107, 163, 78, 78, 90, 137, 44, 20, 0, 194, 70, 89, 185, 230, 32, 161, - 37, 134, 142, 94, 155, 99, 18, 117, 154, 146, 129, 178, 53, 75, 113, 214, 116, 30, 218, - 53, 180, 61, 237, 204, 145, 98, 132, 255, 167, 27, 45, 6, 60, 23, 50, 254, 108, 76, 42, - 93, 131, 90, 209, 55, 0, 139, 71, 242, 18, 42, 225, 247, 183, 240, 147, 227, 254, 164, - 19, 184, 41, 3, 112, 41, 191, 21, 140, 43, 230, 124, 207, 193, 233, 123, 45, 79, 195, - 231, 59, 2, 181, 216, 54, 205, 186, 103, 203, 67, 10, 132, 122, 62, 203, 249, 223, 174, - 234, 104, 130, 42, 32, 32, 94, 54, 135, 161, 186, 14, 34, 125, 102, 219, 251, 209, 221, - 221, 125, 232, 18, 223, 208, 175, 206, 133, 160, 11, 228, 119, 142, 197, 232, 21, 10, - 67, 68, 132, 11, 182, 80, 158, 67, 254, 252, 90, 15, 113, 112, 15, 60, 238, 90, 147, - 207, 140, 90, 162, 211, 240, 193, 215, 182, 74, 101, 220, 176, 7, 168, 217, 104, 189, - 59, 228, 142, 204, 180, 13, 203, 209, 83, 41, 148, 179, 159, 160, 250, 91, 79, 207, - 233, 40, 4, 253, 168, 98, 209, 63, 58, 150, 164, 222, 133, 127, 213, 98, 158, 58, 14, - 207, 208, 218, 25, 71, 224, 191, 62, 178, 234, 214, 111, 105, 0, 17, 167, 226, 93, 161, - 245, 194, 161, 164, 156, 61, 174, 86, 76, 143, 78, 180, 242, 198, 189, 40, 27, 11, 119, - 165, 160, 115, 105, 8, 68, 133, 214, 163, 223, 64, 137, 185, 146, 82, 106, 38, 76, 144, - 61, 148, 57, 245, 29, 254, 246, 193, 9, 33, 84, 17, 84, 226, 201, 68, 103, 97, 220, - 221, 25, 237, 18, 242, 72, 56, 226, 26, 140, 128, 82, 224, 238, 85, 137, 243, 204, 53, - 148, 134, 103, 204, 93, 19, 253, 244, 200, 232, 100, 184, 242, 204, 155, 106, 154, 29, - 46, 168, 152, 246, 179, 85, 253, 60, 243, 159, 62, 130, 41, 55, 131, 110, 146, 68, 137, - 187, 75, 56, 9, 39, 10, 136, 120, 165, 205, 202, 76, 248, 123, 127, 159, 91, 51, 205, - 165, 76, 241, 68, 25, 38, 138, 166, 228, 98, 242, 234, 155, 147, 252, 240, 208, 145, - 23, 51, 115, 165, 22, 139, 227, 18, 81, 177, 10, 109, 86, 47, 179, 4, 198, 87, 207, - 141, 110, 129, 53, 221, 82, 182, 220, 12, 127, 17, 191, 138, 130, 95, 80, 239, 36, 90, - 185, 3, 128, 221, 252, 150, 126, 234, 79, 35, 89, 15, 175, 197, 74, 129, 167, 195, 243, - 123, 23, 179, 96, 62, 217, 158, 90, 49, 137, 144, 199, 9, 129, 91, 66, 28, 29, 24, 245, - 37, 16, 130, 47, 127, 16, 244, 220, 210, 248, 45, 98, 59, 90, 108, 153, 39, 37, 14, 22, - 72, 227, 132, 1, 72, 2, 53, 42, 150, 201, 241, 221, 21, 41, 207, 135, 191, 50, 217, 11, - 113, 73, 85, 139, 221, 233, 222, 250, 176, 230, 238, 67, 61, 26, 185, 162, 113, 139, - 10, 189, 31, 151, 154, 199, 83, 47, 229, 68, 33, 248, 228, 32, 193, 252, 30, 134, 203, - 16, 50, 157, 223, 66, 40, 207, 113, 1, 182, 195, 6, 66, 35, 187, 28, 20, 53, 118, 168, - 184, 81, 202, 34, 48, 155, 135, 157, 205, 227, 227, 187, 4, 195, 139, 2, 15, 15, 174, - 222, 109, 249, 146, 214, 77, 48, 63, 235, 45, 156, 211, 148, 188, 83, 45, 141, 250, - 253, 71, 38, 83, 145, 199, 161, 210, 213, 169, 37, 253, 175, 81, 52, 133, 76, 109, 54, - 107, 153, 205, 56, 74, 252, 58, 214, 195, 124, 19, 207, 237, 106, 205, 70, 165, 79, 28, - 182, 202, 45, 254, 55, 118, 16, 17, 3, 21, 179, 64, 215, 69, 97, 216, 41, 183, 144, - 191, 194, 113, 105, 206, 6, 180, 78, 139, 209, 44, 153, 89, 39, 248, 42, 128, 178, 19, - 125, 246, 177, 221, 39, 89, 240, 200, 158, 25, 51, 162, 105, 42, 11, 254, 156, 62, 255, - 183, 47, 228, 161, 87, 75, 132, 11, 107, 45, 45, 160, 169, 115, 73, 0, 14, 163, - ]; - - let serialized_proof = StoneCompatibleSerializer::serialize_proof::>( - &proof, - &pub_inputs, - &proof_options, - ); - assert_eq!(serialized_proof, expected_bytes); - } - - #[test] - fn test_serialization_compatible_with_stone_4() { - let trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::one(), 4); - - let claimed_index = 2; - let claimed_value = trace.get_row(claimed_index)[0]; - let proof_options = ProofOptions { - blowup_factor: 2, - coset_offset: 3, - grinding_factor: 0, - fri_number_of_queries: 2, - }; - - let pub_inputs = fibonacci_2_cols_shifted::PublicInputs { - claimed_value, - claimed_index, - }; - - let proof = Prover::>::prove( - &trace, - &pub_inputs, - &proof_options, - StoneProverTranscript::new(&pub_inputs.as_bytes()), - ) - .unwrap(); - - let expected_bytes = [ - 9, 161, 59, 243, 85, 60, 44, 155, 163, 203, 128, 147, 203, 253, 93, 16, 137, 42, 94, - 225, 173, 254, 120, 1, 43, 167, 254, 15, 49, 148, 2, 50, 47, 159, 254, 83, 209, 26, 91, - 113, 237, 157, 107, 252, 35, 130, 117, 22, 155, 181, 217, 11, 145, 208, 53, 201, 14, - 148, 19, 247, 19, 105, 239, 108, 2, 17, 212, 103, 137, 76, 186, 20, 31, 118, 21, 139, - 122, 39, 100, 197, 112, 11, 188, 227, 236, 15, 127, 186, 231, 187, 158, 137, 41, 180, - 233, 36, 3, 145, 50, 37, 100, 198, 0, 152, 68, 30, 64, 111, 78, 211, 119, 49, 142, 180, - 178, 74, 59, 150, 209, 45, 211, 159, 6, 216, 205, 161, 255, 142, 0, 104, 163, 169, 38, - 160, 79, 95, 195, 96, 46, 20, 45, 189, 161, 181, 95, 133, 26, 124, 224, 44, 153, 119, - 121, 29, 187, 126, 125, 161, 4, 45, 2, 1, 113, 106, 28, 174, 255, 138, 4, 34, 227, 191, - 33, 203, 60, 20, 34, 36, 33, 8, 44, 53, 250, 177, 127, 59, 157, 229, 179, 87, 165, 58, - 0, 0, 83, 98, 7, 41, 90, 187, 198, 80, 159, 250, 57, 252, 211, 64, 233, 110, 223, 155, - 56, 189, 215, 57, 80, 161, 169, 246, 65, 133, 129, 132, 129, 233, 154, 204, 187, 178, - 244, 76, 12, 9, 30, 113, 105, 206, 46, 192, 68, 96, 27, 72, 94, 126, 101, 253, 63, 94, - 10, 89, 116, 120, 31, 123, 5, 224, 161, 148, 232, 99, 202, 108, 45, 218, 145, 93, 103, - 64, 177, 105, 163, 115, 34, 11, 250, 31, 46, 213, 139, 205, 219, 194, 199, 175, 220, - 79, 7, 51, 41, 162, 227, 93, 103, 1, 119, 157, 40, 0, 161, 176, 143, 13, 53, 64, 172, - 166, 74, 71, 4, 177, 30, 109, 56, 217, 15, 172, 148, 119, 0, 1, 40, 225, 211, 37, 67, - 227, 195, 75, 15, 184, 75, 35, 121, 152, 11, 206, 130, 181, 93, 52, 26, 222, 54, 225, - 164, 206, 119, 98, 49, 127, 1, 245, 239, 229, 226, 164, 147, 237, 23, 92, 189, 192, - 202, 171, 211, 97, 221, 103, 41, 20, 123, 42, 73, 255, 19, 182, 16, 44, 170, 91, 163, - 241, 3, 122, 35, 184, 126, 224, 183, 84, 233, 162, 161, 139, 249, 241, 173, 181, 44, - 40, 254, 122, 243, 31, 209, 50, 95, 136, 54, 66, 182, 182, 120, 86, 1, 200, 25, 46, - 236, 199, 14, 120, 215, 166, 119, 142, 184, 187, 93, 210, 70, 99, 209, 109, 106, 7, 38, - 13, 86, 113, 77, 40, 239, 101, 112, 47, 2, 80, 119, 11, 163, 93, 205, 89, 30, 136, 45, - 112, 44, 157, 216, 11, 39, 148, 121, 29, 189, 236, 115, 33, 204, 138, 68, 69, 217, 20, - 115, 169, 5, 14, 205, 72, 77, 54, 231, 218, 153, 95, 162, 175, 218, 232, 63, 190, 166, - 244, 88, 215, 208, 135, 139, 66, 119, 107, 105, 209, 86, 146, 86, 139, 2, 52, 60, 90, - 10, 156, 32, 31, 52, 138, 33, 75, 142, 77, 0, 167, 160, 116, 5, 177, 241, 191, 160, - 205, 157, 11, 224, 168, 248, 210, 225, 35, 28, 249, 169, 95, 21, 155, 125, 184, 161, - 209, 104, 28, 40, 157, 113, 186, 88, 83, 80, 52, 130, 162, 139, 20, 152, 253, 6, 236, - 251, 188, 248, 74, 3, 157, 144, 158, 44, 242, 203, 233, 164, 71, 98, 98, 68, 87, 50, - 103, 230, 182, 72, 240, 222, 223, 129, 196, 249, 204, 56, 77, 80, 64, 39, 35, 0, 32, - 49, 240, 229, 228, 251, 68, 176, 221, 45, 123, 205, 240, 137, 20, 168, 248, 87, 111, - 142, 170, 189, 190, 226, 99, 108, 192, 61, 135, 89, 138, 5, 100, 74, 55, 89, 173, 9, - 154, 231, 111, 119, 138, 82, 126, 3, 197, 143, 28, 74, 78, 198, 99, 129, 126, 84, 31, - 119, 224, 42, 247, 70, 75, 6, 249, 103, 53, 199, 171, 214, 151, 83, 116, 110, 0, 226, - 78, 69, 116, 76, 146, 140, 180, 251, 2, 154, 84, 34, 123, 74, 210, 202, 193, 129, 242, - 181, 142, 85, 140, 84, 138, 69, 121, 69, 23, 14, 219, 249, 133, 141, 242, 128, 253, 44, - 159, 125, 93, 13, 89, 70, 107, 195, 118, 133, 114, 4, 202, 76, 185, 171, 27, 107, 95, - 178, 68, 155, 72, 25, 53, 160, 89, 109, 77, 67, 112, 240, 99, 114, 26, 51, 240, 83, - 134, 72, 157, 118, 238, 0, 156, - ]; - - let serialized_proof = StoneCompatibleSerializer::serialize_proof::>( - &proof, - &pub_inputs, - &proof_options, - ); - assert_eq!(serialized_proof, expected_bytes); - } - - #[test] - fn test_serialization_compatible_with_stone_5() { - let trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::one(), 128); - - let claimed_index = 111; - let claimed_value = trace.get_row(claimed_index)[0]; - let proof_options = ProofOptions { - blowup_factor: 4, - coset_offset: 3, - grinding_factor: 0, - fri_number_of_queries: 3, - }; - - let pub_inputs = fibonacci_2_cols_shifted::PublicInputs { - claimed_value, - claimed_index, - }; - - let proof = Prover::>::prove( - &trace, - &pub_inputs, - &proof_options, - StoneProverTranscript::new(&pub_inputs.as_bytes()), - ) - .unwrap(); - - let expected_bytes = [ - 68, 228, 98, 183, 28, 139, 62, 73, 131, 192, 34, 97, 48, 52, 113, 8, 60, 34, 63, 155, - 94, 81, 98, 20, 135, 161, 25, 61, 234, 184, 129, 198, 144, 128, 202, 95, 113, 181, 23, - 21, 159, 52, 240, 15, 152, 224, 44, 222, 4, 55, 135, 79, 36, 227, 217, 2, 99, 161, 149, - 115, 30, 184, 45, 230, 4, 77, 37, 128, 110, 52, 56, 37, 193, 196, 32, 179, 243, 141, - 31, 42, 204, 120, 141, 60, 220, 222, 222, 215, 24, 213, 46, 45, 197, 81, 12, 217, 6, - 192, 96, 58, 36, 138, 6, 26, 193, 18, 57, 204, 116, 181, 43, 73, 201, 23, 56, 191, 204, - 196, 103, 248, 81, 175, 7, 191, 7, 96, 94, 249, 1, 121, 108, 49, 11, 225, 107, 207, - 252, 200, 206, 7, 175, 20, 138, 144, 147, 251, 124, 82, 97, 200, 54, 7, 85, 59, 200, - 14, 98, 254, 17, 4, 7, 75, 53, 15, 137, 76, 197, 75, 96, 177, 216, 83, 24, 248, 153, - 197, 35, 234, 125, 210, 179, 239, 38, 3, 147, 48, 3, 215, 224, 97, 158, 61, 3, 126, 7, - 213, 168, 94, 76, 45, 126, 222, 108, 126, 98, 94, 181, 180, 118, 69, 73, 214, 126, 171, - 171, 202, 3, 187, 25, 139, 137, 61, 168, 34, 228, 73, 162, 238, 201, 149, 8, 247, 182, - 167, 58, 131, 254, 110, 116, 66, 36, 194, 73, 58, 230, 242, 105, 34, 119, 228, 51, 251, - 56, 120, 109, 169, 9, 39, 243, 26, 57, 57, 60, 178, 75, 236, 199, 241, 184, 94, 150, - 101, 202, 22, 99, 11, 6, 137, 207, 124, 220, 239, 95, 42, 177, 251, 103, 130, 56, 45, - 74, 17, 203, 52, 106, 210, 111, 13, 90, 244, 147, 58, 194, 151, 31, 72, 196, 213, 43, - 197, 113, 132, 5, 75, 120, 170, 187, 23, 187, 216, 67, 113, 205, 179, 18, 20, 92, 32, - 204, 197, 25, 31, 253, 56, 204, 167, 77, 68, 218, 98, 186, 246, 237, 91, 67, 166, 157, - 87, 193, 17, 28, 208, 248, 9, 158, 213, 14, 232, 27, 170, 208, 10, 28, 87, 85, 107, 16, - 114, 130, 65, 211, 63, 185, 200, 32, 196, 50, 39, 234, 172, 62, 236, 108, 203, 61, 28, - 143, 60, 61, 88, 54, 20, 228, 26, 62, 158, 49, 35, 64, 201, 182, 76, 166, 91, 237, 106, - 66, 123, 144, 37, 119, 205, 156, 42, 142, 179, 6, 51, 80, 39, 144, 181, 147, 155, 195, - 147, 115, 126, 133, 228, 85, 152, 154, 188, 114, 10, 9, 215, 176, 133, 207, 112, 52, - 226, 238, 30, 74, 18, 1, 11, 196, 150, 186, 177, 35, 112, 40, 217, 137, 137, 207, 123, - 104, 13, 239, 231, 201, 87, 108, 76, 75, 73, 12, 103, 0, 43, 168, 13, 40, 42, 5, 186, - 109, 184, 112, 11, 56, 245, 168, 76, 222, 106, 188, 154, 219, 181, 69, 45, 158, 243, - 89, 144, 86, 144, 232, 148, 25, 39, 89, 247, 95, 181, 7, 164, 13, 119, 129, 40, 59, - 108, 21, 234, 12, 216, 35, 47, 214, 135, 136, 133, 146, 114, 106, 44, 87, 87, 239, 49, - 161, 206, 102, 25, 33, 63, 5, 107, 72, 49, 191, 149, 185, 133, 160, 79, 228, 98, 219, - 82, 69, 215, 230, 78, 145, 23, 161, 64, 200, 183, 50, 48, 71, 146, 173, 140, 39, 9, 7, - 123, 153, 177, 94, 211, 89, 72, 83, 58, 26, 218, 17, 85, 196, 107, 97, 207, 15, 248, - 122, 85, 194, 237, 25, 133, 54, 221, 54, 247, 35, 111, 0, 208, 142, 88, 50, 205, 210, - 163, 184, 46, 195, 83, 185, 188, 104, 102, 247, 40, 141, 20, 55, 29, 25, 120, 135, 51, - 69, 129, 224, 51, 150, 114, 3, 253, 93, 25, 49, 124, 36, 249, 212, 37, 126, 251, 218, - 93, 50, 228, 222, 233, 229, 72, 116, 109, 3, 212, 79, 53, 195, 179, 134, 49, 176, 25, - 3, 92, 61, 142, 129, 23, 152, 177, 153, 80, 223, 227, 47, 26, 39, 36, 22, 10, 96, 130, - 211, 103, 128, 244, 243, 171, 100, 175, 26, 197, 156, 241, 2, 186, 125, 100, 79, 57, - 119, 22, 36, 98, 178, 130, 49, 83, 132, 195, 21, 231, 138, 65, 235, 145, 236, 235, 73, - 175, 183, 200, 78, 52, 95, 7, 1, 154, 106, 98, 38, 34, 125, 79, 194, 182, 75, 26, 36, - 120, 239, 212, 90, 215, 225, 60, 57, 99, 159, 79, 145, 116, 235, 251, 142, 226, 56, - 197, 3, 208, 28, 167, 217, 109, 97, 164, 78, 9, 221, 139, 241, 209, 198, 38, 234, 171, - 166, 174, 244, 182, 228, 121, 71, 4, 219, 46, 146, 32, 153, 79, 0, 229, 11, 36, 224, - 61, 63, 63, 223, 95, 190, 126, 79, 27, 233, 156, 232, 147, 3, 96, 233, 120, 240, 197, - 168, 68, 173, 9, 87, 73, 150, 56, 230, 74, 62, 76, 205, 143, 234, 82, 186, 92, 209, - 154, 181, 231, 146, 150, 218, 233, 192, 114, 135, 240, 252, 59, 28, 169, 254, 204, 37, - 25, 50, 39, 199, 195, 40, 184, 197, 230, 68, 196, 171, 61, 133, 181, 140, 132, 116, - 169, 211, 164, 3, 5, 17, 37, 149, 79, 160, 145, 107, 194, 58, 130, 226, 93, 38, 247, - 17, 150, 146, 72, 188, 109, 75, 15, 170, 128, 97, 229, 188, 170, 188, 133, 103, 217, - 153, 41, 64, 154, 159, 87, 167, 80, 240, 89, 123, 16, 152, 42, 23, 235, 165, 232, 71, - 32, 101, 31, 18, 27, 79, 122, 243, 65, 83, 76, 90, 200, 108, 203, 252, 64, 53, 97, 230, - 117, 194, 55, 249, 168, 98, 203, 12, 179, 20, 223, 151, 185, 253, 89, 29, 232, 86, 1, - 26, 123, 245, 220, 240, 198, 90, 200, 187, 99, 80, 22, 100, 113, 163, 105, 109, 69, 87, - 49, 150, 68, 124, 149, 68, 102, 62, 17, 139, 36, 205, 201, 119, 12, 47, 172, 148, 107, - 234, 240, 95, 111, 193, 142, 215, 149, 216, 239, 133, 171, 180, 88, 68, 35, 128, 205, - 214, 29, 34, 123, 166, 211, 173, 22, 129, 23, 116, 30, 79, 148, 38, 183, 196, 205, 233, - 208, 166, 133, 158, 5, 61, 143, 89, 15, 119, 45, 160, 34, 100, 233, 242, 174, 246, 156, - 28, 68, 157, 216, 96, 95, 144, 145, 188, 251, 88, 211, 67, 245, 224, 233, 154, 145, 75, - 126, 207, 89, 206, 219, 207, 64, 79, 155, 172, 175, 211, 148, 237, 102, 130, 249, 13, - 40, 229, 74, 140, 198, 170, 0, 153, 157, 83, 183, 177, 41, 219, 229, 16, 233, 69, 95, - 239, 241, 93, 54, 219, 200, 204, 154, 81, 162, 234, 16, 164, 68, 147, 97, 213, 197, - 180, 198, 243, 58, 92, 161, 203, 230, 106, 191, 110, 167, 115, 124, 216, 61, 251, 9, - 16, 190, 50, 60, 230, 237, 2, 38, 27, 18, 85, 78, 225, 44, 251, 232, 48, 217, 96, 56, - 25, 230, 224, 118, 25, 253, 198, 21, 78, 22, 153, 101, 159, 239, 209, 40, 98, 44, 36, - 74, 251, 150, 171, 107, 83, 164, 200, 154, 113, 18, 162, 204, 179, 56, 170, 71, 253, - 206, 68, 63, 92, 114, 207, 64, 213, 160, 36, 169, 121, 170, 226, 126, 37, 64, 53, 62, - 16, 96, 187, 32, 14, 186, 29, 127, 178, 23, 199, 56, 133, 139, 164, 78, 79, 235, 158, - 131, 189, 178, 8, 75, 197, 139, 88, 250, 133, 155, 95, 212, 56, 135, 122, 194, 247, 94, - 49, 108, 65, 3, 182, 15, 43, 226, 153, 135, 142, 229, 178, 0, 93, 91, 116, 163, 228, - 145, 112, 112, 78, 109, 23, 206, 245, 65, 10, 19, 45, 118, 96, 91, 184, 162, 217, 74, - 135, 106, 233, 151, 97, 69, 106, 54, 22, 135, 48, 189, 165, 191, 9, 113, 238, 226, 16, - 154, 162, 141, 15, 81, 110, 33, 61, 253, 218, 230, 112, 35, 2, 64, 253, 59, 89, 128, - 85, 216, 157, 240, 241, 118, 248, 132, 182, 59, 137, 73, 171, 88, 152, 227, 205, 19, - 220, 85, 60, 122, 87, 94, 150, 221, 2, 135, 13, 66, 187, 49, 197, 41, 101, 243, 246, - 183, 197, 212, 15, 107, 193, 156, 220, 63, 123, 224, 16, 184, 134, 114, 73, 33, 26, 35, - 110, 152, 2, 222, 134, 92, 157, 96, 123, 189, 210, 214, 78, 114, 52, 51, 33, 49, 124, - 75, 224, 108, 130, 162, 20, 43, 193, 94, 229, 228, 174, 33, 162, 230, 2, 67, 193, 53, - 92, 25, 154, 95, 29, 158, 67, 35, 255, 194, 83, 170, 26, 76, 53, 98, 2, 138, 27, 103, - 6, 203, 183, 226, 48, 0, 22, 254, 0, 3, 94, 32, 155, 0, 191, 57, 203, 150, 21, 83, 133, - 242, 130, 244, 91, 10, 83, 5, 113, 44, 10, 248, 142, 20, 73, 10, 71, 240, 157, 161, 5, - 143, 247, 49, 252, 183, 33, 50, 137, 74, 197, 4, 42, 50, 113, 36, 206, 204, 213, 198, - 100, 197, 80, 206, 40, 224, 114, 159, 59, 145, 231, 176, 80, 20, 252, 161, 230, 26, - 114, 245, 38, 71, 150, 233, 168, 195, 228, 168, 78, 149, 0, 95, 55, 24, 159, 157, 76, - 227, 4, 185, 5, 192, 102, 240, 103, 40, 9, 69, 72, 236, 44, 181, 98, 29, 58, 121, 63, - 168, 190, 225, 27, 35, 59, 228, 230, 15, 227, 211, 90, 205, 108, 203, 228, 145, 219, - 212, 254, 92, 100, 220, 50, 57, 62, 36, 194, 133, 80, 11, 243, 190, 227, 83, 152, 168, - 50, 114, 146, 4, 134, 77, 236, 36, 235, 104, 113, 72, 140, 148, 53, 109, 109, 154, 203, - 128, 21, 253, 192, 18, 44, 220, 150, 63, 118, 67, 30, 7, 0, 81, 226, 168, 92, 185, 135, - 192, 152, 18, 213, 217, 120, 15, 145, 206, 194, 168, 56, 158, 189, 112, 143, 45, 11, - 197, 229, 69, 245, 105, 217, 9, 97, 177, 107, 59, 144, 247, 23, 132, 50, 129, 75, 134, - 125, 95, 78, 172, 175, 3, 193, 3, 247, 125, 11, 25, 125, 21, 198, 124, 108, 234, 120, - 52, 104, 64, 204, 147, 109, 117, 108, 45, 3, 29, 163, 208, 221, 199, 64, 162, 214, 72, - 56, 32, 221, 13, 220, 59, 239, 242, 232, 210, 113, 43, 75, 149, 170, 229, 221, 49, 161, - 253, 78, 106, 113, 65, 227, 169, 99, 72, 225, 65, 62, 57, 127, 53, 167, 25, 73, 164, 0, - 208, 84, 56, 86, 132, 13, 17, 83, 183, 27, 164, 26, 196, 193, 214, 195, 76, 176, 210, - 135, 88, 151, 69, 253, 24, 47, 146, 0, 120, 3, 211, 113, 128, 191, 227, 235, 105, 198, - 181, 240, 186, 255, 242, 196, 193, 216, 15, 192, 101, 165, 160, 19, 243, 52, 166, 254, - 137, 11, 156, 192, 63, 70, 91, 251, 0, 229, 197, 209, 129, 198, 232, 97, 49, 238, 248, - 141, 210, 9, 80, 14, 115, 251, 82, 235, 132, 209, 3, 123, 43, 25, 29, 59, 175, 204, - 127, 144, 241, 61, 137, 123, 6, 130, 155, 200, 55, 190, 33, 194, 50, 48, 238, 239, 132, - 118, 216, 63, 203, 178, 81, 227, 87, 184, 177, 147, 192, 254, 206, 134, 77, 2, 120, 58, - 180, 95, 159, 37, 207, 64, 121, 101, 134, 179, 165, 105, 154, 212, 50, 195, 23, 39, 66, - 190, 216, 32, 56, 224, 165, 191, 114, 84, 96, 155, 85, 71, 135, 46, 198, 47, 80, 151, - 176, 94, 211, 249, 48, 134, 114, 110, 131, 32, 21, 12, 162, 245, 7, 186, 30, 199, 218, - 204, 232, 115, 160, 85, 45, 0, 80, 227, 65, 212, 135, 143, 151, 84, 168, 237, 85, 38, - 141, 154, 216, 217, 241, 77, 141, 113, 207, 196, 132, 156, 240, 130, 249, 118, 251, 61, - 112, 4, 68, 121, 110, 140, 255, 49, 123, 233, 40, 222, 225, 213, 160, 81, 1, 236, 126, - 136, 42, 145, 123, 239, 96, 215, 233, 81, 172, 231, 11, 138, 194, 116, 4, 54, 43, 117, - 64, 159, 170, 166, 162, 143, 245, 175, 100, 116, 156, 227, 64, 0, 200, 44, 239, 120, - 98, 68, 96, 27, 218, 61, 5, 62, 159, 225, 248, 250, 172, 77, 61, 190, 158, 84, 143, 48, - 177, 68, 18, 225, 147, 106, 93, 5, 109, 237, 41, 154, 223, 225, 6, 45, 41, 48, 243, - 184, 129, 161, 224, 67, 2, 34, 71, 61, 36, 96, 139, 217, 194, 107, 15, 224, 21, 144, - 191, 0, 194, 170, 179, 77, 194, 164, 32, 255, 81, 252, 211, 137, 45, 90, 238, 151, 229, - 25, 31, 24, 176, 150, 252, 202, 14, 176, 159, 232, 199, 115, 147, 184, 236, 254, 115, - 18, 10, 113, 29, 15, 120, 125, 204, 34, 25, 14, 33, 103, 7, 118, 8, 120, 95, 3, 225, - 123, 82, 87, 41, 136, 152, 150, 185, 1, 1, 192, 119, 80, 225, 235, 11, 171, 28, 189, - 62, 157, 244, 240, 117, 104, 154, 69, 114, 58, 152, 188, 62, 185, 174, 151, 204, 194, - 160, 36, 146, 90, 3, 181, 253, 91, 180, 196, 210, 102, 20, 237, 201, 45, 116, 22, 178, - 36, 161, 133, 84, 39, 220, 181, 133, 235, 72, 128, 198, 186, 55, 160, 81, 36, 98, 140, - 128, 131, 140, 199, 201, 142, 171, 106, 33, 210, 198, 66, 164, 9, 161, 46, 232, 216, - 239, 244, 66, 88, 166, 111, 82, 201, 46, 53, 194, 117, 244, 34, 89, 156, 148, 180, 84, - 49, 176, 38, 193, 5, 25, 132, 91, 210, 101, 13, 205, 228, 222, 84, 81, 160, 94, 34, - 136, 192, 223, 119, 224, 16, 1, 74, 62, 42, 177, 100, 202, 183, 170, 108, 146, 201, 99, - 175, 196, 55, 189, 170, 110, 233, 86, 223, 233, 249, 165, 68, 178, 26, 87, 49, 19, 212, - 152, 40, 114, 175, 166, 145, 133, 202, 93, 153, 57, 19, 229, 216, 148, 234, 15, 46, - 167, 5, 95, 51, 144, 242, 159, 28, 236, 158, 12, 206, 109, 165, 35, 105, 158, 238, 207, - 197, 179, 150, 119, 151, 199, 21, 36, 101, 188, 116, 106, 240, 101, 159, 154, 194, 240, - 39, 128, 152, 160, 178, 251, 56, 249, 195, 50, 113, 227, 202, 175, 5, 9, 249, 117, 148, - 203, 104, 14, 169, 174, 197, 121, 245, 81, 140, 16, 129, 47, 255, 7, 125, 169, 239, - 111, 235, 138, 243, 52, 63, 230, 187, 163, 234, 134, 184, 36, 136, 24, 181, 226, 243, - 153, 8, 61, 242, 126, 123, 64, 245, 196, 11, 189, 149, 238, 56, 228, 248, 87, 19, 215, - 198, 29, 145, 155, 118, 246, 120, 198, 170, 107, 1, 174, 81, 237, 113, 79, 100, 102, - 237, 28, 10, 198, 210, 178, 250, 8, 138, 64, 184, 187, 13, 171, 107, 236, 127, 198, 41, - 240, 158, 96, 243, 229, 191, 251, 102, 191, 202, 186, 90, 255, 54, 15, 172, 46, 135, - 247, 116, 238, 184, 227, 57, 252, 227, 149, 219, 69, 92, 24, 245, 83, 49, 250, 130, - 212, 115, 8, 166, 14, 145, 240, 119, 40, 147, 9, 247, 235, 232, 159, 65, 72, 204, 131, - 132, 94, 6, 155, 127, 65, 84, 141, 54, 213, 93, 217, 118, 100, 175, 20, 55, 38, 12, 63, - 109, 69, 113, 169, 95, 29, 227, 137, 105, 100, 255, 166, 229, 216, 1, 148, 154, 105, - 227, 201, 229, 195, 134, 12, 251, 164, 76, 103, 227, 205, 19, 188, 141, 66, 24, 241, - 59, 49, 178, 95, 11, 154, 240, 182, 83, 33, 7, 62, 98, 233, 175, 150, 136, 1, 137, 152, - 28, 83, 237, 100, 236, 147, 131, 196, 119, 219, 143, 113, 0, 18, 232, 195, 92, 90, 191, - 243, 64, 181, 240, 217, 13, 101, 72, 197, 237, 199, 138, 60, 21, 70, 144, 86, 178, 175, - 145, 95, 76, 174, 43, 188, 233, 139, 161, 203, 91, 235, 178, 182, 225, 155, 23, 219, - 42, 119, 143, 246, 211, 154, 55, 126, 69, 61, 8, 40, 189, 190, 92, 130, 85, 54, 143, - 231, 191, 19, 243, 31, 192, 242, 150, 131, 195, 130, 111, 181, 32, 147, 190, 138, 172, - 146, 222, 208, 74, 95, 209, 122, 185, 72, 1, 96, 71, 34, 116, 182, 82, 35, 126, 133, - 51, 101, 17, 2, 83, 15, 149, 98, 49, 47, 172, 137, 223, 248, 89, 82, 186, 152, 89, 4, - 60, 74, 7, 181, 205, 181, 14, 92, 40, 203, 101, 155, 35, 206, 112, 144, 102, 184, 219, - 16, 87, 237, 188, 68, 169, 90, 189, 61, 201, 209, 192, 99, 154, 134, 56, 19, 102, 107, - 25, 241, 237, 174, 105, 136, 199, 55, 111, 225, 58, 152, 112, 159, 125, 111, 81, 237, - 21, 39, 54, 253, 120, 189, 220, 164, 138, 135, 25, 61, 182, 242, 116, 100, 159, 41, 27, - 144, 78, 104, 71, 129, 64, 142, 5, 63, 97, 239, 225, 163, 229, 9, 143, 156, 101, 201, - 237, 57, 80, 103, 1, 36, 135, 63, 61, 247, 89, 202, 132, 140, 177, 178, 98, 7, 151, 10, - 240, 59, 152, 109, 124, 11, 28, 218, 94, 131, 163, 101, 71, 187, 17, 162, 35, 22, 22, - 9, 237, 30, 120, 118, 15, 50, 179, 52, 50, 5, 183, 194, 137, 254, 74, 80, 158, 238, - 236, 186, 186, 121, 197, 231, 114, 183, 27, 6, 238, 104, 30, 254, 130, 247, 149, 224, - 129, 200, 162, 49, 206, 20, 197, 45, 206, 179, 118, 169, 128, 184, 157, 85, 212, 198, - 192, 22, 208, 130, 116, 99, 218, 56, 14, 249, 204, 234, 50, 74, 12, 7, 155, 116, 192, - 213, 201, 115, 2, 22, 203, 145, 45, 140, 35, 17, 156, 209, 62, 73, 171, 132, 196, 84, - 231, 146, 76, 123, 253, 109, 178, 117, 99, 52, 6, 221, 115, 207, 36, 232, 3, 46, 133, - 43, 190, 220, 39, 242, 179, 120, 205, 120, 221, 101, 249, 43, 226, 131, 59, 159, 214, - 202, 202, 90, 133, 51, 135, 141, 179, 123, 114, 167, 4, 65, 149, 218, 30, 196, 221, 44, - 249, 170, 179, 73, 171, 89, 59, 177, 194, 95, 94, 61, 62, 44, 172, 172, 94, 228, 92, - 17, 68, 16, 157, 1, 119, 137, 91, 67, 52, 14, 235, 57, 92, 102, 224, 208, 182, 222, 43, - 196, 69, 33, 14, 184, 75, 54, 5, 59, 127, 69, 156, 222, 116, 185, 224, 106, 233, 94, - 189, 183, 90, 204, 198, 142, 51, 129, 134, 251, 108, 187, 61, 78, 135, 102, 59, 165, - 49, 38, 102, 97, 38, 102, 160, 229, 238, 170, 20, 24, 214, 83, 0, 202, 171, 190, 74, - 55, 243, 17, 36, 116, 241, 94, 26, 17, 55, 245, 71, 104, 130, 141, 251, 1, 47, 77, 74, - 17, 113, 48, 43, 204, 233, 157, 153, 136, 42, 132, 58, 173, 224, 23, 245, 9, 220, 224, - 49, 142, 179, 49, 0, 135, 25, 109, 220, 226, 252, 51, 213, 235, 150, 101, 30, 63, 128, - 82, 112, 187, 90, 64, 81, 30, 32, 116, 75, 233, 128, 79, 246, 155, 95, 193, 172, 93, - 193, 84, 146, 143, 172, 21, 172, 6, 41, 41, 213, 50, 26, 178, 196, 126, 186, 74, 45, - 141, 211, 182, 92, 154, 186, 207, 99, 221, 21, 177, 107, 199, 7, 98, 231, 144, 252, - 120, 113, 217, 138, 23, 234, 162, 127, 180, 130, 126, 159, 1, 17, 50, 36, 249, 181, - 123, 236, 110, 59, 26, 38, 212, 137, 58, 2, 73, 224, 135, 178, 0, 31, 157, 255, 68, 49, - 205, 4, 109, 154, 29, 232, 129, 92, 67, 158, 161, 213, 129, 113, 53, 231, 159, 234, - 114, 104, 17, 79, 89, 214, 106, 55, 150, 252, 35, 39, 78, 186, 59, 6, 12, 215, 97, 45, - 88, 146, 80, 229, 50, 153, 202, 83, 158, 58, 247, 124, 78, 52, 194, 26, 198, 250, 14, - 192, 162, 161, 25, 146, 190, 171, 241, 7, 94, 203, 139, 69, 222, 13, 1, 57, 86, 64, 84, - 159, 226, 195, 239, 40, 26, 4, 120, 56, 127, 123, 209, 35, 127, 95, 157, 15, 155, 6, - 143, 124, 37, 211, 186, 113, 213, 29, 101, 209, 238, 20, 207, 127, 45, 90, 245, 44, - 220, 94, 224, 57, 204, 96, 83, 1, 90, 132, 111, 221, 5, 210, 186, 230, 39, 151, 46, 57, - 31, 96, 218, 59, 115, 108, 29, 78, 23, 55, 231, 88, 142, 61, 147, 44, 57, 9, 112, 84, - 55, 136, 254, 87, 83, 214, 23, 173, 31, 156, 202, 26, 193, 84, 130, 158, 88, 208, 209, - 118, 231, 92, 160, 51, 32, 210, 125, 5, 114, 230, 119, 152, 165, 153, 98, 76, 145, 143, - 78, 35, 201, 207, 251, 9, 44, 167, 198, 112, 22, 54, 224, 178, 216, 201, 248, 217, 139, - 103, 86, 83, 220, 71, 244, 164, 126, 22, 91, 122, 154, 205, 30, 4, 76, 248, 75, 200, - 191, 201, 95, 209, 20, 107, 13, 70, 88, 212, 15, 33, 160, 178, 202, 221, 23, 159, 1, - 115, 152, 141, 54, 105, 37, 188, 106, 216, 119, 188, 233, 128, 226, 25, 12, 101, 193, - 171, 81, 34, 156, 229, 241, 99, 243, 146, 33, 89, 193, 48, 48, 134, 213, 134, 232, 209, - 177, 91, 29, 82, 242, 106, 241, 216, 132, 39, 20, 166, 59, 199, 184, 187, 139, 174, 40, - 171, 149, 158, 160, 163, 255, 210, 111, 24, 201, 96, 54, 190, 244, 214, 85, 200, 239, - 61, 99, 124, 239, 244, 170, 247, 153, 202, 47, 20, 136, 236, 17, 58, 164, 17, 196, 171, - 171, 7, 235, 126, 171, 148, 60, 19, 1, 205, 202, 6, 230, 164, 222, 254, 83, 237, 80, - 32, 177, 77, 12, 67, 106, 39, 48, 156, 107, 178, 36, 72, 125, 131, 179, 165, 124, 40, - 139, 172, 178, 1, 170, 7, 247, 141, 97, 68, 98, 180, 164, 54, 120, 128, 134, 192, 248, - 3, 197, 136, 207, 82, 119, 185, 10, 106, 216, 84, 173, 87, 176, 0, 21, 151, 48, 220, - 196, 109, 236, 149, 52, 82, 251, 14, 201, 97, 226, 75, 177, 52, 16, 249, 36, 158, 103, - 210, 33, 191, 114, 98, 40, 235, 19, 219, 101, 88, 189, - ]; - - let serialized_proof = StoneCompatibleSerializer::serialize_proof::>( - &proof, - &pub_inputs, - &proof_options, - ); - assert_eq!(serialized_proof, expected_bytes); - } -} +// #[cfg(test)] +// mod tests { +// use lambdaworks_math::{field::element::FieldElement, traits::AsBytes}; + +// use crate::{ +// examples::fibonacci_2_cols_shifted::{self, Fibonacci2ColsShifted}, +// proof::{options::ProofOptions, stark::StoneCompatibleSerializer}, +// prover::{IsStarkProver, Prover}, +// transcript::StoneProverTranscript, +// }; + +// #[test] +// fn test_serialization_compatible_with_stone_1() { +// let mut trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::one(), 4); + +// let claimed_index = 3; +// let claimed_value = trace.get_row(claimed_index)[0]; +// let proof_options = ProofOptions { +// blowup_factor: 4, +// coset_offset: 3, +// grinding_factor: 0, +// fri_number_of_queries: 1, +// }; + +// let pub_inputs = fibonacci_2_cols_shifted::PublicInputs { +// claimed_value, +// claimed_index, +// }; + +// let proof = Prover::>::prove( +// &mut trace, +// &pub_inputs, +// &proof_options, +// StoneProverTranscript::new(&pub_inputs.as_bytes()), +// ) +// .unwrap(); + +// let expected_bytes = [ +// 14, 185, 220, 192, 251, 24, 84, 87, 42, 1, 35, 103, 83, 206, 5, 19, 157, 57, 42, 163, +// 174, 175, 231, 42, 191, 241, 80, 254, 33, 23, 85, 148, 240, 15, 97, 4, 33, 250, 73, 57, +// 153, 20, 91, 112, 71, 103, 155, 245, 134, 85, 150, 224, 103, 5, 176, 183, 152, 52, 190, +// 56, 94, 184, 211, 203, 1, 10, 170, 210, 58, 15, 137, 139, 84, 215, 101, 26, 236, 253, +// 138, 16, 34, 94, 85, 246, 117, 36, 122, 25, 65, 56, 39, 64, 182, 60, 92, 149, 0, 61, +// 238, 22, 79, 89, 52, 136, 161, 125, 245, 232, 111, 27, 91, 235, 0, 112, 73, 52, 122, +// 171, 178, 11, 249, 92, 149, 195, 95, 127, 77, 90, 0, 63, 48, 208, 46, 245, 248, 39, +// 173, 179, 161, 21, 59, 173, 210, 38, 117, 61, 159, 103, 129, 41, 200, 180, 127, 152, +// 136, 37, 52, 131, 168, 143, 7, 71, 166, 221, 33, 179, 43, 105, 109, 45, 26, 161, 194, +// 171, 13, 78, 139, 52, 158, 132, 170, 241, 155, 38, 213, 231, 199, 58, 181, 248, 101, +// 136, 5, 201, 25, 47, 164, 4, 56, 196, 188, 130, 134, 39, 128, 65, 210, 9, 124, 10, 82, +// 253, 146, 34, 57, 37, 92, 71, 2, 44, 3, 248, 124, 227, 206, 179, 238, 69, 200, 177, 31, +// 7, 171, 247, 48, 97, 185, 116, 237, 171, 117, 251, 207, 4, 66, 112, 144, 10, 255, 60, +// 207, 185, 25, 7, 110, 159, 3, 120, 156, 213, 179, 46, 1, 189, 58, 131, 21, 190, 194, +// 176, 219, 255, 172, 68, 21, 117, 44, 122, 177, 139, 62, 111, 251, 21, 15, 81, 246, 120, +// 6, 115, 221, 244, 77, 82, 191, 9, 150, 178, 205, 168, 196, 218, 39, 107, 231, 32, 56, +// 92, 78, 19, 151, 21, 18, 123, 158, 163, 7, 245, 10, 237, 4, 231, 187, 232, 154, 165, +// 106, 226, 45, 101, 155, 81, 137, 180, 78, 215, 206, 64, 112, 184, 156, 39, 46, 42, 36, +// 247, 61, 70, 15, 234, 20, 185, 1, 140, 34, 11, 178, 173, 48, 7, 105, 77, 50, 87, 59, +// 37, 216, 148, 24, 223, 199, 163, 177, 236, 104, 234, 237, 132, 97, 92, 248, 10, 244, +// 20, 3, 24, 68, 23, 101, 90, 108, 206, 210, 154, 100, 174, 118, 75, 177, 40, 49, 191, +// 143, 71, 99, 216, 209, 213, 219, 8, 194, 185, 240, 21, 232, 232, 145, 176, 192, 178, +// 75, 157, 0, 6, 123, 14, 250, 181, 8, 50, 183, 108, 249, 113, 146, 9, 22, 36, 212, 43, +// 134, 116, 6, 102, 197, 211, 105, 230, 153, 59, 4, 77, 178, 36, 68, 192, 192, 235, 241, +// 9, 91, 154, 81, 250, 235, 0, 28, 155, 77, 234, 54, 171, 233, 5, 247, 22, 38, 32, 219, +// 189, 80, 23, 171, 236, 163, 63, 168, 37, 118, 181, 197, 194, 198, 23, 146, 105, 59, 72, +// 201, 212, 65, 74, 64, 126, 239, 102, 182, 2, 157, 174, 7, 234, 6, 40, 218, 216, 248, +// 96, 149, 112, 209, 255, 173, 185, 81, 55, 105, 97, 6, 239, 20, 189, 183, 213, 184, 147, +// 226, 210, 8, 224, 248, 198, 11, 186, 7, 179, 148, 95, 226, 129, 234, 27, 46, 85, 20, +// 182, 118, 241, 2, 69, 184, 39, 231, 81, 9, 28, 60, 114, 120, 53, 252, 192, 115, 40, +// 213, 33, 160, 213, 41, 195, 61, 131, 42, 105, 77, 188, 109, 118, 53, 70, 24, 141, 94, +// 101, 222, 67, 254, 29, 157, 8, 184, 145, 194, 89, 189, 95, 253, 181, 90, 70, 207, 28, +// 53, 40, 246, 178, 129, 178, 83, 109, 24, 202, 136, 140, 211, 4, 167, 36, 253, 29, 66, +// 79, 250, 184, 63, 158, 162, 206, 83, 135, 251, 125, 215, 121, 149, 118, 82, 112, 53, +// 242, 58, 127, 196, 123, 63, 110, 192, 137, 125, 95, 72, 122, 82, 8, 121, 113, 241, 76, +// 255, 36, 96, 225, 5, 158, 234, 196, 65, 220, 82, 70, 244, 90, 62, 85, 201, 169, 9, 104, +// 29, 215, 76, 179, 28, 235, 123, 86, 98, 25, 254, 123, 7, 55, 26, 190, 66, 97, 62, 111, +// 150, 110, 27, 233, 81, 131, 192, 21, 72, 16, 130, 46, 43, 43, 213, 145, 96, 22, 224, +// 211, 5, 253, 114, 94, 164, 190, 87, 143, 69, 128, 1, 253, 103, 213, 139, 7, 35, 132, +// 52, 242, 55, 248, 72, 214, 102, 108, 57, 205, 46, 20, 1, 83, 198, 32, 167, 96, 242, +// 117, 87, 201, +// ]; + +// let serialized_proof = StoneCompatibleSerializer::serialize_proof::>( +// &proof, +// &pub_inputs, +// &proof_options, +// ); +// assert_eq!(serialized_proof, expected_bytes); +// } + +// #[test] +// fn test_serialization_compatible_with_stone_case_2() { +// let mut trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::one(), 4); + +// let claimed_index = 2; +// let claimed_value = trace.get_row(claimed_index)[0]; +// let proof_options = ProofOptions { +// blowup_factor: 2, +// coset_offset: 3, +// grinding_factor: 0, +// fri_number_of_queries: 10, +// }; + +// let pub_inputs = fibonacci_2_cols_shifted::PublicInputs { +// claimed_value, +// claimed_index, +// }; + +// let proof = Prover::>::prove( +// &mut trace, +// &pub_inputs, +// &proof_options, +// StoneProverTranscript::new(&pub_inputs.as_bytes()), +// ) +// .unwrap(); +// let expected_bytes = [ +// 9, 161, 59, 243, 85, 60, 44, 155, 163, 203, 128, 147, 203, 253, 93, 16, 137, 42, 94, +// 225, 173, 254, 120, 1, 43, 167, 254, 15, 49, 148, 2, 50, 47, 159, 254, 83, 209, 26, 91, +// 113, 237, 157, 107, 252, 35, 130, 117, 22, 155, 181, 217, 11, 145, 208, 53, 201, 14, +// 148, 19, 247, 19, 105, 239, 108, 2, 17, 212, 103, 137, 76, 186, 20, 31, 118, 21, 139, +// 122, 39, 100, 197, 112, 11, 188, 227, 236, 15, 127, 186, 231, 187, 158, 137, 41, 180, +// 233, 36, 3, 145, 50, 37, 100, 198, 0, 152, 68, 30, 64, 111, 78, 211, 119, 49, 142, 180, +// 178, 74, 59, 150, 209, 45, 211, 159, 6, 216, 205, 161, 255, 142, 0, 104, 163, 169, 38, +// 160, 79, 95, 195, 96, 46, 20, 45, 189, 161, 181, 95, 133, 26, 124, 224, 44, 153, 119, +// 121, 29, 187, 126, 125, 161, 4, 45, 2, 1, 113, 106, 28, 174, 255, 138, 4, 34, 227, 191, +// 33, 203, 60, 20, 34, 36, 33, 8, 44, 53, 250, 177, 127, 59, 157, 229, 179, 87, 165, 58, +// 0, 0, 83, 98, 7, 41, 90, 187, 198, 80, 159, 250, 57, 252, 211, 64, 233, 110, 223, 155, +// 56, 189, 215, 57, 80, 161, 169, 246, 65, 133, 129, 132, 129, 233, 154, 204, 187, 178, +// 244, 76, 12, 9, 30, 113, 105, 206, 46, 192, 68, 96, 27, 72, 94, 126, 101, 253, 63, 94, +// 10, 89, 116, 120, 31, 123, 5, 224, 161, 148, 232, 99, 202, 108, 45, 218, 145, 93, 103, +// 64, 177, 105, 163, 115, 34, 11, 250, 31, 46, 213, 139, 205, 219, 194, 199, 175, 220, +// 79, 3, 24, 68, 23, 101, 90, 193, 206, 210, 154, 100, 174, 118, 75, 177, 40, 49, 191, +// 143, 71, 99, 216, 209, 213, 219, 8, 194, 185, 240, 21, 237, 232, 4, 164, 102, 35, 24, +// 8, 49, 150, 59, 231, 151, 5, 177, 113, 137, 188, 74, 159, 86, 235, 21, 197, 58, 192, +// 200, 141, 36, 22, 232, 32, 229, 188, 4, 231, 187, 232, 154, 165, 64, 98, 45, 101, 155, +// 81, 137, 180, 78, 215, 206, 64, 112, 184, 156, 39, 46, 42, 36, 247, 61, 70, 15, 234, +// 18, 57, 3, 91, 153, 220, 231, 247, 223, 122, 196, 24, 104, 250, 78, 142, 118, 67, 181, +// 96, 169, 20, 234, 58, 197, 63, 55, 114, 219, 233, 23, 223, 27, 69, 6, 115, 221, 244, +// 77, 82, 191, 9, 150, 178, 205, 168, 196, 218, 39, 107, 231, 32, 56, 92, 78, 19, 151, +// 21, 18, 123, 158, 163, 7, 245, 10, 237, 4, 231, 187, 232, 154, 165, 106, 226, 45, 101, +// 155, 81, 137, 180, 78, 215, 206, 64, 112, 184, 156, 39, 46, 42, 36, 247, 61, 70, 15, +// 234, 20, 185, 1, 140, 34, 11, 178, 173, 48, 7, 105, 77, 50, 87, 59, 37, 216, 148, 24, +// 223, 199, 163, 177, 236, 104, 234, 237, 132, 97, 92, 248, 10, 244, 20, 3, 24, 68, 23, +// 101, 90, 108, 206, 210, 154, 100, 174, 118, 75, 177, 40, 49, 191, 143, 71, 99, 216, +// 209, 213, 219, 8, 194, 185, 240, 21, 232, 232, 7, 51, 41, 162, 227, 93, 103, 1, 119, +// 157, 40, 0, 161, 176, 143, 13, 53, 64, 172, 166, 74, 71, 4, 177, 30, 109, 56, 217, 15, +// 172, 148, 119, 0, 1, 40, 225, 211, 37, 67, 227, 195, 75, 15, 184, 75, 35, 121, 152, 11, +// 206, 130, 181, 93, 52, 26, 222, 54, 225, 164, 206, 119, 98, 49, 127, 1, 245, 239, 229, +// 226, 164, 147, 237, 23, 92, 189, 192, 202, 171, 211, 97, 221, 103, 41, 20, 123, 42, 73, +// 255, 19, 182, 16, 44, 170, 91, 163, 241, 3, 122, 35, 184, 126, 224, 183, 84, 233, 162, +// 161, 139, 249, 241, 173, 181, 44, 40, 254, 122, 243, 31, 209, 50, 95, 136, 54, 66, 182, +// 182, 120, 86, 1, 200, 25, 46, 236, 199, 14, 120, 215, 166, 119, 142, 184, 187, 93, 210, +// 70, 99, 209, 109, 106, 7, 38, 13, 86, 113, 77, 40, 239, 101, 112, 47, 2, 80, 119, 11, +// 163, 93, 205, 89, 30, 136, 45, 112, 44, 157, 216, 11, 39, 148, 121, 29, 189, 236, 115, +// 33, 204, 138, 68, 69, 217, 20, 115, 169, 5, 14, 205, 72, 77, 54, 231, 218, 153, 95, +// 162, 175, 218, 232, 63, 190, 166, 244, 88, 215, 208, 135, 139, 66, 119, 107, 105, 209, +// 86, 146, 86, 139, 2, 52, 60, 90, 10, 156, 32, 31, 52, 138, 33, 75, 142, 77, 0, 167, +// 160, 116, 5, 177, 241, 191, 160, 205, 157, 11, 224, 168, 248, 210, 225, 35, 1, 8, 125, +// 71, 71, 5, 38, 16, 199, 27, 91, 50, 8, 54, 219, 166, 194, 250, 10, 202, 190, 145, 195, +// 160, 218, 188, 29, 73, 184, 247, 42, 44, 3, 221, 45, 93, 101, 219, 38, 37, 3, 232, 2, +// 98, 27, 149, 66, 245, 31, 23, 114, 149, 174, 202, 119, 96, 233, 114, 114, 46, 147, 166, +// 89, 244, 1, 166, 156, 186, 246, 241, 109, 41, 76, 181, 248, 23, 253, 193, 236, 87, 42, +// 52, 162, 91, 167, 141, 227, 164, 162, 247, 95, 64, 90, 59, 117, 210, 1, 143, 44, 156, +// 144, 94, 237, 240, 120, 79, 31, 189, 37, 133, 249, 195, 95, 23, 87, 168, 26, 6, 60, +// 175, 235, 164, 121, 7, 220, 167, 78, 247, 3, 157, 144, 158, 44, 242, 203, 233, 164, 71, +// 98, 98, 68, 87, 50, 103, 230, 182, 72, 240, 222, 223, 129, 196, 249, 204, 56, 77, 80, +// 64, 39, 35, 0, 32, 49, 240, 229, 228, 251, 68, 176, 221, 45, 123, 205, 240, 137, 20, +// 168, 248, 87, 111, 142, 170, 189, 190, 226, 99, 108, 192, 61, 135, 89, 138, 5, 100, 74, +// 55, 89, 173, 9, 154, 231, 111, 119, 138, 82, 126, 3, 197, 143, 28, 74, 78, 198, 99, +// 129, 126, 84, 31, 119, 224, 42, 247, 70, 75, 6, 249, 103, 53, 199, 171, 214, 151, 83, +// 116, 110, 0, 226, 78, 69, 116, 76, 146, 140, 180, 251, 2, 154, 84, 34, 123, 74, 210, +// 202, 193, 129, 242, +// ]; + +// let serialized_proof = StoneCompatibleSerializer::serialize_proof::>( +// &proof, +// &pub_inputs, +// &proof_options, +// ); +// assert_eq!(serialized_proof, expected_bytes); +// } + +// #[test] +// fn test_serialization_compatible_with_stone_case_3() { +// let mut trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::from(12345), 512); + +// let claimed_index = 420; +// let claimed_value = trace.get_row(claimed_index)[0]; +// let proof_options = ProofOptions { +// blowup_factor: 64, +// coset_offset: 3, +// grinding_factor: 0, +// fri_number_of_queries: 1, +// }; + +// let pub_inputs = fibonacci_2_cols_shifted::PublicInputs { +// claimed_value, +// claimed_index, +// }; + +// let proof = Prover::>::prove( +// &mut trace, +// &pub_inputs, +// &proof_options, +// StoneProverTranscript::new(&pub_inputs.as_bytes()), +// ) +// .unwrap(); + +// let expected_bytes = [ +// 109, 49, 221, 0, 3, 137, 116, 189, 229, 254, 12, 94, 58, 118, 95, 141, 220, 130, 42, +// 93, 243, 37, 79, 202, 133, 161, 149, 10, 224, 32, 140, 190, 239, 19, 119, 217, 232, 38, +// 44, 103, 224, 84, 37, 164, 175, 0, 176, 5, 228, 209, 131, 135, 35, 160, 245, 180, 101, +// 20, 17, 193, 139, 244, 214, 182, 4, 75, 226, 131, 251, 225, 219, 95, 239, 73, 57, 144, +// 157, 77, 141, 185, 96, 12, 72, 162, 220, 59, 28, 165, 125, 180, 59, 196, 125, 175, 147, +// 35, 3, 166, 113, 39, 138, 98, 152, 242, 130, 179, 98, 207, 75, 213, 4, 166, 18, 174, +// 48, 180, 163, 178, 171, 151, 243, 160, 172, 30, 19, 10, 81, 246, 7, 162, 17, 184, 194, +// 192, 238, 157, 46, 254, 115, 59, 129, 110, 64, 254, 132, 223, 32, 210, 127, 58, 127, +// 190, 163, 99, 231, 54, 160, 7, 227, 245, 1, 28, 36, 75, 6, 234, 197, 16, 123, 234, 123, +// 154, 110, 86, 44, 23, 105, 219, 66, 35, 196, 86, 208, 208, 157, 109, 255, 213, 31, 138, +// 123, 204, 0, 132, 81, 145, 33, 88, 101, 30, 95, 38, 58, 112, 158, 89, 220, 144, 206, +// 77, 119, 14, 188, 69, 181, 70, 203, 71, 219, 116, 215, 142, 82, 164, 61, 94, 225, 126, +// 73, 242, 43, 24, 127, 130, 247, 244, 127, 165, 142, 63, 223, 61, 62, 47, 58, 50, 239, +// 208, 158, 217, 33, 145, 153, 52, 14, 146, 60, 152, 42, 0, 41, 233, 231, 56, 238, 53, +// 148, 74, 50, 241, 205, 55, 228, 202, 41, 162, 225, 98, 181, 163, 113, 121, 186, 191, +// 251, 237, 32, 214, 95, 103, 181, 76, 217, 46, 234, 0, 133, 191, 106, 153, 5, 56, 85, +// 104, 188, 40, 43, 58, 21, 49, 220, 52, 59, 55, 57, 161, 205, 139, 63, 152, 192, 83, +// 136, 28, 1, 55, 103, 147, 6, 199, 241, 92, 63, 22, 56, 220, 43, 42, 4, 48, 68, 250, 77, +// 111, 227, 149, 14, 210, 133, 198, 182, 114, 56, 21, 64, 202, 15, 57, 86, 25, 159, 1, +// 35, 149, 231, 230, 219, 194, 124, 165, 228, 46, 208, 208, 164, 239, 100, 33, 111, 18, +// 227, 115, 181, 168, 180, 24, 131, 150, 226, 64, 87, 166, 222, 137, 57, 189, 96, 66, 46, +// 148, 142, 4, 142, 243, 124, 107, 115, 149, 111, 232, 87, 214, 39, 169, 76, 71, 189, 27, +// 56, 42, 148, 156, 18, 98, 128, 83, 135, 142, 177, 240, 195, 181, 221, 74, 3, 246, 155, +// 238, 56, 177, 216, 10, 65, 176, 176, 212, 50, 153, 84, 128, 133, 72, 64, 210, 71, 10, +// 48, 15, 164, 237, 45, 117, 5, 187, 184, 110, 119, 11, 176, 88, 244, 33, 128, 177, 152, +// 84, 180, 245, 96, 179, 0, 229, 209, 249, 139, 216, 125, 21, 8, 97, 40, 101, 126, 12, +// 86, 7, 58, 198, 234, 37, 156, 164, 28, 147, 117, 228, 144, 110, 220, 76, 177, 162, 6, +// 197, 149, 26, 240, 74, 208, 137, 170, 135, 203, 150, 205, 215, 51, 209, 52, 226, 185, +// 209, 170, 24, 64, 229, 90, 4, 210, 205, 115, 74, 164, 106, 7, 92, 83, 16, 123, 27, 14, +// 166, 87, 98, 205, 51, 110, 212, 153, 51, 231, 14, 51, 252, 2, 143, 196, 251, 26, 139, +// 172, 22, 53, 159, 102, 132, 0, 72, 76, 107, 117, 128, 25, 180, 198, 189, 189, 5, 45, +// 174, 88, 212, 140, 156, 71, 133, 166, 85, 44, 208, 109, 241, 218, 237, 126, 135, 159, +// 245, 4, 252, 211, 29, 148, 213, 86, 146, 213, 64, 168, 202, 144, 142, 118, 62, 66, 222, +// 252, 200, 165, 10, 226, 2, 159, 80, 239, 120, 74, 233, 33, 183, 135, 240, 9, 224, 18, +// 8, 242, 173, 64, 189, 254, 101, 25, 116, 224, 85, 71, 75, 28, 107, 156, 197, 233, 58, +// 215, 153, 14, 110, 80, 2, 254, 31, 10, 152, 9, 182, 44, 18, 128, 22, 64, 20, 175, 135, +// 117, 227, 111, 88, 148, 211, 188, 21, 233, 222, 56, 64, 219, 219, 57, 0, 242, 47, 240, +// 142, 172, 143, 46, 26, 205, 28, 28, 204, 175, 7, 16, 55, 157, 18, 59, 85, 96, 12, 161, +// 195, 113, 218, 83, 47, 191, 147, 91, 134, 244, 105, 179, 250, 211, 242, 252, 220, 59, +// 165, 146, 120, 202, 78, 196, 59, 169, 9, 10, 215, 21, 233, 236, 62, 126, 42, 108, 101, +// 150, 41, 198, 240, 102, 175, 43, 7, 117, 175, 8, 173, 182, 110, 124, 184, 31, 68, 251, +// 58, 156, 75, 22, 152, 171, 231, 122, 174, 65, 152, 228, 111, 145, 59, 97, 216, 8, 27, +// 170, 190, 95, 60, 179, 225, 115, 7, 87, 179, 156, 39, 151, 104, 248, 150, 153, 45, 198, +// 251, 253, 90, 22, 78, 15, 184, 68, 216, 106, 19, 24, 5, 136, 206, 229, 175, 254, 173, +// 177, 240, 221, 3, 156, 244, 92, 5, 237, 51, 202, 54, 101, 247, 95, 25, 234, 164, 217, +// 81, 5, 98, 193, 159, 81, 27, 161, 210, 195, 10, 61, 163, 168, 196, 190, 166, 31, 153, +// 103, 44, 57, 82, 245, 233, 21, 163, 5, 255, 63, 98, 250, 230, 134, 239, 130, 241, 40, +// 12, 66, 150, 73, 61, 231, 25, 155, 136, 16, 177, 131, 254, 17, 199, 46, 55, 83, 209, +// 203, 148, 20, 253, 89, 194, 121, 212, 156, 46, 42, 211, 13, 209, 251, 66, 136, 118, 51, +// 218, 166, 53, 97, 13, 162, 17, 58, 241, 225, 49, 231, 110, 253, 23, 186, 100, 143, 106, +// 209, 98, 176, 88, 131, 128, 22, 171, 147, 210, 79, 79, 2, 185, 240, 232, 248, 244, 216, +// 102, 170, 223, 42, 221, 209, 223, 88, 168, 52, 161, 250, 144, 138, 51, 57, 14, 225, 94, +// 44, 92, 159, 185, 161, 161, 23, 39, 102, 155, 37, 60, 158, 87, 223, 77, 117, 116, 86, +// 16, 207, 223, 9, 147, 47, 107, 172, 83, 246, 7, 133, 107, 110, 59, 167, 172, 203, 229, +// 114, 13, 183, 168, 172, 135, 192, 136, 80, 119, 67, 14, 254, 168, 56, 252, 111, 46, 13, +// 45, 166, 94, 99, 87, 193, 50, 17, 196, 0, 113, 135, 60, 104, 213, 3, 147, 151, 69, 123, +// 184, 247, 86, 208, 191, 63, 49, 124, 39, 153, 208, 240, 78, 91, 251, 222, 197, 237, +// 101, 221, 226, 189, 61, 1, 223, 152, 242, 135, 190, 30, 33, 118, 28, 134, 96, 255, 2, +// 3, 82, 102, 242, 105, 129, 86, 250, 249, 81, 246, 78, 207, 234, 47, 49, 44, 6, 1, 209, +// 121, 88, 181, 75, 98, 7, 171, 77, 227, 63, 203, 30, 108, 141, 33, 153, 2, 105, 125, +// 163, 197, 212, 90, 23, 87, 50, 97, 60, 102, 158, 230, 76, 9, 115, 86, 216, 215, 16, 41, +// 20, 47, 34, 20, 221, 144, 161, 102, 251, 212, 29, 24, 77, 76, 54, 95, 227, 133, 112, +// 134, 113, 197, 181, 151, 16, 103, 221, 115, 146, 226, 114, 240, 147, 205, 155, 155, 86, +// 216, 168, 102, 56, 73, 115, 164, 174, 76, 140, 62, 82, 221, 172, 69, 127, 175, 68, 15, +// 147, 11, 43, 162, 106, 224, 3, 137, 66, 240, 52, 244, 138, 231, 45, 192, 40, 124, 32, +// 166, 117, 7, 148, 179, 148, 142, 82, 165, 240, 211, 183, 159, 248, 144, 67, 85, 229, +// 10, 202, 39, 181, 181, 102, 190, 31, 198, 67, 124, 154, 3, 253, 122, 78, 56, 107, 195, +// 216, 243, 27, 85, 12, 18, 216, 134, 123, 107, 113, 210, 28, 125, 136, 75, 135, 213, +// 194, 210, 102, 183, 254, 69, 92, 157, 221, 119, 71, 105, 218, 10, 238, 112, 57, 203, +// 249, 35, 19, 39, 97, 37, 188, 192, 242, 83, 199, 255, 0, 117, 70, 193, 4, 85, 195, 164, +// 14, 84, 194, 117, 30, 169, 247, 101, 164, 228, 170, 210, 136, 236, 252, 88, 3, 80, 239, +// 109, 10, 250, 224, 169, 142, 110, 119, 160, 78, 188, 154, 155, 105, 88, 197, 81, 165, +// 90, 33, 139, 91, 31, 183, 236, 204, 100, 17, 183, 214, 33, 104, 243, 8, 25, 251, 149, +// 95, 247, 98, 248, 23, 7, 37, 128, 202, 37, 67, 107, 16, 18, 228, 252, 175, 55, 9, 97, +// 142, 228, 163, 25, 196, 247, 92, 61, 161, 20, 218, 252, 80, 215, 22, 83, 30, 246, 167, +// 75, 109, 44, 118, 81, 74, 26, 27, 180, 35, 115, 206, 175, 229, 90, 242, 120, 74, 164, +// 96, 54, 167, 67, 41, 219, 129, 224, 28, 52, 119, 29, 4, 11, 72, 86, 28, 7, 74, 76, 52, +// 179, 185, 57, 71, 134, 103, 63, 57, 168, 244, 194, 194, 205, 158, 233, 203, 155, 250, +// 118, 18, 146, 84, 173, 87, 201, 49, 146, 135, 113, 254, 63, 199, 36, 227, 189, 241, +// 197, 204, 119, 50, 10, 253, 201, 207, 9, 149, 79, 218, 123, 149, 26, 141, 53, 177, 179, +// 68, 183, 13, 158, 212, 231, 236, 212, 188, 192, 201, 129, 161, 121, 63, 225, 161, 104, +// 154, 203, 221, 53, 171, 235, 154, 137, 254, 247, 95, 215, 23, 109, 83, 148, 46, 160, +// 77, 164, 166, 156, 157, 27, 38, 111, 30, 127, 243, 163, 104, 251, 95, 15, 122, 132, 65, +// 88, 201, 15, 185, 146, 151, 169, 148, 184, 180, 44, 198, 244, 243, 170, 15, 217, 170, +// 157, 126, 163, 201, 71, 221, 97, 138, 4, 2, 178, 39, 118, 28, 107, 55, 24, 8, 38, 127, +// 160, 68, 204, 40, 139, 172, 121, 229, 232, 158, 197, 74, 241, 49, 224, 75, 127, 223, +// 150, 31, 221, 154, 209, 209, 152, 148, 206, 239, 63, 228, 54, 141, 73, 239, 241, 84, +// 43, 141, 223, 155, 160, 240, 208, 129, 125, 152, 209, 191, 84, 11, 5, 187, 0, 170, 82, +// 169, 142, 76, 191, 30, 221, 84, 80, 85, 30, 56, 127, 77, 37, 102, 212, 247, 168, 64, +// 201, 96, 85, 253, 58, 56, 106, 91, 99, 208, 16, 69, 15, 159, 57, 149, 124, 215, 138, 2, +// 143, 145, 0, 84, 233, 123, 126, 237, 240, 60, 107, 148, 1, 101, 199, 24, 180, 211, 147, +// 152, 98, 32, 76, 154, 112, 35, 187, 21, 72, 186, 22, 128, 171, 48, 179, 120, 132, 15, +// 118, 107, 103, 161, 76, 83, 216, 232, 22, 68, 203, 109, 26, 146, 160, 183, 39, 225, 43, +// 187, 121, 209, 176, 223, 62, 117, 154, 70, 218, 179, 56, 226, 186, 133, 203, 244, 25, +// 206, 121, 195, 33, 107, 43, 220, 183, 192, 194, 70, 157, 122, 236, 45, 93, 120, 252, +// 248, 17, 245, 187, 196, 57, 151, 50, 153, 151, 109, 52, 120, 229, 244, 193, 34, 219, +// 251, 244, 167, 245, 195, 171, 248, 100, 9, 126, 141, 121, 16, 126, 134, 105, 107, 129, +// 79, 237, 140, 144, 220, 219, 122, 51, 231, 78, 137, 36, 8, 218, 220, 34, 149, 198, 142, +// 240, 173, 27, 6, 207, 72, 131, 65, 155, 150, 106, 49, 193, 239, 160, 80, 92, 42, 149, +// 182, 43, 176, 230, 27, 245, 49, 83, 131, 61, 194, 116, 24, 215, 79, 48, 230, 78, 165, +// 79, 146, 16, 70, 134, 210, 213, 208, 210, 14, 200, 147, 148, 54, 108, 154, 155, 249, +// 71, 250, 199, 14, 249, 151, 234, 17, 170, 85, 201, 59, 40, 40, 251, 74, 54, 198, 250, +// 57, 221, 230, 132, 25, 201, 197, 205, 137, 200, 153, 255, 44, 79, 241, 83, 195, 206, +// 144, 12, 31, 251, 87, 99, 31, 254, 146, 82, 214, 51, 10, 80, 26, 30, 184, 224, 65, 137, +// 100, 61, 128, 193, 225, 85, 253, 192, 236, 29, 213, 90, 213, 197, 142, 47, 245, 243, +// 93, 192, 159, 235, 203, 206, 90, 231, 62, 52, 59, 254, 134, 213, 179, 164, 196, 239, +// 142, 28, 242, 185, 18, 100, 211, 39, 57, 206, 55, 107, 6, 223, 53, 127, 85, 196, 175, +// 202, 226, 83, 23, 58, 7, 131, 55, 49, 241, 47, 146, 75, 95, 131, 61, 30, 0, 201, 216, +// 226, 73, 15, 46, 156, 255, 3, 186, 188, 131, 118, 74, 228, 112, 156, 31, 41, 182, 25, +// 184, 126, 254, 35, 63, 132, 216, 83, 121, 200, 232, 213, 131, 208, 66, 34, 145, 114, +// 109, 109, 51, 174, 164, 89, 152, 45, 94, 205, 231, 136, 125, 201, 154, 104, 14, 178, +// 68, 126, 116, 246, 165, 127, 2, 175, 198, 98, 187, 95, 66, 220, 190, 132, 223, 75, 145, +// 173, 26, 84, 194, 177, 171, 144, 33, 48, 172, 94, 207, 22, 186, 146, 161, 29, 23, 174, +// 1, 138, 169, 178, 43, 126, 52, 58, 236, 47, 114, 147, 69, 86, 246, 196, 50, 100, 45, +// 94, 179, 93, 17, 115, 166, 83, 229, 220, 206, 83, 221, 235, 89, 247, 239, 177, 38, 235, +// 141, 64, 144, 240, 255, 127, 99, 132, 227, 183, 22, 174, 175, 71, 81, 236, 34, 191, 50, +// 107, 101, 113, 96, 88, 175, 23, 191, 219, 184, 69, 72, 164, 187, 168, 41, 103, 150, 67, +// 9, 153, 217, 25, 156, 235, 69, 144, 44, 180, 171, 70, 193, 209, 127, 10, 60, 203, 125, +// 154, 192, 65, 176, 80, 70, 51, 8, 154, 150, 6, 58, 210, 220, 6, 123, 123, 166, 141, 8, +// 167, 19, 93, 144, 21, 247, 104, 86, 255, 126, 188, 137, 59, 137, 119, 94, 153, 27, 246, +// 192, 11, 87, 153, 232, 34, 126, 167, 245, 15, 69, 188, 36, 41, 183, 230, 216, 179, 195, +// 21, 234, 109, 240, 4, 64, 72, 250, 43, 54, 72, 16, 69, 162, 235, 97, 59, 211, 123, 247, +// 59, 215, 110, 177, 7, 159, 210, 14, 25, 36, 123, 9, 232, 160, 211, 130, 213, 22, 254, +// 43, 151, 90, 14, 118, 78, 108, 248, 31, 118, 90, 243, 203, 163, 20, 109, 35, 30, 110, +// 65, 155, 182, 98, 64, 161, 15, 144, 89, 66, 63, 234, 111, 90, 184, 20, 175, 114, 103, +// 254, 203, 103, 95, 7, 128, 147, 58, 19, 73, 102, 145, 125, 98, 12, 87, 121, 57, 117, +// 114, 53, 170, 232, 50, 35, 228, 145, 21, 3, 152, 118, 250, 78, 24, 6, 140, 15, 125, +// 118, 247, 183, 198, 103, 98, 20, 112, 8, 31, 60, 15, 33, 3, 235, 119, 184, 102, 137, +// 145, 228, 147, 115, 95, 34, 212, 207, 125, 251, 240, 16, 186, 247, 188, 9, 29, 179, +// 176, 194, 250, 115, 71, 59, 197, 244, 199, 142, 19, 25, 14, 254, 109, 182, 160, 10, +// 123, 202, 55, 120, 80, 108, 3, 115, 66, 65, 77, 190, 248, 35, 116, 208, 23, 74, 164, +// 158, 133, 51, 234, 23, 152, 122, 84, 62, 203, 162, 53, 9, 152, 117, 121, 72, 45, 85, +// 191, 236, 150, 54, 238, 150, 171, 151, 166, 214, 67, 91, 104, 42, 119, 51, 168, 168, +// 158, 115, 193, 41, 125, 217, 78, 176, 73, 36, 132, 83, 7, 240, 82, 52, 147, 37, 38, +// 145, 191, 75, 133, 216, 143, 0, 55, 233, 230, 25, 113, 243, 251, 230, 43, 78, 183, 170, +// 250, 145, 168, 234, 180, 68, 55, 233, 53, 166, 80, 174, 43, 137, 157, 46, 107, 90, 154, +// 44, 229, 27, 83, 77, 226, 203, 24, 203, 105, 254, 242, 175, 230, 96, 45, 189, 42, 17, +// 118, 163, 89, 172, 138, 250, 245, 105, 82, 166, 238, 46, 95, 13, 255, 123, 14, 58, 40, +// 103, 179, 52, 94, 41, 32, 249, 39, 36, 83, 198, 144, 205, 114, 103, 219, 159, 78, 10, +// 77, 249, 30, 245, 207, 9, 160, 137, 200, 126, 97, 63, 194, 134, 137, 62, 53, 210, 224, +// 81, 225, 101, 120, 35, 158, 44, 65, 156, 23, 103, 57, 81, 82, 137, 94, 34, 251, 210, +// 238, 81, 25, 227, 16, 142, 230, 220, 255, 225, 98, 206, 238, 189, 54, 231, 80, 148, +// 212, 244, 13, 129, 55, 109, 164, 214, 15, 38, 246, 130, 51, 187, 83, 116, 150, 164, 35, +// 224, 162, 131, 189, 173, 117, 225, 236, 23, 102, 111, 146, 69, 146, 116, 125, 33, 214, +// 232, 112, 241, 169, 247, 80, 150, 27, 38, 179, 32, 107, 245, 170, 93, 32, 204, 243, 13, +// 130, 190, 57, 125, 14, 64, 16, 151, 77, 238, 178, 24, 88, 240, 41, 191, 116, 166, 126, +// 224, 42, 65, 166, 208, 35, 95, 24, 3, 216, 234, 60, 156, 110, 225, 78, 43, 147, 24, +// 103, 154, 220, 185, 7, 5, 4, 61, 222, 22, 83, 143, 156, 15, 78, 144, 46, 252, 193, 225, +// 101, 140, 154, 168, 107, 113, 213, 104, 147, 160, 232, 77, 143, 57, 170, 196, 109, 152, +// 31, 232, 70, 103, 179, 72, 49, 19, 12, 227, 98, 118, 107, 187, 30, 170, 40, 54, 88, +// 202, 222, 242, 54, 96, 28, 57, 147, 131, 105, 103, 68, 147, 6, 189, 201, 222, 223, 135, +// 111, 85, 12, 239, 17, 7, 137, 188, 172, 230, 129, 36, 165, 140, 136, 55, 123, 116, 23, +// 48, 122, 247, 235, 81, 63, 43, 180, 192, 175, 1, 243, 80, 116, 158, 228, 228, 115, 131, +// 124, 1, 7, 236, 97, 3, 168, 220, 43, 95, 118, 146, 51, 156, 84, 0, 24, 131, 237, 83, +// 117, 89, 109, 216, 173, 196, 148, 232, 170, 111, 188, 147, 58, 133, 152, 207, 48, 210, +// 195, 237, 0, 139, 177, 188, 113, 41, 133, 146, 249, 190, 184, 228, 4, 22, 147, 89, 66, +// 50, 77, 59, 179, 215, 87, 234, 166, 211, 186, 154, 125, 151, 100, 206, 176, 84, 65, +// 232, 108, 35, 39, 8, 234, 195, 214, 6, 138, 132, 172, 164, 215, 16, 200, 213, 203, 99, +// 9, 69, 6, 74, 34, 144, 49, 7, 236, 156, 73, 142, 156, 168, 40, 7, 126, 134, 43, 28, +// 148, 255, 94, 170, 23, 20, 228, 114, 165, 152, 148, 184, 159, 58, 214, 66, 118, 106, +// 165, 69, 100, 105, 106, 185, 187, 119, 205, 52, 233, 185, 167, 111, 117, 164, 60, 14, +// 201, 70, 24, 216, 149, 52, 57, 229, 198, 225, 12, 129, 52, 49, 228, 146, 86, 65, 251, +// 215, 61, 91, 104, 1, 141, 148, 5, 230, 212, 21, 96, 107, 220, 252, 150, 128, 37, 34, +// 97, 68, 189, 141, 59, 224, 93, 150, 199, 249, 170, 64, 78, 61, 231, 169, 212, 171, 98, +// 64, 2, 247, 190, 105, 31, 113, 201, 165, 102, 216, 100, 128, 233, 190, 150, 14, 71, 40, +// 142, 37, 45, 213, 56, 212, 229, 59, 42, 88, 175, 9, 231, 220, 37, 28, 230, 171, 14, +// 122, 78, 96, 111, 179, 18, 239, 193, 88, 125, 155, 99, 178, 211, 190, 100, 122, 126, +// 203, 219, 83, 29, 235, 242, 129, 50, 201, 15, 175, 95, 45, 244, 217, 186, 242, 98, 71, +// 197, 169, 155, 63, 107, 59, 155, 88, 5, 224, 20, 238, 113, 147, 11, 93, 228, 112, 180, +// 69, 229, 154, 188, 118, 210, 52, 6, 238, 83, 70, 184, 34, 136, 7, 200, 187, 40, 144, +// 76, 106, 56, 179, 198, 253, 47, 46, 16, 90, 126, 240, 26, 116, 102, 96, 30, 91, 235, +// 120, 183, 80, 62, 102, 111, 191, 241, 184, 129, 55, 79, 142, 204, 46, 70, 196, 8, 228, +// 67, 56, 202, 252, 91, 72, 74, 89, 195, 203, 81, 172, 198, 48, 187, 224, 77, 223, 216, +// 208, 31, 25, 95, 107, 141, 104, 101, 92, 190, 31, 223, 164, 221, 155, 180, 33, 202, +// 248, 217, 182, 253, 56, 132, 220, 212, 10, 18, 53, 192, 155, 232, 22, 68, 74, 62, 180, +// 253, 77, 21, 199, 56, 60, 101, 201, 215, 218, 221, 133, 229, 199, 82, 230, 190, 74, 69, +// 236, 226, 12, 203, 3, 216, 125, 254, 176, 176, 91, 39, 67, 182, 25, 47, 45, 58, 13, 38, +// 229, 130, 162, 255, 117, 80, 141, 188, 23, 87, 96, 101, 35, 128, 124, 112, 124, 29, +// 121, 114, 89, 253, 244, 161, 22, 231, 229, 178, 30, 99, 34, 220, 28, 172, 61, 229, 40, +// 19, 195, 32, 235, 203, 174, 78, 124, 131, 68, 31, 139, 142, 156, 38, 255, 44, 166, 171, +// 9, 196, 173, 49, 156, 16, 208, 244, 227, 30, 83, 150, 82, 61, 109, 200, 237, 163, 171, +// 188, 121, 118, 149, 61, 245, 224, 62, 179, 139, 217, 62, 245, 3, 110, 216, 142, 207, +// 17, 125, 51, 198, 124, 60, 46, 240, 26, 119, 215, 14, 68, 142, 150, 210, 197, 110, 107, +// 204, 128, 43, 214, 90, 187, 142, 60, 51, 56, 227, 239, 17, 13, 80, 199, 101, 8, 50, +// 122, 1, 190, 158, 212, 115, 61, 197, 51, 50, 235, 184, 200, 4, 250, 244, 203, 201, 222, +// 206, 252, 138, 34, 8, 16, 148, 198, 112, 157, 103, 243, 74, 209, 244, 186, 198, 244, +// 21, 229, 168, 246, 211, 151, 87, 7, 71, 253, 147, 109, 108, 78, 62, 148, 129, 220, 1, +// 104, 76, 69, 95, 81, 99, 13, 65, 108, 42, 176, 94, 189, 120, 205, 48, 112, 207, 188, +// 186, 93, 250, 13, 168, 247, 53, 112, 56, 227, 140, 246, 130, 229, 36, 200, 253, 212, +// 189, 217, 128, 107, 163, 78, 78, 90, 137, 44, 20, 0, 194, 70, 89, 185, 230, 32, 161, +// 37, 134, 142, 94, 155, 99, 18, 117, 154, 146, 129, 178, 53, 75, 113, 214, 116, 30, 218, +// 53, 180, 61, 237, 204, 145, 98, 132, 255, 167, 27, 45, 6, 60, 23, 50, 254, 108, 76, 42, +// 93, 131, 90, 209, 55, 0, 139, 71, 242, 18, 42, 225, 247, 183, 240, 147, 227, 254, 164, +// 19, 184, 41, 3, 112, 41, 191, 21, 140, 43, 230, 124, 207, 193, 233, 123, 45, 79, 195, +// 231, 59, 2, 181, 216, 54, 205, 186, 103, 203, 67, 10, 132, 122, 62, 203, 249, 223, 174, +// 234, 104, 130, 42, 32, 32, 94, 54, 135, 161, 186, 14, 34, 125, 102, 219, 251, 209, 221, +// 221, 125, 232, 18, 223, 208, 175, 206, 133, 160, 11, 228, 119, 142, 197, 232, 21, 10, +// 67, 68, 132, 11, 182, 80, 158, 67, 254, 252, 90, 15, 113, 112, 15, 60, 238, 90, 147, +// 207, 140, 90, 162, 211, 240, 193, 215, 182, 74, 101, 220, 176, 7, 168, 217, 104, 189, +// 59, 228, 142, 204, 180, 13, 203, 209, 83, 41, 148, 179, 159, 160, 250, 91, 79, 207, +// 233, 40, 4, 253, 168, 98, 209, 63, 58, 150, 164, 222, 133, 127, 213, 98, 158, 58, 14, +// 207, 208, 218, 25, 71, 224, 191, 62, 178, 234, 214, 111, 105, 0, 17, 167, 226, 93, 161, +// 245, 194, 161, 164, 156, 61, 174, 86, 76, 143, 78, 180, 242, 198, 189, 40, 27, 11, 119, +// 165, 160, 115, 105, 8, 68, 133, 214, 163, 223, 64, 137, 185, 146, 82, 106, 38, 76, 144, +// 61, 148, 57, 245, 29, 254, 246, 193, 9, 33, 84, 17, 84, 226, 201, 68, 103, 97, 220, +// 221, 25, 237, 18, 242, 72, 56, 226, 26, 140, 128, 82, 224, 238, 85, 137, 243, 204, 53, +// 148, 134, 103, 204, 93, 19, 253, 244, 200, 232, 100, 184, 242, 204, 155, 106, 154, 29, +// 46, 168, 152, 246, 179, 85, 253, 60, 243, 159, 62, 130, 41, 55, 131, 110, 146, 68, 137, +// 187, 75, 56, 9, 39, 10, 136, 120, 165, 205, 202, 76, 248, 123, 127, 159, 91, 51, 205, +// 165, 76, 241, 68, 25, 38, 138, 166, 228, 98, 242, 234, 155, 147, 252, 240, 208, 145, +// 23, 51, 115, 165, 22, 139, 227, 18, 81, 177, 10, 109, 86, 47, 179, 4, 198, 87, 207, +// 141, 110, 129, 53, 221, 82, 182, 220, 12, 127, 17, 191, 138, 130, 95, 80, 239, 36, 90, +// 185, 3, 128, 221, 252, 150, 126, 234, 79, 35, 89, 15, 175, 197, 74, 129, 167, 195, 243, +// 123, 23, 179, 96, 62, 217, 158, 90, 49, 137, 144, 199, 9, 129, 91, 66, 28, 29, 24, 245, +// 37, 16, 130, 47, 127, 16, 244, 220, 210, 248, 45, 98, 59, 90, 108, 153, 39, 37, 14, 22, +// 72, 227, 132, 1, 72, 2, 53, 42, 150, 201, 241, 221, 21, 41, 207, 135, 191, 50, 217, 11, +// 113, 73, 85, 139, 221, 233, 222, 250, 176, 230, 238, 67, 61, 26, 185, 162, 113, 139, +// 10, 189, 31, 151, 154, 199, 83, 47, 229, 68, 33, 248, 228, 32, 193, 252, 30, 134, 203, +// 16, 50, 157, 223, 66, 40, 207, 113, 1, 182, 195, 6, 66, 35, 187, 28, 20, 53, 118, 168, +// 184, 81, 202, 34, 48, 155, 135, 157, 205, 227, 227, 187, 4, 195, 139, 2, 15, 15, 174, +// 222, 109, 249, 146, 214, 77, 48, 63, 235, 45, 156, 211, 148, 188, 83, 45, 141, 250, +// 253, 71, 38, 83, 145, 199, 161, 210, 213, 169, 37, 253, 175, 81, 52, 133, 76, 109, 54, +// 107, 153, 205, 56, 74, 252, 58, 214, 195, 124, 19, 207, 237, 106, 205, 70, 165, 79, 28, +// 182, 202, 45, 254, 55, 118, 16, 17, 3, 21, 179, 64, 215, 69, 97, 216, 41, 183, 144, +// 191, 194, 113, 105, 206, 6, 180, 78, 139, 209, 44, 153, 89, 39, 248, 42, 128, 178, 19, +// 125, 246, 177, 221, 39, 89, 240, 200, 158, 25, 51, 162, 105, 42, 11, 254, 156, 62, 255, +// 183, 47, 228, 161, 87, 75, 132, 11, 107, 45, 45, 160, 169, 115, 73, 0, 14, 163, +// ]; + +// let serialized_proof = StoneCompatibleSerializer::serialize_proof::>( +// &proof, +// &pub_inputs, +// &proof_options, +// ); +// assert_eq!(serialized_proof, expected_bytes); +// } + +// #[test] +// fn test_serialization_compatible_with_stone_4() { +// let mut trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::one(), 4); + +// let claimed_index = 2; +// let claimed_value = trace.get_row(claimed_index)[0]; +// let proof_options = ProofOptions { +// blowup_factor: 2, +// coset_offset: 3, +// grinding_factor: 0, +// fri_number_of_queries: 2, +// }; + +// let pub_inputs = fibonacci_2_cols_shifted::PublicInputs { +// claimed_value, +// claimed_index, +// }; + +// let proof = Prover::>::prove( +// &mut trace, +// &pub_inputs, +// &proof_options, +// StoneProverTranscript::new(&pub_inputs.as_bytes()), +// ) +// .unwrap(); + +// let expected_bytes = [ +// 9, 161, 59, 243, 85, 60, 44, 155, 163, 203, 128, 147, 203, 253, 93, 16, 137, 42, 94, +// 225, 173, 254, 120, 1, 43, 167, 254, 15, 49, 148, 2, 50, 47, 159, 254, 83, 209, 26, 91, +// 113, 237, 157, 107, 252, 35, 130, 117, 22, 155, 181, 217, 11, 145, 208, 53, 201, 14, +// 148, 19, 247, 19, 105, 239, 108, 2, 17, 212, 103, 137, 76, 186, 20, 31, 118, 21, 139, +// 122, 39, 100, 197, 112, 11, 188, 227, 236, 15, 127, 186, 231, 187, 158, 137, 41, 180, +// 233, 36, 3, 145, 50, 37, 100, 198, 0, 152, 68, 30, 64, 111, 78, 211, 119, 49, 142, 180, +// 178, 74, 59, 150, 209, 45, 211, 159, 6, 216, 205, 161, 255, 142, 0, 104, 163, 169, 38, +// 160, 79, 95, 195, 96, 46, 20, 45, 189, 161, 181, 95, 133, 26, 124, 224, 44, 153, 119, +// 121, 29, 187, 126, 125, 161, 4, 45, 2, 1, 113, 106, 28, 174, 255, 138, 4, 34, 227, 191, +// 33, 203, 60, 20, 34, 36, 33, 8, 44, 53, 250, 177, 127, 59, 157, 229, 179, 87, 165, 58, +// 0, 0, 83, 98, 7, 41, 90, 187, 198, 80, 159, 250, 57, 252, 211, 64, 233, 110, 223, 155, +// 56, 189, 215, 57, 80, 161, 169, 246, 65, 133, 129, 132, 129, 233, 154, 204, 187, 178, +// 244, 76, 12, 9, 30, 113, 105, 206, 46, 192, 68, 96, 27, 72, 94, 126, 101, 253, 63, 94, +// 10, 89, 116, 120, 31, 123, 5, 224, 161, 148, 232, 99, 202, 108, 45, 218, 145, 93, 103, +// 64, 177, 105, 163, 115, 34, 11, 250, 31, 46, 213, 139, 205, 219, 194, 199, 175, 220, +// 79, 7, 51, 41, 162, 227, 93, 103, 1, 119, 157, 40, 0, 161, 176, 143, 13, 53, 64, 172, +// 166, 74, 71, 4, 177, 30, 109, 56, 217, 15, 172, 148, 119, 0, 1, 40, 225, 211, 37, 67, +// 227, 195, 75, 15, 184, 75, 35, 121, 152, 11, 206, 130, 181, 93, 52, 26, 222, 54, 225, +// 164, 206, 119, 98, 49, 127, 1, 245, 239, 229, 226, 164, 147, 237, 23, 92, 189, 192, +// 202, 171, 211, 97, 221, 103, 41, 20, 123, 42, 73, 255, 19, 182, 16, 44, 170, 91, 163, +// 241, 3, 122, 35, 184, 126, 224, 183, 84, 233, 162, 161, 139, 249, 241, 173, 181, 44, +// 40, 254, 122, 243, 31, 209, 50, 95, 136, 54, 66, 182, 182, 120, 86, 1, 200, 25, 46, +// 236, 199, 14, 120, 215, 166, 119, 142, 184, 187, 93, 210, 70, 99, 209, 109, 106, 7, 38, +// 13, 86, 113, 77, 40, 239, 101, 112, 47, 2, 80, 119, 11, 163, 93, 205, 89, 30, 136, 45, +// 112, 44, 157, 216, 11, 39, 148, 121, 29, 189, 236, 115, 33, 204, 138, 68, 69, 217, 20, +// 115, 169, 5, 14, 205, 72, 77, 54, 231, 218, 153, 95, 162, 175, 218, 232, 63, 190, 166, +// 244, 88, 215, 208, 135, 139, 66, 119, 107, 105, 209, 86, 146, 86, 139, 2, 52, 60, 90, +// 10, 156, 32, 31, 52, 138, 33, 75, 142, 77, 0, 167, 160, 116, 5, 177, 241, 191, 160, +// 205, 157, 11, 224, 168, 248, 210, 225, 35, 28, 249, 169, 95, 21, 155, 125, 184, 161, +// 209, 104, 28, 40, 157, 113, 186, 88, 83, 80, 52, 130, 162, 139, 20, 152, 253, 6, 236, +// 251, 188, 248, 74, 3, 157, 144, 158, 44, 242, 203, 233, 164, 71, 98, 98, 68, 87, 50, +// 103, 230, 182, 72, 240, 222, 223, 129, 196, 249, 204, 56, 77, 80, 64, 39, 35, 0, 32, +// 49, 240, 229, 228, 251, 68, 176, 221, 45, 123, 205, 240, 137, 20, 168, 248, 87, 111, +// 142, 170, 189, 190, 226, 99, 108, 192, 61, 135, 89, 138, 5, 100, 74, 55, 89, 173, 9, +// 154, 231, 111, 119, 138, 82, 126, 3, 197, 143, 28, 74, 78, 198, 99, 129, 126, 84, 31, +// 119, 224, 42, 247, 70, 75, 6, 249, 103, 53, 199, 171, 214, 151, 83, 116, 110, 0, 226, +// 78, 69, 116, 76, 146, 140, 180, 251, 2, 154, 84, 34, 123, 74, 210, 202, 193, 129, 242, +// 181, 142, 85, 140, 84, 138, 69, 121, 69, 23, 14, 219, 249, 133, 141, 242, 128, 253, 44, +// 159, 125, 93, 13, 89, 70, 107, 195, 118, 133, 114, 4, 202, 76, 185, 171, 27, 107, 95, +// 178, 68, 155, 72, 25, 53, 160, 89, 109, 77, 67, 112, 240, 99, 114, 26, 51, 240, 83, +// 134, 72, 157, 118, 238, 0, 156, +// ]; + +// let serialized_proof = StoneCompatibleSerializer::serialize_proof::>( +// &proof, +// &pub_inputs, +// &proof_options, +// ); +// assert_eq!(serialized_proof, expected_bytes); +// } + +// #[test] +// fn test_serialization_compatible_with_stone_5() { +// let mut trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::one(), 128); + +// let claimed_index = 111; +// let claimed_value = trace.get_row(claimed_index)[0]; +// let proof_options = ProofOptions { +// blowup_factor: 4, +// coset_offset: 3, +// grinding_factor: 0, +// fri_number_of_queries: 3, +// }; + +// let pub_inputs = fibonacci_2_cols_shifted::PublicInputs { +// claimed_value, +// claimed_index, +// }; + +// let proof = Prover::>::prove( +// &mut trace, +// &pub_inputs, +// &proof_options, +// StoneProverTranscript::new(&pub_inputs.as_bytes()), +// ) +// .unwrap(); + +// let expected_bytes = [ +// 68, 228, 98, 183, 28, 139, 62, 73, 131, 192, 34, 97, 48, 52, 113, 8, 60, 34, 63, 155, +// 94, 81, 98, 20, 135, 161, 25, 61, 234, 184, 129, 198, 144, 128, 202, 95, 113, 181, 23, +// 21, 159, 52, 240, 15, 152, 224, 44, 222, 4, 55, 135, 79, 36, 227, 217, 2, 99, 161, 149, +// 115, 30, 184, 45, 230, 4, 77, 37, 128, 110, 52, 56, 37, 193, 196, 32, 179, 243, 141, +// 31, 42, 204, 120, 141, 60, 220, 222, 222, 215, 24, 213, 46, 45, 197, 81, 12, 217, 6, +// 192, 96, 58, 36, 138, 6, 26, 193, 18, 57, 204, 116, 181, 43, 73, 201, 23, 56, 191, 204, +// 196, 103, 248, 81, 175, 7, 191, 7, 96, 94, 249, 1, 121, 108, 49, 11, 225, 107, 207, +// 252, 200, 206, 7, 175, 20, 138, 144, 147, 251, 124, 82, 97, 200, 54, 7, 85, 59, 200, +// 14, 98, 254, 17, 4, 7, 75, 53, 15, 137, 76, 197, 75, 96, 177, 216, 83, 24, 248, 153, +// 197, 35, 234, 125, 210, 179, 239, 38, 3, 147, 48, 3, 215, 224, 97, 158, 61, 3, 126, 7, +// 213, 168, 94, 76, 45, 126, 222, 108, 126, 98, 94, 181, 180, 118, 69, 73, 214, 126, 171, +// 171, 202, 3, 187, 25, 139, 137, 61, 168, 34, 228, 73, 162, 238, 201, 149, 8, 247, 182, +// 167, 58, 131, 254, 110, 116, 66, 36, 194, 73, 58, 230, 242, 105, 34, 119, 228, 51, 251, +// 56, 120, 109, 169, 9, 39, 243, 26, 57, 57, 60, 178, 75, 236, 199, 241, 184, 94, 150, +// 101, 202, 22, 99, 11, 6, 137, 207, 124, 220, 239, 95, 42, 177, 251, 103, 130, 56, 45, +// 74, 17, 203, 52, 106, 210, 111, 13, 90, 244, 147, 58, 194, 151, 31, 72, 196, 213, 43, +// 197, 113, 132, 5, 75, 120, 170, 187, 23, 187, 216, 67, 113, 205, 179, 18, 20, 92, 32, +// 204, 197, 25, 31, 253, 56, 204, 167, 77, 68, 218, 98, 186, 246, 237, 91, 67, 166, 157, +// 87, 193, 17, 28, 208, 248, 9, 158, 213, 14, 232, 27, 170, 208, 10, 28, 87, 85, 107, 16, +// 114, 130, 65, 211, 63, 185, 200, 32, 196, 50, 39, 234, 172, 62, 236, 108, 203, 61, 28, +// 143, 60, 61, 88, 54, 20, 228, 26, 62, 158, 49, 35, 64, 201, 182, 76, 166, 91, 237, 106, +// 66, 123, 144, 37, 119, 205, 156, 42, 142, 179, 6, 51, 80, 39, 144, 181, 147, 155, 195, +// 147, 115, 126, 133, 228, 85, 152, 154, 188, 114, 10, 9, 215, 176, 133, 207, 112, 52, +// 226, 238, 30, 74, 18, 1, 11, 196, 150, 186, 177, 35, 112, 40, 217, 137, 137, 207, 123, +// 104, 13, 239, 231, 201, 87, 108, 76, 75, 73, 12, 103, 0, 43, 168, 13, 40, 42, 5, 186, +// 109, 184, 112, 11, 56, 245, 168, 76, 222, 106, 188, 154, 219, 181, 69, 45, 158, 243, +// 89, 144, 86, 144, 232, 148, 25, 39, 89, 247, 95, 181, 7, 164, 13, 119, 129, 40, 59, +// 108, 21, 234, 12, 216, 35, 47, 214, 135, 136, 133, 146, 114, 106, 44, 87, 87, 239, 49, +// 161, 206, 102, 25, 33, 63, 5, 107, 72, 49, 191, 149, 185, 133, 160, 79, 228, 98, 219, +// 82, 69, 215, 230, 78, 145, 23, 161, 64, 200, 183, 50, 48, 71, 146, 173, 140, 39, 9, 7, +// 123, 153, 177, 94, 211, 89, 72, 83, 58, 26, 218, 17, 85, 196, 107, 97, 207, 15, 248, +// 122, 85, 194, 237, 25, 133, 54, 221, 54, 247, 35, 111, 0, 208, 142, 88, 50, 205, 210, +// 163, 184, 46, 195, 83, 185, 188, 104, 102, 247, 40, 141, 20, 55, 29, 25, 120, 135, 51, +// 69, 129, 224, 51, 150, 114, 3, 253, 93, 25, 49, 124, 36, 249, 212, 37, 126, 251, 218, +// 93, 50, 228, 222, 233, 229, 72, 116, 109, 3, 212, 79, 53, 195, 179, 134, 49, 176, 25, +// 3, 92, 61, 142, 129, 23, 152, 177, 153, 80, 223, 227, 47, 26, 39, 36, 22, 10, 96, 130, +// 211, 103, 128, 244, 243, 171, 100, 175, 26, 197, 156, 241, 2, 186, 125, 100, 79, 57, +// 119, 22, 36, 98, 178, 130, 49, 83, 132, 195, 21, 231, 138, 65, 235, 145, 236, 235, 73, +// 175, 183, 200, 78, 52, 95, 7, 1, 154, 106, 98, 38, 34, 125, 79, 194, 182, 75, 26, 36, +// 120, 239, 212, 90, 215, 225, 60, 57, 99, 159, 79, 145, 116, 235, 251, 142, 226, 56, +// 197, 3, 208, 28, 167, 217, 109, 97, 164, 78, 9, 221, 139, 241, 209, 198, 38, 234, 171, +// 166, 174, 244, 182, 228, 121, 71, 4, 219, 46, 146, 32, 153, 79, 0, 229, 11, 36, 224, +// 61, 63, 63, 223, 95, 190, 126, 79, 27, 233, 156, 232, 147, 3, 96, 233, 120, 240, 197, +// 168, 68, 173, 9, 87, 73, 150, 56, 230, 74, 62, 76, 205, 143, 234, 82, 186, 92, 209, +// 154, 181, 231, 146, 150, 218, 233, 192, 114, 135, 240, 252, 59, 28, 169, 254, 204, 37, +// 25, 50, 39, 199, 195, 40, 184, 197, 230, 68, 196, 171, 61, 133, 181, 140, 132, 116, +// 169, 211, 164, 3, 5, 17, 37, 149, 79, 160, 145, 107, 194, 58, 130, 226, 93, 38, 247, +// 17, 150, 146, 72, 188, 109, 75, 15, 170, 128, 97, 229, 188, 170, 188, 133, 103, 217, +// 153, 41, 64, 154, 159, 87, 167, 80, 240, 89, 123, 16, 152, 42, 23, 235, 165, 232, 71, +// 32, 101, 31, 18, 27, 79, 122, 243, 65, 83, 76, 90, 200, 108, 203, 252, 64, 53, 97, 230, +// 117, 194, 55, 249, 168, 98, 203, 12, 179, 20, 223, 151, 185, 253, 89, 29, 232, 86, 1, +// 26, 123, 245, 220, 240, 198, 90, 200, 187, 99, 80, 22, 100, 113, 163, 105, 109, 69, 87, +// 49, 150, 68, 124, 149, 68, 102, 62, 17, 139, 36, 205, 201, 119, 12, 47, 172, 148, 107, +// 234, 240, 95, 111, 193, 142, 215, 149, 216, 239, 133, 171, 180, 88, 68, 35, 128, 205, +// 214, 29, 34, 123, 166, 211, 173, 22, 129, 23, 116, 30, 79, 148, 38, 183, 196, 205, 233, +// 208, 166, 133, 158, 5, 61, 143, 89, 15, 119, 45, 160, 34, 100, 233, 242, 174, 246, 156, +// 28, 68, 157, 216, 96, 95, 144, 145, 188, 251, 88, 211, 67, 245, 224, 233, 154, 145, 75, +// 126, 207, 89, 206, 219, 207, 64, 79, 155, 172, 175, 211, 148, 237, 102, 130, 249, 13, +// 40, 229, 74, 140, 198, 170, 0, 153, 157, 83, 183, 177, 41, 219, 229, 16, 233, 69, 95, +// 239, 241, 93, 54, 219, 200, 204, 154, 81, 162, 234, 16, 164, 68, 147, 97, 213, 197, +// 180, 198, 243, 58, 92, 161, 203, 230, 106, 191, 110, 167, 115, 124, 216, 61, 251, 9, +// 16, 190, 50, 60, 230, 237, 2, 38, 27, 18, 85, 78, 225, 44, 251, 232, 48, 217, 96, 56, +// 25, 230, 224, 118, 25, 253, 198, 21, 78, 22, 153, 101, 159, 239, 209, 40, 98, 44, 36, +// 74, 251, 150, 171, 107, 83, 164, 200, 154, 113, 18, 162, 204, 179, 56, 170, 71, 253, +// 206, 68, 63, 92, 114, 207, 64, 213, 160, 36, 169, 121, 170, 226, 126, 37, 64, 53, 62, +// 16, 96, 187, 32, 14, 186, 29, 127, 178, 23, 199, 56, 133, 139, 164, 78, 79, 235, 158, +// 131, 189, 178, 8, 75, 197, 139, 88, 250, 133, 155, 95, 212, 56, 135, 122, 194, 247, 94, +// 49, 108, 65, 3, 182, 15, 43, 226, 153, 135, 142, 229, 178, 0, 93, 91, 116, 163, 228, +// 145, 112, 112, 78, 109, 23, 206, 245, 65, 10, 19, 45, 118, 96, 91, 184, 162, 217, 74, +// 135, 106, 233, 151, 97, 69, 106, 54, 22, 135, 48, 189, 165, 191, 9, 113, 238, 226, 16, +// 154, 162, 141, 15, 81, 110, 33, 61, 253, 218, 230, 112, 35, 2, 64, 253, 59, 89, 128, +// 85, 216, 157, 240, 241, 118, 248, 132, 182, 59, 137, 73, 171, 88, 152, 227, 205, 19, +// 220, 85, 60, 122, 87, 94, 150, 221, 2, 135, 13, 66, 187, 49, 197, 41, 101, 243, 246, +// 183, 197, 212, 15, 107, 193, 156, 220, 63, 123, 224, 16, 184, 134, 114, 73, 33, 26, 35, +// 110, 152, 2, 222, 134, 92, 157, 96, 123, 189, 210, 214, 78, 114, 52, 51, 33, 49, 124, +// 75, 224, 108, 130, 162, 20, 43, 193, 94, 229, 228, 174, 33, 162, 230, 2, 67, 193, 53, +// 92, 25, 154, 95, 29, 158, 67, 35, 255, 194, 83, 170, 26, 76, 53, 98, 2, 138, 27, 103, +// 6, 203, 183, 226, 48, 0, 22, 254, 0, 3, 94, 32, 155, 0, 191, 57, 203, 150, 21, 83, 133, +// 242, 130, 244, 91, 10, 83, 5, 113, 44, 10, 248, 142, 20, 73, 10, 71, 240, 157, 161, 5, +// 143, 247, 49, 252, 183, 33, 50, 137, 74, 197, 4, 42, 50, 113, 36, 206, 204, 213, 198, +// 100, 197, 80, 206, 40, 224, 114, 159, 59, 145, 231, 176, 80, 20, 252, 161, 230, 26, +// 114, 245, 38, 71, 150, 233, 168, 195, 228, 168, 78, 149, 0, 95, 55, 24, 159, 157, 76, +// 227, 4, 185, 5, 192, 102, 240, 103, 40, 9, 69, 72, 236, 44, 181, 98, 29, 58, 121, 63, +// 168, 190, 225, 27, 35, 59, 228, 230, 15, 227, 211, 90, 205, 108, 203, 228, 145, 219, +// 212, 254, 92, 100, 220, 50, 57, 62, 36, 194, 133, 80, 11, 243, 190, 227, 83, 152, 168, +// 50, 114, 146, 4, 134, 77, 236, 36, 235, 104, 113, 72, 140, 148, 53, 109, 109, 154, 203, +// 128, 21, 253, 192, 18, 44, 220, 150, 63, 118, 67, 30, 7, 0, 81, 226, 168, 92, 185, 135, +// 192, 152, 18, 213, 217, 120, 15, 145, 206, 194, 168, 56, 158, 189, 112, 143, 45, 11, +// 197, 229, 69, 245, 105, 217, 9, 97, 177, 107, 59, 144, 247, 23, 132, 50, 129, 75, 134, +// 125, 95, 78, 172, 175, 3, 193, 3, 247, 125, 11, 25, 125, 21, 198, 124, 108, 234, 120, +// 52, 104, 64, 204, 147, 109, 117, 108, 45, 3, 29, 163, 208, 221, 199, 64, 162, 214, 72, +// 56, 32, 221, 13, 220, 59, 239, 242, 232, 210, 113, 43, 75, 149, 170, 229, 221, 49, 161, +// 253, 78, 106, 113, 65, 227, 169, 99, 72, 225, 65, 62, 57, 127, 53, 167, 25, 73, 164, 0, +// 208, 84, 56, 86, 132, 13, 17, 83, 183, 27, 164, 26, 196, 193, 214, 195, 76, 176, 210, +// 135, 88, 151, 69, 253, 24, 47, 146, 0, 120, 3, 211, 113, 128, 191, 227, 235, 105, 198, +// 181, 240, 186, 255, 242, 196, 193, 216, 15, 192, 101, 165, 160, 19, 243, 52, 166, 254, +// 137, 11, 156, 192, 63, 70, 91, 251, 0, 229, 197, 209, 129, 198, 232, 97, 49, 238, 248, +// 141, 210, 9, 80, 14, 115, 251, 82, 235, 132, 209, 3, 123, 43, 25, 29, 59, 175, 204, +// 127, 144, 241, 61, 137, 123, 6, 130, 155, 200, 55, 190, 33, 194, 50, 48, 238, 239, 132, +// 118, 216, 63, 203, 178, 81, 227, 87, 184, 177, 147, 192, 254, 206, 134, 77, 2, 120, 58, +// 180, 95, 159, 37, 207, 64, 121, 101, 134, 179, 165, 105, 154, 212, 50, 195, 23, 39, 66, +// 190, 216, 32, 56, 224, 165, 191, 114, 84, 96, 155, 85, 71, 135, 46, 198, 47, 80, 151, +// 176, 94, 211, 249, 48, 134, 114, 110, 131, 32, 21, 12, 162, 245, 7, 186, 30, 199, 218, +// 204, 232, 115, 160, 85, 45, 0, 80, 227, 65, 212, 135, 143, 151, 84, 168, 237, 85, 38, +// 141, 154, 216, 217, 241, 77, 141, 113, 207, 196, 132, 156, 240, 130, 249, 118, 251, 61, +// 112, 4, 68, 121, 110, 140, 255, 49, 123, 233, 40, 222, 225, 213, 160, 81, 1, 236, 126, +// 136, 42, 145, 123, 239, 96, 215, 233, 81, 172, 231, 11, 138, 194, 116, 4, 54, 43, 117, +// 64, 159, 170, 166, 162, 143, 245, 175, 100, 116, 156, 227, 64, 0, 200, 44, 239, 120, +// 98, 68, 96, 27, 218, 61, 5, 62, 159, 225, 248, 250, 172, 77, 61, 190, 158, 84, 143, 48, +// 177, 68, 18, 225, 147, 106, 93, 5, 109, 237, 41, 154, 223, 225, 6, 45, 41, 48, 243, +// 184, 129, 161, 224, 67, 2, 34, 71, 61, 36, 96, 139, 217, 194, 107, 15, 224, 21, 144, +// 191, 0, 194, 170, 179, 77, 194, 164, 32, 255, 81, 252, 211, 137, 45, 90, 238, 151, 229, +// 25, 31, 24, 176, 150, 252, 202, 14, 176, 159, 232, 199, 115, 147, 184, 236, 254, 115, +// 18, 10, 113, 29, 15, 120, 125, 204, 34, 25, 14, 33, 103, 7, 118, 8, 120, 95, 3, 225, +// 123, 82, 87, 41, 136, 152, 150, 185, 1, 1, 192, 119, 80, 225, 235, 11, 171, 28, 189, +// 62, 157, 244, 240, 117, 104, 154, 69, 114, 58, 152, 188, 62, 185, 174, 151, 204, 194, +// 160, 36, 146, 90, 3, 181, 253, 91, 180, 196, 210, 102, 20, 237, 201, 45, 116, 22, 178, +// 36, 161, 133, 84, 39, 220, 181, 133, 235, 72, 128, 198, 186, 55, 160, 81, 36, 98, 140, +// 128, 131, 140, 199, 201, 142, 171, 106, 33, 210, 198, 66, 164, 9, 161, 46, 232, 216, +// 239, 244, 66, 88, 166, 111, 82, 201, 46, 53, 194, 117, 244, 34, 89, 156, 148, 180, 84, +// 49, 176, 38, 193, 5, 25, 132, 91, 210, 101, 13, 205, 228, 222, 84, 81, 160, 94, 34, +// 136, 192, 223, 119, 224, 16, 1, 74, 62, 42, 177, 100, 202, 183, 170, 108, 146, 201, 99, +// 175, 196, 55, 189, 170, 110, 233, 86, 223, 233, 249, 165, 68, 178, 26, 87, 49, 19, 212, +// 152, 40, 114, 175, 166, 145, 133, 202, 93, 153, 57, 19, 229, 216, 148, 234, 15, 46, +// 167, 5, 95, 51, 144, 242, 159, 28, 236, 158, 12, 206, 109, 165, 35, 105, 158, 238, 207, +// 197, 179, 150, 119, 151, 199, 21, 36, 101, 188, 116, 106, 240, 101, 159, 154, 194, 240, +// 39, 128, 152, 160, 178, 251, 56, 249, 195, 50, 113, 227, 202, 175, 5, 9, 249, 117, 148, +// 203, 104, 14, 169, 174, 197, 121, 245, 81, 140, 16, 129, 47, 255, 7, 125, 169, 239, +// 111, 235, 138, 243, 52, 63, 230, 187, 163, 234, 134, 184, 36, 136, 24, 181, 226, 243, +// 153, 8, 61, 242, 126, 123, 64, 245, 196, 11, 189, 149, 238, 56, 228, 248, 87, 19, 215, +// 198, 29, 145, 155, 118, 246, 120, 198, 170, 107, 1, 174, 81, 237, 113, 79, 100, 102, +// 237, 28, 10, 198, 210, 178, 250, 8, 138, 64, 184, 187, 13, 171, 107, 236, 127, 198, 41, +// 240, 158, 96, 243, 229, 191, 251, 102, 191, 202, 186, 90, 255, 54, 15, 172, 46, 135, +// 247, 116, 238, 184, 227, 57, 252, 227, 149, 219, 69, 92, 24, 245, 83, 49, 250, 130, +// 212, 115, 8, 166, 14, 145, 240, 119, 40, 147, 9, 247, 235, 232, 159, 65, 72, 204, 131, +// 132, 94, 6, 155, 127, 65, 84, 141, 54, 213, 93, 217, 118, 100, 175, 20, 55, 38, 12, 63, +// 109, 69, 113, 169, 95, 29, 227, 137, 105, 100, 255, 166, 229, 216, 1, 148, 154, 105, +// 227, 201, 229, 195, 134, 12, 251, 164, 76, 103, 227, 205, 19, 188, 141, 66, 24, 241, +// 59, 49, 178, 95, 11, 154, 240, 182, 83, 33, 7, 62, 98, 233, 175, 150, 136, 1, 137, 152, +// 28, 83, 237, 100, 236, 147, 131, 196, 119, 219, 143, 113, 0, 18, 232, 195, 92, 90, 191, +// 243, 64, 181, 240, 217, 13, 101, 72, 197, 237, 199, 138, 60, 21, 70, 144, 86, 178, 175, +// 145, 95, 76, 174, 43, 188, 233, 139, 161, 203, 91, 235, 178, 182, 225, 155, 23, 219, +// 42, 119, 143, 246, 211, 154, 55, 126, 69, 61, 8, 40, 189, 190, 92, 130, 85, 54, 143, +// 231, 191, 19, 243, 31, 192, 242, 150, 131, 195, 130, 111, 181, 32, 147, 190, 138, 172, +// 146, 222, 208, 74, 95, 209, 122, 185, 72, 1, 96, 71, 34, 116, 182, 82, 35, 126, 133, +// 51, 101, 17, 2, 83, 15, 149, 98, 49, 47, 172, 137, 223, 248, 89, 82, 186, 152, 89, 4, +// 60, 74, 7, 181, 205, 181, 14, 92, 40, 203, 101, 155, 35, 206, 112, 144, 102, 184, 219, +// 16, 87, 237, 188, 68, 169, 90, 189, 61, 201, 209, 192, 99, 154, 134, 56, 19, 102, 107, +// 25, 241, 237, 174, 105, 136, 199, 55, 111, 225, 58, 152, 112, 159, 125, 111, 81, 237, +// 21, 39, 54, 253, 120, 189, 220, 164, 138, 135, 25, 61, 182, 242, 116, 100, 159, 41, 27, +// 144, 78, 104, 71, 129, 64, 142, 5, 63, 97, 239, 225, 163, 229, 9, 143, 156, 101, 201, +// 237, 57, 80, 103, 1, 36, 135, 63, 61, 247, 89, 202, 132, 140, 177, 178, 98, 7, 151, 10, +// 240, 59, 152, 109, 124, 11, 28, 218, 94, 131, 163, 101, 71, 187, 17, 162, 35, 22, 22, +// 9, 237, 30, 120, 118, 15, 50, 179, 52, 50, 5, 183, 194, 137, 254, 74, 80, 158, 238, +// 236, 186, 186, 121, 197, 231, 114, 183, 27, 6, 238, 104, 30, 254, 130, 247, 149, 224, +// 129, 200, 162, 49, 206, 20, 197, 45, 206, 179, 118, 169, 128, 184, 157, 85, 212, 198, +// 192, 22, 208, 130, 116, 99, 218, 56, 14, 249, 204, 234, 50, 74, 12, 7, 155, 116, 192, +// 213, 201, 115, 2, 22, 203, 145, 45, 140, 35, 17, 156, 209, 62, 73, 171, 132, 196, 84, +// 231, 146, 76, 123, 253, 109, 178, 117, 99, 52, 6, 221, 115, 207, 36, 232, 3, 46, 133, +// 43, 190, 220, 39, 242, 179, 120, 205, 120, 221, 101, 249, 43, 226, 131, 59, 159, 214, +// 202, 202, 90, 133, 51, 135, 141, 179, 123, 114, 167, 4, 65, 149, 218, 30, 196, 221, 44, +// 249, 170, 179, 73, 171, 89, 59, 177, 194, 95, 94, 61, 62, 44, 172, 172, 94, 228, 92, +// 17, 68, 16, 157, 1, 119, 137, 91, 67, 52, 14, 235, 57, 92, 102, 224, 208, 182, 222, 43, +// 196, 69, 33, 14, 184, 75, 54, 5, 59, 127, 69, 156, 222, 116, 185, 224, 106, 233, 94, +// 189, 183, 90, 204, 198, 142, 51, 129, 134, 251, 108, 187, 61, 78, 135, 102, 59, 165, +// 49, 38, 102, 97, 38, 102, 160, 229, 238, 170, 20, 24, 214, 83, 0, 202, 171, 190, 74, +// 55, 243, 17, 36, 116, 241, 94, 26, 17, 55, 245, 71, 104, 130, 141, 251, 1, 47, 77, 74, +// 17, 113, 48, 43, 204, 233, 157, 153, 136, 42, 132, 58, 173, 224, 23, 245, 9, 220, 224, +// 49, 142, 179, 49, 0, 135, 25, 109, 220, 226, 252, 51, 213, 235, 150, 101, 30, 63, 128, +// 82, 112, 187, 90, 64, 81, 30, 32, 116, 75, 233, 128, 79, 246, 155, 95, 193, 172, 93, +// 193, 84, 146, 143, 172, 21, 172, 6, 41, 41, 213, 50, 26, 178, 196, 126, 186, 74, 45, +// 141, 211, 182, 92, 154, 186, 207, 99, 221, 21, 177, 107, 199, 7, 98, 231, 144, 252, +// 120, 113, 217, 138, 23, 234, 162, 127, 180, 130, 126, 159, 1, 17, 50, 36, 249, 181, +// 123, 236, 110, 59, 26, 38, 212, 137, 58, 2, 73, 224, 135, 178, 0, 31, 157, 255, 68, 49, +// 205, 4, 109, 154, 29, 232, 129, 92, 67, 158, 161, 213, 129, 113, 53, 231, 159, 234, +// 114, 104, 17, 79, 89, 214, 106, 55, 150, 252, 35, 39, 78, 186, 59, 6, 12, 215, 97, 45, +// 88, 146, 80, 229, 50, 153, 202, 83, 158, 58, 247, 124, 78, 52, 194, 26, 198, 250, 14, +// 192, 162, 161, 25, 146, 190, 171, 241, 7, 94, 203, 139, 69, 222, 13, 1, 57, 86, 64, 84, +// 159, 226, 195, 239, 40, 26, 4, 120, 56, 127, 123, 209, 35, 127, 95, 157, 15, 155, 6, +// 143, 124, 37, 211, 186, 113, 213, 29, 101, 209, 238, 20, 207, 127, 45, 90, 245, 44, +// 220, 94, 224, 57, 204, 96, 83, 1, 90, 132, 111, 221, 5, 210, 186, 230, 39, 151, 46, 57, +// 31, 96, 218, 59, 115, 108, 29, 78, 23, 55, 231, 88, 142, 61, 147, 44, 57, 9, 112, 84, +// 55, 136, 254, 87, 83, 214, 23, 173, 31, 156, 202, 26, 193, 84, 130, 158, 88, 208, 209, +// 118, 231, 92, 160, 51, 32, 210, 125, 5, 114, 230, 119, 152, 165, 153, 98, 76, 145, 143, +// 78, 35, 201, 207, 251, 9, 44, 167, 198, 112, 22, 54, 224, 178, 216, 201, 248, 217, 139, +// 103, 86, 83, 220, 71, 244, 164, 126, 22, 91, 122, 154, 205, 30, 4, 76, 248, 75, 200, +// 191, 201, 95, 209, 20, 107, 13, 70, 88, 212, 15, 33, 160, 178, 202, 221, 23, 159, 1, +// 115, 152, 141, 54, 105, 37, 188, 106, 216, 119, 188, 233, 128, 226, 25, 12, 101, 193, +// 171, 81, 34, 156, 229, 241, 99, 243, 146, 33, 89, 193, 48, 48, 134, 213, 134, 232, 209, +// 177, 91, 29, 82, 242, 106, 241, 216, 132, 39, 20, 166, 59, 199, 184, 187, 139, 174, 40, +// 171, 149, 158, 160, 163, 255, 210, 111, 24, 201, 96, 54, 190, 244, 214, 85, 200, 239, +// 61, 99, 124, 239, 244, 170, 247, 153, 202, 47, 20, 136, 236, 17, 58, 164, 17, 196, 171, +// 171, 7, 235, 126, 171, 148, 60, 19, 1, 205, 202, 6, 230, 164, 222, 254, 83, 237, 80, +// 32, 177, 77, 12, 67, 106, 39, 48, 156, 107, 178, 36, 72, 125, 131, 179, 165, 124, 40, +// 139, 172, 178, 1, 170, 7, 247, 141, 97, 68, 98, 180, 164, 54, 120, 128, 134, 192, 248, +// 3, 197, 136, 207, 82, 119, 185, 10, 106, 216, 84, 173, 87, 176, 0, 21, 151, 48, 220, +// 196, 109, 236, 149, 52, 82, 251, 14, 201, 97, 226, 75, 177, 52, 16, 249, 36, 158, 103, +// 210, 33, 191, 114, 98, 40, 235, 19, 219, 101, 88, 189, +// ]; + +// let serialized_proof = StoneCompatibleSerializer::serialize_proof::>( +// &proof, +// &pub_inputs, +// &proof_options, +// ); +// assert_eq!(serialized_proof, expected_bytes); +// } +// } diff --git a/provers/stark/src/prover.rs b/provers/stark/src/prover.rs index 7a5a4210e..0e0fcfb3a 100644 --- a/provers/stark/src/prover.rs +++ b/provers/stark/src/prover.rs @@ -170,15 +170,31 @@ where /// https://github.com/starkware-libs/stone-prover pub trait IsStarkProver { /// Returns the Merkle tree and the commitment to the vectors `vectors`. - fn batch_commit(vectors: &[Vec>]) -> (BatchedMerkleTree, Commitment) + fn batch_commit_main( + vectors: &[Vec>], + ) -> (BatchedMerkleTree, Commitment) + where + FieldElement: AsBytes + Sync + Send, + // FieldElement: AsBytes + Sync + Send, + // E: IsSubFieldOf, + // A::Field: IsSubFieldOf, + { + let tree = BatchedMerkleTree::build(vectors); + let commitment = tree.root; + (tree, commitment) + } + + /// Returns the Merkle tree and the commitment to the vectors `vectors`. + fn batch_commit_extension( + vectors: &[Vec>], + ) -> (BatchedMerkleTree, Commitment) where FieldElement: AsBytes + Sync + Send, FieldElement: AsBytes + Sync + Send, - FieldElement: AsBytes + Sync + Send, - E: IsSubFieldOf, - A::Field: IsSubFieldOf, + // E: IsSubFieldOf, + // A::Field: IsSubFieldOf, { - let tree = BatchedMerkleTree::::build(vectors); + let tree = BatchedMerkleTree::build(vectors); let commitment = tree.root; (tree, commitment) } @@ -191,25 +207,77 @@ pub trait IsStarkProver { /// • The Merkle tree of evaluations of the above polynomials over the domain `domain`. /// • The roots of the above Merkle trees. #[allow(clippy::type_complexity)] - fn interpolate_and_commit( - trace: &TraceTable, + fn interpolate_and_commit_main( + trace: &TraceTable, domain: &Domain, transcript: &mut impl IsTranscript, ) -> ( - Vec>>, - Vec>>, - BatchedMerkleTree, + Vec>>, + Vec>>, + BatchedMerkleTree, Commitment, ) where FieldElement: AsBytes + Send + Sync, - FieldElement: AsBytes + Send + Sync, + // FieldElement: AsBytes + Send + Sync, FieldElement: AsBytes + Send + Sync, - E: IsSubFieldOf, - A::Field: IsSubFieldOf, + A::Field: IsSubFieldOf, + { + // Interpolate columns of `trace`. + let trace_polys = trace.compute_trace_polys_main::(); + + // Evaluate those polynomials t_j on the large domain D_LDE. + let lde_trace_evaluations = + Self::compute_lde_trace_evaluations::(&trace_polys, domain); + + let mut lde_trace_permuted = lde_trace_evaluations.clone(); + for col in lde_trace_permuted.iter_mut() { + in_place_bit_reverse_permute(col); + } + + // Compute commitment. + let lde_trace_permuted_rows = columns2rows(lde_trace_permuted); + let (lde_trace_merkle_tree, lde_trace_merkle_root) = + Self::batch_commit_main(&lde_trace_permuted_rows); + + // >>>> Send commitment. + transcript.append_bytes(&lde_trace_merkle_root); + + ( + trace_polys, + lde_trace_evaluations, + lde_trace_merkle_tree, + lde_trace_merkle_root, + ) + } + + /// Given a `TraceTable`, this method interpolates its columns, computes the commitment to the + /// table and appends it to the transcript. + /// Output: a touple of length 4 with the following: + /// • The polynomials interpolating the columns of `trace`. + /// • The evaluations of the above polynomials over the domain `domain`. + /// • The Merkle tree of evaluations of the above polynomials over the domain `domain`. + /// • The roots of the above Merkle trees. + #[allow(clippy::type_complexity)] + fn interpolate_and_commit_aux( + trace: &TraceTable, + domain: &Domain, + transcript: &mut impl IsTranscript, + ) -> ( + Vec>>, + Vec>>, + BatchedMerkleTree, + Commitment, + ) + where + FieldElement: AsBytes + Send + Sync, + // FieldElement: AsBytes + Send + Sync, + FieldElement: AsBytes + Send + Sync, + // E: IsSubFieldOf + IsFFTField, + A::Field: IsSubFieldOf + IsFFTField, { // Interpolate columns of `trace`. - let trace_polys = trace.compute_trace_polys::(); + let trace_polys = trace.compute_trace_polys_aux::(); // Evaluate those polynomials t_j on the large domain D_LDE. let lde_trace_evaluations = Self::compute_lde_trace_evaluations(&trace_polys, domain); @@ -222,7 +290,7 @@ pub trait IsStarkProver { // Compute commitment. let lde_trace_permuted_rows = columns2rows(lde_trace_permuted); let (lde_trace_merkle_tree, lde_trace_merkle_root) = - Self::batch_commit(&lde_trace_permuted_rows); + Self::batch_commit_extension(&lde_trace_permuted_rows); // >>>> Send commitment. transcript.append_bytes(&lde_trace_merkle_root); @@ -242,10 +310,11 @@ pub trait IsStarkProver { domain: &Domain, ) -> Vec>> where - FieldElement: Send + Sync, FieldElement: Send + Sync, + FieldElement: Send + Sync, E: IsSubFieldOf, A::Field: IsSubFieldOf, + // F: IsFFTField, { #[cfg(not(feature = "parallel"))] let trace_polys_iter = trace_polys.iter(); @@ -268,16 +337,18 @@ pub trait IsStarkProver { /// Returns the result of the first round of the STARK Prove protocol. fn round_1_randomized_air_with_preprocessing( air: &A, - main_trace: &TraceTable, + trace: &mut TraceTable, domain: &Domain, transcript: &mut impl IsTranscript, ) -> Result, ProvingError> where FieldElement: AsBytes + Send + Sync, + A::FieldExtension: IsFFTField, FieldElement: AsBytes + Send + Sync, { let (trace_polys, evaluations, main_merkle_tree, main_merkle_root) = - Self::interpolate_and_commit::(main_trace, domain, transcript); + // Self::interpolate_and_commit_main::(trace, domain, transcript); + Self::interpolate_and_commit_main(trace, domain, transcript); let main = Round1CommitmentData:: { trace_polys, @@ -286,11 +357,10 @@ pub trait IsStarkProver { }; let rap_challenges = air.build_rap_challenges(transcript); - - let aux_trace = air.build_auxiliary_trace(main_trace, &rap_challenges); - let (aux, aux_evaluations) = if !aux_trace.is_empty() { + let (aux, aux_evaluations) = if air.has_trace_interaction() { + air.build_auxiliary_trace(trace, &rap_challenges); let (aux_trace_polys, aux_trace_polys_evaluations, aux_merkle_tree, aux_merkle_root) = - Self::interpolate_and_commit(&aux_trace, domain, transcript); + Self::interpolate_and_commit_aux(trace, domain, transcript); let aux_evaluations = aux_trace_polys_evaluations; let aux = Some(Round1CommitmentData:: { trace_polys: aux_trace_polys, @@ -345,7 +415,7 @@ pub trait IsStarkProver { lde_composition_poly_evaluations_merged.push(chunk0); } - Self::batch_commit(&lde_composition_poly_evaluations_merged) + Self::batch_commit_extension(&lde_composition_poly_evaluations_merged) } /// Returns the result of the second round of the STARK Prove protocol. @@ -471,17 +541,26 @@ pub trait IsStarkProver { let coset_offset = FieldElement::::from(coset_offset_u64); let gamma = transcript.sample_field_element(); + let n_terms_composition_poly = round_2_result.lde_composition_poly_evaluations.len(); - let n_terms_trace = air.context().transition_offsets.len() * air.context().trace_columns; + let num_terms_trace = + air.context().transition_offsets.len() * A::STEP_SIZE * air.context().trace_columns; // <<<< Receive challenges: 𝛾, 𝛾' let mut deep_composition_coefficients: Vec<_> = core::iter::successors(Some(FieldElement::one()), |x| Some(x * &gamma)) - .take(n_terms_composition_poly + n_terms_trace) + .take(n_terms_composition_poly + num_terms_trace) .collect(); - let trace_poly_coeffients: Vec<_> = deep_composition_coefficients - .drain(..n_terms_trace) + // let trace_poly_coeffients: Vec<_> = deep_composition_coefficients + // .drain(..num_terms_trace) + // .collect(); + + let trace_term_coeffs: Vec<_> = deep_composition_coefficients + .drain(..num_terms_trace) + .collect::>() + .chunks(air.context().transition_offsets.len() * A::STEP_SIZE) + .map(|chunk| chunk.to_vec()) .collect(); // <<<< Receive challenges: 𝛾ⱼ, 𝛾ⱼ' @@ -489,14 +568,13 @@ pub trait IsStarkProver { // Compute p₀ (deep composition polynomial) let deep_composition_poly = Self::compute_deep_composition_poly( - air, &round_1_result.all_trace_polys(), round_2_result, round_3_result, z, &domain.trace_primitive_root, &gammas, - &trace_poly_coeffients, + &trace_term_coeffs, ); let domain_size = domain.lde_roots_of_unity_coset.len(); @@ -522,6 +600,7 @@ pub trait IsStarkProver { let number_of_queries = air.options().fri_number_of_queries; let iotas = Self::sample_query_indexes(number_of_queries, domain, transcript); + let query_list = fri::query_phase(&fri_layers, &iotas); let fri_layers_merkle_roots: Vec<_> = fri_layers @@ -557,14 +636,13 @@ pub trait IsStarkProver { /// composition polynomial, with coefficients sampled by the verifier (i.e. using Fiat-Shamir). #[allow(clippy::too_many_arguments)] fn compute_deep_composition_poly( - air: &A, trace_polys: &[Polynomial>], round_2_result: &Round2, round_3_result: &Round3, z: &FieldElement, primitive_root: &FieldElement, composition_poly_gammas: &[FieldElement], - trace_terms_gammas: &[FieldElement], + trace_terms_gammas: &[Vec>], ) -> Polynomial> where FieldElement: AsBytes + Send + Sync, @@ -585,28 +663,26 @@ pub trait IsStarkProver { h_terms.ruffini_division_inplace(&z_power); // Get trace evaluations needed for the trace terms of the deep composition polynomial - let transition_offsets = &air.context().transition_offsets; let trace_frame_evaluations = &round_3_result.trace_ood_evaluations; // Compute the sum of all the trace terms of the deep composition polynomial. // There is one term for every trace polynomial and for every row in the frame. // ∑ ⱼₖ [ 𝛾ₖ ( tⱼ − tⱼ(z) ) / ( X − zgᵏ )] - // @@@ this could be const - let trace_frame_length = trace_frame_evaluations.height; + let trace_evaluations_columns = &trace_frame_evaluations.columns(); #[cfg(feature = "parallel")] let trace_terms = trace_polys .par_iter() .enumerate() .fold(Polynomial::zero, |trace_terms, (i, t_j)| { + let gammas_i = &trace_terms_gammas[i]; + let trace_evaluations_i = &trace_evaluations_columns[i]; Self::compute_trace_term( &trace_terms, - (i, t_j), - trace_frame_length, - trace_terms_gammas, - &trace_frame_evaluations.columns(), - transition_offsets, + t_j, + gammas_i, + trace_evaluations_i, (z, primitive_root), ) }) @@ -618,13 +694,13 @@ pub trait IsStarkProver { .iter() .enumerate() .fold(Polynomial::zero(), |trace_terms, (i, t_j)| { + let gammas_i = &trace_terms_gammas[i]; + let trace_evaluations_i = &trace_evaluations_columns[i]; Self::compute_trace_term( &trace_terms, - (i, t_j), - trace_frame_length, - trace_terms_gammas, - &trace_frame_evaluations.columns(), - transition_offsets, + t_j, + gammas_i, + trace_evaluations_i, (z, primitive_root), ) }); @@ -632,33 +708,31 @@ pub trait IsStarkProver { h_terms + trace_terms } + // FIXME: FIX THIS DOCS! /// Adds to `accumulator` the term corresponding to the trace polynomial `t_j` of the Deep /// composition polynomial. That is, returns `accumulator + \sum_i \gamma_i \frac{ t_j - t_j(zg^i) }{ X - zg^i }`, /// where `i` ranges from `T * j` to `T * j + T - 1`, where `T` is the number of offsets in every frame. fn compute_trace_term( accumulator: &Polynomial>, - (j, t_j): (usize, &Polynomial>), - trace_frame_length: usize, + trace_term_poly: &Polynomial>, trace_terms_gammas: &[FieldElement], - trace_frame_evaluations: &[Vec>], - transition_offsets: &[usize], + trace_frame_evaluations: &[FieldElement], (z, primitive_root): (&FieldElement, &FieldElement), ) -> Polynomial> where FieldElement: AsBytes + Send + Sync, FieldElement: AsBytes + Send + Sync, { - let iter_trace_gammas = trace_terms_gammas.iter().skip(j * trace_frame_length); - let trace_int = trace_frame_evaluations[j] + let trace_int = trace_frame_evaluations .iter() - .zip(transition_offsets) - .zip(iter_trace_gammas) + .enumerate() + .zip(trace_terms_gammas) .fold( Polynomial::zero(), - |trace_agg, ((t_j_z, offset), trace_gamma)| { + |trace_agg, ((offset, trace_term_poly_evaluation), trace_gamma)| { // @@@ this can be pre-computed - let z_shifted = primitive_root.pow(*offset) * z; - let mut poly = t_j - t_j_z; + let z_shifted = primitive_root.pow(offset) * z; + let mut poly = trace_term_poly - trace_term_poly_evaluation; poly.ruffini_division_inplace(&z_shifted); trace_agg + poly * trace_gamma }, @@ -790,7 +864,7 @@ pub trait IsStarkProver { /// Generates a STARK proof for the trace `main_trace` with public inputs `pub_inputs`. /// Warning: the transcript must be safely initializated before passing it to this method. fn prove( - main_trace: &TraceTable, + trace: &mut TraceTable, pub_inputs: &A::PublicInputs, proof_options: &ProofOptions, mut transcript: impl IsTranscript, @@ -798,6 +872,7 @@ pub trait IsStarkProver { where A: Send + Sync, FieldElement: AsBytes + Send + Sync, + A::FieldExtension: IsFFTField, FieldElement: AsBytes + Send + Sync, { info!("Started proof generation..."); @@ -806,7 +881,7 @@ pub trait IsStarkProver { #[cfg(feature = "instruments")] let timer0 = Instant::now(); - let air = A::new(main_trace.n_rows(), pub_inputs, proof_options); + let air = A::new(trace.num_rows(), pub_inputs, proof_options); let domain = Domain::new(&air); #[cfg(feature = "instruments")] @@ -823,12 +898,8 @@ pub trait IsStarkProver { #[cfg(feature = "instruments")] let timer1 = Instant::now(); - let round_1_result = Self::round_1_randomized_air_with_preprocessing( - &air, - main_trace, - &domain, - &mut transcript, - )?; + let round_1_result = + Self::round_1_randomized_air_with_preprocessing(&air, trace, &domain, &mut transcript)?; #[cfg(debug_assertions)] validate_trace( @@ -1041,7 +1112,7 @@ mod tests { a1: Felt252::one(), }; let trace = simple_fibonacci::fibonacci_trace([Felt252::from(1), Felt252::from(1)], 8); - let trace_length = trace.n_rows(); + let trace_length = trace.num_rows(); let coset_offset = 3; let blowup_factor: usize = 2; let grinding_factor = 20; @@ -1083,8 +1154,10 @@ mod tests { #[test] fn test_evaluate_polynomial_on_lde_domain_on_trace_polys() { let trace = simple_fibonacci::fibonacci_trace([Felt252::from(1), Felt252::from(1)], 8); - let trace_length = trace.n_rows(); - let trace_polys = trace.compute_trace_polys::(); + + let trace_length = trace.num_rows(); + + let trace_polys = trace.compute_trace_polys_main::(); let coset_offset = Felt252::from(3); let blowup_factor: usize = 2; let domain_size = 8; @@ -1133,10 +1206,11 @@ mod tests { ProofOptions, [u8; 4], ) { - let trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::one(), 4); + let mut trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::one(), 4); let claimed_index = 3; - let claimed_value = trace.get_row(claimed_index)[0]; + let col = 0; + let claimed_value = trace.get_main(claimed_index, col).clone(); let mut proof_options = ProofOptions::default_test_options(); proof_options.blowup_factor = 4; proof_options.coset_offset = 3; @@ -1151,7 +1225,7 @@ mod tests { let transcript_init_seed = [0xca, 0xfe, 0xca, 0xfe]; let proof = Prover::>::prove( - &trace, + &mut trace, &pub_inputs, &proof_options, StoneProverTranscript::new(&transcript_init_seed), @@ -1529,10 +1603,11 @@ mod tests { ProofOptions, [u8; 4], ) { - let trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::from(12345), 512); + let mut trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::from(12345), 512); let claimed_index = 420; - let claimed_value = trace.get_row(claimed_index)[0]; + let col = 0; + let claimed_value = trace.get_main(claimed_index, col).clone(); let mut proof_options = ProofOptions::default_test_options(); proof_options.blowup_factor = 1 << 6; proof_options.coset_offset = 3; @@ -1547,7 +1622,7 @@ mod tests { let transcript_init_seed = [0xfa, 0xfa, 0xfa, 0xee]; let proof = Prover::>::prove( - &trace, + &mut trace, &pub_inputs, &proof_options, StoneProverTranscript::new(&transcript_init_seed), diff --git a/provers/stark/src/table.rs b/provers/stark/src/table.rs index 54a978a2c..215aa81d8 100644 --- a/provers/stark/src/table.rs +++ b/provers/stark/src/table.rs @@ -73,12 +73,12 @@ impl<'t, F: IsField> Table { &self.data[row_offset..row_offset + self.width] } - /// Given a row index, returns a mutable reference to that row as a slice of field elements. - pub fn get_row_mut(&mut self, row_idx: usize) -> &mut [FieldElement] { - let n_cols = self.width; - let row_offset = row_idx * n_cols; - &mut self.data[row_offset..row_offset + n_cols] - } + // /// Given a row index, returns a mutable reference to that row as a slice of field elements. + // pub fn get_row_mut(&mut self, row_idx: usize) -> &mut [FieldElement] { + // let n_cols = self.width; + // let row_offset = row_idx * n_cols; + // &mut self.data[row_offset..row_offset + n_cols] + // } /// Given a slice of field elements representing a row, appends it to /// the end of the table. @@ -105,12 +105,23 @@ impl<'t, F: IsField> Table { .collect() } + pub fn get_column(&self, col_idx: usize) -> Vec> { + (0..self.height) + .map(|row_idx| self.data[row_idx * self.width + col_idx].clone()) + .collect() + } + /// Given row and column indexes, returns the stored field element in that position of the table. pub fn get(&self, row: usize, col: usize) -> &FieldElement { let idx = row * self.width + col; &self.data[idx] } + pub fn set(&mut self, row: usize, col: usize, value: FieldElement) { + let idx = row * self.width + col; + self.data[idx] = value; + } + /// Given a step size, converts the given table into a `Frame`. pub fn into_frame(&'t self, main_trace_columns: usize, step_size: usize) -> Frame<'t, F, F> { debug_assert!(self.height % step_size == 0); diff --git a/provers/stark/src/tests/integration_tests.rs b/provers/stark/src/tests/integration_tests.rs index 7febbd28a..c7f2f6a4c 100644 --- a/provers/stark/src/tests/integration_tests.rs +++ b/provers/stark/src/tests/integration_tests.rs @@ -11,7 +11,7 @@ use crate::{ fibonacci_rap::{fibonacci_rap_trace, FibonacciRAP, FibonacciRAPPublicInputs}, quadratic_air::{self, QuadraticAIR, QuadraticPublicInputs}, simple_fibonacci::{self, FibonacciAIR, FibonacciPublicInputs}, - simple_periodic_cols::{self, SimplePeriodicAIR, SimplePeriodicPublicInputs}, + simple_periodic_cols::{self, SimplePeriodicAIR, SimplePeriodicPublicInputs}, // simple_periodic_cols::{self, SimplePeriodicAIR, SimplePeriodicPublicInputs}, }, proof::options::ProofOptions, prover::{IsStarkProver, Prover}, @@ -22,7 +22,7 @@ use crate::{ #[test_log::test] fn test_prove_fib() { - let trace = simple_fibonacci::fibonacci_trace([Felt252::from(1), Felt252::from(1)], 1024); + let mut trace = simple_fibonacci::fibonacci_trace([Felt252::from(1), Felt252::from(1)], 8); let proof_options = ProofOptions::default_test_options(); @@ -32,7 +32,7 @@ fn test_prove_fib() { }; let proof = Prover::>::prove( - &trace, + &mut trace, &pub_inputs, &proof_options, StoneProverTranscript::new(&[]), @@ -46,41 +46,9 @@ fn test_prove_fib() { )); } -#[test_log::test] -fn test_prove_fib17() { - type FE = FieldElement; - let trace = simple_fibonacci::fibonacci_trace([FE::from(1), FE::from(1)], 4); - - let proof_options = ProofOptions { - blowup_factor: 2, - fri_number_of_queries: 7, - coset_offset: 3, - grinding_factor: 1, - }; - - let pub_inputs = FibonacciPublicInputs { - a0: FE::one(), - a1: FE::one(), - }; - - let proof = Prover::>::prove( - &trace, - &pub_inputs, - &proof_options, - StoneProverTranscript::new(&[]), - ) - .unwrap(); - assert!(Verifier::>::verify( - &proof, - &pub_inputs, - &proof_options, - StoneProverTranscript::new(&[]), - )); -} - #[test_log::test] fn test_prove_simple_periodic_8() { - let trace = simple_periodic_cols::simple_periodic_trace::(8); + let mut trace = simple_periodic_cols::simple_periodic_trace::(8); let proof_options = ProofOptions::default_test_options(); @@ -90,7 +58,7 @@ fn test_prove_simple_periodic_8() { }; let proof = Prover::>::prove( - &trace, + &mut trace, &pub_inputs, &proof_options, StoneProverTranscript::new(&[]), @@ -106,7 +74,7 @@ fn test_prove_simple_periodic_8() { #[test_log::test] fn test_prove_simple_periodic_32() { - let trace = simple_periodic_cols::simple_periodic_trace::(32); + let mut trace = simple_periodic_cols::simple_periodic_trace::(32); let proof_options = ProofOptions::default_test_options(); @@ -116,7 +84,7 @@ fn test_prove_simple_periodic_32() { }; let proof = Prover::>::prove( - &trace, + &mut trace, &pub_inputs, &proof_options, StoneProverTranscript::new(&[]), @@ -132,7 +100,8 @@ fn test_prove_simple_periodic_32() { #[test_log::test] fn test_prove_fib_2_cols() { - let trace = fibonacci_2_columns::compute_trace([Felt252::from(1), Felt252::from(1)], 16); + let mut trace = fibonacci_2_columns::compute_trace([Felt252::from(1), Felt252::from(1)], 16); + let proof_options = ProofOptions::default_test_options(); let pub_inputs = FibonacciPublicInputs { a0: Felt252::one(), @@ -140,7 +109,7 @@ fn test_prove_fib_2_cols() { }; let proof = Prover::>::prove( - &trace, + &mut trace, &pub_inputs, &proof_options, StoneProverTranscript::new(&[]), @@ -157,10 +126,10 @@ fn test_prove_fib_2_cols() { #[test_log::test] fn test_prove_fib_2_cols_shifted() { - let trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::one(), 16); + let mut trace = fibonacci_2_cols_shifted::compute_trace(FieldElement::one(), 16); let claimed_index = 14; - let claimed_value = trace.get_row(claimed_index)[0]; + let claimed_value = trace.main_table.get_row(claimed_index)[0]; let proof_options = ProofOptions::default_test_options(); let pub_inputs = fibonacci_2_cols_shifted::PublicInputs { @@ -169,7 +138,7 @@ fn test_prove_fib_2_cols_shifted() { }; let proof = Prover::>::prove( - &trace, + &mut trace, &pub_inputs, &proof_options, StoneProverTranscript::new(&[]), @@ -185,7 +154,7 @@ fn test_prove_fib_2_cols_shifted() { #[test_log::test] fn test_prove_quadratic() { - let trace = quadratic_air::quadratic_trace(Felt252::from(3), 32); + let mut trace = quadratic_air::quadratic_trace(Felt252::from(3), 32); let proof_options = ProofOptions::default_test_options(); @@ -194,7 +163,7 @@ fn test_prove_quadratic() { }; let proof = Prover::>::prove( - &trace, + &mut trace, &pub_inputs, &proof_options, StoneProverTranscript::new(&[]), @@ -211,7 +180,7 @@ fn test_prove_quadratic() { #[test_log::test] fn test_prove_rap_fib() { let steps = 16; - let trace = fibonacci_rap_trace([Felt252::from(1), Felt252::from(1)], steps); + let mut trace = fibonacci_rap_trace([Felt252::from(1), Felt252::from(1)], steps); let proof_options = ProofOptions::default_test_options(); @@ -222,7 +191,7 @@ fn test_prove_rap_fib() { }; let proof = Prover::>::prove( - &trace, + &mut trace, &pub_inputs, &proof_options, StoneProverTranscript::new(&[]), @@ -239,14 +208,17 @@ fn test_prove_rap_fib() { #[test_log::test] fn test_prove_dummy() { let trace_length = 16; - let trace = dummy_air::dummy_trace(trace_length); + let mut trace = dummy_air::dummy_trace(trace_length); let proof_options = ProofOptions::default_test_options(); - let proof = - Prover::::prove(&trace, &(), &proof_options, StoneProverTranscript::new(&[])) - .unwrap(); - + let proof = Prover::::prove( + &mut trace, + &(), + &proof_options, + StoneProverTranscript::new(&[]), + ) + .unwrap(); assert!(Verifier::::verify( &proof, &(), @@ -257,12 +229,16 @@ fn test_prove_dummy() { #[test_log::test] fn test_prove_bit_flags() { - let trace = bit_flags::bit_prefix_flag_trace(32); + let mut trace = bit_flags::bit_prefix_flag_trace(32); let proof_options = ProofOptions::default_test_options(); - let proof = - Prover::::prove(&trace, &(), &proof_options, StoneProverTranscript::new(&[])) - .unwrap(); + let proof = Prover::::prove( + &mut trace, + &(), + &proof_options, + StoneProverTranscript::new(&[]), + ) + .unwrap(); assert!(Verifier::::verify( &proof, diff --git a/provers/stark/src/trace.rs b/provers/stark/src/trace.rs index b9e3de0cf..419d612ff 100644 --- a/provers/stark/src/trace.rs +++ b/provers/stark/src/trace.rs @@ -17,41 +17,78 @@ use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; /// STARK protocol, such as the step size (number of consecutive rows of the table) /// of the computation being proven. #[derive(Clone, Default, Debug, PartialEq, Eq)] -pub struct TraceTable { - pub table: Table, - pub step_size: usize, +pub struct TraceTable +where + E: IsField, + F: IsSubFieldOf + IsField, +{ + pub main_table: Table, + pub aux_table: Table, pub num_main_columns: usize, pub num_aux_columns: usize, + pub step_size: usize, } -impl TraceTable { +impl TraceTable +where + E: IsField, + F: IsSubFieldOf + IsFFTField, +{ pub fn new( - data: Vec>, + main_data: Vec>, + aux_data: Vec>, num_main_columns: usize, num_aux_columns: usize, step_size: usize, ) -> Self { - let num_columns = num_main_columns + num_aux_columns; - let table = Table::new(data, num_columns); + let main_table = Table::new(main_data, num_main_columns); + let aux_table = Table::new(aux_data, num_aux_columns); + Self { - table, + main_table, + aux_table, num_main_columns, num_aux_columns, step_size, } } - pub fn from_columns( - columns: Vec>>, + /// Creates a new TraceTable from from a one-dimensional array in row major order and the intended width of the table. + /// Step size is how many are needed to represent a state of the VM + pub fn new_main( + main_data: Vec>, num_main_columns: usize, step_size: usize, ) -> Self { - println!("COLUMNS LEN: {}", columns.len()); - println!("NUM MAIN COLUMNS: {}", num_main_columns); - let num_aux_columns = columns.len() - num_main_columns; - let table = Table::from_columns(columns); + let num_aux_columns = 0; + let main_table = Table::new(main_data, num_main_columns); + let aux_table = Table::new(Vec::new(), num_aux_columns); + Self { - table, + main_table, + aux_table, + num_main_columns, + num_aux_columns, + step_size, + } + } + + /// Creates a new TraceTable from its colummns + /// Step size is how many are needed to represent a state of the VM + pub fn from_columns( + main_columns: Vec>>, + aux_columns: Vec>>, + step_size: usize, + ) -> Self { + let num_main_columns = main_columns.len(); + let num_aux_columns = aux_columns.len(); + + let main_table = Table::from_columns(main_columns); + let aux_table = Table::from_columns(aux_columns); + + Self { + main_table, + aux_table, num_main_columns, num_aux_columns, step_size, @@ -61,10 +98,12 @@ impl TraceTable { pub fn from_columns_main(columns: Vec>>, step_size: usize) -> Self { let num_main_columns = columns.len(); let num_aux_columns = 0; - let table = Table::from_columns(columns); + let main_table = Table::from_columns(columns); + let aux_table = Table::from_columns(Vec::new()); Self { - table, + main_table, + aux_table, num_main_columns, num_aux_columns, step_size, @@ -72,20 +111,20 @@ impl TraceTable { } pub fn empty() -> Self { - Self::new(Vec::new(), 0, 0, 0) + Self::new(Vec::new(), Vec::new(), 0, 0, 0) } pub fn is_empty(&self) -> bool { - self.table.width == 0 + self.main_table.width == 0 && self.aux_table.width == 0 } - pub fn n_rows(&self) -> usize { - self.table.height + pub fn num_rows(&self) -> usize { + self.main_table.height } pub fn num_steps(&self) -> usize { - debug_assert!((self.table.height % self.step_size) == 0); - self.table.height / self.step_size + debug_assert!((self.main_table.height % self.step_size) == 0); + self.main_table.height / self.step_size } /// Given a particular step of the computation represented on the trace, @@ -94,52 +133,59 @@ impl TraceTable { self.step_size * step } - pub fn n_cols(&self) -> usize { - self.table.width + pub fn num_cols(&self) -> usize { + self.main_table.width + self.aux_table.width } - pub fn rows(&self) -> Vec>> { - self.table.rows() + pub fn columns_main(&self) -> Vec>> { + self.main_table.columns() } - pub fn get_row(&self, row_idx: usize) -> &[FieldElement] { - self.table.get_row(row_idx) + pub fn columns_aux(&self) -> Vec>> { + self.aux_table.columns() } - pub fn get_row_mut(&mut self, row_idx: usize) -> &mut [FieldElement] { - self.table.get_row_mut(row_idx) + /// Given a row and a column index, gives stored value in that position + pub fn get_main(&self, row: usize, col: usize) -> &FieldElement { + self.main_table.get(row, col) } - pub fn last_row(&self) -> &[FieldElement] { - self.get_row(self.n_rows() - 1) + /// Given a row and a column index, gives stored value in that position + pub fn get_aux(&self, row: usize, col: usize) -> &FieldElement { + self.aux_table.get(row, col) } - pub fn columns(&self) -> Vec>> { - self.table.columns() + pub fn set_main(&mut self, row: usize, col: usize, value: FieldElement) { + self.main_table.set(row, col, value); } - /// Given a slice of integer numbers representing column indexes, merge these columns into - /// a one-dimensional vector. - /// - /// The particular way they are merged is not really important since this function is used to - /// aggreagate values distributed across various columns with no importance on their ordering, - /// such as to sort them. - pub fn merge_columns(&self, column_indexes: &[usize]) -> Vec> { - let mut data = Vec::with_capacity(self.n_rows() * column_indexes.len()); - for row_index in 0..self.n_rows() { - for column in column_indexes { - data.push(self.table.data[row_index * self.n_cols() + column].clone()); - } - } - data + pub fn set_aux(&mut self, row: usize, col: usize, value: FieldElement) { + self.aux_table.set(row, col, value); + } + + pub fn allocate_with_zeros( + num_steps: usize, + num_main_columns: usize, + num_aux_columns: usize, + step_size: usize, + ) -> TraceTable { + let main_data = vec![FieldElement::::zero(); step_size * num_steps * num_main_columns]; + let aux_data = vec![FieldElement::::zero(); step_size * num_steps * num_aux_columns]; + TraceTable::new( + main_data, + aux_data, + num_main_columns, + num_aux_columns, + step_size, + ) } - pub fn compute_trace_polys(&self) -> Vec>> + pub fn compute_trace_polys_main(&self) -> Vec>> where S: IsFFTField + IsSubFieldOf, FieldElement: Send + Sync, { - let columns = self.columns(); + let columns = self.columns_main(); #[cfg(feature = "parallel")] let iter = columns.par_iter(); #[cfg(not(feature = "parallel"))] @@ -150,44 +196,34 @@ impl TraceTable { .unwrap() } - /// Given the padding length, appends the last row of the trace table - /// that many times. - /// This is useful for example when the desired trace length should be power - /// of two, and only the last row is the one that can be appended without affecting - /// the integrity of the constraints. - pub fn pad_with_last_row(&mut self, padding_len: usize) { - let last_row = self.last_row().to_vec(); - (0..padding_len).for_each(|_| { - self.table.append_row(&last_row); - }) + pub fn compute_trace_polys_aux(&self) -> Vec>> + where + S: IsFFTField + IsSubFieldOf, + FieldElement: Send + Sync, + { + let columns = self.columns_aux(); + #[cfg(feature = "parallel")] + let iter = columns.par_iter(); + #[cfg(not(feature = "parallel"))] + let iter = columns.iter(); + + iter.map(|col| Polynomial::interpolate_fft::(col)) + .collect::>>, FFTError>>() + .unwrap() } - /// Given a row index, a column index and a value, tries to set that location - /// of the trace with the given value. - /// The row_idx passed as argument may be greater than the max row index by 1. In this case, - /// last row of the trace is cloned, and the value is set in that cloned row. Then, the row is - /// appended to the end of the trace. - pub fn set_or_extend(&mut self, row_idx: usize, col_idx: usize, value: &FieldElement) { - debug_assert!(col_idx < self.n_cols()); - // NOTE: This is not very nice, but for how the function is being used at the moment, - // the passed `row_idx` should never be greater than `self.n_rows() + 1`. This is just - // an integrity check for ease in the developing process, we should think a better alternative - // in the future. - debug_assert!(row_idx <= self.n_rows() + 1); - if row_idx >= self.n_rows() { - let mut last_row = self.last_row().to_vec(); - last_row[col_idx] = value.clone(); - self.table.append_row(&last_row) - } else { - let row = self.get_row_mut(row_idx); - row[col_idx] = value.clone(); - } + pub fn get_column_main(&self, col_idx: usize) -> Vec> { + self.main_table.get_column(col_idx) + } + + pub fn get_column_aux(&self, col_idx: usize) -> Vec> { + self.aux_table.get_column(col_idx) } } pub struct LDETraceTable where E: IsField, - F: IsSubFieldOf, + F: IsSubFieldOf + IsField, { pub(crate) main_table: Table, pub(crate) aux_table: Table, @@ -334,7 +370,10 @@ where Table::new(table_data, table_width) } -pub fn columns2rows(columns: Vec>>) -> Vec>> { +pub fn columns2rows(columns: Vec>) -> Vec> +where + F: Clone, +{ let num_rows = columns[0].len(); let num_cols = columns.len(); @@ -347,20 +386,20 @@ pub fn columns2rows(columns: Vec>>) -> Vec; +// #[cfg(test)] +// mod test { +// use super::TraceTable; +// use lambdaworks_math::field::{element::FieldElement, fields::u64_prime_field::F17}; +// type FE = FieldElement; - #[test] - fn test_cols() { - let col_1 = vec![FE::from(1), FE::from(2), FE::from(5), FE::from(13)]; - let col_2 = vec![FE::from(1), FE::from(3), FE::from(8), FE::from(21)]; +// #[test] +// fn test_cols() { +// let col_1 = vec![FE::from(1), FE::from(2), FE::from(5), FE::from(13)]; +// let col_2 = vec![FE::from(1), FE::from(3), FE::from(8), FE::from(21)]; - let trace_table = TraceTable::from_columns(vec![col_1.clone(), col_2.clone()], 2, 1); - let res_cols = trace_table.columns(); +// let trace_table = TraceTable::from_columns(vec![col_1.clone(), col_2.clone()], 2, 1); +// let res_cols = trace_table.columns(); - assert_eq!(res_cols, vec![col_1, col_2]); - } -} +// assert_eq!(res_cols, vec![col_1, col_2]); +// } +// } diff --git a/provers/stark/src/traits.rs b/provers/stark/src/traits.rs index d33343bb2..56a96b89b 100644 --- a/provers/stark/src/traits.rs +++ b/provers/stark/src/traits.rs @@ -34,10 +34,11 @@ pub trait AIR { fn build_auxiliary_trace( &self, - _main_trace: &TraceTable, + _main_trace: &mut TraceTable, _rap_challenges: &[FieldElement], - ) -> TraceTable { - TraceTable::empty() + ) where + Self::FieldExtension: IsFFTField, + { } fn build_rap_challenges( @@ -47,8 +48,14 @@ pub trait AIR { Vec::new() } + /// Returns the amount main trace columns and auxiliary trace columns fn trace_layout(&self) -> (usize, usize); + fn has_trace_interaction(&self) -> bool { + let (_main_trace_columns, aux_trace_columns) = self.trace_layout(); + aux_trace_columns != 0 + } + fn num_auxiliary_rap_columns(&self) -> usize { self.trace_layout().1 } @@ -145,8 +152,6 @@ pub trait AIR { &self, ) -> &Vec>>; - /// Computes the unique zerofier evaluations for all transitions constraints. - /// Returns a vector of vectors, where each inner vector contains the unique zerofier evaluations for a given constraint fn transition_zerofier_evaluations( &self, domain: &Domain, diff --git a/provers/stark/src/transcript.rs b/provers/stark/src/transcript.rs index 239c338d6..abd040faf 100644 --- a/provers/stark/src/transcript.rs +++ b/provers/stark/src/transcript.rs @@ -9,7 +9,7 @@ use lambdaworks_math::{ }; use sha3::{Digest, Keccak256}; -/// A transcript implementing `IsStarkTranscript` and compatible with Stone (https://github.com/starkware-libs/stone-prover). +/// A transcript implementing `IsTranscript` and compatible with Stone (https://github.com/starkware-libs/stone-prover). pub struct StoneProverTranscript { state: [u8; 32], seed_increment: U256, diff --git a/provers/stark/src/verifier.rs b/provers/stark/src/verifier.rs index ea25dbe79..9f7a32df3 100644 --- a/provers/stark/src/verifier.rs +++ b/provers/stark/src/verifier.rs @@ -141,20 +141,21 @@ pub trait IsStarkVerifier { // ==========| Round 4 |========== // =================================== - let n_terms_composition_poly = proof.composition_poly_parts_ood_evaluation.len(); - let n_terms_trace = air.context().transition_offsets.len() * air.context().trace_columns; + let num_terms_composition_poly = proof.composition_poly_parts_ood_evaluation.len(); + let num_terms_trace = + air.context().transition_offsets.len() * A::STEP_SIZE * air.context().trace_columns; let gamma = transcript.sample_field_element(); // <<<< Receive challenges: 𝛾, 𝛾' let mut deep_composition_coefficients: Vec<_> = core::iter::successors(Some(FieldElement::one()), |x| Some(x * &gamma)) - .take(n_terms_composition_poly + n_terms_trace) + .take(num_terms_composition_poly + num_terms_trace) .collect(); let trace_term_coeffs: Vec<_> = deep_composition_coefficients - .drain(..n_terms_trace) + .drain(..num_terms_trace) .collect::>() - .chunks(air.context().transition_offsets.len()) + .chunks(air.context().transition_offsets.len() * A::STEP_SIZE) .map(|chunk| chunk.to_vec()) .collect(); @@ -666,15 +667,23 @@ pub trait IsStarkVerifier { lde_trace_evaluations: &[FieldElement], lde_composition_poly_parts_evaluation: &[FieldElement], ) -> FieldElement { - let mut denoms_trace = (0..proof.trace_ood_evaluations.height) + let ood_evaluations_table_height = proof.trace_ood_evaluations.height; + let ood_evaluations_table_width = proof.trace_ood_evaluations.width; + let trace_term_coeffs = &challenges.trace_term_coeffs; + debug_assert_eq!( + ood_evaluations_table_height * ood_evaluations_table_width, + trace_term_coeffs.len() * trace_term_coeffs[0].len() + ); + + let mut denoms_trace = (0..ood_evaluations_table_height) .map(|row_idx| evaluation_point - primitive_root.pow(row_idx as u64) * &challenges.z) .collect::>>(); FieldElement::inplace_batch_inverse(&mut denoms_trace).unwrap(); - let trace_term = (0..proof.trace_ood_evaluations.width) + let trace_term = (0..ood_evaluations_table_width) .zip(&challenges.trace_term_coeffs) .fold(FieldElement::zero(), |trace_terms, (col_idx, coeff_row)| { - let trace_i = (0..proof.trace_ood_evaluations.height).zip(coeff_row).fold( + let trace_i = (0..ood_evaluations_table_height).zip(coeff_row).fold( FieldElement::zero(), |trace_t, (row_idx, coeff)| { let poly_evaluation = (lde_trace_evaluations[col_idx].clone() diff --git a/winterfell_adapter/src/adapter/mod.rs b/winterfell_adapter/src/adapter/mod.rs new file mode 100644 index 000000000..72fb8d719 --- /dev/null +++ b/winterfell_adapter/src/adapter/mod.rs @@ -0,0 +1,87 @@ +use lambdaworks_math::{field::fields::winterfell::QuadFelt, traits::ByteConversion}; +use miden_core::Felt; +use sha3::{Digest, Keccak256}; +use stark_platinum_prover::{fri::FieldElement, transcript::IsStarkTranscript}; +use winter_math::StarkField; + +pub mod air; +pub mod public_inputs; + +pub struct FeltTranscript { + hasher: Keccak256, +} + +impl FeltTranscript { + pub fn new(data: &[u8]) -> Self { + let mut res = Self { + hasher: Keccak256::new(), + }; + res.append_bytes(data); + res + } +} + +impl IsTranscript for FeltTranscript { + fn append_field_element(&mut self, element: &FieldElement) { + self.append_bytes(&element.value().to_bytes_be()); + } + + fn append_bytes(&mut self, new_bytes: &[u8]) { + self.hasher.update(&mut new_bytes.to_owned()); + } + + fn state(&self) -> [u8; 32] { + self.hasher.clone().finalize().into() + } + + fn sample_field_element(&mut self) -> FieldElement { + let mut bytes = self.state()[..8].try_into().unwrap(); + let mut x = u64::from_be_bytes(bytes); + while x >= Felt::MODULUS { + self.append_bytes(&bytes); + bytes = self.state()[..8].try_into().unwrap(); + x = u64::from_be_bytes(bytes); + } + FieldElement::const_from_raw(Felt::new(x)) + } + + fn sample_u64(&mut self, upper_bound: u64) -> u64 { + u64::from_be_bytes(self.state()[..8].try_into().unwrap()) % upper_bound + } +} + +pub struct QuadFeltTranscript { + felt_transcript: FeltTranscript, +} + +impl QuadFeltTranscript { + pub fn new(data: &[u8]) -> Self { + Self { + felt_transcript: FeltTranscript::new(data), + } + } +} + +impl IsTranscript for QuadFeltTranscript { + fn append_field_element(&mut self, element: &FieldElement) { + self.append_bytes(&element.value().to_bytes_be()); + } + + fn append_bytes(&mut self, new_bytes: &[u8]) { + self.felt_transcript.append_bytes(new_bytes); + } + + fn state(&self) -> [u8; 32] { + self.felt_transcript.state() + } + + fn sample_field_element(&mut self) -> FieldElement { + let x = self.felt_transcript.sample_field_element(); + let y = self.felt_transcript.sample_field_element(); + FieldElement::const_from_raw(QuadFelt::new(*x.value(), *y.value())) + } + + fn sample_u64(&mut self, upper_bound: u64) -> u64 { + u64::from_be_bytes(self.state()[..8].try_into().unwrap()) % upper_bound + } +}