diff --git a/ffi_interface/src/lib.rs b/ffi_interface/src/lib.rs index 88a4502..0672219 100644 --- a/ffi_interface/src/lib.rs +++ b/ffi_interface/src/lib.rs @@ -5,8 +5,13 @@ // Once the java jni crate uses the below implementation, we will remove this file. pub mod interop; +use banderwagon::Fr; use banderwagon::{trait_defs::*, Element}; use ipa_multipoint::committer::{Committer, DefaultCommitter}; +use ipa_multipoint::crs::CRS; +use ipa_multipoint::lagrange_basis::{LagrangeBasis, PrecomputedWeights}; +use ipa_multipoint::multiproof::{MultiPoint, ProverQuery}; +use ipa_multipoint::transcript::Transcript; /// A serialized uncompressed group element pub type CommitmentBytes = [u8; 64]; @@ -157,6 +162,70 @@ fn fr_from_be_bytes(bytes: &[u8]) -> Result { }) } +/// Receives a tuple (C_i, f_i(X), z_i, y_i) +/// Where C_i is a commitment to f_i(X) serialized as 32 bytes +/// f_i(X) is the polynomial serialized as 8192 bytes since we have 256 Fr elements each serialized as 32 bytes +/// z_i is index of the point in the polynomial: 1 byte (number from 1 to 256) +/// y_i is the evaluation of the polynomial at z_i i.e value we are opening: 32 bytes +/// Returns a proof serialized as bytes +/// +/// This function assumes that the domain is always 256 values and commitment is 32bytes. +/// TODO: change commitment to 64bytes since we are moving to uncompressed commitment. +pub fn create_proof(input: Vec) -> Vec { + // Define the chunk size (8257 bytes) + // C_i, f_i(X), z_i, y_i + // 32, 8192, 1, 32 + // = 8257 + let chunk_size = 8257; + // Create an iterator over the input Vec + let chunked_data = input.chunks(chunk_size); + + let mut prover_queries: Vec = Vec::new(); + + for chunk in chunked_data.into_iter() { + if chunk.len() >= chunk_size { + let data = chunk; + let commitment = Element::from_bytes(&data[0..32]).unwrap(); + + // Create f_x from the next 8192 bytes + let f_i_x: Vec = chunk[32..8224].to_vec(); + + let chunked_f_i_x_data = f_i_x.chunks(32); + + let mut collect_lagrange_basis: Vec = Vec::new(); + for chunk_f_i_x in chunked_f_i_x_data.into_iter() { + if chunk_f_i_x.len() >= 32 { + let data_f_i_x = chunk_f_i_x; + let fr_data_f_i_x = Fr::from_be_bytes_mod_order(data_f_i_x); + collect_lagrange_basis.push(fr_data_f_i_x); + } + } + + let lagrange_basis = LagrangeBasis::new(collect_lagrange_basis); + + let z_i: usize = chunk[8224] as usize; + + let y_i = Fr::from_be_bytes_mod_order(&chunk[8225..8257]); + + let prover_query = ProverQuery { + commitment, + poly: lagrange_basis, + point: z_i, + result: y_i, + }; + prover_queries.push(prover_query); + } + } + // TODO: This should be passed in as a pointer + let precomp = PrecomputedWeights::new(256); + + let crs = CRS::default(); + let mut transcript = Transcript::new(b"verkle"); + // TODO: This should not need to clone the CRS, but instead take a reference + let proof = MultiPoint::open(crs.clone(), &precomp, &mut transcript, prover_queries); + proof.to_bytes().unwrap() +} + #[cfg(test)] mod tests { use ipa_multipoint::{