Implement compute row kzg commitments

Fix related bugs
This commit is contained in:
Daniel Sanchez Quiros 2024-04-15 19:20:30 +02:00
parent 8b12b7abc1
commit 3a89597f8d
2 changed files with 33 additions and 8 deletions

View File

@ -1,6 +1,7 @@
use crate::common::{hash_column_and_commitment, Chunk, ChunksMatrix, Row}; use crate::common::{hash_column_and_commitment, Chunk, ChunksMatrix, Row};
use crate::global::{DOMAIN, GLOBAL_PARAMETERS}; use crate::global::{DOMAIN, GLOBAL_PARAMETERS};
use ark_poly::univariate::DensePolynomial; use ark_poly::univariate::DensePolynomial;
use kzgrs::common::bytes_to_polynomial_unchecked;
use kzgrs::{ use kzgrs::{
bytes_to_polynomial, commit_polynomial, encode, generate_element_proof, Commitment, bytes_to_polynomial, commit_polynomial, encode, generate_element_proof, Commitment,
Evaluations, KzgRsError, Polynomial, Proof, BYTES_PER_FIELD_ELEMENT, Evaluations, KzgRsError, Polynomial, Proof, BYTES_PER_FIELD_ELEMENT,
@ -62,11 +63,15 @@ impl DaEncoder {
matrix matrix
.rows() .rows()
.map(|r| { .map(|r| {
bytes_to_polynomial::<BYTES_PER_FIELD_ELEMENT>(r.as_bytes().as_ref(), *DOMAIN) // Using the unchecked version here. Because during the process of chunkifiying
.and_then(|(evals, poly)| { // we already make sure to have the chunks of proper elements.
commit_polynomial(&poly, &GLOBAL_PARAMETERS) // Also, after rs encoding, we are sure all `Fr` elements already fits within modulus.
.map(|commitment| ((evals, poly), commitment)) let (evals, poly) = bytes_to_polynomial_unchecked::<BYTES_PER_FIELD_ELEMENT>(
}) r.as_bytes().as_ref(),
*DOMAIN,
);
commit_polynomial(&poly, &GLOBAL_PARAMETERS)
.map(|commitment| ((evals, poly), commitment))
}) })
.collect() .collect()
} }
@ -217,4 +222,12 @@ pub mod test {
assert_eq!(row.0[0].len(), BYTES_PER_FIELD_ELEMENT); assert_eq!(row.0[0].len(), BYTES_PER_FIELD_ELEMENT);
} }
} }
#[test]
fn test_compute_row_kzg_commitments() {
let data = rand_data(32);
let matrix = ENCODER.chunkify(data.as_ref());
let commitments_data = DaEncoder::compute_kzg_row_commitments(&matrix).unwrap();
assert_eq!(commitments_data.len(), matrix.len());
}
} }

View File

@ -1,6 +1,6 @@
// std // std
// crates // crates
use crate::Commitment; use crate::{Commitment, BYTES_PER_FIELD_ELEMENT};
use ark_bls12_381::fr::Fr; use ark_bls12_381::fr::Fr;
use ark_ff::{BigInteger256, PrimeField, Zero}; use ark_ff::{BigInteger256, PrimeField, Zero};
use ark_poly::domain::general::GeneralEvaluationDomain; use ark_poly::domain::general::GeneralEvaluationDomain;
@ -53,7 +53,7 @@ pub fn bytes_to_polynomial<const CHUNK_SIZE: usize>(
data: &[u8], data: &[u8],
domain: GeneralEvaluationDomain<Fr>, domain: GeneralEvaluationDomain<Fr>,
) -> Result<(Evaluations<Fr>, DensePolynomial<Fr>), KzgRsError> { ) -> Result<(Evaluations<Fr>, DensePolynomial<Fr>), KzgRsError> {
if CHUNK_SIZE >= 32 { if CHUNK_SIZE > BYTES_PER_FIELD_ELEMENT {
return Err(KzgRsError::ChunkSizeTooBig(CHUNK_SIZE)); return Err(KzgRsError::ChunkSizeTooBig(CHUNK_SIZE));
} }
if data.len() % CHUNK_SIZE != 0 { if data.len() % CHUNK_SIZE != 0 {
@ -62,9 +62,21 @@ pub fn bytes_to_polynomial<const CHUNK_SIZE: usize>(
current_size: data.len(), current_size: data.len(),
}); });
} }
Ok(bytes_to_polynomial_unchecked::<CHUNK_SIZE>(data, domain))
}
/// Transform chunks of bytes (of size `CHUNK_SIZE`) into `Fr` which are considered evaluations of a
/// polynomial. Then use FFT to transform that polynomial into coefficient form.
/// No extra checks are done for the caller.
/// Caller need to ensure that `CHUNK_SIZE` is not bigger than the underlying `Fr` element can be
/// decoded from.
pub fn bytes_to_polynomial_unchecked<const CHUNK_SIZE: usize>(
data: &[u8],
domain: GeneralEvaluationDomain<Fr>,
) -> (Evaluations<Fr>, DensePolynomial<Fr>) {
let evals = bytes_to_evaluations::<CHUNK_SIZE>(data, domain); let evals = bytes_to_evaluations::<CHUNK_SIZE>(data, domain);
let coefficients = evals.interpolate_by_ref(); let coefficients = evals.interpolate_by_ref();
Ok((evals, coefficients)) (evals, coefficients)
} }
#[cfg(test)] #[cfg(test)]