Carry the constraint system through and compute QAP reduction whenever necessary.

This commit is contained in:
Sean Bowe 2016-08-05 12:06:51 -06:00
parent a736e51e7f
commit dc87adf7fc
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
3 changed files with 32 additions and 36 deletions

View File

@ -18,8 +18,8 @@ pub use self::g2::G2;
extern "C" { extern "C" {
fn libsnarkwrap_init(); fn libsnarkwrap_init();
fn libsnarkwrap_pairing(p: *const G1, q: *const G2) -> Gt; fn libsnarkwrap_pairing(p: *const G1, q: *const G2) -> Gt;
fn libsnarkwrap_getqap(d: *mut libc::uint32_t, omega: *mut Fr) -> *mut libc::c_void; fn libsnarkwrap_getcs(d: *mut libc::uint32_t, omega: *mut Fr) -> *mut libc::c_void;
fn libsnarkwrap_dropqap(qap: *mut libc::c_void); fn libsnarkwrap_dropcs(cs: *mut libc::c_void);
fn libsnarkwrap_test_compare_tau( fn libsnarkwrap_test_compare_tau(
i: *const G1, i: *const G1,
tau: *const Fr, tau: *const Fr,
@ -41,29 +41,28 @@ pub fn initialize() {
} }
} }
pub struct QAP(*mut libc::c_void); pub struct CS(*mut libc::c_void);
impl Drop for QAP { impl Drop for CS {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { libsnarkwrap_dropqap(self.0) } unsafe { libsnarkwrap_dropcs(self.0) }
} }
} }
/// Get the QAP info for the generation routines /// Get the QAP info for the generation routines
pub fn getqap() -> (usize, Fr, QAP) { pub fn getqap() -> (usize, Fr, CS) {
let mut d = 0; let mut d = 0;
let mut o = Fr::zero(); let mut o = Fr::zero();
let cs = unsafe { libsnarkwrap_getcs(&mut d, &mut o) };
let qap = unsafe { libsnarkwrap_getqap(&mut d, &mut o) }; (d as usize, o, CS(cs))
(d as usize, o, QAP(qap))
} }
/// Check that the lagrange coefficients computed by tau over /// Check that the lagrange coefficients computed by tau over
/// G1 equal the expected vector. /// G1 equal the expected vector.
pub fn compare_tau(v: &[G1], tau: &Fr, qap: &QAP) -> bool { pub fn compare_tau(v: &[G1], tau: &Fr, cs: &CS) -> bool {
unsafe { libsnarkwrap_test_compare_tau(&v[0], tau, v.len() as u32, qap.0) } unsafe { libsnarkwrap_test_compare_tau(&v[0], tau, v.len() as u32, cs.0) }
} }
pub trait Pairing<Other: Group> { pub trait Pairing<Other: Group> {

View File

@ -172,7 +172,7 @@ extern "C" curve_GT libsnarkwrap_pairing(const curve_G1 *p, const curve_G2 *q) {
// QAP // QAP
qap_instance<curve_Fr> get_qap() extern "C" void* libsnarkwrap_getcs(uint32_t *d, curve_Fr *omega)
{ {
// Generate a dummy circuit // Generate a dummy circuit
auto example = generate_r1cs_example_with_field_input<curve_Fr>(250, 4); auto example = generate_r1cs_example_with_field_input<curve_Fr>(250, 4);
@ -180,41 +180,38 @@ qap_instance<curve_Fr> get_qap()
// A/B swap // A/B swap
example.constraint_system.swap_AB_if_beneficial(); example.constraint_system.swap_AB_if_beneficial();
{
// QAP reduction // QAP reduction
auto qap = r1cs_to_qap_instance_map(example.constraint_system); auto qap = r1cs_to_qap_instance_map(example.constraint_system);
// Degree of the QAP must be a power of 2 // Degree of the QAP must be a power of 2
assert(qap.degree() == 256); assert(qap.degree() == 256);
return qap;
}
extern "C" void* libsnarkwrap_getqap(uint32_t *d, curve_Fr *omega)
{
auto qap = new qap_instance<curve_Fr>(get_qap());
// Assume radix2 evaluation domain // Assume radix2 evaluation domain
*omega = std::static_pointer_cast<basic_radix2_domain<curve_Fr>>(qap->domain)->omega; *omega = std::static_pointer_cast<basic_radix2_domain<curve_Fr>>(qap.domain)->omega;
*d = qap->degree();
return qap; *d = qap.degree();
}
return new r1cs_constraint_system<curve_Fr>(example.constraint_system);
} }
extern "C" void libsnarkwrap_dropqap(qap_instance<curve_Fr> *qap) extern "C" void libsnarkwrap_dropcs(r1cs_constraint_system<curve_Fr> *cs)
{ {
delete qap; delete cs;
} }
extern "C" bool libsnarkwrap_test_compare_tau( extern "C" bool libsnarkwrap_test_compare_tau(
const curve_G1 *inputs, const curve_G1 *inputs,
const curve_Fr *tau, const curve_Fr *tau,
uint32_t d, uint32_t d,
const qap_instance<curve_Fr> *qap const r1cs_constraint_system<curve_Fr> *cs
) )
{ {
auto coeffs = qap->domain->lagrange_coeffs(*tau); auto qap = r1cs_to_qap_instance_map(*cs);
auto coeffs = qap.domain->lagrange_coeffs(*tau);
assert(coeffs.size() == d); assert(coeffs.size() == d);
assert(qap->degree() == d); assert(qap.degree() == d);
bool res = true; bool res = true;
for (size_t i = 0; i < d; i++) { for (size_t i = 0; i < d; i++) {

View File

@ -46,7 +46,7 @@ mod test {
initialize(); initialize();
// Get the QAP degree and omega (for FFT evaluation) // Get the QAP degree and omega (for FFT evaluation)
let (d, omega, qap) = getqap(); let (d, omega, cs) = getqap();
// Sample a random tau // Sample a random tau
let tau = Fr::random(); let tau = Fr::random();
@ -62,9 +62,9 @@ mod test {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
// Compare against libsnark // Compare against libsnark
assert!(compare_tau(&lc, &tau, &qap)); assert!(compare_tau(&lc, &tau, &cs));
// Wrong tau // Wrong tau
assert!(!compare_tau(&lc, &Fr::random(), &qap)); assert!(!compare_tau(&lc, &Fr::random(), &cs));
} }
} }