1use deepsize2::DeepSizeOf;
4use enum_map::Enum;
5use serde::{Deserialize, Serialize};
6use strum::EnumIter;
7
8use crate::{events::FieldOperation, RiscvAirId};
9
10#[derive(
27 Debug,
28 Copy,
29 Clone,
30 PartialEq,
31 Eq,
32 Hash,
33 EnumIter,
34 Ord,
35 PartialOrd,
36 Serialize,
37 Deserialize,
38 Enum,
39 Default,
40 DeepSizeOf,
41)]
42#[allow(non_camel_case_types)]
43#[allow(clippy::upper_case_acronyms)]
44#[repr(u32)]
45pub enum SyscallCode {
46 #[default]
48 HALT = 0x00_00_00_00,
49
50 WRITE = 0x00_00_00_02,
52
53 ENTER_UNCONSTRAINED = 0x00_00_00_03,
55
56 EXIT_UNCONSTRAINED = 0x00_00_00_04,
58
59 SHA_EXTEND = 0x00_30_01_05,
61
62 SHA_COMPRESS = 0x00_01_01_06,
64
65 ED_ADD = 0x00_01_01_07,
67
68 ED_DECOMPRESS = 0x00_00_01_08,
70
71 KECCAK_PERMUTE = 0x00_01_01_09,
73
74 SECP256K1_ADD = 0x00_01_01_0A,
76
77 SECP256K1_DOUBLE = 0x00_00_01_0B,
79
80 SECP256K1_DECOMPRESS = 0x00_00_01_0C,
82
83 BN254_ADD = 0x00_01_01_0E,
85
86 BN254_DOUBLE = 0x00_00_01_0F,
88
89 COMMIT = 0x00_00_00_10,
91
92 COMMIT_DEFERRED_PROOFS = 0x00_00_00_1A,
94
95 VERIFY_SP1_PROOF = 0x00_00_00_1B,
97
98 BLS12381_DECOMPRESS = 0x00_00_01_1C,
100
101 HINT_LEN = 0x00_00_00_F0,
103
104 HINT_READ = 0x00_00_00_F1,
106
107 UINT256_MUL = 0x00_01_01_1D,
109
110 U256XU2048_MUL = 0x00_01_01_2F,
112
113 BLS12381_ADD = 0x00_01_01_1E,
115
116 BLS12381_DOUBLE = 0x00_00_01_1F,
118
119 BLS12381_FP_ADD = 0x00_01_01_20,
121
122 BLS12381_FP_SUB = 0x00_01_01_21,
124
125 BLS12381_FP_MUL = 0x00_01_01_22,
127
128 BLS12381_FP2_ADD = 0x00_01_01_23,
130
131 BLS12381_FP2_SUB = 0x00_01_01_24,
133
134 BLS12381_FP2_MUL = 0x00_01_01_25,
136
137 BN254_FP_ADD = 0x00_01_01_26,
139
140 BN254_FP_SUB = 0x00_01_01_27,
142
143 BN254_FP_MUL = 0x00_01_01_28,
145
146 BN254_FP2_ADD = 0x00_01_01_29,
148
149 BN254_FP2_SUB = 0x00_01_01_2A,
151
152 BN254_FP2_MUL = 0x00_01_01_2B,
154
155 SECP256R1_ADD = 0x00_01_01_2C,
157
158 SECP256R1_DOUBLE = 0x00_00_01_2D,
160
161 SECP256R1_DECOMPRESS = 0x00_00_01_2E,
163
164 UINT256_ADD_CARRY = 0x00_01_01_30,
166
167 UINT256_MUL_CARRY = 0x00_01_01_31,
169
170 #[allow(clippy::mistyped_literal_suffixes)]
172 MPROTECT = 0x00_00_01_32,
173
174 POSEIDON2 = 0x00_00_01_33,
176
177 #[allow(clippy::mistyped_literal_suffixes)]
179 SIG_RETURN = 0x00_00_01_34,
180
181 HINT_MPROTECT_FLUSH = 0x00_00_00_35,
183
184 DUMP_ELF = 0x00_00_00_40,
186
187 INSERT_PROFILER_SYMBOLS = 0x00_00_00_41,
189
190 DELETE_PROFILER_SYMBOLS = 0x00_00_00_42,
192}
193
194impl SyscallCode {
195 #[must_use]
197 pub fn from_u32(value: u32) -> Self {
198 match value {
199 0x00_00_00_00 => SyscallCode::HALT,
200 0x00_00_00_02 => SyscallCode::WRITE,
201 0x00_00_00_03 => SyscallCode::ENTER_UNCONSTRAINED,
202 0x00_00_00_04 => SyscallCode::EXIT_UNCONSTRAINED,
203 0x00_30_01_05 => SyscallCode::SHA_EXTEND,
204 0x00_01_01_06 => SyscallCode::SHA_COMPRESS,
205 0x00_01_01_07 => SyscallCode::ED_ADD,
206 0x00_00_01_08 => SyscallCode::ED_DECOMPRESS,
207 0x00_01_01_09 => SyscallCode::KECCAK_PERMUTE,
208 0x00_01_01_0A => SyscallCode::SECP256K1_ADD,
209 0x00_00_01_0B => SyscallCode::SECP256K1_DOUBLE,
210 0x00_00_01_0C => SyscallCode::SECP256K1_DECOMPRESS,
211 0x00_01_01_0E => SyscallCode::BN254_ADD,
212 0x00_00_01_0F => SyscallCode::BN254_DOUBLE,
213 0x00_01_01_1E => SyscallCode::BLS12381_ADD,
214 0x00_00_01_1F => SyscallCode::BLS12381_DOUBLE,
215 0x00_00_00_10 => SyscallCode::COMMIT,
216 0x00_00_00_1A => SyscallCode::COMMIT_DEFERRED_PROOFS,
217 0x00_00_00_1B => SyscallCode::VERIFY_SP1_PROOF,
218 0x00_00_00_F0 => SyscallCode::HINT_LEN,
219 0x00_00_00_F1 => SyscallCode::HINT_READ,
220 0x00_01_01_1D => SyscallCode::UINT256_MUL,
221 0x00_01_01_2F => SyscallCode::U256XU2048_MUL,
222 0x00_01_01_20 => SyscallCode::BLS12381_FP_ADD,
223 0x00_01_01_21 => SyscallCode::BLS12381_FP_SUB,
224 0x00_01_01_22 => SyscallCode::BLS12381_FP_MUL,
225 0x00_01_01_23 => SyscallCode::BLS12381_FP2_ADD,
226 0x00_01_01_24 => SyscallCode::BLS12381_FP2_SUB,
227 0x00_01_01_25 => SyscallCode::BLS12381_FP2_MUL,
228 0x00_01_01_26 => SyscallCode::BN254_FP_ADD,
229 0x00_01_01_27 => SyscallCode::BN254_FP_SUB,
230 0x00_01_01_28 => SyscallCode::BN254_FP_MUL,
231 0x00_01_01_29 => SyscallCode::BN254_FP2_ADD,
232 0x00_01_01_2A => SyscallCode::BN254_FP2_SUB,
233 0x00_01_01_2B => SyscallCode::BN254_FP2_MUL,
234 0x00_00_01_1C => SyscallCode::BLS12381_DECOMPRESS,
235 0x00_01_01_2C => SyscallCode::SECP256R1_ADD,
236 0x00_00_01_2D => SyscallCode::SECP256R1_DOUBLE,
237 0x00_00_01_2E => SyscallCode::SECP256R1_DECOMPRESS,
238 0x00_01_01_30 => SyscallCode::UINT256_ADD_CARRY,
239 0x00_01_01_31 => SyscallCode::UINT256_MUL_CARRY,
240 #[allow(clippy::mistyped_literal_suffixes)]
241 0x00_00_01_32 => SyscallCode::MPROTECT,
242 0x00_00_01_33 => SyscallCode::POSEIDON2,
243 #[allow(clippy::mistyped_literal_suffixes)]
244 0x00_00_01_34 => SyscallCode::SIG_RETURN,
245 0x00_00_00_35 => SyscallCode::HINT_MPROTECT_FLUSH,
246 0x00_00_00_40 => SyscallCode::DUMP_ELF,
247 0x00_00_00_41 => SyscallCode::INSERT_PROFILER_SYMBOLS,
248 0x00_00_00_42 => SyscallCode::DELETE_PROFILER_SYMBOLS,
249 _ => panic!("invalid syscall number: {value}"),
250 }
251 }
252
253 #[must_use]
255 pub fn syscall_id(self) -> u32 {
256 (self as u32).to_le_bytes()[0].into()
257 }
258
259 #[must_use]
261 pub fn should_send(self) -> u32 {
262 (self as u32).to_le_bytes()[1].into()
263 }
264
265 #[must_use]
267 #[allow(clippy::match_same_arms)]
268 pub fn count_map(&self) -> Self {
269 match self {
270 SyscallCode::BN254_FP_SUB => SyscallCode::BN254_FP_ADD,
271 SyscallCode::BN254_FP_MUL => SyscallCode::BN254_FP_ADD,
272 SyscallCode::BN254_FP2_SUB => SyscallCode::BN254_FP2_ADD,
273 SyscallCode::BLS12381_FP_SUB => SyscallCode::BLS12381_FP_ADD,
274 SyscallCode::BLS12381_FP_MUL => SyscallCode::BLS12381_FP_ADD,
275 SyscallCode::BLS12381_FP2_SUB => SyscallCode::BLS12381_FP2_ADD,
276 _ => *self,
277 }
278 }
279
280 #[must_use]
282 pub fn fp_op_map(&self) -> FieldOperation {
283 match self {
284 SyscallCode::BLS12381_FP_ADD
285 | SyscallCode::BLS12381_FP2_ADD
286 | SyscallCode::BN254_FP_ADD
287 | SyscallCode::BN254_FP2_ADD => FieldOperation::Add,
288 SyscallCode::BLS12381_FP_SUB
289 | SyscallCode::BLS12381_FP2_SUB
290 | SyscallCode::BN254_FP_SUB
291 | SyscallCode::BN254_FP2_SUB => FieldOperation::Sub,
292 SyscallCode::BLS12381_FP_MUL
293 | SyscallCode::BLS12381_FP2_MUL
294 | SyscallCode::BN254_FP_MUL
295 | SyscallCode::BN254_FP2_MUL => FieldOperation::Mul,
296 _ => unreachable!(),
297 }
298 }
299
300 #[must_use]
302 pub fn uint256_op_map(&self) -> crate::events::Uint256Operation {
303 match self {
304 SyscallCode::UINT256_ADD_CARRY => crate::events::Uint256Operation::Add,
305 SyscallCode::UINT256_MUL_CARRY => crate::events::Uint256Operation::Mul,
306 _ => unreachable!(),
307 }
308 }
309
310 #[must_use]
313 pub fn as_air_id_flag(self, enable_untrusted_programs: bool) -> Option<RiscvAirId> {
314 if enable_untrusted_programs {
315 return self.as_air_id_user();
316 }
317 self.as_air_id()
318 }
319
320 #[must_use]
322 pub fn as_air_id(self) -> Option<RiscvAirId> {
323 Some(match self {
324 SyscallCode::SHA_EXTEND => RiscvAirId::ShaExtend,
325 SyscallCode::SHA_COMPRESS => RiscvAirId::ShaCompress,
326 SyscallCode::ED_ADD => RiscvAirId::EdAddAssign,
327 SyscallCode::ED_DECOMPRESS => RiscvAirId::EdDecompress,
328 SyscallCode::KECCAK_PERMUTE => RiscvAirId::KeccakPermute,
329 SyscallCode::SECP256K1_ADD => RiscvAirId::Secp256k1AddAssign,
330 SyscallCode::SECP256K1_DOUBLE => RiscvAirId::Secp256k1DoubleAssign,
331 SyscallCode::BN254_ADD => RiscvAirId::Bn254AddAssign,
332 SyscallCode::BN254_DOUBLE => RiscvAirId::Bn254DoubleAssign,
333 SyscallCode::UINT256_MUL => RiscvAirId::Uint256MulMod,
334 SyscallCode::BLS12381_ADD => RiscvAirId::Bls12381AddAssign,
335 SyscallCode::BLS12381_DOUBLE => RiscvAirId::Bls12381DoubleAssign,
336 SyscallCode::BLS12381_FP_ADD
337 | SyscallCode::BLS12381_FP_SUB
338 | SyscallCode::BLS12381_FP_MUL => RiscvAirId::Bls12381FpOpAssign,
339 SyscallCode::BLS12381_FP2_ADD | SyscallCode::BLS12381_FP2_SUB => {
340 RiscvAirId::Bls12381Fp2AddSubAssign
341 }
342 SyscallCode::BLS12381_FP2_MUL => RiscvAirId::Bls12381Fp2MulAssign,
343 SyscallCode::BN254_FP_ADD | SyscallCode::BN254_FP_SUB | SyscallCode::BN254_FP_MUL => {
344 RiscvAirId::Bn254FpOpAssign
345 }
346 SyscallCode::BN254_FP2_ADD | SyscallCode::BN254_FP2_SUB => {
347 RiscvAirId::Bn254Fp2AddSubAssign
348 }
349 SyscallCode::BN254_FP2_MUL => RiscvAirId::Bn254Fp2MulAssign,
350 SyscallCode::SECP256R1_ADD => RiscvAirId::Secp256r1AddAssign,
351 SyscallCode::SECP256R1_DOUBLE => RiscvAirId::Secp256r1DoubleAssign,
352 SyscallCode::UINT256_ADD_CARRY | SyscallCode::UINT256_MUL_CARRY => {
353 RiscvAirId::Uint256Ops
354 }
355 SyscallCode::MPROTECT => RiscvAirId::Mprotect,
356 SyscallCode::POSEIDON2 => RiscvAirId::Poseidon2,
357 SyscallCode::SIG_RETURN => RiscvAirId::SigReturn,
358 SyscallCode::HINT_MPROTECT_FLUSH
359 | SyscallCode::DUMP_ELF
360 | SyscallCode::INSERT_PROFILER_SYMBOLS
361 | SyscallCode::DELETE_PROFILER_SYMBOLS
362 | SyscallCode::U256XU2048_MUL
363 | SyscallCode::SECP256K1_DECOMPRESS
364 | SyscallCode::BLS12381_DECOMPRESS
365 | SyscallCode::SECP256R1_DECOMPRESS
366 | SyscallCode::HALT
367 | SyscallCode::WRITE
368 | SyscallCode::ENTER_UNCONSTRAINED
369 | SyscallCode::EXIT_UNCONSTRAINED
370 | SyscallCode::COMMIT
371 | SyscallCode::COMMIT_DEFERRED_PROOFS
372 | SyscallCode::VERIFY_SP1_PROOF
373 | SyscallCode::HINT_LEN
374 | SyscallCode::HINT_READ => return None,
375 })
376 }
377
378 #[must_use]
380 pub fn as_air_id_user(self) -> Option<RiscvAirId> {
381 Some(match self {
382 SyscallCode::SHA_EXTEND => RiscvAirId::ShaExtend,
383 SyscallCode::SHA_COMPRESS => RiscvAirId::ShaCompress,
384 SyscallCode::ED_ADD => RiscvAirId::EdAddAssignUser,
385 SyscallCode::ED_DECOMPRESS => RiscvAirId::EdDecompressUser,
386 SyscallCode::KECCAK_PERMUTE => RiscvAirId::KeccakPermute,
387 SyscallCode::SECP256K1_ADD => RiscvAirId::Secp256k1AddAssignUser,
388 SyscallCode::SECP256K1_DOUBLE => RiscvAirId::Secp256k1DoubleAssignUser,
389 SyscallCode::BN254_ADD => RiscvAirId::Bn254AddAssignUser,
390 SyscallCode::BN254_DOUBLE => RiscvAirId::Bn254DoubleAssignUser,
391 SyscallCode::UINT256_MUL => RiscvAirId::Uint256MulModUser,
392 SyscallCode::BLS12381_ADD => RiscvAirId::Bls12381AddAssignUser,
393 SyscallCode::BLS12381_DOUBLE => RiscvAirId::Bls12381DoubleAssignUser,
394 SyscallCode::BLS12381_FP_ADD
395 | SyscallCode::BLS12381_FP_SUB
396 | SyscallCode::BLS12381_FP_MUL => RiscvAirId::Bls12381FpOpAssignUser,
397 SyscallCode::BLS12381_FP2_ADD | SyscallCode::BLS12381_FP2_SUB => {
398 RiscvAirId::Bls12381Fp2AddSubAssignUser
399 }
400 SyscallCode::BLS12381_FP2_MUL => RiscvAirId::Bls12381Fp2MulAssignUser,
401 SyscallCode::BN254_FP_ADD | SyscallCode::BN254_FP_SUB | SyscallCode::BN254_FP_MUL => {
402 RiscvAirId::Bn254FpOpAssignUser
403 }
404 SyscallCode::BN254_FP2_ADD | SyscallCode::BN254_FP2_SUB => {
405 RiscvAirId::Bn254Fp2AddSubAssignUser
406 }
407 SyscallCode::BN254_FP2_MUL => RiscvAirId::Bn254Fp2MulAssignUser,
408 SyscallCode::SECP256R1_ADD => RiscvAirId::Secp256r1AddAssignUser,
409 SyscallCode::SECP256R1_DOUBLE => RiscvAirId::Secp256r1DoubleAssignUser,
410 SyscallCode::UINT256_ADD_CARRY | SyscallCode::UINT256_MUL_CARRY => {
411 RiscvAirId::Uint256OpsUser
412 }
413 SyscallCode::MPROTECT => RiscvAirId::Mprotect,
414 SyscallCode::SIG_RETURN => RiscvAirId::SigReturn,
415 SyscallCode::POSEIDON2 => RiscvAirId::Poseidon2User,
416 SyscallCode::HINT_MPROTECT_FLUSH
417 | SyscallCode::DUMP_ELF
418 | SyscallCode::INSERT_PROFILER_SYMBOLS
419 | SyscallCode::DELETE_PROFILER_SYMBOLS
420 | SyscallCode::U256XU2048_MUL
421 | SyscallCode::SECP256K1_DECOMPRESS
422 | SyscallCode::BLS12381_DECOMPRESS
423 | SyscallCode::SECP256R1_DECOMPRESS
424 | SyscallCode::HALT
425 | SyscallCode::WRITE
426 | SyscallCode::ENTER_UNCONSTRAINED
427 | SyscallCode::EXIT_UNCONSTRAINED
428 | SyscallCode::COMMIT
429 | SyscallCode::COMMIT_DEFERRED_PROOFS
430 | SyscallCode::VERIFY_SP1_PROOF
431 | SyscallCode::HINT_LEN
432 | SyscallCode::HINT_READ => return None,
433 })
434 }
435
436 #[must_use]
438 #[allow(clippy::match_same_arms)]
439 pub fn touched_addresses(&self) -> usize {
440 match self {
444 SyscallCode::SHA_EXTEND => 64,
445 SyscallCode::SHA_COMPRESS => 72,
446 SyscallCode::KECCAK_PERMUTE => 25,
447 SyscallCode::BLS12381_ADD
448 | SyscallCode::BLS12381_FP2_ADD
449 | SyscallCode::BLS12381_FP2_SUB
450 | SyscallCode::BLS12381_FP2_MUL => 24,
451 SyscallCode::BLS12381_DECOMPRESS
452 | SyscallCode::BLS12381_DOUBLE
453 | SyscallCode::BLS12381_FP_ADD
454 | SyscallCode::BLS12381_FP_SUB
455 | SyscallCode::BLS12381_FP_MUL => 12,
456 SyscallCode::ED_ADD
457 | SyscallCode::SECP256K1_ADD
458 | SyscallCode::SECP256R1_ADD
459 | SyscallCode::BN254_ADD
460 | SyscallCode::BN254_FP2_ADD
461 | SyscallCode::BN254_FP2_SUB
462 | SyscallCode::BN254_FP2_MUL => 16,
463 SyscallCode::ED_DECOMPRESS
464 | SyscallCode::SECP256K1_DECOMPRESS
465 | SyscallCode::SECP256R1_DECOMPRESS
466 | SyscallCode::SECP256K1_DOUBLE
467 | SyscallCode::SECP256R1_DOUBLE
468 | SyscallCode::BN254_DOUBLE
469 | SyscallCode::BN254_FP_ADD
470 | SyscallCode::BN254_FP_SUB
471 | SyscallCode::BN254_FP_MUL => 8,
472 SyscallCode::UINT256_MUL => 12,
473 SyscallCode::UINT256_ADD_CARRY | SyscallCode::UINT256_MUL_CARRY => 20,
474 SyscallCode::U256XU2048_MUL => 72,
475 SyscallCode::MPROTECT => 0,
476 SyscallCode::POSEIDON2 => 8,
477 _ => 0,
478 }
479 }
480
481 #[must_use]
483 #[allow(clippy::match_same_arms)]
484 pub fn touched_pages(&self) -> usize {
485 match self {
489 SyscallCode::SHA_EXTEND => 2 * 2,
490 SyscallCode::SHA_COMPRESS => 3 * 2,
491 SyscallCode::KECCAK_PERMUTE => 2 * 2,
492 SyscallCode::BLS12381_ADD
493 | SyscallCode::SECP256K1_ADD
494 | SyscallCode::SECP256R1_ADD
495 | SyscallCode::BN254_ADD
496 | SyscallCode::ED_ADD
497 | SyscallCode::BLS12381_DECOMPRESS
498 | SyscallCode::SECP256K1_DECOMPRESS
499 | SyscallCode::SECP256R1_DECOMPRESS
500 | SyscallCode::ED_DECOMPRESS => 2 * 2,
501
502 SyscallCode::BLS12381_DOUBLE
503 | SyscallCode::SECP256K1_DOUBLE
504 | SyscallCode::SECP256R1_DOUBLE
505 | SyscallCode::BN254_DOUBLE => 2,
506
507 SyscallCode::BLS12381_FP2_ADD
508 | SyscallCode::BLS12381_FP2_SUB
509 | SyscallCode::BLS12381_FP2_MUL
510 | SyscallCode::BLS12381_FP_ADD
511 | SyscallCode::BLS12381_FP_SUB
512 | SyscallCode::BLS12381_FP_MUL
513 | SyscallCode::BN254_FP2_ADD
514 | SyscallCode::BN254_FP2_SUB
515 | SyscallCode::BN254_FP2_MUL
516 | SyscallCode::BN254_FP_ADD
517 | SyscallCode::BN254_FP_SUB
518 | SyscallCode::BN254_FP_MUL => 2 * 2,
519
520 SyscallCode::UINT256_MUL => 2 * 2,
521 SyscallCode::UINT256_ADD_CARRY | SyscallCode::UINT256_MUL_CARRY => 5 * 2,
522 SyscallCode::U256XU2048_MUL => 4 * 2,
523 SyscallCode::MPROTECT => 1,
524 SyscallCode::POSEIDON2 => 2,
525 _ => 0,
526 }
527 }
528}
529
530impl std::fmt::Display for SyscallCode {
531 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
532 write!(f, "{self:?}")
533 }
534}