
package org.bouncycastle.jce.provider.test;

import java.security.MessageDigest;
import java.security.Security;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.test.SimpleTestResult;
import org.bouncycastle.util.test.Test;
import org.bouncycastle.util.test.TestResult;

public class DigestTest
    implements Test
{
	final static String provider = "BC";

    public String getName()
    {
        return "Digest";
    }

	TestResult test(String algorithm)
	{
		byte[] message = "hello world".getBytes();

        try
        {
			MessageDigest digest = MessageDigest.getInstance(algorithm, provider);

			byte[] result = digest.digest(message);
			byte[] result2 = digest.digest(message);

			// test one digest the same message with the same instance
			if (!MessageDigest.isEqual(result, result2))
			{
                return new SimpleTestResult(false, "Result object 1 not equal");
			}

			// test two, single byte updates
			for (int i = 0; i < message.length; i++)
				digest.update(message[i]);
			result2 = digest.digest();

			if (!MessageDigest.isEqual(result, result2))
			{
                return new SimpleTestResult(false, "Result object 2 not equal");
			}

			// test three, two half updates
			digest.update(message, 0, message.length/2);
			digest.update(message, message.length/2, message.length-message.length/2);
			result2 = digest.digest();

			if (!MessageDigest.isEqual(result, result2))
			{
                return new SimpleTestResult(false, "Result object 3 not equal");
			}

			// test four, clone test
			digest.update(message, 0, message.length/2);
			MessageDigest d = (MessageDigest)digest.clone();
			digest.update(message, message.length/2, message.length-message.length/2);
			result2 = digest.digest();

			if (!MessageDigest.isEqual(result, result2))
			{
                return new SimpleTestResult(false, "Result object 4(a) not equal");
			}

			d.update(message, message.length/2, message.length-message.length/2);
			result2 = d.digest();

			if (!MessageDigest.isEqual(result, result2))
			{
                return new SimpleTestResult(false, "Result object 4(b) not equal");
			}

			// test five, check reset() method
			digest.update(message, 0, message.length/2);
			digest.reset();
			digest.update(message, 0, message.length/2);
			digest.update(message, message.length/2, message.length-message.length/2);
			result2 = digest.digest();

			if (!MessageDigest.isEqual(result, result2))
			{
                return new SimpleTestResult(false, "Result object 5 not equal");
			}


            return new SimpleTestResult(true, getName() + ": Okay");
        }
        catch (Exception e)
        {
            return new SimpleTestResult(false, getName() + ": failed excpetion - " + e.toString());
        }
	}

    public TestResult perform()
    {
		TestResult result;
		boolean failed = false;

		result = test("SHA-1");
		if (!result.isSuccessful())
		{
			System.out.println(result);
			failed = true;
		}

		result = test("SHA-256");
		if (!result.isSuccessful())
		{
			System.out.println(result);
			failed = true;
		}

		result = test("SHA-384");
		if (!result.isSuccessful())
		{
			System.out.println(result);
			failed = true;
		}

		result = test("SHA-512");
		if (!result.isSuccessful())
		{
			System.out.println(result);
			failed = true;
		}

		result = test("MD2");
		if (!result.isSuccessful())
		{
			System.out.println(result);
			failed = true;
		}

		result = test("MD4");
		if (!result.isSuccessful())
		{
			System.out.println(result);
			failed = true;
		}

		result = test("MD5");
		if (!result.isSuccessful())
		{
			System.out.println(result);
			failed = true;
		}

		result = test("RIPEMD128");
		if (!result.isSuccessful())
		{
			System.out.println(result);
			failed = true;
		}

		result = test("RIPEMD160");
		if (!result.isSuccessful())
		{
			System.out.println(result);
			failed = true;
		}
		
		result = test("RIPEMD256");
		if (!result.isSuccessful())
		{
			System.out.println(result);
			failed = true;
		}
		
		result = test("RIPEMD320");
		if (!result.isSuccessful())
		{
			System.out.println(result);
			failed = true;
		}

		result = test("Tiger");
		if (!result.isSuccessful())
		{
			System.out.println(result);
			failed = true;
		}

		if ( failed )
		{
			return new SimpleTestResult(false, getName() + ": Failed");
		}

		return new SimpleTestResult(true, getName() + ": Okay");
	}

	public static void main(String[] args)
    {
        Security.addProvider(new BouncyCastleProvider());

        Test            test = new DigestTest();
        TestResult      result = test.perform();

        System.out.println(result.toString());
    }
}

