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
10 changes: 6 additions & 4 deletions barretenberg/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@ barretenberg-acir-tests-bb:
# This ensures we test independent pk construction through real/garbage witness data paths.
RUN FLOW=prove_then_verify ./run_acir_tests.sh
# Construct and separately verify a UltraHonk proof for a single program
RUN FLOW=prove_then_verify_ultra_honk ./run_acir_tests.sh double_verify_nested_proof
RUN FLOW=prove_then_verify_ultra_honk ./run_acir_tests.sh sha256
# Construct and separately verify a MegaHonk proof for all acir programs
RUN FLOW=prove_then_verify_mega_honk ./run_acir_tests.sh
# Construct and verify a UltraHonk proof for a single program
RUN FLOW=prove_and_verify_ultra_honk ./run_acir_tests.sh double_verify_nested_proof
RUN FLOW=prove_and_verify_ultra_honk ./run_acir_tests.sh pedersen_hash
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason this one is pedersen and the other is sha256?
We should add a TODO for bringing back a double_verify_nested_proof

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nah, I was just picking different ones to increase variability. We should be able to bring this back in other PR which adds the verify_honk_proof test program.

# Construct and verify a MegaHonk proof for a single arbitrary program
RUN FLOW=prove_and_verify_mega_honk ./run_acir_tests.sh 6_array
# Construct and verify a UltraHonk proof for all ACIR programs using the new witness stack workflow
RUN FLOW=prove_and_verify_ultra_honk_program ./run_acir_tests.sh
# Construct and verify a MegaHonk proof on one non-recursive program using the new witness stack workflow
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Construct and verify a MegaHonk proof on one non-recursive program using the new witness stack workflow
# Construct and verify a UltraHonk proof on one non-recursive program using the new witness stack workflow

?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oops forgot to fix this. Oh well

RUN FLOW=prove_and_verify_ultra_honk_program ./run_acir_tests.sh merkle_insert
# Construct and verify a MegaHonk proof for all ACIR programs using the new witness stack workflow
RUN FLOW=prove_and_verify_mega_honk_program ./run_acir_tests.sh
# Fold and verify an ACIR program stack using ClientIvc
RUN FLOW=fold_and_verify_program ./run_acir_tests.sh fold_basic
# Run 1_mul through native bb build, all_cmds flow, to test all cli args.
Expand Down
63 changes: 45 additions & 18 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ acir_format::WitnessVector get_witness(std::string const& witness_path)
return acir_format::witness_buf_to_witness_data(witness_data);
}

acir_format::AcirFormat get_constraint_system(std::string const& bytecode_path)
acir_format::AcirFormat get_constraint_system(std::string const& bytecode_path, bool honk_recursion)
{
auto bytecode = get_bytecode(bytecode_path);
return acir_format::circuit_buf_to_acir_format(bytecode);
return acir_format::circuit_buf_to_acir_format(bytecode, honk_recursion);
}

acir_format::WitnessVectorStack get_witness_stack(std::string const& witness_path)
Expand All @@ -90,10 +90,10 @@ acir_format::WitnessVectorStack get_witness_stack(std::string const& witness_pat
return acir_format::witness_buf_to_witness_stack(witness_data);
}

std::vector<acir_format::AcirFormat> get_constraint_systems(std::string const& bytecode_path)
std::vector<acir_format::AcirFormat> get_constraint_systems(std::string const& bytecode_path, bool honk_recursion)
{
auto bytecode = get_bytecode(bytecode_path);
return acir_format::program_buf_to_acir_format(bytecode);
return acir_format::program_buf_to_acir_format(bytecode, honk_recursion);
}

