From 93acf2839ca9255a5927dd5dedb74dffe91fa460 Mon Sep 17 00:00:00 2001 From: York Jasper Niebuhr Date: Thu, 27 Nov 2025 12:34:08 +0100 Subject: [PATCH] Implementation blueprint for Microsoft SEAL code --- include/bfv.hpp | 29 +++++ src/CMakeLists.txt | 2 +- src/bfv.cpp | 2 +- src/seal_bfv.cpp | 175 ++++++++++++++++++++++++++++ test/CMakeLists.txt | 4 +- test/bfv/{main.cpp => bfv_seal.cpp} | 11 +- 6 files changed, 213 insertions(+), 10 deletions(-) create mode 100644 src/seal_bfv.cpp rename test/bfv/{main.cpp => bfv_seal.cpp} (60%) diff --git a/include/bfv.hpp b/include/bfv.hpp index 0c21c17..b407c37 100644 --- a/include/bfv.hpp +++ b/include/bfv.hpp @@ -51,6 +51,7 @@ using ciphertext = int; class bfv_exception : public std::exception { public: enum class REASON { + CTX_NOT_IMPLEMENTED, CTX_NO_PRIVATE, CTX_NO_PUBLIC, CTX_ARITHMETIC, @@ -105,6 +106,34 @@ Additionally, a graph of running operations is maintained to handle data depende Only when data is required to actually be present (e.g. decrypt), does the implementation wait */ +// BFV implementation using Microsoft SEAL + +struct seal_context : public context { + seal_context(); + ~seal_context(); + + void new_components(int components) override; + void has_components(int components) const override; + void clone_components(int components, std::shared_ptr& ptr) const override; + void allocate(ciphertext& ct) override; + void free(ciphertext ct) override; + void serialize(ciphertext ct, void* buf, std::size_t& n) const override; + void deserialize(ciphertext ct, const void* buf, std::size_t n) const override; + void encrypt(const plaintext& pt, ciphertext ct) const override; + void decrypt(ciphertext ct, plaintext& pt) const override; + void add_cipher_plain(ciphertext a, const plaintext& b, ciphertext res) const override; + void add_cipher_cipher(ciphertext a, ciphertext b, ciphertext res) const override; + void sub_cipher_plain(ciphertext a, const plaintext& b, ciphertext res) const override; + void sub_cipher_cipher(ciphertext a, ciphertext b, ciphertext res) const override; + void mul_cipher_plain(ciphertext a, const plaintext& b, ciphertext res) const override; + void mul_cipher_cipher(ciphertext a, ciphertext b, ciphertext res) const override; + void rot_cipher_rows(ciphertext ct, int r, ciphertext res) const override; + void swap_cipher_rows(ciphertext ct, ciphertext res) const override; + void noise_budget(ciphertext ct, std::size_t& budget) const override; +private: + int m_id; +}; + /* activate_context(std::shared_ptr ctx) -> thread local pointer is set Raw ciphertext and plaintext classes always have the full 8192 coefficients (defined in context as static constexpr) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cc5664e..834a744 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1 +1 @@ -target_sources(homcert PRIVATE bfv.cpp) +target_sources(homcert PRIVATE bfv.cpp seal_bfv.cpp) diff --git a/src/bfv.cpp b/src/bfv.cpp index 7e6e7ae..d0d9e3f 100644 --- a/src/bfv.cpp +++ b/src/bfv.cpp @@ -13,4 +13,4 @@ const char* bfv_exception::what() const noexcept { return m_message.c_str(); } -}; +} diff --git a/src/seal_bfv.cpp b/src/seal_bfv.cpp new file mode 100644 index 0000000..9f9af91 --- /dev/null +++ b/src/seal_bfv.cpp @@ -0,0 +1,175 @@ +#include + +#ifdef HOMCERT_BFV_SEAL + +namespace homcert::bfv { + +seal_context::seal_context() { + +} + +seal_context::~seal_context() { + +} + +void seal_context::new_components(int components) { + +} + +void seal_context::has_components(int components) const { + +} + +void seal_context::clone_components(int components, std::shared_ptr& ptr) const { + +} + +void seal_context::allocate(ciphertext& ct) { + +} + +void seal_context::free(ciphertext ct) { + +} + +void seal_context::serialize(ciphertext ct, void* buf, std::size_t& n) const { + +} + +void seal_context::deserialize(ciphertext ct, const void* buf, std::size_t n) const { + +} + +void seal_context::encrypt(const plaintext& pt, ciphertext ct) const { + +} + +void seal_context::decrypt(ciphertext ct, plaintext& pt) const { + +} + +void seal_context::add_cipher_plain(ciphertext a, const plaintext& b, ciphertext res) const { + +} + +void seal_context::add_cipher_cipher(ciphertext a, ciphertext b, ciphertext res) const { + +} + +void seal_context::sub_cipher_plain(ciphertext a, const plaintext& b, ciphertext res) const { + +} + +void seal_context::sub_cipher_cipher(ciphertext a, ciphertext b, ciphertext res) const { + +} + +void seal_context::mul_cipher_plain(ciphertext a, const plaintext& b, ciphertext res) const { + +} + +void seal_context::mul_cipher_cipher(ciphertext a, ciphertext b, ciphertext res) const { + +} + +void seal_context::rot_cipher_rows(ciphertext ct, int r, ciphertext res) const { + +} + +void seal_context::swap_cipher_rows(ciphertext ct, ciphertext res) const { + +} + +void seal_context::noise_budget(ciphertext ct, std::size_t& budget) const { + +} + +} + +#else + +namespace homcert::bfv { + +seal_context::seal_context() { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +seal_context::~seal_context() { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::new_components(int components) { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::has_components(int components) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::clone_components(int components, std::shared_ptr& ptr) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::allocate(ciphertext& ct) { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::free(ciphertext ct) { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::serialize(ciphertext ct, void* buf, std::size_t& n) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::deserialize(ciphertext ct, const void* buf, std::size_t n) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::encrypt(const plaintext& pt, ciphertext ct) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::decrypt(ciphertext ct, plaintext& pt) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::add_cipher_plain(ciphertext a, const plaintext& b, ciphertext res) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::add_cipher_cipher(ciphertext a, ciphertext b, ciphertext res) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::sub_cipher_plain(ciphertext a, const plaintext& b, ciphertext res) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::sub_cipher_cipher(ciphertext a, ciphertext b, ciphertext res) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::mul_cipher_plain(ciphertext a, const plaintext& b, ciphertext res) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::mul_cipher_cipher(ciphertext a, ciphertext b, ciphertext res) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::rot_cipher_rows(ciphertext ct, int r, ciphertext res) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::swap_cipher_rows(ciphertext ct, ciphertext res) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +void seal_context::noise_budget(ciphertext ct, std::size_t& budget) const { + throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented"); +} + +} + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index af52a7e..8963d6f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,6 @@ find_package(GTest REQUIRED) if (HOMCERT_BFV_SEAL) - add_executable(test_bfv bfv/main.cpp) - target_link_libraries(test_bfv PRIVATE homcert GTest::GTest) + add_executable(test_bfv_seal bfv/bfv_seal.cpp) + target_link_libraries(test_bfv_seal PRIVATE homcert GTest::GTest) endif() diff --git a/test/bfv/main.cpp b/test/bfv/bfv_seal.cpp similarity index 60% rename from test/bfv/main.cpp rename to test/bfv/bfv_seal.cpp index aed80f0..7ef9c54 100644 --- a/test/bfv/main.cpp +++ b/test/bfv/bfv_seal.cpp @@ -7,15 +7,14 @@ using namespace homcert; -class BFV : public ::testing::Test { +class BFV_SEAL : public ::testing::Test { protected: - std::shared_ptr m_context; -}; + inline static std::shared_ptr CTX0; -class BFV_SEAL : public BFV { -protected: static void SetUpTestSuite() { - // GTEST_SKIP() << "Test environment not available"; + CTX0 = std::make_shared(); + if (!CTX0) + GTEST_SKIP() << "Microsoft SEAL BFV implementation is not available!"; } static void TearDownTestSuite() {}