#![deny( unused_import_braces, unused_qualifications, trivial_casts, trivial_numeric_casts )] #![deny( unused_qualifications, variant_size_differences, stable_features, unreachable_pub )] #![deny( non_shorthand_field_patterns, unused_attributes, unused_imports, unused_extern_crates )] #![deny( renamed_and_removed_lints, stable_features, unused_allocation, unused_comparisons, bare_trait_objects )] #![deny( const_err, unused_must_use, unused_mut, unused_unsafe, private_in_public, unsafe_code )] #![forbid(unsafe_code)] #[macro_use] extern crate algebra; #[macro_use] extern crate derivative; use crate::ConstraintVar::*; use algebra::Field; use r1cs_core::{LinearCombination, SynthesisError, Variable}; use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub}; pub mod test_constraint_system; pub mod bits; pub use self::bits::*; pub mod fields; pub mod groups; pub mod pairing; pub mod eq; pub mod select; pub mod alloc; pub mod prelude { pub use crate::eq::*; pub use crate::select::*; pub use crate::alloc::*; pub use crate::fields::FieldGadget; pub use crate::groups::GroupGadget; pub use crate::bits::{ToBitsGadget, ToBytesGadget, boolean::Boolean, uint8::UInt8, uint32::UInt32}; } pub trait Assignment { fn get(self) -> Result; } impl Assignment for Option { fn get(self) -> Result { match self { Some(v) => Ok(v), None => Err(SynthesisError::AssignmentMissing), } } } #[derive(Clone, Debug)] pub enum ConstraintVar { LC(LinearCombination), Var(Variable), } impl From for ConstraintVar { #[inline] fn from(var: Variable) -> Self { Var(var) } } impl From<(F, Variable)> for ConstraintVar { #[inline] fn from(coeff_var: (F, Variable)) -> Self { LC(coeff_var.into()) } } impl From<(F, LinearCombination)> for ConstraintVar { #[inline] fn from((coeff, mut lc): (F, LinearCombination)) -> Self { lc *= coeff; LC(lc) } } impl From<(F, ConstraintVar)> for ConstraintVar { #[inline] fn from((coeff, var): (F, ConstraintVar)) -> Self { match var { LC(lc) => (coeff, lc).into(), Var(var) => (coeff, var).into(), } } } impl ConstraintVar { #[inline] pub fn zero() -> Self { LC(LinearCombination::zero()) } pub fn negate_in_place(&mut self) { match self { LC(ref mut lc) => lc.negate_in_place(), Var(var) => *self = (-F::one(), *var).into(), } } pub fn double_in_place(&mut self) { match self { LC(lc) => lc.double_in_place(), Var(var) => *self = (F::one().double(), *var).into(), } } } impl Add> for ConstraintVar { type Output = LinearCombination; #[inline] fn add(self, other_lc: LinearCombination) -> LinearCombination { match self { LC(lc) => other_lc + lc, Var(var) => other_lc + var, } } } impl Sub> for ConstraintVar { type Output = LinearCombination; #[inline] fn sub(self, other_lc: LinearCombination) -> LinearCombination { let result = match self { LC(lc) => other_lc - lc, Var(var) => other_lc - var, }; -result } } impl Add> for &ConstraintVar { type Output = LinearCombination; #[inline] fn add(self, other_lc: LinearCombination) -> LinearCombination { match self { LC(lc) => other_lc + lc, Var(var) => other_lc + *var, } } } impl Sub> for &ConstraintVar { type Output = LinearCombination; #[inline] fn sub(self, other_lc: LinearCombination) -> LinearCombination { let result = match self { LC(lc) => other_lc - lc, Var(var) => other_lc - *var, }; -result } } impl Add<(F, Variable)> for ConstraintVar { type Output = Self; #[inline] fn add(self, var: (F, Variable)) -> Self { let lc = match self { LC(lc) => lc + var, Var(var2) => LinearCombination::from(var2) + var, }; LC(lc) } } impl AddAssign<(F, Variable)> for ConstraintVar { #[inline] fn add_assign(&mut self, var: (F, Variable)) { match self { LC(ref mut lc) => *lc += var, Var(var2) => *self = LC(LinearCombination::from(*var2) + var), }; } } impl Neg for ConstraintVar { type Output = Self; #[inline] fn neg(mut self) -> Self { self.negate_in_place(); self } } impl Mul for ConstraintVar { type Output = Self; #[inline] fn mul(self, scalar: F) -> Self { match self { LC(lc) => LC(lc * scalar), Var(var) => (scalar, var).into(), } } } impl MulAssign for ConstraintVar { #[inline] fn mul_assign(&mut self, scalar: F) { match self { LC(lc) => *lc *= scalar, Var(var) => *self = (scalar, *var).into(), } } } impl Sub<(F, Variable)> for ConstraintVar { type Output = Self; #[inline] fn sub(self, (coeff, var): (F, Variable)) -> Self { self + (-coeff, var) } } impl Add for ConstraintVar { type Output = Self; fn add(self, other: Variable) -> Self { self + (F::one(), other) } } impl Sub for ConstraintVar { type Output = Self; #[inline] fn sub(self, other: Variable) -> Self { self - (F::one(), other) } } impl<'a, F: Field> Add<&'a Self> for ConstraintVar { type Output = Self; #[inline] fn add(self, other: &'a Self) -> Self { let lc = match self { LC(lc2) => lc2, Var(var) => var.into(), }; let lc2 = match other { LC(lc2) => lc + lc2, Var(var) => lc + *var, }; LC(lc2) } } impl<'a, F: Field> Sub<&'a Self> for ConstraintVar { type Output = Self; #[inline] fn sub(self, other: &'a Self) -> Self { let lc = match self { LC(lc2) => lc2, Var(var) => var.into(), }; let lc2 = match other { LC(lc2) => lc - lc2, Var(var) => lc - *var, }; LC(lc2) } } impl Add<&ConstraintVar> for &ConstraintVar { type Output = ConstraintVar; #[inline] fn add(self, other: &ConstraintVar) -> Self::Output { (ConstraintVar::zero() + self) + other } } impl Sub<&ConstraintVar> for &ConstraintVar { type Output = ConstraintVar; #[inline] fn sub(self, other: &ConstraintVar) -> Self::Output { (ConstraintVar::zero() + self) - other } } impl<'a, F: Field> Add<(F, &'a Self)> for ConstraintVar { type Output = Self; #[inline] fn add(self, (coeff, other): (F, &'a Self)) -> Self { let mut lc = match self { LC(lc2) => lc2, Var(var) => LinearCombination::zero() + var, }; lc = match other { LC(lc2) => lc + (coeff, lc2), Var(var) => lc + (coeff, *var), }; LC(lc) } } impl<'a, F: Field> Sub<(F, &'a Self)> for ConstraintVar { type Output = Self; #[inline] fn sub(self, (coeff, other): (F, &'a Self)) -> Self { let mut lc = match self { LC(lc2) => lc2, Var(var) => LinearCombination::zero() + var, }; lc = match other { LC(lc2) => lc - (coeff, lc2), Var(var) => lc - (coeff, *var), }; LC(lc) } }