sp1_core_executor/syscalls/
mod.rs

1//! Syscall definitions & implementations for the [`crate::Executor`].
2
3mod code;
4mod commit;
5mod context;
6mod deferred;
7mod halt;
8mod hint;
9mod precompiles;
10mod unconstrained;
11mod verify;
12mod write;
13
14use std::sync::Arc;
15
16use commit::CommitSyscall;
17use deferred::CommitDeferredSyscall;
18use halt::HaltSyscall;
19use hashbrown::HashMap;
20
21pub use code::*;
22pub use context::*;
23use hint::{HintLenSyscall, HintReadSyscall};
24use precompiles::{
25    edwards::{add::EdwardsAddAssignSyscall, decompress::EdwardsDecompressSyscall},
26    fptower::{Fp2AddSubSyscall, Fp2MulSyscall, FpOpSyscall},
27    keccak256::permute::Keccak256PermuteSyscall,
28    sha256::{compress::Sha256CompressSyscall, extend::Sha256ExtendSyscall},
29    u256x2048_mul::U256xU2048MulSyscall,
30    uint256::Uint256MulSyscall,
31    weierstrass::{
32        add::WeierstrassAddAssignSyscall, decompress::WeierstrassDecompressSyscall,
33        double::WeierstrassDoubleAssignSyscall,
34    },
35};
36
37use sp1_curves::{
38    edwards::ed25519::{Ed25519, Ed25519Parameters},
39    weierstrass::{
40        bls12_381::{Bls12381, Bls12381BaseField},
41        bn254::{Bn254, Bn254BaseField},
42        secp256k1::Secp256k1,
43        secp256r1::Secp256r1,
44    },
45};
46use unconstrained::{EnterUnconstrainedSyscall, ExitUnconstrainedSyscall};
47use verify::VerifySyscall;
48use write::WriteSyscall;
49
50use crate::events::FieldOperation;
51
52/// A system call in the SP1 RISC-V zkVM.
53///
54/// This trait implements methods needed to execute a system call inside the [`crate::Executor`].
55pub trait Syscall: Send + Sync {
56    /// Executes the syscall.
57    ///
58    /// Returns the resulting value of register a0. `arg1` and `arg2` are the values in registers
59    /// X10 and X11, respectively. While not a hard requirement, the convention is that the return
60    /// value is only for system calls such as `HALT`. Most precompiles use `arg1` and `arg2` to
61    /// denote the addresses of the input data, and write the result to the memory at `arg1`.
62    fn execute(
63        &self,
64        ctx: &mut SyscallContext,
65        syscall_code: SyscallCode,
66        arg1: u32,
67        arg2: u32,
68    ) -> Option<u32>;
69
70    /// The number of extra cycles that the syscall takes to execute.
71    ///
72    /// Unless this syscall is complex and requires many cycles, this should be zero.
73    fn num_extra_cycles(&self) -> u32 {
74        0
75    }
76}
77
78/// Creates the default syscall map.
79#[must_use]
80#[allow(clippy::too_many_lines)]
81pub fn default_syscall_map() -> HashMap<SyscallCode, Arc<dyn Syscall>> {
82    let mut syscall_map = HashMap::<SyscallCode, Arc<dyn Syscall>>::default();
83
84    syscall_map.insert(SyscallCode::HALT, Arc::new(HaltSyscall));
85
86    syscall_map.insert(SyscallCode::SHA_EXTEND, Arc::new(Sha256ExtendSyscall));
87
88    syscall_map.insert(SyscallCode::SHA_COMPRESS, Arc::new(Sha256CompressSyscall));
89
90    syscall_map.insert(SyscallCode::ED_ADD, Arc::new(EdwardsAddAssignSyscall::<Ed25519>::new()));
91
92    syscall_map.insert(
93        SyscallCode::ED_DECOMPRESS,
94        Arc::new(EdwardsDecompressSyscall::<Ed25519Parameters>::new()),
95    );
96
97    syscall_map.insert(SyscallCode::KECCAK_PERMUTE, Arc::new(Keccak256PermuteSyscall));
98
99    syscall_map.insert(
100        SyscallCode::SECP256K1_ADD,
101        Arc::new(WeierstrassAddAssignSyscall::<Secp256k1>::new()),
102    );
103
104    syscall_map.insert(
105        SyscallCode::SECP256K1_DOUBLE,
106        Arc::new(WeierstrassDoubleAssignSyscall::<Secp256k1>::new()),
107    );
108
109    syscall_map.insert(
110        SyscallCode::SECP256K1_DECOMPRESS,
111        Arc::new(WeierstrassDecompressSyscall::<Secp256k1>::new()),
112    );
113
114    syscall_map.insert(
115        SyscallCode::SECP256R1_ADD,
116        Arc::new(WeierstrassAddAssignSyscall::<Secp256r1>::new()),
117    );
118
119    syscall_map.insert(
120        SyscallCode::SECP256R1_DOUBLE,
121        Arc::new(WeierstrassDoubleAssignSyscall::<Secp256r1>::new()),
122    );
123
124    syscall_map.insert(
125        SyscallCode::SECP256R1_DECOMPRESS,
126        Arc::new(WeierstrassDecompressSyscall::<Secp256r1>::new()),
127    );
128
129    syscall_map
130        .insert(SyscallCode::BN254_ADD, Arc::new(WeierstrassAddAssignSyscall::<Bn254>::new()));
131
132    syscall_map.insert(
133        SyscallCode::BN254_DOUBLE,
134        Arc::new(WeierstrassDoubleAssignSyscall::<Bn254>::new()),
135    );
136
137    syscall_map.insert(
138        SyscallCode::BLS12381_ADD,
139        Arc::new(WeierstrassAddAssignSyscall::<Bls12381>::new()),
140    );
141
142    syscall_map.insert(
143        SyscallCode::BLS12381_DOUBLE,
144        Arc::new(WeierstrassDoubleAssignSyscall::<Bls12381>::new()),
145    );
146
147    syscall_map.insert(SyscallCode::UINT256_MUL, Arc::new(Uint256MulSyscall));
148
149    syscall_map.insert(SyscallCode::U256XU2048_MUL, Arc::new(U256xU2048MulSyscall));
150
151    syscall_map.insert(
152        SyscallCode::BLS12381_FP_ADD,
153        Arc::new(FpOpSyscall::<Bls12381BaseField>::new(FieldOperation::Add)),
154    );
155
156    syscall_map.insert(
157        SyscallCode::BLS12381_FP_SUB,
158        Arc::new(FpOpSyscall::<Bls12381BaseField>::new(FieldOperation::Sub)),
159    );
160
161    syscall_map.insert(
162        SyscallCode::BLS12381_FP_MUL,
163        Arc::new(FpOpSyscall::<Bls12381BaseField>::new(FieldOperation::Mul)),
164    );
165
166    syscall_map.insert(
167        SyscallCode::BLS12381_FP2_ADD,
168        Arc::new(Fp2AddSubSyscall::<Bls12381BaseField>::new(FieldOperation::Add)),
169    );
170
171    syscall_map.insert(
172        SyscallCode::BLS12381_FP2_SUB,
173        Arc::new(Fp2AddSubSyscall::<Bls12381BaseField>::new(FieldOperation::Sub)),
174    );
175
176    syscall_map
177        .insert(SyscallCode::BLS12381_FP2_MUL, Arc::new(Fp2MulSyscall::<Bls12381BaseField>::new()));
178
179    syscall_map.insert(
180        SyscallCode::BN254_FP_ADD,
181        Arc::new(FpOpSyscall::<Bn254BaseField>::new(FieldOperation::Add)),
182    );
183
184    syscall_map.insert(
185        SyscallCode::BN254_FP_SUB,
186        Arc::new(FpOpSyscall::<Bn254BaseField>::new(FieldOperation::Sub)),
187    );
188
189    syscall_map.insert(
190        SyscallCode::BN254_FP_MUL,
191        Arc::new(FpOpSyscall::<Bn254BaseField>::new(FieldOperation::Mul)),
192    );
193
194    syscall_map.insert(
195        SyscallCode::BN254_FP2_ADD,
196        Arc::new(Fp2AddSubSyscall::<Bn254BaseField>::new(FieldOperation::Add)),
197    );
198
199    syscall_map.insert(
200        SyscallCode::BN254_FP2_SUB,
201        Arc::new(Fp2AddSubSyscall::<Bn254BaseField>::new(FieldOperation::Sub)),
202    );
203
204    syscall_map
205        .insert(SyscallCode::BN254_FP2_MUL, Arc::new(Fp2MulSyscall::<Bn254BaseField>::new()));
206
207    syscall_map.insert(SyscallCode::ENTER_UNCONSTRAINED, Arc::new(EnterUnconstrainedSyscall));
208
209    syscall_map.insert(SyscallCode::EXIT_UNCONSTRAINED, Arc::new(ExitUnconstrainedSyscall));
210
211    syscall_map.insert(SyscallCode::WRITE, Arc::new(WriteSyscall));
212
213    syscall_map.insert(SyscallCode::COMMIT, Arc::new(CommitSyscall));
214
215    syscall_map.insert(SyscallCode::COMMIT_DEFERRED_PROOFS, Arc::new(CommitDeferredSyscall));
216
217    syscall_map.insert(SyscallCode::VERIFY_SP1_PROOF, Arc::new(VerifySyscall));
218
219    syscall_map.insert(SyscallCode::HINT_LEN, Arc::new(HintLenSyscall));
220
221    syscall_map.insert(SyscallCode::HINT_READ, Arc::new(HintReadSyscall));
222
223    syscall_map.insert(
224        SyscallCode::BLS12381_DECOMPRESS,
225        Arc::new(WeierstrassDecompressSyscall::<Bls12381>::new()),
226    );
227
228    syscall_map
229}