@@ -8,11 +8,11 @@ use p3_circuit::CircuitBuilder;
88use p3_circuit:: op:: { NonPrimitiveOpConfig , NonPrimitiveOpType } ;
99use p3_circuit:: utils:: ColumnsTargets ;
1010use p3_commit:: Pcs ;
11- use p3_field:: { BasedVectorSpace , Field , PrimeCharacteristicRing } ;
11+ use p3_field:: { BasedVectorSpace , PrimeCharacteristicRing } ;
1212use p3_uni_stark:: StarkGenericConfig ;
1313use p3_util:: zip_eq:: zip_eq;
1414
15- use super :: { ObservableCommitment , VerificationError } ;
15+ use super :: { ObservableCommitment , VerificationError , recompose_quotient_from_chunks_circuit } ;
1616use crate :: Target ;
1717use crate :: challenger:: CircuitChallenger ;
1818use crate :: traits:: { Recursive , RecursiveAir , RecursivePcs } ;
@@ -31,6 +31,11 @@ type PcsVerifierParams<SC, InputProof, OpeningProof, Comm> =
3131 > >:: Domain ,
3232 > >:: VerifierParams ;
3333
34+ type PcsDomain < SC > = <<SC as StarkGenericConfig >:: Pcs as Pcs <
35+ <SC as StarkGenericConfig >:: Challenge ,
36+ <SC as StarkGenericConfig >:: Challenger ,
37+ > >:: Domain ;
38+
3439/// Verifies a STARK proof within a circuit.
3540///
3641/// This function adds constraints to the circuit builder that verify a STARK proof.
@@ -205,14 +210,19 @@ where
205210 ) ?;
206211
207212 // Compute quotient polynomial evaluation from chunks
208- let zero = circuit. add_const ( SC :: Challenge :: ZERO ) ;
209- let one = circuit. add_const ( SC :: Challenge :: ONE ) ;
210-
211- let zps =
212- compute_quotient_chunk_products ( circuit, config, & quotient_chunks_domains, zeta, one, pcs) ;
213-
214- let quotient =
215- compute_quotient_evaluation :: < SC > ( circuit, opened_quotient_chunks_targets, & zps, zero) ;
213+ let quotient = recompose_quotient_from_chunks_circuit :: <
214+ SC ,
215+ InputProof ,
216+ OpeningProof ,
217+ Comm ,
218+ PcsDomain < SC > ,
219+ > (
220+ circuit,
221+ & quotient_chunks_domains,
222+ opened_quotient_chunks_targets,
223+ zeta,
224+ pcs,
225+ ) ;
216226
217227 // Evaluate AIR constraints at out-of-domain point
218228 let sels = pcs. selectors_at_point_circuit ( circuit, & init_trace_domain, & zeta) ;
@@ -349,119 +359,3 @@ where
349359
350360 Ok ( ( ) )
351361}
352-
353- /// Compute the product terms for quotient chunk reconstruction.
354- ///
355- /// For each chunk i, computes: ∏_{j≠i} (Z_{domain_j}(zeta) / Z_{domain_j}(first_point_i))
356- fn compute_quotient_chunk_products <
357- SC : StarkGenericConfig ,
358- InputProof : Recursive < SC :: Challenge > ,
359- OpeningProof : Recursive < SC :: Challenge > ,
360- Comm : Recursive < SC :: Challenge > ,
361- Domain : Copy ,
362- > (
363- circuit : & mut CircuitBuilder < SC :: Challenge > ,
364- config : & SC ,
365- quotient_chunks_domains : & [ Domain ] ,
366- zeta : Target ,
367- one : Target ,
368- pcs : & <SC as StarkGenericConfig >:: Pcs ,
369- ) -> Vec < Target >
370- where
371- <SC as StarkGenericConfig >:: Pcs : RecursivePcs < SC , InputProof , OpeningProof , Comm , Domain > ,
372- {
373- quotient_chunks_domains
374- . iter ( )
375- . enumerate ( )
376- . map ( |( i, domain) | {
377- quotient_chunks_domains
378- . iter ( )
379- . enumerate ( )
380- . filter ( |( j, _) | * j != i)
381- . fold ( one, |total, ( _, other_domain) | {
382- let vp_zeta =
383- vanishing_poly_at_point_circuit ( config, * other_domain, zeta, circuit) ;
384-
385- let first_point = circuit. add_const ( pcs. first_point ( domain) ) ;
386- let vp_first_point = vanishing_poly_at_point_circuit (
387- config,
388- * other_domain,
389- first_point,
390- circuit,
391- ) ;
392- let div = circuit. div ( vp_zeta, vp_first_point) ;
393-
394- circuit. mul ( total, div)
395- } )
396- } )
397- . collect_vec ( )
398- }
399-
400- /// Compute the quotient polynomial evaluation from chunks.
401- ///
402- /// quotient(zeta) = ∑_i (∑_j e_j · chunk_i[j]) · zps[i]
403- fn compute_quotient_evaluation < SC : StarkGenericConfig > (
404- circuit : & mut CircuitBuilder < SC :: Challenge > ,
405- opened_quotient_chunks : & [ Vec < Target > ] ,
406- zps : & [ Target ] ,
407- zero : Target ,
408- ) -> Target
409- where
410- SC :: Challenge : PrimeCharacteristicRing ,
411- {
412- opened_quotient_chunks
413- . iter ( )
414- . enumerate ( )
415- . fold ( zero, |quotient, ( i, chunk) | {
416- let zp = zps[ i] ;
417-
418- // Sum chunk elements weighted by basis elements: ∑_j e_j · chunk[j]
419- let inner_result = chunk. iter ( ) . enumerate ( ) . fold ( zero, |cur_s, ( e_i, c) | {
420- let e_i_target = circuit. add_const ( SC :: Challenge :: ith_basis_element ( e_i) . unwrap ( ) ) ;
421- let inner_mul = circuit. mul ( e_i_target, * c) ;
422- circuit. add ( cur_s, inner_mul)
423- } ) ;
424-
425- let mul = circuit. mul ( inner_result, zp) ;
426- circuit. add ( quotient, mul)
427- } )
428- }
429-
430- /// Compute the vanishing polynomial Z_H(point) = point^n - 1 at a given point.
431- ///
432- /// # Parameters
433- /// - `config`: STARK configuration
434- /// - `domain`: The domain (defines n)
435- /// - `point`: The evaluation point
436- /// - `circuit`: Circuit builder
437- ///
438- /// # Returns
439- /// Target representing Z_H(point)
440- fn vanishing_poly_at_point_circuit <
441- SC : StarkGenericConfig ,
442- InputProof : Recursive < SC :: Challenge > ,
443- OpeningProof : Recursive < SC :: Challenge > ,
444- Comm : Recursive < SC :: Challenge > ,
445- Domain ,
446- > (
447- config : & SC ,
448- domain : Domain ,
449- point : Target ,
450- circuit : & mut CircuitBuilder < SC :: Challenge > ,
451- ) -> Target
452- where
453- <SC as StarkGenericConfig >:: Pcs : RecursivePcs < SC , InputProof , OpeningProof , Comm , Domain > ,
454- {
455- let pcs = config. pcs ( ) ;
456-
457- // Normalize point: point' = point / first_point
458- let inv = circuit. add_const ( pcs. first_point ( & domain) . inverse ( ) ) ;
459- let mul = circuit. mul ( point, inv) ;
460-
461- // Compute (point')^n
462- let exp = circuit. exp_power_of_2 ( mul, pcs. log_size ( & domain) ) ;
463-
464- // Return (point')^n - 1
465- let one = circuit. add_const ( SC :: Challenge :: ONE ) ;
466- circuit. sub ( exp, one)
467- }
0 commit comments