diff --git a/.vscode/settings.json b/.vscode/settings.json index d7568504da65e57eb219720716ef0fed1c7ac80a..e1c2be9c9e30eaf4c19a3d73292557faef475412 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { "files.associations": { - "complex": "cpp" + "complex": "cpp", + "dense": "cpp" } } \ No newline at end of file diff --git a/src/ckks.cpp b/src/ckks.cpp index ddb9881631e70e90d87b873794fc0c7138a92e1e..10878eb8501e85fd1cbce2ee7b86b29b4730dd16 100644 --- a/src/ckks.cpp +++ b/src/ckks.cpp @@ -4,6 +4,8 @@ #include <random> #include <polynomial.h> #include <pubkey.h> +#include <seckey.h> +#include <ciphertext.h> #include <eigen3/Eigen/Dense> #define J dcomplex(0.0,1.0) @@ -11,44 +13,7 @@ using namespace std; -typedef complex<double> dcomplex; -typedef Eigen::Matrix<dcomplex, 4, 4> Matrix4dc; -typedef Eigen::Matrix<dcomplex, 4, 1> Matrix1dc; - -struct dcomparr { - dcomplex arr[10]; -}; - -struct coeffarr { - int arr[10]; -}; - -dcomplex vdot(dcomplex a[], dcomplex b[]){ - dcomplex out (0.0, 0.0); - for(int i=0; i<10; i++){ - out += b[i] * conj(a[i]); - } - return out; -} - -double randomChoice(double val){ - default_random_engine generator; - discrete_distribution<int> distribution {round(1.0 - val), round(val)}; - int number = distribution(generator); - return ((number == 0) ? val : (val - 1.0)); -} - -dcomparr matMult(dcomplex mat[SIZE][SIZE], coeffarr in, int m){ - dcomparr out; - for(int i=0; i<m; i++){ - for(int j=0; j<m; j++){ - out.arr[i] += mat[i][j] * (double)in.arr[j]; - } - } - return out; -} - -Polynomial genError(int degree, double var){ +Polynomial genE(int degree, double var){ double errCoeffs[degree]; random_device rd; @@ -63,8 +28,6 @@ Polynomial genError(int degree, double var){ return err; } - - class CKKS { private: SecKey sk; @@ -77,14 +40,14 @@ class CKKS { deg = N; } - Polynomial genError(){ + Polynomial genTestError(){ double test[4] = {1.0, 1.0, 1.0, 1.0}; Polynomial err(4, test); return err; } Ciphertext encrypt(Polynomial pt){ - Polynomial e = genError(); + Polynomial e = genTestError(); Polynomial c0 = (e + pt) + pk.b; Polynomial c1 = pk.a; @@ -114,9 +77,6 @@ class CKKS { }; - - - int main(){ } \ No newline at end of file diff --git a/src/encoder.cpp b/src/encoder.cpp index fb30b0ea88bb26370a2ed9decfa6326cc34834f4..5ea8a54fd6a1b83a3862981420323e4a52f676b2 100644 --- a/src/encoder.cpp +++ b/src/encoder.cpp @@ -2,154 +2,155 @@ #include <complex> #include <cmath> #include <random> -#include <polynomial.h> #include <eigen3/Eigen/Dense> -#define J dcomplex(0.0,1.0) -#define SIZE 10 +#include <polynomial.h> +#include <encoder.h> using namespace std; -typedef complex<double> dcomplex; -typedef Eigen::Matrix<dcomplex, 4, 4> Matrix4dc; -typedef Eigen::Matrix<dcomplex, 4, 1> Matrix1dc; - -struct dcomparr { - dcomplex arr[10]; -}; - -struct coeffarr { - int arr[10]; -}; - -class Encoder { - public: - int M; - double scale; - dcomplex root; - dcomplex vandermonde[10][10]; - dcomplex sigmaRBasis[10][10]; - Matrix4dc vand; - - Encoder(int in, double inScale){ - M = in; - scale = inScale; - root = exp((2*M_PI/M) * J); - initVandermonde(root); - initSigmaRBasis(); - } - - void initVandermonde(dcomplex xi){ - int N = M/2; - for(int i=0; i<N; i++){ - for(int j=0; j<N; j++){ - int power = (2*i+1) * j; - dcomplex temp = pow(xi, power); - vandermonde[i][j] = temp; - vand(i,j) = temp; - - } - } - } - - void initSigmaRBasis(){ - int N = M/2; - for(int i=0; i<N; i++){ - for(int j=0; j<N; j++){ - sigmaRBasis[j][i] = vandermonde[i][j]; - } - } - } - - dcomparr piInv(dcomparr input){ - int N = M/4; - dcomparr out; - for (int i=0; i<N; i++){ - out.arr[i] = input.arr[i]; - out.arr[2*N-i-1] = conj(input.arr[i]); - } - - return out; - } - - dcomparr sigma(Polynomial pol){ - int N = M/4; - dcomparr out; - for(int i=0; i<N; i++){ - for (int j=0; j<M/2; j++){ - out.arr[i] += pol.coeffs[j] * vandermonde[i][j]; - } - } - - return out; +dcomplex vdot(dcomplex a[], dcomplex b[]){ + dcomplex out (0.0, 0.0); + for(int i=0; i<10; i++){ + out += b[i] * conj(a[i]); + } + return out; +} + +double randomChoice(double val){ + default_random_engine generator; + discrete_distribution<int> distribution {round(1.0 - val), round(val)}; + int number = distribution(generator); + return ((number == 0) ? val : (val - 1.0)); +} + +dcomparr matMult(dcomplex mat[SIZE][SIZE], coeffarr in, int m){ + dcomparr out; + for(int i=0; i<m; i++){ + for(int j=0; j<m; j++){ + out.arr[i] += mat[i][j] * (double)in.arr[j]; } - - dcomparr decode(Polynomial pol){ - Polynomial unscaled = pol.scaleCoeff(1.0/scale); - return sigma(unscaled); + } + return out; +} + +Encoder::Encoder(int in, double inScale){ + M = in; + scale = inScale; + root = exp((2*M_PI/M) * J); + initVandermonde(root); + initSigmaRBasis(); +} + +void Encoder::initVandermonde(dcomplex xi){ + int N = M/2; + for(int i=0; i<N; i++){ + for(int j=0; j<N; j++){ + int power = (2*i+1) * j; + dcomplex temp = pow(xi, power); + vandermonde[i][j] = temp; + vand(i,j) = temp; } - - dcomparr computeCoordinate(dcomparr z){ - dcomparr out; - for (int i=0; i<M/2; i++){ - dcomplex zi = vdot(z.arr, sigmaRBasis[i]) / vdot(sigmaRBasis[i], sigmaRBasis[i]); - out.arr[i] = real(zi); - } - - return out; + } +} + +void Encoder::initSigmaRBasis(){ + int N = M/2; + for(int i=0; i<N; i++){ + for(int j=0; j<N; j++){ + sigmaRBasis[j][i] = vandermonde[i][j]; } - - coeffarr coordinateWRR(dcomparr coordinates){ - double r; - double f; - - coeffarr roundedCoor; - - for (int i=0; i<10; i++){ - r = real(coordinates.arr[i]) - floor(real(coordinates.arr[i])); - f = randomChoice(r); - roundedCoor.arr[i] = round(real(coordinates.arr[i])-f); - } - - return roundedCoor; + } +} + +dcomparr Encoder::piInv(dcomparr input){ + int N = M/4; + dcomparr out; + for (int i=0; i<N; i++){ + out.arr[i] = input.arr[i]; + out.arr[2*N-i-1] = conj(input.arr[i]); + } + + return out; +} + +dcomparr Encoder::sigma(Polynomial pol){ + int N = M/4; + dcomparr out; + for(int i=0; i<N; i++){ + for (int j=0; j<M/2; j++){ + out.arr[i] += pol.coeffs[j] * vandermonde[i][j]; } + } + + return out; +} + +dcomparr Encoder::decode(Polynomial pol){ + Polynomial unscaled = pol.scaleCoeff(1.0/scale); + return sigma(unscaled); +} + +dcomparr Encoder::computeCoordinate(dcomparr z){ + dcomparr out; + for (int i=0; i<M/2; i++){ + dcomplex zi = vdot(z.arr, sigmaRBasis[i]) / vdot(sigmaRBasis[i], sigmaRBasis[i]); + out.arr[i] = real(zi); + } + + return out; +} + +coeffarr Encoder::coordinateWRR(dcomparr coordinates){ + double r; + double f; + + coeffarr roundedCoor; + + for (int i=0; i<10; i++){ + r = real(coordinates.arr[i]) - floor(real(coordinates.arr[i])); + f = randomChoice(r); + roundedCoor.arr[i] = round(real(coordinates.arr[i])-f); + } + + return roundedCoor; +} + +dcomparr Encoder::discretization(dcomparr z){ + dcomparr coor = computeCoordinate(z); + coeffarr roundedCoor = coordinateWRR(coor); + dcomparr out = matMult(vandermonde, roundedCoor, M/2); + return out; +} + +Polynomial Encoder::sigmaInv(dcomparr z){ + Matrix1dc zRounded; + int N = M/2; + Polynomial out(N); + + for (int i=0; i<N; i++){ + zRounded(i,0) = z.arr[i]; + } - dcomparr discretization(dcomparr z){ - dcomparr coor = computeCoordinate(z); - coeffarr roundedCoor = coordinateWRR(coor); - dcomparr out = matMult(vandermonde, roundedCoor, M/2); - return out; - } + Matrix1dc res = vand.lu().solve(zRounded); - Polynomial sigmaInv(dcomparr z){ - Matrix1dc zRounded; - int N = M/2; - Polynomial out(N); - - for (int i=0; i<N; i++){ - zRounded(i,0) = z.arr[i]; - } - - Matrix1dc res = vand.lu().solve(zRounded); - - for(int i=0; i<N; i++){ - out.coeffs[i] = real(res(i,0)); - } - return out; - } + for(int i=0; i<N; i++){ + out.coeffs[i] = real(res(i,0)); + } + return out; +} - Polynomial encode(dcomparr input){ - dcomparr zPi = piInv(input); +Polynomial Encoder::encode(dcomparr input){ + dcomparr zPi = piInv(input); - int N = M/4; - for (int i=0; i<N; i++){ - zPi.arr[i] *= scale; - zPi.arr[i+N] *= scale; - } + int N = M/4; + for (int i=0; i<N; i++){ + zPi.arr[i] *= scale; + zPi.arr[i+N] *= scale; + } - dcomparr roundZ = discretization(zPi); - Polynomial out = sigmaInv(roundZ); + dcomparr roundZ = discretization(zPi); + Polynomial out = sigmaInv(roundZ); - return out; - } -}; \ No newline at end of file + return out; +} diff --git a/src/encoder.h b/src/encoder.h index 7876df70a1d10edf60b04a5ed21663b03fcffac8..75fd9b39f5b547b853b566f923504a9aebb84744 100644 --- a/src/encoder.h +++ b/src/encoder.h @@ -1,9 +1,24 @@ #include <polynomial.h> -#include <util.h> +#include <complex> #ifndef ENCODER_H #define ENCODER_H +#define J dcomplex(0.0,1.0) +#define SIZE 10 + +typedef complex<double> dcomplex; +typedef Eigen::Matrix<dcomplex, 4, 4> Matrix4dc; +typedef Eigen::Matrix<dcomplex, 4, 1> Matrix1dc; + +struct dcomparr { + dcomplex arr[10]; +}; + +struct coeffarr { + int arr[10]; +}; + class Encoder { public: int M; diff --git a/src/util.h b/src/util.h deleted file mode 100644 index d2ac39910083f8c7e3a993b67372798f3432c5fa..0000000000000000000000000000000000000000 --- a/src/util.h +++ /dev/null @@ -1,24 +0,0 @@ -#include <eigen3/Eigen/Dense> -#include <complex> - -#ifndef UTIL_H -#define UTIL_H - -#define J dcomplex(0.0,1.0) -#define SIZE 10 - -using namespace std; - -typedef complex<double> dcomplex; -typedef Eigen::Matrix<dcomplex, 4, 4> Matrix4dc; -typedef Eigen::Matrix<dcomplex, 4, 1> Matrix1dc; - -struct dcomparr { - dcomplex arr[10]; -}; - -struct coeffarr { - int arr[10]; -}; - -#endif \ No newline at end of file