From 705bc251c76ef4457496dfa69dd41be9980d4558 Mon Sep 17 00:00:00 2001 From: Dmitriy Suponitskiy Date: Tue, 11 Jun 2024 13:12:09 -0400 Subject: [PATCH] Addressed review comments --- .../include/schemerns/rns-cryptoparameters.h | 4 +- .../bfvrns/bfvrns-parametergeneration.cpp | 6 +- .../bgvrns/bgvrns-parametergeneration.cpp | 9 +-- .../lib/schemerns/rns-cryptoparameters.cpp | 73 +++++++++---------- 4 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/pke/include/schemerns/rns-cryptoparameters.h b/src/pke/include/schemerns/rns-cryptoparameters.h index 9e67d0ff8..2c2692c76 100644 --- a/src/pke/include/schemerns/rns-cryptoparameters.h +++ b/src/pke/include/schemerns/rns-cryptoparameters.h @@ -177,8 +177,8 @@ class CryptoParametersRNS : public CryptoParametersRLWE { * * @return number of extra bits needed for noise flooding */ - static double EstimateMultipartyFloodingLogQ() { - return NoiseFlooding::MULTIPARTY_MOD_SIZE * NoiseFlooding::NUM_MODULI_MULTIPARTY; + static constexpr double EstimateMultipartyFloodingLogQ() { + return static_cast(NoiseFlooding::MULTIPARTY_MOD_SIZE * NoiseFlooding::NUM_MODULI_MULTIPARTY); } /** diff --git a/src/pke/lib/scheme/bfvrns/bfvrns-parametergeneration.cpp b/src/pke/lib/scheme/bfvrns/bfvrns-parametergeneration.cpp index 9ed0412c6..b79af6d11 100644 --- a/src/pke/lib/scheme/bfvrns/bfvrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/bfvrns/bfvrns-parametergeneration.cpp @@ -117,7 +117,7 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptrEstimateMultipartyFloodingLogQ(); // adds logP in the case of HYBRID key switching if (ksTech == HYBRID) { @@ -129,7 +129,7 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr(hybridKSInfo); } return static_cast( - StdLatticeParm::FindRingDim(distType, stdLevel, static_cast(std::ceil(logq)))); + StdLatticeParm::FindRingDim(distType, stdLevel, static_cast(std::ceil(logq)))); } }; @@ -138,7 +138,7 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr(logqPrev) / dcrtBits); + double numTowers = ceil(logqPrev / dcrtBits); return numTowers * (delta(n) * Berr + delta(n) * Bkey + 1.0) / 2.0; } else { diff --git a/src/pke/lib/scheme/bgvrns/bgvrns-parametergeneration.cpp b/src/pke/lib/scheme/bgvrns/bgvrns-parametergeneration.cpp index f49d87a63..909bef4d9 100644 --- a/src/pke/lib/scheme/bgvrns/bgvrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/bgvrns/bgvrns-parametergeneration.cpp @@ -475,9 +475,8 @@ bool ParameterGenerationBGVRNS::ParamsGenBGVRNS(std::shared_ptr(moduliInfo); uint32_t newQBound = std::get<1>(moduliInfo); - // the counter makes sure the first iteration of the while loop is always run - uint32_t counter = 0; - while ((counter == 0) || (qBound < newQBound)) { + // the loop must be executed at least once + do { qBound = newQBound; n = computeRingDimension(cryptoParams, newQBound, cyclOrder); auto moduliInfo = computeModuli(cryptoParams, n, evalAddCount, keySwitchCount, auxTowers, numPrimes); @@ -493,8 +492,8 @@ bool ParameterGenerationBGVRNS::ParamsGenBGVRNS(std::shared_ptr(hybridKSInfo); } - counter++; - } + } while (qBound < newQBound); + cyclOrder = 2 * n; modulusOrder = getCyclicOrder(n, ptm, scalTech); diff --git a/src/pke/lib/schemerns/rns-cryptoparameters.cpp b/src/pke/lib/schemerns/rns-cryptoparameters.cpp index f0e9e1f1c..4243da149 100644 --- a/src/pke/lib/schemerns/rns-cryptoparameters.cpp +++ b/src/pke/lib/schemerns/rns-cryptoparameters.cpp @@ -70,14 +70,16 @@ void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scaling DiscreteFourierTransform::Initialize(n * 2, n / 2); ChineseRemainderTransformFTT().PreCompute(rootsQ, 2 * n, moduliQ); if (m_ksTechnique == HYBRID) { - // Compute ceil(sizeQ/m_numPartQ), the # of towers per digit - uint32_t a = ceil(static_cast(sizeQ) / numPartQ); - if ((int32_t)(sizeQ - a * (numPartQ - 1)) <= 0) { - auto str = - "CryptoParametersRNS::PrecomputeCRTTables - HYBRID key " - "switching parameters: Can't appropriately distribute " + - std::to_string(sizeQ) + " towers into " + std::to_string(numPartQ) + - " digits. Please select different number of digits."; + // numPartQ can not be zero as there is a division by numPartQ + if (numPartQ == 0) + OPENFHE_THROW("numPartQ is zero"); + + // Compute ceil(sizeQ/numPartQ), the # of towers per digit + uint32_t a = static_cast(ceil(static_cast(sizeQ) / numPartQ)); + if (sizeQ <= (a * (numPartQ - 1))) { + auto str = "HYBRID key switching parameters: Can't appropriately distribute " + std::to_string(sizeQ) + + " towers into " + std::to_string(numPartQ) + + " digits. Please select different number of digits."; OPENFHE_THROW(str); } @@ -122,16 +124,15 @@ void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scaling std::make_shared>(params[0]->GetCyclotomicOrder(), moduli, roots); } - uint32_t sizeP; // Find number and size of individual special primes. uint32_t maxBits = moduliPartQ[0].GetLengthForBase(2); - for (usint j = 1; j < m_numPartQ; j++) { + for (uint32_t j = 1; j < m_numPartQ; j++) { uint32_t bits = moduliPartQ[j].GetLengthForBase(2); if (bits > maxBits) maxBits = bits; } // Select number of primes in auxiliary CRT basis - sizeP = ceil(static_cast(maxBits) / auxBits); + uint32_t sizeP = static_cast(ceil(static_cast(maxBits) / auxBits)); uint64_t primeStep = FindAuxPrimeStep(); // Choose special primes in auxiliary basis and compute their roots @@ -143,7 +144,7 @@ void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scaling NativeInteger firstP = FirstPrime(auxBits, primeStep); NativeInteger pPrev = firstP; BigInteger modulusP(1); - for (usint i = 0; i < sizeP; i++) { + for (uint32_t i = 0; i < sizeP; i++) { // The following loop makes sure that moduli in // P and Q are different bool foundInQ = false; @@ -234,11 +235,11 @@ void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scaling } // Pre-compute compementary partitions for ModUp - uint32_t alpha = ceil(static_cast(sizeQ) / m_numPartQ); + uint32_t alpha = static_cast(ceil(static_cast(sizeQ) / m_numPartQ)); m_paramsComplPartQ.resize(sizeQ); m_modComplPartqBarrettMu.resize(sizeQ); for (int32_t l = sizeQ - 1; l >= 0; l--) { - uint32_t beta = ceil(static_cast(l + 1) / alpha); + uint32_t beta = static_cast(ceil(static_cast(l + 1) / alpha)); m_paramsComplPartQ[l].resize(beta); m_modComplPartqBarrettMu[l].resize(beta); for (uint32_t j = 0; j < beta; j++) { @@ -305,8 +306,8 @@ void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scaling // Pre-compute QHat mod complementary partition qi's m_PartQlHatModp.resize(sizeQ); for (uint32_t l = 0; l < sizeQ; l++) { - uint32_t alpha = ceil(static_cast(sizeQ) / m_numPartQ); - uint32_t beta = ceil(static_cast(l + 1) / alpha); + uint32_t alpha = static_cast(ceil(static_cast(sizeQ) / m_numPartQ)); + uint32_t beta = static_cast(ceil(static_cast(l + 1) / alpha)); m_PartQlHatModp[l].resize(beta); for (uint32_t k = 0; k < beta; k++) { auto paramsPartQ = GetParamsPartQ(k)->GetParams(); @@ -391,46 +392,42 @@ uint64_t CryptoParametersRNS::FindAuxPrimeStep() const { std::pair CryptoParametersRNS::EstimateLogP(uint32_t numPartQ, double firstModulusSize, double dcrtBits, double extraModulusSize, uint32_t numPrimes, uint32_t auxBits) { - uint32_t sizeQ = numPrimes; + // numPartQ can not be zero as there is a division by numPartQ + if (numPartQ == 0) + OPENFHE_THROW("numPartQ is zero"); + + size_t sizeQ = numPrimes; if (extraModulusSize > 0) sizeQ++; // Compute ceil(sizeQ/numPartQ), the # of towers per digit - uint32_t numPerPartQ = ceil(static_cast(sizeQ) / numPartQ); - if ((uint32_t)(sizeQ - numPerPartQ * (numPartQ - 1)) <= 0) { - auto str = - "CryptoParametersRNS::EstimateLogP - HYBRID key " - "switching parameters: Can't appropriately distribute " + - std::to_string(sizeQ) + " towers into " + std::to_string(numPartQ) + - " digits. Please select different number of digits."; + size_t numPerPartQ = static_cast(ceil(static_cast(sizeQ) / numPartQ)); + if (sizeQ <= (numPerPartQ * (numPartQ - 1))) { + auto str = "HYBRID key switching parameters: Can't appropriately distribute " + std::to_string(sizeQ) + + " towers into " + std::to_string(numPartQ) + " digits. Please select different number of digits."; OPENFHE_THROW(str); } - // create a vector with bit sizes - std::vector qi(sizeQ); + // create a vector with the same value of bit sizes + std::vector qi(sizeQ, dcrtBits); qi[0] = firstModulusSize; - for (uint32_t i = 1; i < numPrimes; i++) { - qi[i] = dcrtBits; - } if (extraModulusSize > 0) qi[sizeQ - 1] = extraModulusSize; // Compute partitions of Q into numPartQ digits double maxBits = 0; - for (uint32_t j = 0; j < numPartQ; j++) { - auto startTower = j * numPerPartQ; - auto endTower = ((j + 1) * numPerPartQ - 1 < sizeQ) ? (j + 1) * numPerPartQ - 1 : sizeQ - 1; - double bits = 0.0; - for (uint32_t i = startTower; i <= endTower; i++) { - bits += qi[i]; - } + for (size_t j = 0; j < numPartQ; ++j) { + size_t startTower = j * numPerPartQ; + 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) + double bits = std::accumulate(qi.begin() + startTower, qi.begin() + (endTower + 1), 0.0); if (bits > maxBits) maxBits = bits; } // Select number of primes in auxiliary CRT basis - uint32_t sizeP; - sizeP = std::ceil(static_cast(maxBits) / auxBits); + auto sizeP = static_cast(std::ceil(maxBits / auxBits)); return std::make_pair(sizeP * auxBits, sizeP); }