From beeede72c0ce14918a15b18804250d20fa1dd1cd Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Tue, 11 Feb 2025 16:07:56 -0500 Subject: [PATCH 01/21] feat: implement `BusMessage` and `BusDebugger` --- processor/src/chiplets/aux_trace/mod.rs | 3 +- processor/src/debug.rs | 110 +++++++++++++++++++++++- 2 files changed, 110 insertions(+), 3 deletions(-) diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index d00987fd94..e4e2765090 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -67,8 +67,7 @@ impl AuxTraceBuilder { let b_chip = bus_col_builder.build_aux_column(main_trace, rand_elements); debug_assert_eq!(*t_chip.last().unwrap(), E::ONE); - // TODO: Fix and re-enable after testing with miden-base - // debug_assert_eq!(*b_chip.last().unwrap(), E::ONE); + debug_assert_eq!(*b_chip.last().unwrap(), E::ONE); vec![t_chip, b_chip] } } diff --git a/processor/src/debug.rs b/processor/src/debug.rs index 4826811a82..e4b321a2c4 100644 --- a/processor/src/debug.rs +++ b/processor/src/debug.rs @@ -1,11 +1,12 @@ use alloc::{ + boxed::Box, string::{String, ToString}, vec::Vec, }; use core::fmt; use miden_air::RowIndex; -use vm_core::{AssemblyOp, Operation, StackOutputs}; +use vm_core::{AssemblyOp, FieldElement, Operation, StackOutputs}; use crate::{ range::RangeChecker, system::ContextId, Chiplets, ChipletsLengths, Decoder, ExecutionError, @@ -313,3 +314,110 @@ impl AsRef for AsmOpInfo { &self.asmop } } + +// BUS DEBUGGING +// ================================================================= + +/// A message that can be sent on a bus. +pub trait BusMessage>: fmt::Display { + /// The concrete value that this message evaluates to. + fn value(&self, alphas: &[E]) -> E; + + /// The source of this message (e.g. "mload" or "memory chiplet"). + fn source(&self) -> &str; +} + +/// Note: we use `Vec` internall instead of a `BTreeMap` as a workaround for field elements not +/// implementing `Ord`. Since this is only used in debug/test code, this is acceptable. +pub struct BusDebugger> { + pub bus_name: String, + pub outstanding_requests: Vec<(E, Box>)>, + pub outstanding_responses: Vec<(E, Box>)>, +} + +impl BusDebugger +where + E: FieldElement, +{ + pub fn new(bus_name: String) -> Self { + Self { + bus_name, + outstanding_requests: Vec::new(), + outstanding_responses: Vec::new(), + } + } +} + +impl BusDebugger +where + E: FieldElement, +{ + /// Attempts to match the request with an existing response. If a match is found, the response + /// is removed from the list of outstanding responses. Otherwise, the request is added to the + /// list of outstanding requests. + pub fn add_request(&mut self, request_msg: Box>, alphas: &[E]) { + let msg_value = request_msg.value(alphas); + + if let Some(pos) = + self.outstanding_responses.iter().position(|(value, _)| *value == msg_value) + { + self.outstanding_responses.swap_remove(pos); + } else { + self.outstanding_requests.push((msg_value, request_msg)); + } + } + + /// Attempts to match the response with an existing request. If a match is found, the request is + /// removed from the list of outstanding requests. Otherwise, the response is added to the list + /// of outstanding responses. + pub fn add_response(&mut self, response_msg: Box>, alphas: &[E]) { + let msg_value = response_msg.value(alphas); + + if let Some(pos) = + self.outstanding_requests.iter().position(|(value, _)| *value == msg_value) + { + self.outstanding_requests.swap_remove(pos); + } else { + self.outstanding_responses.push((msg_value, response_msg)); + } + } + + /// Returns true if there are no outstanding requests or responses. + /// + /// This is meant to be called at the end of filling the bus. If there are any outstanding + /// requests or responses, it means that there is a mismatch between the requests and responses, + /// and the test should fail. The `Debug` implementation for `BusDebugger` will print out the + /// outstanding requests and responses. + pub fn is_empty(&self) -> bool { + self.outstanding_requests.is_empty() && self.outstanding_responses.is_empty() + } +} + +impl fmt::Display for BusDebugger +where + E: FieldElement, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.is_empty() { + writeln!(f, "Bus '{}' is empty.", self.bus_name)?; + } else { + writeln!(f, "Bus '{}' construction failed.", self.bus_name)?; + + if !self.outstanding_requests.is_empty() { + writeln!(f, "The following requests are still outstanding:")?; + for (_value, msg) in &self.outstanding_requests { + writeln!(f, "- {}: {}", msg.source(), msg)?; + } + } + + if !self.outstanding_responses.is_empty() { + writeln!(f, "\nThe following responses are still outstanding:")?; + for (_value, msg) in &self.outstanding_responses { + writeln!(f, "- {}: {}", msg.source(), msg)?; + } + } + } + + Ok(()) + } +} From 5303ad2d20b458b3663ad2ac300ce580dea94c40 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Tue, 11 Feb 2025 16:42:44 -0500 Subject: [PATCH 02/21] feat: integrate `BusDebugger` in `AuxColumnBuilder` --- processor/src/chiplets/aux_trace/mod.rs | 40 +++++++++++++-- .../src/decoder/aux_trace/block_hash_table.rs | 24 +++++++-- .../decoder/aux_trace/block_stack_table.rs | 17 ++++++- .../src/decoder/aux_trace/op_group_table.rs | 17 ++++++- processor/src/stack/aux_trace.rs | 18 +++++-- processor/src/trace/utils.rs | 51 +++++++++++++++---- 6 files changed, 141 insertions(+), 26 deletions(-) diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index e4e2765090..b3344952a4 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -27,6 +27,7 @@ use vm_core::{ }; use super::{super::trace::AuxColumnBuilder, Felt, FieldElement}; +use crate::debug::BusDebugger; // CONSTANTS // ================================================================================================ @@ -88,7 +89,12 @@ impl ChipletsVTableColBuilder { } impl> AuxColumnBuilder for ChipletsVTableColBuilder { - fn init_requests(&self, _main_trace: &MainTrace, alphas: &[E]) -> E { + fn init_requests( + &self, + _main_trace: &MainTrace, + alphas: &[E], + _debugger: &mut BusDebugger, + ) -> E { let mut requests = E::ONE; for (idx, proc_hash) in self.kernel.proc_hashes().iter().enumerate() { requests *= alphas[0] @@ -101,11 +107,23 @@ impl> AuxColumnBuilder for ChipletsVTableCo requests } - fn get_requests_at(&self, main_trace: &MainTrace, alphas: &[E], row: RowIndex) -> E { + fn get_requests_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, + ) -> E { chiplets_vtable_remove_sibling(main_trace, alphas, row) } - fn get_responses_at(&self, main_trace: &MainTrace, alphas: &[E], row: RowIndex) -> E { + fn get_responses_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, + ) -> E { chiplets_vtable_add_sibling(main_trace, alphas, row) * build_kernel_procedure_table_inclusions(main_trace, alphas, row) } @@ -276,7 +294,13 @@ pub struct BusColumnBuilder {} impl> AuxColumnBuilder for BusColumnBuilder { /// Constructs the requests made by the VM-components to the chiplets at `row`. - fn get_requests_at(&self, main_trace: &MainTrace, alphas: &[E], row: RowIndex) -> E + fn get_requests_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, + ) -> E where E: FieldElement, { @@ -323,7 +347,13 @@ impl> AuxColumnBuilder for BusColumnBuilder } /// Constructs the responses from the chiplets to the other VM-components at `row`. - fn get_responses_at(&self, main_trace: &MainTrace, alphas: &[E], row: RowIndex) -> E + fn get_responses_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, + ) -> E where E: FieldElement, { diff --git a/processor/src/decoder/aux_trace/block_hash_table.rs b/processor/src/decoder/aux_trace/block_hash_table.rs index 75d831b1fb..f09145d67d 100644 --- a/processor/src/decoder/aux_trace/block_hash_table.rs +++ b/processor/src/decoder/aux_trace/block_hash_table.rs @@ -5,6 +5,7 @@ use vm_core::{ }; use super::{AuxColumnBuilder, Felt, FieldElement, MainTrace, ONE}; +use crate::debug::BusDebugger; // BLOCK HASH TABLE COLUMN BUILDER // ================================================================================================ @@ -24,12 +25,23 @@ use super::{AuxColumnBuilder, Felt, FieldElement, MainTrace, ONE}; pub struct BlockHashTableColumnBuilder {} impl> AuxColumnBuilder for BlockHashTableColumnBuilder { - fn init_responses(&self, main_trace: &MainTrace, alphas: &[E]) -> E { + fn init_responses( + &self, + main_trace: &MainTrace, + alphas: &[E], + _debugger: &mut BusDebugger, + ) -> E { BlockHashTableRow::table_init(main_trace).collapse(alphas) } /// Removes a row from the block hash table. - fn get_requests_at(&self, main_trace: &MainTrace, alphas: &[E], row: RowIndex) -> E { + fn get_requests_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, + ) -> E { let op_code = main_trace.get_op_code(row).as_int() as u8; match op_code { @@ -39,7 +51,13 @@ impl> AuxColumnBuilder for BlockHashTableCo } /// Adds a row to the block hash table. - fn get_responses_at(&self, main_trace: &MainTrace, alphas: &[E], row: RowIndex) -> E { + fn get_responses_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, + ) -> E { let op_code = main_trace.get_op_code(row).as_int() as u8; match op_code { diff --git a/processor/src/decoder/aux_trace/block_stack_table.rs b/processor/src/decoder/aux_trace/block_stack_table.rs index e59c668617..b34a9a342a 100644 --- a/processor/src/decoder/aux_trace/block_stack_table.rs +++ b/processor/src/decoder/aux_trace/block_stack_table.rs @@ -5,6 +5,7 @@ use vm_core::{ }; use super::{AuxColumnBuilder, Felt, FieldElement, MainTrace, ONE, ZERO}; +use crate::debug::BusDebugger; // BLOCK STACK TABLE COLUMN BUILDER // ================================================================================================ @@ -16,7 +17,13 @@ pub struct BlockStackColumnBuilder {} impl> AuxColumnBuilder for BlockStackColumnBuilder { /// Removes a row from the block stack table. - fn get_requests_at(&self, main_trace: &MainTrace, alphas: &[E], i: RowIndex) -> E { + fn get_requests_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + i: RowIndex, + _debugger: &mut BusDebugger, + ) -> E { let op_code_felt = main_trace.get_op_code(i); let op_code = op_code_felt.as_int() as u8; @@ -28,7 +35,13 @@ impl> AuxColumnBuilder for BlockStackColumn } /// Adds a row to the block stack table. - fn get_responses_at(&self, main_trace: &MainTrace, alphas: &[E], i: RowIndex) -> E { + fn get_responses_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + i: RowIndex, + _debugger: &mut BusDebugger, + ) -> E { let op_code_felt = main_trace.get_op_code(i); let op_code = op_code_felt.as_int() as u8; diff --git a/processor/src/decoder/aux_trace/op_group_table.rs b/processor/src/decoder/aux_trace/op_group_table.rs index 5800a6b2e2..7c68819dc0 100644 --- a/processor/src/decoder/aux_trace/op_group_table.rs +++ b/processor/src/decoder/aux_trace/op_group_table.rs @@ -5,6 +5,7 @@ use miden_air::{ use vm_core::{OPCODE_EMIT, OPCODE_PUSH, OPCODE_RESPAN, OPCODE_SPAN}; use super::{AuxColumnBuilder, Felt, FieldElement, MainTrace, ONE}; +use crate::debug::BusDebugger; // OP GROUP TABLE COLUMN // ================================================================================================ @@ -16,7 +17,13 @@ pub struct OpGroupTableColumnBuilder {} impl> AuxColumnBuilder for OpGroupTableColumnBuilder { /// Removes a row from the block hash table. - fn get_requests_at(&self, main_trace: &MainTrace, alphas: &[E], i: RowIndex) -> E { + fn get_requests_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + i: RowIndex, + _debugger: &mut BusDebugger, + ) -> E { let delete_group_flag = main_trace.delta_group_count(i) * main_trace.is_in_span(i); if delete_group_flag == ONE { @@ -27,7 +34,13 @@ impl> AuxColumnBuilder for OpGroupTableColu } /// Adds a row to the block hash table. - fn get_responses_at(&self, main_trace: &MainTrace, alphas: &[E], i: RowIndex) -> E { + fn get_responses_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + i: RowIndex, + _debugger: &mut BusDebugger, + ) -> E { let op_code_felt = main_trace.get_op_code(i); let op_code = op_code_felt.as_int() as u8; diff --git a/processor/src/stack/aux_trace.rs b/processor/src/stack/aux_trace.rs index 8c34985756..09ab0f6159 100644 --- a/processor/src/stack/aux_trace.rs +++ b/processor/src/stack/aux_trace.rs @@ -4,7 +4,7 @@ use miden_air::{trace::main_trace::MainTrace, RowIndex}; use vm_core::OPCODE_DYNCALL; use super::{Felt, FieldElement, OverflowTableRow}; -use crate::trace::AuxColumnBuilder; +use crate::{debug::BusDebugger, trace::AuxColumnBuilder}; // AUXILIARY TRACE BUILDER // ================================================================================================ @@ -30,7 +30,13 @@ impl AuxTraceBuilder { impl> AuxColumnBuilder for AuxTraceBuilder { /// Removes a row from the stack overflow table. - fn get_requests_at(&self, main_trace: &MainTrace, alphas: &[E], i: RowIndex) -> E { + fn get_requests_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + i: RowIndex, + _debugger: &mut BusDebugger, + ) -> E { let is_left_shift = main_trace.is_left_shift(i); let is_dyncall = main_trace.get_op_code(i) == OPCODE_DYNCALL.into(); let is_non_empty_overflow = main_trace.is_non_empty_overflow(i); @@ -53,7 +59,13 @@ impl> AuxColumnBuilder for AuxTraceBuilder } /// Adds a row to the stack overflow table. - fn get_responses_at(&self, main_trace: &MainTrace, alphas: &[E], i: RowIndex) -> E { + fn get_responses_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + i: RowIndex, + _debugger: &mut BusDebugger, + ) -> E { let is_right_shift = main_trace.is_right_shift(i); if is_right_shift { diff --git a/processor/src/trace/utils.rs b/processor/src/trace/utils.rs index bee240455d..f653f3e0a0 100644 --- a/processor/src/trace/utils.rs +++ b/processor/src/trace/utils.rs @@ -1,12 +1,13 @@ use alloc::vec::Vec; use core::slice; +use std::string::ToString; use miden_air::{trace::main_trace::MainTrace, RowIndex}; #[cfg(test)] use vm_core::{utils::ToElements, Operation}; use super::{Felt, FieldElement, NUM_RAND_ROWS}; -use crate::{chiplets::Chiplets, utils::uninit_vector}; +use crate::{chiplets::Chiplets, debug::BusDebugger, utils::uninit_vector}; // TRACE FRAGMENT // ================================================================================================ @@ -209,18 +210,40 @@ pub trait AuxColumnBuilder> { // REQUIRED METHODS // -------------------------------------------------------------------------------------------- - fn get_requests_at(&self, main_trace: &MainTrace, alphas: &[E], row: RowIndex) -> E; - - fn get_responses_at(&self, main_trace: &MainTrace, alphas: &[E], row: RowIndex) -> E; + fn get_requests_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + debugger: &mut BusDebugger, + ) -> E; + + fn get_responses_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + debugger: &mut BusDebugger, + ) -> E; // PROVIDED METHODS // -------------------------------------------------------------------------------------------- - fn init_requests(&self, _main_trace: &MainTrace, _alphas: &[E]) -> E { + fn init_requests( + &self, + _main_trace: &MainTrace, + _alphas: &[E], + _debugger: &mut BusDebugger, + ) -> E { E::ONE } - fn init_responses(&self, _main_trace: &MainTrace, _alphas: &[E]) -> E { + fn init_responses( + &self, + _main_trace: &MainTrace, + _alphas: &[E], + _debugger: &mut BusDebugger, + ) -> E { E::ONE } @@ -228,16 +251,18 @@ pub trait AuxColumnBuilder> { fn build_aux_column(&self, main_trace: &MainTrace, alphas: &[E]) -> Vec { let mut responses_prod: Vec = unsafe { uninit_vector(main_trace.num_rows()) }; let mut requests: Vec = unsafe { uninit_vector(main_trace.num_rows()) }; + let mut bus_debugger = BusDebugger::new("chiplets bus".to_string()); - responses_prod[0] = self.init_responses(main_trace, alphas); - requests[0] = self.init_requests(main_trace, alphas); + responses_prod[0] = self.init_responses(main_trace, alphas, &mut bus_debugger); + requests[0] = self.init_requests(main_trace, alphas, &mut bus_debugger); let mut requests_running_prod = requests[0]; for row_idx in 0..main_trace.num_rows() - 1 { let row = row_idx.into(); - responses_prod[row_idx + 1] = - responses_prod[row_idx] * self.get_responses_at(main_trace, alphas, row); - requests[row_idx + 1] = self.get_requests_at(main_trace, alphas, row); + responses_prod[row_idx + 1] = responses_prod[row_idx] + * self.get_responses_at(main_trace, alphas, row, &mut bus_debugger); + requests[row_idx + 1] = + self.get_requests_at(main_trace, alphas, row, &mut bus_debugger); requests_running_prod *= requests[row_idx + 1]; } @@ -247,6 +272,10 @@ pub trait AuxColumnBuilder> { result_aux_column[i] *= requests_running_divisor; requests_running_divisor *= requests[i]; } + + #[cfg(any(test, feature = "testing"))] + assert!(bus_debugger.is_empty(), "{bus_debugger}"); + result_aux_column } } From 34d4d17a11dd982fbf84c1d1562b5667238c1f56 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Wed, 12 Feb 2025 10:11:39 -0500 Subject: [PATCH 03/21] feat: implement messages for `BusColumnBuilder` --- processor/src/chiplets/aux_trace/messages.rs | 663 +++++++++++++++++++ processor/src/chiplets/aux_trace/mod.rs | 559 +++++++--------- 2 files changed, 918 insertions(+), 304 deletions(-) create mode 100644 processor/src/chiplets/aux_trace/messages.rs diff --git a/processor/src/chiplets/aux_trace/messages.rs b/processor/src/chiplets/aux_trace/messages.rs new file mode 100644 index 0000000000..a1ec6500c4 --- /dev/null +++ b/processor/src/chiplets/aux_trace/messages.rs @@ -0,0 +1,663 @@ +use core::fmt::{Display, Formatter, Result as FmtResult}; + +use miden_air::trace::chiplets::{ + hasher::{ + LINEAR_HASH_LABEL, MP_VERIFY_LABEL, MR_UPDATE_NEW_LABEL, MR_UPDATE_OLD_LABEL, + RETURN_HASH_LABEL, RETURN_STATE_LABEL, + }, + kernel_rom::KERNEL_PROC_LABEL, +}; +use vm_core::{ + Felt, FieldElement, ONE, OPCODE_CALL, OPCODE_DYN, OPCODE_DYNCALL, OPCODE_JOIN, OPCODE_LOOP, + OPCODE_SPLIT, +}; + +use super::build_value; +use crate::debug::BusMessage; + +// CONTROL BLOCK MESSAGE +// =============================================================================================== + +pub struct ControlBlockMessage { + pub transition_label: Felt, + pub addr_next: Felt, + pub op_code: Felt, + pub decoder_hasher_state: [Felt; 8], +} + +impl BusMessage for ControlBlockMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let header = alphas[0] + + alphas[1].mul_base(self.transition_label) + + alphas[2].mul_base(self.addr_next); + + header + + alphas[5].mul_base(self.op_code) + + build_value(&alphas[8..16], self.decoder_hasher_state) + } + + fn source(&self) -> &str { + let op_code = self.op_code.as_int() as u8; + match op_code { + OPCODE_JOIN => "join", + OPCODE_SPLIT => "split", + OPCODE_LOOP => "loop", + OPCODE_CALL => "call", + _ => panic!("unexpected opcode: {op_code}"), + } + } +} + +impl Display for ControlBlockMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "transition_label: {}, addr_next: {}, op_code: {}, decoder_hasher_state: {:?}", + self.transition_label, self.addr_next, self.op_code, self.decoder_hasher_state + ) + } +} + +// DYN BLOCK MESSAGE +// =============================================================================================== + +pub struct DynBlockMessage { + pub control_block_req: ControlBlockMessage, + pub memory_req: MemRequestWordMessage, +} + +impl BusMessage for DynBlockMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + self.control_block_req.value(alphas) * self.memory_req.value(alphas) + } + + fn source(&self) -> &str { + let op_code = self.control_block_req.op_code.as_int() as u8; + match op_code { + OPCODE_DYN => "dyn", + OPCODE_DYNCALL => "dyncall", + _ => panic!("unexpected opcode: {op_code}"), + } + } +} + +impl Display for DynBlockMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "control block request: {} || memory_req: {}", + self.control_block_req, self.memory_req + ) + } +} + +// SYSCALL BLOCK MESSAGE +// =============================================================================================== + +pub struct SyscallBlockMessage { + pub control_block_req: ControlBlockMessage, + pub kernel_proc_digest: [Felt; 4], +} + +impl BusMessage for SyscallBlockMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let control_block_req_val = self.control_block_req.value(alphas); + let kernel_rom_req_val = alphas[0] + + alphas[1].mul_base(KERNEL_PROC_LABEL) + + alphas[2].mul_base(self.kernel_proc_digest[0]) + + alphas[3].mul_base(self.kernel_proc_digest[1]) + + alphas[4].mul_base(self.kernel_proc_digest[2]) + + alphas[5].mul_base(self.kernel_proc_digest[3]); + + control_block_req_val * kernel_rom_req_val + } + + fn source(&self) -> &str { + "syscall" + } +} + +impl Display for SyscallBlockMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "control_block_req: {}, op_label: {}, state: {:?}", + self.control_block_req, KERNEL_PROC_LABEL, self.kernel_proc_digest + ) + } +} + +// SPAN BLOCK MESSAGE +// =============================================================================================== + +pub struct SpanBlockMessage { + pub transition_label: Felt, + pub addr_next: Felt, + pub state: [Felt; 8], +} + +impl BusMessage for SpanBlockMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let header = alphas[0] + + alphas[1].mul_base(self.transition_label) + + alphas[2].mul_base(self.addr_next); + + header + build_value(&alphas[8..16], self.state) + } + + fn source(&self) -> &str { + "span" + } +} + +impl Display for SpanBlockMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "transition_label: {}, addr_next: {}, state: {:?}", + self.transition_label, self.addr_next, self.state + ) + } +} + +// RESPAN BLOCK MESSAGE +// =============================================================================================== + +pub struct RespanBlockMessage { + pub transition_label: Felt, + pub addr_next: Felt, + pub state: [Felt; 8], +} + +impl BusMessage for RespanBlockMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let header = alphas[0] + + alphas[1].mul_base(self.transition_label) + + alphas[2].mul_base(self.addr_next - ONE); + + header + build_value(&alphas[8..16], self.state) + } + + fn source(&self) -> &str { + "respan" + } +} + +impl Display for RespanBlockMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "transition_label: {}, addr_next: {}, state: {:?}", + self.transition_label, self.addr_next, self.state + ) + } +} + +// END BLOCK MESSAGE +// =============================================================================================== + +pub struct EndBlockMessage { + pub addr: Felt, + pub transition_label: Felt, + pub digest: [Felt; 4], +} + +impl BusMessage for EndBlockMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let header = + alphas[0] + alphas[1].mul_base(self.transition_label) + alphas[2].mul_base(self.addr); + + header + build_value(&alphas[8..12], self.digest) + } + + fn source(&self) -> &str { + "end" + } +} + +impl Display for EndBlockMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "addr: {}, transition_label: {}, digest: {:?}", + self.addr, self.transition_label, self.digest + ) + } +} + +// BITWISE REQUEST MESSAGE +// =============================================================================================== + +pub struct BitwiseRequestMessage { + pub op_label: Felt, + pub a: Felt, + pub b: Felt, + pub z: Felt, +} + +impl BusMessage for BitwiseRequestMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + alphas[0] + build_value(&alphas[1..5], [self.op_label, self.a, self.b, self.z]) + } + + fn source(&self) -> &str { + "bitwise" + } +} + +impl Display for BitwiseRequestMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "op_label: {}, a: {}, b: {}, z: {}", self.op_label, self.a, self.b, self.z) + } +} + +// MEMORY REQUEST WORD MESSAGE +// =============================================================================================== + +pub struct MemRequestWordMessage { + pub op_label: Felt, + pub ctx: Felt, + pub addr: Felt, + pub clk: Felt, + pub word: [Felt; 4], +} + +impl BusMessage for MemRequestWordMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + alphas[0] + + build_value( + &alphas[1..9], + [ + self.op_label, + self.ctx, + self.addr, + self.clk, + self.word[0], + self.word[1], + self.word[2], + self.word[3], + ], + ) + } + + fn source(&self) -> &str { + "memory word" + } +} + +impl Display for MemRequestWordMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "op_label: {}, ctx: {}, addr: {}, clk: {}, word: {:?}", + self.op_label, self.ctx, self.addr, self.clk, self.word + ) + } +} + +// MEMORY REQUEST ELEMENT MESSAGE +// =============================================================================================== + +pub struct MemRequestElementMessage { + pub op_label: Felt, + pub ctx: Felt, + pub addr: Felt, + pub clk: Felt, + pub element: Felt, +} + +impl BusMessage for MemRequestElementMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + alphas[0] + + build_value( + &alphas[1..6], + [self.op_label, self.ctx, self.addr, self.clk, self.element], + ) + } + + fn source(&self) -> &str { + "memory element" + } +} + +impl Display for MemRequestElementMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "op_label: {}, ctx: {}, addr: {}, clk: {}, element: {}", + self.op_label, self.ctx, self.addr, self.clk, self.element + ) + } +} + +// MSTREAM REQUEST MESSAGE +// =============================================================================================== + +pub struct MstreamRequestMessage { + pub mem_req_1: MemRequestWordMessage, + pub mem_req_2: MemRequestWordMessage, +} + +impl BusMessage for MstreamRequestMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + self.mem_req_1.value(alphas) * self.mem_req_2.value(alphas) + } + + fn source(&self) -> &str { + "mstream" + } +} + +impl Display for MstreamRequestMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "mem_req_1: {} || mem_req_2: {}", self.mem_req_1, self.mem_req_2) + } +} + +// PIPE REQUEST MESSAGE +// =============================================================================================== + +pub struct PipeRequestMessage { + pub mem_req_1: MemRequestWordMessage, + pub mem_req_2: MemRequestWordMessage, +} + +impl BusMessage for PipeRequestMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + self.mem_req_1.value(alphas) * self.mem_req_2.value(alphas) + } + + fn source(&self) -> &str { + "pipe" + } +} + +impl Display for PipeRequestMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "mem_req_1: {} || mem_req_2: {}", self.mem_req_1, self.mem_req_2) + } +} + +// RCOMB BASE REQUEST MESSAGE +// =============================================================================================== + +pub struct RcombBaseRequestMessage { + pub mem_req_1: MemRequestWordMessage, + pub mem_req_2: MemRequestWordMessage, +} + +impl BusMessage for RcombBaseRequestMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + self.mem_req_1.value(alphas) * self.mem_req_2.value(alphas) + } + + fn source(&self) -> &str { + "rcombbase" + } +} + +impl Display for RcombBaseRequestMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "mem_req_1: {} || mem_req_2: {}", self.mem_req_1, self.mem_req_2) + } +} + +// HPERM REQUEST MESSAGE +// =============================================================================================== + +pub struct HpermRequestMessage { + pub helper_0: Felt, + pub s0_s12_cur: [Felt; 12], + pub s0_s12_nxt: [Felt; 12], +} + +impl BusMessage for HpermRequestMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let v_input_req = { + let op_label = LINEAR_HASH_LABEL + 16; + + let sum_input = alphas[4..16] + .iter() + .rev() + .enumerate() + .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s0_s12_cur[i])); + + alphas[0] + + alphas[1].mul_base(Felt::from(op_label)) + + alphas[2].mul_base(self.helper_0) + + sum_input + }; + + let v_output_req = { + let op_label = RETURN_STATE_LABEL + 32; + + let sum_output = alphas[4..16] + .iter() + .rev() + .enumerate() + .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s0_s12_nxt[i])); + alphas[0] + + alphas[1].mul_base(Felt::from(op_label)) + + alphas[2].mul_base(self.helper_0 + Felt::new(7)) + + sum_output + }; + + v_input_req * v_output_req + } + + fn source(&self) -> &str { + "hperm" + } +} + +impl Display for HpermRequestMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "helper_0: {}, s0_s12_cur: {:?}, s0_s12_nxt: {:?}", + self.helper_0, self.s0_s12_cur, self.s0_s12_nxt + ) + } +} + +// MPVERIFY REQUEST MESSAGE +// =============================================================================================== + +pub struct MpverifyRequestMessage { + pub helper_0: Felt, + pub s0_s3: [Felt; 4], + pub s4: Felt, + pub s5: Felt, + pub s6_s9: [Felt; 4], +} + +impl BusMessage for MpverifyRequestMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let op_label = MP_VERIFY_LABEL + 16; + + let v_input = { + let sum_input = alphas[8..12] + .iter() + .rev() + .enumerate() + .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s0_s3[i])); + + alphas[0] + + alphas[1].mul_base(Felt::from(op_label)) + + alphas[2].mul_base(self.helper_0) + + alphas[3].mul_base(self.s5) + + sum_input + }; + + let v_output = { + let op_label = RETURN_HASH_LABEL + 32; + + let sum_output = alphas[8..12] + .iter() + .rev() + .enumerate() + .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s6_s9[i])); + alphas[0] + + alphas[1].mul_base(Felt::from(op_label)) + + alphas[2].mul_base(self.helper_0 + self.s4.mul_small(8) - ONE) + + sum_output + }; + + v_input * v_output + } + + fn source(&self) -> &str { + "mpverify" + } +} + +impl Display for MpverifyRequestMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "helper_0: {}, s0_s3: {:?}, s4: {}, s5: {}, s6_s9: {:?}", + self.helper_0, self.s0_s3, self.s4, self.s5, self.s6_s9 + ) + } +} + +// MRUPDATE REQUEST MESSAGE +// =============================================================================================== + +pub struct MrupdateRequestMessage { + pub helper_0: Felt, + pub s0_s3: [Felt; 4], + pub s0_s3_nxt: [Felt; 4], + pub s4: Felt, + pub s5: Felt, + pub s6_s9: [Felt; 4], + pub s10_s13: [Felt; 4], +} + +impl BusMessage for MrupdateRequestMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let v_input_old = { + let op_label = MR_UPDATE_OLD_LABEL + 16; + + let sum_input = alphas[8..12] + .iter() + .rev() + .enumerate() + .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s0_s3[i])); + alphas[0] + + alphas[1].mul_base(Felt::from(op_label)) + + alphas[2].mul_base(self.helper_0) + + alphas[3].mul_base(self.s5) + + sum_input + }; + + let v_output_old = { + let op_label = RETURN_HASH_LABEL + 32; + + let sum_output = alphas[8..12] + .iter() + .rev() + .enumerate() + .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s6_s9[i])); + alphas[0] + + alphas[1].mul_base(Felt::from(op_label)) + + alphas[2].mul_base(self.helper_0 + self.s4.mul_small(8) - ONE) + + sum_output + }; + + let v_input_new = { + let op_label = MR_UPDATE_NEW_LABEL + 16; + let sum_input = alphas[8..12] + .iter() + .rev() + .enumerate() + .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s10_s13[i])); + alphas[0] + + alphas[1].mul_base(Felt::from(op_label)) + + alphas[2].mul_base(self.helper_0 + self.s4.mul_small(8)) + + alphas[3].mul_base(self.s5) + + sum_input + }; + + let v_output_new = { + let op_label = RETURN_HASH_LABEL + 32; + + let sum_output = alphas[8..12] + .iter() + .rev() + .enumerate() + .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s0_s3_nxt[i])); + alphas[0] + + alphas[1].mul_base(Felt::from(op_label)) + + alphas[2].mul_base(self.helper_0 + self.s4.mul_small(16) - ONE) + + sum_output + }; + + v_input_old * v_output_old * v_input_new * v_output_new + } + + fn source(&self) -> &str { + "mrupdate" + } +} + +impl Display for MrupdateRequestMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "helper_0: {}, s0_s3: {:?}, s0_s3_nxt: {:?}, s4: {}, s5: {}, s6_s9: {:?}, s10_s13: {:?}", + self.helper_0, + self.s0_s3, + self.s0_s3_nxt, + self.s4, + self.s5, + self.s6_s9, + self.s10_s13, + ) + } +} diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index b3344952a4..4c83a0611f 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -1,13 +1,18 @@ use alloc::vec::Vec; +use messages::{ + BitwiseRequestMessage, ControlBlockMessage, DynBlockMessage, EndBlockMessage, + HpermRequestMessage, MemRequestElementMessage, MemRequestWordMessage, MpverifyRequestMessage, + MrupdateRequestMessage, MstreamRequestMessage, PipeRequestMessage, RcombBaseRequestMessage, + RespanBlockMessage, SpanBlockMessage, SyscallBlockMessage, +}; use miden_air::{ trace::{ chiplets::{ bitwise::OP_CYCLE_LEN as BITWISE_OP_CYCLE_LEN, hasher::{ - CAPACITY_LEN, DIGEST_RANGE, HASH_CYCLE_LEN, LINEAR_HASH_LABEL, MP_VERIFY_LABEL, - MR_UPDATE_NEW_LABEL, MR_UPDATE_OLD_LABEL, NUM_ROUNDS, RETURN_HASH_LABEL, - RETURN_STATE_LABEL, STATE_WIDTH, + CAPACITY_LEN, DIGEST_RANGE, HASH_CYCLE_LEN, LINEAR_HASH_LABEL, NUM_ROUNDS, + RETURN_HASH_LABEL, STATE_WIDTH, }, kernel_rom::KERNEL_PROC_LABEL, memory::{ @@ -20,14 +25,16 @@ use miden_air::{ RowIndex, }; use vm_core::{ - Kernel, Word, ONE, OPCODE_CALL, OPCODE_DYN, OPCODE_DYNCALL, OPCODE_END, OPCODE_HPERM, - OPCODE_JOIN, OPCODE_LOOP, OPCODE_MLOAD, OPCODE_MLOADW, OPCODE_MPVERIFY, OPCODE_MRUPDATE, - OPCODE_MSTORE, OPCODE_MSTOREW, OPCODE_MSTREAM, OPCODE_PIPE, OPCODE_RCOMBBASE, OPCODE_RESPAN, - OPCODE_SPAN, OPCODE_SPLIT, OPCODE_SYSCALL, OPCODE_U32AND, OPCODE_U32XOR, ZERO, + Kernel, ONE, OPCODE_CALL, OPCODE_DYN, OPCODE_DYNCALL, OPCODE_END, OPCODE_HPERM, OPCODE_JOIN, + OPCODE_LOOP, OPCODE_MLOAD, OPCODE_MLOADW, OPCODE_MPVERIFY, OPCODE_MRUPDATE, OPCODE_MSTORE, + OPCODE_MSTOREW, OPCODE_MSTREAM, OPCODE_PIPE, OPCODE_RCOMBBASE, OPCODE_RESPAN, OPCODE_SPAN, + OPCODE_SPLIT, OPCODE_SYSCALL, OPCODE_U32AND, OPCODE_U32XOR, ZERO, }; use super::{super::trace::AuxColumnBuilder, Felt, FieldElement}; -use crate::debug::BusDebugger; +use crate::debug::{BusDebugger, BusMessage}; + +mod messages; // CONSTANTS // ================================================================================================ @@ -382,14 +389,14 @@ fn build_control_block_request>( alphas: &[E], row: RowIndex, ) -> E { - let op_label = LINEAR_HASH_LABEL; - let addr_nxt = main_trace.addr(row + 1); - let transition_label = op_label + 16; - - let header = - alphas[0] + alphas[1].mul_base(Felt::from(transition_label)) + alphas[2].mul_base(addr_nxt); + let message = ControlBlockMessage { + transition_label: Felt::from(LINEAR_HASH_LABEL + 16), + addr_next: main_trace.addr(row + 1), + op_code: op_code_felt, + decoder_hasher_state, + }; - header + build_value(&alphas[8..16], decoder_hasher_state) + alphas[5].mul_base(op_code_felt) + message.value(alphas) } /// Builds requests made on a `DYN` or `DYNCALL` operation. @@ -399,24 +406,24 @@ fn build_dyn_block_request>( alphas: &[E], row: RowIndex, ) -> E { - let control_block_req = - build_control_block_request(main_trace, [ZERO; 8], op_code_felt, alphas, row); - - let memory_req = { - let mem_addr = main_trace.stack_element(0, row); - let mem_value = main_trace.decoder_hasher_state_first_half(row); - - compute_mem_request_word( - main_trace, - MEMORY_READ_WORD_LABEL, - alphas, - row, - mem_addr, - mem_value, - ) + let control_block_req = ControlBlockMessage { + transition_label: Felt::from(LINEAR_HASH_LABEL + 16), + addr_next: main_trace.addr(row + 1), + op_code: op_code_felt, + decoder_hasher_state: [ZERO; 8], + }; + + let memory_req = MemRequestWordMessage { + op_label: Felt::from(MEMORY_READ_WORD_LABEL), + ctx: main_trace.ctx(row), + addr: main_trace.stack_element(0, row), + clk: main_trace.clk(row), + word: main_trace.decoder_hasher_state_first_half(row), }; - control_block_req * memory_req + let dyn_block_message = DynBlockMessage { control_block_req, memory_req }; + + dyn_block_message.value(alphas) } /// Builds requests made to kernel ROM chiplet when initializing a syscall block. @@ -426,24 +433,19 @@ fn build_syscall_block_request>( alphas: &[E], row: RowIndex, ) -> E { - let factor1 = build_control_block_request( - main_trace, - main_trace.decoder_hasher_state(row), - op_code_felt, - alphas, - row, - ); + let control_block_req = ControlBlockMessage { + transition_label: Felt::from(LINEAR_HASH_LABEL + 16), + addr_next: main_trace.addr(row + 1), + op_code: op_code_felt, + decoder_hasher_state: main_trace.decoder_hasher_state(row), + }; - let op_label = KERNEL_PROC_LABEL; - let state = main_trace.decoder_hasher_state(row); - let factor2 = alphas[0] - + alphas[1].mul_base(op_label) - + alphas[2].mul_base(state[0]) - + alphas[3].mul_base(state[1]) - + alphas[4].mul_base(state[2]) - + alphas[5].mul_base(state[3]); - - factor1 * factor2 + let syscall_block_message = SyscallBlockMessage { + control_block_req, + kernel_proc_digest: main_trace.decoder_hasher_state(row)[0..4].try_into().unwrap(), + }; + + syscall_block_message.value(alphas) } /// Builds requests made to the hasher chiplet at the start of a span block. @@ -452,15 +454,13 @@ fn build_span_block_request>( alphas: &[E], row: RowIndex, ) -> E { - let op_label = LINEAR_HASH_LABEL; - let addr_nxt = main_trace.addr(row + 1); - let transition_label = op_label + 16; - - let header = - alphas[0] + alphas[1].mul_base(Felt::from(transition_label)) + alphas[2].mul_base(addr_nxt); + let span_block_message = SpanBlockMessage { + transition_label: Felt::from(LINEAR_HASH_LABEL + 16), + addr_next: main_trace.addr(row + 1), + state: main_trace.decoder_hasher_state(row), + }; - let state = main_trace.decoder_hasher_state(row); - header + build_value(&alphas[8..16], state) + span_block_message.value(alphas) } /// Builds requests made to the hasher chiplet at the start of a respan block. @@ -469,18 +469,13 @@ fn build_respan_block_request>( alphas: &[E], row: RowIndex, ) -> E { - let op_label = LINEAR_HASH_LABEL; - let addr_nxt = main_trace.addr(row + 1); - let transition_label = op_label + 32; - - let header = alphas[0] - + alphas[1].mul_base(Felt::from(transition_label)) - + alphas[2].mul_base(addr_nxt - ONE) - + alphas[3].mul_base(ZERO); - - let state = main_trace.decoder_hasher_state(row); + let respan_block_message = RespanBlockMessage { + transition_label: Felt::from(LINEAR_HASH_LABEL + 32), + addr_next: main_trace.addr(row + 1), + state: main_trace.decoder_hasher_state(row), + }; - header + build_value(&alphas[8..16], state) + respan_block_message.value(alphas) } /// Builds requests made to the hasher chiplet at the end of a block. @@ -489,17 +484,13 @@ fn build_end_block_request>( alphas: &[E], row: RowIndex, ) -> E { - let op_label = RETURN_HASH_LABEL; - let addr = main_trace.addr(row) + Felt::from(NUM_ROUNDS as u8); - let transition_label = op_label + 32; - - let header = - alphas[0] + alphas[1].mul_base(Felt::from(transition_label)) + alphas[2].mul_base(addr); - - let state = main_trace.decoder_hasher_state(row); - let digest: [Felt; 4] = state[..4].try_into().unwrap(); + let end_block_message = EndBlockMessage { + addr: main_trace.addr(row) + Felt::from(NUM_ROUNDS as u8), + transition_label: Felt::from(RETURN_HASH_LABEL + 32), + digest: main_trace.decoder_hasher_state(row)[..4].try_into().unwrap(), + }; - header + build_value(&alphas[8..12], digest) + end_block_message.value(alphas) } /// Builds requests made to the bitwise chiplet. This can be either a request for the computation @@ -510,12 +501,14 @@ fn build_bitwise_request>( alphas: &[E], row: RowIndex, ) -> E { - let op_label = get_op_label(ONE, ZERO, is_xor, ZERO); - let a = main_trace.stack_element(1, row); - let b = main_trace.stack_element(0, row); - let z = main_trace.stack_element(0, row + 1); + let bitwise_request_message = BitwiseRequestMessage { + op_label: get_op_label(ONE, ZERO, is_xor, ZERO), + a: main_trace.stack_element(1, row), + b: main_trace.stack_element(0, row), + z: main_trace.stack_element(0, row + 1), + }; - alphas[0] + build_value(&alphas[1..5], [op_label, a, b, z]) + bitwise_request_message.value(alphas) } /// Builds `MSTREAM` requests made to the memory chiplet. @@ -524,25 +517,39 @@ fn build_mstream_request>( alphas: &[E], row: RowIndex, ) -> E { - let word1 = [ - main_trace.stack_element(7, row + 1), - main_trace.stack_element(6, row + 1), - main_trace.stack_element(5, row + 1), - main_trace.stack_element(4, row + 1), - ]; - let word2 = [ - main_trace.stack_element(3, row + 1), - main_trace.stack_element(2, row + 1), - main_trace.stack_element(1, row + 1), - main_trace.stack_element(0, row + 1), - ]; + let op_label = Felt::from(MEMORY_READ_WORD_LABEL); let addr = main_trace.stack_element(12, row); - let op_label = MEMORY_READ_WORD_LABEL; + let ctx = main_trace.ctx(row); + let clk = main_trace.clk(row); - let factor1 = compute_mem_request_word(main_trace, op_label, alphas, row, addr, word1); - let factor2 = compute_mem_request_word(main_trace, op_label, alphas, row, addr + FOUR, word2); + let mstream_request_message = MstreamRequestMessage { + mem_req_1: MemRequestWordMessage { + op_label, + ctx, + addr, + clk, + word: [ + main_trace.stack_element(7, row + 1), + main_trace.stack_element(6, row + 1), + main_trace.stack_element(5, row + 1), + main_trace.stack_element(4, row + 1), + ], + }, + mem_req_2: MemRequestWordMessage { + op_label, + ctx, + addr: addr + FOUR, + clk, + word: [ + main_trace.stack_element(3, row + 1), + main_trace.stack_element(2, row + 1), + main_trace.stack_element(1, row + 1), + main_trace.stack_element(0, row + 1), + ], + }, + }; - factor1 * factor2 + mstream_request_message.value(alphas) } /// Builds `PIPE` requests made to the memory chiplet. @@ -551,25 +558,39 @@ fn build_pipe_request>( alphas: &[E], row: RowIndex, ) -> E { - let word1 = [ - main_trace.stack_element(7, row + 1), - main_trace.stack_element(6, row + 1), - main_trace.stack_element(5, row + 1), - main_trace.stack_element(4, row + 1), - ]; - let word2 = [ - main_trace.stack_element(3, row + 1), - main_trace.stack_element(2, row + 1), - main_trace.stack_element(1, row + 1), - main_trace.stack_element(0, row + 1), - ]; + let op_label = Felt::from(MEMORY_WRITE_WORD_LABEL); let addr = main_trace.stack_element(12, row); - let op_label = MEMORY_WRITE_WORD_LABEL; + let ctx = main_trace.ctx(row); + let clk = main_trace.clk(row); - let req1 = compute_mem_request_word(main_trace, op_label, alphas, row, addr, word1); - let req2 = compute_mem_request_word(main_trace, op_label, alphas, row, addr + FOUR, word2); + let pipe_request_message = PipeRequestMessage { + mem_req_1: MemRequestWordMessage { + op_label, + ctx, + addr, + clk, + word: [ + main_trace.stack_element(7, row + 1), + main_trace.stack_element(6, row + 1), + main_trace.stack_element(5, row + 1), + main_trace.stack_element(4, row + 1), + ], + }, + mem_req_2: MemRequestWordMessage { + op_label, + ctx, + addr: addr + FOUR, + clk, + word: [ + main_trace.stack_element(3, row + 1), + main_trace.stack_element(2, row + 1), + main_trace.stack_element(1, row + 1), + main_trace.stack_element(0, row + 1), + ], + }, + }; - req1 * req2 + pipe_request_message.value(alphas) } /// Builds `RCOMBBASE` requests made to the memory chiplet. @@ -586,14 +607,29 @@ fn build_rcomb_base_request>( let a1 = main_trace.helper_register(5, row); let z_ptr = main_trace.stack_element(13, row); let a_ptr = main_trace.stack_element(14, row); - let op_label = MEMORY_READ_WORD_LABEL; + let op_label = Felt::from(MEMORY_READ_WORD_LABEL); - let req1 = - compute_mem_request_word(main_trace, op_label, alphas, row, z_ptr, [tz0, tz1, tzg0, tzg1]); - let req2 = - compute_mem_request_word(main_trace, op_label, alphas, row, a_ptr, [a0, a1, ZERO, ZERO]); + let ctx = main_trace.ctx(row); + let clk = main_trace.clk(row); - req1 * req2 + let rcombbase_request_message = RcombBaseRequestMessage { + mem_req_1: MemRequestWordMessage { + op_label, + ctx, + addr: z_ptr, + clk, + word: [tz0, tz1, tzg0, tzg1], + }, + mem_req_2: MemRequestWordMessage { + op_label, + ctx, + addr: a_ptr, + clk, + word: [a0, a1, ZERO, ZERO], + }, + }; + + rcombbase_request_message.value(alphas) } /// Builds `HPERM` requests made to the hash chiplet. @@ -602,63 +638,39 @@ fn build_hperm_request>( alphas: &[E], row: RowIndex, ) -> E { - let helper_0 = main_trace.helper_register(0, row); - - let s0_s12_cur = [ - main_trace.stack_element(0, row), - main_trace.stack_element(1, row), - main_trace.stack_element(2, row), - main_trace.stack_element(3, row), - main_trace.stack_element(4, row), - main_trace.stack_element(5, row), - main_trace.stack_element(6, row), - main_trace.stack_element(7, row), - main_trace.stack_element(8, row), - main_trace.stack_element(9, row), - main_trace.stack_element(10, row), - main_trace.stack_element(11, row), - ]; - - let s0_s12_nxt = [ - main_trace.stack_element(0, row + 1), - main_trace.stack_element(1, row + 1), - main_trace.stack_element(2, row + 1), - main_trace.stack_element(3, row + 1), - main_trace.stack_element(4, row + 1), - main_trace.stack_element(5, row + 1), - main_trace.stack_element(6, row + 1), - main_trace.stack_element(7, row + 1), - main_trace.stack_element(8, row + 1), - main_trace.stack_element(9, row + 1), - main_trace.stack_element(10, row + 1), - main_trace.stack_element(11, row + 1), - ]; + let hperm_request_message = HpermRequestMessage { + helper_0: main_trace.helper_register(0, row), + s0_s12_cur: [ + main_trace.stack_element(0, row), + main_trace.stack_element(1, row), + main_trace.stack_element(2, row), + main_trace.stack_element(3, row), + main_trace.stack_element(4, row), + main_trace.stack_element(5, row), + main_trace.stack_element(6, row), + main_trace.stack_element(7, row), + main_trace.stack_element(8, row), + main_trace.stack_element(9, row), + main_trace.stack_element(10, row), + main_trace.stack_element(11, row), + ], + s0_s12_nxt: [ + main_trace.stack_element(0, row + 1), + main_trace.stack_element(1, row + 1), + main_trace.stack_element(2, row + 1), + main_trace.stack_element(3, row + 1), + main_trace.stack_element(4, row + 1), + main_trace.stack_element(5, row + 1), + main_trace.stack_element(6, row + 1), + main_trace.stack_element(7, row + 1), + main_trace.stack_element(8, row + 1), + main_trace.stack_element(9, row + 1), + main_trace.stack_element(10, row + 1), + main_trace.stack_element(11, row + 1), + ], + }; - let op_label = LINEAR_HASH_LABEL + 16; - - let sum_input = alphas[4..16] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(s0_s12_cur[i])); - let v_input = alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(helper_0) - + sum_input; - - let op_label = RETURN_STATE_LABEL + 32; - - let sum_output = alphas[4..16] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(s0_s12_nxt[i])); - let v_output = alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(helper_0 + Felt::new(7)) - + sum_output; - - v_input * v_output + hperm_request_message.value(alphas) } /// Builds `MPVERIFY` requests made to the hash chiplet. @@ -667,50 +679,25 @@ fn build_mpverify_request>( alphas: &[E], row: RowIndex, ) -> E { - let helper_0 = main_trace.helper_register(0, row); - - let s0_s3 = [ - main_trace.stack_element(0, row), - main_trace.stack_element(1, row), - main_trace.stack_element(2, row), - main_trace.stack_element(3, row), - ]; - let s4 = main_trace.stack_element(4, row); - let s5 = main_trace.stack_element(5, row); - let s6_s9 = [ - main_trace.stack_element(6, row), - main_trace.stack_element(7, row), - main_trace.stack_element(8, row), - main_trace.stack_element(9, row), - ]; + let mpverify_request_message = MpverifyRequestMessage { + helper_0: main_trace.helper_register(0, row), + s0_s3: [ + main_trace.stack_element(0, row), + main_trace.stack_element(1, row), + main_trace.stack_element(2, row), + main_trace.stack_element(3, row), + ], + s4: main_trace.stack_element(4, row), + s5: main_trace.stack_element(5, row), + s6_s9: [ + main_trace.stack_element(6, row), + main_trace.stack_element(7, row), + main_trace.stack_element(8, row), + main_trace.stack_element(9, row), + ], + }; - let op_label = MP_VERIFY_LABEL + 16; - - let sum_input = alphas[8..12] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(s0_s3[i])); - - let v_input = alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(helper_0) - + alphas[3].mul_base(s5) - + sum_input; - - let op_label = RETURN_HASH_LABEL + 32; - - let sum_output = alphas[8..12] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(s6_s9[i])); - let v_output = alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(helper_0 + s4.mul_small(8) - ONE) - + sum_output; - - v_input * v_output + mpverify_request_message.value(alphas) } /// Builds `MRUPDATE` requests made to the hash chiplet. @@ -719,85 +706,37 @@ fn build_mrupdate_request>( alphas: &[E], row: RowIndex, ) -> E { - let helper_0 = main_trace.helper_register(0, row); - - let s0_s3 = [ - main_trace.stack_element(0, row), - main_trace.stack_element(1, row), - main_trace.stack_element(2, row), - main_trace.stack_element(3, row), - ]; - let s0_s3_nxt = [ - main_trace.stack_element(0, row + 1), - main_trace.stack_element(1, row + 1), - main_trace.stack_element(2, row + 1), - main_trace.stack_element(3, row + 1), - ]; - let s4 = main_trace.stack_element(4, row); - let s5 = main_trace.stack_element(5, row); - let s6_s9 = [ - main_trace.stack_element(6, row), - main_trace.stack_element(7, row), - main_trace.stack_element(8, row), - main_trace.stack_element(9, row), - ]; - let s10_s13 = [ - main_trace.stack_element(10, row), - main_trace.stack_element(11, row), - main_trace.stack_element(12, row), - main_trace.stack_element(13, row), - ]; + let mrupdate_request_message = MrupdateRequestMessage { + helper_0: main_trace.helper_register(0, row), + s0_s3: [ + main_trace.stack_element(0, row), + main_trace.stack_element(1, row), + main_trace.stack_element(2, row), + main_trace.stack_element(3, row), + ], + s0_s3_nxt: [ + main_trace.stack_element(0, row + 1), + main_trace.stack_element(1, row + 1), + main_trace.stack_element(2, row + 1), + main_trace.stack_element(3, row + 1), + ], + s4: main_trace.stack_element(4, row), + s5: main_trace.stack_element(5, row), + s6_s9: [ + main_trace.stack_element(6, row), + main_trace.stack_element(7, row), + main_trace.stack_element(8, row), + main_trace.stack_element(9, row), + ], + s10_s13: [ + main_trace.stack_element(10, row), + main_trace.stack_element(11, row), + main_trace.stack_element(12, row), + main_trace.stack_element(13, row), + ], + }; - let op_label = MR_UPDATE_OLD_LABEL + 16; - - let sum_input = alphas[8..12] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(s0_s3[i])); - let v_input_old = alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(helper_0) - + alphas[3].mul_base(s5) - + sum_input; - - let op_label = RETURN_HASH_LABEL + 32; - - let sum_output = alphas[8..12] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(s6_s9[i])); - let v_output_old = alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(helper_0 + s4.mul_small(8) - ONE) - + sum_output; - - let op_label = MR_UPDATE_NEW_LABEL + 16; - let sum_input = alphas[8..12] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(s10_s13[i])); - let v_input_new = alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(helper_0 + s4.mul_small(8)) - + alphas[3].mul_base(s5) - + sum_input; - - let op_label = RETURN_HASH_LABEL + 32; - - let sum_output = alphas[8..12] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(s0_s3_nxt[i])); - let v_output_new = alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(helper_0 + s4.mul_small(16) - ONE) - + sum_output; - - v_input_new * v_input_old * v_output_new * v_output_old + mrupdate_request_message.value(alphas) } // CHIPLETS RESPONSES @@ -1071,7 +1010,15 @@ fn compute_mem_request_element>( let ctx = main_trace.ctx(row); let clk = main_trace.clk(row); - alphas[0] + build_value(&alphas[1..6], [Felt::from(op_label), ctx, addr, clk, element]) + let message = MemRequestElementMessage { + op_label: Felt::from(op_label), + ctx, + addr, + clk, + element, + }; + + message.value(alphas) } /// Computes a memory request for a read or write of a word. @@ -1081,15 +1028,19 @@ fn compute_mem_request_word>( alphas: &[E], row: RowIndex, addr: Felt, - word: Word, + word: [Felt; 4], ) -> E { debug_assert!(op_label == MEMORY_READ_WORD_LABEL || op_label == MEMORY_WRITE_WORD_LABEL); let ctx = main_trace.ctx(row); let clk = main_trace.clk(row); - alphas[0] - + build_value( - &alphas[1..9], - [Felt::from(op_label), ctx, addr, clk, word[0], word[1], word[2], word[3]], - ) + let message = MemRequestWordMessage { + op_label: Felt::from(op_label), + ctx, + addr, + clk, + word, + }; + + message.value(alphas) } From 117f87ee1d0a6acc991fb9ade57d6c40d2bd8d70 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Wed, 12 Feb 2025 13:37:48 -0500 Subject: [PATCH 04/21] feat: add messages to bus debugger --- processor/src/chiplets/aux_trace/messages.rs | 411 ++------- processor/src/chiplets/aux_trace/mod.rs | 860 +++++++++++++------ 2 files changed, 630 insertions(+), 641 deletions(-) diff --git a/processor/src/chiplets/aux_trace/messages.rs b/processor/src/chiplets/aux_trace/messages.rs index a1ec6500c4..1e2c3502fb 100644 --- a/processor/src/chiplets/aux_trace/messages.rs +++ b/processor/src/chiplets/aux_trace/messages.rs @@ -1,31 +1,24 @@ use core::fmt::{Display, Formatter, Result as FmtResult}; -use miden_air::trace::chiplets::{ - hasher::{ - LINEAR_HASH_LABEL, MP_VERIFY_LABEL, MR_UPDATE_NEW_LABEL, MR_UPDATE_OLD_LABEL, - RETURN_HASH_LABEL, RETURN_STATE_LABEL, - }, - kernel_rom::KERNEL_PROC_LABEL, -}; +use miden_air::trace::chiplets::{hasher, kernel_rom::KERNEL_PROC_LABEL}; use vm_core::{ - Felt, FieldElement, ONE, OPCODE_CALL, OPCODE_DYN, OPCODE_DYNCALL, OPCODE_JOIN, OPCODE_LOOP, - OPCODE_SPLIT, + utils::range, Felt, FieldElement, ONE, OPCODE_CALL, OPCODE_JOIN, OPCODE_LOOP, OPCODE_SPLIT, }; use super::build_value; use crate::debug::BusMessage; -// CONTROL BLOCK MESSAGE +// HASHER MESSAGES // =============================================================================================== -pub struct ControlBlockMessage { +pub struct ControlBlockRequestMessage { pub transition_label: Felt, pub addr_next: Felt, pub op_code: Felt, pub decoder_hasher_state: [Felt; 8], } -impl BusMessage for ControlBlockMessage +impl BusMessage for ControlBlockRequestMessage where E: FieldElement, { @@ -51,94 +44,90 @@ where } } -impl Display for ControlBlockMessage { +impl Display for ControlBlockRequestMessage { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!( f, - "transition_label: {}, addr_next: {}, op_code: {}, decoder_hasher_state: {:?}", + "{{ transition_label: {}, addr_next: {}, op_code: {}, decoder_hasher_state: {:?} }}", self.transition_label, self.addr_next, self.op_code, self.decoder_hasher_state ) } } -// DYN BLOCK MESSAGE -// =============================================================================================== +const NUM_HEADER_ALPHAS: usize = 4; -pub struct DynBlockMessage { - pub control_block_req: ControlBlockMessage, - pub memory_req: MemRequestWordMessage, +pub struct HasherMessage { + pub transition_label: Felt, + pub addr_next: Felt, + pub node_index: Felt, + pub hasher_state: [Felt; hasher::STATE_WIDTH], + pub source: &'static str, } -impl BusMessage for DynBlockMessage +impl BusMessage for HasherMessage where E: FieldElement, { fn value(&self, alphas: &[E]) -> E { - self.control_block_req.value(alphas) * self.memory_req.value(alphas) + let header = alphas[0] + + alphas[1].mul_base(self.transition_label) + + alphas[2].mul_base(self.addr_next) + + alphas[3].mul_base(self.node_index); + + header + + build_value(&alphas[range(NUM_HEADER_ALPHAS, hasher::STATE_WIDTH)], self.hasher_state) } fn source(&self) -> &str { - let op_code = self.control_block_req.op_code.as_int() as u8; - match op_code { - OPCODE_DYN => "dyn", - OPCODE_DYNCALL => "dyncall", - _ => panic!("unexpected opcode: {op_code}"), - } + self.source } } -impl Display for DynBlockMessage { +impl Display for HasherMessage { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!( f, - "control block request: {} || memory_req: {}", - self.control_block_req, self.memory_req + "{{ transition_label: {}, addr_next: {}, node_index: {}, decoder_hasher_state: {:?} }}", + self.transition_label, self.addr_next, self.node_index, self.hasher_state ) } } -// SYSCALL BLOCK MESSAGE +// KERNEL ROM MESSAGES // =============================================================================================== -pub struct SyscallBlockMessage { - pub control_block_req: ControlBlockMessage, +pub struct KernelRomMessage { pub kernel_proc_digest: [Felt; 4], } -impl BusMessage for SyscallBlockMessage +impl BusMessage for KernelRomMessage where E: FieldElement, { fn value(&self, alphas: &[E]) -> E { - let control_block_req_val = self.control_block_req.value(alphas); - let kernel_rom_req_val = alphas[0] + alphas[0] + alphas[1].mul_base(KERNEL_PROC_LABEL) + alphas[2].mul_base(self.kernel_proc_digest[0]) + alphas[3].mul_base(self.kernel_proc_digest[1]) + alphas[4].mul_base(self.kernel_proc_digest[2]) - + alphas[5].mul_base(self.kernel_proc_digest[3]); - - control_block_req_val * kernel_rom_req_val + + alphas[5].mul_base(self.kernel_proc_digest[3]) } fn source(&self) -> &str { - "syscall" + "kernel rom" } } -impl Display for SyscallBlockMessage { +impl Display for KernelRomMessage { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - "control_block_req: {}, op_label: {}, state: {:?}", - self.control_block_req, KERNEL_PROC_LABEL, self.kernel_proc_digest - ) + write!(f, "{{ proc digest: {:?} }}", self.kernel_proc_digest) } } // SPAN BLOCK MESSAGE // =============================================================================================== +// TODO(plafer): Remove this in favor of `ControlBlockRequestMessage` pub struct SpanBlockMessage { pub transition_label: Felt, pub addr_next: Felt, @@ -166,7 +155,7 @@ impl Display for SpanBlockMessage { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!( f, - "transition_label: {}, addr_next: {}, state: {:?}", + "{{ transition_label: {}, addr_next: {}, state: {:?} }}", self.transition_label, self.addr_next, self.state ) } @@ -202,7 +191,7 @@ impl Display for RespanBlockMessage { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!( f, - "transition_label: {}, addr_next: {}, state: {:?}", + "{{ transition_label: {}, addr_next: {}, state: {:?} }}", self.transition_label, self.addr_next, self.state ) } @@ -237,7 +226,7 @@ impl Display for EndBlockMessage { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!( f, - "addr: {}, transition_label: {}, digest: {:?}", + "{{ addr: {}, transition_label: {}, digest: {:?} }}", self.addr, self.transition_label, self.digest ) } @@ -246,14 +235,14 @@ impl Display for EndBlockMessage { // BITWISE REQUEST MESSAGE // =============================================================================================== -pub struct BitwiseRequestMessage { +pub struct BitwiseMessage { pub op_label: Felt, pub a: Felt, pub b: Felt, pub z: Felt, } -impl BusMessage for BitwiseRequestMessage +impl BusMessage for BitwiseMessage where E: FieldElement, { @@ -266,9 +255,13 @@ where } } -impl Display for BitwiseRequestMessage { +impl Display for BitwiseMessage { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "op_label: {}, a: {}, b: {}, z: {}", self.op_label, self.a, self.b, self.z) + write!( + f, + "{{ op_label: {}, a: {}, b: {}, z: {} }}", + self.op_label, self.a, self.b, self.z + ) } } @@ -281,6 +274,7 @@ pub struct MemRequestWordMessage { pub addr: Felt, pub clk: Felt, pub word: [Felt; 4], + pub source: &'static str, } impl BusMessage for MemRequestWordMessage @@ -305,7 +299,7 @@ where } fn source(&self) -> &str { - "memory word" + self.source } } @@ -313,7 +307,7 @@ impl Display for MemRequestWordMessage { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!( f, - "op_label: {}, ctx: {}, addr: {}, clk: {}, word: {:?}", + "{{ op_label: {}, ctx: {}, addr: {}, clk: {}, word: {:?} }}", self.op_label, self.ctx, self.addr, self.clk, self.word ) } @@ -351,313 +345,8 @@ impl Display for MemRequestElementMessage { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!( f, - "op_label: {}, ctx: {}, addr: {}, clk: {}, element: {}", + "{{ op_label: {}, ctx: {}, addr: {}, clk: {}, element: {} }}", self.op_label, self.ctx, self.addr, self.clk, self.element ) } } - -// MSTREAM REQUEST MESSAGE -// =============================================================================================== - -pub struct MstreamRequestMessage { - pub mem_req_1: MemRequestWordMessage, - pub mem_req_2: MemRequestWordMessage, -} - -impl BusMessage for MstreamRequestMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - self.mem_req_1.value(alphas) * self.mem_req_2.value(alphas) - } - - fn source(&self) -> &str { - "mstream" - } -} - -impl Display for MstreamRequestMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "mem_req_1: {} || mem_req_2: {}", self.mem_req_1, self.mem_req_2) - } -} - -// PIPE REQUEST MESSAGE -// =============================================================================================== - -pub struct PipeRequestMessage { - pub mem_req_1: MemRequestWordMessage, - pub mem_req_2: MemRequestWordMessage, -} - -impl BusMessage for PipeRequestMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - self.mem_req_1.value(alphas) * self.mem_req_2.value(alphas) - } - - fn source(&self) -> &str { - "pipe" - } -} - -impl Display for PipeRequestMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "mem_req_1: {} || mem_req_2: {}", self.mem_req_1, self.mem_req_2) - } -} - -// RCOMB BASE REQUEST MESSAGE -// =============================================================================================== - -pub struct RcombBaseRequestMessage { - pub mem_req_1: MemRequestWordMessage, - pub mem_req_2: MemRequestWordMessage, -} - -impl BusMessage for RcombBaseRequestMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - self.mem_req_1.value(alphas) * self.mem_req_2.value(alphas) - } - - fn source(&self) -> &str { - "rcombbase" - } -} - -impl Display for RcombBaseRequestMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "mem_req_1: {} || mem_req_2: {}", self.mem_req_1, self.mem_req_2) - } -} - -// HPERM REQUEST MESSAGE -// =============================================================================================== - -pub struct HpermRequestMessage { - pub helper_0: Felt, - pub s0_s12_cur: [Felt; 12], - pub s0_s12_nxt: [Felt; 12], -} - -impl BusMessage for HpermRequestMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - let v_input_req = { - let op_label = LINEAR_HASH_LABEL + 16; - - let sum_input = alphas[4..16] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s0_s12_cur[i])); - - alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(self.helper_0) - + sum_input - }; - - let v_output_req = { - let op_label = RETURN_STATE_LABEL + 32; - - let sum_output = alphas[4..16] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s0_s12_nxt[i])); - alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(self.helper_0 + Felt::new(7)) - + sum_output - }; - - v_input_req * v_output_req - } - - fn source(&self) -> &str { - "hperm" - } -} - -impl Display for HpermRequestMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - "helper_0: {}, s0_s12_cur: {:?}, s0_s12_nxt: {:?}", - self.helper_0, self.s0_s12_cur, self.s0_s12_nxt - ) - } -} - -// MPVERIFY REQUEST MESSAGE -// =============================================================================================== - -pub struct MpverifyRequestMessage { - pub helper_0: Felt, - pub s0_s3: [Felt; 4], - pub s4: Felt, - pub s5: Felt, - pub s6_s9: [Felt; 4], -} - -impl BusMessage for MpverifyRequestMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - let op_label = MP_VERIFY_LABEL + 16; - - let v_input = { - let sum_input = alphas[8..12] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s0_s3[i])); - - alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(self.helper_0) - + alphas[3].mul_base(self.s5) - + sum_input - }; - - let v_output = { - let op_label = RETURN_HASH_LABEL + 32; - - let sum_output = alphas[8..12] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s6_s9[i])); - alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(self.helper_0 + self.s4.mul_small(8) - ONE) - + sum_output - }; - - v_input * v_output - } - - fn source(&self) -> &str { - "mpverify" - } -} - -impl Display for MpverifyRequestMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - "helper_0: {}, s0_s3: {:?}, s4: {}, s5: {}, s6_s9: {:?}", - self.helper_0, self.s0_s3, self.s4, self.s5, self.s6_s9 - ) - } -} - -// MRUPDATE REQUEST MESSAGE -// =============================================================================================== - -pub struct MrupdateRequestMessage { - pub helper_0: Felt, - pub s0_s3: [Felt; 4], - pub s0_s3_nxt: [Felt; 4], - pub s4: Felt, - pub s5: Felt, - pub s6_s9: [Felt; 4], - pub s10_s13: [Felt; 4], -} - -impl BusMessage for MrupdateRequestMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - let v_input_old = { - let op_label = MR_UPDATE_OLD_LABEL + 16; - - let sum_input = alphas[8..12] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s0_s3[i])); - alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(self.helper_0) - + alphas[3].mul_base(self.s5) - + sum_input - }; - - let v_output_old = { - let op_label = RETURN_HASH_LABEL + 32; - - let sum_output = alphas[8..12] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s6_s9[i])); - alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(self.helper_0 + self.s4.mul_small(8) - ONE) - + sum_output - }; - - let v_input_new = { - let op_label = MR_UPDATE_NEW_LABEL + 16; - let sum_input = alphas[8..12] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s10_s13[i])); - alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(self.helper_0 + self.s4.mul_small(8)) - + alphas[3].mul_base(self.s5) - + sum_input - }; - - let v_output_new = { - let op_label = RETURN_HASH_LABEL + 32; - - let sum_output = alphas[8..12] - .iter() - .rev() - .enumerate() - .fold(E::ZERO, |acc, (i, x)| acc + x.mul_base(self.s0_s3_nxt[i])); - alphas[0] - + alphas[1].mul_base(Felt::from(op_label)) - + alphas[2].mul_base(self.helper_0 + self.s4.mul_small(16) - ONE) - + sum_output - }; - - v_input_old * v_output_old * v_input_new * v_output_new - } - - fn source(&self) -> &str { - "mrupdate" - } -} - -impl Display for MrupdateRequestMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - "helper_0: {}, s0_s3: {:?}, s0_s3_nxt: {:?}, s4: {}, s5: {}, s6_s9: {:?}, s10_s13: {:?}", - self.helper_0, - self.s0_s3, - self.s0_s3_nxt, - self.s4, - self.s5, - self.s6_s9, - self.s10_s13, - ) - } -} diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index 4c83a0611f..cedcfbba2c 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -1,20 +1,18 @@ -use alloc::vec::Vec; +use alloc::{boxed::Box, vec::Vec}; use messages::{ - BitwiseRequestMessage, ControlBlockMessage, DynBlockMessage, EndBlockMessage, - HpermRequestMessage, MemRequestElementMessage, MemRequestWordMessage, MpverifyRequestMessage, - MrupdateRequestMessage, MstreamRequestMessage, PipeRequestMessage, RcombBaseRequestMessage, - RespanBlockMessage, SpanBlockMessage, SyscallBlockMessage, + BitwiseMessage, ControlBlockRequestMessage, EndBlockMessage, HasherMessage, KernelRomMessage, + MemRequestElementMessage, MemRequestWordMessage, RespanBlockMessage, SpanBlockMessage, }; use miden_air::{ trace::{ chiplets::{ bitwise::OP_CYCLE_LEN as BITWISE_OP_CYCLE_LEN, hasher::{ - CAPACITY_LEN, DIGEST_RANGE, HASH_CYCLE_LEN, LINEAR_HASH_LABEL, NUM_ROUNDS, - RETURN_HASH_LABEL, STATE_WIDTH, + DIGEST_RANGE, HASH_CYCLE_LEN, LINEAR_HASH_LABEL, MP_VERIFY_LABEL, + MR_UPDATE_NEW_LABEL, MR_UPDATE_OLD_LABEL, NUM_ROUNDS, RETURN_HASH_LABEL, + RETURN_STATE_LABEL, }, - kernel_rom::KERNEL_PROC_LABEL, memory::{ MEMORY_ACCESS_ELEMENT, MEMORY_ACCESS_WORD, MEMORY_READ_ELEMENT_LABEL, MEMORY_READ_WORD_LABEL, MEMORY_WRITE_ELEMENT_LABEL, MEMORY_WRITE_WORD_LABEL, @@ -39,7 +37,6 @@ mod messages; // CONSTANTS // ================================================================================================ -const NUM_HEADER_ALPHAS: usize = 4; const FOUR: Felt = Felt::new(4); // CHIPLETS AUXILIARY TRACE BUILDER @@ -306,7 +303,7 @@ impl> AuxColumnBuilder for BusColumnBuilder main_trace: &MainTrace, alphas: &[E], row: RowIndex, - _debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E where E: FieldElement, @@ -321,57 +318,78 @@ impl> AuxColumnBuilder for BusColumnBuilder op_code_felt, alphas, row, + #[cfg(any(test, feature = "testing"))] + debugger, ), OPCODE_DYN | OPCODE_DYNCALL => { - build_dyn_block_request(main_trace, op_code_felt, alphas, row) - }, - OPCODE_SYSCALL => build_syscall_block_request(main_trace, op_code_felt, alphas, row), - OPCODE_SPAN => build_span_block_request(main_trace, alphas, row), - OPCODE_RESPAN => build_respan_block_request(main_trace, alphas, row), - OPCODE_END => build_end_block_request(main_trace, alphas, row), - OPCODE_U32AND => build_bitwise_request(main_trace, ZERO, alphas, row), - OPCODE_U32XOR => build_bitwise_request(main_trace, ONE, alphas, row), - OPCODE_MLOADW => { - build_mem_mloadw_mstorew_request(main_trace, MEMORY_READ_WORD_LABEL, alphas, row) - }, - OPCODE_MSTOREW => { - build_mem_mloadw_mstorew_request(main_trace, MEMORY_WRITE_WORD_LABEL, alphas, row) - }, - OPCODE_MLOAD => { - build_mem_mload_mstore_request(main_trace, MEMORY_READ_ELEMENT_LABEL, alphas, row) + build_dyn_block_request(main_trace, op_code_felt, alphas, row, debugger) }, - OPCODE_MSTORE => { - build_mem_mload_mstore_request(main_trace, MEMORY_WRITE_ELEMENT_LABEL, alphas, row) + OPCODE_SYSCALL => { + build_syscall_block_request(main_trace, op_code_felt, alphas, row, debugger) }, - OPCODE_MSTREAM => build_mstream_request(main_trace, alphas, row), - OPCODE_RCOMBBASE => build_rcomb_base_request(main_trace, alphas, row), - OPCODE_HPERM => build_hperm_request(main_trace, alphas, row), - OPCODE_MPVERIFY => build_mpverify_request(main_trace, alphas, row), - OPCODE_MRUPDATE => build_mrupdate_request(main_trace, alphas, row), - OPCODE_PIPE => build_pipe_request(main_trace, alphas, row), + OPCODE_SPAN => build_span_block_request(main_trace, alphas, row, debugger), + OPCODE_RESPAN => build_respan_block_request(main_trace, alphas, row, debugger), + OPCODE_END => build_end_block_request(main_trace, alphas, row, debugger), + OPCODE_U32AND => build_bitwise_request(main_trace, ZERO, alphas, row, debugger), + OPCODE_U32XOR => build_bitwise_request(main_trace, ONE, alphas, row, debugger), + OPCODE_MLOADW => build_mem_mloadw_mstorew_request( + main_trace, + MEMORY_READ_WORD_LABEL, + alphas, + row, + debugger, + ), + OPCODE_MSTOREW => build_mem_mloadw_mstorew_request( + main_trace, + MEMORY_WRITE_WORD_LABEL, + alphas, + row, + debugger, + ), + OPCODE_MLOAD => build_mem_mload_mstore_request( + main_trace, + MEMORY_READ_ELEMENT_LABEL, + alphas, + row, + debugger, + ), + OPCODE_MSTORE => build_mem_mload_mstore_request( + main_trace, + MEMORY_WRITE_ELEMENT_LABEL, + alphas, + row, + debugger, + ), + OPCODE_MSTREAM => build_mstream_request(main_trace, alphas, row, debugger), + OPCODE_RCOMBBASE => build_rcomb_base_request(main_trace, alphas, row, debugger), + OPCODE_HPERM => build_hperm_request(main_trace, alphas, row, debugger), + OPCODE_MPVERIFY => build_mpverify_request(main_trace, alphas, row, debugger), + OPCODE_MRUPDATE => build_mrupdate_request(main_trace, alphas, row, debugger), + OPCODE_PIPE => build_pipe_request(main_trace, alphas, row, debugger), _ => E::ONE, } } + // TODO(plafer): `debugger` field only in test mode /// Constructs the responses from the chiplets to the other VM-components at `row`. fn get_responses_at( &self, main_trace: &MainTrace, alphas: &[E], row: RowIndex, - _debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E where E: FieldElement, { if main_trace.is_hash_row(row) { - build_hasher_chiplet_responses(main_trace, row, alphas) + build_hasher_chiplet_responses(main_trace, row, alphas, debugger) } else if main_trace.is_bitwise_row(row) { - build_bitwise_chiplet_responses(main_trace, row, alphas) + build_bitwise_chiplet_responses(main_trace, row, alphas, debugger) } else if main_trace.is_memory_row(row) { - build_memory_chiplet_responses(main_trace, row, alphas) + build_memory_chiplet_responses(main_trace, row, alphas, debugger) } else if main_trace.is_kernel_row(row) { - build_kernel_chiplet_responses(main_trace, row, alphas) + build_kernel_chiplet_responses(main_trace, row, alphas, debugger) } else { E::ONE } @@ -388,15 +406,21 @@ fn build_control_block_request>( op_code_felt: Felt, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { - let message = ControlBlockMessage { + let message = ControlBlockRequestMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 16), addr_next: main_trace.addr(row + 1), op_code: op_code_felt, decoder_hasher_state, }; - message.value(alphas) + let value = message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_request(Box::new(message), alphas); + + value } /// Builds requests made on a `DYN` or `DYNCALL` operation. @@ -405,8 +429,9 @@ fn build_dyn_block_request>( op_code_felt: Felt, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { - let control_block_req = ControlBlockMessage { + let control_block_req = ControlBlockRequestMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 16), addr_next: main_trace.addr(row + 1), op_code: op_code_felt, @@ -419,11 +444,21 @@ fn build_dyn_block_request>( addr: main_trace.stack_element(0, row), clk: main_trace.clk(row), word: main_trace.decoder_hasher_state_first_half(row), + source: if op_code_felt == OPCODE_DYNCALL.into() { + "dyncall" + } else { + "dyn" + }, }; - let dyn_block_message = DynBlockMessage { control_block_req, memory_req }; + let combined_value = control_block_req.value(alphas) * memory_req.value(alphas); + #[cfg(any(test, feature = "testing"))] + { + debugger.add_request(Box::new(control_block_req), alphas); + debugger.add_request(Box::new(memory_req), alphas); + } - dyn_block_message.value(alphas) + combined_value } /// Builds requests made to kernel ROM chiplet when initializing a syscall block. @@ -432,20 +467,28 @@ fn build_syscall_block_request>( op_code_felt: Felt, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { - let control_block_req = ControlBlockMessage { + let control_block_req = ControlBlockRequestMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 16), addr_next: main_trace.addr(row + 1), op_code: op_code_felt, decoder_hasher_state: main_trace.decoder_hasher_state(row), }; - let syscall_block_message = SyscallBlockMessage { - control_block_req, + let kernel_rom_req = KernelRomMessage { kernel_proc_digest: main_trace.decoder_hasher_state(row)[0..4].try_into().unwrap(), }; - syscall_block_message.value(alphas) + let combined_value = control_block_req.value(alphas) * kernel_rom_req.value(alphas); + + #[cfg(any(test, feature = "testing"))] + { + debugger.add_request(Box::new(control_block_req), alphas); + debugger.add_request(Box::new(kernel_rom_req), alphas); + } + + combined_value } /// Builds requests made to the hasher chiplet at the start of a span block. @@ -453,6 +496,7 @@ fn build_span_block_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { let span_block_message = SpanBlockMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 16), @@ -460,7 +504,12 @@ fn build_span_block_request>( state: main_trace.decoder_hasher_state(row), }; - span_block_message.value(alphas) + let value = span_block_message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_request(Box::new(span_block_message), alphas); + + value } /// Builds requests made to the hasher chiplet at the start of a respan block. @@ -468,6 +517,7 @@ fn build_respan_block_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { let respan_block_message = RespanBlockMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 32), @@ -475,7 +525,12 @@ fn build_respan_block_request>( state: main_trace.decoder_hasher_state(row), }; - respan_block_message.value(alphas) + let value = respan_block_message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_request(Box::new(respan_block_message), alphas); + + value } /// Builds requests made to the hasher chiplet at the end of a block. @@ -483,6 +538,7 @@ fn build_end_block_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { let end_block_message = EndBlockMessage { addr: main_trace.addr(row) + Felt::from(NUM_ROUNDS as u8), @@ -490,7 +546,12 @@ fn build_end_block_request>( digest: main_trace.decoder_hasher_state(row)[..4].try_into().unwrap(), }; - end_block_message.value(alphas) + let value = end_block_message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_request(Box::new(end_block_message), alphas); + + value } /// Builds requests made to the bitwise chiplet. This can be either a request for the computation @@ -500,15 +561,21 @@ fn build_bitwise_request>( is_xor: Felt, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { - let bitwise_request_message = BitwiseRequestMessage { + let bitwise_request_message = BitwiseMessage { op_label: get_op_label(ONE, ZERO, is_xor, ZERO), a: main_trace.stack_element(1, row), b: main_trace.stack_element(0, row), z: main_trace.stack_element(0, row + 1), }; - bitwise_request_message.value(alphas) + let value = bitwise_request_message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_request(Box::new(bitwise_request_message), alphas); + + value } /// Builds `MSTREAM` requests made to the memory chiplet. @@ -516,40 +583,49 @@ fn build_mstream_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { let op_label = Felt::from(MEMORY_READ_WORD_LABEL); let addr = main_trace.stack_element(12, row); let ctx = main_trace.ctx(row); let clk = main_trace.clk(row); - let mstream_request_message = MstreamRequestMessage { - mem_req_1: MemRequestWordMessage { - op_label, - ctx, - addr, - clk, - word: [ - main_trace.stack_element(7, row + 1), - main_trace.stack_element(6, row + 1), - main_trace.stack_element(5, row + 1), - main_trace.stack_element(4, row + 1), - ], - }, - mem_req_2: MemRequestWordMessage { - op_label, - ctx, - addr: addr + FOUR, - clk, - word: [ - main_trace.stack_element(3, row + 1), - main_trace.stack_element(2, row + 1), - main_trace.stack_element(1, row + 1), - main_trace.stack_element(0, row + 1), - ], - }, + let mem_req_1 = MemRequestWordMessage { + op_label, + ctx, + addr, + clk, + word: [ + main_trace.stack_element(7, row + 1), + main_trace.stack_element(6, row + 1), + main_trace.stack_element(5, row + 1), + main_trace.stack_element(4, row + 1), + ], + source: "mstream req 1", + }; + let mem_req_2 = MemRequestWordMessage { + op_label, + ctx, + addr: addr + FOUR, + clk, + word: [ + main_trace.stack_element(3, row + 1), + main_trace.stack_element(2, row + 1), + main_trace.stack_element(1, row + 1), + main_trace.stack_element(0, row + 1), + ], + source: "mstream req 2", }; - mstream_request_message.value(alphas) + let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); + + #[cfg(any(test, feature = "testing"))] + { + debugger.add_request(Box::new(mem_req_1), alphas); + debugger.add_request(Box::new(mem_req_2), alphas); + } + + combined_value } /// Builds `PIPE` requests made to the memory chiplet. @@ -557,40 +633,49 @@ fn build_pipe_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { let op_label = Felt::from(MEMORY_WRITE_WORD_LABEL); let addr = main_trace.stack_element(12, row); let ctx = main_trace.ctx(row); let clk = main_trace.clk(row); - let pipe_request_message = PipeRequestMessage { - mem_req_1: MemRequestWordMessage { - op_label, - ctx, - addr, - clk, - word: [ - main_trace.stack_element(7, row + 1), - main_trace.stack_element(6, row + 1), - main_trace.stack_element(5, row + 1), - main_trace.stack_element(4, row + 1), - ], - }, - mem_req_2: MemRequestWordMessage { - op_label, - ctx, - addr: addr + FOUR, - clk, - word: [ - main_trace.stack_element(3, row + 1), - main_trace.stack_element(2, row + 1), - main_trace.stack_element(1, row + 1), - main_trace.stack_element(0, row + 1), - ], - }, + let mem_req_1 = MemRequestWordMessage { + op_label, + ctx, + addr, + clk, + word: [ + main_trace.stack_element(7, row + 1), + main_trace.stack_element(6, row + 1), + main_trace.stack_element(5, row + 1), + main_trace.stack_element(4, row + 1), + ], + source: "pipe req 1", + }; + let mem_req_2 = MemRequestWordMessage { + op_label, + ctx, + addr: addr + FOUR, + clk, + word: [ + main_trace.stack_element(3, row + 1), + main_trace.stack_element(2, row + 1), + main_trace.stack_element(1, row + 1), + main_trace.stack_element(0, row + 1), + ], + source: "pipe req 2", }; - pipe_request_message.value(alphas) + let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); + + #[cfg(any(test, feature = "testing"))] + { + debugger.add_request(Box::new(mem_req_1), alphas); + debugger.add_request(Box::new(mem_req_2), alphas); + } + + combined_value } /// Builds `RCOMBBASE` requests made to the memory chiplet. @@ -598,6 +683,7 @@ fn build_rcomb_base_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { let tz0 = main_trace.helper_register(0, row); let tz1 = main_trace.helper_register(1, row); @@ -612,24 +698,32 @@ fn build_rcomb_base_request>( let ctx = main_trace.ctx(row); let clk = main_trace.clk(row); - let rcombbase_request_message = RcombBaseRequestMessage { - mem_req_1: MemRequestWordMessage { - op_label, - ctx, - addr: z_ptr, - clk, - word: [tz0, tz1, tzg0, tzg1], - }, - mem_req_2: MemRequestWordMessage { - op_label, - ctx, - addr: a_ptr, - clk, - word: [a0, a1, ZERO, ZERO], - }, + let mem_req_1 = MemRequestWordMessage { + op_label, + ctx, + addr: z_ptr, + clk, + word: [tz0, tz1, tzg0, tzg1], + source: "rcombbase req 1", + }; + let mem_req_2 = MemRequestWordMessage { + op_label, + ctx, + addr: a_ptr, + clk, + word: [a0, a1, ZERO, ZERO], + source: "rcombbase req 2", }; - rcombbase_request_message.value(alphas) + let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); + + #[cfg(any(test, feature = "testing"))] + { + debugger.add_request(Box::new(mem_req_1), alphas); + debugger.add_request(Box::new(mem_req_2), alphas); + } + + combined_value } /// Builds `HPERM` requests made to the hash chiplet. @@ -637,40 +731,61 @@ fn build_hperm_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { - let hperm_request_message = HpermRequestMessage { - helper_0: main_trace.helper_register(0, row), - s0_s12_cur: [ - main_trace.stack_element(0, row), - main_trace.stack_element(1, row), - main_trace.stack_element(2, row), - main_trace.stack_element(3, row), - main_trace.stack_element(4, row), - main_trace.stack_element(5, row), - main_trace.stack_element(6, row), - main_trace.stack_element(7, row), - main_trace.stack_element(8, row), - main_trace.stack_element(9, row), - main_trace.stack_element(10, row), - main_trace.stack_element(11, row), - ], - s0_s12_nxt: [ - main_trace.stack_element(0, row + 1), - main_trace.stack_element(1, row + 1), - main_trace.stack_element(2, row + 1), - main_trace.stack_element(3, row + 1), - main_trace.stack_element(4, row + 1), - main_trace.stack_element(5, row + 1), - main_trace.stack_element(6, row + 1), - main_trace.stack_element(7, row + 1), - main_trace.stack_element(8, row + 1), - main_trace.stack_element(9, row + 1), - main_trace.stack_element(10, row + 1), - main_trace.stack_element(11, row + 1), + let helper_0 = main_trace.helper_register(0, row); + let s0 = main_trace.stack_element(0, row); + let s1 = main_trace.stack_element(1, row); + let s2 = main_trace.stack_element(2, row); + let s3 = main_trace.stack_element(3, row); + let s4 = main_trace.stack_element(4, row); + let s5 = main_trace.stack_element(5, row); + let s6 = main_trace.stack_element(6, row); + let s7 = main_trace.stack_element(7, row); + let s8 = main_trace.stack_element(8, row); + let s9 = main_trace.stack_element(9, row); + let s10 = main_trace.stack_element(10, row); + let s11 = main_trace.stack_element(11, row); + let s0_nxt = main_trace.stack_element(0, row + 1); + let s1_nxt = main_trace.stack_element(1, row + 1); + let s2_nxt = main_trace.stack_element(2, row + 1); + let s3_nxt = main_trace.stack_element(3, row + 1); + let s4_nxt = main_trace.stack_element(4, row + 1); + let s5_nxt = main_trace.stack_element(5, row + 1); + let s6_nxt = main_trace.stack_element(6, row + 1); + let s7_nxt = main_trace.stack_element(7, row + 1); + let s8_nxt = main_trace.stack_element(8, row + 1); + let s9_nxt = main_trace.stack_element(9, row + 1); + let s10_nxt = main_trace.stack_element(10, row + 1); + let s11_nxt = main_trace.stack_element(11, row + 1); + + let input_req = HasherMessage { + transition_label: Felt::from(LINEAR_HASH_LABEL + 16), + addr_next: helper_0, + node_index: ZERO, + hasher_state: [s11, s10, s9, s8, s7, s6, s5, s4, s3, s2, s1, s0], + source: "hperm input", + }; + let output_req = HasherMessage { + transition_label: Felt::from(RETURN_STATE_LABEL + 32), + addr_next: helper_0 + Felt::new(7), + node_index: ZERO, + hasher_state: [ + s11_nxt, s10_nxt, s9_nxt, s8_nxt, s7_nxt, s6_nxt, s5_nxt, s4_nxt, s3_nxt, s2_nxt, + s1_nxt, s0_nxt, ], + source: "hperm input", }; - hperm_request_message.value(alphas) + let combined_value = input_req.value(alphas) * output_req.value(alphas); + + #[cfg(any(test, feature = "testing"))] + { + debugger.add_request(Box::new(input_req), alphas); + debugger.add_request(Box::new(output_req), alphas); + } + + combined_value } /// Builds `MPVERIFY` requests made to the hash chiplet. @@ -678,26 +793,46 @@ fn build_mpverify_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { - let mpverify_request_message = MpverifyRequestMessage { - helper_0: main_trace.helper_register(0, row), - s0_s3: [ - main_trace.stack_element(0, row), - main_trace.stack_element(1, row), - main_trace.stack_element(2, row), - main_trace.stack_element(3, row), - ], - s4: main_trace.stack_element(4, row), - s5: main_trace.stack_element(5, row), - s6_s9: [ - main_trace.stack_element(6, row), - main_trace.stack_element(7, row), - main_trace.stack_element(8, row), - main_trace.stack_element(9, row), - ], + let helper_0 = main_trace.helper_register(0, row); + + let s0 = main_trace.stack_element(0, row); + let s1 = main_trace.stack_element(1, row); + let s2 = main_trace.stack_element(2, row); + let s3 = main_trace.stack_element(3, row); + let s4 = main_trace.stack_element(4, row); + let s5 = main_trace.stack_element(5, row); + let s6 = main_trace.stack_element(6, row); + let s7 = main_trace.stack_element(7, row); + let s8 = main_trace.stack_element(8, row); + let s9 = main_trace.stack_element(9, row); + + let input = HasherMessage { + transition_label: Felt::from(MP_VERIFY_LABEL + 16), + addr_next: helper_0, + node_index: s5, + hasher_state: [ZERO, ZERO, ZERO, ZERO, s3, s2, s1, s0, ZERO, ZERO, ZERO, ZERO], + source: "mpverify input", }; - mpverify_request_message.value(alphas) + let output = HasherMessage { + transition_label: Felt::from(RETURN_HASH_LABEL + 32), + addr_next: helper_0 + s4.mul_small(8) - ONE, + node_index: ZERO, + hasher_state: [ZERO, ZERO, ZERO, ZERO, s9, s8, s7, s6, ZERO, ZERO, ZERO, ZERO], + source: "mpverify output", + }; + + let combined_value = input.value(alphas) * output.value(alphas); + + #[cfg(any(test, feature = "testing"))] + { + debugger.add_request(Box::new(input), alphas); + debugger.add_request(Box::new(output), alphas); + } + + combined_value } /// Builds `MRUPDATE` requests made to the hash chiplet. @@ -705,45 +840,89 @@ fn build_mrupdate_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { - let mrupdate_request_message = MrupdateRequestMessage { - helper_0: main_trace.helper_register(0, row), - s0_s3: [ - main_trace.stack_element(0, row), - main_trace.stack_element(1, row), - main_trace.stack_element(2, row), - main_trace.stack_element(3, row), - ], - s0_s3_nxt: [ - main_trace.stack_element(0, row + 1), - main_trace.stack_element(1, row + 1), - main_trace.stack_element(2, row + 1), - main_trace.stack_element(3, row + 1), - ], - s4: main_trace.stack_element(4, row), - s5: main_trace.stack_element(5, row), - s6_s9: [ - main_trace.stack_element(6, row), - main_trace.stack_element(7, row), - main_trace.stack_element(8, row), - main_trace.stack_element(9, row), - ], - s10_s13: [ - main_trace.stack_element(10, row), - main_trace.stack_element(11, row), - main_trace.stack_element(12, row), - main_trace.stack_element(13, row), + let helper_0 = main_trace.helper_register(0, row); + + let s0 = main_trace.stack_element(0, row); + let s1 = main_trace.stack_element(1, row); + let s2 = main_trace.stack_element(2, row); + let s3 = main_trace.stack_element(3, row); + let s4 = main_trace.stack_element(4, row); + let s5 = main_trace.stack_element(5, row); + let s6 = main_trace.stack_element(6, row); + let s7 = main_trace.stack_element(7, row); + let s8 = main_trace.stack_element(8, row); + let s9 = main_trace.stack_element(9, row); + let s10 = main_trace.stack_element(10, row); + let s11 = main_trace.stack_element(11, row); + let s12 = main_trace.stack_element(12, row); + let s13 = main_trace.stack_element(13, row); + let s0_nxt = main_trace.stack_element(0, row + 1); + let s1_nxt = main_trace.stack_element(1, row + 1); + let s2_nxt = main_trace.stack_element(2, row + 1); + let s3_nxt = main_trace.stack_element(3, row + 1); + + let input_old = HasherMessage { + transition_label: Felt::from(MR_UPDATE_OLD_LABEL + 16), + addr_next: helper_0, + node_index: s5, + hasher_state: [ZERO, ZERO, ZERO, ZERO, s3, s2, s1, s0, ZERO, ZERO, ZERO, ZERO], + source: "mrupdate input_old", + }; + + let output_old = HasherMessage { + transition_label: Felt::from(RETURN_HASH_LABEL + 32), + addr_next: helper_0 + s4.mul_small(8) - ONE, + node_index: ZERO, + hasher_state: [ZERO, ZERO, ZERO, ZERO, s9, s8, s7, s6, ZERO, ZERO, ZERO, ZERO], + source: "mrupdate output_old", + }; + + let input_new = HasherMessage { + transition_label: Felt::from(MR_UPDATE_NEW_LABEL + 16), + addr_next: helper_0 + s4.mul_small(8), + node_index: s5, + hasher_state: [ZERO, ZERO, ZERO, ZERO, s13, s12, s11, s10, ZERO, ZERO, ZERO, ZERO], + source: "mrupdate input_new", + }; + + let output_new = HasherMessage { + transition_label: Felt::from(RETURN_HASH_LABEL + 32), + addr_next: helper_0 + s4.mul_small(16) - ONE, + node_index: ZERO, + hasher_state: [ + ZERO, ZERO, ZERO, ZERO, s3_nxt, s2_nxt, s1_nxt, s0_nxt, ZERO, ZERO, ZERO, ZERO, ], + source: "mrupdate output_new", }; - mrupdate_request_message.value(alphas) + let combined_value = input_old.value(alphas) + * output_old.value(alphas) + * input_new.value(alphas) + * output_new.value(alphas); + + #[cfg(any(test, feature = "testing"))] + { + debugger.add_request(Box::new(input_old), alphas); + debugger.add_request(Box::new(output_old), alphas); + debugger.add_request(Box::new(input_new), alphas); + debugger.add_request(Box::new(output_new), alphas); + } + + combined_value } // CHIPLETS RESPONSES // ================================================================================================ /// Builds the response from the hasher chiplet at `row`. -fn build_hasher_chiplet_responses(main_trace: &MainTrace, row: RowIndex, alphas: &[E]) -> E +fn build_hasher_chiplet_responses( + main_trace: &MainTrace, + row: RowIndex, + alphas: &[E], + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, +) -> E where E: FieldElement, { @@ -753,141 +932,209 @@ where let selector2 = main_trace.chiplet_selector_2(row); let selector3 = main_trace.chiplet_selector_3(row); let op_label = get_op_label(selector0, selector1, selector2, selector3); + let addr_next = Felt::from(row + 1); // f_bp, f_mp, f_mv or f_mu == 1 if row.as_usize() % HASH_CYCLE_LEN == 0 { let state = main_trace.chiplet_hasher_state(row); - let alphas_state = &alphas[NUM_HEADER_ALPHAS..(NUM_HEADER_ALPHAS + STATE_WIDTH)]; let node_index = main_trace.chiplet_node_index(row); let transition_label = op_label + Felt::from(16_u8); // f_bp == 1 // v_all = v_h + v_a + v_b + v_c if selector1 == ONE && selector2 == ZERO && selector3 == ZERO { - let header = alphas[0] - + build_value(&alphas[1..4], [transition_label, Felt::from(row + 1), node_index]); - - multiplicand = header + build_value(alphas_state, state); + let hasher_message = HasherMessage { + transition_label, + addr_next, + node_index, + hasher_state: state, + source: "hasher", + }; + multiplicand = hasher_message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_response(Box::new(hasher_message), alphas); } // f_mp or f_mv or f_mu == 1 // v_leaf = v_h + (1 - b) * v_b + b * v_d if selector1 == ONE && !(selector2 == ZERO && selector3 == ZERO) { - let header = alphas[0] - + build_value(&alphas[1..4], [transition_label, Felt::from(row + 1), node_index]); - let bit = (node_index.as_int() & 1) as u8; - let left_word = build_value::<_, 4>( - &alphas_state[DIGEST_RANGE], - state[DIGEST_RANGE].try_into().unwrap(), - ); - let right_word = build_value::<_, 4>( - &alphas_state[DIGEST_RANGE], - state[DIGEST_RANGE.end..].try_into().unwrap(), - ); - - multiplicand = header + E::from(1 - bit).mul(left_word) + E::from(bit).mul(right_word); + if bit == 0 { + let hasher_message = HasherMessage { + transition_label, + addr_next, + node_index, + hasher_state: [ + state[4], state[5], state[6], state[7], ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, + ZERO, ZERO, + ], + source: "hasher", + }; + + multiplicand = hasher_message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_response(Box::new(hasher_message), alphas); + } else { + let hasher_message = HasherMessage { + transition_label, + addr_next, + node_index, + hasher_state: [ + ZERO, ZERO, ZERO, ZERO, state[8], state[9], state[10], state[11], ZERO, + ZERO, ZERO, ZERO, + ], + source: "hasher", + }; + + multiplicand = hasher_message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_response(Box::new(hasher_message), alphas); + } } } // f_hout, f_sout, f_abp == 1 if row.as_usize() % HASH_CYCLE_LEN == HASH_CYCLE_LEN - 1 { let state = main_trace.chiplet_hasher_state(row); - let alphas_state = &alphas[NUM_HEADER_ALPHAS..(NUM_HEADER_ALPHAS + STATE_WIDTH)]; let node_index = main_trace.chiplet_node_index(row); let transition_label = op_label + Felt::from(32_u8); // f_hout == 1 // v_res = v_h + v_b; if selector1 == ZERO && selector2 == ZERO && selector3 == ZERO { - let header = alphas[0] - + build_value(&alphas[1..4], [transition_label, Felt::from(row + 1), node_index]); - - multiplicand = header - + build_value::<_, 4>( - &alphas_state[DIGEST_RANGE], - state[DIGEST_RANGE].try_into().unwrap(), - ); + let hasher_message = HasherMessage { + transition_label, + addr_next, + node_index, + hasher_state: [ + ZERO, ZERO, ZERO, ZERO, state[4], state[5], state[6], state[7], ZERO, ZERO, + ZERO, ZERO, + ], + source: "hasher", + }; + multiplicand = hasher_message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_response(Box::new(hasher_message), alphas); } // f_sout == 1 // v_all = v_h + v_a + v_b + v_c if selector1 == ZERO && selector2 == ZERO && selector3 == ONE { - let header = alphas[0] - + build_value(&alphas[1..4], [transition_label, Felt::from(row + 1), node_index]); - - multiplicand = header + build_value(alphas_state, state); + let hasher_message = HasherMessage { + transition_label, + addr_next, + node_index, + hasher_state: state, + source: "hasher", + }; + + multiplicand = hasher_message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_response(Box::new(hasher_message), alphas); } // f_abp == 1 // v_abp = v_h + v_b' + v_c' - v_b - v_c if selector1 == ONE && selector2 == ZERO && selector3 == ZERO { - let header = alphas[0] - + build_value(&alphas[1..4], [transition_label, Felt::from(row + 1), node_index]); - - let state_nxt = main_trace.chiplet_hasher_state(row + 1); - // build the value from the hasher state's just right after the absorption of new // elements. - const SIZE: usize = STATE_WIDTH - CAPACITY_LEN; - let next_state_value = build_value::<_, SIZE>( - &alphas_state[CAPACITY_LEN..], - state_nxt[CAPACITY_LEN..].try_into().unwrap(), - ); + let state_nxt = main_trace.chiplet_hasher_state(row + 1); - multiplicand = header + next_state_value; + let hasher_message = HasherMessage { + transition_label, + addr_next, + node_index, + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + state_nxt[4], + state_nxt[5], + state_nxt[6], + state_nxt[7], + state_nxt[8], + state_nxt[9], + state_nxt[10], + state_nxt[11], + ], + source: "hasher", + }; + + multiplicand = hasher_message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_response(Box::new(hasher_message), alphas); } } multiplicand } /// Builds the response from the bitwise chiplet at `row`. -fn build_bitwise_chiplet_responses(main_trace: &MainTrace, row: RowIndex, alphas: &[E]) -> E +fn build_bitwise_chiplet_responses( + main_trace: &MainTrace, + row: RowIndex, + alphas: &[E], + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, +) -> E where E: FieldElement, { let is_xor = main_trace.chiplet_selector_2(row); if row.as_usize() % BITWISE_OP_CYCLE_LEN == BITWISE_OP_CYCLE_LEN - 1 { - let op_label = get_op_label(ONE, ZERO, is_xor, ZERO); + let bitwise_message = BitwiseMessage { + op_label: get_op_label(ONE, ZERO, is_xor, ZERO), + a: main_trace.chiplet_bitwise_a(row), + b: main_trace.chiplet_bitwise_b(row), + z: main_trace.chiplet_bitwise_z(row), + }; - let a = main_trace.chiplet_bitwise_a(row); - let b = main_trace.chiplet_bitwise_b(row); - let z = main_trace.chiplet_bitwise_z(row); + let value = bitwise_message.value(alphas); - alphas[0] + build_value(&alphas[1..5], [op_label, a, b, z]) + #[cfg(any(test, feature = "testing"))] + debugger.add_response(Box::new(bitwise_message), alphas); + + value } else { E::ONE } } /// Builds the response from the memory chiplet at `row`. -fn build_memory_chiplet_responses(main_trace: &MainTrace, row: RowIndex, alphas: &[E]) -> E +fn build_memory_chiplet_responses( + main_trace: &MainTrace, + row: RowIndex, + alphas: &[E], + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, +) -> E where E: FieldElement, { - let is_word_access = main_trace.chiplet_selector_4(row); - let header = { + let access_type = main_trace.chiplet_selector_4(row); + let op_label = { let is_read = main_trace.chiplet_selector_3(row); - let op_label = get_memory_op_label(is_read, is_word_access); - - let ctx = main_trace.chiplet_memory_ctx(row); - let clk = main_trace.chiplet_memory_clk(row); - let address = { - let word = main_trace.chiplet_memory_word(row); - let idx0 = main_trace.chiplet_memory_idx0(row); - let idx1 = main_trace.chiplet_memory_idx1(row); - - word + idx1.mul_small(2) + idx0 - }; + get_memory_op_label(is_read, access_type) + }; + let ctx = main_trace.chiplet_memory_ctx(row); + let clk = main_trace.chiplet_memory_clk(row); + let addr = { + let word = main_trace.chiplet_memory_word(row); + let idx0 = main_trace.chiplet_memory_idx0(row); + let idx1 = main_trace.chiplet_memory_idx1(row); - alphas[0] + build_value(&alphas[1..5], [op_label, ctx, address, clk]) + word + idx1.mul_small(2) + idx0 }; - if is_word_access == MEMORY_ACCESS_ELEMENT { + let message: Box> = if access_type == MEMORY_ACCESS_ELEMENT { let idx0 = main_trace.chiplet_memory_idx0(row); let idx1 = main_trace.chiplet_memory_idx1(row); - let value = if idx1 == ZERO && idx0 == ZERO { + let element = if idx1 == ZERO && idx0 == ZERO { main_trace.chiplet_memory_value_0(row) } else if idx1 == ZERO && idx0 == ONE { main_trace.chiplet_memory_value_1(row) @@ -899,35 +1146,69 @@ where panic!("Invalid word indices. idx0: {idx0}, idx1: {idx1}"); }; - header + alphas[5].mul_base(value) - } else if is_word_access == MEMORY_ACCESS_WORD { + let message = MemRequestElementMessage { op_label, ctx, addr, clk, element }; + + Box::new(message) + } else if access_type == MEMORY_ACCESS_WORD { let value0 = main_trace.chiplet_memory_value_0(row); let value1 = main_trace.chiplet_memory_value_1(row); let value2 = main_trace.chiplet_memory_value_2(row); let value3 = main_trace.chiplet_memory_value_3(row); - header + build_value(&alphas[5..9], [value0, value1, value2, value3]) + let message = MemRequestWordMessage { + op_label, + ctx, + addr, + clk, + word: [value0, value1, value2, value3], + source: "memory chiplet", + }; + + Box::new(message) } else { - panic!("Invalid memory element/word column value: {is_word_access}"); - } + panic!("Invalid memory element/word column value: {access_type}"); + }; + + let value = message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_response(message, alphas); + + value } /// Builds the response from the kernel chiplet at `row`. -fn build_kernel_chiplet_responses(main_trace: &MainTrace, row: RowIndex, alphas: &[E]) -> E +fn build_kernel_chiplet_responses( + main_trace: &MainTrace, + row: RowIndex, + alphas: &[E], + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, +) -> E where E: FieldElement, { - let op_label = KERNEL_PROC_LABEL; + let kernel_chiplet_selector = main_trace.chiplet_selector_4(row); + if kernel_chiplet_selector == ONE { + let message = { + let root0 = main_trace.chiplet_kernel_root_0(row); + let root1 = main_trace.chiplet_kernel_root_1(row); + let root2 = main_trace.chiplet_kernel_root_2(row); + let root3 = main_trace.chiplet_kernel_root_3(row); - let root0 = main_trace.chiplet_kernel_root_0(row); - let root1 = main_trace.chiplet_kernel_root_1(row); - let root2 = main_trace.chiplet_kernel_root_2(row); - let root3 = main_trace.chiplet_kernel_root_3(row); + KernelRomMessage { + kernel_proc_digest: [root0, root1, root2, root3], + } + }; - let v = alphas[0] + build_value(&alphas[1..6], [op_label, root0, root1, root2, root3]); + let value = message.value(alphas); - let kernel_chiplet_selector = main_trace.chiplet_selector_4(row); - v.mul_base(kernel_chiplet_selector) + E::from(ONE - kernel_chiplet_selector) + #[cfg(any(test, feature = "testing"))] + debugger.add_response(Box::new(message), alphas); + + value + } else { + E::ONE + } } // HELPER FUNCTIONS @@ -971,6 +1252,7 @@ fn build_mem_mloadw_mstorew_request>( op_label: u8, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { let word = [ main_trace.stack_element(3, row + 1), @@ -980,7 +1262,7 @@ fn build_mem_mloadw_mstorew_request>( ]; let addr = main_trace.stack_element(0, row); - compute_mem_request_word(main_trace, op_label, alphas, row, addr, word) + compute_mem_request_word(main_trace, op_label, alphas, row, addr, word, debugger) } /// Builds `MLOAD` and `MSTORE` requests made to the memory chiplet. @@ -989,11 +1271,12 @@ fn build_mem_mload_mstore_request>( op_label: u8, alphas: &[E], row: RowIndex, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { let element = main_trace.stack_element(0, row + 1); let addr = main_trace.stack_element(0, row); - compute_mem_request_element(main_trace, op_label, alphas, row, addr, element) + compute_mem_request_element(main_trace, op_label, alphas, row, addr, element, debugger) } /// Computes a memory request for a read or write of a single element. @@ -1004,6 +1287,7 @@ fn compute_mem_request_element>( row: RowIndex, addr: Felt, element: Felt, + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { debug_assert!(op_label == MEMORY_READ_ELEMENT_LABEL || op_label == MEMORY_WRITE_ELEMENT_LABEL); @@ -1018,7 +1302,12 @@ fn compute_mem_request_element>( element, }; - message.value(alphas) + let value = message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_request(Box::new(message), alphas); + + value } /// Computes a memory request for a read or write of a word. @@ -1029,6 +1318,7 @@ fn compute_mem_request_word>( row: RowIndex, addr: Felt, word: [Felt; 4], + #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, ) -> E { debug_assert!(op_label == MEMORY_READ_WORD_LABEL || op_label == MEMORY_WRITE_WORD_LABEL); let ctx = main_trace.ctx(row); @@ -1040,7 +1330,17 @@ fn compute_mem_request_word>( addr, clk, word, + source: if op_label == MEMORY_READ_WORD_LABEL { + "mloadw" + } else { + "mstorew" + }, }; - message.value(alphas) + let value = message.value(alphas); + + #[cfg(any(test, feature = "testing"))] + debugger.add_request(Box::new(message), alphas); + + value } From 206fdec251b2931e0a819aeced40f5d5c1a1d24a Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Thu, 13 Feb 2025 09:58:29 -0500 Subject: [PATCH 05/21] fix: remove some `#[cfg(any(test, feature = "testing"))` --- processor/src/chiplets/aux_trace/mod.rs | 43 ++++++++++++------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index cedcfbba2c..751656957d 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -318,7 +318,6 @@ impl> AuxColumnBuilder for BusColumnBuilder op_code_felt, alphas, row, - #[cfg(any(test, feature = "testing"))] debugger, ), OPCODE_DYN | OPCODE_DYNCALL => { @@ -406,7 +405,7 @@ fn build_control_block_request>( op_code_felt: Felt, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let message = ControlBlockRequestMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 16), @@ -429,7 +428,7 @@ fn build_dyn_block_request>( op_code_felt: Felt, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let control_block_req = ControlBlockRequestMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 16), @@ -467,7 +466,7 @@ fn build_syscall_block_request>( op_code_felt: Felt, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let control_block_req = ControlBlockRequestMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 16), @@ -496,7 +495,7 @@ fn build_span_block_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let span_block_message = SpanBlockMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 16), @@ -517,7 +516,7 @@ fn build_respan_block_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let respan_block_message = RespanBlockMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 32), @@ -538,7 +537,7 @@ fn build_end_block_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let end_block_message = EndBlockMessage { addr: main_trace.addr(row) + Felt::from(NUM_ROUNDS as u8), @@ -561,7 +560,7 @@ fn build_bitwise_request>( is_xor: Felt, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let bitwise_request_message = BitwiseMessage { op_label: get_op_label(ONE, ZERO, is_xor, ZERO), @@ -583,7 +582,7 @@ fn build_mstream_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let op_label = Felt::from(MEMORY_READ_WORD_LABEL); let addr = main_trace.stack_element(12, row); @@ -633,7 +632,7 @@ fn build_pipe_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let op_label = Felt::from(MEMORY_WRITE_WORD_LABEL); let addr = main_trace.stack_element(12, row); @@ -683,7 +682,7 @@ fn build_rcomb_base_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let tz0 = main_trace.helper_register(0, row); let tz1 = main_trace.helper_register(1, row); @@ -731,7 +730,7 @@ fn build_hperm_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let helper_0 = main_trace.helper_register(0, row); let s0 = main_trace.stack_element(0, row); @@ -793,7 +792,7 @@ fn build_mpverify_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let helper_0 = main_trace.helper_register(0, row); @@ -840,7 +839,7 @@ fn build_mrupdate_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let helper_0 = main_trace.helper_register(0, row); @@ -921,7 +920,7 @@ fn build_hasher_chiplet_responses( main_trace: &MainTrace, row: RowIndex, alphas: &[E], - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E where E: FieldElement, @@ -1080,7 +1079,7 @@ fn build_bitwise_chiplet_responses( main_trace: &MainTrace, row: RowIndex, alphas: &[E], - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E where E: FieldElement, @@ -1110,7 +1109,7 @@ fn build_memory_chiplet_responses( main_trace: &MainTrace, row: RowIndex, alphas: &[E], - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E where E: FieldElement, @@ -1182,7 +1181,7 @@ fn build_kernel_chiplet_responses( main_trace: &MainTrace, row: RowIndex, alphas: &[E], - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E where E: FieldElement, @@ -1252,7 +1251,7 @@ fn build_mem_mloadw_mstorew_request>( op_label: u8, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let word = [ main_trace.stack_element(3, row + 1), @@ -1271,7 +1270,7 @@ fn build_mem_mload_mstore_request>( op_label: u8, alphas: &[E], row: RowIndex, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { let element = main_trace.stack_element(0, row + 1); let addr = main_trace.stack_element(0, row); @@ -1287,7 +1286,7 @@ fn compute_mem_request_element>( row: RowIndex, addr: Felt, element: Felt, - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { debug_assert!(op_label == MEMORY_READ_ELEMENT_LABEL || op_label == MEMORY_WRITE_ELEMENT_LABEL); @@ -1318,7 +1317,7 @@ fn compute_mem_request_word>( row: RowIndex, addr: Felt, word: [Felt; 4], - #[cfg(any(test, feature = "testing"))] debugger: &mut BusDebugger, + debugger: &mut BusDebugger, ) -> E { debug_assert!(op_label == MEMORY_READ_WORD_LABEL || op_label == MEMORY_WRITE_WORD_LABEL); let ctx = main_trace.ctx(row); From ff9d5d57d081e9c0ecb8b82f408ce3fd155014db Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Thu, 13 Feb 2025 14:28:17 -0500 Subject: [PATCH 06/21] chore: update chiplets bus var names for mrupdate --- processor/src/chiplets/aux_trace/mod.rs | 112 ++++++++++++++++++------ 1 file changed, 85 insertions(+), 27 deletions(-) diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index 751656957d..ea67269c73 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -843,55 +843,113 @@ fn build_mrupdate_request>( ) -> E { let helper_0 = main_trace.helper_register(0, row); - let s0 = main_trace.stack_element(0, row); - let s1 = main_trace.stack_element(1, row); - let s2 = main_trace.stack_element(2, row); - let s3 = main_trace.stack_element(3, row); - let s4 = main_trace.stack_element(4, row); - let s5 = main_trace.stack_element(5, row); - let s6 = main_trace.stack_element(6, row); - let s7 = main_trace.stack_element(7, row); - let s8 = main_trace.stack_element(8, row); - let s9 = main_trace.stack_element(9, row); - let s10 = main_trace.stack_element(10, row); - let s11 = main_trace.stack_element(11, row); - let s12 = main_trace.stack_element(12, row); - let s13 = main_trace.stack_element(13, row); - let s0_nxt = main_trace.stack_element(0, row + 1); - let s1_nxt = main_trace.stack_element(1, row + 1); - let s2_nxt = main_trace.stack_element(2, row + 1); - let s3_nxt = main_trace.stack_element(3, row + 1); + let old_node_value = [ + main_trace.stack_element(0, row), + main_trace.stack_element(1, row), + main_trace.stack_element(2, row), + main_trace.stack_element(3, row), + ]; + let merkle_path_depth = main_trace.stack_element(4, row); + let node_index = main_trace.stack_element(5, row); + let old_root = [ + main_trace.stack_element(6, row), + main_trace.stack_element(7, row), + main_trace.stack_element(8, row), + main_trace.stack_element(9, row), + ]; + let new_node_value = [ + main_trace.stack_element(10, row), + main_trace.stack_element(11, row), + main_trace.stack_element(12, row), + main_trace.stack_element(13, row), + ]; + let new_root = [ + main_trace.stack_element(0, row + 1), + main_trace.stack_element(1, row + 1), + main_trace.stack_element(2, row + 1), + main_trace.stack_element(3, row + 1), + ]; let input_old = HasherMessage { transition_label: Felt::from(MR_UPDATE_OLD_LABEL + 16), addr_next: helper_0, - node_index: s5, - hasher_state: [ZERO, ZERO, ZERO, ZERO, s3, s2, s1, s0, ZERO, ZERO, ZERO, ZERO], + node_index, + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + old_node_value[3], + old_node_value[2], + old_node_value[1], + old_node_value[0], + ZERO, + ZERO, + ZERO, + ZERO, + ], source: "mrupdate input_old", }; let output_old = HasherMessage { transition_label: Felt::from(RETURN_HASH_LABEL + 32), - addr_next: helper_0 + s4.mul_small(8) - ONE, + addr_next: helper_0 + merkle_path_depth.mul_small(8) - ONE, node_index: ZERO, - hasher_state: [ZERO, ZERO, ZERO, ZERO, s9, s8, s7, s6, ZERO, ZERO, ZERO, ZERO], + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + old_root[3], + old_root[2], + old_root[1], + old_root[0], + ZERO, + ZERO, + ZERO, + ZERO, + ], source: "mrupdate output_old", }; let input_new = HasherMessage { transition_label: Felt::from(MR_UPDATE_NEW_LABEL + 16), - addr_next: helper_0 + s4.mul_small(8), - node_index: s5, - hasher_state: [ZERO, ZERO, ZERO, ZERO, s13, s12, s11, s10, ZERO, ZERO, ZERO, ZERO], + addr_next: helper_0 + merkle_path_depth.mul_small(8), + node_index, + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + new_node_value[3], + new_node_value[2], + new_node_value[1], + new_node_value[0], + ZERO, + ZERO, + ZERO, + ZERO, + ], source: "mrupdate input_new", }; let output_new = HasherMessage { transition_label: Felt::from(RETURN_HASH_LABEL + 32), - addr_next: helper_0 + s4.mul_small(16) - ONE, + addr_next: helper_0 + merkle_path_depth.mul_small(16) - ONE, node_index: ZERO, hasher_state: [ - ZERO, ZERO, ZERO, ZERO, s3_nxt, s2_nxt, s1_nxt, s0_nxt, ZERO, ZERO, ZERO, ZERO, + ZERO, + ZERO, + ZERO, + ZERO, + new_root[3], + new_root[2], + new_root[1], + new_root[0], + ZERO, + ZERO, + ZERO, + ZERO, ], source: "mrupdate output_new", }; From 0f3e11db1a501119eeee1d6fde3c018377f3d0f1 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Thu, 13 Feb 2025 14:47:46 -0500 Subject: [PATCH 07/21] test: add failing tests with `mrupdate` and `mpverify` --- Cargo.lock | 74 +++++++++++++++++++++++++++++ processor/Cargo.toml | 1 + processor/src/trace/tests/hasher.rs | 19 +++++--- 3 files changed, 87 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aaa5b5b9f7..dd674229d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -697,6 +697,17 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.31" @@ -709,6 +720,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.31" @@ -716,10 +733,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", + "futures-macro", "futures-sink", "futures-task", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -1190,6 +1209,7 @@ dependencies = [ "miden-assembly", "miden-core", "miden-test-utils", + "rstest", "thiserror 2.0.11", "tracing", "winter-fri", @@ -1610,6 +1630,15 @@ dependencies = [ "yansi", ] +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.93" @@ -1788,6 +1817,42 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + +[[package]] +name = "rstest" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e905296805ab93e13c1ec3a03f4b6c4f35e9498a3d5fa96dc626d22c03cd89" +dependencies = [ + "futures-timer", + "futures-util", + "rstest_macros", + "rustc_version 0.4.1", +] + +[[package]] +name = "rstest_macros" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef0053bbffce09062bee4bcc499b0fbe7a57b879f1efe088d6d8d4c7adcdef9b" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version 0.4.1", + "syn", + "unicode-ident", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -1993,6 +2058,15 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.13.2" diff --git a/processor/Cargo.toml b/processor/Cargo.toml index 46c04d313b..fc227c8a06 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -33,6 +33,7 @@ thiserror = { workspace = true } [dev-dependencies] assembly = { package = "miden-assembly", path = "../assembly", version = "0.13", default-features = false } logtest = { version = "2.0", default-features = false } +rstest = "0.24.0" test-utils = { package = "miden-test-utils", path = "../test-utils" } winter-fri = { package = "winter-fri", version = "0.11" } winter-utils = { package = "winter-utils", version = "0.11" } diff --git a/processor/src/trace/tests/hasher.rs b/processor/src/trace/tests/hasher.rs index 7197c925f5..d86f847279 100644 --- a/processor/src/trace/tests/hasher.rs +++ b/processor/src/trace/tests/hasher.rs @@ -3,6 +3,7 @@ use alloc::vec::Vec; use miden_air::trace::{ chiplets::hasher::P1_COL_IDX, main_trace::MainTrace, AUX_TRACE_RAND_ELEMENTS, }; +use rstest::rstest; use vm_core::{ crypto::merkle::{MerkleStore, MerkleTree, NodeIndex}, FieldElement, @@ -17,17 +18,20 @@ use crate::StackInputs; // SIBLING TABLE TESTS // ================================================================================================ -#[test] +#[rstest] +#[case(5_u64)] +#[case(4_u64)] #[allow(clippy::needless_range_loop)] -fn hasher_p1_mp_verify() { +fn hasher_p1_mp_verify(#[case] index: u64) { let (tree, _) = build_merkle_tree(); let store = MerkleStore::from(&tree); - let node = tree.get_node(NodeIndex::new(3, 1).unwrap()).unwrap(); + let depth = 3; + let node = tree.get_node(NodeIndex::new(depth as u8, index).unwrap()).unwrap(); // build program inputs let mut init_stack = vec![]; append_word(&mut init_stack, node.into()); - init_stack.extend_from_slice(&[3, 1]); + init_stack.extend_from_slice(&[depth, index]); append_word(&mut init_stack, tree.root().into()); init_stack.reverse(); let stack_inputs = StackInputs::try_from_ints(init_stack).unwrap(); @@ -47,11 +51,12 @@ fn hasher_p1_mp_verify() { } } -#[test] +#[rstest] +#[case(5_u64)] +#[case(4_u64)] #[allow(clippy::needless_range_loop)] -fn hasher_p1_mr_update() { +fn hasher_p1_mr_update(#[case] index: u64) { let (tree, _) = build_merkle_tree(); - let index = 5_u64; let old_node = tree.get_node(NodeIndex::new(3, index).unwrap()).unwrap(); let new_node = init_leaf(11); let path = tree.get_path(NodeIndex::new(3, index).unwrap()).unwrap(); From 7e9b7cddd5859f902cfae61361a1c3ddb2b16684 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Thu, 13 Feb 2025 14:57:01 -0500 Subject: [PATCH 08/21] fix bus --- processor/src/chiplets/aux_trace/mod.rs | 61 +++++++++++++++++++------ 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index ea67269c73..a3320682c3 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -796,30 +796,61 @@ fn build_mpverify_request>( ) -> E { let helper_0 = main_trace.helper_register(0, row); - let s0 = main_trace.stack_element(0, row); - let s1 = main_trace.stack_element(1, row); - let s2 = main_trace.stack_element(2, row); - let s3 = main_trace.stack_element(3, row); - let s4 = main_trace.stack_element(4, row); - let s5 = main_trace.stack_element(5, row); - let s6 = main_trace.stack_element(6, row); - let s7 = main_trace.stack_element(7, row); - let s8 = main_trace.stack_element(8, row); - let s9 = main_trace.stack_element(9, row); + let node_value = [ + main_trace.stack_element(0, row), + main_trace.stack_element(1, row), + main_trace.stack_element(2, row), + main_trace.stack_element(3, row), + ]; + let node_depth = main_trace.stack_element(4, row); + let node_index = main_trace.stack_element(5, row); + + let merkle_tree_root = [ + main_trace.stack_element(6, row), + main_trace.stack_element(7, row), + main_trace.stack_element(8, row), + main_trace.stack_element(9, row), + ]; let input = HasherMessage { transition_label: Felt::from(MP_VERIFY_LABEL + 16), addr_next: helper_0, - node_index: s5, - hasher_state: [ZERO, ZERO, ZERO, ZERO, s3, s2, s1, s0, ZERO, ZERO, ZERO, ZERO], + node_index, + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + node_value[3], + node_value[2], + node_value[1], + node_value[0], + ZERO, + ZERO, + ZERO, + ZERO, + ], source: "mpverify input", }; let output = HasherMessage { transition_label: Felt::from(RETURN_HASH_LABEL + 32), - addr_next: helper_0 + s4.mul_small(8) - ONE, + addr_next: helper_0 + node_depth.mul_small(8) - ONE, node_index: ZERO, - hasher_state: [ZERO, ZERO, ZERO, ZERO, s9, s8, s7, s6, ZERO, ZERO, ZERO, ZERO], + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + merkle_tree_root[3], + merkle_tree_root[2], + merkle_tree_root[1], + merkle_tree_root[0], + ZERO, + ZERO, + ZERO, + ZERO, + ], source: "mpverify output", }; @@ -1023,7 +1054,7 @@ where addr_next, node_index, hasher_state: [ - state[4], state[5], state[6], state[7], ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, + ZERO, ZERO, ZERO, ZERO, state[4], state[5], state[6], state[7], ZERO, ZERO, ZERO, ZERO, ], source: "hasher", From 463dc494105a1bf0707edd46a92a3736a1fbfbe7 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Thu, 13 Feb 2025 15:11:18 -0500 Subject: [PATCH 09/21] fix clippy --- processor/src/chiplets/aux_trace/mod.rs | 1 - processor/src/trace/tests/hasher.rs | 34 ++++++++++++------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index a3320682c3..18ed36b563 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -369,7 +369,6 @@ impl> AuxColumnBuilder for BusColumnBuilder } } - // TODO(plafer): `debugger` field only in test mode /// Constructs the responses from the chiplets to the other VM-components at `row`. fn get_responses_at( &self, diff --git a/processor/src/trace/tests/hasher.rs b/processor/src/trace/tests/hasher.rs index d86f847279..f333167010 100644 --- a/processor/src/trace/tests/hasher.rs +++ b/processor/src/trace/tests/hasher.rs @@ -21,7 +21,6 @@ use crate::StackInputs; #[rstest] #[case(5_u64)] #[case(4_u64)] -#[allow(clippy::needless_range_loop)] fn hasher_p1_mp_verify(#[case] index: u64) { let (tree, _) = build_merkle_tree(); let store = MerkleStore::from(&tree); @@ -46,15 +45,14 @@ fn hasher_p1_mp_verify(#[case] index: u64) { // executing MPVERIFY does not affect the sibling table - so, all values in the column must be // ONE - for i in 0..(p1.len() - NUM_RAND_ROWS) { - assert_eq!(ONE, p1[i]); + for value in p1.iter().take(p1.len() - NUM_RAND_ROWS) { + assert_eq!(ONE, *value); } } #[rstest] #[case(5_u64)] #[case(4_u64)] -#[allow(clippy::needless_range_loop)] fn hasher_p1_mr_update(#[case] index: u64) { let (tree, _) = build_merkle_tree(); let old_node = tree.get_node(NodeIndex::new(3, index).unwrap()).unwrap(); @@ -94,8 +92,8 @@ fn hasher_p1_mr_update(#[case] index: u64) { // the running product does not change for the next 7 steps because the hasher computes the // hash of the SPAN block - for i in 1..8 { - assert_eq!(expected_value, p1[i]); + for value in p1.iter().take(8).skip(1) { + assert_eq!(expected_value, *value); } // on step 8, computations of the "old Merkle root" is started and the first sibling is added @@ -104,8 +102,8 @@ fn hasher_p1_mr_update(#[case] index: u64) { assert_eq!(expected_value, p1[9]); // and then again for the next 6 steps the value remains the same - for i in 10..16 { - assert_eq!(expected_value, p1[i]); + for value in p1.iter().take(16).skip(10) { + assert_eq!(expected_value, *value); } // on step 15, the next sibling is added to the table in the following row (step 16) @@ -113,8 +111,8 @@ fn hasher_p1_mr_update(#[case] index: u64) { assert_eq!(expected_value, p1[16]); // and then again for the next 6 steps the value remains the same - for i in 18..24 { - assert_eq!(expected_value, p1[i]); + for value in p1.iter().take(24).skip(18) { + assert_eq!(expected_value, *value); } // on step 23, the last sibling is added to the table in the following row (step 24) @@ -122,8 +120,8 @@ fn hasher_p1_mr_update(#[case] index: u64) { assert_eq!(expected_value, p1[24]); // and then again for the next 7 steps the value remains the same - for i in 25..33 { - assert_eq!(expected_value, p1[i]); + for value in p1.iter().take(33).skip(25) { + assert_eq!(expected_value, *value); } // on step 32, computations of the "new Merkle root" is started and the first sibling is @@ -132,8 +130,8 @@ fn hasher_p1_mr_update(#[case] index: u64) { assert_eq!(expected_value, p1[33]); // then, for the next 6 steps the value remains the same - for i in 33..40 { - assert_eq!(expected_value, p1[i]); + for value in p1.iter().take(40).skip(33) { + assert_eq!(expected_value, *value); } // on step 39, the next sibling is removed from the table in the following row (step 40) @@ -141,8 +139,8 @@ fn hasher_p1_mr_update(#[case] index: u64) { assert_eq!(expected_value, p1[40]); // and then again for the next 6 steps the value remains the same - for i in 41..48 { - assert_eq!(expected_value, p1[i]); + for value in p1.iter().take(48).skip(41) { + assert_eq!(expected_value, *value); } // on step 47, the last sibling is removed from the table in the following row (step 48) @@ -151,8 +149,8 @@ fn hasher_p1_mr_update(#[case] index: u64) { // at this point the table should be empty again, and it should stay empty until the end assert_eq!(expected_value, ONE); - for i in 50..(p1.len() - NUM_RAND_ROWS) { - assert_eq!(ONE, p1[i]); + for value in p1.iter().skip(50).take(p1.len() - NUM_RAND_ROWS - 50) { + assert_eq!(ONE, *value); } } From e0dd5fb0562c9029a504f01971d015be67cff701 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Thu, 13 Feb 2025 15:26:56 -0500 Subject: [PATCH 10/21] chore: put bus debugger behind new `testing-slow` feature --- processor/Cargo.toml | 2 + processor/src/chiplets/aux_trace/messages.rs | 1 - processor/src/chiplets/aux_trace/mod.rs | 154 +++++++++---------- processor/src/debug.rs | 7 +- processor/src/trace/utils.rs | 2 +- 5 files changed, 85 insertions(+), 81 deletions(-) diff --git a/processor/Cargo.toml b/processor/Cargo.toml index fc227c8a06..9da6d073ef 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -22,6 +22,8 @@ concurrent = ["std", "winter-prover/concurrent"] default = ["std"] std = ["vm-core/std", "winter-prover/std", "thiserror/std"] testing = ["miden-air/testing"] +# Like `testing`, but slows down the processor speed to make it easier to debug. +slow-testing = ["testing", "miden-air/testing"] [dependencies] miden-air = { package = "miden-air", path = "../air", version = "0.13", default-features = false } diff --git a/processor/src/chiplets/aux_trace/messages.rs b/processor/src/chiplets/aux_trace/messages.rs index 1e2c3502fb..b202fe56f2 100644 --- a/processor/src/chiplets/aux_trace/messages.rs +++ b/processor/src/chiplets/aux_trace/messages.rs @@ -127,7 +127,6 @@ impl Display for KernelRomMessage { // SPAN BLOCK MESSAGE // =============================================================================================== -// TODO(plafer): Remove this in favor of `ControlBlockRequestMessage` pub struct SpanBlockMessage { pub transition_label: Felt, pub addr_next: Felt, diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index 18ed36b563..8f15c24e19 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -404,7 +404,7 @@ fn build_control_block_request>( op_code_felt: Felt, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let message = ControlBlockRequestMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 16), @@ -415,8 +415,8 @@ fn build_control_block_request>( let value = message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_request(Box::new(message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_request(Box::new(message), alphas); value } @@ -427,7 +427,7 @@ fn build_dyn_block_request>( op_code_felt: Felt, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let control_block_req = ControlBlockRequestMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 16), @@ -450,10 +450,10 @@ fn build_dyn_block_request>( }; let combined_value = control_block_req.value(alphas) * memory_req.value(alphas); - #[cfg(any(test, feature = "testing"))] + #[cfg(any(test, feature = "slow-testing"))] { - debugger.add_request(Box::new(control_block_req), alphas); - debugger.add_request(Box::new(memory_req), alphas); + _debugger.add_request(Box::new(control_block_req), alphas); + _debugger.add_request(Box::new(memory_req), alphas); } combined_value @@ -465,7 +465,7 @@ fn build_syscall_block_request>( op_code_felt: Felt, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let control_block_req = ControlBlockRequestMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 16), @@ -480,10 +480,10 @@ fn build_syscall_block_request>( let combined_value = control_block_req.value(alphas) * kernel_rom_req.value(alphas); - #[cfg(any(test, feature = "testing"))] + #[cfg(any(test, feature = "slow-testing"))] { - debugger.add_request(Box::new(control_block_req), alphas); - debugger.add_request(Box::new(kernel_rom_req), alphas); + _debugger.add_request(Box::new(control_block_req), alphas); + _debugger.add_request(Box::new(kernel_rom_req), alphas); } combined_value @@ -494,7 +494,7 @@ fn build_span_block_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let span_block_message = SpanBlockMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 16), @@ -504,8 +504,8 @@ fn build_span_block_request>( let value = span_block_message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_request(Box::new(span_block_message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_request(Box::new(span_block_message), alphas); value } @@ -515,7 +515,7 @@ fn build_respan_block_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let respan_block_message = RespanBlockMessage { transition_label: Felt::from(LINEAR_HASH_LABEL + 32), @@ -525,8 +525,8 @@ fn build_respan_block_request>( let value = respan_block_message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_request(Box::new(respan_block_message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_request(Box::new(respan_block_message), alphas); value } @@ -536,7 +536,7 @@ fn build_end_block_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let end_block_message = EndBlockMessage { addr: main_trace.addr(row) + Felt::from(NUM_ROUNDS as u8), @@ -546,8 +546,8 @@ fn build_end_block_request>( let value = end_block_message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_request(Box::new(end_block_message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_request(Box::new(end_block_message), alphas); value } @@ -559,7 +559,7 @@ fn build_bitwise_request>( is_xor: Felt, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let bitwise_request_message = BitwiseMessage { op_label: get_op_label(ONE, ZERO, is_xor, ZERO), @@ -570,8 +570,8 @@ fn build_bitwise_request>( let value = bitwise_request_message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_request(Box::new(bitwise_request_message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_request(Box::new(bitwise_request_message), alphas); value } @@ -581,7 +581,7 @@ fn build_mstream_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let op_label = Felt::from(MEMORY_READ_WORD_LABEL); let addr = main_trace.stack_element(12, row); @@ -617,10 +617,10 @@ fn build_mstream_request>( let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); - #[cfg(any(test, feature = "testing"))] + #[cfg(any(test, feature = "slow-testing"))] { - debugger.add_request(Box::new(mem_req_1), alphas); - debugger.add_request(Box::new(mem_req_2), alphas); + _debugger.add_request(Box::new(mem_req_1), alphas); + _debugger.add_request(Box::new(mem_req_2), alphas); } combined_value @@ -631,7 +631,7 @@ fn build_pipe_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let op_label = Felt::from(MEMORY_WRITE_WORD_LABEL); let addr = main_trace.stack_element(12, row); @@ -667,10 +667,10 @@ fn build_pipe_request>( let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); - #[cfg(any(test, feature = "testing"))] + #[cfg(any(test, feature = "slow-testing"))] { - debugger.add_request(Box::new(mem_req_1), alphas); - debugger.add_request(Box::new(mem_req_2), alphas); + _debugger.add_request(Box::new(mem_req_1), alphas); + _debugger.add_request(Box::new(mem_req_2), alphas); } combined_value @@ -681,7 +681,7 @@ fn build_rcomb_base_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let tz0 = main_trace.helper_register(0, row); let tz1 = main_trace.helper_register(1, row); @@ -715,10 +715,10 @@ fn build_rcomb_base_request>( let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); - #[cfg(any(test, feature = "testing"))] + #[cfg(any(test, feature = "slow-testing"))] { - debugger.add_request(Box::new(mem_req_1), alphas); - debugger.add_request(Box::new(mem_req_2), alphas); + _debugger.add_request(Box::new(mem_req_1), alphas); + _debugger.add_request(Box::new(mem_req_2), alphas); } combined_value @@ -729,7 +729,7 @@ fn build_hperm_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let helper_0 = main_trace.helper_register(0, row); let s0 = main_trace.stack_element(0, row); @@ -777,10 +777,10 @@ fn build_hperm_request>( let combined_value = input_req.value(alphas) * output_req.value(alphas); - #[cfg(any(test, feature = "testing"))] + #[cfg(any(test, feature = "slow-testing"))] { - debugger.add_request(Box::new(input_req), alphas); - debugger.add_request(Box::new(output_req), alphas); + _debugger.add_request(Box::new(input_req), alphas); + _debugger.add_request(Box::new(output_req), alphas); } combined_value @@ -791,7 +791,7 @@ fn build_mpverify_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let helper_0 = main_trace.helper_register(0, row); @@ -855,10 +855,10 @@ fn build_mpverify_request>( let combined_value = input.value(alphas) * output.value(alphas); - #[cfg(any(test, feature = "testing"))] + #[cfg(any(test, feature = "slow-testing"))] { - debugger.add_request(Box::new(input), alphas); - debugger.add_request(Box::new(output), alphas); + _debugger.add_request(Box::new(input), alphas); + _debugger.add_request(Box::new(output), alphas); } combined_value @@ -869,7 +869,7 @@ fn build_mrupdate_request>( main_trace: &MainTrace, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let helper_0 = main_trace.helper_register(0, row); @@ -989,12 +989,12 @@ fn build_mrupdate_request>( * input_new.value(alphas) * output_new.value(alphas); - #[cfg(any(test, feature = "testing"))] + #[cfg(any(test, feature = "slow-testing"))] { - debugger.add_request(Box::new(input_old), alphas); - debugger.add_request(Box::new(output_old), alphas); - debugger.add_request(Box::new(input_new), alphas); - debugger.add_request(Box::new(output_new), alphas); + _debugger.add_request(Box::new(input_old), alphas); + _debugger.add_request(Box::new(output_old), alphas); + _debugger.add_request(Box::new(input_new), alphas); + _debugger.add_request(Box::new(output_new), alphas); } combined_value @@ -1008,7 +1008,7 @@ fn build_hasher_chiplet_responses( main_trace: &MainTrace, row: RowIndex, alphas: &[E], - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E where E: FieldElement, @@ -1039,8 +1039,8 @@ where }; multiplicand = hasher_message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_response(Box::new(hasher_message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_response(Box::new(hasher_message), alphas); } // f_mp or f_mv or f_mu == 1 @@ -1061,8 +1061,8 @@ where multiplicand = hasher_message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_response(Box::new(hasher_message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_response(Box::new(hasher_message), alphas); } else { let hasher_message = HasherMessage { transition_label, @@ -1077,8 +1077,8 @@ where multiplicand = hasher_message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_response(Box::new(hasher_message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_response(Box::new(hasher_message), alphas); } } } @@ -1104,8 +1104,8 @@ where }; multiplicand = hasher_message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_response(Box::new(hasher_message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_response(Box::new(hasher_message), alphas); } // f_sout == 1 @@ -1121,8 +1121,8 @@ where multiplicand = hasher_message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_response(Box::new(hasher_message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_response(Box::new(hasher_message), alphas); } // f_abp == 1 @@ -1155,8 +1155,8 @@ where multiplicand = hasher_message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_response(Box::new(hasher_message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_response(Box::new(hasher_message), alphas); } } multiplicand @@ -1167,7 +1167,7 @@ fn build_bitwise_chiplet_responses( main_trace: &MainTrace, row: RowIndex, alphas: &[E], - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E where E: FieldElement, @@ -1183,8 +1183,8 @@ where let value = bitwise_message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_response(Box::new(bitwise_message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_response(Box::new(bitwise_message), alphas); value } else { @@ -1197,7 +1197,7 @@ fn build_memory_chiplet_responses( main_trace: &MainTrace, row: RowIndex, alphas: &[E], - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E where E: FieldElement, @@ -1258,8 +1258,8 @@ where let value = message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_response(message, alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_response(message, alphas); value } @@ -1269,7 +1269,7 @@ fn build_kernel_chiplet_responses( main_trace: &MainTrace, row: RowIndex, alphas: &[E], - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E where E: FieldElement, @@ -1289,8 +1289,8 @@ where let value = message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_response(Box::new(message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_response(Box::new(message), alphas); value } else { @@ -1374,7 +1374,7 @@ fn compute_mem_request_element>( row: RowIndex, addr: Felt, element: Felt, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { debug_assert!(op_label == MEMORY_READ_ELEMENT_LABEL || op_label == MEMORY_WRITE_ELEMENT_LABEL); @@ -1391,8 +1391,8 @@ fn compute_mem_request_element>( let value = message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_request(Box::new(message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_request(Box::new(message), alphas); value } @@ -1405,7 +1405,7 @@ fn compute_mem_request_word>( row: RowIndex, addr: Felt, word: [Felt; 4], - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { debug_assert!(op_label == MEMORY_READ_WORD_LABEL || op_label == MEMORY_WRITE_WORD_LABEL); let ctx = main_trace.ctx(row); @@ -1426,8 +1426,8 @@ fn compute_mem_request_word>( let value = message.value(alphas); - #[cfg(any(test, feature = "testing"))] - debugger.add_request(Box::new(message), alphas); + #[cfg(any(test, feature = "slow-testing"))] + _debugger.add_request(Box::new(message), alphas); value } diff --git a/processor/src/debug.rs b/processor/src/debug.rs index e4b321a2c4..e427c0f936 100644 --- a/processor/src/debug.rs +++ b/processor/src/debug.rs @@ -319,7 +319,7 @@ impl AsRef for AsmOpInfo { // ================================================================= /// A message that can be sent on a bus. -pub trait BusMessage>: fmt::Display { +pub(crate) trait BusMessage>: fmt::Display { /// The concrete value that this message evaluates to. fn value(&self, alphas: &[E]) -> E; @@ -329,7 +329,7 @@ pub trait BusMessage>: fmt::Display { /// Note: we use `Vec` internall instead of a `BTreeMap` as a workaround for field elements not /// implementing `Ord`. Since this is only used in debug/test code, this is acceptable. -pub struct BusDebugger> { +pub(crate) struct BusDebugger> { pub bus_name: String, pub outstanding_requests: Vec<(E, Box>)>, pub outstanding_responses: Vec<(E, Box>)>, @@ -355,6 +355,7 @@ where /// Attempts to match the request with an existing response. If a match is found, the response /// is removed from the list of outstanding responses. Otherwise, the request is added to the /// list of outstanding requests. + #[allow(dead_code)] pub fn add_request(&mut self, request_msg: Box>, alphas: &[E]) { let msg_value = request_msg.value(alphas); @@ -370,6 +371,7 @@ where /// Attempts to match the response with an existing request. If a match is found, the request is /// removed from the list of outstanding requests. Otherwise, the response is added to the list /// of outstanding responses. + #[allow(dead_code)] pub fn add_response(&mut self, response_msg: Box>, alphas: &[E]) { let msg_value = response_msg.value(alphas); @@ -388,6 +390,7 @@ where /// requests or responses, it means that there is a mismatch between the requests and responses, /// and the test should fail. The `Debug` implementation for `BusDebugger` will print out the /// outstanding requests and responses. + #[allow(dead_code)] pub fn is_empty(&self) -> bool { self.outstanding_requests.is_empty() && self.outstanding_responses.is_empty() } diff --git a/processor/src/trace/utils.rs b/processor/src/trace/utils.rs index f653f3e0a0..730500c3c0 100644 --- a/processor/src/trace/utils.rs +++ b/processor/src/trace/utils.rs @@ -273,7 +273,7 @@ pub trait AuxColumnBuilder> { requests_running_divisor *= requests[i]; } - #[cfg(any(test, feature = "testing"))] + #[cfg(any(test, feature = "slow-testing"))] assert!(bus_debugger.is_empty(), "{bus_debugger}"); result_aux_column From b60b521629bd20cecbcab28e4e7cf2367092357d Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Thu, 13 Feb 2025 15:37:40 -0500 Subject: [PATCH 11/21] changelog --- CHANGELOG.md | 1 + processor/src/host/dsa.rs | 3 ++- processor/src/trace/utils.rs | 3 +-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3f48ae8f3..71c22809b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Update minimum supported Rust version to 1.84. - Change Chiplet Fields to Public (#1629). - Added to the `Assembler` the ability to vendor a compiled library. +- Introduce `BusDebugger` to facilitate debugging buses (#1664) ## 0.12.0 (2025-01-22) diff --git a/processor/src/host/dsa.rs b/processor/src/host/dsa.rs index 5c7fa1c813..681e840c8f 100644 --- a/processor/src/host/dsa.rs +++ b/processor/src/host/dsa.rs @@ -1,10 +1,11 @@ use alloc::vec::Vec; +#[cfg(feature = "std")] use vm_core::{ crypto::dsa::rpo_falcon512::{Polynomial, SecretKey}, utils::Deserializable, - Felt, Word, }; +use vm_core::{Felt, Word}; use crate::ExecutionError; diff --git a/processor/src/trace/utils.rs b/processor/src/trace/utils.rs index 730500c3c0..1647db2e3c 100644 --- a/processor/src/trace/utils.rs +++ b/processor/src/trace/utils.rs @@ -1,6 +1,5 @@ -use alloc::vec::Vec; +use alloc::{string::ToString, vec::Vec}; use core::slice; -use std::string::ToString; use miden_air::{trace::main_trace::MainTrace, RowIndex}; #[cfg(test)] From cea5b680955048a4d7f5056f75f8c2533054888d Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Tue, 18 Feb 2025 09:33:23 -0500 Subject: [PATCH 12/21] fix: typo --- processor/src/debug.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/processor/src/debug.rs b/processor/src/debug.rs index e427c0f936..bee8ea784d 100644 --- a/processor/src/debug.rs +++ b/processor/src/debug.rs @@ -327,7 +327,7 @@ pub(crate) trait BusMessage>: fmt::Display { fn source(&self) -> &str; } -/// Note: we use `Vec` internall instead of a `BTreeMap` as a workaround for field elements not +/// Note: we use `Vec` internally instead of a `BTreeMap` as a workaround for field elements not /// implementing `Ord`. Since this is only used in debug/test code, this is acceptable. pub(crate) struct BusDebugger> { pub bus_name: String, From eb9266ec7c6c9b241fff616025625729c621fdde Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Wed, 19 Feb 2025 09:20:33 -0500 Subject: [PATCH 13/21] fix bitwise message source --- processor/src/chiplets/aux_trace/messages.rs | 3 ++- processor/src/chiplets/aux_trace/mod.rs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/processor/src/chiplets/aux_trace/messages.rs b/processor/src/chiplets/aux_trace/messages.rs index b202fe56f2..9e4e7ee1da 100644 --- a/processor/src/chiplets/aux_trace/messages.rs +++ b/processor/src/chiplets/aux_trace/messages.rs @@ -239,6 +239,7 @@ pub struct BitwiseMessage { pub a: Felt, pub b: Felt, pub z: Felt, + pub source: &'static str, } impl BusMessage for BitwiseMessage @@ -250,7 +251,7 @@ where } fn source(&self) -> &str { - "bitwise" + &self.source } } diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index 8f15c24e19..fd81bb79d6 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -566,6 +566,7 @@ fn build_bitwise_request>( a: main_trace.stack_element(1, row), b: main_trace.stack_element(0, row), z: main_trace.stack_element(0, row + 1), + source: if is_xor == ONE { "u32xor" } else { "u32and" }, }; let value = bitwise_request_message.value(alphas); @@ -1179,6 +1180,7 @@ where a: main_trace.chiplet_bitwise_a(row), b: main_trace.chiplet_bitwise_b(row), z: main_trace.chiplet_bitwise_z(row), + source: "bitwise chiplet", }; let value = bitwise_message.value(alphas); From fc1470663461fea2430e1424e1561a5fc3adf7b5 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Wed, 19 Feb 2025 09:28:13 -0500 Subject: [PATCH 14/21] docs: fix `BusDebugger` docstring --- processor/src/debug.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/processor/src/debug.rs b/processor/src/debug.rs index bee8ea784d..293f3d33c0 100644 --- a/processor/src/debug.rs +++ b/processor/src/debug.rs @@ -327,8 +327,11 @@ pub(crate) trait BusMessage>: fmt::Display { fn source(&self) -> &str; } -/// Note: we use `Vec` internally instead of a `BTreeMap` as a workaround for field elements not -/// implementing `Ord`. Since this is only used in debug/test code, this is acceptable. +/// A debugger for a bus that can be used to track outstanding requests and responses. +/// +/// Note: we use `Vec` internally instead of a `BTreeMap`, since messages can have collisions (i.e. +/// 2 messages sent with the same key), which results in relatively complex insertion/deletion +/// logic. Since this is only used in debug/test code, the performance hit is acceptable. pub(crate) struct BusDebugger> { pub bus_name: String, pub outstanding_requests: Vec<(E, Box>)>, From 2273212319760f239b977cbb5ab2834ff3d9e4e0 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Wed, 19 Feb 2025 09:29:41 -0500 Subject: [PATCH 15/21] nits --- processor/Cargo.toml | 2 +- processor/src/host/dsa.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/processor/Cargo.toml b/processor/Cargo.toml index 9da6d073ef..9671d848d4 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -35,7 +35,7 @@ thiserror = { workspace = true } [dev-dependencies] assembly = { package = "miden-assembly", path = "../assembly", version = "0.13", default-features = false } logtest = { version = "2.0", default-features = false } -rstest = "0.24.0" +rstest = { version = "0.24.0" } test-utils = { package = "miden-test-utils", path = "../test-utils" } winter-fri = { package = "winter-fri", version = "0.11" } winter-utils = { package = "winter-utils", version = "0.11" } diff --git a/processor/src/host/dsa.rs b/processor/src/host/dsa.rs index 681e840c8f..73060f062c 100644 --- a/processor/src/host/dsa.rs +++ b/processor/src/host/dsa.rs @@ -1,10 +1,5 @@ use alloc::vec::Vec; -#[cfg(feature = "std")] -use vm_core::{ - crypto::dsa::rpo_falcon512::{Polynomial, SecretKey}, - utils::Deserializable, -}; use vm_core::{Felt, Word}; use crate::ExecutionError; @@ -25,6 +20,11 @@ use crate::ExecutionError; /// - The signature generation failed. #[cfg(feature = "std")] pub fn falcon_sign(sk: &[Felt], msg: Word) -> Result, ExecutionError> { + use vm_core::{ + crypto::dsa::rpo_falcon512::{Polynomial, SecretKey}, + utils::Deserializable, + }; + // Create the corresponding secret key let mut sk_bytes = Vec::with_capacity(sk.len()); for element in sk { From c14cb1f5f1f5cd05149bed684ba394c97210a942 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Wed, 19 Feb 2025 09:36:31 -0500 Subject: [PATCH 16/21] chore: rename `slow-testing` feature to `bus-debugger` --- processor/Cargo.toml | 2 +- processor/src/chiplets/aux_trace/mod.rs | 48 ++++++++++++------------- processor/src/trace/utils.rs | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/processor/Cargo.toml b/processor/Cargo.toml index 9671d848d4..8932d0d22d 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -23,7 +23,7 @@ default = ["std"] std = ["vm-core/std", "winter-prover/std", "thiserror/std"] testing = ["miden-air/testing"] # Like `testing`, but slows down the processor speed to make it easier to debug. -slow-testing = ["testing", "miden-air/testing"] +bus-debugger = ["testing", "miden-air/testing"] [dependencies] miden-air = { package = "miden-air", path = "../air", version = "0.13", default-features = false } diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index fd81bb79d6..c2e43a7466 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -415,7 +415,7 @@ fn build_control_block_request>( let value = message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_request(Box::new(message), alphas); value @@ -450,7 +450,7 @@ fn build_dyn_block_request>( }; let combined_value = control_block_req.value(alphas) * memory_req.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] { _debugger.add_request(Box::new(control_block_req), alphas); _debugger.add_request(Box::new(memory_req), alphas); @@ -480,7 +480,7 @@ fn build_syscall_block_request>( let combined_value = control_block_req.value(alphas) * kernel_rom_req.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] { _debugger.add_request(Box::new(control_block_req), alphas); _debugger.add_request(Box::new(kernel_rom_req), alphas); @@ -504,7 +504,7 @@ fn build_span_block_request>( let value = span_block_message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_request(Box::new(span_block_message), alphas); value @@ -525,7 +525,7 @@ fn build_respan_block_request>( let value = respan_block_message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_request(Box::new(respan_block_message), alphas); value @@ -546,7 +546,7 @@ fn build_end_block_request>( let value = end_block_message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_request(Box::new(end_block_message), alphas); value @@ -571,7 +571,7 @@ fn build_bitwise_request>( let value = bitwise_request_message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_request(Box::new(bitwise_request_message), alphas); value @@ -618,7 +618,7 @@ fn build_mstream_request>( let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] { _debugger.add_request(Box::new(mem_req_1), alphas); _debugger.add_request(Box::new(mem_req_2), alphas); @@ -668,7 +668,7 @@ fn build_pipe_request>( let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] { _debugger.add_request(Box::new(mem_req_1), alphas); _debugger.add_request(Box::new(mem_req_2), alphas); @@ -716,7 +716,7 @@ fn build_rcomb_base_request>( let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] { _debugger.add_request(Box::new(mem_req_1), alphas); _debugger.add_request(Box::new(mem_req_2), alphas); @@ -778,7 +778,7 @@ fn build_hperm_request>( let combined_value = input_req.value(alphas) * output_req.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] { _debugger.add_request(Box::new(input_req), alphas); _debugger.add_request(Box::new(output_req), alphas); @@ -856,7 +856,7 @@ fn build_mpverify_request>( let combined_value = input.value(alphas) * output.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] { _debugger.add_request(Box::new(input), alphas); _debugger.add_request(Box::new(output), alphas); @@ -990,7 +990,7 @@ fn build_mrupdate_request>( * input_new.value(alphas) * output_new.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] { _debugger.add_request(Box::new(input_old), alphas); _debugger.add_request(Box::new(output_old), alphas); @@ -1040,7 +1040,7 @@ where }; multiplicand = hasher_message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_response(Box::new(hasher_message), alphas); } @@ -1062,7 +1062,7 @@ where multiplicand = hasher_message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_response(Box::new(hasher_message), alphas); } else { let hasher_message = HasherMessage { @@ -1078,7 +1078,7 @@ where multiplicand = hasher_message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_response(Box::new(hasher_message), alphas); } } @@ -1105,7 +1105,7 @@ where }; multiplicand = hasher_message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_response(Box::new(hasher_message), alphas); } @@ -1122,7 +1122,7 @@ where multiplicand = hasher_message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_response(Box::new(hasher_message), alphas); } @@ -1156,7 +1156,7 @@ where multiplicand = hasher_message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_response(Box::new(hasher_message), alphas); } } @@ -1185,7 +1185,7 @@ where let value = bitwise_message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_response(Box::new(bitwise_message), alphas); value @@ -1260,7 +1260,7 @@ where let value = message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_response(message, alphas); value @@ -1291,7 +1291,7 @@ where let value = message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_response(Box::new(message), alphas); value @@ -1393,7 +1393,7 @@ fn compute_mem_request_element>( let value = message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_request(Box::new(message), alphas); value @@ -1428,7 +1428,7 @@ fn compute_mem_request_word>( let value = message.value(alphas); - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] _debugger.add_request(Box::new(message), alphas); value diff --git a/processor/src/trace/utils.rs b/processor/src/trace/utils.rs index 1647db2e3c..ac9f72f15a 100644 --- a/processor/src/trace/utils.rs +++ b/processor/src/trace/utils.rs @@ -272,7 +272,7 @@ pub trait AuxColumnBuilder> { requests_running_divisor *= requests[i]; } - #[cfg(any(test, feature = "slow-testing"))] + #[cfg(any(test, feature = "bus-debugger"))] assert!(bus_debugger.is_empty(), "{bus_debugger}"); result_aux_column From aec1be922e974fe7834d8d5ca3b38f4b7b1cbdc4 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Wed, 19 Feb 2025 13:33:55 -0500 Subject: [PATCH 17/21] nit Cargo --- processor/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/processor/Cargo.toml b/processor/Cargo.toml index 8932d0d22d..0069c7642a 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -35,7 +35,7 @@ thiserror = { workspace = true } [dev-dependencies] assembly = { package = "miden-assembly", path = "../assembly", version = "0.13", default-features = false } logtest = { version = "2.0", default-features = false } -rstest = { version = "0.24.0" } +rstest = { version = "0.24" } test-utils = { package = "miden-test-utils", path = "../test-utils" } winter-fri = { package = "winter-fri", version = "0.11" } winter-utils = { package = "winter-utils", version = "0.11" } From b71d11e548e52513b60998e4fdf1a97c723f0136 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Wed, 19 Feb 2025 14:25:17 -0500 Subject: [PATCH 18/21] rename to `Memory{Element,Word}Message` --- processor/src/chiplets/aux_trace/messages.rs | 12 +-- processor/src/chiplets/aux_trace/mod.rs | 82 +++++++------------- 2 files changed, 34 insertions(+), 60 deletions(-) diff --git a/processor/src/chiplets/aux_trace/messages.rs b/processor/src/chiplets/aux_trace/messages.rs index 9e4e7ee1da..09dd2da871 100644 --- a/processor/src/chiplets/aux_trace/messages.rs +++ b/processor/src/chiplets/aux_trace/messages.rs @@ -268,7 +268,7 @@ impl Display for BitwiseMessage { // MEMORY REQUEST WORD MESSAGE // =============================================================================================== -pub struct MemRequestWordMessage { +pub struct MemoryWordMessage { pub op_label: Felt, pub ctx: Felt, pub addr: Felt, @@ -277,7 +277,7 @@ pub struct MemRequestWordMessage { pub source: &'static str, } -impl BusMessage for MemRequestWordMessage +impl BusMessage for MemoryWordMessage where E: FieldElement, { @@ -303,7 +303,7 @@ where } } -impl Display for MemRequestWordMessage { +impl Display for MemoryWordMessage { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!( f, @@ -316,7 +316,7 @@ impl Display for MemRequestWordMessage { // MEMORY REQUEST ELEMENT MESSAGE // =============================================================================================== -pub struct MemRequestElementMessage { +pub struct MemoryElementMessage { pub op_label: Felt, pub ctx: Felt, pub addr: Felt, @@ -324,7 +324,7 @@ pub struct MemRequestElementMessage { pub element: Felt, } -impl BusMessage for MemRequestElementMessage +impl BusMessage for MemoryElementMessage where E: FieldElement, { @@ -341,7 +341,7 @@ where } } -impl Display for MemRequestElementMessage { +impl Display for MemoryElementMessage { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!( f, diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index c2e43a7466..66311e3a8d 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -2,7 +2,7 @@ use alloc::{boxed::Box, vec::Vec}; use messages::{ BitwiseMessage, ControlBlockRequestMessage, EndBlockMessage, HasherMessage, KernelRomMessage, - MemRequestElementMessage, MemRequestWordMessage, RespanBlockMessage, SpanBlockMessage, + MemoryElementMessage, MemoryWordMessage, RespanBlockMessage, SpanBlockMessage, }; use miden_air::{ trace::{ @@ -436,7 +436,7 @@ fn build_dyn_block_request>( decoder_hasher_state: [ZERO; 8], }; - let memory_req = MemRequestWordMessage { + let memory_req = MemoryWordMessage { op_label: Felt::from(MEMORY_READ_WORD_LABEL), ctx: main_trace.ctx(row), addr: main_trace.stack_element(0, row), @@ -589,7 +589,7 @@ fn build_mstream_request>( let ctx = main_trace.ctx(row); let clk = main_trace.clk(row); - let mem_req_1 = MemRequestWordMessage { + let mem_req_1 = MemoryWordMessage { op_label, ctx, addr, @@ -602,7 +602,7 @@ fn build_mstream_request>( ], source: "mstream req 1", }; - let mem_req_2 = MemRequestWordMessage { + let mem_req_2 = MemoryWordMessage { op_label, ctx, addr: addr + FOUR, @@ -639,7 +639,7 @@ fn build_pipe_request>( let ctx = main_trace.ctx(row); let clk = main_trace.clk(row); - let mem_req_1 = MemRequestWordMessage { + let mem_req_1 = MemoryWordMessage { op_label, ctx, addr, @@ -652,7 +652,7 @@ fn build_pipe_request>( ], source: "pipe req 1", }; - let mem_req_2 = MemRequestWordMessage { + let mem_req_2 = MemoryWordMessage { op_label, ctx, addr: addr + FOUR, @@ -697,7 +697,7 @@ fn build_rcomb_base_request>( let ctx = main_trace.ctx(row); let clk = main_trace.clk(row); - let mem_req_1 = MemRequestWordMessage { + let mem_req_1 = MemoryWordMessage { op_label, ctx, addr: z_ptr, @@ -705,7 +705,7 @@ fn build_rcomb_base_request>( word: [tz0, tz1, tzg0, tzg1], source: "rcombbase req 1", }; - let mem_req_2 = MemRequestWordMessage { + let mem_req_2 = MemoryWordMessage { op_label, ctx, addr: a_ptr, @@ -1235,7 +1235,7 @@ where panic!("Invalid word indices. idx0: {idx0}, idx1: {idx1}"); }; - let message = MemRequestElementMessage { op_label, ctx, addr, clk, element }; + let message = MemoryElementMessage { op_label, ctx, addr, clk, element }; Box::new(message) } else if access_type == MEMORY_ACCESS_WORD { @@ -1244,7 +1244,7 @@ where let value2 = main_trace.chiplet_memory_value_2(row); let value3 = main_trace.chiplet_memory_value_3(row); - let message = MemRequestWordMessage { + let message = MemoryWordMessage { op_label, ctx, addr, @@ -1341,7 +1341,7 @@ fn build_mem_mloadw_mstorew_request>( op_label: u8, alphas: &[E], row: RowIndex, - debugger: &mut BusDebugger, + _debugger: &mut BusDebugger, ) -> E { let word = [ main_trace.stack_element(3, row + 1), @@ -1351,44 +1351,21 @@ fn build_mem_mloadw_mstorew_request>( ]; let addr = main_trace.stack_element(0, row); - compute_mem_request_word(main_trace, op_label, alphas, row, addr, word, debugger) -} - -/// Builds `MLOAD` and `MSTORE` requests made to the memory chiplet. -fn build_mem_mload_mstore_request>( - main_trace: &MainTrace, - op_label: u8, - alphas: &[E], - row: RowIndex, - debugger: &mut BusDebugger, -) -> E { - let element = main_trace.stack_element(0, row + 1); - let addr = main_trace.stack_element(0, row); - - compute_mem_request_element(main_trace, op_label, alphas, row, addr, element, debugger) -} - -/// Computes a memory request for a read or write of a single element. -fn compute_mem_request_element>( - main_trace: &MainTrace, - op_label: u8, - alphas: &[E], - row: RowIndex, - addr: Felt, - element: Felt, - _debugger: &mut BusDebugger, -) -> E { - debug_assert!(op_label == MEMORY_READ_ELEMENT_LABEL || op_label == MEMORY_WRITE_ELEMENT_LABEL); - + debug_assert!(op_label == MEMORY_READ_WORD_LABEL || op_label == MEMORY_WRITE_WORD_LABEL); let ctx = main_trace.ctx(row); let clk = main_trace.clk(row); - let message = MemRequestElementMessage { + let message = MemoryWordMessage { op_label: Felt::from(op_label), ctx, addr, clk, - element, + word, + source: if op_label == MEMORY_READ_WORD_LABEL { + "mloadw" + } else { + "mstorew" + }, }; let value = message.value(alphas); @@ -1399,31 +1376,28 @@ fn compute_mem_request_element>( value } -/// Computes a memory request for a read or write of a word. -fn compute_mem_request_word>( +/// Builds `MLOAD` and `MSTORE` requests made to the memory chiplet. +fn build_mem_mload_mstore_request>( main_trace: &MainTrace, op_label: u8, alphas: &[E], row: RowIndex, - addr: Felt, - word: [Felt; 4], _debugger: &mut BusDebugger, ) -> E { - debug_assert!(op_label == MEMORY_READ_WORD_LABEL || op_label == MEMORY_WRITE_WORD_LABEL); + let element = main_trace.stack_element(0, row + 1); + let addr = main_trace.stack_element(0, row); + + debug_assert!(op_label == MEMORY_READ_ELEMENT_LABEL || op_label == MEMORY_WRITE_ELEMENT_LABEL); + let ctx = main_trace.ctx(row); let clk = main_trace.clk(row); - let message = MemRequestWordMessage { + let message = MemoryElementMessage { op_label: Felt::from(op_label), ctx, addr, clk, - word, - source: if op_label == MEMORY_READ_WORD_LABEL { - "mloadw" - } else { - "mstorew" - }, + element, }; let value = message.value(alphas); From 9fda21833b9eea3ab2181f3e98ebde59ba22275b Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Wed, 19 Feb 2025 15:20:13 -0500 Subject: [PATCH 19/21] clippy --- processor/src/chiplets/aux_trace/messages.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/processor/src/chiplets/aux_trace/messages.rs b/processor/src/chiplets/aux_trace/messages.rs index 09dd2da871..2c15f32727 100644 --- a/processor/src/chiplets/aux_trace/messages.rs +++ b/processor/src/chiplets/aux_trace/messages.rs @@ -251,7 +251,7 @@ where } fn source(&self) -> &str { - &self.source + self.source } } From e0f0b37d4c7b56fad6b6839d3cbca603c3960f70 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Wed, 19 Feb 2025 17:28:56 -0500 Subject: [PATCH 20/21] chore: move bus builder to different files --- .../src/chiplets/aux_trace/bus/bitwise.rs | 70 + .../src/chiplets/aux_trace/bus/hasher.rs | 548 +++++++ .../src/chiplets/aux_trace/bus/kernel.rs | 48 + .../src/chiplets/aux_trace/bus/memory.rs | 336 ++++ .../chiplets/aux_trace/{ => bus}/messages.rs | 0 processor/src/chiplets/aux_trace/bus/mod.rs | 243 +++ processor/src/chiplets/aux_trace/mod.rs | 1376 +---------------- .../src/chiplets/aux_trace/virtual_table.rs | 217 +++ 8 files changed, 1469 insertions(+), 1369 deletions(-) create mode 100644 processor/src/chiplets/aux_trace/bus/bitwise.rs create mode 100644 processor/src/chiplets/aux_trace/bus/hasher.rs create mode 100644 processor/src/chiplets/aux_trace/bus/kernel.rs create mode 100644 processor/src/chiplets/aux_trace/bus/memory.rs rename processor/src/chiplets/aux_trace/{ => bus}/messages.rs (100%) create mode 100644 processor/src/chiplets/aux_trace/bus/mod.rs create mode 100644 processor/src/chiplets/aux_trace/virtual_table.rs diff --git a/processor/src/chiplets/aux_trace/bus/bitwise.rs b/processor/src/chiplets/aux_trace/bus/bitwise.rs new file mode 100644 index 0000000000..1ff1c217b7 --- /dev/null +++ b/processor/src/chiplets/aux_trace/bus/bitwise.rs @@ -0,0 +1,70 @@ +use miden_air::{ + trace::{chiplets::bitwise::OP_CYCLE_LEN as BITWISE_OP_CYCLE_LEN, main_trace::MainTrace}, + RowIndex, +}; +use vm_core::{Felt, FieldElement, ONE, ZERO}; + +use super::{get_op_label, messages::BitwiseMessage}; +use crate::debug::{BusDebugger, BusMessage}; + +// REQUESTS +// ============================================================================================== + +/// Builds requests made to the bitwise chiplet. This can be either a request for the computation +/// of a `XOR` or an `AND` operation. +pub(super) fn build_bitwise_request>( + main_trace: &MainTrace, + is_xor: Felt, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let bitwise_request_message = BitwiseMessage { + op_label: get_op_label(ONE, ZERO, is_xor, ZERO), + a: main_trace.stack_element(1, row), + b: main_trace.stack_element(0, row), + z: main_trace.stack_element(0, row + 1), + source: if is_xor == ONE { "u32xor" } else { "u32and" }, + }; + + let value = bitwise_request_message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_request(alloc::boxed::Box::new(bitwise_request_message), alphas); + + value +} + +// RESPONSES +// ============================================================================================== + +/// Builds the response from the bitwise chiplet at `row`. +pub(super) fn build_bitwise_chiplet_responses( + main_trace: &MainTrace, + row: RowIndex, + alphas: &[E], + _debugger: &mut BusDebugger, +) -> E +where + E: FieldElement, +{ + let is_xor = main_trace.chiplet_selector_2(row); + if row.as_usize() % BITWISE_OP_CYCLE_LEN == BITWISE_OP_CYCLE_LEN - 1 { + let bitwise_message = BitwiseMessage { + op_label: get_op_label(ONE, ZERO, is_xor, ZERO), + a: main_trace.chiplet_bitwise_a(row), + b: main_trace.chiplet_bitwise_b(row), + z: main_trace.chiplet_bitwise_z(row), + source: "bitwise chiplet", + }; + + let value = bitwise_message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_response(alloc::boxed::Box::new(bitwise_message), alphas); + + value + } else { + E::ONE + } +} diff --git a/processor/src/chiplets/aux_trace/bus/hasher.rs b/processor/src/chiplets/aux_trace/bus/hasher.rs new file mode 100644 index 0000000000..106509c682 --- /dev/null +++ b/processor/src/chiplets/aux_trace/bus/hasher.rs @@ -0,0 +1,548 @@ +use miden_air::{ + trace::{ + chiplets::hasher::{ + HASH_CYCLE_LEN, LINEAR_HASH_LABEL, MP_VERIFY_LABEL, MR_UPDATE_NEW_LABEL, + MR_UPDATE_OLD_LABEL, NUM_ROUNDS, RETURN_HASH_LABEL, RETURN_STATE_LABEL, + }, + main_trace::MainTrace, + }, + RowIndex, +}; +use vm_core::{Felt, FieldElement, ONE, ZERO}; + +use super::{ + get_op_label, + messages::{ + ControlBlockRequestMessage, EndBlockMessage, HasherMessage, RespanBlockMessage, + SpanBlockMessage, + }, +}; +use crate::debug::{BusDebugger, BusMessage}; + +// REQUESTS +// ============================================================================================== + +/// Builds requests made to the hasher chiplet at the start of a control block. +pub(super) fn build_control_block_request>( + main_trace: &MainTrace, + decoder_hasher_state: [Felt; 8], + op_code_felt: Felt, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let message = ControlBlockRequestMessage { + transition_label: Felt::from(LINEAR_HASH_LABEL + 16), + addr_next: main_trace.addr(row + 1), + op_code: op_code_felt, + decoder_hasher_state, + }; + + let value = message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_request(alloc::boxed::Box::new(message), alphas); + + value +} + +/// Builds requests made to the hasher chiplet at the start of a span block. +pub(super) fn build_span_block_request>( + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let span_block_message = SpanBlockMessage { + transition_label: Felt::from(LINEAR_HASH_LABEL + 16), + addr_next: main_trace.addr(row + 1), + state: main_trace.decoder_hasher_state(row), + }; + + let value = span_block_message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_request(alloc::boxed::Box::new(span_block_message), alphas); + + value +} + +/// Builds requests made to the hasher chiplet at the start of a respan block. +pub(super) fn build_respan_block_request>( + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let respan_block_message = RespanBlockMessage { + transition_label: Felt::from(LINEAR_HASH_LABEL + 32), + addr_next: main_trace.addr(row + 1), + state: main_trace.decoder_hasher_state(row), + }; + + let value = respan_block_message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_request(alloc::boxed::Box::new(respan_block_message), alphas); + + value +} + +/// Builds requests made to the hasher chiplet at the end of a block. +pub(super) fn build_end_block_request>( + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let end_block_message = EndBlockMessage { + addr: main_trace.addr(row) + Felt::from(NUM_ROUNDS as u8), + transition_label: Felt::from(RETURN_HASH_LABEL + 32), + digest: main_trace.decoder_hasher_state(row)[..4].try_into().unwrap(), + }; + + let value = end_block_message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_request(alloc::boxed::Box::new(end_block_message), alphas); + + value +} + +/// Builds `HPERM` requests made to the hash chiplet. +pub(super) fn build_hperm_request>( + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let helper_0 = main_trace.helper_register(0, row); + let s0 = main_trace.stack_element(0, row); + let s1 = main_trace.stack_element(1, row); + let s2 = main_trace.stack_element(2, row); + let s3 = main_trace.stack_element(3, row); + let s4 = main_trace.stack_element(4, row); + let s5 = main_trace.stack_element(5, row); + let s6 = main_trace.stack_element(6, row); + let s7 = main_trace.stack_element(7, row); + let s8 = main_trace.stack_element(8, row); + let s9 = main_trace.stack_element(9, row); + let s10 = main_trace.stack_element(10, row); + let s11 = main_trace.stack_element(11, row); + let s0_nxt = main_trace.stack_element(0, row + 1); + let s1_nxt = main_trace.stack_element(1, row + 1); + let s2_nxt = main_trace.stack_element(2, row + 1); + let s3_nxt = main_trace.stack_element(3, row + 1); + let s4_nxt = main_trace.stack_element(4, row + 1); + let s5_nxt = main_trace.stack_element(5, row + 1); + let s6_nxt = main_trace.stack_element(6, row + 1); + let s7_nxt = main_trace.stack_element(7, row + 1); + let s8_nxt = main_trace.stack_element(8, row + 1); + let s9_nxt = main_trace.stack_element(9, row + 1); + let s10_nxt = main_trace.stack_element(10, row + 1); + let s11_nxt = main_trace.stack_element(11, row + 1); + + let input_req = HasherMessage { + transition_label: Felt::from(LINEAR_HASH_LABEL + 16), + addr_next: helper_0, + node_index: ZERO, + hasher_state: [s11, s10, s9, s8, s7, s6, s5, s4, s3, s2, s1, s0], + source: "hperm input", + }; + let output_req = HasherMessage { + transition_label: Felt::from(RETURN_STATE_LABEL + 32), + addr_next: helper_0 + Felt::new(7), + node_index: ZERO, + hasher_state: [ + s11_nxt, s10_nxt, s9_nxt, s8_nxt, s7_nxt, s6_nxt, s5_nxt, s4_nxt, s3_nxt, s2_nxt, + s1_nxt, s0_nxt, + ], + source: "hperm input", + }; + + let combined_value = input_req.value(alphas) * output_req.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + { + _debugger.add_request(alloc::boxed::Box::new(input_req), alphas); + _debugger.add_request(alloc::boxed::Box::new(output_req), alphas); + } + + combined_value +} + +/// Builds `MPVERIFY` requests made to the hash chiplet. +pub(super) fn build_mpverify_request>( + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let helper_0 = main_trace.helper_register(0, row); + + let node_value = [ + main_trace.stack_element(0, row), + main_trace.stack_element(1, row), + main_trace.stack_element(2, row), + main_trace.stack_element(3, row), + ]; + let node_depth = main_trace.stack_element(4, row); + let node_index = main_trace.stack_element(5, row); + + let merkle_tree_root = [ + main_trace.stack_element(6, row), + main_trace.stack_element(7, row), + main_trace.stack_element(8, row), + main_trace.stack_element(9, row), + ]; + + let input = HasherMessage { + transition_label: Felt::from(MP_VERIFY_LABEL + 16), + addr_next: helper_0, + node_index, + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + node_value[3], + node_value[2], + node_value[1], + node_value[0], + ZERO, + ZERO, + ZERO, + ZERO, + ], + source: "mpverify input", + }; + + let output = HasherMessage { + transition_label: Felt::from(RETURN_HASH_LABEL + 32), + addr_next: helper_0 + node_depth.mul_small(8) - ONE, + node_index: ZERO, + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + merkle_tree_root[3], + merkle_tree_root[2], + merkle_tree_root[1], + merkle_tree_root[0], + ZERO, + ZERO, + ZERO, + ZERO, + ], + source: "mpverify output", + }; + + let combined_value = input.value(alphas) * output.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + { + _debugger.add_request(alloc::boxed::Box::new(input), alphas); + _debugger.add_request(alloc::boxed::Box::new(output), alphas); + } + + combined_value +} + +/// Builds `MRUPDATE` requests made to the hash chiplet. +pub(super) fn build_mrupdate_request>( + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let helper_0 = main_trace.helper_register(0, row); + + let old_node_value = [ + main_trace.stack_element(0, row), + main_trace.stack_element(1, row), + main_trace.stack_element(2, row), + main_trace.stack_element(3, row), + ]; + let merkle_path_depth = main_trace.stack_element(4, row); + let node_index = main_trace.stack_element(5, row); + let old_root = [ + main_trace.stack_element(6, row), + main_trace.stack_element(7, row), + main_trace.stack_element(8, row), + main_trace.stack_element(9, row), + ]; + let new_node_value = [ + main_trace.stack_element(10, row), + main_trace.stack_element(11, row), + main_trace.stack_element(12, row), + main_trace.stack_element(13, row), + ]; + let new_root = [ + main_trace.stack_element(0, row + 1), + main_trace.stack_element(1, row + 1), + main_trace.stack_element(2, row + 1), + main_trace.stack_element(3, row + 1), + ]; + + let input_old = HasherMessage { + transition_label: Felt::from(MR_UPDATE_OLD_LABEL + 16), + addr_next: helper_0, + node_index, + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + old_node_value[3], + old_node_value[2], + old_node_value[1], + old_node_value[0], + ZERO, + ZERO, + ZERO, + ZERO, + ], + source: "mrupdate input_old", + }; + + let output_old = HasherMessage { + transition_label: Felt::from(RETURN_HASH_LABEL + 32), + addr_next: helper_0 + merkle_path_depth.mul_small(8) - ONE, + node_index: ZERO, + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + old_root[3], + old_root[2], + old_root[1], + old_root[0], + ZERO, + ZERO, + ZERO, + ZERO, + ], + source: "mrupdate output_old", + }; + + let input_new = HasherMessage { + transition_label: Felt::from(MR_UPDATE_NEW_LABEL + 16), + addr_next: helper_0 + merkle_path_depth.mul_small(8), + node_index, + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + new_node_value[3], + new_node_value[2], + new_node_value[1], + new_node_value[0], + ZERO, + ZERO, + ZERO, + ZERO, + ], + source: "mrupdate input_new", + }; + + let output_new = HasherMessage { + transition_label: Felt::from(RETURN_HASH_LABEL + 32), + addr_next: helper_0 + merkle_path_depth.mul_small(16) - ONE, + node_index: ZERO, + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + new_root[3], + new_root[2], + new_root[1], + new_root[0], + ZERO, + ZERO, + ZERO, + ZERO, + ], + source: "mrupdate output_new", + }; + + let combined_value = input_old.value(alphas) + * output_old.value(alphas) + * input_new.value(alphas) + * output_new.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + { + _debugger.add_request(alloc::boxed::Box::new(input_old), alphas); + _debugger.add_request(alloc::boxed::Box::new(output_old), alphas); + _debugger.add_request(alloc::boxed::Box::new(input_new), alphas); + _debugger.add_request(alloc::boxed::Box::new(output_new), alphas); + } + + combined_value +} + +// RESPONSES +// ============================================================================================== + +/// Builds the response from the hasher chiplet at `row`. +pub(super) fn build_hasher_chiplet_responses( + main_trace: &MainTrace, + row: RowIndex, + alphas: &[E], + _debugger: &mut BusDebugger, +) -> E +where + E: FieldElement, +{ + let mut multiplicand = E::ONE; + let selector0 = main_trace.chiplet_selector_0(row); + let selector1 = main_trace.chiplet_selector_1(row); + let selector2 = main_trace.chiplet_selector_2(row); + let selector3 = main_trace.chiplet_selector_3(row); + let op_label = get_op_label(selector0, selector1, selector2, selector3); + let addr_next = Felt::from(row + 1); + + // f_bp, f_mp, f_mv or f_mu == 1 + if row.as_usize() % HASH_CYCLE_LEN == 0 { + let state = main_trace.chiplet_hasher_state(row); + let node_index = main_trace.chiplet_node_index(row); + let transition_label = op_label + Felt::from(16_u8); + + // f_bp == 1 + // v_all = v_h + v_a + v_b + v_c + if selector1 == ONE && selector2 == ZERO && selector3 == ZERO { + let hasher_message = HasherMessage { + transition_label, + addr_next, + node_index, + hasher_state: state, + source: "hasher", + }; + multiplicand = hasher_message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_response(alloc::boxed::Box::new(hasher_message), alphas); + } + + // f_mp or f_mv or f_mu == 1 + // v_leaf = v_h + (1 - b) * v_b + b * v_d + if selector1 == ONE && !(selector2 == ZERO && selector3 == ZERO) { + let bit = (node_index.as_int() & 1) as u8; + if bit == 0 { + let hasher_message = HasherMessage { + transition_label, + addr_next, + node_index, + hasher_state: [ + ZERO, ZERO, ZERO, ZERO, state[4], state[5], state[6], state[7], ZERO, ZERO, + ZERO, ZERO, + ], + source: "hasher", + }; + + multiplicand = hasher_message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_response(alloc::boxed::Box::new(hasher_message), alphas); + } else { + let hasher_message = HasherMessage { + transition_label, + addr_next, + node_index, + hasher_state: [ + ZERO, ZERO, ZERO, ZERO, state[8], state[9], state[10], state[11], ZERO, + ZERO, ZERO, ZERO, + ], + source: "hasher", + }; + + multiplicand = hasher_message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_response(alloc::boxed::Box::new(hasher_message), alphas); + } + } + } + + // f_hout, f_sout, f_abp == 1 + if row.as_usize() % HASH_CYCLE_LEN == HASH_CYCLE_LEN - 1 { + let state = main_trace.chiplet_hasher_state(row); + let node_index = main_trace.chiplet_node_index(row); + let transition_label = op_label + Felt::from(32_u8); + + // f_hout == 1 + // v_res = v_h + v_b; + if selector1 == ZERO && selector2 == ZERO && selector3 == ZERO { + let hasher_message = HasherMessage { + transition_label, + addr_next, + node_index, + hasher_state: [ + ZERO, ZERO, ZERO, ZERO, state[4], state[5], state[6], state[7], ZERO, ZERO, + ZERO, ZERO, + ], + source: "hasher", + }; + multiplicand = hasher_message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_response(alloc::boxed::Box::new(hasher_message), alphas); + } + + // f_sout == 1 + // v_all = v_h + v_a + v_b + v_c + if selector1 == ZERO && selector2 == ZERO && selector3 == ONE { + let hasher_message = HasherMessage { + transition_label, + addr_next, + node_index, + hasher_state: state, + source: "hasher", + }; + + multiplicand = hasher_message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_response(alloc::boxed::Box::new(hasher_message), alphas); + } + + // f_abp == 1 + // v_abp = v_h + v_b' + v_c' - v_b - v_c + if selector1 == ONE && selector2 == ZERO && selector3 == ZERO { + // build the value from the hasher state's just right after the absorption of new + // elements. + let state_nxt = main_trace.chiplet_hasher_state(row + 1); + + let hasher_message = HasherMessage { + transition_label, + addr_next, + node_index, + hasher_state: [ + ZERO, + ZERO, + ZERO, + ZERO, + state_nxt[4], + state_nxt[5], + state_nxt[6], + state_nxt[7], + state_nxt[8], + state_nxt[9], + state_nxt[10], + state_nxt[11], + ], + source: "hasher", + }; + + multiplicand = hasher_message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_response(alloc::boxed::Box::new(hasher_message), alphas); + } + } + multiplicand +} diff --git a/processor/src/chiplets/aux_trace/bus/kernel.rs b/processor/src/chiplets/aux_trace/bus/kernel.rs new file mode 100644 index 0000000000..3554328645 --- /dev/null +++ b/processor/src/chiplets/aux_trace/bus/kernel.rs @@ -0,0 +1,48 @@ +use miden_air::{trace::main_trace::MainTrace, RowIndex}; +use vm_core::{Felt, FieldElement, ONE}; + +use super::messages::KernelRomMessage; +use crate::debug::{BusDebugger, BusMessage}; + +// REQUESTS +// ================================================================================================ + +// Note: all requests are handled in the `super` module, since they involve messages to multiple +// chiplets. + +// RESPONSES +// ================================================================================================ + +/// Builds the response from the kernel chiplet at `row`. +pub(super) fn build_kernel_chiplet_responses( + main_trace: &MainTrace, + row: RowIndex, + alphas: &[E], + _debugger: &mut BusDebugger, +) -> E +where + E: FieldElement, +{ + let kernel_chiplet_selector = main_trace.chiplet_selector_4(row); + if kernel_chiplet_selector == ONE { + let message = { + let root0 = main_trace.chiplet_kernel_root_0(row); + let root1 = main_trace.chiplet_kernel_root_1(row); + let root2 = main_trace.chiplet_kernel_root_2(row); + let root3 = main_trace.chiplet_kernel_root_3(row); + + KernelRomMessage { + kernel_proc_digest: [root0, root1, root2, root3], + } + }; + + let value = message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_response(alloc::boxed::Box::new(message), alphas); + + value + } else { + E::ONE + } +} diff --git a/processor/src/chiplets/aux_trace/bus/memory.rs b/processor/src/chiplets/aux_trace/bus/memory.rs new file mode 100644 index 0000000000..f0cf74e136 --- /dev/null +++ b/processor/src/chiplets/aux_trace/bus/memory.rs @@ -0,0 +1,336 @@ +use alloc::boxed::Box; + +use miden_air::{ + trace::{ + chiplets::memory::{ + MEMORY_ACCESS_ELEMENT, MEMORY_ACCESS_WORD, MEMORY_READ_ELEMENT_LABEL, + MEMORY_READ_WORD_LABEL, MEMORY_WRITE_ELEMENT_LABEL, MEMORY_WRITE_WORD_LABEL, + }, + main_trace::MainTrace, + }, + RowIndex, +}; +use vm_core::{Felt, FieldElement, ONE, ZERO}; + +use super::messages::{MemoryElementMessage, MemoryWordMessage}; +use crate::debug::{BusDebugger, BusMessage}; + +// CONSTANTS +// ================================================================================================ + +const FOUR: Felt = Felt::new(4); + +// REQUESTS +// ================================================================================================ + +/// Builds `MLOADW` and `MSTOREW` requests made to the memory chiplet. +pub(super) fn build_mem_mloadw_mstorew_request>( + main_trace: &MainTrace, + op_label: u8, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let word = [ + main_trace.stack_element(3, row + 1), + main_trace.stack_element(2, row + 1), + main_trace.stack_element(1, row + 1), + main_trace.stack_element(0, row + 1), + ]; + let addr = main_trace.stack_element(0, row); + + debug_assert!(op_label == MEMORY_READ_WORD_LABEL || op_label == MEMORY_WRITE_WORD_LABEL); + let ctx = main_trace.ctx(row); + let clk = main_trace.clk(row); + + let message = MemoryWordMessage { + op_label: Felt::from(op_label), + ctx, + addr, + clk, + word, + source: if op_label == MEMORY_READ_WORD_LABEL { + "mloadw" + } else { + "mstorew" + }, + }; + + let value = message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_request(Box::new(message), alphas); + + value +} + +/// Builds `MLOAD` and `MSTORE` requests made to the memory chiplet. +pub(super) fn build_mem_mload_mstore_request>( + main_trace: &MainTrace, + op_label: u8, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let element = main_trace.stack_element(0, row + 1); + let addr = main_trace.stack_element(0, row); + + debug_assert!(op_label == MEMORY_READ_ELEMENT_LABEL || op_label == MEMORY_WRITE_ELEMENT_LABEL); + + let ctx = main_trace.ctx(row); + let clk = main_trace.clk(row); + + let message = MemoryElementMessage { + op_label: Felt::from(op_label), + ctx, + addr, + clk, + element, + }; + + let value = message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_request(Box::new(message), alphas); + + value +} + +/// Builds `MSTREAM` requests made to the memory chiplet. +pub(super) fn build_mstream_request>( + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let op_label = Felt::from(MEMORY_READ_WORD_LABEL); + let addr = main_trace.stack_element(12, row); + let ctx = main_trace.ctx(row); + let clk = main_trace.clk(row); + + let mem_req_1 = MemoryWordMessage { + op_label, + ctx, + addr, + clk, + word: [ + main_trace.stack_element(7, row + 1), + main_trace.stack_element(6, row + 1), + main_trace.stack_element(5, row + 1), + main_trace.stack_element(4, row + 1), + ], + source: "mstream req 1", + }; + let mem_req_2 = MemoryWordMessage { + op_label, + ctx, + addr: addr + FOUR, + clk, + word: [ + main_trace.stack_element(3, row + 1), + main_trace.stack_element(2, row + 1), + main_trace.stack_element(1, row + 1), + main_trace.stack_element(0, row + 1), + ], + source: "mstream req 2", + }; + + let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + { + _debugger.add_request(Box::new(mem_req_1), alphas); + _debugger.add_request(Box::new(mem_req_2), alphas); + } + + combined_value +} + +/// Builds `PIPE` requests made to the memory chiplet. +pub(super) fn build_pipe_request>( + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let op_label = Felt::from(MEMORY_WRITE_WORD_LABEL); + let addr = main_trace.stack_element(12, row); + let ctx = main_trace.ctx(row); + let clk = main_trace.clk(row); + + let mem_req_1 = MemoryWordMessage { + op_label, + ctx, + addr, + clk, + word: [ + main_trace.stack_element(7, row + 1), + main_trace.stack_element(6, row + 1), + main_trace.stack_element(5, row + 1), + main_trace.stack_element(4, row + 1), + ], + source: "pipe req 1", + }; + let mem_req_2 = MemoryWordMessage { + op_label, + ctx, + addr: addr + FOUR, + clk, + word: [ + main_trace.stack_element(3, row + 1), + main_trace.stack_element(2, row + 1), + main_trace.stack_element(1, row + 1), + main_trace.stack_element(0, row + 1), + ], + source: "pipe req 2", + }; + + let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + { + _debugger.add_request(Box::new(mem_req_1), alphas); + _debugger.add_request(Box::new(mem_req_2), alphas); + } + + combined_value +} + +/// Builds `RCOMBBASE` requests made to the memory chiplet. +pub(super) fn build_rcomb_base_request>( + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let tz0 = main_trace.helper_register(0, row); + let tz1 = main_trace.helper_register(1, row); + let tzg0 = main_trace.helper_register(2, row); + let tzg1 = main_trace.helper_register(3, row); + let a0 = main_trace.helper_register(4, row); + let a1 = main_trace.helper_register(5, row); + let z_ptr = main_trace.stack_element(13, row); + let a_ptr = main_trace.stack_element(14, row); + let op_label = Felt::from(MEMORY_READ_WORD_LABEL); + + let ctx = main_trace.ctx(row); + let clk = main_trace.clk(row); + + let mem_req_1 = MemoryWordMessage { + op_label, + ctx, + addr: z_ptr, + clk, + word: [tz0, tz1, tzg0, tzg1], + source: "rcombbase req 1", + }; + let mem_req_2 = MemoryWordMessage { + op_label, + ctx, + addr: a_ptr, + clk, + word: [a0, a1, ZERO, ZERO], + source: "rcombbase req 2", + }; + + let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + { + _debugger.add_request(Box::new(mem_req_1), alphas); + _debugger.add_request(Box::new(mem_req_2), alphas); + } + + combined_value +} + +// RESPONSES +// ================================================================================================ + +/// Builds the response from the memory chiplet at `row`. +pub(super) fn build_memory_chiplet_responses( + main_trace: &MainTrace, + row: RowIndex, + alphas: &[E], + _debugger: &mut BusDebugger, +) -> E +where + E: FieldElement, +{ + let access_type = main_trace.chiplet_selector_4(row); + let op_label = { + let is_read = main_trace.chiplet_selector_3(row); + get_memory_op_label(is_read, access_type) + }; + let ctx = main_trace.chiplet_memory_ctx(row); + let clk = main_trace.chiplet_memory_clk(row); + let addr = { + let word = main_trace.chiplet_memory_word(row); + let idx0 = main_trace.chiplet_memory_idx0(row); + let idx1 = main_trace.chiplet_memory_idx1(row); + + word + idx1.mul_small(2) + idx0 + }; + + let message: Box> = if access_type == MEMORY_ACCESS_ELEMENT { + let idx0 = main_trace.chiplet_memory_idx0(row); + let idx1 = main_trace.chiplet_memory_idx1(row); + + let element = if idx1 == ZERO && idx0 == ZERO { + main_trace.chiplet_memory_value_0(row) + } else if idx1 == ZERO && idx0 == ONE { + main_trace.chiplet_memory_value_1(row) + } else if idx1 == ONE && idx0 == ZERO { + main_trace.chiplet_memory_value_2(row) + } else if idx1 == ONE && idx0 == ONE { + main_trace.chiplet_memory_value_3(row) + } else { + panic!("Invalid word indices. idx0: {idx0}, idx1: {idx1}"); + }; + + let message = MemoryElementMessage { op_label, ctx, addr, clk, element }; + + Box::new(message) + } else if access_type == MEMORY_ACCESS_WORD { + let value0 = main_trace.chiplet_memory_value_0(row); + let value1 = main_trace.chiplet_memory_value_1(row); + let value2 = main_trace.chiplet_memory_value_2(row); + let value3 = main_trace.chiplet_memory_value_3(row); + + let message = MemoryWordMessage { + op_label, + ctx, + addr, + clk, + word: [value0, value1, value2, value3], + source: "memory chiplet", + }; + + Box::new(message) + } else { + panic!("Invalid memory element/word column value: {access_type}"); + }; + + let value = message.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + _debugger.add_response(message, alphas); + + value +} + +// HELPER FUNCTIONS +// ================================================================================================ + +/// Returns the operation unique label for memory operations. +/// +/// The memory operation label is currently the only label that is built differently (or *simpler*) +/// from the other chiplets. We should refactor the other chiplets to use a similar (simpler) +/// approach. +fn get_memory_op_label(is_read: Felt, is_word_access: Felt) -> Felt { + const MEMORY_SELECTOR: u8 = 0b110; + // Equivalent to `is_read << 1` + let is_read_left_shift_1 = is_read + is_read; + + Felt::from(MEMORY_SELECTOR << 2) + is_read_left_shift_1 + is_word_access +} diff --git a/processor/src/chiplets/aux_trace/messages.rs b/processor/src/chiplets/aux_trace/bus/messages.rs similarity index 100% rename from processor/src/chiplets/aux_trace/messages.rs rename to processor/src/chiplets/aux_trace/bus/messages.rs diff --git a/processor/src/chiplets/aux_trace/bus/mod.rs b/processor/src/chiplets/aux_trace/bus/mod.rs new file mode 100644 index 0000000000..79ee25bfc8 --- /dev/null +++ b/processor/src/chiplets/aux_trace/bus/mod.rs @@ -0,0 +1,243 @@ +use bitwise::{build_bitwise_chiplet_responses, build_bitwise_request}; +use hasher::{ + build_control_block_request, build_end_block_request, build_hasher_chiplet_responses, + build_hperm_request, build_mpverify_request, build_mrupdate_request, + build_respan_block_request, build_span_block_request, +}; +use kernel::build_kernel_chiplet_responses; +use memory::{ + build_mem_mload_mstore_request, build_mem_mloadw_mstorew_request, + build_memory_chiplet_responses, build_mstream_request, build_pipe_request, + build_rcomb_base_request, +}; +use messages::{ControlBlockRequestMessage, KernelRomMessage, MemoryWordMessage}; +use miden_air::{ + trace::{ + chiplets::{ + hasher::LINEAR_HASH_LABEL, + memory::{ + MEMORY_READ_ELEMENT_LABEL, MEMORY_READ_WORD_LABEL, MEMORY_WRITE_ELEMENT_LABEL, + MEMORY_WRITE_WORD_LABEL, + }, + }, + main_trace::MainTrace, + }, + RowIndex, +}; +use vm_core::{ + ONE, OPCODE_CALL, OPCODE_DYN, OPCODE_DYNCALL, OPCODE_END, OPCODE_HPERM, OPCODE_JOIN, + OPCODE_LOOP, OPCODE_MLOAD, OPCODE_MLOADW, OPCODE_MPVERIFY, OPCODE_MRUPDATE, OPCODE_MSTORE, + OPCODE_MSTOREW, OPCODE_MSTREAM, OPCODE_PIPE, OPCODE_RCOMBBASE, OPCODE_RESPAN, OPCODE_SPAN, + OPCODE_SPLIT, OPCODE_SYSCALL, OPCODE_U32AND, OPCODE_U32XOR, ZERO, +}; + +use super::{Felt, FieldElement}; +use crate::{ + debug::{BusDebugger, BusMessage}, + trace::AuxColumnBuilder, +}; + +mod bitwise; +mod hasher; +mod kernel; +mod memory; +mod messages; + +// BUS COLUMN BUILDER +// ================================================================================================ + +/// Describes how to construct the execution trace of the chiplets bus auxiliary trace column. +#[derive(Default)] +pub struct BusColumnBuilder {} + +impl> AuxColumnBuilder for BusColumnBuilder { + /// Constructs the requests made by the VM-components to the chiplets at `row`. + fn get_requests_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + debugger: &mut BusDebugger, + ) -> E + where + E: FieldElement, + { + let op_code_felt = main_trace.get_op_code(row); + let op_code = op_code_felt.as_int() as u8; + + match op_code { + OPCODE_JOIN | OPCODE_SPLIT | OPCODE_LOOP | OPCODE_CALL => build_control_block_request( + main_trace, + main_trace.decoder_hasher_state(row), + op_code_felt, + alphas, + row, + debugger, + ), + OPCODE_DYN | OPCODE_DYNCALL => { + build_dyn_block_request(main_trace, op_code_felt, alphas, row, debugger) + }, + OPCODE_SYSCALL => { + build_syscall_block_request(main_trace, op_code_felt, alphas, row, debugger) + }, + OPCODE_SPAN => build_span_block_request(main_trace, alphas, row, debugger), + OPCODE_RESPAN => build_respan_block_request(main_trace, alphas, row, debugger), + OPCODE_END => build_end_block_request(main_trace, alphas, row, debugger), + OPCODE_U32AND => build_bitwise_request(main_trace, ZERO, alphas, row, debugger), + OPCODE_U32XOR => build_bitwise_request(main_trace, ONE, alphas, row, debugger), + OPCODE_MLOADW => build_mem_mloadw_mstorew_request( + main_trace, + MEMORY_READ_WORD_LABEL, + alphas, + row, + debugger, + ), + OPCODE_MSTOREW => build_mem_mloadw_mstorew_request( + main_trace, + MEMORY_WRITE_WORD_LABEL, + alphas, + row, + debugger, + ), + OPCODE_MLOAD => build_mem_mload_mstore_request( + main_trace, + MEMORY_READ_ELEMENT_LABEL, + alphas, + row, + debugger, + ), + OPCODE_MSTORE => build_mem_mload_mstore_request( + main_trace, + MEMORY_WRITE_ELEMENT_LABEL, + alphas, + row, + debugger, + ), + OPCODE_MSTREAM => build_mstream_request(main_trace, alphas, row, debugger), + OPCODE_RCOMBBASE => build_rcomb_base_request(main_trace, alphas, row, debugger), + OPCODE_HPERM => build_hperm_request(main_trace, alphas, row, debugger), + OPCODE_MPVERIFY => build_mpverify_request(main_trace, alphas, row, debugger), + OPCODE_MRUPDATE => build_mrupdate_request(main_trace, alphas, row, debugger), + OPCODE_PIPE => build_pipe_request(main_trace, alphas, row, debugger), + _ => E::ONE, + } + } + + /// Constructs the responses from the chiplets to the other VM-components at `row`. + fn get_responses_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + debugger: &mut BusDebugger, + ) -> E + where + E: FieldElement, + { + if main_trace.is_hash_row(row) { + build_hasher_chiplet_responses(main_trace, row, alphas, debugger) + } else if main_trace.is_bitwise_row(row) { + build_bitwise_chiplet_responses(main_trace, row, alphas, debugger) + } else if main_trace.is_memory_row(row) { + build_memory_chiplet_responses(main_trace, row, alphas, debugger) + } else if main_trace.is_kernel_row(row) { + build_kernel_chiplet_responses(main_trace, row, alphas, debugger) + } else { + E::ONE + } + } +} + +// CHIPLETS REQUESTS TO MORE THAN ONE CHIPLET +// ================================================================================================ + +/// Builds requests made on a `DYN` or `DYNCALL` operation. +fn build_dyn_block_request>( + main_trace: &MainTrace, + op_code_felt: Felt, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let control_block_req = ControlBlockRequestMessage { + transition_label: Felt::from(LINEAR_HASH_LABEL + 16), + addr_next: main_trace.addr(row + 1), + op_code: op_code_felt, + decoder_hasher_state: [ZERO; 8], + }; + + let memory_req = MemoryWordMessage { + op_label: Felt::from(MEMORY_READ_WORD_LABEL), + ctx: main_trace.ctx(row), + addr: main_trace.stack_element(0, row), + clk: main_trace.clk(row), + word: main_trace.decoder_hasher_state_first_half(row), + source: if op_code_felt == OPCODE_DYNCALL.into() { + "dyncall" + } else { + "dyn" + }, + }; + + let combined_value = control_block_req.value(alphas) * memory_req.value(alphas); + #[cfg(any(test, feature = "bus-debugger"))] + { + use alloc::boxed::Box; + _debugger.add_request(Box::new(control_block_req), alphas); + _debugger.add_request(Box::new(memory_req), alphas); + } + + combined_value +} + +/// Builds requests made to kernel ROM chiplet when initializing a syscall block. +fn build_syscall_block_request>( + main_trace: &MainTrace, + op_code_felt: Felt, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, +) -> E { + let control_block_req = ControlBlockRequestMessage { + transition_label: Felt::from(LINEAR_HASH_LABEL + 16), + addr_next: main_trace.addr(row + 1), + op_code: op_code_felt, + decoder_hasher_state: main_trace.decoder_hasher_state(row), + }; + + let kernel_rom_req = KernelRomMessage { + kernel_proc_digest: main_trace.decoder_hasher_state(row)[0..4].try_into().unwrap(), + }; + + let combined_value = control_block_req.value(alphas) * kernel_rom_req.value(alphas); + + #[cfg(any(test, feature = "bus-debugger"))] + { + _debugger.add_request(alloc::boxed::Box::new(control_block_req), alphas); + _debugger.add_request(alloc::boxed::Box::new(kernel_rom_req), alphas); + } + + combined_value +} + +// HELPER FUNCTIONS +// ================================================================================================ + +/// Runs an inner product between the alphas and the elements. +#[inline(always)] +fn build_value, const N: usize>( + alphas: &[E], + elements: [Felt; N], +) -> E { + debug_assert_eq!(alphas.len(), elements.len()); + let mut value = E::ZERO; + for i in 0..N { + value += alphas[i].mul_base(elements[i]); + } + value +} + +/// Returns the operation unique label. +fn get_op_label(s0: Felt, s1: Felt, s2: Felt, s3: Felt) -> Felt { + s3.mul_small(1 << 3) + s2.mul_small(1 << 2) + s1.mul_small(2) + s0 + ONE +} diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index 66311e3a8d..9a6b9511e2 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -1,46 +1,15 @@ -use alloc::{boxed::Box, vec::Vec}; +use alloc::vec::Vec; -use messages::{ - BitwiseMessage, ControlBlockRequestMessage, EndBlockMessage, HasherMessage, KernelRomMessage, - MemoryElementMessage, MemoryWordMessage, RespanBlockMessage, SpanBlockMessage, -}; -use miden_air::{ - trace::{ - chiplets::{ - bitwise::OP_CYCLE_LEN as BITWISE_OP_CYCLE_LEN, - hasher::{ - DIGEST_RANGE, HASH_CYCLE_LEN, LINEAR_HASH_LABEL, MP_VERIFY_LABEL, - MR_UPDATE_NEW_LABEL, MR_UPDATE_OLD_LABEL, NUM_ROUNDS, RETURN_HASH_LABEL, - RETURN_STATE_LABEL, - }, - memory::{ - MEMORY_ACCESS_ELEMENT, MEMORY_ACCESS_WORD, MEMORY_READ_ELEMENT_LABEL, - MEMORY_READ_WORD_LABEL, MEMORY_WRITE_ELEMENT_LABEL, MEMORY_WRITE_WORD_LABEL, - }, - }, - main_trace::MainTrace, - }, - RowIndex, -}; -use vm_core::{ - Kernel, ONE, OPCODE_CALL, OPCODE_DYN, OPCODE_DYNCALL, OPCODE_END, OPCODE_HPERM, OPCODE_JOIN, - OPCODE_LOOP, OPCODE_MLOAD, OPCODE_MLOADW, OPCODE_MPVERIFY, OPCODE_MRUPDATE, OPCODE_MSTORE, - OPCODE_MSTOREW, OPCODE_MSTREAM, OPCODE_PIPE, OPCODE_RCOMBBASE, OPCODE_RESPAN, OPCODE_SPAN, - OPCODE_SPLIT, OPCODE_SYSCALL, OPCODE_U32AND, OPCODE_U32XOR, ZERO, -}; +use miden_air::trace::main_trace::MainTrace; +use vm_core::Kernel; use super::{super::trace::AuxColumnBuilder, Felt, FieldElement}; -use crate::debug::{BusDebugger, BusMessage}; -mod messages; +mod bus; +pub use bus::BusColumnBuilder; -// CONSTANTS -// ================================================================================================ - -const FOUR: Felt = Felt::new(4); - -// CHIPLETS AUXILIARY TRACE BUILDER -// ================================================================================================ +mod virtual_table; +pub use virtual_table::ChipletsVTableColBuilder; /// Constructs the execution trace for chiplets-related auxiliary columns (used in multiset checks). pub struct AuxTraceBuilder { @@ -76,1334 +45,3 @@ impl AuxTraceBuilder { vec![t_chip, b_chip] } } - -// VIRTUAL TABLE COLUMN BUILDER -// ================================================================================================ - -/// Describes how to construct the execution trace of the chiplets virtual table auxiliary trace -/// column. -pub struct ChipletsVTableColBuilder { - kernel: Kernel, -} - -impl ChipletsVTableColBuilder { - fn new(kernel: Kernel) -> Self { - Self { kernel } - } -} - -impl> AuxColumnBuilder for ChipletsVTableColBuilder { - fn init_requests( - &self, - _main_trace: &MainTrace, - alphas: &[E], - _debugger: &mut BusDebugger, - ) -> E { - let mut requests = E::ONE; - for (idx, proc_hash) in self.kernel.proc_hashes().iter().enumerate() { - requests *= alphas[0] - + alphas[1].mul_base((idx as u32).into()) - + alphas[2].mul_base(proc_hash[0]) - + alphas[3].mul_base(proc_hash[1]) - + alphas[4].mul_base(proc_hash[2]) - + alphas[5].mul_base(proc_hash[3]); - } - requests - } - - fn get_requests_at( - &self, - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, - ) -> E { - chiplets_vtable_remove_sibling(main_trace, alphas, row) - } - - fn get_responses_at( - &self, - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, - ) -> E { - chiplets_vtable_add_sibling(main_trace, alphas, row) - * build_kernel_procedure_table_inclusions(main_trace, alphas, row) - } -} - -// VIRTUAL TABLE REQUESTS -// ================================================================================================ - -/// Constructs the removals from the table when the hasher absorbs a new sibling node while -/// computing the new Merkle root. -fn chiplets_vtable_remove_sibling(main_trace: &MainTrace, alphas: &[E], row: RowIndex) -> E -where - E: FieldElement, -{ - let f_mu: bool = main_trace.f_mu(row); - let f_mua: bool = main_trace.f_mua(row); - - if f_mu { - let index = main_trace.chiplet_node_index(row); - let lsb = index.as_int() & 1; - if lsb == 0 { - let sibling = &main_trace.chiplet_hasher_state(row)[DIGEST_RANGE.end..]; - alphas[0] - + alphas[3].mul_base(index) - + alphas[12].mul_base(sibling[0]) - + alphas[13].mul_base(sibling[1]) - + alphas[14].mul_base(sibling[2]) - + alphas[15].mul_base(sibling[3]) - } else { - let sibling = &main_trace.chiplet_hasher_state(row)[DIGEST_RANGE]; - alphas[0] - + alphas[3].mul_base(index) - + alphas[8].mul_base(sibling[0]) - + alphas[9].mul_base(sibling[1]) - + alphas[10].mul_base(sibling[2]) - + alphas[11].mul_base(sibling[3]) - } - } else if f_mua { - let index = main_trace.chiplet_node_index(row); - let lsb = index.as_int() & 1; - if lsb == 0 { - let sibling = &main_trace.chiplet_hasher_state(row + 1)[DIGEST_RANGE.end..]; - alphas[0] - + alphas[3].mul_base(index) - + alphas[12].mul_base(sibling[0]) - + alphas[13].mul_base(sibling[1]) - + alphas[14].mul_base(sibling[2]) - + alphas[15].mul_base(sibling[3]) - } else { - let sibling = &main_trace.chiplet_hasher_state(row + 1)[DIGEST_RANGE]; - alphas[0] - + alphas[3].mul_base(index) - + alphas[8].mul_base(sibling[0]) - + alphas[9].mul_base(sibling[1]) - + alphas[10].mul_base(sibling[2]) - + alphas[11].mul_base(sibling[3]) - } - } else { - E::ONE - } -} - -// VIRTUAL TABLE RESPONSES -// ================================================================================================ - -/// Constructs the inclusions to the table when the hasher absorbs a new sibling node while -/// computing the old Merkle root. -fn chiplets_vtable_add_sibling(main_trace: &MainTrace, alphas: &[E], row: RowIndex) -> E -where - E: FieldElement, -{ - let f_mv: bool = main_trace.f_mv(row); - let f_mva: bool = main_trace.f_mva(row); - - if f_mv { - let index = main_trace.chiplet_node_index(row); - let lsb = index.as_int() & 1; - if lsb == 0 { - let sibling = &main_trace.chiplet_hasher_state(row)[DIGEST_RANGE.end..]; - alphas[0] - + alphas[3].mul_base(index) - + alphas[12].mul_base(sibling[0]) - + alphas[13].mul_base(sibling[1]) - + alphas[14].mul_base(sibling[2]) - + alphas[15].mul_base(sibling[3]) - } else { - let sibling = &main_trace.chiplet_hasher_state(row)[DIGEST_RANGE]; - alphas[0] - + alphas[3].mul_base(index) - + alphas[8].mul_base(sibling[0]) - + alphas[9].mul_base(sibling[1]) - + alphas[10].mul_base(sibling[2]) - + alphas[11].mul_base(sibling[3]) - } - } else if f_mva { - let index = main_trace.chiplet_node_index(row); - let lsb = index.as_int() & 1; - if lsb == 0 { - let sibling = &main_trace.chiplet_hasher_state(row + 1)[DIGEST_RANGE.end..]; - alphas[0] - + alphas[3].mul_base(index) - + alphas[12].mul_base(sibling[0]) - + alphas[13].mul_base(sibling[1]) - + alphas[14].mul_base(sibling[2]) - + alphas[15].mul_base(sibling[3]) - } else { - let sibling = &main_trace.chiplet_hasher_state(row + 1)[DIGEST_RANGE]; - alphas[0] - + alphas[3].mul_base(index) - + alphas[8].mul_base(sibling[0]) - + alphas[9].mul_base(sibling[1]) - + alphas[10].mul_base(sibling[2]) - + alphas[11].mul_base(sibling[3]) - } - } else { - E::ONE - } -} - -/// Builds the inclusions to the kernel procedure table at `row`. -fn build_kernel_procedure_table_inclusions( - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, -) -> E -where - E: FieldElement, -{ - if main_trace.is_kernel_row(row) { - let idx = main_trace.chiplet_kernel_idx(row); - let idx_delta = { - let idx_next = main_trace.chiplet_kernel_idx(row + 1); - idx_next - idx - }; - let next_row_is_kernel = main_trace.is_kernel_row(row + 1); - - // We want to add an entry to the table in 2 cases: - // 1. when the next row is a kernel row and the idx changes - // - this adds the last row of all rows that share the same idx - // 2. when the next row is not a kernel row - // - this is the edge case of (1) - if !next_row_is_kernel || idx_delta == ONE { - let root0 = main_trace.chiplet_kernel_root_0(row); - let root1 = main_trace.chiplet_kernel_root_1(row); - let root2 = main_trace.chiplet_kernel_root_2(row); - let root3 = main_trace.chiplet_kernel_root_3(row); - - alphas[0] - + alphas[1].mul_base(idx) - + alphas[2].mul_base(root0) - + alphas[3].mul_base(root1) - + alphas[4].mul_base(root2) - + alphas[5].mul_base(root3) - } else { - E::ONE - } - } else { - E::ONE - } -} - -// BUS COLUMN BUILDER -// ================================================================================================ - -/// Describes how to construct the execution trace of the chiplets bus auxiliary trace column. -#[derive(Default)] -pub struct BusColumnBuilder {} - -impl> AuxColumnBuilder for BusColumnBuilder { - /// Constructs the requests made by the VM-components to the chiplets at `row`. - fn get_requests_at( - &self, - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - debugger: &mut BusDebugger, - ) -> E - where - E: FieldElement, - { - let op_code_felt = main_trace.get_op_code(row); - let op_code = op_code_felt.as_int() as u8; - - match op_code { - OPCODE_JOIN | OPCODE_SPLIT | OPCODE_LOOP | OPCODE_CALL => build_control_block_request( - main_trace, - main_trace.decoder_hasher_state(row), - op_code_felt, - alphas, - row, - debugger, - ), - OPCODE_DYN | OPCODE_DYNCALL => { - build_dyn_block_request(main_trace, op_code_felt, alphas, row, debugger) - }, - OPCODE_SYSCALL => { - build_syscall_block_request(main_trace, op_code_felt, alphas, row, debugger) - }, - OPCODE_SPAN => build_span_block_request(main_trace, alphas, row, debugger), - OPCODE_RESPAN => build_respan_block_request(main_trace, alphas, row, debugger), - OPCODE_END => build_end_block_request(main_trace, alphas, row, debugger), - OPCODE_U32AND => build_bitwise_request(main_trace, ZERO, alphas, row, debugger), - OPCODE_U32XOR => build_bitwise_request(main_trace, ONE, alphas, row, debugger), - OPCODE_MLOADW => build_mem_mloadw_mstorew_request( - main_trace, - MEMORY_READ_WORD_LABEL, - alphas, - row, - debugger, - ), - OPCODE_MSTOREW => build_mem_mloadw_mstorew_request( - main_trace, - MEMORY_WRITE_WORD_LABEL, - alphas, - row, - debugger, - ), - OPCODE_MLOAD => build_mem_mload_mstore_request( - main_trace, - MEMORY_READ_ELEMENT_LABEL, - alphas, - row, - debugger, - ), - OPCODE_MSTORE => build_mem_mload_mstore_request( - main_trace, - MEMORY_WRITE_ELEMENT_LABEL, - alphas, - row, - debugger, - ), - OPCODE_MSTREAM => build_mstream_request(main_trace, alphas, row, debugger), - OPCODE_RCOMBBASE => build_rcomb_base_request(main_trace, alphas, row, debugger), - OPCODE_HPERM => build_hperm_request(main_trace, alphas, row, debugger), - OPCODE_MPVERIFY => build_mpverify_request(main_trace, alphas, row, debugger), - OPCODE_MRUPDATE => build_mrupdate_request(main_trace, alphas, row, debugger), - OPCODE_PIPE => build_pipe_request(main_trace, alphas, row, debugger), - _ => E::ONE, - } - } - - /// Constructs the responses from the chiplets to the other VM-components at `row`. - fn get_responses_at( - &self, - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - debugger: &mut BusDebugger, - ) -> E - where - E: FieldElement, - { - if main_trace.is_hash_row(row) { - build_hasher_chiplet_responses(main_trace, row, alphas, debugger) - } else if main_trace.is_bitwise_row(row) { - build_bitwise_chiplet_responses(main_trace, row, alphas, debugger) - } else if main_trace.is_memory_row(row) { - build_memory_chiplet_responses(main_trace, row, alphas, debugger) - } else if main_trace.is_kernel_row(row) { - build_kernel_chiplet_responses(main_trace, row, alphas, debugger) - } else { - E::ONE - } - } -} - -// CHIPLETS REQUESTS -// ================================================================================================ - -/// Builds requests made to the hasher chiplet at the start of a control block. -fn build_control_block_request>( - main_trace: &MainTrace, - decoder_hasher_state: [Felt; 8], - op_code_felt: Felt, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let message = ControlBlockRequestMessage { - transition_label: Felt::from(LINEAR_HASH_LABEL + 16), - addr_next: main_trace.addr(row + 1), - op_code: op_code_felt, - decoder_hasher_state, - }; - - let value = message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_request(Box::new(message), alphas); - - value -} - -/// Builds requests made on a `DYN` or `DYNCALL` operation. -fn build_dyn_block_request>( - main_trace: &MainTrace, - op_code_felt: Felt, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let control_block_req = ControlBlockRequestMessage { - transition_label: Felt::from(LINEAR_HASH_LABEL + 16), - addr_next: main_trace.addr(row + 1), - op_code: op_code_felt, - decoder_hasher_state: [ZERO; 8], - }; - - let memory_req = MemoryWordMessage { - op_label: Felt::from(MEMORY_READ_WORD_LABEL), - ctx: main_trace.ctx(row), - addr: main_trace.stack_element(0, row), - clk: main_trace.clk(row), - word: main_trace.decoder_hasher_state_first_half(row), - source: if op_code_felt == OPCODE_DYNCALL.into() { - "dyncall" - } else { - "dyn" - }, - }; - - let combined_value = control_block_req.value(alphas) * memory_req.value(alphas); - #[cfg(any(test, feature = "bus-debugger"))] - { - _debugger.add_request(Box::new(control_block_req), alphas); - _debugger.add_request(Box::new(memory_req), alphas); - } - - combined_value -} - -/// Builds requests made to kernel ROM chiplet when initializing a syscall block. -fn build_syscall_block_request>( - main_trace: &MainTrace, - op_code_felt: Felt, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let control_block_req = ControlBlockRequestMessage { - transition_label: Felt::from(LINEAR_HASH_LABEL + 16), - addr_next: main_trace.addr(row + 1), - op_code: op_code_felt, - decoder_hasher_state: main_trace.decoder_hasher_state(row), - }; - - let kernel_rom_req = KernelRomMessage { - kernel_proc_digest: main_trace.decoder_hasher_state(row)[0..4].try_into().unwrap(), - }; - - let combined_value = control_block_req.value(alphas) * kernel_rom_req.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - { - _debugger.add_request(Box::new(control_block_req), alphas); - _debugger.add_request(Box::new(kernel_rom_req), alphas); - } - - combined_value -} - -/// Builds requests made to the hasher chiplet at the start of a span block. -fn build_span_block_request>( - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let span_block_message = SpanBlockMessage { - transition_label: Felt::from(LINEAR_HASH_LABEL + 16), - addr_next: main_trace.addr(row + 1), - state: main_trace.decoder_hasher_state(row), - }; - - let value = span_block_message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_request(Box::new(span_block_message), alphas); - - value -} - -/// Builds requests made to the hasher chiplet at the start of a respan block. -fn build_respan_block_request>( - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let respan_block_message = RespanBlockMessage { - transition_label: Felt::from(LINEAR_HASH_LABEL + 32), - addr_next: main_trace.addr(row + 1), - state: main_trace.decoder_hasher_state(row), - }; - - let value = respan_block_message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_request(Box::new(respan_block_message), alphas); - - value -} - -/// Builds requests made to the hasher chiplet at the end of a block. -fn build_end_block_request>( - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let end_block_message = EndBlockMessage { - addr: main_trace.addr(row) + Felt::from(NUM_ROUNDS as u8), - transition_label: Felt::from(RETURN_HASH_LABEL + 32), - digest: main_trace.decoder_hasher_state(row)[..4].try_into().unwrap(), - }; - - let value = end_block_message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_request(Box::new(end_block_message), alphas); - - value -} - -/// Builds requests made to the bitwise chiplet. This can be either a request for the computation -/// of a `XOR` or an `AND` operation. -fn build_bitwise_request>( - main_trace: &MainTrace, - is_xor: Felt, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let bitwise_request_message = BitwiseMessage { - op_label: get_op_label(ONE, ZERO, is_xor, ZERO), - a: main_trace.stack_element(1, row), - b: main_trace.stack_element(0, row), - z: main_trace.stack_element(0, row + 1), - source: if is_xor == ONE { "u32xor" } else { "u32and" }, - }; - - let value = bitwise_request_message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_request(Box::new(bitwise_request_message), alphas); - - value -} - -/// Builds `MSTREAM` requests made to the memory chiplet. -fn build_mstream_request>( - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let op_label = Felt::from(MEMORY_READ_WORD_LABEL); - let addr = main_trace.stack_element(12, row); - let ctx = main_trace.ctx(row); - let clk = main_trace.clk(row); - - let mem_req_1 = MemoryWordMessage { - op_label, - ctx, - addr, - clk, - word: [ - main_trace.stack_element(7, row + 1), - main_trace.stack_element(6, row + 1), - main_trace.stack_element(5, row + 1), - main_trace.stack_element(4, row + 1), - ], - source: "mstream req 1", - }; - let mem_req_2 = MemoryWordMessage { - op_label, - ctx, - addr: addr + FOUR, - clk, - word: [ - main_trace.stack_element(3, row + 1), - main_trace.stack_element(2, row + 1), - main_trace.stack_element(1, row + 1), - main_trace.stack_element(0, row + 1), - ], - source: "mstream req 2", - }; - - let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - { - _debugger.add_request(Box::new(mem_req_1), alphas); - _debugger.add_request(Box::new(mem_req_2), alphas); - } - - combined_value -} - -/// Builds `PIPE` requests made to the memory chiplet. -fn build_pipe_request>( - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let op_label = Felt::from(MEMORY_WRITE_WORD_LABEL); - let addr = main_trace.stack_element(12, row); - let ctx = main_trace.ctx(row); - let clk = main_trace.clk(row); - - let mem_req_1 = MemoryWordMessage { - op_label, - ctx, - addr, - clk, - word: [ - main_trace.stack_element(7, row + 1), - main_trace.stack_element(6, row + 1), - main_trace.stack_element(5, row + 1), - main_trace.stack_element(4, row + 1), - ], - source: "pipe req 1", - }; - let mem_req_2 = MemoryWordMessage { - op_label, - ctx, - addr: addr + FOUR, - clk, - word: [ - main_trace.stack_element(3, row + 1), - main_trace.stack_element(2, row + 1), - main_trace.stack_element(1, row + 1), - main_trace.stack_element(0, row + 1), - ], - source: "pipe req 2", - }; - - let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - { - _debugger.add_request(Box::new(mem_req_1), alphas); - _debugger.add_request(Box::new(mem_req_2), alphas); - } - - combined_value -} - -/// Builds `RCOMBBASE` requests made to the memory chiplet. -fn build_rcomb_base_request>( - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let tz0 = main_trace.helper_register(0, row); - let tz1 = main_trace.helper_register(1, row); - let tzg0 = main_trace.helper_register(2, row); - let tzg1 = main_trace.helper_register(3, row); - let a0 = main_trace.helper_register(4, row); - let a1 = main_trace.helper_register(5, row); - let z_ptr = main_trace.stack_element(13, row); - let a_ptr = main_trace.stack_element(14, row); - let op_label = Felt::from(MEMORY_READ_WORD_LABEL); - - let ctx = main_trace.ctx(row); - let clk = main_trace.clk(row); - - let mem_req_1 = MemoryWordMessage { - op_label, - ctx, - addr: z_ptr, - clk, - word: [tz0, tz1, tzg0, tzg1], - source: "rcombbase req 1", - }; - let mem_req_2 = MemoryWordMessage { - op_label, - ctx, - addr: a_ptr, - clk, - word: [a0, a1, ZERO, ZERO], - source: "rcombbase req 2", - }; - - let combined_value = mem_req_1.value(alphas) * mem_req_2.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - { - _debugger.add_request(Box::new(mem_req_1), alphas); - _debugger.add_request(Box::new(mem_req_2), alphas); - } - - combined_value -} - -/// Builds `HPERM` requests made to the hash chiplet. -fn build_hperm_request>( - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let helper_0 = main_trace.helper_register(0, row); - let s0 = main_trace.stack_element(0, row); - let s1 = main_trace.stack_element(1, row); - let s2 = main_trace.stack_element(2, row); - let s3 = main_trace.stack_element(3, row); - let s4 = main_trace.stack_element(4, row); - let s5 = main_trace.stack_element(5, row); - let s6 = main_trace.stack_element(6, row); - let s7 = main_trace.stack_element(7, row); - let s8 = main_trace.stack_element(8, row); - let s9 = main_trace.stack_element(9, row); - let s10 = main_trace.stack_element(10, row); - let s11 = main_trace.stack_element(11, row); - let s0_nxt = main_trace.stack_element(0, row + 1); - let s1_nxt = main_trace.stack_element(1, row + 1); - let s2_nxt = main_trace.stack_element(2, row + 1); - let s3_nxt = main_trace.stack_element(3, row + 1); - let s4_nxt = main_trace.stack_element(4, row + 1); - let s5_nxt = main_trace.stack_element(5, row + 1); - let s6_nxt = main_trace.stack_element(6, row + 1); - let s7_nxt = main_trace.stack_element(7, row + 1); - let s8_nxt = main_trace.stack_element(8, row + 1); - let s9_nxt = main_trace.stack_element(9, row + 1); - let s10_nxt = main_trace.stack_element(10, row + 1); - let s11_nxt = main_trace.stack_element(11, row + 1); - - let input_req = HasherMessage { - transition_label: Felt::from(LINEAR_HASH_LABEL + 16), - addr_next: helper_0, - node_index: ZERO, - hasher_state: [s11, s10, s9, s8, s7, s6, s5, s4, s3, s2, s1, s0], - source: "hperm input", - }; - let output_req = HasherMessage { - transition_label: Felt::from(RETURN_STATE_LABEL + 32), - addr_next: helper_0 + Felt::new(7), - node_index: ZERO, - hasher_state: [ - s11_nxt, s10_nxt, s9_nxt, s8_nxt, s7_nxt, s6_nxt, s5_nxt, s4_nxt, s3_nxt, s2_nxt, - s1_nxt, s0_nxt, - ], - source: "hperm input", - }; - - let combined_value = input_req.value(alphas) * output_req.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - { - _debugger.add_request(Box::new(input_req), alphas); - _debugger.add_request(Box::new(output_req), alphas); - } - - combined_value -} - -/// Builds `MPVERIFY` requests made to the hash chiplet. -fn build_mpverify_request>( - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let helper_0 = main_trace.helper_register(0, row); - - let node_value = [ - main_trace.stack_element(0, row), - main_trace.stack_element(1, row), - main_trace.stack_element(2, row), - main_trace.stack_element(3, row), - ]; - let node_depth = main_trace.stack_element(4, row); - let node_index = main_trace.stack_element(5, row); - - let merkle_tree_root = [ - main_trace.stack_element(6, row), - main_trace.stack_element(7, row), - main_trace.stack_element(8, row), - main_trace.stack_element(9, row), - ]; - - let input = HasherMessage { - transition_label: Felt::from(MP_VERIFY_LABEL + 16), - addr_next: helper_0, - node_index, - hasher_state: [ - ZERO, - ZERO, - ZERO, - ZERO, - node_value[3], - node_value[2], - node_value[1], - node_value[0], - ZERO, - ZERO, - ZERO, - ZERO, - ], - source: "mpverify input", - }; - - let output = HasherMessage { - transition_label: Felt::from(RETURN_HASH_LABEL + 32), - addr_next: helper_0 + node_depth.mul_small(8) - ONE, - node_index: ZERO, - hasher_state: [ - ZERO, - ZERO, - ZERO, - ZERO, - merkle_tree_root[3], - merkle_tree_root[2], - merkle_tree_root[1], - merkle_tree_root[0], - ZERO, - ZERO, - ZERO, - ZERO, - ], - source: "mpverify output", - }; - - let combined_value = input.value(alphas) * output.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - { - _debugger.add_request(Box::new(input), alphas); - _debugger.add_request(Box::new(output), alphas); - } - - combined_value -} - -/// Builds `MRUPDATE` requests made to the hash chiplet. -fn build_mrupdate_request>( - main_trace: &MainTrace, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let helper_0 = main_trace.helper_register(0, row); - - let old_node_value = [ - main_trace.stack_element(0, row), - main_trace.stack_element(1, row), - main_trace.stack_element(2, row), - main_trace.stack_element(3, row), - ]; - let merkle_path_depth = main_trace.stack_element(4, row); - let node_index = main_trace.stack_element(5, row); - let old_root = [ - main_trace.stack_element(6, row), - main_trace.stack_element(7, row), - main_trace.stack_element(8, row), - main_trace.stack_element(9, row), - ]; - let new_node_value = [ - main_trace.stack_element(10, row), - main_trace.stack_element(11, row), - main_trace.stack_element(12, row), - main_trace.stack_element(13, row), - ]; - let new_root = [ - main_trace.stack_element(0, row + 1), - main_trace.stack_element(1, row + 1), - main_trace.stack_element(2, row + 1), - main_trace.stack_element(3, row + 1), - ]; - - let input_old = HasherMessage { - transition_label: Felt::from(MR_UPDATE_OLD_LABEL + 16), - addr_next: helper_0, - node_index, - hasher_state: [ - ZERO, - ZERO, - ZERO, - ZERO, - old_node_value[3], - old_node_value[2], - old_node_value[1], - old_node_value[0], - ZERO, - ZERO, - ZERO, - ZERO, - ], - source: "mrupdate input_old", - }; - - let output_old = HasherMessage { - transition_label: Felt::from(RETURN_HASH_LABEL + 32), - addr_next: helper_0 + merkle_path_depth.mul_small(8) - ONE, - node_index: ZERO, - hasher_state: [ - ZERO, - ZERO, - ZERO, - ZERO, - old_root[3], - old_root[2], - old_root[1], - old_root[0], - ZERO, - ZERO, - ZERO, - ZERO, - ], - source: "mrupdate output_old", - }; - - let input_new = HasherMessage { - transition_label: Felt::from(MR_UPDATE_NEW_LABEL + 16), - addr_next: helper_0 + merkle_path_depth.mul_small(8), - node_index, - hasher_state: [ - ZERO, - ZERO, - ZERO, - ZERO, - new_node_value[3], - new_node_value[2], - new_node_value[1], - new_node_value[0], - ZERO, - ZERO, - ZERO, - ZERO, - ], - source: "mrupdate input_new", - }; - - let output_new = HasherMessage { - transition_label: Felt::from(RETURN_HASH_LABEL + 32), - addr_next: helper_0 + merkle_path_depth.mul_small(16) - ONE, - node_index: ZERO, - hasher_state: [ - ZERO, - ZERO, - ZERO, - ZERO, - new_root[3], - new_root[2], - new_root[1], - new_root[0], - ZERO, - ZERO, - ZERO, - ZERO, - ], - source: "mrupdate output_new", - }; - - let combined_value = input_old.value(alphas) - * output_old.value(alphas) - * input_new.value(alphas) - * output_new.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - { - _debugger.add_request(Box::new(input_old), alphas); - _debugger.add_request(Box::new(output_old), alphas); - _debugger.add_request(Box::new(input_new), alphas); - _debugger.add_request(Box::new(output_new), alphas); - } - - combined_value -} - -// CHIPLETS RESPONSES -// ================================================================================================ - -/// Builds the response from the hasher chiplet at `row`. -fn build_hasher_chiplet_responses( - main_trace: &MainTrace, - row: RowIndex, - alphas: &[E], - _debugger: &mut BusDebugger, -) -> E -where - E: FieldElement, -{ - let mut multiplicand = E::ONE; - let selector0 = main_trace.chiplet_selector_0(row); - let selector1 = main_trace.chiplet_selector_1(row); - let selector2 = main_trace.chiplet_selector_2(row); - let selector3 = main_trace.chiplet_selector_3(row); - let op_label = get_op_label(selector0, selector1, selector2, selector3); - let addr_next = Felt::from(row + 1); - - // f_bp, f_mp, f_mv or f_mu == 1 - if row.as_usize() % HASH_CYCLE_LEN == 0 { - let state = main_trace.chiplet_hasher_state(row); - let node_index = main_trace.chiplet_node_index(row); - let transition_label = op_label + Felt::from(16_u8); - - // f_bp == 1 - // v_all = v_h + v_a + v_b + v_c - if selector1 == ONE && selector2 == ZERO && selector3 == ZERO { - let hasher_message = HasherMessage { - transition_label, - addr_next, - node_index, - hasher_state: state, - source: "hasher", - }; - multiplicand = hasher_message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_response(Box::new(hasher_message), alphas); - } - - // f_mp or f_mv or f_mu == 1 - // v_leaf = v_h + (1 - b) * v_b + b * v_d - if selector1 == ONE && !(selector2 == ZERO && selector3 == ZERO) { - let bit = (node_index.as_int() & 1) as u8; - if bit == 0 { - let hasher_message = HasherMessage { - transition_label, - addr_next, - node_index, - hasher_state: [ - ZERO, ZERO, ZERO, ZERO, state[4], state[5], state[6], state[7], ZERO, ZERO, - ZERO, ZERO, - ], - source: "hasher", - }; - - multiplicand = hasher_message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_response(Box::new(hasher_message), alphas); - } else { - let hasher_message = HasherMessage { - transition_label, - addr_next, - node_index, - hasher_state: [ - ZERO, ZERO, ZERO, ZERO, state[8], state[9], state[10], state[11], ZERO, - ZERO, ZERO, ZERO, - ], - source: "hasher", - }; - - multiplicand = hasher_message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_response(Box::new(hasher_message), alphas); - } - } - } - - // f_hout, f_sout, f_abp == 1 - if row.as_usize() % HASH_CYCLE_LEN == HASH_CYCLE_LEN - 1 { - let state = main_trace.chiplet_hasher_state(row); - let node_index = main_trace.chiplet_node_index(row); - let transition_label = op_label + Felt::from(32_u8); - - // f_hout == 1 - // v_res = v_h + v_b; - if selector1 == ZERO && selector2 == ZERO && selector3 == ZERO { - let hasher_message = HasherMessage { - transition_label, - addr_next, - node_index, - hasher_state: [ - ZERO, ZERO, ZERO, ZERO, state[4], state[5], state[6], state[7], ZERO, ZERO, - ZERO, ZERO, - ], - source: "hasher", - }; - multiplicand = hasher_message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_response(Box::new(hasher_message), alphas); - } - - // f_sout == 1 - // v_all = v_h + v_a + v_b + v_c - if selector1 == ZERO && selector2 == ZERO && selector3 == ONE { - let hasher_message = HasherMessage { - transition_label, - addr_next, - node_index, - hasher_state: state, - source: "hasher", - }; - - multiplicand = hasher_message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_response(Box::new(hasher_message), alphas); - } - - // f_abp == 1 - // v_abp = v_h + v_b' + v_c' - v_b - v_c - if selector1 == ONE && selector2 == ZERO && selector3 == ZERO { - // build the value from the hasher state's just right after the absorption of new - // elements. - let state_nxt = main_trace.chiplet_hasher_state(row + 1); - - let hasher_message = HasherMessage { - transition_label, - addr_next, - node_index, - hasher_state: [ - ZERO, - ZERO, - ZERO, - ZERO, - state_nxt[4], - state_nxt[5], - state_nxt[6], - state_nxt[7], - state_nxt[8], - state_nxt[9], - state_nxt[10], - state_nxt[11], - ], - source: "hasher", - }; - - multiplicand = hasher_message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_response(Box::new(hasher_message), alphas); - } - } - multiplicand -} - -/// Builds the response from the bitwise chiplet at `row`. -fn build_bitwise_chiplet_responses( - main_trace: &MainTrace, - row: RowIndex, - alphas: &[E], - _debugger: &mut BusDebugger, -) -> E -where - E: FieldElement, -{ - let is_xor = main_trace.chiplet_selector_2(row); - if row.as_usize() % BITWISE_OP_CYCLE_LEN == BITWISE_OP_CYCLE_LEN - 1 { - let bitwise_message = BitwiseMessage { - op_label: get_op_label(ONE, ZERO, is_xor, ZERO), - a: main_trace.chiplet_bitwise_a(row), - b: main_trace.chiplet_bitwise_b(row), - z: main_trace.chiplet_bitwise_z(row), - source: "bitwise chiplet", - }; - - let value = bitwise_message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_response(Box::new(bitwise_message), alphas); - - value - } else { - E::ONE - } -} - -/// Builds the response from the memory chiplet at `row`. -fn build_memory_chiplet_responses( - main_trace: &MainTrace, - row: RowIndex, - alphas: &[E], - _debugger: &mut BusDebugger, -) -> E -where - E: FieldElement, -{ - let access_type = main_trace.chiplet_selector_4(row); - let op_label = { - let is_read = main_trace.chiplet_selector_3(row); - get_memory_op_label(is_read, access_type) - }; - let ctx = main_trace.chiplet_memory_ctx(row); - let clk = main_trace.chiplet_memory_clk(row); - let addr = { - let word = main_trace.chiplet_memory_word(row); - let idx0 = main_trace.chiplet_memory_idx0(row); - let idx1 = main_trace.chiplet_memory_idx1(row); - - word + idx1.mul_small(2) + idx0 - }; - - let message: Box> = if access_type == MEMORY_ACCESS_ELEMENT { - let idx0 = main_trace.chiplet_memory_idx0(row); - let idx1 = main_trace.chiplet_memory_idx1(row); - - let element = if idx1 == ZERO && idx0 == ZERO { - main_trace.chiplet_memory_value_0(row) - } else if idx1 == ZERO && idx0 == ONE { - main_trace.chiplet_memory_value_1(row) - } else if idx1 == ONE && idx0 == ZERO { - main_trace.chiplet_memory_value_2(row) - } else if idx1 == ONE && idx0 == ONE { - main_trace.chiplet_memory_value_3(row) - } else { - panic!("Invalid word indices. idx0: {idx0}, idx1: {idx1}"); - }; - - let message = MemoryElementMessage { op_label, ctx, addr, clk, element }; - - Box::new(message) - } else if access_type == MEMORY_ACCESS_WORD { - let value0 = main_trace.chiplet_memory_value_0(row); - let value1 = main_trace.chiplet_memory_value_1(row); - let value2 = main_trace.chiplet_memory_value_2(row); - let value3 = main_trace.chiplet_memory_value_3(row); - - let message = MemoryWordMessage { - op_label, - ctx, - addr, - clk, - word: [value0, value1, value2, value3], - source: "memory chiplet", - }; - - Box::new(message) - } else { - panic!("Invalid memory element/word column value: {access_type}"); - }; - - let value = message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_response(message, alphas); - - value -} - -/// Builds the response from the kernel chiplet at `row`. -fn build_kernel_chiplet_responses( - main_trace: &MainTrace, - row: RowIndex, - alphas: &[E], - _debugger: &mut BusDebugger, -) -> E -where - E: FieldElement, -{ - let kernel_chiplet_selector = main_trace.chiplet_selector_4(row); - if kernel_chiplet_selector == ONE { - let message = { - let root0 = main_trace.chiplet_kernel_root_0(row); - let root1 = main_trace.chiplet_kernel_root_1(row); - let root2 = main_trace.chiplet_kernel_root_2(row); - let root3 = main_trace.chiplet_kernel_root_3(row); - - KernelRomMessage { - kernel_proc_digest: [root0, root1, root2, root3], - } - }; - - let value = message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_response(Box::new(message), alphas); - - value - } else { - E::ONE - } -} - -// HELPER FUNCTIONS -// ================================================================================================ - -/// Runs an inner product between the alphas and the elements. -#[inline(always)] -fn build_value, const N: usize>( - alphas: &[E], - elements: [Felt; N], -) -> E { - debug_assert_eq!(alphas.len(), elements.len()); - let mut value = E::ZERO; - for i in 0..N { - value += alphas[i].mul_base(elements[i]); - } - value -} - -/// Returns the operation unique label. -fn get_op_label(s0: Felt, s1: Felt, s2: Felt, s3: Felt) -> Felt { - s3.mul_small(1 << 3) + s2.mul_small(1 << 2) + s1.mul_small(2) + s0 + ONE -} - -/// Returns the operation unique label for memory operations. -/// -/// The memory operation label is currently the only label that is built differently (or *simpler*) -/// from the other chiplets. We should refactor the other chiplets to use a similar (simpler) -/// approach. -fn get_memory_op_label(is_read: Felt, is_word_access: Felt) -> Felt { - const MEMORY_SELECTOR: u8 = 0b110; - // Equivalent to `is_read << 1` - let is_read_left_shift_1 = is_read + is_read; - - Felt::from(MEMORY_SELECTOR << 2) + is_read_left_shift_1 + is_word_access -} - -/// Builds `MLOADW` and `MSTOREW` requests made to the memory chiplet. -fn build_mem_mloadw_mstorew_request>( - main_trace: &MainTrace, - op_label: u8, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let word = [ - main_trace.stack_element(3, row + 1), - main_trace.stack_element(2, row + 1), - main_trace.stack_element(1, row + 1), - main_trace.stack_element(0, row + 1), - ]; - let addr = main_trace.stack_element(0, row); - - debug_assert!(op_label == MEMORY_READ_WORD_LABEL || op_label == MEMORY_WRITE_WORD_LABEL); - let ctx = main_trace.ctx(row); - let clk = main_trace.clk(row); - - let message = MemoryWordMessage { - op_label: Felt::from(op_label), - ctx, - addr, - clk, - word, - source: if op_label == MEMORY_READ_WORD_LABEL { - "mloadw" - } else { - "mstorew" - }, - }; - - let value = message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_request(Box::new(message), alphas); - - value -} - -/// Builds `MLOAD` and `MSTORE` requests made to the memory chiplet. -fn build_mem_mload_mstore_request>( - main_trace: &MainTrace, - op_label: u8, - alphas: &[E], - row: RowIndex, - _debugger: &mut BusDebugger, -) -> E { - let element = main_trace.stack_element(0, row + 1); - let addr = main_trace.stack_element(0, row); - - debug_assert!(op_label == MEMORY_READ_ELEMENT_LABEL || op_label == MEMORY_WRITE_ELEMENT_LABEL); - - let ctx = main_trace.ctx(row); - let clk = main_trace.clk(row); - - let message = MemoryElementMessage { - op_label: Felt::from(op_label), - ctx, - addr, - clk, - element, - }; - - let value = message.value(alphas); - - #[cfg(any(test, feature = "bus-debugger"))] - _debugger.add_request(Box::new(message), alphas); - - value -} diff --git a/processor/src/chiplets/aux_trace/virtual_table.rs b/processor/src/chiplets/aux_trace/virtual_table.rs new file mode 100644 index 0000000000..8b0720e695 --- /dev/null +++ b/processor/src/chiplets/aux_trace/virtual_table.rs @@ -0,0 +1,217 @@ +use miden_air::{ + trace::{chiplets::hasher::DIGEST_RANGE, main_trace::MainTrace}, + RowIndex, +}; +use vm_core::{Kernel, ONE}; + +use super::{Felt, FieldElement}; +use crate::{debug::BusDebugger, trace::AuxColumnBuilder}; + +/// Describes how to construct the execution trace of the chiplets virtual table auxiliary trace +/// column. +pub struct ChipletsVTableColBuilder { + kernel: Kernel, +} + +impl ChipletsVTableColBuilder { + pub(super) fn new(kernel: Kernel) -> Self { + Self { kernel } + } +} + +impl> AuxColumnBuilder for ChipletsVTableColBuilder { + fn init_requests( + &self, + _main_trace: &MainTrace, + alphas: &[E], + _debugger: &mut BusDebugger, + ) -> E { + let mut requests = E::ONE; + for (idx, proc_hash) in self.kernel.proc_hashes().iter().enumerate() { + requests *= alphas[0] + + alphas[1].mul_base((idx as u32).into()) + + alphas[2].mul_base(proc_hash[0]) + + alphas[3].mul_base(proc_hash[1]) + + alphas[4].mul_base(proc_hash[2]) + + alphas[5].mul_base(proc_hash[3]); + } + requests + } + + fn get_requests_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, + ) -> E { + chiplets_vtable_remove_sibling(main_trace, alphas, row) + } + + fn get_responses_at( + &self, + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, + _debugger: &mut BusDebugger, + ) -> E { + chiplets_vtable_add_sibling(main_trace, alphas, row) + * build_kernel_procedure_table_inclusions(main_trace, alphas, row) + } +} + +// VIRTUAL TABLE REQUESTS +// ================================================================================================ + +/// Constructs the removals from the table when the hasher absorbs a new sibling node while +/// computing the new Merkle root. +fn chiplets_vtable_remove_sibling(main_trace: &MainTrace, alphas: &[E], row: RowIndex) -> E +where + E: FieldElement, +{ + let f_mu: bool = main_trace.f_mu(row); + let f_mua: bool = main_trace.f_mua(row); + + if f_mu { + let index = main_trace.chiplet_node_index(row); + let lsb = index.as_int() & 1; + if lsb == 0 { + let sibling = &main_trace.chiplet_hasher_state(row)[DIGEST_RANGE.end..]; + alphas[0] + + alphas[3].mul_base(index) + + alphas[12].mul_base(sibling[0]) + + alphas[13].mul_base(sibling[1]) + + alphas[14].mul_base(sibling[2]) + + alphas[15].mul_base(sibling[3]) + } else { + let sibling = &main_trace.chiplet_hasher_state(row)[DIGEST_RANGE]; + alphas[0] + + alphas[3].mul_base(index) + + alphas[8].mul_base(sibling[0]) + + alphas[9].mul_base(sibling[1]) + + alphas[10].mul_base(sibling[2]) + + alphas[11].mul_base(sibling[3]) + } + } else if f_mua { + let index = main_trace.chiplet_node_index(row); + let lsb = index.as_int() & 1; + if lsb == 0 { + let sibling = &main_trace.chiplet_hasher_state(row + 1)[DIGEST_RANGE.end..]; + alphas[0] + + alphas[3].mul_base(index) + + alphas[12].mul_base(sibling[0]) + + alphas[13].mul_base(sibling[1]) + + alphas[14].mul_base(sibling[2]) + + alphas[15].mul_base(sibling[3]) + } else { + let sibling = &main_trace.chiplet_hasher_state(row + 1)[DIGEST_RANGE]; + alphas[0] + + alphas[3].mul_base(index) + + alphas[8].mul_base(sibling[0]) + + alphas[9].mul_base(sibling[1]) + + alphas[10].mul_base(sibling[2]) + + alphas[11].mul_base(sibling[3]) + } + } else { + E::ONE + } +} + +// VIRTUAL TABLE RESPONSES +// ================================================================================================ + +/// Constructs the inclusions to the table when the hasher absorbs a new sibling node while +/// computing the old Merkle root. +fn chiplets_vtable_add_sibling(main_trace: &MainTrace, alphas: &[E], row: RowIndex) -> E +where + E: FieldElement, +{ + let f_mv: bool = main_trace.f_mv(row); + let f_mva: bool = main_trace.f_mva(row); + + if f_mv { + let index = main_trace.chiplet_node_index(row); + let lsb = index.as_int() & 1; + if lsb == 0 { + let sibling = &main_trace.chiplet_hasher_state(row)[DIGEST_RANGE.end..]; + alphas[0] + + alphas[3].mul_base(index) + + alphas[12].mul_base(sibling[0]) + + alphas[13].mul_base(sibling[1]) + + alphas[14].mul_base(sibling[2]) + + alphas[15].mul_base(sibling[3]) + } else { + let sibling = &main_trace.chiplet_hasher_state(row)[DIGEST_RANGE]; + alphas[0] + + alphas[3].mul_base(index) + + alphas[8].mul_base(sibling[0]) + + alphas[9].mul_base(sibling[1]) + + alphas[10].mul_base(sibling[2]) + + alphas[11].mul_base(sibling[3]) + } + } else if f_mva { + let index = main_trace.chiplet_node_index(row); + let lsb = index.as_int() & 1; + if lsb == 0 { + let sibling = &main_trace.chiplet_hasher_state(row + 1)[DIGEST_RANGE.end..]; + alphas[0] + + alphas[3].mul_base(index) + + alphas[12].mul_base(sibling[0]) + + alphas[13].mul_base(sibling[1]) + + alphas[14].mul_base(sibling[2]) + + alphas[15].mul_base(sibling[3]) + } else { + let sibling = &main_trace.chiplet_hasher_state(row + 1)[DIGEST_RANGE]; + alphas[0] + + alphas[3].mul_base(index) + + alphas[8].mul_base(sibling[0]) + + alphas[9].mul_base(sibling[1]) + + alphas[10].mul_base(sibling[2]) + + alphas[11].mul_base(sibling[3]) + } + } else { + E::ONE + } +} + +/// Builds the inclusions to the kernel procedure table at `row`. +fn build_kernel_procedure_table_inclusions( + main_trace: &MainTrace, + alphas: &[E], + row: RowIndex, +) -> E +where + E: FieldElement, +{ + if main_trace.is_kernel_row(row) { + let idx = main_trace.chiplet_kernel_idx(row); + let idx_delta = { + let idx_next = main_trace.chiplet_kernel_idx(row + 1); + idx_next - idx + }; + let next_row_is_kernel = main_trace.is_kernel_row(row + 1); + + // We want to add an entry to the table in 2 cases: + // 1. when the next row is a kernel row and the idx changes + // - this adds the last row of all rows that share the same idx + // 2. when the next row is not a kernel row + // - this is the edge case of (1) + if !next_row_is_kernel || idx_delta == ONE { + let root0 = main_trace.chiplet_kernel_root_0(row); + let root1 = main_trace.chiplet_kernel_root_1(row); + let root2 = main_trace.chiplet_kernel_root_2(row); + let root3 = main_trace.chiplet_kernel_root_3(row); + + alphas[0] + + alphas[1].mul_base(idx) + + alphas[2].mul_base(root0) + + alphas[3].mul_base(root1) + + alphas[4].mul_base(root2) + + alphas[5].mul_base(root3) + } else { + E::ONE + } + } else { + E::ONE + } +} From a454015b864f4490dbe886aa2d489961cfc37726 Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Thu, 20 Feb 2025 09:14:49 -0500 Subject: [PATCH 21/21] chore: move messages into their own file --- .../src/chiplets/aux_trace/bus/bitwise.rs | 38 +- .../src/chiplets/aux_trace/bus/hasher.rs | 222 ++++++++++- .../src/chiplets/aux_trace/bus/kernel.rs | 39 +- .../src/chiplets/aux_trace/bus/memory.rs | 86 ++++- .../src/chiplets/aux_trace/bus/messages.rs | 352 ------------------ processor/src/chiplets/aux_trace/bus/mod.rs | 8 +- 6 files changed, 371 insertions(+), 374 deletions(-) delete mode 100644 processor/src/chiplets/aux_trace/bus/messages.rs diff --git a/processor/src/chiplets/aux_trace/bus/bitwise.rs b/processor/src/chiplets/aux_trace/bus/bitwise.rs index 1ff1c217b7..feeaae58e3 100644 --- a/processor/src/chiplets/aux_trace/bus/bitwise.rs +++ b/processor/src/chiplets/aux_trace/bus/bitwise.rs @@ -1,10 +1,12 @@ +use core::fmt::{Display, Formatter, Result as FmtResult}; + use miden_air::{ trace::{chiplets::bitwise::OP_CYCLE_LEN as BITWISE_OP_CYCLE_LEN, main_trace::MainTrace}, RowIndex, }; use vm_core::{Felt, FieldElement, ONE, ZERO}; -use super::{get_op_label, messages::BitwiseMessage}; +use super::{build_value, get_op_label}; use crate::debug::{BusDebugger, BusMessage}; // REQUESTS @@ -68,3 +70,37 @@ where E::ONE } } + +// MESSAGE +// =============================================================================================== + +pub struct BitwiseMessage { + pub op_label: Felt, + pub a: Felt, + pub b: Felt, + pub z: Felt, + pub source: &'static str, +} + +impl BusMessage for BitwiseMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + alphas[0] + build_value(&alphas[1..5], [self.op_label, self.a, self.b, self.z]) + } + + fn source(&self) -> &str { + self.source + } +} + +impl Display for BitwiseMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "{{ op_label: {}, a: {}, b: {}, z: {} }}", + self.op_label, self.a, self.b, self.z + ) + } +} diff --git a/processor/src/chiplets/aux_trace/bus/hasher.rs b/processor/src/chiplets/aux_trace/bus/hasher.rs index 106509c682..4f59a70c0b 100644 --- a/processor/src/chiplets/aux_trace/bus/hasher.rs +++ b/processor/src/chiplets/aux_trace/bus/hasher.rs @@ -1,24 +1,25 @@ +use core::fmt::{Display, Formatter, Result as FmtResult}; + use miden_air::{ trace::{ - chiplets::hasher::{ - HASH_CYCLE_LEN, LINEAR_HASH_LABEL, MP_VERIFY_LABEL, MR_UPDATE_NEW_LABEL, - MR_UPDATE_OLD_LABEL, NUM_ROUNDS, RETURN_HASH_LABEL, RETURN_STATE_LABEL, + chiplets::{ + hasher, + hasher::{ + HASH_CYCLE_LEN, LINEAR_HASH_LABEL, MP_VERIFY_LABEL, MR_UPDATE_NEW_LABEL, + MR_UPDATE_OLD_LABEL, NUM_ROUNDS, RETURN_HASH_LABEL, RETURN_STATE_LABEL, + }, }, main_trace::MainTrace, }, RowIndex, }; -use vm_core::{Felt, FieldElement, ONE, ZERO}; - -use super::{ - get_op_label, - messages::{ - ControlBlockRequestMessage, EndBlockMessage, HasherMessage, RespanBlockMessage, - SpanBlockMessage, - }, +use vm_core::{ + utils::range, Felt, FieldElement, ONE, OPCODE_CALL, OPCODE_JOIN, OPCODE_LOOP, OPCODE_SPLIT, + ZERO, }; -use crate::debug::{BusDebugger, BusMessage}; +use super::{build_value, get_op_label}; +use crate::debug::{BusDebugger, BusMessage}; // REQUESTS // ============================================================================================== @@ -157,7 +158,7 @@ pub(super) fn build_hperm_request>( s11_nxt, s10_nxt, s9_nxt, s8_nxt, s7_nxt, s6_nxt, s5_nxt, s4_nxt, s3_nxt, s2_nxt, s1_nxt, s0_nxt, ], - source: "hperm input", + source: "hperm output", }; let combined_value = input_req.value(alphas) * output_req.value(alphas); @@ -546,3 +547,198 @@ where } multiplicand } + +// CONTROL BLOCK REQUEST MESSAGE +// =============================================================================================== + +pub struct ControlBlockRequestMessage { + pub transition_label: Felt, + pub addr_next: Felt, + pub op_code: Felt, + pub decoder_hasher_state: [Felt; 8], +} + +impl BusMessage for ControlBlockRequestMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let header = alphas[0] + + alphas[1].mul_base(self.transition_label) + + alphas[2].mul_base(self.addr_next); + + header + + alphas[5].mul_base(self.op_code) + + build_value(&alphas[8..16], self.decoder_hasher_state) + } + + fn source(&self) -> &str { + let op_code = self.op_code.as_int() as u8; + match op_code { + OPCODE_JOIN => "join", + OPCODE_SPLIT => "split", + OPCODE_LOOP => "loop", + OPCODE_CALL => "call", + _ => panic!("unexpected opcode: {op_code}"), + } + } +} + +impl Display for ControlBlockRequestMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "{{ transition_label: {}, addr_next: {}, op_code: {}, decoder_hasher_state: {:?} }}", + self.transition_label, self.addr_next, self.op_code, self.decoder_hasher_state + ) + } +} + +// GENERIC HASHER MESSAGE +// =============================================================================================== + +const NUM_HEADER_ALPHAS: usize = 4; + +pub struct HasherMessage { + pub transition_label: Felt, + pub addr_next: Felt, + pub node_index: Felt, + pub hasher_state: [Felt; hasher::STATE_WIDTH], + pub source: &'static str, +} + +impl BusMessage for HasherMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let header = alphas[0] + + alphas[1].mul_base(self.transition_label) + + alphas[2].mul_base(self.addr_next) + + alphas[3].mul_base(self.node_index); + + header + + build_value(&alphas[range(NUM_HEADER_ALPHAS, hasher::STATE_WIDTH)], self.hasher_state) + } + + fn source(&self) -> &str { + self.source + } +} + +impl Display for HasherMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "{{ transition_label: {}, addr_next: {}, node_index: {}, decoder_hasher_state: {:?} }}", + self.transition_label, self.addr_next, self.node_index, self.hasher_state + ) + } +} + +// SPAN BLOCK MESSAGE +// =============================================================================================== + +pub struct SpanBlockMessage { + pub transition_label: Felt, + pub addr_next: Felt, + pub state: [Felt; 8], +} + +impl BusMessage for SpanBlockMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let header = alphas[0] + + alphas[1].mul_base(self.transition_label) + + alphas[2].mul_base(self.addr_next); + + header + build_value(&alphas[8..16], self.state) + } + + fn source(&self) -> &str { + "span" + } +} + +impl Display for SpanBlockMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "{{ transition_label: {}, addr_next: {}, state: {:?} }}", + self.transition_label, self.addr_next, self.state + ) + } +} + +// RESPAN BLOCK MESSAGE +// =============================================================================================== + +pub struct RespanBlockMessage { + pub transition_label: Felt, + pub addr_next: Felt, + pub state: [Felt; 8], +} + +impl BusMessage for RespanBlockMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let header = alphas[0] + + alphas[1].mul_base(self.transition_label) + + alphas[2].mul_base(self.addr_next - ONE); + + header + build_value(&alphas[8..16], self.state) + } + + fn source(&self) -> &str { + "respan" + } +} + +impl Display for RespanBlockMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "{{ transition_label: {}, addr_next: {}, state: {:?} }}", + self.transition_label, self.addr_next, self.state + ) + } +} + +// END BLOCK MESSAGE +// =============================================================================================== + +pub struct EndBlockMessage { + pub addr: Felt, + pub transition_label: Felt, + pub digest: [Felt; 4], +} + +impl BusMessage for EndBlockMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + let header = + alphas[0] + alphas[1].mul_base(self.transition_label) + alphas[2].mul_base(self.addr); + + header + build_value(&alphas[8..12], self.digest) + } + + fn source(&self) -> &str { + "end" + } +} + +impl Display for EndBlockMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "{{ addr: {}, transition_label: {}, digest: {:?} }}", + self.addr, self.transition_label, self.digest + ) + } +} diff --git a/processor/src/chiplets/aux_trace/bus/kernel.rs b/processor/src/chiplets/aux_trace/bus/kernel.rs index 3554328645..26eca183d3 100644 --- a/processor/src/chiplets/aux_trace/bus/kernel.rs +++ b/processor/src/chiplets/aux_trace/bus/kernel.rs @@ -1,7 +1,11 @@ -use miden_air::{trace::main_trace::MainTrace, RowIndex}; +use core::fmt::{Display, Formatter, Result as FmtResult}; + +use miden_air::{ + trace::{chiplets::kernel_rom::KERNEL_PROC_LABEL, main_trace::MainTrace}, + RowIndex, +}; use vm_core::{Felt, FieldElement, ONE}; -use super::messages::KernelRomMessage; use crate::debug::{BusDebugger, BusMessage}; // REQUESTS @@ -46,3 +50,34 @@ where E::ONE } } + +// MESSAGE +// =============================================================================================== + +pub struct KernelRomMessage { + pub kernel_proc_digest: [Felt; 4], +} + +impl BusMessage for KernelRomMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + alphas[0] + + alphas[1].mul_base(KERNEL_PROC_LABEL) + + alphas[2].mul_base(self.kernel_proc_digest[0]) + + alphas[3].mul_base(self.kernel_proc_digest[1]) + + alphas[4].mul_base(self.kernel_proc_digest[2]) + + alphas[5].mul_base(self.kernel_proc_digest[3]) + } + + fn source(&self) -> &str { + "kernel rom" + } +} + +impl Display for KernelRomMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "{{ proc digest: {:?} }}", self.kernel_proc_digest) + } +} diff --git a/processor/src/chiplets/aux_trace/bus/memory.rs b/processor/src/chiplets/aux_trace/bus/memory.rs index f0cf74e136..9c0b7759a3 100644 --- a/processor/src/chiplets/aux_trace/bus/memory.rs +++ b/processor/src/chiplets/aux_trace/bus/memory.rs @@ -1,4 +1,5 @@ use alloc::boxed::Box; +use core::fmt::{Display, Formatter, Result as FmtResult}; use miden_air::{ trace::{ @@ -12,7 +13,7 @@ use miden_air::{ }; use vm_core::{Felt, FieldElement, ONE, ZERO}; -use super::messages::{MemoryElementMessage, MemoryWordMessage}; +use super::build_value; use crate::debug::{BusDebugger, BusMessage}; // CONSTANTS @@ -334,3 +335,86 @@ fn get_memory_op_label(is_read: Felt, is_word_access: Felt) -> Felt { Felt::from(MEMORY_SELECTOR << 2) + is_read_left_shift_1 + is_word_access } + +// MESSAGES +// =============================================================================================== + +pub struct MemoryWordMessage { + pub op_label: Felt, + pub ctx: Felt, + pub addr: Felt, + pub clk: Felt, + pub word: [Felt; 4], + pub source: &'static str, +} + +impl BusMessage for MemoryWordMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + alphas[0] + + build_value( + &alphas[1..9], + [ + self.op_label, + self.ctx, + self.addr, + self.clk, + self.word[0], + self.word[1], + self.word[2], + self.word[3], + ], + ) + } + + fn source(&self) -> &str { + self.source + } +} + +impl Display for MemoryWordMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "{{ op_label: {}, ctx: {}, addr: {}, clk: {}, word: {:?} }}", + self.op_label, self.ctx, self.addr, self.clk, self.word + ) + } +} + +pub struct MemoryElementMessage { + pub op_label: Felt, + pub ctx: Felt, + pub addr: Felt, + pub clk: Felt, + pub element: Felt, +} + +impl BusMessage for MemoryElementMessage +where + E: FieldElement, +{ + fn value(&self, alphas: &[E]) -> E { + alphas[0] + + build_value( + &alphas[1..6], + [self.op_label, self.ctx, self.addr, self.clk, self.element], + ) + } + + fn source(&self) -> &str { + "memory element" + } +} + +impl Display for MemoryElementMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "{{ op_label: {}, ctx: {}, addr: {}, clk: {}, element: {} }}", + self.op_label, self.ctx, self.addr, self.clk, self.element + ) + } +} diff --git a/processor/src/chiplets/aux_trace/bus/messages.rs b/processor/src/chiplets/aux_trace/bus/messages.rs deleted file mode 100644 index 2c15f32727..0000000000 --- a/processor/src/chiplets/aux_trace/bus/messages.rs +++ /dev/null @@ -1,352 +0,0 @@ -use core::fmt::{Display, Formatter, Result as FmtResult}; - -use miden_air::trace::chiplets::{hasher, kernel_rom::KERNEL_PROC_LABEL}; -use vm_core::{ - utils::range, Felt, FieldElement, ONE, OPCODE_CALL, OPCODE_JOIN, OPCODE_LOOP, OPCODE_SPLIT, -}; - -use super::build_value; -use crate::debug::BusMessage; - -// HASHER MESSAGES -// =============================================================================================== - -pub struct ControlBlockRequestMessage { - pub transition_label: Felt, - pub addr_next: Felt, - pub op_code: Felt, - pub decoder_hasher_state: [Felt; 8], -} - -impl BusMessage for ControlBlockRequestMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - let header = alphas[0] - + alphas[1].mul_base(self.transition_label) - + alphas[2].mul_base(self.addr_next); - - header - + alphas[5].mul_base(self.op_code) - + build_value(&alphas[8..16], self.decoder_hasher_state) - } - - fn source(&self) -> &str { - let op_code = self.op_code.as_int() as u8; - match op_code { - OPCODE_JOIN => "join", - OPCODE_SPLIT => "split", - OPCODE_LOOP => "loop", - OPCODE_CALL => "call", - _ => panic!("unexpected opcode: {op_code}"), - } - } -} - -impl Display for ControlBlockRequestMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - "{{ transition_label: {}, addr_next: {}, op_code: {}, decoder_hasher_state: {:?} }}", - self.transition_label, self.addr_next, self.op_code, self.decoder_hasher_state - ) - } -} - -const NUM_HEADER_ALPHAS: usize = 4; - -pub struct HasherMessage { - pub transition_label: Felt, - pub addr_next: Felt, - pub node_index: Felt, - pub hasher_state: [Felt; hasher::STATE_WIDTH], - pub source: &'static str, -} - -impl BusMessage for HasherMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - let header = alphas[0] - + alphas[1].mul_base(self.transition_label) - + alphas[2].mul_base(self.addr_next) - + alphas[3].mul_base(self.node_index); - - header - + build_value(&alphas[range(NUM_HEADER_ALPHAS, hasher::STATE_WIDTH)], self.hasher_state) - } - - fn source(&self) -> &str { - self.source - } -} - -impl Display for HasherMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - "{{ transition_label: {}, addr_next: {}, node_index: {}, decoder_hasher_state: {:?} }}", - self.transition_label, self.addr_next, self.node_index, self.hasher_state - ) - } -} - -// KERNEL ROM MESSAGES -// =============================================================================================== - -pub struct KernelRomMessage { - pub kernel_proc_digest: [Felt; 4], -} - -impl BusMessage for KernelRomMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - alphas[0] - + alphas[1].mul_base(KERNEL_PROC_LABEL) - + alphas[2].mul_base(self.kernel_proc_digest[0]) - + alphas[3].mul_base(self.kernel_proc_digest[1]) - + alphas[4].mul_base(self.kernel_proc_digest[2]) - + alphas[5].mul_base(self.kernel_proc_digest[3]) - } - - fn source(&self) -> &str { - "kernel rom" - } -} - -impl Display for KernelRomMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "{{ proc digest: {:?} }}", self.kernel_proc_digest) - } -} - -// SPAN BLOCK MESSAGE -// =============================================================================================== - -pub struct SpanBlockMessage { - pub transition_label: Felt, - pub addr_next: Felt, - pub state: [Felt; 8], -} - -impl BusMessage for SpanBlockMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - let header = alphas[0] - + alphas[1].mul_base(self.transition_label) - + alphas[2].mul_base(self.addr_next); - - header + build_value(&alphas[8..16], self.state) - } - - fn source(&self) -> &str { - "span" - } -} - -impl Display for SpanBlockMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - "{{ transition_label: {}, addr_next: {}, state: {:?} }}", - self.transition_label, self.addr_next, self.state - ) - } -} - -// RESPAN BLOCK MESSAGE -// =============================================================================================== - -pub struct RespanBlockMessage { - pub transition_label: Felt, - pub addr_next: Felt, - pub state: [Felt; 8], -} - -impl BusMessage for RespanBlockMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - let header = alphas[0] - + alphas[1].mul_base(self.transition_label) - + alphas[2].mul_base(self.addr_next - ONE); - - header + build_value(&alphas[8..16], self.state) - } - - fn source(&self) -> &str { - "respan" - } -} - -impl Display for RespanBlockMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - "{{ transition_label: {}, addr_next: {}, state: {:?} }}", - self.transition_label, self.addr_next, self.state - ) - } -} - -// END BLOCK MESSAGE -// =============================================================================================== - -pub struct EndBlockMessage { - pub addr: Felt, - pub transition_label: Felt, - pub digest: [Felt; 4], -} - -impl BusMessage for EndBlockMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - let header = - alphas[0] + alphas[1].mul_base(self.transition_label) + alphas[2].mul_base(self.addr); - - header + build_value(&alphas[8..12], self.digest) - } - - fn source(&self) -> &str { - "end" - } -} - -impl Display for EndBlockMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - "{{ addr: {}, transition_label: {}, digest: {:?} }}", - self.addr, self.transition_label, self.digest - ) - } -} - -// BITWISE REQUEST MESSAGE -// =============================================================================================== - -pub struct BitwiseMessage { - pub op_label: Felt, - pub a: Felt, - pub b: Felt, - pub z: Felt, - pub source: &'static str, -} - -impl BusMessage for BitwiseMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - alphas[0] + build_value(&alphas[1..5], [self.op_label, self.a, self.b, self.z]) - } - - fn source(&self) -> &str { - self.source - } -} - -impl Display for BitwiseMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - "{{ op_label: {}, a: {}, b: {}, z: {} }}", - self.op_label, self.a, self.b, self.z - ) - } -} - -// MEMORY REQUEST WORD MESSAGE -// =============================================================================================== - -pub struct MemoryWordMessage { - pub op_label: Felt, - pub ctx: Felt, - pub addr: Felt, - pub clk: Felt, - pub word: [Felt; 4], - pub source: &'static str, -} - -impl BusMessage for MemoryWordMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - alphas[0] - + build_value( - &alphas[1..9], - [ - self.op_label, - self.ctx, - self.addr, - self.clk, - self.word[0], - self.word[1], - self.word[2], - self.word[3], - ], - ) - } - - fn source(&self) -> &str { - self.source - } -} - -impl Display for MemoryWordMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - "{{ op_label: {}, ctx: {}, addr: {}, clk: {}, word: {:?} }}", - self.op_label, self.ctx, self.addr, self.clk, self.word - ) - } -} - -// MEMORY REQUEST ELEMENT MESSAGE -// =============================================================================================== - -pub struct MemoryElementMessage { - pub op_label: Felt, - pub ctx: Felt, - pub addr: Felt, - pub clk: Felt, - pub element: Felt, -} - -impl BusMessage for MemoryElementMessage -where - E: FieldElement, -{ - fn value(&self, alphas: &[E]) -> E { - alphas[0] - + build_value( - &alphas[1..6], - [self.op_label, self.ctx, self.addr, self.clk, self.element], - ) - } - - fn source(&self) -> &str { - "memory element" - } -} - -impl Display for MemoryElementMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - "{{ op_label: {}, ctx: {}, addr: {}, clk: {}, element: {} }}", - self.op_label, self.ctx, self.addr, self.clk, self.element - ) - } -} diff --git a/processor/src/chiplets/aux_trace/bus/mod.rs b/processor/src/chiplets/aux_trace/bus/mod.rs index 79ee25bfc8..708af306bc 100644 --- a/processor/src/chiplets/aux_trace/bus/mod.rs +++ b/processor/src/chiplets/aux_trace/bus/mod.rs @@ -2,15 +2,14 @@ use bitwise::{build_bitwise_chiplet_responses, build_bitwise_request}; use hasher::{ build_control_block_request, build_end_block_request, build_hasher_chiplet_responses, build_hperm_request, build_mpverify_request, build_mrupdate_request, - build_respan_block_request, build_span_block_request, + build_respan_block_request, build_span_block_request, ControlBlockRequestMessage, }; -use kernel::build_kernel_chiplet_responses; +use kernel::{build_kernel_chiplet_responses, KernelRomMessage}; use memory::{ build_mem_mload_mstore_request, build_mem_mloadw_mstorew_request, build_memory_chiplet_responses, build_mstream_request, build_pipe_request, - build_rcomb_base_request, + build_rcomb_base_request, MemoryWordMessage, }; -use messages::{ControlBlockRequestMessage, KernelRomMessage, MemoryWordMessage}; use miden_air::{ trace::{ chiplets::{ @@ -41,7 +40,6 @@ mod bitwise; mod hasher; mod kernel; mod memory; -mod messages; // BUS COLUMN BUILDER // ================================================================================================