diff --git a/Cargo.toml b/Cargo.toml index 6b2b45d09774ad847a395cd268218816a1fa4326..745d0bdd73411ed0c80e376148cc0266b7e46c4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,3 +21,8 @@ tracing-subscriber = "0.3.17" [dev-dependencies] rand = "0.8.5" +criterion = "0.3" + +[[bench]] +name = "recoding" +harness = false diff --git a/benches/recoding.rs b/benches/recoding.rs new file mode 100644 index 0000000000000000000000000000000000000000..01069027659b3b48a66ff4c01c5e6c23cacb0729 --- /dev/null +++ b/benches/recoding.rs @@ -0,0 +1,64 @@ +use ark_bls12_381::Bls12_381; +use ark_ec::pairing::Pairing; +use ark_ff::PrimeField; + +use rand::Rng; + +use komodo::{ + fec::{combine, Shard}, + field, +}; + +use criterion::{criterion_group, criterion_main, Criterion}; + +fn to_curve<E: Pairing>(n: u128) -> E::ScalarField { + E::ScalarField::from_le_bytes_mod_order(&n.to_le_bytes()) +} + +fn create_fake_shard<E: Pairing>(nb_bytes: usize, k: usize) -> Shard<E> { + let mut rng = rand::thread_rng(); + let bytes: Vec<u8> = (0..nb_bytes).map(|_| rng.gen::<u8>()).collect(); + + let linear_combination: Vec<E::ScalarField> = + (0..k).map(|_| to_curve::<E>(rng.gen::<u128>())).collect(); + + Shard { + k: k as u32, + linear_combination, + hash: vec![], + bytes: field::split_data_into_field_elements::<E>(&bytes, 1), + size: 0, + } +} + +fn bench_template<E: Pairing>(c: &mut Criterion, nb_bytes: usize, k: usize, nb_shards: usize) { + let shards: Vec<Shard<E>> = (0..nb_shards) + .map(|_| create_fake_shard(nb_bytes, k)) + .collect(); + + let mut rng = rand::thread_rng(); + let coeffs: Vec<E::ScalarField> = (0..nb_shards) + .map(|_| to_curve::<E>(rng.gen::<u128>())) + .collect(); + + c.bench_function( + &format!( + "recoding {} bytes and {} shards with k = {}", + nb_bytes, nb_shards, k + ), + |b| b.iter(|| combine(&shards, &coeffs)), + ); +} + +fn criterion_benchmark(c: &mut Criterion) { + for nb_bytes in [1, 1_024, 1_024 * 1_024] { + for nb_shards in [2, 4, 8, 16] { + for k in [2, 4, 8, 16] { + bench_template::<Bls12_381>(c, nb_bytes, k, nb_shards); + } + } + } +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/src/fec.rs b/src/fec.rs index 2c83471878ac5b377d5347658770932a77f67413..fadf5ecf8956572608d39c8ff58019944fe8cf5d 100644 --- a/src/fec.rs +++ b/src/fec.rs @@ -47,10 +47,7 @@ impl<E: Pairing> Shard<E> { } } -pub(super) fn combine<E: Pairing>( - shards: &[Shard<E>], - coeffs: &[E::ScalarField], -) -> Option<Shard<E>> { +pub fn combine<E: Pairing>(shards: &[Shard<E>], coeffs: &[E::ScalarField]) -> Option<Shard<E>> { if shards.len() != coeffs.len() { return None; } diff --git a/src/field.rs b/src/field.rs index 1b92cdb7071178c1bbdb1737f61ba5bd7a5b8e48..e3e79115573373ff63fd2c66abe3fdcd936c2720 100644 --- a/src/field.rs +++ b/src/field.rs @@ -6,7 +6,7 @@ use ark_std::One; /// /// [`split_data_into_field_elements`] supports padding the output vector of /// elements by giving a number that needs to divide the length of the vector. -pub(crate) fn split_data_into_field_elements<E: Pairing>( +pub fn split_data_into_field_elements<E: Pairing>( bytes: &[u8], modulus: usize, ) -> Vec<E::ScalarField> { diff --git a/src/lib.rs b/src/lib.rs index d581ff9aa9e900d67b760a94d5507797678e2e2b..9d334b0efdf2f00eab3db34ab92aed62bd7306ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ use tracing::{debug, info}; mod error; pub mod fec; -mod field; +pub mod field; pub mod linalg; pub mod setup;