sp1_lib/lib.rs
1//! Syscalls for the SP1 zkVM.
2//!
3//! Documentation for these syscalls can be found in the zkVM entrypoint
4//! `sp1_zkvm::syscalls` module.
5
6pub mod bls12381;
7pub mod bn254;
8
9#[cfg(feature = "ecdsa")]
10pub mod ecdsa;
11
12pub mod ed25519;
13pub mod io;
14pub mod mprotect;
15pub mod poseidon2;
16pub mod secp256k1;
17pub mod secp256r1;
18pub mod unconstrained;
19pub mod utils;
20
21#[cfg(feature = "verify")]
22pub mod verify;
23
24/// Halts the zkVM with exit code 3, signalling that a prover-supplied hint
25/// failed verification.
26///
27/// This exists to disambiguate hint-validation failures from regular Rust
28/// panics (which use exit code 1). Patches should call this on any hint check
29/// that would otherwise panic, so a malicious prover cannot forge a "panicked"
30/// proof by feeding wrong hints.
31///
32/// Prefer the [`invalid_hint!`] macro when you have a diagnostic message
33/// to attach.
34#[inline(never)]
35pub fn halt_invalid_hint() -> ! {
36 unsafe { syscall_halt(3) }
37}
38
39/// Internal helper used by [`invalid_hint!`] — write a formatted diagnostic
40/// to stderr (FD 2), then halt with exit code 3.
41///
42/// Kept out-of-line so the macro expansion stays small at every call site.
43#[doc(hidden)]
44#[cold]
45#[inline(never)]
46pub fn __invalid_hint_fmt(args: std::fmt::Arguments<'_>) -> ! {
47 let msg = std::format!("invalid prover hint: {}\n", args);
48 unsafe {
49 syscall_write(2, msg.as_ptr(), msg.len());
50 }
51 halt_invalid_hint()
52}
53
54/// Halts the zkVM with exit code 3 (invalid prover hint), optionally writing
55/// a formatted diagnostic to stderr first.
56///
57/// Format-arg syntax matches [`panic!`], but exit code 3 disambiguates
58/// hint-validation failures from regular panics (exit code 1) — a malicious
59/// prover cannot forge a panicked-program proof by feeding wrong hints.
60/// Patches should reach for this on any hint check that would otherwise panic.
61///
62/// ```ignore
63/// sp1_lib::invalid_hint!(); // no message
64/// sp1_lib::invalid_hint!("Fp inverse hint mismatch");
65/// sp1_lib::invalid_hint!("expected {} bytes, got {}", expected, got);
66/// ```
67#[macro_export]
68macro_rules! invalid_hint {
69 () => {{
70 $crate::halt_invalid_hint()
71 }};
72 ($($arg:tt)*) => {{
73 $crate::__invalid_hint_fmt(::core::format_args!($($arg)*))
74 }};
75}
76
77extern "C" {
78 /// Halts the program with the given exit code.
79 pub fn syscall_halt(exit_code: u8) -> !;
80
81 /// Writes the bytes in the given buffer to the given file descriptor.
82 pub fn syscall_write(fd: u32, write_buf: *const u8, nbytes: usize);
83
84 /// Reads the bytes from the given file descriptor into the given buffer.
85 pub fn syscall_read(fd: u32, read_buf: *mut u8, nbytes: usize);
86
87 /// Executes the SHA-256 extend operation on the given word array.
88 pub fn syscall_sha256_extend(w: *mut [u64; 64]);
89
90 /// Executes the SHA-256 compress operation on the given word array and a given state.
91 pub fn syscall_sha256_compress(w: *mut [u64; 64], state: *mut [u64; 8]);
92
93 /// Executes an Ed25519 curve addition on the given points.
94 pub fn syscall_ed_add(p: *mut [u64; 8], q: *const [u64; 8]);
95
96 /// Executes an Ed25519 curve decompression on the given point.
97 pub fn syscall_ed_decompress(point: &mut [u64; 8]);
98
99 /// Executes an Sepc256k1 curve addition on the given points.
100 pub fn syscall_secp256k1_add(p: *mut [u64; 8], q: *const [u64; 8]);
101
102 /// Executes an Secp256k1 curve doubling on the given point.
103 pub fn syscall_secp256k1_double(p: *mut [u64; 8]);
104
105 /// Executes an Secp256k1 curve decompression on the given point.
106 pub fn syscall_secp256k1_decompress(point: &mut [u64; 8], is_odd: bool);
107
108 /// Executes an Secp256r1 curve addition on the given points.
109 pub fn syscall_secp256r1_add(p: *mut [u64; 8], q: *const [u64; 8]);
110
111 /// Executes an Secp256r1 curve doubling on the given point.
112 pub fn syscall_secp256r1_double(p: *mut [u64; 8]);
113
114 /// Executes an Secp256r1 curve decompression on the given point.
115 pub fn syscall_secp256r1_decompress(point: &mut [u64; 8], is_odd: bool);
116
117 /// Executes a Bn254 curve addition on the given points.
118 pub fn syscall_bn254_add(p: *mut [u64; 8], q: *const [u64; 8]);
119
120 /// Executes a Bn254 curve doubling on the given point.
121 pub fn syscall_bn254_double(p: *mut [u64; 8]);
122
123 /// Executes a BLS12-381 curve addition on the given points.
124 pub fn syscall_bls12381_add(p: *mut [u64; 12], q: *const [u64; 12]);
125
126 /// Executes a BLS12-381 curve doubling on the given point.
127 pub fn syscall_bls12381_double(p: *mut [u64; 12]);
128
129 /// Executes the Keccak-256 permutation on the given state.
130 pub fn syscall_keccak_permute(state: *mut [u64; 25]);
131
132 /// Executes an uint256 multiplication on the given inputs.
133 pub fn syscall_uint256_mulmod(x: *mut [u64; 4], y: *const [u64; 4]);
134
135 /// Executes a 256-bit by 2048-bit multiplication on the given inputs.
136 pub fn syscall_u256x2048_mul(
137 x: *const [u64; 4],
138 y: *const [u64; 32],
139 lo: *mut [u64; 32],
140 hi: *mut [u64; 4],
141 );
142
143 /// Executes Uint256 addition operation with carry.
144 pub fn syscall_uint256_add_with_carry(
145 a: *const [u64; 4],
146 b: *const [u64; 4],
147 c: *const [u64; 4],
148 d: *mut [u64; 4],
149 e: *mut [u64; 4],
150 );
151
152 /// Executes Uint256 multiplication operation with carry.
153 pub fn syscall_uint256_mul_with_carry(
154 a: *const [u64; 4],
155 b: *const [u64; 4],
156 c: *const [u64; 4],
157 d: *mut [u64; 4],
158 e: *mut [u64; 4],
159 );
160
161 /// Enters unconstrained mode.
162 pub fn syscall_enter_unconstrained() -> bool;
163
164 /// Exits unconstrained mode.
165 pub fn syscall_exit_unconstrained();
166
167 /// Defers the verification of a valid SP1 zkVM proof.
168 pub fn syscall_verify_sp1_proof(vk_digest: &[u64; 4], pv_digest: &[u64; 4]);
169
170 /// Returns the length of the next element in the hint stream.
171 pub fn syscall_hint_len() -> usize;
172
173 /// Reads the next element in the hint stream into the given buffer.
174 pub fn syscall_hint_read(ptr: *mut u8, len: usize);
175
176 /// Allocates a buffer aligned to the given alignment.
177 pub fn sys_alloc_aligned(bytes: usize, align: usize) -> *mut u8;
178
179 /// Decompresses a BLS12-381 point.
180 pub fn syscall_bls12381_decompress(point: &mut [u64; 12], is_odd: bool);
181
182 /// Computes a big integer operation with a modulus.
183 pub fn sys_bigint(
184 result: *mut [u64; 4],
185 op: u64,
186 x: *const [u64; 4],
187 y: *const [u64; 4],
188 modulus: *const [u64; 4],
189 );
190
191 /// Executes a BLS12-381 field addition on the given inputs.
192 pub fn syscall_bls12381_fp_addmod(p: *mut u64, q: *const u64);
193
194 /// Executes a BLS12-381 field subtraction on the given inputs.
195 pub fn syscall_bls12381_fp_submod(p: *mut u64, q: *const u64);
196
197 /// Executes a BLS12-381 field multiplication on the given inputs.
198 pub fn syscall_bls12381_fp_mulmod(p: *mut u64, q: *const u64);
199
200 /// Executes a BLS12-381 Fp2 addition on the given inputs.
201 pub fn syscall_bls12381_fp2_addmod(p: *mut u64, q: *const u64);
202
203 /// Executes a BLS12-381 Fp2 subtraction on the given inputs.
204 pub fn syscall_bls12381_fp2_submod(p: *mut u64, q: *const u64);
205
206 /// Executes a BLS12-381 Fp2 multiplication on the given inputs.
207 pub fn syscall_bls12381_fp2_mulmod(p: *mut u64, q: *const u64);
208
209 /// Executes a BN254 field addition on the given inputs.
210 pub fn syscall_bn254_fp_addmod(p: *mut u64, q: *const u64);
211
212 /// Executes a BN254 field subtraction on the given inputs.
213 pub fn syscall_bn254_fp_submod(p: *mut u64, q: *const u64);
214
215 /// Executes a BN254 field multiplication on the given inputs.
216 pub fn syscall_bn254_fp_mulmod(p: *mut u64, q: *const u64);
217
218 /// Executes a BN254 Fp2 addition on the given inputs.
219 pub fn syscall_bn254_fp2_addmod(p: *mut u64, q: *const u64);
220
221 /// Executes a BN254 Fp2 subtraction on the given inputs.
222 pub fn syscall_bn254_fp2_submod(p: *mut u64, q: *const u64);
223
224 /// Executes a BN254 Fp2 multiplication on the given inputs.
225 pub fn syscall_bn254_fp2_mulmod(p: *mut u64, q: *const u64);
226
227 /// Executes the mprotect syscall.
228 pub fn syscall_mprotect(addr: *const u8, prot: u8);
229
230 /// Flushes all pending mprotect changes.
231 pub fn syscall_mprotect_flush();
232
233 /// Reads a buffer from the input stream.
234 pub fn read_vec_raw() -> ReadVecResult;
235
236 /// Executes the Poseidon2 permutation on the given state buffer in-place.
237 pub fn syscall_poseidon2(inout: &mut crate::poseidon2::Poseidon2State);
238}
239
240#[repr(C)]
241pub struct ReadVecResult {
242 pub ptr: *mut u8,
243 pub len: usize,
244 pub capacity: usize,
245}