Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
translator_circuit_builder.test.cpp
Go to the documentation of this file.
5#include <array>
6#include <cstddef>
7#include <gtest/gtest.h>
8
9using namespace bb;
10namespace {
12}
18TEST(TranslatorCircuitBuilder, CircuitBuilderBaseCase)
19{
22
23 constexpr size_t NUM_LIMB_BITS = TranslatorCircuitBuilder::NUM_LIMB_BITS;
24 constexpr size_t NUM_Z_BITS = TranslatorCircuitBuilder::NUM_Z_BITS;
25
26 // Generate random EccOpQueue transcript values
27 EccOpCode op_code;
28 switch (engine.get_random_uint8() % 4) {
29 case 0:
30 op_code = {};
31 break;
32 case 1:
33 op_code = { .eq = true, .reset = true };
34 break;
35 case 2:
36 op_code = { .mul = true };
37 break;
38 case 3:
39 op_code = { .add = true };
40 break;
41 }
42 auto get_random_z_scalar = []() { return Fr(engine.get_random_uint256().slice(0, NUM_Z_BITS)); };
43
44 Fq p_x = Fq::random_element();
45 Fr p_x_lo = uint256_t(p_x).slice(0, 2 * NUM_LIMB_BITS);
46 Fr p_x_hi = uint256_t(p_x).slice(2 * NUM_LIMB_BITS, 4 * NUM_LIMB_BITS);
47 Fq p_y = Fq::random_element();
48 Fr p_y_lo = uint256_t(p_y).slice(0, 2 * NUM_LIMB_BITS);
49 Fr p_y_hi = uint256_t(p_y).slice(2 * NUM_LIMB_BITS, 4 * NUM_LIMB_BITS);
50 Fr z_1 = get_random_z_scalar();
51 Fr z_2 = get_random_z_scalar();
54
55 Fq previous_accumulator = Fq(0);
56
57 // Create a circuit builder
58 auto circuit_builder = TranslatorCircuitBuilder(v, x);
59 UltraOp op = UltraOp{
60 .op_code = op_code, .x_lo = p_x_lo, .x_hi = p_x_hi, .y_lo = p_y_lo, .y_hi = p_y_hi, .z_1 = z_1, .z_2 = z_2
61 };
62
63 // Generate the witness for a single step
64 TranslatorCircuitBuilder::AccumulationInput single_accumulation_step =
65 TranslatorCircuitBuilder::generate_witness_values(op, previous_accumulator, v, x);
66
67 // Submit one accumulation step in the builder
68 circuit_builder.create_accumulation_gate(single_accumulation_step);
69 // Check if the circuit fails
70 EXPECT_TRUE(TranslatorCircuitChecker::check(circuit_builder));
71}
72
77TEST(TranslatorCircuitBuilder, SeveralOperationCorrectness)
78{
79 using point = g1::affine_element;
80 using scalar = fr;
81 using Fq = fq;
82
83 auto P1 = point::random_element();
84 auto P2 = point::random_element();
85 auto z = scalar::random_element();
86
87 // Add the same operations to the ECC op queue; the native computation is performed under the hood.
88 auto op_queue = std::make_shared<ECCOpQueue>();
89 op_queue->no_op_ultra_only();
90 op_queue->add_accumulate(P1);
91 op_queue->mul_accumulate(P2, z);
92 Fq op_accumulator = 0;
93 Fq p_x_accumulator = 0;
94 Fq p_y_accumulator = 0;
95 Fq z_1_accumulator = 0;
96 Fq z_2_accumulator = 0;
97 Fq batching_challenge = fq::random_element();
98
99 op_queue->eq_and_reset();
100 op_queue->empty_row_for_testing();
101 op_queue->merge();
102
103 // Sample the evaluation input x
105 // Get an inverse
106 Fq x_inv = x.invert();
107 // Compute the batched evaluation of polynomials (multiplying by inverse to go from lower to higher)
108 const auto& ultra_ops = op_queue->get_ultra_ops();
109 for (size_t i = 1; i < ultra_ops.size(); i++) {
110 const auto& ecc_op = ultra_ops[i];
111 op_accumulator = op_accumulator * x_inv + ecc_op.op_code.value();
112 const auto [x_u256, y_u256] = ecc_op.get_base_point_standard_form();
113 p_x_accumulator = p_x_accumulator * x_inv + x_u256;
114 p_y_accumulator = p_y_accumulator * x_inv + y_u256;
115 z_1_accumulator = z_1_accumulator * x_inv + uint256_t(ecc_op.z_1);
116 z_2_accumulator = z_2_accumulator * x_inv + uint256_t(ecc_op.z_2);
117 }
118 // The degree is ultra_ops.size() - 2 as we ignore the first no-op in computation
119 Fq x_pow = x.pow(ultra_ops.size() - 2);
120
121 // Multiply by an appropriate power of x to get rid of the inverses
122 Fq result = ((((z_2_accumulator * batching_challenge + z_1_accumulator) * batching_challenge + p_y_accumulator) *
123 batching_challenge +
124 p_x_accumulator) *
125 batching_challenge +
126 op_accumulator) *
127 x_pow;
128
129 // Create circuit builder and feed the queue inside
130 auto circuit_builder = TranslatorCircuitBuilder(batching_challenge, x, op_queue);
131 // Check that the circuit passes
132 EXPECT_TRUE(CircuitChecker::check(circuit_builder));
133 // Check the accumulation result stored as 4 limbs in the circuit and then reconstructed is consistent with the
134 // value computed by hand.
135 EXPECT_EQ(result, CircuitChecker::get_computation_result(circuit_builder));
136}
The unified interface for check circuit functionality implemented in the specialized CircuitChecker c...
TranslatorCircuitBuilder creates a circuit that evaluates the correctness of the evaluation of EccOpQ...
static AccumulationInput generate_witness_values(const UltraOp &ultra_op, const Fq &previous_accumulator, const Fq &batching_challenge_v, const Fq &evaluation_input_x)
Given the transcript values from the EccOpQueue, the values of the previous accumulator,...
static Fq get_computation_result(const Builder &circuit)
Get the result of accumulation, stored as 4 binary limbs in the first row of the circuit.
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
bb::fq BaseField
Definition bn254.hpp:19
bb::fr ScalarField
Definition bn254.hpp:18
group_elements::affine_element< Fq, Fr, Params > affine_element
Definition group.hpp:42
virtual uint8_t get_random_uint8()=0
virtual uint256_t get_random_uint256()=0
constexpr uint256_t slice(uint64_t start, uint64_t end) const
numeric::RNG & engine
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:190
Entry point for Barretenberg command-line interface.
field< Bn254FqParams > fq
Definition fq.hpp:169
TEST(MegaCircuitBuilder, CopyConstructor)
field< Bn254FrParams > fr
Definition fr.hpp:174
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Curve::ScalarField Fr
Defines the opcodes for ECC operations used in both the Ultra and ECCVM formats. There are three opco...
The accumulation input structure contains all the necessary values to initalize an accumulation gate ...
EccOpCode op_code
BB_INLINE constexpr field pow(const uint256_t &exponent) const noexcept
constexpr field invert() const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
bb::fq Fq