This is an automated email from the ASF dual-hosted git repository.

sandreoli pushed a commit to branch issue51
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-c.git

commit afeb64e2a675161de42227c606e8a0dd1e1d88f1
Author: samuele-andreoli <[email protected]>
AuthorDate: Thu Nov 28 15:13:16 2019 +0000

    change paillier API to use private/public key
---
 benchmark/benchtest_paillier.c.in |  78 ++-------
 config.mk                         |   2 +-
 examples/example_paillier.c       | 101 +++--------
 include/paillier.h                |  60 ++++---
 src/paillier.c                    | 191 ++++++++++-----------
 test/test_paillier_add.c          |  68 +++-----
 test/test_paillier_consistency.c  | 142 +++++++---------
 test/test_paillier_decrypt.c      |  88 ++++------
 test/test_paillier_encrypt.c      |  98 +++++------
 test/test_paillier_keygen.c       | 344 +++++++++++++-------------------------
 test/test_paillier_mult.c         |  68 +++-----
 11 files changed, 470 insertions(+), 770 deletions(-)

diff --git a/benchmark/benchtest_paillier.c.in 
b/benchmark/benchtest_paillier.c.in
index 2e5a2ec..5511b5d 100644
--- a/benchmark/benchtest_paillier.c.in
+++ b/benchmark/benchtest_paillier.c.in
@@ -110,32 +110,13 @@ static void print_system_info()
 
 int paillier(csprng *RNG)
 {
-    int rc;
-
     int iterations;
     clock_t start;
     double elapsed;
 
-    char p[FS_2048];
-    octet P = {0,sizeof(p),p};
-    char q[FS_2048];
-    octet Q = {0,sizeof(q),q};
-
-    char p1[FS_2048];
-    octet P1 = {0,sizeof(p1),p1};
-    char q1[FS_2048];
-    octet Q1 = {0,sizeof(q1),q1};
-
-    char n[FS_2048] = {0};
-    octet N = {0,sizeof(n),n};
-    char g[FS_2048];
-    octet G = {0,sizeof(g),g};
-
-    char l[FS_2048] = {0};
-    octet L = {0,sizeof(l),l};
-
-    char m[FS_2048] = {0};
-    octet M = {0,sizeof(m),m};
+    // Key material
+    PAILLIER_private_key PRIV;
+    PAILLIER_public_key PUB;
 
     // Plaintext to encrypt
     char ptin[NTHREADS][FS_2048];
@@ -172,30 +153,25 @@ int paillier(csprng *RNG)
     // Initialize octets
     for(int i=0; i<NTHREADS; i++)
     {
-        memset(ptin[i], 0, FS_2048*sizeof(ptin[i][0]));
         PTIN[i].max = FS_2048;
-        PTIN[i].len = 0;
         PTIN[i].val = ptin[i];
+        OCT_clear(&PTIN[i]);
 
-        memset(ptout[i], 0, FS_2048*sizeof(ptout[i][0]));
         PTOUT[i].max = FS_2048;
-        PTOUT[i].len = 0;
         PTOUT[i].val = ptout[i];
+        OCT_clear(&PTOUT[i]);
 
-        memset(ptko[i], 0, FS_2048*sizeof(ptko[i][0]));
         PTK[i].max = FS_2048;
-        PTK[i].len = 0;
         PTK[i].val = ptko[i];
+        OCT_clear(&PTIN[i]);
 
-        memset(cto[i], 0, FS_4096*sizeof(cto[i][0]));
         CT[i].max = FS_4096;
-        CT[i].len = 0;
         CT[i].val = cto[i];
+        OCT_clear(&PTIN[i]);
 
-        memset(cta[i], 0, FS_4096*sizeof(cta[i][0]));
         CTA[i].max = FS_4096;
-        CTA[i].len = 0;
         CTA[i].val = cta[i];
+        OCT_clear(&PTIN[i]);
     }
 
     printf("Timing info\n");
@@ -206,7 +182,7 @@ int paillier(csprng *RNG)
     start=clock();
     do
     {
-        PAILLIER_KEY_PAIR(RNG, &P, &Q, &N, &G, &L, &M);
+        PAILLIER_KEY_PAIR(RNG, NULL, NULL,&PUB, &PRIV);
         iterations++;
         elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
     }
@@ -232,7 +208,7 @@ int paillier(csprng *RNG)
     start=clock();
     do
     {
-        PAILLIER_ENCRYPT(RNG, &N, &G, &PTIN[0], &CT[0], NULL);
+        PAILLIER_ENCRYPT(RNG, &PUB, &PTIN[0], &CT[0], NULL);
         iterations++;
         elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
     }
@@ -241,19 +217,14 @@ int paillier(csprng *RNG)
     printf("PAILLIER_ENCRYPT\t%8d iterations\t",iterations);
     printf("%8.2lf ms per iteration\n",elapsed);
 
-    rc = PAILLIER_ENCRYPT(RNG, &N, &G, &PTIN[1], &CT[1], NULL);
-    if (rc)
-    {
-        fprintf(stderr, "ERROR PAILLIER_ENCRYPT rc: %d\n", rc);
-        exit(EXIT_FAILURE);
-    }
+    PAILLIER_ENCRYPT(RNG, &PUB, &PTIN[1], &CT[1], NULL);
 
     // Multiple by constant
     iterations=0;
     start=clock();
     do
     {
-        PAILLIER_MULT(&N, &CT[0], &PTK[0], &CTA[0]);
+        PAILLIER_MULT(&PUB, &CT[0], &PTK[0], &CTA[0]);
         iterations++;
         elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
     }
@@ -262,19 +233,14 @@ int paillier(csprng *RNG)
     printf("PAILLIER_MULT\t\t%8d iterations\t",iterations);
     printf("%8.2lf ms per iteration\n",elapsed);
 
-    rc = PAILLIER_MULT(&N, &CT[1], &PTK[1], &CTA[1]);
-    if (rc)
-    {
-        fprintf(stderr, "ERROR PAILLIER_MULT rc: %d\n", rc);
-        exit(EXIT_FAILURE);
-    }
+    PAILLIER_MULT(&PUB, &CT[1], &PTK[1], &CTA[1]);
 
     // Homomorphic addition
     iterations=0;
     start=clock();
     do
     {
-        PAILLIER_ADD(&N, &CTA[0], &CTA[1], &CT3);
+        PAILLIER_ADD(&PUB, &CTA[0], &CTA[1], &CT3);
         iterations++;
         elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
     }
@@ -288,7 +254,7 @@ int paillier(csprng *RNG)
     start=clock();
     do
     {
-        PAILLIER_DECRYPT(&N, &L, &M, &CT3, &PT3);
+        PAILLIER_DECRYPT(&PRIV, &CT3, &PT3);
         iterations++;
         elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
     }
@@ -312,22 +278,14 @@ int paillier(csprng *RNG)
     printf("\n");
 #endif
 
-    OCT_clear(&P);
-    OCT_clear(&Q);
-    OCT_clear(&P1);
-    OCT_clear(&Q1);
-    OCT_clear(&N);
-    OCT_clear(&G);
-    OCT_clear(&L);
-    OCT_clear(&M);
-    OCT_clear(&CT3);
+    // Clean sensitive memory
+    PAILLIER_PRIVATE_KEY_KILL(&PRIV);
+
     OCT_clear(&PT3);
     for(int i=0; i<NTHREADS; i++)
     {
         OCT_clear(&PTIN[i]);
         OCT_clear(&PTOUT[i]);
-        OCT_clear(&CT[i]);
-        OCT_clear(&CTA[i]);
     }
     return 0;
 }
diff --git a/config.mk b/config.mk
index bdbc4cd..18467bb 100644
--- a/config.mk
+++ b/config.mk
@@ -6,8 +6,8 @@ WORD_SIZE:=64
 # Current choice of Elliptic Curve ANSSI C25519 NIST521 BLS24 C41417 NUMS256E 
BLS381 ED25519 NUMS256W BLS383 FP256BN NUMS384E BLS461 FP512BN NUMS384W BLS48 
GOLDILOCKS NUMS512E BN254 HIFIVE NUMS512W BN254CX NIST256 SECP256K1 BRAINPOOL 
NIST384
 AMCL_CURVE:=ED25519,NIST256,GOLDILOCKS,BLS381
 
-# RSA security level: 2048 3072 4096 (8192 for Paillier)
 AMCL_RSA:=2048,4096
+# RSA security level: 2048 3072 4096
 
 # Build type Debug Release Coverage ASan Check CheckFull
 CMAKE_BUILD_TYPE:=Release
