Skip to content

Commit c52acf6

Browse files
authored
feat(avm-main): pil -> permutations (AztecProtocol#3650)
Replacing the toy_avm with a pil version that defines a permutation in pil. ``` pol commit q_tuple_set; // Set 1 pol commit set_1_column_1; pol commit set_1_column_2; // Set 2 pol commit set_2_column_1; pol commit set_2_column_2; // This is a column based tuple permutation #[two_column_perm] // the name of the inverse polynomial q_tuple_set { set_1_column_1, set_1_column_2 } is { set_2_column_1, set_2_column_2 }; ``` Syntax is as shown.
1 parent 17ba715 commit c52acf6

26 files changed

+1225
-866
lines changed

barretenberg/.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ node_modules
55
ts/dest
66
.tsbuildinfo
77
.idea
8-
cmake-build-debug
8+
cmake-build-debug
9+
*_opt.pil

barretenberg/cpp/pil/avm/toy_avm.pil

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace toy(256);
2+
pol commit q_tuple_set;
3+
4+
// Set 1
5+
pol commit set_1_column_1;
6+
pol commit set_1_column_2;
7+
// Set 2
8+
pol commit set_2_column_1;
9+
pol commit set_2_column_2;
10+
11+
// This is a column based tuple lookup
12+
#[two_column_perm] // the name of the inverse
13+
q_tuple_set { set_1_column_1, set_1_column_2 } is { set_2_column_1, set_2_column_2 };
14+
15+
// Relation not used -> we currently require a single relation for codegen
16+
pol commit x;
17+
x' - x = 0;
18+
19+
// Also needs a fixed relation
20+
pol fixed first = [1] + [0]*;

barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp

+11-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "barretenberg/polynomials/barycentric.hpp"
88
#include "barretenberg/polynomials/univariate.hpp"
99

10+
#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp"
11+
1012
#include "barretenberg/flavor/flavor.hpp"
1113
#include "barretenberg/flavor/flavor_macros.hpp"
1214
#include "barretenberg/polynomials/evaluation_domain.hpp"
@@ -40,7 +42,7 @@ class AvmMiniFlavor {
4042
// the unshifted and one for the shifted
4143
static constexpr size_t NUM_ALL_ENTITIES = 30;
4244

43-
using Relations = std::tuple<AvmMini_vm::avm_mini<FF>, AvmMini_vm::mem_trace<FF>>;
45+
using Relations = std::tuple<AvmMini_vm::mem_trace<FF>, AvmMini_vm::avm_mini<FF>>;
4446

4547
static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length<Relations>();
4648

@@ -144,8 +146,8 @@ class AvmMiniFlavor {
144146
avmMini_mem_idx_c,
145147
avmMini_last,
146148
memTrace_m_rw_shift,
147-
memTrace_m_val_shift,
148-
memTrace_m_addr_shift)
149+
memTrace_m_addr_shift,
150+
memTrace_m_val_shift)
149151

150152
RefVector<DataType> get_wires()
151153
{
@@ -177,8 +179,8 @@ class AvmMiniFlavor {
177179
avmMini_mem_idx_c,
178180
avmMini_last,
179181
memTrace_m_rw_shift,
180-
memTrace_m_val_shift,
181-
memTrace_m_addr_shift };
182+
memTrace_m_addr_shift,
183+
memTrace_m_val_shift };
182184
};
183185
RefVector<DataType> get_unshifted()
184186
{
@@ -210,10 +212,10 @@ class AvmMiniFlavor {
210212
avmMini_mem_idx_c,
211213
avmMini_last };
212214
};
213-
RefVector<DataType> get_to_be_shifted() { return { memTrace_m_rw, memTrace_m_val, memTrace_m_addr }; };
215+
RefVector<DataType> get_to_be_shifted() { return { memTrace_m_rw, memTrace_m_addr, memTrace_m_val }; };
214216
RefVector<DataType> get_shifted()
215217
{
216-
return { memTrace_m_rw_shift, memTrace_m_val_shift, memTrace_m_addr_shift };
218+
return { memTrace_m_rw_shift, memTrace_m_addr_shift, memTrace_m_val_shift };
217219
};
218220
};
219221

@@ -467,4 +469,6 @@ class AvmMiniFlavor {
467469
};
468470

