#![no_main] use libfuzzer_sys::fuzz_target; use soliton::primitives::xwing; use std::sync::LazyLock; // Fixed keypair for ciphertext mutation testing — keygen is expensive. static KP: LazyLock<(xwing::PublicKey, xwing::SecretKey)> = LazyLock::new(|| xwing::keygen().unwrap()); const CT_SIZE: usize = 1120; // Two modes selected by data[0] & 0x01: // 0 (even) — encapsulate + decapsulate roundtrip: proves freshly produced // ciphertexts always decapsulate without error. // 1 (odd) — fuzz ciphertext bytes: decapsulate must never panic on any ct. fuzz_target!(|data: &[u8]| { if data.is_empty() { return; } if data[0] & 0x01 != 0 { // Mode A: arbitrary ciphertext → decapsulate must not panic. if data.len() < 1 + CT_SIZE { return; } let Ok(ct) = xwing::Ciphertext::from_bytes(data[1..1 + CT_SIZE].to_vec()) else { return; }; let _ = xwing::decapsulate(&KP.1, &ct); } else { // Mode B: encapsulate → decapsulate → must succeed. // Exercises the full KEM path with freshly-generated randomness. let Ok((ct, _ss)) = xwing::encapsulate(&KP.0) else { panic!("encapsulate failed on a valid public key"); }; if xwing::decapsulate(&KP.1, &ct).is_err() { panic!("decapsulate failed on a ciphertext produced by encapsulate"); } } });