Complete the verification in MainMockPod (#302)
- Update the `RecursivePod` trait to return `vd_set` instead of `vds_root` - A native verifier requires the entire set to reason about the circuits that have been used in the recursive tree - Implement serialization/deserialization for `VDSet` - Remove `DynError` and use `BackendError` instead for middleware functions that wrap or define trait functions implemented in the backend. This is based on the fact that we will only have a single backend enabled at a time, so there's no need for a `dyn Error` - Move the implementations of `_verify` functions to `verify` and similarly for `_prove` - Complete the verification of a MockMainPod: the verification of input pods was missing. The inclusion of these input pods in the serialization was also missing. With this change a `MockMainPod` will grow after each recursion. This was expected from the design but was not the case because of the missing recursive native verification implementation. * apply feedback from @arnaucube
This commit is contained in:
parent
df8fce76d6
commit
6249406cb2
16 changed files with 427 additions and 350 deletions
|
|
@ -20,15 +20,15 @@ use crate::{
|
|||
error::{Error, Result},
|
||||
mock::{emptypod::MockEmptyPod, signedpod::MockSignedPod},
|
||||
primitives::merkletree::MerkleClaimAndProof,
|
||||
recursion::{RecursiveCircuit, RecursiveParams},
|
||||
recursion::{hash_verifier_data, RecursiveCircuit, RecursiveParams},
|
||||
serialize_proof,
|
||||
signedpod::SignedPod,
|
||||
STANDARD_REC_MAIN_POD_CIRCUIT_DATA,
|
||||
},
|
||||
middleware::{
|
||||
self, resolve_wildcard_values, value_from_op, AnchoredKey, CustomPredicateBatch, DynError,
|
||||
Hash, MainPodInputs, NativeOperation, OperationType, Params, Pod, PodId, PodProver,
|
||||
PodType, RecursivePod, StatementArg, ToFields, VDSet, F, KEY_TYPE, SELF,
|
||||
self, resolve_wildcard_values, value_from_op, AnchoredKey, CustomPredicateBatch, Hash,
|
||||
MainPodInputs, NativeOperation, OperationType, Params, Pod, PodId, PodProver, PodType,
|
||||
RecursivePod, StatementArg, ToFields, VDSet, F, KEY_TYPE, SELF,
|
||||
},
|
||||
timed,
|
||||
};
|
||||
|
|
@ -294,9 +294,9 @@ pub(crate) fn layout_statements(
|
|||
let empty_pod_box: Box<dyn RecursivePod> =
|
||||
if mock || inputs.recursive_pods.len() == params.max_input_recursive_pods {
|
||||
// We mocking or we don't need padding so we skip creating an EmptyPod
|
||||
MockEmptyPod::new_boxed(params)
|
||||
MockEmptyPod::new_boxed(params, inputs.vd_set.clone())
|
||||
} else {
|
||||
EmptyPod::new_boxed(params, inputs.vds_set.root())
|
||||
EmptyPod::new_boxed(params, inputs.vd_set.clone())
|
||||
};
|
||||
let empty_pod = empty_pod_box.as_ref();
|
||||
assert!(inputs.recursive_pods.len() <= params.max_input_recursive_pods);
|
||||
|
|
@ -432,8 +432,13 @@ pub(crate) fn process_public_statements_operations(
|
|||
|
||||
pub struct Prover {}
|
||||
|
||||
impl Prover {
|
||||
fn _prove(&self, params: &Params, vd_set: &VDSet, inputs: MainPodInputs) -> Result<MainPod> {
|
||||
impl PodProver for Prover {
|
||||
fn prove(
|
||||
&self,
|
||||
params: &Params,
|
||||
vd_set: &VDSet,
|
||||
inputs: MainPodInputs,
|
||||
) -> Result<Box<dyn RecursivePod>> {
|
||||
let rec_circuit_data = &*STANDARD_REC_MAIN_POD_CIRCUIT_DATA;
|
||||
let (main_pod_target, circuit_data) =
|
||||
RecursiveCircuit::<MainPodVerifyTarget>::target_and_circuit_data_padded(
|
||||
|
|
@ -466,9 +471,9 @@ impl Prover {
|
|||
// Pad input recursive pods with empty pods if necessary
|
||||
let empty_pod = if inputs.recursive_pods.len() == params.max_input_recursive_pods {
|
||||
// We don't need padding so we skip creating an EmptyPod
|
||||
MockEmptyPod::new_boxed(params)
|
||||
MockEmptyPod::new_boxed(params, inputs.vd_set.clone())
|
||||
} else {
|
||||
EmptyPod::new_boxed(params, inputs.vds_set.root())
|
||||
EmptyPod::new_boxed(params, inputs.vd_set.clone())
|
||||
};
|
||||
let inputs = MainPodInputs {
|
||||
recursive_pods: &inputs
|
||||
|
|
@ -515,10 +520,10 @@ impl Prover {
|
|||
.recursive_pods
|
||||
.iter()
|
||||
.map(|pod| {
|
||||
assert_eq!(inputs.vds_set.root(), pod.vds_root());
|
||||
assert_eq!(inputs.vd_set.root(), pod.vd_set().root());
|
||||
ProofWithPublicInputs {
|
||||
proof: pod.proof(),
|
||||
public_inputs: [pod.id().0 .0, inputs.vds_set.root().0].concat(),
|
||||
public_inputs: [pod.id().0 .0, inputs.vd_set.root().0].concat(),
|
||||
}
|
||||
})
|
||||
.collect_vec();
|
||||
|
|
@ -531,7 +536,7 @@ impl Prover {
|
|||
let vd_mt_proofs = vd_set.get_vds_proofs(&verifier_datas)?;
|
||||
|
||||
let input = MainPodVerifyInput {
|
||||
vds_set: inputs.vds_set.clone(),
|
||||
vds_set: inputs.vd_set.clone(),
|
||||
vd_mt_proofs,
|
||||
signed_pods: signed_pods_input,
|
||||
recursive_pods_pub_self_statements,
|
||||
|
|
@ -546,24 +551,13 @@ impl Prover {
|
|||
main_pod.prove(&input, proofs, verifier_datas)?
|
||||
);
|
||||
|
||||
Ok(MainPod {
|
||||
Ok(Box::new(MainPod {
|
||||
params: params.clone(),
|
||||
id,
|
||||
vds_root: inputs.vds_set.root(),
|
||||
vd_set: inputs.vd_set,
|
||||
public_statements,
|
||||
proof: proof_with_pis.proof,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl PodProver for Prover {
|
||||
fn prove(
|
||||
&self,
|
||||
params: &Params,
|
||||
vd_set: &VDSet,
|
||||
inputs: MainPodInputs,
|
||||
) -> Result<Box<dyn RecursivePod>, Box<DynError>> {
|
||||
Ok(self._prove(params, vd_set, inputs).map(Box::new)?)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -576,7 +570,7 @@ pub struct MainPod {
|
|||
/// the succession of recursive MainPods, which when proving the POD, it is
|
||||
/// proven that all the recursive proofs that are being verified in-circuit
|
||||
/// use one of the verifier_data's contained in the VDSet.
|
||||
vds_root: Hash,
|
||||
vd_set: VDSet,
|
||||
public_statements: Vec<Statement>,
|
||||
proof: Proof,
|
||||
}
|
||||
|
|
@ -605,13 +599,37 @@ struct Data {
|
|||
}
|
||||
|
||||
impl MainPod {
|
||||
fn _verify(&self) -> Result<()> {
|
||||
pub fn proof(&self) -> Proof {
|
||||
self.proof.clone()
|
||||
}
|
||||
|
||||
pub fn params(&self) -> &Params {
|
||||
&self.params
|
||||
}
|
||||
}
|
||||
|
||||
impl Pod for MainPod {
|
||||
fn params(&self) -> &Params {
|
||||
&self.params
|
||||
}
|
||||
fn verify(&self) -> Result<()> {
|
||||
// 2. get the id out of the public statements
|
||||
let id = PodId(calculate_id(&self.public_statements, &self.params));
|
||||
if id != self.id {
|
||||
return Err(Error::id_not_equal(self.id, id));
|
||||
}
|
||||
|
||||
// 7. verifier_data_hash is in the VDSet
|
||||
let verifier_data = self.verifier_data();
|
||||
let verifier_data_hash = hash_verifier_data(&verifier_data);
|
||||
if !self.vd_set.contains(verifier_data_hash) {
|
||||
return Err(Error::custom(format!(
|
||||
"vds_root in input recursive pod not in the set: {} not in {}",
|
||||
Hash(verifier_data_hash.elements),
|
||||
self.vd_set.root(),
|
||||
)));
|
||||
}
|
||||
|
||||
// 1, 3, 4, 5 verification via the zkSNARK proof
|
||||
let rec_circuit_data = &*STANDARD_REC_MAIN_POD_CIRCUIT_DATA;
|
||||
// TODO: cache these artefacts
|
||||
|
|
@ -625,7 +643,7 @@ impl MainPod {
|
|||
let public_inputs = id
|
||||
.to_fields(&self.params)
|
||||
.iter()
|
||||
.chain(self.vds_root.0.iter())
|
||||
.chain(self.vd_set.root().0.iter())
|
||||
.cloned()
|
||||
.collect_vec();
|
||||
circuit_data
|
||||
|
|
@ -633,28 +651,7 @@ impl MainPod {
|
|||
proof: self.proof.clone(),
|
||||
public_inputs,
|
||||
})
|
||||
.map_err(|e| Error::custom(format!("MainPod proof verification failure: {:?}", e)))
|
||||
}
|
||||
|
||||
pub fn proof(&self) -> Proof {
|
||||
self.proof.clone()
|
||||
}
|
||||
|
||||
pub fn vds_root(&self) -> Hash {
|
||||
self.vds_root
|
||||
}
|
||||
|
||||
pub fn params(&self) -> &Params {
|
||||
&self.params
|
||||
}
|
||||
}
|
||||
|
||||
impl Pod for MainPod {
|
||||
fn params(&self) -> &Params {
|
||||
&self.params
|
||||
}
|
||||
fn verify(&self) -> Result<(), Box<DynError>> {
|
||||
Ok(self._verify()?)
|
||||
.map_err(|e| Error::plonky2_proof_fail("MainPod", e))
|
||||
}
|
||||
|
||||
fn id(&self) -> PodId {
|
||||
|
|
@ -689,22 +686,22 @@ impl RecursivePod for MainPod {
|
|||
fn proof(&self) -> Proof {
|
||||
self.proof.clone()
|
||||
}
|
||||
fn vds_root(&self) -> Hash {
|
||||
self.vds_root
|
||||
fn vd_set(&self) -> &VDSet {
|
||||
&self.vd_set
|
||||
}
|
||||
fn deserialize_data(
|
||||
params: Params,
|
||||
data: serde_json::Value,
|
||||
vds_root: Hash,
|
||||
vd_set: VDSet,
|
||||
id: PodId,
|
||||
) -> Result<Box<dyn RecursivePod>, Box<DynError>> {
|
||||
) -> Result<Box<dyn RecursivePod>> {
|
||||
let data: Data = serde_json::from_value(data)?;
|
||||
let common = get_common_data(¶ms)?;
|
||||
let proof = deserialize_proof(&common, &data.proof)?;
|
||||
Ok(Box::new(Self {
|
||||
params,
|
||||
id,
|
||||
vds_root,
|
||||
vd_set,
|
||||
proof,
|
||||
public_statements: data.public_statements,
|
||||
}))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue