use octets in factoring zk API
diff --git a/benchmark/bench_factoring_zk.c b/benchmark/bench_factoring_zk.c
index e7f97df..0a7445c 100644
--- a/benchmark/bench_factoring_zk.c
+++ b/benchmark/bench_factoring_zk.c
@@ -29,6 +29,7 @@
 
 char *P_hex = "e008507e09c24d756280f3d94912fb9ac16c0a8a1757ee01a350736acfc7f65880f87eca55d6680253383fc546d03fd9ebab7d8fa746455180888cb7c17edf58d3327296468e5ab736374bc9a0fa02606ed5d3a4a5fb1677891f87fbf3c655c3e0549a86b17b7ddce07c8f73e253105e59f5d3ed2c7ba5bdf8495df40ae71a7f";
 char *Q_hex = "dbffe278edd44c2655714e5a4cc82e66e46063f9ab69df9d0ed20eb3d7f2d8c7d985df71c28707f32b961d160ca938e9cf909cd77c4f8c630aec34b67714cbfd4942d7147c509db131bc2d6a667eb30df146f64b710f8f5247848b0a75738a38772e31014fd63f0b769209928d586499616dcc90700b393156e12eea7e15a835";
+char *N_hex = "c0870b552afb6c8c09f79e39ad6ca17ca93085c2cd7a726ade69574961ff9ce8ad33c7dda2e0703a3b0010c2e5bb7552c74164ce8dd011d85e5969090df53fe10e39cbe530704da32ff07228a6b6da34a5929e8a231c3080d812dc6e93affd81682339a6aee192927c582da8941bebf46e13c4ea3918a1477951fa66d367e70d8551b1869316d48317e0702d7bce242a326000f3dc763c44eba2044a1df713a94c1339edd464b145dcadf94e6e61be73dc270c878e1a28be720df2209202d00e101c3b255b757eaf547acd863d51eb676b851511b3dadeda926714719dceddd3af7908893ae65f2b95ee5c4d36cc6862cbe6886a62d7c1e2d0db48c399a6d44b";
 char *R_hex = "c05f6c79e81fab2f1aa6af48dc5afa89a21c0aee03e93944cacfefef1be90f41ec8c2055760beafa9ed87dd67dbd56b33a2568dfec62a03f06c4f8449a93eee858507f4b602bf305e1c9968d9f5b6dc3120c27e053a1d7e51590e0bacb8d36c27bccce1a57c1e3aeb0832905d4e2bb8eaee883b4df042d8660cf3e0c9777b6be34c18bef02347f92cb71f372f61c018860211932dd46de8f925212d7afe6dd2f3cda05f8d5a6bd1b138b66c5efd7fca31f926c721f6d4207b97fc01cdf325da21233f6df37adbcd67472b332f7490a4a96e0fef31beef55b9446067b8e8d807384e3d31051c7a1f27296a6ae111b30c3d1f3f81666fd9ad99df531bb68428029";
 
 int main()
@@ -57,19 +58,12 @@
     char y[FS_2048];
     octet Y = {0, sizeof(y), y};
 
-    FACTORING_ZK_modulus m;
-
     // Load values
     OCT_fromHex(&P, P_hex);
     OCT_fromHex(&Q, Q_hex);
+    OCT_fromHex(&N, N_hex);
     OCT_fromHex(&R, R_hex);
 
-    FF_2048_fromOctet(m.p, &P, HFLEN_2048);
-    FF_2048_fromOctet(m.q, &Q, HFLEN_2048);
-
-    FF_2048_mul(m.n, m.p, m.q, HFLEN_2048);
-    FF_2048_toOctet(&N, m.n, FFLEN_2048);
-
     print_system_info();
 
     printf("Timing info\n");
@@ -79,7 +73,7 @@
     start = clock();
     do
     {
-        FACTORING_ZK_prove(&m, NULL, &R, &E, &Y);
+        FACTORING_ZK_prove(NULL, &P, &Q, &R, &E, &Y);
         iterations++;
         elapsed = (clock() - start) / (double)CLOCKS_PER_SEC;
     }
diff --git a/examples/example_factoring_zk.c b/examples/example_factoring_zk.c
index d3924f8..3a4741a 100644
--- a/examples/example_factoring_zk.c
+++ b/examples/example_factoring_zk.c
@@ -23,6 +23,7 @@
 
 char *P_hex = "e008507e09c24d756280f3d94912fb9ac16c0a8a1757ee01a350736acfc7f65880f87eca55d6680253383fc546d03fd9ebab7d8fa746455180888cb7c17edf58d3327296468e5ab736374bc9a0fa02606ed5d3a4a5fb1677891f87fbf3c655c3e0549a86b17b7ddce07c8f73e253105e59f5d3ed2c7ba5bdf8495df40ae71a7f";
 char *Q_hex = "dbffe278edd44c2655714e5a4cc82e66e46063f9ab69df9d0ed20eb3d7f2d8c7d985df71c28707f32b961d160ca938e9cf909cd77c4f8c630aec34b67714cbfd4942d7147c509db131bc2d6a667eb30df146f64b710f8f5247848b0a75738a38772e31014fd63f0b769209928d586499616dcc90700b393156e12eea7e15a835";
+char *N_hex = "c0870b552afb6c8c09f79e39ad6ca17ca93085c2cd7a726ade69574961ff9ce8ad33c7dda2e0703a3b0010c2e5bb7552c74164ce8dd011d85e5969090df53fe10e39cbe530704da32ff07228a6b6da34a5929e8a231c3080d812dc6e93affd81682339a6aee192927c582da8941bebf46e13c4ea3918a1477951fa66d367e70d8551b1869316d48317e0702d7bce242a326000f3dc763c44eba2044a1df713a94c1339edd464b145dcadf94e6e61be73dc270c878e1a28be720df2209202d00e101c3b255b757eaf547acd863d51eb676b851511b3dadeda926714719dceddd3af7908893ae65f2b95ee5c4d36cc6862cbe6886a62d7c1e2d0db48c399a6d44b";
 
 int main()
 {
@@ -41,8 +42,6 @@
     char y[FS_2048];
     octet Y = {0, sizeof(y), y};
 
-    FACTORING_ZK_modulus m;
-
     // Deterministic RNG for testing
     char seed[64] = {0};
     csprng RNG;
@@ -51,12 +50,7 @@
     // Load RSA modulus
     OCT_fromHex(&P, P_hex);
     OCT_fromHex(&Q, Q_hex);
-
-    FF_2048_fromOctet(m.p, &P, HFLEN_2048);
-    FF_2048_fromOctet(m.q, &Q, HFLEN_2048);
-
-    FF_2048_mul(m.n, m.p, m.q, HFLEN_2048);
-    FF_2048_toOctet(&N, m.n, FFLEN_2048);
+    OCT_fromHex(&N, N_hex);
 
     printf("Prove knowledge of factoring for\n");
     printf("\tN = ");
@@ -68,7 +62,7 @@
 
     // ZK proof
     printf("\nGenerate proof\n");
-    FACTORING_ZK_prove(&m, &RNG, NULL, &E, &Y);
+    FACTORING_ZK_prove(&RNG, &P, &Q, NULL, &E, &Y);
 
     printf("\tE = ");
     OCT_output(&E);
@@ -87,7 +81,4 @@
     {
         printf("\tFailure!\n");
     }
-
-    // Clean memory
-    FACTORING_ZK_kill_modulus(&m);
 }
diff --git a/examples/example_full.c b/examples/example_full.c
index 55eabb6..dd5dd9a 100644
--- a/examples/example_full.c
+++ b/examples/example_full.c
@@ -131,7 +131,11 @@
     char s_e[EGS_SECP256K1];
     octet S_E = {0, sizeof(s_e), s_e};
 
-    FACTORING_ZK_modulus m;
+    char p[HFS_2048] = {0};
+    octet M_P = {0, sizeof(p), p};
+
+    char q[HFS_2048];
+    octet M_Q = {0, sizeof(q), q};
 
     /* Prove knowledge of DLOG PK = s.G */
 
@@ -151,11 +155,10 @@
 
     /* Prove knowledge of factorization of the Paillier modulus */
 
-    FF_2048_copy(m.p, km->paillier_sk.p, HFLEN_2048);
-    FF_2048_copy(m.q, km->paillier_sk.q, HFLEN_2048);
-    FF_2048_mul(m.n, m.p, m.q, HFLEN_2048);
+    FF_2048_toOctet(&M_P, km->paillier_sk.p, HFLEN_2048);
+    FF_2048_toOctet(&M_Q, km->paillier_sk.q, HFLEN_2048);
 
-    FACTORING_ZK_prove(&m, RNG, NULL, E, Y);
+    FACTORING_ZK_prove(RNG, &M_P, &M_Q, NULL, E, Y);
 
     printf("\n\tProve knowledge of the Paillier Secret Key\n");
     printf("\t\tE = ");
@@ -163,7 +166,8 @@
     printf("\t\tY = ");
     OCT_output(Y);
 
-    FACTORING_ZK_kill_modulus(&m);
+    OCT_clear(&M_P);
+    OCT_clear(&M_Q);
 }
 
 int key_material_verify_zkp(key_material *km, octet *C, octet *P, octet *E, octet *Y)
