use crate::Error; use algebra::PairingEngine; use groth16::{ create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, Parameters, PreparedVerifyingKey, Proof, VerifyingKey, }; use r1cs_core::ConstraintSynthesizer; use rand::Rng; use algebra::ToConstraintField; use std::marker::PhantomData; use super::NIZK; #[cfg(feature = "r1cs")] pub mod constraints; /// Note: V should serialize its contents to `Vec` in the same order as /// during the constraint generation. pub struct Groth16< E: PairingEngine, C: ConstraintSynthesizer, V: ToConstraintField + ?Sized, > { #[doc(hidden)] _engine: PhantomData, #[doc(hidden)] _circuit: PhantomData, #[doc(hidden)] _verifier_input: PhantomData, } impl, V: ToConstraintField + ?Sized> NIZK for Groth16 { type Circuit = C; type AssignedCircuit = C; type ProvingParameters = Parameters; type VerificationParameters = VerifyingKey; type PreparedVerificationParameters = PreparedVerifyingKey; type VerifierInput = V; type Proof = Proof; fn setup( circuit: Self::Circuit, rng: &mut R, ) -> Result< ( Self::ProvingParameters, Self::PreparedVerificationParameters, ), Error, > { let nizk_time = start_timer!(|| "{Groth 2016}::Setup"); let pp = generate_random_parameters::(circuit, rng)?; let vk = prepare_verifying_key(&pp.vk); end_timer!(nizk_time); Ok((pp, vk)) } fn prove( pp: &Self::ProvingParameters, input_and_witness: Self::AssignedCircuit, rng: &mut R, ) -> Result { let proof_time = start_timer!(|| "{Groth 2016}::Prove"); let result = create_random_proof::(input_and_witness, pp, rng)?; end_timer!(proof_time); Ok(result) } fn verify( vk: &Self::PreparedVerificationParameters, input: &Self::VerifierInput, proof: &Self::Proof, ) -> Result { let verify_time = start_timer!(|| "{Groth-Maller 2017}::Verify"); let conversion_time = start_timer!(|| "Convert input to E::Fr"); let input = input.to_field_elements()?; end_timer!(conversion_time); let verification = start_timer!(|| format!("Verify proof w/ input len: {}", input.len())); let result = verify_proof(&vk, proof, &input)?; end_timer!(verification); end_timer!(verify_time); Ok(result) } }