Skip to content

Commit

Permalink
Adapt proving methods onto SumcheckInstanceProof. Remove ZK proof str…
Browse files Browse the repository at this point in the history
…uct.
  • Loading branch information
darth-cy committed Dec 5, 2024
1 parent acbc979 commit 4b160ca
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 183 deletions.
6 changes: 3 additions & 3 deletions spartan_parallel/src/dense_mlpoly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use crate::scalar::SpartanExtensionField;

use super::errors::ProofVerifyError;
use super::math::Math;
use super::nizk::DotProductProofLog;
use super::random::RandomTape;
use super::transcript::ProofTranscript;
use super::unipoly::CompressedUniPoly;
use core::ops::Index;
use merlin::Transcript;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -309,9 +309,9 @@ impl<S: SpartanExtensionField> Index<usize> for DensePolynomial<S> {
}
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize)]
pub struct PolyEvalProof<S: SpartanExtensionField> {
proof: DotProductProofLog<S>,
polys: Vec<CompressedUniPoly<S>>,
}

impl<S: SpartanExtensionField> PolyEvalProof<S> {
Expand Down
16 changes: 7 additions & 9 deletions spartan_parallel/src/r1csproof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ use super::custom_dense_mlpoly::DensePolynomialPqx;
use super::dense_mlpoly::{DensePolynomial, EqPolynomial, PolyEvalProof};
use super::errors::ProofVerifyError;
use super::math::Math;
use super::nizk::{EqualityProof, KnowledgeProof, ProductProof};
use super::r1csinstance::R1CSInstance;
use super::random::RandomTape;
use super::sumcheck::R1CSSumcheckInstanceProof;
use super::sumcheck::SumcheckInstanceProof;
use super::timer::Timer;
use super::transcript::ProofTranscript;
use crate::scalar::SpartanExtensionField;
Expand All @@ -17,8 +16,8 @@ use std::cmp::min;

#[derive(Serialize, Deserialize, Debug)]
pub struct R1CSProof<S: SpartanExtensionField> {
sc_proof_phase1: R1CSSumcheckInstanceProof<S>,
sc_proof_phase2: R1CSSumcheckInstanceProof<S>,
sc_proof_phase1: SumcheckInstanceProof<S>,
sc_proof_phase2: SumcheckInstanceProof<S>,
pok_claims_phase2: (KnowledgeProof<S>, ProductProof<S>),
proof_eq_sc_phase1: EqualityProof<S>,
proof_eq_sc_phase2: EqualityProof<S>,
Expand All @@ -41,13 +40,13 @@ impl<S: SpartanExtensionField> R1CSProof<S> {
evals_Cz: &mut DensePolynomialPqx<S>,
transcript: &mut Transcript,
random_tape: &mut RandomTape<S>,
) -> (R1CSSumcheckInstanceProof<S>, Vec<S>, Vec<S>) {
) -> (SumcheckInstanceProof<S>, Vec<S>, Vec<S>) {
let comb_func = |poly_A_comp: &S, poly_B_comp: &S, poly_C_comp: &S, poly_D_comp: &S| -> S {
*poly_A_comp * (*poly_B_comp * *poly_C_comp - *poly_D_comp)
};

let (sc_proof_phase_one, r, claims) =
R1CSSumcheckInstanceProof::<S>::prove_cubic_with_additive_term_disjoint_rounds(
SumcheckInstanceProof::<S>::prove_cubic_with_additive_term_disjoint_rounds(
&S::field_zero(), // claim is zero
num_rounds,
num_rounds_x_max,
Expand Down Expand Up @@ -83,12 +82,12 @@ impl<S: SpartanExtensionField> R1CSProof<S> {
evals_z: &mut DensePolynomialPqx<S>,
transcript: &mut Transcript,
random_tape: &mut RandomTape<S>,
) -> (R1CSSumcheckInstanceProof<S>, Vec<S>, Vec<S>) {
) -> (SumcheckInstanceProof<S>, Vec<S>, Vec<S>) {
let comb_func = |poly_A_comp: &S, poly_B_comp: &S, poly_C_comp: &S| -> S {
*poly_A_comp * *poly_B_comp * *poly_C_comp
};
let (sc_proof_phase_two, r, claims) =
R1CSSumcheckInstanceProof::<S>::prove_cubic_disjoint_rounds(
SumcheckInstanceProof::<S>::prove_cubic_disjoint_rounds(
claim,
num_rounds,
num_rounds_y_max,
Expand All @@ -102,7 +101,6 @@ impl<S: SpartanExtensionField> R1CSProof<S> {
evals_z,
comb_func,
transcript,
random_tape,
);

(sc_proof_phase_two, r, claims)
Expand Down
188 changes: 17 additions & 171 deletions spartan_parallel/src/sumcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use crate::scalar::SpartanExtensionField;

use super::dense_mlpoly::DensePolynomial;
use super::errors::ProofVerifyError;
use super::nizk::DotProductProof;
use super::random::RandomTape;
use super::transcript::{AppendToTranscript, ProofTranscript};
use super::unipoly::{CompressedUniPoly, UniPoly};
Expand Down Expand Up @@ -70,67 +69,6 @@ impl<S: SpartanExtensionField> SumcheckInstanceProof<S> {
}
}

#[derive(Serialize, Deserialize, Debug)]
pub struct R1CSSumcheckInstanceProof<S: SpartanExtensionField> {
proofs: Vec<DotProductProof<S>>,
}

impl<S: SpartanExtensionField> R1CSSumcheckInstanceProof<S> {
pub fn new(proofs: Vec<DotProductProof<S>>) -> Self {
R1CSSumcheckInstanceProof { proofs }
}

pub fn verify(
&self,
num_rounds: usize,
degree_bound: usize,
transcript: &mut Transcript,
) -> Result<Vec<S>, ProofVerifyError> {
let mut r: Vec<S> = Vec::new();

for i in 0..num_rounds {
// derive the verifier's challenge for the next round
let r_i = transcript.challenge_scalar(b"challenge_nextround");

// verify the proof of sum-check and evals
let _res = {
// produce two weights
let w: Vec<S> = transcript.challenge_vector(b"combine_two_claims_to_one", 2);

let a = {
// the vector to use to decommit for sum-check test
let a_sc = {
let mut a = vec![S::field_one(); degree_bound + 1];
a[0] = a[0] + S::field_one();
a
};

// the vector to use to decommit for evaluation
let a_eval = {
let mut a = vec![S::field_one(); degree_bound + 1];
for j in 1..a.len() {
a[j] = a[j - 1] * r_i;
}
a
};

// take weighted sum of the two vectors using w
assert_eq!(a_sc.len(), a_eval.len());
(0..a_sc.len())
.map(|i| w[0] * a_sc[i] + w[1] * a_eval[i])
.collect::<Vec<S>>()
};

self.proofs[i].verify(transcript, &a).is_ok()
};

r.push(r_i);
}

Ok(r)
}
}

impl<S: SpartanExtensionField> SumcheckInstanceProof<S> {
pub fn prove_cubic<F>(
claim: &S,
Expand Down Expand Up @@ -379,9 +317,7 @@ impl<S: SpartanExtensionField> SumcheckInstanceProof<S> {
claims_dotp,
)
}
}

impl<S: SpartanExtensionField> R1CSSumcheckInstanceProof<S> {
pub fn prove_cubic_disjoint_rounds<F>(
claim: &S,
num_rounds: usize,
Expand All @@ -396,7 +332,6 @@ impl<S: SpartanExtensionField> R1CSSumcheckInstanceProof<S> {
poly_C: &mut DensePolynomialPqx<S>,
comb_func: F,
transcript: &mut Transcript,
random_tape: &mut RandomTape<S>,
) -> (Self, Vec<S>, Vec<S>)
where
F: Fn(&S, &S, &S) -> S,
Expand All @@ -410,7 +345,7 @@ impl<S: SpartanExtensionField> R1CSSumcheckInstanceProof<S> {
let mut claim_per_round = *claim;

let mut r: Vec<S> = Vec::new();
let mut proofs: Vec<DotProductProof<S>> = Vec::new();
let mut cubic_polys: Vec<CompressedUniPoly<S>> = Vec::new();

let mut inputs_len = num_rounds_y_max.pow2();
let mut witness_secs_len = num_rounds_w.pow2();
Expand Down Expand Up @@ -540,8 +475,12 @@ impl<S: SpartanExtensionField> R1CSSumcheckInstanceProof<S> {
poly
};

// 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
if mode == MODE_P {
Expand All @@ -552,61 +491,12 @@ impl<S: SpartanExtensionField> R1CSSumcheckInstanceProof<S> {
}
poly_C.bound_poly(&r_j, mode);

// produce a proof of sum-check and of evaluation
let (proof, claim_next_round) = {
let eval = poly.evaluate(&r_j);

// we need to prove the following under homomorphic commitments:
// (1) poly(0) + poly(1) = claim_per_round
// (2) poly(r_j) = eval

// Our technique is to leverage dot product proofs:
// (1) we can prove: <poly_in_coeffs_form, (2, 1, 1, 1)> = claim_per_round
// (2) we can prove: <poly_in_coeffs_form, (1, r_j, r^2_j, ..) = eval
// for efficiency we batch them using random weights

// produce two weights
let w: Vec<S> = transcript.challenge_vector(b"combine_two_claims_to_one", 2);

// compute a weighted sum of the RHS
let target = w[0] * claim_per_round + w[1] * eval;

let a = {
// the vector to use to decommit for sum-check test
let a_sc = {
let mut a = vec![S::field_one(); poly.degree() + 1];
a[0] = a[0] + S::field_one();
a
};

// the vector to use to decommit for evaluation
let a_eval = {
let mut a = vec![S::field_one(); poly.degree() + 1];
for j in 1..a.len() {
a[j] = a[j - 1] * r_j;
}
a
};

// take weighted sum of the two vectors using w
assert_eq!(a_sc.len(), a_eval.len());
(0..a_sc.len())
.map(|i| w[0] * a_sc[i] + w[1] * a_eval[i])
.collect::<Vec<S>>()
};

let proof = DotProductProof::prove(transcript, random_tape, &poly.as_vec(), &a, &target);

(proof, eval)
};

proofs.push(proof);
claim_per_round = claim_next_round;
r.push(r_j);
claim_per_round = poly.evaluate(&r_j);
cubic_polys.push(poly.compress());
}

(
R1CSSumcheckInstanceProof::new(proofs),
SumcheckInstanceProof::new(cubic_polys),
r,
vec![
poly_A[0],
Expand Down Expand Up @@ -653,7 +543,7 @@ impl<S: SpartanExtensionField> R1CSSumcheckInstanceProof<S> {
let mut claim_per_round = *claim;

let mut r: Vec<S> = Vec::new();
let mut proofs: Vec<DotProductProof<S>> = Vec::new();
let mut cubic_polys: Vec<CompressedUniPoly<S>> = Vec::new();

let mut cons_len = num_rounds_x_max.pow2();
let mut proof_len = num_rounds_q_max.pow2();
Expand Down Expand Up @@ -798,8 +688,12 @@ impl<S: SpartanExtensionField> R1CSSumcheckInstanceProof<S> {
poly
};

// 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
if mode == 1 {
Expand All @@ -813,60 +707,12 @@ impl<S: SpartanExtensionField> R1CSSumcheckInstanceProof<S> {
poly_C.bound_poly(&r_j, mode);
poly_D.bound_poly(&r_j, mode);

let (proof, claim_next_round) = {
let eval = poly.evaluate(&r_j);

// we need to prove the following under homomorphic commitments:
// (1) poly(0) + poly(1) = claim_per_round
// (2) poly(r_j) = eval

// Our technique is to leverage dot product proofs:
// (1) we can prove: <poly_in_coeffs_form, (2, 1, 1, 1)> = claim_per_round
// (2) we can prove: <poly_in_coeffs_form, (1, r_j, r^2_j, ..) = eval
// for efficiency we batch them using random weights

// produce two weights
let w: Vec<S> = transcript.challenge_vector(b"combine_two_claims_to_one", 2);

// compute a weighted sum of the RHS
let target = w[0] * claim_per_round + w[1] * eval;

let a = {
// the vector to use to decommit for sum-check test
let a_sc = {
let mut a = vec![S::field_one(); poly.degree() + 1];
a[0] = a[0] + S::field_one();
a
};

// the vector to use to decommit for evaluation
let a_eval = {
let mut a = vec![S::field_one(); poly.degree() + 1];
for j in 1..a.len() {
a[j] = a[j - 1] * r_j;
}
a
};

// take weighted sum of the two vectors using w
assert_eq!(a_sc.len(), a_eval.len());
(0..a_sc.len())
.map(|i| w[0] * a_sc[i] + w[1] * a_eval[i])
.collect::<Vec<S>>()
};

let proof = DotProductProof::prove(transcript, random_tape, &poly.as_vec(), &a, &target);

(proof, eval)
};

proofs.push(proof);
claim_per_round = claim_next_round;
r.push(r_j);
claim_per_round = poly.evaluate(&r_j);
cubic_polys.push(poly.compress());
}

(
R1CSSumcheckInstanceProof::new(proofs),
SumcheckInstanceProof::new(cubic_polys),
r,
vec![
poly_Ap[0] * poly_Aq[0] * poly_Ax[0],
Expand All @@ -876,4 +722,4 @@ impl<S: SpartanExtensionField> R1CSSumcheckInstanceProof<S> {
],
)
}
}
}

0 comments on commit 4b160ca

Please sign in to comment.