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