diff --git a/pgpainless-core/src/main/java/org/pgpainless/algorithm/PublicKeyAlgorithm.java b/pgpainless-core/src/main/java/org/pgpainless/algorithm/PublicKeyAlgorithm.java index 8307cb91..63d88890 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/algorithm/PublicKeyAlgorithm.java +++ b/pgpainless-core/src/main/java/org/pgpainless/algorithm/PublicKeyAlgorithm.java @@ -36,6 +36,7 @@ public enum PublicKeyAlgorithm { ECDSA (PublicKeyAlgorithmTags.ECDSA), ELGAMAL_GENERAL (PublicKeyAlgorithmTags.ELGAMAL_GENERAL), DIFFIE_HELLMAN (PublicKeyAlgorithmTags.DIFFIE_HELLMAN), + EDDSA (PublicKeyAlgorithmTags.EDDSA), ; private static final Map MAP = new ConcurrentHashMap<>(); diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/EDDSA.java b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/EDDSA.java new file mode 100644 index 00000000..7ba30e8d --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/EDDSA.java @@ -0,0 +1,35 @@ +package org.pgpainless.key.generation.type; + +import java.security.spec.AlgorithmParameterSpec; + +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.pgpainless.algorithm.PublicKeyAlgorithm; +import org.pgpainless.key.generation.type.curve.EdDSACurve; + +public class EDDSA implements KeyType { + + private final EdDSACurve curve; + + private EDDSA(EdDSACurve curve) { + this.curve = curve; + } + + public static EDDSA fromCurve(EdDSACurve curve) { + return new EDDSA(curve); + } + + @Override + public String getName() { + return "EdDSA"; + } + + @Override + public PublicKeyAlgorithm getAlgorithm() { + return PublicKeyAlgorithm.EDDSA; + } + + @Override + public AlgorithmParameterSpec getAlgorithmSpec() { + return new ECNamedCurveGenParameterSpec(curve.getName()); + } +} diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/XDH.java b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/XDH.java new file mode 100644 index 00000000..ae9361f6 --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/XDH.java @@ -0,0 +1,35 @@ +package org.pgpainless.key.generation.type; + +import java.security.spec.AlgorithmParameterSpec; + +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; +import org.pgpainless.algorithm.PublicKeyAlgorithm; +import org.pgpainless.key.generation.type.curve.XDHCurve; + +public class XDH implements KeyType { + + private XDHCurve curve; + + private XDH(XDHCurve curve) { + this.curve = curve; + } + + public static XDH fromCurve(XDHCurve curve) { + return new XDH(curve); + } + + @Override + public String getName() { + return "XDH"; + } + + @Override + public PublicKeyAlgorithm getAlgorithm() { + return PublicKeyAlgorithm.ECDH; + } + + @Override + public AlgorithmParameterSpec getAlgorithmSpec() { + return new ECNamedCurveGenParameterSpec(curve.getName()); + } +} diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/curve/EdDSACurve.java b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/curve/EdDSACurve.java new file mode 100644 index 00000000..2b7cb7bd --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/curve/EdDSACurve.java @@ -0,0 +1,18 @@ +package org.pgpainless.key.generation.type.curve; + +import javax.annotation.Nonnull; + +public enum EdDSACurve { + _Ed25519("ed25519"), + ; + + final String name; + + EdDSACurve(@Nonnull String curveName) { + this.name = curveName; + } + + public String getName() { + return name; + } +} diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/curve/EllipticCurve.java b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/curve/EllipticCurve.java index 74703e2d..471eb6bd 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/curve/EllipticCurve.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/curve/EllipticCurve.java @@ -19,6 +19,8 @@ import javax.annotation.Nonnull; public enum EllipticCurve { _P256("P-256"), + _P384("P-384"), + _P521("P-521"), ; private final String name; diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/curve/XDHCurve.java b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/curve/XDHCurve.java new file mode 100644 index 00000000..6a35b661 --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/curve/XDHCurve.java @@ -0,0 +1,18 @@ +package org.pgpainless.key.generation.type.curve; + +import javax.annotation.Nonnull; + +public enum XDHCurve { + _X25519("X25519"), + ; + + final String name; + + XDHCurve(@Nonnull String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/generation/GenerateEllipticCurveKeyTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/generation/GenerateEllipticCurveKeyTest.java new file mode 100644 index 00000000..2a6ac23f --- /dev/null +++ b/pgpainless-core/src/test/java/org/pgpainless/key/generation/GenerateEllipticCurveKeyTest.java @@ -0,0 +1,35 @@ +package org.pgpainless.key.generation; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; + +import org.bouncycastle.openpgp.PGPException; +import org.junit.jupiter.api.Test; +import org.pgpainless.PGPainless; +import org.pgpainless.key.collection.PGPKeyRing; +import org.pgpainless.key.generation.type.EDDSA; +import org.pgpainless.key.generation.type.XDH; +import org.pgpainless.key.generation.type.curve.EdDSACurve; +import org.pgpainless.key.generation.type.curve.XDHCurve; +import org.pgpainless.key.util.UserId; +import org.pgpainless.util.ArmorUtils; + +public class GenerateEllipticCurveKeyTest { + + @Test + public void test() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, IOException { + PGPKeyRing keyRing = PGPainless.generateKeyRing() + .withSubKey(KeySpec.getBuilder(XDH.fromCurve(XDHCurve._X25519)) + .withDefaultKeyFlags() + .withDefaultAlgorithms()) + .withMasterKey(KeySpec.getBuilder(EDDSA.fromCurve(EdDSACurve._Ed25519)) + .withDefaultKeyFlags() + .withDefaultAlgorithms()) + .withPrimaryUserId(UserId.onlyEmail("alice@wonderland.lit").toString()) + .withoutPassphrase() + .build(); + + System.out.println(ArmorUtils.toAsciiArmoredString(keyRing.getPublicKeys())); + } +}