Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composite Prime Moduli Sampling and Scaling Factor Calculations (#910 phase 2) #929

Open
wants to merge 23 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3ed5909
Initial commit: adding composite scaling parameters and scaling tech …
fdiasmor Dec 12, 2024
fb50d79
Initial commit: adding composite scaling parameters and scaling tech …
fdiasmor Dec 12, 2024
d3c1a58
Composite prime generation and adaptive scaling factors.
fdiasmor Dec 16, 2024
e397a73
Propagating composite degree to mod reduce calls.
fdiasmor Dec 17, 2024
3bf393a
Handling overflow for scaling factors over 64 bits on composite scali…
fdiasmor Dec 17, 2024
51db3ca
Bug fix of overflow handling for d > 2 and sc > 64.
fdiasmor Dec 18, 2024
44b206b
Update impl of Rescale and Mod/LevelReduce methods with composite deg…
fdiasmor Dec 18, 2024
3d2c220
Minor bug fix: else case missing.
fdiasmor Dec 19, 2024
a9c9978
Update EvalPoly functions to use composite degree.
fdiasmor Dec 19, 2024
c03c8f9
Update Compress function to raise error.
fdiasmor Dec 19, 2024
470cd11
Update/Add new composite scaling examples.
fdiasmor Dec 19, 2024
6369eaa
Recalculate sizeP and update EstimateLogP interface.
fdiasmor Dec 19, 2024
5d54a9f
Update composite-prime generation function.
fdiasmor Dec 31, 2024
a5a2b9c
Remove comments from prime gen function.
fdiasmor Jan 3, 2025
9a7ad26
Update composite scaling unittests and fix unittest runtime issue.
fdiasmor Dec 25, 2024
c8c76a8
Some review changes.
fdiasmor Jan 8, 2025
4b721d9
Update composite scaling unittests and fix unittest runtime issue.
fdiasmor Dec 25, 2024
cf685de
Disable composite scaling set methods for non-CKKS schemes.
fdiasmor Jan 9, 2025
a5a443a
Move COMPOSITESCALING support error handling.
fdiasmor Jan 10, 2025
b14472d
Disable composite scaling set methods for non-CKKS schemes.
fdiasmor Jan 9, 2025
6dd35c0
Removing additional constructor that accepts composite scaling parame…
fdiasmor Jan 10, 2025
e9cdffa
Merge/rebase review changes from (#928).
fdiasmor Jan 18, 2025
80fe03f
Merge branch 'dev' into 910-composite-prime-gen
fdiasmor Jan 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions src/pke/examples/function-evaluation-composite-scaling.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
//==================================================================================
// BSD 2-Clause License
//
// Copyright (c) 2014-2022, NJIT, Duality Technologies Inc. and other contributors
//
// All rights reserved.
//
// Author TPOC: [email protected]
//
// 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.
//==================================================================================

/*
Example of evaluating arbitrary smooth functions with the Chebyshev approximation using CKKS.
*/

#include "openfhe.h"

#include <iostream>
#include <vector>

using namespace lbcrypto;

void EvalLogisticExample();

void EvalFunctionExample();

int main(int argc, char* argv[]) {
EvalLogisticExample();
EvalFunctionExample();
return 0;
}

// In this example, we evaluate the logistic function 1 / (1 + exp(-x)) on an input of doubles
void EvalLogisticExample() {
std::cout << "--------------------------------- EVAL LOGISTIC FUNCTION ---------------------------------"
<< std::endl;
CCParams<CryptoContextCKKSRNS> parameters;

// We set a smaller ring dimension to improve performance for this example.
// In production environments, the security level should be set to
// HEStd_128_classic, HEStd_192_classic, or HEStd_256_classic for 128-bit, 192-bit,
// or 256-bit security, respectively.
parameters.SetSecurityLevel(HEStd_NotSet);
parameters.SetRingDim(1 << 10);
#if NATIVEINT == 128
usint scalingModSize = 78;
usint firstModSize = 89;
#else
usint scalingModSize = 50;
usint firstModSize = 60;
#endif
parameters.SetScalingModSize(scalingModSize);
parameters.SetFirstModSize(firstModSize);
parameters.SetScalingTechnique(COMPOSITESCALINGAUTO);
parameters.SetRegisterWordSize(32);

// Choosing a higher degree yields better precision, but a longer runtime.
uint32_t polyDegree = 16;

// The multiplicative depth depends on the polynomial degree.
// See the FUNCTION_EVALUATION.md file for a table mapping polynomial degrees to multiplicative depths.
uint32_t multDepth = 6;

parameters.SetMultiplicativeDepth(multDepth);
CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
cc->Enable(PKE);
cc->Enable(KEYSWITCH);
cc->Enable(LEVELEDSHE);
// We need to enable Advanced SHE to use the Chebyshev approximation.
cc->Enable(ADVANCEDSHE);

auto keyPair = cc->KeyGen();
// We need to generate mult keys to run Chebyshev approximations.
cc->EvalMultKeyGen(keyPair.secretKey);

std::vector<std::complex<double>> input{-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0};
size_t encodedLength = input.size();
Plaintext plaintext = cc->MakeCKKSPackedPlaintext(input);
auto ciphertext = cc->Encrypt(keyPair.publicKey, plaintext);

double lowerBound = -5;
double upperBound = 5;
auto result = cc->EvalLogistic(ciphertext, lowerBound, upperBound, polyDegree);

Plaintext plaintextDec;
cc->Decrypt(keyPair.secretKey, result, &plaintextDec);
plaintextDec->SetLength(encodedLength);

std::vector<std::complex<double>> expectedOutput(
{0.0179885, 0.0474289, 0.119205, 0.268936, 0.5, 0.731064, 0.880795, 0.952571, 0.982011});
std::cout << "Expected output\n\t" << expectedOutput << std::endl;

std::vector<std::complex<double>> finalResult = plaintextDec->GetCKKSPackedValue();
std::cout << "Actual output\n\t" << finalResult << std::endl << std::endl;
}

void EvalFunctionExample() {
std::cout << "--------------------------------- EVAL SQUARE ROOT FUNCTION ---------------------------------"
<< std::endl;
CCParams<CryptoContextCKKSRNS> parameters;

// We set a smaller ring dimension to improve performance for this example.
// In production environments, the security level should be set to
// HEStd_128_classic, HEStd_192_classic, or HEStd_256_classic for 128-bit, 192-bit,
// or 256-bit security, respectively.
parameters.SetSecurityLevel(HEStd_NotSet);
parameters.SetRingDim(1 << 10);
#if NATIVEINT == 128
usint scalingModSize = 78;
usint firstModSize = 89;
#else
usint scalingModSize = 50;
usint firstModSize = 60;
#endif
parameters.SetScalingModSize(scalingModSize);
parameters.SetFirstModSize(firstModSize);
parameters.SetScalingTechnique(COMPOSITESCALINGAUTO);
parameters.SetRegisterWordSize(32);

// Choosing a higher degree yields better precision, but a longer runtime.
uint32_t polyDegree = 50;

// The multiplicative depth depends on the polynomial degree.
// See the FUNCTION_EVALUATION.md file for a table mapping polynomial degrees to multiplicative depths.
uint32_t multDepth = 7;

parameters.SetMultiplicativeDepth(multDepth);
CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
cc->Enable(PKE);
cc->Enable(KEYSWITCH);
cc->Enable(LEVELEDSHE);
// We need to enable Advanced SHE to use the Chebyshev approximation.
cc->Enable(ADVANCEDSHE);

auto keyPair = cc->KeyGen();
// We need to generate mult keys to run Chebyshev approximations.
cc->EvalMultKeyGen(keyPair.secretKey);

std::vector<std::complex<double>> input{1, 2, 3, 4, 5, 6, 7, 8, 9};
size_t encodedLength = input.size();
Plaintext plaintext = cc->MakeCKKSPackedPlaintext(input);
auto ciphertext = cc->Encrypt(keyPair.publicKey, plaintext);

double lowerBound = 0;
double upperBound = 10;

// We can input any lambda function, which inputs a double and returns a double.
auto result = cc->EvalChebyshevFunction([](double x) -> double { return std::sqrt(x); }, ciphertext, lowerBound,
upperBound, polyDegree);

Plaintext plaintextDec;
cc->Decrypt(keyPair.secretKey, result, &plaintextDec);
plaintextDec->SetLength(encodedLength);

std::vector<std::complex<double>> expectedOutput(
{1, 1.414213, 1.732050, 2, 2.236067, 2.449489, 2.645751, 2.828427, 3});
std::cout << "Expected output\n\t" << expectedOutput << std::endl;

std::vector<std::complex<double>> finalResult = plaintextDec->GetCKKSPackedValue();
std::cout << "Actual output\n\t" << finalResult << std::endl << std::endl;
}
125 changes: 125 additions & 0 deletions src/pke/examples/linearwsum-evaluation-composite-scaling.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//==================================================================================
// BSD 2-Clause License
//
// Copyright (c) 2014-2022, NJIT, Duality Technologies Inc. and other contributors
//
// All rights reserved.
//
// Author TPOC: [email protected]
//
// 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.
//==================================================================================

/*
Example of polynomial evaluation using CKKS.
*/

#define PROFILE // turns on the reporting of timing results

#include "openfhe.h"

#include <iostream>
#include <vector>

using namespace lbcrypto;

int main(int argc, char* argv[]) {
TimeVar t;

double timeEvalLinearWSum(0.0);

std::cout << "\n======EXAMPLE FOR EVAL LINEAR WEIGHTED SUM========\n" << std::endl;

CCParams<CryptoContextCKKSRNS> parameters;
parameters.SetMultiplicativeDepth(1);
parameters.SetScalingModSize(50);
parameters.SetBatchSize(8);
parameters.SetSecurityLevel(HEStd_NotSet);
parameters.SetRingDim(2048);
parameters.SetScalingTechnique(COMPOSITESCALINGAUTO);
parameters.SetFirstModSize(60);
parameters.SetRegisterWordSize(32);

CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
cc->Enable(PKE);
cc->Enable(KEYSWITCH);
cc->Enable(LEVELEDSHE);
cc->Enable(ADVANCEDSHE);

std::vector<std::vector<std::complex<double>>> input;

input.push_back({0.5, 0.7, 0.9, 0.95, 0.93, 1.3});
input.push_back({1.2, 1.7, -0.9, 0.85, -0.63, 2});
input.push_back({0.5, 0, 1.9, 2.95, -3.93, 3.3});
input.push_back({1.5, 0.7, 1.9, 2.95, -3.78, 3.3});
input.push_back({0.5, 2.7, 1.9, 0.0, -3.43, 1.3});
input.push_back({0.5, 0.7, -1.9, 2.95, 1.96, 0.0});
input.push_back({0.0, 0.0, 1.0, 0.0, 0.0, 0.0});

size_t encodedLength = input.size();

std::vector<double> coefficients({0.15, 0.75, 1.25, 1, 0, 0.5, 0.5});

auto keyPair = cc->KeyGen();

std::cout << "Generating evaluation key for homomorphic multiplication...";
cc->EvalMultKeyGen(keyPair.secretKey);
std::cout << "Completed." << std::endl;

std::vector<ConstCiphertext<DCRTPoly>> ciphertextVec;
for (usint i = 0; i < encodedLength; ++i) {
Plaintext plaintext = cc->MakeCKKSPackedPlaintext(input[i]);
ciphertextVec.push_back(cc->Encrypt(keyPair.publicKey, plaintext));
}

TIC(t);

auto result = cc->EvalLinearWSum(ciphertextVec, coefficients);

timeEvalLinearWSum = TOC(t);

std::vector<std::complex<double>> unencIP;
for (usint i = 0; i < input[0].size(); ++i) {
std::complex<double> x = 0;
for (usint j = 0; j < encodedLength; ++j) {
x += input[j][i] * coefficients[j];
}
unencIP.push_back(x);
}

Plaintext plaintextDec;

cc->Decrypt(keyPair.secretKey, result, &plaintextDec);

plaintextDec->SetLength(encodedLength);

std::cout << std::setprecision(10) << std::endl;

std::cout << "\n Result of evaluating a linear weighted sum with coefficients " << coefficients << " \n";
std::cout << plaintextDec << std::endl;

std::cout << "\n Expected result: " << unencIP << std::endl;

std::cout << "\n Evaluation time: " << timeEvalLinearWSum << " ms" << std::endl;

return 0;
}
Loading