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

[27/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_fp_arithmetics_YYY.c.in
----------------------------------------------------------------------
diff --git a/test/test_fp_arithmetics_YYY.c.in b/test/test_fp_arithmetics_YYY.c.in
new file mode 100644
index 0000000..c541fc3
--- /dev/null
+++ b/test/test_fp_arithmetics_YYY.c.in
@@ -0,0 +1,376 @@
+/**
+ * @file test_fp_arithmetics_YYY.c
+ * @author Alessandro Budroni
+ * @brief Test for aritmetics with FP_YYY
+ *
+ * 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 <string.h>
+#include <stdlib.h>
+#include "arch.h"
+#include "amcl.h"
+#include "utils.h"
+#include "fp_YYY.h"
+
+#define LINE_LEN 10000
+#define MAX_STRING 300
+
+void read_FP_YYY(FP_YYY *R, char* string)
+{
+    int len;
+    char support[LINE_LEN];
+    BIG_XXX A;
+    BIG_XXX_zero(A);
+    len = strlen(string)+1;
+    amcl_hex2bin(string,support,len);
+    len = (len-1)/2;;
+    BIG_XXX_fromBytesLen(A,support,len);
+    BIG_XXX_norm(A);
+    FP_YYY_nres(R,A);
+}
+
+int main(int argc, char** argv)
+{
+    if (argc != 2)
+    {
+        printf("usage: ./test_fp_arithmetics_YYY [path to test vector file]\n");
+        exit(EXIT_FAILURE);
+    }
+
+    int i = 0, len = 0, j = 0, k = 0;
+    FILE *fp;
+
+    char line[LINE_LEN];
+    char * linePtr = NULL;
+
+    BIG_XXX bigsupp;
+    FP_YYY supp, supp1, supp2, supp3;
+
+    FP_YYY FP_1;
+    const char* FP_1line = "FP_1 = ";
+    FP_YYY FP_2;
+    const char* FP_2line = "FP_2 = ";
+    FP_YYY FPadd;
+    const char* FPaddline = "FPadd = ";
+    FP_YYY FPsub;
+    const char* FPsubline = "FPsub = ";
+    FP_YYY FP_1nres;
+    const char* FP_1nresline = "FP_1nres = ";
+    FP_YYY FP_2nres;
+    const char* FP_2nresline = "FP_2nres = ";
+    FP_YYY FPmulmod;
+    const char* FPmulmodline = "FPmulmod = ";
+    FP_YYY FPsmallmul;
+    const char* FPsmallmulline = "FPsmallmul = ";
+    FP_YYY FPsqr;
+    const char* FPsqrline = "FPsqr = ";
+    FP_YYY FPreduce;
+    const char* FPreduceline = "FPreduce = ";
+    FP_YYY FPneg;
+    const char* FPnegline = "FPneg = ";
+    FP_YYY FPdiv2;
+    const char* FPdiv2line = "FPdiv2 = ";
+    FP_YYY FPinv;
+    const char* FPinvline = "FPinv = ";
+    FP_YYY FPexp;
+    const char* FPexpline = "FPexp = ";
+
+    // Set to zero
+    FP_YYY_zero(&FP_1);
+    FP_YYY_zero(&FP_2);
+
+    // Testing equal function and set zero function
+    if(!FP_YYY_equals(&FP_1,&FP_2) || !FP_YYY_iszilch(&FP_1) || !FP_YYY_iszilch(&FP_2))
+    {
+        printf("ERROR comparing FPs or setting FP to zero\n");
+        exit(EXIT_FAILURE);
+    }
+
+    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 first FP_YYY
+        if (!strncmp(line,FP_1line, strlen(FP_1line)))
+        {
+            len = strlen(FP_1line);
+            linePtr = line + len;
+            read_FP_YYY(&FP_1,linePtr);
+        }
+        // Read second FP
+        if (!strncmp(line,FP_2line, strlen(FP_2line)))
+        {
+            len = strlen(FP_2line);
+            linePtr = line + len;
+            read_FP_YYY(&FP_2,linePtr);
+        }
+        // Addition test
+        if (!strncmp(line,FPaddline, strlen(FPaddline)))
+        {
+            len = strlen(FPaddline);
+            linePtr = line + len;
+            read_FP_YYY(&FPadd,linePtr);
+            FP_YYY_copy(&supp1,&FP_2);
+            FP_YYY_copy(&supp,&FP_1);
+            FP_YYY_copy(&supp2,&FP_1);
+            FP_YYY_add(&supp,&supp,&supp1);
+            FP_YYY_add(&supp2,&supp2,&supp1); // test commutativity P+Q = Q+P
+            FP_YYY_reduce(&supp);
+            FP_YYY_reduce(&supp2);
+            if(!FP_YYY_equals(&supp,&FPadd) || !FP_YYY_equals(&supp2,&FPadd))
+            {
+                printf("ERROR adding two FPs, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+            FP_YYY_copy(&supp,&FP_1); // test associativity (P+Q)+R = P+(Q+R)
+            FP_YYY_copy(&supp2,&FP_1);
+            FP_YYY_copy(&supp1,&FP_2);
+            FP_YYY_copy(&supp3,&FPadd);
+            FP_YYY_add(&supp,&supp,&supp1);
+            FP_YYY_add(&supp,&supp,&supp3);
+            FP_YYY_add(&supp1,&supp1,&supp3);
+            FP_YYY_add(&supp1,&supp1,&supp2);
+            FP_YYY_reduce(&supp);
+            FP_YYY_reduce(&supp1);
+            if(!FP_YYY_equals(&supp,&supp1))
+            {
+                printf("ERROR testing associativity between three FPs, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+        // Subtraction test
+        if (!strncmp(line,FPsubline, strlen(FPsubline)))
+        {
+            len = strlen(FPsubline);
+            linePtr = line + len;
+            read_FP_YYY(&FPsub,linePtr);
+            FP_YYY_copy(&supp,&FP_1);
+            FP_YYY_copy(&supp1,&FP_2);
+            FP_YYY_sub(&supp,&supp,&supp1);
+            FP_YYY_reduce(&supp);
+            if(!FP_YYY_equals(&supp,&FPsub))
+            {
+                printf("ERROR subtraction between two FPs, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+        // Reduce first FP
+        if (!strncmp(line,FP_1nresline, strlen(FP_1nresline)))
+        {
+            len = strlen(FP_1nresline);
+            linePtr = line + len;
+            read_FP_YYY(&FP_1nres,linePtr);
+            FP_YYY_copy(&supp,&FP_1);
+            if(!FP_YYY_equals(&supp,&FP_1nres))
+            {
+                printf("ERROR Converts from BIG_XXX integer to n-residue form, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+        // Reduce second FP
+        if (!strncmp(line,FP_2nresline, strlen(FP_2nresline)))
+        {
+            len = strlen(FP_2nresline);
+            linePtr = line + len;
+            read_FP_YYY(&FP_2nres,linePtr);
+            FP_YYY_copy(&supp,&FP_2);
+            if(!FP_YYY_equals(&supp,&FP_2nres))
+            {
+                printf("ERROR Converts from BIG_XXX integer to n-residue form, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+        // Multiplication modulo
+        if (!strncmp(line,FPmulmodline, strlen(FPmulmodline)))
+        {
+            len = strlen(FPmulmodline);
+            linePtr = line + len;
+            read_FP_YYY(&FPmulmod,linePtr);
+            FP_YYY_copy(&supp,&FP_1);
+            FP_YYY_copy(&supp1,&FP_2);
+            FP_YYY_reduce(&supp1);
+            FP_YYY_reduce(&supp);
+            FP_YYY_mul(&supp,&supp,&supp1);
+            FP_YYY_reduce(&supp);
+            if(!FP_YYY_equals(&supp,&FPmulmod))
+            {
+                printf("ERROR in multiplication and reduction by Modulo, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+        // Small multiplication
+        if (!strncmp(line,FPsmallmulline, strlen(FPsmallmulline)))
+        {
+            len = strlen(FPsmallmulline);
+            linePtr = line + len;
+            read_FP_YYY(&FPsmallmul,linePtr);
+            FP_YYY_imul(&supp,&FP_1,0);
+            FP_YYY_norm(&supp);
+            if (!FP_YYY_iszilch(&supp))
+            {
+                printf("ERROR in  multiplication by 0, line %d\n",i);
+            }
+            for (j = 1; j <= 10; ++j)
+            {
+                FP_YYY_imul(&supp,&FP_1,j);
+                FP_YYY_copy(&supp1,&FP_1);
+                for (k = 1; k < j; ++k)
+                {
+                    FP_YYY_norm(&supp1);
+                    FP_YYY_add(&supp1,&supp1,&FP_1);
+                }
+                FP_YYY_norm(&supp1);
+                if(!FP_YYY_equals(&supp,&supp1))
+                {
+                    printf("ERROR in small multiplication or addition, line %d, multiplier %d\n",i,j);
+                    exit(EXIT_FAILURE);
+                }
+            }
+            FP_YYY_reduce(&supp);
+            FP_YYY_reduce(&supp1);
+            if(!FP_YYY_equals(&supp,&FPsmallmul) | !FP_YYY_equals(&supp1,&supp))
+            {
+                printf("ERROR in small multiplication, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+        // Square and square root
+        if (!strncmp(line,FPsqrline, strlen(FPsqrline)))
+        {
+            len = strlen(FPsqrline);
+            linePtr = line + len;
+            read_FP_YYY(&FPsqr,linePtr);
+            FP_YYY_copy(&supp,&FP_1);
+            FP_YYY_sqr(&supp,&supp);
+            FP_YYY_reduce(&supp);
+            if(!FP_YYY_equals(&supp,&FPsqr))
+            {
+                printf("ERROR in squaring FP, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+            FP_YYY_sqrt(&supp,&supp);
+            FP_YYY_neg(&supp1,&supp);
+            if(!(FP_YYY_equals(&supp,&FP_1) || FP_YYY_equals(&supp1,&FP_1)))
+            {
+                printf("ERROR square/square root consistency FP, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+        // Reducing Modulo
+        if (!strncmp(line,FPreduceline, strlen(FPreduceline)))
+        {
+            len = strlen(FPreduceline);
+            linePtr = line + len;
+            read_FP_YYY(&FPreduce,linePtr);
+            FP_YYY_copy(&supp,&FP_1);
+            FP_YYY_reduce(&supp);
+            if(!FP_YYY_equals(&supp,&FPreduce))
+            {
+                printf("ERROR in reducing FP, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+        // Negative an FP
+        if (!strncmp(line,FPnegline, strlen(FPnegline)))
+        {
+            len = strlen(FPnegline);
+            linePtr = line + len;
+            read_FP_YYY(&FPneg,linePtr);
+            FP_YYY_copy(&supp,&FP_1);
+            FP_YYY_neg(&supp,&supp);
+            FP_YYY_reduce(&supp);
+            FP_YYY_norm(&supp);
+            if(!FP_YYY_equals(&supp,&FPneg))
+            {
+                printf("ERROR in computing FP_neg, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+        // Division by 2
+        if (!strncmp(line,FPdiv2line, strlen(FPdiv2line)))
+        {
+            len = strlen(FPdiv2line);
+            linePtr = line + len;
+            read_FP_YYY(&FPdiv2,linePtr);
+            FP_YYY_copy(&supp,&FP_1);
+            FP_YYY_div2(&supp,&supp);
+            if(!FP_YYY_equals(&supp,&FPdiv2))
+            {
+                printf("ERROR in division by 2, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+        // Inverse Modulo and FP_one
+        if (!strncmp(line,FPinvline, strlen(FPinvline)))
+        {
+            len = strlen(FPinvline);
+            linePtr = line + len;
+            read_FP_YYY(&FPinv,linePtr);
+            FP_YYY_copy(&supp,&FP_1);
+            FP_YYY_copy(&supp1,&FP_1);
+            FP_YYY_inv(&supp,&supp);
+            FP_YYY_reduce(&supp);
+            if(!FP_YYY_equals(&supp,&FPinv))
+            {
+                printf("ERROR computing inverse modulo, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+            FP_YYY_mul(&supp,&supp,&supp1);
+            FP_YYY_reduce(&supp);
+            FP_YYY_one(&supp1);
+            FP_YYY_reduce(&supp1);
+            if(!FP_YYY_equals(&supp,&supp1))
+            {
+                printf("ERROR multipling FP and its inverse, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+        // modular exponentiation
+        if (!strncmp(line,FPexpline, strlen(FPexpline)))
+        {
+            len = strlen(FPexpline);
+            linePtr = line + len;
+            read_FP_YYY(&FPexp,linePtr);
+            FP_YYY_copy(&supp,&FP_1);
+            FP_YYY_reduce(&supp);
+            FP_YYY_redc(bigsupp,&FP_2);
+            BIG_XXX_norm(bigsupp);
+            FP_YYY_pow(&supp,&supp,bigsupp);
+            FP_YYY_reduce(&supp);
+            if(!FP_YYY_equals(&supp,&FPexp))
+            {
+                printf("ERROR in modular exponentiation, line %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+        }
+    }
+    fclose(fp);
+
+    printf("SUCCESS TEST ARITMETIC OF FP_YYY PASSED\n");
+    exit(EXIT_SUCCESS);
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_gcm_decrypt.c
----------------------------------------------------------------------
diff --git a/test/test_gcm_decrypt.c b/test/test_gcm_decrypt.c
new file mode 100644
index 0000000..f13d30f
--- /dev/null
+++ b/test/test_gcm_decrypt.c
@@ -0,0 +1,294 @@
+/**
+ * @file test_gcm_decrypt.c
+ * @author Kealan McCusker
+ * @brief Test function for Galois Counter Mode decryption,
+ *
+ * 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.
+ */
+
+/* Build executible after installation:
+
+  gcc -std=c99 -g ./test_gcm_decrypt.c -I/opt/amcl/include -L/opt/amcl/lib -lamcl -o test_gcm_decrypt
+
+*/
+
+#include "arch.h"
+#include "amcl.h"
+#include "utils.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define LINE_LEN 300
+// #define DEBUG
+
+int main(int argc, char** argv)
+{
+    if (argc != 2)
+    {
+        printf("usage: ./test_gcm_decrypt [path to test vector file]\n");
+        exit(EXIT_FAILURE);
+    }
+
+    FILE * fp = NULL;
+    char line[LINE_LEN];
+    char * linePtr = NULL;
+    int l1=0;
+
+    char * Key = NULL;
+    int KeyLen = 0;
+    const char* KeyStr = "Key = ";
+
+    char * IV = NULL;
+    int IVLen = 0;
+    const char* IVStr = "IV = ";
+
+    char * PT = NULL;
+    const char* PTStr = "PT = ";
+
+    char * PT1 = NULL;
+    octet PT1Oct;
+
+    char * AAD = NULL;
+    int AADLen = 0;
+    const char* AADStr = "AAD = ";
+
+    char * CT = NULL;
+    int CTLen = 0;
+    const char* CTStr = "CT = ";
+
+    char Tag[16];
+    const char* TagStr = "Tag = ";
+
+    char * Tag1 = NULL;
+    octet Tag1Oct;
+    int TagLen=0;
+
+    const char* FAILStr = "FAIL";
+
+    fp = fopen(argv[1], "r");
+    if (fp == NULL)
+    {
+        printf("ERROR opening test vector file\n");
+        exit(EXIT_FAILURE);
+    }
+
+    bool readLine = false;
+
+    int i=0;
+    while (fgets(line, LINE_LEN, fp) != NULL)
+    {
+        i++;
+        readLine = true;
+        if (!strncmp(line, KeyStr, strlen(KeyStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(KeyStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr)-1;
+            KeyLen = l1/2;
+            Key = (char*) malloc (KeyLen);
+            if (Key==NULL)
+                exit(EXIT_FAILURE);
+
+            // Key binary value
+            amcl_hex2bin(linePtr, Key, l1);
+        }
+
+        if (!strncmp(line, IVStr, strlen(IVStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(IVStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr)-1;
+            IVLen = l1/2;
+            IV = (char*) malloc (IVLen);
+            if (IV==NULL)
+                exit(EXIT_FAILURE);
+
+            // IV binary value
+            amcl_hex2bin(linePtr, IV, l1);
+        }
+
+        if (!strncmp(line, CTStr, strlen(CTStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(CTStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr);
+            CTLen = l1/2;
+            CT = (char*) malloc (CTLen);
+            if (CT==NULL)
+                exit(EXIT_FAILURE);
+
+            PT = (char*) malloc (CTLen);
+            if (PT==NULL)
+                exit(EXIT_FAILURE);
+
+            // CT binary value
+            amcl_hex2bin(linePtr, CT, l1);
+        }
+
+        if (!strncmp(line, AADStr, strlen(AADStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(AADStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr)-1;
+            AADLen = l1/2;
+            AAD = (char*) malloc (AADLen);
+            if (AAD==NULL)
+                exit(EXIT_FAILURE);
+
+            // AAD binary value
+            amcl_hex2bin(linePtr, AAD, l1);
+        }
+
+        if (!strncmp(line, TagStr, strlen(TagStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(TagStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr);
+            TagLen = l1/2;
+            Tag1 = (char*) malloc (TagLen);
+            if (Tag1==NULL)
+                exit(EXIT_FAILURE);
+
+            // Golden Tag value
+            amcl_hex2bin(linePtr, Tag1, l1);
+
+            Tag1Oct.len=TagLen;
+            Tag1Oct.max=TagLen;
+            Tag1Oct.val=Tag1;
+        }
+
+        if ( !strncmp(line, PTStr, strlen(PTStr)) || !strncmp(line, FAILStr, strlen(FAILStr)) )
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+
+            if (!strncmp(line, PTStr, strlen(PTStr)))
+            {
+                // Find hex value in string
+                linePtr = line + strlen(PTStr);
+
+                // Allocate memory
+                l1 = strlen(linePtr)-1;
+                PT1 = (char*) malloc (CTLen);
+                if (PT1==NULL)
+                    exit(EXIT_FAILURE);
+
+                // Golden PT value
+                amcl_hex2bin(linePtr, PT1, l1);
+
+                PT1Oct.len=CTLen;
+                PT1Oct.max=CTLen;
+                PT1Oct.val=PT1;
+            }
+
+            gcm g;
+
+            GCM_init(&g,KeyLen,Key,IVLen,IV);
+            GCM_add_header(&g,AAD,AADLen);
+            GCM_add_cipher(&g,PT,CT,CTLen);
+            GCM_finish(&g,Tag);
+
+            octet PTOct = {CTLen,CTLen, PT};
+            octet TagOct = {TagLen,TagLen, Tag};
+
+            int rc;
+            if (!strncmp(line, PTStr, strlen(PTStr)))
+            {
+                rc =  OCT_comp(&PT1Oct,&PTOct);
+                if (!rc)
+                {
+                    printf("TEST GCM DECRYPT FAILED COMPARE PT LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+            }
+
+            if (!strncmp(line, PTStr, strlen(PTStr)))
+            {
+                rc = OCT_comp(&Tag1Oct,&TagOct);
+                if (!rc)
+                {
+                    printf("TEST GCM DECRYPT FAILED COMPARE Tag LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+            }
+
+            // Expect tag to be different from input tag
+            if (!strncmp(line, FAILStr, strlen(FAILStr)))
+            {
+                rc = OCT_comp(&Tag1Oct,&TagOct);
+                if (rc)
+                {
+                    printf("TEST GCM DECRYPT FAILED COMPARE Tag LINE %d\n",i);
+                    exit(EXIT_FAILURE);
+                }
+            }
+
+            free(Key);
+            Key = NULL;
+            free(IV);
+            IV = NULL;
+            free(PT);
+            PT = NULL;
+            free(AAD);
+            AAD = NULL;
+            free(CT);
+            CT = NULL;
+            free(PT1);
+            PT1 = NULL;
+            free(Tag1);
+            Tag1 = NULL;
+        }
+    }
+    fclose(fp);
+    if (!readLine)
+    {
+        printf("ERROR Empty test vector file\n");
+        exit(EXIT_FAILURE);
+    }
+    printf("SUCCESS TEST AES-GCM DECRYPT PASSED\n");
+    exit(EXIT_SUCCESS);
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_gcm_encrypt.c
----------------------------------------------------------------------
diff --git a/test/test_gcm_encrypt.c b/test/test_gcm_encrypt.c
new file mode 100644
index 0000000..e189ebb
--- /dev/null
+++ b/test/test_gcm_encrypt.c
@@ -0,0 +1,272 @@
+/**
+ * @file test_gcm_encrypt.c
+ * @author Kealan McCusker
+ * @brief Test function for Galois Counter Mode encryption,
+ *
+ * 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.
+ */
+
+/* Build executible after installation:
+
+  gcc -std=c99 -g ./test_gcm_encrypt.c -I/opt/amcl/include -L/opt/amcl/lib -lamcl -o test_gcm_encrypt
+
+*/
+
+#include "arch.h"
+#include "amcl.h"
+#include "utils.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define LINE_LEN 300
+//#define DEBUG
+
+int main(int argc, char** argv)
+{
+    if (argc != 2)
+    {
+        printf("usage: ./test_gcm_encrypt [path to test vector file]\n");
+        exit(EXIT_FAILURE);
+    }
+
+    FILE * fp = NULL;
+    char line[LINE_LEN];
+    char * linePtr = NULL;
+    int l1=0;
+
+    char * Key = NULL;
+    int KeyLen = 0;
+    const char* KeyStr = "Key = ";
+
+    char * IV = NULL;
+    int IVLen = 0;
+    const char* IVStr = "IV = ";
+
+    char * PT = NULL;
+    int PTLen = 0;
+    const char* PTStr = "PT = ";
+
+    char * AAD = NULL;
+    int AADLen = 0;
+    const char* AADStr = "AAD = ";
+
+    char * CT = NULL;
+    int CTLen = 0;
+    const char* CTStr = "CT = ";
+
+    char * CT1 = NULL;
+    octet CT1Oct;
+
+    char Tag[16];
+    const char* TagStr = "Tag = ";
+
+    char * Tag1 = NULL;
+    octet Tag1Oct;
+    int TagLen;
+
+    fp = fopen(argv[1], "r");
+    if (fp == NULL)
+    {
+        printf("ERROR opening test vector file\n");
+        exit(EXIT_FAILURE);
+    }
+
+    bool readLine = false;
+
+    int i=0;
+    while (fgets(line, LINE_LEN, fp) != NULL)
+    {
+        i++;
+        readLine = true;
+        if (!strncmp(line, KeyStr, strlen(KeyStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(KeyStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr)-1;
+            KeyLen = l1/2;
+            Key = (char*) malloc (KeyLen);
+            if (Key==NULL)
+                exit(EXIT_FAILURE);
+
+            // Key binary value
+            amcl_hex2bin(linePtr, Key, l1);
+        }
+
+        if (!strncmp(line, IVStr, strlen(IVStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(IVStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr)-1;
+            IVLen = l1/2;
+            IV = (char*) malloc (IVLen);
+            if (IV==NULL)
+                exit(EXIT_FAILURE);
+
+            // IV binary value
+            amcl_hex2bin(linePtr, IV, l1);
+        }
+
+        if (!strncmp(line, PTStr, strlen(PTStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(PTStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr)-1;
+            PTLen = l1/2;
+            PT = (char*) malloc (PTLen);
+            if (PT==NULL)
+                exit(EXIT_FAILURE);
+
+            // PT binary value
+            amcl_hex2bin(linePtr, PT, l1);
+        }
+
+        if (!strncmp(line, AADStr, strlen(AADStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(AADStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr)-1;
+            AADLen = l1/2;
+            AAD = (char*) malloc (AADLen);
+            if (AAD==NULL)
+                exit(EXIT_FAILURE);
+
+            // AAD binary value
+            amcl_hex2bin(linePtr, AAD, l1);
+        }
+
+        if (!strncmp(line, CTStr, strlen(CTStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(CTStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr);
+            CTLen = l1/2;
+            CT1 = (char*) malloc (CTLen);
+            if (CT1==NULL)
+                exit(EXIT_FAILURE);
+            CT = (char*) malloc (CTLen);
+            if (CT==NULL)
+                exit(EXIT_FAILURE);
+
+            // Golden CT value
+            amcl_hex2bin(linePtr, CT1, l1);
+
+            CT1Oct.len=CTLen;
+            CT1Oct.max=CTLen;
+            CT1Oct.val=CT1;
+        }
+
+        if (!strncmp(line, TagStr, strlen(TagStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", i,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(TagStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr);
+            TagLen = l1/2;
+            Tag1 = (char*) malloc (TagLen);
+            if (Tag1==NULL)
+                exit(EXIT_FAILURE);
+
+            // Golden Tag value
+            amcl_hex2bin(linePtr, Tag1, l1);
+
+            Tag1Oct.len=TagLen;
+            Tag1Oct.max=TagLen;
+            Tag1Oct.val=Tag1;
+
+
+            gcm g;
+
+            GCM_init(&g,KeyLen,Key,IVLen,IV);
+            GCM_add_header(&g,AAD,AADLen);
+            GCM_add_plain(&g,CT,PT,PTLen);
+            GCM_finish(&g,Tag);
+
+
+            octet CTOct = {CTLen,CTLen, CT};
+            int rc = OCT_comp(&CT1Oct,&CTOct);
+            if (!rc)
+            {
+                printf("TEST GCM ENCRYPT FAILED COMPARE CT LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            octet TagOct = {TagLen,TagLen, Tag};
+            rc = OCT_comp(&Tag1Oct,&TagOct);
+            if (!rc)
+            {
+                printf("TEST GCM ENCRYPT FAILED COMPARE Tag LINE %d\n",i);
+                exit(EXIT_FAILURE);
+            }
+
+            free(Key);
+            Key = NULL;
+            free(IV);
+            IV = NULL;
+            free(PT);
+            PT = NULL;
+            free(AAD);
+            AAD = NULL;
+            free(CT);
+            CT = NULL;
+            free(CT1);
+            CT1 = NULL;
+            free(Tag1);
+            Tag1 = NULL;
+        }
+    }
+    fclose(fp);
+    if (!readLine)
+    {
+        printf("ERROR Empty test vector file\n");
+        exit(EXIT_FAILURE);
+    }
+    printf("SUCCESS TEST AES-GCM ENCRYPT PASSED\n");
+    exit(EXIT_SUCCESS);
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_hash.c
----------------------------------------------------------------------
diff --git a/test/test_hash.c b/test/test_hash.c
new file mode 100644
index 0000000..c8530de
--- /dev/null
+++ b/test/test_hash.c
@@ -0,0 +1,184 @@
+/**
+ * @file test_hash.c
+ * @author Kealan McCusker
+ * @brief Test for hash 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.
+ */
+
+/* Build executible after installation:
+
+  gcc -std=c99 -g ./test_hash.c -I/opt/amcl/include -L/opt/amcl/lib -lamcl -o test_hash
+
+*/
+
+#include "arch.h"
+#include "amcl.h"
+#include "utils.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define LINE_LEN 600
+//#define DEBUG
+
+int main(int argc, char** argv)
+{
+    if (argc != 3)
+    {
+        printf("usage: ./test_hash [path to test vector file] [sha256||sha384||sha512]\n");
+        exit(EXIT_FAILURE);
+    }
+
+    int i=0;
+    FILE * fp = NULL;
+    char line[LINE_LEN];
+    char * linePtr = NULL;
+    int l1=0;
+    char * Msg = NULL;
+    int MsgLen = 0;
+    const char* MsgStr = "Msg = ";
+
+    const char* MDStr = "MD = ";
+    int MDLen = 0;
+    char * MD = NULL;
+
+    char * MD1 = NULL;
+
+    hash256 sha256;
+    hash384 sha384;
+    hash512 sha512;
+
+    // Hash initialization
+    if (!strcmp(argv[2], "sha512"))
+    {
+        HASH512_init(&sha512);
+    }
+    else if (!strcmp(argv[2], "sha384"))
+    {
+        HASH384_init(&sha384);
+    }
+    else
+    {
+        HASH256_init(&sha256);
+    }
+
+    // Open file
+    fp = fopen(argv[1], "r");
+    if (fp == NULL)
+    {
+        printf("ERROR opening test vector file\n");
+        exit(EXIT_FAILURE);
+    }
+    bool readLine = false;
+
+    int lineNo=0;
+    while ( (fgets(line, LINE_LEN, fp) != NULL))
+    {
+        readLine = true;
+        if (!strncmp(line, MsgStr, strlen(MsgStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", lineNo,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(MsgStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr)-1;
+            MsgLen = l1/2;
+            Msg = (char*) malloc(MsgLen);
+            if (Msg==NULL)
+                exit(EXIT_FAILURE);
+
+            // Msg binary value
+            amcl_hex2bin(linePtr, Msg, l1);
+        }
+
+        if (!strncmp(line, MDStr, strlen(MDStr)))
+        {
+#ifdef DEBUG
+            printf("line %d %s\n", lineNo,line);
+#endif
+            // Find hex value in string
+            linePtr = line + strlen(MDStr);
+
+            // Allocate memory
+            l1 = strlen(linePtr);
+
+            // Allocate memory for digest
+            MDLen = l1/2;
+            MD = (char*) malloc(MDLen);
+            if (MD==NULL)
+                exit(EXIT_FAILURE);
+            MD1 = (char*) malloc(MDLen);
+            if (MD1==NULL)
+                exit(EXIT_FAILURE);
+
+            octet MD1Oct= {MDLen,MDLen,MD1};
+
+            // Golden MD value
+            amcl_hex2bin(linePtr, MD1, l1);
+
+            if (!strcmp(argv[2], "sha512"))
+            {
+                for (i=0; i<MsgLen; i++)
+                    HASH512_process(&sha512,Msg[i]);
+                HASH512_hash(&sha512,MD);
+            }
+            else if (!strcmp(argv[2], "sha384"))
+            {
+                HASH384_init(&sha384);
+                for (i=0; i<MsgLen; i++)
+                    HASH384_process(&sha384,Msg[i]);
+                HASH384_hash(&sha384,MD);
+            }
+            else
+            {
+                for (i=0; i<MsgLen; i++)
+                    HASH256_process(&sha256,Msg[i]);
+                HASH256_hash(&sha256,MD);
+            }
+
+            octet MDOct= {MDLen,MDLen,MD};
+            int rc = OCT_comp(&MD1Oct,&MDOct);
+            if (!rc)
+            {
+                printf("TEST HASH FAILED COMPARE MD LINE %d\n",lineNo);
+                exit(EXIT_FAILURE);
+            }
+            free(Msg);
+            Msg = NULL;
+            free(MD1);
+            MD1 = NULL;
+            free(MD);
+            MD = NULL;
+        }
+        lineNo++;
+    }
+    fclose(fp);
+    if (!readLine)
+    {
+        printf("ERROR Empty test vector file\n");
+        exit(EXIT_FAILURE);
+    }
+    printf("SUCCESS TEST HASH %s PASSED\n", argv[2]);
+    exit(EXIT_SUCCESS);
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_mpin_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpin_ZZZ.c.in b/test/test_mpin_ZZZ.c.in
new file mode 100644
index 0000000..483966c
--- /dev/null
+++ b/test/test_mpin_ZZZ.c.in
@@ -0,0 +1,302 @@
+/**
+ * @file test_mpin_ZZZ.c
+ * @author Kealan McCusker
+ * @brief Test good token and correct PIN with D-TA. Single pass
+ *
+ * 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. Single pass */
+
+#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};
+
+    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[32] = {0};
+    octet SEED = {0,sizeof(seed),seed};
+    csprng RNG;
+
+    /* 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);
+
+    /* 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);
+
+    /* Single pass MPIN protocol */
+    /* Client  */
+    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,NULL,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,NULL,TimeValue,NULL);
+
+    printf("Y2 = 0x");
+    OCT_output(&Y2);
+    if (rtn != 0)
+    {
+        printf("FAILURE Invalid Token Error Code %d\n", rtn);
+    }
+    else
+    {
+        printf("SUCCESS Error Code %d\n", rtn);
+    }
+
+    /* clear memory */
+    OCT_clear(&ID);
+    OCT_clear(&X);
+    OCT_clear(&Y1);
+    OCT_clear(&Y2);
+    OCT_clear(&MS1);
+    OCT_clear(&MS2);
+    OCT_clear(&HCID);
+    OCT_clear(&SEC);
+    OCT_clear(&CS1);
+    OCT_clear(&CS2);
+    OCT_clear(&ServerSecret);
+    OCT_clear(&SS1);
+    OCT_clear(&SS2);
+    OCT_clear(&TP);
+    OCT_clear(&TP1);
+    OCT_clear(&TP2);
+    OCT_clear(&TOKEN);
+    OCT_clear(&UT);
+    OCT_clear(&HID);
+    OCT_clear(&HTID);
+    OCT_clear(&E);
+    OCT_clear(&F);
+    OCT_clear(&SEED);
+
+    KILL_CSPRNG(&RNG);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_mpin_bad_pin_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpin_bad_pin_ZZZ.c.in b/test/test_mpin_bad_pin_ZZZ.c.in
new file mode 100644
index 0000000..8449e7f
--- /dev/null
+++ b/test/test_mpin_bad_pin_ZZZ.c.in
@@ -0,0 +1,292 @@
+/**
+ * @file test_mpin_bad_pin_ZZZ.c
+ * @author Kealan McCusker
+ * @brief Test function for bad 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 incorrect 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= {sizeof(x), sizeof(x),x};
+    octet Y= {sizeof(y),sizeof(y),y};
+
+    /* Master secret shares */
+    char ms1[PGS_ZZZ], ms2[PGS_ZZZ];
+    octet MS1= {sizeof(ms1),sizeof(ms1),ms1};
+    octet MS2= {sizeof(ms2),sizeof(ms2),ms2};
+
+    /* Hash values of ID */
+    char hcid[PFS_ZZZ];
+    octet HCID= {sizeof(hcid),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 = 1237;
+
+    /* Assign the End-User an ID */
+    char* user = "testuser@miracl.com";
+    OCT_jstring(&ID,user);
+    printf("CLIENT: ID %s\n", user);
+
+    int date = 16512;
+    char seed[100] = {0};
+    octet SEED = {0,sizeof(seed),seed};
+    csprng RNG;
+
+    /* non random 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 */
+    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);
+    }
+    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)
+            printf("FAILURE PIN Error %d, Error Code %d\n",err, rtn);
+        else
+            printf("FAILURE Invalid Token Error Code %d\n", rtn);
+    }
+    else
+    {
+        printf("SUCCESS Error Code %d\n", rtn);
+        OCT_output_string(&ID);
+        printf("\n");
+    }
+    KILL_CSPRNG(&RNG);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_mpin_bad_token_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpin_bad_token_ZZZ.c.in b/test/test_mpin_bad_token_ZZZ.c.in
new file mode 100644
index 0000000..6a1f91f
--- /dev/null
+++ b/test/test_mpin_bad_token_ZZZ.c.in
@@ -0,0 +1,291 @@
+/**
+ * @file test_mpin_bad_token_ZZZ.c
+ * @author Kealan McCusker
+ * @brief Test function for bad TOKEN 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 bad 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 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;
+
+    /* non random 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);
+    }
+    printf("V = 0x");
+    OCT_output(&SEC);
+
+    /* Server second pass */
+    /* Set SEC to UT to simulate a bad token */
+    rtn = MPIN_ZZZ_SERVER_2(date,&HID,&HTID,&Y,&ServerSecret,&U,&UT,&UT,&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);
+        OCT_output_string(&ID);
+        printf("\n");
+    }
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_mpin_dvs_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpin_dvs_ZZZ.c.in b/test/test_mpin_dvs_ZZZ.c.in
new file mode 100644
index 0000000..f3a6387
--- /dev/null
+++ b/test/test_mpin_dvs_ZZZ.c.in
@@ -0,0 +1,300 @@
+/**
+ * @file test_mpin_dvs_ZZZ.c
+ * @author Kealan McCusker
+ * @brief Test Designated Verifier Signature (DVS) scheme
+ *
+ * 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 Designated Verifier Signature (DVS) scheme */
+
+#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+G2LEN];
+    octet ID = {0,sizeof(id),id};
+
+    // Message to sign
+    char m[256];
+    octet M= {0,sizeof(m),m};
+
+    /* Hash of the message */
+    char hm[PFS_ZZZ];
+    octet HM= {0,sizeof(hm), hm};
+
+    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};
+
+    /* Client Public Key and z */
+    char z[PGS_ZZZ], pa[G2LEN];
+    octet Z= {0,sizeof(z),z};
+    octet Pa= {0,sizeof(pa),pa};
+
+    /* 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 computer */
+    char token[2*PFS_ZZZ+1];
+    octet TOKEN= {0,sizeof(token),token};
+
+    char u[2*PFS_ZZZ+1];
+    octet U= {0,sizeof(u),u};
+
+    char hid[2*PFS_ZZZ+1];
+    octet HID= {0,sizeof(hid),hid};
+
+    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);
+
+    char seed[32] = {0};
+    octet SEED = {0,sizeof(seed),seed};
+    csprng RNG;
+
+    /* 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);
+
+    /* Generate random public key and z */
+    rtn = MPIN_ZZZ_GET_DVS_KEYPAIR(&RNG,&Z,&Pa);
+    if (rtn!=0)
+    {
+        printf("MPIN_ZZZ_GET_DVS_KEYPAIR(&RNG,&Z,&Pa) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Z: 0x");
+    OCT_output(&Z);
+    printf("Pa: 0x");
+    OCT_output(&Pa);
+
+    /* Append Pa to ID */
+    OCT_joctet(&ID,&Pa);
+    printf("ID|Pa: 0x");
+    OCT_output(&ID);
+
+    /* 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 CS = 0x");
+    OCT_output(&TOKEN);
+
+    /* Compute client secret for key escrow less scheme z.CS */
+    rtn = MPIN_ZZZ_GET_G1_MULTIPLE(NULL,0,&Z,&TOKEN,&TOKEN);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_G1_MULTIPLE(NULL,0,&Z,&CS,&CS) Error %d\n", rtn);
+        return 1;
+    }
+    printf("z.CS: 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);
+
+    /* Client: Sign message */
+    TimeValue = GET_TIME();
+    printf("TimeValue %d \n", TimeValue);
+    char* message = "sign this message";
+    OCT_jstring(&M,message);
+    HASH_ID(HASH_TYPE_ZZZ,&M,&HM);
+    printf("HM: 0x");
+    OCT_output(&HM);
+
+    rtn = MPIN_ZZZ_CLIENT(HASH_TYPE_ZZZ,0,&ID,&RNG,&X,PIN2,&TOKEN,&SEC,&U,NULL,NULL,&HM,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: Verify message */
+    rtn = MPIN_ZZZ_SERVER(HASH_TYPE_ZZZ,0,&HID,NULL,&Y2,&ServerSecret,&U,NULL,&SEC,NULL,NULL,&ID,&HM,TimeValue,&Pa);
+    printf("Y2 = 0x");
+    OCT_output(&Y2);
+    if (rtn != 0)
+    {
+        printf("FAILURE Signature Verification %d\n", rtn);
+    }
+    else
+    {
+        printf("SUCCESS Error Code %d\n", rtn);
+    }
+
+    /* clear memory */
+    OCT_clear(&ID);
+    OCT_clear(&X);
+    OCT_clear(&Y1);
+    OCT_clear(&Y2);
+    OCT_clear(&MS1);
+    OCT_clear(&MS2);
+    OCT_clear(&HCID);
+    OCT_clear(&SEC);
+    OCT_clear(&CS1);
+    OCT_clear(&CS2);
+    OCT_clear(&ServerSecret);
+    OCT_clear(&SS1);
+    OCT_clear(&SS2);
+    OCT_clear(&TOKEN);
+    OCT_clear(&U);
+    OCT_clear(&HID);
+    OCT_clear(&SEED);
+    OCT_clear(&Z);
+    OCT_clear(&Pa);
+
+    KILL_CSPRNG(&RNG);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_mpin_dvs_wrong_pk_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpin_dvs_wrong_pk_ZZZ.c.in b/test/test_mpin_dvs_wrong_pk_ZZZ.c.in
new file mode 100644
index 0000000..c3df9d7
--- /dev/null
+++ b/test/test_mpin_dvs_wrong_pk_ZZZ.c.in
@@ -0,0 +1,315 @@
+/**
+ * @file test_mpin_ZZZ.c
+ * @author Kealan McCusker
+ * @brief Test Designated Verifier Signature (DVS) scheme with incorrect PIN
+ *
+ * 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 Designated Verifier Signature (DVS) scheme with incorrect PIN*/
+
+#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+G2LEN];
+    octet ID = {0,sizeof(id),id};
+
+    // Message to sign
+    char m[256];
+    octet M= {0,sizeof(m),m};
+
+    /* Hash of the message */
+    char hm[PFS_ZZZ];
+    octet HM= {0,sizeof(hm), hm};
+
+    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};
+
+    /* Client Public Key and z */
+    char z1[PGS_ZZZ], z2[PGS_ZZZ], pa1[G2LEN], pa2[G2LEN];
+    octet Z1= {0,sizeof(z1),z1};
+    octet Z2= {0,sizeof(z2),z2};
+    octet Pa1= {0,sizeof(pa1),pa1};
+    octet Pa2= {0,sizeof(pa2),pa2};
+
+    /* 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 computer */
+    char token[2*PFS_ZZZ+1];
+    octet TOKEN= {0,sizeof(token),token};
+
+    char u[2*PFS_ZZZ+1];
+    octet U= {0,sizeof(u),u};
+
+    char hid[2*PFS_ZZZ+1];
+    octet HID= {0,sizeof(hid),hid};
+
+    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);
+
+    char seed[32] = {0};
+    octet SEED = {0,sizeof(seed),seed};
+    csprng RNG;
+
+    /* 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);
+
+    /* Generate random public key and z */
+    rtn = MPIN_ZZZ_GET_DVS_KEYPAIR(&RNG,&Z1,&Pa1);
+    if (rtn!=0)
+    {
+        printf("MPIN_ZZZ_GET_DVS_KEYPAIR(&RNG,&Z1,&Pa1) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Z1: 0x");
+    OCT_output(&Z1);
+    printf("Pa1: 0x");
+    OCT_output(&Pa1);
+
+    rtn = MPIN_ZZZ_GET_DVS_KEYPAIR(&RNG,&Z2,&Pa2);
+    if (rtn!=0)
+    {
+        printf("MPIN_ZZZ_GET_DVS_KEYPAIR(&RNG,&Z2,&Pa2) Error %d\n", rtn);
+        return 1;
+    }
+    printf("Z2: 0x");
+    OCT_output(&Z2);
+    printf("Pa2: 0x");
+    OCT_output(&Pa2);
+
+    /* Append Pa to ID */
+    OCT_joctet(&ID,&Pa1);
+    printf("ID|Pa1: 0x");
+    OCT_output(&ID);
+
+    /* 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 CS = 0x");
+    OCT_output(&TOKEN);
+
+    /* Compute client secret for key escrow less scheme z.CS */
+    rtn = MPIN_ZZZ_GET_G1_MULTIPLE(NULL,0,&Z2,&TOKEN,&TOKEN);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_G1_MULTIPLE(NULL,0,&Z,&CS,&CS) Error %d\n", rtn);
+        return 1;
+    }
+    printf("z2.CS: 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);
+
+    /* Client: Sign message */
+    TimeValue = GET_TIME();
+    printf("TimeValue %d \n", TimeValue);
+    char* message = "sign this message";
+    OCT_jstring(&M,message);
+    HASH_ID(HASH_TYPE_ZZZ,&M,&HM);
+    printf("HM: 0x");
+    OCT_output(&HM);
+
+    rtn = MPIN_ZZZ_CLIENT(HASH_TYPE_ZZZ,0,&ID,&RNG,&X,PIN2,&TOKEN,&SEC,&U,NULL,NULL,&HM,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: Verify message */
+    rtn = MPIN_ZZZ_SERVER(HASH_TYPE_ZZZ,0,&HID,NULL,&Y2,&ServerSecret,&U,NULL,&SEC,NULL,NULL,&ID,&HM,TimeValue,&Pa1);
+    printf("Y2 = 0x");
+    OCT_output(&Y2);
+    if (rtn != 0)
+    {
+        printf("FAILURE Signature Verification Error Code %d\n", rtn);
+    }
+    else
+    {
+        printf("SUCCESS Error Code %d\n", rtn);
+    }
+
+    /* clear memory */
+    OCT_clear(&ID);
+    OCT_clear(&X);
+    OCT_clear(&Y1);
+    OCT_clear(&Y2);
+    OCT_clear(&MS1);
+    OCT_clear(&MS2);
+    OCT_clear(&HCID);
+    OCT_clear(&SEC);
+    OCT_clear(&CS1);
+    OCT_clear(&CS2);
+    OCT_clear(&ServerSecret);
+    OCT_clear(&SS1);
+    OCT_clear(&SS2);
+    OCT_clear(&TOKEN);
+    OCT_clear(&U);
+    OCT_clear(&HID);
+    OCT_clear(&SEED);
+    OCT_clear(&Z1);
+    OCT_clear(&Z2);
+    OCT_clear(&Pa1);
+    OCT_clear(&Pa2);
+
+    KILL_CSPRNG(&RNG);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto-c/blob/8d28d2c3/test/test_mpin_expired_tp_ZZZ.c.in
----------------------------------------------------------------------
diff --git a/test/test_mpin_expired_tp_ZZZ.c.in b/test/test_mpin_expired_tp_ZZZ.c.in
new file mode 100644
index 0000000..7182bd5
--- /dev/null
+++ b/test/test_mpin_expired_tp_ZZZ.c.in
@@ -0,0 +1,292 @@
+/**
+ * @file test_mpin_expired_tp_ZZZ.c
+ * @author Kealan McCusker
+ * @brief Test function for expired Time Permit 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 and expired time permit */
+
+#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 ID */
+    char hcid[PFS_ZZZ];
+    octet HCID= {sizeof(hcid),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);
+    int yesterday = date -1;
+    rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,yesterday,&MS1,&HCID,&TP1);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_PERMIT(yesterday,&MS1,&HCID,&TP1) Error %d\n", rtn);
+        return 1;
+    }
+    rtn = MPIN_ZZZ_GET_CLIENT_PERMIT(HASH_TYPE_ZZZ,yesterday,&MS2,&HCID,&TP2);
+    if (rtn != 0)
+    {
+        printf("MPIN_ZZZ_GET_CLIENT_PERMIT(yesterday,&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);
+    }
+    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);
+        OCT_output_string(&ID);
+        printf("\n");
+    }
+    KILL_CSPRNG(&RNG);
+    return 0;
+}