/*
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 ECDH/ECIES/ECDSA API Functions */

package org.apache.milagro.amcl.BN254CX;  //

import java.util.Scanner;
import junit.framework.TestCase;       //
import org.apache.milagro.amcl.RAND;
import org.apache.milagro.amcl.AES;

public class TestECDH extends TestCase   //
{
	private 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 testECDH()
	{
		byte[] RAW=new byte[100];
		RAND rng=new RAND();
		int i,j=0,res;
		int result;
		String pp=new String("M0ng00se");

		rng.clean();
		for (i=0;i<100;i++) RAW[i]=(byte)(i);
		rng.seed(100,RAW);

		int EGS=ECDH.EGS;
		int EFS=ECDH.EFS;
		int EAS=AES.KS;
		int sha=ECP.HASH_TYPE;

		byte[] S1=new byte[EGS];
		byte[] W0=new byte[2*EFS+1];
		byte[] W1=new byte[2*EFS+1];
		byte[] Z0=new byte[EFS];
		byte[] Z1=new byte[EFS];

		byte[] SALT=new byte[8];
		byte[] P1=new byte[3];
		byte[] P2=new byte[4];
		byte[] V=new byte[2*EFS+1];
		byte[] M=new byte[17];
		byte[] T=new byte[12];
		byte[] CS=new byte[EGS];
		byte[] DS=new byte[EGS];

		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt

		System.out.println("Testing ECDH code");
		System.out.println("Alice's Passphrase= "+pp);
		byte[] PW=pp.getBytes();

/* private key S0 of size EGS bytes derived from Password and Salt */

		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);

		System.out.print("Alice's private key= 0x");
		printBinary(S0);

/* Generate Key pair S/W */
		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 

		System.out.print("Alice's public key= 0x");
		printBinary(W0);

		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
		if (res!=0)
		{
			fail("ECP Public Key is invalid!");
		}
/* Random private key for other party */
		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);

		System.out.print("Servers private key= 0x");
		printBinary(S1);

		System.out.print("Servers public key= 0x");
		printBinary(W1);


		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
		if (res!=0)
		{
			fail("ECP Public Key is invalid!");
		}

/* Calculate common key using DH - IEEE 1363 method */

		ECDH.SVDP_DH(S0,W1,Z0);
		ECDH.SVDP_DH(S1,W0,Z1);

		boolean same=true;
		for (i=0;i<EFS;i++)
			if (Z0[i]!=Z1[i]) same=false;

		if (!same)
		{
			fail("*** ECPSVDP-DH Failed");
		}

		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);

		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
		System.out.print("Servers DH Key=  0x"); printBinary(KEY);

		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
		{
			System.out.println("Testing ECIES");

			P1[0]=0x0; P1[1]=0x1; P1[2]=0x2; 
			P2[0]=0x0; P2[1]=0x1; P2[2]=0x2; P2[3]=0x3; 

			for (i=0;i<=16;i++) M[i]=(byte)i; 

			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);

			System.out.println("Ciphertext= ");
			System.out.print("V= 0x"); printBinary(V);
			System.out.print("C= 0x"); printBinary(C);
			System.out.print("T= 0x"); printBinary(T);


			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
			if (M.length==0)
			{
				fail("*** ECIES Decryption Failed");
			}
			else System.out.println("Decryption succeeded");

			System.out.print("Message is 0x"); printBinary(M);

			System.out.println("Testing ECDSA");

			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
			{
				fail("***ECDSA Signature Failed");
			}
			System.out.println("Signature= ");
			System.out.print("C= 0x"); printBinary(CS);
			System.out.print("D= 0x"); printBinary(DS);

			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
			{
				fail("***ECDSA Verification Failed");
			}
			else System.out.println("ECDSA Signature/Verification succeeded "+j);
			System.out.println("");

		}
	}

/*
	public static void main(String[] args) 
	{

		byte[] RAW=new byte[100];
		RAND rng=new RAND();

		rng.clean();
		for (int i=0;i<100;i++) RAW[i]=(byte)(i);

		rng.seed(100,RAW);
		ecdh(rng);

	} */
}
