11#include <gtest/gtest.h>
23TEST(boomerang_ultra_circuit_constructor, test_graph_for_arithmetic_gates)
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);
32 uint32_t result_idx = circuit_constructor.
add_variable(
fr(left ^ right));
37 { left_idx, right_idx, result_idx, add_idx,
fr(1),
fr(1),
fr(1),
fr(-1),
fr(0) });
44 EXPECT_EQ(variables_in_one_gate.size(), 1024);
45 EXPECT_EQ(connected_components.size(), 256);
55TEST(boomerang_ultra_circuit_constructor, test_graph_for_arithmetic_gates_with_shifts)
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);
64 uint32_t result_idx = circuit_constructor.
add_variable(
fr(left ^ right));
69 { left_idx, right_idx, result_idx, add_idx,
fr(1),
fr(1),
fr(1),
fr(-1),
fr(0) },
true);
75 auto num_connected_components = connected_components.size();
76 bool result = num_connected_components == 1;
77 EXPECT_EQ(result,
true);
88TEST(boomerang_ultra_circuit_constructor, test_graph_for_boolean_gates)
92 for (
size_t i = 0; i < 20; ++i) {
100 auto num_connected_components = connected_components.size();
102 bool result = num_connected_components == 0;
103 EXPECT_EQ(result,
true);
104 EXPECT_EQ(variables_in_one_gate.size(), 20);
115TEST(boomerang_ultra_circuit_constructor, test_graph_for_elliptic_add_gate)
124 affine_element p3(element(p1) + element(p2));
137 auto num_connected_components = connected_components.size();
138 bool result = num_connected_components == 1;
139 EXPECT_EQ(result,
true);
150TEST(boomerang_ultra_circuit_constructor, test_graph_for_elliptic_double_gate)
157 affine_element p3(element(p1).dbl());
168 auto num_connected_components = connected_components.size();
169 bool result = num_connected_components == 1;
170 EXPECT_EQ(result,
true);
182TEST(boomerang_ultra_circuit_constructor, test_graph_for_elliptic_together)
191 affine_element p3(element(p1) + element(p2));
201 affine_element p4(element(p3).dbl());
208 affine_element p7(element(p5) + element(p6));
218 affine_element p8(element(p7).dbl());
225 auto num_connected_components = connected_components.size();
226 bool result = num_connected_components == 2;
227 EXPECT_EQ(result,
true);
239TEST(boomerang_ultra_circuit_constructor, test_graph_for_sort_constraints)
265 EXPECT_EQ(connected_components[0].size(), 4);
266 EXPECT_EQ(connected_components[1].size(), 4);
267 EXPECT_EQ(connected_components.size(), 2);
279TEST(boomerang_ultra_circuit_constructor, test_graph_for_sort_constraints_with_edges)
300 { a_idx, b_idx, c_idx, d_idx, e_idx, f_idx, g_idx, h_idx },
a, h);
321 { a1_idx, b1_idx, c1_idx, d1_idx, e1_idx, f1_idx, g1_idx, h1_idx }, a1, h1);
324 auto num_connected_components = connected_components.size();
325 bool result = num_connected_components == 2;
326 EXPECT_EQ(result,
true);
336TEST(boomerang_ultra_circuit_constructor, test_graph_with_plookup_accumulators)
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);
347 plookup::MultiTableId::FIXED_BASE_LEFT_LO, sequence_data_lo, input_lo_index);
349 const size_t num_lookups = plookup::fixed_base::table::NUM_TABLES_PER_LO_MULTITABLE;
351 EXPECT_EQ(num_lookups, lookup_witnesses[plookup::ColumnIdx::C1].size());
355 auto num_connected_components = connected_components.size();
356 bool result = num_connected_components == 1;
357 EXPECT_EQ(result,
true);
367TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_arithmetic_gate)
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);
377 uint32_t result_idx = circuit_constructor.
add_variable(
fr(left ^ right));
382 { left_idx, right_idx, result_idx, add_idx,
fr(1),
fr(1),
fr(1),
fr(-1),
fr(0) });
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);
397 EXPECT_EQ(result,
true);
407TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_arithmetic_gate_with_shifts)
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);
417 uint32_t result_idx = circuit_constructor.
add_variable(
fr(left ^ right));
422 { left_idx, right_idx, result_idx, add_idx,
fr(1),
fr(1),
fr(1),
fr(-1),
fr(0) },
true);
428 uint32_t zero_idx = circuit_constructor.
zero_idx();
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));
435 EXPECT_EQ(result,
true);
444TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_boolean_gates)
448 for (
size_t i = 0; i < 20; ++i) {
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);
463 EXPECT_EQ(result,
true);
473TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_sorted_constraints)
500 EXPECT_EQ(connected_components.size(), 2);
502 for (
const auto& var_idx : connected_components[0].vars()) {
503 result = result && (variables_gate_counts[var_idx] == 1);
506 for (
const auto& var_idx : connected_components[1].vars()) {
507 result = result && (variables_gate_counts[var_idx] == 1);
509 EXPECT_EQ(result,
true);
519TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_sorted_constraints_with_edges)
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));
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);
541 EXPECT_EQ(connected_components.size(), 2);
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";
557TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_ecc_add_gates)
566 affine_element p3(element(p1) + element(p2));
580 auto variable_indices = connected_components[0].vars();
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);
597TEST(boomerang_ultra_circuit_constructor, test_variables_gates_counts_for_ecc_dbl_gate)
604 affine_element p3(element(p1).dbl());
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);
622 EXPECT_EQ(connected_components.size(), 1);
623 EXPECT_EQ(result,
true);
633TEST(boomerang_ultra_circuit_constructor, test_graph_for_range_constraints)
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));
644 auto indices = add_variables({
fr(1),
fr(2),
fr(3),
fr(4) });
645 for (
size_t i = 0; i < indices.size(); i++) {
651 EXPECT_EQ(connected_components.size(), 1);
661TEST(boomerang_ultra_circuit_constructor, composed_range_constraint)
669 { a_idx, circuit_constructor.
zero_idx(), circuit_constructor.
zero_idx(), 1, 0, 0, -
fr(e) });
674 EXPECT_EQ(connected_components.size(), 1);
virtual uint32_t add_variable(const FF &in)
Add a variable to variables.
uint32_t zero_idx() const
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.
element class. Implements ecc group arithmetic using Jacobian coordinates See https://hyperelliptic....
group class. Represents an elliptic curve group element. Group is parametrised by Fq and Fr
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 ...
std::unordered_set< uint32_t > get_variables_in_one_gate()
this method returns a final set of variables that were in one gate
std::unordered_map< uint32_t, size_t > get_variables_gate_counts() const
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.
field< Bn254FrParams > fr
C slice(C const &container, size_t start)
UltraCircuitBuilder_< UltraExecutionTraceBlocks > UltraCircuitBuilder
UltraStaticAnalyzer StaticAnalyzer
static constexpr field one()
static field random_element(numeric::RNG *engine=nullptr) noexcept
static constexpr field zero()