Skip to content

Commit

Permalink
feat: UltraRollupRecursiveFlavor (#10088)
Browse files Browse the repository at this point in the history
Creates new recursive flavor. The recursive verifier with this flavor
will extract the IPA claim from the public inputs and return it as part
of its output. Modifies the ClientTubeBase test to use this new flavor.
  • Loading branch information
lucasxia01 authored Nov 25, 2024
1 parent 3a425e9 commit 4418ef2
Show file tree
Hide file tree
Showing 19 changed files with 283 additions and 61 deletions.
2 changes: 1 addition & 1 deletion barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1148,7 +1148,7 @@ template <IsUltraFlavor Flavor> bool verify_honk(const std::string& proof_path,
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1154): Remove this and pass in the IPA proof to the
// verifier.
std::shared_ptr<VerifierCommitmentKey<curve::Grumpkin>> ipa_verification_key = nullptr;
if constexpr (HasIPAAccumulatorFlavor<Flavor>) {
if constexpr (HasIPAAccumulator<Flavor>) {
init_grumpkin_crs(1 << 16);
vk->contains_ipa_claim = false;
ipa_verification_key = std::make_shared<VerifierCommitmentKey<curve::Grumpkin>>(1 << CONST_ECCVM_LOG_N);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
#include "barretenberg/stdlib/primitives/bigfield/constants.hpp"
#include "barretenberg/stdlib/primitives/curves/bn254.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp"
#include "proof_surgeon.hpp"
#include "recursion_constraint.hpp"

namespace acir_format {

using namespace bb;
using namespace bb::stdlib::recursion::honk;
using field_ct = stdlib::field_t<Builder>;
using bn254 = stdlib::bn254<Builder>;
using aggregation_state_ct = bb::stdlib::recursion::aggregation_state<bn254>;
Expand Down Expand Up @@ -208,11 +210,11 @@ PairingPointAccumulatorIndices create_honk_recursion_constraints(
RecursiveVerifier verifier(&builder, vkey);
aggregation_state_ct input_agg_obj = bb::stdlib::recursion::convert_witness_indices_to_agg_obj<Builder, bn254>(
builder, input_aggregation_object_indices);
aggregation_state_ct output_agg_object = verifier.verify_proof(proof_fields, input_agg_obj);
UltraRecursiveVerifierOutput<Flavor> output = verifier.verify_proof(proof_fields, input_agg_obj);
// TODO(https://github.com/AztecProtocol/barretenberg/issues/996): investigate whether assert_equal on public inputs
// is important, like what the plonk recursion constraint does.

return output_agg_object.get_witness_indices();
return output.agg_obj.get_witness_indices();
}

} // namespace acir_format
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "barretenberg/stdlib/primitives/bigfield/constants.hpp"
#include "barretenberg/stdlib/primitives/curves/bn254.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp"
#include "proof_surgeon.hpp"
#include "recursion_constraint.hpp"

Expand Down
33 changes: 18 additions & 15 deletions barretenberg/cpp/src/barretenberg/flavor/flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ class MegaZKFlavor;
class TranslatorFlavor;
class AvmFlavor;
template <typename BuilderType> class UltraRecursiveFlavor_;
template <typename BuilderType> class UltraRollupRecursiveFlavor_;
template <typename BuilderType> class MegaRecursiveFlavor_;
template <typename BuilderType> class MegaZKRecursiveFlavor_;
template <typename BuilderType> class TranslatorRecursiveFlavor_;
Expand Down Expand Up @@ -367,30 +368,31 @@ template <typename T>
concept IsMegaFlavor = IsAnyOf<T, MegaFlavor, MegaZKFlavor,
MegaRecursiveFlavor_<UltraCircuitBuilder>,
MegaRecursiveFlavor_<MegaCircuitBuilder>,
MegaRecursiveFlavor_<CircuitSimulatorBN254>,
MegaZKRecursiveFlavor_<MegaCircuitBuilder>,
MegaZKRecursiveFlavor_<UltraCircuitBuilder>>;
MegaRecursiveFlavor_<CircuitSimulatorBN254>,
MegaZKRecursiveFlavor_<MegaCircuitBuilder>,
MegaZKRecursiveFlavor_<UltraCircuitBuilder>>;

template <typename T>
concept HasDataBus = IsMegaFlavor<T>;

template <typename T>
concept HasIPAAccumulatorFlavor = IsAnyOf<T, UltraRollupFlavor>;
concept HasIPAAccumulator = IsAnyOf<T, UltraRollupFlavor, UltraRollupRecursiveFlavor_<UltraCircuitBuilder>>;

template <typename T>
concept IsRecursiveFlavor = IsAnyOf<T, UltraRecursiveFlavor_<UltraCircuitBuilder>,
UltraRecursiveFlavor_<MegaCircuitBuilder>,
UltraRecursiveFlavor_<CircuitSimulatorBN254>,
UltraRollupRecursiveFlavor_<UltraCircuitBuilder>,
MegaRecursiveFlavor_<UltraCircuitBuilder>,
MegaRecursiveFlavor_<MegaCircuitBuilder>,
MegaRecursiveFlavor_<CircuitSimulatorBN254>,
MegaZKRecursiveFlavor_<MegaCircuitBuilder>,
MegaZKRecursiveFlavor_<UltraCircuitBuilder>,
TranslatorRecursiveFlavor_<UltraCircuitBuilder>,
TranslatorRecursiveFlavor_<MegaCircuitBuilder>,
TranslatorRecursiveFlavor_<CircuitSimulatorBN254>,
ECCVMRecursiveFlavor_<UltraCircuitBuilder>,
AvmRecursiveFlavor_<UltraCircuitBuilder>>;
MegaRecursiveFlavor_<CircuitSimulatorBN254>,
MegaZKRecursiveFlavor_<MegaCircuitBuilder>,
MegaZKRecursiveFlavor_<UltraCircuitBuilder>,
TranslatorRecursiveFlavor_<UltraCircuitBuilder>,
TranslatorRecursiveFlavor_<MegaCircuitBuilder>,
TranslatorRecursiveFlavor_<CircuitSimulatorBN254>,
ECCVMRecursiveFlavor_<UltraCircuitBuilder>,
AvmRecursiveFlavor_<UltraCircuitBuilder>>;

template <typename T> concept IsECCVMRecursiveFlavor = IsAnyOf<T, ECCVMRecursiveFlavor_<UltraCircuitBuilder>>;

Expand All @@ -406,11 +408,12 @@ template <typename T> concept IsFoldingFlavor = IsAnyOf<T, UltraFlavor,
UltraRecursiveFlavor_<UltraCircuitBuilder>,
UltraRecursiveFlavor_<MegaCircuitBuilder>,
UltraRecursiveFlavor_<CircuitSimulatorBN254>,
UltraRollupRecursiveFlavor_<UltraCircuitBuilder>,
MegaRecursiveFlavor_<UltraCircuitBuilder>,
MegaRecursiveFlavor_<MegaCircuitBuilder>,
MegaRecursiveFlavor_<CircuitSimulatorBN254>,
MegaZKRecursiveFlavor_<MegaCircuitBuilder>,
MegaZKRecursiveFlavor_<UltraCircuitBuilder>>;
MegaRecursiveFlavor_<CircuitSimulatorBN254>,
MegaZKRecursiveFlavor_<MegaCircuitBuilder>,
MegaZKRecursiveFlavor_<UltraCircuitBuilder>>;
template <typename T>
concept FlavorHasZK = T::HasZK;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ class ClientIVCRecursiveVerifier {
using RecursiveDeciderVerificationKeys = RecursiveDeciderVerificationKeys_<RecursiveFlavor, 2>;
using RecursiveDeciderVerificationKey = RecursiveDeciderVerificationKeys::DeciderVK;
using RecursiveVerificationKey = RecursiveDeciderVerificationKeys::VerificationKey;
using DeciderVerifier = DeciderRecursiveVerifier_<RecursiveFlavor>;
using FoldingVerifier = ProtogalaxyRecursiveVerifier_<RecursiveDeciderVerificationKeys>;
using MegaVerifier = UltraRecursiveVerifier_<RecursiveFlavor>;
using GoblinVerifier = GoblinRecursiveVerifier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class ClientIVCRecursionTests : public testing::Test {
using ECCVMVK = GoblinVerifier::ECCVMVerificationKey;
using TranslatorVK = GoblinVerifier::TranslatorVerificationKey;
using Proof = ClientIVC::Proof;
using Flavor = UltraRecursiveFlavor_<Builder>;
using NativeFlavor = UltraRollupFlavor;
using Flavor = UltraRollupRecursiveFlavor_<Builder>;
using NativeFlavor = Flavor::NativeFlavor;
using UltraRecursiveVerifier = UltraRecursiveVerifier_<Flavor>;

static void SetUpTestSuite()
Expand Down Expand Up @@ -125,7 +125,7 @@ TEST_F(ClientIVCRecursionTests, ClientTubeBase)
// EXPECT_TRUE(CircuitChecker::check(*tube_builder));

// Construct and verify a proof for the ClientIVC Recursive Verifier circuit
auto proving_key = std::make_shared<DeciderProvingKey_<UltraRollupFlavor>>(*tube_builder);
auto proving_key = std::make_shared<DeciderProvingKey_<NativeFlavor>>(*tube_builder);
UltraProver_<NativeFlavor> tube_prover{ proving_key };
auto native_tube_proof = tube_prover.construct_proof();

Expand All @@ -135,18 +135,26 @@ TEST_F(ClientIVCRecursionTests, ClientTubeBase)
UltraVerifier_<NativeFlavor> native_verifier(native_vk_with_ipa, ipa_verification_key);
EXPECT_TRUE(native_verifier.verify_proof(native_tube_proof, tube_prover.proving_key->proving_key.ipa_proof));

// Construct a base rollup circuit that recursively verifies the tube proof.
// Construct a base rollup circuit that recursively verifies the tube proof and forwards the IPA proof.
Builder base_builder;
auto native_vk = std::make_shared<UltraFlavor::VerificationKey>(proving_key->proving_key);
auto native_vk = std::make_shared<NativeFlavor::VerificationKey>(proving_key->proving_key);
auto vk = std::make_shared<Flavor::VerificationKey>(&base_builder, native_vk);
auto tube_proof = bb::convert_native_proof_to_stdlib(&base_builder, native_tube_proof);
UltraRecursiveVerifier base_verifier{ &base_builder, vk };
base_verifier.verify_proof(tube_proof,
stdlib::recursion::init_default_aggregation_state<Builder, Flavor::Curve>(base_builder));
UltraRecursiveVerifierOutput<Flavor> output = base_verifier.verify_proof(
tube_proof, stdlib::recursion::init_default_aggregation_state<Builder, Flavor::Curve>(base_builder));
info("UH Recursive Verifier: num prefinalized gates = ", base_builder.num_gates);

base_builder.add_pairing_point_accumulator(output.agg_obj.get_witness_indices());
base_builder.add_ipa_claim(output.ipa_opening_claim.get_witness_indices());
base_builder.ipa_proof = tube_prover.proving_key->proving_key.ipa_proof;
EXPECT_EQ(base_builder.failed(), false) << base_builder.err();
EXPECT_TRUE(CircuitChecker::check(base_builder));

// Natively verify the IPA proof for the base rollup circuit
auto base_proving_key = std::make_shared<DeciderProvingKey_<NativeFlavor>>(base_builder);
auto ipa_transcript = std::make_shared<NativeTranscript>(base_proving_key->proving_key.ipa_proof);
IPA<curve::Grumpkin>::reduce_verify(
ipa_verification_key, output.ipa_opening_claim.get_native_opening_claim(), ipa_transcript);
}

} // namespace bb::stdlib::recursion::honk
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "barretenberg/stdlib/transcript/transcript.hpp"
#include "barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp"
#include "barretenberg/sumcheck/sumcheck.hpp"

namespace bb::stdlib::recursion::honk {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/mega_zk_recursive_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp"
#include <utility>

namespace bb::stdlib::recursion::honk {
Expand Down Expand Up @@ -136,4 +137,5 @@ template class OinkRecursiveVerifier_<bb::MegaZKRecursiveFlavor_<MegaCircuitBuil
template class OinkRecursiveVerifier_<bb::MegaZKRecursiveFlavor_<UltraCircuitBuilder>>;
template class OinkRecursiveVerifier_<bb::UltraRecursiveFlavor_<CircuitSimulatorBN254>>;
template class OinkRecursiveVerifier_<bb::MegaRecursiveFlavor_<CircuitSimulatorBN254>>;
template class OinkRecursiveVerifier_<bb::UltraRollupRecursiveFlavor_<UltraCircuitBuilder>>;
} // namespace bb::stdlib::recursion::honk
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ UltraRecursiveVerifier_<Flavor>::UltraRecursiveVerifier_(Builder* builder, const
* @return Output aggregation object
*/
template <typename Flavor>
UltraRecursiveVerifier_<Flavor>::AggregationObject UltraRecursiveVerifier_<Flavor>::verify_proof(
const HonkProof& proof, AggregationObject agg_obj)
UltraRecursiveVerifier_<Flavor>::Output UltraRecursiveVerifier_<Flavor>::verify_proof(const HonkProof& proof,
AggregationObject agg_obj)
{
StdlibProof<Builder> stdlib_proof = bb::convert_native_proof_to_stdlib(builder, proof);
return verify_proof(stdlib_proof, agg_obj);
Expand All @@ -36,8 +36,8 @@ UltraRecursiveVerifier_<Flavor>::AggregationObject UltraRecursiveVerifier_<Flavo
* @return Output aggregation object
*/
template <typename Flavor>
UltraRecursiveVerifier_<Flavor>::AggregationObject UltraRecursiveVerifier_<Flavor>::verify_proof(
const StdlibProof<Builder>& proof, AggregationObject agg_obj)
UltraRecursiveVerifier_<Flavor>::Output UltraRecursiveVerifier_<Flavor>::verify_proof(const StdlibProof<Builder>& proof,
AggregationObject agg_obj)
{
using Sumcheck = ::bb::SumcheckVerifier<Flavor>;
using PCS = typename Flavor::PCS;
Expand Down Expand Up @@ -127,7 +127,39 @@ UltraRecursiveVerifier_<Flavor>::AggregationObject UltraRecursiveVerifier_<Flavo
pairing_points[1] = pairing_points[1].normalize();
// TODO(https://github.com/AztecProtocol/barretenberg/issues/995): generate recursion separator challenge properly.
agg_obj.aggregate(pairing_points, recursion_separator);
return agg_obj;
Output output;
output.agg_obj = std::move(agg_obj);

// Extract the IPA claim from the public inputs
// Parse out the nested IPA claim using key->ipa_claim_public_input_indices and runs the native IPA verifier.
if constexpr (HasIPAAccumulator<Flavor>) {
const auto recover_fq_from_public_inputs = [](std::array<FF, 4>& limbs) {
for (size_t k = 0; k < Curve::BaseField::NUM_LIMBS; k++) {
limbs[k].create_range_constraint(Curve::BaseField::NUM_LIMB_BITS, "limb_" + std::to_string(k));
}
return Curve::BaseField::unsafe_construct_from_limbs(limbs[0], limbs[1], limbs[2], limbs[3], false);
};

if (verification_key->verification_key->contains_ipa_claim) {
OpeningClaim<grumpkin<Builder>> ipa_claim;
std::array<FF, 4> bigfield_limbs;
for (size_t k = 0; k < 4; k++) {
bigfield_limbs[k] =
verification_key
->public_inputs[verification_key->verification_key->ipa_claim_public_input_indices[k]];
}
ipa_claim.opening_pair.challenge = recover_fq_from_public_inputs(bigfield_limbs);
ipa_claim.opening_pair.evaluation = 0;
ipa_claim.commitment = {
verification_key->public_inputs[verification_key->verification_key->ipa_claim_public_input_indices[4]],
verification_key->public_inputs[verification_key->verification_key->ipa_claim_public_input_indices[5]],
false // WORKTODO: make this a witness?
};
output.ipa_opening_claim = std::move(ipa_claim);
}
}

return output;
}

template class UltraRecursiveVerifier_<bb::UltraRecursiveFlavor_<UltraCircuitBuilder>>;
Expand All @@ -138,4 +170,5 @@ template class UltraRecursiveVerifier_<bb::MegaZKRecursiveFlavor_<MegaCircuitBui
template class UltraRecursiveVerifier_<bb::MegaZKRecursiveFlavor_<UltraCircuitBuilder>>;
template class UltraRecursiveVerifier_<bb::UltraRecursiveFlavor_<CircuitSimulatorBN254>>;
template class UltraRecursiveVerifier_<bb::MegaRecursiveFlavor_<CircuitSimulatorBN254>>;
template class UltraRecursiveVerifier_<bb::UltraRollupRecursiveFlavor_<UltraCircuitBuilder>>;
} // namespace bb::stdlib::recursion::honk
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,17 @@
#include "barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/mega_zk_recursive_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp"
#include "barretenberg/sumcheck/sumcheck.hpp"

namespace bb::stdlib::recursion::honk {

template <typename Flavor> struct UltraRecursiveVerifierOutput {
using AggregationObject = aggregation_state<typename Flavor::Curve>;
using Builder = typename Flavor::CircuitBuilder;
AggregationObject agg_obj;
OpeningClaim<grumpkin<Builder>> ipa_opening_claim;
};
template <typename Flavor> class UltraRecursiveVerifier_ {
public:
using FF = typename Flavor::FF;
Expand All @@ -23,13 +31,14 @@ template <typename Flavor> class UltraRecursiveVerifier_ {
using AggregationObject = aggregation_state<typename Flavor::Curve>;
using Transcript = bb::BaseTranscript<bb::stdlib::recursion::honk::StdlibTranscriptParams<Builder>>;
using OinkVerifier = OinkRecursiveVerifier_<Flavor>;
using Output = UltraRecursiveVerifierOutput<Flavor>;

explicit UltraRecursiveVerifier_(Builder* builder,
const std::shared_ptr<NativeVerificationKey>& native_verifier_key);
explicit UltraRecursiveVerifier_(Builder* builder, const std::shared_ptr<VerificationKey>& vkey);

AggregationObject verify_proof(const HonkProof& proof, AggregationObject agg_obj);
AggregationObject verify_proof(const StdlibProof<Builder>& proof, AggregationObject agg_obj);
Output verify_proof(const HonkProof& proof, AggregationObject agg_obj);
Output verify_proof(const StdlibProof<Builder>& proof, AggregationObject agg_obj);

std::shared_ptr<VerificationKey> key;
std::shared_ptr<VerifierCommitmentKey> pcs_verification_key;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,9 @@ template <typename RecursiveFlavor> class RecursiveVerifierTest : public testing

aggregation_state<typename RecursiveFlavor::Curve> agg_obj =
init_default_aggregation_state<OuterBuilder, typename RecursiveFlavor::Curve>(outer_circuit);
auto pairing_points = verifier.verify_proof(inner_proof, agg_obj);
bb::stdlib::recursion::honk::UltraRecursiveVerifierOutput<RecursiveFlavor> output =
verifier.verify_proof(inner_proof, agg_obj);
aggregation_state<typename RecursiveFlavor::Curve> pairing_points = output.agg_obj;
info("Recursive Verifier: num gates = ", outer_circuit.get_estimated_num_finalized_gates());

// Check for a failure flag in the recursive verifier circuit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1606,6 +1606,6 @@ template <typename Builder> cycle_group<Builder> cycle_group<Builder>::operator/
template class cycle_group<bb::StandardCircuitBuilder>;
template class cycle_group<bb::UltraCircuitBuilder>;
template class cycle_group<bb::MegaCircuitBuilder>;
template struct cycle_group<bb::CircuitSimulatorBN254>::cycle_scalar;
template class cycle_group<bb::CircuitSimulatorBN254>;

} // namespace bb::stdlib
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "barretenberg/polynomials/univariate.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp"
#include "barretenberg/transcript/transcript.hpp"
#include "barretenberg/ultra_honk/decider_proving_key.hpp"
#include "barretenberg/ultra_honk/ultra_prover.hpp"
Expand Down
Loading

0 comments on commit 4418ef2

Please sign in to comment.