diff --git a/examples/example_paillier.c b/examples/example_paillier.c
index b293724..d51b174 100644
--- a/examples/example_paillier.c
+++ b/examples/example_paillier.c
@@ -35,22 +35,9 @@ under the License.
 
 int paillier(csprng *RNG)
 {
-    int rc;
-    char p[FS_2048];
-    octet P = {0,sizeof(p),p};
-    char q[FS_2048];
-    octet Q = {0,sizeof(q),q};
-
-    char n[FS_2048] = {0};
-    octet N = {0,sizeof(n),n};
-    char g[FS_2048];
-    octet G = {0,sizeof(g),g};
-
-    char l[FS_2048] = {0};
-    octet L = {0,sizeof(l),l};
-
-    char m[FS_2048] = {0};
-    octet M = {0,sizeof(m),m};
+    // Key material
+    PAILLIER_private_key PRIV;
+    PAILLIER_public_key PUB;
 
     // Plaintext to encrypt
     char ptin[NTHREADS][FS_2048];
@@ -85,61 +72,51 @@ int paillier(csprng *RNG)
     // Initialize octets
     for(int i=0; i<NTHREADS; i++)
     {
-        memset(ptin[i], 0, FS_2048*sizeof(ptin[i][0]));
         PTIN[i].max = FS_2048;
-        PTIN[i].len = 0;
         PTIN[i].val = ptin[i];
+        OCT_clear(&PTIN[i]);
 
-        memset(ptout[i], 0, FS_2048*sizeof(ptout[i][0]));
         PTOUT[i].max = FS_2048;
-        PTOUT[i].len = 0;
         PTOUT[i].val = ptout[i];
+        OCT_clear(&PTOUT[i]);
 
-        memset(ptko[i], 0, FS_2048*sizeof(ptko[i][0]));
         PTK[i].max = FS_2048;
-        PTK[i].len = 0;
         PTK[i].val = ptko[i];
+        OCT_clear(&PTIN[i]);
 
-        memset(cto[i], 0, FS_4096*sizeof(cto[i][0]));
         CT[i].max = FS_4096;
-        CT[i].len = 0;
         CT[i].val = cto[i];
+        OCT_clear(&PTIN[i]);
 
-        memset(cta[i], 0, FS_4096*sizeof(cta[i][0]));
         CTA[i].max = FS_4096;
-        CTA[i].len = 0;
         CTA[i].val = cta[i];
+        OCT_clear(&PTIN[i]);
     }
 
     printf("Generating public/private key pair\n");
-    rc = PAILLIER_KEY_PAIR(RNG, &P, &Q, &N, &G, &L, &M);
-    if (rc)
-    {
-        fprintf(stderr, "ERROR PAILLIER_KEY_PAIR rc: %d\n", rc);
-        exit(EXIT_FAILURE);
-    }
+    PAILLIER_KEY_PAIR(RNG, NULL, NULL, &PUB, &PRIV);
 
     printf("P: ");
-    OCT_output(&P);
+    FF_4096_output(PRIV.p, HFLEN_4096/2);
     printf("\n");
     printf("Q: ");
-    OCT_output(&Q);
+    FF_4096_output(PRIV.q, HFLEN_4096/2);
     printf("\n");
 
     printf("Public Key \n");
     printf("N: ");
-    OCT_output(&N);
+    FF_4096_output(PRIV.n, HFLEN_4096);
     printf("\n");
     printf("G: ");
-    OCT_output(&G);
+    FF_4096_output(PRIV.g, FFLEN_4096);
     printf("\n");
 
     printf("Secret Key \n");
     printf("L: ");
-    OCT_output(&L);
+    FF_4096_output(PRIV.l, HFLEN_4096);
     printf("\n");
     printf("M: ");
-    OCT_output(&M);
+    FF_4096_output(PRIV.m, HFLEN_4096);
     printf("\n");
 
     // Set plaintext values
@@ -164,12 +141,7 @@ int paillier(csprng *RNG)
     // Encrypt plaintext
     for(int i=0; i<NTHREADS; i++)
     {
-        rc = PAILLIER_ENCRYPT(RNG, &N, &G, &PTIN[i], &CT[i], NULL);
-        if (rc)
-        {
-            fprintf(stderr, "ERROR PAILLIER_ENCRYPT rc: %d\n", rc);
-            exit(EXIT_FAILURE);
-        }
+        PAILLIER_ENCRYPT(RNG, &PUB, &PTIN[i], &CT[i], NULL);
     }
 
     for(int i=0; i<NTHREADS; i++)
@@ -182,12 +154,7 @@ int paillier(csprng *RNG)
     // Decrypt ciphertexts
     for(int i=0; i<NTHREADS; i++)
     {
-        rc = PAILLIER_DECRYPT(&N, &L, &M, &CT[i], &PTOUT[i]);
-        if (rc)
-        {
-            fprintf(stderr, "ERROR PAILLIER_DECRYPT rc: %d\n", rc);
-            exit(EXIT_FAILURE);
-        }
+        PAILLIER_DECRYPT(&PRIV, &CT[i], &PTOUT[i]);
     }
 
     for(int i=0; i<NTHREADS; i++)
@@ -199,20 +166,10 @@ int paillier(csprng *RNG)
 
     for(int i=0; i<NTHREADS; i++)
     {
-        rc = PAILLIER_MULT(&N, &CT[i], &PTK[i], &CTA[i]);
-        if (rc)
-        {
-            fprintf(stderr, "ERROR PAILLIER_MULT rc: %d\n", rc);
-            exit(EXIT_FAILURE);
-        }
+        PAILLIER_MULT(&PUB, &CT[i], &PTK[i], &CTA[i]);
     }
 
-    rc = PAILLIER_ADD(&N, &CTA[0], &CTA[1], &CT3);
-    if (rc)
-    {
-        fprintf(stderr, "ERROR PAILLIER_ADD rc: %d\n", rc);
-        exit(EXIT_FAILURE);
-    }
+    PAILLIER_ADD(&PUB, &CTA[0], &CTA[1], &CT3);
 
     for(int i=0; i<NTHREADS; i++)
     {
@@ -224,32 +181,22 @@ int paillier(csprng *RNG)
     OCT_output(&CT3);
     printf("\n");
 
-    rc = PAILLIER_DECRYPT(&N, &L, &M, &CT3, &PT3);
-    if (rc)
-    {
-        fprintf(stderr, "ERROR PAILLIER_DECRYPT rc: %d\n", rc);
-        exit(EXIT_FAILURE);
-    }
+    PAILLIER_DECRYPT(&PRIV, &CT3, &PT3);
 
     printf("PT3: ");
     OCT_output(&PT3);
     printf("\n");
 
-    OCT_clear(&P);
-    OCT_clear(&Q);
-    OCT_clear(&N);
-    OCT_clear(&G);
-    OCT_clear(&L);
-    OCT_clear(&M);
-    OCT_clear(&CT3);
+    // Clear sensitive memory
+    PAILLIER_PRIVATE_KEY_KILL(&PRIV);
+
     OCT_clear(&PT3);
     for(int i=0; i<NTHREADS; i++)
     {
         OCT_clear(&PTIN[i]);
         OCT_clear(&PTOUT[i]);
-        OCT_clear(&CT[i]);
-        OCT_clear(&CTA[i]);
     }
+
     return 0;
 }
 
diff --git a/include/paillier.h b/include/paillier.h
index 8072370..7ba9592 100644
--- a/include/paillier.h
+++ b/include/paillier.h
@@ -38,6 +38,29 @@ under the License.
 #define HFS_4096 MODBYTES_512_60*HFLEN_4096   /**< Half 4096 field size in 
bytes */
 #define HFS_2048 MODBYTES_1024_58*HFLEN_2048  /**< Half 2048 field size in 
bytes */
 
+/*!
+ * \brief Paillier Public Key
+ */
+typedef struct{
+    BIG_512_60 n[FFLEN_4096]; /**< Paillier Modulus - n = pq */
+    BIG_512_60 g[FFLEN_4096]; /**< Public Base - n+1 */
+
+    BIG_512_60 n2[FFLEN_4096]; /**< Precomputed n^2 */
+}PAILLIER_public_key;
+
+/*!
+ * \brief Paillier Private Key
+ */
+typedef struct{
+    BIG_512_60 n[FFLEN_4096]; /**< Paillier Modulus - n = pq*/
+    BIG_512_60 g[FFLEN_4096]; /**< Public Base - n+1 */
+    BIG_512_60 l[FFLEN_4096]; /**< Private Key (Euler totient of n) */
+    BIG_512_60 m[FFLEN_4096]; /**< Precomputed l^(-1) */
+
+    BIG_512_60 p[HFLEN_4096];  /**< Secret Prime */
+    BIG_512_60 q[HFLEN_4096];  /**< Secret Prime */
+    BIG_512_60 n2[FFLEN_4096]; /**< Precomputed n^2 */
+}PAILLIER_private_key;
 
 /*! \brief Generate the key pair
  *
@@ -53,13 +76,16 @@ under the License.
  *  @param  RNG              Pointer to a cryptographically secure random 
number generator
  *  @param  P                Prime number. If RNG is NULL then this value is 
read
  *  @param  Q                Prime number. If RNG is NULL then this value is 
read
- *  @param  N                Public key (see above)
- *  @param  G                Public key (see above)
- *  @param  L                Private key (see above)
- *  @param  M                Private key (see above)
- *  @return                  Returns 0 or else error code
+ *  @param  PUB              Public key
+ *  @param  PRIV             Private key
  */
-int PAILLIER_KEY_PAIR(csprng *RNG, octet *P, octet* Q, octet* N, octet* G, 
octet* L, octet* M);
+void PAILLIER_KEY_PAIR(csprng *RNG, octet *P, octet* Q, PAILLIER_public_key 
*PUB, PAILLIER_private_key *PRIV);
+
+/*! \brief Clear private key
+ *
+ *  @param PRIV             Private key to clean
+ */
+void PAILLIER_PRIVATE_KEY_KILL(PAILLIER_private_key *PRIV);
 
 /*! \brief Encrypt a plaintext
  *
@@ -72,14 +98,12 @@ int PAILLIER_KEY_PAIR(csprng *RNG, octet *P, octet* Q, 
octet* N, octet* G, octet
  *  </ol>
  *
  *  @param  RNG              Pointer to a cryptographically secure random 
number generator
- *  @param  N                Public key
- *  @param  G                Public key (see above)
+ *  @param  PUB              Public key
  *  @param  PT               Plaintext
  *  @param  CT               Ciphertext
  *  @param  R                R value for testing. If RNG is NULL then this 
value is read.
- *  @return                  Returns 0 or else error code
  */
-int PAILLIER_ENCRYPT(csprng *RNG, octet* N, octet* G, octet* PT, octet* CT, 
octet* R);
+void PAILLIER_ENCRYPT(csprng *RNG, PAILLIER_public_key *PUB, octet* PT, octet* 
CT, octet* R);
 
 /*! \brief Decrypt ciphertext
  *
@@ -92,14 +116,11 @@ int PAILLIER_ENCRYPT(csprng *RNG, octet* N, octet* G, 
octet* PT, octet* CT, octe
  *  <li> \f$ pt = ctln * m \pmod{n} \f$
  *  </ol>
  *
- *  @param   N                Public key
- *  @param   L                Private key (see above)
- *  @param   M                Private key (see above)
+ *  @param   PRIV             Private key
  *  @param   CT               Ciphertext
  *  @param   PT               Plaintext
- *  @return                   Returns 0 or else error code
  */
-int PAILLIER_DECRYPT(octet* N, octet* L, octet* M, octet* CT, octet* PT);
+void PAILLIER_DECRYPT(PAILLIER_private_key *PRIV, octet* CT, octet* PT);
 
 /*! \brief Homomorphic addition of plaintexts
  *
@@ -109,13 +130,13 @@ int PAILLIER_DECRYPT(octet* N, octet* L, octet* M, octet* 
CT, octet* PT);
  *  <li> \f$ ct = ct1*ct2 \pmod{n^2} \f$
  *  </ol>
  *
- *  @param   N                Public key
+ *  @param   PUB              Public key
  *  @param   CT1              Ciphertext one
  *  @param   CT2              Ciphertext two
  *  @param   CT               Ciphertext
  *  @return                   Returns 0 or else error code
  */
-int PAILLIER_ADD(octet* N, octet* CT1, octet* CT2, octet* CT);
+void PAILLIER_ADD(PAILLIER_public_key *PUB, octet* CT1, octet* CT2, octet* CT);
 
 /*! \brief Homomorphic multipication of plaintexts
  *
@@ -125,10 +146,9 @@ int PAILLIER_ADD(octet* N, octet* CT1, octet* CT2, octet* 
CT);
  *  <li> \f$ ct = ct1^{m2} \pmod{n^2} \f$
  *  </ol>
  *
- *  @param   N                Public key
+ *  @param   PUB              Public key
  *  @param   CT1              Ciphertext one
  *  @param   PT               Plaintext constant
  *  @param   CT               Ciphertext
- *  @return                   Returns 0 or else error code
  */
-int PAILLIER_MULT(octet* N, octet* CT1, octet* PT, octet* CT);
+void PAILLIER_MULT(PAILLIER_public_key *PUB, octet* CT1, octet* PT, octet* CT);
diff --git a/src/paillier.c b/src/paillier.c
index ddf25be..aa3a5c5 100644
--- a/src/paillier.c
+++ b/src/paillier.c
@@ -27,7 +27,7 @@ under the License.
 #include "ff_2048.h"
 #include "paillier.h"
 
-int FF_4096_divide(BIG_512_60 x[], BIG_512_60 y[], BIG_512_60 z[])
+void FF_4096_divide(BIG_512_60 x[], BIG_512_60 y[], BIG_512_60 z[])
 {
     BIG_512_60 d[FFLEN_4096];
     BIG_512_60 q[FFLEN_4096];
@@ -61,12 +61,10 @@ int FF_4096_divide(BIG_512_60 x[], BIG_512_60 y[], 
BIG_512_60 z[])
         // z = z + q i.e. update quotient
         FF_4096_add(z,z,q,FFLEN_4096);
     }
-
-    return 0;
 }
 
 /* generate a Paillier key pair */
