Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
translator_selectors.test.cpp
Go to the documentation of this file.
7
8#include <gtest/gtest.h>
9
10using namespace bb;
11
12namespace {
13
22template <size_t LOG_MINI> void test_translator_selector_evaluations()
23{
24 using FF = fr;
26 using Poly = Polynomial<FF>;
27
28 constexpr size_t D = Evaluations::LOG_N;
29 constexpr size_t N = 1UL << D;
30 constexpr size_t MINI = 1UL << LOG_MINI;
31 constexpr size_t NUM_MASKED_ROWS_END = Evaluations::NUM_MASKED_ROWS_END;
32 constexpr size_t RESULT_ROW = Evaluations::RESULT_ROW;
33 constexpr size_t RANDOMNESS_START = Evaluations::RANDOMNESS_START;
34 constexpr size_t CONCATENATION_GROUP_SIZE = Evaluations::CONCATENATION_GROUP_SIZE;
35 constexpr size_t MAX_RANDOM_VALUES_PER_ORDERED = Evaluations::MAX_RANDOM_VALUES_PER_ORDERED;
36 constexpr size_t MINI_WITHOUT_MASKING = MINI - NUM_MASKED_ROWS_END;
37
38 // Random sumcheck challenge
39 std::vector<FF> u(D);
40 for (auto& ui : u) {
41 ui = FF::random_element();
42 }
43
44 // Compute selector evaluations analytically
45 auto evals = Evaluations::compute(u);
46
47 // Helper: create a full-size polynomial, set specified indices to 1, evaluate MLE
48 auto make_and_eval = [&](auto set_fn) -> FF {
49 Poly poly(N);
50 set_fn(poly);
51 return poly.evaluate_mle(u);
52 };
53
54 // --- lagrange_first: 1 at row 0 ---
55 EXPECT_EQ(make_and_eval([](Poly& p) { p.at(0) = 1; }), evals.lagrange_first);
56
57 // --- lagrange_last: 1 at row N-1 ---
58 EXPECT_EQ(make_and_eval([](Poly& p) { p.at(N - 1) = 1; }), evals.lagrange_last);
59
60 // --- lagrange_result_row: 1 at row RESULT_ROW ---
61 EXPECT_EQ(make_and_eval([](Poly& p) { p.at(RESULT_ROW) = 1; }), evals.lagrange_result_row);
62
63 // --- lagrange_last_in_minicircuit: 1 at row MINI - NUM_MASKED - 1 ---
64 EXPECT_EQ(make_and_eval([](Poly& p) { p.at(MINI_WITHOUT_MASKING - 1) = 1; }), evals.lagrange_last_in_minicircuit);
65
66 // --- lagrange_real_last: 1 at row N - MAX_RANDOM - 1 ---
67 EXPECT_EQ(make_and_eval([](Poly& p) { p.at(N - MAX_RANDOM_VALUES_PER_ORDERED - 1) = 1; }),
68 evals.lagrange_real_last);
69
70 // --- lagrange_ordered_masking: 1 at rows [N - MAX_RANDOM, N - 1] ---
71 EXPECT_EQ(make_and_eval([](Poly& p) {
72 for (size_t i = N - MAX_RANDOM_VALUES_PER_ORDERED; i < N; i++) {
73 p.at(i) = 1;
74 }
75 }),
76 evals.lagrange_ordered_masking);
77
78 // --- lagrange_masking: 1 at last NUM_MASKED rows of each of 16 blocks ---
79 EXPECT_EQ(make_and_eval([](Poly& p) {
80 for (size_t j = 0; j < CONCATENATION_GROUP_SIZE; j++) {
81 for (size_t k = MINI - NUM_MASKED_ROWS_END; k < MINI; k++) {
82 p.at(j * MINI + k) = 1;
83 }
84 }
85 }),
86 evals.lagrange_masking);
87
88 // --- lagrange_mini_masking: rows [RANDOMNESS_START..RESULT_ROW-1] ∪ [MINI-NUM_MASKED..MINI-1] in block 0 ---
89 EXPECT_EQ(make_and_eval([](Poly& p) {
90 for (size_t i = RANDOMNESS_START; i < RESULT_ROW; i++) {
91 p.at(i) = 1;
92 }
93 for (size_t i = MINI_WITHOUT_MASKING; i < MINI; i++) {
94 p.at(i) = 1;
95 }
96 }),
97 evals.lagrange_mini_masking);
98
99 // --- lagrange_even_in_minicircuit: 1 at even rows in [RESULT_ROW, MINI_WITHOUT_MASKING - 2], block 0 ---
100 EXPECT_EQ(make_and_eval([](Poly& p) {
101 for (size_t i = RESULT_ROW; i < MINI_WITHOUT_MASKING; i += 2) {
102 p.at(i) = 1;
103 }
104 }),
105 evals.lagrange_even_in_minicircuit);
106
107 // --- lagrange_odd_in_minicircuit: 1 at odd rows in [RESULT_ROW+1, MINI_WITHOUT_MASKING - 1], block 0 ---
108 EXPECT_EQ(make_and_eval([](Poly& p) {
109 for (size_t i = RESULT_ROW; i < MINI_WITHOUT_MASKING; i += 2) {
110 p.at(i + 1) = 1;
111 }
112 }),
113 evals.lagrange_odd_in_minicircuit);
114}
115
116} // anonymous namespace
117
118TEST(TranslatorSelectors, SmallCircuit)
119{
120 // LOG_MINI = 7: MINI = 128, N = 2048. Fast and tests the generic formulas.
121 test_translator_selector_evaluations<7>();
122}
123
124TEST(TranslatorSelectors, RealCircuit)
125{
126 // LOG_MINI = 13: MINI = 8192, N = 131072. Matches the actual Translator circuit size.
127 test_translator_selector_evaluations<13>();
128}
129
136template <typename Builder, size_t LOG_MINI> void test_translator_selector_circuit_cost()
137{
140 using NativeEvaluations = TranslatorSelectorEvaluations<fr, LOG_MINI>;
141 using CircuitEvaluations = TranslatorSelectorEvaluations<field_ct, LOG_MINI>;
142
143 constexpr size_t D = NativeEvaluations::LOG_N;
144
146
147 // Generate random native challenge and create circuit witnesses
148 std::vector<fr> u_native(D);
149 std::vector<field_ct> u_circuit(D);
150 for (size_t k = 0; k < D; k++) {
151 u_native[k] = fr::random_element();
152 u_circuit[k] = field_ct(witness_ct(&builder, u_native[k]));
153 }
154
155 // Compute native reference values
156 auto native_evals = NativeEvaluations::compute(u_native);
157
158 // Measure circuit cost
159 size_t gates_before = builder.num_gates();
160 auto circuit_evals = CircuitEvaluations::compute(u_circuit);
161 size_t gates_after = builder.num_gates();
162 size_t gates_added = gates_after - gates_before;
163
164 info("TranslatorSelectorEvaluations in-circuit cost (",
165 Builder::NAME_STRING,
166 ", LOG_MINI=",
167 LOG_MINI,
168 "): ",
169 gates_added,
170 " gates");
171
172 // Verify correctness: circuit values must match native values
173 EXPECT_EQ(circuit_evals.lagrange_first.get_value(), native_evals.lagrange_first);
174 EXPECT_EQ(circuit_evals.lagrange_last.get_value(), native_evals.lagrange_last);
175 EXPECT_EQ(circuit_evals.lagrange_odd_in_minicircuit.get_value(), native_evals.lagrange_odd_in_minicircuit);
176 EXPECT_EQ(circuit_evals.lagrange_even_in_minicircuit.get_value(), native_evals.lagrange_even_in_minicircuit);
177 EXPECT_EQ(circuit_evals.lagrange_result_row.get_value(), native_evals.lagrange_result_row);
178 EXPECT_EQ(circuit_evals.lagrange_last_in_minicircuit.get_value(), native_evals.lagrange_last_in_minicircuit);
179 EXPECT_EQ(circuit_evals.lagrange_masking.get_value(), native_evals.lagrange_masking);
180 EXPECT_EQ(circuit_evals.lagrange_mini_masking.get_value(), native_evals.lagrange_mini_masking);
181 EXPECT_EQ(circuit_evals.lagrange_real_last.get_value(), native_evals.lagrange_real_last);
182 EXPECT_EQ(circuit_evals.lagrange_ordered_masking.get_value(), native_evals.lagrange_ordered_masking);
183}
184
185TEST(TranslatorSelectors, CircuitCostUltra)
186{
187 test_translator_selector_circuit_cost<UltraCircuitBuilder, 13>();
188}
189
190TEST(TranslatorSelectors, CircuitCostMega)
191{
192 test_translator_selector_circuit_cost<MegaCircuitBuilder, 13>();
193}
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
#define info(...)
Definition log.hpp:93
AluTraceBuilder builder
Definition alu.test.cpp:124
stdlib::witness_t< Builder > witness_ct
stdlib::field_t< Builder > field_ct
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
field< Bn254FrParams > fr
Definition fr.hpp:155
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Evaluates the 10 structured Translator precomputed selectors at a sumcheck challenge point.
static field random_element(numeric::RNG *engine=nullptr) noexcept
void test_translator_selector_circuit_cost()
Measure the in-circuit cost of computing all 11 Translator selector evaluations.