limit public APIs
This commit is contained in:
Srinath Setty
2020-04-28 13:36:54 -07:00
parent 290bbc0897
commit eb969d5dcf
17 changed files with 314 additions and 1091 deletions

View File

@@ -115,41 +115,6 @@ impl EqPolynomial {
}
}
pub struct ConstPolynomial {
num_vars: usize,
c: Scalar,
}
impl ConstPolynomial {
pub fn new(num_vars: usize, c: Scalar) -> Self {
ConstPolynomial { num_vars, c }
}
pub fn evaluate(&self, rx: &Vec<Scalar>) -> Scalar {
assert_eq!(self.num_vars, rx.len());
self.c
}
pub fn get_num_vars(&self) -> usize {
self.num_vars
}
/// produces a binding commitment
pub fn commit(&self, gens: &PolyCommitmentGens) -> PolyCommitment {
let ell = self.get_num_vars();
let (left_num_vars, right_num_vars) = EqPolynomial::compute_factored_lens(ell);
let L_size = left_num_vars.pow2();
let R_size = right_num_vars.pow2();
assert_eq!(L_size * R_size, ell.pow2());
let vec = vec![self.c; R_size];
let c = vec.commit(&Scalar::zero(), &gens.gens.gens_n).compress();
PolyCommitment { C: vec![c; L_size] }
}
}
pub struct IdentityPolynomial {
size_point: usize,
}
@@ -456,48 +421,6 @@ impl PolyEvalProof {
.verify(R.len(), &gens.gens, transcript, &R, &C_LZ, C_Zr)
}
pub fn verify_batched(
&self,
gens: &PolyCommitmentGens,
transcript: &mut Transcript,
r: &Vec<Scalar>, // point at which the polynomial is evaluated
C_Zr: &CompressedGroup, // commitment to \widetilde{Z}(r)
comm: &[&PolyCommitment],
coeff: &[&Scalar],
) -> Result<(), ProofVerifyError> {
transcript.append_protocol_name(PolyEvalProof::protocol_name());
// compute L and R
let eq = EqPolynomial::new(r.to_vec());
let (L, R) = eq.compute_factored_evals();
// compute a weighted sum of commitments and L
let C_decompressed: Vec<Vec<GroupElement>> = (0..comm.len())
.map(|i| {
comm[i]
.C
.iter()
.map(|pt| pt.decompress().unwrap())
.collect()
})
.collect();
let C_LZ: Vec<GroupElement> = (0..comm.len())
.map(|i| GroupElement::vartime_multiscalar_mul(&L, &C_decompressed[i]))
.collect();
let C_LZ_combined: GroupElement = (0..C_LZ.len()).map(|i| C_LZ[i] * coeff[i]).sum();
self.proof.verify(
R.len(),
&gens.gens,
transcript,
&R,
&C_LZ_combined.compress(),
C_Zr,
)
}
pub fn verify_plain(
&self,
gens: &PolyCommitmentGens,
@@ -511,23 +434,6 @@ impl PolyEvalProof {
self.verify(gens, transcript, r, &C_Zr, comm)
}
pub fn verify_plain_batched(
&self,
gens: &PolyCommitmentGens,
transcript: &mut Transcript,
r: &Vec<Scalar>, // point at which the polynomial is evaluated
Zr: &Scalar, // evaluation \widetilde{Z}(r)
comm: &[&PolyCommitment],
coeff: &[&Scalar],
) -> Result<(), ProofVerifyError> {
// compute a commitment to Zr with a blind of zero
let C_Zr = Zr.commit(&Scalar::zero(), &gens.gens.gens_1).compress();
assert_eq!(comm.len(), coeff.len());
self.verify_batched(gens, transcript, r, &C_Zr, comm, coeff)
}
}
#[cfg(test)]

View File

@@ -11,20 +11,20 @@ extern crate rayon;
extern crate sha3;
extern crate test;
pub mod commitments;
pub mod dense_mlpoly;
mod commitments;
mod dense_mlpoly;
mod errors;
mod group;
pub mod math;
pub mod nizk;
mod math;
mod nizk;
mod product_tree;
pub mod r1csinstance;
pub mod r1csproof;
pub mod random;
pub mod scalar;
pub mod sparse_mlpoly;
mod r1csproof;
mod random;
mod scalar;
mod sparse_mlpoly;
pub mod spartan;
pub mod sumcheck;
mod sumcheck;
pub mod timer;
pub mod transcript;
mod transcript;
mod unipoly;

