Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: zk sumcheck #7517

Merged
merged 28 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
36523c1
added changes to flavors, relation_types.hpp and flavor.hpp
iakovenkos Jul 16, 2024
4692e4c
Expanded docs and added UltraFlavorWithZK
iakovenkos Jul 16, 2024
da478a6
fix: added NUM_ALL_WITNESSES to AvmFlavor
iakovenkos Jul 17, 2024
ffdf418
feat: added zk sumcheck, need to expand the docs
iakovenkos Jul 17, 2024
573f13c
docs: updated sumcheck_outline.md and inline docs
iakovenkos Jul 18, 2024
be77077
Merge branch 'master' into adjust-flavors-and-relation-types-to-zk-su…
iakovenkos Jul 18, 2024
ec0bfc7
fixed tests and gcc build issues
iakovenkos Jul 19, 2024
0fbf781
resolved comments
iakovenkos Jul 22, 2024
051a966
Merge branch 'adjust-flavors-and-relation-types-to-zk-sumcheck' of gi…
iakovenkos Jul 22, 2024
afa284e
refactor: added get_shifted_witnesses and AllWitnessEntities
iakovenkos Jul 29, 2024
74cf2e7
Merge remote-tracking branch 'origin/master' into adjust-flavors-and-…
iakovenkos Jul 29, 2024
2487f75
Merge branch 'adjust-flavors-and-relation-types-to-zk-sumcheck' into …
iakovenkos Jul 29, 2024
63bd81b
wip: fixing build issues
iakovenkos Jul 29, 2024
d449355
refactor: AllEntities and ShiftedEntities in Mega and Ultra
iakovenkos Jul 29, 2024
c5fab2b
Merge branch 'adjust-flavors-and-relation-types-to-zk-sumcheck' into …
iakovenkos Jul 29, 2024
4dbae08
fixed issues
iakovenkos Jul 29, 2024
eaeca2d
Merge branch 'adjust-flavors-and-relation-types-to-zk-sumcheck' into …
iakovenkos Jul 29, 2024
14fb4e1
wip: resolving comments
iakovenkos Aug 1, 2024
c2bf3f6
docs fix
iakovenkos Aug 12, 2024
0c07e19
fixed gcc added libra evals to sumcheck output
iakovenkos Aug 12, 2024
2002fe3
Merge branch 'adjust-flavors-and-relation-types-to-zk-sumcheck' into …
iakovenkos Aug 12, 2024
1dd93cc
comments resolved branch updated
iakovenkos Aug 16, 2024
94c95f3
comments resolved
iakovenkos Aug 16, 2024
e75c4f9
Merge branch 'master' into si/zk-sumcheck-and-sumcheck-tests
iakovenkos Aug 16, 2024
70d04c9
Merge branch 'master' into si/zk-sumcheck-and-sumcheck-tests
iakovenkos Aug 16, 2024
332eab9
simplified HasZK concept
iakovenkos Aug 19, 2024
f6916b9
Merge branch 'master' into si/zk-sumcheck-and-sumcheck-tests
iakovenkos Aug 19, 2024
c62a745
Merge branch 'master' into si/zk-sumcheck-and-sumcheck-tests
iakovenkos Aug 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion barretenberg/cpp/docs/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -1355,7 +1355,7 @@ HTML_EXTRA_FILES =
# The default value is: AUTO_LIGHT.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_COLORSTYLE = AUTO_LIGHT
HTML_COLORSTYLE = TOGGLE
iakovenkos marked this conversation as resolved.
Show resolved Hide resolved

# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
Expand Down
225 changes: 122 additions & 103 deletions barretenberg/cpp/docs/src/sumcheck-outline.md

Large diffs are not rendered by default.

