Commit 8f956b4d authored by Yuriy Polyakov's avatar Yuriy Polyakov
Browse files

updated to v1.11.7

parent 08601274
......@@ -27,7 +27,7 @@ project (PALISADE C CXX)
set(PALISADE_VERSION_MAJOR 1)
set(PALISADE_VERSION_MINOR 11)
set(PALISADE_VERSION_PATCH 6)
set(PALISADE_VERSION_PATCH 7)
set(PALISADE_VERSION ${PALISADE_VERSION_MAJOR}.${PALISADE_VERSION_MINOR}.${PALISADE_VERSION_PATCH})
set(CMAKE_CXX_STANDARD 11)
......@@ -85,6 +85,7 @@ option( WITH_TCM "Activate tcmalloc by setting WITH_TCM to ON" OFF )
option( WITH_INTEL_HEXL "Use Intel HEXL library" OFF)
option( WITH_NATIVEOPT "Use machine-specific optimizations" OFF)
option( WITH_COVTEST "Turn on to enable coverage testing" OFF)
option( USE_MACPORTS "Use MacPorts installed packages" OFF)
# Set required number of bits for native integer in build by setting NATIVE_SIZE to 64 or 128
if( NOT NATIVE_SIZE )
......@@ -114,6 +115,7 @@ message( STATUS "NATIVE_SIZE: ${NATIVE_SIZE}")
message( STATUS "CKKS_M_FACTOR: ${CKKS_M_FACTOR}")
message( STATUS "WITH_NATIVEOPT: ${WITH_NATIVEOPT}")
message( STATUS "WITH_COVTEST: ${WITH_COVTEST}")
message( STATUS "USE_MACPORTS: ${USE_MACPORTS}")
#--------------------------------------------------------------------
# Compiler logic
......@@ -381,32 +383,47 @@ if (WITH_OPENMP)
# Used to optionally compile openmp code
add_definitions(-DPARALLEL)
find_package (OpenMP)
# Set OpenMP configuration manually for macOS
if (APPLE)
# Check for Apple M1 Processor
if (${ARCHITECTURE} MATCHES "arm64")
message( STATUS "Apple M1 detected")
set(OPENMP_LIBRARIES "/opt/homebrew/opt/libomp/lib")
set(OPENMP_INCLUDES "/opt/homebrew/opt/libomp/include")
else() # Apple Intel Processor
message( STATUS "Apple Intel detected")
set(OPENMP_LIBRARIES "/usr/local/opt/libomp/lib")
set(OPENMP_INCLUDES "/usr/local/opt/libomp/include")
endif()
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp -lomp -Wno-unused-command-line-argument")
set(OpenMP_C_LIB_NAMES "libomp")
set(OpenMP_libomp_LIBRARY ${OpenMP_C_LIB_NAMES})
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -lomp -Wno-unused-command-line-argument")
set(OpenMP_CXX_LIB_NAMES "libomp")
set(OpenMP_libomp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
endif()
if (USE_MACPORTS)
# Macports-based installation
message( STATUS "Using Macports setup")
set(OPENMP_LIBRARIES "/opt/local/lib/libomp")
set(OPENMP_INCLUDES "/opt/local/include/libomp")
if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "AppleClang")
set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp -lomp -Wno-unused-command-line-argument")
set(OpenMP_C_LIB_NAMES "omp")
set(OpenMP_omp_LIBRARY ${OpenMP_C_LIB_NAMES})
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -lomp -Wno-unused-command-line-argument")
set(OpenMP_CXX_LIB_NAMES "omp")
set(OpenMP_omp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
endif()
else (USE_MACPORTS)
# Homebrew-based installation
# Check for Apple M1 Processor
if (${ARCHITECTURE} MATCHES "arm64")
message( STATUS "Apple M1 detected")
set(OPENMP_LIBRARIES "/opt/homebrew/opt/libomp/lib")
set(OPENMP_INCLUDES "/opt/homebrew/opt/libomp/include")
else() # Apple Intel Processor
message( STATUS "Apple Intel detected")
set(OPENMP_LIBRARIES "/usr/local/opt/libomp/lib")
set(OPENMP_INCLUDES "/usr/local/opt/libomp/include")
endif()
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp -lomp -Wno-unused-command-line-argument")
set(OpenMP_C_LIB_NAMES "libomp")
set(OpenMP_libomp_LIBRARY ${OpenMP_C_LIB_NAMES})
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -lomp -Wno-unused-command-line-argument")
set(OpenMP_CXX_LIB_NAMES "libomp")
set(OpenMP_libomp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
endif()
endif (USE_MACPORTS)
include_directories("${OPENMP_INCLUDES}")
link_directories("${OPENMP_LIBRARIES}")
......@@ -419,6 +436,8 @@ if (WITH_OPENMP)
message( STATUS "OpenMP_CXX_LIB_NAMES: " ${OpenMP_CXX_LIB_NAMES})
endif()
find_package (OpenMP)
# OpenMP_CXX_FOUND was added in cmake 3.9.x
# so we are also checking the OpenMP_FOUND flag
if (OpenMP_CXX_FOUND OR OpenMP_FOUND)
......
04/30/2022: PALISADE v1.11.7 (stable) is released in the palisade-release repo
* Updates the parameter sets for FHEW/TFHE
* Optimizes the BGV AUTO modulus switching mode
* Fixes several bugs
01/28/2022: PALISADE v1.11.6 (stable) is released in the palisade-release repo
* Fixes a bug affecting Intel HEXL builds
* Updates Intel HEXL to 1.2.3
......
No preview for this file type
......@@ -38,7 +38,7 @@ PROJECT_NAME = "PALISADE Lattice Crypto Library"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = "v1.11.6"
PROJECT_NUMBER = "v1.11.7"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
......
......@@ -37,25 +37,39 @@ namespace lbcrypto {
// security levels for predefined parameter sets
enum BINFHEPARAMSET {
TOY, // no security
TOY, // no security
MEDIUM, // 108 bits of security for classical and 100 bits for quantum
STD128, // more than 128 bits of security for classical
// computer attacks - uses the same setup as HE standard
STD128_AP, // Optimized for AP (has higher failure probability for GINX) -
// more than 128 bits of security for classical computer attacks -
// uses the same setup as HE standard
STD192, // more than 192 bits of security for classical computer attacks -
// uses the same setup as HE standard
STD256, // more than 256 bits of security for classical computer attacks -
// uses the same setup as HE standard
STD128Q, // more than 128 bits of security for quantum attacks - uses the
// same setup as HE standard
STD192Q, // more than 192 bits of security for quantum attacks - uses the
// same setup as HE standard
STD256Q, // more than 256 bits of security for quantum attacks - uses the
// same setup as HE standard
STD128_AP, // Optimized for AP (has higher failure probability for GINX) -
// more than 128 bits of security for classical
// computer attacks - uses the same setup as HE standard
STD128_APOPT, // Optimized for AP (has higher failure probability for GINX) -
// more than 128 bits of security for classical computer attacks -
// optimize runtime by finding a non-power-of-two n
STD128, // more than 128 bits of security for classical
// computer attacks - uses the same setup as HE standard
STD128_OPT, // more than 128 bits of security for classical computer attacks -
// optimize runtime by finding a non-power-of-two n
STD192, // more than 192 bits of security for classical computer attacks -
// uses the same setup as HE standard
STD192_OPT, // more than 192 bits of security for classical computer attacks -
// optimize runtime by finding a non-power-of-two n
STD256, // more than 256 bits of security for classical computer attacks -
// uses the same setup as HE standard
STD256_OPT, // more than 256 bits of security for classical computer attacks -
// optimize runtime by finding a non-power-of-two n
STD128Q, // more than 128 bits of security for quantum attacks - uses the
// same setup as HE standard
STD128Q_OPT, // more than 128 bits of security for quantum attacks -
// optimize runtime by finding a non-power-of-two n
STD192Q, // more than 192 bits of security for quantum attacks - uses the
// same setup as HE standard
STD192Q_OPT, // more than 192 bits of security for quantum attacks -
// optimize runtime by finding a non-power-of-two n
STD256Q, // more than 256 bits of security for quantum attacks - uses the
// same setup as HE standard
STD256Q_OPT, // more than 256 bits of security for quantum attacks -
// optimize runtime by finding a non-power-of-two n
SIGNED_MOD_TEST // special parameter set for confirming the signed modular
// reduction in the accumulator updates works correctly
};
// Type of ciphertext generated by the Encrypt method
......@@ -94,6 +108,7 @@ class BinFHEContext : public Serializable {
* @param N ring dimension for RingGSW/RLWE used in bootstrapping
* @param &q modulus for additive LWE
* @param &Q modulus for RingGSW/RLWE used in bootstrapping
* @param &qKS modulus for key switching
* @param std standard deviation
* @param baseKS the base used for key switching
* @param baseG the gadget base used in bootstrapping
......@@ -101,8 +116,8 @@ class BinFHEContext : public Serializable {
* @param method the bootstrapping method (AP or GINX)
* @return creates the cryptocontext
*/
void GenerateBinFHEContext(uint32_t n, uint32_t N, const NativeInteger &q,
const NativeInteger &Q, double std,
void GenerateBinFHEContext(uint32_t n, uint32_t N, const NativeInteger &q,
const NativeInteger &Q, const NativeInteger &qKS, double std,
uint32_t baseKS, uint32_t baseG, uint32_t baseR,
BINFHEMETHOD method = GINX);
......
......@@ -93,13 +93,12 @@ class LWEEncryptionScheme {
/**
* Changes an LWE ciphertext modulo Q into an LWE ciphertext modulo q
*
* @param params a shared pointer to LWE scheme parameters
* @param q modulus to
* @param ctQ the input ciphertext
* @return resulting ciphertext
*/
std::shared_ptr<LWECiphertextImpl> ModSwitch(
const std::shared_ptr<LWECryptoParams> params,
const std::shared_ptr<const LWECiphertextImpl> ctQ) const;
NativeInteger q, const std::shared_ptr<const LWECiphertextImpl> ctQ) const;
/**
* Generates a switching key to go from a secret key with (Q,N) to a secret
......
......@@ -41,7 +41,7 @@ typedef int64_t LWEPlaintext;
*/
class LWECryptoParams : public Serializable {
public:
LWECryptoParams() : m_n(0), m_N(0), m_q(0), m_Q(0), m_baseKS(0) {}
LWECryptoParams() : m_n(0), m_N(0), m_q(0), m_Q(0), m_qKS(0), m_baseKS(0) {}
/**
* Main constructor for LWECryptoParams
......@@ -50,12 +50,13 @@ class LWECryptoParams : public Serializable {
* @param N ring dimension for RingGSW/RLWE used in bootstrapping
* @param &q modulus for additive LWE
* @param &Q modulus for RingGSW/RLWE used in bootstrapping
* @param &qKS modulus for key switching
* @param std standard deviation
* @param baseKS the base used for key switching
*/
explicit LWECryptoParams(uint32_t n, uint32_t N, const NativeInteger &q,
const NativeInteger &Q, double std, uint32_t baseKS)
: m_n(n), m_N(N), m_q(q), m_Q(Q), m_baseKS(baseKS) {
const NativeInteger &Q, const NativeInteger &qKS, double std, uint32_t baseKS)
: m_n(n), m_N(N), m_q(q), m_Q(Q), m_qKS(qKS), m_baseKS(baseKS) {
m_dgg.SetStd(std);
if (Q.GetMSB() > MAX_MODULUS_SIZE) {
......@@ -73,7 +74,7 @@ class LWECryptoParams : public Serializable {
void PreCompute() {
// Number of digits in representing numbers mod Q
uint32_t digitCount = (uint32_t)std::ceil(
log(m_Q.ConvertToDouble()) / log(static_cast<double>(m_baseKS)));
log(m_qKS.ConvertToDouble()) / log(static_cast<double>(m_baseKS)));
// Populate digits
NativeInteger value = 1;
for (uint32_t i = 0; i < digitCount; i++) {
......@@ -87,6 +88,7 @@ class LWECryptoParams : public Serializable {
this->m_N = rhs.m_N;
this->m_q = rhs.m_q;
this->m_Q = rhs.m_Q;
this->m_qKS = rhs.m_qKS;
this->m_baseKS = rhs.m_baseKS;
this->m_digitsKS = rhs.m_digitsKS;
this->m_dgg.SetStd(rhs.m_dgg.GetStd());
......@@ -97,6 +99,7 @@ class LWECryptoParams : public Serializable {
this->m_N = std::move(rhs.m_N);
this->m_q = std::move(rhs.m_q);
this->m_Q = std::move(rhs.m_Q);
this->m_qKS = std::move(rhs.m_qKS);
this->m_baseKS = std::move(rhs.m_baseKS);
this->m_digitsKS = std::move(rhs.m_digitsKS);
this->m_dgg.SetStd(rhs.m_dgg.GetStd());
......@@ -107,6 +110,7 @@ class LWECryptoParams : public Serializable {
this->m_N = rhs.m_N;
this->m_q = rhs.m_q;
this->m_Q = rhs.m_Q;
this->m_qKS = rhs.m_qKS;
this->m_baseKS = rhs.m_baseKS;
this->m_digitsKS = rhs.m_digitsKS;
this->m_dgg.SetStd(rhs.m_dgg.GetStd());
......@@ -118,6 +122,7 @@ class LWECryptoParams : public Serializable {
this->m_N = std::move(rhs.m_N);
this->m_q = std::move(rhs.m_q);
this->m_Q = std::move(rhs.m_Q);
this->m_qKS = std::move(rhs.m_qKS);
this->m_baseKS = std::move(rhs.m_baseKS);
this->m_digitsKS = std::move(rhs.m_digitsKS);
this->m_dgg.SetStd(rhs.m_dgg.GetStd());
......@@ -132,6 +137,8 @@ class LWECryptoParams : public Serializable {
const NativeInteger &GetQ() const { return m_Q; }
const NativeInteger &GetqKS() const { return m_qKS; }
uint32_t GetBaseKS() const { return m_baseKS; }
const std::vector<NativeInteger> &GetDigitsKS() const { return m_digitsKS; }
......@@ -156,6 +163,7 @@ class LWECryptoParams : public Serializable {
ar(::cereal::make_nvp("N", m_N));
ar(::cereal::make_nvp("q", m_q));
ar(::cereal::make_nvp("Q", m_Q));
ar(::cereal::make_nvp("qSK", m_qKS));
ar(::cereal::make_nvp("sigma", m_dgg.GetStd()));
ar(::cereal::make_nvp("bKS", m_baseKS));
}
......@@ -172,6 +180,7 @@ class LWECryptoParams : public Serializable {
ar(::cereal::make_nvp("N", m_N));
ar(::cereal::make_nvp("q", m_q));
ar(::cereal::make_nvp("Q", m_Q));
ar(::cereal::make_nvp("qSK", m_qKS));
double sigma;
ar(::cereal::make_nvp("sigma", sigma));
this->m_dgg.SetStd(sigma);
......@@ -192,6 +201,8 @@ class LWECryptoParams : public Serializable {
NativeInteger m_q;
// modulus for the RingGSW/RingLWE scheme
NativeInteger m_Q;
// modulus for key-switching
NativeInteger m_qKS;
// Error distribution generator
DiscreteGaussianGeneratorImpl<NativeVector> m_dgg;
// Base used in key switching
......
......@@ -28,10 +28,12 @@ namespace lbcrypto {
void BinFHEContext::GenerateBinFHEContext(uint32_t n, uint32_t N,
const NativeInteger &q,
const NativeInteger &Q, double std,
const NativeInteger &Q,
const NativeInteger &qKS,
double std,
uint32_t baseKS, uint32_t baseG,
uint32_t baseR, BINFHEMETHOD method) {
auto lweparams = std::make_shared<LWECryptoParams>(n, N, q, Q, std, baseKS);
auto lweparams = std::make_shared<LWECryptoParams>(n, N, q, Q, qKS, std, baseKS);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, baseG, baseR, method);
}
......@@ -44,79 +46,133 @@ void BinFHEContext::GenerateBinFHEContext(BINFHEPARAMSET set,
case TOY:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(27, 1024),
1024);
lweparams = std::make_shared<LWECryptoParams>(64, 512, 512, Q, 3.19, 25);
lweparams = std::make_shared<LWECryptoParams>(64, 512, 512, Q, Q, 3.19, 25);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 9, 23, method);
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 9, 32, method);
break;
case MEDIUM:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(28, 2048),
2048);
lweparams = std::make_shared<LWECryptoParams>(422, 1024, 1024, Q, 1 << 14, 3.19, 1 << 7);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 10, 32, method);
case STD128_AP:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(27, 2048),
2048);
lweparams =
std::make_shared<LWECryptoParams>(256, 1024, 512, Q, 3.19, 25);
std::make_shared<LWECryptoParams>(512, 1024, 1024, Q, 1 << 14, 3.19, 1 << 7);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 9, 23, method);
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 9, 32, method);
break;
case STD128_AP:
case STD128_APOPT:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(27, 2048),
2048);
lweparams =
std::make_shared<LWECryptoParams>(512, 1024, 512, Q, 3.19, 25);
std::make_shared<LWECryptoParams>(502, 1024, 1024, Q, 1 << 14, 3.19, 1 << 7);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 9, 23, method);
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 9, 32, method);
break;
case STD128:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(27, 2048),
2048);
lweparams =
std::make_shared<LWECryptoParams>(512, 1024, 512, Q, 3.19, 25);
std::make_shared<LWECryptoParams>(512, 1024, 1024, Q, 1 << 14, 3.19, 1 << 7);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 7, 23, method);
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 7, 32, method);
break;
case STD128_OPT:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(27, 2048),
2048);
lweparams =
std::make_shared<LWECryptoParams>(502, 1024, 1024, Q, 1 << 14, 3.19, 1 << 7);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 7, 32, method);
break;
case STD192:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(37, 4096),
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(54, 4096),
4096);
lweparams =
std::make_shared<LWECryptoParams>(1024, 2048, 1024, Q, 1 << 19, 3.19, 28);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 27, 32, method);
break;
case STD192_OPT:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(54, 4096),
4096);
lweparams =
std::make_shared<LWECryptoParams>(512, 2048, 512, Q, 3.19, 25);
std::make_shared<LWECryptoParams>(805, 2048, 1024, Q, 1 << 15, 3.19, 1 << 5);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 13, 23, method);
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 27, 32, method);
break;
case STD256:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(29, 4096),
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(50, 4096),
4096);
lweparams =
std::make_shared<LWECryptoParams>(1024, 2048, 1024, Q, 3.19, 25);
std::make_shared<LWECryptoParams>(1024, 2048, 2048, Q, 1 << 14, 3.19, 1 << 7);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 10, 32, method);
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 25, 46, method);
break;
case STD256_OPT:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(50, 4096),
4096);
lweparams =
std::make_shared<LWECryptoParams>(990, 2048, 2048, Q, 1 << 14, 3.19, 1 << 7);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 25, 46, method);
break;
case STD128Q:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(50, 4096),
4096);
lweparams =
std::make_shared<LWECryptoParams>(512, 2048, 512, Q, 3.19, 25);
std::make_shared<LWECryptoParams>(1024, 2048, 1024, Q, 1 << 25, 3.19, 32);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 25, 32, method);
break;
case STD128Q_OPT:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(50, 4096),
4096);
lweparams =
std::make_shared<LWECryptoParams>(585, 2048, 1024, Q, 1 << 15, 3.19, 32);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 25, 23, method);
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 25, 32, method);
break;
case STD192Q:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(35, 4096),
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(50, 4096),
4096);
lweparams =
std::make_shared<LWECryptoParams>(1024, 2048, 1024, Q, 3.19, 25);
std::make_shared<LWECryptoParams>(1024, 2048, 1024, Q, 1 << 17, 3.19, 64);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 12, 32, method);
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 25, 32, method);
break;
case STD192Q_OPT:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(50, 4096),
4096);
lweparams =
std::make_shared<LWECryptoParams>(875, 2048, 1024, Q, 1 << 15, 3.19, 1 << 5);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 25, 32, method);
break;
case STD256Q:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(27, 4096),
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(54, 4096),
4096);
lweparams =
std::make_shared<LWECryptoParams>(1024, 2048, 1024, Q, 3.19, 25);
std::make_shared<LWECryptoParams>(2048, 2048, 1024, Q, 1 << 16, 3.19, 16);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 7, 32, method);
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 27, 32, method);
break;
case STD256Q_OPT:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(54, 4096),
4096);
lweparams =
std::make_shared<LWECryptoParams>(1225, 2048, 1024, Q, 1 << 16, 3.19, 16);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 27, 32, method);
break;
case SIGNED_MOD_TEST:
Q = PreviousPrime<NativeInteger>(FirstPrime<NativeInteger>(28, 2048),
2048);
lweparams =
std::make_shared<LWECryptoParams>(512, 1024, 512, Q, 3.19, 25);
std::make_shared<LWECryptoParams>(512, 1024, 512, Q, Q, 3.19, 25);
m_params =
std::make_shared<RingGSWCryptoParams>(lweparams, 1 << 7, 23, method);
break;
......
......@@ -560,15 +560,15 @@ std::shared_ptr<LWECiphertextImpl> RingGSWAccumulatorScheme::EvalBinGate(
// we add Q/8 to "b" to to map back to Q/4 (i.e., mod 2) arithmetic.
bNew = Q8.ModAddFast(temp[0], Q);
auto eQN =
std::make_shared<LWECiphertextImpl>(std::move(aNew), std::move(bNew));
// Modulus switching to a middle step Q'
auto eQN = LWEscheme->ModSwitch(params->GetLWEParams()->GetqKS(), std::make_shared<LWECiphertextImpl>(aNew, bNew));
// Key switching
const std::shared_ptr<const LWECiphertextImpl> eQ =
LWEscheme->KeySwitch(params->GetLWEParams(), EK.KSkey, eQN);
// Modulus switching
return LWEscheme->ModSwitch(params->GetLWEParams(), eQ);
return LWEscheme->ModSwitch(q, eQ);
}
}
......@@ -607,15 +607,15 @@ std::shared_ptr<LWECiphertextImpl> RingGSWAccumulatorScheme::Bootstrap(
// we add Q/8 to "b" to to map back to Q/4 (i.e., mod 2) arithmetic.
bNew = Q8.ModAddFast(temp[0], Q);
auto eQN =
std::make_shared<LWECiphertextImpl>(std::move(aNew), std::move(bNew));
// Modulus switching to a middle step Q'
auto eQN = LWEscheme->ModSwitch(params->GetLWEParams()->GetqKS(), std::make_shared<LWECiphertextImpl>(aNew, bNew));
// Key switching
const std::shared_ptr<const LWECiphertextImpl> eQ =
LWEscheme->KeySwitch(params->GetLWEParams(), EK.KSkey, eQN);
// Modulus switching
return LWEscheme->ModSwitch(params->GetLWEParams(), eQ);
return LWEscheme->ModSwitch(q, eQ);
}
// Evaluation of the NOT operation; no key material is needed
......
......@@ -132,16 +132,12 @@ NativeInteger RoundqQ(const NativeInteger &v, const NativeInteger &q,
// Modulus switching - directly applies the scale-and-round operation RoundQ
std::shared_ptr<LWECiphertextImpl> LWEEncryptionScheme::ModSwitch(
const std::shared_ptr<LWECryptoParams> params,
const std::shared_ptr<const LWECiphertextImpl> ctQ) const {
NativeVector a(params->Getn(), params->Getq());
uint32_t n = params->Getn();
NativeInteger q = params->Getq();
NativeInteger Q = params->GetQ();
NativeInteger q, const std::shared_ptr<const LWECiphertextImpl> ctQ) const {
auto n = ctQ->GetA().GetLength();
auto Q = ctQ->GetA().GetModulus();
NativeVector a(n, q);
for (uint32_t i = 0; i < n; ++i) a[i] = RoundqQ(ctQ->GetA()[i], q, Q);
NativeInteger b = RoundqQ(ctQ->GetB(), q, Q);
return std::make_shared<LWECiphertextImpl>(LWECiphertextImpl(a, b));
......@@ -155,7 +151,7 @@ std::shared_ptr<LWESwitchingKey> LWEEncryptionScheme::KeySwitchGen(
// Create local copies of main variables
uint32_t n = params->Getn();
uint32_t N = params->GetN();
NativeInteger Q = params->GetQ();
NativeInteger Q = params->GetqKS();
uint32_t baseKS = params->GetBaseKS();
std::vector<NativeInteger> digitsKS = params->GetDigitsKS();
uint32_t expKS = digitsKS.size();
......@@ -165,7 +161,16 @@ std::shared_ptr<LWESwitchingKey> LWEEncryptionScheme::KeySwitchGen(
NativeVector newSK = sk->GetElement();
newSK.SwitchModulus(Q);
NativeVector oldSK = skN->GetElement();
NativeVector oldSKlargeQ = skN->GetElement();
NativeVector oldSK(oldSKlargeQ.GetLength(), Q);
for(size_t i = 0; i < oldSK.GetLength(); i++){
if((oldSKlargeQ[i] == 0) || (oldSKlargeQ[i] == 1)){
oldSK[i] = oldSKlargeQ[i];
}
else {
oldSK[i] = Q - 1;
}
}
DiscreteUniformGeneratorImpl<NativeVector> dug;
dug.SetModulus(Q);
......@@ -214,7 +219,7 @@ std::shared_ptr<LWECiphertextImpl> LWEEncryptionScheme::KeySwitch(
const std::shared_ptr<const LWECiphertextImpl> ctQN) const {
uint32_t n = params->Getn();
uint32_t N = params->GetN();
NativeInteger Q = params->GetQ();
NativeInteger Q = params->GetqKS();
uint32_t baseKS = params->GetBaseKS();
std::vector<NativeInteger> digitsKS = params->GetDigitsKS();
uint32_t expKS = digitsKS.size();
......
......@@ -120,8 +120,8 @@ TEST(UnitTestFHEWAP, ModSwitch) {
auto ctQ0 = cc.Encrypt(skQ, 0, FRESH);