Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 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
25 changes: 25 additions & 0 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ TEST_F(ECCVMTests, BaseCase)

ASSERT_TRUE(verified);
}
TEST_F(ECCVMTests, BaseCaseFixedSize)
{
ECCVMCircuitBuilder builder = generate_circuit(&engine);
ECCVMProver prover(builder, /*fixed_size = */ true);
ECCVMProof proof = prover.construct_proof();
ECCVMVerifier verifier(prover.key);
bool verified = verifier.verify_proof(proof);

ASSERT_TRUE(verified);
}

TEST_F(ECCVMTests, EqFails)
{
Expand All @@ -114,6 +124,21 @@ TEST_F(ECCVMTests, EqFails)
ASSERT_FALSE(verified);
}

TEST_F(ECCVMTests, EqFailsFixedSize)
{
auto builder = generate_circuit(&engine);
// Tamper with the eq op such that the expected value is incorect
builder.op_queue->add_erroneous_equality_op_for_testing();

builder.op_queue->num_transcript_rows++;
ECCVMProver prover(builder, /*fixed_size = */ true);

ECCVMProof proof = prover.construct_proof();
ECCVMVerifier verifier(prover.key);
bool verified = verifier.verify_proof(proof);
ASSERT_FALSE(verified);
}

TEST_F(ECCVMTests, CommittedSumcheck)
{
using Flavor = ECCVMFlavor;
Expand Down
152 changes: 104 additions & 48 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,7 @@ class ECCVMFlavor {
z_perm, // column 0
lookup_inverses); // column 1
};

