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: UltraRollupRecursiveFlavor #10088

Merged
merged 10 commits into from
Nov 25, 2024
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 Expand Up @@ -208,11 +209,12 @@ 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);
bb::stdlib::recursion::honk::UltraRecursiveVerifierOutput<Flavor> output =
lucasxia01 marked this conversation as resolved.
Show resolved Hide resolved
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 HasIPAAccumulatorFlavor = IsAnyOf<T, UltraRollupFlavor, UltraRollupRecursiveFlavor_<UltraCircuitBuilder>>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: concept name is ungrammatical; if constexpr HasIPAAccumulator<Flavor> vs if constexpr HasIPAAccumulatorFlavor<Flavor>

Copy link
Contributor Author

@lucasxia01 lucasxia01 Nov 25, 2024

Choose a reason for hiding this comment

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

yeah fair. Was following the style of some of the other flavor names which have Flavor in them, but I can remove this one


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 (HasIPAAccumulatorFlavor<Flavor>) {
const auto recover_fq_from_public_inputs = [](std::array<FF, 4>& limbs) {
for (size_t k = 0; k < 4; k++) {
lucasxia01 marked this conversation as resolved.
Show resolved Hide resolved
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?
Copy link
Contributor Author

Choose a reason for hiding this comment

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

maybe this can stay as a constant?

};
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
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,23 @@ class CircuitSimulatorBN254 {

[[nodiscard]] bool check_circuit() const { return !_failed; }

size_t create_ROM_array([[maybe_unused]] const size_t array_size) { return {}; }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

had to add these since cycle group takes in CircuitSimulator now, because its being used in the ultra RecursiveVerifier


void set_ROM_element_pair([[maybe_unused]] const size_t rom_id,
[[maybe_unused]] const size_t index_value,
[[maybe_unused]] const std::array<uint32_t, 2>& value_witnesses)
{}
uint32_t read_ROM_array([[maybe_unused]] const size_t rom_id, [[maybe_unused]] const uint32_t index_witness)
{
return {};
}
std::array<uint32_t, 2> read_ROM_array_pair([[maybe_unused]] const size_t rom_id,
[[maybe_unused]] const uint32_t index_witness)
{
return {};
}
void create_ecc_dbl_gate([[maybe_unused]] const ecc_dbl_gate_<FF>& in){};

// Public input indices which contain recursive proof information
PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices;
};
Expand Down
Loading