Add ID and additional data from RFC8235
diff --git a/include/amcl/factoring_zk.h b/include/amcl/factoring_zk.h
index d4db1ac..4ae7a39 100644
--- a/include/amcl/factoring_zk.h
+++ b/include/amcl/factoring_zk.h
@@ -55,11 +55,13 @@
  *  @param  RNG         Cryptographically secure PRNG
  *  @param  P           First prime of the factorization
  *  @param  Q           Second prime of the factorization
+ *  @param  ID          Prover unique identifier
+ *  @param  AD          Additional data to bind in the proof - Optional
  *  @param  R           Random value used in the proof. If RNG is NULL this is read
  *  @param  E           First component of the ZK proof
  *  @param  Y           Second component of the ZK proof
  */
-void FACTORING_ZK_prove(csprng *RNG, octet *P, octet *Q, octet *R, octet *E, octet *Y);
+void FACTORING_ZK_prove(csprng *RNG, octet *P, octet *Q, octet *ID, octet *AD, octet *R, octet *E, octet *Y);
 
 /** \brief Verify ZK proof of knowledge of factoring of N
  *
@@ -68,9 +70,11 @@
  *  @param  N           Public integer, the RSA modulus
  *  @param  E           Fisrt component of the ZK proof
  *  @param  Y           Second component of the ZK proof
+ *  @param  ID          Prover unique identifier
+ *  @param  AD          Additional data to bind in the proof - Optional
  *  @return             1 if the proof is valid, 0 otherwise
  */
-int FACTORING_ZK_verify(octet *N, octet *E, octet *Y);
+int FACTORING_ZK_verify(octet *N, octet *E, octet *Y, octet *ID, octet *AD);
 
 #ifdef __cplusplus
 }
diff --git a/include/amcl/schnorr.h b/include/amcl/schnorr.h
index 74529b7..8ab93a8 100644
--- a/include/amcl/schnorr.h
+++ b/include/amcl/schnorr.h
@@ -68,9 +68,11 @@
  *
  * @param V     Public ECP of the DLOG. V = x.G. Compressed form
  * @param C     Public commitment value. Compressed form
+ * @param ID    Prover unique identifier
+ * @param AD    Additional data to bind in the challenge - Optional
  * @param E     Challenge generated
  */
-extern void SCHNORR_challenge(const octet *V, const octet *C, octet *E);
+extern void SCHNORR_challenge(const octet *V, const octet *C, octet *ID, octet *AD, octet *E);
 
 /*! \brief Generate the proof for the given commitment and challenge
  *
@@ -111,14 +113,16 @@
  *
  * Compute the challenge for the proof. RFC8235#section-3.3 can not be applied
  * here, but we try to follow closely by treating R like a secondary generator.
- * Returns H(G, R, C, V)
+ * Returns H(G, R, C, V, ID[, AD])
  *
  * @param V     Public ECP result of the DLOG. V = s.R + l.G. Compressed form
  * @param R     Public ECP base of the DLOG. Compressed form
  * @param C     Public commitment value. Compressed form
+ * @param ID    Prover unique identifier
+ * @param AD    Additional data to bind in the challenge - Optional
  * @param E     Challenge generated
  */
-extern void SCHNORR_D_challenge(const octet *R, const octet *V, const octet *C, octet *E);
+extern void SCHNORR_D_challenge(const octet *R, const octet *V, const octet *C, octet* ID, octet *AD, octet *E);
 
 /*! \brief Generate the proof for the given commitment and challenge
  *
diff --git a/src/factoring_zk.c b/src/factoring_zk.c
index 7578733..d8d24e9 100644
--- a/src/factoring_zk.c
+++ b/src/factoring_zk.c
@@ -90,10 +90,10 @@
 /*
  *  Zi = MGF_SHA256(N, i)
  *  X  = H(Z1^r, Z2^r)
- *  e  = H'(N, Z1, Z2, X)
+ *  e  = H'(N, Z1, Z2, X, ID, AD)
  *  y  = r + (N - phi(N)) * e
  */