std::string proof_to_json(std::vector<bb::fr>& proof)
Expand Down Expand Up @@ -124,7 +124,7 @@ std::string vk_to_json(std::vector<bb::fr>& data)
*/
bool proveAndVerify(const std::string& bytecodePath, const std::string& witnessPath)
{
auto constraint_system = get_constraint_system(bytecodePath);
auto constraint_system = get_constraint_system(bytecodePath, /*honk_recursion=*/false);
auto witness = get_witness(witnessPath);

acir_proofs::AcirComposer acir_composer{ 0, verbose };
Expand Down Expand Up @@ -161,8 +161,12 @@ bool proveAndVerifyHonkAcirFormat(acir_format::AcirFormat constraint_system, aci
using Verifier = UltraVerifier_<Flavor>;
using VerificationKey = Flavor::VerificationKey;

bool honk_recursion = false;
if constexpr (IsAnyOf<Flavor, UltraFlavor>) {
honk_recursion = true;
}
// Construct a bberg circuit from the acir representation
auto builder = acir_format::create_circuit<Builder>(constraint_system, 0, witness);
auto builder = acir_format::create_circuit<Builder>(constraint_system, 0, witness, honk_recursion);

auto num_extra_gates = builder.get_num_gates_added_to_ensure_nonzero_polynomials();
size_t srs_size = builder.get_circuit_subgroup_size(builder.get_total_circuit_size() + num_extra_gates);
Expand All @@ -188,8 +192,12 @@ bool proveAndVerifyHonkAcirFormat(acir_format::AcirFormat constraint_system, aci
*/
template <IsUltraFlavor Flavor> bool proveAndVerifyHonk(const std::string& bytecodePath, const std::string& witnessPath)
{
bool honk_recursion = false;
if constexpr (IsAnyOf<Flavor, UltraFlavor>) {
honk_recursion = true;
}
// Populate the acir constraint system and witness from gzipped data
auto constraint_system = get_constraint_system(bytecodePath);
auto constraint_system = get_constraint_system(bytecodePath, honk_recursion);
auto witness = get_witness(witnessPath);

return proveAndVerifyHonkAcirFormat<Flavor>(constraint_system, witness);
Expand All @@ -206,7 +214,11 @@ template <IsUltraFlavor Flavor> bool proveAndVerifyHonk(const std::string& bytec
template <IsUltraFlavor Flavor>
bool proveAndVerifyHonkProgram(const std::string& bytecodePath, const std::string& witnessPath)
{
auto program_stack = acir_format::get_acir_program_stack(bytecodePath, witnessPath);
bool honk_recursion = false;
if constexpr (IsAnyOf<Flavor, UltraFlavor>) {
honk_recursion = true;
}
auto program_stack = acir_format::get_acir_program_stack(bytecodePath, witnessPath, honk_recursion);

while (!program_stack.empty()) {
auto stack_item = program_stack.back();
Expand All @@ -230,7 +242,9 @@ bool foldAndVerifyProgram(const std::string& bytecodePath, const std::string& wi
ClientIVC ivc;
ivc.structured_flag = true;

auto program_stack = acir_format::get_acir_program_stack(bytecodePath, witnessPath);
auto program_stack = acir_format::get_acir_program_stack(
bytecodePath, witnessPath, false); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1013): this
// assumes that folding is never done with ultrahonk.

// Accumulate the entire program stack into the IVC
while (!program_stack.empty()) {
Expand Down Expand Up @@ -261,7 +275,7 @@ bool foldAndVerifyProgram(const std::string& bytecodePath, const std::string& wi
*/
void prove(const std::string& bytecodePath, const std::string& witnessPath, const std::string& outputPath)
{
auto constraint_system = get_constraint_system(bytecodePath);
auto constraint_system = get_constraint_system(bytecodePath, /*honk_recursion=*/false);
auto witness = get_witness(witnessPath);

acir_proofs::AcirComposer acir_composer{ 0, verbose };
Expand All @@ -287,11 +301,11 @@ void prove(const std::string& bytecodePath, const std::string& witnessPath, cons
*
* @param bytecodePath Path to the file containing the serialized circuit
*/
void gateCount(const std::string& bytecodePath)
void gateCount(const std::string& bytecodePath, bool honk_recursion)
{
// All circuit reports will be built into the string below
std::string functions_string = "{\"functions\": [\n ";
auto constraint_systems = get_constraint_systems(bytecodePath);
auto constraint_systems = get_constraint_systems(bytecodePath, honk_recursion);
size_t i = 0;
for (auto constraint_system : constraint_systems) {
acir_proofs::AcirComposer acir_composer(0, verbose);
Expand Down Expand Up @@ -360,7 +374,7 @@ bool verify(const std::string& proof_path, const std::string& vk_path)
*/
void write_vk(const std::string& bytecodePath, const std::string& outputPath)
{
auto constraint_system = get_constraint_system(bytecodePath);
auto constraint_system = get_constraint_system(bytecodePath, /*honk_recursion=*/false);
acir_proofs::AcirComposer acir_composer{ 0, verbose };
acir_composer.create_circuit(constraint_system);
init_bn254_crs(acir_composer.get_dyadic_circuit_size());
Expand All @@ -378,7 +392,7 @@ void write_vk(const std::string& bytecodePath, const std::string& outputPath)

void write_pk(const std::string& bytecodePath, const std::string& outputPath)
{
auto constraint_system = get_constraint_system(bytecodePath);
auto constraint_system = get_constraint_system(bytecodePath, /*honk_recursion=*/false);
acir_proofs::AcirComposer acir_composer{ 0, verbose };
acir_composer.create_circuit(constraint_system);
init_bn254_crs(acir_composer.get_dyadic_circuit_size());
Expand Down Expand Up @@ -572,7 +586,11 @@ void prove_honk(const std::string& bytecodePath, const std::string& witnessPath,
using Builder = Flavor::CircuitBuilder;
using Prover = UltraProver_<Flavor>;

auto constraint_system = get_constraint_system(bytecodePath);
bool honk_recursion = false;
if constexpr (IsAnyOf<Flavor, UltraFlavor>) {
honk_recursion = true;
}
auto constraint_system = get_constraint_system(bytecodePath, honk_recursion);
auto witness = get_witness(witnessPath);

auto builder = acir_format::create_circuit<Builder>(constraint_system, 0, witness);
Expand Down Expand Up @@ -645,7 +663,11 @@ template <IsUltraFlavor Flavor> void write_vk_honk(const std::string& bytecodePa
using ProverInstance = ProverInstance_<Flavor>;
using VerificationKey = Flavor::VerificationKey;

auto constraint_system = get_constraint_system(bytecodePath);
bool honk_recursion = false;
if constexpr (IsAnyOf<Flavor, UltraFlavor>) {
honk_recursion = true;
}
auto constraint_system = get_constraint_system(bytecodePath, honk_recursion);
auto builder = acir_format::create_circuit<Builder>(constraint_system, 0, {});

auto num_extra_gates = builder.get_num_gates_added_to_ensure_nonzero_polynomials();
Expand Down Expand Up @@ -733,7 +755,7 @@ template <IsUltraFlavor Flavor> void vk_as_fields_honk(const std::string& vk_pat
*/
void prove_output_all(const std::string& bytecodePath, const std::string& witnessPath, const std::string& outputPath)
{
auto constraint_system = get_constraint_system(bytecodePath);
auto constraint_system = get_constraint_system(bytecodePath, /*honk_recursion=*/false);
auto witness = get_witness(witnessPath);

acir_proofs::AcirComposer acir_composer{ 0, verbose };
Expand Down Expand Up @@ -802,6 +824,11 @@ int main(int argc, char* argv[])
std::string proof_path = get_option(args, "-p", "./proofs/proof");
std::string vk_path = get_option(args, "-k", "./target/vk");
std::string pk_path = get_option(args, "-r", "./target/pk");
std::string honk_recursion_str = get_option(args, "-h", "false");
bool honk_recursion = false;
if (honk_recursion_str == "true") {
honk_recursion = true;
}
CRS_PATH = get_option(args, "-c", CRS_PATH);

// Skip CRS initialization for any command which doesn't require the CRS.
Expand Down Expand Up @@ -835,7 +862,7 @@ int main(int argc, char* argv[])
std::string output_path = get_option(args, "-o", "./proofs");
prove_output_all(bytecode_path, witness_path, output_path);
} else if (command == "gates") {
gateCount(bytecode_path);
gateCount(bytecode_path, honk_recursion);
} else if (command == "verify") {
return verify(proof_path, vk_path) ? 0 : 1;
} else if (command == "contract") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,19 @@ class AcirIntegrationTest : public ::testing::Test {
return file.good();
}

acir_format::AcirProgramStack get_program_stack_data_from_test_file(const std::string& test_program_name)
acir_format::AcirProgramStack get_program_stack_data_from_test_file(const std::string& test_program_name,
bool honk_recursion)
{
std::string base_path = "../../acir_tests/acir_tests/" + test_program_name + "/target";
std::string bytecode_path = base_path + "/program.json";
std::string witness_path = base_path + "/witness.gz";

return acir_format::get_acir_program_stack(bytecode_path, witness_path);
return acir_format::get_acir_program_stack(bytecode_path, witness_path, honk_recursion);
}

acir_format::AcirProgram get_program_data_from_test_file(const std::string& test_program_name)
acir_format::AcirProgram get_program_data_from_test_file(const std::string& test_program_name, bool honk_recursion)
{
auto program_stack = get_program_stack_data_from_test_file(test_program_name);
auto program_stack = get_program_stack_data_from_test_file(test_program_name, honk_recursion);
ASSERT(program_stack.size() == 1); // Otherwise this method will not return full stack data

return program_stack.back();
Expand Down Expand Up @@ -142,7 +143,10 @@ TEST_P(AcirIntegrationSingleTest, DISABLED_ProveAndVerifyProgram)

std::string test_name = GetParam();
info("Test: ", test_name);
acir_format::AcirProgram acir_program = get_program_data_from_test_file(test_name);
acir_format::AcirProgram acir_program = get_program_data_from_test_file(
test_name,
/*honk_recursion=*/
false); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1013): Assumes Flavor is not UltraHonk

// Construct a bberg circuit from the acir representation
Builder builder = acir_format::create_circuit<Builder>(acir_program.constraints, 0, acir_program.witness);
Expand Down Expand Up @@ -369,7 +373,9 @@ TEST_P(AcirIntegrationFoldingTest, DISABLED_ProveAndVerifyProgramStack)
std::string test_name = GetParam();
info("Test: ", test_name);

auto program_stack = get_program_stack_data_from_test_file(test_name);
auto program_stack = get_program_stack_data_from_test_file(
test_name, /*honk_recursion=*/false); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1013):
// Assumes Flavor is not UltraHonk

while (!program_stack.empty()) {
auto program = program_stack.back();
Expand All @@ -390,7 +396,9 @@ TEST_P(AcirIntegrationFoldingTest, DISABLED_FoldAndVerifyProgramStack)
using Builder = Flavor::CircuitBuilder;

std::string test_name = GetParam();
auto program_stack = get_program_stack_data_from_test_file(test_name);
auto program_stack = get_program_stack_data_from_test_file(
test_name, /*honk_recursion=*/false); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1013):
// Assumes Flavor is not UltraHonk

ClientIVC ivc;
ivc.structured_flag = true;
Expand Down Expand Up @@ -428,7 +436,9 @@ TEST_F(AcirIntegrationTest, DISABLED_UpdateAcirCircuit)
using Builder = Flavor::CircuitBuilder;

std::string test_name = "6_array"; // arbitrary program with RAM gates
auto acir_program = get_program_data_from_test_file(test_name);
auto acir_program = get_program_data_from_test_file(
test_name, /*honk_recursion=*/false); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1013):
// Assumes Flavor is not UltraHonk

// Construct a bberg circuit from the acir representation
auto circuit = acir_format::create_circuit<Builder>(acir_program.constraints, 0, acir_program.witness);
Expand Down
Loading