monerochan_runtime/
lib.rs1#[cfg(all(target_os = "zkvm", feature = "embedded"))]
2use syscalls::MAX_MEMORY;
3
4#[cfg(target_os = "zkvm")]
5use {
6 cfg_if::cfg_if,
7 syscalls::{syscall_hint_len, syscall_hint_read},
8};
9
10extern crate alloc;
11
12#[cfg(target_os = "zkvm")]
13pub mod allocators;
14
15pub mod syscalls;
16
17#[cfg(feature = "lib")]
18pub mod io {
19 pub use monerochan_lib::io::*;
20}
21
22#[cfg(feature = "lib")]
23pub mod lib {
24 pub use monerochan_lib::*;
25}
26
27#[cfg(all(target_os = "zkvm", feature = "libm"))]
28mod libm;
29
30pub const PV_DIGEST_NUM_WORDS: usize = 8;
32pub const POSEIDON_NUM_WORDS: usize = 8;
33
34#[cfg(all(target_os = "zkvm", feature = "embedded"))]
36pub(crate) const EMBEDDED_RESERVED_INPUT_REGION_SIZE: usize = 1024 * 1024 * 1024;
37
38#[cfg(all(target_os = "zkvm", feature = "embedded"))]
40pub(crate) const EMBEDDED_RESERVED_INPUT_START: usize =
41 MAX_MEMORY - EMBEDDED_RESERVED_INPUT_REGION_SIZE;
42
43#[cfg(all(target_os = "zkvm", feature = "embedded"))]
45static mut EMBEDDED_RESERVED_INPUT_PTR: usize = EMBEDDED_RESERVED_INPUT_START;
46
47#[repr(C)]
48pub struct ReadVecResult {
49 pub ptr: *mut u8,
50 pub len: usize,
51 pub capacity: usize,
52}
53
54#[no_mangle]
69pub extern "C" fn read_vec_raw() -> ReadVecResult {
70 #[cfg(not(target_os = "zkvm"))]
71 unreachable!("read_vec_raw should only be called on the zkvm target.");
72
73 #[cfg(target_os = "zkvm")]
74 {
75 let len = syscall_hint_len();
77
78 if len == usize::MAX {
80 return ReadVecResult { ptr: std::ptr::null_mut(), len: 0, capacity: 0 };
81 }
82
83 let capacity = (len + 3) / 4 * 4;
85
86 cfg_if! {
87 if #[cfg(feature = "embedded")] {
88 let ptr = unsafe { EMBEDDED_RESERVED_INPUT_PTR };
91 if ptr.saturating_add(capacity) > MAX_MEMORY {
92 panic!("Input region overflowed.")
93 }
94
95 unsafe { EMBEDDED_RESERVED_INPUT_PTR += capacity };
97
98 syscall_hint_read(ptr as *mut u8, len);
102
103 ReadVecResult {
105 ptr: ptr as *mut u8,
106 len,
107 capacity,
108 }
109 } else {
110 let layout = std::alloc::Layout::from_size_align(capacity, 4).expect("vec is too large");
112
113 let ptr = unsafe { std::alloc::alloc(layout) };
115
116 syscall_hint_read(ptr as *mut u8, len);
120
121 ReadVecResult {
123 ptr: ptr as *mut u8,
124 len,
125 capacity,
126 }
127 }
128 }
129 }
130}
131
132#[cfg(target_os = "zkvm")]
133mod zkvm {
134 use crate::syscalls::syscall_halt;
135
136 use cfg_if::cfg_if;
137 use sha2::{Digest, Sha256};
138
139 cfg_if! {
140 if #[cfg(feature = "verify")] {
141 use p3_baby_bear::BabyBear;
142 use p3_field::AbstractField;
143
144 pub static mut DEFERRED_PROOFS_DIGEST: Option<[BabyBear; 8]> = None;
145 }
146 }
147
148 cfg_if::cfg_if! {
149 if #[cfg(feature = "blake3")] {
150 pub static mut PUBLIC_VALUES_HASHER: Option<blake3::Hasher> = None;
151 }
152 else {
153 pub static mut PUBLIC_VALUES_HASHER: Option<Sha256> = None;
154 }
155 }
156
157 #[no_mangle]
158 unsafe extern "C" fn __start() {
159 {
160 #[cfg(all(target_os = "zkvm", feature = "embedded"))]
161 crate::allocators::init();
162
163 cfg_if::cfg_if! {
164 if #[cfg(feature = "blake3")] {
165 PUBLIC_VALUES_HASHER = Some(blake3::Hasher::new());
166 }
167 else {
168 PUBLIC_VALUES_HASHER = Some(Sha256::new());
169 }
170 }
171
172 #[cfg(feature = "verify")]
173 {
174 DEFERRED_PROOFS_DIGEST = Some([BabyBear::zero(); 8]);
175 }
176
177 extern "C" {
178 fn main();
179 }
180 main()
181 }
182
183 syscall_halt(0);
184 }
185
186 static STACK_TOP: u32 = 0x0020_0400;
187
188 core::arch::global_asm!(include_str!("memset.s"));
189 core::arch::global_asm!(include_str!("memcpy.s"));
190
191 core::arch::global_asm!(
192 r#"
193 .section .text._start;
194 .globl _start;
195 _start:
196 .option push;
197 .option norelax;
198 la gp, __global_pointer$;
199 .option pop;
200 la sp, {0}
201 lw sp, 0(sp)
202 call __start;
203 "#,
204 sym STACK_TOP
205 );
206
207 pub fn zkvm_getrandom_v2(s: &mut [u8]) -> Result<(), getrandom_v2::Error> {
208 unsafe {
209 crate::syscalls::sys_rand(s.as_mut_ptr(), s.len());
210 }
211
212 Ok(())
213 }
214
215 getrandom_v2::register_custom_getrandom!(zkvm_getrandom_v2);
216
217 #[no_mangle]
218 unsafe extern "Rust" fn __getrandom_v03_custom(
219 dest: *mut u8,
220 len: usize,
221 ) -> Result<(), getrandom_v3::Error> {
222 unsafe {
223 crate::syscalls::sys_rand(dest, len);
224 }
225
226 Ok(())
227 }
228}
229
230#[macro_export]
231macro_rules! entrypoint {
232 ($path:path) => {
233 const ZKVM_ENTRY: fn() = $path;
234
235 mod zkvm_generated_main {
236
237 #[no_mangle]
238 fn main() {
239 if cfg!(target_os = "zkvm") {
248 super::ZKVM_ENTRY()
249 } else {
250 eprintln!("Not running in zkVM, skipping entrypoint");
251 }
252 }
253 }
254 };
255}