Skip to main content

miden_core_lib/
lib.rs

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    u128_div::{U128_DIV_EVENT_NAME, handle_u128_div},
31};
32
33// CORE LIBRARY
34// ================================================================================================
35
36/// The Miden core library, providing a set of optimized procedures for Miden programs.
37///
38/// This library wraps a [`Library`] containing highly-optimized and battle-tested implementations
39/// of commonly-used primitives. When the core library is dynamically linked during assembly time,
40/// procedures can be called from any Miden program and are serialized as 32 bytes, reducing the
41/// amount of code that needs to be shared between parties for proving and verifying program
42/// execution.
43///
44/// # Contents
45///
46/// The core library provides several categories of functionality:
47///
48/// - **Cryptographic primitives**: Hash functions (Keccak256, SHA-512), digital signature
49///   verification (ECDSA, EdDSA-Ed25519, Falcon), and authenticated encryption (AEAD decryption).
50/// - **Mathematical operations**: Division operations for u64, u128, and u256.
51/// - **Data structures**: Sparse Merkle Tree operations, Merkle Mountain Range (MMR), and sorted
52///   array utilities with lower-bound search capabilities.
53/// - **Memory operations**: Efficient hashing and "un-hashing" of large amounts of data.
54///
55/// Many of these operations are implemented as **precompiles** - special procedures that execute
56/// outside the Miden VM but are verified as part of the proof. Precompiles allow for efficient
57/// execution of complex operations that would be expensive to compute directly in the VM, while
58/// maintaining the security guarantees of the Miden proof system. The core library includes
59/// precompiles for cryptographic operations like hash functions and signature verification.
60///
61/// # Usage
62///
63/// The core library is typically used with an [`Assembler`] to enable core library procedures
64/// in compiled programs:
65///
66/// ```rust,ignore
67/// use miden_assembly::Assembler;
68/// use miden_core_lib::CoreLibrary;
69///
70/// let assembler = Assembler::new(source_manager)
71///     .with_dynamic_library(&CoreLibrary::default())
72///     .unwrap();
73/// ```
74///
75/// For program execution, you'll also need to register the event handlers:
76///
77/// ```rust,ignore
78/// let core_lib = CoreLibrary::default();
79/// let handlers = core_lib.handlers();
80/// // Register handlers with your host...
81/// ```
82///
83/// For proof verification, use [`verifier_registry()`](Self::verifier_registry) to get the
84/// precompile verifiers required to validate core library precompile requests.
85///
86/// [`Library`]: miden_assembly::Library
87/// [`Assembler`]: miden_assembly::Assembler
88#[derive(Clone)]
89pub struct CoreLibrary(Library);
90
91impl AsRef<Library> for CoreLibrary {
92    fn as_ref(&self) -> &Library {
93        &self.0
94    }
95}
96
97impl From<CoreLibrary> for Library {
98    fn from(value: CoreLibrary) -> Self {
99        value.0
100    }
101}
102
103impl From<&CoreLibrary> for HostLibrary {
104    fn from(core_lib: &CoreLibrary) -> Self {
105        Self {
106            mast_forest: core_lib.mast_forest().clone(),
107            handlers: core_lib.handlers(),
108        }
109    }
110}
111
112impl CoreLibrary {
113    /// Serialized representation of the Miden core library.
114    pub const SERIALIZED: &'static [u8] =
115        include_bytes!(concat!(env!("OUT_DIR"), "/assets/core.masl"));
116
117    /// Returns a reference to the [MastForest] underlying the Miden core library.
118    pub fn mast_forest(&self) -> &Arc<MastForest> {
119        self.0.mast_forest()
120    }
121
122    /// Returns a reference to the underlying [`Library`].
123    pub fn library(&self) -> &Library {
124        &self.0
125    }
126
127    /// List of all `EventHandlers` required to run all of the core library.
128    pub fn handlers(&self) -> Vec<(EventName, Arc<dyn EventHandler>)> {
129        vec![
130            (KECCAK_HASH_BYTES_EVENT_NAME, Arc::new(KeccakPrecompile)),
131            (SHA512_HASH_BYTES_EVENT_NAME, Arc::new(Sha512Precompile)),
132            (ECDSA_VERIFY_EVENT_NAME, Arc::new(EcdsaPrecompile)),
133            (EDDSA25519_VERIFY_EVENT_NAME, Arc::new(EddsaPrecompile)),
134            (SMT_PEEK_EVENT_NAME, Arc::new(handle_smt_peek)),
135            (U64_DIV_EVENT_NAME, Arc::new(handle_u64_div)),
136            (U128_DIV_EVENT_NAME, Arc::new(handle_u128_div)),
137            (FALCON_DIV_EVENT_NAME, Arc::new(handle_falcon_div)),
138            (LOWERBOUND_ARRAY_EVENT_NAME, Arc::new(handle_lowerbound_array)),
139            (LOWERBOUND_KEY_VALUE_EVENT_NAME, Arc::new(handle_lowerbound_key_value)),
140            (AEAD_DECRYPT_EVENT_NAME, Arc::new(handle_aead_decrypt)),
141        ]
142    }
143
144    /// Returns a [`PrecompileVerifierRegistry`] containing all verifiers required to validate
145    /// core library precompile requests.
146    pub fn verifier_registry(&self) -> PrecompileVerifierRegistry {
147        PrecompileVerifierRegistry::new()
148            .with_verifier(&KECCAK_HASH_BYTES_EVENT_NAME, Arc::new(KeccakPrecompile))
149            .with_verifier(&SHA512_HASH_BYTES_EVENT_NAME, Arc::new(Sha512Precompile))
150            .with_verifier(&ECDSA_VERIFY_EVENT_NAME, Arc::new(EcdsaPrecompile))
151            .with_verifier(&EDDSA25519_VERIFY_EVENT_NAME, Arc::new(EddsaPrecompile))
152    }
153}
154
155impl Default for CoreLibrary {
156    fn default() -> Self {
157        static CORELIB: LazyLock<CoreLibrary> = LazyLock::new(|| {
158            let contents = Library::read_from_bytes(CoreLibrary::SERIALIZED)
159                .expect("failed to read core masl!");
160            CoreLibrary(contents)
161        });
162        CORELIB.clone()
163    }
164}
165
166// TESTS
167// ================================================================================================
168
169#[cfg(test)]
170mod tests {
171    use miden_assembly::Path;
172
173    use super::*;
174
175    #[test]
176    fn test_compile() {
177        let path = Path::new("::miden::core::math::u64::overflowing_add");
178        let core_lib = CoreLibrary::default();
179        let exists = core_lib.0.module_infos().any(|module| {
180            module.procedures().any(|(_, proc)| &module.path().join(&proc.name) == path)
181        });
182
183        assert!(exists);
184    }
185}