mirror of
https://github.com/logos-storage/dynamic-data-experiments.git
synced 2026-01-02 13:13:08 +00:00
impl BLS encoder
This commit is contained in:
parent
5e75e1e654
commit
ea58b0ed15
@ -1,5 +1,7 @@
|
|||||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||||
use dynamic_data_experiments::{byte_data::{Params,Data}, encoder::{RSEncoder, BLSEncoder}};
|
use dynamic_data_experiments::{byte_data::{Params,Data}, encoder::{G8Encoder, BLSEncoder}};
|
||||||
|
use dynamic_data_experiments::encoder::BLSFieldEncoder;
|
||||||
|
use dynamic_data_experiments::field_matrix::Matrix;
|
||||||
use dynamic_data_experiments::traits::{DataMatrix, Encoder};
|
use dynamic_data_experiments::traits::{DataMatrix, Encoder};
|
||||||
|
|
||||||
fn bench_rs_encode(c: &mut Criterion) {
|
fn bench_rs_encode(c: &mut Criterion) {
|
||||||
@ -13,11 +15,11 @@ fn bench_rs_encode(c: &mut Criterion) {
|
|||||||
// generate a random data matrix once
|
// generate a random data matrix once
|
||||||
let data = Data::new_random(params.clone());
|
let data = Data::new_random(params.clone());
|
||||||
|
|
||||||
c.bench_function("RSEncoder::encode", |b| {
|
c.bench_function("G8Encoder::encode", |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
// clone data for each iteration to avoid mutating the original
|
// clone data for each iteration to avoid mutating the original
|
||||||
let mut d = black_box(data.clone());
|
let mut d = black_box(data.clone());
|
||||||
RSEncoder::encode(&mut d).expect("encode failed");
|
G8Encoder::encode(&mut d).expect("encode failed");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -41,5 +43,24 @@ fn bench_bls_encode(c: &mut Criterion) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
criterion_group!(benches, bench_rs_encode, bench_bls_encode);
|
fn bench_bls_field_encode(c: &mut Criterion) {
|
||||||
|
// test parameters
|
||||||
|
let k = 100;
|
||||||
|
let p = 100;
|
||||||
|
let n = k + p;
|
||||||
|
let m = 200;
|
||||||
|
let params = Params { k, n, m };
|
||||||
|
|
||||||
|
// generate a random data matrix once
|
||||||
|
let data = Matrix::new_random(params.clone());
|
||||||
|
|
||||||
|
c.bench_function("BLSFieldEncoder::encode", |b| {
|
||||||
|
b.iter(|| {
|
||||||
|
let mut d = black_box(data.clone());
|
||||||
|
BLSFieldEncoder::encode(&mut d).expect("encode failed");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
criterion_group!(benches, bench_rs_encode, bench_bls_encode, bench_bls_field_encode);
|
||||||
criterion_main!(benches);
|
criterion_main!(benches);
|
||||||
|
|||||||
@ -11,6 +11,44 @@ pub struct Params{
|
|||||||
pub n: usize,
|
pub n: usize,
|
||||||
pub m: usize,
|
pub m: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Params{
|
||||||
|
pub fn check_bounds(&self, r: usize, c: usize) -> anyhow::Result<()>{
|
||||||
|
assert!(
|
||||||
|
r < self.n,
|
||||||
|
"row index {} out of bounds; must be < {}",
|
||||||
|
r,
|
||||||
|
self.n
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
c < self.m,
|
||||||
|
"col index {} out of bounds; must be < {}",
|
||||||
|
c,
|
||||||
|
self.m
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
pub fn check_rows(&self, r: usize) -> anyhow::Result<()>{
|
||||||
|
assert!(
|
||||||
|
r < self.n,
|
||||||
|
"row index {} out of bounds; must be < {}",
|
||||||
|
r,
|
||||||
|
self.n
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_cols(&self, c: usize) -> anyhow::Result<()>{
|
||||||
|
assert!(
|
||||||
|
c < self.m,
|
||||||
|
"col index {} out of bounds; must be < {}",
|
||||||
|
c,
|
||||||
|
self.m
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// data struct contains shards matrix with dimensions `n`*`m`
|
/// data struct contains shards matrix with dimensions `n`*`m`
|
||||||
/// the matrix contains n rows, k of which are source data and the rest p = (n-k) are parity
|
/// the matrix contains n rows, k of which are source data and the rest p = (n-k) are parity
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -20,21 +58,11 @@ pub struct Data<T>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Data<T>{
|
impl<T> Data<T>{
|
||||||
pub fn get_row(&self, idx: usize) -> &Vec<T>{
|
|
||||||
&self.matrix[idx]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_row_mut(&mut self, idx: usize) -> &mut Vec<T>{
|
pub fn get_row_mut(&mut self, idx: usize) -> &mut Vec<T>{
|
||||||
&mut self.matrix[idx]
|
&mut self.matrix[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_col(&self, idx: usize) -> Vec<&T> {
|
|
||||||
self.matrix
|
|
||||||
.iter()
|
|
||||||
.map(|row| &row[idx])
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_col_mut(&mut self, idx: usize) -> Vec<&mut T> {
|
pub fn get_col_mut(&mut self, idx: usize) -> Vec<&mut T> {
|
||||||
self.matrix
|
self.matrix
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
@ -67,9 +95,35 @@ impl DataMatrix<u8> for Data<u8> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get(&self, r: usize, c: usize) -> anyhow::Result<u8> {
|
||||||
|
self.params.check_bounds(r,c)?;
|
||||||
|
Ok(self.matrix[r][c].clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_row(&self, r: usize) -> anyhow::Result<Vec<u8>> {
|
||||||
|
self.params.check_rows(r)?;
|
||||||
|
|
||||||
|
Ok(self.matrix[r].to_vec())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_col(&self, c: usize) -> anyhow::Result<Vec<u8>> {
|
||||||
|
self.params.check_cols(c)?;
|
||||||
|
|
||||||
|
Ok(self.matrix
|
||||||
|
.iter()
|
||||||
|
.map(|row| row[c].clone())
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set(&mut self, r: usize, c: usize, elem: u8) -> anyhow::Result<()> {
|
||||||
|
self.params.check_bounds(r,c)?;
|
||||||
|
self.matrix[r][c] = elem;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Update col `c` in shards.
|
/// Update col `c` in shards.
|
||||||
/// given `new_col` will replace the column `c` or `shards[0..k][c]`
|
/// given `new_col` will replace the column `c` or `shards[0..k][c]`
|
||||||
fn update_col(&mut self, c: usize, new_col: &[u8]) {
|
fn update_col(&mut self, c: usize, new_col: &[u8]) -> anyhow::Result<()>{
|
||||||
// sanity checks
|
// sanity checks
|
||||||
assert!(
|
assert!(
|
||||||
new_col.len() == self.params.k,
|
new_col.len() == self.params.k,
|
||||||
@ -77,17 +131,13 @@ impl DataMatrix<u8> for Data<u8> {
|
|||||||
new_col.len(),
|
new_col.len(),
|
||||||
self.params.k
|
self.params.k
|
||||||
);
|
);
|
||||||
assert!(
|
self.params.check_cols(c)?;
|
||||||
c < self.params.m,
|
|
||||||
"col index {} out of bounds; must be < {}",
|
|
||||||
c,
|
|
||||||
self.params.m
|
|
||||||
);
|
|
||||||
|
|
||||||
// write into each of the k data row at position c
|
// write into each of the k data row at position c
|
||||||
for i in 0..self.params.k {
|
for i in 0..self.params.k {
|
||||||
self.matrix[i][c] = new_col[i];
|
self.matrix[i][c] = new_col[i];
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print all shards
|
/// Print all shards
|
||||||
|
|||||||
@ -7,16 +7,16 @@ use ark_poly::{DenseUVPolynomial, GeneralEvaluationDomain, Polynomial};
|
|||||||
use ark_poly::univariate::DensePolynomial;
|
use ark_poly::univariate::DensePolynomial;
|
||||||
use reed_solomon_erasure::galois_8::ReedSolomon;
|
use reed_solomon_erasure::galois_8::ReedSolomon;
|
||||||
use crate::byte_data::{Data, Params};
|
use crate::byte_data::{Data, Params};
|
||||||
use crate::traits::Encoder;
|
use crate::traits::{DataMatrix, Encoder};
|
||||||
use ark_poly::domain::EvaluationDomain;
|
use ark_poly::domain::EvaluationDomain;
|
||||||
use crate::field_matrix::Matrix;
|
use crate::field_matrix::Matrix;
|
||||||
// ------------- RS Encoder ------------
|
// ------------- RS Encoder ------------
|
||||||
|
|
||||||
pub struct RSEncoder<T>{
|
pub struct G8Encoder<T>{
|
||||||
phantom_data: PhantomData<T>
|
phantom_data: PhantomData<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RSEncoder<u8>{
|
impl G8Encoder<u8>{
|
||||||
pub fn new() -> Self{
|
pub fn new() -> Self{
|
||||||
Self{
|
Self{
|
||||||
phantom_data: PhantomData::default()
|
phantom_data: PhantomData::default()
|
||||||
@ -24,7 +24,7 @@ impl RSEncoder<u8>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encoder<u8> for RSEncoder<u8> {
|
impl Encoder<u8> for G8Encoder<u8> {
|
||||||
type Params = Params;
|
type Params = Params;
|
||||||
type DataMatrix<T> = Data<u8>;
|
type DataMatrix<T> = Data<u8>;
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ impl Encoder<u8> for RSEncoder<u8> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_col(data: &mut Data<u8>, c: usize) -> Result<Vec<u8>>{
|
fn encode_col(data: &mut Data<u8>, c: usize) -> Result<()>{
|
||||||
// bounds check
|
// bounds check
|
||||||
if c >= data.params.m {
|
if c >= data.params.m {
|
||||||
return Err(anyhow!("col index {} out of bounds (< {})", c, data.params.m));
|
return Err(anyhow!("col index {} out of bounds (< {})", c, data.params.m));
|
||||||
@ -66,7 +66,7 @@ impl Encoder<u8> for RSEncoder<u8> {
|
|||||||
// Build the column: data = existing byte, parity = zero
|
// Build the column: data = existing byte, parity = zero
|
||||||
let mut temp: Vec<Vec<u8>> = (0..n)
|
let mut temp: Vec<Vec<u8>> = (0..n)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let byte = data.matrix[i][c];
|
let byte = data.get(i,c).unwrap();
|
||||||
if i < k {
|
if i < k {
|
||||||
vec![byte]
|
vec![byte]
|
||||||
} else {
|
} else {
|
||||||
@ -80,17 +80,15 @@ impl Encoder<u8> for RSEncoder<u8> {
|
|||||||
let rse = ReedSolomon::new(k, p)?;
|
let rse = ReedSolomon::new(k, p)?;
|
||||||
rse.encode(&mut refs)?;
|
rse.encode(&mut refs)?;
|
||||||
|
|
||||||
// Write back parity and collect full col
|
// Write back parity
|
||||||
let mut full_col = Vec::with_capacity(n);
|
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
let b = refs[i][0];
|
let b = refs[i][0];
|
||||||
if i >= k {
|
if i >= k {
|
||||||
data.matrix[i][c] = b;
|
data.set(i,c, b)?;
|
||||||
}
|
}
|
||||||
full_col.push(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(full_col)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reconstruct(params: Params, matrix_opts: &mut Vec<Option<Vec<u8>>>) -> Result<()>{
|
fn reconstruct(params: Params, matrix_opts: &mut Vec<Option<Vec<u8>>>) -> Result<()>{
|
||||||
@ -133,7 +131,7 @@ impl Encoder<u8> for BLSEncoder<u8> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_col(data: &mut Self::DataMatrix<u8>, c: usize) -> Result<Vec<u8>> {
|
fn encode_col(data: &mut Self::DataMatrix<u8>, c: usize) -> Result<()> {
|
||||||
let n = data.params.n.clone();
|
let n = data.params.n.clone();
|
||||||
let k = data.params.k.clone();
|
let k = data.params.k.clone();
|
||||||
let mut col = data.get_col_mut(c);
|
let mut col = data.get_col_mut(c);
|
||||||
@ -141,14 +139,13 @@ impl Encoder<u8> for BLSEncoder<u8> {
|
|||||||
let poly_poly = UniPoly381::from_coefficients_slice(&col_f);
|
let poly_poly = UniPoly381::from_coefficients_slice(&col_f);
|
||||||
let domain: GeneralEvaluationDomain<F> = EvaluationDomain::<F>::new(n).unwrap();
|
let domain: GeneralEvaluationDomain<F> = EvaluationDomain::<F>::new(n).unwrap();
|
||||||
|
|
||||||
let mut new_col: Vec<u8> = vec![];
|
// let mut new_col: Vec<u8> = vec![];
|
||||||
for i in k..n{
|
for i in k..n{
|
||||||
let eval = poly_poly.evaluate(&domain.element(i));
|
let eval = poly_poly.evaluate(&domain.element(i));
|
||||||
new_col.push(eval.0.0[0] as u8);
|
|
||||||
*col[i] = eval.0.0[0] as u8;
|
*col[i] = eval.0.0[0] as u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(new_col)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reconstruct(_params: Params, _matrix_opts: &mut Vec<Option<Vec<u8>>>) -> Result<()> {
|
fn reconstruct(_params: Params, _matrix_opts: &mut Vec<Option<Vec<u8>>>) -> Result<()> {
|
||||||
@ -158,7 +155,11 @@ impl Encoder<u8> for BLSEncoder<u8> {
|
|||||||
|
|
||||||
// --------- BLS Encoder over FieldMatrix ----------------
|
// --------- BLS Encoder over FieldMatrix ----------------
|
||||||
|
|
||||||
impl Encoder<F> for BLSEncoder<F> {
|
pub struct BLSFieldEncoder<T>{
|
||||||
|
phantom_data: PhantomData<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encoder<F> for BLSFieldEncoder<F>{
|
||||||
type Params = Params;
|
type Params = Params;
|
||||||
type DataMatrix<T> = Matrix<F>;
|
type DataMatrix<T> = Matrix<F>;
|
||||||
|
|
||||||
@ -169,23 +170,18 @@ impl Encoder<F> for BLSEncoder<F> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_col(data: &mut Matrix<F>, c: usize) -> Result<Vec<F>> {
|
fn encode_col(data: &mut Matrix<F>, c: usize) -> Result<()> {
|
||||||
// let n = data.params.n.clone();
|
let n = data.params.n.clone();
|
||||||
// let k = data.params.k.clone();
|
let k = data.params.k.clone();
|
||||||
// let mut col = data.get_col_mut(c);
|
let col: Vec<F> = data.get_col(c)?;
|
||||||
// let col_f: Vec<F> = col.iter().map(|i| <F as PrimeField>::from_le_bytes_mod_order(&i.clone().to_le_bytes())).collect();
|
let poly = UniPoly381::from_coefficients_slice(&col);
|
||||||
// let poly_poly = UniPoly381::from_coefficients_slice(&col_f);
|
let domain: GeneralEvaluationDomain<F> = EvaluationDomain::<F>::new(n).unwrap();
|
||||||
// let domain: GeneralEvaluationDomain<F> = EvaluationDomain::<F>::new(n).unwrap();
|
|
||||||
//
|
for i in k..n{
|
||||||
// let mut new_col: Vec<u8> = vec![];
|
let eval = poly.evaluate(&domain.element(i));
|
||||||
// for i in k..n{
|
data.set(i,c,eval)?;
|
||||||
// let eval = poly_poly.evaluate(&domain.element(i));
|
}
|
||||||
// new_col.push(eval.0.0[0] as u8);
|
Ok(())
|
||||||
// *col[i] = eval.0.0[0] as u8;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Ok(new_col)
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reconstruct(_params: Params, _matrix_opts: &mut Vec<Option<Vec<F>>>) -> Result<()> {
|
fn reconstruct(_params: Params, _matrix_opts: &mut Vec<Option<Vec<F>>>) -> Result<()> {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use ark_ff::Field;
|
use ark_ff::Field;
|
||||||
use ark_std::rand::Rng;
|
use ark_std::{test_rng};
|
||||||
use ark_std::UniformRand;
|
|
||||||
use crate::byte_data::{Data, Params};
|
use crate::byte_data::{Data, Params};
|
||||||
|
use crate::traits::DataMatrix;
|
||||||
|
|
||||||
|
|
||||||
/// a Field matrix with `row` number of rows and `cols` number of columns
|
/// a Field matrix with `row` number of rows and `cols` number of columns
|
||||||
@ -12,34 +12,8 @@ pub struct Matrix<F: Field + Clone> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field + Clone> Matrix<F> {
|
impl<F: Field + Clone> Matrix<F> {
|
||||||
/// Creates a new matrix from given field data.
|
|
||||||
pub fn new(params: Params, elms: Vec<Vec<F>>) -> Self {
|
|
||||||
assert!(elms.len() == params.n, "number of rows must match");
|
|
||||||
for row in &elms {
|
|
||||||
assert!(row.len() == params.m, "each row must have `m` elements");
|
|
||||||
}
|
|
||||||
Matrix { params, elms }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generates a random matrix with given dimensions, uses given rng for randomness.
|
/// Creates a new matrix from given u8 data struct
|
||||||
pub fn new_random<R: Rng + ?Sized>(params: Params, rng: &mut R) -> Self
|
|
||||||
where
|
|
||||||
F: UniformRand,
|
|
||||||
{
|
|
||||||
let rows = params.n;
|
|
||||||
let cols = params.m;
|
|
||||||
let mut data = Vec::with_capacity(rows);
|
|
||||||
for _ in 0..rows {
|
|
||||||
let mut row = Vec::with_capacity(cols);
|
|
||||||
for _ in 0..cols {
|
|
||||||
row.push(F::rand(rng));
|
|
||||||
}
|
|
||||||
data.push(row);
|
|
||||||
}
|
|
||||||
Matrix { params, elms: data }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new matrix from given data struct
|
|
||||||
pub fn from_data(data: &Data<u8>) -> Self{
|
pub fn from_data(data: &Data<u8>) -> Self{
|
||||||
let rows = data.params.n;
|
let rows = data.params.n;
|
||||||
let cols = data.params.m;
|
let cols = data.params.m;
|
||||||
@ -55,23 +29,10 @@ impl<F: Field + Clone> Matrix<F> {
|
|||||||
Matrix { params: data.params.clone(), elms:field_data }
|
Matrix { params: data.params.clone(), elms:field_data }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get the row at 0<idx<n
|
|
||||||
pub fn row(&self, idx: usize) -> Vec<F>{
|
|
||||||
assert!(idx < self.params.n, "Row index out of bounds");
|
|
||||||
self.elms[idx].to_vec()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// get mut the row at 0<idx<n
|
/// get mut the row at 0<idx<n
|
||||||
pub fn row_mut(&mut self, idx: usize) -> &mut Vec<F>{
|
pub fn get_row_mut(&mut self, idx: usize) -> anyhow::Result<&mut Vec<F>>{
|
||||||
assert!(idx < self.params.n, "Row index out of bounds");
|
self.params.check_rows(idx)?;
|
||||||
&mut self.elms[idx]
|
Ok(&mut self.elms[idx])
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_col(&self, idx: usize) -> Vec<&F> {
|
|
||||||
self.elms
|
|
||||||
.iter()
|
|
||||||
.map(|row| &row[idx])
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_col_mut(&mut self, idx: usize) -> Vec<&mut F> {
|
pub fn get_col_mut(&mut self, idx: usize) -> Vec<&mut F> {
|
||||||
@ -80,9 +41,54 @@ impl<F: Field + Clone> Matrix<F> {
|
|||||||
.map(|row| &mut row[idx])
|
.map(|row| &mut row[idx])
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: Field + Clone> DataMatrix<F> for Matrix<F> {
|
||||||
|
type Params = Params;
|
||||||
|
|
||||||
|
/// Generates a random matrix with given dimensions, uses given rng for randomness.
|
||||||
|
fn new_random(params: Params) -> Self
|
||||||
|
{
|
||||||
|
let mut rng = test_rng();
|
||||||
|
let rows = params.n;
|
||||||
|
let cols = params.m;
|
||||||
|
let mut data = Vec::with_capacity(rows);
|
||||||
|
for _ in 0..rows {
|
||||||
|
let mut row = Vec::with_capacity(cols);
|
||||||
|
for _ in 0..cols {
|
||||||
|
row.push(F::rand(&mut rng));
|
||||||
|
}
|
||||||
|
data.push(row);
|
||||||
|
}
|
||||||
|
Matrix { params, elms: data }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&self, r: usize, c: usize) -> anyhow::Result<F> {
|
||||||
|
self.params.check_bounds(r,c)?;
|
||||||
|
Ok(self.elms[r][c].clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set(&mut self, r: usize, c: usize, elem: F) -> anyhow::Result<()>{
|
||||||
|
self.params.check_bounds(r,c)?;
|
||||||
|
Ok(self.elms[r][c] = elem)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// get the row at 0<idx<n
|
||||||
|
fn get_row(&self, idx: usize) -> anyhow::Result<Vec<F>>{
|
||||||
|
self.params.check_rows(idx)?;
|
||||||
|
Ok(self.elms[idx].to_vec())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_col(&self, idx: usize) -> anyhow::Result<Vec<F>> {
|
||||||
|
self.params.check_cols(idx)?;
|
||||||
|
Ok(self.elms
|
||||||
|
.iter()
|
||||||
|
.map(|row| row[idx].clone())
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
/// Print matrix
|
/// Print matrix
|
||||||
pub fn pretty_print(&self) {
|
fn pretty_print(&self) {
|
||||||
for (i, shard) in self.elms.iter().enumerate() {
|
for (i, shard) in self.elms.iter().enumerate() {
|
||||||
print!("row {:>2}: ", i);
|
print!("row {:>2}: ", i);
|
||||||
for &b in shard {
|
for &b in shard {
|
||||||
@ -91,6 +97,24 @@ impl<F: Field + Clone> Matrix<F> {
|
|||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_col(&mut self, c: usize, new_col: &[F]) -> anyhow::Result<()> {
|
||||||
|
self.params.check_cols(c)?;
|
||||||
|
|
||||||
|
// ensure the provided column has exactly `k` entries
|
||||||
|
assert!(
|
||||||
|
new_col.len() == self.params.k,
|
||||||
|
"new_col length ({}) must equal k ({})",
|
||||||
|
new_col.len(),
|
||||||
|
self.params.k
|
||||||
|
);
|
||||||
|
|
||||||
|
for (r, val) in new_col.iter().enumerate() {
|
||||||
|
self.elms[r][c] = val.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ use ark_poly_commit::marlin_pc::MarlinKZG10;
|
|||||||
use ark_poly_commit::sonic_pc::UniversalParams;
|
use ark_poly_commit::sonic_pc::UniversalParams;
|
||||||
use crate::byte_data::Params;
|
use crate::byte_data::Params;
|
||||||
use crate::field_matrix::Matrix;
|
use crate::field_matrix::Matrix;
|
||||||
use crate::traits::PolynomialCommitmentScheme;
|
use crate::traits::{PolynomialCommitmentScheme, DataMatrix};
|
||||||
use ark_crypto_primitives::sponge::poseidon::{PoseidonSponge, PoseidonConfig};
|
use ark_crypto_primitives::sponge::poseidon::{PoseidonSponge, PoseidonConfig};
|
||||||
use ark_poly_commit::kzg10::Proof;
|
use ark_poly_commit::kzg10::Proof;
|
||||||
|
|
||||||
@ -67,7 +67,8 @@ impl PolynomialCommitmentScheme for KZGPolyComm {
|
|||||||
let mut row_polynomials = vec![];
|
let mut row_polynomials = vec![];
|
||||||
let timer = start_timer!(|| format!("Poly evaluations and interpolation for {} rows", degree));
|
let timer = start_timer!(|| format!("Poly evaluations and interpolation for {} rows", degree));
|
||||||
for i in 0..matrix.params.n{
|
for i in 0..matrix.params.n{
|
||||||
let poly_evals = Evaluations::from_vec_and_domain(matrix.row(i), srs.ploycommit_domain.clone());
|
let row = matrix.get_row(i)?.to_vec();
|
||||||
|
let poly_evals = Evaluations::from_vec_and_domain(row, srs.ploycommit_domain.clone());
|
||||||
let row_poly = poly_evals.interpolate();
|
let row_poly = poly_evals.interpolate();
|
||||||
let label = String::from(format!("row_poly_{}", i));
|
let label = String::from(format!("row_poly_{}", i));
|
||||||
let labeled_poly = LabeledPolynomial::new(
|
let labeled_poly = LabeledPolynomial::new(
|
||||||
|
|||||||
76
src/test.rs
76
src/test.rs
@ -5,7 +5,7 @@ mod tests {
|
|||||||
use crate::kzg::{F, KZGPolyComm};
|
use crate::kzg::{F, KZGPolyComm};
|
||||||
use crate::field_matrix::Matrix;
|
use crate::field_matrix::Matrix;
|
||||||
use ark_poly_commit::{Polynomial};
|
use ark_poly_commit::{Polynomial};
|
||||||
use crate::encoder::{BLSEncoder, RSEncoder};
|
use crate::encoder::{BLSEncoder, BLSFieldEncoder, G8Encoder};
|
||||||
use crate::traits::{DataMatrix, Encoder, PolynomialCommitmentScheme};
|
use crate::traits::{DataMatrix, Encoder, PolynomialCommitmentScheme};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -31,7 +31,7 @@ mod tests {
|
|||||||
let original: Vec<Vec<u8>> = data.matrix[..k].to_vec();
|
let original: Vec<Vec<u8>> = data.matrix[..k].to_vec();
|
||||||
|
|
||||||
// encode
|
// encode
|
||||||
RSEncoder::encode(&mut data).expect("encode failed");
|
G8Encoder::encode(&mut data).expect("encode failed");
|
||||||
println!("data after encoding:");
|
println!("data after encoding:");
|
||||||
data.pretty_print();
|
data.pretty_print();
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ mod tests {
|
|||||||
matrix_opts[k] = None;
|
matrix_opts[k] = None;
|
||||||
|
|
||||||
// reconstruct missing rows
|
// reconstruct missing rows
|
||||||
RSEncoder::reconstruct(data.params.clone(), &mut matrix_opts).expect("reconstruction should succeed");
|
G8Encoder::reconstruct(data.params.clone(), &mut matrix_opts).expect("reconstruction should succeed");
|
||||||
|
|
||||||
// verify reconstruction for data shards
|
// verify reconstruction for data shards
|
||||||
for i in 0..k {
|
for i in 0..k {
|
||||||
@ -54,7 +54,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bls_encodeer() {
|
fn test_bls_encoder() {
|
||||||
// test parameters
|
// test parameters
|
||||||
let k = 4;
|
let k = 4;
|
||||||
let p = 4;
|
let p = 4;
|
||||||
@ -98,6 +98,54 @@ mod tests {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bls_field_encoder() {
|
||||||
|
// test parameters
|
||||||
|
let k = 4;
|
||||||
|
let p = 4;
|
||||||
|
let n = k + p;
|
||||||
|
let m = 8;
|
||||||
|
|
||||||
|
// generate Data with random content
|
||||||
|
let params = Params {
|
||||||
|
k,
|
||||||
|
n,
|
||||||
|
m,
|
||||||
|
};
|
||||||
|
let data = Data::new_random(params);
|
||||||
|
println!("data #row ={}", data.matrix.len());
|
||||||
|
println!("data #col ={}", data.matrix[0].len());
|
||||||
|
println!("data before encoding:");
|
||||||
|
data.pretty_print();
|
||||||
|
// original data matrix
|
||||||
|
let mut original = Matrix::from_data(&data);
|
||||||
|
let original_copy = Matrix::from_data(&data);
|
||||||
|
println!("data as Field elements:");
|
||||||
|
original.pretty_print();
|
||||||
|
|
||||||
|
// encode
|
||||||
|
BLSFieldEncoder::encode(&mut original).expect("encode failed");
|
||||||
|
println!("data after encoding:");
|
||||||
|
original.pretty_print();
|
||||||
|
|
||||||
|
// verify data matrix unchanged
|
||||||
|
assert_eq!(original.elms[..k], original_copy.elms[..k]);
|
||||||
|
|
||||||
|
// simulate loss of one data and one parity rows
|
||||||
|
let mut matrix_opts: Vec<_> = data.matrix.iter().cloned().map(Some).collect();
|
||||||
|
matrix_opts[1] = None;
|
||||||
|
matrix_opts[k] = None;
|
||||||
|
|
||||||
|
// TODO: reconstruct missing rows
|
||||||
|
// BLSEncoder::reconstruct(data.params.clone(), &mut matrix_opts).expect("reconstruction should succeed");
|
||||||
|
|
||||||
|
// verify reconstruction for data shards
|
||||||
|
// for i in 0..k {
|
||||||
|
// let recovered = matrix_opts[i].clone().unwrap();
|
||||||
|
// assert_eq!(recovered, &original[i][..]);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_commit_rows() {
|
fn test_commit_rows() {
|
||||||
// dimensions: 8 rows (4 parity), 8 columns
|
// dimensions: 8 rows (4 parity), 8 columns
|
||||||
@ -112,7 +160,7 @@ mod tests {
|
|||||||
m,
|
m,
|
||||||
};
|
};
|
||||||
let mut data = Data::new_random(params.clone());
|
let mut data = Data::new_random(params.clone());
|
||||||
RSEncoder::encode(&mut data).expect("encode failed");
|
G8Encoder::encode(&mut data).expect("encode failed");
|
||||||
|
|
||||||
// make a random n×m matrix
|
// make a random n×m matrix
|
||||||
let matrix = Matrix::from_data(&data);
|
let matrix = Matrix::from_data(&data);
|
||||||
@ -136,7 +184,7 @@ mod tests {
|
|||||||
|
|
||||||
// check that each polynomial really interpolates its original rows
|
// check that each polynomial really interpolates its original rows
|
||||||
for (i, poly) in row_polys.iter().enumerate() {
|
for (i, poly) in row_polys.iter().enumerate() {
|
||||||
let row = matrix.row(i);
|
let row = matrix.get_row(i).unwrap();
|
||||||
// evaluate poly at each domain point and collect
|
// evaluate poly at each domain point and collect
|
||||||
let evals: Vec<_> = srs
|
let evals: Vec<_> = srs
|
||||||
.ploycommit_domain
|
.ploycommit_domain
|
||||||
@ -161,7 +209,7 @@ mod tests {
|
|||||||
m,
|
m,
|
||||||
};
|
};
|
||||||
let mut data = Data::new_random(params.clone());
|
let mut data = Data::new_random(params.clone());
|
||||||
RSEncoder::encode(&mut data).expect("encode failed");
|
G8Encoder::encode(&mut data).expect("encode failed");
|
||||||
|
|
||||||
// make a random n×m matrix
|
// make a random n×m matrix
|
||||||
let matrix = Matrix::from_data(&data);
|
let matrix = Matrix::from_data(&data);
|
||||||
@ -178,7 +226,7 @@ mod tests {
|
|||||||
for col in 0..m {
|
for col in 0..m {
|
||||||
let proof = KZGPolyComm::open(&kzg_comm, &srs, row, col)
|
let proof = KZGPolyComm::open(&kzg_comm, &srs, row, col)
|
||||||
.expect("open should succeed");
|
.expect("open should succeed");
|
||||||
let expected: F = matrix.row(row)[col].clone();
|
let expected: F = matrix.elms[row][col].clone();
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
KZGPolyComm::verify(&kzg_comm, &srs, row, col, expected, &proof)
|
KZGPolyComm::verify(&kzg_comm, &srs, row, col, expected, &proof)
|
||||||
@ -206,7 +254,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
// snapshot of original
|
// snapshot of original
|
||||||
let mut data = Data::new_random(params);
|
let mut data = Data::new_random(params);
|
||||||
RSEncoder::encode(&mut data).expect("encode failed");
|
G8Encoder::encode(&mut data).expect("encode failed");
|
||||||
println!("original data:");
|
println!("original data:");
|
||||||
data.pretty_print();
|
data.pretty_print();
|
||||||
|
|
||||||
@ -230,7 +278,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let _coded_row = RSEncoder::encode_col(&mut data, c).unwrap();
|
let _coded_row = G8Encoder::encode_col(&mut data, c).unwrap();
|
||||||
println!("data after encoding update:");
|
println!("data after encoding update:");
|
||||||
data.pretty_print();
|
data.pretty_print();
|
||||||
}
|
}
|
||||||
@ -250,7 +298,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
// snapshot of original
|
// snapshot of original
|
||||||
let mut data = Data::new_random(params.clone());
|
let mut data = Data::new_random(params.clone());
|
||||||
RSEncoder::encode(&mut data).expect("encode failed");
|
G8Encoder::encode(&mut data).expect("encode failed");
|
||||||
|
|
||||||
// Build a matrix where entry (i,j) = i * m + j
|
// Build a matrix where entry (i,j) = i * m + j
|
||||||
let mut matrix = Matrix::<F>::from_data(&data);
|
let mut matrix = Matrix::<F>::from_data(&data);
|
||||||
@ -266,7 +314,7 @@ mod tests {
|
|||||||
|
|
||||||
// a row to update
|
// a row to update
|
||||||
let row_idx = 1;
|
let row_idx = 1;
|
||||||
let old_row = matrix.row(row_idx);
|
let old_row = matrix.get_row(row_idx)?;
|
||||||
|
|
||||||
// a new row by adding a constant to each element
|
// a new row by adding a constant to each element
|
||||||
let new_row: Vec<_> = old_row.iter()
|
let new_row: Vec<_> = old_row.iter()
|
||||||
@ -275,7 +323,7 @@ mod tests {
|
|||||||
|
|
||||||
// Apply the change to the in-memory matrix
|
// Apply the change to the in-memory matrix
|
||||||
{
|
{
|
||||||
let row_slice = matrix.row_mut(row_idx);
|
let row_slice = matrix.get_row_mut(row_idx)?;
|
||||||
for (j, val) in new_row.iter().enumerate() {
|
for (j, val) in new_row.iter().enumerate() {
|
||||||
row_slice[j] = *val;
|
row_slice[j] = *val;
|
||||||
}
|
}
|
||||||
@ -291,7 +339,7 @@ mod tests {
|
|||||||
.elements()
|
.elements()
|
||||||
.map(|x| poly.polynomial().evaluate(&x))
|
.map(|x| poly.polynomial().evaluate(&x))
|
||||||
.collect();
|
.collect();
|
||||||
assert_eq!(evals, matrix.row(i));
|
assert_eq!(evals, matrix.get_row(i)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
// === new fresh commit on updated matrix ===
|
// === new fresh commit on updated matrix ===
|
||||||
|
|||||||
@ -4,7 +4,11 @@ use crate::byte_data::Params;
|
|||||||
pub trait DataMatrix<T>{
|
pub trait DataMatrix<T>{
|
||||||
type Params;
|
type Params;
|
||||||
fn new_random(params: Self::Params) -> Self;
|
fn new_random(params: Self::Params) -> Self;
|
||||||
fn update_col(&mut self, c: usize, new_col: &[T]);
|
fn get(&self, r: usize, c: usize) -> Result<T>;
|
||||||
|
fn get_row(&self, r: usize) -> Result<Vec<T>>;
|
||||||
|
fn get_col(&self, c: usize) -> Result<Vec<T>>;
|
||||||
|
fn set(&mut self, r: usize, c: usize, elem: T) -> Result<()>;
|
||||||
|
fn update_col(&mut self, c: usize, new_col: &[T]) -> Result<()>;
|
||||||
fn pretty_print(&self);
|
fn pretty_print(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,7 +21,7 @@ pub trait Encoder<T>{
|
|||||||
/// encode in place the input data matrix
|
/// encode in place the input data matrix
|
||||||
fn encode(data: &mut Self::DataMatrix<T>) -> Result<()>;
|
fn encode(data: &mut Self::DataMatrix<T>) -> Result<()>;
|
||||||
/// encode a single column in place
|
/// encode a single column in place
|
||||||
fn encode_col(data: &mut Self::DataMatrix<T>, c: usize) -> Result<Vec<T>>;
|
fn encode_col(data: &mut Self::DataMatrix<T>, c: usize) -> Result<()>;
|
||||||
/// reconstruct in place
|
/// reconstruct in place
|
||||||
fn reconstruct(params: Params, matrix_opts: &mut Vec<Option<Vec<T>>>) -> Result<()>;
|
fn reconstruct(params: Params, matrix_opts: &mut Vec<Option<Vec<T>>>) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user