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: new test program for verifying honk #6781

Merged
merged 2 commits into from
Jun 3, 2024
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
4 changes: 4 additions & 0 deletions barretenberg/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ barretenberg-acir-tests-bb:
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
# Construct and separately verify a UltraHonk proof for a single program that recursively verifies a Honk proof
RUN FLOW=prove_then_verify_ultra_honk ./run_acir_tests.sh verify_honk_proof
# Construct and verify a UltraHonk proof for a single program that recursively verifies a Honk proof
RUN FLOW=prove_and_verify_ultra_honk ./run_acir_tests.sh verify_honk_proof
# Run 1_mul through native bb build, all_cmds flow, to test all cli args.
RUN FLOW=all_cmds ./run_acir_tests.sh 1_mul

Expand Down
13 changes: 5 additions & 8 deletions barretenberg/acir_tests/gen_inner_proof_inputs_ultra_honk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# BIN: to specify a different binary to test with (e.g. bb.js or bb.js-dev).
set -eu

BIN=${BIN:-../cpp/build/bin/bb}
BIN=${BIN:-../cpp/build-debug/bin/bb}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

now that the debug build and standard build have diverged, I just changed this to debug, but maybe I can print out something that informs the user that the binary is defaulted to the debug version.

CRS_PATH=~/.bb-crs
BRANCH=master
VERBOSE=${VERBOSE:-}
Expand All @@ -28,18 +28,15 @@ VFLAG=${VERBOSE:+-v}
RFLAG=${RECURSIVE:+-r}

echo "Write VK to file for assert_statement..."
$BIN write_vk_ultra_honk $VFLAG -c $CRS_PATH -o ./target/vk
$BIN write_vk_ultra_honk $VFLAG -c $CRS_PATH -o ./target/honk_vk
Copy link
Contributor Author

Choose a reason for hiding this comment

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

just some name changes to separate it from the plonk vk and proof


echo "Write VK as fields for recursion..."
$BIN vk_as_fields_ultra_honk $VFLAG -c $CRS_PATH -k ./target/vk -o ./target/vk_fields.json
$BIN vk_as_fields_ultra_honk $VFLAG -c $CRS_PATH -k ./target/honk_vk -o ./target/honk_vk_fields.json

echo "Generate proof to file..."
[ -d "$PROOF_DIR" ] || mkdir $PWD/proofs
[ -e "$PROOF_PATH" ] || touch $PROOF_PATH
$BIN prove_ultra_honk $VFLAG -c $CRS_PATH -b ./target/program.json -o "./proofs/$PROOF_NAME"
$BIN prove_ultra_honk $VFLAG -c $CRS_PATH -b ./target/program.json -o "./proofs/honk_$PROOF_NAME"

echo "Write proof as fields for recursion..."
$BIN proof_as_fields_honk $VFLAG -c $CRS_PATH -p "./proofs/$PROOF_NAME" -o "./proofs/${PROOF_NAME}_fields.json"

cat ./proofs/${PROOF_NAME}_fields.json
echo
$BIN proof_as_fields_honk $VFLAG -c $CRS_PATH -p "./proofs/honk_$PROOF_NAME" -o "./proofs/honk_${PROOF_NAME}_fields.json"
Empty file modified barretenberg/acir_tests/reset_acir_tests.sh
100644 → 100755
Empty file.
7 changes: 7 additions & 0 deletions barretenberg/acir_tests/run_acir_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ trap handle_sigchild SIGCHLD

BIN=${BIN:-../cpp/build/bin/bb}
FLOW=${FLOW:-prove_and_verify}
HONK=${HONK:-false}
CRS_PATH=~/.bb-crs
BRANCH=master
VERBOSE=${VERBOSE:-}
Expand All @@ -37,6 +38,12 @@ cd acir_tests
# Convert them to array
SKIP_ARRAY=(diamond_deps_0 workspace workspace_default_member)

# if HONK is false, we should skip verify_honk_proof
if [ "$HONK" = false ]; then
# Insert the new item into the array
SKIP_ARRAY+=(verify_honk_proof)
fi

