Skip to content

Commit

Permalink
feat(avm-main): pil -> permutations (#3650)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Maddiaa0 authored Dec 14, 2023
1 parent 17ba715 commit c52acf6
Show file tree
Hide file tree
Showing 26 changed files with 1,225 additions and 866 deletions.
3 changes: 2 additions & 1 deletion barretenberg/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ node_modules
ts/dest
.tsbuildinfo
.idea
cmake-build-debug
cmake-build-debug
*_opt.pil
20 changes: 20 additions & 0 deletions barretenberg/cpp/pil/avm/toy_avm.pil
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace toy(256);
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 lookup
#[two_column_perm] // the name of the inverse
q_tuple_set { set_1_column_1, set_1_column_2 } is { set_2_column_1, set_2_column_2 };

// Relation not used -> we currently require a single relation for codegen
pol commit x;
x' - x = 0;

// Also needs a fixed relation
pol fixed first = [1] + [0]*;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "barretenberg/polynomials/barycentric.hpp"
#include "barretenberg/polynomials/univariate.hpp"

#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp"

#include "barretenberg/flavor/flavor.hpp"
#include "barretenberg/flavor/flavor_macros.hpp"
#include "barretenberg/polynomials/evaluation_domain.hpp"
Expand Down Expand Up @@ -40,7 +42,7 @@ class AvmMiniFlavor {
// the unshifted and one for the shifted
static constexpr size_t NUM_ALL_ENTITIES = 30;

using Relations = std::tuple<AvmMini_vm::avm_mini<FF>, AvmMini_vm::mem_trace<FF>>;
using Relations = std::tuple<AvmMini_vm::mem_trace<FF>, AvmMini_vm::avm_mini<FF>>;

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

Expand Down Expand Up @@ -144,8 +146,8 @@ class AvmMiniFlavor {
avmMini_mem_idx_c,
avmMini_last,
memTrace_m_rw_shift,
memTrace_m_val_shift,
memTrace_m_addr_shift)
memTrace_m_addr_shift,
memTrace_m_val_shift)

RefVector<DataType> get_wires()
{
Expand Down Expand Up @@ -177,8 +179,8 @@ class AvmMiniFlavor {
avmMini_mem_idx_c,
avmMini_last,
memTrace_m_rw_shift,
memTrace_m_val_shift,
memTrace_m_addr_shift };
memTrace_m_addr_shift,
memTrace_m_val_shift };
};
RefVector<DataType> get_unshifted()
{
Expand Down Expand Up @@ -210,10 +212,10 @@ class AvmMiniFlavor {
avmMini_mem_idx_c,
avmMini_last };
};
RefVector<DataType> get_to_be_shifted() { return { memTrace_m_rw, memTrace_m_val, memTrace_m_addr }; };
RefVector<DataType> get_to_be_shifted() { return { memTrace_m_rw, memTrace_m_addr, memTrace_m_val }; };
RefVector<DataType> get_shifted()
{
return { memTrace_m_rw_shift, memTrace_m_val_shift, memTrace_m_addr_shift };
return { memTrace_m_rw_shift, memTrace_m_addr_shift, memTrace_m_val_shift };
};
};

Expand Down Expand Up @@ -467,4 +469,6 @@ class AvmMiniFlavor {
};

} // namespace flavor

namespace sumcheck {}
} // namespace proof_system::honk
304 changes: 304 additions & 0 deletions barretenberg/cpp/src/barretenberg/flavor/generated/Toy_flavor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,304 @@


#pragma once
#include "../relation_definitions_fwd.hpp"
#include "barretenberg/commitment_schemes/kzg/kzg.hpp"
#include "barretenberg/ecc/curves/bn254/g1.hpp"
#include "barretenberg/polynomials/barycentric.hpp"
#include "barretenberg/polynomials/univariate.hpp"

#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp"

#include "barretenberg/flavor/flavor.hpp"
#include "barretenberg/flavor/flavor_macros.hpp"
#include "barretenberg/polynomials/evaluation_domain.hpp"
#include "barretenberg/polynomials/polynomial.hpp"
#include "barretenberg/relations/generated/Toy/toy_avm.hpp"
#include "barretenberg/relations/generated/Toy/two_column_perm.hpp"
#include "barretenberg/transcript/transcript.hpp"

