barretenberg
Loading...
Searching...
No Matches
composer_lib.hpp
1#pragma once
3#include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp"
4#include "barretenberg/srs/factories/crs_factory.hpp"
5#include <memory>
6
7namespace proof_system {
8
16template <typename Flavor>
17void construct_selector_polynomials(const typename Flavor::CircuitBuilder& circuit_constructor,
18 typename Flavor::ProvingKey* proving_key)
19{
20 // Offset for starting to write selectors is zero row offset + num public inputs
21 const size_t zero_row_offset = Flavor::has_zero_row ? 1 : 0;
22 size_t gate_offset = zero_row_offset + circuit_constructor.public_inputs.size();
23
24 // If Goblin, (1) update the conventional gate offset to account for ecc op gates at the top of the execution trace,
25 // and (2) construct ecc op gate selector polynomial. This selector is handled separately from the others since it
26 // is computable based simply on num_ecc_op_gates and thus is not constructed explicitly in the builder.
27 // Note 1: All other selectors will be automatically and correctly initialized to 0 on this domain.
28 // Note 2: If applicable, the ecc op gates are shifted down by 1 to account for a zero row.
29 if constexpr (IsGoblinFlavor<Flavor>) {
30 const size_t num_ecc_op_gates = circuit_constructor.num_ecc_op_gates;
31 gate_offset += num_ecc_op_gates;
32 const size_t op_gate_offset = zero_row_offset;
33 // The op gate selector is simply the indicator on the domain [offset, num_ecc_op_gates + offset - 1]
34 barretenberg::polynomial ecc_op_selector(proving_key->circuit_size);
35 for (size_t i = 0; i < num_ecc_op_gates; ++i) {
36 ecc_op_selector[i + op_gate_offset] = 1;
37 }
38 proving_key->lagrange_ecc_op = ecc_op_selector.share();
39 }
40
41 // TODO(#398): Loose coupling here! Would rather build up pk from arithmetization
42 if constexpr (IsHonkFlavor<Flavor>) {
43 for (auto [poly, selector_values] : zip_view(ZipAllowDifferentSizes::FLAG,
44 proving_key->get_precomputed_polynomials(),
45 circuit_constructor.selectors.get())) {
46 ASSERT(proving_key->circuit_size >= selector_values.size());
47
48 // Copy the selector values for all gates, keeping the rows at which we store public inputs as 0.
49 // Initializing the polynomials in this way automatically applies 0-padding to the selectors.
50 typename Flavor::Polynomial selector_poly_lagrange(proving_key->circuit_size);
51 for (size_t i = 0; i < selector_values.size(); ++i) {
52 selector_poly_lagrange[i + gate_offset] = selector_values[i];
53 }
54 poly = selector_poly_lagrange.share();
55 }
56 } else if constexpr (IsPlonkFlavor<Flavor>) {
57 size_t selector_idx = 0;
58 for (auto& selector_values : circuit_constructor.selectors.get()) {
59 ASSERT(proving_key->circuit_size >= selector_values.size());
60
61 // Copy the selector values for all gates, keeping the rows at which we store public inputs as 0.
62 // Initializing the polynomials in this way automatically applies 0-padding to the selectors.
63 typename Flavor::Polynomial selector_poly_lagrange(proving_key->circuit_size);
64 for (size_t i = 0; i < selector_values.size(); ++i) {
65 selector_poly_lagrange[i + gate_offset] = selector_values[i];
66 }
67 // TODO(Cody): Loose coupling here of selector_names and selector_properties.
68 proving_key->polynomial_store.put(circuit_constructor.selector_names[selector_idx] + "_lagrange",
69 std::move(selector_poly_lagrange));
70 ++selector_idx;
71 }
72 }
73}
74
91template <typename Flavor>
92std::vector<typename Flavor::Polynomial> construct_wire_polynomials_base(
93 const typename Flavor::CircuitBuilder& circuit_constructor, const size_t dyadic_circuit_size)
94{
95 // Determine size of each block of data in the wire polynomials
96 const size_t num_zero_rows = Flavor::has_zero_row ? 1 : 0;
97 const size_t num_gates = circuit_constructor.num_gates;
98 std::span<const uint32_t> public_inputs = circuit_constructor.public_inputs;
99 const size_t num_public_inputs = public_inputs.size();
100 size_t num_ecc_op_gates = 0;
101 if constexpr (IsGoblinFlavor<Flavor>) {
102 num_ecc_op_gates = circuit_constructor.num_ecc_op_gates;
103 }
104
105 // Define offsets at which to start writing different blocks of data
106 size_t op_gate_offset = num_zero_rows;
107 size_t pub_input_offset = num_zero_rows + num_ecc_op_gates;
108 size_t gate_offset = num_zero_rows + num_ecc_op_gates + num_public_inputs;
109
110 std::vector<typename Flavor::Polynomial> wire_polynomials;
111
112 // Populate the wire polynomials with values from ecc op gates, public inputs and conventional wires
113 for (size_t wire_idx = 0; wire_idx < Flavor::NUM_WIRES; ++wire_idx) {
114
115 // Expect all values to be set to 0 initially
116 typename Flavor::Polynomial w_lagrange(dyadic_circuit_size);
117
118 // Insert leading zero row into wire poly (for clarity; not stricly necessary due to zero-initialization)
119 for (size_t i = 0; i < num_zero_rows; ++i) {
120 w_lagrange[i] = circuit_constructor.get_variable(circuit_constructor.zero_idx);
121 }
122
123 // Insert ECC op wire values into wire polynomial
124 if constexpr (IsGoblinFlavor<Flavor>) {
125 for (size_t i = 0; i < num_ecc_op_gates; ++i) {
126 auto& op_wire = circuit_constructor.ecc_op_wires[wire_idx];
127 w_lagrange[i + op_gate_offset] = circuit_constructor.get_variable(op_wire[i]);
128 }
129 }
130
131 // Insert public inputs (first two wire polynomials only)
132 if (wire_idx < 2) {
133 for (size_t i = 0; i < num_public_inputs; ++i) {
134 w_lagrange[i + pub_input_offset] = circuit_constructor.get_variable(public_inputs[i]);
135 }
136 }
137
138 // Insert conventional gate wire values into the wire polynomial
139 for (size_t i = 0; i < num_gates; ++i) {
140 auto& wire = circuit_constructor.wires[wire_idx];
141 w_lagrange[i + gate_offset] = circuit_constructor.get_variable(wire[i]);
142 }
143
144 wire_polynomials.push_back(std::move(w_lagrange));
145 }
146 return wire_polynomials;
147}
148} // namespace proof_system
Definition: zip_view.hpp:159
Base class templates for structures that contain data parameterized by the fundamental polynomials of...