-int PAILLIER_KEY_PAIR(csprng *RNG, octet *P, octet* Q, octet* N, octet* G, 
octet* L, octet* M)
+void PAILLIER_KEY_PAIR(csprng *RNG, octet *P, octet* Q, PAILLIER_public_key 
*PUB, PAILLIER_private_key *PRIV)
 {
     BIG_1024_58 p[HFLEN_2048];
     BIG_1024_58 q[HFLEN_2048];
@@ -131,18 +129,49 @@ int PAILLIER_KEY_PAIR(csprng *RNG, octet *P, octet* Q, 
octet* N, octet* G, octet
     FF_2048_inc(p,1,HFLEN_2048);
     FF_2048_inc(q,1,HFLEN_2048);
 
-    // Output
-    if (P != NULL)
-        FF_2048_toOctet(P, p, HFLEN_2048);
 
-    if (Q != NULL)
-        FF_2048_toOctet(Q, q, HFLEN_2048);
+    // Output Private Key
+    char oct[FS_2048];
+    octet OCT = {0,FS_2048, oct};
+
+    FF_2048_toOctet(&OCT, p, HFLEN_2048);
+    OCT_pad(&OCT,HFS_4096);
+    FF_4096_fromOctet(PRIV->p, &OCT, HFLEN_4096);
+    OCT_empty(&OCT);
+
+    FF_2048_toOctet(&OCT, q, HFLEN_2048);
+    OCT_pad(&OCT,HFS_4096);
+    FF_4096_fromOctet(PRIV->q, &OCT, HFLEN_4096);
+    OCT_empty(&OCT);
+
+    FF_2048_toOctet(&OCT, n, FFLEN_2048);
+    FF_4096_zero(PRIV->n, FFLEN_4096);
+    FF_4096_fromOctet(PRIV->n, &OCT, HFLEN_4096);
+    OCT_empty(&OCT);
 
-    FF_2048_toOctet(N, n, FFLEN_2048);
-    FF_2048_toOctet(G, g, FFLEN_2048);
+    FF_2048_toOctet(&OCT, g, FFLEN_2048);
+    FF_4096_zero(PRIV->g, FFLEN_4096);
+    FF_4096_fromOctet(PRIV->g, &OCT, HFLEN_4096);
+    OCT_empty(&OCT);
 
-    FF_2048_toOctet(L, l, FFLEN_2048);
-    FF_2048_toOctet(M, m, FFLEN_2048);
+    FF_2048_toOctet(&OCT, l, FFLEN_2048);
+    FF_4096_zero(PRIV->l, FFLEN_4096);
+    FF_4096_fromOctet(PRIV->l, &OCT, HFLEN_4096);
+    OCT_empty(&OCT);
+
+    FF_2048_toOctet(&OCT, m, FFLEN_2048);
+    FF_4096_zero(PRIV->m, FFLEN_4096);
+    FF_4096_fromOctet(PRIV->m, &OCT, HFLEN_4096);
+    OCT_empty(&OCT);
+
+    // Precompute n^2
+    FF_4096_sqr(PRIV->n2, PRIV->n, HFLEN_4096);
+    FF_4096_norm(PRIV->n2, FFLEN_4096);
+
+    // Output Public Key
+    FF_4096_copy(PUB->n , PRIV->n , FFLEN_4096);
+    FF_4096_copy(PUB->g , PRIV->g , FFLEN_4096);
+    FF_4096_copy(PUB->n2, PRIV->n2, FFLEN_4096);
 
 #ifdef DEBUG
     printf("p ");
@@ -167,21 +196,27 @@ int PAILLIER_KEY_PAIR(csprng *RNG, octet *P, octet* Q, 
octet* N, octet* G, octet
     printf("\n");
 #endif
 
-    return 0;
+    // Clean secret keys from memory
+    FF_2048_zero(p,HFLEN_2048);
+    FF_2048_zero(q,HFLEN_2048);
+    FF_2048_zero(l,FFLEN_2048);
+    FF_2048_zero(m,FFLEN_2048);
+}
+
+/* Clean secrets from private key */
+void PAILLIER_PRIVATE_KEY_KILL(PAILLIER_private_key *PRIV)
+{
+    FF_4096_zero(PRIV->l, FFLEN_4096);
+    FF_4096_zero(PRIV->m, FFLEN_4096);
+    FF_4096_zero(PRIV->p, HFLEN_4096/2);
+    FF_4096_zero(PRIV->q, HFLEN_4096/2);
 }
 
 /* Paillier encrypt
  R is for testing
 */
-int PAILLIER_ENCRYPT(csprng *RNG, octet* N, octet* G, octet* PT, octet* CT, 
octet* R)
+void PAILLIER_ENCRYPT(csprng *RNG, PAILLIER_public_key *PUB, octet* PT, octet* 
CT, octet* R)
 {
-    // Public key
-    BIG_512_60 n[FFLEN_4096];
-    BIG_512_60 g[FFLEN_4096];
-
-    // n2 = n^2
-    BIG_512_60 n2[FFLEN_4096];
-
     // Random r < n
     BIG_512_60 r[FFLEN_4096];
 
@@ -191,23 +226,13 @@ int PAILLIER_ENCRYPT(csprng *RNG, octet* N, octet* G, 
octet* PT, octet* CT, octe
     // ciphertext
     BIG_512_60 ct[FFLEN_4096];
 
-    FF_4096_zero(n, FFLEN_4096);
-    FF_4096_fromOctet(n,N,HFLEN_4096);
-
-    FF_4096_zero(g, FFLEN_4096);
-    FF_4096_fromOctet(g,G,HFLEN_4096);
-
     FF_4096_zero(pt, FFLEN_4096);
     FF_4096_fromOctet(pt,PT,HFLEN_4096);
 
-    // n2 = n^2
-    FF_4096_sqr(n2, n, HFLEN_4096);
-    FF_4096_norm(n2, FFLEN_4096);
-
     // In production generate R from RNG
     if (RNG!=NULL)
     {
-        FF_4096_randomnum(r,n2,RNG,FFLEN_4096);
+        FF_4096_randomnum(r,PUB->n2,RNG,FFLEN_4096);
     }
     else
     {
@@ -215,7 +240,7 @@ int PAILLIER_ENCRYPT(csprng *RNG, octet* N, octet* G, 
octet* PT, octet* CT, octe
     }
 
     // ct = g^pt * r^n mod n2
-    FF_4096_skpow2(ct, g, pt, r, n, n2, FFLEN_4096);
+    FF_4096_skpow2(ct, PUB->g, pt, r, PUB->n, PUB->n2, FFLEN_4096);
 
     // Output
     FF_4096_toOctet(CT, ct, FFLEN_4096);
@@ -228,13 +253,13 @@ int PAILLIER_ENCRYPT(csprng *RNG, octet* N, octet* G, 
octet* PT, octet* CT, octe
 
 #ifdef DEBUG
     printf("n ");
-    FF_4096_output(n,FFLEN_4096);
+    FF_4096_output(PUB->n,FFLEN_4096);
     printf("\n\n");
     printf("g ");
-    FF_4096_output(g,FFLEN_4096);
+    FF_4096_output(PUB->g,FFLEN_4096);
     printf("\n\n");
     printf("n2 ");
-    FF_4096_output(n2,FFLEN_4096);
+    FF_4096_output(PUB->n2,FFLEN_4096);
     printf("\n\n");
     printf("r ");
     FF_4096_output(r,FFLEN_4096);
@@ -250,51 +275,29 @@ int PAILLIER_ENCRYPT(csprng *RNG, octet* N, octet* G, 
octet* PT, octet* CT, octe
     printf("\n");
 #endif
 
-    return 0;
+    // Clean memory
+    FF_4096_zero(pt, HFLEN_4096);
 }
 
 /* Paillier decrypt */
-int PAILLIER_DECRYPT(octet* N, octet* L, octet* M, octet* CT, octet* PT)
+void PAILLIER_DECRYPT(PAILLIER_private_key *PRIV, octet* CT, octet* PT)
 {
-    // Public key
-    BIG_512_60 n[FFLEN_4096];
-
-    // secret key
-    BIG_512_60 l[FFLEN_4096];
-    BIG_512_60 m[FFLEN_4096];
-
-    // Ciphertext
+       // Ciphertext
     BIG_512_60 ct[FFLEN_4096];
 
     // Plaintext
     BIG_512_60 pt[FFLEN_4096];
 
-    // n2 = n^2
-    BIG_512_60 n2[FFLEN_4096];
-
     // ctl = ct^l mod n^2
     BIG_512_60 ctl[FFLEN_4096];
 
     // ctln = ctl / n
     BIG_512_60 ctln[FFLEN_4096];
 
-    FF_4096_zero(n, FFLEN_4096);
-    FF_4096_fromOctet(n,N,HFLEN_4096);
-
-    FF_4096_zero(l, FFLEN_4096);
-    FF_4096_fromOctet(l,L,HFLEN_4096);
-
-    FF_4096_zero(m, FFLEN_4096);
-    FF_4096_fromOctet(m,M,HFLEN_4096);
-
     FF_4096_fromOctet(ct,CT,FFLEN_4096);
 
-    // n2 = n^2
-    FF_4096_sqr(n2, n, HFLEN_4096);
-    FF_4096_norm(n2, FFLEN_4096);
-
     // ct^l mod n^2 - 1
-    FF_4096_skpow(ctl,ct,l,n2,FFLEN_4096);
+    FF_4096_skpow(ctl,ct,PRIV->l,PRIV->n2,FFLEN_4096);
     FF_4096_dec(ctl,1,FFLEN_4096);
 
 #ifdef DEBUG
@@ -306,31 +309,31 @@ int PAILLIER_DECRYPT(octet* N, octet* L, octet* M, octet* 
CT, octet* PT)
     // ctln = ctl / n
     // note that ctln fits into a FF_2048 element,
     // since ctln = ctl/n < n^2 / n = n
-    FF_4096_divide(n, ctl, ctln);
+    FF_4096_divide(PRIV->n, ctl, ctln);
 
     // pt = ctln * m mod n
     // the result fits into a FF_4096 element,
     // since both m and ctln fit into a FF_2048 element
-    FF_4096_mul(pt, ctln, m, HFLEN_4096);
+    FF_4096_mul(pt, ctln, PRIV->m, HFLEN_4096);
 #ifdef DEBUG
     printf("pt1 ");
     FF_4096_output(pt,FFLEN_4096);
     printf("\n\n");
 #endif
-    FF_4096_mod(pt,n,FFLEN_4096);
+    FF_4096_mod(pt,PRIV->n,FFLEN_4096);
 
     // Output
     FF_4096_toOctet(PT, pt, HFLEN_4096);
 
 #ifdef DEBUG
     printf("PAILLIER_DECRYPT n ");
-    FF_4096_output(n,FFLEN_4096);
+    FF_4096_output(PRIV->n,FFLEN_4096);
     printf("\n\n");
     printf("PAILLIER_DECRYPT l ");
-    FF_4096_output(l,FFLEN_4096);
+    FF_4096_output(PRIV->l,FFLEN_4096);
     printf("\n\n");
     printf("PAILLIER_DECRYPT m ");
-    FF_4096_output(m,FFLEN_4096);
+    FF_4096_output(PRIV->m,FFLEN_4096);
     printf("\n\n");
     printf("PAILLIER_DECRYPT ct ");
     FF_4096_output(ct,FFLEN_4096);
@@ -343,8 +346,10 @@ int PAILLIER_DECRYPT(octet* N, octet* L, octet* M, octet* 
CT, octet* PT)
     printf("\n\n");
 #endif
 
-    return 0;
-
+    // Clean memory
+    FF_4096_zero(ctl, FFLEN_4096);
+    FF_4096_zero(ctln, FFLEN_4096);
+    FF_4096_zero(pt, HFLEN_4096);
 }
 
 /* Homomorphic addition of plaintexts */
@@ -352,27 +357,16 @@ int PAILLIER_DECRYPT(octet* N, octet* L, octet* M, octet* 
CT, octet* PT)
     ct = ct1 * ct2
     ct = ct % n2
 */
-int PAILLIER_ADD(octet* N, octet* CT1, octet* CT2, octet* CT)
+void PAILLIER_ADD(PAILLIER_public_key *PUB, octet* CT1, octet* CT2, octet* CT)
 {
-    // Public key
-    BIG_512_60 n[HFLEN_4096];
-
-    // n2 = n^2
-    BIG_512_60 n2[FFLEN_4096];
-
     // ciphertext
     BIG_512_60 ct1[FFLEN_4096];
     BIG_512_60 ct2[FFLEN_4096];
     BIG_512_60 ct[2 * FFLEN_4096];
 
-    FF_4096_fromOctet(n,N,HFLEN_4096);
     FF_4096_fromOctet(ct1,CT1,FFLEN_4096);
     FF_4096_fromOctet(ct2,CT2,FFLEN_4096);
 
-    // n2 = n^2
-    FF_4096_sqr(n2, n, HFLEN_4096);
-    FF_4096_norm(n2, FFLEN_4096);
-
 #ifdef DEBUG
     printf("PAILLIER_ADD ct1 ");
     FF_4096_output(ct1,FFLEN_4096);
@@ -391,14 +385,14 @@ int PAILLIER_ADD(octet* N, octet* CT1, octet* CT2, octet* 
CT)
     printf("\n\n");
 #endif
 
-    FF_4096_dmod(ct,ct,n2,FFLEN_4096);
+    FF_4096_dmod(ct,ct,PUB->n2,FFLEN_4096);
 
     // Output
     FF_4096_toOctet(CT, ct, FFLEN_4096);
 
 #ifdef DEBUG
     printf("PAILLIER_ADD n ");
-    FF_4096_output(n,HFLEN_4096);
+    FF_4096_output(PUB->n,HFLEN_4096);
     printf("\n\n");
     printf("PAILLIER_ADD ct1 ");
     FF_4096_output(ct1,FFLEN_4096);
@@ -407,8 +401,6 @@ int PAILLIER_ADD(octet* N, octet* CT1, octet* CT2, octet* 
CT)
     FF_4096_output(ct2,FFLEN_4096);
     printf("\n\n");
 #endif
-
-    return 0;
 }
 
 /* Homomorphic multiplation of plaintext
@@ -416,14 +408,8 @@ int PAILLIER_ADD(octet* N, octet* CT1, octet* CT2, octet* 
CT)
     ct = ct1 ^ pt mod n^2
 
 */
-int PAILLIER_MULT(octet* N, octet* CT1, octet* PT, octet* CT)
+void PAILLIER_MULT(PAILLIER_public_key *PUB, octet* CT1, octet* PT, octet* CT)
 {
-    // Public key
-    BIG_512_60 n[HFLEN_4096];
-
-    // n^2
-    BIG_512_60 n2[FFLEN_4096];
-
     // Ciphertext
     BIG_512_60 ct1[FFLEN_4096];
 
@@ -433,29 +419,23 @@ int PAILLIER_MULT(octet* N, octet* CT1, octet* PT, octet* 
CT)
     // Ciphertext output. ct = ct1 ^ pt mod n^2
     BIG_512_60 ct[FFLEN_4096];
 
-    FF_4096_fromOctet(n,N,HFLEN_4096);
-
     FF_4096_zero(pt, FFLEN_4096);
     FF_4096_fromOctet(pt,PT,HFLEN_4096);
 
     FF_4096_fromOctet(ct1,CT1,FFLEN_4096);
 
-    // n2 = n^2
-    FF_4096_sqr(n2, n, HFLEN_4096);
-    FF_4096_norm(n2, FFLEN_4096);
-
     // ct1^pt mod n^2
-    FF_4096_skpow(ct,ct1,pt,n2,FFLEN_4096);
+    FF_4096_skpow(ct,ct1,pt,PUB->n2,FFLEN_4096);
 
     // output
     FF_4096_toOctet(CT, ct, FFLEN_4096);
 
 #ifdef DEBUG
     printf("PAILLIER_MULT n: ");
-    FF_4096_output(n,HFLEN_4096);
+    FF_4096_output(PUB->n,HFLEN_4096);
     printf("\n\n");
     printf("PAILLIER_MULT n2: ");
-    FF_4096_output(n2,FFLEN_4096);
+    FF_4096_output(PUB->n2,FFLEN_4096);
     printf("\n\n");
     printf("PAILLIER_MULT ct1: ");
     FF_4096_output(ct1,FFLEN_4096);
@@ -468,5 +448,6 @@ int PAILLIER_MULT(octet* N, octet* CT1, octet* PT, octet* 
CT)
     printf("\n\n");
 #endif
 
-    return 0;
+    // Clean memory
+    FF_4096_zero(pt, HFLEN_4096);
 }
diff --git a/test/test_paillier_add.c b/test/test_paillier_add.c
index 7408547..7b1ba93 100644
--- a/test/test_paillier_add.c
+++ b/test/test_paillier_add.c
@@ -41,6 +41,16 @@ void read_OCTET(octet* OCT, char* string)
     OCT_fromHex(OCT,buff);
 }
 
+void read_FF_4096(BIG_512_60 *x, char* string, int n)
+{
+    int len = strlen(string);
+    char oct[len/2];
+    octet OCT = {0, len/2, oct};
+
+    read_OCTET(&OCT, string);
+    FF_4096_fromOctet(x, &OCT, n);
+}
+
 int main(int argc, char** argv)
 {
     if (argc != 2)
@@ -55,20 +65,13 @@ int main(int argc, char** argv)
     char line[LINE_LEN]= {0};
     char *linePtr=NULL;
 
-    int applyVector=0;
-
-    const char* TESTline = "TEST = ";
-    int testNo=0;
-
     char ct[FS_4096]= {0};
     octet CT = {0,sizeof(ct),ct};
 
-    // Test result
-    int result = 0;
-    const char* RESULTline = "RESULT = ";
+    int testNo;
+    const char* TESTline = "TEST = ";
 
-    char ngolden[FS_2048]= {0};
-    octet NGOLDEN = {0,sizeof(ngolden),ngolden};
+    PAILLIER_public_key PUB;
     const char* Nline = "N = ";
 
     char ct1golden[FS_4096]= {0};
@@ -98,7 +101,6 @@ int main(int argc, char** argv)
             len = strlen(TESTline);
             linePtr = line + len;
             sscanf(linePtr,"%d\n",&testNo);
-            printf("TEST = %d\n",testNo);
         }
 
         // Read N
@@ -106,10 +108,14 @@ int main(int argc, char** argv)
         {
             len = strlen(Nline);
             linePtr = line + len;
-            read_OCTET(&NGOLDEN,linePtr);
+            read_FF_4096(PUB.n, linePtr, HFLEN_4096);
+
+            FF_4096_sqr(PUB.n2, PUB.n, HFLEN_4096);
+            FF_4096_norm(PUB.n2, FFLEN_4096);
 #ifdef DEBUG
             printf("N = ");
-            OCT_output(&NGOLDEN);
+            FF_4096_output(PUB.n , FFLEN_4096);
+            printf("\n");
 #endif
         }
 
@@ -137,7 +143,7 @@ int main(int argc, char** argv)
 #endif
         }
 
-        // Read CIPHERTEXT
+        // Read CIPHERTEXT and process test vector
         if (!strncmp(line,CTline, strlen(CTline)))
         {
             len = strlen(CTline);
@@ -147,32 +153,8 @@ int main(int argc, char** argv)
             printf("CIPHERTEXT = ");
             OCT_output(&CTGOLDEN);
 #endif
-        }
-
-        // Read expected result
-        if (!strncmp(line,RESULTline, strlen(RESULTline)))
-        {
-            len = strlen(RESULTline);
-            linePtr = line + len;
-            sscanf(linePtr,"%d\n",&result);
-            applyVector=1;
-#ifdef DEBUG
-            printf("RESULT = %d\n\n", result);
-#endif
-        }
-
-        if (applyVector)
-        {
-            applyVector=0;
-
-            int rc = PAILLIER_ADD(&NGOLDEN, &CT1GOLDEN, &CT2GOLDEN, &CT);
-            if (rc)
-            {
-                fprintf(stderr, "FAILURE PAILLIER_ADD rc: %d\n", rc);
-                fclose(fp);
-                exit(EXIT_FAILURE);
-            }
 
+            PAILLIER_ADD(&PUB, &CT1GOLDEN, &CT2GOLDEN, &CT);
 
 #ifdef DEBUG
             printf("CT: ");
@@ -180,22 +162,22 @@ int main(int argc, char** argv)
             printf("\n");
 #endif
 
-            // OCT_comp return 1 for equal
-            rc = !(OCT_comp(&CTGOLDEN,&CT));
-            if(rc != result)
+            if(!(OCT_comp(&CTGOLDEN,&CT)))
             {
 #ifdef DEBUG
                 printf("CTGOLDEN: ");
                 OCT_output(&CTGOLDEN);
                 printf("\n");
 #endif
-                fprintf(stderr, "FAILURE Test %d rc: %d\n", testNo, rc);
+                fprintf(stderr, "FAILURE Test %d\n", testNo);
                 fclose(fp);
                 exit(EXIT_FAILURE);
             }
         }
     }
+
     fclose(fp);
+
     printf("SUCCESS TEST PAILLIER ADD PASSED\n");
     exit(EXIT_SUCCESS);
 }
diff --git a/test/test_paillier_consistency.c b/test/test_paillier_consistency.c
index b21a1cb..dd8a3c8 100644
--- a/test/test_paillier_consistency.c
+++ b/test/test_paillier_consistency.c
@@ -34,22 +34,11 @@ char* PT3GOLDEN_hex = 
"000000000000000000000000000000000000000000000000000000000
 
 int paillier(csprng *RNG)
 {
-    int rc;
-    char p[FS_2048];
-    octet P = {0,sizeof(p),p};
-    char q[FS_2048];
-    octet Q = {0,sizeof(q),q};
+    BIG_512_60 zero[FFLEN_4096];
 
-    char n[FS_2048] = {0};
-    octet N = {0,sizeof(n),n};
-    char g[FS_2048];
-    octet G = {0,sizeof(g),g};
-
-    char l[FS_2048] = {0};
-    octet L = {0,sizeof(l),l};
-
-    char m[FS_2048] = {0};
-    octet M = {0,sizeof(m),m};
+    // Key material
+    PAILLIER_private_key PRIV;
+    PAILLIER_public_key PUB;
 
     // Plaintext to encrypt
     char ptin[NTHREADS][FS_2048];
@@ -88,62 +77,53 @@ int paillier(csprng *RNG)
     // Initialize octets
     for(int i=0; i<NTHREADS; i++)
     {
-        memset(ptin[i], 0, FS_2048*sizeof(ptin[i][0]));
         PTIN[i].max = FS_2048;
-        PTIN[i].len = 0;
         PTIN[i].val = ptin[i];
+        OCT_clear(&PTIN[i]);
 
-        memset(ptout[i], 0, FS_2048*sizeof(ptout[i][0]));
         PTOUT[i].max = FS_2048;
-        PTOUT[i].len = 0;
         PTOUT[i].val = ptout[i];
+        OCT_clear(&PTOUT[i]);
 
-        memset(ptko[i], 0, FS_2048*sizeof(ptko[i][0]));
         PTK[i].max = FS_2048;
-        PTK[i].len = 0;
         PTK[i].val = ptko[i];
+        OCT_clear(&PTIN[i]);
 
-        memset(cto[i], 0, FS_4096*sizeof(cto[i][0]));
         CT[i].max = FS_4096;
-        CT[i].len = 0;
         CT[i].val = cto[i];
+        OCT_clear(&PTIN[i]);
 
-        memset(cta[i], 0, FS_4096*sizeof(cta[i][0]));
         CTA[i].max = FS_4096;
-        CTA[i].len = 0;
         CTA[i].val = cta[i];
+        OCT_clear(&PTIN[i]);
     }
 
-    printf("Generating public/private key pair\n");
-    rc = PAILLIER_KEY_PAIR(RNG, &P, &Q, &N, &G, &L, &M);
-    if (rc)
-    {
-        fprintf(stderr, "FAILURE PAILLIER_KEY_PAIR rc: %d\n", rc);
-        exit(EXIT_FAILURE);
-    }
+    PAILLIER_KEY_PAIR(RNG, NULL, NULL, &PUB, &PRIV);
 
+#ifdef DEBUG
     printf("P: ");
-    OCT_output(&P);
+    FF_4096_output(PRIV.p, HFLEN_4096);
     printf("\n");
     printf("Q: ");
-    OCT_output(&Q);
+    FF_4096_output(PRIV.q, HFLEN_4096);
     printf("\n");
 
     printf("Public Key \n");
     printf("N: ");
-    OCT_output(&N);
+    FF_4096_output(PUB.n, HFLEN_4096);
     printf("\n");
     printf("G: ");
-    OCT_output(&G);
+    FF_4096_output(PUB.g, HFLEN_4096);
     printf("\n");
 
     printf("Secret Key \n");
     printf("L: ");
-    OCT_output(&L);
+    FF_4096_output(PRIV.l, HFLEN_4096);
     printf("\n");
     printf("M: ");
-    OCT_output(&M);
+    FF_4096_output(PRIV.m, HFLEN_4096);
     printf("\n");
+#endif
 
     // Set plaintext values
     for(int i=0; i<NTHREADS; i++)
@@ -166,66 +146,53 @@ int paillier(csprng *RNG)
 #endif
     }
 
+#ifdef DEBUG
     for(int i=0; i<NTHREADS; i++)
     {
         printf("PTIN[%d] ", i);
         OCT_output(&PTIN[i]);
         printf("\n");
     }
+#endif
 
     // Encrypt plaintext
     for(int i=0; i<NTHREADS; i++)
     {
-        rc = PAILLIER_ENCRYPT(RNG, &N, &G, &PTIN[i], &CT[i], NULL);
-        if (rc)
-        {
-            fprintf(stderr, "FAILURE PAILLIER_ENCRYPT rc: %d\n", rc);
-            exit(EXIT_FAILURE);
-        }
+        PAILLIER_ENCRYPT(RNG, &PUB, &PTIN[i], &CT[i], NULL);
     }
 
+#ifdef DEBUG
     for(int i=0; i<NTHREADS; i++)
     {
         printf("CT[%d] ", i);
         OCT_output(&CT[i]);
         printf("\n");
     }
+#endif
 
     // Decrypt ciphertexts
     for(int i=0; i<NTHREADS; i++)
     {
-        rc = PAILLIER_DECRYPT(&N, &L, &M, &CT[i], &PTOUT[i]);
-        if (rc)
-        {
-            fprintf(stderr, "FAILURE PAILLIER_DECRYPT rc: %d\n", rc);
-            exit(EXIT_FAILURE);
-        }
+        PAILLIER_DECRYPT(&PRIV, &CT[i], &PTOUT[i]);
     }
 
+#ifdef DEBUG
     for(int i=0; i<NTHREADS; i++)
     {
         printf("PTOUT[%d] ", i);
         OCT_output(&PTOUT[i]);
         printf("\n");
     }
+#endif
 
     for(int i=0; i<NTHREADS; i++)
     {
-        rc = PAILLIER_MULT(&N, &CT[i], &PTK[i], &CTA[i]);
-        if (rc)
-        {
-            fprintf(stderr, "FAILURE PAILLIER_MULT rc: %d\n", rc);
-            exit(EXIT_FAILURE);
-        }
+        PAILLIER_MULT(&PUB, &CT[i], &PTK[i], &CTA[i]);
     }
 
-    rc = PAILLIER_ADD(&N, &CTA[0], &CTA[1], &CT3);
-    if (rc)
-    {
-        fprintf(stderr, "FAILURE PAILLIER_ADD rc: %d\n", rc);
-        exit(EXIT_FAILURE);
-    }
+    PAILLIER_ADD(&PUB, &CTA[0], &CTA[1], &CT3);
 
+#ifdef DEBUG
     for(int i=0; i<NTHREADS; i++)
     {
         printf("CTA[%d] ", i);
@@ -235,35 +202,53 @@ int paillier(csprng *RNG)
     printf("CT3: ");
     OCT_output(&CT3);
     printf("\n");
+#endif
 
-    rc = PAILLIER_DECRYPT(&N, &L, &M, &CT3, &PT3);
-    if (rc)
-    {
-        fprintf(stderr, "FAILURE PAILLIER_DECRYPT rc: %d\n", rc);
-        exit(EXIT_FAILURE);
-    }
+    PAILLIER_DECRYPT(&PRIV, &CT3, &PT3);
 
-    OCT_fromHex(&PT3GOLDEN,PT3GOLDEN_hex);
+#ifdef DEBUG
     printf("PT3GOLDEN: ");
     OCT_output(&PT3GOLDEN);
 
     printf("PT3: ");
     OCT_output(&PT3);
     printf("\n");
+#endif
+    OCT_fromHex(&PT3GOLDEN,PT3GOLDEN_hex);
+    if(!OCT_comp(&PT3GOLDEN,&PT3))
+    {
+        fprintf(stderr, "FAILURE PT3 != PT3GOLDEN\n");
+        exit(EXIT_FAILURE);
+    }
+
+    PAILLIER_PRIVATE_KEY_KILL(&PRIV);
+
+    FF_4096_zero(zero, FFLEN_4096);
+
+    if(FF_4096_comp(zero, PRIV.p, HFLEN_4096))
+    {
+        fprintf(stderr, "FAILURE p not cleaned from private key\n");
+        exit(EXIT_FAILURE);
+    }
+
+    if(FF_4096_comp(zero, PRIV.q, HFLEN_4096))
+    {
+        fprintf(stderr, "FAILURE q not cleaned from private key\n");
+        exit(EXIT_FAILURE);
+    }
+
+    if(FF_4096_comp(zero, PRIV.l, FFLEN_4096))
+    {
+        fprintf(stderr, "FAILURE l not cleaned from private key\n");
+        exit(EXIT_FAILURE);
+    }
 
-    rc = OCT_comp(&PT3GOLDEN,&PT3);
-    if(!rc)
+    if(FF_4096_comp(zero, PRIV.m, FFLEN_4096))
     {
-        fprintf(stderr, "FAILURE PT3 != PT3GOLDEN rc: %d\n", rc);
+        fprintf(stderr, "FAILURE m not cleaned from private key\n");
         exit(EXIT_FAILURE);
     }
 
-    OCT_clear(&P);
-    OCT_clear(&Q);
-    OCT_clear(&N);
-    OCT_clear(&G);
-    OCT_clear(&L);
-    OCT_clear(&M);
     OCT_clear(&CT3);
     OCT_clear(&PT3);
     for(int i=0; i<NTHREADS; i++)
@@ -295,7 +280,6 @@ int main()
     // initialise strong RNG
     CREATE_CSPRNG(&RNG,&SEED);
 
-    printf("\nPaillier example\n");
     paillier(&RNG);
 
     KILL_CSPRNG(&RNG);
diff --git a/test/test_paillier_decrypt.c b/test/test_paillier_decrypt.c
index 6f12989..855cb14 100644
--- a/test/test_paillier_decrypt.c
+++ b/test/test_paillier_decrypt.c
@@ -41,6 +41,16 @@ void read_OCTET(octet* OCT, char* string)
     OCT_fromHex(OCT,buff);
 }
 
+void read_FF_4096(BIG_512_60 *x, char* string, int n)
+{
+    int len = strlen(string);
+    char oct[len/2];
+    octet OCT = {0, len/2, oct};
+
+    read_OCTET(&OCT, string);
+    FF_4096_fromOctet(x, &OCT, n);
+}
+
 int main(int argc, char** argv)
 {
     if (argc != 2)
@@ -55,28 +65,15 @@ int main(int argc, char** argv)
     char line[LINE_LEN]= {0};
     char *linePtr=NULL;
 
-    int applyVector=0;
-
-    const char* TESTline = "TEST = ";
-    int testNo=0;
-
-    // Test result
-    int result=0;
-    const char* RESULTline = "RESULT = ";
-
     char pt[FS_2048]= {0};
     octet PT = {0,sizeof(pt),pt};
 
-    char ngolden[FS_2048]= {0};
-    octet NGOLDEN = {0,sizeof(ngolden),ngolden};
-    const char* Nline = "N = ";
+    int testNo=0;
+    const char* TESTline = "TEST = ";
 
-    char lgolden[FS_2048] = {0};
-    octet LGOLDEN = {0,sizeof(lgolden),lgolden};
+    PAILLIER_private_key PRIV;
+    const char* Nline = "N = ";
     const char* Lline = "L = ";
-
-    char mgolden[FS_2048]= {0};
-    octet MGOLDEN = {0,sizeof(mgolden),mgolden};
     const char* Mline = "M = ";
 
     char ptgolden[FS_2048]= {0};
@@ -102,7 +99,6 @@ int main(int argc, char** argv)
             len = strlen(TESTline);
             linePtr = line + len;
             sscanf(linePtr,"%d\n",&testNo);
-            printf("TEST = %d\n",testNo);
         }
 
         // Read N
@@ -110,10 +106,15 @@ int main(int argc, char** argv)
         {
             len = strlen(Nline);
             linePtr = line + len;
-            read_OCTET(&NGOLDEN,linePtr);
+            FF_4096_zero(PRIV.n, FFLEN_4096);
+            read_FF_4096(PRIV.n, linePtr, HFLEN_4096);
+
+            FF_4096_sqr(PRIV.n2,PRIV.n, HFLEN_4096);
+            FF_4096_norm(PRIV.n2, FFLEN_4096);
 #ifdef DEBUG
             printf("N = ");
-            OCT_output(&NGOLDEN);
+            FF_4096_output(PRIV.n , FFLEN_4096);
+            printf("\n");
 #endif
         }
 
@@ -122,10 +123,12 @@ int main(int argc, char** argv)
         {
             len = strlen(Lline);
             linePtr = line + len;
-            read_OCTET(&LGOLDEN,linePtr);
+            FF_4096_zero(PRIV.l, FFLEN_4096);
+            read_FF_4096(PRIV.l, linePtr, HFLEN_4096);
 #ifdef DEBUG
             printf("L = ");
-            OCT_output(&LGOLDEN);
+            FF_4096_output(PRIV.l , FFLEN_4096);
+            printf("\n");
 #endif
         }
 
@@ -134,10 +137,12 @@ int main(int argc, char** argv)
         {
             len = strlen(Mline);
             linePtr = line + len;
-            read_OCTET(&MGOLDEN,linePtr);
+            FF_4096_zero(PRIV.m, FFLEN_4096);
+            read_FF_4096(PRIV.m, linePtr, HFLEN_4096);
 #ifdef DEBUG
             printf("M = ");
-            OCT_output(&MGOLDEN);
+            FF_4096_output(PRIV.m , FFLEN_4096);
+            printf("\n");
 #endif
         }
 
@@ -153,7 +158,7 @@ int main(int argc, char** argv)
 #endif
         }
 
-        // Read PLAINTEXT
+        // Read PLAINTEXT and process test vector
         if (!strncmp(line,PTline, strlen(PTline)))
         {
             len = strlen(PTline);
@@ -163,31 +168,8 @@ int main(int argc, char** argv)
             printf("PLAINTEXT = ");
             OCT_output(&PTGOLDEN);
 #endif
-        }
 
-        // Read expected result
-        if (!strncmp(line,RESULTline, strlen(RESULTline)))
-        {
-            len = strlen(RESULTline);
-            linePtr = line + len;
-            sscanf(linePtr,"%d\n",&result);
-            applyVector=1;
-#ifdef DEBUG
-            printf("RESULT = %d\n\n", result);
-#endif
-        }
-
-        if (applyVector)
-        {
-            applyVector=0;
-
-            int rc = PAILLIER_DECRYPT(&NGOLDEN, &LGOLDEN, &MGOLDEN, &CTGOLDEN, 
&PT);
-            if (rc)
-            {
-                fprintf(stderr, "FAILURE PAILLIER_DECRYPT Test %d rc: %d\n", 
testNo, rc);
-                fclose(fp);
-                exit(EXIT_FAILURE);
-            }
+            PAILLIER_DECRYPT(&PRIV, &CTGOLDEN, &PT);
 
 #ifdef DEBUG
             printf("PT: ");
@@ -195,22 +177,22 @@ int main(int argc, char** argv)
             printf("\n");
 #endif
 
-            // OCT_comp return 1 for equal
-            rc = !(OCT_comp(&PTGOLDEN,&PT));
-            if(rc != result)
+            if(!OCT_comp(&PTGOLDEN,&PT))
             {
 #ifdef DEBUG
                 printf("PTGOLDEN: ");
                 OCT_output(&PTGOLDEN);
                 printf("\n");
 #endif
-                fprintf(stderr, "FAILURE Test %d rc: %d\n", testNo, rc);
+                fprintf(stderr, "FAILURE Test %d\n", testNo);
                 fclose(fp);
                 exit(EXIT_FAILURE);
             }
         }
     }
