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;
9pub mod handlers;
10
11extern crate alloc;
12
13use alloc::{sync::Arc, vec, vec::Vec};
14
15use miden_assembly::{Library, mast::MastForest};
16use miden_core::{
17 events::EventName, precompile::PrecompileVerifierRegistry, serde::Deserializable,
18};
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 ecdsa::{ECDSA_VERIFY_EVENT_NAME, EcdsaPrecompile},
25 eddsa_ed25519::{EDDSA25519_VERIFY_EVENT_NAME, EddsaPrecompile},
26 falcon_div::{FALCON_DIV_EVENT_NAME, handle_falcon_div},
27 keccak256::{KECCAK_HASH_BYTES_EVENT_NAME, KeccakPrecompile},
28 sha512::{SHA512_HASH_BYTES_EVENT_NAME, Sha512Precompile},
29 smt_peek::{SMT_PEEK_EVENT_NAME, handle_smt_peek},
30 sorted_array::{
31 LOWERBOUND_ARRAY_EVENT_NAME, LOWERBOUND_KEY_VALUE_EVENT_NAME, handle_lowerbound_array,
32 handle_lowerbound_key_value,
33 },
34 u64_div::{U64_DIV_EVENT_NAME, handle_u64_div},
35 u128_div::{U128_DIV_EVENT_NAME, handle_u128_div},
36};
37
38#[derive(Clone)]
94pub struct CoreLibrary(Library);
95
96impl AsRef<Library> for CoreLibrary {
97 fn as_ref(&self) -> &Library {
98 &self.0
99 }
100}
101
102impl From<CoreLibrary> for Library {
103 fn from(value: CoreLibrary) -> Self {
104 value.0
105 }
106}
107
108impl From<&CoreLibrary> for HostLibrary {
109 fn from(core_lib: &CoreLibrary) -> Self {
110 Self {
111 mast_forest: core_lib.mast_forest().clone(),
112 handlers: core_lib.handlers(),
113 }
114 }
115}
116
117impl CoreLibrary {
118 pub const SERIALIZED: &'static [u8] =
120 include_bytes!(concat!(env!("OUT_DIR"), "/assets/core.masl"));
121
122 pub fn mast_forest(&self) -> &Arc<MastForest> {
124 self.0.mast_forest()
125 }
126
127 pub fn library(&self) -> &Library {
129 &self.0
130 }
131
132 pub fn handlers(&self) -> Vec<(EventName, Arc<dyn EventHandler>)> {
134 vec![
135 (KECCAK_HASH_BYTES_EVENT_NAME, Arc::new(KeccakPrecompile)),
136 (SHA512_HASH_BYTES_EVENT_NAME, Arc::new(Sha512Precompile)),
137 (ECDSA_VERIFY_EVENT_NAME, Arc::new(EcdsaPrecompile)),
138 (EDDSA25519_VERIFY_EVENT_NAME, Arc::new(EddsaPrecompile)),
139 (SMT_PEEK_EVENT_NAME, Arc::new(handle_smt_peek)),
140 (U64_DIV_EVENT_NAME, Arc::new(handle_u64_div)),
141 (U128_DIV_EVENT_NAME, Arc::new(handle_u128_div)),
142 (FALCON_DIV_EVENT_NAME, Arc::new(handle_falcon_div)),
143 (LOWERBOUND_ARRAY_EVENT_NAME, Arc::new(handle_lowerbound_array)),
144 (LOWERBOUND_KEY_VALUE_EVENT_NAME, Arc::new(handle_lowerbound_key_value)),
145 (AEAD_DECRYPT_EVENT_NAME, Arc::new(handle_aead_decrypt)),
146 ]
147 }
148
149 pub fn verifier_registry(&self) -> PrecompileVerifierRegistry {
152 PrecompileVerifierRegistry::new()
153 .with_verifier(&KECCAK_HASH_BYTES_EVENT_NAME, Arc::new(KeccakPrecompile))
154 .with_verifier(&SHA512_HASH_BYTES_EVENT_NAME, Arc::new(Sha512Precompile))
155 .with_verifier(&ECDSA_VERIFY_EVENT_NAME, Arc::new(EcdsaPrecompile))
156 .with_verifier(&EDDSA25519_VERIFY_EVENT_NAME, Arc::new(EddsaPrecompile))
157 }
158}
159
160impl Default for CoreLibrary {
161 fn default() -> Self {
162 static CORELIB: LazyLock<CoreLibrary> = LazyLock::new(|| {
163 let contents = Library::read_from_bytes(CoreLibrary::SERIALIZED)
164 .expect("failed to read core masl!");
165 CoreLibrary(contents)
166 });
167 CORELIB.clone()
168 }
169}
170
171#[cfg(test)]
175mod tests {
176 use miden_assembly::Path;
177
178 use super::*;
179
180 #[test]
181 fn test_compile() {
182 let path = Path::new("::miden::core::math::u64::overflowing_add");
183 let core_lib = CoreLibrary::default();
184 let exists = core_lib.0.module_infos().any(|module| {
185 module.procedures().any(|(_, proc)| &module.path().join(&proc.name) == path)
186 });
187
188 assert!(exists);
189 }
190}