@@ -20,19 +20,19 @@ SecretKey *receiver_key_leaked;
20
20
#endif
21
21
22
22
void multiply_by_random_mask (Ciphertext &ciphertext,
23
- shared_ptr <UniformRandomGenerator> random,
23
+ shared_ptr<UniformRandomGenerator> random,
24
24
std::unique_ptr<seal::BatchEncoder> encoder,
25
25
std::unique_ptr<seal::Evaluator> evaluator,
26
26
RelinKeys &relin_keys,
27
27
uint64_t plain_modulus) {
28
28
size_t slot_count = encoder->slot_count ();
29
29
Plaintext mask;
30
- vector <uint64_t > mask_coefficients (slot_count, 0 ) ;
30
+ vector<uint64_t > mask_coefficients;
31
31
for (size_t j = 0 ; j < slot_count; j++) {
32
- mask_coefficients[j] = random_nonzero_integer (random , plain_modulus);
32
+ mask_coefficients. push_back ( random_nonzero_integer (random , plain_modulus) );
33
33
}
34
34
encoder->encode (mask_coefficients, mask);
35
- evaluator->multiply_plain_inplace (ciphertext, mask, {} );
35
+ evaluator->multiply_plain_inplace (ciphertext, mask);
36
36
evaluator->relinearize_inplace (ciphertext, relin_keys);
37
37
}
38
38
@@ -113,7 +113,7 @@ void PSIParams::generate_seeds() {
113
113
}
114
114
}
115
115
116
- void PSIParams::set_seeds (vector <uint64_t > &seeds_ext) {
116
+ void PSIParams::set_seeds (vector<uint64_t > &seeds_ext) {
117
117
assert (seeds_ext.size () == hash_functions ());
118
118
seeds = seeds_ext;
119
119
}
@@ -220,7 +220,7 @@ void PSIParams::set_window_size(size_t new_value) {
220
220
}
221
221
222
222
223
- uint64_t PSIParams::encode_bucket_element (vector <uint64_t > &inputs, bucket_slot &element, bool is_receiver) {
223
+ uint64_t PSIParams::encode_bucket_element (vector<uint64_t > &inputs, bucket_slot &element, bool is_receiver) {
224
224
uint64_t result;
225
225
if (element != BUCKET_EMPTY) {
226
226
// we need to encode:
@@ -255,12 +255,13 @@ receiver_key_leaked = &secret_key;
255
255
#endif
256
256
257
257
258
- vector <Ciphertext> PSIReceiver::encrypt_inputs (vector <uint64_t > &inputs, vector <bucket_slot> &buckets) {
258
+ vector<Ciphertext> PSIReceiver::encrypt_inputs (vector<uint64_t > &inputs, vector<bucket_slot> &buckets) {
259
259
assert (inputs.size () == params.receiver_size );
260
260
261
- std::unique_ptr<seal::Encryptor> encryptor=make_unique<Encryptor>(std::move (*(params.context )),std::move (public_key_));
261
+ std::unique_ptr<seal::Encryptor> encryptor = make_unique<Encryptor>(std::move (*(params.context )),
262
+ std::move (public_key_));
262
263
// Encryptor encryptor(params.context, public_key_);
263
- std::unique_ptr<seal::BatchEncoder> encoder= make_unique<BatchEncoder>(std::move (*(params.context )));
264
+ std::unique_ptr<seal::BatchEncoder> encoder = make_unique<BatchEncoder>(std::move (*(params.context )));
264
265
// BatchEncoder encoder(params.context);
265
266
266
267
auto random_factory (UniformRandomGeneratorFactory::DefaultFactory ());
@@ -271,7 +272,7 @@ vector <Ciphertext> PSIReceiver::encrypt_inputs(vector <uint64_t> &inputs, vecto
271
272
bool res = cuckoo_hash (random , inputs, bucket_count_log, buckets, params.seeds );
272
273
assert (res); // TODO: handle gracefully
273
274
274
- vector <uint64_t > buckets_enc (bucket_count);
275
+ vector<uint64_t > buckets_enc (bucket_count);
275
276
size_t partition_count = params.sender_partition_count ();
276
277
size_t max_partition_size = (params.sender_bucket_capacity () + (partition_count - 1 )) / partition_count;
277
278
Windowing windowing (params.window_size (), max_partition_size);
@@ -280,23 +281,23 @@ vector <Ciphertext> PSIReceiver::encrypt_inputs(vector <uint64_t> &inputs, vecto
280
281
buckets_enc[i] = params.encode_bucket_element (inputs, buckets[i], true );
281
282
}
282
283
283
- vector <Ciphertext> result;
284
+ vector<Ciphertext> result;
284
285
windowing.prepare (buckets_enc, result, params.plain_modulus (), std::move (encoder), std::move (encryptor));
285
286
286
287
return result;
287
288
}
288
289
289
290
290
- vector <size_t > PSIReceiver::decrypt_matches (vector <Ciphertext> &encrypted_matches) {
291
- std::unique_ptr<seal::Decryptor> decryptor= make_unique<Decryptor>(*(params.context ),secret_key);
292
- std::unique_ptr<seal::BatchEncoder> encoder= make_unique<BatchEncoder>(*(params.context ));
291
+ vector<size_t > PSIReceiver::decrypt_matches (vector<Ciphertext> &encrypted_matches) {
292
+ std::unique_ptr<seal::Decryptor> decryptor = make_unique<Decryptor>(*(params.context ), secret_key);
293
+ std::unique_ptr<seal::BatchEncoder> encoder = make_unique<BatchEncoder>(*(params.context ));
293
294
// Decryptor decryptor(params.context, secret_key);
294
295
// BatchEncoder encoder(params.context);
295
296
size_t slot_count = encoder->slot_count ();
296
297
297
298
size_t bucket_count = (1 << params.bucket_count_log ());
298
299
299
- vector <size_t > result;
300
+ vector<size_t > result;
300
301
301
302
Plaintext decrypted;
302
303
for (size_t i = 0 ; i < encrypted_matches.size (); i++) {
@@ -313,23 +314,23 @@ vector <size_t> PSIReceiver::decrypt_matches(vector <Ciphertext> &encrypted_matc
313
314
return result;
314
315
}
315
316
316
- vector <pair<size_t , uint64_t >> PSIReceiver::decrypt_labeled_matches (vector <Ciphertext> &encrypted_matches) {
317
+ vector<pair<size_t , uint64_t >> PSIReceiver::decrypt_labeled_matches (vector<Ciphertext> &encrypted_matches) {
317
318
assert (encrypted_matches.size () % 2 == 0 );
318
319
319
- // Decryptor decryptor(params.context, secret_key);
320
- // BatchEncoder encoder(params.context);
321
- std::unique_ptr<seal::Decryptor> decryptor= make_unique<Decryptor>(*(params.context ),secret_key);
322
- std::unique_ptr<seal::BatchEncoder> encoder= make_unique<BatchEncoder>(*(params.context ));
320
+ // Decryptor decryptor(params.context, secret_key);
321
+ // BatchEncoder encoder(params.context);
322
+ std::unique_ptr<seal::Decryptor> decryptor = make_unique<Decryptor>(*(params.context ), secret_key);
323
+ std::unique_ptr<seal::BatchEncoder> encoder = make_unique<BatchEncoder>(*(params.context ));
323
324
size_t slot_count = encoder->slot_count ();
324
325
325
326
size_t bucket_count = (1 << params.bucket_count_log ());
326
327
327
- vector <pair<size_t , uint64_t >> result;
328
+ vector<pair<size_t , uint64_t >> result;
328
329
329
330
Plaintext decrypted_matches, decrypted_labels;
330
331
for (size_t i = 0 ; i < encrypted_matches.size () / 2 ; i++) {
331
- vector <uint64_t > result1;
332
- vector <uint64_t > lbresult;
332
+ vector<uint64_t > result1;
333
+ vector<uint64_t > lbresult;
333
334
decryptor->decrypt (encrypted_matches[2 * i], decrypted_matches);
334
335
encoder->decode (decrypted_matches, result1);
335
336
decryptor->decrypt (encrypted_matches[2 * i + 1 ], decrypted_labels);
@@ -358,11 +359,11 @@ RelinKeys PSIReceiver::relin_keys() {
358
359
PSISender::PSISender (PSIParams ¶ms)
359
360
: params(params) {}
360
361
361
- vector <Ciphertext> PSISender::compute_matches (vector <uint64_t > &inputs,
362
- optional <vector<uint64_t >> &labels,
363
- PublicKey &receiver_public_key,
364
- RelinKeys relin_keys,
365
- vector <Ciphertext> &receiver_inputs) {
362
+ vector<Ciphertext> PSISender::compute_matches (vector<uint64_t > &inputs,
363
+ optional<vector<uint64_t >> &labels,
364
+ PublicKey &receiver_public_key,
365
+ RelinKeys relin_keys,
366
+ vector<Ciphertext> &receiver_inputs) {
366
367
assert (inputs.size () == params.sender_size );
367
368
assert (!labels.has_value () || (labels.value ().size () == inputs.size ()));
368
369
@@ -371,16 +372,16 @@ vector <Ciphertext> PSISender::compute_matches(vector <uint64_t> &inputs,
371
372
372
373
uint64_t plain_modulus = params.plain_modulus ();
373
374
374
- std::unique_ptr<seal::Encryptor> encryptor= make_unique<Encryptor>(*(params.context ),receiver_public_key);
375
- std::unique_ptr<seal::BatchEncoder> encoder= make_unique<BatchEncoder>(*(params.context ));
376
- std::unique_ptr<seal::Evaluator> evaluator= make_unique<Evaluator>(*(params.context ));
375
+ std::unique_ptr<seal::Encryptor> encryptor = make_unique<Encryptor>(*(params.context ), receiver_public_key);
376
+ std::unique_ptr<seal::BatchEncoder> encoder = make_unique<BatchEncoder>(*(params.context ));
377
+ std::unique_ptr<seal::Evaluator> evaluator = make_unique<Evaluator>(*(params.context ));
377
378
378
379
// hash all of the sender's inputs, using every possible hash function, into
379
380
// a (capacity × bucket_count) hash table.
380
381
size_t bucket_count_log = params.bucket_count_log ();
381
382
size_t bucket_count = (1 << bucket_count_log);
382
383
size_t capacity = params.sender_bucket_capacity ();
383
- vector <bucket_slot> buckets;
384
+ vector<bucket_slot> buckets;
384
385
bool res = complete_hash (random , inputs, bucket_count_log, capacity, buckets, params.seeds );
385
386
assert (res); // TODO: handle gracefully
386
387
@@ -398,20 +399,20 @@ vector <Ciphertext> PSISender::compute_matches(vector <uint64_t> &inputs,
398
399
399
400
// if we're doing labeled PSI, we need two ciphertexts per partition:
400
401
// one for f(x) and one for r*f(x) + g(x)
401
- vector <Ciphertext> result ((labels.has_value () ? 2 : 1 ) * partition_count);
402
+ vector<Ciphertext> result ((labels.has_value () ? 2 : 1 ) * partition_count);
402
403
403
404
// compute all the powers of the receiver's input.
404
- vector <Ciphertext> powers (max_partition_size + 1 );
405
+ vector<Ciphertext> powers (max_partition_size + 1 );
405
406
windowing.compute_powers (receiver_inputs, powers, std::move (evaluator), relin_keys);
406
407
407
408
// we'll need these vectors for each iteration, so let's declare them here
408
409
// to avoid reallocating them anew each time.
409
- vector <uint64_t > current_bucket (max_partition_size);
410
- vector <vector<uint64_t >> f_coeffs (bucket_count);
410
+ vector<uint64_t > current_bucket (max_partition_size);
411
+ vector<vector<uint64_t >> f_coeffs (bucket_count);
411
412
// we'll only need these if we're doing labeled PSI, so we set the sizes to
412
413
// 0 if we aren't to avoid unnecessarily wasting memory
413
- vector <uint64_t > current_labels (labels.has_value () ? max_partition_size : 0 );
414
- vector <vector<uint64_t >> g_coeffs (labels.has_value () ? bucket_count : 0 );
414
+ vector<uint64_t > current_labels (labels.has_value () ? max_partition_size : 0 );
415
+ vector<vector<uint64_t >> g_coeffs (labels.has_value () ? bucket_count : 0 );
415
416
416
417
for (size_t partition = 0 ; partition < partition_count; partition++) {
417
418
// figure out which many rows go into this partition
@@ -472,11 +473,17 @@ vector <Ciphertext> PSISender::compute_matches(vector <uint64_t> &inputs,
472
473
for (size_t j = 0 ; j < partition_size + 1 ; j++) {
473
474
// encode the jth coefficients of all polynomials into a vector
474
475
Plaintext f_coeffs_enc (bucket_count, bucket_count);
476
+ std::vector<uint64_t > temp;
475
477
for (size_t k = 0 ; k < bucket_count; k++) {
476
- f_coeffs_enc[k] = f_coeffs[k][j];
478
+ temp. push_back ( f_coeffs[k][j]) ;
477
479
}
480
+ encoder->encode (temp, f_coeffs_enc);
481
+ // for (size_t k = 0; k < bucket_count; k++) {
482
+ // encoder->encode(f_coeffs[k][j],f_coeffs_enc[k]);
483
+ // f_coeffs_enc[k] = f_coeffs[k][j];
484
+ // }
478
485
Plaintext f_coeffs_plaintext;
479
- // encoder. encode(f_coeffs_enc,f_coeffs_plaintext );
486
+ // encoder-> encode(f_coeffs_enc);
480
487
481
488
Plaintext g_coeffs_enc;
482
489
Plaintext g_coeffs_plaintext;
@@ -490,7 +497,7 @@ vector <Ciphertext> PSISender::compute_matches(vector <uint64_t> &inputs,
490
497
491
498
// encoder.encode(g_coeffs_enc, g_coeffs_plaintext);
492
499
}
493
-
500
+ std::unique_ptr<seal::Evaluator> evaluator = std::make_unique<Evaluator>(*(params. context ));
494
501
if (j == 0 ) {
495
502
// the constant term just goes straight into the result, and
496
503
// then the other terms will be added into it later.
@@ -503,14 +510,15 @@ vector <Ciphertext> PSISender::compute_matches(vector <uint64_t> &inputs,
503
510
// multiply_plain does not allow the second parameter to be zero.
504
511
if (!f_coeffs_enc.is_zero ()) {
505
512
Ciphertext term;
506
- evaluator->multiply_plain (powers[j], f_coeffs_plaintext, term);
513
+ // std::cout << powers[j].is_transparent() << std::endl;
514
+ evaluator->multiply_plain (powers[j], f_coeffs_enc, term);
507
515
evaluator->relinearize_inplace (term, relin_keys);
508
516
evaluator->add_inplace (f_evaluated, term);
509
517
}
510
518
511
519
if (!g_coeffs_enc.is_zero ()) {
512
520
Ciphertext term;
513
- evaluator->multiply_plain (powers[j], g_coeffs_plaintext , term);
521
+ evaluator->multiply_plain (powers[j], g_coeffs_enc , term);
514
522
evaluator->relinearize_inplace (term, relin_keys);
515
523
evaluator->add_inplace (g_evaluated, term);
516
524
}
@@ -524,16 +532,21 @@ vector <Ciphertext> PSISender::compute_matches(vector <uint64_t> &inputs,
524
532
// for unlabeled PSI, return r * f(x)
525
533
// for labeled PSI, return (r * f(x), r' * f(x) + g(x))
526
534
// where r and r' are random.
527
- multiply_by_random_mask (f_evaluated, random , std::move (encoder), std::move (evaluator), relin_keys, plain_modulus);
535
+ std::unique_ptr<seal::BatchEncoder> encoder = std::make_unique<BatchEncoder>(*(params.context ));
536
+ std::unique_ptr<seal::Evaluator> evaluator = std::make_unique<Evaluator>(*(params.context ));
537
+ multiply_by_random_mask (f_evaluated, random , std::move (encoder), std::move (evaluator), relin_keys,
538
+ plain_modulus);
528
539
529
540
#ifdef DEBUG_WITH_KEY_LEAK
530
541
cerr << " after mask it is " << decryptor.invariant_noise_budget (f_evaluated) << endl;
531
542
#endif
532
543
533
544
if (labels.has_value ()) {
534
545
result[2 * partition] = f_evaluated;
535
-
536
- multiply_by_random_mask (f_evaluated, random , std::move (encoder), std::move (evaluator), relin_keys, plain_modulus);
546
+ std::unique_ptr<seal::BatchEncoder> encoder = make_unique<BatchEncoder>(*(params.context ));
547
+ std::unique_ptr<seal::Evaluator> evaluator = make_unique<Evaluator>(*(params.context ));
548
+ multiply_by_random_mask (f_evaluated, random , std::move (encoder), std::move (evaluator), relin_keys,
549
+ plain_modulus);
537
550
538
551
#ifdef DEBUG_WITH_KEY_LEAK
539
552
cerr << " after second mask it is " << decryptor.invariant_noise_budget (f_evaluated) << endl;
0 commit comments