+
     fclose(fp);
+
     printf("SUCCESS TEST PAILLIER DECRYPTION PASSED\n");
     exit(EXIT_SUCCESS);
 }
diff --git a/test/test_paillier_encrypt.c b/test/test_paillier_encrypt.c
index da759cb..2f1891e 100644
--- a/test/test_paillier_encrypt.c
+++ b/test/test_paillier_encrypt.c
@@ -41,6 +41,16 @@ void read_OCTET(octet* OCT, char* string)
     OCT_fromHex(OCT,buff);
 }
 
+void read_FF_4096(BIG_512_60 *x, char* string, int n)
+{
+    int len = strlen(string);
+    char oct[len/2];
+    octet OCT = {0, len/2, oct};
+
+    read_OCTET(&OCT, string);
+    FF_4096_fromOctet(x, &OCT, n);
+}
+
 int main(int argc, char** argv)
 {
     if (argc != 2)
@@ -55,25 +65,15 @@ int main(int argc, char** argv)
     char line[LINE_LEN]= {0};
     char *linePtr=NULL;
 
-    int applyVector=0;
-
-    const char* TESTline = "TEST = ";
-    int testNo=0;
-
-    // Test result
-    int result=0;
-    const char* RESULTline = "RESULT = ";
-
     char ct[FS_4096]= {0};
     octet CT = {0,sizeof(ct),ct};
 
-    char ngolden[FS_2048]= {0};
-    octet NGOLDEN = {0,sizeof(ngolden),ngolden};
-    const char* Nline = "N = ";
+    int testNo=0;
+    const char* TESTline = "TEST = ";
 
-    char ggolden[FS_2048]= {0};
-    octet GGOLDEN = {0,sizeof(ggolden),ggolden};
-    const char* Lline = "G = ";
+    PAILLIER_public_key PUB;
+    const char* Nline = "N = ";
+    const char* Gline = "G = ";
 
     char rgolden[FS_4096]= {0};
     octet RGOLDEN = {0,sizeof(rgolden),rgolden};
@@ -102,7 +102,6 @@ int main(int argc, char** argv)
             len = strlen(TESTline);
             linePtr = line + len;
             sscanf(linePtr,"%d\n",&testNo);
-            printf("TEST = %d\n",testNo);
         }
 
         // Read N
