Skip to content

Commit

Permalink
Optimising proving by avoiding recomputing final Pi polynomial in M…
Browse files Browse the repository at this point in the history
…LKZG (#242)

* feat: Avoid computing final 'Pi' polynomial which is constant

* chore: Cleanup

* chore: Latest suggestions
  • Loading branch information
storojs72 authored Jan 10, 2024
1 parent 85c04b3 commit 6c0945e
Showing 1 changed file with 59 additions and 30 deletions.
89 changes: 59 additions & 30 deletions src/provider/mlkzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ where
ck: &UniversalKZGParam<E>,
_pk: &Self::ProverKey,
transcript: &mut <NE as NovaEngine>::TE,
C: &Commitment<NE>,
_C: &Commitment<NE>,
hat_P: &[E::Fr],
point: &[E::Fr],
eval: &E::Fr,
_eval: &E::Fr,
) -> Result<Self::EvaluationArgument, NovaError> {
let x: Vec<E::Fr> = point.to_vec();

Expand Down Expand Up @@ -164,8 +164,7 @@ where
.to_affine()
};

let kzg_open_batch = |C: &[E::G1Affine],
f: &[Vec<E::Fr>],
let kzg_open_batch = |f: &[Vec<E::Fr>],
u: &[E::Fr],
transcript: &mut <NE as NovaEngine>::TE|
-> (Vec<E::G1Affine>, Vec<Vec<E::Fr>>) {
Expand Down Expand Up @@ -194,15 +193,14 @@ where

let k = f.len();
let t = u.len();
assert!(C.len() == k);

// The verifier needs f_i(u_j), so we compute them here
// (V will compute B(u_j) itself)
let mut v = vec![vec!(E::Fr::ZERO; k); t];
v.par_iter_mut().enumerate().for_each(|(i, v_i)| {
// for each point u
v_i.par_iter_mut().zip_eq(f).for_each(|(v_ij, f)| {
// for each poly f
// for each poly f (except the last one - since it is constant)
*v_ij = UniPoly::ref_cast(f).evaluate(&u[i]);
});
});
Expand All @@ -216,7 +214,6 @@ where
// The prover computes the challenge to keep the transcript in the same
// state as that of the verifier
let _d_0 = Self::verifier_second_challenge(&w, transcript);

(w, v)
};

Expand All @@ -229,7 +226,10 @@ where
// Phase 1 -- create commitments com_1, ..., com_\ell
let mut polys: Vec<Vec<E::Fr>> = Vec::new();
polys.push(hat_P.to_vec());
for i in 0..ell {

// We don't compute final Pi (and its commitment) as it is constant and equals to 'eval'
// also known to verifier, so can be derived on its side as well
for i in 0..x.len() - 1 {
let Pi_len = polys[i].len() / 2;
let mut Pi = vec![E::Fr::ZERO; Pi_len];

Expand All @@ -238,10 +238,6 @@ where
*Pi_j = x[ell - i - 1] * (polys[i][2 * j + 1] - polys[i][2 * j]) + polys[i][2 * j];
});

if i == ell - 1 && *eval != Pi[0] {
return Err(NovaError::UnSat);
}

polys.push(Pi);
}

Expand All @@ -263,9 +259,7 @@ where
let u = vec![r, -r, r * r];

// Phase 3 -- create response
let mut com_all = comms.clone();
com_all.insert(0, C.comm.to_affine());
let (w, evals) = kzg_open_batch(&com_all, &polys, &u, transcript);
let (w, evals) = kzg_open_batch(&polys, &u, transcript);

Ok(EvaluationArgument { comms, w, evals })
}
Expand Down Expand Up @@ -380,7 +374,6 @@ where
// we do not need to add x to the transcript, because in our context x was
// obtained from the transcript
let r = Self::compute_challenge(&com, transcript);

if r == E::Fr::ZERO || C.comm == E::G1::identity() {
return Err(NovaError::ProofVerifyError);
}
Expand All @@ -393,18 +386,15 @@ where
if v.len() != 3 {
return Err(NovaError::ProofVerifyError);
}
if v[0].len() != ell + 1 || v[1].len() != ell + 1 || v[2].len() != ell + 1 {
if v[0].len() != ell || v[1].len() != ell || v[2].len() != ell {
return Err(NovaError::ProofVerifyError);
}
let ypos = &v[0];
let yneg = &v[1];
let Y = &v[2];
let mut Y = v[2].to_vec();
Y.push(*y);

// Check consistency of (Y, ypos, yneg)
if Y[ell] != *y {
return Err(NovaError::ProofVerifyError);
}

let two = E::Fr::from(2u64);
for i in 0..ell {
if two * r * Y[i + 1]
Expand Down Expand Up @@ -474,15 +464,54 @@ mod tests {
let point = vec![Fr::from(2), Fr::from(2)];
let eval = Fr::from(9);
assert!(EvaluationEngine::<E, NE>::prove(&ck, &pk, &mut tr, &C, &poly, &point, &eval).is_ok());
}

// Try a couple incorrect evaluations and expect failure
let point = vec![Fr::from(2), Fr::from(2)];
let eval = Fr::from(50);
assert!(EvaluationEngine::<E, NE>::prove(&ck, &pk, &mut tr, &C, &poly, &point, &eval).is_err());
#[test]
fn test_mlkzg_alternative() {
fn test_inner(n: usize, poly: &[Fr], point: &[Fr], eval: Fr) -> Result<(), NovaError> {
let ck: CommitmentKey<NE> =
<KZGCommitmentEngine<E> as CommitmentEngineTrait<NE>>::setup(b"test", n);
let (pk, vk): (KZGProverKey<E>, KZGVerifierKey<E>) = EvaluationEngine::<E, NE>::setup(&ck);

// make a commitment
let C = KZGCommitmentEngine::commit(&ck, poly);

// prove an evaluation
let mut prover_transcript = Keccak256Transcript::new(b"TestEval");
let proof =
EvaluationEngine::<E, NE>::prove(&ck, &pk, &mut prover_transcript, &C, poly, point, &eval)
.unwrap();

// verify the evaluation
let mut verifier_transcript = Keccak256Transcript::<NE>::new(b"TestEval");
EvaluationEngine::<E, NE>::verify(&vk, &mut verifier_transcript, &C, point, &eval, &proof)
}

let point = vec![Fr::from(0), Fr::from(2)];
let eval = Fr::from(4);
assert!(EvaluationEngine::<E, NE>::prove(&ck, &pk, &mut tr, &C, &poly, &point, &eval).is_err());
let n = 8;

// poly = [1, 2, 1, 4, 1, 2, 1, 4]
let poly = vec![
Fr::ONE,
Fr::from(2),
Fr::from(1),
Fr::from(4),
Fr::ONE,
Fr::from(2),
Fr::from(1),
Fr::from(4),
];

// point = [4,3,8]
let point = vec![Fr::from(4), Fr::from(3), Fr::from(8)];

// eval = 57
let eval = Fr::from(57);

assert!(test_inner(n, &poly, &point, eval).is_ok());

// wrong eval
let eval = Fr::from(56);
assert!(test_inner(n, &poly, &point, eval).is_err());
}

#[test]
Expand Down Expand Up @@ -541,7 +570,7 @@ mod tests {

// Change the proof and expect verification to fail
let mut bad_proof = proof.clone();
bad_proof.comms[0] = (bad_proof.comms[0] + bad_proof.comms[1]).to_affine();
bad_proof.comms[0] = (bad_proof.comms[0] + bad_proof.comms[0] * Fr::from(123)).to_affine();
let mut verifier_transcript2 = Keccak256Transcript::<NE>::new(b"TestEval");
assert!(EvaluationEngine::<E, NE>::verify(
&vk,
Expand Down

1 comment on commit 6c0945e

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmarks

Table of Contents

Overview

This benchmark report shows the Arecibo GPU benchmarks.
NVIDIA L4
Intel(R) Xeon(R) CPU @ 2.20GHz
32
125 GB RAM
Workflow run: https://github.com/lurk-lab/arecibo/actions/runs/7477000938

Benchmark Results

RecursiveSNARK

ref=85c04b3ab1d8446b0a8337ad738ea11aa94f45b4 ref=6c0945e2f8fecde6a043abc1f8e033b144eaaa65
Prove-StepCircuitSize-0 43.08 ms (✅ 1.00x) 43.57 ms (✅ 1.01x slower)
Verify-StepCircuitSize-0 22.31 ms (✅ 1.00x) 22.33 ms (✅ 1.00x slower)
Prove-StepCircuitSize-6559 50.66 ms (✅ 1.00x) 50.69 ms (✅ 1.00x slower)
Verify-StepCircuitSize-6559 28.48 ms (✅ 1.00x) 28.40 ms (✅ 1.00x faster)
Prove-StepCircuitSize-22943 69.70 ms (✅ 1.00x) 69.88 ms (✅ 1.00x slower)
Verify-StepCircuitSize-22943 43.94 ms (✅ 1.00x) 43.59 ms (✅ 1.01x faster)
Prove-StepCircuitSize-55711 87.49 ms (✅ 1.00x) 87.48 ms (✅ 1.00x faster)
Verify-StepCircuitSize-55711 46.78 ms (✅ 1.00x) 47.02 ms (✅ 1.01x slower)
Prove-StepCircuitSize-121247 68.10 ms (✅ 1.00x) 68.10 ms (✅ 1.00x faster)
Verify-StepCircuitSize-121247 29.60 ms (✅ 1.00x) 29.34 ms (✅ 1.01x faster)
Prove-StepCircuitSize-252319 125.20 ms (✅ 1.00x) 95.83 ms (✅ 1.31x faster)
Verify-StepCircuitSize-252319 43.86 ms (✅ 1.00x) 44.05 ms (✅ 1.00x slower)
Prove-StepCircuitSize-514463 180.89 ms (✅ 1.00x) 170.35 ms (✅ 1.06x faster)
Verify-StepCircuitSize-514463 53.29 ms (✅ 1.00x) 53.52 ms (✅ 1.00x slower)
Prove-StepCircuitSize-1038751 318.73 ms (✅ 1.00x) 299.65 ms (✅ 1.06x faster)
Verify-StepCircuitSize-1038751 95.65 ms (✅ 1.00x) 94.68 ms (✅ 1.01x faster)

RecursiveSNARKSuperNova-1circuit

ref=85c04b3ab1d8446b0a8337ad738ea11aa94f45b4
Prove-StepCircuitSize-... 46.12 ms (✅ 1.00x)
Verify-StepCircuitSize... 26.22 ms (✅ 1.00x)
Prove-StepCircuitSize-... #2 53.49 ms (✅ 1.00x)
Verify-StepCircuitSize... #2 32.70 ms (✅ 1.00x)
Prove-StepCircuitSize-... #3 72.65 ms (✅ 1.00x)
Verify-StepCircuitSize... #3 48.51 ms (✅ 1.00x)
Prove-StepCircuitSize-... #4 89.99 ms (✅ 1.00x)
Verify-StepCircuitSize... #4 54.01 ms (✅ 1.00x)
Prove-StepCircuitSize-... #5 74.52 ms (✅ 1.00x)
Verify-StepCircuitSize... #5 42.13 ms (✅ 1.00x)
Prove-StepCircuitSize-... #6 101.77 ms (✅ 1.00x)
Verify-StepCircuitSize... #6 61.52 ms (✅ 1.00x)
Prove-StepCircuitSize-... #7 209.77 ms (✅ 1.00x)
Verify-StepCircuitSize... #7 148.41 ms (✅ 1.00x)
Prove-StepCircuitSize-... #8 376.19 ms (✅ 1.00x)
Verify-StepCircuitSize... #8 290.87 ms (✅ 1.00x)

RecursiveSNARKSuperNova-2circuit

ref=85c04b3ab1d8446b0a8337ad738ea11aa94f45b4
Prove-StepCircuitSize-... 45.95 ms (✅ 1.00x)
Verify-StepCircuitSize... 26.04 ms (✅ 1.00x)
Prove-StepCircuitSize-... #2 53.56 ms (✅ 1.00x)
Verify-StepCircuitSize... #2 32.59 ms (✅ 1.00x)
Prove-StepCircuitSize-... #3 72.56 ms (✅ 1.00x)
Verify-StepCircuitSize... #3 48.26 ms (✅ 1.00x)
Prove-StepCircuitSize-... #4 89.73 ms (✅ 1.00x)
Verify-StepCircuitSize... #4 54.14 ms (✅ 1.00x)
Prove-StepCircuitSize-... #5 74.70 ms (✅ 1.00x)
Verify-StepCircuitSize... #5 41.80 ms (✅ 1.00x)
Prove-StepCircuitSize-... #6 101.68 ms (✅ 1.00x)
Verify-StepCircuitSize... #6 61.64 ms (✅ 1.00x)
Prove-StepCircuitSize-... #7 211.59 ms (✅ 1.00x)
Verify-StepCircuitSize... #7 151.72 ms (✅ 1.00x)
Prove-StepCircuitSize-... #8 376.66 ms (✅ 1.00x)
Verify-StepCircuitSize... #8 291.50 ms (✅ 1.00x)

CompressedSNARK

ref=85c04b3ab1d8446b0a8337ad738ea11aa94f45b4 ref=6c0945e2f8fecde6a043abc1f8e033b144eaaa65
Prove-StepCircuitSize-0 543.41 ms (✅ 1.00x) 544.63 ms (✅ 1.00x slower)
Verify-StepCircuitSize-0 29.11 ms (✅ 1.00x) 28.94 ms (✅ 1.01x faster)
Prove-StepCircuitSize-6559 559.58 ms (✅ 1.00x) 559.40 ms (✅ 1.00x faster)
Verify-StepCircuitSize-6559 29.20 ms (✅ 1.00x) 29.22 ms (✅ 1.00x slower)
Prove-StepCircuitSize-22943 813.49 ms (✅ 1.00x) 811.62 ms (✅ 1.00x faster)
Verify-StepCircuitSize-22943 38.68 ms (✅ 1.00x) 38.82 ms (✅ 1.00x slower)
Prove-StepCircuitSize-55711 1.36 s (✅ 1.00x) 1.36 s (✅ 1.00x slower)
Verify-StepCircuitSize-55711 25.11 ms (✅ 1.00x) 24.81 ms (✅ 1.01x faster)
Prove-StepCircuitSize-121247 2.31 s (✅ 1.00x) 2.31 s (✅ 1.00x slower)
Verify-StepCircuitSize-121247 36.02 ms (✅ 1.00x) 35.41 ms (✅ 1.02x faster)
Prove-StepCircuitSize-252319 4.25 s (✅ 1.00x) 4.25 s (✅ 1.00x slower)
Verify-StepCircuitSize-252319 52.20 ms (✅ 1.00x) 52.06 ms (✅ 1.00x faster)
Prove-StepCircuitSize-514463 8.25 s (✅ 1.00x) 8.24 s (✅ 1.00x faster)
Verify-StepCircuitSize-514463 107.47 ms (✅ 1.00x) 102.06 ms (✅ 1.05x faster)
Prove-StepCircuitSize-1038751 16.04 s (✅ 1.00x) 16.05 s (✅ 1.00x slower)
Verify-StepCircuitSize-1038751 226.00 ms (✅ 1.00x) 255.73 ms (❌ 1.13x slower)

CompressedSNARK-Commitments

ref=85c04b3ab1d8446b0a8337ad738ea11aa94f45b4 ref=6c0945e2f8fecde6a043abc1f8e033b144eaaa65
Prove-StepCircuitSize-0 4.43 s (✅ 1.00x) 4.33 s (✅ 1.02x faster)
Verify-StepCircuitSize-0 28.86 ms (✅ 1.00x) 28.71 ms (✅ 1.00x faster)
Prove-StepCircuitSize-6559 8.17 s (✅ 1.00x) 8.09 s (✅ 1.01x faster)
Verify-StepCircuitSize-6559 37.50 ms (✅ 1.00x) 37.72 ms (✅ 1.01x slower)
Prove-StepCircuitSize-22943 7.47 s (✅ 1.00x) 7.32 s (✅ 1.02x faster)
Verify-StepCircuitSize-2294... 37.74 ms (✅ 1.00x) 37.53 ms (✅ 1.01x faster)
Prove-StepCircuitSize-55711 14.32 s (✅ 1.00x) 14.02 s (✅ 1.02x faster)
Verify-StepCircuitSize-5571... 78.84 ms (✅ 1.00x) 59.75 ms (✅ 1.32x faster)
Prove-StepCircuitSize-12124... 11.02 s (✅ 1.00x) 10.93 s (✅ 1.01x faster)
Verify-StepCircuitSize-1212... 79.02 ms (✅ 1.00x) 59.93 ms (✅ 1.32x faster)
Prove-StepCircuitSize-25231... 21.67 s (✅ 1.00x) 21.71 s (✅ 1.00x slower)
Verify-StepCircuitSize-2523... 163.56 ms (✅ 1.00x) 143.86 ms (✅ 1.14x faster)

CompressedSNARKSuperNova-1circuit

ref=85c04b3ab1d8446b0a8337ad738ea11aa94f45b4
Prove-StepCircuitSize... 630.20 ms (✅ 1.00x)
Verify-StepCircuitSiz... 40.53 ms (✅ 1.00x)
Prove-StepCircuitSize... #2 621.06 ms (✅ 1.00x)
Verify-StepCircuitSiz... #2 40.58 ms (✅ 1.00x)
Prove-StepCircuitSize... #3 885.64 ms (✅ 1.00x)
Verify-StepCircuitSiz... #3 50.82 ms (✅ 1.00x)
Prove-StepCircuitSize... #4 1.42 s (✅ 1.00x)
Verify-StepCircuitSiz... #4 38.33 ms (✅ 1.00x)
Prove-StepCircuitSize... #5 2.40 s (✅ 1.00x)
Verify-StepCircuitSiz... #5 47.54 ms (✅ 1.00x)
Prove-StepCircuitSize... #6 4.43 s (✅ 1.00x)
Verify-StepCircuitSiz... #6 64.76 ms (✅ 1.00x)
Prove-StepCircuitSize... #7 8.30 s (✅ 1.00x)
Verify-StepCircuitSiz... #7 119.44 ms (✅ 1.00x)
Prove-StepCircuitSize... #8 16.14 s (✅ 1.00x)
Verify-StepCircuitSiz... #8 251.10 ms (✅ 1.00x)

CompressedSNARKSuperNova-2circuit

ref=85c04b3ab1d8446b0a8337ad738ea11aa94f45b4
Prove-StepCircuitSize... 622.56 ms (✅ 1.00x)
Verify-StepCircuitSiz... 42.70 ms (✅ 1.00x)
Prove-StepCircuitSize... #2 633.11 ms (✅ 1.00x)
Verify-StepCircuitSiz... #2 42.51 ms (✅ 1.00x)
Prove-StepCircuitSize... #3 885.30 ms (✅ 1.00x)
Verify-StepCircuitSiz... #3 53.97 ms (✅ 1.00x)
Prove-StepCircuitSize... #4 1.40 s (✅ 1.00x)
Verify-StepCircuitSiz... #4 43.65 ms (✅ 1.00x)
Prove-StepCircuitSize... #5 2.39 s (✅ 1.00x)
Verify-StepCircuitSiz... #5 56.02 ms (✅ 1.00x)
Prove-StepCircuitSize... #6 4.49 s (✅ 1.00x)
Verify-StepCircuitSiz... #6 75.46 ms (✅ 1.00x)
Prove-StepCircuitSize... #7 8.59 s (✅ 1.00x)
Verify-StepCircuitSiz... #7 144.84 ms (✅ 1.00x)
Prove-StepCircuitSize... #8 16.24 s (✅ 1.00x)
Verify-StepCircuitSiz... #8 333.66 ms (✅ 1.00x)

CompressedSNARKSuperNova-Commitments-2circuit

ref=85c04b3ab1d8446b0a8337ad738ea11aa94f45b4
Prove-Ste... 8.21 s (✅ 1.00x)
Verify-St... 65.34 ms (✅ 1.00x)
Prove-Ste... #2 14.12 s (✅ 1.00x)
Verify-St... #2 78.17 ms (✅ 1.00x)
Prove-Ste... #3 12.51 s (✅ 1.00x)
Verify-St... #3 78.47 ms (✅ 1.00x)
Prove-Ste... #4 22.75 s (✅ 1.00x)
Verify-St... #4 121.32 ms (✅ 1.00x)
Prove-Ste... #5 15.70 s (✅ 1.00x)
Verify-St... #5 122.01 ms (✅ 1.00x)
Prove-Ste... #6 29.92 s (✅ 1.00x)
Verify-St... #6 236.82 ms (✅ 1.00x)
Prove-Ste... #7 57.65 s (✅ 1.00x)
Verify-St... #7 415.49 ms (✅ 1.00x)
Prove-Ste... #8 111.72 s (✅ 1.00x)
Verify-St... #8 772.64 ms (✅ 1.00x)

Made with criterion-table

Please sign in to comment.