// JUSTIFICATION: Some cryptographic dependencies (fn-dsa, fips205) instantiate large
// const arrays internally. In test builds these get monomorphized into the crate,
// triggering large_stack_arrays. The arrays are in dependency code, not ours.
#![cfg_attr(test, allow(clippy::large_stack_arrays))]
//! LatticeArc - Post-Quantum Cryptography Library
//!
//! Post-quantum cryptography on the aws-lc-rs FIPS 140-3 backend. Hybrid
//! ML-KEM+X25519 by default, all 4 NIST PQC standards (FIPS 203–206) — one
//! crate, zero unsafe. For PQ TLS, use rustls 0.23.37+ with `aws-lc-rs`
//! directly; this crate does not wrap rustls.
//!
//! > **IMPORTANT — FIPS terminology:** this crate distinguishes *algorithm
//! > conformance* (implementing the NIST specs FIPS 203/204/205/206) from
//! > *module validation* (FIPS 140-3 CMVP certification of a cryptographic
//! > module). LatticeArc implements the algorithms for all four standards but
//! > is **not itself CMVP-validated**. With `--features fips`, AES-GCM,
//! > ML-KEM, HKDF, and SHA-2 are routed through the FIPS 140-3 validated
//! > aws-lc-rs backend. ML-DSA (`fips204`), SLH-DSA (`fips205`), and FN-DSA
//! > (`fn-dsa`) are NIST-conformant but use non-validated crate
//! > implementations regardless of feature flags.
//!
//! ## Why LatticeArc?
//!
//! | Without LatticeArc | With LatticeArc |
//! |--------------------|-----------------|
//! | ~50 lines for hybrid encrypt | 3 lines |
//! | Manage 4 key vectors manually | Single [`EncryptKey::Hybrid`] |
//! | Research NIST parameter sets | [`UseCase`] auto-selects |
//! | Manual secret zeroization | Automatic via `Zeroize` |
//!
//! ## Known limitations
//!
//! - **No streaming AEAD API.** All `encrypt` / `decrypt` entry points
//! operate on whole-message buffers. For very large payloads (multi-GiB
//! files, network streams), partition into chunks at the application
//! layer and bind chunk-index + total-count into the AEAD additional
//! authenticated data so the per-chunk tags compose into a single
//! document tag. A native streaming API is on the roadmap; not in 0.8.
//! - **No async API.** Cryptographic functions are blocking. They run in
//! microseconds-to-low-milliseconds and don't interact with I/O, so
//! wrapping them in `tokio::task::spawn_blocking` is the recommended
//! integration pattern. A native async API is not planned because the
//! added complexity is rarely worth the wins given the latency profile.
//!
//! ## Algorithm Validation Status
//!
//! | Algorithm | Standard | Backend | FIPS Validated |
//! |-----------|----------|---------|----------------|
//! | ML-KEM | FIPS 203 | aws-lc-rs | Yes |
//! | AES-256-GCM | SP 800-38D | aws-lc-rs | Yes |
//! | HKDF-SHA256 | SP 800-56C | aws-lc-rs | Yes |
//! | SHA-256 | FIPS 180-4 | aws-lc-rs | Yes |
//! | ML-DSA | FIPS 204 | fips204 | No |
//! | SLH-DSA | FIPS 205 | fips205 | No |
//! | FN-DSA | FIPS 206 (draft / Falcon) | fn-dsa | No |
//!
//! ## Unified API with CryptoConfig
//!
//! All cryptographic operations use [`CryptoConfig`] for configuration. This builder
//! pattern provides automatic algorithm selection based on use case or security level,
//! with optional Zero Trust session verification.
//!
//! ### Basic Usage (Hybrid — Recommended)
//!
//! ```rust,no_run
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use latticearc::{encrypt, decrypt, CryptoConfig, EncryptKey, DecryptKey};
//!
//! // Hybrid encryption: ML-KEM-768 + X25519 + HKDF + AES-256-GCM
//! let (pk, sk) = latticearc::generate_hybrid_keypair()?;
//! let encrypted = encrypt(b"secret", EncryptKey::Hybrid(&pk), CryptoConfig::new())?;
//! let decrypted = decrypt(&encrypted, DecryptKey::Hybrid(&sk), CryptoConfig::new())?;
//! # Ok(())
//! # }
//! ```
//!
//! ### PQ-Only Encryption (0.6.0+)
//!
//! Use [`CryptoMode::PqOnly`] for pure post-quantum encryption without a classical
//! component. Required for CNSA 2.0 compliance.
//!
//! ```rust,no_run
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use latticearc::{encrypt, decrypt, CryptoConfig, CryptoMode, EncryptKey, DecryptKey};
//!
//! // PQ-only: ML-KEM-768 + HKDF + AES-256-GCM (no X25519)
//! let (pk, sk) = latticearc::generate_pq_keypair()
//! .map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?;
//! let config = CryptoConfig::new().crypto_mode(CryptoMode::PqOnly);
//! let encrypted = encrypt(b"secret", EncryptKey::PqOnly(&pk), config.clone())?;
//! let decrypted = decrypt(&encrypted, DecryptKey::PqOnly(&sk), config)?;
//! # Ok(())
//! # }
//! ```
//!
//! For low-level access to the PQ-only ciphertext components, use
//! [`PqOnlyCiphertext`](hybrid::pq_only::PqOnlyCiphertext) getters or `into_parts()`.
//! To convert a hybrid scheme to its PQ-only equivalent at the same NIST level:
//! [`EncryptionScheme::to_pq_equivalent()`].
//!
//! ## Digital Signatures
//!
//! ```rust,no_run
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use latticearc::{generate_signing_keypair, sign_with_key, verify, CryptoConfig};
//!
//! let message = b"Document to sign";
//!
//! // Generate a persistent signing keypair (ML-DSA-65 + Ed25519 hybrid)
//! let (pk, sk, scheme) = generate_signing_keypair(CryptoConfig::new())?;
//!
//! // Sign with the persistent keypair
//! let signed = sign_with_key(message, &sk, &pk, CryptoConfig::new())?;
//!
//! // Verify (uses public key embedded in SignedData)
//! let is_valid = verify(&signed, CryptoConfig::new())?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Feature Flags
//!
//! | Feature | Description |
//! |---------|-------------|
//! | `fips` | FIPS 140-3 validated backend via aws-lc-rs. Requires CMake + Go build tools. Without this feature, aws-lc-rs uses its default non-FIPS backend (C compiler only). Transitively enables `fips-self-test`. |
//! | `fips-self-test` | Power-up KAT self-tests (ML-KEM via aws-lc-rs, AES-GCM, SHA-3, ML-DSA, SLH-DSA, FN-DSA). Pulled in transitively by `fips`; can be enabled standalone for non-FIPS builds that still want POST coverage. |
//! | `tracing-init` | Subscriber/init helpers (`init_tracing`, `init_tracing_with_file`) for the `tracing` facade. Off by default so downstream binaries that wire their own subscriber don't fight ours. The `latticearc-cli` binary enables this. |
//! | `zkp-serde` | Serialization support for ZKP types (enables `serde_with` for Schnorr/Sigma protocol structs). |
//! | `secret-mlock` | OS-level memory locking for `SecretVec` (Secret Type Invariant I-10). Uses `mlock(2)` on Linux/macOS via `region`. **No-op on Windows** — `VirtualLock` is documented as best-effort and `VirtualUnlock`'s `ERROR_NOT_LOCKED` path causes a `panic = "abort"` build to abort the process; the this feature off on Windows targets so the cfg evaluates `false` regardless of the feature flag. Default-off because `RLIMIT_MEMLOCK` can fail at constructor time on some deployments. |
//! | `kat-test-vectors` | Exposes `AeadCipher::new_allow_weak_key` (AES-GCM Test Cases 1/2 reproducer). Default-off so production builds cannot construct weak-key ciphers. |
//! | `test-utils` | Exposes FIPS module-error-state recovery helpers (`clear_error_state`, `restore_operational_state`) for negative tests that need to recover global state without re-running POST. FIPS 140-3 §9.6 state-machine bypass — must NOT be enabled in production builds. Default-off. (Note: earlier rounds listed `SigmaProof::challenge_mut` here. M3 narrowed it to `#[cfg(test)]` — strictly narrower than `test-utils` — so downstream consumers **cannot** acquire the soundness-bypass mutator by enabling this feature. The mutator is reachable only from in-tree lib unit tests.) |
//! | `kat-replay` | Exposes legitimate KAT-replay entry points that bypass operator parameter floors but NOT cryptographic soundness checks. Currently: `pbkdf2_kat` (replays RFC 6070 / NIST CAVP fixtures with sub-OWASP iteration counts; DoS cap and PRF correctness still enforced). The CLI enables this for `kdf --allow-weak-iterations`. Distinct from `test-utils`; safe to ship to consumers that need vector replay. Default-off. |
//! | `formal-verification` | Compilation marker: enables formal verification harness code (Kani proofs). Does not run proofs — use `cargo kani` separately. |
//! | `kani` | Compilation marker: enables Kani bounded model checking proof harnesses. Requires `cargo kani` to execute proofs. |
//! | `saw` | Compilation marker: enables SAW formal verification markers (inherited from aws-lc-rs). Does not run SAW proofs at build time. |
//!
//! ## More Examples
//!
//! ### Symmetric Encryption
//!
//! ```rust,no_run
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use latticearc::{encrypt, decrypt, CryptoConfig, CryptoScheme, EncryptKey, DecryptKey};
//! use latticearc::primitives::rand::random_bytes;
//!
//! // Generate a fresh 256-bit key from the OS CSPRNG. Never use a constant
//! // (e.g. `[0u8; 32]`) — AEAD constructors reject all-zero keys per the
//! // McGrew/Viega NIST AES-GCM Test Cases 1 and 2 weak-key check.
//! let key = random_bytes(32);
//! let encrypted = encrypt(b"secret", EncryptKey::Symmetric(&key),
//! CryptoConfig::new().force_scheme(CryptoScheme::Symmetric))?;
//! let decrypted = decrypt(&encrypted, DecryptKey::Symmetric(&key), CryptoConfig::new())?;
//! # Ok(())
//! # }
//! ```
//!
//! ### With Use Case Selection
//!
//! ```rust,no_run
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use latticearc::{encrypt, CryptoConfig, UseCase, EncryptKey};
//! use latticearc::generate_hybrid_keypair_with_level;
//! use latticearc::primitives::kem::ml_kem::MlKemSecurityLevel;
//!
//! // FileStorage resolves to ML-KEM-1024 (Level 5), so the keypair MUST
//! // be generated at the matching level. `generate_hybrid_keypair()`
//! // defaults to ML-KEM-768 and would be rejected by
//! // `validate_key_matches_scheme`.
//! let (pk, _sk) = generate_hybrid_keypair_with_level(MlKemSecurityLevel::MlKem1024)?;
//! let encrypted = encrypt(b"data", EncryptKey::Hybrid(&pk),
//! CryptoConfig::new().use_case(UseCase::FileStorage))?;
//! # Ok(())
//! # }
//! ```
//!
//! ### Zero Trust Session Verification
//!
//! For production deployments, use [`VerifiedSession`] to enable Zero Trust
//! verification before each operation:
//!
//! ```rust,no_run
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use latticearc::{
//! encrypt, decrypt, CryptoConfig, VerifiedSession, generate_keypair,
//! EncryptKey, DecryptKey,
//! };
//!
//! // Step 1: Generate a keypair (done once, typically at provisioning)
//! let (pk, sk) = generate_keypair()?;
//!
//! // Step 2: Establish a verified session (performs challenge-response)
//! let session = VerifiedSession::establish(pk.as_slice(), sk.expose_secret())?;
//!
//! // Step 3: Hybrid encryption with session verification
//! let (enc_pk, enc_sk) = latticearc::generate_hybrid_keypair()?;
//! let encrypted = encrypt(b"secret", EncryptKey::Hybrid(&enc_pk),
//! CryptoConfig::new().session(&session))?;
//! let decrypted = decrypt(&encrypted, DecryptKey::Hybrid(&enc_sk),
//! CryptoConfig::new().session(&session))?;
//! # Ok(())
//! # }
//! ```
//!
//! ### Hybrid Encryption (ML-KEM-768 + X25519)
//!
//! Use the unified API with `EncryptKey::Hybrid` / `DecryptKey::Hybrid`:
//!
//! ```rust,no_run
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use latticearc::{encrypt, decrypt, CryptoConfig, EncryptKey, DecryptKey};
//!
//! let (pk, sk) = latticearc::generate_hybrid_keypair()?;
//! let encrypted = encrypt(b"secret data", EncryptKey::Hybrid(&pk), CryptoConfig::new())?;
//! let decrypted = decrypt(&encrypted, DecryptKey::Hybrid(&sk), CryptoConfig::new())?;
//! # Ok(())
//! # }
//! ```
//!
//! ### Hybrid Signatures (ML-DSA-65 + Ed25519)
//!
//! ```rust,no_run
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use latticearc::{generate_hybrid_signing_keypair, sign_hybrid, verify_hybrid_signature, SecurityMode};
//!
//! // Generate a hybrid signing keypair (ML-DSA-65 + Ed25519)
//! let (pk, sk) = generate_hybrid_signing_keypair(SecurityMode::Unverified)?;
//!
//! // Sign (both ML-DSA and Ed25519 signatures generated)
//! let signature = sign_hybrid(b"document", &sk, SecurityMode::Unverified)?;
//!
//! // Verify (both must pass for signature to be valid)
//! let valid = verify_hybrid_signature(b"document", &signature, &pk, SecurityMode::Unverified)?;
//! # Ok(())
//! # }
//! ```
//!
//! ### Session Lifecycle
//!
//! Sessions have a 30-minute default lifetime:
//!
//! ```rust,no_run
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use latticearc::{encrypt, CryptoConfig, VerifiedSession, generate_keypair, CoreError, EncryptKey};
//!
//! let (pk, sk) = generate_keypair()?;
//! let session = VerifiedSession::establish(pk.as_slice(), sk.expose_secret())?;
//!
//! // Check session properties
//! assert!(session.is_valid()); // Not expired
//! let _ = session.session_id(); // Unique ID for audit
//! let _ = session.expires_at(); // Expiration time
//!
//! // Validate before critical operations
//! session.verify_valid()?; // Returns Err(SessionExpired) if expired
//!
//! // Refresh if expired
//! if !session.is_valid() {
//! let new_session = VerifiedSession::establish(pk.as_slice(), sk.expose_secret())?;
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ### Complete Example
//!
//! ```rust,no_run
//! use latticearc::{
//! encrypt, decrypt, generate_signing_keypair, sign_with_key, verify,
//! generate_hybrid_keypair, CryptoConfig, CoreError,
//! EncryptKey, DecryptKey,
//! };
//!
//! fn secure_workflow() -> Result<(), CoreError> {
//! // --- Hybrid Encryption (unified API) ---
//! let (enc_pk, enc_sk) = generate_hybrid_keypair()?;
//! let encrypted = encrypt(b"confidential", EncryptKey::Hybrid(&enc_pk),
//! CryptoConfig::new())?;
//! let decrypted = decrypt(&encrypted, DecryptKey::Hybrid(&enc_sk),
//! CryptoConfig::new())?;
//!
//! // --- Digital Signatures ---
//! let (sign_pk, sign_sk, _scheme) = generate_signing_keypair(CryptoConfig::new())?;
//! let signed = sign_with_key(b"important document", &sign_sk, &sign_pk, CryptoConfig::new())?;
//! let is_valid = verify(&signed, CryptoConfig::new())?;
//! assert!(is_valid);
//!
//! Ok(())
//! }
//! ```
//!
// ============================================================================
// Module Declarations
// ============================================================================
/// Pure-Rust domain types, traits, configuration, and policy engine.
pub mod types;
/// Common prelude with error handling, domain constants, and testing infrastructure.
pub mod prelude;
/// Core cryptographic primitives (KEM, signatures, AEAD, hash, KDF, MAC).
pub mod primitives;
/// Hybrid cryptography combining post-quantum and classical algorithms.
pub mod hybrid;
/// Unified cryptographic API with Zero-Trust security.
pub mod unified_api;
/// Zero-knowledge proof primitives (Schnorr, Sigma protocols, Pedersen commitments).
/// Non-FIPS: uses non-approved EC operations.
#[cfg(not(feature = "fips"))]
pub mod zkp;
/// Performance monitoring and benchmarking utilities.
pub mod perf;
// ============================================================================
// Backward-compatible module aliases
// ============================================================================
/// Backward-compatible alias for [`unified_api`].
///
/// New code should reach types through the canonical paths
/// (`latticearc::Foo` flat re-exports below, or
/// `latticearc::unified_api::Foo`). The `latticearc::core` alias
/// dates from a pre-0.7 module rename and is retained only so
/// integrations carrying `use latticearc::core::*;` keep compiling.
/// The alias is scheduled for removal pre-1.0.
#[doc(hidden)]
#[deprecated(
since = "0.8.0",
note = "use `latticearc::unified_api` (or the flat `latticearc::*` re-exports) instead; \
the `core` alias is scheduled for removal pre-1.0"
)]
pub use unified_api as core;
// Explicit re-export of LatticeArcError for error compatibility.
// All other prelude types are accessible via `latticearc::prelude::*`.
pub use prelude::LatticeArcError;
// ============================================================================
// Core Types
// ============================================================================
pub use unified_api::{
// Algorithm selection types
AlgorithmSelection,
Challenge,
// Compliance
ComplianceMode,
ContinuousSession,
// Traits
ContinuousVerifiable,
// Types
CoreError,
// Unified configuration for cryptographic operations
CryptoConfig,
CryptoContext,
// Cryptographic mode (hybrid vs PQ-only)
CryptoMode,
CryptoPayload,
CryptoScheme,
DataCharacteristics,
// Type-safe encryption key types (no silent degradation)
DecryptKey,
EncryptKey,
EncryptedData,
EncryptedMetadata,
// Type-safe encrypted output (replaces string-based scheme dispatch)
EncryptedOutput,
EncryptionScheme,
HashOutput,
// Hybrid encryption components (ML-KEM ciphertext + ECDH ephemeral key)
HybridComponents,
KeyPair,
PatternType,
PerformancePreference,
PrivateKey,
ProofOfPossession,
ProofOfPossessionData,
PublicKey,
// ⚠ NOTE: this `Result<T>` is the project alias `Result<T, CoreError>`,
// NOT `std::result::Result<T, E>`. A `use latticearc::*;` glob will
// SHADOW the std type alias in the importing module. If you need both,
// either (a) avoid the glob: `use latticearc::{encrypt, decrypt...};`,
// or (b) re-import std after: `use std::result::Result as StdResult;`.
Result,
SchemeSelector,
SecretBytes,
SecretVec,
SecurityLevel,
// Zero Trust types
SecurityMode,
SignedData,
SignedMetadata,
SymmetricKey,
TrustLevel,
UseCase,
// Constants
VERSION,
VerificationStatus,
VerifiedSession,
ZeroKnowledgeProof,
ZeroTrustAuth,
ZeroTrustAuthenticable,
ZeroTrustSession,
// Compile-time feature detection
fips_available,
// Initialization
init,
init_with_config,
};
// PQ-only key types and key generation
pub use hybrid::pq_only::{
PqOnlyPublicKey, PqOnlySecretKey, generate_pq_keypair, generate_pq_keypair_with_level,
};
// Hybrid types — re-exported from `hybrid::{kem_hybrid, sig_hybrid, encrypt_hybrid}`
// so consumers can name them via the public crate path
// (`latticearc::HybridKemPublicKey`) instead of the internal module path
// (`latticearc::hybrid::kem_hybrid::HybridKemPublicKey`). The `generate_*`
// constructors are already re-exported below; without these type re-exports
// callers can't write function signatures or struct fields that hold the
// returned values without referencing the internal path.
pub use hybrid::encrypt_hybrid::{DerivationBinding, HybridCiphertext, HybridEncryptionError};
pub use hybrid::kem_hybrid::{
EncapsulatedKey, HybridKemError, HybridKemPublicKey, HybridKemSecretKey,
};
pub use hybrid::sig_hybrid::{
HybridSigPublicKey, HybridSigSecretKey, HybridSignature, HybridSignatureError,
};
// ============================================================================
// Unified API (Recommended)
// ============================================================================
// Single entry points for all cryptographic operations
pub use unified_api::{decrypt, encrypt, generate_signing_keypair, sign_with_key, verify};
// Hybrid key generation (ML-KEM + X25519)
pub use unified_api::{generate_hybrid_keypair, generate_hybrid_keypair_with_level};
// Hybrid signatures (ML-DSA-65 + Ed25519)
pub use unified_api::{
generate_hybrid_signing_keypair, generate_hybrid_signing_keypair_with_config, sign_hybrid,
sign_hybrid_with_config, verify_hybrid_signature, verify_hybrid_signature_with_config,
};
// Key generation (no SecurityMode needed - creates credentials)
#[doc(hidden)]
pub use unified_api::{
generate_fn_dsa_keypair, generate_fn_dsa_keypair_with_config,
generate_fn_dsa_keypair_with_level, generate_keypair, generate_keypair_with_config,
generate_ml_dsa_keypair, generate_ml_dsa_keypair_with_config, generate_ml_kem_keypair,
generate_ml_kem_keypair_with_config, generate_slh_dsa_keypair,
generate_slh_dsa_keypair_with_config,
};
// Hashing (hash_data is stateless, others use SecurityMode)
#[doc(hidden)]
pub use unified_api::{
derive_key, derive_key_with_config, derive_key_with_info, hash_data, hmac, hmac_check,
hmac_check_with_config, hmac_with_config,
};
// AES-GCM
#[doc(hidden)]
pub use unified_api::{
decrypt_aes_gcm, decrypt_aes_gcm_with_aad, decrypt_aes_gcm_with_config, encrypt_aes_gcm,
encrypt_aes_gcm_with_aad, encrypt_aes_gcm_with_config,
};
// Ed25519
#[doc(hidden)]
pub use unified_api::{
sign_ed25519, sign_ed25519_with_config, verify_ed25519, verify_ed25519_with_config,
};
// Post-Quantum KEM (ML-KEM)
#[doc(hidden)]
pub use unified_api::{
decrypt_pq_ml_kem, decrypt_pq_ml_kem_with_config, encrypt_pq_ml_kem,
encrypt_pq_ml_kem_with_config,
};
// Post-Quantum Signatures (ML-DSA, SLH-DSA, FN-DSA)
#[doc(hidden)]
pub use unified_api::{
sign_pq_fn_dsa, sign_pq_fn_dsa_with_config, sign_pq_ml_dsa, sign_pq_ml_dsa_with_config,
sign_pq_slh_dsa, sign_pq_slh_dsa_with_config, verify_pq_fn_dsa, verify_pq_fn_dsa_with_config,
verify_pq_ml_dsa, verify_pq_ml_dsa_with_config, verify_pq_slh_dsa,
verify_pq_slh_dsa_with_config,
};
// ============================================================================
// Low-Level Unverified Variants (for primitives)
// ============================================================================
#[doc(hidden)]
pub use unified_api::{
// AES-GCM
decrypt_aes_gcm_unverified,
decrypt_aes_gcm_with_aad_unverified,
decrypt_aes_gcm_with_config_unverified,
// PQ KEM
decrypt_pq_ml_kem_unverified,
decrypt_pq_ml_kem_with_config_unverified,
// Hashing
derive_key_unverified,
derive_key_with_config_unverified,
derive_key_with_info_unverified,
encrypt_aes_gcm_unverified,
encrypt_aes_gcm_with_aad_unverified,
encrypt_aes_gcm_with_config_unverified,
encrypt_pq_ml_kem_unverified,
encrypt_pq_ml_kem_with_config_unverified,
// Hybrid Signatures (ML-DSA-65 + Ed25519)
generate_hybrid_signing_keypair_unverified,
hmac_check_unverified,
hmac_check_with_config_unverified,
hmac_unverified,
hmac_with_config_unverified,
// Ed25519
sign_ed25519_unverified,
sign_ed25519_with_config_unverified,
sign_hybrid_unverified,
// PQ Signatures
sign_pq_fn_dsa_unverified,
sign_pq_fn_dsa_with_config_unverified,
sign_pq_ml_dsa_unverified,
sign_pq_ml_dsa_with_config_unverified,
sign_pq_slh_dsa_unverified,
sign_pq_slh_dsa_with_config_unverified,
verify_ed25519_unverified,
verify_ed25519_with_config_unverified,
verify_hybrid_signature_unverified,
verify_pq_fn_dsa_unverified,
verify_pq_fn_dsa_with_config_unverified,
verify_pq_ml_dsa_unverified,
verify_pq_ml_dsa_with_config_unverified,
verify_pq_slh_dsa_unverified,
verify_pq_slh_dsa_with_config_unverified,
};
// ============================================================================
// Serialization Utilities
// ============================================================================
//
// `#[doc(hidden)]` on these six fns was internally inconsistent —
// `docs/API_DOCUMENTATION.md` directs users at them as part of the
// public surface. Hidden marker removed; these are now first-class
// public API. If we ever need to walk this back, drop the public
// reference in the docs first.
pub use unified_api::serialization::{
deserialize_encrypted_output, deserialize_keypair, deserialize_signed_data,
serialize_encrypted_output, serialize_keypair, serialize_signed_data,
};
// ============================================================================
// Portable Key Format
// ============================================================================
pub use unified_api::key_format::{KeyAlgorithm, KeyData, KeyType, PortableKey};
// ============================================================================
// Zeroize re-export
// ============================================================================
//
// Re-export `Zeroizing` so downstream consumers (including our own tests)
// can name the wrapper type returned by `decrypt()` without needing to add
// `zeroize` as a separate dependency.
pub use zeroize::Zeroizing;