469471
} // namespace flavor
472+
473+
namespace sumcheck {}
470474
} // namespace proof_system::honk
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
2+
3+
#pragma once
4+
#include "../relation_definitions_fwd.hpp"
5+
#include "barretenberg/commitment_schemes/kzg/kzg.hpp"
6+
#include "barretenberg/ecc/curves/bn254/g1.hpp"
7+
#include "barretenberg/polynomials/barycentric.hpp"
8+
#include "barretenberg/polynomials/univariate.hpp"
9+
10+
#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp"
11+
12+
#include "barretenberg/flavor/flavor.hpp"
13+
#include "barretenberg/flavor/flavor_macros.hpp"
14+
#include "barretenberg/polynomials/evaluation_domain.hpp"
15+
#include "barretenberg/polynomials/polynomial.hpp"
16+
#include "barretenberg/relations/generated/Toy/toy_avm.hpp"
17+
#include "barretenberg/relations/generated/Toy/two_column_perm.hpp"
18+
#include "barretenberg/transcript/transcript.hpp"
19+
20+
namespace proof_system::honk {
21+
namespace flavor {
22+
23+
class ToyFlavor {
24+
public:
25+
using Curve = curve::BN254;
26+
using G1 = Curve::Group;
27+
using PCS = pcs::kzg::KZG<Curve>;
28+
29+
using FF = G1::subgroup_field;
30+
using Polynomial = barretenberg::Polynomial<FF>;
31+
using PolynomialHandle = std::span<FF>;
32+
using GroupElement = G1::element;
33+
using Commitment = G1::affine_element;
34+
using CommitmentHandle = G1::affine_element;
35+
using CommitmentKey = pcs::CommitmentKey<Curve>;
36+
using VerifierCommitmentKey = pcs::VerifierCommitmentKey<Curve>;
37+
38+
static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 1;
39+
static constexpr size_t NUM_WITNESS_ENTITIES = 7;
40+
static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES;
41+
// We have two copies of the witness entities, so we subtract the number of fixed ones (they have no shift), one for
42+
// the unshifted and one for the shifted
43+
static constexpr size_t NUM_ALL_ENTITIES = 9;
44+
45+
using Relations = std::tuple<Toy_vm::toy_avm<FF>, sumcheck::two_column_perm_relation<FF>>;
46+
47+
static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length<Relations>();
48+
49+
// BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta`
50+
// random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation
51+
// length = 3
52+
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1;
53+
static constexpr size_t NUM_RELATIONS = std::tuple_size<Relations>::value;
54+
55+
template <size_t NUM_INSTANCES>
56+
using ProtogalaxyTupleOfTuplesOfUnivariates =
57+
decltype(create_protogalaxy_tuple_of_tuples_of_univariates<Relations, NUM_INSTANCES>());
58+
using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates<Relations>());
59+
using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values<Relations>());
60+
61+
static constexpr bool has_zero_row = true;
62+
63+
private:
64+
template <typename DataType_> class PrecomputedEntities : public PrecomputedEntitiesBase {
65+
public:
66+
using DataType = DataType_;
67+
68+
DEFINE_FLAVOR_MEMBERS(DataType, toy_first)
69+
70+
RefVector<DataType> get_selectors() { return { toy_first }; };
71+
RefVector<DataType> get_sigma_polynomials() { return {}; };
72+
RefVector<DataType> get_id_polynomials() { return {}; };
73+
RefVector<DataType> get_table_polynomials() { return {}; };
74+
};
75+
76+
template <typename DataType> class WitnessEntities {
77+
public:
78+
DEFINE_FLAVOR_MEMBERS(DataType,
79+
toy_q_tuple_set,
80+
toy_set_1_column_1,
81+
toy_set_1_column_2,
82+
toy_set_2_column_1,
83+
toy_set_2_column_2,
84+
toy_x,
85+
two_column_perm)
86+
87+
RefVector<DataType> get_wires()
88+
{
89+
return { toy_q_tuple_set, toy_set_1_column_1, toy_set_1_column_2, toy_set_2_column_1, toy_set_2_column_2,
90+
toy_x, two_column_perm };
91+
};
92+
RefVector<DataType> get_sorted_polynomials() { return {}; };
93+
};
94+
95+
template <typename DataType> class AllEntities {
96+
public:
97+
DEFINE_FLAVOR_MEMBERS(DataType,
98+
toy_first,
99+
toy_q_tuple_set,
100+
toy_set_1_column_1,
101+
toy_set_1_column_2,
102+
toy_set_2_column_1,
103+
toy_set_2_column_2,
104+
toy_x,
105+
two_column_perm,
106+
toy_x_shift)
107+
108+
RefVector<DataType> get_wires()
109+
{
110+
return { toy_first, toy_q_tuple_set, toy_set_1_column_1, toy_set_1_column_2, toy_set_2_column_1,
111+
toy_set_2_column_2, toy_x, two_column_perm, toy_x_shift };
112+
};
113+
RefVector<DataType> get_unshifted()
114+
{
115+
return { toy_first, toy_q_tuple_set, toy_set_1_column_1, toy_set_1_column_2, toy_set_2_column_1,
116+
toy_set_2_column_2, toy_x, two_column_perm };
117+
};
118+
RefVector<DataType> get_to_be_shifted() { return { toy_x }; };
119+
RefVector<DataType> get_shifted() { return { toy_x_shift }; };
120+
};
121+
122+
public:
123+
class ProvingKey : public ProvingKey_<PrecomputedEntities<Polynomial>, WitnessEntities<Polynomial>> {
124+
public:
125+
// Expose constructors on the base class
126+
using Base = ProvingKey_<PrecomputedEntities<Polynomial>, WitnessEntities<Polynomial>>;
127+
using Base::Base;
128+
129+
// The plookup wires that store plookup read data.
130+
std::array<PolynomialHandle, 0> get_table_column_wires() { return {}; };
131+
};
132+
133+
using VerificationKey = VerificationKey_<PrecomputedEntities<Commitment>>;
134+
135+
using ProverPolynomials = AllEntities<PolynomialHandle>;
136+
137+
using FoldedPolynomials = AllEntities<std::vector<FF>>;
138+
139+
class AllValues : public AllEntities<FF> {
140+
public:
141+
using Base = AllEntities<FF>;
142+
using Base::Base;
143+
};
144+
145+
class AllPolynomials : public AllEntities<Polynomial> {
146+
public:
147+
[[nodiscard]] size_t get_polynomial_size() const { return this->toy_q_tuple_set.size(); }
148+
[[nodiscard]] AllValues get_row(const size_t row_idx) const
149+
{
150+
AllValues result;
151+
for (auto [result_field, polynomial] : zip_view(result.get_all(), get_all())) {
152+
result_field = polynomial[row_idx];
153+
}
154+
return result;
155+
}
156+
};
157+
158+
using RowPolynomials = AllEntities<FF>;
159+
160+
class PartiallyEvaluatedMultivariates : public AllEntities<Polynomial> {
161+
public:
162+
PartiallyEvaluatedMultivariates() = default;
163+
PartiallyEvaluatedMultivariates(const size_t circuit_size)
164+
{
165+
// Storage is only needed after the first partial evaluation, hence polynomials of size (n / 2)
166+
for (auto& poly : get_all()) {
167+
poly = Polynomial(circuit_size / 2);
168+
}
169+
}
170+
};
171+
172+
/**
173+
* @brief A container for univariates used during Protogalaxy folding and sumcheck.
174+
* @details During folding and sumcheck, the prover evaluates the relations on these univariates.
175+
*/
176+
template <size_t LENGTH> using ProverUnivariates = AllEntities<barretenberg::Univariate<FF, LENGTH>>;
177+
178+
/**
179+
* @brief A container for univariates produced during the hot loop in sumcheck.
180+
*/
181+
using ExtendedEdges = ProverUnivariates<MAX_PARTIAL_RELATION_LENGTH>;
182+
183+
class CommitmentLabels : public AllEntities<std::string> {
184+
private:
185+
using Base = AllEntities<std::string>;
186+
187+
public:
188+
CommitmentLabels()
189+
: AllEntities<std::string>()
190+
{
191+
Base::toy_first = "TOY_FIRST";
192+
Base::toy_q_tuple_set = "TOY_Q_TUPLE_SET";
193+
Base::toy_set_1_column_1 = "TOY_SET_1_COLUMN_1";
194+
Base::toy_set_1_column_2 = "TOY_SET_1_COLUMN_2";
195+
Base::toy_set_2_column_1 = "TOY_SET_2_COLUMN_1";
196+
Base::toy_set_2_column_2 = "TOY_SET_2_COLUMN_2";
197+
Base::toy_x = "TOY_X";
198+
Base::two_column_perm = "TWO_COLUMN_PERM";
199+
};
200+
};
201+
202+
class VerifierCommitments : public AllEntities<Commitment> {
203+
private:
204+
using Base = AllEntities<Commitment>;
205+
206+
public:
207+
VerifierCommitments(const std::shared_ptr<VerificationKey>& verification_key)
208+
{
209+
toy_first = verification_key->toy_first;
210+
}
211+
};
212+
213+
class Transcript : public BaseTranscript {
214+
public:
215+
uint32_t circuit_size;
216+
217+
Commitment toy_q_tuple_set;
218+
Commitment toy_set_1_column_1;
219+
Commitment toy_set_1_column_2;
220+
Commitment toy_set_2_column_1;
221+
Commitment toy_set_2_column_2;
222+
Commitment toy_x;
223+
Commitment two_column_perm;
224+
225+
std::vector<barretenberg::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>> sumcheck_univariates;
226+
std::array<FF, NUM_ALL_ENTITIES> sumcheck_evaluations;
227+
std::vector<Commitment> zm_cq_comms;
228+
Commitment zm_cq_comm;
229+
Commitment zm_pi_comm;
230+
231+
Transcript() = default;
232+
233+
Transcript(const std::vector<uint8_t>& proof)
234+
: BaseTranscript(proof)
235+
{}
236+
237+
void deserialize_full_transcript()
238+
{
239+
size_t num_bytes_read = 0;
240+
circuit_size = deserialize_from_buffer<uint32_t>(proof_data, num_bytes_read);
241+
size_t log_n = numeric::get_msb(circuit_size);
242+
243+
toy_q_tuple_set = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
244+
toy_set_1_column_1 = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
245+
toy_set_1_column_2 = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
246+
toy_set_2_column_1 = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
247+
toy_set_2_column_2 = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
248+
toy_x = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
249+
two_column_perm = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
250+
251+
for (size_t i = 0; i < log_n; ++i) {
252+
sumcheck_univariates.emplace_back(
253+
deserialize_from_buffer<barretenberg::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(
254+
Transcript::proof_data, num_bytes_read));
255+
}
256+
sumcheck_evaluations =
257+
deserialize_from_buffer<std::array<FF, NUM_ALL_ENTITIES>>(Transcript::proof_data, num_bytes_read);
258+
for (size_t i = 0; i < log_n; ++i) {
259+
zm_cq_comms.push_back(deserialize_from_buffer<Commitment>(proof_data, num_bytes_read));
260+
}
261+
zm_cq_comm = deserialize_from_buffer<Commitment>(proof_data, num_bytes_read);
262+
zm_pi_comm = deserialize_from_buffer<Commitment>(proof_data, num_bytes_read);
263+
}
264+
265+
void serialize_full_transcript()
266+
{
267+
size_t old_proof_length = proof_data.size();
268+
Transcript::proof_data.clear();
269+
size_t log_n = numeric::get_msb(circuit_size);
270+
271+
serialize_to_buffer(circuit_size, Transcript::proof_data);
272+
273+
serialize_to_buffer<Commitment>(toy_q_tuple_set, Transcript::proof_data);
274+
serialize_to_buffer<Commitment>(toy_set_1_column_1, Transcript::proof_data);
275+
serialize_to_buffer<Commitment>(toy_set_1_column_2, Transcript::proof_data);
276+
serialize_to_buffer<Commitment>(toy_set_2_column_1, Transcript::proof_data);
277+
serialize_to_buffer<Commitment>(toy_set_2_column_2, Transcript::proof_data);
278+
serialize_to_buffer<Commitment>(toy_x, Transcript::proof_data);
279+
serialize_to_buffer<Commitment>(two_column_perm, Transcript::proof_data);
280+
281+
for (size_t i = 0; i < log_n; ++i) {
282+
serialize_to_buffer(sumcheck_univariates[i], Transcript::proof_data);
283+
}
284+
serialize_to_buffer(sumcheck_evaluations, Transcript::proof_data);
285+
for (size_t i = 0; i < log_n; ++i) {
286+
serialize_to_buffer(zm_cq_comms[i], proof_data);
287+
}
288+
serialize_to_buffer(zm_cq_comm, proof_data);
289+
serialize_to_buffer(zm_pi_comm, proof_data);
290+
291+
// sanity check to make sure we generate the same length of proof as before.
292+
ASSERT(proof_data.size() == old_proof_length);
293+
}
294+
};
295+
};
296+
297+
} // namespace flavor
298+
299+
namespace sumcheck {
300+
301+
DECLARE_SUMCHECK_RELATION_CLASS(two_column_perm, flavor::ToyFlavor);
302+
303+
}
304+
} // namespace proof_system::honk

0 commit comments

Comments
 (0)