mirror of
https://github.com/logos-blockchain/lez-fuzzing.git
synced 2026-06-07 19:49:27 +00:00
62 lines
2.7 KiB
Rust
62 lines
2.7 KiB
Rust
#![cfg_attr(feature = "fuzzer-libfuzzer", no_main)]
|
|
//! Fuzz target: signature creation and verification.
|
|
//!
|
|
//! Invariants exercised:
|
|
//!
|
|
//! 1. **Correctness** — `Signature::new(key, msg).is_valid_for(msg, pub_key)` is always `true`
|
|
//! for the matching public key.
|
|
//! 2. **No panics** — random (possibly invalid) signatures and public keys must never cause a
|
|
//! panic in `is_valid_for`.
|
|
//! 3. **Cross-key soundness** — signing with key A and verifying against key B must not panic
|
|
//! (the result must be `false`; if it is `true` that is a security invariant violation).
|
|
|
|
use arbitrary::{Arbitrary, Unstructured};
|
|
use fuzz_props::arbitrary_types::{ArbPrivateKey, ArbPublicKey, ArbSignature};
|
|
use nssa::{PublicKey, Signature};
|
|
|
|
fuzz_props::fuzz_entry!(|data: &[u8]| {
|
|
let mut u = Unstructured::new(data);
|
|
|
|
// ── 1. Freshly signed message always verifies with the correct key ─────────
|
|
if let Ok(key_wrap) = ArbPrivateKey::arbitrary(&mut u) {
|
|
let private_key = key_wrap.0;
|
|
let public_key = PublicKey::new_from_private_key(&private_key);
|
|
let msg: [u8; 32] = u.arbitrary().unwrap_or_default();
|
|
|
|
let sig = Signature::new(&private_key, &msg);
|
|
assert!(
|
|
sig.is_valid_for(&msg, &public_key),
|
|
"INVARIANT VIOLATION: Signature::new + is_valid_for returned false for the signing key"
|
|
);
|
|
}
|
|
|
|
// ── 2. Random bytes as signature must never panic ──────────────────────────
|
|
if let (Ok(sig_wrap), Ok(pk_wrap)) = (
|
|
ArbSignature::arbitrary(&mut u),
|
|
ArbPublicKey::arbitrary(&mut u),
|
|
) {
|
|
let msg: [u8; 32] = u.arbitrary().unwrap_or_default();
|
|
// The result may be true or false — we only assert no panic.
|
|
let _ = sig_wrap.0.is_valid_for(&msg, &pk_wrap.0);
|
|
}
|
|
|
|
// ── 3. Cross-key soundness: different keys must never cross-verify ─────────
|
|
if let (Ok(key_a_wrap), Ok(key_b_wrap)) = (
|
|
ArbPrivateKey::arbitrary(&mut u),
|
|
ArbPrivateKey::arbitrary(&mut u),
|
|
) {
|
|
let public_a = PublicKey::new_from_private_key(&key_a_wrap.0);
|
|
let public_b = PublicKey::new_from_private_key(&key_b_wrap.0);
|
|
let msg: [u8; 32] = u.arbitrary().unwrap_or_default();
|
|
let sig_from_a = Signature::new(&key_a_wrap.0, &msg);
|
|
|
|
if public_a != public_b {
|
|
assert!(
|
|
!sig_from_a.is_valid_for(&msg, &public_b),
|
|
"INVARIANT VIOLATION: signature created with key_a verified successfully \
|
|
against key_b where key_a != key_b (cross-key forgery / broken verification)"
|
|
);
|
|
}
|
|
}
|
|
});
|