@@ -40,54 +40,6 @@ machine Arith(byte: Byte, byte2: Byte2) with
40
40
// Constrain th at y2 = 0 when operation is div .
41
41
array::new( 4 , |i| is_division * y2 [ i ] = 0 ) ;
42
42
43
- // We need to provide hints for the quotient and remainder , because they are not unique under our current constraints.
44
- // They are unique given additional main machine constraints , but it's still good to provide hints for the solver.
45
- let quotient_hint = query |limb| match(eval(is_division)) {
46
- 1 => {
47
- if x1_int() == 0 {
48
- // Quotient is unconstrained , use zero.
49
- Query::Hint( 0 )
50
- } else {
51
- let y3 = y3_int() ;
52
- let x1 = x1_int() ;
53
- let quotient = y3 / x1 ;
54
- Query::Hint(fe(select_limb(quotient , limb)))
55
- }
56
- } ,
57
- _ => Query::None
58
- } ;
59
-
60
- col witness y1_0(i) query quotient_hint( 0 ) ;
61
- col witness y1_1(i) query quotient_hint( 1 ) ;
62
- col witness y1_2(i) query quotient_hint( 2 ) ;
63
- col witness y1_3(i) query quotient_hint( 3 ) ;
64
-
65
- let y1: expr [] = [ y1_0 , y1_1 , y1_2 , y1_3 ] ;
66
-
67
- let remainder_hint = query |limb| match(eval(is_division)) {
68
- 1 => {
69
- let y3 = y3_int() ;
70
- let x1 = x1_int() ;
71
- if x1 == 0 {
72
- // To satisfy x1 * y1 + x2 = y3 , we need to set x2 = y3.
73
- Query::Hint(fe(select_limb(y3 , limb)))
74
- } else {
75
- let remainder = y3 % x1 ;
76
- Query::Hint(fe(select_limb(remainder , limb)))
77
- }
78
- } ,
79
- _ => Query::None
80
- } ;
81
-
82
- col witness x2_0(i) query remainder_hint( 0 ) ;
83
- col witness x2_1(i) query remainder_hint( 1 ) ;
84
- col witness x2_2(i) query remainder_hint( 2 ) ;
85
- col witness x2_3(i) query remainder_hint( 3 ) ;
86
-
87
- let x2: expr [] = [ x2_0 , x2_1 , x2_2 , x2_3 ] ;
88
-
89
- pol commit x1 [ 4 ], y2 [ 4 ], y3 [ 4 ] ;
90
-
91
43
// Selects the ith limb of x (little endian)
92
44
// All limbs are 8 bits
93
45
let select_limb = |x , i| if i >= 0 {
@@ -96,13 +48,32 @@ machine Arith(byte: Byte, byte2: Byte2) with
96
48
0
97
49
} ;
98
50
99
- let limbs_to_int: expr [] - > int = query |limbs| array::sum(array::map_enumerated(limbs , |i , limb| int (eval(limb)) << (i * 8 ))) ;
51
+ let limbs_to_int: fe [] - > int = |limbs| array::sum(array::map_enumerated(limbs , |i , limb| int (limb) << (i * 8 ))) ;
52
+ let int_to_limbs: int - > fe [] = |x| array::new( 4 , |i| fe(select_limb(x , i))) ;
53
+
54
+ // We need to provide hints for the quotient and remainder , because they are not unique under our current constraints.
55
+ // They are unique given additional main machine constraints , but it's still good to provide hints for the solver.
56
+ query |i| std ::prover::compute_from_multi_if(
57
+ is_division = 1 ,
58
+ y1 + x2 ,
59
+ i ,
60
+ y3 + x1 ,
61
+ |values| {
62
+ let y3_value = limbs_to_int( [ values [ 0 ], values [ 1 ], values [ 2 ], values [ 3 ]] ) ;
63
+ let x1_value = limbs_to_int( [ values [ 4 ], values [ 5 ], values [ 6 ], values [ 7 ]] ) ;
64
+ if x1_value == 0 {
65
+ // Quotient is unconstrained , use zero for y1
66
+ // and set remainder x2 = y3.
67
+ [ 0 , 0 , 0 , 0 ] + int_to_limbs(y3_value)
68
+ } else {
69
+ let quotient = y3_value / x1_value ;
70
+ let remainder = y3_value % x1_value ;
71
+ int_to_limbs(quotient) + int_to_limbs(remainder)
72
+ }
73
+ }
74
+ ) ;
100
75
101
- let x1_int = query || limbs_to_int(x1) ;
102
- let y1_int = query || limbs_to_int(y1) ;
103
- let x2_int = query || limbs_to_int(x2) ;
104
- let y2_int = query || limbs_to_int(y2) ;
105
- let y3_int = query || limbs_to_int(y3) ;
76
+ pol commit x1 [ 4 ], x2 [ 4 ], y1 [ 4 ], y2 [ 4 ], y3 [ 4 ] ;
106
77
107
78
let combine: expr [] - > expr [] = |x| array::new(array::len(x) / 2 , |i| x [ 2 * i + 1 ] * 2 ** 8 + x [ 2 * i ] ) ;
108
79
// Intermediate polynomials , arrays of 16 columns , 16 bit per column.
0 commit comments