From 3ed5909960ff7dbc4e236b7fb8e8cdadf426966c Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 11 Dec 2024 17:51:43 -0800 Subject: [PATCH 01/21] Initial commit: adding composite scaling parameters and scaling tech mode. --- src/pke/include/constants-defs.h | 2 + .../scheme/ckksrns/ckksrns-cryptoparameters.h | 22 +++++ .../gen-cryptocontext-ckksrns-internal.h | 2 + .../gen-cryptocontext-params-defaults.h | 6 ++ .../include/scheme/gen-cryptocontext-params.h | 21 ++++- .../include/schemerns/rns-cryptoparameters.h | 91 +++++++++++++++++-- src/pke/lib/constants-impl.cpp | 12 +++ .../ckksrns/ckksrns-cryptoparameters.cpp | 31 ++++++- .../lib/scheme/ckksrns/ckksrns-leveledshe.cpp | 79 +++++++++------- .../ckksrns/ckksrns-parametergeneration.cpp | 18 +++- .../scheme/gen-cryptocontext-params-impl.cpp | 10 +- .../gen-cryptocontext-params-validation.cpp | 3 +- 12 files changed, 251 insertions(+), 46 deletions(-) diff --git a/src/pke/include/constants-defs.h b/src/pke/include/constants-defs.h index 1cef5594f..c78d268a4 100644 --- a/src/pke/include/constants-defs.h +++ b/src/pke/include/constants-defs.h @@ -54,6 +54,8 @@ enum ScalingTechnique { FIXEDAUTO, FLEXIBLEAUTO, FLEXIBLEAUTOEXT, + COMPOSITESCALINGAUTO, + COMPOSITESCALINGMANUAL, NORESCALE, INVALID_RS_TECHNIQUE, // TODO (dsuponit): make this the first value }; diff --git a/src/pke/include/scheme/ckksrns/ckksrns-cryptoparameters.h b/src/pke/include/scheme/ckksrns/ckksrns-cryptoparameters.h index 0a7e40751..bf649e863 100644 --- a/src/pke/include/scheme/ckksrns/ckksrns-cryptoparameters.h +++ b/src/pke/include/scheme/ckksrns/ckksrns-cryptoparameters.h @@ -83,6 +83,26 @@ class CryptoParametersCKKSRNS : public CryptoParametersRNS { multipartyMode, executionMode, decryptionNoiseMode, noiseScale, statisticalSecurity, numAdversarialQueries, thresholdNumOfParties, mPIntBootCiphertextCompressionLevel) {} + // This constructor is ideal when register word size varies and composite degree is set manually + CryptoParametersCKKSRNS(std::shared_ptr params, EncodingParams encodingParams, + float distributionParameter, float assuranceMeasure, SecurityLevel securityLevel, + usint digitSize, SecretKeyDist secretKeyDist, int maxRelinSkDeg = 2, + KeySwitchTechnique ksTech = BV, ScalingTechnique scalTech = FIXEDMANUAL, + usint compositeDegree = BASE_NUM_LEVELS_TO_DROP, usint registerWordSize = NATIVEINT, + EncryptionTechnique encTech = STANDARD, MultiplicationTechnique multTech = HPS, + ProxyReEncryptionMode PREMode = NOT_SET, + MultipartyMode multipartyMode = FIXED_NOISE_MULTIPARTY, + ExecutionMode executionMode = EXEC_EVALUATION, + DecryptionNoiseMode decryptionNoiseMode = FIXED_NOISE_DECRYPT, + PlaintextModulus noiseScale = 1, uint32_t statisticalSecurity = 30, + uint32_t numAdversarialQueries = 1, uint32_t thresholdNumOfParties = 1, + COMPRESSION_LEVEL mPIntBootCiphertextCompressionLevel = COMPRESSION_LEVEL::SLACK) + : CryptoParametersRNS(params, encodingParams, distributionParameter, assuranceMeasure, securityLevel, digitSize, + secretKeyDist, maxRelinSkDeg, ksTech, scalTech, compositeDegree, registerWordSize, + encTech, multTech, PREMode, multipartyMode, executionMode, decryptionNoiseMode, + noiseScale, statisticalSecurity, numAdversarialQueries, thresholdNumOfParties, + mPIntBootCiphertextCompressionLevel) {} + virtual ~CryptoParametersCKKSRNS() {} void PrecomputeCRTTables(KeySwitchTechnique ksTech, ScalingTechnique scalTech, EncryptionTechnique encTech, @@ -91,6 +111,8 @@ class CryptoParametersCKKSRNS : public CryptoParametersRNS { uint64_t FindAuxPrimeStep() const override; + void ConfigureCompositeDegree(usint scalingModSize); + ///////////////////////////////////// // SERIALIZATION ///////////////////////////////////// diff --git a/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h b/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h index eadc47589..85b1887b7 100644 --- a/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h +++ b/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h @@ -102,6 +102,8 @@ typename ContextGeneratorType::ContextType genCryptoContextCKKSRNSInternal( parameters.GetMaxRelinSkDeg(), parameters.GetKeySwitchTechnique(), parameters.GetScalingTechnique(), + parameters.GetCompositeDegree(), + parameters.GetRegisterWordSize(), parameters.GetEncryptionTechnique(), parameters.GetMultiplicationTechnique(), parameters.GetPREMode(), diff --git a/src/pke/include/scheme/gen-cryptocontext-params-defaults.h b/src/pke/include/scheme/gen-cryptocontext-params-defaults.h index 4d3f977e4..461b60f12 100644 --- a/src/pke/include/scheme/gen-cryptocontext-params-defaults.h +++ b/src/pke/include/scheme/gen-cryptocontext-params-defaults.h @@ -81,6 +81,8 @@ constexpr uint32_t statisticalSecurity = 30; constexpr uint32_t numAdversarialQueries = 1; constexpr uint32_t thresholdNumOfParties = 1; constexpr COMPRESSION_LEVEL interactiveBootCompressionLevel = SLACK; +constexpr uint32_t compositeDegree = BASE_NUM_LEVELS_TO_DROP; +constexpr uint32_t registerWordSize = NATIVEINT; }; // namespace CKKSRNS_SCHEME_DEFAULTS namespace BFVRNS_SCHEME_DEFAULTS { @@ -118,6 +120,8 @@ constexpr uint32_t statisticalSecurity = 0; constexpr uint32_t numAdversarialQueries = 0; constexpr uint32_t thresholdNumOfParties = 1; constexpr COMPRESSION_LEVEL interactiveBootCompressionLevel = SLACK; +constexpr uint32_t compositeDegree = BASE_NUM_LEVELS_TO_DROP; +constexpr uint32_t registerWordSize = NATIVEINT; }; // namespace BFVRNS_SCHEME_DEFAULTS namespace BGVRNS_SCHEME_DEFAULTS { @@ -151,6 +155,8 @@ constexpr uint32_t statisticalSecurity = 30; constexpr uint32_t numAdversarialQueries = 1; constexpr uint32_t thresholdNumOfParties = 1; constexpr COMPRESSION_LEVEL interactiveBootCompressionLevel = SLACK; +constexpr uint32_t compositeDegree = BASE_NUM_LEVELS_TO_DROP; +constexpr uint32_t registerWordSize = NATIVEINT; }; // namespace BGVRNS_SCHEME_DEFAULTS //==================================================================================================================== diff --git a/src/pke/include/scheme/gen-cryptocontext-params.h b/src/pke/include/scheme/gen-cryptocontext-params.h index c78a8edcf..e9bd084fc 100644 --- a/src/pke/include/scheme/gen-cryptocontext-params.h +++ b/src/pke/include/scheme/gen-cryptocontext-params.h @@ -167,6 +167,11 @@ class Params { // COMPACT has stronger security assumption, thus more efficient COMPRESSION_LEVEL interactiveBootCompressionLevel; + // CKKS composite scaling parameters to support high-precision CKKS RNS with small word sizes + // Please refer to https://eprint.iacr.org/2023/1462.pdf for details + uint32_t compositeDegree; + uint32_t registerWordSize; + void SetToDefaults(SCHEME scheme); protected: @@ -247,7 +252,9 @@ class Params { "statisticalSecurity", "numAdversarialQueries", "thresholdNumOfParties", - "interactiveBootCompressionLevel"}; + "interactiveBootCompressionLevel" + "compositeDegree", + "registerWordSize"}; } // getters @@ -343,6 +350,12 @@ class Params { COMPRESSION_LEVEL GetInteractiveBootCompressionLevel() const { return interactiveBootCompressionLevel; } + uint32_t GetCompositeDegree() const { + return compositeDegree; + } + uint32_t GetRegisterWordSize() const { + return registerWordSize; + } // setters // They all must be virtual, so any of them can be disabled in the derived class @@ -433,6 +446,12 @@ class Params { virtual void SetInteractiveBootCompressionLevel(COMPRESSION_LEVEL interactiveBootCompressionLevel0) { interactiveBootCompressionLevel = interactiveBootCompressionLevel0; } + virtual void SetCompositeDegree(uint32_t compositeDegree0) { + compositeDegree = compositeDegree0; + } + virtual void SetRegisterWordSize(uint32_t registerWordSize0) { + registerWordSize = registerWordSize0; + } friend std::ostream& operator<<(std::ostream& os, const Params& obj); }; diff --git a/src/pke/include/schemerns/rns-cryptoparameters.h b/src/pke/include/schemerns/rns-cryptoparameters.h index 0d07d7db4..b0d0b31da 100644 --- a/src/pke/include/schemerns/rns-cryptoparameters.h +++ b/src/pke/include/schemerns/rns-cryptoparameters.h @@ -116,6 +116,8 @@ class CryptoParametersRNS : public CryptoParametersRLWE { m_encTechnique = encTech; m_multTechnique = multTech; m_MPIntBootCiphertextCompressionLevel = mPIntBootCiphertextCompressionLevel; + m_compositeDegree = BASE_NUM_LEVELS_TO_DROP; + m_registerWordSize = NATIVEINT; } CryptoParametersRNS(std::shared_ptr params, EncodingParams encodingParams, float distributionParameter, @@ -138,6 +140,33 @@ class CryptoParametersRNS : public CryptoParametersRLWE { m_encTechnique = encTech; m_multTechnique = multTech; m_MPIntBootCiphertextCompressionLevel = mPIntBootCiphertextCompressionLevel; + m_compositeDegree = BASE_NUM_LEVELS_TO_DROP; + m_registerWordSize = NATIVEINT; + } + + CryptoParametersRNS(std::shared_ptr params, EncodingParams encodingParams, float distributionParameter, + float assuranceMeasure, SecurityLevel securityLevel, usint digitSize, + SecretKeyDist secretKeyDist, int maxRelinSkDeg = 2, KeySwitchTechnique ksTech = BV, + ScalingTechnique scalTech = FIXEDMANUAL, usint compositeDegree = BASE_NUM_LEVELS_TO_DROP, + usint registerWordSize = NATIVEINT, EncryptionTechnique encTech = STANDARD, + MultiplicationTechnique multTech = HPS, ProxyReEncryptionMode PREMode = INDCPA, + MultipartyMode multipartyMode = FIXED_NOISE_MULTIPARTY, + ExecutionMode executionMode = EXEC_EVALUATION, + DecryptionNoiseMode decryptionNoiseMode = FIXED_NOISE_DECRYPT, PlaintextModulus noiseScale = 1, + uint32_t statisticalSecurity = 30, uint32_t numAdversarialQueries = 1, + uint32_t thresholdNumOfParties = 1, + COMPRESSION_LEVEL mPIntBootCiphertextCompressionLevel = COMPRESSION_LEVEL::SLACK) + : CryptoParametersRLWE(std::move(params), std::move(encodingParams), distributionParameter, + assuranceMeasure, securityLevel, digitSize, maxRelinSkDeg, secretKeyDist, + PREMode, multipartyMode, executionMode, decryptionNoiseMode, noiseScale, + statisticalSecurity, numAdversarialQueries, thresholdNumOfParties) { + m_ksTechnique = ksTech; + m_scalTechnique = scalTech; + m_encTechnique = encTech; + m_multTechnique = multTech; + m_MPIntBootCiphertextCompressionLevel = mPIntBootCiphertextCompressionLevel; + m_compositeDegree = compositeDegree; + m_registerWordSize = registerWordSize; } virtual ~CryptoParametersRNS() {} @@ -198,7 +227,8 @@ class CryptoParametersRNS : public CryptoParametersRLWE { m_ksTechnique == el->GetKeySwitchTechnique() && m_multTechnique == el->GetMultiplicationTechnique() && m_encTechnique == el->GetEncryptionTechnique() && m_numPartQ == el->GetNumPartQ() && m_auxBits == el->GetAuxBits() && m_extraBits == el->GetExtraBits() && m_PREMode == el->GetPREMode() && - m_multipartyMode == el->GetMultipartyMode() && m_executionMode == el->GetExecutionMode(); + m_multipartyMode == el->GetMultipartyMode() && m_executionMode == el->GetExecutionMode() && + m_compositeDegree == el->GetCompositeDegree() && m_registerWordSize == el->GetRegisterWordSize(); } void PrintParameters(std::ostream& os) const override { @@ -608,7 +638,8 @@ class CryptoParametersRNS : public CryptoParametersRLWE { * @return the scaling factor. */ double GetScalingFactorReal(uint32_t l = 0) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT) { + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { if (l >= m_scalingFactorsReal.size()) { // TODO: Return an error here. return m_approxSF; @@ -621,7 +652,8 @@ class CryptoParametersRNS : public CryptoParametersRLWE { } double GetScalingFactorRealBig(uint32_t l = 0) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT) { + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { if (l >= m_scalingFactorsRealBig.size()) { // TODO: Return an error here. return m_approxSF; @@ -633,20 +665,47 @@ class CryptoParametersRNS : public CryptoParametersRLWE { return m_approxSF; } - /** + /** * Method to retrieve the modulus to be dropped of level l. * For FIXEDMANUAL rescaling technique method always returns 2^p, where p corresponds to plaintext modulus * @param l index of modulus to be dropped for FLEXIBLEAUTO scaling technique * @return the precomputed table */ double GetModReduceFactor(uint32_t l = 0) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT) { + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { return m_dmoduliQ[l]; } return m_approxSF; } + ///////////////////////////////////// + // CKKS RNS Composite Scaling Params + ///////////////////////////////////// + + /** + * Returns the composite scaling degree d. Its values is determined at runtime based on + * input scaling factor and architecture register size (e.g., 32 bits, 48 bits, 64 bits). + * This parameter is only relevant when using the CKKS scheme and . + * + * @return the composite degree value for COMPOSITESCALING scaling technique + **/ + uint32_t const& GetCompositeDegree() const { + // If not CKKS scheme, same value as BASE_NUM_LEVELS_TO_DROP + return m_compositeDegree; + } + /** + * Returns the architecture register word size (e.g., 32 bits, 48 bits, 64 bits). + * Used to determine the size of prime moduli in the CKKS scheme on + * composite scaling mode (COMPOSITESCALINGAUTO). + * + * @return the register word size for COMPOSITESCALING scaling technique + **/ + uint32_t const& GetRegisterWordSize() const { + return m_registerWordSize; + } + ///////////////////////////////////// // BFVrns : Encrypt : POverQ ///////////////////////////////////// @@ -938,7 +997,8 @@ class CryptoParametersRNS : public CryptoParametersRLWE { } const NativeInteger& GetScalingFactorInt(usint l) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT) { + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { if (l >= m_scalingFactorsInt.size()) { // TODO: Return an error here. return m_fixedSF; @@ -949,7 +1009,8 @@ class CryptoParametersRNS : public CryptoParametersRLWE { } const NativeInteger& GetScalingFactorIntBig(usint l) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT) { + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { if (l >= m_scalingFactorsIntBig.size()) { // TODO: Return an error here. return m_fixedSF; @@ -960,7 +1021,8 @@ class CryptoParametersRNS : public CryptoParametersRLWE { } const NativeInteger& GetModReduceFactorInt(uint32_t l = 0) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT) { + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { return m_qModt[l]; } return m_fixedSF; @@ -1482,6 +1544,15 @@ class CryptoParametersRNS : public CryptoParametersRLWE { // Stores 2^ptm where ptm - plaintext modulus double m_approxSF = 0; + ///////////////////////////////////// + // CKKS RNS Composite Scaling Params + ///////////////////////////////////// + + // Stores composite degree for composite modulus chain + uint32_t m_compositeDegree = BASE_NUM_LEVELS_TO_DROP; + // Stores the architecture register word size + uint32_t m_registerWordSize = NATIVEINT; + ///////////////////////////////////// // BFVrns : Encrypt ///////////////////////////////////// @@ -1791,6 +1862,8 @@ class CryptoParametersRNS : public CryptoParametersRLWE { ar(cereal::make_nvp("ab", m_auxBits)); ar(cereal::make_nvp("eb", m_extraBits)); ar(cereal::make_nvp("ccl", m_MPIntBootCiphertextCompressionLevel)); + ar(cereal::make_nvp("cd", m_compositeDegree)); + ar(cereal::make_nvp("rws", m_registerWordSize)); } template @@ -1816,6 +1889,8 @@ class CryptoParametersRNS : public CryptoParametersRLWE { catch (cereal::Exception&) { m_MPIntBootCiphertextCompressionLevel = COMPRESSION_LEVEL::SLACK; } + ar(cereal::make_nvp("cd", m_compositeDegree)); + ar(cereal::make_nvp("rws", m_registerWordSize)); } std::string SerializedObjectName() const override { diff --git a/src/pke/lib/constants-impl.cpp b/src/pke/lib/constants-impl.cpp index 2b99b81c4..826daa743 100644 --- a/src/pke/lib/constants-impl.cpp +++ b/src/pke/lib/constants-impl.cpp @@ -79,6 +79,10 @@ ScalingTechnique convertToScalingTechnique(const std::string& str) { return FLEXIBLEAUTO; else if (str == "FLEXIBLEAUTOEXT") return FLEXIBLEAUTOEXT; + else if (str == "COMPOSITESCALINGAUTO") + return COMPOSITESCALINGAUTO; + else if (str == "COMPOSITESCALINGMANUAL") + return COMPOSITESCALINGMANUAL; else if (str == "NORESCALE") return NORESCALE; @@ -92,6 +96,8 @@ ScalingTechnique convertToScalingTechnique(uint32_t num) { case FIXEDAUTO: case FLEXIBLEAUTO: case FLEXIBLEAUTOEXT: + case COMPOSITESCALINGAUTO: + case COMPOSITESCALINGMANUAL: case NORESCALE: // case INVALID_RS_TECHNIQUE: return scTech; @@ -116,6 +122,12 @@ std::ostream& operator<<(std::ostream& s, ScalingTechnique t) { case FLEXIBLEAUTOEXT: s << "FLEXIBLEAUTOEXT"; break; + case COMPOSITESCALINGAUTO: + s << "COMPOSITESCALINGAUTO"; + break; + case COMPOSITESCALINGMANUAL: + s << "COMPOSITESCALINGMANUAL"; + break; case NORESCALE: s << "NORESCALE"; break; diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp index a2db8cdb1..bc39c8559 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp @@ -48,6 +48,8 @@ void CryptoParametersCKKSRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Sca CryptoParametersRNS::PrecomputeCRTTables(ksTech, scalTech, encTech, multTech, numPartQ, auxBits, extraBits); size_t sizeQ = GetElementParams()->GetParams().size(); + uint32_t compositeDegree = this->GetCompositeDegree(); + compositeDegree = (compositeDegree == 0) ? 1 : compositeDegree; std::vector moduliQ(sizeQ); std::vector rootsQ(sizeQ); @@ -82,7 +84,8 @@ void CryptoParametersCKKSRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Sca } // Pre-compute scaling factors for each level (used in FLEXIBLE* scaling techniques) - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT) { + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { m_scalingFactorsReal.resize(sizeQ); if ((sizeQ == 1) && (extraBits == 0)) { @@ -154,4 +157,30 @@ uint64_t CryptoParametersCKKSRNS::FindAuxPrimeStep() const { return static_cast(2 * n); } +void CryptoParametersCKKSRNS::ConfigureCompositeDegree(uint32_t scalingModSize) { + // Add logic to determine whether composite scaling is feasible or not + if (GetScalingTechnique() == COMPOSITESCALINGAUTO) { + if (NATIVEINT != 64) + OPENFHE_THROW(config_error, "COMPOSITESCALINGAUTO scaling technique only supported with NATIVEINT==64."); + usint compositeDegree = GetCompositeDegree(); + usint registerWordSize = GetRegisterWordSize(); + if (registerWordSize <= 64) { + if (registerWordSize < scalingModSize) { + compositeDegree = (uint32_t)std::ceil(static_cast(scalingModSize) / registerWordSize); + // Assert minimum allowed moduli size on composite scaling mode + // @fdiasmor TODO: make it more robust for a range of multiplicative depth + if (static_cast(scalingModSize) / compositeDegree < 21) { + OPENFHE_THROW( + config_error, + "Moduli size is too short (< 21) for target multiplicative depth. Consider increasing the scaling factor or the register word size."); + } + m_compositeDegree = compositeDegree; + } // else composite degree remains set to 1 + } + else { + OPENFHE_THROW(config_error, "COMPOSITESCALING scaling technique only supports register word size <= 64."); + } + } +} + } // namespace lbcrypto diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp index d25ee6f92..7ec37b0aa 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp @@ -89,7 +89,7 @@ void LeveledSHECKKSRNS::EvalMultInPlace(Ciphertext& ciphertext, double if (cryptoParams->GetScalingTechnique() != FIXEDMANUAL) { if (ciphertext->GetNoiseScaleDeg() == 2) { - ModReduceInternalInPlace(ciphertext, BASE_NUM_LEVELS_TO_DROP); + ModReduceInternalInPlace(ciphertext, cryptoParams->GetCompositeDegree()); } } @@ -120,7 +120,7 @@ void LeveledSHECKKSRNS::ModReduceInternalInPlace(Ciphertext& ciphertex } } - ciphertext->SetNoiseScaleDeg(ciphertext->GetNoiseScaleDeg() - levels); + ciphertext->SetNoiseScaleDeg(ciphertext->GetNoiseScaleDeg() - levels / cryptoParams->GetCompositeDegree()); ciphertext->SetLevel(ciphertext->GetLevel() + levels); for (usint i = 0; i < levels; ++i) { @@ -519,6 +519,7 @@ void LeveledSHECKKSRNS::AdjustLevelsAndDepthInPlace(Ciphertext& cipher usint c2depth = ciphertext2->GetNoiseScaleDeg(); auto sizeQl1 = ciphertext1->GetElements()[0].GetNumOfElements(); auto sizeQl2 = ciphertext2->GetElements()[0].GetNumOfElements(); + uint32_t compositeDegree = cryptoParams->GetCompositeDegree(); if (c1lvl < c2lvl) { if (c1depth == 2) { @@ -527,28 +528,34 @@ void LeveledSHECKKSRNS::AdjustLevelsAndDepthInPlace(Ciphertext& cipher double scf2 = ciphertext2->GetScalingFactor(); double scf = cryptoParams->GetScalingFactorReal(c1lvl); double q1 = cryptoParams->GetModReduceFactor(sizeQl1 - 1); + for (uint32_t j = 1; j < compositeDegree; j++) { + q1 *= cryptoParams->GetModReduceFactor(sizeQl1 - j - 1); + } EvalMultCoreInPlace(ciphertext1, scf2 / scf1 * q1 / scf); - ModReduceInternalInPlace(ciphertext1, BASE_NUM_LEVELS_TO_DROP); - if (c1lvl + 1 < c2lvl) { - LevelReduceInternalInPlace(ciphertext1, c2lvl - c1lvl - 1); + ModReduceInternalInPlace(ciphertext1, compositeDegree); + if (c1lvl + compositeDegree < c2lvl) { + LevelReduceInternalInPlace(ciphertext1, c2lvl - c1lvl - compositeDegree); } ciphertext1->SetScalingFactor(ciphertext2->GetScalingFactor()); } else { - if (c1lvl + 1 == c2lvl) { - ModReduceInternalInPlace(ciphertext1, BASE_NUM_LEVELS_TO_DROP); + if (c1lvl + compositeDegree == c2lvl) { + ModReduceInternalInPlace(ciphertext1, compositeDegree); } else { double scf1 = ciphertext1->GetScalingFactor(); - double scf2 = cryptoParams->GetScalingFactorRealBig(c2lvl - 1); + double scf2 = cryptoParams->GetScalingFactorRealBig(c2lvl - compositeDegree); double scf = cryptoParams->GetScalingFactorReal(c1lvl); double q1 = cryptoParams->GetModReduceFactor(sizeQl1 - 1); + for (uint32_t j = 1; j < compositeDegree; j++) { + q1 *= cryptoParams->GetModReduceFactor(sizeQl1 - j - 1); + } EvalMultCoreInPlace(ciphertext1, scf2 / scf1 * q1 / scf); - ModReduceInternalInPlace(ciphertext1, BASE_NUM_LEVELS_TO_DROP); - if (c1lvl + 2 < c2lvl) { - LevelReduceInternalInPlace(ciphertext1, c2lvl - c1lvl - 2); + ModReduceInternalInPlace(ciphertext1, compositeDegree); + if (c1lvl + 2 * compositeDegree < c2lvl) { + LevelReduceInternalInPlace(ciphertext1, c2lvl - c1lvl - 2 * compositeDegree); } - ModReduceInternalInPlace(ciphertext1, BASE_NUM_LEVELS_TO_DROP); + ModReduceInternalInPlace(ciphertext1, compositeDegree); ciphertext1->SetScalingFactor(ciphertext2->GetScalingFactor()); } } @@ -564,13 +571,13 @@ void LeveledSHECKKSRNS::AdjustLevelsAndDepthInPlace(Ciphertext& cipher } else { double scf1 = ciphertext1->GetScalingFactor(); - double scf2 = cryptoParams->GetScalingFactorRealBig(c2lvl - 1); + double scf2 = cryptoParams->GetScalingFactorRealBig(c2lvl - compositeDegree); double scf = cryptoParams->GetScalingFactorReal(c1lvl); EvalMultCoreInPlace(ciphertext1, scf2 / scf1 / scf); - if (c1lvl + 1 < c2lvl) { - LevelReduceInternalInPlace(ciphertext1, c2lvl - c1lvl - 1); + if (c1lvl + compositeDegree < c2lvl) { + LevelReduceInternalInPlace(ciphertext1, c2lvl - c1lvl - compositeDegree); } - ModReduceInternalInPlace(ciphertext1, BASE_NUM_LEVELS_TO_DROP); + ModReduceInternalInPlace(ciphertext1, compositeDegree); ciphertext1->SetScalingFactor(ciphertext2->GetScalingFactor()); } } @@ -582,28 +589,34 @@ void LeveledSHECKKSRNS::AdjustLevelsAndDepthInPlace(Ciphertext& cipher double scf1 = ciphertext1->GetScalingFactor(); double scf = cryptoParams->GetScalingFactorReal(c2lvl); double q2 = cryptoParams->GetModReduceFactor(sizeQl2 - 1); + for (uint32_t j = 1; j < compositeDegree; j++) { + q2 *= cryptoParams->GetModReduceFactor(sizeQl2 - j - 1); + } EvalMultCoreInPlace(ciphertext2, scf1 / scf2 * q2 / scf); - ModReduceInternalInPlace(ciphertext2, BASE_NUM_LEVELS_TO_DROP); - if (c2lvl + 1 < c1lvl) { - LevelReduceInternalInPlace(ciphertext2, c1lvl - c2lvl - 1); + ModReduceInternalInPlace(ciphertext2, compositeDegree); + if (c2lvl + compositeDegree < c1lvl) { + LevelReduceInternalInPlace(ciphertext2, c1lvl - c2lvl - compositeDegree); } ciphertext2->SetScalingFactor(ciphertext1->GetScalingFactor()); } else { - if (c2lvl + 1 == c1lvl) { - ModReduceInternalInPlace(ciphertext2, BASE_NUM_LEVELS_TO_DROP); + if (c2lvl + compositeDegree == c1lvl) { + ModReduceInternalInPlace(ciphertext2, compositeDegree); } else { double scf2 = ciphertext2->GetScalingFactor(); - double scf1 = cryptoParams->GetScalingFactorRealBig(c1lvl - 1); + double scf1 = cryptoParams->GetScalingFactorRealBig(c1lvl - compositeDegree); double scf = cryptoParams->GetScalingFactorReal(c2lvl); double q2 = cryptoParams->GetModReduceFactor(sizeQl2 - 1); + for (uint32_t j = 1; j < compositeDegree; j++) { + q2 *= cryptoParams->GetModReduceFactor(sizeQl2 - j - 1); + } EvalMultCoreInPlace(ciphertext2, scf1 / scf2 * q2 / scf); - ModReduceInternalInPlace(ciphertext2, BASE_NUM_LEVELS_TO_DROP); - if (c2lvl + 2 < c1lvl) { - LevelReduceInternalInPlace(ciphertext2, c1lvl - c2lvl - 2); + ModReduceInternalInPlace(ciphertext2, compositeDegree); + if (c2lvl + 2 * compositeDegree < c1lvl) { + LevelReduceInternalInPlace(ciphertext2, c1lvl - c2lvl - 2 * compositeDegree); } - ModReduceInternalInPlace(ciphertext2, BASE_NUM_LEVELS_TO_DROP); + ModReduceInternalInPlace(ciphertext2, compositeDegree); ciphertext2->SetScalingFactor(ciphertext1->GetScalingFactor()); } } @@ -619,13 +632,13 @@ void LeveledSHECKKSRNS::AdjustLevelsAndDepthInPlace(Ciphertext& cipher } else { double scf2 = ciphertext2->GetScalingFactor(); - double scf1 = cryptoParams->GetScalingFactorRealBig(c1lvl - 1); + double scf1 = cryptoParams->GetScalingFactorRealBig(c1lvl - compositeDegree); double scf = cryptoParams->GetScalingFactorReal(c2lvl); EvalMultCoreInPlace(ciphertext2, scf1 / scf2 / scf); - if (c2lvl + 1 < c1lvl) { - LevelReduceInternalInPlace(ciphertext2, c1lvl - c2lvl - 1); + if (c2lvl + compositeDegree < c1lvl) { + LevelReduceInternalInPlace(ciphertext2, c1lvl - c2lvl - compositeDegree); } - ModReduceInternalInPlace(ciphertext2, BASE_NUM_LEVELS_TO_DROP); + ModReduceInternalInPlace(ciphertext2, compositeDegree); ciphertext2->SetScalingFactor(ciphertext1->GetScalingFactor()); } } @@ -645,8 +658,10 @@ void LeveledSHECKKSRNS::AdjustLevelsAndDepthToOneInPlace(Ciphertext& c AdjustLevelsAndDepthInPlace(ciphertext1, ciphertext2); if (ciphertext1->GetNoiseScaleDeg() == 2) { - ModReduceInternalInPlace(ciphertext1, BASE_NUM_LEVELS_TO_DROP); - ModReduceInternalInPlace(ciphertext2, BASE_NUM_LEVELS_TO_DROP); + const auto cryptoParams + = std::dynamic_pointer_cast(ciphertext1->GetCryptoParameters()); + ModReduceInternalInPlace(ciphertext1, cryptoParams->GetCompositeDegree()); + ModReduceInternalInPlace(ciphertext2, cryptoParams->GetCompositeDegree()); } } diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp index c2840ad3d..a85ab3b83 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp @@ -62,6 +62,15 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptrGetMultiplicationTechnique(); ProxyReEncryptionMode PREMode = cryptoParamsCKKSRNS->GetPREMode(); + // Determine appropriate composite degree automatically if scaling technique set to COMPOSITESCALINGAUTO + cryptoParamsCKKSRNS->ConfigureCompositeDegree(firstModSize); + uint32_t compositeDegree = cryptoParamsCKKSRNS->GetCompositeDegree(); + uint32_t registerWordSize = cryptoParamsCKKSRNS->GetRegisterWordSize(); + compositeDegree *= (uint32_t)1; // @fdiasmor: Avoid unused variable compilation error. + registerWordSize *= (uint32_t)1; // @fdiasmor: Avoid unused variable compilation error. + // Bookeeping unique prime moduli + // std::unordered_set moduliQRecord; + if ((PREMode != INDCPA) && (PREMode != NOT_SET)) { std::stringstream s; s << "This PRE mode " << PREMode << " is not supported for CKKSRNS"; @@ -73,7 +82,7 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptrGetStdLevel(); - uint32_t auxBits = AUXMODSIZE; + uint32_t auxBits = (scalTech == COMPOSITESCALINGAUTO || scalTech == COMPOSITESCALINGMANUAL) ? 30 : AUXMODSIZE; uint32_t n = cyclOrder / 2; uint32_t qBound = firstModSize + (numPrimes - 1) * scalingModSize + extraModSize; @@ -86,7 +95,12 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptr(hybridKSInfo); + if (scalTech == COMPOSITESCALINGAUTO || scalTech == COMPOSITESCALINGMANUAL) { + uint32_t tmpFactor = (compositeDegree == 2) ? 2 : 4; + qBound += ceil(ceil(static_cast(qBound) / numPartQ) / (tmpFactor * auxBits)) * tmpFactor * auxBits; + } else { + qBound += std::get<0>(hybridKSInfo); + } } // GAUSSIAN security constraint diff --git a/src/pke/lib/scheme/gen-cryptocontext-params-impl.cpp b/src/pke/lib/scheme/gen-cryptocontext-params-impl.cpp index 6f4d6940e..33204aa17 100644 --- a/src/pke/lib/scheme/gen-cryptocontext-params-impl.cpp +++ b/src/pke/lib/scheme/gen-cryptocontext-params-impl.cpp @@ -76,6 +76,8 @@ namespace lbcrypto { SET_TO_SCHEME_DEFAULT(SCHEME, numAdversarialQueries); \ SET_TO_SCHEME_DEFAULT(SCHEME, thresholdNumOfParties); \ SET_TO_SCHEME_DEFAULT(SCHEME, interactiveBootCompressionLevel); \ + SET_TO_SCHEME_DEFAULT(SCHEME, compositeDegree); \ + SET_TO_SCHEME_DEFAULT(SCHEME, registerWordSize); \ } void Params::SetToDefaults(SCHEME scheme) { switch (scheme) { @@ -163,6 +165,10 @@ Params::Params(const std::vector& vals) { thresholdNumOfParties = static_cast(std::stoul(*it)); if (!(++it)->empty()) interactiveBootCompressionLevel = convertToCompressionLevel(*it); + if (!(++it)->empty()) + compositeDegree = static_cast(std::stoul(*it)); + if (!(++it)->empty()) + registerWordSize = static_cast(std::stoul(*it)); } //==================================================================================================================== // clang-format off @@ -196,7 +202,9 @@ std::ostream& operator<<(std::ostream& os, const Params& obj) { << "; statisticalSecurity: " << obj.statisticalSecurity << "; numAdversarialQueries: " << obj.numAdversarialQueries << "; thresholdNumOfParties: " << obj.thresholdNumOfParties - << "; interactiveBootCompressionLevel: " << obj.interactiveBootCompressionLevel; + << "; interactiveBootCompressionLevel: " << obj.interactiveBootCompressionLevel + << "; compositeDegree: " << obj.compositeDegree + << "; registerWordSize: " << obj.registerWordSize; return os; } diff --git a/src/pke/lib/scheme/gen-cryptocontext-params-validation.cpp b/src/pke/lib/scheme/gen-cryptocontext-params-validation.cpp index 5146a1007..e6ae33619 100644 --- a/src/pke/lib/scheme/gen-cryptocontext-params-validation.cpp +++ b/src/pke/lib/scheme/gen-cryptocontext-params-validation.cpp @@ -46,7 +46,8 @@ void validateParametersForCryptocontext(const Params& parameters) { if (NOISE_FLOODING_MULTIPARTY == parameters.GetMultipartyMode()) { OPENFHE_THROW("NOISE_FLOODING_MULTIPARTY is not supported in CKKSRNS"); } - if (MAX_MODULUS_SIZE <= parameters.GetScalingModSize()) { + if (MAX_MODULUS_SIZE <= parameters.GetScalingModSize() + && COMPOSITESCALINGAUTO != parameters.GetScalingTechnique() && COMPOSITESCALINGMANUAL != parameters.GetScalingTechnique()) { OPENFHE_THROW("scalingModSize should be less than " + std::to_string(MAX_MODULUS_SIZE)); } if (30 != parameters.GetStatisticalSecurity()) { From fb50d7936d0c3ad7cc624e332afeb03bc3bf9faa Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 11 Dec 2024 17:51:43 -0800 Subject: [PATCH 02/21] Initial commit: adding composite scaling parameters and scaling tech mode. --- src/pke/examples/simple-composite-scaling.cpp | 267 ++++++++++++++++++ .../gen-cryptocontext-params-defaults.h | 2 +- .../ckksrns/ckksrns-cryptoparameters.cpp | 12 +- .../lib/scheme/ckksrns/ckksrns-leveledshe.cpp | 37 +-- .../ckksrns/ckksrns-parametergeneration.cpp | 19 +- 5 files changed, 308 insertions(+), 29 deletions(-) create mode 100644 src/pke/examples/simple-composite-scaling.cpp diff --git a/src/pke/examples/simple-composite-scaling.cpp b/src/pke/examples/simple-composite-scaling.cpp new file mode 100644 index 000000000..9dc4fce04 --- /dev/null +++ b/src/pke/examples/simple-composite-scaling.cpp @@ -0,0 +1,267 @@ +//================================================================================== +// BSD 2-Clause License +// +// Copyright (c) 2014-2022, NJIT, Duality Technologies Inc. and other contributors +// +// All rights reserved. +// +// Author TPOC: contact@openfhe.org +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//================================================================================== + +/* + Simple examples for CKKS + */ + +#define PROFILE + +#include "openfhe.h" +#include +#include + +using namespace lbcrypto; + +int main() { + // Step 1: Setup CryptoContext + + // A. Specify main parameters + /* A1) Multiplicative depth: + * The CKKS scheme we setup here will work for any computation + * that has a multiplicative depth equal to 'multDepth'. + * This is the maximum possible depth of a given multiplication, + * but not the total number of multiplications supported by the + * scheme. + * + * For example, computation f(x, y) = x^2 + x*y + y^2 + x + y has + * a multiplicative depth of 1, but requires a total of 3 multiplications. + * On the other hand, computation g(x_i) = x1*x2*x3*x4 can be implemented + * either as a computation of multiplicative depth 3 as + * g(x_i) = ((x1*x2)*x3)*x4, or as a computation of multiplicative depth 2 + * as g(x_i) = (x1*x2)*(x3*x4). + * + * For performance reasons, it's generally preferable to perform operations + * in the shorted multiplicative depth possible. + */ + uint32_t multDepth = 2; + + /* A2) Bit-length of scaling factor. + * CKKS works for real numbers, but these numbers are encoded as integers. + * For instance, real number m=0.01 is encoded as m'=round(m*D), where D is + * a scheme parameter called scaling factor. Suppose D=1000, then m' is 10 (an + * integer). Say the result of a computation based on m' is 130, then at + * decryption, the scaling factor is removed so the user is presented with + * the real number result of 0.13. + * + * Parameter 'scaleModSize' determines the bit-length of the scaling + * factor D, but not the scaling factor itself. The latter is implementation + * specific, and it may also vary between ciphertexts in certain versions of + * CKKS (e.g., in FLEXIBLEAUTO). + * + * Choosing 'scaleModSize' depends on the desired accuracy of the + * computation, as well as the remaining parameters like multDepth or security + * standard. This is because the remaining parameters determine how much noise + * will be incurred during the computation (remember CKKS is an approximate + * scheme that incurs small amounts of noise with every operation). The + * scaling factor should be large enough to both accommodate this noise and + * support results that match the desired accuracy. + */ + uint32_t firstModSize = 60; + uint32_t scaleModSize = 52; + + /* A3) Number of plaintext slots used in the ciphertext. + * CKKS packs multiple plaintext values in each ciphertext. + * The maximum number of slots depends on a security parameter called ring + * dimension. In this instance, we don't specify the ring dimension directly, + * but let the library choose it for us, based on the security level we + * choose, the multiplicative depth we want to support, and the scaling factor + * size. + * + * Please use method GetRingDimension() to find out the exact ring dimension + * being used for these parameters. Give ring dimension N, the maximum batch + * size is N/2, because of the way CKKS works. + */ + uint32_t batchSize = 8; + + /* + * The word size in bits of the target hardware architecture. + */ + uint32_t registerWordSize = 32; + + /* A4) Desired security level based on FHE standards. + * This parameter can take four values. Three of the possible values + * correspond to 128-bit, 192-bit, and 256-bit security, and the fourth value + * corresponds to "NotSet", which means that the user is responsible for + * choosing security parameters. Naturally, "NotSet" should be used only in + * non-production environments, or by experts who understand the security + * implications of their choices. + * + * If a given security level is selected, the library will consult the current + * security parameter tables defined by the FHE standards consortium + * (https://homomorphicencryption.org/introduction/) to automatically + * select the security parameters. Please see "TABLES of RECOMMENDED + * PARAMETERS" in the following reference for more details: + * http://homomorphicencryption.org/wp-content/uploads/2018/11/HomomorphicEncryptionStandardv1.1.pdf + */ + CCParams parameters; + parameters.SetMultiplicativeDepth(multDepth); + parameters.SetFirstModSize(firstModSize); + parameters.SetScalingModSize(scaleModSize); + parameters.SetBatchSize(batchSize); + + parameters.SetScalingTechnique(COMPOSITESCALINGAUTO); + parameters.SetRegisterWordSize(registerWordSize); + + CryptoContext cc = GenCryptoContext(parameters); + const auto cryptoParamsCKKSRNS = std::dynamic_pointer_cast(cc->GetCryptoParameters()); + std::cout << "Composite Degree: " << cryptoParamsCKKSRNS->GetCompositeDegree() << "\nPrime Modulus Size: " + << static_cast(scaleModSize) / cryptoParamsCKKSRNS->GetCompositeDegree() + << "\nRegister Word Size: " << registerWordSize << std::endl; + + // Enable the features that you wish to use + cc->Enable(PKE); + cc->Enable(KEYSWITCH); + cc->Enable(LEVELEDSHE); + std::cout << "CKKS scheme is using ring dimension " << cc->GetRingDimension() << std::endl << std::endl; + + // B. Step 2: Key Generation + /* B1) Generate encryption keys. + * These are used for encryption/decryption, as well as in generating + * different kinds of keys. + */ + auto keys = cc->KeyGen(); + + /* B2) Generate the digit size + * In CKKS, whenever someone multiplies two ciphertexts encrypted with key s, + * we get a result with some components that are valid under key s, and + * with an additional component that's valid under key s^2. + * + * In most cases, we want to perform relinearization of the multiplicaiton + * result, i.e., we want to transform the s^2 component of the ciphertext so + * it becomes valid under original key s. To do so, we need to create what we + * call a relinearization key with the following line. + */ + cc->EvalMultKeyGen(keys.secretKey); + + /* B3) Generate the rotation keys + * CKKS supports rotating the contents of a packed ciphertext, but to do so, + * we need to create what we call a rotation key. This is done with the + * following call, which takes as input a vector with indices that correspond + * to the rotation offset we want to support. Negative indices correspond to + * right shift and positive to left shift. Look at the output of this demo for + * an illustration of this. + * + * Keep in mind that rotations work over the batch size or entire ring dimension (if the batch size is not specified). + * This means that, if ring dimension is 8 and batch + * size is not specified, then an input (1,2,3,4,0,0,0,0) rotated by 2 will become + * (3,4,0,0,0,0,1,2) and not (3,4,1,2,0,0,0,0). + * If ring dimension is 8 and batch + * size is set to 4, then the rotation of (1,2,3,4) by 2 will become (3,4,1,2). + * Also, as someone can observe + * in the output of this demo, since CKKS is approximate, zeros are not exact + * - they're just very small numbers. + */ + cc->EvalRotateKeyGen(keys.secretKey, {1, -2}); + + // Step 3: Encoding and encryption of inputs + + // Inputs + std::vector x1 = {0.25, 0.5, 0.75, 1.0, 2.0, 3.0, 4.0, 5.0}; + std::vector x2 = {5.0, 4.0, 3.0, 2.0, 1.0, 0.75, 0.5, 0.25}; + + // Encoding as plaintexts + Plaintext ptxt1 = cc->MakeCKKSPackedPlaintext(x1); + Plaintext ptxt2 = cc->MakeCKKSPackedPlaintext(x2); + + std::cout << "Input x1: " << ptxt1 << std::endl; + std::cout << "Input x2: " << ptxt2 << std::endl; + + // Encrypt the encoded vectors + auto c1 = cc->Encrypt(keys.publicKey, ptxt1); + auto c2 = cc->Encrypt(keys.publicKey, ptxt2); + + // Step 4: Evaluation + + // Homomorphic addition + auto cAdd = cc->EvalAdd(c1, c2); + + // Homomorphic subtraction + auto cSub = cc->EvalSub(c1, c2); + + // Homomorphic scalar multiplication + auto cScalar = cc->EvalMult(c1, 4.0); + + // Homomorphic multiplication + auto cMul = cc->EvalMult(c1, c2); + + // Homomorphic rotations + auto cRot1 = cc->EvalRotate(c1, 1); + auto cRot2 = cc->EvalRotate(c1, -2); + + // Step 5: Decryption and output + Plaintext result; + // We set the cout precision to 8 decimal digits for a nicer output. + // If you want to see the error/noise introduced by CKKS, bump it up + // to 15 and it should become visible. + std::cout.precision(8); + + std::cout << std::endl << "Results of homomorphic computations: " << std::endl; + + cc->Decrypt(keys.secretKey, c1, &result); + result->SetLength(batchSize); + std::cout << "x1 = " << result; + std::cout << "Estimated precision in bits: " << result->GetLogPrecision() << std::endl; + + // Decrypt the result of addition + cc->Decrypt(keys.secretKey, cAdd, &result); + result->SetLength(batchSize); + std::cout << "x1 + x2 = " << result; + std::cout << "Estimated precision in bits: " << result->GetLogPrecision() << std::endl; + + // Decrypt the result of subtraction + cc->Decrypt(keys.secretKey, cSub, &result); + result->SetLength(batchSize); + std::cout << "x1 - x2 = " << result << std::endl; + + // Decrypt the result of scalar multiplication + cc->Decrypt(keys.secretKey, cScalar, &result); + result->SetLength(batchSize); + std::cout << "4 * x1 = " << result << std::endl; + + // Decrypt the result of multiplication + cc->Decrypt(keys.secretKey, cMul, &result); + result->SetLength(batchSize); + std::cout << "x1 * x2 = " << result << std::endl; + + // Decrypt the result of rotations + + cc->Decrypt(keys.secretKey, cRot1, &result); + result->SetLength(batchSize); + std::cout << std::endl << "In rotations, very small outputs (~10^-10 here) correspond to 0's:" << std::endl; + std::cout << "x1 rotate by 1 = " << result << std::endl; + + cc->Decrypt(keys.secretKey, cRot2, &result); + result->SetLength(batchSize); + std::cout << "x1 rotate by -2 = " << result << std::endl; + + return 0; +} diff --git a/src/pke/include/scheme/gen-cryptocontext-params-defaults.h b/src/pke/include/scheme/gen-cryptocontext-params-defaults.h index 461b60f12..db03ee39d 100644 --- a/src/pke/include/scheme/gen-cryptocontext-params-defaults.h +++ b/src/pke/include/scheme/gen-cryptocontext-params-defaults.h @@ -101,7 +101,7 @@ constexpr uint32_t multiplicativeDepth = 1; #if defined(HAVE_INT128) || NATIVEINT != 64 constexpr uint32_t scalingModSize = 60; #else -constexpr uint32_t scalingModSize = 57; +constexpr uint32_t scalingModSize = 57; #endif constexpr SecurityLevel securityLevel = HEStd_128_classic; constexpr uint32_t ringDim = 0; diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp index bc39c8559..d54060c39 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp @@ -38,6 +38,8 @@ CKKS implementation. See https://eprint.iacr.org/2020/1118 for details. #include "cryptocontext.h" #include "scheme/ckksrns/ckksrns-cryptoparameters.h" +#include + namespace lbcrypto { // Precomputation of CRT tables encryption, decryption, and homomorphic @@ -47,9 +49,9 @@ void CryptoParametersCKKSRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Sca uint32_t numPartQ, uint32_t auxBits, uint32_t extraBits) { CryptoParametersRNS::PrecomputeCRTTables(ksTech, scalTech, encTech, multTech, numPartQ, auxBits, extraBits); - size_t sizeQ = GetElementParams()->GetParams().size(); + size_t sizeQ = GetElementParams()->GetParams().size(); uint32_t compositeDegree = this->GetCompositeDegree(); - compositeDegree = (compositeDegree == 0) ? 1 : compositeDegree; + compositeDegree = (compositeDegree == 0) ? 1 : compositeDegree; std::vector moduliQ(sizeQ); std::vector rootsQ(sizeQ); @@ -162,11 +164,11 @@ void CryptoParametersCKKSRNS::ConfigureCompositeDegree(uint32_t scalingModSize) if (GetScalingTechnique() == COMPOSITESCALINGAUTO) { if (NATIVEINT != 64) OPENFHE_THROW(config_error, "COMPOSITESCALINGAUTO scaling technique only supported with NATIVEINT==64."); - usint compositeDegree = GetCompositeDegree(); - usint registerWordSize = GetRegisterWordSize(); + uint32_t compositeDegree = GetCompositeDegree(); + uint32_t registerWordSize = GetRegisterWordSize(); if (registerWordSize <= 64) { if (registerWordSize < scalingModSize) { - compositeDegree = (uint32_t)std::ceil(static_cast(scalingModSize) / registerWordSize); + compositeDegree = static_cast(std::ceil(static_cast(scalingModSize) / registerWordSize)); // Assert minimum allowed moduli size on composite scaling mode // @fdiasmor TODO: make it more robust for a range of multiplicative depth if (static_cast(scalingModSize) / compositeDegree < 21) { diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp index 7ec37b0aa..198568f3f 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp @@ -42,6 +42,11 @@ CKKS implementation. See https://eprint.iacr.org/2020/1118 for details. #include "schemebase/base-scheme.h" +#include +#include +#include +#include + namespace lbcrypto { ///////////////////////////////////////// @@ -120,7 +125,7 @@ void LeveledSHECKKSRNS::ModReduceInternalInPlace(Ciphertext& ciphertex } } - ciphertext->SetNoiseScaleDeg(ciphertext->GetNoiseScaleDeg() - levels / cryptoParams->GetCompositeDegree()); + ciphertext->SetNoiseScaleDeg(ciphertext->GetNoiseScaleDeg() - levels / cryptoParams->GetCompositeDegree()); ciphertext->SetLevel(ciphertext->GetLevel() + levels); for (usint i = 0; i < levels; ++i) { @@ -186,7 +191,7 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalAddOrSub(Cons } DCRTPoly::Integer intPowP; - int64_t powp64 = ((int64_t)1) << precision; + int64_t powp64 = (static_cast(1)) << precision; if (pCurrent < 0) { intPowP = NativeInteger((uint128_t)powp64 >> (-pCurrent)); } @@ -258,7 +263,7 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalAddOrSub(Cons int32_t logStep = (logApprox <= LargeScalingFactorConstants::MAX_LOG_STEP) ? logApprox : LargeScalingFactorConstants::MAX_LOG_STEP; - DCRTPoly::Integer intStep = uint64_t(1) << logStep; + DCRTPoly::Integer intStep = static_cast(1) << logStep; std::vector crtApprox(sizeQl, intStep); logApprox -= logStep; @@ -266,7 +271,7 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalAddOrSub(Cons int32_t logStep = (logApprox <= LargeScalingFactorConstants::MAX_LOG_STEP) ? logApprox : LargeScalingFactorConstants::MAX_LOG_STEP; - DCRTPoly::Integer intStep = uint64_t(1) << logStep; + DCRTPoly::Integer intStep = static_cast(1) << logStep; std::vector crtSF(sizeQl, intStep); crtApprox = CKKSPackedEncoding::CRTMult(crtApprox, crtSF, moduli); logApprox -= logStep; @@ -386,7 +391,7 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalMult(ConstCip DoubleInteger large = static_cast(operand / approxFactor * scFactor + 0.5); DoubleInteger large_abs = (large < 0 ? -large : large); - DoubleInteger bound = (uint64_t)1 << 63; + DoubleInteger bound = static_cast(1) << 63; std::vector factors(numTowers); @@ -412,7 +417,7 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalMult(ConstCip int32_t logStep = (logApprox <= LargeScalingFactorConstants::MAX_LOG_STEP) ? logApprox : LargeScalingFactorConstants::MAX_LOG_STEP; - DCRTPoly::Integer intStep = uint64_t(1) << logStep; + DCRTPoly::Integer intStep = static_cast(1) << logStep; std::vector crtApprox(numTowers, intStep); logApprox -= logStep; @@ -420,7 +425,7 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalMult(ConstCip int32_t logStep = (logApprox <= LargeScalingFactorConstants::MAX_LOG_STEP) ? logApprox : LargeScalingFactorConstants::MAX_LOG_STEP; - DCRTPoly::Integer intStep = uint64_t(1) << logStep; + DCRTPoly::Integer intStep = static_cast(1) << logStep; std::vector crtSF(numTowers, intStep); crtApprox = CKKSPackedEncoding::CRTMult(crtApprox, crtSF, moduli); logApprox -= logStep; @@ -512,13 +517,13 @@ void LeveledSHECKKSRNS::MultByIntegerInPlace(Ciphertext& ciphertext, u void LeveledSHECKKSRNS::AdjustLevelsAndDepthInPlace(Ciphertext& ciphertext1, Ciphertext& ciphertext2) const { - const auto cryptoParams = std::dynamic_pointer_cast(ciphertext1->GetCryptoParameters()); - usint c1lvl = ciphertext1->GetLevel(); - usint c2lvl = ciphertext2->GetLevel(); - usint c1depth = ciphertext1->GetNoiseScaleDeg(); - usint c2depth = ciphertext2->GetNoiseScaleDeg(); - auto sizeQl1 = ciphertext1->GetElements()[0].GetNumOfElements(); - auto sizeQl2 = ciphertext2->GetElements()[0].GetNumOfElements(); + const auto cryptoParams = std::dynamic_pointer_cast(ciphertext1->GetCryptoParameters()); + usint c1lvl = ciphertext1->GetLevel(); + usint c2lvl = ciphertext2->GetLevel(); + usint c1depth = ciphertext1->GetNoiseScaleDeg(); + usint c2depth = ciphertext2->GetNoiseScaleDeg(); + auto sizeQl1 = ciphertext1->GetElements()[0].GetNumOfElements(); + auto sizeQl2 = ciphertext2->GetElements()[0].GetNumOfElements(); uint32_t compositeDegree = cryptoParams->GetCompositeDegree(); if (c1lvl < c2lvl) { @@ -658,8 +663,8 @@ void LeveledSHECKKSRNS::AdjustLevelsAndDepthToOneInPlace(Ciphertext& c AdjustLevelsAndDepthInPlace(ciphertext1, ciphertext2); if (ciphertext1->GetNoiseScaleDeg() == 2) { - const auto cryptoParams - = std::dynamic_pointer_cast(ciphertext1->GetCryptoParameters()); + const auto cryptoParams = + std::dynamic_pointer_cast(ciphertext1->GetCryptoParameters()); ModReduceInternalInPlace(ciphertext1, cryptoParams->GetCompositeDegree()); ModReduceInternalInPlace(ciphertext2, cryptoParams->GetCompositeDegree()); } diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp index a85ab3b83..95186e109 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp @@ -39,6 +39,10 @@ CKKS implementation. See https://eprint.iacr.org/2020/1118 for details. #include "scheme/ckksrns/ckksrns-cryptoparameters.h" #include "scheme/ckksrns/ckksrns-parametergeneration.h" +#include +#include +#include + namespace lbcrypto { #if NATIVEINT == 128 && !defined(__EMSCRIPTEN__) @@ -64,10 +68,10 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptrConfigureCompositeDegree(firstModSize); - uint32_t compositeDegree = cryptoParamsCKKSRNS->GetCompositeDegree(); - uint32_t registerWordSize = cryptoParamsCKKSRNS->GetRegisterWordSize(); - compositeDegree *= (uint32_t)1; // @fdiasmor: Avoid unused variable compilation error. - registerWordSize *= (uint32_t)1; // @fdiasmor: Avoid unused variable compilation error. + uint32_t compositeDegree = cryptoParamsCKKSRNS->GetCompositeDegree(); + uint32_t registerWordSize = cryptoParamsCKKSRNS->GetRegisterWordSize(); + compositeDegree *= static_cast(1); // @fdiasmor: Avoid unused variable compilation error. + registerWordSize *= static_cast(1); // @fdiasmor: Avoid unused variable compilation error. // Bookeeping unique prime moduli // std::unordered_set moduliQRecord; @@ -96,9 +100,10 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptr(qBound) / numPartQ) / (tmpFactor * auxBits)) * tmpFactor * auxBits; - } else { + uint32_t tmpFactor = (compositeDegree == 2) ? 2 : 4; + qBound += ceil(ceil(static_cast(qBound) / numPartQ) / (tmpFactor * auxBits)) * tmpFactor * auxBits; + } + else { qBound += std::get<0>(hybridKSInfo); } } From d3c1a582ec30ff42e5dfab0da2d8a794fb6f8d00 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Sun, 15 Dec 2024 19:17:56 -0800 Subject: [PATCH 03/21] Composite prime generation and adaptive scaling factors. --- .../ckksrns/ckksrns-parametergeneration.h | 10 + src/pke/lib/encoding/ckkspackedencoding.cpp | 15 +- .../ckksrns/ckksrns-cryptoparameters.cpp | 55 +- .../ckksrns/ckksrns-parametergeneration.cpp | 497 ++++++++++++++++-- 4 files changed, 522 insertions(+), 55 deletions(-) diff --git a/src/pke/include/scheme/ckksrns/ckksrns-parametergeneration.h b/src/pke/include/scheme/ckksrns/ckksrns-parametergeneration.h index 7b1cdbb95..ec41f4a6a 100644 --- a/src/pke/include/scheme/ckksrns/ckksrns-parametergeneration.h +++ b/src/pke/include/scheme/ckksrns/ckksrns-parametergeneration.h @@ -34,6 +34,7 @@ #include "schemerns/rns-parametergeneration.h" +#include #include #include @@ -44,6 +45,15 @@ namespace lbcrypto { class ParameterGenerationCKKSRNS : public ParameterGenerationRNS { +protected: + void CompositePrimeModuliGen(std::vector& moduliQ, std::vector& rootsQ, + uint32_t compositeDegree, uint32_t numPrimes, uint32_t firstModSize, uint32_t dcrtBits, + uint32_t cyclOrder, uint32_t registerWordSize) const; + + void SinglePrimeModuliGen(std::vector& moduliQ, std::vector& rootsQ, + ScalingTechnique scalTech, uint32_t numPrimes, uint32_t firstModSize, uint32_t dcrtBits, + uint32_t cyclOrder, uint32_t extraModsize) const; + public: virtual ~ParameterGenerationCKKSRNS() {} diff --git a/src/pke/lib/encoding/ckkspackedencoding.cpp b/src/pke/lib/encoding/ckkspackedencoding.cpp index b8bd4b576..aa6701b4f 100644 --- a/src/pke/lib/encoding/ckkspackedencoding.cpp +++ b/src/pke/lib/encoding/ckkspackedencoding.cpp @@ -43,6 +43,9 @@ #include #include #include +#include +#include +#include namespace lbcrypto { @@ -186,7 +189,7 @@ bool CKKSPackedEncoding::Encode() { im = im64 >> (-pRemaining); } else { - int128_t pPowRemaining = ((int64_t)1) << pRemaining; + int128_t pPowRemaining = (static_cast(1)) << pRemaining; im = pPowRemaining * im64; } @@ -396,13 +399,13 @@ bool CKKSPackedEncoding::Encode() { int32_t MAX_LOG_STEP = 60; if (logApprox > 0) { int32_t logStep = (logApprox <= MAX_LOG_STEP) ? logApprox : MAX_LOG_STEP; - DCRTPoly::Integer intStep = uint64_t(1) << logStep; + DCRTPoly::Integer intStep = static_cast(1) << logStep; std::vector crtApprox(numTowers, intStep); logApprox -= logStep; while (logApprox > 0) { int32_t logStep = (logApprox <= MAX_LOG_STEP) ? logApprox : MAX_LOG_STEP; - DCRTPoly::Integer intStep = uint64_t(1) << logStep; + DCRTPoly::Integer intStep = static_cast(1) << logStep; std::vector crtSF(numTowers, intStep); crtApprox = CRTMult(crtApprox, crtSF, moduli); logApprox -= logStep; @@ -434,7 +437,8 @@ bool CKKSPackedEncoding::Decode(size_t noiseScaleDeg, double scalingFactor, Scal std::vector> curValues(slots); if (this->typeFlag == IsNativePoly) { - if (scalTech == FLEXIBLEAUTO || scalTech == FLEXIBLEAUTOEXT) + if (scalTech == FLEXIBLEAUTO || scalTech == FLEXIBLEAUTOEXT || scalTech == COMPOSITESCALINGAUTO || + scalTech == COMPOSITESCALINGMANUAL) powP = pow(scalingFactor, -1); else powP = pow(2, -p); @@ -466,7 +470,8 @@ bool CKKSPackedEncoding::Decode(size_t noiseScaleDeg, double scalingFactor, Scal // we will bring down the scaling factor to 2^p double scalingFactorPre = 0.0; - if (scalTech == FLEXIBLEAUTO || scalTech == FLEXIBLEAUTOEXT) + if (scalTech == FLEXIBLEAUTO || scalTech == FLEXIBLEAUTOEXT || scalTech == COMPOSITESCALINGAUTO || + scalTech == COMPOSITESCALINGMANUAL) scalingFactorPre = pow(scalingFactor, -1) * pow(2, p); else scalingFactorPre = pow(2, -p * (noiseScaleDeg - 1)); diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp index d54060c39..a059eaa9c 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp @@ -51,7 +51,7 @@ void CryptoParametersCKKSRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Sca size_t sizeQ = GetElementParams()->GetParams().size(); uint32_t compositeDegree = this->GetCompositeDegree(); - compositeDegree = (compositeDegree == 0) ? 1 : compositeDegree; + // compositeDegree = (compositeDegree == 0) ? 1 : compositeDegree; std::vector moduliQ(sizeQ); std::vector rootsQ(sizeQ); @@ -90,13 +90,15 @@ void CryptoParametersCKKSRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Sca m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { m_scalingFactorsReal.resize(sizeQ); - if ((sizeQ == 1) && (extraBits == 0)) { + if ((sizeQ == 1) && (extraBits == 0) && (m_scalTechnique != COMPOSITESCALINGAUTO) && + (m_scalTechnique != COMPOSITESCALINGMANUAL)) { // mult depth = 0 and FLEXIBLEAUTO // when multiplicative depth = 0, we use the scaling mod size instead of modulus size // Plaintext modulus is used in EncodingParamsImpl to store the exponent p of the scaling factor m_scalingFactorsReal[0] = pow(2, GetPlaintextModulus()); } - else if ((sizeQ == 2) && (extraBits > 0)) { + else if ((sizeQ == 2) && (extraBits > 0) && (m_scalTechnique != COMPOSITESCALINGAUTO) && + (m_scalTechnique != COMPOSITESCALINGMANUAL)) { // mult depth = 0 and FLEXIBLEAUTOEXT // when multiplicative depth = 0, we use the scaling mod size instead of modulus size // Plaintext modulus is used in EncodingParamsImpl to store the exponent p of the scaling factor @@ -105,19 +107,45 @@ void CryptoParametersCKKSRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Sca } else { m_scalingFactorsReal[0] = moduliQ[sizeQ - 1].ConvertToDouble(); - if (extraBits > 0) + if (m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { + for (uint32_t j = 1; j < compositeDegree; j++) { + m_scalingFactorsReal[0] *= moduliQ[sizeQ - j - 1].ConvertToDouble(); + } + } + if (extraBits > 0 && m_scalTechnique != COMPOSITESCALINGAUTO && m_scalTechnique != COMPOSITESCALINGMANUAL) m_scalingFactorsReal[1] = moduliQ[sizeQ - 2].ConvertToDouble(); + const double lastPresetFactor = (extraBits == 0) ? m_scalingFactorsReal[0] : m_scalingFactorsReal[1]; // number of levels with pre-calculated factors - const size_t numPresetFactors = (extraBits == 0) ? 1 : 2; + const size_t numPresetFactors = (extraBits == 0 || (m_scalTechnique == COMPOSITESCALINGAUTO || + m_scalTechnique == COMPOSITESCALINGMANUAL)) ? + 1 : + 2; for (size_t k = numPresetFactors; k < sizeQ; k++) { - double prevSF = m_scalingFactorsReal[k - 1]; - m_scalingFactorsReal[k] = prevSF * prevSF / moduliQ[sizeQ - k].ConvertToDouble(); - double ratio = m_scalingFactorsReal[k] / lastPresetFactor; - if (ratio <= 0.5 || ratio >= 2.0) - OPENFHE_THROW( - "FLEXIBLEAUTO cannot support this number of levels in this parameter setting. Please use FIXEDMANUAL or FIXEDAUTO instead."); + if (m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { + if (k % compositeDegree == 0) { + double prevSF = m_scalingFactorsReal[k - compositeDegree]; + m_scalingFactorsReal[k] = prevSF * prevSF; + for (uint32_t j = 0; j < compositeDegree; j++) { + m_scalingFactorsReal[k] /= moduliQ[sizeQ - k + j].ConvertToDouble(); + } + } + else { + m_scalingFactorsReal[k] = 1; + } + } + else { + double prevSF = m_scalingFactorsReal[k - 1]; + m_scalingFactorsReal[k] = prevSF * prevSF / moduliQ[sizeQ - k].ConvertToDouble(); + } + + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT) { + double ratio = m_scalingFactorsReal[k] / lastPresetFactor; + if (ratio <= 0.5 || ratio >= 2.0) + OPENFHE_THROW( + "FLEXIBLEAUTO cannot support this number of levels in this parameter setting. Please use FIXEDMANUAL or FIXEDAUTO instead."); + } } } @@ -168,10 +196,11 @@ void CryptoParametersCKKSRNS::ConfigureCompositeDegree(uint32_t scalingModSize) uint32_t registerWordSize = GetRegisterWordSize(); if (registerWordSize <= 64) { if (registerWordSize < scalingModSize) { - compositeDegree = static_cast(std::ceil(static_cast(scalingModSize) / registerWordSize)); + compositeDegree = + static_cast(std::ceil(static_cast(scalingModSize) / registerWordSize)); // Assert minimum allowed moduli size on composite scaling mode // @fdiasmor TODO: make it more robust for a range of multiplicative depth - if (static_cast(scalingModSize) / compositeDegree < 21) { + if (static_cast(scalingModSize) / compositeDegree < 22) { OPENFHE_THROW( config_error, "Moduli size is too short (< 21) for target multiplicative depth. Consider increasing the scaling factor or the register word size."); diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp index 95186e109..79b0844c6 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp @@ -42,6 +42,8 @@ CKKS implementation. See https://eprint.iacr.org/2020/1118 for details. #include #include #include +#include +#include namespace lbcrypto { @@ -75,6 +77,26 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptr moduliQRecord; + if (scalTech == COMPOSITESCALINGAUTO || scalTech == COMPOSITESCALINGMANUAL) { + if (compositeDegree > 2 && (firstModSize <= 68 || scalingModSize <= 67)) { + OPENFHE_THROW( + config_error, + "This COMPOSITESCALING* version does not fully support composite degree > 2 for small prime moduli. Prime moduli size must generally be greater than 22."); + } + else if (compositeDegree == 1 && registerWordSize < 32) { + OPENFHE_THROW(config_error, "This COMPOSITESCALING* version does not support composite degree == 1."); + } + else if (compositeDegree < 1) { + OPENFHE_THROW(config_error, "Composite degree must be greater than or equal to 1."); + } + + if (registerWordSize < 24 && scalTech == COMPOSITESCALINGAUTO) { + OPENFHE_THROW( + config_error, + "Register word size must be greater than or equal to 24 for COMPOSITESCALINGAUTO. Otherwise, try it with COMPOSITESCALINGMANUAL."); + } + } + if ((PREMode != INDCPA) && (PREMode != NOT_SET)) { std::stringstream s; s << "This PRE mode " << PREMode << " is not supported for CKKSRNS"; @@ -147,10 +169,448 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptr moduliQ(vecSize); std::vector rootsQ(vecSize); + if (scalTech == COMPOSITESCALINGAUTO || scalTech == COMPOSITESCALINGMANUAL) { + if (compositeDegree > 1) { + CompositePrimeModuliGen(moduliQ, rootsQ, compositeDegree, numPrimes, firstModSize, dcrtBits, cyclOrder, + registerWordSize); + } + else { + SinglePrimeModuliGen(moduliQ, rootsQ, scalTech, numPrimes, firstModSize, dcrtBits, cyclOrder, extraModSize); + } + } + else { + SinglePrimeModuliGen(moduliQ, rootsQ, scalTech, numPrimes, firstModSize, dcrtBits, cyclOrder, extraModSize); + } + + auto paramsDCRT = std::make_shared>(cyclOrder, moduliQ, rootsQ); + + cryptoParamsCKKSRNS->SetElementParams(paramsDCRT); + + // if no batch size was specified, we set batchSize = n/2 by default (for full packing) + if (encodingParams->GetBatchSize() == 0) { + uint32_t batchSize = n / 2; + EncodingParams encodingParamsNew( + std::make_shared(encodingParams->GetPlaintextModulus(), batchSize)); + cryptoParamsCKKSRNS->SetEncodingParams(encodingParamsNew); + } + + cryptoParamsCKKSRNS->PrecomputeCRTTables(ksTech, scalTech, encTech, multTech, numPartQ, auxBits, extraModSize); + + // Validate the ring dimension found using estimated logQ(P) against actual logQ(P) + if (stdLevel != HEStd_NotSet) { + uint32_t logActualQ = 0; + if (ksTech == HYBRID) { + logActualQ = cryptoParamsCKKSRNS->GetParamsQP()->GetModulus().GetMSB(); + } + else { + logActualQ = cryptoParamsCKKSRNS->GetElementParams()->GetModulus().GetMSB(); + } + + uint32_t nActual = StdLatticeParm::FindRingDim(distType, stdLevel, logActualQ); + if (n < nActual) { + std::string errMsg("The ring dimension found using estimated logQ(P) ["); + errMsg += std::to_string(n) + "] does does not meet security requirements. "; + errMsg += "Report this problem to OpenFHE developers and set the ring dimension manually to "; + errMsg += std::to_string(nActual) + "."; + + OPENFHE_THROW(errMsg); + } + } + + return true; +} + +void ParameterGenerationCKKSRNS::CompositePrimeModuliGen(std::vector& moduliQ, + std::vector& rootsQ, usint compositeDegree, + usint numPrimes, usint firstModSize, usint dcrtBits, + usint cyclOrder, usint registerWordSize) const { + std::unordered_set moduliQRecord; + + std::cout << __FUNCTION__ << "::" << __LINE__ << " numPrimes=" << numPrimes + << " compositeDegree=" << compositeDegree << std::endl; + + // Sample q0, the first primes in the modulus chain + NativeInteger q; + uint32_t qBitSize = static_cast(dcrtBits) / compositeDegree; + uint32_t remBits = dcrtBits; + + for (uint32_t d = 1; d <= compositeDegree; ++d) { + // qBitSize = static_cast(std::ceil(static_cast(remBits) / (compositeDegree - d + 1))); + double numBits = static_cast(remBits) / (compositeDegree - d + 1); + qBitSize = std::ceil(numBits); + q = FirstPrime(qBitSize, cyclOrder); + q = PreviousPrime(q, cyclOrder); + while (std::log2(q.ConvertToDouble()) > registerWordSize || std::log2(q.ConvertToDouble()) > numBits || + moduliQRecord.find(q.ConvertToInt()) != moduliQRecord.end()) { + q = PreviousPrime(q, cyclOrder); + } + std::cout << __FUNCTION__ << "::" << __LINE__ << " d=" << d << " moduliQ=" << q + << " logq2=" << std::log2(q.ConvertToDouble()) << " remBits=" << remBits << "\n"; + std::cout << __FUNCTION__ << "::" << __LINE__ << " d=" << d << " moduliQ=" << q + << " logq2=" << std::log2(q.ConvertToDouble()) << "\n"; + moduliQ[numPrimes - d] = q; + rootsQ[numPrimes - d] = RootOfUnity(cyclOrder, moduliQ[numPrimes - d]); + moduliQRecord.emplace(q.ConvertToInt()); + remBits -= qBitSize; + // remBits -= std::ceil(std::log2(q.ConvertToDouble())); + } + +#ifdef DEBUG_COMPOSITE_SCALING + std::cout << __FUNCTION__ << "::" << __LINE__ << " numPrimes=" << numPrimes + << " compositeDegree=" << compositeDegree << std::endl; +#endif + + // std::vector qPrev(std::ceil(static_cast(compositeDegree) / 2)); + // std::vector qNext(compositeDegree - (uint32_t)qPrev.size()); + std::vector qPrev(1); + std::vector innerPrimes((compositeDegree > 2) ? compositeDegree - 2 : 1); + std::vector qNext(1); + bool altPrevNext = false; + + if (numPrimes > 1) { + // Prep to compute initial scaling factor + double sf = moduliQ[numPrimes - 1].ConvertToDouble(); + for (uint32_t d = 2; d <= compositeDegree; ++d) { + sf *= moduliQ[numPrimes - d].ConvertToDouble(); + std::cout << __FUNCTION__ << "::" << __LINE__ << " d=" << d << " moduliQ=" << q + << " logq2=" << std::log2(q.ConvertToDouble()) << " sf=" << sf << "\n"; + } + + std::cout << "Composite degree: " << compositeDegree << std::endl; + + uint32_t cnt = 1; + for (usint i = numPrimes - compositeDegree; i >= 2 * compositeDegree; i -= compositeDegree) { + std::cout << "Selecting Prime Moduli for L=" << i / compositeDegree << std::endl; + // Compute initial scaling factor + sf = static_cast(std::pow(sf, 2)); + for (usint d = 0; d < compositeDegree; ++d) { + std::cout << "moduliQ[" << i + d << "] = " << moduliQ[i + d] << ", "; + sf /= moduliQ[i + d].ConvertToDouble(); + } + std::cout << std::endl; + + // denom = moduliQ[i].ConvertToDouble(); + // for (usint d = 1; d < compositeDegree; ++d) { + // denom *= moduliQ[i + d].ConvertToDouble(); + // } + + auto sf_sqrt = std::pow(sf, 1.0 / compositeDegree); + // auto sf_sqrt = std::pow((sf * sf) / denom, 1.0 / compositeDegree); // std::sqrt((sf * sf) / denom); + std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " sf_sqrt=" << sf_sqrt + << " logsf_sqrt2=" << std::ceil(std::log2(sf_sqrt)) << " sf=" << sf << "\n"; + + qBitSize = std::ceil(std::log2(sf_sqrt)); + + NativeInteger sfInt = std::llround(sf_sqrt); + NativeInteger sfRem = sfInt.Mod(cyclOrder); + +#ifdef DEBUG_COMPOSITE_SCALING + std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " sfInt=" << sfInt + << " logq2=" << std::log2(sfInt.ConvertToDouble()) << "\n"; +#endif + double primeProduct = 1.0; + std::unordered_set qCurrentRecord; // current prime tracker + + // for (uint32_t step = 0; step < (uint32_t)qPrev.size(); ++step) { + // //qPrev[step] = sfInt - (NativeInteger(step + 1) * NativeInteger(cyclOrder)) - sfRem + NativeInteger(1); + // qPrev[step] = sfInt - sfRem + NativeInteger(1) - NativeInteger(cyclOrder); + // do { + // // if (step % 2 == 0) { + // // qPrev[step] = lbcrypto::PreviousPrime(qPrev[step], cyclOrder); + // // } else { + // // qPrev[step] = lbcrypto::NextPrime(qPrev[step], cyclOrder); + // // } + // qPrev[step] = lbcrypto::PreviousPrime(qPrev[step], cyclOrder); + // } while (//std::log2(qPrev[step].ConvertToDouble()) > qBitSize || + // std::log2(qPrev[step].ConvertToDouble()) > registerWordSize || + // moduliQRecord.find(qPrev[step].ConvertToInt()) != moduliQRecord.end() || + // qCurrentRecord.find(qPrev[step].ConvertToInt()) != qCurrentRecord.end()); + // qCurrentRecord.emplace(qPrev[step].ConvertToInt()); + // primeProduct *= qPrev[step].ConvertToDouble(); + // // sfInt = qPrev[step]; + // // sfRem = sfInt.Mod(cyclOrder); + // } + + for (uint32_t step = 0; step < compositeDegree - 2; step++) { + std::cout << "step: " << step << std::endl; + // innerPrimes[step] = sfInt - (NativeInteger(step + 1) * NativeInteger(cyclOrder)) - sfRem + NativeInteger(1); + // innerPrimes[step] = sfInt - sfRem + NativeInteger(1); + if (altPrevNext) { + innerPrimes[step] = sfInt - sfRem + NativeInteger(1) - NativeInteger(cyclOrder); + // innerPrimes[step] = lbcrypto::PreviousPrime(innerPrimes[step], cyclOrder); + } + else { + innerPrimes[step] = sfInt - sfRem + NativeInteger(1) + NativeInteger(cyclOrder); + // innerPrimes[step] = lbcrypto::NextPrime(innerPrimes[step], cyclOrder); + } + do { + switch (altPrevNext) { + case true: + innerPrimes[step] = lbcrypto::PreviousPrime(innerPrimes[step], cyclOrder); + break; + default: + innerPrimes[step] = lbcrypto::NextPrime(innerPrimes[step], cyclOrder); + break; + } + } while (std::log2(innerPrimes[step].ConvertToDouble()) > registerWordSize || + moduliQRecord.find(innerPrimes[step].ConvertToInt()) != moduliQRecord.end() || + qCurrentRecord.find(innerPrimes[step].ConvertToInt()) != qCurrentRecord.end()); + qCurrentRecord.emplace(innerPrimes[step].ConvertToInt()); + primeProduct *= innerPrimes[step].ConvertToDouble(); + + altPrevNext = !altPrevNext; + + sfInt = innerPrimes[step]; + sfRem = sfInt.Mod(cyclOrder); + } + + qPrev[0] = sfInt - sfRem + NativeInteger(1) - NativeInteger(cyclOrder); + do { + qPrev[0] = lbcrypto::PreviousPrime(qPrev[0], cyclOrder); + } while (std::log2(qPrev[0].ConvertToDouble()) > registerWordSize || + moduliQRecord.find(qPrev[0].ConvertToInt()) != moduliQRecord.end() || + qCurrentRecord.find(qPrev[0].ConvertToInt()) != qCurrentRecord.end()); + qCurrentRecord.emplace(qPrev[0].ConvertToInt()); + primeProduct *= qPrev[0].ConvertToDouble(); + sfInt = qPrev[0]; + sfRem = sfInt.Mod(cyclOrder); + + qNext[0] = sfInt - sfRem + NativeInteger(1) + NativeInteger(cyclOrder); + std::cout << "find last prime" << std::endl; + do { + std::cout << "qNext[0]: " << qNext[0] << std::endl; + qNext[0] = lbcrypto::NextPrime(qNext[0], cyclOrder); + } while (std::log2(qNext[0].ConvertToDouble()) > registerWordSize || + moduliQRecord.find(qNext[0].ConvertToInt()) != moduliQRecord.end() || + qCurrentRecord.find(qNext[0].ConvertToInt()) != qCurrentRecord.end()); + qCurrentRecord.emplace(qNext[0].ConvertToInt()); + primeProduct *= qNext[0].ConvertToDouble(); + sfInt = qNext[0]; + sfRem = sfInt.Mod(cyclOrder); + + // for (uint32_t step = 0; step < (uint32_t)qNext.size(); ++step) { + // // qNext[step] = sfInt + (NativeInteger(step + 1) * NativeInteger(cyclOrder)) - sfRem + NativeInteger(1); + // qNext[step] = sfInt - sfRem + NativeInteger(1) + NativeInteger(cyclOrder); + // // qBitSize = std::ceil(std::log2(qNext[step].ConvertToDouble())); + // // qNext[step] = FirstPrime(qBitSize, cyclOrder); + // // qNext[step] = NextPrime(q, cyclOrder); + // do { + // // if (step % 2) { + // // qNext[step] = lbcrypto::NextPrime(qNext[step], cyclOrder); + // // } else { + // // qNext[step] = lbcrypto::PreviousPrime(qNext[step], cyclOrder); + // // } + // qNext[step] = lbcrypto::NextPrime(qNext[step], cyclOrder); + // } while (//std::log2(qNext[step].ConvertToDouble()) > qBitSize || + // std::log2(qNext[step].ConvertToDouble()) > registerWordSize || + // moduliQRecord.find(qNext[step].ConvertToInt()) != moduliQRecord.end() || + // qCurrentRecord.find(qNext[step].ConvertToInt()) != qCurrentRecord.end()); + // qCurrentRecord.emplace(qNext[step].ConvertToInt()); + // primeProduct *= qNext[step].ConvertToDouble(); + // // sfInt = qNext[step]; + // // sfRem = sfInt.Mod(cyclOrder); + // } + +#ifdef DEBUG_COMPOSITE_SCALING + std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " primeProduct=" << primeProduct + << " sf=" << sf << "\n"; +#endif + + if (cnt == 0) { + // NativeInteger qPrevNext = NativeInteger(qNext[qNext.size() - 1].ConvertToInt()); + NativeInteger qPrevNext = NativeInteger(qNext[0].ConvertToInt()); +#ifdef DEBUG_COMPOSITE_SCALING + std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " qPrevPrev=" << qPrevPrev << "\n"; +#endif + while (primeProduct > sf) { + // while (primeProduct > sf0) { + do { + qCurrentRecord.erase(qPrevNext.ConvertToInt()); // constant time + qPrevNext = lbcrypto::PreviousPrime(qPrevNext, cyclOrder); + } while ( // std::log2(qPrevNext.ConvertToDouble()) > qBitSize || + std::log2(qPrevNext.ConvertToDouble()) > registerWordSize || + moduliQRecord.find(qPrevNext.ConvertToInt()) != moduliQRecord.end() || + qCurrentRecord.find(qPrevNext.ConvertToInt()) != qCurrentRecord.end()); + qCurrentRecord.emplace(qPrevNext.ConvertToInt()); + +#ifdef DEBUG_COMPOSITE_SCALING + std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " primeFound=" << qPrevPrev + << " primeProduct=" << primeProduct << " sf=" << sf << "\n"; +#endif + + // primeProduct /= qNext[qNext.size() - 1].ConvertToDouble(); + // qNext[qNext.size() - 1] = qPrevNext; + primeProduct /= qNext[0].ConvertToDouble(); + qNext[0] = qPrevNext; + primeProduct *= qPrevNext.ConvertToDouble(); + + if (std::log2(primeProduct) > std::log2(sf)) { + std::cout << "************* VIOLATION ************* cnt: " << cnt << std::endl; + std::cout << "primeProduct " << (numPrimes - i) / compositeDegree << ": " << primeProduct + << " > sf: " << sf << " log2(primeProduct): " << std::log2(primeProduct) + << " log2(sf): " << std::log2(sf) << std::endl; + } + +#ifdef DEBUG_COMPOSITE_SCALING + std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " qPrevPrev" << qPrevPrev + << " logq2=" << std::log2(qPrevPrev.ConvertToDouble()) << " primeProduct=" << primeProduct + << " sf=" << sf << "\n"; +#endif + } + + moduliQ[i - 1] = qPrev[0]; + for (uint32_t d = 2; d < compositeDegree; ++d) { + moduliQ[i - d] = innerPrimes[d - 2]; + } + moduliQ[i - compositeDegree] = qNext[0]; + + // uint32_t m = qPrev.size(); + // for (uint32_t d = 1; d <= m; ++d) { + // moduliQ[i - d] = qPrev[d - 1]; + // } + // for (uint32_t d = m+1; d <= compositeDegree; ++d) { + // moduliQ[i - d] = qNext[d - (m+1)]; + // } + + for (uint32_t d = 1; d <= compositeDegree; ++d) { + std::cout << __FUNCTION__ << "::" << __LINE__ << " i: " << i << " moduliQ: " << moduliQ[i - d] + << " logq2: " << std::log2(moduliQ[i - d].ConvertToDouble()) << "\n"; + rootsQ[i - d] = RootOfUnity(cyclOrder, moduliQ[i - d]); + moduliQRecord.emplace(moduliQ[i - d].ConvertToInt()); + } + + // //#ifdef DEBUG_COMPOSITE_SCALING + // std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " moduliQ=" << moduliQ[i - d] + // << " logq2=" << std::log2(moduliQ[i - d].ConvertToDouble()) << "\n"; + // //#endif + // rootsQ[i - d] = RootOfUnity(cyclOrder, moduliQ[i - d]); + // moduliQRecord.emplace(moduliQ[i - d].ConvertToInt()); + // } + cnt = 1; + } + else { + // NativeInteger qNextPrev = NativeInteger(qPrev[qPrev.size()-1].ConvertToInt()); + NativeInteger qNextPrev = NativeInteger(qPrev[0].ConvertToInt()); +#ifdef DEBUG_COMPOSITE_SCALING + std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " qNextNext=" << qNextNext << "\n"; +#endif + while (primeProduct < sf) { + // while (primeProduct < sf0) { + do { + qCurrentRecord.erase(qNextPrev.ConvertToInt()); // constant time + qNextPrev = lbcrypto::NextPrime(qNextPrev, cyclOrder); + } while ( // std::log2(qNextPrev.ConvertToDouble()) > qBitSize || + std::log2(qNextPrev.ConvertToDouble()) > registerWordSize || + moduliQRecord.find(qNextPrev.ConvertToInt()) != moduliQRecord.end() || + qCurrentRecord.find(qNextPrev.ConvertToInt()) != qCurrentRecord.end()); + qCurrentRecord.emplace(qNextPrev.ConvertToInt()); + +#ifdef DEBUG_COMPOSITE_SCALING + std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " primeFound=" << qNextNext + << " primeProduct=" << primeProduct << " sf=" << sf << "\n"; +#endif + // primeProduct /= qPrev[qPrev.size()-1].ConvertToDouble(); + // qPrev[qPrev.size()-1] = qNextPrev; + primeProduct /= qPrev[0].ConvertToDouble(); + qPrev[0] = qNextPrev; + primeProduct *= qNextPrev.ConvertToDouble(); + + if (std::log2(primeProduct) > std::log2(sf)) { + std::cout << "************* VIOLATION ************* cnt: " << cnt << std::endl; + std::cout << "primeProduct " << (numPrimes - i) / compositeDegree << ": " << primeProduct + << " > sf: " << sf << " log2(primeProduct): " << std::log2(primeProduct) + << " log2(sf): " << std::log2(sf) << std::endl; + } + +#ifdef DEBUG_COMPOSITE_SCALING + std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " qNextNext" << qNextNext + << " logq2=" << std::log2(qNextNext.ConvertToDouble()) << " primeProduct=" << primeProduct + << " sf=" << sf << "\n"; +#endif + } + + // assgin samples prime moduli to the chain + moduliQ[i - 1] = qPrev[0]; + for (uint32_t d = 2; d < compositeDegree; ++d) { + moduliQ[i - d] = innerPrimes[d - 2]; + } + moduliQ[i - compositeDegree] = qNext[0]; + + // uint32_t m = qPrev.size(); + // for (uint32_t d = 1; d <= m; ++d) { + // moduliQ[i - d] = qPrev[d - 1]; + // } + // for (uint32_t d = m+1; d <= compositeDegree; ++d) { + // moduliQ[i - d] = qNext[d - (m+1)]; + // } + + for (uint32_t d = 1; d <= compositeDegree; ++d) { + std::cout << __FUNCTION__ << "::" << __LINE__ << " i: " << i << " moduliQ: " << moduliQ[i - d] + << " logq2: " << std::log2(moduliQ[i - d].ConvertToDouble()) << "\n"; + rootsQ[i - d] = RootOfUnity(cyclOrder, moduliQ[i - d]); + moduliQRecord.emplace(moduliQ[i - d].ConvertToInt()); + } + + cnt = 0; + } + } // for loop + } // if numPrimes > 1 + + if (firstModSize == dcrtBits) { // this requires dcrtBits < 60 + OPENFHE_THROW(config_error, "firstModSize must be > scalingModSize."); + } + else { + qBitSize = 0; + remBits = static_cast(firstModSize); + for (uint32_t d = 1; d <= compositeDegree; ++d) { + qBitSize = std::ceil(static_cast(remBits) / (compositeDegree - d + 1)); + // Find next prime + NativeInteger nextInteger = FirstPrime(qBitSize, cyclOrder); + nextInteger = PreviousPrime(nextInteger, cyclOrder); + // nextInteger = NextPrime(nextInteger, cyclOrder); + // Ensure it fits in 32-bit register + while (std::log2(nextInteger.ConvertToDouble()) > qBitSize || + std::log2(nextInteger.ConvertToDouble()) > registerWordSize || + moduliQRecord.find(nextInteger.ConvertToInt()) != moduliQRecord.end()) + nextInteger = PreviousPrime(nextInteger, cyclOrder); + // nextInteger = NextPrime(nextInteger, cyclOrder); + // Store prime + moduliQ[d - 1] = nextInteger; + rootsQ[d - 1] = RootOfUnity(cyclOrder, moduliQ[d - 1]); + // Keep track of existing primes + moduliQRecord.emplace(moduliQ[d - 1].ConvertToInt()); + remBits -= qBitSize; + // #ifdef DEBUG_COMPOSITE_SCALING + std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << 1 << " moduliQ=" << moduliQ[d - 1] + << " logq2=" << std::log2(moduliQ[d - 1].ConvertToDouble()) << "\n"; + // #endif + } + } + +#ifdef DEBUG_COMPOSITE_SCALING + std::cout << __FUNCTION__ << "::" << __LINE__ << " prime moduli:" << std::endl; + for (size_t i = 0; i < moduliQ.size(); i++) { + std::cout << "moduliQ[" << i << "]=" << moduliQ[i] << " logq[" << i + << "]=" << std::log2(moduliQ[i].ConvertToDouble()) << std::endl; + } +#endif + + return; +} + +void ParameterGenerationCKKSRNS::SinglePrimeModuliGen(std::vector& moduliQ, + std::vector& rootsQ, ScalingTechnique scalTech, + uint32_t numPrimes, uint32_t firstModSize, uint32_t dcrtBits, + uint32_t cyclOrder, uint32_t extraModSize) const { NativeInteger q = FirstPrime(dcrtBits, cyclOrder); moduliQ[numPrimes - 1] = q; rootsQ[numPrimes - 1] = RootOfUnity(cyclOrder, moduliQ[numPrimes - 1]); @@ -263,43 +723,6 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptr>(cyclOrder, moduliQ, rootsQ); - - cryptoParamsCKKSRNS->SetElementParams(paramsDCRT); - - // if no batch size was specified, we set batchSize = n/2 by default (for full packing) - if (encodingParams->GetBatchSize() == 0) { - uint32_t batchSize = n / 2; - EncodingParams encodingParamsNew( - std::make_shared(encodingParams->GetPlaintextModulus(), batchSize)); - cryptoParamsCKKSRNS->SetEncodingParams(encodingParamsNew); - } - - cryptoParamsCKKSRNS->PrecomputeCRTTables(ksTech, scalTech, encTech, multTech, numPartQ, auxBits, extraModSize); - - // Validate the ring dimension found using estimated logQ(P) against actual logQ(P) - if (stdLevel != HEStd_NotSet) { - uint32_t logActualQ = 0; - if (ksTech == HYBRID) { - logActualQ = cryptoParamsCKKSRNS->GetParamsQP()->GetModulus().GetMSB(); - } - else { - logActualQ = cryptoParamsCKKSRNS->GetElementParams()->GetModulus().GetMSB(); - } - - uint32_t nActual = StdLatticeParm::FindRingDim(distType, stdLevel, logActualQ); - if (n < nActual) { - std::string errMsg("The ring dimension found using estimated logQ(P) ["); - errMsg += std::to_string(n) + "] does does not meet security requirements. "; - errMsg += "Report this problem to OpenFHE developers and set the ring dimension manually to "; - errMsg += std::to_string(nActual) + "."; - - OPENFHE_THROW(errMsg); - } - } - - return true; } } // namespace lbcrypto From e397a73c6704b6bd384d8a90cffbdc8fcf1fbe8c Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 16 Dec 2024 19:17:28 -0800 Subject: [PATCH 04/21] Propagating composite degree to mod reduce calls. --- ...ation-high-precision-composite-scaling.cpp | 249 ++++++++++++++++++ .../include/schemerns/rns-cryptoparameters.h | 24 +- .../scheme/ckksrns/ckksrns-advancedshe.cpp | 58 ++-- .../ckksrns/ckksrns-cryptoparameters.cpp | 2 +- src/pke/lib/schemebase/base-advancedshe.cpp | 20 +- src/pke/lib/schemebase/base-leveledshe.cpp | 16 +- src/pke/lib/schemerns/rns-leveledshe.cpp | 30 ++- 7 files changed, 353 insertions(+), 46 deletions(-) create mode 100644 src/pke/examples/polynomial-evaluation-high-precision-composite-scaling.cpp diff --git a/src/pke/examples/polynomial-evaluation-high-precision-composite-scaling.cpp b/src/pke/examples/polynomial-evaluation-high-precision-composite-scaling.cpp new file mode 100644 index 000000000..37d52bb54 --- /dev/null +++ b/src/pke/examples/polynomial-evaluation-high-precision-composite-scaling.cpp @@ -0,0 +1,249 @@ +//================================================================================== +// BSD 2-Clause License +// +// Copyright (c) 2014-2022, NJIT, Duality Technologies Inc. and other contributors +// +// All rights reserved. +// +// Author TPOC: contact@openfhe.org +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//================================================================================== + +/* + Example of polynomial evaluation using CKKS. + */ + +#define PROFILE // turns on the reporting of timing results + +#include "openfhe.h" +#include +#include + +using namespace lbcrypto; + +void printPrimeModuliChain(const DCRTPoly& poly) { + int num_primes = poly.GetNumOfElements(); + double total_bit_len = 0.0; + for (int i = 0; i < num_primes; i++) { + auto qi = poly.GetParams()->GetParams()[i]->GetModulus(); + std::cout << "q_" << i << ": " << qi << ", log q_" << i << ": " << log(qi.ConvertToDouble()) / log(2) + << std::endl; + total_bit_len += log(qi.ConvertToDouble()) / log(2); + } + std::cout << "Total bit length: " << total_bit_len << std::endl; +} + +double getScaleApproxError(const DCRTPoly& poly, uint32_t numPrimes, uint32_t compositeDegree, uint32_t firstModSize, + uint32_t scalingModSize) { + double delta0 = std::pow(2.0, static_cast(firstModSize)); + double delta = std::pow(2.0, static_cast(scalingModSize)); + // uint32_t numPrimes = poly.GetNumOfElements(); + auto q = poly.GetParams()->GetParams(); + + std::cout << "numPrimes=" << numPrimes << " compositeDegree=" << compositeDegree << " firstModSize=" << firstModSize + << " scalingModSize=" << scalingModSize << std::endl; + + double prod = q[0]->GetModulus().ConvertToDouble(); + std::cout << "q0_0: " << prod; + for (uint32_t d = 1; d < compositeDegree; ++d) { + std::cout << " q0_" << d << ": " << q[d]->GetModulus().ConvertToDouble(); + prod *= q[d]->GetModulus().ConvertToDouble(); + } + std::cout << "\n"; + double cumApproxError = std::abs(delta0 - prod); + + std::cout << "q0: " << prod << " delta0: " << delta0 << " approxErr=" << std::abs(delta0 - prod) << std::endl; + + for (uint32_t i = compositeDegree; i < numPrimes; i += compositeDegree) { + prod = q[i]->GetModulus().ConvertToDouble(); + std::cout << "q" << i / compositeDegree << "_0: " << prod; + for (uint32_t d = 1; d < compositeDegree; ++d) { + std::cout << " q" << i / compositeDegree << "_" << d << ": " << q[i + d]->GetModulus().ConvertToDouble(); + prod *= q[i + d]->GetModulus().ConvertToDouble(); + } + std::cout << "\n"; + cumApproxError += std::abs(delta - prod); + std::cout << "q" << i / compositeDegree << ": " << prod << " delta: " << delta + << " approxErr=" << std::abs(delta - prod) << std::endl; + } + + std::cout << "Average distance to scaling factor: " + << cumApproxError / ((numPrimes - compositeDegree) / compositeDegree) << std::endl; + + return cumApproxError / ((numPrimes - compositeDegree) / compositeDegree); +} + +int main(int argc, char* argv[]) { + TimeVar t; + + double timeEvalPoly1(0.0), timeEvalPoly2(0.0); + // Parameters for d=4 + // uint32_t firstModSize = 106; + // uint32_t scalingModSize = 104; + // uint32_t registerWordSize = 32; + // Parameters for d=3 + uint32_t firstModSize = 96; + uint32_t scalingModSize = 80; + uint32_t registerWordSize = 32; + + std::cout << "\n======EXAMPLE FOR EVALPOLY========\n" << std::endl; + + uint32_t multDepth = 7; + int argcCount = 0; + if (argc > 1) { + while (argcCount < argc) { + uint32_t paramValue = atoi(argv[argcCount]); + switch (argcCount) { + case 1: + firstModSize = paramValue; + std::cout << "Setting First Mod Size: " << firstModSize << std::endl; + break; + case 2: + scalingModSize = paramValue; + std::cout << "Setting Scaling Mod Size: " << scalingModSize << std::endl; + break; + case 3: + registerWordSize = paramValue; + std::cout << "Setting Register Word Size: " << registerWordSize << std::endl; + break; + case 4: + multDepth = paramValue; + std::cout << "Setting Multiplicative Depth: " << multDepth << std::endl; + break; + default: + std::cout << "Invalid option" << std::endl; + break; + } + argcCount += 1; + std::cout << "argcCount: " << argcCount << std::endl; + } + std::cout << "Complete !" << std::endl; + } + else { + std::cout << "Using default parameters" << std::endl; + std::cout << "First Mod Size: " << firstModSize << std::endl; + std::cout << "Scaling Mod Size: " << scalingModSize << std::endl; + std::cout << "Register Word Size: " << registerWordSize << std::endl; + std::cout << "Multiplicative Depth: " << multDepth << std::endl; + std::cout << "Usage: " << argv[0] << " [firstModSize] [scalingModSize] [registerWordSize] [multDepth]" + << std::endl; + } + + CCParams parameters; + parameters.SetMultiplicativeDepth(multDepth); + parameters.SetFirstModSize(firstModSize); + parameters.SetScalingModSize(scalingModSize); + + parameters.SetRegisterWordSize(registerWordSize); + parameters.SetScalingTechnique(COMPOSITESCALINGAUTO); + + CryptoContext cc = GenCryptoContext(parameters); + cc->Enable(PKE); + cc->Enable(KEYSWITCH); + cc->Enable(LEVELEDSHE); + cc->Enable(ADVANCEDSHE); + + const auto cryptoParamsCKKSRNS = std::dynamic_pointer_cast(cc->GetCryptoParameters()); + uint32_t compositeDegree = cryptoParamsCKKSRNS->GetCompositeDegree(); + std::cout << "Composite Degree: " << compositeDegree << "\nPrime Moduli Bit Length: " + << static_cast(scalingModSize) / cryptoParamsCKKSRNS->GetCompositeDegree() + << "\nTarget HW Arch Word Size: " << registerWordSize << std::endl; + + std::vector> input({0.5, 0.7, 0.9, 0.95, 0.93}); + + size_t encodedLength = input.size(); + + std::vector coefficients1({0.15, 0.75, 0, 1.25, 0, 0, 1, 0, 1, 2, 0, 1, 0, 0, 0, 0, 1}); + std::vector coefficients2({1, 2, 3, 4, 5, -1, -2, -3, -4, -5, + 0.1, 0.2, 0.3, 0.4, 0.5, -0.1, -0.2, -0.3, -0.4, -0.5, + 0.1, 0.2, 0.3, 0.4, 0.5, -0.1, -0.2, -0.3, -0.4, -0.5}); + // std::vector coefficients2({0, 0, 0, 0, 0, -0, -0, -0, -0, -0, + // 0., 0., 0., 0., 0., -0., -0., -0., -0., -0., + // 0., 0., 0., 0., 0., -0., -0., -0., -0., -0.}); + Plaintext plaintext1 = cc->MakeCKKSPackedPlaintext(input); + + auto keyPair = cc->KeyGen(); + + std::cout << "Generating evaluation key for homomorphic multiplication..."; + cc->EvalMultKeyGen(keyPair.secretKey); + std::cout << "Completed." << std::endl; + + const std::vector& ckkspk = keyPair.publicKey->GetPublicElements(); + std::cout << "Moduli chain of pk: " << std::endl; + printPrimeModuliChain(ckkspk[0]); + + double avgScaleError = getScaleApproxError(ckkspk[0], (multDepth + 1) * compositeDegree, compositeDegree, + firstModSize, scalingModSize); + std::cout << "Average Scale Error: " << avgScaleError << std::endl; + + auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1); + + TIC(t); + + auto result = cc->EvalPoly(ciphertext1, coefficients1); + + timeEvalPoly1 = TOC(t); + + TIC(t); + + auto result2 = cc->EvalPoly(ciphertext1, coefficients2); + + timeEvalPoly2 = TOC(t); + + Plaintext plaintextDec; + + cc->Decrypt(keyPair.secretKey, result, &plaintextDec); + + plaintextDec->SetLength(encodedLength); + + Plaintext plaintextDec2; + + cc->Decrypt(keyPair.secretKey, result2, &plaintextDec2); + + plaintextDec2->SetLength(encodedLength); + + std::cout << std::setprecision(15) << std::endl; + + std::cout << "\n Original Plaintext #1: \n"; + std::cout << plaintext1 << std::endl; + + std::cout << "\n Result of evaluating a polynomial with coefficients " << coefficients1 << " \n"; + std::cout << plaintextDec << std::endl; + + std::cout << "\n Expected result: (0.70519107, 1.38285078, 3.97211180, " + "5.60215665, 4.86357575) " + << std::endl; + + std::cout << "\n Evaluation time: " << timeEvalPoly1 << " ms" << std::endl; + + std::cout << "\n Result of evaluating a polynomial with coefficients " << coefficients2 << " \n"; + std::cout << plaintextDec2 << std::endl; + + std::cout << "\n Expected result: (3.4515092326, 5.3752765397, 4.8993108833, " + "3.2495023573, 4.0485229982) " + << std::endl; + + std::cout << "\n Evaluation time: " << timeEvalPoly2 << " ms" << std::endl; + + return 0; +} diff --git a/src/pke/include/schemerns/rns-cryptoparameters.h b/src/pke/include/schemerns/rns-cryptoparameters.h index b0d0b31da..b16b7da83 100644 --- a/src/pke/include/schemerns/rns-cryptoparameters.h +++ b/src/pke/include/schemerns/rns-cryptoparameters.h @@ -165,7 +165,7 @@ class CryptoParametersRNS : public CryptoParametersRLWE { m_encTechnique = encTech; m_multTechnique = multTech; m_MPIntBootCiphertextCompressionLevel = mPIntBootCiphertextCompressionLevel; - m_compositeDegree = compositeDegree; + m_compositeDegree = compositeDegree; m_registerWordSize = registerWordSize; } @@ -633,12 +633,12 @@ class CryptoParametersRNS : public CryptoParametersRLWE { /** * Method to retrieve the scaling factor of level l. * For FIXEDMANUAL scaling technique method always returns 2^p, where p corresponds to plaintext modulus - * @param l For FLEXIBLEAUTO scaling technique the level whose scaling factor we want to learn. + * @param l For FLEXIBLEAUTO and COMPOSITESCALING scaling techniques the level whose scaling factor we want to learn. * Levels start from 0 (no scaling done - all towers) and go up to K-1, where K is the number of towers supported. * @return the scaling factor. */ double GetScalingFactorReal(uint32_t l = 0) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { if (l >= m_scalingFactorsReal.size()) { // TODO: Return an error here. @@ -652,7 +652,7 @@ class CryptoParametersRNS : public CryptoParametersRLWE { } double GetScalingFactorRealBig(uint32_t l = 0) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { if (l >= m_scalingFactorsRealBig.size()) { // TODO: Return an error here. @@ -665,15 +665,15 @@ class CryptoParametersRNS : public CryptoParametersRLWE { return m_approxSF; } - /** + /** * Method to retrieve the modulus to be dropped of level l. * For FIXEDMANUAL rescaling technique method always returns 2^p, where p corresponds to plaintext modulus - * @param l index of modulus to be dropped for FLEXIBLEAUTO scaling technique + * @param l index of modulus to be dropped for FLEXIBLEAUTO and COMPOSITESCALING scaling techniques * @return the precomputed table */ double GetModReduceFactor(uint32_t l = 0) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || - m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { return m_dmoduliQ[l]; } @@ -697,9 +697,9 @@ class CryptoParametersRNS : public CryptoParametersRLWE { } /** * Returns the architecture register word size (e.g., 32 bits, 48 bits, 64 bits). - * Used to determine the size of prime moduli in the CKKS scheme on + * Used to determine the size of prime moduli in the CKKS scheme on * composite scaling mode (COMPOSITESCALINGAUTO). - * + * * @return the register word size for COMPOSITESCALING scaling technique **/ uint32_t const& GetRegisterWordSize() const { @@ -1021,7 +1021,7 @@ class CryptoParametersRNS : public CryptoParametersRLWE { } const NativeInteger& GetModReduceFactorInt(uint32_t l = 0) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { return m_qModt[l]; } @@ -1549,7 +1549,7 @@ class CryptoParametersRNS : public CryptoParametersRLWE { ///////////////////////////////////// // Stores composite degree for composite modulus chain - uint32_t m_compositeDegree = BASE_NUM_LEVELS_TO_DROP; + uint32_t m_compositeDegree = BASE_NUM_LEVELS_TO_DROP; // Stores the architecture register word size uint32_t m_registerWordSize = NATIVEINT; diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-advancedshe.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-advancedshe.cpp index 9d0f2ff09..d18151929 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-advancedshe.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-advancedshe.cpp @@ -42,6 +42,8 @@ CKKS implementation. See https://eprint.iacr.org/2020/1118 for details. #include "schemebase/base-scheme.h" +#include + namespace lbcrypto { //------------------------------------------------------------------------------ @@ -63,6 +65,8 @@ Ciphertext AdvancedSHECKKSRNS::EvalLinearWSumMutable(std::vector& constants) const { const auto cryptoParams = std::dynamic_pointer_cast(ciphertexts[0]->GetCryptoParameters()); + uint32_t compositeDegree = cryptoParams->GetCompositeDegree(); + auto cc = ciphertexts[0]->GetCryptoContext(); auto algo = cc->GetScheme(); @@ -89,7 +93,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalLinearWSumMutable(std::vectorGetNoiseScaleDeg() == 2) { for (uint32_t i = 0; i < ciphertexts.size(); i++) { - algo->ModReduceInternalInPlace(ciphertexts[i], BASE_NUM_LEVELS_TO_DROP); + algo->ModReduceInternalInPlace(ciphertexts[i], compositeDegree); } } } @@ -148,7 +152,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyLinear(ConstCiphertext(std::floor(std::log2(i))); int64_t rem = i % powerOf2; if (indices[rem - 1] == 0) indices[rem - 1] = 1; @@ -156,7 +160,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyLinear(ConstCiphertext(std::floor(std::log2(rem))); rem = rem % powerOf2; if (indices[rem - 1] == 0) indices[rem - 1] = 1; @@ -179,7 +183,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyLinear(ConstCiphertext(std::floor(std::log2(i))); int64_t rem = i % powerOf2; usint levelDiff = powers[powerOf2 - 1]->GetLevel() - powers[rem - 1]->GetLevel(); cc->LevelReduceInPlace(powers[rem - 1], nullptr, levelDiff); @@ -228,19 +232,19 @@ Ciphertext AdvancedSHECKKSRNS::InnerEvalPolyPS(ConstCiphertext xkm(int32_t(k2m2k + k) + 1, 0.0); + std::vector xkm(static_cast(k2m2k + k) + 1, 0.0); xkm.back() = 1; auto divqr = LongDivisionPoly(coefficients, xkm); // Subtract x^{k(2^{m-1} - 1)} from r std::vector r2 = divqr->r; - if (int32_t(k2m2k - Degree(divqr->r)) <= 0) { - r2[int32_t(k2m2k)] -= 1; + if (static_cast(k2m2k - Degree(divqr->r)) <= 0) { + r2[static_cast(k2m2k)] -= 1; r2.resize(Degree(r2) + 1); } else { - r2.resize(int32_t(k2m2k + 1), 0.0); + r2.resize(static_cast(k2m2k + 1), 0.0); r2.back() = -1; } @@ -249,7 +253,7 @@ Ciphertext AdvancedSHECKKSRNS::InnerEvalPolyPS(ConstCiphertext s2 = divcs->r; - s2.resize(int32_t(k2m2k + 1), 0.0); + s2.resize(static_cast(k2m2k + 1), 0.0); s2.back() = 1; Ciphertext cu; @@ -393,7 +397,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyPS(ConstCiphertext x, else { // non-power of 2 indices[i - 1] = 1; - int64_t powerOf2 = 1 << (int64_t)std::floor(std::log2(i)); + int64_t powerOf2 = 1 << static_cast(std::floor(std::log2(i))); int64_t rem = i % powerOf2; if (indices[rem - 1] == 0) indices[rem - 1] = 1; @@ -401,7 +405,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyPS(ConstCiphertext x, // while rem is not a power of 2 // set indices required to compute rem to 1 while ((rem & (rem - 1))) { - powerOf2 = 1 << (int64_t)std::floor(std::log2(rem)); + powerOf2 = 1 << static_cast(std::floor(std::log2(rem))); rem = rem % powerOf2; if (indices[rem - 1] == 0) indices[rem - 1] = 1; @@ -423,7 +427,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyPS(ConstCiphertext x, else { if (indices[i - 1] == 1) { // non-power of 2 - int64_t powerOf2 = 1 << (int64_t)std::floor(std::log2(i)); + int64_t powerOf2 = 1 << static_cast(std::floor(std::log2(i))); int64_t rem = i % powerOf2; usint levelDiff = powers[powerOf2 - 1]->GetLevel() - powers[rem - 1]->GetLevel(); cc->LevelReduceInPlace(powers[rem - 1], nullptr, levelDiff); @@ -479,18 +483,18 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyPS(ConstCiphertext x, f2.back() = 1; // Divide f2 by x^{k*2^{m-1}} - std::vector xkm(int32_t(k2m2k + k) + 1, 0.0); + std::vector xkm(static_cast(k2m2k + k) + 1, 0.0); xkm.back() = 1; auto divqr = LongDivisionPoly(f2, xkm); // Subtract x^{k(2^{m-1} - 1)} from r std::vector r2 = divqr->r; - if (int32_t(k2m2k - Degree(divqr->r)) <= 0) { - r2[int32_t(k2m2k)] -= 1; + if (static_cast(k2m2k - Degree(divqr->r)) <= 0) { + r2[static_cast(k2m2k)] -= 1; r2.resize(Degree(r2) + 1); } else { - r2.resize(int32_t(k2m2k + 1), 0.0); + r2.resize(static_cast(k2m2k + 1), 0.0); r2.back() = -1; } @@ -499,7 +503,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyPS(ConstCiphertext x, // Add x^{k(2^{m-1} - 1)} to s std::vector s2 = divcs->r; - s2.resize(int32_t(k2m2k + 1), 0.0); + s2.resize(static_cast(k2m2k + 1), 0.0); s2.back() = 1; // Evaluate c at u @@ -739,18 +743,18 @@ Ciphertext AdvancedSHECKKSRNS::InnerEvalChebyshevPS(ConstCiphertext Tkm(int32_t(k2m2k + k) + 1, 0.0); + std::vector Tkm(static_cast(k2m2k + k) + 1, 0.0); Tkm.back() = 1; auto divqr = LongDivisionChebyshev(coefficients, Tkm); // Subtract x^{k(2^{m-1} - 1)} from r std::vector r2 = divqr->r; - if (int32_t(k2m2k - Degree(divqr->r)) <= 0) { - r2[int32_t(k2m2k)] -= 1; + if (static_cast(k2m2k - Degree(divqr->r)) <= 0) { + r2[static_cast(k2m2k)] -= 1; r2.resize(Degree(r2) + 1); } else { - r2.resize(int32_t(k2m2k + 1), 0.0); + r2.resize(static_cast(k2m2k + 1), 0.0); r2.back() = -1; } @@ -759,7 +763,7 @@ Ciphertext AdvancedSHECKKSRNS::InnerEvalChebyshevPS(ConstCiphertext s2 = divcs->r; - s2.resize(int32_t(k2m2k + 1), 0.0); + s2.resize(static_cast(k2m2k + 1), 0.0); s2.back() = 1; // Evaluate c at u @@ -1013,18 +1017,18 @@ Ciphertext AdvancedSHECKKSRNS::EvalChebyshevSeriesPS(ConstCiphertext Tkm(int32_t(k2m2k + k) + 1, 0.0); + std::vector Tkm(static_cast(k2m2k + k) + 1, 0.0); Tkm.back() = 1; auto divqr = LongDivisionChebyshev(f2, Tkm); // Subtract x^{k(2^{m-1} - 1)} from r std::vector r2 = divqr->r; - if (int32_t(k2m2k - Degree(divqr->r)) <= 0) { - r2[int32_t(k2m2k)] -= 1; + if (static_cast(k2m2k - Degree(divqr->r)) <= 0) { + r2[static_cast(k2m2k)] -= 1; r2.resize(Degree(r2) + 1); } else { - r2.resize(int32_t(k2m2k + 1), 0.0); + r2.resize(static_cast(k2m2k + 1), 0.0); r2.back() = -1; } @@ -1033,7 +1037,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalChebyshevSeriesPS(ConstCiphertext s2 = divcs->r; - s2.resize(int32_t(k2m2k + 1), 0.0); + s2.resize(static_cast(k2m2k + 1), 0.0); s2.back() = 1; // Evaluate c at u diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp index a059eaa9c..d7fed2e18 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp @@ -203,7 +203,7 @@ void CryptoParametersCKKSRNS::ConfigureCompositeDegree(uint32_t scalingModSize) if (static_cast(scalingModSize) / compositeDegree < 22) { OPENFHE_THROW( config_error, - "Moduli size is too short (< 21) for target multiplicative depth. Consider increasing the scaling factor or the register word size."); + "Moduli size is too short (< 22) for target multiplicative depth. Consider increasing the scaling factor or the register word size."); } m_compositeDegree = compositeDegree; } // else composite degree remains set to 1 diff --git a/src/pke/lib/schemebase/base-advancedshe.cpp b/src/pke/lib/schemebase/base-advancedshe.cpp index b14b5891a..2f3a3f8c8 100644 --- a/src/pke/lib/schemebase/base-advancedshe.cpp +++ b/src/pke/lib/schemebase/base-advancedshe.cpp @@ -34,6 +34,12 @@ #include "cryptocontext.h" #include "schemebase/base-scheme.h" +#include +#include +#include +#include +#include + namespace lbcrypto { template @@ -99,11 +105,20 @@ Ciphertext AdvancedSHEBase::EvalMultMany(const std::vectorGetCryptoContext()->GetScheme(); + const auto cc = ciphertextVec[0]->GetCryptoContext(); + + usint levelsToDrop = 1; // TODO(@fdiasmor): Or BASE_NUM_LEVELS_TO_DROP ? + if (cc->getSchemeId() == CKKSRNS_SCHEME) { + const auto cryptoParams = + std::dynamic_pointer_cast(ciphertextVec[0]->GetCryptoParameters()); + levelsToDrop = cryptoParams->GetCompositeDegree(); + } + for (size_t i = 0; i < lim; i = i + 2) { ciphertextMultVec[ctrIndex] = algo->EvalMultAndRelinearize( i < inSize ? ciphertextVec[i] : ciphertextMultVec[i - inSize], i + 1 < inSize ? ciphertextVec[i + 1] : ciphertextMultVec[i + 1 - inSize], evalKeys); - algo->ModReduceInPlace(ciphertextMultVec[ctrIndex++], 1); + algo->ModReduceInPlace(ciphertextMultVec[ctrIndex++], levelsToDrop); } return ciphertextMultVec.back(); @@ -395,7 +410,8 @@ Ciphertext AdvancedSHEBase::EvalMerge(const std::vectorEvalAdd( - ciphertextMerged, algo->EvalAtIndex(algo->EvalMult(ciphertextVec[i], plaintext), -(int32_t)i, evalKeyMap)); + ciphertextMerged, + algo->EvalAtIndex(algo->EvalMult(ciphertextVec[i], plaintext), -static_cast(i), evalKeyMap)); } return ciphertextMerged; diff --git a/src/pke/lib/schemebase/base-leveledshe.cpp b/src/pke/lib/schemebase/base-leveledshe.cpp index 29f0cf909..3646cecbe 100644 --- a/src/pke/lib/schemebase/base-leveledshe.cpp +++ b/src/pke/lib/schemebase/base-leveledshe.cpp @@ -35,6 +35,13 @@ #include "cryptocontext.h" #include "schemebase/base-scheme.h" +#include +#include +#include +#include +#include +#include + namespace lbcrypto { ///////////////////////////////////////// @@ -557,10 +564,17 @@ template Ciphertext LeveledSHEBase::ComposedEvalMult(ConstCiphertext ciphertext1, ConstCiphertext ciphertext2, const EvalKey evalKey) const { + const auto cc = ciphertext1->GetCryptoContext(); auto algo = ciphertext1->GetCryptoContext()->GetScheme(); + const auto cryptoParams = ciphertext1->GetCryptoParameters(); Ciphertext ciphertext = EvalMult(ciphertext1, ciphertext2); algo->KeySwitchInPlace(ciphertext, evalKey); - ModReduceInPlace(ciphertext, BASE_NUM_LEVELS_TO_DROP); + uint32_t levelsToDrop = BASE_NUM_LEVELS_TO_DROP; + if (cc->getSchemeId() == CKKSRNS_SCHEME) { + const auto cryptoRNSParams = std::dynamic_pointer_cast(cryptoParams); + levelsToDrop = cryptoRNSParams->GetCompositeDegree(); + } + ModReduceInPlace(ciphertext, levelsToDrop); return ciphertext; } diff --git a/src/pke/lib/schemerns/rns-leveledshe.cpp b/src/pke/lib/schemerns/rns-leveledshe.cpp index 85ed30e7b..a63f7cf23 100644 --- a/src/pke/lib/schemerns/rns-leveledshe.cpp +++ b/src/pke/lib/schemerns/rns-leveledshe.cpp @@ -34,6 +34,9 @@ #include "cryptocontext.h" #include "schemerns/rns-leveledshe.h" +#include +#include + namespace lbcrypto { ///////////////////////////////////////// @@ -212,7 +215,13 @@ Ciphertext LeveledSHERNS::EvalSquare(ConstCiphertext ciphert } auto c = ciphertext->Clone(); - ModReduceInternalInPlace(c, BASE_NUM_LEVELS_TO_DROP); + if (cryptoParams->GetScalingTechnique() == COMPOSITESCALINGAUTO || + cryptoParams->GetScalingTechnique() == COMPOSITESCALINGMANUAL) { + ModReduceInternalInPlace(c, cryptoParams->GetCompositeDegree()); + } + else { + ModReduceInternalInPlace(c, BASE_NUM_LEVELS_TO_DROP); + } return EvalSquareCore(c); } @@ -222,7 +231,13 @@ Ciphertext LeveledSHERNS::EvalSquareMutable(Ciphertext& ciph if (cryptoParams->GetScalingTechnique() != NORESCALE && cryptoParams->GetScalingTechnique() != FIXEDMANUAL && ciphertext->GetNoiseScaleDeg() == 2) { - ModReduceInternalInPlace(ciphertext, BASE_NUM_LEVELS_TO_DROP); + if (cryptoParams->GetScalingTechnique() == COMPOSITESCALINGAUTO || + cryptoParams->GetScalingTechnique() == COMPOSITESCALINGMANUAL) { + ModReduceInternalInPlace(ciphertext, cryptoParams->GetCompositeDegree()); + } + else { + ModReduceInternalInPlace(ciphertext, BASE_NUM_LEVELS_TO_DROP); + } } return EvalSquareCore(ciphertext); @@ -377,9 +392,18 @@ void LeveledSHERNS::LevelReduceInPlace(Ciphertext& ciphertext, const E Ciphertext LeveledSHERNS::Compress(ConstCiphertext ciphertext, size_t towersLeft) const { Ciphertext result = std::make_shared>(*ciphertext); + const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); + + usint levelsToDrop = BASE_NUM_LEVELS_TO_DROP; + if (cryptoParams->GetScalingTechnique() == COMPOSITESCALINGAUTO || + cryptoParams->GetScalingTechnique() == COMPOSITESCALINGMANUAL) { + usint compositeDegree = cryptoParams->GetCompositeDegree(); + levelsToDrop = compositeDegree; + // towersLeft *= compositeDegree; + } while (result->GetNoiseScaleDeg() > 1) { - ModReduceInternalInPlace(result, BASE_NUM_LEVELS_TO_DROP); + ModReduceInternalInPlace(result, levelsToDrop); } const std::vector& cv = result->GetElements(); usint sizeQl = cv[0].GetNumOfElements(); From 3bf393a80acbbdfb0adfaaa210b7135154949b2d Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 16 Dec 2024 19:25:53 -0800 Subject: [PATCH 05/21] Handling overflow for scaling factors over 64 bits on composite scaling mode. --- .../lib/scheme/ckksrns/ckksrns-leveledshe.cpp | 64 +++++++++++++++++-- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp index 198568f3f..30f833da7 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp @@ -253,7 +253,8 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalAddOrSub(Cons LargeScalingFactorConstants::MAX_BITS_IN_WORD; logApprox = logSF - logValid; } - double approxFactor = pow(2, logApprox); + int32_t logApprox_cp = logApprox; + double approxFactor = pow(2, logApprox); DCRTPoly::Integer scConstant = static_cast(operand * scFactor / approxFactor + 0.5); std::vector crtConstant(sizeQl, scConstant); @@ -285,13 +286,66 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalAddOrSub(Cons return crtConstant; } - DCRTPoly::Integer intScFactor = static_cast(scFactor + 0.5); - std::vector crtScFactor(sizeQl, intScFactor); + // COMPOSITESCALING support to 128-bit scaling factor + if (cryptoParams->GetScalingTechnique() == COMPOSITESCALINGAUTO || + cryptoParams->GetScalingTechnique() == COMPOSITESCALINGMANUAL) { + int32_t logSF_cp = static_cast(std::ceil(std::log2(res))); + // int32_t logValid_cp = (logSF_cp <= LargeScalingFactorConstants::MAX_BITS_IN_WORD) ? + // logSF_cp : + // LargeScalingFactorConstants::MAX_BITS_IN_WORD; + if (logSF_cp < 64) { + // DCRTPoly::Integer intScFactor = static_cast(scFactor + 0.5); + DCRTPoly::Integer intScFactor = std::llround(scFactor + 0.5); + std::vector crtScFactor(sizeQl, intScFactor); + for (usint i = 1; i < ciphertext->GetNoiseScaleDeg(); i++) { + crtConstant = CKKSPackedEncoding::CRTMult(crtConstant, crtScFactor, moduli); + } + } + else { + // Multiply scFactor in two steps: scFactor / approxFactor and then approxFactor + // DCRTPoly::Integer intScFactor = static_cast(scFactor / approxFactor + 0.5); + DCRTPoly::Integer intScFactor = static_cast(scFactor / approxFactor + 0.5); + std::vector crtScFactor(sizeQl, intScFactor); + for (usint i = 1; i < ciphertext->GetNoiseScaleDeg(); i++) { + crtConstant = CKKSPackedEncoding::CRTMult(crtConstant, crtScFactor, moduli); + } + if (logApprox_cp > 0) { + int32_t logStep = (logApprox_cp <= LargeScalingFactorConstants::MAX_LOG_STEP) ? + logApprox_cp : + LargeScalingFactorConstants::MAX_LOG_STEP; + DCRTPoly::Integer intStep = static_cast(1) << logStep; + std::vector crtApprox(sizeQl, intStep); + logApprox_cp -= logStep; + + while (logApprox_cp > 0) { + int32_t logStep = (logApprox_cp <= LargeScalingFactorConstants::MAX_LOG_STEP) ? + logApprox_cp : + LargeScalingFactorConstants::MAX_LOG_STEP; + DCRTPoly::Integer intStep = static_cast(1) << logStep; + std::vector crtSF(sizeQl, intStep); + crtApprox = CKKSPackedEncoding::CRTMult(crtApprox, crtSF, moduli); + logApprox_cp -= logStep; + } + crtConstant = CKKSPackedEncoding::CRTMult(crtConstant, crtApprox, moduli); + } + } + } + else { + DCRTPoly::Integer intScFactor = static_cast(scFactor + 0.5); + std::vector crtScFactor(sizeQl, intScFactor); - for (usint i = 1; i < ciphertext->GetNoiseScaleDeg(); i++) { - crtConstant = CKKSPackedEncoding::CRTMult(crtConstant, crtScFactor, moduli); + for (usint i = 1; i < ciphertext->GetNoiseScaleDeg(); i++) { + crtConstant = CKKSPackedEncoding::CRTMult(crtConstant, crtScFactor, moduli); + } } + // DCRTPoly::Integer intScFactor = static_cast(scFactor + 0.5); + // std::vector crtScFactor(sizeQl, intScFactor); + + // for (usint i = 1; i < ciphertext->GetNoiseScaleDeg(); i++) { + // crtConstant = CKKSPackedEncoding::CRTMult(crtConstant, crtScFactor, moduli); + // } + return crtConstant; } #endif From 51db3ca6943c6d3ea4ae6cfea68f050ee27b6718 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 17 Dec 2024 22:26:32 -0800 Subject: [PATCH 06/21] Bug fix of overflow handling for d > 2 and sc > 64. --- .../lib/scheme/ckksrns/ckksrns-leveledshe.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp index 30f833da7..2b08a2969 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp @@ -245,7 +245,10 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalAddOrSub(Cons // -gsimple-template-names // -gsplit-dwarf int32_t logApprox = 0; - const double res = std::fabs(operand * scFactor); + const double res = (cryptoParams->GetScalingTechnique() == COMPOSITESCALINGAUTO || + cryptoParams->GetScalingTechnique() == COMPOSITESCALINGMANUAL) ? + std::fabs(scFactor) : + std::fabs(operand * scFactor); if (res > 0) { int32_t logSF = static_cast(std::ceil(std::log2(res))); int32_t logValid = (logSF <= LargeScalingFactorConstants::MAX_BITS_IN_WORD) ? @@ -290,12 +293,8 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalAddOrSub(Cons if (cryptoParams->GetScalingTechnique() == COMPOSITESCALINGAUTO || cryptoParams->GetScalingTechnique() == COMPOSITESCALINGMANUAL) { int32_t logSF_cp = static_cast(std::ceil(std::log2(res))); - // int32_t logValid_cp = (logSF_cp <= LargeScalingFactorConstants::MAX_BITS_IN_WORD) ? - // logSF_cp : - // LargeScalingFactorConstants::MAX_BITS_IN_WORD; if (logSF_cp < 64) { - // DCRTPoly::Integer intScFactor = static_cast(scFactor + 0.5); - DCRTPoly::Integer intScFactor = std::llround(scFactor + 0.5); + DCRTPoly::Integer intScFactor = static_cast(scFactor + 0.5); std::vector crtScFactor(sizeQl, intScFactor); for (usint i = 1; i < ciphertext->GetNoiseScaleDeg(); i++) { crtConstant = CKKSPackedEncoding::CRTMult(crtConstant, crtScFactor, moduli); @@ -303,7 +302,6 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalAddOrSub(Cons } else { // Multiply scFactor in two steps: scFactor / approxFactor and then approxFactor - // DCRTPoly::Integer intScFactor = static_cast(scFactor / approxFactor + 0.5); DCRTPoly::Integer intScFactor = static_cast(scFactor / approxFactor + 0.5); std::vector crtScFactor(sizeQl, intScFactor); for (usint i = 1; i < ciphertext->GetNoiseScaleDeg(); i++) { @@ -339,13 +337,6 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalAddOrSub(Cons } } - // DCRTPoly::Integer intScFactor = static_cast(scFactor + 0.5); - // std::vector crtScFactor(sizeQl, intScFactor); - - // for (usint i = 1; i < ciphertext->GetNoiseScaleDeg(); i++) { - // crtConstant = CKKSPackedEncoding::CRTMult(crtConstant, crtScFactor, moduli); - // } - return crtConstant; } #endif From 44b206bfff50234cca63ebd4727f708637b918eb Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 17 Dec 2024 23:16:40 -0800 Subject: [PATCH 07/21] Update impl of Rescale and Mod/LevelReduce methods with composite degree. --- src/pke/include/cryptocontext.h | 40 +++++++++++++++++++-- src/pke/lib/schemebase/base-advancedshe.cpp | 2 +- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/pke/include/cryptocontext.h b/src/pke/include/cryptocontext.h index 8c4413e21..b958cfe4b 100644 --- a/src/pke/include/cryptocontext.h +++ b/src/pke/include/cryptocontext.h @@ -66,6 +66,9 @@ #include #include #include +#ifdef DEBUG_KEY + #include +#endif namespace lbcrypto { @@ -2339,7 +2342,10 @@ class CryptoContextImpl : public Serializable { Ciphertext Rescale(ConstCiphertext ciphertext) const { ValidateCiphertext(ciphertext); - return GetScheme()->ModReduce(ciphertext, BASE_NUM_LEVELS_TO_DROP); + const auto cryptoParams = + std::dynamic_pointer_cast(ciphertext->GetCryptoContext()->GetCryptoParameters()); + + return GetScheme()->ModReduce(ciphertext, cryptoParams->GetCompositeDegree()); } /** @@ -2351,7 +2357,10 @@ class CryptoContextImpl : public Serializable { void RescaleInPlace(Ciphertext& ciphertext) const { ValidateCiphertext(ciphertext); - GetScheme()->ModReduceInPlace(ciphertext, BASE_NUM_LEVELS_TO_DROP); + const auto cryptoParams = + std::dynamic_pointer_cast(ciphertext->GetCryptoContext()->GetCryptoParameters()); + + GetScheme()->ModReduceInPlace(ciphertext, cryptoParams->GetCompositeDegree()); } /** @@ -2362,6 +2371,12 @@ class CryptoContextImpl : public Serializable { Ciphertext ModReduce(ConstCiphertext ciphertext) const { ValidateCiphertext(ciphertext); + if (isCKKS(m_schemeId)) { + const auto cryptoParams = + std::dynamic_pointer_cast(ciphertext->GetCryptoContext()->GetCryptoParameters()); + return GetScheme()->ModReduce(ciphertext, cryptoParams->GetCompositeDegree()); + } + return GetScheme()->ModReduce(ciphertext, BASE_NUM_LEVELS_TO_DROP); } @@ -2372,11 +2387,18 @@ class CryptoContextImpl : public Serializable { void ModReduceInPlace(Ciphertext& ciphertext) const { ValidateCiphertext(ciphertext); + if (isCKKS(m_schemeId)) { + const auto cryptoParams = + std::dynamic_pointer_cast(ciphertext->GetCryptoContext()->GetCryptoParameters()); + GetScheme()->ModReduceInPlace(ciphertext, cryptoParams->GetCompositeDegree()); + } + GetScheme()->ModReduceInPlace(ciphertext, BASE_NUM_LEVELS_TO_DROP); } /** * LevelReduce - drops unnecessary RNS limbs (levels) from the ciphertext and evaluation key + * Note: the number of levels to drop is multiplied by the composite degree in CKKS when using COMPOSITESCALING* scaling techniques. * @param ciphertext input ciphertext. Supported only in BGV/CKKS. * @param evalKey input evaluation key (modified in place) * @returns the ciphertext with reduced number opf RNS limbs @@ -2385,11 +2407,18 @@ class CryptoContextImpl : public Serializable { size_t levels = 1) const { ValidateCiphertext(ciphertext); + if (isCKKS(m_schemeId)) { + const auto cryptoParams = + std::dynamic_pointer_cast(ciphertext->GetCryptoContext()->GetCryptoParameters()); + return GetScheme()->LevelReduce(ciphertext, evalKey, levels * cryptoParams->GetCompositeDegree()); + } + return GetScheme()->LevelReduce(ciphertext, evalKey, levels); } /** * LevelReduceInPlace - drops unnecessary RNS limbs (levels) from the ciphertext and evaluation key. Supported only in BGV/CKKS. + * Note: the number of levels to drop is multiplied by the composite degree in CKKS when using COMPOSITESCALING* scaling techniques. * @param ciphertext input ciphertext (modified in place) * @param evalKey input evaluation key (modified in place) */ @@ -2398,6 +2427,13 @@ class CryptoContextImpl : public Serializable { if (levels <= 0) { return; } + + if (isCKKS(m_schemeId)) { + const auto cryptoParams = + std::dynamic_pointer_cast(ciphertext->GetCryptoContext()->GetCryptoParameters()); + GetScheme()->LevelReduceInPlace(ciphertext, evalKey, levels * cryptoParams->GetCompositeDegree()); + } + GetScheme()->LevelReduceInPlace(ciphertext, evalKey, levels); } /** diff --git a/src/pke/lib/schemebase/base-advancedshe.cpp b/src/pke/lib/schemebase/base-advancedshe.cpp index 2f3a3f8c8..54ee29dbc 100644 --- a/src/pke/lib/schemebase/base-advancedshe.cpp +++ b/src/pke/lib/schemebase/base-advancedshe.cpp @@ -107,7 +107,7 @@ Ciphertext AdvancedSHEBase::EvalMultMany(const std::vectorGetCryptoContext(); - usint levelsToDrop = 1; // TODO(@fdiasmor): Or BASE_NUM_LEVELS_TO_DROP ? + uint32_t levelsToDrop = BASE_NUM_LEVELS_TO_DROP; if (cc->getSchemeId() == CKKSRNS_SCHEME) { const auto cryptoParams = std::dynamic_pointer_cast(ciphertextVec[0]->GetCryptoParameters()); From 3d2c2203c5e23295241a141ab195647d10b4d442 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 18 Dec 2024 18:56:42 -0800 Subject: [PATCH 08/21] Minor bug fix: else case missing. --- src/pke/include/cryptocontext.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/pke/include/cryptocontext.h b/src/pke/include/cryptocontext.h index b958cfe4b..5ad36a684 100644 --- a/src/pke/include/cryptocontext.h +++ b/src/pke/include/cryptocontext.h @@ -2392,8 +2392,9 @@ class CryptoContextImpl : public Serializable { std::dynamic_pointer_cast(ciphertext->GetCryptoContext()->GetCryptoParameters()); GetScheme()->ModReduceInPlace(ciphertext, cryptoParams->GetCompositeDegree()); } - - GetScheme()->ModReduceInPlace(ciphertext, BASE_NUM_LEVELS_TO_DROP); + else { + GetScheme()->ModReduceInPlace(ciphertext, BASE_NUM_LEVELS_TO_DROP); + } } /** @@ -2433,8 +2434,9 @@ class CryptoContextImpl : public Serializable { std::dynamic_pointer_cast(ciphertext->GetCryptoContext()->GetCryptoParameters()); GetScheme()->LevelReduceInPlace(ciphertext, evalKey, levels * cryptoParams->GetCompositeDegree()); } - - GetScheme()->LevelReduceInPlace(ciphertext, evalKey, levels); + else { + GetScheme()->LevelReduceInPlace(ciphertext, evalKey, levels); + } } /** * Compress - Reduces the size of ciphertext modulus to minimize the From a9c9978f96a28225c5395848b28a30cf48fc3cbd Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 18 Dec 2024 19:11:59 -0800 Subject: [PATCH 09/21] Update EvalPoly functions to use composite degree. --- .../scheme/ckksrns/ckksrns-advancedshe.cpp | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-advancedshe.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-advancedshe.cpp index d18151929..88e75f262 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-advancedshe.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-advancedshe.cpp @@ -170,8 +170,10 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyLinear(ConstCiphertext> powers(k); - powers[0] = x->Clone(); - auto cc = x->GetCryptoContext(); + powers[0] = x->Clone(); + auto cc = x->GetCryptoContext(); + auto cryptoParams = std::dynamic_pointer_cast(x->GetCryptoParameters()); + uint32_t compositeDegree = cryptoParams->GetCompositeDegree(); // computes all powers up to k for x for (size_t i = 2; i <= k; i++) { @@ -186,7 +188,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyLinear(ConstCiphertext(std::floor(std::log2(i))); int64_t rem = i % powerOf2; usint levelDiff = powers[powerOf2 - 1]->GetLevel() - powers[rem - 1]->GetLevel(); - cc->LevelReduceInPlace(powers[rem - 1], nullptr, levelDiff); + cc->LevelReduceInPlace(powers[rem - 1], nullptr, levelDiff / compositeDegree); powers[i - 1] = cc->EvalMult(powers[powerOf2 - 1], powers[rem - 1]); cc->ModReduceInPlace(powers[i - 1]); @@ -198,7 +200,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyLinear(ConstCiphertextGetLevel() - powers[i - 1]->GetLevel(); - cc->LevelReduceInPlace(powers[i - 1], nullptr, levelDiff); + cc->LevelReduceInPlace(powers[i - 1], nullptr, levelDiff / compositeDegree); } } @@ -416,6 +418,8 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyPS(ConstCiphertext x, std::vector> powers(k); powers[0] = x->Clone(); auto cc = x->GetCryptoContext(); + uint32_t compositeDegree = + std::dynamic_pointer_cast(x->GetCryptoParameters())->GetCompositeDegree(); // computes all powers up to k for x for (size_t i = 2; i <= k; i++) { @@ -430,7 +434,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalPolyPS(ConstCiphertext x, int64_t powerOf2 = 1 << static_cast(std::floor(std::log2(i))); int64_t rem = i % powerOf2; usint levelDiff = powers[powerOf2 - 1]->GetLevel() - powers[rem - 1]->GetLevel(); - cc->LevelReduceInPlace(powers[rem - 1], nullptr, levelDiff); + cc->LevelReduceInPlace(powers[rem - 1], nullptr, levelDiff / compositeDegree); powers[i - 1] = cc->EvalMult(powers[powerOf2 - 1], powers[rem - 1]); cc->ModReduceInPlace(powers[i - 1]); } @@ -662,6 +666,8 @@ Ciphertext AdvancedSHECKKSRNS::EvalChebyshevSeriesLinear(ConstCipherte } Ciphertext yReduced = T[0]->Clone(); + uint32_t compositeDegree = + std::dynamic_pointer_cast(x->GetCryptoParameters())->GetCompositeDegree(); // Computes Chebyshev polynomials up to degree k // for y: T_1(y) = y, T_2(y), ... , T_k(y) @@ -710,7 +716,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalChebyshevSeriesLinear(ConstCipherte } for (size_t i = 1; i < k; i++) { usint levelDiff = T[k - 1]->GetLevel() - T[i - 1]->GetLevel(); - cc->LevelReduceInPlace(T[i - 1], nullptr, levelDiff); + cc->LevelReduceInPlace(T[i - 1], nullptr, levelDiff / compositeDegree); } // perform scalar multiplication for the highest-order term @@ -738,6 +744,8 @@ Ciphertext AdvancedSHECKKSRNS::InnerEvalChebyshevPS(ConstCiphertext>& T, std::vector>& T2) const { auto cc = x->GetCryptoContext(); + uint32_t compositeDegree = + std::dynamic_pointer_cast(x->GetCryptoParameters())->GetCompositeDegree(); // Compute k*2^{m-1}-k because we use it a lot uint32_t k2m2k = k * (1 << (m - 1)) - k; @@ -796,7 +804,7 @@ Ciphertext AdvancedSHECKKSRNS::InnerEvalChebyshevPS(ConstCiphertextEvalAddInPlace(cu, divcs->q.front() / 2); // Need to reduce levels up to the level of T2[m-1]. usint levelDiff = T2[m - 1]->GetLevel() - cu->GetLevel(); - cc->LevelReduceInPlace(cu, nullptr, levelDiff); + cc->LevelReduceInPlace(cu, nullptr, levelDiff / compositeDegree); flag_c = true; } From c03c8f9f903bf4326f1718610e9cb449bbbda39a Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 18 Dec 2024 19:13:11 -0800 Subject: [PATCH 10/21] Update Compress function to raise error. --- src/pke/lib/schemerns/rns-leveledshe.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pke/lib/schemerns/rns-leveledshe.cpp b/src/pke/lib/schemerns/rns-leveledshe.cpp index a63f7cf23..e1e31ba58 100644 --- a/src/pke/lib/schemerns/rns-leveledshe.cpp +++ b/src/pke/lib/schemerns/rns-leveledshe.cpp @@ -390,6 +390,10 @@ void LeveledSHERNS::LevelReduceInPlace(Ciphertext& ciphertext, const E // SHE LEVELED Compress ///////////////////////////////////////// +/* + * On COMPOSITESCALING technique, the number of towers to drop passed + * must be a multiple of composite degree. + */ Ciphertext LeveledSHERNS::Compress(ConstCiphertext ciphertext, size_t towersLeft) const { Ciphertext result = std::make_shared>(*ciphertext); const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); @@ -399,7 +403,9 @@ Ciphertext LeveledSHERNS::Compress(ConstCiphertext ciphertex cryptoParams->GetScalingTechnique() == COMPOSITESCALINGMANUAL) { usint compositeDegree = cryptoParams->GetCompositeDegree(); levelsToDrop = compositeDegree; - // towersLeft *= compositeDegree; + if (towersLeft % compositeDegree != 0) { + OPENFHE_THROW("Number of towers to drop must be a multiple of composite degree."); + } } while (result->GetNoiseScaleDeg() > 1) { From 470cd11180078035ae73d6906737b50b3c690b92 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 18 Dec 2024 19:17:58 -0800 Subject: [PATCH 11/21] Update/Add new composite scaling examples. --- .../function-evaluation-composite-scaling.cpp | 181 ++++++++++++++++++ ...inearwsum-evaluation-composite-scaling.cpp | 125 ++++++++++++ ...ation-high-precision-composite-scaling.cpp | 3 +- 3 files changed, 308 insertions(+), 1 deletion(-) create mode 100644 src/pke/examples/function-evaluation-composite-scaling.cpp create mode 100644 src/pke/examples/linearwsum-evaluation-composite-scaling.cpp diff --git a/src/pke/examples/function-evaluation-composite-scaling.cpp b/src/pke/examples/function-evaluation-composite-scaling.cpp new file mode 100644 index 000000000..994adecf3 --- /dev/null +++ b/src/pke/examples/function-evaluation-composite-scaling.cpp @@ -0,0 +1,181 @@ +//================================================================================== +// BSD 2-Clause License +// +// Copyright (c) 2014-2022, NJIT, Duality Technologies Inc. and other contributors +// +// All rights reserved. +// +// Author TPOC: contact@openfhe.org +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//================================================================================== + +/* + Example of evaluating arbitrary smooth functions with the Chebyshev approximation using CKKS. + */ + +#include "openfhe.h" + +#include +#include + +using namespace lbcrypto; + +void EvalLogisticExample(); + +void EvalFunctionExample(); + +int main(int argc, char* argv[]) { + EvalLogisticExample(); + EvalFunctionExample(); + return 0; +} + +// In this example, we evaluate the logistic function 1 / (1 + exp(-x)) on an input of doubles +void EvalLogisticExample() { + std::cout << "--------------------------------- EVAL LOGISTIC FUNCTION ---------------------------------" + << std::endl; + CCParams parameters; + + // We set a smaller ring dimension to improve performance for this example. + // In production environments, the security level should be set to + // HEStd_128_classic, HEStd_192_classic, or HEStd_256_classic for 128-bit, 192-bit, + // or 256-bit security, respectively. + parameters.SetSecurityLevel(HEStd_NotSet); + parameters.SetRingDim(1 << 10); +#if NATIVEINT == 128 + usint scalingModSize = 78; + usint firstModSize = 89; +#else + usint scalingModSize = 50; + usint firstModSize = 60; +#endif + parameters.SetScalingModSize(scalingModSize); + parameters.SetFirstModSize(firstModSize); + parameters.SetScalingTechnique(COMPOSITESCALINGAUTO); + parameters.SetRegisterWordSize(32); + + // Choosing a higher degree yields better precision, but a longer runtime. + uint32_t polyDegree = 16; + + // The multiplicative depth depends on the polynomial degree. + // See the FUNCTION_EVALUATION.md file for a table mapping polynomial degrees to multiplicative depths. + uint32_t multDepth = 6; + + parameters.SetMultiplicativeDepth(multDepth); + CryptoContext cc = GenCryptoContext(parameters); + cc->Enable(PKE); + cc->Enable(KEYSWITCH); + cc->Enable(LEVELEDSHE); + // We need to enable Advanced SHE to use the Chebyshev approximation. + cc->Enable(ADVANCEDSHE); + + auto keyPair = cc->KeyGen(); + // We need to generate mult keys to run Chebyshev approximations. + cc->EvalMultKeyGen(keyPair.secretKey); + + std::vector> input{-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0}; + size_t encodedLength = input.size(); + Plaintext plaintext = cc->MakeCKKSPackedPlaintext(input); + auto ciphertext = cc->Encrypt(keyPair.publicKey, plaintext); + + double lowerBound = -5; + double upperBound = 5; + auto result = cc->EvalLogistic(ciphertext, lowerBound, upperBound, polyDegree); + + Plaintext plaintextDec; + cc->Decrypt(keyPair.secretKey, result, &plaintextDec); + plaintextDec->SetLength(encodedLength); + + std::vector> expectedOutput( + {0.0179885, 0.0474289, 0.119205, 0.268936, 0.5, 0.731064, 0.880795, 0.952571, 0.982011}); + std::cout << "Expected output\n\t" << expectedOutput << std::endl; + + std::vector> finalResult = plaintextDec->GetCKKSPackedValue(); + std::cout << "Actual output\n\t" << finalResult << std::endl << std::endl; +} + +void EvalFunctionExample() { + std::cout << "--------------------------------- EVAL SQUARE ROOT FUNCTION ---------------------------------" + << std::endl; + CCParams parameters; + + // We set a smaller ring dimension to improve performance for this example. + // In production environments, the security level should be set to + // HEStd_128_classic, HEStd_192_classic, or HEStd_256_classic for 128-bit, 192-bit, + // or 256-bit security, respectively. + parameters.SetSecurityLevel(HEStd_NotSet); + parameters.SetRingDim(1 << 10); +#if NATIVEINT == 128 + usint scalingModSize = 78; + usint firstModSize = 89; +#else + usint scalingModSize = 50; + usint firstModSize = 60; +#endif + parameters.SetScalingModSize(scalingModSize); + parameters.SetFirstModSize(firstModSize); + parameters.SetScalingTechnique(COMPOSITESCALINGAUTO); + parameters.SetRegisterWordSize(32); + + // Choosing a higher degree yields better precision, but a longer runtime. + uint32_t polyDegree = 50; + + // The multiplicative depth depends on the polynomial degree. + // See the FUNCTION_EVALUATION.md file for a table mapping polynomial degrees to multiplicative depths. + uint32_t multDepth = 7; + + parameters.SetMultiplicativeDepth(multDepth); + CryptoContext cc = GenCryptoContext(parameters); + cc->Enable(PKE); + cc->Enable(KEYSWITCH); + cc->Enable(LEVELEDSHE); + // We need to enable Advanced SHE to use the Chebyshev approximation. + cc->Enable(ADVANCEDSHE); + + auto keyPair = cc->KeyGen(); + // We need to generate mult keys to run Chebyshev approximations. + cc->EvalMultKeyGen(keyPair.secretKey); + + std::vector> input{1, 2, 3, 4, 5, 6, 7, 8, 9}; + size_t encodedLength = input.size(); + Plaintext plaintext = cc->MakeCKKSPackedPlaintext(input); + auto ciphertext = cc->Encrypt(keyPair.publicKey, plaintext); + + double lowerBound = 0; + double upperBound = 10; + + // We can input any lambda function, which inputs a double and returns a double. + auto result = cc->EvalChebyshevFunction([](double x) -> double { return std::sqrt(x); }, ciphertext, lowerBound, + upperBound, polyDegree); + + Plaintext plaintextDec; + cc->Decrypt(keyPair.secretKey, result, &plaintextDec); + plaintextDec->SetLength(encodedLength); + + std::vector> expectedOutput( + {1, 1.414213, 1.732050, 2, 2.236067, 2.449489, 2.645751, 2.828427, 3}); + std::cout << "Expected output\n\t" << expectedOutput << std::endl; + + std::vector> finalResult = plaintextDec->GetCKKSPackedValue(); + std::cout << "Actual output\n\t" << finalResult << std::endl << std::endl; +} diff --git a/src/pke/examples/linearwsum-evaluation-composite-scaling.cpp b/src/pke/examples/linearwsum-evaluation-composite-scaling.cpp new file mode 100644 index 000000000..e23b59848 --- /dev/null +++ b/src/pke/examples/linearwsum-evaluation-composite-scaling.cpp @@ -0,0 +1,125 @@ +//================================================================================== +// BSD 2-Clause License +// +// Copyright (c) 2014-2022, NJIT, Duality Technologies Inc. and other contributors +// +// All rights reserved. +// +// Author TPOC: contact@openfhe.org +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//================================================================================== + +/* + Example of polynomial evaluation using CKKS. + */ + +#define PROFILE // turns on the reporting of timing results + +#include "openfhe.h" + +#include +#include + +using namespace lbcrypto; + +int main(int argc, char* argv[]) { + TimeVar t; + + double timeEvalLinearWSum(0.0); + + std::cout << "\n======EXAMPLE FOR EVAL LINEAR WEIGHTED SUM========\n" << std::endl; + + CCParams parameters; + parameters.SetMultiplicativeDepth(1); + parameters.SetScalingModSize(50); + parameters.SetBatchSize(8); + parameters.SetSecurityLevel(HEStd_NotSet); + parameters.SetRingDim(2048); + parameters.SetScalingTechnique(COMPOSITESCALINGAUTO); + parameters.SetFirstModSize(60); + parameters.SetRegisterWordSize(32); + + CryptoContext cc = GenCryptoContext(parameters); + cc->Enable(PKE); + cc->Enable(KEYSWITCH); + cc->Enable(LEVELEDSHE); + cc->Enable(ADVANCEDSHE); + + std::vector>> input; + + input.push_back({0.5, 0.7, 0.9, 0.95, 0.93, 1.3}); + input.push_back({1.2, 1.7, -0.9, 0.85, -0.63, 2}); + input.push_back({0.5, 0, 1.9, 2.95, -3.93, 3.3}); + input.push_back({1.5, 0.7, 1.9, 2.95, -3.78, 3.3}); + input.push_back({0.5, 2.7, 1.9, 0.0, -3.43, 1.3}); + input.push_back({0.5, 0.7, -1.9, 2.95, 1.96, 0.0}); + input.push_back({0.0, 0.0, 1.0, 0.0, 0.0, 0.0}); + + size_t encodedLength = input.size(); + + std::vector coefficients({0.15, 0.75, 1.25, 1, 0, 0.5, 0.5}); + + auto keyPair = cc->KeyGen(); + + std::cout << "Generating evaluation key for homomorphic multiplication..."; + cc->EvalMultKeyGen(keyPair.secretKey); + std::cout << "Completed." << std::endl; + + std::vector> ciphertextVec; + for (usint i = 0; i < encodedLength; ++i) { + Plaintext plaintext = cc->MakeCKKSPackedPlaintext(input[i]); + ciphertextVec.push_back(cc->Encrypt(keyPair.publicKey, plaintext)); + } + + TIC(t); + + auto result = cc->EvalLinearWSum(ciphertextVec, coefficients); + + timeEvalLinearWSum = TOC(t); + + std::vector> unencIP; + for (usint i = 0; i < input[0].size(); ++i) { + std::complex x = 0; + for (usint j = 0; j < encodedLength; ++j) { + x += input[j][i] * coefficients[j]; + } + unencIP.push_back(x); + } + + Plaintext plaintextDec; + + cc->Decrypt(keyPair.secretKey, result, &plaintextDec); + + plaintextDec->SetLength(encodedLength); + + std::cout << std::setprecision(10) << std::endl; + + std::cout << "\n Result of evaluating a linear weighted sum with coefficients " << coefficients << " \n"; + std::cout << plaintextDec << std::endl; + + std::cout << "\n Expected result: " << unencIP << std::endl; + + std::cout << "\n Evaluation time: " << timeEvalLinearWSum << " ms" << std::endl; + + return 0; +} diff --git a/src/pke/examples/polynomial-evaluation-high-precision-composite-scaling.cpp b/src/pke/examples/polynomial-evaluation-high-precision-composite-scaling.cpp index 37d52bb54..fed7902b5 100644 --- a/src/pke/examples/polynomial-evaluation-high-precision-composite-scaling.cpp +++ b/src/pke/examples/polynomial-evaluation-high-precision-composite-scaling.cpp @@ -36,6 +36,7 @@ #define PROFILE // turns on the reporting of timing results #include "openfhe.h" + #include #include @@ -108,7 +109,7 @@ int main(int argc, char* argv[]) { std::cout << "\n======EXAMPLE FOR EVALPOLY========\n" << std::endl; - uint32_t multDepth = 7; + uint32_t multDepth = 6; int argcCount = 0; if (argc > 1) { while (argcCount < argc) { From 6369eaad34009c235da2c20fb41b27917ebc2ab2 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 19 Dec 2024 14:32:22 -0800 Subject: [PATCH 12/21] Recalculate sizeP and update EstimateLogP interface. --- .../include/schemerns/rns-cryptoparameters.h | 3 ++ .../bfvrns/bfvrns-parametergeneration.cpp | 7 +++- .../bgvrns/bgvrns-parametergeneration.cpp | 19 +++++---- .../ckksrns/ckksrns-parametergeneration.cpp | 9 ++-- .../lib/schemerns/rns-cryptoparameters.cpp | 41 +++++++++++++++++-- 5 files changed, 62 insertions(+), 17 deletions(-) diff --git a/src/pke/include/schemerns/rns-cryptoparameters.h b/src/pke/include/schemerns/rns-cryptoparameters.h index b16b7da83..33adea599 100644 --- a/src/pke/include/schemerns/rns-cryptoparameters.h +++ b/src/pke/include/schemerns/rns-cryptoparameters.h @@ -195,12 +195,15 @@ class CryptoParametersRNS : public CryptoParametersRLWE { * @param extraModulusSize bit size for extra modulus in FLEXIBLEAUTOEXT (CKKS and BGV only) * @param numPrimes number of moduli witout extraModulus * @param auxBits size of auxiliar moduli used for hybrid key switching + * @param scalTech scaling technique + * @param compositeDegree number of moduli in each level (CKKS only) * @param addOne should an extra bit be added (for CKKS and BGV) * * @return log2 of the modulus and number of RNS limbs. */ static std::pair EstimateLogP(uint32_t numPartQ, double firstModulusSize, double dcrtBits, double extraModulusSize, uint32_t numPrimes, uint32_t auxBits, + ScalingTechnique scalTech, uint32_t compositeDegree = 1, bool addOne = false); /* diff --git a/src/pke/lib/scheme/bfvrns/bfvrns-parametergeneration.cpp b/src/pke/lib/scheme/bfvrns/bfvrns-parametergeneration.cpp index ca20f32e4..eeebc2fb8 100644 --- a/src/pke/lib/scheme/bfvrns/bfvrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/bfvrns/bfvrns-parametergeneration.cpp @@ -40,6 +40,10 @@ BFV implementation. See https://eprint.iacr.org/2021/204 for details. #include "scheme/bfvrns/bfvrns-parametergeneration.h" #include "scheme/scheme-utils.h" +#include +#include +#include + namespace lbcrypto { bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr> cryptoParams, @@ -125,7 +129,8 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr(std::ceil(std::ceil(logq) / dcrtBits)); // set the number of digits uint32_t numPartQ = ComputeNumLargeDigits(numDigits, k - 1); - auto hybridKSInfo = CryptoParametersRNS::EstimateLogP(numPartQ, dcrtBits, dcrtBits, 0, k, auxBits); + auto hybridKSInfo = + CryptoParametersRNS::EstimateLogP(numPartQ, dcrtBits, dcrtBits, 0, k, auxBits, scalTech); logq += std::get<0>(hybridKSInfo); } return static_cast( diff --git a/src/pke/lib/scheme/bgvrns/bgvrns-parametergeneration.cpp b/src/pke/lib/scheme/bgvrns/bgvrns-parametergeneration.cpp index c617d53ca..55397939d 100644 --- a/src/pke/lib/scheme/bgvrns/bgvrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/bgvrns/bgvrns-parametergeneration.cpp @@ -39,6 +39,11 @@ BGV implementation. See https://eprint.iacr.org/2021/204 for details. #include "scheme/bgvrns/bgvrns-cryptoparameters.h" #include "scheme/bgvrns/bgvrns-parametergeneration.h" +#include +#include +#include +#include + namespace lbcrypto { uint32_t ParameterGenerationBGVRNS::computeRingDimension( @@ -151,7 +156,7 @@ uint64_t ParameterGenerationBGVRNS::getCyclicOrder(const uint32_t ringDimension, if (pow2ptm < cyclOrder) pow2ptm = cyclOrder; - lcmCyclOrderPtm = (uint64_t)pow2ptm * plaintextModulus; + lcmCyclOrderPtm = static_cast(pow2ptm) * plaintextModulus; } else { lcmCyclOrderPtm = cyclOrder; @@ -451,8 +456,8 @@ bool ParameterGenerationBGVRNS::ParamsGenBGVRNS(std::shared_ptr(hybridKSInfo); auxTowers = std::get<1>(hybridKSInfo); } @@ -484,7 +489,7 @@ bool ParameterGenerationBGVRNS::ParamsGenBGVRNS(std::shared_ptr 1) ? std::log2(moduliQ[1].ConvertToDouble()) : 0, (scalTech == FLEXIBLEAUTOEXT) ? std::log2(moduliQ[moduliQ.size() - 1].ConvertToDouble()) : 0, - (scalTech == FLEXIBLEAUTOEXT) ? moduliQ.size() - 1 : moduliQ.size(), auxBits, false); + (scalTech == FLEXIBLEAUTOEXT) ? moduliQ.size() - 1 : moduliQ.size(), auxBits, scalTech, 1, false); newQBound += std::get<0>(hybridKSInfo); } } while (qBound < newQBound); @@ -511,7 +516,7 @@ bool ParameterGenerationBGVRNS::ParamsGenBGVRNS(std::shared_ptr(pow2ptm) * plaintextModulus; // Get the largest prime with size less or equal to firstModSize bits. moduliQ[0] = LastPrime(firstModSize, modulusOrder); @@ -592,10 +597,10 @@ bool ParameterGenerationBGVRNS::ParamsGenBGVRNS(std::shared_ptr(ptm) % cyclOrder; b = 1; while (a != 1) { - a = ((uint64_t)(a * ptm)) % cyclOrder; + a = static_cast(a * ptm) % cyclOrder; b++; } diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp index 79b0844c6..e7cf142d0 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp @@ -72,10 +72,6 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptrConfigureCompositeDegree(firstModSize); uint32_t compositeDegree = cryptoParamsCKKSRNS->GetCompositeDegree(); uint32_t registerWordSize = cryptoParamsCKKSRNS->GetRegisterWordSize(); - compositeDegree *= static_cast(1); // @fdiasmor: Avoid unused variable compilation error. - registerWordSize *= static_cast(1); // @fdiasmor: Avoid unused variable compilation error. - // Bookeeping unique prime moduli - // std::unordered_set moduliQRecord; if (scalTech == COMPOSITESCALINGAUTO || scalTech == COMPOSITESCALINGMANUAL) { if (compositeDegree > 2 && (firstModSize <= 68 || scalingModSize <= 67)) { @@ -120,7 +116,7 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptr(qBound) / numPartQ) / (tmpFactor * auxBits)) * tmpFactor * auxBits; @@ -171,7 +167,8 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptr +#include +#include + namespace lbcrypto { void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, ScalingTechnique scalTech, @@ -128,7 +132,21 @@ void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scaling maxBits = bits; } // Select number of primes in auxiliary CRT basis - uint32_t sizeP = static_cast(std::ceil(static_cast(maxBits) / auxBits)); + uint32_t sizeP = static_cast(std::ceil(static_cast(maxBits) / auxBits)); + if (GetScalingTechnique() == COMPOSITESCALINGAUTO || GetScalingTechnique() == COMPOSITESCALINGMANUAL) { + usint compositeDegree = GetCompositeDegree(); + switch (compositeDegree) { + case 0: // not allowed + case 1: // not composite + break; + case 2: // composite degree == 2 + sizeP += (sizeP % 2); + break; + default: // composite degree > 2 + sizeP += (sizeP % 4); + break; + } + } uint64_t primeStep = FindAuxPrimeStep(); // Choose special primes in auxiliary basis and compute their roots @@ -387,7 +405,9 @@ uint64_t CryptoParametersRNS::FindAuxPrimeStep() const { std::pair CryptoParametersRNS::EstimateLogP(uint32_t numPartQ, double firstModulusSize, double dcrtBits, double extraModulusSize, - uint32_t numPrimes, uint32_t auxBits, bool addOne) { + uint32_t numPrimes, uint32_t auxBits, + ScalingTechnique scalTech, uint32_t compositeDegree, + bool addOne) { // numPartQ can not be zero as there is a division by numPartQ if (numPartQ == 0) OPENFHE_THROW("numPartQ is zero"); @@ -421,7 +441,8 @@ std::pair CryptoParametersRNS::EstimateLogP(uint32_t numPartQ, size_t endTower = ((j + 1) * numPerPartQ - 1 < sizeQ) ? (j + 1) * numPerPartQ - 1 : sizeQ - 1; // sum qi elements qi[startTower] + ... + qi[endTower] inclusive. the end element should be qi.begin()+(endTower+1) - uint32_t bits = static_cast(std::accumulate(qi.begin() + startTower, qi.begin() + (endTower + 1), 0.0)); + uint32_t bits = + static_cast(std::accumulate(qi.begin() + startTower, qi.begin() + (endTower + 1), 0.0)); if (bits > maxBits) maxBits = bits; } @@ -434,6 +455,20 @@ std::pair CryptoParametersRNS::EstimateLogP(uint32_t numPartQ, // Select number of primes in auxiliary CRT basis auto sizeP = static_cast(std::ceil(static_cast(maxBits) / auxBits)); + if (scalTech == COMPOSITESCALINGAUTO || scalTech == COMPOSITESCALINGMANUAL) { + switch (compositeDegree) { + case 0: // not allowed + case 1: // not composite + break; + case 2: // composite degree == 2 + sizeP += (sizeP % 2); + break; + default: // composite degree > 2 + sizeP += (sizeP % 4); + break; + } + } + return std::make_pair(sizeP * auxBits, sizeP); } From 5d54a9f92a599f5c1b41600eaabc92e2006623ab Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 30 Dec 2024 22:49:13 -0800 Subject: [PATCH 13/21] Update composite-prime generation function. --- src/pke/examples/simple-composite-scaling.cpp | 42 +- .../ckksrns/ckksrns-parametergeneration.cpp | 399 +++++++----------- .../lib/schemerns/rns-cryptoparameters.cpp | 10 +- 3 files changed, 205 insertions(+), 246 deletions(-) diff --git a/src/pke/examples/simple-composite-scaling.cpp b/src/pke/examples/simple-composite-scaling.cpp index 9dc4fce04..efe68a6ec 100644 --- a/src/pke/examples/simple-composite-scaling.cpp +++ b/src/pke/examples/simple-composite-scaling.cpp @@ -41,7 +41,7 @@ using namespace lbcrypto; -int main() { +int main(int argc, char* argv[]) { // Step 1: Setup CryptoContext // A. Specify main parameters @@ -107,6 +107,46 @@ int main() { */ uint32_t registerWordSize = 32; + int argcCount = 1; + if (argc > 1) { + while (argcCount < argc) { + uint32_t paramValue = atoi(argv[argcCount]); + switch (argcCount) { + case 1: + firstModSize = paramValue; + std::cout << "Setting First Mod Size: " << firstModSize << std::endl; + break; + case 2: + scaleModSize = paramValue; + std::cout << "Setting Scaling Mod Size: " << scaleModSize << std::endl; + break; + case 3: + registerWordSize = paramValue; + std::cout << "Setting Register Word Size: " << registerWordSize << std::endl; + break; + case 4: + multDepth = paramValue; + std::cout << "Setting Multiplicative Depth: " << multDepth << std::endl; + break; + default: + std::cout << "Invalid option" << std::endl; + break; + } + argcCount += 1; + std::cout << "argcCount: " << argcCount << std::endl; + } + std::cout << "Complete !" << std::endl; + } + else { + std::cout << "Using default parameters" << std::endl; + std::cout << "First Mod Size: " << firstModSize << std::endl; + std::cout << "Scaling Mod Size: " << scaleModSize << std::endl; + std::cout << "Register Word Size: " << registerWordSize << std::endl; + std::cout << "Multiplicative Depth: " << multDepth << std::endl; + std::cout << "Usage: " << argv[0] << " [firstModSize] [scalingModSize] [registerWordSize] [multDepth]" + << std::endl; + } + /* A4) Desired security level based on FHE standards. * This parameter can take four values. Three of the possible values * correspond to 128-bit, 192-bit, and 256-bit security, and the fourth value diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp index e7cf142d0..8c43b6783 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp @@ -74,13 +74,15 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptrGetRegisterWordSize(); if (scalTech == COMPOSITESCALINGAUTO || scalTech == COMPOSITESCALINGMANUAL) { - if (compositeDegree > 2 && (firstModSize <= 68 || scalingModSize <= 67)) { + if (compositeDegree > 2 && scalingModSize < 55) { OPENFHE_THROW( config_error, - "This COMPOSITESCALING* version does not fully support composite degree > 2 for small prime moduli. Prime moduli size must generally be greater than 22."); + "COMPOSITESCALING Warning: There will probably not be enough prime moduli for composite degree > 2 and scaling factor < 55, prime moduli too small. Prime moduli size must generally be greater than 22, especially for larger multiplicative depth. Try increasing the scaling factor (scalingModSize) or feel free to try it using COMPOSITESCALINGMANUAL at your own risk."); } - else if (compositeDegree == 1 && registerWordSize < 32) { - OPENFHE_THROW(config_error, "This COMPOSITESCALING* version does not support composite degree == 1."); + else if (compositeDegree == 1 && registerWordSize < 64) { + OPENFHE_THROW( + config_error, + "This COMPOSITESCALING* version does not support composite degree == 1 with register size < 64."); } else if (compositeDegree < 1) { OPENFHE_THROW(config_error, "Composite degree must be greater than or equal to 1."); @@ -232,16 +234,12 @@ void ParameterGenerationCKKSRNS::CompositePrimeModuliGen(std::vector moduliQRecord; - std::cout << __FUNCTION__ << "::" << __LINE__ << " numPrimes=" << numPrimes - << " compositeDegree=" << compositeDegree << std::endl; - // Sample q0, the first primes in the modulus chain NativeInteger q; uint32_t qBitSize = static_cast(dcrtBits) / compositeDegree; uint32_t remBits = dcrtBits; for (uint32_t d = 1; d <= compositeDegree; ++d) { - // qBitSize = static_cast(std::ceil(static_cast(remBits) / (compositeDegree - d + 1))); double numBits = static_cast(remBits) / (compositeDegree - d + 1); qBitSize = std::ceil(numBits); q = FirstPrime(qBitSize, cyclOrder); @@ -250,309 +248,236 @@ void ParameterGenerationCKKSRNS::CompositePrimeModuliGen(std::vector(q, cyclOrder); } - std::cout << __FUNCTION__ << "::" << __LINE__ << " d=" << d << " moduliQ=" << q - << " logq2=" << std::log2(q.ConvertToDouble()) << " remBits=" << remBits << "\n"; - std::cout << __FUNCTION__ << "::" << __LINE__ << " d=" << d << " moduliQ=" << q - << " logq2=" << std::log2(q.ConvertToDouble()) << "\n"; moduliQ[numPrimes - d] = q; rootsQ[numPrimes - d] = RootOfUnity(cyclOrder, moduliQ[numPrimes - d]); moduliQRecord.emplace(q.ConvertToInt()); - remBits -= qBitSize; - // remBits -= std::ceil(std::log2(q.ConvertToDouble())); + remBits -= std::ceil(std::log2(q.ConvertToDouble())); } -#ifdef DEBUG_COMPOSITE_SCALING - std::cout << __FUNCTION__ << "::" << __LINE__ << " numPrimes=" << numPrimes - << " compositeDegree=" << compositeDegree << std::endl; -#endif - - // std::vector qPrev(std::ceil(static_cast(compositeDegree) / 2)); - // std::vector qNext(compositeDegree - (uint32_t)qPrev.size()); - std::vector qPrev(1); - std::vector innerPrimes((compositeDegree > 2) ? compositeDegree - 2 : 1); - std::vector qNext(1); - bool altPrevNext = false; + std::vector qPrev(std::ceil(static_cast(compositeDegree) / 2)); + std::vector qNext(compositeDegree - static_cast(qPrev.size())); + // std::vector qPrev(1); + // std::vector innerPrimes((compositeDegree > 2) ? compositeDegree - 2 : 1); + // std::vector qNext(1); + // bool altPrevNext = false; if (numPrimes > 1) { // Prep to compute initial scaling factor double sf = moduliQ[numPrimes - 1].ConvertToDouble(); for (uint32_t d = 2; d <= compositeDegree; ++d) { sf *= moduliQ[numPrimes - d].ConvertToDouble(); - std::cout << __FUNCTION__ << "::" << __LINE__ << " d=" << d << " moduliQ=" << q - << " logq2=" << std::log2(q.ConvertToDouble()) << " sf=" << sf << "\n"; } - std::cout << "Composite degree: " << compositeDegree << std::endl; - uint32_t cnt = 1; for (usint i = numPrimes - compositeDegree; i >= 2 * compositeDegree; i -= compositeDegree) { - std::cout << "Selecting Prime Moduli for L=" << i / compositeDegree << std::endl; // Compute initial scaling factor sf = static_cast(std::pow(sf, 2)); for (usint d = 0; d < compositeDegree; ++d) { - std::cout << "moduliQ[" << i + d << "] = " << moduliQ[i + d] << ", "; sf /= moduliQ[i + d].ConvertToDouble(); } - std::cout << std::endl; - - // denom = moduliQ[i].ConvertToDouble(); - // for (usint d = 1; d < compositeDegree; ++d) { - // denom *= moduliQ[i + d].ConvertToDouble(); - // } auto sf_sqrt = std::pow(sf, 1.0 / compositeDegree); // auto sf_sqrt = std::pow((sf * sf) / denom, 1.0 / compositeDegree); // std::sqrt((sf * sf) / denom); - std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " sf_sqrt=" << sf_sqrt - << " logsf_sqrt2=" << std::ceil(std::log2(sf_sqrt)) << " sf=" << sf << "\n"; qBitSize = std::ceil(std::log2(sf_sqrt)); NativeInteger sfInt = std::llround(sf_sqrt); NativeInteger sfRem = sfInt.Mod(cyclOrder); -#ifdef DEBUG_COMPOSITE_SCALING - std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " sfInt=" << sfInt - << " logq2=" << std::log2(sfInt.ConvertToDouble()) << "\n"; -#endif double primeProduct = 1.0; std::unordered_set qCurrentRecord; // current prime tracker - // for (uint32_t step = 0; step < (uint32_t)qPrev.size(); ++step) { - // //qPrev[step] = sfInt - (NativeInteger(step + 1) * NativeInteger(cyclOrder)) - sfRem + NativeInteger(1); - // qPrev[step] = sfInt - sfRem + NativeInteger(1) - NativeInteger(cyclOrder); - // do { - // // if (step % 2 == 0) { - // // qPrev[step] = lbcrypto::PreviousPrime(qPrev[step], cyclOrder); - // // } else { - // // qPrev[step] = lbcrypto::NextPrime(qPrev[step], cyclOrder); - // // } - // qPrev[step] = lbcrypto::PreviousPrime(qPrev[step], cyclOrder); - // } while (//std::log2(qPrev[step].ConvertToDouble()) > qBitSize || - // std::log2(qPrev[step].ConvertToDouble()) > registerWordSize || - // moduliQRecord.find(qPrev[step].ConvertToInt()) != moduliQRecord.end() || - // qCurrentRecord.find(qPrev[step].ConvertToInt()) != qCurrentRecord.end()); - // qCurrentRecord.emplace(qPrev[step].ConvertToInt()); - // primeProduct *= qPrev[step].ConvertToDouble(); - // // sfInt = qPrev[step]; - // // sfRem = sfInt.Mod(cyclOrder); - // } - - for (uint32_t step = 0; step < compositeDegree - 2; step++) { - std::cout << "step: " << step << std::endl; - // innerPrimes[step] = sfInt - (NativeInteger(step + 1) * NativeInteger(cyclOrder)) - sfRem + NativeInteger(1); - // innerPrimes[step] = sfInt - sfRem + NativeInteger(1); - if (altPrevNext) { - innerPrimes[step] = sfInt - sfRem + NativeInteger(1) - NativeInteger(cyclOrder); - // innerPrimes[step] = lbcrypto::PreviousPrime(innerPrimes[step], cyclOrder); - } - else { - innerPrimes[step] = sfInt - sfRem + NativeInteger(1) + NativeInteger(cyclOrder); - // innerPrimes[step] = lbcrypto::NextPrime(innerPrimes[step], cyclOrder); - } + for (uint32_t step = 0; step < static_cast(qPrev.size()); ++step) { + qPrev[step] = sfInt - sfRem + NativeInteger(1) - NativeInteger(cyclOrder); do { - switch (altPrevNext) { - case true: - innerPrimes[step] = lbcrypto::PreviousPrime(innerPrimes[step], cyclOrder); - break; - default: - innerPrimes[step] = lbcrypto::NextPrime(innerPrimes[step], cyclOrder); - break; + try { + qPrev[step] = lbcrypto::PreviousPrime(qPrev[step], cyclOrder); } - } while (std::log2(innerPrimes[step].ConvertToDouble()) > registerWordSize || - moduliQRecord.find(innerPrimes[step].ConvertToInt()) != moduliQRecord.end() || - qCurrentRecord.find(innerPrimes[step].ConvertToInt()) != qCurrentRecord.end()); - qCurrentRecord.emplace(innerPrimes[step].ConvertToInt()); - primeProduct *= innerPrimes[step].ConvertToDouble(); - - altPrevNext = !altPrevNext; - - sfInt = innerPrimes[step]; - sfRem = sfInt.Mod(cyclOrder); + catch (const OpenFHEException& ex) { + OPENFHE_THROW( + config_error, + "COMPOSITE SCALING previous prime sampling error. Try increasing scaling factor (scalingModSize)."); + } + } while ( // std::log2(qPrev[step].ConvertToDouble()) > qBitSize || + std::log2(qPrev[step].ConvertToDouble()) > registerWordSize || + moduliQRecord.find(qPrev[step].ConvertToInt()) != moduliQRecord.end() || + qCurrentRecord.find(qPrev[step].ConvertToInt()) != qCurrentRecord.end()); + qCurrentRecord.emplace(qPrev[step].ConvertToInt()); + primeProduct *= qPrev[step].ConvertToDouble(); + // sfInt = qPrev[step]; + // sfRem = sfInt.Mod(cyclOrder); } - qPrev[0] = sfInt - sfRem + NativeInteger(1) - NativeInteger(cyclOrder); - do { - qPrev[0] = lbcrypto::PreviousPrime(qPrev[0], cyclOrder); - } while (std::log2(qPrev[0].ConvertToDouble()) > registerWordSize || - moduliQRecord.find(qPrev[0].ConvertToInt()) != moduliQRecord.end() || - qCurrentRecord.find(qPrev[0].ConvertToInt()) != qCurrentRecord.end()); - qCurrentRecord.emplace(qPrev[0].ConvertToInt()); - primeProduct *= qPrev[0].ConvertToDouble(); - sfInt = qPrev[0]; - sfRem = sfInt.Mod(cyclOrder); - - qNext[0] = sfInt - sfRem + NativeInteger(1) + NativeInteger(cyclOrder); - std::cout << "find last prime" << std::endl; - do { - std::cout << "qNext[0]: " << qNext[0] << std::endl; - qNext[0] = lbcrypto::NextPrime(qNext[0], cyclOrder); - } while (std::log2(qNext[0].ConvertToDouble()) > registerWordSize || - moduliQRecord.find(qNext[0].ConvertToInt()) != moduliQRecord.end() || - qCurrentRecord.find(qNext[0].ConvertToInt()) != qCurrentRecord.end()); - qCurrentRecord.emplace(qNext[0].ConvertToInt()); - primeProduct *= qNext[0].ConvertToDouble(); - sfInt = qNext[0]; - sfRem = sfInt.Mod(cyclOrder); - - // for (uint32_t step = 0; step < (uint32_t)qNext.size(); ++step) { - // // qNext[step] = sfInt + (NativeInteger(step + 1) * NativeInteger(cyclOrder)) - sfRem + NativeInteger(1); - // qNext[step] = sfInt - sfRem + NativeInteger(1) + NativeInteger(cyclOrder); - // // qBitSize = std::ceil(std::log2(qNext[step].ConvertToDouble())); - // // qNext[step] = FirstPrime(qBitSize, cyclOrder); - // // qNext[step] = NextPrime(q, cyclOrder); + // for (uint32_t step = 0; step < compositeDegree - 2; step++) { + // std::cout << "step: " << step << std::endl; + // // innerPrimes[step] = sfInt - (NativeInteger(step + 1) * NativeInteger(cyclOrder)) - sfRem + NativeInteger(1); + // // innerPrimes[step] = sfInt - sfRem + NativeInteger(1); + // if (altPrevNext) { + // innerPrimes[step] = sfInt - sfRem + NativeInteger(1) - NativeInteger(cyclOrder); + // // innerPrimes[step] = lbcrypto::PreviousPrime(innerPrimes[step], cyclOrder); + // } + // else { + // innerPrimes[step] = sfInt - sfRem + NativeInteger(1) + NativeInteger(cyclOrder); + // // innerPrimes[step] = lbcrypto::NextPrime(innerPrimes[step], cyclOrder); + // } // do { - // // if (step % 2) { - // // qNext[step] = lbcrypto::NextPrime(qNext[step], cyclOrder); - // // } else { - // // qNext[step] = lbcrypto::PreviousPrime(qNext[step], cyclOrder); - // // } - // qNext[step] = lbcrypto::NextPrime(qNext[step], cyclOrder); - // } while (//std::log2(qNext[step].ConvertToDouble()) > qBitSize || - // std::log2(qNext[step].ConvertToDouble()) > registerWordSize || - // moduliQRecord.find(qNext[step].ConvertToInt()) != moduliQRecord.end() || - // qCurrentRecord.find(qNext[step].ConvertToInt()) != qCurrentRecord.end()); - // qCurrentRecord.emplace(qNext[step].ConvertToInt()); - // primeProduct *= qNext[step].ConvertToDouble(); - // // sfInt = qNext[step]; - // // sfRem = sfInt.Mod(cyclOrder); + // switch (altPrevNext) { + // case true: + // innerPrimes[step] = lbcrypto::PreviousPrime(innerPrimes[step], cyclOrder); + // break; + // default: + // innerPrimes[step] = lbcrypto::NextPrime(innerPrimes[step], cyclOrder); + // break; + // } + // } while (std::log2(innerPrimes[step].ConvertToDouble()) > registerWordSize || + // moduliQRecord.find(innerPrimes[step].ConvertToInt()) != moduliQRecord.end() || + // qCurrentRecord.find(innerPrimes[step].ConvertToInt()) != qCurrentRecord.end()); + // qCurrentRecord.emplace(innerPrimes[step].ConvertToInt()); + // primeProduct *= innerPrimes[step].ConvertToDouble(); + + // altPrevNext = !altPrevNext; + + // sfInt = innerPrimes[step]; + // sfRem = sfInt.Mod(cyclOrder); // } -#ifdef DEBUG_COMPOSITE_SCALING - std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " primeProduct=" << primeProduct - << " sf=" << sf << "\n"; -#endif + // qPrev[0] = sfInt - sfRem + NativeInteger(1) - NativeInteger(cyclOrder); + // do { + // qPrev[0] = lbcrypto::PreviousPrime(qPrev[0], cyclOrder); + // } while (std::log2(qPrev[0].ConvertToDouble()) > registerWordSize || + // moduliQRecord.find(qPrev[0].ConvertToInt()) != moduliQRecord.end() || + // qCurrentRecord.find(qPrev[0].ConvertToInt()) != qCurrentRecord.end()); + // qCurrentRecord.emplace(qPrev[0].ConvertToInt()); + // primeProduct *= qPrev[0].ConvertToDouble(); + // sfInt = qPrev[0]; + // sfRem = sfInt.Mod(cyclOrder); + + // qNext[0] = sfInt - sfRem + NativeInteger(1) + NativeInteger(cyclOrder); + // std::cout << "find last prime" << std::endl; + // do { + // std::cout << "qNext[0]: " << qNext[0] << std::endl; + // qNext[0] = lbcrypto::NextPrime(qNext[0], cyclOrder); + // } while (std::log2(qNext[0].ConvertToDouble()) > registerWordSize || + // moduliQRecord.find(qNext[0].ConvertToInt()) != moduliQRecord.end() || + // qCurrentRecord.find(qNext[0].ConvertToInt()) != qCurrentRecord.end()); + // qCurrentRecord.emplace(qNext[0].ConvertToInt()); + // primeProduct *= qNext[0].ConvertToDouble(); + // sfInt = qNext[0]; + // sfRem = sfInt.Mod(cyclOrder); + + for (uint32_t step = 0; step < static_cast(qNext.size()); ++step) { + qNext[step] = sfInt - sfRem + NativeInteger(1) + NativeInteger(cyclOrder); + do { + try { + qNext[step] = lbcrypto::NextPrime(qNext[step], cyclOrder); + } + catch (const OpenFHEException& ex) { + OPENFHE_THROW( + config_error, + "COMPOSITE SCALING next prime sampling error. Try increasing scaling factor (scalingModSize)."); + } + } while ( // std::log2(qNext[step].ConvertToDouble()) > qBitSize || + std::log2(qNext[step].ConvertToDouble()) > registerWordSize || + moduliQRecord.find(qNext[step].ConvertToInt()) != moduliQRecord.end() || + qCurrentRecord.find(qNext[step].ConvertToInt()) != qCurrentRecord.end()); + qCurrentRecord.emplace(qNext[step].ConvertToInt()); + primeProduct *= qNext[step].ConvertToDouble(); + // sfInt = qNext[step]; + // sfRem = sfInt.Mod(cyclOrder); + } if (cnt == 0) { - // NativeInteger qPrevNext = NativeInteger(qNext[qNext.size() - 1].ConvertToInt()); - NativeInteger qPrevNext = NativeInteger(qNext[0].ConvertToInt()); -#ifdef DEBUG_COMPOSITE_SCALING - std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " qPrevPrev=" << qPrevPrev << "\n"; -#endif + NativeInteger qPrevNext = NativeInteger(qNext[qNext.size() - 1].ConvertToInt()); + // NativeInteger qPrevNext = NativeInteger(qNext[0].ConvertToInt()); while (primeProduct > sf) { - // while (primeProduct > sf0) { do { qCurrentRecord.erase(qPrevNext.ConvertToInt()); // constant time - qPrevNext = lbcrypto::PreviousPrime(qPrevNext, cyclOrder); + try { + qPrevNext = lbcrypto::PreviousPrime(qPrevNext, cyclOrder); + } + catch (const OpenFHEException& ex) { + OPENFHE_THROW( + config_error, + "COMPOSITE SCALING previous prime sampling error. Try increasing scaling factor (scalingModSize)."); + } } while ( // std::log2(qPrevNext.ConvertToDouble()) > qBitSize || std::log2(qPrevNext.ConvertToDouble()) > registerWordSize || moduliQRecord.find(qPrevNext.ConvertToInt()) != moduliQRecord.end() || qCurrentRecord.find(qPrevNext.ConvertToInt()) != qCurrentRecord.end()); qCurrentRecord.emplace(qPrevNext.ConvertToInt()); -#ifdef DEBUG_COMPOSITE_SCALING - std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " primeFound=" << qPrevPrev - << " primeProduct=" << primeProduct << " sf=" << sf << "\n"; -#endif - - // primeProduct /= qNext[qNext.size() - 1].ConvertToDouble(); - // qNext[qNext.size() - 1] = qPrevNext; - primeProduct /= qNext[0].ConvertToDouble(); - qNext[0] = qPrevNext; + primeProduct /= qNext[qNext.size() - 1].ConvertToDouble(); + qNext[qNext.size() - 1] = qPrevNext; + // primeProduct /= qNext[0].ConvertToDouble(); + // qNext[0] = qPrevNext; primeProduct *= qPrevNext.ConvertToDouble(); + } - if (std::log2(primeProduct) > std::log2(sf)) { - std::cout << "************* VIOLATION ************* cnt: " << cnt << std::endl; - std::cout << "primeProduct " << (numPrimes - i) / compositeDegree << ": " << primeProduct - << " > sf: " << sf << " log2(primeProduct): " << std::log2(primeProduct) - << " log2(sf): " << std::log2(sf) << std::endl; - } + // moduliQ[i - 1] = qPrev[0]; + // for (uint32_t d = 2; d < compositeDegree; ++d) { + // moduliQ[i - d] = innerPrimes[d - 2]; + // } + // moduliQ[i - compositeDegree] = qNext[0]; -#ifdef DEBUG_COMPOSITE_SCALING - std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " qPrevPrev" << qPrevPrev - << " logq2=" << std::log2(qPrevPrev.ConvertToDouble()) << " primeProduct=" << primeProduct - << " sf=" << sf << "\n"; -#endif + uint32_t m = qPrev.size(); + for (uint32_t d = 1; d <= m; ++d) { + moduliQ[i - d] = qPrev[d - 1]; } - - moduliQ[i - 1] = qPrev[0]; - for (uint32_t d = 2; d < compositeDegree; ++d) { - moduliQ[i - d] = innerPrimes[d - 2]; + for (uint32_t d = m + 1; d <= compositeDegree; ++d) { + moduliQ[i - d] = qNext[d - (m + 1)]; } - moduliQ[i - compositeDegree] = qNext[0]; - - // uint32_t m = qPrev.size(); - // for (uint32_t d = 1; d <= m; ++d) { - // moduliQ[i - d] = qPrev[d - 1]; - // } - // for (uint32_t d = m+1; d <= compositeDegree; ++d) { - // moduliQ[i - d] = qNext[d - (m+1)]; - // } for (uint32_t d = 1; d <= compositeDegree; ++d) { - std::cout << __FUNCTION__ << "::" << __LINE__ << " i: " << i << " moduliQ: " << moduliQ[i - d] - << " logq2: " << std::log2(moduliQ[i - d].ConvertToDouble()) << "\n"; rootsQ[i - d] = RootOfUnity(cyclOrder, moduliQ[i - d]); moduliQRecord.emplace(moduliQ[i - d].ConvertToInt()); } - // //#ifdef DEBUG_COMPOSITE_SCALING - // std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " moduliQ=" << moduliQ[i - d] - // << " logq2=" << std::log2(moduliQ[i - d].ConvertToDouble()) << "\n"; - // //#endif - // rootsQ[i - d] = RootOfUnity(cyclOrder, moduliQ[i - d]); - // moduliQRecord.emplace(moduliQ[i - d].ConvertToInt()); - // } cnt = 1; } else { - // NativeInteger qNextPrev = NativeInteger(qPrev[qPrev.size()-1].ConvertToInt()); - NativeInteger qNextPrev = NativeInteger(qPrev[0].ConvertToInt()); -#ifdef DEBUG_COMPOSITE_SCALING - std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " qNextNext=" << qNextNext << "\n"; -#endif + NativeInteger qNextPrev = NativeInteger(qPrev[qPrev.size() - 1].ConvertToInt()); + // NativeInteger qNextPrev = NativeInteger(qPrev[0].ConvertToInt()); + while (primeProduct < sf) { - // while (primeProduct < sf0) { do { qCurrentRecord.erase(qNextPrev.ConvertToInt()); // constant time - qNextPrev = lbcrypto::NextPrime(qNextPrev, cyclOrder); + try { + qNextPrev = lbcrypto::NextPrime(qNextPrev, cyclOrder); + } + catch (const OpenFHEException& ex) { + OPENFHE_THROW( + config_error, + "COMPOSITE SCALING next prime sampling error. Try increasing scaling factor (scalingModSize)."); + } } while ( // std::log2(qNextPrev.ConvertToDouble()) > qBitSize || std::log2(qNextPrev.ConvertToDouble()) > registerWordSize || moduliQRecord.find(qNextPrev.ConvertToInt()) != moduliQRecord.end() || qCurrentRecord.find(qNextPrev.ConvertToInt()) != qCurrentRecord.end()); qCurrentRecord.emplace(qNextPrev.ConvertToInt()); -#ifdef DEBUG_COMPOSITE_SCALING - std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " primeFound=" << qNextNext - << " primeProduct=" << primeProduct << " sf=" << sf << "\n"; -#endif - // primeProduct /= qPrev[qPrev.size()-1].ConvertToDouble(); - // qPrev[qPrev.size()-1] = qNextPrev; - primeProduct /= qPrev[0].ConvertToDouble(); - qPrev[0] = qNextPrev; + primeProduct /= qPrev[qPrev.size() - 1].ConvertToDouble(); + qPrev[qPrev.size() - 1] = qNextPrev; + // primeProduct /= qPrev[0].ConvertToDouble(); + // qPrev[0] = qNextPrev; primeProduct *= qNextPrev.ConvertToDouble(); - - if (std::log2(primeProduct) > std::log2(sf)) { - std::cout << "************* VIOLATION ************* cnt: " << cnt << std::endl; - std::cout << "primeProduct " << (numPrimes - i) / compositeDegree << ": " << primeProduct - << " > sf: " << sf << " log2(primeProduct): " << std::log2(primeProduct) - << " log2(sf): " << std::log2(sf) << std::endl; - } - -#ifdef DEBUG_COMPOSITE_SCALING - std::cout << __FUNCTION__ << "::" << __LINE__ << " i=" << i << " qNextNext" << qNextNext - << " logq2=" << std::log2(qNextNext.ConvertToDouble()) << " primeProduct=" << primeProduct - << " sf=" << sf << "\n"; -#endif } // assgin samples prime moduli to the chain - moduliQ[i - 1] = qPrev[0]; - for (uint32_t d = 2; d < compositeDegree; ++d) { - moduliQ[i - d] = innerPrimes[d - 2]; - } - moduliQ[i - compositeDegree] = qNext[0]; - - // uint32_t m = qPrev.size(); - // for (uint32_t d = 1; d <= m; ++d) { - // moduliQ[i - d] = qPrev[d - 1]; - // } - // for (uint32_t d = m+1; d <= compositeDegree; ++d) { - // moduliQ[i - d] = qNext[d - (m+1)]; + // moduliQ[i - 1] = qPrev[0]; + // for (uint32_t d = 2; d < compositeDegree; ++d) { + // moduliQ[i - d] = innerPrimes[d - 2]; // } + // moduliQ[i - compositeDegree] = qNext[0]; + + uint32_t m = qPrev.size(); + for (uint32_t d = 1; d <= m; ++d) { + moduliQ[i - d] = qPrev[d - 1]; + } + for (uint32_t d = m + 1; d <= compositeDegree; ++d) { + moduliQ[i - d] = qNext[d - (m + 1)]; + } for (uint32_t d = 1; d <= compositeDegree; ++d) { - std::cout << __FUNCTION__ << "::" << __LINE__ << " i: " << i << " moduliQ: " << moduliQ[i - d] - << " logq2: " << std::log2(moduliQ[i - d].ConvertToDouble()) << "\n"; rootsQ[i - d] = RootOfUnity(cyclOrder, moduliQ[i - d]); moduliQRecord.emplace(moduliQ[i - d].ConvertToInt()); } @@ -586,21 +511,9 @@ void ParameterGenerationCKKSRNS::CompositePrimeModuliGen(std::vector Date: Thu, 2 Jan 2025 18:30:28 -0800 Subject: [PATCH 14/21] Remove comments from prime gen function. --- .../ckksrns/ckksrns-parametergeneration.cpp | 104 ++---------------- 1 file changed, 8 insertions(+), 96 deletions(-) diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp index 8c43b6783..162b172b2 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp @@ -256,10 +256,6 @@ void ParameterGenerationCKKSRNS::CompositePrimeModuliGen(std::vector qPrev(std::ceil(static_cast(compositeDegree) / 2)); std::vector qNext(compositeDegree - static_cast(qPrev.size())); - // std::vector qPrev(1); - // std::vector innerPrimes((compositeDegree > 2) ? compositeDegree - 2 : 1); - // std::vector qNext(1); - // bool altPrevNext = false; if (numPrimes > 1) { // Prep to compute initial scaling factor @@ -277,7 +273,6 @@ void ParameterGenerationCKKSRNS::CompositePrimeModuliGen(std::vector registerWordSize || - // moduliQRecord.find(innerPrimes[step].ConvertToInt()) != moduliQRecord.end() || - // qCurrentRecord.find(innerPrimes[step].ConvertToInt()) != qCurrentRecord.end()); - // qCurrentRecord.emplace(innerPrimes[step].ConvertToInt()); - // primeProduct *= innerPrimes[step].ConvertToDouble(); - - // altPrevNext = !altPrevNext; - - // sfInt = innerPrimes[step]; - // sfRem = sfInt.Mod(cyclOrder); - // } - - // qPrev[0] = sfInt - sfRem + NativeInteger(1) - NativeInteger(cyclOrder); - // do { - // qPrev[0] = lbcrypto::PreviousPrime(qPrev[0], cyclOrder); - // } while (std::log2(qPrev[0].ConvertToDouble()) > registerWordSize || - // moduliQRecord.find(qPrev[0].ConvertToInt()) != moduliQRecord.end() || - // qCurrentRecord.find(qPrev[0].ConvertToInt()) != qCurrentRecord.end()); - // qCurrentRecord.emplace(qPrev[0].ConvertToInt()); - // primeProduct *= qPrev[0].ConvertToDouble(); - // sfInt = qPrev[0]; - // sfRem = sfInt.Mod(cyclOrder); - - // qNext[0] = sfInt - sfRem + NativeInteger(1) + NativeInteger(cyclOrder); - // std::cout << "find last prime" << std::endl; - // do { - // std::cout << "qNext[0]: " << qNext[0] << std::endl; - // qNext[0] = lbcrypto::NextPrime(qNext[0], cyclOrder); - // } while (std::log2(qNext[0].ConvertToDouble()) > registerWordSize || - // moduliQRecord.find(qNext[0].ConvertToInt()) != moduliQRecord.end() || - // qCurrentRecord.find(qNext[0].ConvertToInt()) != qCurrentRecord.end()); - // qCurrentRecord.emplace(qNext[0].ConvertToInt()); - // primeProduct *= qNext[0].ConvertToDouble(); - // sfInt = qNext[0]; - // sfRem = sfInt.Mod(cyclOrder); - for (uint32_t step = 0; step < static_cast(qNext.size()); ++step) { qNext[step] = sfInt - sfRem + NativeInteger(1) + NativeInteger(cyclOrder); do { @@ -376,19 +312,15 @@ void ParameterGenerationCKKSRNS::CompositePrimeModuliGen(std::vector qBitSize || - std::log2(qNext[step].ConvertToDouble()) > registerWordSize || - moduliQRecord.find(qNext[step].ConvertToInt()) != moduliQRecord.end() || - qCurrentRecord.find(qNext[step].ConvertToInt()) != qCurrentRecord.end()); + } while (std::log2(qNext[step].ConvertToDouble()) > registerWordSize || + moduliQRecord.find(qNext[step].ConvertToInt()) != moduliQRecord.end() || + qCurrentRecord.find(qNext[step].ConvertToInt()) != qCurrentRecord.end()); qCurrentRecord.emplace(qNext[step].ConvertToInt()); primeProduct *= qNext[step].ConvertToDouble(); - // sfInt = qNext[step]; - // sfRem = sfInt.Mod(cyclOrder); } if (cnt == 0) { NativeInteger qPrevNext = NativeInteger(qNext[qNext.size() - 1].ConvertToInt()); - // NativeInteger qPrevNext = NativeInteger(qNext[0].ConvertToInt()); while (primeProduct > sf) { do { qCurrentRecord.erase(qPrevNext.ConvertToInt()); // constant time @@ -400,25 +332,16 @@ void ParameterGenerationCKKSRNS::CompositePrimeModuliGen(std::vector qBitSize || - std::log2(qPrevNext.ConvertToDouble()) > registerWordSize || - moduliQRecord.find(qPrevNext.ConvertToInt()) != moduliQRecord.end() || - qCurrentRecord.find(qPrevNext.ConvertToInt()) != qCurrentRecord.end()); + } while (std::log2(qPrevNext.ConvertToDouble()) > registerWordSize || + moduliQRecord.find(qPrevNext.ConvertToInt()) != moduliQRecord.end() || + qCurrentRecord.find(qPrevNext.ConvertToInt()) != qCurrentRecord.end()); qCurrentRecord.emplace(qPrevNext.ConvertToInt()); primeProduct /= qNext[qNext.size() - 1].ConvertToDouble(); qNext[qNext.size() - 1] = qPrevNext; - // primeProduct /= qNext[0].ConvertToDouble(); - // qNext[0] = qPrevNext; primeProduct *= qPrevNext.ConvertToDouble(); } - // moduliQ[i - 1] = qPrev[0]; - // for (uint32_t d = 2; d < compositeDegree; ++d) { - // moduliQ[i - d] = innerPrimes[d - 2]; - // } - // moduliQ[i - compositeDegree] = qNext[0]; - uint32_t m = qPrev.size(); for (uint32_t d = 1; d <= m; ++d) { moduliQ[i - d] = qPrev[d - 1]; @@ -436,7 +359,6 @@ void ParameterGenerationCKKSRNS::CompositePrimeModuliGen(std::vector(qBitSize, cyclOrder); nextInteger = PreviousPrime(nextInteger, cyclOrder); - // nextInteger = NextPrime(nextInteger, cyclOrder); - // Ensure it fits in 32-bit register + while (std::log2(nextInteger.ConvertToDouble()) > qBitSize || std::log2(nextInteger.ConvertToDouble()) > registerWordSize || moduliQRecord.find(nextInteger.ConvertToInt()) != moduliQRecord.end()) nextInteger = PreviousPrime(nextInteger, cyclOrder); - // nextInteger = NextPrime(nextInteger, cyclOrder); + // Store prime moduliQ[d - 1] = nextInteger; rootsQ[d - 1] = RootOfUnity(cyclOrder, moduliQ[d - 1]); From 9a7ad26175d39b825b20dee92f0bffbf80bedce5 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 24 Dec 2024 17:58:46 -0800 Subject: [PATCH 15/21] Update composite scaling unittests and fix unittest runtime issue. --- .../include/scheme/gen-cryptocontext-params.h | 2 +- .../utbgvrns/UnitTestBGVrnsAutomorphism.csv | 142 +++++++++--------- .../UnitTestInteractiveBootstrap.csv | 36 ++--- src/pke/unittest/utils/UnitTestUtils.h | 1 + 4 files changed, 91 insertions(+), 90 deletions(-) diff --git a/src/pke/include/scheme/gen-cryptocontext-params.h b/src/pke/include/scheme/gen-cryptocontext-params.h index e9bd084fc..1e8b25221 100644 --- a/src/pke/include/scheme/gen-cryptocontext-params.h +++ b/src/pke/include/scheme/gen-cryptocontext-params.h @@ -252,7 +252,7 @@ class Params { "statisticalSecurity", "numAdversarialQueries", "thresholdNumOfParties", - "interactiveBootCompressionLevel" + "interactiveBootCompressionLevel", "compositeDegree", "registerWordSize"}; } diff --git a/src/pke/unittest/utbgvrns/UnitTestBGVrnsAutomorphism.csv b/src/pke/unittest/utbgvrns/UnitTestBGVrnsAutomorphism.csv index 4c9fe0241..f8b7edde1 100644 --- a/src/pke/unittest/utbgvrns/UnitTestBGVrnsAutomorphism.csv +++ b/src/pke/unittest/utbgvrns/UnitTestBGVrnsAutomorphism.csv @@ -1,71 +1,71 @@ -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,Error,indexList -BGVRNS_AUTOMORPHISM,1,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,2,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,3,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,4,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,5,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,6,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,7,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,8,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,9,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,10,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,11,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,12,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,13,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,14,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,15,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,16,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,17,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,18,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,19,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,20,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,21,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,22,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,23,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,24,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,Error,indexList -EVAL_AT_INDX_PACKED_ARRAY,31,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,32,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 -EVAL_AT_INDX_PACKED_ARRAY,33,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,34,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,35,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,36,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,37,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,38,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 -EVAL_AT_INDX_PACKED_ARRAY,39,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,40,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,41,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,42,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,43,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,44,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 -EVAL_AT_INDX_PACKED_ARRAY,45,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,46,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,47,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,48,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,49,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,50,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 -EVAL_AT_INDX_PACKED_ARRAY,51,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,52,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,53,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,54,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,Error,indexList -EVAL_SUM_PACKED_ARRAY,61,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, -EVAL_SUM_PACKED_ARRAY,62,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, -EVAL_SUM_PACKED_ARRAY,63,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, -EVAL_SUM_PACKED_ARRAY,64,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, -EVAL_SUM_PACKED_ARRAY,65,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, -EVAL_SUM_PACKED_ARRAY,66,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, -EVAL_SUM_PACKED_ARRAY,67,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, -EVAL_SUM_PACKED_ARRAY,68,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, -EVAL_SUM_PACKED_ARRAY,69,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, -EVAL_SUM_PACKED_ARRAY,70,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, -EVAL_SUM_PACKED_ARRAY,71,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, -EVAL_SUM_PACKED_ARRAY,72,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, -EVAL_SUM_PACKED_ARRAY,73,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, -EVAL_SUM_PACKED_ARRAY,74,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, -EVAL_SUM_PACKED_ARRAY,75,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, -EVAL_SUM_PACKED_ARRAY,76,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, -EVAL_SUM_PACKED_ARRAY,77,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, -EVAL_SUM_PACKED_ARRAY,78,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, -EVAL_SUM_PACKED_ARRAY,79,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, -EVAL_SUM_PACKED_ARRAY,80,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,compositeDegree,registerWordSize,Error,indexList +BGVRNS_AUTOMORPHISM,1,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,2,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,3,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,4,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,5,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,6,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,7,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,8,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,9,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,10,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,11,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,12,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,13,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,14,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,15,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,16,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,17,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,18,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,19,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,20,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,21,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,22,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,23,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,24,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,compositeDegree,registerWordSize,Error,indexList +EVAL_AT_INDX_PACKED_ARRAY,31,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,32,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 +EVAL_AT_INDX_PACKED_ARRAY,33,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,34,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,35,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,36,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,37,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,38,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 +EVAL_AT_INDX_PACKED_ARRAY,39,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,40,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,41,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,42,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,43,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,44,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 +EVAL_AT_INDX_PACKED_ARRAY,45,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,46,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,47,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,48,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,49,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,50,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 +EVAL_AT_INDX_PACKED_ARRAY,51,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,52,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,53,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,54,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,compositeDegree,registerWordSize,Error,indexList +EVAL_SUM_PACKED_ARRAY,61,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, +EVAL_SUM_PACKED_ARRAY,62,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, +EVAL_SUM_PACKED_ARRAY,63,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, +EVAL_SUM_PACKED_ARRAY,64,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, +EVAL_SUM_PACKED_ARRAY,65,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, +EVAL_SUM_PACKED_ARRAY,66,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, +EVAL_SUM_PACKED_ARRAY,67,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, +EVAL_SUM_PACKED_ARRAY,68,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, +EVAL_SUM_PACKED_ARRAY,69,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, +EVAL_SUM_PACKED_ARRAY,70,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, +EVAL_SUM_PACKED_ARRAY,71,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, +EVAL_SUM_PACKED_ARRAY,72,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, +EVAL_SUM_PACKED_ARRAY,73,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, +EVAL_SUM_PACKED_ARRAY,74,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, +EVAL_SUM_PACKED_ARRAY,75,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, +EVAL_SUM_PACKED_ARRAY,76,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, +EVAL_SUM_PACKED_ARRAY,77,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, +EVAL_SUM_PACKED_ARRAY,78,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, +EVAL_SUM_PACKED_ARRAY,79,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, +EVAL_SUM_PACKED_ARRAY,80,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, diff --git a/src/pke/unittest/utckksrns/UnitTestInteractiveBootstrap.csv b/src/pke/unittest/utckksrns/UnitTestInteractiveBootstrap.csv index 4c1e56efb..2ef3bc4d5 100644 --- a/src/pke/unittest/utckksrns/UnitTestInteractiveBootstrap.csv +++ b/src/pke/unittest/utckksrns/UnitTestInteractiveBootstrap.csv @@ -1,18 +1,18 @@ -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,numParties -INTERACTIVE_MP_BOOT,1,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,3 -INTERACTIVE_MP_BOOT,2,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,3 -INTERACTIVE_MP_BOOT,3,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,3 -INTERACTIVE_MP_BOOT,4,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,3 -INTERACTIVE_MP_BOOT,5,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,3 -INTERACTIVE_MP_BOOT,6,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,3 -INTERACTIVE_MP_BOOT,7,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,3 -INTERACTIVE_MP_BOOT,8,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,3 -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,numParties -INTERACTIVE_MP_BOOT_CHEBYSHEV,1,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK, -INTERACTIVE_MP_BOOT_CHEBYSHEV,2,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK, -INTERACTIVE_MP_BOOT_CHEBYSHEV,3,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK, -INTERACTIVE_MP_BOOT_CHEBYSHEV,4,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK, -INTERACTIVE_MP_BOOT_CHEBYSHEV,5,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT, -INTERACTIVE_MP_BOOT_CHEBYSHEV,6,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT, -INTERACTIVE_MP_BOOT_CHEBYSHEV,7,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT, -INTERACTIVE_MP_BOOT_CHEBYSHEV,8,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT, +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,compositeDegree,registerWordSize,numParties +INTERACTIVE_MP_BOOT,1,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,,3 +INTERACTIVE_MP_BOOT,2,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,,3 +INTERACTIVE_MP_BOOT,3,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,,3 +INTERACTIVE_MP_BOOT,4,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,,3 +INTERACTIVE_MP_BOOT,5,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,,3 +INTERACTIVE_MP_BOOT,6,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,,3 +INTERACTIVE_MP_BOOT,7,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,,3 +INTERACTIVE_MP_BOOT,8,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,,3 +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,compositeDegree,registerWordSize,numParties +INTERACTIVE_MP_BOOT_CHEBYSHEV,1,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,2,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,3,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,4,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,5,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,6,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,7,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,8,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,, diff --git a/src/pke/unittest/utils/UnitTestUtils.h b/src/pke/unittest/utils/UnitTestUtils.h index b6bdefe8d..c90337e55 100644 --- a/src/pke/unittest/utils/UnitTestUtils.h +++ b/src/pke/unittest/utils/UnitTestUtils.h @@ -43,6 +43,7 @@ #include #include #include +#include // some functions are inlined in this files to avoid link errors //=========================================================================================================== From c8c76a83e3b7fb232b5bf83f50218e4a3d1d920f Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 7 Jan 2025 17:10:27 -0800 Subject: [PATCH 16/21] Some review changes. --- .../include/scheme/gen-cryptocontext-params-defaults.h | 6 +++--- src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp | 9 ++++----- src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp | 2 +- .../lib/scheme/ckksrns/ckksrns-parametergeneration.cpp | 8 +------- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/pke/include/scheme/gen-cryptocontext-params-defaults.h b/src/pke/include/scheme/gen-cryptocontext-params-defaults.h index db03ee39d..8693417aa 100644 --- a/src/pke/include/scheme/gen-cryptocontext-params-defaults.h +++ b/src/pke/include/scheme/gen-cryptocontext-params-defaults.h @@ -81,7 +81,7 @@ constexpr uint32_t statisticalSecurity = 30; constexpr uint32_t numAdversarialQueries = 1; constexpr uint32_t thresholdNumOfParties = 1; constexpr COMPRESSION_LEVEL interactiveBootCompressionLevel = SLACK; -constexpr uint32_t compositeDegree = BASE_NUM_LEVELS_TO_DROP; +constexpr uint32_t compositeDegree = 1; constexpr uint32_t registerWordSize = NATIVEINT; }; // namespace CKKSRNS_SCHEME_DEFAULTS @@ -120,7 +120,7 @@ constexpr uint32_t statisticalSecurity = 0; constexpr uint32_t numAdversarialQueries = 0; constexpr uint32_t thresholdNumOfParties = 1; constexpr COMPRESSION_LEVEL interactiveBootCompressionLevel = SLACK; -constexpr uint32_t compositeDegree = BASE_NUM_LEVELS_TO_DROP; +constexpr uint32_t compositeDegree = 1; constexpr uint32_t registerWordSize = NATIVEINT; }; // namespace BFVRNS_SCHEME_DEFAULTS @@ -155,7 +155,7 @@ constexpr uint32_t statisticalSecurity = 30; constexpr uint32_t numAdversarialQueries = 1; constexpr uint32_t thresholdNumOfParties = 1; constexpr COMPRESSION_LEVEL interactiveBootCompressionLevel = SLACK; -constexpr uint32_t compositeDegree = BASE_NUM_LEVELS_TO_DROP; +constexpr uint32_t compositeDegree = 1; constexpr uint32_t registerWordSize = NATIVEINT; }; // namespace BGVRNS_SCHEME_DEFAULTS diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp index d54060c39..21beb385f 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp @@ -163,24 +163,23 @@ void CryptoParametersCKKSRNS::ConfigureCompositeDegree(uint32_t scalingModSize) // Add logic to determine whether composite scaling is feasible or not if (GetScalingTechnique() == COMPOSITESCALINGAUTO) { if (NATIVEINT != 64) - OPENFHE_THROW(config_error, "COMPOSITESCALINGAUTO scaling technique only supported with NATIVEINT==64."); - uint32_t compositeDegree = GetCompositeDegree(); + OPENFHE_THROW("COMPOSITESCALINGAUTO scaling technique only supported with NATIVEINT==64."); uint32_t registerWordSize = GetRegisterWordSize(); if (registerWordSize <= 64) { if (registerWordSize < scalingModSize) { - compositeDegree = static_cast(std::ceil(static_cast(scalingModSize) / registerWordSize)); + uint32_t compositeDegree = + static_cast(std::ceil(static_cast(scalingModSize) / registerWordSize)); // Assert minimum allowed moduli size on composite scaling mode // @fdiasmor TODO: make it more robust for a range of multiplicative depth if (static_cast(scalingModSize) / compositeDegree < 21) { OPENFHE_THROW( - config_error, "Moduli size is too short (< 21) for target multiplicative depth. Consider increasing the scaling factor or the register word size."); } m_compositeDegree = compositeDegree; } // else composite degree remains set to 1 } else { - OPENFHE_THROW(config_error, "COMPOSITESCALING scaling technique only supports register word size <= 64."); + OPENFHE_THROW("COMPOSITESCALING scaling technique only supports register word size <= 64."); } } } diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp index 198568f3f..91a7219f5 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-leveledshe.cpp @@ -191,7 +191,7 @@ std::vector LeveledSHECKKSRNS::GetElementForEvalAddOrSub(Cons } DCRTPoly::Integer intPowP; - int64_t powp64 = (static_cast(1)) << precision; + uint64_t powp64 = (static_cast(1)) << precision; if (pCurrent < 0) { intPowP = NativeInteger((uint128_t)powp64 >> (-pCurrent)); } diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp index 95186e109..c45de167d 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp @@ -68,12 +68,6 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptrConfigureCompositeDegree(firstModSize); - uint32_t compositeDegree = cryptoParamsCKKSRNS->GetCompositeDegree(); - uint32_t registerWordSize = cryptoParamsCKKSRNS->GetRegisterWordSize(); - compositeDegree *= static_cast(1); // @fdiasmor: Avoid unused variable compilation error. - registerWordSize *= static_cast(1); // @fdiasmor: Avoid unused variable compilation error. - // Bookeeping unique prime moduli - // std::unordered_set moduliQRecord; if ((PREMode != INDCPA) && (PREMode != NOT_SET)) { std::stringstream s; @@ -100,7 +94,7 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptrGetCompositeDegree() == 2) ? 2 : 4; qBound += ceil(ceil(static_cast(qBound) / numPartQ) / (tmpFactor * auxBits)) * tmpFactor * auxBits; } else { From 4b721d90cdadad224e8f2d344a3b3ebd58da73be Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 24 Dec 2024 17:58:46 -0800 Subject: [PATCH 17/21] Update composite scaling unittests and fix unittest runtime issue. --- .../include/scheme/gen-cryptocontext-params.h | 2 +- .../utbgvrns/UnitTestBGVrnsAutomorphism.csv | 142 +++++++++--------- .../UnitTestInteractiveBootstrap.csv | 36 ++--- src/pke/unittest/utils/UnitTestUtils.h | 1 + 4 files changed, 91 insertions(+), 90 deletions(-) diff --git a/src/pke/include/scheme/gen-cryptocontext-params.h b/src/pke/include/scheme/gen-cryptocontext-params.h index e9bd084fc..1e8b25221 100644 --- a/src/pke/include/scheme/gen-cryptocontext-params.h +++ b/src/pke/include/scheme/gen-cryptocontext-params.h @@ -252,7 +252,7 @@ class Params { "statisticalSecurity", "numAdversarialQueries", "thresholdNumOfParties", - "interactiveBootCompressionLevel" + "interactiveBootCompressionLevel", "compositeDegree", "registerWordSize"}; } diff --git a/src/pke/unittest/utbgvrns/UnitTestBGVrnsAutomorphism.csv b/src/pke/unittest/utbgvrns/UnitTestBGVrnsAutomorphism.csv index 4c9fe0241..f8b7edde1 100644 --- a/src/pke/unittest/utbgvrns/UnitTestBGVrnsAutomorphism.csv +++ b/src/pke/unittest/utbgvrns/UnitTestBGVrnsAutomorphism.csv @@ -1,71 +1,71 @@ -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,Error,indexList -BGVRNS_AUTOMORPHISM,1,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,2,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,3,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,4,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,5,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,6,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,7,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,8,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,9,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,10,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,11,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,12,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,13,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,14,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,15,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,16,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,17,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,18,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,19,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,20,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,21,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,22,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,23,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 -BGVRNS_AUTOMORPHISM,24,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,Error,indexList -EVAL_AT_INDX_PACKED_ARRAY,31,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,32,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 -EVAL_AT_INDX_PACKED_ARRAY,33,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,34,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,35,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,36,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,37,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,38,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 -EVAL_AT_INDX_PACKED_ARRAY,39,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,40,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,41,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,42,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,43,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,44,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 -EVAL_AT_INDX_PACKED_ARRAY,45,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,46,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,47,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,48,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,49,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,50,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 -EVAL_AT_INDX_PACKED_ARRAY,51,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,52,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,53,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 -EVAL_AT_INDX_PACKED_ARRAY,54,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,Error,indexList -EVAL_SUM_PACKED_ARRAY,61,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, -EVAL_SUM_PACKED_ARRAY,62,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, -EVAL_SUM_PACKED_ARRAY,63,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, -EVAL_SUM_PACKED_ARRAY,64,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, -EVAL_SUM_PACKED_ARRAY,65,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, -EVAL_SUM_PACKED_ARRAY,66,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, -EVAL_SUM_PACKED_ARRAY,67,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, -EVAL_SUM_PACKED_ARRAY,68,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, -EVAL_SUM_PACKED_ARRAY,69,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, -EVAL_SUM_PACKED_ARRAY,70,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, -EVAL_SUM_PACKED_ARRAY,71,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, -EVAL_SUM_PACKED_ARRAY,72,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, -EVAL_SUM_PACKED_ARRAY,73,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, -EVAL_SUM_PACKED_ARRAY,74,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, -EVAL_SUM_PACKED_ARRAY,75,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, -EVAL_SUM_PACKED_ARRAY,76,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, -EVAL_SUM_PACKED_ARRAY,77,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, -EVAL_SUM_PACKED_ARRAY,78,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, -EVAL_SUM_PACKED_ARRAY,79,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, -EVAL_SUM_PACKED_ARRAY,80,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,compositeDegree,registerWordSize,Error,indexList +BGVRNS_AUTOMORPHISM,1,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,2,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,3,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,4,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,5,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,6,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,7,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,8,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,9,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,10,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,11,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,12,BGVRNS_SCHEME,17,1,,,,BV,FIXEDAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,13,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,14,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,15,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,16,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,17,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,18,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTO,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,19,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,20,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,21,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,22,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,23,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 +BGVRNS_AUTOMORPHISM,24,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,compositeDegree,registerWordSize,Error,indexList +EVAL_AT_INDX_PACKED_ARRAY,31,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,32,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 +EVAL_AT_INDX_PACKED_ARRAY,33,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,34,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,35,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,36,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,37,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,38,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 +EVAL_AT_INDX_PACKED_ARRAY,39,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,40,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,41,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,42,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,43,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,44,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 +EVAL_AT_INDX_PACKED_ARRAY,45,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,46,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,47,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,48,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,49,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,50,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 +EVAL_AT_INDX_PACKED_ARRAY,51,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,52,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,53,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 +EVAL_AT_INDX_PACKED_ARRAY,54,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,compositeDegree,registerWordSize,Error,indexList +EVAL_SUM_PACKED_ARRAY,61,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, +EVAL_SUM_PACKED_ARRAY,62,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, +EVAL_SUM_PACKED_ARRAY,63,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, +EVAL_SUM_PACKED_ARRAY,64,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, +EVAL_SUM_PACKED_ARRAY,65,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, +EVAL_SUM_PACKED_ARRAY,66,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, +EVAL_SUM_PACKED_ARRAY,67,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, +EVAL_SUM_PACKED_ARRAY,68,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, +EVAL_SUM_PACKED_ARRAY,69,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, +EVAL_SUM_PACKED_ARRAY,70,BGVRNS_SCHEME,65537,,,,,,FIXEDAUTO,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, +EVAL_SUM_PACKED_ARRAY,71,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, +EVAL_SUM_PACKED_ARRAY,72,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, +EVAL_SUM_PACKED_ARRAY,73,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, +EVAL_SUM_PACKED_ARRAY,74,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, +EVAL_SUM_PACKED_ARRAY,75,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTO,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, +EVAL_SUM_PACKED_ARRAY,76,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, +EVAL_SUM_PACKED_ARRAY,77,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, +EVAL_SUM_PACKED_ARRAY,78,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, +EVAL_SUM_PACKED_ARRAY,79,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,INVALID_BATCH_SIZE, +EVAL_SUM_PACKED_ARRAY,80,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL, diff --git a/src/pke/unittest/utckksrns/UnitTestInteractiveBootstrap.csv b/src/pke/unittest/utckksrns/UnitTestInteractiveBootstrap.csv index 4c1e56efb..2ef3bc4d5 100644 --- a/src/pke/unittest/utckksrns/UnitTestInteractiveBootstrap.csv +++ b/src/pke/unittest/utckksrns/UnitTestInteractiveBootstrap.csv @@ -1,18 +1,18 @@ -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,numParties -INTERACTIVE_MP_BOOT,1,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,3 -INTERACTIVE_MP_BOOT,2,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,3 -INTERACTIVE_MP_BOOT,3,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,3 -INTERACTIVE_MP_BOOT,4,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,3 -INTERACTIVE_MP_BOOT,5,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,3 -INTERACTIVE_MP_BOOT,6,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,3 -INTERACTIVE_MP_BOOT,7,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,3 -INTERACTIVE_MP_BOOT,8,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,3 -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,numParties -INTERACTIVE_MP_BOOT_CHEBYSHEV,1,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK, -INTERACTIVE_MP_BOOT_CHEBYSHEV,2,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK, -INTERACTIVE_MP_BOOT_CHEBYSHEV,3,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK, -INTERACTIVE_MP_BOOT_CHEBYSHEV,4,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK, -INTERACTIVE_MP_BOOT_CHEBYSHEV,5,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT, -INTERACTIVE_MP_BOOT_CHEBYSHEV,6,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT, -INTERACTIVE_MP_BOOT_CHEBYSHEV,7,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT, -INTERACTIVE_MP_BOOT_CHEBYSHEV,8,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT, +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,compositeDegree,registerWordSize,numParties +INTERACTIVE_MP_BOOT,1,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,,3 +INTERACTIVE_MP_BOOT,2,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,,3 +INTERACTIVE_MP_BOOT,3,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,,3 +INTERACTIVE_MP_BOOT,4,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,,3 +INTERACTIVE_MP_BOOT,5,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,,3 +INTERACTIVE_MP_BOOT,6,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,,3 +INTERACTIVE_MP_BOOT,7,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,,3 +INTERACTIVE_MP_BOOT,8,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,,3 +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,compositeDegree,registerWordSize,numParties +INTERACTIVE_MP_BOOT_CHEBYSHEV,1,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,2,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,3,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,4,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,5,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,6,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,7,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,, +INTERACTIVE_MP_BOOT_CHEBYSHEV,8,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,,, diff --git a/src/pke/unittest/utils/UnitTestUtils.h b/src/pke/unittest/utils/UnitTestUtils.h index b6bdefe8d..c90337e55 100644 --- a/src/pke/unittest/utils/UnitTestUtils.h +++ b/src/pke/unittest/utils/UnitTestUtils.h @@ -43,6 +43,7 @@ #include #include #include +#include // some functions are inlined in this files to avoid link errors //=========================================================================================================== From cf685de3e26b6fb7fbd531192f211dd98930fd70 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 9 Jan 2025 15:56:51 -0800 Subject: [PATCH 18/21] Disable composite scaling set methods for non-CKKS schemes. --- .../include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h | 6 ++++++ .../include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h b/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h index 91a116c76..5f2fac065 100644 --- a/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h +++ b/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h @@ -94,6 +94,12 @@ class CCParams : public Params { void SetInteractiveBootCompressionLevel(COMPRESSION_LEVEL interactiveBootCompressionLevel0) override { DISABLED_FOR_BFVRNS; } + void SetCompositeDegree(uint32_t compositeDegree0) override { + DISABLED_FOR_BFVRNS; + } + void SetRegisterWordSize(uint32_t registerWordSize0) override { + DISABLED_FOR_BFVRNS; + } }; //==================================================================================================================== diff --git a/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h b/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h index cda5c6043..a42ab54f3 100644 --- a/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h +++ b/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h @@ -84,6 +84,12 @@ class CCParams : public Params { void SetInteractiveBootCompressionLevel(COMPRESSION_LEVEL interactiveBootCompressionLevel0) override { DISABLED_FOR_BGVRNS; } + void SetCompositeDegree(uint32_t compositeDegree0) override { + DISABLED_FOR_BGVRNS; + } + void SetRegisterWordSize(uint32_t registerWordSize0) override { + DISABLED_FOR_BGVRNS; + } }; //==================================================================================================================== From a5a443a262f725035c63b14632d85e59239f275e Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 9 Jan 2025 16:13:48 -0800 Subject: [PATCH 19/21] Move COMPOSITESCALING support error handling. --- .../scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h | 7 +++++-- src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp | 6 ++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h b/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h index 85b1887b7..33f9b833d 100644 --- a/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h +++ b/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h @@ -54,8 +54,11 @@ template typename ContextGeneratorType::ContextType genCryptoContextCKKSRNSInternal( const CCParams& parameters) { #if NATIVEINT == 128 && !defined(__EMSCRIPTEN__) - if (parameters.GetScalingTechnique() == FLEXIBLEAUTO || parameters.GetScalingTechnique() == FLEXIBLEAUTOEXT) { - OPENFHE_THROW("128-bit CKKS is not supported for the FLEXIBLEAUTO or FLEXIBLEAUTOEXT methods."); + if (parameters.GetScalingTechnique() == FLEXIBLEAUTO || parameters.GetScalingTechnique() == FLEXIBLEAUTOEXT || + parameters.GetScalingTechnique() == COMPOSITESCALINGAUTO || + parameters.GetScalingTechnique() == COMPOSITESCALINGMANUAL) { + OPENFHE_THROW( + "128-bit CKKS is not supported for the FLEXIBLEAUTO, FLEXIBLEAUTOEXT, COMPOSITESCALINGAUTO or COMPOSITESCALINGMANUAL methods."); } #endif using ParmType = typename Element::Params; diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp index 21beb385f..5849af17c 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-cryptoparameters.cpp @@ -162,8 +162,6 @@ uint64_t CryptoParametersCKKSRNS::FindAuxPrimeStep() const { void CryptoParametersCKKSRNS::ConfigureCompositeDegree(uint32_t scalingModSize) { // Add logic to determine whether composite scaling is feasible or not if (GetScalingTechnique() == COMPOSITESCALINGAUTO) { - if (NATIVEINT != 64) - OPENFHE_THROW("COMPOSITESCALINGAUTO scaling technique only supported with NATIVEINT==64."); uint32_t registerWordSize = GetRegisterWordSize(); if (registerWordSize <= 64) { if (registerWordSize < scalingModSize) { @@ -171,9 +169,9 @@ void CryptoParametersCKKSRNS::ConfigureCompositeDegree(uint32_t scalingModSize) static_cast(std::ceil(static_cast(scalingModSize) / registerWordSize)); // Assert minimum allowed moduli size on composite scaling mode // @fdiasmor TODO: make it more robust for a range of multiplicative depth - if (static_cast(scalingModSize) / compositeDegree < 21) { + if (static_cast(scalingModSize) / compositeDegree < 22) { OPENFHE_THROW( - "Moduli size is too short (< 21) for target multiplicative depth. Consider increasing the scaling factor or the register word size."); + "Moduli size is too short (< 22) for target multiplicative depth. Consider increasing the scaling factor or the register word size."); } m_compositeDegree = compositeDegree; } // else composite degree remains set to 1 From b14472d5926ccddc6ab7ed48bc3ad5160760a2bf Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 9 Jan 2025 15:56:51 -0800 Subject: [PATCH 20/21] Disable composite scaling set methods for non-CKKS schemes. --- .../include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h | 6 ++++++ .../include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h b/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h index 91a116c76..5f2fac065 100644 --- a/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h +++ b/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h @@ -94,6 +94,12 @@ class CCParams : public Params { void SetInteractiveBootCompressionLevel(COMPRESSION_LEVEL interactiveBootCompressionLevel0) override { DISABLED_FOR_BFVRNS; } + void SetCompositeDegree(uint32_t compositeDegree0) override { + DISABLED_FOR_BFVRNS; + } + void SetRegisterWordSize(uint32_t registerWordSize0) override { + DISABLED_FOR_BFVRNS; + } }; //==================================================================================================================== diff --git a/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h b/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h index cda5c6043..a42ab54f3 100644 --- a/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h +++ b/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h @@ -84,6 +84,12 @@ class CCParams : public Params { void SetInteractiveBootCompressionLevel(COMPRESSION_LEVEL interactiveBootCompressionLevel0) override { DISABLED_FOR_BGVRNS; } + void SetCompositeDegree(uint32_t compositeDegree0) override { + DISABLED_FOR_BGVRNS; + } + void SetRegisterWordSize(uint32_t registerWordSize0) override { + DISABLED_FOR_BGVRNS; + } }; //==================================================================================================================== From 6dd35c035f377c91f8be03aaf2237468b6f98346 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 9 Jan 2025 18:08:47 -0800 Subject: [PATCH 21/21] Removing additional constructor that accepts composite scaling parameters. --- .../scheme/ckksrns/ckksrns-cryptoparameters.h | 26 ++-------- .../gen-cryptocontext-ckksrns-internal.h | 6 +-- .../include/schemerns/rns-cryptoparameters.h | 50 +++++-------------- 3 files changed, 19 insertions(+), 63 deletions(-) diff --git a/src/pke/include/scheme/ckksrns/ckksrns-cryptoparameters.h b/src/pke/include/scheme/ckksrns/ckksrns-cryptoparameters.h index bf649e863..a7ac18cc2 100644 --- a/src/pke/include/scheme/ckksrns/ckksrns-cryptoparameters.h +++ b/src/pke/include/scheme/ckksrns/ckksrns-cryptoparameters.h @@ -77,31 +77,13 @@ class CryptoParametersCKKSRNS : public CryptoParametersRNS { DecryptionNoiseMode decryptionNoiseMode = FIXED_NOISE_DECRYPT, PlaintextModulus noiseScale = 1, uint32_t statisticalSecurity = 30, uint32_t numAdversarialQueries = 1, uint32_t thresholdNumOfParties = 1, - COMPRESSION_LEVEL mPIntBootCiphertextCompressionLevel = COMPRESSION_LEVEL::SLACK) + COMPRESSION_LEVEL mPIntBootCiphertextCompressionLevel = COMPRESSION_LEVEL::SLACK, + usint compositeDegree = BASE_NUM_LEVELS_TO_DROP, usint registerWordSize = NATIVEINT) : CryptoParametersRNS(params, encodingParams, distributionParameter, assuranceMeasure, securityLevel, digitSize, secretKeyDist, maxRelinSkDeg, ksTech, scalTech, encTech, multTech, PREMode, multipartyMode, executionMode, decryptionNoiseMode, noiseScale, statisticalSecurity, - numAdversarialQueries, thresholdNumOfParties, mPIntBootCiphertextCompressionLevel) {} - - // This constructor is ideal when register word size varies and composite degree is set manually - CryptoParametersCKKSRNS(std::shared_ptr params, EncodingParams encodingParams, - float distributionParameter, float assuranceMeasure, SecurityLevel securityLevel, - usint digitSize, SecretKeyDist secretKeyDist, int maxRelinSkDeg = 2, - KeySwitchTechnique ksTech = BV, ScalingTechnique scalTech = FIXEDMANUAL, - usint compositeDegree = BASE_NUM_LEVELS_TO_DROP, usint registerWordSize = NATIVEINT, - EncryptionTechnique encTech = STANDARD, MultiplicationTechnique multTech = HPS, - ProxyReEncryptionMode PREMode = NOT_SET, - MultipartyMode multipartyMode = FIXED_NOISE_MULTIPARTY, - ExecutionMode executionMode = EXEC_EVALUATION, - DecryptionNoiseMode decryptionNoiseMode = FIXED_NOISE_DECRYPT, - PlaintextModulus noiseScale = 1, uint32_t statisticalSecurity = 30, - uint32_t numAdversarialQueries = 1, uint32_t thresholdNumOfParties = 1, - COMPRESSION_LEVEL mPIntBootCiphertextCompressionLevel = COMPRESSION_LEVEL::SLACK) - : CryptoParametersRNS(params, encodingParams, distributionParameter, assuranceMeasure, securityLevel, digitSize, - secretKeyDist, maxRelinSkDeg, ksTech, scalTech, compositeDegree, registerWordSize, - encTech, multTech, PREMode, multipartyMode, executionMode, decryptionNoiseMode, - noiseScale, statisticalSecurity, numAdversarialQueries, thresholdNumOfParties, - mPIntBootCiphertextCompressionLevel) {} + numAdversarialQueries, thresholdNumOfParties, mPIntBootCiphertextCompressionLevel, + compositeDegree, registerWordSize) {} virtual ~CryptoParametersCKKSRNS() {} diff --git a/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h b/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h index 33f9b833d..ddfbe116e 100644 --- a/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h +++ b/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-internal.h @@ -105,8 +105,6 @@ typename ContextGeneratorType::ContextType genCryptoContextCKKSRNSInternal( parameters.GetMaxRelinSkDeg(), parameters.GetKeySwitchTechnique(), parameters.GetScalingTechnique(), - parameters.GetCompositeDegree(), - parameters.GetRegisterWordSize(), parameters.GetEncryptionTechnique(), parameters.GetMultiplicationTechnique(), parameters.GetPREMode(), @@ -117,7 +115,9 @@ typename ContextGeneratorType::ContextType genCryptoContextCKKSRNSInternal( parameters.GetStatisticalSecurity(), parameters.GetNumAdversarialQueries(), parameters.GetThresholdNumOfParties(), - parameters.GetInteractiveBootCompressionLevel()); + parameters.GetInteractiveBootCompressionLevel(), + parameters.GetCompositeDegree(), + parameters.GetRegisterWordSize()); // for CKKS scheme noise scale is always set to 1 params->SetNoiseScale(1); diff --git a/src/pke/include/schemerns/rns-cryptoparameters.h b/src/pke/include/schemerns/rns-cryptoparameters.h index b0d0b31da..cbcbda348 100644 --- a/src/pke/include/schemerns/rns-cryptoparameters.h +++ b/src/pke/include/schemerns/rns-cryptoparameters.h @@ -116,8 +116,6 @@ class CryptoParametersRNS : public CryptoParametersRLWE { m_encTechnique = encTech; m_multTechnique = multTech; m_MPIntBootCiphertextCompressionLevel = mPIntBootCiphertextCompressionLevel; - m_compositeDegree = BASE_NUM_LEVELS_TO_DROP; - m_registerWordSize = NATIVEINT; } CryptoParametersRNS(std::shared_ptr params, EncodingParams encodingParams, float distributionParameter, @@ -130,7 +128,8 @@ class CryptoParametersRNS : public CryptoParametersRLWE { DecryptionNoiseMode decryptionNoiseMode = FIXED_NOISE_DECRYPT, PlaintextModulus noiseScale = 1, uint32_t statisticalSecurity = 30, uint32_t numAdversarialQueries = 1, uint32_t thresholdNumOfParties = 1, - COMPRESSION_LEVEL mPIntBootCiphertextCompressionLevel = COMPRESSION_LEVEL::SLACK) + COMPRESSION_LEVEL mPIntBootCiphertextCompressionLevel = COMPRESSION_LEVEL::SLACK, + usint compositeDegree = BASE_NUM_LEVELS_TO_DROP, usint registerWordSize = NATIVEINT) : CryptoParametersRLWE(std::move(params), std::move(encodingParams), distributionParameter, assuranceMeasure, securityLevel, digitSize, maxRelinSkDeg, secretKeyDist, PREMode, multipartyMode, executionMode, decryptionNoiseMode, noiseScale, @@ -140,32 +139,7 @@ class CryptoParametersRNS : public CryptoParametersRLWE { m_encTechnique = encTech; m_multTechnique = multTech; m_MPIntBootCiphertextCompressionLevel = mPIntBootCiphertextCompressionLevel; - m_compositeDegree = BASE_NUM_LEVELS_TO_DROP; - m_registerWordSize = NATIVEINT; - } - - CryptoParametersRNS(std::shared_ptr params, EncodingParams encodingParams, float distributionParameter, - float assuranceMeasure, SecurityLevel securityLevel, usint digitSize, - SecretKeyDist secretKeyDist, int maxRelinSkDeg = 2, KeySwitchTechnique ksTech = BV, - ScalingTechnique scalTech = FIXEDMANUAL, usint compositeDegree = BASE_NUM_LEVELS_TO_DROP, - usint registerWordSize = NATIVEINT, EncryptionTechnique encTech = STANDARD, - MultiplicationTechnique multTech = HPS, ProxyReEncryptionMode PREMode = INDCPA, - MultipartyMode multipartyMode = FIXED_NOISE_MULTIPARTY, - ExecutionMode executionMode = EXEC_EVALUATION, - DecryptionNoiseMode decryptionNoiseMode = FIXED_NOISE_DECRYPT, PlaintextModulus noiseScale = 1, - uint32_t statisticalSecurity = 30, uint32_t numAdversarialQueries = 1, - uint32_t thresholdNumOfParties = 1, - COMPRESSION_LEVEL mPIntBootCiphertextCompressionLevel = COMPRESSION_LEVEL::SLACK) - : CryptoParametersRLWE(std::move(params), std::move(encodingParams), distributionParameter, - assuranceMeasure, securityLevel, digitSize, maxRelinSkDeg, secretKeyDist, - PREMode, multipartyMode, executionMode, decryptionNoiseMode, noiseScale, - statisticalSecurity, numAdversarialQueries, thresholdNumOfParties) { - m_ksTechnique = ksTech; - m_scalTechnique = scalTech; - m_encTechnique = encTech; - m_multTechnique = multTech; - m_MPIntBootCiphertextCompressionLevel = mPIntBootCiphertextCompressionLevel; - m_compositeDegree = compositeDegree; + m_compositeDegree = compositeDegree; m_registerWordSize = registerWordSize; } @@ -638,7 +612,7 @@ class CryptoParametersRNS : public CryptoParametersRLWE { * @return the scaling factor. */ double GetScalingFactorReal(uint32_t l = 0) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { if (l >= m_scalingFactorsReal.size()) { // TODO: Return an error here. @@ -652,7 +626,7 @@ class CryptoParametersRNS : public CryptoParametersRLWE { } double GetScalingFactorRealBig(uint32_t l = 0) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { if (l >= m_scalingFactorsRealBig.size()) { // TODO: Return an error here. @@ -665,15 +639,15 @@ class CryptoParametersRNS : public CryptoParametersRLWE { return m_approxSF; } - /** + /** * Method to retrieve the modulus to be dropped of level l. * For FIXEDMANUAL rescaling technique method always returns 2^p, where p corresponds to plaintext modulus * @param l index of modulus to be dropped for FLEXIBLEAUTO scaling technique * @return the precomputed table */ double GetModReduceFactor(uint32_t l = 0) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || - m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { return m_dmoduliQ[l]; } @@ -697,9 +671,9 @@ class CryptoParametersRNS : public CryptoParametersRLWE { } /** * Returns the architecture register word size (e.g., 32 bits, 48 bits, 64 bits). - * Used to determine the size of prime moduli in the CKKS scheme on + * Used to determine the size of prime moduli in the CKKS scheme on * composite scaling mode (COMPOSITESCALINGAUTO). - * + * * @return the register word size for COMPOSITESCALING scaling technique **/ uint32_t const& GetRegisterWordSize() const { @@ -1021,7 +995,7 @@ class CryptoParametersRNS : public CryptoParametersRLWE { } const NativeInteger& GetModReduceFactorInt(uint32_t l = 0) const { - if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || + if (m_scalTechnique == FLEXIBLEAUTO || m_scalTechnique == FLEXIBLEAUTOEXT || m_scalTechnique == COMPOSITESCALINGAUTO || m_scalTechnique == COMPOSITESCALINGMANUAL) { return m_qModt[l]; } @@ -1549,7 +1523,7 @@ class CryptoParametersRNS : public CryptoParametersRLWE { ///////////////////////////////////// // Stores composite degree for composite modulus chain - uint32_t m_compositeDegree = BASE_NUM_LEVELS_TO_DROP; + uint32_t m_compositeDegree = BASE_NUM_LEVELS_TO_DROP; // Stores the architecture register word size uint32_t m_registerWordSize = NATIVEINT;