-
Notifications
You must be signed in to change notification settings - Fork 266
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: protogalaxy interfaces #2125
Conversation
461a24e
to
8e480cb
Compare
// The responsability of a Prover is to commit, add to transcript while the Instance manages its polynomials | ||
template <UltraFlavor Flavor> class Instance_ { | ||
public: | ||
using Circuit = typename Flavor::CircuitBuilder; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at this stage in the code, we're not building a circuit anymore so Circuit
is a more fitting name, I have also done some renaming so CircuitBuilder
variables are now called builder
rather than circuit_constructor
when we're actually building circuits
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to me + reads nicely.
// The responsability of a Prover is to commit, add to transcript while the Instance manages its polynomials | ||
// TODO: we might wanna have a specialisaition of the Instance class for the Accumulator | ||
template <UltraFlavor Flavor> class Instance_ { | ||
public: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an initial design I think we can use a single Instance
structure to refer to both normal instances (whose folding parameters will be 0 and which will be created from circuits) and accumulated instances (which will be created from a FoldingResult
i.e. the accumulated result from the work of PG prover and PG verifier) but we can revisit this as we're building the full PG prover and verifier.
using ProverPolynomials = typename Flavor::ProverPolynomials; | ||
using FoldingParameters = typename Flavor::FoldingParameters; | ||
ProverPolynomials folded_prover_polynomials; | ||
std::vector<uint8_t> folding_data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the content of the transcript and in UltraProver it's a plonk::proof
which seemed confusing to use in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I hate that, we need AztecProtocol/barretenberg#656
#include "barretenberg/proof_system/flavor/flavor.hpp" | ||
namespace proof_system::honk { | ||
template <UltraFlavor Flavor> | ||
ProtoGalaxyProver_<Flavor>::ProtoGalaxyProver_(std::vector<std::shared_ptr<Instance>> insts) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if shared_ptr is the right way to go so i'm open to feedback, but afaiu you can't have a vector of references
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, well essentially all of the data in an instance is already handled through a shared pointer, so copying an instance should be inexpensive, but then again there are these vectors it contains, and you've already implemented instance handling through shared pointers, and that seems fine for now.
8e480cb
to
398797a
Compare
|
||
// The number of public inputs has to be the same for all instances because they are | ||
// folded element by element. | ||
std::vector<FF> public_inputs; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also we can't have the case where instance A has 50 inputs and instance B has 3 inputs and from index 4 to 50 instance B has zeros because, on one hand this is wasteful and on the other hand the number of actual public inputs matter for the compute_public_input_delta function
19a2420
to
cd1f647
Compare
@@ -1,17 +0,0 @@ | |||
#pragma once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was able to remove the prover_library because only the Instance was using it. We could do the same with the grand_product_library if we sunset StandardHonk or it is updated to suport instances.
#include <vector> | ||
|
||
using namespace proof_system::honk; | ||
namespace prover_library_tests { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some tests here were testing the grand_product_library which I have moved in the grand_product_library.test.cpp.
b6764d9
to
cf4435f
Compare
442492b
to
7e3bf57
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this very solid work. I have some follow-on requests (many fairly trivial, a few more involved) that I think will make it even stronger and more robust.
@@ -224,11 +224,21 @@ void construct_proof_with_specified_num_iterations(State& state, | |||
test_circuit_function(builder, num_iterations); | |||
|
|||
auto composer = Composer(); | |||
auto ext_prover = composer.create_prover(builder); | |||
state.ResumeTiming(); | |||
if constexpr (Composer::NAME_STRING == "UltraHonk") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the type system for this (one of the Is
concepts) and not the name string. I think the name string can go away from the Instance
definition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to get rid of the NAME_STRING
altogether but it was needed for something. But in the past using identifiers lead to really confusing code.
auto proof = ext_prover.construct_proof(); | ||
|
||
} else { | ||
auto ext_prover = composer.create_prover(builder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much more work would it be to implement for StandardHonk
? I know we talked about this and I suggested doing Ultra only, but now that I see it leads a major divergence in structure and also in interace, I'm in favor of bringing Standard along for the ride. Should be routine now that you've done the same for Ultra, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
erm, couple of hours max, will do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but the divergence around here is between honk and plonk now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not ideal, but we have accepted divergence with Plonk if it means improving Honk.
barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp
Show resolved
Hide resolved
// The responsability of a Prover is to commit, add to transcript while the Instance manages its polynomials | ||
template <UltraFlavor Flavor> class Instance_ { | ||
public: | ||
using Circuit = typename Flavor::CircuitBuilder; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to me + reads nicely.
using ProverPolynomials = typename Flavor::ProverPolynomials; | ||
using FoldingParameters = typename Flavor::FoldingParameters; | ||
ProverPolynomials folded_prover_polynomials; | ||
std::vector<uint8_t> folding_data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I hate that, we need AztecProtocol/barretenberg#656
#include "barretenberg/proof_system/flavor/flavor.hpp" | ||
namespace proof_system::honk { | ||
template <UltraFlavor Flavor> | ||
ProtoGalaxyProver_<Flavor>::ProtoGalaxyProver_(std::vector<std::shared_ptr<Instance>> insts) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, well essentially all of the data in an instance is already handled through a shared pointer, so copying an instance should be inexpensive, but then again there are these vectors it contains, and you've already implemented instance handling through shared pointers, and that seems fine for now.
|
||
FoldingParameters folding_params; | ||
// Used by the prover for domain separation in the transcript | ||
uint32_t index; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This index
usage feels kinda bad and brittle. When you create the vector of shared pointers to instances, why can't we just use the index of the pointer in that vector?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've mocked out related things in my combiner work, and I ended up defining an Instances
object that wraps multiple instances. What do you think about implementing that and having that class manage the domain separation?
aztec-packages/circuits/cpp/barretenberg/cpp/src/barretenberg/protogalaxy/combiner.hpp
Line 11 in e74d800
template <typename Flavor, size_t NUM_> struct Instances { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about having a lightweight Instances
class that encapsulates NUM_
-many Instance
objects. I've tentatively added a TODO (+issue: AztecProtocol/barretenberg#725) to smoothen things out?
@@ -62,24 +54,23 @@ template <UltraFlavor Flavor> class UltraComposer_ { | |||
UltraComposer_& operator=(UltraComposer_ const& other) noexcept = default; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've noticed in the files i've added that explicit constructors are not needed. I only added them because they were also present here but it seems that they are not needed here either (by "seems" I mean code compiles and tests pass if I remove them). Can they be removed here as well?
auto ext_prover = composer.create_prover(builder); | ||
state.ResumeTiming(); | ||
if constexpr (Composer::NAME_STRING == "UltraHonk") { | ||
auto instance = composer.create_instance(builder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ideally, I think the benchmarks should be templated by Flavor
a830dae
to
7406e65
Compare
🤖 I have created a release *beep* *boop* --- <details><summary>aztec-packages: 0.7.5</summary> ## [0.7.5](aztec-packages-v0.7.4...aztec-packages-v0.7.5) (2023-09-15) ### Features * Protogalaxy interfaces ([#2125](#2125)) ([b45dd26](b45dd26)) * Renamed `nargoVersion` as `compatibleNargoVersion` ([#2338](#2338)) ([6f9e0f1](6f9e0f1)) ### Bug Fixes * Add retry around docker login and revive spot_run_test_script ([#2346](#2346)) ([79e5f05](79e5f05)) * Unbox command. ([#2337](#2337)) ([e9bc9c6](e9bc9c6)) ### Miscellaneous * Increase guides-dapp-testing test timeout ([#2343](#2343)) ([1cebe2c](1cebe2c)) * Use retries by default on rpc client fetch ([#2342](#2342)) ([f4ffd68](f4ffd68)) </details> <details><summary>barretenberg.js: 0.7.5</summary> ## [0.7.5](barretenberg.js-v0.7.4...barretenberg.js-v0.7.5) (2023-09-15) ### Miscellaneous * **barretenberg.js:** Synchronize aztec-packages versions </details> <details><summary>barretenberg: 0.7.5</summary> ## [0.7.5](barretenberg-v0.7.4...barretenberg-v0.7.5) (2023-09-15) ### Features * Protogalaxy interfaces ([#2125](#2125)) ([b45dd26](b45dd26)) </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
This PR introduces the concept of an
Instance
and slightly reworks the components of Honk as follows:Instance
contains and is responsible for creating all the polynomials resulting from a circuit and required to generate a proof (the functionality that performs these operations has been hence moved from the Composer and Prover to the Instance). This abstraction is necessary for implementing ProtoGalaxy since we are going to fold polynomials. Moreover, it makes certain tests in Honk more lightweight as we no longer have to create a full Prover to produce polynomials from a finalised circuit.Composer
now creates anInstance
from a finalised circuit and creates a Prover and Verifier from an Instance (or several Instances in the case of ProtoGalaxy).The
Instance
abstraction is currently only supported by UltraHonk.Then, I introduced shells for the
ProtoGalaxyProver
andProtoGalaxyVerifier
and data structures involved in folding.Resolves #684 and partially resolves #681 (might also need to provide some shell in the circuits library to fully resolve this one).
Checklist:
Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge.