From a0aaf7a6e4a491193a544bc9f51f7e1eb7dd0816 Mon Sep 17 00:00:00 2001 From: Alex Vlasov Date: Fri, 15 Mar 2019 18:00:52 +0300 Subject: [PATCH] temporary commit --- src/sonic/S_poly.pdf | Bin 0 -> 82009 bytes src/sonic/helped/adapted_verifier.rs | 49 -- src/sonic/helped/poly.rs | 6 +- src/sonic/helped/prover.rs | 1 - src/sonic/tests/sonics.rs | 98 +++ src/sonic/unhelped/mod.rs | 1 + src/sonic/unhelped/padding.rs | 686 +++++++++++++++++++++ src/sonic/unhelped/permutation_argument.rs | 2 - src/sonic/util.rs | 10 +- 9 files changed, 793 insertions(+), 60 deletions(-) create mode 100644 src/sonic/S_poly.pdf create mode 100644 src/sonic/unhelped/padding.rs diff --git a/src/sonic/S_poly.pdf b/src/sonic/S_poly.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a3d626e0757a456cb9e1e72c29000908d483c6fa GIT binary patch literal 82009 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�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 literal 0 HcmV?d00001 diff --git a/src/sonic/helped/adapted_verifier.rs b/src/sonic/helped/adapted_verifier.rs index 0a4b159..83bfa72 100644 --- a/src/sonic/helped/adapted_verifier.rs +++ b/src/sonic/helped/adapted_verifier.rs @@ -51,52 +51,3 @@ pub fn verify_aggregate + Clone, R: Rng>( } -// #[test] -// fn my_fun_circuit_test() { -// use pairing::ff::PrimeField; -// use pairing::bls12_381::{Bls12, Fr}; -// use super::*; -// use crate::sonic::cs::{Basic, ConstraintSystem, LinearCombination}; - -// struct MyCircuit; - -// impl Circuit for MyCircuit { -// fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { -// let (a, b, _) = cs.multiply(|| { -// Ok(( -// E::Fr::from_str("10").unwrap(), -// E::Fr::from_str("20").unwrap(), -// E::Fr::from_str("200").unwrap(), -// )) -// })?; - -// cs.enforce_zero(LinearCombination::from(a) + a - b); - -// //let multiplier = cs.alloc_input(|| Ok(E::Fr::from_str("20").unwrap()))?; - -// //cs.enforce_zero(LinearCombination::from(b) - multiplier); - -// Ok(()) -// } -// } - -// let srs = SRS::::new( -// 20, -// Fr::from_str("22222").unwrap(), -// Fr::from_str("33333333").unwrap(), -// ); -// let proof = create_proof_on_srs::(&MyCircuit, &srs).unwrap(); - -// use std::time::{Instant}; -// let start = Instant::now(); -// let mut batch = MultiVerifier::::new(MyCircuit, &srs).unwrap(); - -// for _ in 0..1 { -// batch.add_proof(&proof, &[/*Fr::from_str("20").unwrap()*/], |_, _| None); -// } - -// assert!(batch.check_all()); - -// let elapsed = start.elapsed(); -// println!("time to verify: {:?}", elapsed); -// } diff --git a/src/sonic/helped/poly.rs b/src/sonic/helped/poly.rs index 58b046e..e16325e 100644 --- a/src/sonic/helped/poly.rs +++ b/src/sonic/helped/poly.rs @@ -74,11 +74,11 @@ impl SxEval { let mut acc = E::Fr::zero(); - let mut tmp = x_inv; + let tmp = x_inv; acc.add_assign(&evaluate_at_consequitive_powers(& self.u[..], tmp, tmp)); - let mut tmp = x; + let tmp = x; acc.add_assign(&evaluate_at_consequitive_powers(& self.v[..], tmp, tmp)); - let mut tmp = x.pow(&[(self.v.len()+1) as u64]); + let tmp = x.pow(&[(self.v.len()+1) as u64]); acc.add_assign(&evaluate_at_consequitive_powers(& self.w[..], tmp, x)); // let mut tmp = x_inv; diff --git a/src/sonic/helped/prover.rs b/src/sonic/helped/prover.rs index 2624bfc..d6558bf 100644 --- a/src/sonic/helped/prover.rs +++ b/src/sonic/helped/prover.rs @@ -240,7 +240,6 @@ pub fn create_proof_on_srs, S: SynthesisDriver>( rx1.push(E::Fr::zero()); rx1.extend(wires.a); - let mut rxy = rx1.clone(); let y_inv = y.inverse().ok_or(SynthesisError::DivisionByZero)?; diff --git a/src/sonic/tests/sonics.rs b/src/sonic/tests/sonics.rs index 114a061..cbea80c 100644 --- a/src/sonic/tests/sonics.rs +++ b/src/sonic/tests/sonics.rs @@ -539,4 +539,102 @@ fn test_high_level_sonic_api() { println!("done in {:?}", start.elapsed()); } } +} + +#[test] +fn test_constraints_info() { + use pairing::bn256::{Bn256}; + use std::time::{Instant}; + use crate::sonic::unhelped::padding::{constraints_info}; + { + // This may not be cryptographically safe, use + // `OsRng` (for example) in production software. + let mut rng = &mut thread_rng(); + + // Generate the MiMC round constants + let constants = (0..MIMC_ROUNDS).map(|_| rng.gen()).collect::>(); + + let xl = rng.gen(); + let xr = rng.gen(); + let image = mimc::(xl, xr, &constants); + + // Create an instance of our circuit (with the + // witness) + let circuit = MiMCDemo { + xl: Some(xl), + xr: Some(xr), + constants: &constants + }; + + constraints_info::(circuit.clone()); + } +} + +#[test] +fn test_padding_using_mimc() { + use pairing::ff::{Field, PrimeField}; + use pairing::{Engine, CurveAffine, CurveProjective}; + use pairing::bls12_381::{Bls12, Fr}; + use std::time::{Instant}; + use crate::sonic::srs::SRS; + + let srs_x = Fr::from_str("23923").unwrap(); + let srs_alpha = Fr::from_str("23728792").unwrap(); + println!("making srs"); + let start = Instant::now(); + let srs = SRS::::dummy(830564, srs_x, srs_alpha); + println!("done in {:?}", start.elapsed()); + + { + // This may not be cryptographically safe, use + // `OsRng` (for example) in production software. + let rng = &mut thread_rng(); + + // Generate the MiMC round constants + let constants = (0..MIMC_ROUNDS).map(|_| rng.gen()).collect::>(); + let samples: usize = 100; + + let xl = rng.gen(); + let xr = rng.gen(); + let image = mimc::(xl, xr, &constants); + + // Create an instance of our circuit (with the + // witness) + let circuit = MiMCDemoNoInputs { + xl: Some(xl), + xr: Some(xr), + image: Some(image), + constants: &constants + }; + + use crate::sonic::cs::Basic; + use crate::sonic::sonic::AdaptorCircuit; + use crate::sonic::helped::prover::{create_advice_on_srs, create_proof_on_srs}; + use crate::sonic::helped::{MultiVerifier, get_circuit_parameters}; + use crate::sonic::helped::helper::{create_aggregate_on_srs}; + use crate::sonic::unhelped::padding::Padding; + + let info = get_circuit_parameters::(circuit.clone()).expect("Must get circuit info"); + println!("{:?}", info); + + println!("creating proof"); + let start = Instant::now(); + let proof = create_proof_on_srs::(&AdaptorCircuit(circuit.clone()), &srs).unwrap(); + println!("done in {:?}", start.elapsed()); + + { + let rng = thread_rng(); + let mut verifier = MultiVerifier::::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap(); + println!("K map = {:?}", verifier.get_k_map()); + println!("verifying 1 proof without advice"); + let start = Instant::now(); + { + for _ in 0..1 { + verifier.add_proof(&proof, &[], |_, _| None); + } + assert_eq!(verifier.check_all(), true); // TODO + } + println!("done in {:?}", start.elapsed()); + } + } } \ No newline at end of file diff --git a/src/sonic/unhelped/mod.rs b/src/sonic/unhelped/mod.rs index 7c54dec..4cece77 100644 --- a/src/sonic/unhelped/mod.rs +++ b/src/sonic/unhelped/mod.rs @@ -7,5 +7,6 @@ mod s2_proof; mod wellformed_argument; mod grand_product_argument; mod permutation_argument; +pub mod padding; pub use self::wellformed_argument::{WellformednessArgument, WellformednessProof}; \ No newline at end of file diff --git a/src/sonic/unhelped/padding.rs b/src/sonic/unhelped/padding.rs new file mode 100644 index 0000000..99229ff --- /dev/null +++ b/src/sonic/unhelped/padding.rs @@ -0,0 +1,686 @@ +use pairing::ff::{Field}; +use pairing::{Engine, CurveProjective}; +use std::marker::PhantomData; + +use crate::sonic::cs::{Backend}; +use crate::sonic::cs::{Coeff, Variable, LinearCombination}; +use crate::sonic::util::*; +use crate::sonic::util::*; +use crate::sonic::cs::{SynthesisDriver}; +use crate::Circuit as BellmanCircuit; +use crate::sonic::sonic::AdaptorCircuit; +use crate::sonic::cs::Circuit; +use crate::sonic::cs::ConstraintSystem; +use crate::sonic::cs::Nonassigning; +use crate::SynthesisError; + +/* +s_1(X, Y) = \sum\limits_{i=1}^N u_i(Y) X^{N + 1 - i} + + \sum\limits_{i=1}^N v_i(Y) X^{N + 1 + i} + + \sum\limits_{i=1}^N w_i(Y) X^{2N + 1 + i} + +where + + u_i(Y) = \sum\limits_{q=1}^Q Y^{q} u_{i,q} + v_i(Y) = \sum\limits_{q=1}^Q Y^{q} v_{i,q} + w_i(Y) = \sum\limits_{q=1}^Q Y^{q} w_{i,q} + +s_1(X, Y) = \sum\limits_{i=1}^(3N + 1) [u_{N + 1 - i}(Y), v_{i - N - 1}(Y), w_{i - 2N - 1}(Y)] X^{i} + +where [] means concatenation + +if we open up both sums a little it would look like + +// q = 1, +Y * ( X * u_{N, 1} + X^{N + 1} * v_{1, 1} + X^{2N + 1} * w{1, 1}) = Y * (k_0 * X + k_1 * X^{N + 1} + k_2 * X^{2N + 1}) +and for permutation where should exist another term over Y that would have the same structure, but with coefficients permuted, e.g. +Y^{p_1} * (k_1 * X + k_2 * X^{N + 1} + k_0 * X^{2N + 1}) and Y^{p_2} * (k_2 * X + k_0 * X^{N + 1} + k_1 * X^{2N + 1}) +that would result in a sum + + X * (k_0 * Y + k_1 * Y^{p_1} + k_2 * Y^{p_2}) ++ X^{N + 1} * (k_1 * Y + k_2 * Y^{p_1} + k_0 * Y^{p_2}) ++ X^{2N + 1} * (k_2 * Y + k_0 * Y^{p_1} + k_1 * Y^{p_2}) + +and permutations would look like + [k_0, k_1, k_2] + [1 , p_1, p_2] + + [k_0, k_1, k_2] + [p_2, 1 , p_1] + + [k_0, k_1, k_2] + [p_1, p_2, 1 ] + +that would naively mean that k_0 should appear in constraint number 1 for variable number 1 + constraint number p_1 for variable number N + 1 + constraint number p_2 for variable number 2N + 1 + +restructuring strategy: + +where u_{i, q} is a coefficient in a linear constraint for an A type variable number i +that corresponds to the qth multiplication gate + +to make s_1 representable as a permutation we first must synthesize all the normal constraints, +then make what would look like a cyclic shift + expansion + +- imagine that there were originally N variables +- variable A(i) in linear constraint number q had a coefficient of u{i, q} +- add a variable B(i+n) that would have a number + +*/ + +pub struct Debugging { + constraint_num: usize, + u: Vec, + v: Vec, + w: Vec, + _marker: std::marker::PhantomData +} + +impl<'a, E: Engine> Backend for &'a mut Debugging { + fn new_linear_constraint(&mut self) { + self.constraint_num += 1; + self.u.push("".to_string()); + self.v.push("".to_string()); + self.w.push("".to_string()); + } + + fn insert_coefficient(&mut self, var: Variable, coeff: Coeff) { + let one = E::Fr::one(); + let mut minus_one = one; + minus_one.negate(); + match var { + Variable::A(index) => { + let acc = &mut self.u[self.constraint_num - 1]; + match coeff { + Coeff::Zero => { }, + Coeff::One => { + acc.push_str(&format!(" + A{}", index)); + }, + Coeff::NegativeOne => { + acc.push_str(&format!(" - A{}", index)); + }, + Coeff::Full(val) => { + if val == one { + acc.push_str(&format!(" + A{}", index)); + } else if val == minus_one { + acc.push_str(&format!(" - A{}", index)); + } else { + acc.push_str(&format!(" + {}*A{}", val, index)); + } + } + } + } + Variable::B(index) => { + let acc = &mut self.v[self.constraint_num - 1]; + match coeff { + Coeff::Zero => { }, + Coeff::One => { + acc.push_str(&format!(" + B{}", index)); + }, + Coeff::NegativeOne => { + acc.push_str(&format!(" - B{}", index)); + }, + Coeff::Full(val) => { + if val == one { + acc.push_str(&format!(" + B{}", index)); + } else if val == minus_one { + acc.push_str(&format!(" - B{}", index)); + } else { + acc.push_str(&format!(" + {}*B{}", val, index)); + } + } + } + } + Variable::C(index) => { + let acc = &mut self.w[self.constraint_num - 1]; + match coeff { + Coeff::Zero => { }, + Coeff::One => { + acc.push_str(&format!(" + C{}", index)); + }, + Coeff::NegativeOne => { + acc.push_str(&format!(" - C{}", index)); + }, + Coeff::Full(val) => { + if val == one { + acc.push_str(&format!(" + C{}", index)); + } else if val == minus_one { + acc.push_str(&format!(" - C{}", index)); + } else { + acc.push_str(&format!(" + {}*C{}", val, index)); + } + } + } + } + }; + } +} + +pub struct Padding; + +impl SynthesisDriver for Padding { + fn synthesize, B: Backend>(backend: B, circuit: &C) -> Result<(), SynthesisError> { + struct Synthesizer> { + backend: B, + current_variable: Option, + _marker: PhantomData, + q: usize, + n: usize, + } + + impl>Synthesizer { + fn purge_current_var(&mut self) { + match self.current_variable.take() { + Some(index) => { + let var_a = Variable::A(index); + let var_b = Variable::B(index); + let var_c = Variable::C(index); + + let mut product = None; + + let value_a = self.backend.get_var(var_a); + + self.backend.set_var(var_b, || { + let value_b = E::Fr::one(); + product = Some(value_a.ok_or(SynthesisError::AssignmentMissing)?); + product.as_mut().map(|product| product.mul_assign(&value_b)); + + Ok(value_b) + }).expect("should exist by now"); + + self.backend.set_var(var_c, || { + product.ok_or(SynthesisError::AssignmentMissing) + }).expect("should exist by now"); + + self.current_variable = None; + }, + _ => {} + } + } + + fn alloc_one(&mut self) -> Variable { + self.n += 1; + let index = self.n; + assert_eq!(index, 1); + self.backend.new_multiplication_gate(); + + let var_a = Variable::A(1); + let var_b = Variable::B(1); + let var_c = Variable::C(1); + + self.backend.set_var(var_a, || { + Ok(E::Fr::one()) + }).expect("should exist by now"); + + self.backend.set_var(var_b, || { + Ok(E::Fr::one()) + }).expect("should exist by now"); + + self.backend.set_var(var_c, || { + Ok(E::Fr::one()) + }).expect("should exist by now"); + + self.q += 1; + self.backend.new_linear_constraint(); + self.backend.insert_coefficient(var_a, Coeff::One); + self.backend.insert_coefficient(var_b, Coeff::One); + self.backend.insert_coefficient(var_c, Coeff::NegativeOne); + self.backend.new_k_power(self.q); + + var_a + } + } + + impl> ConstraintSystem for Synthesizer { + const ONE: Variable = Variable::A(1); + + fn alloc(&mut self, value: F) -> Result + where + F: FnOnce() -> Result + { + match self.current_variable.take() { + Some(index) => { + let var_a = Variable::A(index); + let var_b = Variable::B(index); + let var_c = Variable::C(index); + + let mut product = None; + + let value_a = self.backend.get_var(var_a); + + self.backend.set_var(var_b, || { + let value_b = value()?; + product = Some(value_a.ok_or(SynthesisError::AssignmentMissing)?); + product.as_mut().map(|product| product.mul_assign(&value_b)); + + Ok(value_b) + })?; + + self.backend.set_var(var_c, || { + product.ok_or(SynthesisError::AssignmentMissing) + })?; + + self.current_variable = None; + + Ok(var_b) + }, + None => { + self.n += 1; + let index = self.n; + self.backend.new_multiplication_gate(); + + let var_a = Variable::A(index); + + self.backend.set_var(var_a, value)?; + + self.current_variable = Some(index); + + Ok(var_a) + } + } + } + + // TODO: allocate input without spawning extra constraints + fn alloc_input(&mut self, value: F) -> Result + where + F: FnOnce() -> Result + { + // self.purge_current_var(); + // self.n += 1; + // self.backend.new_multiplication_gate(); + + // let index = self.n; + + // let var = Variable::A::(index); + + // self.q += 1; + // self.backend.new_k_power(self.q); + // self.backend.self.backend.insert_coefficient(new_var, Coeff::One); + + // it's always going to be + let input_var = self.alloc(value)?; + + self.enforce_zero(LinearCombination::zero() + input_var); + self.backend.new_k_power(self.q-2); + self.backend.new_k_power(self.q-1); + self.backend.new_k_power(self.q); + + Ok(input_var) + } + + fn enforce_zero(&mut self, lc: LinearCombination) + { + self.q += 1; + self.backend.new_linear_constraint(); + + for (var, coeff) in lc.as_ref() { + self.backend.insert_coefficient(*var, *coeff); + } + + // now we need to "rotate" a linear constraint by allocating more dummy variables, so ensuring + // that if for some q (index of LC) there is a coefficient C in front of a variable A(i) (that will result in a term ~ C*Y^{q}*X^{i}) + // then there will be some other q' where there is a coefficient C in front of the variable B(i) + // (that will result in a term ~ C*Y^{q'}*X^{i+N}) and another q'' with C in front of C(i) + // (that will result in a term ~ C*Y^{q''}*X^{i+2N}), so S polynomial is indeed a permutation + + // allocate at max 1 variable to later work with whole gates directly + + self.purge_current_var(); + + use std::collections::HashMap; + + // A -> B, B -> C, C -> A + { + self.q += 1; + self.backend.new_linear_constraint(); + + let mut allocation_map = HashMap::with_capacity(lc.as_ref().len()); + let mut expected_new_index = self.n + 1; + + // determine size of the map + for (var, _) in lc.as_ref() { + match var { + Variable::A(index) => { + if allocation_map.get(index).is_none() && *index != 1 { + allocation_map.insert(*index, expected_new_index); + expected_new_index += 1; + println!("A{} -> B{}", index, expected_new_index); + } + }, + Variable::B(index) => { + if allocation_map.get(index).is_none() && *index != 2 { + allocation_map.insert(*index, expected_new_index); + expected_new_index += 1; + println!("B{} -> C{}", index, expected_new_index); + } + }, + Variable::C(index) => { + if allocation_map.get(index).is_none() && *index != 3 { + allocation_map.insert(*index, expected_new_index); + expected_new_index += 1; + println!("C{} -> A{}", index, expected_new_index); + } + } + } + } + + for _ in 0..allocation_map.len() { + self.backend.new_multiplication_gate(); + self.n += 1; + } + + for (index, new_index) in allocation_map.iter() { + let var_a = Variable::A(*new_index); + let var_b = Variable::B(*new_index); + let var_c = Variable::C(*new_index); + + // A -> B, B -> C, C -> A + let b_val = self.backend.get_var(Variable::A(*index)); + let c_val = self.backend.get_var(Variable::B(*index)); + let a_val = self.backend.get_var(Variable::C(*index)); + + self.backend.set_var(var_a, || { + let value = a_val.ok_or(SynthesisError::AssignmentMissing)?; + + Ok(value) + }).expect("should exist by now"); + + self.backend.set_var(var_b, || { + let value = b_val.ok_or(SynthesisError::AssignmentMissing)?; + + Ok(value) + }).expect("should exist by now"); + + self.backend.set_var(var_c, || { + let value = c_val.ok_or(SynthesisError::AssignmentMissing)?; + + Ok(value) + }).expect("should exist by now"); + + } + + // A -> B, B -> C, C -> A + for (var, coeff) in lc.as_ref() { + let new_var = match var { + Variable::A(index) => { + let var = if *index == 1 { + Variable::B(2) + } else { + let new_index = allocation_map.get(index).unwrap(); + Variable::B(*new_index) + }; + + var + }, + Variable::B(index) => { + let var = if *index == 2 { + Variable::C(3) + } else { + let new_index = allocation_map.get(index).unwrap(); + Variable::C(*new_index) + }; + + var + }, + Variable::C(index) => { + let var = if *index == 3 { + Variable::A(1) + } else { + let new_index = allocation_map.get(index).unwrap(); + Variable::A(*new_index) + }; + + var + } + }; + + self.backend.insert_coefficient(new_var, *coeff); + } + } + + // A -> C, B -> A, C -> B + { + self.q += 1; + self.backend.new_linear_constraint(); + + let mut allocation_map = HashMap::with_capacity(lc.as_ref().len()); + let mut expected_new_index = self.n + 1; + + // determine size of the map + for (var, _) in lc.as_ref() { + match var { + Variable::A(index) => { + if allocation_map.get(index).is_none() && *index != 1 { + allocation_map.insert(*index, expected_new_index); + expected_new_index += 1; + println!("A{} -> C{}", index, expected_new_index); + } + }, + Variable::B(index) => { + if allocation_map.get(index).is_none() && *index != 2 { + allocation_map.insert(*index, expected_new_index); + expected_new_index += 1; + println!("B{} -> A{}", index, expected_new_index); + } + }, + Variable::C(index) => { + if allocation_map.get(index).is_none() && *index != 3 { + allocation_map.insert(*index, expected_new_index); + expected_new_index += 1; + println!("C{} -> B{}", index, expected_new_index); + } + } + } + } + + for _ in 0..allocation_map.len() { + self.backend.new_multiplication_gate(); + self.n += 1; + } + + // A -> C, B -> A, C -> B + for (index, new_index) in allocation_map.iter() { + let var_a = Variable::A(*new_index); + let var_b = Variable::B(*new_index); + let var_c = Variable::C(*new_index); + + let b_val = self.backend.get_var(Variable::C(*index)); + let c_val = self.backend.get_var(Variable::A(*index)); + let a_val = self.backend.get_var(Variable::B(*index)); + + self.backend.set_var(var_a, || { + let value = a_val.ok_or(SynthesisError::AssignmentMissing)?; + + Ok(value) + }).expect("should exist by now"); + + self.backend.set_var(var_b, || { + let value = b_val.ok_or(SynthesisError::AssignmentMissing)?; + + Ok(value) + }).expect("should exist by now"); + + self.backend.set_var(var_c, || { + let value = c_val.ok_or(SynthesisError::AssignmentMissing)?; + + Ok(value) + }).expect("should exist by now"); + } + + // A -> C, B -> A, C -> B + for (var, coeff) in lc.as_ref() { + let new_var = match var { + Variable::A(index) => { + let var = if *index == 1 { + Variable::C(3) + } else { + let new_index = allocation_map.get(index).unwrap(); + Variable::C(*new_index) + }; + + var + }, + Variable::B(index) => { + let var = if *index == 2 { + Variable::A(1) + } else { + let new_index = allocation_map.get(index).unwrap(); + Variable::A(*new_index) + }; + + var + }, + Variable::C(index) => { + let var = if *index == 3 { + Variable::B(2) + } else { + let new_index = allocation_map.get(index).unwrap(); + Variable::B(*new_index) + }; + + var + } + }; + + self.backend.insert_coefficient(new_var, *coeff); + } + } + } + + fn multiply(&mut self, values: F) -> Result<(Variable, Variable, Variable), SynthesisError> + where + F: FnOnce() -> Result<(E::Fr, E::Fr, E::Fr), SynthesisError> + { + self.n += 1; + let index = self.n; + self.backend.new_multiplication_gate(); + + let a = Variable::A(index); + let b = Variable::B(index); + let c = Variable::C(index); + + let mut b_val = None; + let mut c_val = None; + + self.backend.set_var(a, || { + let (a, b, c) = values()?; + + b_val = Some(b); + c_val = Some(c); + + Ok(a) + })?; + + self.backend.set_var(b, || { + b_val.ok_or(SynthesisError::AssignmentMissing) + })?; + + self.backend.set_var(c, || { + c_val.ok_or(SynthesisError::AssignmentMissing) + })?; + + Ok((a, b, c)) + } + + fn get_value(&self, var: Variable) -> Result { + self.backend.get_var(var).ok_or(()) + } + } + + let mut tmp: Synthesizer = Synthesizer { + backend: backend, + current_variable: None, + _marker: PhantomData, + q: 0, + n: 0, + }; + + let one = tmp.alloc_input(|| Ok(E::Fr::one())).expect("should have no issues"); + + match (one, as ConstraintSystem>::ONE) { + (Variable::A(1), Variable::A(1)) => {}, + _ => panic!("one variable is incorrect") + } + + circuit.synthesize(&mut tmp)?; + + println!("Done synthesizing, N = {}, Q = {}", tmp.n, tmp.q); + + Ok(()) + } +} + +pub fn constraints_info + Clone>( + circuit: C, +) +{ + let adapted_circuit = AdaptorCircuit(circuit); + + create_constraints_info::<_, _, Nonassigning>(&adapted_circuit) +} + +pub fn constraints_padding_info + Clone>( + circuit: C, +) +{ + let adapted_circuit = AdaptorCircuit(circuit); + + create_constraints_info::<_, _, Padding>(&adapted_circuit) +} + +pub fn create_constraints_info, S: SynthesisDriver>( + circuit: &C, +) +{ + let mut backend = Debugging:: { + constraint_num: 0, + u: vec![], + v: vec![], + w: vec![], + _marker: std::marker::PhantomData + }; + + S::synthesize(&mut backend, circuit).unwrap(); + + + for (i, ((u, v), w)) in backend.u.iter() + .zip(backend.v.iter()) + .zip(backend.w.iter()) + .enumerate() + { + println!("Constraint {}: 0 = {}{}{}", i, u, v, w); + } +} + +#[test] +fn my_fun_circuit_test() { + use pairing::ff::PrimeField; + use pairing::bls12_381::{Bls12, Fr}; + + struct MyCircuit; + + impl Circuit for MyCircuit { + fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { + let (a, b, _) = cs.multiply(|| { + Ok(( + E::Fr::from_str("10").unwrap(), + E::Fr::from_str("20").unwrap(), + E::Fr::from_str("200").unwrap(), + )) + })?; + + cs.enforce_zero(LinearCombination::from(a) + a - b); + + let multiplier = cs.alloc_input(|| Ok(E::Fr::from_str("20").unwrap()))?; + + cs.enforce_zero(LinearCombination::from(b) - multiplier); + + Ok(()) + } + } + + create_constraints_info::(&MyCircuit); + println!("---------------"); + create_constraints_info::(&MyCircuit); +} \ No newline at end of file diff --git a/src/sonic/unhelped/permutation_argument.rs b/src/sonic/unhelped/permutation_argument.rs index 1813ae6..021e5a3 100644 --- a/src/sonic/unhelped/permutation_argument.rs +++ b/src/sonic/unhelped/permutation_argument.rs @@ -43,8 +43,6 @@ pub struct Proof { s_zy: E::Fr } - - fn permute(coeffs: &[F], permutation: & [usize]) -> Vec{ assert_eq!(coeffs.len(), permutation.len()); let mut result: Vec = vec![F::zero(); coeffs.len()]; diff --git a/src/sonic/util.rs b/src/sonic/util.rs index 16505a8..aa26854 100644 --- a/src/sonic/util.rs +++ b/src/sonic/util.rs @@ -123,12 +123,12 @@ pub fn polynomial_commitment_opening< ) -> E::G1Affine where I::IntoIter: DoubleEndedIterator + ExactSizeIterator, { - let poly = parallel_kate_divison::(polynomial_coefficients, point); + // let poly = parallel_kate_divison::(polynomial_coefficients, point); - // let poly = kate_divison( - // polynomial_coefficients, - // point, - // ); + let poly = kate_divison( + polynomial_coefficients, + point, + ); let negative_poly = poly[0..largest_negative_power].iter().rev(); let positive_poly = poly[largest_negative_power..].iter();