11use std ::array::map ;
2- use std ::array::len ;
32use std ::check::assert ;
43use std ::check::panic ;
54use std ::math::fp2::Fp2 ;
@@ -14,6 +13,8 @@ use std::math::fp2::eval_ext;
1413use std ::math::fp2::from_base ;
1514use std ::math::fp2::fp2_from_array ;
1615use std ::math::fp2::constrain_eq_ext ;
16+ use std ::math::fp2::required_extension_size ;
17+ use std ::math::fp2::needs_extension ;
1718use std ::protocols::fingerprint::fingerprint ;
1819use std ::utils::unwrap_or_else ;
1920
@@ -53,16 +54,9 @@ let compute_next_z: Fp2<expr>, Fp2<expr>, Fp2<expr>, Constr -> fe[] = query |acc
5354} ;
5455
5556/// Returns constraints th at enforce th at lhs is a permutation of rhs
56- ///
57- /// # Arguments:
58- /// - acc: A phase - 2 witness column to be used as the accumulator. If 2 are provided , computations
59- /// are done on the F_{p^ 2 } extension field.
60- /// - alpha: A challenge used to compress the LHS and RHS values
61- /// - beta: A challenge used to update the accumulator
62- /// - permutation_constraint: The permutation constraint
63- ///
64- /// # Returns:
65- /// - Constraints to be added to enforce the permutation
57+ /// WARNING: This function can currently not be used multiple times since
58+ /// the used challenges would overlap
59+ /// TODO: Implement this for an array of constraints
6660///
6761/// # Implementation:
6862/// This function implements a permutation argument described e.g. in
@@ -79,7 +73,12 @@ let compute_next_z: Fp2<expr>, Fp2<expr>, Fp2<expr>, Constr -> fe[] = query |acc
7973/// the wrapping behavior: The first accumulator is constrained to be 1 , and the last
8074/// accumulator is the same as the first one , because of wrapping.
8175/// For small fields , this computation should happen in the extension field.
82- let permutation: expr [], Fp2<expr> , Fp2<expr> , Constr - > () = constr |acc , alpha , beta , permutation_constraint| {
76+ let permutation: Constr - > () = constr |permutation_constraint| {
77+ std ::check::assert(required_extension_size() <= 2 , || "Invalid extension size" ) ;
78+ // Alpha is used to compress the LHS and RHS arrays
79+ let alpha = fp2_from_array( std ::array::new(required_extension_size() , |i| challenge( 0 , i + 1 ))) ;
80+ // Beta is used to update the accumulator
81+ let beta = fp2_from_array( std ::array::new(required_extension_size() , |i| challenge( 0 , i + 3 ))) ;
8382
8483 let (lhs_selector , lhs , rhs_selector , rhs) = unpack_permutation_constraint(permutation_constraint) ;
8584
@@ -88,6 +87,8 @@ let permutation: expr[], Fp2<expr>, Fp2<expr>, Constr -> () = constr |acc, alpha
8887 // Implemented as: folded = selector * (beta - fingerprint(values) - 1 ) + 1 ;
8988 let lhs_folded = selected_or_one(lhs_selector , sub_ext(beta , fingerprint(lhs , alpha))) ;
9089 let rhs_folded = selected_or_one(rhs_selector , sub_ext(beta , fingerprint(rhs , alpha))) ;
90+
91+ let acc = std ::array::new(required_extension_size() , |i| std ::prover::new_witness_col_at_stage( "acc" , 1 )) ;
9192 let acc_ext = fp2_from_array(acc) ;
9293 let next_acc = next_ext(acc_ext) ;
9394
@@ -108,4 +109,21 @@ let permutation: expr[], Fp2<expr>, Fp2<expr>, Constr -> () = constr |acc, alpha
108109 is_first * (acc_1 - 1 ) = 0 ;
109110 is_first * acc_2 = 0 ;
110111 constrain_eq_ext(update_expr , from_base( 0 )) ;
112+
113+ // In the extension field , we need a prover function for the accumulator.
114+ if needs_extension() {
115+ // TODO: Helper columns , because we can't access the previous row in hints
116+ let acc_next_col = std ::array::map(acc , |_| std ::prover::new_witness_col_at_stage( "acc_next" , 1 )) ;
117+ query |i| {
118+ let _ = std ::array::zip(
119+ acc_next_col ,
120+ compute_next_z(acc_ext , alpha , beta , permutation_constraint) ,
121+ |acc_next , hint_val| std ::prover::provide_value(acc_next , i , hint_val)
122+ ) ;
123+ } ;
124+ std ::array::zip(acc , acc_next_col , |acc_col , acc_next| {
125+ acc_col' = acc_next
126+ }) ;
127+ } else {
128+ }
111129} ;
0 commit comments