17 changes: 15 additions & 2 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class ECCVMFlavor {
using RelationSeparator = FF;
using MSM = bb::eccvm::MSM<CycleGroup>;

// Indicates that this flavor runs with non-ZK Sumcheck.
static constexpr bool HasZK = false;
static constexpr size_t NUM_WIRES = 85;

// The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often
Expand All @@ -49,6 +51,8 @@ class ECCVMFlavor {
static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 3;
// The total number of witness entities not including shifts.
static constexpr size_t NUM_WITNESS_ENTITIES = 87;
// The total number of witnesses including shifts and derived entities.
static constexpr size_t NUM_ALL_WITNESS_ENTITIES = 113;

using GrandProductRelations = std::tuple<ECCVMSetRelation<FF>>;
// define the tuple of Relations that comprise the Sumcheck relation
Expand Down Expand Up @@ -279,6 +283,7 @@ class ECCVMFlavor {
entities.precompute_select, // column 24
entities.z_perm }; // column 25
}

/**
* @brief A base class labelling all entities (for instance, all of the polynomials used by the prover during
* sumcheck) in this Honk variant along with particular subsets of interest
Expand Down Expand Up @@ -308,10 +313,18 @@ class ECCVMFlavor {
{
return concatenate(PrecomputedEntities<DataType>::get_all(), WitnessEntities<DataType>::get_all());
};

auto get_to_be_shifted() { return ECCVMFlavor::get_to_be_shifted<DataType>(*this); }
auto get_shifted() { return ShiftedEntities<DataType>::get_all(); };
// this getter is necessary for more uniform zk verifiers
auto get_shifted_witnesses() { return ShiftedEntities<DataType>::get_all(); };
auto get_precomputed() { return PrecomputedEntities<DataType>::get_all(); };
// the getter for all witnesses including derived and shifted ones
auto get_all_witnesses()
{
return concatenate(WitnessEntities<DataType>::get_all(), ShiftedEntities<DataType>::get_all());
};
// this getter is necessary for a universal ZK Sumcheck
auto get_non_witnesses() { return PrecomputedEntities<DataType>::get_all(); };
};

public:
Expand Down Expand Up @@ -1297,4 +1310,4 @@ class ECCVMFlavor {

// NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members)

} // namespace bb
} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ template <typename BuilderType> class ECCVMRecursiveFlavor_ {
using NativeVerificationKey = NativeFlavor::VerificationKey;
using PCS = IPA<Curve>;

// Indicates that this flavor runs with non-ZK Sumcheck.
static constexpr bool HasZK = false;
static constexpr size_t NUM_WIRES = ECCVMFlavor::NUM_WIRES;
// The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often
// need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`.
Expand Down Expand Up @@ -130,4 +132,4 @@ template <typename BuilderType> class ECCVMRecursiveFlavor_ {

}; // NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members)

} // namespace bb
} // namespace bb
57 changes: 53 additions & 4 deletions barretenberg/cpp/src/barretenberg/flavor/flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
* @note It would be ideal to codify more structure in these base class template and to have it imposed on the actual
* flavors, but our inheritance model is complicated as it is, and we saw no reasonable way to fix this.
*
* @note One asymmetry to note is in the use of the term "key". It is worthwhile to distinguish betwen prover/verifier
* @note One asymmetry to note is in the use of the term "key". It is worthwhile to distinguish between prover/verifier
* circuit data, and "keys" that consist of such data augmented with witness data (whether, raw, blinded, or polynomial
* commitments). Currently the proving key contains witness data, while the verification key does not.
* TODO(Cody): It would be nice to resolve this but it's not essential.
Expand Down Expand Up @@ -292,6 +292,27 @@ template <typename Tuple, std::size_t Index = 0> static constexpr size_t compute
return subrelations_in_relation + compute_number_of_subrelations<Tuple, Index + 1>();
}
}

/**
* @brief Takes a Tuple of objects in the Relation class and recursively computes the maximum among partial
* subrelation lengths incremented by corresponding subrelation witness degrees over all
* subrelations of given relations. This method is required to compute the size of
* Round Univariates in ZK Sumcheck.
* @tparam Tuple
* @tparam Index
* @return constexpr size_t
*/
template <typename Tuple, std::size_t Index = 0> static constexpr size_t compute_max_total_zk_relation_length()
{
if constexpr (Index >= std::tuple_size<Tuple>::value) {
return 0; // Return 0 when reach end of the tuple
} else {
constexpr size_t current_zk_length = std::tuple_element<Index, Tuple>::type::ZK_TOTAL_RELATION_LENGTH;
constexpr size_t next_zk_length = compute_max_total_zk_relation_length<Tuple, Index + 1>();
return (current_zk_length > next_zk_length) ? current_zk_length : next_zk_length;
}
}

/**
* @brief Recursive utility function to construct a container for the subrelation accumulators of Protogalaxy folding.
* @details The size of the outer tuple is equal to the number of relations. Each relation contributes an inner tuple of
Expand Down Expand Up @@ -334,6 +355,26 @@ template <typename Tuple, std::size_t Index = 0> static constexpr auto create_su
}
}

/**
* @brief Recursive utility function to construct a container for the subrelation accumulators of ZK Sumcheck prover.
* @details The size of the outer tuple is equal to the number of relations. Each relation contributes an inner tuple of
* univariates whose size is equal to the number of subrelations of the relation. The length of a univariate in an inner
* tuple is determined by the corresponding zk subrelation length, i.e. by the subrelation partial length corrected by
* the corresponding witness degree.
*/
template <typename Tuple, std::size_t Index = 0>
static constexpr auto create_zk_sumcheck_tuple_of_tuples_of_univariates()
{
if constexpr (Index >= std::tuple_size<Tuple>::value) {
return std::tuple<>{}; // Return empty when reach end of the tuple
} else {
using UnivariateTuple =
typename std::tuple_element_t<Index, Tuple>::ZKSumcheckTupleOfUnivariatesOverSubrelations;
return std::tuple_cat(std::tuple<UnivariateTuple>{},
create_zk_sumcheck_tuple_of_tuples_of_univariates<Tuple, Index + 1>());
}
}

/**
* @brief Recursive utility function to construct tuple of arrays
* @details Container for storing value of each identity in each relation. Each Relation contributes an array of
Expand All @@ -354,6 +395,7 @@ template <typename Tuple, std::size_t Index = 0> static constexpr auto create_tu
// Forward declare honk flavors
namespace bb {
class UltraFlavor;
class UltraFlavorWithZK;
class ECCVMFlavor;
class UltraKeccakFlavor;
class MegaFlavor;
Expand Down Expand Up @@ -387,13 +429,13 @@ template <typename T>
concept IsUltraPlonkFlavor = IsAnyOf<T, plonk::flavor::Ultra, UltraKeccakFlavor>;

template <typename T>
concept IsUltraPlonkOrHonk = IsAnyOf<T, plonk::flavor::Ultra, UltraFlavor, UltraKeccakFlavor, MegaFlavor>;
concept IsUltraPlonkOrHonk = IsAnyOf<T, plonk::flavor::Ultra, UltraFlavor, UltraKeccakFlavor, UltraFlavorWithZK, MegaFlavor>;

template <typename T>
concept IsHonkFlavor = IsAnyOf<T, UltraFlavor, UltraKeccakFlavor, MegaFlavor>;
concept IsHonkFlavor = IsAnyOf<T, UltraFlavor, UltraKeccakFlavor, UltraFlavorWithZK, MegaFlavor>;

template <typename T>
concept IsUltraFlavor = IsAnyOf<T, UltraFlavor, UltraKeccakFlavor, MegaFlavor>;
concept IsUltraFlavor = IsAnyOf<T, UltraFlavor, UltraKeccakFlavor, UltraFlavorWithZK, MegaFlavor>;

template <typename T>
concept IsGoblinFlavor = IsAnyOf<T, MegaFlavor,
Expand All @@ -420,12 +462,19 @@ template <typename T> concept IsGrumpkinFlavor = IsAnyOf<T, ECCVMFlavor>;
template <typename T> concept IsFoldingFlavor = IsAnyOf<T, UltraFlavor,
// Note(md): must be here to use oink prover
UltraKeccakFlavor,
UltraFlavorWithZK,
MegaFlavor,
UltraRecursiveFlavor_<UltraCircuitBuilder>,
UltraRecursiveFlavor_<MegaCircuitBuilder>,
UltraRecursiveFlavor_<CircuitSimulatorBN254>,
MegaRecursiveFlavor_<UltraCircuitBuilder>,
MegaRecursiveFlavor_<MegaCircuitBuilder>, MegaRecursiveFlavor_<CircuitSimulatorBN254>>;
template <typename T>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need this concept to be so complicated?

concept FlavorHasZK = requires {
{
T::HasZK
} -> std::convertible_to<bool>;
} && T::HasZK;

template <typename Container, typename Element>
inline std::string flavor_get_label(Container&& container, const Element& element) {
Expand Down
35 changes: 35 additions & 0 deletions barretenberg/cpp/src/barretenberg/relations/relation_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ concept HasSubrelationLinearlyIndependentMember = requires(T) {

template <typename T>
concept HasParameterLengthAdjustmentsMember = requires { T::TOTAL_LENGTH_ADJUSTMENTS; };
// The concept needed to adjust the sumcheck univariate lengths in the case of ZK Flavors and to avoid adding redundant
// constants to the relations that are not used by ZK flavors
template <typename T>
concept HasWitnessDegrees = requires { T::SUBRELATION_WITNESS_DEGREES; };

/**
* @brief Check whether a given subrelation is linearly independent from the other subrelations.
Expand Down Expand Up @@ -66,6 +70,27 @@ consteval std::array<size_t, RelationImpl::SUBRELATION_PARTIAL_LENGTHS.size()> c
return RelationImpl::SUBRELATION_PARTIAL_LENGTHS;
}
};
/**
* @brief This metod adjusts the subrelation partial lengths to ZK Flavors.
*
* @tparam RelationImpl
* @return consteval
*/
template <typename RelationImpl>
consteval std::array<size_t, RelationImpl::SUBRELATION_PARTIAL_LENGTHS.size()> compute_zk_partial_subrelation_lengths()
{
if constexpr (HasWitnessDegrees<RelationImpl>) {
constexpr size_t NUM_SUBRELATIONS = RelationImpl::SUBRELATION_PARTIAL_LENGTHS.size();
std::array<size_t, NUM_SUBRELATIONS> result;
for (size_t idx = 0; idx < NUM_SUBRELATIONS; idx++) {
result[idx] =
RelationImpl::SUBRELATION_PARTIAL_LENGTHS[idx] + RelationImpl::SUBRELATION_WITNESS_DEGREES[idx];
}
return result;
} else {
return RelationImpl::SUBRELATION_PARTIAL_LENGTHS;
}
};

/**
* @brief Get the subrelation accumulators for the Protogalaxy combiner calculation.
Expand Down Expand Up @@ -139,12 +164,18 @@ template <typename RelationImpl> class Relation : public RelationImpl {

static constexpr std::array<size_t, RelationImpl::SUBRELATION_PARTIAL_LENGTHS.size()> SUBRELATION_TOTAL_LENGTHS =
compute_total_subrelation_lengths<RelationImpl>();
// Compute the subrelation partial lengths adjusted to ZK
static constexpr std::array<size_t, RelationImpl::SUBRELATION_PARTIAL_LENGTHS.size()> ZK_PARTIAL_LENGTHS =
compute_zk_partial_subrelation_lengths<RelationImpl>();

static constexpr size_t RELATION_LENGTH = *std::max_element(RelationImpl::SUBRELATION_PARTIAL_LENGTHS.begin(),
RelationImpl::SUBRELATION_PARTIAL_LENGTHS.end());

static constexpr size_t TOTAL_RELATION_LENGTH =
*std::max_element(SUBRELATION_TOTAL_LENGTHS.begin(), SUBRELATION_TOTAL_LENGTHS.end());
// Determine the maximum subrelation length in the case if ZK Flavors
static constexpr size_t ZK_TOTAL_RELATION_LENGTH =
*std::max_element(ZK_PARTIAL_LENGTHS.begin(), ZK_PARTIAL_LENGTHS.end());

template <size_t NUM_INSTANCES>
using ProtogalaxyTupleOfUnivariatesOverSubrelations =
Expand All @@ -157,6 +188,10 @@ template <typename RelationImpl> class Relation : public RelationImpl {
NUM_INSTANCES - 1>;
using SumcheckTupleOfUnivariatesOverSubrelations =
TupleOfUnivariates<FF, RelationImpl::SUBRELATION_PARTIAL_LENGTHS>;
// The containter constructor for sumcheck univariates corresponding to each subrelation in ZK Flavor's relations
using ZKSumcheckTupleOfUnivariatesOverSubrelations =
TupleOfUnivariates<FF, compute_zk_partial_subrelation_lengths<RelationImpl>()>;

using SumcheckArrayOfValuesOverSubrelations = ArrayOfValues<FF, RelationImpl::SUBRELATION_PARTIAL_LENGTHS>;

// These are commonly needed, most importantly, for explicitly instantiating
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class MegaFlavor {
using CommitmentKey = bb::CommitmentKey<Curve>;
using VerifierCommitmentKey = bb::VerifierCommitmentKey<Curve>;

// Indicates that this flavor runs with non-ZK Sumcheck.
static constexpr bool HasZK = false;
static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES;
// The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often
// need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`.
Expand Down Expand Up @@ -74,6 +76,8 @@ class MegaFlavor {
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1;
static constexpr size_t BATCHED_RELATION_TOTAL_LENGTH = MAX_TOTAL_RELATION_LENGTH + 1;
static constexpr size_t NUM_RELATIONS = std::tuple_size_v<Relations>;
// The total number of witnesses including shifts and derived entities.
static constexpr size_t NUM_ALL_WITNESS_ENTITIES = 23;

// For instances of this flavour, used in folding, we need a unique sumcheck batching challenges for each
// subrelation. This
Expand Down Expand Up @@ -196,6 +200,7 @@ class MegaFlavor {
return_data_read_counts, // column 21
return_data_read_tags, // column 22
return_data_inverses); // column 23
auto get_to_be_shifted() { return RefArray{ z_perm }; };
};

/**
Expand Down Expand Up @@ -230,6 +235,7 @@ class MegaFlavor {
this->return_data_inverses,
};
}
auto get_to_be_shifted() { return DerivedEntities<DataType>::get_to_be_shifted(); }

MSGPACK_FIELDS(this->w_l,
this->w_r,
Expand Down Expand Up @@ -257,18 +263,44 @@ class MegaFlavor {
this->return_data_inverses);
};

template <typename DataType> class ShiftedEntities {
/**
* @brief Class for ShiftedWitnessEntities, containing only shifted witness polynomials.
*/
template <typename DataType> class ShiftedWitnessEntities {
public:
DEFINE_FLAVOR_MEMBERS(DataType,
w_l_shift, // column 0
w_r_shift, // column 1
w_o_shift, // column 2
w_4_shift, // column 3
z_perm_shift) // column 4

auto get_shifted_witnesses() { return RefArray{ w_l_shift, w_r_shift, w_o_shift, w_4_shift, z_perm_shift }; };
};

/**
* @brief Class for ShiftedEntities, containing shifted witness and table polynomials.
*/
template <typename DataType> class ShiftedTables {
public:
DEFINE_FLAVOR_MEMBERS(DataType,
table_1_shift, // column 0
table_2_shift, // column 1
table_3_shift, // column 2
table_4_shift, // column 3
w_l_shift, // column 4
w_r_shift, // column 5
w_o_shift, // column 6
w_4_shift, // column 7
z_perm_shift) // column 8
table_4_shift // column 3
)
};

