From 9d1ede111bdc297ccc43870b417d7a4805a20522 Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 19 Jan 2024 11:28:42 +0100
Subject: [PATCH 1/8] global vector

---
 src/lib.rs | 48 +++++++++++++++++++++++++-----------------------
 1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index 7e416931..f36f6865 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -112,31 +112,33 @@ where
 {
     let k = polynomials[0].coeffs().len();
 
-    let evaluations = points
+    Ok(points
         .iter()
-        .map(|point| polynomials.iter().map(|p| p.evaluate(point)).collect())
-        .collect::<Vec<Vec<E::ScalarField>>>();
-
-    let mut proofs = Vec::new();
-    for (i, row) in evaluations.iter().enumerate() {
-        let mut linear_combination = Vec::new();
-        linear_combination.resize(i + 1, E::ScalarField::zero());
-        linear_combination[i] = E::ScalarField::one();
-
-        proofs.push(Block {
-            shard: fec::Shard {
-                k: k as u32,
-                linear_combination,
-                hash: hash.to_vec(),
-                bytes: row.clone(),
-                size: nb_bytes,
-            },
-            commit: commits.clone(),
-            m: polynomials.len(),
-        })
-    }
+        .map(|point| {
+            let eval = polynomials
+                .iter()
+                .map(|p| p.evaluate(point))
+                .collect::<Vec<_>>();
 
-    Ok(proofs)
+            let mut linear_combination = Vec::new();
+            linear_combination.push(E::ScalarField::one());
+            for i in 1..k {
+                linear_combination.push(linear_combination[i - 1].mul(point));
+            }
+
+            Block {
+                shard: fec::Shard {
+                    k: k as u32,
+                    linear_combination,
+                    hash: hash.to_vec(),
+                    bytes: eval.clone(),
+                    size: nb_bytes,
+                },
+                commit: commits.clone(),
+                m: polynomials.len(),
+            }
+        })
+        .collect::<Vec<_>>())
 }
 
 pub fn encode<E, P>(
-- 
GitLab


From 48706cf16fa2557485ca4bcf844103fcfb96155e Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 19 Jan 2024 11:31:46 +0100
Subject: [PATCH 2/8] fix verify

---
 src/lib.rs | 18 +-----------------
 1 file changed, 1 insertion(+), 17 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index f36f6865..563cb987 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -260,23 +260,7 @@ where
         .linear_combination
         .iter()
         .enumerate()
-        .map(|(i, w)| {
-            // NOTE: this is where we implicitely compute the Vandermonde matrix
-            // hence, the sum of commits is indeed the sum of the encoded n shards
-            // and not the original k source shards.
-            let alpha = E::ScalarField::from_le_bytes_mod_order(&i.to_le_bytes());
-
-            let f: E::G1 = block
-                .commit
-                .iter()
-                .enumerate()
-                .map(|(j, c)| {
-                    let commit: E::G1 = c.0.into();
-                    commit.mul(alpha.pow([j as u64]))
-                })
-                .sum();
-            f * w
-        })
+        .map(|(i, w)| Into::<E::G1>::into(block.commit[i].0) * w)
         .sum();
     Ok(Into::<E::G1>::into(commit.0) == rhs)
 }
-- 
GitLab


From 88bee6530da127d9b682a9ad22e3c015bb5fd4f5 Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 19 Jan 2024 11:32:05 +0100
Subject: [PATCH 3/8] remove unused imports

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

diff --git a/src/lib.rs b/src/lib.rs
index 563cb987..837d2a90 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,7 +1,7 @@
 use std::ops::{Div, Mul};
 
 use ark_ec::pairing::Pairing;
-use ark_ff::{Field, PrimeField};
+use ark_ff::PrimeField;
 use ark_poly::DenseUVPolynomial;
 use ark_poly_commit::kzg10::{Commitment, Powers, Randomness, KZG10};
 use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
-- 
GitLab


From 6c61e86614fa67f1bbbcade07115ec2cd428f305 Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 19 Jan 2024 11:36:30 +0100
Subject: [PATCH 4/8] fix fec::decode

