Skip to content

Commit 8631b15

Browse files
committed
Finished diff size but same point
1 parent 21e964b commit 8631b15

File tree

3 files changed

+111
-30
lines changed

3 files changed

+111
-30
lines changed

mpcs/src/basefold.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1220,7 +1220,7 @@ mod test {
12201220
let gen_rand_poly = gen_rand_poly_base;
12211221
run_diff_size_batch_commit_open_verify::<GoldilocksExt2, PcsGoldilocksBaseCode>(
12221222
gen_rand_poly,
1223-
17,
1223+
20,
12241224
3,
12251225
5,
12261226
);

mpcs/src/lib.rs

Lines changed: 98 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,21 @@ pub fn pcs_batch_commit<E: ExtensionField, Pcs: PolynomialCommitmentScheme<E>>(
5555
Pcs::batch_commit(pp, polys)
5656
}
5757

58+
pub fn pcs_batch_commit_and_write<E: ExtensionField, Pcs: PolynomialCommitmentScheme<E>>(
59+
pp: &Pcs::ProverParam,
60+
polys: &[DenseMultilinearExtension<E>],
61+
transcript: &mut impl Transcript<E>,
62+
) -> Result<Pcs::CommitmentWithWitness, Error> {
63+
Pcs::batch_commit_and_write(pp, polys, transcript)
64+
}
65+
5866
// Express Value as binary in big-endian
5967
fn compute_binary_with_length(length: usize, mut value: usize) -> Vec<bool> {
60-
assert!(value < 1 << length);
68+
assert!(value < (1 << length));
6169
let mut bin = Vec::new();
6270
for _ in 0..length {
6371
bin.insert(0, value % 2 == 1);
64-
value <<= 1;
72+
value >>= 1;
6573
}
6674
bin
6775
}
@@ -233,26 +241,32 @@ fn compute_packed_eval<E: ExtensionField>(
233241
// Use comps to compute evals for packed polys from regular evals
234242
let mut packed_evals = Vec::new();
235243
let mut next_orig_poly = 0;
244+
let pack_num_vars = packed_point.len();
236245
for next_packed_comp in packed_comps {
237246
let mut packed_eval = E::ZERO;
238247
for next_index in next_packed_comp {
239248
let mut next_eval = evals[next_orig_poly];
249+
// Note: the points are stored in reverse
240250
for (j, b) in next_index.iter().enumerate() {
241-
if *b { next_eval *= packed_point[j] }
251+
let next_point = packed_point[pack_num_vars - 1 - j];
252+
if *b { next_eval *= next_point } else { next_eval *= E::ONE - next_point }
242253
}
243-
packed_eval *= next_eval;
254+
packed_eval += next_eval;
244255
next_orig_poly += 1;
245256
}
246257
packed_evals.push(packed_eval);
247258
}
248259
if let Some(final_comp) = final_comp {
249260
let mut final_eval = E::ZERO;
261+
let final_num_vars = final_point.len();
250262
for next_index in final_comp {
251263
let mut next_eval = evals[next_orig_poly];
264+
// Note: the points are stored in reverse
252265
for (j, b) in next_index.iter().enumerate() {
253-
if *b { next_eval *= final_point[j] }
266+
let next_point = final_point[final_num_vars - 1 - j];
267+
if *b { next_eval *= next_point } else { next_eval *= E::ONE - next_point }
254268
}
255-
final_eval *= next_eval;
269+
final_eval += next_eval;
256270
next_orig_poly += 1;
257271
}
258272
(packed_evals, Some(final_eval))
@@ -262,25 +276,35 @@ fn compute_packed_eval<E: ExtensionField>(
262276
}
263277

264278
pub fn pcs_batch_commit_diff_size<E: ExtensionField, Pcs: PolynomialCommitmentScheme<E>>(
265-
pp: &Pcs::ProverParam,
279+
pack_pp: &Pcs::ProverParam,
280+
final_pp: &Option<Pcs::ProverParam>,
266281
polys: &[DenseMultilinearExtension<E>],
267282
) -> Result<(Pcs::CommitmentWithWitness, Option<Pcs::CommitmentWithWitness>), Error> {
268283
let (packed_polys, final_poly, _, _) = pack_poly_prover(polys);
269284
// Final packed poly
270-
if let Some(final_poly) = final_poly {
271-
Ok((Pcs::batch_commit(pp, &packed_polys)?, Some(Pcs::batch_commit(pp, &[final_poly])?)))
272-
} else {
273-
Ok((Pcs::batch_commit(pp, &packed_polys)?, None))
285+
match (final_pp, final_poly) {
286+
(Some(final_pp), Some(final_poly)) => Ok((Pcs::batch_commit(pack_pp, &packed_polys)?, Some(Pcs::batch_commit(final_pp, &[final_poly])?))),
287+
(None, None) => Ok((Pcs::batch_commit(pack_pp, &packed_polys)?, None)),
288+
_ => unreachable!()
274289
}
275290
}
276291

277-
pub fn pcs_batch_commit_and_write<E: ExtensionField, Pcs: PolynomialCommitmentScheme<E>>(
292+
pub fn pcs_batch_commit_diff_size_and_write<E: ExtensionField, Pcs: PolynomialCommitmentScheme<E>>(
278293
pp: &Pcs::ProverParam,
279294
polys: &[DenseMultilinearExtension<E>],
280295
transcript: &mut impl Transcript<E>,
281-
) -> Result<Pcs::CommitmentWithWitness, Error> {
282-
Pcs::batch_commit_and_write(pp, polys, transcript)
283-
}
296+
) -> Result<(Pcs::CommitmentWithWitness, Option<Pcs::CommitmentWithWitness>), Error> {
297+
let (packed_polys, final_poly, _, _) = pack_poly_prover(polys);
298+
// Final packed poly
299+
if let Some(final_poly) = final_poly {
300+
Ok((
301+
Pcs::batch_commit_and_write(pp, &packed_polys, transcript)?,
302+
Some(Pcs::commit_and_write(pp, &final_poly, transcript)?)
303+
))
304+
} else {
305+
Ok((Pcs::batch_commit_and_write(pp, &packed_polys, transcript)?, None))
306+
}
307+
}
284308

285309
pub fn pcs_open<E: ExtensionField, Pcs: PolynomialCommitmentScheme<E>>(
286310
pp: &Pcs::ProverParam,
@@ -316,18 +340,22 @@ pub fn pcs_batch_open_diff_size<E: ExtensionField, Pcs: PolynomialCommitmentSche
316340
// TODO: Sort the polys by decreasing size
317341
// TODO: The prover should be able to avoid packing the polys again
318342
let (packed_polys, final_poly, packed_comps, final_comp) = pack_poly_prover(polys);
319-
let packed_polys: Vec<ArcMultilinearExtension<E>> = packed_polys.into_iter().map(|p| ArcMultilinearExtension::from(p)).collect();
320343
// TODO: Add unifying sumcheck if the points do not match
321344
// For now, assume that all polys are evaluated on the same points
322345
let packed_point = points[0].clone();
323-
let final_point = if let Some(final_poly) = &final_poly { packed_point[packed_point.len() - final_poly.num_vars..packed_point.len()].to_vec() } else { Vec::new() };
346+
// Note: the points are stored in reverse
347+
let final_point = if let Some(final_poly) = &final_poly { packed_point[..final_poly.num_vars].to_vec() } else { Vec::new() };
324348
// Use comps to compute evals for packed polys from regular evals
325349
let (packed_evals, final_eval) = compute_packed_eval(&packed_point, &final_point, evals, &packed_comps, &final_comp);
326350

351+
let packed_polys: Vec<ArcMultilinearExtension<E>> = packed_polys.into_iter().map(|p| ArcMultilinearExtension::from(p)).collect();
327352
let pack_proof = Pcs::simple_batch_open(pp, &packed_polys, packed_comm, &packed_point, &packed_evals, transcript)?;
328353
let final_proof = match (&final_poly, &final_comm, &final_eval) {
329-
(Some(final_poly), Some(final_comm), Some(final_eval)) => Some(Pcs::open(pp, final_poly, final_comm, &final_point, final_eval, transcript)?),
330-
_ => None,
354+
(Some(final_poly), Some(final_comm), Some(final_eval)) => {
355+
Some(Pcs::open(pp, final_poly, final_comm, &final_point, final_eval, transcript)?)
356+
}
357+
(None, None, None) => None,
358+
_ => unreachable!(),
331359
};
332360
Ok((pack_proof, final_proof))
333361
}
@@ -376,13 +404,17 @@ where
376404
// TODO: Add unifying sumcheck if the points do not match
377405
// For now, assume that all polys are evaluated on the same points
378406
let packed_point = points[0].clone();
379-
let final_point = if let Some(final_poly_num_vars) = &final_poly_num_vars { packed_point[packed_point.len() - final_poly_num_vars..packed_point.len()].to_vec() } else { Vec::new() };
407+
let final_point = if let Some(final_poly_num_vars) = &final_poly_num_vars { packed_point[..*final_poly_num_vars].to_vec() } else { Vec::new() };
380408
// Use comps to compute evals for packed polys from regular evals
381409
let (packed_evals, final_eval) = compute_packed_eval(&packed_point, &final_point, evals, &packed_comps, &final_comp);
410+
382411
Pcs::simple_batch_verify(vp, packed_comm, &packed_point, &packed_evals, packed_proof, transcript)?;
383412
match (&final_comm, &final_eval, &final_proof) {
384-
(Some(final_comm), Some(final_eval), Some(final_proof)) => Pcs::verify(vp, final_comm, &final_point, &final_eval, final_proof, transcript),
385-
_ => Ok(()),
413+
(Some(final_comm), Some(final_eval), Some(final_proof)) => {
414+
Pcs::verify(vp, final_comm, &final_point, &final_eval, final_proof, transcript)
415+
}
416+
(None, None, None) => Ok(()),
417+
_ => unreachable!(),
386418
}
387419
}
388420

@@ -926,24 +958,26 @@ pub mod test_util {
926958
E: ExtensionField,
927959
Pcs: PolynomialCommitmentScheme<E>,
928960
{
929-
use crate::{pcs_batch_commit_diff_size, pcs_batch_open_diff_size, pcs_batch_verify_diff_size};
961+
use crate::{pcs_batch_commit_diff_size_and_write, pcs_batch_open_diff_size, pcs_batch_verify_diff_size};
930962

931963
for vars_gap in 1..=max_vars_gap {
932964
assert!(max_num_vars > vars_gap * batch_size);
933965
let (pp, vp) = setup_pcs::<E, Pcs>(max_num_vars);
934966

935967
let (poly_num_vars, packed_comm, final_comm, evals, packed_proof, final_proof, challenge) = {
936968
let mut transcript = BasicTranscript::new(b"BaseFold");
937-
let polys: Vec<DenseMultilinearExtension<E>> = (0..batch_size).map(|i| gen_rand_polys(|_| max_num_vars - i * vars_gap, 1, gen_rand_poly)).flatten().collect();
938-
let (packed_comm, final_comm) = pcs_batch_commit_diff_size::<E, Pcs>(&pp, &polys).unwrap();
969+
let polys: Vec<DenseMultilinearExtension<E>> = (0..batch_size).map(|i|
970+
gen_rand_polys(|_| max_num_vars - i * vars_gap, 1, gen_rand_poly)
971+
).flatten().collect();
972+
let (packed_comm, final_comm) = pcs_batch_commit_diff_size_and_write::<E, Pcs>(&pp, &polys, &mut transcript).unwrap();
939973
let point = get_point_from_challenge(max_num_vars, &mut transcript);
940-
let points: Vec<Vec<E>> = polys.iter().map(|p| point[max_num_vars - p.num_vars..].to_vec()).collect();
974+
let points: Vec<Vec<E>> = polys.iter().map(|p| point[..p.num_vars].to_vec()).collect();
941975
let evals = polys.iter().zip(&points).map(|(poly, point)| poly.evaluate(point)).collect_vec();
942976
transcript.append_field_element_exts(&evals);
943977

944978
let (packed_proof, final_proof) = pcs_batch_open_diff_size::<E, Pcs>(&pp, &polys, &packed_comm, &final_comm, &points, &evals, &mut transcript).unwrap();
945979
(
946-
polys.iter().map(|p| p.num_vars).collect::<Vec<usize>>(),
980+
polys.iter().map(|p| p.num_vars()).collect::<Vec<_>>(),
947981
Pcs::get_pure_commitment(&packed_comm),
948982
if let Some(final_comm) = final_comm { Some(Pcs::get_pure_commitment(&final_comm)) } else { None },
949983
evals,
@@ -961,7 +995,7 @@ pub mod test_util {
961995
}
962996

963997
let point = get_point_from_challenge(max_num_vars, &mut transcript);
964-
let points: Vec<Vec<E>> = poly_num_vars.iter().map(|n| point[max_num_vars - n..].to_vec()).collect();
998+
let points: Vec<Vec<E>> = poly_num_vars.iter().map(|n| point[..*n].to_vec()).collect();
965999
transcript.append_field_element_exts(&evals);
9661000

9671001
pcs_batch_verify_diff_size::<E, Pcs>(&vp, &poly_num_vars, &packed_comm, &final_comm, &points, &evals, &packed_proof, &final_proof, &mut transcript).unwrap();
@@ -980,6 +1014,12 @@ pub mod test_util {
9801014

9811015
#[cfg(test)]
9821016
mod test {
1017+
use ark_std::test_rng;
1018+
use ff_ext::GoldilocksExt2;
1019+
use multilinear_extensions::mle::{DenseMultilinearExtension, FieldType, MultilinearExtension};
1020+
use p3_field::PrimeCharacteristicRing;
1021+
use p3_goldilocks::Goldilocks;
1022+
type E = GoldilocksExt2;
9831023

9841024
#[test]
9851025
fn test_packing() {
@@ -993,4 +1033,34 @@ mod test {
9931033
println!("FINAL_COMP: {:?}", final_comp);
9941034
}
9951035

1036+
#[test]
1037+
fn test_packing_eval() {
1038+
let mut rng = test_rng();
1039+
let poly0 = DenseMultilinearExtension::<E>::random(4, &mut rng);
1040+
let poly1 = DenseMultilinearExtension::<E>::random(3, &mut rng);
1041+
let poly2 = DenseMultilinearExtension::<E>::random(2, &mut rng);
1042+
let point = [E::from_i32(5), E::from_i32(7), E::from_i32(9), E::from_i32(11), E::from_i32(13)];
1043+
let eval0 = poly0.evaluate(&point[..4]);
1044+
let eval1 = poly1.evaluate(&point[..3]);
1045+
let eval2 = poly2.evaluate(&point[..2]);
1046+
let claim =
1047+
(E::ONE - point[4]) * eval0 +
1048+
point[4] * (E::ONE - point[3]) * eval1 +
1049+
point[4] * point[3] * (E::ONE - point[2]) * eval2;
1050+
1051+
let mut poly = poly0.clone();
1052+
poly.merge(poly1.clone());
1053+
poly.merge(poly2.clone());
1054+
match &mut poly.evaluations {
1055+
FieldType::Base(e) => {
1056+
e.extend(vec![Goldilocks::ZERO; 4])
1057+
}
1058+
FieldType::Ext(e) => {
1059+
e.extend(vec![E::ZERO; 4])
1060+
}
1061+
_ => ()
1062+
}
1063+
let eval = poly.evaluate(&point);
1064+
println!("CLAIM: {:?}, EXPECTED: {:?}", claim, eval);
1065+
}
9961066
}

mpcs/src/whir.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ where
179179
mod tests {
180180
use super::*;
181181
use crate::test_util::{
182-
gen_rand_poly_base, run_commit_open_verify, run_simple_batch_commit_open_verify,
182+
gen_rand_poly_base, run_commit_open_verify, run_diff_size_batch_commit_open_verify, run_simple_batch_commit_open_verify
183183
};
184184
use ff_ext::GoldilocksExt2;
185185
use spec::WhirDefaultSpec;
@@ -258,4 +258,15 @@ mod tests {
258258
);
259259
}
260260
}
261+
262+
#[test]
263+
fn batch_commit_diff_size_open_verify() {
264+
let gen_rand_poly = gen_rand_poly_base;
265+
run_diff_size_batch_commit_open_verify::<GoldilocksExt2, PcsGoldilocks>(
266+
gen_rand_poly,
267+
20,
268+
3,
269+
5,
270+
);
271+
}
261272
}

0 commit comments

Comments
 (0)