· 5 years ago · Oct 13, 2020, 08:28 AM
1void demo3()
2{
3 vector<double> inputs{0.0,1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9};
4
5
6 EncryptionParameters parms(scheme_type::CKKS);
7 size_t poly_modulus_degree = 8192;
8 parms.set_poly_modulus_degree(poly_modulus_degree);
9 parms.set_coeff_modulus(CoeffModulus::Create(poly_modulus_degree, {60, 30, 30, 30, 60}));
10 auto context = SEALContext::Create(parms);
11 double scale = pow(2.0, 30);
12 CKKSEncoder encoder(context);
13
14
15 cout << "Valid parms: " << boolalpha << context->key_context_data()->qualifiers().parameters_set() << endl;
16 cout << "Max allowed coeff_modulus bit-count for this poly_mod_deg: " << CoeffModulus::MaxBitCount(poly_modulus_degree) << endl;
17 cout << "Current coeff_modulus bit-count: " << context->key_context_data()->total_coeff_modulus_bit_count() << endl;
18 cout << "Encoder.slot_count: " << encoder.slot_count() << endl << endl;
19
20
21 KeyGenerator keygen(context);
22 auto secret_key = keygen.secret_key();
23 auto public_key = keygen.public_key();
24 auto relin_keys = keygen.relin_keys_local();
25 auto galois_keys = keygen.galois_keys_local();
26 Encryptor encryptor(context, public_key);
27 Decryptor decryptor(context, secret_key);
28
29 Plaintext p;
30 encoder.encode(inputs, scale, p);
31 Ciphertext c;
32 encryptor.encrypt(p, c);
33
34
35//SERVER SIDE
36 Evaluator evaluator(context);
37 auto c_cpy = c;
38
39 for (size_t i = 1; i < encoder.slot_count(); i <<= 1){
40 Ciphertext temp_c;
41 evaluator.rotate_vector(c, i, galois_keys, temp_c);
42 evaluator.add_inplace(c, temp_c);
43 }
44
45 auto N = inputs.size();
46 double N_inv = 1.0;
47 N_inv /= ((int)N);
48 Plaintext pN_inv;
49 encoder.encode(N_inv, scale, pN_inv);
50 Ciphertext c_avg;
51 evaluator.multiply_plain(c, pN_inv, c_avg);
52
53 evaluator.relinearize_inplace(c_avg, relin_keys);
54 evaluator.rescale_to_next_inplace(c_avg);
55 c_avg.scale() = scale;
56
57
58 c = c_cpy;
59
60 evaluator.mod_switch_to_next_inplace(c);
61 evaluator.sub_inplace(c, c_avg);
62
63 evaluator.square_inplace(c);
64 evaluator.relinearize_inplace(c, relin_keys);
65 evaluator.rescale_to_next_inplace(c);
66 c.scale() = scale;
67
68 auto temp_c = c;
69 for (size_t i = 1; i < inputs.size(); i++){
70 evaluator.rotate_vector_inplace(temp_c, 1, galois_keys);
71 evaluator.add_inplace(c, temp_c);
72 }
73
74 encoder.encode(N_inv, c.parms_id(), scale, pN_inv);
75 Ciphertext c_var;
76 evaluator.multiply_plain(c, pN_inv, c_var);
77
78
79
80
81//CLIENT SIDE
82
83 Plaintext p_avg;
84 decryptor.decrypt(c_avg, p_avg);
85 vector<double> vect;
86 encoder.decode(p_avg, vect);
87 auto avg = vect[0];
88
89 Plaintext p_var;
90 decryptor.decrypt(c_var, p_var);
91 encoder.decode(p_var, vect);
92 auto var = vect[0];
93
94
95 cout << "Average: " << avg << endl;
96 cout << "Variance: " << var << endl;
97}
98