15 #include "seal/seal.h" 
   22     std::vector<seal::Plaintext> encodeVector(
const std::vector<std::vector<std::int64_t>> &vec);
 
   23     std::vector<seal::Ciphertext> encryptVector(
const std::vector<seal::Plaintext> &encoded_vec);
 
   24     std::vector<seal::Ciphertext> eltwiseadd(
const std::vector<seal::Plaintext> &A,
 
   25                                              const std::vector<seal::Ciphertext> &B);
 
   26     std::vector<seal::Plaintext> decryptResult(
const std::vector<seal::Ciphertext> &encrypted_result);
 
   27     std::vector<std::vector<int64_t>> decodeResult(
const std::vector<seal::Plaintext> &encoded_result);
 
   33         SealBFVContext(
int poly_modulus_degree)
 
   35             seal::EncryptionParameters parms{ seal::scheme_type::bfv };
 
   36             parms.set_poly_modulus_degree(poly_modulus_degree);
 
   37             parms.set_coeff_modulus(seal::CoeffModulus::Create(poly_modulus_degree, { 60, 60 }));
 
   38             parms.set_plain_modulus(seal::PlainModulus::Batching(poly_modulus_degree, 20));
 
   39             m_p_seal_context.reset(
 
   40                 new seal::SEALContext(parms, 
true, seal::sec_level_type::tc128));
 
   41             m_p_keygen = std::make_unique<seal::KeyGenerator>(context());
 
   43             m_p_keygen->create_public_key(m_public_key);
 
   44             m_secret_key = m_p_keygen->secret_key();
 
   46             m_p_encryptor     = std::make_unique<seal::Encryptor>(context(), m_public_key);
 
   47             m_p_evaluator     = std::make_unique<seal::Evaluator>(context());
 
   48             m_p_decryptor     = std::make_unique<seal::Decryptor>(context(), m_secret_key);
 
   49             m_p_batch_encoder = std::make_unique<seal::BatchEncoder>(context());
 
   52         seal::BatchEncoder &encoder() { 
return *m_p_batch_encoder; }
 
   53         seal::Evaluator &evaluator() { 
return *m_p_evaluator; }
 
   54         seal::Decryptor &decryptor() { 
return *m_p_decryptor; }
 
   55         const seal::Encryptor &encryptor()
 const { 
return *m_p_encryptor; }
 
   56         const seal::PublicKey &public_key()
 const { 
return m_public_key; }
 
   57         const seal::SecretKey &secret_key()
 const { 
return m_secret_key; }
 
   58         seal::SEALContext &context() { 
return *m_p_seal_context; }
 
   61         std::shared_ptr<seal::SEALContext> m_p_seal_context;
 
   62         std::unique_ptr<seal::KeyGenerator> m_p_keygen;
 
   63         seal::PublicKey m_public_key;
 
   64         seal::SecretKey m_secret_key;
 
   65         std::unique_ptr<seal::Encryptor> m_p_encryptor;
 
   66         std::unique_ptr<seal::Evaluator> m_p_evaluator;
 
   67         std::unique_ptr<seal::Decryptor> m_p_decryptor;
 
   68         std::unique_ptr<seal::BatchEncoder> m_p_batch_encoder;
 
   71     std::size_t m_vector_size;
 
   72     std::shared_ptr<SealBFVContext> m_p_context;
 
   74     SealBFVContext &context() { 
return *m_p_context; }
 
   80         throw std::invalid_argument(
"vector_size");
 
   81     m_vector_size = vector_size;
 
   82     m_p_context   = std::make_shared<SealBFVContext>(8192);
 
   85 std::vector<seal::Plaintext> Workload::encodeVector(
const std::vector<std::vector<std::int64_t>> &vec)
 
   87     std::vector<seal::Plaintext> retval(vec.size());
 
   89     for (std::size_t i = 0; i < vec.size(); ++i)
 
   91         assert(vec[i].size() <= context().encoder().slot_count());
 
   92         context().encoder().encode(vec[i], retval[i]);
 
   97 std::vector<seal::Ciphertext> Workload::encryptVector(
const std::vector<seal::Plaintext> &encoded_vec)
 
   99     std::vector<seal::Ciphertext> retval(encoded_vec.size());
 
  100     for (std::size_t i = 0; i < encoded_vec.size(); i++)
 
  101         context().encryptor().encrypt(encoded_vec[i], retval[i]);
 
  105 std::vector<seal::Ciphertext> Workload::eltwiseadd(
const std::vector<seal::Plaintext> &A,
 
  106                                                    const std::vector<seal::Ciphertext> &B)
 
  108     std::vector<seal::Ciphertext> retval(A.size() * B.size());
 
  115     for (std::size_t A_i = 0; A_i < A.size(); ++A_i)
 
  116         for (std::size_t B_i = 0; B_i < B.size(); ++B_i)
 
  118             seal::Ciphertext &retval_item = retval[A_i * B.size() + B_i];
 
  119             context().evaluator().add_plain(B[B_i], A[A_i], retval_item);
 
  125 std::vector<seal::Plaintext> Workload::decryptResult(
const std::vector<seal::Ciphertext> &encrypted_result)
 
  127     std::vector<seal::Plaintext> retval(encrypted_result.size());
 
  128     for (std::size_t i = 0; i < encrypted_result.size(); i++)
 
  129         context().decryptor().decrypt(encrypted_result[i], retval[i]);
 
  133 std::vector<std::vector<int64_t>> Workload::decodeResult(
const std::vector<seal::Plaintext> &encoded_result)
 
  135     std::vector<std::vector<int64_t>> retval(encoded_result.size());
 
  136     for (std::size_t i = 0; i < encoded_result.size(); ++i)
 
  138         context().encoder().decode(encoded_result[i], retval[i]);
 
  139         retval[i].resize(m_vector_size);
 
  149     static const std::size_t VectorSize = 400;
 
  150     static const std::size_t DimensionA = 2;
 
  151     static const std::size_t DimensionB = 5;
 
  154     std::vector<std::vector<std::int64_t>> A(DimensionA, std::vector<std::int64_t>(VectorSize));
 
  155     std::vector<std::vector<std::int64_t>> B(DimensionB, std::vector<std::int64_t>(VectorSize));
 
  158     std::random_device rd;
 
  159     std::mt19937 gen(rd());
 
  160     std::uniform_int_distribution<> distrib(-100, 100);
 
  162     for (std::size_t i = 0; i < A.size(); ++i)
 
  163         for (std::size_t j = 0; j < A[i].size(); ++j)
 
  164             A[i][j] = distrib(gen);
 
  165     for (std::size_t i = 0; i < B.size(); ++i)
 
  166         for (std::size_t j = 0; j < B[i].size(); ++j)
 
  167             B[i][j] = distrib(gen);
 
  173     std::shared_ptr<Workload> p_workload = 
 
  174         std::make_shared<Workload>(VectorSize);
 
  178     std::vector<std::vector<std::int64_t>> result =
 
  179         workload.decodeResult(
 
  180             workload.decryptResult(
 
  181                 workload.eltwiseadd(workload.encodeVector(A),
 
  182                                     workload.encryptVector(workload.encodeVector(B)))));
 
  190     std::vector<std::vector<std::int64_t>> exp_out(DimensionA * DimensionB, std::vector<std::int64_t>(VectorSize));
 
  191     assert(exp_out.size() == result.size());
 
  194     std::size_t result_i = 0;
 
  195     for (std::size_t A_i = 0; A_i < A.size(); ++A_i)
 
  196         for (std::size_t B_i = 0; B_i < B.size(); ++B_i)
 
  198             for (std::size_t i = 0; i < VectorSize; ++i)
 
  199                 exp_out[result_i][i] = A[A_i][i] + B[B_i][i];
 
  203     if (result == exp_out)
 
  204         std::cout << 
"OK" << std::endl;
 
  206         std::cout << 
"Fail" << std::endl;
 
Workload
Defines all possible workloads.
int main(int argc, char **argv)