1use super::*;
2use crypto_primitives::{ConstIntSemiring, FromPrimitiveWithConfig, FromWithConfig};
3use num_traits::Zero;
4use std::{collections::HashMap, fmt::Debug};
5use zinc_piop::{
6 combined_poly_resolver::CombinedPolyResolver,
7 ideal_check::IdealCheckProtocol,
8 multipoint_eval::{MultipointEval, Proof as MultipointEvalProof},
9 projections::{
10 ColumnMajorTrace, ProjectedTrace, RowMajorTrace, evaluate_trace_to_column_mles,
11 project_scalars, project_scalars_to_field, project_trace_coeffs_column_major,
12 project_trace_coeffs_row_major,
13 },
14 sumcheck::multi_degree::MultiDegreeSumcheck,
15};
16use zinc_poly::univariate::dynamic::over_field::DynamicPolynomialF;
17use zinc_transcript::traits::{ConstTranscribable, Transcript};
18use zinc_uair::{
19 Uair, UairSignature, UairTrace, constraint_counter::count_constraints,
20 degree_counter::count_max_degree,
21};
22use zinc_utils::{
23 add, cfg_join, from_ref::FromRef, inner_transparent_field::InnerTransparentField,
24 mul_by_scalar::MulByScalar, projectable_to_field::ProjectableToField,
25};
26use zip_plus::{
27 pcs::structs::{ZipPlus, ZipPlusHint, ZipPlusParams, ZipTypes},
28 pcs_transcript::PcsProverTranscript,
29};
30
31#[derive(Clone, Debug)]
39pub struct ProverBase<'a, Zt: ZincTypes<D>, U: Uair, F: PrimeField, const D: usize> {
40 num_vars: usize,
41 uair_signature: UairSignature,
42 pcs_transcript: PcsProverTranscript,
43 trace: &'a UairTrace<'static, Zt::Int, Zt::Int, D>,
44
45 pp_bin: &'a ZipPlusParams<Zt::BinaryZt, Zt::BinaryLc>,
47 pp_arb: &'a ZipPlusParams<Zt::ArbitraryZt, Zt::ArbitraryLc>,
48 pp_int: &'a ZipPlusParams<Zt::IntZt, Zt::IntLc>,
49 hint_bin: Option<ZipPlusHint<<Zt::BinaryZt as ZipTypes>::Cw>>,
50 hint_arb: Option<ZipPlusHint<<Zt::ArbitraryZt as ZipTypes>::Cw>>,
51 hint_int: Option<ZipPlusHint<<Zt::IntZt as ZipTypes>::Cw>>,
52 commitment_bin: ZipPlusCommitment,
53 commitment_arb: ZipPlusCommitment,
54 commitment_int: ZipPlusCommitment,
55
56 _phantom: PhantomData<(U, F)>,
57}
58
59#[derive(Clone, Debug)]
66pub struct ProverProjectedCombined<'a, Zt: ZincTypes<D>, U: Uair, F: PrimeField, const D: usize> {
67 base: ProverBase<'a, Zt, U, F, D>,
68 field_cfg: F::Config,
69 projected_trace: RowMajorTrace<F>,
70 projected_scalars_fx: HashMap<U::Scalar, DynamicPolynomialF<F>>,
71}
72
73#[derive(Clone, Debug)]
76pub struct ProverProjectedMleFirst<'a, Zt: ZincTypes<D>, U: Uair, F: PrimeField, const D: usize> {
77 base: ProverBase<'a, Zt, U, F, D>,
78 field_cfg: F::Config,
79 projected_trace: ColumnMajorTrace<F>,
80 projected_scalars_fx: HashMap<U::Scalar, DynamicPolynomialF<F>>,
81}
82
83#[derive(Clone, Debug)]
85pub struct ProverIdealChecked<'a, Zt: ZincTypes<D>, U: Uair, F: PrimeField, const D: usize> {
86 base: ProverBase<'a, Zt, U, F, D>,
87 field_cfg: F::Config,
88 projected_trace: ProjectedTrace<F>,
89 projected_scalars_fx: HashMap<U::Scalar, DynamicPolynomialF<F>>,
90
91 ic_proof: IdealCheckProof<F>,
93 ic_eval_point: Vec<F>,
94}
95
96#[derive(Clone, Debug)]
98pub struct ProverEvalProjected<'a, Zt: ZincTypes<D>, U: Uair, F: PrimeField, const D: usize> {
99 base: ProverBase<'a, Zt, U, F, D>,
100 field_cfg: F::Config,
101 projected_trace: ProjectedTrace<F>,
102 ic_proof: IdealCheckProof<F>,
103 ic_eval_point: Vec<F>,
104
105 projected_trace_f: Vec<DenseMultilinearExtension<F::Inner>>,
107 projected_scalars_f: HashMap<U::Scalar, F>,
108}
109
110#[allow(clippy::type_complexity)]
112#[derive(Clone, Debug)]
113pub struct ProverSumchecked<'a, Zt: ZincTypes<D>, U: Uair, F: PrimeField, const D: usize> {
114 base: ProverBase<'a, Zt, U, F, D>,
115 field_cfg: F::Config,
116 projected_trace: ProjectedTrace<F>,
117 ic_proof: IdealCheckProof<F>,
118 projected_trace_f: Vec<DenseMultilinearExtension<F::Inner>>,
119
120 cpr_proof: CombinedPolyResolverProof<F>,
122 cpr_eval_point: Vec<F>,
123 combined_sumcheck: MultiDegreeSumcheckProof<F>,
124 lookup_proof: Option<BatchedLookupProof<F>>,
125}
126
127#[derive(Clone, Debug)]
129pub struct ProverMultipointEvaled<'a, Zt: ZincTypes<D>, U: Uair, F: PrimeField, const D: usize> {
130 base: ProverBase<'a, Zt, U, F, D>,
131 field_cfg: F::Config,
132 projected_trace: ProjectedTrace<F>,
133 ic_proof: IdealCheckProof<F>,
134 cpr_proof: CombinedPolyResolverProof<F>,
135 combined_sumcheck: MultiDegreeSumcheckProof<F>,
136 lookup_proof: Option<BatchedLookupProof<F>>,
137
138 mp_proof: MultipointEvalProof<F>,
140 r_0: Vec<F>,
141}
142
143#[derive(Clone, Debug)]
145pub struct ProverLifted<'a, Zt: ZincTypes<D>, U: Uair, F: PrimeField, const D: usize> {
146 base: ProverBase<'a, Zt, U, F, D>,
147 field_cfg: F::Config,
148 ic_proof: IdealCheckProof<F>,
149 cpr_proof: CombinedPolyResolverProof<F>,
150 combined_sumcheck: MultiDegreeSumcheckProof<F>,
151 lookup_proof: Option<BatchedLookupProof<F>>,
152 mp_proof: MultipointEvalProof<F>,
153 r_0: Vec<F>,
154
155 lifted_evals: Vec<DynamicPolynomialF<F>>,
157}
158
159#[derive(Clone, Debug)]
164pub struct ProverPcsOpened<'a, Zt: ZincTypes<D>, U: Uair, F: PrimeField, const D: usize> {
165 base: ProverBase<'a, Zt, U, F, D>,
166 ic_proof: IdealCheckProof<F>,
167 cpr_proof: CombinedPolyResolverProof<F>,
168 combined_sumcheck: MultiDegreeSumcheckProof<F>,
169 lookup_proof: Option<BatchedLookupProof<F>>,
170 mp_proof: MultipointEvalProof<F>,
171 lifted_evals: Vec<DynamicPolynomialF<F>>,
172}
173
174macro_rules! impl_with_type_bounds {
181 ($type_name:ident { $($code:tt)* }) => {
182 impl<'a, Zt, U, F, const D: usize> $type_name<'a, Zt, U, F, D>
183 where
184 Zt: ZincTypes<D>,
185 Zt::Int: ProjectableToField<F>,
186 <Zt::ArbitraryZt as ZipTypes>::Eval: ProjectableToField<F>,
187 U: Uair + 'static,
188 F: InnerTransparentField
189 + FromPrimitiveWithConfig
190 + for<'b> FromWithConfig<&'b Zt::Int>
191 + for<'b> FromWithConfig<&'b Zt::CombR>
192 + for<'b> FromWithConfig<&'b Zt::Chal>
193 + for<'b> MulByScalar<&'b F>
194 + FromRef<F>
195 + Send
196 + Sync
197 + 'static,
198 F::Inner:
199 ConstIntSemiring + ConstTranscribable + FromRef<Zt::Fmod> + Send + Sync + Zero + Default,
200 F::Modulus: ConstTranscribable + FromRef<Zt::Fmod>,
201 {
202 $($code)*
203 }
204 };
205}
206
207impl<Zt, U, F, const D: usize> ZincPlusPiop<Zt, U, F, D>
208where
209 Zt: ZincTypes<D>,
210 U: Uair,
211 F: PrimeField,
212 F::Inner: ConstTranscribable,
213{
214 #[allow(clippy::type_complexity)]
218 pub fn step0_commit<'a>(
219 (pp_bin, pp_arb, pp_int): &'a (
220 ZipPlusParams<Zt::BinaryZt, Zt::BinaryLc>,
221 ZipPlusParams<Zt::ArbitraryZt, Zt::ArbitraryLc>,
222 ZipPlusParams<Zt::IntZt, Zt::IntLc>,
223 ),
224 trace: &'a UairTrace<'static, Zt::Int, Zt::Int, D>,
225 num_vars: usize,
226 ) -> Result<ProverBase<'a, Zt, U, F, D>, ProtocolError<F, U::Ideal>> {
227 let uair_signature = U::signature();
228 let public_trace = trace.public(&uair_signature);
229 let witness_trace = trace.witness(&uair_signature);
230
231 let (res_bin, (res_arb, res_int)) = cfg_join!(
232 commit_optionally(pp_bin, &witness_trace.binary_poly),
233 commit_optionally(pp_arb, &witness_trace.arbitrary_poly),
234 commit_optionally(pp_int, &witness_trace.int),
235 );
236 let (hint_bin, commitment_bin) = res_bin?;
237 let (hint_arb, commitment_arb) = res_arb?;
238 let (hint_int, commitment_int) = res_int?;
239
240 let mut pcs_transcript = PcsProverTranscript::new_from_commitments(
241 [&commitment_bin, &commitment_arb, &commitment_int].into_iter(),
242 );
243
244 absorb_public_columns(&mut pcs_transcript.fs_transcript, &public_trace.binary_poly);
245 absorb_public_columns(
246 &mut pcs_transcript.fs_transcript,
247 &public_trace.arbitrary_poly,
248 );
249 absorb_public_columns(&mut pcs_transcript.fs_transcript, &public_trace.int);
250
251 Ok(ProverBase {
252 num_vars,
253 uair_signature,
254 pcs_transcript,
255 trace,
256 pp_bin,
257 pp_arb,
258 pp_int,
259 hint_bin,
260 hint_arb,
261 hint_int,
262 commitment_bin,
263 commitment_arb,
264 commitment_int,
265 _phantom: PhantomData,
266 })
267 }
268}
269
270impl_with_type_bounds!(ProverBase
271{
272 #[allow(clippy::type_complexity)]
273 fn project_common<S: Fn(&U::Scalar, &F::Config) -> DynamicPolynomialF<F>>(
274 &mut self,
275 project_scalar: S,
276 ) -> Result<(F::Config, HashMap<U::Scalar, DynamicPolynomialF<F>>), ProtocolError<F, U::Ideal>>
277 {
278 let field_cfg = self
279 .pcs_transcript
280 .fs_transcript
281 .get_random_field_cfg::<F, Zt::Fmod, Zt::PrimeTest>();
282
283 let projected_scalars_fx = project_scalars::<F, U>(|s| project_scalar(s, &field_cfg));
284 Ok((field_cfg, projected_scalars_fx))
285 }
286
287 pub fn step1_combined<S: Fn(&U::Scalar, &F::Config) -> DynamicPolynomialF<F>>(
292 mut self,
293 project_scalar: S,
294 ) -> Result<ProverProjectedCombined<'a, Zt, U, F, D>, ProtocolError<F, U::Ideal>> {
295 let (field_cfg, projected_scalars_fx) = self.project_common(project_scalar)?;
296
297 let projected_trace = project_trace_coeffs_row_major(self.trace, &field_cfg);
298 Ok(ProverProjectedCombined {
299 base: self,
300 field_cfg,
301 projected_trace,
302 projected_scalars_fx,
303 })
304 }
305
306 pub fn step1_mle_first<S: Fn(&U::Scalar, &F::Config) -> DynamicPolynomialF<F>>(
311 mut self,
312 project_scalar: S,
313 ) -> Result<ProverProjectedMleFirst<'a, Zt, U, F, D>, ProtocolError<F, U::Ideal>> {
314 let (field_cfg, projected_scalars_fx) = self.project_common(project_scalar)?;
315
316 let projected_trace = project_trace_coeffs_column_major(self.trace, &field_cfg);
317 Ok(ProverProjectedMleFirst {
318 base: self,
319 field_cfg,
320 projected_trace,
321 projected_scalars_fx,
322 })
323 }
324});
325
326impl_with_type_bounds!(ProverProjectedCombined
327{
328 pub fn step2_ideal_check(
331 mut self,
332 ) -> Result<ProverIdealChecked<'a, Zt, U, F, D>, ProtocolError<F, U::Ideal>> {
333 let num_constraints = count_constraints::<U>();
334
335 let (ic_proof, ic_prover_state) = U::prove_combined(
336 &mut self.base.pcs_transcript.fs_transcript,
337 &self.projected_trace,
338 &self.projected_scalars_fx,
339 num_constraints,
340 self.base.num_vars,
341 &self.field_cfg,
342 )?;
343
344 Ok(ProverIdealChecked {
345 base: self.base,
346 field_cfg: self.field_cfg,
347 projected_trace: ProjectedTrace::RowMajor(self.projected_trace),
348 projected_scalars_fx: self.projected_scalars_fx,
349 ic_proof,
350 ic_eval_point: ic_prover_state.evaluation_point,
351 })
352 }
353});
354
355impl_with_type_bounds!(ProverProjectedMleFirst
356{
357 pub fn step2_ideal_check(
360 mut self,
361 ) -> Result<ProverIdealChecked<'a, Zt, U, F, D>, ProtocolError<F, U::Ideal>> {
362 let num_constraints = count_constraints::<U>();
363
364 let (ic_proof, ic_prover_state) = U::prove_linear(
365 &mut self.base.pcs_transcript.fs_transcript,
366 &self.projected_trace,
367 &self.projected_scalars_fx,
368 num_constraints,
369 self.base.num_vars,
370 &self.field_cfg,
371 )?;
372
373 Ok(ProverIdealChecked {
374 base: self.base,
375 field_cfg: self.field_cfg,
376 projected_trace: ProjectedTrace::ColumnMajor(self.projected_trace),
377 projected_scalars_fx: self.projected_scalars_fx,
378 ic_proof,
379 ic_eval_point: ic_prover_state.evaluation_point,
380 })
381 }
382});
383
384impl_with_type_bounds!(ProverIdealChecked
385{
386 pub fn step3_eval_projection(
389 mut self,
390 ) -> Result<ProverEvalProjected<'a, Zt, U, F, D>, ProtocolError<F, U::Ideal>> {
391 let projecting_element: Zt::Chal = self.base.pcs_transcript.fs_transcript.get_challenge();
392 let projecting_element_f: F = F::from_with_cfg(&projecting_element, &self.field_cfg);
393
394 let projected_trace_f =
395 evaluate_trace_to_column_mles(&self.projected_trace, &projecting_element_f);
396
397 let projected_scalars_f =
398 project_scalars_to_field(self.projected_scalars_fx, &projecting_element_f)
399 .map_err(|(_s, _f, e)| ProtocolError::ScalarProjection(e))?;
400
401 Ok(ProverEvalProjected {
402 base: self.base,
403 field_cfg: self.field_cfg,
404 projected_trace: self.projected_trace,
405 ic_proof: self.ic_proof,
406 ic_eval_point: self.ic_eval_point,
407 projected_trace_f,
408 projected_scalars_f,
409 })
410 }
411});
412
413impl_with_type_bounds!(ProverEvalProjected
414{
415 pub fn step4_sumcheck(
420 mut self,
421 ) -> Result<ProverSumchecked<'a, Zt, U, F, D>, ProtocolError<F, U::Ideal>> {
422 let num_constraints = count_constraints::<U>();
423 let max_degree = count_max_degree::<U>();
424
425 let (cpr_group, cpr_ancillary) = CombinedPolyResolver::prepare_sumcheck_group::<U>(
426 &mut self.base.pcs_transcript.fs_transcript,
427 self.projected_trace_f.clone(),
428 &self.ic_eval_point,
429 &self.projected_scalars_f,
430 num_constraints,
431 self.base.num_vars,
432 max_degree,
433 &self.field_cfg,
434 )?;
435
436 let lookup_specs = &self.base.uair_signature;
438 let groups = vec![cpr_group];
439 let _ = lookup_specs; let (combined_sumcheck, md_states) = MultiDegreeSumcheck::prove_as_subprotocol(
446 &mut self.base.pcs_transcript.fs_transcript,
447 groups,
448 self.base.num_vars,
449 &self.field_cfg,
450 );
451 let (cpr_proof, cpr_prover_state) = CombinedPolyResolver::finalize_prover(
453 &mut self.base.pcs_transcript.fs_transcript,
454 md_states.into_iter().next().expect("one CPR group"),
455 cpr_ancillary,
456 &self.field_cfg,
457 )?;
458
459 let lookup_proof = None;
461
462 Ok(ProverSumchecked {
463 base: self.base,
464 field_cfg: self.field_cfg,
465 projected_trace: self.projected_trace,
466 ic_proof: self.ic_proof,
467 projected_trace_f: self.projected_trace_f,
468 cpr_proof,
469 cpr_eval_point: cpr_prover_state.evaluation_point,
470 combined_sumcheck,
471 lookup_proof,
472 })
473 }
474});
475
476impl_with_type_bounds!(ProverSumchecked
477{
478 pub fn step5_multipoint_eval(
483 mut self,
484 ) -> Result<ProverMultipointEvaled<'a, Zt, U, F, D>, ProtocolError<F, U::Ideal>> {
485 let (mp_proof, mp_prover_state) = MultipointEval::prove_as_subprotocol(
486 &mut self.base.pcs_transcript.fs_transcript,
487 &self.projected_trace_f,
488 &self.cpr_eval_point,
489 &self.cpr_proof.up_evals,
490 &self.cpr_proof.down_evals,
491 self.base.uair_signature.shifts(),
492 &self.field_cfg,
493 )?;
494
495 Ok(ProverMultipointEvaled {
496 base: self.base,
497 field_cfg: self.field_cfg,
498 projected_trace: self.projected_trace,
499 ic_proof: self.ic_proof,
500 cpr_proof: self.cpr_proof,
501 combined_sumcheck: self.combined_sumcheck,
502 lookup_proof: self.lookup_proof,
503 mp_proof,
504 r_0: mp_prover_state.eval_point,
505 })
506 }
507});
508
509impl_with_type_bounds!(ProverMultipointEvaled
510{
511 pub fn step6_lift_and_project(
514 mut self,
515 ) -> Result<ProverLifted<'a, Zt, U, F, D>, ProtocolError<F, U::Ideal>> {
516 let lifted_evals = compute_lifted_evals::<F, D>(
521 &self.r_0,
522 &self.base.trace.binary_poly,
523 &self.projected_trace,
524 &self.field_cfg,
525 );
526
527 let mut transcription_buf: Vec<u8> = vec![0; F::Inner::NUM_BYTES];
528 for bar_u in &lifted_evals {
529 self.base
530 .pcs_transcript
531 .fs_transcript
532 .absorb_random_field_slice(&bar_u.coeffs, &mut transcription_buf);
533 }
534
535 Ok(ProverLifted {
536 base: self.base,
537 field_cfg: self.field_cfg,
538 ic_proof: self.ic_proof,
539 cpr_proof: self.cpr_proof,
540 combined_sumcheck: self.combined_sumcheck,
541 lookup_proof: self.lookup_proof,
542 mp_proof: self.mp_proof,
543 r_0: self.r_0,
544 lifted_evals,
545 })
546 }
547});
548
549impl_with_type_bounds!(ProverLifted
550{
551 pub fn step7_pcs_open<const CHECK_FOR_OVERFLOW: bool>(
553 mut self,
554 ) -> Result<ProverPcsOpened<'a, Zt, U, F, D>, ProtocolError<F, U::Ideal>> {
555 let witness_trace = self.base.trace.witness(&self.base.uair_signature);
556
557 if let Some(hint_bin) = &self.base.hint_bin {
558 let _ = ZipPlus::<Zt::BinaryZt, Zt::BinaryLc>::prove_f::<_, CHECK_FOR_OVERFLOW>(
559 &mut self.base.pcs_transcript,
560 self.base.pp_bin,
561 &witness_trace.binary_poly,
562 &self.r_0,
563 hint_bin,
564 &self.field_cfg,
565 )?;
566 }
567 if let Some(hint_arb) = &self.base.hint_arb {
568 let _ = ZipPlus::<Zt::ArbitraryZt, Zt::ArbitraryLc>::prove_f::<_, CHECK_FOR_OVERFLOW>(
569 &mut self.base.pcs_transcript,
570 self.base.pp_arb,
571 &witness_trace.arbitrary_poly,
572 &self.r_0,
573 hint_arb,
574 &self.field_cfg,
575 )?;
576 }
577 if let Some(hint_int) = &self.base.hint_int {
578 let _ = ZipPlus::<Zt::IntZt, Zt::IntLc>::prove_f::<_, CHECK_FOR_OVERFLOW>(
579 &mut self.base.pcs_transcript,
580 self.base.pp_int,
581 &witness_trace.int,
582 &self.r_0,
583 hint_int,
584 &self.field_cfg,
585 )?;
586 }
587
588 Ok(ProverPcsOpened {
589 base: self.base,
590 ic_proof: self.ic_proof,
591 cpr_proof: self.cpr_proof,
592 combined_sumcheck: self.combined_sumcheck,
593 lookup_proof: self.lookup_proof,
594 mp_proof: self.mp_proof,
595 lifted_evals: self.lifted_evals,
596 })
597 }
598});
599
600impl_with_type_bounds!(ProverPcsOpened
601{
602 pub fn finish(self) -> Result<Proof<F>, ProtocolError<F, U::Ideal>> {
604 let sig = self.base.uair_signature;
605 let zip_proof = self.base.pcs_transcript.stream.into_inner();
606 let commitments = (
607 self.base.commitment_bin,
608 self.base.commitment_arb,
609 self.base.commitment_int,
610 );
611
612 let lifted_evals = self.lifted_evals;
613
614 let pub_cols = sig.public_cols();
616 let num_pub_bin = pub_cols.num_binary_poly_cols();
617 let num_pub_arb = pub_cols.num_arbitrary_poly_cols();
618 let num_pub_int = pub_cols.num_int_cols();
619 let total = sig.total_cols();
620 let num_total_bin = total.num_binary_poly_cols();
621 let num_total_arb = total.num_arbitrary_poly_cols();
622 let witness = sig.witness_cols();
623 let witness_arb_offset = add!(num_total_bin, num_pub_arb);
624 let witness_arb_end = add!(witness_arb_offset, witness.num_arbitrary_poly_cols());
625 let witness_int_offset = add!(add!(num_total_bin, num_total_arb), num_pub_int);
626 let witness_lifted_evals: Vec<_> = lifted_evals[num_pub_bin..num_total_bin]
627 .iter()
628 .chain(&lifted_evals[witness_arb_offset..witness_arb_end])
629 .chain(&lifted_evals[witness_int_offset..])
630 .cloned()
631 .collect();
632
633 Ok(Proof {
634 commitments,
635 ideal_check: self.ic_proof,
636 resolver: self.cpr_proof,
637 combined_sumcheck: self.combined_sumcheck,
638 multipoint_eval: self.mp_proof,
639 zip: zip_proof,
640 witness_lifted_evals,
641 lookup_proof: self.lookup_proof,
642 })
643 }
644});
645
646impl<Zt, U, F, const D: usize> ZincPlusPiop<Zt, U, F, D>
651where
652 Zt: ZincTypes<D>,
653 Zt::Int: ProjectableToField<F>,
654 <Zt::ArbitraryZt as ZipTypes>::Eval: ProjectableToField<F>,
655 F: InnerTransparentField
656 + FromPrimitiveWithConfig
657 + for<'a> FromWithConfig<&'a Zt::Int>
658 + for<'a> FromWithConfig<&'a Zt::CombR>
659 + for<'a> FromWithConfig<&'a Zt::Chal>
660 + for<'a> FromWithConfig<&'a Zt::Pt>
661 + for<'a> MulByScalar<&'a F>
662 + FromRef<F>
663 + Send
664 + Sync
665 + 'static,
666 F::Inner:
667 ConstIntSemiring + ConstTranscribable + FromRef<Zt::Fmod> + Send + Sync + Zero + Default,
668 F::Modulus: ConstTranscribable + FromRef<Zt::Fmod>,
669 U: Uair + 'static,
670{
671 #[allow(clippy::too_many_arguments, clippy::type_complexity)]
677 pub fn prove<const MLE_FIRST: bool, const CHECK_FOR_OVERFLOW: bool>(
678 pp: &(
679 ZipPlusParams<Zt::BinaryZt, Zt::BinaryLc>,
680 ZipPlusParams<Zt::ArbitraryZt, Zt::ArbitraryLc>,
681 ZipPlusParams<Zt::IntZt, Zt::IntLc>,
682 ),
683 trace: &UairTrace<'static, Zt::Int, Zt::Int, D>,
684 num_vars: usize,
685 project_scalar: impl Fn(&U::Scalar, &F::Config) -> DynamicPolynomialF<F>,
686 ) -> Result<Proof<F>, ProtocolError<F, U::Ideal>> {
687 let committed = Self::step0_commit(pp, trace, num_vars)?;
688
689 let ideal_checked = if MLE_FIRST {
690 committed
691 .step1_mle_first(project_scalar)?
692 .step2_ideal_check()?
693 } else {
694 committed
695 .step1_combined(project_scalar)?
696 .step2_ideal_check()?
697 };
698
699 ideal_checked
700 .step3_eval_projection()?
701 .step4_sumcheck()?
702 .step5_multipoint_eval()?
703 .step6_lift_and_project()?
704 .step7_pcs_open::<CHECK_FOR_OVERFLOW>()?
705 .finish()
706 }
707}
708
709#[allow(clippy::type_complexity)]
710fn commit_optionally<Zt: ZipTypes, Lc: LinearCode<Zt>>(
711 pp: &ZipPlusParams<Zt, Lc>,
712 trace: &[DenseMultilinearExtension<Zt::Eval>],
713) -> Result<(Option<ZipPlusHint<Zt::Cw>>, ZipPlusCommitment), ZipError> {
714 if trace.is_empty() {
715 Ok((
716 None,
717 ZipPlusCommitment {
718 root: Default::default(),
719 batch_size: 0,
720 },
721 ))
722 } else {
723 let (hint, commitment) = ZipPlus::commit(pp, trace)?;
724 Ok((Some(hint), commitment))
725 }
726}