#![feature(i128_type)] extern crate rand; extern crate num_cpus; extern crate crossbeam; extern crate byteorder; extern crate serde; pub mod curves; pub mod groth16; use std::collections::HashMap; use std::ops; use std::ops::Deref; use std::borrow::Borrow; use curves::{Engine, Field}; #[derive(Copy, Clone)] pub struct Variable(Index); impl Variable { pub fn one() -> Self { Variable(Index::Input(0)) } } #[derive(Clone, Copy, PartialEq, Eq, Hash)] enum Index { Input(usize), Aux(usize) } pub struct LinearCombination<'a, E: Engine + 'a>(HashMap, &'a E); impl<'a, E: Engine + 'a> ops::Add for LinearCombination<'a, E> { type Output = LinearCombination<'a, E>; fn add(self, other: Variable) -> LinearCombination<'a, E> { let one = E::Fr::one(self.1); self.add(one, other) } } impl<'a, E: Engine + 'a> ops::Add<(E::Fr, Variable)> for LinearCombination<'a, E> { type Output = LinearCombination<'a, E>; fn add(self, (coeff, var): (E::Fr, Variable)) -> LinearCombination<'a, E> { self.add(coeff, var) } } impl<'a, E: Engine + 'a> ops::Sub for LinearCombination<'a, E> { type Output = LinearCombination<'a, E>; fn sub(self, other: Variable) -> LinearCombination<'a, E> { let one = E::Fr::one(self.1); self.sub(one, other) } } impl<'a, E: Engine + 'a> ops::Sub<(E::Fr, Variable)> for LinearCombination<'a, E> { type Output = LinearCombination<'a, E>; fn sub(self, (coeff, var): (E::Fr, Variable)) -> LinearCombination<'a, E> { self.sub(coeff, var) } } impl<'a, E: Engine> LinearCombination<'a, E> { pub fn zero(e: &'a E) -> LinearCombination<'a, E> { LinearCombination(HashMap::new(), e) } pub fn one(e: &'a E) -> LinearCombination<'a, E> { LinearCombination::zero(e).add(E::Fr::one(e), Variable::one()) } pub fn add(mut self, coeff: E::Fr, var: Variable) -> Self { self.0.entry(var.0) .or_insert(E::Fr::zero()) .add_assign(self.1, &coeff); self } pub fn sub(self, mut coeff: E::Fr, var: Variable) -> Self { coeff.negate(self.1); self.add(coeff, var) } fn evaluate( &self, e: &E, input_assignment: &[E::Fr], aux_assignment: &[E::Fr] ) -> E::Fr { let mut acc = E::Fr::zero(); for (index, coeff) in self.0.iter() { let mut n = *coeff; match index { &Index::Input(id) => { n.mul_assign(e, &input_assignment[id]); }, &Index::Aux(id) => { n.mul_assign(e, &aux_assignment[id]); } } acc.add_assign(e, &n); } acc } } pub trait Circuit { type InputMap: Input; /// Synthesize the circuit into a rank-1 quadratic constraint system #[must_use] fn synthesize>(self, engine: &E, cs: &mut CS) -> Self::InputMap; } pub trait Input { /// Synthesize the circuit, except with additional access to public input /// variables fn synthesize>(self, engine: &E, cs: &mut CS); } pub trait PublicConstraintSystem: ConstraintSystem { /// Allocate a public input that the verifier knows. fn alloc_input(&mut self, value: E::Fr) -> Variable; } pub trait ConstraintSystem { /// Allocate a private variable in the constraint system, setting it to /// the provided value. fn alloc(&mut self, value: E::Fr) -> Variable; /// Enforce that `A` * `B` = `C`. fn enforce( &mut self, a: LinearCombination, b: LinearCombination, c: LinearCombination ); } pub enum Cow<'a, T: 'a> { Owned(T), Borrowed(&'a T) } impl<'a, T: 'a> Deref for Cow<'a, T> { type Target = T; fn deref(&self) -> &T { match *self { Cow::Owned(ref v) => v, Cow::Borrowed(v) => v } } } pub trait Convert { type Target: Borrow; fn convert(&self, &E) -> Cow; } impl Convert for T { type Target = T; fn convert(&self, _: &E) -> Cow { Cow::Borrowed(self) } } pub struct BitIterator { t: T, n: usize } impl> BitIterator { fn new(t: T) -> Self { let bits = 64 * t.as_ref().len(); BitIterator { t: t, n: bits } } } impl> Iterator for BitIterator { type Item = bool; fn next(&mut self) -> Option { if self.n == 0 { None } else { self.n -= 1; let part = self.n / 64; let bit = self.n - (64 * part); Some(self.t.as_ref()[part] & (1 << bit) > 0) } } }