@@ -87,44 +87,44 @@ pub fn verify_tower_proof<C: Config>(
8787
8888 proof : & TowerProofInputVariable < C > ,
8989 unipoly_extrapolator : & UniPolyExtrapolator < C > ,
90+ // The number of product and lookup specs is fixed by the verifying key, so
91+ // thread them in explicitly to keep the verifier loops static.
92+ num_prod_specs : usize ,
93+ num_logup_specs : usize ,
9094) -> (
9195 PointVariable < C > ,
9296 Array < C , PointAndEvalVariable < C > > ,
9397 Array < C , PointAndEvalVariable < C > > ,
9498 Array < C , PointAndEvalVariable < C > > ,
9599) {
96- let num_prod_spec = prod_out_evals. len ( ) ;
97- let num_logup_spec = logup_out_evals. len ( ) ;
100+ let num_prod_spec = Usize :: from ( num_prod_specs) ;
101+ let num_logup_spec = Usize :: from ( num_logup_specs) ;
102+ let num_specs_usize = num_prod_specs + num_logup_specs;
98103
99104 let one: Ext < C :: F , C :: EF > = builder. constant ( C :: EF :: ONE ) ;
100105 let zero: Ext < C :: F , C :: EF > = builder. constant ( C :: EF :: ZERO ) ;
101106
102107 builder. assert_usize_eq ( proof. prod_specs_eval . len ( ) , num_prod_spec. clone ( ) ) ;
103- iter_zip ! ( builder, prod_out_evals) . for_each ( |ptr_vec, builder| {
104- let ptr = ptr_vec[ 0 ] ;
105- let evals = builder. iter_ptr_get ( & prod_out_evals, ptr) ;
108+ for idx in 0 ..num_prod_specs {
109+ let evals = builder. get ( & prod_out_evals, Usize :: from ( idx) ) ;
106110 builder. assert_usize_eq ( evals. len ( ) , num_fanin. clone ( ) ) ;
107- } ) ;
111+ }
108112 builder. assert_usize_eq ( proof. logup_specs_eval . len ( ) , num_logup_spec. clone ( ) ) ;
109- iter_zip ! ( builder, logup_out_evals) . for_each ( |ptr_vec, builder| {
110- let ptr = ptr_vec[ 0 ] ;
111- let evals = builder. iter_ptr_get ( logup_out_evals, ptr) ;
113+ for idx in 0 ..num_logup_specs {
114+ let evals = builder. get ( logup_out_evals, Usize :: from ( idx) ) ;
112115 builder. assert_usize_eq ( evals. len ( ) , RVar :: from ( 4 ) ) ;
113- } ) ;
116+ }
114117 builder. assert_usize_eq (
115118 num_variables. len ( ) ,
116119 num_prod_spec. clone ( ) + num_logup_spec. clone ( ) ,
117120 ) ;
118121
119122 let var_zero: Var < C :: N > = builder. constant ( C :: N :: ZERO ) ;
120- let num_specs: Var < C :: N > = builder. eval ( num_prod_spec. get_var ( ) + num_logup_spec. get_var ( ) ) ;
121- let should_skip: Array < C , Var < C :: N > > = builder. dyn_array ( num_specs) ;
122- builder. range ( 0 , num_specs) . for_each ( |i_vec, builder| {
123- let i = i_vec[ 0 ] ;
124-
123+ let should_skip: Array < C , Var < C :: N > > = builder. uninit_fixed_array ( num_specs_usize) ;
124+ for idx in 0 ..num_specs_usize {
125125 // all specs should not be skipped initially
126- builder. set_value ( & should_skip, i , var_zero) ;
127- } ) ;
126+ builder. set_value ( & should_skip, Usize :: from ( idx ) , var_zero) ;
127+ }
128128
129129 transcript_observe_label ( builder, challenger, b"combine subset evals" ) ;
130130 let alpha = challenger. sample_ext ( builder) ;
@@ -139,99 +139,79 @@ pub fn verify_tower_proof<C: Config>(
139139 builder. cycle_tracker_start ( "initial sum" ) ;
140140 let initial_rt: Array < C , Ext < C :: F , C :: EF > > = builder. dyn_array ( log2_num_fanin) ;
141141 transcript_observe_label ( builder, challenger, b"product_sum" ) ;
142- builder
143- . range ( 0 , initial_rt. len ( ) )
144- . for_each ( |idx_vec, builder| {
145- let idx = idx_vec[ 0 ] ;
146- let c = challenger. sample_ext ( builder) ;
147- builder. set_value ( & initial_rt, idx, c) ;
148- } ) ;
142+ for idx in 0 ..log2_num_fanin {
143+ let c = challenger. sample_ext ( builder) ;
144+ builder. set_value ( & initial_rt, Usize :: from ( idx) , c) ;
145+ }
149146
150147 let prod_spec_point_n_eval: Array < C , PointAndEvalVariable < C > > =
151- builder. dyn_array ( num_prod_spec. clone ( ) ) ;
152-
153- iter_zip ! ( builder, prod_out_evals, prod_spec_point_n_eval) . for_each ( |ptr_vec, builder| {
154- let ptr = ptr_vec[ 0 ] ;
155- let evals = builder. iter_ptr_get ( & prod_out_evals, ptr) ;
148+ builder. uninit_fixed_array ( num_prod_specs) ;
149+ for idx in 0 ..num_prod_specs {
150+ let evals = builder. get ( & prod_out_evals, Usize :: from ( idx) ) ;
156151 let e = evaluate_at_point_degree_1 ( builder, & evals, & initial_rt) ;
157- let p_ptr = ptr_vec[ 1 ] ;
158- builder. iter_ptr_set (
152+ builder. set (
159153 & prod_spec_point_n_eval,
160- p_ptr ,
154+ Usize :: from ( idx ) ,
161155 PointAndEvalVariable {
162156 point : PointVariable {
163157 fs : initial_rt. clone ( ) ,
164158 } ,
165159 eval : e,
166160 } ,
167161 ) ;
168- } ) ;
162+ }
169163
170164 let logup_spec_p_point_n_eval: Array < C , PointAndEvalVariable < C > > =
171- builder. dyn_array ( num_logup_spec . clone ( ) ) ;
165+ builder. uninit_fixed_array ( num_logup_specs ) ;
172166 let logup_spec_q_point_n_eval: Array < C , PointAndEvalVariable < C > > =
173- builder. dyn_array ( num_logup_spec. clone ( ) ) ;
174-
175- iter_zip ! (
176- builder,
177- logup_out_evals,
178- logup_spec_p_point_n_eval,
179- logup_spec_q_point_n_eval
180- )
181- . for_each ( |ptr_vec, builder| {
182- let ptr = ptr_vec[ 0 ] ;
183- let evals = builder. iter_ptr_get ( & prod_out_evals, ptr) ;
184-
167+ builder. uninit_fixed_array ( num_logup_specs) ;
168+ for idx in 0 ..num_logup_specs {
169+ let evals = builder. get ( logup_out_evals, Usize :: from ( idx) ) ;
185170 let p_slice = evals. slice ( builder, 0 , 2 ) ;
186171 let q_slice = evals. slice ( builder, 2 , 4 ) ;
187172
188173 let e1 = evaluate_at_point_degree_1 ( builder, & p_slice, & initial_rt) ;
189174 let e2 = evaluate_at_point_degree_1 ( builder, & q_slice, & initial_rt) ;
190175
191- let p_ptr = ptr_vec[ 1 ] ;
192- let q_ptr = ptr_vec[ 2 ] ;
193-
194- builder. iter_ptr_set (
176+ builder. set (
195177 & logup_spec_p_point_n_eval,
196- p_ptr ,
178+ Usize :: from ( idx ) ,
197179 PointAndEvalVariable {
198180 point : PointVariable {
199181 fs : initial_rt. clone ( ) ,
200182 } ,
201183 eval : e1,
202184 } ,
203185 ) ;
204- builder. iter_ptr_set (
186+ builder. set (
205187 & logup_spec_q_point_n_eval,
206- q_ptr ,
188+ Usize :: from ( idx ) ,
207189 PointAndEvalVariable {
208190 point : PointVariable {
209191 fs : initial_rt. clone ( ) ,
210192 } ,
211193 eval : e2,
212194 } ,
213195 ) ;
214- } ) ;
196+ }
215197
216198 let initial_claim: Ext < C :: F , C :: EF > = builder. eval ( zero + zero) ;
217199
218- iter_zip ! ( builder, prod_spec_point_n_eval) . for_each ( |ptr_vec, builder| {
219- let ptr = ptr_vec[ 0 ] ;
220- let prod_eval = builder. iter_ptr_get ( & prod_spec_point_n_eval, ptr) ;
200+ for idx in 0 ..num_prod_specs {
201+ let prod_eval = builder. get ( & prod_spec_point_n_eval, Usize :: from ( idx) ) ;
221202 builder. assign ( & initial_claim, initial_claim + prod_eval. eval * alpha_acc) ;
222203 builder. assign ( & alpha_acc, alpha_acc * alpha) ;
223- } ) ;
204+ }
224205
225- builder
226- . range ( 0 , num_logup_spec. clone ( ) )
227- . for_each ( |i_vec, builder| {
228- let p = builder. get ( & logup_spec_p_point_n_eval, i_vec[ 0 ] ) ;
229- builder. assign ( & initial_claim, initial_claim + p. eval * alpha_acc) ;
230- builder. assign ( & alpha_acc, alpha_acc * alpha) ;
231- let q = builder. get ( & logup_spec_q_point_n_eval, i_vec[ 0 ] ) ;
232- builder. assign ( & initial_claim, initial_claim + q. eval * alpha_acc) ;
233- builder. assign ( & alpha_acc, alpha_acc * alpha) ;
234- } ) ;
206+ for idx in 0 ..num_logup_specs {
207+ let lk_idx = Usize :: from ( idx) ;
208+ let p = builder. get ( & logup_spec_p_point_n_eval, lk_idx. clone ( ) ) ;
209+ builder. assign ( & initial_claim, initial_claim + p. eval * alpha_acc) ;
210+ builder. assign ( & alpha_acc, alpha_acc * alpha) ;
211+ let q = builder. get ( & logup_spec_q_point_n_eval, lk_idx) ;
212+ builder. assign ( & initial_claim, initial_claim + q. eval * alpha_acc) ;
213+ builder. assign ( & alpha_acc, alpha_acc * alpha) ;
214+ }
235215 builder. cycle_tracker_end ( "initial sum" ) ;
236216
237217 let curr_pt = initial_rt. clone ( ) ;
@@ -244,10 +224,9 @@ pub fn verify_tower_proof<C: Config>(
244224 eval : initial_claim,
245225 } ;
246226
247- let next_layer_evals_output_len: Usize < C :: N > = builder
248- . eval ( Usize :: from ( 1 ) + num_prod_spec. clone ( ) + Usize :: from ( 2 ) * num_logup_spec. clone ( ) ) ;
227+ let next_layer_evals_len = 1 + num_prod_specs + 2 * num_logup_specs;
249228 let next_layer_evals: Array < C , Ext < C :: F , C :: EF > > =
250- builder. dyn_array ( next_layer_evals_output_len ) ;
229+ builder. dyn_array ( next_layer_evals_len ) ;
251230
252231 builder. range ( 0 , op_range) . for_each ( |i_vec, builder| {
253232 let round_var = i_vec[ 0 ] ;
@@ -374,49 +353,37 @@ pub fn verify_tower_proof<C: Config>(
374353
375354 builder. if_ne ( op_range, Usize :: from ( 0 ) ) . then ( |builder| {
376355 // update prod_spec and logup_spec evaluations at next_rt
377- let product_evals = {
378- let start: Var < C :: N > = builder. eval ( Usize :: from ( 1 ) ) ;
379- let end: Var < C :: N > = builder. eval ( start + num_prod_spec. clone ( ) ) ;
380- next_layer_evals. slice ( builder, start, end)
381- } ;
382- let logup_evals = {
383- let start: Var < C :: N > = builder. eval ( Usize :: from ( 1 ) + num_prod_spec. clone ( ) ) ;
384- let end: Var < C :: N > = builder. eval ( start + Usize :: from ( 2 ) * num_logup_spec. clone ( ) ) ;
385- next_layer_evals. slice ( builder, start, end)
386- } ;
387-
388- builder
389- . range ( 0 , num_prod_spec. clone ( ) )
390- . for_each ( |i_vec, builder| {
391- let i = i_vec[ 0 ] ;
392- let eval = builder. get ( & product_evals, i) ;
393-
394- let point_and_eval: PointAndEvalVariable < C > = builder. eval ( PointAndEvalVariable {
395- point : next_rt. point . clone ( ) ,
396- eval,
397- } ) ;
398- builder. set_value ( & prod_spec_point_n_eval, i, point_and_eval) ;
356+ let product_evals = next_layer_evals. slice ( builder, 1 , 1 + num_prod_specs) ;
357+ let logup_start = 1 + num_prod_specs;
358+ let logup_evals =
359+ next_layer_evals. slice ( builder, logup_start, logup_start + 2 * num_logup_specs) ;
360+
361+ for idx in 0 ..num_prod_specs {
362+ let eval = builder. get ( & product_evals, Usize :: from ( idx) ) ;
363+
364+ let point_and_eval: PointAndEvalVariable < C > = builder. eval ( PointAndEvalVariable {
365+ point : next_rt. point . clone ( ) ,
366+ eval,
367+ } ) ;
368+ builder. set_value ( & prod_spec_point_n_eval, Usize :: from ( idx) , point_and_eval) ;
369+ }
370+ for idx in 0 ..num_logup_specs {
371+ let lk_idx = Usize :: from ( idx) ;
372+ let q_idx = Usize :: from ( num_logup_specs + idx) ;
373+ let p_eval = builder. get ( & logup_evals, lk_idx. clone ( ) ) ;
374+ let q_eval = builder. get ( & logup_evals, q_idx) ;
375+
376+ let p_eval: PointAndEvalVariable < C > = builder. eval ( PointAndEvalVariable {
377+ point : next_rt. point . clone ( ) ,
378+ eval : p_eval,
399379 } ) ;
400- builder
401- . range ( 0 , num_logup_spec. clone ( ) )
402- . for_each ( |i_vec, builder| {
403- let i = i_vec[ 0 ] ;
404- let p_idx = i;
405- let q_idx: Var < C :: N > = builder. eval ( num_logup_spec. clone ( ) + i) ;
406- let p_eval = builder. get ( & logup_evals, p_idx) ;
407- let q_eval = builder. get ( & logup_evals, q_idx) ;
408-
409- let p_eval: PointAndEvalVariable < C > = builder. eval ( PointAndEvalVariable {
410- point : next_rt. point . clone ( ) ,
411- eval : p_eval,
412- } ) ;
413- let q_eval: PointAndEvalVariable < C > = builder. eval ( PointAndEvalVariable {
414- point : next_rt. point . clone ( ) ,
415- eval : q_eval,
416- } ) ;
417- builder. set_value ( & logup_spec_p_point_n_eval, i, p_eval) ;
418- builder. set_value ( & logup_spec_q_point_n_eval, i, q_eval) ;
380+ let q_eval: PointAndEvalVariable < C > = builder. eval ( PointAndEvalVariable {
381+ point : next_rt. point . clone ( ) ,
382+ eval : q_eval,
419383 } ) ;
384+ builder. set_value ( & logup_spec_p_point_n_eval, lk_idx. clone ( ) , p_eval) ;
385+ builder. set_value ( & logup_spec_q_point_n_eval, lk_idx, q_eval) ;
386+ }
420387 } ) ;
421388
422389 (
0 commit comments