/*
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.XXX;

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

public class TesttimeECDH extends TestCase
{
	public static final int MIN_TIME=10; /* seconds */
	public static final int MIN_ITERS=10; 

	public static void testtimeECDH()
	{
		byte[] RAW=new byte[100];
		RAND rng=new RAND();
		int i,iterations;
		long start,elapsed;
		double dur;

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

		System.out.println("\nTesting/Timing ECC");
		if (ECP.CURVETYPE==ECP.WEIERSTRASS)
		{
			System.out.print("Weierstrass parameterization\n");
		}		
		if (ECP.CURVETYPE==ECP.EDWARDS)
		{
			System.out.print("Edwards parameterization\n");
		}
		if (ECP.CURVETYPE==ECP.MONTGOMERY)
		{
			System.out.print("Montgomery parameterization\n");
		}

		if (FP.MODTYPE==FP.PSEUDO_MERSENNE)
		{
			System.out.print("Pseudo-Mersenne Modulus\n");
		}
		if (FP.MODTYPE==FP.MONTGOMERY_FRIENDLY)
		{
			System.out.print("Montgomery friendly Modulus\n");
		}
		if (FP.MODTYPE==FP.GENERALISED_MERSENNE)
		{
			System.out.print("Generalised-Mersenne Modulus\n");
		}
		if (FP.MODTYPE==FP.NOT_SPECIAL)
		{
			System.out.print("Not special Modulus\n");
		}

		System.out.format("Modulus size %d bits\n",FP.MODBITS); 
		System.out.format("%d bit build\n",BIG.CHUNK); 
		BIG r,s,wx,wy;
		ECP G,WP;

		G=ECP.generator();

		r=new BIG(ROM.CURVE_Order);
		s=BIG.randomnum(r,rng);

		WP=G.mul(r);
		if (!WP.is_infinity())
		{
			fail("FAILURE - rG!=O");
		}

		start = System.currentTimeMillis();
		iterations=0;
		do {
			WP=G.mul(s);
			iterations++;
			elapsed=(System.currentTimeMillis()-start);
		} while (elapsed<MIN_TIME*1000 || iterations<MIN_ITERS);
		dur=(double)elapsed/iterations;
		System.out.format("EC  mul - %8d iterations  ",iterations);
		System.out.format(" %8.2f ms per iteration\n",dur);

	}
}
