diff --git a/src/math_utils/evaluator_wrapper.cpp b/src/math_utils/evaluator_wrapper.cpp index 4078acd..17978a5 100644 --- a/src/math_utils/evaluator_wrapper.cpp +++ b/src/math_utils/evaluator_wrapper.cpp @@ -235,23 +235,31 @@ namespace math_utils { } } - void EvaluatorWrapper::get_ptx_embedding(const seal::Ciphertext &ctx, const seal::RelinKeys& relin_keys, std::vector &ptx_decomposition) const { - seal::Ciphertext ctx_copy; - evaluator->relinearize(ctx, relin_keys, ctx_copy); - evaluator->mod_switch_to_inplace(ctx_copy, context.last_parms_id()); + void EvaluatorWrapper::get_ptx_embedding(const seal::Ciphertext &ctx, EmbeddedCiphertext &ptx_decomposition) const { - ptx_decomposition = std::move(decompose_to_plaintexts(context.last_context_data()->parms(), ctx_copy)); + ptx_decomposition = std::move(decompose_to_plaintexts(context.last_context_data()->parms(), ctx)); - for(auto & ptx : ptx_decomposition){ - evaluator->transform_to_ntt_inplace(ptx, context.first_parms_id()); - } } void EvaluatorWrapper::compose_to_ctx(const std::vector &ptx_decomposition, seal::Ciphertext &decoded) const { seal::Ciphertext ctx_copy(context, context.last_parms_id()); compose_to_ciphertext( context.last_context_data()->parms(), ptx_decomposition, ctx_copy); - decoded = ctx_copy; + decoded = std::move(ctx_copy); + } + + + void EvaluatorWrapper::mult_with_ptx_decomposition(const EmbeddedCiphertext &ptx_decomposition, const seal::Ciphertext &ctx, EncryptedEmbeddedCiphertext &result) const { +#ifdef DISTRIBICOM_DEBUG + assert(ptx_decomposition[0].is_ntt_form()); + assert(ctx.is_ntt_form()); +#endif + + std::vector result_copy(ptx_decomposition.size()); + for(auto i=0; imultiply_plain(ctx, ptx_decomposition[i], result_copy[i]); + } + result = std::move(result_copy); } void EvaluatorWrapper::scalar_multiply(std::uint64_t scalar, const seal::Ciphertext &right, @@ -268,4 +276,25 @@ namespace math_utils { } + void EvaluatorWrapper::transform_to_ntt_inplace(EmbeddedCiphertext &encoded) const { + for(auto & ptx_piece : encoded) { + evaluator->transform_to_ntt_inplace(ptx_piece, context.first_parms_id()); + } + } + + + void EvaluatorWrapper::add_embedded_ctxs(const EncryptedEmbeddedCiphertext &ctx_decomposition1, const EncryptedEmbeddedCiphertext &ctx_decomposition2, EncryptedEmbeddedCiphertext &result) const { +#ifdef DISTRIBICOM_DEBUG + assert(ctx_decomposition1[0].is_ntt_form()); + assert(ctx_decomposition2[0].is_ntt_form()); + assert(ctx_decomposition1.size()==ctx_decomposition2.size()); +#endif + + EncryptedEmbeddedCiphertext result_copy(ctx_decomposition1.size()); + for(auto i=0; iadd(ctx_decomposition1[i], ctx_decomposition2[i], result_copy[i]); + } + result = std::move(result_copy); + } + } diff --git a/src/math_utils/evaluator_wrapper.hpp b/src/math_utils/evaluator_wrapper.hpp index 7646f59..9998dd7 100644 --- a/src/math_utils/evaluator_wrapper.hpp +++ b/src/math_utils/evaluator_wrapper.hpp @@ -12,6 +12,14 @@ namespace math_utils { */ typedef std::vector SplitPlaintextNTTForm; + + /*** + * EmbeddedCiphertext represents a ciphertext that was embedded into plaintexts + */ + typedef std::vector EmbeddedCiphertext; + + typedef std::vector EncryptedEmbeddedCiphertext; + /*** * This class wraps and modifies the behaviour of seal::Evaluator to add wanted multiplication for distribicom. */ @@ -103,10 +111,20 @@ namespace math_utils { void trivial_ciphertext(const seal::Plaintext &ptx, seal::Ciphertext &result) const; /*** - * writes ptx embedding of ctx to ptx_decomposition after relinearizing ctx and putting switching to last modulus + * writes ptx embedding of ctx to ptx_decompositio */ - void get_ptx_embedding(const seal::Ciphertext &ctx, const seal::RelinKeys& relin_keys, std::vector &ptx_decomposition) const; + void get_ptx_embedding(const seal::Ciphertext &ctx, EmbeddedCiphertext &ptx_decomposition) const; void compose_to_ctx(const std::vector &ptx_decomposition, seal::Ciphertext &decoded) const; + + void + mult_with_ptx_decomposition(const EmbeddedCiphertext &ptx_decomposition, const seal::Ciphertext &ctx, + std::vector &result) const; + + void add_embedded_ctxs(const EncryptedEmbeddedCiphertext &ctx_decomposition1, + const EncryptedEmbeddedCiphertext &ctx_decomposition2, + EncryptedEmbeddedCiphertext &result) const; + + void transform_to_ntt_inplace(EmbeddedCiphertext &encoded) const; }; } \ No newline at end of file diff --git a/src/math_utils/matrix_operations.cpp b/src/math_utils/matrix_operations.cpp index bc9f22b..7483fd5 100644 --- a/src/math_utils/matrix_operations.cpp +++ b/src/math_utils/matrix_operations.cpp @@ -144,6 +144,13 @@ namespace math_utils { } } + void MatrixOperations::to_ntt(std::vector &m) const { + std::for_each(std::execution::par_unseq, m.begin(), m.end(), [this](seal::Plaintext &ptx) { + w_evaluator->evaluator->transform_to_ntt_inplace(ptx, this->w_evaluator->context.first_parms_id()); + }); + } + + void MatrixOperations::to_ntt(std::vector &m) const { std::for_each(std::execution::par_unseq, m.begin(), m.end(), [this](seal::Ciphertext &ctx) { w_evaluator->evaluator->transform_to_ntt_inplace(ctx); diff --git a/src/math_utils/matrix_operations.hpp b/src/math_utils/matrix_operations.hpp index c89d829..ac4c414 100644 --- a/src/math_utils/matrix_operations.hpp +++ b/src/math_utils/matrix_operations.hpp @@ -192,6 +192,7 @@ namespace math_utils { const matrix &b, matrix &result) const; + void to_ntt(std::vector &m) const; }; } diff --git a/src/services/manager.cpp b/src/services/manager.cpp index 9989ae8..c4eb99b 100644 --- a/src/services/manager.cpp +++ b/src/services/manager.cpp @@ -81,9 +81,9 @@ namespace services { std::shared_ptr Manager::distribute_work(const math_utils::matrix &db, const ClientDB &all_clients, - int rnd, int epoch, + int rnd, int epoch #ifdef DISTRIBICOM_DEBUG - const seal::GaloisKeys &expansion_key + ,const seal::GaloisKeys &expansion_key #endif ) { diff --git a/src/services/server.cpp b/src/services/server.cpp index 8eb2804..f8de829 100644 --- a/src/services/server.cpp +++ b/src/services/server.cpp @@ -113,9 +113,9 @@ std::shared_ptr services::FullServer::distribu // // todo: set specific round and handle. - ledger = manager.distribute_work(db_handle.mat, client_query_manager, 1, 1, + ledger = manager.distribute_work(db_handle.mat, client_query_manager, 1, 1 #ifdef DISTRIBICOM_DEBUG - client_query_manager.id_to_info.begin()->second->galois_keys + ,client_query_manager.id_to_info.begin()->second->galois_keys #endif ); } diff --git a/test/math_utils/evaluator_wrapper_test.cpp b/test/math_utils/evaluator_wrapper_test.cpp index 3f46283..44337f6 100644 --- a/test/math_utils/evaluator_wrapper_test.cpp +++ b/test/math_utils/evaluator_wrapper_test.cpp @@ -7,8 +7,12 @@ void order_of_ops_test1(); void order_of_ops_test2(std::shared_ptr all); +void ctx_composition_test(); + int evaluator_wrapper_test(int, char *[]) { + ctx_composition_test(); + mult_slow_vs_modified_test(); // commutative test. @@ -211,4 +215,26 @@ void benchmark_mult() { std::cout << "comparing mult_slow to both mult and mult_plain: " << std::endl; std::cout << "mult_slow / mult: " << double(mult_slow_time) / double(mult_time) << std::endl; std::cout << "mult_slow / mult_plain: " << double(mult_slow_time) / double(mult_plain_time) << std::endl; +} + +void ctx_composition_test() { + auto all = TestUtils::setup(TestUtils::DEFAULT_SETUP_CONFIGS); + + auto ptx = all->random_plaintext(); + seal::Ciphertext enc_ptx; + + + all->encryptor.encrypt_symmetric(ptx, enc_ptx); + + math_utils::EmbeddedCiphertext embedded_enc_ptx; + + all->w_evaluator->get_ptx_embedding(enc_ptx, embedded_enc_ptx); + + seal::Ciphertext unembedded_enc_ptx; + all->w_evaluator->compose_to_ctx(embedded_enc_ptx, unembedded_enc_ptx); + + seal::Plaintext decrypted_unembedded_enc_ptx; + all->decryptor.decrypt(unembedded_enc_ptx, decrypted_unembedded_enc_ptx); + + assert(decrypted_unembedded_enc_ptx.to_string() == ptx.to_string()); } \ No newline at end of file