serialization.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. // BSD 2-Clause License
  2. // Copyright (c) 2023, OpenFHE
  3. // All rights reserved.
  4. // Redistribution and use in source and binary forms, with or without
  5. // modification, are permitted provided that the following conditions are met:
  6. // 1. Redistributions of source code must retain the above copyright notice, this
  7. // list of conditions and the following disclaimer.
  8. // 2. Redistributions in binary form must reproduce the above copyright notice,
  9. // this list of conditions and the following disclaimer in the documentation
  10. // and/or other materials provided with the distribution.
  11. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  12. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  13. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  14. // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  15. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  16. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  17. // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  18. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  19. // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  20. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  21. #include <pybind11/pybind11.h>
  22. #include <pybind11/stl.h>
  23. #include "openfhe.h"
  24. #include "bindings.h"
  25. #include "utils/exception.h"
  26. // header files needed for serialization
  27. #include "serialization.h"
  28. #include "metadata-ser.h"
  29. #include "ciphertext-ser.h"
  30. #include "cryptocontext-ser.h"
  31. #include "key/key-ser.h"
  32. #include "scheme/bfvrns/bfvrns-ser.h"
  33. #include "scheme/bgvrns/bgvrns-ser.h"
  34. #include "scheme/ckksrns/ckksrns-ser.h"
  35. using namespace lbcrypto;
  36. namespace py = pybind11;
  37. template <typename ST>
  38. bool SerializeEvalMultKeyWrapper(const std::string &filename, const ST &sertype, std::string id)
  39. {
  40. std::ofstream outfile(filename, std::ios::out | std::ios::binary);
  41. bool res = CryptoContextImpl<DCRTPoly>::SerializeEvalMultKey<ST>(outfile, sertype, id);
  42. outfile.close();
  43. return res;
  44. }
  45. template <typename ST>
  46. bool SerializeEvalAutomorphismKeyWrapper(const std::string& filename, const ST& sertype, std::string id)
  47. {
  48. std::ofstream outfile(filename, std::ios::out | std::ios::binary);
  49. bool res = CryptoContextImpl<DCRTPoly>::SerializeEvalAutomorphismKey<ST>(outfile, sertype, id);
  50. outfile.close();
  51. return res;
  52. }
  53. template <typename ST>
  54. bool DeserializeEvalMultKeyWrapper(const std::string &filename, const ST &sertype)
  55. {
  56. std::ifstream emkeys(filename, std::ios::in | std::ios::binary);
  57. if (!emkeys.is_open())
  58. {
  59. std::cerr << "I cannot read serialization from " << filename << std::endl;
  60. }
  61. bool res = CryptoContextImpl<DCRTPoly>::DeserializeEvalMultKey<ST>(emkeys, sertype);
  62. return res; }
  63. template <typename T, typename ST>
  64. std::tuple<T, bool> DeserializeFromFileWrapper(const std::string& filename, const ST& sertype) {
  65. T newob;
  66. bool result = Serial::DeserializeFromFile<T>(filename, newob, sertype);
  67. return std::make_tuple(newob, result);
  68. }
  69. template <typename ST>
  70. std::tuple<CryptoContext<DCRTPoly>, bool> DeserializeCCWrapper(const std::string& filename, const ST& sertype) {
  71. CryptoContext<DCRTPoly> newob;
  72. bool result = Serial::DeserializeFromFile<DCRTPoly>(filename, newob, sertype);
  73. return std::make_tuple(newob, result);
  74. }
  75. template <typename T, typename ST>
  76. std::string SerializeToStringWrapper(const T& obj, const ST& sertype) {
  77. std::ostringstream oss;
  78. Serial::Serialize<T>(obj, oss, sertype);
  79. return oss.str();
  80. }
  81. template <typename T, typename ST>
  82. py::bytes SerializeToBytesWrapper(const T& obj, const ST& sertype) {
  83. std::ostringstream oss(std::ios::binary);
  84. Serial::Serialize<T>(obj, oss, sertype);
  85. std::string str = oss.str();
  86. return py::bytes(str);
  87. }
  88. template <typename T, typename ST>
  89. T DeserializeFromStringWrapper(const std::string& str, const ST& sertype) {
  90. T obj;
  91. std::istringstream iss(str);
  92. Serial::Deserialize<T>(obj, iss, sertype);
  93. return obj;
  94. }
  95. template <typename ST>
  96. CryptoContext<DCRTPoly> DeserializeCCFromStringWrapper(const std::string& str, const ST& sertype) {
  97. CryptoContext<DCRTPoly> obj;
  98. std::istringstream iss(str);
  99. Serial::Deserialize<DCRTPoly>(obj, iss, sertype);
  100. return obj;
  101. }
  102. template <typename T, typename ST>
  103. T DeserializeFromBytesWrapper(const py::bytes& bytes, const ST& sertype) {
  104. T obj;
  105. std::string str(bytes);
  106. std::istringstream iss(str, std::ios::binary);
  107. Serial::Deserialize<T>(obj, iss, sertype);
  108. return obj;
  109. }
  110. template <typename ST>
  111. CryptoContext<DCRTPoly> DeserializeCCFromBytesWrapper(const py::bytes& bytes, const ST& sertype) {
  112. CryptoContext<DCRTPoly> obj;
  113. std::string str(bytes);
  114. std::istringstream iss(str, std::ios::binary);
  115. Serial::Deserialize<DCRTPoly>(obj, iss, sertype);
  116. return obj;
  117. }
  118. template <typename ST>
  119. std::string SerializeEvalMultKeyToStringWrapper(const ST& sertype, const std::string& id) {
  120. std::ostringstream oss;
  121. bool res = CryptoContextImpl<DCRTPoly>::SerializeEvalMultKey(oss, sertype, id);
  122. if (!res) {
  123. throw std::runtime_error("Failed to serialize EvalMultKey");
  124. }
  125. return oss.str();
  126. }
  127. template <typename ST>
  128. py::bytes SerializeEvalMultKeyToBytesWrapper(const ST& sertype, const std::string& id) {
  129. std::ostringstream oss(std::ios::binary);
  130. bool res = CryptoContextImpl<DCRTPoly>::SerializeEvalMultKey(oss, sertype, id);
  131. if (!res) {
  132. throw std::runtime_error("Failed to serialize EvalMultKey");
  133. }
  134. std::string str = oss.str();
  135. return py::bytes(str);
  136. }
  137. template <typename ST>
  138. std::string SerializeEvalAutomorphismKeyToStringWrapper(const ST& sertype, const std::string& id) {
  139. std::ostringstream oss;
  140. bool res = CryptoContextImpl<DCRTPoly>::SerializeEvalAutomorphismKey(oss, sertype, id);
  141. if (!res) {
  142. throw std::runtime_error("Failed to serialize EvalAutomorphismKey");
  143. }
  144. return oss.str();
  145. }
  146. template <typename ST>
  147. py::bytes SerializeEvalAutomorphismKeyToBytesWrapper(const ST& sertype, const std::string& id) {
  148. std::ostringstream oss(std::ios::binary);
  149. bool res = CryptoContextImpl<DCRTPoly>::SerializeEvalAutomorphismKey(oss, sertype, id);
  150. if (!res) {
  151. throw std::runtime_error("Failed to serialize EvalAutomorphismKey");
  152. }
  153. return oss.str();
  154. }
  155. template <typename ST>
  156. void DeserializeEvalMultKeyFromStringWrapper(const std::string& data, const ST& sertype) {
  157. std::istringstream iss(data);
  158. bool res = CryptoContextImpl<DCRTPoly>::DeserializeEvalMultKey<ST>(iss, sertype);
  159. if (!res) {
  160. throw std::runtime_error("Failed to deserialize EvalMultKey");
  161. }
  162. }
  163. template <typename ST>
  164. void DeserializeEvalMultKeyFromBytesWrapper(const std::string& data, const ST& sertype) {
  165. std::string str(data);
  166. std::istringstream iss(str, std::ios::binary);
  167. bool res = CryptoContextImpl<DCRTPoly>::DeserializeEvalMultKey<ST>(iss, sertype);
  168. if (!res) {
  169. throw std::runtime_error("Failed to deserialize EvalMultKey");
  170. }
  171. }
  172. template <typename ST>
  173. void DeserializeEvalAutomorphismKeyFromStringWrapper(const std::string& data, const ST& sertype) {
  174. std::istringstream iss(data);
  175. std::map<std::string, std::shared_ptr<std::map<usint, EvalKey<DCRTPoly>>>> keyMap;
  176. bool res = CryptoContextImpl<DCRTPoly>::DeserializeEvalAutomorphismKey<ST>(iss, sertype);
  177. if (!res) {
  178. throw std::runtime_error("Failed to deserialize EvalAutomorphismKey");
  179. }
  180. }
  181. template <typename ST>
  182. void DeserializeEvalAutomorphismKeyFromBytesWrapper(const std::string& data, const ST& sertype) {
  183. std::string str(data);
  184. std::istringstream iss(str, std::ios::binary);
  185. bool res = CryptoContextImpl<DCRTPoly>::DeserializeEvalAutomorphismKey<ST>(iss, sertype);
  186. if (!res) {
  187. throw std::runtime_error("Failed to deserialize EvalAutomorphismKey");
  188. }
  189. }
  190. void bind_serialization(pybind11::module &m) {
  191. // Json Serialization
  192. m.def("SerializeToFile", static_cast<bool (*)(const std::string &, const CryptoContext<DCRTPoly> &, const SerType::SERJSON &)>(&Serial::SerializeToFile<DCRTPoly>),
  193. py::arg("filename"), py::arg("obj"), py::arg("sertype"));
  194. m.def("DeserializeCryptoContext", static_cast<std::tuple<CryptoContext<DCRTPoly>, bool> (*)(const std::string &, const SerType::SERJSON &)>(&DeserializeCCWrapper<SerType::SERJSON>),
  195. py::arg("filename"), py::arg("sertype"));
  196. m.def("SerializeToFile", static_cast<bool (*)(const std::string &, const PublicKey<DCRTPoly> &, const SerType::SERJSON &)>(&Serial::SerializeToFile<PublicKey<DCRTPoly>>),
  197. py::arg("filename"), py::arg("obj"), py::arg("sertype"));
  198. m.def("DeserializePublicKey", static_cast<std::tuple<PublicKey<DCRTPoly>,bool> (*)(const std::string&, const SerType::SERJSON&)>(&DeserializeFromFileWrapper<PublicKey<DCRTPoly>, SerType::SERJSON>),
  199. py::arg("filename"), py::arg("sertype"));
  200. m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const PrivateKey<DCRTPoly>&, const SerType::SERJSON&)>(&Serial::SerializeToFile<PrivateKey<DCRTPoly>>),
  201. py::arg("filename"), py::arg("obj"), py::arg("sertype"));
  202. m.def("DeserializePrivateKey", static_cast<std::tuple<PrivateKey<DCRTPoly>,bool> (*)(const std::string&, const SerType::SERJSON&)>(&DeserializeFromFileWrapper<PrivateKey<DCRTPoly>, SerType::SERJSON>),
  203. py::arg("filename"), py::arg("sertype"));
  204. m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const Ciphertext<DCRTPoly>&, const SerType::SERJSON&)>(&Serial::SerializeToFile<Ciphertext<DCRTPoly>>),
  205. py::arg("filename"), py::arg("obj"), py::arg("sertype"));
  206. m.def("DeserializeCiphertext", static_cast<std::tuple<Ciphertext<DCRTPoly>,bool> (*)(const std::string&, const SerType::SERJSON&)>(&DeserializeFromFileWrapper<Ciphertext<DCRTPoly>, SerType::SERJSON>),
  207. py::arg("filename"), py::arg("sertype"));
  208. m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const EvalKey<DCRTPoly>&, const SerType::SERJSON&)>(&Serial::SerializeToFile<EvalKey<DCRTPoly>>),
  209. py::arg("filename"), py::arg("obj"), py::arg("sertype"));
  210. m.def("DeserializeEvalKey", static_cast<std::tuple<EvalKey<DCRTPoly>,bool> (*)(const std::string&, const SerType::SERJSON&)>(&DeserializeFromFileWrapper<EvalKey<DCRTPoly>, SerType::SERJSON>),
  211. py::arg("filename"), py::arg("sertype"));
  212. // JSON Serialization to string
  213. m.def("Serialize", &SerializeToStringWrapper<CryptoContext<DCRTPoly>, SerType::SERJSON>,
  214. py::arg("obj"), py::arg("sertype"));
  215. m.def("DeserializeCryptoContextString", &DeserializeCCFromStringWrapper<SerType::SERJSON>,
  216. py::arg("str"), py::arg("sertype"));
  217. m.def("Serialize", &SerializeToStringWrapper<PublicKey<DCRTPoly>, SerType::SERJSON>,
  218. py::arg("obj"), py::arg("sertype"));
  219. m.def("DeserializePublicKeyString", &DeserializeFromStringWrapper<PublicKey<DCRTPoly>, SerType::SERJSON>,
  220. py::arg("str"), py::arg("sertype"));
  221. m.def("Serialize", &SerializeToStringWrapper<PrivateKey<DCRTPoly>, SerType::SERJSON>,
  222. py::arg("obj"), py::arg("sertype"));
  223. m.def("DeserializePrivateKeyString", &DeserializeFromStringWrapper<PrivateKey<DCRTPoly>, SerType::SERJSON>,
  224. py::arg("str"), py::arg("sertype"));
  225. m.def("Serialize", &SerializeToStringWrapper<Ciphertext<DCRTPoly>, SerType::SERJSON>,
  226. py::arg("obj"), py::arg("sertype"));
  227. m.def("DeserializeCiphertextString", &DeserializeFromStringWrapper<Ciphertext<DCRTPoly>, SerType::SERJSON>,
  228. py::arg("str"), py::arg("sertype"));
  229. m.def("Serialize", &SerializeToStringWrapper<EvalKey<DCRTPoly>, SerType::SERJSON>,
  230. py::arg("obj"), py::arg("sertype"));
  231. m.def("DeserializeEvalKeyString", &DeserializeFromStringWrapper<EvalKey<DCRTPoly>, SerType::SERJSON>,
  232. py::arg("str"), py::arg("sertype"));
  233. m.def("SerializeEvalMultKeyString", &SerializeEvalMultKeyToStringWrapper<SerType::SERJSON>,
  234. py::arg("sertype"), py::arg("id") = "");
  235. m.def("DeserializeEvalMultKeyString", &DeserializeEvalMultKeyFromStringWrapper<SerType::SERJSON>,
  236. py::arg("sertype"), py::arg("id") = "");
  237. m.def("SerializeEvalAutomorphismKeyString", &SerializeEvalAutomorphismKeyToStringWrapper<SerType::SERJSON>,
  238. py::arg("sertype"), py::arg("id") = "");
  239. m.def("DeserializeEvalAutomorphismKeyString", &DeserializeEvalAutomorphismKeyFromStringWrapper<SerType::SERJSON>,
  240. py::arg("sertype"), py::arg("id") = "");
  241. // Binary Serialization
  242. m.def("SerializeToFile", static_cast<bool (*)(const std::string&,const CryptoContext<DCRTPoly>&, const SerType::SERBINARY&)>(&Serial::SerializeToFile<DCRTPoly>),
  243. py::arg("filename"), py::arg("obj"), py::arg("sertype"));
  244. m.def("DeserializeCryptoContext", static_cast<std::tuple<CryptoContext<DCRTPoly>,bool> (*)(const std::string&, const SerType::SERBINARY&)>(&DeserializeCCWrapper<SerType::SERBINARY>),
  245. py::arg("filename"), py::arg("sertype"));
  246. m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const PublicKey<DCRTPoly>&, const SerType::SERBINARY&)>(&Serial::SerializeToFile<PublicKey<DCRTPoly>>),
  247. py::arg("filename"), py::arg("obj"), py::arg("sertype"));
  248. m.def("DeserializePublicKey", static_cast<std::tuple<PublicKey<DCRTPoly>,bool> (*)(const std::string&, const SerType::SERBINARY&)>(&DeserializeFromFileWrapper<PublicKey<DCRTPoly>, SerType::SERBINARY>),
  249. py::arg("filename"), py::arg("sertype"));
  250. m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const PrivateKey<DCRTPoly>&, const SerType::SERBINARY&)>(&Serial::SerializeToFile<PrivateKey<DCRTPoly>>),
  251. py::arg("filename"), py::arg("obj"), py::arg("sertype"));
  252. m.def("DeserializePrivateKey", static_cast<std::tuple<PrivateKey<DCRTPoly>,bool> (*)(const std::string&, const SerType::SERBINARY&)>(&DeserializeFromFileWrapper<PrivateKey<DCRTPoly>, SerType::SERBINARY>),
  253. py::arg("filename"), py::arg("sertype"));
  254. m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const Ciphertext<DCRTPoly>&, const SerType::SERBINARY&)>(&Serial::SerializeToFile<Ciphertext<DCRTPoly>>),
  255. py::arg("filename"), py::arg("obj"), py::arg("sertype"));
  256. m.def("DeserializeCiphertext", static_cast<std::tuple<Ciphertext<DCRTPoly>,bool> (*)(const std::string&, const SerType::SERBINARY&)>(&DeserializeFromFileWrapper<Ciphertext<DCRTPoly>, SerType::SERBINARY>),
  257. py::arg("filename"), py::arg("sertype"));
  258. m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const EvalKey<DCRTPoly>&, const SerType::SERBINARY&)>(&Serial::SerializeToFile<EvalKey<DCRTPoly>>),
  259. py::arg("filename"), py::arg("obj"), py::arg("sertype"));
  260. m.def("DeserializeEvalKey", static_cast<std::tuple<EvalKey<DCRTPoly>,bool> (*)(const std::string&, const SerType::SERBINARY&)>(&DeserializeFromFileWrapper<EvalKey<DCRTPoly>, SerType::SERBINARY>),
  261. py::arg("filename"), py::arg("sertype"));
  262. // Binary Serialization to bytes
  263. m.def("Serialize", &SerializeToBytesWrapper<CryptoContext<DCRTPoly>, SerType::SERBINARY>,
  264. py::arg("obj"), py::arg("sertype"));
  265. m.def("DeserializeCryptoContextString", &DeserializeCCFromBytesWrapper<SerType::SERBINARY>,
  266. py::arg("str"), py::arg("sertype"));
  267. m.def("Serialize", &SerializeToBytesWrapper<PublicKey<DCRTPoly>, SerType::SERBINARY>,
  268. py::arg("obj"), py::arg("sertype"));
  269. m.def("DeserializePublicKeyString", &DeserializeFromBytesWrapper<PublicKey<DCRTPoly>, SerType::SERBINARY>,
  270. py::arg("str"), py::arg("sertype"));
  271. m.def("Serialize", &SerializeToBytesWrapper<PrivateKey<DCRTPoly>, SerType::SERBINARY>,
  272. py::arg("obj"), py::arg("sertype"));
  273. m.def("DeserializePrivateKeyString", &DeserializeFromBytesWrapper<PrivateKey<DCRTPoly>, SerType::SERBINARY>,
  274. py::arg("str"), py::arg("sertype"));
  275. m.def("Serialize", &SerializeToBytesWrapper<Ciphertext<DCRTPoly>, SerType::SERBINARY>,
  276. py::arg("obj"), py::arg("sertype"));
  277. m.def("DeserializeCiphertextString", &DeserializeFromBytesWrapper<Ciphertext<DCRTPoly>, SerType::SERBINARY>,
  278. py::arg("str"), py::arg("sertype"));
  279. m.def("Serialize", &SerializeToBytesWrapper<EvalKey<DCRTPoly>, SerType::SERBINARY>,
  280. py::arg("obj"), py::arg("sertype"));
  281. m.def("DeserializeEvalKeyString", &DeserializeFromBytesWrapper<EvalKey<DCRTPoly>, SerType::SERBINARY>,
  282. py::arg("str"), py::arg("sertype"));
  283. m.def("SerializeEvalMultKeyString", &SerializeEvalMultKeyToBytesWrapper<SerType::SERBINARY>,
  284. py::arg("sertype"), py::arg("id") = "");
  285. m.def("DeserializeEvalMultKeyString", &DeserializeEvalMultKeyFromBytesWrapper<SerType::SERBINARY>,
  286. py::arg("sertype"), py::arg("id") = "");
  287. m.def("SerializeEvalAutomorphismKeyString", &SerializeEvalAutomorphismKeyToBytesWrapper<SerType::SERBINARY>,
  288. py::arg("sertype"), py::arg("id") = "");
  289. m.def("DeserializeEvalAutomorphismKeyString", &DeserializeEvalAutomorphismKeyFromBytesWrapper<SerType::SERBINARY>,
  290. py::arg("sertype"), py::arg("id") = "");
  291. }