@@ -110,22 +109,30 @@ int main(int argc, char** argv)
         {
             len = strlen(Nline);
             linePtr = line + len;
-            read_OCTET(&NGOLDEN,linePtr);
+            FF_4096_zero(PUB.n, FFLEN_4096);
+            read_FF_4096(PUB.n, linePtr, HFLEN_4096);
+
+            FF_4096_sqr(PUB.n2, PUB.n, HFLEN_4096);
+            FF_4096_norm(PUB.n2, FFLEN_4096);
 #ifdef DEBUG
             printf("N = ");
-            OCT_output(&NGOLDEN);
+            FF_4096_output(PUB.n , FFLEN_4096);
+            printf("\n");
 #endif
         }
 
+
         // Read G
-        if (!strncmp(line,Lline, strlen(Lline)))
+        if (!strncmp(line,Gline, strlen(Gline)))
         {
-            len = strlen(Lline);
+            len = strlen(Gline);
             linePtr = line + len;
-            read_OCTET(&GGOLDEN,linePtr);
+            FF_4096_zero(PUB.g, FFLEN_4096);
+            read_FF_4096(PUB.g, linePtr, HFLEN_4096);
 #ifdef DEBUG
-            printf("L = ");
-            OCT_output(&GGOLDEN);
+            printf("\nG = ");
+            FF_4096_output(PUB.g , FFLEN_4096);
+            printf("\n");
 #endif
         }
 
