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