|
|
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<E::Fr>` in the same order as
/// during the constraint generation.
pub struct Groth16<
E: PairingEngine,
C: ConstraintSynthesizer<E::Fr>,
V: ToConstraintField<E::Fr> + ?Sized,
> {
#[doc(hidden)]
_engine: PhantomData<E>,
#[doc(hidden)]
_circuit: PhantomData<C>,
#[doc(hidden)]
_verifier_input: PhantomData<V>,
}
impl<E: PairingEngine, C: ConstraintSynthesizer<E::Fr>, V: ToConstraintField<E::Fr> + ?Sized> NIZK
for Groth16<E, C, V>
{
type Circuit = C;
type AssignedCircuit = C;
type ProvingParameters = Parameters<E>;
type VerificationParameters = VerifyingKey<E>;
type PreparedVerificationParameters = PreparedVerifyingKey<E>;
type VerifierInput = V;
type Proof = Proof<E>;
fn setup<R: Rng>(
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::<E, Self::Circuit, R>(circuit, rng)?;
let vk = prepare_verifying_key(&pp.vk);
end_timer!(nizk_time);
Ok((pp, vk))
}
fn prove<R: Rng>(
pp: &Self::ProvingParameters,
input_and_witness: Self::AssignedCircuit,
rng: &mut R,
) -> Result<Self::Proof, Error> {
let proof_time = start_timer!(|| "{Groth 2016}::Prove");
let result = create_random_proof::<E, _, _>(input_and_witness, pp, rng)?;
end_timer!(proof_time);
Ok(result)
}
fn verify(
vk: &Self::PreparedVerificationParameters,
input: &Self::VerifierInput,
proof: &Self::Proof,
) -> Result<bool, Error> {
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)
}
}
|