From 2d6edcb3a81d28aa175c3d1571b39096e83c6213 Mon Sep 17 00:00:00 2001 From: David Wong Date: Fri, 29 Oct 2021 13:47:18 -0700 Subject: [PATCH 1/4] [kimchi] add a ZK_ROWS constant --- .../src/nolookup/constraints.rs | 21 +++++++--- .../plonk-15-wires/src/polynomials/chacha.rs | 13 +++---- dlog/plonk-15-wires/src/prover.rs | 39 +++++++++++-------- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/circuits/plonk-15-wires/src/nolookup/constraints.rs b/circuits/plonk-15-wires/src/nolookup/constraints.rs index 8c27a6a041..794374b1cd 100644 --- a/circuits/plonk-15-wires/src/nolookup/constraints.rs +++ b/circuits/plonk-15-wires/src/nolookup/constraints.rs @@ -21,6 +21,16 @@ use oracle::poseidon::ArithmeticSpongeParams; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde_with::serde_as; +// +// Constants +// + +pub const ZK_ROWS: u64 = 3; + +// +// ConstraintSystem +// + #[serde_as] #[derive(Clone, Serialize, Deserialize, Debug)] pub struct ConstraintSystem { @@ -255,7 +265,7 @@ where /// Returns the end of the circuit, which is used for introducing zero-knowledge in the permutation polynomial pub fn zk_w3(domain: D) -> F { - domain.group_gen.pow(&[domain.size - 3]) + domain.group_gen.pow(&[domain.size - (ZK_ROWS)]) } /// Evaluates the polynomial @@ -270,7 +280,7 @@ pub fn eval_zk_polynomial(domain: D, x: F) -> F { /// Evaluates the polynomial /// (x - w^{n - 4}) (x - w^{n - 3}) * (x - w^{n - 2}) * (x - w^{n - 1}) pub fn eval_vanishes_on_last_4_rows(domain: D, x: F) -> F { - let w4 = domain.group_gen.pow(&[domain.size - 4]); + let w4 = domain.group_gen.pow(&[domain.size - (ZK_ROWS + 1)]); let w3 = domain.group_gen * w4; let w2 = domain.group_gen * w3; let w1 = domain.group_gen * w2; @@ -282,7 +292,7 @@ pub fn eval_vanishes_on_last_4_rows(domain: D, x: F) -> F { pub fn vanishes_on_last_4_rows(domain: D) -> DP { let x = DP::from_coefficients_slice(&[F::zero(), F::one()]); let c = |a: F| DP::from_coefficients_slice(&[a]); - let w4 = domain.group_gen.pow(&[domain.size - 4]); + let w4 = domain.group_gen.pow(&[domain.size - (ZK_ROWS + 1)]); let w3 = domain.group_gen * w4; let w2 = domain.group_gen * w3; let w1 = domain.group_gen * w2; @@ -332,9 +342,8 @@ impl ConstraintSystem { // +3 on gates.len() here to ensure that we have room for the zero-knowledge entries of the permutation polynomial // see https://minaprotocol.com/blog/a-more-efficient-approach-to-zero-knowledge-for-plonk - // TODO: hardcode this value somewhere - let domain = EvaluationDomains::::create(gates.len() + 3)?; - assert!(domain.d1.size > 3); + let domain = EvaluationDomains::::create(gates.len() + ZK_ROWS as usize)?; + assert!(domain.d1.size > ZK_ROWS); // pre-compute all the elements let mut sid = domain.d1.elements().map(|elm| elm).collect::>(); diff --git a/circuits/plonk-15-wires/src/polynomials/chacha.rs b/circuits/plonk-15-wires/src/polynomials/chacha.rs index ceccaa42d3..fdffcb2eaa 100644 --- a/circuits/plonk-15-wires/src/polynomials/chacha.rs +++ b/circuits/plonk-15-wires/src/polynomials/chacha.rs @@ -435,16 +435,13 @@ mod tests { use super::*; use crate::polynomials::chacha::constraint; use crate::{ - expr::{Column, Constants, Expr, Linearization, PolishToken}, - gate::{LookupInfo, LookupsUsed}, - gates::poseidon::ROUNDS_PER_ROW, - nolookup::constraints::{zk_w3, ConstraintSystem}, + expr::{Column, Constants, PolishToken}, + gate::LookupInfo, nolookup::scalars::{LookupEvaluations, ProofEvaluations}, - polynomials::{chacha, lookup}, wires::*, }; use ark_ff::UniformRand; - use ark_poly::{univariate::DensePolynomial, EvaluationDomain, Radix2EvaluationDomain as D}; + use ark_poly::{EvaluationDomain, Radix2EvaluationDomain as D}; use array_init::array_init; use mina_curves::pasta::fp::Fp as F; use rand::{rngs::StdRng, SeedableRng}; @@ -491,10 +488,10 @@ mod tests { let expr = constraint::(10); let linearized = expr.linearize(evaluated_cols).unwrap(); - let expr_polish = expr.to_polish(); + let _expr_polish = expr.to_polish(); let linearized_polish = linearized.map(|e| e.to_polish()); - let mut rng = &mut StdRng::from_seed([0u8; 32]); + let rng = &mut StdRng::from_seed([0u8; 32]); let d = D::new(1024).unwrap(); diff --git a/dlog/plonk-15-wires/src/prover.rs b/dlog/plonk-15-wires/src/prover.rs index 539b6180e5..b3821a1fff 100644 --- a/dlog/plonk-15-wires/src/prover.rs +++ b/dlog/plonk-15-wires/src/prover.rs @@ -109,10 +109,9 @@ where index: &Index, prev_challenges: Vec<(Vec>, PolyComm)>, ) -> Result { - let d1 = index.cs.domain.d1; - let n = index.cs.domain.d1.size as usize; for w in witness.iter() { if w.len() != n { + let d1_size = index.cs.domain.d1.size as usize; return Err(ProofError::WitnessCsInconsistent); } } @@ -137,7 +136,9 @@ where witness[i].clone(), index.cs.domain.d1, ); - index.srs.commit_evaluations(d1, &e, None, rng) + index + .srs + .commit_evaluations(index.cs.domain.d1, &e, None, rng) }); // compute witness polynomials @@ -224,7 +225,7 @@ where None => (None, None, None, None), Some(_) => { let iter_lookup_table = || { - (0..n).map(|i| { + (0..d1_size).map(|i| { let row = index.cs.lookup_tables8[0].iter().map(|e| &e.evals[8 * i]); CombinedEntry(combine_table_entry(joint_combiner, row)) }) @@ -237,7 +238,7 @@ where dummy_lookup_value.clone(), iter_lookup_table, index.cs.lookup_table_lengths[0], - d1, + index.cs.domain.d1, &index.cs.gates, &witness, joint_combiner, @@ -247,13 +248,17 @@ where .into_iter() .map(|chunk| { let v: Vec<_> = chunk.into_iter().map(|x| x.0).collect(); - lookup::zk_patch(v, d1, rng) + lookup::zk_patch(v, index.cs.domain.d1, rng) }) .collect(); let comm: Vec<_> = lookup_sorted .iter() - .map(|v| index.srs.commit_evaluations(d1, v, None, rng)) + .map(|v| { + index + .srs + .commit_evaluations(index.cs.domain.d1, v, None, rng) + }) .collect(); let coeffs : Vec<_> = // TODO: We can avoid storing these coefficients. @@ -279,7 +284,7 @@ where match lookup_sorted { None => (None, None, None), Some(lookup_sorted) => { - let iter_lookup_table = || (0..n).map(|i| { + let iter_lookup_table = || (0..d1_size).map(|i| { let row = index.cs.lookup_tables8[0].iter().map(|e| & e.evals[8 * i]); combine_table_entry(joint_combiner, row) }); @@ -288,7 +293,7 @@ where lookup::aggregation::<_, Fr, _>( dummy_lookup_value.0, iter_lookup_table(), - d1, + index.cs.domain.d1, &index.cs.gates, &witness, joint_combiner, @@ -297,11 +302,11 @@ where rng)?; drop(lookup_sorted); - if aggreg.evals[n - 4] != Fr::::one() { - panic!("aggregation incorrect: {}", aggreg.evals[n-3]); + if aggreg.evals[d1_size - (ZK_ROWS as usize + 1)] != Fr::::one() { + panic!("aggregation incorrect: {}", aggreg.evals[d1_size-(ZK_ROWS as usize + 1)]); } - let comm = index.srs.commit_evaluations(d1, &aggreg, None, rng); + let comm = index.srs.commit_evaluations(index.cs.domain.d1, &aggreg, None, rng); fq_sponge.absorb_g(&comm.0.unshifted); let coeffs = aggreg.interpolate(); @@ -381,7 +386,7 @@ where coefficient: &index.cs.coefficients8, vanishes_on_last_4_rows: &index.cs.vanishes_on_last_4_rows, z: &lagrange.d8.this.z, - l0_1: l0_1(d1), + l0_1: l0_1(index.cs.domain.d1), domain: index.cs.domain, index: index_evals, lookup: lookup_env, @@ -440,7 +445,7 @@ where (t4, t8), alpha, alphas[alphas.len() - 1], - lookup::constraints(&index.cs.dummy_lookup_values[0], d1) + lookup::constraints(&index.cs.dummy_lookup_values[0], index.cs.domain.d1) .iter() .map(|e| e.evaluations(&env)) .collect(), @@ -606,8 +611,8 @@ where ) }) .collect::>(); - let non_hiding = |n: usize| PolyComm { - unshifted: vec![Fr::::zero(); n], + let non_hiding = |d1_size: usize| PolyComm { + unshifted: vec![Fr::::zero(); d1_size], shifted: None, }; @@ -627,7 +632,7 @@ where // construct evaluation proof let mut polynomials = polys .iter() - .map(|(p, n)| (p, None, non_hiding(*n))) + .map(|(p, d1_size)| (p, None, non_hiding(*d1_size))) .collect::>(); polynomials.extend(vec![(&p, None, non_hiding(1))]); polynomials.extend(vec![(&ft, None, blinding_ft)]); From b047b6e79751ac5945f29072485672d0fdd74039 Mon Sep 17 00:00:00 2001 From: David Wong Date: Fri, 29 Oct 2021 13:49:39 -0700 Subject: [PATCH 2/4] [kimchi] zero-knowledgize the witness cols within the proof creation this was previously done on the OCaml side. This is better because the caller doesn't have to think about doing it. To make sure that the caller didn't mess up this part, we now ask the caller to send the unpadded witness columns. --- .../src/nolookup/constraints.rs | 12 +++++- dlog/plonk-15-wires/src/prover.rs | 40 +++++++++++++++---- oracle/src/rndoracle.rs | 1 + 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/circuits/plonk-15-wires/src/nolookup/constraints.rs b/circuits/plonk-15-wires/src/nolookup/constraints.rs index 794374b1cd..e7ece828c4 100644 --- a/circuits/plonk-15-wires/src/nolookup/constraints.rs +++ b/circuits/plonk-15-wires/src/nolookup/constraints.rs @@ -608,6 +608,15 @@ impl ConstraintSystem { pub fn verify(&self, witness: &[Vec; COLUMNS]) -> Result<(), GateError> { let left_wire = vec![F::one(), F::zero(), F::zero(), F::zero(), F::zero()]; + // pad the witness + let pad = vec![F::zero(); self.domain.d1.size as usize - witness[0].len()]; + let witness: [Vec; COLUMNS] = array_init(|i| { + let mut w = witness[i].to_vec(); + w.extend_from_slice(&pad); + w + }); + + // check each rows' wiring for (row, gate) in self.gates.iter().enumerate() { // check if wires are connected for col in 0..PERMUTS { @@ -630,7 +639,8 @@ impl ConstraintSystem { } } - gate.verify(witness, &self) + // check the gate's satisfiability + gate.verify(&witness, &self) .map_err(|err| GateError::Custom { row, err })?; } diff --git a/dlog/plonk-15-wires/src/prover.rs b/dlog/plonk-15-wires/src/prover.rs index b3821a1fff..49c95eed7d 100644 --- a/dlog/plonk-15-wires/src/prover.rs +++ b/dlog/plonk-15-wires/src/prover.rs @@ -7,6 +7,7 @@ This source file implements prover's zk-proof primitive. pub use super::{index::Index, range}; use crate::plonk_sponge::FrSponge; use ark_ec::AffineCurve; +use ark_ff::UniformRand; use ark_ff::{FftField, Field, One, Zero}; use ark_poly::{ univariate::DensePolynomial, Evaluations, Polynomial, Radix2EvaluationDomain as D, UVPolynomial, @@ -18,6 +19,7 @@ use commitment_dlog::commitment::{ use lookup::CombinedEntry; use o1_utils::ExtendedDensePolynomial; use oracle::{rndoracle::ProofError, sponge::ScalarChallenge, FqSponge}; +use plonk_15_wires_circuits::nolookup::constraints::ZK_ROWS; use plonk_15_wires_circuits::{ expr::{l0_1, Constants, Environment, LookupEnvironment}, gate::{combine_table_entry, GateType, LookupInfo, LookupsUsed}, @@ -25,7 +27,6 @@ use plonk_15_wires_circuits::{ polynomials::{chacha, complete_add, endomul_scalar, endosclmul, lookup, poseidon, varbasemul}, wires::{COLUMNS, PERMUTS}, }; -use rand::thread_rng; use std::collections::HashMap; type Fr = ::ScalarField; @@ -105,17 +106,42 @@ where // RETURN: prover's zk-proof pub fn create, G, Fr>, EFrSponge: FrSponge>>( group_map: &G::Map, - witness: &[Vec>; COLUMNS], + mut witness: [Vec>; COLUMNS], index: &Index, prev_challenges: Vec<(Vec>, PolyComm)>, ) -> Result { - for w in witness.iter() { - if w.len() != n { let d1_size = index.cs.domain.d1.size as usize; + // TODO: rng should be passed as arg + let rng = &mut rand::rngs::OsRng; + + // double-check the witness + if cfg!(test) { + index.cs.verify(&witness).expect("incorrect witness"); + } + + // ensure we have room for the zero-knowledge rows + let length_witness = witness[0].len(); + let length_padding = d1_size + .checked_sub(length_witness) + .ok_or_else(|| ProofError::NoRoomForZkInWitness)?; + if length_padding < ZK_ROWS as usize { + return Err(ProofError::NoRoomForZkInWitness); + } + + // pad and add zero-knowledge rows to the witness columns + for w in &mut witness { + if w.len() != length_witness { return Err(ProofError::WitnessCsInconsistent); } + + // padding + w.extend(std::iter::repeat(Fr::::zero()).take(length_padding)); + + // zk-rows + for row in w.iter_mut().rev().take(ZK_ROWS as usize) { + *row = Fr::::rand(rng); + } } - //if index.cs.verify(witness) != true {return Err(ProofError::WitnessCsInconsistent)}; // the transcript of the random oracle non-interactive argument let mut fq_sponge = EFqSponge::new(index.fq_sponge_params.clone()); @@ -128,8 +154,6 @@ where ) .interpolate(); - let rng = &mut thread_rng(); - // commit to the wire values let w_comm: [(PolyComm, PolyComm>); COLUMNS] = array_init(|i| { let e = Evaluations::, D>>::from_vec_and_domain( @@ -319,7 +343,7 @@ where }; // compute permutation aggregation polynomial - let z = index.cs.perm_aggreg(witness, &beta, &gamma, rng)?; + let z = index.cs.perm_aggreg(&witness, &beta, &gamma, rng)?; // commit to z let z_comm = index.srs.commit(&z, None, rng); diff --git a/oracle/src/rndoracle.rs b/oracle/src/rndoracle.rs index cd70f6fa1d..ab3189c35f 100644 --- a/oracle/src/rndoracle.rs +++ b/oracle/src/rndoracle.rs @@ -10,6 +10,7 @@ use std::fmt; // TODO(mimoo): move this out of oracle #[derive(Debug, Clone, Copy)] pub enum ProofError { + NoRoomForZkInWitness, WitnessCsInconsistent, // TODO(mimoo): once this is moved, error can be propagated here WitnessGateError, From acfe19ae667ddcf73b9f47f8f8f7d8c23546d53e Mon Sep 17 00:00:00 2001 From: David Wong Date: Fri, 29 Oct 2021 13:50:06 -0700 Subject: [PATCH 3/4] [kimchi] fix tests to not pad the witness cols before creating the proof --- .../src/polynomials/endomul_scalar.rs | 22 ++-- .../src/polynomials/permutation.rs | 4 +- dlog/plonk-15-wires/tests/ec.rs | 119 +++++++++--------- dlog/plonk-15-wires/tests/endomul_scalar.rs | 26 ++-- dlog/plonk-15-wires/tests/generic.rs | 16 +-- dlog/tests/chacha_test.rs | 16 +-- dlog/tests/endomul.rs | 23 ++-- dlog/tests/poseidon_vesta_15_wires.rs | 12 +- dlog/tests/varbasemul.rs | 23 ++-- oracle/tests/poseidon_tests.rs | 2 +- 10 files changed, 120 insertions(+), 143 deletions(-) diff --git a/circuits/plonk-15-wires/src/polynomials/endomul_scalar.rs b/circuits/plonk-15-wires/src/polynomials/endomul_scalar.rs index 0420eaf9fa..5318d6d0ce 100644 --- a/circuits/plonk-15-wires/src/polynomials/endomul_scalar.rs +++ b/circuits/plonk-15-wires/src/polynomials/endomul_scalar.rs @@ -183,18 +183,18 @@ pub fn witness( let one = F::one(); let neg_one = -one; - for (i, row_bits) in bits_msb[..].chunks(bits_per_row).enumerate() { - let row = row0 + i; - w[0][row] = n; - w[2][row] = a; - w[3][row] = b; + let mut row = row0; + for row_bits in bits_msb[..].chunks(bits_per_row) { + w[0].push(n); + w[2].push(a); + w[3].push(b); for (j, crumb_bits) in row_bits.chunks(2).enumerate() { let b0 = *crumb_bits[1]; let b1 = *crumb_bits[0]; let crumb = F::from(b0 as u64) + F::from(b1 as u64).double(); - w[6 + j][row] = crumb; + w[6 + j].push(crumb); a.double_in_place(); b.double_in_place(); @@ -213,9 +213,13 @@ pub fn witness( n += crumb; } - w[1][row] = n; - w[4][row] = a; - w[5][row] = b; + w[1].push(n); + w[4].push(a); + w[5].push(b); + + w[14].push(F::zero()); // unused + + row += 1; } assert_eq!(x, n); diff --git a/circuits/plonk-15-wires/src/polynomials/permutation.rs b/circuits/plonk-15-wires/src/polynomials/permutation.rs index cac2d87b6e..500eaa8ef2 100644 --- a/circuits/plonk-15-wires/src/polynomials/permutation.rs +++ b/circuits/plonk-15-wires/src/polynomials/permutation.rs @@ -16,7 +16,7 @@ use ark_poly::{ use ark_poly::{Polynomial, UVPolynomial}; use o1_utils::{ExtendedDensePolynomial, ExtendedEvaluations}; use oracle::rndoracle::ProofError; -use rand::rngs::ThreadRng; +use rand::{CryptoRng, RngCore}; impl ConstraintSystem { /// permutation quotient poly contribution computation @@ -122,7 +122,7 @@ impl ConstraintSystem { witness: &[Vec; COLUMNS], beta: &F, gamma: &F, - rng: &mut ThreadRng, + rng: &mut (impl RngCore + CryptoRng), ) -> Result, ProofError> { let n = self.domain.d1.size as usize; diff --git a/dlog/plonk-15-wires/tests/ec.rs b/dlog/plonk-15-wires/tests/ec.rs index 3d78bb8f26..9488cadbe8 100644 --- a/dlog/plonk-15-wires/tests/ec.rs +++ b/dlog/plonk-15-wires/tests/ec.rs @@ -1,34 +1,28 @@ use ark_ec::{AffineCurve, ProjectiveCurve}; -use ark_ff::{BigInteger, BitIteratorLE, Field, One, PrimeField, UniformRand, Zero}; -use ark_poly::{univariate::DensePolynomial, EvaluationDomain, Radix2EvaluationDomain as D}; +use ark_ff::{Field, One, PrimeField, UniformRand, Zero}; use array_init::array_init; use colored::Colorize; use commitment_dlog::{ - commitment::{b_poly_coefficients, ceil_log2, CommitmentCurve}, + commitment::CommitmentCurve, srs::{endos, SRS}, }; use groupmap::GroupMap; use mina_curves::pasta::{ fp::Fp as F, - pallas::{Affine as Other, Projective as OtherProjective}, + pallas::Affine as Other, vesta::{Affine, VestaParameters}, }; use oracle::{ - poseidon::{ArithmeticSponge, PlonkSpongeConstants15W, Sponge, SpongeConstants}, - sponge::{DefaultFqSponge, DefaultFrSponge, ScalarChallenge}, + poseidon::PlonkSpongeConstants15W, + sponge::{DefaultFqSponge, DefaultFrSponge}, }; use plonk_15_wires_circuits::{ - expr::{Column, Constants, Expr, Linearization, PolishToken}, - gate::{CircuitGate, GateType, LookupInfo, LookupsUsed}, - gates::poseidon::ROUNDS_PER_ROW, - nolookup::constraints::{zk_w3, ConstraintSystem}, - nolookup::scalars::{LookupEvaluations, ProofEvaluations}, - polynomials::endosclmul, + gate::{CircuitGate, GateType}, + nolookup::constraints::ConstraintSystem, wires::*, }; use plonk_15_wires_protocol_dlog::{index::Index, prover::ProverProof}; use rand::{rngs::StdRng, SeedableRng}; -use std::fmt::{Display, Formatter}; use std::{sync::Arc, time::Instant}; const PUBLIC: usize = 0; @@ -64,12 +58,12 @@ fn ec_test() { srs.add_lagrange_basis(cs.domain.d1); let fq_sponge_params = oracle::pasta::fq::params(); - let (endo_q, endo_r) = endos::(); + let (endo_q, _endo_r) = endos::(); let srs = Arc::new(srs); let index = Index::::create(cs, fq_sponge_params, endo_q, srs); - let mut witness: [Vec; COLUMNS] = array_init(|_| vec![F::zero(); n]); + let mut witness: [Vec; COLUMNS] = array_init(|_| vec![]); let verifier_index = index.verifier_index(); let group_map = ::Map::setup(); @@ -77,9 +71,6 @@ fn ec_test() { let lgr_comms = vec![]; let rng = &mut StdRng::from_seed([0; 32]); - let start = Instant::now(); - let mut g = Other::prime_subgroup_generator(); - let ps = { let p = Other::prime_subgroup_generator() .into_projective() @@ -87,7 +78,7 @@ fn ec_test() { .into_affine(); let mut res = vec![]; let mut acc = p; - for i in 0..num_additions { + for _ in 0..num_additions { res.push(acc); acc = acc + p; } @@ -101,7 +92,7 @@ fn ec_test() { .into_affine(); let mut res = vec![]; let mut acc = q; - for i in 0..num_additions { + for _ in 0..num_additions { res.push(acc); acc = acc + q; } @@ -111,77 +102,89 @@ fn ec_test() { for i in 0..num_doubles { let p = ps[i]; - let row = i; let p2 = p + p; let (x1, y1) = (p.x, p.y); let x1_squared = x1.square(); // 2 * s * y1 = 3 * x1^2 let s = (x1_squared.double() + x1_squared) / y1.double(); - witness[0][row] = p.x; - witness[1][row] = p.y; - witness[2][row] = p.x; - witness[3][row] = p.y; - witness[4][row] = p2.x; - witness[5][row] = p2.y; - witness[6][row] = F::zero(); - witness[7][row] = F::one(); - witness[8][row] = s; - witness[9][row] = F::zero(); - witness[10][row] = F::zero(); + + witness[0].push(p.x); + witness[1].push(p.y); + witness[2].push(p.x); + witness[3].push(p.y); + witness[4].push(p2.x); + witness[5].push(p2.y); + witness[6].push(F::zero()); + witness[7].push(F::one()); + witness[8].push(s); + witness[9].push(F::zero()); + witness[10].push(F::zero()); + + witness[11].push(F::zero()); + witness[12].push(F::zero()); + witness[13].push(F::zero()); + witness[14].push(F::zero()); } for i in 0..num_additions { let p = ps[i]; let q = qs[i]; - let row = num_doubles + i; - let pq = p + q; let (x1, y1) = (p.x, p.y); let (x2, y2) = (q.x, q.y); // (x2 - x1) * s = y2 - y1 let s = (y2 - y1) / (x2 - x1); - witness[0][row] = x1; - witness[1][row] = y1; - witness[2][row] = x2; - witness[3][row] = y2; - witness[4][row] = pq.x; - witness[5][row] = pq.y; - witness[6][row] = F::zero(); - witness[7][row] = F::zero(); - witness[8][row] = s; - witness[9][row] = F::zero(); - witness[10][row] = (x2 - x1).inverse().unwrap(); + witness[0].push(x1); + witness[1].push(y1); + witness[2].push(x2); + witness[3].push(y2); + witness[4].push(pq.x); + witness[5].push(pq.y); + witness[6].push(F::zero()); + witness[7].push(F::zero()); + witness[8].push(s); + witness[9].push(F::zero()); + witness[10].push((x2 - x1).inverse().unwrap()); + + witness[11].push(F::zero()); + witness[12].push(F::zero()); + witness[13].push(F::zero()); + witness[14].push(F::zero()); } for i in 0..num_infs { let p = ps[i]; let q = -p; - let row = num_doubles + num_additions + i; let p2 = p + p; let (x1, y1) = (p.x, p.y); let x1_squared = x1.square(); // 2 * s * y1 = -3 * x1^2 let s = (x1_squared.double() + x1_squared) / y1.double(); - witness[0][row] = p.x; - witness[1][row] = p.y; - witness[2][row] = q.x; - witness[3][row] = q.y; - witness[4][row] = p2.x; - witness[5][row] = p2.y; - witness[6][row] = F::one(); - witness[7][row] = F::one(); - witness[8][row] = s; - witness[9][row] = (q.y - p.y).inverse().unwrap(); - witness[10][row] = F::zero(); + witness[0].push(p.x); + witness[1].push(p.y); + witness[2].push(q.x); + witness[3].push(q.y); + witness[4].push(p2.x); + witness[5].push(p2.y); + witness[6].push(F::one()); + witness[7].push(F::one()); + witness[8].push(s); + witness[9].push((q.y - p.y).inverse().unwrap()); + witness[10].push(F::zero()); + + witness[11].push(F::zero()); + witness[12].push(F::zero()); + witness[13].push(F::zero()); + witness[14].push(F::zero()); } index.cs.verify(&witness).unwrap(); let start = Instant::now(); let proof = - ProverProof::create::(&group_map, &witness, &index, vec![]) + ProverProof::create::(&group_map, witness, &index, vec![]) .unwrap(); println!("{}{:?}", "Prover time: ".yellow(), start.elapsed()); diff --git a/dlog/plonk-15-wires/tests/endomul_scalar.rs b/dlog/plonk-15-wires/tests/endomul_scalar.rs index 213deb4dca..30e813f884 100644 --- a/dlog/plonk-15-wires/tests/endomul_scalar.rs +++ b/dlog/plonk-15-wires/tests/endomul_scalar.rs @@ -1,34 +1,28 @@ -use ark_ec::{AffineCurve, ProjectiveCurve}; -use ark_ff::{BigInteger, BitIteratorLE, Field, One, PrimeField, UniformRand, Zero}; -use ark_poly::{univariate::DensePolynomial, EvaluationDomain, Radix2EvaluationDomain as D}; +use ark_ff::{BigInteger, BitIteratorLE, PrimeField, UniformRand, Zero}; use array_init::array_init; use colored::Colorize; use commitment_dlog::{ - commitment::{b_poly_coefficients, ceil_log2, CommitmentCurve}, + commitment::CommitmentCurve, srs::{endos, SRS}, }; use groupmap::GroupMap; use mina_curves::pasta::{ fp::Fp as F, - pallas::{Affine as Other, Projective as OtherProjective}, + pallas::Affine as Other, vesta::{Affine, VestaParameters}, }; use oracle::{ - poseidon::{ArithmeticSponge, PlonkSpongeConstants15W, Sponge, SpongeConstants}, + poseidon::PlonkSpongeConstants15W, sponge::{DefaultFqSponge, DefaultFrSponge, ScalarChallenge}, }; use plonk_15_wires_circuits::{ - expr::{Column, Constants, Expr, Linearization, PolishToken}, - gate::{CircuitGate, GateType, LookupInfo, LookupsUsed}, - gates::poseidon::ROUNDS_PER_ROW, - nolookup::constraints::{zk_w3, ConstraintSystem}, - nolookup::scalars::{LookupEvaluations, ProofEvaluations}, + gate::{CircuitGate, GateType}, + nolookup::constraints::ConstraintSystem, polynomials::endomul_scalar, wires::*, }; use plonk_15_wires_protocol_dlog::{index::Index, prover::ProverProof}; use rand::{rngs::StdRng, SeedableRng}; -use std::fmt::{Display, Formatter}; use std::{sync::Arc, time::Instant}; const PUBLIC: usize = 0; @@ -70,14 +64,14 @@ fn endomul_scalar_test() { srs.add_lagrange_basis(cs.domain.d1); let fq_sponge_params = oracle::pasta::fq::params(); - let (endo_q, endo_r) = endos::(); + let (endo_q, _endo_r) = endos::(); let (_, endo_scalar_coeff) = endos::(); let srs = Arc::new(srs); let index = Index::::create(cs, fq_sponge_params, endo_q, srs); - let mut witness: [Vec; COLUMNS] = array_init(|_| vec![F::zero(); n]); + let mut witness: [Vec; COLUMNS] = array_init(|_| vec![]); let verifier_index = index.verifier_index(); let group_map = ::Map::setup(); @@ -85,7 +79,7 @@ fn endomul_scalar_test() { let lgr_comms = vec![]; let rng = &mut StdRng::from_seed([0; 32]); - let start = Instant::now(); + //let start = Instant::now(); for i in 0..num_scalars { let x = { let bits_lsb: Vec<_> = BitIteratorLE::new(F::rand(rng).into_repr()) @@ -108,7 +102,7 @@ fn endomul_scalar_test() { let start = Instant::now(); let proof = - ProverProof::create::(&group_map, &witness, &index, vec![]) + ProverProof::create::(&group_map, witness, &index, vec![]) .unwrap(); println!("{}{:?}", "Prover time: ".yellow(), start.elapsed()); diff --git a/dlog/plonk-15-wires/tests/generic.rs b/dlog/plonk-15-wires/tests/generic.rs index e075a2a0a0..a6472a498d 100644 --- a/dlog/plonk-15-wires/tests/generic.rs +++ b/dlog/plonk-15-wires/tests/generic.rs @@ -6,7 +6,6 @@ use array_init::array_init; use commitment_dlog::{ commitment::{b_poly_coefficients, ceil_log2, CommitmentCurve}, srs::{endos, SRS}, - PolyComm, }; use groupmap::GroupMap; use mina_curves::pasta::{ @@ -23,10 +22,7 @@ use plonk_15_wires_circuits::{ nolookup::constraints::ConstraintSystem, wires::{Wire, COLUMNS, GENERICS}, }; -use plonk_15_wires_protocol_dlog::{ - index::{Index, VerifierIndex}, - prover::ProverProof, -}; +use plonk_15_wires_protocol_dlog::{index::Index, prover::ProverProof}; use rand::{rngs::StdRng, SeedableRng}; // aliases @@ -96,7 +92,7 @@ fn test_generic_gate() { verify_proof(gates, witness, 0); } -fn verify_proof(gates: Vec>, mut witness: [Vec; COLUMNS], public: usize) { +fn verify_proof(gates: Vec>, witness: [Vec; COLUMNS], public: usize) { // set up let rng = &mut StdRng::from_seed([0u8; 32]); let group_map = ::Map::setup(); @@ -112,12 +108,6 @@ fn verify_proof(gates: Vec>, mut witness: [Vec; COLUMNS], pu let srs = Arc::new(srs); let index = Index::::create(cs, fq_sponge_params, endo_q, srs); - // pad the witness - for v in witness.iter_mut() { - let padding = vec![Fp::zero(); n - v.len()]; - v.extend(padding); - } - // verify the circuit satisfiability by the computed witness index.cs.verify(&witness).unwrap(); @@ -136,7 +126,7 @@ fn verify_proof(gates: Vec>, mut witness: [Vec; COLUMNS], pu // add the proof to the batch let mut batch = Vec::new(); batch.push( - ProverProof::create::(&group_map, &witness, &index, vec![prev]) + ProverProof::create::(&group_map, witness, &index, vec![prev]) .unwrap(), ); diff --git a/dlog/tests/chacha_test.rs b/dlog/tests/chacha_test.rs index 4c3607abe2..8b7956821e 100644 --- a/dlog/tests/chacha_test.rs +++ b/dlog/tests/chacha_test.rs @@ -1,9 +1,7 @@ -use ark_ff::{UniformRand, Zero}; -use ark_poly::{univariate::DensePolynomial, UVPolynomial}; use array_init::array_init; use colored::Colorize; use commitment_dlog::{ - commitment::{b_poly_coefficients, ceil_log2, CommitmentCurve}, + commitment::{ceil_log2, CommitmentCurve}, srs::{endos, SRS}, }; use groupmap::GroupMap; @@ -13,7 +11,7 @@ use mina_curves::pasta::{ vesta::{Affine, VestaParameters}, }; use oracle::{ - poseidon::{ArithmeticSponge, PlonkSpongeConstants15W, Sponge, SpongeConstants}, + poseidon::PlonkSpongeConstants15W, sponge::{DefaultFqSponge, DefaultFrSponge}, }; use plonk_15_wires_circuits::wires::{Wire, COLUMNS}; @@ -21,8 +19,6 @@ use plonk_15_wires_circuits::{ gate::CircuitGate, nolookup::constraints::ConstraintSystem, polynomials::chacha, }; use plonk_15_wires_protocol_dlog::{index::Index, prover::ProverProof}; -use rand::{rngs::StdRng, SeedableRng}; -use std::{io, io::Write}; use std::{sync::Arc, time::Instant}; // aliases @@ -86,10 +82,10 @@ fn chacha_prover() { for _ in 0..num_chachas { rows.extend(chacha::chacha20_rows::(s0.clone())) } - let mut witness: [Vec; COLUMNS] = array_init(|_| vec![Fp::zero(); max_size]); - for (i, r) in rows.into_iter().enumerate() { + let mut witness: [Vec; COLUMNS] = array_init(|_| vec![]); + for r in rows.into_iter() { for (col, c) in r.into_iter().enumerate() { - witness[col][i] = c; + witness[col].push(c); } } @@ -97,7 +93,7 @@ fn chacha_prover() { let start = Instant::now(); let proof = - ProverProof::create::(&group_map, &witness, &index, vec![]) + ProverProof::create::(&group_map, witness, &index, vec![]) .unwrap(); println!("{}{:?}", "Prover time: ".yellow(), start.elapsed()); diff --git a/dlog/tests/endomul.rs b/dlog/tests/endomul.rs index 06253fbb36..a41a3c4575 100644 --- a/dlog/tests/endomul.rs +++ b/dlog/tests/endomul.rs @@ -1,34 +1,29 @@ use ark_ec::{AffineCurve, ProjectiveCurve}; use ark_ff::{BigInteger, BitIteratorLE, Field, One, PrimeField, UniformRand, Zero}; -use ark_poly::{univariate::DensePolynomial, EvaluationDomain, Radix2EvaluationDomain as D}; use array_init::array_init; use colored::Colorize; use commitment_dlog::{ - commitment::{b_poly_coefficients, ceil_log2, CommitmentCurve}, + commitment::CommitmentCurve, srs::{endos, SRS}, }; use groupmap::GroupMap; use mina_curves::pasta::{ fp::Fp as F, - pallas::{Affine as Other, Projective as OtherProjective}, + pallas::Affine as Other, vesta::{Affine, VestaParameters}, }; use oracle::{ - poseidon::{ArithmeticSponge, PlonkSpongeConstants15W, Sponge, SpongeConstants}, + poseidon::PlonkSpongeConstants15W, sponge::{DefaultFqSponge, DefaultFrSponge, ScalarChallenge}, }; use plonk_15_wires_circuits::{ - expr::{Column, Constants, Expr, Linearization, PolishToken}, - gate::{CircuitGate, GateType, LookupInfo, LookupsUsed}, - gates::poseidon::ROUNDS_PER_ROW, - nolookup::constraints::{zk_w3, ConstraintSystem}, - nolookup::scalars::{LookupEvaluations, ProofEvaluations}, + gate::{CircuitGate, GateType}, + nolookup::constraints::ConstraintSystem, polynomials::endosclmul, wires::*, }; use plonk_15_wires_protocol_dlog::{index::Index, prover::ProverProof}; use rand::{rngs::StdRng, SeedableRng}; -use std::fmt::{Display, Formatter}; use std::{sync::Arc, time::Instant}; const PUBLIC: usize = 0; @@ -74,7 +69,6 @@ fn endomul_test() { } let cs = ConstraintSystem::::create(gates, vec![], fp_sponge_params, PUBLIC).unwrap(); - let n = cs.domain.d1.size as usize; let mut srs = SRS::create(cs.domain.d1.size as usize); srs.add_lagrange_basis(cs.domain.d1); @@ -85,7 +79,8 @@ fn endomul_test() { let index = Index::::create(cs, fq_sponge_params, endo_q, srs); - let mut witness: [Vec; COLUMNS] = array_init(|_| vec![F::zero(); n]); + let mut witness: [Vec; COLUMNS] = + array_init(|_| vec![F::zero(); rows_per_scalar * num_scalars]); let verifier_index = index.verifier_index(); let group_map = ::Map::setup(); @@ -93,7 +88,7 @@ fn endomul_test() { let lgr_comms = vec![]; let rng = &mut StdRng::from_seed([0; 32]); - let start = Instant::now(); + // let start = Instant::now(); for i in 0..num_scalars { let bits_lsb: Vec<_> = BitIteratorLE::new(F::rand(rng).into_repr()) .take(num_bits) @@ -151,7 +146,7 @@ fn endomul_test() { let start = Instant::now(); let proof = - ProverProof::create::(&group_map, &witness, &index, vec![]) + ProverProof::create::(&group_map, witness, &index, vec![]) .unwrap(); println!("{}{:?}", "Prover time: ".yellow(), start.elapsed()); diff --git a/dlog/tests/poseidon_vesta_15_wires.rs b/dlog/tests/poseidon_vesta_15_wires.rs index d91eb581fa..82e38f5b39 100644 --- a/dlog/tests/poseidon_vesta_15_wires.rs +++ b/dlog/tests/poseidon_vesta_15_wires.rs @@ -121,7 +121,8 @@ fn positive(index: &Index) { let mut start = Instant::now(); for test in 0..1 { // witness for Poseidon permutation custom constraints - let mut witness: [Vec; COLUMNS] = array_init(|_| vec![Fp::zero(); max_size]); + let mut witness_cols: [Vec; COLUMNS] = + array_init(|_| vec![Fp::zero(); POS_ROWS_PER_HASH * NUM_POS + 1 /* last output row */]); // creates a random initial state let init = vec![Fp::rand(rng), Fp::rand(rng), Fp::rand(rng)]; @@ -129,11 +130,10 @@ fn positive(index: &Index) { // number of poseidon instances in the circuit for h in 0..NUM_POS { // index - // TODO: is the `+ 1` correct? let first_row = h * (POS_ROWS_PER_HASH + 1); // initialize the sponge in the circuit with our random state - let first_state_cols = &mut witness[round_to_cols(0)]; + let first_state_cols = &mut witness_cols[round_to_cols(0)]; for state_idx in 0..SPONGE_WIDTH { first_state_cols[state_idx][first_row] = init[state_idx]; } @@ -162,7 +162,7 @@ fn positive(index: &Index) { // apply the sponge and record the result in the witness let cols_to_update = round_to_cols((round + 1) % ROUNDS_PER_ROW); - witness[cols_to_update] + witness_cols[cols_to_update] .iter_mut() .zip(sponge.state.iter()) // update the state (last update is on the next row) @@ -172,7 +172,7 @@ fn positive(index: &Index) { } // verify the circuit satisfiability by the computed witness - index.cs.verify(&witness).unwrap(); + index.cs.verify(&witness_cols).unwrap(); // let prev = { @@ -194,7 +194,7 @@ fn positive(index: &Index) { batch.push( ProverProof::create::( &group_map, - &witness, + witness_cols, &index, vec![prev], ) diff --git a/dlog/tests/varbasemul.rs b/dlog/tests/varbasemul.rs index d5264cee0e..8a4fed2ad3 100644 --- a/dlog/tests/varbasemul.rs +++ b/dlog/tests/varbasemul.rs @@ -1,34 +1,29 @@ use ark_ec::{AffineCurve, ProjectiveCurve}; use ark_ff::{BigInteger, BitIteratorLE, Field, One, PrimeField, UniformRand, Zero}; -use ark_poly::{univariate::DensePolynomial, EvaluationDomain, Radix2EvaluationDomain as D}; use array_init::array_init; use colored::Colorize; use commitment_dlog::{ - commitment::{b_poly_coefficients, ceil_log2, CommitmentCurve}, + commitment::CommitmentCurve, srs::{endos, SRS}, }; use groupmap::GroupMap; use mina_curves::pasta::{ fp::Fp as F, - pallas::{Affine as Other, Projective as OtherProjective}, + pallas::Affine as Other, vesta::{Affine, VestaParameters}, }; use oracle::{ - poseidon::{ArithmeticSponge, PlonkSpongeConstants15W, Sponge, SpongeConstants}, + poseidon::PlonkSpongeConstants15W, sponge::{DefaultFqSponge, DefaultFrSponge}, }; use plonk_15_wires_circuits::{ - expr::{Column, Constants, Expr, Linearization, PolishToken}, - gate::{CircuitGate, GateType, LookupInfo, LookupsUsed}, - gates::poseidon::ROUNDS_PER_ROW, - nolookup::constraints::{zk_w3, ConstraintSystem}, - nolookup::scalars::{LookupEvaluations, ProofEvaluations}, + gate::{CircuitGate, GateType}, + nolookup::constraints::ConstraintSystem, polynomials::varbasemul, wires::*, }; use plonk_15_wires_protocol_dlog::{index::Index, prover::ProverProof}; use rand::{rngs::StdRng, SeedableRng}; -use std::fmt::{Display, Formatter}; use std::{sync::Arc, time::Instant}; const PUBLIC: usize = 0; @@ -45,6 +40,7 @@ fn varbase_mul_test() { let chunks = num_bits / 5; let num_scalars = 10; + let rows_per_scalar = 2 * (255 / 5); assert_eq!(num_bits % 5, 0); @@ -78,7 +74,8 @@ fn varbase_mul_test() { let index = Index::::create(cs, fq_sponge_params, endo_q, srs); - let mut witness: [Vec; COLUMNS] = array_init(|_| vec![F::zero(); n]); + let mut witness: [Vec; COLUMNS] = + array_init(|_| vec![F::zero(); rows_per_scalar * num_scalars]); let verifier_index = index.verifier_index(); let group_map = ::Map::setup(); @@ -86,8 +83,6 @@ fn varbase_mul_test() { let lgr_comms = vec![]; let rng = &mut StdRng::from_seed([0; 32]); - let rows_per_scalar = 2 * (255 / 5); - let start = Instant::now(); for i in 0..num_scalars { let x = F::rand(rng); @@ -128,7 +123,7 @@ fn varbase_mul_test() { let start = Instant::now(); let proof = - ProverProof::create::(&group_map, &witness, &index, vec![]) + ProverProof::create::(&group_map, witness, &index, vec![]) .unwrap(); println!("{}{:?}", "Prover time: ".yellow(), start.elapsed()); diff --git a/oracle/tests/poseidon_tests.rs b/oracle/tests/poseidon_tests.rs index 097c620475..46f2966303 100644 --- a/oracle/tests/poseidon_tests.rs +++ b/oracle/tests/poseidon_tests.rs @@ -1,4 +1,4 @@ -use ark_ff::{BigInteger256, PrimeField, UniformRand}; +use ark_ff::{BigInteger256, PrimeField}; use ark_serialize::CanonicalDeserialize as _; use mina_curves::pasta::Fp; use oracle::poseidon::Sponge as _; From 7c5bd58c1f7463c9f5a63a241e9ce4124eec36f0 Mon Sep 17 00:00:00 2001 From: David Wong Date: Fri, 29 Oct 2021 13:54:52 -0700 Subject: [PATCH 4/4] [kimchi] fix array into_iter --- circuits/plonk-15-wires/src/gate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuits/plonk-15-wires/src/gate.rs b/circuits/plonk-15-wires/src/gate.rs index 532cf22efb..f9ae3b69e8 100644 --- a/circuits/plonk-15-wires/src/gate.rs +++ b/circuits/plonk-15-wires/src/gate.rs @@ -493,7 +493,7 @@ pub mod caml { T1: Clone, T2: From, { - std::array::IntoIter::new(a) + a.into_iter() .map(Into::into) .next_tuple() .expect("bug in array_to_tuple")