Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ultra_circuit_builder_range.test.cpp
Go to the documentation of this file.
4
5#include <gtest/gtest.h>
6
7using namespace bb;
8
9namespace bb {
10
11static std::vector<uint32_t> add_variables(UltraCircuitBuilder& builder, const std::vector<fr>& variables)
12{
13 std::vector<uint32_t> res;
14 for (size_t i = 0; i < variables.size(); i++) {
15 res.emplace_back(builder.add_variable(variables[i]));
16 }
17 return res;
18}
23TEST(UltraCircuitBuilder, RangeConstraint)
24{
25 {
27 auto indices = add_variables(builder, { 1, 2, 3, 4, 5, 6, 7, 8 });
28 for (size_t i = 0; i < indices.size(); i++) {
29 builder.create_small_range_constraint(indices[i], 8);
30 }
31 builder.enforce_small_deltas(indices);
32 EXPECT_TRUE(CircuitChecker::check(builder));
33 }
34 {
36 auto indices = add_variables(builder, { 3 });
37 for (size_t i = 0; i < indices.size(); i++) {
38 builder.create_small_range_constraint(indices[i], 3);
39 }
40 builder.create_unconstrained_gates(indices);
41 EXPECT_TRUE(CircuitChecker::check(builder));
42 }
43 {
45 auto indices = add_variables(builder, { 1, 2, 3, 4, 5, 6, 8, 25 });
46 for (size_t i = 0; i < indices.size(); i++) {
47 builder.create_small_range_constraint(indices[i], 8);
48 }
49 builder.enforce_small_deltas(indices);
50 EXPECT_FALSE(CircuitChecker::check(builder));
51 }
52 {
54 auto indices =
55 add_variables(builder, { 1, 2, 3, 4, 5, 6, 10, 8, 15, 11, 32, 21, 42, 79, 16, 10, 3, 26, 19, 51 });
56 for (size_t i = 0; i < indices.size(); i++) {
57 builder.create_small_range_constraint(indices[i], 128);
58 }
59 builder.create_unconstrained_gates(indices);
60 EXPECT_TRUE(CircuitChecker::check(builder));
61 }
62 {
64 auto indices =
65 add_variables(builder, { 1, 2, 3, 80, 5, 6, 29, 8, 15, 11, 32, 21, 42, 79, 16, 10, 3, 26, 13, 14 });
66 for (size_t i = 0; i < indices.size(); i++) {
67 builder.create_small_range_constraint(indices[i], 79);
68 }
69 builder.create_unconstrained_gates(indices);
70 EXPECT_FALSE(CircuitChecker::check(builder));
71 }
72 {
74 auto indices =
75 add_variables(builder, { 1, 0, 3, 80, 5, 6, 29, 8, 15, 11, 32, 21, 42, 79, 16, 10, 3, 26, 13, 14 });
76 for (size_t i = 0; i < indices.size(); i++) {
77 builder.create_small_range_constraint(indices[i], 79);
78 }
79 builder.create_unconstrained_gates(indices);
80 EXPECT_FALSE(CircuitChecker::check(builder));
81 }
82}
83
84TEST(UltraCircuitBuilder, RangeWithGates)
85{
87 auto idx = add_variables(builder, { 1, 2, 3, 4, 5, 6, 7, 8 });
88 for (size_t i = 0; i < idx.size(); i++) {
89 builder.create_small_range_constraint(idx[i], 8);
90 }
91
92 builder.create_add_gate({ idx[0], idx[1], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -3 });
93 builder.create_add_gate({ idx[2], idx[3], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -7 });
94 builder.create_add_gate({ idx[4], idx[5], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -11 });
95 builder.create_add_gate({ idx[6], idx[7], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -15 });
96 EXPECT_TRUE(CircuitChecker::check(builder));
97}
98
99TEST(UltraCircuitBuilder, RangeWithGatesWhereRangeNotDyadic)
100{
102 auto idx = add_variables(builder, { 1, 2, 3, 4, 5, 6, 7, 8 });
103 for (size_t i = 0; i < idx.size(); i++) {
104 builder.create_small_range_constraint(idx[i], 12);
105 }
106
107 builder.create_add_gate({ idx[0], idx[1], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -3 });
108 builder.create_add_gate({ idx[2], idx[3], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -7 });
109 builder.create_add_gate({ idx[4], idx[5], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -11 });
110 builder.create_add_gate({ idx[6], idx[7], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -15 });
111 EXPECT_TRUE(CircuitChecker::check(builder));
112}
113
114TEST(UltraCircuitBuilder, ComposedRangeConstraint)
115{
116 // even num bits - not divisible by 3
118 auto c = fr::random_element();
119 auto d = uint256_t(c).slice(0, 133);
120 auto e = fr(d);
121 auto a_idx = builder.add_variable(fr(e));
122 builder.create_add_gate({ a_idx, builder.zero_idx(), builder.zero_idx(), 1, 0, 0, -fr(e) });
123 builder.create_limbed_range_constraint(a_idx, 134);
124
125 // odd num bits - divisible by 3
126 auto c_1 = fr::random_element();
127 auto d_1 = uint256_t(c_1).slice(0, 126);
128 auto e_1 = fr(d_1);
129 auto a_idx_1 = builder.add_variable(fr(e_1));
130 builder.create_add_gate({ a_idx_1, builder.zero_idx(), builder.zero_idx(), 1, 0, 0, -fr(e_1) });
131 builder.create_limbed_range_constraint(a_idx_1, 127);
132
133 EXPECT_TRUE(CircuitChecker::check(builder));
134}
135
136TEST(UltraCircuitBuilder, RangeChecksOnDuplicates)
137{
139
140 uint32_t a = builder.add_variable(fr(100));
141 uint32_t b = builder.add_variable(fr(100));
142 uint32_t c = builder.add_variable(fr(100));
143 uint32_t d = builder.add_variable(fr(100));
144
145 builder.assert_equal(a, b);
146 builder.assert_equal(a, c);
147 builder.assert_equal(a, d);
148
149 builder.create_small_range_constraint(a, 1000);
150 builder.create_small_range_constraint(b, 1001);
151 builder.create_small_range_constraint(c, 999);
152 builder.create_small_range_constraint(d, 1000);
153
154 builder.create_unconstrained_gates({ a, b, c, d });
155 EXPECT_TRUE(CircuitChecker::check(builder));
156}
157
158} // namespace bb
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
constexpr uint256_t slice(uint64_t start, uint64_t end) const
AluTraceBuilder builder
Definition alu.test.cpp:124
FF a
FF b
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
field< Bn254FrParams > fr
Definition fr.hpp:174
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
static constexpr field one()
static field random_element(numeric::RNG *engine=nullptr) noexcept
static constexpr field zero()