1
1
use crate :: tower_verifier:: binding:: PointAndEvalVariable ;
2
- use crate :: zkvm_verifier:: binding:: ZKVMOpcodeProofInputVariable ;
3
- use ceno_mle:: expression :: { Expression , Fixed , Instance } ;
2
+ use crate :: zkvm_verifier:: binding:: ZKVMChipProofInputVariable ;
3
+ use ceno_mle:: { Expression , Fixed , Instance } ;
4
4
use ceno_zkvm:: structs:: { ChallengeId , WitnessId } ;
5
5
use ff_ext:: ExtensionField ;
6
6
use ff_ext:: { BabyBearExt4 , SmallField } ;
@@ -41,10 +41,6 @@ pub unsafe fn exts_to_felts<C: Config>(
41
41
builder : & mut Builder < C > ,
42
42
exts : & Array < C , Ext < C :: F , C :: EF > > ,
43
43
) -> Array < C , Felt < C :: F > > {
44
- assert ! (
45
- matches!( exts, Array :: Dyn ( _, _) ) ,
46
- "Expected dynamic array of Exts"
47
- ) ;
48
44
let f_len: Usize < C :: N > = builder. eval ( exts. len ( ) * Usize :: from ( C :: EF :: D ) ) ;
49
45
let f_arr: Array < C , Felt < C :: F > > = Array :: Dyn ( exts. ptr ( ) , f_len) ;
50
46
f_arr
@@ -101,6 +97,23 @@ pub fn evaluate_at_point_degree_1<C: Config>(
101
97
builder. eval ( r * ( right - left) + left)
102
98
}
103
99
100
+ pub fn fixed_dot_product < C : Config > (
101
+ builder : & mut Builder < C > ,
102
+ a : & [ Ext < C :: F , C :: EF > ] ,
103
+ b : & Array < C , Ext < C :: F , C :: EF > > ,
104
+ zero : Ext < C :: F , C :: EF > ,
105
+ ) -> Ext < <C as Config >:: F , <C as Config >:: EF > {
106
+ // simple trick to prefer AddE(1 cycle) than AddEI(4 cycles)
107
+ let acc: Ext < C :: F , C :: EF > = builder. eval ( zero + zero) ;
108
+
109
+ for ( i, va) in a. iter ( ) . enumerate ( ) {
110
+ let vb = builder. get ( b, i) ;
111
+ builder. assign ( & acc, acc + * va * vb) ;
112
+ }
113
+
114
+ acc
115
+ }
116
+
104
117
pub struct PolyEvaluator < C : Config > {
105
118
powers_of_2 : Array < C , Usize < C :: N > > ,
106
119
}
@@ -191,19 +204,20 @@ pub fn dot_product<C: Config>(
191
204
acc
192
205
}
193
206
194
- pub fn fixed_dot_product < C : Config > (
207
+ pub fn dot_product_pt_n_eval < C : Config > (
195
208
builder : & mut Builder < C > ,
196
- a : & [ Ext < C :: F , C :: EF > ] ,
209
+ pt_and_eval : & Array < C , PointAndEvalVariable < C > > ,
197
210
b : & Array < C , Ext < C :: F , C :: EF > > ,
198
- zero : Ext < C :: F , C :: EF > ,
199
211
) -> Ext < <C as Config >:: F , <C as Config >:: EF > {
200
- // simple trick to prefer AddE(1 cycle) than AddEI(4 cycles)
201
- let acc: Ext < C :: F , C :: EF > = builder. eval ( zero + zero) ;
202
-
203
- for ( i, va) in a. iter ( ) . enumerate ( ) {
204
- let vb = builder. get ( b, i) ;
205
- builder. assign ( & acc, acc + * va * vb) ;
206
- }
212
+ let acc: Ext < C :: F , C :: EF > = builder. eval ( C :: F :: ZERO ) ;
213
+
214
+ iter_zip ! ( builder, pt_and_eval, b) . for_each ( |idx_vec, builder| {
215
+ let ptr_a = idx_vec[ 0 ] ;
216
+ let ptr_b = idx_vec[ 1 ] ;
217
+ let v_a = builder. iter_ptr_get ( & pt_and_eval, ptr_a) ;
218
+ let v_b = builder. iter_ptr_get ( & b, ptr_b) ;
219
+ builder. assign ( & acc, acc + v_a. eval * v_b) ;
220
+ } ) ;
207
221
208
222
acc
209
223
}
@@ -281,6 +295,32 @@ pub fn eq_eval<C: Config>(
281
295
acc
282
296
}
283
297
298
+ // Evaluate eq polynomial.
299
+ pub fn eq_eval_with_index < C : Config > (
300
+ builder : & mut Builder < C > ,
301
+ x : & Array < C , Ext < C :: F , C :: EF > > ,
302
+ y : & Array < C , Ext < C :: F , C :: EF > > ,
303
+ xlo : Usize < C :: N > ,
304
+ ylo : Usize < C :: N > ,
305
+ len : Usize < C :: N > ,
306
+ ) -> Ext < C :: F , C :: EF > {
307
+ let acc: Ext < C :: F , C :: EF > = builder. constant ( C :: EF :: ONE ) ;
308
+
309
+ builder. range ( 0 , len) . for_each ( |i_vec, builder| {
310
+ let i = i_vec[ 0 ] ;
311
+ let ptr_x: Var < C :: N > = builder. eval ( xlo. clone ( ) + i) ;
312
+ let ptr_y: Var < C :: N > = builder. eval ( ylo. clone ( ) + i) ;
313
+ let v_x = builder. get ( & x, ptr_x) ;
314
+ let v_y = builder. get ( & y, ptr_y) ;
315
+ let xi_yi: Ext < C :: F , C :: EF > = builder. eval ( v_x * v_y) ;
316
+ let one: Ext < C :: F , C :: EF > = builder. constant ( C :: EF :: ONE ) ;
317
+ let new_acc: Ext < C :: F , C :: EF > = builder. eval ( acc * ( xi_yi + xi_yi - v_x - v_y + one) ) ;
318
+ builder. assign ( & acc, new_acc) ;
319
+ } ) ;
320
+
321
+ acc
322
+ }
323
+
284
324
// Multiply all elements in the Array
285
325
pub fn product < C : Config > (
286
326
builder : & mut Builder < C > ,
@@ -327,21 +367,29 @@ pub fn sum<C: Config>(
327
367
acc
328
368
}
329
369
330
- // Extend an array by one element
331
- pub fn extend < C : Config > (
370
+ // Join two arrays
371
+ pub fn join < C : Config > (
332
372
builder : & mut Builder < C > ,
333
- arr : & Array < C , Ext < C :: F , C :: EF > > ,
334
- elem : & Ext < C :: F , C :: EF > ,
373
+ a : & Array < C , Ext < C :: F , C :: EF > > ,
374
+ b : & Array < C , Ext < C :: F , C :: EF > > ,
335
375
) -> Array < C , Ext < C :: F , C :: EF > > {
336
- let new_len: Var < C :: N > = builder. eval ( arr. len ( ) + C :: N :: ONE ) ;
337
- let out = builder. dyn_array ( new_len) ;
376
+ let a_len = a. len ( ) ;
377
+ let b_len = b. len ( ) ;
378
+ let out_len = builder. eval_expr ( a_len. clone ( ) + b_len. clone ( ) ) ;
379
+ let out = builder. dyn_array ( out_len) ;
338
380
339
- builder. range ( 0 , arr . len ( ) ) . for_each ( |i_vec, builder| {
381
+ builder. range ( 0 , a_len . clone ( ) ) . for_each ( |i_vec, builder| {
340
382
let i = i_vec[ 0 ] ;
341
- let val = builder. get ( arr, i) ;
342
- builder. set_value ( & out, i, val) ;
383
+ let a_val = builder. get ( a, i) ;
384
+ builder. set ( & out, i, a_val) ;
385
+ } ) ;
386
+
387
+ builder. range ( 0 , b_len) . for_each ( |i_vec, builder| {
388
+ let b_i = i_vec[ 0 ] ;
389
+ let i = builder. eval_expr ( b_i + a_len. clone ( ) ) ;
390
+ let b_val = builder. get ( b, b_i) ;
391
+ builder. set ( & out, i, b_val) ;
343
392
} ) ;
344
- builder. set_value ( & out, arr. len ( ) , elem. clone ( ) ) ;
345
393
346
394
out
347
395
}
@@ -374,7 +422,7 @@ pub fn gen_alpha_pows<C: Config>(
374
422
pub fn eq_eval_less_or_equal_than < C : Config > (
375
423
builder : & mut Builder < C > ,
376
424
_challenger : & mut DuplexChallengerVariable < C > ,
377
- opcode_proof : & ZKVMOpcodeProofInputVariable < C > ,
425
+ opcode_proof : & ZKVMChipProofInputVariable < C > ,
378
426
a : & Array < C , Ext < C :: F , C :: EF > > ,
379
427
b : & Array < C , Ext < C :: F , C :: EF > > ,
380
428
) -> Ext < C :: F , C :: EF > {
@@ -471,6 +519,35 @@ pub fn build_eq_x_r_vec_sequential<C: Config>(
471
519
evals
472
520
}
473
521
522
+ pub fn build_eq_x_r_vec_sequential_with_offset < C : Config > (
523
+ builder : & mut Builder < C > ,
524
+ r : & Array < C , Ext < C :: F , C :: EF > > ,
525
+ offset : Usize < C :: N > ,
526
+ ) -> Array < C , Ext < C :: F , C :: EF > > {
527
+ // we build eq(x,r) from its evaluations
528
+ // we want to evaluate eq(x,r) over x \in {0, 1}^num_vars
529
+ // for example, with num_vars = 4, x is a binary vector of 4, then
530
+ // 0 0 0 0 -> (1-r0) * (1-r1) * (1-r2) * (1-r3)
531
+ // 1 0 0 0 -> r0 * (1-r1) * (1-r2) * (1-r3)
532
+ // 0 1 0 0 -> (1-r0) * r1 * (1-r2) * (1-r3)
533
+ // 1 1 0 0 -> r0 * r1 * (1-r2) * (1-r3)
534
+ // ....
535
+ // 1 1 1 1 -> r0 * r1 * r2 * r3
536
+ // we will need 2^num_var evaluations
537
+
538
+ let r_len: Var < C :: N > = builder. eval ( r. len ( ) - offset) ;
539
+ let evals_len: Felt < C :: F > = builder. constant ( C :: F :: ONE ) ;
540
+ let evals_len = builder. exp_power_of_2_v :: < Felt < C :: F > > ( evals_len, r_len) ;
541
+ let evals_len = builder. cast_felt_to_var ( evals_len) ;
542
+
543
+ let evals: Array < C , Ext < C :: F , C :: EF > > = builder. dyn_array ( evals_len) ;
544
+ // _debug
545
+ // build_eq_x_r_helper_sequential_offset(r, &mut evals, E::ONE);
546
+ // unsafe { std::mem::transmute(evals) }
547
+ // FIXME: this function is not implemented yet
548
+ evals
549
+ }
550
+
474
551
pub fn ceil_log2 ( x : usize ) -> usize {
475
552
assert ! ( x > 0 , "ceil_log2: x must be positive" ) ;
476
553
// Calculate the number of bits in usize
@@ -829,7 +906,7 @@ impl<C: Config> UniPolyExtrapolator<C> {
829
906
p_i : & Array < C , Ext < C :: F , C :: EF > > ,
830
907
eval_at : Ext < C :: F , C :: EF > ,
831
908
) -> Ext < C :: F , C :: EF > {
832
- let res: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 0 ] + self . constants [ 0 ] ) ;
909
+ let res: Ext < C :: F , C :: EF > = builder. constant ( C :: EF :: ZERO ) ;
833
910
834
911
builder. if_eq ( p_i. len ( ) , Usize :: from ( 4 ) ) . then_or_else (
835
912
|builder| {
@@ -884,8 +961,8 @@ impl<C: Config> UniPolyExtrapolator<C> {
884
961
let p_i_0 = builder. get ( p_i, 0 ) ;
885
962
let p_i_1 = builder. get ( p_i, 1 ) ;
886
963
887
- let t0: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 5 ] * p_i_0 / d0) ;
888
- let t1: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 1 ] * p_i_1 / d1) ;
964
+ let t0: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 5 ] * p_i_0 * d0. inverse ( ) ) ;
965
+ let t1: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 1 ] * p_i_1 * d1. inverse ( ) ) ;
889
966
890
967
builder. eval ( l * ( t0 + t1) )
891
968
}
@@ -909,9 +986,9 @@ impl<C: Config> UniPolyExtrapolator<C> {
909
986
let p_i_1: Ext < C :: F , C :: EF > = builder. get ( p_i, 1 ) ;
910
987
let p_i_2: Ext < C :: F , C :: EF > = builder. get ( p_i, 2 ) ;
911
988
912
- let t0: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 6 ] * p_i_0 / d0) ;
913
- let t1: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 5 ] * p_i_1 / d1) ;
914
- let t2: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 6 ] * p_i_2 / d2) ;
989
+ let t0: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 6 ] * p_i_0 * d0. inverse ( ) ) ;
990
+ let t1: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 5 ] * p_i_1 * d1. inverse ( ) ) ;
991
+ let t2: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 6 ] * p_i_2 * d2. inverse ( ) ) ;
915
992
916
993
builder. eval ( l * ( t0 + t1 + t2) )
917
994
}
@@ -938,10 +1015,10 @@ impl<C: Config> UniPolyExtrapolator<C> {
938
1015
let p_i_2: Ext < C :: F , C :: EF > = builder. get ( p_i, 2 ) ;
939
1016
let p_i_3: Ext < C :: F , C :: EF > = builder. get ( p_i, 3 ) ;
940
1017
941
- let t0: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 9 ] * p_i_0 / d0) ;
942
- let t1: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 6 ] * p_i_1 / d1) ;
943
- let t2: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 7 ] * p_i_2 / d2) ;
944
- let t3: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 8 ] * p_i_3 / d3) ;
1018
+ let t0: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 9 ] * p_i_0 * d0. inverse ( ) ) ;
1019
+ let t1: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 6 ] * p_i_1 * d1. inverse ( ) ) ;
1020
+ let t2: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 7 ] * p_i_2 * d2. inverse ( ) ) ;
1021
+ let t3: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 8 ] * p_i_3 * d3. inverse ( ) ) ;
945
1022
946
1023
builder. eval ( l * ( t0 + t1 + t2 + t3) )
947
1024
}
@@ -971,12 +1048,30 @@ impl<C: Config> UniPolyExtrapolator<C> {
971
1048
let p_i_3: Ext < C :: F , C :: EF > = builder. get ( p_i, 3 ) ;
972
1049
let p_i_4: Ext < C :: F , C :: EF > = builder. get ( p_i, 4 ) ;
973
1050
974
- let t0: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 11 ] * p_i_0 / d0) ;
975
- let t1: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 9 ] * p_i_1 / d1) ;
976
- let t2: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 10 ] * p_i_2 / d2) ;
977
- let t3: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 9 ] * p_i_3 / d3) ;
978
- let t4: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 11 ] * p_i_4 / d4) ;
1051
+ let t0: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 11 ] * p_i_0 * d0. inverse ( ) ) ;
1052
+ let t1: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 9 ] * p_i_1 * d1. inverse ( ) ) ;
1053
+ let t2: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 10 ] * p_i_2 * d2. inverse ( ) ) ;
1054
+ let t3: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 9 ] * p_i_3 * d3. inverse ( ) ) ;
1055
+ let t4: Ext < C :: F , C :: EF > = builder. eval ( self . constants [ 11 ] * p_i_4 * d4. inverse ( ) ) ;
979
1056
980
1057
builder. eval ( l * ( t0 + t1 + t2 + t3 + t4) )
981
1058
}
982
1059
}
1060
+
1061
+ pub fn extend < C : Config > (
1062
+ builder : & mut Builder < C > ,
1063
+ arr : & Array < C , Ext < C :: F , C :: EF > > ,
1064
+ elem : & Ext < C :: F , C :: EF > ,
1065
+ ) -> Array < C , Ext < C :: F , C :: EF > > {
1066
+ let new_len: Var < C :: N > = builder. eval ( arr. len ( ) + C :: N :: ONE ) ;
1067
+ let out = builder. dyn_array ( new_len) ;
1068
+
1069
+ builder. range ( 0 , arr. len ( ) ) . for_each ( |i_vec, builder| {
1070
+ let i = i_vec[ 0 ] ;
1071
+ let val = builder. get ( arr, i) ;
1072
+ builder. set_value ( & out, i, val) ;
1073
+ } ) ;
1074
+ builder. set_value ( & out, arr. len ( ) , elem. clone ( ) ) ;
1075
+
1076
+ out
1077
+ }
0 commit comments