Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,26 @@ template <class Curve> class CommitmentKey {

return result;
}

enum class CommitType { Default, Structured, Sparse, StructuredNonZeroComplement };

Commitment commit_with_type(PolynomialSpan<const Fr> poly,
CommitType type,
const std::vector<std::pair<size_t, size_t>>& active_ranges = {},
size_t final_active_wire_idx = 0)
{
switch (type) {
case CommitType::Structured:
return commit_structured(poly, active_ranges, final_active_wire_idx);
case CommitType::Sparse:
return commit_sparse(poly);
case CommitType::StructuredNonZeroComplement:
return commit_structured_with_nonzero_complement(poly, active_ranges, final_active_wire_idx);
case CommitType::Default:
default:
return commit(poly);
}
}
};

} // namespace bb
17 changes: 17 additions & 0 deletions barretenberg/cpp/src/barretenberg/ultra_honk/mega_honk.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ TYPED_TEST(MegaHonkTests, Basic)
TYPED_TEST(MegaHonkTests, BasicStructured)
{
using Flavor = TypeParam;

// In MegaZKFlavor, we mask witness polynomials by placing random values at the indices `dyadic_circuit_size`-i for
// i=1,2,3. This mechanism does not work with structured polynomials yet.
if constexpr (std::is_same_v<Flavor, MegaZKFlavor>) {
GTEST_SKIP() << "Skipping 'BasicStructured' test for MegaZKFlavor.";
}
typename Flavor::CircuitBuilder builder;
using Prover = UltraProver_<Flavor>;
using Verifier = UltraVerifier_<Flavor>;
Expand Down Expand Up @@ -143,6 +149,12 @@ TYPED_TEST(MegaHonkTests, BasicStructured)
TYPED_TEST(MegaHonkTests, DynamicVirtualSizeIncrease)
{
using Flavor = TypeParam;

// In MegaZKFlavor, we mask witness polynomials by placing random values at the indices `dyadic_circuit_size`-i for
// i=1,2,3. This mechanism does not work with structured polynomials yet.
if constexpr (std::is_same_v<Flavor, MegaZKFlavor>) {
GTEST_SKIP() << "Skipping 'DynamicVirtualSizeIncrease' test for MegaZKFlavor.";
}
typename Flavor::CircuitBuilder builder;
using Prover = UltraProver_<Flavor>;
using Verifier = UltraVerifier_<Flavor>;
Expand Down Expand Up @@ -382,6 +394,11 @@ TYPED_TEST(MegaHonkTests, StructuredTraceOverflow)
TYPED_TEST(MegaHonkTests, PolySwap)
{
using Flavor = TypeParam;
// In MegaZKFlavor, we mask witness polynomials by placing random values at the indices `dyadic_circuit_size`-i, for
// i=1,2,3. This mechanism does not work with structured polynomials yet.
if constexpr (std::is_same_v<Flavor, MegaZKFlavor>) {
GTEST_SKIP() << "Skipping 'PolySwap' test for MegaZKFlavor.";
}
using Builder = Flavor::CircuitBuilder;

TraceSettings trace_settings{ SMALL_TEST_STRUCTURE_FOR_OVERFLOWS };
Expand Down
147 changes: 75 additions & 72 deletions barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,52 +99,35 @@ template <IsUltraFlavor Flavor> void OinkProver<Flavor>::execute_wire_commitment
// We only commit to the fourth wire polynomial after adding memory recordss
{
PROFILE_THIS_NAME("COMMIT::wires");
if (proving_key->get_is_structured()) {
witness_commitments.w_l = proving_key->proving_key.commitment_key->commit_structured(
proving_key->proving_key.polynomials.w_l, proving_key->proving_key.active_region_data.get_ranges());
witness_commitments.w_r = proving_key->proving_key.commitment_key->commit_structured(
proving_key->proving_key.polynomials.w_r, proving_key->proving_key.active_region_data.get_ranges());
witness_commitments.w_o = proving_key->proving_key.commitment_key->commit_structured(
proving_key->proving_key.polynomials.w_o, proving_key->proving_key.active_region_data.get_ranges());
} else {
witness_commitments.w_l =
proving_key->proving_key.commitment_key->commit(proving_key->proving_key.polynomials.w_l);
witness_commitments.w_r =
proving_key->proving_key.commitment_key->commit(proving_key->proving_key.polynomials.w_r);
witness_commitments.w_o =
proving_key->proving_key.commitment_key->commit(proving_key->proving_key.polynomials.w_o);
}
}
auto commit_type = (proving_key->get_is_structured()) ? CommitmentKey::CommitType::Structured
: CommitmentKey::CommitType::Default;

auto wire_comms = witness_commitments.get_wires();
auto wire_labels = commitment_labels.get_wires();
for (size_t idx = 0; idx < 3; ++idx) {
transcript->send_to_verifier(domain_separator + wire_labels[idx], wire_comms[idx]);
commit_to_witness_polynomial(proving_key->proving_key.polynomials.w_l, commitment_labels.w_l, commit_type);
commit_to_witness_polynomial(proving_key->proving_key.polynomials.w_r, commitment_labels.w_r, commit_type);
commit_to_witness_polynomial(proving_key->proving_key.polynomials.w_o, commitment_labels.w_o, commit_type);
}

if constexpr (IsMegaFlavor<Flavor>) {

// Commit to Goblin ECC op wires
for (auto [commitment, polynomial, label] : zip_view(witness_commitments.get_ecc_op_wires(),
proving_key->proving_key.polynomials.get_ecc_op_wires(),
commitment_labels.get_ecc_op_wires())) {
// Commit to Goblin ECC op wires.
// To avoid possible issues with the current work on the merge protocol, they are not
// masked in MegaZKFlavor
for (auto [polynomial, label] :
zip_view(proving_key->proving_key.polynomials.get_ecc_op_wires(), commitment_labels.get_ecc_op_wires())) {
{
PROFILE_THIS_NAME("COMMIT::ecc_op_wires");
commitment = proving_key->proving_key.commitment_key->commit(polynomial);
}
transcript->send_to_verifier(domain_separator + label, commitment);
transcript->send_to_verifier(domain_separator + label,
proving_key->proving_key.commitment_key->commit(polynomial));
};
}

// Commit to DataBus related polynomials
for (auto [commitment, polynomial, label] :
zip_view(witness_commitments.get_databus_entities(),
proving_key->proving_key.polynomials.get_databus_entities(),
commitment_labels.get_databus_entities())) {
for (auto [polynomial, label] : zip_view(proving_key->proving_key.polynomials.get_databus_entities(),
commitment_labels.get_databus_entities())) {
{
PROFILE_THIS_NAME("COMMIT::databus");
commitment = proving_key->proving_key.commitment_key->commit(polynomial);
commit_to_witness_polynomial(polynomial, label);
}
transcript->send_to_verifier(domain_separator + label, commitment);
}
}
}
Expand All @@ -168,27 +151,21 @@ template <IsUltraFlavor Flavor> void OinkProver<Flavor>::execute_sorted_list_acc
// Commit to lookup argument polynomials and the finalized (i.e. with memory records) fourth wire polynomial
{
PROFILE_THIS_NAME("COMMIT::lookup_counts_tags");
witness_commitments.lookup_read_counts =
proving_key->proving_key.commitment_key->commit(proving_key->proving_key.polynomials.lookup_read_counts);
witness_commitments.lookup_read_tags =
proving_key->proving_key.commitment_key->commit(proving_key->proving_key.polynomials.lookup_read_tags);
commit_to_witness_polynomial(proving_key->proving_key.polynomials.lookup_read_counts,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you please turn on the use of commit_sparse here? Its not being used in master either but it definitely should be used

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done, I'm seeing -70ms in ClientIVCBench

commitment_labels.lookup_read_counts,
CommitmentKey::CommitType::Sparse);

commit_to_witness_polynomial(proving_key->proving_key.polynomials.lookup_read_tags,
commitment_labels.lookup_read_tags,
CommitmentKey::CommitType::Sparse);
}
{
PROFILE_THIS_NAME("COMMIT::wires");
if (proving_key->get_is_structured()) {
witness_commitments.w_4 = proving_key->proving_key.commitment_key->commit_structured(
proving_key->proving_key.polynomials.w_4, proving_key->proving_key.active_region_data.get_ranges());
} else {
witness_commitments.w_4 =
proving_key->proving_key.commitment_key->commit(proving_key->proving_key.polynomials.w_4);
}
auto commit_type = (proving_key->get_is_structured()) ? CommitmentKey::CommitType::Structured
: CommitmentKey::CommitType::Default;
commit_to_witness_polynomial(
proving_key->proving_key.polynomials.w_4, domain_separator + commitment_labels.w_4, commit_type);
}

transcript->send_to_verifier(domain_separator + commitment_labels.lookup_read_counts,
witness_commitments.lookup_read_counts);
transcript->send_to_verifier(domain_separator + commitment_labels.lookup_read_tags,
witness_commitments.lookup_read_tags);
transcript->send_to_verifier(domain_separator + commitment_labels.w_4, witness_commitments.w_4);
}

/**
Expand All @@ -208,24 +185,20 @@ template <IsUltraFlavor Flavor> void OinkProver<Flavor>::execute_log_derivative_

{
PROFILE_THIS_NAME("COMMIT::lookup_inverses");
witness_commitments.lookup_inverses = proving_key->proving_key.commitment_key->commit_sparse(
proving_key->proving_key.polynomials.lookup_inverses);
commit_to_witness_polynomial(proving_key->proving_key.polynomials.lookup_inverses,
commitment_labels.lookup_inverses,
CommitmentKey::CommitType::Sparse);
}
transcript->send_to_verifier(domain_separator + commitment_labels.lookup_inverses,
witness_commitments.lookup_inverses);

// If Mega, commit to the databus inverse polynomials and send
if constexpr (IsMegaFlavor<Flavor>) {
for (auto [commitment, polynomial, label] :
zip_view(witness_commitments.get_databus_inverses(),
proving_key->proving_key.polynomials.get_databus_inverses(),
commitment_labels.get_databus_inverses())) {
for (auto [polynomial, label] : zip_view(proving_key->proving_key.polynomials.get_databus_inverses(),
commitment_labels.get_databus_inverses())) {
{
PROFILE_THIS_NAME("COMMIT::databus_inverses");
commitment = proving_key->proving_key.commitment_key->commit_sparse(polynomial);
commit_to_witness_polynomial(polynomial, label, CommitmentKey::CommitType::Sparse);
}
transcript->send_to_verifier(domain_separator + label, commitment);
}
};
}
}

Expand All @@ -243,18 +216,11 @@ template <IsUltraFlavor Flavor> void OinkProver<Flavor>::execute_grand_product_c

{
PROFILE_THIS_NAME("COMMIT::z_perm");
if (proving_key->get_is_structured()) {
witness_commitments.z_perm =
proving_key->proving_key.commitment_key->commit_structured_with_nonzero_complement(
proving_key->proving_key.polynomials.z_perm,
proving_key->proving_key.active_region_data.get_ranges(),
proving_key->final_active_wire_idx + 1);
} else {
witness_commitments.z_perm =
proving_key->proving_key.commitment_key->commit(proving_key->proving_key.polynomials.z_perm);
}
auto commit_type = (proving_key->get_is_structured()) ? CommitmentKey::CommitType::StructuredNonZeroComplement
: CommitmentKey::CommitType::Default;
commit_to_witness_polynomial(
proving_key->proving_key.polynomials.z_perm, commitment_labels.z_perm, commit_type);
}
transcript->send_to_verifier(domain_separator + commitment_labels.z_perm, witness_commitments.z_perm);
}

template <IsUltraFlavor Flavor> typename Flavor::RelationSeparator OinkProver<Flavor>::generate_alphas_round()
Expand All @@ -269,6 +235,43 @@ template <IsUltraFlavor Flavor> typename Flavor::RelationSeparator OinkProver<Fl
return alphas;
}

/**
* @brief We mask the commitment to a witness, its evaluation at the Sumcheck challenge and, if needed, the
* evaluation of its shift.
*/
template <IsUltraFlavor Flavor> void OinkProver<Flavor>::mask_witness_polynomial(Polynomial<FF>& polynomial)
{
const size_t circuit_size = polynomial.virtual_size();
for (size_t idx = 1; idx < MASKING_OFFSET; idx++) {
polynomial.at(circuit_size - idx) = FF::random_element();
}
}

/**
* @brief A uniform method to mask, commit, and send the corresponding commitment to the verifier.
*
* @param polynomial
* @param label
* @param type
*/
template <IsUltraFlavor Flavor>
void OinkProver<Flavor>::commit_to_witness_polynomial(Polynomial<FF>& polynomial,
const std::string& label,
const CommitmentKey::CommitType type)
{
// Mask if needed
if constexpr (Flavor::HasZK) {
mask_witness_polynomial(polynomial);
};

typename Flavor::Commitment commitment;

commitment = proving_key->proving_key.commitment_key->commit_with_type(
polynomial, type, proving_key->proving_key.active_region_data.get_ranges());
// Send the commitment to the verifier
transcript->send_to_verifier(domain_separator + label, commitment);
}

template class OinkProver<UltraFlavor>;
template class OinkProver<UltraZKFlavor>;
template class OinkProver<UltraKeccakFlavor>;
Expand Down
5 changes: 4 additions & 1 deletion barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ template <IsUltraFlavor Flavor> class OinkProver {
std::string domain_separator;
ExecutionTraceUsageTracker trace_usage_tracker;

typename Flavor::WitnessCommitments witness_commitments;
typename Flavor::CommitmentLabels commitment_labels;
using RelationSeparator = typename Flavor::RelationSeparator;

Expand All @@ -64,6 +63,10 @@ template <IsUltraFlavor Flavor> class OinkProver {
void execute_log_derivative_inverse_round();
void execute_grand_product_computation_round();
RelationSeparator generate_alphas_round();
void mask_witness_polynomial(Polynomial<FF>& polynomial);
void commit_to_witness_polynomial(Polynomial<FF>& polynomial,
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps this is a bit of a nitpick but I don't love a method with a simple name that does more than it says, i.e. this doesn't just commit, it potentially adds blinding and adds the commit to the proof. I don't feel strongly though. Either way, could you move the definitions of any new methods to the .cpp file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, will move to cpp.

I see your point, the justification I had for myself is that commit and send_to_verifier are basically inseparable + when I added branching on ZK in each method, they became unreadable

const std::string& label,
const CommitmentKey::CommitType type = CommitmentKey::CommitType::Default);
};

using MegaOinkProver = OinkProver<MegaFlavor>;
Expand Down