diff --git a/src/cli/lurk_proof.rs b/src/cli/lurk_proof.rs index 42ea62ef40..3c5c93b1bd 100644 --- a/src/cli/lurk_proof.rs +++ b/src/cli/lurk_proof.rs @@ -47,21 +47,6 @@ impl HasFieldModulus for LurkProofMeta { } } -impl< - 'a, - F: CurveCycleEquipped, - C: Coprocessor + 'a + Serialize + DeserializeOwned, - M: MultiFrameTrait<'a, F, C>, - > HasFieldModulus for LurkProof<'a, F, C, M> -where - < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, - < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, -{ - fn field_modulus() -> String { - F::MODULUS.to_owned() - } -} - impl LurkProofMeta { fn without_envs(self) -> Result { if self.env_io.is_none() { @@ -99,7 +84,7 @@ impl LurkProofMeta { store_state: Option<(&Store, &State)>, full: bool, ) -> Result<()> { - let Ok(proof_meta) = load::>(&proof_meta_path(proof_key)) else { + let Ok(proof_meta) = load::(&proof_meta_path(proof_key)) else { bail!("Missing or corrupted proof meta file. Prove again to regenerate.") }; let do_inspect = |store: &Store, state: &State| { @@ -185,6 +170,74 @@ pub(crate) enum LurkProof< }, } +impl< + 'a, + F: CurveCycleEquipped, + C: Coprocessor + 'a + Serialize + DeserializeOwned, + M: MultiFrameTrait<'a, F, C>, + > HasFieldModulus for LurkProof<'a, F, C, M> +where + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, +{ + fn field_modulus() -> String { + F::MODULUS.to_owned() + } +} + +impl< + 'a, + F: CurveCycleEquipped, + C: Coprocessor + Serialize + DeserializeOwned, + M: MultiFrameTrait<'a, F, C>, + > LurkProof<'a, F, C, M> +where + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, +{ + #[inline] + fn public_io(&self) -> (&[F], &[F]) { + match self { + Self::Nova { + proof: _, + public_inputs, + public_outputs, + .. + } => (public_inputs, public_outputs), + } + } + + fn matches_meta(&self, meta: &LurkProofMeta) -> bool { + let (public_input, public_output) = self.public_io(); + let matches_exprs = { + let (expr, expr_out) = &meta.expr_io; + public_input[0] == expr.tag_field() + && &public_input[1] == expr.value() + && public_output[0] == expr_out.tag_field() + && &public_output[1] == expr_out.value() + }; + let matches_envs = { + if let Some((env, env_out)) = &meta.env_io { + public_input[2] == env.tag_field() + && &public_input[3] == env.value() + && public_output[2] == env_out.tag_field() + && &public_output[3] == env_out.value() + } else { + // no data to trigger inconsistency + true + } + }; + let matches_conts = { + let (cont, cont_out) = &meta.cont_io; + public_input[4] == cont.tag_field() + && &public_input[5] == cont.value() + && public_output[4] == cont_out.tag_field() + && &public_output[5] == cont_out.value() + }; + matches_exprs && matches_envs && matches_conts + } +} + impl< 'a, F: CurveCycleEquipped + Serialize, @@ -202,7 +255,7 @@ where } impl< - F: CurveCycleEquipped + Serialize + DeserializeOwned, + F: CurveCycleEquipped + DeserializeOwned, C: Coprocessor + Serialize + DeserializeOwned + 'static, M: MultiFrameTrait<'static, F, C> + SuperStepCircuit @@ -214,7 +267,7 @@ where < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, { pub(crate) fn verify_proof(proof_key: &str) -> Result<()> { - let lurk_proof: LurkProof<'_, F, C, M> = load(&proof_path(proof_key))?; + let lurk_proof = load::(&proof_path(proof_key))?; if lurk_proof.verify()? { println!("✓ Proof \"{proof_key}\" verified"); } else { @@ -223,9 +276,9 @@ where Ok(()) } + #[inline] pub(crate) fn is_cached(proof_key: &str) -> bool { - let lurk_proof: Result> = load(&proof_path(proof_key)); - lurk_proof.is_ok() + load::(&proof_path(proof_key)).is_ok() } fn verify(&self) -> Result { @@ -317,15 +370,17 @@ where } pub(crate) fn unpack(path: &Utf8PathBuf) -> Result<()> { - let packed_proof: PackedLurkProof<'_, F, C, M> = load(path)?; - let PackedLurkProof { proof, meta, key } = packed_proof; + let PackedLurkProof { proof, meta, key } = load::(path)?; if !proof.verify()? { bail!("Proof verification failed") } - proof.persist(&key)?; if let Some(meta) = meta { + if !proof.matches_meta(&meta) { + bail!("Meta data is incompatible with the proof") + } meta.persist(&key)?; } + proof.persist(&key)?; println!("Proof {key} unpacked"); Ok(()) }