|
@@ -12,20 +12,52 @@ using namespace std::chrono;
|
|
|
using namespace std;
|
|
|
using namespace seal;
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+uint8_t no_of_expected_parameters = 4;
|
|
|
+uint64_t number_of_items;
|
|
|
+uint64_t size_per_item;
|
|
|
+uint32_t d;
|
|
|
+uint64_t num_requests;
|
|
|
+
|
|
|
+int getCMDArgs(int argc, char * argv[]) {
|
|
|
+ if(argc < no_of_expected_parameters){
|
|
|
+ printf("Command line parameters error, expected :\n");
|
|
|
+ printf("./sealpir <number_of_items> <size_per_item> <d> <num_requests>\n");
|
|
|
+ exit(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ std::string str = argv[1];
|
|
|
+ number_of_items = std::stoi(str);
|
|
|
+ str = argv[2];
|
|
|
+ size_per_item = std::stoi(str);
|
|
|
+ str = argv[3];
|
|
|
+ d = std::stoi(str);
|
|
|
+ str = argv[4];
|
|
|
+ num_requests = std::stoi(str);
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
|
|
+ getCMDArgs(argc, argv);
|
|
|
|
|
|
-
|
|
|
- uint64_t number_of_items = 1 << 12;
|
|
|
-
|
|
|
- uint64_t size_per_item = 288;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t N = 2048;
|
|
|
|
|
|
uint32_t logt = 12;
|
|
|
- uint32_t d = 5;
|
|
|
+
|
|
|
+
|
|
|
|
|
|
EncryptionParameters params(scheme_type::BFV);
|
|
|
PirParams pir_params;
|
|
@@ -80,68 +112,96 @@ int main(int argc, char *argv[]) {
|
|
|
auto time_pre_e = high_resolution_clock::now();
|
|
|
auto time_pre_us = duration_cast<microseconds>(time_pre_e - time_pre_s).count();
|
|
|
|
|
|
-
|
|
|
- uint64_t ele_index = rd() % number_of_items;
|
|
|
-
|
|
|
- cout << "Main: element index = " << ele_index << " from [0, " << number_of_items -1 << "]" << endl;
|
|
|
- uint64_t index = client.get_fv_index(ele_index, size_per_item);
|
|
|
- uint64_t offset = client.get_fv_offset(ele_index, size_per_item);
|
|
|
-
|
|
|
- cout << "Main: FV index = " << index << ", FV offset = " << offset << endl;
|
|
|
-
|
|
|
- auto time_query_s = high_resolution_clock::now();
|
|
|
- PirQuery query = client.generate_query(index);
|
|
|
- auto time_query_e = high_resolution_clock::now();
|
|
|
- auto time_query_us = duration_cast<microseconds>(time_query_e - time_query_s).count();
|
|
|
- cout << "Main: query generated" << endl;
|
|
|
-
|
|
|
-
|
|
|
- auto time_server_s = high_resolution_clock::now();
|
|
|
-
|
|
|
- PirReply reply = server.generate_reply(query, 0, client);
|
|
|
- auto time_server_e = high_resolution_clock::now();
|
|
|
- auto time_server_us = duration_cast<microseconds>(time_server_e - time_server_s).count();
|
|
|
-
|
|
|
-
|
|
|
- auto time_decode_s = chrono::high_resolution_clock::now();
|
|
|
- Plaintext result = client.decode_reply(reply);
|
|
|
- auto time_decode_e = chrono::high_resolution_clock::now();
|
|
|
- auto time_decode_us = duration_cast<microseconds>(time_decode_e - time_decode_s).count();
|
|
|
-
|
|
|
-
|
|
|
- vector<uint8_t> elems(N * logt / 8);
|
|
|
- coeffs_to_bytes(logt, result, elems.data(), (N * logt) / 8);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- for (uint32_t i = 0; i < size_per_item; i++) {
|
|
|
- if (elems[(offset * size_per_item) + i] != check_db.get()[(ele_index * size_per_item) + i]) {
|
|
|
- cout << "elems " << (int)elems[(offset * size_per_item) + i] << ", db "
|
|
|
- << (int) check_db.get()[(ele_index * size_per_item) + i] << endl;
|
|
|
- cout << "PIR result wrong!" << endl;
|
|
|
- return -1;
|
|
|
- }
|
|
|
+
|
|
|
+ for (uint64_t l = 0; l< num_requests; l++) {
|
|
|
+
|
|
|
+
|
|
|
+ uint64_t ele_index = rd() % number_of_items;
|
|
|
+
|
|
|
+ cout << "Main: element index = " << ele_index << " from [0, " << number_of_items -1 << "]" << endl;
|
|
|
+ uint64_t index = client.get_fv_index(ele_index, size_per_item);
|
|
|
+ uint64_t offset = client.get_fv_offset(ele_index, size_per_item);
|
|
|
+
|
|
|
+ cout << "Main: FV index = " << index << ", FV offset = " << offset << endl;
|
|
|
+
|
|
|
+ auto time_query_s = high_resolution_clock::now();
|
|
|
+ PirQuery query = client.generate_query(index);
|
|
|
+
|
|
|
+
|
|
|
+ uint64_t query_size = 0;
|
|
|
+ for (vector<vector<Ciphertext>>::iterator iter = query.begin(); iter != query.end(); iter++) {
|
|
|
+ uint64_t vector_size = (*iter).size();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ query_size+=(vector_size*(((*iter).front()).uint64_count())*8);
|
|
|
+ }
|
|
|
+ auto time_query_e = high_resolution_clock::now();
|
|
|
+ auto time_query_us = duration_cast<microseconds>(time_query_e - time_query_s).count();
|
|
|
+ cout << "Main: query generated" << endl;
|
|
|
+
|
|
|
+
|
|
|
+ auto time_server_s = high_resolution_clock::now();
|
|
|
+ double time_expand_us = 0;
|
|
|
+
|
|
|
+ PirReply reply = server.generate_reply(query, 0, client, &time_expand_us);
|
|
|
+ uint64_t reply_size, reply_vector_size;
|
|
|
+ vector<Ciphertext>::iterator iter=reply.begin();
|
|
|
+ reply_vector_size = reply.size();
|
|
|
+ reply_size=reply_vector_size * ((*iter).uint64_count()*8);
|
|
|
+ cout<<"reply_vector_size = "<<reply_vector_size<<", reply_size = "<< reply_size<<endl;
|
|
|
+ auto time_server_e = high_resolution_clock::now();
|
|
|
+ auto time_server_us = duration_cast<microseconds>(time_server_e - time_server_s).count();
|
|
|
+
|
|
|
+
|
|
|
+ auto time_decode_s = chrono::high_resolution_clock::now();
|
|
|
+ Plaintext result = client.decode_reply(reply);
|
|
|
+ auto time_decode_e = chrono::high_resolution_clock::now();
|
|
|
+ auto time_decode_us = duration_cast<microseconds>(time_decode_e - time_decode_s).count();
|
|
|
+
|
|
|
+
|
|
|
+ vector<uint8_t> elems(N * logt / 8);
|
|
|
+ coeffs_to_bytes(logt, result, elems.data(), (N * logt) / 8);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ for (uint32_t i = 0; i < size_per_item; i++) {
|
|
|
+ if (elems[(offset * size_per_item) + i] != check_db.get()[(ele_index * size_per_item) + i]) {
|
|
|
+ cout << "elems " << (int)elems[(offset * size_per_item) + i] << ", db "
|
|
|
+ << (int) check_db.get()[(ele_index * size_per_item) + i] << endl;
|
|
|
+ cout << "PIR result wrong!" << endl;
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ cout << "PIR reseult correct!" << endl;
|
|
|
+ cout << "_QGT_: PIRClient query generation time: " << double(time_query_us) / 1000 << " ms" << endl;
|
|
|
+ cout << "_QPT_: PIRServer query total processing time: " << double(time_server_us) / 1000 << " ms"
|
|
|
+ << endl;
|
|
|
+ cout << "_QET_: PIRServer query expansion time: " << double(time_expand_us) / 1000 << " ms"
|
|
|
+ << endl;
|
|
|
+ cout << "_RET_: PIRClient answer decode time: " << double(time_decode_us) / 1000 << " ms" << endl;
|
|
|
+
|
|
|
+ cout << "_TQS_: Total query size: "<< query_size <<" bytes"<< endl;
|
|
|
+ cout << "_TRS_: Total reply size: "<< reply_size <<" bytes"<< endl;
|
|
|
+ cout << "_PPT_: PIRServer pre-processing time: " << double(time_pre_us) / 1000 << " ms" << endl;
|
|
|
+ cout << "Reply num ciphertexts: " << reply.size() << endl;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- cout << "PIR reseult correct!" << endl;
|
|
|
- cout << "PIRServer pre-processing time: " << time_pre_us / 1000 << " ms" << endl;
|
|
|
- cout << "PIRServer reply generation time: " << time_server_us / 1000 << " ms"
|
|
|
- << endl;
|
|
|
- cout << "PIRClient query generation time: " << time_query_us / 1000 << " ms" << endl;
|
|
|
- cout << "PIRClient answer decode time: " << time_decode_us / 1000 << " ms" << endl;
|
|
|
- cout << "Reply num ciphertexts: " << reply.size() << endl;
|
|
|
-
|
|
|
return 0;
|
|
|
}
|