@@ -141,18 +148,6 @@ int main(int argc, char** argv)
 #endif
         }
 
-        // Read CIPHERTEXT
-        if (!strncmp(line,CTline, strlen(CTline)))
-        {
-            len = strlen(CTline);
-            linePtr = line + len;
-            read_OCTET(&CTGOLDEN,linePtr);
-#ifdef DEBUG
-            printf("CIPHERTEXT = ");
-            OCT_output(&CTGOLDEN);
-#endif
-        }
-
         // Read PLAINTEXT
         if (!strncmp(line,PTline, strlen(PTline)))
         {
@@ -165,29 +160,18 @@ int main(int argc, char** argv)
 #endif
         }
 
-        // Read expected result
-        if (!strncmp(line,RESULTline, strlen(RESULTline)))
+        // Read CIPHERTEXT and process test vector
+        if (!strncmp(line,CTline, strlen(CTline)))
         {
-            len = strlen(RESULTline);
+            len = strlen(CTline);
             linePtr = line + len;
-            sscanf(linePtr,"%d\n",&result);
-            applyVector=1;
+            read_OCTET(&CTGOLDEN,linePtr);
 #ifdef DEBUG
-            printf("RESULT = %d\n\n", result);
+            printf("CIPHERTEXT = ");
+            OCT_output(&CTGOLDEN);
 #endif
-        }
 
-        if (applyVector)
-        {
-            applyVector=0;
-
-            int rc = PAILLIER_ENCRYPT(NULL, &NGOLDEN, &GGOLDEN, &PTGOLDEN, 
&CT, &RGOLDEN);
-            if (rc)
-            {
-                fprintf(stderr, "FAILURE PAILLIER_DECRYPT Test %d rc: %d\n", 
testNo, rc);
-                fclose(fp);
-                exit(EXIT_FAILURE);
-            }
+            PAILLIER_ENCRYPT(NULL, &PUB, &PTGOLDEN, &CT, &RGOLDEN);
 
 #ifdef DEBUG
             printf("CT: ");
@@ -195,22 +179,22 @@ int main(int argc, char** argv)
             printf("\n");
 #endif
 
-            // OCT_comp return 1 for equal
-            rc = !(OCT_comp(&CTGOLDEN,&CT));
-            if(rc != result)
+            if(!OCT_comp(&CTGOLDEN,&CT))
             {
 #ifdef DEBUG
                 printf("CTGOLDEN: ");
                 OCT_output(&CTGOLDEN);
                 printf("\n");
 #endif
-                fprintf(stderr, "FAILURE Test %d rc: %d\n", testNo, rc);
+                fprintf(stderr, "FAILURE Test %d\n", testNo);
                 fclose(fp);
                 exit(EXIT_FAILURE);
             }
         }
     }
+
     fclose(fp);
+
     printf("SUCCESS TEST PAILLIER ENCRYPTION PASSED\n");
     exit(EXIT_SUCCESS);
 }
diff --git a/test/test_paillier_keygen.c b/test/test_paillier_keygen.c
index 74c8673..fecb25d 100644
--- a/test/test_paillier_keygen.c
+++ b/test/test_paillier_keygen.c
@@ -42,6 +42,40 @@ void read_OCTET(octet* OCT, char* string)
     OCT_fromHex(OCT,buff);
 }
 
