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 readonly::{
29 READONLY_MIDEN_DEBUG_ASSERTION_FAILED, READONLY_MIDEN_DEBUG_FRAME_END,
30 READONLY_MIDEN_DEBUG_FRAME_START, READONLY_MIDEN_DEBUG_PRINTLN,
31 READONLY_MIDEN_DEBUG_UNKNOWN, readonly_noop_handler,
32 },
33 sha512::{SHA512_HASH_BYTES_EVENT_NAME, Sha512Precompile},
34 smt_peek::{SMT_PEEK_EVENT_NAME, handle_smt_peek},
35 sorted_array::{
36 LOWERBOUND_ARRAY_EVENT_NAME, LOWERBOUND_KEY_VALUE_EVENT_NAME, handle_lowerbound_array,
37 handle_lowerbound_key_value,
38 },
39 u64_div::{U64_DIV_EVENT_NAME, handle_u64_div},
40 u128_div::{U128_DIV_EVENT_NAME, handle_u128_div},
41};
42
43#[derive(Clone)]
99pub struct CoreLibrary(Library);
100
101impl AsRef<Library> for CoreLibrary {
102 fn as_ref(&self) -> &Library {
103 &self.0
104 }
105}
106
107impl From<CoreLibrary> for Library {
108 fn from(value: CoreLibrary) -> Self {
109 value.0
110 }
111}
112
113impl From<&CoreLibrary> for HostLibrary {
114 fn from(core_lib: &CoreLibrary) -> Self {
115 Self {
116 mast_forest: core_lib.mast_forest().clone(),
117 handlers: core_lib.handlers(),
118 }
119 }
120}
121
122impl CoreLibrary {
123 pub const SERIALIZED: &'static [u8] =
125 include_bytes!(concat!(env!("OUT_DIR"), "/assets/core.masl"));
126
127 pub fn mast_forest(&self) -> &Arc<MastForest> {
129 self.0.mast_forest()
130 }
131
132 pub fn library(&self) -> &Library {
134 &self.0
135 }
136
137 pub fn handlers(&self) -> Vec<(EventName, Arc<dyn EventHandler>)> {
139 vec![
140 (KECCAK_HASH_BYTES_EVENT_NAME, Arc::new(KeccakPrecompile)),
141 (SHA512_HASH_BYTES_EVENT_NAME, Arc::new(Sha512Precompile)),
142 (ECDSA_VERIFY_EVENT_NAME, Arc::new(EcdsaPrecompile)),
143 (EDDSA25519_VERIFY_EVENT_NAME, Arc::new(EddsaPrecompile)),
144 (SMT_PEEK_EVENT_NAME, Arc::new(handle_smt_peek)),
145 (U64_DIV_EVENT_NAME, Arc::new(handle_u64_div)),
146 (U128_DIV_EVENT_NAME, Arc::new(handle_u128_div)),
147 (FALCON_DIV_EVENT_NAME, Arc::new(handle_falcon_div)),
148 (LOWERBOUND_ARRAY_EVENT_NAME, Arc::new(handle_lowerbound_array)),
149 (LOWERBOUND_KEY_VALUE_EVENT_NAME, Arc::new(handle_lowerbound_key_value)),
150 (AEAD_DECRYPT_EVENT_NAME, Arc::new(handle_aead_decrypt)),
151 (READONLY_MIDEN_DEBUG_FRAME_START, Arc::new(readonly_noop_handler)),
152 (READONLY_MIDEN_DEBUG_FRAME_END, Arc::new(readonly_noop_handler)),
153 (READONLY_MIDEN_DEBUG_ASSERTION_FAILED, Arc::new(readonly_noop_handler)),
154 (READONLY_MIDEN_DEBUG_UNKNOWN, Arc::new(readonly_noop_handler)),
155 (READONLY_MIDEN_DEBUG_PRINTLN, Arc::new(readonly_noop_handler)),
156 ]
157 }
158
159 pub fn verifier_registry(&self) -> PrecompileVerifierRegistry {
162 PrecompileVerifierRegistry::new()
163 .with_verifier(&KECCAK_HASH_BYTES_EVENT_NAME, Arc::new(KeccakPrecompile))
164 .with_verifier(&SHA512_HASH_BYTES_EVENT_NAME, Arc::new(Sha512Precompile))
165 .with_verifier(&ECDSA_VERIFY_EVENT_NAME, Arc::new(EcdsaPrecompile))
166 .with_verifier(&EDDSA25519_VERIFY_EVENT_NAME, Arc::new(EddsaPrecompile))
167 }
168}
169
170impl Default for CoreLibrary {
171 fn default() -> Self {
172 static CORELIB: LazyLock<CoreLibrary> = LazyLock::new(|| {
173 let contents = Library::read_from_bytes(CoreLibrary::SERIALIZED)
174 .expect("failed to read core masl!");
175 CoreLibrary(contents)
176 });
177 CORELIB.clone()
178 }
179}
180
181#[cfg(test)]
185mod tests {
186 use miden_assembly::Path;
187
188 use super::*;
189
190 #[test]
191 fn test_compile() {
192 let path = Path::new("::miden::core::math::u64::overflowing_add");
193 let core_lib = CoreLibrary::default();
194 let exists = core_lib.0.module_infos().any(|module| {
195 module.procedures().any(|(_, proc)| &module.path().join(&proc.name) == path)
196 });
197
198 assert!(exists);
199 }
200}