use ark_bls12_381::Bls12_381;
use ark_ec::pairing::Pairing;
use ark_ff::PrimeField;
use ark_poly::univariate::DensePolynomial;
use ark_poly::DenseUVPolynomial;
use ark_poly_commit::kzg10::KZG10;
use ark_std::ops::Div;
use ark_std::test_rng;
use komodo::{algebra, algebra::linalg::Matrix, error::KomodoError, fec::encode, kzg, zk::trim};
fn run<E, P>() -> Result<(), KomodoError>
where
E: Pairing,
P: DenseUVPolynomial<E::ScalarField>,
for<'a, 'b> &'a P: Div<&'b P, Output = P>,
{
let rng = &mut test_rng();
let (k, n) = (3, 6_usize);
let bytes = include_bytes!("../assets/dragoon_133x133.png").to_vec();
let degree = bytes.len() / (E::ScalarField::MODULUS_BIT_SIZE as usize / 8);
let params = KZG10::<E, P>::setup(degree, false, rng).expect("setup failed");
let (powers, verifier_key) = trim(params, degree);
let elements = algebra::split_data_into_field_elements::<E::ScalarField>(&bytes, k);
let mut polynomials = Vec::new();
for chunk in elements.chunks(k) {
polynomials.push(P::from_coefficients_vec(chunk.to_vec()))
}
let (commits, _) = kzg::commit(&powers, &polynomials).unwrap();
let encoding_points = &(0..n)
.map(|i| E::ScalarField::from_le_bytes_mod_order(&i.to_le_bytes()))
.collect::<Vec<_>>();
let encoding_mat = Matrix::vandermonde_unchecked(encoding_points, k);
let shards = encode::<E::ScalarField>(&bytes, &encoding_mat)
.unwrap_or_else(|_| panic!("could not encode"));
let blocks = kzg::prove::<E, P>(
commits,
polynomials,
shards,
encoding_points.clone(),
powers,
)
.expect("KZG+ proof failed");
for (i, block) in blocks.iter().enumerate() {
assert!(
kzg::verify::<E, P>(
block,
E::ScalarField::from_le_bytes_mod_order(&[i as u8]),
&verifier_key,
),
"could not verify block {}",
i
);
}
assert!(
kzg::batch_verify(
&blocks[1..3],
&[
E::ScalarField::from_le_bytes_mod_order(&[1]),
E::ScalarField::from_le_bytes_mod_order(&[2]),
E::ScalarField::from_le_bytes_mod_order(&[3]),
],
&verifier_key
)
.unwrap(),
"could not batch-verify blocks 1..3"
);
Ok(())
}
fn main() {
run::<Bls12_381, DensePolynomial<<Bls12_381 as Pairing>::ScalarField>>().unwrap();
}