Skip to content
Closed
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
97 changes: 53 additions & 44 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "barretenberg/client_ivc/client_ivc.hpp"
#include "barretenberg/eccvm/eccvm_trace_checker.hpp"
#include "barretenberg/goblin/goblin.hpp"
#include "barretenberg/goblin/mock_circuits.hpp"
#include "barretenberg/stdlib_circuit_builders/goblin_ultra_circuit_builder.hpp"
Expand Down Expand Up @@ -113,53 +114,61 @@ class ClientIVCTests : public ::testing::Test {
*/
// TODO fix with https://github.com/AztecProtocol/barretenberg/issues/930
// intermittent failures, presumably due to uninitialized memory
TEST_F(ClientIVCTests, DISABLED_Full)
TEST_F(ClientIVCTests, Full)
{
using VerificationKey = Flavor::VerificationKey;

ClientIVC ivc;
// Initialize IVC with function circuit
Builder function_circuit = create_mock_circuit(ivc);
ivc.initialize(function_circuit);

auto function_vk = std::make_shared<VerificationKey>(ivc.prover_fold_output.accumulator->proving_key);
auto foo_verifier_instance = std::make_shared<VerifierInstance>(function_vk);
// Accumulate kernel circuit (first kernel mocked as simple circuit since no folding proofs yet)
Builder kernel_circuit = create_mock_circuit(ivc);
FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit);
// This will have a different verification key because we added the recursive merge verification to the circuit
auto function_vk_with_merge = std::make_shared<VerificationKey>(ivc.prover_instance->proving_key);
auto kernel_vk = function_vk_with_merge;
auto intermediary_acc = update_accumulator_and_decide_native(
ivc.prover_fold_output.accumulator, kernel_fold_proof, foo_verifier_instance, kernel_vk);

VerifierFoldData kernel_fold_output = { kernel_fold_proof, function_vk_with_merge };
size_t NUM_CIRCUITS = 1;
for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) {
// Accumulate function circuit
Builder function_circuit = create_mock_circuit(ivc);
FoldProof function_fold_proof = ivc.accumulate(function_circuit);
const auto run_test = []() {
using VerificationKey = Flavor::VerificationKey;

intermediary_acc = update_accumulator_and_decide_native(
ivc.prover_fold_output.accumulator, function_fold_proof, intermediary_acc, function_vk_with_merge);
ClientIVC ivc;
// Initialize IVC with function circuit
Builder function_circuit = create_mock_circuit(ivc);
ivc.initialize(function_circuit);

VerifierFoldData function_fold_output = { function_fold_proof, function_vk_with_merge };
// Accumulate kernel circuit
Builder kernel_circuit{ ivc.goblin.op_queue };
foo_verifier_instance = construct_mock_folding_kernel(
kernel_circuit, kernel_fold_output, function_fold_output, foo_verifier_instance);
auto function_vk = std::make_shared<VerificationKey>(ivc.prover_fold_output.accumulator->proving_key);
auto foo_verifier_instance = std::make_shared<VerifierInstance>(function_vk);
// Accumulate kernel circuit (first kernel mocked as simple circuit since no folding proofs yet)
Builder kernel_circuit = create_mock_circuit(ivc);
FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit);
kernel_vk = std::make_shared<VerificationKey>(ivc.prover_instance->proving_key);

intermediary_acc = update_accumulator_and_decide_native(
ivc.prover_fold_output.accumulator, kernel_fold_proof, intermediary_acc, kernel_vk);

VerifierFoldData kernel_fold_output = { kernel_fold_proof, kernel_vk };
// This will have a different verification key because we added the recursive merge verification to the circuit
auto function_vk_with_merge = std::make_shared<VerificationKey>(ivc.prover_instance->proving_key);
auto kernel_vk = function_vk_with_merge;
auto intermediary_acc = update_accumulator_and_decide_native(
ivc.prover_fold_output.accumulator, kernel_fold_proof, foo_verifier_instance, kernel_vk);

VerifierFoldData kernel_fold_output = { kernel_fold_proof, function_vk_with_merge };
size_t NUM_CIRCUITS = 1;
for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) {
// Accumulate function circuit
Builder function_circuit = create_mock_circuit(ivc);
FoldProof function_fold_proof = ivc.accumulate(function_circuit);

intermediary_acc = update_accumulator_and_decide_native(
ivc.prover_fold_output.accumulator, function_fold_proof, intermediary_acc, function_vk_with_merge);

VerifierFoldData function_fold_output = { function_fold_proof, function_vk_with_merge };
// Accumulate kernel circuit
Builder kernel_circuit{ ivc.goblin.op_queue };
foo_verifier_instance = construct_mock_folding_kernel(
kernel_circuit, kernel_fold_output, function_fold_output, foo_verifier_instance);
FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit);
kernel_vk = std::make_shared<VerificationKey>(ivc.prover_instance->proving_key);

