1#![no_std]
2
3pub mod dsa;
4pub mod handlers;
5
6extern crate alloc;
7
8use alloc::{sync::Arc, vec, vec::Vec};
9
10use miden_assembly::{Library, mast::MastForest};
11use miden_core::{
12 events::EventName, precompile::PrecompileVerifierRegistry, serde::Deserializable,
13};
14use miden_processor::{HostLibrary, event::EventHandler};
15use miden_utils_sync::LazyLock;
16
17use crate::handlers::{
18 aead_decrypt::{AEAD_DECRYPT_EVENT_NAME, handle_aead_decrypt},
19 ecdsa::{ECDSA_VERIFY_EVENT_NAME, EcdsaPrecompile},
20 eddsa_ed25519::{EDDSA25519_VERIFY_EVENT_NAME, EddsaPrecompile},
21 falcon_div::{FALCON_DIV_EVENT_NAME, handle_falcon_div},
22 keccak256::{KECCAK_HASH_BYTES_EVENT_NAME, KeccakPrecompile},
23 sha512::{SHA512_HASH_BYTES_EVENT_NAME, Sha512Precompile},
24 smt_peek::{SMT_PEEK_EVENT_NAME, handle_smt_peek},
25 sorted_array::{
26 LOWERBOUND_ARRAY_EVENT_NAME, LOWERBOUND_KEY_VALUE_EVENT_NAME, handle_lowerbound_array,
27 handle_lowerbound_key_value,
28 },
29 u64_div::{U64_DIV_EVENT_NAME, handle_u64_div},
30};
31
32#[derive(Clone)]
37pub struct CoreLibrary(Library);
38
39impl AsRef<Library> for CoreLibrary {
40 fn as_ref(&self) -> &Library {
41 &self.0
42 }
43}
44
45impl From<CoreLibrary> for Library {
46 fn from(value: CoreLibrary) -> Self {
47 value.0
48 }
49}
50
51impl From<&CoreLibrary> for HostLibrary {
52 fn from(core_lib: &CoreLibrary) -> Self {
53 Self {
54 mast_forest: core_lib.mast_forest().clone(),
55 handlers: core_lib.handlers(),
56 }
57 }
58}
59
60impl CoreLibrary {
61 pub const SERIALIZED: &'static [u8] =
63 include_bytes!(concat!(env!("OUT_DIR"), "/assets/core.masl"));
64
65 pub fn mast_forest(&self) -> &Arc<MastForest> {
67 self.0.mast_forest()
68 }
69
70 pub fn library(&self) -> &Library {
72 &self.0
73 }
74
75 pub fn handlers(&self) -> Vec<(EventName, Arc<dyn EventHandler>)> {
77 vec![
78 (KECCAK_HASH_BYTES_EVENT_NAME, Arc::new(KeccakPrecompile)),
79 (SHA512_HASH_BYTES_EVENT_NAME, Arc::new(Sha512Precompile)),
80 (ECDSA_VERIFY_EVENT_NAME, Arc::new(EcdsaPrecompile)),
81 (EDDSA25519_VERIFY_EVENT_NAME, Arc::new(EddsaPrecompile)),
82 (SMT_PEEK_EVENT_NAME, Arc::new(handle_smt_peek)),
83 (U64_DIV_EVENT_NAME, Arc::new(handle_u64_div)),
84 (FALCON_DIV_EVENT_NAME, Arc::new(handle_falcon_div)),
85 (LOWERBOUND_ARRAY_EVENT_NAME, Arc::new(handle_lowerbound_array)),
86 (LOWERBOUND_KEY_VALUE_EVENT_NAME, Arc::new(handle_lowerbound_key_value)),
87 (AEAD_DECRYPT_EVENT_NAME, Arc::new(handle_aead_decrypt)),
88 ]
89 }
90
91 pub fn verifier_registry(&self) -> PrecompileVerifierRegistry {
94 PrecompileVerifierRegistry::new()
95 .with_verifier(&KECCAK_HASH_BYTES_EVENT_NAME, Arc::new(KeccakPrecompile))
96 .with_verifier(&SHA512_HASH_BYTES_EVENT_NAME, Arc::new(Sha512Precompile))
97 .with_verifier(&ECDSA_VERIFY_EVENT_NAME, Arc::new(EcdsaPrecompile))
98 .with_verifier(&EDDSA25519_VERIFY_EVENT_NAME, Arc::new(EddsaPrecompile))
99 }
100}
101
102impl Default for CoreLibrary {
103 fn default() -> Self {
104 static STDLIB: LazyLock<CoreLibrary> = LazyLock::new(|| {
105 let contents = Library::read_from_bytes(CoreLibrary::SERIALIZED)
106 .expect("failed to read std masl!");
107 CoreLibrary(contents)
108 });
109 STDLIB.clone()
110 }
111}
112
113#[cfg(test)]
117mod tests {
118 use miden_assembly::Path;
119
120 use super::*;
121
122 #[test]
123 fn test_compile() {
124 let path = Path::new("::miden::core::math::u64::overflowing_add");
125 let core_lib = CoreLibrary::default();
126 let exists = core_lib.0.module_infos().any(|module| {
127 module.procedures().any(|(_, proc)| &module.path().join(&proc.name) == path)
128 });
129
130 assert!(exists);
131 }
132}