@@ -14,6 +14,10 @@ SEALPIR can be executed for keyword-based queries through network communication
14
14
#include " seal/seal.h"
15
15
#include " seal/util/polyarithsmallmod.h"
16
16
#include " ../../netio/stream_channel.hpp"
17
+ #include " ../../crypto/bigint.hpp"
18
+ #include " ../../crypto/hash.hpp"
19
+ #include " ../../include/global.hpp"
20
+
17
21
#include " pir.hpp"
18
22
#include " pir_client.hpp"
19
23
#include " pir_server.hpp"
@@ -35,55 +39,63 @@ namespace SEALPIRKEYWORD {
35
39
/*
36
40
* add keyword query
37
41
* use a vector to save mapping of indexs and keywords
38
-
39
42
* */
40
43
/* First clinet need to read file for KeyWord*/
41
44
std::ifstream fin;
42
- std::vector<block> index_data ;
45
+ std::vector<std::string> keyword ;
43
46
fin.open (" A_PIR_ID.txt" , std::ios::binary);
44
47
if (!fin) {
45
48
std::cout << " Failed to open file" << std::endl;
46
49
std::exit (-1 );
47
50
}
48
51
std::string line;
49
52
int i = 0 ;
50
- while (std::getline (fin, line)) {
51
- index_data.push_back (Block::MakeBlock (0LL , std::stoull (line)));
53
+ while (std::getline (fin, line, ' \n ' )) {
54
+ if (!line.empty () && line[line.size () - 1 ] == ' \r ' )
55
+ line.erase (line.size () - 1 );
56
+ keyword.push_back (line);
52
57
}
53
58
fin.close ();
54
- /* Second client receive file for Server for mapping of indexs and keywords */
59
+ /* Second client receive file for Server for mapping of indexs and hash( keywords) */
55
60
block a;
56
61
/* Recive file size */
57
62
io.ReceiveBlock (a);
58
63
int server_file_len = Block::BlockToInt64 (a);
59
64
/* Receive file*/
60
- std::vector<block> index_num;
65
+ std::vector<block> index_num (server_file_len) ;
61
66
62
67
std::cout << " Start receive file data" << std::endl;
68
+ // io.ReceiveBlocks(index_num.data(),server_file_len);
69
+
70
+ #pragma omp parallel for num_threads(thread_count)
63
71
for (int i = 0 ; i < server_file_len; i++) {
64
72
io.ReceiveBlock (a);
65
- index_num. push_back (a) ;
73
+ index_num[i] = a ;
66
74
}
67
75
std::cout << " receive file finish" << std::endl;
68
- // use map to save mapping indexs of keywords in order to achieve fast finding
76
+ // use map to save mapping indexs of hash( keywords) in order to achieve fast finding
69
77
// construct map
70
78
std::map<std::uint64_t , std::uint64_t > m;
71
79
// data insert map
72
- for (auto a: index_num) {
73
- std::uint64_t index = Block::BlockToUint64High (a);
74
- std::uint64_t keyword = Block::BlockToInt64 (a);
80
+ // #pragma omp parallel for num_threads(thread_count)
81
+ for (int i = 0 ; i < index_num.size (); i++) {
82
+ std::uint64_t index = Block::BlockToUint64High (index_num[i]);
83
+ std::uint64_t keyword = Block::BlockToInt64 (index_num[i]);
75
84
m[keyword] = index ;
76
85
}
77
- // find index by keyword and save data to block
78
- for (int i = 0 ; i < index_data.size (); i++) {
86
+
87
+ std::vector<std::uint64_t > keyword_index (keyword.size ());
88
+ // #pragma omp parallel for num_threads(thread_count)
89
+ for (int i = 0 ; i < keyword.size (); i++) {
90
+ auto a = Hash::StringToBlock (keyword[i]);
91
+ auto s = Block::BlockToInt64 (a);
79
92
std::map<std::uint64_t , std::uint64_t >::iterator it = m.find (
80
- Block::BlockToInt64 (index_data[i]) ); // 在 std::map 容器中查找 key 对应的 value
93
+ s ); // 在 std::map 容器中查找 key 对应的 value
81
94
if (it != m.end ()) {
82
- block temp = Block::MakeBlock (it->second , Block::BlockToInt64 (index_data[i]));
83
- index_data[i] = temp;
84
-
95
+ keyword_index[i] = (it->second );
85
96
}
86
97
}
98
+ std::cout << " keyword_inde size= " << keyword_index.size () << std::endl;
87
99
auto start_time = std::chrono::steady_clock::now ();
88
100
/* The preprocessing of the files has been completed */
89
101
cout << " Main: Generating galois keys for client" << endl;
@@ -103,15 +115,19 @@ namespace SEALPIRKEYWORD {
103
115
* it means the query is finished and the network communication is disconnected*/
104
116
std::string isend = " 1" ;
105
117
io.SendString (isend);
106
- for ( int i = 0 ; i < index_data. size (); i++) {
118
+ int query_toltal_size = 0 ;
107
119
120
+ for (int i = 0 ; i < keyword_index.size (); i++) {
108
121
/* Generate query*/
109
- uint64_t ele_index = Block::BlockToUint64High (index_data[i]);
122
+ // uint64_t ele_index = Block::BlockToUint64High(index_data[i]);
123
+ uint64_t ele_index = keyword_index[i];
110
124
uint64_t index = client.get_fv_index (ele_index); // index of FV plaintext
111
125
uint64_t offset = client.get_fv_offset (ele_index); // offset in FV plaintext
126
+
112
127
/* Serialization query sending by network*/
113
128
stringstream client_stream;
114
129
int query_size = client.generate_serialized_query (index , client_stream);
130
+ query_toltal_size += query_size;
115
131
/* First send query size to server*/
116
132
io.SendBlock (Block::MakeBlock (0LL , query_size));
117
133
std::cout << " query_size" << query_size << std::endl;
@@ -130,7 +146,7 @@ namespace SEALPIRKEYWORD {
130
146
PirReply reply = client.deserialize_reply (sreply, context);
131
147
vector<uint8_t > elems = client.decode_reply (reply, offset);
132
148
ans.push_back (elems);
133
- if (i != index_data .size () - 1 )
149
+ if (i != keyword_index .size () - 1 )
134
150
isend = " 1" ;
135
151
else isend = " 0" ;
136
152
io.SendString (isend);
@@ -141,9 +157,10 @@ namespace SEALPIRKEYWORD {
141
157
auto running_time = end_time - start_time;
142
158
std::cout << " SealPIR:Client side takes time = "
143
159
<< std::chrono::duration<double , std::milli>(running_time).count () << " ms" << std::endl;
144
-
160
+ std::cout << " SealPIR:Client Query size= ["
161
+ << (double ) (query_toltal_size) / (1024 * 1024 ) << " MB]" << std::endl;
145
162
return ans;
146
- }
163
+ } // client
147
164
148
165
void Server (NetIO &io, PirParams params, const EncryptionParameters &enc_params, std::string filename) {
149
166
/* , unique_ptr<uint8_t[]> &db1*/
@@ -174,19 +191,27 @@ namespace SEALPIRKEYWORD {
174
191
175
192
}
176
193
fin.close ();
177
- /* save index and keyword to block */
178
- std::vector<block> index ;
179
- for (int i = 0 ; i < file_data.size (); i++) {
180
- block a = Block::MakeBlock (std::stoull (file_data[i][0 ]), std::stoull (file_data[i][1 ]));
181
- index .push_back (a);
194
+ /*
195
+ * mapping keyword-> hash(keyword)
196
+ * block=(index,hash(keyword)
197
+ * */
198
+ std::vector<block> hash_index (file_data.size ());
199
+ #pragma omp parallel for num_threads(thread_count)
200
+ for (auto i = 0 ; i < file_data.size (); i++) {
201
+ auto s = Hash::StringToBlock (file_data[i][1 ]);
202
+ block a = Block::MakeBlock (std::stoull (file_data[i][0 ]), Block::BlockToInt64 (s));
203
+ hash_index[i] = a;
182
204
}
205
+
183
206
std::cout << " Send file size" << std::endl;
184
- io.SendBlock (Block::MakeBlock (0LL , index .size ()));
207
+ io.SendBlock (Block::MakeBlock (0LL , hash_index .size ()));
185
208
std::cout << " The file length has been sent successfully" << std::endl;
186
209
std::cout << " start send file data" << std::endl;
187
- for (auto a: index ) {
188
- io.SendBlock (a);
210
+ #pragma omp parallel for num_threads(thread_count)
211
+ for (auto i = 0 ; i < hash_index.size (); i++) {
212
+ io.SendBlock (hash_index[i]);
189
213
}
214
+
190
215
std::cout << " file data send successfully" << std::endl;
191
216
auto start_time = std::chrono::steady_clock::now ();
192
217
block c;
@@ -198,6 +223,7 @@ namespace SEALPIRKEYWORD {
198
223
server.set_galois_key (0 , *galois_keys1);
199
224
/* Before generating the database file, it is necessary to remove the special
200
225
* symbol '-' from the second column of the raw data*/
226
+ // #pragma omp parallel for num_threads(thread_count)
201
227
for (int i = 0 ; i < file_data.size (); i++) {
202
228
std::string temp = file_data[i][2 ];
203
229
temp.erase (std::remove (temp.begin (), temp.end (), ' -' ), temp.end ());
@@ -220,26 +246,22 @@ namespace SEALPIRKEYWORD {
220
246
221
247
std::string isend (1 , ' 0' );
222
248
io.ReceiveString (isend);
249
+ int reply_toltal_size = 0 ;
223
250
while (isend == " 1" ) {
224
-
225
251
block a;
226
252
io.ReceiveBlock (a);
227
253
int query_size = Block::BlockToInt64 (a);
228
254
std::cout << " rec_query_size " << query_size << std::endl;
229
-
230
255
std::string query (query_size, ' 0' );
231
256
io.ReceiveString (query);
232
257
std::stringstream server_stream;
233
258
std::stringstream server_stream1 (query);
234
259
PirQuery query2 = server.deserialize_query (server_stream1);
235
-
236
260
PirReply reply = server.generate_reply (query2, 0 );
237
-
238
261
int reply_size = server.serialize_reply (reply, server_stream);
239
-
262
+ reply_toltal_size += reply_size;
240
263
io.SendBlock (Block::MakeBlock (0LL , reply_size));
241
264
std::string str1 = server_stream.str ();
242
-
243
265
io.SendString (str1);
244
266
io.ReceiveString (isend);
245
267
// if (isend == "0") return;
@@ -248,11 +270,10 @@ namespace SEALPIRKEYWORD {
248
270
auto running_time = end_time - start_time;
249
271
std::cout << " SealPIR:Server side takes time = "
250
272
<< std::chrono::duration<double , std::milli>(running_time).count () << " ms" << std::endl;
251
-
252
- }
253
-
254
-
255
- }
273
+ std::cout << " SealPIR:Server Reply size= ["
274
+ << (double ) (reply_toltal_size) / (1024 * 1024 ) << " MB]" << std::endl;
275
+ }// server
276
+ }// namespace
256
277
257
278
258
279
#endif
0 commit comments