-
Notifications
You must be signed in to change notification settings - Fork 234
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Goblin Recursive Verifier (#6778)
Implements a Goblin Recursive Verifier without the Merge. Removes hack in Translator Recursive Verifier and ensures we are able to pass the Transcript from ECCVM to Translator Recursive Verifier. --------- Co-authored-by: ledwards2225 <l.edwards.d@gmail.com>
- Loading branch information
1 parent
a98d30b
commit 53d0d55
Showing
11 changed files
with
232 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
...tenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/goblin_recursive_verifier.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#include "barretenberg/stdlib/honk_recursion/verifier/goblin_recursive_verifier.hpp" | ||
|
||
namespace bb::stdlib::recursion::honk { | ||
|
||
void GoblinRecursiveVerifier::verify(GoblinProof& proof) | ||
{ | ||
// Run the ECCVM recursive verifier | ||
ECCVMVerifier eccvm_verifier{ builder, verification_keys.eccvm_verification_key }; | ||
eccvm_verifier.verify_proof(proof.eccvm_proof); | ||
|
||
// Run the Translator recursive verifier | ||
TranslatorVerifier translator_verifier{ builder, | ||
verification_keys.translator_verification_key, | ||
eccvm_verifier.transcript }; | ||
translator_verifier.verify_proof(proof.translator_proof); | ||
|
||
// Verify the consistency between the ECCVM and Translator transcript polynomial evaluations | ||
// In reality the Goblin Proof is going to already be a stdlib proof and this conversion is not going to happen here | ||
// (see https://github.com/AztecProtocol/barretenberg/issues/991) | ||
auto native_translation_evaluations = proof.translation_evaluations; | ||
auto translation_evaluations = | ||
TranslationEvaluations{ TranslatorBF::from_witness(builder, native_translation_evaluations.op), | ||
TranslatorBF::from_witness(builder, native_translation_evaluations.Px), | ||
TranslatorBF::from_witness(builder, native_translation_evaluations.Py), | ||
TranslatorBF::from_witness(builder, native_translation_evaluations.z1), | ||
TranslatorBF::from_witness(builder, native_translation_evaluations.z2) | ||
|
||
}; | ||
translator_verifier.verify_translation(translation_evaluations); | ||
|
||
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1024): Perform recursive merge verification once it | ||
// works with Ultra arithmetization | ||
// MergeVerifier merge_verified{ builder }; | ||
// [[maybe_unused]] auto merge_pairing_points = merge_verifier.verify_proof(proof.merge_proof); | ||
} | ||
} // namespace bb::stdlib::recursion::honk |
45 changes: 45 additions & 0 deletions
45
...tenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/goblin_recursive_verifier.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#pragma once | ||
#include "barretenberg/eccvm_recursion/eccvm_recursive_verifier.hpp" | ||
#include "barretenberg/goblin/goblin.hpp" | ||
#include "barretenberg/stdlib/honk_recursion/verifier/merge_recursive_verifier.hpp" | ||
#include "barretenberg/translator_vm_recursion/translator_recursive_verifier.hpp" | ||
|
||
namespace bb::stdlib::recursion::honk { | ||
class GoblinRecursiveVerifier { | ||
public: | ||
// Goblin Recursive Verifier circuit is using Ultra arithmetisation | ||
using Builder = UltraCircuitBuilder; | ||
using MergeVerifier = goblin::MergeRecursiveVerifier_<Builder>; | ||
|
||
using TranslatorFlavor = TranslatorRecursiveFlavor_<Builder>; | ||
using TranslatorVerifier = TranslatorRecursiveVerifier_<TranslatorFlavor>; | ||
using TranslationEvaluations = TranslatorVerifier::TranslationEvaluations; | ||
using TranslatorBF = TranslatorFlavor::BF; | ||
|
||
using ECCVMFlavor = ECCVMRecursiveFlavor_<Builder>; | ||
using ECCVMVerifier = ECCVMRecursiveVerifier_<ECCVMFlavor>; | ||
|
||
// ECCVM and Translator verification keys | ||
using VerifierInput = GoblinVerifier::VerifierInput; | ||
|
||
GoblinRecursiveVerifier(Builder* builder, VerifierInput& verification_keys) | ||
: builder(builder) | ||
, verification_keys(verification_keys){}; | ||
|
||
/** | ||
* @brief Construct a Goblin recursive verifier circuit | ||
* @details Contains three recursive verifiers: Merge, ECCVM, and Translator | ||
* @todo(https://github.com/AztecProtocol/barretenberg/issues/1021): The values returned by the recursive verifiers | ||
* are not aggregated here. We need to aggregate and return the pairing points from Merge/Translator plus deal with | ||
* the IPA accumulator from ECCVM. | ||
* | ||
* @todo(https://github.com/AztecProtocol/barretenberg/issues/991): The GoblinProof should aleady be a stdlib proof | ||
*/ | ||
void verify(GoblinProof&); | ||
|
||
private: | ||
Builder* builder; | ||
VerifierInput verification_keys; // ECCVM and Translator verification keys | ||
}; | ||
|
||
} // namespace bb::stdlib::recursion::honk |
106 changes: 106 additions & 0 deletions
106
...rg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/goblin_recursive_verifier.test.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#include "barretenberg/stdlib/honk_recursion/verifier/goblin_recursive_verifier.hpp" | ||
#include "barretenberg/circuit_checker/circuit_checker.hpp" | ||
#include "barretenberg/common/test.hpp" | ||
#include "barretenberg/goblin/goblin.hpp" | ||
#include "barretenberg/ultra_honk/ultra_prover.hpp" | ||
#include "barretenberg/ultra_honk/ultra_verifier.hpp" | ||
|
||
namespace bb::stdlib::recursion::honk { | ||
class GoblinRecursiveVerifierTests : public testing::Test { | ||
public: | ||
using Builder = GoblinRecursiveVerifier::Builder; | ||
using ECCVMVK = GoblinVerifier::ECCVMVerificationKey; | ||
using TranslatorVK = GoblinVerifier::TranslatorVerificationKey; | ||
|
||
using OuterFlavor = UltraFlavor; | ||
using OuterProver = UltraProver_<OuterFlavor>; | ||
using OuterVerifier = UltraVerifier_<OuterFlavor>; | ||
using OuterProverInstance = ProverInstance_<OuterFlavor>; | ||
|
||
static void SetUpTestSuite() | ||
{ | ||
bb::srs::init_crs_factory("../srs_db/ignition"); | ||
bb::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); | ||
} | ||
|
||
static MegaCircuitBuilder construct_mock_circuit(std::shared_ptr<ECCOpQueue> op_queue) | ||
{ | ||
MegaCircuitBuilder circuit{ op_queue }; | ||
MockCircuits::construct_arithmetic_circuit(circuit, /*target_log2_dyadic_size=*/8); | ||
MockCircuits::construct_goblin_ecc_op_circuit(circuit); | ||
return circuit; | ||
} | ||
|
||
struct ProverOutput { | ||
GoblinProof proof; | ||
GoblinVerifier::VerifierInput verfier_input; | ||
}; | ||
|
||
/** | ||
* @brief Create a goblin proof and the VM verification keys needed by the goblin recursive verifier | ||
* | ||
* @return ProverOutput | ||
*/ | ||
ProverOutput create_goblin_prover_output() | ||
{ | ||
GoblinProver goblin; | ||
|
||
// Construct and accumulate multiple circuits | ||
size_t NUM_CIRCUITS = 3; | ||
for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) { | ||
auto circuit = construct_mock_circuit(goblin.op_queue); | ||
goblin.merge(circuit); // appends a recurisve merge verifier if a merge proof exists | ||
} | ||
|
||
// Output is a goblin proof plus ECCVM/Translator verification keys | ||
return { goblin.prove(), | ||
{ std::make_shared<ECCVMVK>(goblin.get_eccvm_proving_key()), | ||
std::make_shared<TranslatorVK>(goblin.get_translator_proving_key()) } }; | ||
} | ||
}; | ||
|
||
/** | ||
* @brief Ensure the Goblin proof produced by the test method can be natively verified | ||
* | ||
*/ | ||
TEST_F(GoblinRecursiveVerifierTests, NativeVerification) | ||
{ | ||
auto [proof, verifier_input] = create_goblin_prover_output(); | ||
|
||
GoblinVerifier verifier{ verifier_input }; | ||
|
||
EXPECT_TRUE(verifier.verify(proof)); | ||
} | ||
|
||
/** | ||
* @brief Construct and check a goblin recursive verification circuit | ||
* | ||
*/ | ||
TEST_F(GoblinRecursiveVerifierTests, Basic) | ||
{ | ||
auto [proof, verifier_input] = create_goblin_prover_output(); | ||
|
||
Builder builder; | ||
GoblinRecursiveVerifier verifier{ &builder, verifier_input }; | ||
verifier.verify(proof); | ||
|
||
info("Recursive Verifier: num gates = ", builder.num_gates); | ||
|
||
EXPECT_EQ(builder.failed(), false) << builder.err(); | ||
|
||
EXPECT_TRUE(CircuitChecker::check(builder)); | ||
|
||
// Construct and verify a proof for the Goblin Recursive Verifier circuit | ||
{ | ||
auto instance = std::make_shared<OuterProverInstance>(builder); | ||
OuterProver prover(instance); | ||
auto verification_key = std::make_shared<typename OuterFlavor::VerificationKey>(instance->proving_key); | ||
OuterVerifier verifier(verification_key); | ||
auto proof = prover.construct_proof(); | ||
bool verified = verifier.verify_proof(proof); | ||
|
||
ASSERT(verified); | ||
} | ||
} | ||
|
||
} // namespace bb::stdlib::recursion::honk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters