diff --git a/fuzz/.gitignore b/fuzz/.gitignore new file mode 100644 index 0000000..572e03b --- /dev/null +++ b/fuzz/.gitignore @@ -0,0 +1,4 @@ + +target +corpus +artifacts diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml new file mode 100644 index 0000000..b1c23b6 --- /dev/null +++ b/fuzz/Cargo.toml @@ -0,0 +1,32 @@ + +[package] +name = "grin_secp256k1zkp-fuzz" +version = "0.0.0" +authors = ["Automatically generated"] +publish = false +edition = "2018" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.3" + +[dependencies.grin_secp256k1zkp] +path = ".." + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "fuzz_sign" +path = "fuzz_targets/fuzz_sign.rs" + +[[bin]] +name = "fuzz_ecdh" +path = "fuzz_targets/fuzz_ecdh.rs" + +[[bin]] +name = "fuzz_aggsig" +path = "fuzz_targets/fuzz_aggsig.rs" diff --git a/fuzz/fuzz_targets/fuzz_aggsig.rs b/fuzz/fuzz_targets/fuzz_aggsig.rs new file mode 100644 index 0000000..e5b681e --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_aggsig.rs @@ -0,0 +1,66 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; + +extern crate secp256k1zkp; + +use secp256k1zkp::{ + AggSigPartialSignature, + ContextFlag, + Message, + Secp256k1, + PublicKey, + SecretKey +}; + +use secp256k1zkp::aggsig::AggSigContext; +use secp256k1zkp::rand::{Rng, thread_rng}; + +fuzz_target!(|data: &[u8]| { + let numkeys = 3; + if data.len() < (numkeys + 1) * 32 { + return (); + } + + let mut rng = thread_rng(); + let secp = Secp256k1::with_caps(ContextFlag::Full); + let mut pks: Vec = Vec::with_capacity(numkeys); + let mut keypairs: Vec<(SecretKey, PublicKey)> = Vec::with_capacity(numkeys); + + for i in 0..numkeys { + if let Ok(sk) = SecretKey::from_slice(&secp, &data[i*32..(i+1)*32]) { + let pk = PublicKey::from_secret_key(&secp, &sk).unwrap(); + pks.push(pk.clone()); + keypairs.push((sk, pk)); + } else { + let (sk, pk) = secp.generate_keypair(&mut rng).unwrap(); + pks.push(pk.clone()); + keypairs.push((sk, pk)); + } + } + + let aggsig = AggSigContext::new(&secp, &pks); + + for i in 0..numkeys { + if aggsig.generate_nonce(i) != true { + panic!("failed to generate aggsig nonce: {}", i); + } + } + + let mut msg_in = [0u8; 32]; + rng.fill(&mut msg_in); + let msg = Message::from_slice(&msg_in).unwrap(); + + let mut partial_sigs: Vec = vec![]; + + for (i, (ss, _)) in keypairs.iter().enumerate() { + match aggsig.partial_sign(msg.clone(), ss.clone(), i) { + Ok(res) => partial_sigs.push(res), + Err(e) => panic!("error creating partial signature: {:?}", e), + } + } + + match aggsig.combine_signatures(&partial_sigs) { + Ok(full_sig) => { let _ = aggsig.verify(full_sig, msg.clone(), &pks); () }, + Err(e) => panic!("error combining signatures: {:?}", e), + } +}); diff --git a/fuzz/fuzz_targets/fuzz_ecdh.rs b/fuzz/fuzz_targets/fuzz_ecdh.rs new file mode 100644 index 0000000..187040a --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_ecdh.rs @@ -0,0 +1,23 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; + +extern crate secp256k1zkp; + +use secp256k1zkp::{Secp256k1, PublicKey, SecretKey}; +use secp256k1zkp::ecdh::SharedSecret; + +fuzz_target!(|data: &[u8]| { + if data.len() < 32 { + return (); + } + + let s = Secp256k1::new(); + + if let Ok(sk) = SecretKey::from_slice(&s, &data[..32]) { + match PublicKey::from_secret_key(&s, &sk) { + Ok(pk) => { let _ = SharedSecret::new(&s, &pk, &sk); () }, + Err(e) => panic!("cannot create public key from secret: {}", e), + } + } +}); + diff --git a/fuzz/fuzz_targets/fuzz_sign.rs b/fuzz/fuzz_targets/fuzz_sign.rs new file mode 100644 index 0000000..5e86e73 --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_sign.rs @@ -0,0 +1,28 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; + +extern crate secp256k1zkp; + +use secp256k1zkp::{Message, Secp256k1, PublicKey, SecretKey}; + +fuzz_target!(|data: &[u8]| { + if data.len() < 64 { + return (); + } + + let s = Secp256k1::new(); + + let msg = Message::from_slice(&data[..32]).unwrap(); + + if let Ok(sk) = SecretKey::from_slice(&s, &data[32..64]) { + match s.sign(&msg, &sk) { + Ok(sig) => { + match PublicKey::from_secret_key(&s, &sk) { + Ok(pk) => s.verify(&msg, &sig, &pk).unwrap(), + Err(e) => panic!("cannot create public key from secret: {}", e), + } + } + Err(e) => panic!("error creating signature: {}", e), + } + } +});