// BSD 2-Clause License // Copyright (c) 2023, OpenFHE // All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include "openfhe.h" #include "bindings.h" #include "utils/exception.h" // header files needed for serialization #include "serialization.h" #include "metadata-ser.h" #include "ciphertext-ser.h" #include "cryptocontext-ser.h" #include "key/key-ser.h" #include "scheme/bfvrns/bfvrns-ser.h" #include "scheme/bgvrns/bgvrns-ser.h" #include "scheme/ckksrns/ckksrns-ser.h" using namespace lbcrypto; namespace py = pybind11; template bool SerializeEvalMultKeyWrapper(const std::string &filename, const ST &sertype, std::string id) { std::ofstream outfile(filename, std::ios::out | std::ios::binary); bool res = CryptoContextImpl::SerializeEvalMultKey(outfile, sertype, id); outfile.close(); return res; } template bool SerializeEvalAutomorphismKeyWrapper(const std::string& filename, const ST& sertype, std::string id) { std::ofstream outfile(filename, std::ios::out | std::ios::binary); bool res = CryptoContextImpl::SerializeEvalAutomorphismKey(outfile, sertype, id); outfile.close(); return res; } template bool DeserializeEvalMultKeyWrapper(const std::string &filename, const ST &sertype) { std::ifstream emkeys(filename, std::ios::in | std::ios::binary); if (!emkeys.is_open()) { std::cerr << "I cannot read serialization from " << filename << std::endl; } bool res = CryptoContextImpl::DeserializeEvalMultKey(emkeys, sertype); return res; } template std::tuple DeserializeFromFileWrapper(const std::string& filename, const ST& sertype) { T newob; bool result = Serial::DeserializeFromFile(filename, newob, sertype); return std::make_tuple(newob, result); } template std::tuple, bool> DeserializeCCWrapper(const std::string& filename, const ST& sertype) { CryptoContext newob; bool result = Serial::DeserializeFromFile(filename, newob, sertype); return std::make_tuple(newob, result); } template std::string SerializeToStringWrapper(const T& obj, const ST& sertype) { std::ostringstream oss; Serial::Serialize(obj, oss, sertype); return oss.str(); } template py::bytes SerializeToBytesWrapper(const T& obj, const ST& sertype) { std::ostringstream oss(std::ios::binary); Serial::Serialize(obj, oss, sertype); std::string str = oss.str(); return py::bytes(str); } template T DeserializeFromStringWrapper(const std::string& str, const ST& sertype) { T obj; std::istringstream iss(str); Serial::Deserialize(obj, iss, sertype); return obj; } template CryptoContext DeserializeCCFromStringWrapper(const std::string& str, const ST& sertype) { CryptoContext obj; std::istringstream iss(str); Serial::Deserialize(obj, iss, sertype); return obj; } template T DeserializeFromBytesWrapper(const py::bytes& bytes, const ST& sertype) { T obj; std::string str(bytes); std::istringstream iss(str, std::ios::binary); Serial::Deserialize(obj, iss, sertype); return obj; } template CryptoContext DeserializeCCFromBytesWrapper(const py::bytes& bytes, const ST& sertype) { CryptoContext obj; std::string str(bytes); std::istringstream iss(str, std::ios::binary); Serial::Deserialize(obj, iss, sertype); return obj; } template std::string SerializeEvalMultKeyToStringWrapper(const ST& sertype, const std::string& id) { std::ostringstream oss; bool res = CryptoContextImpl::SerializeEvalMultKey(oss, sertype, id); if (!res) { throw std::runtime_error("Failed to serialize EvalMultKey"); } return oss.str(); } template py::bytes SerializeEvalMultKeyToBytesWrapper(const ST& sertype, const std::string& id) { std::ostringstream oss(std::ios::binary); bool res = CryptoContextImpl::SerializeEvalMultKey(oss, sertype, id); if (!res) { throw std::runtime_error("Failed to serialize EvalMultKey"); } std::string str = oss.str(); return py::bytes(str); } template std::string SerializeEvalAutomorphismKeyToStringWrapper(const ST& sertype, const std::string& id) { std::ostringstream oss; bool res = CryptoContextImpl::SerializeEvalAutomorphismKey(oss, sertype, id); if (!res) { throw std::runtime_error("Failed to serialize EvalAutomorphismKey"); } return oss.str(); } template py::bytes SerializeEvalAutomorphismKeyToBytesWrapper(const ST& sertype, const std::string& id) { std::ostringstream oss(std::ios::binary); bool res = CryptoContextImpl::SerializeEvalAutomorphismKey(oss, sertype, id); if (!res) { throw std::runtime_error("Failed to serialize EvalAutomorphismKey"); } return oss.str(); } template void DeserializeEvalMultKeyFromStringWrapper(const std::string& data, const ST& sertype) { std::istringstream iss(data); bool res = CryptoContextImpl::DeserializeEvalMultKey(iss, sertype); if (!res) { throw std::runtime_error("Failed to deserialize EvalMultKey"); } } template void DeserializeEvalMultKeyFromBytesWrapper(const std::string& data, const ST& sertype) { std::string str(data); std::istringstream iss(str, std::ios::binary); bool res = CryptoContextImpl::DeserializeEvalMultKey(iss, sertype); if (!res) { throw std::runtime_error("Failed to deserialize EvalMultKey"); } } template void DeserializeEvalAutomorphismKeyFromStringWrapper(const std::string& data, const ST& sertype) { std::istringstream iss(data); std::map>>> keyMap; bool res = CryptoContextImpl::DeserializeEvalAutomorphismKey(iss, sertype); if (!res) { throw std::runtime_error("Failed to deserialize EvalAutomorphismKey"); } } template void DeserializeEvalAutomorphismKeyFromBytesWrapper(const std::string& data, const ST& sertype) { std::string str(data); std::istringstream iss(str, std::ios::binary); bool res = CryptoContextImpl::DeserializeEvalAutomorphismKey(iss, sertype); if (!res) { throw std::runtime_error("Failed to deserialize EvalAutomorphismKey"); } } void bind_serialization(pybind11::module &m) { // Json Serialization m.def("SerializeToFile", static_cast &, const SerType::SERJSON &)>(&Serial::SerializeToFile), py::arg("filename"), py::arg("obj"), py::arg("sertype")); m.def("DeserializeCryptoContext", static_cast, bool> (*)(const std::string &, const SerType::SERJSON &)>(&DeserializeCCWrapper), py::arg("filename"), py::arg("sertype")); m.def("SerializeToFile", static_cast &, const SerType::SERJSON &)>(&Serial::SerializeToFile>), py::arg("filename"), py::arg("obj"), py::arg("sertype")); m.def("DeserializePublicKey", static_cast,bool> (*)(const std::string&, const SerType::SERJSON&)>(&DeserializeFromFileWrapper, SerType::SERJSON>), py::arg("filename"), py::arg("sertype")); m.def("SerializeToFile", static_cast&, const SerType::SERJSON&)>(&Serial::SerializeToFile>), py::arg("filename"), py::arg("obj"), py::arg("sertype")); m.def("DeserializePrivateKey", static_cast,bool> (*)(const std::string&, const SerType::SERJSON&)>(&DeserializeFromFileWrapper, SerType::SERJSON>), py::arg("filename"), py::arg("sertype")); m.def("SerializeToFile", static_cast&, const SerType::SERJSON&)>(&Serial::SerializeToFile>), py::arg("filename"), py::arg("obj"), py::arg("sertype")); m.def("DeserializeCiphertext", static_cast,bool> (*)(const std::string&, const SerType::SERJSON&)>(&DeserializeFromFileWrapper, SerType::SERJSON>), py::arg("filename"), py::arg("sertype")); m.def("SerializeToFile", static_cast&, const SerType::SERJSON&)>(&Serial::SerializeToFile>), py::arg("filename"), py::arg("obj"), py::arg("sertype")); m.def("DeserializeEvalKey", static_cast,bool> (*)(const std::string&, const SerType::SERJSON&)>(&DeserializeFromFileWrapper, SerType::SERJSON>), py::arg("filename"), py::arg("sertype")); // JSON Serialization to string m.def("Serialize", &SerializeToStringWrapper, SerType::SERJSON>, py::arg("obj"), py::arg("sertype")); m.def("DeserializeCryptoContextString", &DeserializeCCFromStringWrapper, py::arg("str"), py::arg("sertype")); m.def("Serialize", &SerializeToStringWrapper, SerType::SERJSON>, py::arg("obj"), py::arg("sertype")); m.def("DeserializePublicKeyString", &DeserializeFromStringWrapper, SerType::SERJSON>, py::arg("str"), py::arg("sertype")); m.def("Serialize", &SerializeToStringWrapper, SerType::SERJSON>, py::arg("obj"), py::arg("sertype")); m.def("DeserializePrivateKeyString", &DeserializeFromStringWrapper, SerType::SERJSON>, py::arg("str"), py::arg("sertype")); m.def("Serialize", &SerializeToStringWrapper, SerType::SERJSON>, py::arg("obj"), py::arg("sertype")); m.def("DeserializeCiphertextString", &DeserializeFromStringWrapper, SerType::SERJSON>, py::arg("str"), py::arg("sertype")); m.def("Serialize", &SerializeToStringWrapper, SerType::SERJSON>, py::arg("obj"), py::arg("sertype")); m.def("DeserializeEvalKeyString", &DeserializeFromStringWrapper, SerType::SERJSON>, py::arg("str"), py::arg("sertype")); m.def("SerializeEvalMultKeyString", &SerializeEvalMultKeyToStringWrapper, py::arg("sertype"), py::arg("id") = ""); m.def("DeserializeEvalMultKeyString", &DeserializeEvalMultKeyFromStringWrapper, py::arg("sertype"), py::arg("id") = ""); m.def("SerializeEvalAutomorphismKeyString", &SerializeEvalAutomorphismKeyToStringWrapper, py::arg("sertype"), py::arg("id") = ""); m.def("DeserializeEvalAutomorphismKeyString", &DeserializeEvalAutomorphismKeyFromStringWrapper, py::arg("sertype"), py::arg("id") = ""); // Binary Serialization m.def("SerializeToFile", static_cast&, const SerType::SERBINARY&)>(&Serial::SerializeToFile), py::arg("filename"), py::arg("obj"), py::arg("sertype")); m.def("DeserializeCryptoContext", static_cast,bool> (*)(const std::string&, const SerType::SERBINARY&)>(&DeserializeCCWrapper), py::arg("filename"), py::arg("sertype")); m.def("SerializeToFile", static_cast&, const SerType::SERBINARY&)>(&Serial::SerializeToFile>), py::arg("filename"), py::arg("obj"), py::arg("sertype")); m.def("DeserializePublicKey", static_cast,bool> (*)(const std::string&, const SerType::SERBINARY&)>(&DeserializeFromFileWrapper, SerType::SERBINARY>), py::arg("filename"), py::arg("sertype")); m.def("SerializeToFile", static_cast&, const SerType::SERBINARY&)>(&Serial::SerializeToFile>), py::arg("filename"), py::arg("obj"), py::arg("sertype")); m.def("DeserializePrivateKey", static_cast,bool> (*)(const std::string&, const SerType::SERBINARY&)>(&DeserializeFromFileWrapper, SerType::SERBINARY>), py::arg("filename"), py::arg("sertype")); m.def("SerializeToFile", static_cast&, const SerType::SERBINARY&)>(&Serial::SerializeToFile>), py::arg("filename"), py::arg("obj"), py::arg("sertype")); m.def("DeserializeCiphertext", static_cast,bool> (*)(const std::string&, const SerType::SERBINARY&)>(&DeserializeFromFileWrapper, SerType::SERBINARY>), py::arg("filename"), py::arg("sertype")); m.def("SerializeToFile", static_cast&, const SerType::SERBINARY&)>(&Serial::SerializeToFile>), py::arg("filename"), py::arg("obj"), py::arg("sertype")); m.def("DeserializeEvalKey", static_cast,bool> (*)(const std::string&, const SerType::SERBINARY&)>(&DeserializeFromFileWrapper, SerType::SERBINARY>), py::arg("filename"), py::arg("sertype")); // Binary Serialization to bytes m.def("Serialize", &SerializeToBytesWrapper, SerType::SERBINARY>, py::arg("obj"), py::arg("sertype")); m.def("DeserializeCryptoContextString", &DeserializeCCFromBytesWrapper, py::arg("str"), py::arg("sertype")); m.def("Serialize", &SerializeToBytesWrapper, SerType::SERBINARY>, py::arg("obj"), py::arg("sertype")); m.def("DeserializePublicKeyString", &DeserializeFromBytesWrapper, SerType::SERBINARY>, py::arg("str"), py::arg("sertype")); m.def("Serialize", &SerializeToBytesWrapper, SerType::SERBINARY>, py::arg("obj"), py::arg("sertype")); m.def("DeserializePrivateKeyString", &DeserializeFromBytesWrapper, SerType::SERBINARY>, py::arg("str"), py::arg("sertype")); m.def("Serialize", &SerializeToBytesWrapper, SerType::SERBINARY>, py::arg("obj"), py::arg("sertype")); m.def("DeserializeCiphertextString", &DeserializeFromBytesWrapper, SerType::SERBINARY>, py::arg("str"), py::arg("sertype")); m.def("Serialize", &SerializeToBytesWrapper, SerType::SERBINARY>, py::arg("obj"), py::arg("sertype")); m.def("DeserializeEvalKeyString", &DeserializeFromBytesWrapper, SerType::SERBINARY>, py::arg("str"), py::arg("sertype")); m.def("SerializeEvalMultKeyString", &SerializeEvalMultKeyToBytesWrapper, py::arg("sertype"), py::arg("id") = ""); m.def("DeserializeEvalMultKeyString", &DeserializeEvalMultKeyFromBytesWrapper, py::arg("sertype"), py::arg("id") = ""); m.def("SerializeEvalAutomorphismKeyString", &SerializeEvalAutomorphismKeyToBytesWrapper, py::arg("sertype"), py::arg("id") = ""); m.def("DeserializeEvalAutomorphismKeyString", &DeserializeEvalAutomorphismKeyFromBytesWrapper, py::arg("sertype"), py::arg("id") = ""); }