Skip to content

Commit fab6bb0

Browse files
committed
sumcheck: when folding with small base-field scalars [0, 2, 3, ...], use repeated sums instead of muls
1 parent 2ab7055 commit fab6bb0

7 files changed

Lines changed: 135 additions & 171 deletions

File tree

crates/air/src/prove.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ where
5555
air,
5656
&extra_data,
5757
Some((zerocheck_challenges, None)),
58-
virtual_column_statement.is_none(),
5958
prover_state,
6059
virtual_column_statement
6160
.as_ref()
@@ -120,7 +119,6 @@ fn open_columns<EF: ExtensionField<PF<EF>>>(
120119
&ProductComputation {},
121120
&vec![],
122121
None,
123-
false,
124122
prover_state,
125123
inner_sum,
126124
false,

crates/backend/sumcheck/src/product_computation.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ pub fn run_product_sumcheck<EF: ExtensionField<PF<EF>>>(
107107
&ProductComputation {},
108108
&vec![],
109109
None,
110-
false,
111110
prover_state,
112111
sum,
113112
None,

crates/backend/sumcheck/src/prove.rs

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ pub fn sumcheck_prove<'a, EF, SC, M: Into<MleGroup<'a, EF>>>(
1212
computation: &SC,
1313
extra_data: &SC::ExtraData,
1414
eq_factor: Option<(Vec<EF>, Option<MleOwned<EF>>)>, // (a, b, c ...), eq_poly(b, c, ...)
15-
is_zerofier: bool,
1615
prover_state: &mut impl FSProver<EF>,
1716
sum: EF,
1817
store_intermediate_foldings: bool,
@@ -28,7 +27,6 @@ where
2827
computation,
2928
extra_data,
3029
eq_factor,
31-
is_zerofier,
3230
prover_state,
3331
sum,
3432
store_intermediate_foldings,
@@ -42,7 +40,6 @@ pub fn sumcheck_fold_and_prove<'a, EF, SC, M: Into<MleGroup<'a, EF>>>(
4240
computation: &SC,
4341
extra_data: &SC::ExtraData,
4442
eq_factor: Option<(Vec<EF>, Option<MleOwned<EF>>)>, // (a, b, c ...), eq_poly(b, c, ...)
45-
is_zerofier: bool,
4643
prover_state: &mut impl FSProver<EF>,
4744
sum: EF,
4845
store_intermediate_foldings: bool,
@@ -63,7 +60,6 @@ where
6360
computation,
6461
extra_data,
6562
eq_factor,
66-
is_zerofier,
6763
prover_state,
6864
sum,
6965
None,
@@ -93,7 +89,6 @@ pub fn sumcheck_prove_many_rounds<'a, EF, SC, M: Into<MleGroup<'a, EF>>>(
9389
computation: &SC,
9490
extra_data: &SC::ExtraData,
9591
mut eq_factor: Option<(Vec<EF>, Option<MleOwned<EF>>)>, // (a, b, c ...), eq_poly(b, c, ...)
96-
mut is_zerofier: bool,
9792
prover_state: &mut impl FSProver<EF>,
9893
mut sum: EF,
9994
mut missing_mul_factors: Option<EF>,
@@ -151,7 +146,6 @@ where
151146
computation,
152147
&eq_factor,
153148
extra_data,
154-
is_zerofier,
155149
prover_state,
156150
sum,
157151
missing_mul_factors,
@@ -170,7 +164,6 @@ where
170164
&ps,
171165
store_intermediate_foldings,
172166
);
173-
is_zerofier = false;
174167
}
175168

176169
if let Some(pf) = prev_folding_factor {
@@ -187,7 +180,6 @@ fn compute_and_send_polynomial<'a, EF, SC>(
187180
computation: &SC,
188181
eq_factor: &Option<(Vec<EF>, MleOwned<EF>)>, // (a, b, c ...), eq_poly(b, c, ...)
189182
extra_data: &SC::ExtraData,
190-
is_zerofier: bool,
191183
prover_state: &mut impl FSProver<EF>,
192184
sum: EF,
193185
missing_mul_factor: Option<EF>,
@@ -197,50 +189,49 @@ where
197189
SC: SumcheckComputation<EF> + 'static,
198190
SC::ExtraData: AlphaPowers<EF>,
199191
{
200-
let mut p_evals = Vec::<(PF<EF>, EF)>::new();
201-
let start = if is_zerofier {
202-
p_evals.push((PF::<EF>::ZERO, EF::ZERO));
203-
2
204-
} else {
205-
0
206-
};
192+
// Interpolation points = 0, 2, 3, 4, ...
193+
// evaluation at 1 is deduced since we know f(0) + f(1) = sum
207194

195+
let mut p_evals = Vec::<EF>::new();
208196
let computation_degree = computation.degree();
209-
let zs = (start..=computation_degree).filter(|&i| i != 1).collect::<Vec<_>>();
210-
211-
let compute_folding_factors: Vec<PF<EF>> = zs.iter().map(|&z| PF::<EF>::from_usize(z)).collect();
212197

213198
let sc_params = SumcheckComputeParams {
214199
eq_mle: eq_factor.as_ref().map(|(_, eq_mle)| eq_mle),
215200
first_eq_factor: eq_factor.as_ref().map(|(first_eq_factor, _)| first_eq_factor[0]),
216-
folding_factors: &compute_folding_factors,
217201
computation,
218202
extra_data,
219203
missing_mul_factor,
220204
sum,
221205
};
222206
p_evals.extend(match prev_folding_factor {
223207
Some(prev_folding_factor) => {
224-
let (computed_p_evals, folded_multilinears) =
225-
fold_and_sumcheck_compute(prev_folding_factor, &multilinears.by_ref(), sc_params, &zs);
208+
let (computed_p_evals, folded_multilinears) = fold_and_sumcheck_compute(
209+
prev_folding_factor,
210+
&multilinears.by_ref(),
211+
sc_params,
212+
computation_degree,
213+
);
226214
*multilinears = folded_multilinears.into();
227215
computed_p_evals
228216
}
229-
None => sumcheck_compute(&multilinears.by_ref(), sc_params, &zs),
217+
None => sumcheck_compute(&multilinears.by_ref(), sc_params, computation_degree),
230218
});
231219

232-
if is_zerofier {
233-
p_evals.push((PF::<EF>::ONE, EF::ZERO));
220+
let p_at_1 = if let Some((eq_factor, _)) = eq_factor {
221+
(sum - (EF::ONE - eq_factor[0]) * p_evals[0]) / eq_factor[0]
234222
} else {
235-
let p_at_1 = if let Some((eq_factor, _)) = eq_factor {
236-
(sum - (EF::ONE - eq_factor[0]) * p_evals[0].1) / eq_factor[0]
237-
} else {
238-
sum - p_evals[0].1
239-
};
240-
p_evals.push((PF::<EF>::from_usize(1), p_at_1));
241-
}
223+
sum - p_evals[0]
224+
};
225+
p_evals.insert(1, p_at_1);
242226

243-
let poly = DensePolynomial::lagrange_interpolation(&p_evals).unwrap();
227+
let poly = DensePolynomial::lagrange_interpolation(
228+
&p_evals
229+
.iter()
230+
.enumerate()
231+
.map(|(i, &val)| (PF::<EF>::from_usize(i), val))
232+
.collect::<Vec<_>>(),
233+
)
234+
.unwrap();
244235
let eq_alpha = eq_factor.as_ref().map(|(p, _)| p[0]);
245236
prover_state.add_sumcheck_polynomial(&poly.coeffs, eq_alpha);
246237
poly

0 commit comments

Comments
 (0)