Avoid the use of dynamic dispatch during verification.

This commit is contained in:
Sean Bowe 2017-06-15 17:39:07 -06:00
parent 97d58c7954
commit 8f6a5737c0
1 changed files with 51 additions and 33 deletions

View File

@ -307,55 +307,73 @@ pub fn prepare_verifying_key<E: Engine>(
} }
} }
pub fn verify<E: Engine, C: Input<E>, F: FnOnce(&mut ConstraintSystem<E>) -> C>( pub struct VerifierInput<'a, E: Engine + 'a> {
e: &E, e: &'a E,
circuit: F, acc: E::G1,
proof: &Proof<E>, ic: &'a [<E::G1 as Curve<E>>::Affine],
pvk: &PreparedVerifyingKey<E> insufficient_inputs: bool,
) -> bool num_inputs: usize,
{ num_aux: usize
struct VerifierInput<'a, E: Engine + 'a> { }
e: &'a E,
acc: E::G1, impl<'a, E: Engine> ConstraintSystem<E> for VerifierInput<'a, E> {
ic: &'a [<E::G1 as Curve<E>>::Affine], fn alloc(&mut self, _: E::Fr) -> Variable {
insufficient_inputs: bool, let index = self.num_aux;
num_inputs: usize, self.num_aux += 1;
num_aux: usize
Variable(Index::Aux(index))
} }
impl<'a, E: Engine> PublicConstraintSystem<E> for VerifierInput<'a, E> { fn enforce(
&mut self,
_: LinearCombination<E>,
_: LinearCombination<E>,
_: LinearCombination<E>
)
{
// Do nothing; we don't care about the constraint system
// in this context.
}
}
pub fn verify<'a, E: Engine, C: Input<E>, F: FnOnce(&mut VerifierInput<'a, E>) -> C>(
e: &'a E,
circuit: F,
proof: &Proof<E>,
pvk: &'a PreparedVerifyingKey<E>
) -> bool
{
struct InputAllocator<T>(T);
impl<'a, 'b, E: Engine> PublicConstraintSystem<E> for InputAllocator<&'b mut VerifierInput<'a, E>> {
fn alloc_input(&mut self, value: E::Fr) -> Variable { fn alloc_input(&mut self, value: E::Fr) -> Variable {
if self.ic.len() == 0 { if self.0.ic.len() == 0 {
self.insufficient_inputs = true; self.0.insufficient_inputs = true;
} else { } else {
self.acc.add_assign(self.e, &self.ic[0].mul(self.e, &value)); self.0.acc.add_assign(self.0.e, &self.0.ic[0].mul(self.0.e, &value));
self.ic = &self.ic[1..]; self.0.ic = &self.0.ic[1..];
} }
let index = self.num_inputs; let index = self.0.num_inputs;
self.num_inputs += 1; self.0.num_inputs += 1;
Variable(Index::Input(index)) Variable(Index::Input(index))
} }
} }
impl<'a, E: Engine> ConstraintSystem<E> for VerifierInput<'a, E> { impl<'a, 'b, E: Engine> ConstraintSystem<E> for InputAllocator<&'b mut VerifierInput<'a, E>> {
fn alloc(&mut self, _: E::Fr) -> Variable { fn alloc(&mut self, num: E::Fr) -> Variable {
let index = self.num_aux; self.0.alloc(num)
self.num_aux += 1;
Variable(Index::Aux(index))
} }
fn enforce( fn enforce(
&mut self, &mut self,
_: LinearCombination<E>, a: LinearCombination<E>,
_: LinearCombination<E>, b: LinearCombination<E>,
_: LinearCombination<E> c: LinearCombination<E>
) )
{ {
// Do nothing; we don't care about the constraint system self.0.enforce(a, b, c);
// in this context.
} }
} }
@ -368,7 +386,7 @@ pub fn verify<E: Engine, C: Input<E>, F: FnOnce(&mut ConstraintSystem<E>) -> C>(
num_aux: 0 num_aux: 0
}; };
circuit(&mut witness).synthesize(e, &mut witness); circuit(&mut witness).synthesize(e, &mut InputAllocator(&mut witness));
if witness.ic.len() != 0 || witness.insufficient_inputs { if witness.ic.len() != 0 || witness.insufficient_inputs {
return false; return false;