pub fn verify(
    &self,
    pp: &PublicParams<G1, G2, C1, C2>,
    num_steps: usize,
    z0_primary: G1::Scalar,
    z0_secondary: G2::Scalar,
  ) -> Result<(G1::Scalar, G2::Scalar), NovaError> {
    // number of steps cannot be zero
    if num_steps == 0 {
      return Err(NovaError::ProofVerifyError);
    }

    // check if the (relaxed) R1CS instances have two public outputs
    if self.l_u_primary.X.len() != 2
      || self.l_u_secondary.X.len() != 2
      || self.r_U_primary.X.len() != 2
      || self.r_U_secondary.X.len() != 2
    {
      return Err(NovaError::ProofVerifyError);
    }

    // check if the output hashes in R1CS instances point to the right running instances
    let (hash_primary, hash_secondary) = {
      let mut hasher = <G2 as Group>::HashFunc::new(pp.ro_consts_secondary.clone());
      hasher.absorb(scalar_as_base::<G2>(pp.r1cs_shape_secondary.get_digest()));
      hasher.absorb(G1::Scalar::from(num_steps as u64));
      hasher.absorb(z0_primary);
      hasher.absorb(self.zn_primary);
      self.r_U_secondary.absorb_in_ro(&mut hasher);

      let mut hasher2 = <G1 as Group>::HashFunc::new(pp.ro_consts_primary.clone());
      hasher2.absorb(scalar_as_base::<G1>(pp.r1cs_shape_primary.get_digest()));
      hasher2.absorb(G2::Scalar::from(num_steps as u64));
      hasher2.absorb(z0_secondary);
      hasher2.absorb(self.zn_secondary);
      self.r_U_primary.absorb_in_ro(&mut hasher2);

      (hasher.get_hash(), hasher2.get_hash())
    };

    if hash_primary != scalar_as_base::<G1>(self.l_u_primary.X[1])
      || hash_secondary != scalar_as_base::<G2>(self.l_u_secondary.X[1])
    {
      return Err(NovaError::ProofVerifyError);
    }

    // check the satisfiability of the provided instances
    pp.r1cs_shape_primary.is_sat_relaxed(
      &pp.r1cs_gens_primary,
      &self.r_U_primary,
      &self.r_W_primary,
    )?;

    pp.r1cs_shape_primary
      .is_sat(&pp.r1cs_gens_primary, &self.l_u_primary, &self.l_w_primary)?;

    pp.r1cs_shape_secondary.is_sat_relaxed(
      &pp.r1cs_gens_secondary,
      &self.r_U_secondary,
      &self.r_W_secondary,
    )?;

    pp.r1cs_shape_secondary.is_sat(
      &pp.r1cs_gens_secondary,
      &self.l_u_secondary,
      &self.l_w_secondary,
    )?;

    Ok((self.zn_primary, self.zn_secondary))
  }
/// Verify the correctness of the `RecursiveSNARK`
Verify the correctness of the `RecursiveSNARK`
Verify the correctness of the ` RecursiveSNARK `
pub fn verify(
    &self,
    pp: &PublicParams<G1, G2, C1, C2>,
    num_steps: usize,
    z0_primary: G1::Scalar,
    z0_secondary: G2::Scalar,
  ) -> Result<(G1::Scalar, G2::Scalar), NovaError> {
    // number of steps cannot be zero
    if num_steps == 0 {
      return Err(NovaError::ProofVerifyError);
    }
    // check if the (relaxed) R1CS instances have two public outputs
    if self.l_u_primary.X.len() != 2
      || self.l_u_secondary.X.len() != 2
      || self.r_U_primary.X.len() != 2
      || self.r_U_secondary.X.len() != 2
    {
      return Err(NovaError::ProofVerifyError);
    }
    // check if the output hashes in R1CS instances point to the right running instances
    let (hash_primary, hash_secondary) = {
      let mut hasher = <G2 as Group>::HashFunc::new(pp.ro_consts_secondary.clone());
      hasher.absorb(scalar_as_base::<G2>(pp.r1cs_shape_secondary.get_digest()));
      hasher.absorb(G1::Scalar::from(num_steps as u64));
      hasher.absorb(z0_primary);
      hasher.absorb(self.zn_primary);
      self.r_U_secondary.absorb_in_ro(&mut hasher);
      let mut hasher2 = <G1 as Group>::HashFunc::new(pp.ro_consts_primary.clone());
      hasher2.absorb(scalar_as_base::<G1>(pp.r1cs_shape_primary.get_digest()));
      hasher2.absorb(G2::Scalar::from(num_steps as u64));
      hasher2.absorb(z0_secondary);
      hasher2.absorb(self.zn_secondary);
      self.r_U_primary.absorb_in_ro(&mut hasher2);
      (hasher.get_hash(), hasher2.get_hash())
    };
    if hash_primary != scalar_as_base::<G1>(self.l_u_primary.X[1])
      || hash_secondary != scalar_as_base::<G2>(self.l_u_secondary.X[1])
    {
      return Err(NovaError::ProofVerifyError);
    }
    // check the satisfiability of the provided instances
    pp.r1cs_shape_primary.is_sat_relaxed(
      &pp.r1cs_gens_primary,
      &self.r_U_primary,
      &self.r_W_primary,
    )?;
    pp.r1cs_shape_primary
      .is_sat(&pp.r1cs_gens_primary, &self.l_u_primary, &self.l_w_primary)?;
    pp.r1cs_shape_secondary.is_sat_relaxed(
      &pp.r1cs_gens_secondary,
      &self.r_U_secondary,
      &self.r_W_secondary,
    )?;
    pp.r1cs_shape_secondary.is_sat(
      &pp.r1cs_gens_secondary,
      &self.l_u_secondary,
      &self.l_w_secondary,
    )?;
    Ok((self.zn_primary, self.zn_secondary))
  }
