Skip to content

Commit

Permalink
Syncify fuzz tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sgwilym committed Sep 9, 2024
1 parent bc4696b commit 80ce3b4
Show file tree
Hide file tree
Showing 43 changed files with 275 additions and 339 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions earthstar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ willow-data-model = { path = "../data-model" }
arbitrary = { version = "1.0.2", features = ["derive"]}
ufotofu = { version = "0.4.2", features = ["std"] }
willow-encoding = { path = "../encoding" }
syncify = "0.1.0"

[lints]
workspace = true
154 changes: 83 additions & 71 deletions earthstar/src/cinn25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ use arbitrary::{
Arbitrary, Error as ArbitraryError,
};
use either::Either;
use ufotofu::local_nb::{BulkConsumer, BulkProducer};
use willow_encoding::{Decodable, DecodeError, Encodable};

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Shortname<const MIN_LENGTH: usize, const MAX_LENGTH: usize>(pub Vec<u8>);
Expand Down Expand Up @@ -97,94 +95,108 @@ impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> Cinn25519PublicKey<MIN_LE
// TODO: fn verify
}

impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> Encodable
for Cinn25519PublicKey<MIN_LENGTH, MAX_LENGTH>
{
async fn encode<Consumer>(&self, consumer: &mut Consumer) -> Result<(), Consumer::Error>
where
Consumer: BulkConsumer<Item = u8>,
use syncify::syncify;
use syncify::syncify_replace;

#[syncify(encoding_sync)]
pub(super) mod encoding {
use super::*;

#[syncify_replace(use ufotofu::sync::{BulkConsumer, BulkProducer};)]
use ufotofu::local_nb::{BulkConsumer, BulkProducer};
use willow_encoding::DecodeError;
#[syncify_replace(use willow_encoding::sync::{Encodable, Decodable};)]
use willow_encoding::{Decodable, Encodable};

impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> Encodable
for Cinn25519PublicKey<MIN_LENGTH, MAX_LENGTH>
{
let mut vec = Vec::new();
async fn encode<Consumer>(&self, consumer: &mut Consumer) -> Result<(), Consumer::Error>
where
Consumer: BulkConsumer<Item = u8>,
{
let mut vec = Vec::new();

vec.extend_from_slice(&self.shortname.0);
vec.extend_from_slice(&self.shortname.0);

consumer
.bulk_consume_full_slice(&self.shortname.0)
.await
.map_err(|f| f.reason)?;
consumer
.bulk_consume_full_slice(&self.shortname.0)
.await
.map_err(|f| f.reason)?;

if MIN_LENGTH < MAX_LENGTH {
consumer.consume(0x0).await?;
}
if MIN_LENGTH < MAX_LENGTH {
consumer.consume(0x0).await?;
}

consumer
.bulk_consume_full_slice(&self.underlying)
.await
.map_err(|f| f.reason)?;
consumer
.bulk_consume_full_slice(&self.underlying)
.await
.map_err(|f| f.reason)?;

Ok(())
Ok(())
}
}
}

impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> Decodable
for Cinn25519PublicKey<MIN_LENGTH, MAX_LENGTH>
{
async fn decode<Producer>(
producer: &mut Producer,
) -> Result<Self, DecodeError<<Producer>::Error>>
where
Producer: BulkProducer<Item = u8>,
impl<const MIN_LENGTH: usize, const MAX_LENGTH: usize> Decodable
for Cinn25519PublicKey<MIN_LENGTH, MAX_LENGTH>
{
if MIN_LENGTH == MAX_LENGTH {
let mut shortname_box = vec![0; MIN_LENGTH].into_boxed_slice();
async fn decode<Producer>(
producer: &mut Producer,
) -> Result<Self, DecodeError<<Producer>::Error>>
where
Producer: BulkProducer<Item = u8>,
{
if MIN_LENGTH == MAX_LENGTH {
let mut shortname_box = vec![0; MIN_LENGTH].into_boxed_slice();

producer
.bulk_overwrite_full_slice(shortname_box.as_mut())
.await?;

let mut underlying_slice = [0u8; 32];

producer
.bulk_overwrite_full_slice(&mut underlying_slice)
.await?;

return Ok(Self {
shortname: Shortname(shortname_box.into()),
underlying: underlying_slice,
});
}

producer
.bulk_overwrite_full_slice(shortname_box.as_mut())
.await?;
let mut shortname_vec: Vec<u8> = Vec::new();

loop {
match producer.produce().await {
Ok(Either::Left(item)) => {
// if item is 0x0, stop
if item == 0x0 {
break;
}

shortname_vec.push(item);
}
Ok(Either::Right(_)) => {
// whatever happens, we won't be able to make a full public key.
// Error!
return Err(DecodeError::InvalidInput);
}
Err(err) => return Err(DecodeError::Producer(err)),
}
}

let mut underlying_slice = [0u8; 32];

producer
.bulk_overwrite_full_slice(&mut underlying_slice)
.await?;

return Ok(Self {
shortname: Shortname(shortname_box.into()),
Ok(Self {
shortname: Shortname(shortname_vec),
underlying: underlying_slice,
});
})
}

let mut shortname_vec: Vec<u8> = Vec::new();

loop {
match producer.produce().await {
Ok(Either::Left(item)) => {
// if item is 0x0, stop
if item == 0x0 {
break;
}

shortname_vec.push(item);
}
Ok(Either::Right(_)) => {
// whatever happens, we won't be able to make a full public key.
// Error!
return Err(DecodeError::InvalidInput);
}
Err(err) => return Err(DecodeError::Producer(err)),
}
}

let mut underlying_slice = [0u8; 32];

producer
.bulk_overwrite_full_slice(&mut underlying_slice)
.await?;

Ok(Self {
shortname: Shortname(shortname_vec),
underlying: underlying_slice,
})
}
}

Expand Down
51 changes: 31 additions & 20 deletions earthstar/src/identity_id.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use crate::cinn25519::{Cinn25519PublicKey, Shortname};
use arbitrary::Arbitrary;
use ufotofu::local_nb::{BulkConsumer, BulkProducer};
use willow_data_model::SubspaceId;
use willow_encoding::{Decodable, DecodeError, Encodable};

use crate::cinn25519::{Cinn25519PublicKey, Shortname};

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Arbitrary)]
pub struct IdentityIdentifier(Cinn25519PublicKey<4, 4>);
Expand All @@ -17,24 +14,38 @@ impl Default for IdentityIdentifier {
}
}