namespace proof_system::honk {
namespace flavor {

class ToyFlavor {
public:
using Curve = curve::BN254;
using G1 = Curve::Group;
using PCS = pcs::kzg::KZG<Curve>;

using FF = G1::subgroup_field;
using Polynomial = barretenberg::Polynomial<FF>;
using PolynomialHandle = std::span<FF>;
using GroupElement = G1::element;
using Commitment = G1::affine_element;
using CommitmentHandle = G1::affine_element;
using CommitmentKey = pcs::CommitmentKey<Curve>;
using VerifierCommitmentKey = pcs::VerifierCommitmentKey<Curve>;

static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 1;
static constexpr size_t NUM_WITNESS_ENTITIES = 7;
static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES;
// We have two copies of the witness entities, so we subtract the number of fixed ones (they have no shift), one for
// the unshifted and one for the shifted
static constexpr size_t NUM_ALL_ENTITIES = 9;

using Relations = std::tuple<Toy_vm::toy_avm<FF>, sumcheck::two_column_perm_relation<FF>>;

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

// BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta`
// random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation
// length = 3
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1;
static constexpr size_t NUM_RELATIONS = std::tuple_size<Relations>::value;

template <size_t NUM_INSTANCES>
using ProtogalaxyTupleOfTuplesOfUnivariates =
decltype(create_protogalaxy_tuple_of_tuples_of_univariates<Relations, NUM_INSTANCES>());
using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates<Relations>());
using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values<Relations>());

static constexpr bool has_zero_row = true;

private:
template <typename DataType_> class PrecomputedEntities : public PrecomputedEntitiesBase {
public:
using DataType = DataType_;

DEFINE_FLAVOR_MEMBERS(DataType, toy_first)

RefVector<DataType> get_selectors() { return { toy_first }; };
RefVector<DataType> get_sigma_polynomials() { return {}; };
RefVector<DataType> get_id_polynomials() { return {}; };
RefVector<DataType> get_table_polynomials() { return {}; };
};

template <typename DataType> class WitnessEntities {
public:
DEFINE_FLAVOR_MEMBERS(DataType,
toy_q_tuple_set,
toy_set_1_column_1,
toy_set_1_column_2,
toy_set_2_column_1,
toy_set_2_column_2,
toy_x,
two_column_perm)

RefVector<DataType> get_wires()
{
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,
toy_x, two_column_perm };
};
RefVector<DataType> get_sorted_polynomials() { return {}; };
};

template <typename DataType> class AllEntities {
public:
DEFINE_FLAVOR_MEMBERS(DataType,
toy_first,
toy_q_tuple_set,
toy_set_1_column_1,
toy_set_1_column_2,
toy_set_2_column_1,
toy_set_2_column_2,
toy_x,
two_column_perm,
toy_x_shift)

RefVector<DataType> get_wires()
{
return { toy_first, toy_q_tuple_set, toy_set_1_column_1, toy_set_1_column_2, toy_set_2_column_1,
toy_set_2_column_2, toy_x, two_column_perm, toy_x_shift };
};
RefVector<DataType> get_unshifted()
{
return { toy_first, toy_q_tuple_set, toy_set_1_column_1, toy_set_1_column_2, toy_set_2_column_1,
toy_set_2_column_2, toy_x, two_column_perm };
};
RefVector<DataType> get_to_be_shifted() { return { toy_x }; };
RefVector<DataType> get_shifted() { return { toy_x_shift }; };
};

public:
class ProvingKey : public ProvingKey_<PrecomputedEntities<Polynomial>, WitnessEntities<Polynomial>> {
public:
// Expose constructors on the base class
using Base = ProvingKey_<PrecomputedEntities<Polynomial>, WitnessEntities<Polynomial>>;
using Base::Base;

// The plookup wires that store plookup read data.
std::array<PolynomialHandle, 0> get_table_column_wires() { return {}; };
};

using VerificationKey = VerificationKey_<PrecomputedEntities<Commitment>>;

using ProverPolynomials = AllEntities<PolynomialHandle>;

using FoldedPolynomials = AllEntities<std::vector<FF>>;

class AllValues : public AllEntities<FF> {
public:
using Base = AllEntities<FF>;
using Base::Base;
};

class AllPolynomials : public AllEntities<Polynomial> {
public:
[[nodiscard]] size_t get_polynomial_size() const { return this->toy_q_tuple_set.size(); }
[[nodiscard]] AllValues get_row(const size_t row_idx) const
{
AllValues result;
for (auto [result_field, polynomial] : zip_view(result.get_all(), get_all())) {
result_field = polynomial[row_idx];
}
return result;
}
};

using RowPolynomials = AllEntities<FF>;

class PartiallyEvaluatedMultivariates : public AllEntities<Polynomial> {
public:
PartiallyEvaluatedMultivariates() = default;
PartiallyEvaluatedMultivariates(const size_t circuit_size)
{
// Storage is only needed after the first partial evaluation, hence polynomials of size (n / 2)
for (auto& poly : get_all()) {
poly = Polynomial(circuit_size / 2);
}
}
};

/**
* @brief A container for univariates used during Protogalaxy folding and sumcheck.
* @details During folding and sumcheck, the prover evaluates the relations on these univariates.
*/
template <size_t LENGTH> using ProverUnivariates = AllEntities<barretenberg::Univariate<FF, LENGTH>>;