diff --git a/include/amcl/factoring_zk.h b/include/amcl/factoring_zk.h
index b8738f3..bd8a81e 100644
--- a/include/amcl/factoring_zk.h
+++ b/include/amcl/factoring_zk.h
@@ -48,25 +48,16 @@
 #define FACTORING_ZK_OK   0  /** < Proof successfully verified */
 #define FACTORING_ZK_FAIL 91 /** < Invalid proof */
 
-/*!
- * \brief RSA modulus for ZKP
- */
-typedef struct
-{
-    BIG_1024_58 n[FFLEN_2048]; /**< Integer to prove knowledge of factoring */
-    BIG_1024_58 p[HFLEN_2048]; /**< First prime factor of n */
-    BIG_1024_58 q[HFLEN_2048]; /**< Second prime factor of n*/
-} FACTORING_ZK_modulus;
-
 /** \brief Prove knowledge of the modulus m in ZK
  *
- *  @param  m           Modulus to prove knowledge of factoring for
  *  @param  RNG         Cryptographically secure PRNG
+ *  @param  P           First prime of the factorization
+ *  @param  Q           Second prime of the factorization
  *  @param  R           Random value used in the proof. If RNG is NULL this is read
  *  @param  E           Fisrt component of the ZK proof
  *  @param  Y           Second component of the ZK proof
  */
-void FACTORING_ZK_prove(FACTORING_ZK_modulus *m, csprng *RNG, octet *R, octet *E, octet *Y);
+void FACTORING_ZK_prove(csprng *RNG, octet *P, octet *Q, octet *R, octet *E, octet *Y);
 
 /** \brief Verify ZK proof of knowledge of factoring of N
  *
@@ -79,13 +70,6 @@
  */
 int FACTORING_ZK_verify(octet *N, octet *E, octet *Y);
 
-/** \brief Clear modulus
- *
- *  @param m             Modulus for the ZK proof to clean
- *
- */
-void FACTORING_ZK_kill_modulus(FACTORING_ZK_modulus *m);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/factoring_zk.c b/src/factoring_zk.c
index 513f364..339d349 100644
--- a/src/factoring_zk.c
+++ b/src/factoring_zk.c
@@ -93,7 +93,7 @@
  *  e  = H'(N, Z1, Z2, X)
  *  y  = r + (N - phi(N)) * e
  */
