Commit d8df7d47 authored by Hoang Gia NGUYEN's avatar Hoang Gia NGUYEN
Browse files

testing

parent c6c9d2f5

Too many changes to show.

To preserve performance only 269 of 269+ files are displayed.
#include <iomanip>
#include "seal_api.h"
#include "util.h"
using namespace seal;
using namespace std;
string ciphertext_name;
string key_dir;
// bool decrypt(size_t poly_d, size_t p_modulus, int &sample_size, string &ciphertext_dir);
bool decrypt(int &sample_size, string &ciphertext_dir);
void binarySimilarityCalculateDecrypt(int &sample_size, string &ciphertext_dir);
void binarySimilarityCalculateDecrypt1st(int &sample_size, string &ciphertext_dir);
int main(int argc, char **argv)
{
if (argc != 4)
{
// cout << "[ERROR] please enter /full/path/to/file/to/decrypt full/path/key " << endl;
// cout << "[ERROR] please enter prefix_file_to_decrypt full/path/key /full/path/to/storage" << endl;
// cout << "[ERROR] please enter a ciphertext file path, sample size and secret key path" << endl;
return -1;
}
else
{
string dir = argv[1];
int sample_size = atol(argv[2]);
key_dir = argv[3];
binarySimilarityCalculateDecrypt(sample_size, dir);
// binarySimilarityCalculateDecrypt1st(sample_size, dir);
// bool result_str = decrypt(sample_size, dir);
// cout << result_str << endl;
return 0;
}
}
bool decrypt(int &sample_size, string &ciphertext_dir)
{
struct decryptor_t decr;
init_operator_batching(decr, key_dir);
bool isContain = false;
if (sample_size <= decr.bcode->slot_count() / 2)
{
Ciphertext cipher_matrix;
vector<int64_t> pod_matrix;
load_ciphertext(decr, cipher_matrix, ciphertext_dir);
pod_matrix = decrypt_ciphermatrix(decr, cipher_matrix);
// cout << pod_matrix.size() << endl;
int no_dual_vectors = (decr.bcode->slot_count() / 2) / (sample_size);
for (size_t i = 0; i < decr.bcode->slot_count(); i++)
{
cout << (pod_matrix[i]);
}
vector<int64_t> v1, v2;
for (size_t i = 0; i < no_dual_vectors * sample_size; i++)
{
v1.push_back(pod_matrix[i]);
v2.push_back(pod_matrix[(pod_matrix.size() / 2) + i]);
}
int64_t sum = 0;
if (isContain == false)
{
cout << "1 : ";
for (size_t i = 0; i < v1.size(); i++)
{
cout << v1[i];
if ((i + 1) % sample_size == 0)
{
cout << endl;
if (i < v1.size() - 1)
{
cout << ((i + 1) / 40) + 1 << " : ";
}
}
else
{
cout << ", ";
}
if (v1[i] == 0)
{
sum = sum + 1;
}
else
{
sum = 0;
}
if (sum == sample_size)
{
isContain = true;
}
}
}
cout << endl;
if (isContain == false)
{
sum = 0;
cout << (v2.size() + 1) / 40 + 1 << " : ";
for (size_t i = 0; i < v2.size(); i++)
{
cout << v2[i];
if ((i + 1) % sample_size == 0)
{
cout << endl;
if (i < v2.size() - 1)
{
cout << ((v2.size() + i + 1) / 40) + 1 << " : ";
}
}
else
{
cout << ", ";
}
if (v2[i] == 0)
{
sum = sum + 1;
}
else
{
sum = 0;
}
if (sum == sample_size)
{
isContain = true;
}
}
}
cout << sample_size;
}
else
{
cout << endl << "Sample size is too large" << endl;
}
delete_operator_batching(decr);
return isContain;
}
void binarySimilarityCalculateDecrypt(int &sample_size, string &ciphertext_dir)
{
struct decryptor_t decr;
init_operator_batching(decr, key_dir);
if (sample_size <= decr.bcode->slot_count() / 2)
{
Ciphertext cipher_matrix;
vector<int64_t> pod_matrix;
load_ciphertext(decr, cipher_matrix, ciphertext_dir);
pod_matrix = decrypt_ciphermatrix(decr, cipher_matrix);
// cout << pod_matrix.size() << endl;
int no_dual_vectors = (decr.bcode->slot_count() / 2) / (sample_size);
vector<int64_t> v1, v2;
for (size_t i = 0; i < no_dual_vectors * sample_size; i++)
{
v1.push_back(pod_matrix[i]);
v2.push_back(pod_matrix[(pod_matrix.size() / 2) + i]);
}
float sum = 0;
for (size_t i = 0; i < v1.size(); i++)
{
if (v1[i] == 0)
{
sum = sum + 1;
}
if ((i + 1) % sample_size == 0)
{
// cout << ((i + 1) / 40) << " : ";
cout << ((sum / sample_size) * 100);
sum = 0;
cout << endl;
}
}
float sum2 = 0;
for (size_t i = 0; i < v2.size(); i++)
{
if (v2[i] == 0)
{
sum2 = sum2 + 1;
}
if ((i + 1) % sample_size == 0)
{
// cout << ((v2.size() + i + 1) / 40) << " : ";
cout << ((sum2 / sample_size) * 100);
sum2 = 0;
cout << endl;
}
}
}
else
{
cout << endl << "Sample size is too large" << endl;
}
delete_operator_batching(decr);
}
void binarySimilarityCalculateDecrypt1st(int &sample_size, string &ciphertext_dir)
{
struct decryptor_t decr;
init_operator_batching(decr, key_dir);
if (sample_size <= decr.bcode->slot_count() / 2)
{
Ciphertext cipher_matrix;
vector<int64_t> pod_matrix;
load_ciphertext(decr, cipher_matrix, ciphertext_dir);
pod_matrix = decrypt_ciphermatrix(decr, cipher_matrix);
vector<int64_t> v1;
for (size_t i = 0; i < sample_size; i++)
{
v1.push_back(pod_matrix[i]);
}
int unMatched = 0;
int other = 0;
float sum = 0;
for (size_t i = 0; i < v1.size(); i++)
{
if (v1[i] == 0)
{
sum = sum + 1;
} else if (v1[i] == 1 || v1[i] == -1)
{
unMatched = unMatched + 1;
} else {
other = other + 1;
}
if ((i + 1) % sample_size == 0)
{
// cout << ((i + 1) / 40) << " : ";
cout << (sum / (sample_size - other) * 100);
sum = 0;
cout << endl;
}
}
}
else
{
cout << endl << "Sample size is too large" << endl;
}
delete_operator_batching(decr);
// return isContain;
}
\ No newline at end of file
#include "seal_api.h"
using namespace seal;
using namespace std;
int main(int argc, char **argv)
{
if (argc != 6)
{
// cout << "[ERROR] please enter 1 plaintext values, prefix pathstorage(exists) " << endl;
cout << "[ERROR] please enter plaintext vector value (eg. 75 67 8 23 076 2 23), output ciphertext file name or "
"prefix, ciphertext output file directory, sample size and public key path"
<< endl;
// cout << "patternSearchN_encrypt \"1 2 3 ... 99\" filename directory/subdirectory/ 40 keys/" << endl;
return -1;
}
else
{
string plaintext = argv[1];
string ciphertext_name = argv[2];
string ciphertext_dir = argv[3];
int sample_size = atol(argv[4]);
string key_dir = argv[5];
struct encryptor_t encr;
init_operator_batching(encr, key_dir);
stringstream ss;
ss << plaintext;
vector<int64_t> pod_matrix;
int64_t x = 0;
while (ss >> x)
{
pod_matrix.push_back(x);
}
if (pod_matrix.size() <= encr.bcode->slot_count() / 2 && pod_matrix.size() <= sample_size)
{
Ciphertext encrypted_matrix;
init_ciphermatrix(encr, pod_matrix, encrypted_matrix);
save_ciphertext(encrypted_matrix, ciphertext_dir + "/" + ciphertext_name + ".ct");
delete_operator_batching(encr);
return 0;
}
else
{
delete_operator_batching(encr);
return -1;
}
// delete_operator_batching(encr);
// return 0;
}
}
// #include <algorithm>
// #include <iterator>
// #include <vector>
// #include <filesystem>
#include <iostream>
#include "seal_api.h"
#include "util.h"
using namespace seal;
using namespace std;
void sub_ciphertext(struct evaluator_t &op_st, Ciphertext &ct1, Ciphertext &ct2, Ciphertext &ct_out);
void add_ciphertext(struct evaluator_t &op_st, Ciphertext &ct1, Ciphertext &ct2, Ciphertext &ct_out);
void multiply_ciphertext(struct evaluator_t &op_st, Ciphertext &ct1, Ciphertext &ct2, Ciphertext &ct_out);
bool is_number(const string &s);
void printStrVector(const vector<string> &v);
void multiply_ciphertexts(struct evaluator_t &op_st, vector<Ciphertext> &cts, Ciphertext &ct_out);
void relinearize_inplace(struct evaluator_t &op_st, Ciphertext &ct);
void rescale_to_next_inplace(struct evaluator_t &op_st, Ciphertext &ct);
void multiply_inplace_ciphertext(struct evaluator_t &op_st, Ciphertext &ct1, Ciphertext &ct2);
void relinearize(struct evaluator_t &op_st, Ciphertext &ct, Ciphertext &ct_out);
void sub_inplace_ciphertext(struct evaluator_t &op_st, Ciphertext &ct1, Ciphertext &ct2);
void negate_inplace__ciphertext(struct evaluator_t &op_st, Ciphertext &ct);
void add_plain_inplace_ciphertext(struct evaluator_t &op_st, struct Ciphertext &ct, const Plaintext &plain);
void multiply_plain_inplace(struct evaluator_t &op_st, Ciphertext &ct, const Plaintext &plain);
void add_many_ciphertext(struct evaluator_t &op_st, vector<Ciphertext> &cts, Ciphertext &ct_out);
void exponentiate_inplace_ciphertext(struct evaluator_t &op_st, Ciphertext &ct, uint64_t &exponent);
void sub_plain_inplace_ciphertext(struct evaluator_t &op_st, Ciphertext &ct, const Plaintext &plain);
void mod_switch_to_next_inplace_ciphertext(struct evaluator_t &op_st, Ciphertext &ct);
int computeSimilarity(
string &source, vector<string> &data, string &result_name, string &result_dir, int &sample_size, string &key_dir);
int checkSq(
string &source, vector<string> &data, string &result_name, string &result_dir, int &sample_size, string &key_dir);
// string relink_key_path;
// string galois_key_path;
// string public_key_path;
string key_dir = "";
vector<vector<string>> split_ends(const vector<string> &data, const vector<int> &ends);
Ciphertext check(
string &source, vector<string> &data, string &result_name, string &result_dir, int &sample_size, string &key_dir,
struct encryptor_t &encr, struct evaluator_t &eval);
int main(int argc, char **argv)
{
// input processing - begin
// string result_name = argv[argc - 6];
// string result_dir = argv[argc - 5];
// int sample_size = atoi(argv[argc - 4]);
// relink_key_path = argv[argc - 3];
// galois_key_path = argv[argc - 2];
// public_key_path = argv[argc - 1];
string source = argv[1];
string result_name = argv[argc - 4];
string result_dir = argv[argc - 3];
int sample_size = atoi(argv[argc - 2]);
key_dir = argv[argc - 1];
vector<string> data;
for (int i = 2; i < argc - 4; i++)
{
data.push_back(argv[i]);
}
// if (source == "" || data.size() == 0 || result_name == "" || result_dir == "" || sample_size == 0 ||
// relink_key_path == "" || galois_key_path == "" || public_key_path == "")
if (source == "" || data.size() == 0 || result_name == "" || result_dir == "" || sample_size == 0 || key_dir == "")
{
// error handling
cout << "[ERROR] please enter a source path, data paths, output ciphertext file name or prefix, output "
"ciphertext directory, sample size, linking key path, galois key path and public key path"
<< endl;
return -1;
}
// input processing - end
int result = computeSimilarity(source, data, result_name, result_dir, sample_size, key_dir);
// int result = checkSq(source, data, result_name, result_dir, sample_size, key_dir);
// checkSq(source, data, result_name, result_dir, sample_size, relink_key_path, galois_key_path, public_key_path);
// error handling
if (result == -1)
{
fprintf(stderr, "error!\n");
}
else
{
cout << "done";
}
return result;
}
int computeSimilarity(
string &source, vector<string> &data, string &result_name, string &result_dir, int &sample_size, string &key_dir)
{
// cout << "\n[INFO] Start Similarity Search Algorithm!" << endl;
// cout << "\n[INFO] Start Initializing Evaluator!" << endl;
struct evaluator_t eval;
init_operator_batching(eval, key_dir);
// cout << "[INFO] End Initializing Evaluator!" << endl;
// cout << "\n[INFO] Start Initializing Encryptor!" << endl;
struct encryptor_t encr;
init_operator_batching(encr, key_dir);
// cout << "[INFO] End Initializing Encryptor!" << endl;
// cout << "\n[INFO] Input Parameters:" << endl;
// cout << " Sample Size: " << sample_size << endl;
// cout << " Required Slots (Sample Size x Data Size): " << sample_size * data.size() << endl;
// cout << " Provided Slots: " << encr.bcode->slot_count() << endl;
if (sample_size * data.size() > encr.bcode->slot_count() || sample_size > encr.bcode->slot_count() / 2)
{
// Error handling
delete_operator_batching(encr);
delete_operator_batching(eval);
return -1;
}
else
{
Ciphertext encrypted_result_matrix;
vector<int64_t> result_matrix;
init_ciphermatrix(encr, result_matrix, encrypted_result_matrix);
vector<int64_t> dummy_matrix;
for (size_t i = 0; i < sample_size; i++)
{
dummy_matrix.push_back(1);
}
Ciphertext encrypted_dummy_matrix;
init_ciphermatrix(encr, dummy_matrix, encrypted_dummy_matrix);
// Normalizing data input if the number ciphertext is odd
int normalized_data_size;
if (data.size() % 2 == 0)
{
normalized_data_size = data.size();
}
else
{
normalized_data_size = data.size() + 1;
}
// cout << "[INFO] normalized_data_size: " << normalized_data_size << endl;
int normalized_required_slots = normalized_data_size * sample_size;
int half_normalized_required_slots = normalized_required_slots / 2;
// int required_range_row = normalized_required_slots / 2;
// Create padding matrix
int padding_slots = (encr.bcode->slot_count() / 2) - half_normalized_required_slots;
// cout << "[INFO] padding_slots: " << padding_slots << endl;
vector<int64_t> padding_matrix(encr.bcode->slot_count(), 0ULL);
for (size_t i = 0; i < padding_slots; i++)
{
padding_matrix[half_normalized_required_slots + i] = 1;
padding_matrix[encr.bcode->slot_count() - 1 - i] = 1;
}
Ciphertext encrypted_padding_matrix;
init_ciphermatrix(encr, padding_matrix, encrypted_padding_matrix);
if (half_normalized_required_slots > 0 && half_normalized_required_slots <= encr.bcode->slot_count())
{
for (int index = 0; index < normalized_data_size / 2; index++)
{
Ciphertext ct1, ct2, ct3;
Ciphertext temp1, temp2;
// cout << "[INFO] loading ciphertext 1" << endl;
load_ciphertext(eval, ct1, source);
// cout << "[INFO] loading ciphertext 2" << endl;
load_ciphertext(eval, ct2, data.at(index));
sub_ciphertext(eval, ct1, ct2, temp1);
if ((normalized_data_size / 2) + index < data.size())
{
// cout << "[INFO] loading ciphertext 3" << endl;
load_ciphertext(eval, ct3, data.at((normalized_data_size / 2) + index));
sub_ciphertext(eval, ct1, ct3, temp2);
}
else
{
// Add dummy vector for oddy data
temp2 = encrypted_dummy_matrix;
}
// Switching column
eval.eval->rotate_columns_inplace(temp2, eval.gk);
add_ciphertext(eval, temp1, temp2, temp1);
add_ciphertext(eval, temp1, encrypted_result_matrix, encrypted_result_matrix);
// Shifting slots
// cout << "[INFO] index: " << index << endl;
// eval.eval->rotate_rows_inplace(encrypted_result_matrix, +sample_size, eval.gk);
// avoid the last shift
if (index + 1 != (normalized_data_size / 2))
{
eval.eval->rotate_rows_inplace(encrypted_result_matrix, -sample_size, eval.gk);
}
}
add_ciphertext(eval, encrypted_result_matrix, encrypted_padding_matrix, encrypted_result_matrix);
// Shifting the remaining slots
// eval.eval->rotate_rows_inplace(encrypted_result_matrix, +((encr.bcode->slot_count() - sample_size *
// data.size()) / 2), eval.gk); eval.eval->rotate_rows_inplace(encrypted_result_matrix,
// +((encr.bcode->slot_count()%sample_size))/2, eval.gk);
}
save_ciphertext(encrypted_result_matrix, result_dir + "/" + result_name + ".ct");
delete_operator_batching(encr);
delete_operator_batching(eval);
// cout << "\n[INFO] End Similarity Search Algorithm!" << endl;
return 0;
}
}
// This is advance algorithm - Testing
// int checkSq(
// string &source, vector<string> &data, string &result_name, string &result_dir, int &sample_size,
// string &relink_key_path, string &galois_key_path, string &public_key_path)
int checkSq(
string &source, vector<string> &data, string &result_name, string &result_dir, int &sample_size, string &key_dir)
{
struct evaluator_t eval;
// init_operator_batching(2048, 4294967296, eval, relink_key_path, galois_key_path);
// init_operator_batching(4096, 4294967296, eval, relink_key_path, galois_key_path);
// init_operator_batching(8192, 4294967296, eval, relink_key_path, galois_key_path);
// init_operator_batching(16384, 4294967296, eval, relink_key_path, galois_key_path);
// init_operator_batching(32768, 4294967296, eval, relink_key_path, galois_key_path);
init_operator_batching(eval, key_dir);
struct encryptor_t encr;
// init_operator_batching(4096, 4294967296, encr, public_key_path);
// init_operator_batching(8192, 4294967296, encr, public_key_path);
// init_operator_batching(16384, 4294967296, encr, public_key_path);
// init_operator_batching(32768, 4294967296, encr, public_key_path);
init_operator_batching(encr, key_dir);
// if (sample_size*data.size() > encr.bcode->slot_count() || sample_size > encr.bcode->slot_count()/2)
if (sample_size > encr.bcode->slot_count() / 2)
{
// error handling
delete_operator_batching(encr);
delete_operator_batching(eval);
return -1;
}
else
{
// struct evaluator_t eval;
// // init_operator_batching(2048, 4294967296, eval, relink_key_path, galois_key_path);
// // init_operator_batching(4096, 4294967296, eval, relink_key_path, galois_key_path);
// init_operator_batching(8192, 4294967296, eval, relink_key_path, galois_key_path);
// // init_operator_batching(16384, 4294967296, eval, relink_key_path, galois_key_path);
// // init_operator_batching(32768, 4294967296, eval, relink_key_path, galois_key_path);
// struct encryptor_t encr;
// // init_operator_batching(4096, 4294967296, encr, public_key_path);
// init_operator_batching(8192, 4294967296, encr, public_key_path);
// // init_operator_batching(16384, 4294967296, encr, public_key_path);
// // init_operator_batching(32768, 4294967296, encr, public_key_path);
int capacity = (encr.bcode->slot_count()) / sample_size;
// cout << capacity << endl;
// vector<string> v_temp;
// vector<string> v_v_temp;
// Ciphertext result;
vector<Ciphertext> v_result;
int nSq = data.size() / capacity;
for (size_t i = 0; i < nSq; i++)
{
Ciphertext result;
// cout << "sq : " << i << endl;
vector<string> v_temp;
for (size_t j = 0; j < capacity; j++)
{
string str = data.back();
v_temp.push_back(str);
data.pop_back();
}
if (i == 0)
{
// cout << "sq : init" << endl;
// result = check(
// source, v_temp, result_name, result_dir, sample_size, relink_key_path, galois_key_path,
// public_key_path, encr, eval);
result = check(source, v_temp, result_name, result_dir, sample_size, key_dir, encr, eval);
v_result.push_back(result);
}
else
{
// cout << "sq : other" << endl;
// Ciphertext result2 = check(
// source, v_temp, result_name, result_dir, sample_size, relink_key_path, galois_key_path,
// public_key_path, encr, eval);
// multiply_ciphertext(eval, result2, result, result);
// relinearize_inplace(eval, result);
// result = check(
// source, v_temp, result_name, result_dir, sample_size, relink_key_path, galois_key_path,
// public_key_path, encr, eval);
result = check(source, v_temp, result_name, result_dir, sample_size, key_dir, encr, eval);
v_result.push_back(result);
}
}
if (data.size() % capacity != 0)
{
// cout << "oddy!!! " << endl;
// Ciphertext result = check(
// source, data, result_name, result_dir, sample_size, relink_key_path, galois_key_path,
// public_key_path, encr, eval);
Ciphertext result = check(source, data, result_name, result_dir, sample_size, key_dir, encr, eval);
// multiply_ciphertext(eval, result2, result, result);
// relinearize_inplace(eval, result);
v_result.push_back(result);
}
Ciphertext result;
multiply_ciphertexts(eval, v_result, result);
relinearize_inplace(eval, result);
save_ciphertext(result, result_dir + "/" + result_name + ".ct");
delete_operator_batching(encr);
delete_operator_batching(eval);
return 0;
}
}
// Ciphertext check(
// string &source, vector<string> &data, string &result_name, string &result_dir, int &sample_size,
// string &relink_key_path, string &galois_key_path, string &public_key_path, struct encryptor_t &encr,
// struct evaluator_t &eval)
Ciphertext check(
string &source, vector<string> &data, string &result_name, string &result_dir, int &sample_size, string &key_dir,
struct encryptor_t &encr, struct evaluator_t &eval)
{
// if (source == "" || data.size() == 0 || result_name == "" || result_dir == "" || sample_size == 0)
// {
// // error handling
// // return -1;
// }
// else
// {
Ciphertext encrypted_result_matrix;
vector<int64_t> result_matrix;
init_ciphermatrix(encr, result_matrix, encrypted_result_matrix);
vector<int64_t> dummy_matrix;
for (size_t i = 0; i < sample_size; i++)
{
dummy_matrix.push_back(1);
}
Ciphertext encrypted_dummy_matrix;
init_ciphermatrix(encr, dummy_matrix, encrypted_dummy_matrix);
// normalize input data if its size is odd
int normalized_data_size;
if (data.size() % 2 == 0)
{
normalized_data_size = data.size();
}
else
{
normalized_data_size = data.size() + 1;
}
int required_range = normalized_data_size * sample_size;
int required_no_row_elements = required_range / 2;
int required_range_row = required_range / 2;
// create padding matrix
int padding_slots = (encr.bcode->slot_count() / 2) - required_range_row;
vector<int64_t> padding_matrix(encr.bcode->slot_count(), 0ULL);
for (size_t i = 0; i < padding_slots; i++)
{
padding_matrix[required_no_row_elements + i] = 1;
padding_matrix[encr.bcode->slot_count() - i] = 1;
}
Ciphertext encrypted_padding_matrix;
init_ciphermatrix(encr, padding_matrix, encrypted_padding_matrix);
if (required_range_row <= encr.bcode->slot_count() && required_range_row > 0)
{
for (int index = 0; index < normalized_data_size / 2; index++)
{
Ciphertext ct1, ct2, ct3;
Ciphertext temp1, temp2;
// cout << "[INFO] loading ciphertext 1" << endl;
load_ciphertext(eval, ct1, source);
// cout << "[INFO] loading ciphertext 2" << endl;
load_ciphertext(eval, ct2, data.at(index));
sub_ciphertext(eval, ct1, ct2, temp1);
if ((normalized_data_size / 2) + index < data.size())
{
// cout << "[INFO] loading ciphertext 3" << endl;
load_ciphertext(eval, ct3, data.at((normalized_data_size / 2) + index));
sub_ciphertext(eval, ct1, ct3, temp2);
}
else
{
// add dummy vector for oddy data
temp2 = encrypted_dummy_matrix;
}
eval.eval->rotate_columns_inplace(temp2, eval.gk);
add_ciphertext(eval, temp1, temp2, temp1);
add_ciphertext(eval, temp1, encrypted_result_matrix, encrypted_result_matrix);
// avoid the last shift
if (index + 1 != (normalized_data_size / 2))
{
eval.eval->rotate_rows_inplace(encrypted_result_matrix, -sample_size, eval.gk);
}
}
// add renmaining padding slots
add_ciphertext(eval, encrypted_result_matrix, encrypted_padding_matrix, encrypted_result_matrix);
}
// // save_ciphertext(encrypted_result_matrix, result_dir + "/" + result_name + ".ct");
// delete_operator_batching(eval);
return encrypted_result_matrix;
// }
}
void sub_ciphertext(struct evaluator_t &op_st, Ciphertext &ct1, Ciphertext &ct2, Ciphertext &ct_out)
{
op_st.eval->sub(ct1, ct2, ct_out);
}
void sub_inplace_ciphertext(struct evaluator_t &op_st, Ciphertext &ct1, Ciphertext &ct2)
{
op_st.eval->sub_inplace(ct1, ct2);
}
void sub_plain_inplace_ciphertext(struct evaluator_t &op_st, Ciphertext &ct, const Plaintext &plain)
{
op_st.eval->sub_plain_inplace(ct, plain);
}
void negate_inplace_ciphertext(struct evaluator_t &op_st, Ciphertext &ct)
{
op_st.eval->negate_inplace(ct);
}
void add_plain_inplace_ciphertext(struct evaluator_t &op_st, struct Ciphertext &ct, const Plaintext &plain)
{
op_st.eval->add_plain_inplace(ct, plain);
}
void add_ciphertext(struct evaluator_t &op_st, Ciphertext &ct1, Ciphertext &ct2, Ciphertext &ct_out)
{
op_st.eval->add(ct1, ct2, ct_out);
}
void add_many_ciphertext(struct evaluator_t &op_st, vector<Ciphertext> &cts, Ciphertext &ct_out)
{
op_st.eval->add_many(cts, ct_out);
}
void multiply_ciphertext(struct evaluator_t &op_st, Ciphertext &ct1, Ciphertext &ct2, Ciphertext &ct_out)
{
op_st.eval->multiply(ct1, ct2, ct_out);
}
void multiply_inplace_ciphertext(struct evaluator_t &op_st, Ciphertext &ct1, Ciphertext &ct2)
{
op_st.eval->multiply_inplace(ct1, ct2);
}
void multiply_ciphertexts(struct evaluator_t &op_st, vector<Ciphertext> &cts, Ciphertext &ct_out)
{
op_st.eval->multiply_many(cts, op_st.lk, ct_out);
}
void multiply_plain_inplace(struct evaluator_t &op_st, Ciphertext &ct, const Plaintext &plain)
{
op_st.eval->multiply_plain_inplace(ct, plain);
}
void relinearize_inplace(struct evaluator_t &op_st, Ciphertext &ct)
{
op_st.eval->relinearize_inplace(ct, op_st.lk);
}
void relinearize(struct evaluator_t &op_st, Ciphertext &ct, Ciphertext &ct_out)
{
op_st.eval->relinearize(ct, op_st.lk, ct_out);
}
void rescale_to_next_inplace(struct evaluator_t &op_st, Ciphertext &ct)
{
op_st.eval->rescale_to_next_inplace(ct);
}
void exponentiate_inplace_ciphertext(struct evaluator_t &op_st, Ciphertext &ct, uint64_t &exponent)
{
op_st.eval->exponentiate_inplace(ct, exponent, op_st.lk);
}
void mod_switch_to_next_inplace_ciphertext(struct evaluator_t &op_st, Ciphertext &ct)
{
op_st.eval->mod_switch_to_next_inplace(ct);
}
#include "seal_api.h"
using namespace std;
using namespace seal;
int main(int argc, char **argv)
{
string key_dir = argv[1];
size_t poly_d = 4096;
// Params option 1
int bit_size = 20;
// Params option 2
// uint64_t plain_modulus = 1032193;
// vector<int> bit_sizes = { 36, 36, 37 };
// timeval t0, t1;
// unsigned long dt = 0;
// gettimeofday(&t0, NULL);
batching_generate_keys(poly_d, bit_size, key_dir, true);
// batching_generate_keys(poly_d, bit_sizes, plain_modulus, key_dir, true);
// gettimeofday(&t1, NULL);
// dt = 1000000 * (t1.tv_sec - t0.tv_sec) + (t1.tv_usec - t0.tv_usec);
// cout << "[INFO] keys generation time in seconds: " << ((float)dt)/1000000 << endl;
return 0;
}
# Testing Script
CURR_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
###################### Test 1 - Begin ######################
mkdir -p keys/
mkdir -p lcheck/
mkdir -p parent/
mkdir -p result/
# rm ls.txt
# Number of ciphertext data, eg: (0..99)
min=0
max=0 # max=101 or 1631
n_char=39 # Number of chars/words of a ciphertext, eg: 9
# Encrypted number range, eg: 2(1-bit), 10, 100, 255(8-bit), 1000
# range=255
range=2
sample=40 # sampling size
# Generate keys
${CURR_DIR}/similarityMatch_genkey keys/ # gen keys
# Get random data line
if [[ "$max" -ne 0 ]]
then
line=$((RANDOM %max))
else
line=0
fi
lcheck=""
# Generate data randomly
for i in $(seq $min $max)
do
mkdir -p parent/l"$i"/
echo "Created folder $i"
value=""
for j in $(seq 0 $n_char)
do
value+="$((RANDOM %$range)) "
done
echo $value
echo $value >> ls.txt
# ./similarityMatch_encrypt "$value" "l" parent/l"$i"/ $sample keys/
${CURR_DIR}/similarityMatch_encrypt "$value" "l" parent/l"$i"/ $sample keys/
if [[ "$line" -eq "$i" ]]
then
lcheck="$value"
fi
done
echo "Pick up data to check: $lcheck"
${CURR_DIR}/similarityMatch_encrypt "$lcheck" "l" lcheck/ $sample keys/
# Evaluate
value1="lcheck/l.ct "
value2=""
for i in $(seq 0 $max)
do
value2+="parent/l${i}/l.ct "
done
value3="$value1$value2"
echo "$value3"
time ${CURR_DIR}/similarityMatch_evaluate $value3 "l" result/ $sample keys/
echo ""
${CURR_DIR}/similarityMatch_decrypt_1st_result result/l.ct $sample keys/
# rm -r keys/*
# rm -r lcheck/*
# rm -r parent/*
# rm -r result/*
# rm ls.txt
###################### Test 1 - End ########################
###################### Report - Begin ######################
# sim: (eval: 0.465s, 0.488s, 0.480s decrypt: 0.028s, 0.080s, 0.077s)
# seq: (eval: 0.xxx, 0.xxx, 0.xxx decrypt: 0.xxx, 0.xxx, 0.xxx)
# max=203
# (eval: 3.635s, 3.510s, 3.628s decrypt: 0.062s, 0.153s. 0.134s)
# seq: (eval: 0.xxx, 0.xxx, 0.xxx decrypt: 0.xxx, 0.xxx, 0.xxx)
# max=407
# (eval: 38.607s, 39.600s, 39.565s decrypt: 0.264s, 0.260s, 0.245s)
# seq: (eval: 0.xxx, 0.xxx, 0.xxx decrypt: 0.xxx, 0.xxx, 0.xxx)
# max=815
# (eval: x decrypt: x )
###################### Report - End ########################
\ No newline at end of file
#include "util.h"
// #include <filesystem>
#include "seal_api.h"
// #include <boost/filesystem.hpp>
// namespace fs = boost::filesystem;
bool sub_str_exist(const std::string &str, const std::string &sub_str)
{
return str.size() >= sub_str.size() && str.compare(str.size() - sub_str.size(), sub_str.size(), sub_str) == 0;
}
// int findNumberOfFilesInDirectory(const std::string &path)
// {
// auto dirIter = std::filesystem::directory_iterator(path);
// int fileCount = std::count_if(
// begin(dirIter),
// end(dirIter),
// [](auto &entry) { return entry.is_regular_file(); });
// return fileCount;
// }
// int findNumberOfFilesInDirectory(std::string &path, std::string &ext)
// int findNumberOfFilesInDirectory(const std::string &path)
// {
// // namespace fs = boost::filesystem;
// std::string ext = ".ct";
// fs::path Path(path);
// int Nb_ext = 0;
// fs::directory_iterator end_iter; // Default constructor for an iterator is the end iterator
// for (fs::directory_iterator iter(Path); iter != end_iter; ++iter)
// if (iter->path().extension() == ext)
// ++Nb_ext;
// return Nb_ext;
// }
// c++ 17
// std::vector<std::string> get_directories(const std::string &s)
// {
// std::vector<std::string> r;
// for(auto& p : std::filesystem::recursive_directory_iterator(s))
// if (p.is_directory())
// r.push_back(p.path().string());
// return r;
// }
// struct path_leaf_string
// {
// std::string operator()(const boost::filesystem::directory_entry &entry) const
// {
// return entry.path().leaf().string();
// }
// };
// std::vector<std::string> get_directories(const std::string &s)
// {
// std::vector<std::string> v;
// boost::filesystem::path p(s);
// boost::filesystem::directory_iterator start(p);
// boost::filesystem::directory_iterator end;
// std::transform(start, end, std::back_inserter(v), path_leaf_string());
// std::copy(v.begin(), v.end(),
// std::ostream_iterator<std::string>(std::cout, "\n"));
// return v;
// }
#ifndef _UTIL_H_
#define _UTIL_H_
#include <string>
#include <vector>
// int findNumberOfFilesInDirectory(const std::string &path);
bool sub_str_exist(const std::string &str, const std::string &sub_str);
// std::vector<std::string> get_directories(const std::string &s);
// std::vector<std::string> get_directories_deep(const std::string &s);
#endif
@echo off
rem Copyright (c) Microsoft Corporation. All rights reserved.
rem Licensed under the MIT license.
setlocal
rem The purpose of this script is to have CMake generate config.h for use by Microsoft SEAL.
rem We assume that CMake was installed with Visual Studio, which should be the default
rem when the user installs the "Desktop Development with C++" workload.
set VSVERSION=%~1
set PROJECTCONFIGURATION=%~2
set PROJECTPLATFORM=%~3
set VSDEVENVDIR=%~4
set INCLUDEPATH=%~5
set LIBRARYPATH=%~6
echo Configuring Microsoft SEAL through CMake
if not exist "%VSDEVENVDIR%" (
rem We may be running in the CI server. Try a standard VS path.
echo Did not find VS at provided location: "%VSDEVENVDIR%".
echo Trying standard location.
set VSDEVENVDIR="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE"
)
set VSDEVENVDIR=%VSDEVENVDIR:"=%
set CMAKEPATH=%VSDEVENVDIR%\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe
if not exist "%CMAKEPATH%" (
echo ******************************************************************************************************************
echo ** Did not find CMake at "%CMAKEPATH%"
echo ** Please make sure "Visual C++ Tools for CMake" are enabled in the "Desktop development with C++" workload.
echo ******************************************************************************************************************
exit 1
)
echo Found CMake at %CMAKEPATH%
rem Identify Visual Studio version and set CMake generator accordingly.
set CMAKEGEN=""
if "%VSVERSION%"=="15.0" (
set CMAKEGEN="Visual Studio 15 2017"
) else if "%VSVERSION%"=="16.0" (
set CMAKEGEN="Visual Studio 16 2019"
) else (
echo ***************************************************
echo ** Unsupported Visual Studio version "%VSVERSION%"
echo ***************************************************
exit 1
)
rem Download Microsoft GSL
set MSGSLCONFIGDIR="..\..\thirdparty\msgsl\.config\%VSVERSION%\%PROJECTPLATFORM%"
cd %~dp0
if not exist %MSGSLCONFIGDIR% (
mkdir %MSGSLCONFIGDIR%
)
cd %MSGSLCONFIGDIR%
"%CMAKEPATH%" ..\..\.. -G %CMAKEGEN% -A %PROJECTPLATFORM%
"%CMAKEPATH%" --build . --config "%PROJECTCONFIGURATION%"
rem Copy Microsoft GSL header files into the local source directory
robocopy ..\..\..\src\include %~dp0 /s
rem Download and build ZLIB
set ZLIBCONFIGDIR="..\..\thirdparty\zlib\.config\%VSVERSION%\%PROJECTPLATFORM%"
cd %~dp0
if not exist %ZLIBCONFIGDIR% (
mkdir %ZLIBCONFIGDIR%
)
cd %ZLIBCONFIGDIR%
"%CMAKEPATH%" ..\..\.. -G %CMAKEGEN% -A %PROJECTPLATFORM% ^
-DZLIB_PLATFORM="%PROJECTPLATFORM%"
"%CMAKEPATH%" --build . --config "%PROJECTCONFIGURATION%"
rem Configure Microsoft SEAL
set CONFIGDIR="..\..\.config\%VSVERSION%\%PROJECTPLATFORM%"
cd %~dp0
if not exist %CONFIGDIR% (
mkdir %CONFIGDIR%
)
cd %CONFIGDIR%
echo Running CMake configuration in %cd%
"%CMAKEPATH%" ..\..\.. -G %CMAKEGEN% -A %PROJECTPLATFORM% ^
-DALLOW_COMMAND_LINE_BUILD=1 ^
-DCMAKE_BUILD_TYPE="%PROJECTCONFIGURATION%" ^
-DBUILD_SHARED_LIBS=OFF ^
-DSEAL_USE_MSGSL=ON ^
-DSEAL_USE_ZLIB=ON ^
-DSEAL_BUILD_TESTS=OFF ^
-DSEAL_BUILD_EXAMPLES=OFF ^
-DSEAL_BUILD_SEAL_C=OFF ^
--no-warn-unused-cli
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="seal\batchencoder.h" />
<ClInclude Include="seal\biguint.h" />
<ClInclude Include="seal\ciphertext.h" />
<ClInclude Include="seal\ckks.h" />
<ClInclude Include="seal\modulus.h" />
<ClInclude Include="seal\context.h" />
<ClInclude Include="seal\decryptor.h" />
<ClInclude Include="seal\encryptionparams.h" />
<ClInclude Include="seal\encryptor.h" />
<ClInclude Include="seal\evaluator.h" />
<ClInclude Include="seal\galoiskeys.h" />
<ClInclude Include="seal\intarray.h" />
<ClInclude Include="seal\intencoder.h" />
<ClInclude Include="seal\keygenerator.h" />
<ClInclude Include="seal\kswitchkeys.h" />
<ClInclude Include="seal\memorymanager.h" />
<ClInclude Include="seal\plaintext.h" />
<ClInclude Include="seal\publickey.h" />
<ClInclude Include="seal\randomgen.h" />
<ClInclude Include="seal\randomtostd.h" />
<ClInclude Include="seal\relinkeys.h" />
<ClInclude Include="seal\seal.h" />
<ClInclude Include="seal\secretkey.h" />
<ClInclude Include="seal\serializable.h" />
<ClInclude Include="seal\serialization.h" />
<ClInclude Include="seal\util\blake2.h" />
<ClInclude Include="seal\util\blake2-impl.h" />
<ClInclude Include="seal\util\clang.h" />
<ClInclude Include="seal\util\clipnormal.h" />
<ClInclude Include="seal\util\common.h" />
<ClInclude Include="seal\util\croots.h" />
<ClInclude Include="seal\util\defines.h" />
<ClInclude Include="seal\util\galois.h" />
<ClInclude Include="seal\util\gcc.h" />
<ClInclude Include="seal\util\globals.h" />
<ClInclude Include="seal\util\hash.h" />
<ClInclude Include="seal\util\hestdparms.h" />
<ClInclude Include="seal\util\iterator.h" />
<ClInclude Include="seal\util\locks.h" />
<ClInclude Include="seal\util\mempool.h" />
<ClInclude Include="seal\util\msvc.h" />
<ClInclude Include="seal\util\numth.h" />
<ClInclude Include="seal\util\pointer.h" />
<ClInclude Include="seal\util\polyarith.h" />
<ClInclude Include="seal\util\polyarithmod.h" />
<ClInclude Include="seal\util\polyarithsmallmod.h" />
<ClInclude Include="seal\util\polycore.h" />
<ClInclude Include="seal\util\rlwe.h" />
<ClInclude Include="seal\util\rns.h" />
<ClInclude Include="seal\util\scalingvariant.h" />
<ClInclude Include="seal\util\ntt.h" />
<ClInclude Include="seal\util\streambuf.h" />
<ClInclude Include="seal\util\uintarith.h" />
<ClInclude Include="seal\util\uintarithmod.h" />
<ClInclude Include="seal\util\uintarithsmallmod.h" />
<ClInclude Include="seal\util\uintcore.h" />
<ClInclude Include="seal\util\ztools.h" />
<ClInclude Include="seal\valcheck.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="seal\batchencoder.cpp" />
<ClCompile Include="seal\biguint.cpp" />
<ClCompile Include="seal\ciphertext.cpp" />
<ClCompile Include="seal\ckks.cpp" />
<ClCompile Include="seal\modulus.cpp" />
<ClCompile Include="seal\context.cpp" />
<ClCompile Include="seal\decryptor.cpp" />
<ClCompile Include="seal\encryptionparams.cpp" />
<ClCompile Include="seal\encryptor.cpp" />
<ClCompile Include="seal\evaluator.cpp" />
<ClCompile Include="seal\intencoder.cpp" />
<ClCompile Include="seal\keygenerator.cpp" />
<ClCompile Include="seal\kswitchkeys.cpp" />
<ClCompile Include="seal\memorymanager.cpp" />
<ClCompile Include="seal\plaintext.cpp" />
<ClCompile Include="seal\randomgen.cpp" />
<ClCompile Include="seal\serialization.cpp" />
<ClCompile Include="seal\util\rns.cpp" />
<ClCompile Include="seal\util\ztools.cpp" />
<ClCompile Include="seal\valcheck.cpp" />
<ClCompile Include="seal\util\blake2b.c" />
<ClCompile Include="seal\util\blake2xb.c" />
<ClCompile Include="seal\util\clipnormal.cpp" />
<ClCompile Include="seal\util\croots.cpp" />
<ClCompile Include="seal\util\galois.cpp" />
<ClCompile Include="seal\util\globals.cpp" />
<ClCompile Include="seal\util\hash.cpp" />
<ClCompile Include="seal\util\mempool.cpp" />
<ClCompile Include="seal\util\numth.cpp" />
<ClCompile Include="seal\util\polyarith.cpp" />
<ClCompile Include="seal\util\polyarithmod.cpp" />
<ClCompile Include="seal\util\polyarithsmallmod.cpp" />
<ClCompile Include="seal\util\rlwe.cpp" />
<ClCompile Include="seal\util\scalingvariant.cpp" />
<ClCompile Include="seal\util\ntt.cpp" />
<ClCompile Include="seal\util\streambuf.cpp" />
<ClCompile Include="seal\util\uintarith.cpp" />
<ClCompile Include="seal\util\uintarithmod.cpp" />
<ClCompile Include="seal\util\uintarithsmallmod.cpp" />
<ClCompile Include="seal\util\uintcore.cpp" />
</ItemGroup>
<ItemGroup>
<Text Include="seal\CMakeLists.txt" />
<Text Include="seal\util\CMakeLists.txt" />
</ItemGroup>
<ItemGroup>
<None Include="cmake\FindMSGSL.cmake" />
<None Include="cmake\SEALConfig.cmake.in" />
<None Include="seal\util\config.h.in" />
<None Include="CMakeConfig.cmd" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7EA96C25-FC0D-485A-BB71-32B6DA55652A}</ProjectGuid>
<RootNamespace>SEAL</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>false</CLRSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>false</CLRSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>false</CLRSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>false</CLRSupport>
</PropertyGroup>
<PropertyGroup>
<ZlibName Condition="'$(ZLIB_ROOT)'!=''">zlibstatic.lib</ZlibName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(ProjectDir)..\..\lib\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)obj\$(Platform)\$(Configuration)\seal\</IntDir>
<TargetExt>.lib</TargetExt>
<TargetName>seal</TargetName>
<ExtensionsToDeleteOnClean>
</ExtensionsToDeleteOnClean>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(ProjectDir)..\..\lib\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)obj\$(Platform)\$(Configuration)\seal\</IntDir>
<TargetExt>.lib</TargetExt>
<TargetName>seal</TargetName>
<ExtensionsToDeleteOnClean>
</ExtensionsToDeleteOnClean>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(ProjectDir)..\..\lib\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)obj\$(Platform)\$(Configuration)\seal\</IntDir>
<TargetExt>.lib</TargetExt>
<TargetName>seal</TargetName>
<ExtensionsToDeleteOnClean>
</ExtensionsToDeleteOnClean>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(ProjectDir)..\..\lib\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)obj\$(Platform)\$(Configuration)\seal\</IntDir>
<TargetExt>.lib</TargetExt>
<TargetName>seal</TargetName>
<ExtensionsToDeleteOnClean>
</ExtensionsToDeleteOnClean>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)\thirdparty\zlib\build\$(Platform);$(SolutionDir)/thirdparty/zlib/src;$(ProjectDir)</AdditionalIncludeDirectories>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
<LanguageStandard>stdcpp17</LanguageStandard>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_ENABLE_EXTENDED_ALIGNED_STORAGE</PreprocessorDefinitions>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<ControlFlowGuard>Guard</ControlFlowGuard>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<OmitFramePointers>false</OmitFramePointers>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PreBuildEvent>
<Command>"$(ProjectDir)CMakeConfig.cmd" "$(VisualStudioVersion)" "$(Configuration)" "$(Platform)" "$(DevEnvDir)" "$(IncludePath)" "$(LibraryPath)"</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Configure Microsoft SEAL through CMake</Message>
</PreBuildEvent>
<Lib>
<AdditionalDependencies>Bcrypt.lib;zlibstaticd.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\thirdparty\zlib\build\$(Platform)\$(Configuration)</AdditionalLibraryDirectories>
<AdditionalOptions>/IGNORE:4006 %(AdditionalOptions)</AdditionalOptions>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)/thirdparty/zlib/src;$(SolutionDir)/thirdparty/zlib/build/$(Platform);$(ProjectDir)</AdditionalIncludeDirectories>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
<LanguageStandard>stdcpp17</LanguageStandard>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_ENABLE_EXTENDED_ALIGNED_STORAGE</PreprocessorDefinitions>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<ControlFlowGuard>Guard</ControlFlowGuard>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PreBuildEvent>
<Command>"$(ProjectDir)CMakeConfig.cmd" "$(VisualStudioVersion)" "$(Configuration)" "$(Platform)" "$(DevEnvDir)" "$(IncludePath)" "$(LibraryPath)"</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Configure Microsoft SEAL through CMake</Message>
</PreBuildEvent>
<Lib>
<AdditionalDependencies>Bcrypt.lib;zlibstaticd.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\thirdparty\zlib\build\$(Platform)\$(Configuration)</AdditionalLibraryDirectories>
<AdditionalOptions>/IGNORE:4006 %(AdditionalOptions)</AdditionalOptions>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)/thirdparty/zlib/src;$(SolutionDir)/thirdparty/zlib/build/$(Platform);$(ProjectDir)</AdditionalIncludeDirectories>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<LanguageStandard>stdcpp17</LanguageStandard>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_ENABLE_EXTENDED_ALIGNED_STORAGE</PreprocessorDefinitions>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<ControlFlowGuard>Guard</ControlFlowGuard>
<OmitFramePointers>true</OmitFramePointers>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PreBuildEvent>
<Command>"$(ProjectDir)CMakeConfig.cmd" "$(VisualStudioVersion)" "$(Configuration)" "$(Platform)" "$(DevEnvDir)" "$(IncludePath)" "$(LibraryPath)"</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Configure Microsoft SEAL through CMake</Message>
</PreBuildEvent>
<Lib>
<AdditionalDependencies>Bcrypt.lib;zlibstatic.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\thirdparty\zlib\build\$(Platform)\$(Configuration)</AdditionalLibraryDirectories>
<AdditionalOptions>/IGNORE:4006 %(AdditionalOptions)</AdditionalOptions>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)/thirdparty/zlib/src;$(SolutionDir)/thirdparty/zlib/build/$(Platform);$(ProjectDir)</AdditionalIncludeDirectories>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<LanguageStandard>stdcpp17</LanguageStandard>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_ENABLE_EXTENDED_ALIGNED_STORAGE</PreprocessorDefinitions>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<ControlFlowGuard>Guard</ControlFlowGuard>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PreBuildEvent>
<Command>"$(ProjectDir)CMakeConfig.cmd" "$(VisualStudioVersion)" "$(Configuration)" "$(Platform)" "$(DevEnvDir)" "$(IncludePath)" "$(LibraryPath)"</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Configure Microsoft SEAL through CMake</Message>
</PreBuildEvent>
<Lib>
<AdditionalDependencies>Bcrypt.lib;zlibstatic.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\thirdparty\zlib\build\$(Platform)\$(Configuration)</AdditionalLibraryDirectories>
<AdditionalOptions>/IGNORE:4006 %(AdditionalOptions)</AdditionalOptions>
</Lib>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Source Files\util">
<UniqueIdentifier>{a119ce23-aae9-4b06-be2c-1c8aada4ab20}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\util">
<UniqueIdentifier>{8740bd83-253c-49f3-8f9a-3b9c526f67c2}</UniqueIdentifier>
</Filter>
<Filter Include="Other">
<UniqueIdentifier>{8585bc5e-eaa9-481a-a6ee-c38be1319a32}</UniqueIdentifier>
</Filter>
<Filter Include="Other\cmake">
<UniqueIdentifier>{aaf838b1-cab2-4ccc-a016-a81c7edf506e}</UniqueIdentifier>
</Filter>
<Filter Include="Other\seal">
<UniqueIdentifier>{31fb1149-1a6f-438b-a86a-744384986d21}</UniqueIdentifier>
</Filter>
<Filter Include="Other\seal\util">
<UniqueIdentifier>{497d5f96-98a3-44e9-8b38-a2ea4bbea366}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="seal\batchencoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\biguint.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\ciphertext.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\ckks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\context.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\decryptor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\encryptionparams.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\encryptor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\evaluator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\galoiskeys.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\intarray.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\intencoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\keygenerator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\kswitchkeys.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\memorymanager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\plaintext.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\publickey.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\randomgen.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\randomtostd.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\relinkeys.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\seal.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\secretkey.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\modulus.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\valcheck.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\util\blake2.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\blake2-impl.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\clang.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\clipnormal.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\common.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\croots.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\defines.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\gcc.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\galois.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\globals.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\hash.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\hestdparms.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\locks.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\mempool.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\msvc.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\numth.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\pointer.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\polyarith.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\polyarithmod.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\polyarithsmallmod.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\polycore.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\rlwe.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\scalingvariant.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\ntt.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\streambuf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\util\uintarith.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\uintarithmod.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\uintarithsmallmod.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\uintcore.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\serializable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\serialization.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\util\ztools.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\rns.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="seal\util\iterator.h">
<Filter>Header Files\util</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="seal\batchencoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\biguint.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\ciphertext.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\ckks.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\context.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\decryptor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\encryptionparams.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\encryptor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\evaluator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\intencoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\keygenerator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\kswitchkeys.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\memorymanager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\modulus.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\plaintext.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\randomgen.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\serialization.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\valcheck.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\util\blake2xb.c">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\blake2b.c">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\clipnormal.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\croots.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\galois.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\globals.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\hash.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\mempool.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\numth.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\polyarith.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\polyarithmod.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\polyarithsmallmod.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\rlwe.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\rns.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\scalingvariant.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\ntt.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\streambuf.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\uintarith.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\uintarithmod.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\uintarithsmallmod.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\uintcore.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="seal\util\ztools.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="seal\CMakeLists.txt">
<Filter>Other\seal</Filter>
</Text>
<Text Include="seal\util\CMakeLists.txt">
<Filter>Other\seal\util</Filter>
</Text>
</ItemGroup>
<ItemGroup>
<None Include="cmake\SEALConfig.cmake.in">
<Filter>Other\cmake</Filter>
</None>
<None Include="seal\util\config.h.in">
<Filter>Other\seal\util</Filter>
</None>
<None Include="cmake\FindMSGSL.cmake">
<Filter>Other\cmake</Filter>
</None>
<None Include="CMakeConfig.cmd">
<Filter>Other</Filter>
</None>
</ItemGroup>
</Project>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{70BBB2AA-FA77-40C1-890F-7AA7DBB3AD3D}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>SEAL_C</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>SEAL_C</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(ProjectDir)..\..\lib\$(Platform)\$(Configuration)\</OutDir>
<TargetName>sealc</TargetName>
<IntDir>$(ProjectDir)obj\$(Platform)\$(Configuration)\seal\c\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(ProjectDir)..\..\lib\$(Platform)\$(Configuration)\</OutDir>
<TargetName>sealc</TargetName>
<IntDir>$(ProjectDir)obj\$(Platform)\$(Configuration)\seal\c\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)..\..\lib\$(Platform)\$(Configuration)\</OutDir>
<TargetName>sealc</TargetName>
<IntDir>$(ProjectDir)obj\$(Platform)\$(Configuration)\seal\c\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)..\..\lib\$(Platform)\$(Configuration)\</OutDir>
<TargetName>sealc</TargetName>
<IntDir>$(ProjectDir)obj\$(Platform)\$(Configuration)\seal\c\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>SEAL_C_EXPORTS;NOMINMAX;_ENABLE_EXTENDED_ALIGNED_STORAGE;_SCL_SECURE_NO_WARNING;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
<PrecompiledHeaderFile>seal\c/stdafx.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ControlFlowGuard>Guard</ControlFlowGuard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>seal.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>SEAL_C_EXPORTS;NOMINMAX;_ENABLE_EXTENDED_ALIGNED_STORAGE;_SCL_SECURE_NO_WARNING;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
<PrecompiledHeaderFile>seal\c\stdafx.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ControlFlowGuard>Guard</ControlFlowGuard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>seal.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>SEAL_C_EXPORTS;NOMINMAX;_ENABLE_EXTENDED_ALIGNED_STORAGE;_SCL_SECURE_NO_WARNING;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
<PrecompiledHeaderFile>seal\c\stdafx.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ControlFlowGuard>Guard</ControlFlowGuard>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>seal.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>SEAL_C_EXPORTS;NOMINMAX;_ENABLE_EXTENDED_ALIGNED_STORAGE;_SCL_SECURE_NO_WARNING;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
<PrecompiledHeaderFile>seal\c\stdafx.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ControlFlowGuard>Guard</ControlFlowGuard>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>seal.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\lib\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="seal\c\modulus.h" />
<ClInclude Include="seal\c\contextdata.h" />
<ClInclude Include="seal\c\batchencoder.h" />
<ClInclude Include="seal\c\biguint.h" />
<ClInclude Include="seal\c\ciphertext.h" />
<ClInclude Include="seal\c\ckksencoder.h" />
<ClInclude Include="seal\c\decryptor.h" />
<ClInclude Include="seal\c\defines.h" />
<ClInclude Include="seal\c\intencoder.h" />
<ClInclude Include="seal\c\encryptionparameterqualifiers.h" />
<ClInclude Include="seal\c\encryptionparameters.h" />
<ClInclude Include="seal\c\encryptor.h" />
<ClInclude Include="seal\c\evaluator.h" />
<ClInclude Include="seal\c\galoiskeys.h" />
<ClInclude Include="seal\c\keygenerator.h" />
<ClInclude Include="seal\c\kswitchkeys.h" />
<ClInclude Include="seal\c\memorymanager.h" />
<ClInclude Include="seal\c\memorypoolhandle.h" />
<ClInclude Include="seal\c\plaintext.h" />
<ClInclude Include="seal\c\publickey.h" />
<ClInclude Include="seal\c\relinkeys.h" />
<ClInclude Include="seal\c\sealcontext.h" />
<ClInclude Include="seal\c\secretkey.h" />
<ClInclude Include="seal\c\serialization.h" />
<ClInclude Include="seal\c\stdafx.h" />
<ClInclude Include="seal\c\targetver.h" />
<ClInclude Include="seal\c\utilities.h" />
<ClInclude Include="seal\c\valcheck.h" />
<ClInclude Include="seal\c\version.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="seal\c\modulus.cpp" />
<ClCompile Include="seal\c\contextdata.cpp" />
<ClCompile Include="seal\c\batchencoder.cpp" />
<ClCompile Include="seal\c\ciphertext.cpp" />
<ClCompile Include="seal\c\ckksencoder.cpp" />
<ClCompile Include="seal\c\decryptor.cpp" />
<ClCompile Include="seal\c\dllmain.cpp" />
<ClCompile Include="seal\c\biguint.cpp" />
<ClCompile Include="seal\c\intencoder.cpp" />
<ClCompile Include="seal\c\encryptionparameterqualifiers.cpp" />
<ClCompile Include="seal\c\encryptor.cpp" />
<ClCompile Include="seal\c\evaluator.cpp" />
<ClCompile Include="seal\c\galoiskeys.cpp" />
<ClCompile Include="seal\c\keygenerator.cpp" />
<ClCompile Include="seal\c\kswitchkeys.cpp" />
<ClCompile Include="seal\c\memorymanager.cpp" />
<ClCompile Include="seal\c\memorypoolhandle.cpp" />
<ClCompile Include="seal\c\plaintext.cpp" />
<ClCompile Include="seal\c\publickey.cpp" />
<ClCompile Include="seal\c\relinkeys.cpp" />
<ClCompile Include="seal\c\sealcontext.cpp" />
<ClCompile Include="seal\c\secretkey.cpp" />
<ClCompile Include="seal\c\serialization.cpp" />
<ClCompile Include="seal\c\encryptionparameters.cpp" />
<ClCompile Include="seal\c\utilities.cpp" />
<ClCompile Include="seal\c\stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="seal\c\valcheck.cpp" />
<ClCompile Include="seal\c\version.cpp" />
</ItemGroup>
<ItemGroup>
<Text Include="seal\c\CMakeLists.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Other">
<UniqueIdentifier>{1027e253-e357-4456-b08e-f29b7cceb334}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="seal\c\defines.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\utilities.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\batchencoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\biguint.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\ciphertext.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\ckksencoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\contextdata.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\decryptor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\encryptionparameterqualifiers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\encryptionparameters.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\encryptor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\evaluator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\galoiskeys.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\intencoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\keygenerator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\kswitchkeys.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\memorymanager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\memorypoolhandle.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\modulus.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\plaintext.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\publickey.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\relinkeys.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\sealcontext.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\secretkey.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\serialization.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\valcheck.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seal\c\version.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="seal\c\dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\utilities.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\batchencoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\biguint.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\ciphertext.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\ckksencoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\contextdata.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\decryptor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\encryptionparameterqualifiers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\encryptionparameters.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\encryptor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\evaluator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\galoiskeys.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\intencoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\keygenerator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\kswitchkeys.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\memorymanager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\memorypoolhandle.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\modulus.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\plaintext.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\publickey.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\relinkeys.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\sealcontext.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\secretkey.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\serialization.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\valcheck.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seal\c\version.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="seal\c\CMakeLists.txt">
<Filter>Other</Filter>
</Text>
</ItemGroup>
</Project>
\ No newline at end of file
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT license.
# Source files in this directory
target_sources(seal_obj PRIVATE
${CMAKE_CURRENT_LIST_DIR}/batchencoder.cpp
${CMAKE_CURRENT_LIST_DIR}/biguint.cpp
${CMAKE_CURRENT_LIST_DIR}/ciphertext.cpp
${CMAKE_CURRENT_LIST_DIR}/ckks.cpp
${CMAKE_CURRENT_LIST_DIR}/context.cpp
${CMAKE_CURRENT_LIST_DIR}/decryptor.cpp
${CMAKE_CURRENT_LIST_DIR}/intencoder.cpp
${CMAKE_CURRENT_LIST_DIR}/encryptionparams.cpp
${CMAKE_CURRENT_LIST_DIR}/encryptor.cpp
${CMAKE_CURRENT_LIST_DIR}/evaluator.cpp
${CMAKE_CURRENT_LIST_DIR}/keygenerator.cpp
${CMAKE_CURRENT_LIST_DIR}/kswitchkeys.cpp
${CMAKE_CURRENT_LIST_DIR}/memorymanager.cpp
${CMAKE_CURRENT_LIST_DIR}/modulus.cpp
${CMAKE_CURRENT_LIST_DIR}/plaintext.cpp
${CMAKE_CURRENT_LIST_DIR}/randomgen.cpp
${CMAKE_CURRENT_LIST_DIR}/serialization.cpp
${CMAKE_CURRENT_LIST_DIR}/valcheck.cpp
)
# Add header files for installation
install(
FILES
${CMAKE_CURRENT_LIST_DIR}/batchencoder.h
${CMAKE_CURRENT_LIST_DIR}/biguint.h
${CMAKE_CURRENT_LIST_DIR}/ciphertext.h
${CMAKE_CURRENT_LIST_DIR}/ckks.h
${CMAKE_CURRENT_LIST_DIR}/modulus.h
${CMAKE_CURRENT_LIST_DIR}/context.h
${CMAKE_CURRENT_LIST_DIR}/decryptor.h
${CMAKE_CURRENT_LIST_DIR}/intencoder.h
${CMAKE_CURRENT_LIST_DIR}/encryptionparams.h
${CMAKE_CURRENT_LIST_DIR}/encryptor.h
${CMAKE_CURRENT_LIST_DIR}/evaluator.h
${CMAKE_CURRENT_LIST_DIR}/galoiskeys.h
${CMAKE_CURRENT_LIST_DIR}/intarray.h
${CMAKE_CURRENT_LIST_DIR}/keygenerator.h
${CMAKE_CURRENT_LIST_DIR}/kswitchkeys.h
${CMAKE_CURRENT_LIST_DIR}/memorymanager.h
${CMAKE_CURRENT_LIST_DIR}/plaintext.h
${CMAKE_CURRENT_LIST_DIR}/publickey.h
${CMAKE_CURRENT_LIST_DIR}/randomgen.h
${CMAKE_CURRENT_LIST_DIR}/randomtostd.h
${CMAKE_CURRENT_LIST_DIR}/relinkeys.h
${CMAKE_CURRENT_LIST_DIR}/seal.h
${CMAKE_CURRENT_LIST_DIR}/secretkey.h
${CMAKE_CURRENT_LIST_DIR}/serializable.h
${CMAKE_CURRENT_LIST_DIR}/serialization.h
${CMAKE_CURRENT_LIST_DIR}/valcheck.h
DESTINATION
${SEAL_INCLUDES_INSTALL_DIR}/seal
)
add_subdirectory(util)
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include "seal/batchencoder.h"
#include "seal/valcheck.h"
#include "seal/util/common.h"
#include "seal/util/polycore.h"
#include <cstdlib>
#include <limits>
#include <random>
#include <stdexcept>
using namespace std;
using namespace seal::util;
namespace seal
{
BatchEncoder::BatchEncoder(shared_ptr<SEALContext> context) : context_(move(context))
{
// Verify parameters
if (!context_)
{
throw invalid_argument("invalid context");
}
if (!context_->parameters_set())
{
throw invalid_argument("encryption parameters are not set correctly");
}
auto &context_data = *context_->first_context_data();
if (context_data.parms().scheme() != scheme_type::BFV)
{
throw invalid_argument("unsupported scheme");
}
if (!context_data.qualifiers().using_batching)
{
throw invalid_argument("encryption parameters are not valid for batching");
}
// Set the slot count
slots_ = context_data.parms().poly_modulus_degree();
// Reserve space for all of the primitive roots
roots_of_unity_ = allocate_uint(slots_, pool_);
// Fill the vector of roots of unity with all distinct odd powers of generator.
// These are all the primitive (2*slots_)-th roots of unity in integers modulo
// parms.plain_modulus().
populate_roots_of_unity_vector(context_data);
// Populate matrix representation index map
populate_matrix_reps_index_map();
}
void BatchEncoder::populate_roots_of_unity_vector(const SEALContext::ContextData &context_data)
{
uint64_t root = context_data.plain_ntt_tables()->get_root();
auto &modulus = context_data.parms().plain_modulus();
uint64_t generator_sq = multiply_uint_uint_mod(root, root, modulus);
roots_of_unity_[0] = root;
for (size_t i = 1; i < slots_; i++)
{
roots_of_unity_[i] = multiply_uint_uint_mod(roots_of_unity_[i - 1], generator_sq, modulus);
}
}
void BatchEncoder::populate_matrix_reps_index_map()
{
int logn = get_power_of_two(slots_);
matrix_reps_index_map_ = allocate<size_t>(slots_, pool_);
// Copy from the matrix to the value vectors
size_t row_size = slots_ >> 1;
size_t m = slots_ << 1;
uint64_t gen = 3;
uint64_t pos = 1;
for (size_t i = 0; i < row_size; i++)
{
// Position in normal bit order
uint64_t index1 = (pos - 1) >> 1;
uint64_t index2 = (m - pos - 1) >> 1;
// Set the bit-reversed locations
matrix_reps_index_map_[i] = safe_cast<size_t>(util::reverse_bits(index1, logn));
matrix_reps_index_map_[row_size | i] = safe_cast<size_t>(util::reverse_bits(index2, logn));
// Next primitive root
pos *= gen;
pos &= (m - 1);
}
}
void BatchEncoder::reverse_bits(uint64_t *input)
{
#ifdef SEAL_DEBUG
if (input == nullptr)
{
throw invalid_argument("input cannot be null");
}
#endif
size_t coeff_count = context_->first_context_data()->parms().poly_modulus_degree();
int logn = get_power_of_two(coeff_count);
for (size_t i = 0; i < coeff_count; i++)
{
uint64_t reversed_i = util::reverse_bits(i, logn);
if (i < reversed_i)
{
swap(input[i], input[reversed_i]);
}
}
}
void BatchEncoder::encode(const vector<uint64_t> &values_matrix, Plaintext &destination)
{
auto &context_data = *context_->first_context_data();
// Validate input parameters
size_t values_matrix_size = values_matrix.size();
if (values_matrix_size > slots_)
{
throw logic_error("values_matrix size is too large");
}
#ifdef SEAL_DEBUG
uint64_t modulus = context_data.parms().plain_modulus().value();
for (auto v : values_matrix)
{
// Validate the i-th input
if (v >= modulus)
{
throw invalid_argument("input value is larger than plain_modulus");
}
}
#endif
// Set destination to full size
destination.resize(slots_);
destination.parms_id() = parms_id_zero;
// First write the values to destination coefficients.
// Read in top row, then bottom row.
for (size_t i = 0; i < values_matrix_size; i++)
{
*(destination.data() + matrix_reps_index_map_[i]) = values_matrix[i];
}
for (size_t i = values_matrix_size; i < slots_; i++)
{
*(destination.data() + matrix_reps_index_map_[i]) = 0;
}
// Transform destination using inverse of negacyclic NTT
// Note: We already performed bit-reversal when reading in the matrix
inverse_ntt_negacyclic_harvey(destination.data(), *context_data.plain_ntt_tables());
}
void BatchEncoder::encode(const vector<int64_t> &values_matrix, Plaintext &destination)
{
auto &context_data = *context_->first_context_data();
uint64_t modulus = context_data.parms().plain_modulus().value();
// Validate input parameters
size_t values_matrix_size = values_matrix.size();
if (values_matrix_size > slots_)
{
throw logic_error("values_matrix size is too large");
}
#ifdef SEAL_DEBUG
uint64_t plain_modulus_div_two = modulus >> 1;
for (auto v : values_matrix)
{
// Validate the i-th input
if (unsigned_gt(llabs(v), plain_modulus_div_two))
{
throw invalid_argument("input value is larger than plain_modulus");
}
}
#endif
// Set destination to full size
destination.resize(slots_);
destination.parms_id() = parms_id_zero;
// First write the values to destination coefficients.
// Read in top row, then bottom row.
for (size_t i = 0; i < values_matrix_size; i++)
{
*(destination.data() + matrix_reps_index_map_[i]) =
(values_matrix[i] < 0) ? (modulus + static_cast<uint64_t>(values_matrix[i]))
: static_cast<uint64_t>(values_matrix[i]);
}
for (size_t i = values_matrix_size; i < slots_; i++)
{
*(destination.data() + matrix_reps_index_map_[i]) = 0;
}
// Transform destination using inverse of negacyclic NTT
// Note: We already performed bit-reversal when reading in the matrix
inverse_ntt_negacyclic_harvey(destination.data(), *context_data.plain_ntt_tables());
}
#ifdef SEAL_USE_MSGSL
void BatchEncoder::encode(gsl::span<const uint64_t> values_matrix, Plaintext &destination)
{
auto &context_data = *context_->first_context_data();
// Validate input parameters
size_t values_matrix_size = static_cast<size_t>(values_matrix.size());
if (values_matrix_size > slots_)
{
throw logic_error("values_matrix size is too large");
}
#ifdef SEAL_DEBUG
uint64_t modulus = context_data.parms().plain_modulus().value();
for (auto v : values_matrix)
{
// Validate the i-th input
if (v >= modulus)
{
throw invalid_argument("input value is larger than plain_modulus");
}
}
#endif
// Set destination to full size
destination.resize(slots_);
destination.parms_id() = parms_id_zero;
// First write the values to destination coefficients. Read
// in top row, then bottom row.
using index_type = decltype(values_matrix)::size_type;
for (size_t i = 0; i < values_matrix_size; i++)
{
*(destination.data() + matrix_reps_index_map_[i]) = values_matrix[static_cast<index_type>(i)];
}
for (size_t i = values_matrix_size; i < slots_; i++)
{
*(destination.data() + matrix_reps_index_map_[i]) = 0;
}
// Transform destination using inverse of negacyclic NTT
// Note: We already performed bit-reversal when reading in the matrix
inverse_ntt_negacyclic_harvey(destination.data(), *context_data.plain_ntt_tables());
}
void BatchEncoder::encode(gsl::span<const int64_t> values_matrix, Plaintext &destination)
{
auto &context_data = *context_->first_context_data();
uint64_t modulus = context_data.parms().plain_modulus().value();
// Validate input parameters
size_t values_matrix_size = static_cast<size_t>(values_matrix.size());
if (values_matrix_size > slots_)
{
throw logic_error("values_matrix size is too large");
}
#ifdef SEAL_DEBUG
uint64_t plain_modulus_div_two = modulus >> 1;
for (auto v : values_matrix)
{
// Validate the i-th input
if (unsigned_gt(llabs(v), plain_modulus_div_two))
{
throw invalid_argument("input value is larger than plain_modulus");
}
}
#endif
// Set destination to full size
destination.resize(slots_);
destination.parms_id() = parms_id_zero;
// First write the values to destination coefficients. Read
// in top row, then bottom row.
using index_type = decltype(values_matrix)::size_type;
for (size_t i = 0; i < values_matrix_size; i++)
{
*(destination.data() + matrix_reps_index_map_[i]) =
(values_matrix[static_cast<index_type>(i)] < 0)
? (modulus + static_cast<uint64_t>(values_matrix[static_cast<index_type>(i)]))
: static_cast<uint64_t>(values_matrix[static_cast<index_type>(i)]);
}
for (size_t i = values_matrix_size; i < slots_; i++)
{
*(destination.data() + matrix_reps_index_map_[i]) = 0;
}
// Transform destination using inverse of negacyclic NTT
// Note: We already performed bit-reversal when reading in the matrix
inverse_ntt_negacyclic_harvey(destination.data(), *context_data.plain_ntt_tables());
}
#endif
void BatchEncoder::encode(Plaintext &plain, MemoryPoolHandle pool)
{
if (plain.is_ntt_form())
{
throw invalid_argument("plain cannot be in NTT form");
}
if (!pool)
{
throw invalid_argument("pool is uninitialized");
}
auto &context_data = *context_->first_context_data();
// Validate input parameters
if (plain.coeff_count() > context_data.parms().poly_modulus_degree())
{
throw invalid_argument("plain is not valid for encryption parameters");
}
#ifdef SEAL_DEBUG
if (!are_poly_coefficients_less_than(
plain.data(), plain.coeff_count(), context_data.parms().plain_modulus().value()))
{
throw invalid_argument("plain is not valid for encryption parameters");
}
#endif
// We need to permute the coefficients of plain. To do this, we allocate
// temporary space.
size_t input_plain_coeff_count = min(plain.coeff_count(), slots_);
auto temp(allocate_uint(input_plain_coeff_count, pool));
set_uint_uint(plain.data(), input_plain_coeff_count, temp.get());
// Set plain to full slot count size.
plain.resize(slots_);
plain.parms_id() = parms_id_zero;
// First write the values to destination coefficients. Read
// in top row, then bottom row.
for (size_t i = 0; i < input_plain_coeff_count; i++)
{
*(plain.data() + matrix_reps_index_map_[i]) = temp[i];
}
for (size_t i = input_plain_coeff_count; i < slots_; i++)
{
*(plain.data() + matrix_reps_index_map_[i]) = 0;
}
// Transform destination using inverse of negacyclic NTT
// Note: We already performed bit-reversal when reading in the matrix
inverse_ntt_negacyclic_harvey(plain.data(), *context_data.plain_ntt_tables());
}
void BatchEncoder::decode(const Plaintext &plain, vector<uint64_t> &destination, MemoryPoolHandle pool)
{
if (!is_valid_for(plain, context_))
{
throw invalid_argument("plain is not valid for encryption parameters");
}
if (plain.is_ntt_form())
{
throw invalid_argument("plain cannot be in NTT form");
}
if (!pool)
{
throw invalid_argument("pool is uninitialized");
}
auto &context_data = *context_->first_context_data();
// Set destination size
destination.resize(slots_);
// Never include the leading zero coefficient (if present)
size_t plain_coeff_count = min(plain.coeff_count(), slots_);
auto temp_dest(allocate_uint(slots_, pool));
// Make a copy of poly
set_uint_uint(plain.data(), plain_coeff_count, temp_dest.get());
set_zero_uint(slots_ - plain_coeff_count, temp_dest.get() + plain_coeff_count);
// Transform destination using negacyclic NTT.
ntt_negacyclic_harvey(temp_dest.get(), *context_data.plain_ntt_tables());
// Read top row
for (size_t i = 0; i < slots_; i++)
{
destination[i] = temp_dest[matrix_reps_index_map_[i]];
}
}
void BatchEncoder::decode(const Plaintext &plain, vector<int64_t> &destination, MemoryPoolHandle pool)
{
if (!is_valid_for(plain, context_))
{
throw invalid_argument("plain is not valid for encryption parameters");
}
if (plain.is_ntt_form())
{
throw invalid_argument("plain cannot be in NTT form");
}
if (!pool)
{
throw invalid_argument("pool is uninitialized");
}
auto &context_data = *context_->first_context_data();
uint64_t modulus = context_data.parms().plain_modulus().value();
// Set destination size
destination.resize(slots_);
// Never include the leading zero coefficient (if present)
size_t plain_coeff_count = min(plain.coeff_count(), slots_);
auto temp_dest(allocate_uint(slots_, pool));
// Make a copy of poly
set_uint_uint(plain.data(), plain_coeff_count, temp_dest.get());
set_zero_uint(slots_ - plain_coeff_count, temp_dest.get() + plain_coeff_count);
// Transform destination using negacyclic NTT.
ntt_negacyclic_harvey(temp_dest.get(), *context_data.plain_ntt_tables());
// Read top row, then bottom row
uint64_t plain_modulus_div_two = modulus >> 1;
for (size_t i = 0; i < slots_; i++)
{
uint64_t curr_value = temp_dest[matrix_reps_index_map_[i]];
destination[i] = (curr_value > plain_modulus_div_two)
? (static_cast<int64_t>(curr_value) - static_cast<int64_t>(modulus))
: static_cast<int64_t>(curr_value);
}
}
#ifdef SEAL_USE_MSGSL
void BatchEncoder::decode(const Plaintext &plain, gsl::span<uint64_t> destination, MemoryPoolHandle pool)
{
if (!is_valid_for(plain, context_))
{
throw invalid_argument("plain is not valid for encryption parameters");
}
if (plain.is_ntt_form())
{
throw invalid_argument("plain cannot be in NTT form");
}
if (!pool)
{
throw invalid_argument("pool is uninitialized");
}
auto &context_data = *context_->first_context_data();
using index_type = decltype(destination)::size_type;
if (unsigned_gt(destination.size(), numeric_limits<int>::max()) || unsigned_neq(destination.size(), slots_))
{
throw invalid_argument("destination has incorrect size");
}
// Never include the leading zero coefficient (if present)
size_t plain_coeff_count = min(plain.coeff_count(), slots_);
auto temp_dest(allocate_uint(slots_, pool));
// Make a copy of poly
set_uint_uint(plain.data(), plain_coeff_count, temp_dest.get());
set_zero_uint(slots_ - plain_coeff_count, temp_dest.get() + plain_coeff_count);
// Transform destination using negacyclic NTT.
ntt_negacyclic_harvey(temp_dest.get(), *context_data.plain_ntt_tables());
// Read top row
for (size_t i = 0; i < slots_; i++)
{
destination[static_cast<index_type>(i)] = temp_dest[matrix_reps_index_map_[i]];
}
}
void BatchEncoder::decode(const Plaintext &plain, gsl::span<int64_t> destination, MemoryPoolHandle pool)
{
if (!is_valid_for(plain, context_))
{
throw invalid_argument("plain is not valid for encryption parameters");
}
if (plain.is_ntt_form())
{
throw invalid_argument("plain cannot be in NTT form");
}
if (!pool)
{
throw invalid_argument("pool is uninitialized");
}
auto &context_data = *context_->first_context_data();
uint64_t modulus = context_data.parms().plain_modulus().value();
using index_type = decltype(destination)::size_type;
if (unsigned_gt(destination.size(), numeric_limits<int>::max()) || unsigned_neq(destination.size(), slots_))
{
throw invalid_argument("destination has incorrect size");
}
// Never include the leading zero coefficient (if present)
size_t plain_coeff_count = min(plain.coeff_count(), slots_);
auto temp_dest(allocate_uint(slots_, pool));
// Make a copy of poly
set_uint_uint(plain.data(), plain_coeff_count, temp_dest.get());
set_zero_uint(slots_ - plain_coeff_count, temp_dest.get() + plain_coeff_count);
// Transform destination using negacyclic NTT.
ntt_negacyclic_harvey(temp_dest.get(), *context_data.plain_ntt_tables());
// Read top row, then bottom row
uint64_t plain_modulus_div_two = modulus >> 1;
for (size_t i = 0; i < slots_; i++)
{
uint64_t curr_value = temp_dest[matrix_reps_index_map_[i]];
destination[static_cast<index_type>(i)] =
(curr_value > plain_modulus_div_two)
? (static_cast<int64_t>(curr_value) - static_cast<int64_t>(modulus))
: static_cast<int64_t>(curr_value);
}
}
#endif
void BatchEncoder::decode(Plaintext &plain, MemoryPoolHandle pool)
{
if (!is_valid_for(plain, context_))
{
throw invalid_argument("plain is not valid for encryption parameters");
}
if (plain.is_ntt_form())
{
throw invalid_argument("plain cannot be in NTT form");
}
if (!pool)
{
throw invalid_argument("pool is uninitialized");
}
auto &context_data = *context_->first_context_data();
// Never include the leading zero coefficient (if present)
size_t plain_coeff_count = min(plain.coeff_count(), slots_);
// Allocate temporary space to store a wide copy of plain
auto temp(allocate_uint(slots_, pool));
// Make a copy of poly
set_uint_uint(plain.data(), plain_coeff_count, temp.get());
set_zero_uint(slots_ - plain_coeff_count, temp.get() + plain_coeff_count);
// Transform destination using negacyclic NTT.
ntt_negacyclic_harvey(temp.get(), *context_data.plain_ntt_tables());
// Set plain to full slot count size (note that all new coefficients are
// set to zero).
plain.resize(slots_);
// Read top row, then bottom row
for (size_t i = 0; i < slots_; i++)
{
*(plain.data() + i) = temp[matrix_reps_index_map_[i]];
}
}
} // namespace seal
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#pragma once
#include "seal/context.h"
#include "seal/plaintext.h"
#include "seal/util/common.h"
#include "seal/util/defines.h"
#include "seal/util/uintarithsmallmod.h"
#include "seal/util/uintcore.h"
#include <limits>
#include <vector>
#ifdef SEAL_USE_MSGSL
#include <gsl/span>
#endif
namespace seal
{
/**
Provides functionality for CRT batching. If the polynomial modulus degree is N, and
the plaintext modulus is a prime number T such that T is congruent to 1 modulo 2N,
then BatchEncoder allows the plaintext elements to be viewed as 2-by-(N/2)
matrices of integers modulo T. Homomorphic operations performed on such encrypted
matrices are applied coefficient (slot) wise, enabling powerful SIMD functionality
for computations that are vectorizable. This functionality is often called "batching"
in the homomorphic encryption literature.
@par Mathematical Background
Mathematically speaking, if the polynomial modulus is X^N+1, N is a power of two, and
plain_modulus is a prime number T such that 2N divides T-1, then integers modulo T
contain a primitive 2N-th root of unity and the polynomial X^N+1 splits into n distinct
linear factors as X^N+1 = (X-a_1)*...*(X-a_N) mod T, where the constants a_1, ..., a_n
are all the distinct primitive 2N-th roots of unity in integers modulo T. The Chinese
Remainder Theorem (CRT) states that the plaintext space Z_T[X]/(X^N+1) in this case is
isomorphic (as an algebra) to the N-fold direct product of fields Z_T. The isomorphism
is easy to compute explicitly in both directions, which is what this class does.
Furthermore, the Galois group of the extension is (Z/2NZ)* ~= Z/2Z x Z/(N/2) whose
action on the primitive roots of unity is easy to describe. Since the batching slots
correspond 1-to-1 to the primitive roots of unity, applying Galois automorphisms on the
plaintext act by permuting the slots. By applying generators of the two cyclic
subgroups of the Galois group, we can effectively view the plaintext as a 2-by-(N/2)
matrix, and enable cyclic row rotations, and column rotations (row swaps).
@par Valid Parameters
Whether batching can be used depends on whether the plaintext modulus has been chosen
appropriately. Thus, to construct a BatchEncoder the user must provide an instance
of SEALContext such that its associated EncryptionParameterQualifiers object has the
flags parameters_set and enable_batching set to true.
@see EncryptionParameters for more information about encryption parameters.
@see EncryptionParameterQualifiers for more information about parameter qualifiers.
@see Evaluator for rotating rows and columns of encrypted matrices.
*/
class BatchEncoder
{
public:
/**
Creates a BatchEncoder. It is necessary that the encryption parameters
given through the SEALContext object support batching.
@param[in] context The SEALContext
@throws std::invalid_argument if the context is not set or encryption
parameters are not valid for batching
@throws std::invalid_argument if scheme is not scheme_type::BFV
*/
BatchEncoder(std::shared_ptr<SEALContext> context);
/**
Creates a plaintext from a given matrix. This function "batches" a given matrix
of integers modulo the plaintext modulus into a plaintext element, and stores
the result in the destination parameter. The input vector must have size at most equal
to the degree of the polynomial modulus. The first half of the elements represent the
first row of the matrix, and the second half represent the second row. The numbers
in the matrix can be at most equal to the plaintext modulus for it to represent
a valid plaintext.
If the destination plaintext overlaps the input values in memory, the behavior of
this function is undefined.
@param[in] values The matrix of integers modulo plaintext modulus to batch
@param[out] destination The plaintext polynomial to overwrite with the result
@throws std::invalid_argument if values is too large
*/
void encode(const std::vector<std::uint64_t> &values, Plaintext &destination);
/**
Creates a plaintext from a given matrix. This function "batches" a given matrix
of integers modulo the plaintext modulus into a plaintext element, and stores
the result in the destination parameter. The input vector must have size at most equal
to the degree of the polynomial modulus. The first half of the elements represent the
first row of the matrix, and the second half represent the second row. The numbers
in the matrix can be at most equal to the plaintext modulus for it to represent
a valid plaintext.
If the destination plaintext overlaps the input values in memory, the behavior of
this function is undefined.
@param[in] values The matrix of integers modulo plaintext modulus to batch
@param[out] destination The plaintext polynomial to overwrite with the result
@throws std::invalid_argument if values is too large
*/
void encode(const std::vector<std::int64_t> &values, Plaintext &destination);
#ifdef SEAL_USE_MSGSL
/**
Creates a plaintext from a given matrix. This function "batches" a given matrix
of integers modulo the plaintext modulus into a plaintext element, and stores
the result in the destination parameter. The input must have size at most equal
to the degree of the polynomial modulus. The first half of the elements represent the
first row of the matrix, and the second half represent the second row. The numbers
in the matrix can be at most equal to the plaintext modulus for it to represent
a valid plaintext.
If the destination plaintext overlaps the input values in memory, the behavior of
this function is undefined.
@param[in] values The matrix of integers modulo plaintext modulus to batch
@param[out] destination The plaintext polynomial to overwrite with the result
@throws std::invalid_argument if values is too large
*/
void encode(gsl::span<const std::uint64_t> values, Plaintext &destination);
/**
Creates a plaintext from a given matrix. This function "batches" a given matrix
of integers modulo the plaintext modulus into a plaintext element, and stores
the result in the destination parameter. The input must have size at most equal
to the degree of the polynomial modulus. The first half of the elements represent the
first row of the matrix, and the second half represent the second row. The numbers
in the matrix can be at most equal to the plaintext modulus for it to represent
a valid plaintext.
If the destination plaintext overlaps the input values in memory, the behavior of
this function is undefined.
@param[in] values The matrix of integers modulo plaintext modulus to batch
@param[out] destination The plaintext polynomial to overwrite with the result
@throws std::invalid_argument if values is too large
*/
void encode(gsl::span<const std::int64_t> values, Plaintext &destination);
#endif
/**
Creates a plaintext from a given matrix. This function "batches" a given matrix
of integers modulo the plaintext modulus in-place into a plaintext ready to be
encrypted. The matrix is given as a plaintext element whose first N/2 coefficients
represent the first row of the matrix, and the second N/2 coefficients represent the
second row, where N denotes the degree of the polynomial modulus. The input plaintext
must have degress less than the polynomial modulus, and coefficients less than the
plaintext modulus, i.e. it must be a valid plaintext for the encryption parameters.
Dynamic memory allocations in the process are allocated from the memory pool pointed
to by the given MemoryPoolHandle.
@param[in] plain The matrix of integers modulo plaintext modulus to batch
@param[in] pool The MemoryPoolHandle pointing to a valid memory pool
@throws std::invalid_argument if plain is not valid for the encryption parameters
@throws std::invalid_argument if plain is in NTT form
@throws std::invalid_argument if pool is uninitialized
*/
void encode(Plaintext &plain, MemoryPoolHandle pool = MemoryManager::GetPool());
/**
Inverse of encode. This function "unbatches" a given plaintext into a matrix
of integers modulo the plaintext modulus, and stores the result in the destination
parameter. The input plaintext must have degress less than the polynomial modulus,
and coefficients less than the plaintext modulus, i.e. it must be a valid plaintext
for the encryption parameters. Dynamic memory allocations in the process are
allocated from the memory pool pointed to by the given MemoryPoolHandle.
@param[in] plain The plaintext polynomial to unbatch
@param[out] destination The matrix to be overwritten with the values in the slots
@param[in] pool The MemoryPoolHandle pointing to a valid memory pool
@throws std::invalid_argument if plain is not valid for the encryption parameters
@throws std::invalid_argument if plain is in NTT form
@throws std::invalid_argument if pool is uninitialized
*/
void decode(
const Plaintext &plain, std::vector<std::uint64_t> &destination,
MemoryPoolHandle pool = MemoryManager::GetPool());
/**
Inverse of encode. This function "unbatches" a given plaintext into a matrix
of integers modulo the plaintext modulus, and stores the result in the destination
parameter. The input plaintext must have degress less than the polynomial modulus,
and coefficients less than the plaintext modulus, i.e. it must be a valid plaintext
for the encryption parameters. Dynamic memory allocations in the process are
allocated from the memory pool pointed to by the given MemoryPoolHandle.
@param[in] plain The plaintext polynomial to unbatch
@param[out] destination The matrix to be overwritten with the values in the slots
@param[in] pool The MemoryPoolHandle pointing to a valid memory pool
@throws std::invalid_argument if plain is not valid for the encryption parameters
@throws std::invalid_argument if plain is in NTT form
@throws std::invalid_argument if pool is uninitialized
*/
void decode(
const Plaintext &plain, std::vector<std::int64_t> &destination,
MemoryPoolHandle pool = MemoryManager::GetPool());
#ifdef SEAL_USE_MSGSL
/**
Inverse of encode. This function "unbatches" a given plaintext into a matrix
of integers modulo the plaintext modulus, and stores the result in the destination
parameter. The input plaintext must have degress less than the polynomial modulus,
and coefficients less than the plaintext modulus, i.e. it must be a valid plaintext
for the encryption parameters. Dynamic memory allocations in the process are
allocated from the memory pool pointed to by the given MemoryPoolHandle.
@param[in] plain The plaintext polynomial to unbatch
@param[out] destination The matrix to be overwritten with the values in the slots
@param[in] pool The MemoryPoolHandle pointing to a valid memory pool
@throws std::invalid_argument if plain is not valid for the encryption parameters
@throws std::invalid_argument if plain is in NTT form
@throws std::invalid_argument if destination has incorrect size
@throws std::invalid_argument if pool is uninitialized
*/
void decode(
const Plaintext &plain, gsl::span<std::uint64_t> destination,
MemoryPoolHandle pool = MemoryManager::GetPool());
/**
Inverse of encode. This function "unbatches" a given plaintext into a matrix
of integers modulo the plaintext modulus, and stores the result in the destination
parameter. The input plaintext must have degress less than the polynomial modulus,
and coefficients less than the plaintext modulus, i.e. it must be a valid plaintext
for the encryption parameters. Dynamic memory allocations in the process are
allocated from the memory pool pointed to by the given MemoryPoolHandle.
@param[in] plain The plaintext polynomial to unbatch
@param[out] destination The matrix to be overwritten with the values in the slots
@param[in] pool The MemoryPoolHandle pointing to a valid memory pool
@throws std::invalid_argument if plain is not valid for the encryption parameters
@throws std::invalid_argument if plain is in NTT form
@throws std::invalid_argument if destination has incorrect size
@throws std::invalid_argument if pool is uninitialized
*/
void decode(
const Plaintext &plain, gsl::span<std::int64_t> destination,
MemoryPoolHandle pool = MemoryManager::GetPool());
#endif
/**
Inverse of encode. This function "unbatches" a given plaintext in-place into
a matrix of integers modulo the plaintext modulus. The input plaintext must have
degress less than the polynomial modulus, and coefficients less than the plaintext
modulus, i.e. it must be a valid plaintext for the encryption parameters. Dynamic
memory allocations in the process are allocated from the memory pool pointed to by
the given MemoryPoolHandle.
@param[in] plain The plaintext polynomial to unbatch
@param[in] pool The MemoryPoolHandle pointing to a valid memory pool
@throws std::invalid_argument if plain is not valid for the encryption parameters
@throws std::invalid_argument if plain is in NTT form
@throws std::invalid_argument if pool is uninitialized
*/
void decode(Plaintext &plain, MemoryPoolHandle pool = MemoryManager::GetPool());
/**
Returns the number of slots.
*/
SEAL_NODISCARD inline auto slot_count() const noexcept
{
return slots_;
}
private:
BatchEncoder(const BatchEncoder &copy) = delete;
BatchEncoder(BatchEncoder &&source) = delete;
BatchEncoder &operator=(const BatchEncoder &assign) = delete;
BatchEncoder &operator=(BatchEncoder &&assign) = delete;
void populate_roots_of_unity_vector(const SEALContext::ContextData &context_data);
void populate_matrix_reps_index_map();
void reverse_bits(std::uint64_t *input);
MemoryPoolHandle pool_ = MemoryManager::GetPool();
std::shared_ptr<SEALContext> context_{ nullptr };
std::size_t slots_;
util::Pointer<std::uint64_t> roots_of_unity_;
util::Pointer<std::size_t> matrix_reps_index_map_;
};
} // namespace seal
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include "seal/biguint.h"
#include "seal/util/common.h"
#include "seal/util/uintarith.h"
#include "seal/util/uintarithmod.h"
#include "seal/util/uintcore.h"
#include <algorithm>
using namespace std;
using namespace seal::util;
namespace seal
{
BigUInt::BigUInt(int bit_count)
{
resize(bit_count);
}
BigUInt::BigUInt(const string &hex_value)
{
operator=(hex_value);
}
BigUInt::BigUInt(int bit_count, const string &hex_value)
{
resize(bit_count);
operator=(hex_value);
if (bit_count != bit_count_)
{
resize(bit_count);
}
}
BigUInt::BigUInt(int bit_count, uint64_t *value) : value_(decltype(value_)::Aliasing(value)), bit_count_(bit_count)
{
if (bit_count < 0)
{
throw invalid_argument("bit_count must be non-negative");
}
if (value == nullptr && bit_count > 0)
{
throw invalid_argument("value must be non-null for non-zero bit count");
}
}
#ifdef SEAL_USE_MSGSL
BigUInt::BigUInt(gsl::span<uint64_t> value)
{
if (unsigned_gt(value.size(), numeric_limits<int>::max() / bits_per_uint64))
{
throw std::invalid_argument("value has too large size");
}
value_ = decltype(value_)::Aliasing(value.data());
bit_count_ = static_cast<int>(value.size()) * bits_per_uint64;
}
#endif
BigUInt::BigUInt(int bit_count, uint64_t value)
{
resize(bit_count);
operator=(value);
if (bit_count != bit_count_)
{
resize(bit_count);
}
}
BigUInt::BigUInt(const BigUInt &copy)
{
resize(copy.bit_count());
operator=(copy);
}
BigUInt::BigUInt(BigUInt &&source) noexcept
: pool_(move(source.pool_)), value_(move(source.value_)), bit_count_(source.bit_count_)
{
// Pointer in source has been taken over so set it to nullptr
source.bit_count_ = 0;
}
BigUInt::~BigUInt() noexcept
{
reset();
}
string BigUInt::to_string() const
{
return uint_to_hex_string(value_.get(), uint64_count());
}
string BigUInt::to_dec_string() const
{
return uint_to_dec_string(value_.get(), uint64_count(), pool_);
}
void BigUInt::resize(int bit_count)
{
if (bit_count < 0)
{
throw invalid_argument("bit_count must be non-negative");
}
if (value_.is_alias())
{
throw logic_error("Cannot resize an aliased BigUInt");
}
if (bit_count == bit_count_)
{
return;
}
// Lazy initialization of MemoryPoolHandle
if (!pool_)
{
pool_ = MemoryManager::GetPool();
}
// Fast path if allocation size doesn't change.
size_t old_uint64_count = uint64_count();
size_t new_uint64_count = safe_cast<size_t>(divide_round_up(bit_count, bits_per_uint64));
if (old_uint64_count == new_uint64_count)
{
bit_count_ = bit_count;
return;
}
// Allocate new space.
decltype(value_) new_value;
if (new_uint64_count > 0)
{
new_value = allocate_uint(new_uint64_count, pool_);
}
// Copy over old value.
if (new_uint64_count > 0)
{
set_uint_uint(value_.get(), old_uint64_count, new_uint64_count, new_value.get());
filter_highbits_uint(new_value.get(), new_uint64_count, bit_count);
}
// Deallocate any owned pointers.
reset();
// Update class.
swap(value_, new_value);
bit_count_ = bit_count;
}
BigUInt &BigUInt::operator=(const BigUInt &assign)
{
// Do nothing if same thing.
if (&assign == this)
{
return *this;
}
// Verify assigned value will fit within bit count.
int assign_sig_bit_count = assign.significant_bit_count();
if (assign_sig_bit_count > bit_count_)
{
// Size is too large to currently fit, so resize.
resize(assign_sig_bit_count);
}
// Copy over value.
size_t assign_uint64_count = safe_cast<size_t>(divide_round_up(assign_sig_bit_count, bits_per_uint64));
if (uint64_count() > 0)
{
set_uint_uint(assign.value_.get(), assign_uint64_count, uint64_count(), value_.get());
}
return *this;
}
BigUInt &BigUInt::operator=(const string &hex_value)
{
int hex_value_length = safe_cast<int>(hex_value.size());
int assign_bit_count = get_hex_string_bit_count(hex_value.data(), hex_value_length);
if (assign_bit_count > bit_count_)
{
// Size is too large to currently fit, so resize.
resize(assign_bit_count);
}
if (bit_count_ > 0)
{
// Copy over value.
hex_string_to_uint(hex_value.data(), hex_value_length, uint64_count(), value_.get());
}
return *this;
}
BigUInt BigUInt::operator/(const BigUInt &operand2) const
{
int result_bits = significant_bit_count();
int operand2_bits = operand2.significant_bit_count();
if (operand2_bits == 0)
{
throw invalid_argument("operand2 must be positive");
}
if (operand2_bits > result_bits)
{
BigUInt zero(result_bits);
return zero;
}
BigUInt result(result_bits);
BigUInt remainder(result_bits);
size_t result_uint64_count = result.uint64_count();
if (result_uint64_count > operand2.uint64_count())
{
BigUInt operand2resized(result_bits);
operand2resized = operand2;
divide_uint_uint(
value_.get(), operand2resized.data(), result_uint64_count, result.data(), remainder.data(), pool_);
}
else
{
divide_uint_uint(
value_.get(), operand2.data(), result_uint64_count, result.data(), remainder.data(), pool_);
}
return result;
}
BigUInt BigUInt::divrem(const BigUInt &operand2, BigUInt &remainder) const
{
int result_bits = significant_bit_count();
remainder = *this;
int operand2_bits = operand2.significant_bit_count();
if (operand2_bits > result_bits)
{
BigUInt zero;
return zero;
}
BigUInt quotient(result_bits);
size_t uint64_count = remainder.uint64_count();
if (uint64_count > operand2.uint64_count())
{
BigUInt operand2resized(result_bits);
operand2resized = operand2;
divide_uint_uint_inplace(remainder.data(), operand2resized.data(), uint64_count, quotient.data(), pool_);
}
else
{
divide_uint_uint_inplace(remainder.data(), operand2.data(), uint64_count, quotient.data(), pool_);
}
return quotient;
}
void BigUInt::save_members(ostream &stream) const
{
auto old_except_mask = stream.exceptions();
try
{
// Throw exceptions on std::ios_base::badbit and std::ios_base::failbit
stream.exceptions(ios_base::badbit | ios_base::failbit);
int32_t bit_count32 = safe_cast<int32_t>(bit_count_);
streamsize data_size = safe_cast<streamsize>(mul_safe(uint64_count(), sizeof(uint64_t)));
stream.write(reinterpret_cast<const char *>(&bit_count32), sizeof(int32_t));
if (data_size)
{
stream.write(reinterpret_cast<const char *>(value_.get()), data_size);
}
}
catch (const ios_base::failure &)
{
stream.exceptions(old_except_mask);
throw runtime_error("I/O error");
}
catch (...)
{
stream.exceptions(old_except_mask);
throw;
}
stream.exceptions(old_except_mask);
}
void BigUInt::load_members(istream &stream)
{
auto old_except_mask = stream.exceptions();
try
{
// Throw exceptions on std::ios_base::badbit and std::ios_base::failbit
stream.exceptions(ios_base::badbit | ios_base::failbit);
int32_t read_bit_count = 0;
stream.read(reinterpret_cast<char *>(&read_bit_count), sizeof(int32_t));
if (read_bit_count > bit_count_)
{
// Size is too large to currently fit, so resize.
resize(read_bit_count);
}
size_t read_uint64_count = safe_cast<size_t>(divide_round_up(read_bit_count, bits_per_uint64));
streamsize data_size = safe_cast<streamsize>(mul_safe(read_uint64_count, sizeof(uint64_t)));
if (data_size)
{
stream.read(reinterpret_cast<char *>(value_.get()), data_size);
}
// Zero any extra space.
if (uint64_count() > read_uint64_count)
{
set_zero_uint(uint64_count() - read_uint64_count, value_.get() + read_uint64_count);
}
}
catch (const ios_base::failure &)
{
stream.exceptions(old_except_mask);
throw runtime_error("I/O error");
}
catch (...)
{
stream.exceptions(old_except_mask);
throw;
}
stream.exceptions(old_except_mask);
}
} // namespace seal
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#pragma once
#include "seal/memorymanager.h"
#include "seal/serialization.h"
#include "seal/util/common.h"
#include "seal/util/defines.h"
#include "seal/util/pointer.h"
#include "seal/util/uintarith.h"
#include "seal/util/uintarithmod.h"
#include "seal/util/uintcore.h"
#include "seal/util/ztools.h"
#include <cstdint>
#include <iostream>
#include <string>
#ifdef SEAL_USE_MSGSL
#include <gsl/span>
#endif
namespace seal
{
/**
Represents an unsigned integer with a specified bit width. Non-const
BigUInts are mutable and able to be resized. The bit count for a BigUInt
(which can be read with bit_count()) is set initially by the constructor
and can be resized either explicitly with the resize() function or
implicitly with an assignment operation (e.g., operator=(), operator+=(),
etc.). A rich set of unsigned integer operations are provided by the
BigUInt class, including comparison, traditional arithmetic (addition,
subtraction, multiplication, division), and modular arithmetic functions.
@par Backing Array
The backing array for a BigUInt stores its unsigned integer value as
a contiguous std::uint64_t array. Each std::uint64_t in the array
sequentially represents 64-bits of the integer value, with the least
significant quad-word storing the lower 64-bits and the order of the bits
for each quad word dependent on the architecture's std::uint64_t
representation. The size of the array equals the bit count of the BigUInt
(which can be read with bit_count()) rounded up to the next std::uint64_t
boundary (i.e., rounded up to the next 64-bit boundary). The uint64_count()
function returns the number of std::uint64_t in the backing array. The
data() function returns a pointer to the first std::uint64_t in the array.
Additionally, the operator [] function allows accessing the individual
bytes of the integer value in a platform-independent way - for example,
reading the third byte will always return bits 16-24 of the BigUInt value
regardless of the platform being little-endian or big-endian.
@par Implicit Resizing
Both the copy constructor and operator=() allocate more memory for the
backing array when needed, i.e. when the source BigUInt has a larger
backing array than the destination. Conversely, when the destination
backing array is already large enough, the data is only copied and the
unnecessary higher order bits are set to zero. When new memory has to be
allocated, only the significant bits of the source BigUInt are taken
into account. This is is important, because it avoids unnecessary zero
bits to be included in the destination, which in some cases could
accumulate and result in very large unnecessary allocations. However,
sometimes it is necessary to preserve the original size, even if some
of the leading bits are zero. For this purpose BigUInt contains functions
duplicate_from and duplicate_to, which create an exact copy of the source
BigUInt.
@par Alias BigUInts
An aliased BigUInt (which can be determined with is_alias()) is a special
type of BigUInt that does not manage its underlying std::uint64_t pointer
used to store the value. An aliased BigUInt supports most of the same
operations as a non-aliased BigUInt, including reading and writing the
value, however an aliased BigUInt does not internally allocate or
deallocate its backing array and, therefore, does not support resizing.
Any attempt, either explicitly or implicitly, to resize the BigUInt will
result in an exception being thrown. An aliased BigUInt can be created
with the BigUInt(int, std::uint64_t*) constructor or the alias() function.
Note that the pointer specified to be aliased must be deallocated
externally after the BigUInt is no longer in use. Aliasing is useful in
cases where it is desirable to not have each BigUInt manage its own memory
allocation and/or to prevent unnecessary copying.
@par Thread Safety
In general, reading a BigUInt is thread-safe while mutating is not.
Specifically, the backing array may be freed whenever a resize occurs,
the BigUInt is destroyed, or alias() is called, which would invalidate
the address returned by data() and the byte references returned by
operator []. When it is known that a resize will not occur, concurrent
reading and mutating will not inherently fail but it is possible for
a read to see a partially updated value from a concurrent write.
A non-aliased BigUInt allocates its backing array from the global
(thread-safe) memory pool. Consequently, creating or resizing a large
number of BigUInt can result in a performance loss due to thread
contention.
*/
class BigUInt
{
public:
/**
Creates an empty BigUInt with zero bit width. No memory is allocated
by this constructor.
*/
BigUInt() = default;
/**
Creates a zero-initialized BigUInt of the specified bit width.
@param[in] bit_count The bit width
@throws std::invalid_argument if bit_count is negative
*/
BigUInt(int bit_count);
/**
Creates a BigUInt initialized and minimally sized to fit the unsigned
hexadecimal integer specified by the string. The string matches the format
returned by to_string() and must consist of only the characters 0-9, A-F,
or a-f, most-significant nibble first.
@param[in] hex_value The hexadecimal integer string specifying the initial
value
@throws std::invalid_argument if hex_value does not adhere to the expected
format
*/
BigUInt(const std::string &hex_value);
/**
Creates a BigUInt of the specified bit width and initializes it with the
unsigned hexadecimal integer specified by the string. The string must match
the format returned by to_string() and must consist of only the characters
0-9, A-F, or a-f, most-significant nibble first.
@param[in] bit_count The bit width
@param[in] hex_value The hexadecimal integer string specifying the initial
value
@throws std::invalid_argument if bit_count is negative
@throws std::invalid_argument if hex_value does not adhere to the expected
format
*/
BigUInt(int bit_count, const std::string &hex_value);
/**
Creates an aliased BigUInt with the specified bit width and backing array.
An aliased BigUInt does not internally allocate or deallocate the backing
array, and instead uses the specified backing array for all read/write
operations. Note that resizing is not supported by an aliased BigUInt and
any required deallocation of the specified backing array must occur
externally after the aliased BigUInt is no longer in use.
@param[in] bit_count The bit width
@param[in] value The backing array to use
@throws std::invalid_argument if bit_count is negative or value is null
and bit_count is positive
*/
BigUInt(int bit_count, std::uint64_t *value);
#ifdef SEAL_USE_MSGSL
/**
Creates an aliased BigUInt with given backing array and bit width set to
the size of the backing array. An aliased BigUInt does not internally
allocate or deallocate the backing array, and instead uses the specified
backing array for all read/write operations. Note that resizing is not
supported by an aliased BigUInt and any required deallocation of the
specified backing array must occur externally after the aliased BigUInt
is no longer in use.
@param[in] value The backing array to use
@throws std::invalid_argument if value has too large size
*/
BigUInt(gsl::span<std::uint64_t> value);
#endif
/**
Creates a BigUInt of the specified bit width and initializes it to the
specified unsigned integer value.
@param[in] bit_count The bit width
@param[in] value The initial value to set the BigUInt
@throws std::invalid_argument if bit_count is negative
*/
BigUInt(int bit_count, std::uint64_t value);
/**
Creates a deep copy of a BigUInt. The created BigUInt will have the same
bit count and value as the original.
@param[in] copy The BigUInt to copy from
*/
BigUInt(const BigUInt &copy);
/**
Creates a new BigUInt by moving an old one.
@param[in] source The BigUInt to move from
*/
BigUInt(BigUInt &&source) noexcept;
/**
Destroys the BigUInt and deallocates the backing array if it is not
an aliased BigUInt.
*/
~BigUInt() noexcept;
/**
Returns whether or not the BigUInt is an alias.
*/
SEAL_NODISCARD inline bool is_alias() const noexcept
{
return value_.is_alias();
}
/**
Returns the bit count for the BigUInt.
*/
SEAL_NODISCARD inline int bit_count() const noexcept
{
return bit_count_;
}
/**
Returns a pointer to the backing array storing the BigUInt value.
The pointer points to the beginning of the backing array at the
least-significant quad word.
@warning The pointer is valid only until the backing array is freed,
which occurs when the BigUInt is resized, destroyed, or the alias()
function is called.
*/
SEAL_NODISCARD inline std::uint64_t *data()
{
return value_.get();
}
/**
Returns a const pointer to the backing array storing the BigUInt value.
The pointer points to the beginning of the backing array at the
least-significant quad word.
@warning The pointer is valid only until the backing array is freed, which
occurs when the BigUInt is resized, destroyed, or the alias() function is
called.
*/
SEAL_NODISCARD inline const std::uint64_t *data() const noexcept
{
return value_.get();
}
#ifdef SEAL_USE_MSGSL
/**
Returns the backing array storing the BigUInt value.
@warning The span is valid only until the backing array is freed, which
occurs when the BigUInt is resized, destroyed, or the alias() function is
called.
*/
SEAL_NODISCARD inline gsl::span<std::uint64_t> data_span()
{
return gsl::span<std::uint64_t>(value_.get(), uint64_count());
}
/**
Returns the backing array storing the BigUInt value.
@warning The span is valid only until the backing array is freed, which
occurs when the BigUInt is resized, destroyed, or the alias() function is
called.
*/
SEAL_NODISCARD inline gsl::span<const std::uint64_t> data_span() const
{
return gsl::span<const std::uint64_t>(value_.get(), uint64_count());
}
#endif
/**
Returns the number of bytes in the backing array used to store the BigUInt
value.
*/
SEAL_NODISCARD inline std::size_t byte_count() const
{
return static_cast<std::size_t>(util::divide_round_up(bit_count_, util::bits_per_byte));
}
/**
Returns the number of std::uint64_t in the backing array used to store
the BigUInt value.
*/
SEAL_NODISCARD inline std::size_t uint64_count() const
{
return static_cast<std::size_t>(util::divide_round_up(bit_count_, util::bits_per_uint64));
}
/**
Returns the number of significant bits for the BigUInt.
*/
SEAL_NODISCARD inline int significant_bit_count() const
{
if (bit_count_ == 0)
{
return 0;
}
return util::get_significant_bit_count_uint(value_.get(), uint64_count());
}
/**
Returns the BigUInt value as a double. Note that precision may be lost during
the conversion.
*/
SEAL_NODISCARD double to_double() const noexcept
{
const double TwoToThe64 = 18446744073709551616.0;
double result = 0;
for (std::size_t i = uint64_count(); i--;)
{
result *= TwoToThe64;
result += static_cast<double>(value_[i]);
}
return result;
}
/**
Returns the BigUInt value as a hexadecimal string.
*/
SEAL_NODISCARD std::string to_string() const;
/**
Returns the BigUInt value as a decimal string.
*/
SEAL_NODISCARD std::string to_dec_string() const;
/**
Returns whether or not the BigUInt has the value zero.
*/
SEAL_NODISCARD inline bool is_zero() const
{
if (bit_count_ == 0)
{
return true;
}
return util::is_zero_uint(value_.get(), uint64_count());
}
/**
Returns the byte at the corresponding byte index of the BigUInt's integer
value. The bytes of the BigUInt are indexed least-significant byte first.
@param[in] index The index of the byte to read
@throws std::out_of_range if index is not within [0, byte_count())
*/
SEAL_NODISCARD inline const SEAL_BYTE &operator[](std::size_t index) const
{
if (index >= byte_count())
{
throw std::out_of_range("index must be within [0, byte count)");
}
return *util::get_uint64_byte(value_.get(), index);
}
/**
Returns an byte reference that can read/write the byte at the corresponding
byte index of the BigUInt's integer value. The bytes of the BigUInt are
indexed least-significant byte first.
@warning The returned byte is an reference backed by the BigUInt's backing
array. As such, it is only valid until the BigUInt is resized, destroyed,
or alias() is called.
@param[in] index The index of the byte to read
@throws std::out_of_range if index is not within [0, byte_count())
*/
SEAL_NODISCARD inline SEAL_BYTE &operator[](std::size_t index)
{
if (index >= byte_count())
{
throw std::out_of_range("index must be within [0, byte count)");
}
return *util::get_uint64_byte(value_.get(), index);
}
/**
Sets the BigUInt value to zero. This does not resize the BigUInt.
*/
inline void set_zero()
{
if (bit_count_)
{
return util::set_zero_uint(uint64_count(), value_.get());
}
}
/**
Resizes the BigUInt to the specified bit width, copying over the old value
as much as will fit.
@param[in] bit_count The bit width
@throws std::invalid_argument if bit_count is negative
@throws std::logic_error if the BigUInt is an alias
*/
void resize(int bit_count);
/**
Makes the BigUInt an aliased BigUInt with the specified bit width and
backing array. An aliased BigUInt does not internally allocate or
deallocate the backing array, and instead uses the specified backing array
for all read/write operations. Note that resizing is not supported by
an aliased BigUInt and any required deallocation of the specified backing
array must occur externally after the aliased BigUInt is no longer in use.
@param[in] bit_count The bit width
@param[in] value The backing array to use
@throws std::invalid_argument if bit_count is negative or value is null
*/
inline void alias(int bit_count, std::uint64_t *value)
{
if (bit_count < 0)
{
throw std::invalid_argument("bit_count must be non-negative");
}
if (value == nullptr && bit_count > 0)
{
throw std::invalid_argument("value must be non-null for non-zero bit count");
}
// Deallocate any owned pointers.
reset();
// Update class.
value_ = util::Pointer<std::uint64_t>::Aliasing(value);
bit_count_ = bit_count;
}
#ifdef SEAL_USE_MSGSL
/**
Makes the BigUInt an aliased BigUInt with the given backing array
and bit width set equal to the size of the backing array. An aliased
BigUInt does not internally allocate or deallocate the backing array,
and instead uses the specified backing array for all read/write
operations. Note that resizing is not supported by an aliased BigUInt
and any required deallocation of the specified backing array must
occur externally after the aliased BigUInt is no longer in use.
@param[in] value The backing array to use
@throws std::invalid_argument if value has too large size
*/
inline void alias(gsl::span<std::uint64_t> value)
{
if (util::unsigned_gt(value.size(), std::numeric_limits<int>::max()))
{
throw std::invalid_argument("value has too large size");
}
// Deallocate any owned pointers.
reset();
// Update class.
value_ = util::Pointer<std::uint64_t>::Aliasing(value.data());
bit_count_ = static_cast<int>(value.size());
;
}
#endif
/**
Resets an aliased BigUInt into an empty non-alias BigUInt with bit count
of zero.
@throws std::logic_error if BigUInt is not an alias
*/
inline void unalias()
{
if (!value_.is_alias())
{
throw std::logic_error("BigUInt is not an alias");
}
// Reset class.
reset();
}
/**
Overwrites the BigUInt with the value of the specified BigUInt, enlarging
if needed to fit the assigned value. Only significant bits are used to
size the BigUInt.
@param[in] assign The BigUInt whose value should be assigned to the
current BigUInt
@throws std::logic_error if BigUInt is an alias and the assigned BigUInt is
too large to fit the current bit width
*/
BigUInt &operator=(const BigUInt &assign);
/**
Overwrites the BigUInt with the unsigned hexadecimal value specified by
the string, enlarging if needed to fit the assigned value. The string must
match the format returned by to_string() and must consist of only the
characters 0-9, A-F, or a-f, most-significant nibble first.
@param[in] hex_value The hexadecimal integer string specifying the value
to assign
@throws std::invalid_argument if hex_value does not adhere to the
expected format
@throws std::logic_error if BigUInt is an alias and the assigned value
is too large to fit the current bit width
*/
BigUInt &operator=(const std::string &hex_value);
/**
Overwrites the BigUInt with the specified integer value, enlarging if
needed to fit the value.
@param[in] value The value to assign
@throws std::logic_error if BigUInt is an alias and the significant bit
count of value is too large to fit the
current bit width
*/
inline BigUInt &operator=(std::uint64_t value)
{
int assign_bit_count = util::get_significant_bit_count(value);
if (assign_bit_count > bit_count_)
{
// Size is too large to currently fit, so resize.
resize(assign_bit_count);
}
if (bit_count_ > 0)
{
util::set_uint(value, uint64_count(), value_.get());
}
return *this;
}
/**
Returns a copy of the BigUInt value resized to the significant bit count.
*/
SEAL_NODISCARD inline BigUInt operator+() const
{
BigUInt result;
result = *this;
return result;
}
/**
Returns a negated copy of the BigUInt value. The bit count does not change.
*/
SEAL_NODISCARD inline BigUInt operator-() const
{
BigUInt result(bit_count_);
util::negate_uint(value_.get(), result.uint64_count(), result.data());
util::filter_highbits_uint(result.data(), result.uint64_count(), result.bit_count());
return result;
}
/**
Returns an inverted copy of the BigUInt value. The bit count does not change.
*/
SEAL_NODISCARD inline BigUInt operator~() const
{
BigUInt result(bit_count_);
util::not_uint(value_.get(), result.uint64_count(), result.data());
util::filter_highbits_uint(result.data(), result.uint64_count(), result.bit_count());
return result;
}
/**
Increments the BigUInt and returns the incremented value. The BigUInt will
increment the bit count if needed to fit the carry.
@throws std::logic_error if BigUInt is an alias and a carry occurs requiring
the BigUInt to be resized
*/
inline BigUInt &operator++()
{
if (util::increment_uint(value_.get(), uint64_count(), value_.get()))
{
resize(util::add_safe(bit_count_, 1));
util::set_bit_uint(value_.get(), uint64_count(), bit_count_);
}
bit_count_ = std::max(bit_count_, significant_bit_count());
return *this;
}
/**
Decrements the BigUInt and returns the decremented value. The bit count
does not change.
*/
inline BigUInt &operator--()
{
util::decrement_uint(value_.get(), uint64_count(), value_.get());
util::filter_highbits_uint(value_.get(), uint64_count(), bit_count_);
return *this;
}
#ifndef SEAL_USE_MAYBE_UNUSED
#if (SEAL_COMPILER == SEAL_COMPILER_GCC)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#elif (SEAL_COMPILER == SEAL_COMPILER_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#endif
#endif
/**
Increments the BigUInt but returns its old value. The BigUInt will increment
the bit count if needed to fit the carry.
*/
inline BigUInt operator++(int postfix SEAL_MAYBE_UNUSED)
{
BigUInt result;
result = *this;
if (util::increment_uint(value_.get(), uint64_count(), value_.get()))
{
resize(util::add_safe(bit_count_, 1));
util::set_bit_uint(value_.get(), uint64_count(), bit_count_);
}
bit_count_ = std::max(bit_count_, significant_bit_count());
return result;
}
/**
Decrements the BigUInt but returns its old value. The bit count does not change.
*/
inline BigUInt operator--(int postfix SEAL_MAYBE_UNUSED)
{
BigUInt result;
result = *this;
util::decrement_uint(value_.get(), uint64_count(), value_.get());
util::filter_highbits_uint(value_.get(), uint64_count(), bit_count_);
return result;
}
#ifndef SEAL_USE_MAYBE_UNUSED
#if (SEAL_COMPILER == SEAL_COMPILER_GCC)
#pragma GCC diagnostic pop
#elif (SEAL_COMPILER == SEAL_COMPILER_CLANG)
#pragma clang diagnostic pop
#endif
#endif
/**
Adds two BigUInts and returns the sum. The input operands are not modified.
The bit count of the sum is set to be one greater than the significant bit
count of the larger of the two input operands.
@param[in] operand2 The second operand to add
*/
SEAL_NODISCARD inline BigUInt operator+(const BigUInt &operand2) const
{
int result_bits = util::add_safe(std::max(significant_bit_count(), operand2.significant_bit_count()), 1);
BigUInt result(result_bits);
util::add_uint_uint(
value_.get(), uint64_count(), operand2.data(), operand2.uint64_count(), false, result.uint64_count(),
result.data());
return result;
}
/**
Adds a BigUInt and an unsigned integer and returns the sum. The input
operands are not modified. The bit count of the sum is set to be one greater
than the significant bit count of the larger of the two operands.
@param[in] operand2 The second operand to add
*/
SEAL_NODISCARD inline BigUInt operator+(std::uint64_t operand2) const
{
BigUInt operand2uint;
operand2uint = operand2;
return *this + operand2uint;
}
/**
Subtracts two BigUInts and returns the difference. The input operands are
not modified. The bit count of the difference is set to be the significant
bit count of the larger of the two input operands.
@param[in] operand2 The second operand to subtract
*/
SEAL_NODISCARD inline BigUInt operator-(const BigUInt &operand2) const
{
int result_bits = std::max(bit_count_, operand2.bit_count());
BigUInt result(result_bits);
util::sub_uint_uint(
value_.get(), uint64_count(), operand2.data(), operand2.uint64_count(), false, result.uint64_count(),
result.data());
util::filter_highbits_uint(result.data(), result.uint64_count(), result_bits);
return result;
}
/**
Subtracts a BigUInt and an unsigned integer and returns the difference.
The input operands are not modified. The bit count of the difference is set
to be the significant bit count of the larger of the two operands.
@param[in] operand2 The second operand to subtract
*/
SEAL_NODISCARD inline BigUInt operator-(std::uint64_t operand2) const
{
BigUInt operand2uint;
operand2uint = operand2;
return *this - operand2uint;
}
/**
Multiplies two BigUInts and returns the product. The input operands are
not modified. The bit count of the product is set to be the sum of the
significant bit counts of the two input operands.
@param[in] operand2 The second operand to multiply
*/
SEAL_NODISCARD inline BigUInt operator*(const BigUInt &operand2) const
{
int result_bits = util::add_safe(significant_bit_count(), operand2.significant_bit_count());
BigUInt result(result_bits);
util::multiply_uint_uint(
value_.get(), uint64_count(), operand2.data(), operand2.uint64_count(), result.uint64_count(),
result.data());
return result;
}
/**
Multiplies a BigUInt and an unsigned integer and returns the product.
The input operands are not modified. The bit count of the product is set
to be the sum of the significant bit counts of the two input operands.
@param[in] operand2 The second operand to multiply
*/
SEAL_NODISCARD inline BigUInt operator*(std::uint64_t operand2) const
{
BigUInt operand2uint;
operand2uint = operand2;
return *this * operand2uint;
}
/**
Divides two BigUInts and returns the quotient. The input operands are
not modified. The bit count of the quotient is set to be the significant
bit count of the first input operand.
@param[in] operand2 The second operand to divide
@throws std::invalid_argument if operand2 is zero
*/
SEAL_NODISCARD BigUInt operator/(const BigUInt &operand2) const;
/**
Divides a BigUInt and an unsigned integer and returns the quotient. The
input operands are not modified. The bit count of the quotient is set
to be the significant bit count of the first input operand.
@param[in] operand2 The second operand to divide
@throws std::invalid_argument if operand2 is zero
*/
SEAL_NODISCARD inline BigUInt operator/(std::uint64_t operand2) const
{
BigUInt operand2uint;
operand2uint = operand2;
return *this / operand2uint;
}
/**
Performs a bit-wise XOR operation between two BigUInts and returns the
result. The input operands are not modified. The bit count of the result
is set to the maximum of the two input operand bit counts.
@param[in] operand2 The second operand to XOR
*/
SEAL_NODISCARD inline BigUInt operator^(const BigUInt &operand2) const
{
int result_bits = std::max(bit_count_, operand2.bit_count());
BigUInt result(result_bits);
std::size_t uint64_count = result.uint64_count();
if (uint64_count != this->uint64_count())
{
result = *this;
util::xor_uint_uint(result.data(), operand2.data(), uint64_count, result.data());
}
else if (uint64_count != operand2.uint64_count())
{
result = operand2;
util::xor_uint_uint(result.data(), value_.get(), uint64_count, result.data());
}
else
{
util::xor_uint_uint(value_.get(), operand2.data(), uint64_count, result.data());
}
return result;
}
/**
Performs a bit-wise XOR operation between a BigUInt and an unsigned
integer and returns the result. The input operands are not modified.
The bit count of the result is set to the maximum of the two input
operand bit counts.
@param[in] operand2 The second operand to XOR
*/
SEAL_NODISCARD inline BigUInt operator^(std::uint64_t operand2) const
{
BigUInt operand2uint;
operand2uint = operand2;
return *this ^ operand2uint;
}
/**
Performs a bit-wise AND operation between two BigUInts and returns the
result. The input operands are not modified. The bit count of the result
is set to the maximum of the two input operand bit counts.
@param[in] operand2 The second operand to AND
*/
SEAL_NODISCARD inline BigUInt operator&(const BigUInt &operand2) const
{
int result_bits = std::max(bit_count_, operand2.bit_count());
BigUInt result(result_bits);
std::size_t uint64_count = result.uint64_count();
if (uint64_count != this->uint64_count())
{
result = *this;
util::and_uint_uint(result.data(), operand2.data(), uint64_count, result.data());
}
else if (uint64_count != operand2.uint64_count())
{
result = operand2;
util::and_uint_uint(result.data(), value_.get(), uint64_count, result.data());
}
else
{
util::and_uint_uint(value_.get(), operand2.data(), uint64_count, result.data());
}
return result;
}
/**
Performs a bit-wise AND operation between a BigUInt and an unsigned
integer and returns the result. The input operands are not modified.
The bit count of the result is set to the maximum of the two input
operand bit counts.
@param[in] operand2 The second operand to AND
*/
SEAL_NODISCARD inline BigUInt operator&(std::uint64_t operand2) const
{
BigUInt operand2uint;
operand2uint = operand2;
return *this & operand2uint;
}
/**
Performs a bit-wise OR operation between two BigUInts and returns the
result. The input operands are not modified. The bit count of the result
is set to the maximum of the two input operand bit counts.
@param[in] operand2 The second operand to OR
*/
SEAL_NODISCARD inline BigUInt operator|(const BigUInt &operand2) const
{
int result_bits = std::max(bit_count_, operand2.bit_count());
BigUInt result(result_bits);
std::size_t uint64_count = result.uint64_count();
if (uint64_count != this->uint64_count())
{
result = *this;
util::or_uint_uint(result.data(), operand2.data(), uint64_count, result.data());
}
else if (uint64_count != operand2.uint64_count())
{
result = operand2;
util::or_uint_uint(result.data(), value_.get(), uint64_count, result.data());
}
else
{
util::or_uint_uint(value_.get(), operand2.data(), uint64_count, result.data());
}
return result;
}
/**
Performs a bit-wise OR operation between a BigUInt and an unsigned
integer and returns the result. The input operands are not modified.
The bit count of the result is set to the maximum of the two input
operand bit counts.
@param[in] operand2 The second operand to OR
*/
SEAL_NODISCARD inline BigUInt operator|(std::uint64_t operand2) const
{
BigUInt operand2uint;
operand2uint = operand2;
return *this | operand2uint;
}
/**
Compares two BigUInts and returns -1, 0, or 1 if the BigUInt is
less-than, equal-to, or greater-than the second operand respectively.
The input operands are not modified.
@param[in] compare The value to compare against
*/
SEAL_NODISCARD inline int compareto(const BigUInt &compare) const
{
return util::compare_uint_uint(value_.get(), uint64_count(), compare.value_.get(), compare.uint64_count());
}
/**
Compares a BigUInt and an unsigned integer and returns -1, 0, or 1 if
the BigUInt is less-than, equal-to, or greater-than the second operand
respectively. The input operands are not modified.
@param[in] compare The value to compare against
*/
SEAL_NODISCARD inline int compareto(std::uint64_t compare) const
{
BigUInt compareuint;
compareuint = compare;
return compareto(compareuint);
}
/**
Returns whether or not a BigUInt is less-than a second BigUInt. The
input operands are not modified.
@param[in] operand2 The value to compare against
*/
SEAL_NODISCARD inline bool operator<(const BigUInt &compare) const
{
return util::compare_uint_uint(value_.get(), uint64_count(), compare.value_.get(), compare.uint64_count()) <
0;
}
/**
Returns whether or not a BigUInt is less-than an unsigned integer.
The input operands are not modified.
@param[in] operand2 The value to compare against
*/
SEAL_NODISCARD inline bool operator<(std::uint64_t compare) const
{
BigUInt compareuint;
compareuint = compare;
return *this < compareuint;
}
/**
Returns whether or not a BigUInt is greater-than a second BigUInt.
The input operands are not modified.
@param[in] operand2 The value to compare against
*/
SEAL_NODISCARD inline bool operator>(const BigUInt &compare) const
{
return util::compare_uint_uint(value_.get(), uint64_count(), compare.value_.get(), compare.uint64_count()) >
0;
}
/**
Returns whether or not a BigUInt is greater-than an unsigned integer.
The input operands are not modified.
@param[in] operand2 The value to compare against
*/
SEAL_NODISCARD inline bool operator>(std::uint64_t compare) const
{
BigUInt compareuint;
compareuint = compare;
return *this > compareuint;
}
/**
Returns whether or not a BigUInt is less-than or equal to a second
BigUInt. The input operands are not modified.
@param[in] operand2 The value to compare against
*/
SEAL_NODISCARD inline bool operator<=(const BigUInt &compare) const
{
return util::compare_uint_uint(
value_.get(), uint64_count(), compare.value_.get(), compare.uint64_count()) <= 0;
}
/**
Returns whether or not a BigUInt is less-than or equal to an unsigned
integer. The input operands are not modified.
@param[in] operand2 The value to compare against
*/
SEAL_NODISCARD inline bool operator<=(std::uint64_t compare) const
{
BigUInt compareuint;
compareuint = compare;
return *this <= compareuint;
}
/**
Returns whether or not a BigUInt is greater-than or equal to a second
BigUInt. The input operands are not modified.
@param[in] operand2 The value to compare against
*/
SEAL_NODISCARD inline bool operator>=(const BigUInt &compare) const
{
return util::compare_uint_uint(
value_.get(), uint64_count(), compare.value_.get(), compare.uint64_count()) >= 0;
}
/**
Returns whether or not a BigUInt is greater-than or equal to an unsigned
integer. The input operands are not modified.
@param[in] operand2 The value to compare against
*/
SEAL_NODISCARD inline bool operator>=(std::uint64_t compare) const
{
BigUInt compareuint;
compareuint = compare;
return *this >= compareuint;
}
/**
Returns whether or not a BigUInt is equal to a second BigUInt.
The input operands are not modified.
@param[in] compare The value to compare against
*/
SEAL_NODISCARD inline bool operator==(const BigUInt &compare) const
{
return util::compare_uint_uint(
value_.get(), uint64_count(), compare.value_.get(), compare.uint64_count()) == 0;
}
/**
Returns whether or not a BigUInt is equal to an unsigned integer.
The input operands are not modified.
@param[in] compare The value to compare against
*/
SEAL_NODISCARD inline bool operator==(std::uint64_t compare) const
{
BigUInt compareuint;
compareuint = compare;
return *this == compareuint;
}
/**
Returns whether or not a BigUInt is not equal to a second BigUInt.
The input operands are not modified.
@param[in] compare The value to compare against
*/
SEAL_NODISCARD inline bool operator!=(const BigUInt &compare) const
{
return !(operator==(compare));
}
/**
Returns whether or not a BigUInt is not equal to an unsigned integer.
The input operands are not modified.
@param[in] operand2 The value to compare against
*/
SEAL_NODISCARD inline bool operator!=(std::uint64_t compare) const
{
BigUInt compareuint;
compareuint = compare;
return *this != compareuint;
}
/**
Returns a left-shifted copy of the BigUInt. The bit count of the
returned value is the sum of the original significant bit count and
the shift amount.
@param[in] shift The number of bits to shift by
@throws std::invalid_argument if shift is negative
*/
SEAL_NODISCARD inline BigUInt operator<<(int shift) const
{
if (shift < 0)
{
throw std::invalid_argument("shift must be non-negative");
}
int result_bits = util::add_safe(significant_bit_count(), shift);
BigUInt result(result_bits);
result = *this;
util::left_shift_uint(result.data(), shift, result.uint64_count(), result.data());
return result;
}
/**
Returns a right-shifted copy of the BigUInt. The bit count of the
returned value is the original significant bit count subtracted by
the shift amount (clipped to zero if negative).
@param[in] shift The number of bits to shift by
@throws std::invalid_argument if shift is negative
*/
SEAL_NODISCARD inline BigUInt operator>>(int shift) const
{
if (shift < 0)
{
throw std::invalid_argument("shift must be non-negative");
}
int result_bits = util::sub_safe(significant_bit_count(), shift);
if (result_bits <= 0)
{
BigUInt zero;
return zero;
}
BigUInt result(result_bits);
result = *this;
util::right_shift_uint(result.data(), shift, result.uint64_count(), result.data());
return result;
}
/**
Adds two BigUInts saving the sum to the first operand, returning
a reference of the first operand. The second input operand is not
modified. The first operand is resized if and only if its bit count
is smaller than one greater than the significant bit count of the
larger of the two input operands.
@param[in] operand2 The second operand to add
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator+=(const BigUInt &operand2)
{
int result_bits = util::add_safe(std::max(significant_bit_count(), operand2.significant_bit_count()), 1);
if (bit_count_ < result_bits)
{
resize(result_bits);
}
util::add_uint_uint(
value_.get(), uint64_count(), operand2.data(), operand2.uint64_count(), false, uint64_count(),
value_.get());
return *this;
}
/**
Adds a BigUInt and an unsigned integer saving the sum to the first operand,
returning a reference of the first operand. The second input operand is not
modified. The first operand is resized if and only if its bit count is
smaller than one greater than the significant bit count of the larger of
the two input operands.
@param[in] operand2 The second operand to add
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator+=(std::uint64_t operand2)
{
BigUInt operand2uint;
operand2uint = operand2;
return operator+=(operand2uint);
}
/**
Subtracts two BigUInts saving the difference to the first operand,
returning a reference of the first operand. The second input operand is
not modified. The first operand is resized if and only if its bit count
is smaller than the significant bit count of the second operand.
@param[in] operand2 The second operand to subtract
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator-=(const BigUInt &operand2)
{
int result_bits = std::max(bit_count_, operand2.bit_count());
if (bit_count_ < result_bits)
{
resize(result_bits);
}
util::sub_uint_uint(
value_.get(), uint64_count(), operand2.data(), operand2.uint64_count(), false, uint64_count(),
value_.get());
util::filter_highbits_uint(value_.get(), uint64_count(), result_bits);
return *this;
}
/**
Subtracts a BigUInt and an unsigned integer saving the difference to
the first operand, returning a reference of the first operand. The second
input operand is not modified. The first operand is resized if and only
if its bit count is smaller than the significant bit count of the second
operand.
@param[in] operand2 The second operand to subtract
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator-=(std::uint64_t operand2)
{
BigUInt operand2uint;
operand2uint = operand2;
return operator-=(operand2uint);
}
/**
Multiplies two BigUInts saving the product to the first operand,
returning a reference of the first operand. The second input operand
is not modified. The first operand is resized if and only if its bit
count is smaller than the sum of the significant bit counts of the two
input operands.
@param[in] operand2 The second operand to multiply
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator*=(const BigUInt &operand2)
{
*this = *this * operand2;
return *this;
}
/**
Multiplies a BigUInt and an unsigned integer saving the product to
the first operand, returning a reference of the first operand. The
second input operand is not modified. The first operand is resized if
and only if its bit count is smaller than the sum of the significant
bit counts of the two input operands.
@param[in] operand2 The second operand to multiply
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator*=(std::uint64_t operand2)
{
BigUInt operand2uint;
operand2uint = operand2;
return operator*=(operand2uint);
}
/**
Divides two BigUInts saving the quotient to the first operand,
returning a reference of the first operand. The second input operand
is not modified. The first operand is never resized.
@param[in] operand2 The second operand to divide
@throws std::invalid_argument if operand2 is zero
*/
inline BigUInt &operator/=(const BigUInt &operand2)
{
*this = *this / operand2;
return *this;
}
/**
Divides a BigUInt and an unsigned integer saving the quotient to
the first operand, returning a reference of the first operand. The
second input operand is not modified. The first operand is never resized.
@param[in] operand2 The second operand to divide
@throws std::invalid_argument if operand2 is zero
*/
inline BigUInt &operator/=(std::uint64_t operand2)
{
BigUInt operand2uint;
operand2uint = operand2;
return operator/=(operand2uint);
}
/**
Performs a bit-wise XOR operation between two BigUInts saving the result
to the first operand, returning a reference of the first operand. The
second input operand is not modified. The first operand is resized if
and only if its bit count is smaller than the significant bit count of
the second operand.
@param[in] operand2 The second operand to XOR
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator^=(const BigUInt &operand2)
{
int result_bits = std::max(bit_count_, operand2.bit_count());
if (bit_count_ != result_bits)
{
resize(result_bits);
}
util::xor_uint_uint(value_.get(), operand2.data(), operand2.uint64_count(), value_.get());
return *this;
}
/**
Performs a bit-wise XOR operation between a BigUInt and an unsigned integer
saving the result to the first operand, returning a reference of the first
operand. The second input operand is not modified. The first operand is
resized if and only if its bit count is smaller than the significant bit
count of the second operand.
@param[in] operand2 The second operand to XOR
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator^=(std::uint64_t operand2)
{
BigUInt operand2uint;
operand2uint = operand2;
return operator^=(operand2uint);
}
/**
Performs a bit-wise AND operation between two BigUInts saving the result
to the first operand, returning a reference of the first operand. The
second input operand is not modified. The first operand is resized if
and only if its bit count is smaller than the significant bit count of
the second operand.
@param[in] operand2 The second operand to AND
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator&=(const BigUInt &operand2)
{
int result_bits = std::max(bit_count_, operand2.bit_count());
if (bit_count_ != result_bits)
{
resize(result_bits);
}
util::and_uint_uint(value_.get(), operand2.data(), operand2.uint64_count(), value_.get());
return *this;
}
/**
Performs a bit-wise AND operation between a BigUInt and an unsigned integer
saving the result to the first operand, returning a reference of the first
operand. The second input operand is not modified. The first operand is
resized if and only if its bit count is smaller than the significant bit
count of the second operand.
@param[in] operand2 The second operand to AND
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator&=(std::uint64_t operand2)
{
BigUInt operand2uint;
operand2uint = operand2;
return operator&=(operand2uint);
}
/**
Performs a bit-wise OR operation between two BigUInts saving the result to
the first operand, returning a reference of the first operand. The second
input operand is not modified. The first operand is resized if and only if
its bit count is smaller than the significant bit count of the second
operand.
@param[in] operand2 The second operand to OR
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator|=(const BigUInt &operand2)
{
int result_bits = std::max(bit_count_, operand2.bit_count());
if (bit_count_ != result_bits)
{
resize(result_bits);
}
util::or_uint_uint(value_.get(), operand2.data(), operand2.uint64_count(), value_.get());
return *this;
}
/**
Performs a bit-wise OR operation between a BigUInt and an unsigned integer
saving the result to the first operand, returning a reference of the first
operand. The second input operand is not modified. The first operand is
resized if and only if its bit count is smaller than the significant bit
count of the second operand.
@param[in] operand2 The second operand to OR
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator|=(std::uint64_t operand2)
{
BigUInt operand2uint;
operand2uint = operand2;
return operator|=(operand2uint);
}
/**
Left-shifts a BigUInt by the specified amount. The BigUInt is resized if
and only if its bit count is smaller than the sum of its significant bit
count and the shift amount.
@param[in] shift The number of bits to shift by
@throws std::invalid_argument if shift is negative
@throws std::logic_error if the BigUInt is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
inline BigUInt &operator<<=(int shift)
{
if (shift < 0)
{
throw std::invalid_argument("shift must be non-negative");
}
int result_bits = util::add_safe(significant_bit_count(), shift);
if (bit_count_ < result_bits)
{
resize(result_bits);
}
util::left_shift_uint(value_.get(), shift, uint64_count(), value_.get());
return *this;
}
/**
Right-shifts a BigUInt by the specified amount. The BigUInt is never
resized.
@param[in] shift The number of bits to shift by
@throws std::invalid_argument if shift is negative
*/
inline BigUInt &operator>>=(int shift)
{
if (shift < 0)
{
throw std::invalid_argument("shift must be non-negative");
}
if (shift > bit_count_)
{
set_zero();
return *this;
}
util::right_shift_uint(value_.get(), shift, uint64_count(), value_.get());
return *this;
}
/**
Divides two BigUInts and returns the quotient and sets the remainder
parameter to the remainder. The bit count of the quotient is set to be
the significant bit count of the BigUInt. The remainder is resized if
and only if it is smaller than the bit count of the BigUInt.
@param[in] operand2 The second operand to divide
@param[out] remainder The BigUInt to store the remainder
@throws std::invalid_argument if operand2 is zero
@throws std::logic_error if the remainder is an alias and the operator
attempts to enlarge the BigUInt to fit the result
*/
BigUInt divrem(const BigUInt &operand2, BigUInt &remainder) const;
/**
Divides a BigUInt and an unsigned integer and returns the quotient and
sets the remainder parameter to the remainder. The bit count of the
quotient is set to be the significant bit count of the BigUInt. The
remainder is resized if and only if it is smaller than the bit count
of the BigUInt.
@param[in] operand2 The second operand to divide
@param[out] remainder The BigUInt to store the remainder
@throws std::invalid_argument if operand2 is zero
@throws std::logic_error if the remainder is an alias which the
function attempts to enlarge to fit the result
*/
inline BigUInt divrem(std::uint64_t operand2, BigUInt &remainder) const
{
BigUInt operand2uint;
operand2uint = operand2;
return divrem(operand2uint, remainder);
}
/**
Returns the inverse of a BigUInt with respect to the specified modulus.
The original BigUInt is not modified. The bit count of the inverse is
set to be the significant bit count of the modulus.
@param[in] modulus The modulus to calculate the inverse with respect to
@throws std::invalid_argument if modulus is zero
@throws std::invalid_argument if modulus is not greater than the BigUInt value
@throws std::invalid_argument if the BigUInt value and modulus are not co-prime
@throws std::logic_error if the BigUInt value is zero
*/
SEAL_NODISCARD inline BigUInt modinv(const BigUInt &modulus) const
{
if (modulus.is_zero())
{
throw std::invalid_argument("modulus must be positive");
}
if (is_zero())
{
throw std::logic_error("BigUInt value cannot be zero");
}
int result_bits = modulus.significant_bit_count();
if (*this >= modulus)
{
throw std::invalid_argument("modulus must be greater than BigUInt");
}
BigUInt result(result_bits);
result = *this;
if (!util::try_invert_uint_mod(result.data(), modulus.data(), result.uint64_count(), result.data(), pool_))
{
throw std::invalid_argument("BigUInt and modulus are not co-prime");
}
return result;
}
/**
Returns the inverse of a BigUInt with respect to the specified modulus.
The original BigUInt is not modified. The bit count of the inverse is set
to be the significant bit count of the modulus.
@param[in] modulus The modulus to calculate the inverse with respect to
@throws std::invalid_argument if modulus is zero
@throws std::invalid_argument if modulus is not greater than the BigUInt value
@throws std::invalid_argument if the BigUInt value and modulus are not co-prime
@throws std::logic_error if the BigUInt value is zero
*/
SEAL_NODISCARD inline BigUInt modinv(std::uint64_t modulus) const
{
BigUInt modulusuint;
modulusuint = modulus;
return modinv(modulusuint);
}
/**
Attempts to calculate the inverse of a BigUInt with respect to the
specified modulus, returning whether or not the inverse was successful
and setting the inverse parameter to the inverse. The original BigUInt
is not modified. The inverse parameter is resized if and only if its bit
count is smaller than the significant bit count of the modulus.
@param[in] modulus The modulus to calculate the inverse with respect to
@param[out] inverse Stores the inverse if the inverse operation was
successful
@throws std::invalid_argument if modulus is zero
@throws std::invalid_argument if modulus is not greater than the BigUInt
value
@throws std::logic_error if the inverse is an alias which the function
attempts to enlarge to fit the result
*/
inline bool trymodinv(const BigUInt &modulus, BigUInt &inverse) const
{
if (modulus.is_zero())
{
throw std::invalid_argument("modulus must be positive");
}
if (is_zero())
{
return false;
}
int result_bits = modulus.significant_bit_count();
if (*this >= modulus)
{
throw std::invalid_argument("modulus must be greater than BigUInt");
}
if (inverse.bit_count() < result_bits)
{
inverse.resize(result_bits);
}
inverse = *this;
return util::try_invert_uint_mod(
inverse.data(), modulus.data(), inverse.uint64_count(), inverse.data(), pool_);
}
/**
Attempts to calculate the inverse of a BigUInt with respect to the
specified modulus, returning whether or not the inverse was successful
and setting the inverse parameter to the inverse. The original BigUInt
is not modified. The inverse parameter is resized if and only if its
bit count is smaller than the significant bit count of the modulus.
@param[in] modulus The modulus to calculate the inverse with respect to
@param[out] inverse Stores the inverse if the inverse operation was
successful
@throws std::invalid_argument if modulus is zero
@throws std::invalid_argument if modulus is not greater than the BigUInt
value
@throws std::logic_error if the inverse is an alias which the function
attempts to enlarge to fit the result
*/
inline bool trymodinv(std::uint64_t modulus, BigUInt &inverse) const
{
BigUInt modulusuint;
modulusuint = modulus;
return trymodinv(modulusuint, inverse);
}
/**
Returns an upper bound on the size of the BigUInt, as if it was written
to an output stream.
@param[in] compr_mode The compression mode
@throws std::invalid_argument if the compression mode is not supported
@throws std::logic_error if the size does not fit in the return type
*/
SEAL_NODISCARD inline std::streamoff save_size(
compr_mode_type compr_mode = Serialization::compr_mode_default) const
{
std::size_t members_size = Serialization::ComprSizeEstimate(
util::add_safe(
util::mul_safe(uint64_count(), sizeof(std::uint64_t)), // value_
sizeof(std::int32_t)), // bit_count_
compr_mode);
return util::safe_cast<std::streamoff>(util::add_safe(sizeof(Serialization::SEALHeader), members_size));
}
/**
Saves the BigUInt to an output stream. The full state of the BigUInt is
serialized, including insignificant bits. The output is in binary format
and not human-readable. The output stream must have the "binary" flag set.
@param[out] stream The stream to save the BigUInt to
@param[in] compr_mode The desired compression mode
@throws std::invalid_argument if the compression mode is not supported
@throws std::logic_error if the data to be saved is invalid, or if
compression failed
@throws std::runtime_error if I/O operations failed
*/
inline std::streamoff save(
std::ostream &stream, compr_mode_type compr_mode = Serialization::compr_mode_default) const
{
using namespace std::placeholders;
return Serialization::Save(
std::bind(&BigUInt::save_members, this, _1), save_size(compr_mode_type::none), stream, compr_mode);
}
/**
Loads a BigUInt from an input stream overwriting the current BigUInt.
@param[in] stream The stream to load the BigUInt from
@throws std::logic_error if the data cannot be loaded by this version of
Microsoft SEAL, if the loaded data is invalid, if decompression failed,
or if the loaded BigUInt is too large for an aliased BigUInt
@throws std::runtime_error if I/O operations failed
*/
inline std::streamoff load(std::istream &stream)
{
using namespace std::placeholders;
return Serialization::Load(std::bind(&BigUInt::load_members, this, _1), stream);
}
/**
Saves the BigUInt to a given memory location. The full state of the
BigUInt is serialized, including insignificant bits. The output is in
binary format and not human-readable.
@param[out] out The memory location to write the BigUInt to
@param[in] size The number of bytes available in the given memory location
@param[in] compr_mode The desired compression mode
@throws std::invalid_argument if out is null or if size is too small to
contain a SEALHeader, or if the compression mode is not supported
@throws std::logic_error if the data to be saved is invalid, or if
compression failed
@throws std::runtime_error if I/O operations failed
*/
inline std::streamoff save(
SEAL_BYTE *out, std::size_t size, compr_mode_type compr_mode = Serialization::compr_mode_default) const
{
using namespace std::placeholders;
return Serialization::Save(
std::bind(&BigUInt::save_members, this, _1), save_size(compr_mode_type::none), out, size, compr_mode);
}
/**
Loads a BigUInt from a memory location overwriting the current BigUInt.
@param[in] in The memory location to load the BigUInt from
@param[in] size The number of bytes available in the given memory location
@throws std::invalid_argument if in is null or if size is too small to
contain a SEALHeader
@throws std::logic_error if the data cannot be loaded by this version of
Microsoft SEAL, if the loaded data is invalid, if decompression failed,
or if the loaded BigUInt is too large for an aliased BigUInt
@throws std::runtime_error if I/O operations failed
*/
inline std::streamoff load(const SEAL_BYTE *in, std::size_t size)
{
using namespace std::placeholders;
return Serialization::Load(std::bind(&BigUInt::load_members, this, _1), in, size);
}
/**
Creates a minimally sized BigUInt initialized to the specified unsigned
integer value.
@param[in] value The value to initialized the BigUInt to
*/
SEAL_NODISCARD inline static BigUInt of(std::uint64_t value)
{
BigUInt result;
result = value;
return result;
}
/**
Duplicates the current BigUInt. The bit count and the value of the
given BigUInt are set to be exactly the same as in the current one.
@param[out] destination The BigUInt to overwrite with the duplicate
@throws std::logic_error if the destination BigUInt is an alias
*/
inline void duplicate_to(BigUInt &destination) const
{
destination.resize(this->bit_count_);
destination = *this;
}
/**
Duplicates a given BigUInt. The bit count and the value of the current
BigUInt are set to be exactly the same as in the given one.
@param[in] value The BigUInt to duplicate
@throws std::logic_error if the current BigUInt is an alias
*/
inline void duplicate_from(const BigUInt &value)
{
this->resize(value.bit_count_);
*this = value;
}
private:
MemoryPoolHandle pool_;
/**
Resets the entire state of the BigUInt to an empty, zero-sized state,
freeing any memory it internally allocated. If the BigUInt was an alias,
the backing array is not freed but the alias is no longer referenced.
*/
inline void reset() noexcept
{
value_.release();
bit_count_ = 0;
}
void save_members(std::ostream &stream) const;
void load_members(std::istream &stream);
/**
Points to the backing array for the BigUInt. This pointer will be set
to nullptr if and only if the bit count is zero. This pointer is
automatically allocated and freed by the BigUInt if and only if
the BigUInt is not an alias. If the BigUInt is an alias, then the
pointer was passed-in to a constructor or alias() call, and will not be
deallocated by the BigUInt.
*/
util::Pointer<std::uint64_t> value_;
/**
The bit count for the BigUInt.
*/
int bit_count_ = 0;
};
} // namespace seal
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT license.
# Source files in this directory
target_sources(sealc PRIVATE
${CMAKE_CURRENT_LIST_DIR}/batchencoder.cpp
${CMAKE_CURRENT_LIST_DIR}/biguint.cpp
${CMAKE_CURRENT_LIST_DIR}/ciphertext.cpp
${CMAKE_CURRENT_LIST_DIR}/ckksencoder.cpp
${CMAKE_CURRENT_LIST_DIR}/contextdata.cpp
${CMAKE_CURRENT_LIST_DIR}/decryptor.cpp
# ${CMAKE_CURRENT_LIST_DIR}/dllmain.cpp
${CMAKE_CURRENT_LIST_DIR}/encryptionparameterqualifiers.cpp
${CMAKE_CURRENT_LIST_DIR}/encryptionparameters.cpp
${CMAKE_CURRENT_LIST_DIR}/encryptor.cpp
${CMAKE_CURRENT_LIST_DIR}/evaluator.cpp
${CMAKE_CURRENT_LIST_DIR}/galoiskeys.cpp
${CMAKE_CURRENT_LIST_DIR}/intencoder.cpp
${CMAKE_CURRENT_LIST_DIR}/keygenerator.cpp
${CMAKE_CURRENT_LIST_DIR}/kswitchkeys.cpp
${CMAKE_CURRENT_LIST_DIR}/memorymanager.cpp
${CMAKE_CURRENT_LIST_DIR}/memorypoolhandle.cpp
${CMAKE_CURRENT_LIST_DIR}/modulus.cpp
${CMAKE_CURRENT_LIST_DIR}/plaintext.cpp
${CMAKE_CURRENT_LIST_DIR}/publickey.cpp
${CMAKE_CURRENT_LIST_DIR}/relinkeys.cpp
${CMAKE_CURRENT_LIST_DIR}/sealcontext.cpp
${CMAKE_CURRENT_LIST_DIR}/secretkey.cpp
${CMAKE_CURRENT_LIST_DIR}/serialization.cpp
${CMAKE_CURRENT_LIST_DIR}/utilities.cpp
${CMAKE_CURRENT_LIST_DIR}/valcheck.cpp
${CMAKE_CURRENT_LIST_DIR}/version.cpp
)
# Add header files for installation
install(
FILES
${CMAKE_CURRENT_LIST_DIR}/batchencoder.h
${CMAKE_CURRENT_LIST_DIR}/biguint.h
${CMAKE_CURRENT_LIST_DIR}/ciphertext.h
${CMAKE_CURRENT_LIST_DIR}/ckksencoder.h
${CMAKE_CURRENT_LIST_DIR}/contextdata.h
${CMAKE_CURRENT_LIST_DIR}/decryptor.h
${CMAKE_CURRENT_LIST_DIR}/defines.h
${CMAKE_CURRENT_LIST_DIR}/encryptionparameterqualifiers.h
${CMAKE_CURRENT_LIST_DIR}/encryptionparameters.h
${CMAKE_CURRENT_LIST_DIR}/encryptor.h
${CMAKE_CURRENT_LIST_DIR}/evaluator.h
${CMAKE_CURRENT_LIST_DIR}/galoiskeys.h
${CMAKE_CURRENT_LIST_DIR}/intencoder.h
${CMAKE_CURRENT_LIST_DIR}/keygenerator.h
${CMAKE_CURRENT_LIST_DIR}/kswitchkeys.h
${CMAKE_CURRENT_LIST_DIR}/memorymanager.h
${CMAKE_CURRENT_LIST_DIR}/memorypoolhandle.h
${CMAKE_CURRENT_LIST_DIR}/modulus.h
${CMAKE_CURRENT_LIST_DIR}/plaintext.h
${CMAKE_CURRENT_LIST_DIR}/publickey.h
${CMAKE_CURRENT_LIST_DIR}/relinkeys.h
${CMAKE_CURRENT_LIST_DIR}/sealcontext.h
${CMAKE_CURRENT_LIST_DIR}/secretkey.h
${CMAKE_CURRENT_LIST_DIR}/serialization.h
${CMAKE_CURRENT_LIST_DIR}/stdafx.h
${CMAKE_CURRENT_LIST_DIR}/targetver.h
${CMAKE_CURRENT_LIST_DIR}/utilities.h
${CMAKE_CURRENT_LIST_DIR}/valcheck.h
${CMAKE_CURRENT_LIST_DIR}/version.h
DESTINATION
${SEAL_INCLUDES_INSTALL_DIR}/seal/c
)
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
// STD
#include <vector>
// SEALNet
#include "seal/c/batchencoder.h"
#include "seal/c/stdafx.h"
#include "seal/c/utilities.h"
// SEAL
#include "seal/batchencoder.h"
using namespace std;
using namespace seal;
using namespace seal::c;
SEAL_C_FUNC BatchEncoder_Create(void *context, void **batch_encoder)
{
const auto &sharedctx = SharedContextFromVoid(context);
IfNullRet(sharedctx, E_POINTER);
IfNullRet(batch_encoder, E_POINTER);
try
{
BatchEncoder *encoder = new BatchEncoder(sharedctx);
*batch_encoder = encoder;
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
}
SEAL_C_FUNC BatchEncoder_Destroy(void *thisptr)
{
BatchEncoder *encoder = FromVoid<BatchEncoder>(thisptr);
IfNullRet(encoder, E_POINTER);
delete encoder;
return S_OK;
}
SEAL_C_FUNC BatchEncoder_Encode1(void *thisptr, uint64_t count, uint64_t *values, void *destination)
{
BatchEncoder *encoder = FromVoid<BatchEncoder>(thisptr);
IfNullRet(encoder, E_POINTER);
IfNullRet(values, E_POINTER);
Plaintext *plain = FromVoid<Plaintext>(destination);
IfNullRet(plain, E_POINTER);
vector<uint64_t> valvec(count);
for (uint64_t i = 0; i < count; i++)
{
valvec[i] = values[i];
}
try
{
encoder->encode(valvec, *plain);
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
}
SEAL_C_FUNC BatchEncoder_Encode2(void *thisptr, uint64_t count, int64_t *values, void *destination)
{
BatchEncoder *encoder = FromVoid<BatchEncoder>(thisptr);
IfNullRet(encoder, E_POINTER);
IfNullRet(values, E_POINTER);
Plaintext *plain = FromVoid<Plaintext>(destination);
IfNullRet(plain, E_POINTER);
vector<int64_t> valvec(count);
for (uint64_t i = 0; i < count; i++)
{
valvec[i] = values[i];
}
try
{
encoder->encode(valvec, *plain);
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
}
SEAL_C_FUNC BatchEncoder_Encode3(void *thisptr, void *plain, void *pool)
{
BatchEncoder *encoder = FromVoid<BatchEncoder>(thisptr);
IfNullRet(encoder, E_POINTER);
Plaintext *plainptr = FromVoid<Plaintext>(plain);
IfNullRet(plainptr, E_POINTER);
unique_ptr<MemoryPoolHandle> handle = MemHandleFromVoid(pool);
try
{
encoder->encode(*plainptr, *handle);
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
}
SEAL_C_FUNC BatchEncoder_Decode1(void *thisptr, void *plain, uint64_t *count, uint64_t *destination, void *pool)
{
BatchEncoder *encoder = FromVoid<BatchEncoder>(thisptr);
IfNullRet(encoder, E_POINTER);
IfNullRet(count, E_POINTER);
IfNullRet(destination, E_POINTER);
Plaintext *plainptr = FromVoid<Plaintext>(plain);
IfNullRet(plainptr, E_POINTER);
unique_ptr<MemoryPoolHandle> handle = MemHandleFromVoid(pool);
vector<uint64_t> result;
try
{
encoder->decode(*plainptr, result, *handle);
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
// Copy to actual destination
*count = result.size();
for (uint64_t i = 0; i < *count; i++)
{
destination[i] = result[i];
}
return S_OK;
}
SEAL_C_FUNC BatchEncoder_Decode2(void *thisptr, void *plain, uint64_t *count, int64_t *destination, void *pool)
{
BatchEncoder *encoder = FromVoid<BatchEncoder>(thisptr);
IfNullRet(encoder, E_POINTER);
IfNullRet(count, E_POINTER);
IfNullRet(destination, E_POINTER);
Plaintext *plainptr = FromVoid<Plaintext>(plain);
IfNullRet(plainptr, E_POINTER);
unique_ptr<MemoryPoolHandle> handle = MemHandleFromVoid(pool);
vector<int64_t> result;
try
{
encoder->decode(*plainptr, result, *handle);
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
*count = result.size();
// Copy to actual destination
for (uint64_t i = 0; i < *count; i++)
{
destination[i] = result[i];
}
return S_OK;
}
SEAL_C_FUNC BatchEncoder_Decode3(void *thisptr, void *plain, void *pool)
{
BatchEncoder *encoder = FromVoid<BatchEncoder>(thisptr);
IfNullRet(encoder, E_POINTER);
Plaintext *plainptr = FromVoid<Plaintext>(plain);
IfNullRet(plainptr, E_POINTER);
unique_ptr<MemoryPoolHandle> handle = MemHandleFromVoid(pool);
try
{
encoder->decode(*plainptr, *handle);
return S_OK;
}
catch (const invalid_argument &)
{
return E_INVALIDARG;
}
}
SEAL_C_FUNC BatchEncoder_GetSlotCount(void *thisptr, uint64_t *slot_count)
{
BatchEncoder *encoder = FromVoid<BatchEncoder>(thisptr);
IfNullRet(encoder, E_POINTER);
IfNullRet(slot_count, E_POINTER);
*slot_count = encoder->slot_count();
return S_OK;
}
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#pragma once
///////////////////////////////////////////////////////////////////////////
//
// This API is provided as a simple interface for Microsoft SEAL library
// that can be PInvoked by .Net code.
//
///////////////////////////////////////////////////////////////////////////
#include "seal/c/defines.h"
#include <stdint.h>
SEAL_C_FUNC BatchEncoder_Create(void *context, void **batch_encoder);
SEAL_C_FUNC BatchEncoder_Destroy(void *thisptr);
SEAL_C_FUNC BatchEncoder_Encode1(void *thisptr, uint64_t count, uint64_t *values, void *destination);
SEAL_C_FUNC BatchEncoder_Encode2(void *thisptr, uint64_t count, int64_t *values, void *destination);
SEAL_C_FUNC BatchEncoder_Encode3(void *thisptr, void *plain, void *pool);
SEAL_C_FUNC BatchEncoder_Decode1(void *thisptr, void *plain, uint64_t *count, uint64_t *destination, void *pool);
SEAL_C_FUNC BatchEncoder_Decode2(void *thisptr, void *plain, uint64_t *count, int64_t *destination, void *pool);
SEAL_C_FUNC BatchEncoder_Decode3(void *thisptr, void *plain, void *pool);
SEAL_C_FUNC BatchEncoder_GetSlotCount(void *thisptr, uint64_t *slot_count);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment