forked from I2P_Developers/i2p.i2p
KeyFactory and KeyPairGenerator for ElGamal.
Stub out decoding key constructors.
This commit is contained in:
@ -79,6 +79,11 @@ public class CryptoConstants {
|
||||
*/
|
||||
public static final DSAParameterSpec DSA_SHA1_SPEC = new DSAParameterSpec(dsap, dsaq, dsag);
|
||||
|
||||
/**
|
||||
* @since 0.9.25
|
||||
*/
|
||||
public static final ElGamalParameterSpec I2P_ELGAMAL_2048_SPEC = new ElGamalParameterSpec(elgp, elgg);
|
||||
|
||||
/**
|
||||
* This will be org.bouncycastle.jce.spec.ElgamalParameterSpec
|
||||
* if BC is available, otherwise it
|
||||
@ -99,11 +104,11 @@ public class CryptoConstants {
|
||||
} catch (Exception e) {
|
||||
//System.out.println("BC ElG spec failed");
|
||||
//e.printStackTrace();
|
||||
spec = new ElGamalParameterSpec(elgp, elgg);
|
||||
spec = I2P_ELGAMAL_2048_SPEC;
|
||||
}
|
||||
} else {
|
||||
//System.out.println("BC not available");
|
||||
spec = new ElGamalParameterSpec(elgp, elgg);
|
||||
spec = I2P_ELGAMAL_2048_SPEC;
|
||||
}
|
||||
ELGAMAL_2048_SPEC = spec;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public enum EncType {
|
||||
* This is the default.
|
||||
* Pubkey 256 bytes, privkey 256 bytes.
|
||||
*/
|
||||
ELGAMAL_2048(0, 256, 256, EncAlgo.ELGAMAL, "ElGamal/None/NoPadding", CryptoConstants.ELGAMAL_2048_SPEC, "0"),
|
||||
ELGAMAL_2048(0, 256, 256, EncAlgo.ELGAMAL, "ElGamal/None/NoPadding", CryptoConstants.I2P_ELGAMAL_2048_SPEC, "0"),
|
||||
|
||||
/** Pubkey 64 bytes; privkey 32 bytes; */
|
||||
EC_P256(1, 64, 32, EncAlgo.EC, "EC/None/NoPadding", ECConstants.P256_SPEC, "0.9.20"),
|
||||
|
88
core/java/src/net/i2p/crypto/elgamal/KeyFactory.java
Normal file
88
core/java/src/net/i2p/crypto/elgamal/KeyFactory.java
Normal file
@ -0,0 +1,88 @@
|
||||
package net.i2p.crypto.elgamal;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactorySpi;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
import javax.crypto.spec.DHParameterSpec;
|
||||
|
||||
import static net.i2p.crypto.CryptoConstants.I2P_ELGAMAL_2048_SPEC;
|
||||
import net.i2p.crypto.elgamal.impl.ElGamalPrivateKeyImpl;
|
||||
import net.i2p.crypto.elgamal.impl.ElGamalPrivateKeyImpl;
|
||||
import net.i2p.crypto.elgamal.impl.ElGamalPublicKeyImpl;
|
||||
import net.i2p.crypto.elgamal.spec.ElGamalParameterSpec;
|
||||
import net.i2p.crypto.elgamal.spec.ElGamalPrivateKeySpec;
|
||||
import net.i2p.crypto.elgamal.spec.ElGamalPublicKeySpec;
|
||||
|
||||
/**
|
||||
* Modified from eddsa
|
||||
*
|
||||
* @since 0.9.25
|
||||
*/
|
||||
public class KeyFactory extends KeyFactorySpi {
|
||||
|
||||
/**
|
||||
* Supports PKCS8EncodedKeySpec
|
||||
*/
|
||||
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
|
||||
throws InvalidKeySpecException {
|
||||
if (keySpec instanceof ElGamalPrivateKeySpec) {
|
||||
return new ElGamalPrivateKeyImpl((ElGamalPrivateKeySpec) keySpec);
|
||||
}
|
||||
if (keySpec instanceof PKCS8EncodedKeySpec) {
|
||||
return new ElGamalPrivateKeyImpl((PKCS8EncodedKeySpec) keySpec);
|
||||
}
|
||||
throw new InvalidKeySpecException("key spec not recognised");
|
||||
}
|
||||
|
||||
/**
|
||||
* Supports X509EncodedKeySpec
|
||||
*/
|
||||
protected PublicKey engineGeneratePublic(KeySpec keySpec)
|
||||
throws InvalidKeySpecException {
|
||||
if (keySpec instanceof ElGamalPublicKeySpec) {
|
||||
return new ElGamalPublicKeyImpl((ElGamalPublicKeySpec) keySpec);
|
||||
}
|
||||
if (keySpec instanceof X509EncodedKeySpec) {
|
||||
return new ElGamalPublicKeyImpl((X509EncodedKeySpec) keySpec);
|
||||
}
|
||||
throw new InvalidKeySpecException("key spec not recognised");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
|
||||
throws InvalidKeySpecException {
|
||||
if (keySpec.isAssignableFrom(ElGamalPublicKeySpec.class) && key instanceof ElGamalPublicKey) {
|
||||
ElGamalPublicKey k = (ElGamalPublicKey) key;
|
||||
// key.getParams() is a DHParameterSpec
|
||||
DHParameterSpec dhp = k.getParams();
|
||||
if (dhp != null) {
|
||||
if (dhp.getP().equals(I2P_ELGAMAL_2048_SPEC.getP()) &&
|
||||
dhp.getG().equals(I2P_ELGAMAL_2048_SPEC.getG()))
|
||||
return (T) new ElGamalPrivateKeySpec(k.getY(), I2P_ELGAMAL_2048_SPEC);
|
||||
return (T) new ElGamalPrivateKeySpec(k.getY(), new ElGamalParameterSpec(dhp.getP(), dhp.getG()));
|
||||
}
|
||||
} else if (keySpec.isAssignableFrom(ElGamalPrivateKeySpec.class) && key instanceof ElGamalPrivateKey) {
|
||||
ElGamalPrivateKey k = (ElGamalPrivateKey) key;
|
||||
// key.getParams() is a DHParameterSpec
|
||||
DHParameterSpec dhp = k.getParams();
|
||||
if (dhp != null) {
|
||||
if (dhp.getP().equals(I2P_ELGAMAL_2048_SPEC.getP()) &&
|
||||
dhp.getG().equals(I2P_ELGAMAL_2048_SPEC.getG()))
|
||||
return (T) new ElGamalPrivateKeySpec(k.getX(), I2P_ELGAMAL_2048_SPEC);
|
||||
return (T) new ElGamalPrivateKeySpec(k.getX(), new ElGamalParameterSpec(dhp.getP(), dhp.getG()));
|
||||
}
|
||||
}
|
||||
throw new InvalidKeySpecException("not implemented yet " + key + " " + keySpec);
|
||||
}
|
||||
|
||||
protected Key engineTranslateKey(Key key) throws InvalidKeyException {
|
||||
throw new InvalidKeyException("No other ElGamal key providers known");
|
||||
}
|
||||
}
|
84
core/java/src/net/i2p/crypto/elgamal/KeyPairGenerator.java
Normal file
84
core/java/src/net/i2p/crypto/elgamal/KeyPairGenerator.java
Normal file
@ -0,0 +1,84 @@
|
||||
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 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);
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
|
||||
import javax.crypto.interfaces.DHPrivateKey;
|
||||
import javax.crypto.spec.DHParameterSpec;
|
||||
@ -25,34 +26,50 @@ public class ElGamalPrivateKeyImpl
|
||||
{
|
||||
}
|
||||
|
||||
ElGamalPrivateKeyImpl(
|
||||
public ElGamalPrivateKeyImpl(
|
||||
ElGamalPrivateKey key)
|
||||
{
|
||||
this.x = key.getX();
|
||||
this.elSpec = key.getParameters();
|
||||
}
|
||||
|
||||
ElGamalPrivateKeyImpl(
|
||||
public ElGamalPrivateKeyImpl(
|
||||
DHPrivateKey key)
|
||||
{
|
||||
this.x = key.getX();
|
||||
this.elSpec = new ElGamalParameterSpec(key.getParams().getP(), key.getParams().getG());
|
||||
}
|
||||
|
||||
ElGamalPrivateKeyImpl(
|
||||
public ElGamalPrivateKeyImpl(
|
||||
ElGamalPrivateKeySpec spec)
|
||||
{
|
||||
this.x = spec.getX();
|
||||
this.elSpec = new ElGamalParameterSpec(spec.getParams().getP(), spec.getParams().getG());
|
||||
}
|
||||
|
||||
ElGamalPrivateKeyImpl(
|
||||
public ElGamalPrivateKeyImpl(
|
||||
DHPrivateKeySpec spec)
|
||||
{
|
||||
this.x = spec.getX();
|
||||
this.elSpec = new ElGamalParameterSpec(spec.getP(), spec.getG());
|
||||
}
|
||||
|
||||
public ElGamalPrivateKeyImpl(
|
||||
BigInteger x,
|
||||
ElGamalParameterSpec elSpec)
|
||||
{
|
||||
this.x = x;
|
||||
this.elSpec = elSpec;
|
||||
}
|
||||
|
||||
public ElGamalPrivateKeyImpl(
|
||||
PKCS8EncodedKeySpec spec)
|
||||
{
|
||||
throw new UnsupportedOperationException("todo");
|
||||
//this.x = spec.getX();
|
||||
//this.elSpec = new ElGamalParameterSpec(spec.getP(), spec.getG());
|
||||
}
|
||||
|
||||
public String getAlgorithm()
|
||||
{
|
||||
return "ElGamal";
|
||||
|
@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
import javax.crypto.interfaces.DHPublicKey;
|
||||
import javax.crypto.spec.DHParameterSpec;
|
||||
@ -21,41 +22,49 @@ public class ElGamalPublicKeyImpl
|
||||
private BigInteger y;
|
||||
private ElGamalParameterSpec elSpec;
|
||||
|
||||
ElGamalPublicKeyImpl(
|
||||
public ElGamalPublicKeyImpl(
|
||||
ElGamalPublicKeySpec spec)
|
||||
{
|
||||
this.y = spec.getY();
|
||||
this.elSpec = new ElGamalParameterSpec(spec.getParams().getP(), spec.getParams().getG());
|
||||
}
|
||||
|
||||
ElGamalPublicKeyImpl(
|
||||
public ElGamalPublicKeyImpl(
|
||||
DHPublicKeySpec spec)
|
||||
{
|
||||
this.y = spec.getY();
|
||||
this.elSpec = new ElGamalParameterSpec(spec.getP(), spec.getG());
|
||||
}
|
||||
|
||||
ElGamalPublicKeyImpl(
|
||||
public ElGamalPublicKeyImpl(
|
||||
ElGamalPublicKey key)
|
||||
{
|
||||
this.y = key.getY();
|
||||
this.elSpec = key.getParameters();
|
||||
}
|
||||
|
||||
ElGamalPublicKeyImpl(
|
||||
public ElGamalPublicKeyImpl(
|
||||
DHPublicKey key)
|
||||
{
|
||||
this.y = key.getY();
|
||||
this.elSpec = new ElGamalParameterSpec(key.getParams().getP(), key.getParams().getG());
|
||||
}
|
||||
|
||||
ElGamalPublicKeyImpl(
|
||||
public ElGamalPublicKeyImpl(
|
||||
BigInteger y,
|
||||
ElGamalParameterSpec elSpec)
|
||||
{
|
||||
this.y = y;
|
||||
this.elSpec = elSpec;
|
||||
}
|
||||
|
||||
public ElGamalPublicKeyImpl(
|
||||
X509EncodedKeySpec spec)
|
||||
{
|
||||
throw new UnsupportedOperationException("todo");
|
||||
//this.y = y;
|
||||
//this.elSpec = elSpec;
|
||||
}
|
||||
|
||||
public String getAlgorithm()
|
||||
{
|
||||
|
Reference in New Issue
Block a user