Skip to main content

lib_q_core/
lib.rs

1//! lib-Q Core - Common types and traits for post-quantum cryptography
2//!
3//! This crate provides the foundational types, traits, and error handling
4//! used across all lib-Q crates.
5//!
6//! ## Context factories
7//!
8//! Core does not provide factories that depend on algorithm implementation crates (no cycles).
9//! For [`AeadContext`], use [`AeadContext::new`](crate::contexts::AeadContext::new),
10//! [`AeadContext::with_aead_operations`](crate::contexts::AeadContext::with_aead_operations), or
11//! [`AeadContext::with_provider`](crate::contexts::AeadContext::with_provider). The `lib-q-aead` crate supplies
12//! `LibQAeadProvider` for [`AeadContext::with_aead_operations`](crate::contexts::AeadContext::with_aead_operations); the umbrella `lib-q` crate exposes `libq::aead::context()` wired to that provider.
13
14#![cfg_attr(not(feature = "std"), no_std)]
15#![deny(unsafe_code)]
16#![deny(unused_qualifications)]
17
18#[cfg(feature = "alloc")]
19extern crate alloc;
20
21pub mod algorithm_registry;
22pub mod api;
23pub mod error;
24pub mod traits;
25pub mod wasm_common;
26
27// New modular architecture
28#[cfg(feature = "alloc")]
29pub mod aead_semantic;
30#[cfg(feature = "alloc")]
31pub mod contexts;
32#[cfg(feature = "alloc")]
33pub mod providers;
34#[cfg(feature = "alloc")]
35pub mod security;
36
37// WASM bindings
38#[cfg(feature = "wasm")]
39pub mod wasm;
40
41// Re-exports
42#[cfg(feature = "alloc")]
43pub use aead_semantic::{
44    AeadDecryptSemantic,
45    DecryptSemanticOutcome,
46};
47pub use algorithm_registry::*;
48pub use api::*;
49#[cfg(feature = "alloc")]
50pub use contexts::{
51    AeadContext,
52    HashContext,
53    KemContext,
54    SignatureContext,
55};
56pub use error::{
57    Error,
58    HexDecodeError,
59    Result,
60};
61// Re-export new modular components
62#[cfg(feature = "alloc")]
63pub use providers::LibQCryptoProvider;
64#[cfg(feature = "alloc")]
65pub use security::SecurityValidator;
66pub use traits::*;
67#[cfg(feature = "wasm")]
68pub use wasm::*;
69
70// Constants
71pub const VERSION: &str = env!("CARGO_PKG_VERSION");
72
73/// Initialize the core library
74pub fn init() -> Result<()> {
75    Ok(())
76}
77
78/// Get library version information
79pub fn version() -> &'static str {
80    VERSION
81}
82
83/// Create a new hash context with no provider installed.
84///
85/// Call [`HashContext::set_provider`] or use [`HashContext::with_provider`] before
86/// [`HashContext::hash`] will succeed. Leaf crates (for example `lib-q-hash`) and the
87/// `libq` umbrella expose factories that install a hash implementation up front.
88#[cfg(feature = "alloc")]
89pub fn create_hash_context() -> HashContext {
90    HashContext::new()
91}
92
93/// Create a new KEM context
94#[cfg(feature = "alloc")]
95pub fn create_kem_context() -> KemContext {
96    KemContext::new()
97}
98
99/// Create a new signature context
100#[cfg(feature = "alloc")]
101pub fn create_signature_context() -> SignatureContext {
102    SignatureContext::new()
103}
104
105#[cfg(all(not(feature = "std"), feature = "no_std_panic_handler"))]
106mod no_std_panic_handler {
107    use core::panic::PanicInfo;
108
109    #[panic_handler]
110    #[allow(clippy::empty_loop)]
111    fn panic(_info: &PanicInfo) -> ! {
112        loop {}
113    }
114}
115
116#[cfg(test)]
117mod tests {
118    use super::*;
119
120    #[test]
121    fn test_init() {
122        assert!(init().is_ok());
123    }
124
125    #[test]
126    fn test_version() {
127        assert!(!version().is_empty());
128        assert_eq!(version(), VERSION);
129    }
130
131    #[test]
132    fn test_no_std_compatibility() {
133        #[cfg(not(feature = "std"))]
134        use alloc::string::ToString;
135
136        // Test that core functionality works in no_std mode
137        let error = Error::InvalidKeySize {
138            expected: 32,
139            actual: 16,
140        };
141        assert_eq!(error.to_string(), "Invalid key size: expected 32, got 16");
142
143        // Test that we can create basic structures
144        #[cfg(feature = "alloc")]
145        {
146            let public_key = KemPublicKey::new(vec![1, 2, 3, 4]);
147            assert_eq!(public_key.as_bytes(), &[1, 2, 3, 4]);
148
149            let secret_key = KemSecretKey::new(vec![5, 6, 7, 8]);
150            assert_eq!(secret_key.as_bytes(), &[5, 6, 7, 8]);
151        }
152    }
153}