BFV context API

This commit is contained in:
York Jasper Niebuhr 2025-11-21 19:15:14 +01:00
parent 7bcec991ae
commit 5ad59651bc

View File

@ -1,15 +1,84 @@
#pragma once #pragma once
#include <cstddef>
#include <cstdint>
#include <type_traits>
#include <bit>
namespace homcert::bfv { namespace homcert::bfv {
constexpr std::size_t VECSIZE = 8192;
constexpr std::size_t PLAINMOD = 16760833; // 8192*2*1023+1 and prime
template<std::size_t N, typename = void>
struct smallest_uint;
template<std::size_t N>
struct smallest_uint<N, std::enable_if_t<(N <= UINT8_MAX)>> {
using type = std::uint8_t;
};
template<std::size_t N>
struct smallest_uint<N, std::enable_if_t<(UINT8_MAX < N && N <= UINT16_MAX)>> {
using type = std::uint16_t;
};
template<std::size_t N>
struct smallest_uint<N, std::enable_if_t<(UINT16_MAX < N && N <= UINT32_MAX)>> {
using type = std::uint32_t;
};
template<std::size_t N>
struct smallest_uint<N, std::enable_if_t<(UINT32_MAX < N)>> {
using type = std::uint64_t;
};
struct plaintext {
using coefficient = typename smallest_uint<PLAINMOD>::type;
std::array<coefficient, VECSIZE> coefficients;
// Arithmetic...
};
using ciphertext = int;
// Inheriting from context class allows pluggability of implementations (e.g. SEAL vs. GPU)
class context {
public:
context(const context& other) = delete;
context(context&& other) noexcept;
context& operator=(const context& other) = delete;
context& operator=(context&& other) noexcept;
context();
virtual ~context();
virtual bool allocate(ciphertext& ct) = 0;
virtual bool free(ciphertext ct) = 0;
virtual bool serialize(ciphertext ct, void* buf, std::size_t& n) = 0;
virtual bool deserialize(ciphertext ct, const void* buf, std::size_t n) = 0;
virtual bool encrypt(const plaintext& pt, ciphertext ct) = 0;
virtual bool decrypt(ciphertext ct, plaintext& pt) = 0;
virtual bool add_cipher_plain(ciphertext a, const plaintext& b, ciphertext res) = 0;
virtual bool add_cipher_cipher(ciphertext a, ciphertext b, ciphertext res) = 0;
virtual bool sub_cipher_plain(ciphertext a, const plaintext& b, ciphertext res) = 0;
virtual bool sub_cipher_cipher(ciphertext a, ciphertext b, ciphertext res) = 0;
virtual bool mul_cipher_plain(ciphertext a, const plaintext& b, ciphertext res) = 0;
virtual bool mul_cipher_cipher(ciphertext a, ciphertext b, ciphertext res) = 0;
virtual bool rot_cipher_rows(ciphertext ct, int r, ciphertext res) = 0;
virtual bool swap_cipher_rows(ciphertext ct, ciphertext res) = 0;
virtual bool noise_budget(ciphertext ct, std::size_t& budget) = 0;
};
/* /*
TODO NOTE -> Implementations may defer operations or not wait for them to finish
Device handles pluggability of implementations (e.g. SEAL vs. GPU) For example, GPU implementations may dispatch multiplications when they arive
Operations are queued on device so the device can parallelize ops Additionally, a graph of running operations is maintained to handle data dependencies
Only when data is required to actually be present (e.g. decrypt), does the implementation wait
*/ */
/* /*
No device class at all, just the context class which is handed to system as shared_ptr
activate_context(std::shared_ptr<bfv::context> ctx) -> thread local pointer is set activate_context(std::shared_ptr<bfv::context> ctx) -> thread local pointer is set
Raw ciphertext and plaintext classes always have the full 8192 coefficients (defined in context as static constexpr) Raw ciphertext and plaintext classes always have the full 8192 coefficients (defined in context as static constexpr)
bfv::vector<...> bfv::vector<...>
@ -32,6 +101,7 @@ Programs are defined TWICE
-> local stuff is executed -> local stuff is executed
-> remote stuff is hosted (e.g. bootstrapping server) -> remote stuff is hosted (e.g. bootstrapping server)
-> defined once from each side (differ e.g. in the plaintext inputs etc.) -> defined once from each side (differ e.g. in the plaintext inputs etc.)
-> program base class may be used to handle context setting
*/ */
} }