diff --git a/core/src/cpu/air/mod.rs b/core/src/cpu/air/mod.rs index 653c809c9b..4caebbbf73 100644 --- a/core/src/cpu/air/mod.rs +++ b/core/src/cpu/air/mod.rs @@ -26,10 +26,12 @@ use crate::operations::BabyBearWordRangeChecker; use crate::runtime::Opcode; use super::columns::eval_channel_selectors; +use super::columns::OPCODE_SELECTORS_COL_MAP; impl Air for CpuChip where AB: SP1AirBuilder + AirBuilderWithPublicValues, + AB::Var: Sized, { #[inline(never)] fn eval(&self, builder: &mut AB) { @@ -123,6 +125,27 @@ where // Check that the is_real flag is correct. self.eval_is_real(builder, local, next); + + // Check that when `is_real=0` that all flags that send interactions are zero. + local + .selectors + .into_iter() + .enumerate() + .for_each(|(i, selector)| { + if i == OPCODE_SELECTORS_COL_MAP.imm_b { + builder + .when(AB::Expr::one() - local.is_real) + .assert_one(local.selectors.imm_b); + } else if i == OPCODE_SELECTORS_COL_MAP.imm_c { + builder + .when(AB::Expr::one() - local.is_real) + .assert_one(local.selectors.imm_c); + } else { + builder + .when(AB::Expr::one() - local.is_real) + .assert_zero(selector); + } + }); } } diff --git a/core/src/cpu/columns/opcode.rs b/core/src/cpu/columns/opcode.rs index ac67c6934e..80fd63ad3d 100644 --- a/core/src/cpu/columns/opcode.rs +++ b/core/src/cpu/columns/opcode.rs @@ -1,11 +1,23 @@ use p3_field::PrimeField; use sp1_derive::AlignedBorrow; -use std::mem::size_of; +use std::mem::{size_of, transmute}; use std::vec::IntoIter; -use crate::runtime::{Instruction, Opcode}; +use crate::{ + runtime::{Instruction, Opcode}, + utils::indices_arr, +}; pub const NUM_OPCODE_SELECTOR_COLS: usize = size_of::>(); +pub const OPCODE_SELECTORS_COL_MAP: OpcodeSelectorCols = make_selectors_col_map(); + +/// Creates the column map for the CPU. +const fn make_selectors_col_map() -> OpcodeSelectorCols { + let indices_arr = indices_arr::(); + unsafe { + transmute::<[usize; NUM_OPCODE_SELECTOR_COLS], OpcodeSelectorCols>(indices_arr) + } +} /// The column layout for opcode selectors. #[derive(AlignedBorrow, Clone, Copy, Default, Debug)] @@ -98,7 +110,7 @@ impl IntoIterator for OpcodeSelectorCols { type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { - vec![ + let columns = vec![ self.imm_b, self.imm_c, self.is_alu, @@ -121,7 +133,8 @@ impl IntoIterator for OpcodeSelectorCols { self.is_jal, self.is_auipc, self.is_unimpl, - ] - .into_iter() + ]; + assert_eq!(columns.len(), NUM_OPCODE_SELECTOR_COLS); + columns.into_iter() } }