Cypheron Core
IMPORTANT DEVELOPMENT STATUS NOTICE
This library is currently in ACTIVE DEVELOPMENT (v0.1.0) and is EXPERIMENTAL.
This is a Rust wrapper around official NIST reference implementations - not custom cryptography. The core algorithms are NIST-certified, but the Rust integration layer has NOT undergone:
- Independent security audits of FFI bindings
- Formal verification of memory safety wrappers
- Production environment validation
DO NOT USE IN PRODUCTION without comprehensive integration review and testing.
Risk areas: FFI safety, memory management, build system - NOT the underlying NIST algorithms.
Post-quantum cryptography library implementing NIST-standardized quantum-resistant algorithms
Cypheron Core is a Rust library implementing NIST-standardized quantum-resistant algorithms designed to protect against both classical and quantum computer attacks. The library provides high-performance implementations with strong security guarantees.
Quick Start
Add to your Cargo.toml:
[dependencies]
cypheron-core = "0.1.0"
Basic usage:
#![allow(unused)] fn main() { use cypheron_core::kem::{MlKem768, Kem}; // Generate keypair let (public_key, secret_key) = MlKem768::keypair()?; // Encapsulate shared secret let (ciphertext, shared_secret) = MlKem768::encapsulate(&public_key)?; // Decapsulate shared secret let decapsulated_secret = MlKem768::decapsulate(&ciphertext, &secret_key)?; assert_eq!(shared_secret.expose_secret(), decapsulated_secret.expose_secret()); }
Algorithms Supported
Key Encapsulation Mechanisms (KEM)
Digital Signatures
Hybrid Cryptography
- ECC + ML-DSA: Classical elliptic curve + post-quantum signatures
- Hybrid KEM: Combined classical and post-quantum key agreement
Performance
| Algorithm | Key Gen | Sign/Encaps | Verify/Decaps |
|---|---|---|---|
| ML-KEM-768 | ~50μs | ~60μs | ~80μs |
| ML-DSA-65 | ~120μs | ~250μs | ~110μs |
Security Features
- Side-channel resistance: Constant-time implementations
- Memory safety: Secure key zeroization
- NIST compliance: Implements FIPS 203, 204, 205 standards
- Production hardened: Extensive testing and validation
Documentation Sections
- Getting Started - Installation and basic usage
- API Reference - Complete API documentation
- Algorithms - Detailed algorithm documentation
- Security - Security model and considerations
- Troubleshooting - Common issues and solutions
Error Handling
When you encounter errors, they include direct links to relevant documentation:
#![allow(unused)] fn main() { match MlKem768::keypair() { Ok((pk, sk)) => { /* use keys */ }, Err(e) => { // Error includes link: ERROR-KEM-001 // See: https://docs.rs/cypheron-core/troubleshooting/errors.html#error-kem-001 eprintln!("Key generation failed: {}", e); } } }
Local Development
Run the documentation locally:
# Install mdBook
cargo install mdbook
# Serve documentation with hot reload
cd docs
mdbook serve
# Open http://localhost:3000 in your browser
License
Licensed under the Apache License 2.0. See LICENSE for details.
Installation
System Requirements
- Rust: 1.80 or higher
- Operating System: Linux, macOS, or Windows
- Architecture: x86_64, aarch64
Cargo Installation
Add Cypheron Core to your Cargo.toml:
[dependencies]
cypheron-core = "0.1.0"
Then run:
cargo build
Feature Flags
Cypheron Core supports optional features:
[dependencies]
cypheron-core = { version = "0.1.0", features = ["std", "alloc"] }
Available features:
std(default): Standard library supportalloc: Allocation support forno_stdenvironmentshybrid: Hybrid cryptography algorithmsserialize: Serde serialization support
No-std Support
For embedded and constrained environments:
[dependencies]
cypheron-core = { version = "0.1.0", default-features = false, features = ["alloc"] }
Development Dependencies
For testing and benchmarking:
[dev-dependencies]
cypheron-core = { version = "0.1.0", features = ["test-utils"] }
criterion = "0.5"
Platform-Specific Notes
Linux
No additional dependencies required.
macOS
Ensure Xcode command line tools are installed:
xcode-select --install
Windows
Requires Visual Studio Build Tools or MSVC.
Verification
Verify your installation:
use cypheron_core::kem::{MlKem768, Kem}; fn main() { match MlKem768::keypair() { Ok(_) => println!("Installation successful!"), Err(e) => eprintln!("Installation issue: {}", e), } }
Next Steps
- Quick Start Guide - Basic usage examples
- API Reference - Complete API documentation
Quick Start Guide
Get up and running with Cypheron Core in minutes.
Installation
Add cypheron-core to your Cargo.toml:
[dependencies]
cypheron-core = "0.1.0"
Basic KEM Example
Key Encapsulation Mechanisms (KEMs) are used for secure key exchange:
use cypheron_core::kem::{MlKem768, Kem}; fn main() -> Result<(), Box<dyn std::error::Error>> { // Generate a keypair let (public_key, secret_key) = MlKem768::keypair()?; // Alice encapsulates a shared secret using Bob's public key let (ciphertext, shared_secret_alice) = MlKem768::encapsulate(&public_key)?; // Bob decapsulates the shared secret using his secret key let shared_secret_bob = MlKem768::decapsulate(&ciphertext, &secret_key)?; // Both parties now have the same shared secret assert_eq!(shared_secret_alice.expose_secret(), shared_secret_bob.expose_secret()); println!("Key exchange successful!"); Ok(()) }
Basic Signature Example
Digital signatures provide authentication and non-repudiation:
use cypheron_core::sig::{MlDsa65, SignatureEngine}; fn main() -> Result<(), Box<dyn std::error::Error>> { let message = b"Hello, post-quantum world!"; // Generate signing keypair let (public_key, secret_key) = MlDsa65::keypair()?; // Sign the message let signature = MlDsa65::sign(message, &secret_key)?; // Verify the signature let is_valid = MlDsa65::verify(message, &signature, &public_key); assert!(is_valid); println!("Signature verification successful!"); Ok(()) }
Hybrid Example
Combine classical and post-quantum security:
use cypheron_core::hybrid::{EccDilithium, HybridEngine}; fn main() -> Result<(), Box<dyn std::error::Error>> { let message = b"Hybrid security message"; // Generate hybrid keypair (ECC + ML-DSA) let (public_key, secret_key) = EccDilithium::keypair()?; // Create hybrid signature let signature = EccDilithium::sign(message, &secret_key)?; // Verify with different policies use cypheron_core::hybrid::VerificationPolicy; // Require both classical and post-quantum signatures to be valid let strict_valid = EccDilithium::verify_with_policy( message, &signature, &public_key, VerificationPolicy::BothRequired ); // Accept if either classical OR post-quantum signature is valid let relaxed_valid = EccDilithium::verify_with_policy( message, &signature, &public_key, VerificationPolicy::EitherValid ); println!("Strict policy: {}", strict_valid); println!("Relaxed policy: {}", relaxed_valid); Ok(()) }
Error Handling
Cypheron Core uses structured error types with helpful messages:
#![allow(unused)] fn main() { use cypheron_core::kem::{MlKem768, Kem}; match MlKem768::keypair() { Ok((pk, sk)) => { println!("Keypair generated successfully"); // Use the keys... }, Err(e) => { eprintln!("Key generation failed: {}", e); // Error codes like ERROR-KEM-001 link to documentation // See troubleshooting/errors.md for complete error reference } } }
Memory Safety
All sensitive data is automatically zeroized when dropped:
#![allow(unused)] fn main() { use cypheron_core::kem::{MlKem768, Kem}; { let (public_key, secret_key) = MlKem768::keypair().unwrap(); // Use keys... } // secret_key is automatically zeroized when it goes out of scope }
Next Steps
- Algorithm Details - Learn about specific algorithms
- API Reference - Complete API documentation
- Security Model - Understanding security guarantees
- Performance Guide - Optimizing your application
Production Checklist
Before using in production:
- Read the Security Model
- Review Compliance Requirements
- Set up Monitoring
- Test your Error Handling
- Performance test with Benchmarking Guide
Basic Examples
Complete working examples to get you started with Cypheron Core.
Key Encapsulation (KEM) Example
#![allow(unused)] fn main() { use cypheron_core::kem::{MlKem768, Kem}; use cypheron_core::SecretBox; fn kem_example() -> Result<(), Box<dyn std::error::Error>> { // Alice generates a keypair let (alice_pk, alice_sk) = MlKem768::keypair()?; // Bob wants to send a secret to Alice // He encapsulates using Alice's public key let (ciphertext, shared_secret_bob) = MlKem768::encapsulate(&alice_pk)?; // Alice decapsulates using her secret key let shared_secret_alice = MlKem768::decapsulate(&ciphertext, &alice_sk)?; // Both parties now have the same shared secret assert_eq!( shared_secret_alice.expose_secret(), shared_secret_bob.expose_secret() ); println!("Shared secret exchange successful!"); Ok(()) } }
Digital Signature Example
#![allow(unused)] fn main() { use cypheron_core::sig::{MlDsa65, SignatureEngine}; fn signature_example() -> Result<(), Box<dyn std::error::Error>> { let document = b"Important contract terms..."; // Alice generates signing keys let (verify_key, signing_key) = MlDsa65::keypair()?; // Alice signs the document let signature = MlDsa65::sign(document, &signing_key)?; // Bob verifies Alice's signature let is_valid = MlDsa65::verify(document, &signature, &verify_key); if is_valid { println!("Signature is valid - document authenticated!"); } else { println!("Invalid signature - document may be tampered!"); } Ok(()) } }
Hybrid Signature Example
#![allow(unused)] fn main() { use cypheron_core::hybrid::{EccDilithium, HybridEngine, VerificationPolicy}; fn hybrid_example() -> Result<(), Box<dyn std::error::Error>> { let message = b"Quantum-safe hybrid message"; // Generate hybrid keypair (ECC + ML-DSA) let (public_key, secret_key) = EccDilithium::keypair()?; // Create hybrid signature let signature = EccDilithium::sign(message, &secret_key)?; // Verify with strict policy (both signatures must be valid) let strict_valid = EccDilithium::verify_with_policy( message, &signature, &public_key, VerificationPolicy::BothRequired ); // Verify with relaxed policy (either signature valid) let relaxed_valid = EccDilithium::verify_with_policy( message, &signature, &public_key, VerificationPolicy::EitherValid ); println!("Strict policy result: {}", strict_valid); println!("Relaxed policy result: {}", relaxed_valid); Ok(()) } }
Error Handling Example
#![allow(unused)] fn main() { use cypheron_core::kem::{MlKem768, Kem, MlKemError}; fn error_handling_example() { match MlKem768::keypair() { Ok((pk, sk)) => { println!("Keys generated successfully"); // Try to encapsulate match MlKem768::encapsulate(&pk) { Ok((ct, ss)) => { println!("Encapsulation successful"); // Try to decapsulate match MlKem768::decapsulate(&ct, &sk) { Ok(decrypted_ss) => { println!("Decapsulation successful"); }, Err(e) => { eprintln!("Decapsulation failed: {}", e); // Error includes helpful documentation links } } }, Err(e) => eprintln!("Encapsulation failed: {}", e), } }, Err(e) => { eprintln!("Key generation failed: {}", e); // Errors include ERROR-KEM-XXX codes linking to docs } } } }
Memory Safety Example
#![allow(unused)] fn main() { use cypheron_core::kem::{MlKem768, Kem}; use cypheron_core::SecretBox; fn memory_safety_example() -> Result<(), Box<dyn std::error::Error>> { let shared_secret = { let (pk, sk) = MlKem768::keypair()?; let (ct, ss) = MlKem768::encapsulate(&pk)?; // Secret key `sk` is automatically zeroized when it goes out of scope ss }; // Keys are now securely zeroized // Shared secret is still valid and secure println!("Shared secret length: {}", shared_secret.expose_secret().len()); // When shared_secret goes out of scope, it will be zeroized Ok(()) } }
Complete Application Example
use cypheron_core::kem::{MlKem768, Kem}; use cypheron_core::sig::{MlDsa65, SignatureEngine}; struct SecureMessage { encrypted_data: Vec<u8>, signature: Vec<u8>, } fn secure_messaging_example() -> Result<(), Box<dyn std::error::Error>> { // Alice's keys for encryption let (alice_kem_pk, alice_kem_sk) = MlKem768::keypair()?; // Bob's keys for signing let (bob_sig_pk, bob_sig_sk) = MlDsa65::keypair()?; let plaintext = b"Confidential message from Bob to Alice"; // Bob encrypts message for Alice let (ciphertext, shared_secret) = MlKem768::encapsulate(&alice_kem_pk)?; // Use shared secret to encrypt data (simplified - in practice use AES-GCM) let mut encrypted_data = plaintext.to_vec(); for (i, byte) in encrypted_data.iter_mut().enumerate() { *byte ^= shared_secret.expose_secret()[i % 32]; } // Bob signs the encrypted message let signature = MlDsa65::sign(&encrypted_data, &bob_sig_sk)?; let secure_msg = SecureMessage { encrypted_data, signature, }; // Alice receives and verifies the message // First verify Bob's signature let signature_valid = MlDsa65::verify( &secure_msg.encrypted_data, &secure_msg.signature, &bob_sig_pk ); if !signature_valid { return Err("Invalid signature!".into()); } // Then decrypt using her private key let decrypted_secret = MlKem768::decapsulate(&ciphertext, &alice_kem_sk)?; // Decrypt the message let mut decrypted_data = secure_msg.encrypted_data.clone(); for (i, byte) in decrypted_data.iter_mut().enumerate() { *byte ^= decrypted_secret.expose_secret()[i % 32]; } println!("Decrypted message: {}", String::from_utf8_lossy(&decrypted_data)); Ok(()) } fn main() { if let Err(e) = secure_messaging_example() { eprintln!("Secure messaging failed: {}", e); } }
Next Steps
- Algorithm Details - Learn about specific algorithms
- Security Model - Understand security guarantees
- Performance Guide - Optimize your applications
Development Roadmap
This section provides an overview of Cypheron Core’s development timeline and current priorities.
For complete details, see the full Development Roadmap.
Current Status: v0.1.1 - Foundation Complete (September 2025)
Status: [X] COMPLETED - Core implementation and documentation finished
Achievement: Full post-quantum algorithm implementation with comprehensive security documentation
[X] Completed Foundation Work
- Complete unsafe code documentation and justification
- Architecture documentation with FFI boundary analysis
- Security vulnerability reporting policy
- Comprehensive security testing suite
- Cross-platform implementation (Linux, macOS, Windows)
- Supply chain integrity verification system
- Memory safety validation and documentation
Current Priorities: Q4 2025
Focus: Community Audit and Funding Phase
Community Audit Initiative
- Open source community security review
- Academic cryptography community feedback
- Independent security researcher analysis
- Community-driven testing and validation
Grant Funding and Support
- Research foundation grant applications
- Open source security initiative funding
- Academic institution partnership opportunities
- Government cybersecurity grant programs
2026 Goals: Production Release
Following successful security audit and validation:
- Production-ready release with security audit approval
- Long-term API stability commitment
- Enterprise deployment support
- Comprehensive documentation for production use
Algorithm Implementation Status
[X] Complete Implementations
- ML-KEM (Kyber) - 512, 768, 1024 bit security levels
- ML-DSA (Dilithium) - Levels 2, 3, 5
- Falcon - 512, 1024 bit variants
- SPHINCS+ - Multiple parameter configurations
- Hybrid cryptography support (Classical + PQ combinations)
How to Get Involved
Security Review
- Review our Security Documentation
- Examine Unsafe Code Guide
- Report findings via Security Policy
Development
- See Contributing Guidelines
- Review Build System documentation
- Participate in Testing efforts
For the complete roadmap with detailed timelines and success metrics, see ROADMAP.md.
ML-KEM (Module-Lattice-Based Key Encapsulation Mechanism)
ML-KEM is the NIST-standardized quantum-resistant key encapsulation mechanism, formerly known as Kyber. It enables secure key exchange that is resistant to both classical and quantum computer attacks.
Overview
ML-KEM is based on the Module Learning With Errors (M-LWE) problem, which is believed to be hard even for quantum computers. The algorithm provides:
- Key Encapsulation: Secure key exchange between parties
- Quantum Resistance: Security against Shor’s algorithm
- Performance: Efficient operations suitable for real-world use
- Standardization: NIST FIPS 203 compliance
Security Levels
Cypheron Core implements all three ML-KEM variants:
| Variant | Security Level | Classical Security | Quantum Security | Key Sizes |
|---|---|---|---|---|
| ML-KEM-512 | 1 | ~128-bit | ~64-bit | PK: 800B, SK: 1632B |
| ML-KEM-768 | 3 | ~192-bit | ~96-bit | PK: 1184B, SK: 2400B |
| ML-KEM-1024 | 5 | ~256-bit | ~128-bit | PK: 1568B, SK: 3168B |
Basic Usage
#![allow(unused)] fn main() { use cypheron_core::kem::{MlKem768, Kem}; // Generate keypair let (public_key, secret_key) = MlKem768::keypair()?; // Alice encapsulates a shared secret let (ciphertext, shared_secret_alice) = MlKem768::encapsulate(&public_key)?; // Bob decapsulates the shared secret let shared_secret_bob = MlKem768::decapsulate(&ciphertext, &secret_key)?; // Both parties have the same 32-byte shared secret assert_eq!(shared_secret_alice.expose_secret(), shared_secret_bob.expose_secret()); }
Algorithm Details
Key Generation
- Generate matrix A from public randomness
- Generate secret vectors s and e from centered binomial distribution
- Compute t = A·s + e
- Public key: (ρ, t), Secret key: s
Encapsulation
- Generate ephemeral secret r and error vectors e1, e2
- Compute u = A^T·r + e1
- Compute v = t^T·r + e2 + Encode(m)
- Return ciphertext (u, v) and shared secret KDF(m)
Decapsulation
- Compute m’ = Decode(v - s^T·u)
- Re-encapsulate with m’ to get (u’, v’)
- If (u’, v’) = (u, v), return KDF(m’), else return KDF(z)
Performance Characteristics
ML-KEM operations are highly efficient:
#![allow(unused)] fn main() { use std::time::Instant; use cypheron_core::kem::{MlKem768, Kem}; fn benchmark_ml_kem() -> Result<(), Box<dyn std::error::Error>> { // Key generation let start = Instant::now(); let (pk, sk) = MlKem768::keypair()?; println!("Keygen: {:?}", start.elapsed()); // Encapsulation let start = Instant::now(); let (ct, ss1) = MlKem768::encapsulate(&pk)?; println!("Encaps: {:?}", start.elapsed()); // Decapsulation let start = Instant::now(); let ss2 = MlKem768::decapsulate(&ct, &sk)?; println!("Decaps: {:?}", start.elapsed()); Ok(()) } }
Security Considerations
Proper Usage
#![allow(unused)] fn main() { use cypheron_core::kem::{MlKem768, Kem}; // Correct: Use each key pair only once let (pk, sk) = MlKem768::keypair()?; let (ct, ss) = MlKem768::encapsulate(&pk)?; // Correct: Validate ciphertext before decapsulation if ct.len() == 1088 { // ML-KEM-768 ciphertext size let ss2 = MlKem768::decapsulate(&ct, &sk)?; } // Incorrect: Reusing the same keypair multiple times // This could leak information about the secret key }
Side-Channel Protection
All operations use constant-time implementations:
- Constant-time sampling: Secret values don’t affect execution time
- Constant-time arithmetic: Operations always take the same time
- Memory access patterns: No secret-dependent memory accesses
Migration from Kyber
Cypheron Core provides compatibility aliases for smooth migration:
#![allow(unused)] fn main() { // Old Kyber code use cypheron_core::kem::{Kyber768, KyberError}; // Deprecated // New ML-KEM code use cypheron_core::kem::{MlKem768, MlKemError}; // Recommended // Both interfaces are identical let (pk, sk) = MlKem768::keypair()?; }
Test Vectors
Validation against NIST test vectors:
#![allow(unused)] fn main() { #[cfg(test)] mod tests { use super::*; #[test] fn test_nist_vectors() { // Test against official NIST ML-KEM test vectors // See tests/kat/ directory for complete vectors let (pk, sk) = MlKem768::keypair().unwrap(); let (ct, ss1) = MlKem768::encapsulate(&pk).unwrap(); let ss2 = MlKem768::decapsulate(&ct, &sk).unwrap(); assert_eq!(ss1.expose_secret(), ss2.expose_secret()); } } }
Variants
- ML-KEM-512 - Security Level 1
- ML-KEM-768 - Security Level 3 (Recommended)
- ML-KEM-1024 - Security Level 5
See Also
ML-DSA (Digital Signatures)
ML-DSA (Module-Lattice-Based Digital Signature Algorithm) is the NIST-standardized post-quantum digital signature scheme, based on the Dilithium algorithm.
Overview
ML-DSA is designed to resist attacks from both classical and quantum computers, providing:
- Quantum Resistance: Security against Shor’s algorithm
- Efficiency: Fast signature generation and verification
- Small Signatures: Compact signature sizes for practical deployment
- NIST Standardized: FIPS 204 compliant implementation
Security Levels
Cypheron Core implements three ML-DSA variants:
| Variant | Security Level | Public Key | Secret Key | Signature |
|---|---|---|---|---|
| ML-DSA-44 | Level 2 (~112-bit) | 1,312 bytes | 2,560 bytes | 2,420 bytes |
| ML-DSA-65 | Level 3 (~128-bit) | 1,952 bytes | 4,032 bytes | 3,293 bytes |
| ML-DSA-87 | Level 5 (~256-bit) | 2,592 bytes | 4,896 bytes | 4,595 bytes |
Basic Usage
Key Generation
#![allow(unused)] fn main() { use cypheron_core::sig::{MlDsa65, DigitalSignature}; // Generate a new keypair let (public_key, secret_key) = MlDsa65::keypair()?; }
Message Signing
#![allow(unused)] fn main() { let message = b"Hello, post-quantum world!"; // Sign the message let signature = MlDsa65::sign(&secret_key, message)?; }
Signature Verification
#![allow(unused)] fn main() { // Verify the signature let is_valid = MlDsa65::verify(&public_key, message, &signature)?; assert!(is_valid); }
Advanced Usage
Deterministic Key Generation
#![allow(unused)] fn main() { use cypheron_core::sig::MlDsa65; // Generate keypair from seed (for testing) let seed = [42u8; 32]; let (pk, sk) = MlDsa65::keypair_deterministic(&seed)?; }
Context Separation
#![allow(unused)] fn main() { // Sign with context for domain separation let context = b"email-signature-v1"; let signature = MlDsa65::sign_with_context(&secret_key, message, context)?; let is_valid = MlDsa65::verify_with_context(&public_key, message, &signature, context)?; }
Security Considerations
Recommended Usage
- Use ML-DSA-65 for most applications (128-bit security level)
- Use ML-DSA-87 for high-security applications requiring 256-bit security
- Use ML-DSA-44 only for resource-constrained environments
Key Management
#![allow(unused)] fn main() { use secrecy::{ExposeSecret, Zeroize}; // Secret keys are automatically zeroized on drop impl Drop for MlDsaSecretKey { fn drop(&mut self) { self.0.zeroize(); } } // Access secret key material safely secret_key.expose_secret(|key_bytes| { // Use key_bytes for signing operation MlDsa65::sign_with_raw_key(key_bytes, message) }) }
Side-Channel Resistance
- Implementation uses constant-time operations where feasible
- Secret key operations avoid data-dependent branches
- Memory access patterns independent of secret values
Performance Characteristics
Typical Performance (x86_64, 3.0 GHz)
| Operation | ML-DSA-44 | ML-DSA-65 | ML-DSA-87 |
|---|---|---|---|
| Key Generation | ~95μs | ~120μs | ~160μs |
| Sign | ~180μs | ~250μs | ~380μs |
| Verify | ~85μs | ~110μs | ~150μs |
Memory Usage
- Stack allocation for all operations
- No dynamic memory allocation required
- Secure automatic cleanup on scope exit
Error Handling
Common Errors
#![allow(unused)] fn main() { use cypheron_core::error::Error; match MlDsa65::verify(&public_key, message, &signature) { Ok(true) => println!("Valid signature"), Ok(false) => println!("Invalid signature"), Err(Error::InvalidPublicKey) => println!("Malformed public key"), Err(Error::InvalidSignature) => println!("Malformed signature"), Err(e) => println!("Other error: {}", e), } }
Input Validation
- All inputs are validated before processing
- Malformed keys/signatures return appropriate errors
- No panics on invalid input data
Interoperability
NIST Compliance
- Implements FIPS 204 specification exactly
- Compatible with other FIPS 204 implementations
- Passes all NIST Known Answer Tests (KAT)
Serialization
#![allow(unused)] fn main() { // Serialize keys and signatures let pk_bytes = public_key.as_bytes(); let sk_bytes = secret_key.expose_secret(|bytes| bytes.to_vec()); let sig_bytes = signature.as_bytes(); // Deserialize from bytes let public_key = MlDsaPublicKey::from_bytes(&pk_bytes)?; let signature = MlDsaSignature::from_bytes(&sig_bytes)?; }
Hybrid Signatures
ML-DSA can be combined with classical signatures for transitional security:
#![allow(unused)] fn main() { use cypheron_core::hybrid::EccDilithium; // Hybrid ECDSA + ML-DSA signature let (hybrid_pk, hybrid_sk) = EccDilithium::keypair()?; let hybrid_sig = EccDilithium::sign(&hybrid_sk, message)?; let is_valid = EccDilithium::verify(&hybrid_pk, message, &hybrid_sig)?; }
See Also
- Falcon Digital Signatures - Alternative post-quantum signature scheme
- SPHINCS+ Digital Signatures - Hash-based signature scheme
- Hybrid Cryptography - Combining classical and post-quantum
- Security Model - Overall security considerations
Falcon (Digital Signatures)
Falcon is a post-quantum digital signature scheme based on the NTRU lattice structure, offering compact signatures and fast verification.
Overview
Falcon provides:
- Compact Signatures: Smallest signature sizes among post-quantum schemes
- Fast Verification: Efficient signature verification operations
- Quantum Resistance: Security against quantum cryptanalysis
- NIST Finalist: Round 3 finalist in NIST post-quantum standardization
Security Levels
Cypheron Core implements two Falcon variants:
| Variant | Security Level | Public Key | Secret Key | Signature |
|---|---|---|---|---|
| Falcon-512 | Level 1 (~112-bit) | 897 bytes | 1,281 bytes | ~666 bytes |
| Falcon-1024 | Level 5 (~256-bit) | 1,793 bytes | 2,305 bytes | ~1,280 bytes |
Note: Falcon signatures have variable length; sizes shown are typical values.
Basic Usage
Key Generation
#![allow(unused)] fn main() { use cypheron_core::sig::{Falcon512, DigitalSignature}; // Generate a new keypair let (public_key, secret_key) = Falcon512::keypair()?; }
Message Signing
#![allow(unused)] fn main() { let message = b"Falcon signature example"; // Sign the message let signature = Falcon512::sign(&secret_key, message)?; }
Signature Verification
#![allow(unused)] fn main() { // Verify the signature let is_valid = Falcon512::verify(&public_key, message, &signature)?; assert!(is_valid); }
Advanced Usage
Deterministic Key Generation
#![allow(unused)] fn main() { use cypheron_core::sig::Falcon512; // Generate keypair from seed (for testing) let seed = [1u8; 48]; // Falcon uses 48-byte seeds let (pk, sk) = Falcon512::keypair_deterministic(&seed)?; }
Variable-Length Signatures
#![allow(unused)] fn main() { // Falcon signatures have variable length let signature = Falcon512::sign(&secret_key, message)?; println!("Signature length: {} bytes", signature.len()); // Length varies based on randomness and message // Typical range: 600-700 bytes for Falcon-512 }
Security Considerations
Recommended Usage
- Use Falcon-512 for applications requiring compact signatures
- Use Falcon-1024 for high-security applications needing 256-bit security
- Consider ML-DSA for applications where deterministic signature size is important
Key Security
#![allow(unused)] fn main() { use secrecy::{ExposeSecret, Zeroize}; // Secret keys are automatically zeroized impl Drop for FalconSecretKey { fn drop(&mut self) { self.0.zeroize(); } } // Safe secret key access secret_key.expose_secret(|key_bytes| { Falcon512::sign_with_raw_key(key_bytes, message) }) }
Implementation Notes
- Uses floating-point arithmetic internally (NTRU structure)
- Signature generation involves random sampling
- Verification is deterministic and constant-time
Performance Characteristics
Typical Performance (x86_64, 3.0 GHz)
| Operation | Falcon-512 | Falcon-1024 |
|---|---|---|
| Key Generation | ~2.5ms | ~8ms |
| Sign | ~1.2ms | ~3.5ms |
| Verify | ~85μs | ~180μs |
Memory Usage
- Key generation requires temporary working memory
- Signing uses stack-allocated buffers
- Verification is memory-efficient
Error Handling
Common Errors
#![allow(unused)] fn main() { use cypheron_core::error::Error; match Falcon512::verify(&public_key, message, &signature) { Ok(true) => println!("Valid signature"), Ok(false) => println!("Invalid signature"), Err(Error::InvalidPublicKey) => println!("Malformed public key"), Err(Error::InvalidSignature) => println!("Malformed signature"), Err(Error::SigningFailed) => println!("Random sampling failed"), Err(e) => println!("Other error: {}", e), } }
Input Validation
- Public keys validated for proper NTRU structure
- Signatures validated for encoding compliance
- Invalid inputs return errors without panicking
Interoperability
NIST Compatibility
- Implements NIST Round 3 Falcon specification
- Compatible with reference implementations
- Passes all official test vectors
Serialization
#![allow(unused)] fn main() { // Serialize keys and signatures let pk_bytes = public_key.as_bytes(); let sk_bytes = secret_key.expose_secret(|bytes| bytes.to_vec()); let sig_bytes = signature.as_bytes(); // Deserialize from bytes let public_key = FalconPublicKey::from_bytes(&pk_bytes)?; let signature = FalconSignature::from_bytes(&sig_bytes)?; }
Comparison with Other Schemes
Falcon vs ML-DSA
| Aspect | Falcon | ML-DSA |
|---|---|---|
| Signature Size | Smaller (~666 bytes) | Larger (~2,420+ bytes) |
| Key Generation | Slower | Faster |
| Verification | Fast | Fast |
| Implementation | More complex | Simpler |
| Standardization | NIST Round 3 finalist | NIST standardized |
Use Case Recommendations
- Choose Falcon when signature size is critical
- Choose ML-DSA for standardized compliance
- Consider SPHINCS+ for hash-based security model
Hybrid Usage
Falcon can be combined with classical signatures:
#![allow(unused)] fn main() { use cypheron_core::hybrid::EccFalcon; // Hybrid ECDSA + Falcon signature let (hybrid_pk, hybrid_sk) = EccFalcon::keypair()?; let hybrid_sig = EccFalcon::sign(&hybrid_sk, message)?; let is_valid = EccFalcon::verify(&hybrid_pk, message, &hybrid_sig)?; }
Implementation Details
NTRU Lattice Structure
- Based on polynomial rings over NTRU lattices
- Uses Gaussian sampling for signature generation
- Rejection sampling ensures security properties
Floating-Point Considerations
- Implementation uses controlled floating-point arithmetic
- Results are deterministic across platforms
- Special handling for edge cases and rounding
See Also
- ML-DSA Digital Signatures - NIST-standardized alternative
- SPHINCS+ Digital Signatures - Hash-based signatures
- Hybrid Cryptography - Combining schemes
- Security Model - Security considerations
SPHINCS+ (Digital Signatures)
SPHINCS+ is a hash-based post-quantum digital signature scheme offering conservative security assumptions and no reliance on algebraic problems.
Overview
SPHINCS+ provides:
- Conservative Security: Based only on hash function security
- No Algebraic Assumptions: Unlike lattice-based schemes
- Stateless Operation: No state management required
- Multiple Variants: Different security/performance tradeoffs
Security Model
SPHINCS+ security relies solely on:
- Hash Function Security: SHA-256 or SHAKE-256 collision resistance
- No Quantum Vulnerability: Hash functions remain secure against quantum attacks
- Proven Reduction: Security reduces to underlying hash function
Parameter Sets
Cypheron Core implements multiple SPHINCS+ variants:
SPHINCS+-SHA256 Variants
| Variant | Security Level | Public Key | Secret Key | Signature |
|---|---|---|---|---|
| sphincs-sha256-128s | Level 1 (small sig) | 32 bytes | 64 bytes | 7,856 bytes |
| sphincs-sha256-128f | Level 1 (fast) | 32 bytes | 64 bytes | 17,088 bytes |
| sphincs-sha256-192s | Level 3 (small sig) | 48 bytes | 96 bytes | 16,224 bytes |
| sphincs-sha256-192f | Level 3 (fast) | 48 bytes | 96 bytes | 35,664 bytes |
| sphincs-sha256-256s | Level 5 (small sig) | 64 bytes | 128 bytes | 29,792 bytes |
| sphincs-sha256-256f | Level 5 (fast) | 64 bytes | 128 bytes | 49,856 bytes |
SPHINCS+-SHAKE256 Variants
| Variant | Security Level | Public Key | Secret Key | Signature |
|---|---|---|---|---|
| sphincs-shake256-128s | Level 1 (small sig) | 32 bytes | 64 bytes | 7,856 bytes |
| sphincs-shake256-128f | Level 1 (fast) | 32 bytes | 64 bytes | 17,088 bytes |
| sphincs-shake256-192s | Level 3 (small sig) | 48 bytes | 96 bytes | 16,224 bytes |
| sphincs-shake256-192f | Level 3 (fast) | 48 bytes | 96 bytes | 35,664 bytes |
| sphincs-shake256-256s | Level 5 (small sig) | 64 bytes | 128 bytes | 29,792 bytes |
| sphincs-shake256-256f | Level 5 (fast) | 64 bytes | 128 bytes | 49,856 bytes |
Basic Usage
Key Generation
#![allow(unused)] fn main() { use cypheron_core::sig::{SphincsPlusSha256128s, DigitalSignature}; // Generate a new keypair let (public_key, secret_key) = SphincsPlusSha256128s::keypair()?; }
Message Signing
#![allow(unused)] fn main() { let message = b"SPHINCS+ hash-based signature"; // Sign the message let signature = SphincsPlusSha256128s::sign(&secret_key, message)?; }
Signature Verification
#![allow(unused)] fn main() { // Verify the signature let is_valid = SphincsPlusSha256128s::verify(&public_key, message, &signature)?; assert!(is_valid); }
Variant Selection
Small vs Fast Variants
#![allow(unused)] fn main() { use cypheron_core::sig::{SphincsPlusSha256128s, SphincsPlusSha256128f}; // Small signature variant (slower, smaller signatures) let (pk_s, sk_s) = SphincsPlusSha256128s::keypair()?; let sig_s = SphincsPlusSha256128s::sign(&sk_s, message)?; println!("Small signature: {} bytes", sig_s.len()); // Fast variant (faster, larger signatures) let (pk_f, sk_f) = SphincsPlusSha256128f::keypair()?; let sig_f = SphincsPlusSha256128f::sign(&sk_f, message)?; println!("Fast signature: {} bytes", sig_f.len()); }
SHA-256 vs SHAKE-256
#![allow(unused)] fn main() { use cypheron_core::sig::{SphincsPlusSha256128s, SphincsPlusShake256128s}; // SHA-256 based variant let (pk_sha, sk_sha) = SphincsPlusSha256128s::keypair()?; // SHAKE-256 based variant let (pk_shake, sk_shake) = SphincsPlusShake256128s::keypair()?; // Both provide equivalent security, choose based on: // - SHA-256: Wider acceptance, NIST standard // - SHAKE-256: More flexible, part of SHA-3 family }
Advanced Usage
Deterministic Key Generation
#![allow(unused)] fn main() { use cypheron_core::sig::SphincsPlusSha256128s; // Generate keypair from seed let seed = [0u8; 48]; // SPHINCS+ uses variable seed lengths let (pk, sk) = SphincsPlusSha256128s::keypair_deterministic(&seed)?; }
Context Separation
#![allow(unused)] fn main() { // Sign with context for domain separation let context = b"document-signing-v2"; let signature = SphincsPlusSha256128s::sign_with_context(&secret_key, message, context)?; let is_valid = SphincsPlusSha256128s::verify_with_context(&public_key, message, &signature, context)?; }
Security Considerations
Conservative Security Model
- No Algebraic Assumptions: Security doesn’t depend on lattice problems
- Post-Quantum Safe: Hash functions remain secure against quantum computers
- Proven Security: Well-understood cryptographic foundations
Recommended Usage
- Use 128s variants for applications requiring smaller signatures
- Use 128f variants for applications requiring faster signing
- Use 192s/256s for higher security requirements
- Choose SHA-256 for maximum compatibility
Key Management
#![allow(unused)] fn main() { use secrecy::{ExposeSecret, Zeroize}; // Secret keys automatically zeroized on drop impl Drop for SphincsSecretKey { fn drop(&mut self) { self.0.zeroize(); } } // Safe secret key access secret_key.expose_secret(|key_bytes| { SphincsPlusSha256128s::sign_with_raw_key(key_bytes, message) }) }
Performance Characteristics
Typical Performance (x86_64, 3.0 GHz)
| Variant | Key Generation | Sign | Verify |
|---|---|---|---|
| sha256-128s | ~15ms | ~180ms | ~4ms |
| sha256-128f | ~15ms | ~8ms | ~2ms |
| sha256-192s | ~25ms | ~650ms | ~8ms |
| sha256-192f | ~25ms | ~18ms | ~4ms |
| sha256-256s | ~35ms | ~1.2s | ~12ms |
| sha256-256f | ~35ms | ~35ms | ~6ms |
Memory Usage
- Small key sizes (32-128 bytes)
- Large signature sizes (7KB-50KB)
- Stack-based operations, no heap allocation
Error Handling
Common Errors
#![allow(unused)] fn main() { use cypheron_core::error::Error; match SphincsPlusSha256128s::verify(&public_key, message, &signature) { Ok(true) => println!("Valid signature"), Ok(false) => println!("Invalid signature"), Err(Error::InvalidPublicKey) => println!("Malformed public key"), Err(Error::InvalidSignature) => println!("Malformed signature"), Err(Error::HashingFailed) => println!("Internal hash computation failed"), Err(e) => println!("Other error: {}", e), } }
Interoperability
NIST Compliance
- Implements NIST Round 3 SPHINCS+ specification
- Compatible with reference implementations
- Passes all official test vectors
Serialization
#![allow(unused)] fn main() { // Serialize keys and signatures let pk_bytes = public_key.as_bytes(); let sk_bytes = secret_key.expose_secret(|bytes| bytes.to_vec()); let sig_bytes = signature.as_bytes(); // Deserialize from bytes let public_key = SphincsPublicKey::from_bytes(&pk_bytes)?; let signature = SphincsSignature::from_bytes(&sig_bytes)?; }
Comparison with Other Schemes
SPHINCS+ vs Lattice-Based Schemes
| Aspect | SPHINCS+ | ML-DSA/Falcon |
|---|---|---|
| Security Model | Hash functions only | Lattice problems |
| Signature Size | Large (7KB-50KB) | Small (0.7KB-4KB) |
| Key Size | Small (32-128 bytes) | Medium (1-3KB) |
| Speed | Slower | Faster |
| Quantum Resistance | Very conservative | Well-studied |
Use Case Recommendations
- Choose SPHINCS+ for maximum conservative security
- Choose ML-DSA for practical performance and NIST standardization
- Choose Falcon for compact signatures
- Consider hybrid for transition periods
Hybrid Usage
SPHINCS+ can be combined with other schemes:
#![allow(unused)] fn main() { use cypheron_core::hybrid::EccSphincs; // Hybrid ECDSA + SPHINCS+ signature let (hybrid_pk, hybrid_sk) = EccSphincs::keypair()?; let hybrid_sig = EccSphincs::sign(&hybrid_sk, message)?; let is_valid = EccSphincs::verify(&hybrid_pk, message, &hybrid_sig)?; }
Implementation Details
Hash-Based Construction
- Built on one-way hash functions and Merkle trees
- Uses WOTS+ (Winternitz One-Time Signature Plus)
- XMSS-style tree authentication
- No state management required (stateless)
Parameter Selection
- “s” variants: Optimize for smaller signatures
- “f” variants: Optimize for faster operations
- Security levels: 128, 192, 256-bit equivalent security
- Hash functions: SHA-256 or SHAKE-256
See Also
- ML-DSA Digital Signatures - Lattice-based alternative
- Falcon Digital Signatures - Compact lattice-based signatures
- Hybrid Cryptography - Combining schemes
- Security Model - Security considerations
Hybrid Cryptography Overview
Hybrid cryptography combines classical and post-quantum algorithms to provide defense against both current and future cryptographic attacks.
Why Hybrid?
Hybrid schemes provide multiple layers of security:
- Classical Security: Protection against traditional computing threats
- Quantum Resistance: Protection against quantum computer attacks
- Migration Safety: Smooth transition from classical to post-quantum
- Defense in Depth: Multiple independent security assumptions
Hybrid Strategies
Composite Signatures
Combine classical and post-quantum signature schemes:
#![allow(unused)] fn main() { use cypheron_core::hybrid::{EccDilithium, HybridEngine}; // Generate hybrid keypair (ECC + ML-DSA) let (public_key, secret_key) = EccDilithium::keypair()?; // Create composite signature let message = b"Hybrid signed message"; let signature = EccDilithium::sign(message, &secret_key)?; // Verification can use different policies let is_valid = EccDilithium::verify(message, &signature, &public_key); }
Verification Policies
Different policies for signature verification:
#![allow(unused)] fn main() { use cypheron_core::hybrid::VerificationPolicy; // Strict: Both signatures must be valid let strict_valid = EccDilithium::verify_with_policy( message, &signature, &public_key, VerificationPolicy::BothRequired ); // Relaxed: Either signature can be valid let relaxed_valid = EccDilithium::verify_with_policy( message, &signature, &public_key, VerificationPolicy::EitherValid ); // Migration: Prefer post-quantum but accept classical let migration_valid = EccDilithium::verify_with_policy( message, &signature, &public_key, VerificationPolicy::PostQuantumPreferred ); }
Security Analysis
Combined Security Level
The security of hybrid schemes depends on verification policy:
| Policy | Security Level | Description |
|---|---|---|
| BothRequired | min(classical, pq) | Weakest component determines security |
| EitherValid | max(classical, pq) | Strongest component determines security |
| PostQuantumPreferred | post-quantum | Prioritizes quantum resistance |
Attack Scenarios
Quantum Computer Attack:
- Classical component: Broken
- Post-quantum component: Secure
- Result with EitherValid: Secure
Classical Cryptanalysis:
- Classical component: Potentially broken
- Post-quantum component: Secure
- Result with EitherValid: Secure
Post-Quantum Cryptanalysis:
- Classical component: Secure
- Post-quantum component: Potentially broken
- Result with EitherValid: Secure
Performance Considerations
Signature Size
Hybrid signatures combine both signature types:
#![allow(unused)] fn main() { // Individual signature sizes (approximate) // ECDSA P-256: ~64 bytes // ML-DSA-65: ~3300 bytes // Combined: ~3364 bytes let (pk, sk) = EccDilithium::keypair()?; let signature = EccDilithium::sign(b"message", &sk)?; println!("Hybrid signature size: {} bytes", signature.len()); // Output: Hybrid signature size: 3364 bytes }
Verification Time
Verification involves both algorithms:
#![allow(unused)] fn main() { use std::time::Instant; let start = Instant::now(); let valid = EccDilithium::verify(message, &signature, &public_key); let duration = start.elapsed(); println!("Hybrid verification: {:?}", duration); // Typical: ~0.5ms (classical) + ~0.1ms (post-quantum) = ~0.6ms }
Migration Strategies
Phase 1: Introduction
Start with relaxed verification policy:
#![allow(unused)] fn main() { // Accept either classical or post-quantum signatures let valid = EccDilithium::verify_with_policy( message, &signature, &public_key, VerificationPolicy::EitherValid ); }
Phase 2: Transition
Require both signatures but log failures:
#![allow(unused)] fn main() { let strict_valid = EccDilithium::verify_with_policy( message, &signature, &public_key, VerificationPolicy::BothRequired ); if !strict_valid { // Log for monitoring but continue processing log::warn!("Hybrid signature verification failed"); // Fallback to relaxed policy during transition let relaxed_valid = EccDilithium::verify_with_policy( message, &signature, &public_key, VerificationPolicy::EitherValid ); return relaxed_valid; } }
Phase 3: Post-Quantum Only
Eventually migrate to pure post-quantum:
#![allow(unused)] fn main() { use cypheron_core::sig::{MlDsa65, SignatureEngine}; // Pure post-quantum signatures let (pk, sk) = MlDsa65::keypair()?; let signature = MlDsa65::sign(message, &sk)?; let valid = MlDsa65::verify(message, &signature, &pk); }
Configuration Management
Policy Configuration
#![allow(unused)] fn main() { use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize)] pub struct HybridConfig { pub verification_policy: VerificationPolicy, pub signature_format: SignatureFormat, pub key_rotation_interval: u64, // days } impl Default for HybridConfig { fn default() -> Self { Self { verification_policy: VerificationPolicy::EitherValid, signature_format: SignatureFormat::Concatenated, key_rotation_interval: 90, } } } }
Environment-Based Configuration
#![allow(unused)] fn main() { use std::env; fn get_verification_policy() -> VerificationPolicy { match env::var("CYPHERON_VERIFICATION_POLICY").as_deref() { Ok("strict") => VerificationPolicy::BothRequired, Ok("relaxed") => VerificationPolicy::EitherValid, Ok("pq-preferred") => VerificationPolicy::PostQuantumPreferred, _ => VerificationPolicy::EitherValid, // Default } } }
Interoperability
Wire Format
Hybrid signatures can use different encoding formats:
#![allow(unused)] fn main() { // Concatenated format: [classical_sig][pq_sig] // Tagged format: [tag][len][classical_sig][tag][len][pq_sig] // ASN.1 format: Structured encoding with OIDs }
Protocol Integration
Example integration with TLS:
#![allow(unused)] fn main() { // Custom signature scheme identifier const HYBRID_ECC_MLDSA: u16 = 0xFE00; impl SignatureScheme for EccDilithium { fn scheme_id(&self) -> u16 { HYBRID_ECC_MLDSA } fn sign(&self, message: &[u8], key: &PrivateKey) -> Vec<u8> { // Convert from TLS types to Cypheron types let sk = HybridSecretKey::from_tls(key); EccDilithium::sign(message, &sk).unwrap() } } }
See Also
- ECC + ML-DSA - Specific hybrid implementation
- Hybrid KEM - Key encapsulation mechanisms
- Security Considerations - Security analysis
Core Types
This section documents the core types and data structures used throughout Cypheron Core.
Key Types
Public Keys
All public key types are Clone and can be safely shared:
#![allow(unused)] fn main() { use cypheron_core::kem::MlKemPublicKey; use cypheron_core::sig::MlDsaPublicKey; // ML-KEM public keys let pk: MlKemPublicKey = // ... from keypair generation let pk_clone = pk.clone(); // Safe to clone // ML-DSA public keys let verify_key: MlDsaPublicKey = // ... from keypair generation }
Secret Keys
Secret keys are wrapped in SecretBox for memory safety:
#![allow(unused)] fn main() { use cypheron_core::kem::MlKemSecretKey; use cypheron_core::sig::MlDsaSecretKey; use secrecy::ExposeSecret; // Secret keys are automatically zeroized when dropped let sk: MlKemSecretKey = // ... from keypair generation // Access secret data only when needed let secret_bytes = sk.0.expose_secret(); // sk is automatically zeroized when it goes out of scope }
Shared Secrets
Shared secrets from KEM operations are securely managed:
#![allow(unused)] fn main() { use cypheron_core::kem::{MlKem768, Kem}; use secrecy::ExposeSecret; let (pk, sk) = MlKem768::keypair()?; let (ct, shared_secret) = MlKem768::encapsulate(&pk)?; // Access shared secret data let secret_data = shared_secret.expose_secret(); // &[u8; 32] // shared_secret is zeroized when dropped }
Error Types
KEM Errors
#![allow(unused)] fn main() { use cypheron_core::kem::MlKemError; pub enum MlKemError { KeyGenerationEntropyFailure, KeyGenerationInternalError, EncapsulationInvalidKey, EncapsulationInternalError, DecapsulationInvalidCiphertext, DecapsulationInternalError, InvalidCiphertextLength { expected: usize, actual: usize }, InvalidPublicKeyLength { expected: usize, actual: usize }, InvalidSecretKeyLength { expected: usize, actual: usize }, CLibraryError { code: i32 }, } }
Signature Errors
#![allow(unused)] fn main() { use cypheron_core::sig::MlDsaError; pub enum MlDsaError { KeyGenerationFailed, SignatureFailed, VerificationFailed, InvalidSignatureLength { expected: usize, actual: usize }, InvalidPublicKeyLength { expected: usize, actual: usize }, InvalidSecretKeyLength { expected: usize, actual: usize }, CLibraryError { code: i32 }, } }
Trait Definitions
KEM Trait
#![allow(unused)] fn main() { pub trait Kem { type PublicKey; type SecretKey; type Ciphertext; type SharedSecret; type Error; fn keypair() -> Result<(Self::PublicKey, Self::SecretKey), Self::Error>; fn encapsulate(pk: &Self::PublicKey) -> Result<(Self::Ciphertext, Self::SharedSecret), Self::Error>; fn decapsulate(ct: &Self::Ciphertext, sk: &Self::SecretKey) -> Result<Self::SharedSecret, Self::Error>; } }
SignatureEngine Trait
#![allow(unused)] fn main() { pub trait SignatureEngine { type PublicKey; type SecretKey; type Signature; type Error; fn keypair() -> Result<(Self::PublicKey, Self::SecretKey), Self::Error>; fn sign(message: &[u8], sk: &Self::SecretKey) -> Result<Self::Signature, Self::Error>; fn verify(message: &[u8], signature: &Self::Signature, pk: &Self::PublicKey) -> bool; } }
Size Constants
All algorithm parameters are available as constants:
#![allow(unused)] fn main() { use cypheron_core::kem::sizes; use cypheron_core::sig::sizes as sig_sizes; // ML-KEM sizes const ML_KEM_768_PUBLIC: usize = sizes::ML_KEM_768_PUBLIC; // 1184 const ML_KEM_768_SECRET: usize = sizes::ML_KEM_768_SECRET; // 2400 const ML_KEM_768_CIPHERTEXT: usize = sizes::ML_KEM_768_CIPHERTEXT; // 1088 const ML_KEM_768_SHARED: usize = sizes::ML_KEM_768_SHARED; // 32 // ML-DSA sizes const ML_DSA_65_PUBLIC: usize = sig_sizes::ML_DSA_65_PUBLIC; // 1952 const ML_DSA_65_SECRET: usize = sig_sizes::ML_DSA_65_SECRET; // 4032 }
Memory Safety Guarantees
Automatic Zeroization
#![allow(unused)] fn main() { use zeroize::Zeroize; // All secret types implement Zeroize fn example() { let (pk, sk) = MlKem768::keypair().unwrap(); // Use secret key... } // sk is automatically zeroized here when dropped }
SecretBox Protection
#![allow(unused)] fn main() { use secrecy::{SecretBox, ExposeSecret}; // Secret data is protected until explicitly exposed let secret = SecretBox::new([1, 2, 3, 4]); // Only expose when absolutely necessary let data = secret.expose_secret(); // &[u8] // secret is zeroized when dropped }
Serialization Support
With the serialize feature enabled:
#![allow(unused)] fn main() { use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize)] struct KeyPair { public_key: MlKemPublicKey, // Note: Secret keys should NOT be serialized in most cases } // Serialize public key safely let json = serde_json::to_string(&public_key)?; // Deserialize public key let pk: MlKemPublicKey = serde_json::from_str(&json)?; }
Thread Safety
All public key types are Send and Sync:
#![allow(unused)] fn main() { use std::sync::Arc; use std::thread; let (pk, _sk) = MlKem768::keypair().unwrap(); let shared_pk = Arc::new(pk); // Public keys can be shared across threads let handles: Vec<_> = (0..4).map(|_| { let pk = shared_pk.clone(); thread::spawn(move || { // Use pk in thread... MlKem768::encapsulate(&pk) }) }).collect(); }
See Also
- KEM Operations - Key Encapsulation APIs
- Signature Operations - Digital Signature APIs
- Error Handling - Error types and handling
System Architecture
This section provides an overview of Cypheron Core’s architecture and design principles.
For complete technical details, see the full Architecture Documentation.
Overview
Cypheron Core is structured as a multi-layered system combining Rust-native implementations with NIST reference implementations through FFI bindings. The architecture ensures cross-platform compatibility while maintaining security and performance.
Core Components
| Component | Module Path | Primary Types | Purpose |
|---|---|---|---|
| ML-KEM(Kyber) | kem/ | MlKem512, MlKem768, MlKem1024 | Key encapsulation mechanisms |
| Digital Signatures | sig/ | MlDsa44, MlDsa65, MlDsa87, Falcon512, Falcon1024 | Post-quantum digital signatures |
| Hybrid Cryptography | hybrid/ | P256mlKem768, EccDilithium, CompositeKeypair | Classical + PQ combinations |
Architecture Layers
┌─────────────────────────────────────────────────────────────┐
│ APPLICATION LAYER │
│ • Safe Rust API │
│ • Type Safety Guaranteed │
├─────────────────────────────────────────────────────────────┤
│ CYPHERON CORE │
│ • Algorithm Wrappers │
│ • Memory Management │
│ • Error Handling │
├═════════════════════════════════════════════════════════════┤
│ FFI BOUNDARY │
│ • Input Validation │
│ • Buffer Management │
│ • Safety Enforcement │
├═════════════════════════════════════════════════════════════┤
│ NIST C IMPLEMENTATIONS │
│ • ML-KEM Reference Code │
│ • ML-DSA Reference Code │
│ • Falcon & SPHINCS+ Code │
└─────────────────────────────────────────────────────────────┘
Build System Architecture
The build system orchestrates compilation of NIST reference implementations and generates FFI bindings:
- Vendor Code Integrity: SHA-256 verification of all C source files
- Secure Compilation: Platform-specific optimization with security flags
- FFI Safety: Automated binding generation with function allowlisting
Platform Abstraction Layer
| Platform | Secure Random | Memory Protection | Key Features |
|---|---|---|---|
| Windows | BCryptGenRandom | VirtualProtect | BCrypt API, Windows Crypto |
| macOS | SecRandom | mprotect | Security Framework, Apple Silicon detection |
| Linux | getrandom syscall | mprotect | Hardware RNG detection, CPU affinity |
Testing and Validation
The testing infrastructure includes:
- Known Answer Tests (KAT) - NIST compliance validation
- Property Based Testing - Cryptographic property verification
- Security Analysis - Timing attacks and memory safety
- Fuzzing Infrastructure - Robustness testing
- Performance Benchmarking - Regression detection
For detailed technical architecture including security analysis, see the complete Architecture Documentation.
Security Architecture
Cypheron Core implements a comprehensive security architecture designed for post-quantum cryptographic applications requiring high assurance.
For complete security analysis, see the full Architecture Documentation.
Security Architecture Diagram
┌─────────────────────────────────────────────────────────────────────────────┐
│ CYPHERON CORE SECURITY ARCHITECTURE │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ APPLICATION LAYER │ │
│ │ • Memory Safety: Rust Compiler Guaranteed │ │
│ │ • Security Level: FULLY TRUSTED │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ CYPHERON CORE API │ │
│ │ • Input Validation & Sanitization │ │
│ │ • Secure Memory Management │ │
│ │ • Error Handling & Recovery │ │
│ │ • Security Level: CONDITIONALLY TRUSTED │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ ┌═════════════════════════════════════════════════════════════════════════┐ │
│ ║ FFI SECURITY BOUNDARY ║ │
│ ║ • Buffer Bounds Validation ║ │
│ ║ • Type Safety Enforcement ║ │
│ ║ • Memory Ownership Control ║ │
│ ║ • Security Level: CRITICAL TRUST BOUNDARY ║ │
│ └═════════════════════════════════════════════════════════════════════════┘ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ NIST C IMPLEMENTATIONS │ │
│ │ • Cryptographic Operations │ │
│ │ • Manual Memory Management │ │
│ │ • Platform-Specific Optimizations │ │
│ │ • Security Level: UNTRUSTED (VERIFIED BY TESTING) │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
Trust Boundaries
Fully Trusted Zone
Rust Application Code & Core API
- Type safety guaranteed by Rust compiler
- Memory safety enforced automatically
- Bounds checking on all array accesses
Conditionally Trusted Zone
Cypheron Core Unsafe Wrappers
- Input validation and sanitization
- Buffer allocation and lifetime management
- Error handling and conversion
- Manual safety verification required
Untrusted Zone
NIST C Reference Implementations
- Manual memory management
- Potential undefined behavior
- Platform-specific behavior
- Trust through verification and testing
Security Properties
Memory Safety
- Rust Code: Automatic memory safety through type system
- FFI Boundary: Manual validation with comprehensive testing
- C Code: Trust through NIST reference implementation quality
Side-Channel Resistance
- Constant-time implementations where feasible in C vendor code
- Secure memory zeroization using Rust’s zeroize crate
- Platform-specific secure random number generation
Supply Chain Security
- SHA-256 verification of all vendor C code
- Reproducible build process
- Version-controlled checksum validation
- Build failure on integrity violations
Attack Surface Analysis
Primary Attack Vectors
- FFI Boundary Exploitation: Buffer overflows, type confusion
- Memory Safety Violations: Use-after-free, double-free in unsafe code
- Supply Chain Attacks: Compromised vendor code, build system tampering
- Side-Channel Analysis: Timing attacks, power analysis
Mitigation Strategies
- Comprehensive Input Validation: All FFI inputs validated before C calls
- Bounded Buffer Operations: All C functions receive exact buffer sizes
- Integrity Verification: Cryptographic verification of vendor code
- Security Testing: Fuzzing, property-based testing, KAT validation
Vendor Code Provenance
All C implementations sourced from official NIST references:
- ML-KEM: NIST FIPS 203 reference implementation
- ML-DSA: NIST FIPS 204 reference implementation
- Falcon: NIST PQC Round 3 submission
- SPHINCS+: NIST PQC Round 3 submission
Each with SHA-256 integrity verification and controlled update process.
For complete technical details including FFI boundary analysis, memory safety model, and build process security, see the full Architecture Documentation.
FFI Boundary Security
The Foreign Function Interface (FFI) boundary represents the most security-critical component of Cypheron Core, defining the transition between memory-safe Rust and potentially unsafe C implementations.
For complete technical analysis, see Architecture Documentation.
Trust Boundary Model
The FFI boundary creates a clear separation between trusted and untrusted zones:
┌─────────────────────────────────────────────────────────────┐
│ TRUSTED ZONE │
│ • Rust Application Code - Type & Memory Safe │
│ • Cypheron Safe Wrappers - Input Validation │
│ • Buffer Management - Lifetime Control │
├═════════════════════════════════════════════════════════════┤
│ FFI SECURITY BOUNDARY │
├═════════════════════════════════════════════════════════════┤
│ UNTRUSTED ZONE │
│ • NIST C Reference Code - Manual Memory Management │
│ • Potential Undefined Behavior - Platform Specific │
└─────────────────────────────────────────────────────────────┘
Data Flow Security
Inbound Path (Rust → C)
- Input Validation: All parameters validated against algorithm specifications
- Buffer Preparation: Memory allocated with exact required sizes
- Pointer Safety: Raw pointers derived only from valid Rust references
- Length Verification: Buffer sizes cross-checked against C function expectations
Outbound Path (C → Rust)
- Return Code Verification: All C function return values checked
- Output Validation: Generated data verified for proper initialization
- Size Consistency: Output lengths validated against expected algorithm outputs
- Memory Transfer: C-generated data safely transferred to Rust ownership
Memory Ownership Model
Pre-Call State
- Rust allocates and owns all input and output buffers
- Buffer sizes calculated from algorithm-specific constants
- Pointers derived from valid Rust slice references
During C Execution
- Temporary shared access granted via raw pointers
- Rust retains ownership but cannot access during execution
- C code operates within provided buffer boundaries
Post-Call State
- Full ownership returns to Rust immediately
- C-modified buffers validated for proper initialization
- Sensitive data securely zeroized via Drop traits
Safety Guarantees
Buffer Boundary Protection
- All buffer accesses validated before FFI calls
- C functions receive exact sizes via separate length parameters
- No C function can access memory beyond provided boundaries
Type Safety Maintenance
- Raw pointers used only for duration of C function calls
- All data marshalling preserves Rust type invariants
- No C pointers retained beyond function call scope
Error Handling Isolation
- C function errors isolated and converted to Rust error types
- No C error state can compromise Rust memory safety
- Failed operations trigger secure cleanup of sensitive data
Concurrency Safety
- FFI calls protected by appropriate synchronization primitives
- No shared mutable state accessible across FFI boundary
- Thread-local storage used for algorithm-specific contexts
Example: Safe FFI Pattern
#![allow(unused)] fn main() { pub fn ml_kem_keypair() -> Result<(PublicKey, SecretKey), Error> { // 1. Allocate buffers in Rust let mut pk = [0u8; ML_KEM_768_PUBLIC_KEY_BYTES]; let mut sk = [0u8; ML_KEM_768_SECRET_KEY_BYTES]; // 2. Validate buffer sizes assert_eq!(pk.len(), ML_KEM_768_PUBLIC_KEY_BYTES); assert_eq!(sk.len(), ML_KEM_768_SECRET_KEY_BYTES); // 3. Call C function with temporary access let result = unsafe { pqcrystals_kyber768_ref_keypair( pk.as_mut_ptr(), // Temporary pointer access sk.as_mut_ptr(), // Rust maintains ownership ) }; // 4. Validate C function success if result != 0 { return Err(Error::KeygenFailed); } // 5. Verify output initialization (C code populated buffers) if pk.iter().all(|&b| b == 0) || sk.iter().all(|&b| b == 0) { return Err(Error::InvalidOutput); } // 6. Transfer ownership back to Rust types Ok((PublicKey::new(pk), SecretKey::new(sk))) } }
Security Testing
The FFI boundary undergoes comprehensive testing:
- Buffer Boundary Testing: Verify no out-of-bounds access
- Type Safety Validation: Ensure proper data marshalling
- Error Injection: Test error handling paths
- Fuzzing: Automated robustness testing with malformed inputs
- Memory Safety Analysis: AddressSanitizer and Valgrind testing
For detailed implementation analysis including specific safety invariants for each unsafe block, see the Unsafe Code Guide.
Memory Safety Model
Cypheron Core’s memory safety model defines how the library maintains safety guarantees while interfacing with potentially unsafe C vendor code.
For complete technical details, see Architecture Documentation.
Memory Management Architecture
Buffer Ownership Pattern
Rust-Owned Memory Model:
#![allow(unused)] fn main() { // All cryptographic buffers allocated in Rust let mut public_key = [0u8; ML_KEM_768_PUBLIC_KEY_BYTES]; let mut secret_key = [0u8; ML_KEM_768_SECRET_KEY_BYTES]; // Temporary access granted to C code let result = unsafe { pqcrystals_kyber768_ref_keypair( public_key.as_mut_ptr(), // Rust maintains ownership secret_key.as_mut_ptr(), // C code gets temporary access ) }; // Ownership returns to Rust immediately }
Memory Lifecycle Management
1. Allocation Phase
- All buffers allocated by Rust with correct sizes
- Stack allocation preferred for fixed-size cryptographic parameters
- Heap allocation only when necessary, with explicit cleanup
2. Access Phase
- C code receives raw pointers with length information
- Access duration limited to specific function call
- No C code pointer retention beyond function scope
3. Cleanup Phase
- Sensitive data automatically zeroized by Drop implementations
- No manual cleanup required in normal operation
- Cleanup guaranteed even on panic conditions
Safety Enforcement Mechanisms
Pre-Call Validation
#![allow(unused)] fn main() { pub fn validate_buffer_for_ffi<T>(buffer: &[T], expected_len: usize) -> bool { buffer.len() == expected_len && // Length verification !buffer.as_ptr().is_null() && // Non-null pointer buffer.as_ptr().is_aligned() && // Proper alignment is_valid_memory_range(buffer) // Address space validation } }
Buffer Bounds Protection
#![allow(unused)] fn main() { trait FfiSafe { fn is_valid_for_ffi(&self) -> bool; } impl FfiSafe for &[u8] { fn is_valid_for_ffi(&self) -> bool { !self.is_empty() && // Non-empty buffer self.len() <= isize::MAX as usize && // Size limits // Proper alignment self.as_ptr() as usize % std::mem::align_of::<u8>() == 0 } } }
Post-Call Validation
#![allow(unused)] fn main() { fn verify_buffer_initialized(buffer: &[u8], expected_len: usize) -> bool { // Verify C code properly initialized buffer buffer.len() == expected_len && // Additional cryptographic output validation verify_crypto_output_validity(buffer) } }
Secure Memory Management
Secret Key Protection
#![allow(unused)] fn main() { use secrecy::{SecretBox, ExposeSecret, Zeroize}; pub struct SecretKey(SecretBox<[u8; ML_DSA_SECRET_KEY_BYTES]>); impl SecretKey { pub fn expose_for_ffi<F, R>(&self, f: F) -> R where F: FnOnce(&[u8]) -> R { // Controlled access to secret material self.0.expose_secret(f) } } impl Drop for SecretKey { fn drop(&mut self) { // Automatic secure cleanup self.0.expose_secret_mut(|s| s.zeroize()); } } }
Memory Protection
- Stack Protection: Fixed-size buffers on stack when possible
- Heap Isolation: Dynamic allocation with secure cleanup
- Zeroization: All sensitive data cleared on drop
- ASLR Support: Position-independent code generation
Trust Zone Classification
Fully Trusted Zone
- Rust Application Code: Memory safety guaranteed by compiler
- Safe API Layer: Type safety enforced automatically
- Standard Library: Rust std library safety guarantees
Conditionally Trusted Zone
- Unsafe Wrappers: Manual safety verification through code review
- FFI Management: Comprehensive testing and validation
- Platform Code: OS-specific implementations with error handling
Untrusted Zone
- C Reference Code: Manual memory management, potential UB
- Vendor Libraries: Trust through testing and verification
- System Interfaces: OS APIs with proper error handling
Memory Safety Testing
Validation Methods
- Static Analysis: Rust compiler checks and Clippy lints
- Dynamic Testing: AddressSanitizer and MemorySanitizer
- Fuzzing: Automated testing with malformed inputs
- Property Testing: Cryptographic property verification
- Manual Review: Code review of all unsafe blocks
Continuous Validation
- CI/CD Integration: Memory safety testing on all commits
- Platform Testing: Validation across Linux, macOS, Windows
- Regression Prevention: Automated detection of safety violations
- Documentation: All unsafe code documented with safety invariants
Safety Guarantees
What We Guarantee
- No Buffer Overflows: All C function calls bounds-checked
- No Use-After-Free: Rust ownership model prevents dangling pointers
- No Double-Free: Single ownership prevents multiple deallocation
- Secure Cleanup: All sensitive data zeroized on drop
What We Don’t Guarantee
- C Code Internal Safety: Reliant on NIST reference quality
- Side-Channel Resistance: Depends on C implementation properties
- Perfect Forward Secrecy: Application-level concern
- Quantum Resistance: Depends on algorithm security assumptions
For complete technical analysis including specific memory management patterns and safety invariants, see the full Architecture Documentation.
Security Model
DEVELOPMENT STATUS WARNING
This security model describes the INTENDED security properties of Cypheron Core v0.1.0.
CRITICAL: This is a Rust wrapper around official NIST reference implementations - not custom cryptography. The core algorithms are NIST-certified, but the Rust integration layer is experimental and has NOT been:
- Independently audited for FFI safety
- Formally verified for memory management
- Validated in production environments
Integration layer uses C vendor code with Rust FFI bindings requiring security evaluation.
Cypheron Core’s security model describes intended cryptographic foundations and defensive programming practices.
Threat Model
Adversarial Capabilities
We protect against adversaries with the following capabilities:
- Classical Computers: Unlimited classical computational power
- Quantum Computers: Large-scale fault-tolerant quantum computers
- Side-Channel Attacks: Timing, power, and electromagnetic analysis
- Memory Attacks: Cold boot attacks, memory dumps, swap file analysis
Security Goals
- Confidentiality: Encrypted data remains secret
- Authenticity: Signatures prove message origin
- Integrity: Tampering is detectable
- Forward Secrecy: Past communications remain secure if keys are compromised
Cryptographic Security
Post-Quantum Resistance
All algorithms are designed to resist quantum computer attacks:
- ML-KEM: Based on Module Learning With Errors (M-LWE)
- ML-DSA: Based on Module Short Integer Solution (M-SIS)
- Falcon: Based on NTRU lattices and Gaussian sampling
- SPHINCS+: Based on hash functions and one-time signatures
Security Levels
| Level | Classical Security | Quantum Security | Real-World Equivalent |
|---|---|---|---|
| 1 | 128-bit | 64-bit | AES-128 |
| 2 | 128-bit | 64-bit | SHA-256 |
| 3 | 192-bit | 96-bit | AES-192 |
| 4 | 192-bit | 96-bit | SHA-256 |
| 5 | 256-bit | 128-bit | AES-256 |
Implementation Security
Constant-Time Operations
All cryptographic operations execute in constant time:
#![allow(unused)] fn main() { // Example: Constant-time secret key usage let (pk, sk) = MlKem768::keypair()?; let (ct, ss) = MlKem768::encapsulate(&pk)?; // Decapsulation time is independent of: // - Secret key content // - Ciphertext validity // - Previous operations let result = MlKem768::decapsulate(&ct, &sk)?; }
Memory Protection
Sensitive data is automatically protected:
#![allow(unused)] fn main() { use secrecy::ExposeSecret; { let (pk, sk) = MlKem768::keypair()?; // Secret key is in protected memory let secret_data = sk.0.expose_secret(); // Use secret_data... } // Secret key memory is zeroized automatically }
Randomness Requirements
Cryptographic operations require high-quality randomness:
- Entropy Sources: Hardware RNG, OS entropy pools
- Seeding: Proper CSPRNG initialization
- Reseeding: Regular entropy pool updates
#![allow(unused)] fn main() { // Entropy failure is handled gracefully match MlKem768::keypair() { Ok((pk, sk)) => { /* success */ }, Err(MlKemError::KeyGenerationEntropyFailure) => { // Handle insufficient entropy std::thread::sleep(std::time::Duration::from_millis(100)); // Retry... }, Err(e) => return Err(e), } }
Side-Channel Protection
Timing Attacks
All operations use constant-time algorithms:
- No secret-dependent branches: Control flow is independent of secrets
- No secret-dependent memory access: Memory patterns are predictable
- No secret-dependent loop bounds: Iteration counts are fixed
Power Analysis
Operations are designed to minimize power analysis vulnerabilities:
- Uniform operations: Similar power consumption patterns
- Masked arithmetic: Secret values are never used directly
- Randomized execution: Some operations include deliberate randomness
Fault Injection
Critical operations include integrity checks:
#![allow(unused)] fn main() { // Example: Built-in integrity verification let (pk, sk) = MlKem768::keypair()?; let (ct, ss1) = MlKem768::encapsulate(&pk)?; // Decapsulation includes implicit ciphertext validation match MlKem768::decapsulate(&ct, &sk) { Ok(ss2) => { // ss1 and ss2 are identical if no faults occurred assert_eq!(ss1.expose_secret(), ss2.expose_secret()); }, Err(MlKemError::DecapsulationInvalidCiphertext) => { // Ciphertext was corrupted or maliciously modified }, } }
Key Management
Key Lifecycle
- Generation: High-entropy key creation
- Storage: Encrypted at rest when possible
- Usage: Minimal exposure time
- Destruction: Cryptographic erasure
#![allow(unused)] fn main() { // Proper key lifecycle management fn secure_key_usage() -> Result<(), Box<dyn std::error::Error>> { // 1. Generation let (pk, sk) = MlKem768::keypair()?; // 2. Usage (minimize exposure time) let (ct, ss) = MlKem768::encapsulate(&pk)?; // 3. Destruction is automatic when variables go out of scope Ok(()) } // Keys are zeroized here }
Key Rotation
Regular key rotation is recommended:
#![allow(unused)] fn main() { use std::time::{Duration, Instant}; struct KeyManager { current_keys: (MlKemPublicKey, MlKemSecretKey), created_at: Instant, rotation_interval: Duration, } impl KeyManager { fn should_rotate(&self) -> bool { self.created_at.elapsed() > self.rotation_interval } fn rotate(&mut self) -> Result<(), MlKemError> { if self.should_rotate() { self.current_keys = MlKem768::keypair()?; self.created_at = Instant::now(); } Ok(()) } } }
Compliance and Standards
NIST Standardization
All algorithms implement NIST-standardized specifications:
- FIPS 203: ML-KEM standard
- FIPS 204: ML-DSA standard
- FIPS 205: SPHINCS+ standard
Security Validations
- Known Answer Tests (KAT): Validation against NIST test vectors
- Monte Carlo Testing: Statistical randomness validation
- Side-Channel Testing: Timing and power analysis resistance
Limitations and Assumptions
Trust Assumptions
- Implementation Correctness: No bugs in cryptographic implementations
- Hardware Security: CPU and memory provide basic security guarantees
- Random Number Generation: OS provides cryptographically secure randomness
Known Limitations
- No Perfect Forward Secrecy: KEM schemes don’t provide PFS by default
- Post-Quantum Assumptions: Security relies on unproven mathematical assumptions
- Implementation Attacks: Hardware vulnerabilities could compromise security
Best Practices
Application Security
#![allow(unused)] fn main() { // ✅ Good: Validate all inputs if ciphertext.len() != EXPECTED_CIPHERTEXT_SIZE { return Err("Invalid ciphertext size"); } // ✅ Good: Handle errors appropriately match MlKem768::decapsulate(&ct, &sk) { Ok(ss) => use_shared_secret(ss), Err(e) => log_security_event(e), } // ❌ Bad: Ignoring security-critical errors let ss = MlKem768::decapsulate(&ct, &sk).unwrap(); // Don't do this! }
Operational Security
- Monitor Entropy: Check system entropy levels
- Log Security Events: Record cryptographic failures
- Update Regularly: Keep libraries up to date
- Test Thoroughly: Validate all error paths
See Also
- Side-Channel Protection - Detailed protection mechanisms
- Memory Safety - Memory security guarantees
- Compliance - Standards compliance
Vulnerability Reporting
For comprehensive security vulnerability reporting procedures, please see our Security Policy.
Quick Reference
For security vulnerabilities, please report privately to:
- Email: michael@cypheronlabs.com
- Subject Line: [SECURITY] Brief description of issue
Please do NOT:
- Open public GitHub issues for security vulnerabilities
- Discuss security issues in public forums or chat rooms
- Share vulnerabilities on social media before resolution
Response Timeline
- Initial Response: Within 48 hours of report
- Assessment: Within 7 days for severity classification
- Resolution: Timeline depends on complexity and severity
- Disclosure: Coordinated disclosure after fix is available
What to Include
- Vulnerability Description: Clear explanation of the issue
- Impact Assessment: Potential security implications
- Reproduction Steps: Detailed steps to reproduce the issue
- Proof of Concept: Code or commands demonstrating the vulnerability
- Environment Details: Operating system, Rust version, library version
- Suggested Fix: If you have recommendations for resolution
For complete details including scope, security model, and recognition policy, see the full Security Policy.
Unsafe Code Guide
Cypheron Core contains unsafe Rust code required for FFI integration with NIST C reference implementations. This section provides an overview of our unsafe code usage and safety guarantees.
For complete documentation of all unsafe code blocks, see the comprehensive Unsafe Code Guide.
Overview
The library contains 91 unsafe blocks across 19 files, each with detailed safety justifications. All unsafe code is:
- Documented with safety invariants
- Required for FFI with C vendor code
- Minimized to essential operations
- Reviewed for memory safety
Categories of Unsafe Code
1. FFI Function Calls
Direct calls to C cryptographic functions from NIST reference implementations.
Safety Guarantee: Buffer bounds validated before calls, return codes checked.
2. Pointer Dereferencing
Converting Rust slices to raw pointers for C function parameters.
Safety Guarantee: Pointers derived from valid Rust references, lifetimes controlled.
3. Memory Operations
Buffer initialization and secure cleanup operations.
Safety Guarantee: All operations within allocated bounds, proper initialization verified.
4. Platform-Specific Code
OS-specific secure random number generation and memory protection.
Safety Guarantee: Platform APIs used according to documentation, error handling comprehensive.
Security Audit Considerations
Each unsafe block is documented with:
- Safety Invariant: What conditions must hold for safety
- Justification: Why the unsafe operation is necessary
- Verification: How safety is ensured in practice
- Error Handling: What happens when invariants are violated
Complete Documentation
For detailed analysis of every unsafe block including line-by-line safety justifications, see:
This comprehensive guide provides security auditors with complete visibility into all potentially unsafe operations.
Audit Readiness
Cypheron Core (v0.1.1) has been prepared for professional security audits with comprehensive documentation and transparency measures.
Current Status
Status: [X] AUDIT READY - Complete documentation and security analysis finished
Phase: Seeking community audit and professional security evaluation
Timeline: Q4 2025 community audit, 2026 professional audit
Audit Documentation Package
1. Security Architecture
- Security Architecture - Complete security model
- FFI Boundary Analysis - Trust boundaries and memory safety
- Memory Safety Model - Safety guarantees and validation
2. Code Transparency
- Unsafe Code Guide - All 91 unsafe blocks documented
- Build System Security - Secure compilation process
- Vendor Code Integrity - Supply chain security
3. Security Policies
- Security Policy - Vulnerability reporting and response
- Development Roadmap - Current priorities and timeline
Audit Scope
In Scope
- FFI boundary security between Rust and C code
- Memory safety of wrapper implementations
- Build system security and vendor code integrity
- API design and usage patterns
- Error handling and secure cleanup
- Platform-specific security implementations
Out of Scope
- NIST C reference implementation algorithms (externally audited)
- Standard Rust compiler safety guarantees
- Operating system security features
- Network protocol implementations (none present)
Auditor Resources
Documentation Hierarchy
PROJECT ROOT/
├── SECURITY.md # Primary security policy
├── ARCHITECTURE.md # Complete security architecture
├── UNSAFE_GUIDE.md # All unsafe code documentation
├── ROADMAP.md # Development status and priorities
└── docs/ # Comprehensive documentation
├── security/ # Security-focused documentation
├── architecture/ # Technical architecture details
└── development/ # Build and development processes
Key Audit Entry Points
- Security Model - Start here for overall security approach
- FFI Boundary - Primary attack surface analysis
- Unsafe Code Guide - All potentially vulnerable code sections
Community Audit Process
Current Phase: Community Validation
- Open source security community review
- Academic cryptography community feedback
- Independent security researcher analysis
- Public vulnerability disclosure process
How to Participate
- Review Security Policy for vulnerability reporting
- Examine Unsafe Code Guide for code analysis
- Test security properties using provided test suite
- Report findings through responsible disclosure process
Professional Audit Preparation
Following successful community validation:
- Engage qualified cryptographic auditing firm
- Execute formal security audit of all components
- Address any findings from security audit
- Obtain public security audit report
- Prepare for production release
Standards Compliance
Prepared for evaluation against:
- NIST post-quantum cryptography standards (FIPS 203, 204, 205)
- Memory safety best practices for Rust FFI
- Supply chain security standards
- Open source security audit methodologies
For current development status and priorities, see the Development Roadmap.
Contributing Guidelines
We welcome contributions to Cypheron Core! This project implements post-quantum cryptography with a focus on security and reliability.
Development Status
Current Phase: Seeking community audit and validation (Q4 2025) Status: v0.1.1 - Foundation complete, documentation finished
Areas for Contribution
High Priority
- Security Analysis - Review FFI boundary implementations
- Code Review - Examine unsafe code blocks and safety justifications
- Testing - Add test cases, fuzzing, property-based testing
- Documentation - Improve API docs and usage examples
Standard Contributions
- Bug fixes and error handling improvements
- Performance optimizations
- Platform compatibility enhancements
- Build system improvements
Security-Focused Development
Required Reading
Before contributing, please review:
- Security Policy - Vulnerability reporting process
- Unsafe Code Guide - All unsafe code documentation
- Architecture - Complete security architecture
Security Requirements
- All unsafe code must include detailed safety justifications
- FFI boundary changes require comprehensive testing
- Memory safety must be preserved across all changes
- Security properties must be validated
Development Process
1. Setup
git clone https://github.com/CypheronLabs/Cypheron-core.git
cd Cypheron-core
cargo build
cargo test
2. Code Standards
- Follow Rust standard formatting with
cargo fmt - Pass all lints with
cargo clippy - Maintain comprehensive test coverage
- Document all public APIs
3. Testing Requirements
- Unit tests for all new functionality
- Integration tests for algorithm implementations
- Known Answer Tests (KAT) for NIST compliance
- Property-based testing for cryptographic properties
4. Submission Process
- Fork the repository
- Create feature branch from main
- Implement changes with tests
- Run full test suite
- Submit pull request with detailed description
Pull Request Guidelines
Required Information
- Purpose: Clear description of changes and motivation
- Testing: Evidence of comprehensive testing
- Security Impact: Analysis of security implications
- Documentation: Updates to relevant documentation
Review Process
- Code Review: Technical implementation review
- Security Review: Security implications analysis
- Testing Validation: Comprehensive test execution
- Documentation Check: Accuracy and completeness
Unsafe Code Contributions
Changes to unsafe code require additional scrutiny:
Documentation Requirements
- Safety Invariant: What conditions ensure safety
- Justification: Why unsafe code is necessary
- Verification: How safety is validated
- Error Handling: Behavior when invariants are violated
Review Process
- Manual code review by multiple contributors
- Comprehensive testing including edge cases
- Memory safety validation with sanitizers
- Documentation accuracy verification
Community Standards
Communication
- Respectful and professional interaction
- Constructive feedback and suggestions
- Focus on technical merit and security
Quality Standards
- High-quality implementations
- Comprehensive testing
- Clear documentation
- Security-first mindset
Getting Help
Questions and Support
- GitHub Discussions: Technical questions and design discussions
- GitHub Issues: Bug reports and feature requests (non-security)
- Security Issues: Private disclosure via Security Policy
Resources
Recognition
Contributors will be acknowledged in:
- Release notes for significant contributions
- Project documentation for major features
- Security credits for vulnerability reports
Thank you for helping make post-quantum cryptography accessible and secure!
Build System Security
Cypheron Core’s build system implements comprehensive security measures to safely compile potentially untrusted C vendor code while maintaining security guarantees.
For complete technical details, see Architecture Documentation.
Build Security Pipeline
┌─────────────────────────────────────────────────────────────┐
│ BUILD SECURITY PIPELINE │
├─────────────────────────────────────────────────────────────┤
│ 1. Pre-Build Security Checks │
│ ├─ Vendor code integrity verification │
│ ├─ Build dependency validation │
│ └─ Toolchain security verification │
├─────────────────────────────────────────────────────────────┤
│ 2. Secure Compilation Phase │
│ ├─ Security-hardened compiler flags │
│ ├─ Platform-specific optimizations │
│ └─ Stack protection enablement │
├─────────────────────────────────────────────────────────────┤
│ 3. FFI Binding Generation │
│ ├─ API surface minimization │
│ ├─ Function allowlisting │
│ └─ Type safety enforcement │
└─────────────────────────────────────────────────────────────┘
Vendor Code Integrity
Verification Process
# Automated integrity verification
find vendor/ -name "*.c" -o -name "*.h" | xargs sha256sum > SHA256SUMS
sha256sum -c SHA256SUMS
Security Properties
- Tamper Detection: Any modification to vendor code detected immediately
- Reproducible Builds: Consistent verification across environments
- Build Failure on Mismatch: Compilation halts if integrity check fails
- Version Control Integration: Checksum files tracked in git
Vendor Sources
| Algorithm | Official Source | Verification |
|---|---|---|
| ML-KEM | NIST FIPS 203 Reference | SHA-256 checksums |
| ML-DSA | NIST FIPS 204 Reference | SHA-256 checksums |
| Falcon | NIST PQC Round 3 | SHA-256 checksums |
| SPHINCS+ | NIST PQC Round 3 | SHA-256 checksums |
Secure Compilation
Security-Hardened Compiler Flags
Stack Protection:
#![allow(unused)] fn main() { cc.flag("-fstack-protector-strong"); // Stack canary protection cc.flag("-D_FORTIFY_SOURCE=2"); // Buffer overflow detection }
Control Flow Integrity:
#![allow(unused)] fn main() { #[cfg(target_os = "linux")] cc.flag("-fcf-protection=full"); // Intel CET support #[cfg(target_os = "windows")] cc.flag("/guard:cf"); // Windows CFG }
Memory Safety Hardening:
#![allow(unused)] fn main() { cc.flag("-fPIE"); // Position Independent Executable cc.flag("-Wl,-z,relro"); // Read-only relocations cc.flag("-Wl,-z,now"); // Immediate symbol resolution }
Platform-Specific Security
Linux Security Features:
#![allow(unused)] fn main() { cc.flag("-fstack-clash-protection"); // Stack clash protection cc.flag("-fcf-protection=full"); // Control Flow Integrity cc.flag("-mshstk"); // Shadow stack (Intel CET) }
Windows Security Features:
#![allow(unused)] fn main() { cc.flag("/GS"); // Stack buffer security check cc.flag("/guard:cf"); // Control Flow Guard cc.flag("/DYNAMICBASE"); // ASLR support }
FFI Binding Security
API Surface Minimization
Function Allowlisting:
#![allow(unused)] fn main() { let allowed_functions = vec![ "crypto_kem_keypair", "crypto_kem_enc", "crypto_kem_dec", "crypto_sign_keypair", "crypto_sign", "crypto_sign_open", // Only essential cryptographic functions exposed ]; }
Type Restriction:
#![allow(unused)] fn main() { bindgen_builder .allowlist_type("crypto_.*") .blocklist_type("internal_.*") // Block internal details .opaque_type("rng_state") // Opaque sensitive structures }
Security Through Isolation
Symbol Visibility Control:
#![allow(unused)] fn main() { cc.flag("-fvisibility=hidden"); // Hide symbols by default cc.define("CRYPTO_API", "extern"); // Explicit API marking // Platform-specific symbol control #[cfg(target_os = "windows")] cc.define("CRYPTO_EXPORT", "__declspec(dllexport)"); #[cfg(unix)] cc.define("CRYPTO_EXPORT", "__attribute__((visibility(\"default\")))"); }
Static Linking Security:
#![allow(unused)] fn main() { cc.static_flag(true); // Force static linking cc.shared_flag(false); // Prevent DLL injection cc.flag("-static-libgcc"); // Static runtime linking }
Build Reproducibility
Deterministic Compilation
#![allow(unused)] fn main() { cc.flag("-frandom-seed=0"); // Reproducible randomization cc.env("SOURCE_DATE_EPOCH", "1609459200"); // Reproducible timestamps cc.flag("-fdebug-prefix-map=/build=."); // Reproducible debug paths }
Build Audit Trail
#![allow(unused)] fn main() { println!("cargo:warning=Building with security flags: {:?}", security_flags); println!("cargo:warning=Target architecture: {}", target_arch()); println!("cargo:warning=Compiler version: {}", compiler_version()); }
Development Build Commands
Standard Build
cargo build # Debug build with all security checks
cargo build --release # Optimized build with security hardening
Security Validation
cargo clippy # Static analysis and security lints
cargo test # Comprehensive test suite
cargo audit # Dependency security audit
Platform-Specific Builds
# Linux with maximum security features
RUSTFLAGS="-C target-cpu=native" cargo build --release
# Windows with enhanced security
cargo build --target x86_64-pc-windows-msvc --release
# macOS with Apple Silicon optimizations
cargo build --target aarch64-apple-darwin --release
Continuous Integration Security
Security Validation Pipeline
- Vendor Integrity Check: Verify all C code checksums
- Compiler Security Audit: Validate security flags applied
- Binary Analysis: Static analysis of generated binaries
- Symbol Analysis: Verify minimal symbol exposure
- Runtime Security Testing: Validate security features
Security Regression Prevention
- All security flags tracked in version control
- Build failures on missing security features
- Automated security flag regression detection
- Platform-specific security feature validation
For complete build system architecture including dependency management and security validation, see the full Architecture Documentation.
Testing and Validation
Cypheron Core implements comprehensive testing across multiple validation layers to ensure NIST compliance, cryptographic correctness, and security properties.
For complete technical details, see Architecture Documentation.
Testing Categories
1. Known Answer Tests (KAT)
Purpose: NIST compliance validation using official test vectors
cargo test kat_ # Run all KAT tests
cargo test ml_kem_kat # ML-KEM specific KAT
cargo test ml_dsa_kat # ML-DSA specific KAT
Coverage:
- FIPS 203 (ML-KEM) compliance validation
- FIPS 204 (ML-DSA) compliance validation
- Parameter compliance verification
- Cross-platform consistency testing
2. Property-Based Testing
Purpose: Cryptographic property verification using proptest
cargo test property_ # All property-based tests
cargo test correctness_ # Cryptographic correctness
cargo test roundtrip_ # Encryption/decryption cycles
Properties Verified:
- Key generation produces valid keypairs
- Encryption/decryption roundtrip correctness
- Signature generation/verification consistency
- Hybrid cryptography composition properties
3. Security Analysis Testing
Purpose: Security vulnerability detection and validation
cargo test security_ # Security-focused tests
cargo test timing_ # Basic timing attack detection
cargo test memory_safety_ # Memory safety validation
Security Testing:
- Memory safety validation with sanitizers
- Basic timing attack resistance
- Buffer boundary protection testing
- FFI safety validation
4. Fuzzing Infrastructure
Purpose: Robustness testing with malformed and edge-case inputs
# Install cargo-fuzz
cargo install cargo-fuzz
# Run fuzzing campaigns
cargo fuzz run fuzz_ml_kem # ML-KEM fuzzing
cargo fuzz run fuzz_ml_dsa # ML-DSA fuzzing
cargo fuzz run fuzz_hybrid # Hybrid crypto fuzzing
Fuzzing Targets:
- Algorithm input validation
- FFI boundary robustness
- Error handling completeness
- Memory safety under stress
5. Performance Benchmarking
Purpose: Performance regression detection and analysis
cargo bench # Run all benchmarks
cargo bench ml_kem # ML-KEM performance
cargo bench signatures # Signature algorithm performance
Performance Metrics:
- Key generation timing
- Encryption/decryption performance
- Signature generation/verification speed
- Memory usage analysis
NIST Compliance Testing
Test Vector Validation
The KAT implementation validates against official NIST test vectors:
#![allow(unused)] fn main() { #[test] fn test_ml_kem_768_kat() { // Load NIST test vectors let test_vectors = load_nist_kat_vectors("ML-KEM-768"); for vector in test_vectors { // Validate key generation let (pk, sk) = MlKem768::keypair_deterministic(&vector.seed)?; assert_eq!(pk.as_bytes(), &vector.public_key); assert_eq!(sk.as_bytes(), &vector.secret_key); // Validate encapsulation let (ct, ss) = MlKem768::encapsulate_deterministic(&pk, &vector.enc_seed)?; assert_eq!(ct.as_bytes(), &vector.ciphertext); assert_eq!(ss.expose_secret(), &vector.shared_secret); } } }
Integration Testing
#![allow(unused)] fn main() { #[test] fn test_algorithm_integration() { // Cross-algorithm compatibility test_hybrid_kem_dsa_integration(); // Platform consistency test_cross_platform_compatibility(); // Error handling test_comprehensive_error_cases(); } }
Security Testing
Memory Safety Testing
# AddressSanitizer
RUSTFLAGS="-Zsanitizer=address" cargo test
# MemorySanitizer
RUSTFLAGS="-Zsanitizer=memory" cargo test
# ThreadSanitizer
RUSTFLAGS="-Zsanitizer=thread" cargo test
FFI Boundary Testing
#![allow(unused)] fn main() { #[test] fn test_ffi_boundary_safety() { // Buffer boundary validation test_buffer_overflow_protection(); // Null pointer handling test_null_pointer_safety(); // Invalid input handling test_malformed_input_handling(); // Error propagation test_c_error_handling(); } }
Timing Analysis
#![allow(unused)] fn main() { #[test] fn test_timing_side_channels() { // Basic constant-time validation let measurements = measure_operation_timing(); validate_timing_consistency(&measurements); } }
Development Testing Workflow
Pre-Commit Testing
#!/bin/bash
# scripts/pre-commit-test.sh
# Format check
cargo fmt --check
# Lint check
cargo clippy -- -D warnings
# Unit tests
cargo test --all
# Integration tests
cargo test --test integration
# Documentation tests
cargo test --doc
Continuous Integration Testing
# .github/workflows/test.yml (excerpt)
- name: Security Testing
run: |
# Memory safety testing
RUSTFLAGS="-Zsanitizer=address" cargo test
# Dependency audit
cargo audit
# Security lints
cargo clippy -- -D warnings -W clippy::all
Platform Testing Matrix
| Platform | Rust Version | Test Suite | Additional Validation |
|---|---|---|---|
| Linux x86_64 | stable, beta, nightly | Full | AddressSanitizer, Valgrind |
| macOS x86_64 | stable | Full | Instruments profiling |
| macOS ARM64 | stable | Full | Apple Silicon validation |
| Windows x86_64 | stable | Full | Visual Studio analysis |
Test Data Management
NIST Test Vectors
tests/data/
├── kat/
│ ├── ml-kem-512.rsp # NIST KAT for ML-KEM-512
│ ├── ml-kem-768.rsp # NIST KAT for ML-KEM-768
│ ├── ml-kem-1024.rsp # NIST KAT for ML-KEM-1024
│ ├── ml-dsa-44.rsp # NIST KAT for ML-DSA-44
│ └── ...
└── vectors/
├── property_test_seeds.txt
└── fuzzing_corpus/
Test Coverage Reporting
# Generate coverage report
cargo install cargo-tarpaulin
cargo tarpaulin --out Html --output-dir coverage/
# View coverage report
open coverage/tarpaulin-report.html
Contributing Testing
Adding New Tests
- Unit Tests: Add alongside implementation in
src/ - Integration Tests: Add to
tests/directory - KAT Tests: Update with new NIST vectors when available
- Property Tests: Add to
tests/property/ - Fuzzing: Add new fuzz targets in
fuzz/
Test Quality Standards
- Comprehensive Coverage: All public APIs tested
- Edge Case Testing: Boundary conditions validated
- Error Path Testing: All error conditions exercised
- Performance Testing: No performance regressions
- Security Testing: Security properties validated
For complete testing architecture including specific test implementations and validation methodologies, see the full Architecture Documentation.
Error Codes Reference
Complete reference for all error codes in Cypheron Core.
KEM Errors
ERROR-KEM-001
Key Generation Entropy Failure
Cause: Insufficient entropy available for key generation.
Solution:
#![allow(unused)] fn main() { // Ensure your system has adequate entropy // On Linux: check /proc/sys/kernel/random/entropy_avail // Consider using hardware RNG if available use cypheron_core::kem::{MlKem768, Kem}; // Retry with backoff for attempt in 1..=3 { match MlKem768::keypair() { Ok(keys) => return Ok(keys), Err(e) if attempt < 3 => { std::thread::sleep(std::time::Duration::from_millis(100 * attempt)); continue; }, Err(e) => return Err(e), } } }
ERROR-KEM-002
Decapsulation Invalid Ciphertext
Cause: Ciphertext was corrupted or not generated with the corresponding public key.
Solution:
#![allow(unused)] fn main() { use cypheron_core::kem::{MlKem768, Kem}; let (pk, sk) = MlKem768::keypair().unwrap(); let (ct, ss1) = MlKem768::encapsulate(&pk).unwrap(); // Verify ciphertext length before decapsulation if ct.len() != 1088 { // ML-KEM-768 ciphertext size return Err("Invalid ciphertext size"); } match MlKem768::decapsulate(&ct, &sk) { Ok(shared_secret) => { /* success */ }, Err(e) => { // Check if ciphertext is corrupted // Verify it was generated with correct public key eprintln!("Decapsulation failed: {}", e); } } }
ERROR-KEM-003
Encapsulation Invalid Public Key
Cause: Public key format is invalid or corrupted.
Solution:
#![allow(unused)] fn main() { // Validate public key before use use cypheron_core::kem::{MlKem768, Kem}; fn validate_public_key(pk_bytes: &[u8]) -> Result<(), &'static str> { if pk_bytes.len() != 1184 { // ML-KEM-768 public key size return Err("Invalid public key size"); } // Additional validation logic... Ok(()) } // Use validated public key if let Err(e) = validate_public_key(&pk_bytes) { return Err(format!("Public key validation failed: {}", e)); } }
Signature Errors
ERROR-SIG-001
Signature Generation Failed
Cause: Internal error during signature generation, possibly due to entropy issues.
Solution:
#![allow(unused)] fn main() { use cypheron_core::sig::{MlDsa65, SignatureEngine}; let message = b"message to sign"; let (pk, sk) = MlDsa65::keypair().unwrap(); match MlDsa65::sign(message, &sk) { Ok(signature) => { /* success */ }, Err(e) => { // Check message size (ML-DSA has no message size limit) // Verify secret key integrity // Ensure adequate system entropy eprintln!("Signature generation failed: {}", e); } } }
ERROR-SIG-002
Signature Verification Failed
Cause: Signature is invalid, message was modified, or wrong public key used.
Solution:
#![allow(unused)] fn main() { use cypheron_core::sig::{MlDsa65, SignatureEngine}; // Ensure exact message match let original_message = b"Hello, world!"; let modified_message = b"Hello, world?"; // Note the different punctuation let (pk, sk) = MlDsa65::keypair().unwrap(); let signature = MlDsa65::sign(original_message, &sk).unwrap(); // This will fail let valid = MlDsa65::verify(modified_message, &signature, &pk); assert!(!valid); // Verification fails due to message modification // This will succeed let valid = MlDsa65::verify(original_message, &signature, &pk); assert!(valid); }
Hybrid Errors
ERROR-HYBRID-001
Composite Key Generation Failed
Cause: Failure in either classical or post-quantum key generation.
Solution:
#![allow(unused)] fn main() { use cypheron_core::hybrid::{EccDilithium, HybridEngine}; // Retry hybrid key generation with error isolation match EccDilithium::keypair() { Ok(keys) => { /* success */ }, Err(e) => { // Error could be from ECC or ML-DSA component // Check system entropy and crypto library status eprintln!("Hybrid key generation failed: {}", e); // Consider fallback to individual algorithms for debugging use cypheron_core::sig::{MlDsa44, SignatureEngine}; let pq_test = MlDsa44::keypair(); match pq_test { Ok(_) => println!("Post-quantum component working"), Err(e) => println!("Post-quantum issue: {}", e), } } } }
Platform-Specific Errors
ERROR-PLATFORM-001
Windows Entropy Source Unavailable
Cause: Windows CryptoAPI is not accessible.
Solution:
#![allow(unused)] fn main() { // Ensure Windows CryptoAPI is available // This is rare but can happen in restricted environments #[cfg(target_os = "windows")] fn check_windows_crypto() -> Result<(), Box<dyn std::error::Error>> { // The library will automatically fallback to other entropy sources // but you can manually check availability use cypheron_core::platform::secure_random_bytes; let mut buffer = vec![0u8; 32]; secure_random_bytes(&mut buffer)?; Ok(()) } }
Memory Errors
ERROR-MEM-001
Secure Memory Allocation Failed
Cause: System cannot allocate secure memory for sensitive operations.
Solution:
#![allow(unused)] fn main() { // Reduce memory pressure or increase available memory // Check system memory limits and available RAM use cypheron_core::kem::{MlKem512, Kem}; // Use smaller variant if needed // Consider using smaller security parameters temporarily let (pk, sk) = MlKem512::keypair()?; // Instead of MlKem1024 }
FFI Errors
ERROR-FFI-001
C Library Binding Failed
Cause: Underlying C library call failed.
Solution:
#![allow(unused)] fn main() { // This indicates an issue with the vendor C implementations // Usually due to memory corruption or invalid parameters // Enable debug logging to get more details std::env::set_var("RUST_LOG", "debug"); env_logger::init(); // The error will include more detailed information in debug mode }
Debugging Tips
Enable Detailed Logging
// Add to your Cargo.toml [dependencies] env_logger = "0.10" // In your code fn main() { env_logger::init(); // Your code here - errors will include more details }
Validate Input Data
#![allow(unused)] fn main() { use cypheron_core::kem::{MlKem768, Kem}; fn safe_decapsulate(ct: &[u8], sk: &SecretKey) -> Result<SharedSecret, String> { // Validate ciphertext size if ct.len() != 1088 { return Err(format!("Invalid ciphertext size: expected 1088, got {}", ct.len())); } // Additional validation... MlKem768::decapsulate(ct, sk) .map_err(|e| format!("Decapsulation failed: {}", e)) } }
Test with Known Good Data
#![allow(unused)] fn main() { #[cfg(test)] mod tests { use super::*; #[test] fn test_with_known_vectors() { // Use NIST test vectors for validation // See tests/kat/ directory for examples let (pk, sk) = MlKem768::keypair().unwrap(); let (ct, ss1) = MlKem768::encapsulate(&pk).unwrap(); let ss2 = MlKem768::decapsulate(&ct, &sk).unwrap(); assert_eq!(ss1.expose_secret(), ss2.expose_secret()); } } }
Getting Help
If you encounter an error not covered here:
- Check the FAQ for common solutions
- Enable debug logging to get more details
- Search GitHub Issues
- Create a minimal reproduction case
- File a new issue with full error details
See Also
- Common Issues - Frequent problems and solutions
- Debug Guide - Advanced debugging techniques
- API Reference - Error type documentation