Skip to content

Commit 182f21c

Browse files
committed
Add function tests for Ed25519,Ed448,X25519,X448 supported PGP key variants
1 parent 22f6fec commit 182f21c

6 files changed

+521
-14
lines changed

pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedEd25519KeyPairTest.java

+61-5
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,19 @@
77
import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters;
88
import org.bouncycastle.jcajce.spec.EdDSAParameterSpec;
99
import org.bouncycastle.jce.provider.BouncyCastleProvider;
10-
import org.bouncycastle.openpgp.PGPException;
11-
import org.bouncycastle.openpgp.PGPPublicKey;
12-
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
13-
import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter;
14-
import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair;
10+
import org.bouncycastle.openpgp.*;
11+
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
12+
import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider;
13+
import org.bouncycastle.openpgp.operator.bc.*;
14+
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
15+
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
1516
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter;
1617
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
1718
import org.bouncycastle.util.Pack;
1819
import org.bouncycastle.util.encoders.Hex;
1920

2021
import java.io.IOException;
22+
import java.nio.charset.StandardCharsets;
2123
import java.security.*;
2224
import java.util.Date;
2325

@@ -36,10 +38,64 @@ public void performTest()
3638
{
3739
testConversionOfJcaKeyPair();
3840
testConversionOfBcKeyPair();
41+
testV4SigningVerificationWithJcaKey();
42+
testV4SigningVerificationWithBcKey();
3943

4044
testConversionOfTestVectorKey();
4145
}
4246

47+
private void testV4SigningVerificationWithJcaKey()
48+
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException
49+
{
50+
Date date = currentTimeRounded();
51+
KeyPairGenerator gen = KeyPairGenerator.getInstance("EDDSA", new BouncyCastleProvider());
52+
gen.initialize(new EdDSAParameterSpec("Ed25519"));
53+
KeyPair kp = gen.generateKeyPair();
54+
PGPKeyPair keyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.Ed25519, kp, date);
55+
56+
byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);
57+
58+
PGPContentSignerBuilder contSigBuilder = new JcaPGPContentSignerBuilder(
59+
keyPair.getPublicKey().getAlgorithm(),
60+
HashAlgorithmTags.SHA512)
61+
.setProvider(new BouncyCastleProvider());
62+
PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder);
63+
sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey());
64+
sigGen.update(data);
65+
PGPSignature signature = sigGen.generate();
66+
67+
PGPContentVerifierBuilderProvider contVerBuilder = new JcaPGPContentVerifierBuilderProvider()
68+
.setProvider(new BouncyCastleProvider());
69+
signature.init(contVerBuilder, keyPair.getPublicKey());
70+
signature.update(data);
71+
isTrue(signature.verify());
72+
}
73+
74+
private void testV4SigningVerificationWithBcKey()
75+
throws PGPException
76+
{
77+
Date date = currentTimeRounded();
78+
Ed25519KeyPairGenerator gen = new Ed25519KeyPairGenerator();
79+
gen.init(new Ed25519KeyGenerationParameters(new SecureRandom()));
80+
AsymmetricCipherKeyPair kp = gen.generateKeyPair();
81+
BcPGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.Ed25519, kp, date);
82+
83+
byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);
84+
85+
PGPContentSignerBuilder contSigBuilder = new BcPGPContentSignerBuilder(
86+
keyPair.getPublicKey().getAlgorithm(),
87+
HashAlgorithmTags.SHA512);
88+
PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder);
89+
sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey());
90+
sigGen.update(data);
91+
PGPSignature signature = sigGen.generate();
92+
93+
PGPContentVerifierBuilderProvider contVerBuilder = new BcPGPContentVerifierBuilderProvider();
94+
signature.init(contVerBuilder, keyPair.getPublicKey());
95+
signature.update(data);
96+
isTrue(signature.verify());
97+
}
98+
4399
private void testConversionOfJcaKeyPair()
44100
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException, IOException
45101
{

pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedEd448KeyPairTest.java

+65
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,28 @@
22

33
import org.bouncycastle.bcpg.Ed448PublicBCPGKey;
44
import org.bouncycastle.bcpg.Ed448SecretBCPGKey;
5+
import org.bouncycastle.bcpg.HashAlgorithmTags;
56
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
67
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
78
import org.bouncycastle.crypto.generators.Ed448KeyPairGenerator;
89
import org.bouncycastle.crypto.params.Ed448KeyGenerationParameters;
910
import org.bouncycastle.jcajce.spec.EdDSAParameterSpec;
1011
import org.bouncycastle.jce.provider.BouncyCastleProvider;
1112
import org.bouncycastle.openpgp.PGPException;
13+
import org.bouncycastle.openpgp.PGPKeyPair;
14+
import org.bouncycastle.openpgp.PGPSignature;
15+
import org.bouncycastle.openpgp.PGPSignatureGenerator;
16+
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
17+
import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider;
18+
import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder;
19+
import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
1220
import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair;
21+
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
22+
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
1323
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
1424

1525
import java.io.IOException;
26+
import java.nio.charset.StandardCharsets;
1627
import java.security.*;
1728
import java.util.Date;
1829

@@ -31,6 +42,60 @@ public void performTest()
3142
{
3243
testConversionOfJcaKeyPair();
3344
testConversionOfBcKeyPair();
45+
testV4SigningVerificationWithJcaKey();
46+
testV4SigningVerificationWithBcKey();
47+
}
48+
49+
private void testV4SigningVerificationWithJcaKey()
50+
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException
51+
{
52+
Date date = currentTimeRounded();
53+
KeyPairGenerator gen = KeyPairGenerator.getInstance("EDDSA", new BouncyCastleProvider());
54+
gen.initialize(new EdDSAParameterSpec("Ed448"));
55+
KeyPair kp = gen.generateKeyPair();
56+
PGPKeyPair keyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.Ed448, kp, date);
57+
58+
byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);
59+
60+
PGPContentSignerBuilder contSigBuilder = new JcaPGPContentSignerBuilder(
61+
keyPair.getPublicKey().getAlgorithm(),
62+
HashAlgorithmTags.SHA512)
63+
.setProvider(new BouncyCastleProvider());
64+
PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder);
65+
sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey());
66+
sigGen.update(data);
67+
PGPSignature signature = sigGen.generate();
68+
69+
PGPContentVerifierBuilderProvider contVerBuilder = new JcaPGPContentVerifierBuilderProvider()
70+
.setProvider(new BouncyCastleProvider());
71+
signature.init(contVerBuilder, keyPair.getPublicKey());
72+
signature.update(data);
73+
isTrue(signature.verify());
74+
}
75+
76+
private void testV4SigningVerificationWithBcKey()
77+
throws PGPException
78+
{
79+
Date date = currentTimeRounded();
80+
Ed448KeyPairGenerator gen = new Ed448KeyPairGenerator();
81+
gen.init(new Ed448KeyGenerationParameters(new SecureRandom()));
82+
AsymmetricCipherKeyPair kp = gen.generateKeyPair();
83+
BcPGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.Ed448, kp, date);
84+
85+
byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);
86+
87+
PGPContentSignerBuilder contSigBuilder = new BcPGPContentSignerBuilder(
88+
keyPair.getPublicKey().getAlgorithm(),
89+
HashAlgorithmTags.SHA512);
90+
PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder);
91+
sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey());
92+
sigGen.update(data);
93+
PGPSignature signature = sigGen.generate();
94+
95+
PGPContentVerifierBuilderProvider contVerBuilder = new BcPGPContentVerifierBuilderProvider();
96+
signature.init(contVerBuilder, keyPair.getPublicKey());
97+
signature.update(data);
98+
isTrue(signature.verify());
3499
}
35100