function test() {
cd $1

Expand Down
19 changes: 9 additions & 10 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ std::string vk_to_json(std::vector<bb::fr>& data)
return format("[", join(map(data, [](auto fr) { return format("\"", fr, "\""); })), "]");
}

std::string honk_vk_to_json(std::vector<bb::fr>& data)
{
return format("[", join(map(data, [](auto fr) { return format("\"", fr, "\""); })), "]");
}

/**
* @brief Proves and Verifies an ACIR circuit
*
Expand Down Expand Up @@ -593,7 +598,7 @@ void prove_honk(const std::string& bytecodePath, const std::string& witnessPath,
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);
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 Down Expand Up @@ -668,7 +673,7 @@ template <IsUltraFlavor Flavor> void write_vk_honk(const std::string& bytecodePa
honk_recursion = true;
}
auto constraint_system = get_constraint_system(bytecodePath, honk_recursion);
auto builder = acir_format::create_circuit<Builder>(constraint_system, 0, {});
auto builder = acir_format::create_circuit<Builder>(constraint_system, 0, {}, 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 Down Expand Up @@ -732,8 +737,7 @@ template <IsUltraFlavor Flavor> void vk_as_fields_honk(const std::string& vk_pat

auto verification_key = std::make_shared<VerificationKey>(from_buffer<VerificationKey>(read_file(vk_path)));
std::vector<bb::fr> data = verification_key->to_field_elements();

auto json = vk_to_json(data);
auto json = honk_vk_to_json(data);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixing the vk generation for honk.

if (output_path == "-") {
writeStringToStdout(json);
vinfo("vk as fields written to stdout");
Expand Down Expand Up @@ -811,7 +815,6 @@ int main(int argc, char* argv[])
try {
std::vector<std::string> args(argv + 1, argv + argc);
verbose = flag_present(args, "-v") || flag_present(args, "--verbose");

if (args.empty()) {
std::cerr << "No command provided.\n";
return 1;
Expand All @@ -824,11 +827,7 @@ 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;
}
bool honk_recursion = flag_present(args, "-h");
CRS_PATH = get_option(args, "-c", CRS_PATH);

// Skip CRS initialization for any command which doesn't require the CRS.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> create_ho
using RecursiveVerificationKey = Flavor::VerificationKey;
using RecursiveVerifier = UltraRecursiveVerifier_<Flavor>;

// Ignore the case of invalid witness assignments for now.
static_cast<void>(has_valid_witness_assignments);

// Construct aggregation points from the nested aggregation witness indices
std::array<bn254::Group, 2> nested_aggregation_points =
agg_points_from_witness_indicies(builder, nested_aggregation_object);
Expand Down Expand Up @@ -115,6 +112,23 @@ std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> create_ho

// Recursively verify the proof
auto vkey = std::make_shared<RecursiveVerificationKey>(builder, key_fields);
if (!has_valid_witness_assignments) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

second fix: we must know what recursive verifier to generate without knowing the witnesses

// Set vkey->circuit_size correctly based on the proof size
size_t num_frs_comm = bb::field_conversion::calc_num_bn254_frs<UltraFlavor::Commitment>();
size_t num_frs_fr = bb::field_conversion::calc_num_bn254_frs<UltraFlavor::FF>();
assert((input.proof.size() - HonkRecursionConstraint::inner_public_input_offset -
UltraFlavor::NUM_WITNESS_ENTITIES * num_frs_comm - UltraFlavor::NUM_ALL_ENTITIES * num_frs_fr -
2 * num_frs_comm) %
(num_frs_comm + num_frs_fr * UltraFlavor::BATCHED_RELATION_PARTIAL_LENGTH) ==
0);
vkey->log_circuit_size = (input.proof.size() - HonkRecursionConstraint::inner_public_input_offset -
UltraFlavor::NUM_WITNESS_ENTITIES * num_frs_comm -
UltraFlavor::NUM_ALL_ENTITIES * num_frs_fr - 2 * num_frs_comm) /
(num_frs_comm + num_frs_fr * UltraFlavor::BATCHED_RELATION_PARTIAL_LENGTH);
vkey->circuit_size = (1 << vkey->log_circuit_size);
vkey->num_public_inputs = input.public_inputs.size();
vkey->pub_inputs_offset = UltraFlavor::has_zero_row ? 1 : 0;
}
RecursiveVerifier verifier(&builder, vkey);
std::array<typename Flavor::GroupElement, 2> pairing_points = verifier.verify_proof(proof_fields);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ std::array<typename Flavor::GroupElement, 2> UltraRecursiveVerifier_<Flavor>::ve
VerifierCommitments commitments{ key };
CommitmentLabels commitment_labels;

const auto circuit_size = transcript->template receive_from_prover<FF>("circuit_size");
const auto public_input_size = transcript->template receive_from_prover<FF>("public_input_size");
const auto pub_inputs_offset = transcript->template receive_from_prover<FF>("pub_inputs_offset");
transcript->template receive_from_prover<FF>("circuit_size");
transcript->template receive_from_prover<FF>("public_input_size");
transcript->template receive_from_prover<FF>("pub_inputs_offset");

// For debugging purposes only
ASSERT(static_cast<uint32_t>(circuit_size.get_value()) == key->circuit_size);
ASSERT(static_cast<uint32_t>(public_input_size.get_value()) == key->num_public_inputs);
ASSERT(static_cast<uint32_t>(pub_inputs_offset.get_value()) == key->pub_inputs_offset);
// ASSERT(static_cast<uint32_t>(circuit_size.get_value()) == key->circuit_size);
// ASSERT(static_cast<uint32_t>(public_input_size.get_value()) == key->num_public_inputs);
// ASSERT(static_cast<uint32_t>(pub_inputs_offset.get_value()) == key->pub_inputs_offset);
Comment on lines +60 to +62
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
// ASSERT(static_cast<uint32_t>(circuit_size.get_value()) == key->circuit_size);
// ASSERT(static_cast<uint32_t>(public_input_size.get_value()) == key->num_public_inputs);
// ASSERT(static_cast<uint32_t>(pub_inputs_offset.get_value()) == key->pub_inputs_offset);
ASSERT(static_cast<uint32_t>(circuit_size.get_value()) == key->circuit_size);
ASSERT(static_cast<uint32_t>(public_input_size.get_value()) == key->num_public_inputs);
ASSERT(static_cast<uint32_t>(pub_inputs_offset.get_value()) == key->pub_inputs_offset);

Should we bring these back?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, they don't work anymore since the proof is garbage when the witnesses are not valid

Copy link
Contributor

Choose a reason for hiding this comment

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

Then let's delete or pass in the has_valid_witness_params field


std::vector<FF> public_inputs;
for (size_t i = 0; i < key->num_public_inputs; ++i) {
Expand Down Expand Up @@ -111,8 +111,8 @@ std::array<typename Flavor::GroupElement, 2> UltraRecursiveVerifier_<Flavor>::ve
}

const FF public_input_delta = compute_public_input_delta<Flavor>(
public_inputs, beta, gamma, circuit_size, static_cast<uint32_t>(pub_inputs_offset.get_value()));
const FF lookup_grand_product_delta = compute_lookup_grand_product_delta<FF>(beta, gamma, circuit_size);
public_inputs, beta, gamma, key->circuit_size, static_cast<uint32_t>(key->pub_inputs_offset));
const FF lookup_grand_product_delta = compute_lookup_grand_product_delta<FF>(beta, gamma, key->circuit_size);

relation_parameters.beta = beta;
relation_parameters.gamma = gamma;
Expand All @@ -125,7 +125,7 @@ std::array<typename Flavor::GroupElement, 2> UltraRecursiveVerifier_<Flavor>::ve

// Execute Sumcheck Verifier and extract multivariate opening point u = (u_0, ..., u_{d-1}) and purported
// multivariate evaluations at u
const size_t log_circuit_size = numeric::get_msb(static_cast<uint32_t>(circuit_size.get_value()));
const size_t log_circuit_size = numeric::get_msb(static_cast<uint32_t>(key->circuit_size));
auto sumcheck = Sumcheck(log_circuit_size, transcript);
RelationSeparator alpha;
for (size_t idx = 0; idx < alpha.size(); idx++) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "verify_honk_proof"
type = "bin"
authors = [""]
compiler_version = ">=0.29.0"

[dependencies]
Loading
Loading