sp1_core_machine/syscall/instructions/mod.rs
1use std::marker::PhantomData;
2
3use columns::{NUM_SYSCALL_INSTR_COLS_SUPERVISOR, NUM_SYSCALL_INSTR_COLS_USER};
4use slop_air::BaseAir;
5
6use crate::TrustMode;
7
8pub mod air;
9pub mod columns;
10pub mod trace;
11
12#[derive(Default)]
13pub struct SyscallInstrsChip<M: TrustMode> {
14 pub _phantom: PhantomData<M>,
15}
16
17impl<F, M: TrustMode> BaseAir<F> for SyscallInstrsChip<M> {
18 fn width(&self) -> usize {
19 if M::IS_TRUSTED {
20 NUM_SYSCALL_INSTR_COLS_SUPERVISOR
21 } else {
22 NUM_SYSCALL_INSTR_COLS_USER
23 }
24 }
25}
26
27// #[cfg(test)]
28// mod tests {
29// use std::borrow::BorrowMut;
30
31// use sp1_primitives::SP1Field;
32// use slop_algebra::AbstractField;
33// use slop_matrix::dense::RowMajorMatrix;
34// use sp1_core_executor::{ExecutionRecord, Instruction, Opcode, Program};
35// use sp1_hypercube::{
36// air::MachineAir, koala_bear_poseidon2::SP1InnerPcs, chip_name, CpuProver,
37// MachineProver, Val,
38// };
39// use sp1_zkvm::syscalls::{COMMIT, COMMIT_DEFERRED_PROOFS, HALT, SHA_EXTEND};
40
41// use crate::{
42// cpu::{columns::CpuCols, CpuChip},
43// io::SP1Stdin,
44// riscv::RiscvAir,
45// syscall::instructions::{columns::SyscallInstrColumns, SyscallInstrsChip},
46// utils::run_malicious_test,
47// };
48
49// #[test]
50// fn test_malicious_next_pc() {
51// struct TestCase {
52// program: Vec<Instruction>,
53// incorrect_next_pc: u64,
54// }
55
56// let test_cases = vec![
57// TestCase {
58// program: vec![
59// Instruction::new(Opcode::ADD, 5, 0, HALT, false, true), // Set the syscall
60// code in register x5. Instruction::new(Opcode::ECALL, 5, 10, 11, false,
61// false), // Call the syscall. Instruction::new(Opcode::ADD, 30, 0, 100, false,
62// true), ],
63// incorrect_next_pc: 8, // The correct next_pc is 0.
64// },
65// TestCase {
66// program: vec![
67// Instruction::new(Opcode::ADD, 5, 0, SHA_EXTEND, false, true), // Set the
68// syscall code in register x5. Instruction::new(Opcode::ADD, 10, 0, 40, false,
69// true), // Set the syscall arg1 to 40. Instruction::new(Opcode::ECALL, 5, 10,
70// 11, false, false), // Call the syscall. Instruction::new(Opcode::ADD, 30, 0,
71// 100, false, true), ],
72// incorrect_next_pc: 0, // The correct next_pc is 12.
73// },
74// ];
75
76// for test_case in test_cases {
77// let program = Program::new(test_case.program, 0, 0);
78// let stdin = SP1Stdin::new();
79
80// type P = CpuProver<SP1InnerPcs, RiscvAir<SP1Field>>;
81
82// let malicious_trace_pv_generator =
83// move |prover: &P,
84// record: &mut ExecutionRecord|
85// -> Vec<(String, RowMajorMatrix<Val<SP1InnerPcs>>)> {
86// // Create a malicious record where the next pc is set to the incorrect value.
87// let mut malicious_record = record.clone();
88
89// // There can be multiple shards for programs with syscalls, so need to figure
90// out which // record is for a CPU shard.
91// if !malicious_record.cpu_events.is_empty() {
92// malicious_record.syscall_events[0].next_pc =
93// test_case.incorrect_next_pc; }
94
95// prover.generate_traces(&malicious_record)
96// };
97
98// let result =
99// run_malicious_test::<P>(program, stdin, Box::new(malicious_trace_pv_generator));
100// assert!(result.is_err() && result.unwrap_err().is_constraints_failing());
101// }
102// }
103
104// #[test]
105// fn test_malicious_extra_cycles() {
106// let instructions = vec![
107// Instruction::new(Opcode::ADD, 5, 0, SHA_EXTEND, false, true), // Set the syscall code
108// in register x5. Instruction::new(Opcode::ADD, 10, 0, 40, false, true), // Set the
109// syscall arg1 to 40. Instruction::new(Opcode::ECALL, 5, 10, 11, false, false), // Call
110// the syscall. Instruction::new(Opcode::ADD, 30, 20, 100, true, true),
111// ];
112// let program = Program::new(instructions, 0, 0);
113// let stdin = SP1Stdin::new();
114
115// type P = CpuProver<SP1InnerPcs, RiscvAir<SP1Field>>;
116
117// let malicious_trace_pv_generator =
118// |prover: &P,
119// record: &mut ExecutionRecord|
120// -> Vec<(String, RowMajorMatrix<Val<SP1InnerPcs>>)> {
121// let mut traces = prover.generate_traces(record);
122
123// let cpu_chip_name = chip_name!(CpuChip, SP1Field);
124// let syscall_chip_name = chip_name!(SyscallInstrsChip, SP1Field);
125
126// for (chip_name, trace) in traces.iter_mut() {
127// if *chip_name == cpu_chip_name {
128// let third_row = trace.row_mut(2);
129// let third_row: &mut CpuCols<SP1Field> = third_row.borrow_mut();
130// assert!(third_row.is_syscall == SP1Field::one());
131// third_row.num_extra_cycles = SP1Field::from_canonical_usize(8);
132// // Correct value is 48.
133
134// let fourth_row = trace.row_mut(3);
135// let fourth_row: &mut CpuCols<SP1Field> = fourth_row.borrow_mut();
136// fourth_row.clk_16bit_limb = SP1Field::from_canonical_usize(20);
137// // Correct value is 60.
138// }
139
140// if *chip_name == syscall_chip_name {
141// let first_row = trace.row_mut(0);
142// let first_row: &mut SyscallInstrColumns<SP1Field> =
143// first_row.borrow_mut(); first_row.num_extra_cycles =
144// SP1Field::from_canonical_usize(4); // Correct value is 48.
145// }
146// }
147
148// traces
149// };
150
151// let result =
152// run_malicious_test::<P>(program, stdin, Box::new(malicious_trace_pv_generator));
153// assert!(result.is_err() && result.unwrap_err().is_constraints_failing());
154// }
155
156// #[test]
157// fn test_malicious_commit() {
158// let instructions = vec![
159// Instruction::new(Opcode::ADD, 5, 0, COMMIT, false, true), // Set the syscall code in
160// register x5. Instruction::new(Opcode::ADD, 10, 0, 0, false, false), // Set the
161// syscall code in register x5. Instruction::new(Opcode::ADD, 11, 0, 40, false, true),
162// // Set the syscall arg1 to 40. Instruction::new(Opcode::ECALL, 5, 10, 11, false,
163// false), // Call the syscall. ];
164// let program = Program::new(instructions, 0, 0);
165// let stdin = SP1Stdin::new();
166
167// type P = CpuProver<SP1InnerPcs, RiscvAir<SP1Field>>;
168
169// let malicious_trace_pv_generator =
170// |prover: &P,
171// record: &mut ExecutionRecord|
172// -> Vec<(String, RowMajorMatrix<Val<SP1InnerPcs>>)> {
173// record.public_values.committed_value_digest[0] = 10; // The correct value is 40.
174// prover.generate_traces(record)
175// };
176
177// let result =
178// run_malicious_test::<P>(program, stdin, Box::new(malicious_trace_pv_generator));
179// assert!(result.is_err() && result.unwrap_err().is_constraints_failing());
180// }
181
182// #[test]
183// fn test_malicious_commit_deferred() {
184// let instructions = vec![
185// Instruction::new(Opcode::ADD, 5, 0, COMMIT_DEFERRED_PROOFS, false, true), // Set the
186// syscall code in register x5. Instruction::new(Opcode::ADD, 10, 0, 0, false, false),
187// // Set the syscall code in register x5. Instruction::new(Opcode::ADD, 11, 0, 40,
188// false, true), // Set the syscall arg1 to 40. Instruction::new(Opcode::ECALL, 5, 10,
189// 11, false, false), // Call the syscall. ];
190// let program = Program::new(instructions, 0, 0);
191// let stdin = SP1Stdin::new();
192
193// type P = CpuProver<SP1InnerPcs, RiscvAir<SP1Field>>;
194
195// let malicious_trace_pv_generator =
196// |prover: &P,
197// record: &mut ExecutionRecord|
198// -> Vec<(String, RowMajorMatrix<Val<SP1InnerPcs>>)> {
199// record.public_values.deferred_proofs_digest[0] = 10; // The correct value is 40.
200// prover.generate_traces(record)
201// };
202
203// let result =
204// run_malicious_test::<P>(program, stdin, Box::new(malicious_trace_pv_generator));
205// assert!(result.is_err() && result.unwrap_err().is_constraints_failing());
206// }
207// }