diff --git a/crypto/src/openpgp/PgpEncryptedDataGenerator.cs b/crypto/src/openpgp/PgpEncryptedDataGenerator.cs
index a6482db6c..ac847ddb6 100644
--- a/crypto/src/openpgp/PgpEncryptedDataGenerator.cs
+++ b/crypto/src/openpgp/PgpEncryptedDataGenerator.cs
@@ -149,9 +149,14 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
byte[] secret = new byte[agreement.AgreementSize];
agreement.CalculateAgreement(cryptoPublicKey, secret, 0);
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ Span<byte> ephPubEncoding = stackalloc byte[1 + X25519PublicKeyParameters.KeySize];
+ ((X25519PublicKeyParameters)ephKp.Public).Encode(ephPubEncoding[1..]);
+#else
byte[] ephPubEncoding = new byte[1 + X25519PublicKeyParameters.KeySize];
- ephPubEncoding[0] = 0x40;
((X25519PublicKeyParameters)ephKp.Public).Encode(ephPubEncoding, 1);
+#endif
+ ephPubEncoding[0] = 0x40;
return EncryptSessionInfo(ecPubKey, sessionInfo, secret, ephPubEncoding, random);
}
@@ -168,9 +173,14 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
byte[] secret = new byte[agreement.AgreementSize];
agreement.CalculateAgreement(cryptoPublicKey, secret, 0);
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ Span<byte> ephPubEncoding = stackalloc byte[1 + X448PublicKeyParameters.KeySize];
+ ((X448PublicKeyParameters)ephKp.Public).Encode(ephPubEncoding[1..]);
+#else
byte[] ephPubEncoding = new byte[1 + X448PublicKeyParameters.KeySize];
- ephPubEncoding[0] = 0x40;
((X448PublicKeyParameters)ephKp.Public).Encode(ephPubEncoding, 1);
+#endif
+ ephPubEncoding[0] = 0x40;
return EncryptSessionInfo(ecPubKey, sessionInfo, secret, ephPubEncoding, random);
}
@@ -188,13 +198,29 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
BigInteger S = agreement.CalculateAgreement(cryptoPublicKey);
byte[] secret = BigIntegers.AsUnsignedByteArray(agreement.GetFieldSize(), S);
- byte[] ephPubEncoding = ((ECPublicKeyParameters)ephKp.Public).Q.GetEncoded(false);
+ var q = ((ECPublicKeyParameters)ephKp.Public).Q;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ int encodedLength = q.GetEncodedLength(false);
+ Span<byte> ephPubEncoding = encodedLength <= 512
+ ? stackalloc byte[encodedLength]
+ : new byte[encodedLength];
+ q.EncodeTo(false, ephPubEncoding);
+#else
+ byte[] ephPubEncoding = q.GetEncoded(false);
+#endif
+
return EncryptSessionInfo(ecPubKey, sessionInfo, secret, ephPubEncoding, random);
}
}
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ private byte[] EncryptSessionInfo(ECDHPublicBcpgKey ecPubKey, byte[] sessionInfo, byte[] secret,
+ ReadOnlySpan<byte> ephPubEncoding, SecureRandom random)
+#else
private byte[] EncryptSessionInfo(ECDHPublicBcpgKey ecPubKey, byte[] sessionInfo, byte[] secret,
byte[] ephPubEncoding, SecureRandom random)
+#endif
{
var key = new KeyParameter(Rfc6637Utilities.CreateKey(pubKey.PublicKeyPacket, secret));
@@ -402,14 +428,12 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
sessionInfo[sessionInfo.Length - 1] = (byte)(check);
}
- private byte[] CreateSessionInfo(
- SymmetricKeyAlgorithmTag algorithm,
- KeyParameter key)
+ private byte[] CreateSessionInfo(SymmetricKeyAlgorithmTag algorithm, KeyParameter key)
{
- byte[] keyBytes = key.GetKey();
- byte[] sessionInfo = new byte[keyBytes.Length + 3];
- sessionInfo[0] = (byte) algorithm;
- keyBytes.CopyTo(sessionInfo, 1);
+ int keyLength = key.KeyLength;
+ byte[] sessionInfo = new byte[keyLength + 3];
+ sessionInfo[0] = (byte)algorithm;
+ key.CopyTo(sessionInfo, 1, keyLength);
AddCheckSum(sessionInfo);
return sessionInfo;
}
diff --git a/crypto/src/openpgp/PgpPublicKey.cs b/crypto/src/openpgp/PgpPublicKey.cs
index 8b3575909..fa924ff37 100644
--- a/crypto/src/openpgp/PgpPublicKey.cs
+++ b/crypto/src/openpgp/PgpPublicKey.cs
@@ -575,8 +575,11 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
return PublicKeyFactory.CreateKey(new SubjectPublicKeyInfo(
new AlgorithmIdentifier(curveOid),
- // TODO Span variant
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ pEnc.AsSpan(1)));
+#else
Arrays.CopyOfRange(pEnc, 1, pEnc.Length)));
+#endif
}
else if (EdECObjectIdentifiers.id_X448.Equals(curveOid))
{
@@ -586,8 +589,11 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
return PublicKeyFactory.CreateKey(new SubjectPublicKeyInfo(
new AlgorithmIdentifier(curveOid),
- // TODO Span variant
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ pEnc.AsSpan(1)));
+#else
Arrays.CopyOfRange(pEnc, 1, pEnc.Length)));
+#endif
}
else
{
@@ -608,8 +614,11 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
return PublicKeyFactory.CreateKey(new SubjectPublicKeyInfo(
new AlgorithmIdentifier(curveOid),
- // TODO Span variant
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ pEnc.AsSpan(1)));
+#else
Arrays.CopyOfRange(pEnc, 1, pEnc.Length)));
+#endif
}
else if (EdECObjectIdentifiers.id_Ed448.Equals(curveOid))
{
@@ -619,8 +628,11 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
return PublicKeyFactory.CreateKey(new SubjectPublicKeyInfo(
new AlgorithmIdentifier(curveOid),
- // TODO Span variant
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ pEnc.AsSpan(1)));
+#else
Arrays.CopyOfRange(pEnc, 1, pEnc.Length)));
+#endif
}
else
{
diff --git a/crypto/src/openpgp/PgpSecretKey.cs b/crypto/src/openpgp/PgpSecretKey.cs
index 627b6788a..184621b5c 100644
--- a/crypto/src/openpgp/PgpSecretKey.cs
+++ b/crypto/src/openpgp/PgpSecretKey.cs
@@ -67,9 +67,13 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
}
else
{
- // 'reverse' because the native format for X25519 private keys is little-endian
+ // The native format for X25519 private keys is little-endian
X25519PrivateKeyParameters xK = (X25519PrivateKeyParameters)privKey.Key;
- secKey = new ECSecretBcpgKey(new BigInteger(1, Arrays.ReverseInPlace(xK.GetEncoded())));
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ secKey = new ECSecretBcpgKey(new BigInteger(1, xK.DataSpan, bigEndian: false));
+#else
+ secKey = new ECSecretBcpgKey(new BigInteger(1, xK.GetEncoded(), bigEndian: false));
+#endif
}
break;
}
@@ -81,11 +85,19 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
{
if (privKey.Key is Ed25519PrivateKeyParameters ed25519K)
{
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ secKey = new EdSecretBcpgKey(new BigInteger(1, ed25519K.DataSpan));
+#else
secKey = new EdSecretBcpgKey(new BigInteger(1, ed25519K.GetEncoded()));
+#endif
}
else if (privKey.Key is Ed448PrivateKeyParameters ed448K)
{
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ secKey = new EdSecretBcpgKey(new BigInteger(1, ed448K.DataSpan));
+#else
secKey = new EdSecretBcpgKey(new BigInteger(1, ed448K.GetEncoded()));
+#endif
}
else
{
|