intermediary_acc = update_accumulator_and_decide_native(
ivc.prover_fold_output.accumulator, kernel_fold_proof, intermediary_acc, kernel_vk);

VerifierFoldData kernel_fold_output = { kernel_fold_proof, kernel_vk };
}

// Constuct four proofs: merge, eccvm, translator, decider
auto proof = ivc.prove();
EXPECT_TRUE(ECCVMTraceChecker::check(*(ivc.goblin.eccvm_builder), &engine));
auto inst = std::make_shared<VerifierInstance>(kernel_vk);
// Verify all four proofs
EXPECT_TRUE(ivc.verify(proof, { foo_verifier_instance, inst }));
};
for (size_t idx = 84; idx < 256; idx++) {
numeric::get_debug_randomness(true, idx);
info("run ", idx);
run_test();
}

// Constuct four proofs: merge, eccvm, translator, decider
auto proof = ivc.prove();
auto inst = std::make_shared<VerifierInstance>(kernel_vk);
// Verify all four proofs
EXPECT_TRUE(ivc.verify(proof, { foo_verifier_instance, inst }));
};
11 changes: 11 additions & 0 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_builder_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ template <typename CycleGroup> struct VMOperation {
return res;
}
bool operator==(const VMOperation<CycleGroup>& other) const = default;
void print() const
{
info("add : ", add);
info("mul : ", mul);
info("eq : ", eq);
info("reset : ", reset);
info("base_point : ", base_point);
info("z1 : ", z1);
info("z2 : ", z2);
info("mul_scalar_full: ", mul_scalar_full);
}
};
template <typename CycleGroup> struct ScalarMul {
uint32_t pc;
Expand Down
63 changes: 32 additions & 31 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ class ECCVMCircuitBuilder {
size_t op_idx = 0;
// populate opqueue and mul indices
for (const auto& op : raw_ops) {
info("op index: ", op_idx);
op.print();
if (op.mul) {
if (op.z1 != 0 || op.z2 != 0) {
msm_opqueue_index.push_back(op_idx);
Expand Down Expand Up @@ -148,38 +150,36 @@ class ECCVMCircuitBuilder {
msm.resize(msm_sizes[i]);
}

run_loop_in_parallel(msm_opqueue_index.size(), [&](size_t start, size_t end) {
for (size_t i = start; i < end; i++) {
const auto& op = raw_ops[msm_opqueue_index[i]];
auto [msm_index, mul_index] = msm_mul_index[i];
if (op.z1 != 0) {
ASSERT(result.size() > msm_index);
ASSERT(result[msm_index].size() > mul_index);
result[msm_index][mul_index] = (ScalarMul{
.pc = 0,
.scalar = op.z1,
.base_point = op.base_point,
.wnaf_digits = compute_wnaf_digits(op.z1),
.wnaf_skew = (op.z1 & 1) == 0,
.precomputed_table = compute_precomputed_table(op.base_point),
});
mul_index++;
}
if (op.z2 != 0) {
ASSERT(result.size() > msm_index);
ASSERT(result[msm_index].size() > mul_index);
auto endo_point = AffineElement{ op.base_point.x * FF::cube_root_of_unity(), -op.base_point.y };
result[msm_index][mul_index] = (ScalarMul{
.pc = 0,
.scalar = op.z2,
.base_point = endo_point,
.wnaf_digits = compute_wnaf_digits(op.z2),
.wnaf_skew = (op.z2 & 1) == 0,
.precomputed_table = compute_precomputed_table(endo_point),
});
}
for (size_t i = 0; i < msm_opqueue_index.size(); i++) {
const auto& op = raw_ops[msm_opqueue_index[i]];
auto [msm_index, mul_index] = msm_mul_index[i];
if (op.z1 != 0) {
ASSERT(result.size() > msm_index);
ASSERT(result[msm_index].size() > mul_index);
result[msm_index][mul_index] = (ScalarMul{
.pc = 0,
.scalar = op.z1,
.base_point = op.base_point,
.wnaf_digits = compute_wnaf_digits(op.z1),
.wnaf_skew = (op.z1 & 1) == 0,
.precomputed_table = compute_precomputed_table(op.base_point),
});
mul_index++;
}
if (op.z2 != 0) {
ASSERT(result.size() > msm_index);
ASSERT(result[msm_index].size() > mul_index);
auto endo_point = AffineElement{ op.base_point.x * FF::cube_root_of_unity(), -op.base_point.y };
result[msm_index][mul_index] = (ScalarMul{
.pc = 0,
.scalar = op.z2,
.base_point = endo_point,
.wnaf_digits = compute_wnaf_digits(op.z2),
.wnaf_skew = (op.z2 & 1) == 0,
.precomputed_table = compute_precomputed_table(endo_point),
});
}
});
};

// update pc. easier to do this serially but in theory could be optimised out
// We start pc at `num_muls` and decrement for each mul processed.
Expand All @@ -190,6 +190,7 @@ class ECCVMCircuitBuilder {
// sumcheck relations that involve pc (if we did the other way around, starting at 1 and ending at num_muls,
// we create a discontinuity in pc values between the last transcript row and the following empty row)
uint32_t pc = num_muls;
// index of bad sm is [38], [0]
for (auto& msm : result) {
for (auto& mul : msm) {
mul.pc = pc;
Expand Down
4 changes: 2 additions & 2 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,13 @@ void ECCVMProver::execute_transcript_consistency_univariate_opening_round()
translation_batching_challenge_v = transcript->template get_challenge<FF>("Translation:batching_challenge");
}

HonkProof& ECCVMProver::export_proof()
HonkProof ECCVMProver::export_proof()
{
proof = transcript->export_proof();
return proof;
}

HonkProof& ECCVMProver::construct_proof()
HonkProof ECCVMProver::construct_proof()
{
BB_OP_COUNT_TIME_NAME("ECCVMProver::construct_proof");

Expand Down
4 changes: 2 additions & 2 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ class ECCVMProver {
BB_PROFILE void execute_zeromorph_rounds();
BB_PROFILE void execute_transcript_consistency_univariate_opening_round();

HonkProof& export_proof();
HonkProof& construct_proof();
HonkProof export_proof();
HonkProof construct_proof();

std::shared_ptr<Transcript> transcript;

Expand Down
2 changes: 2 additions & 0 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ bool ECCVMVerifier::verify_proof(const HonkProof& proof)

// If Sumcheck did not verify, return false
if (sumcheck_verified.has_value() && !sumcheck_verified.value()) {
ASSERT(sumcheck_verified.value());
info("ECCVM sumcheck verification failed");
return false;
}

Expand Down
28 changes: 28 additions & 0 deletions barretenberg/cpp/src/barretenberg/eccvm/msm_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,38 @@ class ECCVMMSMMBuilder {
AffineElement point{ 0, 0 };
FF lambda = 0;
FF collision_inverse = 0;
void print() const
{
info(" add :", add);
info(" slice :", slice);
info(" point :", point);
info(" lambda :", lambda);
info(" collision_inverse :", collision_inverse);
}
};
std::array<AddState, 4> add_state{ AddState{ false, 0, { 0, 0 }, 0, 0 },
AddState{ false, 0, { 0, 0 }, 0, 0 },
AddState{ false, 0, { 0, 0 }, 0, 0 },
AddState{ false, 0, { 0, 0 }, 0, 0 } };
FF accumulator_x = 0;
FF accumulator_y = 0;

void print() const
{
info("pc : ", pc);
info("msm_size : ", msm_size);
info("msm_count : ", msm_count);
info("msm_round : ", msm_round);
info("msm_transition : ", msm_transition);
info("q_add : ", q_add);
info("q_double : ", q_double);
info("q_skew : ", q_skew);
for (const auto& state : add_state) {
state.print();
}
info("accumulator_x : ", accumulator_x);
info("accumulator_y : ", accumulator_y);
};
};

/**
Expand Down Expand Up @@ -469,6 +494,9 @@ class ECCVMMSMMBuilder {
typename MSMRow::AddState{ false, 0, AffineElement{ 0, 0 }, 0, 0 },
typename MSMRow::AddState{ false, 0, AffineElement{ 0, 0 }, 0, 0 } };

msm_rows[2697].print();
info("printed the failing row");

return { msm_rows, point_table_read_counts };
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
RelationImpl<Flavor::FF>::MethodName<bb::Relation<RelationImpl<Flavor::FF>>::AccumulatorType, EdgeType(Flavor)>( \
EdgeType(Flavor) const&, RelationParameters<Flavor::FF> const&);

#define SUMCHECK_RELATION_CLASS(...) _SUMCHECK_RELATION_CLASS(__VA_ARGS__)
#define DEFINE_SUMCHECK_RELATION_CLASS(RelationImpl, Flavor) \
ACCUMULATE(RelationImpl, Flavor, SumcheckTupleOfUnivariatesOverSubrelations, ExtendedEdge) \
ACCUMULATE(RelationImpl, Flavor, SumcheckArrayOfValuesOverSubrelations, EvaluationEdge) \
Expand Down
6 changes: 5 additions & 1 deletion barretenberg/cpp/src/barretenberg/goblin/goblin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ class Goblin {
// on the first call to accumulate there is no merge proof to verify
bool merge_proof_exists{ false };

private:
// TODO(https://github.com/AztecProtocol/barretenberg/issues/798) unique_ptr use is a hack
std::unique_ptr<ECCVMBuilder> eccvm_builder;
std::unique_ptr<TranslatorBuilder> translator_builder;
std::unique_ptr<TranslatorProver> translator_prover;
std::unique_ptr<ECCVMProver> eccvm_prover;

private:
AccumulationOutput accumulator; // Used only for ACIR methods for now

public:
Expand Down Expand Up @@ -191,6 +191,10 @@ class Goblin {
goblin_proof.merge_proof = std::move(merge_proof);
prove_eccvm();
prove_translator();
info("proof exported: ");
for (auto& elt : goblin_proof.to_buffer()) {
info(elt);
}
return goblin_proof;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ template <IsUltraFlavor Flavor> void DeciderProver_<Flavor>::execute_zeromorph_r
transcript);
}

template <IsUltraFlavor Flavor> HonkProof& DeciderProver_<Flavor>::export_proof()
template <IsUltraFlavor Flavor> HonkProof DeciderProver_<Flavor>::export_proof()
{
proof = transcript->proof_data;
return proof;
}

template <IsUltraFlavor Flavor> HonkProof& DeciderProver_<Flavor>::construct_proof()
template <IsUltraFlavor Flavor> HonkProof DeciderProver_<Flavor>::construct_proof()
{
BB_OP_COUNT_TIME_NAME("Decider::construct_proof");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ template <IsUltraFlavor Flavor> class DeciderProver_ {
BB_PROFILE void execute_relation_check_rounds();
BB_PROFILE void execute_zeromorph_rounds();

HonkProof& export_proof();
HonkProof& construct_proof();
HonkProof export_proof();
HonkProof construct_proof();

std::shared_ptr<Instance> accumulator;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "barretenberg/stdlib/primitives/field/field_conversion.hpp"

// #define LOG_CHALLENGES
// #define LOG_INTERACTIONS
#define LOG_INTERACTIONS

namespace bb {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ GoblinTranslatorProver::GoblinTranslatorProver(CircuitBuilder& circuit_builder,
// Compute total number of gates, dyadic circuit size, etc.
key = std::make_shared<ProvingKey>(circuit_builder);
compute_witness(circuit_builder);
compute_commitment_key(key->circuit_size);
compute_commitment_key(16 * key->circuit_size);
}

/**
Expand Down Expand Up @@ -183,13 +183,13 @@ void GoblinTranslatorProver::execute_zeromorph_rounds()
key->polynomials.get_concatenation_groups());
}

HonkProof& GoblinTranslatorProver::export_proof()
HonkProof GoblinTranslatorProver::export_proof()
{
proof = transcript->export_proof();
return proof;
}

HonkProof& GoblinTranslatorProver::construct_proof()
HonkProof GoblinTranslatorProver::construct_proof()
{
BB_OP_COUNT_TIME_NAME("GoblinTranslatorProver::construct_proof");

Expand Down
Loading