/**
* @brief Class for ShiftedEntities, containing shifted witness and table polynomials.
*/
template <typename DataType>
class ShiftedEntities : public ShiftedTables<DataType>, public ShiftedWitnessEntities<DataType> {
public:
DEFINE_COMPOUND_GET_ALL(ShiftedTables<DataType>, ShiftedWitnessEntities<DataType>)

auto get_shifted_witnesses() { return ShiftedWitnessEntities<DataType>::get_all(); };
auto get_shifted_tables() { return ShiftedTables<DataType>::get_all(); };
};

public:
Expand All @@ -288,25 +320,40 @@ class MegaFlavor {
public:
DEFINE_COMPOUND_GET_ALL(PrecomputedEntities<DataType>, WitnessEntities<DataType>, ShiftedEntities<DataType>)

auto get_wires() { return RefArray{ this->w_l, this->w_r, this->w_o, this->w_4 }; };
auto get_wires() { return WitnessEntities<DataType>::get_wires(); };
auto get_selectors() { return PrecomputedEntities<DataType>::get_selectors(); }
auto get_sigmas() { return RefArray{ this->sigma_1, this->sigma_2, this->sigma_3, this->sigma_4 }; };
auto get_ids() { return RefArray{ this->id_1, this->id_2, this->id_3, this->id_4 }; };
auto get_tables() { return RefArray{ this->table_1, this->table_2, this->table_3, this->table_4 }; };
// Gemini-specific getters.
auto get_sigmas() { return PrecomputedEntities<DataType>::get_sigma_polynomials(); };
auto get_ids() { return PrecomputedEntities<DataType>::get_id_polynomials(); };
auto get_tables() { return PrecomputedEntities<DataType>::get_table_polynomials(); };
auto get_unshifted()
{
return concatenate(PrecomputedEntities<DataType>::get_all(), WitnessEntities<DataType>::get_all());
};

auto get_precomputed() { return PrecomputedEntities<DataType>::get_all(); }
auto get_witness() { return WitnessEntities<DataType>::get_all(); };
auto get_to_be_shifted()
{
return RefArray{ this->table_1, this->table_2, this->table_3, this->table_4, this->w_l,
this->w_r, this->w_o, this->w_4, this->z_perm };
return concatenate(PrecomputedEntities<DataType>::get_table_polynomials(),
WitnessEntities<DataType>::get_wires(),
WitnessEntities<DataType>::get_to_be_shifted());
};
auto get_precomputed() { return PrecomputedEntities<DataType>::get_all(); }
auto get_shifted() { return ShiftedEntities<DataType>::get_all(); };
// getter for shifted witnesses
auto get_shifted_witnesses() { return ShiftedWitnessEntities<DataType>::get_all(); };
// getter for shifted tables
auto get_shifted_tables() { return ShiftedEntities<DataType>::get_shifted_tables(); };
// this getter is used in ZK Sumcheck, where all witness evaluations (including shifts) have to be masked
auto get_all_witnesses()
{
return concatenate(WitnessEntities<DataType>::get_all(),
ShiftedEntities<DataType>::get_shifted_witnesses());
};
// getter for the complement of all witnesses inside all entities
auto get_non_witnesses()
{
return concatenate(PrecomputedEntities<DataType>::get_all(),
ShiftedEntities<DataType>::get_shifted_tables());
};
};

/**
Expand Down
Loading
Loading