36101
private void testConversionOfJcaKeyPair()

pg/src/test/java/org/bouncycastle/openpgp/test/DedicatedX25519KeyPairTest.java

+110-3
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,33 @@
11
package org.bouncycastle.openpgp.test;
22

33
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
4+
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
45
import org.bouncycastle.bcpg.X25519PublicBCPGKey;
56
import org.bouncycastle.bcpg.X25519SecretBCPGKey;
67
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
78
import org.bouncycastle.crypto.generators.X25519KeyPairGenerator;
89
import org.bouncycastle.crypto.params.X25519KeyGenerationParameters;
910
import org.bouncycastle.jcajce.spec.XDHParameterSpec;
1011
import org.bouncycastle.jce.provider.BouncyCastleProvider;
11-
import org.bouncycastle.openpgp.PGPException;
12+
import org.bouncycastle.openpgp.*;
13+
import org.bouncycastle.openpgp.bc.BcPGPObjectFactory;
14+
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
15+
import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder;
16+
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
17+
import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator;
18+
import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder;
1219
import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair;
20+
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
21+
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator;
1322
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
14-
15-
import java.io.IOException;
23+
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
24+
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
25+
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
26+
import org.bouncycastle.util.Arrays;
27+
import org.bouncycastle.util.io.Streams;
28+
29+
import java.io.*;
30+
import java.nio.charset.StandardCharsets;
1631
import java.security.*;
1732
import java.util.Date;
1833

