From d03a99a68c8e97c155103f5c2135aea89ba3710b Mon Sep 17 00:00:00 2001 From: Archit <42545374+gargarchit@users.noreply.github.com> Date: Tue, 9 Jun 2020 17:14:21 +0530 Subject: [PATCH] Add binding for QAP, SAP and R1CS (#47) * Restructure binding files Splitted binding files for each binding * Add binding for QAP and r1cs r1cs_examples binding will be used in test QAP binding * Add Bindings for Square Arithmetic Program --- src/CMakeLists.txt | 10 +- src/PyZPK/binding.cpp | 141 +++--------------- .../data_structures/integer_permutation.cpp | 29 ++++ .../common/data_structures/set_commitment.cpp | 21 +++ .../common/default_types/r1cs_ppzkpcd_pp.cpp | 13 ++ .../default_types/tinyram_ppzksnark_pp.cpp | 14 ++ .../as_waksman_routing_algorithm.cpp | 60 ++++++++ .../benes_routing_algorithm.cpp | 49 ++++++ .../relations/arithmetic_programs/qap.cpp | 93 ++++++++++++ .../relations/arithmetic_programs/sap.cpp | 85 +++++++++++ .../r1cs/r1cs_examples.cpp | 37 +++++ 11 files changed, 430 insertions(+), 122 deletions(-) create mode 100644 src/PyZPK/common/data_structures/integer_permutation.cpp create mode 100644 src/PyZPK/common/data_structures/set_commitment.cpp create mode 100644 src/PyZPK/common/default_types/r1cs_ppzkpcd_pp.cpp create mode 100644 src/PyZPK/common/default_types/tinyram_ppzksnark_pp.cpp create mode 100644 src/PyZPK/common/routing_algorithms/as_waksman_routing_algorithm.cpp create mode 100644 src/PyZPK/common/routing_algorithms/benes_routing_algorithm.cpp create mode 100644 src/PyZPK/relations/arithmetic_programs/qap.cpp create mode 100644 src/PyZPK/relations/arithmetic_programs/sap.cpp create mode 100644 src/PyZPK/relations/constraint_satisfaction_problems/r1cs/r1cs_examples.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fcc492c..29459f4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,14 @@ set( SRC + "${CMAKE_CURRENT_SOURCE_DIR}/PyZPK/common/data_structures/integer_permutation.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/PyZPK/common/data_structures/set_commitment.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/PyZPK/common/routing_algorithms/benes_routing_algorithm.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/PyZPK/common/routing_algorithms/as_waksman_routing_algorithm.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/PyZPK/common/default_types/r1cs_ppzkpcd_pp.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/PyZPK/common/default_types/tinyram_ppzksnark_pp.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/PyZPK/relations/constraint_satisfaction_problems/r1cs/r1cs_examples.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/PyZPK/relations/arithmetic_programs/qap.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/PyZPK/relations/arithmetic_programs/sap.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/PyZPK/binding.cpp" ) @@ -12,7 +21,6 @@ set_target_properties(ff PROPERTIES POSITION_INDEPENDENT_CODE TRUE) target_link_libraries(pyzpk PRIVATE snark) target_link_libraries(pyzpk PRIVATE ff) - target_include_directories( pyzpk diff --git a/src/PyZPK/binding.cpp b/src/PyZPK/binding.cpp index 37de08c..73973ed 100644 --- a/src/PyZPK/binding.cpp +++ b/src/PyZPK/binding.cpp @@ -1,128 +1,27 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; -using namespace libsnark; namespace py = pybind11; +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_examples(py::module &); +void init_relations_arithmetic_programs_qap(py::module &); +void init_relations_arithmetic_programs_sap(py::module &); + PYBIND11_MODULE(pyzpk, m) { m.doc() = "Python wrapper for open source Zero Proof Knowledge Library"; - - // Binding for common/data_structures/integer_permutation.cpp - py::class_(m, "integer_permutation") - .def(py::init()) - .def(py::init()) - .def("set", &integer_permutation::set, py::arg("position"), py::arg("value")) - .def("get", &integer_permutation::get, py::arg("position")) - .def("size", &integer_permutation::size) - .def("is_valid", &integer_permutation::is_valid) - .def("inverse", &integer_permutation::inverse) - .def("slice", &integer_permutation::slice, py::arg("slice_min_element"), py::arg("slice_max_element")) - .def("next_permutation", &integer_permutation::next_permutation) - .def("random_shuffle", &integer_permutation::random_shuffle) - .def( - "__eq__", [](integer_permutation const &self, integer_permutation const &other) { return self == other; }, py::is_operator()); - - // Binding for common/data_structures/set_commitment.cpp // set_membership_proof - py::class_(m, "set_membership_proof") - .def("size_in_bits", &set_membership_proof::size_in_bits) - .def( - "__eq__", [](set_membership_proof const &self, set_membership_proof const &other) { return self == other; }, py::is_operator()); - - // Todo - // std::ostream& operator<<(std::ostream &out, const set_membership_proof &proof) - // std::istream& operator>>(std::istream &in, set_membership_proof &proof) - - // Binding for common/routing_algorithms/benes_routing_algorithm.hpp - // Declaration of interfaces for functionality for routing on a Benes network. - m.def("benes_cross_edge_mask", &benes_cross_edge_mask, R"pbdoc( - Compute the mask for all the cross edges originating at a particular column. - )pbdoc", py::arg("dimension"), py::arg("column_idx")); - m.def("benes_lhs_packet_destination", &benes_lhs_packet_destination, R"pbdoc( - Return the specified destination of packet of the left-hand side of the routing network, based on the subnetwork - )pbdoc", py::arg("dimension"), py::arg("column_idx"), py::arg("row_idx"), py::arg("use_top")); - m.def("benes_rhs_packet_source", &benes_rhs_packet_source, R"pbdoc( - Return the specified source of packet of the right-hand side of the routing network, based on the subnetwork - )pbdoc", py::arg("dimension"), py::arg("column_idx"), py::arg("row_idx"), py::arg("use_top")); - m.def("benes_get_switch_setting_from_subnetwork", &benes_get_switch_setting_from_subnetwork, R"pbdoc( - For a switch located at column_idx-th column and row_idx-th row, return the switch setting that would route its packet - using the top subnetwork. - )pbdoc", py::arg("dimension"), py::arg("column_idx"), py::arg("row_idx"), py::arg("use_top")); - m.def("benes_packet_cross_destination", &benes_packet_cross_destination, R"pbdoc( - A packet column_idx-th column and row_idx-th row of the routing network has two destinations (see comment by benes_cross_edge_mask), - this returns row_idx' of the "cross" destination. - )pbdoc", py::arg("dimension"), py::arg("column_idx"), py::arg("row_idx")); - m.def("benes_packet_cross_source", &benes_packet_cross_source, R"pbdoc( - A packet column_idx-th column and row_idx-th row of the routing network has two source packets that could give rise to it, this - returns row_idx' of the "cross" source packet. - )pbdoc", py::arg("dimension"), py::arg("column_idx"), py::arg("packet_idx")); - m.def("benes_num_columns", &benes_num_columns, py::arg("num_packets")); - m.def("generate_benes_topology", &generate_benes_topology, py::arg("num_packets")); - m.def("route_benes_inner", &route_benes_inner, py::arg("dimension"), py::arg("permutation"), py::arg("permutation_inv"), py::arg("column_idx_start"), py::arg("column_idx_end"), py::arg("subnetwork_offset"), py::arg("subnetwork_size"), py::arg("routing")); - m.def("get_benes_routing", &get_benes_routing, py::arg("permutation")); - m.def("valid_benes_routing", &valid_benes_routing, py::arg("permutation"), py::arg("routing")); - // Todo - // template - // std::vector > route_by_benes(const benes_routing &routing, const std::vector &start) - - // Binding for common/routing_algorithms/as_waksman_routing_algorithm.hpp - // Declaration of interfaces for functionality for routing on an arbitrary-size (AS) Waksman network. - m.def("as_waksman_top_height", &as_waksman_top_height, R"pbdoc( - Return the height of the AS-Waksman network's top sub-network. - )pbdoc", py::arg("num_packets")); - m.def("as_waksman_switch_output", &as_waksman_switch_output, R"pbdoc( - Return the input wire of a left-hand side switch of an AS-Waksman network for a given number of packets. - )pbdoc", py::arg("num_packets"), py::arg("row_offset"), py::arg("row_idx"), py::arg("use_top") ); - m.def("as_waksman_switch_input", &as_waksman_switch_input, R"pbdoc( - Return the input wire of a right-hand side switch of an AS-Waksman network for a given number of packets. - )pbdoc", py::arg("num_packets"), py::arg("row_offset"), py::arg("row_idx"), py::arg("use_top")); - m.def("as_waksman_num_columns", &as_waksman_num_columns, py::arg("num_packets")); - m.def("construct_as_waksman_inner", &construct_as_waksman_inner, R"pbdoc( - Construct AS-Waksman subnetwork - )pbdoc", py::arg("left"), py::arg("right"), py::arg("lo"), py::arg("hi"), py::arg("rhs_dests"), py::arg("neighbors")); - m.def("generate_as_waksman_topology", &generate_as_waksman_topology, py::arg("num_packets")); - m.def("as_waksman_get_canonical_row_idx", &as_waksman_get_canonical_row_idx, R"pbdoc( - Given either a position occupied either by its top or bottom ports, return the row index of its canonical position. - )pbdoc", py::arg("row_offset"), py::arg("row_idx")); - m.def("as_waksman_get_switch_setting_from_top_bottom_decision", &as_waksman_get_switch_setting_from_top_bottom_decision, R"pbdoc( - Return a switch value that makes switch row_idx = as_waksman_switch_position_from_wire_position(row_offset, packet_idx) to - route the wire packet_idx via the top (if top = true), resp., bottom (if top = false) subnetwork. - )pbdoc", py::arg("row_offset"), py::arg("packet_idx"), py::arg("use_top")); - m.def("as_waksman_get_top_bottom_decision_from_switch_setting", &as_waksman_get_top_bottom_decision_from_switch_setting ,R"pbdoc( - Return true if the switch with input port at (column_idx, row_idx) when set to "straight" (if top = true), resp., "cross" - (if top = false), routes the packet at (column_idx, row_idx) via the top subnetwork. - )pbdoc", py::arg("row_offset"), py::arg("packet_idx"), py::arg("switch_setting")); - m.def("as_waksman_other_output_position", &as_waksman_other_output_position ,R"pbdoc( - Given an output wire of a RHS switch, compute and return the output position of the other wire also connected to this switch. - )pbdoc", py::arg("row_offset"), py::arg("packet_idx")); - m.def("as_waksman_other_input_position", &as_waksman_other_input_position ,R"pbdoc( - Given an input wire of a LHS switch, compute and return the input position of the other wire also connected to this switch. - )pbdoc", py::arg("row_offset"), py::arg("packet_idx")); - m.def("as_waksman_route_inner", &as_waksman_route_inner ,R"pbdoc( - Compute AS-Waksman switch settings for the subnetwork - )pbdoc", py::arg("left"), py::arg("right"), py::arg("lo"), py::arg("hi"), py::arg("permutation"), py::arg("permutation_inv"), py::arg("routing")); - m.def("get_as_waksman_routing", &get_as_waksman_routing, py::arg("permutation")); - m.def("valid_as_waksman_routing", &valid_as_waksman_routing, py::arg("permutation"), py::arg("routing")); - - - // Binding for #include common/default_types/r1cs_ppzkpcd_pp.hpp - py::class_(m, "default_r1cs_ppzkpcd_pp") - .def_static("init_public_params", &default_r1cs_ppzkpcd_pp::init_public_params); - // Binding for #include common/default_types/tinyram_ppzksnark_pp.hpp - py::class_(m, "default_tinyram_ppzksnark_pp") - .def_static("init_public_params", &default_tinyram_ppzksnark_pp::init_public_params); -} + 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_examples(m); + init_relations_arithmetic_programs_qap(m); + init_relations_arithmetic_programs_sap(m); +} \ No newline at end of file diff --git a/src/PyZPK/common/data_structures/integer_permutation.cpp b/src/PyZPK/common/data_structures/integer_permutation.cpp new file mode 100644 index 0000000..6a1096a --- /dev/null +++ b/src/PyZPK/common/data_structures/integer_permutation.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +namespace py = pybind11; +using namespace libsnark; + +void init_data_structures_integer_permutation(py::module &m) +{ + // Binding for common/data_structures/integer_permutation.cpp + py::class_(m, "integer_permutation") + .def(py::init()) + .def(py::init()) + .def("set", &integer_permutation::set, py::arg("position"), py::arg("value")) + .def("get", &integer_permutation::get, py::arg("position")) + .def("size", &integer_permutation::size) + .def("is_valid", &integer_permutation::is_valid) + .def("inverse", &integer_permutation::inverse) + .def("slice", &integer_permutation::slice, py::arg("slice_min_element"), py::arg("slice_max_element")) + .def("next_permutation", &integer_permutation::next_permutation) + .def("random_shuffle", &integer_permutation::random_shuffle) + .def( + "__eq__", [](integer_permutation const &self, integer_permutation const &other) { return self == other; }, py::is_operator()); +} \ No newline at end of file diff --git a/src/PyZPK/common/data_structures/set_commitment.cpp b/src/PyZPK/common/data_structures/set_commitment.cpp new file mode 100644 index 0000000..f665198 --- /dev/null +++ b/src/PyZPK/common/data_structures/set_commitment.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include + +using namespace std; +namespace py = pybind11; +using namespace libsnark; + +void init_data_structures_set_commitment(py::module &m) +{ + // Binding for common/data_structures/set_commitment.cpp // set_membership_proof + py::class_(m, "set_membership_proof") + .def("size_in_bits", &set_membership_proof::size_in_bits) + .def( + "__eq__", [](set_membership_proof const &self, set_membership_proof const &other) { return self == other; }, py::is_operator()); + + // Todo + // std::ostream& operator<<(std::ostream &out, const set_membership_proof &proof) + // std::istream& operator>>(std::istream &in, set_membership_proof &proof) +} \ No newline at end of file diff --git a/src/PyZPK/common/default_types/r1cs_ppzkpcd_pp.cpp b/src/PyZPK/common/default_types/r1cs_ppzkpcd_pp.cpp new file mode 100644 index 0000000..36f8611 --- /dev/null +++ b/src/PyZPK/common/default_types/r1cs_ppzkpcd_pp.cpp @@ -0,0 +1,13 @@ +#include +#include + +using namespace std; +namespace py = pybind11; +using namespace libsnark; + +void init_default_types_r1cs_ppzkpcd_pp(py::module &m) +{ + // Binding for #include common/default_types/r1cs_ppzkpcd_pp.hpp + py::class_(m, "default_r1cs_ppzkpcd_pp") + .def_static("init_public_params", &default_r1cs_ppzkpcd_pp::init_public_params); +} \ No newline at end of file diff --git a/src/PyZPK/common/default_types/tinyram_ppzksnark_pp.cpp b/src/PyZPK/common/default_types/tinyram_ppzksnark_pp.cpp new file mode 100644 index 0000000..ad034a2 --- /dev/null +++ b/src/PyZPK/common/default_types/tinyram_ppzksnark_pp.cpp @@ -0,0 +1,14 @@ +#include +#include + +using namespace std; +namespace py = pybind11; +using namespace libsnark; + +void init_default_types_tinyram_ppzksnark_pp(py::module &m) +{ + // Binding for #include common/default_types/tinyram_ppzksnark_pp.hpp + py::class_(m, "default_tinyram_ppzksnark_pp") + .def_static("init_public_params", &default_tinyram_ppzksnark_pp::init_public_params); + +} \ No newline at end of file diff --git a/src/PyZPK/common/routing_algorithms/as_waksman_routing_algorithm.cpp b/src/PyZPK/common/routing_algorithms/as_waksman_routing_algorithm.cpp new file mode 100644 index 0000000..de5d773 --- /dev/null +++ b/src/PyZPK/common/routing_algorithms/as_waksman_routing_algorithm.cpp @@ -0,0 +1,60 @@ +#include +#include +#include + +using namespace std; +namespace py = pybind11; +using namespace libsnark; + +void init_algorithms_as_waksman(py::module &m) +{ + + // Binding for common/routing_algorithms/as_waksman_routing_algorithm.hpp + // Declaration of interfaces for functionality for routing on an arbitrary-size (AS) Waksman network. + m.def("as_waksman_top_height", &as_waksman_top_height, R"pbdoc( + Return the height of the AS-Waksman network's top sub-network. + )pbdoc", + py::arg("num_packets")); + m.def("as_waksman_switch_output", &as_waksman_switch_output, R"pbdoc( + Return the input wire of a left-hand side switch of an AS-Waksman network for a given number of packets. + )pbdoc", + py::arg("num_packets"), py::arg("row_offset"), py::arg("row_idx"), py::arg("use_top")); + m.def("as_waksman_switch_input", &as_waksman_switch_input, R"pbdoc( + Return the input wire of a right-hand side switch of an AS-Waksman network for a given number of packets. + )pbdoc", + py::arg("num_packets"), py::arg("row_offset"), py::arg("row_idx"), py::arg("use_top")); + m.def("as_waksman_num_columns", &as_waksman_num_columns, py::arg("num_packets")); + m.def("construct_as_waksman_inner", &construct_as_waksman_inner, R"pbdoc( + Construct AS-Waksman subnetwork + )pbdoc", + py::arg("left"), py::arg("right"), py::arg("lo"), py::arg("hi"), py::arg("rhs_dests"), py::arg("neighbors")); + m.def("generate_as_waksman_topology", &generate_as_waksman_topology, py::arg("num_packets")); + m.def("as_waksman_get_canonical_row_idx", &as_waksman_get_canonical_row_idx, R"pbdoc( + Given either a position occupied either by its top or bottom ports, return the row index of its canonical position. + )pbdoc", + py::arg("row_offset"), py::arg("row_idx")); + m.def("as_waksman_get_switch_setting_from_top_bottom_decision", &as_waksman_get_switch_setting_from_top_bottom_decision, R"pbdoc( + Return a switch value that makes switch row_idx = as_waksman_switch_position_from_wire_position(row_offset, packet_idx) to + route the wire packet_idx via the top (if top = true), resp., bottom (if top = false) subnetwork. + )pbdoc", + py::arg("row_offset"), py::arg("packet_idx"), py::arg("use_top")); + m.def("as_waksman_get_top_bottom_decision_from_switch_setting", &as_waksman_get_top_bottom_decision_from_switch_setting, R"pbdoc( + Return true if the switch with input port at (column_idx, row_idx) when set to "straight" (if top = true), resp., "cross" + (if top = false), routes the packet at (column_idx, row_idx) via the top subnetwork. + )pbdoc", + py::arg("row_offset"), py::arg("packet_idx"), py::arg("switch_setting")); + m.def("as_waksman_other_output_position", &as_waksman_other_output_position, R"pbdoc( + Given an output wire of a RHS switch, compute and return the output position of the other wire also connected to this switch. + )pbdoc", + py::arg("row_offset"), py::arg("packet_idx")); + m.def("as_waksman_other_input_position", &as_waksman_other_input_position, R"pbdoc( + Given an input wire of a LHS switch, compute and return the input position of the other wire also connected to this switch. + )pbdoc", + py::arg("row_offset"), py::arg("packet_idx")); + m.def("as_waksman_route_inner", &as_waksman_route_inner, R"pbdoc( + Compute AS-Waksman switch settings for the subnetwork + )pbdoc", + py::arg("left"), py::arg("right"), py::arg("lo"), py::arg("hi"), py::arg("permutation"), py::arg("permutation_inv"), py::arg("routing")); + m.def("get_as_waksman_routing", &get_as_waksman_routing, py::arg("permutation")); + m.def("valid_as_waksman_routing", &valid_as_waksman_routing, py::arg("permutation"), py::arg("routing")); +} \ No newline at end of file diff --git a/src/PyZPK/common/routing_algorithms/benes_routing_algorithm.cpp b/src/PyZPK/common/routing_algorithms/benes_routing_algorithm.cpp new file mode 100644 index 0000000..84230de --- /dev/null +++ b/src/PyZPK/common/routing_algorithms/benes_routing_algorithm.cpp @@ -0,0 +1,49 @@ +#include +#include +#include + +using namespace std; +namespace py = pybind11; +using namespace libsnark; + +void init_algorithms_benes(py::module &m) +{ + + // Binding for common/routing_algorithms/benes_routing_algorithm.hpp + // Declaration of interfaces for functionality for routing on a Benes network. + m.def("benes_cross_edge_mask", &benes_cross_edge_mask, R"pbdoc( + Compute the mask for all the cross edges originating at a particular column. + )pbdoc", + py::arg("dimension"), py::arg("column_idx")); + m.def("benes_lhs_packet_destination", &benes_lhs_packet_destination, R"pbdoc( + Return the specified destination of packet of the left-hand side of the routing network, based on the subnetwork + )pbdoc", + py::arg("dimension"), py::arg("column_idx"), py::arg("row_idx"), py::arg("use_top")); + m.def("benes_rhs_packet_source", &benes_rhs_packet_source, R"pbdoc( + Return the specified source of packet of the right-hand side of the routing network, based on the subnetwork + )pbdoc", + py::arg("dimension"), py::arg("column_idx"), py::arg("row_idx"), py::arg("use_top")); + m.def("benes_get_switch_setting_from_subnetwork", &benes_get_switch_setting_from_subnetwork, R"pbdoc( + For a switch located at column_idx-th column and row_idx-th row, return the switch setting that would route its packet + using the top subnetwork. + )pbdoc", + py::arg("dimension"), py::arg("column_idx"), py::arg("row_idx"), py::arg("use_top")); + m.def("benes_packet_cross_destination", &benes_packet_cross_destination, R"pbdoc( + A packet column_idx-th column and row_idx-th row of the routing network has two destinations (see comment by benes_cross_edge_mask), + this returns row_idx' of the "cross" destination. + )pbdoc", + py::arg("dimension"), py::arg("column_idx"), py::arg("row_idx")); + m.def("benes_packet_cross_source", &benes_packet_cross_source, R"pbdoc( + A packet column_idx-th column and row_idx-th row of the routing network has two source packets that could give rise to it, this + returns row_idx' of the "cross" source packet. + )pbdoc", + py::arg("dimension"), py::arg("column_idx"), py::arg("packet_idx")); + m.def("benes_num_columns", &benes_num_columns, py::arg("num_packets")); + m.def("generate_benes_topology", &generate_benes_topology, py::arg("num_packets")); + m.def("route_benes_inner", &route_benes_inner, py::arg("dimension"), py::arg("permutation"), py::arg("permutation_inv"), py::arg("column_idx_start"), py::arg("column_idx_end"), py::arg("subnetwork_offset"), py::arg("subnetwork_size"), py::arg("routing")); + m.def("get_benes_routing", &get_benes_routing, py::arg("permutation")); + m.def("valid_benes_routing", &valid_benes_routing, py::arg("permutation"), py::arg("routing")); + // Todo + // template + // std::vector > route_by_benes(const benes_routing &routing, const std::vector &start) +} \ No newline at end of file diff --git a/src/PyZPK/relations/arithmetic_programs/qap.cpp b/src/PyZPK/relations/arithmetic_programs/qap.cpp new file mode 100644 index 0000000..85678e2 --- /dev/null +++ b/src/PyZPK/relations/arithmetic_programs/qap.cpp @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define FieldT libff::Fr + +using namespace std; +namespace py = pybind11; +using namespace libsnark; + +// Implementation of interfaces for a QAP ("Quadratic Arithmetic Program"). +void init_relations_arithmetic_programs_qap(py::module &m) +{ + // A QAP instance. + py::class_>(m, "qap_instance") + .def(py::init> &, + const size_t, + const size_t, + const size_t, + const std::vector> &, + const std::vector> &, + const std::vector> &>()) + .def(py::init> &, + const size_t, + const size_t, + const size_t, + std::vector> &, + std::vector> &, + std::vector> &>()) + .def("num_variables", &qap_instance::num_variables) + .def("degree", &qap_instance::degree) + .def("num_inputs", &qap_instance::num_inputs) + .def("is_satisfied", &qap_instance::is_satisfied, py::arg("witness")); + + // A QAP instance evaluation is a QAP instance that is evaluated at a field element t. + py::class_>(m, "qap_instance_evaluation") + .def(py::init> &, + const size_t, + const size_t, + const size_t, + const FieldT &, + const std::vector &, + const std::vector &, + const std::vector &, + const std::vector &, + const FieldT &>()) + .def(py::init> &, + const size_t, + const size_t, + const size_t, + const FieldT &, + std::vector &&, + std::vector &&, + std::vector &&, + std::vector &&, + const FieldT &>()) + .def("num_variables", &qap_instance_evaluation::num_variables) + .def("degree", &qap_instance_evaluation::degree) + .def("num_inputs", &qap_instance_evaluation::num_inputs) + .def("is_satisfied", &qap_instance_evaluation::is_satisfied, py::arg("witness")); + + //A QAP witness. + py::class_>(m, "qap_witness") + .def(py::init &, + const std::vector &>()) + .def(py::init &, + std::vector &>()) + .def("num_variables", &qap_witness::num_variables) + .def("degree", &qap_witness::degree) + .def("num_inputs", &qap_witness::num_inputs); + + // Source: libff/algebra/curves/mnt/mnt6/mnt6_init.cpp + // Implementation of interfaces for initializing MNT6. + m.attr("mnt6_Fr_s") = 17; +} \ No newline at end of file diff --git a/src/PyZPK/relations/arithmetic_programs/sap.cpp b/src/PyZPK/relations/arithmetic_programs/sap.cpp new file mode 100644 index 0000000..567ef31 --- /dev/null +++ b/src/PyZPK/relations/arithmetic_programs/sap.cpp @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define FieldT libff::Fr + +using namespace std; +namespace py = pybind11; +using namespace libsnark; + +// Implementation of interfaces for a SAP ("Square Arithmetic Program"). +void init_relations_arithmetic_programs_sap(py::module &m) +{ + // A SAP instance. + py::class_>(m, "sap_instance") + .def(py::init> &, + const size_t, + const size_t, + const size_t, + const std::vector> &, + const std::vector> &>()) + .def(py::init> &, + const size_t, + const size_t, + const size_t, + std::vector> &, + std::vector> &>()) + .def("num_variables", &sap_instance::num_variables) + .def("degree", &sap_instance::degree) + .def("num_inputs", &sap_instance::num_inputs) + .def("is_satisfied", &sap_instance::is_satisfied, py::arg("witness")); + + // A SAP instance evaluation is a SAP instance that is evaluated at a field element t. + py::class_>(m, "sap_instance_evaluation") + .def(py::init> &, + const size_t, + const size_t, + const size_t, + const FieldT &, + const std::vector &, + const std::vector &, + const std::vector &, + const FieldT &>()) + .def(py::init> &, + const size_t, + const size_t, + const size_t, + const FieldT &, + std::vector &&, + std::vector &&, + std::vector &&, + const FieldT &>()) + .def("num_variables", &sap_instance_evaluation::num_variables) + .def("degree", &sap_instance_evaluation::degree) + .def("num_inputs", &sap_instance_evaluation::num_inputs) + .def("is_satisfied", &sap_instance_evaluation::is_satisfied, py::arg("witness")); + + //A SAP witness. + py::class_>(m, "sap_witness") + .def(py::init &, + const std::vector &>()) + .def(py::init &, + std::vector &>()) + .def("num_variables", &sap_witness::num_variables) + .def("degree", &sap_witness::degree) + .def("num_inputs", &sap_witness::num_inputs); + + m.attr("mnt6_Fr_s") = 17; +} \ No newline at end of file diff --git a/src/PyZPK/relations/constraint_satisfaction_problems/r1cs/r1cs_examples.cpp b/src/PyZPK/relations/constraint_satisfaction_problems/r1cs/r1cs_examples.cpp new file mode 100644 index 0000000..1360361 --- /dev/null +++ b/src/PyZPK/relations/constraint_satisfaction_problems/r1cs/r1cs_examples.cpp @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define FieldT libff::Fr + +using namespace std; +namespace py = pybind11; +using namespace libsnark; + +// Declaration of interfaces for a R1CS example, as well as functions to sample +// R1CS examples with prescribed parameters (according to some distribution). +void init_relations_constraint_satisfaction_problems_r1cs_examples(py::module &m) +{ + py::class_>(m, "r1cs_constraint_system") + .def(py::init<>()) + .def("is_satisfied", &r1cs_constraint_system::is_satisfied); + + py::class_>(m, "r1cs_example") + .def(py::init &, + const r1cs_primary_input &, + const r1cs_auxiliary_input &>()) + .def_readwrite("constraint_system", &r1cs_example::constraint_system) + .def_readwrite("primary_input", &r1cs_example::primary_input) + .def_readwrite("auxiliary_input", &r1cs_example::auxiliary_input); + + m.def("generate_r1cs_example_with_field_input", &generate_r1cs_example_with_field_input, py::arg("num_constraints"), py::arg("num_inputs")); + m.def("generate_r1cs_example_with_binary_input", &generate_r1cs_example_with_binary_input, py::arg("num_constraints"), py::arg("num_inputs")); +} \ No newline at end of file