@@ -5,7 +5,9 @@ use crate::{
55 exts_to_felts,
66 } ,
77 tower_verifier:: binding:: IOPProverMessageVecVariable ,
8- transcript:: transcript_observe_label,
8+ transcript:: {
9+ transcript_label_as_array, transcript_observe_label, transcript_observe_label_felts,
10+ } ,
911 zkvm_verifier:: binding:: TowerProofInputVariable ,
1012} ;
1113use openvm_native_compiler:: prelude:: * ;
@@ -22,51 +24,84 @@ pub fn iop_verifier_state_verify<C: Config>(
2224 out_claim : & Ext < C :: F , C :: EF > ,
2325 prover_messages : & IOPProverMessageVecVariable < C > ,
2426 max_num_variables : Felt < C :: F > ,
25- max_degree : Felt < C :: F > ,
27+ max_degree : usize ,
2628 unipoly_extrapolator : & UniPolyExtrapolator < C > ,
2729) -> (
2830 Array < C , Ext < <C as Config >:: F , <C as Config >:: EF > > ,
2931 Ext < <C as Config >:: F , <C as Config >:: EF > ,
3032) {
31- // TODO: either store it in a global cache or pass them as parameters
32- let zero: Ext < C :: F , C :: EF > = builder. constant ( C :: EF :: ZERO ) ;
33- let zero_f: Felt < C :: F > = builder. constant ( C :: F :: ZERO ) ;
34-
33+ let max_degree_felt: Felt < C :: F > = builder. constant ( C :: F :: from_canonical_usize ( max_degree) ) ;
3534 let max_num_variables_usize: Usize < C :: N > =
3635 Usize :: from ( builder. cast_felt_to_var ( max_num_variables) ) ;
37- challenger. observe ( builder, max_num_variables) ;
38- challenger. observe ( builder, zero_f) ;
39- challenger. observe ( builder, max_degree) ;
40- challenger. observe ( builder, zero_f) ;
36+ let pre_verified_integrity_data: Array < C , Felt < C :: F > > = builder. dyn_array ( 4 ) ;
37+ // Prover and verifier currently agree on how `usize` values are serialized.
38+ // On a 64-bit platform, a `usize` spans 64 bits, so it is represented
39+ // as two ordered `u32` Felts.
40+ //
41+ // `max_num_variables` occupies the first Felt,
42+ // with the second Felt padded with 0. The same layout applies to `max_degree`.
43+ //
44+ // TODO fix to single u32
45+ builder. set_value ( & pre_verified_integrity_data, 0 , max_num_variables) ;
46+ builder. set_value ( & pre_verified_integrity_data, 2 , max_degree_felt) ;
47+ challenger_multi_observe ( builder, challenger, & pre_verified_integrity_data) ;
4148
4249 builder. assert_var_eq ( max_num_variables_usize. get_var ( ) , prover_messages. len ( ) ) ;
4350
4451 let challenges: Array < C , Ext < C :: F , C :: EF > > = builder. dyn_array ( max_num_variables_usize. clone ( ) ) ;
45- let expected: Ext < C :: F , C :: EF > = builder. eval ( * out_claim + zero) ;
52+ let expected: Ext < C :: F , C :: EF > = builder. eval ( * out_claim) ;
53+ let internal_round_label = transcript_label_as_array ( builder, b"Internal round" ) ;
4654
4755 builder. cycle_tracker_start ( "IOPVerifierState::verify_round_and_update_state" ) ;
56+ let curr_offset: Var < C :: N > = builder. eval ( C :: N :: ZERO ) ;
4857 builder
4958 . range ( 0 , max_num_variables_usize. clone ( ) )
5059 . for_each ( |i_vec, builder| {
5160 let i = i_vec[ 0 ] ;
5261
53- // TODO: this takes 7 cycles, can we optimize it?
54- let prover_msg = prover_messages. get ( builder, i. variable ( ) ) ;
62+ let next_offset: Var < C :: N > =
63+ builder. eval ( curr_offset + prover_messages. prover_message_size ) ;
64+ let prover_msg = prover_messages
65+ . evaluations
66+ . slice ( builder, curr_offset, next_offset) ;
67+ builder. assign ( & curr_offset, next_offset) ;
5568
5669 unsafe {
5770 let prover_msg_felts = exts_to_felts ( builder, & prover_msg) ;
5871 challenger_multi_observe ( builder, challenger, & prover_msg_felts) ;
5972 }
6073
61- transcript_observe_label ( builder, challenger, b"Internal round" ) ;
74+ transcript_observe_label_felts ( builder, challenger, & internal_round_label ) ;
6275 let challenge = challenger. sample_ext ( builder) ;
6376
6477 let e1 = builder. get ( & prover_msg, 0 ) ;
6578 let e0 = builder. eval ( expected - e1) ;
66- let p_r =
67- unipoly_extrapolator. extrapolate_uni_poly ( builder, e0, & prover_msg, challenge) ;
68-
69- builder. assign ( & expected, p_r + zero) ;
79+ let p_r = match max_degree {
80+ 1 => unipoly_extrapolator. extrapolate_uni_poly_deg_1 ( builder, e0, e1, challenge) ,
81+ 2 => {
82+ let p1 = e1;
83+ let p2 = builder. get ( & prover_msg, 1 ) ;
84+ unipoly_extrapolator. extrapolate_uni_poly_deg_2 ( builder, e0, p1, p2, challenge)
85+ }
86+ 3 => {
87+ let p1 = e1;
88+ let p2 = builder. get ( & prover_msg, 1 ) ;
89+ let p3 = builder. get ( & prover_msg, 2 ) ;
90+ unipoly_extrapolator
91+ . extrapolate_uni_poly_deg_3 ( builder, e0, p1, p2, p3, challenge)
92+ }
93+ 4 => {
94+ let p1 = e1;
95+ let p2 = builder. get ( & prover_msg, 1 ) ;
96+ let p3 = builder. get ( & prover_msg, 2 ) ;
97+ let p4 = builder. get ( & prover_msg, 3 ) ;
98+ unipoly_extrapolator
99+ . extrapolate_uni_poly_deg_4 ( builder, e0, p1, p2, p3, p4, challenge)
100+ }
101+ _ => panic ! ( "unsupported max_degree {max_degree}" ) ,
102+ } ;
103+
104+ builder. assign ( & expected, p_r) ;
70105 builder. set_value ( & challenges, i, challenge) ;
71106 } ) ;
72107 builder. cycle_tracker_end ( "IOPVerifierState::verify_round_and_update_state" ) ;
@@ -258,16 +293,14 @@ pub fn verify_tower_proof<C: Config>(
258293 let max_num_variables: Felt < C :: F > = builder. constant ( C :: F :: ONE ) ;
259294 builder. assign ( & max_num_variables, max_num_variables + round) ;
260295
261- let max_degree = builder. constant ( C :: F :: from_canonical_usize ( 3 ) ) ;
262-
263296 builder. cycle_tracker_start ( "sumcheck verify" ) ;
264297 let ( sub_rt, sub_e) = iop_verifier_state_verify (
265298 builder,
266299 challenger,
267300 out_claim,
268301 & prover_messages,
269302 max_num_variables,
270- max_degree ,
303+ 3 ,
271304 unipoly_extrapolator,
272305 ) ;
273306 builder. cycle_tracker_end ( "sumcheck verify" ) ;
0 commit comments