View File

@@ -1,96 +0,0 @@
#![allow(non_snake_case)]
extern crate flate2;
extern crate libspartan;
extern crate merlin;
extern crate rand;
use flate2::{write::ZlibEncoder, Compression};
use libspartan::math::Math;
use libspartan::r1csinstance::{R1CSCommitmentGens, R1CSInstance};
use libspartan::r1csproof::R1CSGens;
use libspartan::spartan::{NIZKGens, SNARKGens, NIZK, SNARK};
use libspartan::timer::Timer;
use merlin::Transcript;
pub fn main() {
// the list of number of variables (and constraints) in an R1CS instance
let inst_sizes = vec![12, 16, 20];
println!("Profiler:: SNARK");
for &s in inst_sizes.iter() {
let num_vars = (s as usize).pow2();
let num_cons = num_vars;
let num_inputs = 10;
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
Timer::print(&format!("number_of_constraints {}", num_cons));
let r1cs_size = inst.size();
let gens_r1cs_eval = R1CSCommitmentGens::new(&r1cs_size, b"gens_r1cs_eval");
// create a commitment to R1CSInstance
let timer_encode = Timer::new("SNARK::encode");
let (comm, decomm) = SNARK::encode(&inst, &gens_r1cs_eval);
timer_encode.stop();
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
let gens = SNARKGens::new(gens_r1cs_sat, gens_r1cs_eval);
// produce a proof of satisfiability
let timer_prove = Timer::new("SNARK::prove");
let mut prover_transcript = Transcript::new(b"example");
let proof = SNARK::prove(&inst, &decomm, vars, &input, &gens, &mut prover_transcript);
timer_prove.stop();
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
bincode::serialize_into(&mut encoder, &proof).unwrap();
let proof_encoded = encoder.finish().unwrap();
let msg_proof_len = format!("SNARK::proof_compressed_len {:?}", proof_encoded.len());
Timer::print(&msg_proof_len);
// verify the proof of satisfiability
let timer_verify = Timer::new("SNARK::verify");
let mut verifier_transcript = Transcript::new(b"example");
assert!(proof
.verify(&comm, &input, &mut verifier_transcript, &gens)
.is_ok());
timer_verify.stop();
println!();
}
println!("Profiler:: NIZK");
for &s in inst_sizes.iter() {
let num_vars = (s as usize).pow2();
let num_cons = num_vars;
let num_inputs = 10;
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
Timer::print(&format!("number_of_constraints {}", num_cons));
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
let gens = NIZKGens::new(gens_r1cs_sat);
// produce a proof of satisfiability
let timer_prove = Timer::new("NIZK::prove");
let mut prover_transcript = Transcript::new(b"example");
let proof = NIZK::prove(&inst, vars, &input, &gens, &mut prover_transcript);
timer_prove.stop();
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
bincode::serialize_into(&mut encoder, &proof).unwrap();
let proof_encoded = encoder.finish().unwrap();
let msg_proof_len = format!("NIZK::proof_compressed_len {:?}", proof_encoded.len());
Timer::print(&msg_proof_len);
// verify the proof of satisfiability
let timer_verify = Timer::new("NIZK::verify");
let mut verifier_transcript = Transcript::new(b"example");
assert!(proof
.verify(&inst, &input, &mut verifier_transcript, &gens)
.is_ok());
timer_verify.stop();
println!();
}
}

View File

