diff --git a/crypto/src/asn1/Asn1RelativeOid.cs b/crypto/src/asn1/Asn1RelativeOid.cs
index b7df4b75a..1d2ecb3df 100644
--- a/crypto/src/asn1/Asn1RelativeOid.cs
+++ b/crypto/src/asn1/Asn1RelativeOid.cs
@@ -137,8 +137,11 @@ namespace Org.BouncyCastle.Asn1
return new PrimitiveDerEncoding(tagClass, tagNo, GetContents());
}
- private void DoOutput(MemoryStream bOut)
+ private byte[] GetContents() => Objects.EnsureSingletonInitialized(ref contents, identifier, CreateContents);
+
+ private static byte[] CreateContents(string identifier)
{
+ MemoryStream bOut = new MemoryStream();
OidTokenizer tok = new OidTokenizer(identifier);
while (tok.HasMoreTokens)
{
@@ -152,21 +155,7 @@ namespace Org.BouncyCastle.Asn1
WriteField(bOut, new BigInteger(token));
}
}
- }
-
- private byte[] GetContents()
- {
- lock (this)
- {
- if (contents == null)
- {
- MemoryStream bOut = new MemoryStream();
- DoOutput(bOut);
- contents = bOut.ToArray();
- }
-
- return contents;
- }
+ return bOut.ToArray();
}
internal static Asn1RelativeOid CreatePrimitive(byte[] contents, bool clone)
diff --git a/crypto/src/asn1/DerObjectIdentifier.cs b/crypto/src/asn1/DerObjectIdentifier.cs
index 91e427d0b..12e8ea0a8 100644
--- a/crypto/src/asn1/DerObjectIdentifier.cs
+++ b/crypto/src/asn1/DerObjectIdentifier.cs
@@ -168,8 +168,11 @@ namespace Org.BouncyCastle.Asn1
return new PrimitiveDerEncoding(tagClass, tagNo, GetContents());
}
- private void DoOutput(MemoryStream bOut)
+ private byte[] GetContents() => Objects.EnsureSingletonInitialized(ref contents, identifier, CreateContents);
+
+ private static byte[] CreateContents(string identifier)
{
+ MemoryStream bOut = new MemoryStream();
OidTokenizer tok = new OidTokenizer(identifier);
string token = tok.NextToken();
@@ -197,21 +200,8 @@ namespace Org.BouncyCastle.Asn1
Asn1RelativeOid.WriteField(bOut, new BigInteger(token));
}
}
- }
-
- private byte[] GetContents()
- {
- lock (this)
- {
- if (contents == null)
- {
- MemoryStream bOut = new MemoryStream();
- DoOutput(bOut);
- contents = bOut.ToArray();
- }
- return contents;
- }
+ return bOut.ToArray();
}
internal static DerObjectIdentifier CreatePrimitive(byte[] contents, bool clone)
diff --git a/crypto/src/asn1/x9/X9ECParametersHolder.cs b/crypto/src/asn1/x9/X9ECParametersHolder.cs
index ea72cc6ac..535dad9f7 100644
--- a/crypto/src/asn1/x9/X9ECParametersHolder.cs
+++ b/crypto/src/asn1/x9/X9ECParametersHolder.cs
@@ -1,4 +1,5 @@
using Org.BouncyCastle.Math.EC;
+using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.X9
{
@@ -7,42 +8,12 @@ namespace Org.BouncyCastle.Asn1.X9
private ECCurve m_curve;
private X9ECParameters m_parameters;
- public ECCurve Curve
- {
- get
- {
- lock (this)
- {
- if (m_curve == null)
- {
- m_curve = CreateCurve();
- }
+ public ECCurve Curve => Objects.EnsureSingletonInitialized(ref m_curve, this, self => self.CreateCurve());
- return m_curve;
- }
- }
- }
+ public X9ECParameters Parameters =>
+ Objects.EnsureSingletonInitialized(ref m_parameters, this, self => self.CreateParameters());
- public X9ECParameters Parameters
- {
- get
- {
- lock (this)
- {
- if (m_parameters == null)
- {
- m_parameters = CreateParameters();
- }
-
- return m_parameters;
- }
- }
- }
-
- protected virtual ECCurve CreateCurve()
- {
- return CreateParameters().Curve;
- }
+ protected virtual ECCurve CreateCurve() => Parameters.Curve;
protected abstract X9ECParameters CreateParameters();
}
diff --git a/crypto/src/crypto/parameters/ECDomainParameters.cs b/crypto/src/crypto/parameters/ECDomainParameters.cs
index b5ca183de..8bd58d018 100644
--- a/crypto/src/crypto/parameters/ECDomainParameters.cs
+++ b/crypto/src/crypto/parameters/ECDomainParameters.cs
@@ -81,20 +81,8 @@ namespace Org.BouncyCastle.Crypto.Parameters
get { return h; }
}
- public BigInteger HInv
- {
- get
- {
- lock (this)
- {
- if (hInv == null)
- {
- hInv = BigIntegers.ModOddInverseVar(n, h);
- }
- return hInv;
- }
- }
- }
+ public BigInteger HInv =>
+ Objects.EnsureSingletonInitialized(ref hInv, this, self => BigIntegers.ModOddInverseVar(self.n, self.h));
public byte[] GetSeed()
{
diff --git a/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs b/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs
index 3a760afc1..4d2746065 100644
--- a/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs
+++ b/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs
@@ -76,22 +76,8 @@ namespace Org.BouncyCastle.Crypto.Parameters
internal ReadOnlyMemory<byte> DataMemory => data;
#endif
- public Ed25519PublicKeyParameters GeneratePublicKey()
- {
- lock (data)
- {
- if (null == cachedPublicKey)
- {
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- cachedPublicKey = new Ed25519PublicKeyParameters(Ed25519.GeneratePublicKey(data));
-#else
- cachedPublicKey = new Ed25519PublicKeyParameters(Ed25519.GeneratePublicKey(data, 0));
-#endif
- }
-
- return cachedPublicKey;
- }
- }
+ public Ed25519PublicKeyParameters GeneratePublicKey() =>
+ Objects.EnsureSingletonInitialized(ref cachedPublicKey, data, CreatePublicKey);
public void Sign(Ed25519.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff, int msgLen,
byte[] sig, int sigOff)
@@ -140,6 +126,13 @@ namespace Org.BouncyCastle.Crypto.Parameters
}
}
+ private static Ed25519PublicKeyParameters CreatePublicKey(byte[] data) =>
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ new Ed25519PublicKeyParameters(Ed25519.GeneratePublicKey(data));
+#else
+ new Ed25519PublicKeyParameters(Ed25519.GeneratePublicKey(data, 0));
+#endif
+
private static byte[] Validate(byte[] buf)
{
if (buf.Length != KeySize)
diff --git a/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs b/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs
index 544dbf32d..664716ae9 100644
--- a/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs
+++ b/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs
@@ -76,22 +76,8 @@ namespace Org.BouncyCastle.Crypto.Parameters
internal ReadOnlyMemory<byte> DataMemory => data;
#endif
- public Ed448PublicKeyParameters GeneratePublicKey()
- {
- lock (data)
- {
- if (null == cachedPublicKey)
- {
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- cachedPublicKey = new Ed448PublicKeyParameters(Ed448.GeneratePublicKey(data));
-#else
- cachedPublicKey = new Ed448PublicKeyParameters(Ed448.GeneratePublicKey(data, 0));
-#endif
- }
-
- return cachedPublicKey;
- }
- }
+ public Ed448PublicKeyParameters GeneratePublicKey() =>
+ Objects.EnsureSingletonInitialized(ref cachedPublicKey, data, CreatePublicKey);
public void Sign(Ed448.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff, int msgLen,
byte[] sig, int sigOff)
@@ -132,6 +118,13 @@ namespace Org.BouncyCastle.Crypto.Parameters
}
}
+ private static Ed448PublicKeyParameters CreatePublicKey(byte[] data) =>
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ new Ed448PublicKeyParameters(Ed448.GeneratePublicKey(data));
+#else
+ new Ed448PublicKeyParameters(Ed448.GeneratePublicKey(data, 0));
+#endif
+
private static byte[] Validate(byte[] buf)
{
if (buf.Length != KeySize)
|