diff --git a/r1cs-std/Cargo.toml b/r1cs-std/Cargo.toml index 44c6705..750d3f4 100644 --- a/r1cs-std/Cargo.toml +++ b/r1cs-std/Cargo.toml @@ -41,8 +41,8 @@ full = [ ] bls12_377 = [ "algebra/bls12_377" ] -ed_on_bls12_381 = [ "algebra/ed_on_bls12_381" ] ed_on_bn254 = [ "algebra/ed_on_bn254" ] +ed_on_bls12_381 = [ "algebra/ed_on_bls12_381" ] ed_on_bls12_377 = [ "algebra/ed_on_bls12_377" ] ed_on_cp6_782 = [ "algebra/ed_on_cp6_782" ] ed_on_bw6_761 = [ "algebra/ed_on_bw6_761", "algebra/ed_on_cp6_782" ] @@ -53,5 +53,5 @@ mnt4_753 = [ "algebra/mnt4_753" ] mnt6_298 = [ "algebra/mnt6_298" ] mnt6_753 = [ "algebra/mnt6_753" ] -std = [ "algebra/std" ] +std = [ "algebra/std", "r1cs-core/std" ] parallel = [ "std", "algebra/parallel" ] diff --git a/r1cs-std/src/test_constraint_counter.rs b/r1cs-std/src/test_constraint_counter.rs deleted file mode 100644 index 359f71d..0000000 --- a/r1cs-std/src/test_constraint_counter.rs +++ /dev/null @@ -1,130 +0,0 @@ -use crate::String; -use algebra::Field; -use r1cs_core::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; - -/// Constraint counter for testing purposes. -pub struct ConstraintCounter { - pub num_inputs: usize, - pub num_aux: usize, - pub num_constraints: usize, -} - -impl ConstraintCounter { - pub fn new() -> Self { - Self { - num_aux: 0, - num_inputs: 0, - num_constraints: 0, - } - } - - pub fn num_constraints(&self) -> usize { - self.num_constraints - } -} - -impl ConstraintSystem for ConstraintCounter { - type Root = Self; - - fn alloc(&mut self, _: A, _: F) -> Result - where - F: FnOnce() -> Result, - A: FnOnce() -> AR, - AR: Into, - { - let var = Variable::new_unchecked(Index::Aux(self.num_aux)); - self.num_aux += 1; - Ok(var) - } - - fn alloc_input(&mut self, _: A, _: F) -> Result - where - F: FnOnce() -> Result, - A: FnOnce() -> AR, - AR: Into, - { - let var = Variable::new_unchecked(Index::Input(self.num_inputs)); - self.num_inputs += 1; - - Ok(var) - } - - fn enforce(&mut self, _: A, _: LA, _: LB, _: LC) - where - A: FnOnce() -> AR, - AR: Into, - LA: FnOnce(LinearCombination) -> LinearCombination, - LB: FnOnce(LinearCombination) -> LinearCombination, - LC: FnOnce(LinearCombination) -> LinearCombination, - { - self.num_constraints += 1; - } - - fn push_namespace(&mut self, _: N) - where - NR: Into, - N: FnOnce() -> NR, - { - } - - fn pop_namespace(&mut self) {} - - fn get_root(&mut self) -> &mut Self::Root { - self - } - - fn num_constraints(&self) -> usize { - self.num_constraints - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::test_constraint_system::TestConstraintSystem; - use algebra::{bls12_381::Fq, Field}; - use r1cs_core::{ConstraintSynthesizer, SynthesisError}; - - // circuit proving knowledge of a square root - #[derive(Clone, Debug)] - struct TestCircuit(Option); - - impl ConstraintSynthesizer for TestCircuit { - fn generate_constraints>( - self, - cs: &mut CS, - ) -> Result<(), SynthesisError> { - let x = cs.alloc(|| "x", || self.0.ok_or(SynthesisError::AssignmentMissing))?; - // 1 input! - let out = cs.alloc_input( - || "square", - || { - self.0 - .map(|x| x.square()) - .ok_or(SynthesisError::AssignmentMissing) - }, - )?; - cs.enforce(|| "x * x = x^2", |lc| lc + x, |lc| lc + x, |lc| lc + out); - Ok(()) - } - } - - #[test] - fn test_constraints_counter() { - let empty_circuit = TestCircuit::(None); - let populated_circuit = TestCircuit(Some(Fq::from(10u32))); - - let mut counter = ConstraintCounter::new(); - let mut cs = TestConstraintSystem::new(); - - empty_circuit - .clone() - .generate_constraints(&mut counter) - .unwrap(); - // an empty circuit cannot be used with TestConstraintSystem - empty_circuit.generate_constraints(&mut cs).unwrap_err(); - populated_circuit.generate_constraints(&mut cs).unwrap(); - - assert_eq!(counter.num_constraints(), cs.num_constraints()) - } -} diff --git a/r1cs-std/src/test_constraint_system.rs b/r1cs-std/src/test_constraint_system.rs deleted file mode 100644 index f20a21c..0000000 --- a/r1cs-std/src/test_constraint_system.rs +++ /dev/null @@ -1,233 +0,0 @@ -use crate::{BTreeMap, String, Vec}; -use algebra::Field; -use r1cs_core::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; - -#[derive(Debug)] -enum NamedObject { - Constraint(usize), - Var(Variable), - Namespace, -} - -/// Constraint system for testing purposes. -pub struct TestConstraintSystem { - named_objects: BTreeMap, - current_namespace: Vec, - pub constraints: Vec<( - LinearCombination, - LinearCombination, - LinearCombination, - String, - )>, - inputs: Vec<(ConstraintF, String)>, - aux: Vec<(ConstraintF, String)>, -} - -impl TestConstraintSystem { - fn eval_lc( - terms: &[(Variable, ConstraintF)], - inputs: &[(ConstraintF, String)], - aux: &[(ConstraintF, String)], - ) -> ConstraintF { - let mut acc = ConstraintF::zero(); - - for &(var, ref coeff) in terms { - let mut tmp = match var.get_unchecked() { - Index::Input(index) => inputs[index].0, - Index::Aux(index) => aux[index].0, - }; - - tmp *= coeff; - acc += tmp; - } - - acc - } -} - -impl TestConstraintSystem { - pub fn new() -> TestConstraintSystem { - let mut map = BTreeMap::new(); - map.insert( - "ONE".into(), - NamedObject::Var(TestConstraintSystem::::one()), - ); - - TestConstraintSystem { - named_objects: map, - current_namespace: vec![], - constraints: vec![], - inputs: vec![(ConstraintF::one(), "ONE".into())], - aux: vec![], - } - } - - #[allow(unused_variables)] - pub fn print_named_objects(&self) { - for &(_, _, _, ref name) in &self.constraints { - println!("{}", name); - } - } - - pub fn which_is_unsatisfied(&self) -> Option<&str> { - for &(ref a, ref b, ref c, ref path) in &self.constraints { - let mut a = Self::eval_lc(a.as_ref(), &self.inputs, &self.aux); - let b = Self::eval_lc(b.as_ref(), &self.inputs, &self.aux); - let c = Self::eval_lc(c.as_ref(), &self.inputs, &self.aux); - - a.mul_assign(&b); - - if a != c { - return Some(&*path); - } - } - - None - } - - pub fn is_satisfied(&self) -> bool { - self.which_is_unsatisfied().is_none() - } - - pub fn num_constraints(&self) -> usize { - self.constraints.len() - } - - pub fn set(&mut self, path: &str, to: ConstraintF) { - match self.named_objects.get(path) { - 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), - } - } - - pub fn get(&mut self, path: &str) -> ConstraintF { - match self.named_objects.get(path) { - 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), - } - } - - fn set_named_obj(&mut self, path: String, to: NamedObject) { - if self.named_objects.get(&path).is_some() { - panic!("tried to create object at existing path: {}", path); - } - - self.named_objects.insert(path, to); - } -} - -fn compute_path(ns: &[String], this: String) -> String { - if this.chars().any(|a| a == '/') { - panic!( - "'/' is not allowed in namespaces. Error in namespace '{}'", - this - ); - } - - let mut name = String::new(); - - let mut needs_separation = false; - for ns in ns.iter().chain(Some(&this).into_iter()) { - if needs_separation { - name += "/"; - } - - name += ns; - needs_separation = true; - } - - name -} - -impl ConstraintSystem for TestConstraintSystem { - type Root = Self; - - fn alloc(&mut self, annotation: A, f: F) -> 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::new_unchecked(Index::Aux(index)); - self.set_named_obj(path, NamedObject::Var(var)); - - Ok(var) - } - - fn alloc_input(&mut self, annotation: A, 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, - 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 mut a = a(LinearCombination::zero()); - let mut b = b(LinearCombination::zero()); - let mut c = c(LinearCombination::zero()); - a.0.shrink_to_fit(); - b.0.shrink_to_fit(); - c.0.shrink_to_fit(); - - self.constraints.push((a, b, c, path)); - } - - fn push_namespace(&mut self, name_fn: N) - where - NR: Into, - N: FnOnce() -> NR, - { - let name = name_fn().into(); - let path = compute_path(&self.current_namespace, name.clone()); - self.set_named_obj(path, NamedObject::Namespace); - self.current_namespace.push(name); - } - - fn pop_namespace(&mut self) { - assert!(self.current_namespace.pop().is_some()); - } - - fn get_root(&mut self) -> &mut Self::Root { - self - } - - fn num_constraints(&self) -> usize { - self.constraints.len() - } -}