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