- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add bindings for r1cs_to_qap. Test SAP/QAP (#48)
* Add Binding for r1cs * Fix Todos for r1cs.cpp * Add Binding for Fp_model class type and some test Fp_model class type will be used as class type for relations and used in testing * Add Test for QAP & SAP, Bindings for r1cs to QAP
1 parent
d03a99a
commit d2c873b
Showing
11 changed files
with
252 additions
and
13 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,33 @@ | ||
#include <pybind11/pybind11.h> | ||
namespace py = pybind11; | ||
|
||
void init_utils_Fp_model(py::module &); | ||
void init_data_structures_integer_permutation(py::module &); | ||
void init_data_structures_set_commitment(py::module &); | ||
void init_algorithms_benes(py::module &); | ||
void init_algorithms_as_waksman(py::module &); | ||
void init_default_types_r1cs_ppzkpcd_pp(py::module &); | ||
void init_default_types_tinyram_ppzksnark_pp(py::module &); | ||
void init_relations_constraint_satisfaction_problems_r1cs(py::module &); | ||
void init_relations_constraint_satisfaction_problems_r1cs_examples(py::module &); | ||
void init_relations_arithmetic_programs_qap(py::module &); | ||
void init_relations_arithmetic_programs_sap(py::module &); | ||
void init_reductions_r1cs_to_qap(py::module &); | ||
|
||
PYBIND11_MODULE(pyzpk, m) | ||
{ | ||
m.doc() = "Python wrapper for open source Zero Proof Knowledge Library"; | ||
|
||
init_utils_Fp_model(m); | ||
init_data_structures_integer_permutation(m); | ||
init_data_structures_set_commitment(m); | ||
init_algorithms_benes(m); | ||
init_algorithms_as_waksman(m); | ||
init_default_types_r1cs_ppzkpcd_pp(m); | ||
init_default_types_tinyram_ppzksnark_pp(m); | ||
init_relations_constraint_satisfaction_problems_r1cs(m); | ||
init_relations_constraint_satisfaction_problems_r1cs_examples(m); | ||
init_relations_arithmetic_programs_qap(m); | ||
init_relations_arithmetic_programs_sap(m); | ||
init_reductions_r1cs_to_qap(m); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#include <pybind11/pybind11.h> | ||
#include <pybind11/operators.h> | ||
#include <pybind11/stl.h> | ||
#include <libff/algebra/curves/mnt/mnt6/mnt6_pp.hpp> | ||
#include <libff/algebra/fields/field_utils.hpp> | ||
#include <libff/algebra/scalar_multiplication/multiexp.hpp> | ||
#include <libff/common/profiling.hpp> | ||
#include <libff/common/utils.hpp> | ||
#include <libsnark/relations/arithmetic_programs/qap/qap.hpp> | ||
#include <libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp> | ||
#include <libsnark/reductions/r1cs_to_qap/r1cs_to_qap.hpp> | ||
using namespace std; | ||
namespace py = pybind11; | ||
using namespace libsnark; | ||
using namespace libff; | ||
|
||
// Implementation of interfaces for a R1CS-to-QAP reduction. | ||
void init_reductions_r1cs_to_qap(py::module &m) | ||
{ | ||
using FieldT = Fp_model<5l, libff::mnt46_modulus_B>; | ||
|
||
// Instance map for the R1CS-to-QAP reduction. | ||
m.def("r1cs_to_qap_instance_map", &r1cs_to_qap_instance_map<FieldT>, py::arg("cs")); | ||
|
||
// Instance map for the R1CS-to-QAP reduction followed by evaluation of the resulting QAP instance. | ||
m.def("r1cs_to_qap_instance_map_with_evaluation", &r1cs_to_qap_instance_map_with_evaluation<FieldT>, | ||
py::arg("cs"), py::arg("t")); | ||
|
||
// Witness map for the R1CS-to-QAP reduction. | ||
// The witness map takes zero knowledge into account when d1,d2,d3 are random. | ||
m.def("r1cs_to_qap_witness_map", &r1cs_to_qap_witness_map<FieldT>, | ||
py::arg("cs"), py::arg("primary_input"), py::arg("auxiliary_input"), | ||
py::arg("d1"), py::arg("d2"), py::arg("d3")); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
src/PyZPK/relations/constraint_satisfaction_problems/r1cs/r1cs.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
#include <pybind11/pybind11.h> | ||
#include <pybind11/stl.h> | ||
#include <pybind11/stl_bind.h> | ||
#include <pybind11/cast.h> | ||
#include <pybind11/complex.h> | ||
#include <pybind11/functional.h> | ||
#include <pybind11/chrono.h> | ||
#include <vector> | ||
#include <cassert> | ||
#include <libff/algebra/curves/mnt/mnt6/mnt6_pp.hpp> | ||
#include <libff/algebra/fields/field_utils.hpp> | ||
#include <libff/algebra/scalar_multiplication/multiexp.hpp> | ||
#include <libff/common/profiling.hpp> | ||
#include <libff/common/utils.hpp> | ||
#include <libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp> | ||
|
||
using namespace std; | ||
namespace py = pybind11; | ||
using namespace libsnark; | ||
using namespace libff; | ||
|
||
// Interfaces for a R1CS constraint, a R1CS variable assignment, and a R1CS constraint system. | ||
void init_relations_constraint_satisfaction_problems_r1cs(py::module &m) | ||
{ | ||
using FieldT = Fp_model<5l, libff::mnt46_modulus_B>; | ||
py::class_<r1cs_constraint<FieldT>>(m, "r1cs_constraint") | ||
.def(py::init<>()) | ||
.def_readwrite("a", &r1cs_constraint<FieldT>::a) | ||
.def_readwrite("b", &r1cs_constraint<FieldT>::b) | ||
.def_readwrite("c", &r1cs_constraint<FieldT>::c) | ||
.def(py::init<const linear_combination<FieldT> &, | ||
const linear_combination<FieldT> &, | ||
const linear_combination<FieldT> &>()) | ||
.def(py::init<const std::initializer_list<linear_combination<FieldT>> &, | ||
const std::initializer_list<linear_combination<FieldT>> &, | ||
const std::initializer_list<linear_combination<FieldT>> &>()) | ||
.def( | ||
"__eq__", [](r1cs_constraint<FieldT> const &self, r1cs_constraint<FieldT> const &other) { return self == other; }, py::is_operator()) | ||
.def("__ostr__", [](r1cs_constraint<FieldT> const &self) { | ||
std::ostringstream os; | ||
os << self.a << "\n"; | ||
os << self.b << "\n"; | ||
os << self.c << "\n"; | ||
return os; | ||
}) | ||
.def("__istr__", [](r1cs_constraint<FieldT> &self) { | ||
std::istringstream os; | ||
os >> self.a; | ||
os >> self.b; | ||
os >> self.c; | ||
return os; | ||
}); | ||
|
||
py::class_<r1cs_constraint_system<FieldT>>(m, "r1cs_constraint_system") | ||
.def(py::init<>()) | ||
.def_readwrite("primary_input_size", &r1cs_constraint_system<FieldT>::primary_input_size) | ||
.def_readwrite("auxiliary_input_size", &r1cs_constraint_system<FieldT>::auxiliary_input_size) | ||
.def_readwrite("constraints", &r1cs_constraint_system<FieldT>::constraints) | ||
.def("num_inputs", &r1cs_constraint_system<FieldT>::num_inputs) | ||
.def("num_variables", &r1cs_constraint_system<FieldT>::num_variables) | ||
.def("num_constraints", &r1cs_constraint_system<FieldT>::num_constraints) | ||
.def("is_valid", &r1cs_constraint_system<FieldT>::is_valid) | ||
.def("add_constraint", (void (r1cs_constraint_system<FieldT>::*)(const r1cs_constraint<FieldT> &)) & r1cs_constraint_system<FieldT>::add_constraint, py::arg("c")) | ||
.def("add_constraint", (void (r1cs_constraint_system<FieldT>::*)(const r1cs_constraint<FieldT> &, const std::string &)) & r1cs_constraint_system<FieldT>::add_constraint, py::arg("c"), py::arg("annotation")) | ||
.def("is_satisfied", &r1cs_constraint_system<FieldT>::is_satisfied, py::arg("primary_input"), py::arg("auxiliary_input")) | ||
.def("swap_AB_if_beneficial", &r1cs_constraint_system<FieldT>::swap_AB_if_beneficial) | ||
.def( | ||
"__eq__", [](r1cs_constraint_system<FieldT> const &self, r1cs_constraint_system<FieldT> const &other) { return self == other; }, py::is_operator()) | ||
.def("report_linear_constraint_statistics", &r1cs_constraint_system<FieldT>::report_linear_constraint_statistics) | ||
.def("__ostr__", [](r1cs_constraint_system<FieldT> const &self) { | ||
std::ostringstream os; | ||
os << self.primary_input_size << "\n"; | ||
os << self.auxiliary_input_size << "\n"; | ||
for (const r1cs_constraint<FieldT> &c : self.constraints) | ||
{ | ||
os << c; | ||
} | ||
return os; | ||
}) | ||
.def("__istr__", [](r1cs_constraint_system<FieldT> &self) { | ||
std::istringstream os; | ||
os >> self.primary_input_size; | ||
os >> self.auxiliary_input_size; | ||
self.constraints.clear(); | ||
size_t s; | ||
os >> s; | ||
char b; | ||
os.read(&b, 1); | ||
self.constraints.reserve(s); | ||
for (size_t i = 0; i < s; ++i) | ||
{ | ||
r1cs_constraint<FieldT> c; | ||
os >> c; | ||
self.constraints.emplace_back(c); | ||
} | ||
return os; | ||
}); | ||
} |
16 changes: 7 additions & 9 deletions
16
src/PyZPK/relations/constraint_satisfaction_problems/r1cs/r1cs_examples.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,35 @@ | ||
#include <pybind11/pybind11.h> | ||
#include <pybind11/stl.h> | ||
#include <pybind11/stl_bind.h> | ||
#include <pybind11/cast.h> | ||
#include <pybind11/complex.h> | ||
#include <vector> | ||
#include <cassert> | ||
#include <libff/algebra/curves/mnt/mnt6/mnt6_pp.hpp> | ||
#include <libff/algebra/fields/field_utils.hpp> | ||
#include <libff/algebra/scalar_multiplication/multiexp.hpp> | ||
#include <libff/common/profiling.hpp> | ||
#include <libff/common/utils.hpp> | ||
#include <libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp> | ||
#include <libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp> | ||
#define FieldT libff::Fr<libff::mnt6_pp> | ||
|
||
using namespace std; | ||
namespace py = pybind11; | ||
using namespace libsnark; | ||
using namespace libff; | ||
|
||
// Declaration of interfaces for a R1CS example, as well as functions to sample | ||
// R1CS examples with prescribed parameters (according to some distribution). | ||
// R1CS examples with prescribed parameters (according to some distribution) | ||
void init_relations_constraint_satisfaction_problems_r1cs_examples(py::module &m) | ||
{ | ||
py::class_<r1cs_constraint_system<FieldT>>(m, "r1cs_constraint_system") | ||
.def(py::init<>()) | ||
.def("is_satisfied", &r1cs_constraint_system<FieldT>::is_satisfied); | ||
|
||
using FieldT = Fp_model<5l, libff::mnt46_modulus_B>; | ||
py::class_<r1cs_example<FieldT>>(m, "r1cs_example") | ||
.def(py::init<const r1cs_constraint_system<FieldT> &, | ||
const r1cs_primary_input<FieldT> &, | ||
const r1cs_auxiliary_input<FieldT> &>()) | ||
.def_readwrite("constraint_system", &r1cs_example<FieldT>::constraint_system) | ||
.def_readwrite("primary_input", &r1cs_example<FieldT>::primary_input) | ||
.def_readwrite("auxiliary_input", &r1cs_example<FieldT>::auxiliary_input); | ||
|
||
m.def("generate_r1cs_example_with_field_input", &generate_r1cs_example_with_field_input<FieldT>, py::arg("num_constraints"), py::arg("num_inputs")); | ||
m.def("generate_r1cs_example_with_binary_input", &generate_r1cs_example_with_binary_input<FieldT>, py::arg("num_constraints"), py::arg("num_inputs")); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#include <pybind11/pybind11.h> | ||
#include <pybind11/stl.h> | ||
#include <pybind11/stl_bind.h> | ||
#include <pybind11/cast.h> | ||
#include <pybind11/complex.h> | ||
#include <vector> | ||
#include <cassert> | ||
#include <cmath> | ||
#include <cstdlib> | ||
#include <limits> | ||
#include <random> | ||
#include <cstddef> | ||
#include <iostream> | ||
#include <libff/algebra/scalar_multiplication/multiexp.hpp> | ||
#include <libff/algebra/curves/mnt/mnt6/mnt6_pp.hpp> | ||
#include <libff/algebra/curves/mnt/mnt6/mnt6_g1.hpp> | ||
#include <libff/algebra/curves/mnt/mnt6/mnt6_g2.hpp> | ||
#include <libff/algebra/curves/mnt/mnt6/mnt6_init.hpp> | ||
#include <libff/algebra/curves/mnt/mnt6/mnt6_pairing.hpp> | ||
#include <libff/algebra/curves/public_params.hpp> | ||
#include <libff/algebra/exponentiation/exponentiation.hpp> | ||
#include <libff/algebra/fields/field_utils.hpp> | ||
#include <libff/algebra/fields/bigint.hpp> | ||
#include <libff/algebra/fields/fp_aux.tcc> | ||
#include <libff/common/profiling.hpp> | ||
#include <libff/common/utils.hpp> | ||
#include <libff/common/serialization.hpp> | ||
#include <gmp.h> | ||
|
||
using namespace std; | ||
namespace py = pybind11; | ||
using namespace libff; | ||
|
||
// Used as FieldT class type | ||
void init_utils_Fp_model(py::module &m) | ||
{ | ||
// bigint wrapper class around GMP's MPZ long integers. | ||
py::class_<bigint<5l>>(m, "bigint") | ||
.def(py::init<>()) | ||
.def(py::init<const unsigned long>()) | ||
.def(py::init<const char*>()) | ||
.def("test_bit", &bigint<5l>::test_bit) | ||
.def("randomize", &bigint<5l>::randomize); | ||
|
||
py::class_<mnt6_pp>(m, "mnt6_pp"); | ||
|
||
// Implementation of arithmetic in the finite field F[p], for prime p of fixed length. | ||
py::class_<Fp_model<5l, libff::mnt46_modulus_B>>(m, "Fp_model") | ||
.def(py::init<>()) | ||
.def(py::init<const bigint<5l> &>()) | ||
.def(py::init<const long, const bool>()) | ||
.def_readwrite("mont_repr", &Fp_model<5l, libff::mnt46_modulus_B>::mont_repr) | ||
.def("random_element", &Fp_model<5l, libff::mnt46_modulus_B>::random_element) // Todo | ||
.def("inverse", &Fp_model<5l, libff::mnt46_modulus_B>::inverse); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import pytest | ||
import pyzpk | ||
import math | ||
|
||
# Test for QAP | ||
@pytest.mark.parametrize("qap_degree, num_inputs, binary_input", | ||
[ | ||
# basic_domain_size | ||
(1 << pyzpk.mnt6_Fr_s, 10, True), | ||
# step_domain_size | ||
((1 << 10) + (1 << 8), 10, True), | ||
# extended_domain_size | ||
(1 << (pyzpk.mnt6_Fr_s+1), 10, True), | ||
# extended_domain_size_special | ||
((1 << (pyzpk.mnt6_Fr_s+1))-1, 10, True) | ||
]) | ||
def test_qap(qap_degree, num_inputs, binary_input): | ||
assert num_inputs + 1 <= qap_degree | ||
num_constraints = qap_degree - num_inputs - 1 | ||
# For Binary input | ||
example = pyzpk.generate_r1cs_example_with_binary_input( | ||
num_constraints, num_inputs) | ||
assert example.constraint_system.is_satisfied( | ||
example.primary_input, example.auxiliary_input) | ||
|
||
# Test for SAP | ||
@pytest.mark.parametrize("sap_degree, num_inputs, binary_input", | ||
[ | ||
# basic_domain_size_special | ||
((1 << pyzpk.mnt6_Fr_s) - 1, 10, True), | ||
# # step_domain_size_special | ||
((1 << 10) + (1 << 8) - 1, 10, True), | ||
# # extended_domain_size_special | ||
(1 << (pyzpk.mnt6_Fr_s+1) - 1, 10, True) | ||
]) | ||
def test_sap(sap_degree, num_inputs, binary_input): | ||
num_constraints = int((sap_degree - 1) / 2) - num_inputs | ||
assert num_constraints >= 1 | ||
# For Binary input | ||
example = pyzpk.generate_r1cs_example_with_binary_input( | ||
num_constraints, num_inputs) | ||
assert example.constraint_system.is_satisfied( | ||
example.primary_input, example.auxiliary_input) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters