Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
translator_circuit_checker.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Planned, auditors: [], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
9
10namespace bb {
11
13{
14 Params params;
15
16 const Fq v = circuit.batching_challenge_v;
17 const Fq v2 = v * v;
18 const Fq v3 = v2 * v;
19 const Fq v4 = v3 * v;
20
21 const auto x_limbs = Builder::split_fq_into_limbs(circuit.evaluation_input_x);
22 const auto v_limbs = Builder::split_fq_into_limbs(v);
23 const auto v2_limbs = Builder::split_fq_into_limbs(v2);
24 const auto v3_limbs = Builder::split_fq_into_limbs(v3);
25 const auto v4_limbs = Builder::split_fq_into_limbs(v4);
26
27 // evaluation_input_x: 4 binary limbs + 1 native Fr representation
28 params.evaluation_input_x = {
29 x_limbs[0], x_limbs[1], x_limbs[2], x_limbs[3], Fr(uint256_t(circuit.evaluation_input_x))
30 };
31
32 // batching_challenge_v^1 through v^4: each has 4 binary limbs + 1 native Fr
33 params.batching_challenge_v[0] = { v_limbs[0], v_limbs[1], v_limbs[2], v_limbs[3], Fr(uint256_t(v)) };
34 params.batching_challenge_v[1] = { v2_limbs[0], v2_limbs[1], v2_limbs[2], v2_limbs[3], Fr(uint256_t(v2)) };
35 params.batching_challenge_v[2] = { v3_limbs[0], v3_limbs[1], v3_limbs[2], v3_limbs[3], Fr(uint256_t(v3)) };
36 params.batching_challenge_v[3] = { v4_limbs[0], v4_limbs[1], v4_limbs[2], v4_limbs[3], Fr(uint256_t(v4)) };
37
38 // accumulated_result: the 4 binary limbs stored at RESULT_ROW.
39 // The AccumulatorTransferRelation verifies this matches the accumulator at the result row.
41 params.accumulated_result = {
42 circuit.get_variable(circuit.wires[WireIds::ACCUMULATORS_BINARY_LIMBS_0][RESULT_ROW]),
43 circuit.get_variable(circuit.wires[WireIds::ACCUMULATORS_BINARY_LIMBS_1][RESULT_ROW]),
44 circuit.get_variable(circuit.wires[WireIds::ACCUMULATORS_BINARY_LIMBS_2][RESULT_ROW]),
45 circuit.get_variable(circuit.wires[WireIds::ACCUMULATORS_BINARY_LIMBS_3][RESULT_ROW]),
46 };
47
48 return params;
49}
50
51void TranslatorCircuitChecker::populate_values(const Builder& circuit, AllValues& values, size_t row_idx)
52{
53 const size_t num_gates = circuit.num_gates();
54 BB_ASSERT_LT(row_idx, num_gates);
55
56 // -----------------------------------------------------------------------
57 // Wire values at current row
58 // get_wires() returns 81 refs in WireIds order: [op, x_lo_y_hi, ..., range_constraints]
59 // This matches circuit.wires[0..80] exactly.
60 // -----------------------------------------------------------------------
61 auto wire_refs = values.get_wires();
62 for (size_t j = 0; j < Builder::WireIds::TOTAL_COUNT; j++) {
63 wire_refs[j] = circuit.get_variable(circuit.wires[j][row_idx]);
64 }
65
66 // -----------------------------------------------------------------------
67 // Shifted wire values (= values at next row, or zero at boundary).
68 // ShiftedEntities::get_all() returns 86 refs:
69 // [0..79] : shifts of circuit.wires[1..80] (x_lo_y_hi through last range constraint)
70 // [80..85] : shifts of ordered range constraints (0..4) and z_perm (not from circuit wires)
71 // -----------------------------------------------------------------------
72 auto& shifted_base = static_cast<Flavor::ShiftedEntities<Fr>&>(values);
73 auto shifted_refs = shifted_base.get_all();
74 if (row_idx + 1 < num_gates) {
75 // circuit.wires[j+1] holds the wire that shifts to shifted_refs[j]
76 for (size_t j = 0; j < 80; j++) {
77 shifted_refs[j] = circuit.get_variable(circuit.wires[j + 1][row_idx + 1]);
78 }
79 }
80 // shifted_refs[80..85] (ordered range constraints + z_perm) remain zero;
81 // the relations that use them (Permutation, DeltaRange) are not checked here.
82
83 // -----------------------------------------------------------------------
84 // Lagrange selector values — computed analytically from the row index.
85 //
86 // Translator processes the trace in two regions per mini-circuit:
87 // [0, RANDOMNESS_START) : initialisation rows (rows 0..1)
88 // [RANDOMNESS_START, RESULT_ROW) : random no-op rows (lagrange_mini_masking)
89 // [RESULT_ROW, num_without_mask) : actual accumulation rows (even/odd processing)
90 // [num_without_mask, num_gates) : end-masking rows (lagrange_mini_masking, unless AVM mode)
91 // -----------------------------------------------------------------------
92 const size_t end_masking_rows = circuit.avm_mode ? 0 : Flavor::NUM_MASKED_ROWS_END;
93 const size_t num_without_mask = (num_gates > end_masking_rows) ? (num_gates - end_masking_rows) : num_gates;
94
95 const bool in_start_random_range = (row_idx >= Flavor::RANDOMNESS_START && row_idx < RESULT_ROW);
96 const bool in_end_random_range = (row_idx >= num_without_mask);
97 const bool in_processing_range = (row_idx >= RESULT_ROW && row_idx < num_without_mask);
98 const bool is_even = (row_idx % 2 == 0);
99
100 values.lagrange_mini_masking = Fr(in_start_random_range || in_end_random_range ? 1 : 0);
101 values.lagrange_even_in_minicircuit = Fr(in_processing_range && is_even ? 1 : 0);
102 values.lagrange_odd_in_minicircuit = Fr(in_processing_range && !is_even ? 1 : 0);
103 values.lagrange_result_row = Fr(row_idx == RESULT_ROW ? 1 : 0);
104 values.lagrange_last_in_minicircuit = Fr(num_without_mask > 0 && row_idx == num_without_mask - 1 ? 1 : 0);
105}
106
108{
109 using OpcodeConstraint = TranslatorOpcodeConstraintRelation<Fr>;
110 using AccumulatorTransfer = TranslatorAccumulatorTransferRelation<Fr>;
111 using Decomposition = TranslatorDecompositionRelation<Fr>;
112 using NonNativeField = TranslatorNonNativeFieldRelation<Fr>;
113
114 const Params params = compute_relation_params(circuit);
115 AllValues values{};
116
117 for (size_t i = 0; i < circuit.num_gates(); ++i) {
118 populate_values(circuit, values, i);
119
120 if (!check_relation<OpcodeConstraint>(values, params)) {
121 info("TranslatorCircuitChecker: Failed TranslatorOpcodeConstraintRelation at row = ", i);
122 return false;
123 }
124 if (!check_relation<AccumulatorTransfer>(values, params)) {
125 info("TranslatorCircuitChecker: Failed TranslatorAccumulatorTransferRelation at row = ", i);
126 return false;
127 }
128 if (!check_relation<Decomposition>(values, params)) {
129 info("TranslatorCircuitChecker: Failed TranslatorDecompositionRelation at row = ", i);
130 return false;
131 }
132 if (!check_relation<NonNativeField>(values, params)) {
133 info("TranslatorCircuitChecker: Failed TranslatorNonNativeFieldRelation at row = ", i);
134 return false;
135 }
136 }
137 return true;
138}
139
140} // namespace bb
#define BB_ASSERT_GT(left, right,...)
Definition assert.hpp:113
#define BB_ASSERT_LT(left, right,...)
Definition assert.hpp:143
FF get_variable(const uint32_t index) const
Get the value of the variable v_{index}.
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
TranslatorCircuitBuilder creates a circuit that evaluates the correctness of the evaluation of EccOpQ...
static std::array< Fr, NUM_BINARY_LIMBS > split_fq_into_limbs(const Fq &base)
A small function to transform a native element Fq into its bigfield representation in Fr scalars.
std::array< std::vector< uint32_t >, NUM_WIRES > wires
static void populate_values(const Builder &circuit, AllValues &values, size_t row_idx)
Populate an AllValues struct for a single row of the circuit.
static Params compute_relation_params(const Builder &circuit)
Build the RelationParameters from the circuit's public inputs.
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
A field element for each entity of the flavor. These entities represent the prover polynomials evalua...
Represents polynomials shifted by 1 or their evaluations, defined relative to WireToBeShiftedEntities...
static constexpr size_t RANDOMNESS_START
static constexpr size_t NUM_MASKED_ROWS_END
#define info(...)
Definition log.hpp:93
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
Container for parameters used by the grand product (permutation, lookup) Honk relations.
std::array< std::array< T, NUM_BINARY_LIMBS_IN_GOBLIN_TRANSLATOR+NUM_NATIVE_LIMBS_IN_GOBLIN_TRANSLATOR >, NUM_CHALLENGE_POWERS_IN_GOBLIN_TRANSLATOR > batching_challenge_v
std::array< T, NUM_BINARY_LIMBS_IN_GOBLIN_TRANSLATOR > accumulated_result
std::array< T, NUM_BINARY_LIMBS_IN_GOBLIN_TRANSLATOR+NUM_NATIVE_LIMBS_IN_GOBLIN_TRANSLATOR > evaluation_input_x