...
 
Commits (3)
......@@ -50,3 +50,10 @@ src/circuit/lib/scan.cpp
src/circuit/lib/parse.cpp
src/circuit/lib/parse.hpp
src/circuit/lib/*.hh
# vagrant output
.vagrant/
*.log
# gtest output files
test_detail.xml
......@@ -75,7 +75,7 @@ endif
ROOTDIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
PACKAGE := palisade
VERSION := 1.4.1
VERSION := 1.5.0
#build directory
BUILDDIR := build
......@@ -184,7 +184,7 @@ uninstall: uninstallcore uninstallpke uninstallabe uninstallsignature
UNITTESTMAINOBJ := $(BINDIR)/unittest/Main_TestAll.o
$(UNITTESTMAINOBJ): test/include/gtest/Main_TestAll.cpp src/core/lib/math/backend.h
$(UNITTESTMAINOBJ): test/include/gtest/Main_TestAll.cpp src/core/lib/math/backend.h src/version.h
@mkdir -p $(BINDIR)/unittest
$(CC) -c $(CPPFLAGS) $(INC) -o $@ $<
......
3/20/2019: PALISADE v1.5.0 is released
Fixes the vulnerability found in https://eprint.iacr.org/2017/785 (PKC'19) for the PRE schemes based on BGV/BFV
Adds PRE modes for BGV/BFV that are secure under honest re-reencryption attacks (recommended security for practical use)
Adds support for splitting lattice trapdoor sampling into offline and online phases (used by digital signatures, IBE, and ABE constructions)
Fixes bugs related to the multi-threaded mode of operation
02/11/2018: PALISADE v1.4.1 is released
Fixes a bug affecting the IBE and CP-ABE implementations (some unit tests for IBE/CP-ABE were entering in an infinite loop in about 10% of the runs).
......
......@@ -111,34 +111,6 @@ static void GeneratePolys(map<usint,shared_ptr<P>>& parmArray, map<usint,vector<
}
}
// the ifdefs below are a hack to make sure this compiles in all backends
// when backend is == 2, BigInteger is the same as M2Integer... and so these methods
// will have duplicate instantiations... which is bad
// FIXME later
#if MATHBACKEND != 2
template<>
inline shared_ptr<ILDCRTParams<M2Integer>>
ElemParamFactory::GenElemParams<ILDCRTParams<M2Integer>>(usint m, usint bits, usint towersize) {
return GenerateDCRTParams<M2Integer>(m, towersize, bits);
}
#endif
#if MATHBACKEND != 4
template<>
inline shared_ptr<ILDCRTParams<M4Integer>>
ElemParamFactory::GenElemParams<ILDCRTParams<M4Integer>>(usint m, usint bits, usint towersize) {
return GenerateDCRTParams<M4Integer>(m, towersize, bits);
}
#endif
#if MATHBACKEND != 6
template<>
inline shared_ptr<ILDCRTParams<M6Integer>>
ElemParamFactory::GenElemParams<ILDCRTParams<M6Integer>>(usint m, usint bits, usint towersize) {
return GenerateDCRTParams<M6Integer>(m, towersize, bits);
}
#endif
}
map<usint,shared_ptr<ILNativeParams>> Nativeparms;
......
......@@ -86,3 +86,9 @@ echo OpenMP OK
MINGWREGEX="-Lc:/Mingw64/mingw64/opt/lib -lregex -lshlwapi"
OMPINCLUDE="-I /opt/local/include/libomp -fopenmp"
lzip -V >/dev/null 2>&1
[ $? -ne 0 ] && echo lzip is not available installed -- needed for gmp install && exit 1
echo lzip OK -- needed for gmp install
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.4.1"
PROJECT_NUMBER = "v1.5.0"
# 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
......
/**
* @file CPABETwoPhaseDemo.cpp - Demo file for ciphertext-policy attribute based encryption utilizing two-phase approach in key generation
* @author TPOC: palisade@njit.edu
*
* @copyright Copyright (c) 2017, New Jersey Institute of Technology (NJIT)
* All rights reserved.
* 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 "palisade.h"
#include "../lib/abecontext.h"
using namespace lbcrypto;
int main(){
//Create context under security level and number of attributes
std::cout<<"This is a demo file of the CPABE scheme with two-phase key generation"<<std::endl<<std::endl;
usint ringsize = 1024;
usint numAttributes = 6;
usint base = 64;
TimeVar t1;
std::cout<<"Used parameters:"<<std::endl;
std::cout<<"Ring size: "<<ringsize<<std::endl;
std::cout<<"Number of attributes: "<<numAttributes<<std::endl;
std::cout<<"Base: "<<base<<std::endl<<std::endl;
ABEContext<NativePoly> context;
std::cout<<"Generating a context under these parameters"<<std::endl<<std::endl;
context.GenerateCPABEContext(numAttributes,ringsize,base);
std::cout<<"Generating master secret key and master public key"<<std::endl;
//Generate master keys
TIC(t1);
CPABEMasterPublicKey<NativePoly> mpk;
CPABEMasterSecretKey<NativePoly> msk;
context.Setup(&mpk,&msk);
double duration = TOC(t1);
std::cout<<"Setup: "<<duration<<" ms"<<std::endl<<std::endl;
//Create a random access policy and user attribute set
std::cout<<" Creating access policy and user attribute sets"<<std::endl;
std::vector<usint> s(6);
std::vector<int> w(6);
for(usint j=0; j<6; j++)
s[j] = rand()%2;
for(usint j=0; j<6; j++)
w[j] = s[j];
for(usint j=0; j<6; j++)
if(w[j]==1) {
w[j] = 0;
break;
}
for(usint j=0; j<6; j++)
if(s[j]==0) {
w[j] = -1;
break;
}
std::cout<<"User attribute set: "<<s<<std::endl;
std::cout<<"Access policy defined:"<<w<<std::endl<<std::endl;
CPABEUserAccess<NativePoly> ua(s);
CPABEAccessPolicy<NativePoly> ap(w);
//Create the key corresponding to the access policy
CPABESecretKey<NativePoly> sk;
std::cout<<"Creating secret key for the attribute set"<<std::endl;
PerturbationVector<NativePoly> pv;
TIC(t1);
context.KeyGenOfflinePhase(msk,pv);
duration = TOC(t1);
std::cout<<"KeyGen (Offline): "<<duration<<" ms"<<std::endl;
TIC(t1);
context.KeyGenOnlinePhase(msk,mpk,ua,pv,&sk);
duration = TOC(t1);
std::cout<<"KeyGen (Online): "<<duration<<" ms"<<std::endl<<std::endl;
//Create a plaintext
std::vector<int64_t> vectorOfInts = { 1,0,0,1,1,0,1,0, 1, 0};
Plaintext pt = context.MakeCoefPackedPlaintext(vectorOfInts);
std::cout<<"Plaintext vector of bits: "<<vectorOfInts<<std::endl<<std::endl;
//Encrypt the plaintext
std::cout<<"Encrypting the plaintext under the access policy"<<std::endl;
TIC(t1);
CPABECiphertext<NativePoly> ct;
context.Encrypt(mpk,ap,pt,&ct);
duration = TOC(t1);
std::cout<<"Encryption: "<<duration<<" ms"<<std::endl<<std::endl;
//Decrypt the ciphertext
std::cout<<"Decrpyting the ciphertext"<<std::endl;
TIC(t1);
Plaintext dt = context.Decrypt(ap,ua,sk,ct);
duration = TOC(t1);
std::cout<<"Decryption: "<<duration<<" ms"<<std::endl<<std::endl;
std::cout<<"Checking if the plaintext & decrypted text match"<<std::endl;
//Check if original plaintext and decrypted plaintext match
if(pt->GetElement<NativePoly>() == dt->GetElement<NativePoly>()){
std::cout<<"Encryption & decryption successful"<<std::endl;
}else{
std::cout<<"Encryption & decryption failed"<<std::endl;
}
}
/**
* @file IBETwoPhaseDemo.cpp - Demo file for identity based encryption utilizing a two-phase approach for key generation
* @author TPOC: palisade@njit.edu
*
* @copyright Copyright (c) 2017, New Jersey Institute of Technology (NJIT)
* All rights reserved.
* 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 "../lib/abecontext.h"
#include "palisade.h"
using namespace lbcrypto;
int main(){
//Create context under given ringsize and base
//Create context under security level and number of attributes
std::cout<<"This is a demo file of the IBE scheme with two-phase key generation"<<std::endl<<std::endl;
usint ringsize = 1024;
usint base = 4;
TimeVar t1;
std::cout<<"Used parameters:"<<std::endl;
std::cout<<"Ring size: "<<ringsize<<std::endl;
std::cout<<"Base: "<<base<<std::endl<<std::endl;
ABEContext<NativePoly> context;
std::cout<<"Generating a context under these parameters"<<std::endl<<std::endl;
context.GenerateIBEContext(ringsize,base);
//Generate master keys
std::cout<<"Generating master secret and public keys"<<std::endl;
IBEMasterPublicKey<NativePoly> mpk;
IBEMasterSecretKey<NativePoly> msk;
TIC(t1);
context.Setup(&mpk,&msk);
double duration = TOC(t1);
std::cout<<"Setup: "<<duration<<" ms"<<std::endl<<std::endl;
std::cout<<"Creating a random identifier for the user"<<std::endl<<std::endl;
//Generate a random identifier for the user
IBEUserIdentifier<NativePoly> id(context.GenerateRandomElement());
std::cout<<"Generating the secret key for the user"<<std::endl;
//Generate the secret key for the user
IBESecretKey<NativePoly> sk;
PerturbationVector<NativePoly> pv;
TIC(t1);
context.KeyGenOfflinePhase(msk,pv);
duration = TOC(t1);
std::cout<<"KeyGen (Offline): "<<duration<<" ms"<<std::endl;
TIC(t1);
context.KeyGenOnlinePhase(msk,mpk,id,pv,&sk);
duration = TOC(t1);
std::cout<<"KeyGen (Online): "<<duration<<" ms"<<std::endl<<std::endl;
//Generate a plaintext
std::vector<int64_t> vectorOfInts = { 1,0,0,1,1,0,1,0, 1, 0};
Plaintext pt = context.MakeCoefPackedPlaintext(vectorOfInts);
std::cout<<"Plaintext vector of bits:"<<vectorOfInts<<std::endl<<std::endl;
//Encrypt the plaintext
std::cout<<"Encrypting the plaintext for the user with the id"<<std::endl;
IBECiphertext<NativePoly> ct;
TIC(t1);
context.Encrypt(mpk,id,pt,&ct);
duration = TOC(t1);
std::cout<<"Encryption: "<<duration<<" ms"<<std::endl<<std::endl;
//Decrypt the ciphertext
std::cout<<"Decrypting the ciphertext"<<std::endl;
TIC(t1);
Plaintext dt = context.Decrypt(id,id,sk,ct);
duration = TOC(t1);
std::cout<<"Decryption: "<<duration<<" ms"<<std::endl<<std::endl;
std::cout<<"Checking if plaintext & decrypted text match"<<std::endl;
//Check if original plaintext and decrypted plaintext match
if(pt->GetElement<NativePoly>() == dt->GetElement<NativePoly>()){
std::cout<<"Encryption & decryption successful"<<std::endl;
}else{
std::cout<<"Encryption & decryption failed"<<std::endl;
}
return 0;
}
......@@ -76,6 +76,16 @@ namespace lbcrypto{
void ABEContext<Element>::KeyGen(const ABECoreMasterSecretKey<Element> & msk,const ABECoreMasterPublicKey<Element>& mpk, const ABECoreAccessPolicy<Element> & ap,ABECoreSecretKey<Element>* sk){
m_scheme->KeyGen(m_params,msk,mpk,ap,sk);
}
//Method for offline phase of individual/policy specific key generation for decryption
template <class Element>
void ABEContext<Element>::KeyGenOfflinePhase(const ABECoreMasterSecretKey<Element> & msk,PerturbationVector<Element>& pv){
pv = m_scheme->KeyGenOffline(m_params,msk);
}
//Method for online phase individual/policy specific key generation for decryption
template <class Element>
void ABEContext<Element>::KeyGenOnlinePhase(const ABECoreMasterSecretKey<Element> & msk,const ABECoreMasterPublicKey<Element>& mpk, const ABECoreAccessPolicy<Element> & ap,const PerturbationVector<Element> & pv,ABECoreSecretKey<Element>* sk){
m_scheme->KeyGenOnline(m_params,msk,mpk,ap,pv,sk);
}
//Method for encryption
template <class Element>
void ABEContext<Element>::Encrypt(const ABECoreMasterPublicKey<Element> & mpk,const ABECoreAccessPolicy<Element> & ap,const Plaintext & ptext,ABECoreCiphertext<Element>* ct){
......
......@@ -87,6 +87,21 @@
*/
void KeyGen(const ABECoreMasterSecretKey<Element> & msk,const ABECoreMasterPublicKey<Element>& mpk, const ABECoreAccessPolicy<Element> & ap,ABECoreSecretKey<Element>* sk);
/**
*@brief Method for offline phase of individual/policy specific key generation for decryption
*@param msk Master secret key
*@param pv Perturbation vector sampled - Output
*/
void KeyGenOfflinePhase(const ABECoreMasterSecretKey<Element> & msk,PerturbationVector<Element>& pv);
/**
*@brief Method for online phase individual/policy specific key generation for decryption
*@param msk Master secret key
*@param mpk Master public key
*@param ap Access policy/user identifier
*@param pv Perturbation vector sampled in the offline phase of key generation
*@param sk Secret key defined for the given policy/identifier - Output
*/
void KeyGenOnlinePhase(const ABECoreMasterSecretKey<Element> & msk,const ABECoreMasterPublicKey<Element>& mpk, const ABECoreAccessPolicy<Element> & ap,const PerturbationVector<Element> & pv,ABECoreSecretKey<Element>* sk);
/**
*@brief Method for encryption
*@param mpk Master public key
*@param ap Access structure
......
......@@ -322,7 +322,34 @@ namespace lbcrypto{
const ABECoreMasterSecretKey<Element> & msk,
const ABECoreMasterPublicKey<Element> & mpk,
ABECoreSecretKey<Element>* sk){};
/*
/*
*@brief Method for offline sampling for key generation phase of an ABE cycle
*@param m_params Parameters used in operations
*@param msk Master secret key
*@return Perturbation vector sampled
*/
virtual PerturbationVector<Element> KeyGenOffline(
shared_ptr<ABECoreParams<Element>> m_params,
const ABECoreMasterSecretKey<Element> & msk){ return PerturbationVector<Element>();};
/*
*@brief Method for online phase for key generation phase of an IBE cycle without sampling
*@param m_params Parameters used in operations
*@param msk Master secret key
*@param mpk Master public key
*@param ap Access policy defining who will be able to decrypt
*@param pvector Perturbation vector sampled before hand
*@param sk Secret key for decryption - Output
*/
virtual void KeyGenOnline(
shared_ptr<ABECoreParams<Element>> m_params,
const ABECoreMasterSecretKey<Element> & msk,
const ABECoreMasterPublicKey<Element> & mpk,
const ABECoreAccessPolicy<Element> & ap,
const PerturbationVector<Element> & pvector,
ABECoreSecretKey<Element>* sk){};
/*
*@brief Method for encryption phase of an ABE cycle
*@param mpk Master public key
*@param ap Access policy defining who will be able to decrypt
......
......@@ -127,9 +127,7 @@ namespace lbcrypto{
y = pubElemD - y;
Matrix<Element> skA(Element::Allocator(m_params->GetTrapdoorParams()->GetElemParams(), EVALUATION), m_m, 1);
skA = RLWETrapdoorUtility<Element>::GaussSamp(m_N, m_k, mpk.GetA(), msk.GetTA(), y, m_params->GetTrapdoorParams()->GetDGG(), m_params->GetTrapdoorParams()->GetDGGLargeSigma(), m_base);
Matrix<Element> sk(Element::Allocator(ep, COEFFICIENT), m_m, m_ell+1);
for(usint i=0; i<m_m; i++)
(sk)(i, 0) = skA(i, 0);
......@@ -143,14 +141,23 @@ namespace lbcrypto{
}
//Method for offline sampling for key generation phase of an CPABE cycle
template <class Element>
PerturbationVector<Element> KeyGenOffline(shared_ptr<CPABEParams<Element>> m_params,const CPABEMasterSecretKey<Element> & msk){
shared_ptr<Matrix<Element>> pertubationVector = RLWETrapdoorUtility<Element>::GaussSampOffline(m_params->GetTrapdoorParams()->GetN(), m_params()->GetTrapdoorParams()->GetK(), msk.GetTA(), m_params->GetTrapdoorParams()->GetDGG(), m_params->GetTrapdoorParams()->GetDGGLargeSigma(), m_params->GetTrapdoorParams()->GetBase());
PerturbationVector<Element> CPABEScheme<Element>::KeyGenOffline(shared_ptr<ABECoreParams<Element>> cm_params,const ABECoreMasterSecretKey<Element> & cmsk){
shared_ptr<CPABEParams<Element>> m_params = dynamic_pointer_cast<CPABEParams<Element>>(cm_params);
const CPABEMasterSecretKey<Element> & msk = dynamic_cast<const CPABEMasterSecretKey<Element> &>(cmsk);
shared_ptr<Matrix<Element>> pertubationVector = RLWETrapdoorUtility<Element>::GaussSampOffline(m_params->GetTrapdoorParams()->GetN(), m_params->GetTrapdoorParams()->GetK(), msk.GetTA(), m_params->GetTrapdoorParams()->GetDGG(), m_params->GetTrapdoorParams()->GetDGGLargeSigma(), m_params->GetTrapdoorParams()->GetBase());
PerturbationVector<Element> pvector(pertubationVector);
return pvector;
}
//Method for online phase for key generation phase of an CPABE cycle without sampling
template <class Element>
void KeyGenOnline(shared_ptr<CPABEParams<Element>> m_params,const CPABEMasterSecretKey<Element> & msk,const CPABEMasterPublicKey<Element> & mpk, const CPABEUserAccess<Element> & id,const PerturbationVector<Element> & pvector,CPABESecretKey<Element>* usk){
void CPABEScheme<Element>::KeyGenOnline(shared_ptr<ABECoreParams<Element>> cm_params,const ABECoreMasterSecretKey<Element> & cmsk,const ABECoreMasterPublicKey<Element> & cmpk, const ABECoreAccessPolicy<Element> & cid,const PerturbationVector<Element> & pvector,ABECoreSecretKey<Element>* cusk){
shared_ptr<CPABEParams<Element>> m_params = dynamic_pointer_cast<CPABEParams<Element>>(cm_params);
const CPABEMasterSecretKey<Element> & msk = dynamic_cast<const CPABEMasterSecretKey<Element> &>(cmsk);
const CPABEMasterPublicKey<Element> & mpk = dynamic_cast<const CPABEMasterPublicKey<Element> &>(cmpk);
const CPABEUserAccess<Element> & id = dynamic_cast<const CPABEUserAccess<Element> &>(cid);
CPABESecretKey<Element>* usk = dynamic_cast<CPABESecretKey<Element>*>(cusk);
usint m_ell = m_params->GetEll();
usint m_k = m_params->GetTrapdoorParams()->GetK();
usint m_m = m_k+2;
......@@ -174,7 +181,7 @@ namespace lbcrypto{
const Matrix<Element> & pubElemBPos = mpk.GetBPos();
const Matrix<Element> & pubElemBNeg = mpk.GetBNeg();
usint *s = id.GetS();
const std::vector<usint> s = id.GetS();
const Element & pubElemD = mpk.GetPubElemD();
//#pragma omp parallel for firstprivate(z) num_threads(4)
for(usint i=0; i<m_ell; i++) {
......
......@@ -355,8 +355,8 @@ namespace lbcrypto{
*@param msk Master secret key
*@return Perturbation vector sampled
*/
PerturbationVector<Element> KeyGenOffline(shared_ptr<CPABEParams<Element>> m_params,
const CPABEMasterSecretKey<Element> & msk);
PerturbationVector<Element> KeyGenOffline(shared_ptr<ABECoreParams<Element>> m_params,
const ABECoreMasterSecretKey<Element> & msk);
/*
*@brief Method for online phase for key generation phase of an CPABE cycle without sampling
*@param m_params Parameters used in operations
......@@ -366,12 +366,12 @@ namespace lbcrypto{
*@param pvector Perturbation vector sampled before hand
*@param usk Secret key for decryption - Output
*/
void KeyGenOnline(shared_ptr<CPABEParams<Element>> m_params,
const CPABEMasterSecretKey<Element> & msk,
const CPABEMasterPublicKey<Element> & mpk,
const CPABEUserAccess<Element> & id,
void KeyGenOnline(shared_ptr<ABECoreParams<Element>> m_params,
const ABECoreMasterSecretKey<Element> & msk,
const ABECoreMasterPublicKey<Element> & mpk,
const ABECoreAccessPolicy<Element> & id,
const PerturbationVector<Element> & pvector,
CPABESecretKey<Element>* usk);
ABECoreSecretKey<Element>* usk);
/*
*@brief Method for encryption phase of a CPABE cycle
......
......@@ -50,22 +50,34 @@ namespace lbcrypto{
}
//Method for offline sampling for key generation phase of an IBE cycle
template<class Element>
PerturbationVector<Element> KeyGenOffline(shared_ptr<IBEParams<Element>> m_params,const IBEMasterSecretKey<Element> & msk){
shared_ptr<Matrix<Element>> pertubationVector = RLWETrapdoorUtility<Element>::GaussSampOffline(m_params->GetTrapdoorParams()->GetN(), m_params()->GetTrapdoorParams()->GetK(), msk.GetTA(), m_params->GetTrapdoorParams()->GetDGG(), m_params->GetTrapdoorParams()->GetDGGLargeSigma(), m_params->GetTrapdoorParams()->GetBase());
PerturbationVector<Element> IBEScheme<Element>::KeyGenOffline(
shared_ptr<ABECoreParams<Element>> cm_params,
const ABECoreMasterSecretKey<Element> & cmsk){
shared_ptr<IBEParams<Element>> m_params = dynamic_pointer_cast<IBEParams<Element>>(cm_params);
const IBEMasterSecretKey<Element>& msk = dynamic_cast<const IBEMasterSecretKey<Element>&>(cmsk);
shared_ptr<Matrix<Element>> pertubationVector = RLWETrapdoorUtility<Element>::GaussSampOffline(m_params->GetTrapdoorParams()->GetN(), m_params->GetTrapdoorParams()->GetK(), msk.GetTA(), m_params->GetTrapdoorParams()->GetDGG(), m_params->GetTrapdoorParams()->GetDGGLargeSigma(), m_params->GetTrapdoorParams()->GetBase());
PerturbationVector<Element> pvector(pertubationVector);
return pvector;
}
//Method for online phase for key generation phase of an IBE cycle without sampling
template<class Element>
void KeyGenOnline(
shared_ptr<IBEParams<Element>> m_params,
const IBEMasterSecretKey<Element> & msk,
const IBEMasterPublicKey<Element> & mpk,
const IBEUserIdentifier<Element> & id,
const PerturbationVector<Element> & pvector,
IBESecretKey<Element>* sk){
sk->SetSK(RLWETrapdoorUtility<Element>::GaussSampOnline(m_params->GetTrapdoorParams()->GetN(), m_params->GetTrapdoorParams()->GetK(), mpk.GetA(), msk.GetTA(), id.GetID(), m_params->GetTrapdoorParams()->GetDGG(), pvector.GetVector(), m_params->GetTrapdoorParams()->GetBase()));
void IBEScheme<Element>::KeyGenOnline(
shared_ptr<ABECoreParams<Element>> cm_params,
const ABECoreMasterSecretKey<Element> & cmsk,
const ABECoreMasterPublicKey<Element> & cmpk,
const ABECoreAccessPolicy<Element> & cid,
const PerturbationVector<Element> & pvector,
ABECoreSecretKey<Element>* csk){
shared_ptr<IBEParams<Element>> m_params = dynamic_pointer_cast<IBEParams<Element>>(cm_params);
const IBEMasterPublicKey<Element> & mpk = dynamic_cast<const IBEMasterPublicKey<Element>&>(cmpk);
const IBEMasterSecretKey<Element>& msk = dynamic_cast<const IBEMasterSecretKey<Element>&>(cmsk);
const IBEUserIdentifier<Element> & id = dynamic_cast<const IBEUserIdentifier<Element> &>(cid);
IBESecretKey<Element>* sk = dynamic_cast<IBESecretKey<Element>*>(csk);
Matrix<Element> key = RLWETrapdoorUtility<Element>::GaussSampOnline(m_params->GetTrapdoorParams()->GetN(), m_params->GetTrapdoorParams()->GetK(), mpk.GetA(), msk.GetTA(), id.GetID(), m_params->GetTrapdoorParams()->GetDGG(), pvector.GetVector(), m_params->GetTrapdoorParams()->GetBase());
sk->SetSK(std::make_shared<Matrix<Element>>(key));
}
//Method for encryption phase of an IBE cycle
template<class Element>
......
......@@ -280,8 +280,8 @@ namespace lbcrypto{
*@return Perturbation vector sampled
*/
PerturbationVector<Element> KeyGenOffline(
shared_ptr<IBEParams<Element>> m_params,
const IBEMasterSecretKey<Element> & msk);
shared_ptr<ABECoreParams<Element>> m_params,
const ABECoreMasterSecretKey<Element> & msk);
/*
*@brief Method for online phase for key generation phase of an IBE cycle without sampling
*@param m_params Parameters used in operations
......@@ -292,12 +292,12 @@ namespace lbcrypto{
*@param sk Secret key for decryption - Output
*/
void KeyGenOnline(
shared_ptr<IBEParams<Element>> m_params,
const IBEMasterSecretKey<Element> & msk,
const IBEMasterPublicKey<Element> & mpk,
const IBEUserIdentifier<Element> & id,
const PerturbationVector<Element> & pvector,
IBESecretKey<Element>* sk);
shared_ptr<ABECoreParams<Element>> m_params,
const ABECoreMasterSecretKey<Element> & msk,
const ABECoreMasterPublicKey<Element> & mpk,
const ABECoreAccessPolicy<Element> & ap,
const PerturbationVector<Element> & pvector,
ABECoreSecretKey<Element>* sk);
/*
*@brief Method for encryption phase of an IBE cycle
*@param m_params Parameters used in operations
......
......@@ -63,7 +63,6 @@ void UnitTestCPABE(SecurityLevel level,usint ell){
CPABEMasterPublicKey<Element> mpk;
CPABEMasterSecretKey<Element> msk;
context.Setup(&mpk,&msk);
std::vector<usint> s(ell);
std::vector<int> w(ell);
......@@ -95,6 +94,48 @@ void UnitTestCPABE(SecurityLevel level,usint ell){
context.Encrypt(mpk,ap,pt,&ct);
Plaintext dt = context.Decrypt(ap,ua,sk,ct);
EXPECT_EQ(pt->GetElement<Element>(),dt->GetElement<Element>());
}
template <class Element>
void UnitTestCPABETwoPhase(SecurityLevel level,usint ell){
ABEContext<Element> context;
context.GenerateCPABEContext(level,ell);
CPABEMasterPublicKey<Element> mpk;
CPABEMasterSecretKey<Element> msk;
context.Setup(&mpk,&msk);
std::vector<usint> s(ell);
std::vector<int> w(ell);
for(usint j=0; j<ell; j++)
s[j] = rand()%2;
for(usint j=0; j<ell; j++)
w[j] = s[j];
for(usint j=0; j<ell; j++)
if(w[j]==1) {
w[j] = 0;
break;
}
for(usint j=0; j<ell; j++)
if(s[j]==0) {
w[j] = -1;
break;
}
CPABEUserAccess<Element> ua(s);
CPABEAccessPolicy<Element> ap(w);
CPABESecretKey<Element> sk;
PerturbationVector<Element> pv;
context.KeyGenOfflinePhase(msk,pv);
context.KeyGenOnlinePhase(msk,mpk,ua,pv,&sk);
std::vector<int64_t> vectorOfInts = { 1,0,0,1,1,0,1,0, 1, 0};
Plaintext pt = context.MakeCoefPackedPlaintext(vectorOfInts);
CPABECiphertext<Element> ct;
context.Encrypt(mpk,ap,pt,&ct);
Plaintext dt = context.Decrypt(ap,ua,sk,ct);
EXPECT_EQ(pt->GetElement<Element>(),dt->GetElement<Element>());
......@@ -153,3 +194,6 @@ TEST(UTCPABE, cp_abe_256_native_20) {
TEST(UTCPABE, cp_abe_256_native_32) {
UnitTestCPABE<NativePoly>(HEStd_256_classic,32);
}
TEST(UTCPABE, cp_abe_two_phase) {
UnitTestCPABETwoPhase<NativePoly>(HEStd_192_classic,6);
}
......@@ -76,6 +76,28 @@ void UnitTestIBE(SecurityLevel level){
EXPECT_EQ(pt->GetElement<Element>(),dt->GetElement<Element>());
}
template <class Element>
void UnitTestIBETwoPhase(SecurityLevel level){
ABEContext<Element> context;
context.GenerateIBEContext(level);
IBEMasterPublicKey<Element> mpk;
IBEMasterSecretKey<Element> msk;
context.Setup(&mpk,&msk);
IBEUserIdentifier<Element> id(context.GenerateRandomElement());
IBESecretKey<Element> sk;
PerturbationVector<Element> pv;
context.KeyGenOfflinePhase(msk,pv);
context.KeyGenOnlinePhase(msk,mpk,id,pv,&sk);
std::vector<int64_t> vectorOfInts = { 1,0,0,1,1,0,1,0, 1, 0};
Plaintext pt = context.MakeCoefPackedPlaintext(vectorOfInts);
IBECiphertext<Element> ct;
context.Encrypt(mpk,id,pt,&ct);
Plaintext dt = context.Decrypt(sk,ct);
EXPECT_EQ(pt->GetElement<Element>(),dt->GetElement<Element>());
}
//Tests for 128 bit security
TEST(UTIBE, ibe_128_poly) {
UnitTestIBE<Poly>(HEStd_128_classic);
......@@ -97,4 +119,8 @@ TEST(UTIBE, ibe_256_poly) {
TEST(UTIBE, ibe_256_native) {
UnitTestIBE<NativePoly>(HEStd_256_classic);
}
//Test for two-phase key generation
TEST(UTIBE, ibe_two_phase) {
UnitTestIBETwoPhase<NativePoly>(HEStd_192_classic);
}
\ No newline at end of file
This diff is collapsed.
......@@ -286,6 +286,15 @@ public:
}
/**
* @brief returns the element's original modulus, derived from Poly
* @return returns the modulus of the element.
*/
const Integer &GetOriginalModulus() const {
return m_params->GetOriginalModulus();
}
/**
* @brief returns the element's root of unity.
* @return the element's root of unity.
*/
......@@ -306,12 +315,29 @@ public:
return m_vectors[0].GetValues().GetLength();
}
/**
* @brief Get interpolated value of elements at all tower index i.
* Note this operation is computationally intense.
* @return interpolated value at index i.
*/
Integer& at(usint i) ;
const Integer& at(usint i) const;
/**
* @brief Get method of individual compoment elements.
*
* @param i index of component element to be returned.
* @returns a reference to the component element at index i.
* @brief Get interpolated value of element at index i.
* Note this operation is computationally intense.
* @return interpolated value at index i.
*/
Integer& operator[](usint i);
const Integer& operator[](usint i) const;
/**
* @brief Get method of individual tower of elements.
* Note this behavior is different than poly
* @param i index of tower to be returned.
* @returns a reference to the returned tower
*/
const PolyType &GetElementAtIndex(usint i) const;
......@@ -415,6 +441,15 @@ public:
DCRTPolyType& operator=(std::vector<int32_t> rhs);
/**
* @brief Initalizer list
*
* @param &rhs the list to set the PolyImpl to.
* @return the resulting PolyImpl.
*/
DCRTPolyType& operator=(std::initializer_list<std::string> rhs);
/**
* @brief Unary minus on a element.
* @return additive inverse of the an element.
*/
......@@ -714,6 +749,16 @@ public:
PolyType DecryptionCRTInterpolate(PlaintextModulus ptm) const;
/**
* @brief Interpolates the DCRTPoly to an Poly based on the Chinese Remainder Transform Interpolation, only at element index i, all other elements are zero.
* and then returns a Poly with that single element
*
* @return the interpolated ring element as a Poly object.
*/
PolyLargeType CRTInterpolateIndex(usint i) const;
/**
* @brief Computes Round(p/q*x) mod p as [\sum_i x_i*alpha_i + Round(\sum_i x_i*beta_i)] mod p for fast rounding in RNS;
* used in the decryption of BFVrns
......@@ -953,6 +998,7 @@ public:
* @return a resulting concatenated output stream
*/
friend inline std::ostream& operator<<(std::ostream& os, const DCRTPolyType& vec) {
//os << (vec.m_format == EVALUATION ? "EVAL: " : "COEF: ");
for( usint i=0; i<vec.GetAllElements().size(); i++ ) {
if( i != 0 ) os << std::endl;
os << i << ": ";
......@@ -1040,6 +1086,7 @@ public:
}
private:
shared_ptr<Params> m_params;
// array of vectors used for double-CRT presentation
......@@ -1047,7 +1094,7 @@ private:
// Either Format::EVALUATION (0) or Format::COEFFICIENT (1)
Format m_format;
};
};
} // namespace lbcrypto ends
namespace lbcrypto
......
......@@ -452,13 +452,14 @@ namespace lbcrypto {
template <class Element>
shared_ptr<Matrix<int64_t>> LatticeGaussSampUtility<Element>::ZSampleF(const Field2n &f, const Field2n &c,
const typename Element::DggType &dgg, size_t n) {
if (f.Size() == 1)
{
{
shared_ptr<Matrix<int64_t>> p(new Matrix<int64_t>([]() { return 0; }, 1, 1));
(*p)(0, 0) = dgg.GenerateIntegerKarney(c[0].real(), sqrt(f[0].real()));
return p;
}
else {
Field2n f0 = f.ExtractEven();
......@@ -476,9 +477,7 @@ namespace lbcrypto {
cPermuted(0, 0) = c.ExtractEven();
cPermuted(1, 0) = c.ExtractOdd();
LatticeGaussSampUtility<Element>::ZSampleSigma2x2(f0, f1, f0, cPermuted, dgg, qZVector);
InversePermute(qZVector);
return qZVector;
......
......@@ -84,6 +84,8 @@ public:
*/
template<typename P>
static shared_ptr<P> GenElemParams(ElementOrder o) {
bool dbg_flag(false);
DEBUG("in GenElemParams(ElementOrder o)");
return shared_ptr<P>( new P(DefaultSet[o].m, typename P::Integer(DefaultSet[o].q), typename P::Integer(DefaultSet[o].ru)) );
}
......@@ -95,6 +97,9 @@ public:
*/
template<typename P>
static shared_ptr<P> GenElemParams(usint m) {
bool dbg_flag(false);
DEBUG("in GenElemParams(usint m)");
size_t sIdx = GetNearestIndex(m);
return shared_ptr<P>( new P(DefaultSet[sIdx].m, typename P::Integer(DefaultSet[sIdx].q), typename P::Integer(DefaultSet[sIdx].ru)) );
......@@ -109,7 +114,10 @@ public:
* @return new params
*/
template<typename P>
static shared_ptr<P> GenElemParams(usint m, usint bits, usint towersize = 0) {
static shared_ptr<P> GenElemParams(usint m, usint bits, usint towersize = 1) {
bool dbg_flag(false);
DEBUG("in GenElemParams(usint m, usint bits, usint towers)");
typename P::Integer q = FirstPrime<typename P::Integer>(bits,m);
typename P::Integer ru = RootOfUnity<typename P::Integer>(m, q);
return shared_ptr<P>( new P(m, q, ru) );
......@@ -125,14 +133,47 @@ public:
*/
template<typename P>
static shared_ptr<P> GenElemParams(usint m, const typename P::Integer& ctModulus, const typename P::Integer& rootUnity) {
bool dbg_flag(false);
DEBUG("in GenElemParams(usint m, const typename P::Integer etc)");
return shared_ptr<P>( new P(m, ctModulus, rootUnity) );
}
};
template<>
inline shared_ptr<ILDCRTParams<BigInteger>>
ElemParamFactory::GenElemParams<ILDCRTParams<BigInteger>>(usint m, usint bits, usint towersize) {
return GenerateDCRTParams<BigInteger>(m, towersize, bits);
inline shared_ptr<ILDCRTParams<M2Integer>>
ElemParamFactory::GenElemParams<ILDCRTParams<M2Integer>>(usint m, usint bits, usint towersize) {
bool dbg_flag(false);
DEBUG("in GenElemParams<ILDCRTParams<M2Integer>>(usint m, usint bits, usint towersize)");
DEBUGEXP(m);
DEBUGEXP(bits);
DEBUGEXP(towersize);
return GenerateDCRTParams<M2Integer>(m, towersize, bits);
}
template<>
inline shared_ptr<ILDCRTParams<M4Integer>>
ElemParamFactory::GenElemParams<ILDCRTParams<M4Integer>>(usint m, usint bits, usint towersize) {
bool dbg_flag(false);
DEBUG("in GenElemParams<ILDCRTParams<M4Integer>>(usint m, usint bits, usint towersize)");
DEBUGEXP(m);
DEBUGEXP(bits);
DEBUGEXP(towersize);
return GenerateDCRTParams<M4Integer>(m, towersize, bits);
}
template<>
inline shared_ptr<ILDCRTParams<M6Integer>>
ElemParamFactory::GenElemParams<ILDCRTParams<M6Integer>>(usint m, usint bits, usint towersize) {
bool dbg_flag(false);
DEBUG("in GenElemParams<ILDCRTParams<M6Integer>>(usint m, usint bits, usint towersize)");
DEBUGEXP(m);
DEBUGEXP(bits);
DEBUGEXP(towersize);
return GenerateDCRTParams<M6Integer>(m, towersize, bits);
}
} /* namespace lbcrypto */
......
......@@ -48,17 +48,19 @@ template<typename IntType>
class ILDCRTParams : public ElemParams<IntType>
{
public:
typedef IntType Integer;
static const usint DEFAULT_NBITS = 20;
typedef IntType Integer;
using ILNativeParams = ILParamsImpl<NativeInteger>;
/**
* @brief Constructor with basic parameter set.
*
* q is selected as FirstPrime(bits, order)
* @param order the order of the ciphertext.
* @param depth is the modulus for the entire tower.
* @param bits is the number of bits of each moduli.
* @param depth is the size of the tower.
* @param bits is the number of bits of each tower's moduli.
*/
ILDCRTParams(usint order=0, usint depth=1, usint bits=20);
ILDCRTParams(usint order=0, usint depth=1, usint bits= DEFAULT_NBITS);
/**
* @brief Constructor with basic parameters
......@@ -69,7 +71,47 @@ public:
*/
ILDCRTParams(const usint cyclotomic_order, const IntType &modulus, const IntType& rootOfUnity)
: ElemParams<IntType>(cyclotomic_order, modulus, 0, 0, 0) {
// note this does not create a tower of native params
// NOTE parms generation uses this constructor to make an empty parms that it will later
// populate during the gen process. For that special case... we don't populate, and
// we just return
if( cyclotomic_order == 0 )
return;
bool dbg_flag(false);
DEBUG("in ILDCRTParams(const usint cyclotomic_order, const IntType &modulus, const IntType& rootOfUnity");
DEBUGEXP(cyclotomic_order);
DEBUGEXP(modulus);
DEBUGEXP(rootOfUnity);
usint numOfTower = 1;
std::vector<NativeInteger> moduli;
std::vector<NativeInteger> rootsOfUnity;
NativeInteger q = FirstPrime<NativeInteger>(DEFAULT_NBITS, cyclotomic_order);
IntType compositeModulus(1);
for(;;) {
moduli.push_back(q);
rootsOfUnity.push_back(RootOfUnity(cyclotomic_order, q));
compositeModulus = compositeModulus * IntType(q.ConvertToInt());
if( compositeModulus >= modulus )
break;
q = NextPrime(q, cyclotomic_order);
numOfTower++;
}
originalModulus = modulus;
DEBUGEXP(compositeModulus);
DEBUGEXP(moduli);
DEBUGEXP(rootsOfUnity);
DEBUGEXP(m_parms.size());
for (size_t i = 0; i < moduli.size(); i++) {
m_parms.push_back(std::shared_ptr<ILNativeParams>(new ILNativeParams(cyclotomic_order, moduli[i], rootsOfUnity[i])));
}
RecalculateModulus();
DEBUGEXP(m_parms.size());
}
/**
......@@ -83,8 +125,9 @@ public:
*/
ILDCRTParams(const usint cyclotomic_order,
const std::vector<NativeInteger> &moduli, const std::vector<NativeInteger>& rootsOfUnity,
const std::vector<NativeInteger> &moduliBig = {}, const std::vector<NativeInteger>& rootsOfUnityBig = {})
const std::vector<NativeInteger> &moduliBig = {}, const std::vector<NativeInteger>& rootsOfUnityBig = {}, const IntType &inputOriginalModulus = IntType(0))
: ElemParams<IntType>(cyclotomic_order, 0, 0, 0, 0) {
this->originalModulus = inputOriginalModulus;
if( moduli.size() != rootsOfUnity.size() )
throw std::logic_error("sizes of moduli and roots of unity do not match");
......@@ -110,9 +153,11 @@ public:
* @param cyclotomic_order the order of the ciphertext
* @param &moduli is the tower of moduli
*/
ILDCRTParams(const usint cyclotomic_order, const std::vector<NativeInteger> &moduli)
ILDCRTParams(const usint cyclotomic_order, const std::vector<NativeInteger> &moduli, const IntType &inputOriginalModulus = IntType(0) )
: ElemParams<IntType>(cyclotomic_order, 0, 0, 0, 0) {
for( size_t i=0; i<moduli.size(); i++ ) {
this->originalModulus = inputOriginalModulus;
for( size_t i=0; i<moduli.size(); i++ ) {
m_parms.push_back( std::shared_ptr<ILNativeParams>( new ILNativeParams(cyclotomic_order, moduli[i], 0, 0, 0) ) );
}
RecalculateModulus();
......@@ -124,8 +169,10 @@ public:
* @param parms the componet parameters.
* @return
*/
ILDCRTParams(const usint cyclotomic_order, std::vector<std::shared_ptr<ILNativeParams>>& parms)
ILDCRTParams(const usint cyclotomic_order, std::vector<std::shared_ptr<ILNativeParams>>& parms, const IntType &inputOriginalModulus = IntType(0))
: ElemParams<IntType>(cyclotomic_order, 0, 0, 0, 0), m_parms(parms) {
this->originalModulus = inputOriginalModulus;
RecalculateModulus();
}
......@@ -138,6 +185,8 @@ public:
*/
const ILDCRTParams& operator=(const ILDCRTParams &rhs) {
ElemParams<IntType>::operator=(rhs);
originalModulus = rhs.originalModulus;
m_parms = rhs.m_parms;
return *this;
......@@ -153,7 +202,21 @@ public:
}
/**
* @brief Getter method for the comp19onent parameters of a specific index.
* @brief Simple getter method for the original modulus, not the ciphertex modulus.
* @return The original modulus, not the big ciphertext modulus.
*/
const IntType &GetOriginalModulus() const {
return originalModulus;
}
/**
* @brief Simple setter method for the original modulus, not the ciphertex modulus.
* @return void
*/
void SetOriginalModulus( const IntType& inputOriginalModulus ) {
originalModulus = inputOriginalModulus;
}
/**
* @brief Getter method for the component parameters of a specific index.
* @param i the index of the parameters to return. Note this this call is unguarded if the index is out of bounds.
* @return the parameters at index i.
*/
......@@ -207,6 +270,9 @@ public:
return false;
}
if (originalModulus != dcrtParams->originalModulus)
return false;
return true;
}
......@@ -249,7 +315,15 @@ private:
private:
// array of smaller ILParams
std::vector<std::shared_ptr<ILNativeParams>> m_parms;
std::vector<std::shared_ptr<ILNativeParams>> m_parms;
//original modulus when being constructed from a Poly or when
//ctor is passed that parameter
// note orignalModulus will be <= composite modules
// i.e. \Prod_i=0^k-1 m_params[i]->GetModulus()
// note not using ElemParams::ciphertextModulus due to object stripping
Integer originalModulus;
};
......
......@@ -531,7 +531,10 @@ template<typename VecType>
PolyImpl<VecType> PolyImpl<VecType>::Plus(const Integer &element) const
{
PolyImpl<VecType> tmp = CloneParametersOnly();
tmp.SetValues( GetValues().ModAddAtIndex(0, element), this->m_format );
if (this->m_format == COEFFICIENT)
tmp.SetValues( GetValues().ModAddAtIndex(0, element), this->m_format );
else
tmp.SetValues( GetValues().ModAdd(element), this->m_format );
return std::move( tmp );
}
......@@ -615,7 +618,7 @@ PolyImpl<VecType> PolyImpl<VecType>::Times(const PolyImpl &element) const
template<typename VecType>
const PolyImpl<VecType>& PolyImpl<VecType>::operator+=(const PolyImpl &element)
{
bool dbg_flag = true;
bool dbg_flag = false;
if (!(*this->m_params == *element.m_params)){
DEBUGEXP(*this->m_params);
DEBUGEXP(*element.m_params);
......
......@@ -183,9 +183,7 @@ namespace lbcrypto {
NativeInteger qu = params->GetParams()[u]->GetModulus();
Matrix<int64_t> digits([]() { return 0; }, kRes, n);
LatticeGaussSampUtility<NativePoly>::GaussSampGqArbBase(perturbedSyndrome.GetElementAtIndex(u), c, kRes, qu, base, dgg, &digits);
for(size_t p=0; p<kRes; p++) {
for(size_t j=0; j<n; j++) {
zHatBBI(p + u*kRes,j) = digits(p,j);
......
......@@ -227,19 +227,19 @@ public:
// for distribution parameters up to 3e5 (experimentally found threshold) use the Peikert's inversion method
// otherwise, use Karney's method
if (sigmaLarge > KARNEY_THRESHOLD) {
//Karney rejection sampling method
for (size_t i = 0; i < n * k; i++) {
p2ZVector(i, 0) = dgg.GenerateIntegerKarney(0, sigmaLarge);
}
}
else
{
//Peikert's inversion sampling method
std::shared_ptr<int32_t> dggVector = dggLargeSigma.GenerateIntVector(n*k);
for (size_t i = 0; i < n * k; i++) {
p2ZVector(i, 0) = (dggVector.get())[i];
}
......@@ -281,7 +281,6 @@ public:
shared_ptr<Matrix<int64_t>> p1ZVector(new Matrix<int64_t>([]() { return 0; }, n * 2, 1));
DEBUG("z1i: "<<TOC(t1));
TIC(t1);
LatticeGaussSampUtility<Element>::ZSampleSigma2x2(a, b, d, c, dgg, p1ZVector);
DEBUG("z1j1: "<<TOC(t1)); //14
TIC(t1);
......
......@@ -179,6 +179,7 @@ public:
os<< ptr_obj.m_data[i];
os << ((i == (len-1))?"]":" ");
}
os<<" modulus: "<<ptr_obj.m_modulus;
return os;
}
......
......@@ -237,6 +237,7 @@ public:
friend std::ostream& operator<<(std::ostream& os,
const mubintvec &ptr_obj)
{
#if 0 //old way
os<<std::endl;
for(usint i=0;i<ptr_obj.m_data.size();i++){
os<<ptr_obj.m_data[i] <<std::endl;
......@@ -244,7 +245,16 @@ public:
os<<"modulus: "<<ptr_obj.m_modulus;
os <<std::endl;
#else
auto len = ptr_obj.m_data.size();
os<<"[";
for(usint i=0;i<len;i++){
os<< ptr_obj.m_data[i];
os << ((i == (len-1))?"]":" ");
}
os<<" modulus: "<<ptr_obj.m_modulus;
#endif
return os;
}
......
......@@ -126,6 +126,7 @@ public:
os<< ptr_obj.at(i);
os << ((i == (len-1))?"]":" ");
}
os<<" modulus: "<<ptr_obj.m_modulus;
return os;
}
......
......@@ -246,6 +246,7 @@ class NativeVector : public lbcrypto::BigVectorInterface<NativeVector<IntegerTyp
os<< ptr_obj.m_data[i];
os << ((i == (len-1))?"]":" ");
}
os<<" modulus: "<<ptr_obj.m_modulus;
return os;
}
......
......@@ -284,9 +284,79 @@ namespace lbcrypto {
DEBUG("result = " << result.ToString());
if (result == IntType(1)) {
DEBUG("LOOP?");
return RootOfUnity(m, modulo);
result = RootOfUnity(m, modulo);
}
return result;
/*
* At this point, result contains a primitive root of unity. However,
* we want to return the minimum root of unity, to avoid different
* crypto contexts having different roots of unity for the same
* cyclotomic order and moduli. Therefore, we are going to cycle over
* all primitive roots of unity and select the smallest one (minRU).
*
* To cycle over all primitive roots of unity, we raise the root of
* unity in result to all the powers that are co-prime to the
* cyclotomic order. In power-of-two cyclotomics, this will be the
* set of all odd powers, but here we use a more general routine
* to support arbitrary cyclotomics.
*
*/
IntType mu = ComputeMu<IntType>(modulo);
IntType x(1);
x.ModBarrettMulInPlace(result, modulo, mu);
IntType minRU(x);
IntType curPowIdx(1);
std::vector<IntType> coprimes = GetTotientList<IntType>(m);
for (usint i=0; i<coprimes.size(); i++) {
auto nextPowIdx = coprimes[i];
IntType diffPow(nextPowIdx - curPowIdx);
for (IntType j(0); j<diffPow; j+=IntType(1)) {
x.ModBarrettMulInPlace(result, modulo, mu);
}
if (x < minRU && x != IntType(1)) {
minRU = x;
}
curPowIdx = nextPowIdx;
}
return minRU;
}
template<typename IntType>
......
......@@ -247,7 +247,7 @@ namespace lbcrypto {
* @param nBits the number of bits needed to be in q.
* @param m the the ring parameter.
*
* @return the next prime modulus.
* @return the first prime modulus.
*/
template<typename IntType>
IntType FirstPrime(uint64_t nBits, uint64_t m);
......
......@@ -345,7 +345,8 @@ void ChineseRemainderTransformFTT<VecType>::PreCompute(const IntType& rootOfUnit
rootOfUnityTableCheck = &m_rootOfUnityTableByModulus[modulus];
//Precomputes twiddle factor omega and FTT parameter phi for Forward Transform
if (rootOfUnityTableCheck->GetLength() == 0) {
if (rootOfUnityTableCheck->GetLength() == 0 ||
m_rootOfUnityTableByModulus[modulus][0] != rootOfUnity ) {
#pragma omp critical
{
VecType Table(CycloOrder / 2, modulus);
......@@ -433,7 +434,8 @@ void ChineseRemainderTransformFTT<VecType>::PreCompute(std::vector<IntType> &roo
//Precompute the Barrett mu parameter
IntType mu = ComputeMu<IntType>(currentMod);
if (m_rootOfUnityTableByModulus[moduliiChain[i]].GetLength() != 0)
if (m_rootOfUnityTableByModulus[moduliiChain[i]].GetLength() != 0 &&
m_rootOfUnityTableByModulus[moduliiChain[i]][0] == currentRoot)
continue;
IntType x(1);
......
......@@ -52,7 +52,11 @@ using namespace lbcrypto;
*/
template<typename I>
inline shared_ptr<ILDCRTParams<I>> GenerateDCRTParams(usint m, usint numOfTower, usint pbits) {
bool dbg_flag(false);
DEBUG("in GenerateDCRTParams");
DEBUGEXP(m);
DEBUGEXP(numOfTower);
DEBUGEXP(pbits);
if( numOfTower == 0 )
throw std::logic_error("Can't make parms with numOfTower == 0 ");
......@@ -63,10 +67,13 @@ inline shared_ptr<ILDCRTParams<I>> GenerateDCRTParams(usint m, usint numOfTower,
I modulus(1);
usint j = 0;
DEBUGEXP(q);
for(;;) {
moduli[j] = q;
rootsOfUnity[j] = RootOfUnity(m, q);
modulus = modulus * I(q.ConvertToInt());
DEBUG("j "<<j<<" modulus "<<q<<" rou "<<rootsOfUnity[j]);
if( ++j == numOfTower )
break;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -92,7 +92,7 @@ void basic_il2n_math(const string& msg) {
I.SetFormat(EVALUATION);
EXPECT_EQ(n, I*n) << msg;
n -= n;
n = n - n;
EXPECT_EQ(n, z) << msg;
}
......@@ -106,7 +106,7 @@ void basic_int_math(const string& msg) {
Matrix<T> n = Matrix<T>(T::Allocator, 2, 2).Ones();
Matrix<T> I = Matrix<T>(T::Allocator, 2, 2).Identity();
EXPECT_EQ(n, I*n) << msg;
n -= n;
n = n - n;
EXPECT_EQ(n, z) << msg;
}
......@@ -137,7 +137,7 @@ void basic_intvec_math(const string& msg) {
DEBUG("I mod "<<I(0,0).GetModulus().ToString());
EXPECT_EQ(n, I*n) << msg;
DEBUG("6");
n -= n;
n = n - n;
DEBUG("7");
EXPECT_EQ(n, z) << msg;
DEBUG("8");
......
This diff is collapsed.
......@@ -676,7 +676,7 @@ NativeInteger CRTInterpolate(const std::vector<Plaintext> &crtVector) {
else
value = NativeInteger(crtVector[i]->GetPackedValue()[0]);
result += ((value*qInverse[i]).Mod(q[i])*Q / q[i]).Mod(Q);
result += ((value*qInverse[i]).Mod(q[i])*(Q / q[i])).Mod(Q);
}
return result.Mod(Q);
......
......@@ -709,7 +709,7 @@ NativeInteger CRTInterpolate(const std::vector<Plaintext> &crtVector) {
else
value = NativeInteger(crtVector[i]->GetPackedValue()[0]);
result += ((value*qInverse[i]).Mod(q[i])*Q / q[i]).Mod(Q);
result += ((value*qInverse[i]).Mod(q[i])*(Q / q[i])).Mod(Q);