/**
* @brief A container for univariates produced during the hot loop in sumcheck.
*/
using ExtendedEdges = ProverUnivariates<MAX_PARTIAL_RELATION_LENGTH>;

class CommitmentLabels : public AllEntities<std::string> {
private:
using Base = AllEntities<std::string>;

public:
CommitmentLabels()
: AllEntities<std::string>()
{
Base::toy_first = "TOY_FIRST";
Base::toy_q_tuple_set = "TOY_Q_TUPLE_SET";
Base::toy_set_1_column_1 = "TOY_SET_1_COLUMN_1";
Base::toy_set_1_column_2 = "TOY_SET_1_COLUMN_2";
Base::toy_set_2_column_1 = "TOY_SET_2_COLUMN_1";
Base::toy_set_2_column_2 = "TOY_SET_2_COLUMN_2";
Base::toy_x = "TOY_X";
Base::two_column_perm = "TWO_COLUMN_PERM";
};
};

class VerifierCommitments : public AllEntities<Commitment> {
private:
using Base = AllEntities<Commitment>;

public:
VerifierCommitments(const std::shared_ptr<VerificationKey>& verification_key)
{
toy_first = verification_key->toy_first;
}
};

class Transcript : public BaseTranscript {
public:
uint32_t circuit_size;

Commitment toy_q_tuple_set;
Commitment toy_set_1_column_1;
Commitment toy_set_1_column_2;
Commitment toy_set_2_column_1;
Commitment toy_set_2_column_2;
Commitment toy_x;
Commitment two_column_perm;

std::vector<barretenberg::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>> sumcheck_univariates;
std::array<FF, NUM_ALL_ENTITIES> sumcheck_evaluations;
std::vector<Commitment> zm_cq_comms;
Commitment zm_cq_comm;
Commitment zm_pi_comm;

Transcript() = default;

Transcript(const std::vector<uint8_t>& proof)
: BaseTranscript(proof)
{}

void deserialize_full_transcript()
{
size_t num_bytes_read = 0;
circuit_size = deserialize_from_buffer<uint32_t>(proof_data, num_bytes_read);
size_t log_n = numeric::get_msb(circuit_size);

toy_q_tuple_set = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
toy_set_1_column_1 = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
toy_set_1_column_2 = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
toy_set_2_column_1 = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
toy_set_2_column_2 = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
toy_x = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);
two_column_perm = deserialize_from_buffer<Commitment>(Transcript::proof_data, num_bytes_read);

for (size_t i = 0; i < log_n; ++i) {
sumcheck_univariates.emplace_back(
deserialize_from_buffer<barretenberg::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(
Transcript::proof_data, num_bytes_read));
}
sumcheck_evaluations =
deserialize_from_buffer<std::array<FF, NUM_ALL_ENTITIES>>(Transcript::proof_data, num_bytes_read);
for (size_t i = 0; i < log_n; ++i) {
zm_cq_comms.push_back(deserialize_from_buffer<Commitment>(proof_data, num_bytes_read));
}
zm_cq_comm = deserialize_from_buffer<Commitment>(proof_data, num_bytes_read);
zm_pi_comm = deserialize_from_buffer<Commitment>(proof_data, num_bytes_read);
}

void serialize_full_transcript()
{
size_t old_proof_length = proof_data.size();
Transcript::proof_data.clear();
size_t log_n = numeric::get_msb(circuit_size);

serialize_to_buffer(circuit_size, Transcript::proof_data);

serialize_to_buffer<Commitment>(toy_q_tuple_set, Transcript::proof_data);
serialize_to_buffer<Commitment>(toy_set_1_column_1, Transcript::proof_data);
serialize_to_buffer<Commitment>(toy_set_1_column_2, Transcript::proof_data);
serialize_to_buffer<Commitment>(toy_set_2_column_1, Transcript::proof_data);
serialize_to_buffer<Commitment>(toy_set_2_column_2, Transcript::proof_data);
serialize_to_buffer<Commitment>(toy_x, Transcript::proof_data);
serialize_to_buffer<Commitment>(two_column_perm, Transcript::proof_data);

for (size_t i = 0; i < log_n; ++i) {
serialize_to_buffer(sumcheck_univariates[i], Transcript::proof_data);
}
serialize_to_buffer(sumcheck_evaluations, Transcript::proof_data);
for (size_t i = 0; i < log_n; ++i) {
serialize_to_buffer(zm_cq_comms[i], proof_data);
}
serialize_to_buffer(zm_cq_comm, proof_data);
serialize_to_buffer(zm_pi_comm, proof_data);

// sanity check to make sure we generate the same length of proof as before.
ASSERT(proof_data.size() == old_proof_length);
}
};
};

} // namespace flavor

namespace sumcheck {

DECLARE_SUMCHECK_RELATION_CLASS(two_column_perm, flavor::ToyFlavor);

}
} // namespace proof_system::honk
Loading

0 comments on commit c52acf6

Please sign in to comment.