-
Notifications
You must be signed in to change notification settings - Fork 6
Add RecursiveCircuit #204
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
base: main
Are you sure you want to change the base?
Add RecursiveCircuit #204
Conversation
8b8501b
to
19af95f
Compare
The RecursiveCircuit verifies N proofs of itself (N=arity), together with the logic defined at the InnerCircuit (in our case, used for the MainPodCircuit logic). The arity defines the maximum amount of proofs of itself that the RecursiveCircuit verifies. When arity>1, using the RecursiveCircuit has the shape of a tree of the same arity. π_root ▲ ┌───────┴────────┐ │RecursiveCircuit│ └─▲───▲───▲────▲─┘ ┌───────┘ ┌┘ └┐ └──────┐ │π''_1 │ ... │ π''_N│ ┌────────┴───────┐ ┌┴┐┌─┐┌┴┐ ┌───────┴────────┐ │RecursiveCircuit│ │.││.││.│ │RecursiveCircuit│ └──▲─────────▲───┘ └─┘└─┘└─┘ └──▲─────────▲───┘ │ │ │ │ π_1 ... π_N π'_1 ... π'_N where N: arity of the RecursiveCircuit π_i: plonky2 proof of the RecursiveCircuit
bd6efce
to
62a9f88
Compare
(rebased to latest |
62a9f88
to
cfcfbaf
Compare
…ata; polish recursion interfaces
cfcfbaf
to
c14382e
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.
I've done an initial review. I haven't reviewed the tests properly yet.
// used in the InnerCircuit | ||
let pub_inp: Vec<Target> = proofs_targ | ||
.iter() | ||
.flat_map(|proof_pis| proof_pis.public_inputs.clone()) |
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.
These public inputs are built like this:
[inner_circuit_public, circuit_digest, constants_sigmas_cap].
We should do two things here:
- If the
selectors_targ=true
, thencircuit_digest, constants_sigmas_cap
from the proof should be equal to the values inverifier_data_targ
. Or maybe we skip the conditional part and just connect, beacuse the dummy proof may use the same verifier data? - Extract the
inner_circuit_public
and that's collected and passed toI::build
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.
1. If the `selectors_targ=true`, then `circuit_digest, constants_sigmas_cap` from the proof should be equal to the values in `verifier_data_targ`. Or maybe we skip the conditional part and just connect, beacuse the dummy proof may use the same verifier data?
I learned that this is already being done through the combination of
builder.add_verifier_data_public_inputs()
and
builder.conditionally_verify_cyclic_proof_or_dummy()
public_inputs: Vec<Target>, | ||
selectors: Vec<BoolTarget>, | ||
) -> Result<Self>; | ||
|
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 think we need a new method to return the public inputs so that we can pass them from InnerCircuit
to RecursiveCircuit
.
For example something like this:
pub trait InnerCircuit: Clone {
type InputTarget: Flattenable;
fn public_inputs(&self) -> Self::InputTarget;
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.
yes, I've opened the issue #208 to tackle this
.collect(), | ||
] | ||
.concat() | ||
} |
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 think we should add a verify function, because the verification of this proof is not just calling the plonky2 method, but we also need to check that the expected verifier_data is in the 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.
Agree, but probably this verify function will include also the logic to check the validity of the verifier_data, right? I would propose to map it into a separate issue for the entire task (which includes implementing one of the approaches that you described in the hackmd of the 'recursion family framework').
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.
The verifier_data
must be equal to the one calculated via:
let circuit_data = RecursiveCircuit::<I>::circuit_data(¶ms, &inner_params)?;
let verifier_data = circuit_data.verifier_data();
That's the case if we consider a circuit that verifies itself. If the verifier data in the public inputs is not the verifier data of the outer circuit then it's not a circuit that verifies itself.
The RecursiveCircuit verifies N proofs of itself (N=arity), together with the logic defined at the InnerCircuit (in our case, used for the MainPodCircuit logic).
The arity defines the maximum amount of proofs of itself that the RecursiveCircuit verifies. When arity>1, using the RecursiveCircuit has the shape of a tree of the same arity.
In the direction of #174 .