package aalg.crypto;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import aalg.algebra.IElement;
import aalg.algebra.IGroup;
import aalg.algebra.SubGroupDefinition;
import aalg.algebra.Utils;

/**
 * Generator of private and public keys in discrete logarithm cryptosystems.
 * @author Ing. Petr Ležák
 *
 * @param <T> type of group element
 */
public class DlKeyGenerator<T extends IElement> implements IKeyGenerator<DlPrivateKey, DlPublicKey<T>> {
	
	private final IRandomGenerator rng;
	private final SubGroupDefinition<T> subGroupDefinition;
	private DlPrivateKey privateKey;
	private DlPublicKey<T> publicKey;
	
	public DlKeyGenerator (final SubGroupDefinition<T> subGroupDefinition, final IRandomGenerator rng) {
		this.rng = rng;
		this.subGroupDefinition = subGroupDefinition;
	}
	
	public void generateKeys() {
		final BigInteger generatorOrder = subGroupDefinition.getOrder();
		final BigInteger multiplier = rng.nextNumber(BigInteger.ONE, generatorOrder.subtract(BigInteger.ONE));
		privateKey = new DlPrivateKey(multiplier);
		
		final IGroup<T> group = subGroupDefinition.getGroup();
		final T generator = subGroupDefinition.getGenerator();
		publicKey = new DlPublicKey<T>(group.repeatOperation(generator, multiplier));
	}

	public DlPrivateKey getPrivateKey() {
		return privateKey;
	}

	public DlPublicKey<T> getPublicKey() {
		return publicKey;
	}
	
}