pub fn verify ( & self , pp : & PublicParams < G1 , G2 , C1 , C2 > , num_steps : usize , z0_primary : G1 :: Scalar , z0_secondary : G2 :: Scalar , ) -> Result < ( G1 :: Scalar , G2 :: Scalar ) , NovaError > { // number of steps cannot be zero if num_steps == 0 { return Err ( NovaError :: ProofVerifyError ) ; } // check if the (relaxed) R1CS instances have two public outputs if self . l_u_primary . X . len ( ) != 2 || self . l_u_secondary . X . len ( ) != 2 || self . r_U_primary . X . len ( ) != 2 || self . r_U_secondary . X . len ( ) != 2 { return Err ( NovaError :: ProofVerifyError ) ; } // check if the output hashes in R1CS instances point to the right running instances let ( hash_primary , hash_secondary ) = { let mut hasher = < G2 as Group > :: HashFunc :: new ( pp . ro_consts_secondary . clone ( ) ) ; hasher . absorb ( scalar_as_base :: < G2 > ( pp . r1cs_shape_secondary . get_digest ( ) ) ) ; hasher . absorb ( G1 :: Scalar :: from ( num_steps as u64 ) ) ; hasher . absorb ( z0_primary ) ; hasher . absorb ( self . zn_primary ) ; self . r_U_secondary . absorb_in_ro ( & mut hasher ) ; let mut hasher2 = < G1 as Group > :: HashFunc :: new ( pp . ro_consts_primary . clone ( ) ) ; hasher2 . absorb ( scalar_as_base :: < G1 > ( pp . r1cs_shape_primary . get_digest ( ) ) ) ; hasher2 . absorb ( G2 :: Scalar :: from ( num_steps as u64 ) ) ; hasher2 . absorb ( z0_secondary ) ; hasher2 . absorb ( self . zn_secondary ) ; self . r_U_primary . absorb_in_ro ( & mut hasher2 ) ; ( hasher . get_hash ( ) , hasher2 . get_hash ( ) ) } ; if hash_primary != scalar_as_base :: < G1 > ( self . l_u_primary . X [ 1 ] ) || hash_secondary != scalar_as_base :: < G2 > ( self . l_u_secondary . X [ 1 ] ) { return Err ( NovaError :: ProofVerifyError ) ; } // check the satisfiability of the provided instances pp . r1cs_shape_primary . is_sat_relaxed ( & pp . r1cs_gens_primary , & self . r_U_primary , & self . r_W_primary , ) ? ; pp . r1cs_shape_primary . is_sat ( & pp . r1cs_gens_primary , & self . l_u_primary , & self . l_w_primary ) ? ; pp . r1cs_shape_secondary . is_sat_relaxed ( & pp . r1cs_gens_secondary , & self . r_U_secondary , & self . r_W_secondary , ) ? ; pp . r1cs_shape_secondary . is_sat ( & pp . r1cs_gens_secondary , & self . l_u_secondary , & self . l_w_secondary , ) ? ; Ok ( ( self . zn_primary , self . zn_secondary ) ) }
Verify the correctness of the `RecursiveSNARK`
Verify the correctness of the ` RecursiveSNARK `
&self
pp
&PublicParams<G1, G2, C1, C2>
num_steps
usize
z0_primary
G1::Scalar
z0_secondary
G2::Scalar
&self
pp
&PublicParams<G1, G2, C1, C2>
num_steps
usize
z0_primary
G1::Scalar
z0_secondary
G2::Scalar