You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@milagro.apache.org by br...@apache.org on 2018/11/08 00:12:44 UTC

[24/51] [partial] incubator-milagro-crypto-c git commit: update code

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_wcc_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_wcc_ZZZ.c.in b/test/test_wcc_ZZZ.c.in
new file mode 100644
index 0000000..f0d39c6
--- /dev/null
+++ b/test/test_wcc_ZZZ.c.in
@@ -0,0 +1,271 @@
+/**
+ * @file test_wcc.c
+ * @author Kealan McCusker
+ * @brief Test WCC with and without time permits
+ *
+ * LICENSE
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+/* Smoke test: Test WCC */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "utils.h"
+#include "config_curve_ZZZ.h"
+#include "randapi.h"
+#if CURVE_SECURITY_ZZZ == 128
+#include "wcc_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "wcc192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "wcc256_ZZZ.h"
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*WCC_PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*WCC_PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*WCC_PFS_ZZZ
+#endif
+
+// #define DEBUG
+
+int main()
+{
+    int i,rtn;
+
+    /* Master secret */
+    char ms[WCC_PGS_ZZZ];
+    octet MS= {sizeof(ms),sizeof(ms),ms};
+
+    // sender key
+    char akeyG1[2*WCC_PFS_ZZZ+1];
+    octet AKeyG1= {0,sizeof(akeyG1), akeyG1};
+
+    // receiver key
+    char bkeyG2[G2LEN];
+    octet BKeyG2= {0,sizeof(bkeyG2), bkeyG2};
+
+    // Identities
+    char alice_id[256],bob_id[256];
+    octet IdA= {0,sizeof(alice_id),alice_id};
+    octet IdB= {0,sizeof(bob_id),bob_id};
+
+    // Hash of the identities
+    char hida[WCC_PFS_ZZZ], hidb[WCC_PFS_ZZZ];
+    octet HIdA = {0,sizeof(hida),hida};
+    octet HIdB = {0,sizeof(hidb),hidb};
+
+    char x[WCC_PGS_ZZZ];
+    octet X= {0,sizeof(x),x};
+    char y[WCC_PGS_ZZZ];
+    octet Y= {0,sizeof(y),y};
+    char w[WCC_PGS_ZZZ];
+    octet W= {0,sizeof(w),w};
+    char pia[WCC_PGS_ZZZ];
+    octet PIA= {0,sizeof(pia),pia};
+    char pib[WCC_PGS_ZZZ];
+    octet PIB= {0,sizeof(pib),pib};
+
+    char pgg1[2*WCC_PFS_ZZZ+1];
+    octet PgG1= {0,sizeof(pgg1), pgg1};
+
+    char pag1[2*WCC_PFS_ZZZ+1];
+    octet PaG1= {0,sizeof(pag1), pag1};
+
+    char pbg2[G2LEN];
+    octet PbG2= {0,sizeof(pbg2), pbg2};
+
+    char seed[32] = {0};
+    octet SEED = {0,sizeof(seed),seed};
+    csprng RNG;
+
+    char message1[256];
+    octet MESSAGE1 = {0, sizeof(message1), message1};
+    OCT_jstring(&MESSAGE1,"Hello Bob");
+
+    char k1[AESKEY_ZZZ];  // AES Key
+    char k2[AESKEY_ZZZ];  // AES Key
+    octet K1= {0,sizeof(k1),k1};
+    octet K2= {0,sizeof(k2),k2};
+
+    // Zero octet
+    char zero[AESKEY_ZZZ];
+    octet ZERO= {0,sizeof(zero),zero};
+    for(i=0; i<AESKEY_ZZZ; i++)
+    {
+        ZERO.val[i]=0;
+    }
+
+    /* non random seed value */
+    SEED.len=32;
+    for (i=0; i<32; i++) SEED.val[i]=i+1;
+
+    /* initialise random number generator */
+    CREATE_CSPRNG(&RNG,&SEED);
+
+#ifdef DEBUG
+    printf("SEED: 0x");
+    OCT_output(&SEED);
+#endif
+
+    /* TA: Generate master secret  */
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&MS);
+    if (rtn != 0)
+    {
+        printf("TA WCC_ZZZ_RANDOM_GENERATE() Error %d\n", rtn);
+        return 1;
+    }
+
+    printf("MS: 0x");
+    OCT_output(&MS);
+
+    // Alice's ID
+    OCT_jstring(&IdA,"alice@miracl.com");
+
+    // Hash Alice's Id
+    HASH_ID(HASH_TYPE_ZZZ,&IdA,&HIdA);
+
+    // TA: Generate Alice's sender key
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&MS,&HIdA,&AKeyG1);
+    if (rtn != 0)
+    {
+        printf("TA WCC_ZZZ_GET_G1_MULTIPLE() Error %d\n", rtn);
+        return 1;
+    }
+
+    // Bob's ID
+    OCT_jstring(&IdB,"bob@miracl.com");
+
+    // Hash Bob's Id
+    HASH_ID(HASH_TYPE_ZZZ,&IdB,&HIdB);
+
+    // TA: Generate Bob's receiver key
+    rtn = WCC_ZZZ_GET_G2_MULTIPLE(&MS,&HIdB,&BKeyG2);
+    if (rtn != 0)
+    {
+        printf("TA WCC_ZZZ_GET_G2_MULTIPLE() Error %d\n", rtn);
+        return 1;
+    }
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&X);
+    if (rtn != 0)
+    {
+        printf("Alice WCC_ZZZ_RANDOM_GENERATE() Error %d\n", rtn);
+        return 1;
+    }
+
+    printf("X: 0x");
+    OCT_output(&X);
+
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&X,&HIdA,&PaG1);
+    if (rtn != 0)
+    {
+        printf("Alice WCC_ZZZ_GET_G1_MULTIPLE() Error %d\n", rtn);
+        return 1;
+    }
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&W);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_RANDOM_GENERATE() Error %d\n", rtn);
+        return 1;
+    }
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&W,&HIdA,&PgG1);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_GET_G1_MULTIPLE() Error %d\n", rtn);
+        return 1;
+    }
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y) Error %d\n", rtn);
+        return 1;
+    }
+
+    rtn = WCC_ZZZ_GET_G2_MULTIPLE(&Y,&HIdB,&PbG2);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_GET_G1_MULTIPLE() Error %d\n", rtn);
+        return 1;
+    }
+
+    // pia = Hq(PaG1,PbG2,PgG1,IdB)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+
+    // pib = Hq(PbG2,PaG1,PgG1,IdA)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+
+    // Bob calculates AES Key
+    rtn = WCC_ZZZ_RECEIVER_KEY(HASH_TYPE_ZZZ,&Y,&W, &PIA,&PIB,&PaG1,&PgG1,&BKeyG2,&IdA,&K2);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_RECEIVER_KEY() Error %d\n", rtn);
+        return 1;
+    }
+    if (OCT_comp(&K2,&ZERO))
+    {
+        printf("Bob WCC_ZZZ_Receiver_KEY() Error: generated key is zero\n");
+        return 1;
+    }
+
+    // pia = Hq(PaG1,PbG2,PgG1,IdB)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+
+    // pib = Hq(PbG2,PaG1,PgG1,IdA)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+
+    // printf("PIA: ");OCT_output(&PIA);printf("\n");
+    // printf("PIB: ");OCT_output(&PIB);printf("\n");
+
+    // Alice calculates AES Key
+    rtn = WCC_ZZZ_SENDER_KEY(HASH_TYPE_ZZZ,&X,&PIA,&PIB,&PbG2,&PgG1,&AKeyG1,&IdB,&K1);
+    if (rtn != 0)
+    {
+        printf("Alice WCC_ZZZ_SENDER_KEY() Error %d\n", rtn);
+        return 1;
+    }
+    if (OCT_comp(&K1,&ZERO))
+    {
+        printf("Alice WCC_ZZZ_SENDER_KEY() Error: generated key is zero\n");
+        return 1;
+    }
+
+    printf("K1: 0x");
+    OCT_output(&K1);
+    printf("K2: 0x");
+    OCT_output(&K2);
+    if (!OCT_comp(&K1,&K2))
+    {
+        printf("FAILURE OCT_comp(&K1,&K2)\n");
+        return 1;
+    }
+
+    KILL_CSPRNG(&RNG);
+
+    printf("SUCCESS\n");
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_wcc_bad_receiver_key_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_wcc_bad_receiver_key_ZZZ.c.in b/test/test_wcc_bad_receiver_key_ZZZ.c.in
new file mode 100644
index 0000000..d705830
--- /dev/null
+++ b/test/test_wcc_bad_receiver_key_ZZZ.c.in
@@ -0,0 +1,590 @@
+/**
+ * @file test_wcc_random.c
+ * @author Samuele Andreoli
+ * @brief Test WCC with bad receiver key
+ *
+ * LICENSE
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* Smoke test: Test WCC using the wrong receiver key, i.e. a key generated from a different identity */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "utils.h"
+#include "config_curve_ZZZ.h"
+#include "randapi.h"
+#if CURVE_SECURITY_ZZZ == 128
+#include "wcc_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "wcc192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "wcc256_ZZZ.h"
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*WCC_PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*WCC_PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*WCC_PFS_ZZZ
+#endif
+
+// #define DEBUG
+
+int main()
+{
+    int i,rtn;
+
+    // Master secret
+    char ms[WCC_PGS_ZZZ];
+    octet MS= {0,sizeof(ms),ms};
+
+    // Alice Sender key
+    char akeyG1[2*WCC_PFS_ZZZ+1];
+    octet AKeyG1= {0,sizeof(akeyG1), akeyG1};
+
+    // Bob Receiver key
+    char bkeyG2[G2LEN];
+    octet BKeyG2= {0,sizeof(bkeyG2), bkeyG2};
+
+    // Eve Receiver key
+    char ekeyG2[G2LEN];
+    octet EKeyG2= {0,sizeof(ekeyG2), ekeyG2};
+
+    // Identities
+    char alice_id[256],bob_id[256],eve_id[256];
+    octet IdA= {0,sizeof(alice_id),alice_id};
+    octet IdB= {0,sizeof(bob_id),bob_id};
+    octet IdE= {0,sizeof(eve_id),eve_id};
+
+    // Hash of the identities
+    char hida[WCC_PFS_ZZZ], hidb[WCC_PFS_ZZZ], hide[WCC_PFS_ZZZ];
+    octet HIdA = {0,sizeof(hida),hida};
+    octet HIdB = {0,sizeof(hidb),hidb};
+    octet HIdE = {0,sizeof(hide),hide};
+
+    // Ephemeral and intermediate values
+    char x[WCC_PGS_ZZZ];
+    octet X= {0,sizeof(x),x};
+    char y[WCC_PGS_ZZZ];
+    octet Y= {0,sizeof(y),y};
+    char w[WCC_PGS_ZZZ];
+    octet W= {0,sizeof(w),w};
+    char pia[WCC_PGS_ZZZ];
+    octet PIA= {0,sizeof(pia),pia};
+    char pib[WCC_PGS_ZZZ];
+    octet PIB= {0,sizeof(pib),pib};
+
+    char pgg1[2*WCC_PFS_ZZZ+1];
+    octet PgG1= {0,sizeof(pgg1), pgg1};
+
+    char pag1[2*WCC_PFS_ZZZ+1];
+    octet PaG1= {0,sizeof(pag1), pag1};
+
+    char pbg2[G2LEN];
+    octet PbG2= {0,sizeof(pbg2), pbg2};
+
+    // Derived AES keys
+    char k1[AESKEY_ZZZ];
+    char k2[AESKEY_ZZZ];
+    octet K1= {0,sizeof(k1),k1};
+    octet K2= {0,sizeof(k2),k2};
+
+    // Zero octet
+    char zero[AESKEY_ZZZ];
+    octet ZERO= {0,sizeof(zero),zero};
+    for(i=0; i<AESKEY_ZZZ; i++)
+    {
+        ZERO.val[i]=0;
+    }
+
+    // non random seed value
+    char seed[32] = {0};
+    octet SEED = {sizeof(seed),sizeof(seed),seed};
+    for (i=0; i<32; i++) SEED.val[i]=i+1;
+    csprng RNG;
+
+#ifdef DEBUG
+    printf("SEED 0x");
+    OCT_output(&SEED);
+#endif
+
+    /* initialize random number generator */
+    CREATE_CSPRNG(&RNG,&SEED);
+
+    /* Generate master secret */
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&MS);
+    if (rtn != 0)
+    {
+        printf("TA WCC_ZZZ_RANDOM_GENERATE(&RNG,&MS) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("TA MASTER SECRET: ");
+    OCT_output(&MS);
+#endif
+
+
+    /* Generate key material for Alice, Bob and Eve */
+
+    // Alice's ID
+    OCT_jstring(&IdA,"alice@miracl.com");
+#ifdef DEBUG
+    printf("ALICE ID:");
+    OCT_output_string(&IdA);
+    printf("\n");
+#endif
+
+    // Hash Alice's Id
+    HASH_ID(HASH_TYPE_ZZZ,&IdA,&HIdA);
+
+    // TA: Generate Alice's sender key
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&MS,&HIdA,&AKeyG1);
+    if (rtn != 0)
+    {
+        printf("TA WCC_ZZZ_GET_G1_MULTIPLE(&MS,&HIdA,&AKeyG1) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("TA Alice's sender key: ");
+    OCT_output(&AKeyG1);
+#endif
+
+    // Bob's ID
+    OCT_jstring(&IdB,"bob@miracl.com");
+#ifdef DEBUG
+    printf("BOB ID:");
+    OCT_output_string(&IdB);
+    printf("\n");
+#endif
+
+    // Hash Bob's Id
+    HASH_ID(HASH_TYPE_ZZZ,&IdB,&HIdB);
+
+    // TA: Generate Bob's receiver key
+    rtn = WCC_ZZZ_GET_G2_MULTIPLE(&MS,&HIdB,&BKeyG2);
+    if (rtn != 0)
+    {
+        printf("TA WCC_ZZZ_GET_G2_MULTIPLE(&MS,&HIdB,&BKeyG2) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("TA Bob's receiver key: ");
+    OCT_output(&BKeyG2);
+#endif
+
+    // Eve's ID
+    OCT_jstring(&IdE,"eve@miracl.com");
+#ifdef DEBUG
+    printf("EVE ID:");
+    OCT_output_string(&IdE);
+    printf("\n");
+#endif
+
+    // Hash Eve's Id
+    HASH_ID(HASH_TYPE_ZZZ,&IdE,&HIdE);
+
+    // TA: Generate Eve's receiver key
+    rtn = WCC_ZZZ_GET_G2_MULTIPLE(&MS,&HIdE,&EKeyG2);
+    if (rtn != 0)
+    {
+        printf("TA WCC_ZZZ_GET_G2_MULTIPLE(&MS,&HIdE,&EKeyG2) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("TA Eve's receiver key: ");
+    OCT_output(&EKeyG2);
+#endif
+
+
+    /* TEST RUN: Check that the protocol is working when using the right receiver key */
+
+#ifdef DEBUG
+    printf("Control Run. Alice:\n");
+#endif
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&X);
+    if (rtn != 0)
+    {
+        printf("Alice WCC_ZZZ_RANDOM_GENERATE(&RNG,&X) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Alice X: ");
+    OCT_output(&X);
+    printf("\n");
+#endif
+
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&X,&HIdA,&PaG1);
+    if (rtn != 0)
+    {
+        printf("Alice WCC_ZZZ_GET_G1_MULTIPLE(&X,&HIdA,&PaG1) Error %d\n", rtn);
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("Alice sends IdA and PaG1 to Bob\n\n");
+    printf("Alice IdA: ");
+    OCT_output_string(&IdA);
+    printf("\n");
+    printf("Alice PaG1: ");
+    OCT_output(&PaG1);
+    printf("\n");
+#endif
+
+#ifdef DEBUG
+    printf("Bob\n");
+#endif
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&W);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_RANDOM_GENERATE(&RNG,&W) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Bob W: ");
+    OCT_output(&W);
+    printf("\n");
+#endif
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&W,&HIdA,&PgG1);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_GET_G1_MULTIPLE(&W,&HIdA,&PgG1) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("PgG1: ");
+    OCT_output(&PgG1);
+    printf("\n");
+#endif
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Bob Y: ");
+    OCT_output(&Y);
+    printf("\n");
+#endif
+    rtn = WCC_ZZZ_GET_G2_MULTIPLE(&Y,&HIdB,&PbG2);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_GET_G2_MULTIPLE(&Y,&HIdB,&PbG2) Error %d\n", rtn);
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("Bob PaG1: ");
+    OCT_output(&PaG1);
+    printf("\n");
+    printf("Bob PbG2: ");
+    OCT_output(&PbG2);
+    printf("\n");
+    printf("Bob PgG1: ");
+    OCT_output(&PgG1);
+    printf("\n");
+    printf("Bob IdB: ");
+    OCT_output(&IdB);
+    printf("\n");
+#endif
+
+    // pia = Hq(PaG1,PbG2,PgG1,IdB)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+
+    // pib = Hq(PbG2,PaG1,PgG1,IdA)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+
+#ifdef DEBUG
+    printf("Bob PIA: ");
+    OCT_output(&PIA);
+    printf("\n");
+    printf("Bob PIB: ");
+    OCT_output(&PIB);
+    printf("\n");
+#endif
+
+    // Bob calculates AES Key
+    rtn = WCC_ZZZ_RECEIVER_KEY(HASH_TYPE_ZZZ,&Y,&W,&PIA,&PIB,&PaG1,&PgG1,&BKeyG2,&IdA,&K2);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_RECEIVER_KEY() Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Bob AES Key: ");
+    OCT_output(&K2);
+#endif
+    if (OCT_comp(&K2,&ZERO))
+    {
+        printf("Bob WCC_ZZZ_RECEIVER_KEY() Error: generated key is zero\n");
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("Bob sends IdB, PbG2 and PgG1 to Alice\n\n");
+    printf("Bob IdB: ");
+    OCT_output_string(&IdB);
+    printf("\n");
+    printf("Bob PbG2: ");
+    OCT_output(&PbG2);
+    printf("\n");
+    printf("Bob PgG1: ");
+    OCT_output(&PgG1);
+    printf("\n");
+#endif
+
+#ifdef DEBUG
+    printf("Alice\n");
+#endif
+
+    // pia = Hq(PaG1,PbG2,PgG1,IdB)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+
+    // pib = Hq(PbG2,PaG1,PgG1,IdA)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+#ifdef DEBUG
+    printf("Alice PIA: ");
+    OCT_output(&PIA);
+    printf("\n");
+    printf("Alice PIB: ");
+    OCT_output(&PIB);
+    printf("\n");
+#endif
+
+    // Alice calculates AES Key
+    rtn = WCC_ZZZ_SENDER_KEY(HASH_TYPE_ZZZ,&X,&PIA,&PIB,&PbG2,&PgG1,&AKeyG1,&IdB,&K1);
+    if (rtn != 0)
+    {
+        printf("Alice WCC_ZZZ_SENDER_KEY() Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Alice AES Key: ");
+    OCT_output(&K1);
+#endif
+    if (OCT_comp(&K1,&ZERO))
+    {
+        printf("Alice WCC_ZZZ_SENDER_KEY() Error: generated key is zero\n");
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("K1: 0x");
+    OCT_output(&K1);
+    printf("K2: 0x");
+    OCT_output(&K2);
+#endif
+    if (!OCT_comp(&K1,&K2))
+    {
+        printf("FAILURE Control run keys do not match. OCT_comp(&K1,&K2)\n");
+        return 1;
+    }
+
+
+    /* BAD KEY RUN: Check that someone with the wrong receiver key obtains a different session key */
+
+#ifdef DEBUG
+    printf("Bad key run. Alice:\n");
+#endif
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&X);
+    if (rtn != 0)
+    {
+        printf("Alice WCC_ZZZ_RANDOM_GENERATE(&RNG,&X) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Alice X: ");
+    OCT_output(&X);
+    printf("\n");
+#endif
+
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&X,&HIdA,&PaG1);
+    if (rtn != 0)
+    {
+        printf("Alice WCC_ZZZ_GET_G1_MULTIPLE(&X,&HIdA,&PaG1) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Alice sends IdA and PaG1 to Bob\n\n");
+    printf("Alice IdA: ");
+    OCT_output_string(&IdA);
+    printf("\n");
+    printf("Alice PaG1: ");
+    OCT_output(&PaG1);
+    printf("\n");
+#endif
+
+#ifdef DEBUG
+    printf("Eve\n");
+#endif
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&W);
+    if (rtn != 0)
+    {
+        printf("Eve WCC_ZZZ_RANDOM_GENERATE(&RNG,&W) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Eve W: ");
+    OCT_output(&W);
+    printf("\n");
+#endif
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&W,&HIdA,&PgG1);
+    if (rtn != 0)
+    {
+        printf("Eve WCC_ZZZ_GET_G1_MULTIPLE(&W,&HIdA,&PgG1) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("PgG1: ");
+    OCT_output(&PgG1);
+    printf("\n");
+#endif
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y);
+    if (rtn != 0)
+    {
+        printf("Eve WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Eve Y: ");
+    OCT_output(&Y);
+    printf("\n");
+#endif
+    rtn = WCC_ZZZ_GET_G2_MULTIPLE(&Y,&HIdE,&PbG2);
+    if (rtn != 0)
+    {
+        printf("Eve WCC_ZZZ_GET_G2_MULTIPLE(&Y,&HIdE,&PbG2) Error %d\n", rtn);
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("Eve PbG2: ");
+    OCT_output(&PbG2);
+    printf("\n");
+#endif
+
+    // pia = Hq(PaG1,PbG2,PgG1,IdB)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+
+    // pib = Hq(PbG2,PaG1,PgG1,IdA)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+
+#ifdef DEBUG
+    printf("Eve PIA: ");
+    OCT_output(&PIA);
+    printf("\n");
+    printf("Eve PIB: ");
+    OCT_output(&PIB);
+    printf("\n");
+#endif
+
+    // Eve calculates AES Key
+    rtn = WCC_ZZZ_RECEIVER_KEY(HASH_TYPE_ZZZ,&Y,&W,&PIA,&PIB,&PaG1,&PgG1,&EKeyG2,&IdA,&K2);
+    if (rtn != 0)
+    {
+        printf("Eve WCC_ZZZ_RECEIVER_KEY() Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Eve AES Key: ");
+    OCT_output(&K2);
+#endif
+    if (OCT_comp(&K2,&ZERO))
+    {
+        printf("Eve WCC_ZZZ_RECEIVER_KEY() Error: generated key is zero\n");
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("Eve sends IdB, PbG2 and PgG1 to Alice\n\n");
+    printf("Eve IdB: ");
+    OCT_output_string(&IdB);
+    printf("\n");
+    printf("Eve PbG2: ");
+    OCT_output(&PbG2);
+    printf("\n");
+    printf("Eve PgG1: ");
+    OCT_output(&PgG1);
+    printf("\n");
+#endif
+
+#ifdef DEBUG
+    printf("Alice\n");
+#endif
+
+    // pia = Hq(PaG1,PbG2,PgG1,IdB)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+
+    // pib = Hq(PbG2,PaG1,PgG1,IdA)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+
+#ifdef DEBUG
+    printf("Alice PIA: ");
+    OCT_output(&PIA);
+    printf("\n");
+    printf("Alice PIB: ");
+    OCT_output(&PIB);
+    printf("\n");
+#endif
+
+    // Alice calculates AES Key
+    rtn = WCC_ZZZ_SENDER_KEY(HASH_TYPE_ZZZ,&X,&PIA,&PIB,&PbG2,&PgG1,&AKeyG1,&IdB,&K1);
+    if (rtn != 0)
+    {
+        printf("Alice WCC_ZZZ_SENDER_KEY() Error %d\n", rtn);
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("Alice AES Key: ");
+    OCT_output(&K1);
+#endif
+    if (OCT_comp(&K1,&ZERO))
+    {
+        printf("Alice WCC_ZZZ_SENDER_KEY() Error: generated key is zero\n");
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("K1: 0x");
+    OCT_output(&K1);
+    printf("K2: 0x");
+    OCT_output(&K2);
+#endif
+
+    if (OCT_comp(&K1,&K2))
+    {
+        printf("FAILURE Bad key run keys match. OCT_comp(&K1,&K2)\n");
+        return 1;
+    }
+
+    KILL_CSPRNG(&RNG);
+    printf("SUCCESS! WCC BAD RECEIVER KEY TEST\n");
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_wcc_bad_sender_key_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_wcc_bad_sender_key_ZZZ.c.in b/test/test_wcc_bad_sender_key_ZZZ.c.in
new file mode 100644
index 0000000..d9d8179
--- /dev/null
+++ b/test/test_wcc_bad_sender_key_ZZZ.c.in
@@ -0,0 +1,591 @@
+/**
+ * @file test_wcc_random.c
+ * @author Samuele Andreoli
+ * @brief Test WCC with bad sender key
+ *
+ * LICENSE
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* Smoke test: Test WCC using the wrong sender key, i.e. a key generated from a different identity */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "utils.h"
+#include "config_curve_ZZZ.h"
+#include "randapi.h"
+#if CURVE_SECURITY_ZZZ == 128
+#include "wcc_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "wcc192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "wcc256_ZZZ.h"
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*WCC_PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*WCC_PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*WCC_PFS_ZZZ
+#endif
+
+// #define DEBUG
+
+int main()
+{
+    int i,rtn;
+
+    // Master secret
+    char ms[WCC_PGS_ZZZ];
+    octet MS= {0,sizeof(ms),ms};
+
+    // Alice Sender key
+    char akeyG1[2*WCC_PFS_ZZZ+1];
+    octet AKeyG1= {0,sizeof(akeyG1), akeyG1};
+
+    // Eve Sender key
+    char ekeyG1[2*WCC_PFS_ZZZ+1];
+    octet EKeyG1= {0,sizeof(ekeyG1), ekeyG1};
+
+    // Bob Receiver key
+    char bkeyG2[G2LEN];
+    octet BKeyG2= {0,sizeof(bkeyG2), bkeyG2};
+
+    // Identities
+    char alice_id[256],bob_id[256],eve_id[256];
+    octet IdA= {0,sizeof(alice_id),alice_id};
+    octet IdB= {0,sizeof(bob_id),bob_id};
+    octet IdE= {0,sizeof(eve_id),eve_id};
+
+    // Hash of the identities
+    char hida[WCC_PFS_ZZZ], hidb[WCC_PFS_ZZZ], hide[WCC_PFS_ZZZ];
+    octet HIdA = {0,sizeof(hida),hida};
+    octet HIdB = {0,sizeof(hidb),hidb};
+    octet HIdE = {0,sizeof(hide),hide};
+
+    // Ephemeral and intermediate values
+    char x[WCC_PGS_ZZZ];
+    octet X= {0,sizeof(x),x};
+    char y[WCC_PGS_ZZZ];
+    octet Y= {0,sizeof(y),y};
+    char w[WCC_PGS_ZZZ];
+    octet W= {0,sizeof(w),w};
+    char pia[WCC_PGS_ZZZ];
+    octet PIA= {0,sizeof(pia),pia};
+    char pib[WCC_PGS_ZZZ];
+    octet PIB= {0,sizeof(pib),pib};
+
+    char pgg1[2*WCC_PFS_ZZZ+1];
+    octet PgG1= {0,sizeof(pgg1), pgg1};
+
+    char pag1[2*WCC_PFS_ZZZ+1];
+    octet PaG1= {0,sizeof(pag1), pag1};
+
+    char pbg2[G2LEN];
+    octet PbG2= {0,sizeof(pbg2), pbg2};
+
+    // Derived AES keys
+    char k1[AESKEY_ZZZ];
+    char k2[AESKEY_ZZZ];
+    octet K1= {0,sizeof(k1),k1};
+    octet K2= {0,sizeof(k2),k2};
+
+    // Zero octet
+    char zero[AESKEY_ZZZ];
+    octet ZERO= {0,sizeof(zero),zero};
+    for(i=0; i<AESKEY_ZZZ; i++)
+    {
+        ZERO.val[i]=0;
+    }
+
+    // non random seed value
+    char seed[32] = {0};
+    octet SEED = {sizeof(seed),sizeof(seed),seed};
+    for (i=0; i<32; i++) SEED.val[i]=i+1;
+    csprng RNG;
+
+#ifdef DEBUG
+    printf("SEED 0x");
+    OCT_output(&SEED);
+#endif
+
+    /* initialize random number generator */
+    CREATE_CSPRNG(&RNG,&SEED);
+
+    /* Generate master secret */
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&MS);
+    if (rtn != 0)
+    {
+        printf("TA WCC_ZZZ_RANDOM_GENERATE(&RNG,&MS) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("TA MASTER SECRET: ");
+    OCT_output(&MS);
+#endif
+
+
+    /* Generate key material for Alice, Bob and Eve */
+
+    // Alice's ID
+    OCT_jstring(&IdA,"alice@miracl.com");
+#ifdef DEBUG
+    printf("ALICE ID:");
+    OCT_output_string(&IdA);
+    printf("\n");
+#endif
+
+    // Hash Alice's Id
+    HASH_ID(HASH_TYPE_ZZZ,&IdA,&HIdA);
+
+    // TA: Generate Alice's sender key
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&MS,&HIdA,&AKeyG1);
+    if (rtn != 0)
+    {
+        printf("TA WCC_ZZZ_GET_G1_MULTIPLE(&MS,&HIdA,&AKeyG1) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("TA Alice's sender key: ");
+    OCT_output(&AKeyG1);
+#endif
+
+    // Bob's ID
+    OCT_jstring(&IdB,"bob@miracl.com");
+#ifdef DEBUG
+    printf("BOB ID:");
+    OCT_output_string(&IdB);
+    printf("\n");
+#endif
+
+    // Hash Bob's Id
+    HASH_ID(HASH_TYPE_ZZZ,&IdB,&HIdB);
+
+    // TA: Generate Bob's receiver key
+    rtn = WCC_ZZZ_GET_G2_MULTIPLE(&MS,&HIdB,&BKeyG2);
+    if (rtn != 0)
+    {
+        printf("TA WCC_ZZZ_GET_G2_MULTIPLE(&MS,&HIdB,&BKeyG2) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("TA Bob's receiver key: ");
+    OCT_output(&BKeyG2);
+#endif
+
+    // Eve's ID
+    OCT_jstring(&IdE,"eve@miracl.com");
+#ifdef DEBUG
+    printf("EVE ID:");
+    OCT_output_string(&IdE);
+    printf("\n");
+#endif
+
+    // Hash Eve's Id
+    HASH_ID(HASH_TYPE_ZZZ,&IdE,&HIdE);
+
+    // TA: Generate Eve's sender key
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&MS,&HIdE,&EKeyG1);
+    if (rtn != 0)
+    {
+        printf("TA WCC_ZZZ_GET_G1_MULTIPLE(&MS,&HIdE,&EKeyG1) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("TA Eve's sender key: ");
+    OCT_output(&EKeyG1);
+#endif
+
+    /* TEST RUN: Check that the protocol is working when using the right receiver key */
+
+
+#ifdef DEBUG
+    printf("Control Run. Alice:\n");
+#endif
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&X);
+    if (rtn != 0)
+    {
+        printf("Alice WCC_ZZZ_RANDOM_GENERATE(&RNG,&X) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Alice X: ");
+    OCT_output(&X);
+    printf("\n");
+#endif
+
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&X,&HIdA,&PaG1);
+    if (rtn != 0)
+    {
+        printf("Alice WCC_ZZZ_GET_G1_MULTIPLE(&X,&HIdA,&PaG1) Error %d\n", rtn);
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("Alice sends IdA and PaG1 to Bob\n\n");
+    printf("Alice IdA: ");
+    OCT_output_string(&IdA);
+    printf("\n");
+    printf("Alice PaG1: ");
+    OCT_output(&PaG1);
+    printf("\n");
+#endif
+
+#ifdef DEBUG
+    printf("Bob\n");
+#endif
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&W);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_RANDOM_GENERATE(&RNG,&W) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Bob W: ");
+    OCT_output(&W);
+    printf("\n");
+#endif
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&W,&HIdA,&PgG1);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_GET_G1_MULTIPLE(&W,&HIdA,&PgG1) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("PgG1: ");
+    OCT_output(&PgG1);
+    printf("\n");
+#endif
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Bob Y: ");
+    OCT_output(&Y);
+    printf("\n");
+#endif
+    rtn = WCC_ZZZ_GET_G2_MULTIPLE(&Y,&HIdB,&PbG2);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_GET_G2_MULTIPLE(&Y,&HIdB,&PbG2) Error %d\n", rtn);
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("Bob PaG1: ");
+    OCT_output(&PaG1);
+    printf("\n");
+    printf("Bob PbG2: ");
+    OCT_output(&PbG2);
+    printf("\n");
+    printf("Bob PgG1: ");
+    OCT_output(&PgG1);
+    printf("\n");
+    printf("Bob IdB: ");
+    OCT_output(&IdB);
+    printf("\n");
+#endif
+
+    // pia = Hq(PaG1,PbG2,PgG1,IdB)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+
+    // pib = Hq(PbG2,PaG1,PgG1,IdA)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+
+#ifdef DEBUG
+    printf("Bob PIA: ");
+    OCT_output(&PIA);
+    printf("\n");
+    printf("Bob PIB: ");
+    OCT_output(&PIB);
+    printf("\n");
+#endif
+
+    // Bob calculates AES Key
+    rtn = WCC_ZZZ_RECEIVER_KEY(HASH_TYPE_ZZZ,&Y,&W,&PIA,&PIB,&PaG1,&PgG1,&BKeyG2,&IdA,&K2);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_RECEIVER_KEY() Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Bob AES Key: ");
+    OCT_output(&K2);
+#endif
+    if (OCT_comp(&K2,&ZERO))
+    {
+        printf("Bob WCC_ZZZ_RECEIVER_KEY() Error: generated key is zero\n");
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("Bob sends IdB, PbG2 and PgG1 to Alice\n\n");
+    printf("Bob IdB: ");
+    OCT_output_string(&IdB);
+    printf("\n");
+    printf("Bob PbG2: ");
+    OCT_output(&PbG2);
+    printf("\n");
+    printf("Bob PgG1: ");
+    OCT_output(&PgG1);
+    printf("\n");
+#endif
+
+#ifdef DEBUG
+    printf("Alice\n");
+#endif
+
+    // pia = Hq(PaG1,PbG2,PgG1,IdB)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+
+    // pib = Hq(PbG2,PaG1,PgG1,IdA)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+
+#ifdef DEBUG
+    printf("Alice PIA: ");
+    OCT_output(&PIA);
+    printf("\n");
+    printf("Alice PIB: ");
+    OCT_output(&PIB);
+    printf("\n");
+#endif
+
+    // Alice calculates AES Key
+    rtn = WCC_ZZZ_SENDER_KEY(HASH_TYPE_ZZZ,&X,&PIA,&PIB,&PbG2,&PgG1,&AKeyG1,&IdB,&K1);
+    if (rtn != 0)
+    {
+        printf("Alice WCC_ZZZ_SENDER_KEY() Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Alice AES Key: ");
+    OCT_output(&K1);
+#endif
+    if (OCT_comp(&K1,&ZERO))
+    {
+        printf("Alice WCC_ZZZ_SENDER_KEY() Error: generated key is zero\n");
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("K1: 0x");
+    OCT_output(&K1);
+    printf("K2: 0x");
+    OCT_output(&K2);
+#endif
+    if (!OCT_comp(&K1,&K2))
+    {
+        printf("FAILURE Control run keys do not match. OCT_comp(&K1,&K2)\n");
+        return 1;
+    }
+
+
+    /* BAD KEY RUN: Check that someone with the wrong sender key obtains a different session key */
+
+#ifdef DEBUG
+    printf("Bad key run. Eve:\n");
+#endif
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&X);
+    if (rtn != 0)
+    {
+        printf("Eve WCC_ZZZ_RANDOM_GENERATE(&RNG,&X) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Eve X: ");
+    OCT_output(&X);
+    printf("\n");
+#endif
+
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&X,&HIdA,&PaG1);
+    if (rtn != 0)
+    {
+        printf("Eve WCC_ZZZ_GET_G1_MULTIPLE(&X,&HIdA,&PaG1) Error %d\n", rtn);
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("Eve sends IdA and PaG1 to Bob\n\n");
+    printf("Eve IdA: ");
+    OCT_output_string(&IdA);
+    printf("\n");
+    printf("Eve PaG1: ");
+    OCT_output(&PaG1);
+    printf("\n");
+#endif
+
+#ifdef DEBUG
+    printf("Bob\n");
+#endif
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&W);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_RANDOM_GENERATE(&RNG,&W) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Bob W: ");
+    OCT_output(&W);
+    printf("\n");
+#endif
+    rtn = WCC_ZZZ_GET_G1_MULTIPLE(&W,&HIdA,&PgG1);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_GET_G1_MULTIPLE(&W,&HIdA,&PgG1) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("PgG1: ");
+    OCT_output(&PgG1);
+    printf("\n");
+#endif
+
+    rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y) Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Bob Y: ");
+    OCT_output(&Y);
+    printf("\n");
+#endif
+    rtn = WCC_ZZZ_GET_G2_MULTIPLE(&Y,&HIdB,&PbG2);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_GET_G2_MULTIPLE(&Y,&HIdB,&PbG2) Error %d\n", rtn);
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("Bob PbG2: ");
+    OCT_output(&PbG2);
+    printf("\n");
+#endif
+
+    // pia = Hq(PaG1,PbG2,PgG1,IdB)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+
+    // pib = Hq(PbG2,PaG1,PgG1,IdA)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+
+#ifdef DEBUG
+    printf("Bob PIA: ");
+    OCT_output(&PIA);
+    printf("\n");
+    printf("Bob PIB: ");
+    OCT_output(&PIB);
+    printf("\n");
+#endif
+
+    // Bob calculates AES Key
+    rtn = WCC_ZZZ_RECEIVER_KEY(HASH_TYPE_ZZZ,&Y,&W,&PIA,&PIB,&PaG1,&PgG1,&BKeyG2,&IdA,&K2);
+    if (rtn != 0)
+    {
+        printf("Bob WCC_ZZZ_RECEIVER_KEY() Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Bob AES Key: ");
+    OCT_output(&K2);
+#endif
+    if (OCT_comp(&K2,&ZERO))
+    {
+        printf("Bob WCC_ZZZ_RECEIVER_KEY() Error: generated key is zero\n");
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("Bob sends IdB, PbG2 and PgG1 to Alice\n\n");
+    printf("Bob IdB: ");
+    OCT_output_string(&IdB);
+    printf("\n");
+    printf("Bob PbG2: ");
+    OCT_output(&PbG2);
+    printf("\n");
+    printf("Bob PgG1: ");
+    OCT_output(&PgG1);
+    printf("\n");
+#endif
+
+#ifdef DEBUG
+    printf("Eve\n");
+#endif
+
+    // pia = Hq(PaG1,PbG2,PgG1,IdB)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+
+    // pib = Hq(PbG2,PaG1,PgG1,IdA)
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+
+#ifdef DEBUG
+    printf("Eve PIA: ");
+    OCT_output(&PIA);
+    printf("\n");
+    printf("Eve PIB: ");
+    OCT_output(&PIB);
+    printf("\n");
+#endif
+
+    // Eve calculates AES Key. nb use wrong key EKeyG1
+    rtn = WCC_ZZZ_SENDER_KEY(HASH_TYPE_ZZZ,&X,&PIA,&PIB,&PbG2,&PgG1,&EKeyG1,&IdB,&K1);
+    if (rtn != 0)
+    {
+        printf("Eve WCC_ZZZ_SENDER_KEY() Error %d\n", rtn);
+        return 1;
+    }
+#ifdef DEBUG
+    printf("Eve AES Key: ");
+    OCT_output(&K1);
+#endif
+    if (OCT_comp(&K1,&ZERO))
+    {
+        printf("Eve WCC_ZZZ_SENDER_KEY() Error: generated key is zero\n");
+        return 1;
+    }
+
+#ifdef DEBUG
+    printf("K1: 0x");
+    OCT_output(&K1);
+    printf("K2: 0x");
+    OCT_output(&K2);
+#endif
+
+    if (OCT_comp(&K1,&K2))
+    {
+        printf("FAILURE Bad key run keys match. OCT_comp(&K1,&K2)\n");
+        return 1;
+    }
+
+    KILL_CSPRNG(&RNG);
+    printf("SUCCESS! WCC BAD RECEIVER KEY TEST\n");
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_wcc_invalid_points_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_wcc_invalid_points_ZZZ.c.in b/test/test_wcc_invalid_points_ZZZ.c.in
new file mode 100644
index 0000000..cf70de2
--- /dev/null
+++ b/test/test_wcc_invalid_points_ZZZ.c.in
@@ -0,0 +1,245 @@
+/**
+ * @file test_wcc_invalid_points.c
+ * @author Samuele Andreoli
+ * @brief Test WCC handling of invalid points
+ *
+ * LICENSE
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* Test WCC with invalid, random generated, points */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "utils.h"
+#include "config_curve_ZZZ.h"
+#include "config_test.h"
+#include "randapi.h"
+#if CURVE_SECURITY_ZZZ == 128
+#include "wcc_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "wcc192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "wcc256_ZZZ.h"
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*WCC_PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*WCC_PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*WCC_PFS_ZZZ
+#endif
+
+// #define DEBUG
+
+int main()
+{
+
+    /* Master secret */
+    char ms[WCC_PGS_ZZZ];
+    octet MS= {sizeof(ms),sizeof(ms),ms};
+
+    // Sender key
+    char akeyG1[2*WCC_PFS_ZZZ+1];
+    octet AKeyG1= {0,sizeof(akeyG1), akeyG1};
+
+    // Receiver key
+    char bkeyG2[G2LEN];
+    octet BKeyG2= {0,sizeof(bkeyG2), bkeyG2};
+
+    // Identities
+    char alice_id[256],bob_id[256];
+    octet IdA= {0,sizeof(alice_id),alice_id};
+    octet IdB= {0,sizeof(bob_id),bob_id};
+
+    // Hash of the identities
+    char hida[WCC_PFS_ZZZ], hidb[WCC_PFS_ZZZ];
+    octet HIdA = {0,sizeof(hida),hida};
+    octet HIdB = {0,sizeof(hidb),hidb};
+
+    // Ephemeral parameters
+    char x[WCC_PGS_ZZZ];
+    octet X= {0,sizeof(x),x};
+    char y[WCC_PGS_ZZZ];
+    octet Y= {0,sizeof(y),y};
+    char w[WCC_PGS_ZZZ];
+    octet W= {0,sizeof(w),w};
+    char pia[WCC_PGS_ZZZ];
+    octet PIA= {0,sizeof(pia),pia};
+    char pib[WCC_PGS_ZZZ];
+    octet PIB= {0,sizeof(pib),pib};
+
+    char pgg1[2*WCC_PFS_ZZZ+1];
+    octet PgG1= {0,sizeof(pgg1), pgg1};
+    char pag1[2*WCC_PFS_ZZZ+1];
+    octet PaG1= {0,sizeof(pag1), pag1};
+    char pbg2[G2LEN];
+    octet PbG2= {0,sizeof(pbg2), pbg2};
+
+    // Invalid points
+    char invalidG1[2*WCC_PFS_ZZZ+1];
+    octet InvalidG1= {0,sizeof(invalidG1), invalidG1};
+
+    char invalidG2[G2LEN];
+    octet InvalidG2= {0,sizeof(invalidG2), invalidG2};
+
+    // Session keys
+    char k1[AESKEY_ZZZ];
+    octet K1= {0,sizeof(k1),k1};
+    char k2[AESKEY_ZZZ];
+    octet K2= {0,sizeof(k2),k2};
+
+    char seed[32] = {0};
+    octet SEED = {0,sizeof(seed),seed};
+    csprng RNG;
+
+    int i, rtn;
+
+    /* non random seed value */
+    SEED.len=32;
+    for (i=0; i<32; i++) SEED.val[i]=i+1;
+
+    /* initialize random number generator */
+    CREATE_CSPRNG(&RNG,&SEED);
+
+    /* TEST RUN: execute a test run with valid points to make sure
+     * the protocol runs correctly with valid points
+     */
+
+    /* TA: Generate master secret  */
+    WCC_ZZZ_RANDOM_GENERATE(&RNG,&MS);
+
+    // Alice's ID
+    OCT_jstring(&IdA,"alice@miracl.com");
+
+    // Hash Alice's Id
+    HASH_ID(HASH_TYPE_ZZZ,&IdA,&HIdA);
+
+    // TA: Generate Alice's sender key
+    WCC_ZZZ_GET_G1_MULTIPLE(&MS,&HIdA,&AKeyG1);
+
+    // Bob's ID
+    OCT_jstring(&IdB,"bob@miracl.com");
+
+    // Hash Bob's Id
+    HASH_ID(HASH_TYPE_ZZZ,&IdB,&HIdB);
+
+    // TA: Generate Bob's receiver key
+    WCC_ZZZ_GET_G2_MULTIPLE(&MS,&HIdB,&BKeyG2);
+
+    // Generate ephemeral parameters
+    WCC_ZZZ_RANDOM_GENERATE(&RNG,&X);
+    WCC_ZZZ_GET_G1_MULTIPLE(&X,&HIdA,&PaG1);
+
+    WCC_ZZZ_RANDOM_GENERATE(&RNG,&W);
+    WCC_ZZZ_GET_G1_MULTIPLE(&W,&HIdA,&PgG1);
+
+    WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y);
+    WCC_ZZZ_GET_G2_MULTIPLE(&Y,&HIdB,&PbG2);
+
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+    WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+
+    /* Check that the functions work with valid points */
+    rtn = WCC_ZZZ_SENDER_KEY(HASH_TYPE_ZZZ,&X,&PIA,&PIB,&PbG2,&PgG1,&AKeyG1,&IdB,&K1);
+    if (rtn != WCC_OK)
+    {
+        printf("FAILURE Check sender with valid points\n");
+        return 1;
+    }
+
+    rtn = WCC_ZZZ_RECEIVER_KEY(HASH_TYPE_ZZZ,&Y,&W,&PIA,&PIB,&PaG1,&PgG1,&BKeyG2,&IdA,&K2);
+    if (rtn != WCC_OK)
+    {
+        printf("FAILURE Check receiver with valid points\n");
+        return 1;
+    }
+
+    if (!OCT_ncomp(&K1,&K2,AESKEY_ZZZ))
+    {
+        printf("FAILURE Keys do not match\n");
+        return 1;
+    }
+
+    /* Generate invalid points
+     * Randomly generate two octets of the right length to be points in G1 and G2.
+     * The probability these are actually valid points is negligible.
+     */
+    OCT_rand(&InvalidG1,&RNG,InvalidG1.max);
+    OCT_rand(&InvalidG2,&RNG,InvalidG2.max);
+    // Fix point encoding for G1
+    invalidG1[0] = '\x04';
+
+    /* Check handling of invalid points */
+
+    // Invalid Sender PbG2
+    rtn = WCC_ZZZ_SENDER_KEY(HASH_TYPE_ZZZ,&X,&PIA,&PIB,&InvalidG2,&PgG1,&AKeyG1,&IdB,&K1);
+    if (rtn != WCC_INVALID_POINT)
+    {
+        printf("FAILURE Handle invalid PbG2: 51 != %d\n", rtn);
+        return 1;
+    }
+
+    // Invalid Sender PgG1
+    rtn = WCC_ZZZ_SENDER_KEY(HASH_TYPE_ZZZ,&X,&PIA,&PIB,&PbG2,&InvalidG1,&AKeyG1,&IdB,&K1);
+    if (rtn != WCC_INVALID_POINT)
+    {
+        printf("FAILURE Handle invalid PgG1: 51 != %d\n", rtn);
+        return 1;
+    }
+
+    // Invalid Sender AKeyG1
+    rtn = WCC_ZZZ_SENDER_KEY(HASH_TYPE_ZZZ,&X,&PIA,&PIB,&PbG2,&PgG1,&InvalidG1,&IdB,&K1);
+    if (rtn != WCC_INVALID_POINT)
+    {
+        printf("FAILURE Handle invalid AKeyG1: 51 != %d\n", rtn);
+        return 1;
+    }
+
+    // Invalid Receiver PaG1
+    rtn = WCC_ZZZ_RECEIVER_KEY(HASH_TYPE_ZZZ,&Y,&W,&PIA,&PIB,&InvalidG1,&PgG1,&BKeyG2,&IdA,&K2);
+    if (rtn != WCC_INVALID_POINT)
+    {
+        printf("FAILURE Handle invalid PaG1: 51 != %d\n", rtn);
+        return 1;
+    }
+
+    // Invalid Receiver PgG1
+    rtn = WCC_ZZZ_RECEIVER_KEY(HASH_TYPE_ZZZ,&Y,&W,&PIA,&PIB,&PaG1,&InvalidG1,&BKeyG2,&IdA,&K2);
+    if (rtn != WCC_INVALID_POINT)
+    {
+        printf("FAILURE Handle invalid PgG1: 51 != %d\n", rtn);
+        return 1;
+    }
+
+    // Invalid Receiver BKeyG2
+    rtn = WCC_ZZZ_RECEIVER_KEY(HASH_TYPE_ZZZ,&Y,&W,&PIA,&PIB,&PaG1,&PgG1,&InvalidG2,&IdA,&K2);
+    if (rtn != WCC_INVALID_POINT)
+    {
+        printf("FAILURE Handle invalid BKeyG2: 51 != %d\n", rtn);
+        return 1;
+    }
+
+    KILL_CSPRNG(&RNG);
+    printf("SUCCESS! WCC INVALID POINT HANDLING TEST\n");
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_wcc_random_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_wcc_random_ZZZ.c.in b/test/test_wcc_random_ZZZ.c.in
new file mode 100644
index 0000000..2dc0a06
--- /dev/null
+++ b/test/test_wcc_random_ZZZ.c.in
@@ -0,0 +1,466 @@
+/**
+ * @file test_wcc_random.c
+ * @author Kealan McCusker
+ * @brief Test WCC with two TAs for random values
+ *
+ * LICENSE
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* Smoke test: Test WCC with two TAs for random values */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "utils.h"
+#include "config_curve_ZZZ.h"
+#include "config_test.h"
+#include "randapi.h"
+#if CURVE_SECURITY_ZZZ == 128
+#include "wcc_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "wcc192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "wcc256_ZZZ.h"
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*WCC_PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*WCC_PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*WCC_PFS_ZZZ
+#endif
+// #define DEBUG
+
+void rand_str(octet* dest, csprng *RNG)
+{
+    BIG_XXX r;
+    char charset[] = "0123456789@.*"
+                     "abcdefghijklmnopqrstuvwxyz"
+                     "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+    for(; dest->len < dest->max; dest->len++)
+    {
+        BIG_XXX_random(r,RNG);
+        size_t index = r[0] % (sizeof charset -1);
+        dest->val[dest->len] = charset[index];
+    }
+}
+
+int main()
+{
+    int i,rtn,iter;
+
+    /* Master secret shares */
+    char ms1[WCC_PGS_ZZZ], ms2[WCC_PGS_ZZZ];
+    octet MS1= {0,sizeof(ms1),ms1};
+    octet MS2= {0,sizeof(ms2),ms2};
+
+    // Sender keys
+    char a1keyG1[2*WCC_PFS_ZZZ+1], a2keyG1[2*WCC_PFS_ZZZ+1];
+    octet A1KeyG1= {0,sizeof(a1keyG1), a1keyG1};
+    octet A2KeyG1= {0,sizeof(a2keyG1), a2keyG1};
+    char akeyG1[2*WCC_PFS_ZZZ+1];
+    octet AKeyG1= {0,sizeof(akeyG1), akeyG1};
+
+    // Receiver keys
+    char b1keyG2[G2LEN], b2keyG2[G2LEN];
+    octet B1KeyG2= {0,sizeof(b1keyG2), b1keyG2};
+    octet B2KeyG2= {0,sizeof(b2keyG2), b2keyG2};
+    char bkeyG2[G2LEN];
+    octet BKeyG2= {0,sizeof(bkeyG2), bkeyG2};
+
+    // Identities
+    char alice_id[256],bob_id[256];
+    octet IdA= {0,sizeof(alice_id),alice_id};
+    octet IdB= {0,sizeof(bob_id),bob_id};
+
+    // Hash of the identities
+    char hida[WCC_PFS_ZZZ], hidb[WCC_PFS_ZZZ];
+    octet HIdA = {0,sizeof(hida),hida};
+    octet HIdB = {0,sizeof(hidb),hidb};
+
+    char x[WCC_PGS_ZZZ];
+    octet X= {0,sizeof(x),x};
+    char y[WCC_PGS_ZZZ];
+    octet Y= {0,sizeof(y),y};
+    char w[WCC_PGS_ZZZ];
+    octet W= {0,sizeof(w),w};
+    char pia[WCC_PGS_ZZZ];
+    octet PIA= {0,sizeof(pia),pia};
+    char pib[WCC_PGS_ZZZ];
+    octet PIB= {0,sizeof(pib),pib};
+
+    char pgg1[2*WCC_PFS_ZZZ+1];
+    octet PgG1= {0,sizeof(pgg1), pgg1};
+
+    char pag1[2*WCC_PFS_ZZZ+1];
+    octet PaG1= {0,sizeof(pag1), pag1};
+
+    char pbg2[G2LEN];
+    octet PbG2= {0,sizeof(pbg2), pbg2};
+
+    char message1[256];
+    char message2[256];
+    octet MESSAGE1 = {0, sizeof(message1), message1};
+    octet MESSAGE2 = {0, sizeof(message2), message2};
+
+    char t1[PTAG];  // Tag
+    char t2[PTAG];  // Tag
+    char k1[AESKEY_ZZZ];  // AES Key
+    char k2[AESKEY_ZZZ];  // AES Key
+    char iv[PIV]; // IV - Initialization vector
+    char c[100];  // Ciphertext
+    char p[100];  // Recovered Plaintext
+    octet T1= {sizeof(t1),sizeof(t1),t1};
+    octet T2= {sizeof(t2),sizeof(t2),t2};
+    octet K1= {0,sizeof(k1),k1};
+    octet K2= {0,sizeof(k2),k2};
+    octet IV= {0,sizeof(iv),iv};
+    octet C= {0,sizeof(c),c};
+    octet P= {0,sizeof(p),p};
+
+    // Zero octet
+    char zero[AESKEY_ZZZ];
+    octet ZERO= {0,sizeof(zero),zero};
+    for(i=0; i<AESKEY_ZZZ; i++)
+    {
+        ZERO.val[i]=0;
+    }
+
+    OCT_jstring(&MESSAGE1,"Hello Bob");
+    OCT_jstring(&MESSAGE2,"Hello Alice");
+
+    int byte_count = 32;
+    char seed[32] = {0};
+    octet SEED = {sizeof(seed),sizeof(seed),seed};
+    csprng RNG;
+
+#ifdef __linux__
+    FILE *fp;
+    fp = fopen("/dev/urandom", "r");
+    if (fread(&seed, 1, byte_count, fp)) {};
+    fclose(fp);
+#else
+    /* non random seed value! */
+    unsigned long ran;
+    time((time_t *)&ran);
+    SEED.val[0]=ran;
+    SEED.val[1]=ran>>8;
+    SEED.val[2]=ran>>16;
+    SEED.val[3]=ran>>24;
+    for (i=4; i<byte_count; i++) SEED.val[i]=i+1;
+#endif
+    printf("SEED 0x");
+    OCT_output(&SEED);
+
+    /* initialise random number generator */
+    CREATE_CSPRNG(&RNG,&SEED);
+
+    for(iter=1; iter<nRandomTests+1; iter++)
+    {
+        /* Generate Client master secret for MIRACL and Customer */
+        rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&MS1);
+        if (rtn != 0)
+        {
+            printf("TA WCC_ZZZ_RANDOM_GENERATE(&RNG,&MS1) Error %d\n", rtn);
+            return 1;
+        }
+        rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&MS2);
+        if (rtn != 0)
+        {
+            printf("TA WCC_ZZZ_RANDOM_GENERATE(&RNG,&MS2) Error %d\n", rtn);
+            return 1;
+        }
+        printf("TA1 MASTER SECRET: ");
+        OCT_output(&MS1);
+        printf("TA2 MASTER SECRET: ");
+        OCT_output(&MS2);
+
+        // Alice's ID
+        rand_str(&IdA,&RNG);
+        printf("ALICE ID:");
+        OCT_output_string(&IdA);
+        printf("\n");
+
+        // Hash Alice's Id
+        HASH_ID(HASH_TYPE_ZZZ,&IdA,&HIdA);
+
+        // TA: Generate Alice's sender key
+        rtn = WCC_ZZZ_GET_G1_MULTIPLE(&MS1,&HIdA,&A1KeyG1);
+        if (rtn != 0)
+        {
+            printf("TA WCC_ZZZ_GET_G1_MULTIPLE(&MS1,&HIdA,&A1KeyG1) Error %d\n", rtn);
+            return 1;
+        }
+        rtn = WCC_ZZZ_GET_G1_MULTIPLE(&MS2,&HIdA,&A2KeyG1);
+        if (rtn != 0)
+        {
+            printf("TA WCC_ZZZ_GET_G1_MULTIPLE(&MS2,&HIdA,&A2KeyG1) Error %d\n", rtn);
+            return 1;
+        }
+        printf("TA A1KeyG1: ");
+        OCT_output(&A1KeyG1);
+        printf("TA A2KeyG1: ");
+        OCT_output(&A2KeyG1);
+
+        rtn = WCC_ZZZ_RECOMBINE_G1(&A1KeyG1, &A2KeyG1, &AKeyG1);
+        if (rtn != 0)
+        {
+            printf("TA WCC_ZZZ_RECOMBINE_G1(&A1KeyG1, &A2KeyG1, &AKeyG1) Error %d\n", rtn);
+            return 1;
+        }
+        printf("TA Alice's sender key: ");
+        OCT_output(&AKeyG1);
+
+        // Bob's ID
+        rand_str(&IdB,&RNG);
+        printf("BOB ID:");
+        OCT_output_string(&IdB);
+        printf("\n");
+
+        // Hash Bob's Id
+        HASH_ID(HASH_TYPE_ZZZ,&IdB,&HIdB);
+
+        // TA: Generate Bob's receiver key
+        rtn = WCC_ZZZ_GET_G2_MULTIPLE(&MS1,&HIdB,&B1KeyG2);
+        if (rtn != 0)
+        {
+            printf("TA WCC_ZZZ_GET_G2_MULTIPLE(&MS1,&HIdB,&B1KeyG2) Error %d\n", rtn);
+            return 1;
+        }
+        rtn = WCC_ZZZ_GET_G2_MULTIPLE(&MS2,&HIdB,&B2KeyG2);
+        if (rtn != 0)
+        {
+            printf("Bob WCC_ZZZ_GET_G2_MULTIPLE(&MS2,&HIdB,&B2KeyG2) Error %d\n", rtn);
+            return 1;
+        }
+        printf("TA B1KeyG2: ");
+        OCT_output(&B1KeyG2);
+        printf("TA B2KeyG2: ");
+        OCT_output(&B2KeyG2);
+
+        rtn = WCC_ZZZ_RECOMBINE_G2(&B1KeyG2, &B2KeyG2, &BKeyG2);
+        if (rtn != 0)
+        {
+            printf("Bob WCC_ZZZ_RECOMBINE_G2(&B1KeyG1, &B2KeyG1, &BKeyG2) Error %d\n", rtn);
+            return 1;
+        }
+        printf("TA Bob's receiver key: ");
+        OCT_output(&BKeyG2);
+
+        printf("Alice\n");
+
+        rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&X);
+        if (rtn != 0)
+        {
+            printf("Alice WCC_ZZZ_RANDOM_GENERATE(&RNG,&X) Error %d\n", rtn);
+            return 1;
+        }
+#ifdef DEBUG
+        printf("Alice X: ");
+        OCT_output(&X);
+        printf("\n");
+#endif
+
+        rtn = WCC_ZZZ_GET_G1_MULTIPLE(&X,&HIdA,&PaG1);
+        if (rtn != 0)
+        {
+            printf("Alice WCC_ZZZ_GET_G1_MULTIPLE(&X,&HIdA,&PaG1) Error %d\n", rtn);
+            return 1;
+        }
+
+        printf("Alice sends IdA and PaG1 to Bob\n\n");
+        printf("Alice IdA: ");
+        OCT_output_string(&IdA);
+        printf("\n");
+        printf("Alice PaG1: ");
+        OCT_output(&PaG1);
+        printf("\n");
+
+        printf("Bob\n");
+
+        rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&W);
+        if (rtn != 0)
+        {
+            printf("Bob WCC_ZZZ_RANDOM_GENERATE(&RNG,&W) Error %d\n", rtn);
+            return 1;
+        }
+#ifdef DEBUG
+        printf("Bob W: ");
+        OCT_output(&W);
+        printf("\n");
+#endif
+        rtn = WCC_ZZZ_GET_G1_MULTIPLE(&W,&HIdA,&PgG1);
+        if (rtn != 0)
+        {
+            printf("Bob WCC_ZZZ_GET_G1_MULTIPLE(&W,&HIdA,&PgG1) Error %d\n", rtn);
+            return 1;
+        }
+#ifdef DEBUG
+        printf("PgG1: ");
+        OCT_output(&PgG1);
+        printf("\n");
+#endif
+
+        rtn = WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y);
+        if (rtn != 0)
+        {
+            printf("Bob WCC_ZZZ_RANDOM_GENERATE(&RNG,&Y) Error %d\n", rtn);
+            return 1;
+        }
+#ifdef DEBUG
+        printf("Bob Y: ");
+        OCT_output(&Y);
+        printf("\n");
+#endif
+        rtn = WCC_ZZZ_GET_G2_MULTIPLE(&Y,&HIdB,&PbG2);
+        if (rtn != 0)
+        {
+            printf("Bob WCC_ZZZ_GET_G1_MULTIPLE(&Y,&HIdB,&PbG2) Error %d\n", rtn);
+            return 1;
+        }
+#ifdef DEBUG
+        printf("Bob PbG2: ");
+        OCT_output(&PbG2);
+        printf("\n");
+#endif
+
+        // pia = Hq(PaG1,PbG2,PgG1,IdB)
+        WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+
+        // pib = Hq(PbG2,PaG1,PgG1,IdA)
+        WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+
+#ifdef DEBUG
+        printf("Bob PIA: ");
+        OCT_output(&PIA);
+        printf("\n");
+        printf("Bob PIB: ");
+        OCT_output(&PIB);
+        printf("\n");
+#endif
+
+        // Bob calculates AES Key
+        rtn = WCC_ZZZ_RECEIVER_KEY(HASH_TYPE_ZZZ,&Y,&W,&PIA,&PIB,&PaG1,&PgG1,&BKeyG2,&IdA,&K2);
+        if (rtn != 0)
+        {
+            printf("Bob WCC_ZZZ_RECEIVER_KEY() Error %d\n", rtn);
+            return 1;
+        }
+        printf("Bob AES Key: ");
+        OCT_output(&K2);
+        if (OCT_comp(&K2,&ZERO))
+        {
+            printf("Bob WCC_ZZZ_RECEIVER_KEY() Error: generated key is zero\n");
+            return 1;
+        }
+
+        printf("Bob sends IdB, PbG2 and PgG1 to Alice\n\n");
+        printf("Bob IdB: ");
+        OCT_output_string(&IdB);
+        printf("\n");
+        printf("Bob PbG2: ");
+        OCT_output(&PbG2);
+        printf("\n");
+        printf("Bob PgG1: ");
+        OCT_output(&PgG1);
+        printf("\n");
+
+        printf("Alice\n");
+
+        // pia = Hq(PaG1,PbG2,PgG1,IdB)
+        WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PaG1,&PbG2,&PgG1,&IdB,&PIA);
+
+        // pib = Hq(PbG2,PaG1,PgG1,IdA)
+        WCC_ZZZ_Hq(HASH_TYPE_ZZZ,&PbG2,&PaG1,&PgG1,&IdA,&PIB);
+
+#ifdef DEBUG
+        printf("Alice PIA: ");
+        OCT_output(&PIA);
+        printf("\n");
+        printf("Alice PIB: ");
+        OCT_output(&PIB);
+        printf("\n");
+#endif
+
+        // Alice calculates AES Key
+        rtn = WCC_ZZZ_SENDER_KEY(HASH_TYPE_ZZZ,&X,&PIA,&PIB,&PbG2,&PgG1,&AKeyG1,&IdB,&K1);
+        if (rtn != 0)
+        {
+            printf("Alice WCC_ZZZ_SENDER_KEY() Error %d\n", rtn);
+            return 1;
+        }
+        printf("Alice AES Key: ");
+        OCT_output(&K1);
+        if (OCT_comp(&K1,&ZERO))
+        {
+            printf("Alice WCC_ZZZ_SENDER_KEY() Error: generated key is zero\n");
+            return 1;
+        }
+
+        // Send message
+        IV.len=12;
+        for (i=0; i<IV.len; i++)
+            IV.val[i]=i+1;
+        printf("Alice: IV ");
+        OCT_output(&IV);
+
+        printf("Alice: Message to encrypt for Bob: ");
+        OCT_output_string(&MESSAGE1);
+        printf("\n");
+
+        AES_GCM_ENCRYPT(&K1,&IV,&IdA,&MESSAGE1,&C,&T1);
+
+        printf("Alice: Ciphertext: ");
+        OCT_output(&C);
+
+        printf("Alice: Encryption Tag: ");
+        OCT_output(&T1);
+        printf("\n");
+
+        AES_GCM_DECRYPT(&K2,&IV,&IdA,&C,&P,&T2);
+
+        printf("Bob: Decrypted message received from Alice: ");
+        OCT_output_string(&P);
+        printf("\n");
+
+        printf("Bob: Decryption Tag: ");
+        OCT_output(&T2);
+        printf("\n");
+
+        if (!OCT_comp(&MESSAGE1,&P))
+        {
+            printf("FAILURE Decryption\n");
+            return 1;
+        }
+
+        if (!OCT_comp(&T1,&T2))
+        {
+            printf("FAILURE TAG mismatch\n");
+            return 1;
+        }
+        printf("Iteration %d SUCCESS \n\n", iter);
+    }
+
+    KILL_CSPRNG(&RNG);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_x509_WWW_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_x509_WWW_ZZZ.c.in b/test/test_x509_WWW_ZZZ.c.in
new file mode 100644
index 0000000..bd4d3d9
--- /dev/null
+++ b/test/test_x509_WWW_ZZZ.c.in
@@ -0,0 +1,1054 @@
+/**
+ * @file test_x509.c
+ * @author Kealan McCusker
+ * @brief Test x509 functions
+ *
+ * LICENSE
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "rsa_WWW.h"
+#include "ecdh_ZZZ.h"
+#include "x509.h"
+#include "utils.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+//#define DEBUG
+
+#define ECC 1
+#define RSA 2
+#define H160 1
+#define H256 2
+#define H384 3
+#define H512 4
+
+// #define CHOICE "ZZZ"
+
+#define LINE_LEN 10000
+#define MAX_STRING 300
+
+#define MAXMODBYTES 72
+#define MAXFFLEN 16
+
+char sig[MAXMODBYTES*MAXFFLEN];
+octet SIG= {0,sizeof(sig),sig};
+
+char sig2[MAXMODBYTES*MAXFFLEN];
+octet SIG2= {0,sizeof(sig2),sig2};
+
+char r[MAXMODBYTES];
+octet R= {0,sizeof(r),r};
+
+char s[MAXMODBYTES];
+octet S= {0,sizeof(s),s};
+
+char cakey[MAXMODBYTES*MAXFFLEN];
+octet CAKEY= {0,sizeof(cakey),cakey};
+
+char certkey[MAXMODBYTES*MAXFFLEN];
+octet CERTKEY= {0,sizeof(certkey),certkey};
+
+char h[5000];
+octet H= {0,sizeof(h),h};
+
+char hh[5000];
+octet HH= {0,sizeof(hh),hh};
+
+char hp[RFS_WWW];
+octet HP= {0,sizeof(hp),hp};
+
+// countryName
+static char cn[3]= {0x55,0x04,0x06};
+static octet CN= {3,sizeof(cn),cn};
+
+// stateName
+static char sn[3]= {0x55,0x04,0x08};
+static octet SN= {3,sizeof(sn),sn};
+
+// localName
+static char ln[3]= {0x55,0x04,0x07};
+static octet LN= {3,sizeof(ln),ln};
+
+// orgName
+static char on[3]= {0x55,0x04,0x0A};
+static octet ON= {3,sizeof(on),on};
+
+// unitName
+static char un[3]= {0x55,0x04,0x0B};
+static octet UN= {3,sizeof(un),un};
+
+// myName
+static char mn[3]= {0x55,0x04,0x03};
+static octet MN= {3,sizeof(mn),mn};
+
+// emailName
+static char en[9]= {0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x09,0x01};
+static octet EN= {9,sizeof(en),en};
+
+int compare_data(octet *cert,octet *data,int index)
+{
+    int i;
+    for (i=0; i<data->len; i++)
+    {
+        if (cert->val[index+i]!=data->val[i])
+        {
+            return 0;
+        }
+    }
+    return 1;
+}
+
+int main(int argc, char** argv)
+{
+    if (argc != 2)
+    {
+        printf("usage: ./test_x509 [path to test vector file]\n");
+        exit(EXIT_FAILURE);
+    }
+    int sha;
+    pktype st,pt;
+    pktype ca = {0,0,0};
+    FILE * fp = NULL;
+    char line[LINE_LEN];
+    char * linePtr = NULL;
+    int l1=0;
+    const char* CAStr = "CA = ";
+    const char* CERTStr = "CERT = ";
+
+    char issuerc[MAX_STRING];
+    octet IssuerCOct= {0,MAX_STRING,issuerc};
+    const char* IssuerCStr = "IssuerC = ";
+
+    char issuerst[MAX_STRING];
+    octet IssuerSTOct= {0,MAX_STRING,issuerst};
+    const char* IssuerSTStr = "IssuerST = ";
+
+    char issuerl[MAX_STRING];
+    octet IssuerLOct= {0,MAX_STRING,issuerl};
+    const char* IssuerLStr = "IssuerL = ";
+
+    char issuero[MAX_STRING];
+    octet IssuerOOct= {0,MAX_STRING,issuero};
+    const char* IssuerOStr = "IssuerO = ";
+
+    char issuerou[MAX_STRING];
+    octet IssuerOUOct= {0,MAX_STRING,issuerou};
+    const char* IssuerOUStr = "IssuerOU = ";
+
+    char issuercn[MAX_STRING];
+    octet IssuerCNOct= {0,MAX_STRING,issuercn};
+    const char* IssuerCNStr = "IssuerCN = ";
+
+    char issueremailaddress[MAX_STRING];
+    octet IssuerEmailAddressOct= {0,MAX_STRING,issueremailaddress};
+    const char* IssuerEmailAddressStr = "IssuerEmailAddress = ";
+
+
+    char subjectc[MAX_STRING];
+    octet SubjectCOct= {0,MAX_STRING,subjectc};
+    const char* SubjectCStr = "SubjectC = ";
+
+    char subjectst[MAX_STRING];
+    octet SubjectSTOct= {0,MAX_STRING,subjectst};
+    const char* SubjectSTStr = "SubjectST = ";
+
+    char subjectl[MAX_STRING];
+    octet SubjectLOct= {0,MAX_STRING,subjectl};
+    const char* SubjectLStr = "SubjectL = ";
+
+    char subjecto[MAX_STRING];
+    octet SubjectOOct= {0,MAX_STRING,subjecto};
+    const char* SubjectOStr = "SubjectO = ";
+
+    char subjectou[MAX_STRING];
+    octet SubjectOUOct= {0,MAX_STRING,subjectou};
+    const char* SubjectOUStr = "SubjectOU = ";
+
+    char subjectcn[MAX_STRING];
+    octet SubjectCNOct= {0,MAX_STRING,subjectcn};
+    const char* SubjectCNStr = "SubjectCN = ";
+
+    char subjectemailaddress[MAX_STRING];
+    octet SubjectEmailAddressOct= {0,MAX_STRING,subjectemailaddress};
+    const char* SubjectEmailAddressStr = "SubjectEmailAddress = ";
+
+    char vf[MAX_STRING];
+    octet vfOct= {0,MAX_STRING,vf};
+    const char* vfStr = "vf = ";
+
+    char vt[MAX_STRING];
+    octet vtOct= {0,MAX_STRING,vt};
+    const char* vtStr = "vt = ";
+
+    char cert_pk[512];
+    octet CERT_PKOct= {0,sizeof(cert_pk),cert_pk};
+    const char* CERT_PKStr = "CERT_PK = ";
+
+    fp = fopen(argv[1], "r");
+    if (fp == NULL)
+    {
+        printf("ERROR opening test vector file\n");
+        exit(EXIT_FAILURE);
+    }
+
+    rsa_public_key_WWW PK;
+
+    bool readLine = false;
+    int i=0;
+    while (fgets(line, LINE_LEN, fp) != NULL)
+    {
+        i++;
+        readLine = true;
+
+        if (!strncmp(line,  IssuerCStr, strlen(IssuerCStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(IssuerCStr);
+            OCT_clear(&IssuerCOct);
+            OCT_jstring(&IssuerCOct,linePtr);
+            IssuerCOct.len -= 1;
+
+#ifdef DEBUG
+            printf("IssuerCOct Hex: ");
+            OCT_output(&IssuerCOct);
+            printf("IssuerCOct ASCII: ");
+            OCT_output_string(&IssuerCOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line,  IssuerSTStr, strlen(IssuerSTStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(IssuerSTStr);
+            OCT_clear(&IssuerSTOct);
+            OCT_jstring(&IssuerSTOct,linePtr);
+            IssuerSTOct.len -= 1;
+
+#ifdef DEBUG
+            printf("IssuerSTOct Hex: ");
+            OCT_output(&IssuerSTOct);
+            printf("IssuerSTOct ASCII: ");
+            OCT_output_string(&IssuerSTOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line,  IssuerLStr, strlen(IssuerLStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(IssuerLStr);
+            OCT_clear(&IssuerLOct);
+            OCT_jstring(&IssuerLOct,linePtr);
+            IssuerLOct.len -= 1;
+
+#ifdef DEBUG
+            printf("IssuerLOct Hex: ");
+            OCT_output(&IssuerLOct);
+            printf("IssuerLOct ASCII: ");
+            OCT_output_string(&IssuerLOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line,  IssuerOStr, strlen(IssuerOStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(IssuerOStr);
+            OCT_clear(&IssuerOOct);
+            OCT_jstring(&IssuerOOct,linePtr);
+            IssuerOOct.len -= 1;
+
+#ifdef DEBUG
+            printf("IssuerOOct Hex: ");
+            OCT_output(&IssuerOOct);
+            printf("IssuerOOct ASCII: ");
+            OCT_output_string(&IssuerOOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line,  IssuerOUStr, strlen(IssuerOUStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(IssuerOUStr);
+            OCT_clear(&IssuerOUOct);
+            OCT_jstring(&IssuerOUOct,linePtr);
+            IssuerOUOct.len -= 1;
+
+#ifdef DEBUG
+            printf("IssuerOUOct Hex: ");
+            OCT_output(&IssuerOUOct);
+            printf("IssuerOUOct ASCII: ");
+            OCT_output_string(&IssuerOUOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line,  IssuerCNStr, strlen(IssuerCNStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(IssuerCNStr);
+            OCT_clear(&IssuerCNOct);
+            OCT_jstring(&IssuerCNOct,linePtr);
+            IssuerCNOct.len -= 1;
+
+#ifdef DEBUG
+            printf("IssuerCNOct Hex: ");
+            OCT_output(&IssuerCNOct);
+            printf("IssuerCNOct ASCII: ");
+            OCT_output_string(&IssuerCNOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line, IssuerEmailAddressStr, strlen(IssuerEmailAddressStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(IssuerEmailAddressStr);
+            OCT_clear(&IssuerEmailAddressOct);
+            OCT_jstring(&IssuerEmailAddressOct,linePtr);
+            IssuerEmailAddressOct.len -= 1;
+
+#ifdef DEBUG
+            printf("IssuerEmailAddressOct Hex: ");
+            OCT_output(&IssuerEmailAddressOct);
+            printf("IssuerEmailAddressOct ASCII: ");
+            OCT_output_string(&IssuerEmailAddressOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line,  SubjectCStr, strlen(SubjectCStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(SubjectCStr);
+            OCT_clear(&SubjectCOct);
+            OCT_jstring(&SubjectCOct,linePtr);
+            SubjectCOct.len -= 1;
+
+#ifdef DEBUG
+            printf("SubjectCOct Hex: ");
+            OCT_output(&SubjectCOct);
+            printf("SubjectCOct ASCII: ");
+            OCT_output_string(&SubjectCOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line,  SubjectSTStr, strlen(SubjectSTStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(SubjectSTStr);
+            OCT_clear(&SubjectSTOct);
+            OCT_jstring(&SubjectSTOct,linePtr);
+            SubjectSTOct.len -= 1;
+
+#ifdef DEBUG
+            printf("SubjectSTOct Hex: ");
+            OCT_output(&SubjectSTOct);
+            printf("SubjectSTOct ASCII: ");
+            OCT_output_string(&SubjectSTOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line,  SubjectLStr, strlen(SubjectLStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(SubjectLStr);
+            OCT_clear(&SubjectLOct);
+            OCT_jstring(&SubjectLOct,linePtr);
+            SubjectLOct.len -= 1;
+
+#ifdef DEBUG
+            printf("SubjectLOct Hex: ");
+            OCT_output(&SubjectLOct);
+            printf("SubjectLOct ASCII: ");
+            OCT_output_string(&SubjectLOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line,  SubjectOStr, strlen(SubjectOStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(SubjectOStr);
+            OCT_clear(&SubjectOOct);
+            OCT_jstring(&SubjectOOct,linePtr);
+            SubjectOOct.len -= 1;
+
+#ifdef DEBUG
+            printf("SubjectOOct Hex: ");
+            OCT_output(&SubjectOOct);
+            printf("SubjectOOct ASCII: ");
+            OCT_output_string(&SubjectOOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line,  SubjectOUStr, strlen(SubjectOUStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(SubjectOUStr);
+            OCT_clear(&SubjectOUOct);
+            OCT_jstring(&SubjectOUOct,linePtr);
+            SubjectOUOct.len -= 1;
+
+#ifdef DEBUG
+            printf("SubjectOUOct Hex: ");
+            OCT_output(&SubjectOUOct);
+            printf("SubjectOUOct ASCII: ");
+            OCT_output_string(&SubjectOUOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line,  SubjectCNStr, strlen(SubjectCNStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(SubjectCNStr);
+            OCT_clear(&SubjectCNOct);
+            OCT_jstring(&SubjectCNOct,linePtr);
+            SubjectCNOct.len -= 1;
+
+#ifdef DEBUG
+            printf("SubjectCNOct Hex: ");
+            OCT_output(&SubjectCNOct);
+            printf("SubjectCNOct ASCII: ");
+            OCT_output_string(&SubjectCNOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line, SubjectEmailAddressStr, strlen(SubjectEmailAddressStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(SubjectEmailAddressStr);
+            OCT_clear(&SubjectEmailAddressOct);
+            OCT_jstring(&SubjectEmailAddressOct,linePtr);
+            SubjectEmailAddressOct.len -= 1;
+
+#ifdef DEBUG
+            printf("SubjectEmailAddressOct Hex: ");
+            OCT_output(&SubjectEmailAddressOct);
+            printf("SubjectEmailAddressOct ASCII: ");
+            OCT_output_string(&SubjectEmailAddressOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line, vfStr, strlen(vfStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(vfStr);
+            OCT_clear(&vfOct);
+            OCT_jstring(&vfOct,linePtr);
+            vfOct.len -= 1;
+
+#ifdef DEBUG
+            printf("vfOct Hex: ");
+            OCT_output(&vfOct);
+            printf("vfOct ASCII: ");
+            OCT_output_string(&vfOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line, vtStr, strlen(vtStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            linePtr = line + strlen(vtStr);
+            OCT_clear(&vtOct);
+            OCT_jstring(&vtOct,linePtr);
+            vtOct.len -= 1;
+
+#ifdef DEBUG
+            printf("vtOct Hex: ");
+            OCT_output(&vtOct);
+            printf("vtOct ASCII: ");
+            OCT_output_string(&vtOct);
+            printf("\n");
+#endif
+        }
+
+        if (!strncmp(line, CERT_PKStr, strlen(CERT_PKStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(CERT_PKStr);
+
+            // p binary value
+            l1 = strlen(linePtr)-1;
+            amcl_hex2bin(linePtr, CERT_PKOct.val, l1);
+            CERT_PKOct.len = l1/2;
+
+#ifdef DEBUG
+            printf("CERT_PKOct Hex: ");
+            OCT_output(&CERT_PKOct);
+            printf("\n");
+#endif
+        }
+
+
+        // Self-Signed CA cert
+        if (!strncmp(line, CAStr, strlen(CAStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find base64 value in string
+            char io[5000];
+            octet IO= {0,sizeof(io),io};
+            linePtr = line + strlen(CAStr);
+            l1 = strlen(linePtr);
+            char* ca_b64 = (char*) calloc (l1,sizeof(char));
+            strncpy(ca_b64,linePtr,l1-1);
+            OCT_frombase64(&IO,ca_b64);
+
+#ifdef DEBUG
+            printf("CA Self-Signed Cert: \n");
+            OCT_output(&IO);
+            printf("\n");
+#endif
+
+            free(ca_b64);
+            ca_b64 = NULL;
+
+            // returns signature type
+            st=X509_extract_cert_sig(&IO,&SIG);
+
+            if (st.type==0)
+            {
+                printf("Unable to extract self-signed cert signature\r\n");
+            }
+
+            if (st.type==ECC)
+            {
+                OCT_chop(&SIG,&S,SIG.len/2);
+                OCT_copy(&R,&SIG);
+                // printf("SIG: ");
+                // OCT_output(&R);
+                // printf("\r\n");
+                // OCT_output(&S);
+                // printf("\r\n");
+            }
+
+            if (st.type==RSA)
+            {
+                //printf("SIG: ");
+                //OCT_output(&SIG);
+                //printf("\r\n");
+            }
+
+            // Extract Cert from signed Cert
+            X509_extract_cert(&IO,&H);
+
+            ca=X509_extract_public_key(&H,&CAKEY);
+
+            if (ca.type==0)
+            {
+                printf("Not supported by library\n");
+                exit(EXIT_FAILURE);
+            }
+            if (ca.type!=st.type)
+            {
+                printf("Not self-signed\n");
+                exit(EXIT_FAILURE);
+            }
+
+            if (ca.type==ECC)
+            {
+                // printf("EXTRACTED ECC CA PUBLIC KEY: ");
+                // OCT_output(&CAKEY);
+                // printf("\n");
+            }
+            if (ca.type==RSA)
+            {
+                // printf("EXTRACTED RSA CA PUBLIC KEY:  ");
+                //  OCT_output(&CAKEY);
+                //  printf("\n");
+            }
+
+            // Cert is self-signed - so check signature
+            // printf("Checking Self-Signed Signature\r\n");
+            if (ca.type==ECC)
+            {
+                // if (ca.curve!=CHOICE)
+                // {
+                //     printf("TEST X509 ERROR CURVE IS NOT SUPPORTED LINE %d\n",i);
+                //     exit(EXIT_FAILURE);
+                // }
+                int res=ECP_ZZZ_PUBLIC_KEY_VALIDATE(&CAKEY);
+                if (res!=0)
+                {
+                    printf("TEST X509 ERROR PUBLIC KEY IS INVALID LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+
+                sha=0;
+                if (st.hash==H256) sha=SHA256;
+                if (st.hash==H384) sha=SHA384;
+                if (st.hash==H512) sha=SHA512;
+                if (st.hash==0)
+                {
+                    printf("TEST X509 ERROR HASH FUNCTION NOT SUPPORTED LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+
+                if (ECP_ZZZ_VP_DSA(sha,&CAKEY,&H,&R,&S)!=0)
+                {
+                    printf("X509 ERROR ECDSA VERIFICATION FAILED LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+            }
+
+            if (ca.type==RSA)
+            {
+                PK.e=65537; // assuming this!
+                FF_WWW_fromOctet(PK.n,&CAKEY,FFLEN_WWW);
+
+                sha=0;
+                if (st.hash==H256) sha=SHA256;
+                if (st.hash==H384) sha=SHA384;
+                if (st.hash==H512) sha=SHA512;
+                if (st.hash==0)
+                {
+                    printf("TEST X509 ERROR Hash Function not supported LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+                PKCS15(sha,&H,&HP);
+
+                RSA_WWW_ENCRYPT(&PK,&SIG,&HH);
+                if (!OCT_comp(&HP,&HH))
+                {
+                    printf("TEST X509 ERROR RSA VERIFICATION FAILED LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+            }
+        }
+
+        /////////// CA Signed cert /////////////////
+        if (!strncmp(line, CERTStr, strlen(CERTStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find base64 value in string
+            char io[5000];
+            octet IO= {0,sizeof(io),io};
+            linePtr = line + strlen(CERTStr);
+            l1 = strlen(linePtr);
+            char* cert_b64 = (char*) calloc (l1,sizeof(char));
+            strncpy(cert_b64,linePtr,l1-1);
+            OCT_frombase64(&IO,cert_b64);
+
+#ifdef DEBUG
+            printf("CA Signed Cert: \n");
+            OCT_output(&IO);
+            printf("\n");
+#endif
+
+            free(cert_b64);
+            cert_b64 = NULL;
+
+            // returns signature type
+            st=X509_extract_cert_sig(&IO,&SIG);
+
+            if (st.type==0)
+            {
+                printf("TEST X509 ERROR UNABLE TO CHECK CERT SIGNATURE LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            if (st.type==ECC)
+            {
+                OCT_chop(&SIG,&S,SIG.len/2);
+                OCT_copy(&R,&SIG);
+#ifdef DEBUG
+                printf("ECC SIG: ");
+                OCT_output(&R);
+                printf("\r\n");
+                OCT_output(&S);
+                printf("\r\n");
+#endif
+            }
+
+#ifdef DEBUG
+            if (st.type==RSA)
+            {
+                printf("RSA SIG: ");
+                OCT_output(&SIG);
+                printf("\r\n");
+            }
+#endif
+
+            // Extract Cert
+            int c;
+            c=X509_extract_cert(&IO,&H);
+
+#ifdef DEBUG
+            printf("Cert: ");
+            OCT_output(&H);
+            printf("\n");
+#endif
+
+            // Check Details
+            int ic,len;
+            // Issuer Details
+            ic=X509_find_issuer(&H);
+
+            c=X509_find_entity_property(&H,&CN,ic,&len);
+#ifdef DEBUG
+            print_out("countryName: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&IssuerCOct,c))
+            {
+                printf("TEST X509 ERROR IssuerC LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_entity_property(&H,&SN,ic,&len);
+#ifdef DEBUG
+            print_out("stateOrProvinceName: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&IssuerSTOct,c))
+            {
+                printf("TEST X509 ERROR IssuerST LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_entity_property(&H,&LN,ic,&len);
+#ifdef DEBUG
+            print_out("localityName: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&IssuerLOct,c))
+            {
+                printf("TEST X509 ERROR IssuerL LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_entity_property(&H,&ON,ic,&len);
+#ifdef DEBUG
+            print_out("organizationName: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&IssuerOOct,c))
+            {
+                printf("TEST X509 ERROR IssuerO LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_entity_property(&H,&UN,ic,&len);
+#ifdef DEBUG
+            print_out("organizationalUnitName: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&IssuerOUOct,c))
+            {
+                printf("TEST X509 ERROR IssuerOU LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_entity_property(&H,&MN,ic,&len);
+#ifdef DEBUG
+            print_out("commonName: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&IssuerCNOct,c))
+            {
+                printf("TEST X509 ERROR IssuerCN LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_entity_property(&H,&EN,ic,&len);
+#ifdef DEBUG
+            print_out("emailAddress: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&IssuerEmailAddressOct,c))
+            {
+                printf("TEST X509 ERROR IssuerEmailAddress LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            // Subject details
+#ifdef DEBUG
+            printf("Subject Details\n");
+#endif
+            ic=X509_find_subject(&H);
+
+            c=X509_find_entity_property(&H,&CN,ic,&len);
+#ifdef DEBUG
+            print_out("countryName: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&SubjectCOct,c))
+            {
+                printf("TEST X509 ERROR SubjectC LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_entity_property(&H,&SN,ic,&len);
+#ifdef DEBUG
+            print_out("stateOrProvinceName: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&SubjectSTOct,c))
+            {
+                printf("TEST X509 ERROR SubjectST LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_entity_property(&H,&LN,ic,&len);
+#ifdef DEBUG
+            print_out("localityName: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&SubjectLOct,c))
+            {
+                printf("TEST X509 ERROR SubjectL LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_entity_property(&H,&ON,ic,&len);
+#ifdef DEBUG
+            print_out("organizationName: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&SubjectOOct,c))
+            {
+                printf("TEST X509 ERROR SubjectO LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_entity_property(&H,&UN,ic,&len);
+#ifdef DEBUG
+            print_out("organizationalUnitName: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&SubjectOUOct,c))
+            {
+                printf("TEST X509 ERROR SubjectOU LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_entity_property(&H,&MN,ic,&len);
+#ifdef DEBUG
+            print_out("commonName: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&SubjectCNOct,c))
+            {
+                printf("TEST X509 ERROR SubjectCN LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_entity_property(&H,&EN,ic,&len);
+#ifdef DEBUG
+            print_out("emailAddress: ",&H,c,len);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&SubjectEmailAddressOct,c))
+            {
+                printf("TEST X509 ERROR SubjectEmailAddress LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            ic=X509_find_validity(&H);
+            c=X509_find_start_date(&H,ic);
+#ifdef DEBUG
+            print_date("start date: ",&H,c);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&vfOct,c))
+            {
+                printf("TEST X509 ERROR VALID FROM LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            c=X509_find_expiry_date(&H,ic);
+#ifdef DEBUG
+            print_date("expiry date: ",&H,c);
+            printf("\n");
+#endif
+
+            if (!compare_data(&H,&vtOct,c))
+            {
+                printf("TEST X509 ERROR VALID TO LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            pt=X509_extract_public_key(&H,&CERTKEY);
+
+            if (pt.type==0)
+            {
+                printf("TEST X509 ERROR NOT SUPPORTED BY LIBRARY LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+#ifdef DEBUG
+            if (pt.type==ECC)
+            {
+                printf("EXTRACTED ECC PUBLIC KEY: ");
+                OCT_output(&CERTKEY);
+                printf("\n");
+            }
+            if (pt.type==RSA)
+            {
+                printf("EXTRACTED RSA PUBLIC KEY:  ");
+                OCT_output(&CERTKEY);
+                printf("\n");
+            }
+#endif
+            if (!compare_data(&CERTKEY,&CERT_PKOct,0))
+            {
+                printf("TEST X509 ERROR CERT PUBLIC KEY  LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            // Check CA signature
+            // printf("Checking CA Signed Signature\n");
+
+#ifdef DEBUG
+            printf("CA PUBLIC KEY:  ");
+            OCT_output(&CAKEY);
+            printf("\n");
+#endif
+
+            if (ca.type==ECC)
+            {
+                // if (ca.curve!=CHOICE)
+                // {
+                //     printf("TEST X509 ERROR CURVE IS NOT SUPPORTED LINE %d\n",i);
+                //     exit(EXIT_FAILURE);
+                // }
+                int res=ECP_ZZZ_PUBLIC_KEY_VALIDATE(&CAKEY);
+                if (res!=0)
+                {
+                    printf("TEST X509 ERROR PUBLIC KEY IS INVALID LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+
+                sha=0;
+                if (st.hash==H256) sha=SHA256;
+                if (st.hash==H384) sha=SHA384;
+                if (st.hash==H512) sha=SHA512;
+                if (st.hash==0)
+                {
+                    printf("TEST X509 ERROR HASH FUNCTION NOT SUPPORTED LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+
+                if (ECP_ZZZ_VP_DSA(sha,&CAKEY,&H,&R,&S)!=0)
+                {
+                    printf("X509 ERROR ECDSA VERIFICATION FAILED LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+            }
+
+            if (ca.type==RSA)
+            {
+                PK.e=65537; // assuming this!
+                FF_WWW_fromOctet(PK.n,&CAKEY,FFLEN_WWW);
+
+                sha=0;
+                if (st.hash==H256) sha=SHA256;
+                if (st.hash==H384) sha=SHA384;
+                if (st.hash==H512) sha=SHA512;
+                if (st.hash==0)
+                {
+                    printf("TEST X509 ERROR Hash Function not supported LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+                PKCS15(sha,&H,&HP);
+
+                RSA_WWW_ENCRYPT(&PK,&SIG,&HH);
+                if (!OCT_comp(&HP,&HH))
+                {
+                    printf("TEST X509 ERROR RSA VERIFICATION FAILED LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+            }
+        }
+
+    }
+    fclose(fp);
+    if (!readLine)
+    {
+        printf("X509 ERROR Empty test vector file\n");
+        exit(EXIT_FAILURE);
+    }
+    printf("SUCCESS TEST X509 PASSED\n");
+    exit(EXIT_SUCCESS);
+}