/*
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 driver and function exerciser for MPIN API Functions */

import java.util.Date;
import java.util.Scanner;

public class TestMPIN
{
	static boolean PERMITS=true;
	static boolean PINERROR=true;
	static boolean FULL=true;
	static boolean SINGLE_PASS=false;

	static void printBinary(byte[] array)
	{
		int i;
		for (i=0;i<array.length;i++)
		{
			System.out.printf("%02x", array[i]);
		}
		System.out.println();
	} 

	public static void main(String[] args) {
		RAND rng=new RAND();
		byte[] raw=new byte[100];
		for (int i=0;i<100;i++) raw[i]=(byte)(i+1);
		rng.seed(100,raw);

		int EGS=MPIN.EGS;
		int EFS=MPIN.EFS;
		int G1S=2*EFS+1; /* Group 1 Size */
		int G2S=4*EFS; /* Group 2 Size */
		int EAS=16;

		int sha=MPIN.HASH_TYPE;

		byte[] S = new byte[EGS];
		byte[] SST = new byte[G2S];
		byte[] TOKEN = new byte[G1S];
		byte[] PERMIT = new byte[G1S];
		byte[] SEC = new byte[G1S];
		byte[] xID = new byte[G1S];
		byte[] xCID = new byte[G1S];
		byte[] X= new byte[EGS];
		byte[] Y= new byte[EGS];
		byte[] E=new byte[12*EFS];
		byte[] F=new byte[12*EFS];
		byte[] HID=new byte[G1S];
		byte[] HTID=new byte[G1S];

		byte[] G1=new byte[12*EFS];
		byte[] G2=new byte[12*EFS];
		byte[] R=new byte[EGS];
		byte[] Z=new byte[G1S];
		byte[] W=new byte[EGS];
		byte[] T=new byte[G1S];
		byte[] CK=new byte[EAS];
		byte[] SK=new byte[EAS];

		byte[] HSID=null;

/* Trusted Authority set-up */

		MPIN.RANDOM_GENERATE(rng,S);
		System.out.print("Master Secret s: 0x");  printBinary(S);
 
 /* Create Client Identity */
 		String IDstr = "testUser@miracl.com";
		byte[] CLIENT_ID = IDstr.getBytes();   

		byte[] HCID=MPIN.HASH_ID(sha,CLIENT_ID);  /* Either Client or TA calculates Hash(ID) - you decide! */

		System.out.print("Client ID Hash= "); printBinary(HCID);
		System.out.print("Client ID= "); printBinary(CLIENT_ID);

/* Client and Server are issued secrets by DTA */
		MPIN.GET_SERVER_SECRET(S,SST);
		System.out.print("Server Secret SS: 0x");  printBinary(SST); 

		MPIN.GET_CLIENT_SECRET(S,HCID,TOKEN);
		System.out.print("Client Secret CS: 0x");        
		printBinary(TOKEN); 

/* Client extracts PIN from secret to create Token */
		int pin=1234;
		System.out.println("Client extracts PIN= "+pin); 
		int rtn=MPIN.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
		if (rtn != 0)
			System.out.println("FAILURE: EXTRACT_PIN rtn: " + rtn);

		System.out.print("Client Token TK: 0x"); printBinary(TOKEN);

		if (FULL)
		{
			MPIN.PRECOMPUTE(TOKEN,HCID,G1,G2);
		}
		int date;
		if (PERMITS)
		{
			date=MPIN.today();
/* Client gets "Time Token" permit from DTA */ 
			MPIN.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
			System.out.print("Time Permit TP: 0x");  printBinary(PERMIT); 

/* This encoding makes Time permit look random - Elligator squared */
			MPIN.ENCODING(rng,PERMIT);
			System.out.print("Encoded Time Permit TP: 0x");  printBinary(PERMIT); 
			MPIN.DECODING(PERMIT);
			System.out.print("Decoded Time Permit TP: 0x");  printBinary(PERMIT); 
		}
		else date=0;

		System.out.print("\nPIN= ");
		Scanner scan=new Scanner(System.in);
		pin=scan.nextInt();

/* Set date=0 and PERMIT=null if time permits not in use

Client First pass: Inputs CLIENT_ID, optional RNG, pin, TOKEN and PERMIT. Output xID =x .H(CLIENT_ID) and re-combined secret SEC
If PERMITS are is use, then date!=0 and PERMIT is added to secret and xCID = x.(H(CLIENT_ID)+H(date|H(CLIENT_ID)))
Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG

IMPORTANT: To save space and time..
If Time Permits OFF set xCID = null, HTID=null and use xID and HID only
If Time permits are ON, AND pin error detection is required then all of xID, xCID, HID and HTID are required
If Time permits are ON, AND pin error detection is NOT required, set xID=null, HID=null and use xCID and HTID only.


*/

		byte[] pxID=xID;
		byte[] pxCID=xCID;
		byte[] pHID=HID;
		byte[] pHTID=HTID;
		byte[] pE=E;
		byte[] pF=F;
		byte[] pPERMIT=PERMIT;
		byte[] prHID;

		if (date!=0)
		{

			prHID=pHTID;
			if (!PINERROR)
			{
				pxID=null;
		//		pHID=null;  // new
			}
		}
		else
		{
			prHID=pHID;
			pPERMIT=null;
			pxCID=null;
			pHTID=null;
		}
		if (!PINERROR)
		{
			pE=null;
			pF=null;
		}
                 
		if (SINGLE_PASS)
		{
  			System.out.println("MPIN Single Pass");
			int timeValue = MPIN.GET_TIME();
			rtn=MPIN.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
			if (rtn != 0)
  				System.out.println("FAILURE: CLIENT rtn: " + rtn);

			if (FULL)
			{
				HCID=MPIN.HASH_ID(sha,CLIENT_ID);
				MPIN.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
			}

			rtn=MPIN.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
			if (rtn != 0)
  		    System.out.println("FAILURE: SERVER rtn: " + rtn);

			if (FULL)
			{
				HSID=MPIN.HASH_ID(sha,CLIENT_ID);
				MPIN.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
			}
		}
		else
		{
  			System.out.println("MPIN Multi Pass");
                  /* Send U=x.ID to server, and recreate secret from token and pin */
  			rtn=MPIN.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
  			if (rtn != 0)
  				System.out.println("FAILURE: CLIENT_1 rtn: " + rtn);
  
  			if (FULL)
  			{
  				HCID=MPIN.HASH_ID(sha,CLIENT_ID);
  				MPIN.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
  			}
  
                  /* 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.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
  
                  /* Server generates Random number Y and sends it to Client */
  			MPIN.RANDOM_GENERATE(rng,Y);
  
			if (FULL)
			{
				HSID=MPIN.HASH_ID(sha,CLIENT_ID);
  				MPIN.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
			}
  
                  /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
  			rtn=MPIN.CLIENT_2(X,Y,SEC);
  			if (rtn != 0)
  				System.out.println("FAILURE: CLIENT_2 rtn: " + rtn);
  
                  /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
                  /* If PIN error not required, set E and F = null */
  
  			rtn=MPIN.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
  
  			if (rtn != 0)
  				System.out.println("FAILURE: SERVER_2 rtn: " + rtn);
		}
  
		if (rtn == MPIN.BAD_PIN)
		{
			System.out.println("Server says - Bad Pin. I don't know you. Feck off.\n");
			if (PINERROR)
			{
				int err=MPIN.KANGAROO(E,F);
				if (err!=0) System.out.format("(Client PIN is out by %d)\n",err);
			}
			return;
		}
		else System.out.println("Server says - PIN is good! You really are "+IDstr);


		if (FULL)
		{
			byte[] H=MPIN.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T);
			MPIN.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
			System.out.print("Client Key =  0x");  printBinary(CK); 

			H=MPIN.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T);
			MPIN.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
			System.out.print("Server Key =  0x");  printBinary(SK); 
		}
	}
}
