Program Listing for File run-bfvrns-behz.cpp
↰ Return to documentation for file (pke/extras/run-bfvrns-behz.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.
//==================================================================================
/*
BFV RNS testing programs
*/
#define PROFILE
#include <iostream>
#include "openfhe.h"
#include "utils/parallel.h"
typedef std::numeric_limits<double> dbl;
using namespace lbcrypto;
// Poly tests
void SHERun();
int main() {
SHERun();
// cin.get();
return 0;
}
void SHERun() {
std::cerr << "Running with " << ParallelControls::GetNumProcs() << " processors and "
<< ParallelControls().GetNumThreads() << " threads. " << std::endl;
std::cout << "\n===========BENCHMARKING FOR BFVRNS-B===============: " << std::endl;
std::cout << "\nThis code demonstrates the use of the BFV-RNS scheme for "
"basic homomorphic encryption operations. "
<< std::endl;
std::cout << "This code shows how to auto-generate parameters during run-time "
"based on desired plaintext moduli and security levels. "
<< std::endl;
std::cout << "In this demonstration we use three input plaintext and show "
"how to both add them together and multiply them together. "
<< std::endl;
size_t count = 100;
CCParams<CryptoContextBFVRNS> parameters;
parameters.SetPlaintextModulus(2);
parameters.SetMultiplicativeDepth(5);
parameters.SetMaxRelinSkDeg(3);
parameters.SetScalingModSize(55);
parameters.SetMultiplicationTechnique(BEHZ);
CryptoContext<DCRTPoly> cryptoContext = GenCryptoContext(parameters);
// enable features that you wish to use
cryptoContext->Enable(PKE);
cryptoContext->Enable(KEYSWITCH);
cryptoContext->Enable(LEVELEDSHE);
std::cout << "p = " << cryptoContext->GetCryptoParameters()->GetPlaintextModulus() << std::endl;
std::cout << "n = " << cryptoContext->GetCryptoParameters()->GetElementParams()->GetCyclotomicOrder() / 2
<< std::endl;
std::cout << "log2 q = " << cryptoContext->GetCryptoParameters()->GetElementParams()->GetModulus().GetMSB()
<< std::endl;
// Initialize Public Key Containers
KeyPair<DCRTPoly> keyPair;
// Perform Key Generation Operation
std::cout << "Running key generation (used for source data)..." << std::endl;
double start = currentDateTime();
keyPair = cryptoContext->KeyGen();
double finish = currentDateTime();
double diff = finish - start;
std::cout << "Key generation time: "
<< "\t" << diff << " ms" << std::endl;
if (!keyPair.good()) {
std::cout << "Key generation failed!" << std::endl;
exit(1);
}
cryptoContext->EvalMultKeyGen(keyPair.secretKey);
// Encode source data
std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
Plaintext plaintext1 = cryptoContext->MakeCoefPackedPlaintext(vectorOfInts1);
std::vector<int64_t> vectorOfInts2 = {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0};
Plaintext plaintext2 = cryptoContext->MakeCoefPackedPlaintext(vectorOfInts2);
double timeDecrypt(0.0);
double timeMult(0.0);
double timeRelin(0.0);
for (size_t k = 0; k < count; k++) {
TimeVar tDecrypt;
TimeVar tMult;
TimeVar tRelin;
auto ciphertext1 = cryptoContext->Encrypt(keyPair.publicKey, plaintext1);
auto ciphertext2 = cryptoContext->Encrypt(keyPair.publicKey, plaintext2);
Plaintext plaintextDec1;
cryptoContext->Decrypt(keyPair.secretKey, ciphertext1, &plaintextDec1);
Plaintext plaintextDec2;
TIC(tDecrypt);
cryptoContext->Decrypt(keyPair.secretKey, ciphertext2, &plaintextDec2);
timeDecrypt += TOC_US(tDecrypt);
TIC(tMult);
auto ciphertextMul = cryptoContext->EvalMultNoRelin(ciphertext1, ciphertext2);
timeMult += TOC_US(tMult);
TIC(tRelin);
auto ciphertextMulRelin = cryptoContext->EvalMult(ciphertext1, ciphertext2);
timeRelin += TOC_US(tRelin);
}
std::cout << "Average decryption time:\t" << timeDecrypt / (1000 * count) << " ms" << std::endl;
std::cout << "Average multiplication time:\t" << timeMult / (1000 * count) << " ms" << std::endl;
std::cout << "Average relinearization time:\t" << (timeRelin - timeMult) / (1000 * count) << " ms" << std::endl;
std::cout << "Average multiplication + relinearization time:\t" << timeRelin / (1000 * count) << " ms" << std::endl;
}