-void FACTORING_ZK_prove(csprng *RNG, octet *P, octet *Q, octet *R, octet *E, octet *Y)
+void FACTORING_ZK_prove(csprng *RNG, octet *P, octet *Q, octet *ID, octet *AD, octet *R, octet *E, octet *Y)
 {
     int i;
 
@@ -188,8 +188,15 @@
     HASH256_hash(&sha_x, W.val);
     W.len = SHA256;
 
-    // Compute e = H(N, Z1, Z2, X)
+    // Compute e = H(N, Z1, Z2, X, ID, AD)
     hash_oct(&sha_prime, &W);
+    hash_oct(&sha_prime, ID);
+
+    if (AD != NULL)
+    {
+        hash_oct(&sha_prime, AD);
+    }
+
     HASH256_hash(&sha_prime, W.val);
     W.len = FACTORING_ZK_B;
 
@@ -222,7 +229,7 @@
     FF_2048_zero(hws, HFLEN_2048);
 }
 
-int FACTORING_ZK_verify(octet *N, octet *E, octet *Y)
+int FACTORING_ZK_verify(octet *N, octet *E, octet *Y, octet *ID, octet *AD)
 {
     int i;
 
@@ -303,8 +310,15 @@
     HASH256_hash(&sha_x, W.val);
     W.len = SHA256;
 
-    // Compute e = H(N, Z1, Z2, X)
+    // Compute e = H(N, Z1, Z2, X, ID, AD)
     hash_oct(&sha_prime, &W);
+    hash_oct(&sha_prime, ID);
+
+    if (AD != NULL)
+    {
+        hash_oct(&sha_prime, AD);
+    }
+
     HASH256_hash(&sha_prime, W.val);
     W.len = FACTORING_ZK_B;
 
diff --git a/src/schnorr.c b/src/schnorr.c
index 7d20095..f5082ce 100644
--- a/src/schnorr.c
+++ b/src/schnorr.c
@@ -75,7 +75,7 @@
     BIG_256_56_zero(r);
 }
 
-void SCHNORR_challenge(const octet *V, const octet *C, octet *E)
+void SCHNORR_challenge(const octet *V, const octet *C, octet *ID, octet *AD, octet *E)
 {
     hash256 sha;
 
@@ -91,11 +91,18 @@
     ECP_SECP256K1_generator(&G);
     ECP_SECP256K1_toOctet(&O, &G, true);
 
-    // e = H(G,C,V) mod q
+    // e = H(G,C,V,ID,AD) mod q
     HASH256_init(&sha);
     hash_octet(&sha, &O);
     hash_octet(&sha, C);
     hash_octet(&sha, V);
+    hash_octet(&sha, ID);
+
+    if (AD != NULL)
+    {
+        hash_octet(&sha, AD);
+    }
+
     HASH256_hash(&sha, o);
 
     BIG_256_56_fromBytesLen(e, o, SHA256);
@@ -219,7 +226,7 @@
     return SCHNORR_OK;
 }
 
-void SCHNORR_D_challenge(const octet *R, const octet *V, const octet *C, octet *E)
+void SCHNORR_D_challenge(const octet *R, const octet *V, const octet *C, octet *ID, octet *AD, octet *E)
 {
     hash256 sha;
 
@@ -235,12 +242,19 @@
     ECP_SECP256K1_generator(&G);
     ECP_SECP256K1_toOctet(&O, &G, true);
 
-    // e = H(G,R,C,V) mod q
+    // e = H(G,R,C,V,ID,AD) mod q
     HASH256_init(&sha);
     hash_octet(&sha, &O);
     hash_octet(&sha, R);
     hash_octet(&sha, C);
     hash_octet(&sha, V);
+    hash_octet(&sha, ID);
+
+    if (AD != NULL)
+    {
+        hash_octet(&sha, AD);
+    }
+
     HASH256_hash(&sha, o);
 
     BIG_256_56_fromBytesLen(e, o, SHA256);