1 // @file bfv.h -- Operations for the BFV cryptoscheme. 2 // @author TPOC: contact@palisade-crypto.org 3 // 4 // @copyright Copyright (c) 2019, New Jersey Institute of Technology (NJIT) 5 // All rights reserved. 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions are met: 8 // 1. Redistributions of source code must retain the above copyright notice, 9 // this list of conditions and the following disclaimer. 10 // 2. Redistributions in binary form must reproduce the above copyright notice, 11 // this list of conditions and the following disclaimer in the documentation 12 // and/or other materials provided with the distribution. THIS SOFTWARE IS 13 // PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 14 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 15 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 16 // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 17 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 24 /* 25 * 26 * This code implements the Brakerski-Fan-Vercauteren (BFV) homomorphic 27 * encryption scheme. This scheme is also referred to as the FV scheme. The BFV 28 * scheme is introduced here: 29 * - Junfeng Fan and Frederik Vercauteren. Somewhat Practical Fully 30 * Homomorphic Encryption. Cryptology ePrint Archive, Report 2012/144. 31 * (https://eprint.iacr.org/2012/144.pdf) 32 * 33 * Our implementation builds from the designs here: 34 * - Lepoint T., Naehrig M. (2014) A Comparison of the Homomorphic Encryption 35 * Schemes FV and YASHE. In: Pointcheval D., Vergnaud D. (eds) Progress in 36 * Cryptology – AFRICACRYPT 2014. AFRICACRYPT 2014. Lecture Notes in Computer 37 * Science, vol 8469. Springer, Cham. (https://eprint.iacr.org/2014/062.pdf) 38 * 39 */ 40 41 #ifndef LBCRYPTO_CRYPTO_BFV_H 42 #define LBCRYPTO_CRYPTO_BFV_H 43 44 #include <map> 45 #include <memory> 46 #include <string> 47 #include <vector> 48 49 #include "palisade.h" 50 #include "utils/caller_info.h" 51 52 namespace lbcrypto { 53 54 /** 55 * @brief This is the parameters class for the BFV encryption scheme. This 56 * scheme is also referred to as the FV scheme. 57 * 58 * The BFV scheme parameter guidelines are introduced here: 59 * - Junfeng Fan and Frederik Vercauteren. Somewhat Practical Fully 60 * Homomorphic Encryption. Cryptology ePrint Archive, Report 2012/144. 61 * (https://eprint.iacr.org/2012/144.pdf) 62 * 63 * We used the optimized parameter selection from the designs here: 64 * - Lepoint T., Naehrig M. (2014) A Comparison of the Homomorphic Encryption 65 * Schemes FV and YASHE. In: Pointcheval D., Vergnaud D. (eds) Progress in 66 * Cryptology – AFRICACRYPT 2014. AFRICACRYPT 2014. Lecture Notes in Computer 67 * Science, vol 8469. Springer, Cham. (https://eprint.iacr.org/2014/062.pdf) 68 * 69 * @tparam Element a ring element type. 70 */ 71 template <class Element> 72 class LPCryptoParametersBFV : public LPCryptoParametersRLWE<Element> { 73 using IntType = typename Element::Integer; 74 using ParmType = typename Element::Params; 75 76 public: 77 /** 78 * Default constructor. 79 */ 80 LPCryptoParametersBFV(); 81 82 /** 83 * Copy constructor. 84 * @param rhs - source 85 */ 86 LPCryptoParametersBFV(const LPCryptoParametersBFV &rhs); 87 88 /** 89 * Constructor that initializes values. Note that it is possible to set 90 * parameters in a way that is overall infeasible for actual use. There are 91 * fewer degrees of freedom than parameters provided. Typically one chooses 92 * the basic noise, assurance and security parameters as the typical 93 * community-accepted values, then chooses the plaintext modulus and depth as 94 * needed. The element parameters should then be choosen to provide 95 * correctness and security. In some cases we would need to operate over 96 * already encrypted/provided ciphertext and the depth needs to be 97 * pre-computed for initial settings. 98 * 99 * @param ¶ms Element parameters. This will depend on the specific class 100 * of element being used. 101 * @param &plaintextModulus Plaintext modulus, typically denoted as p in most 102 * publications. 103 * @param distributionParameter Noise distribution parameter, typically 104 * denoted as /sigma in most publications. Community standards typically call 105 * for a value of 3 to 6. Lower values provide more room for computation while 106 * larger values provide more security. 107 * @param assuranceMeasure Assurance level, typically denoted as w in most 108 * applications. This is oftern perceived as a fudge factor in the 109 * literature, with a typical value of 9. 110 * @param securityLevel Security level as Root Hermite Factor. We use the 111 * Root Hermite Factor representation of the security level to better conform 112 * with US ITAR and EAR export regulations. This is typically represented as 113 * /delta in the literature. Typically a Root Hermite Factor of 1.006 or less 114 * provides reasonable security for RLWE crypto schemes. 115 * @param relinWindow The size of the relinearization window. This is 116 * relevant when using this scheme for proxy re-encryption, and the value is 117 * denoted as r in the literature. 118 * @param delta BFV-specific factor that is multiplied by the plaintext 119 * polynomial. 120 * @param mode mode for secret polynomial, defaults to RLWE. 121 * @param bigModulus modulus used in polynomial multiplications in EvalMult 122 * @param bigRootOfUnity root of unity for bigModulus 123 * @param bigModulusArb modulus used in polynomial multiplications in EvalMult 124 * (for arbitrary cyclotomics) 125 * @param bigRootOfUnityArb root of unity for bigModulus (for arbitrary 126 * cyclotomics) 127 * @param depth is the depth of computation circuit supported for these 128 * parameters (not used now; for future use). 129 * @param maxDepth the maximum power of secret key for which the 130 * relinearization key is generated 131 */ 132 LPCryptoParametersBFV(shared_ptr<ParmType> params, 133 const PlaintextModulus &plaintextModulus, 134 float distributionParameter, float assuranceMeasure, 135 float securityLevel, usint relinWindow, 136 const IntType &delta = IntType(0), MODE mode = RLWE, 137 const IntType &bigModulus = IntType(0), 138 const IntType &bigRootOfUnity = IntType(0), 139 const IntType &bigModulusArb = IntType(0), 140 const IntType &bigRootOfUnityArb = IntType(0), 141 int depth = 1, int maxDepth = 2); 142 143 /** 144 * Constructor that initializes values. 145 * 146 * @param ¶ms element parameters. 147 * @param &encodingParams plaintext space parameters. 148 * @param distributionParameter noise distribution parameter. 149 * @param assuranceMeasure assurance level. = BigInteger::ZERO 150 * @param securityLevel security level (root Hermite factor). 151 * @param relinWindow the size of the relinearization window. 152 * @param delta BFV-specific factor that is multiplied by the plaintext 153 * polynomial. 154 * @param mode mode for secret polynomial, defaults to RLWE. 155 * @param bigModulus modulus used in polynomial multiplications in EvalMult 156 * @param bigRootOfUnity root of unity for bigModulus 157 * @param bigModulusArb modulus used in polynomial multiplications in EvalMult 158 * (arbitrary cyclotomics) 159 * @param bigRootOfUnityArb root of unity for bigModulus (arbitrary 160 * cyclotomics) 161 * @param depth is the depth of computation circuit supported for these 162 * parameters (not used now; for future use). 163 * @param maxDepth the maximum power of secret key for which the 164 * relinearization key is generated 165 */ 166 LPCryptoParametersBFV(shared_ptr<ParmType> params, 167 EncodingParams encodingParams, 168 float distributionParameter, float assuranceMeasure, 169 float securityLevel, usint relinWindow, 170 const IntType &delta = IntType(0), MODE mode = RLWE, 171 const IntType &bigModulus = IntType(0), 172 const IntType &bigRootOfUnity = IntType(0), 173 const IntType &bigModulusArb = IntType(0), 174 const IntType &bigRootOfUnityArb = IntType(0), 175 int depth = 1, int maxDepth = 2); 176 177 /** 178 * Constructor that initializes values. 179 * 180 * @param ¶ms element parameters. 181 * @param &encodingParams plaintext space parameters. 182 * @param distributionParameter noise distribution parameter. 183 * @param assuranceMeasure assurance level. = BigInteger::ZERO 184 * @param securityLevel standard security level. 185 * @param relinWindow the size of the relinearization window. 186 * @param delta BFV-specific factor that is multiplied by the plaintext 187 * polynomial. 188 * @param mode mode for secret polynomial, defaults to RLWE. 189 * @param bigModulus modulus used in polynomial multiplications in EvalMult 190 * @param bigRootOfUnity root of unity for bigModulus 191 * @param bigModulusArb modulus used in polynomial multiplications in EvalMult 192 * (arbitrary cyclotomics) 193 * @param bigRootOfUnityArb root of unity for bigModulus (arbitrary 194 * cyclotomics) 195 * @param depth is the depth of computation circuit supported for these 196 * parameters (not used now; for future use). 197 * @param maxDepth the maximum power of secret key for which the 198 * relinearization key is generated 199 */ 200 LPCryptoParametersBFV(shared_ptr<ParmType> params, 201 EncodingParams encodingParams, 202 float distributionParameter, float assuranceMeasure, 203 SecurityLevel securityLevel, usint relinWindow, 204 const IntType &delta = IntType(0), MODE mode = RLWE, 205 const IntType &bigModulus = IntType(0), 206 const IntType &bigRootOfUnity = IntType(0), 207 const IntType &bigModulusArb = IntType(0), 208 const IntType &bigRootOfUnityArb = IntType(0), 209 int depth = 1, int maxDepth = 2); 210 211 /** 212 * Destructor 213 */ 214 virtual ~LPCryptoParametersBFV() {} 215 216 /** 217 * Gets the value of the delta factor. 218 * 219 * @return the delta factor. It is an BFV-specific factor that is multiplied 220 * by the plaintext polynomial. 221 */ 222 const IntType &GetDelta() const { return m_delta; } 223 224 /** 225 * Gets the modulus used for polynomial multiplications in EvalMult 226 * 227 * @return the modulus value. 228 */ 229 const IntType &GetBigModulus() const { return m_bigModulus; } 230 231 /** 232 * Gets the primitive root of unity used for polynomial multiplications in 233 * EvalMult 234 * 235 * @return the primitive root of unity value. 236 */ 237 const IntType &GetBigRootOfUnity() const { return m_bigRootOfUnity; } 238 239 /** 240 * Gets the modulus used for polynomial multiplications in EvalMult (arbitrary 241 * cyclotomics) 242 * 243 * @return the modulus value. 244 */ 245 const IntType &GetBigModulusArb() const { return m_bigModulusArb; } 246 247 /** 248 * Gets the primitive root of unity used for polynomial multiplications in 249 * EvalMult (arbitrary cyclotomics) 250 * 251 * @return the primitive root of unity value. 252 */ 253 const IntType &GetBigRootOfUnityArb() const { return m_bigRootOfUnityArb; } 254 255 /** 256 * Sets the value of the delta factor 257 * @param &delta is the delta factor 258 */ 259 void SetDelta(const IntType &delta) { m_delta = delta; } 260 261 /** 262 * Sets the modulus used for polynomial multiplications in EvalMult 263 * 264 * @param &bigModulus the modulus value. 265 */ 266 void SetBigModulus(const IntType &bigModulus) { m_bigModulus = bigModulus; } 267 268 /** 269 * Sets primitive root of unity used for polynomial multiplications in 270 * EvalMult 271 * @param &bigRootOfUnity is the root of unity used for EvalMult operations. 272 */ 273 void SetBigRootOfUnity(const IntType &bigRootOfUnity) { 274 m_bigRootOfUnity = bigRootOfUnity; 275 } 276 277 /** 278 * Sets the modulus used for polynomial multiplications in EvalMult (arbitrary 279 * cyclotomics) 280 */ 281 void SetBigModulusArb(const IntType &bigModulusArb) { 282 m_bigModulusArb = bigModulusArb; 283 } 284 285 /** 286 * Sets primitive root of unity used for polynomial multiplications in 287 * EvalMult (arbitrary cyclotomics) 288 */ 289 void SetBigRootOfUnityArb(const IntType &bigRootOfUnityArb) { 290 m_bigRootOfUnityArb = bigRootOfUnityArb; 291 } 292 293 /** 294 * == operator to compare to this instance of LPCryptoParametersBFV object. 295 * 296 * @param &rhs LPCryptoParameters to check equality against. 297 */ 298 bool operator==(const LPCryptoParameters<Element> &rhs) const { 299 const auto *el = dynamic_cast<const LPCryptoParametersBFV<Element> *>(&rhs); 300 301 if (el == nullptr) return false; 302 303 if (m_delta != el->m_delta) return false; 304 if (m_bigModulus != el->m_bigModulus) return false; 305 if (m_bigRootOfUnity != el->m_bigRootOfUnity) return false; 306 if (m_bigModulusArb != el->m_bigModulusArb) return false; 307 if (m_bigRootOfUnityArb != el->m_bigRootOfUnityArb) return false; 308 309 return LPCryptoParametersRLWE<Element>::operator==(rhs); 310 } 311 312 void PrintParameters(std::ostream &os) const { 313 LPCryptoParametersRLWE<Element>::PrintParameters(os); 314 315 os << " delta: " << m_delta << " bigmodulus: " << m_bigModulus 316 << " bigrootofunity: " << m_bigRootOfUnity 317 << " bigmodulusarb: " << m_bigModulusArb 318 << " bigrootofunityarb: " << m_bigRootOfUnityArb; 319 } 320 321 template <class Archive> 322 void save(Archive &ar, std::uint32_t const version) const { 323 ar(::cereal::base_class<LPCryptoParametersRLWE<Element>>(this)); 324 ar(::cereal::make_nvp("d", m_delta)); 325 ar(::cereal::make_nvp("bm", m_bigModulus)); 326 ar(::cereal::make_nvp("br", m_bigRootOfUnity)); 327 ar(::cereal::make_nvp("bma", m_bigModulusArb)); 328 ar(::cereal::make_nvp("bra", m_bigRootOfUnityArb)); 329 } 330 331 template <class Archive> 332 void load(Archive &ar, std::uint32_t const version) { 333 if (version > SerializedVersion()) { 334 PALISADE_THROW(deserialize_error, 335 "serialized object version " + std::to_string(version) + 336 " is from a later version of the library"); 337 } 338 ar(::cereal::base_class<LPCryptoParametersRLWE<Element>>(this)); 339 ar(::cereal::make_nvp("d", m_delta)); 340 ar(::cereal::make_nvp("bm", m_bigModulus)); 341 ar(::cereal::make_nvp("br", m_bigRootOfUnity)); 342 ar(::cereal::make_nvp("bma", m_bigModulusArb)); 343 ar(::cereal::make_nvp("bra", m_bigRootOfUnityArb)); 344 } 345 346 std::string SerializedObjectName() const { return "BFVSchemeParameters"; } 347 static uint32_t SerializedVersion() { return 1; } 348 349 private: 350 // factor delta = floor(q/p) that is multipled by the plaintext polynomial 351 // in BFV (most significant bit ranges are used to represent the message) 352 IntType m_delta; 353 354 // larger modulus that is used in polynomial multiplications within EvalMult 355 // (before rounding is done) 356 IntType m_bigModulus; 357 358 // primitive root of unity for m_bigModulus 359 IntType m_bigRootOfUnity; 360 361 // Large modulus used for CRT with m_bigModulus 362 IntType m_bigModulusArb; 363 364 // Primitive root of unity for m_bigModulusArb 365 IntType m_bigRootOfUnityArb; 366 }; 367 368 /** 369 * @brief Parameter generation for BFV. This scheme is also referred to as the 370 * FV scheme. 371 * 372 * The BFV scheme parameter guidelines are introduced here: 373 * - Junfeng Fan and Frederik Vercauteren. Somewhat Practical Fully 374 * Homomorphic Encryption. Cryptology ePrint Archive, Report 2012/144. 375 * (https://eprint.iacr.org/2012/144.pdf) 376 * 377 * We used the optimized parameter selection from the designs here: 378 * - Lepoint T., Naehrig M. (2014) A Comparison of the Homomorphic Encryption 379 * Schemes FV and YASHE. In: Pointcheval D., Vergnaud D. (eds) Progress in 380 * Cryptology – AFRICACRYPT 2014. AFRICACRYPT 2014. Lecture Notes in Computer 381 * Science, vol 8469. Springer, Cham. (https://eprint.iacr.org/2014/062.pdf) 382 * 383 * @tparam Element a ring element. 384 */ 385 template <class Element> 386 class LPAlgorithmParamsGenBFV : public LPParameterGenerationAlgorithm<Element> { 387 using IntType = typename Element::Integer; 388 using ParmType = typename Element::Params; 389 390 public: 391 /** 392 * Default constructor 393 */ 394 LPAlgorithmParamsGenBFV() {} 395 396 /** 397 * Method for computing all derived parameters based on chosen primitive 398 * parameters 399 * 400 * @param cryptoParams the crypto parameters object to be populated with 401 * parameters. 402 * @param evalAddCount number of EvalAdds assuming no EvalMult and KeySwitch 403 * operations are performed. 404 * @param evalMultCount number of EvalMults assuming no EvalAdd and KeySwitch 405 * operations are performed. 406 * @param keySwitchCount number of KeySwitch operations assuming no EvalAdd 407 * and EvalMult operations are performed. 408 * @param dcrtBits number of bits in each CRT modulus - NOT USED IN BFV 409 * @param n ring dimension in case the user wants to use a custom ring 410 * dimension 411 */ 412 virtual bool ParamsGen(shared_ptr<LPCryptoParameters<Element>> cryptoParams, 413 int32_t evalAddCount = 0, int32_t evalMultCount = 0, 414 int32_t keySwitchCount = 0, size_t dcrtBits = 0, 415 uint32_t n = 0) const; 416 417 virtual ~LPAlgorithmParamsGenBFV() {} 418 }; 419 420 /** 421 * @brief Encryption algorithm implementation for BFV for the basic public key 422 * encrypt, decrypt and key generation methods for the BFV encryption scheme. 423 * This scheme is also referred to as the FV scheme. 424 * 425 * The BFV scheme parameter guidelines are introduced here: 426 * - Junfeng Fan and Frederik Vercauteren. Somewhat Practical Fully 427 * Homomorphic Encryption. Cryptology ePrint Archive, Report 2012/144. 428 * (https://eprint.iacr.org/2012/144.pdf) 429 * 430 * We used the optimized parameter selection from the designs here: 431 * - Lepoint T., Naehrig M. (2014) A Comparison of the Homomorphic Encryption 432 * Schemes FV and YASHE. In: Pointcheval D., Vergnaud D. (eds) Progress in 433 * Cryptology – AFRICACRYPT 2014. AFRICACRYPT 2014. Lecture Notes in Computer 434 * Science, vol 8469. Springer, Cham. (https://eprint.iacr.org/2014/062.pdf) 435 * 436 * @tparam Element a ring element. 437 */ 438 template <class Element> 439 class LPAlgorithmBFV : public LPEncryptionAlgorithm<Element> { 440 using IntType = typename Element::Integer; 441 using ParmType = typename Element::Params; 442 using DggType = typename Element::DggType; 443 using DugType = typename Element::DugType; 444 using TugType = typename Element::TugType; 445 446 public: 447 /** 448 * Default constructor 449 */ 450 LPAlgorithmBFV() {} 451 452 virtual ~LPAlgorithmBFV() {} 453 454 /** 455 * Method for encrypting plaintext using BFV. 456 * 457 * @param publicKey public key used for encryption. 458 * @param plaintext the plaintext input. 459 * @return ciphertext which results from encryption. 460 */ 461 virtual Ciphertext<Element> Encrypt(const LPPublicKey<Element> publicKey, 462 Element plaintext) const; 463 464 /** 465 * Method for encrypting plaintext with private key using BFV. 466 * 467 * @param privateKey private key used for encryption. 468 * @param plaintext the plaintext input. 469 * @return ciphertext which results from encryption. 470 */ 471 virtual Ciphertext<Element> Encrypt(const LPPrivateKey<Element> privateKey, 472 Element plaintext) const; 473 474 /** 475 * Method for decrypting using BFV. See the class description for citations on 476 * where the algorithms were taken from. 477 * 478 * @param privateKey private key used for decryption. 479 * @param ciphertext ciphertext to be decrypted. 480 * @param *plaintext the plaintext output. 481 * @return the decrypted plaintext returned. 482 */ 483 virtual DecryptResult Decrypt(const LPPrivateKey<Element> privateKey, 484 ConstCiphertext<Element> ciphertext, 485 NativePoly *plaintext) const; 486 487 /** 488 * Function to generate public and private keys. See the class description for 489 * citations on where the algorithms were taken from. 490 * 491 * @param cc cryptocontext for the keys to be generated. 492 * @param makeSparse set to true if ring reduce by a factor of 2 is to be 493 * used. Generally this should always be false. 494 * @return key pair including the private and public key 495 */ 496 LPKeyPair<Element> KeyGen(CryptoContext<Element> cc, bool makeSparse = false); 497 }; 498 499 /** 500 * @brief SHE algorithms implementation for BFV. This scheme is also referred 501 * to as the FV scheme. 502 * 503 * The BFV scheme parameter guidelines are introduced here: 504 * - Junfeng Fan and Frederik Vercauteren. Somewhat Practical Fully 505 * Homomorphic Encryption. Cryptology ePrint Archive, Report 2012/144. 506 * (https://eprint.iacr.org/2012/144.pdf) 507 * 508 * We used the optimized parameter selection from the designs here: 509 * - Lepoint T., Naehrig M. (2014) A Comparison of the Homomorphic Encryption 510 * Schemes FV and YASHE. In: Pointcheval D., Vergnaud D. (eds) Progress in 511 * Cryptology – AFRICACRYPT 2014. AFRICACRYPT 2014. Lecture Notes in Computer 512 * Science, vol 8469. Springer, Cham. (https://eprint.iacr.org/2014/062.pdf) 513 * 514 * @tparam Element a ring element. 515 */ 516 template <class Element> 517 class LPAlgorithmSHEBFV : public LPSHEAlgorithm<Element> { 518 using IntType = typename Element::Integer; 519 using ParmType = typename Element::Params; 520 using DggType = typename Element::DggType; 521 using DugType = typename Element::DugType; 522 using TugType = typename Element::TugType; 523 524 public: 525 /** 526 * Default constructor 527 */ 528 LPAlgorithmSHEBFV() {} 529 530 virtual ~LPAlgorithmSHEBFV() {} 531 532 /** 533 * Function for in-place homomorphic addition of ciphertexts. 534 * 535 * @param ct1 first input/output ciphertext. 536 * @param ct2 second input ciphertext. 537 * @details \p ct1 stores the result of \p ct1 + \p ct2 538 */ 539 void EvalAddInPlace(Ciphertext<Element>& ct1, 540 ConstCiphertext<Element> ct2) const override; 541 542 /** 543 * Function for homomorphic addition of ciphertext and plaintext. 544 * 545 * @param ct1 input ciphertext. 546 * @param pt input ciphertext. 547 * @return new ciphertext. 548 */ 549 Ciphertext<Element> EvalAdd(ConstCiphertext<Element> ct, 550 ConstPlaintext pt) const override; 551 552 /** 553 * Function for homomorphic subtraction of ciphertexts. 554 * 555 * @param ct1 first input ciphertext. 556 * @param ct2 second input ciphertext. 557 * @return new ciphertext. 558 */ 559 Ciphertext<Element> EvalSub(ConstCiphertext<Element> ct1, 560 ConstCiphertext<Element> ct2) const override; 561 562 /** 563 * Function for homomorphic subtraction of ciphertext ans plaintext. 564 * 565 * @param ct input ciphertext. 566 * @param pt input ciphertext. 567 * @return new ciphertext. 568 */ 569 Ciphertext<Element> EvalSub(ConstCiphertext<Element> ct1, 570 ConstPlaintext pt) const override; 571 572 /** 573 * Function for homomorphic evaluation of ciphertexts. 574 * The multiplication is supported for a fixed level without keyswitching 575 * requirement (default level=2). If the total depth of the ciphertexts 576 * exceeds the supported level, it throws an error. 577 * 578 * @param ciphertext1 first input ciphertext. 579 * @param ciphertext2 second input ciphertext. 580 * @return resulting EvalMult ciphertext. 581 */ 582 Ciphertext<Element> EvalMult(ConstCiphertext<Element> ct1, 583 ConstCiphertext<Element> ct2) const override; 584 585 /** 586 * Function for multiplying ciphertext by plaintext. 587 * 588 * @param ciphertext input ciphertext. 589 * @param plaintext input plaintext embedded in the cryptocontext. 590 * @return result of the multiplication. 591 */ 592 Ciphertext<Element> EvalMult(ConstCiphertext<Element> ciphertext, 593 ConstPlaintext plaintext) const override; 594 595 /** 596 * Function for evaluating multiplication on ciphertext followed by key 597 * switching operation. Currently it assumes that the input arguments are 598 * fresh ciphertexts (of depth 1). Support for the input ciphertexts of higher 599 * depths will be added later. 600 * 601 * @param ct1 first input ciphertext. 602 * @param ct2 second input ciphertext. 603 * @param ek is the evaluation key to make the newCiphertext 604 * decryptable by the same secret key as that of ciphertext1 and ciphertext2. 605 * @return new ciphertext 606 */ 607 Ciphertext<Element> EvalMult(ConstCiphertext<Element> ct1, 608 ConstCiphertext<Element> ct, 609 const LPEvalKey<Element> ek) const override; 610 611 /** 612 * Function for evaluating multiplication on ciphertext followed by 613 * relinearization operation. It computes the multiplication in a binary tree 614 * manner. Also, it reduces the number of elements in the ciphertext to two 615 * after each multiplication. Currently it assumes that the consecutive two 616 * input arguments have total depth smaller than the supported depth. 617 * Otherwise, it throws an error. 618 * 619 * @param cipherTextList is the ciphertext list. 620 * @param evalKeys is the evaluation key to make the newCiphertext 621 * decryptable by the same secret key as that of ciphertext list. 622 * @return new ciphertext. 623 */ 624 Ciphertext<Element> EvalMultMany( 625 const vector<Ciphertext<Element>> &cipherTextList, 626 const vector<LPEvalKey<Element>> &evalKeys) const override; 627 628 /** 629 * Function for evaluating multiplication on ciphertext followed by 630 * relinearization operation. Currently it assumes that the input arguments 631 * have total depth smaller than the supported depth. Otherwise, it throws an 632 * error. 633 * 634 * @param ct1 first input ciphertext. 635 * @param ct2 second input ciphertext. 636 * @param ek is the evaluation key to make the newCiphertext 637 * decryptable by the same secret key as that of ciphertext1 and ciphertext2. 638 * @return new ciphertext 639 */ 640 Ciphertext<Element> EvalMultAndRelinearize( 641 ConstCiphertext<Element> ct1, ConstCiphertext<Element> ct, 642 const vector<LPEvalKey<Element>> &ek) const override; 643 644 /** 645 * Function for homomorphic negation of ciphertexts. 646 * 647 * @param ct first input ciphertext. 648 * @return new ciphertext. 649 */ 650 Ciphertext<Element> EvalNegate(ConstCiphertext<Element> ct) const override; 651 652 /** 653 * Method for generating a KeySwitchHint using RLWE relinearization 654 * 655 * @param originalPrivateKey Original private key used for encryption. 656 * @param newPrivateKey New private key to generate the keyswitch hint. 657 * @return resulting keySwitchHint. 658 */ 659 LPEvalKey<Element> KeySwitchGen( 660 const LPPrivateKey<Element> originalPrivateKey, 661 const LPPrivateKey<Element> newPrivateKey) const override; 662 663 /** 664 * Method for in-place key switching based on a KeySwitchHint using RLWE 665 * relinearization 666 * 667 * @param keySwitchHint Hint required to perform the ciphertext switching. 668 * @param &cipherText Original ciphertext to perform in-place key switching 669 * on. 670 */ 671 void KeySwitchInPlace(const LPEvalKey<Element> keySwitchHint, 672 Ciphertext<Element> &cipherText) const override; 673 674 /** 675 * Function to generate 1..log(q) encryptions for each bit of the square of 676 * the original private key 677 * 678 * @param k1 private key. 679 * @return evaluation key. 680 */ 681 LPEvalKey<Element> EvalMultKeyGen( 682 const LPPrivateKey<Element> k1) const override; 683 684 /** 685 * Function to generate 1..log(q) encryptions for each bit of the powers of 686 * the original private key. The number of the powers is determined by the 687 * depth. If we choose depth 4, it means we can decrypt ciphertexts with 5 688 * elements. For c[i] being the ciphertext elements, we compute 689 * \sum_{i=0}^{i<5} c[i]*s^i. 690 * 691 * @param k1 private key. 692 * @return evaluation key. 693 */ 694 vector<LPEvalKey<Element>> EvalMultKeysGen( 695 const LPPrivateKey<Element> k1) const override; 696 697 /** 698 * Function for evaluating automorphism of ciphertext at index i. 699 * 700 * @param ciphertext the input ciphertext. 701 * @param i automorphism index 702 * @param &evalKeys - reference to the map of evaluation keys generated by 703 * EvalAutomorphismKeyGen. 704 * @return resulting ciphertext 705 */ 706 Ciphertext<Element> EvalAutomorphism( 707 ConstCiphertext<Element> ciphertext, usint i, 708 const std::map<usint, LPEvalKey<Element>> &evalKeys, 709 CALLER_INFO_ARGS_HDR) const override; 710 711 /** 712 * Generate automophism keys for a given private key; Uses the private key for 713 * encryption 714 * 715 * @param privateKey private key. 716 * @param indexList list of automorphism indices to be computed 717 * @return returns the evaluation keys 718 */ 719 shared_ptr<std::map<usint, LPEvalKey<Element>>> EvalAutomorphismKeyGen( 720 const LPPrivateKey<Element> privateKey, 721 const std::vector<usint> &indexList) const override; 722 723 /** 724 * Generate automophism keys for a given private key; Uses the public key for 725 * encryption 726 * 727 * @param publicKey public key. 728 * @param privateKey private key. 729 * @param indexList list of automorphism indices to be computed 730 * @return returns the evaluation keys 731 */ 732 shared_ptr<std::map<usint, LPEvalKey<Element>>> EvalAutomorphismKeyGen( 733 const LPPublicKey<Element> publicKey, 734 const LPPrivateKey<Element> privateKey, 735 const std::vector<usint> &indexList) const override { 736 std::string errMsg = 737 "LPAlgorithmSHEBFV::EvalAutomorphismKeyGen is not implemented for BFV " 738 "SHE Scheme."; 739 PALISADE_THROW(not_implemented_error, errMsg); 740 } 741 }; 742 743 /** 744 * @brief PRE scheme based on BFV. This functionality is currently DISABLED in 745 * LPPublicKeyEncryptionSchemeBFV because it needs more testing 746 * @tparam Element a ring element. 747 */ 748 template <class Element> 749 class LPAlgorithmPREBFV : public LPPREAlgorithm<Element> { 750 using IntType = typename Element::Integer; 751 using ParmType = typename Element::Params; 752 using DggType = typename Element::DggType; 753 using TugType = typename Element::TugType; 754 755 public: 756 /** 757 * Default constructor 758 */ 759 LPAlgorithmPREBFV() {} 760 761 /* 762 * DISABLED. Function to generate a re-encryption key as 1..log(q) encryptions 763 * for each bit of the original private key Variant that uses the new secret 764 * key directly. 765 * 766 * @param newKey new private key for the new ciphertext. 767 * @param origPrivateKey original private key used for decryption. 768 * @return evalKey the evaluation key for switching the ciphertext to be 769 * decryptable by new private key. 770 */ 771 LPEvalKey<Element> ReKeyGen(const LPPrivateKey<Element> newKey, 772 const LPPrivateKey<Element> origPrivateKey) const; 773 774 /** 775 * The generation of re-encryption keys is based on the BG-PRE scheme 776 * described in Polyakov, et. al., "Fast proxy re-encryption for 777 * publish/subscribe systems". 778 * 779 * The above scheme was found to have a weakness in Cohen, "What about Bob? 780 * The inadequacy of CPA Security for proxy re-encryption". Section 5.1 shows 781 * an attack where given an original ciphertext c=(c0,c1) and a re-encrypted 782 * ciphertext c'=(c'0, c'1), the subscriber (Bob) can compute the secret key 783 * of the publisher (Alice). 784 * 785 * We fix this vulnerability by making re-encryption keys be encryptions of 786 * the s*(2^{i*r}) terms, instead of simple addition as previously defined. 787 * This makes retrieving the secret key using the above attack as hard as 788 * breaking the RLWE assumption. 789 * 790 * Our modification makes the scheme CPA-secure, but does not achieve 791 * HRA-security as it was defined in the Cohen paper above. Please look at the 792 * ReEncrypt method for an explanation of the two security definitions and how 793 * to achieve each in Palisade. 794 * 795 * @param newKey public key for the new private key. 796 * @param origPrivateKey original private key used for decryption. 797 * @return evalKey the evaluation key for switching the ciphertext to be 798 * decryptable by new private key. 799 */ 800 LPEvalKey<Element> ReKeyGen(const LPPublicKey<Element> newKey, 801 const LPPrivateKey<Element> origPrivateKey) const; 802 803 /** 804 * This method implements re-encryption using the evaluation key generated by 805 * ReKeyGen. 806 * 807 * The PRE scheme used can achieve two different levels of security, based on 808 * the value supplied in the publicKey argument: 809 * 810 * If publicKey is nullptr, the PRE scheme is CPA-secure. If the publicKey of 811 * the recipient of the re-encrypted ciphertext is supplied, then the scheme 812 * is HRA- secure. Please refer to Cohen, "What about Bob? The inadequacy of 813 * CPA Security for proxy re-encryption", for more information on HRA 814 * security. 815 * 816 * The tradeoff of going for HRA is twofold: (1) performance is a little worst 817 * because we add one additional encryption and homomorphic addition to the 818 * result, and (2) more noise is added to the result because of the additional 819 * operations - in particular, the extra encryption draws noise from a 820 * distribution whose standard deviation is scaled by K, the number of digits 821 * in the PRE decomposition. 822 * 823 * @param evalKey the evaluation key. 824 * @param ciphertext the input ciphertext. 825 * @param publicKey the public key of the recipient of the re-encrypted 826 * ciphertext. 827 * @return resulting ciphertext after the re-encryption operation. 828 */ 829 Ciphertext<Element> ReEncrypt( 830 const LPEvalKey<Element> evalKey, ConstCiphertext<Element> ciphertext, 831 const LPPublicKey<Element> publicKey = nullptr) const; 832 }; 833 834 /** 835 * @brief Concrete class for the FHE Multiparty algorithms on BFV. A version of 836 * this multiparty scheme built on the BGV scheme is seen here: 837 * - Asharov G., Jain A., López-Alt A., Tromer E., Vaikuntanathan V., Wichs D. 838 * (2012) Multiparty Computation with Low Communication, Computation and 839 * Interaction via Threshold FHE. In: Pointcheval D., Johansson T. (eds) 840 * Advances in Cryptology – EUROCRYPT 2012. EUROCRYPT 2012. Lecture Notes in 841 * Computer Science, vol 7237. Springer, Berlin, Heidelberg 842 * 843 * During offline key generation, this multiparty scheme relies on the clients 844 * coordinating their public key generation. To do this, a single client 845 * generates a public-secret key pair. This public key is shared with other keys 846 * which use an element in the public key to generate their own public keys. The 847 * clients generate a shared key pair using a scheme-specific approach, then 848 * generate re-encryption keys. Re-encryption keys are uploaded to the server. 849 * Clients encrypt data with their public keys and send the encrypted data 850 * server. The data is re-encrypted. Computations are then run on the data. The 851 * result is sent to each of the clients. One client runs a "Leader" multiparty 852 * decryption operation with its own secret key. All other clients run a 853 * regular "Main" multiparty decryption with their own secret key. The resulting 854 * partially decrypted ciphertext are then fully decrypted with the decryption 855 * fusion algorithms. 856 * 857 * @tparam Element a ring element. 858 */ 859 template <class Element> 860 class LPAlgorithmMultipartyBFV : public LPMultipartyAlgorithm<Element> { 861 using IntType = typename Element::Integer; 862 using ParmType = typename Element::Params; 863 using DggType = typename Element::DggType; 864 using DugType = typename Element::DugType; 865 using TugType = typename Element::TugType; 866 867 public: 868 /** 869 * Default constructor 870 */ 871 LPAlgorithmMultipartyBFV() {} 872 873 virtual ~LPAlgorithmMultipartyBFV() {} 874 875 /** 876 * Threshold FHE: Generation of a public key derived 877 * from a previous joined public key (for prior secret shares) and the secret 878 * key share of the current party. 879 * 880 * @param cc cryptocontext for the keys to be generated. 881 * @param pk1 joined public key from prior parties. 882 * @param makeSparse set to true if ring reduce by a factor of 2 is to be 883 * used. NOT SUPPORTED BY ANY SCHEME ANYMORE. 884 * @param fresh set to true if proxy re-encryption is used in the multi-party 885 * protocol or star topology is used 886 * @return key pair including the secret share for the current party and 887 * joined public key 888 */ 889 LPKeyPair<Element> MultipartyKeyGen(CryptoContext<Element> cc, 890 const LPPublicKey<Element> pk1, 891 bool makeSparse = false, 892 bool fresh = false) override; 893 894 /** 895 * Threshold FHE: Generates a public key from a vector of secret shares. 896 * ONLY FOR DEBUGGIN PURPOSES. SHOULD NOT BE USED IN PRODUCTION. 897 * 898 * @param cc cryptocontext for the keys to be generated. 899 * @param secretkeys secrete key sahres. 900 * @param makeSparse set to true if ring reduce by a factor of 2 is to be 901 * used. NOT SUPPORTED BY ANY SCHEME ANYMORE. 902 * @return key pair including the private for the current party and joined 903 * public key 904 */ 905 LPKeyPair<Element> MultipartyKeyGen( 906 CryptoContext<Element> cc, 907 const vector<LPPrivateKey<Element>> &secretKeys, 908 bool makeSparse = false) override; 909 910 /** 911 * Threshold FHE: "Partial" decryption computed by all parties except for the 912 * lead one. 913 * 914 * @param privateKey secret key share used for decryption. 915 * @param ciphertext ciphertext that is being decrypted. 916 */ 917 Ciphertext<Element> MultipartyDecryptMain( 918 const LPPrivateKey<Element> privateKey, 919 ConstCiphertext<Element> ciphertext) const override; 920 921 /** 922 * Threshold FHE: Method for decryption operation run by the lead decryption 923 * client. 924 * 925 * @param privateKey secret key share used for decryption. 926 * @param ciphertext ciphertext id decrypted. 927 */ 928 Ciphertext<Element> MultipartyDecryptLead( 929 const LPPrivateKey<Element> privateKey, 930 ConstCiphertext<Element> ciphertext) const override; 931 932 /** 933 * Threshold FHE: Method for combining the partially decrypted ciphertexts 934 * and getting the final decryption in the clear as a NativePoly. 935 * 936 * @param &ciphertextVec vector of "partial" decryptions. 937 * @param *plaintext the plaintext output as a NativePoly. 938 * @return the decoding result. 939 */ 940 DecryptResult MultipartyDecryptFusion( 941 const vector<Ciphertext<Element>> &ciphertextVec, 942 NativePoly *plaintext) const override; 943 944 /** 945 * Threshold FHE: Generates a joined evaluation key 946 * from the current secret share and a prior joined 947 * evaluation key 948 * 949 * @param originalPrivateKey secret key transformed from. 950 * @param newPrivateKey secret key transformed to. 951 * @param ek the prior joined evaluation key. 952 * @return the new joined evaluation key. 953 */ 954 LPEvalKey<Element> MultiKeySwitchGen( 955 const LPPrivateKey<Element> originalPrivateKey, 956 const LPPrivateKey<Element> newPrivateKey, 957 const LPEvalKey<Element> ek) const override; 958 959 /** 960 * Threshold FHE: Generates joined automorphism keys 961 * from the current secret share and prior joined 962 * automorphism keys 963 * 964 * @param privateKey secret key share. 965 * @param eAuto a dictionary with prior joined automorphism keys. 966 * @param &indexList a vector of automorphism indices. 967 * @return a dictionary with new joined automorphism keys. 968 */ 969 shared_ptr<std::map<usint, LPEvalKey<Element>>> MultiEvalAutomorphismKeyGen( 970 const LPPrivateKey<Element> privateKey, 971 const shared_ptr<std::map<usint, LPEvalKey<Element>>> eAuto, 972 const std::vector<usint> &indexList) const override; 973 974 /** 975 * Threshold FHE: Generates joined summation evaluation keys 976 * from the current secret share and prior joined 977 * summation keys 978 * 979 * @param privateKey secret key share. 980 * @param eSum a dictionary with prior joined summation keys. 981 * @return new joined summation keys. 982 */ 983 shared_ptr<std::map<usint, LPEvalKey<Element>>> MultiEvalSumKeyGen( 984 const LPPrivateKey<Element> privateKey, 985 const shared_ptr<std::map<usint, LPEvalKey<Element>>> eSum) 986 const override; 987 988 /** 989 * Threshold FHE: Adds two prior evaluation keys 990 * 991 * @param evalKey1 first evaluation key. 992 * @param evalKey2 second evaluation key. 993 * @return the new joined key. 994 */ 995 LPEvalKey<Element> MultiAddEvalKeys( 996 LPEvalKey<Element> evalKey1, LPEvalKey<Element> evalKey2) const override; 997 998 /** 999 * Threshold FHE: Generates a partial evaluation key for homomorphic 1000 * multiplication based on the current secret share and an existing partial 1001 * evaluation key 1002 * 1003 * @param evalKey prior evaluation key. 1004 * @param sk current secret share. 1005 * @return the new joined key. 1006 */ 1007 LPEvalKey<Element> MultiMultEvalKey(LPEvalKey<Element> evalKey, 1008 LPPrivateKey<Element> sk) const override; 1009 1010 template <class Archive> 1011 void save(Archive &ar) const { 1012 ar(cereal::base_class<LPMultipartyAlgorithm<Element>>(this)); 1013 } 1014 1015 template <class Archive> 1016 void load(Archive &ar) { 1017 ar(cereal::base_class<LPMultipartyAlgorithm<Element>>(this)); 1018 } 1019 1020 std::string SerializedObjectName() const { return "BFVMultiparty"; } 1021 }; 1022 1023 /** 1024 * @brief Main public key encryption scheme for BFV implementation, 1025 * @tparam Element a ring element. 1026 */ 1027 template <class Element> 1028 class LPPublicKeyEncryptionSchemeBFV 1029 : public LPPublicKeyEncryptionScheme<Element> { 1030 using IntType = typename Element::Integer; 1031 using ParmType = typename Element::Params; 1032 using DggType = typename Element::DggType; 1033 using TugType = typename Element::TugType; 1034 1035 public: 1036 LPPublicKeyEncryptionSchemeBFV(); 1037 1038 bool operator==( 1039 const LPPublicKeyEncryptionScheme<Element> &sch) const override { 1040 return dynamic_cast<const LPPublicKeyEncryptionSchemeBFV<Element> *>( 1041 &sch) != nullptr; 1042 } 1043 1044 void Enable(PKESchemeFeature feature) override; 1045 1046 template <class Archive> 1047 void save(Archive &ar, std::uint32_t const version) const { 1048 ar(::cereal::base_class<LPPublicKeyEncryptionScheme<Element>>(this)); 1049 } 1050 1051 template <class Archive> 1052 void load(Archive &ar, std::uint32_t const version) { 1053 ar(::cereal::base_class<LPPublicKeyEncryptionScheme<Element>>(this)); 1054 } 1055 1056 std::string SerializedObjectName() const override { return "BFVScheme"; } 1057 }; 1058 1059 } // namespace lbcrypto 1060 1061 #endif 1062