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)

ML-KEM-512
Security Level 1
ML-KEM-768
Security Level 3
ML-KEM-1024
Security Level 5

Digital Signatures

ML-DSA-44
Security Level 2
ML-DSA-65
Security Level 3
ML-DSA-87
Security Level 5
Falcon-512
Security Level 1
Falcon-1024
Security Level 5
SPHINCS+
Multiple variants available

Hybrid Cryptography

  • ECC + ML-DSA: Classical elliptic curve + post-quantum signatures
  • Hybrid KEM: Combined classical and post-quantum key agreement

Performance

AlgorithmKey GenSign/EncapsVerify/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

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.


Development Status: This library (v0.1.0) contains experimental implementations and has not been audited. DO NOT USE IN PRODUCTION without thorough security review. Built with C vendor code + Rust FFI requiring careful validation. See Security Model 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 support
  • alloc: Allocation support for no_std environments
  • hybrid: Hybrid cryptography algorithms
  • serialize: 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

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

Production Checklist

Before using in production:

  1. Read the Security Model
  2. Review Compliance Requirements
  3. Set up Monitoring
  4. Test your Error Handling
  5. 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

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

Development

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:

VariantSecurity LevelClassical SecurityQuantum SecurityKey Sizes
ML-KEM-5121~128-bit~64-bitPK: 800B, SK: 1632B
ML-KEM-7683~192-bit~96-bitPK: 1184B, SK: 2400B
ML-KEM-10245~256-bit~128-bitPK: 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

  1. Generate matrix A from public randomness
  2. Generate secret vectors s and e from centered binomial distribution
  3. Compute t = A·s + e
  4. Public key: (ρ, t), Secret key: s

Encapsulation

  1. Generate ephemeral secret r and error vectors e1, e2
  2. Compute u = A^T·r + e1
  3. Compute v = t^T·r + e2 + Encode(m)
  4. Return ciphertext (u, v) and shared secret KDF(m)

Decapsulation

  1. Compute m’ = Decode(v - s^T·u)
  2. Re-encapsulate with m’ to get (u’, v’)
  3. 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

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:

VariantSecurity LevelPublic KeySecret KeySignature
ML-DSA-44Level 2 (~112-bit)1,312 bytes2,560 bytes2,420 bytes
ML-DSA-65Level 3 (~128-bit)1,952 bytes4,032 bytes3,293 bytes
ML-DSA-87Level 5 (~256-bit)2,592 bytes4,896 bytes4,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

  • 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)

OperationML-DSA-44ML-DSA-65ML-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)

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:

VariantSecurity LevelPublic KeySecret KeySignature
Falcon-512Level 1 (~112-bit)897 bytes1,281 bytes~666 bytes
Falcon-1024Level 5 (~256-bit)1,793 bytes2,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

  • 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)

OperationFalcon-512Falcon-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

AspectFalconML-DSA
Signature SizeSmaller (~666 bytes)Larger (~2,420+ bytes)
Key GenerationSlowerFaster
VerificationFastFast
ImplementationMore complexSimpler
StandardizationNIST Round 3 finalistNIST 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

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

VariantSecurity LevelPublic KeySecret KeySignature
sphincs-sha256-128sLevel 1 (small sig)32 bytes64 bytes7,856 bytes
sphincs-sha256-128fLevel 1 (fast)32 bytes64 bytes17,088 bytes
sphincs-sha256-192sLevel 3 (small sig)48 bytes96 bytes16,224 bytes
sphincs-sha256-192fLevel 3 (fast)48 bytes96 bytes35,664 bytes
sphincs-sha256-256sLevel 5 (small sig)64 bytes128 bytes29,792 bytes
sphincs-sha256-256fLevel 5 (fast)64 bytes128 bytes49,856 bytes

SPHINCS+-SHAKE256 Variants

VariantSecurity LevelPublic KeySecret KeySignature
sphincs-shake256-128sLevel 1 (small sig)32 bytes64 bytes7,856 bytes
sphincs-shake256-128fLevel 1 (fast)32 bytes64 bytes17,088 bytes
sphincs-shake256-192sLevel 3 (small sig)48 bytes96 bytes16,224 bytes
sphincs-shake256-192fLevel 3 (fast)48 bytes96 bytes35,664 bytes
sphincs-shake256-256sLevel 5 (small sig)64 bytes128 bytes29,792 bytes
sphincs-shake256-256fLevel 5 (fast)64 bytes128 bytes49,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
  • 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)

VariantKey GenerationSignVerify
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

AspectSPHINCS+ML-DSA/Falcon
Security ModelHash functions onlyLattice problems
Signature SizeLarge (7KB-50KB)Small (0.7KB-4KB)
Key SizeSmall (32-128 bytes)Medium (1-3KB)
SpeedSlowerFaster
Quantum ResistanceVery conservativeWell-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

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:

  1. Classical Security: Protection against traditional computing threats
  2. Quantum Resistance: Protection against quantum computer attacks
  3. Migration Safety: Smooth transition from classical to post-quantum
  4. 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:

PolicySecurity LevelDescription
BothRequiredmin(classical, pq)Weakest component determines security
EitherValidmax(classical, pq)Strongest component determines security
PostQuantumPreferredpost-quantumPrioritizes 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

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

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

ComponentModule PathPrimary TypesPurpose
ML-KEM(Kyber)kem/MlKem512, MlKem768, MlKem1024Key encapsulation mechanisms
Digital Signaturessig/MlDsa44, MlDsa65, MlDsa87, Falcon512, Falcon1024Post-quantum digital signatures
Hybrid Cryptographyhybrid/P256mlKem768, EccDilithium, CompositeKeypairClassical + 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

PlatformSecure RandomMemory ProtectionKey Features
WindowsBCryptGenRandomVirtualProtectBCrypt API, Windows Crypto
macOSSecRandommprotectSecurity Framework, Apple Silicon detection
Linuxgetrandom syscallmprotectHardware RNG detection, CPU affinity

Testing and Validation

The testing infrastructure includes:

  1. Known Answer Tests (KAT) - NIST compliance validation
  2. Property Based Testing - Cryptographic property verification
  3. Security Analysis - Timing attacks and memory safety
  4. Fuzzing Infrastructure - Robustness testing
  5. 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

  1. FFI Boundary Exploitation: Buffer overflows, type confusion
  2. Memory Safety Violations: Use-after-free, double-free in unsafe code
  3. Supply Chain Attacks: Compromised vendor code, build system tampering
  4. Side-Channel Analysis: Timing attacks, power analysis

Mitigation Strategies

  1. Comprehensive Input Validation: All FFI inputs validated before C calls
  2. Bounded Buffer Operations: All C functions receive exact buffer sizes
  3. Integrity Verification: Cryptographic verification of vendor code
  4. 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)

  1. Input Validation: All parameters validated against algorithm specifications
  2. Buffer Preparation: Memory allocated with exact required sizes
  3. Pointer Safety: Raw pointers derived only from valid Rust references
  4. Length Verification: Buffer sizes cross-checked against C function expectations

Outbound Path (C → Rust)

  1. Return Code Verification: All C function return values checked
  2. Output Validation: Generated data verified for proper initialization
  3. Size Consistency: Output lengths validated against expected algorithm outputs
  4. 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

  1. Static Analysis: Rust compiler checks and Clippy lints
  2. Dynamic Testing: AddressSanitizer and MemorySanitizer
  3. Fuzzing: Automated testing with malformed inputs
  4. Property Testing: Cryptographic property verification
  5. 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:

  1. Classical Computers: Unlimited classical computational power
  2. Quantum Computers: Large-scale fault-tolerant quantum computers
  3. Side-Channel Attacks: Timing, power, and electromagnetic analysis
  4. 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

LevelClassical SecurityQuantum SecurityReal-World Equivalent
1128-bit64-bitAES-128
2128-bit64-bitSHA-256
3192-bit96-bitAES-192
4192-bit96-bitSHA-256
5256-bit128-bitAES-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

  1. Generation: High-entropy key creation
  2. Storage: Encrypted at rest when possible
  3. Usage: Minimal exposure time
  4. 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

  1. Monitor Entropy: Check system entropy levels
  2. Log Security Events: Record cryptographic failures
  3. Update Regularly: Keep libraries up to date
  4. Test Thoroughly: Validate all error paths

See Also

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

  1. Vulnerability Description: Clear explanation of the issue
  2. Impact Assessment: Potential security implications
  3. Reproduction Steps: Detailed steps to reproduce the issue
  4. Proof of Concept: Code or commands demonstrating the vulnerability
  5. Environment Details: Operating system, Rust version, library version
  6. 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

2. Code Transparency

3. Security Policies

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

  1. Security Model - Start here for overall security approach
  2. FFI Boundary - Primary attack surface analysis
  3. 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

  1. Security Analysis - Review FFI boundary implementations
  2. Code Review - Examine unsafe code blocks and safety justifications
  3. Testing - Add test cases, fuzzing, property-based testing
  4. 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 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

AlgorithmOfficial SourceVerification
ML-KEMNIST FIPS 203 ReferenceSHA-256 checksums
ML-DSANIST FIPS 204 ReferenceSHA-256 checksums
FalconNIST PQC Round 3SHA-256 checksums
SPHINCS+NIST PQC Round 3SHA-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

  1. Vendor Integrity Check: Verify all C code checksums
  2. Compiler Security Audit: Validate security flags applied
  3. Binary Analysis: Static analysis of generated binaries
  4. Symbol Analysis: Verify minimal symbol exposure
  5. 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

PlatformRust VersionTest SuiteAdditional Validation
Linux x86_64stable, beta, nightlyFullAddressSanitizer, Valgrind
macOS x86_64stableFullInstruments profiling
macOS ARM64stableFullApple Silicon validation
Windows x86_64stableFullVisual 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

  1. Unit Tests: Add alongside implementation in src/
  2. Integration Tests: Add to tests/ directory
  3. KAT Tests: Update with new NIST vectors when available
  4. Property Tests: Add to tests/property/
  5. 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:

  1. Check the FAQ for common solutions
  2. Enable debug logging to get more details
  3. Search GitHub Issues
  4. Create a minimal reproduction case
  5. File a new issue with full error details

See Also