Skip to content

Commit

Permalink
Merge pull request #1868 from o1-labs/dw/serializer-main-file
Browse files Browse the repository at this point in the history
Serialization/MSM: create the main file
  • Loading branch information
dannywillems authored Feb 29, 2024
2 parents 489c7dd + 5eaa236 commit 9fd540c
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 0 deletions.
3 changes: 3 additions & 0 deletions msm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ path = "src/lib.rs"
name = "main"
path = "src/main.rs"

[[bin]]
name = "serialization"
path = "src/serialization/main.rs"

[dependencies]
ark-bn254 = { version = "0.3.0" }
Expand Down
1 change: 1 addition & 0 deletions msm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub mod proof;
pub mod prover;
pub mod serialization;
pub mod verifier;
pub mod witness;

/// Domain size for the MSM project, equal to the BN254 SRS size.
pub const DOMAIN_SIZE: usize = 1 << 15;
Expand Down
51 changes: 51 additions & 0 deletions msm/src/serialization/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use kimchi::circuits::domains::EvaluationDomains;
use kimchi_msm::serialization::witness;
use kimchi_msm::witness::Witness;
use poly_commitment::pairing_proof::PairingSRS;

use kimchi_msm::precomputed_srs::get_bn254_srs;
use kimchi_msm::serialization::witness::deserialize_field_element;
use kimchi_msm::{Fp, BN254, DOMAIN_SIZE, LIMBS_NUM};

pub fn main() {
// FIXME: use a proper RNG
let mut _rng = o1_utils::tests::make_test_rng();

println!("Creating the domain and SRS");
let domain = EvaluationDomains::<Fp>::create(DOMAIN_SIZE).unwrap();

let _srs: PairingSRS<BN254> = get_bn254_srs(domain);

let mut env = witness::Env::<Fp>::create();
let mut witness: Witness<DOMAIN_SIZE, Vec<Fp>> = Witness {
cols: std::array::from_fn(|_| Vec::with_capacity(DOMAIN_SIZE)),
};

// FIXME: this could be read from a file or a CLI argument
let field_elements = [[0, 0, 0]];
for limbs in field_elements {
deserialize_field_element(&mut env, limbs);
for i in 0..3 {
witness.cols[i].push(env.current_kimchi_limbs[i]);
}
for i in 0..LIMBS_NUM {
witness.cols[3 + i].push(env.msm_limbs[i]);
}
for i in 0..19 {
witness.cols[3 + LIMBS_NUM + i].push(env.intermediate_limbs[i]);
}
}

// println!("Generating the proof");
// let proof = prove::<_, OpeningProof, BaseSponge, ScalarSponge, Column, _>(
// domain,
// &srs,
// witness,
// constraints,
// &mut rng,
// );

// println!("Verifying the proof");
// let verifies = verify::<_, OpeningProof, BaseSponge, ScalarSponge>(domain, &srs, &proof);
// println!("Proof verification result: {verifies}")
}
92 changes: 92 additions & 0 deletions msm/src/witness.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
use ark_ff::Zero;
use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelIterator};

/// The witness columns used by a gate of the MSM circuits.
/// It is generic over the number of columns, N, and the type of the witness, T.
/// It can be used to represent the different subcircuits used by the project.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Witness<const N: usize, T> {
/// A witness row is represented by an array of N witness columns
/// When T is a vector, then the witness describes the rows of the circuit.
pub cols: [T; N],
}

impl<const N: usize, T: Zero + Clone> Default for Witness<N, T> {
fn default() -> Self {
Witness {
cols: std::array::from_fn(|_| T::zero()),
}
}
}

// IMPLEMENTATION OF ITERATORS FOR THE WITNESS STRUCTURE

impl<const N: usize, F: Clone> IntoIterator for Witness<N, F> {
type Item = F;
type IntoIter = std::vec::IntoIter<F>;

/// Iterate over the columns in the circuit.
fn into_iter(self) -> Self::IntoIter {
let mut iter_contents = Vec::with_capacity(N);
iter_contents.extend(self.cols);
iter_contents.into_iter()
}
}

impl<const N: usize, G> IntoParallelIterator for Witness<N, G>
where
Vec<G>: IntoParallelIterator,
{
type Iter = <Vec<G> as IntoParallelIterator>::Iter;
type Item = <Vec<G> as IntoParallelIterator>::Item;

/// Iterate over the columns in the circuit, in parallel.
fn into_par_iter(self) -> Self::Iter {
let mut iter_contents = Vec::with_capacity(N);
iter_contents.extend(self.cols);
iter_contents.into_par_iter()
}
}

impl<const N: usize, G: Send + std::fmt::Debug> FromParallelIterator<G> for Witness<N, G> {
fn from_par_iter<I>(par_iter: I) -> Self
where
I: IntoParallelIterator<Item = G>,
{
let mut iter_contents = par_iter.into_par_iter().collect::<Vec<_>>();
let cols = iter_contents
.drain(..N)
.collect::<Vec<G>>()
.try_into()
.unwrap();
Witness { cols }
}
}

impl<'data, const N: usize, G> IntoParallelIterator for &'data Witness<N, G>
where
Vec<&'data G>: IntoParallelIterator,
{
type Iter = <Vec<&'data G> as IntoParallelIterator>::Iter;
type Item = <Vec<&'data G> as IntoParallelIterator>::Item;

fn into_par_iter(self) -> Self::Iter {
let mut iter_contents = Vec::with_capacity(N);
iter_contents.extend(&self.cols);
iter_contents.into_par_iter()
}
}

impl<'data, const N: usize, G> IntoParallelIterator for &'data mut Witness<N, G>
where
Vec<&'data mut G>: IntoParallelIterator,
{
type Iter = <Vec<&'data mut G> as IntoParallelIterator>::Iter;
type Item = <Vec<&'data mut G> as IntoParallelIterator>::Item;

fn into_par_iter(self) -> Self::Iter {
let mut iter_contents = Vec::with_capacity(N);
iter_contents.extend(&mut self.cols);
iter_contents.into_par_iter()
}
}

0 comments on commit 9fd540c

Please sign in to comment.