-void FACTORING_ZK_prove(FACTORING_ZK_modulus *m, csprng *RNG, octet *R, octet *E, octet *Y)
+void FACTORING_ZK_prove(csprng *RNG, octet *P, octet *Q, octet *R, octet *E, octet *Y)
 {
     int i;
 
@@ -102,6 +102,10 @@
     hash256 sha_x;
     hash256 sha_prime;
 
+    BIG_1024_58 p[HFLEN_2048];
+    BIG_1024_58 q[HFLEN_2048];
+    BIG_1024_58 n[FFLEN_2048];
+
     BIG_1024_58 r[FFLEN_2048];
     BIG_1024_58 rp[HFLEN_2048];
     BIG_1024_58 rq[HFLEN_2048];
@@ -116,6 +120,11 @@
     char w[FS_2048];
     octet W = {0, sizeof(w), w};
 
+    // Read modulus
+    FF_2048_fromOctet(p, P, HFLEN_2048);
+    FF_2048_fromOctet(q, Q, HFLEN_2048);
+    FF_2048_mul(n, p, q, HFLEN_2048);
+
     if (RNG != NULL)
     {
         FF_2048_random(r, RNG, FFLEN_2048);
@@ -126,17 +135,17 @@
     }
 
     // Compute r mod (p-1) and r mod (q-1) for exponent with CRT
-    FF_2048_copy(hws, m->p, HFLEN_2048);
+    FF_2048_copy(hws, p, HFLEN_2048);
     FF_2048_dec(hws, 1, HFLEN_2048);
     FF_2048_dmod(rp, r, hws, HFLEN_2048);
 
-    FF_2048_copy(hws, m->q, HFLEN_2048);
+    FF_2048_copy(hws, q, HFLEN_2048);
     FF_2048_dec(hws, 1, HFLEN_2048);
     FF_2048_dmod(rq, r, hws, HFLEN_2048);
 
     // Process N in the hash function H(N, ?)
     HASH256_init(&sha);
-    FF_2048_toOctet(&W, m->n, FFLEN_2048);
+    FF_2048_toOctet(&W, n, FFLEN_2048);
     hash_oct(&sha, &W);
 
     // Duplicate the state of H so it can be used as H'(N, ?)
@@ -152,21 +161,21 @@
         generator(&mgf, i, &W);
 
         FF_2048_fromOctet(ws, &W, FFLEN_2048);
-        FF_2048_mod(ws, m->n, FFLEN_2048);
+        FF_2048_mod(ws, n, FFLEN_2048);
 
         FF_2048_toOctet(&W, ws, FFLEN_2048);
         hash_oct(&sha_prime, &W);
 
         // Compute Z_i ^ r mod P
-        FF_2048_dmod(hws, ws, m->p, HFLEN_2048);
-        FF_2048_skpow(zrp, hws, rp, m->p, HFLEN_2048, HFLEN_2048);
+        FF_2048_dmod(hws, ws, p, HFLEN_2048);
+        FF_2048_skpow(zrp, hws, rp, p, HFLEN_2048, HFLEN_2048);
 
         // Compute Z_i ^ r mod Q
-        FF_2048_dmod(hws, ws, m->q, HFLEN_2048);
-        FF_2048_skpow(zrq, hws, rq, m->q, HFLEN_2048, HFLEN_2048);
+        FF_2048_dmod(hws, ws, q, HFLEN_2048);
+        FF_2048_skpow(zrq, hws, rq, q, HFLEN_2048, HFLEN_2048);
 
         // Combine Z_i ^ r mod N with CRT
-        FF_2048_crt(ws, zrp, zrq, m->p, m->q, HFLEN_2048);
+        FF_2048_crt(ws, zrp, zrq, p, q, HFLEN_2048);
 
         // Process Z_i ^ r mod N in H
         FF_2048_toOctet(&W, ws, FFLEN_2048);
@@ -187,7 +196,7 @@
     FF_2048_fromOctet(e, &W, HFLEN_2048);
 
     // N - phi(N) = P + Q - 1
-    FF_2048_add(hws, m->p, m->q, HFLEN_2048);
+    FF_2048_add(hws, p, q, HFLEN_2048);
     FF_2048_dec(hws, 1, HFLEN_2048);
 
     // e * (N - phi(N))
@@ -201,10 +210,14 @@
 
     // Clear memory
     FF_2048_zero(r,   FFLEN_2048);
+    FF_2048_zero(n,   FFLEN_2048);
+    FF_2048_zero(p,   HFLEN_2048);
+    FF_2048_zero(q,   HFLEN_2048);
     FF_2048_zero(rp,  HFLEN_2048);
     FF_2048_zero(rq,  HFLEN_2048);
     FF_2048_zero(zrp, HFLEN_2048);
     FF_2048_zero(zrq, HFLEN_2048);
+    FF_2048_zero(hws, HFLEN_2048);
 }
 
 int FACTORING_ZK_verify(octet *N, octet *E, octet *Y)
@@ -291,8 +304,3 @@
     return FACTORING_ZK_OK;
 }
 
-void FACTORING_ZK_kill_modulus(FACTORING_ZK_modulus *m)
-{
-    FF_2048_zero(m->p, HFLEN_2048);
-    FF_2048_zero(m->q, HFLEN_2048);
-}
diff --git a/test/smoke/test_factoring_zk_smoke.c b/test/smoke/test_factoring_zk_smoke.c
index 4e5f065..d2a0b54 100644
--- a/test/smoke/test_factoring_zk_smoke.c
+++ b/test/smoke/test_factoring_zk_smoke.c
@@ -23,6 +23,7 @@
 
 char *P_hex = "e008507e09c24d756280f3d94912fb9ac16c0a8a1757ee01a350736acfc7f65880f87eca55d6680253383fc546d03fd9ebab7d8fa746455180888cb7c17edf58d3327296468e5ab736374bc9a0fa02606ed5d3a4a5fb1677891f87fbf3c655c3e0549a86b17b7ddce07c8f73e253105e59f5d3ed2c7ba5bdf8495df40ae71a7f";
 char *Q_hex = "dbffe278edd44c2655714e5a4cc82e66e46063f9ab69df9d0ed20eb3d7f2d8c7d985df71c28707f32b961d160ca938e9cf909cd77c4f8c630aec34b67714cbfd4942d7147c509db131bc2d6a667eb30df146f64b710f8f5247848b0a75738a38772e31014fd63f0b769209928d586499616dcc90700b393156e12eea7e15a835";
