|
|
|
@ -422,222 +422,3 @@ impl<'cs, E: Engine, CS: ConstraintSystem<E>> ConstraintSystem<E> for &'cs mut C
|
|
|
|
|
(**self).get_root() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// #[test]
|
|
|
|
|
// fn test_cs() {
|
|
|
|
|
// use pairing::bls12_381::{Bls12, Fr};
|
|
|
|
|
|
|
|
|
|
// struct MySillyConstraintSystem<E: Engine> {
|
|
|
|
|
// inputs: Vec<(E::Fr, String)>,
|
|
|
|
|
// aux: Vec<(E::Fr, String)>,
|
|
|
|
|
// constraints: Vec<(LinearCombination<E>, LinearCombination<E>, LinearCombination<E>, String)>,
|
|
|
|
|
// current_namespace: Vec<String>
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// fn compute_path(ns: &[String], this: String) -> String {
|
|
|
|
|
// 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<E: Engine> PublicConstraintSystem<E> for MySillyConstraintSystem<E> {
|
|
|
|
|
// type PublicRoot = Self;
|
|
|
|
|
|
|
|
|
|
// fn alloc_input<F, A, AR>(
|
|
|
|
|
// &mut self,
|
|
|
|
|
// annotation: A,
|
|
|
|
|
// f: F
|
|
|
|
|
// ) -> Result<Variable, SynthesisError>
|
|
|
|
|
// where F: FnOnce() -> Result<E::Fr, SynthesisError>, A: FnOnce() -> AR, AR: Into<String>
|
|
|
|
|
// {
|
|
|
|
|
// let index = self.inputs.len();
|
|
|
|
|
// let path = compute_path(&self.current_namespace, annotation().into());
|
|
|
|
|
// self.inputs.push((f()?, path));
|
|
|
|
|
|
|
|
|
|
// Ok(Var::Input(index))
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// fn get_public_root(&mut self) -> &mut Self::PublicRoot
|
|
|
|
|
// {
|
|
|
|
|
// self
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// impl<E: Engine> ConstraintSystem<E> for MySillyConstraintSystem<E> {
|
|
|
|
|
// type Variable = Var;
|
|
|
|
|
// type Root = Self;
|
|
|
|
|
|
|
|
|
|
// fn one(&self) -> Variable {
|
|
|
|
|
// Var::Input(0)
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// fn alloc<F, A, AR>(
|
|
|
|
|
// &mut self,
|
|
|
|
|
// annotation: A,
|
|
|
|
|
// f: F
|
|
|
|
|
// ) -> Result<Variable, SynthesisError>
|
|
|
|
|
// where F: FnOnce() -> Result<E::Fr, SynthesisError>, A: FnOnce() -> AR, AR: Into<String>
|
|
|
|
|
// {
|
|
|
|
|
// let index = self.aux.len();
|
|
|
|
|
// let path = compute_path(&self.current_namespace, annotation().into());
|
|
|
|
|
// self.aux.push((f()?, path));
|
|
|
|
|
|
|
|
|
|
// Ok(Var::Aux(index))
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// fn enforce<A, AR, LA, LB, LC>(
|
|
|
|
|
// &mut self,
|
|
|
|
|
// annotation: A,
|
|
|
|
|
// a: LA,
|
|
|
|
|
// b: LB,
|
|
|
|
|
// c: LC
|
|
|
|
|
// )
|
|
|
|
|
// where A: FnOnce() -> AR, AR: Into<String>,
|
|
|
|
|
// LA: FnOnce(LinearCombination<E>) -> LinearCombination<E>,
|
|
|
|
|
// LB: FnOnce(LinearCombination<E>) -> LinearCombination<E>,
|
|
|
|
|
// LC: FnOnce(LinearCombination<E>) -> LinearCombination<E>
|
|
|
|
|
// {
|
|
|
|
|
// let path = compute_path(&self.current_namespace, annotation().into());
|
|
|
|
|
|
|
|
|
|
// let a = a(LinearCombination::zero());
|
|
|
|
|
// let b = b(LinearCombination::zero());
|
|
|
|
|
// let c = c(LinearCombination::zero());
|
|
|
|
|
|
|
|
|
|
// self.constraints.push((a, b, c, path));
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// fn push_namespace<NR, N>(&mut self, name_fn: N)
|
|
|
|
|
// where NR: Into<String>, N: FnOnce() -> NR
|
|
|
|
|
// {
|
|
|
|
|
// self.current_namespace.push(name_fn().into());
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// fn pop_namespace(&mut self)
|
|
|
|
|
// {
|
|
|
|
|
// self.current_namespace.pop();
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// fn get_root(&mut self) -> &mut Self::Root
|
|
|
|
|
// {
|
|
|
|
|
// self
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// fn do_stuff_with_pcs<E: Engine, CS: PublicConstraintSystem<E>>(mut cs: CS, one_more: bool)
|
|
|
|
|
// {
|
|
|
|
|
// cs.alloc_input(|| "something", || Ok(E::Fr::zero())).unwrap();
|
|
|
|
|
|
|
|
|
|
// if one_more {
|
|
|
|
|
// do_stuff_with_pcs(cs.namespace_public(|| "cool namespace"), false);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// let mut cs = MySillyConstraintSystem::<Bls12> {
|
|
|
|
|
// inputs: vec![(Fr::one(), "ONE".into())],
|
|
|
|
|
// aux: vec![],
|
|
|
|
|
// constraints: vec![],
|
|
|
|
|
// current_namespace: vec![]
|
|
|
|
|
// };
|
|
|
|
|
// cs.alloc(|| "something", || Ok(Fr::zero())).unwrap();
|
|
|
|
|
// assert_eq!(cs.inputs, vec![(Fr::one(), "ONE".into())]);
|
|
|
|
|
// assert_eq!(cs.aux, vec![(Fr::zero(), "something".into())]);
|
|
|
|
|
// {
|
|
|
|
|
// let mut cs = cs.namespace(|| "woohoo");
|
|
|
|
|
|
|
|
|
|
// cs.alloc(|| "whatever", || Ok(Fr::one())).unwrap();
|
|
|
|
|
// cs.alloc(|| "you", || Ok(Fr::zero())).unwrap();
|
|
|
|
|
// cs.alloc(|| "say", || Ok(Fr::one())).unwrap();
|
|
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
// let mut cs = cs.namespace(|| "hehe");
|
|
|
|
|
|
|
|
|
|
// let v1 = cs.alloc(|| "hehe, indeed", || Ok(Fr::one())).unwrap();
|
|
|
|
|
// let v2 = cs.alloc_input(|| "works lol", || Ok(Fr::zero())).unwrap();
|
|
|
|
|
|
|
|
|
|
// let one = cs.one();
|
|
|
|
|
|
|
|
|
|
// cs.enforce(
|
|
|
|
|
// || "great constraint",
|
|
|
|
|
// |lc| lc + v1,
|
|
|
|
|
// |lc| lc + one,
|
|
|
|
|
// |lc| lc + v2
|
|
|
|
|
// );
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// assert_eq!(cs.aux, vec![
|
|
|
|
|
// (Fr::zero(), "something".into()),
|
|
|
|
|
// (Fr::one(), "woohoo/whatever".into()),
|
|
|
|
|
// (Fr::zero(), "woohoo/you".into()),
|
|
|
|
|
// (Fr::one(), "woohoo/say".into()),
|
|
|
|
|
// (Fr::one(), "woohoo/hehe/hehe, indeed".into()),
|
|
|
|
|
// ]);
|
|
|
|
|
// assert_eq!(cs.inputs, vec![
|
|
|
|
|
// (Fr::one(), "ONE".into()),
|
|
|
|
|
// (Fr::zero(), "woohoo/hehe/works lol".into()),
|
|
|
|
|
// ]);
|
|
|
|
|
// assert!(cs.constraints.len() == 1);
|
|
|
|
|
// assert!((cs.constraints[0].0).0 == vec![(Var::Aux(4), Fr::one())]);
|
|
|
|
|
// assert!((cs.constraints[0].1).0 == vec![(Var::Input(0), Fr::one())]);
|
|
|
|
|
// assert!((cs.constraints[0].2).0 == vec![(Var::Input(1), Fr::one())]);
|
|
|
|
|
// assert!(cs.constraints[0].3 == "woohoo/hehe/great constraint");
|
|
|
|
|
|
|
|
|
|
// do_stuff_with_pcs(cs.namespace(|| "namey"), true);
|
|
|
|
|
|
|
|
|
|
// assert_eq!(cs.inputs, vec![
|
|
|
|
|
// (Fr::one(), "ONE".into()),
|
|
|
|
|
// (Fr::zero(), "woohoo/hehe/works lol".into()),
|
|
|
|
|
// (Fr::zero(), "namey/something".into()),
|
|
|
|
|
// (Fr::zero(), "namey/cool namespace/something".into()),
|
|
|
|
|
// ]);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// #[test]
|
|
|
|
|
// fn test_lc() {
|
|
|
|
|
// use pairing::bls12_381::{Bls12, Fr};
|
|
|
|
|
// use pairing::PrimeField;
|
|
|
|
|
|
|
|
|
|
// let a = LinearCombination::<Bls12>::zero() + 0usize + 1usize + 2usize - 3usize;
|
|
|
|
|
|
|
|
|
|
// let mut negone = Fr::one();
|
|
|
|
|
// negone.negate();
|
|
|
|
|
|
|
|
|
|
// assert_eq!(a.0, vec![(0usize, Fr::one()), (1usize, Fr::one()), (2usize, Fr::one()), (3usize, negone)]);
|
|
|
|
|
|
|
|
|
|
// let x = LinearCombination::<Bls12>::zero() + (Fr::one(), 0usize) - (Fr::one(), 1usize);
|
|
|
|
|
// let y = LinearCombination::<Bls12>::zero() + (Fr::one(), 2usize) - (Fr::one(), 3usize);
|
|
|
|
|
// let z = x.clone() + &y - &y;
|
|
|
|
|
|
|
|
|
|
// assert_eq!(z.0, vec![
|
|
|
|
|
// (0usize, Fr::one()),
|
|
|
|
|
// (1usize, negone),
|
|
|
|
|
// (2usize, Fr::one()),
|
|
|
|
|
// (3usize, negone),
|
|
|
|
|
// (2usize, negone),
|
|
|
|
|
// (3usize, Fr::one())
|
|
|
|
|
// ]);
|
|
|
|
|
|
|
|
|
|
// let coeff = Fr::from_str("3").unwrap();
|
|
|
|
|
// let mut neg_coeff = coeff;
|
|
|
|
|
// neg_coeff.negate();
|
|
|
|
|
// let z = x + (coeff, &y) - (coeff, &y);
|
|
|
|
|
|
|
|
|
|
// assert_eq!(z.0, vec![
|
|
|
|
|
// (0usize, Fr::one()),
|
|
|
|
|
// (1usize, negone),
|
|
|
|
|
// (2usize, Fr::from_str("3").unwrap()),
|
|
|
|
|
// (3usize, neg_coeff),
|
|
|
|
|
// (2usize, neg_coeff),
|
|
|
|
|
// (3usize, Fr::from_str("3").unwrap())
|
|
|
|
|
// ]);
|
|
|
|
|
// }
|
|
|
|
|