---
 src/fec.rs | 35 ++++++-----------------------------
 1 file changed, 6 insertions(+), 29 deletions(-)

diff --git a/src/fec.rs b/src/fec.rs
index 3c231564..122dfa7a 100644
--- a/src/fec.rs
+++ b/src/fec.rs
@@ -65,33 +65,14 @@ pub fn decode<E: Pairing>(blocks: Vec<Shard<E>>, transpose: bool) -> Result<Vec<
         return Err(KomodoError::TooFewShards(np, k as usize));
     }
 
-    let n = 1 + blocks
-        .iter()
-        .flat_map(|b| {
-            b.linear_combination
-                .iter()
-                .enumerate()
-                .filter(|(_, l)| !l.is_zero())
-                .map(|(i, _)| i)
-                .collect::<Vec<_>>()
-        })
-        .max()
-        .unwrap_or_default();
-    let points: Vec<E::ScalarField> = (0..n)
-        .map(|i| E::ScalarField::from_le_bytes_mod_order(&i.to_le_bytes()))
-        .collect();
-    let encoding_mat = Matrix::vandermonde(&points, k as usize);
-
-    let lin_comb_mat = Matrix::from_vec_vec(
+    let encoding_mat = Matrix::from_vec_vec(
         blocks
             .iter()
-            .map(|b| {
-                let mut comb = b.linear_combination.clone();
-                comb.resize(n, E::ScalarField::zero());
-                comb
-            })
+            .map(|b| b.linear_combination.clone())
             .collect(),
-    )?;
+    )?
+    .transpose()
+    .truncate(None, Some(np - k as usize));
 
     let shards = Matrix::from_vec_vec(
         blocks
@@ -102,11 +83,7 @@ pub fn decode<E: Pairing>(blocks: Vec<Shard<E>>, transpose: bool) -> Result<Vec<
     )?
     .transpose();
 
