From 2e7bab0a3cfa73679034c4dcd8a4566f9ce6e3e3 Mon Sep 17 00:00:00 2001 From: huelse Date: Tue, 3 May 2022 19:37:14 +0800 Subject: [PATCH 1/5] Add to_string in Ciphertext and from_string in context --- src/wrapper.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/wrapper.cpp b/src/wrapper.cpp index c3671a1..3c565d6 100644 --- a/src/wrapper.cpp +++ b/src/wrapper.cpp @@ -105,7 +105,14 @@ PYBIND11_MODULE(seal, m) .def("parameters_set", &SEALContext::parameters_set) .def("first_parms_id", &SEALContext::first_parms_id) .def("last_parms_id", &SEALContext::last_parms_id) - .def("using_keyswitching", &SEALContext::using_keyswitching); + .def("using_keyswitching", &SEALContext::using_keyswitching) + .def("from_string", [](const SEALContext &context, const std::string &str){ + Ciphertext cipher; + std::stringstream in(std::ios::binary | std::ios::in); + in.str(str); + cipher.load(context, in); + return cipher; + }); // modulus.h py::class_(m, "Modulus") @@ -183,17 +190,22 @@ PYBIND11_MODULE(seal, m) cipher.scale() = scale; }) .def("save", [](const Ciphertext &cipher, const std::string &path){ - std::ofstream out(path, std::ofstream::binary); + std::ofstream out(path, std::ios::binary); cipher.save(out); out.close(); }) .def("load", [](Ciphertext &cipher, const SEALContext &context, const std::string &path){ - std::ifstream in(path, std::ifstream::binary); + std::ifstream in(path, std::ios::binary); cipher.load(context, in); in.close(); }) .def("save_size", [](const Ciphertext &cipher){ return cipher.save_size(); + }) + .def("to_string", [](const Ciphertext &cipher){ + std::stringstream out(std::ios::binary | std::ios::out); + cipher.save(out); + return py::bytes(out.str()); }); // secretkey.h From d2953c2d488d1bf7c297737ea9a909798e1379d3 Mon Sep 17 00:00:00 2001 From: huelse Date: Tue, 3 May 2022 19:51:12 +0800 Subject: [PATCH 2/5] Add more main data class from string methods --- src/wrapper.cpp | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/wrapper.cpp b/src/wrapper.cpp index 3c565d6..f4f9626 100644 --- a/src/wrapper.cpp +++ b/src/wrapper.cpp @@ -106,12 +106,47 @@ PYBIND11_MODULE(seal, m) .def("first_parms_id", &SEALContext::first_parms_id) .def("last_parms_id", &SEALContext::last_parms_id) .def("using_keyswitching", &SEALContext::using_keyswitching) - .def("from_string", [](const SEALContext &context, const std::string &str){ + .def("from_cipher_str", [](const SEALContext &context, const std::string &str){ Ciphertext cipher; std::stringstream in(std::ios::binary | std::ios::in); in.str(str); cipher.load(context, in); return cipher; + }) + .def("from_plain_str", [](const SEALContext &context, const std::string &str){ + Plaintext plain; + std::stringstream in(std::ios::binary | std::ios::in); + in.str(str); + plain.load(context, in); + return plain; + }) + .def("from_secret_str", [](const SEALContext &context, const std::string &str){ + SecretKey secret; + std::stringstream in(std::ios::binary | std::ios::in); + in.str(str); + secret.load(context, in); + return secret; + }) + .def("from_public_str", [](const SEALContext &context, const std::string &str){ + PublicKey public1; + std::stringstream in(std::ios::binary | std::ios::in); + in.str(str); + public1.load(context, in); + return public1; + }) + .def("from_relin_str", [](const SEALContext &context, const std::string &str){ + RelinKeys relin; + std::stringstream in(std::ios::binary | std::ios::in); + in.str(str); + relin.load(context, in); + return relin; + }) + .def("from_galois_str", [](const SEALContext &context, const std::string &str){ + GaloisKeys galois; + std::stringstream in(std::ios::binary | std::ios::in); + in.str(str); + galois.load(context, in); + return galois; }); // modulus.h @@ -257,7 +292,7 @@ PYBIND11_MODULE(seal, m) in.close(); }); - // relinKeys.h + // relinkeys.h py::class_(m, "RelinKeys") .def(py::init<>()) .def(py::init()) @@ -276,7 +311,7 @@ PYBIND11_MODULE(seal, m) in.close(); }); - // galoisKeys.h + // galoiskeys.h py::class_(m, "GaloisKeys") .def(py::init<>()) .def(py::init()) From 91e61dd72c2ae55f89a23a3271ce651cd3c4fc3a Mon Sep 17 00:00:00 2001 From: huelse Date: Wed, 4 May 2022 14:23:54 +0800 Subject: [PATCH 3/5] Add to string api to the main data class --- src/wrapper.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/src/wrapper.cpp b/src/wrapper.cpp index f4f9626..79d6c85 100644 --- a/src/wrapper.cpp +++ b/src/wrapper.cpp @@ -39,15 +39,31 @@ PYBIND11_MODULE(seal, m) .def("coeff_modulus", &EncryptionParameters::coeff_modulus) .def("plain_modulus", &EncryptionParameters::plain_modulus) .def("save", [](const EncryptionParameters &parms, std::string &path){ - std::ofstream out(path, std::ofstream::binary); + std::ofstream out(path, std::ios::binary); parms.save(out); out.close(); }) .def("load", [](EncryptionParameters &parms, std::string &path){ - std::ifstream in(path, std::ifstream::binary); + std::ifstream in(path, std::ios::binary); parms.load(in); in.close(); - }); + }) + .def(py::pickle( + [](const EncryptionParameters &parms){ + std::stringstream out(std::ios::binary | std::ios::out); + parms.save(out); + return py::make_tuple(py::bytes(out.str())); + }, + [](py::tuple t){ + if (t.size() != 1) + throw std::runtime_error("(Pickle) Invalid input tuple!"); + std::string str = t[0].cast(); + std::stringstream in(std::ios::binary | std::ios::in); + EncryptionParameters parms; + parms.load(in); + return parms; + } + )); // modulus.h py::enum_(m, "sec_level_type") @@ -128,11 +144,11 @@ PYBIND11_MODULE(seal, m) return secret; }) .def("from_public_str", [](const SEALContext &context, const std::string &str){ - PublicKey public1; + PublicKey public_; std::stringstream in(std::ios::binary | std::ios::in); in.str(str); - public1.load(context, in); - return public1; + public_.load(context, in); + return public_; }) .def("from_relin_str", [](const SEALContext &context, const std::string &str){ RelinKeys relin; @@ -204,6 +220,11 @@ PYBIND11_MODULE(seal, m) }) .def("save_size", [](const Plaintext &plain){ return plain.save_size(); + }) + .def("to_string", [](const Plaintext &plain){ + std::stringstream out(std::ios::binary | std::ios::out); + plain.save(out); + return py::bytes(out.str()); }); // ciphertext.h @@ -257,6 +278,11 @@ PYBIND11_MODULE(seal, m) std::ifstream in(path, std::ifstream::binary); sk.load(context, in); in.close(); + }) + .def("to_string", [](const SecretKey &secret){ + std::stringstream out(std::ios::binary | std::ios::out); + secret.save(out); + return py::bytes(out.str()); }); // publickey.h @@ -273,6 +299,11 @@ PYBIND11_MODULE(seal, m) std::ifstream in(path, std::ifstream::binary); pk.load(context, in); in.close(); + }) + .def("to_string", [](const PublicKey &public_){ + std::stringstream out(std::ios::binary | std::ios::out); + public_.save(out); + return py::bytes(out.str()); }); // kswitchkeys.h @@ -309,6 +340,11 @@ PYBIND11_MODULE(seal, m) std::ifstream in(path, std::ifstream::binary); rk.load(context, in); in.close(); + }) + .def("to_string", [](const RelinKeys &relin){ + std::stringstream out(std::ios::binary | std::ios::out); + relin.save(out); + return py::bytes(out.str()); }); // galoiskeys.h @@ -328,6 +364,11 @@ PYBIND11_MODULE(seal, m) std::ifstream in(path, std::ifstream::binary); gk.load(context, in); in.close(); + }) + .def("to_string", [](const GaloisKeys &galois){ + std::stringstream out(std::ios::binary | std::ios::out); + galois.save(out); + return py::bytes(out.str()); }); // keygenerator.h From 629c4678c1686fc87db6aa2cac10ea9db72c1fa1 Mon Sep 17 00:00:00 2001 From: huelse Date: Wed, 4 May 2022 14:28:26 +0800 Subject: [PATCH 4/5] Use `std::ios::binary` instead --- src/wrapper.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/wrapper.cpp b/src/wrapper.cpp index 79d6c85..270b7d4 100644 --- a/src/wrapper.cpp +++ b/src/wrapper.cpp @@ -209,12 +209,12 @@ PYBIND11_MODULE(seal, m) plain.scale() = scale; }) .def("save", [](const Plaintext &plain, const std::string &path){ - std::ofstream out(path, std::ofstream::binary); + std::ofstream out(path, std::ios::binary); plain.save(out); out.close(); }) .def("load", [](Plaintext &plain, const SEALContext &context, const std::string &path){ - std::ifstream in(path, std::ifstream::binary); + std::ifstream in(path, std::ios::binary); plain.load(context, in); in.close(); }) @@ -270,12 +270,12 @@ PYBIND11_MODULE(seal, m) .def(py::init()) .def("parms_id", py::overload_cast<>(&SecretKey::parms_id, py::const_)) .def("save", [](const SecretKey &sk, const std::string &path){ - std::ofstream out(path, std::ofstream::binary); + std::ofstream out(path, std::ios::binary); sk.save(out); out.close(); }) .def("load", [](SecretKey &sk, const SEALContext &context, const std::string &path){ - std::ifstream in(path, std::ifstream::binary); + std::ifstream in(path, std::ios::binary); sk.load(context, in); in.close(); }) @@ -291,12 +291,12 @@ PYBIND11_MODULE(seal, m) .def(py::init()) .def("parms_id", py::overload_cast<>(&PublicKey::parms_id, py::const_)) .def("save", [](const PublicKey &pk, const std::string &path){ - std::ofstream out(path, std::ofstream::binary); + std::ofstream out(path, std::ios::binary); pk.save(out); out.close(); }) .def("load", [](PublicKey &pk, const SEALContext &context, const std::string &path){ - std::ifstream in(path, std::ifstream::binary); + std::ifstream in(path, std::ios::binary); pk.load(context, in); in.close(); }) @@ -313,12 +313,12 @@ PYBIND11_MODULE(seal, m) .def("size", &KSwitchKeys::size) .def("parms_id", py::overload_cast<>(&KSwitchKeys::parms_id, py::const_)) .def("save", [](const KSwitchKeys &ksk, const std::string &path){ - std::ofstream out(path, std::ofstream::binary); + std::ofstream out(path, std::ios::binary); ksk.save(out); out.close(); }) .def("load", [](KSwitchKeys &ksk, const SEALContext &context, const std::string &path){ - std::ifstream in(path, std::ifstream::binary); + std::ifstream in(path, std::ios::binary); ksk.load(context, in); in.close(); }); @@ -332,12 +332,12 @@ PYBIND11_MODULE(seal, m) .def_static("get_index", &RelinKeys::get_index) .def("has_key", &RelinKeys::has_key) .def("save", [](const RelinKeys &rk, const std::string &path){ - std::ofstream out(path, std::ofstream::binary); + std::ofstream out(path, std::ios::binary); rk.save(out); out.close(); }) .def("load", [](RelinKeys &rk, const SEALContext &context, const std::string &path){ - std::ifstream in(path, std::ifstream::binary); + std::ifstream in(path, std::ios::binary); rk.load(context, in); in.close(); }) @@ -356,12 +356,12 @@ PYBIND11_MODULE(seal, m) .def_static("get_index", &GaloisKeys::get_index) .def("has_key", &GaloisKeys::has_key) .def("save", [](const GaloisKeys &gk, const std::string &path){ - std::ofstream out(path, std::ofstream::binary); + std::ofstream out(path, std::ios::binary); gk.save(out); out.close(); }) .def("load", [](GaloisKeys &gk, const SEALContext &context, const std::string &path){ - std::ifstream in(path, std::ifstream::binary); + std::ifstream in(path, std::ios::binary); gk.load(context, in); in.close(); }) From 7e5f990d039b31d1e1031b9146205344bd81f6e6 Mon Sep 17 00:00:00 2001 From: huelse Date: Wed, 4 May 2022 14:28:41 +0800 Subject: [PATCH 5/5] Add some details --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 95b5a6e..fd93396 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ This is a python binding for the Microsoft SEAL library. * ### Windows - Visual Studio 2019 or newer is required. And use the **x64 Native Tools Command Prompt for VS** command prompt to configure and build the Microsoft SEAL library. It's usually can be found in your Start Menu. + Visual Studio 2019 or newer is required. x64 support only! And use the **x64 Native Tools Command Prompt for VS** command prompt to configure and build the Microsoft SEAL library. It's usually can be found in your Start Menu. ```shell # Same as above @@ -74,6 +74,8 @@ This is a python binding for the Microsoft SEAL library. pip install numpy pybind11 python setup.py build_ext -i + + cp *.so examples ``` Microsoft SEAL official [docs](https://github.com/microsoft/SEAL#building-microsoft-seal-manually).