### Complete Quantum-Secure Communication Example Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/README.md Combines ML-KEM key exchange with ChaCha20-Poly1305 for end-to-end quantum-secure communication. This example covers key generation, encapsulation, decapsulation, key derivation using HKDF, and symmetric encryption/decryption. ```rust use saorsa_pqc::api::{ml_kem_768, ChaCha20Poly1305}; use saorsa_pqc::api::symmetric::generate_nonce; // Alice generates ML-KEM keypair let kem = ml_kem_768(); let (alice_pk, alice_sk) = kem.generate_keypair()?; // Bob encapsulates a shared secret using Alice's public key let (shared_secret, ciphertext) = kem.encapsulate(&alice_pk)?; // Alice decapsulates to get the same shared secret let recovered_secret = kem.decapsulate(&alice_sk, &ciphertext)?; // Derive proper encryption key from shared secret using HKDF use saorsa_pqc::api::kdf::HkdfSha3_256; use saorsa_pqc::api::traits::Kdf; let mut encryption_key = [0u8; 32]; HkdfSha3_256::derive( &shared_secret.to_bytes(), None, b"saorsa-pqc encryption key", &mut encryption_key )?; // Create cipher with derived key let cipher = ChaCha20Poly1305::new(&encryption_key); // Now Bob can encrypt messages to Alice let nonce = generate_nonce(); let message = b"Quantum-secure message"; let encrypted = cipher.encrypt(&nonce, message)?; // Alice decrypts using the same key let decrypted = cipher.decrypt(&nonce, &encrypted)?; assert_eq!(decrypted, message); ``` -------------------------------- ### Development Setup: Cloning, Testing, Benchmarking, and Linting Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/README.md Provides essential bash commands for setting up the development environment, including cloning the repository, running tests, executing benchmarks, and performing code quality checks with clippy and fmt. ```bash # Clone the repository git clone https://github.com/dirvine/saorsa-pqc cd saorsa-pqc # Run tests cargo test --all-features # Run benchmarks cargo bench # Check code quality cargo clippy --all-features ``` -------------------------------- ### ML-DSA-65 Usage Example in Rust Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/docs/ml-dsa-65-implementation.md Demonstrates the basic usage of the ML-DSA-65 cryptographic algorithm, including key generation, signing, and signature verification. Requires the `saorsa-pqc` library. ```rust use saorsa_pqc::pqc::ml_dsa_65::{MlDsa65, MlDsa65Operations}; // Create ML-DSA-65 instance let ml_dsa = MlDsa65::new(); // Generate keypair let (public_key, secret_key) = ml_dsa.generate_keypair()?; // Sign a message let message = b"Important document to sign"; let signature = ml_dsa.sign(&secret_key, message, None)?; // Verify signature let is_valid = ml_dsa.verify(&public_key, message, &signature, None)?; assert!(is_valid); ``` -------------------------------- ### HKDF-SHA3 Key Derivation Examples Source: https://context7.com/saorsa-labs/saorsa-pqc/llms.txt Demonstrates various key derivation patterns using HKDF-SHA3-256 and HKDF-SHA3-512. Requires input key material, an optional salt, and context information. Ensure salt is unique for security. ```rust use saorsa_pqc::api::kdf::KdfAlgorithm; use saorsa_pqc::api::traits::Kdf; fn main() -> Result<(), Box> { let ikm = b"input key material from KEM"; let salt = b"random 32-byte salt value!!!"; let info = b"saorsa-app v1 / session key"; // ── One-shot derive ─────────────────────────────────────────────────────── let key32 = KdfAlgorithm::HkdfSha3_256.derive(ikm, Some(salt), info, 32)?; let key64 = KdfAlgorithm::HkdfSha3_512.derive(ikm, Some(salt), info, 64)?; assert_eq!(key32.len(), 32); assert_eq!(key64.len(), 64); // ── Two-phase extract + expand ──────────────────────────────────────────── let prk = saorsa_pqc::api::kdf::HkdfSha3_256::extract(Some(salt), ikm); assert_eq!(prk.len(), 32); // PRK is SHA3-256 output length let mut okm = [0u8; 32]; saorsa_pqc::api::kdf::HkdfSha3_256::expand(&prk, info, &mut okm)?; // One-shot must produce the same result let mut okm2 = [0u8; 32]; saorsa_pqc::api::kdf::HkdfSha3_256::derive(ikm, Some(salt), info, &mut okm2)?; assert_eq!(okm, okm2); Ok(()) } ``` ```rust use saorsa_pqc::api::kdf::helpers::derive_enc_auth_keys; fn main() -> Result<(), Box> { let shared_secret = b"ml-kem-shared-secret-32-bytes!!!"; let context = b"saorsa-app v1 / key expansion"; let (enc_key, auth_key) = derive_enc_auth_keys(shared_secret, context)?; assert_eq!(enc_key.len(), 32); assert_eq!(auth_key.len(), 32); assert_ne!(&enc_key[..], &auth_key[..]); // must be independent Ok(()) } ``` ```rust use saorsa_pqc::api::kdf::helpers::derive_key_from_password; fn main() -> Result<(), Box> { let pass_key = derive_key_from_password(b"Passw0rd!", b"16-byte-salt!!!!", 100_000)?; assert_eq!(pass_key.len(), 32); println!("PBKDF2-SHA3 key: {} bytes ({})", pass_key.len(), hex::encode(&pass_key[..4])); Ok(()) } ``` ```rust use saorsa_pqc::api::kdf::helpers::stretch_key; fn main() -> Result<(), Box> { let stretched = stretch_key(b"short-key", b"session-encryption", 64)?; assert_eq!(stretched.len(), 64); Ok(()) } ``` ```rust use saorsa_pqc::api::kdf::helpers::derive_key_hierarchy; fn main() -> Result<(), Box> { let master = b"master-key-from-key-exchange"; let labels: &[&[u8]] = &[b"encryption", b"authentication", b"signing"]; let keys = derive_key_hierarchy(master, labels)?; assert_eq!(keys.len(), 3); for (k, label) in keys.iter().zip(labels) { println!("{}: {} bytes", std::str::from_utf8(label)?, k.len()); assert_eq!(k.len(), 32); } // All three keys must be distinct assert_ne!(&keys[0][..], &keys[1][..]); assert_ne!(&keys[1][..], &keys[2][..]); Ok(()) } ``` -------------------------------- ### ML-DSA Full Example: Keygen, Sign, Verify, Context-Bound Source: https://context7.com/saorsa-labs/saorsa-pqc/llms.txt Demonstrates the complete lifecycle of ML-DSA, including key generation, plain signing and verification, context-bound signing and verification for domain separation, and serialization of keys and signatures. Ensure the correct `MlDsaVariant` is used for key operations. ```rust use saorsa_pqc::api::{MlDsa, MlDsaVariant, MlDsaPublicKey, MlDsaSecretKey, MlDsaSignature}; fn main() -> Result<(), Box> { let dsa = MlDsa::new(MlDsaVariant::MlDsa65); // 192-bit security // --- Key generation --- let (public_key, secret_key) = dsa.generate_keypair()?; println!("PK size: {} bytes", public_key.to_bytes().len()); // 1952 println!("SK size: {} bytes", secret_key.to_bytes().len()); // 4032 // --- Plain signing and verification --- let message = b"Transfer $5000 from Alice to Bob"; let signature = dsa.sign(&secret_key, message)?; println!("Signature size: {} bytes", signature.to_bytes().len()); // 3309 assert!(dsa.verify(&public_key, message, &signature)?); assert!(!dsa.verify(&public_key, b"Tampered message", &signature)?); // --- Context-bound signing (domain separation) --- let context = b"BankingApp-v2.0-Transfer"; let ctx_sig = dsa.sign_with_context(&secret_key, message, context)?; assert!(dsa.verify_with_context(&public_key, message, &ctx_sig, context)?); // Wrong context fails assert!(!dsa.verify_with_context(&public_key, message, &ctx_sig, b"BankingApp-v1.0")?); // Plain verify also fails (empty context ≠ provided context) assert!(!dsa.verify(&public_key, message, &ctx_sig)?); // --- Serialization round-trip --- let pk_bytes = public_key.to_bytes(); let sk_bytes = secret_key.to_bytes(); let sig_bytes = signature.to_bytes(); let pk2 = MlDsaPublicKey::from_bytes(MlDsaVariant::MlDsa65, &pk_bytes)?; let sk2 = MlDsaSecretKey::from_bytes(MlDsaVariant::MlDsa65, &sk_bytes)?; let sig2 = MlDsaSignature::from_bytes(MlDsaVariant::MlDsa65, &sig_bytes)?; let new_sig = dsa.sign(&sk2, message)?; assert!(dsa.verify(&pk2, message, &new_sig)?); assert!(dsa.verify(&pk2, message, &sig2)?); // --- Variant overview --- for (variant, name) in [ (MlDsaVariant::MlDsa44, "ML-DSA-44"), (MlDsaVariant::MlDsa65, "ML-DSA-65"), (MlDsaVariant::MlDsa87, "ML-DSA-87"), ] { let d = MlDsa::new(variant); let (pk, sk) = d.generate_keypair()?; let s = d.sign(&sk, b"test")?; println!("{}: pk={}B sk={}B sig={}B", name, pk.to_bytes().len(), sk.to_bytes().len(), s.to_bytes().len()); } Ok(()) } ``` -------------------------------- ### PQC Trait-Based API Example Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/README.md Demonstrates using the trait-based API for ML-KEM and ML-DSA, including key generation, encapsulation/decapsulation, signing/verification, and BLAKE3 key derivation. Ensures constant-time operations and automatic zeroization of secret keys. ```rust use saorsa_pqc::pqc::{Kem, Sig, MlKem768Trait, MlDsa65Trait, ConstantTimeCompare}; // Key Encapsulation with trait API let (kem_pk, kem_sk) = MlKem768Trait::keypair(); let (shared_secret, ciphertext) = MlKem768Trait::encap(&kem_pk); let recovered = MlKem768Trait::decap(&kem_sk, &ciphertext)?; assert!(shared_secret.ct_eq(&recovered)); // Constant-time comparison // Digital Signatures with trait API let (sig_pk, sig_sk) = MlDsa65Trait::keypair(); let message = b"Quantum-resistant message"; let signature = MlDsa65Trait::sign(&sig_sk, message); assert!(MlDsa65Trait::verify(&sig_pk, message, &signature)); // BLAKE3 helpers for secure key derivation use saorsa_pqc::pqc::blake3_helpers; let derived_key = blake3_helpers::derive_key("app-context", shared_secret.as_ref()); ``` -------------------------------- ### Key Confirmation for Key-Exchange Protocols Source: https://context7.com/saorsa-labs/saorsa-pqc/llms.txt Provides an example of generating a key confirmation value using shared secret and public data from both parties in a key-exchange protocol. Demonstrates that the order of public data matters. ```rust use saorsa_pqc::api::hmac::helpers::key_confirmation; fn main() -> Result<(), Box> { // ── Key confirmation (for key-exchange protocols) ───────────────────────── let shared_secret = b"kem-derived-shared-secret"; let alice_data = b"Alice's ephemeral public key"; let bob_data = b"Bob's ephemeral public key"; let confirmation = key_confirmation(shared_secret, alice_data, bob_data)?; assert_eq!(confirmation.len(), 32); // Order is significant let reversed = key_confirmation(shared_secret, bob_data, alice_data)?; assert_ne!(confirmation, reversed); Ok(()) } // Expected output: // HMAC-SHA3-256: 32 bytes ``` -------------------------------- ### ML-DSA Digital Signatures Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/README.md Provides an example of generating a keypair for ML-DSA-65, signing a message, and verifying the signature. Requires the public and secret keys. ```rust use saorsa_pqc::api::{ml_dsa_65, MlDsaPublicKey, MlDsaSecretKey}; // Generate keypair let dsa = ml_dsa_65(); let (public_key, secret_key) = dsa.generate_keypair()?; // Sign message let message = b"Authenticate this message"; let signature = dsa.sign(&secret_key, message)?; // Verify signature let is_valid = dsa.verify(&public_key, message, &signature)?; assert!(is_valid); ``` -------------------------------- ### Deterministic Key Generation from Seeds Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/README.md Shows how to generate cryptographic keys deterministically from two seeds, useful for testing and reproducibility. This example uses ML-KEM and follows FIPS 203 standards for seed usage. ```rust // Generate keys from seed (for testing/reproducibility) // Uses FIPS 203 deterministic generation with two 32-byte seeds let d_seed = [0u8; 32]; // First seed value let z_seed = [1u8; 32]; // Second seed value let kem = ml_kem_768(); let (pk, sk) = kem.generate_keypair_from_seed(&d_seed, &z_seed); // Deterministic generation produces identical keys let (pk2, sk2) = kem.generate_keypair_from_seed(&d_seed, &z_seed); assert_eq!(pk.to_bytes(), pk2.to_bytes()); ``` -------------------------------- ### HMAC Computation and Verification with saorsa-pqc Source: https://context7.com/saorsa-labs/saorsa-pqc/llms.txt Demonstrates one-shot HMAC computation and verification using helper functions for SHA3-256 and SHA3-512. Includes examples of successful verification and how bit-flips in the tag lead to verification failure. ```rust use saorsa_pqc::api::hmac::helpers::{hmac_sha3_256, hmac_sha3_512, verify_hmac_sha3_256}; use saorsa_pqc::api::traits::Mac; fn main() -> Result<(), Box> { let key = b"super-secret-key"; let data = b"message to authenticate"; // ── One-shot helpers ───────────────────────────────────────────────────── let tag256 = hmac_sha3_256(key, data)?; let tag512 = hmac_sha3_512(key, data)?; verify_hmac_sha3_256(key, data, &tag256)?; assert!(verify_hmac_sha3_256(key, b"wrong", &tag256).is_err()); // Bit-flip in tag fails constant-time comparison let mut bad = tag256; bad[0] ^= 0x01; assert!(verify_hmac_sha3_256(key, data, &bad).is_err()); Ok(()) } // Expected output: // HMAC-SHA3-256: 32 bytes ``` -------------------------------- ### Add saorsa-pqc to Cargo.toml Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/README.md Include the saorsa-pqc library as a dependency in your project's Cargo.toml file to start using its cryptographic functionalities. ```toml [dependencies] saorsa-pqc = "0.4" ``` -------------------------------- ### Raw Public Keys (PQC) Handling Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/src/pqc/README.md Shows how to handle raw public keys for both classical (Ed25519) and PQC (ML-DSA) algorithms, including encoding to SPKI format and verifying signatures. Supports hybrid keys and PQC-aware verifiers. ```rust use ant_quic::crypto::raw_public_keys::pqc::{ExtendedRawPublicKey, PqcRawPublicKeyVerifier}; use ant_quic::crypto::pqc::ml_dsa::MlDsa65; // Create Ed25519 key (classical) let (_, ed25519_key) = generate_ed25519_keypair(); let extended_key = ExtendedRawPublicKey::Ed25519(ed25519_key); // Create ML-DSA key (when available) let ml_dsa = MlDsa65::new(); match ml_dsa.generate_keypair() { Ok((public_key, _)) => { let pqc_key = ExtendedRawPublicKey::MlDsa65(public_key); // Encode to SPKI let spki = pqc_key.to_subject_public_key_info().unwrap(); // Verify signatures let result = pqc_key.verify( message, signature, SignatureScheme::Unknown(0xFE3C), // ML-DSA scheme ); } Err(e) => eprintln!("ML-DSA not yet available: {}", e), } // Create hybrid key let hybrid_key = ExtendedRawPublicKey::HybridEd25519MlDsa65 { ed25519: ed25519_key, ml_dsa: ml_dsa_public_key, }; // PQC-aware verifier let mut verifier = PqcRawPublicKeyVerifier::new(vec![]); verifier.add_trusted_key(extended_key); verifier.add_trusted_key(pqc_key); ``` -------------------------------- ### Basic KEM and Signature Integration Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/docs/ARCHITECTURE.md Demonstrates basic usage of ML-KEM for key encapsulation and ML-DSA for digital signatures. Requires importing the respective algorithm types. ```rust use saorsa_pqc::{MlKem, MlDsa, SlhDsa}; // Simple KEM usage let kem = MlKem::ml_kem_768(); let (public_key, secret_key) = kem.generate_keypair()?; let (ciphertext, shared_secret) = kem.encapsulate(&public_key)?; // Simple signature usage let dsa = MlDsa::ml_dsa_65(); let (public_key, secret_key) = dsa.generate_keypair()?; let signature = dsa.sign(&secret_key, message, None)?; ``` -------------------------------- ### PQC Key Generation (ML-KEM, ML-DSA) Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/src/pqc/README.md Demonstrates generating keypairs for ML-KEM and ML-DSA algorithms. Use these for key encapsulation and digital signatures respectively. Error handling is included for cases where algorithms might not be available. ```rust use ant_quic::crypto::pqc::{ml_kem::MlKem768, ml_dsa::MlDsa65}; // Key Encapsulation let kem = MlKem768::new(); match kem.generate_keypair() { Ok((public_key, secret_key)) => { // Use for key encapsulation } Err(e) => eprintln!("ML-KEM not yet available: {}", e), } // Digital Signatures let dsa = MlDsa65::new(); match dsa.generate_keypair() { Ok((public_key, secret_key)) => { // Use for signing/verification } Err(e) => eprintln!("ML-DSA not yet available: {}", e), } ``` -------------------------------- ### Run PQC Performance Benchmarks Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/src/pqc/PERFORMANCE_OPTIMIZATION.md Execute performance benchmarks for the PQC module within the ant-quic library. Ensure to use the --nocapture flag for detailed output. ```bash cargo test --package ant-quic --lib crypto::pqc::performance_tests -- --nocapture ``` ```bash cargo bench --features pqc ``` -------------------------------- ### rustls Integration with PQC Support Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/src/pqc/README.md Demonstrates how to integrate PQC support into rustls client and server configurations. This allows for TLS connections that utilize PQC algorithms. ```rust use ant_quic::{ClientConfig, ServerConfig}; use ant_quic::crypto::pqc::rustls_provider::{with_pqc_support, with_pqc_support_server, PqcConfigExt}; // Client with PQC support let client_config = ClientConfig::try_with_platform_verifier()?; let pqc_client = with_pqc_support(client_config)?; // Server with PQC support let server_config = ServerConfig::with_single_cert(certs, key)?; let pqc_server = with_pqc_support_server(server_config)?; // Check PQC support assert!(pqc_client.has_pqc_support()); assert!(pqc_server.has_pqc_support()); ``` -------------------------------- ### AEAD Cipher Encryption and Decryption (Rust) Source: https://context7.com/saorsa-labs/saorsa-pqc/llms.txt Demonstrates encrypting and decrypting data using both AES-256-GCM and ChaCha20-Poly1305 via the AeadCipher enum. Includes examples of tampering detection and usage of the lower-level symmetric module with automatic nonce generation and associated data. ```rust use saorsa_pqc::api::aead::AeadCipher; use saorsa_pqc::symmetric::{ChaCha20Poly1305Cipher, SymmetricKey, utils}; fn main() -> Result<(), Box> { // ── Low-level AeadCipher API ───────────────────────────────────────────── let key = [0x42u8; 32]; let nonce = [0x11u8; 12]; let plaintext = b"Confidential payload"; let aad = b"request-id:abc123"; // AES-256-GCM let ct_aes = AeadCipher::Aes256Gcm.encrypt(&key, &nonce, plaintext, aad)?; let pt_aes = AeadCipher::Aes256Gcm.decrypt(&key, &nonce, &ct_aes, aad)?; assert_eq!(pt_aes, plaintext); // ChaCha20-Poly1305 via enum let ct_cha = AeadCipher::ChaCha20Poly1305.encrypt(&key, &nonce, plaintext, aad)?; let pt_cha = AeadCipher::ChaCha20Poly1305.decrypt(&key, &nonce, &ct_cha, aad)?; assert_eq!(pt_cha, plaintext); // Tampered ciphertext must fail authentication let mut bad_ct = ct_aes.clone(); bad_ct[0] ^= 0x01; assert!(AeadCipher::Aes256Gcm.decrypt(&key, &nonce, &bad_ct, aad).is_err()); // ── High-level symmetric module ────────────────────────────────────────── let sym_key = SymmetricKey::generate(); let cipher = ChaCha20Poly1305Cipher::new(&sym_key); // Random nonce generated internally on each call let secret = b"Hello, quantum-resistant world!"; let (ciphertext, nonce_bytes) = cipher.encrypt(secret, None)?; let decrypted = cipher.decrypt(&ciphertext, &nonce_bytes, None)?; assert_eq!(decrypted, secret); // With associated data (authenticated but not encrypted) let metadata = b"version=2;sender=Alice"; let (ct2, n2) = cipher.encrypt(secret, Some(metadata))?; assert!(cipher.decrypt(&ct2, &n2, Some(b"wrong metadata")).is_err()); // auth failure let ok = cipher.decrypt(&ct2, &n2, Some(metadata))?; assert_eq!(ok, secret); // One-shot utils API with EncryptedMessage container (JSON-serializable) let msg = utils::encrypt_message(&sym_key, b"Packaged payload", Some(b"aad"))?; println!("EncryptedMessage size: {} bytes", msg.size()); let recovered = utils::decrypt_message(&sym_key, &msg)?; assert_eq!(recovered, b"Packaged payload"); // Key from password (PBKDF2-SHA256, 100 000 iterations) let derived = utils::derive_key_from_password(b"passw0rd", b"random-salt-16b!", 100_000)?; println!("Derived key: {} bytes", derived.as_bytes().len()); // 32 Ok(()) } ``` -------------------------------- ### Hash Functions with Blake3 and Sha3_256 Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/README.md Demonstrates hashing data using BLAKE3 for high performance and SHA3-256 as a NIST standard. Ensure the `saorsa_pqc::api::hash` and `saorsa_pqc::api::traits::Hash` traits are imported. ```rust use saorsa_pqc::api::hash::{Blake3Hasher, Sha3_256Hasher}; use saorsa_pqc::api::traits::Hash; // High performance: BLAKE3 let mut hasher = Blake3Hasher::new(); hasher.update(b"data to hash"); let hash = hasher.finalize(); // NIST standard: SHA3-256 let mut hasher = Sha3_256Hasher::new(); hasher.update(b"data to hash"); let hash = hasher.finalize(); ``` -------------------------------- ### Run Comprehensive Benchmarks Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/README.md Execute a full suite of performance benchmarks for all supported algorithms and operations. This command provides detailed performance metrics. ```bash cargo bench --bench comprehensive_benchmarks ``` -------------------------------- ### SLH-DSA Convenience Constructors Source: https://context7.com/saorsa-labs/saorsa-pqc/llms.txt Demonstrates the use of convenience constructors to create SLH-DSA instances with specific parameter sets, such as SHA2-128s for small signatures and SHA2-128f for faster signing. ```APIDOC ## SLH-DSA Convenience Constructors ### Description Instantiate SLH-DSA with predefined parameter sets using convenience constructors. ### Methods - `slh_dsa_sha2_128s()`: Creates an SLH-DSA instance with SHA2 hash family, 128-bit security, and small signature size. - `slh_dsa_sha2_128f()`: Creates an SLH-DSA instance with SHA2 hash family, 128-bit security, and fast signing mode. ### Example ```rust use saorsa_pqc::api::SlhDsa; use saorsa_pqc::api::slh_dsa_sha2_128s; use saorsa_pqc::api::slh_dsa_sha2_128f; let slh_small = slh_dsa_sha2_128s(); // smallest sigs, 128-bit security let slh_fast = slh_dsa_sha2_128f(); // faster signing, 128-bit security ``` ``` -------------------------------- ### Hash Function Usage with Helpers and Enum API Source: https://context7.com/saorsa-labs/saorsa-pqc/llms.txt Demonstrates one-shot hashing using helper functions and the generic HashAlgorithm enum. Ensure correct data types and expected output sizes. ```Rust use saorsa_pqc::api::hash::{ Blake3Hasher, Sha3_256Hasher, Sha3_512Hasher, HashAlgorithm, Shake256Xof, helpers::{blake3, sha3_256, sha3_512, shake256, derive_key_blake3}, }; use saorsa_pqc::api::traits::Hash; fn main() { let data = b"post-quantum data"; // ── One-shot helpers ───────────────────────────────────────────────────── let h3 = blake3(data); // [u8; 32] let h256 = sha3_256(data); // [u8; 32] let h512 = sha3_512(data); // [u8; 64] let hxof = shake256(data, 48); // Vec with 48 bytes assert_eq!(h3.len(), 32); assert_eq!(h512.len(), 64); assert_eq!(hxof.len(), 48); // SHAKE XOF: prefix of longer output equals shorter output let hxof32 = shake256(data, 32); let hxof64 = shake256(data, 64); assert_eq!(&hxof64[..32], &hxof32[..]); // ── Enum API ───────────────────────────────────────────────────────────── let alg = HashAlgorithm::Blake3; println!("{}: {} bytes output", alg.name(), alg.output_size()); // BLAKE3: 32 bytes output let hash_bytes = alg.hash(data); assert_eq!(hash_bytes, h3.to_vec()); // ── Incremental hashing ────────────────────────────────────────────────── let part1 = b"first-"; let part2 = b"second"; let combined = b"first-second"; let mut hasher = Blake3Hasher::new(); hasher.update(part1); hasher.update(part2); let inc_hash = hasher.finalize(); let dir_hash = Blake3Hasher::hash(combined); assert_eq!(inc_hash.as_ref(), dir_hash.as_ref()); // SHA3-256 incremental let mut h = Sha3_256Hasher::new(); h.update(b"chunk1"); h.update(b"chunk2"); let _ = h.finalize(); // ── BLAKE3 key derivation (domain-separated KDF) ───────────────────────── let key = derive_key_blake3("my-app v1.0 / session-key", b"shared-secret-material"); println!("Derived key: {} bytes", key.len()); // 32 // Different context → different key let key2 = derive_key_blake3("my-app v1.0 / auth-key", b"shared-secret-material"); assert_ne!(key, key2); } // Expected output: // BLAKE3: 32 bytes output // Derived key: 32 bytes ``` -------------------------------- ### Generate FIPS Evidence Package (Quick) Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/docs/fips/README.md Generate a FIPS evidence package with a quick verification process, estimated to take around 5 minutes. This is useful for initial checks. ```bash ./scripts/generate_fips_evidence.sh --quick ``` -------------------------------- ### ML-DSA-65 Performance Benchmarks Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/docs/ml-dsa-65-architecture.md Benchmarks for ML-DSA-65 key generation, signing, and verification using the Criterion library. Requires the 'benchmarks' feature to be enabled. ```rust #[cfg(feature = "benchmarks")] mod benchmarks { use super::*; use criterion::{black_box, criterion_group, criterion_main, Criterion}; fn benchmark_keygen(c: &mut Criterion) { let ml_dsa = MlDsa65::new(); c.bench_function("ml_dsa_65_keygen", |b| { b.iter(|| { let (pk, sk) = ml_dsa.generate_keypair().unwrap(); black_box((pk, sk)); }) }); } fn benchmark_sign(c: &mut Criterion) { let ml_dsa = MlDsa65::new(); let (pk, sk) = ml_dsa.generate_keypair().unwrap(); let message = b"benchmark message"; c.bench_function("ml_dsa_65_sign", |b| { b.iter(|| { let sig = ml_dsa.sign(black_box(&sk), black_box(message), None).unwrap(); black_box(sig); }) }); } fn benchmark_verify(c: &mut Criterion) { let ml_dsa = MlDsa65::new(); let (pk, sk) = ml_dsa.generate_keypair().unwrap(); let message = b"benchmark message"; let signature = ml_dsa.sign(&sk, message, None).unwrap(); c.bench_function("ml_dsa_65_verify", |b| { b.iter(|| { let valid = ml_dsa.verify( black_box(&pk), black_box(message), black_box(&signature), None ).unwrap(); black_box(valid); }) }); } criterion_group!(benches, benchmark_keygen, benchmark_sign, benchmark_verify); criterion_main!(benches); } ``` -------------------------------- ### ML-KEM Key Generation, Encapsulation, and Decapsulation Source: https://context7.com/saorsa-labs/saorsa-pqc/llms.txt Demonstrates key generation, encapsulation, and decapsulation using ML-KEM. Supports byte serialization for keys and ciphertexts, and includes variant comparisons for different security levels. ```rust use saorsa_pqc::api::{MlKem, MlKemVariant, MlKemPublicKey, MlKemSecretKey, MlKemCiphertext}; fn main() -> Result<(), Box> { // --- Key generation --- let kem = MlKem::new(MlKemVariant::MlKem768); let (public_key, secret_key) = kem.generate_keypair()?; println!("Public key : {} bytes", public_key.to_bytes().len()); // 1184 println!("Secret key : {} bytes", secret_key.to_bytes().len()); // 2400 // --- Encapsulation (sender side) --- let (shared_secret_enc, ciphertext) = kem.encapsulate(&public_key)?; println!("Ciphertext : {} bytes", ciphertext.to_bytes().len()); // 1088 println!("Shared secret: {} bytes", shared_secret_enc.to_bytes().len()); // 32 // --- Decapsulation (recipient side) --- let shared_secret_dec = kem.decapsulate(&secret_key, &ciphertext)?; assert_eq!(shared_secret_enc.to_bytes(), shared_secret_dec.to_bytes()); println!("Shared secrets match — secure channel established"); // --- Round-trip via byte serialization (e.g., network transfer) --- let pk_bytes = public_key.to_bytes(); let ct_bytes = ciphertext.to_bytes(); let pk_restored = MlKemPublicKey::from_bytes(MlKemVariant::MlKem768, &pk_bytes)?; let ct_restored = MlKemCiphertext::from_bytes(MlKemVariant::MlKem768, &ct_bytes)?; let ss_restored = kem.decapsulate(&secret_key, &ct_restored)?; assert_eq!(shared_secret_enc.to_bytes(), ss_restored.to_bytes()); // --- Variant comparison --- let sizes = [ (MlKemVariant::MlKem512, "512", 800, 768, 32), (MlKemVariant::MlKem768, "768", 1184, 1088, 32), (MlKemVariant::MlKem1024, "1024", 1568, 1568, 32), ]; for (variant, name, pk_sz, ct_sz, ss_sz) in sizes { let k = MlKem::new(variant); let (pk, sk) = k.generate_keypair()?; let (ss, ct) = k.encapsulate(&pk)?; println!( "ML-KEM-{}: pk={}B ct={}B ss={}B", name, pk.to_bytes().len(), ct.to_bytes().len(), ss.to_bytes().len() ); assert_eq!(pk.to_bytes().len(), pk_sz); assert_eq!(ct.to_bytes().len(), ct_sz); assert_eq!(ss.to_bytes().len(), ss_sz); } Ok(()) } ``` -------------------------------- ### Run Tests with Release Optimizations Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/README.md Execute tests with release optimizations enabled for faster execution. Note that this may not reflect debug build performance. ```bash cargo test --release ``` -------------------------------- ### Trait-Based API - ML-KEM and ML-DSA Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/README.md Demonstrates the usage of the trait-based API for Key Encapsulation (ML-KEM) and Digital Signatures (ML-DSA), highlighting features like zero-copy, automatic zeroization, and constant-time operations. ```APIDOC ## Trait-Based API Usage ### Description This section shows how to use the trait-based API for ML-KEM and ML-DSA algorithms. ### Key Encapsulation with trait API ```rust use saorsa_pqc::pqc::{Kem, MlKem768Trait, ConstantTimeCompare}; // Key Encapsulation with trait API let (kem_pk, kem_sk) = MlKem768Trait::keypair(); let (shared_secret, ciphertext) = MlKem768Trait::encap(&kem_pk); let recovered = MlKem768Trait::decap(&kem_sk, &ciphertext)?; assert!(shared_secret.ct_eq(&recovered)); // Constant-time comparison ``` ### Digital Signatures with trait API ```rust use saorsa_pqc::pqc::{Sig, MlDsa65Trait}; // Digital Signatures with trait API let (sig_pk, sig_sk) = MlDsa65Trait::keypair(); let message = b"Quantum-resistant message"; let signature = MlDsa65Trait::sign(&sig_sk, message); assert!(MlDsa65Trait::verify(&sig_pk, message, &signature)); ``` ### BLAKE3 helpers for secure key derivation ```rust use saorsa_pqc::pqc::blake3_helpers; // Assuming shared_secret is available from ML-KEM operation // let shared_secret = ...; let derived_key = blake3_helpers::derive_key("app-context", shared_secret.as_ref()); ``` ### Key Features - Zero-copy buffers - Automatic zeroization of secret keys - Constant-time operations - Generic programming for algorithm agility ``` -------------------------------- ### Deriving MAC Key via HKDF Source: https://context7.com/saorsa-labs/saorsa-pqc/llms.txt Illustrates deriving a MAC key using HKDF with a master key material and a context string. The derived key is then used for HMAC computation. ```rust use saorsa_pqc::api::hmac::helpers::derive_mac_key; use saorsa_pqc::api::hmac::hmac_sha3_256; fn main() -> Result<(), Box> { // ── Derive a MAC key via HKDF ───────────────────────────────────────────── let mac_key = derive_mac_key(b"master-key-material", b"HMAC key for API auth")?; assert_eq!(mac_key.len(), 32); let api_tag = hmac_sha3_256(&mac_key[..], b"GET /users")?; Ok(()) } // Expected output: // HMAC-SHA3-256: 32 bytes ``` -------------------------------- ### SLH-DSA Key Generation and Signing Source: https://context7.com/saorsa-labs/saorsa-pqc/llms.txt Shows how to generate a public and secret key pair, sign a message using the secret key, and verify the signature with the public key. ```APIDOC ## SLH-DSA Key Generation and Signing ### Description Generate key pairs, sign messages, and verify signatures using the SLH-DSA scheme. ### Methods - `generate_keypair()`: Generates a new public and secret key pair. - `sign(secret_key, message)`: Signs a message using the provided secret key. - `verify(public_key, message, signature)`: Verifies if a signature is valid for a given message and public key. ### Example ```rust use saorsa_pqc::api::{SlhDsa, SlhDsaPublicKey, SlhDsaSecretKey, SlhDsaSignature}; use saorsa_pqc::api::slh_dsa_sha2_128s; let slh_small = slh_dsa_sha2_128s(); let (pk, sk) = slh_small.generate_keypair()?; let message = b"Legal contract v1.2"; let signature = slh_small.sign(&sk, message)?; assert!(slh_small.verify(&pk, message, &signature)?); assert!(!slh_small.verify(&pk, b"Different message", &signature)?); ``` ``` -------------------------------- ### Key Derivation with HkdfSha3_256 Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/README.md Demonstrates deriving an encryption key from a shared secret using HKDF-SHA3-256. Requires importing `saorsa_pqc::api::kdf::HkdfSha3_256` and `saorsa_pqc::api::traits::Kdf`. ```rust use saorsa_pqc::api::kdf::HkdfSha3_256; use saorsa_pqc::api::traits::Kdf; // Derive encryption key from shared secret let shared_secret = b"shared secret from ML-KEM"; let info = b"application context"; let mut derived_key = [0u8; 32]; HkdfSha3_256::derive(shared_secret, None, info, &mut derived_key)?; ``` -------------------------------- ### SLH-DSA Key Generation, Signing, and Verification in Rust Source: https://context7.com/saorsa-labs/saorsa-pqc/llms.txt Demonstrates key generation, signing, and verification using SLH-DSA with SHA-2 and 128-bit security. Includes context-bound operations and serialization. ```Rust use saorsa_pqc::api::{ SlhDsa, SlhDsaVariant, SlhDsaPublicKey, SlhDsaSecretKey, SlhDsaSignature, slh_dsa_sha2_128s, slh_dsa_sha2_128f, }; fn main() -> Result<(), Box> { // --- Convenience constructors --- let slh_small = slh_dsa_sha2_128s(); // smallest sigs, 128-bit security let slh_fast = slh_dsa_sha2_128f(); // faster signing, 128-bit security // --- Key generation and signing --- let (pk, sk) = slh_small.generate_keypair()?; let message = b"Legal contract v1.2"; let signature = slh_small.sign(&sk, message)?; println!("SLH-DSA-SHA2-128s signature: {} bytes", signature.to_bytes().len()); // 7856 assert!(slh_small.verify(&pk, message, &signature)?); assert!(!slh_small.verify(&pk, b"Different message", &signature)?); // --- Context-bound signing --- let context = b"ContractSystem-v1.0"; let ctx_sig = slh_small.sign_with_context(&sk, message, context)?; assert!(slh_small.verify_with_context(&pk, message, &ctx_sig, context)?); assert!(!slh_small.verify_with_context(&pk, message, &ctx_sig, b"ContractSystem-v2.0")?); // --- Serialization --- let pk_bytes = pk.to_bytes(); assert_eq!(pk_bytes.len(), 32); // 32 bytes for 128-bit security let sk_bytes = sk.to_bytes(); assert_eq!(sk_bytes.len(), 64); // 64 bytes for 128-bit security let pk_restored = SlhDsaPublicKey::from_bytes(SlhDsaVariant::Sha2_128s, &pk_bytes)?; let sk_restored = SlhDsaSecretKey::from_bytes(SlhDsaVariant::Sha2_128s, &sk_bytes)?; let sig2 = slh_small.sign(&sk_restored, message)?; assert!(slh_small.verify(&pk_restored, message, &sig2)?); // --- Variant size trade-offs --- for (variant, label) in [ (SlhDsaVariant::Sha2_128s, "SHA2-128s (small)"), (SlhDsaVariant::Sha2_128f, "SHA2-128f (fast) "), (SlhDsaVariant::Sha2_256s, "SHA2-256s (small)"), (SlhDsaVariant::Shake128s, "SHAKE-128s (small)"), ] { println!( "{}: sig={}B pk={}B security={}", label, variant.signature_size(), variant.public_key_size(), variant.security_level() ); } Ok(()) } ``` -------------------------------- ### Advanced API Integration for KEM, Signatures, and Symmetric Encryption Source: https://github.com/saorsa-labs/saorsa-pqc/blob/main/docs/ARCHITECTURE.md Shows advanced integration patterns using the `saorsa_pqc::api` module for key exchange, signatures, and symmetric encryption. Assumes `message` is defined elsewhere. ```rust use saorsa_pqc::api; // Key exchange (ML-KEM-768) let (pk, sk) = api::kem::keypair()?; let (ciphertext, shared_secret) = api::kem::encapsulate(&pk)?; let decapsulated = api::kem::decapsulate(&sk, &ciphertext)?; // Signatures (ML-DSA-65) let (sign_pk, sign_sk) = api::sig::keypair()?; let signature = api::sig::sign(&sign_sk, message)?; let valid = api::sig::verify(&sign_pk, message, &signature)?; // Symmetric encryption (ChaCha20-Poly1305) let encrypted = api::symmetric::encrypt(&key, &nonce, plaintext)?; let decrypted = api::symmetric::decrypt(&key, &nonce, &encrypted)?; ```