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!();
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!();
}
{
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!();
}
{
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!();
}
{
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!();
}
}