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