diff --git a/.gitignore b/.gitignore index b72b451..4458a29 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ Cargo.lock **/*.rs.bk *.txt +*.csv +*.ipynb diff --git a/Cargo.toml b/Cargo.toml index d1eca6d..4088fb8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,13 +38,21 @@ ark-r1cs-std = { version = "^0.3.0", default-features = false } ark-nonnative-field = { version = "0.3.0", default-features = false } ark-relations = { version = "^0.3.0", default-features = false } ark-snark = { version = "^0.3.0", default-features = false } +ark-groth16 = { version = "^0.3.0", features = ["r1cs"] } +ark-bw6-761 = { version = "^0.3.0" } lazy_static = "1.4.0" rand = { version = "0.8", features = [ "std", "std_rng" ] } num-bigint = { version = "0.4" } +tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } +tracing-subscriber = { version = "0.2" } + + [dev-dependencies] -criterion = "0.3.1" +serde = { version = "1.0", features = ["derive"] } +csv = "1.1.5" +criterion = "0.3.6" [lib] name = "libspartan" @@ -66,10 +74,17 @@ harness = false name = "nizk" harness = false +[[bench]] +name = "r1cs" +harness = false +debug = true + [features] -default = ["curve25519-dalek/simd_backend"] multicore = ["rayon"] profile = [] +default = ["parallel", "std"] +parallel = [ "std", "ark-ff/parallel", "ark-std/parallel", "ark-ec/parallel"] +std = ["ark-ff/std", "ark-ec/std", "ark-std/std", "ark-relations/std", "ark-serialize/std"] [patch.crates-io] ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std/", rev = "a2a5ac491ae005ba2afd03fd21b7d3160d794a83"} \ No newline at end of file diff --git a/README.md b/README.md index 0eed4a7..1003957 100644 --- a/README.md +++ b/README.md @@ -100,12 +100,12 @@ Here is another example to use the NIZK variant of the Spartan proof system: // produce a proof of satisfiability let mut prover_transcript = PoseidonTranscript::new(¶ms); - let proof = NIZK::prove(&inst, vars, &inputs, &gens, &mut prover_transcript); + let proof = NIZK::prove(&inst, vars, &inputs, &mut prover_transcript); // verify the proof of satisfiability let mut verifier_transcript = PoseidonTranscript::new(¶ms); assert!(proof - .verify(&inst, &inputs, &mut verifier_transcript, &gens) + .verify(&inst, &inputs, &mut verifier_transcript) .is_ok()); println!("proof verification successful!"); # } diff --git a/benches/nizk.rs b/benches/nizk.rs index ab0fdd3..e2f6bea 100644 --- a/benches/nizk.rs +++ b/benches/nizk.rs @@ -1,4 +1,3 @@ -#![allow(clippy::assertions_on_result_states)] extern crate byteorder; extern crate core; extern crate criterion; @@ -7,89 +6,137 @@ extern crate libspartan; extern crate merlin; extern crate sha3; +use std::time::{Duration, SystemTime}; + use libspartan::{ - parameters::poseidon_params, poseidon_transcript::PoseidonTranscript, Instance, NIZKGens, NIZK, + parameters::POSEIDON_PARAMETERS_FR_377, poseidon_transcript::PoseidonTranscript, Instance, NIZK, }; -use merlin::Transcript; use criterion::*; fn nizk_prove_benchmark(c: &mut Criterion) { - for &s in [10, 12, 16].iter() { - let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic); - let mut group = c.benchmark_group("NIZK_prove_benchmark"); - group.plot_config(plot_config); + for &s in [24, 28, 30].iter() { + let mut group = c.benchmark_group("R1CS_prove_benchmark"); let num_vars = (2_usize).pow(s as u32); let num_cons = num_vars; let num_inputs = 10; - - let params = poseidon_params(); - + let start = SystemTime::now(); let (inst, vars, inputs) = Instance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs); + let end = SystemTime::now(); + let duration = end.duration_since(start).unwrap(); + println!( + "Generating r1cs instance with {} constraints took {} ms", + num_cons, + duration.as_millis() + ); - let gens = NIZKGens::new(num_cons, num_vars, num_inputs); - - let name = format!("NIZK_prove_{}", num_vars); - group.bench_function(&name, move |b| { - b.iter(|| { - let mut prover_transcript = PoseidonTranscript::new(¶ms); - NIZK::prove( - black_box(&inst), - black_box(vars.clone()), - black_box(&inputs), - black_box(&gens), - black_box(&mut prover_transcript), - ); + let name = format!("R1CS_prove_{}", num_vars); + group + .measurement_time(Duration::from_secs(60)) + .bench_function(&name, move |b| { + b.iter(|| { + let mut prover_transcript = PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377); + NIZK::prove( + black_box(&inst), + black_box(vars.clone()), + black_box(&inputs), + black_box(&mut prover_transcript), + ); + }); }); - }); group.finish(); } } fn nizk_verify_benchmark(c: &mut Criterion) { - for &s in [10, 12, 16].iter() { - let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic); - let mut group = c.benchmark_group("NIZK_verify_benchmark"); - group.plot_config(plot_config); + for &s in [4, 6, 8, 10, 12, 16, 20, 24, 28, 30].iter() { + let mut group = c.benchmark_group("R1CS_verify_benchmark"); let num_vars = (2_usize).pow(s as u32); let num_cons = num_vars; + // these are the public io let num_inputs = 10; + let start = SystemTime::now(); let (inst, vars, inputs) = Instance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs); + let end = SystemTime::now(); + let duration = end.duration_since(start).unwrap(); + println!( + "Generating r1cs instance with {} constraints took {} ms", + num_cons, + duration.as_millis() + ); + // produce a proof of satisfiability + let mut prover_transcript = PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377); + let proof = NIZK::prove(&inst, vars, &inputs, &mut prover_transcript); - let gens = NIZKGens::new(num_cons, num_vars, num_inputs); - let params = poseidon_params(); + let name = format!("R1CS_verify_{}", num_cons); + group + .measurement_time(Duration::from_secs(60)) + .bench_function(&name, move |b| { + b.iter(|| { + let mut verifier_transcript = PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377); + assert!(proof + .verify( + black_box(&inst), + black_box(&inputs), + black_box(&mut verifier_transcript), + ) + .is_ok()); + }); + }); + group.finish(); + } +} + +fn nizk_verify_groth16_benchmark(c: &mut Criterion) { + for &s in [4, 6, 8, 10, 12, 16, 20, 24, 28, 30].iter() { + let mut group = c.benchmark_group("R1CS_verify_groth16_benchmark"); + + let num_vars = (2_usize).pow(s as u32); + let num_cons = num_vars; + // these are the public io + let num_inputs = 10; + let start = SystemTime::now(); + let (inst, vars, inputs) = Instance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs); + let end = SystemTime::now(); + let duration = end.duration_since(start).unwrap(); + println!( + "Generating r1cs instance with {} constraints took {} ms", + num_cons, + duration.as_millis() + ); // produce a proof of satisfiability - let mut prover_transcript = PoseidonTranscript::new(¶ms); - let proof = NIZK::prove(&inst, vars, &inputs, &gens, &mut prover_transcript); + let mut prover_transcript = PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377); + let proof = NIZK::prove(&inst, vars, &inputs, &mut prover_transcript); - let name = format!("NIZK_verify_{}", num_cons); - group.bench_function(&name, move |b| { - b.iter(|| { - let mut verifier_transcript = PoseidonTranscript::new(¶ms); - assert!(proof - .verify( - black_box(&inst), - black_box(&inputs), - black_box(&mut verifier_transcript), - black_box(&gens) - ) - .is_ok()); + let name = format!("R1CS_verify_groth16_{}", num_cons); + group + .measurement_time(Duration::from_secs(60)) + .bench_function(&name, move |b| { + b.iter(|| { + let mut verifier_transcript = PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377); + assert!(proof + .verify_groth16( + black_box(&inst), + black_box(&inputs), + black_box(&mut verifier_transcript), + ) + .is_ok()); + }); }); - }); group.finish(); } } fn set_duration() -> Criterion { - Criterion::default().sample_size(10) + Criterion::default().sample_size(2) } criterion_group! { name = benches_nizk; config = set_duration(); -targets = nizk_prove_benchmark, nizk_verify_benchmark +targets = nizk_prove_benchmark, nizk_verify_benchmark, nizk_verify_groth16_benchmark } criterion_main!(benches_nizk); diff --git a/benches/r1cs.rs b/benches/r1cs.rs new file mode 100644 index 0000000..79daa68 --- /dev/null +++ b/benches/r1cs.rs @@ -0,0 +1,68 @@ +use std::time::Instant; + +use libspartan::{ + parameters::POSEIDON_PARAMETERS_FR_377, poseidon_transcript::PoseidonTranscript, Instance, NIZK, +}; +use serde::Serialize; + +#[derive(Default, Clone, Serialize)] +struct BenchmarkResults { + power: usize, + input_constraints: usize, + spartan_verifier_circuit_constraints: usize, + r1cs_instance_generation_time: u128, + spartan_proving_time: u128, + groth16_setup_time: u128, + groth16_proving_time: u128, + groth16_verification_time: u128, + testudo_proving_time: u128, +} + +fn main() { + let mut writer = csv::Writer::from_path("testudo.csv").expect("unable to open csv writer"); + for &s in [ + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + ] + .iter() + { + println!("Running for {} inputs", s); + let mut br = BenchmarkResults::default(); + let num_vars = (2_usize).pow(s as u32); + let num_cons = num_vars; + br.power = s; + br.input_constraints = num_cons; + let num_inputs = 10; + + let start = Instant::now(); + let (inst, vars, inputs) = Instance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs); + let duration = start.elapsed().as_millis(); + br.r1cs_instance_generation_time = duration; + let mut prover_transcript = PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377); + let start = Instant::now(); + let proof = NIZK::prove(&inst, vars, &inputs, &mut prover_transcript); + let duration = start.elapsed().as_millis(); + println!("{:?}", duration); + br.spartan_proving_time = duration; + + let mut verifier_transcript = PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377); + let res = proof.verify(&inst, &inputs, &mut verifier_transcript); + assert!(res.is_ok()); + br.spartan_verifier_circuit_constraints = res.unwrap(); + + let mut verifier_transcript = PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377); + let res = proof.verify_groth16(&inst, &inputs, &mut verifier_transcript); + assert!(res.is_ok()); + + let (ds, dp, dv) = res.unwrap(); + br.groth16_setup_time = ds; + br.groth16_proving_time = dp; + br.groth16_verification_time = dv; + + br.testudo_proving_time = br.spartan_proving_time + br.groth16_proving_time; + + writer + .serialize(br) + .expect("unable to write results to csv"); + writer.flush().expect("wasn't able to flush"); + } +} diff --git a/benches/snark.rs b/benches/snark.rs index cf4bf66..3fc6f34 100644 --- a/benches/snark.rs +++ b/benches/snark.rs @@ -1,13 +1,9 @@ -#![allow(clippy::assertions_on_result_states)] extern crate libspartan; extern crate merlin; use libspartan::{ - parameters::poseidon_params, - poseidon_transcript::{self, PoseidonTranscript}, - Instance, SNARKGens, SNARK, + parameters::poseidon_params, poseidon_transcript::PoseidonTranscript, Instance, SNARKGens, SNARK, }; -use merlin::Transcript; use criterion::*; @@ -133,7 +129,7 @@ fn set_duration() -> Criterion { criterion_group! { name = benches_snark; config = set_duration(); -targets = snark_encode_benchmark, snark_prove_benchmark, snark_verify_benchmark +targets = snark_verify_benchmark } criterion_main!(benches_snark); diff --git a/examples/cubic.rs b/examples/cubic.rs index baa8b2d..b474594 100644 --- a/examples/cubic.rs +++ b/examples/cubic.rs @@ -11,16 +11,10 @@ use ark_bls12_377::Fr as Scalar; use ark_ff::{BigInteger, PrimeField}; use ark_std::{One, UniformRand, Zero}; -<<<<<<< HEAD -use libspartan::{InputsAssignment, Instance, SNARKGens, VarsAssignment, SNARK}; -======= use libspartan::{ - parameters::poseidon_params, - poseidon_transcript::{self, PoseidonTranscript}, - InputsAssignment, Instance, SNARKGens, VarsAssignment, SNARK, + parameters::poseidon_params, poseidon_transcript::PoseidonTranscript, InputsAssignment, Instance, + SNARKGens, VarsAssignment, SNARK, }; ->>>>>>> implement alternative transcript with poseidon backend -use merlin::Transcript; #[allow(non_snake_case)] fn produce_r1cs() -> ( diff --git a/profiler/nizk.rs b/profiler/nizk.rs index 9c17206..335e9d7 100644 --- a/profiler/nizk.rs +++ b/profiler/nizk.rs @@ -9,8 +9,7 @@ extern crate rand; use ark_serialize::*; use libspartan::parameters::poseidon_params; use libspartan::poseidon_transcript::PoseidonTranscript; -use libspartan::{Instance, NIZKGens, NIZK}; -use merlin::Transcript; +use libspartan::{Instance, NIZK}; fn print(msg: &str) { let star = "* "; @@ -31,12 +30,12 @@ pub fn main() { let (inst, vars, inputs) = Instance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs); // produce public generators - let gens = NIZKGens::new(num_cons, num_vars, num_inputs); + // let gens = NIZKGens::new(num_cons, num_vars, num_inputs); let params = poseidon_params(); // produce a proof of satisfiability let mut prover_transcript = PoseidonTranscript::new(¶ms); - let proof = NIZK::prove(&inst, vars, &inputs, &gens, &mut prover_transcript); + let proof = NIZK::prove(&inst, vars, &inputs, &mut prover_transcript); let mut proof_encoded = Vec::new(); proof.serialize(&mut proof_encoded).unwrap(); @@ -46,7 +45,7 @@ pub fn main() { // verify the proof of satisfiability let mut verifier_transcript = PoseidonTranscript::new(¶ms); assert!(proof - .verify(&inst, &inputs, &mut verifier_transcript, &gens) + .verify(&inst, &inputs, &mut verifier_transcript) .is_ok()); println!(); diff --git a/src/commitments.rs b/src/commitments.rs index 66ca927..eb646cf 100644 --- a/src/commitments.rs +++ b/src/commitments.rs @@ -1,18 +1,14 @@ -use super::group::{Fq, GroupElement, GroupElementAffine, VartimeMultiscalarMul, GROUP_BASEPOINT}; +use super::group::{GroupElement, GroupElementAffine, VartimeMultiscalarMul, GROUP_BASEPOINT}; use super::scalar::Scalar; -use crate::group::{CompressGroupElement, DecompressGroupElement}; +use crate::group::CompressGroupElement; use crate::parameters::*; use ark_ec::{AffineCurve, ProjectiveCurve}; use ark_ff::PrimeField; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_sponge::poseidon::{PoseidonParameters, PoseidonSponge}; + +use ark_sponge::poseidon::PoseidonSponge; use ark_sponge::CryptographicSponge; -use digest::{ExtendableOutput, Input}; -use sha3::Shake256; -use std::io::Read; -use std::str::FromStr; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct MultiCommitGens { pub n: usize, pub G: Vec, @@ -24,7 +20,7 @@ impl MultiCommitGens { let params = poseidon_params(); let mut sponge = PoseidonSponge::new(¶ms); sponge.absorb(&label); - sponge.absorb(&GROUP_BASEPOINT.into_affine()); + sponge.absorb(&GROUP_BASEPOINT.compress().0); let mut gens: Vec = Vec::new(); for _ in 0..n + 1 { diff --git a/src/constraints.rs b/src/constraints.rs new file mode 100644 index 0000000..c8db59a --- /dev/null +++ b/src/constraints.rs @@ -0,0 +1,440 @@ +use std::{borrow::Borrow, vec}; + +use super::scalar::Scalar; +use crate::{ + group::Fq, + math::Math, + sparse_mlpoly::{SparsePolyEntry, SparsePolynomial}, + unipoly::UniPoly, +}; +use ark_bls12_377::{constraints::PairingVar as IV, Bls12_377 as I, Fr}; +use ark_crypto_primitives::{ + snark::BooleanInputVar, CircuitSpecificSetupSNARK, SNARKGadget, SNARK, +}; + +use ark_ff::{BitIteratorLE, PrimeField, Zero}; +use ark_groth16::{ + constraints::{Groth16VerifierGadget, PreparedVerifyingKeyVar, ProofVar}, + Groth16, PreparedVerifyingKey, Proof as GrothProof, +}; + +use ark_r1cs_std::{ + alloc::{AllocVar, AllocationMode}, + fields::fp::FpVar, + prelude::{Boolean, EqGadget, FieldVar}, +}; +use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, Namespace, SynthesisError}; +use ark_sponge::{ + constraints::CryptographicSpongeVar, + poseidon::{constraints::PoseidonSpongeVar, PoseidonParameters}, +}; +use rand::{CryptoRng, Rng}; + +pub struct PoseidonTranscripVar { + pub cs: ConstraintSystemRef, + pub sponge: PoseidonSpongeVar, + pub params: PoseidonParameters, +} + +impl PoseidonTranscripVar { + fn new( + cs: ConstraintSystemRef, + params: &PoseidonParameters, + challenge: Option, + ) -> Self { + let mut sponge = PoseidonSpongeVar::new(cs.clone(), params); + + if let Some(c) = challenge { + let c_var = FpVar::::new_witness(cs.clone(), || Ok(c)).unwrap(); + sponge.absorb(&c_var); + } + + Self { + cs: cs, + sponge: sponge, + params: params.clone(), + } + } + + fn append(&mut self, input: &FpVar) -> Result<(), SynthesisError> { + self.sponge.absorb(&input) + } + + fn append_vector(&mut self, input_vec: &Vec>) -> Result<(), SynthesisError> { + for input in input_vec.iter() { + self.append(input)?; + } + Ok(()) + } + + fn challenge(&mut self) -> Result, SynthesisError> { + let c_var = self.sponge.squeeze_field_elements(1).unwrap().remove(0); + + Ok(c_var) + } + + fn challenge_vector(&mut self, len: usize) -> Result>, SynthesisError> { + let c_vars = self.sponge.squeeze_field_elements(len).unwrap(); + + Ok(c_vars) + } +} + +#[derive(Clone)] +pub struct UniPolyVar { + pub coeffs: Vec>, +} + +impl AllocVar for UniPolyVar { + fn new_variable>( + cs: impl Into>, + f: impl FnOnce() -> Result, + mode: AllocationMode, + ) -> Result { + f().and_then(|c| { + let cs = cs.into(); + let cp: &UniPoly = c.borrow(); + let mut coeffs_var = Vec::new(); + for coeff in cp.coeffs.iter() { + let coeff_var = FpVar::::new_variable(cs.clone(), || Ok(coeff.clone()), mode)?; + coeffs_var.push(coeff_var); + } + Ok(Self { coeffs: coeffs_var }) + }) + } +} + +impl UniPolyVar { + pub fn eval_at_zero(&self) -> FpVar { + self.coeffs[0].clone() + } + + pub fn eval_at_one(&self) -> FpVar { + let mut res = self.coeffs[0].clone(); + for i in 1..self.coeffs.len() { + res = &res + &self.coeffs[i]; + } + res + } + + // mul without reduce + pub fn evaluate(&self, r: &FpVar) -> FpVar { + let mut eval = self.coeffs[0].clone(); + let mut power = r.clone(); + + for i in 1..self.coeffs.len() { + eval += &power * &self.coeffs[i]; + power *= r; + } + eval + } +} + +#[derive(Clone)] +pub struct SumcheckVerificationCircuit { + pub polys: Vec, +} + +impl SumcheckVerificationCircuit { + fn verifiy_sumcheck( + &self, + poly_vars: &Vec, + claim_var: &FpVar, + transcript_var: &mut PoseidonTranscripVar, + ) -> Result<(FpVar, Vec>), SynthesisError> { + let mut e_var = claim_var.clone(); + let mut r_vars: Vec> = Vec::new(); + + for (poly_var, _poly) in poly_vars.iter().zip(self.polys.iter()) { + let res = poly_var.eval_at_one() + poly_var.eval_at_zero(); + res.enforce_equal(&e_var)?; + transcript_var.append_vector(&poly_var.coeffs)?; + let r_i_var = transcript_var.challenge()?; + r_vars.push(r_i_var.clone()); + e_var = poly_var.evaluate(&r_i_var.clone()); + } + + Ok((e_var, r_vars)) + } +} + +#[derive(Clone)] +pub struct SparsePolyEntryVar { + idx: usize, + val_var: FpVar, +} + +impl AllocVar for SparsePolyEntryVar { + fn new_variable>( + cs: impl Into>, + f: impl FnOnce() -> Result, + _mode: AllocationMode, + ) -> Result { + f().and_then(|s| { + let cs = cs.into(); + let spe: &SparsePolyEntry = s.borrow(); + let val_var = FpVar::::new_witness(cs.clone(), || Ok(spe.val))?; + Ok(Self { + idx: spe.idx, + val_var, + }) + }) + } +} + +#[derive(Clone)] +pub struct SparsePolynomialVar { + num_vars: usize, + Z_var: Vec, +} + +impl AllocVar for SparsePolynomialVar { + fn new_variable>( + cs: impl Into>, + f: impl FnOnce() -> Result, + mode: AllocationMode, + ) -> Result { + f().and_then(|s| { + let cs = cs.into(); + let sp: &SparsePolynomial = s.borrow(); + let mut Z_var = Vec::new(); + for spe in sp.Z.iter() { + let spe_var = SparsePolyEntryVar::new_variable(cs.clone(), || Ok(spe), mode)?; + Z_var.push(spe_var); + } + Ok(Self { + num_vars: sp.num_vars, + Z_var, + }) + }) + } +} + +impl SparsePolynomialVar { + fn compute_chi(a: &[bool], r_vars: &Vec>) -> FpVar { + let mut chi_i_var = FpVar::::one(); + let one = FpVar::::one(); + for (i, r_var) in r_vars.iter().enumerate() { + if a[i] { + chi_i_var *= r_var; + } else { + chi_i_var *= &one - r_var; + } + } + chi_i_var + } + + pub fn evaluate(&self, r_var: &Vec>) -> FpVar { + let mut sum = FpVar::::zero(); + for spe_var in self.Z_var.iter() { + // potential problem + let bits = &spe_var.idx.get_bits(r_var.len()); + sum += SparsePolynomialVar::compute_chi(&bits, r_var) * &spe_var.val_var; + } + sum + } +} + +#[derive(Clone)] +pub struct R1CSVerificationCircuit { + pub num_vars: usize, + pub num_cons: usize, + pub input: Vec, + pub input_as_sparse_poly: SparsePolynomial, + pub evals: (Fr, Fr, Fr), + pub params: PoseidonParameters, + pub prev_challenge: Fr, + pub claims_phase2: (Scalar, Scalar, Scalar, Scalar), + pub eval_vars_at_ry: Fr, + pub sc_phase1: SumcheckVerificationCircuit, + pub sc_phase2: SumcheckVerificationCircuit, +} + +impl R1CSVerificationCircuit { + fn new(config: &VerifierConfig) -> Self { + Self { + num_vars: config.num_vars, + num_cons: config.num_cons, + input: config.input.clone(), + input_as_sparse_poly: config.input_as_sparse_poly.clone(), + evals: config.evals, + params: config.params.clone(), + prev_challenge: config.prev_challenge, + claims_phase2: config.claims_phase2, + eval_vars_at_ry: config.eval_vars_at_ry, + sc_phase1: SumcheckVerificationCircuit { + polys: config.polys_sc1.clone(), + }, + sc_phase2: SumcheckVerificationCircuit { + polys: config.polys_sc2.clone(), + }, + } + } +} + +impl ConstraintSynthesizer for R1CSVerificationCircuit { + fn generate_constraints(self, cs: ConstraintSystemRef) -> ark_relations::r1cs::Result<()> { + let mut transcript_var = + PoseidonTranscripVar::new(cs.clone(), &self.params, Some(self.prev_challenge)); + + let poly_sc1_vars = self + .sc_phase1 + .polys + .iter() + .map(|p| UniPolyVar::new_variable(cs.clone(), || Ok(p), AllocationMode::Witness).unwrap()) + .collect::>(); + + let poly_sc2_vars = self + .sc_phase2 + .polys + .iter() + .map(|p| UniPolyVar::new_variable(cs.clone(), || Ok(p), AllocationMode::Witness).unwrap()) + .collect::>(); + + let input_vars = self + .input + .iter() + .map(|i| FpVar::::new_input(cs.clone(), || Ok(i)).unwrap()) + .collect::>>(); + + transcript_var.append_vector(&input_vars)?; + + let num_rounds_x = self.num_cons.log_2(); + let _num_rounds_y = (2 * self.num_vars).log_2(); + + let tau_vars = transcript_var.challenge_vector(num_rounds_x)?; + + let claim_phase1_var = FpVar::::new_witness(cs.clone(), || Ok(Fr::zero()))?; + + let (claim_post_phase1_var, rx_var) = + self + .sc_phase1 + .verifiy_sumcheck(&poly_sc1_vars, &claim_phase1_var, &mut transcript_var)?; + + let (Az_claim, Bz_claim, Cz_claim, prod_Az_Bz_claims) = &self.claims_phase2; + + let Az_claim_var = FpVar::::new_input(cs.clone(), || Ok(Az_claim))?; + let Bz_claim_var = FpVar::::new_input(cs.clone(), || Ok(Bz_claim))?; + let Cz_claim_var = FpVar::::new_input(cs.clone(), || Ok(Cz_claim))?; + let prod_Az_Bz_claim_var = FpVar::::new_input(cs.clone(), || Ok(prod_Az_Bz_claims))?; + let one = FpVar::::one(); + let prod_vars: Vec> = (0..rx_var.len()) + .map(|i| (&rx_var[i] * &tau_vars[i]) + (&one - &rx_var[i]) * (&one - &tau_vars[i])) + .collect(); + let mut taus_bound_rx_var = FpVar::::one(); + + for p_var in prod_vars.iter() { + taus_bound_rx_var *= p_var; + } + + let expected_claim_post_phase1_var = + (&prod_Az_Bz_claim_var - &Cz_claim_var) * &taus_bound_rx_var; + + claim_post_phase1_var.enforce_equal(&expected_claim_post_phase1_var)?; + + let r_A_var = transcript_var.challenge()?; + let r_B_var = transcript_var.challenge()?; + let r_C_var = transcript_var.challenge()?; + + let claim_phase2_var = + &r_A_var * &Az_claim_var + &r_B_var * &Bz_claim_var + &r_C_var * &Cz_claim_var; + + let (claim_post_phase2_var, ry_var) = + self + .sc_phase2 + .verifiy_sumcheck(&poly_sc2_vars, &claim_phase2_var, &mut transcript_var)?; + + let input_as_sparse_poly_var = SparsePolynomialVar::new_variable( + cs.clone(), + || Ok(&self.input_as_sparse_poly), + AllocationMode::Witness, + )?; + + let poly_input_eval_var = input_as_sparse_poly_var.evaluate(&ry_var[1..].to_vec()); + + let eval_vars_at_ry_var = FpVar::::new_input(cs.clone(), || Ok(&self.eval_vars_at_ry))?; + + let eval_Z_at_ry_var = + (FpVar::::one() - &ry_var[0]) * &eval_vars_at_ry_var + &ry_var[0] * &poly_input_eval_var; + + let (eval_A_r, eval_B_r, eval_C_r) = self.evals; + + let eval_A_r_var = FpVar::::new_witness(cs.clone(), || Ok(eval_A_r))?; + let eval_B_r_var = FpVar::::new_witness(cs.clone(), || Ok(eval_B_r))?; + let eval_C_r_var = FpVar::::new_witness(cs.clone(), || Ok(eval_C_r))?; + + let scalar_var = &r_A_var * &eval_A_r_var + &r_B_var * &eval_B_r_var + &r_C_var * &eval_C_r_var; + + let expected_claim_post_phase2_var = eval_Z_at_ry_var * scalar_var; + + claim_post_phase2_var.enforce_equal(&expected_claim_post_phase2_var)?; + + Ok(()) + } +} + +#[derive(Clone)] +pub struct VerifierConfig { + pub num_vars: usize, + pub num_cons: usize, + pub input: Vec, + pub input_as_sparse_poly: SparsePolynomial, + pub evals: (Fr, Fr, Fr), + pub params: PoseidonParameters, + pub prev_challenge: Fr, + pub claims_phase2: (Fr, Fr, Fr, Fr), + pub eval_vars_at_ry: Fr, + pub polys_sc1: Vec, + pub polys_sc2: Vec, +} +#[derive(Clone)] +pub struct VerifierCircuit { + pub inner_circuit: R1CSVerificationCircuit, + pub inner_proof: GrothProof, + pub inner_vk: PreparedVerifyingKey, + pub evals_var_at_ry: Fr, + pub claims_phase2: (Fr, Fr, Fr, Fr), + pub input: Vec, +} + +impl VerifierCircuit { + pub fn new( + config: &VerifierConfig, + mut rng: &mut R, + ) -> Result { + let inner_circuit = R1CSVerificationCircuit::new(config); + let (pk, vk) = Groth16::::setup(inner_circuit.clone(), &mut rng).unwrap(); + let proof = Groth16::::prove(&pk, inner_circuit.clone(), &mut rng)?; + let pvk = Groth16::::process_vk(&vk).unwrap(); + Ok(Self { + inner_circuit: inner_circuit, + inner_proof: proof, + inner_vk: pvk, + evals_var_at_ry: config.eval_vars_at_ry, + claims_phase2: config.claims_phase2, + input: config.input.clone(), + }) + } +} + +impl ConstraintSynthesizer for VerifierCircuit { + fn generate_constraints(self, cs: ConstraintSystemRef) -> ark_relations::r1cs::Result<()> { + let proof_var = ProofVar::::new_witness(cs.clone(), || Ok(self.inner_proof.clone()))?; + let (v_A, v_B, v_C, v_AB) = self.claims_phase2; + let mut pubs = self.input.clone(); + pubs.extend(vec![v_A, v_B, v_C, v_AB, self.evals_var_at_ry]); + let bits = pubs + .iter() + .map(|c| { + let bits: Vec = BitIteratorLE::new(c.into_repr().as_ref().to_vec()).collect(); + Vec::new_witness(cs.clone(), || Ok(bits)) + }) + .collect::, _>>()?; + let input_var = BooleanInputVar::::new(bits); + + let vk_var = PreparedVerifyingKeyVar::new_witness(cs.clone(), || Ok(self.inner_vk.clone()))?; + Groth16VerifierGadget::verify_with_processed_vk(&vk_var, &input_var, &proof_var)? + .enforce_equal(&Boolean::constant(true))?; + Ok(()) + } +} diff --git a/src/dense_mlpoly.rs b/src/dense_mlpoly.rs index e5b90eb..4b05fdd 100644 --- a/src/dense_mlpoly.rs +++ b/src/dense_mlpoly.rs @@ -27,6 +27,7 @@ pub struct DensePolynomial { Z: Vec, // evaluations of the polynomial in all the 2^num_vars Boolean inputs } +#[derive(Clone)] pub struct PolyCommitmentGens { pub gens: DotProductProofGens, } diff --git a/src/errors.rs b/src/errors.rs index 5f83736..2a7dbe9 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -12,7 +12,7 @@ pub enum ProofVerifyError { impl Default for ProofVerifyError { fn default() -> Self { ProofVerifyError::InternalError - } + } } #[derive(Clone, Debug, Eq, PartialEq)] diff --git a/src/group.rs b/src/group.rs index b6ed4f9..55923f5 100644 --- a/src/group.rs +++ b/src/group.rs @@ -2,11 +2,10 @@ use crate::errors::ProofVerifyError; use ark_ec::msm::VariableBaseMSM; use ark_ff::PrimeField; - use lazy_static::lazy_static; -use num_bigint::BigInt; use super::scalar::Scalar; + use ark_ec::{AffineCurve, ProjectiveCurve}; use ark_serialize::*; use core::borrow::Borrow; diff --git a/src/lib.rs b/src/lib.rs index 58affdc..e0566f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ #![allow(non_snake_case)] #![doc = include_str!("../README.md")] -#![deny(missing_docs)] #![feature(test)] #![allow(clippy::assertions_on_result_states)] @@ -37,17 +36,17 @@ mod timer; mod transcript; mod unipoly; -/// TODO pub mod parameters; -/// TODO + +mod constraints; pub mod poseidon_transcript; -use ark_ff::{BigInteger, Field, PrimeField}; +use ark_ff::Field; use ark_serialize::*; -use ark_std::{One, UniformRand, Zero}; +use ark_std::Zero; use core::cmp::max; use errors::{ProofVerifyError, R1CSError}; -use merlin::Transcript; + use poseidon_transcript::{AppendToPoseidon, PoseidonTranscript}; use r1csinstance::{ R1CSCommitment, R1CSCommitmentGens, R1CSDecommitment, R1CSEvalProof, R1CSInstance, @@ -55,9 +54,9 @@ use r1csinstance::{ use r1csproof::{R1CSGens, R1CSProof}; use random::RandomTape; use scalar::Scalar; -use std::borrow::Borrow; + use timer::Timer; -use transcript::{AppendToTranscript, ProofTranscript}; +use transcript::ProofTranscript; /// `ComputationCommitment` holds a public preprocessed NP statement (e.g., R1CS) pub struct ComputationCommitment { @@ -387,9 +386,9 @@ impl SNARK { &inst.inst, padded_vars.assignment, &inputs.assignment, - &gens.gens_r1cs_sat, + // &gens.gens_r1cs_sat, transcript, - &mut random_tape, + // &mut random_tape, ) }; @@ -443,9 +442,9 @@ impl SNARK { comm: &ComputationCommitment, input: &InputsAssignment, transcript: &mut PoseidonTranscript, - gens: &SNARKGens, + _gens: &SNARKGens, ) -> Result<(), ProofVerifyError> { - let timer_verify = Timer::new("SNARK::verify"); + let _timer_verify = Timer::new("SNARK::verify"); // transcript.append_protocol_name(SNARK::protocol_name()); // append a commitment to the computation to the transcript @@ -453,38 +452,40 @@ impl SNARK { let timer_sat_proof = Timer::new("verify_sat_proof"); assert_eq!(input.assignment.len(), comm.comm.get_num_inputs()); - let (rx, ry) = self.r1cs_sat_proof.verify( + // let (rx, ry) = + self.r1cs_sat_proof.circuit_size( comm.comm.get_num_vars(), comm.comm.get_num_cons(), &input.assignment, &self.inst_evals, transcript, - &gens.gens_r1cs_sat, + // &gens.gens_r1cs_sat, )?; timer_sat_proof.stop(); - let timer_eval_proof = Timer::new("verify_eval_proof"); - let (Ar, Br, Cr) = &self.inst_evals; - // Ar.append_to_transcript(b"Ar_claim", transcript); - // Br.append_to_transcript(b"Br_claim", transcript); - // Cr.append_to_transcript(b"Cr_claim", transcript); - transcript.append_scalar(&Ar); - transcript.append_scalar(&Br); - transcript.append_scalar(&Cr); - self.r1cs_eval_proof.verify( - &comm.comm, - &rx, - &ry, - &self.inst_evals, - &gens.gens_r1cs_eval, - transcript, - )?; - timer_eval_proof.stop(); - timer_verify.stop(); + // let timer_eval_proof = Timer::new("verify_eval_proof"); + // let (Ar, Br, Cr) = &self.inst_evals; + // // Ar.append_to_transcript(b"Ar_claim", transcript); + // // Br.append_to_transcript(b"Br_claim", transcript); + // // Cr.append_to_transcript(b"Cr_claim", transcript); + // transcript.append_scalar(&Ar); + // transcript.append_scalar(&Br); + // transcript.append_scalar(&Cr); + // self.r1cs_eval_proof.verify( + // &comm.comm, + // &rx, + // &ry, + // &self.inst_evals, + // &gens.gens_r1cs_eval, + // transcript, + // )?; + // timer_eval_proof.stop(); + // timer_verify.stop(); Ok(()) } } +#[derive(Clone)] /// `NIZKGens` holds public parameters for producing and verifying proofs with the Spartan NIZK pub struct NIZKGens { gens_r1cs_sat: R1CSGens, @@ -523,21 +524,16 @@ impl NIZK { inst: &Instance, vars: VarsAssignment, input: &InputsAssignment, - gens: &NIZKGens, + // gens: &NIZKGens, transcript: &mut PoseidonTranscript, ) -> Self { let timer_prove = Timer::new("NIZK::prove"); // we create a Transcript object seeded with a random Scalar // to aid the prover produce its randomness - let mut random_tape = RandomTape::new(b"proof"); + let _random_tape = RandomTape::new(b"proof"); -<<<<<<< HEAD - transcript.append_protocol_name(NIZK::protocol_name()); - transcript.append_message(b"R1CSInstanceDigest", &inst.digest); -======= // transcript.append_protocol_name(NIZK::protocol_name()); - inst.inst.append_to_poseidon(transcript); ->>>>>>> simplify transcript and change merlin backend to poseidon + transcript.append_bytes(&inst.digest); let (r1cs_sat_proof, rx, ry) = { // we might need to pad variables @@ -555,9 +551,9 @@ impl NIZK { &inst.inst, padded_vars.assignment, &input.assignment, - &gens.gens_r1cs_sat, + // &gens.gens_r1cs_sat, transcript, - &mut random_tape, + // &mut random_tape, ); let mut proof_encoded = Vec::new(); proof.serialize(&mut proof_encoded).unwrap(); @@ -578,17 +574,51 @@ impl NIZK { inst: &Instance, input: &InputsAssignment, transcript: &mut PoseidonTranscript, - gens: &NIZKGens, - ) -> Result<(), ProofVerifyError> { + // gens: &NIZKGens, + ) -> Result { + let timer_verify = Timer::new("NIZK::verify"); + + transcript.append_bytes(&inst.digest); + + // We send evaluations of A, B, C at r = (rx, ry) as claims + // to enable the verifier complete the first sum-check + let timer_eval = Timer::new("eval_sparse_polys"); + let (claimed_rx, claimed_ry) = &self.r; + let inst_evals = inst.inst.evaluate(claimed_rx, claimed_ry); + timer_eval.stop(); + + let timer_sat_proof = Timer::new("verify_sat_proof"); + assert_eq!(input.assignment.len(), inst.inst.get_num_inputs()); + // let (rx, ry) = + let nc = self.r1cs_sat_proof.circuit_size( + inst.inst.get_num_vars(), + inst.inst.get_num_cons(), + &input.assignment, + &inst_evals, + transcript, + // &gens.gens_r1cs_sat, + )?; + + // verify if claimed rx and ry are correct + // assert_eq!(rx, *claimed_rx); + // assert_eq!(ry, *claimed_ry); + timer_sat_proof.stop(); + timer_verify.stop(); + + Ok(nc) + } + + /// A method to verify a NIZK proof of the satisfiability of an R1CS instance with Groth16 + pub fn verify_groth16( + &self, + inst: &Instance, + input: &InputsAssignment, + transcript: &mut PoseidonTranscript, + ) -> Result<(u128, u128, u128), ProofVerifyError> { let timer_verify = Timer::new("NIZK::verify"); -<<<<<<< HEAD - transcript.append_protocol_name(NIZK::protocol_name()); - transcript.append_message(b"R1CSInstanceDigest", &inst.digest); -======= // transcript.append_protocol_name(NIZK::protocol_name()); - inst.inst.append_to_poseidon(transcript); ->>>>>>> simplify transcript and change merlin backend to poseidon + transcript.append_bytes(&inst.digest); // We send evaluations of A, B, C at r = (rx, ry) as claims // to enable the verifier complete the first sum-check @@ -599,22 +629,23 @@ impl NIZK { let timer_sat_proof = Timer::new("verify_sat_proof"); assert_eq!(input.assignment.len(), inst.inst.get_num_inputs()); - let (rx, ry) = self.r1cs_sat_proof.verify( + // let (rx, ry) = + let (ds, dp, dv) = self.r1cs_sat_proof.verify_groth16( inst.inst.get_num_vars(), inst.inst.get_num_cons(), &input.assignment, &inst_evals, transcript, - &gens.gens_r1cs_sat, + // &gens.gens_r1cs_sat, )?; // verify if claimed rx and ry are correct - assert_eq!(rx, *claimed_rx); - assert_eq!(ry, *claimed_ry); + // assert_eq!(rx, *claimed_rx); + // assert_eq!(ry, *claimed_ry); timer_sat_proof.stop(); timer_verify.stop(); - Ok(()) + Ok((ds, dp, dv)) } } @@ -623,7 +654,7 @@ mod tests { use crate::parameters::poseidon_params; use super::*; - use ark_ff::PrimeField; + use ark_ff::{BigInteger, One, PrimeField}; #[test] pub fn check_snark() { @@ -775,7 +806,7 @@ mod tests { .is_ok()); // NIZK public params - let gens = NIZKGens::new(num_cons, num_vars, num_inputs); + let _gens = NIZKGens::new(num_cons, num_vars, num_inputs); let params = poseidon_params(); @@ -785,14 +816,14 @@ mod tests { &inst, assignment_vars, &assignment_inputs, - &gens, + // &gens, &mut prover_transcript, ); // verify the NIZK let mut verifier_transcript = PoseidonTranscript::new(¶ms); assert!(proof - .verify(&inst, &assignment_inputs, &mut verifier_transcript, &gens) + .verify(&inst, &assignment_inputs, &mut verifier_transcript) .is_ok()); } } diff --git a/src/nizk/bullet.rs b/src/nizk/bullet.rs index e36e8e6..f85266e 100644 --- a/src/nizk/bullet.rs +++ b/src/nizk/bullet.rs @@ -11,14 +11,11 @@ use super::super::group::{ CompressGroupElement, CompressedGroup, DecompressGroupElement, GroupElement, VartimeMultiscalarMul, }; -use super::super::math::Math; use super::super::scalar::Scalar; -use super::super::transcript::ProofTranscript; -use ark_ff::{fields, Field}; +use ark_ff::Field; use ark_serialize::*; use ark_std::{One, Zero}; use core::iter; -use merlin::Transcript; use std::ops::MulAssign; #[derive(Debug, CanonicalSerialize, CanonicalDeserialize)] diff --git a/src/nizk/mod.rs b/src/nizk/mod.rs index 9e63ce5..f8e7497 100644 --- a/src/nizk/mod.rs +++ b/src/nizk/mod.rs @@ -5,18 +5,13 @@ use crate::poseidon_transcript::{AppendToPoseidon, PoseidonTranscript}; use super::commitments::{Commitments, MultiCommitGens}; use super::errors::ProofVerifyError; use super::group::{ - CompressGroupElement, CompressedGroup, DecompressGroupElement, GroupElement, GroupElementAffine, - UnpackGroupElement, + CompressGroupElement, CompressedGroup, DecompressGroupElement, GroupElement, UnpackGroupElement, }; -use super::math::Math; use super::random::RandomTape; use super::scalar::Scalar; -use super::transcript::{AppendToTranscript, ProofTranscript}; -use ark_ec::group::Group; use ark_ec::ProjectiveCurve; use ark_ff::PrimeField; use ark_serialize::*; -use merlin::Transcript; mod bullet; use bullet::BulletReductionProof; @@ -423,6 +418,7 @@ impl DotProductProof { } } +#[derive(Clone)] pub struct DotProductProofGens { n: usize, pub gens_n: MultiCommitGens, @@ -595,13 +591,10 @@ impl DotProductProofLog { #[cfg(test)] mod tests { - use std::marker::PhantomData; - use crate::{group::VartimeMultiscalarMul, parameters::poseidon_params}; + use crate::parameters::poseidon_params; use super::*; - use ark_bls12_377::{Fq, FqParameters, G1Affine}; - use ark_ff::{BigInteger384, Fp384}; use ark_std::UniformRand; #[test] fn check_knowledgeproof() { diff --git a/src/parameters.rs b/src/parameters.rs index 8d83cb0..142d327 100644 --- a/src/parameters.rs +++ b/src/parameters.rs @@ -5,225 +5,138 @@ use ark_sponge::poseidon::PoseidonParameters; use json::JsonValue; use lazy_static::lazy_static; -use crate::group::Fq; - +use crate::group::Fr; lazy_static! { - /// bls12377_rate2_constraints: - pub static ref P1: JsonValue = object! { + // bls12377_rate2_constraints_fr: +pub static ref FR: JsonValue = object! { "ark" => array![ - array![ - "123249878756453098914639601843199176451997132612914162343590671120179979107846114348064675842753496966502226470504", - "53905766173893895260794869709237214385817399454448711667759505042599362214601718682151848385057179500606557721647", - "69894258097921391480299485244196654800484322255007476002974737215216019155108287854575586445309048623300976500186" - ], - array![ - "199269668121875174262570566455689951380204776091573924798659006690560053061129973379838694860592058095048653996886", - "238380155638054426865611280966399840311283670977656700124343990049337832223435242290330416091629395326468367200694", - "212599814638151740594239938840408336056840064513659388805072396583467200575230295920880684207605497942975271963482" - ], - array![ - "168914555474650585865140636066457509664822869961119817085015902784107763611497575013588473080216753361935154707010", - "53776337623194839368137436133474167179306472987260969806083684345990583528478024243778418311781192352786333037262", - "248867522100291115924418017563087071912585010573958563496624003376931076896846052799391847772671448846373554213551" - ], - array![ - "35631741058397496924366231156673935881565943972602937094522045989256363839293709188784238224940964750407897277330", - "7156811532468409927576845751990203959972794842929038664826572233020786824205198784067484739611297952558975673525", - "15979461281492123433122857594463244790261784547146673175073000444677214597242748768087325039007316516299176001509" - ], - array![ - "49754305211992756860291736450940496115500536038609822532547985566439150683219315252172063528174877535028115611426", - "216949553183571701463265648286619401188451882876550757881148401346730830975776784112086074385527611896268776861443", - "154083689848809196835533626226861291475925228965341568449375421928198779718328545609801450631059855774468437183675" - ], - array![ - "29502137502944860067241987089780210878930586459241857665873534227953181087265906053919742367508518196418106799806", - "132373035808136518827992049261301947450498154936614023679388954300081661784851944028690271115929087672833323628947", - "215747065685210104280208334912564361804699328020235674942496660758226155688200145092731052953352829033676863042630" - ], - array![ - "199648585544625597282043439398719700409246757664428471828724582419530290323495031580337339234017647369916547108958", - "249575928844995465269738608819476286372884074177639142297081916221358214871660642843838074316560663218386973740173", - "74982114655706235696493453220768307411520767156884132118410225505977592728838652389837915751053304413004683265639" - ], - array![ - "106210893563839260576304917669354671677368166928359922623554581531406088660838991706361575276657684361659801532597", - "11585440423875492387746565618452234080951922019833673083821688269701182965167436520603220148800340540649190539129", - "37259364694251003983990539546703073907090415386678577600390274977885009271501265285951467194762590248232970812844" - ], - array![ - "55837576930986823158863800928077105077853280536700135646766922885911998320579725325719074294029609849816879406734", - "116196118812458208678900768001429737210506949071720002979523997962887466062064707950742955679705357069634209515723", - "24815444638034932833671809997597970940772642987124330190627003560135207315166813788012165972582101193880572012425" - ], - array![ - "8273799170260651595038492091530332589844019793817674372861920239816475852471908767091347071442643736888815451573", - "136990111822759715389631392741048451444971543778803264358207793191138912342988121207664006283186301023235486962908", - "18927153358572748727167231887593945930709178220781358813059367890606662567925981344966823750216495960065937779382" - ], - array![ - "14853717798346258618706074618305350695598054492875071420312670809589654546598863746625188519698040835608660556159", - "176244718044988586163620753193829773891006448729185890339575543133809251309372861124810944047181141986328457412271", - "110233743777966819273995158642051347290508079434162581354613179685804039325709118867348142870653771761630005888307" - ], - array![ - "161450408187838611032909671423510614052593225149162808041124828019352169325631782682210492475825053268732766729188", - "98500573657597535150392453836987141880178711694344573271124963035313026654066107879785978599420939724454330812177", - "215876031358183401857867635719035351422270130594078940310356834104879903855422762837568172975859284057413791888463" - ], - array![ - "204131296462104965227188513952192358580161695271034405933269755582850293970852406144296664401269366372941792250467", - "249055944105228847655227995674839790690527612872758434023675475202902983562708467495202781909125241976893640769485", - "229583286868130259500413761228235662329364304128164289006746728927752301094007770574061957905615623121952293733410" - ], - array![ - "97517137752483519086795583001379387731583152856232248443468839338330057977841917349007821334306740790291136905974", - "123488479251161582154755930609622851433258511862463208593787895860046694339616550157942520077460765622263030118175", - "71432639825611523000280189495110508914555485498103026713477936527348359478511563831157563324853527351478004088468" - ], - array![ - "91036072174315573792700064386146501824720160045153964050728880763049550271037560479809028105202996773568857740730", - "22543564450401763754262340909190687557385187274502421381039682479049063587284520644182139148382788770792136350730", - "142332951471076179551307567596387601171650552060403080229506160329597397458669457278907083453911143048367692807957" - ], - array![ - "132220734042377172239294549962805515211262743615319266088172915692615455860531484953442975677793502323549653807013", - "93545141080589996877640088231346264823743396787843686206971590288437291906435217842171096954488932034021955982341", - "240853888813002049402641151657197764532471620278969626757294146309548064471722973918761650243980940919903584631021" - ], - array![ - "213503951761453329038225269663723790274543267128942326856880800168236861547603473591480303861374397603917184363409", - "89903237953544441905563167047407202265037317870234905464628470820413104873403912116742106741939288646681955585592", - "227121824801807544842683518849178395477499272684097761652696447845872786929195257751449337349649535876783186356932" - ], - array![ - "146971666607035715052553690155718843961663952406456998981945817009558492075030732771578449344145496025583596767529", - "134089029253068479750825302615074040106242441439845487647903191411265000857473209669062720892950980761449114307448", - "240876825504060088346683291079269022914405381209699533928214418428379986520457497863030431018122239809907227823545" - ], - array![ - "198679995161578152944752940670334322637799809857648522826858388680172266023884005933440419287476164086770000386213", - "80453254513068178946616210391952329341738228131537630777936072121633132376974015675425930731821852982135052772824", - "51768068183070369841309308465744117994964313769378589398952388439182600629247824076033474616974680361718264496789" - ], - array![ - "243786304512064454489442716415645262128218178912097043568997297339729319251009514316482045843945939785873311024862", - "132173037488875105639933852791191619959134471035456041997878656537714362390384670197604289467581846432000497395848", - "138604002173172705882182745730007697550901886293221788738303534900559003963900219115006541529324886578352274293799" - ], - array![ - "81783919742603431816536303551235523053319325628680028340677898253811841771498386894771134375242031554657528159968", - "89996400559826291686063370272745776928773053585174906250124744120004601102635457051808673956966087024872962073778", - "12344123991576028812375373502965766640863831483294590816896451707123374600150201588149068234468387476695336142872" - ], - array![ - "126658015711577921340966771989453650175842088716604137911295183366663485409400992312567694787591845600554914654115", - "164573749458837881364642242529191795392373682411872943164652677729048094673511958737424619008331062199862267652935", - "143664707544522749631081019060087611028964440272897357239195964754781588855456478370128855886667526444876450715220" - ], - array![ - "190063502426458192727293662114673159337018305482738016082798402909947909388433256561924969169284825978832455579368", - "200570271046622734241692574928890759512247601848653772722076665026354776331148830989844078413438205377226077381532", - "138002415082423685424410551811447526297743243297262932785520614237184932570821640271043572260989269814779470761461" - ], - array![ - "16788676705864143878780230479765282864054741033672656690224477402805235181341884274547412331727211099012342081859", - "204290600886783875333612666138119904239583082229871768433568000092203989815186589303588884701205693229512519768754", - "87038987841167673770859932175226012933997089943393502222169060963262863845214906568997443646438042896398425595517" - ], - array![ - "36339730403510893807656584803012696279422432037251730189319369181711761371163710757212065138707754369092877655154", - "23719136079159372599286451744989936807954969964666516807332295420486880070514166596679589399139358707568583760908", - "56393335057571631799160728164218189604902690263179612889078150181027528679320914138536210530501845237163318197428" - ], - array![ - "205825956035491267343111682188790766922328411605275469211275484195313659964988531094479492782154028581379936224444", - "14251323509232608512846002255486393977548730149242264667463070512925839406395836441387775340864744223546556498715", - "78428895560820169309169428677090706087502853851935641954584167534512067284012881590143110425966068532035695668777" - ], - array![ - "75494383501361595510879099604200999089073272552094921752996800680267084650818676639185519371499429119407927521694", - "71654751419236499966546173490894599834311797714598165686807217633186393301928260640596079166780877531085221325785", - "200578082042519003217027186194032673613554519507662494009516442239977006673663941756393116663841297396793491871200" - ], - array![ - "120280384146306862951854508424447098979618461682025441151850969362942271625861150381428890843919546149633622105768", - "227475425496153223669855864055613669014065977392917058770175352117179491094064142348157299350182313499504389083442", - "251127263423734302912203519333198755054413799582445749881827904612771493287021107263113755730642765378206506332728" - ], - array![ - "83702595636895308967051271584382753663326775825724154674461807131791275318302215831042606082449545102374950849149", - "72457985217378059985209058682320070298806205003882947360107581077425648268857982638575115120572096951096305132848", - "12116600973201943572988978934130839409963908949941838392365368398743958008280031214900074753572240221871297157796" - ], - array![ - "240872572144156225455781664515486127362275317595363215915293841253269790726868349873274949641462036923410553640448", - "145005621445512968320023394688234446061157047306027479183225589915851108312974841851900985683181027983777819469749", - "223934906758737028193582875327881601162900418521869327818828928797111524239009182764598636421899745113893918838102" - ], - array![ - "16041135858962966773434394701665023495889307936385789447051685789622713476233465453520183391926457145978975456780", - "100995326650741809373350376300291093265611246694300366918949313510272548230989953212376186670081618363334860819266", - "198113061836041953087296741499457296947901762958345262407373960882722071735229745555760175641534017765920249851403" - ], - array![ - "160310964282803191210156178260469498817686363777861893444880694842806130876775742977058740003184226096711472502332", - "188713129639597187156378905515616933770775761286091242780337441914651066308540192205692023798450603034519453279164", - "144177371846162732968346932904974285173557315948314203099016729242538001323624139665700501564547696462348047085475" - ], - array![ - "79270873425284875854185620699109770597921524227459035513636651263949603822776268395349011178814936290604749327216", - "66634508562919326060253106867724866375414704994924403132729353386392729560099833340809999504328104294822126690206", - "153929451747036516277146884279088023240503545576502622475104547924498837499332163003522743849174380874173903478589" - ], - array![ - "65951591639970943843478787167093376292485300299245482252716091066831460583153445126961516774641242644059740963631", - "218283324593072992330537678366612521138133713936527225314279366375484764183384762101590493464257294993736058798003", - "255801326343293104028075157882719596846119525365262151647658801094843254475907908556215545683201236013153654096091" - ], - array![ - "226255389453600272835601278226928175590352392261397636954040403683064727971365284972741836048745971086673805312770", - "30094566584570359029617856208266980210102789615056943080637739339632299082666382408767896640283618386400863011377", - "171014403954507192635907791911496156579477488568451453501143540559952206171633891640382019016227963532953321760176" - ], - array![ - "166057204219683871752892448206953243424627338207417177280506199576386068200127812837156087933305873775343563022702", - "189980739384556361714711372786771245267076300911771323385655044819119270337048535106665515768517077503660696853087", - "160509966668023670725615598656132311085788181242287915812481624013950278259314541983309947248633680202474798784113" - ], - array![ - "121604680206118278311858973633579806987780447456690173958929756615242378735587345162043644789250322132552405934838", - "162490787868836358365957714904092588505217178719637049967797863955517541278871433068812149053958672871873339777657", - "186725839885149672835245872626306502017366920295670132626156737796246154714707858273955752031344539280320214023217" - ], - array![ - "1595442381035683601009655514607864917155264882908420917897267779293136954609652688808389170558528873507396022657", - "136133658372771228168254201060050291177683595113705517331628662542619211285959494716428905546778127973286832435248", - "235707281471584662954139438770000959801075760015072690205031932435280838811659817426504701946918628382850116491607" - ], - array![ - "218394064516331833020386245120198448098388776182164066507039096886784654454748249393443008924076322437744672962940", - "171630003249069743969583651512237853143542592922081517495872510118379411011409238640358871094120884164999614012", - "106352495811714591674517100311841383873861724084673517408579093193910563925812357978278276551276192431523493134802" - ] - ], - "mds" => array![ - array![ - "35463799792750972803746014831251318629433070651916394903137949221437209577677273605833717469941575569104741526451", - "18525374364661750307440824350340771293424609245159218207409253749617918442029080961367157063966182839254983576724", - "96313611821735511449591580163083975587347120205529218061849469348716252837177987500111192232021055962542059542412" - ], - array![ - "184610826894298373826952030256215485452556494530798726246415694794196222735666067140505346074672032818873376193660", - "169170114062164939552104715979827042386033829996509029655899361104098442853225147615546393356393444238242438049980", - "24177241132903335121524689415818818107920151023402250200813429563196326173884815770339346817801446861279643703952" - ], - array![ - "17228430949886884828033371768349883299641066192821547195081333400086665473981454169936377873256566147576607049992", - "35113533023170247280272066588387614578863541036869539331927201531038853371598133096624809442419922813566246641442", - "225762263795139846379155325981635321549752796953252150370574780810431415761301654496442331322761087421338650655933" - ] - ], + array!["1370773116404421539888881648821194629032979299946048429076387284005101684675", +"4673035637825817609038514733539555185313791666023633961663352080665830654830", +"3476986714632640194314485873881082667866912997891863048915892042674874286264"], +array!["1082495278266482754833562621758308632581366365108718780801560341752506567697", +"4949432510532674124503328437030614426007112126335799011165573383397503068558", +"1330731268421256836250705136567442317504087954921291231955447229193812596308"], +array!["2649505161225663922316999879032136225486779063673300240621719420078616600331", +"4969420587703679612645522006695883166296724515300508402438681500077273342102", +"205635712587803026777585519450868615715404988831679984758308345484658244699"], +array!["6145772648854219628629735661952781083869402744236565775495743574991105198727", +"5694971131555029816374722311330556638260056256238039903705739439184187043937", +"5741725876337992913741719090196370235271299497940404104226910654118627348231"], +array!["6469638413629030129780219709477213488269112947492045389237429028620220258446", +"3701595212702118832843766258638566924918883592466668319824165091176624488470", +"3788264172113320071929375505654410621672880197708720070568683533593741188367"], +array!["7440115096888436553805393179190448787187286166192882400220572931865568317182", +"792346028642694686435936057983036575794551345818605100013220351237266490211", +"3512073197867644095949820682768614757198377867832806840119595329029395413419"], +array!["3327088580126882425803902509250293076948968718390152099056814690231480975540", +"7158369207426751973498757672315193862013926247640641608613447343948389969907", +"6576114422707630183258306285876174832535448513519868242206479550748199028650"], +array!["1750441329216804285131573838407988974537000108919914117251383215390240334007", +"6643642586767682146943021170325866479407987761019956931934065669737733844970", +"4106833857706706417652949425395842926674588555313556065852954705212767334548"], +array!["5196247641080157421214976259470019902011109253162446920598369271583914387912", +"6360624992789526556614108772011303405529807087502693775123890278812066474754", +"8425833359837698797187325575646708254811496588866812335451071326764069753553"], +array!["7571765444928048488636382364785227388831860339901373587410494373985769122100", +"1146560176939543249528183531911179059346379826648787355971780563762045417939", +"7065673187452873657602174269205792331276819829797382751854008973390840650347"], +array!["2996886232144394882237600400269759049381836612341075168714674419715424495381", +"7668744387648470169368229696434415530109096020857128629089289952099341334341", +"936627698981026919732496023789041288394375500602254911470718843646602645053"], +array!["6199749224785668013863210092063343076018531979597999604829468825162260274190", +"1653132234679858820482383205271489733007453315887823778464537322543673289375", +"7939359542319254103812635759696217625861967838748888560647186882218141754398"], +array!["5250147394211818178524181700154433748053992647055590962793825894928645733326", +"235902753941634492088451291363018081809625358810315316265161104829935550542", +"6608963137139961850002639926351347514621255004982055637993898513250013620207"], +array!["686840635267965663175276645211808051025823527505028096239338481540935993835", +"6836915689880452140045500520891176609600850753468429607484223074627863622754", +"4411311036661487117682008390277121256586135166845650218368031395328640568455"], +array!["7765580651637884064091086941299831107821005732883926779656422881469118342677", +"332549754384827539552516583331436482626027168628972328124682073094327566178", +"8438579169602499403531276834153862236681805902767396281885988675130427183942"], +array!["4371224392051444141538216717830171873522813314722974453159288159086172590441", +"4471819188266525256545603690402039960553559029943278641513107103995534212653", +"7934285249368611074358220926618133755594116808280441387064776330233673680433"], +array!["3296929004083914338419828203502973195235748568216135964056267831058260996338", +"7828705062628438916991665037339807083733865061668384262916273779860279371794", +"6313358380505257639005175768394745400256528068580776946435054333930810425918"], +array!["7673091158517942236320201239127705985446414040558434294512441355493079388101", +"3589839431787481799335476281766961640592432750884680804513596535388211513959", +"3497309798506406648010286927425548038594271991920637549888387014860982947288"], +array!["3598928531842189258027744661377220155690961099878644839237443661252156892627", +"8323476545439527339398168929351847585459351691146904838200536423836775797722", +"2525233425021205371462807301191193452372106809085080242885832543937723343824"], +array!["1670123541208150697178760793866430341950571765422973242642698972122650175931", +"2615994352824306042392204336460002628039562926557752567316988279659549764738", +"3845612285742795068547496524855308821681721826554794539870518271238257264872"], +array!["8111729937113136682593516470591971173110681064547090000686075778488505769131", +"8396009887088699712099390488777898295472002649026341742255474271675851100167", +"7414449034416524223782013238252312102346828190465700203171291370882467344947"], +array!["3778308769422683143427677977866154704853508570989688082271648398982585170107", +"2565370813801956884760401215151019368813258954878221563399238313359761598300", +"7277843344904687178893605017520459777796065293383180828267621160222576167983"], +array!["6533305346353864830435743885484797433819452357103761181561861553139604158691", +"7023616807188225486961828699414844137821383541366139971758751915067616890468", +"6455936034448761051686329703810283225146169133435552271890713431685063292826"], +array!["2781819771186595572605878483518345975589831093852202671865373784050027047498", +"7768920898267371999735782676903681841500678447293607126814923973294043875457", +"6463549363657422809088424260159871142005366302883731565233242485772646214776"], +array!["4269033939844383336636476360431731618619965524039119758847937142713481376709", +"5618036788017776315188246458501777138795420885496187406031735668173200947333", +"1128431213282240763420656004648057492974288942591424362188971631793337713791"], +array!["6900739195883338461228609955335408882714240356250551921341894223851444718631", +"3771335365721990684607605930021444592509300370948450043449389607062564762590", +"4101659620264578558029808267598816776989279597141521237379858078563415422176"], +array!["7265965499850925058171553371274334440963706378337393611300731052328159723420", +"4766078774636290635629565607286497839044156826339894416138410680627572132174", +"6432220484581857509344049161489739648526811837695982886809250552529276108059"], +array!["6361365189519422980433504384140223138978192212838226387265114914908491362931", +"7610377774980016354219333532677870219839779550900332138169496134065793623856", +"363180943030113865942993953461474483659264066502549823448101062593623940092"], +array!["3562244767885763851343292605940116818317029725206904934994049890929589055395", +"7782549227482772885045540707357099585281118980712854335622177919009966444948", +"1275552603578693917501370061277948491143012995771911804618466157236333967239"], +array!["5104148721380689096094143534135757186465840305075873333902995773940524349076", +"3827555903928560008785730325772720209567461775844698712063218244346202837926", +"6537952092752701292661689328736100739363623229800800023575262375504637794811"], +array!["2625555787287768315537311869809801184270047957788564515280996906803464172085", +"2268046926631224821219360422346148209575446526490776085639666316914303207343", +"8301985790233975096406293902798523168400755923104779849614021896827941122062"], +array!["6186410907907226666421909877388154922245464592386712702411681535145025981542", +"1570197114753247526703806268420919303949793186535455032181860083077073573260", +"6433616921731463425493337442585921501113569311931762833956390491384184622184"], +array!["3730715929874541583946502538607860277000019933547155277889700636306045698678", +"4162712607911623590542516061947062496983700183068013598513127619182396118738", +"4885581468925689451043482261642022591161185334411569876922526171563347772487"], +array!["679010986662603253067780482929422410547319947222192616893132766589997651700", +"7045332371454775389874918027434858274122123892961682451412342124928285105115", +"796483939088841221822094384379289433804847199444006131260701274900329521826"], +array!["6930777873598706215302735286927888271122111082058406024378887982572264481712", +"3833261336312955683233981899122259611841384124139797023838966596495768744423", +"6081952172694136481884686958014712088378824178559544670607383857565862846284"], +array!["3816381396460078181431529965953560061945407168453302734314638292833792891390", +"56734387980297685686110088096585973744605712015961903089771968507489169889", +"1528381975769046861077120384272922840572114805411576866912148437940560430592"], +array!["4051427337822729290390706006634045761150954597129823553613464074823819976689", +"928801883926308717594921627141285880564599719525707838888160095066522021660", +"2575814441780474908465005749689528467553680700052052921662671958906858409792"], +array!["4188482005041843983756841875722811236284873807578170011114849822278345286775", +"2055640774204777367415844703991682482137697203553277498227758201416424138567", +"4575553062307433825409075011087260276527850105624870927391350382554634786094"], +array!["1854996916655462786356197865726500413712215270951193953965916926815164398288", +"4106990062567081635175461840146829007165341060131472749713325730182145598945", +"4440684113159162228103294475409844107272920293202271745070427054893404635089"]], +"mds" => array![array!["6093452032963406658309134825240609333033222270199073508119142384975416392638", +"5968273173562867837210008744966745230923761158428968101807573098840850097286", +"1100466639266852149977689148055725793531897994956807001704693611715839541982"], +array!["3160983601532844171864802850648492289862147997874094785600836495095965353712", +"2338351297827692414112631814274572996809824929139580588221558887342663769892", +"3177005087903404343485399282920555615020488967881372266904325860698809358885"], +array!["2285176219817854683696635383059984246218458246545520061123961933072089703485", +"84377861777946561525373172505381054389617879929776365352216307785104476701", +"8280884008678095605415834125731826663585461281789631237939546251146561093166"]], + "rate" => 2, "alpha"=> 17, "full_rounds" => 8, @@ -232,29 +145,33 @@ lazy_static! { } /// TODO -pub fn poseidon_params() -> PoseidonParameters { - let arks = P1["ark"] +pub fn poseidon_params() -> PoseidonParameters { + let arks = FR["ark"] .members() .map(|ark| { ark .members() - .map(|v| Fq::from_str(v.as_str().unwrap()).unwrap()) + .map(|v| Fr::from_str(v.as_str().unwrap()).unwrap()) .collect::>() }) .collect::>(); - let mds = P1["mds"] + let mds = FR["mds"] .members() .map(|m| { m.members() - .map(|v| Fq::from_str(v.as_str().unwrap()).unwrap()) + .map(|v| Fr::from_str(v.as_str().unwrap()).unwrap()) .collect::>() }) .collect::>(); PoseidonParameters::new( - P1["full_rounds"].as_u32().unwrap(), - P1["partial_rounds"].as_u32().unwrap(), - P1["alpha"].as_u64().unwrap(), + FR["full_rounds"].as_u32().unwrap(), + FR["partial_rounds"].as_u32().unwrap(), + FR["alpha"].as_u64().unwrap(), mds, arks, ) } + +lazy_static! { + pub static ref POSEIDON_PARAMETERS_FR_377: PoseidonParameters = poseidon_params(); +} diff --git a/src/poseidon_transcript.rs b/src/poseidon_transcript.rs new file mode 100644 index 0000000..666f2d9 --- /dev/null +++ b/src/poseidon_transcript.rs @@ -0,0 +1,75 @@ +use crate::group::{CompressedGroup, Fr}; + +use super::scalar::Scalar; + +// use ark_r1cs_std::prelude::*; +use ark_sponge::{ + constraints::CryptographicSpongeVar, + poseidon::{PoseidonParameters, PoseidonSponge}, + CryptographicSponge, +}; + +#[derive(Clone)] +/// TODO +pub struct PoseidonTranscript { + sponge: PoseidonSponge, + params: PoseidonParameters, +} + +impl PoseidonTranscript { + /// create a new transcript + pub fn new(params: &PoseidonParameters) -> Self { + let sponge = PoseidonSponge::new(params); + PoseidonTranscript { + sponge: sponge, + params: params.clone(), + } + } + + pub fn new_from_state(&mut self, challenge: &Scalar) { + self.sponge = PoseidonSponge::new(&self.params); + self.append_scalar(&challenge); + } + + pub fn append_u64(&mut self, x: u64) { + self.sponge.absorb(&x); + } + + pub fn append_bytes(&mut self, x: &Vec) { + self.sponge.absorb(x); + } + + pub fn append_scalar(&mut self, scalar: &Scalar) { + self.sponge.absorb(&scalar); + } + + pub fn append_point(&mut self, point: &CompressedGroup) { + self.sponge.absorb(&point.0); + } + + pub fn append_scalar_vector(&mut self, scalars: &Vec) { + for scalar in scalars.iter() { + self.append_scalar(&scalar); + } + } + + pub fn challenge_scalar(&mut self) -> Scalar { + let scalar = self.sponge.squeeze_field_elements(1).remove(0); + scalar + } + + pub fn challenge_vector(&mut self, len: usize) -> Vec { + let challenges = self.sponge.squeeze_field_elements(len); + challenges + } +} + +pub trait AppendToPoseidon { + fn append_to_poseidon(&self, transcript: &mut PoseidonTranscript); +} + +impl AppendToPoseidon for CompressedGroup { + fn append_to_poseidon(&self, transcript: &mut PoseidonTranscript) { + transcript.append_point(self); + } +} diff --git a/src/product_tree.rs b/src/product_tree.rs index 8e23102..0bb883e 100644 --- a/src/product_tree.rs +++ b/src/product_tree.rs @@ -9,7 +9,6 @@ use super::sumcheck::SumcheckInstanceProof; use super::transcript::ProofTranscript; use ark_serialize::*; use ark_std::One; -use merlin::Transcript; #[derive(Debug)] pub struct ProductCircuit { diff --git a/src/r1csinstance.rs b/src/r1csinstance.rs index aa95a2a..ac9191f 100644 --- a/src/r1csinstance.rs +++ b/src/r1csinstance.rs @@ -14,9 +14,13 @@ use super::timer::Timer; use ark_ff::Field; use ark_serialize::*; use ark_std::{One, UniformRand, Zero}; +use digest::{ExtendableOutput, Input}; + use merlin::Transcript; +use serde::Serialize; +use sha3::Shake256; -#[derive(Debug, CanonicalSerialize, CanonicalDeserialize)] +#[derive(Debug, CanonicalSerialize, CanonicalDeserialize, Clone)] pub struct R1CSInstance { num_cons: usize, num_vars: usize, @@ -159,7 +163,12 @@ impl R1CSInstance { pub fn get_digest(&self) -> Vec { let mut bytes = Vec::new(); self.serialize(&mut bytes).unwrap(); - bytes + let mut shake = Shake256::default(); + shake.input(bytes); + let mut reader = shake.xof_result(); + let mut buf = [0u8; 256]; + reader.read(&mut buf).unwrap(); + buf.to_vec() } pub fn produce_synthetic_r1cs( diff --git a/src/r1csproof.rs b/src/r1csproof.rs index e7a5267..bd60df1 100644 --- a/src/r1csproof.rs +++ b/src/r1csproof.rs @@ -1,29 +1,31 @@ #![allow(clippy::too_many_arguments)] -use crate::group::CompressedGroup; +use crate::constraints::{VerifierCircuit, VerifierConfig}; +use crate::group::{Fq, Fr}; +use crate::math::Math; +use crate::parameters::poseidon_params; +use crate::poseidon_transcript::PoseidonTranscript; use crate::sumcheck::SumcheckInstanceProof; -use super::commitments::{Commitments, MultiCommitGens}; -use super::dense_mlpoly::{ - DensePolynomial, EqPolynomial, PolyCommitment, PolyCommitmentGens, PolyEvalProof, -}; +use ark_bw6_761::BW6_761 as P; + +use super::commitments::MultiCommitGens; +use super::dense_mlpoly::{DensePolynomial, EqPolynomial, PolyCommitmentGens}; use super::errors::ProofVerifyError; -use super::group::{ - CompressGroupElement, DecompressGroupElement, GroupElement, VartimeMultiscalarMul, -}; -use super::math::Math; -use super::nizk::{EqualityProof, KnowledgeProof, ProductProof}; + use super::r1csinstance::R1CSInstance; -use super::random::RandomTape; + use super::scalar::Scalar; use super::sparse_mlpoly::{SparsePolyEntry, SparsePolynomial}; use super::timer::Timer; -use super::transcript::{AppendToTranscript, ProofTranscript}; -use ark_ec::ProjectiveCurve; -use ark_ff::PrimeField; +use super::transcript::ProofTranscript; +use ark_crypto_primitives::{CircuitSpecificSetupSNARK, SNARK}; + +use ark_groth16::Groth16; +use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem}; use ark_serialize::*; use ark_std::{One, Zero}; -use core::iter; -use merlin::Transcript; + +use std::time::Instant; #[derive(CanonicalSerialize, CanonicalDeserialize, Debug)] pub struct R1CSProof { @@ -36,7 +38,7 @@ pub struct R1CSProof { // proof_eval_vars_at_ry: PolyEvalProof, // proof_eq_sc_phase2: EqualityProof, } - +#[derive(Clone)] pub struct R1CSSumcheckGens { gens_1: MultiCommitGens, gens_3: MultiCommitGens, @@ -58,6 +60,7 @@ impl R1CSSumcheckGens { } } +#[derive(Clone)] pub struct R1CSGens { gens_sc: R1CSSumcheckGens, gens_pc: PolyCommitmentGens, @@ -126,14 +129,15 @@ impl R1CSProof { inst: &R1CSInstance, vars: Vec, input: &[Scalar], - gens: &R1CSGens, transcript: &mut PoseidonTranscript, - random_tape: &mut RandomTape, ) -> (R1CSProof, Vec, Vec) { let timer_prove = Timer::new("R1CSProof::prove"); // we currently require the number of |inputs| + 1 to be at most number of vars assert!(input.len() < vars.len()); + let c = transcript.challenge_scalar(); + transcript.new_from_state(&c); + transcript.append_scalar_vector(&input.to_vec()); let poly_vars = DensePolynomial::new(vars.clone()); @@ -152,8 +156,7 @@ impl R1CSProof { }; // derive the verifier's challenge tau - let (num_rounds_x, num_rounds_y) = - (inst.get_num_cons().log2() as usize, z.len().log2() as usize); + let (num_rounds_x, num_rounds_y) = (inst.get_num_cons().log_2(), z.len().log_2()); let tau = transcript.challenge_vector(num_rounds_x); // compute the initial evaluation table for R(\tau, x) let mut poly_tau = DensePolynomial::new(EqPolynomial::new(tau).evals()); @@ -180,7 +183,7 @@ impl R1CSProof { // prove the final step of sum-check #1 let taus_bound_rx = tau_claim; - let claim_post_phase1 = ((*Az_claim) * Bz_claim - Cz_claim) * taus_bound_rx; + let _claim_post_phase1 = ((*Az_claim) * Bz_claim - Cz_claim) * taus_bound_rx; let timer_sc_proof_phase2 = Timer::new("prove_sc_phase_two"); // combine the three claims into a single claim @@ -203,7 +206,7 @@ impl R1CSProof { }; // another instance of the sum-check protocol - let (sc_proof_phase2, ry, claims_phase2) = R1CSProof::prove_phase_two( + let (sc_proof_phase2, ry, _claims_phase2) = R1CSProof::prove_phase_two( num_rounds_y, &claim_phase2, &mut DensePolynomial::new(z), @@ -230,91 +233,134 @@ impl R1CSProof { ) } - pub fn verify( + pub fn verify_groth16( &self, num_vars: usize, num_cons: usize, input: &[Scalar], evals: &(Scalar, Scalar, Scalar), transcript: &mut PoseidonTranscript, - gens: &R1CSGens, - ) -> Result<(Vec, Vec), ProofVerifyError> { - // transcript.append_protocol_name(R1CSProof::protocol_name()); - - for i in 0..input.len() { - transcript.append_scalar(&input[i]); - } + ) -> Result<(u128, u128, u128), ProofVerifyError> { + let c = transcript.challenge_scalar(); + + let mut input_as_sparse_poly_entries = vec![SparsePolyEntry::new(0, Scalar::one())]; + //remaining inputs + input_as_sparse_poly_entries.extend( + (0..input.len()) + .map(|i| SparsePolyEntry::new(i + 1, input[i])) + .collect::>(), + ); let n = num_vars; + let input_as_sparse_poly = + SparsePolynomial::new(n.log_2() as usize, input_as_sparse_poly_entries); + + let config = VerifierConfig { + num_vars: num_vars, + num_cons: num_cons, + input: input.to_vec(), + evals: *evals, + params: poseidon_params(), + prev_challenge: c, + claims_phase2: self.claims_phase2, + polys_sc1: self.sc_proof_phase1.polys.clone(), + polys_sc2: self.sc_proof_phase2.polys.clone(), + eval_vars_at_ry: self.eval_vars_at_ry, + input_as_sparse_poly: input_as_sparse_poly, + }; - let (num_rounds_x, num_rounds_y) = (num_cons.log_2(), (2 * num_vars).log_2()); - - // derive the verifier's challenge tau - let tau = transcript.challenge_vector(num_rounds_x); - - // verify the first sum-check instance - let claim_phase1 = Scalar::zero(); - let (claim_post_phase1, rx) = - self - .sc_proof_phase1 - .verify(claim_phase1, num_rounds_x, 3, transcript)?; + let mut rng = ark_std::test_rng(); - // perform the intermediate sum-check test with claimed Az, Bz, and Cz - let (Az_claim, Bz_claim, Cz_claim, prod_Az_Bz_claims) = &self.claims_phase2; + let start = Instant::now(); + let circuit = VerifierCircuit::new(&config, &mut rng).unwrap(); + let dp1 = start.elapsed().as_millis(); - let taus_bound_rx: Scalar = (0..rx.len()) - .map(|i| rx[i] * tau[i] + (Scalar::one() - rx[i]) * (Scalar::one() - tau[i])) - .product(); + let start = Instant::now(); + let (pk, vk) = Groth16::

::setup(circuit.clone(), &mut rng).unwrap(); + let ds = start.elapsed().as_millis(); - let expected_claim_post_phase1 = (*prod_Az_Bz_claims - *Cz_claim) * (taus_bound_rx); + let start = Instant::now(); + let proof = Groth16::

::prove(&pk, circuit.clone(), &mut rng).unwrap(); + let dp2 = start.elapsed().as_millis(); - assert_eq!(claim_post_phase1, expected_claim_post_phase1); + let start = Instant::now(); + let is_verified = Groth16::

::verify(&vk, &[], &proof).unwrap(); + let dv = start.elapsed().as_millis(); + assert!(is_verified); - // derive three public challenges and then derive a joint claim - let r_A = transcript.challenge_scalar(); - let r_B = transcript.challenge_scalar(); - let r_C = transcript.challenge_scalar(); + Ok((ds, dp1 + dp2, dv)) + } - let claim_phase2 = r_A * Az_claim + r_B * Bz_claim + r_C * Cz_claim; + pub fn circuit_size( + &self, + num_vars: usize, + num_cons: usize, + input: &[Scalar], + evals: &(Scalar, Scalar, Scalar), + transcript: &mut PoseidonTranscript, + ) -> Result { + let c = transcript.challenge_scalar(); + + let mut input_as_sparse_poly_entries = vec![SparsePolyEntry::new(0, Scalar::one())]; + //remaining inputs + input_as_sparse_poly_entries.extend( + (0..input.len()) + .map(|i| SparsePolyEntry::new(i + 1, input[i])) + .collect::>(), + ); - // verify the joint claim with a sum-check protocol - let (claim_post_phase2, ry) = - self - .sc_proof_phase2 - .verify(claim_phase2, num_rounds_y, 2, transcript)?; - - let poly_input_eval = { - // constant term - let mut input_as_sparse_poly_entries = vec![SparsePolyEntry::new(0, Scalar::one())]; - //remaining inputs - input_as_sparse_poly_entries.extend( - (0..input.len()) - .map(|i| SparsePolyEntry::new(i + 1, input[i])) - .collect::>(), - ); - SparsePolynomial::new(n.log_2(), input_as_sparse_poly_entries).evaluate(&ry[1..]) + let n = num_vars; + let input_as_sparse_poly = + SparsePolynomial::new(n.log_2() as usize, input_as_sparse_poly_entries); + + let config = VerifierConfig { + num_vars: num_vars, + num_cons: num_cons, + input: input.to_vec(), + evals: *evals, + params: poseidon_params(), + prev_challenge: c, + claims_phase2: self.claims_phase2, + polys_sc1: self.sc_proof_phase1.polys.clone(), + polys_sc2: self.sc_proof_phase2.polys.clone(), + eval_vars_at_ry: self.eval_vars_at_ry, + input_as_sparse_poly: input_as_sparse_poly, }; - let eval_Z_at_ry = (Scalar::one() - ry[0]) * self.eval_vars_at_ry + ry[0] * poly_input_eval; + let mut rng = ark_std::test_rng(); + let circuit = VerifierCircuit::new(&config, &mut rng).unwrap(); - // perform the final check in the second sum-check protocol - let (eval_A_r, eval_B_r, eval_C_r) = evals; - let scalar = r_A * eval_A_r + r_B * eval_B_r + r_C * eval_C_r; - let expected_claim_post_phase2 = eval_Z_at_ry * scalar; + let nc_inner = verify_constraints_inner(circuit.clone(), &num_cons); - assert_eq!(expected_claim_post_phase2, claim_post_phase2); - - Ok((rx, ry)) + let nc_outer = verify_constraints_outer(circuit.clone(), &num_cons); + Ok(nc_inner + nc_outer) } } +fn verify_constraints_outer(circuit: VerifierCircuit, _num_cons: &usize) -> usize { + let cs = ConstraintSystem::::new_ref(); + circuit.generate_constraints(cs.clone()).unwrap(); + assert!(cs.is_satisfied().unwrap()); + cs.num_constraints() +} + +fn verify_constraints_inner(circuit: VerifierCircuit, _num_cons: &usize) -> usize { + let cs = ConstraintSystem::::new_ref(); + circuit + .inner_circuit + .generate_constraints(cs.clone()) + .unwrap(); + assert!(cs.is_satisfied().unwrap()); + cs.num_constraints() +} + #[cfg(test)] mod tests { use crate::parameters::poseidon_params; use super::*; + use ark_std::UniformRand; - use test::Bencher; fn produce_tiny_r1cs() -> (R1CSInstance, Vec, Vec) { // three constraints over five variables Z1, Z2, Z3, Z4, and Z5 @@ -394,39 +440,29 @@ mod tests { let num_inputs = 10; let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs); - let gens = R1CSGens::new(b"test-m", num_cons, num_vars); + // let gens = R1CSGens::new(b"test-m", num_cons, num_vars); let params = poseidon_params(); - let mut random_tape = RandomTape::new(b"proof"); - // let mut prover_transcript = PoseidonTranscript::new(¶ms); + // let mut random_tape = RandomTape::new(b"proof"); + let mut prover_transcript = PoseidonTranscript::new(¶ms); - let (proof, rx, ry) = R1CSProof::prove( - &inst, - vars, - &input, - &gens, - &mut prover_transcript, - &mut random_tape, - ); + let (proof, rx, ry) = R1CSProof::prove(&inst, vars, &input, &mut prover_transcript); let inst_evals = inst.evaluate(&rx, &ry); - // let mut verifier_transcript = PoseidonTranscript::new(¶ms); let mut verifier_transcript = PoseidonTranscript::new(¶ms); + + // if you want to check the test fails + // input[0] = Scalar::zero(); + assert!(proof - .verify( + .verify_groth16( inst.get_num_vars(), inst.get_num_cons(), &input, &inst_evals, &mut verifier_transcript, - &gens, ) .is_ok()); } - - #[bench] - fn bench_r1cs_proof(b: &mut Bencher) { - b.iter(|| check_r1cs_proof()); - } } diff --git a/src/random.rs b/src/random.rs index 4337f27..56793f7 100644 --- a/src/random.rs +++ b/src/random.rs @@ -1,7 +1,7 @@ use super::scalar::Scalar; use super::transcript::ProofTranscript; +use ark_std::UniformRand; use merlin::Transcript; -use ark_std::{UniformRand}; pub struct RandomTape { tape: Transcript, @@ -10,7 +10,7 @@ pub struct RandomTape { impl RandomTape { pub fn new(name: &'static [u8]) -> Self { let tape = { - let mut rng = ark_std::rand::thread_rng(); + let mut rng = ark_std::rand::thread_rng(); let mut tape = Transcript::new(name); tape.append_scalar(b"init_randomness", &Scalar::rand(&mut rng)); tape diff --git a/src/sparse_mlpoly.rs b/src/sparse_mlpoly.rs index de23cdb..1ec511a 100644 --- a/src/sparse_mlpoly.rs +++ b/src/sparse_mlpoly.rs @@ -18,8 +18,9 @@ use ark_ff::{Field, One, Zero}; use ark_serialize::*; use core::cmp::Ordering; use merlin::Transcript; +use serde::Serialize; -#[derive(Debug, CanonicalSerialize, CanonicalDeserialize)] +#[derive(Debug, CanonicalSerialize, CanonicalDeserialize, Clone)] pub struct SparseMatEntry { row: usize, col: usize, @@ -32,7 +33,7 @@ impl SparseMatEntry { } } -#[derive(Debug, CanonicalSerialize, CanonicalDeserialize)] +#[derive(Debug, CanonicalSerialize, CanonicalDeserialize, Clone)] pub struct SparseMatPolynomial { num_vars_x: usize, num_vars_y: usize, @@ -100,7 +101,7 @@ impl DerefsEvalProof { // n-to-1 reduction let (r_joint, eval_joint) = { - let challenges = transcript.challenge_vector(evals.len().log2()); + let challenges = transcript.challenge_vector(evals.len().log_2()); let mut poly_evals = DensePolynomial::new(evals); for i in (0..challenges.len()).rev() { poly_evals.bound_poly_var_bot(&challenges[i]); @@ -166,7 +167,7 @@ impl DerefsEvalProof { transcript.append_scalar_vector(&evals); // n-to-1 reduction - let challenges = transcript.challenge_vector(evals.len().log2()); + let challenges = transcript.challenge_vector(evals.len().log_2()); let mut poly_evals = DensePolynomial::new(evals); for i in (0..challenges.len()).rev() { poly_evals.bound_poly_var_bot(&challenges[i]); @@ -794,7 +795,7 @@ impl HashLayerProof { evals_ops.extend(&eval_val_vec); evals_ops.resize(evals_ops.len().next_power_of_two(), Scalar::zero()); transcript.append_scalar_vector(&evals_ops); - let challenges_ops = transcript.challenge_vector(evals_ops.len().log2()); + let challenges_ops = transcript.challenge_vector(evals_ops.len().log_2()); let mut poly_evals_ops = DensePolynomial::new(evals_ops); for i in (0..challenges_ops.len()).rev() { @@ -821,7 +822,7 @@ impl HashLayerProof { let evals_mem: Vec = vec![eval_row_audit_ts, eval_col_audit_ts]; // evals_mem.append_to_transcript(b"claim_evals_mem", transcript); transcript.append_scalar_vector(&evals_mem); - let challenges_mem = transcript.challenge_vector(evals_mem.len().log2()); + let challenges_mem = transcript.challenge_vector(evals_mem.len().log_2()); let mut poly_evals_mem = DensePolynomial::new(evals_mem); for i in (0..challenges_mem.len()).rev() { @@ -964,7 +965,7 @@ impl HashLayerProof { evals_ops.resize(evals_ops.len().next_power_of_two(), Scalar::zero()); transcript.append_scalar_vector(&evals_ops); // evals_ops.append_to_transcript(b"claim_evals_ops", transcript); - let challenges_ops = transcript.challenge_vector(evals_ops.len().log2()); + let challenges_ops = transcript.challenge_vector(evals_ops.len().log_2()); let mut poly_evals_ops = DensePolynomial::new(evals_ops); for i in (0..challenges_ops.len()).rev() { @@ -991,7 +992,7 @@ impl HashLayerProof { let evals_mem: Vec = vec![*eval_row_audit_ts, *eval_col_audit_ts]; // evals_mem.append_to_transcript(b"claim_evals_mem", transcript); transcript.append_scalar_vector(&evals_mem); - let challenges_mem = transcript.challenge_vector(evals_mem.len().log2()); + let challenges_mem = transcript.challenge_vector(evals_mem.len().log_2()); let mut poly_evals_mem = DensePolynomial::new(evals_mem); for i in (0..challenges_mem.len()).rev() { @@ -1596,9 +1597,10 @@ impl SparseMatPolyEvalProof { } } +#[derive(Clone)] pub struct SparsePolyEntry { - idx: usize, - val: Scalar, + pub idx: usize, + pub val: Scalar, } impl SparsePolyEntry { @@ -1606,10 +1608,10 @@ impl SparsePolyEntry { SparsePolyEntry { idx, val } } } - +#[derive(Clone)] pub struct SparsePolynomial { - num_vars: usize, - Z: Vec, + pub num_vars: usize, + pub Z: Vec, } impl SparsePolynomial { @@ -1617,6 +1619,8 @@ impl SparsePolynomial { SparsePolynomial { num_vars, Z } } + // TF IS THIS?? + fn compute_chi(a: &[bool], r: &[Scalar]) -> Scalar { assert_eq!(a.len(), r.len()); let mut chi_i = Scalar::one(); @@ -1637,6 +1641,7 @@ impl SparsePolynomial { (0..self.Z.len()) .map(|i| { let bits = self.Z[i].idx.get_bits(r.len()); + println!("{:?}", bits); SparsePolynomial::compute_chi(&bits, r) * self.Z[i].val }) .sum() @@ -1645,7 +1650,7 @@ impl SparsePolynomial { #[cfg(test)] mod tests { - use crate::{commitments::MultiCommitGens, parameters::poseidon_params}; + use crate::parameters::poseidon_params; use super::*; use ark_std::UniformRand; diff --git a/src/sumcheck.rs b/src/sumcheck.rs index 1c5aee4..f6069dd 100644 --- a/src/sumcheck.rs +++ b/src/sumcheck.rs @@ -2,32 +2,26 @@ #![allow(clippy::type_complexity)] use crate::poseidon_transcript::{AppendToPoseidon, PoseidonTranscript}; -use super::commitments::{Commitments, MultiCommitGens}; use super::dense_mlpoly::DensePolynomial; use super::errors::ProofVerifyError; -use super::group::{ - CompressGroupElement, CompressedGroup, DecompressGroupElement, GroupElement, - VartimeMultiscalarMul, -}; -use super::nizk::DotProductProof; -use super::random::RandomTape; + use super::scalar::Scalar; -use super::transcript::{AppendToTranscript, ProofTranscript}; -use super::unipoly::{CompressedUniPoly, UniPoly}; -use ark_ff::{One, Zero}; +use super::transcript::ProofTranscript; +use super::unipoly::UniPoly; + +use ark_ff::Zero; use ark_serialize::*; -use core::iter; + use itertools::izip; -use merlin::Transcript; #[derive(CanonicalSerialize, CanonicalDeserialize, Debug)] pub struct SumcheckInstanceProof { - compressed_polys: Vec, + pub polys: Vec, } impl SumcheckInstanceProof { - pub fn new(compressed_polys: Vec) -> SumcheckInstanceProof { - SumcheckInstanceProof { compressed_polys } + pub fn new(polys: Vec) -> SumcheckInstanceProof { + SumcheckInstanceProof { polys } } pub fn verify( @@ -41,14 +35,14 @@ impl SumcheckInstanceProof { let mut r: Vec = Vec::new(); // verify that there is a univariate polynomial for each round - assert_eq!(self.compressed_polys.len(), num_rounds); - for i in 0..self.compressed_polys.len() { - let poly = self.compressed_polys[i].decompress(&e); + assert_eq!(self.polys.len(), num_rounds); + for i in 0..self.polys.len() { + let poly = self.polys[i].clone(); // verify degree bound assert_eq!(poly.degree(), degree_bound); - // check if G_k(0) + G_k(1) = e + assert_eq!(poly.eval_at_zero() + poly.eval_at_one(), e); // append the prover's message to the transcript @@ -202,8 +196,8 @@ impl SumcheckInstanceProof { { let mut e = *claim; let mut r: Vec = Vec::new(); - let mut cubic_polys: Vec = Vec::new(); - for j in 0..num_rounds { + let mut cubic_polys: Vec = Vec::new(); + for _j in 0..num_rounds { let mut eval_point_0 = Scalar::zero(); let mut eval_point_2 = Scalar::zero(); let mut eval_point_3 = Scalar::zero(); @@ -256,7 +250,7 @@ impl SumcheckInstanceProof { poly_C.bound_poly_var_top(&r_j); e = poly.evaluate(&r_j); - cubic_polys.push(poly.compress()); + cubic_polys.push(poly); } ( SumcheckInstanceProof::new(cubic_polys), @@ -278,7 +272,7 @@ impl SumcheckInstanceProof { { let mut e = *claim; let mut r: Vec = Vec::new(); - let mut cubic_polys: Vec = Vec::new(); + let mut cubic_polys: Vec = Vec::new(); for _j in 0..num_rounds { let mut eval_point_0 = Scalar::zero(); let mut eval_point_2 = Scalar::zero(); @@ -325,7 +319,7 @@ impl SumcheckInstanceProof { poly_B.bound_poly_var_top(&r_j); poly_C.bound_poly_var_top(&r_j); e = poly.evaluate(&r_j); - cubic_polys.push(poly.compress()); + cubic_polys.push(poly); } ( @@ -366,7 +360,7 @@ impl SumcheckInstanceProof { //let (poly_A_vec_seq, poly_B_vec_seq, poly_C_vec_seq) = poly_vec_seq; let mut e = *claim; let mut r: Vec = Vec::new(); - let mut cubic_polys: Vec = Vec::new(); + let mut cubic_polys: Vec = Vec::new(); for _j in 0..num_rounds { let mut evals: Vec<(Scalar, Scalar, Scalar)> = Vec::new(); @@ -477,7 +471,7 @@ impl SumcheckInstanceProof { } e = poly.evaluate(&r_j); - cubic_polys.push(poly.compress()); + cubic_polys.push(poly); } let poly_A_par_final = (0..poly_A_vec_par.len()) @@ -520,9 +514,9 @@ impl SumcheckInstanceProof { { let mut e = *claim; let mut r: Vec = Vec::new(); - let mut quad_polys: Vec = Vec::new(); + let mut quad_polys: Vec = Vec::new(); - for j in 0..num_rounds { + for _j in 0..num_rounds { let mut eval_point_0 = Scalar::zero(); let mut eval_point_2 = Scalar::zero(); @@ -551,7 +545,7 @@ impl SumcheckInstanceProof { poly_A.bound_poly_var_top(&r_j); poly_B.bound_poly_var_top(&r_j); e = poly.evaluate(&r_j); - quad_polys.push(poly.compress()); + quad_polys.push(poly); } ( @@ -586,7 +580,7 @@ impl SumcheckInstanceProof { // let mut comm_claim_per_round = claim_per_round.commit(blind_claim, gens_1).compress(); // let mut r: Vec = Vec::new(); -// let mut comm_polys: Vec = Vec::new(); +// let mut comm_polys: Vec = Vec::new(); // let mut comm_evals: Vec = Vec::new(); // let mut proofs: Vec = Vec::new(); diff --git a/src/transcript.rs b/src/transcript.rs index 359ff11..29eabcc 100644 --- a/src/transcript.rs +++ b/src/transcript.rs @@ -1,8 +1,8 @@ -use crate::group::CompressedGroup; use super::scalar::Scalar; +use crate::group::CompressedGroup; +use ark_ff::{BigInteger, PrimeField}; +use ark_serialize::CanonicalSerialize; use merlin::Transcript; -use ark_ff::{PrimeField, BigInteger}; -use ark_serialize::{CanonicalSerialize}; pub trait ProofTranscript { fn append_protocol_name(&mut self, protocol_name: &'static [u8]); diff --git a/src/unipoly.rs b/src/unipoly.rs index 469727b..d97b189 100644 --- a/src/unipoly.rs +++ b/src/unipoly.rs @@ -4,21 +4,22 @@ use super::commitments::{Commitments, MultiCommitGens}; use super::group::GroupElement; use super::scalar::Scalar; use super::transcript::{AppendToTranscript, ProofTranscript}; -use ark_ff::{Field, One, Zero}; +use ark_ff::Field; use ark_serialize::*; use merlin::Transcript; // ax^2 + bx + c stored as vec![c,b,a] // ax^3 + bx^2 + cx + d stored as vec![d,c,b,a] -#[derive(Debug)] +#[derive(Debug, CanonicalDeserialize, CanonicalSerialize, Clone)] pub struct UniPoly { - coeffs: Vec, + pub coeffs: Vec, + // pub coeffs_fq: Vec, } // ax^2 + bx + c stored as vec![c,a] // ax^3 + bx^2 + cx + d stored as vec![d,b,a] #[derive(CanonicalSerialize, CanonicalDeserialize, Debug)] pub struct CompressedUniPoly { - coeffs_except_linear_term: Vec, + pub coeffs_except_linear_term: Vec, } impl UniPoly { @@ -134,6 +135,8 @@ impl AppendToTranscript for UniPoly { #[cfg(test)] mod tests { + use ark_ff::One; + use super::*; #[test]