-    let ra = encoding_mat
-        .mul(&lin_comb_mat.transpose())?
-        .truncate(None, Some(np - k as usize));
-
-    let source_shards = shards.mul(&ra.invert()?)?;
+    let source_shards = shards.mul(&encoding_mat.invert()?)?;
     let source_shards = if transpose {
         source_shards.transpose().elements
     } else {
-- 
GitLab


From 16e5765b3b2b35cf08c398fae99e4d8712c2583d Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 19 Jan 2024 11:39:35 +0100
Subject: [PATCH 5/8] fix FEC decoding tests

---
 src/fec.rs | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/fec.rs b/src/fec.rs
index 122dfa7a..be205ca5 100644
--- a/src/fec.rs
+++ b/src/fec.rs
@@ -2,7 +2,6 @@ use std::cmp::max;
 use std::ops::{Add, Mul};
 
 use ark_ec::pairing::Pairing;
-use ark_ff::PrimeField;
 use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
 use ark_std::Zero;
 
@@ -97,6 +96,8 @@ pub fn decode<E: Pairing>(blocks: Vec<Shard<E>>, transpose: bool) -> Result<Vec<
 
 #[cfg(test)]
 mod tests {
+    use std::ops::Mul;
+
     use ark_bls12_381::Bls12_381;
     use ark_ec::pairing::Pairing;
     use ark_ff::PrimeField;
@@ -140,9 +141,12 @@ mod tests {
             .chunks(source_shards.height)
             .enumerate()
             .map(|(i, s)| {
+                let alpha = E::ScalarField::from_le_bytes_mod_order(&i.to_le_bytes());
                 let mut linear_combination = Vec::new();
-                linear_combination.resize(i + 1, E::ScalarField::zero());
-                linear_combination[i] = E::ScalarField::one();
+                linear_combination.push(E::ScalarField::one());
+                for i in 1..k {
+                    linear_combination.push(linear_combination[i - 1].mul(alpha));
+                }
 
                 Shard {
                     k: k as u32,
-- 
GitLab


From 4c3f851f9bf5d0ec01abb6bbbaea52cc797c18d6 Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 19 Jan 2024 13:32:02 +0100
Subject: [PATCH 6/8] mark `Matrix::vandermonde` as "dead code"

---
 src/linalg.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/linalg.rs b/src/linalg.rs
index 8a0c527d..222b1baa 100644
--- a/src/linalg.rs
+++ b/src/linalg.rs
@@ -30,6 +30,7 @@ impl<T: Field> Matrix<T> {
         Self::from_diagonal(vec![T::one(); size])
     }
 
+    #[allow(dead_code)]
     pub(super) fn vandermonde(points: &[T], height: usize) -> Self {
         let width = points.len();
 
-- 
GitLab


From 01dd77d89b157966574e9a25cbf8f9977d0da720 Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 19 Jan 2024 15:02:34 +0100
Subject: [PATCH 7/8] combine shards with length k

---
 src/fec.rs | 26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/src/fec.rs b/src/fec.rs
index be205ca5..2ae67e23 100644
--- a/src/fec.rs
+++ b/src/fec.rs
@@ -1,4 +1,3 @@
-use std::cmp::max;
 use std::ops::{Add, Mul};
 
 use ark_ec::pairing::Pairing;
@@ -27,18 +26,14 @@ impl<E: Pairing> Shard<E> {
         }
 
         let mut linear_combination = Vec::new();
-        linear_combination.resize(
-            max(
-                self.linear_combination.len(),
-                other.linear_combination.len(),
-            ),
-            E::ScalarField::zero(),
-        );
-        for (i, l) in self.linear_combination.iter().enumerate() {
-            linear_combination[i] += l.mul(alpha);
-        }
-        for (i, l) in other.linear_combination.iter().enumerate() {
-            linear_combination[i] += l.mul(beta);
+        linear_combination.resize(self.k as usize, E::ScalarField::zero());
+        for (i, (l, r)) in self
+            .linear_combination
+            .iter()
+            .zip(other.linear_combination.iter())
+            .enumerate()
+        {
+            linear_combination[i] = l.mul(alpha) + r.mul(beta);
         }
 
         Shard {
@@ -212,7 +207,7 @@ mod tests {
     ) -> Shard<E> {
         let bytes = field::split_data_into_field_elements::<E>(bytes, 1);
         Shard {
-            k: 0,
+            k: 2,
             linear_combination: linear_combination.to_vec(),
             hash: vec![],
             bytes,
@@ -221,7 +216,8 @@ mod tests {
     }
 
     fn recoding_template<E: Pairing>() {
-        let a: Shard<E> = create_fake_shard(&[E::ScalarField::one()], &[1, 2, 3]);
+        let a: Shard<E> =
+            create_fake_shard(&[E::ScalarField::one(), E::ScalarField::zero()], &[1, 2, 3]);
         let b: Shard<E> =
             create_fake_shard(&[E::ScalarField::zero(), E::ScalarField::one()], &[4, 5, 6]);
 
-- 
GitLab


From 61a19739f76c95137ec951fe66099ad5eaccd797 Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Fri, 19 Jan 2024 15:15:54 +0100
Subject: [PATCH 8/8] compute the linear combination directly

---
 src/fec.rs | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/src/fec.rs b/src/fec.rs
index 2ae67e23..20129c98 100644
--- a/src/fec.rs
+++ b/src/fec.rs
@@ -25,20 +25,14 @@ impl<E: Pairing> Shard<E> {
             return self.clone();
         }
 
-        let mut linear_combination = Vec::new();
-        linear_combination.resize(self.k as usize, E::ScalarField::zero());
-        for (i, (l, r)) in self
-            .linear_combination
-            .iter()
-            .zip(other.linear_combination.iter())
-            .enumerate()
-        {
-            linear_combination[i] = l.mul(alpha) + r.mul(beta);
-        }
-
         Shard {
             k: self.k,
-            linear_combination,
+            linear_combination: self
+                .linear_combination
+                .iter()
+                .zip(other.linear_combination.iter())
+                .map(|(l, r)| l.mul(alpha) + r.mul(beta))
+                .collect(),
             hash: self.hash.clone(),
             bytes: self
                 .bytes
-- 
GitLab