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}
19
20TEST(UltraCircuitBuilder, RangeConstraint)
21{
22 {
24 auto indices = add_variables(builder, { 1, 2, 3, 4, 5, 6, 7, 8 });
25 for (size_t i = 0; i < indices.size(); i++) {
26 builder.create_new_range_constraint(indices[i], 8);
27 }
28 builder.create_sort_constraint(indices);
29 EXPECT_TRUE(CircuitChecker::check(builder));
30 }
31 {
33 auto indices = add_variables(builder, { 3 });
34 for (size_t i = 0; i < indices.size(); i++) {
35 builder.create_new_range_constraint(indices[i], 3);
36 }
37 builder.create_unconstrained_gates(indices);
38 EXPECT_TRUE(CircuitChecker::check(builder));
39 }
40 {
42 auto indices = add_variables(builder, { 1, 2, 3, 4, 5, 6, 8, 25 });
43 for (size_t i = 0; i < indices.size(); i++) {
44 builder.create_new_range_constraint(indices[i], 8);
45 }
46 builder.create_sort_constraint(indices);
47 EXPECT_FALSE(CircuitChecker::check(builder));
48 }
49 {
51 auto indices =
52 add_variables(builder, { 1, 2, 3, 4, 5, 6, 10, 8, 15, 11, 32, 21, 42, 79, 16, 10, 3, 26, 19, 51 });
53 for (size_t i = 0; i < indices.size(); i++) {
54 builder.create_new_range_constraint(indices[i], 128);
55 }
56 builder.create_unconstrained_gates(indices);
57 EXPECT_TRUE(CircuitChecker::check(builder));
58 }
59 {
61 auto indices =
62 add_variables(builder, { 1, 2, 3, 80, 5, 6, 29, 8, 15, 11, 32, 21, 42, 79, 16, 10, 3, 26, 13, 14 });
63 for (size_t i = 0; i < indices.size(); i++) {
64 builder.create_new_range_constraint(indices[i], 79);
65 }
66 builder.create_unconstrained_gates(indices);
67 EXPECT_FALSE(CircuitChecker::check(builder));
68 }
69 {
71 auto indices =
72 add_variables(builder, { 1, 0, 3, 80, 5, 6, 29, 8, 15, 11, 32, 21, 42, 79, 16, 10, 3, 26, 13, 14 });
73 for (size_t i = 0; i < indices.size(); i++) {
74 builder.create_new_range_constraint(indices[i], 79);
75 }
76 builder.create_unconstrained_gates(indices);
77 EXPECT_FALSE(CircuitChecker::check(builder));
78 }
79}
80
81TEST(UltraCircuitBuilder, RangeWithGates)
82{
84 auto idx = add_variables(builder, { 1, 2, 3, 4, 5, 6, 7, 8 });
85 for (size_t i = 0; i < idx.size(); i++) {
86 builder.create_new_range_constraint(idx[i], 8);
87 }
88
89 builder.create_add_gate({ idx[0], idx[1], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -3 });
90 builder.create_add_gate({ idx[2], idx[3], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -7 });
91 builder.create_add_gate({ idx[4], idx[5], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -11 });
92 builder.create_add_gate({ idx[6], idx[7], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -15 });
93 EXPECT_TRUE(CircuitChecker::check(builder));
94}
95
96TEST(UltraCircuitBuilder, RangeWithGatesWhereRangeIsNotAPowerOfTwo)
97{
99 auto idx = add_variables(builder, { 1, 2, 3, 4, 5, 6, 7, 8 });
100 for (size_t i = 0; i < idx.size(); i++) {
101 builder.create_new_range_constraint(idx[i], 12);
102 }
103
104 builder.create_add_gate({ idx[0], idx[1], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -3 });
105 builder.create_add_gate({ idx[2], idx[3], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -7 });
106 builder.create_add_gate({ idx[4], idx[5], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -11 });
107 builder.create_add_gate({ idx[6], idx[7], builder.zero_idx(), fr::one(), fr::one(), fr::zero(), -15 });
108 EXPECT_TRUE(CircuitChecker::check(builder));
109}
110
111TEST(UltraCircuitBuilder, ComposedRangeConstraint)
112{
113 // even num bits - not divisible by 3
115 auto c = fr::random_element();
116 auto d = uint256_t(c).slice(0, 133);
117 auto e = fr(d);
118 auto a_idx = builder.add_variable(fr(e));
119 builder.create_add_gate({ a_idx, builder.zero_idx(), builder.zero_idx(), 1, 0, 0, -fr(e) });
120 builder.decompose_into_default_range(a_idx, 134);
121
122 // odd num bits - divisible by 3
123 auto c_1 = fr::random_element();
124 auto d_1 = uint256_t(c_1).slice(0, 126);
125 auto e_1 = fr(d_1);
126 auto a_idx_1 = builder.add_variable(fr(e_1));
127 builder.create_add_gate({ a_idx_1, builder.zero_idx(), builder.zero_idx(), 1, 0, 0, -fr(e_1) });
128 builder.decompose_into_default_range(a_idx_1, 127);
129
130 EXPECT_TRUE(CircuitChecker::check(builder));
131}
132
133TEST(UltraCircuitBuilder, RangeChecksOnDuplicates)
134{
136
137 uint32_t a = builder.add_variable(fr(100));
138 uint32_t b = builder.add_variable(fr(100));
139 uint32_t c = builder.add_variable(fr(100));
140 uint32_t d = builder.add_variable(fr(100));
141
142 builder.assert_equal(a, b);
143 builder.assert_equal(a, c);
144 builder.assert_equal(a, d);
145
146 builder.create_new_range_constraint(a, 1000);
147 builder.create_new_range_constraint(b, 1001);
148 builder.create_new_range_constraint(c, 999);
149 builder.create_new_range_constraint(d, 1000);
150
151 builder.create_big_add_gate(
152 {
153 a,
154 b,
155 c,
156 d,
157 0,
158 0,
159 0,
160 0,
161 0,
162 },
163 false);
164 EXPECT_TRUE(CircuitChecker::check(builder));
165}
166
167} // 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()