Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
field_gt.cpp
Go to the documentation of this file.
2
5
6namespace bb::avm2::simulation {
7
8namespace {
9
10// Unconstrained. Gives witness values for a > b (or a >= b if allow_eq is true).
11// The approach is that to prove that two range-constrained numbers x, y (e.g., to 20 bits each) are such that x > y,
12// you prove that x - y - 1 does not underflow. That is, you prove that x - y - 1 still fits in 20 bits.
13// So, your witness value (for a later range check) will be x - y - 1, for each pair of limbs.
14// The >= case is handled with a borrow flag.
15LimbsComparisonWitness limb_gt_or_gte_witness_(const U256Decomposition& a, const U256Decomposition& b, bool allow_eq)
16{
17 bool borrow = allow_eq ? (a.lo < b.lo) : (a.lo <= b.lo);
18 // No need to add borrow * TWO_POW_128 since uint128_t will wrap in the way we need
19 uint128_t x_lo = a.lo - b.lo - (allow_eq ? 0 : 1);
20 uint128_t x_hi = a.hi - b.hi - (borrow ? 1 : 0);
21 return { x_lo, x_hi, borrow };
22}
23
24// Unconstrained.
25inline LimbsComparisonWitness limb_gt_witness(const U256Decomposition& a, const U256Decomposition& b)
26{
27 return limb_gt_or_gte_witness_(a, b, false);
28}
29
30// Unconstrained.
31inline LimbsComparisonWitness limb_gte_witness(const U256Decomposition& a, const U256Decomposition& b)
32{
33 return limb_gt_or_gte_witness_(a, b, true);
34}
35
43LimbsComparisonWitness canonical_decomposition(const U256Decomposition& x_limbs, RangeCheckInterface& range_check)
44{
45 range_check.assert_range(x_limbs.lo, 128);
46 range_check.assert_range(x_limbs.hi, 128);
47
48 static U256Decomposition p_limbs = decompose_256(FF::modulus);
49 const LimbsComparisonWitness p_sub_x_witness = limb_gt_witness(p_limbs, x_limbs);
50
51 range_check.assert_range(p_sub_x_witness.lo, 128);
52 range_check.assert_range(p_sub_x_witness.hi, 128);
53
54 return p_sub_x_witness;
55}
56
57} // namespace
58
66bool FieldGreaterThan::ff_gt(const FF& a, const FF& b)
67{
68 const uint256_t a_integer(a);
69 const uint256_t b_integer(b);
70
71 // This result would be enough for fast simulation, but we need to do a lot more for the circuit.
72 const bool result_a_gt_b = a_integer > b_integer;
73
74 const U256Decomposition a_limbs = decompose_256(a_integer);
75 const U256Decomposition b_limbs = decompose_256(b_integer);
76
77 // These decompositions are constrained.
78 const LimbsComparisonWitness p_sub_a_witness = canonical_decomposition(a_limbs, range_check);
79 const LimbsComparisonWitness p_sub_b_witness = canonical_decomposition(b_limbs, range_check);
80
81 // We will either be proving that a > b or that b >= a.
82 const LimbsComparisonWitness res_witness =
83 result_a_gt_b ? limb_gt_witness(a_limbs, b_limbs) : limb_gte_witness(b_limbs, a_limbs);
84 range_check.assert_range(res_witness.lo, 128);
85 range_check.assert_range(res_witness.hi, 128);
86
87 events.emit({
89 .a = a,
90 .b = b,
91 .a_limbs = a_limbs,
92 .p_sub_a_witness = p_sub_a_witness,
93 .b_limbs = b_limbs,
94 .p_sub_b_witness = p_sub_b_witness,
95 .res_witness = res_witness,
96 .gt_result = result_a_gt_b,
97 });
98
99 return result_a_gt_b;
100}
101
109{
110 const U256Decomposition a_limbs = decompose_256(static_cast<uint256_t>(a));
111 const LimbsComparisonWitness p_sub_a_witness = canonical_decomposition(a_limbs, range_check);
112
113 events.emit({
115 .a = a,
116 .a_limbs = a_limbs,
117 .p_sub_a_witness = p_sub_a_witness,
118 });
119
120 return a_limbs;
121}
122
123} // namespace bb::avm2::simulation
RangeCheck range_check
U256Decomposition canon_dec(const FF &a) override
Decomposes the provided field element into 128-bit limbs (in a constrained way).
Definition field_gt.cpp:108
EventEmitterInterface< FieldGreaterThanEvent > & events
Definition field_gt.hpp:23
bool ff_gt(const FF &a, const FF &b) override
Computes the result of a > b (in a constrained way).
Definition field_gt.cpp:66
void assert_range(uint128_t value, uint8_t num_bits) override
Assert that a value fits within a given bit-width.
FF a
FF b
AVM range check gadget for witness generation.
U256Decomposition decompose_256(const uint256_t &x)
AvmFlavorSettings::FF FF
Definition field.hpp:10
unsigned __int128 uint128_t
Definition serialize.hpp:45
static constexpr uint256_t modulus