1 // @file binfhecontext.h - Header file for BinFHEContext class, which is used
2 // for Boolean circuit FHE schemes
3 //
4 // @author TPOC: contact@palisade-crypto.org
5 // @copyright Copyright (c) 2019, Duality Technologies Inc.
6 // All rights reserved.
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 // 1. Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution. THIS SOFTWARE IS
14 // PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
15 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 
25 #ifndef BINFHE_BINFHECONTEXT_H
26 #define BINFHE_BINFHECONTEXT_H
27 
28 #include <memory>
29 #include <string>
30 
31 #include "fhew.h"
32 #include "lwe.h"
33 #include "ringcore.h"
34 #include "utils/serializable.h"
35 
36 namespace lbcrypto {
37 
38 // security levels for predefined parameter sets
39 enum BINFHEPARAMSET {
40   TOY,        // no security
41   MEDIUM,     // 108 bits of security for classical and 100 bits for quantum
42   STD128,     // more than 128 bits of security for classical
43               // computer attacks - uses the same setup as HE standard
44   STD128_AP,  // Optimized for AP (has higher failure probability for GINX) -
45               // more than 128 bits of security for classical computer attacks -
46               // uses the same setup as HE standard
47   STD192,     // more than 192 bits of security for classical computer attacks -
48               // uses the same setup as HE standard
49   STD256,     // more than 256 bits of security for classical computer attacks -
50               // uses the same setup as HE standard
51   STD128Q,    // more than 128 bits of security for quantum attacks - uses the
52               // same setup as HE standard
53   STD192Q,    // more than 192 bits of security for quantum attacks - uses the
54               // same setup as HE standard
55   STD256Q,    // more than 256 bits of security for quantum attacks - uses the
56               // same setup as HE standard
57   SIGNED_MOD_TEST  // special parameter set for confirming the signed modular
58                    // reduction in the accumulator updates works correctly
59 };
60 
61 // Type of ciphertext generated by the Encrypt method
62 enum BINFHEOUTPUT {
63   FRESH,        // a fresh encryption
64   BOOTSTRAPPED  // a freshly encrypted ciphertext is bootstrapped
65 };
66 
67 class LWECiphertextImpl;
68 
69 using LWECiphertext = std::shared_ptr<LWECiphertextImpl>;
70 
71 using ConstLWECiphertext = const std::shared_ptr<const LWECiphertextImpl>;
72 
73 class LWEPrivateKeyImpl;
74 
75 using LWEPrivateKey = std::shared_ptr<LWEPrivateKeyImpl>;
76 
77 using ConstLWEPrivateKey = const std::shared_ptr<const LWEPrivateKeyImpl>;
78 
79 /**
80  * @brief BinFHEContext
81  *
82  * The wrapper class for Boolean circuit FHE
83  */
84 class BinFHEContext : public Serializable {
85  public:
BinFHEContext()86   BinFHEContext() {}
87 
88   /**
89    * Creates a crypto context using custom parameters.
90    * Should be used with care (only for advanced users familiar with LWE
91    * parameter selection).
92    *
93    * @param n lattice parameter for additive LWE scheme
94    * @param N ring dimension for RingGSW/RLWE used in bootstrapping
95    * @param &q modulus for additive LWE
96    * @param &Q modulus for RingGSW/RLWE used in bootstrapping
97    * @param std standard deviation
98    * @param baseKS the base used for key switching
99    * @param baseG the gadget base used in bootstrapping
100    * @param baseR the base used for refreshing
101    * @param method the bootstrapping method (AP or GINX)
102    * @return creates the cryptocontext
103    */
104   void GenerateBinFHEContext(uint32_t n, uint32_t N, const NativeInteger &q,
105                              const NativeInteger &Q, double std,
106                              uint32_t baseKS, uint32_t baseG, uint32_t baseR,
107                              BINFHEMETHOD method = GINX);
108 
109   /**
110    * Creates a crypto context using predefined parameters sets. Recommended for
111    * most users.
112    *
113    * @param set the parameter set: TOY, MEDIUM, STD128, STD192, STD256
114    * @param method the bootstrapping method (AP or GINX)
115    * @return create the cryptocontext
116    */
117   void GenerateBinFHEContext(BINFHEPARAMSET set, BINFHEMETHOD method = GINX);
118 
119   /**
120    * Gets the refreshing key (used for serialization).
121    *
122    * @return a shared pointer to the refreshing key
123    */
GetRefreshKey()124   const std::shared_ptr<RingGSWBTKey> GetRefreshKey() const {
125     return m_BTKey.BSkey;
126   }
127 
128   /**
129    * Gets the switching key (used for serialization).
130    *
131    * @return a shared pointer to the switching key
132    */
GetSwitchKey()133   const std::shared_ptr<LWESwitchingKey> GetSwitchKey() const {
134     return m_BTKey.KSkey;
135   }
136 
137   /**
138    * Generates a secret key for the main LWE scheme
139    *
140    * @return a shared pointer to the secret key
141    */
142   LWEPrivateKey KeyGen() const;
143 
144   /**
145    * Generates a secret key used in bootstrapping
146    * @return a shared pointer to the secret key
147    */
148   LWEPrivateKey KeyGenN() const;
149 
150   /**
151    * Encrypts a bit using a secret key (symmetric key encryption)
152    *
153    * @param sk - the secret key
154    * @param &m - the plaintext
155    * @param output - FRESH to generate fresh ciphertext, BOOTSTRAPPED to
156    * generate a refreshed ciphertext (default)
157    * @return a shared pointer to the ciphertext
158    */
159   LWECiphertext Encrypt(ConstLWEPrivateKey sk, const LWEPlaintext &m,
160                         BINFHEOUTPUT output = BOOTSTRAPPED) const;
161 
162   /**
163    * Decrypts a ciphertext using a secret key
164    *
165    * @param sk the secret key
166    * @param ct the ciphertext
167    * @param *result plaintext result
168    */
169   void Decrypt(ConstLWEPrivateKey sk, ConstLWECiphertext ct,
170                LWEPlaintext *result) const;
171 
172   /**
173    * Generates a switching key to go from a secret key with (Q,N) to a secret
174    * key with (q,n)
175    *
176    * @param sk new secret key
177    * @param skN old secret key
178    * @return a shared pointer to the switching key
179    */
180   std::shared_ptr<LWESwitchingKey> KeySwitchGen(ConstLWEPrivateKey sk,
181                                                 ConstLWEPrivateKey skN) const;
182 
183   /**
184    * Generates boostrapping keys
185    *
186    * @param sk secret key
187    */
188   void BTKeyGen(ConstLWEPrivateKey sk);
189 
190   /**
191    * Loads bootstrapping keys in the context (typically after deserializing)
192    *
193    * @param key struct with the bootstrapping keys
194    */
BTKeyLoad(const RingGSWEvalKey & key)195   void BTKeyLoad(const RingGSWEvalKey &key) { m_BTKey = key; }
196 
197   /**
198    * Clear the bootstrapping keys in the current context
199    */
ClearBTKeys()200   void ClearBTKeys() {
201     m_BTKey.BSkey.reset();
202     m_BTKey.KSkey.reset();
203   }
204 
205   /**
206    * Evaluates a binary gate (calls bootstrapping as a subroutine)
207    *
208    * @param gate the gate; can be AND, OR, NAND, NOR, XOR, or XNOR
209    * @param ct1 first ciphertext
210    * @param ct2 second ciphertext
211    * @return a shared pointer to the resulting ciphertext
212    */
213   LWECiphertext EvalBinGate(const BINGATE gate, ConstLWECiphertext ct1,
214                             ConstLWECiphertext ct2) const;
215 
216   /**
217    * Bootstraps a ciphertext (without peforming any operation)
218    *
219    * @param ct1 ciphertext to be bootstrapped
220    * @return a shared pointer to the resulting ciphertext
221    */
222   LWECiphertext Bootstrap(ConstLWECiphertext ct1) const;
223 
224   /**
225    * Evaluates NOT gate
226    *
227    * @param ct1 the input ciphertext
228    * @return a shared pointer to the resulting ciphertext
229    */
230   LWECiphertext EvalNOT(ConstLWECiphertext ct1) const;
231 
232   /**
233    * Evaluates constant gate
234    *
235    * @param value the Boolean value to output
236    * @return a shared pointer to the resulting ciphertext
237    */
238   LWECiphertext EvalConstant(bool value) const;
239 
GetParams()240   const std::shared_ptr<RingGSWCryptoParams> GetParams() { return m_params; }
241 
GetLWEScheme()242   const std::shared_ptr<LWEEncryptionScheme> GetLWEScheme() {
243     return m_LWEscheme;
244   }
245 
GetRingGSWScheme()246   const std::shared_ptr<RingGSWAccumulatorScheme> GetRingGSWScheme() {
247     return m_RingGSWscheme;
248   }
249 
250   template <class Archive>
save(Archive & ar,std::uint32_t const version)251   void save(Archive &ar, std::uint32_t const version) const {
252     ar(::cereal::make_nvp("params", m_params));
253   }
254 
255   template <class Archive>
load(Archive & ar,std::uint32_t const version)256   void load(Archive &ar, std::uint32_t const version) {
257     if (version > SerializedVersion()) {
258       PALISADE_THROW(deserialize_error,
259                      "serialized object version " + std::to_string(version) +
260                          " is from a later version of the library");
261     }
262     ar(::cereal::make_nvp("params", m_params));
263   }
264 
SerializedObjectName()265   std::string SerializedObjectName() const { return "RingGSWBTKey"; }
SerializedVersion()266   static uint32_t SerializedVersion() { return 1; }
267 
268  private:
269   // Shared pointer to Ring GSW + LWE parameters
270   std::shared_ptr<RingGSWCryptoParams> m_params;
271 
272   // Shared pointer to the underlying additive LWE scheme
273   std::shared_ptr<LWEEncryptionScheme> m_LWEscheme;
274 
275   // Shared pointer to the underlying RingGSW/RLWE scheme
276   std::shared_ptr<RingGSWAccumulatorScheme> m_RingGSWscheme;
277 
278   // Struct containing the bootstrapping keys
279   RingGSWEvalKey m_BTKey;
280 };
281 
282 }  // namespace lbcrypto
283 
284 #endif
285