Browse Source

Change API to support constraint/variable annotation.

master
Sean Bowe 7 years ago
parent
commit
bc19c76326
  1. 24
      src/groth16/generator.rs
  2. 28
      src/groth16/prover.rs
  3. 34
      src/groth16/verifier.rs
  4. 31
      src/lib.rs

24
src/groth16/generator.rs

@ -69,7 +69,13 @@ pub fn generate_parameters<E, C>(
}
impl<E: Engine> PublicConstraintSystem<E> for KeypairAssembly<E> {
fn alloc_input<F: FnOnce() -> Result<E::Fr, Error>>(&mut self, f: F) -> Result<Variable, Error> {
fn alloc_input<NR, N, F>(
&mut self,
_: N,
f: F
) -> Result<Variable, Error>
where NR: Into<String>, N: FnOnce() -> NR, F: FnOnce() -> Result<E::Fr, Error>
{
// In this context, we don't have an assignment.
let _ = f();
@ -85,7 +91,13 @@ pub fn generate_parameters<E, C>(
}
impl<E: Engine> ConstraintSystem<E> for KeypairAssembly<E> {
fn alloc<F: FnOnce() -> Result<E::Fr, Error>>(&mut self, f: F) -> Result<Variable, Error> {
fn alloc<NR, N, F>(
&mut self,
_: N,
f: F
) -> Result<Variable, Error>
where NR: Into<String>, N: FnOnce() -> NR, F: FnOnce() -> Result<E::Fr, Error>
{
// In this context, we don't have an assignment.
let _ = f();
@ -99,8 +111,9 @@ pub fn generate_parameters<E, C>(
Ok(Variable(Index::Aux(index)))
}
fn enforce(
fn enforce<NR: Into<String>, N: FnOnce() -> NR>(
&mut self,
_: N,
a: LinearCombination<E>,
b: LinearCombination<E>,
c: LinearCombination<E>
@ -142,14 +155,15 @@ pub fn generate_parameters<E, C>(
};
// Allocate the "one" input variable
assembly.alloc_input(|| Ok(E::Fr::one()))?;
assembly.alloc_input(|| "", || Ok(E::Fr::one()))?;
// Synthesize the circuit.
circuit.synthesize(&mut assembly)?.synthesize(&mut assembly)?;
// Input consistency constraints: x * 0 = 0
for i in 0..assembly.num_inputs {
assembly.enforce(LinearCombination::zero() + Variable(Index::Input(i)),
assembly.enforce(|| "",
LinearCombination::zero() + Variable(Index::Input(i)),
LinearCombination::zero(),
LinearCombination::zero());
}

28
src/groth16/prover.rs

@ -55,8 +55,14 @@ pub fn create_proof<E, C, P: ParameterSource<E>>(
}
impl<E: Engine> PublicConstraintSystem<E> for ProvingAssignment<E> {
fn alloc_input<F: FnOnce() -> Result<E::Fr, Error>>(&mut self, value: F) -> Result<Variable, Error> {
self.input_assignment.push(value()?);
fn alloc_input<NR, N, F>(
&mut self,
_: N,
f: F
) -> Result<Variable, Error>
where NR: Into<String>, N: FnOnce() -> NR, F: FnOnce() -> Result<E::Fr, Error>
{
self.input_assignment.push(f()?);
self.b_input_density.add_element();
Ok(Variable(Index::Input(self.input_assignment.len() - 1)))
@ -64,16 +70,23 @@ pub fn create_proof<E, C, P: ParameterSource<E>>(
}
impl<E: Engine> ConstraintSystem<E> for ProvingAssignment<E> {
fn alloc<F: FnOnce() -> Result<E::Fr, Error>>(&mut self, value: F) -> Result<Variable, Error> {
self.aux_assignment.push(value()?);
fn alloc<NR, N, F>(
&mut self,
_: N,
f: F
) -> Result<Variable, Error>
where NR: Into<String>, N: FnOnce() -> NR, F: FnOnce() -> Result<E::Fr, Error>
{
self.aux_assignment.push(f()?);
self.a_aux_density.add_element();
self.b_aux_density.add_element();
Ok(Variable(Index::Aux(self.aux_assignment.len() - 1)))
}
fn enforce(
fn enforce<NR: Into<String>, N: FnOnce() -> NR>(
&mut self,
_: N,
a: LinearCombination<E>,
b: LinearCombination<E>,
c: LinearCombination<E>
@ -96,13 +109,14 @@ pub fn create_proof<E, C, P: ParameterSource<E>>(
aux_assignment: vec![]
};
prover.alloc_input(|| Ok(E::Fr::one()))?;
prover.alloc_input(|| "", || Ok(E::Fr::one()))?;
circuit.synthesize(&mut prover)?.synthesize(&mut prover)?;
// Input consistency constraints: x * 0 = 0
for i in 0..prover.input_assignment.len() {
prover.enforce(LinearCombination::zero() + Variable(Index::Input(i)),
prover.enforce(|| "",
LinearCombination::zero() + Variable(Index::Input(i)),
LinearCombination::zero(),
LinearCombination::zero());
}

34
src/groth16/verifier.rs

@ -22,7 +22,13 @@ pub struct VerifierInput<'a, E: Engine> {
}
impl<'a, E: Engine> ConstraintSystem<E> for VerifierInput<'a, E> {
fn alloc<F: FnOnce() -> Result<E::Fr, Error>>(&mut self, f: F) -> Result<Variable, Error> {
fn alloc<NR, N, F>(
&mut self,
_: N,
f: F
) -> Result<Variable, Error>
where NR: Into<String>, N: FnOnce() -> NR, F: FnOnce() -> Result<E::Fr, Error>
{
// Run the function for calculating the allocation but ignore the output,
// since we don't care about the assignment of auxillary variables during
// verification.
@ -34,8 +40,9 @@ impl<'a, E: Engine> ConstraintSystem<E> for VerifierInput<'a, E> {
Ok(Variable(Index::Aux(index)))
}
fn enforce(
fn enforce<NR: Into<String>, N: FnOnce() -> NR>(
&mut self,
_: N,
_: LinearCombination<E>,
_: LinearCombination<E>,
_: LinearCombination<E>
@ -51,12 +58,19 @@ impl<'a, E: Engine> ConstraintSystem<E> for VerifierInput<'a, E> {
struct InputAllocator<T>(T);
impl<'a, 'b, E: Engine> ConstraintSystem<E> for InputAllocator<&'a mut VerifierInput<'b, E>> {
fn alloc<F: FnOnce() -> Result<E::Fr, Error>>(&mut self, value: F) -> Result<Variable, Error> {
self.0.alloc(value)
fn alloc<NR, N, F>(
&mut self,
name_fn: N,
f: F
) -> Result<Variable, Error>
where NR: Into<String>, N: FnOnce() -> NR, F: FnOnce() -> Result<E::Fr, Error>
{
self.0.alloc(name_fn, f)
}
fn enforce(
fn enforce<NR: Into<String>, N: FnOnce() -> NR>(
&mut self,
_: N,
_: LinearCombination<E>,
_: LinearCombination<E>,
_: LinearCombination<E>
@ -68,11 +82,17 @@ impl<'a, 'b, E: Engine> ConstraintSystem<E> for InputAllocator<&'a mut VerifierI
}
impl<'a, 'b, E: Engine> PublicConstraintSystem<E> for InputAllocator<&'a mut VerifierInput<'b, E>> {
fn alloc_input<F: FnOnce() -> Result<E::Fr, Error>>(&mut self, value: F) -> Result<Variable, Error> {
fn alloc_input<NR, N, F>(
&mut self,
_: N,
f: F
) -> Result<Variable, Error>
where NR: Into<String>, N: FnOnce() -> NR, F: FnOnce() -> Result<E::Fr, Error>
{
if self.0.ic.len() == 0 {
self.0.insufficient_inputs = true;
} else {
self.0.acc.add_assign(&self.0.ic[0].mul(value()?));
self.0.acc.add_assign(&self.0.ic[0].mul(f()?));
self.0.ic = &self.0.ic[1..];
}

31
src/lib.rs

@ -25,7 +25,8 @@ pub enum Error {
AssignmentMissing,
UnexpectedIdentity,
UnconstrainedVariable(Variable),
IoError(io::Error)
IoError(io::Error),
NameConflict(&'static str, String)
}
impl From<io::Error> for Error {
@ -185,7 +186,12 @@ pub trait Input<E: Engine> {
pub trait PublicConstraintSystem<E: Engine>: ConstraintSystem<E> {
/// Allocate a public input that the verifier knows. The provided function is used to
/// determine the assignment of the variable.
fn alloc_input<F: FnOnce() -> Result<E::Fr, Error>>(&mut self, f: F) -> Result<Variable, Error>;
fn alloc_input<NR, N, F>(
&mut self,
name_fn: N,
f: F
) -> Result<Variable, Error>
where NR: Into<String>, N: FnOnce() -> NR, F: FnOnce() -> Result<E::Fr, Error>;
}
pub trait ConstraintSystem<E: Engine> {
@ -196,13 +202,30 @@ pub trait ConstraintSystem<E: Engine> {
/// Allocate a private variable in the constraint system. The provided function is used to
/// determine the assignment of the variable.
fn alloc<F: FnOnce() -> Result<E::Fr, Error>>(&mut self, f: F) -> Result<Variable, Error>;
fn alloc<NR, N, F>(
&mut self,
name_fn: N,
f: F
) -> Result<Variable, Error>
where NR: Into<String>, N: FnOnce() -> NR, F: FnOnce() -> Result<E::Fr, Error>;
/// Enforce that `A` * `B` = `C`.
fn enforce(
fn enforce<NR: Into<String>, N: FnOnce() -> NR>(
&mut self,
name_fn: N,
a: LinearCombination<E>,
b: LinearCombination<E>,
c: LinearCombination<E>
);
/// Begin a namespace for the constraint system
fn namespace<NR, N, R, F>(
&mut self,
_: N,
space_fn: F
) -> Result<R, Error>
where NR: Into<String>, N: FnOnce() -> NR, F: FnOnce(&mut Self) -> Result<R, Error>
{
space_fn(self)
}
}

Loading…
Cancel
Save