pqfile 4.2.4

Quantum-resistant file encryption: ML-KEM (512/768/1024), hybrid X25519+ML-KEM-768, ML-DSA-65 signing, multi-recipient, Shamir sharing
Documentation
//! One-time utility that generates and prints static test vector constants.
//!
//! Run with:
//!   cargo run --example gen_vectors -p pqfile
//!
//! Paste the printed constants into pqfile/tests/static_vectors.rs and commit
//! both files together so they stay in sync.

use pqfile::encrypt::{encrypt_bytes, encrypt_stream, encrypt_stream_multi};
use pqfile::format::CHUNK_SIZE;
use pqfile::keygen::{keygen_bytes, keygen_bytes_hybrid_768};

fn to_hex(bytes: &[u8]) -> String {
    bytes.iter().map(|b| format!("{b:02x}")).collect()
}

fn main() {
    const PLAINTEXT: &[u8] = b"pqfile static test vector v1";

    println!("// ----------------------------------------------------------------");
    println!("// Static test vectors for pqfile format compliance.");
    println!("// Generated by: cargo run --example gen_vectors -p pqfile");
    println!("// Plaintext (hex): {}", to_hex(PLAINTEXT));
    println!("// ----------------------------------------------------------------");
    println!();
    println!("const PLAINTEXT: &[u8] = b\"pqfile static test vector v1\";");
    println!();

    // v2 whole-file AEAD vectors (one per KEM variant)
    for level in [512u16, 768, 1024] {
        let (pub_pem, priv_pem) = keygen_bytes(level, None).unwrap();
        let ct = encrypt_bytes(&pub_pem, PLAINTEXT).unwrap();
        println!("// ML-KEM-{level} v2 (whole-file AEAD, FORMAT.md section 5.1)");
        println!("const V2_{level}_PRIV_PEM: &str = concat!(");
        for line in priv_pem.trim().lines() {
            println!("    \"{line}\\n\",");
        }
        println!(");");
        println!("const V2_{level}_CT: &str = \"{}\";", to_hex(&ct));
        println!();
    }

    // v3 chunked STREAM vector - ML-KEM-768
    {
        let (pub_pem, priv_pem) = keygen_bytes(768, None).unwrap();
        let mut ct = Vec::new();
        encrypt_stream(
            &pub_pem,
            PLAINTEXT.len() as u64,
            CHUNK_SIZE,
            &mut { PLAINTEXT },
            &mut ct,
        )
        .unwrap();
        println!("// ML-KEM-768 v3 (64 KiB chunked STREAM, FORMAT.md section 5.2)");
        println!("const V3_768_PRIV_PEM: &str = concat!(");
        for line in priv_pem.trim().lines() {
            println!("    \"{line}\\n\",");
        }
        println!(");");
        println!("const V3_768_CT: &str = \"{}\";", to_hex(&ct));
        println!();
    }

    // v3 hybrid X25519+ML-KEM-768
    {
        let (pub_pem, priv_pem) = keygen_bytes_hybrid_768(None).unwrap();
        let mut ct = Vec::new();
        encrypt_stream(
            &pub_pem,
            PLAINTEXT.len() as u64,
            CHUNK_SIZE,
            &mut { PLAINTEXT },
            &mut ct,
        )
        .unwrap();
        println!("// Hybrid X25519+ML-KEM-768 v3 (FORMAT.md section 2)");
        println!("const V3_HYBRID_PRIV_PEM: &str = concat!(");
        for line in priv_pem.trim().lines() {
            println!("    \"{line}\\n\",");
        }
        println!(");");
        println!("const V3_HYBRID_CT: &str = \"{}\";", to_hex(&ct));
        println!();
    }

    // v4 two-recipient vector
    {
        let (pub1, priv1) = keygen_bytes(768, None).unwrap();
        let (pub2, priv2) = keygen_bytes(768, None).unwrap();
        let mut ct = Vec::new();
        encrypt_stream_multi(
            &[pub1.as_str(), pub2.as_str()],
            PLAINTEXT.len() as u64,
            &mut { PLAINTEXT },
            &mut ct,
        )
        .unwrap();
        println!("// ML-KEM-768 v4 two-recipient (FORMAT.md section 5.5)");
        println!("const V4_768_PRIV1_PEM: &str = concat!(");
        for line in priv1.trim().lines() {
            println!("    \"{line}\\n\",");
        }
        println!(");");
        println!("const V4_768_PRIV2_PEM: &str = concat!(");
        for line in priv2.trim().lines() {
            println!("    \"{line}\\n\",");
        }
        println!(");");
        println!("const V4_768_CT: &str = \"{}\";", to_hex(&ct));
        println!();
    }
}