@@ -31,6 +46,98 @@ public void performTest()
3146
{
3247
testConversionOfJcaKeyPair();
3348
testConversionOfBcKeyPair();
49+
50+
testV4MessageEncryptionDecryptionWithJcaKey();
51+
testV4MessageEncryptionDecryptionWithBcKey();
52+
}
53+
54+
private void testV4MessageEncryptionDecryptionWithJcaKey()
55+
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException
56+
{
57+
BouncyCastleProvider provider = new BouncyCastleProvider();
58+
59+
Date date = currentTimeRounded();
60+
KeyPairGenerator gen = KeyPairGenerator.getInstance("XDH", provider);
61+
gen.initialize(new XDHParameterSpec("X25519"));
62+
KeyPair kp = gen.generateKeyPair();
63+
PGPKeyPair keyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.X25519, kp, date);
64+
65+
byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);
66+
67+
PGPDataEncryptorBuilder encBuilder = new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256)
68+
.setProvider(provider);
69+
PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encBuilder);
70+
PublicKeyKeyEncryptionMethodGenerator metGen = new JcePublicKeyKeyEncryptionMethodGenerator(keyPair.getPublicKey())
71+
.setProvider(provider);
72+
encGen.addMethod(metGen);
73+
PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator();
74+
75+
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
76+
OutputStream encOut = encGen.open(bOut, new byte[4096]);
77+
OutputStream litOut = litGen.open(encOut, PGPLiteralData.BINARY, "", PGPLiteralData.NOW, new byte[4096]);
78+
litOut.write(data);
79+
litGen.close();
80+
encGen.close();
81+
82+
byte[] encrypted = bOut.toByteArray();
83+
84+
ByteArrayInputStream bIn = new ByteArrayInputStream(encrypted);
85+
PGPObjectFactory objectFactory = new JcaPGPObjectFactory(bIn);
86+
PGPEncryptedDataList encDataList = (PGPEncryptedDataList) objectFactory.nextObject();
87+
PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encDataList.get(0);
88+
PublicKeyDataDecryptorFactory decFactory = new JcePublicKeyDataDecryptorFactoryBuilder()
89+
.setProvider(provider)
90+
.build(keyPair.getPrivateKey());
91+
InputStream decIn = encData.getDataStream(decFactory);
92+
objectFactory = new JcaPGPObjectFactory(decIn);
93+
PGPLiteralData lit = (PGPLiteralData) objectFactory.nextObject();
94+
InputStream litIn = lit.getDataStream();
95+
byte[] plaintext = Streams.readAll(litIn);
96+
litIn.close();
97+
decIn.close();
98+
99+
isTrue(Arrays.areEqual(data, plaintext));
100+
}
101+
102+
private void testV4MessageEncryptionDecryptionWithBcKey()
103+
throws PGPException, IOException {
104+
Date date = currentTimeRounded();
105+
X25519KeyPairGenerator gen = new X25519KeyPairGenerator();
106+
gen.init(new X25519KeyGenerationParameters(new SecureRandom()));
107+
AsymmetricCipherKeyPair kp = gen.generateKeyPair();
108+
BcPGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.X25519, kp, date);
109+
110+
byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);
111+
112+
PGPDataEncryptorBuilder encBuilder = new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256);
113+
PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encBuilder);
114+
PublicKeyKeyEncryptionMethodGenerator metGen = new BcPublicKeyKeyEncryptionMethodGenerator(keyPair.getPublicKey());
115+
encGen.addMethod(metGen);
116+
PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator();
117+
118+
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
119+
OutputStream encOut = encGen.open(bOut, new byte[4096]);
120+
OutputStream litOut = litGen.open(encOut, PGPLiteralData.BINARY, "", PGPLiteralData.NOW, new byte[4096]);
121+
litOut.write(data);
122+
litGen.close();
123+
encGen.close();
124+
125+
byte[] encrypted = bOut.toByteArray();
126+
127+
ByteArrayInputStream bIn = new ByteArrayInputStream(encrypted);
128+
PGPObjectFactory objectFactory = new BcPGPObjectFactory(bIn);
129+
PGPEncryptedDataList encDataList = (PGPEncryptedDataList) objectFactory.nextObject();
130+
PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encDataList.get(0);
131+
PublicKeyDataDecryptorFactory decFactory = new BcPublicKeyDataDecryptorFactory(keyPair.getPrivateKey());
132+
InputStream decIn = encData.getDataStream(decFactory);
133+
objectFactory = new BcPGPObjectFactory(decIn);
134+
PGPLiteralData lit = (PGPLiteralData) objectFactory.nextObject();
135+
InputStream litIn = lit.getDataStream();
136+
byte[] plaintext = Streams.readAll(litIn);
137+
litIn.close();
138+
decIn.close();
139+
140+
isTrue(Arrays.areEqual(data, plaintext));
34141
}
35142

36143
private void testConversionOfJcaKeyPair()

0 commit comments

Comments
 (0)