Evaluate Bt in G2.

This commit is contained in:
Sean Bowe 2016-08-06 07:15:28 -06:00
parent 5a93bf365a
commit 5a929abebe
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
3 changed files with 60 additions and 34 deletions

View File

@ -22,18 +22,21 @@ extern "C" {
fn libsnarkwrap_dropcs(cs: *mut libc::c_void); fn libsnarkwrap_dropcs(cs: *mut libc::c_void);
fn libsnarkwrap_eval( fn libsnarkwrap_eval(
cs: *const libc::c_void, cs: *const libc::c_void,
lc: *const G1, lc1: *const G1,
lc2: *const G2,
d: libc::uint64_t, d: libc::uint64_t,
vars: libc::uint64_t, vars: libc::uint64_t,
At: *mut G1, At: *mut G1,
Bt: *mut G1, Bt1: *mut G1,
Bt2: *mut G2,
Ct: *mut G1); Ct: *mut G1);
fn libsnarkwrap_test_eval( fn libsnarkwrap_test_eval(
cs: *const libc::c_void, cs: *const libc::c_void,
tau: *const Fr, tau: *const Fr,
vars: libc::uint64_t, vars: libc::uint64_t,
At: *const G1, At: *const G1,
Bt: *const G1, Bt1: *const G1,
Bt2: *const G2,
Ct: *const G1) -> bool; Ct: *const G1) -> bool;
fn libsnarkwrap_test_compare_tau( fn libsnarkwrap_test_compare_tau(
i: *const G1, i: *const G1,
@ -59,35 +62,43 @@ pub fn initialize() {
pub struct CS(*mut libc::c_void); pub struct CS(*mut libc::c_void);
impl CS { impl CS {
pub fn test_eval(&self, tau: &Fr, At: &[G1], Bt: &[G1], Ct: &[G1]) -> bool { pub fn test_eval(&self, tau: &Fr, At: &[G1], Bt1: &[G1], Bt2: &[G2], Ct: &[G1]) -> bool {
assert_eq!(At.len(), Bt.len()); assert_eq!(At.len(), Bt1.len());
assert_eq!(Bt.len(), Ct.len()); assert_eq!(Bt1.len(), Bt2.len());
assert_eq!(Bt2.len(), Ct.len());
unsafe { unsafe {
libsnarkwrap_test_eval(self.0, libsnarkwrap_test_eval(self.0,
tau, tau,
At.len() as u64, At.len() as u64,
&At[0], &At[0],
&Bt[0], &Bt1[0],
&Bt2[0],
&Ct[0]) &Ct[0])
} }
} }
pub fn eval(&self, pub fn eval(&self,
Lt: &[G1], Lt1: &[G1],
Lt2: &[G2],
At: &mut [G1], At: &mut [G1],
Bt: &mut [G1], Bt1: &mut [G1],
Bt2: &mut [G2],
Ct: &mut [G1]) { Ct: &mut [G1]) {
assert_eq!(At.len(), Bt.len()); assert_eq!(Lt1.len(), Lt2.len());
assert_eq!(Bt.len(), Ct.len()); assert_eq!(At.len(), Bt1.len());
assert_eq!(Bt1.len(), Bt2.len());
assert_eq!(Bt2.len(), Ct.len());
unsafe { unsafe {
libsnarkwrap_eval(self.0, libsnarkwrap_eval(self.0,
&Lt[0], &Lt1[0],
Lt.len() as u64, &Lt2[0],
Lt1.len() as u64,
At.len() as u64, At.len() as u64,
&mut At[0], &mut At[0],
&mut Bt[0], &mut Bt1[0],
&mut Bt2[0],
&mut Ct[0]); &mut Ct[0]);
} }
} }

View File

@ -229,11 +229,13 @@ extern "C" bool libsnarkwrap_test_compare_tau(
extern "C" void libsnarkwrap_eval( extern "C" void libsnarkwrap_eval(
const r1cs_constraint_system<curve_Fr> *cs, const r1cs_constraint_system<curve_Fr> *cs,
const curve_G1 *lc, const curve_G1 *lc1,
const curve_G2 *lc2,
uint64_t d, uint64_t d,
uint64_t vars, uint64_t vars,
curve_G1 *At, curve_G1 *At,
curve_G1 *Bt, curve_G1 *Bt1,
curve_G2 *Bt2,
curve_G1 *Ct curve_G1 *Ct
) )
{ {
@ -246,17 +248,18 @@ extern "C" void libsnarkwrap_eval(
for (size_t i = 0; i < vars; i++) { for (size_t i = 0; i < vars; i++) {
for (auto const &it : qap.A_in_Lagrange_basis[i]) { for (auto const &it : qap.A_in_Lagrange_basis[i]) {
assert(it.first < d); 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]) { for (auto const &it : qap.B_in_Lagrange_basis[i]) {
assert(it.first < d); 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]) { for (auto const &it : qap.C_in_Lagrange_basis[i]) {
assert(it.first < d); 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, const curve_Fr *tau,
uint64_t vars, uint64_t vars,
const curve_G1 *At, const curve_G1 *At,
const curve_G1 *Bt, const curve_G1 *Bt1,
const curve_G2 *Bt2,
const curve_G1 *Ct const curve_G1 *Ct
) { ) {
auto qap = r1cs_to_qap_instance_map_with_evaluation(*cs, *tau); 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++) { 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++) { for (size_t i = 0; i < vars; i++) {

View File

@ -52,32 +52,42 @@ mod test {
let tau = Fr::random(); let tau = Fr::random();
// Generate powers of tau in G1, from 0 to d exclusive of d // 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::<Vec<_>>(); let powers_of_tau_g1 = TauPowers::new(tau).take(d).map(|e| G1::one() * e).collect::<Vec<_>>();
let powers_of_tau_g2 = TauPowers::new(tau).take(d).map(|e| G2::one() * e).collect::<Vec<_>>();
let overd = Fr::from_str(&format!("{}", d)).inverse(); let overd = Fr::from_str(&format!("{}", d)).inverse();
let lc = fft(&powers_of_tau, omega) // omit tau^d let lc1 = fft(&powers_of_tau_g1, omega) // omit tau^d
.into_iter() .into_iter()
.rev() // coefficients are in reverse .rev() // coefficients are in reverse
.map(|e| e * overd) // divide by d .map(|e| e * overd) // divide by d
.collect::<Vec<_>>(); .collect::<Vec<_>>();
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::<Vec<_>>();
// Compare against libsnark // Compare against libsnark
assert!(compare_tau(&lc, &tau, &cs)); assert!(compare_tau(&lc1, &tau, &cs));
// Wrong tau // 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::<Vec<_>>(); let mut At = (0..num_vars).map(|_| G1::zero()).collect::<Vec<_>>();
let mut Bt = (0..num_vars).map(|_| G1::zero()).collect::<Vec<_>>(); let mut Bt1 = (0..num_vars).map(|_| G1::zero()).collect::<Vec<_>>();
let mut Bt2 = (0..num_vars).map(|_| G2::zero()).collect::<Vec<_>>();
let mut Ct = (0..num_vars).map(|_| G1::zero()).collect::<Vec<_>>(); let mut Ct = (0..num_vars).map(|_| G1::zero()).collect::<Vec<_>>();
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 // Compare evaluation with libsnark
assert!(cs.test_eval(&tau, &At, &Bt, &Ct)); assert!(cs.test_eval(&tau, &At, &Bt1, &Bt2, &Ct));
// Wrong tau // 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));
} }
} }