Progress on the SEAL BFV implementation
This commit is contained in:
parent
0893f6044c
commit
fab47a227a
@ -13,33 +13,8 @@ namespace homcert::bfv {
|
|||||||
constexpr std::size_t VECSIZE = 8192;
|
constexpr std::size_t VECSIZE = 8192;
|
||||||
constexpr std::size_t PLAINMOD = 16760833; // 8192*2*1023+1 and prime
|
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 {
|
struct plaintext {
|
||||||
using coefficient = typename smallest_uint<PLAINMOD>::type;
|
std::array<std::uint64_t, VECSIZE> slots;
|
||||||
|
|
||||||
std::array<coefficient, VECSIZE> coefficients;
|
|
||||||
|
|
||||||
// Arithmetic...
|
// Arithmetic...
|
||||||
};
|
};
|
||||||
@ -87,8 +62,8 @@ struct context {
|
|||||||
virtual void new_components() = 0; // context default constructs empty
|
virtual void new_components() = 0; // context default constructs empty
|
||||||
virtual void has_components(int& components) const = 0;
|
virtual void has_components(int& components) const = 0;
|
||||||
virtual void clone_components(int components, std::shared_ptr<context>& ptr) const = 0;
|
virtual void clone_components(int components, std::shared_ptr<context>& ptr) const = 0;
|
||||||
// virtual void dump_components(int components, void* buf, std::size_t& n) const = 0;
|
virtual void dump_components(int components, void* buf, std::size_t& n) const = 0;
|
||||||
// virtual void load_components(int components, const void* buf, std::size_t n) = 0;
|
virtual void load_components(const void* buf, std::size_t n) = 0;
|
||||||
|
|
||||||
virtual void allocate(ciphertext& ct) = 0;
|
virtual void allocate(ciphertext& ct) = 0;
|
||||||
virtual void free(ciphertext ct) = 0;
|
virtual void free(ciphertext ct) = 0;
|
||||||
@ -123,6 +98,8 @@ struct seal_context : public context {
|
|||||||
void new_components() override;
|
void new_components() override;
|
||||||
void has_components(int& components) const override;
|
void has_components(int& components) const override;
|
||||||
void clone_components(int components, std::shared_ptr<context>& ptr) const override;
|
void clone_components(int components, std::shared_ptr<context>& ptr) const override;
|
||||||
|
void dump_components(int components, void* buf, std::size_t& n) const override;
|
||||||
|
void load_components(const void* buf, std::size_t n) override;
|
||||||
void allocate(ciphertext& ct) override;
|
void allocate(ciphertext& ct) override;
|
||||||
void free(ciphertext ct) override;
|
void free(ciphertext ct) override;
|
||||||
void serialize(ciphertext ct, void* buf, std::size_t& n) const override;
|
void serialize(ciphertext ct, void* buf, std::size_t& n) const override;
|
||||||
|
|||||||
@ -81,10 +81,25 @@ struct seal_context_data {
|
|||||||
static minfree ctx_id_factory { 0 };
|
static minfree ctx_id_factory { 0 };
|
||||||
static std::unordered_map<int, seal_context_data> ctxs;
|
static std::unordered_map<int, seal_context_data> ctxs;
|
||||||
|
|
||||||
|
static seal::Plaintext encode_plaintext(const seal::BatchEncoder& encoder, const plaintext& pt) {
|
||||||
|
seal::Plaintext res;
|
||||||
|
|
||||||
|
try {
|
||||||
|
encoder.encode(gsl::span<const uint64_t>(pt.slots), res);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::string what;
|
||||||
|
what += "Microsoft SEAL failed to encode data (";
|
||||||
|
what += e.what();
|
||||||
|
what += ")";
|
||||||
|
throw bfv_exception(bfv_exception::REASON::CTX_INTERNAL, what);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(res);
|
||||||
|
}
|
||||||
|
|
||||||
seal_context::seal_context() : context{}, m_id{ -1 } {
|
seal_context::seal_context() : context{}, m_id{ -1 } {
|
||||||
if (!seal_bfv_ctx || !seal_bfv_ctx->parameters_set())
|
if (!seal_bfv_ctx || !seal_bfv_ctx->parameters_set())
|
||||||
throw bfv_exception(bfv_exception::REASON::CTX_INVALID,
|
return;
|
||||||
"Missing Microsoft SEAL parameter context!");
|
|
||||||
|
|
||||||
int tmp_id;
|
int tmp_id;
|
||||||
if (!ctx_id_factory.min(tmp_id))
|
if (!ctx_id_factory.min(tmp_id))
|
||||||
@ -173,6 +188,24 @@ void seal_context::clone_components(int components, std::shared_ptr<context>& pt
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void seal_context::dump_components(int components, void* buf, std::size_t& n) const {
|
||||||
|
if (!ctxs.contains(m_id))
|
||||||
|
throw bfv_exception(bfv_exception::REASON::CTX_INVALID,
|
||||||
|
"Object does not hold a valid Microsoft SEAL context!");
|
||||||
|
|
||||||
|
seal_context_data& data = ctxs.at(m_id);
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void seal_context::load_components(const void* buf, std::size_t n) {
|
||||||
|
if (!ctxs.contains(m_id))
|
||||||
|
throw bfv_exception(bfv_exception::REASON::CTX_INVALID,
|
||||||
|
"Object does not hold a valid Microsoft SEAL context!");
|
||||||
|
|
||||||
|
seal_context_data& data = ctxs.at(m_id);
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
void seal_context::allocate(ciphertext& ct) {
|
void seal_context::allocate(ciphertext& ct) {
|
||||||
ct = -1;
|
ct = -1;
|
||||||
|
|
||||||
@ -276,6 +309,8 @@ void seal_context::deserialize(ciphertext ct, const void* buf, std::size_t n) co
|
|||||||
throw bfv_exception(bfv_exception::REASON::CTX_INTERNAL,
|
throw bfv_exception(bfv_exception::REASON::CTX_INTERNAL,
|
||||||
"Microsoft SEAL failed to deserialize the specified data!");
|
"Microsoft SEAL failed to deserialize the specified data!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctbuf.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void seal_context::encrypt(const plaintext& pt, ciphertext ct) const {
|
void seal_context::encrypt(const plaintext& pt, ciphertext ct) const {
|
||||||
@ -284,7 +319,30 @@ void seal_context::encrypt(const plaintext& pt, ciphertext ct) const {
|
|||||||
"Object does not hold a valid Microsoft SEAL context!");
|
"Object does not hold a valid Microsoft SEAL context!");
|
||||||
|
|
||||||
seal_context_data& data = ctxs.at(m_id);
|
seal_context_data& data = ctxs.at(m_id);
|
||||||
// TODO
|
|
||||||
|
if (!(data.components & PUBLIC_COMPONENT))
|
||||||
|
throw bfv_exception(bfv_exception::REASON::CTX_COMPONENT,
|
||||||
|
"Context does not hold required PUBLIC_COMPONENT!");
|
||||||
|
|
||||||
|
if (!data.ciphertexts.contains(ct))
|
||||||
|
throw bfv_exception(bfv_exception::REASON::CTX_INVALID_ARGUMENT,
|
||||||
|
"The specified ciphertext does not exist in this context!");
|
||||||
|
|
||||||
|
ct_buffer& ctbuf = data.ciphertexts.at(ct);
|
||||||
|
|
||||||
|
seal::Plaintext encoded = encode_plaintext(*data.pub.encoder, pt);
|
||||||
|
|
||||||
|
try {
|
||||||
|
data.pub.encryptor->encrypt(encoded, ctbuf.value);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::string what;
|
||||||
|
what += "Microsoft SEAL failed to encrypt the given plaintext (";
|
||||||
|
what += e.what();
|
||||||
|
what += ")";
|
||||||
|
throw bfv_exception(bfv_exception::REASON::CTX_INTERNAL, what);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctbuf.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void seal_context::decrypt(ciphertext ct, plaintext& pt) const {
|
void seal_context::decrypt(ciphertext ct, plaintext& pt) const {
|
||||||
@ -399,6 +457,14 @@ void seal_context::clone_components(int components, std::shared_ptr<context>& pt
|
|||||||
throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented");
|
throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void seal_context::dump_components(int components, 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::load_components(const void* buf, std::size_t n) {
|
||||||
|
throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
void seal_context::allocate(ciphertext& ct) {
|
void seal_context::allocate(ciphertext& ct) {
|
||||||
throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented");
|
throw bfv_exception(bfv_exception::REASON::CTX_NOT_IMPLEMENTED, "BFV context for Microsoft SEAL is not implemented");
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user