Skip to content

Commit

Permalink
Merge branch 'master' into fix/bb-pako-import
Browse files Browse the repository at this point in the history
  • Loading branch information
saleel authored Nov 27, 2024
2 parents b246a89 + 089c34c commit 15f2bed
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 107 deletions.
79 changes: 28 additions & 51 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,6 @@ void client_ivc_prove_output_all_msgpack(const std::string& bytecodePath,
using Program = acir_format::AcirProgram;
using ECCVMVK = ECCVMFlavor::VerificationKey;
using TranslatorVK = TranslatorFlavor::VerificationKey;
using DeciderVerificationKey = ClientIVC::DeciderVerificationKey;

using namespace acir_format;

Expand Down Expand Up @@ -378,23 +377,17 @@ void client_ivc_prove_output_all_msgpack(const std::string& bytecodePath,

// Write the proof and verification keys into the working directory in 'binary' format (in practice it seems this
// directory is passed by bb.js)
std::string vkPath = outputDir + "/mega_vk"; // the vk of the last circuit in the stack
std::string vkPath = outputDir + "/client_ivc_vk"; // the vk of the last circuit in the stack
std::string proofPath = outputDir + "/client_ivc_proof";
std::string translatorVkPath = outputDir + "/translator_vk";
std::string eccVkPath = outputDir + "/ecc_vk";

auto proof = ivc.prove();
auto eccvm_vk = std::make_shared<ECCVMVK>(ivc.goblin.get_eccvm_proving_key());
auto translator_vk = std::make_shared<TranslatorVK>(ivc.goblin.get_translator_proving_key());

auto last_vk = std::make_shared<DeciderVerificationKey>(ivc.honk_vk);
vinfo("ensure valid proof: ", ivc.verify(proof));

vinfo("write proof and vk data to files..");
write_file(proofPath, to_buffer(proof));
write_file(vkPath, to_buffer(ivc.honk_vk));
write_file(translatorVkPath, to_buffer(translator_vk));
write_file(eccVkPath, to_buffer(eccvm_vk));
write_file(vkPath, to_buffer(ClientIVC::VerificationKey{ ivc.honk_vk, eccvm_vk, translator_vk }));
}

template <typename T> std::shared_ptr<T> read_to_shared_ptr(const std::filesystem::path& path)
Expand All @@ -414,24 +407,20 @@ template <typename T> std::shared_ptr<T> read_to_shared_ptr(const std::filesyste
* @param accumualtor_path Path to the file containing the serialized protogalaxy accumulator
* @return true (resp., false) if the proof is valid (resp., invalid).
*/
bool verify_client_ivc(const std::filesystem::path& proof_path,
const std::filesystem::path& mega_vk,
const std::filesystem::path& eccvm_vk_path,
const std::filesystem::path& translator_vk_path)
bool verify_client_ivc(const std::filesystem::path& proof_path, const std::filesystem::path& vk_path)
{
init_bn254_crs(1);
init_grumpkin_crs(1 << 15);

const auto proof = from_buffer<ClientIVC::Proof>(read_file(proof_path));
const auto final_vk = read_to_shared_ptr<ClientIVC::VerificationKey>(mega_vk);
final_vk->pcs_verification_key = std::make_shared<VerifierCommitmentKey<curve::BN254>>();

const auto eccvm_vk = read_to_shared_ptr<ECCVMFlavor::VerificationKey>(eccvm_vk_path);
eccvm_vk->pcs_verification_key =
std::make_shared<VerifierCommitmentKey<curve::Grumpkin>>(eccvm_vk->circuit_size + 1);
const auto translator_vk = read_to_shared_ptr<TranslatorFlavor::VerificationKey>(translator_vk_path);
translator_vk->pcs_verification_key = std::make_shared<VerifierCommitmentKey<curve::BN254>>();
const bool verified = ClientIVC::verify(proof, final_vk, eccvm_vk, translator_vk);
const auto vk = from_buffer<ClientIVC::VerificationKey>(read_file(vk_path));

vk.mega->pcs_verification_key = std::make_shared<VerifierCommitmentKey<curve::BN254>>();
vk.eccvm->pcs_verification_key =
std::make_shared<VerifierCommitmentKey<curve::Grumpkin>>(vk.eccvm->circuit_size + 1);
vk.translator->pcs_verification_key = std::make_shared<VerifierCommitmentKey<curve::BN254>>();

const bool verified = ClientIVC::verify(proof, vk);
vinfo("verified: ", verified);
return verified;
}
Expand Down Expand Up @@ -519,10 +508,8 @@ void client_ivc_prove_output_all(const std::string& bytecodePath,

// Write the proof and verification keys into the working directory in 'binary' format (in practice it seems this
// directory is passed by bb.js)
std::string vkPath = outputPath + "/mega_vk"; // the vk of the last circuit in the stack
std::string vkPath = outputPath + "/client_ivc_vk"; // the vk of the last circuit in the stack
std::string proofPath = outputPath + "/client_ivc_proof";
std::string translatorVkPath = outputPath + "/translator_vk";
std::string eccVkPath = outputPath + "/ecc_vk";

auto proof = ivc.prove();
auto eccvm_vk = std::make_shared<ECCVMVK>(ivc.goblin.get_eccvm_proving_key());
Expand All @@ -531,9 +518,7 @@ void client_ivc_prove_output_all(const std::string& bytecodePath,

vinfo("write proof and vk data to files..");
write_file(proofPath, to_buffer(proof));
write_file(vkPath, to_buffer(ivc.honk_vk)); // maybe dereference
write_file(translatorVkPath, to_buffer(translator_vk));
write_file(eccVkPath, to_buffer(eccvm_vk));
write_file(vkPath, to_buffer(ClientIVC::VerificationKey{ ivc.honk_vk, eccvm_vk, translator_vk }));
}

/**
Expand All @@ -544,37 +529,31 @@ void client_ivc_prove_output_all(const std::string& bytecodePath,
*/
void prove_tube(const std::string& output_path)
{
using ClientIVC = stdlib::recursion::honk::ClientIVCRecursiveVerifier;
using StackHonkVK = typename MegaFlavor::VerificationKey;
using ECCVMVk = ECCVMFlavor::VerificationKey;
using TranslatorVk = TranslatorFlavor::VerificationKey;
using GoblinVerifierInput = ClientIVC::GoblinVerifierInput;
using VerifierInput = ClientIVC::VerifierInput;
using namespace stdlib::recursion::honk;

using GoblinVerifierInput = ClientIVCRecursiveVerifier::GoblinVerifierInput;
using VerifierInput = ClientIVCRecursiveVerifier::VerifierInput;
using Builder = UltraCircuitBuilder;
using GrumpkinVk = bb::VerifierCommitmentKey<curve::Grumpkin>;

std::string vkPath = output_path + "/mega_vk"; // the vk of the last circuit in the stack
std::string vkPath = output_path + "/client_ivc_vk"; // the vk of the last circuit in the stack
std::string proofPath = output_path + "/client_ivc_proof";
std::string translatorVkPath = output_path + "/translator_vk";
std::string eccVkPath = output_path + "/ecc_vk";

// Note: this could be decreased once we optimise the size of the ClientIVC recursiveve rifier
init_bn254_crs(1 << 25);
init_grumpkin_crs(1 << 18);

// Read the proof and verification data from given files
auto proof = from_buffer<ClientIVC::Proof>(read_file(proofPath));
std::shared_ptr<StackHonkVK> mega_vk = std::make_shared<StackHonkVK>(from_buffer<StackHonkVK>(read_file(vkPath)));
std::shared_ptr<TranslatorVk> translator_vk =
std::make_shared<TranslatorVk>(from_buffer<TranslatorVk>(read_file(translatorVkPath)));
std::shared_ptr<ECCVMVk> eccvm_vk = std::make_shared<ECCVMVk>(from_buffer<ECCVMVk>(read_file(eccVkPath)));
auto vk = from_buffer<ClientIVC::VerificationKey>(read_file(vkPath));

// We don't serialise and deserialise the Grumkin SRS so initialise with circuit_size + 1 to be able to recursively
// IPA. The + 1 is to satisfy IPA verification key requirements.
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1025)
eccvm_vk->pcs_verification_key = std::make_shared<GrumpkinVk>(eccvm_vk->circuit_size + 1);
vk.eccvm->pcs_verification_key = std::make_shared<GrumpkinVk>(vk.eccvm->circuit_size + 1);

GoblinVerifierInput goblin_verifier_input{ eccvm_vk, translator_vk };
VerifierInput input{ mega_vk, goblin_verifier_input };
GoblinVerifierInput goblin_verifier_input{ vk.eccvm, vk.translator };
VerifierInput input{ vk.mega, goblin_verifier_input };
auto builder = std::make_shared<Builder>();

// Preserve the public inputs that should be passed to the base rollup by making them public inputs to the tube
Expand All @@ -588,9 +567,9 @@ void prove_tube(const std::string& output_path)
auto offset = bb::HONK_PROOF_PUBLIC_INPUT_OFFSET;
builder->add_public_variable(proof.mega_proof[i + offset]);
}
ClientIVC verifier{ builder, input };
ClientIVCRecursiveVerifier verifier{ builder, input };

ClientIVC::Output client_ivc_rec_verifier_output = verifier.verify(proof);
ClientIVCRecursiveVerifier::Output client_ivc_rec_verifier_output = verifier.verify(proof);

PairingPointAccumulatorIndices current_aggregation_object =
stdlib::recursion::init_default_agg_obj_indices<Builder>(*builder);
Expand Down Expand Up @@ -1468,12 +1447,10 @@ int main(int argc, char* argv[])
}
if (command == "verify_client_ivc") {
std::filesystem::path output_dir = get_option(args, "-o", "./target");
std::filesystem::path client_ivc_proof_path = output_dir / "client_ivc_proof";
std::filesystem::path mega_vk_path = output_dir / "mega_vk";
std::filesystem::path eccvm_vk_path = output_dir / "ecc_vk";
std::filesystem::path translator_vk_path = output_dir / "translator_vk";
std::filesystem::path proof_path = output_dir / "client_ivc_proof";
std::filesystem::path vk_path = output_dir / "client_ivc_vk";

return verify_client_ivc(client_ivc_proof_path, mega_vk_path, eccvm_vk_path, translator_vk_path) ? 0 : 1;
return verify_client_ivc(proof_path, vk_path) ? 0 : 1;
}
if (command == "fold_and_verify_program") {
return foldAndVerifyProgram(bytecode_path, witness_path) ? 0 : 1;
Expand Down
25 changes: 12 additions & 13 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ void ClientIVC::complete_kernel_circuit_logic(ClientCircuit& circuit)
* @param circuit
* @param precomputed_vk
*/
void ClientIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr<VerificationKey>& precomputed_vk, bool mock_vk)
void ClientIVC::accumulate(ClientCircuit& circuit,
const std::shared_ptr<MegaVerificationKey>& precomputed_vk,
bool mock_vk)
{
if (auto_verify_mode && circuit.databus_propagation_data.is_kernel) {
complete_kernel_circuit_logic(circuit);
Expand Down Expand Up @@ -186,7 +188,7 @@ void ClientIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr<Verific
trace_usage_tracker.update(circuit);

// Set the verification key from precomputed if available, else compute it
honk_vk = precomputed_vk ? precomputed_vk : std::make_shared<VerificationKey>(proving_key->proving_key);
honk_vk = precomputed_vk ? precomputed_vk : std::make_shared<MegaVerificationKey>(proving_key->proving_key);
if (mock_vk) {
honk_vk->set_metadata(proving_key->proving_key);
}
Expand Down Expand Up @@ -280,7 +282,7 @@ HonkProof ClientIVC::construct_and_prove_hiding_circuit()
merge_verification_queue.emplace_back(merge_proof);

auto decider_pk = std::make_shared<DeciderProvingKey>(builder, TraceSettings(), bn254_commitment_key);
honk_vk = std::make_shared<VerificationKey>(decider_pk->proving_key);
honk_vk = std::make_shared<MegaVerificationKey>(decider_pk->proving_key);
MegaProver prover(decider_pk);

HonkProof proof = prover.construct_proof();
Expand All @@ -301,18 +303,15 @@ ClientIVC::Proof ClientIVC::prove()
return { mega_proof, goblin.prove(merge_proof) };
};

bool ClientIVC::verify(const Proof& proof,
const std::shared_ptr<VerificationKey>& mega_vk,
const std::shared_ptr<ClientIVC::ECCVMVerificationKey>& eccvm_vk,
const std::shared_ptr<ClientIVC::TranslatorVerificationKey>& translator_vk)
bool ClientIVC::verify(const Proof& proof, const VerificationKey& vk)
{

// Verify the hiding circuit proof
MegaVerifier verifer{ mega_vk };
MegaVerifier verifer{ vk.mega };
bool mega_verified = verifer.verify_proof(proof.mega_proof);
vinfo("Mega verified: ", mega_verified);
// Goblin verification (final merge, eccvm, translator)
GoblinVerifier goblin_verifier{ eccvm_vk, translator_vk };
GoblinVerifier goblin_verifier{ vk.eccvm, vk.translator };
bool goblin_verified = goblin_verifier.verify(proof.goblin_proof);
vinfo("Goblin verified: ", goblin_verified);
return goblin_verified && mega_verified;
Expand All @@ -328,7 +327,7 @@ bool ClientIVC::verify(const Proof& proof)
{
auto eccvm_vk = std::make_shared<ECCVMVerificationKey>(goblin.get_eccvm_proving_key());
auto translator_vk = std::make_shared<TranslatorVerificationKey>(goblin.get_translator_proving_key());
return verify(proof, honk_vk, eccvm_vk, translator_vk);
return verify(proof, { honk_vk, eccvm_vk, translator_vk });
}

/**
Expand Down Expand Up @@ -379,12 +378,12 @@ bool ClientIVC::prove_and_verify()
* (albeit innefficient) way of separating out the cost of computing VKs from a benchmark.
*
* @param circuits A copy of the circuits to be accumulated (passing by reference would alter the original circuits)
* @return std::vector<std::shared_ptr<ClientIVC::VerificationKey>>
* @return std::vector<std::shared_ptr<MegaFlavor::VerificationKey>>
*/
std::vector<std::shared_ptr<ClientIVC::VerificationKey>> ClientIVC::precompute_folding_verification_keys(
std::vector<std::shared_ptr<MegaFlavor::VerificationKey>> ClientIVC::precompute_folding_verification_keys(
std::vector<ClientCircuit> circuits)
{
std::vector<std::shared_ptr<VerificationKey>> vkeys;
std::vector<std::shared_ptr<MegaVerificationKey>> vkeys;

for (auto& circuit : circuits) {
accumulate(circuit);
Expand Down
24 changes: 15 additions & 9 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ClientIVC {

public:
using Flavor = MegaFlavor;
using VerificationKey = Flavor::VerificationKey;
using MegaVerificationKey = Flavor::VerificationKey;
using FF = Flavor::FF;
using FoldProof = std::vector<FF>;
using MergeProof = std::vector<FF>;
Expand Down Expand Up @@ -73,12 +73,20 @@ class ClientIVC {
MSGPACK_FIELDS(mega_proof, goblin_proof);
};

struct VerificationKey {
std::shared_ptr<MegaVerificationKey> mega;
std::shared_ptr<ECCVMVerificationKey> eccvm;
std::shared_ptr<TranslatorVerificationKey> translator;

MSGPACK_FIELDS(mega, eccvm, translator);
};

enum class QUEUE_TYPE { OINK, PG }; // for specifying type of proof in the verification queue

// An entry in the native verification queue
struct VerifierInputs {
std::vector<FF> proof; // oink or PG
std::shared_ptr<VerificationKey> honk_verification_key;
std::shared_ptr<MegaVerificationKey> honk_verification_key;
QUEUE_TYPE type;
};
using VerificationQueue = std::vector<VerifierInputs>;
Expand All @@ -89,6 +97,7 @@ class ClientIVC {
std::shared_ptr<RecursiveVerificationKey> honk_verification_key;
QUEUE_TYPE type;
};

using StdlibVerificationQueue = std::vector<StdlibVerifierInputs>;

// Utility for tracking the max size of each block across the full IVC
Expand All @@ -101,7 +110,7 @@ class ClientIVC {
ProverFoldOutput fold_output; // prover accumulator and fold proof

std::shared_ptr<DeciderVerificationKey> verifier_accumulator; // verifier accumulator
std::shared_ptr<VerificationKey> honk_vk; // honk vk to be completed and folded into the accumulator
std::shared_ptr<MegaVerificationKey> honk_vk; // honk vk to be completed and folded into the accumulator

// Set of tuples {proof, verification_key, type} to be recursively verified
VerificationQueue verification_queue;
Expand Down Expand Up @@ -158,25 +167,22 @@ class ClientIVC {
* @param mock_vk A boolean to say whether the precomputed vk shoudl have its metadata set.
*/
void accumulate(ClientCircuit& circuit,
const std::shared_ptr<VerificationKey>& precomputed_vk = nullptr,
const std::shared_ptr<MegaVerificationKey>& precomputed_vk = nullptr,
bool mock_vk = false);

Proof prove();

HonkProof construct_and_prove_hiding_circuit();

static bool verify(const Proof& proof,
const std::shared_ptr<VerificationKey>& mega_vk,
const std::shared_ptr<ClientIVC::ECCVMVerificationKey>& eccvm_vk,
const std::shared_ptr<ClientIVC::TranslatorVerificationKey>& translator_vk);
static bool verify(const Proof& proof, const VerificationKey& vk);

bool verify(const Proof& proof);

bool prove_and_verify();

HonkProof decider_prove() const;

std::vector<std::shared_ptr<VerificationKey>> precompute_folding_verification_keys(
std::vector<std::shared_ptr<MegaVerificationKey>> precompute_folding_verification_keys(
std::vector<ClientCircuit> circuits);
};
} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ ClientIVC::VerifierInputs create_dummy_vkey_and_proof_oink(const TraceSettings&
const size_t num_public_inputs = 0)
{
using Flavor = MegaFlavor;
using VerificationKey = ClientIVC::VerificationKey;
using FF = bb::fr;

MegaExecutionTraceBlocks blocks;
Expand Down Expand Up @@ -89,7 +88,7 @@ ClientIVC::VerifierInputs create_dummy_vkey_and_proof_oink(const TraceSettings&
}

// Set relevant VK metadata and commitments
verifier_inputs.honk_verification_key = std::make_shared<VerificationKey>();
verifier_inputs.honk_verification_key = std::make_shared<Flavor::VerificationKey>();
verifier_inputs.honk_verification_key->circuit_size = structured_dyadic_size;
verifier_inputs.honk_verification_key->num_public_inputs = total_num_public_inputs;
verifier_inputs.honk_verification_key->pub_inputs_offset = blocks.pub_inputs.trace_offset; // must be set correctly
Expand Down Expand Up @@ -146,7 +145,7 @@ ClientIVC::MergeProof create_dummy_merge_proof()
* @param key_witness_indices
*/
void populate_dummy_vk_in_constraint(MegaCircuitBuilder& builder,
const std::shared_ptr<ClientIVC::VerificationKey>& mock_verification_key,
const std::shared_ptr<MegaFlavor::VerificationKey>& mock_verification_key,
std::vector<uint32_t>& key_witness_indices)
{
using Flavor = MegaFlavor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ ClientIVC::VerifierInputs create_dummy_vkey_and_proof_oink(const TraceSettings&
ClientIVC::MergeProof create_dummy_merge_proof();

void populate_dummy_vk_in_constraint(MegaCircuitBuilder& builder,
const std::shared_ptr<ClientIVC::VerificationKey>& mock_verification_key,
const std::shared_ptr<MegaFlavor::VerificationKey>& mock_verification_key,
std::vector<uint32_t>& key_witness_indices);

} // namespace acir_format
Loading

0 comments on commit 15f2bed

Please sign in to comment.