From 675302dc0950d5548112f2084bce82f3d8c80294 Mon Sep 17 00:00:00 2001 From: Jan Ferdinand Sauer Date: Mon, 6 Nov 2023 13:10:32 +0100 Subject: [PATCH 1/3] make instruction `read_io` take an argument in range 1..=5 --- triton-vm/src/error.rs | 2 ++ triton-vm/src/instruction.rs | 20 ++++++++------ triton-vm/src/lib.rs | 17 ++++++++---- triton-vm/src/parser.rs | 36 +++++++++++++++++++++----- triton-vm/src/table/processor_table.rs | 21 ++++++++------- triton-vm/src/vm.rs | 22 ++++++++++------ 6 files changed, 81 insertions(+), 37 deletions(-) diff --git a/triton-vm/src/error.rs b/triton-vm/src/error.rs index a290b02f..37318508 100644 --- a/triton-vm/src/error.rs +++ b/triton-vm/src/error.rs @@ -19,6 +19,7 @@ pub enum InstructionError { VectorAssertionFailed(usize, u32, OpStackElement, BFieldElement, BFieldElement), IllegalPop(usize), IllegalDivine(usize), + IllegalReadIo(usize), SwapST0, InverseOfZero, DivisionByZero, @@ -48,6 +49,7 @@ impl Display for InstructionError { } IllegalPop(st) => write!(f, "must pop at least 1, at most 5 elements, not {st}"), IllegalDivine(st) => write!(f, "must divine at least 1, at most 5 elements, not {st}"), + IllegalReadIo(st) => write!(f, "must read_io at least 1, at most 5 elements, not {st}"), SwapST0 => write!(f, "Cannot swap stack element 0 with itself"), InverseOfZero => write!(f, "0 does not have a multiplicative inverse"), DivisionByZero => write!(f, "Division by 0 is impossible"), diff --git a/triton-vm/src/instruction.rs b/triton-vm/src/instruction.rs index db2a655f..a8313c2d 100644 --- a/triton-vm/src/instruction.rs +++ b/triton-vm/src/instruction.rs @@ -148,7 +148,7 @@ pub enum AnInstruction { XbMul, // Read/write - ReadIo, + ReadIo(OpStackElement), WriteIo, } @@ -192,7 +192,7 @@ impl AnInstruction { XxMul => 74, XInvert => 80, XbMul => 82, - ReadIo => 88, + ReadIo(_) => 41, WriteIo => 90, } } @@ -235,7 +235,7 @@ impl AnInstruction { XxMul => "xxmul", XInvert => "xinvert", XbMul => "xbmul", - ReadIo => "read_io", + ReadIo(_) => "read_io", WriteIo => "write_io", } } @@ -250,6 +250,7 @@ impl AnInstruction { Divine(_) => 2, Dup(_) | Swap(_) => 2, Call(_) => 2, + ReadIo(_) => 2, _ => 1, } } @@ -304,7 +305,7 @@ impl AnInstruction { XxMul => XxMul, XInvert => XInvert, XbMul => XbMul, - ReadIo => ReadIo, + ReadIo(x) => ReadIo(*x), WriteIo => WriteIo, } } @@ -359,7 +360,7 @@ impl AnInstruction { XxMul => -3, XInvert => 0, XbMul => -1, - ReadIo => 1, + ReadIo(n) => n.index() as i32, WriteIo => -1, } } @@ -377,6 +378,7 @@ impl AnInstruction { Pop(st) => *st < ST1 || ST5 < *st, Divine(st) => *st < ST1 || ST5 < *st, Swap(ST0) => true, + ReadIo(st) => *st < ST1 || ST5 < *st, _ => false, } } @@ -387,7 +389,7 @@ impl Display for AnInstruction { write!(f, "{}", self.name())?; match self { Push(arg) => write!(f, " {arg}"), - Pop(arg) | Divine(arg) | Dup(arg) | Swap(arg) => write!(f, " {arg}"), + Pop(arg) | Divine(arg) | Dup(arg) | Swap(arg) | ReadIo(arg) => write!(f, " {arg}"), Call(arg) => write!(f, " {arg}"), _ => Ok(()), } @@ -399,7 +401,7 @@ impl Instruction { pub fn arg(&self) -> Option { match self { Push(arg) | Call(arg) => Some(*arg), - Pop(arg) | Divine(arg) | Dup(arg) | Swap(arg) => Some(arg.into()), + Pop(arg) | Divine(arg) | Dup(arg) | Swap(arg) | ReadIo(arg) => Some(arg.into()), _ => None, } } @@ -429,6 +431,7 @@ impl Instruction { Divine(_) => Some(Divine(stack_element)), Dup(_) => Some(Dup(stack_element)), Swap(_) => Some(Swap(stack_element)), + ReadIo(_) => Some(ReadIo(stack_element)), _ => None, }; if new_instruction?.has_illegal_argument() { @@ -514,7 +517,7 @@ const fn all_instructions_without_args() -> [AnInstruction; Instr XxMul, XInvert, XbMul, - ReadIo, + ReadIo(ST0), WriteIo, ] } @@ -629,6 +632,7 @@ mod tests { Pop(ST0) => Pop(ST1), Divine(ST0) => Divine(ST1), Swap(ST0) => Swap(ST1), + ReadIo(ST0) => ReadIo(ST1), _ => self, } } diff --git a/triton-vm/src/lib.rs b/triton-vm/src/lib.rs index e5f0ecdb..340552fa 100644 --- a/triton-vm/src/lib.rs +++ b/triton-vm/src/lib.rs @@ -258,12 +258,12 @@ macro_rules! triton_program { /// ``` /// # use triton_vm::triton_asm; /// # use triton_vm::instruction::LabelledInstruction; -/// # use triton_vm::instruction::AnInstruction::ReadIo; -/// let instructions = triton_asm![read_io; 3]; +/// # use triton_vm::instruction::AnInstruction::SpongeAbsorb; +/// let instructions = triton_asm![sponge_absorb; 3]; /// assert_eq!(3, instructions.len()); -/// assert_eq!(LabelledInstruction::Instruction(ReadIo), instructions[0]); -/// assert_eq!(LabelledInstruction::Instruction(ReadIo), instructions[1]); -/// assert_eq!(LabelledInstruction::Instruction(ReadIo), instructions[2]); +/// assert_eq!(LabelledInstruction::Instruction(SpongeAbsorb), instructions[0]); +/// assert_eq!(LabelledInstruction::Instruction(SpongeAbsorb), instructions[1]); +/// assert_eq!(LabelledInstruction::Instruction(SpongeAbsorb), instructions[2]); /// ``` /// /// Inserting substring of labelled instructions: @@ -341,6 +341,7 @@ macro_rules! triton_asm { [dup $arg:literal; $num:expr] => { vec![ $crate::triton_instr!(dup $arg); $num ] }; [swap $arg:literal; $num:expr] => { vec![ $crate::triton_instr!(swap $arg); $num ] }; [call $arg:ident; $num:expr] => { vec![ $crate::triton_instr!(call $arg); $num ] }; + [read_io $arg:literal; $num:expr] => { vec![ $crate::triton_instr!(read_io $arg); $num ] }; [$instr:ident; $num:expr] => { vec![ $crate::triton_instr!($instr); $num ] }; // entry point @@ -400,6 +401,12 @@ macro_rules! triton_instr { let instruction = $crate::instruction::AnInstruction::::Call(argument); $crate::instruction::LabelledInstruction::Instruction(instruction) }}; + (read_io $arg:literal) => {{ + assert!(1_u32 <= $arg && $arg <= 5, "`read_io {}` is illegal.", $arg); + let argument: $crate::op_stack::OpStackElement = u32::try_into($arg).unwrap(); + let instruction = $crate::instruction::AnInstruction::::ReadIo(argument); + $crate::instruction::LabelledInstruction::Instruction(instruction) + }}; ($instr:ident) => {{ let (_, instructions) = $crate::parser::tokenize(stringify!($instr)).unwrap(); instructions[0].to_labelled_instruction() diff --git a/triton-vm/src/parser.rs b/triton-vm/src/parser.rs index c476f12f..88e24efa 100644 --- a/triton-vm/src/parser.rs +++ b/triton-vm/src/parser.rs @@ -275,7 +275,7 @@ fn an_instruction(s: &str) -> ParseResult> { )); // Read/write - let read_io = instruction("read_io", ReadIo); + let read_io = read_io_instruction(); let write_io = instruction("write_io", WriteIo); let read_write = alt((read_io, write_io)); @@ -408,6 +408,21 @@ fn call_instruction<'a>() -> impl Fn(&'a str) -> ParseResult impl Fn(&str) -> ParseResult> { + move |s: &str| { + let (s, _) = token1("read_io")(s)?; // require space after instruction name + let (s, stack_register) = stack_register(s)?; + let (s, _) = comment_or_whitespace1(s)?; + + let instruction = ReadIo(stack_register); + if instruction.has_illegal_argument() { + return cut(context("illegal argument for instruction `read_io`", fail))(s); + } + + Ok((s, instruction)) + } +} + fn field_element(s_orig: &str) -> ParseResult { let (s, negative) = opt(token0("-"))(s_orig)?; let (s, n) = digit1(s)?; @@ -639,7 +654,9 @@ pub(crate) mod tests { fn instruction_gen(labels: &mut Vec) -> Vec { let mut rng = thread_rng(); - let difficult_instructions = vec!["pop", "push", "divine", "dup", "swap", "skiz", "call"]; + let difficult_instructions = vec![ + "pop", "push", "divine", "dup", "swap", "skiz", "call", "read_io", + ]; let simple_instructions = ALL_INSTRUCTION_NAMES .into_iter() .filter(|name| !difficult_instructions.contains(name)) @@ -647,7 +664,7 @@ pub(crate) mod tests { let generators = [vec!["simple"], difficult_instructions].concat(); // Test difficult instructions more frequently. - let weights = vec![simple_instructions.len(), 2, 2, 2, 6, 6, 2, 10]; + let weights = vec![simple_instructions.len(), 2, 2, 2, 6, 6, 2, 10, 2]; assert_eq!( generators.len(), @@ -680,12 +697,12 @@ pub(crate) mod tests { } "dup" => { - let arg: usize = rng.gen_range(0..15); + let arg: usize = rng.gen_range(0..16); vec!["dup".to_string(), format!("{arg}")] } "swap" => { - let arg: usize = rng.gen_range(1..15); + let arg: usize = rng.gen_range(1..16); vec!["swap".to_string(), format!("{arg}")] } @@ -700,6 +717,11 @@ pub(crate) mod tests { vec!["call".to_string(), some_label] } + "read_io" => { + let arg: usize = rng.gen_range(1..=5); + vec!["read_io".to_string(), format!("{arg}")] + } + unknown => panic!("Unknown generator, {unknown}"), } } @@ -1098,8 +1120,8 @@ pub(crate) mod tests { let expected_instructions = vec![Instruction(Push(42_u64.into())); 3]; assert_eq!(expected_instructions, instructions); - let instructions = triton_asm![read_io; 15]; - let expected_instructions = vec![Instruction(ReadIo); 15]; + let instructions = triton_asm![read_io 2; 15]; + let expected_instructions = vec![Instruction(ReadIo(ST2)); 15]; assert_eq!(expected_instructions, instructions); let instructions = triton_asm![divine 3; DIGEST_LENGTH]; diff --git a/triton-vm/src/table/processor_table.rs b/triton-vm/src/table/processor_table.rs index 219b54ff..373675aa 100644 --- a/triton-vm/src/table/processor_table.rs +++ b/triton-vm/src/table/processor_table.rs @@ -126,11 +126,14 @@ impl ProcessorTable { // Input table if let Some(prev_row) = previous_row { - if prev_row[CI.base_table_index()] == Instruction::ReadIo.opcode_b() { - let input_symbol = current_row[ST0.base_table_index()]; - input_table_running_evaluation = input_table_running_evaluation - * challenges[StandardInputIndeterminate] - + input_symbol; + if let Some(Instruction::ReadIo(st)) = Self::instruction_from_row(prev_row) { + for i in (0..st.index()).rev() { + let input_symbol_column = Self::op_stack_column_by_index(i as usize); + let input_symbol = current_row[input_symbol_column.base_table_index()]; + input_table_running_evaluation = input_table_running_evaluation + * challenges[StandardInputIndeterminate] + + input_symbol; + } } } @@ -2256,7 +2259,7 @@ impl ExtProcessorTable { XxMul => ExtProcessorTable::instruction_xxmul(circuit_builder), XInvert => ExtProcessorTable::instruction_xinv(circuit_builder), XbMul => ExtProcessorTable::instruction_xbmul(circuit_builder), - ReadIo => ExtProcessorTable::instruction_read_io(circuit_builder), + ReadIo(_) => ExtProcessorTable::instruction_read_io(circuit_builder), WriteIo => ExtProcessorTable::instruction_write_io(circuit_builder), } } @@ -2299,9 +2302,9 @@ impl ExtProcessorTable { circuit_builder.input(NextExtRow(col.master_ext_table_index())) }; - let read_io_deselector = - Self::instruction_deselector_current_row(circuit_builder, Instruction::ReadIo); - let read_io_selector = curr_base_row(CI) - constant(Instruction::ReadIo.opcode()); + let read_io = Instruction::ReadIo(Default::default()); + let read_io_deselector = Self::instruction_deselector_current_row(circuit_builder, read_io); + let read_io_selector = curr_base_row(CI) - constant(read_io.opcode()); let running_evaluation_updates = next_ext_row(InputTableEvalArg) - challenge(StandardInputIndeterminate) * curr_ext_row(InputTableEvalArg) diff --git a/triton-vm/src/vm.rs b/triton-vm/src/vm.rs index a6aab26c..c15ba73f 100644 --- a/triton-vm/src/vm.rs +++ b/triton-vm/src/vm.rs @@ -143,7 +143,7 @@ impl<'pgm> VMState<'pgm> { }; match current_instruction { - Pop(arg) | Divine(arg) | Dup(arg) | Swap(arg) => { + Pop(arg) | Divine(arg) | Dup(arg) | Swap(arg) | ReadIo(arg) => { let arg_val: u64 = arg.into(); hvs[0] = BFieldElement::new(arg_val % 2); hvs[1] = BFieldElement::new((arg_val >> 1) % 2); @@ -238,7 +238,7 @@ impl<'pgm> VMState<'pgm> { XInvert => self.x_invert()?, XbMul => self.xb_mul()?, WriteIo => self.write_io()?, - ReadIo => self.read_io()?, + ReadIo(n) => self.read_io(n)?, }; let op_stack_calls = self.stop_recording_op_stack_calls(); co_processor_calls.extend(op_stack_calls); @@ -706,13 +706,19 @@ impl<'pgm> VMState<'pgm> { Ok(vec![]) } - fn read_io(&mut self) -> Result> { - let read_element = self.public_input.pop_front().ok_or(anyhow!( - "Instruction `read_io`: public input buffer is empty." - ))?; - self.op_stack.push(read_element); + fn read_io(&mut self, n: OpStackElement) -> Result> { + if Instruction::ReadIo(n).has_illegal_argument() { + bail!(IllegalReadIo(n.into())); + } - self.instruction_pointer += 1; + for i in 0..n.into() { + let read_element = self.public_input.pop_front().ok_or(anyhow!( + "Instruction `read_io {n}`: public input buffer is empty after {i}." + ))?; + self.op_stack.push(read_element); + } + + self.instruction_pointer += 2; Ok(vec![]) } From 611d3139be5c5a4ab68eb3176c64e26ada9d0542 Mon Sep 17 00:00:00 2001 From: Jan Ferdinand Sauer Date: Mon, 6 Nov 2023 14:44:00 +0100 Subject: [PATCH 2/3] update constraints for new instruction `read_io n` --- triton-vm/src/table/processor_table.rs | 253 +++++++++++++++++++------ 1 file changed, 193 insertions(+), 60 deletions(-) diff --git a/triton-vm/src/table/processor_table.rs b/triton-vm/src/table/processor_table.rs index 373675aa..95e771a2 100644 --- a/triton-vm/src/table/processor_table.rs +++ b/triton-vm/src/table/processor_table.rs @@ -124,9 +124,10 @@ impl ProcessorTable { for row_idx in 0..base_table.nrows() { let current_row = base_table.row(row_idx); - // Input table + // Standard Input & Output if let Some(prev_row) = previous_row { - if let Some(Instruction::ReadIo(st)) = Self::instruction_from_row(prev_row) { + let previous_instruction = Self::instruction_from_row(prev_row); + if let Some(Instruction::ReadIo(st)) = previous_instruction { for i in (0..st.index()).rev() { let input_symbol_column = Self::op_stack_column_by_index(i as usize); let input_symbol = current_row[input_symbol_column.base_table_index()]; @@ -135,14 +136,12 @@ impl ProcessorTable { + input_symbol; } } - } - - // Output table - if current_row[CI.base_table_index()] == Instruction::WriteIo.opcode_b() { - let output_symbol = current_row[ST0.base_table_index()]; - output_table_running_evaluation = output_table_running_evaluation - * challenges[StandardOutputIndeterminate] - + output_symbol; + if Some(Instruction::WriteIo) == previous_instruction { + let output_symbol = prev_row[ST0.base_table_index()]; + output_table_running_evaluation = output_table_running_evaluation + * challenges[StandardOutputIndeterminate] + + output_symbol; + } } // Program table @@ -768,6 +767,7 @@ impl ExtProcessorTable { Self::instruction_group_keep_jump_stack(circuit_builder), Self::instruction_group_keep_op_stack(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat(); @@ -840,6 +840,15 @@ impl ExtProcessorTable { ] } + fn instruction_group_no_io( + circuit_builder: &ConstraintCircuitBuilder, + ) -> Vec> { + vec![ + Self::running_evaluation_for_standard_input_remains_unchanged(circuit_builder), + Self::running_evaluation_for_standard_output_remains_unchanged(circuit_builder), + ] + } + fn instruction_group_op_stack_remains_and_top_three_elements_unconstrained( circuit_builder: &ConstraintCircuitBuilder, ) -> Vec> { @@ -1216,6 +1225,7 @@ impl ExtProcessorTable { Self::stack_shrinks_by_any_of(circuit_builder, &[1, 2, 3, 4, 5]), stack_does_not_shrink_by_too_much, Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1236,6 +1246,7 @@ impl ExtProcessorTable { Self::instruction_group_grow_op_stack(circuit_builder), Self::instruction_group_step_2(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1255,6 +1266,7 @@ impl ExtProcessorTable { Self::stack_grows_by_any_of(circuit_builder, &[1, 2, 3, 4, 5]), stack_does_not_grow_by_too_much, Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1294,6 +1306,7 @@ impl ExtProcessorTable { Self::instruction_group_step_2(circuit_builder), Self::instruction_group_grow_op_stack(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1371,6 +1384,7 @@ impl ExtProcessorTable { Self::instruction_group_decompose_arg(circuit_builder), Self::instruction_group_step_2(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1382,6 +1396,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_keep_op_stack(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1441,6 +1456,7 @@ impl ExtProcessorTable { Self::instruction_group_keep_jump_stack(circuit_builder), Self::instruction_group_shrink_op_stack(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1504,6 +1520,7 @@ impl ExtProcessorTable { specific_constraints, Self::instruction_group_keep_op_stack(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1530,6 +1547,7 @@ impl ExtProcessorTable { specific_constraints, Self::instruction_group_keep_op_stack(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1552,6 +1570,7 @@ impl ExtProcessorTable { Self::instruction_group_keep_jump_stack(circuit_builder), Self::instruction_group_keep_op_stack(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1573,6 +1592,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_shrink_op_stack(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1596,6 +1616,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_keep_op_stack(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1621,6 +1642,7 @@ impl ExtProcessorTable { specific_constraints, Self::instruction_group_step_1(circuit_builder), Self::instruction_group_grow_op_stack(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1646,6 +1668,7 @@ impl ExtProcessorTable { specific_constraints, Self::instruction_group_step_1(circuit_builder), Self::instruction_group_shrink_op_stack(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1677,6 +1700,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), op_stack_shrinks_by_5_and_top_5_unconstrained, Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1742,6 +1766,7 @@ impl ExtProcessorTable { op_stack_grows_by_5_and_top_11_elements_unconstrained, Self::instruction_group_step_1(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1765,6 +1790,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_keep_op_stack(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1776,6 +1802,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_keep_op_stack(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1787,6 +1814,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::constraints_for_shrinking_stack_by(circuit_builder, 10), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1798,6 +1826,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::constraints_for_growing_stack_by(circuit_builder, 10), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1819,6 +1848,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_binop(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1840,6 +1870,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_binop(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1862,6 +1893,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_unop(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1903,6 +1935,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_binop(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1950,6 +1983,7 @@ impl ExtProcessorTable { ), Self::instruction_group_step_1(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1961,6 +1995,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_binop(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1972,6 +2007,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_binop(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1983,6 +2019,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_binop(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -1994,6 +2031,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_unop(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -2005,6 +2043,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_binop(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -2036,6 +2075,7 @@ impl ExtProcessorTable { circuit_builder, ), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -2047,6 +2087,7 @@ impl ExtProcessorTable { Self::instruction_group_step_1(circuit_builder), Self::instruction_group_unop(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -2075,6 +2116,7 @@ impl ExtProcessorTable { Self::constraints_for_shrinking_stack_by_3_and_top_3_unconstrained(circuit_builder), Self::instruction_group_step_1(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -2114,6 +2156,7 @@ impl ExtProcessorTable { Self::constraints_for_shrinking_stack_by_3_and_top_3_unconstrained(circuit_builder), Self::instruction_group_step_1(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -2159,6 +2202,7 @@ impl ExtProcessorTable { ), Self::instruction_group_step_1(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -2192,6 +2236,7 @@ impl ExtProcessorTable { ), Self::instruction_group_step_1(circuit_builder), Self::instruction_group_keep_ram(circuit_builder), + Self::instruction_group_no_io(circuit_builder), ] .concat() } @@ -2199,10 +2244,27 @@ impl ExtProcessorTable { fn instruction_read_io( circuit_builder: &ConstraintCircuitBuilder, ) -> Vec> { + let dont_read_0_elements = Self::indicator_polynomial(circuit_builder, 0); + let dont_read_too_many_elements = (6..OpStackElement::COUNT) + .map(|idx| Self::indicator_polynomial(circuit_builder, idx)) + .collect_vec(); + + let constraint_groups_for_legal_arguments = (1..=5) + .map(|n| Self::grow_stack_by_n_and_read_n_symbols_from_input(circuit_builder, n)) + .collect_vec(); + let read_any_of_1_through_5_elements = Self::combine_mutually_exclusive_constraint_groups( + circuit_builder, + constraint_groups_for_legal_arguments, + ); + [ - Self::instruction_group_step_1(circuit_builder), - Self::instruction_group_grow_op_stack(circuit_builder), + Self::instruction_group_step_2(circuit_builder), + Self::instruction_group_decompose_arg(circuit_builder), + vec![dont_read_0_elements], + read_any_of_1_through_5_elements, + dont_read_too_many_elements, Self::instruction_group_keep_ram(circuit_builder), + vec![Self::running_evaluation_for_standard_output_remains_unchanged(circuit_builder)], ] .concat() } @@ -2210,10 +2272,27 @@ impl ExtProcessorTable { fn instruction_write_io( circuit_builder: &ConstraintCircuitBuilder, ) -> Vec> { + let challenge = |c: ChallengeId| circuit_builder.challenge(c); + let curr_base_row = |col: ProcessorBaseTableColumn| { + circuit_builder.input(CurrentBaseRow(col.master_base_table_index())) + }; + let curr_ext_row = |col: ProcessorExtTableColumn| { + circuit_builder.input(CurrentExtRow(col.master_ext_table_index())) + }; + let next_ext_row = |col: ProcessorExtTableColumn| { + circuit_builder.input(NextExtRow(col.master_ext_table_index())) + }; + + let running_evaluation_accumulates_one_factor = next_ext_row(OutputTableEvalArg) + - challenge(StandardOutputIndeterminate) * curr_ext_row(OutputTableEvalArg) + - curr_base_row(ST0); + [ Self::instruction_group_step_1(circuit_builder), Self::instruction_group_shrink_op_stack(circuit_builder), + vec![running_evaluation_accumulates_one_factor], Self::instruction_group_keep_ram(circuit_builder), + vec![Self::running_evaluation_for_standard_input_remains_unchanged(circuit_builder)], ] .concat() } @@ -2284,17 +2363,22 @@ impl ExtProcessorTable { - next_base_row(ClockJumpDifferenceLookupMultiplicity) } - fn running_evaluation_for_standard_input_updates_correctly( + fn running_evaluation_for_standard_input_remains_unchanged( circuit_builder: &ConstraintCircuitBuilder, ) -> ConstraintCircuitMonad { - let constant = |c: u32| circuit_builder.b_constant(c.into()); - let challenge = |c: ChallengeId| circuit_builder.challenge(c); - let curr_base_row = |col: ProcessorBaseTableColumn| { - circuit_builder.input(CurrentBaseRow(col.master_base_table_index())) + let curr_ext_row = |col: ProcessorExtTableColumn| { + circuit_builder.input(CurrentExtRow(col.master_ext_table_index())) }; - let next_base_row = |col: ProcessorBaseTableColumn| { - circuit_builder.input(NextBaseRow(col.master_base_table_index())) + let next_ext_row = |col: ProcessorExtTableColumn| { + circuit_builder.input(NextExtRow(col.master_ext_table_index())) }; + + next_ext_row(InputTableEvalArg) - curr_ext_row(InputTableEvalArg) + } + + fn running_evaluation_for_standard_output_remains_unchanged( + circuit_builder: &ConstraintCircuitBuilder, + ) -> ConstraintCircuitMonad { let curr_ext_row = |col: ProcessorExtTableColumn| { circuit_builder.input(CurrentExtRow(col.master_ext_table_index())) }; @@ -2302,25 +2386,29 @@ impl ExtProcessorTable { circuit_builder.input(NextExtRow(col.master_ext_table_index())) }; - let read_io = Instruction::ReadIo(Default::default()); - let read_io_deselector = Self::instruction_deselector_current_row(circuit_builder, read_io); - let read_io_selector = curr_base_row(CI) - constant(read_io.opcode()); - - let running_evaluation_updates = next_ext_row(InputTableEvalArg) - - challenge(StandardInputIndeterminate) * curr_ext_row(InputTableEvalArg) - - next_base_row(ST0); - let running_evaluation_remains = - next_ext_row(InputTableEvalArg) - curr_ext_row(InputTableEvalArg); + next_ext_row(OutputTableEvalArg) - curr_ext_row(OutputTableEvalArg) + } - read_io_selector * running_evaluation_remains - + read_io_deselector * running_evaluation_updates + fn grow_stack_by_n_and_read_n_symbols_from_input( + circuit_builder: &ConstraintCircuitBuilder, + n: usize, + ) -> Vec> { + let running_evaluation_update = + Self::running_evaluation_standard_input_accumulates_n_symbols(circuit_builder, n); + let conditional_running_evaluation_update = + running_evaluation_update * Self::indicator_polynomial(circuit_builder, n); + + let mut constraints = + Self::conditional_constraints_for_growing_stack_by(circuit_builder, n); + constraints.push(conditional_running_evaluation_update); + constraints } - fn log_derivative_for_instruction_lookup_updates_correctly( + fn running_evaluation_standard_input_accumulates_n_symbols( circuit_builder: &ConstraintCircuitBuilder, + n: usize, ) -> ConstraintCircuitMonad { - let one = || circuit_builder.b_constant(1_u32.into()); - let challenge = |c: ChallengeId| circuit_builder.challenge(c); + let indeterminate = || circuit_builder.challenge(StandardInputIndeterminate); let next_base_row = |col: ProcessorBaseTableColumn| { circuit_builder.input(NextBaseRow(col.master_base_table_index())) }; @@ -2331,24 +2419,19 @@ impl ExtProcessorTable { circuit_builder.input(NextExtRow(col.master_ext_table_index())) }; - let compressed_row = challenge(ProgramAddressWeight) * next_base_row(IP) - + challenge(ProgramInstructionWeight) * next_base_row(CI) - + challenge(ProgramNextInstructionWeight) * next_base_row(NIA); - let log_derivative_updates = (next_ext_row(InstructionLookupClientLogDerivative) - - curr_ext_row(InstructionLookupClientLogDerivative)) - * (challenge(InstructionLookupIndeterminate) - compressed_row) - - one(); - let log_derivative_remains = next_ext_row(InstructionLookupClientLogDerivative) - - curr_ext_row(InstructionLookupClientLogDerivative); - - (one() - next_base_row(IsPadding)) * log_derivative_updates - + next_base_row(IsPadding) * log_derivative_remains + let mut running_evaluation = curr_ext_row(InputTableEvalArg); + for i in (0..n).rev() { + let stack_element = ProcessorTable::op_stack_column_by_index(i); + running_evaluation = + indeterminate() * running_evaluation + next_base_row(stack_element); + } + next_ext_row(InputTableEvalArg) - running_evaluation } - fn running_evaluation_for_standard_output_updates_correctly( + fn log_derivative_for_instruction_lookup_updates_correctly( circuit_builder: &ConstraintCircuitBuilder, ) -> ConstraintCircuitMonad { - let constant = |c: u32| circuit_builder.b_constant(c.into()); + let one = || circuit_builder.b_constant(1_u32.into()); let challenge = |c: ChallengeId| circuit_builder.challenge(c); let next_base_row = |col: ProcessorBaseTableColumn| { circuit_builder.input(NextBaseRow(col.master_base_table_index())) @@ -2360,18 +2443,18 @@ impl ExtProcessorTable { circuit_builder.input(NextExtRow(col.master_ext_table_index())) }; - let write_io_deselector = - Self::instruction_deselector_next_row(circuit_builder, Instruction::WriteIo); - let write_io_selector = next_base_row(CI) - constant(Instruction::WriteIo.opcode()); - - let running_evaluation_updates = next_ext_row(OutputTableEvalArg) - - challenge(StandardOutputIndeterminate) * curr_ext_row(OutputTableEvalArg) - - next_base_row(ST0); - let running_evaluation_remains = - next_ext_row(OutputTableEvalArg) - curr_ext_row(OutputTableEvalArg); + let compressed_row = challenge(ProgramAddressWeight) * next_base_row(IP) + + challenge(ProgramInstructionWeight) * next_base_row(CI) + + challenge(ProgramNextInstructionWeight) * next_base_row(NIA); + let log_derivative_updates = (next_ext_row(InstructionLookupClientLogDerivative) + - curr_ext_row(InstructionLookupClientLogDerivative)) + * (challenge(InstructionLookupIndeterminate) - compressed_row) + - one(); + let log_derivative_remains = next_ext_row(InstructionLookupClientLogDerivative) + - curr_ext_row(InstructionLookupClientLogDerivative); - write_io_selector * running_evaluation_remains - + write_io_deselector * running_evaluation_updates + (one() - next_base_row(IsPadding)) * log_derivative_updates + + next_base_row(IsPadding) * log_derivative_remains } fn constraints_for_shrinking_stack_by_3_and_top_3_unconstrained( @@ -3026,9 +3109,7 @@ impl ExtProcessorTable { let table_linking_constraints = vec![ Self::log_derivative_accumulates_clk_next(circuit_builder), - Self::running_evaluation_for_standard_input_updates_correctly(circuit_builder), Self::log_derivative_for_instruction_lookup_updates_correctly(circuit_builder), - Self::running_evaluation_for_standard_output_updates_correctly(circuit_builder), Self::running_product_for_ram_table_updates_correctly(circuit_builder), Self::running_product_for_jump_stack_table_updates_correctly(circuit_builder), Self::running_evaluation_hash_input_updates_correctly(circuit_builder), @@ -3829,6 +3910,58 @@ pub(crate) mod tests { ); } + #[test] + #[should_panic(expected = "at least 1, at most 5")] + fn transition_constraints_for_instruction_read_io_0() { + transition_constraints_for_instruction_read_io_n(0); + } + + #[proptest(cases = 20)] + fn transition_constraints_for_instruction_read_io_n_in_range( + #[strategy(1..=5_usize)] n: usize, + ) { + transition_constraints_for_instruction_read_io_n(n); + } + + #[proptest(cases = 20)] + #[should_panic(expected = "at least 1, at most 5")] + fn transition_constraints_for_instruction_read_io_n_too_large( + #[strategy(6..OpStackElement::COUNT)] n: usize, + ) { + transition_constraints_for_instruction_read_io_n(n); + } + + fn transition_constraints_for_instruction_read_io_n(n: usize) { + let stack_element = n.try_into().unwrap(); + + let instructions = [ReadIo(stack_element), Halt]; + let instructions = instructions.map(LabelledInstruction::Instruction).to_vec(); + + let program_and_input = ProgramAndInput { + program: Program::new(&instructions), + public_input: (1..=16).collect_vec(), + non_determinism: [].into(), + }; + let test_rows = [test_row_from_program_with_input(program_and_input, 0)]; + + test_constraints_for_rows_with_debug_info( + ReadIo(stack_element), + &test_rows, + &[ST0, ST1, ST2], + &[ST0, ST1, ST2], + ); + } + + #[test] + fn transition_constraints_for_instruction_write_io() { + let programs = [ + triton_program!(push 17 write_io halt), + triton_program!(push 42 write_io halt), + ]; + let test_rows = programs.map(|program| test_row_from_program(program, 1)); + test_constraints_for_rows_with_debug_info(WriteIo, &test_rows, &[ST0, ST1], &[ST0, ST1]); + } + #[test] fn instruction_deselector_gives_0_for_all_other_instructions() { let circuit_builder = ConstraintCircuitBuilder::new(); From fd77762a78aa401468531aa0c173b9dff2eabfa3 Mon Sep 17 00:00:00 2001 From: Jan Ferdinand Sauer Date: Mon, 6 Nov 2023 15:24:29 +0100 Subject: [PATCH 3/3] use new `read_io n` syntax in all test & example programs --- triton-vm/src/example_programs.rs | 15 +++++------ triton-vm/src/lib.rs | 8 +++--- triton-vm/src/stark.rs | 2 +- triton-vm/src/vm.rs | 45 +++++++++++++++---------------- 4 files changed, 34 insertions(+), 36 deletions(-) diff --git a/triton-vm/src/example_programs.rs b/triton-vm/src/example_programs.rs index 1d24c2d3..13e8658b 100644 --- a/triton-vm/src/example_programs.rs +++ b/triton-vm/src/example_programs.rs @@ -20,7 +20,7 @@ fn fibonacci_sequence() -> Program { // initialize stack: ⊥ 0 1 i push 0 push 1 - read_io + read_io 1 // is any looping necessary? dup 0 @@ -51,8 +51,7 @@ fn fibonacci_sequence() -> Program { fn greatest_common_divisor() -> Program { triton_program!( - read_io // _ a - read_io // _ a b + read_io 2 // _ a b dup 1 // _ a b a dup 1 // _ a b a b lt // _ a b b Program { /// - output: Result<(), VMFail> fn merkle_tree_authentication_path_verify() -> Program { triton_program!( - read_io // number of authentication paths to test + read_io 1 // number of authentication paths to test // stack: [num] mt_ap_verify: // proper program starts here push 0 swap 1 write_mem pop 1 // store number of APs at RAM address 0 // stack: [] - read_io read_io read_io read_io read_io // read Merkle root + read_io 5 // read Merkle root // stack: [r4 r3 r2 r1 r0] call check_aps pop 5 // leave clean stack: Merkle root @@ -148,8 +147,8 @@ fn merkle_tree_authentication_path_verify() -> Program { // stack before: [*] // stack after: [* idx l4 l3 l2 l1 l0] get_idx_and_leaf: - read_io // read node index - read_io read_io read_io read_io read_io // read leaf's value + read_io 1 // read node index + read_io 5 // read leaf's value return // subroutine: go up tree @@ -228,7 +227,7 @@ fn verify_sudoku() -> Program { // Applies the mapping from legal Sudoku digits to distinct primes. read1: // _ - read_io // _ d + read_io 1 // _ d read_mem // _ d p swap 1 // _ p d pop 1 // _ p diff --git a/triton-vm/src/lib.rs b/triton-vm/src/lib.rs index 340552fa..c6383035 100644 --- a/triton-vm/src/lib.rs +++ b/triton-vm/src/lib.rs @@ -31,7 +31,7 @@ //! ``` //! # use triton_vm::*; //! let factorial_program = triton_program!( -//! read_io // n +//! read_io 1 // n //! push 1 // n 1 //! call factorial // 0 n! //! write_io // 0 @@ -82,7 +82,7 @@ //! ``` //! # use triton_vm::*; //! let sum_of_squares_program = triton_program!( -//! read_io // n +//! read_io 1 // n //! call sum_of_squares_secret_in // n sum_1 //! call sum_of_squares_ram // n sum_1 sum_2 //! add // n sum_1+sum_2 @@ -168,7 +168,7 @@ pub mod vm; /// ``` /// # use triton_vm::triton_program; /// let program = triton_program!( -/// read_io push 5 mul +/// read_io 1 push 5 mul /// call check_eq_15 /// push 1 write_io /// halt @@ -555,7 +555,7 @@ mod tests { push 03612858832443241113 push 12064501419749299924 assert_vector - read_io read_io read_io read_io read_io + read_io 5 halt ); diff --git a/triton-vm/src/stark.rs b/triton-vm/src/stark.rs index 7cee9f14..a595af76 100644 --- a/triton-vm/src/stark.rs +++ b/triton-vm/src/stark.rs @@ -1414,7 +1414,7 @@ pub(crate) mod tests { #[test] fn check_io_terminals() { let read_nop_program = triton_program!( - read_io read_io read_io nop nop write_io push 17 write_io halt + read_io 3 nop nop write_io push 17 write_io halt ); let public_input = vec![3, 5, 7].into(); let (_, claim, _, master_ext_table, all_challenges) = diff --git a/triton-vm/src/vm.rs b/triton-vm/src/vm.rs index c15ba73f..937b088e 100644 --- a/triton-vm/src/vm.rs +++ b/triton-vm/src/vm.rs @@ -1089,7 +1089,7 @@ pub(crate) mod tests { push 0 // filler to keep the OpStack large enough throughout the program push 0 push 0 push 1 push 2 push 3 hash - read_io eq assert halt + read_io 1 eq assert halt ); let hash_input = [3, 2, 1, 0, 0, 0, 0, 0, 0, 0].map(BFieldElement::new); let digest = Tip5::hash_10(&hash_input).map(|e| e.value()); @@ -1220,7 +1220,7 @@ pub(crate) mod tests { let program = triton_program!( push {st4} push {st3} push {st2} push {st1} push {st0} - read_io read_io read_io read_io read_io assert_vector halt + read_io 5 assert_vector halt ); ProgramAndInput { @@ -1294,7 +1294,7 @@ pub(crate) mod tests { } let output_equality_assertions = (0..RATE) - .flat_map(|_| triton_asm![read_io eq assert]) + .flat_map(|_| triton_asm![read_io 1 eq assert]) .collect_vec(); let [st0, st1, st2, st3, st4, st5, st6, st7, st8, st9] = sponge_input; @@ -1329,7 +1329,8 @@ pub(crate) mod tests { let hi = st0 >> 32; let lo = st0 & 0xffff_ffff; - let program = triton_program!(push {st0} split read_io eq assert read_io eq assert halt); + let program = + triton_program!(push {st0} split read_io 1 eq assert read_io 1 eq assert halt); ProgramAndInput { program, public_input: vec![lo, hi], @@ -1339,7 +1340,7 @@ pub(crate) mod tests { pub(crate) fn test_program_for_eq() -> ProgramAndInput { ProgramAndInput { - program: triton_program!(read_io divine 1 eq assert halt), + program: triton_program!(read_io 1 divine 1 eq assert halt), public_input: vec![42], non_determinism: vec![42].into(), } @@ -1350,7 +1351,7 @@ pub(crate) mod tests { let st0 = rng.next_u64() % BFieldElement::P; let program = - triton_program!(push {st0} dup 0 read_io eq assert dup 0 divine 1 eq assert halt); + triton_program!(push {st0} dup 0 read_io 1 eq assert dup 0 divine 1 eq assert halt); ProgramAndInput { program, public_input: vec![st0], @@ -1373,7 +1374,7 @@ pub(crate) mod tests { let st0_shift_right = st0 >> 1; let program = triton_program!( - push {st0} call lsb read_io eq assert read_io eq assert halt + push {st0} call lsb read_io 1 eq assert read_io 1 eq assert halt lsb: push 2 swap 1 div_mod return ); @@ -1412,8 +1413,8 @@ pub(crate) mod tests { }; let program = triton_program!( - push {st1_0} push {st0_0} lt read_io eq assert - push {st1_1} push {st0_1} lt read_io eq assert halt + push {st1_0} push {st0_0} lt read_io 1 eq assert + push {st1_1} push {st0_1} lt read_io 1 eq assert halt ); ProgramAndInput { program, @@ -1440,8 +1441,8 @@ pub(crate) mod tests { let result_1 = st0_1.bitand(st1_1); let program = triton_program!( - push {st1_0} push {st0_0} and read_io eq assert - push {st1_1} push {st0_1} and read_io eq assert halt + push {st1_0} push {st0_0} and read_io 1 eq assert + push {st1_1} push {st0_1} and read_io 1 eq assert halt ); ProgramAndInput { program, @@ -1468,8 +1469,8 @@ pub(crate) mod tests { let result_1 = st0_1.bitxor(st1_1); let program = triton_program!( - push {st1_0} push {st0_0} xor read_io eq assert - push {st1_1} push {st0_1} xor read_io eq assert halt + push {st1_0} push {st0_0} xor read_io 1 eq assert + push {st1_1} push {st0_1} xor read_io 1 eq assert halt ); ProgramAndInput { program, @@ -1505,8 +1506,8 @@ pub(crate) mod tests { let l2f_1 = st0_1.ilog2(); let program = triton_program!( - push {st0_0} log_2_floor read_io eq assert - push {st0_1} log_2_floor read_io eq assert halt + push {st0_0} log_2_floor read_io 1 eq assert + push {st0_1} log_2_floor read_io 1 eq assert halt ); ProgramAndInput { program, @@ -1555,8 +1556,8 @@ pub(crate) mod tests { let result_1 = base_1.mod_pow_u32(exp_1).value(); let program = triton_program!( - push {exp_0} push {base_0} pow read_io eq assert - push {exp_1} push {base_1} pow read_io eq assert halt + push {exp_0} push {base_0} pow read_io 1 eq assert + push {exp_1} push {base_1} pow read_io 1 eq assert halt ); ProgramAndInput { program, @@ -1578,7 +1579,7 @@ pub(crate) mod tests { let remainder = numerator % denominator; let program = triton_program!( - push {denominator} push {numerator} div_mod read_io eq assert read_io eq assert halt + push {denominator} push {numerator} div_mod read_io 1 eq assert read_io 1 eq assert halt ); ProgramAndInput { program, @@ -1599,7 +1600,7 @@ pub(crate) mod tests { let mut rng = ThreadRng::default(); let st0 = rng.next_u32(); let pop_count = st0.count_ones(); - let program = triton_program!(push {st0} pop_count read_io eq assert halt); + let program = triton_program!(push {st0} pop_count read_io 1 eq assert halt); ProgramAndInput { program, public_input: vec![pop_count.into()], @@ -1754,7 +1755,7 @@ pub(crate) mod tests { pub(crate) fn test_program_for_read_io_write_io() -> ProgramAndInput { let program = triton_program!( - read_io assert read_io read_io dup 1 dup 1 add write_io mul write_io halt + read_io 1 assert read_io 2 dup 1 dup 1 add write_io mul write_io halt ); ProgramAndInput { program, @@ -2078,9 +2079,7 @@ pub(crate) mod tests { fn run_tvm_get_colinear_y() { // see also: get_colinear_y in src/shared_math/polynomial.rs let get_colinear_y_program = triton_program!( - read_io // p2_x - read_io read_io // p1_y p1_x - read_io read_io // p0_y p0_x + read_io 5 // p0 p1 p2_x swap 3 push -1 mul dup 1 add // dy = p0_y - p1_y dup 3 push -1 mul dup 5 add mul // dy·(p2_x - p0_x) dup 3 dup 3 push -1 mul add // dx = p0_x - p1_x