#![no_main] use arbitrary::Arbitrary; use commonware_codec::DecodeExt; use commonware_consensus::{ simplex::{ select_leader, signing_scheme::{ bls12381_multisig, bls12381_threshold::{self, Seed}, ed25519, Scheme, }, }, types::Round, }; use commonware_cryptography::{ bls12381::primitives::variant::{MinPk, MinSig}, ed25519::{PrivateKey, PublicKey}, PrivateKeyExt, Signer, }; use libfuzzer_sys::fuzz_target; use rand::{rngs::StdRng, SeedableRng}; type Ed25519Scheme = ed25519::Scheme; type Bls12381MultisigMinPk = bls12381_multisig::Scheme; type Bls12381MultisigMinSig = bls12381_multisig::Scheme; type Bls12381ThresholdMinPk = bls12381_threshold::Scheme; type Bls12381ThresholdMinSig = bls12381_threshold::Scheme; #[derive(Arbitrary, Debug)] enum FuzzScheme { Ed25519, Bls12381MultisigMinPk, Bls12381MultisigMinSig, Bls12381ThresholdMinPk, Bls12381ThresholdMinSig, } #[derive(Arbitrary, Debug)] struct FuzzInput { participants_count: u8, round_epoch: u64, round_view: u64, scheme: FuzzScheme, encoded_seed: Vec, } fn fuzz(input: &FuzzInput, seed: Option) { let participants: Vec = (1..=input.participants_count) .map(|i| { let mut rng = StdRng::seed_from_u64(i as u64); let private_key = PrivateKey::from_rng(&mut rng); private_key.public_key() }) .collect(); if participants.is_empty() { return; } let round = Round::new(input.round_epoch, input.round_view); let _ = select_leader::(&participants, round, seed); } fuzz_target!(|input: FuzzInput| { match input.scheme { FuzzScheme::Ed25519 => { fuzz::(&input, None); } FuzzScheme::Bls12381ThresholdMinPk => { let seed = Seed::::decode(input.encoded_seed.as_slice()).ok(); fuzz::(&input, seed); } FuzzScheme::Bls12381ThresholdMinSig => { let seed = Seed::::decode(input.encoded_seed.as_slice()).ok(); fuzz::(&input, seed); } FuzzScheme::Bls12381MultisigMinPk => { fuzz::(&input, None); } FuzzScheme::Bls12381MultisigMinSig => { fuzz::(&input, None); } } });