Add Memory/Span accessors to avoid some copies
4 files changed, 49 insertions, 1 deletions
diff --git a/crypto/src/asn1/Asn1OctetString.cs b/crypto/src/asn1/Asn1OctetString.cs
index 8f7da8800..e52e50759 100644
--- a/crypto/src/asn1/Asn1OctetString.cs
+++ b/crypto/src/asn1/Asn1OctetString.cs
@@ -103,7 +103,19 @@ namespace Org.BouncyCastle.Asn1
return contents;
}
- protected override int Asn1GetHashCode()
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ internal ReadOnlyMemory<byte> GetOctetsMemory()
+ {
+ return contents.AsMemory();
+ }
+
+ internal ReadOnlySpan<byte> GetOctetsSpan()
+ {
+ return contents.AsSpan();
+ }
+#endif
+
+ protected override int Asn1GetHashCode()
{
return Arrays.GetHashCode(GetOctets());
}
diff --git a/crypto/src/asn1/DerBitString.cs b/crypto/src/asn1/DerBitString.cs
index 2712c3056..b929de357 100644
--- a/crypto/src/asn1/DerBitString.cs
+++ b/crypto/src/asn1/DerBitString.cs
@@ -195,6 +195,24 @@ namespace Org.BouncyCastle.Asn1
return Arrays.CopyOfRange(contents, 1, contents.Length);
}
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ internal ReadOnlyMemory<byte> GetOctetsMemory()
+ {
+ if (contents[0] != 0)
+ throw new InvalidOperationException("attempt to get non-octet aligned data from BIT STRING");
+
+ return contents.AsMemory(1);
+ }
+
+ internal ReadOnlySpan<byte> GetOctetsSpan()
+ {
+ if (contents[0] != 0)
+ throw new InvalidOperationException("attempt to get non-octet aligned data from BIT STRING");
+
+ return contents.AsSpan(1);
+ }
+#endif
+
public virtual byte[] GetBytes()
{
if (contents.Length == 1)
diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs
index 5d70423f4..38e571cd6 100644
--- a/crypto/src/security/PrivateKeyFactory.cs
+++ b/crypto/src/security/PrivateKeyFactory.cs
@@ -350,10 +350,17 @@ namespace Org.BouncyCastle.Security
}
}
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ private static ReadOnlySpan<byte> GetRawKey(PrivateKeyInfo keyInfo)
+ {
+ return Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctetsSpan();
+ }
+#else
private static byte[] GetRawKey(PrivateKeyInfo keyInfo)
{
return Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctets();
}
+#endif
public static AsymmetricKeyParameter DecryptKey(
char[] passPhrase,
diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs
index 775884e94..03cabbb13 100644
--- a/crypto/src/security/PublicKeyFactory.cs
+++ b/crypto/src/security/PublicKeyFactory.cs
@@ -280,6 +280,16 @@ namespace Org.BouncyCastle.Security
}
}
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ private static ReadOnlySpan<byte> GetRawKey(SubjectPublicKeyInfo keyInfo)
+ {
+ /*
+ * TODO[RFC 8422]
+ * - Require keyInfo.Algorithm.Parameters == null?
+ */
+ return keyInfo.PublicKeyData.GetOctetsSpan();
+ }
+#else
private static byte[] GetRawKey(SubjectPublicKeyInfo keyInfo)
{
/*
@@ -288,6 +298,7 @@ namespace Org.BouncyCastle.Security
*/
return keyInfo.PublicKeyData.GetOctets();
}
+#endif
private static bool IsPkcsDHParam(Asn1Sequence seq)
{
|