Skip to content

Commit 9578dd0

Browse files
committed
Prover functions for small arith.
1 parent 4dbbadf commit 9578dd0

File tree

1 file changed

+25
-54
lines changed

1 file changed

+25
-54
lines changed

std/machines/small_field/arith.asm

+25-54
Original file line numberDiff line numberDiff line change
@@ -40,54 +40,6 @@ machine Arith(byte: Byte, byte2: Byte2) with
4040
// Constrain that y2 = 0 when operation is div.
4141
array::new(4, |i| is_division * y2[i] = 0);
4242

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-
9143
// Selects the ith limb of x (little endian)
9244
// All limbs are 8 bits
9345
let select_limb = |x, i| if i >= 0 {
@@ -96,13 +48,32 @@ machine Arith(byte: Byte, byte2: Byte2) with
9648
0
9749
};
9850

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+
);
10075

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];
10677

10778
let combine: expr[] -> expr[] = |x| array::new(array::len(x) / 2, |i| x[2 * i + 1] * 2**8 + x[2 * i]);
10879
// Intermediate polynomials, arrays of 16 columns, 16 bit per column.

0 commit comments

Comments
 (0)