1#![allow(
2 clippy::new_without_default,
3 clippy::field_reassign_with_default,
4 clippy::unnecessary_cast,
5 clippy::cast_abs_to_unsigned,
6 clippy::needless_range_loop,
7 clippy::type_complexity,
8 clippy::unnecessary_unwrap,
9 clippy::default_constructed_unit_structs,
10 clippy::box_default,
11 clippy::assign_op_pattern,
12 deprecated,
13 incomplete_features
14)]
15#![warn(unused_extern_crates)]
16#[macro_use]
17extern crate static_assertions;
18
19pub mod adapter;
20pub mod air;
21pub mod alu;
22pub mod bytes;
23pub mod control_flow;
24pub mod executor;
25pub mod global;
26pub mod io;
27pub mod memory;
28pub mod operations;
29pub mod program;
30pub mod range;
31pub mod riscv;
32pub mod syscall;
33pub mod utils;
34pub mod utype;
35
36use air::SP1CoreAirBuilder;
37use memory::MemoryAccessCols;
38use operations::{AddressSlicePageProtOperation, IsZeroOperation, TrapOperation};
39use program::instruction::InstructionCols;
40use slop_air::AirBuilder;
41use slop_algebra::AbstractField;
42pub use sp1_core_executor::{SupervisorMode, UserMode};
43use sp1_derive::AlignedBorrow;
44use std::{fmt::Debug, marker::PhantomData};
45use struct_reflection::{StructReflection, StructReflectionHelper};
46
47pub trait TrustMode: Send + Sync + 'static {
48 const IS_TRUSTED: bool;
49 type AdapterCols<T>: StructReflectionHelper;
50 type SyscallInstrCols<T>: StructReflectionHelper;
51 type SliceProtCols<T>: StructReflectionHelper;
52 type AluX0SelectorCols<T>: StructReflectionHelper;
53 type TrapCodeCols<T>: StructReflectionHelper;
54}
55
56#[derive(AlignedBorrow, Default, Clone, Copy)]
57#[repr(C)]
58pub struct EmptyCols<T>(PhantomData<T>);
62
63impl<T> StructReflection for EmptyCols<T> {
64 fn struct_reflection() -> Option<Vec<String>> {
65 None
66 }
67}
68
69impl TrustMode for SupervisorMode {
70 const IS_TRUSTED: bool = true;
71 type AdapterCols<T> = EmptyCols<T>;
72 type SyscallInstrCols<T> = EmptyCols<T>;
73 type SliceProtCols<T> = EmptyCols<T>;
74 type AluX0SelectorCols<T> = EmptyCols<T>;
75 type TrapCodeCols<T> = EmptyCols<T>;
76}
77
78#[derive(AlignedBorrow, Default, Debug, Clone, Copy, StructReflection)]
79#[repr(C)]
80pub struct UserModeReaderCols<T> {
81 pub is_trusted: T,
82}
83
84#[derive(AlignedBorrow, Default, Debug, Clone, Copy, StructReflection)]
85#[repr(C)]
86pub struct UserModeSyscallInstrCols<T> {
87 pub is_sig_return: IsZeroOperation<T>,
88 pub next_pc_record: MemoryAccessCols<T>,
89 pub trap_operation: TrapOperation<T>,
90 pub is_not_trap: IsZeroOperation<T>,
91 pub is_page_protect: IsZeroOperation<T>,
92 pub trap_code: T,
93 pub addresses: [[T; 3]; 3],
94}
95
96#[derive(AlignedBorrow, Default, Debug, Clone, Copy, StructReflection)]
100#[repr(C)]
101pub struct AluX0OpcodeSelectors<T> {
102 pub instr_type: T,
103 pub base_opcode: T,
104 pub funct3: T,
105 pub funct7: T,
106 pub is_add: T,
107 pub is_sub: T,
108 pub is_mul: T,
109 pub is_mulh: T,
110 pub is_mulhsu: T,
111 pub is_mulhu: T,
112 pub is_div: T,
113 pub is_divu: T,
114 pub is_rem: T,
115 pub is_remu: T,
116 pub is_sll: T,
117 pub is_srl: T,
118 pub is_sra: T,
119 pub is_xor: T,
120 pub is_or: T,
121 pub is_and: T,
122 pub is_slt: T,
123 pub is_sltu: T,
124 pub is_addi: T,
125 pub is_addw: T,
126 pub is_subw: T,
127 pub is_sllw: T,
128 pub is_srlw: T,
129 pub is_sraw: T,
130 pub is_mulw: T,
131 pub is_divw: T,
132 pub is_divuw: T,
133 pub is_remw: T,
134 pub is_remuw: T,
135}
136
137#[derive(AlignedBorrow, Default, Debug, Clone, Copy, StructReflection)]
138#[repr(C)]
139pub struct UserModeTrapCodeCols<T> {
140 pub trap_code: T,
141}
142
143impl TrustMode for UserMode {
144 const IS_TRUSTED: bool = false;
145 type AdapterCols<T> = UserModeReaderCols<T>;
146 type SyscallInstrCols<T> = UserModeSyscallInstrCols<T>;
147 type SliceProtCols<T> = AddressSlicePageProtOperation<T>;
148 type AluX0SelectorCols<T> = AluX0OpcodeSelectors<T>;
149 type TrapCodeCols<T> = UserModeTrapCodeCols<T>;
150}
151
152fn eval_untrusted_program<AB: SP1CoreAirBuilder>(
153 builder: &mut AB,
154 pc: [impl Into<AB::Expr>; 3],
155 instruction: InstructionCols<AB::Expr>,
156 instruction_field_consts: [AB::Expr; 4],
157 clk: [AB::Expr; 2],
158 is_real: AB::Expr,
159 adapter_cols: UserModeReaderCols<AB::Var>,
160) {
161 builder.send_instruction_fetch(
162 pc,
163 instruction,
164 instruction_field_consts,
165 clk,
166 is_real.clone() - adapter_cols.is_trusted,
167 );
168
169 let is_untrusted = is_real.clone() - adapter_cols.is_trusted;
170 builder.assert_bool(adapter_cols.is_trusted);
171 builder.assert_bool(is_untrusted.clone());
172
173 let public_values = builder.extract_public_values();
175 builder.when(is_untrusted.clone()).assert_one(public_values.is_untrusted_programs_enabled);
176}
177
178fn eval_alu_x0_selectors<AB: SP1CoreAirBuilder>(
186 builder: &mut AB,
187 selectors: AluX0OpcodeSelectors<AB::Var>,
188 imm_c: AB::Expr,
189 is_real: AB::Expr,
190) {
191 use rrs_lib::instruction_formats::{OPCODE_OP, OPCODE_OP_32, OPCODE_OP_IMM, OPCODE_OP_IMM_32};
192 use sp1_core_executor::InstructionType;
193
194 builder.assert_bool(selectors.is_add);
196 builder.assert_bool(selectors.is_sub);
197 builder.assert_bool(selectors.is_mul);
198 builder.assert_bool(selectors.is_mulh);
199 builder.assert_bool(selectors.is_mulhsu);
200 builder.assert_bool(selectors.is_mulhu);
201 builder.assert_bool(selectors.is_div);
202 builder.assert_bool(selectors.is_divu);
203 builder.assert_bool(selectors.is_rem);
204 builder.assert_bool(selectors.is_remu);
205 builder.assert_bool(selectors.is_sll);
206 builder.assert_bool(selectors.is_srl);
207 builder.assert_bool(selectors.is_sra);
208 builder.assert_bool(selectors.is_xor);
209 builder.assert_bool(selectors.is_or);
210 builder.assert_bool(selectors.is_and);
211 builder.assert_bool(selectors.is_slt);
212 builder.assert_bool(selectors.is_sltu);
213 builder.assert_bool(selectors.is_addi);
214 builder.assert_bool(selectors.is_addw);
215 builder.assert_bool(selectors.is_subw);
216 builder.assert_bool(selectors.is_sllw);
217 builder.assert_bool(selectors.is_srlw);
218 builder.assert_bool(selectors.is_sraw);
219 builder.assert_bool(selectors.is_mulw);
220 builder.assert_bool(selectors.is_divw);
221 builder.assert_bool(selectors.is_divuw);
222 builder.assert_bool(selectors.is_remw);
223 builder.assert_bool(selectors.is_remuw);
224
225 let selector_sum: AB::Expr = selectors.is_add
227 + selectors.is_sub
228 + selectors.is_mul
229 + selectors.is_mulh
230 + selectors.is_mulhsu
231 + selectors.is_mulhu
232 + selectors.is_div
233 + selectors.is_divu
234 + selectors.is_rem
235 + selectors.is_remu
236 + selectors.is_sll
237 + selectors.is_srl
238 + selectors.is_sra
239 + selectors.is_xor
240 + selectors.is_or
241 + selectors.is_and
242 + selectors.is_slt
243 + selectors.is_sltu
244 + selectors.is_addi
245 + selectors.is_addw
246 + selectors.is_subw
247 + selectors.is_sllw
248 + selectors.is_srlw
249 + selectors.is_sraw
250 + selectors.is_mulw
251 + selectors.is_divw
252 + selectors.is_divuw
253 + selectors.is_remw
254 + selectors.is_remuw;
255 builder.assert_bool(selector_sum.clone());
256 builder.when(is_real.clone()).assert_one(selector_sum.clone());
257 builder.when_not(is_real.clone()).assert_zero(selector_sum.clone());
258
259 let is_op: AB::Expr = selectors.is_add
262 + selectors.is_sub
263 + selectors.is_mul
264 + selectors.is_mulh
265 + selectors.is_mulhsu
266 + selectors.is_mulhu
267 + selectors.is_div
268 + selectors.is_divu
269 + selectors.is_rem
270 + selectors.is_remu
271 + selectors.is_sll
272 + selectors.is_srl
273 + selectors.is_sra
274 + selectors.is_xor
275 + selectors.is_or
276 + selectors.is_and
277 + selectors.is_slt
278 + selectors.is_sltu;
279
280 let is_op_32: AB::Expr = selectors.is_addw
282 + selectors.is_subw
283 + selectors.is_sllw
284 + selectors.is_srlw
285 + selectors.is_sraw
286 + selectors.is_mulw
287 + selectors.is_divw
288 + selectors.is_divuw
289 + selectors.is_remw
290 + selectors.is_remuw;
291
292 let has_imm_op_imm: AB::Expr = selectors.is_sll
297 + selectors.is_srl
298 + selectors.is_sra
299 + selectors.is_xor
300 + selectors.is_or
301 + selectors.is_and
302 + selectors.is_slt
303 + selectors.is_sltu
304 + selectors.is_addi;
305
306 let has_imm_op_imm_32: AB::Expr =
308 selectors.is_addw + selectors.is_sllw + selectors.is_srlw + selectors.is_sraw;
309
310 let is_addi: AB::Expr = selectors.is_addi.into();
314 let reg_base_opcode: AB::Expr = is_op.clone() * AB::F::from_canonical_u32(OPCODE_OP)
315 + is_op_32.clone() * AB::F::from_canonical_u32(OPCODE_OP_32)
316 + is_addi.clone() * AB::F::from_canonical_u32(OPCODE_OP_IMM);
317
318 let imm_base_opcode: AB::Expr = has_imm_op_imm * AB::F::from_canonical_u32(OPCODE_OP_IMM)
319 + has_imm_op_imm_32 * AB::F::from_canonical_u32(OPCODE_OP_IMM_32);
320
321 let base_opcode: AB::Expr =
322 (is_real.clone() - imm_c.clone()) * reg_base_opcode + imm_c.clone() * imm_base_opcode;
323
324 let reg_instr_type: AB::Expr = (is_op + is_op_32)
328 * AB::F::from_canonical_u32(InstructionType::RType as u32)
329 + is_addi * AB::F::from_canonical_u32(InstructionType::IType as u32);
330
331 let is_shamt: AB::Expr = selectors.is_sll + selectors.is_srl + selectors.is_sra;
333 let is_shamt32: AB::Expr = selectors.is_sllw + selectors.is_srlw + selectors.is_sraw;
335 let is_itype_imm: AB::Expr = selectors.is_xor
337 + selectors.is_or
338 + selectors.is_and
339 + selectors.is_slt
340 + selectors.is_sltu
341 + selectors.is_addi
342 + selectors.is_addw;
343
344 let imm_instr_type: AB::Expr = is_shamt
345 * AB::F::from_canonical_u32(InstructionType::ITypeShamt as u32)
346 + is_shamt32 * AB::F::from_canonical_u32(InstructionType::ITypeShamt32 as u32)
347 + is_itype_imm * AB::F::from_canonical_u32(InstructionType::IType as u32);
348
349 let instr_type: AB::Expr =
350 (is_real.clone() - imm_c.clone()) * reg_instr_type + imm_c.clone() * imm_instr_type;
351
352 let funct3: AB::Expr =
356 (selectors.is_mulh
358 + selectors.is_sll
359 + selectors.is_sllw)
360 * AB::F::from_canonical_u32(0b001)
361 + (selectors.is_mulhsu + selectors.is_slt)
363 * AB::F::from_canonical_u32(0b010)
364 + (selectors.is_mulhu + selectors.is_sltu)
366 * AB::F::from_canonical_u32(0b011)
367 + (selectors.is_div
369 + selectors.is_xor
370 + selectors.is_divw)
371 * AB::F::from_canonical_u32(0b100)
372 + (selectors.is_divu
374 + selectors.is_srl
375 + selectors.is_sra
376 + selectors.is_divuw
377 + selectors.is_srlw
378 + selectors.is_sraw)
379 * AB::F::from_canonical_u32(0b101)
380 + (selectors.is_rem
382 + selectors.is_or
383 + selectors.is_remw)
384 * AB::F::from_canonical_u32(0b110)
385 + (selectors.is_remu
387 + selectors.is_and
388 + selectors.is_remuw)
389 * AB::F::from_canonical_u32(0b111);
390
391 let funct7: AB::Expr =
399 (selectors.is_sub
401 + selectors.is_sra
402 + selectors.is_subw
403 + selectors.is_sraw)
404 * AB::F::from_canonical_u32(0b0100000)
405 + (selectors.is_mul
407 + selectors.is_mulh
408 + selectors.is_mulhsu
409 + selectors.is_mulhu
410 + selectors.is_div
411 + selectors.is_divu
412 + selectors.is_rem
413 + selectors.is_remu
414 + selectors.is_mulw
415 + selectors.is_divw
416 + selectors.is_divuw
417 + selectors.is_remw
418 + selectors.is_remuw)
419 * AB::F::from_canonical_u32(0b0000001);
420
421 builder.assert_eq(selectors.instr_type, instr_type);
422 builder.assert_eq(selectors.base_opcode, base_opcode);
423 builder.assert_eq(selectors.funct3, funct3);
424 builder.assert_eq(selectors.funct7, funct7);
425}
426
427pub mod recursion {
432 pub use sp1_core_executor::SP1RecursionProof;
433}
434
435#[cfg(test)]
436pub mod programs {
437 #[allow(dead_code)]
438 #[allow(missing_docs)]
439 pub mod tests {
440 use sp1_core_executor::{add_halt, Instruction, Opcode, Program};
441
442 pub use test_artifacts::{
443 FIBONACCI_ELF, KECCAK_PERMUTE_ELF, PANIC_ELF, SECP256R1_ADD_ELF, SECP256R1_DOUBLE_ELF,
444 SSZ_WITHDRAWALS_ELF, U256XU2048_MUL_ELF,
445 };
446
447 #[must_use]
448 pub fn simple_program() -> Program {
449 let mut instructions = vec![
450 Instruction::new(Opcode::ADDI, 29, 0, 5, false, true),
451 Instruction::new(Opcode::ADDI, 30, 0, 37, false, true),
452 Instruction::new(Opcode::ADD, 31, 30, 29, false, false),
453 ];
454 add_halt(&mut instructions);
455 Program::new(instructions, 0, 0)
456 }
457
458 #[must_use]
464 pub fn fibonacci_program() -> Program {
465 Program::from(&FIBONACCI_ELF).unwrap()
466 }
467
468 #[must_use]
474 pub fn secp256r1_add_program() -> Program {
475 Program::from(&SECP256R1_ADD_ELF).unwrap()
476 }
477
478 #[must_use]
484 pub fn secp256r1_double_program() -> Program {
485 Program::from(&SECP256R1_DOUBLE_ELF).unwrap()
486 }
487
488 #[must_use]
494 pub fn ssz_withdrawals_program() -> Program {
495 Program::from(&SSZ_WITHDRAWALS_ELF).unwrap()
496 }
497
498 #[must_use]
504 pub fn keccak_permute_program() -> Program {
505 Program::from(&KECCAK_PERMUTE_ELF).unwrap()
506 }
507
508 #[must_use]
514 pub fn panic_program() -> Program {
515 Program::from(&PANIC_ELF).unwrap()
516 }
517
518 #[must_use]
519 #[allow(clippy::unreadable_literal)]
520 pub fn simple_memory_program() -> Program {
521 let instructions = vec![
522 Instruction::new(Opcode::ADDI, 29, 0, 0x12348765, false, true),
523 Instruction::new(Opcode::SW, 29, 0, 0x27654320, false, true),
525 Instruction::new(Opcode::LW, 28, 0, 0x27654320, false, true),
526 Instruction::new(Opcode::LBU, 27, 0, 0x27654320, false, true),
528 Instruction::new(Opcode::LBU, 26, 0, 0x27654321, false, true),
529 Instruction::new(Opcode::LBU, 25, 0, 0x27654322, false, true),
530 Instruction::new(Opcode::LBU, 24, 0, 0x27654323, false, true),
531 Instruction::new(Opcode::LB, 23, 0, 0x27654320, false, true),
533 Instruction::new(Opcode::LB, 22, 0, 0x27654321, false, true),
534 Instruction::new(Opcode::LHU, 21, 0, 0x27654320, false, true),
536 Instruction::new(Opcode::LHU, 20, 0, 0x27654322, false, true),
537 Instruction::new(Opcode::LH, 19, 0, 0x27654320, false, true),
539 Instruction::new(Opcode::LH, 18, 0, 0x27654322, false, true),
540 Instruction::new(Opcode::ADDI, 17, 0, 0x38276525, false, true),
542 Instruction::new(Opcode::SW, 29, 0, 0x43627530, false, true),
544 Instruction::new(Opcode::SB, 17, 0, 0x43627530, false, true),
545 Instruction::new(Opcode::LW, 16, 0, 0x43627530, false, true),
546 Instruction::new(Opcode::SB, 17, 0, 0x43627531, false, true),
547 Instruction::new(Opcode::LW, 15, 0, 0x43627530, false, true),
548 Instruction::new(Opcode::SB, 17, 0, 0x43627532, false, true),
549 Instruction::new(Opcode::LW, 14, 0, 0x43627530, false, true),
550 Instruction::new(Opcode::SB, 17, 0, 0x43627533, false, true),
551 Instruction::new(Opcode::LW, 13, 0, 0x43627530, false, true),
552 Instruction::new(Opcode::SW, 29, 0, 0x43627530, false, true),
555 Instruction::new(Opcode::SH, 17, 0, 0x43627530, false, true),
556 Instruction::new(Opcode::LW, 12, 0, 0x43627530, false, true),
557 Instruction::new(Opcode::SH, 17, 0, 0x43627532, false, true),
558 Instruction::new(Opcode::LW, 11, 0, 0x43627530, false, true),
559 ];
560 Program::new(instructions, 0, 0)
561 }
562 }
563}