+void read_FF_4096(BIG_512_60 *x, char* string, int n)
+{
+    int len = strlen(string);
+    char oct[len/2];
+    octet OCT = {0, len/2, oct};
+
+    read_OCTET(&OCT, string);
+    FF_4096_fromOctet(x, &OCT, n);
+}
+
+void compare_FF(char *x_name, char* y_name, BIG_512_60 *x, BIG_512_60 *y, int 
n)
+{
+    if(FF_4096_comp(x, y, n))
+    {
+        fprintf(stderr, "FAILURE %s != %s\n", x_name, y_name);
+        exit(EXIT_FAILURE);
+    }
+}
+
+void clean_private(PAILLIER_private_key *PRIV)
+{
+    PAILLIER_PRIVATE_KEY_KILL(PRIV);
+    FF_4096_zero(PRIV->n, FFLEN_4096);
+    FF_4096_zero(PRIV->g, FFLEN_4096);
+    FF_4096_zero(PRIV->n2, FFLEN_4096);
+}
+
+void clean_public(PAILLIER_public_key *PUB)
+{
+    FF_4096_zero(PUB->n, FFLEN_4096);
+    FF_4096_zero(PUB->g, FFLEN_4096);
+    FF_4096_zero(PUB->n2, FFLEN_4096);
+}
+
 int main(int argc, char** argv)
 {
     if (argc != 2)
@@ -52,76 +86,46 @@ int main(int argc, char** argv)
 
     int len=0;
     FILE *fp;
-    int rc=0;
 
     char line[LINE_LEN]= {0};
     char * linePtr=NULL;
 
-    int applyVector=0;
     int testSeed=0;
 
-    const char* TESTline = "TEST = ";
-    int testNo=0;
-
-    // Test result
-    int result=0;
-    const char* RESULTline = "RESULT = ";
+    PAILLIER_private_key PRIV;
+    PAILLIER_public_key PUB;
 
-    char p1[FS_2048]= {0};
-    octet P1 = {0,sizeof(p1),p1};
-    char q1[FS_2048]= {0};
-    octet Q1 = {0,sizeof(q1),q1};
-
-    char n1[FS_2048]= {0};
-    octet N1 = {0,sizeof(n1),n1};
-    char g1[FS_2048]= {0};
-    octet G1 = {0,sizeof(g1),g1};
-
-    char l1[FS_2048]= {0};
-    octet L1 = {0,sizeof(l1),l1};
-
-    char m1[FS_2048]= {0};
-    octet M1 = {0,sizeof(m1),m1};
-
-    char n2[FS_2048]= {0};
-    octet N2 = {0,sizeof(n2),n2};
-    char g2[FS_2048]= {0};
-    octet G2 = {0,sizeof(g2),g2};
-
-    char l2[FS_2048]= {0};
-    octet L2 = {0,sizeof(l2),l2};
-
-    char m2[FS_2048]= {0};
-    octet M2 = {0,sizeof(m2),m2};
+    int testNo=0;
+    const char* TESTline = "TEST = ";
 
     char seedgolden[32]= {0};
     octet SEEDGOLDEN = {0,sizeof(seedgolden),seedgolden};
     const char* SEEDline = "SEED = ";
 
-    char pgolden[FS_2048]= {0};
+    char p[FS_2048]={0};
+    char pgolden[HFS_2048]= {0};
+    octet P = {0, sizeof(p),p};
     octet PGOLDEN = {0,sizeof(pgolden),pgolden};
     const char* Pline = "P = ";
 
-    char qgolden[FS_2048]= {0};
+    char q[FS_2048]={0};
+    char qgolden[HFS_2048]={0};
+    octet Q = {0, sizeof(q),q};
     octet QGOLDEN = {0,sizeof(qgolden),qgolden};
     const char* Qline = "Q = ";
 
-    char ngolden[FS_2048]= {0};
-    octet NGOLDEN = {0,sizeof(ngolden),ngolden};
+    PAILLIER_private_key PRIVGOLDEN;
+    PAILLIER_public_key PUBGOLDEN;
     const char* Nline = "N = ";
-
-    char ggolden[FS_2048]= {0};
-    octet GGOLDEN = {0,sizeof(ggolden),ggolden};
     const char* Gline = "G = ";
-
-    char lgolden[FS_2048]= {0};
-    octet LGOLDEN = {0,sizeof(lgolden),lgolden};
     const char* Lline = "L = ";
-
-    char mgolden[FS_2048]= {0};
-    octet MGOLDEN = {0,sizeof(mgolden),mgolden};
     const char* Mline = "M = ";
 
+    // Clean GOLDEN keys, the generated keys should be cleaned
+    // during initialisation
+    clean_private(&PRIVGOLDEN);
+    clean_public(&PUBGOLDEN);
+
     fp = fopen(argv[1], "r");
     if (fp == NULL)
     {
@@ -137,7 +141,6 @@ int main(int argc, char** argv)
             len = strlen(TESTline);
             linePtr = line + len;
             sscanf(linePtr,"%d\n",&testNo);
-            printf("TEST = %d\n",testNo);
         }
 
         // Read SEED
@@ -147,10 +150,6 @@ int main(int argc, char** argv)
             linePtr = line + len;
             read_OCTET(&SEEDGOLDEN,linePtr);
             testSeed = 1;
-#ifdef DEBUG
-            printf("SEED = ");
-            OCT_output(&SEEDGOLDEN);
-#endif
         }
 
         // Read P
@@ -159,10 +158,9 @@ int main(int argc, char** argv)
             len = strlen(Pline);
             linePtr = line + len;
             read_OCTET(&PGOLDEN,linePtr);
-#ifdef DEBUG
-            printf("P = ");
-            OCT_output(&PGOLDEN);
-#endif
+            OCT_copy(&P, &PGOLDEN);
+            OCT_pad(&P, HFS_4096);
+            FF_4096_fromOctet(PRIVGOLDEN.p,&P,HFLEN_4096);
         }
 
         // Read Q
@@ -171,10 +169,9 @@ int main(int argc, char** argv)
             len = strlen(Qline);
             linePtr = line + len;
             read_OCTET(&QGOLDEN,linePtr);
-#ifdef DEBUG
-            printf("Q = ");
-            OCT_output(&QGOLDEN);
-#endif
+            OCT_copy(&Q, &QGOLDEN);
+            OCT_pad(&Q, HFS_4096);
+            FF_4096_fromOctet(PRIVGOLDEN.q,&Q,HFLEN_4096);
         }
 
         // Read N
@@ -182,11 +179,13 @@ int main(int argc, char** argv)
         {
             len = strlen(Nline);
             linePtr = line + len;
-            read_OCTET(&NGOLDEN,linePtr);
-#ifdef DEBUG
-            printf("N = ");
-            OCT_output(&NGOLDEN);
-#endif
+            read_FF_4096(PRIVGOLDEN.n, linePtr, HFLEN_4096);
+
+            FF_4096_sqr(PRIVGOLDEN.n2,PRIVGOLDEN.n, HFLEN_4096);
+            FF_4096_norm(PRIVGOLDEN.n2, FFLEN_4096);
+
+            FF_4096_copy(PUBGOLDEN.n, PRIVGOLDEN.n, HFLEN_4096);
+            FF_4096_copy(PUBGOLDEN.n2, PRIVGOLDEN.n2, FFLEN_4096);
         }
 
         // Read G
@@ -194,11 +193,8 @@ int main(int argc, char** argv)
         {
             len = strlen(Gline);
             linePtr = line + len;
-            read_OCTET(&GGOLDEN,linePtr);
-#ifdef DEBUG
-            printf("G = ");
-            OCT_output(&GGOLDEN);
-#endif
+            read_FF_4096(PRIVGOLDEN.g, linePtr, HFLEN_4096);
+            FF_4096_copy(PUBGOLDEN.g, PRIVGOLDEN.g, HFLEN_4096);
         }
 
         // Read L
@@ -206,41 +202,15 @@ int main(int argc, char** argv)
         {
             len = strlen(Lline);
             linePtr = line + len;
-            read_OCTET(&LGOLDEN,linePtr);
-#ifdef DEBUG
-            printf("L = ");
-            OCT_output(&LGOLDEN);
-#endif
+            read_FF_4096(PRIVGOLDEN.l, linePtr, HFLEN_4096);
         }
 
