Program Listing for File rgsw-cryptoparameters.cpp
↰ Return to documentation for file (binfhe/lib/rgsw-cryptoparameters.cpp)
//==================================================================================
// 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.
//==================================================================================
#include "rgsw-cryptoparameters.h"
namespace lbcrypto {
void RingGSWCryptoParams::PreCompute(bool signEval) {
// Computes baseR^i (only for AP bootstrapping)
if (m_method == BINFHE_METHOD::AP) {
auto&& logq = std::log(m_q.ConvertToDouble());
auto digitCountR{static_cast<size_t>(std::ceil(logq / std::log(static_cast<double>(m_baseR))))};
m_digitsR.clear();
m_digitsR.reserve(digitCountR);
BasicInteger value{1};
for (size_t i = 0; i < digitCountR; ++i, value *= m_baseR)
m_digitsR.emplace_back(value);
}
// Computes baseG^i
if (signEval) {
constexpr uint32_t baseGlist[] = {1 << 14, 1 << 18, 1 << 27};
// {log(1 << 14), log(1 << 18), log(1 << 27)}
constexpr double logbaseGlist[] = {0x1.3687a9f1af2b1p+3, 0x1.8f40b5ed9812dp+3, 0x1.2b708872320e2p+4};
constexpr NativeInteger nativebaseGlist[] = {1 << 14, 1 << 18, 1 << 27};
auto logQ{std::log(m_Q.ConvertToDouble())};
for (size_t j = 0; j < 3; ++j) {
NativeInteger vTemp{1};
auto tempdigits{static_cast<size_t>(std::ceil(logQ / logbaseGlist[j]))};
std::vector<NativeInteger> tempvec(tempdigits);
for (size_t i = 0; i < tempdigits; ++i) {
tempvec[i] = vTemp;
vTemp = vTemp.ModMulFast(nativebaseGlist[j], m_Q);
}
if (m_baseG == baseGlist[j])
m_Gpower = tempvec;
m_Gpower_map[baseGlist[j]] = std::move(tempvec);
}
}
else {
m_Gpower.reserve(m_digitsG);
NativeInteger vTemp{1};
for (uint32_t i = 0; i < m_digitsG; ++i) {
m_Gpower.push_back(vTemp);
vTemp = vTemp.ModMulFast(NativeInteger(m_baseG), m_Q);
}
}
// Sets the gate constants for supported binary operations
m_gateConst = {
NativeInteger(5) * (m_q >> 3), // OR
NativeInteger(7) * (m_q >> 3), // AND
NativeInteger(1) * (m_q >> 3), // NOR
NativeInteger(3) * (m_q >> 3), // NAND
NativeInteger(6) * (m_q >> 3), // XOR
NativeInteger(2) * (m_q >> 3), // XNOR
NativeInteger(7) * (m_q >> 3), // MAJORITY
NativeInteger(11) * (m_q / 12), // AND3
NativeInteger(7) * (m_q / 12), // OR3
NativeInteger(15) * (m_q >> 4), // AND4
NativeInteger(9) * (m_q >> 4), // OR4
NativeInteger(6) * (m_q >> 3), // XOR_FAST
NativeInteger(2) * (m_q >> 3) // XNOR_FAST
};
// Computes polynomials X^m - 1 that are needed in the accumulator for the
// CGGI bootstrapping
if (m_method == BINFHE_METHOD::GINX) {
constexpr NativeInteger one{1};
m_monomials.reserve(2 * m_N);
for (uint32_t i = 0; i < m_N; ++i) {
NativePoly aPoly(m_polyParams, Format::COEFFICIENT, true);
aPoly[0].ModSubFastEq(one, m_Q); // -1
aPoly[i].ModAddFastEq(one, m_Q); // X^m
aPoly.SetFormat(Format::EVALUATION);
m_monomials.push_back(std::move(aPoly));
}
for (uint32_t i = 0; i < m_N; ++i) {
NativePoly aPoly(m_polyParams, Format::COEFFICIENT, true);
aPoly[0].ModSubFastEq(one, m_Q); // -1
aPoly[i].ModSubFastEq(one, m_Q); // -X^m
aPoly.SetFormat(Format::EVALUATION);
m_monomials.push_back(std::move(aPoly));
}
}
if (m_method == LMKCDEY) {
constexpr uint32_t gen{5};
m_logGen.clear();
uint32_t M{2 * m_N};
m_logGen.resize(M);
uint32_t gPow{1};
m_logGen[M - gPow] = M; // for -1
for (uint32_t i = 1; i < m_N / 2; ++i) {
gPow = (gPow * gen) % M;
m_logGen[gPow] = i;
m_logGen[M - gPow] = -i;
}
}
}
}; // namespace lbcrypto