/**
* @brief Container for all witness polynomials used/constructed by the prover.
* @details Shifts are not included here since they do not occupy their own memory.
*/
template <typename DataType> class WireEntities {
template <typename DataType> class WireNonShiftedEntities {
public:
DEFINE_FLAVOR_MEMBERS(DataType,
transcript_add, // column 0
Expand Down Expand Up @@ -195,45 +190,92 @@ class ECCVMFlavor {
transcript_msm_infinity, // column 56
transcript_msm_x_inverse, // column 57
transcript_msm_count_zero_at_transition, // column 58
transcript_msm_count_at_transition_inverse, // column 59
transcript_mul, // column 60
transcript_msm_count, // column 61
transcript_accumulator_x, // column 62
transcript_accumulator_y, // column 63
precompute_scalar_sum, // column 64
precompute_s1hi, // column 65
precompute_dx, // column 66
precompute_dy, // column 67
precompute_tx, // column 68
precompute_ty, // column 69
msm_transition, // column 70
msm_add, // column 71
msm_double, // column 72
msm_skew, // column 73
msm_accumulator_x, // column 74
msm_accumulator_y, // column 75
msm_count, // column 76
msm_round, // column 77
msm_add1, // column 78
msm_pc, // column 79
precompute_pc, // column 80
transcript_pc, // column 81
precompute_round, // column 82
transcript_accumulator_empty, // column 83
precompute_select) // column 84
transcript_msm_count_at_transition_inverse) // column 59
};

/**
* @brief Containter for transcript accumulators, they stand out as the only to-be-shifted wires that are always
* populated until the dyadic size of the circuit.
*/
template <typename DataType> class WireToBeShiftedAccumulatorEntities {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

General question: Are the updates to the flavors here just to coherently organize polynomials into groups that are independent/dependent on the "fixed size" for commitment efficiency?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's right + wanted to avoid duplication.
In the commitment phase, the iteration was over the get_wires(), now its over get_wires_without_accumulators() (possibly short) and get_accumulators() (always max size).

public:
DEFINE_FLAVOR_MEMBERS(DataType,
transcript_accumulator_empty, // column 83
transcript_accumulator_x, // column 62
transcript_accumulator_y) // column 63
};
/**
* @brief Container for all to-be-shifted witness polynomials excluding the accumulators used/constructed by the
* prover.
* @details Shifts are not included here since they do not occupy their own memory.
*/
template <typename DataType> class WireToBeShiftedWithoutAccumulatorsEntities {
public:
DEFINE_FLAVOR_MEMBERS(DataType,
transcript_mul, // column 60
transcript_msm_count, // column 61
precompute_scalar_sum, // column 64
precompute_s1hi, // column 65
precompute_dx, // column 66
precompute_dy, // column 67
precompute_tx, // column 68
precompute_ty, // column 69
msm_transition, // column 70
msm_add, // column 71
msm_double, // column 72
msm_skew, // column 73
msm_accumulator_x, // column 74
msm_accumulator_y, // column 75
msm_count, // column 76
msm_round, // column 77
msm_add1, // column 78
msm_pc, // column 79
precompute_pc, // column 80
transcript_pc, // column 81
precompute_round, // column 82
precompute_select) // column 84
};
/**
* @brief Container for all wire polynomials used/constructed by the prover.
* @details Shifts are not included here since they do not occupy their own memory.
*/
template <typename DataType>
class WireEntities : public WireNonShiftedEntities<DataType>,
public WireToBeShiftedAccumulatorEntities<DataType>,
public WireToBeShiftedWithoutAccumulatorsEntities<DataType> {
public:
DEFINE_COMPOUND_GET_ALL(WireNonShiftedEntities<DataType>,
WireToBeShiftedAccumulatorEntities<DataType>,
WireToBeShiftedWithoutAccumulatorsEntities<DataType>);
};
/**
* @brief Container for all witness polynomials used/constructed by the prover.
* @details Shifts are not included here since they do not occupy their own memory.
*/
template <typename DataType>
class WitnessEntities : public WireEntities<DataType>, public DerivedWitnessEntities<DataType> {
class WitnessEntities : public WireNonShiftedEntities<DataType>,
public WireToBeShiftedWithoutAccumulatorsEntities<DataType>,
public WireToBeShiftedAccumulatorEntities<DataType>,
public DerivedWitnessEntities<DataType> {
public:
DEFINE_COMPOUND_GET_ALL(WireEntities<DataType>, DerivedWitnessEntities<DataType>)
auto get_wires() { return WireEntities<DataType>::get_all(); };
// The sorted concatenations of table and witness data needed for plookup.
auto get_sorted_polynomials() { return RefArray<DataType, 0>{}; };
DEFINE_COMPOUND_GET_ALL(WireNonShiftedEntities<DataType>,
WireToBeShiftedWithoutAccumulatorsEntities<DataType>,
WireToBeShiftedAccumulatorEntities<DataType>,
DerivedWitnessEntities<DataType>)
auto get_wires()
{
return concatenate(WireNonShiftedEntities<DataType>::get_all(),
WireToBeShiftedWithoutAccumulatorsEntities<DataType>::get_all(),
WireToBeShiftedAccumulatorEntities<DataType>::get_all());
};

// Used to amortize the commitment time when the ECCVM size is fixed
auto get_accumulators() { return WireToBeShiftedAccumulatorEntities<DataType>::get_all(); };
auto get_wires_without_accumulators()
{
return concatenate(WireNonShiftedEntities<DataType>::get_all(),
WireToBeShiftedWithoutAccumulatorsEntities<DataType>::get_all());
}
};

/**
Expand All @@ -244,8 +286,6 @@ class ECCVMFlavor {
DEFINE_FLAVOR_MEMBERS(DataType,
transcript_mul_shift, // column 0
transcript_msm_count_shift, // column 1
transcript_accumulator_x_shift, // column 2
transcript_accumulator_y_shift, // column 3
precompute_scalar_sum_shift, // column 4
precompute_s1hi_shift, // column 5
precompute_dx_shift, // column 6
Expand All @@ -265,8 +305,10 @@ class ECCVMFlavor {
precompute_pc_shift, // column 20
transcript_pc_shift, // column 21
precompute_round_shift, // column 22
transcript_accumulator_empty_shift, // column 23
precompute_select_shift, // column 24
transcript_accumulator_empty_shift, // column 23

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

column number comments are off here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

thanks, fixed

transcript_accumulator_x_shift, // column 2
transcript_accumulator_y_shift, // column 3
z_perm_shift); // column 25
};

Expand All @@ -276,8 +318,6 @@ class ECCVMFlavor {
// NOTE: must match order of ShiftedEntities above!
return RefArray{ entities.transcript_mul, // column 0
entities.transcript_msm_count, // column 1
entities.transcript_accumulator_x, // column 2
entities.transcript_accumulator_y, // column 3
entities.precompute_scalar_sum, // column 4
entities.precompute_s1hi, // column 5
entities.precompute_dx, // column 6
Expand All @@ -297,8 +337,10 @@ class ECCVMFlavor {
entities.precompute_pc, // column 20
entities.transcript_pc, // column 21
entities.precompute_round, // column 22
entities.transcript_accumulator_empty, // column 23
entities.precompute_select, // column 24
entities.transcript_accumulator_empty, // column 23

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

also here

entities.transcript_accumulator_x, // column 2
entities.transcript_accumulator_y, // column 3
entities.z_perm }; // column 25
}

Expand Down Expand Up @@ -500,7 +542,7 @@ class ECCVMFlavor {
table (reads come from msm_x/y3, msm_x/y4)
* @return ProverPolynomials
*/
ProverPolynomials(const CircuitBuilder& builder)
ProverPolynomials(const CircuitBuilder& builder, const bool fixed_size = false)
{
// compute rows for the three different sections of the ECCVM execution trace
const auto transcript_rows =
Expand All @@ -516,7 +558,12 @@ class ECCVMFlavor {
const size_t num_rows =
std::max({ point_table_rows.size(), msm_rows.size(), transcript_rows.size() }) + MASKING_OFFSET;
const auto log_num_rows = static_cast<size_t>(numeric::get_msb64(num_rows));
const size_t dyadic_num_rows = 1UL << (log_num_rows + (1UL << log_num_rows == num_rows ? 0 : 1));

ASSERT(1UL << CONST_ECCVM_LOG_N > 1UL << (log_num_rows + (1UL << log_num_rows == num_rows ? 0 : 1)));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

need to change to a runtime check?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Couple of suggestions here: 1) make well named variables for each of the expressions in these conditionals here so they're easier to digest. 2) For runtime checks, I usually just convert something like this to a
if (condition) {info("Relevant warning"); ASSERT(false);}. For now this is better than having nothing at all at runtime - in the future maybe we can improve the pattern further

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

thanks for the suggestion!

simplified the logic here


const size_t dyadic_num_rows = fixed_size
? 1UL << CONST_ECCVM_LOG_N
: 1UL << (log_num_rows + (1UL << log_num_rows == num_rows ? 0 : 1));

for (auto& poly : get_to_be_shifted()) {
poly = Polynomial{ /*memory size*/ dyadic_num_rows - 1,
Expand Down Expand Up @@ -681,12 +728,21 @@ class ECCVMFlavor {
// Expose constructors on the base class
using Base = ProvingKey_<FF, CommitmentKey>;
using Base::Base;
// Used to amortize the commitment time when `fixed_size` = true.
size_t real_size = 0;

ProverPolynomials polynomials; // storage for all polynomials evaluated by the prover

ProvingKey(const CircuitBuilder& builder)
: Base(builder.get_circuit_subgroup_size(builder.get_estimated_num_finalized_gates()), 0)
, polynomials(builder)
ProvingKey(const CircuitBuilder& builder, const bool fixed_size = false)
: Base(
// If we want a fixed size, use 2^(CONST_ECCVM_LOG_N).
// Otherwise, compute the real circuit size from the builder.
fixed_size ? (1UL << CONST_ECCVM_LOG_N)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is another case where the logic is too complicated for a single inline conditional. I'd break it into separate readable variables

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

that's fair, changed the way it's initialized

: builder.get_circuit_subgroup_size(builder.get_estimated_num_finalized_gates()),
0)
, real_size(builder.get_circuit_subgroup_size(builder.get_estimated_num_finalized_gates()))

, polynomials(builder, fixed_size)
{}
};

Expand Down
25 changes: 18 additions & 7 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,20 @@
namespace bb {

ECCVMProver::ECCVMProver(CircuitBuilder& builder,
const bool fixed_size,
const std::shared_ptr<Transcript>& transcript,
const std::shared_ptr<Transcript>& ipa_transcript)
: transcript(transcript)
, ipa_transcript(ipa_transcript)
, fixed_size(fixed_size)
{
PROFILE_THIS_NAME("ECCVMProver(CircuitBuilder&)");

// TODO(https://github.com/AztecProtocol/barretenberg/issues/939): Remove redundancy between
// ProvingKey/ProverPolynomials and update the model to reflect what's done in all other proving systems.

// Construct the proving key; populates all polynomials except for witness polys
key = std::make_shared<ProvingKey>(builder);
key = std::make_shared<ProvingKey>(builder, fixed_size);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

the compiler was choosing the wrong constructor, so I added this condition


key->commitment_key = std::make_shared<CommitmentKey>(key->circuit_size);
}
Expand All @@ -45,10 +47,19 @@ void ECCVMProver::execute_preamble_round()
*/
void ECCVMProver::execute_wire_commitments_round()
{
auto wire_polys = key->polynomials.get_wires();
auto labels = commitment_labels.get_wires();
for (size_t idx = 0; idx < wire_polys.size(); ++idx) {
transcript->send_to_verifier(labels[idx], key->commitment_key->commit(wire_polys[idx]));
// Commit to wires whose length is bounded by the real size of the ECCVM
for (const auto& [wire, label] : zip_view(key->polynomials.get_wires_without_accumulators(),
commitment_labels.get_wires_without_accumulators())) {
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1240) Structured Polynomials in
// ECCVM/Translator/MegaZK
PolynomialSpan<FF> wire_span = wire;
transcript->send_to_verifier(label, key->commitment_key->commit(wire_span.subspan(0, key->real_size)));
}

// The accumulators are populated until the 2^{CONST_ECCVM_LOG_N}, therefore we commit to a full-sized polynomial
for (const auto& [wire, label] :
zip_view(key->polynomials.get_accumulators(), commitment_labels.get_accumulators())) {
transcript->send_to_verifier(label, key->commitment_key->commit(wire));
}
}

Expand All @@ -58,6 +69,7 @@ void ECCVMProver::execute_wire_commitments_round()
*/
void ECCVMProver::execute_log_derivative_commitments_round()
{

// Compute and add beta to relation parameters
auto [beta, gamma] = transcript->template get_challenges<FF>("beta", "gamma");

Expand Down Expand Up @@ -95,6 +107,7 @@ void ECCVMProver::execute_grand_product_computation_round()
*/
void ECCVMProver::execute_relation_check_rounds()
{

using Sumcheck = SumcheckProver<Flavor>;

auto sumcheck = Sumcheck(key->circuit_size, transcript);
Expand Down Expand Up @@ -199,8 +212,6 @@ void ECCVMProver::execute_pcs_rounds()

// Produce another challenge passed as input to the translator verifier
translation_batching_challenge_v = transcript->template get_challenge<FF>("Translation:batching_challenge");

vinfo("computed opening proof");
}

ECCVMProof ECCVMProver::export_proof()
Expand Down
3 changes: 3 additions & 0 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class ECCVMProver {
using SmallSubgroupIPA = SmallSubgroupIPAProver<Flavor>;

explicit ECCVMProver(CircuitBuilder& builder,
const bool fixed_size = false,
const std::shared_ptr<Transcript>& transcript = std::make_shared<Transcript>(),
const std::shared_ptr<Transcript>& ipa_transcript = std::make_shared<Transcript>());

Expand All @@ -47,6 +48,8 @@ class ECCVMProver {
std::shared_ptr<Transcript> transcript;
std::shared_ptr<Transcript> ipa_transcript;

bool fixed_size;

TranslationEvaluations translation_evaluations;

std::vector<FF> public_inputs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ class ECCVMTranscriptTests : public ::testing::Test {
manifest_expected.add_entry(round, "TRANSCRIPT_MSM_COUNT_AT_TRANSITION_INVERSE", frs_per_G);
manifest_expected.add_entry(round, "TRANSCRIPT_MUL", frs_per_G);
manifest_expected.add_entry(round, "TRANSCRIPT_MSM_COUNT", frs_per_G);
manifest_expected.add_entry(round, "TRANSCRIPT_ACCUMULATOR_X", frs_per_G);
manifest_expected.add_entry(round, "TRANSCRIPT_ACCUMULATOR_Y", frs_per_G);
manifest_expected.add_entry(round, "PRECOMPUTE_SCALAR_SUM", frs_per_G);
manifest_expected.add_entry(round, "PRECOMPUTE_S1HI", frs_per_G);
manifest_expected.add_entry(round, "PRECOMPUTE_DX", frs_per_G);
Expand All @@ -120,8 +118,10 @@ class ECCVMTranscriptTests : public ::testing::Test {
manifest_expected.add_entry(round, "PRECOMPUTE_PC", frs_per_G);
manifest_expected.add_entry(round, "TRANSCRIPT_PC", frs_per_G);
manifest_expected.add_entry(round, "PRECOMPUTE_ROUND", frs_per_G);
manifest_expected.add_entry(round, "TRANSCRIPT_ACCUMULATOR_EMPTY", frs_per_G);
manifest_expected.add_entry(round, "PRECOMPUTE_SELECT", frs_per_G);
manifest_expected.add_entry(round, "TRANSCRIPT_ACCUMULATOR_EMPTY", frs_per_G);
manifest_expected.add_entry(round, "TRANSCRIPT_ACCUMULATOR_X", frs_per_G);
manifest_expected.add_entry(round, "TRANSCRIPT_ACCUMULATOR_Y", frs_per_G);
manifest_expected.add_challenge(round, "beta", "gamma");

round++;
Expand Down
Loading