-        // Read M
+        // Read M and process test vector
         if (!strncmp(line,Mline, strlen(Mline)))
         {
             len = strlen(Mline);
             linePtr = line + len;
-            read_OCTET(&MGOLDEN,linePtr);
-#ifdef DEBUG
-            printf("M = ");
-            OCT_output(&MGOLDEN);
-#endif
-        }
-
-        // Read expected result
-        if (!strncmp(line,RESULTline, strlen(RESULTline)))
-        {
-            len = strlen(RESULTline);
-            linePtr = line + len;
-            sscanf(linePtr,"%d\n",&result);
-            applyVector=1;
-#ifdef DEBUG
-            printf("RESULT = %d\n\n", result);
-#endif
-        }
-
-        if (applyVector)
-        {
-            applyVector=0;
-
+            read_FF_4096(PRIVGOLDEN.m, linePtr, HFLEN_4096);
 
             if (testSeed)
             {
@@ -252,152 +222,62 @@ int main(int argc, char** argv)
                 // initialise strong RNG
                 CREATE_CSPRNG(&RNG,&SEEDGOLDEN);
 
-                rc = PAILLIER_KEY_PAIR(&RNG, &P1, &Q1, &N1, &G1, &L1, &M1);
-                if (rc)
-                {
-                    fprintf(stderr, "FAILURE PAILLIER_KEY_PAIR Test %d rc: 
%d\n", testNo, rc);
-                    fclose(fp);
-                    exit(EXIT_FAILURE);
-                }
-
-#ifdef DEBUG
-                printf("P1: ");
-                OCT_output(&P1);
-                printf("\n");
-                printf("Q1: ");
-                OCT_output(&Q1);
-                printf("\n");
-
-                printf("Public Key \n");
-                printf("N1: ");
-                OCT_output(&N1);
-                printf("\n");
-                printf("G1: ");
-                OCT_output(&G1);
-                printf("\n");
-
-                printf("Secret Key \n");
-                printf("L1: ");
-                OCT_output(&L1);
-                printf("\n");
-                printf("M1: ");
-                OCT_output(&M1);
-                printf("\n");
-#endif
-
-                // OCT_comp returns 1 for equal
-                rc = !(OCT_comp(&PGOLDEN,&P1));
-                if(rc != result)
-                {
-                    fprintf(stderr, "FAILURE Test %d PGOLDEN rc: %d\n", 
testNo, rc);
-                    fclose(fp);
-                    exit(EXIT_FAILURE);
-                }
-
-                rc = !(OCT_comp(&QGOLDEN,&Q1));
-                if(rc != result)
-                {
-                    fprintf(stderr, "FAILURE Test %d QGOLDEN rc: %d\n", 
testNo, rc);
-                    fclose(fp);
-                    exit(EXIT_FAILURE);
-                }
-
-                rc = !(OCT_comp(&NGOLDEN,&N1));
-                if(rc != result)
-                {
-                    fprintf(stderr, "FAILURE Test %d NGOLDEN rc: %d\n", 
testNo, rc);
-                    fclose(fp);
-                    exit(EXIT_FAILURE);
-                }
-
-                rc = !(OCT_comp(&GGOLDEN,&G1));
-                if(rc != result)
-                {
-                    fprintf(stderr, "FAILURE Test %d GGOLDEN rc: %d\n", 
testNo, rc);
-                    fclose(fp);
-                    exit(EXIT_FAILURE);
-                }
-
-                rc = !(OCT_comp(&LGOLDEN,&L1));
-                if(rc != result)
-                {
-                    fprintf(stderr, "FAILURE Test %d LGOLDEN rc: %d\n", 
testNo, rc);
-                    fclose(fp);
-                    exit(EXIT_FAILURE);
-                }
-
-                rc = !(OCT_comp(&MGOLDEN,&M1));
-                if(rc != result)
-                {
-                    fprintf(stderr, "FAILURE Test %d MGOLDEN rc: %d\n", 
testNo, rc);
-                    fclose(fp);
-                    exit(EXIT_FAILURE);
-                }
-
+                PAILLIER_KEY_PAIR(&RNG, NULL, NULL, &PUB, &PRIV);
             }
-
-
-            rc = PAILLIER_KEY_PAIR(NULL, &PGOLDEN, &QGOLDEN, &N2, &G2, &L2, 
&M2);
-            if (rc)
+            else
             {
-                fprintf(stderr, "FAILURE PAILLIER_KEY_PAIR Test %d rc: %d\n", 
testNo, rc);
-                fclose(fp);
-                exit(EXIT_FAILURE);
+                PAILLIER_KEY_PAIR(NULL, &PGOLDEN, &QGOLDEN, &PUB, &PRIV);
             }
 
 #ifdef DEBUG
-            printf("Public Key \n");
-            printf("N2: ");
-            OCT_output(&N2);
-            printf("\n");
-            printf("G2: ");
-            OCT_output(&G2);
-            printf("\n");
-
-            printf("Secret Key \n");
-            printf("L2: ");
-            OCT_output(&L2);
-            printf("\n");
-            printf("M2: ");
-            OCT_output(&M2);
-            printf("\n");
+            printf("SEED = ");
+            OCT_output(&SEEDGOLDEN);
+            printf("\nP = ");
+            FF_4096_output(PRIV.p , HFLEN_4096);
+            printf("\nQ = ");
+            FF_4096_output(PRIV.q , HFLEN_4096);
+            printf("\nL = ");
+            FF_4096_output(PRIV.l , FFLEN_4096);
+            printf("\nM = ");
+            FF_4096_output(PRIV.m , FFLEN_4096);
+            printf("\nN = ");
+            FF_4096_output(PRIV.n , FFLEN_4096);
+            printf("\nG = ");
+            FF_4096_output(PRIV.g , FFLEN_4096);
+            printf("\nN2 = ");
+            FF_4096_output(PRIV.n2, FFLEN_4096);
+            printf("\nPUB N = ");
+            FF_4096_output(PUB.n , FFLEN_4096);
+            printf("\nPUB G = ");
+            FF_4096_output(PUB.g , FFLEN_4096);
+            printf("\nPUB N2 = ");
+            FF_4096_output(PUB.n2, FFLEN_4096);
+            printf("\n\n");
 #endif
-            rc = !(OCT_comp(&NGOLDEN,&N2));
-            if(rc != result)
-            {
-                fprintf(stderr, "FAILURE Test %d NGOLDEN rc: %d\n", testNo, 
rc);
-                fclose(fp);
-                exit(EXIT_FAILURE);
-            }
 
-            rc = !(OCT_comp(&GGOLDEN,&G2));
-            if(rc != result)
-            {
-                fprintf(stderr, "FAILURE Test %d GGOLDEN rc: %d\n", testNo, 
rc);
-                fclose(fp);
-                exit(EXIT_FAILURE);
-            }
-
-            rc = !(OCT_comp(&LGOLDEN,&L2));
-            if(rc != result)
-            {
-                fprintf(stderr, "FAILURE Test %d LGOLDEN rc: %d\n", testNo, 
rc);
-                fclose(fp);
-                exit(EXIT_FAILURE);
-            }
+            compare_FF("PRIV.p" , "PRIVGOLDEN.p" , PRIV.p , PRIVGOLDEN.p , 
HFLEN_4096);
+            compare_FF("PRIV.q" , "PRIVGOLDEN.q" , PRIV.q , PRIVGOLDEN.q , 
HFLEN_4096);
+            compare_FF("PRIV.l" , "PRIVGOLDEN.l" , PRIV.l , PRIVGOLDEN.l , 
FFLEN_4096);
+            compare_FF("PRIV.m" , "PRIVGOLDEN.m" , PRIV.m , PRIVGOLDEN.m , 
FFLEN_4096);
+            compare_FF("PRIV.n" , "PRIVGOLDEN.n" , PRIV.n , PRIVGOLDEN.n , 
FFLEN_4096);
+            compare_FF("PRIV.g" , "PRIVGOLDEN.g" , PRIV.g , PRIVGOLDEN.g , 
FFLEN_4096);
+            compare_FF("PRIV.n2", "PRIVGOLDEN.n2", PRIV.n2, PRIVGOLDEN.n2, 
FFLEN_4096);
 
-            rc = !(OCT_comp(&MGOLDEN,&M2));
-            if(rc != result)
-            {
-                fprintf(stderr, "FAILURE Test %d MGOLDEN rc: %d\n", testNo, 
rc);
-                fclose(fp);
-                exit(EXIT_FAILURE);
-            }
+            compare_FF("PUB.n" , "PUBGOLDEN.n" , PUB.n , PUBGOLDEN.n , 
FFLEN_4096);
+            compare_FF("PUB.g" , "PUBGOLDEN.g" , PUB.g , PUBGOLDEN.g , 
FFLEN_4096);
+            compare_FF("PUB.n2", "PUBGOLDEN.n2", PUB.n2, PUBGOLDEN.n2, 
FFLEN_4096);
 
+            // Clean keys for next test vector
+            clean_private(&PRIV);
+            clean_private(&PRIVGOLDEN);
 
+            clean_public(&PUB);
+            clean_public(&PUBGOLDEN);
         }
     }
+
     fclose(fp);
+
     printf("SUCCESS TEST PAILLIER KEYGEN PASSED\n");
     exit(EXIT_SUCCESS);
 }
diff --git a/test/test_paillier_mult.c b/test/test_paillier_mult.c
index b8b7aae..0ca9500 100644
--- a/test/test_paillier_mult.c
+++ b/test/test_paillier_mult.c
@@ -41,6 +41,16 @@ void read_OCTET(octet* OCT, char* string)
     OCT_fromHex(OCT,buff);
 }
 
+void read_FF_4096(BIG_512_60 *x, char* string, int n)
+{
+    int len = strlen(string);
+    char oct[len/2];
+    octet OCT = {0, len/2, oct};
+
+    read_OCTET(&OCT, string);
+    FF_4096_fromOctet(x, &OCT, n);
+}
+
 int main(int argc, char** argv)
 {
     if (argc != 2)
@@ -55,20 +65,13 @@ int main(int argc, char** argv)
     char line[LINE_LEN]= {0};
     char *linePtr=NULL;
 
-    int applyVector=0;
-
-    const char* TESTline = "TEST = ";
-    int testNo=0;
-
     char ct[FS_4096]= {0};
     octet CT = {0,sizeof(ct),ct};
 
-    // Test result
-    int result=0;
-    const char* RESULTline = "RESULT = ";
+    int testNo=0;
+    const char* TESTline = "TEST = ";
 
-    char ngolden[FS_2048]= {0};
-    octet NGOLDEN = {0,sizeof(ngolden),ngolden};
+    PAILLIER_public_key PUB;
     const char* Nline = "N = ";
 
     char ct1golden[FS_4096]= {0};
@@ -98,7 +101,6 @@ int main(int argc, char** argv)
             len = strlen(TESTline);
             linePtr = line + len;
             sscanf(linePtr,"%d\n",&testNo);
-            printf("TEST = %d\n",testNo);
         }
 
         // Read N
@@ -106,10 +108,14 @@ int main(int argc, char** argv)
         {
             len = strlen(Nline);
             linePtr = line + len;
-            read_OCTET(&NGOLDEN,linePtr);
+            read_FF_4096(PUB.n, linePtr, HFLEN_4096);
+
+            FF_4096_sqr(PUB.n2, PUB.n, HFLEN_4096);
+            FF_4096_norm(PUB.n2, FFLEN_4096);
 #ifdef DEBUG
             printf("N = ");
-            OCT_output(&NGOLDEN);
+            FF_4096_output(PUB.n , FFLEN_4096);
+            printf("\n");
 #endif
         }
 
@@ -137,7 +143,7 @@ int main(int argc, char** argv)
 #endif
         }
 
-        // Read CIPHERTEXT
+        // Read CIPHERTEXT and process test vector
         if (!strncmp(line,CTline, strlen(CTline)))
         {
             len = strlen(CTline);
@@ -147,32 +153,8 @@ int main(int argc, char** argv)
             printf("CIPHERTEXT = ");
             OCT_output(&CTGOLDEN);
 #endif
-        }
-
-        // Read expected result
-        if (!strncmp(line,RESULTline, strlen(RESULTline)))
-        {
-            len = strlen(RESULTline);
-            linePtr = line + len;
-            sscanf(linePtr,"%d\n",&result);
-            applyVector=1;
-#ifdef DEBUG
-            printf("RESULT = %d\n\n", result);
-#endif
-        }
-
-        if (applyVector)
-        {
-            applyVector=0;
-
-            int rc = PAILLIER_MULT(&NGOLDEN, &CT1GOLDEN, &PT2GOLDEN, &CT);
-            if (rc)
-            {
-                fprintf(stderr, "FAILURE PAILLIER_ADD rc: %d\n", rc);
-                fclose(fp);
-                exit(EXIT_FAILURE);
-            }
 
+            PAILLIER_MULT(&PUB, &CT1GOLDEN, &PT2GOLDEN, &CT);
 
 #ifdef DEBUG
             printf("CT: ");
@@ -180,22 +162,22 @@ int main(int argc, char** argv)
             printf("\n");
 #endif
 
-            // OCT_comp return 1 for equal
-            rc = !(OCT_comp(&CTGOLDEN,&CT));
-            if(rc != result)
+            if(!OCT_comp(&CTGOLDEN,&CT))
             {
 #ifdef DEBUG
                 printf("CTGOLDEN: ");
                 OCT_output(&CTGOLDEN);
                 printf("\n");
 #endif
-                fprintf(stderr, "FAILURE Test %d rc: %d\n", testNo, rc);
+                fprintf(stderr, "FAILURE Test %d\n", testNo);
                 fclose(fp);
                 exit(EXIT_FAILURE);
             }
         }
     }
+
     fclose(fp);
+
     printf("SUCCESS TEST PAILLIER MULTIPLICATION PASSED\n");
     exit(EXIT_SUCCESS);
 }

Reply via email to