Skip to main content

miden_core_lib/
lib.rs

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// CORE LIBRARY
39// ================================================================================================
40
41/// The Miden core library, providing a set of optimized procedures for Miden programs.
42///
43/// This library wraps a [`Library`] containing highly-optimized and battle-tested implementations
44/// of commonly-used primitives. When the core library is dynamically linked during assembly time,
45/// procedures can be called from any Miden program and are serialized as 32 bytes, reducing the
46/// amount of code that needs to be shared between parties for proving and verifying program
47/// execution.
48///
49/// # Contents
50///
51/// The core library provides several categories of functionality:
52///
53/// - **Cryptographic primitives**: Hash functions (Keccak256, SHA-512), digital signature
54///   verification (ECDSA, EdDSA-Ed25519, Falcon), and authenticated encryption (AEAD decryption).
55/// - **Mathematical operations**: Division operations for u64, u128, and u256.
56/// - **Data structures**: Sparse Merkle Tree operations, Merkle Mountain Range (MMR), and sorted
57///   array utilities with lower-bound search capabilities.
58/// - **Memory operations**: Efficient hashing and "un-hashing" of large amounts of data.
59///
60/// Many of these operations are implemented as **precompiles** - special procedures that execute
61/// outside the Miden VM but are verified as part of the proof. Precompiles allow for efficient
62/// execution of complex operations that would be expensive to compute directly in the VM, while
63/// maintaining the security guarantees of the Miden proof system. The core library includes
64/// precompiles for cryptographic operations like hash functions and signature verification.
65///
66/// # Usage
67///
68/// The core library is typically used with an [`Assembler`] to enable core library procedures
69/// in compiled programs:
70///
71/// ```rust,ignore
72/// use miden_assembly::Assembler;
73/// use miden_core_lib::CoreLibrary;
74///
75/// let assembler = Assembler::new(source_manager)
76///     .with_dynamic_library(&CoreLibrary::default())
77///     .unwrap();
78/// ```
79///
80/// For program execution, you'll also need to register the event handlers:
81///
82/// ```rust,ignore
83/// let core_lib = CoreLibrary::default();
84/// let handlers = core_lib.handlers();
85/// // Register handlers with your host...
86/// ```
87///
88/// For proof verification, use [`verifier_registry()`](Self::verifier_registry) to get the
89/// precompile verifiers required to validate core library precompile requests.
90///
91/// [`Library`]: miden_assembly::Library
92/// [`Assembler`]: miden_assembly::Assembler
93#[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    /// Serialized representation of the Miden core library.
119    pub const SERIALIZED: &'static [u8] =
120        include_bytes!(concat!(env!("OUT_DIR"), "/assets/core.masl"));
121
122    /// Returns a reference to the [MastForest] underlying the Miden core library.
123    pub fn mast_forest(&self) -> &Arc<MastForest> {
124        self.0.mast_forest()
125    }
126
127    /// Returns a reference to the underlying [`Library`].
128    pub fn library(&self) -> &Library {
129        &self.0
130    }
131
132    /// List of all `EventHandlers` required to run all of the core library.
133    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    /// Returns a [`PrecompileVerifierRegistry`] containing all verifiers required to validate
150    /// core library precompile requests.
151    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// TESTS
172// ================================================================================================
173
174#[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}