package aalgTest;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;

import org.junit.Assert;
import org.junit.Test;

import aalg.algebra.DlDomainParameters;
import aalg.algebra.IElement;
import aalg.algebra.IGroup;
import aalg.algebra.SubGroupDefinition;
import aalg.crypto.DirectAsymmetricPadding;
import aalg.crypto.DsaSignature;
import aalg.crypto.DsaSigner;
import aalg.crypto.DsaVerifier;
import aalg.crypto.DlKeyGenerator;
import aalg.crypto.DlPrivateKey;
import aalg.crypto.DlPublicKey;
import aalg.crypto.IAsymmetricPadding;
import aalg.crypto.IHashFunction;
import aalg.crypto.IRandomGenerator;
import aalg.crypto.TestHashFunction;
import aalg.crypto.TestRandomGenerator;

public class DsaTest {
	
	private <T extends IElement> void dhTest (final IGroupCreator<T> creator) throws IOException {
		byte[] message = {1, 2, 3, 4, 5};
		final IHashFunction hashFunction = new TestHashFunction(4);
		
		final DlDomainParameters<T> domainParameters = creator.createGroup();
		
		final IRandomGenerator rng = new TestRandomGenerator();
		final IAsymmetricPadding padding = new DirectAsymmetricPadding();
		
		final SubGroupDefinition<T> subGroupDefinition = domainParameters.getPrimeSubGroup();
		
		final DlKeyGenerator<T> keyGenerator = new DlKeyGenerator<T>(subGroupDefinition, rng);
		keyGenerator.generateKeys();
		
		final DlPrivateKey privateKey = keyGenerator.getPrivateKey();
		final DlPublicKey<T> publicKey = keyGenerator.getPublicKey();
		
		final DsaSigner<T> signer = new DsaSigner<T>(subGroupDefinition, hashFunction, padding, rng);
		final DsaSignature signature = signer.sign(message, privateKey);
		
		final DsaVerifier<T> verifier = new DsaVerifier<T>(subGroupDefinition, hashFunction, padding);
		
		final boolean valid1 = verifier.verify(message, signature, publicKey);
		Assert.assertTrue(valid1);
		
		message[0] = 10;
		final boolean valid2 = verifier.verify(message, signature, publicKey);
		Assert.assertFalse(valid2);
	}
	
	@Test
	public void testDsaPrimeField() throws IOException {
		final PrimeGroupCreator creator = new PrimeGroupCreator();
		dhTest (creator);
	}

	@Test
	public void testDsaMultiGroup() throws IOException {
		final MultiGroupCreator creator = new MultiGroupCreator(BigInteger.valueOf(65537));
		
		dhTest (creator);
	}

}
