diff --git a/Cargo.toml b/Cargo.toml index 18319430e..a60e13894 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ features = ["expose-arith"] rand = "0.3" blake2 = "0.7" digest = "0.7" -bellman = "0.0.7" +bellman = "0.0.8" [features] default = ["u128-support"] diff --git a/src/circuit/blake2s.rs b/src/circuit/blake2s.rs index 9a0d283ad..855a8c64f 100644 --- a/src/circuit/blake2s.rs +++ b/src/circuit/blake2s.rs @@ -90,13 +90,13 @@ const SIGMA: [[usize; 16]; 10] = [ fn mixing_g>( mut cs: CS, - v: &mut [UInt32], + v: &mut [UInt32], a: usize, b: usize, c: usize, d: usize, - x: &UInt32, - y: &UInt32 + x: &UInt32, + y: &UInt32 ) -> Result<(), SynthesisError> { v[a] = UInt32::addmany(cs.namespace(|| "mixing step 1"), &[v[a].clone(), v[b].clone(), x.clone()])?; @@ -162,8 +162,8 @@ fn mixing_g>( fn blake2s_compression>( mut cs: CS, - h: &mut [UInt32], - m: &[UInt32], + h: &mut [UInt32], + m: &[UInt32], t: u64, f: bool ) -> Result<(), SynthesisError> @@ -254,8 +254,8 @@ fn blake2s_compression>( pub fn blake2s>( mut cs: CS, - input: &[Boolean] -) -> Result>, SynthesisError> + input: &[Boolean] +) -> Result, SynthesisError> { assert!(input.len() % 8 == 0); @@ -269,7 +269,7 @@ pub fn blake2s>( h.push(UInt32::constant(0x1F83D9AB)); h.push(UInt32::constant(0x5BE0CD19)); - let mut blocks: Vec>> = vec![]; + let mut blocks: Vec> = vec![]; for block in input.chunks(512) { let mut this_block = Vec::with_capacity(16); diff --git a/src/circuit/boolean.rs b/src/circuit/boolean.rs index 6b5b9cd95..4d1c358a2 100644 --- a/src/circuit/boolean.rs +++ b/src/circuit/boolean.rs @@ -9,7 +9,8 @@ use pairing::{ use bellman::{ ConstraintSystem, SynthesisError, - LinearCombination + LinearCombination, + Variable }; use super::{ @@ -19,17 +20,17 @@ use super::{ /// Represents a variable in the constraint system which is guaranteed /// to be either zero or one. #[derive(Clone)] -pub struct AllocatedBit { - variable: Var, +pub struct AllocatedBit { + variable: Variable, value: Option } -impl AllocatedBit { +impl AllocatedBit { pub fn get_value(&self) -> Option { self.value } - pub fn get_variable(&self) -> Var { + pub fn get_variable(&self) -> Variable { self.variable } @@ -40,7 +41,7 @@ impl AllocatedBit { value: Option, ) -> Result where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { let var = cs.alloc(|| "boolean", || { if *value.get()? { @@ -52,12 +53,11 @@ impl AllocatedBit { // Constrain: (1 - a) * a = 0 // This constrains a to be either 0 or 1. - let one = cs.one(); cs.enforce( || "boolean constraint", - LinearCombination::zero() + one - var, - LinearCombination::zero() + var, - LinearCombination::zero() + |lc| lc + CS::one() - var, + |lc| lc + var, + |lc| lc ); Ok(AllocatedBit { @@ -74,7 +74,7 @@ impl AllocatedBit { b: &Self ) -> Result where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { let mut result_value = None; @@ -107,9 +107,9 @@ impl AllocatedBit { // (a + a) * b = a + b - c cs.enforce( || "xor constraint", - LinearCombination::zero() + a.variable + a.variable, - LinearCombination::zero() + b.variable, - LinearCombination::zero() + a.variable + b.variable - result_var + |lc| lc + a.variable + a.variable, + |lc| lc + b.variable, + |lc| lc + a.variable + b.variable - result_var ); Ok(AllocatedBit { @@ -126,7 +126,7 @@ impl AllocatedBit { b: &Self ) -> Result where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { let mut result_value = None; @@ -146,9 +146,9 @@ impl AllocatedBit { // a AND b are both 1. cs.enforce( || "and constraint", - LinearCombination::zero() + a.variable, - LinearCombination::zero() + b.variable, - LinearCombination::zero() + result_var + |lc| lc + a.variable, + |lc| lc + b.variable, + |lc| lc + result_var ); Ok(AllocatedBit { @@ -164,7 +164,7 @@ impl AllocatedBit { b: &Self ) -> Result where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { let mut result_value = None; @@ -182,12 +182,11 @@ impl AllocatedBit { // Constrain (a) * (1 - b) = (c), ensuring c is 1 iff // a is true and b is false, and otherwise c is 0. - let one = cs.one(); cs.enforce( || "and not constraint", - LinearCombination::zero() + a.variable, - LinearCombination::zero() + one - b.variable, - LinearCombination::zero() + result_var + |lc| lc + a.variable, + |lc| lc + CS::one() - b.variable, + |lc| lc + result_var ); Ok(AllocatedBit { @@ -203,7 +202,7 @@ impl AllocatedBit { b: &Self ) -> Result where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { let mut result_value = None; @@ -221,12 +220,11 @@ impl AllocatedBit { // Constrain (1 - a) * (1 - b) = (c), ensuring c is 1 iff // a and b are both false, and otherwise c is 0. - let one = cs.one(); cs.enforce( || "nor constraint", - LinearCombination::zero() + one - a.variable, - LinearCombination::zero() + one - b.variable, - LinearCombination::zero() + result_var + |lc| lc + CS::one() - a.variable, + |lc| lc + CS::one() - b.variable, + |lc| lc + result_var ); Ok(AllocatedBit { @@ -239,23 +237,23 @@ impl AllocatedBit { /// This is a boolean value which may be either a constant or /// an interpretation of an `AllocatedBit`. #[derive(Clone)] -pub enum Boolean { +pub enum Boolean { /// Existential view of the boolean variable - Is(AllocatedBit), + Is(AllocatedBit), /// Negated view of the boolean variable - Not(AllocatedBit), + Not(AllocatedBit), /// Constant (not an allocated variable) Constant(bool) } -impl Boolean { +impl Boolean { pub fn enforce_equal( mut cs: CS, a: &Self, b: &Self ) -> Result<(), SynthesisError> where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { let c = Self::xor(&mut cs, a, b)?; @@ -270,21 +268,25 @@ impl Boolean { } } - pub fn lc(&self, one: Var, coeff: E::Fr) -> LinearCombination + pub fn lc( + &self, + one: Variable, + coeff: E::Fr + ) -> LinearCombination { match self { &Boolean::Constant(c) => { if c { - LinearCombination::::zero() + (coeff, one) + LinearCombination::::zero() + (coeff, one) } else { - LinearCombination::::zero() + LinearCombination::::zero() } }, &Boolean::Is(ref v) => { - LinearCombination::::zero() + (coeff, v.get_variable()) + LinearCombination::::zero() + (coeff, v.get_variable()) }, &Boolean::Not(ref v) => { - LinearCombination::::zero() + (coeff, one) - (coeff, v.get_variable()) + LinearCombination::::zero() + (coeff, one) - (coeff, v.get_variable()) } } } @@ -310,7 +312,7 @@ impl Boolean { b: &'a Self ) -> Result where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { match (a, b) { (&Boolean::Constant(false), x) | (x, &Boolean::Constant(false)) => Ok(x.clone()), @@ -337,7 +339,7 @@ impl Boolean { b: &'a Self ) -> Result where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { match (a, b) { // false AND x is always false @@ -364,7 +366,7 @@ impl Boolean { bits: &[Self] ) -> Result where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { assert!(bits.len() > 0); let mut bits = bits.iter(); @@ -387,7 +389,7 @@ impl Boolean { bits: &[Self] ) -> Result<(), SynthesisError> where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { let res = Self::kary_and(&mut cs, bits)?; @@ -396,25 +398,24 @@ impl Boolean { Ok(()) }, Boolean::Constant(true) => { - Err(SynthesisError::AssignmentMissing) + Err(SynthesisError::Unsatisfiable) }, Boolean::Is(ref res) => { cs.enforce( || "enforce nand", - LinearCombination::zero(), - LinearCombination::zero(), - LinearCombination::zero() + res.get_variable() + |lc| lc, + |lc| lc, + |lc| lc + res.get_variable() ); Ok(()) }, Boolean::Not(ref res) => { - let one = cs.one(); cs.enforce( || "enforce nand", - LinearCombination::zero(), - LinearCombination::zero(), - LinearCombination::zero() + one - res.get_variable() + |lc| lc, + |lc| lc, + |lc| lc + CS::one() - res.get_variable() ); Ok(()) @@ -429,7 +430,7 @@ impl Boolean { bits: &[Self] ) -> Result<(), SynthesisError> where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { assert_eq!(bits.len(), F::NUM_BITS as usize); @@ -440,7 +441,7 @@ impl Boolean { b.sub_noborrow(&1.into()); // Runs of ones in r - let mut last_run = Boolean::::constant(true); + let mut last_run = Boolean::constant(true); let mut current_run = vec![]; let mut found_one = false; @@ -495,8 +496,8 @@ impl Boolean { } } -impl From> for Boolean { - fn from(b: AllocatedBit) -> Boolean { +impl From for Boolean { + fn from(b: AllocatedBit) -> Boolean { Boolean::Is(b) } } diff --git a/src/circuit/lookup.rs b/src/circuit/lookup.rs index d44d5d36f..e433cd087 100644 --- a/src/circuit/lookup.rs +++ b/src/circuit/lookup.rs @@ -3,8 +3,7 @@ use super::*; use super::num::AllocatedNum; use super::boolean::Boolean; use bellman::{ - ConstraintSystem, - LinearCombination + ConstraintSystem }; // Synthesize the constants for each base pattern. @@ -32,12 +31,12 @@ fn synth<'a, E: Engine, I>( /// Performs a 3-bit window table lookup. `bits` is in /// little-endian order. -pub fn lookup3_xy( +pub fn lookup3_xy( mut cs: CS, - bits: &[Boolean], + bits: &[Boolean], coords: &[(E::Fr, E::Fr)] -) -> Result<(AllocatedNum, AllocatedNum), SynthesisError> - where CS: ConstraintSystem +) -> Result<(AllocatedNum, AllocatedNum), SynthesisError> + where CS: ConstraintSystem { assert_eq!(bits.len(), 3); assert_eq!(coords.len(), 8); @@ -85,34 +84,34 @@ pub fn lookup3_xy( let precomp = Boolean::and(cs.namespace(|| "precomp"), &bits[1], &bits[2])?; - let one = cs.one(); + let one = CS::one(); cs.enforce( || "x-coordinate lookup", - LinearCombination::::zero() + (x_coeffs[0b001], one) - + &bits[1].lc::(one, x_coeffs[0b011]) - + &bits[2].lc::(one, x_coeffs[0b101]) - + &precomp.lc::(one, x_coeffs[0b111]), - LinearCombination::::zero() + &bits[0].lc::(one, E::Fr::one()), - LinearCombination::::zero() + res_x.get_variable() - - (x_coeffs[0b000], one) - - &bits[1].lc::(one, x_coeffs[0b010]) - - &bits[2].lc::(one, x_coeffs[0b100]) - - &precomp.lc::(one, x_coeffs[0b110]), + |lc| lc + (x_coeffs[0b001], one) + + &bits[1].lc::(one, x_coeffs[0b011]) + + &bits[2].lc::(one, x_coeffs[0b101]) + + &precomp.lc::(one, x_coeffs[0b111]), + |lc| lc + &bits[0].lc::(one, E::Fr::one()), + |lc| lc + res_x.get_variable() + - (x_coeffs[0b000], one) + - &bits[1].lc::(one, x_coeffs[0b010]) + - &bits[2].lc::(one, x_coeffs[0b100]) + - &precomp.lc::(one, x_coeffs[0b110]), ); cs.enforce( || "y-coordinate lookup", - LinearCombination::::zero() + (y_coeffs[0b001], one) - + &bits[1].lc::(one, y_coeffs[0b011]) - + &bits[2].lc::(one, y_coeffs[0b101]) - + &precomp.lc::(one, y_coeffs[0b111]), - LinearCombination::::zero() + &bits[0].lc::(one, E::Fr::one()), - LinearCombination::::zero() + res_y.get_variable() - - (y_coeffs[0b000], one) - - &bits[1].lc::(one, y_coeffs[0b010]) - - &bits[2].lc::(one, y_coeffs[0b100]) - - &precomp.lc::(one, y_coeffs[0b110]), + |lc| lc + (y_coeffs[0b001], one) + + &bits[1].lc::(one, y_coeffs[0b011]) + + &bits[2].lc::(one, y_coeffs[0b101]) + + &precomp.lc::(one, y_coeffs[0b111]), + |lc| lc + &bits[0].lc::(one, E::Fr::one()), + |lc| lc + res_y.get_variable() + - (y_coeffs[0b000], one) + - &bits[1].lc::(one, y_coeffs[0b010]) + - &bits[2].lc::(one, y_coeffs[0b100]) + - &precomp.lc::(one, y_coeffs[0b110]), ); Ok((res_x, res_y)) @@ -120,12 +119,12 @@ pub fn lookup3_xy( /// Performs a 3-bit window table lookup, where /// one of the bits is a sign bit. -pub fn lookup3_xy_with_conditional_negation( +pub fn lookup3_xy_with_conditional_negation( mut cs: CS, - bits: &[Boolean], + bits: &[Boolean], coords: &[(E::Fr, E::Fr)] -) -> Result<(AllocatedNum, AllocatedNum), SynthesisError> - where CS: ConstraintSystem +) -> Result<(AllocatedNum, AllocatedNum), SynthesisError> + where CS: ConstraintSystem { assert_eq!(bits.len(), 3); assert_eq!(coords.len(), 4); @@ -162,7 +161,7 @@ pub fn lookup3_xy_with_conditional_negation( } )?; - let one = cs.one(); + let one = CS::one(); // Compute the coefficients for the lookup constraints let mut x_coeffs = [E::Fr::zero(); 4]; @@ -172,22 +171,22 @@ pub fn lookup3_xy_with_conditional_negation( cs.enforce( || "x-coordinate lookup", - LinearCombination::::zero() + (x_coeffs[0b01], one) - + &bits[1].lc::(one, x_coeffs[0b11]), - LinearCombination::::zero() + &bits[0].lc::(one, E::Fr::one()), - LinearCombination::::zero() + res_x.get_variable() - - (x_coeffs[0b00], one) - - &bits[1].lc::(one, x_coeffs[0b10]) + |lc| lc + (x_coeffs[0b01], one) + + &bits[1].lc::(one, x_coeffs[0b11]), + |lc| lc + &bits[0].lc::(one, E::Fr::one()), + |lc| lc + res_x.get_variable() + - (x_coeffs[0b00], one) + - &bits[1].lc::(one, x_coeffs[0b10]) ); cs.enforce( || "y-coordinate lookup", - LinearCombination::::zero() + (y_coeffs[0b01], one) - + &bits[1].lc::(one, y_coeffs[0b11]), - LinearCombination::::zero() + &bits[0].lc::(one, E::Fr::one()), - LinearCombination::::zero() + res_y.get_variable() - - (y_coeffs[0b00], one) - - &bits[1].lc::(one, y_coeffs[0b10]) + |lc| lc + (y_coeffs[0b01], one) + + &bits[1].lc::(one, y_coeffs[0b11]), + |lc| lc + &bits[0].lc::(one, E::Fr::one()), + |lc| lc + res_y.get_variable() + - (y_coeffs[0b00], one) + - &bits[1].lc::(one, y_coeffs[0b10]) ); let final_y = res_y.conditionally_negate(&mut cs, &bits[2])?; @@ -290,7 +289,7 @@ mod test { let window_size = 4; - let mut assignment = vec![Fr::zero(); (1 << window_size)]; + let mut assignment = vec![Fr::zero(); 1 << window_size]; let constants: Vec<_> = (0..(1 << window_size)).map(|_| Fr::rand(&mut rng)).collect(); synth::(window_size, &constants, &mut assignment); diff --git a/src/circuit/mod.rs b/src/circuit/mod.rs index c36148704..45de18fd0 100644 --- a/src/circuit/mod.rs +++ b/src/circuit/mod.rs @@ -5,8 +5,8 @@ pub mod boolean; pub mod uint32; pub mod blake2s; pub mod num; -pub mod mont; pub mod lookup; +pub mod mont; pub mod pedersen_hash; use bellman::SynthesisError; diff --git a/src/circuit/mont.rs b/src/circuit/mont.rs index 0141c8ea7..81a2fcbee 100644 --- a/src/circuit/mont.rs +++ b/src/circuit/mont.rs @@ -5,8 +5,7 @@ use pairing::{ use bellman::{ SynthesisError, - ConstraintSystem, - LinearCombination + ConstraintSystem }; use super::{ @@ -27,12 +26,12 @@ use super::lookup::{ use super::boolean::Boolean; -pub struct EdwardsPoint { - pub x: AllocatedNum, - pub y: AllocatedNum +pub struct EdwardsPoint { + pub x: AllocatedNum, + pub y: AllocatedNum } -impl Clone for EdwardsPoint { +impl Clone for EdwardsPoint { fn clone(&self) -> Self { EdwardsPoint { x: self.x.clone(), @@ -44,15 +43,14 @@ impl Clone for EdwardsPoint { /// Perform a fixed-base scalar multiplication with /// `by` being in little-endian bit order. `by` must /// be a multiple of 3. -pub fn fixed_base_multiplication( +pub fn fixed_base_multiplication( mut cs: CS, base: FixedGenerators, - by: &[Boolean], + by: &[Boolean], params: &E::Params -) -> Result, SynthesisError> - where CS: ConstraintSystem, - E: JubjubEngine, - Var: Copy +) -> Result, SynthesisError> + where CS: ConstraintSystem, + E: JubjubEngine { // We're going to chunk the scalar into 3-bit windows, // so let's force the caller to supply the right number @@ -91,10 +89,10 @@ pub fn fixed_base_multiplication( Ok(result.get()?.clone()) } -impl EdwardsPoint { +impl EdwardsPoint { /// This extracts the x-coordinate, which is an injective /// encoding for elements of the prime order subgroup. - pub fn into_num(&self) -> AllocatedNum { + pub fn into_num(&self) -> AllocatedNum { self.x.clone() } @@ -103,9 +101,9 @@ impl EdwardsPoint { pub fn conditionally_select( &self, mut cs: CS, - condition: &Boolean + condition: &Boolean ) -> Result - where CS: ConstraintSystem + where CS: ConstraintSystem { // Compute x' = self.x if condition, and 0 otherwise let x_prime = AllocatedNum::alloc(cs.namespace(|| "x'"), || { @@ -119,12 +117,12 @@ impl EdwardsPoint { // condition * x = x' // if condition is 0, x' must be 0 // if condition is 1, x' must be x - let one = cs.one(); + let one = CS::one(); cs.enforce( || "x' computation", - LinearCombination::::zero() + self.x.get_variable(), - condition.lc(one, E::Fr::one()), - LinearCombination::::zero() + x_prime.get_variable() + |lc| lc + self.x.get_variable(), + |_| condition.lc(one, E::Fr::one()), + |lc| lc + x_prime.get_variable() ); // Compute y' = self.y if condition, and 1 otherwise @@ -141,9 +139,9 @@ impl EdwardsPoint { // if condition is 1, y' must be y cs.enforce( || "y' computation", - LinearCombination::::zero() + self.y.get_variable(), - condition.lc(one, E::Fr::one()), - LinearCombination::::zero() + y_prime.get_variable() + |lc| lc + self.y.get_variable(), + |_| condition.lc(one, E::Fr::one()), + |lc| lc + y_prime.get_variable() - &condition.not().lc(one, E::Fr::one()) ); @@ -159,10 +157,10 @@ impl EdwardsPoint { pub fn mul( &self, mut cs: CS, - by: &[Boolean], + by: &[Boolean], params: &E::Params ) -> Result - where CS: ConstraintSystem + where CS: ConstraintSystem { // Represents the current "magnitude" of the base // that we're operating over. Starts at self, @@ -210,11 +208,11 @@ impl EdwardsPoint { pub fn interpret( mut cs: CS, - x: &AllocatedNum, - y: &AllocatedNum, + x: &AllocatedNum, + y: &AllocatedNum, params: &E::Params ) -> Result - where CS: ConstraintSystem + where CS: ConstraintSystem { // -x^2 + y^2 = 1 + dx^2y^2 @@ -222,14 +220,14 @@ impl EdwardsPoint { let y2 = y.square(cs.namespace(|| "y^2"))?; let x2y2 = x2.mul(cs.namespace(|| "x^2 y^2"), &y2)?; - let one = cs.one(); + let one = CS::one(); cs.enforce( || "on curve check", - LinearCombination::zero() - x2.get_variable() - + y2.get_variable(), - LinearCombination::zero() + one, - LinearCombination::zero() + one - + (*params.edwards_d(), x2y2.get_variable()) + |lc| lc - x2.get_variable() + + y2.get_variable(), + |lc| lc + one, + |lc| lc + one + + (*params.edwards_d(), x2y2.get_variable()) ); Ok(EdwardsPoint { @@ -243,7 +241,7 @@ impl EdwardsPoint { cs: CS, params: &E::Params ) -> Result - where CS: ConstraintSystem + where CS: ConstraintSystem { self.add(cs, self, params) } @@ -255,7 +253,7 @@ impl EdwardsPoint { other: &Self, params: &E::Params ) -> Result - where CS: ConstraintSystem + where CS: ConstraintSystem { // Compute U = (x1 + y1) * (x2 + y2) let u = AllocatedNum::alloc(cs.namespace(|| "U"), || { @@ -272,11 +270,11 @@ impl EdwardsPoint { cs.enforce( || "U computation", - LinearCombination::::zero() + self.x.get_variable() - + self.y.get_variable(), - LinearCombination::::zero() + other.x.get_variable() - + other.y.get_variable(), - LinearCombination::::zero() + u.get_variable() + |lc| lc + self.x.get_variable() + + self.y.get_variable(), + |lc| lc + other.x.get_variable() + + other.y.get_variable(), + |lc| lc + u.get_variable() ); // Compute A = y2 * x1 @@ -296,9 +294,9 @@ impl EdwardsPoint { cs.enforce( || "C computation", - LinearCombination::::zero() + (*params.edwards_d(), a.get_variable()), - LinearCombination::::zero() + b.get_variable(), - LinearCombination::::zero() + c.get_variable() + |lc| lc + (*params.edwards_d(), a.get_variable()), + |lc| lc + b.get_variable(), + |lc| lc + c.get_variable() ); // Compute x3 = (A + B) / (1 + C) @@ -316,18 +314,18 @@ impl EdwardsPoint { Ok(t0) }, None => { - Err(SynthesisError::AssignmentMissing) + Err(SynthesisError::DivisionByZero) } } })?; - let one = cs.one(); + let one = CS::one(); cs.enforce( || "x3 computation", - LinearCombination::::zero() + one + c.get_variable(), - LinearCombination::::zero() + x3.get_variable(), - LinearCombination::::zero() + a.get_variable() - + b.get_variable() + |lc| lc + one + c.get_variable(), + |lc| lc + x3.get_variable(), + |lc| lc + a.get_variable() + + b.get_variable() ); // Compute y3 = (U - A - B) / (1 - C) @@ -346,18 +344,18 @@ impl EdwardsPoint { Ok(t0) }, None => { - Err(SynthesisError::AssignmentMissing) + Err(SynthesisError::DivisionByZero) } } })?; cs.enforce( || "y3 computation", - LinearCombination::::zero() + one - c.get_variable(), - LinearCombination::::zero() + y3.get_variable(), - LinearCombination::::zero() + u.get_variable() - - a.get_variable() - - b.get_variable() + |lc| lc + one - c.get_variable(), + |lc| lc + y3.get_variable(), + |lc| lc + u.get_variable() + - a.get_variable() + - b.get_variable() ); Ok(EdwardsPoint { @@ -367,12 +365,12 @@ impl EdwardsPoint { } } -pub struct MontgomeryPoint { - x: AllocatedNum, - y: AllocatedNum +pub struct MontgomeryPoint { + x: AllocatedNum, + y: AllocatedNum } -impl MontgomeryPoint { +impl MontgomeryPoint { /// Converts an element in the prime order subgroup into /// a point in the birationally equivalent twisted /// Edwards curve. @@ -380,8 +378,8 @@ impl MontgomeryPoint { &self, mut cs: CS, params: &E::Params - ) -> Result, SynthesisError> - where CS: ConstraintSystem + ) -> Result, SynthesisError> + where CS: ConstraintSystem { // Compute u = (scale*x) / y let u = AllocatedNum::alloc(cs.namespace(|| "u"), || { @@ -395,16 +393,16 @@ impl MontgomeryPoint { Ok(t0) }, None => { - Err(SynthesisError::AssignmentMissing) + Err(SynthesisError::DivisionByZero) } } })?; cs.enforce( || "u computation", - LinearCombination::::zero() + self.y.get_variable(), - LinearCombination::::zero() + u.get_variable(), - LinearCombination::::zero() + (*params.scale(), self.x.get_variable()) + |lc| lc + self.y.get_variable(), + |lc| lc + u.get_variable(), + |lc| lc + (*params.scale(), self.x.get_variable()) ); // Compute v = (x - 1) / (x + 1) @@ -421,19 +419,19 @@ impl MontgomeryPoint { Ok(t0) }, None => { - Err(SynthesisError::AssignmentMissing) + Err(SynthesisError::DivisionByZero) } } })?; - let one = cs.one(); + let one = CS::one(); cs.enforce( || "v computation", - LinearCombination::::zero() + self.x.get_variable() - + one, - LinearCombination::::zero() + v.get_variable(), - LinearCombination::::zero() + self.x.get_variable() - - one, + |lc| lc + self.x.get_variable() + + one, + |lc| lc + v.get_variable(), + |lc| lc + self.x.get_variable() + - one, ); Ok(EdwardsPoint { @@ -447,8 +445,8 @@ impl MontgomeryPoint { /// on the curve. Useful for constants and /// window table lookups. pub fn interpret_unchecked( - x: AllocatedNum, - y: AllocatedNum + x: AllocatedNum, + y: AllocatedNum ) -> Self { MontgomeryPoint { @@ -465,7 +463,7 @@ impl MontgomeryPoint { other: &Self, params: &E::Params ) -> Result - where CS: ConstraintSystem + where CS: ConstraintSystem { // Compute lambda = (y' - y) / (x' - x) let lambda = AllocatedNum::alloc(cs.namespace(|| "lambda"), || { @@ -481,20 +479,20 @@ impl MontgomeryPoint { Ok(n) }, None => { - Err(SynthesisError::AssignmentMissing) + Err(SynthesisError::DivisionByZero) } } })?; cs.enforce( || "evaluate lambda", - LinearCombination::::zero() + other.x.get_variable() - - self.x.get_variable(), + |lc| lc + other.x.get_variable() + - self.x.get_variable(), - LinearCombination::zero() + lambda.get_variable(), + |lc| lc + lambda.get_variable(), - LinearCombination::::zero() + other.y.get_variable() - - self.y.get_variable() + |lc| lc + other.y.get_variable() + - self.y.get_variable() ); // Compute x'' = lambda^2 - A - x - x' @@ -509,15 +507,15 @@ impl MontgomeryPoint { })?; // (lambda) * (lambda) = (A + x + x' + x'') - let one = cs.one(); + let one = CS::one(); cs.enforce( || "evaluate xprime", - LinearCombination::zero() + lambda.get_variable(), - LinearCombination::zero() + lambda.get_variable(), - LinearCombination::::zero() + (*params.montgomery_a(), one) - + self.x.get_variable() - + other.x.get_variable() - + xprime.get_variable() + |lc| lc + lambda.get_variable(), + |lc| lc + lambda.get_variable(), + |lc| lc + (*params.montgomery_a(), one) + + self.x.get_variable() + + other.x.get_variable() + + xprime.get_variable() ); // Compute y' = -(y + lambda(x' - x)) @@ -534,13 +532,13 @@ impl MontgomeryPoint { // y' + y = lambda(x - x') cs.enforce( || "evaluate yprime", - LinearCombination::zero() + self.x.get_variable() - - xprime.get_variable(), + |lc| lc + self.x.get_variable() + - xprime.get_variable(), - LinearCombination::zero() + lambda.get_variable(), + |lc| lc + lambda.get_variable(), - LinearCombination::::zero() + yprime.get_variable() - + self.y.get_variable() + |lc| lc + yprime.get_variable() + + self.y.get_variable() ); Ok(MontgomeryPoint { @@ -556,7 +554,7 @@ impl MontgomeryPoint { mut cs: CS, params: &E::Params ) -> Result - where CS: ConstraintSystem + where CS: ConstraintSystem { // Square x let xx = self.x.square(&mut cs)?; @@ -580,25 +578,25 @@ impl MontgomeryPoint { Ok(t0) }, None => { - Err(SynthesisError::AssignmentMissing) + Err(SynthesisError::DivisionByZero) } } })?; // (2.y) * (lambda) = (3.xx + 2.A.x + 1) - let one = cs.one(); + let one = CS::one(); cs.enforce( || "evaluate lambda", - LinearCombination::::zero() + self.y.get_variable() - + self.y.get_variable(), + |lc| lc + self.y.get_variable() + + self.y.get_variable(), - LinearCombination::zero() + lambda.get_variable(), + |lc| lc + lambda.get_variable(), - LinearCombination::::zero() + xx.get_variable() - + xx.get_variable() - + xx.get_variable() - + (*params.montgomery_2a(), self.x.get_variable()) - + one + |lc| lc + xx.get_variable() + + xx.get_variable() + + xx.get_variable() + + (*params.montgomery_2a(), self.x.get_variable()) + + one ); // Compute x' = (lambda^2) - A - 2.x @@ -615,12 +613,12 @@ impl MontgomeryPoint { // (lambda) * (lambda) = (A + 2.x + x') cs.enforce( || "evaluate xprime", - LinearCombination::zero() + lambda.get_variable(), - LinearCombination::zero() + lambda.get_variable(), - LinearCombination::::zero() + (*params.montgomery_a(), one) - + self.x.get_variable() - + self.x.get_variable() - + xprime.get_variable() + |lc| lc + lambda.get_variable(), + |lc| lc + lambda.get_variable(), + |lc| lc + (*params.montgomery_a(), one) + + self.x.get_variable() + + self.x.get_variable() + + xprime.get_variable() ); // Compute y' = -(y + lambda(x' - x)) @@ -637,13 +635,13 @@ impl MontgomeryPoint { // y' + y = lambda(x - x') cs.enforce( || "evaluate yprime", - LinearCombination::zero() + self.x.get_variable() - - xprime.get_variable(), + |lc| lc + self.x.get_variable() + - xprime.get_variable(), - LinearCombination::zero() + lambda.get_variable(), + |lc| lc + lambda.get_variable(), - LinearCombination::::zero() + yprime.get_variable() - + self.y.get_variable() + |lc| lc + yprime.get_variable() + + self.y.get_variable() ); Ok(MontgomeryPoint { diff --git a/src/circuit/num.rs b/src/circuit/num.rs index 8656e4b7f..aca756276 100644 --- a/src/circuit/num.rs +++ b/src/circuit/num.rs @@ -8,7 +8,8 @@ use pairing::{ use bellman::{ SynthesisError, ConstraintSystem, - LinearCombination + LinearCombination, + Variable }; use super::{ @@ -20,12 +21,12 @@ use super::boolean::{ AllocatedBit }; -pub struct AllocatedNum { +pub struct AllocatedNum { value: Option, - variable: Var + variable: Variable } -impl Clone for AllocatedNum { +impl Clone for AllocatedNum { fn clone(&self) -> Self { AllocatedNum { value: self.value, @@ -34,12 +35,12 @@ impl Clone for AllocatedNum { } } -impl AllocatedNum { +impl AllocatedNum { pub fn alloc( mut cs: CS, value: F, ) -> Result - where CS: ConstraintSystem, + where CS: ConstraintSystem, F: FnOnce() -> Result { let mut new_value = None; @@ -60,8 +61,8 @@ impl AllocatedNum { pub fn into_bits_strict( &self, mut cs: CS - ) -> Result>, SynthesisError> - where CS: ConstraintSystem + ) -> Result, SynthesisError> + where CS: ConstraintSystem { let bits = self.into_bits(&mut cs)?; Boolean::enforce_in_field::<_, _, E::Fr>(&mut cs, &bits)?; @@ -72,8 +73,8 @@ impl AllocatedNum { pub fn into_bits( &self, mut cs: CS - ) -> Result>, SynthesisError> - where CS: ConstraintSystem + ) -> Result, SynthesisError> + where CS: ConstraintSystem { let bit_values = match self.value { Some(value) => { @@ -122,9 +123,9 @@ impl AllocatedNum { cs.enforce( || "unpacking constraint", - LinearCombination::zero(), - LinearCombination::zero(), - lc + |lc| lc, + |lc| lc, + |_| lc ); Ok(bits.into_iter().map(|b| Boolean::from(b)).collect()) @@ -132,16 +133,16 @@ impl AllocatedNum { pub fn from_bits_strict( mut cs: CS, - bits: &[Boolean] + bits: &[Boolean] ) -> Result - where CS: ConstraintSystem + where CS: ConstraintSystem { assert_eq!(bits.len(), E::Fr::NUM_BITS as usize); Boolean::enforce_in_field::<_, _, E::Fr>(&mut cs, bits)?; - let one = cs.one(); - let mut lc = LinearCombination::::zero(); + let one = CS::one(); + let mut lc = LinearCombination::::zero(); let mut coeff = E::Fr::one(); let mut value = Some(E::Fr::zero()); for bit in bits.iter().rev() { @@ -191,9 +192,9 @@ impl AllocatedNum { cs.enforce( || "packing constraint", - LinearCombination::zero(), - LinearCombination::zero(), - lc + |lc| lc, + |lc| lc, + |_| lc ); Ok(num) @@ -204,7 +205,7 @@ impl AllocatedNum { mut cs: CS, other: &Self ) -> Result - where CS: ConstraintSystem + where CS: ConstraintSystem { let mut value = None; @@ -220,9 +221,9 @@ impl AllocatedNum { // Constrain: a * b = ab cs.enforce( || "multiplication constraint", - LinearCombination::zero() + self.variable, - LinearCombination::zero() + other.variable, - LinearCombination::zero() + var + |lc| lc + self.variable, + |lc| lc + other.variable, + |lc| lc + var ); Ok(AllocatedNum { @@ -235,7 +236,7 @@ impl AllocatedNum { &self, mut cs: CS ) -> Result - where CS: ConstraintSystem + where CS: ConstraintSystem { let mut value = None; @@ -251,9 +252,9 @@ impl AllocatedNum { // Constrain: a * a = aa cs.enforce( || "squaring constraint", - LinearCombination::zero() + self.variable, - LinearCombination::zero() + self.variable, - LinearCombination::zero() + var + |lc| lc + self.variable, + |lc| lc + self.variable, + |lc| lc + var ); Ok(AllocatedNum { @@ -266,13 +267,13 @@ impl AllocatedNum { &self, mut cs: CS ) -> Result<(), SynthesisError> - where CS: ConstraintSystem + where CS: ConstraintSystem { let inv = cs.alloc(|| "ephemeral inverse", || { let tmp = *self.value.get()?; if tmp.is_zero() { - Err(SynthesisError::AssignmentMissing) + Err(SynthesisError::DivisionByZero) } else { Ok(tmp.inverse().unwrap()) } @@ -281,12 +282,11 @@ impl AllocatedNum { // Constrain a * inv = 1, which is only valid // iff a has a multiplicative inverse, untrue // for zero. - let one = cs.one(); cs.enforce( || "nonzero assertion constraint", - LinearCombination::zero() + self.variable, - LinearCombination::zero() + inv, - LinearCombination::zero() + one + |lc| lc + self.variable, + |lc| lc + inv, + |lc| lc + CS::one() ); Ok(()) @@ -299,9 +299,9 @@ impl AllocatedNum { mut cs: CS, a: &Self, b: &Self, - condition: &Boolean + condition: &Boolean ) -> Result<(Self, Self), SynthesisError> - where CS: ConstraintSystem + where CS: ConstraintSystem { let c = Self::alloc( cs.namespace(|| "conditional reversal result 1"), @@ -314,12 +314,11 @@ impl AllocatedNum { } )?; - let one = cs.one(); cs.enforce( || "first conditional reversal", - LinearCombination::zero() + a.variable - b.variable, - condition.lc(one, E::Fr::one()), - LinearCombination::zero() + a.variable - c.variable + |lc| lc + a.variable - b.variable, + |_| condition.lc(CS::one(), E::Fr::one()), + |lc| lc + a.variable - c.variable ); let d = Self::alloc( @@ -335,9 +334,9 @@ impl AllocatedNum { cs.enforce( || "second conditional reversal", - LinearCombination::zero() + b.variable - a.variable, - condition.lc(one, E::Fr::one()), - LinearCombination::zero() + b.variable - d.variable + |lc| lc + b.variable - a.variable, + |_| condition.lc(CS::one(), E::Fr::one()), + |lc| lc + b.variable - d.variable ); Ok((c, d)) @@ -346,9 +345,9 @@ impl AllocatedNum { pub fn conditionally_negate( &self, mut cs: CS, - condition: &Boolean + condition: &Boolean ) -> Result - where CS: ConstraintSystem + where CS: ConstraintSystem { let r = Self::alloc( cs.namespace(|| "conditional negation result"), @@ -365,12 +364,11 @@ impl AllocatedNum { // x - 2cx = r // (2x) * (c) = x - r - let one = cs.one(); cs.enforce( || "conditional negation", - LinearCombination::zero() + self.variable + self.variable, - condition.lc(one, E::Fr::one()), - LinearCombination::zero() + self.variable - r.variable + |lc| lc + self.variable + self.variable, + |_| condition.lc(CS::one(), E::Fr::one()), + |lc| lc + self.variable - r.variable ); Ok(r) @@ -380,7 +378,7 @@ impl AllocatedNum { self.value } - pub fn get_variable(&self) -> Var { + pub fn get_variable(&self) -> Variable { self.variable } } diff --git a/src/circuit/pedersen_hash.rs b/src/circuit/pedersen_hash.rs index ee940a382..a405b7a45 100644 --- a/src/circuit/pedersen_hash.rs +++ b/src/circuit/pedersen_hash.rs @@ -10,12 +10,12 @@ use bellman::{ }; use super::lookup::*; -pub fn pedersen_hash( +pub fn pedersen_hash( mut cs: CS, - bits: &[Boolean], + bits: &[Boolean], params: &E::Params -) -> Result, SynthesisError> - where CS: ConstraintSystem +) -> Result, SynthesisError> + where CS: ConstraintSystem { // Unnecessary if forced personalization is introduced assert!(bits.len() > 0); @@ -116,7 +116,7 @@ mod test { let input: Vec = (0..(Fr::NUM_BITS * 2)).map(|_| rng.gen()).collect(); - let input_bools: Vec> = input.iter().enumerate().map(|(i, b)| { + let input_bools: Vec = input.iter().enumerate().map(|(i, b)| { Boolean::from( AllocatedBit::alloc(cs.namespace(|| format!("input {}", i)), Some(*b)).unwrap() ) @@ -143,7 +143,7 @@ mod test { let mut cs = TestConstraintSystem::::new(); - let input_bools: Vec> = input.iter().enumerate().map(|(i, b)| { + let input_bools: Vec = input.iter().enumerate().map(|(i, b)| { Boolean::from( AllocatedBit::alloc(cs.namespace(|| format!("input {}", i)), Some(*b)).unwrap() ) diff --git a/src/circuit/test/mod.rs b/src/circuit/test/mod.rs index 22575e93e..ef042fe62 100644 --- a/src/circuit/test/mod.rs +++ b/src/circuit/test/mod.rs @@ -6,17 +6,13 @@ use pairing::{ use bellman::{ LinearCombination, SynthesisError, - ConstraintSystem + ConstraintSystem, + Variable, + Index }; use std::collections::HashMap; -#[derive(Debug, Copy, Clone)] -pub enum Variable { - Input(usize), - Aux(usize) -} - #[derive(Debug)] enum NamedObject { Constraint(usize), @@ -28,7 +24,12 @@ enum NamedObject { pub struct TestConstraintSystem { named_objects: HashMap, current_namespace: Vec, - constraints: Vec<(LinearCombination, LinearCombination, LinearCombination, String)>, + constraints: Vec<( + LinearCombination, + LinearCombination, + LinearCombination, + String + )>, inputs: Vec<(E::Fr, String)>, aux: Vec<(E::Fr, String)> } @@ -42,9 +43,9 @@ fn eval_lc( let mut acc = E::Fr::zero(); for &(var, ref coeff) in terms { - let mut tmp = match var { - Variable::Input(index) => inputs[index].0, - Variable::Aux(index) => aux[index].0 + let mut tmp = match var.get_unchecked() { + Index::Input(index) => inputs[index].0, + Index::Aux(index) => aux[index].0 }; tmp.mul_assign(&coeff); @@ -57,7 +58,7 @@ fn eval_lc( impl TestConstraintSystem { pub fn new() -> TestConstraintSystem { let mut map = HashMap::new(); - map.insert("ONE".into(), NamedObject::Var(Variable::Input(0))); + map.insert("ONE".into(), NamedObject::Var(TestConstraintSystem::::one())); TestConstraintSystem { named_objects: map, @@ -97,8 +98,12 @@ impl TestConstraintSystem { pub fn set(&mut self, path: &str, to: E::Fr) { match self.named_objects.get(path) { - Some(&NamedObject::Var(Variable::Input(index))) => self.inputs[index].0 = to, - Some(&NamedObject::Var(Variable::Aux(index))) => self.aux[index].0 = to, + Some(&NamedObject::Var(ref v)) => { + match v.get_unchecked() { + Index::Input(index) => self.inputs[index].0 = to, + Index::Aux(index) => self.aux[index].0 = to + } + } Some(e) => panic!("tried to set path `{}` to value, but `{:?}` already exists there.", path, e), _ => panic!("no variable exists at path: {}", path) } @@ -107,8 +112,12 @@ impl TestConstraintSystem { pub fn get(&mut self, path: &str) -> E::Fr { match self.named_objects.get(path) { - Some(&NamedObject::Var(Variable::Input(index))) => self.inputs[index].0, - Some(&NamedObject::Var(Variable::Aux(index))) => self.aux[index].0, + Some(&NamedObject::Var(ref v)) => { + match v.get_unchecked() { + Index::Input(index) => self.inputs[index].0, + Index::Aux(index) => self.aux[index].0 + } + } Some(e) => panic!("tried to get value of path `{}`, but `{:?}` exists there (not a variable)", path, e), _ => panic!("no variable exists at path: {}", path) } @@ -145,42 +154,60 @@ fn compute_path(ns: &[String], this: String) -> String { } impl ConstraintSystem for TestConstraintSystem { - type Variable = Variable; type Root = Self; - fn one(&self) -> Self::Variable { - Variable::Input(0) - } - fn alloc( &mut self, annotation: A, f: F - ) -> Result + ) -> Result where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into { let index = self.aux.len(); let path = compute_path(&self.current_namespace, annotation().into()); self.aux.push((f()?, path.clone())); - let var = Variable::Aux(index); + let var = Variable::new_unchecked(Index::Aux(index)); self.set_named_obj(path, NamedObject::Var(var)); Ok(var) } - fn enforce( + fn alloc_input( &mut self, annotation: A, - a: LinearCombination, - b: LinearCombination, - c: LinearCombination + f: F + ) -> Result + where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + { + let index = self.inputs.len(); + let path = compute_path(&self.current_namespace, annotation().into()); + self.inputs.push((f()?, path.clone())); + let var = Variable::new_unchecked(Index::Input(index)); + self.set_named_obj(path, NamedObject::Var(var)); + + Ok(var) + } + + fn enforce( + &mut self, + annotation: A, + a: LA, + b: LB, + c: LC ) - where A: FnOnce() -> AR, AR: Into + where A: FnOnce() -> AR, AR: Into, + LA: FnOnce(LinearCombination) -> LinearCombination, + LB: FnOnce(LinearCombination) -> LinearCombination, + LC: FnOnce(LinearCombination) -> LinearCombination { let path = compute_path(&self.current_namespace, annotation().into()); let index = self.constraints.len(); self.set_named_obj(path.clone(), NamedObject::Constraint(index)); + let a = a(LinearCombination::zero()); + let b = b(LinearCombination::zero()); + let c = c(LinearCombination::zero()); + self.constraints.push((a, b, c, path)); } @@ -218,21 +245,21 @@ fn test_cs() { cs.enforce( || "mult", - LinearCombination::zero() + a, - LinearCombination::zero() + b, - LinearCombination::zero() + c + |lc| lc + a, + |lc| lc + b, + |lc| lc + c ); assert!(cs.is_satisfied()); assert_eq!(cs.num_constraints(), 1); cs.set("a/var", Fr::from_str("4").unwrap()); - let one = cs.one(); + let one = TestConstraintSystem::::one(); cs.enforce( || "eq", - LinearCombination::zero() + a, - LinearCombination::zero() + one, - LinearCombination::zero() + b + |lc| lc + a, + |lc| lc + one, + |lc| lc + b ); assert!(!cs.is_satisfied()); diff --git a/src/circuit/uint32.rs b/src/circuit/uint32.rs index 7f93879da..ff3943377 100644 --- a/src/circuit/uint32.rs +++ b/src/circuit/uint32.rs @@ -18,13 +18,13 @@ use super::boolean::{ /// Represents an interpretation of 32 `Boolean` objects as an /// unsigned integer. #[derive(Clone)] -pub struct UInt32 { +pub struct UInt32 { // Least significant bit first - bits: Vec>, + bits: Vec, value: Option } -impl UInt32 { +impl UInt32 { /// Construct a constant `UInt32` from a `u32` pub fn constant(value: u32) -> Self { @@ -53,7 +53,7 @@ impl UInt32 { value: Option ) -> Result where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { let values = match value { Some(mut val) => { @@ -72,7 +72,10 @@ impl UInt32 { let bits = values.into_iter() .enumerate() .map(|(i, v)| { - Ok(Boolean::from(AllocatedBit::alloc(cs.namespace(|| format!("allocated bit {}", i)), v)?)) + Ok(Boolean::from(AllocatedBit::alloc( + cs.namespace(|| format!("allocated bit {}", i)), + v + )?)) }) .collect::, SynthesisError>>()?; @@ -83,7 +86,7 @@ impl UInt32 { } /// Turns this `UInt32` into its little-endian byte order representation. - pub fn into_bits(&self) -> Vec> { + pub fn into_bits(&self) -> Vec { self.bits.chunks(8) .flat_map(|v| v.iter().rev()) .cloned() @@ -92,7 +95,7 @@ impl UInt32 { /// Converts a little-endian byte order representation of bits into a /// `UInt32`. - pub fn from_bits(bits: &[Boolean]) -> Self + pub fn from_bits(bits: &[Boolean]) -> Self { assert_eq!(bits.len(), 32); @@ -157,7 +160,7 @@ impl UInt32 { other: &Self ) -> Result where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { let new_value = match (self.value, other.value) { (Some(a), Some(b)) => { @@ -170,7 +173,11 @@ impl UInt32 { .zip(other.bits.iter()) .enumerate() .map(|(i, (a, b))| { - Boolean::xor(cs.namespace(|| format!("xor of bit {}", i)), a, b) + Boolean::xor( + cs.namespace(|| format!("xor of bit {}", i)), + a, + b + ) }) .collect::>()?; @@ -186,7 +193,7 @@ impl UInt32 { operands: &[Self] ) -> Result where E: Engine, - CS: ConstraintSystem + CS: ConstraintSystem { // Make some arbitrary bounds for ourselves to avoid overflows // in the scalar field @@ -235,11 +242,11 @@ impl UInt32 { all_constants = false; // Add coeff * (1 - bit) = coeff * ONE - coeff * bit - lc = lc + (coeff, cs.one()) - (coeff, bit.get_variable()); + lc = lc + (coeff, CS::one()) - (coeff, bit.get_variable()); }, &Boolean::Constant(bit) => { if bit { - lc = lc + (coeff, cs.one()); + lc = lc + (coeff, CS::one()); } } } @@ -266,7 +273,10 @@ impl UInt32 { let mut i = 0; while max_value != 0 { // Allocate the bit - let b = AllocatedBit::alloc(cs.namespace(|| format!("result bit {}", i)), result_value.map(|v| (v >> i) & 1 == 1))?; + let b = AllocatedBit::alloc( + cs.namespace(|| format!("result bit {}", i)), + result_value.map(|v| (v >> i) & 1 == 1) + )?; // Subtract this bit from the linear combination to ensure the sums balance out lc = lc - (coeff, b.get_variable()); @@ -281,9 +291,9 @@ impl UInt32 { // Enforce that the linear combination equals zero cs.enforce( || "modular addition", - LinearCombination::zero(), - LinearCombination::zero(), - lc + |lc| lc, + |lc| lc, + |_| lc ); // Discard carry bits that we don't care about @@ -311,7 +321,7 @@ mod test { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0653]); for _ in 0..1000 { - let mut v = (0..32).map(|_| Boolean::<()>::constant(rng.gen())).collect::>(); + let mut v = (0..32).map(|_| Boolean::constant(rng.gen())).collect::>(); let b = UInt32::from_bits(&v); @@ -473,7 +483,7 @@ mod test { let mut num = rng.gen(); - let a = UInt32::<()>::constant(num); + let a = UInt32::constant(num); for i in 0..32 { let b = a.rotr(i);