fuel-crypto
fuel-crypto copied to clipboard
Add fuzzy tests to signature
This seems quite costly to exhaustively fuzz the entire search space every test run. Using prop-tests we could randomly sample the distribution on each test run and easily track which input params cause a failure:
use proptest::prelude::{
prop::test_runner::{RngAlgorithm, TestRng}, *,
};
prop_compose! {
fn arb_rng()(
bytes: [u8; 32],
) -> TestRng {
TestRng::from_seed(RngAlgorithm::ChaCha, &bytes)
}
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(50))]
#[test]
fn corrupted_signature(
mut rng in arb_rng(),
position in 0..Signature::LEN,
bit in 0..7,
) {
let message = b"When life itself seems lunatic, who knows where madness lies?";
let message = Message::new(message);
let secret = SecretKey::random(&mut rng);
let public = secret.public_key();
let signature = Signature::sign(&secret, &message);
// Tamper a random bit of the signature
//
// The recover and verify operations should fail in all cases.
let mut s = signature;
let m = 1u8 << bit;
s.as_mut()[position] ^= m;
// check recover
match s.recover(&message) {
Ok(pk) => assert_ne!(public, pk),
Err(Error::InvalidSignature) => (),
Err(e) => panic!("Unexpected error: {}", e),
}
// check verify
assert!(s.verify(&public, &message).is_err());
}
#[test]
fn corrupted_public_key(
mut rng in arb_rng(),
position in 0..PublicKey::LEN,
bit in 0..7,
) {
let message = b"When life itself seems lunatic, who knows where madness lies?";
let message = Message::new(message);
let secret = SecretKey::random(&mut rng);
let mut public = secret.public_key();
let signature = Signature::sign(&secret, &message);
// Tamper a random bit of the public key.
//
// The verify operations should fail in all cases.
let m = 1u8 << bit;
public.as_mut()[position] ^= m;
assert!(signature.verify(&public, &message).is_err());
}
}
Originally posted by @Voxelot in https://github.com/FuelLabs/fuel-crypto/pull/2#discussion_r801197967