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:46 UTC

[26/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_mpin_good_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpin_good_ZZZ.c.in b/test/test_mpin_good_ZZZ.c.in
new file mode 100644
index 0000000..505d18e
--- /dev/null
+++ b/test/test_mpin_good_ZZZ.c.in
@@ -0,0 +1,297 @@
+/**
+ * @file test_mpin_good_ZZZ.c
+ * @author Kealan McCusker
+ * @brief Test function for good PIN in MPIN
+ *
+ * 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 good token and correct PIN with D-TA */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "config_curve_ZZZ.h"
+#include "pbc_support.h"
+#include "randapi.h"
+#if CURVE_SECURITY_ZZZ == 128
+#include "mpin_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "mpin192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "mpin256_ZZZ.h"
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*PFS_ZZZ
+#endif
+#define GTLEN 3*G2LEN
+
+int main()
+{
+    int i,PIN1,PIN2,rtn,err;
+
+    char id[256];
+    octet ID = {0,sizeof(id),id};
+
+    char x[PGS_ZZZ],y[PGS_ZZZ];
+    octet X= {0, sizeof(x),x};
+    octet Y= {0,sizeof(y),y};
+
+    /* Master secret shares */
+    char ms1[PGS_ZZZ], ms2[PGS_ZZZ];
+    octet MS1= {0,sizeof(ms1),ms1};
+    octet MS2= {0,sizeof(ms2),ms2};
+
+    /* Hash values of Client ID */
+    char hcid[PFS_ZZZ];
+    octet HCID= {0,sizeof(hcid), hcid};
+
+    /* Client secret and shares */
+    char cs1[2*PFS_ZZZ+1], cs2[2*PFS_ZZZ+1], sec[2*PFS_ZZZ+1];
+    octet SEC= {0,sizeof(sec),sec};
+    octet CS1= {0,sizeof(cs1), cs1};
+    octet CS2= {0,sizeof(cs2), cs2};
+
+    /* Server secret and shares */
+    char ss1[G2LEN], ss2[G2LEN], serverSecret[G2LEN];
+    octet ServerSecret= {0,sizeof(serverSecret),serverSecret};
+    octet SS1= {0,sizeof(ss1),ss1};
+    octet SS2= {0,sizeof(ss2),ss2};
+
+    /* Time Permit and shares */
+    char tp1[2*PFS_ZZZ+1], tp2[2*PFS_ZZZ+1], tp[2*PFS_ZZZ+1];
+    octet TP= {0,sizeof(tp),tp};
+    octet TP1= {0,sizeof(tp1),tp1};
+    octet TP2= {0,sizeof(tp2),tp2};
+
+    /* Token stored on computer */
+    char token[2*PFS_ZZZ+1];
+    octet TOKEN= {0,sizeof(token),token};
+
+    char ut[2*PFS_ZZZ+1],u[2*PFS_ZZZ+1];
+    octet UT= {0,sizeof(ut),ut};
+    octet U= {0,sizeof(u),u};
+
+    char hid[2*PFS_ZZZ+1],htid[2*PFS_ZZZ+1];
+    octet HID= {0,sizeof(hid),hid};
+    octet HTID= {0,sizeof(htid),htid};
+
+    char e[GTLEN], f[GTLEN];
+    octet E= {0,sizeof(e),e};
+    octet F= {0,sizeof(f),f};
+
+    PIN1 = 1234;
+    PIN2 = 1234;
+
+    /* Assign the End-User an ID */
+    char* user = "testuser@miracl.com";
+    OCT_jstring(&ID,user);
+    printf("CLIENT: ID %s\n", user);
+
+    int date = 0;
+    char seed[100] = {0};
+    octet SEED = {0,sizeof(seed),seed};
+    csprng RNG;
+
+    /* unrandom seed value! */
+    SEED.len=100;
+    for (i=0; i<100; i++) SEED.val[i]=i+1;
+
+    /* initialise random number generator */
+    CREATE_CSPRNG(&RNG,&SEED);
+
+    /* Hash ID */
+    HASH_ID(HASH_TYPE_ZZZ,&ID,&HCID);
+    OCT_output(&HCID);
+
+    /* Generate Client master secret for MIRACL and Customer */
+    rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("MASTER SECRET MIRACL:= 0x");
+    OCT_output(&MS1);
+    printf("MASTER SECRET CUSTOMER:= 0x");
+    OCT_output(&MS2);
+
+    /* Generate server secret shares */
+    rtn = MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&SS1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&SS1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_GET_SERVER_SECRET(&MS2,&SS2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_SERVER_SECRET(&MS2,&SS2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("SS1 = 0x");
+    OCT_output(&SS1);
+    printf("SS2 = 0x");
+    OCT_output(&SS2);
+
+    /* Combine server secret share */
+    rtn = MPIN_ZZZ_RECOMBINE_G2(&SS1, &SS2, &ServerSecret);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RECOMBINE_G2(&SS1, &SS2, &ServerSecret) Error %d\n", rtn);
+        return 1;
+    }
+    printf("ServerSecret = 0x");
+    OCT_output(&ServerSecret);
+
+    /* Generate client secret shares */
+    rtn = MPIN_ZZZ_GET_CLIENT_SECRET(&MS1,&HCID,&CS1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_SECRET(&MS1,&HCID,&CS1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_GET_CLIENT_SECRET(&MS2,&HCID,&CS2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_SECRET(&MS2,&HCID,&CS2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("CS1 = 0x");
+    OCT_output(&CS1);
+    printf("CS2 = 0x");
+    OCT_output(&CS2);
+
+    /* Combine client secret shares : TOKEN is the full client secret */
+    rtn = MPIN_ZZZ_RECOMBINE_G1(&CS1, &CS2, &TOKEN);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RECOMBINE_G1(&CS1, &CS2, &TOKEN) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Client Secret = 0x");
+    OCT_output(&TOKEN);
+
+    /* Generate Time Permit shares */
+    date = today();
+    printf("Date %d \n", date);
+    rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS1,&HCID,&TP1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_PERMIT(date,&MS1,&HCID,&TP1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS2,&HCID,&TP2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_PERMIT(date,&MS2,&HCID,&TP2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("TP1 = 0x");
+    OCT_output(&TP1);
+    printf("TP2 = 0x");
+    OCT_output(&TP2);
+
+    /* Combine Time Permit shares */
+    rtn = MPIN_ZZZ_RECOMBINE_G1(&TP1, &TP2, &TP);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RECOMBINE_G1(&TP1, &TP2, &TP) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Time Permit = 0x");
+    OCT_output(&TP);
+
+    /* Client extracts PIN1 from secret to create Token */
+    rtn = MPIN_ZZZ_EXTRACT_PIN(HASH_TYPE_ZZZ,&ID, PIN1, &TOKEN);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_EXTRACT_PIN( &ID, PIN, &TOKEN) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Token = 0x");
+    OCT_output(&TOKEN);
+
+    /* Client first pass */
+    rtn = MPIN_ZZZ_CLIENT_1(HASH_TYPE_ZZZ,date,&ID,&RNG,&X,PIN2,&TOKEN,&SEC,&U,&UT,&TP);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_CLIENT_1 ERROR %d\n", rtn);
+        return 1;
+    }
+
+    /* Server calculates H(ID) and H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. */
+    MPIN_ZZZ_SERVER_1(HASH_TYPE_ZZZ,date,&ID,&HID,&HTID);
+
+    /* Server generates Random number Y and sends it to Client */
+    rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&Y);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&Y) Error %d\n", rtn);
+        return 1;
+    }
+
+    printf("Y = 0x");
+    OCT_output(&Y);
+
+    /* Client second pass */
+    rtn = MPIN_ZZZ_CLIENT_2(&X,&Y,&SEC);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_CLIENT_2(&X,&Y,&SEC) Error %d\n", rtn);
+        return 1;
+    }
+    printf("V = 0x");
+    OCT_output(&SEC);
+
+    /* Server second pass */
+    rtn = MPIN_ZZZ_SERVER_2(date,&HID,&HTID,&Y,&ServerSecret,&U,&UT,&SEC,&E,&F,NULL);
+
+    if (rtn != 0)
+    {
+        err=MPIN_ZZZ_KANGAROO(&E,&F);
+        if (err==0)
+        {
+            printf("FAILURE Invalid Token Error Code %d\n", rtn);
+        }
+        else
+        {
+            printf("FAILURE PIN Error %d, Error> Code %d\n",err, rtn);
+        }
+    }
+    else
+    {
+        printf("SUCCESS Error Code %d\n", rtn);
+    }
+    KILL_CSPRNG(&RNG);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_mpin_random_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpin_random_ZZZ.c.in b/test/test_mpin_random_ZZZ.c.in
new file mode 100644
index 0000000..a4a35aa
--- /dev/null
+++ b/test/test_mpin_random_ZZZ.c.in
@@ -0,0 +1,346 @@
+/**
+ * @file test_mpin_random_ZZZ.c
+ * @author Kealan McCusker
+ * @brief Test good token and correct PIN with D-TA
+ *
+ * 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 good token and correct PIN with D-TA */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "config_curve_ZZZ.h"
+#include "config_test.h"
+#include "pbc_support.h"
+#include "randapi.h"
+#if CURVE_SECURITY_ZZZ == 128
+#include "mpin_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "mpin192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "mpin256_ZZZ.h"
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*PFS_ZZZ
+#endif
+#define GTLEN 3*G2LEN
+
+// Define PIN range:
+#define MAX_RANGE 10000
+
+void rand_str(char *dest, size_t length,csprng *RNG)
+{
+    BIG_XXX r;
+    char charset[] = "0123456789@.*"
+                     "abcdefghijklmnopqrstuvwxyz"
+                     "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    while (length-- > 0)
+    {
+        BIG_XXX_random(r,RNG);
+        size_t index = r[0] % (sizeof charset);
+        *dest++ = charset[index];
+    }
+    *dest = '\0';
+}
+
+int main()
+{
+    int PIN1,PIN2,rtn,err,iter;
+
+    char x[PGS_ZZZ],y[PGS_ZZZ];
+    octet X= {0, sizeof(x),x};
+    octet Y= {0,sizeof(y),y};
+
+    /* Master secret shares */
+    char ms1[PGS_ZZZ], ms2[PGS_ZZZ];
+    octet MS1= {0,sizeof(ms1),ms1};
+    octet MS2= {0,sizeof(ms2),ms2};
+
+    /* Hash values of ID */
+    char hcid[PFS_ZZZ];
+    octet HCID= {0,sizeof(hcid), hcid};
+
+    /* Client secret and shares */
+    char cs1[2*PFS_ZZZ+1], cs2[2*PFS_ZZZ+1], sec[2*PFS_ZZZ+1];
+    octet SEC= {0,sizeof(sec),sec};
+    octet CS1= {0,sizeof(cs1), cs1};
+    octet CS2= {0,sizeof(cs2), cs2};
+
+    /* Server secret and shares */
+    char ss1[G2LEN], ss2[G2LEN], serverSecret[G2LEN];
+    octet ServerSecret= {0,sizeof(serverSecret),serverSecret};
+    octet SS1= {0,sizeof(ss1),ss1};
+    octet SS2= {0,sizeof(ss2),ss2};
+
+    /* Time Permit and shares */
+    char tp1[2*PFS_ZZZ+1], tp2[2*PFS_ZZZ+1], tp[2*PFS_ZZZ+1];
+    octet TP= {0,sizeof(tp),tp};
+    octet TP1= {0,sizeof(tp1),tp1};
+    octet TP2= {0,sizeof(tp2),tp2};
+
+    /* Token stored on computer */
+    char token[2*PFS_ZZZ+1];
+    octet TOKEN= {0,sizeof(token),token};
+
+    char ut[2*PFS_ZZZ+1],u[2*PFS_ZZZ+1];
+    octet UT= {0,sizeof(ut),ut};
+    octet U= {0,sizeof(u),u};
+
+    char hid[2*PFS_ZZZ+1],htid[2*PFS_ZZZ+1];
+    octet HID= {0,sizeof(hid),hid};
+    octet HTID= {0,sizeof(htid),htid};
+
+    char e[GTLEN], f[GTLEN];
+    octet E= {0,sizeof(e),e};
+    octet F= {0,sizeof(f),f};
+
+    int date = 0;
+
+    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! */
+    int i;
+    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 = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS1);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS1) Error %d\n", rtn);
+            return 1;
+        }
+        rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS2);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS2) Error %d\n", rtn);
+            return 1;
+        }
+        printf("MASTER SECRET MIRACL:= 0x");
+        OCT_output(&MS1);
+        printf("MASTER SECRET CUSTOMER:= 0x");
+        OCT_output(&MS2);
+
+        /* Generate server secret shares */
+        rtn = MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&SS1);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&SS1) Error %d\n", rtn);
+            return 1;
+        }
+        rtn = MPIN_ZZZ_GET_SERVER_SECRET(&MS2,&SS2);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_GET_SERVER_SECRET(&MS2,&SS2) Error %d\n", rtn);
+            return 1;
+        }
+        printf("SS1 = 0x");
+        OCT_output(&SS1);
+        printf("SS2 = 0x");
+        OCT_output(&SS2);
+
+        /* Combine server secret share */
+        rtn = MPIN_ZZZ_RECOMBINE_G2(&SS1, &SS2, &ServerSecret);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_RECOMBINE_G2(&SS1, &SS2, &ServerSecret) Error %d\n", rtn);
+            return 1;
+        }
+        printf("ServerSecret = 0x");
+        OCT_output(&ServerSecret);
+
+        /* Assign the End-User an ID */
+        char id[256];
+        octet ID = {0,sizeof(id),id};
+        //rand_str(id,255,&RNG);
+        OCT_jstring(&ID,"testuser@miracl.com");
+        printf("CLIENT_ID = ");
+        OCT_output(&ID);
+
+        /* Hash ID */
+        HASH_ID(HASH_TYPE_ZZZ,&ID,&HCID);
+        OCT_output(&HCID);
+
+        srand ( time (NULL) );
+        PIN1 = rand()%MAX_RANGE; // Get random between 0 and MAX_RANGE
+        PIN2 = PIN1;
+        printf("PIN1 %d PIN2 %d\n", PIN1, PIN2);
+
+        /* Generate client secret shares */
+        rtn = MPIN_ZZZ_GET_CLIENT_SECRET(&MS1,&HCID,&CS1);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_GET_CLIENT_SECRET(&MS1,&HCID,&CS1) Error %d\n", rtn);
+            return 1;
+        }
+        rtn = MPIN_ZZZ_GET_CLIENT_SECRET(&MS2,&HCID,&CS2);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_GET_CLIENT_SECRET(&MS2,&HCID,&CS2) Error %d\n", rtn);
+            return 1;
+        }
+        printf("CS1 = 0x");
+        OCT_output(&CS1);
+        printf("CS2 = 0x");
+        OCT_output(&CS2);
+
+        /* Combine client secret shares : TOKEN is the full client secret */
+        rtn = MPIN_ZZZ_RECOMBINE_G1(&CS1, &CS2, &TOKEN);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_RECOMBINE_G1(&CS1, &CS2, &TOKEN) Error %d\n", rtn);
+            return 1;
+        }
+        printf("Client Secret = 0x");
+        OCT_output(&TOKEN);
+
+        /* Client extracts PIN1 from secret to create Token */
+        rtn = MPIN_ZZZ_EXTRACT_PIN(HASH_TYPE_ZZZ,&ID, PIN1, &TOKEN);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_EXTRACT_PIN( &ID, PIN, &TOKEN) Error %d\n", rtn);
+            return 1;
+        }
+        printf("Token = 0x");
+        OCT_output(&TOKEN);
+
+        /* Generate Time Permit shares */
+        date = today();
+
+        printf("Date %d \n", date);
+        rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS1,&HCID,&TP1);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_GET_CLIENT_PERMIT(date,&MS1,&HCID,&TP1) Error %d\n", rtn);
+            return 1;
+        }
+        rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS2,&HCID,&TP2);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_GET_CLIENT_PERMIT(date,&MS2,&HCID,&TP2) Error %d\n", rtn);
+            return 1;
+        }
+        printf("TP1 = 0x");
+        OCT_output(&TP1);
+        printf("TP2 = 0x");
+        OCT_output(&TP2);
+
+        /* Combine Time Permit shares */
+        rtn = MPIN_ZZZ_RECOMBINE_G1(&TP1, &TP2, &TP);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_RECOMBINE_G1(&TP1, &TP2, &TP) Error %d\n", rtn);
+            return 1;
+        }
+        printf("Time Permit = 0x");
+        OCT_output(&TP);
+
+        /* Client first pass */
+        rtn = MPIN_ZZZ_CLIENT_1(HASH_TYPE_ZZZ,date,&ID,&RNG,&X,PIN2,&TOKEN,&SEC,&U,&UT,&TP);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_CLIENT_1 ERROR %d\n", rtn);
+            return 1;
+        }
+        printf("Date = %d\n",date);
+        printf("U = 0x");
+        OCT_output(&U);
+        printf("UT = 0x");
+        OCT_output(&UT);
+        printf("X = 0x");
+        OCT_output(&X);
+
+        /* Server calculates H(ID) and H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. */
+        MPIN_ZZZ_SERVER_1(HASH_TYPE_ZZZ,date,&ID,&HID,&HTID);
+
+        /* Server generates Random number Y and sends it to Client */
+        rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&Y);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&Y) Error %d\n", rtn);
+            return 1;
+        }
+        printf("Y = 0x");
+        OCT_output(&Y);
+
+        /* Client second pass */
+        rtn = MPIN_ZZZ_CLIENT_2(&X,&Y,&SEC);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_CLIENT_2(&X,&Y,&SEC) Error %d\n", rtn);
+            return 1;
+        }
+        printf("V = 0x");
+        OCT_output(&SEC);
+
+        /* Server second pass */
+        rtn = MPIN_ZZZ_SERVER_2(date,&HID,&HTID,&Y,&ServerSecret,&U,&UT,&SEC,&E,&F,NULL);
+
+        if (rtn != 0)
+        {
+            err=MPIN_ZZZ_KANGAROO(&E,&F);
+            if (err==0)
+            {
+                printf("Iteration %d FAILURE Invalid Token Error Code %d\n", iter, rtn);
+                return 1;
+            }
+            else
+            {
+                printf("Iteration %d FAILURE PIN Error %d, Error Code %d\n", iter, err, rtn);
+                return 1;
+            }
+        }
+        else
+        {
+            printf("Iteration %d SUCCESS Error Code %d\n\n", iter, rtn);
+        }
+    }
+    KILL_CSPRNG(&RNG);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_mpin_sign_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpin_sign_ZZZ.c.in b/test/test_mpin_sign_ZZZ.c.in
new file mode 100644
index 0000000..7489f10
--- /dev/null
+++ b/test/test_mpin_sign_ZZZ.c.in
@@ -0,0 +1,507 @@
+/**
+ * @file test_mpin_sign_ZZZ.c
+ * @author Kealan McCusker
+ * @brief Test function for M-Pin Signature
+ *
+ * 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 M-Pin Signature */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "config_curve_ZZZ.h"
+#include "pbc_support.h"
+#include "randapi.h"
+#if CURVE_SECURITY_ZZZ == 128
+#include "mpin_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "mpin192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "mpin256_ZZZ.h"
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*PFS_ZZZ
+#endif
+#define GTLEN 3*G2LEN
+
+int main()
+{
+    int i,PIN1,PIN2,rtn;
+
+    char id[256];
+    octet ID = {0,sizeof(id),id};
+
+    // Message to sign
+    char m[256];
+    octet M= {0,sizeof(m),m};
+
+    char x[PGS_ZZZ],y1[PGS_ZZZ],y2[PGS_ZZZ];
+    octet X= {0,sizeof(x),x};
+    octet Y1= {0,sizeof(y1),y1};
+    octet Y2= {0,sizeof(y2),y2};
+
+    /* Master secret shares */
+    char ms1[PGS_ZZZ], ms2[PGS_ZZZ];
+    octet MS1= {0,sizeof(ms1),ms1};
+    octet MS2= {0,sizeof(ms2),ms2};
+
+    /* Hash values of Client ID */
+    char hcid[PFS_ZZZ];
+    octet HCID= {0,sizeof(hcid), hcid};
+
+    /* Client secret and shares */
+    char cs1[2*PFS_ZZZ+1], cs2[2*PFS_ZZZ+1], sec[2*PFS_ZZZ+1];
+    octet SEC= {0,sizeof(sec),sec};
+    octet CS1= {0,sizeof(cs1), cs1};
+    octet CS2= {0,sizeof(cs2), cs2};
+
+    /* Server secret and shares */
+    char ss1[G2LEN], ss2[G2LEN], serverSecret[G2LEN];
+    octet ServerSecret= {0,sizeof(serverSecret),serverSecret};
+    octet SS1= {0,sizeof(ss1),ss1};
+    octet SS2= {0,sizeof(ss2),ss2};
+
+    /* Time Permit and shares */
+    char tp1[2*PFS_ZZZ+1], tp2[2*PFS_ZZZ+1], tp[2*PFS_ZZZ+1];
+    octet TP= {0,sizeof(tp),tp};
+    octet TP1= {0,sizeof(tp1),tp1};
+    octet TP2= {0,sizeof(tp2),tp2};
+
+    /* Token stored on computer */
+    char token[2*PFS_ZZZ+1];
+    octet TOKEN= {0,sizeof(token),token};
+
+    char ut[2*PFS_ZZZ+1];
+    octet UT= {0,sizeof(ut),ut};
+
+    char hid[2*PFS_ZZZ+1],htid[2*PFS_ZZZ+1];
+    octet HID= {0,sizeof(hid),hid};
+    octet HTID= {0,sizeof(htid),htid};
+
+    char e[GTLEN], f[GTLEN];
+    octet E= {0,sizeof(e),e};
+    octet F= {0,sizeof(f),f};
+
+    int TimeValue = 0;
+
+    PIN1 = 1234;
+    PIN2 = 1234;
+
+    /* Assign the End-User an ID */
+    char* user = "testuser@miracl.com";
+    OCT_jstring(&ID,user);
+    printf("CLIENT: ID %s\n", user);
+
+    int date = 0;
+    char seed[100] = {0};
+    octet SEED = {0,sizeof(seed),seed};
+    csprng RNG;
+
+    /* unrandom seed value! */
+    SEED.len=100;
+    for (i=0; i<100; i++) SEED.val[i]=i+1;
+
+    /* initialise random number generator */
+    CREATE_CSPRNG(&RNG,&SEED);
+
+    /* Hash ID */
+    HASH_ID(HASH_TYPE_ZZZ,&ID,&HCID);
+    OCT_output(&HCID);
+
+    /* Generate Client master secret for MIRACL and Customer */
+    rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("MASTER SECRET MIRACL:= 0x");
+    OCT_output(&MS1);
+    printf("MASTER SECRET CUSTOMER:= 0x");
+    OCT_output(&MS2);
+
+    /* Generate server secret shares */
+    rtn = MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&SS1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&SS1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_GET_SERVER_SECRET(&MS2,&SS2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_SERVER_SECRET(&MS2,&SS2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("SS1 = 0x");
+    OCT_output(&SS1);
+    printf("SS2 = 0x");
+    OCT_output(&SS2);
+
+    /* Combine server secret share */
+    rtn = MPIN_ZZZ_RECOMBINE_G2(&SS1, &SS2, &ServerSecret);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RECOMBINE_G2(&SS1, &SS2, &ServerSecret) Error %d\n", rtn);
+        return 1;
+    }
+    printf("ServerSecret = 0x");
+    OCT_output(&ServerSecret);
+
+    /* Generate client secret shares */
+    rtn = MPIN_ZZZ_GET_CLIENT_SECRET(&MS1,&HCID,&CS1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_SECRET(&MS1,&HCID,&CS1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_GET_CLIENT_SECRET(&MS2,&HCID,&CS2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_SECRET(&MS2,&HCID,&CS2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("CS1 = 0x");
+    OCT_output(&CS1);
+    printf("CS2 = 0x");
+    OCT_output(&CS2);
+
+    /* Combine client secret shares : TOKEN is the full client secret */
+    rtn = MPIN_ZZZ_RECOMBINE_G1(&CS1, &CS2, &TOKEN);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RECOMBINE_G1(&CS1, &CS2, &TOKEN) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Client Secret = 0x");
+    OCT_output(&TOKEN);
+
+    /* Client extracts PIN1 from secret to create Token */
+    rtn = MPIN_ZZZ_EXTRACT_PIN(HASH_TYPE_ZZZ,&ID, PIN1, &TOKEN);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_EXTRACT_PIN( &ID, PIN, &TOKEN) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Token = 0x");
+    OCT_output(&TOKEN);
+
+    /*********** Fix values for date and time  ********/
+    printf("Fix values for date and time\n");
+    date = 17072;
+    printf("Date %d \n", date);
+    TimeValue = 1475079474;
+    printf("TimeValue %d \n", TimeValue);
+
+    rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS1,&HCID,&TP1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS1,&HCID,&TP1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS2,&HCID,&TP2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS2,&HCID,&TP2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("TP1 = 0x");
+    OCT_output(&TP1);
+    printf("TP2 = 0x");
+    OCT_output(&TP2);
+
+    /* Combine Time Permit shares */
+    rtn = MPIN_ZZZ_RECOMBINE_G1(&TP1, &TP2, &TP);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RECOMBINE_G1(&TP1, &TP2, &TP) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Time Permit = 0x");
+    OCT_output(&TP);
+
+    /* Good signature */
+    printf("***** Fixed good signature *****\n");
+
+    /* Client  */
+    char* message = "sign this message";
+    OCT_jstring(&M,message);
+    rtn = MPIN_ZZZ_CLIENT(HASH_TYPE_ZZZ,date,&ID,&RNG,&X,PIN2,&TOKEN,&SEC,NULL,&UT,&TP,&M,TimeValue,&Y1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_CLIENT ERROR %d\n", rtn);
+        return 1;
+    }
+    printf("Y1 = 0x");
+    OCT_output(&Y1);
+    printf("V = 0x");
+    OCT_output(&SEC);
+
+    /* Server  */
+    rtn = MPIN_ZZZ_SERVER(HASH_TYPE_ZZZ,date,&HID,&HTID,&Y2,&ServerSecret,NULL,&UT,&SEC,&E,&F,&ID,&M,TimeValue,NULL);
+
+    printf("Y2 = 0x");
+    OCT_output(&Y2);
+    if (rtn != 0)
+    {
+        printf("TEST FAILED: valid signature not detected %d\n", rtn);
+        return 1;
+    }
+    else
+    {
+        printf("SUCCESS Error Code %d\n", rtn);
+    }
+
+    /* Time stamp expired */
+    printf("***** Fixed time stamp expired *****\n");
+
+    /* Client  */
+    OCT_clear(&M);
+    message = "sign this message";
+    OCT_jstring(&M,message);
+    rtn = MPIN_ZZZ_CLIENT(HASH_TYPE_ZZZ,date,&ID,&RNG,&X,PIN2,&TOKEN,&SEC,NULL,&UT,&TP,&M,TimeValue,&Y1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_CLIENT ERROR %d\n", rtn);
+        return 1;
+    }
+    printf("Y1 = 0x");
+    OCT_output(&Y1);
+    printf("V = 0x");
+    OCT_output(&SEC);
+
+    /* Server  */
+    TimeValue += 10;
+
+    rtn = MPIN_ZZZ_SERVER(HASH_TYPE_ZZZ,date,&HID,&HTID,&Y2,&ServerSecret,NULL,&UT,&SEC,&E,&F,&ID,&M,TimeValue,NULL);
+
+    printf("Y2 = 0x");
+    OCT_output(&Y2);
+    if (rtn != -19)
+    {
+        printf("TEST FAILED: Invalid signature not detected %d\n", rtn);
+        return 1;
+    }
+    else
+    {
+        printf("SUCCESS Error Code %d\n", rtn);
+    }
+
+    /* Invalid data */
+    printf("***** Fixed invalid data *****\n");
+
+    /* Client  */
+    OCT_clear(&M);
+    message = "sign this message";
+    OCT_jstring(&M,message);
+    OCT_clear(&Y1);
+    rtn = MPIN_ZZZ_CLIENT(HASH_TYPE_ZZZ,date,&ID,&RNG,&X,PIN2,&TOKEN,&SEC,NULL,&UT,&TP,&M,TimeValue,&Y1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_CLIENT ERROR %d\n", rtn);
+        return 1;
+    }
+    printf("Y1 = 0x");
+    OCT_output(&Y1);
+    printf("V = 0x");
+    OCT_output(&SEC);
+
+    /* Server  */
+    OCT_clear(&M);
+    message = "bad message";
+    OCT_jstring(&M,message);
+
+    rtn = MPIN_ZZZ_SERVER(HASH_TYPE_ZZZ,date,&HID,&HTID,&Y2,&ServerSecret,NULL,&UT,&SEC,&E,&F,&ID,&M,TimeValue,NULL);
+
+    printf("Y2 = 0x");
+    OCT_output(&Y2);
+    if (rtn != -19)
+    {
+        printf("TEST FAILED: Invalid signature not detected %d\n", rtn);
+        return 1;
+    }
+    else
+    {
+        printf("SUCCESS Error Code %d\n", rtn);
+    }
+
+    /*********** Current date and time  ********/
+    printf("Current date and time\n");
+
+    date = today();
+    printf("Date %d \n", date);
+    TimeValue = GET_TIME();
+    printf("TimeValue %d \n", TimeValue);
+
+    /* Generate Time Permit shares */
+    rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS1,&HCID,&TP1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS1,&HCID,&TP1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS2,&HCID,&TP2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS2,&HCID,&TP2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("TP1 = 0x");
+    OCT_output(&TP1);
+    printf("TP2 = 0x");
+    OCT_output(&TP2);
+
+    /* Combine Time Permit shares */
+    rtn = MPIN_ZZZ_RECOMBINE_G1(&TP1, &TP2, &TP);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RECOMBINE_G1(&TP1, &TP2, &TP) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Time Permit = 0x");
+    OCT_output(&TP);
+
+
+    /* Good signature */
+    printf("***** Good signature *****\n");
+    ;
+    /* Client  */
+    message = "sign this message";
+    OCT_jstring(&M,message);
+    rtn = MPIN_ZZZ_CLIENT(HASH_TYPE_ZZZ,date,&ID,&RNG,&X,PIN2,&TOKEN,&SEC,NULL,&UT,&TP,&M,TimeValue,&Y1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_CLIENT ERROR %d\n", rtn);
+        return 1;
+    }
+    printf("Y1 = 0x");
+    OCT_output(&Y1);
+    printf("V = 0x");
+    OCT_output(&SEC);
+
+    /* Server  */
+    rtn = MPIN_ZZZ_SERVER(HASH_TYPE_ZZZ,date,&HID,&HTID,&Y2,&ServerSecret,NULL,&UT,&SEC,&E,&F,&ID,&M,TimeValue,NULL);
+
+    printf("Y2 = 0x");
+    OCT_output(&Y2);
+    if (rtn != 0)
+    {
+        printf("TEST FAILED: valid signature not detected %d\n", rtn);
+        return 1;
+    }
+    else
+    {
+        printf("SUCCESS Error Code %d\n", rtn);
+    }
+
+    /* Time stamp expired */
+    printf("***** Time stamp expired *****\n");
+
+    /* Client  */
+    OCT_clear(&M);
+    message = "sign this message";
+    OCT_jstring(&M,message);
+    TimeValue = GET_TIME();
+    printf("TimeValue %d \n", TimeValue);
+    rtn = MPIN_ZZZ_CLIENT(HASH_TYPE_ZZZ,date,&ID,&RNG,&X,PIN2,&TOKEN,&SEC,NULL,&UT,&TP,&M,TimeValue,&Y1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_CLIENT ERROR %d\n", rtn);
+        return 1;
+    }
+    printf("Y1 = 0x");
+    OCT_output(&Y1);
+    printf("V = 0x");
+    OCT_output(&SEC);
+
+    /* Server  */
+    TimeValue += 10;
+
+    rtn = MPIN_ZZZ_SERVER(HASH_TYPE_ZZZ,date,&HID,&HTID,&Y2,&ServerSecret,NULL,&UT,&SEC,&E,&F,&ID,&M,TimeValue,NULL);
+
+    printf("Y2 = 0x");
+    OCT_output(&Y2);
+    if (rtn != -19)
+    {
+        printf("TEST FAILED: Invalid signature not detected %d\n", rtn);
+        return 1;
+    }
+    else
+    {
+        printf("SUCCESS Error Code %d\n", rtn);
+    }
+
+    /* Invalid data */
+    printf("***** Invalid data *****\n");
+
+    /* Client  */
+    OCT_clear(&M);
+    message = "sign this message";
+    OCT_jstring(&M,message);
+    TimeValue = GET_TIME();
+    printf("TimeValue %d \n", TimeValue);
+    rtn = MPIN_ZZZ_CLIENT(HASH_TYPE_ZZZ,date,&ID,&RNG,&X,PIN2,&TOKEN,&SEC,NULL,&UT,&TP,&M,TimeValue,&Y1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_CLIENT ERROR %d\n", rtn);
+        return 1;
+    }
+    printf("Y1 = 0x");
+    OCT_output(&Y1);
+    printf("V = 0x");
+    OCT_output(&SEC);
+
+    /* Server  */
+    OCT_clear(&M);
+    message = "bad message";
+    OCT_jstring(&M,message);
+
+    rtn = MPIN_ZZZ_SERVER(HASH_TYPE_ZZZ,date,&HID,&HTID,&Y2,&ServerSecret,NULL,&UT,&SEC,&E,&F,&ID,&M,TimeValue,NULL);
+
+    printf("Y2 = 0x");
+    OCT_output(&Y2);
+    if (rtn != -19)
+    {
+        printf("TEST FAILED: Invalid signature not detected %d\n", rtn);
+        return 1;
+    }
+    else
+    {
+        printf("SUCCESS Error Code %d\n", rtn);
+    }
+
+    printf("TEST PASSED\n");
+    KILL_CSPRNG(&RNG);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_mpin_tp_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpin_tp_ZZZ.c.in b/test/test_mpin_tp_ZZZ.c.in
new file mode 100644
index 0000000..8ef696a
--- /dev/null
+++ b/test/test_mpin_tp_ZZZ.c.in
@@ -0,0 +1,305 @@
+/**
+ * @file test_mpin_tp_ZZZ.c
+ * @author Kealan McCusker
+ * @brief Test good token and correct PIN with D-TA for nTimePermitTests days in the future
+ *
+ * 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 good token and correct PIN with D-TA for
+   nTimePermitTests days in the future */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "config_curve_ZZZ.h"
+#include "pbc_support.h"
+#include "randapi.h"
+#if CURVE_SECURITY_ZZZ == 128
+#include "mpin_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "mpin192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "mpin256_ZZZ.h"
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*PFS_ZZZ
+#endif
+#define GTLEN 3*G2LEN
+
+#define nTimePermitTests 10
+
+int main()
+{
+    int i,PIN1,PIN2,rtn,err,iter;
+
+    char id[256];
+    octet ID = {0,sizeof(id),id};
+
+    char x[PGS_ZZZ],y[PGS_ZZZ];
+    octet X= {0, sizeof(x),x};
+    octet Y= {0,sizeof(y),y};
+
+    /* Master secret shares */
+    char ms1[PGS_ZZZ], ms2[PGS_ZZZ];
+    octet MS1= {0,sizeof(ms1),ms1};
+    octet MS2= {0,sizeof(ms2),ms2};
+
+    /* Hash values of ID */
+    char hcid[PFS_ZZZ];
+    octet HCID= {0,sizeof(hcid), hcid};
+
+    /* Client secret and shares */
+    char cs1[2*PFS_ZZZ+1], cs2[2*PFS_ZZZ+1], sec[2*PFS_ZZZ+1];
+    octet SEC= {0,sizeof(sec),sec};
+    octet CS1= {0,sizeof(cs1), cs1};
+    octet CS2= {0,sizeof(cs2), cs2};
+
+    /* Server secret and shares */
+    char ss1[G2LEN], ss2[G2LEN], serverSecret[G2LEN];
+    octet ServerSecret= {0,sizeof(serverSecret),serverSecret};
+    octet SS1= {0,sizeof(ss1),ss1};
+    octet SS2= {0,sizeof(ss2),ss2};
+
+    /* Time Permit and shares */
+    char tp1[2*PFS_ZZZ+1], tp2[2*PFS_ZZZ+1], tp[2*PFS_ZZZ+1];
+    octet TP= {0,sizeof(tp),tp};
+    octet TP1= {0,sizeof(tp1),tp1};
+    octet TP2= {0,sizeof(tp2),tp2};
+
+    /* Token stored on computer */
+    char token[2*PFS_ZZZ+1];
+    octet TOKEN= {0,sizeof(token),token};
+
+    char ut[2*PFS_ZZZ+1],u[2*PFS_ZZZ+1];
+    octet UT= {0,sizeof(ut),ut};
+    octet U= {0,sizeof(u),u};
+
+    char hid[2*PFS_ZZZ+1],htid[2*PFS_ZZZ+1];
+    octet HID= {0,sizeof(hid),hid};
+    octet HTID= {0,sizeof(htid),htid};
+
+    char e[GTLEN], f[GTLEN];
+    octet E= {0,sizeof(e),e};
+    octet F= {0,sizeof(f),f};
+
+    PIN1 = 1234;
+    PIN2 = 1234;
+
+    /* Assign the End-User an ID */
+    char* user = "testuser@miracl.com";
+    OCT_jstring(&ID,user);
+    printf("CLIENT: ID %s\n", user);
+
+    int date = 0;
+    char seed[100] = {0};
+    octet SEED = {0,sizeof(seed),seed};
+    csprng RNG;
+
+    /* unrandom seed value! */
+    SEED.len=100;
+    for (i=0; i<100; i++) SEED.val[i]=i+1;
+
+    /* initialise random number generator */
+    CREATE_CSPRNG(&RNG,&SEED);
+
+    /* Hash ID */
+    HASH_ID(HASH_TYPE_ZZZ,&ID,&HCID);
+    OCT_output(&HCID);
+
+    /* Generate Client master secret for MIRACL and Customer */
+    rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("MASTER SECRET MIRACL:= 0x");
+    OCT_output(&MS1);
+    printf("MASTER SECRET CUSTOMER:= 0x");
+    OCT_output(&MS2);
+
+    /* Generate server secret shares */
+    rtn = MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&SS1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&SS1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_GET_SERVER_SECRET(&MS2,&SS2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_SERVER_SECRET(&MS2,&SS2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("SS1 = 0x");
+    OCT_output(&SS1);
+    printf("SS2 = 0x");
+    OCT_output(&SS2);
+
+    /* Combine server secret share */
+    rtn = MPIN_ZZZ_RECOMBINE_G2(&SS1, &SS2, &ServerSecret);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RECOMBINE_G2(&SS1, &SS2, &ServerSecret) Error %d\n", rtn);
+        return 1;
+    }
+    printf("ServerSecret = 0x");
+    OCT_output(&ServerSecret);
+
+    /* Generate client secret shares */
+    rtn = MPIN_ZZZ_GET_CLIENT_SECRET(&MS1,&HCID,&CS1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_SECRET(&MS1,&HCID,&CS1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_GET_CLIENT_SECRET(&MS2,&HCID,&CS2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_SECRET(&MS2,&HCID,&CS2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("CS1 = 0x");
+    OCT_output(&CS1);
+    printf("CS2 = 0x");
+    OCT_output(&CS2);
+
+    /* Combine client secret shares : TOKEN is the full client secret */
+    rtn = MPIN_ZZZ_RECOMBINE_G1(&CS1, &CS2, &TOKEN);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RECOMBINE_G1(&CS1, &CS2, &TOKEN) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Client Secret = 0x");
+    OCT_output(&TOKEN);
+
+    /* Client extracts PIN1 from secret to create Token */
+    rtn = MPIN_ZZZ_EXTRACT_PIN(HASH_TYPE_ZZZ,&ID, PIN1, &TOKEN);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_EXTRACT_PIN( &ID, PIN, &TOKEN) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Token = 0x");
+    OCT_output(&TOKEN);
+
+    /* Generate Time Permit shares */
+    date = today();
+    for(iter=1; iter<nTimePermitTests+1; iter++)
+    {
+        printf("Date %d \n", date);
+        rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS1,&HCID,&TP1);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS1,&HCID,&TP1) Error %d\n", rtn);
+            return 1;
+        }
+        rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS2,&HCID,&TP2);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,date,&MS2,&HCID,&TP2) Error %d\n", rtn);
+            return 1;
+        }
+        printf("TP1 = 0x");
+        OCT_output(&TP1);
+        printf("TP2 = 0x");
+        OCT_output(&TP2);
+
+        /* Combine Time Permit shares */
+        rtn = MPIN_ZZZ_RECOMBINE_G1(&TP1, &TP2, &TP);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_RECOMBINE_G1(&TP1, &TP2, &TP) Error %d\n", rtn);
+            return 1;
+        }
+        printf("Time Permit = 0x");
+        OCT_output(&TP);
+
+        /* Client first pass */
+        rtn = MPIN_ZZZ_CLIENT_1(HASH_TYPE_ZZZ,date,&ID,&RNG,&X,PIN2,&TOKEN,&SEC,&U,&UT,&TP);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_CLIENT_1 ERROR %d\n", rtn);
+            return 1;
+        }
+
+        /* Server calculates H(ID) and H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. */
+        MPIN_ZZZ_SERVER_1(HASH_TYPE_ZZZ,date,&ID,&HID,&HTID);
+
+        /* Server generates Random number Y and sends it to Client */
+        rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&Y);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&Y) Error %d\n", rtn);
+            return 1;
+        }
+        printf("Y = 0x");
+        OCT_output(&Y);
+
+        /* Client second pass */
+        rtn = MPIN_ZZZ_CLIENT_2(&X,&Y,&SEC);
+        if (rtn != 0)
+        {
+            printf("MPIN_ZZZ_CLIENT_2(&X,&Y,&SEC) Error %d\n", rtn);
+            return 1;
+        }
+        printf("V = 0x");
+        OCT_output(&SEC);
+
+        /* Server second pass */
+        rtn = MPIN_ZZZ_SERVER_2(date,&HID,&HTID,&Y,&ServerSecret,&U,&UT,&SEC,&E,&F,NULL);
+
+        if (rtn != 0)
+        {
+            err=MPIN_ZZZ_KANGAROO(&E,&F);
+            if (err==0)
+            {
+                printf("Iteration %d FAILURE Invalid Token Error Code %d\n", iter, rtn);
+                break;
+            }
+            else
+            {
+                printf("Iteration %d FAILURE PIN Error %d, Error Code %d\n", iter, err, rtn);
+                break;
+            }
+        }
+        else
+        {
+            printf("Iteration %d SUCCESS Error Code %d\n", iter, rtn);
+        }
+        date++;
+    }
+    KILL_CSPRNG(&RNG);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_mpin_vectors_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpin_vectors_ZZZ.c.in b/test/test_mpin_vectors_ZZZ.c.in
new file mode 100644
index 0000000..ffa7543
--- /dev/null
+++ b/test/test_mpin_vectors_ZZZ.c.in
@@ -0,0 +1,540 @@
+/**
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "config_curve_ZZZ.h"
+#include "pbc_support.h"
+#include "randapi.h"
+#include "utils.h"
+#if CURVE_SECURITY_ZZZ == 128
+#include "mpin_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "mpin192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "mpin256_ZZZ.h"
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*PFS_ZZZ
+#endif
+#define GTLEN 3*G2LEN
+
+#define LINE_LEN 1000
+
+void read_OCTET(octet* OCT, char* string)
+{
+    int len = strlen(string);
+    char buff[len];
+    strncpy(buff,string,len);
+    char *end = strchr(buff,',');
+    if (end == NULL)
+    {
+        printf("ERROR unexpected test vector %s\n",string);
+        exit(EXIT_FAILURE);
+    }
+    end[0] = '\0';
+    OCT_fromHex(OCT,buff);
+}
+
+int main(int argc, char** argv)
+{
+    if (argc != 2)
+    {
+        printf("usage: ./test_mpin_vectors_ZZZ [path to test vector file]\n");
+        exit(EXIT_FAILURE);
+    }
+
+    int len = 0;
+    int errorCode = 0;
+    FILE *fp;
+
+    char line[LINE_LEN];
+    char * linePtr = NULL;
+
+    int applyVector=0;
+
+    // Do not use time permits
+    int date = 0;
+
+    const char* TESTline = "TEST = ";
+    int testNo;
+    const char* CURVEline = "CURVE = ";
+
+    // Master Secret
+    char ms1Golden[PFS_ZZZ];
+    octet MS1Golden= {0,sizeof(ms1Golden),ms1Golden};
+    const char* MS1line = "MS1 = ";
+    char ms2Golden[PFS_ZZZ];
+    octet MS2Golden= {0,sizeof(ms2Golden),ms2Golden};
+    const char* MS2line = "MS2 = ";
+
+    // Server Secret
+    char ss1[G2LEN];
+    octet SS1= {0,sizeof(ss1),ss1};
+    char ss1Golden[G2LEN];
+    octet SS1Golden= {0,sizeof(ss1Golden),ss1Golden};
+    const char* SS1line = "SS1 = ";
+
+    char ss2[G2LEN];
+    octet SS2= {0,sizeof(ss2),ss2};
+    char ss2Golden[G2LEN];
+    octet SS2Golden= {0,sizeof(ss2Golden),ss2Golden};
+    const char* SS2line = "SS2 = ";
+
+    char ss[G2LEN];
+    octet SS= {0,sizeof(ss),ss};
+    char ssGolden[G2LEN];
+    octet SSGolden= {0,sizeof(ssGolden),ssGolden};
+    const char* SSline = "SS = ";
+
+    // MPIN Id
+    char mpinidGolden[300+1];
+    octet MPINIdGolden= {0,sizeof(mpinidGolden),mpinidGolden};
+    const char* MPINIdline = "MPINId = ";
+
+    // PIN1 creates token
+    int PIN1 = 0;
+    const char* PIN1line = "PIN1 = ";
+
+    // PIN2 used for authentication
+    int PIN2 = 0;
+    const char* PIN2line = "PIN2 = ";
+
+    // Client Secret
+    char cs1[2*PFS_ZZZ+1];
+    octet CS1= {0,sizeof(cs1),cs1};
+    char cs1Golden[2*PFS_ZZZ+1];
+    octet CS1Golden= {0,sizeof(cs1Golden),cs1Golden};
+    const char* CS1line = "CS1 = ";
+
+    char cs2[2*PFS_ZZZ+1];
+    octet CS2= {0,sizeof(cs2),cs2};
+    char cs2Golden[2*PFS_ZZZ+1];
+    octet CS2Golden= {0,sizeof(cs2Golden),cs2Golden};
+    const char* CS2line = "CS2 = ";
+
+    char cs[2*PFS_ZZZ+1];
+    octet CS= {0,sizeof(cs),cs};
+    char csGolden[2*PFS_ZZZ+1];
+    octet CSGolden= {0,sizeof(csGolden),csGolden};
+    const char* CSline = "CS = ";
+
+    // Token
+    char token[2*PFS_ZZZ+1];
+    octet TOKEN= {0,sizeof(token),token};
+    char tokenGolden[2*PFS_ZZZ+1];
+    octet TOKENGolden= {0,sizeof(tokenGolden),tokenGolden};
+    const char* TOKENline = "TOKEN = ";
+
+    // X
+    char xGolden[PFS_ZZZ];
+    octet XGolden= {0,sizeof(xGolden),xGolden};
+    const char* Xline = "X = ";
+
+    // Commitment
+    char u[2*PFS_ZZZ+1];
+    octet U= {0,sizeof(u),u};
+    char uGolden[2*PFS_ZZZ+1];
+    octet UGolden= {0,sizeof(uGolden),uGolden};
+    const char* Uline = "U = ";
+
+    // Y
+    char yGolden[PFS_ZZZ];
+    octet YGolden= {0,sizeof(yGolden),yGolden};
+    const char* Yline = "Y = ";
+
+    // V
+    char v[2*PFS_ZZZ+1];
+    octet V= {0,sizeof(v),v};
+    char vGolden[2*PFS_ZZZ+1];
+    octet VGolden= {0,sizeof(vGolden),vGolden};
+    const char* Vline = "V = ";
+
+    // Authentication result
+    int AuthResultGolden = 0;
+    const char* AuthResultline = "AuthResult = ";
+
+    // Hash MPINId to integer
+    char hiid[PFS_ZZZ];
+    octet HiId= {0,sizeof(hiid),hiid};
+
+    // Hash MPINId to point
+    char hpid[2*PFS_ZZZ+1];
+    octet HpId= {0,sizeof(hpid),hpid};
+
+    // Unused parameters
+    octet *pUT=NULL,*pHTID=NULL,*pPERMIT=NULL,*pE=NULL,*pF=NULL;
+    csprng* RNG=NULL;
+
+    fp = fopen(argv[1], "r");
+    if (fp == NULL)
+    {
+        printf("ERROR opening test vector file\n");
+        exit(EXIT_FAILURE);
+    }
+
+    while (fgets(line, LINE_LEN, fp) != NULL)
+    {
+        // Read TEST Number
+        if (!strncmp(line,TESTline, strlen(TESTline)))
+        {
+            len = strlen(TESTline);
+            linePtr = line + len;
+            sscanf(linePtr,"%d\n",&testNo);
+#ifdef DEBUG
+            printf("TEST = %d\n",testNo);
+#endif
+        }
+        // Read Curve
+        if (!strncmp(line,CURVEline, strlen(CURVEline)))
+        {
+            len = strlen(CURVEline);
+            linePtr = line + len;
+#ifdef DEBUG
+            printf("CURVE = %s",linePtr);
+#endif
+        }
+        // Read MS1
+        if (!strncmp(line,MS1line, strlen(MS1line)))
+        {
+            len = strlen(MS1line);
+            linePtr = line + len;
+            read_OCTET(&MS1Golden,linePtr);
+#ifdef DEBUG
+            printf("MS1 = ");
+            OCT_output(&MS1Golden);
+#endif
+        }
+        // Read MS2
+        if (!strncmp(line,MS2line, strlen(MS2line)))
+        {
+            len = strlen(MS2line);
+            linePtr = line + len;
+            read_OCTET(&MS2Golden,linePtr);
+#ifdef DEBUG
+            printf("MS2 = ");
+            OCT_output(&MS2Golden);
+#endif
+        }
+        // Read SS1
+        if (!strncmp(line,SS1line, strlen(SS1line)))
+        {
+            len = strlen(SS1line);
+            linePtr = line + len;
+            read_OCTET(&SS1Golden,linePtr);
+#ifdef DEBUG
+            printf("SS1 = ");
+            OCT_output(&SS1Golden);
+#endif
+        }
+        // Read SS2
+        if (!strncmp(line,SS2line, strlen(SS2line)))
+        {
+            len = strlen(SS2line);
+            linePtr = line + len;
+            read_OCTET(&SS2Golden,linePtr);
+#ifdef DEBUG
+            printf("SS2 = ");
+            OCT_output(&SS2Golden);
+#endif
+        }
+        // Read SS
+        if (!strncmp(line,SSline, strlen(SSline)))
+        {
+            len = strlen(SSline);
+            linePtr = line + len;
+            read_OCTET(&SSGolden,linePtr);
+#ifdef DEBUG
+            printf("SS = ");
+            OCT_output(&SSGolden);
+#endif
+        }
+        // Read MPINId
+        if (!strncmp(line,MPINIdline, strlen(MPINIdline)))
+        {
+            len = strlen(MPINIdline);
+            linePtr = line + len;
+            read_OCTET(&MPINIdGolden,linePtr);
+#ifdef DEBUG
+            printf("MPINId = ");
+            OCT_output(&MPINIdGolden);
+#endif
+        }
+        // Read PIN1
+        if (!strncmp(line,PIN1line, strlen(PIN1line)))
+        {
+            len = strlen(PIN1line);
+            linePtr = line + len;
+            sscanf(linePtr,"%d\n",&PIN1);
+#ifdef DEBUG
+            printf("PIN1 = %d\n", PIN1);
+#endif
+        }
+        // Read PIN2
+        if (!strncmp(line,PIN2line, strlen(PIN2line)))
+        {
+            len = strlen(PIN2line);
+            linePtr = line + len;
+            sscanf(linePtr,"%d\n",&PIN2);
+#ifdef DEBUG
+            printf("PIN2 = %d\n", PIN2);
+#endif
+        }
+        // Read CS1
+        if (!strncmp(line,CS1line, strlen(CS1line)))
+        {
+            len = strlen(CS1line);
+            linePtr = line + len;
+            read_OCTET(&CS1Golden,linePtr);
+#ifdef DEBUG
+            printf("CS1 = ");
+            OCT_output(&CS1Golden);
+#endif
+        }
+        // Read CS2
+        if (!strncmp(line,CS2line, strlen(CS2line)))
+        {
+            len = strlen(CS2line);
+            linePtr = line + len;
+            read_OCTET(&CS2Golden,linePtr);
+#ifdef DEBUG
+            printf("CS2 = ");
+            OCT_output(&CS2Golden);
+#endif
+        }
+        // Read CS
+        if (!strncmp(line,CSline, strlen(CSline)))
+        {
+            len = strlen(CSline);
+            linePtr = line + len;
+            read_OCTET(&CSGolden,linePtr);
+#ifdef DEBUG
+            printf("CS = ");
+            OCT_output(&CSGolden);
+#endif
+        }
+        // Read TOKEN
+        if (!strncmp(line,TOKENline, strlen(TOKENline)))
+        {
+            len = strlen(TOKENline);
+            linePtr = line + len;
+            read_OCTET(&TOKENGolden,linePtr);
+#ifdef DEBUG
+            printf("TOKEN = ");
+            OCT_output(&TOKENGolden);
+#endif
+        }
+        // Read X
+        if (!strncmp(line,Xline, strlen(Xline)))
+        {
+            len = strlen(Xline);
+            linePtr = line + len;
+            read_OCTET(&XGolden,linePtr);
+#ifdef DEBUG
+            printf("X = ");
+            OCT_output(&XGolden);
+#endif
+        }
+        // Read U
+        if (!strncmp(line,Uline, strlen(Uline)))
+        {
+            len = strlen(Uline);
+            linePtr = line + len;
+            read_OCTET(&UGolden,linePtr);
+#ifdef DEBUG
+            printf("U = ");
+            OCT_output(&UGolden);
+#endif
+        }
+        // Read Y
+        if (!strncmp(line,Yline, strlen(Yline)))
+        {
+            len = strlen(Yline);
+            linePtr = line + len;
+            read_OCTET(&YGolden,linePtr);
+#ifdef DEBUG
+            printf("Y = ");
+            OCT_output(&YGolden);
+#endif
+        }
+        // Read V
+        if (!strncmp(line,Vline, strlen(Vline)))
+        {
+            len = strlen(Vline);
+            linePtr = line + len;
+            read_OCTET(&VGolden,linePtr);
+#ifdef DEBUG
+            printf("V = ");
+            OCT_output(&VGolden);
+#endif
+        }
+        // Read AuthResult
+        if (!strncmp(line,AuthResultline, strlen(AuthResultline)))
+        {
+            len = strlen(AuthResultline);
+            linePtr = line + len;
+            sscanf(linePtr,"%d\n",&AuthResultGolden);
+            applyVector=1;
+#ifdef DEBUG
+            printf("AuthResult = %d\n", AuthResultGolden);
+#endif
+        }
+
+        if (applyVector)
+        {
+            applyVector=0;
+
+            // DTA Issues Server secrets
+            errorCode = MPIN_ZZZ_GET_SERVER_SECRET(&MS1Golden,&SS1);
+            if (errorCode != 0)
+            {
+                printf("ERROR SS1 Test %d Error Code %d\n", testNo,errorCode);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&SS1Golden,&SS1))
+            {
+                printf("ERROR SS1 Test %d\n", testNo);
+                exit(EXIT_FAILURE);
+            }
+
+            errorCode = MPIN_ZZZ_GET_SERVER_SECRET(&MS2Golden,&SS2);
+            if (errorCode != 0)
+            {
+                printf("ERROR SS2 Test %d Error Code %d\n", testNo,errorCode);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&SS2Golden,&SS2))
+            {
+                printf("ERROR SS2 Test %d\n", testNo);
+                exit(EXIT_FAILURE);
+            }
+
+            errorCode = MPIN_ZZZ_RECOMBINE_G2(&SS1Golden, &SS2Golden, &SS);
+            if (errorCode != 0)
+            {
+                printf("ERROR SS Test %d Error Code %d\n", testNo,errorCode);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&SSGolden,&SS))
+            {
+                printf("ERROR SS Test %d\n", testNo);
+                exit(EXIT_FAILURE);
+            }
+
+            // DTA Issues Client secrets
+            HASH_ID(HASH_TYPE_ZZZ,&MPINIdGolden,&HiId);
+            errorCode = MPIN_ZZZ_GET_CLIENT_SECRET(&MS1Golden,&HiId,&CS1);
+            if (errorCode != 0)
+            {
+                printf("ERROR CS1 Test %d Error Code %d\n", testNo,errorCode);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&CS1Golden,&CS1))
+            {
+                printf("ERROR CS1 Test %d\n", testNo);
+                exit(EXIT_FAILURE);
+            }
+
+            errorCode = MPIN_ZZZ_GET_CLIENT_SECRET(&MS2Golden,&HiId,&CS2);
+            if (errorCode != 0)
+            {
+                printf("ERROR CS2 Test %d Error Code %d\n", testNo,errorCode);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&CS2Golden,&CS2))
+            {
+                printf("ERROR CS2 Test %d\n", testNo);
+                exit(EXIT_FAILURE);
+            }
+
+            errorCode = MPIN_ZZZ_RECOMBINE_G1(&CS1Golden, &CS2Golden, &TOKEN);
+            if (errorCode != 0)
+            {
+                printf("ERROR CS Test %d Error Code %d\n", testNo,errorCode);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&CSGolden,&TOKEN))
+            {
+                printf("ERROR CS Test %d\n", testNo);
+                exit(EXIT_FAILURE);
+            }
+
+            errorCode = MPIN_ZZZ_EXTRACT_PIN(HASH_TYPE_ZZZ,&MPINIdGolden,PIN1,&TOKEN);
+            if (errorCode != 0)
+            {
+                printf("ERROR TOKEN Test %d Error Code %d\n", testNo,errorCode);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&TOKENGolden,&TOKEN))
+            {
+                printf("ERROR TOKEN Test %d\n", testNo);
+                exit(EXIT_FAILURE);
+            }
+
+            // Client enters PIN to recreate client secret and generate commitment U
+            errorCode = MPIN_ZZZ_CLIENT_1(HASH_TYPE_ZZZ,date,&MPINIdGolden,RNG,&XGolden,PIN2,&TOKEN,&V,&U,pUT,pPERMIT);
+            if (errorCode != 0)
+            {
+                printf("ERROR CLIENT 1 Test %d Error Code %d\n", testNo,errorCode);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&UGolden,&U))
+            {
+                printf("ERROR U Test %d\n", testNo);
+                exit(EXIT_FAILURE);
+            }
+
+            // Server calculates sha256(ID) and maps this values to a point on the curve
+            MPIN_ZZZ_SERVER_1(HASH_TYPE_ZZZ,date,&MPINIdGolden,&HpId,pHTID);
+
+            // Client calculates V = -(x+y)*V
+            errorCode = MPIN_ZZZ_CLIENT_2(&XGolden,&YGolden,&V);
+            if (errorCode != 0)
+            {
+                printf("ERROR CLIENT 2 Test %d Error Code %d\n", testNo,errorCode);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&VGolden,&V))
+            {
+                printf("ERROR V Test %d\n", testNo);
+                exit(EXIT_FAILURE);
+            }
+
+            // Server authenticates clients based on V value
+            errorCode=MPIN_ZZZ_SERVER_2(date,&HpId,pHTID,&YGolden,&SSGolden,&UGolden,pUT,&VGolden,pE,pF,NULL);
+            if (errorCode != AuthResultGolden)
+            {
+                printf("ERROR SERVER 2 Test %d Error Code %d AuthResult %d\n", testNo,errorCode,AuthResultGolden);
+                exit(EXIT_FAILURE);
+            }
+        }
+    }
+    fclose(fp);
+    printf("SUCCESS TEST MPIN PASSED\n");
+    exit(EXIT_SUCCESS);
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_mpin_vectors_dta_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpin_vectors_dta_ZZZ.c.in b/test/test_mpin_vectors_dta_ZZZ.c.in
new file mode 100644
index 0000000..e288257
--- /dev/null
+++ b/test/test_mpin_vectors_dta_ZZZ.c.in
@@ -0,0 +1,505 @@
+/**
+ * @file test_mpin_vectors_ZZZ.c
+ * @author Alessandro Budroni
+ * @brief Test mpin with test vectors
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "config_curve_ZZZ.h"
+#include "pbc_support.h"
+#include "randapi.h"
+#include "utils.h"
+#if CURVE_SECURITY_ZZZ == 128
+#include "mpin_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "mpin192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "mpin256_ZZZ.h"
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*PFS_ZZZ
+#endif
+#define GTLEN 3*G2LEN
+
+#define LINE_LEN 1000
+
+void read_OCTET(octet* OCT, char* string)
+{
+    int len = strlen(string);
+    char buff[len];
+    strncpy(buff,string,len);
+    char *end = strchr(buff,',');
+    if (end == NULL)
+    {
+        printf("ERROR unexpected test vector %s\n",string);
+        exit(EXIT_FAILURE);
+    }
+    end[0] = '\0';
+    OCT_fromHex(OCT,buff);
+}
+
+int main(int argc, char** argv)
+{
+    if (argc != 2)
+    {
+        printf("usage: ./test_mpin_vectors_ZZZ [path to test vector file]\n");
+        exit(EXIT_FAILURE);
+    }
+
+    int i = 0, len = 0, rtn = 0;
+    FILE *fp;
+
+    char line[LINE_LEN];
+    char * linePtr = NULL;
+
+    char ms1[PFS_ZZZ];
+    octet MS1= {0,sizeof(ms1),ms1};
+    const char* MS1line = "MS1 = ";
+    char ms2[PFS_ZZZ];
+    octet MS2= {0,sizeof(ms2),ms2};
+    const char* MS2line = "MS2 = ";
+    char ss1[G2LEN], rtss1[G2LEN];
+    octet SS1= {0,sizeof(ss1),ss1}, rtSS1= {0,sizeof(rtss1),rtss1};
+    const char* SS1line = "SS1 = ";
+    char ss2[G2LEN], rtss2[G2LEN];
+    octet SS2= {0,sizeof(ss2),ss2}, rtSS2= {0,sizeof(rtss2),rtss2};
+    const char* SS2line = "SS2 = ";
+    int DATE = 0;
+    const char* DATEline = "DATE = ";
+    int PIN1 = 0;
+    const char* PIN1line = "PIN1 = ";
+    int PIN2 = 0;
+    const char* PIN2line = "PIN2 = ";
+    char server_secret[G2LEN], rt_server_secret[G2LEN];
+    octet SERVER_SECRET= {0,sizeof(server_secret),server_secret}, rtSERVER_SECRET= {0,sizeof(rt_server_secret),rt_server_secret};
+    const char* SERVER_SECRETline = "SERVER_SECRET = ";
+    char tp1[2*PFS_ZZZ+1], rttp1[2*PFS_ZZZ+1];
+    octet TP1= {0,sizeof(tp1),tp1}, rtTP1= {0,sizeof(rttp1),rttp1};
+    const char* TP1line = "TP1 = ";
+    char tp2[2*PFS_ZZZ+1], rttp2[2*PFS_ZZZ+1];
+    octet TP2= {0,sizeof(tp2),tp2}, rtTP2= {0,sizeof(rttp2),rttp2};
+    const char* TP2line = "TP2 = ";
+    char cs1[2*PFS_ZZZ+1], rtcs1[2*PFS_ZZZ+1];
+    octet CS1= {0,sizeof(cs1),cs1}, rtCS1= {0,sizeof(rtcs1),rtcs1};
+    const char* CS1line = "CS1 = ";
+    char cs2[2*PFS_ZZZ+1], rtcs2[2*PFS_ZZZ+1];
+    octet CS2= {0,sizeof(cs2),cs2}, rtCS2= {0,sizeof(rtcs2),rtcs2};
+    const char* CS2line = "CS2 = ";
+    char client_secret[2*PFS_ZZZ+1], rtclient_secret[2*PFS_ZZZ+1];
+    octet CLIENT_SECRET= {0,sizeof(client_secret),client_secret}, rtCLIENT_SECRET= {0,sizeof(rtclient_secret),rtclient_secret};
+    const char* CLIENT_SECRETline = "CLIENT_SECRET = ";
+    char hash_mpin_id_hex[PFS_ZZZ], rthash_mpin_id_hex[PFS_ZZZ];
+    octet HASH_MPIN_ID_HEX= {0,sizeof(hash_mpin_id_hex),hash_mpin_id_hex}, rtHASH_MPIN_ID_HEX= {0,sizeof(rthash_mpin_id_hex),rthash_mpin_id_hex};
+    const char* HASH_MPIN_ID_HEXline = "HASH_MPIN_ID_HEX = ";
+    char time_permit[2*PFS_ZZZ+1], rttime_permit[2*PFS_ZZZ+1];
+    octet TIME_PERMIT= {0,sizeof(time_permit),time_permit}, rtTIME_PERMIT= {0,sizeof(rttime_permit),rttime_permit};
+    const char* TIME_PERMITline = "TIME_PERMIT = ";
+    char mpin_id_hex[300+1];
+    octet MPIN_ID_HEX= {0,sizeof(mpin_id_hex),mpin_id_hex};
+    const char* MPIN_ID_HEXline = "MPIN_ID_HEX = ";
+    char token[2*PFS_ZZZ+1];
+    octet TOKEN= {0,sizeof(token),token};
+    const char* TOKENline = "TOKEN = ";
+    int SERVER_OUTPUT = 0;
+    const char* SERVER_OUTPUTline = "SERVER_OUTPUT = ";
+    char u[2*PFS_ZZZ+1], rtu[2*PFS_ZZZ+1];
+    octet U= {0,sizeof(u),u}, rtU= {0,sizeof(rtu),rtu};
+    const char* Uline = "U = ";
+    char v[2*PFS_ZZZ+1];
+    octet V= {0,sizeof(v),v};
+    const char* Vline = "V = ";
+    char y[PFS_ZZZ];
+    octet Y= {0,sizeof(y),y};
+    const char* Yline = "Y = ";
+    char x[PFS_ZZZ];
+    octet X= {0,sizeof(x),x};
+    const char* Xline = "X = ";
+    char ut[2*PFS_ZZZ+1], rtut[2*PFS_ZZZ+1];
+    octet UT= {0,sizeof(ut),ut}, rtUT= {0,sizeof(rtut),rtut};
+    const char* UTline = "UT = ";
+    char sec[2*PFS_ZZZ+1], rtsec[2*PFS_ZZZ+1];
+    octet SEC= {0,sizeof(sec),sec}, rtSEC= {0,sizeof(rtsec),rtsec};
+    const char* SECline = "SEC = ";
+    char hid[2*PFS_ZZZ+1], htid[2*PFS_ZZZ+1];
+    octet HID= {0,sizeof(hid), hid}, HTID= {0,sizeof(htid),htid};
+    char e[GTLEN];
+    octet E= {0,sizeof(e),e};
+    char f[GTLEN];
+    octet F= {0,sizeof(f),f};
+
+    fp = fopen(argv[1], "r");
+    if (fp == NULL)
+    {
+        printf("ERROR opening test vector file\n");
+        exit(EXIT_FAILURE);
+    }
+
+    while (fgets(line, LINE_LEN, fp) != NULL)
+    {
+        i++;
+// Read MS1
+        if (!strncmp(line,MS1line, strlen(MS1line)))
+        {
+            len = strlen(MS1line);
+            linePtr = line + len;
+            read_OCTET(&MS1,linePtr);
+        }
+// Read MS2
+        if (!strncmp(line,MS2line, strlen(MS2line)))
+        {
+            len = strlen(MS2line);
+            linePtr = line + len;
+            read_OCTET(&MS2,linePtr);
+        }
+// Read SS1
+        if (!strncmp(line,SS1line, strlen(SS1line)))
+        {
+            len = strlen(SS1line);
+            linePtr = line + len;
+            read_OCTET(&SS1,linePtr);
+// Generate first server secret shares
+            rtn = MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&rtSS1);
+            if (rtn != 0)
+            {
+                printf("ERROR MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&SS1), %d, line %d\n", rtn,i);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&rtSS1,&SS1))
+            {
+                printf("rtSS1: 0x");
+                OCT_output(&rtSS1);
+                printf("  SS1: 0x");
+                OCT_output(&SS1);
+                printf("ERROR generating server secret, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+// Read SS2
+        if (!strncmp(line,SS2line, strlen(SS2line)))
+        {
+            len = strlen(SS2line);
+            linePtr = line + len;
+            read_OCTET(&SS2,linePtr);
+// Generate second server secret shares
+            rtn = MPIN_ZZZ_GET_SERVER_SECRET(&MS2,&rtSS2);
+            if (rtn != 0)
+            {
+                printf("ERROR MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&SS2), %d, line %d\n", rtn,i);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&rtSS2,&SS2))
+            {
+                printf("ERROR generating server secret, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+// Read SERVER_SECRET
+        if (!strncmp(line,SERVER_SECRETline, strlen(SERVER_SECRETline)))
+        {
+            len = strlen(SERVER_SECRETline);
+            linePtr = line + len;
+            read_OCTET(&SERVER_SECRET,linePtr);
+// Recombine server secret
+            rtn = MPIN_ZZZ_RECOMBINE_G2(&SS1, &SS2, &rtSERVER_SECRET);
+            if (rtn != 0)
+            {
+                printf("MPIN_ZZZ_RECOMBINE_G2(&SS1, &SS2, &SERVER_SECRET) Error %d, line %d\n", rtn,i);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&SERVER_SECRET,&rtSERVER_SECRET))
+            {
+                printf("ERROR recombining server secret, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+// Read MPIN_ID_HEX
+        if (!strncmp(line,MPIN_ID_HEXline, strlen(MPIN_ID_HEXline)))
+        {
+            len = strlen(MPIN_ID_HEXline);
+            linePtr = line + len;
+            read_OCTET(&MPIN_ID_HEX,linePtr);
+        }
+// Read HASH_MPIN_ID_HEX
+        if (!strncmp(line,HASH_MPIN_ID_HEXline, strlen(HASH_MPIN_ID_HEXline)))
+        {
+            len = strlen(HASH_MPIN_ID_HEXline);
+            linePtr = line + len;
+            read_OCTET(&HASH_MPIN_ID_HEX,linePtr);
+// Hash MPIN_ID
+            HASH_ID(HASH_TYPE_ZZZ,&MPIN_ID_HEX,&rtHASH_MPIN_ID_HEX);
+            if (!OCT_comp(&HASH_MPIN_ID_HEX,&rtHASH_MPIN_ID_HEX))
+            {
+                printf("ERROR hashing identity, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+// Read CS1
+        if (!strncmp(line,CS1line, strlen(CS1line)))
+        {
+            len = strlen(CS1line);
+            linePtr = line + len;
+            read_OCTET(&CS1,linePtr);
+// Generate first client secret shares
+            rtn = MPIN_ZZZ_GET_CLIENT_SECRET(&MS1,&HASH_MPIN_ID_HEX,&rtCS1);
+            if (rtn != 0)
+            {
+                printf("MPIN_ZZZ_GET_CLIENT_SECRET(&MS1,&HASH_MPIN_ID_HEX,&CS1) Error %d, line %d\n", rtn,i);
+                exit(EXIT_FAILURE);
+            }
+            if (!OCT_comp(&CS1,&rtCS1))
+            {
+                printf("ERROR generating client share, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+// Read CS2
+        if (!strncmp(line,CS2line, strlen(CS2line)))
+        {
+            len = strlen(CS2line);
+            linePtr = line + len;
+            read_OCTET(&CS2,linePtr);
+// Generate second client secret shares
+            rtn = MPIN_ZZZ_GET_CLIENT_SECRET(&MS2,&HASH_MPIN_ID_HEX,&rtCS2);
+            if (rtn != 0)
+            {
+                printf("MPIN_ZZZ_GET_CLIENT_SECRET(&MS2,&HASH_MPIN_ID_HEX,&CS1) Error %d, line %d\n", rtn,i);
+                exit(EXIT_FAILURE);
+            }
+            if (!OCT_comp(&CS2,&rtCS2))
+            {
+                printf("ERROR generating client share, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+// Read CLIENT_SECRET
+        if (!strncmp(line,CLIENT_SECRETline, strlen(CLIENT_SECRETline)))
+        {
+            len = strlen(CLIENT_SECRETline);
+            linePtr = line + len;
+            read_OCTET(&CLIENT_SECRET,linePtr);
+// Combine client secret shares : TOKEN is the full client secret
+            rtn = MPIN_ZZZ_RECOMBINE_G1(&CS1, &CS2, &rtCLIENT_SECRET);
+            if (rtn != 0)
+            {
+                printf("MPIN_ZZZ_RECOMBINE_G1(&CS1, &CS2, &rtCLIENT_SECRET) Error %d, line %d\n",rtn,i);
+                exit(EXIT_FAILURE);
+            }
+            if (!OCT_comp(&CLIENT_SECRET,&rtCLIENT_SECRET))
+            {
+                printf("ERROR generating CLIENT_SECRET, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+// Read DATE
+        if (!strncmp(line,DATEline, strlen(DATEline)))
+        {
+            len = strlen(DATEline);
+            linePtr = line + len;
+            sscanf(linePtr,"%d\n",&DATE);
+        }
+// Read PIN1
+        if (!strncmp(line,PIN1line, strlen(PIN1line)))
+        {
+            len = strlen(PIN1line);
+            linePtr = line + len;
+            sscanf(linePtr,"%d\n",&PIN1);
+        }
+// Read PIN2
+        if (!strncmp(line,PIN2line, strlen(PIN2line)))
+        {
+            len = strlen(PIN2line);
+            linePtr = line + len;
+            sscanf(linePtr,"%d\n",&PIN2);
+        }
+// Read TP1
+        if (!strncmp(line,TP1line, strlen(TP1line)))
+        {
+            len = strlen(TP1line);
+            linePtr = line + len;
+            read_OCTET(&TP1,linePtr);
+// Generate first Time Permit
+            rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,DATE,&MS1,&HASH_MPIN_ID_HEX,&rtTP1);
+            if (rtn != 0)
+            {
+                printf("MPIN_ZZZ_GET_CLIENT_PERMIT((HASH_TYPE_ZZZ,DATE,&MS1,&HASH_MPIN_ID_HEX,&TP1) Error %d, line %d\n",rtn,i);
+                exit(EXIT_FAILURE);
+            }
+            if (!OCT_comp(&TP1,&rtTP1))
+            {
+                printf("ERROR generating TIME PERMIT, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+// Read TP2
+        if (!strncmp(line,TP2line, strlen(TP2line)))
+        {
+            len = strlen(TP2line);
+            linePtr = line + len;
+            read_OCTET(&TP2,linePtr);
+// Generate second Time Permit
+            rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,DATE,&MS2,&HASH_MPIN_ID_HEX,&rtTP2);
+            if (rtn != 0)
+            {
+                printf("MPIN_ZZZ_GET_CLIENT_PERMIT((HASH_TYPE_ZZZ,DATE,&MS1,&HASH_MPIN_ID_HEX,&TP2) Error %d, line %d\n",rtn,i);
+                exit(EXIT_FAILURE);
+            }
+            if (!OCT_comp(&TP2,&rtTP2))
+            {
+                printf("ERROR generating TIME PERMIT, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+// Read TIME_PERMIT
+        if (!strncmp(line,TIME_PERMITline, strlen(TIME_PERMITline)))
+        {
+            len = strlen(TIME_PERMITline);
+            linePtr = line + len;
+            read_OCTET(&TIME_PERMIT,linePtr);
+// Combine Time Permits
+            rtn = MPIN_ZZZ_RECOMBINE_G1(&TP1, &TP2, &rtTIME_PERMIT);
+            if (rtn != 0)
+            {
+                printf("MPIN_ZZZ_RECOMBINE_G1(&TP1, &TP2, &rtTIME_PERMIT) Error %d, line %d\n",rtn,i);
+                exit(EXIT_FAILURE);
+            }
+            if (!OCT_comp(&TIME_PERMIT,&rtTIME_PERMIT))
+            {
+                printf("ERROR combining TIME PERMITs, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+// Read TOKEN
+        if (!strncmp(line,TOKENline, strlen(TOKENline)))
+        {
+            len = strlen(TOKENline);
+            linePtr = line + len;
+            read_OCTET(&TOKEN,linePtr);
+// Client extracts PIN1 from secret to create Token
+            rtn = MPIN_ZZZ_EXTRACT_PIN(HASH_TYPE_ZZZ,&MPIN_ID_HEX, PIN1, &rtCLIENT_SECRET);
+            if (rtn != 0)
+            {
+                printf("MPIN_ZZZ_EXTRACT_PIN( &ID, PIN, &TOKEN) Error %d, line %d\n",rtn,i);
+                exit(EXIT_FAILURE);
+            }
+            if (!OCT_comp(&TOKEN,&rtCLIENT_SECRET))
+            {
+                printf("ERROR extracting PIN from CLIENT SECRET, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+// Read X
+        if (!strncmp(line,Xline, strlen(Xline)))
+        {
+            len = strlen(Xline);
+            linePtr = line + len;
+            read_OCTET(&X,linePtr);
+        }
+// Read U
+        if (!strncmp(line,Uline, strlen(Uline)))
+        {
+            len = strlen(Uline);
+            linePtr = line + len;
+            read_OCTET(&U,linePtr);
+        }
+// Read UT
+        if (!strncmp(line,UTline, strlen(UTline)))
+        {
+            len = strlen(UTline);
+            linePtr = line + len;
+            read_OCTET(&UT,linePtr);
+        }
+// Read SEC
+        if (!strncmp(line,SECline, strlen(SECline)))
+        {
+            len = strlen(SECline);
+            linePtr = line + len;
+            read_OCTET(&SEC,linePtr);
+// Client first pass
+            rtn = MPIN_ZZZ_CLIENT_1(HASH_TYPE_ZZZ,DATE,&MPIN_ID_HEX,NULL,&X,PIN2,&TOKEN,&rtSEC,&rtU,&rtUT,&TIME_PERMIT);
+            if (rtn != 0)
+            {
+                printf("MPIN_ZZZ_CLIENT_1 ERROR %d, line %d\n",rtn,i);
+                exit(EXIT_FAILURE);
+            }
+            else if (!OCT_comp(&U,&rtU) || !OCT_comp(&UT,&rtUT) || !OCT_comp(&SEC,&rtSEC))
+            {
+                printf("ERROR performing CLIENT FIRST PASS, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+// Read V
+        if (!strncmp(line,Vline, strlen(Vline)))
+        {
+            len = strlen(Vline);
+            linePtr = line + len;
+            read_OCTET(&V,linePtr);
+        }
+// Read Y
+        if (!strncmp(line,Yline, strlen(Yline)))
+        {
+            len = strlen(Yline);
+            linePtr = line + len;
+            read_OCTET(&Y,linePtr);
+        }
+// Read SERVER_OUTPUT
+        if (!strncmp(line,SERVER_OUTPUTline, strlen(SERVER_OUTPUTline)))
+        {
+            len = strlen(SERVER_OUTPUTline);
+            linePtr = line + len;
+            sscanf(linePtr,"%d\n",&SERVER_OUTPUT);
+// Server calculates H(ID) and H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp.
+
+            MPIN_ZZZ_SERVER_1(HASH_TYPE_ZZZ,DATE,&MPIN_ID_HEX,&HID,&HTID);
+// Client second pass
+            rtn = MPIN_ZZZ_CLIENT_2(&X,&Y,&rtSEC);
+            if (rtn != 0)
+            {
+                printf("MPIN_ZZZ_CLIENT_2(&X,&Y,&SEC) Error %d, line %d\n",rtn,i);
+                exit(EXIT_FAILURE);
+            }
+            if (!OCT_comp(&V,&rtSEC))
+            {
+                printf("ERROR performing CLIENT SECOND PASS, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+// Server second pass
+            rtn = MPIN_ZZZ_SERVER_2(DATE,&HID,&HTID,&Y,&SERVER_SECRET,&U,&UT,&V,&E,&F,NULL);
+
+            if (rtn != SERVER_OUTPUT)
+            {
+                printf("ERROR performing SERVER SECOND PASS, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+    }
+    fclose(fp);
+    printf("SUCCESS TEST MPIN PASSED\n");
+    exit(EXIT_SUCCESS);
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_mpinfull_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpinfull_ZZZ.c.in b/test/test_mpinfull_ZZZ.c.in
new file mode 100644
index 0000000..23c5ca0
--- /dev/null
+++ b/test/test_mpinfull_ZZZ.c.in
@@ -0,0 +1,355 @@
+/**
+ * @file test_mpinfull_ZZZ.c
+ * @author Kealan McCusker
+ * @brief Test M-pin Full
+ *
+ * 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 M-Pin Full */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "config_curve_ZZZ.h"
+#include "pbc_support.h"
+#include "randapi.h"
+#if CURVE_SECURITY_ZZZ == 128
+#include "mpin_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "mpin192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "mpin256_ZZZ.h"
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*PFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*PFS_ZZZ
+#endif
+#define GTLEN 3*G2LEN
+
+// #define DEBUG
+
+int main(int argc, char** argv)
+{
+    if (argc != 2)
+    {
+        printf("usage: ./test_mpinfull_ZZZ [hash:sha256||sha384||sha512]\n");
+        exit(EXIT_FAILURE);
+    }
+
+    int i,PIN1,PIN2,rtn;
+
+    char id[256];
+    octet ID = {0,sizeof(id),id};
+
+    char x[PGS_ZZZ],y[PGS_ZZZ];
+    octet X= {0,sizeof(x),x};
+    octet Y= {0,sizeof(y),y};
+
+    /* Master secret shares */
+    char ms1[PGS_ZZZ], ms2[PGS_ZZZ];
+    octet MS1= {0,sizeof(ms1),ms1};
+    octet MS2= {0,sizeof(ms2),ms2};
+
+    /* Hash values of client ID */
+    char hcid[PFS_ZZZ];
+    octet HCID= {0,sizeof(hcid), hcid};
+
+    /* Hash values of messages */
+    char hm[PFS_ZZZ];
+    octet HM= {0,sizeof(hm), hm};
+
+    /* Client secret and shares */
+    char cs1[2*PFS_ZZZ+1], cs2[2*PFS_ZZZ+1], sec[2*PFS_ZZZ+1];
+    octet SEC= {0,sizeof(sec),sec};
+    octet CS1= {0,sizeof(cs1), cs1};
+    octet CS2= {0,sizeof(cs2), cs2};
+
+    /* Server secret and shares */
+    char ss1[G2LEN], ss2[G2LEN], serverSecret[G2LEN];
+    octet ServerSecret= {0,sizeof(serverSecret),serverSecret};
+    octet SS1= {0,sizeof(ss1),ss1};
+    octet SS2= {0,sizeof(ss2),ss2};
+
+    /* Token stored on device */
+    char token[2*PFS_ZZZ+1];
+    octet TOKEN= {0,sizeof(token),token};
+
+    /* Precomputed values stored on device */
+    char g1[GTLEN],g2[GTLEN];
+    octet G1= {0,sizeof(g1),g1};
+    octet G2= {0,sizeof(g2),g2};
+
+    char u[2*PFS_ZZZ+1];
+    octet U= {0,sizeof(u),u};
+
+    char hid[2*PFS_ZZZ+1];
+    octet HID= {0,sizeof(hid),hid};
+
+    char e[GTLEN], f[GTLEN];
+    octet E= {0,sizeof(e),e};
+    octet F= {0,sizeof(f),f};
+
+    char r[PGS_ZZZ],z[2*PFS_ZZZ+1],w[PGS_ZZZ],t[2*PFS_ZZZ+1];
+
+    char ck[AESKEY_ZZZ],sk[AESKEY_ZZZ];
+    octet R= {0,sizeof(r),r};
+    octet Z= {0,sizeof(z),z};
+    octet W= {0,sizeof(w),w};
+    octet T= {0,sizeof(t),t};
+    octet SK= {0,sizeof(sk),sk};
+    octet CK= {0,sizeof(ck),ck};
+
+    /* AES-GCM */
+    char raw[256], header[16], ciphertext[32], res[32], plaintext[32], tag[16], iv[16];
+    octet HEADER= {0,0,header}, Ciphertext= {0,sizeof(ciphertext),ciphertext};
+    octet Plaintext= {0,sizeof(plaintext),plaintext}, Res= {0,sizeof(res),res}, Tag= {0,sizeof(tag),tag}, IV= {0,sizeof(iv),iv};
+    csprng rng;
+
+    int hash;
+    if (!strcmp(argv[1], "sha256"))
+    {
+        hash = SHA256;
+    }
+    else if (!strcmp(argv[1], "sha384"))
+    {
+        hash = SHA384;
+    }
+    else
+    {
+        hash = SHA512;
+    }
+
+    /* Fake random source */
+    RAND_clean(&rng);
+    for (i=0; i<256; i++) raw[i]=(char)i;
+    RAND_seed(&rng,256,raw);
+
+    PIN1 = 1234;
+    PIN2 = 1234;
+
+    /* Assign the End-User an ID */
+    char* user = "testuser@miracl.com";
+    OCT_jstring(&ID,user);
+    printf("CLIENT: ID %s\n", user);
+
+    int date = 0;
+    char seed[100] = {0};
+    octet SEED = {0,sizeof(seed),seed};
+    csprng RNG;
+
+    /* unrandom seed value! */
+    SEED.len=100;
+    for (i=0; i<100; i++) SEED.val[i]=i+1;
+
+    /* initialise random number generator */
+    CREATE_CSPRNG(&RNG,&SEED);
+
+    /* Hash ID */
+    HASH_ID(hash,&ID,&HCID);
+    OCT_output(&HCID);
+
+    /* Generate Client master secret for MIRACL and Customer */
+    rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&MS2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("MASTER SECRET MIRACL:= 0x");
+    OCT_output(&MS1);
+    printf("MASTER SECRET CUSTOMER:= 0x");
+    OCT_output(&MS2);
+
+    /* Generate server secret shares */
+    rtn = MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&SS1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_SERVER_SECRET(&MS1,&SS1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_GET_SERVER_SECRET(&MS2,&SS2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_SERVER_SECRET(&MS2,&SS2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("SS1 = 0x");
+    OCT_output(&SS1);
+    printf("SS2 = 0x");
+    OCT_output(&SS2);
+
+    /* Combine server secret share */
+    rtn = MPIN_ZZZ_RECOMBINE_G2(&SS1, &SS2, &ServerSecret);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RECOMBINE_G2(&SS1, &SS2, &ServerSecret) Error %d\n", rtn);
+        return 1;
+    }
+    printf("ServerSecret = 0x");
+    OCT_output(&ServerSecret);
+
+    /* Generate client secret shares */
+    rtn = MPIN_ZZZ_GET_CLIENT_SECRET(&MS1,&HCID,&CS1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_SECRET(&MS1,&HCID,&CS1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_GET_CLIENT_SECRET(&MS2,&HCID,&CS2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_SECRET(&MS2,&HCID,&CS2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("CS1 = 0x");
+    OCT_output(&CS1);
+    printf("CS2 = 0x");
+    OCT_output(&CS2);
+
+    /* Combine client secret shares : TOKEN is the full client secret */
+    rtn = MPIN_ZZZ_RECOMBINE_G1(&CS1, &CS2, &TOKEN);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RECOMBINE_G1(&CS1, &CS2, &TOKEN) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Client Secret = 0x");
+    OCT_output(&TOKEN);
+
+    /* Client extracts PIN1 from secret to create Token */
+    rtn = MPIN_ZZZ_EXTRACT_PIN(hash,&ID, PIN1, &TOKEN);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_EXTRACT_PIN( &ID, PIN, &TOKEN) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Token = 0x");
+    OCT_output(&TOKEN);
+
+    /* Client precomputation */
+    MPIN_ZZZ_PRECOMPUTE(&TOKEN,&HCID,NULL,&G1,&G2);
+
+    /* Client first pass */
+    rtn = MPIN_ZZZ_CLIENT_1(hash,date,&ID,&RNG,&X,PIN2,&TOKEN,&SEC,&U,NULL,NULL);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_CLIENT_1 ERROR %d\n", rtn);
+        return 1;
+    }
+
+    /* Client sends Z=r.ID to Server */
+    MPIN_ZZZ_GET_G1_MULTIPLE(&RNG,1,&R,&HCID,&Z);
+
+    /* Server calculates H(ID) and maps them to points on the curve HID. */
+    MPIN_ZZZ_SERVER_1(hash,date,&ID,&HID,NULL);
+
+    /* Server generates Random number Y and sends it to Client */
+    rtn = MPIN_ZZZ_RANDOM_GENERATE(&RNG,&Y);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_RANDOM_GENERATE(&RNG,&Y) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Y = 0x");
+    OCT_output(&Y);
+
+    /* Server sends T=w.ID to client */
+    MPIN_ZZZ_GET_G1_MULTIPLE(&RNG,0,&W,&HID,&T);
+    printf("T = 0x");
+    OCT_output(&T);
+
+    /* Client second pass */
+    rtn = MPIN_ZZZ_CLIENT_2(&X,&Y,&SEC);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_CLIENT_2(&X,&Y,&SEC) Error %d\n", rtn);
+    }
+    printf("V = 0x");
+    OCT_output(&SEC);
+
+    printf("date: %d\n",date);
+
+    /* Server second pass */
+    rtn = MPIN_ZZZ_SERVER_2(date,&HID,NULL,&Y,&ServerSecret,&U,NULL,&SEC,&E,&F,NULL);
+
+    if (rtn != 0)
+    {
+        printf("FAILURE Invalid Token Error Code %d\n", rtn);
+    }
+
+    HASH_ALL(hash,&HCID,&U,NULL,&SEC,&Y,&Z,&T,&HM);
+    MPIN_ZZZ_CLIENT_KEY(hash,&G1,&G2,PIN2,&R,&X,&HM,&T,&CK);
+    printf("Client Key = ");
+    OCT_output(&CK);
+
+    /* Server will use the hashed ID if anonymous connection required.
+    HASH_ID(hash,&ID,&HSID);
+    HASH_ALL(&HSID,&U,NULL,&SEC,&Y,&Z,&T,&HM);
+    */
+    MPIN_ZZZ_SERVER_KEY(hash,&Z,&ServerSecret,&W,&HM,&HID,&U,NULL,&SK);
+    printf("Server Key = ");
+    OCT_output(&SK);
+
+    if (!OCT_comp(&CK,&SK))
+    {
+        printf("FAILURE Keys are different\n");
+        return 1;
+    }
+
+    for (i=0; i<10; i++)
+    {
+        /* Self test AES-GCM encyption/decryption */
+        OCT_rand(&IV,&rng,16);
+        OCT_rand(&Plaintext,&rng,32);
+        OCT_copy(&Res,&Plaintext);
+#ifdef DEBUG
+        printf("Plaintext = ");
+        OCT_output(&Plaintext);
+        printf("IV = ");
+        OCT_output(&IV);
+#endif
+        AES_GCM_ENCRYPT(&CK,&IV,&HEADER,&Plaintext,&Ciphertext,&Tag);
+        AES_GCM_DECRYPT(&CK,&IV,&HEADER,&Ciphertext,&Plaintext,&Tag);
+#ifdef DEBUG
+        printf("Ciphertext = ");
+        OCT_output(&Ciphertext);
+#endif
+
+        if (!OCT_comp(&Res,&Plaintext))
+        {
+            printf("FAILURE Encryption/Decryption with AES-GCM\n");
+            return 1;
+        }
+    }
+
+    printf("SUCCESS\n");
+    return 0;
+}