diff --git a/.vscode/settings.json b/.vscode/settings.json index c127f3a71e9a53f61e0cb540d59f3ef28f63bb54..4702363df141b61f83709bfb49de145d31ff70bd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -47,6 +47,8 @@ "streambuf": "cpp", "typeinfo": "cpp", "bit": "cpp", - "chrono": "cpp" + "chrono": "cpp", + "ctime": "cpp", + "ratio": "cpp" } } \ No newline at end of file diff --git a/bin/ciphertext.o b/bin/ciphertext.o index fdf967e0ee407cb913823f950841084e760e809a..4eb4262035b0f6e0f43edc0c096cb331d3b59dd6 100644 Binary files a/bin/ciphertext.o and b/bin/ciphertext.o differ diff --git a/bin/ckks.o b/bin/ckks.o index f7177830de07a577c74798d4d92280441eb81259..c93f7ee3db6f082c7cb6c57ddf374675c8b9ffee 100644 Binary files a/bin/ckks.o and b/bin/ckks.o differ diff --git a/bin/encoder.o b/bin/encoder.o index bcadbac61ceb3d015445657f76d7aa0c56608d2a..90b7bf07128ce858c5729f29d08ed53347b5bf6b 100644 Binary files a/bin/encoder.o and b/bin/encoder.o differ diff --git a/bin/evalkey.o b/bin/evalkey.o index 3e28b2d00d2d83df7a6298c1d4f7e85939e0ad28..cc0f5ba6ca8e3608f4c3a1cf441de988926567d5 100644 Binary files a/bin/evalkey.o and b/bin/evalkey.o differ diff --git a/bin/ntt.o b/bin/ntt.o index 1ade2c809bf9907a892539002ea6f86f45485344..1c5835f63b95da0e851d4c8ecbb8cc26798ccf3d 100644 Binary files a/bin/ntt.o and b/bin/ntt.o differ diff --git a/bin/polynomial.o b/bin/polynomial.o index eab4a4b865234a36882fe3d19864fcbdae6a2188..d7e200b09999cf80452369cba013fc080e75f787 100644 Binary files a/bin/polynomial.o and b/bin/polynomial.o differ diff --git a/bin/pubkey.o b/bin/pubkey.o index 9f076c661993fe6eaf71d983bebb8a22280934f6..9dd5a19a62f020e1c78b076adb02de9d8b16d558 100644 Binary files a/bin/pubkey.o and b/bin/pubkey.o differ diff --git a/bin/seckey.o b/bin/seckey.o index fd6124ac67ea06ef5800f07b7a34639b3b83b710..06f8a9d67f2435ef4f5c990639565cbc8eb843aa 100644 Binary files a/bin/seckey.o and b/bin/seckey.o differ diff --git a/run b/run index 2cfdbf179c1f65eaa41ce8f043fbc8efc5822481..d75f40f1511082efe4456272f3f36ab09a9a4848 100755 Binary files a/run and b/run differ diff --git a/src/ckks.cpp b/src/ckks.cpp index c11832b5a44511be19eca4088126cc7379ef1b7f..08694ff057e175177c915a2c55d05f6edb6b7948 100644 --- a/src/ckks.cpp +++ b/src/ckks.cpp @@ -46,7 +46,17 @@ Polynomial CKKS::fastMult(Polynomial p1, Polynomial p2, int deg, int64_t w){ for(int i=0; i<deg; i++){ mult.push_back(pol1[i] * pol2[i]); } - + + // if(deg == 16){ + // p1.printPol(); + // p2.printPol(); + // (ntt.intt(mult, w)).printPol(); + // // for(int i=0; i<deg; i++){ + // // cout << mult[i] << " "; + // // } + // // cout << endl; + // } + Polynomial out = ntt.intt(mult, w); return out; } @@ -63,7 +73,7 @@ CKKS::CKKS(int N, PubKey _pk, EvalKey _evk, SecKey _sk){ } Polynomial CKKS::genE(int degree, double var){ - double errCoeffs[degree]; + vector<double> errCoeffs(degree); random_device rd; mt19937 gen(rd()); @@ -82,7 +92,7 @@ Polynomial CKKS::genZO(){ double val[3] = {-1.0, 1.0, 0}; discrete_distribution<int> distribution {0.25, 0.25, 0.5}; - double zoCoeffs[deg]; + vector<double> zoCoeffs(deg); for(int i=0; i<deg; i++){ int number = distribution(generator); zoCoeffs[i] = val[number]; @@ -118,25 +128,20 @@ Ciphertext CKKS::mult(Ciphertext ct1, Ciphertext ct2){ Polynomial d3 = (ct1.c1 * ct2.c1).modCoeff(ql); // Relin - Polynomial d3_0 = (d3 * evk.b).scaleRoundCoeff(1.0/1000.0); - Polynomial d3_1 = (d3 * evk.a).scaleRoundCoeff(1.0/1000.0); + Polynomial d3_0 = ((d3 * evk.b).scaleRoundCoeff(1.0/1000.0)).modCoeff(ql); + Polynomial d3_1 = ((d3 * evk.a).scaleRoundCoeff(1.0/1000.0)).modCoeff(ql); Polynomial outC0 = d1.modCoeff(ql) + d3_0.modCoeff(ql); Polynomial outC1 = d2.modCoeff(ql) + d3_1.modCoeff(ql); - - // Rescale ql = (double)ql / (double)pl[level-1]; Polynomial c0 = outC0.scaleRoundCoeff(1.0/(double)pl[level-1]); Polynomial c1 = outC1.scaleRoundCoeff(1.0/(double)pl[level-1]); - - level -= 1; Ciphertext out(c0.modCoeff(ql), c1.modCoeff(ql)); - return out; } @@ -150,17 +155,18 @@ int getNextPow(int deg){ Ciphertext CKKS::multNTT(Ciphertext ct1, Ciphertext ct2){ int deg = getNextPow(ct1.c0.degree+ct2.c0.degree-1); - cout << deg << endl; - int64_t w = ntt.genNthRoot(ntt.M, deg); - level += 1; - + int64_t w = ntt.genNthRoot(ntt.M, deg); //ntt.genNthRoot(ntt.M, deg); + Polynomial d1 = fastMult(ct1.c0, ct2.c0, deg, w).modCoeff(ql); Polynomial d2 = (fastMult(ct1.c0, ct2.c1,deg, w) + fastMult(ct2.c0, ct1.c1,deg, w)).modCoeff(ql); Polynomial d3 = fastMult(ct1.c1, ct2.c1,deg, w).modCoeff(ql); - + // Relin - Polynomial d3_0 = fastMult(d3, evk.b,deg, w).scaleRoundCoeff(1.0/1000.0); - Polynomial d3_1 = fastMult(d3, evk.a,deg, w).scaleRoundCoeff(1.0/1000.0); + Polynomial d3_0 = (d3 * evk.b).scaleRoundCoeff(1.0/1000.0); + Polynomial d3_1 = (d3 * evk.a).scaleRoundCoeff(1.0/1000.0); + //Polynomial d3_0 = fastMult(d3, evk.b,deg, w).scaleRoundCoeff(1.0/1000.0); + //Polynomial d3_1 = fastMult(d3, evk.a,deg, w).scaleRoundCoeff(1.0/1000.0); + Polynomial outC0 = d1.modCoeff(ql) + d3_0.modCoeff(ql); Polynomial outC1 = d2.modCoeff(ql) + d3_1.modCoeff(ql); @@ -168,10 +174,13 @@ Ciphertext CKKS::multNTT(Ciphertext ct1, Ciphertext ct2){ // Rescale ql = (double)ql / (double)pl[level-1]; Polynomial c0 = outC0.scaleRoundCoeff(1.0/(double)pl[level-1]); + c0.reduceDeg(); Polynomial c1 = outC1.scaleRoundCoeff(1.0/(double)pl[level-1]); + c1.reduceDeg(); level -= 1; - + Ciphertext out(c0.modCoeff(ql), c1.modCoeff(ql)); + return out; -} \ No newline at end of file +} diff --git a/src/ckks.h b/src/ckks.h index fa1f8ed0d75d86c7931a76d214b802f6f1b3109a..c81e4177c4870a21d3bbdbb9fb7fc374204c142d 100644 --- a/src/ckks.h +++ b/src/ckks.h @@ -14,7 +14,7 @@ class CKKS { int deg; int level = 6; int q0 = 67; - int pl[6] = {61, 67, 71, 73, 79, 59}; + int pl[6] = {61, 67, 71, 73, 79, 67}; int64_t ql; PubKey pk; EvalKey evk; diff --git a/src/encoder.cpp b/src/encoder.cpp index f4b7eadb744b6c2f57e305d74fe1eb1d4d5e80e0..92de2c302e6aa28ca3ff7815bcc6b12741382076 100644 --- a/src/encoder.cpp +++ b/src/encoder.cpp @@ -11,7 +11,7 @@ using namespace std; using namespace std::chrono; -dcomplex vdot(dcomplex a[], dcomplex* b, int size, int offset){ +dcomplex vdot(vector<dcomplex> a, vector<dcomplex> b, int size, int offset){ dcomplex out (0.0, 0.0); for(int i=0; i<size; i++){ out += b[i+offset] * conj(a[i]); @@ -19,7 +19,7 @@ dcomplex vdot(dcomplex a[], dcomplex* b, int size, int offset){ return out; } -dcomplex vdots(dcomplex* a, dcomplex* b, int size, int offset){ +dcomplex vdots(vector<dcomplex> a, vector<dcomplex> b, int size, int offset){ dcomplex out (0.0, 0.0); for(int i=0; i<size; i++){ out += b[offset+i] * conj(a[offset+i]); @@ -38,8 +38,8 @@ Encoder::Encoder(int in, double inScale){ M = in; scale = inScale; root = exp((2*M_PI/M) * J); - vandermonde = (dcomplex*) malloc(M/2*M/2*sizeof(dcomplex)); - sigmaRBasis = (dcomplex*) malloc(M/2*M/2*sizeof(dcomplex)); + vandermonde = vector<dcomplex>((M/2)*(M/2)); + sigmaRBasis = vector<dcomplex>((M/2)*(M/2)); initVandermonde(root); initSigmaRBasis(); } @@ -65,7 +65,7 @@ void Encoder::initSigmaRBasis(){ dcomparr Encoder::piInv(dcomparr input){ int N = M/4; - dcomparr out; + dcomparr out(M/2); for (int i=0; i<N; i++){ out.arr[i] = input.arr[i]; out.arr[2*N-i-1] = conj(input.arr[i]); @@ -76,21 +76,26 @@ dcomparr Encoder::piInv(dcomparr input){ dcomparr Encoder::sigma(Polynomial pol){ int N = M/4; - dcomparr out; + if(pol.degree == 2*N){ + dcomparr out(pol.degree/2); for(int i=0; i<N; i++){ for (int j=0; j<M/2; j++){ out.arr[i] += pol.coeffs[j] * vandermonde[i*M/2+j]; } } + + return out; }else{ int R = 2; + pol.reduceDeg(); while (R < pol.degree){ - R <<=2; + R <<=1; } - dcomplex* tempVandermonde = (dcomplex*) malloc(R*R*sizeof(dcomplex)); + dcomparr out(R/2); + vector<dcomplex> tempVandermonde = vector<dcomplex>(R*R); for(int i=0; i<R; i++){ for(int j=0; j<R; j++){ @@ -102,11 +107,15 @@ dcomparr Encoder::sigma(Polynomial pol){ for(int i=0; i<R/2; i++){ for (int j=0; j<R; j++){ - out.arr[i] += pol.coeffs[j] * tempVandermonde[i*R+j]; + if(j<pol.degree){ + out.arr[i] += pol.coeffs[j] * tempVandermonde[i*R+j]; + } } } + + return out; } - return out; + } dcomparr Encoder::decode(Polynomial pol){ @@ -117,12 +126,11 @@ dcomparr Encoder::decode(Polynomial pol){ auto stop = high_resolution_clock::now(); auto duration = duration_cast<microseconds>(stop - start); //cout << "Decoding: " << duration.count() << endl; - return out; } dcomparr Encoder::computeCoordinate(dcomparr z){ - dcomparr out; + dcomparr out(M/2); for (int i=0; i<M/2; i++){ dcomplex zi = vdot(z.arr, sigmaRBasis, M/2, i*M/2) / vdots(sigmaRBasis, sigmaRBasis, M/2, i*M/2); out.arr[i] = real(zi); @@ -135,7 +143,7 @@ dcomparr Encoder::coordinateWRR(dcomparr coordinates){ double r; double f; - dcomparr roundedCoor; + dcomparr roundedCoor(M/2); for (int i=0; i<M/2; i++){ r = real(coordinates.arr[i]) - floor(real(coordinates.arr[i])); @@ -166,6 +174,7 @@ Polynomial Encoder::sigmaInv(dcomparr z){ Polynomial Encoder::encode(dcomparr input){ auto start = high_resolution_clock::now(); dcomparr zPi = piInv(input); + int N = M/4; for (int i=0; i<N; i++){ zPi.arr[i] *= scale; @@ -175,6 +184,8 @@ Polynomial Encoder::encode(dcomparr input){ dcomparr roundZ = discretization(zPi); Polynomial out = sigmaInv(roundZ); + // Polynomial out(2); + auto stop = high_resolution_clock::now(); auto duration = duration_cast<microseconds>(stop - start); //cout << "Encoding: " << duration.count() << endl; diff --git a/src/encoder.h b/src/encoder.h index 552ac6361a52b46785fabd176abe093120239a38..ee3abf98d71afe618b0be69997dfb907d19c5b2a 100644 --- a/src/encoder.h +++ b/src/encoder.h @@ -1,6 +1,7 @@ #include "polynomial.h" #include <complex> #include <eigen3/Eigen/Dense> +#include <vector> using namespace std; @@ -10,7 +11,10 @@ using namespace std; typedef complex<double> dcomplex; struct dcomparr { - dcomplex arr[200]; + vector<dcomplex> arr; + dcomparr(int size){ + arr = vector<dcomplex>(size); + } }; @@ -22,8 +26,8 @@ class Encoder { int M; double scale; dcomplex root; - dcomplex* vandermonde; - dcomplex* sigmaRBasis; + vector<dcomplex> vandermonde; + vector<dcomplex> sigmaRBasis; Encoder(int in, double inScale); void initVandermonde(dcomplex xi); @@ -36,7 +40,6 @@ class Encoder { dcomparr discretization(dcomparr z); Polynomial sigmaInv(dcomparr z); Polynomial encode(dcomparr input); - }; diff --git a/src/evalkey.cpp b/src/evalkey.cpp index 5c53b7fa0772f22abc7400d5f859b3124cfda937..d9941a709083779c415461aa721801d351faae29 100644 --- a/src/evalkey.cpp +++ b/src/evalkey.cpp @@ -3,6 +3,7 @@ #include <cmath> #include <random> #include "evalkey.h" +#include <vector> using namespace std; @@ -12,12 +13,12 @@ EvalKey::EvalKey(Polynomial _s, int degree, int64_t q){ p = 1000; s = _s; - generateA(degree, 100); + generateA(degree, 1000); computeB(q); } Polynomial EvalKey::genE(int degree, double var){ - double errCoeffs[degree]; + vector<double> errCoeffs(degree); random_device rd; mt19937 gen(rd()); @@ -36,20 +37,20 @@ void EvalKey::generateA(int degree, int64_t q){ random_device rd; mt19937 gen(rd()); uniform_int_distribution<int64_t> dis(0, half_q); - double a_coeffs[degree]; + vector<double> a_coeffs(degree); for (int i=0; i<degree; i++){ a_coeffs[i] = (double) dis(gen); } + a.setCoeffs(a_coeffs); } void EvalKey::computeB(int q){ Polynomial err = genE(a.degree, 1.0); Polynomial ev = (s * s).scaleCoeff(p); - Polynomial temp = ((a.scaleCoeff(-1.0)) * s) + ev + err; + Polynomial temp = ((a.scaleCoeff(-1.0)) * s) + ev ; Polynomial res = temp.modCoeff(q * p); - b.setDegree(res.degree); - b.setCoeffs(res.coeffs); + b = Polynomial(res.degree, res.coeffs); } \ No newline at end of file diff --git a/src/ntt.cpp b/src/ntt.cpp index 6a5764181dd3f7984e016ae6599f6c2e60e76cd0..d681e78c4bf04baa9cdf4bb8cd404a719ad7b901 100644 --- a/src/ntt.cpp +++ b/src/ntt.cpp @@ -1,4 +1,7 @@ #include "ntt.h" +#include <vector> + +using namespace std; int64_t NTT::modExp(int64_t base, int64_t power, int64_t mod){ int64_t res = 1; @@ -139,7 +142,7 @@ vector<int64_t> NTT::ntt(Polynomial in, int degree, int64_t w){ Polynomial NTT::intt(vector<int64_t> &in, int w){ int N = size(in); Polynomial pOut(N); - double coeff[N]; + vector<double> coeff(N); int64_t wInv = modInv(w, M); int64_t nInv = modInv(N, M); @@ -151,4 +154,4 @@ Polynomial NTT::intt(vector<int64_t> &in, int w){ pOut.setCoeffs(coeff); return pOut; -} \ No newline at end of file +} diff --git a/src/polynomial.cpp b/src/polynomial.cpp index bdd44b74743053e3c172d0b3e6c54b273a573e4f..7c8225df1872b25cc8909e589181d5d848af4f43 100644 --- a/src/polynomial.cpp +++ b/src/polynomial.cpp @@ -5,17 +5,26 @@ #include <string.h> #include <iostream> #include "polynomial.h" +#include <vector> using namespace std; Polynomial::Polynomial(int deg){ degree = deg; - memset(coeffs, 0, sizeof(coeffs)); + coeffs = vector<double>(deg); + for(int i=0; i<degree; i++){ + coeffs[i] = 0.0; + } } -Polynomial::Polynomial(int deg, double coeff[]){ +// Polynomial::~Polynomial(){ +// //free(coeffs); +// coeffs = NULL; +// } + +Polynomial::Polynomial(int deg, vector<double> coeff){ degree = deg; - memset(coeffs, 0, sizeof(coeffs)); + coeffs = vector<double>(deg); for(int i=0; i<degree; i++){ coeffs[i] = coeff[i]; } @@ -25,12 +34,22 @@ void Polynomial::setDegree(int N){ degree = N; } -void Polynomial::setCoeffs(double coeff[]){ +void Polynomial::setCoeffs(vector<double> coeff){ for(int i=0; i<degree; i++){ coeffs[i] = coeff[i]; } } +void Polynomial::reduceDeg(){ + for(int i=degree-1; i>0; i--){ + if(coeffs[i] == 0){ + degree -= 1; + } else{ + break; + } + } +} + Polynomial Polynomial::scaleCoeff(double scale){ Polynomial out(degree); for (int i=0; i<degree; i++){ @@ -58,7 +77,7 @@ Polynomial Polynomial::modCoeff(int64_t q){ Polynomial Polynomial::dot (Polynomial const &obj){ int deg = max(obj.degree, degree); - double coeff[deg]; + vector<double> coeff(deg); for(int i=0; i<deg; i++){ coeff[i] = coeffs[i] * obj.coeffs[i]; } @@ -68,14 +87,16 @@ Polynomial Polynomial::dot (Polynomial const &obj){ Polynomial Polynomial::operator + (Polynomial const &obj){ int deg = max(obj.degree, degree); - double coeff[deg]; - - for (int i = 0; i<deg; i++){ - coeff[i] = 0; - } + vector<double> coeff(deg, 0); for(int i=0; i<deg; i++){ - coeff[i] = coeffs[i] + obj.coeffs[i]; + if(i<degree){ + coeff[i] += coeffs[i]; + } + + if(i<obj.degree){ + coeff[i] += obj.coeffs[i]; + } } Polynomial out(deg, coeff); @@ -84,10 +105,7 @@ Polynomial Polynomial::operator + (Polynomial const &obj){ Polynomial Polynomial::operator * (Polynomial const &obj){ int deg = degree + obj.degree -1; - double coeff[deg]; - for (int i = 0; i<deg; i++){ - coeff[i] = 0; - } + vector<double> coeff(deg, 0); for(int i=0; i<degree; i++){ for(int j=0; j<obj.degree; j++){ @@ -111,4 +129,5 @@ void Polynomial::printPol(){ } } cout << endl; -} \ No newline at end of file +} + diff --git a/src/polynomial.h b/src/polynomial.h index 81753efca7bacccf792ffd73ca92009060984690..7616785f891ee87b3f18f117bbe923c56a8f290d 100644 --- a/src/polynomial.h +++ b/src/polynomial.h @@ -1,18 +1,24 @@ #include<iostream> +#include<vector> + +using namespace std; + #ifndef POLYNOMIAL_H #define POLYNOMIAL_H + class Polynomial { public: int degree; - double coeffs[200]; + vector<double> coeffs; Polynomial() = default; Polynomial(int deg); - Polynomial(int deg, double coeff[]); + Polynomial(int deg, vector<double> coeff); + //~Polynomial(); void setDegree(int N); - void setCoeffs(double coeff[]); + void setCoeffs(vector<double> coeffs); Polynomial scaleCoeff(double scale); Polynomial scaleRoundCoeff(double scale); Polynomial modCoeff(int64_t q); @@ -20,6 +26,7 @@ class Polynomial { Polynomial fastMult(Polynomial p1, Polynomial p2); Polynomial operator + (Polynomial const &obj); Polynomial operator * (Polynomial const &obj); + void reduceDeg(); void printPol(); }; diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 39602619f45a2f9bf94356c031ba9c895c3a5d8b..50b26536c786b6143306ab8c81a82a63352a0d83 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -3,20 +3,20 @@ #include <cmath> #include <random> #include "pubkey.h" +#include <vector> using namespace std; PubKey::PubKey(Polynomial _s, int degree, int64_t q){ a = Polynomial(degree); - b = Polynomial(degree); s = _s; - generateA(degree, 100); + generateA(degree, 1000); computeB(q); } Polynomial PubKey::genE(int degree, double var){ - double errCoeffs[degree]; + vector<double> errCoeffs(degree); random_device rd; mt19937 gen(rd()); @@ -35,7 +35,7 @@ void PubKey::generateA(int degree, int64_t q){ random_device rd; mt19937 gen(rd()); uniform_int_distribution<int64_t> dis(0, half_q); - double a_coeffs[degree]; + vector<double> a_coeffs(degree); for (int i=0; i<degree; i++){ a_coeffs[i] = (double) dis(gen); @@ -48,6 +48,5 @@ void PubKey::computeB(int q){ Polynomial temp = (a.scaleCoeff(-1.0)) * s + err; Polynomial res = temp.modCoeff(q); - b.setDegree(res.degree); - b.setCoeffs(res.coeffs); + b = Polynomial(res.degree, res.coeffs); } diff --git a/src/seckey.cpp b/src/seckey.cpp index 0ea43644b6ca3318e915f4ef2c93a654bcd99166..44f518e15ab81fa49a82c75ecd50d6daeb1d157b 100644 --- a/src/seckey.cpp +++ b/src/seckey.cpp @@ -2,11 +2,12 @@ #include <string> #include "seckey.h" #include "encoder.h" +#include <vector> using namespace std; SecKey::SecKey(int deg){ - double coeff[deg]; + vector<double> coeff(deg); std::random_device rd; std::mt19937 gen(rd()); @@ -20,8 +21,8 @@ SecKey::SecKey(int deg){ random_shuffle(key.begin(), key.end()); for(int i=0; i<deg; i++){ - char temp = key.at(i); - coeff[i] = (double) -1 * (atoi(&temp)); + char temp = key[i]; + coeff[i] = (double) -1 * (int(temp)-48); } s = Polynomial(deg, coeff); diff --git a/test.cpp b/test.cpp index f2482640688e42c6fa71a7d1e987828970490973..e44a7222b6f46fd452d3b6ebf8637ddb39991ee2 100644 --- a/test.cpp +++ b/test.cpp @@ -11,118 +11,211 @@ using namespace std; using namespace std::chrono; +dcomparr randomFill(int n){ + dcomparr out(n); + for(int i=0; i<n; i++){ + out.arr[i] = 1.0 + 1.0*J; + } + return out; +} + int main(){ Encoder enc(8, 64.0); - dcomplex a1 = 4.0 + 3.0 *J; + dcomplex a1 = 3.0 + 4.0 *J; dcomplex a2 = 2.0 - 1.0*J; - dcomparr input = {a1, a2}; + dcomparr input(2); + input.arr[0] = a1; + input.arr[1] = a2; - // dcomparr input; - // dcomplex a = 1.0 + 1.0; - // for(int i=0; i<32; i++){ - // input.arr[i] = a; - // } + // // dcomparr input(128); + // // dcomplex a = 1.0 + 1.0*J; + // // for(int i=0; i<128; i++){ + // // input.arr[i] = a; + // // } Polynomial pt = enc.encode(input); - - // pt.printPol(); + pt.printPol(); int q0 = 67; - int pl[6] = {61, 67, 71, 73, 79, 59}; + int pl[6] = {61, 67, 71, 73, 79, 61}; int64_t ql = q0; for (int i=0; i<3; i++){ ql *= pl[i]; } - - SecKey sk = SecKey(2); - PubKey pk(sk.s, 2, ql); - // cout << "pk: "; - // pk.b.printPol(); - EvalKey evk(sk.s, 2, ql); + // SecKey sk = SecKey(2); + // // sk.s.printPol(); + // PubKey pk(sk.s, 3, ql); + // // cout << "pk: "; + // // pk.b.printPol(); + // EvalKey evk(sk.s, 3, ql); // cout << "evk: "; // evk.b.printPol(); - Polynomial pt2 = pt * pt; - // pt2.printPol(); + // cout << "Control: "; + // Polynomial pt2 = pt * pt; + // pt2.scaleRoundCoeff(1.0/61.0).printPol(); + + // CKKS ckks(4, pk, evk, sk); + // Ciphertext ct = ckks.encrypt(pt); + + // auto start = high_resolution_clock::now(); + // Ciphertext ctadd = ckks.multNTT(ct, ct); + // auto stop = high_resolution_clock::now(); + // auto duration = duration_cast<microseconds>(stop - start); + //cout << "Normal Time: " << duration.count() << endl; + + // cout << "Experiment: "; + // Polynomial ptOut = ckks.decrypt(ctadd); + // ptOut.printPol(); + + bool error = false; + // for(int i=1; i<5; i++){ + // cout << i << endl; + // int N = pow(2, i); + // Encoder enc(N*4, 64.0); + // dcomparr in = randomFill(N); + // Polynomial test = enc.encode(in); + // dcomparr out = enc.decode(test); + // for(int j=0; j<N; j++){ + // if (abs(in.arr[i]-out.arr[i]) > 2.0){ + // error = true; + // break; + // } + // } + // if (error) break; + // } - CKKS ckks(4, pk, evk, sk); - Ciphertext ct = ckks.encrypt(pt); - //ct.c0.printPol(); + // for(int i=1; i<5; i++){ + // int N = pow(2, i); + // Encoder enc(N*4, 64.0); + + // SecKey sk = SecKey(N); + // PubKey pk(sk.s, (N)+1, ql); + // EvalKey evk(sk.s, (N)+1, ql); + // CKKS ckks(N, pk, evk, sk); + + // dcomparr in = randomFill(N); + + // Polynomial test = enc.encode(in); + // Ciphertext ct = ckks.encrypt(test); + // Polynomial testOut = ckks.decrypt(ct); + + // dcomparr out = enc.decode(testOut); + // for(int j=0; j<N; j++){ + // if (abs(in.arr[j]-out.arr[j]) > 2.0){ + // error = true; + // break; + // } + // } + // if (error) break; + // } + // for(int i=1; i<5; i++){ + // int N = pow(2, i); + // Encoder enc(N*4, 64.0); + + // SecKey sk = SecKey(N); + // PubKey pk(sk.s, (N)+1, ql); + // EvalKey evk(sk.s, (N)+1, ql); + // CKKS ckks(N, pk, evk, sk); + + // dcomparr in = randomFill(N); + + // Polynomial test = enc.encode(in); + // Ciphertext ct = ckks.encrypt(test); + // Ciphertext ctadd = ckks.add(ct,ct); + // Polynomial testOut = ckks.decrypt(ctadd); + + // dcomparr out = enc.decode(testOut); + // dcomplex scale(2.0, 0.0); + // for(int j=0; j<N; j++){ + // if (abs((scale*in.arr[j])-out.arr[j]) > 2.0){ + // error = true; + // break; + // } + // } + // if (error) break; + // } - auto start = high_resolution_clock::now(); - Ciphertext ctadd = ckks.mult(ct, ct); - auto stop = high_resolution_clock::now(); - auto duration = duration_cast<microseconds>(stop - start); - cout << "Normal Time: " << duration.count() << endl; + // for(int i=1; i<5; i++){ + // int N = pow(2, i); + // Encoder enc(N*4, 64.0); + + // SecKey sk = SecKey(N); + // PubKey pk(sk.s, (N)+1, ql); + // EvalKey evk(sk.s, (N)+1, ql); + // CKKS ckks(N, pk, evk, sk); + + // dcomparr in = randomFill(N); + + // Polynomial test = enc.encode(in); + // Ciphertext ct = ckks.encrypt(test); + // Ciphertext ctadd = ckks.mult(ct,ct); + // Polynomial testOut = ckks.decrypt(ctadd); + + // Polynomial control = (test * test).scaleRoundCoeff(1.0/64.0); + // dcomparr out = enc.decode(testOut); + // dcomparr check = enc.decode(control); + + // for(int j=0; j<N*2; j++){ + // if (abs(check.arr[j]-out.arr[j]) > 2.0){ + // error = true; + // break; + // } + // } + // if (error) break; + // } - - Polynomial ptOut = ckks.decrypt(ctadd); - //ptOut.printPol(); - - // //problem - // cout << "decode" << endl; - dcomparr output = enc.decode(ptOut); - // for(int i=0; i<4; i++){ - // cout << output.arr[i] << " "; + // for(int i=1; i<5; i++){ + // int N = pow(2, i); + // Encoder enc(N*4, 64.0); + + // SecKey sk = SecKey(N); + // PubKey pk(sk.s, (N)+1, ql); + // EvalKey evk(sk.s, (N)+1, ql); + // CKKS ckks(N, pk, evk, sk); + + // dcomparr in = randomFill(N); + + // Polynomial test = enc.encode(in); + // Ciphertext ct = ckks.encrypt(test); + // Ciphertext ctadd = ckks.multNTT(ct,ct); + // Polynomial testOut = ckks.decrypt(ctadd); + + // Polynomial control = (test * test).scaleRoundCoeff(1.0/64.0); + // dcomparr out = enc.decode(testOut); + // dcomparr check = enc.decode(control); + + // for(int j=0; j<N; j++){ + // if (abs(check.arr[j]-out.arr[j]) > 2.0){ + // error = true; + // break; + // } + // } + // if (error) break; // } - // cout << endl; - // // cout << "test" << endl; - // cout << endl; - - cout << "Experiment" << endl; - cout << "polynomial: "; - ptOut.printPol(); - for(int i=0; i<4; i++){ - cout << output.arr[i]/1.0 << " "; - } - cout << endl; - - cout << "Control" << endl; - cout << "polynomial: "; - (pt2.scaleCoeff(1.0/61.0)).printPol(); - dcomparr out = enc.decode(pt2); - for(int i=0; i<4; i++){ - cout << out.arr[i]/64.0 << " "; - } - cout << endl; - // cout << "NTT test" << endl; + // int N = pow(2, 3); + // Encoder enc(N*4, 64.0); + // SecKey sk = SecKey(N); + // PubKey pk(sk.s, (N)+1, ql); + // EvalKey evk(sk.s, (N)+1, ql); + // CKKS ckks(N, pk, evk, sk); + // dcomparr in = randomFill(N); - auto start1 = high_resolution_clock::now(); - Ciphertext mult = ckks.multNTT(ct, ct); - auto stop1 = high_resolution_clock::now(); - auto duration1 = duration_cast<microseconds>(stop1 - start1); - cout << "NTT Time: " << duration1.count() << endl; + // Polynomial test = enc.encode(in); + // Ciphertext ct = ckks.encrypt(test); + // Ciphertext ctadd = ckks.multNTT(ct,ct); + // Polynomial testOut = ckks.decrypt(ctadd); - Polynomial nttOut = ckks.decrypt(mult); - dcomparr nttoutput = enc.decode(nttOut); - nttOut.printPol(); - for(int i=0; i<4; i++){ - cout << nttoutput.arr[i]/1.0 << " "; + if(error) { + cout << "Error" << endl; + } else { + cout << "Finish" << endl; } - cout << endl; - // double in[] = {2.0, 1.0}; - // Polynomial p1(4, in); - - // double in2[] = {3.0, 1.0}; - // Polynomial p2(4, in2); - - // int64_t w = 1934320121; - // vector<int64_t> out = ckks.ntt.ntt(p1, 16, w); - // for(int i=0; i<16; i++){ - // cout << out[i] << " "; - // } - // cout << endl; - // Polynomial test = ckks.ntt.intt(out, w); - // test.printPol(); - - // Polynomial test = ckks.fastMult(p1, p2, w); - // test.printPol(); - return 0; } \ No newline at end of file diff --git a/test.o b/test.o index 36a54436f8b4b466bd16e43bbb5ccb847efd286c..ebc303e410ea324c4f17110ebf22edebf2630133 100644 Binary files a/test.o and b/test.o differ