From 1420c4077590f0e6c935613f4ebddf65bba0e61e Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Wed, 20 Mar 2024 17:04:38 +0100
Subject: [PATCH 1/7] expose `field::split_data_into_field_elements`

---
 src/field.rs | 2 +-
 src/lib.rs   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/field.rs b/src/field.rs
index 1b92cdb7..e3e79115 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 d581ff9a..9d334b0e 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;
 
-- 
GitLab


From 779b2d041f4a0fd157cd0d62f8abed6189abce7d Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Wed, 20 Mar 2024 17:04:53 +0100
Subject: [PATCH 2/7] add `benches/` and criterion

---
 Cargo.toml          |  5 +++++
 benches/recoding.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)
 create mode 100644 benches/recoding.rs

diff --git a/Cargo.toml b/Cargo.toml
index 6b2b45d0..745d0bdd 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 00000000..bd2577e5
--- /dev/null
+++ b/benches/recoding.rs
@@ -0,0 +1,55 @@
+use ark_bls12_381::Bls12_381;
+use ark_ec::pairing::Pairing;
+use ark_ff::PrimeField;
+use ark_std::{One, Zero};
+
+use rand::Rng;
+
+use komodo::{fec::Shard, field};
+
+use criterion::{black_box, 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>(
+    linear_combination: &[E::ScalarField],
+    nb_bytes: usize,
+) -> Shard<E> {
+    let mut rng = rand::thread_rng();
+    let bytes: Vec<u8> = (0..nb_bytes).map(|_| rng.gen::<u8>()).collect();
+
+    let bytes = field::split_data_into_field_elements::<E>(&bytes, 1);
+    Shard {
+        k: 2,
+        linear_combination: linear_combination.to_vec(),
+        hash: vec![],
+        bytes,
+        size: 0,
+    }
+}
+
+fn bench_template<E: Pairing>(c: &mut Criterion, nb_bytes: usize) {
+    let b1: Shard<E> =
+        create_fake_shard(&[E::ScalarField::one(), E::ScalarField::zero()], nb_bytes);
+    let b2: Shard<E> =
+        create_fake_shard(&[E::ScalarField::zero(), E::ScalarField::one()], nb_bytes);
+
+    let mut rng = rand::thread_rng();
+    let alpha = to_curve::<E>(black_box(rng.gen::<u128>()));
+    let beta = to_curve::<E>(black_box(rng.gen::<u128>()));
+
+    c.bench_function(&format!("recoding {} bytes", nb_bytes), |b| {
+        b.iter(|| b1.combine(alpha, &b2, beta))
+    });
+}
+
+pub fn criterion_benchmark(c: &mut Criterion) {
+    for nb_bytes in [3, 3_000, 3_000_000] {
+        bench_template::<Bls12_381>(c, nb_bytes);
+    }
+}
+
+criterion_group!(benches, criterion_benchmark);
+criterion_main!(benches);
-- 
GitLab


From d71a4784c303622a4165b0836d30e8633265a35d Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 22 Mar 2024 13:30:37 +0100
Subject: [PATCH 3/7] allow to change the number of shards

---
 benches/recoding.rs | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/benches/recoding.rs b/benches/recoding.rs
index bd2577e5..ad2354bb 100644
--- a/benches/recoding.rs
+++ b/benches/recoding.rs
@@ -1,7 +1,6 @@
 use ark_bls12_381::Bls12_381;
 use ark_ec::pairing::Pairing;
 use ark_ff::PrimeField;
-use ark_std::{One, Zero};
 
 use rand::Rng;
 
@@ -13,41 +12,42 @@ 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>(
-    linear_combination: &[E::ScalarField],
-    nb_bytes: usize,
-) -> Shard<E> {
+fn create_fake_shard<E: Pairing>(nb_bytes: usize, nb_shards: usize) -> Shard<E> {
     let mut rng = rand::thread_rng();
     let bytes: Vec<u8> = (0..nb_bytes).map(|_| rng.gen::<u8>()).collect();
 
-    let bytes = field::split_data_into_field_elements::<E>(&bytes, 1);
+    let linear_combination: Vec<E::ScalarField> = (0..nb_bytes)
+        .map(|_| to_curve::<E>(rng.gen::<u128>()))
+        .collect();
+
     Shard {
-        k: 2,
-        linear_combination: linear_combination.to_vec(),
+        k: nb_shards as u32,
+        linear_combination,
         hash: vec![],
-        bytes,
+        bytes: field::split_data_into_field_elements::<E>(&bytes, 1),
         size: 0,
     }
 }
 
-fn bench_template<E: Pairing>(c: &mut Criterion, nb_bytes: usize) {
-    let b1: Shard<E> =
-        create_fake_shard(&[E::ScalarField::one(), E::ScalarField::zero()], nb_bytes);
-    let b2: Shard<E> =
-        create_fake_shard(&[E::ScalarField::zero(), E::ScalarField::one()], nb_bytes);
+fn bench_template<E: Pairing>(c: &mut Criterion, nb_bytes: usize, nb_shards: usize) {
+    let b1: Shard<E> = create_fake_shard(nb_bytes, nb_shards);
+    let b2: Shard<E> = create_fake_shard(nb_bytes, nb_shards);
 
     let mut rng = rand::thread_rng();
     let alpha = to_curve::<E>(black_box(rng.gen::<u128>()));
     let beta = to_curve::<E>(black_box(rng.gen::<u128>()));
 
-    c.bench_function(&format!("recoding {} bytes", nb_bytes), |b| {
-        b.iter(|| b1.combine(alpha, &b2, beta))
-    });
+    c.bench_function(
+        &format!("recoding {} bytes and {} shards", nb_bytes, nb_shards),
+        |b| b.iter(|| b1.combine(alpha, &b2, beta)),
+    );
 }
 
 pub fn criterion_benchmark(c: &mut Criterion) {
-    for nb_bytes in [3, 3_000, 3_000_000] {
-        bench_template::<Bls12_381>(c, nb_bytes);
+    for nb_bytes in [1, 1_024, 1_024 * 1_024] {
+        for nb_shards in [2, 4, 8, 16] {
+            bench_template::<Bls12_381>(c, nb_bytes, nb_shards);
+        }
     }
 }
 
-- 
GitLab


From fc868e6a448d40bf8337b7c9bbc0fbc3a81e4053 Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 22 Mar 2024 13:56:16 +0100
Subject: [PATCH 4/7] make `fec::combine` public

---
 src/fec.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/fec.rs b/src/fec.rs
index 2c834718..1a419b15 100644
--- a/src/fec.rs
+++ b/src/fec.rs
@@ -47,7 +47,7 @@ impl<E: Pairing> Shard<E> {
     }
 }
 
-pub(super) fn combine<E: Pairing>(
+pub fn combine<E: Pairing>(
     shards: &[Shard<E>],
     coeffs: &[E::ScalarField],
 ) -> Option<Shard<E>> {
-- 
GitLab


From 3423cc65469eedf934870eae684842e8118c6db8 Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 22 Mar 2024 13:56:24 +0100
Subject: [PATCH 5/7] add k

---
 benches/recoding.rs | 39 ++++++++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/benches/recoding.rs b/benches/recoding.rs
index ad2354bb..579f2783 100644
--- a/benches/recoding.rs
+++ b/benches/recoding.rs
@@ -4,24 +4,26 @@ use ark_ff::PrimeField;
 
 use rand::Rng;
 
-use komodo::{fec::Shard, field};
+use komodo::{
+    fec::{combine, Shard},
+    field,
+};
 
-use criterion::{black_box, criterion_group, criterion_main, Criterion};
+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, nb_shards: usize) -> Shard<E> {
+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..nb_bytes)
-        .map(|_| to_curve::<E>(rng.gen::<u128>()))
-        .collect();
+    let linear_combination: Vec<E::ScalarField> =
+        (0..k).map(|_| to_curve::<E>(rng.gen::<u128>())).collect();
 
     Shard {
-        k: nb_shards as u32,
+        k: k as u32,
         linear_combination,
         hash: vec![],
         bytes: field::split_data_into_field_elements::<E>(&bytes, 1),
@@ -29,24 +31,31 @@ fn create_fake_shard<E: Pairing>(nb_bytes: usize, nb_shards: usize) -> Shard<E>
     }
 }
 
-fn bench_template<E: Pairing>(c: &mut Criterion, nb_bytes: usize, nb_shards: usize) {
-    let b1: Shard<E> = create_fake_shard(nb_bytes, nb_shards);
-    let b2: Shard<E> = create_fake_shard(nb_bytes, nb_shards);
+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 alpha = to_curve::<E>(black_box(rng.gen::<u128>()));
-    let beta = to_curve::<E>(black_box(rng.gen::<u128>()));
+    let coeffs: Vec<E::ScalarField> = (0..nb_shards)
+        .map(|_| to_curve::<E>(rng.gen::<u128>()))
+        .collect();
 
     c.bench_function(
-        &format!("recoding {} bytes and {} shards", nb_bytes, nb_shards),
-        |b| b.iter(|| b1.combine(alpha, &b2, beta)),
+        &format!(
+            "recoding {} bytes and {} shards with k = {}",
+            nb_bytes, nb_shards, k
+        ),
+        |b| b.iter(|| combine(&shards, &coeffs)),
     );
 }
 
 pub 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] {
-            bench_template::<Bls12_381>(c, nb_bytes, nb_shards);
+            for k in [2, 4, 8, 16] {
+                bench_template::<Bls12_381>(c, nb_bytes, k, nb_shards);
+            }
         }
     }
 }
-- 
GitLab


From 25491b57d6fc77dcc6335f1270b42e2d6c071b4e Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 22 Mar 2024 14:01:37 +0100
Subject: [PATCH 6/7] remove useless public function in benchmark

---
 benches/recoding.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/benches/recoding.rs b/benches/recoding.rs
index 579f2783..01069027 100644
--- a/benches/recoding.rs
+++ b/benches/recoding.rs
@@ -50,7 +50,7 @@ fn bench_template<E: Pairing>(c: &mut Criterion, nb_bytes: usize, k: usize, nb_s
     );
 }
 
-pub fn criterion_benchmark(c: &mut Criterion) {
+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] {
-- 
GitLab


From 5295e0d0cc6233dea6fb829580e54bd0e13df5ab Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 22 Mar 2024 15:22:52 +0100
Subject: [PATCH 7/7] format

---
 src/fec.rs | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/fec.rs b/src/fec.rs
index 1a419b15..fadf5ecf 100644
--- a/src/fec.rs
+++ b/src/fec.rs
@@ -47,10 +47,7 @@ impl<E: Pairing> Shard<E> {
     }
 }
 
-pub 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;
     }
-- 
GitLab