From 5a929abebef64690eb31fbfad0b90b479e6ce611 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sat, 6 Aug 2016 07:15:28 -0600 Subject: [PATCH] Evaluate Bt in G2. --- snark/src/lib.rs | 39 ++++++++++++++++++++++++-------------- snark/src/libsnarkwrap.cpp | 19 ++++++++++++------- src/fft.rs | 36 ++++++++++++++++++++++------------- 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/snark/src/lib.rs b/snark/src/lib.rs index 281433c..b149769 100644 --- a/snark/src/lib.rs +++ b/snark/src/lib.rs @@ -22,18 +22,21 @@ extern "C" { fn libsnarkwrap_dropcs(cs: *mut libc::c_void); fn libsnarkwrap_eval( cs: *const libc::c_void, - lc: *const G1, + lc1: *const G1, + lc2: *const G2, d: libc::uint64_t, vars: libc::uint64_t, At: *mut G1, - Bt: *mut G1, + Bt1: *mut G1, + Bt2: *mut G2, Ct: *mut G1); fn libsnarkwrap_test_eval( cs: *const libc::c_void, tau: *const Fr, vars: libc::uint64_t, At: *const G1, - Bt: *const G1, + Bt1: *const G1, + Bt2: *const G2, Ct: *const G1) -> bool; fn libsnarkwrap_test_compare_tau( i: *const G1, @@ -59,35 +62,43 @@ pub fn initialize() { pub struct CS(*mut libc::c_void); impl CS { - pub fn test_eval(&self, tau: &Fr, At: &[G1], Bt: &[G1], Ct: &[G1]) -> bool { - assert_eq!(At.len(), Bt.len()); - assert_eq!(Bt.len(), Ct.len()); + pub fn test_eval(&self, tau: &Fr, At: &[G1], Bt1: &[G1], Bt2: &[G2], Ct: &[G1]) -> bool { + assert_eq!(At.len(), Bt1.len()); + assert_eq!(Bt1.len(), Bt2.len()); + assert_eq!(Bt2.len(), Ct.len()); unsafe { libsnarkwrap_test_eval(self.0, tau, At.len() as u64, &At[0], - &Bt[0], + &Bt1[0], + &Bt2[0], &Ct[0]) } } pub fn eval(&self, - Lt: &[G1], + Lt1: &[G1], + Lt2: &[G2], At: &mut [G1], - Bt: &mut [G1], + Bt1: &mut [G1], + Bt2: &mut [G2], Ct: &mut [G1]) { - assert_eq!(At.len(), Bt.len()); - assert_eq!(Bt.len(), Ct.len()); + assert_eq!(Lt1.len(), Lt2.len()); + assert_eq!(At.len(), Bt1.len()); + assert_eq!(Bt1.len(), Bt2.len()); + assert_eq!(Bt2.len(), Ct.len()); unsafe { libsnarkwrap_eval(self.0, - &Lt[0], - Lt.len() as u64, + &Lt1[0], + &Lt2[0], + Lt1.len() as u64, At.len() as u64, &mut At[0], - &mut Bt[0], + &mut Bt1[0], + &mut Bt2[0], &mut Ct[0]); } } diff --git a/snark/src/libsnarkwrap.cpp b/snark/src/libsnarkwrap.cpp index a3b1cac..f8ef8af 100644 --- a/snark/src/libsnarkwrap.cpp +++ b/snark/src/libsnarkwrap.cpp @@ -229,11 +229,13 @@ extern "C" bool libsnarkwrap_test_compare_tau( extern "C" void libsnarkwrap_eval( const r1cs_constraint_system *cs, - const curve_G1 *lc, + const curve_G1 *lc1, + const curve_G2 *lc2, uint64_t d, uint64_t vars, curve_G1 *At, - curve_G1 *Bt, + curve_G1 *Bt1, + curve_G2 *Bt2, curve_G1 *Ct ) { @@ -246,17 +248,18 @@ extern "C" void libsnarkwrap_eval( for (size_t i = 0; i < vars; i++) { for (auto const &it : qap.A_in_Lagrange_basis[i]) { assert(it.first < d); - At[i] = At[i] + it.second * lc[it.first]; + At[i] = At[i] + it.second * lc1[it.first]; } for (auto const &it : qap.B_in_Lagrange_basis[i]) { assert(it.first < d); - Bt[i] = Bt[i] + it.second * lc[it.first]; + Bt1[i] = Bt1[i] + it.second * lc1[it.first]; + Bt2[i] = Bt2[i] + it.second * lc2[it.first]; } for (auto const &it : qap.C_in_Lagrange_basis[i]) { assert(it.first < d); - Ct[i] = Ct[i] + it.second * lc[it.first]; + Ct[i] = Ct[i] + it.second * lc1[it.first]; } } } @@ -266,7 +269,8 @@ extern "C" bool libsnarkwrap_test_eval( const curve_Fr *tau, uint64_t vars, const curve_G1 *At, - const curve_G1 *Bt, + const curve_G1 *Bt1, + const curve_G2 *Bt2, const curve_G1 *Ct ) { auto qap = r1cs_to_qap_instance_map_with_evaluation(*cs, *tau); @@ -281,7 +285,8 @@ extern "C" bool libsnarkwrap_test_eval( } for (size_t i = 0; i < vars; i++) { - res &= (qap.Bt[i] * curve_G1::one()) == Bt[i]; + res &= (qap.Bt[i] * curve_G1::one()) == Bt1[i]; + res &= (qap.Bt[i] * curve_G2::one()) == Bt2[i]; } for (size_t i = 0; i < vars; i++) { diff --git a/src/fft.rs b/src/fft.rs index a95ae0d..37636c4 100644 --- a/src/fft.rs +++ b/src/fft.rs @@ -52,32 +52,42 @@ mod test { let tau = Fr::random(); // Generate powers of tau in G1, from 0 to d exclusive of d - let powers_of_tau = TauPowers::new(tau).take(d).map(|e| G1::one() * e).collect::>(); + let powers_of_tau_g1 = TauPowers::new(tau).take(d).map(|e| G1::one() * e).collect::>(); + let powers_of_tau_g2 = TauPowers::new(tau).take(d).map(|e| G2::one() * e).collect::>(); let overd = Fr::from_str(&format!("{}", d)).inverse(); - let lc = fft(&powers_of_tau, omega) // omit tau^d - .into_iter() - .rev() // coefficients are in reverse - .map(|e| e * overd) // divide by d - .collect::>(); + let lc1 = fft(&powers_of_tau_g1, omega) // omit tau^d + .into_iter() + .rev() // coefficients are in reverse + .map(|e| e * overd) // divide by d + .collect::>(); + let lc2 = fft(&powers_of_tau_g2, omega) // omit tau^d + .into_iter() + .rev() // coefficients are in reverse + .map(|e| e * overd) // divide by d + .collect::>(); // Compare against libsnark - assert!(compare_tau(&lc, &tau, &cs)); + assert!(compare_tau(&lc1, &tau, &cs)); // Wrong tau - assert!(!compare_tau(&lc, &Fr::random(), &cs)); + assert!(!compare_tau(&lc1, &Fr::random(), &cs)); - // Evaluate At, Bt, Ct in G1 + // Evaluate At, Ct in G1 and Bt in G1/G2 let mut At = (0..num_vars).map(|_| G1::zero()).collect::>(); - let mut Bt = (0..num_vars).map(|_| G1::zero()).collect::>(); + let mut Bt1 = (0..num_vars).map(|_| G1::zero()).collect::>(); + let mut Bt2 = (0..num_vars).map(|_| G2::zero()).collect::>(); let mut Ct = (0..num_vars).map(|_| G1::zero()).collect::>(); - cs.eval(&lc, &mut At, &mut Bt, &mut Ct); + cs.eval(&lc1, &lc2, &mut At, &mut Bt1, &mut Bt2, &mut Ct); // Compare evaluation with libsnark - assert!(cs.test_eval(&tau, &At, &Bt, &Ct)); + assert!(cs.test_eval(&tau, &At, &Bt1, &Bt2, &Ct)); // Wrong tau - assert!(!cs.test_eval(&Fr::random(), &At, &Bt, &Ct)); + assert!(!cs.test_eval(&Fr::random(), &At, &Bt1, &Bt2, &Ct)); + + // Wrong polynomials + assert!(!cs.test_eval(&Fr::random(), &Bt1, &Bt1, &Bt2, &Ct)); } }