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_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]);
}
}

View File

@ -229,11 +229,13 @@ extern "C" bool libsnarkwrap_test_compare_tau(
extern "C" void libsnarkwrap_eval(
const r1cs_constraint_system<curve_Fr> *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++) {

View File

@ -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::<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 lc = fft(&powers_of_tau, omega) // omit tau^d
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::<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
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::<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<_>>();
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));
}
}