#![no_main] use libfuzzer_sys::fuzz_target; use soliton::call::derive_call_keys; // Fixed root key — exercises the HKDF-based key derivation without restricting // the fuzz input space for the fields that drive branching (kem_ss, fp_a, fp_b). const ROOT_KEY: [u8; 32] = [0x11; 32]; // Wire layout: // kem_ss (32) | call_id (16) | fp_a (32) | fp_b (32) // derive_call_keys returns Err(InvalidData) when kem_ss is all-zeros or // fp_a == fp_b; those inputs exercise the guard paths without reaching advance(). const MIN: usize = 32 + 16 + 32 + 32; // 112 bytes fuzz_target!(|data: &[u8]| { if data.len() < MIN { return; } let kem_ss: &[u8; 32] = data[0..32].try_into().unwrap(); let call_id: &[u8; 16] = data[32..48].try_into().unwrap(); let fp_a: &[u8; 32] = data[48..80].try_into().unwrap(); let fp_b: &[u8; 32] = data[80..112].try_into().unwrap(); // derive_call_keys and advance must never panic regardless of input. // Exercises: kem_ss zero-check, fingerprint equality guard, HKDF key // derivation, HMAC-SHA3-256 rekeying, and old-field zeroization in advance(). // Both role-assignment branches of advance() are covered by corpus seeds: // fp_a < fp_b (lower_role=true) and fp_a > fp_b (lower_role=false). if let Ok(mut keys_ab) = derive_call_keys(&ROOT_KEY, kem_ss, call_id, fp_a, fp_b) { // Symmetry property: swapping fingerprints must swap send/recv keys. // This catches edge cases near the fingerprint comparison boundary // that the unit-level proptest may miss with different input distributions. let keys_ba = derive_call_keys(&ROOT_KEY, kem_ss, call_id, fp_b, fp_a).unwrap(); assert_eq!(keys_ab.send_key(), keys_ba.recv_key(), "symmetry: send/recv mismatch"); assert_eq!(keys_ab.recv_key(), keys_ba.send_key(), "symmetry: recv/send mismatch"); // Verify advance() succeeds and produces different keys. let pre_send = keys_ab.send_key().to_vec(); let pre_recv = keys_ab.recv_key().to_vec(); keys_ab.advance().expect("advance must succeed on valid call keys"); assert_ne!(&*keys_ab.send_key(), &pre_send[..], "advance must change send_key"); assert_ne!(&*keys_ab.recv_key(), &pre_recv[..], "advance must change recv_key"); } });