1 /* Copyright (C) 2020 IBM Corp.
2 * This program is Licensed under the Apache License, Version 2.0
3 * (the "License"); you may not use this file except in compliance
4 * with the License. You may obtain a copy of the License at
5 * http://www.apache.org/licenses/LICENSE-2.0
6 * Unless required by applicable law or agreed to in writing, software
7 * distributed under the License is distributed on an "AS IS" BASIS,
8 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9 * See the License for the specific language governing permissions and
10 * limitations under the License. See accompanying LICENSE file.
11 */
12
13 #ifndef COMMON_H
14 #define COMMON_H
15
16 #include <iostream>
17 #include <fstream>
18
19 #include <helib/helib.h>
20
stripExtension(const std::string & s)21 std::string stripExtension(const std::string& s)
22 {
23 std::size_t dotPos = s.find_last_of(".");
24 return (dotPos == std::string::npos) ? s : s.substr(0, dotPos);
25 }
26
readline(std::istream & is)27 std::string readline(std::istream& is)
28 {
29 std::string s;
30 getline(is, s);
31 return s;
32 }
33
readKeyBinary(std::istream & keyFile,helib::PubKey & pk)34 void readKeyBinary(std::istream& keyFile, helib::PubKey& pk)
35 {
36 helib::readPubKeyBinary(keyFile, pk);
37 }
38
readKeyBinary(std::istream & keyFile,helib::SecKey & sk)39 void readKeyBinary(std::istream& keyFile, helib::SecKey& sk)
40 {
41 helib::readSecKeyBinary(keyFile, sk);
42 }
43
44 template <typename T1, typename T2>
45 using uniq_pair = std::pair<std::unique_ptr<T1>, std::unique_ptr<T2>>;
46
47 template <typename KEY>
loadContextAndKey(const std::string & keyFilePath)48 uniq_pair<helib::Context, KEY> loadContextAndKey(const std::string& keyFilePath)
49 {
50 std::ifstream keyFile(keyFilePath, std::ios::binary);
51 if (!keyFile.is_open())
52 throw std::runtime_error("Cannot open Public Key file '" + keyFilePath +
53 "'.");
54
55 unsigned long m, p, r;
56 std::vector<long> gens, ords;
57
58 helib::readContextBaseBinary(keyFile, m, p, r, gens, ords);
59 std::unique_ptr<helib::Context> contextp =
60 std::make_unique<helib::Context>(m, p, r, gens, ords);
61 helib::readContextBinary(keyFile, *contextp);
62
63 std::unique_ptr<KEY> keyp = std::make_unique<KEY>(*contextp);
64 readKeyBinary(keyFile, *keyp);
65
66 return {std::move(contextp), std::move(keyp)};
67 }
68
estimateCtxtSize(const helib::Context & context,long offset)69 inline long estimateCtxtSize(const helib::Context& context, long offset)
70 {
71 // Return in bytes.
72
73 // We assume that the size of each element in the DCRT is BINIO_64BIT
74
75 // sizeof(BINIO_EYE_CTXT_BEGIN) = 4;
76 // BINIO_32BIT = 4
77 // sizeof(long) = BINIO_64BIT = 8
78 // xdouble = s * sizeof(long) = 2 * BINIO_64BIT = 16
79
80 // We assume that primeSet after encryption is context.ctxtPrimes
81 // We assume we have exactly 2 parts after encryption
82 // We assume that the DCRT prime set is the same as the ctxt one
83
84 long size = 0;
85
86 size += 4;
87
88 // Begin Ctxt metadata
89 // 64 = header_size = ptxtSpace (long) + intFactor (long) + ptxtMag (xdouble)
90 // + ratFactor (xdouble) + noiseBound (xdouble)
91 size += 64;
92
93 // primeSet.write(str);
94 // size of set (long) + each prime (long)
95 size += 8 + context.ctxtPrimes.card() * 8;
96
97 // Begin Ctxt content size
98 // write_raw_vector(str, parts);
99 // Size of the parts vector (long)
100 size += 8;
101
102 long part_size = 0;
103 // Begin CtxtPart size
104
105 // skHandle.write(str);
106 // powerOfS (long) + powerOfX (long) + secretKeyID (long)
107 part_size += 24;
108
109 // Begin DCRT size computation
110
111 // this->DoubleCRT::write(str);
112 // map.getIndexSet().write(str);
113 // size of set (long) + each prime (long)
114 part_size += 8 + context.ctxtPrimes.card() * 8;
115
116 // DCRT data write as write_ntl_vec_long(str, map[i]);
117 // For each prime in the ctxt modulus chain
118 // size of DCRT column (long) + size of each element (long) +
119 // size of all the slots (column in DCRT) (PhiM long elements)
120 long dcrt_size =
121 (8 + 8 * context.zMStar.getPhiM()) * context.ctxtPrimes.card();
122
123 part_size += dcrt_size;
124
125 // End DCRT size
126 // End CtxtPart size
127
128 size += 2 * part_size; // 2 * because we assumed 2 parts
129 // End Ctxt content size
130
131 // End eye-catcher
132 size += 4;
133
134 return size + offset;
135 }
136
137 #endif // COMMON_H
138