@@ -25,11 +25,28 @@ pub struct R1CSInstance {
}
pub struct R1CSInstanceSize {
num_cons: usize,
num_vars: usize,
num_inputs: usize,
size_A: SparseMatPolynomialSize,
size_B: SparseMatPolynomialSize,
size_C: SparseMatPolynomialSize,
}
impl R1CSInstanceSize {
pub fn get_num_cons(&self) -> usize {
self.num_cons
}
pub fn get_num_vars(&self) -> usize {
self.num_vars
}
pub fn get_num_inputs(&self) -> usize {
self.num_inputs
}
}
pub struct R1CSCommitmentGens {
gens: SparseMatPolyCommitmentGens,
}
@@ -124,6 +141,9 @@ impl R1CSInstance {
pub fn size(&self) -> R1CSInstanceSize {
R1CSInstanceSize {
num_cons: self.num_cons,
num_vars: self.num_vars,
num_inputs: self.num_inputs,
size_A: self.A.size(),
size_B: self.B.size(),
size_C: self.C.size(),

View File

@@ -2,7 +2,7 @@ use super::dense_mlpoly::EqPolynomial;
use super::errors::ProofVerifyError;
use super::r1csinstance::{
R1CSCommitment, R1CSCommitmentGens, R1CSDecommitment, R1CSEvalProof, R1CSInstance,
R1CSInstanceEvals,
R1CSInstanceEvals, R1CSInstanceSize,
};
use super::r1csproof::{R1CSGens, R1CSProof};
use super::random::RandomTape;
@@ -18,7 +18,9 @@ pub struct SNARKGens {
}
impl SNARKGens {
pub fn new(gens_r1cs_sat: R1CSGens, gens_r1cs_eval: R1CSCommitmentGens) -> Self {
pub fn new(size: &R1CSInstanceSize) -> Self {
let gens_r1cs_sat = R1CSGens::new(size.get_num_cons(), size.get_num_vars(), b"gens_r1cs_sat");
let gens_r1cs_eval = R1CSCommitmentGens::new(size, b"gens_r1cs_eval");
SNARKGens {
gens_r1cs_sat,
gens_r1cs_eval,
@@ -39,11 +41,8 @@ impl SNARK {
}
/// A public computation to create a commitment to an R1CS instance
pub fn encode(
inst: &R1CSInstance,
gens: &R1CSCommitmentGens,
) -> (R1CSCommitment, R1CSDecommitment) {
inst.commit(gens)
pub fn encode(inst: &R1CSInstance, gens: &SNARKGens) -> (R1CSCommitment, R1CSDecommitment) {
inst.commit(&gens.gens_r1cs_eval)
}
/// A method to produce a proof of the satisfiability of an R1CS instance
@@ -158,7 +157,8 @@ pub struct NIZKGens {
}
impl NIZKGens {
pub fn new(gens_r1cs_sat: R1CSGens) -> Self {
pub fn new(num_cons: usize, num_vars: usize) -> Self {
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
NIZKGens { gens_r1cs_sat }
}
}
@@ -261,19 +261,19 @@ mod tests {
let num_cons = num_vars;
let num_inputs = 10;
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
let r1cs_size = inst.size();
let gens_r1cs_eval = R1CSCommitmentGens::new(&r1cs_size, b"gens_r1cs_eval");
// produce public generators
let gens = SNARKGens::new(&r1cs_size);
// create a commitment to R1CSInstance
let (comm, decomm) = SNARK::encode(&inst, &gens_r1cs_eval);
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
let gens = SNARKGens::new(gens_r1cs_sat, gens_r1cs_eval);
let (comm, decomm) = SNARK::encode(&inst, &gens);
// produce a proof
let mut prover_transcript = Transcript::new(b"example");
let proof = SNARK::prove(&inst, &decomm, vars, &input, &gens, &mut prover_transcript);
// verify the proof
let mut verifier_transcript = Transcript::new(b"example");
assert!(proof
.verify(&comm, &input, &mut verifier_transcript, &gens)

View File

@@ -176,59 +176,6 @@ impl ZKSumcheckInstanceProof {
}
impl SumcheckInstanceProof {
pub fn prove_quad<F>(
claim: &Scalar,
num_rounds: usize,
poly_A: &mut DensePolynomial,
poly_B: &mut DensePolynomial,
comb_func: F,
transcript: &mut Transcript,
) -> (Self, Vec<Scalar>, Vec<Scalar>)
where
F: Fn(&Scalar, &Scalar) -> Scalar,
{
let mut e = *claim;
let mut r: Vec<Scalar> = Vec::new();
let mut quad_polys: Vec<CompressedUniPoly> = Vec::new();
for _j in 0..num_rounds {
let mut eval_point_0 = Scalar::zero();
let mut eval_point_2 = Scalar::zero();
let len = poly_A.len() / 2;
for i in 0..len {
// eval 0: bound_func is A(low)
eval_point_0 = &eval_point_0 + comb_func(&poly_A[i], &poly_B[i]);
// eval 2: bound_func is -A(low) + 2*A(high)
let poly_A_bound_point = &poly_A[len + i] + &poly_A[len + i] - &poly_A[i];
let poly_B_bound_point = &poly_B[len + i] + &poly_B[len + i] - &poly_B[i];
eval_point_2 = &eval_point_2 + comb_func(&poly_A_bound_point, &poly_B_bound_point);
}
let evals = vec![eval_point_0, e - eval_point_0, eval_point_2];
let poly = UniPoly::from_evals(&evals);
// append the prover's message to the transcript
poly.append_to_transcript(b"poly", transcript);
//derive the verifier's challenge for the next round
let r_j = transcript.challenge_scalar(b"challenge_nextround");
r.push(r_j);
// bound all tables to the verifier's challenege
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());
}
(
SumcheckInstanceProof::new(quad_polys),
r,
vec![poly_A[0], poly_B[0]],
)
}
pub fn prove_cubic<F>(
claim: &Scalar,
num_rounds: usize,
@@ -302,84 +249,6 @@ impl SumcheckInstanceProof {
)
}
pub fn prove_cubic_with_additive_term<F>(
claim: &Scalar,
num_rounds: usize,
poly_A: &mut DensePolynomial,
poly_B: &mut DensePolynomial,
poly_C: &mut DensePolynomial,
poly_D: &mut DensePolynomial,
comb_func: F,
transcript: &mut Transcript,
) -> (Self, Vec<Scalar>, Vec<Scalar>)
where
F: Fn(&Scalar, &Scalar, &Scalar, &Scalar) -> Scalar,
{
let mut e = *claim;
let mut r: Vec<Scalar> = Vec::new();
let mut cubic_polys: Vec<CompressedUniPoly> = 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();
let len = poly_A.len() / 2;
for i in 0..len {
// eval 0: bound_func is A(low)
eval_point_0 = &eval_point_0 + comb_func(&poly_A[i], &poly_B[i], &poly_C[i], &poly_D[i]);
// eval 2: bound_func is -A(low) + 2*A(high)
let poly_A_bound_point = &poly_A[len + i] + &poly_A[len + i] - &poly_A[i];
let poly_B_bound_point = &poly_B[len + i] + &poly_B[len + i] - &poly_B[i];
let poly_C_bound_point = &poly_C[len + i] + &poly_C[len + i] - &poly_C[i];
let poly_D_bound_point = &poly_D[len + i] + &poly_D[len + i] - &poly_D[i];
eval_point_2 = &eval_point_2
+ comb_func(
&poly_A_bound_point,
&poly_B_bound_point,
&poly_C_bound_point,
&poly_D_bound_point,
);
// eval 3: bound_func is -2A(low) + 3A(high); computed incrementally with bound_func applied to eval(2)
let poly_A_bound_point = &poly_A_bound_point + &poly_A[len + i] - &poly_A[i];
let poly_B_bound_point = &poly_B_bound_point + &poly_B[len + i] - &poly_B[i];
let poly_C_bound_point = &poly_C_bound_point + &poly_C[len + i] - &poly_C[i];
let poly_D_bound_point = &poly_D_bound_point + &poly_D[len + i] - &poly_D[i];
eval_point_3 = &eval_point_3
+ comb_func(
&poly_A_bound_point,
&poly_B_bound_point,
&poly_C_bound_point,
&poly_D_bound_point,
);
}
let evals = vec![eval_point_0, e - eval_point_0, eval_point_2, eval_point_3];
let poly = UniPoly::from_evals(&evals);
// append the prover's message to the transcript
poly.append_to_transcript(b"poly", transcript);
//derive the verifier's challenge for the next round
let r_j = transcript.challenge_scalar(b"challenge_nextround");
r.push(r_j);
// bound all tables to the verifier's challenege
poly_A.bound_poly_var_top(&r_j);
poly_B.bound_poly_var_top(&r_j);
poly_C.bound_poly_var_top(&r_j);
poly_D.bound_poly_var_top(&r_j);
e = poly.evaluate(&r_j);
cubic_polys.push(poly.compress());
}
(
SumcheckInstanceProof::new(cubic_polys),
r,
vec![poly_A[0], poly_B[0], poly_C[0], poly_D[0]],
)
}
pub fn prove_cubic_batched<F>(
claim: &Scalar,
num_rounds: usize,