Skip to content

Commit

Permalink
Merge branch 'pgpainless-fixEd448Signing'
Browse files Browse the repository at this point in the history
  • Loading branch information
dghgit committed Jun 3, 2024
2 parents 03eb041 + 9aed89e commit c99895d
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 8 deletions.
17 changes: 14 additions & 3 deletions pg/src/main/java/org/bouncycastle/openpgp/PGPSignature.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.bouncycastle.bcpg.SignatureSubpacket;
import org.bouncycastle.bcpg.TrustPacket;
import org.bouncycastle.math.ec.rfc8032.Ed25519;
import org.bouncycastle.math.ec.rfc8032.Ed448;
import org.bouncycastle.openpgp.operator.PGPContentVerifier;
import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilder;
import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider;
Expand Down Expand Up @@ -454,9 +455,19 @@ else if (getKeyAlgorithm() == PublicKeyAlgorithmTags.EDDSA_LEGACY)
{
byte[] a = BigIntegers.asUnsignedByteArray(sigValues[0].getValue());
byte[] b = BigIntegers.asUnsignedByteArray(sigValues[1].getValue());
signature = new byte[Ed25519.SIGNATURE_SIZE];
System.arraycopy(a, 0, signature, Ed25519.PUBLIC_KEY_SIZE - a.length, a.length);
System.arraycopy(b, 0, signature, Ed25519.SIGNATURE_SIZE - b.length, b.length);
if (a.length + b.length == Ed25519.SIGNATURE_SIZE)
{
signature = new byte[Ed25519.SIGNATURE_SIZE];
System.arraycopy(a, 0, signature, Ed25519.PUBLIC_KEY_SIZE - a.length, a.length);
System.arraycopy(b, 0, signature, Ed25519.SIGNATURE_SIZE - b.length, b.length);
}
else
{
signature = new byte[Ed448.SIGNATURE_SIZE];
System.arraycopy(a, 0, signature, Ed448.PUBLIC_KEY_SIZE - a.length, a.length);
System.arraycopy(b, 0, signature, Ed448.SIGNATURE_SIZE - b.length, b.length);
}

}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import org.bouncycastle.crypto.engines.RFC3394WrapEngine;
import org.bouncycastle.crypto.engines.RSABlindedEngine;
import org.bouncycastle.crypto.engines.TwofishEngine;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.crypto.signers.DSADigestSigner;
import org.bouncycastle.crypto.signers.DSASigner;
import org.bouncycastle.crypto.signers.ECDSASigner;
Expand Down Expand Up @@ -96,6 +98,14 @@ static Signer createSigner(int keyAlgorithm, int hashAlgorithm, CipherParameters
case PublicKeyAlgorithmTags.ECDSA:
return new DSADigestSigner(new ECDSASigner(), createDigest(hashAlgorithm));
case PublicKeyAlgorithmTags.EDDSA_LEGACY:
if (keyParam instanceof Ed25519PrivateKeyParameters || keyParam instanceof Ed25519PublicKeyParameters)
{
return new EdDsaSigner(new Ed25519Signer(), createDigest(hashAlgorithm));
}
else
{
return new EdDsaSigner(new Ed448Signer(new byte[0]), createDigest(hashAlgorithm));
}
case PublicKeyAlgorithmTags.Ed25519:
return new EdDsaSigner(new Ed25519Signer(), createDigest(hashAlgorithm));
case PublicKeyAlgorithmTags.Ed448:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,14 @@ public PGPContentSigner build(final int signatureType, final long keyID, final P
final PGPDigestCalculator digestCalculator = digestCalculatorProviderBuilder.build().get(hashAlgorithm);
final PGPDigestCalculator edDigestCalculator = digestCalculatorProviderBuilder.build().get(hashAlgorithm);
final Signature signature;
signature = helper.createSignature(keyAlgorithm, hashAlgorithm);
if (keyAlgorithm == PublicKeyAlgorithmTags.EDDSA_LEGACY && privateKey.getAlgorithm().equals("Ed448"))
{
signature = helper.createSignature(PublicKeyAlgorithmTags.Ed448, hashAlgorithm);
}
else
{
signature = helper.createSignature(keyAlgorithm, hashAlgorithm);
}

try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import java.security.SignatureException;
import java.security.interfaces.RSAPublicKey;

import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
import org.bouncycastle.bcpg.EdDSAPublicBCPGKey;
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
import org.bouncycastle.jcajce.io.OutputStreamFactory;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
Expand Down Expand Up @@ -73,11 +71,19 @@ public JcaPGPContentVerifierBuilder(int keyAlgorithm, int hashAlgorithm)
public PGPContentVerifier build(final PGPPublicKey publicKey)
throws PGPException
{
final Signature signature = helper.createSignature(keyAlgorithm, hashAlgorithm);

final PGPDigestCalculator digestCalculator = digestCalculatorProviderBuilder.build().get(hashAlgorithm);
final PublicKey jcaKey = keyConverter.getPublicKey(publicKey);

final Signature signature;
if (keyAlgorithm == PublicKeyAlgorithmTags.EDDSA_LEGACY && jcaKey.getAlgorithm().equals("Ed448"))
{
signature = helper.createSignature(PublicKeyAlgorithmTags.Ed448, hashAlgorithm);
}
else
{
signature = helper.createSignature(keyAlgorithm, hashAlgorithm);
}

try
{
signature.initVerify(jcaKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,28 @@

import org.bouncycastle.bcpg.EdDSAPublicBCPGKey;
import org.bouncycastle.bcpg.EdSecretBCPGKey;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator;
import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters;
import org.bouncycastle.jcajce.spec.EdDSAParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider;
import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Date;

Expand All @@ -31,6 +42,60 @@ public void performTest()
{
testConversionOfJcaKeyPair();
testConversionOfBcKeyPair();
testV4SigningVerificationWithJcaKey();
testV4SigningVerificationWithBcKey();
}

private void testV4SigningVerificationWithJcaKey()
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException
{
Date date = currentTimeRounded();
KeyPairGenerator gen = KeyPairGenerator.getInstance("EDDSA", new BouncyCastleProvider());
gen.initialize(new EdDSAParameterSpec("Ed25519"));
KeyPair kp = gen.generateKeyPair();
PGPKeyPair keyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.EDDSA_LEGACY, kp, date);

byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);

PGPContentSignerBuilder contSigBuilder = new JcaPGPContentSignerBuilder(
keyPair.getPublicKey().getAlgorithm(),
HashAlgorithmTags.SHA512)
.setProvider(new BouncyCastleProvider());
PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder);
sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey());
sigGen.update(data);
PGPSignature signature = sigGen.generate();

PGPContentVerifierBuilderProvider contVerBuilder = new JcaPGPContentVerifierBuilderProvider()
.setProvider(new BouncyCastleProvider());
signature.init(contVerBuilder, keyPair.getPublicKey());
signature.update(data);
isTrue(signature.verify());
}

private void testV4SigningVerificationWithBcKey()
throws PGPException
{
Date date = currentTimeRounded();
Ed25519KeyPairGenerator gen = new Ed25519KeyPairGenerator();
gen.init(new Ed25519KeyGenerationParameters(new SecureRandom()));
AsymmetricCipherKeyPair kp = gen.generateKeyPair();
BcPGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.EDDSA_LEGACY, kp, date);

byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);

