1#![no_std]
2
3#[cfg(feature = "std")]
4extern crate std;
5
6#[cfg(any(feature = "constraints-tools", all(test, feature = "std")))]
7pub mod constraints_regen;
8pub mod dsa;
9#[cfg(feature = "constraints-tools")]
10pub mod evaluator_regen;
11pub mod handlers;
12
13extern crate alloc;
14
15use alloc::{sync::Arc, vec, vec::Vec};
16
17use miden_core::{Word, events::EventName, mast::MastForest};
18use miden_mast_package::Package;
19use miden_processor::{HostLibrary, event::EventHandler};
20use miden_utils_sync::LazyLock;
21
22use crate::handlers::{
23 aead_decrypt::{AEAD_DECRYPT_EVENT_NAME, handle_aead_decrypt},
24 debug::default_debug_handlers,
25 falcon_div::{FALCON_DIV_EVENT_NAME, handle_falcon_div},
26 precompiles::{
27 keccak256::{KECCAK256_DIGEST_EVENT_NAME, handle_keccak256_digest},
28 uint_field_inv::{UINT_FIELD_INV_EVENT_NAME, handle_uint_field_inv},
29 },
30 readonly::readonly_noop_handlers,
31 smt_peek::{SMT_PEEK_EVENT_NAME, handle_smt_peek},
32 sorted_array::{
33 LOWERBOUND_ARRAY_EVENT_NAME, LOWERBOUND_KEY_VALUE_EVENT_NAME, handle_lowerbound_array,
34 handle_lowerbound_key_value,
35 },
36 u64_div::{U64_DIV_EVENT_NAME, handle_u64_div},
37 u128_div::{U128_DIV_EVENT_NAME, handle_u128_div},
38 u256_div::{U256_DIV_EVENT_NAME, handle_u256_div},
39};
40
41#[derive(Clone)]
94pub struct CoreLibrary {
95 core_package: Arc<Package>,
96 precompiles_package: Arc<Package>,
97 mast_forest: Arc<MastForest>,
98}
99
100impl AsRef<Package> for CoreLibrary {
101 fn as_ref(&self) -> &Package {
102 &self.core_package
103 }
104}
105
106impl From<&CoreLibrary> for HostLibrary {
107 fn from(core_lib: &CoreLibrary) -> Self {
108 Self {
109 mast_forest: Arc::clone(core_lib.mast_forest()),
110 package_debug_info: Ok(None),
111 handlers: core_lib.handlers(),
112 }
113 }
114}
115
116impl CoreLibrary {
117 pub const SERIALIZED: &'static [u8] =
119 include_bytes!(concat!(env!("OUT_DIR"), "/assets/miden-core.masp"));
120
121 pub const PRECOMPILES_SERIALIZED: &'static [u8] =
123 include_bytes!(concat!(env!("OUT_DIR"), "/assets/miden-precompiles.masp"));
124
125 pub fn mast_forest(&self) -> &Arc<MastForest> {
128 &self.mast_forest
129 }
130
131 pub fn package(&self) -> Arc<Package> {
133 Arc::clone(&self.core_package)
134 }
135
136 pub fn precompiles_package(&self) -> Arc<Package> {
138 Arc::clone(&self.precompiles_package)
139 }
140
141 pub fn packages(&self) -> [Arc<Package>; 2] {
143 [self.package(), self.precompiles_package()]
144 }
145
146 pub fn recursive_verifier_root(&self) -> Word {
154 self.core_package
155 .get_procedure_root_by_path("::miden::core::sys::vm::verify_vm_proof")
156 .expect("verify_vm_proof is exported from the core library")
157 }
158
159 pub fn handlers(&self) -> Vec<(EventName, Arc<dyn EventHandler>)> {
168 let mut handlers: Vec<(EventName, Arc<dyn EventHandler>)> = vec![
169 (SMT_PEEK_EVENT_NAME, Arc::new(handle_smt_peek)),
170 (U64_DIV_EVENT_NAME, Arc::new(handle_u64_div)),
171 (U128_DIV_EVENT_NAME, Arc::new(handle_u128_div)),
172 (U256_DIV_EVENT_NAME, Arc::new(handle_u256_div)),
173 (FALCON_DIV_EVENT_NAME, Arc::new(handle_falcon_div)),
174 (LOWERBOUND_ARRAY_EVENT_NAME, Arc::new(handle_lowerbound_array)),
175 (LOWERBOUND_KEY_VALUE_EVENT_NAME, Arc::new(handle_lowerbound_key_value)),
176 (AEAD_DECRYPT_EVENT_NAME, Arc::new(handle_aead_decrypt)),
177 (KECCAK256_DIGEST_EVENT_NAME, Arc::new(handle_keccak256_digest)),
178 (UINT_FIELD_INV_EVENT_NAME, Arc::new(handle_uint_field_inv)),
179 ];
180 handlers.extend(default_debug_handlers());
181 handlers.extend(readonly_noop_handlers());
182 handlers
183 }
184}
185
186impl Default for CoreLibrary {
187 fn default() -> Self {
188 static CORELIB: LazyLock<CoreLibrary> = LazyLock::new(|| {
189 let core_package = Arc::new(
190 Package::read_from_bytes_trusted(CoreLibrary::SERIALIZED)
191 .expect("failed to read core package!"),
192 );
193 let precompiles_package = Arc::new(
194 Package::read_from_bytes_trusted(CoreLibrary::PRECOMPILES_SERIALIZED)
195 .expect("failed to read precompiles package!"),
196 );
197 let (mast_forest, _) = MastForest::merge([
198 core_package.mast_forest().as_ref(),
199 precompiles_package.mast_forest().as_ref(),
200 ])
201 .expect("failed to merge core and precompiles MAST forests");
202
203 CoreLibrary {
204 core_package,
205 precompiles_package,
206 mast_forest: Arc::new(mast_forest),
207 }
208 });
209 CORELIB.clone()
210 }
211}
212
213#[cfg(test)]
217mod tests {
218 use super::*;
219
220 #[test]
221 fn core_package_version_matches_crate_version() {
222 let core_lib = CoreLibrary::default();
223 let crate_version = env!("CARGO_PKG_VERSION")
224 .parse::<miden_mast_package::Version>()
225 .expect("crate version should be a valid package version");
226
227 for package in core_lib.packages() {
228 assert_eq!(
229 &package.version, &crate_version,
230 "embedded package {} should track the miden-core-lib crate version",
231 package.name,
232 );
233 }
234 }
235
236 #[test]
237 fn test_compile() {
238 let core_lib = CoreLibrary::default();
239 let exists = core_lib
240 .core_package
241 .get_procedure_root_by_path("::miden::core::math::u64::overflowing_add")
242 .is_some();
243
244 assert!(exists);
245 }
246}