#pragma once #include "pir.hpp" #include "pir_client.hpp" #include #include #include class PIRServer { public: PIRServer(const seal::EncryptionParameters &enc_params, const PirParams &pir_params); // NOTE: server takes over ownership of db and frees it when it exits. // Caller cannot free db void set_database(std::unique_ptr> &&db); void set_database(const std::unique_ptr &bytes, std::uint64_t ele_num, std::uint64_t ele_size); void preprocess_database(); std::vector expand_query(const seal::Ciphertext &encrypted, std::uint32_t m, std::uint32_t client_id); PirQuery deserialize_query(std::stringstream &stream); PirReply generate_reply(PirQuery &query, std::uint32_t client_id); // Serializes the reply into the provided stream and returns the number of // bytes written int serialize_reply(PirReply &reply, std::stringstream &stream); void set_galois_key(std::uint32_t client_id, seal::GaloisKeys galkey); // Below simple operations are for interacting with the database WITHOUT PIR. // So they can be used to modify a particular element in the database or // to query a particular element (without privacy guarantees). void simple_set(std::uint64_t index, seal::Plaintext pt); seal::Ciphertext simple_query(std::uint64_t index); void set_one_ct(seal::Ciphertext one); private: seal::EncryptionParameters enc_params_; // SEAL parameters PirParams pir_params_; // PIR parameters std::unique_ptr db_; bool is_db_preprocessed_; std::map galoisKeys_; std::unique_ptr evaluator_; std::unique_ptr encoder_; std::shared_ptr context_; // This is only used for simple_query seal::Ciphertext one_; void multiply_power_of_X(const seal::Ciphertext &encrypted, seal::Ciphertext &destination, std::uint32_t index); };