+char *N_hex = "c0870b552afb6c8c09f79e39ad6ca17ca93085c2cd7a726ade69574961ff9ce8ad33c7dda2e0703a3b0010c2e5bb7552c74164ce8dd011d85e5969090df53fe10e39cbe530704da32ff07228a6b6da34a5929e8a231c3080d812dc6e93affd81682339a6aee192927c582da8941bebf46e13c4ea3918a1477951fa66d367e70d8551b1869316d48317e0702d7bce242a326000f3dc763c44eba2044a1df713a94c1339edd464b145dcadf94e6e61be73dc270c878e1a28be720df2209202d00e101c3b255b757eaf547acd863d51eb676b851511b3dadeda926714719dceddd3af7908893ae65f2b95ee5c4d36cc6862cbe6886a62d7c1e2d0db48c399a6d44b";
 
 int main()
 {
@@ -41,8 +42,6 @@
     char y[FS_2048];
     octet Y = {0, sizeof(y), y};
 
-    FACTORING_ZK_modulus m;
-
     BIG_1024_58 zero[HFLEN_2048];
     FF_2048_zero(zero, HFLEN_2048);
 
@@ -54,16 +53,10 @@
     // Load RSA modulus
     OCT_fromHex(&P, P_hex);
     OCT_fromHex(&Q, Q_hex);
-
-    FF_2048_fromOctet(m.p, &P, HFLEN_2048);
-    FF_2048_fromOctet(m.q, &Q, HFLEN_2048);
-
-    FF_2048_mul(m.n, m.p, m.q, HFLEN_2048);
+    OCT_fromHex(&N, N_hex);
 
     // ZK proof
-    FACTORING_ZK_prove(&m, &RNG, NULL, &E, &Y);
-
-    FF_2048_toOctet(&N, m.n, FFLEN_2048);
+    FACTORING_ZK_prove(&RNG, &P, &Q, NULL, &E, &Y);
 
     // Verify proof
     if (FACTORING_ZK_verify(&N, &E, &Y) != FACTORING_ZK_OK)
@@ -72,20 +65,6 @@
         exit(EXIT_FAILURE);
     }
 
-    // Kill modulus
-    FACTORING_ZK_kill_modulus(&m);
-    if (FF_2048_comp(m.p, zero, HFLEN_2048))
-    {
-        printf("FAILUER FACTORING_ZK_kill_modulus. P not zeroed\n");
-        exit(EXIT_FAILURE);
-    }
-
-    if (FF_2048_comp(m.q, zero, HFLEN_2048))
-    {
-        printf("FAILUER FACTORING_ZK_kill_modulus. Q not zeroed\n");
-        exit(EXIT_FAILURE);
-    }
-
     printf("SUCCESS\n");
     exit(EXIT_SUCCESS);
 }
diff --git a/test/unit/test_factoring_zk_prove.c b/test/unit/test_factoring_zk_prove.c
index cab95ee..5c9c3eb 100644
--- a/test/unit/test_factoring_zk_prove.c
+++ b/test/unit/test_factoring_zk_prove.c
@@ -53,11 +53,18 @@
     octet YGOLDEN = {0, sizeof(ygolden), ygolden};
     const char *Yline = "Y = ";
 
-    FACTORING_ZK_modulus m;
-    const char *Nline = "N = ";
+    char p[HFS_2048];
+    octet P = {0, sizeof(p), p};
     const char *Pline = "P = ";
+
+    char q[HFS_2048];
+    octet Q = {0, sizeof(q), q};
     const char *Qline = "Q = ";
 
+    char n[FS_2048];
+    octet N = {0, sizeof(n), n};
+    const char *Nline = "N = ";
+
     char e[FACTORING_ZK_B];
     octet E = {0, sizeof(e), e};
 
@@ -79,9 +86,9 @@
         scan_int(&testNo, line, TESTline);
 
         // Read modulus
-        scan_FF_2048(fp, m.p, line, Pline, HFLEN_2048);
-        scan_FF_2048(fp, m.q, line, Qline, HFLEN_2048);
-        scan_FF_2048(fp, m.n, line, Nline, FFLEN_2048);
+        scan_OCTET(fp, &P, line, Pline);
+        scan_OCTET(fp, &Q, line, Qline);
+        scan_OCTET(fp, &N, line, Nline);
 
         // Read non-random R
         scan_OCTET(fp, &R, line, Rline);
@@ -93,7 +100,7 @@
         // Read Y and run test
         if (!strncmp(line, last_line, strlen(last_line)))
         {
-            FACTORING_ZK_prove(&m, NULL, &R, &E, &Y);
+            FACTORING_ZK_prove(NULL, &P, &Q, &R, &E, &Y);
 
             compare_OCT(fp, testNo, "FACTORING_ZK_prove E", &E, &EGOLDEN);
             compare_OCT(fp, testNo, "FACTORING_ZK_prove Y", &Y, &YGOLDEN);