PGPContentSignerBuilder contSigBuilder = new BcPGPContentSignerBuilder(
keyPair.getPublicKey().getAlgorithm(),
HashAlgorithmTags.SHA512);
PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder);
sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey());
sigGen.update(data);
PGPSignature signature = sigGen.generate();

PGPContentVerifierBuilderProvider contVerBuilder = new BcPGPContentVerifierBuilderProvider();
signature.init(contVerBuilder, keyPair.getPublicKey());
signature.update(data);
isTrue(signature.verify());
}

private void testConversionOfJcaKeyPair()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@
import org.bouncycastle.jcajce.spec.EdDSAParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.*;
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider;
import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Date;

Expand All @@ -29,6 +36,60 @@ public void performTest()
{
testConversionOfJcaKeyPair();
testConversionOfBcKeyPair();
testV4SigningVerificationWithJcaKey();
testV4SigningVerificationWithBcKey();
}

private void testV4SigningVerificationWithJcaKey()
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, PGPException
{
Date date = currentTimeRounded();
KeyPairGenerator gen = KeyPairGenerator.getInstance("EDDSA", new BouncyCastleProvider());
gen.initialize(new EdDSAParameterSpec("Ed448"));
KeyPair kp = gen.generateKeyPair();
PGPKeyPair keyPair = new JcaPGPKeyPair(PublicKeyAlgorithmTags.EDDSA_LEGACY, kp, date);

byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);

PGPContentSignerBuilder contSigBuilder = new JcaPGPContentSignerBuilder(
keyPair.getPublicKey().getAlgorithm(),
HashAlgorithmTags.SHA512)
.setProvider(new BouncyCastleProvider());
PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder);
sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey());
sigGen.update(data);
PGPSignature signature = sigGen.generate();

PGPContentVerifierBuilderProvider contVerBuilder = new JcaPGPContentVerifierBuilderProvider()
.setProvider(new BouncyCastleProvider());
signature.init(contVerBuilder, keyPair.getPublicKey());
signature.update(data);
isTrue(signature.verify());
}

private void testV4SigningVerificationWithBcKey()
throws PGPException
{
Date date = currentTimeRounded();
Ed448KeyPairGenerator gen = new Ed448KeyPairGenerator();
gen.init(new Ed448KeyGenerationParameters(new SecureRandom()));
AsymmetricCipherKeyPair kp = gen.generateKeyPair();
BcPGPKeyPair keyPair = new BcPGPKeyPair(PublicKeyAlgorithmTags.EDDSA_LEGACY, kp, date);

byte[] data = "Hello, World!\n".getBytes(StandardCharsets.UTF_8);

PGPContentSignerBuilder contSigBuilder = new BcPGPContentSignerBuilder(
keyPair.getPublicKey().getAlgorithm(),
HashAlgorithmTags.SHA512);
PGPSignatureGenerator sigGen = new PGPSignatureGenerator(contSigBuilder);
sigGen.init(PGPSignature.BINARY_DOCUMENT, keyPair.getPrivateKey());
sigGen.update(data);
PGPSignature signature = sigGen.generate();

PGPContentVerifierBuilderProvider contVerBuilder = new BcPGPContentVerifierBuilderProvider();
signature.init(contVerBuilder, keyPair.getPublicKey());
signature.update(data);
isTrue(signature.verify());
}

private void testConversionOfJcaKeyPair()
Expand Down

0 comments on commit c99895d

Please sign in to comment.