rustpq 0.3.0

Pure Rust post-quantum cryptography suite - ML-KEM, ML-DSA, and more
Documentation
use rand::rngs::OsRng;
use rustpq::ml_kem_hybrid::x25519_mlkem768::{
    decapsulate, encapsulate, generate, CIPHERTEXT_BYTES, PUBLIC_KEY_BYTES, SECRET_KEY_BYTES,
    SHARED_SECRET_BYTES,
};

fn main() {
    println!("=== X25519-ML-KEM-768 Hybrid KEM ===\n");
    println!("Security: NIST Level 3 (classical + post-quantum)\n");

    let (pk, sk) = generate(&mut OsRng);

    println!("Generated hybrid keypair:");
    println!("  Public key:  {} bytes", PUBLIC_KEY_BYTES);
    println!("  Secret key:  {} bytes", SECRET_KEY_BYTES);

    let (ct, ss_sender) = encapsulate(&pk, &mut OsRng);

    println!("\nEncapsulated:");
    println!("  Ciphertext:  {} bytes", CIPHERTEXT_BYTES);
    println!(
        "  Raw secret:  {} bytes (concatenated)",
        SHARED_SECRET_BYTES
    );

    let ss_receiver = decapsulate(&sk, &ct);

    assert_eq!(ss_sender.as_bytes(), ss_receiver.as_bytes());
    println!("\nShared secrets match!");

    println!("\n--- Raw Shared Secret (64 bytes) ---");
    println!(
        "ML-KEM component (32 bytes): {:02x?}",
        ss_sender.mlkem_shared_secret()
    );
    println!(
        "X25519 component (32 bytes): {:02x?}",
        ss_sender.x25519_shared_secret()
    );

    let derived_key = ss_sender.derive_key();
    println!("\n--- Derived Key (SHA3-256, 32 bytes) ---");
    println!("{:02x?}", derived_key);

    println!("\nUse derive_key() for a ready-to-use symmetric key.");
    println!("Use as_bytes() for protocol integration or custom KDF.");
}