Skip to main content

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// }