Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
graph_description.test.cpp
Go to the documentation of this file.
10
11#include <gtest/gtest.h>
12
13using namespace bb;
14using namespace cdg;
15
23TEST(boomerang_ultra_circuit_constructor, test_graph_for_arithmetic_gates)
24{
25 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
26 for (size_t i = 0; i < 16; ++i) {
27 for (size_t j = 0; j < 16; ++j) {
28 uint64_t left = static_cast<uint64_t>(j);
29 uint64_t right = static_cast<uint64_t>(i);
30 uint32_t left_idx = circuit_constructor.add_variable(fr(left));
31 uint32_t right_idx = circuit_constructor.add_variable(fr(right));
32 uint32_t result_idx = circuit_constructor.add_variable(fr(left ^ right));
33
34 uint32_t add_idx =
35 circuit_constructor.add_variable(fr(left) + fr(right) + circuit_constructor.get_variable(result_idx));
36 circuit_constructor.create_big_add_gate(
37 { left_idx, right_idx, result_idx, add_idx, fr(1), fr(1), fr(1), fr(-1), fr(0) });
38 }
39 }
40
41 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
42 auto connected_components = graph.find_connected_components();
43 auto variables_in_one_gate = graph.get_variables_in_one_gate();
44 EXPECT_EQ(variables_in_one_gate.size(), 1024);
45 EXPECT_EQ(connected_components.size(), 256);
46}
47
55TEST(boomerang_ultra_circuit_constructor, test_graph_for_arithmetic_gates_with_shifts)
56{
57 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
58 for (size_t i = 0; i < 16; ++i) {
59 for (size_t j = 0; j < 16; ++j) {
60 uint64_t left = static_cast<uint64_t>(j);
61 uint64_t right = static_cast<uint64_t>(i);
62 uint32_t left_idx = circuit_constructor.add_variable(fr(left));
63 uint32_t right_idx = circuit_constructor.add_variable(fr(right));
64 uint32_t result_idx = circuit_constructor.add_variable(fr(left ^ right));
65
66 uint32_t add_idx =
67 circuit_constructor.add_variable(fr(left) + fr(right) + circuit_constructor.get_variable(result_idx));
68 circuit_constructor.create_big_add_gate(
69 { left_idx, right_idx, result_idx, add_idx, fr(1), fr(1), fr(1), fr(-1), fr(0) }, true);
70 }
71 }
72
73 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
74 auto connected_components = graph.find_connected_components();
75 auto num_connected_components = connected_components.size();
76 bool result = num_connected_components == 1;
77 EXPECT_EQ(result, true);
78}
79
88TEST(boomerang_ultra_circuit_constructor, test_graph_for_boolean_gates)
89{
90 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
91
92 for (size_t i = 0; i < 20; ++i) {
93 fr a = fr::zero();
94 uint32_t a_idx = circuit_constructor.add_variable(a);
95 circuit_constructor.create_bool_gate(a_idx);
96 }
97
98 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
99 auto connected_components = graph.find_connected_components();
100 auto num_connected_components = connected_components.size();
101 auto variables_in_one_gate = graph.get_variables_in_one_gate();
102 bool result = num_connected_components == 0;
103 EXPECT_EQ(result, true);
104 EXPECT_EQ(variables_in_one_gate.size(), 20);
105}
106
115TEST(boomerang_ultra_circuit_constructor, test_graph_for_elliptic_add_gate)
116{
117 typedef grumpkin::g1::affine_element affine_element;
118 typedef grumpkin::g1::element element;
119 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
120
121 affine_element p1 = crypto::pedersen_commitment::commit_native({ bb::fr(1) }, 0);
122
123 affine_element p2 = crypto::pedersen_commitment::commit_native({ bb::fr(1) }, 1);
124 affine_element p3(element(p1) + element(p2));
125
126 uint32_t x1 = circuit_constructor.add_variable(p1.x);
127 uint32_t y1 = circuit_constructor.add_variable(p1.y);
128 uint32_t x2 = circuit_constructor.add_variable(p2.x);
129 uint32_t y2 = circuit_constructor.add_variable(p2.y);
130 uint32_t x3 = circuit_constructor.add_variable(p3.x);
131 uint32_t y3 = circuit_constructor.add_variable(p3.y);
132
133 circuit_constructor.create_ecc_add_gate({ x1, y1, x2, y2, x3, y3, /*is_addition=*/true });
134
135 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
136 auto connected_components = graph.find_connected_components();
137 auto num_connected_components = connected_components.size();
138 bool result = num_connected_components == 1;
139 EXPECT_EQ(result, true);
140}
141
150TEST(boomerang_ultra_circuit_constructor, test_graph_for_elliptic_double_gate)
151{
152 typedef grumpkin::g1::affine_element affine_element;
153 typedef grumpkin::g1::element element;
154 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
155
156 affine_element p1 = crypto::pedersen_commitment::commit_native({ bb::fr(1) }, 0);
157 affine_element p3(element(p1).dbl());
158
159 uint32_t x1 = circuit_constructor.add_variable(p1.x);
160 uint32_t y1 = circuit_constructor.add_variable(p1.y);
161 uint32_t x3 = circuit_constructor.add_variable(p3.x);
162 uint32_t y3 = circuit_constructor.add_variable(p3.y);
163
164 circuit_constructor.create_ecc_dbl_gate({ x1, y1, x3, y3 });
165
166 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
167 auto connected_components = graph.find_connected_components();
168 auto num_connected_components = connected_components.size();
169 bool result = num_connected_components == 1;
170 EXPECT_EQ(result, true);
171}
172
182TEST(boomerang_ultra_circuit_constructor, test_graph_for_elliptic_together)
183{
184 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
185
186 typedef grumpkin::g1::affine_element affine_element;
187 typedef grumpkin::g1::element element;
188
189 affine_element p1 = crypto::pedersen_commitment::commit_native({ bb::fr(1) }, 0);
190 affine_element p2 = crypto::pedersen_commitment::commit_native({ bb::fr(1) }, 1);
191 affine_element p3(element(p1) + element(p2));
192
193 uint32_t x1 = circuit_constructor.add_variable(p1.x);
194 uint32_t y1 = circuit_constructor.add_variable(p1.y);
195 uint32_t x2 = circuit_constructor.add_variable(p2.x);
196 uint32_t y2 = circuit_constructor.add_variable(p2.y);
197 uint32_t x3 = circuit_constructor.add_variable(p3.x);
198 uint32_t y3 = circuit_constructor.add_variable(p3.y);
199
200 circuit_constructor.create_ecc_add_gate({ x1, y1, x2, y2, x3, y3, /*is_addition=*/true });
201 affine_element p4(element(p3).dbl());
202 uint32_t x4 = circuit_constructor.add_variable(p4.x);
203 uint32_t y4 = circuit_constructor.add_variable(p4.y);
204 circuit_constructor.create_ecc_dbl_gate({ x3, y3, x4, y4 });
205
206 affine_element p5 = crypto::pedersen_commitment::commit_native({ bb::fr(2) }, 1);
207 affine_element p6 = crypto::pedersen_commitment::commit_native({ bb::fr(3) }, 1);
208 affine_element p7(element(p5) + element(p6));
209
210 uint32_t x5 = circuit_constructor.add_variable(p5.x);
211 uint32_t y5 = circuit_constructor.add_variable(p5.y);
212 uint32_t x6 = circuit_constructor.add_variable(p6.x);
213 uint32_t y6 = circuit_constructor.add_variable(p6.y);
214 uint32_t x7 = circuit_constructor.add_variable(p7.x);
215 uint32_t y7 = circuit_constructor.add_variable(p7.y);
216
217 circuit_constructor.create_ecc_add_gate({ x5, y5, x6, y6, x7, y7, /*is_addition=*/true });
218 affine_element p8(element(p7).dbl());
219 uint32_t x8 = circuit_constructor.add_variable(p8.x);
220 uint32_t y8 = circuit_constructor.add_variable(p8.y);
221 circuit_constructor.create_ecc_dbl_gate({ x7, y7, x8, y8 });
222
223 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
224 auto connected_components = graph.find_connected_components();
225 auto num_connected_components = connected_components.size();
226 bool result = num_connected_components == 2;
227 EXPECT_EQ(result, true);
228}
229
239TEST(boomerang_ultra_circuit_constructor, test_graph_for_sort_constraints)
240{
241 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
242 fr a = fr::one();
243 fr b = fr(2);
244 fr c = fr(3);
245 fr d = fr(4);
246
247 auto a_idx = circuit_constructor.add_variable(a);
248 auto b_idx = circuit_constructor.add_variable(b);
249 auto c_idx = circuit_constructor.add_variable(c);
250 auto d_idx = circuit_constructor.add_variable(d);
251 circuit_constructor.enforce_small_deltas({ a_idx, b_idx, c_idx, d_idx });
252
253 fr e = fr(5);
254 fr f = fr(6);
255 fr g = fr(7);
256 fr h = fr(8);
257 auto e_idx = circuit_constructor.add_variable(e);
258 auto f_idx = circuit_constructor.add_variable(f);
259 auto g_idx = circuit_constructor.add_variable(g);
260 auto h_idx = circuit_constructor.add_variable(h);
261 circuit_constructor.enforce_small_deltas({ e_idx, f_idx, g_idx, h_idx });
262
263 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
264 auto connected_components = graph.find_connected_components();
265 EXPECT_EQ(connected_components[0].size(), 4);
266 EXPECT_EQ(connected_components[1].size(), 4);
267 EXPECT_EQ(connected_components.size(), 2);
268}
269
279TEST(boomerang_ultra_circuit_constructor, test_graph_for_sort_constraints_with_edges)
280{
281 fr a = fr::one();
282 fr b = fr(2);
283 fr c = fr(3);
284 fr d = fr(4);
285 fr e = fr(5);
286 fr f = fr(6);
287 fr g = fr(7);
288 fr h = fr(8);
289
290 UltraCircuitBuilder circuit_constructor;
291 auto a_idx = circuit_constructor.add_variable(a);
292 auto b_idx = circuit_constructor.add_variable(b);
293 auto c_idx = circuit_constructor.add_variable(c);
294 auto d_idx = circuit_constructor.add_variable(d);
295 auto e_idx = circuit_constructor.add_variable(e);
296 auto f_idx = circuit_constructor.add_variable(f);
297 auto g_idx = circuit_constructor.add_variable(g);
298 auto h_idx = circuit_constructor.add_variable(h);
299 circuit_constructor.create_sort_constraint_with_edges(
300 { a_idx, b_idx, c_idx, d_idx, e_idx, f_idx, g_idx, h_idx }, a, h);
301
302 fr a1 = fr(9);
303 fr b1 = fr(10);
304 fr c1 = fr(11);
305 fr d1 = fr(12);
306 fr e1 = fr(13);
307 fr f1 = fr(14);
308 fr g1 = fr(15);
309 fr h1 = fr(16);
310
311 auto a1_idx = circuit_constructor.add_variable(a1);
312 auto b1_idx = circuit_constructor.add_variable(b1);
313 auto c1_idx = circuit_constructor.add_variable(c1);
314 auto d1_idx = circuit_constructor.add_variable(d1);
315 auto e1_idx = circuit_constructor.add_variable(e1);
316 auto f1_idx = circuit_constructor.add_variable(f1);
317 auto g1_idx = circuit_constructor.add_variable(g1);
318 auto h1_idx = circuit_constructor.add_variable(h1);
319
320 circuit_constructor.create_sort_constraint_with_edges(
321 { a1_idx, b1_idx, c1_idx, d1_idx, e1_idx, f1_idx, g1_idx, h1_idx }, a1, h1);
322 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
323 auto connected_components = graph.find_connected_components();
324 auto num_connected_components = connected_components.size();
325 bool result = num_connected_components == 2;
326 EXPECT_EQ(result, true);
327}
328
336TEST(boomerang_ultra_circuit_constructor, test_graph_with_plookup_accumulators)
337{
338 UltraCircuitBuilder circuit_builder = UltraCircuitBuilder();
339
340 fr input_value = fr::random_element();
341 const fr input_lo = static_cast<uint256_t>(input_value).slice(0, plookup::fixed_base::table::BITS_PER_LO_SCALAR);
342 const auto input_lo_index = circuit_builder.add_variable(input_lo);
343
344 const auto sequence_data_lo = plookup::get_lookup_accumulators(plookup::MultiTableId::FIXED_BASE_LEFT_LO, input_lo);
345
346 const auto lookup_witnesses = circuit_builder.create_gates_from_plookup_accumulators(
347 plookup::MultiTableId::FIXED_BASE_LEFT_LO, sequence_data_lo, input_lo_index);
348
349 const size_t num_lookups = plookup::fixed_base::table::NUM_TABLES_PER_LO_MULTITABLE;
350
351 EXPECT_EQ(num_lookups, lookup_witnesses[plookup::ColumnIdx::C1].size());
352
353 StaticAnalyzer graph = StaticAnalyzer(circuit_builder);
354 auto connected_components = graph.find_connected_components();
355 auto num_connected_components = connected_components.size();
356 bool result = num_connected_components == 1;
357 EXPECT_EQ(result, true);
358}
359
367TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_arithmetic_gate)
368{
369 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
370
371 for (size_t i = 0; i < 25; ++i) {
372 for (size_t j = 0; j < 25; ++j) {
373 uint64_t left = static_cast<uint64_t>(j);
374 uint64_t right = static_cast<uint64_t>(i);
375 uint32_t left_idx = circuit_constructor.add_variable(fr(left));
376 uint32_t right_idx = circuit_constructor.add_variable(fr(right));
377 uint32_t result_idx = circuit_constructor.add_variable(fr(left ^ right));
378
379 uint32_t add_idx =
380 circuit_constructor.add_variable(fr(left) + fr(right) + circuit_constructor.get_variable(result_idx));
381 circuit_constructor.create_big_add_gate(
382 { left_idx, right_idx, result_idx, add_idx, fr(1), fr(1), fr(1), fr(-1), fr(0) });
383 }
384 }
385
386 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
387 auto variables_gate_counts = graph.get_variables_gate_counts();
388
389 // Verify that each variable (except zero_idx) appears in exactly 1 gate
390 bool result = true;
391 uint32_t zero_idx = circuit_constructor.zero_idx();
392 for (const auto pair : variables_gate_counts) {
393 if (pair.first != zero_idx) {
394 result = result && (pair.second == 1);
395 }
396 }
397 EXPECT_EQ(result, true);
398}
399
407TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_arithmetic_gate_with_shifts)
408{
409 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
410
411 for (size_t i = 0; i < 25; ++i) {
412 for (size_t j = 0; j < 25; ++j) {
413 uint64_t left = static_cast<uint64_t>(j);
414 uint64_t right = static_cast<uint64_t>(i);
415 uint32_t left_idx = circuit_constructor.add_variable(fr(left));
416 uint32_t right_idx = circuit_constructor.add_variable(fr(right));
417 uint32_t result_idx = circuit_constructor.add_variable(fr(left ^ right));
418
419 uint32_t add_idx =
420 circuit_constructor.add_variable(fr(left) + fr(right) + circuit_constructor.get_variable(result_idx));
421 circuit_constructor.create_big_add_gate(
422 { left_idx, right_idx, result_idx, add_idx, fr(1), fr(1), fr(1), fr(-1), fr(0) }, true);
423 }
424 }
425
426 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
427 bool result = true;
428 uint32_t zero_idx = circuit_constructor.zero_idx();
429 auto variables_gate_counts = graph.get_variables_gate_counts();
430 for (const auto& pair : variables_gate_counts) {
431 if (pair.first != zero_idx) {
432 result = result && (pair.first % 4 == 0 && pair.first != 4 ? (pair.second == 2) : (pair.second == 1));
433 }
434 }
435 EXPECT_EQ(result, true);
436}
437
444TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_boolean_gates)
445{
446 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
447
448 for (size_t i = 0; i < 20; ++i) {
449 fr a = fr::zero();
450 uint32_t a_idx = circuit_constructor.add_variable(a);
451 circuit_constructor.create_bool_gate(a_idx);
452 }
453
454 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
455 auto variables_gate_counts = graph.get_variables_gate_counts();
456 bool result = true;
457 uint32_t zero_idx = circuit_constructor.zero_idx();
458 for (const auto& part : variables_gate_counts) {
459 if (part.first != zero_idx) {
460 result = result && (part.second == 1);
461 }
462 }
463 EXPECT_EQ(result, true);
464}
465
473TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_sorted_constraints)
474{
475 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
476 fr a = fr::one();
477 fr b = fr(2);
478 fr c = fr(3);
479 fr d = fr(4);
480
481 auto a_idx = circuit_constructor.add_variable(a);
482 auto b_idx = circuit_constructor.add_variable(b);
483 auto c_idx = circuit_constructor.add_variable(c);
484 auto d_idx = circuit_constructor.add_variable(d);
485 circuit_constructor.enforce_small_deltas({ a_idx, b_idx, c_idx, d_idx });
486
487 fr e = fr(5);
488 fr f = fr(6);
489 fr g = fr(7);
490 fr h = fr(8);
491 auto e_idx = circuit_constructor.add_variable(e);
492 auto f_idx = circuit_constructor.add_variable(f);
493 auto g_idx = circuit_constructor.add_variable(g);
494 auto h_idx = circuit_constructor.add_variable(h);
495 circuit_constructor.enforce_small_deltas({ e_idx, f_idx, g_idx, h_idx });
496
497 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
498 auto variables_gate_counts = graph.get_variables_gate_counts();
499 auto connected_components = graph.find_connected_components();
500 EXPECT_EQ(connected_components.size(), 2);
501 bool result = true;
502 for (const auto& var_idx : connected_components[0].vars()) {
503 result = result && (variables_gate_counts[var_idx] == 1);
504 }
505
506 for (const auto& var_idx : connected_components[1].vars()) {
507 result = result && (variables_gate_counts[var_idx] == 1);
508 }
509 EXPECT_EQ(result, true);
510}
511
519TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_sorted_constraints_with_edges)
520{
521 UltraCircuitBuilder circuit_constructor;
522 auto add_variables = [&circuit_constructor](const std::vector<fr>& vars) {
523 std::vector<uint32_t> res;
524 res.reserve(vars.size());
525 for (const auto& var : vars) {
526 res.emplace_back(circuit_constructor.add_variable(var));
527 }
528 return res;
529 };
530 std::vector<fr> vars1 = { fr::one(), fr(2), fr(3), fr(4), fr(5), fr(6), fr(7), fr(8) };
531 std::vector<fr> vars2 = { fr(9), fr(10), fr(11), fr(12), fr(13), fr(14), fr(15), fr(16) };
532 auto var_idx1 = add_variables(vars1);
533 auto var_idx2 = add_variables(vars2);
534 circuit_constructor.create_sort_constraint_with_edges(var_idx1, vars1[0], vars1[vars1.size() - 1]);
535 circuit_constructor.create_sort_constraint_with_edges(var_idx2, vars2[0], vars2[vars2.size() - 1]);
536 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
537 auto connected_components = graph.find_connected_components();
538 auto variables_gate_counts = graph.get_variables_gate_counts();
539
540 // Two separate sort constraints should create 2 connected components
541 EXPECT_EQ(connected_components.size(), 2);
542
543 // All variables should appear in at least one gate
544 for (size_t i = 0; i < var_idx1.size(); i++) {
545 EXPECT_GE(variables_gate_counts[var_idx1[i]], 1)
546 << "Variable at index " << i << " should appear in at least 1 gate";
547 }
548}
549
557TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_ecc_add_gates)
558{
559 typedef grumpkin::g1::affine_element affine_element;
560 typedef grumpkin::g1::element element;
561 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
562
563 affine_element p1 = crypto::pedersen_commitment::commit_native({ bb::fr(1) }, 0);
564
565 affine_element p2 = crypto::pedersen_commitment::commit_native({ bb::fr(1) }, 1);
566 affine_element p3(element(p1) + element(p2));
567
568 uint32_t x1 = circuit_constructor.add_variable(p1.x);
569 uint32_t y1 = circuit_constructor.add_variable(p1.y);
570 uint32_t x2 = circuit_constructor.add_variable(p2.x);
571 uint32_t y2 = circuit_constructor.add_variable(p2.y);
572 uint32_t x3 = circuit_constructor.add_variable(p3.x);
573 uint32_t y3 = circuit_constructor.add_variable(p3.y);
574
575 circuit_constructor.create_ecc_add_gate({ x1, y1, x2, y2, x3, y3, /*is_addition=*/true });
576
577 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
578 auto variables_gate_counts = graph.get_variables_gate_counts();
579 auto connected_components = graph.find_connected_components();
580 auto variable_indices = connected_components[0].vars();
581 bool result =
582 (variables_gate_counts[variable_indices[0]] == 1) && (variables_gate_counts[variable_indices[1]] == 1) &&
583 (variables_gate_counts[variable_indices[2]] == 1) && (variables_gate_counts[variable_indices[3]] == 1) &&
584 (variables_gate_counts[variable_indices[4]] == 1) && (variables_gate_counts[variable_indices[5]] == 1);
585 EXPECT_EQ(connected_components.size(), 1);
586 EXPECT_EQ(result, true);
587}
588
597TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_ecc_dbl_gate)
598{
599 typedef grumpkin::g1::affine_element affine_element;
600 typedef grumpkin::g1::element element;
601 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
602
603 affine_element p1 = crypto::pedersen_commitment::commit_native({ bb::fr(1) }, 0);
604 affine_element p3(element(p1).dbl());
605
606 uint32_t x1 = circuit_constructor.add_variable(p1.x);
607 uint32_t y1 = circuit_constructor.add_variable(p1.y);
608 uint32_t x3 = circuit_constructor.add_variable(p3.x);
609 uint32_t y3 = circuit_constructor.add_variable(p3.y);
610
611 circuit_constructor.create_ecc_dbl_gate({ x1, y1, x3, y3 });
612
613 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
614 auto variables_gate_counts = graph.get_variables_gate_counts();
615 auto connected_components = graph.find_connected_components();
616
617 auto vars = connected_components[0].vars();
618 EXPECT_EQ(vars.size(), 4);
619 bool result = (variables_gate_counts[vars[0]] == 1) && (variables_gate_counts[vars[1]] == 1) &&
620 (variables_gate_counts[vars[2]] == 1) && (variables_gate_counts[vars[3]] == 1);
621
622 EXPECT_EQ(connected_components.size(), 1);
623 EXPECT_EQ(result, true);
624}
625
633TEST(boomerang_ultra_circuit_constructor, test_graph_for_range_constraints)
634{
635 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
636 auto add_variables = [&circuit_constructor](const std::vector<fr>& vars) {
637 std::vector<uint32_t> res;
638 res.reserve(vars.size());
639 for (const auto& var : vars) {
640 res.emplace_back(circuit_constructor.add_variable(var));
641 }
642 return res;
643 };
644 auto indices = add_variables({ fr(1), fr(2), fr(3), fr(4) });
645 for (size_t i = 0; i < indices.size(); i++) {
646 circuit_constructor.create_small_range_constraint(indices[i], 5);
647 }
648 circuit_constructor.enforce_small_deltas(indices);
649 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
650 auto connected_components = graph.find_connected_components();
651 EXPECT_EQ(connected_components.size(), 1);
652}
653
661TEST(boomerang_ultra_circuit_constructor, composed_range_constraint)
662{
663 UltraCircuitBuilder circuit_constructor = UltraCircuitBuilder();
664 auto c = fr::random_element();
665 auto d = uint256_t(c).slice(0, 133);
666 auto e = fr(d);
667 auto a_idx = circuit_constructor.add_variable(fr(e));
668 circuit_constructor.create_add_gate(
669 { a_idx, circuit_constructor.zero_idx(), circuit_constructor.zero_idx(), 1, 0, 0, -fr(e) });
670 circuit_constructor.create_limbed_range_constraint(a_idx, 134);
671
672 StaticAnalyzer graph = StaticAnalyzer(circuit_constructor);
673 auto connected_components = graph.find_connected_components();
674 EXPECT_EQ(connected_components.size(), 1);
675}
virtual uint32_t add_variable(const FF &in)
Add a variable to variables.
FF get_variable(const uint32_t index) const
Get the value of the variable v_{index}.
void create_ecc_dbl_gate(const ecc_dbl_gate_< FF > &in)
Create an elliptic curve doubling gate.
void create_sort_constraint_with_edges(const std::vector< uint32_t > &variable_indices, const FF &start, const FF &end)
Constrain consecutive variable differences to be in {0, 1, 2, 3}, with boundary checks.
void create_small_range_constraint(const uint32_t variable_index, const uint64_t target_range, std::string const msg="create_small_range_constraint")
Range-constraints for small ranges, where the upper bound (target_range) need not be dyadic....
void create_add_gate(const add_triple_< FF > &in)
Create an addition gate, where in.a * in.a_scaling + in.b * in.b_scaling + in.c * in....
void create_big_add_gate(const add_quad_< FF > &in, const bool use_next_gate_w_4=false)
Create a big addition gate, where in.a * in.a_scaling + in.b * in.b_scaling + in.c * in....
void create_ecc_add_gate(const ecc_add_gate_ &in)
Create an elliptic curve addition gate.
std::vector< uint32_t > create_limbed_range_constraint(const uint32_t variable_index, const uint64_t num_bits, const uint64_t target_range_bitnum=DEFAULT_PLOOKUP_RANGE_BITNUM, std::string const &msg="create_limbed_range_constraint")
Range-constrain a variable to [0, 2^num_bits - 1] by decomposing into smaller limbs.
plookup::ReadData< uint32_t > create_gates_from_plookup_accumulators(const plookup::MultiTableId &id, const plookup::ReadData< FF > &read_values, const uint32_t key_a_index, std::optional< uint32_t > key_b_index=std::nullopt)
Create gates from pre-computed accumulator values which simultaneously establish individual basic-tab...
void enforce_small_deltas(const std::vector< uint32_t > &variable_indices)
Check for a sequence of variables that the neighboring differences are in {0, 1, 2,...
void create_bool_gate(const uint32_t a)
Generate an arithmetic gate equivalent to x^2 - x = 0, which forces x to be 0 or 1.
static AffineElement commit_native(const std::vector< Fq > &inputs, GeneratorContext context={})
Given a vector of fields, generate a pedersen commitment using the indexed generators.
Definition pedersen.cpp:24
element class. Implements ecc group arithmetic using Jacobian coordinates See https://hyperelliptic....
Definition element.hpp:33
group class. Represents an elliptic curve group element. Group is parametrised by Fq and Fr
Definition group.hpp:36
constexpr uint256_t slice(uint64_t start, uint64_t end) const
std::vector< ConnectedComponent > find_connected_components()
this methond finds all connected components in the graph described by adjacency lists and marks some ...
Definition graph.cpp:491
std::unordered_set< uint32_t > get_variables_in_one_gate()
this method returns a final set of variables that were in one gate
Definition graph.cpp:1021
std::unordered_map< uint32_t, size_t > get_variables_gate_counts() const
Definition graph.hpp:108
FF a
FF b
TEST(boomerang_ultra_circuit_constructor, test_graph_for_arithmetic_gates)
Test graph description of circuit with arithmetic gates.
ReadData< bb::fr > get_lookup_accumulators(const MultiTableId id, const fr &key_a, const fr &key_b, const bool is_2_to_1_lookup)
Given a table ID and the key(s) for a key-value lookup, return the lookup accumulators.
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
field< Bn254FrParams > fr
Definition fr.hpp:155
C slice(C const &container, size_t start)
Definition container.hpp:9
UltraCircuitBuilder_< UltraExecutionTraceBlocks > UltraCircuitBuilder
Definition graph.cpp:21
UltraStaticAnalyzer StaticAnalyzer
Definition graph.hpp:190
static constexpr field one()
static field random_element(numeric::RNG *engine=nullptr) noexcept
static constexpr field zero()