diff --git a/fuzz/.gitignore b/fuzz/.gitignore new file mode 100644 index 0000000..1a45eee --- /dev/null +++ b/fuzz/.gitignore @@ -0,0 +1,4 @@ +target +corpus +artifacts +coverage diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml new file mode 100644 index 0000000..8529da7 --- /dev/null +++ b/fuzz/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "sylow-fuzz" +version = "0.0.0" +publish = false +edition = "2021" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.4" +sha3 = "0.11.0-pre.4" +crypto-bigint = "0.6.0-rc.3" +num-traits = "0.2.19" + +[dependencies.sylow] +path = ".." + +[[bin]] +name = "fuzz_sylow_api" +path = "fuzz_targets/fuzz_sylow_api.rs" +test = false +doc = false +bench = false diff --git a/fuzz/fuzz_targets/fuzz_sylow_api.rs b/fuzz/fuzz_targets/fuzz_sylow_api.rs new file mode 100644 index 0000000..6a8598c --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_sylow_api.rs @@ -0,0 +1,74 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; +use sylow::{ + KeyPair, sign, verify, G1Projective, G2Projective, pairing, Fp, Fr, + GroupTrait, FieldExtensionTrait, Gt, XMDExpander +}; +use sha3::Keccak256; +use crypto_bigint::rand_core::OsRng; + +fuzz_target!(|data: &[u8]| { + if data.len() < 64 { + return; + } + + // Test case from g1::tests::test_addition_commutativity + let a = G1Projective::rand(&mut OsRng); + let b = G1Projective::rand(&mut OsRng); + assert_eq!(a + b, b + a, "G1 addition is not commutative"); + + // Test case from g2::tests::test_addition_commutativity + let c = G2Projective::rand(&mut OsRng); + let d = G2Projective::rand(&mut OsRng); + assert_eq!(c + d, d + c, "G2 addition is not commutative"); + + // Test case from g1::tests::test_doubling + assert_eq!(a.double(), a + a, "G1 doubling failed"); + + // Test case from g2::tests::test_doubling + assert_eq!(c.double(), c + c, "G2 doubling failed"); + + // Test case from g1::tests::test_scalar_mul + let three = Fp::from(3u64); + assert_eq!(a + (a + a), a * three, "G1 scalar multiplication failed"); + + // Test case from g2::tests::test_scalar_mul + assert_eq!(c + (c + c), c * three, "G2 scalar multiplication failed"); + + // Test case from gt::tests::test_bilinearity + let p = G1Projective::rand(&mut OsRng); + let q = G2Projective::rand(&mut OsRng); + let s = Fr::rand(&mut OsRng); + let sp = G1Projective::from(p) * s.into(); + let sq = G2Projective::from(q) * s.into(); + + let a = pairing(&p, &q) * s; + let b = pairing(&sp, &q); + let c = pairing(&p, &sq); + + assert_eq!(a, b, "Pairing bilinearity property failed"); + assert_eq!(a, c, "Pairing bilinearity property failed"); + + let t = -Fr::ONE; + assert_ne!(a, Gt::identity(), "Pairing result should not be identity"); + assert_eq!(&(a * t) + &a, Gt::identity(), "Pairing inverse property failed"); + + // Test case from g1::tests::test_hash_to_curve + let dst = b"QUUX-V01-CS02-with-expander-SHA256-128"; + let expander = XMDExpander::::new(dst, 128); + if let Ok(hash_point) = G1Projective::hash_to_curve(&expander, &data[..32]) { + assert!(!hash_point.is_zero(), "Hash to curve resulted in zero point"); + } + + // Test BLS signature scheme + let key_pair = KeyPair::generate(); + match sign(&key_pair.secret_key, &data[32..64]) { + Ok(signature) => { + match verify(&key_pair.public_key, &data[32..64], &signature) { + Ok(is_valid) => assert!(is_valid, "Signature verification failed"), + Err(_) => panic!("Verification error"), + } + } + Err(_) => println!("Signing error"), + } +}); \ No newline at end of file diff --git a/src/groups/group.rs b/src/groups/group.rs index d844217..9c2148c 100644 --- a/src/groups/group.rs +++ b/src/groups/group.rs @@ -331,12 +331,12 @@ impl> GroupProjecti /// Checks if this point is the point at infinity. #[inline(always)] - pub(crate) fn is_zero(&self) -> bool { + pub fn is_zero(&self) -> bool { self.z.is_zero() } /// Doubles this point using an optimized algorithm for curves with j-invariant 0. - pub(crate) fn double(&self) -> Self { + pub fn double(&self) -> Self { // This implementation is based on Algorithm 9 from a Ref (1) above - since BN254 has // j-invariant 0, we can use some nice simplifications to the arithmetic. //