package net.i2p.crypto.elgamal;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidParameterException;
import java.security.KeyPair;
import java.security.KeyPairGeneratorSpi;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import static net.i2p.crypto.CryptoConstants.I2P_ELGAMAL_2048_SPEC;
import net.i2p.crypto.KeyGenerator;
import net.i2p.crypto.elgamal.impl.ElGamalPrivateKeyImpl;
import net.i2p.crypto.elgamal.impl.ElGamalPublicKeyImpl;
import net.i2p.crypto.elgamal.spec.ElGamalGenParameterSpec;
import net.i2p.crypto.elgamal.spec.ElGamalParameterSpec;
import net.i2p.crypto.elgamal.spec.ElGamalPrivateKeySpec;
import net.i2p.crypto.elgamal.spec.ElGamalPublicKeySpec;
import net.i2p.data.PrivateKey;
import net.i2p.data.PublicKey;
import net.i2p.data.SimpleDataStructure;
import net.i2p.util.NativeBigInteger;
import net.i2p.util.RandomSource;
/**
* Modified from eddsa
* Only supported strength is 2048
*
* @since 0.9.25
*/
public final class KeyPairGenerator extends KeyPairGeneratorSpi {
// always long, don't use short key
private static final int DEFAULT_STRENGTH = 2048;
private ElGamalParameterSpec elgParams;
//private SecureRandom random;
private boolean initialized;
/**
* @param strength must be 2048
* @param random ignored
*/
public void initialize(int strength, SecureRandom random) {
if (strength != DEFAULT_STRENGTH)
throw new InvalidParameterException("unknown key type.");
elgParams = I2P_ELGAMAL_2048_SPEC;
try {
initialize(elgParams, random);
} catch (InvalidAlgorithmParameterException e) {
throw new InvalidParameterException("key type not configurable.");
}
}
/**
* @param random ignored
*/
@Override
public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException {
if (params instanceof ElGamalParameterSpec) {
elgParams = (ElGamalParameterSpec) params;
if (!elgParams.equals(I2P_ELGAMAL_2048_SPEC))
throw new InvalidAlgorithmParameterException("unsupported ElGamalParameterSpec");
} else if (params instanceof ElGamalGenParameterSpec) {
ElGamalGenParameterSpec elgGPS = (ElGamalGenParameterSpec) params;
if (elgGPS.getPrimeSize() != DEFAULT_STRENGTH)
throw new InvalidAlgorithmParameterException("unsupported prime size");
elgParams = I2P_ELGAMAL_2048_SPEC;
} else {
throw new InvalidAlgorithmParameterException("parameter object not a ElGamalParameterSpec");
}
//this.random = random;
initialized = true;
}
public KeyPair generateKeyPair() {
if (!initialized)
initialize(DEFAULT_STRENGTH, RandomSource.getInstance());
KeyGenerator kg = KeyGenerator.getInstance();
SimpleDataStructure[] keys = kg.generatePKIKeys();
PublicKey pubKey = (PublicKey) keys[0];
PrivateKey privKey = (PrivateKey) keys[1];
ElGamalPublicKey epubKey = new ElGamalPublicKeyImpl(new NativeBigInteger(1, pubKey.getData()), elgParams);
ElGamalPrivateKey eprivKey = new ElGamalPrivateKeyImpl(new NativeBigInteger(1, privKey.getData()), elgParams);
return new KeyPair(epubKey, eprivKey);
}
}