impl Encodable for IdentityIdentifier {
async fn encode<C>(&self, consumer: &mut C) -> Result<(), C::Error>
where
C: BulkConsumer<Item = u8>,
{
self.0.encode(consumer).await?;
Ok(())
use syncify::syncify;
use syncify::syncify_replace;

#[syncify(encoding_sync)]
pub(super) mod encoding {
use super::*;

#[syncify_replace(use ufotofu::sync::{BulkConsumer, BulkProducer};)]
use ufotofu::local_nb::{BulkConsumer, BulkProducer};
use willow_encoding::DecodeError;
#[syncify_replace(use willow_encoding::sync::{Encodable, Decodable};)]
use willow_encoding::{Decodable, Encodable};

impl Encodable for IdentityIdentifier {
async fn encode<C>(&self, consumer: &mut C) -> Result<(), C::Error>
where
C: BulkConsumer<Item = u8>,
{
self.0.encode(consumer).await?;
Ok(())
}
}
}

impl Decodable for IdentityIdentifier {
async fn decode<P>(producer: &mut P) -> Result<Self, DecodeError<P::Error>>
where
P: BulkProducer<Item = u8>,
{
match Cinn25519PublicKey::decode(producer).await {
Ok(pk) => Ok(Self(pk)),
Err(err) => Err(err),
impl Decodable for IdentityIdentifier {
async fn decode<P>(producer: &mut P) -> Result<Self, DecodeError<P::Error>>
where
P: BulkProducer<Item = u8>,
{
match Cinn25519PublicKey::decode(producer).await {
Ok(pk) => Ok(Self(pk)),
Err(err) => Err(err),
}
}
}
}
Expand Down
49 changes: 31 additions & 18 deletions earthstar/src/namespace_id.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use arbitrary::Arbitrary;
use ufotofu::local_nb::{BulkConsumer, BulkProducer};

use willow_data_model::NamespaceId;
use willow_encoding::{Decodable, DecodeError, Encodable};

use crate::cinn25519::{Cinn25519PublicKey, Shortname};

Expand All @@ -17,24 +16,38 @@ impl Default for NamespaceIdentifier {
}
}

impl Encodable for NamespaceIdentifier {
async fn encode<C>(&self, consumer: &mut C) -> Result<(), C::Error>
where
C: BulkConsumer<Item = u8>,
{
self.0.encode(consumer).await?;
Ok(())
use syncify::syncify;
use syncify::syncify_replace;

#[syncify(encoding_sync)]
pub(super) mod encoding {
use super::*;

#[syncify_replace(use ufotofu::sync::{BulkConsumer, BulkProducer};)]
use ufotofu::local_nb::{BulkConsumer, BulkProducer};
use willow_encoding::DecodeError;
#[syncify_replace(use willow_encoding::sync::{Encodable, Decodable};)]
use willow_encoding::{Decodable, Encodable};

impl Encodable for NamespaceIdentifier {
async fn encode<C>(&self, consumer: &mut C) -> Result<(), C::Error>
where
C: BulkConsumer<Item = u8>,
{
self.0.encode(consumer).await?;
Ok(())
}
}
}

impl Decodable for NamespaceIdentifier {
async fn decode<P>(producer: &mut P) -> Result<Self, DecodeError<<P>::Error>>
where
P: BulkProducer<Item = u8>,
{
match Cinn25519PublicKey::decode(producer).await {
Ok(pk) => Ok(Self(pk)),
Err(err) => Err(err),
impl Decodable for NamespaceIdentifier {
async fn decode<P>(producer: &mut P) -> Result<Self, DecodeError<<P>::Error>>
where
P: BulkProducer<Item = u8>,
{
match Cinn25519PublicKey::decode(producer).await {
Ok(pk) => Ok(Self(pk)),
Err(err) => Err(err),
}
}
}
}
Expand Down
13 changes: 5 additions & 8 deletions fuzz/fuzz_targets/area_rel_area_encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@ fuzz_target!(|data: (
return;
}

smol::block_on(async {
relative_encoding_roundtrip::<
Area<16, 16, 16, IdentityId>,
Area<16, 16, 16, IdentityId>,
TestConsumer<u8, u16, ()>,
>(a, out, &mut consumer)
.await;
});
relative_encoding_roundtrip::<
Area<16, 16, 16, IdentityId>,
Area<16, 16, 16, IdentityId>,
TestConsumer<u8, u16, ()>,
>(a, out, &mut consumer)
});
13 changes: 5 additions & 8 deletions fuzz/fuzz_targets/area_rel_area_encoding_random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@
use earthstar::identity_id::IdentityIdentifier as IdentityId;
use libfuzzer_sys::fuzz_target;
use willow_data_model::grouping::Area;
use willow_fuzz::encode::relative_encoding_random_less_strict;
use willow_fuzz::encode::relative_encoding_relation_random;

fuzz_target!(|data: (&[u8], Area<16, 16, 16, IdentityId>)| {
// fuzzed code goes here
let (random_bytes, area) = data;

smol::block_on(async {
relative_encoding_random_less_strict::<
Area<16, 16, 16, IdentityId>,
Area<16, 16, 16, IdentityId>,
>(area, random_bytes)
.await;
});
relative_encoding_relation_random::<Area<16, 16, 16, IdentityId>, Area<16, 16, 16, IdentityId>>(
area,
random_bytes,
)
});
4 changes: 1 addition & 3 deletions fuzz/fuzz_targets/entry_encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,5 @@ fuzz_target!(|data: (
)| {
let (entry, mut consumer) = data;

smol::block_on(async {
encoding_roundtrip::<_, TestConsumer<u8, u16, ()>>(entry, &mut consumer).await;
});
encoding_roundtrip::<_, TestConsumer<u8, u16, ()>>(entry, &mut consumer);
});
4 changes: 1 addition & 3 deletions fuzz/fuzz_targets/entry_encoding_random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,5 @@ use libfuzzer_sys::fuzz_target;
use willow_fuzz::{encode::encoding_random, placeholder_params::FakePayloadDigest};

fuzz_target!(|data: &[u8]| {
smol::block_on(async {
encoding_random::<Entry<3, 3, 3, EsNamespaceId, IdentityId, FakePayloadDigest>>(data).await;
});
encoding_random::<Entry<3, 3, 3, EsNamespaceId, IdentityId, FakePayloadDigest>>(data);
});
Loading

0 comments on commit 80ce3b4

Please sign in to comment.