summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoy Basmacier <roy.basmacier@keyfactor.com>2022-06-24 16:19:02 -0400
committerRoy Basmacier <roy.basmacier@keyfactor.com>2022-06-24 16:19:02 -0400
commit5ce0ecf7d31b462bd14c51a9e1f6514dc188c17c (patch)
tree9236aa449ab6b2c2142f3f8b0065078e125c2603
parentsphincs plus v3.1 (diff)
parentRefactoring (diff)
downloadBouncyCastle.NET-ed25519-5ce0ecf7d31b462bd14c51a9e1f6514dc188c17c.tar.xz
Merge remote-tracking branch 'origin/master'
-rw-r--r--crypto/src/AssemblyInfo.cs51
-rw-r--r--crypto/src/asn1/ASN1StreamParser.cs4
-rw-r--r--crypto/src/asn1/Asn1Exception.cs17
-rw-r--r--crypto/src/asn1/Asn1InputStream.cs15
-rw-r--r--crypto/src/asn1/Asn1ParsingException.cs17
-rw-r--r--crypto/src/asn1/Asn1TaggedObject.cs16
-rw-r--r--crypto/src/asn1/anssi/ANSSINamedCurves.cs86
-rw-r--r--crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs130
-rw-r--r--crypto/src/asn1/cryptopro/GOST3410NamedParameters.cs91
-rw-r--r--crypto/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs13
-rw-r--r--crypto/src/asn1/esf/CertificateValues.cs7
-rw-r--r--crypto/src/asn1/esf/CompleteCertificateRefs.cs7
-rw-r--r--crypto/src/asn1/esf/CompleteRevocationRefs.cs7
-rw-r--r--crypto/src/asn1/esf/CrlListID.cs7
-rw-r--r--crypto/src/asn1/esf/OcspListID.cs7
-rw-r--r--crypto/src/asn1/esf/OtherSigningCertificate.cs14
-rw-r--r--crypto/src/asn1/esf/RevocationValues.cs15
-rw-r--r--crypto/src/asn1/esf/SignaturePolicyId.cs12
-rw-r--r--crypto/src/asn1/gm/GMNamedCurves.cs94
-rw-r--r--crypto/src/asn1/nist/NISTNamedCurves.cs93
-rw-r--r--crypto/src/asn1/sec/SECNamedCurves.cs188
-rw-r--r--crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs97
-rw-r--r--crypto/src/asn1/util/Asn1Dump.cs11
-rw-r--r--crypto/src/asn1/util/Dump.cs30
-rw-r--r--crypto/src/asn1/x9/ECNamedCurveTable.cs194
-rw-r--r--crypto/src/asn1/x9/X962NamedCurves.cs94
-rw-r--r--crypto/src/bcpg/ArmoredOutputStream.cs2
-rw-r--r--crypto/src/bcpg/UnsupportedPacketVersionException.cs25
-rw-r--r--crypto/src/cmp/CmpException.cs8
-rw-r--r--crypto/src/cms/CMSAttributeTableGenerationException.cs34
-rw-r--r--crypto/src/cms/CMSException.cs20
-rw-r--r--crypto/src/cms/CMSStreamException.cs30
-rw-r--r--crypto/src/crmf/CrmfException.cs34
-rw-r--r--crypto/src/crypto/CryptoException.cs34
-rw-r--r--crypto/src/crypto/DataLengthException.cs51
-rw-r--r--crypto/src/crypto/InvalidCipherTextException.cs47
-rw-r--r--crypto/src/crypto/MaxBytesExceededException.cs23
-rw-r--r--crypto/src/crypto/OutputLengthException.cs36
-rw-r--r--crypto/src/crypto/ec/CustomNamedCurves.cs317
-rw-r--r--crypto/src/math/ec/custom/djb/Curve25519.cs171
-rw-r--r--crypto/src/math/ec/custom/djb/Curve25519Field.cs292
-rw-r--r--crypto/src/math/ec/custom/djb/Curve25519FieldElement.cs233
-rw-r--r--crypto/src/math/ec/custom/djb/Curve25519Point.cs287
-rw-r--r--crypto/src/math/ec/multiplier/FixedPointUtilities.cs2
-rw-r--r--crypto/src/math/ec/multiplier/WTauNafMultiplier.cs4
-rw-r--r--crypto/src/ocsp/OCSPException.cs18
-rw-r--r--crypto/src/openpgp/PgpDataValidationException.cs29
-rw-r--r--crypto/src/openpgp/PgpException.cs27
-rw-r--r--crypto/src/openpgp/PgpKeyValidationException.cs29
-rw-r--r--crypto/src/openssl/EncryptionException.cs22
-rw-r--r--crypto/src/openssl/PEMException.cs22
-rw-r--r--crypto/src/openssl/PasswordException.cs22
-rw-r--r--crypto/src/pkcs/PkcsException.cs36
-rw-r--r--crypto/src/pkcs/PkcsIOException.cs35
-rw-r--r--crypto/src/pkix/PkixCertPathBuilderException.cs32
-rw-r--r--crypto/src/pkix/PkixCertPathValidator.cs21
-rw-r--r--crypto/src/pkix/PkixCertPathValidatorException.cs195
-rw-r--r--crypto/src/pkix/PkixNameConstraintValidatorException.cs26
-rw-r--r--crypto/src/pkix/Rfc3280CertPathUtilities.cs101
-rw-r--r--crypto/src/pqc/crypto/lms/LMSException.cs34
-rw-r--r--crypto/src/security/GeneralSecurityException.cs17
-rw-r--r--crypto/src/security/InvalidKeyException.cs28
-rw-r--r--crypto/src/security/InvalidParameterException.cs28
-rw-r--r--crypto/src/security/KeyException.cs28
-rw-r--r--crypto/src/security/PrivateKeyFactory.cs4
-rw-r--r--crypto/src/security/PublicKeyFactory.cs4
-rw-r--r--crypto/src/security/SecurityUtilityException.cs42
-rw-r--r--crypto/src/security/SignatureException.cs28
-rw-r--r--crypto/src/security/cert/CertificateEncodingException.cs28
-rw-r--r--crypto/src/security/cert/CertificateException.cs28
-rw-r--r--crypto/src/security/cert/CertificateExpiredException.cs28
-rw-r--r--crypto/src/security/cert/CertificateNotYetValidException.cs28
-rw-r--r--crypto/src/security/cert/CertificateParsingException.cs28
-rw-r--r--crypto/src/security/cert/CrlException.cs28
-rw-r--r--crypto/src/tls/TlsException.cs35
-rw-r--r--crypto/src/tls/TlsFatalAlert.cs7
-rw-r--r--crypto/src/tls/TlsFatalAlertReceived.cs7
-rw-r--r--crypto/src/tls/TlsNoCloseNotifyException.cs9
-rw-r--r--crypto/src/tls/TlsTimeoutException.cs35
-rw-r--r--crypto/src/tls/crypto/TlsCryptoException.cs34
-rw-r--r--crypto/src/tsp/TSPException.cs18
-rw-r--r--crypto/src/tsp/TSPValidationException.cs21
-rw-r--r--crypto/src/util/Enums.cs28
-rw-r--r--crypto/src/util/MemoableResetException.cs35
-rw-r--r--crypto/src/util/Platform.cs36
-rw-r--r--crypto/src/util/TypeExtensions.cs17
-rw-r--r--crypto/src/util/collections/CollectionUtilities.cs15
-rw-r--r--crypto/src/util/collections/EnumerableProxy.cs25
-rw-r--r--crypto/src/util/io/StreamOverflowException.cs17
-rw-r--r--crypto/src/util/io/pem/PemGenerationException.cs17
-rw-r--r--crypto/src/x509/store/NoSuchStoreException.cs18
-rw-r--r--crypto/src/x509/store/X509StoreException.cs18
-rw-r--r--crypto/test/src/crypto/test/ECGOST3410_2012Test.cs8
-rw-r--r--crypto/test/src/crypto/test/ECTest.cs15
-rw-r--r--crypto/test/src/math/ec/test/ECPointPerformanceTest.cs18
-rw-r--r--crypto/test/src/math/ec/test/ECPointTest.cs9
-rw-r--r--crypto/test/src/math/ec/test/FixedPointTest.cs10
-rw-r--r--crypto/test/src/pqc/crypto/lms/HSSTests.cs2
-rw-r--r--crypto/test/src/pqc/crypto/lms/LMSTests.cs16
-rw-r--r--crypto/test/src/util/test/SimpleTest.cs2
-rw-r--r--crypto/test/src/util/test/TestFailedException.cs15
101 files changed, 1610 insertions, 2840 deletions
diff --git a/crypto/src/AssemblyInfo.cs b/crypto/src/AssemblyInfo.cs
index 568ecf594..f89d58fbd 100644
--- a/crypto/src/AssemblyInfo.cs
+++ b/crypto/src/AssemblyInfo.cs
@@ -1,17 +1,8 @@
 using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-#if PORTABLE
-using System.Linq;
-#else
 using System.Runtime.InteropServices;
-#endif
 
 [assembly: CLSCompliant(true)]
-#if !PORTABLE
 [assembly: ComVisible(false)]
-#endif
 
 // Start with no permissions
 //[assembly: PermissionSet(SecurityAction.RequestOptional, Unrestricted=false)]
@@ -20,46 +11,7 @@ using System.Runtime.InteropServices;
 // see Org.BouncyCastle.Crypto.Encodings.Pkcs1Encoding.StrictLengthEnabledProperty
 //[assembly: EnvironmentPermission(SecurityAction.RequestOptional, Read="Org.BouncyCastle.Pkcs1.Strict")]
 
-internal class AssemblyInfo
-{
-    private static string version = null;
-
-    public static string Version
-    {
-        get
-        {
-            if (version == null)
-            {
-#if PORTABLE
-#if NEW_REFLECTION
-                var a = typeof(AssemblyInfo).GetTypeInfo().Assembly;
-                var c = a.GetCustomAttributes(typeof(AssemblyVersionAttribute));
-#else
-                var a = typeof(AssemblyInfo).Assembly;
-                var c = a.GetCustomAttributes(typeof(AssemblyVersionAttribute), false);
-#endif
-                var v = (AssemblyVersionAttribute)c.FirstOrDefault();
-                if (v != null)
-                {
-                    version = v.Version;
-                }
-#else
-                version = typeof(AssemblyInfo).Assembly.GetName().Version.ToString();
-#endif
-
-                // if we're still here, then don't try again
-                if (version == null)
-                {
-                    version = string.Empty;
-                }
-            }
-
-            return version;
-        }
-    }
-}
-
-#if NET40
+#if !(NET45_OR_GREATER || NETSTANDARD1_0_OR_GREATER)
 namespace System.Reflection
 {
     [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
@@ -76,5 +28,4 @@ namespace System.Reflection
         public string Value { get; }
     }
 }
-
 #endif
diff --git a/crypto/src/asn1/ASN1StreamParser.cs b/crypto/src/asn1/ASN1StreamParser.cs
index f805f68a5..490b20ccf 100644
--- a/crypto/src/asn1/ASN1StreamParser.cs
+++ b/crypto/src/asn1/ASN1StreamParser.cs
@@ -235,9 +235,9 @@ namespace Org.BouncyCastle.Asn1
 
 		private void Set00Check(bool enabled)
 		{
-			if (_in is IndefiniteLengthInputStream)
+			if (_in is IndefiniteLengthInputStream indef)
 			{
-				((IndefiniteLengthInputStream)_in).SetEofOn00(enabled);
+				indef.SetEofOn00(enabled);
 			}
 		}
 	}
diff --git a/crypto/src/asn1/Asn1Exception.cs b/crypto/src/asn1/Asn1Exception.cs
index 9e4afb49f..ae89bbcdc 100644
--- a/crypto/src/asn1/Asn1Exception.cs
+++ b/crypto/src/asn1/Asn1Exception.cs
@@ -1,11 +1,10 @@
 using System;
 using System.IO;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Asn1
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class Asn1Exception
 		: IOException
 	{
@@ -14,16 +13,18 @@ namespace Org.BouncyCastle.Asn1
 		{
 		}
 
-		public Asn1Exception(
-			string message)
+		public Asn1Exception(string message)
 			: base(message)
 		{
 		}
 
-		public Asn1Exception(
-			string		message,
-			Exception	exception)
-			: base(message, exception)
+		public Asn1Exception(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected Asn1Exception(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/asn1/Asn1InputStream.cs b/crypto/src/asn1/Asn1InputStream.cs
index 33e7b0e0c..1df6a0206 100644
--- a/crypto/src/asn1/Asn1InputStream.cs
+++ b/crypto/src/asn1/Asn1InputStream.cs
@@ -21,17 +21,14 @@ namespace Org.BouncyCastle.Asn1
 
         internal static int FindLimit(Stream input)
         {
-            if (input is LimitedInputStream)
-                return ((LimitedInputStream)input).Limit;
+            if (input is LimitedInputStream limited)
+                return limited.Limit;
 
-            if (input is Asn1InputStream)
-                return ((Asn1InputStream)input).Limit;
+            if (input is Asn1InputStream asn1)
+                return asn1.Limit;
 
-            if (input is MemoryStream)
-            {
-                MemoryStream mem = (MemoryStream)input;
-                return (int)(mem.Length - mem.Position);
-            }
+            if (input is MemoryStream memory)
+                return (int)(memory.Length - memory.Position);
 
             return int.MaxValue;
         }
diff --git a/crypto/src/asn1/Asn1ParsingException.cs b/crypto/src/asn1/Asn1ParsingException.cs
index 294e4c2c9..2b54ae0a1 100644
--- a/crypto/src/asn1/Asn1ParsingException.cs
+++ b/crypto/src/asn1/Asn1ParsingException.cs
@@ -1,10 +1,9 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Asn1
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class Asn1ParsingException
 		: InvalidOperationException
 	{
@@ -13,16 +12,18 @@ namespace Org.BouncyCastle.Asn1
 		{
 		}
 
-		public Asn1ParsingException(
-			string message)
+		public Asn1ParsingException(string message)
 			: base(message)
 		{
 		}
 
-		public Asn1ParsingException(
-			string		message,
-			Exception	exception)
-			: base(message, exception)
+		public Asn1ParsingException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected Asn1ParsingException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/asn1/Asn1TaggedObject.cs b/crypto/src/asn1/Asn1TaggedObject.cs
index cba199fb3..46aa137a8 100644
--- a/crypto/src/asn1/Asn1TaggedObject.cs
+++ b/crypto/src/asn1/Asn1TaggedObject.cs
@@ -26,17 +26,17 @@ namespace Org.BouncyCastle.Asn1
                 return (Asn1TaggedObject)obj;
             }
             //else if (obj is Asn1TaggedObjectParser)
-            else if (obj is IAsn1Convertible)
+            else if (obj is IAsn1Convertible asn1Convertible)
             {
-                Asn1Object asn1Object = ((IAsn1Convertible)obj).ToAsn1Object();
-                if (asn1Object is Asn1TaggedObject)
-                    return (Asn1TaggedObject)asn1Object;
+                Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
+                if (asn1Object is Asn1TaggedObject taggedObject)
+                    return taggedObject;
             }
-            else if (obj is byte[])
+            else if (obj is byte[] byteArray)
             {
                 try
                 {
-                    return CheckedCast(FromByteArray((byte[])obj));
+                    return CheckedCast(FromByteArray(byteArray));
                 }
                 catch (IOException e)
                 {
@@ -313,8 +313,8 @@ namespace Org.BouncyCastle.Asn1
                 return universalType.FromImplicitConstructed(RebuildConstructed(baseObject));
             case ParsedImplicit:
             {
-                if (baseObject is Asn1Sequence)
-                    return universalType.FromImplicitConstructed((Asn1Sequence)baseObject);
+                if (baseObject is Asn1Sequence asn1Sequence)
+                    return universalType.FromImplicitConstructed(asn1Sequence);
 
                 return universalType.FromImplicitPrimitive((DerOctetString)baseObject);
             }
diff --git a/crypto/src/asn1/anssi/ANSSINamedCurves.cs b/crypto/src/asn1/anssi/ANSSINamedCurves.cs
index 3a9e4dd03..ed1faa75c 100644
--- a/crypto/src/asn1/anssi/ANSSINamedCurves.cs
+++ b/crypto/src/asn1/anssi/ANSSINamedCurves.cs
@@ -1,17 +1,17 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Math.EC;
 using Org.BouncyCastle.Math.EC.Multiplier;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Asn1.Anssi
 {
-    public class AnssiNamedCurves
+    /// <summary>Elliptic curve registry for ANSSI.</summary>
+    public static class AnssiNamedCurves
     {
         private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding)
         {
@@ -30,9 +30,6 @@ namespace Org.BouncyCastle.Asn1.Anssi
             return new BigInteger(1, Hex.DecodeStrict(hex));
         }
 
-        /*
-         * FRP256v1
-         */
         internal class Frp256v1Holder
             : X9ECParametersHolder
         {
@@ -63,16 +60,16 @@ namespace Org.BouncyCastle.Asn1.Anssi
             }
         }
 
-        private static readonly IDictionary objIds = Platform.CreateHashtable();
-        private static readonly IDictionary curves = Platform.CreateHashtable();
-        private static readonly IDictionary names = Platform.CreateHashtable();
+        private static readonly Dictionary<string, DerObjectIdentifier> objIds =
+            new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
+        private static readonly Dictionary<DerObjectIdentifier, X9ECParametersHolder> curves =
+            new Dictionary<DerObjectIdentifier, X9ECParametersHolder>();
+        private static readonly Dictionary<DerObjectIdentifier, string> names =
+            new Dictionary<DerObjectIdentifier, string>();
 
-        private static void DefineCurve(
-            string					name,
-            DerObjectIdentifier		oid,
-            X9ECParametersHolder	holder)
+        private static void DefineCurve(string name, DerObjectIdentifier oid, X9ECParametersHolder holder)
         {
-            objIds.Add(Platform.ToUpperInvariant(name), oid);
+            objIds.Add(name, oid);
             names.Add(oid, name);
             curves.Add(oid, holder);
         }
@@ -82,63 +79,64 @@ namespace Org.BouncyCastle.Asn1.Anssi
             DefineCurve("FRP256v1", AnssiObjectIdentifiers.FRP256v1, Frp256v1Holder.Instance);
         }
 
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParameters GetByName(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
             return oid == null ? null : GetByOid(oid);
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given name.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParametersHolder GetByNameLazy(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
             return oid == null ? null : GetByOidLazy(oid);
         }
 
-        /**
-         * return the X9ECParameters object for the named curve represented by
-         * the passed in object identifier. Null if the curve isn't present.
-         *
-         * @param oid an object identifier representing a named curve, if present.
-         */
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParameters GetByOid(DerObjectIdentifier oid)
         {
-            X9ECParametersHolder holder = GetByOidLazy(oid);
-            return holder == null ? null : holder.Parameters;
+            return GetByOidLazy(oid)?.Parameters;
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParametersHolder GetByOidLazy(DerObjectIdentifier oid)
         {
-            return (X9ECParametersHolder)curves[oid];
+            return curves.TryGetValue(oid, out var holder) ? holder : null;
         }
 
-        /**
-         * return the object identifier signified by the passed in name. Null
-         * if there is no object identifier associated with name.
-         *
-         * @return the object identifier associated with name, if present.
-         */
-        public static DerObjectIdentifier GetOid(
-            string name)
+        /// <summary>Look up the name of the curve with the given <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
+        public static string GetName(DerObjectIdentifier oid)
         {
-            return (DerObjectIdentifier)objIds[Platform.ToUpperInvariant(name)];
+            return names.TryGetValue(oid, out var name) ? name : null;
         }
 
-        /**
-         * return the named curve name represented by the given object identifier.
-         */
-        public static string GetName(
-            DerObjectIdentifier oid)
+        /// <summary>Look up the <see cref="DerObjectIdentifier">OID</see> of the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
+        public static DerObjectIdentifier GetOid(string name)
         {
-            return (string)names[oid];
+            return objIds.TryGetValue(name, out var oid) ? oid : null;
         }
 
-        /**
-         * returns an enumeration containing the name strings for curves
-         * contained in this structure.
-         */
-        public static IEnumerable Names
+        /// <summary>Enumerate the available curve names in this registry.</summary>
+        public static IEnumerable<string> Names
         {
-            get { return new EnumerableProxy(names.Values); }
+            get { return CollectionUtilities.Proxy(objIds.Keys); }
         }
     }
 }
diff --git a/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs b/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs
index 5ac8cadfe..ec297f7a1 100644
--- a/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs
+++ b/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs
@@ -1,27 +1,19 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.Rosstandart;
 using Org.BouncyCastle.Asn1.X9;
-using Org.BouncyCastle.Crypto.Parameters;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Math.EC;
 using Org.BouncyCastle.Math.EC.Multiplier;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Asn1.CryptoPro
 {
-    /// <summary>
-    /// Table of the available named parameters for GOST 3410-2001 / 2012.
-    /// </summary>
-    public sealed class ECGost3410NamedCurves
+    /// <summary>Elliptic curve registry for GOST 3410-2001 / 2012.</summary>
+    public static class ECGost3410NamedCurves
     {
-        private ECGost3410NamedCurves()
-        {
-        }
-
         private static X9ECPoint ConfigureBasepoint(ECCurve curve, BigInteger x, BigInteger y)
         {
             ECPoint G = curve.CreatePoint(x, y);
@@ -39,9 +31,6 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             return new BigInteger(1, Hex.DecodeStrict(hex));
         }
 
-        /*
-         * GostR3410-2001-CryptoPro-A (and GostR3410-2001-CryptoPro-XchA)
-         */
         internal class Holder_gostR3410_2001_CryptoPro_A
             : X9ECParametersHolder
         {
@@ -74,9 +63,6 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             }
         };
 
-        /*
-         * GostR3410-2001-CryptoPro-B
-         */
         internal class Holder_gostR3410_2001_CryptoPro_B
             : X9ECParametersHolder
         {
@@ -109,9 +95,6 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             }
         };
 
-        /*
-         * GostR3410-2001-CryptoPro-C
-         */
         internal class Holder_gostR3410_2001_CryptoPro_C
             : X9ECParametersHolder
         {
@@ -144,9 +127,6 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             }
         };
 
-        /*
-         * GostR3410-2001-CryptoPro-XchB
-         */
         internal class Holder_gostR3410_2001_CryptoPro_XchB
             : X9ECParametersHolder
         {
@@ -179,9 +159,6 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             }
         };
 
-        /*
-         * Tc26-Gost-3410-12-256-paramSetA
-         */
         internal class Holder_id_tc26_gost_3410_12_256_paramSetA
             : X9ECParametersHolder
         {
@@ -214,9 +191,6 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             }
         };
 
-        /*
-         * Tc26-Gost-3410-12-512-paramSetA
-         */
         internal class Holder_id_tc26_gost_3410_12_512_paramSetA
             : X9ECParametersHolder
         {
@@ -249,9 +223,6 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             }
         };
 
-        /*
-         * Tc26-Gost-3410-12-512-paramSetB
-         */
         internal class Holder_id_tc26_gost_3410_12_512_paramSetB
             : X9ECParametersHolder
         {
@@ -284,9 +255,6 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             }
         };
 
-        /*
-         * Tc26-Gost-3410-12-512-paramSetC
-         */
         internal class Holder_id_tc26_gost_3410_12_512_paramSetC
             : X9ECParametersHolder
         {
@@ -319,10 +287,12 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             }
         };
 
-
-        private static readonly IDictionary objIds = Platform.CreateHashtable();
-        private static readonly IDictionary curves = Platform.CreateHashtable();
-        private static readonly IDictionary names = Platform.CreateHashtable();
+        private static readonly Dictionary<string, DerObjectIdentifier> objIds =
+            new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
+        private static readonly Dictionary<DerObjectIdentifier, X9ECParametersHolder> curves =
+            new Dictionary<DerObjectIdentifier, X9ECParametersHolder>();
+        private static readonly Dictionary<DerObjectIdentifier, string> names =
+            new Dictionary<DerObjectIdentifier, string>();
 
         private static void DefineCurve(string name, DerObjectIdentifier oid, X9ECParametersHolder holder)
         {
@@ -333,71 +303,93 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
 
         static ECGost3410NamedCurves()
         {
-            DefineCurve("GostR3410-2001-CryptoPro-A", CryptoProObjectIdentifiers.GostR3410x2001CryptoProA,
+            DefineCurve("GostR3410-2001-CryptoPro-A",
+                CryptoProObjectIdentifiers.GostR3410x2001CryptoProA,
                 Holder_gostR3410_2001_CryptoPro_A.Instance);
-            DefineCurve("GostR3410-2001-CryptoPro-B", CryptoProObjectIdentifiers.GostR3410x2001CryptoProB,
+            DefineCurve("GostR3410-2001-CryptoPro-B",
+                CryptoProObjectIdentifiers.GostR3410x2001CryptoProB,
                 Holder_gostR3410_2001_CryptoPro_B.Instance);
-            DefineCurve("GostR3410-2001-CryptoPro-C", CryptoProObjectIdentifiers.GostR3410x2001CryptoProC,
+            DefineCurve("GostR3410-2001-CryptoPro-C",
+                CryptoProObjectIdentifiers.GostR3410x2001CryptoProC,
                 Holder_gostR3410_2001_CryptoPro_C.Instance);
-            DefineCurve("GostR3410-2001-CryptoPro-XchA", CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA,
+            DefineCurve("GostR3410-2001-CryptoPro-XchA",
+                CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA,
                 Holder_gostR3410_2001_CryptoPro_A.Instance);
-            DefineCurve("GostR3410-2001-CryptoPro-XchB", CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB,
+            DefineCurve("GostR3410-2001-CryptoPro-XchB",
+                CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB,
                 Holder_gostR3410_2001_CryptoPro_XchB.Instance);
-            DefineCurve("Tc26-Gost-3410-12-256-paramSetA", RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetA,
+            DefineCurve("Tc26-Gost-3410-12-256-paramSetA",
+                RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetA,
                 Holder_id_tc26_gost_3410_12_256_paramSetA.Instance);
-            DefineCurve("Tc26-Gost-3410-12-512-paramSetA", RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetA,
+            DefineCurve("Tc26-Gost-3410-12-512-paramSetA",
+                RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetA,
                 Holder_id_tc26_gost_3410_12_512_paramSetA.Instance);
-            DefineCurve("Tc26-Gost-3410-12-512-paramSetB", RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetB,
+            DefineCurve("Tc26-Gost-3410-12-512-paramSetB",
+                RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetB,
                 Holder_id_tc26_gost_3410_12_512_paramSetB.Instance);
-            DefineCurve("Tc26-Gost-3410-12-512-paramSetC", RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetC,
+            DefineCurve("Tc26-Gost-3410-12-512-paramSetC",
+                RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetC,
                 Holder_id_tc26_gost_3410_12_512_paramSetC.Instance);
         }
 
-        public static X9ECParameters GetByNameX9(string name)
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
+        public static X9ECParameters GetByName(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
-            return oid == null ? null : GetByOidX9(oid);
+            return oid == null ? null : GetByOid(oid);
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given name.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParametersHolder GetByNameLazy(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
             return oid == null ? null : GetByOidLazy(oid);
         }
 
-        public static X9ECParameters GetByOidX9(DerObjectIdentifier oid)
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
+        public static X9ECParameters GetByOid(DerObjectIdentifier oid)
         {
-            X9ECParametersHolder holder = GetByOidLazy(oid);
-            return holder == null ? null : holder.Parameters;
+            return GetByOidLazy(oid)?.Parameters;
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParametersHolder GetByOidLazy(DerObjectIdentifier oid)
         {
-            return (X9ECParametersHolder)curves[oid];
+            return curves.TryGetValue(oid, out var holder) ? holder : null;
         }
 
-        public static DerObjectIdentifier GetOid(
-            string name)
+        /// <summary>Look up the name of the curve with the given <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
+        public static string GetName(DerObjectIdentifier oid)
         {
-            return (DerObjectIdentifier)objIds[name];
+            return names.TryGetValue(oid, out var name) ? name : null;
         }
 
-        /**
-         * return the named curve name represented by the given object identifier.
-         */
-        public static string GetName(
-            DerObjectIdentifier oid)
+        /// <summary>Look up the <see cref="DerObjectIdentifier">OID</see> of the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
+        public static DerObjectIdentifier GetOid(string name)
         {
-            return (string)names[oid];
+            return objIds.TryGetValue(name, out var oid) ? oid : null;
         }
 
-        /**
-         * returns an enumeration containing the name strings for curves
-         * contained in this structure.
-         */
-        public static IEnumerable Names
+        /// <summary>Enumerate the available curve names in this registry.</summary>
+        public static IEnumerable<string> Names
         {
-            get { return new EnumerableProxy(names.Values); }
+            get { return CollectionUtilities.Proxy(objIds.Keys); }
         }
     }
 }
diff --git a/crypto/src/asn1/cryptopro/GOST3410NamedParameters.cs b/crypto/src/asn1/cryptopro/GOST3410NamedParameters.cs
index 66dba51d7..2d183a4f9 100644
--- a/crypto/src/asn1/cryptopro/GOST3410NamedParameters.cs
+++ b/crypto/src/asn1/cryptopro/GOST3410NamedParameters.cs
@@ -1,25 +1,14 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
-using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Math;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Asn1.CryptoPro
 {
-    /**
-    * table of the available named parameters for GOST 3410-94.
-    */
-    public sealed class Gost3410NamedParameters
+    /// <summary>Registry of available named parameters for GOST 3410-94.</summary>
+    public static class Gost3410NamedParameters
     {
-		private Gost3410NamedParameters()
-		{
-		}
-
-        private static readonly IDictionary objIds = Platform.CreateHashtable();
-        private static readonly IDictionary parameters = Platform.CreateHashtable();
-
         private static readonly Gost3410ParamSetParameters cryptoProA = new Gost3410ParamSetParameters(
             1024,
             new BigInteger("127021248288932417465907042777176443525787653508916535812817507265705031260985098497423188333483401180925999995120988934130659205614996724254121049274349357074920312769561451689224110579311248812610229678534638401693520013288995000362260684222750813532307004517341633685004541062586971416883686778842537820383"),
@@ -65,59 +54,55 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             new BigInteger("133531813272720673433859519948319001217942375967847486899482359599369642528734712461590403327731821410328012529253871914788598993103310567744136196364803064721377826656898686468463277710150809401182608770201615324990468332931294920912776241137878030224355746606283971659376426832674269780880061631528163475887")
             );
 
-		static Gost3410NamedParameters()
-        {
-            parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProA] = cryptoProA;
-            parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProB] = cryptoProB;
-            //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProC] = cryptoProC;
-            //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProD] = cryptoProD;
-            parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProXchA] = cryptoProXchA;
-            //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProXchB] = cryptoProXchA;
-            //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProXchC] = cryptoProXchA;
+        private static readonly Dictionary<string, DerObjectIdentifier> objIds =
+            new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
+        private static readonly Dictionary<DerObjectIdentifier, Gost3410ParamSetParameters> parameters =
+            new Dictionary<DerObjectIdentifier, Gost3410ParamSetParameters>();
 
-			objIds["GostR3410-94-CryptoPro-A"] = CryptoProObjectIdentifiers.GostR3410x94CryptoProA;
-            objIds["GostR3410-94-CryptoPro-B"] = CryptoProObjectIdentifiers.GostR3410x94CryptoProB;
-            objIds["GostR3410-94-CryptoPro-XchA"] = CryptoProObjectIdentifiers.GostR3410x94CryptoProXchA;
+        private static void DefineParameters(string name, DerObjectIdentifier oid,
+            Gost3410ParamSetParameters parameterSet)
+        {
+            objIds.Add(name, oid);
+            parameters.Add(oid, parameterSet);
         }
 
-		/**
-        * return the GOST3410ParamSetParameters object for the given OID, null if it
-        * isn't present.
-        *
-        * @param oid an object identifier representing a named parameters, if present.
-        */
-        public static Gost3410ParamSetParameters GetByOid(
-            DerObjectIdentifier oid)
+        static Gost3410NamedParameters()
         {
-            return (Gost3410ParamSetParameters) parameters[oid];
+            DefineParameters("GostR3410-94-CryptoPro-A", CryptoProObjectIdentifiers.GostR3410x94CryptoProA, cryptoProA);
+            DefineParameters("GostR3410-94-CryptoPro-B", CryptoProObjectIdentifiers.GostR3410x94CryptoProB, cryptoProB);
+            DefineParameters("GostR3410-94-CryptoPro-XchA", CryptoProObjectIdentifiers.GostR3410x94CryptoProXchA,
+                cryptoProXchA);
         }
 
-		/**
-        * returns an enumeration containing the name strings for parameters
-        * contained in this structure.
-        */
-        public static IEnumerable Names
+        /// <summary>Look up the <see cref="Gost3410ParamSetParameters"/> for the parameter set with the given name.
+        /// </summary>
+        /// <param name="name">The name of the parameter set.</param>
+        public static Gost3410ParamSetParameters GetByName(string name)
         {
-			get { return new EnumerableProxy(objIds.Keys); }
+            DerObjectIdentifier oid = GetOid(name);
+            return oid == null ? null : GetByOid(oid);
         }
 
-		public static Gost3410ParamSetParameters GetByName(
-            string name)
+        /// <summary>Look up the <see cref="Gost3410ParamSetParameters"/> for the parameter set with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the parameter set.</param>
+        public static Gost3410ParamSetParameters GetByOid(DerObjectIdentifier oid)
         {
-            DerObjectIdentifier oid = (DerObjectIdentifier) objIds[name];
-
-            if (oid != null)
-            {
-                return (Gost3410ParamSetParameters) parameters[oid];
-            }
+            return parameters.TryGetValue(oid, out var parameterSet) ? parameterSet : null;
+        }
 
-            return null;
+        /// <summary>Look up the <see cref="DerObjectIdentifier">OID</see> of the parameter set with the given name.
+        /// </summary>
+        /// <param name="name">The name of the parameter set.</param>
+        public static DerObjectIdentifier GetOid(string name)
+        {
+            return objIds.TryGetValue(name, out var oid) ? oid : null;
         }
 
-        public static DerObjectIdentifier GetOid(
-			string name)
+        /// <summary>Enumerate the available parameter set names in this registry.</summary>
+        public static IEnumerable<string> Names
         {
-            return (DerObjectIdentifier) objIds[name];
+            get { return CollectionUtilities.Proxy(objIds.Keys); }
         }
     }
 }
diff --git a/crypto/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs b/crypto/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs
index c6ea26204..40b69428d 100644
--- a/crypto/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs
+++ b/crypto/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs
@@ -1,7 +1,5 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.CryptoPro
 {
     public class Gost3410PublicKeyAlgParameters
@@ -11,20 +9,17 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
         private DerObjectIdentifier	digestParamSet;
         private DerObjectIdentifier	encryptionParamSet;
 
-		public static Gost3410PublicKeyAlgParameters GetInstance(
-            Asn1TaggedObject	obj,
-            bool				explicitly)
+		public static Gost3410PublicKeyAlgParameters GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
         {
-            return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+            return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
-		public static Gost3410PublicKeyAlgParameters GetInstance(
-            object obj)
+		public static Gost3410PublicKeyAlgParameters GetInstance(object obj)
         {
             if (obj == null || obj is Gost3410PublicKeyAlgParameters)
                 return (Gost3410PublicKeyAlgParameters)obj;
 
-            return new Gost3410PublicKeyAlgParameters(Asn1Sequence.GetInstance((obj)));
+            return new Gost3410PublicKeyAlgParameters(Asn1Sequence.GetInstance(obj));
         }
 
 		public Gost3410PublicKeyAlgParameters(
diff --git a/crypto/src/asn1/esf/CertificateValues.cs b/crypto/src/asn1/esf/CertificateValues.cs
index 30a719177..ee0d2830c 100644
--- a/crypto/src/asn1/esf/CertificateValues.cs
+++ b/crypto/src/asn1/esf/CertificateValues.cs
@@ -1,9 +1,8 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
@@ -57,12 +56,10 @@ namespace Org.BouncyCastle.Asn1.Esf
 		}
 
 		public CertificateValues(
-			IEnumerable certificates)
+			IEnumerable<X509CertificateStructure> certificates)
 		{
 			if (certificates == null)
 				throw new ArgumentNullException("certificates");
-			if (!CollectionUtilities.CheckElementsAreOfType(certificates, typeof(X509CertificateStructure)))
-				throw new ArgumentException("Must contain only 'X509CertificateStructure' objects", "certificates");
 
 			this.certificates = new DerSequence(
 				Asn1EncodableVector.FromEnumerable(certificates));
diff --git a/crypto/src/asn1/esf/CompleteCertificateRefs.cs b/crypto/src/asn1/esf/CompleteCertificateRefs.cs
index af93700be..2ed66e3dc 100644
--- a/crypto/src/asn1/esf/CompleteCertificateRefs.cs
+++ b/crypto/src/asn1/esf/CompleteCertificateRefs.cs
@@ -1,8 +1,7 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
@@ -56,12 +55,10 @@ namespace Org.BouncyCastle.Asn1.Esf
 		}
 
 		public CompleteCertificateRefs(
-			IEnumerable otherCertIDs)
+			IEnumerable<OtherCertID> otherCertIDs)
 		{
 			if (otherCertIDs == null)
 				throw new ArgumentNullException("otherCertIDs");
-			if (!CollectionUtilities.CheckElementsAreOfType(otherCertIDs, typeof(OtherCertID)))
-				throw new ArgumentException("Must contain only 'OtherCertID' objects", "otherCertIDs");
 
 			this.otherCertIDs = new DerSequence(
 				Asn1EncodableVector.FromEnumerable(otherCertIDs));
diff --git a/crypto/src/asn1/esf/CompleteRevocationRefs.cs b/crypto/src/asn1/esf/CompleteRevocationRefs.cs
index 348e63fdb..9942cec8f 100644
--- a/crypto/src/asn1/esf/CompleteRevocationRefs.cs
+++ b/crypto/src/asn1/esf/CompleteRevocationRefs.cs
@@ -1,8 +1,7 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
@@ -56,12 +55,10 @@ namespace Org.BouncyCastle.Asn1.Esf
 		}
 
 		public CompleteRevocationRefs(
-			IEnumerable crlOcspRefs)
+			IEnumerable<CrlOcspRef> crlOcspRefs)
 		{
 			if (crlOcspRefs == null)
 				throw new ArgumentNullException("crlOcspRefs");
-			if (!CollectionUtilities.CheckElementsAreOfType(crlOcspRefs, typeof(CrlOcspRef)))
-				throw new ArgumentException("Must contain only 'CrlOcspRef' objects", "crlOcspRefs");
 
 			this.crlOcspRefs = new DerSequence(
 				Asn1EncodableVector.FromEnumerable(crlOcspRefs));
diff --git a/crypto/src/asn1/esf/CrlListID.cs b/crypto/src/asn1/esf/CrlListID.cs
index fbd4fb27c..d3c4365c5 100644
--- a/crypto/src/asn1/esf/CrlListID.cs
+++ b/crypto/src/asn1/esf/CrlListID.cs
@@ -1,8 +1,7 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
@@ -61,12 +60,10 @@ namespace Org.BouncyCastle.Asn1.Esf
 		}
 
 		public CrlListID(
-			IEnumerable crls)
+			IEnumerable<CrlValidatedID> crls)
 		{
 			if (crls == null)
 				throw new ArgumentNullException("crls");
-			if (!CollectionUtilities.CheckElementsAreOfType(crls, typeof(CrlValidatedID)))
-				throw new ArgumentException("Must contain only 'CrlValidatedID' objects", "crls");
 
 			this.crls = new DerSequence(
 				Asn1EncodableVector.FromEnumerable(crls));
diff --git a/crypto/src/asn1/esf/OcspListID.cs b/crypto/src/asn1/esf/OcspListID.cs
index 1c8edb16b..3918dfd42 100644
--- a/crypto/src/asn1/esf/OcspListID.cs
+++ b/crypto/src/asn1/esf/OcspListID.cs
@@ -1,8 +1,7 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
@@ -60,12 +59,10 @@ namespace Org.BouncyCastle.Asn1.Esf
 		}
 
 		public OcspListID(
-			IEnumerable ocspResponses)
+			IEnumerable<OcspResponsesID> ocspResponses)
 		{
 			if (ocspResponses == null)
 				throw new ArgumentNullException("ocspResponses");
-			if (!CollectionUtilities.CheckElementsAreOfType(ocspResponses, typeof(OcspResponsesID)))
-				throw new ArgumentException("Must contain only 'OcspResponsesID' objects", "ocspResponses");
 
 			this.ocspResponses = new DerSequence(
 				Asn1EncodableVector.FromEnumerable(ocspResponses));
diff --git a/crypto/src/asn1/esf/OtherSigningCertificate.cs b/crypto/src/asn1/esf/OtherSigningCertificate.cs
index 2b6d646bc..a4f4a0727 100644
--- a/crypto/src/asn1/esf/OtherSigningCertificate.cs
+++ b/crypto/src/asn1/esf/OtherSigningCertificate.cs
@@ -1,9 +1,8 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
@@ -74,28 +73,23 @@ namespace Org.BouncyCastle.Asn1.Esf
 		}
 
 		public OtherSigningCertificate(
-			IEnumerable certs)
+			IEnumerable<OtherCertID> certs)
 			: this(certs, null)
 		{
 		}
 
 		public OtherSigningCertificate(
-			IEnumerable	certs,
-			IEnumerable	policies)
+			IEnumerable<OtherCertID> certs,
+			IEnumerable<PolicyInformation> policies)
 		{
 			if (certs == null)
 				throw new ArgumentNullException("certs");
-			if (!CollectionUtilities.CheckElementsAreOfType(certs, typeof(OtherCertID)))
-				throw new ArgumentException("Must contain only 'OtherCertID' objects", "certs");
 
 			this.certs = new DerSequence(
 				Asn1EncodableVector.FromEnumerable(certs));
 
 			if (policies != null)
 			{
-				if (!CollectionUtilities.CheckElementsAreOfType(policies, typeof(PolicyInformation)))
-					throw new ArgumentException("Must contain only 'PolicyInformation' objects", "policies");
-
 				this.policies = new DerSequence(
 					Asn1EncodableVector.FromEnumerable(policies));
 			}
diff --git a/crypto/src/asn1/esf/RevocationValues.cs b/crypto/src/asn1/esf/RevocationValues.cs
index 5be080f05..682728dde 100644
--- a/crypto/src/asn1/esf/RevocationValues.cs
+++ b/crypto/src/asn1/esf/RevocationValues.cs
@@ -1,9 +1,8 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.Ocsp;
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
@@ -90,24 +89,18 @@ namespace Org.BouncyCastle.Asn1.Esf
 		}
 
 		public RevocationValues(
-			IEnumerable			crlVals,
-			IEnumerable			ocspVals,
-			OtherRevVals		otherRevVals)
+			IEnumerable<CertificateList> crlVals,
+			IEnumerable<BasicOcspResponse> ocspVals,
+			OtherRevVals otherRevVals)
 		{
 			if (crlVals != null)
 			{
-				if (!CollectionUtilities.CheckElementsAreOfType(crlVals, typeof(CertificateList)))
-					throw new ArgumentException("Must contain only 'CertificateList' objects", "crlVals");
-
 				this.crlVals = new DerSequence(
 					Asn1EncodableVector.FromEnumerable(crlVals));
 			}
 
 			if (ocspVals != null)
 			{
-				if (!CollectionUtilities.CheckElementsAreOfType(ocspVals, typeof(BasicOcspResponse)))
-					throw new ArgumentException("Must contain only 'BasicOcspResponse' objects", "ocspVals");
-
 				this.ocspVals = new DerSequence(
 					Asn1EncodableVector.FromEnumerable(ocspVals));
 			}
diff --git a/crypto/src/asn1/esf/SignaturePolicyId.cs b/crypto/src/asn1/esf/SignaturePolicyId.cs
index 7146bb4c1..21bb40560 100644
--- a/crypto/src/asn1/esf/SignaturePolicyId.cs
+++ b/crypto/src/asn1/esf/SignaturePolicyId.cs
@@ -1,8 +1,7 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
@@ -85,9 +84,9 @@ namespace Org.BouncyCastle.Asn1.Esf
 		}
 
 		public SignaturePolicyId(
-			DerObjectIdentifier		sigPolicyIdentifier,
-			OtherHashAlgAndValue	sigPolicyHash,
-			IEnumerable				sigPolicyQualifiers)
+			DerObjectIdentifier sigPolicyIdentifier,
+			OtherHashAlgAndValue sigPolicyHash,
+			IEnumerable<SigPolicyQualifierInfo> sigPolicyQualifiers)
 		{
 			if (sigPolicyIdentifier == null)
 				throw new ArgumentNullException("sigPolicyIdentifier");
@@ -99,9 +98,6 @@ namespace Org.BouncyCastle.Asn1.Esf
 
 			if (sigPolicyQualifiers != null)
 			{
-				if (!CollectionUtilities.CheckElementsAreOfType(sigPolicyQualifiers, typeof(SigPolicyQualifierInfo)))
-					throw new ArgumentException("Must contain only 'SigPolicyQualifierInfo' objects", "sigPolicyQualifiers");
-
 				this.sigPolicyQualifiers = new DerSequence(
 					Asn1EncodableVector.FromEnumerable(sigPolicyQualifiers));
 			}
diff --git a/crypto/src/asn1/gm/GMNamedCurves.cs b/crypto/src/asn1/gm/GMNamedCurves.cs
index f906a2b95..fec0c1401 100644
--- a/crypto/src/asn1/gm/GMNamedCurves.cs
+++ b/crypto/src/asn1/gm/GMNamedCurves.cs
@@ -1,22 +1,18 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Math.EC;
 using Org.BouncyCastle.Math.EC.Multiplier;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Asn1.GM
 {
-    public sealed class GMNamedCurves
+    /// <summary>Elliptic curve registry for GM.</summary>
+    public static class GMNamedCurves
     {
-        private GMNamedCurves()
-        {
-        }
-
         private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding)
         {
             X9ECPoint G = new X9ECPoint(curve, Hex.DecodeStrict(encoding));
@@ -34,9 +30,6 @@ namespace Org.BouncyCastle.Asn1.GM
             return new BigInteger(1, Hex.DecodeStrict(hex));
         }
 
-        /*
-         * sm2p256v1
-         */
         internal class SM2P256V1Holder
             : X9ECParametersHolder
         {
@@ -67,9 +60,6 @@ namespace Org.BouncyCastle.Asn1.GM
             }
         }
 
-        /*
-         * wapip192v1
-         */
         internal class WapiP192V1Holder
             : X9ECParametersHolder
         {
@@ -100,17 +90,16 @@ namespace Org.BouncyCastle.Asn1.GM
             }
         }
 
+        private static readonly Dictionary<string, DerObjectIdentifier> objIds =
+            new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
+        private static readonly Dictionary<DerObjectIdentifier, X9ECParametersHolder> curves =
+            new Dictionary<DerObjectIdentifier, X9ECParametersHolder>();
+        private static readonly Dictionary<DerObjectIdentifier, string> names =
+            new Dictionary<DerObjectIdentifier, string>();
 
-        private static readonly IDictionary objIds = Platform.CreateHashtable();
-        private static readonly IDictionary curves = Platform.CreateHashtable();
-        private static readonly IDictionary names = Platform.CreateHashtable();
-
-        private static void DefineCurve(
-            string					name,
-            DerObjectIdentifier		oid,
-            X9ECParametersHolder	holder)
+        private static void DefineCurve(string name, DerObjectIdentifier oid, X9ECParametersHolder holder)
         {
-            objIds.Add(Platform.ToUpperInvariant(name), oid);
+            objIds.Add(name, oid);
             names.Add(oid, name);
             curves.Add(oid, holder);
         }
@@ -121,63 +110,64 @@ namespace Org.BouncyCastle.Asn1.GM
             DefineCurve("sm2p256v1", GMObjectIdentifiers.sm2p256v1, SM2P256V1Holder.Instance);
         }
 
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParameters GetByName(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
             return oid == null ? null : GetByOid(oid);
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given name.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParametersHolder GetByNameLazy(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
             return oid == null ? null : GetByOidLazy(oid);
         }
 
-        /**
-         * return the X9ECParameters object for the named curve represented by
-         * the passed in object identifier. Null if the curve isn't present.
-         *
-         * @param oid an object identifier representing a named curve, if present.
-         */
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParameters GetByOid(DerObjectIdentifier oid)
         {
-            X9ECParametersHolder holder = GetByOidLazy(oid);
-            return holder == null ? null : holder.Parameters;
+            return GetByOidLazy(oid)?.Parameters;
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParametersHolder GetByOidLazy(DerObjectIdentifier oid)
         {
-            return (X9ECParametersHolder)curves[oid];
+            return curves.TryGetValue(oid, out var holder) ? holder : null;
         }
 
-        /**
-         * return the object identifier signified by the passed in name. Null
-         * if there is no object identifier associated with name.
-         *
-         * @return the object identifier associated with name, if present.
-         */
-        public static DerObjectIdentifier GetOid(
-            string name)
+        /// <summary>Look up the name of the curve with the given <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
+        public static string GetName(DerObjectIdentifier oid)
         {
-            return (DerObjectIdentifier)objIds[Platform.ToUpperInvariant(name)];
+            return names.TryGetValue(oid, out var name) ? name : null;
         }
 
-        /**
-         * return the named curve name represented by the given object identifier.
-         */
-        public static string GetName(
-            DerObjectIdentifier oid)
+        /// <summary>Look up the <see cref="DerObjectIdentifier">OID</see> of the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
+        public static DerObjectIdentifier GetOid(string name)
         {
-            return (string)names[oid];
+            return objIds.TryGetValue(name, out var oid) ? oid : null;
         }
 
-        /**
-         * returns an enumeration containing the name strings for curves
-         * contained in this structure.
-         */
-        public static IEnumerable Names
+        /// <summary>Enumerate the available curve names in this registry.</summary>
+        public static IEnumerable<string> Names
         {
-            get { return new EnumerableProxy(names.Values); }
+            get { return CollectionUtilities.Proxy(objIds.Keys); }
         }
     }
 }
diff --git a/crypto/src/asn1/nist/NISTNamedCurves.cs b/crypto/src/asn1/nist/NISTNamedCurves.cs
index ee256cc2b..a8bc56549 100644
--- a/crypto/src/asn1/nist/NISTNamedCurves.cs
+++ b/crypto/src/asn1/nist/NISTNamedCurves.cs
@@ -1,31 +1,26 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
-using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Sec;
 using Org.BouncyCastle.Asn1.X9;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Asn1.Nist
 {
-    /**
-    * Utility class for fetching curves using their NIST names as published in FIPS-PUB 186-3
-    */
-    public sealed class NistNamedCurves
+    /// <summary>Elliptic curve registry for NIST curves.</summary>
+    public static class NistNamedCurves
     {
-        private NistNamedCurves()
-        {
-        }
+        private static readonly Dictionary<string, DerObjectIdentifier> objIds =
+            new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
+        private static readonly Dictionary<DerObjectIdentifier, string> names =
+            new Dictionary<DerObjectIdentifier, string>();
 
-        private static readonly IDictionary objIds = Platform.CreateHashtable();
-        private static readonly IDictionary names = Platform.CreateHashtable();
-
-        private static void DefineCurveAlias(
-            string				name,
-            DerObjectIdentifier	oid)
+        private static void DefineCurveAlias(string name, DerObjectIdentifier oid)
         {
-            objIds.Add(Platform.ToUpperInvariant(name), oid);
+            if (SecNamedCurves.GetByOidLazy(oid) == null)
+                throw new InvalidOperationException();
+
+            objIds.Add(name, oid);
             names.Add(oid, name);
         }
 
@@ -50,62 +45,64 @@ namespace Org.BouncyCastle.Asn1.Nist
             DefineCurveAlias("P-521", SecObjectIdentifiers.SecP521r1);
         }
 
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParameters GetByName(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
-            return oid == null ? null : SecNamedCurves.GetByOid(oid);
+            return oid == null ? null : GetByOid(oid);
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given name.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParametersHolder GetByNameLazy(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
-            return oid == null ? null : SecNamedCurves.GetByOidLazy(oid);
+            return oid == null ? null : GetByOidLazy(oid);
         }
 
-        /**
-        * return the X9ECParameters object for the named curve represented by
-        * the passed in object identifier. Null if the curve isn't present.
-        *
-        * @param oid an object identifier representing a named curve, if present.
-        */
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParameters GetByOid(DerObjectIdentifier oid)
         {
-            return names.Contains(oid) ? SecNamedCurves.GetByOid(oid) : null;
+            return GetByOidLazy(oid)?.Parameters;
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParametersHolder GetByOidLazy(DerObjectIdentifier oid)
         {
-            return names.Contains(oid) ? SecNamedCurves.GetByOidLazy(oid) : null;
+            return names.ContainsKey(oid) ? SecNamedCurves.GetByOidLazy(oid) : null;
         }
 
-        /**
-        * return the object identifier signified by the passed in name. Null
-        * if there is no object identifier associated with name.
-        *
-        * @return the object identifier associated with name, if present.
-        */
-        public static DerObjectIdentifier GetOid(
-            string name)
+        /// <summary>Look up the name of the curve with the given <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
+        public static string GetName(DerObjectIdentifier oid)
         {
-            return (DerObjectIdentifier) objIds[Platform.ToUpperInvariant(name)];
+            return names.TryGetValue(oid, out var name) ? name : null;
         }
 
-        /**
-        * return the named curve name represented by the given object identifier.
-        */
-        public static string GetName(
-            DerObjectIdentifier  oid)
+        /// <summary>Look up the <see cref="DerObjectIdentifier">OID</see> of the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
+        public static DerObjectIdentifier GetOid(string name)
         {
-            return (string) names[oid];
+            return objIds.TryGetValue(name, out var oid) ? oid : null;
         }
 
-        /**
-        * returns an enumeration containing the name strings for curves
-        * contained in this structure.
-        */
-        public static IEnumerable Names
+        /// <summary>Enumerate the available curve names in this registry.</summary>
+        public static IEnumerable<string> Names
         {
-            get { return new EnumerableProxy(names.Values); }
+            get { return CollectionUtilities.Proxy(objIds.Keys); }
         }
     }
 }
diff --git a/crypto/src/asn1/sec/SECNamedCurves.cs b/crypto/src/asn1/sec/SECNamedCurves.cs
index ad2f3e333..c0a783ec6 100644
--- a/crypto/src/asn1/sec/SECNamedCurves.cs
+++ b/crypto/src/asn1/sec/SECNamedCurves.cs
@@ -1,24 +1,19 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
-using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Math.EC;
 using Org.BouncyCastle.Math.EC.Endo;
 using Org.BouncyCastle.Math.EC.Multiplier;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Asn1.Sec
 {
-    public sealed class SecNamedCurves
+    /// <summary>Elliptic curve registry for the SEC standard.</summary>
+    public static class SecNamedCurves
     {
-        private SecNamedCurves()
-        {
-        }
-
         private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding)
         {
             X9ECPoint G = new X9ECPoint(curve, Hex.DecodeStrict(encoding));
@@ -41,9 +36,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             return new BigInteger(1, Hex.DecodeStrict(hex));
         }
 
-        /*
-         * secp112r1
-         */
         internal class Secp112r1Holder
             : X9ECParametersHolder
         {
@@ -75,9 +67,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp112r2
-         */
         internal class Secp112r2Holder
             : X9ECParametersHolder
         {
@@ -109,9 +98,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp128r1
-         */
         internal class Secp128r1Holder
             : X9ECParametersHolder
         {
@@ -143,9 +129,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp128r2
-         */
         internal class Secp128r2Holder
             : X9ECParametersHolder
         {
@@ -177,9 +160,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp160k1
-         */
         internal class Secp160k1Holder
             : X9ECParametersHolder
         {
@@ -225,9 +205,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp160r1
-         */
         internal class Secp160r1Holder
             : X9ECParametersHolder
         {
@@ -259,9 +236,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp160r2
-         */
         internal class Secp160r2Holder
             : X9ECParametersHolder
         {
@@ -293,9 +267,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp192k1
-         */
         internal class Secp192k1Holder
             : X9ECParametersHolder
         {
@@ -341,9 +312,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp192r1
-         */
         internal class Secp192r1Holder
             : X9ECParametersHolder
         {
@@ -375,9 +343,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp224k1
-         */
         internal class Secp224k1Holder
             : X9ECParametersHolder
         {
@@ -423,9 +388,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp224r1
-         */
         internal class Secp224r1Holder
             : X9ECParametersHolder
         {
@@ -457,9 +419,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp256k1
-         */
         internal class Secp256k1Holder
             : X9ECParametersHolder
         {
@@ -505,9 +464,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp256r1
-         */
         internal class Secp256r1Holder
             : X9ECParametersHolder
         {
@@ -539,9 +495,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp384r1
-         */
         internal class Secp384r1Holder
             : X9ECParametersHolder
         {
@@ -574,9 +527,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * secp521r1
-         */
         internal class Secp521r1Holder
             : X9ECParametersHolder
         {
@@ -609,9 +559,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect113r1
-         */
         internal class Sect113r1Holder
             : X9ECParametersHolder
         {
@@ -644,9 +591,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect113r2
-         */
         internal class Sect113r2Holder
             : X9ECParametersHolder
         {
@@ -679,9 +623,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect131r1
-         */
         internal class Sect131r1Holder
             : X9ECParametersHolder
         {
@@ -716,9 +657,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect131r2
-         */
         internal class Sect131r2Holder
             : X9ECParametersHolder
         {
@@ -753,9 +691,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect163k1
-         */
         internal class Sect163k1Holder
             : X9ECParametersHolder
         {
@@ -790,9 +725,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect163r1
-         */
         internal class Sect163r1Holder
             : X9ECParametersHolder
         {
@@ -827,9 +759,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect163r2
-         */
         internal class Sect163r2Holder
             : X9ECParametersHolder
         {
@@ -864,9 +793,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect193r1
-         */
         internal class Sect193r1Holder
             : X9ECParametersHolder
         {
@@ -899,9 +825,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect193r2
-         */
         internal class Sect193r2Holder
             : X9ECParametersHolder
         {
@@ -934,9 +857,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect233k1
-         */
         internal class Sect233k1Holder
             : X9ECParametersHolder
         {
@@ -969,9 +889,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect233r1
-         */
         internal class Sect233r1Holder
             : X9ECParametersHolder
         {
@@ -1004,9 +921,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect239k1
-         */
         internal class Sect239k1Holder
             : X9ECParametersHolder
         {
@@ -1039,9 +953,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect283k1
-         */
         internal class Sect283k1Holder
             : X9ECParametersHolder
         {
@@ -1077,9 +988,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect283r1
-         */
         internal class Sect283r1Holder
             : X9ECParametersHolder
         {
@@ -1115,9 +1023,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect409k1
-         */
         internal class Sect409k1Holder
             : X9ECParametersHolder
         {
@@ -1151,9 +1056,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect409r1
-         */
         internal class Sect409r1Holder
             : X9ECParametersHolder
         {
@@ -1187,9 +1089,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect571k1
-         */
         internal class Sect571k1Holder
             : X9ECParametersHolder
         {
@@ -1225,9 +1124,6 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
-        /*
-         * sect571r1
-         */
         internal class Sect571r1Holder
             : X9ECParametersHolder
         {
@@ -1263,17 +1159,16 @@ namespace Org.BouncyCastle.Asn1.Sec
             }
         }
 
+        private static readonly Dictionary<string, DerObjectIdentifier> objIds =
+            new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
+        private static readonly Dictionary<DerObjectIdentifier, X9ECParametersHolder> curves =
+            new Dictionary<DerObjectIdentifier, X9ECParametersHolder>();
+        private static readonly Dictionary<DerObjectIdentifier, string> names =
+            new Dictionary<DerObjectIdentifier, string>();
 
-        private static readonly IDictionary objIds = Platform.CreateHashtable();
-        private static readonly IDictionary curves = Platform.CreateHashtable();
-        private static readonly IDictionary names = Platform.CreateHashtable();
-
-        private static void DefineCurve(
-            string					name,
-            DerObjectIdentifier		oid,
-            X9ECParametersHolder	holder)
+        private static void DefineCurve(string name, DerObjectIdentifier oid, X9ECParametersHolder holder)
         {
-            objIds.Add(Platform.ToUpperInvariant(name), oid);
+            objIds.Add(name, oid);
             names.Add(oid, name);
             curves.Add(oid, holder);
         }
@@ -1316,63 +1211,64 @@ namespace Org.BouncyCastle.Asn1.Sec
             DefineCurve("sect571r1", SecObjectIdentifiers.SecT571r1, Sect571r1Holder.Instance);
         }
 
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParameters GetByName(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
             return oid == null ? null : GetByOid(oid);
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given name.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParametersHolder GetByNameLazy(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
             return oid == null ? null : GetByOidLazy(oid);
         }
 
-        /**
-         * return the X9ECParameters object for the named curve represented by
-         * the passed in object identifier. Null if the curve isn't present.
-         *
-         * @param oid an object identifier representing a named curve, if present.
-         */
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParameters GetByOid(DerObjectIdentifier oid)
         {
-            X9ECParametersHolder holder = GetByOidLazy(oid);
-            return holder == null ? null : holder.Parameters;
+            return GetByOidLazy(oid)?.Parameters;
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParametersHolder GetByOidLazy(DerObjectIdentifier oid)
         {
-            return (X9ECParametersHolder)curves[oid];
+            return curves.TryGetValue(oid, out var holder) ? holder : null;
         }
 
-        /**
-         * return the object identifier signified by the passed in name. Null
-         * if there is no object identifier associated with name.
-         *
-         * @return the object identifier associated with name, if present.
-         */
-        public static DerObjectIdentifier GetOid(
-            string name)
+        /// <summary>Look up the name of the curve with the given <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
+        public static string GetName(DerObjectIdentifier oid)
         {
-            return (DerObjectIdentifier)objIds[Platform.ToUpperInvariant(name)];
+            return names.TryGetValue(oid, out var name) ? name : null;
         }
 
-        /**
-         * return the named curve name represented by the given object identifier.
-         */
-        public static string GetName(
-            DerObjectIdentifier oid)
+        /// <summary>Look up the <see cref="DerObjectIdentifier">OID</see> of the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
+        public static DerObjectIdentifier GetOid(string name)
         {
-            return (string)names[oid];
+            return objIds.TryGetValue(name, out var oid) ? oid : null;
         }
 
-        /**
-         * returns an enumeration containing the name strings for curves
-         * contained in this structure.
-         */
-        public static IEnumerable Names
+        /// <summary>Enumerate the available curve names in this registry.</summary>
+        public static IEnumerable<string> Names
         {
-            get { return new EnumerableProxy(names.Values); }
+            get { return CollectionUtilities.Proxy(objIds.Keys); }
         }
     }
 }
diff --git a/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs b/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs
index dcc160016..b863babce 100644
--- a/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs
+++ b/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs
@@ -1,20 +1,18 @@
-using System.Collections;
+using System;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Math.EC;
 using Org.BouncyCastle.Math.EC.Multiplier;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Asn1.TeleTrust
 {
-    /**
-    * elliptic curves defined in "ECC Brainpool Standard Curves and Curve Generation"
-    * http://www.ecc-brainpool.org/download/draft_pkix_additional_ecc_dp.txt
-    */
-    public class TeleTrusTNamedCurves
+    /// <summary>Elliptic curve registry for curves defined in "ECC Brainpool Standard Curves and Curve Generation"
+    /// http://www.ecc-brainpool.org/download/draft_pkix_additional_ecc_dp.txt .</summary>
+    public static class TeleTrusTNamedCurves
     {
         private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding)
         {
@@ -460,17 +458,16 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
             }
         }
 
+        private static readonly Dictionary<string, DerObjectIdentifier> objIds =
+            new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
+        private static readonly Dictionary<DerObjectIdentifier, X9ECParametersHolder> curves =
+            new Dictionary<DerObjectIdentifier, X9ECParametersHolder>();
+        private static readonly Dictionary<DerObjectIdentifier, string> names =
+            new Dictionary<DerObjectIdentifier, string>();
 
-        private static readonly IDictionary objIds = Platform.CreateHashtable();
-        private static readonly IDictionary curves = Platform.CreateHashtable();
-        private static readonly IDictionary names = Platform.CreateHashtable();
-
-        private static void DefineCurve(
-            string					name,
-            DerObjectIdentifier		oid,
-            X9ECParametersHolder	holder)
+        private static void DefineCurve(string name, DerObjectIdentifier oid, X9ECParametersHolder holder)
         {
-            objIds.Add(Platform.ToUpperInvariant(name), oid);
+            objIds.Add(name, oid);
             names.Add(oid, name);
             curves.Add(oid, holder);
         }
@@ -493,70 +490,64 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
             DefineCurve("brainpoolP512t1", TeleTrusTObjectIdentifiers.BrainpoolP512T1, BrainpoolP512t1Holder.Instance);
         }
 
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParameters GetByName(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
             return oid == null ? null : GetByOid(oid);
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given name.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParametersHolder GetByNameLazy(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
             return oid == null ? null : GetByOidLazy(oid);
         }
 
-        /**
-        * return the X9ECParameters object for the named curve represented by
-        * the passed in object identifier. Null if the curve isn't present.
-        *
-        * @param oid an object identifier representing a named curve, if present.
-        */
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParameters GetByOid(DerObjectIdentifier oid)
         {
-            X9ECParametersHolder holder = GetByOidLazy(oid);
-            return holder == null ? null : holder.Parameters;
+            return GetByOidLazy(oid)?.Parameters;
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParametersHolder GetByOidLazy(DerObjectIdentifier oid)
         {
-            return (X9ECParametersHolder)curves[oid];
-        }
-
-        /**
-        * return the object identifier signified by the passed in name. Null
-        * if there is no object identifier associated with name.
-        *
-        * @return the object identifier associated with name, if present.
-        */
-        public static DerObjectIdentifier GetOid(
-            string name)
-        {
-            return (DerObjectIdentifier)objIds[Platform.ToUpperInvariant(name)];
+            return curves.TryGetValue(oid, out var holder) ? holder : null;
         }
 
-        /**
-        * return the named curve name represented by the given object identifier.
-        */
-        public static string GetName(
-            DerObjectIdentifier oid)
+        /// <summary>Look up the name of the curve with the given <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
+        public static string GetName(DerObjectIdentifier oid)
         {
-            return (string)names[oid];
+            return names.TryGetValue(oid, out var name) ? name : null;
         }
 
-        /**
-         * returns an enumeration containing the name strings for curves
-         * contained in this structure.
-         */
-        public static IEnumerable Names
+        /// <summary>Look up the <see cref="DerObjectIdentifier">OID</see> of the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
+        public static DerObjectIdentifier GetOid(string name)
         {
-            get { return new EnumerableProxy(names.Values); }
+            return objIds.TryGetValue(name, out var oid) ? oid : null;
         }
 
-        public static DerObjectIdentifier GetOid(
-            short	curvesize,
-            bool	twisted)
+        /// <summary>Enumerate the available curve names in this registry.</summary>
+        public static IEnumerable<string> Names
         {
-            return GetOid("brainpoolP" + curvesize + (twisted ? "t" : "r") + "1");
+            get { return CollectionUtilities.Proxy(objIds.Keys); }
         }
     }
 }
diff --git a/crypto/src/asn1/util/Asn1Dump.cs b/crypto/src/asn1/util/Asn1Dump.cs
index 406511a72..64d88c373 100644
--- a/crypto/src/asn1/util/Asn1Dump.cs
+++ b/crypto/src/asn1/util/Asn1Dump.cs
@@ -243,6 +243,17 @@ namespace Org.BouncyCastle.Asn1.Utilities
             }
         }
 
+        /// <summary>Parse ASN.1 objects from input <see cref="Stream"/>, and write them to the output.</summary>
+        public static void Dump(Stream input, TextWriter output)
+        {
+            Asn1InputStream asn1InputStream = new Asn1InputStream(input);
+            Asn1Object asn1Object;
+            while ((asn1Object = asn1InputStream.ReadObject()) != null)
+            {
+                output.Write(DumpAsString(asn1Object));
+            }
+        }
+
         /**
          * dump out a DER object as a formatted string, in non-verbose mode
          *
diff --git a/crypto/src/asn1/util/Dump.cs b/crypto/src/asn1/util/Dump.cs
deleted file mode 100644
index e313fe879..000000000
--- a/crypto/src/asn1/util/Dump.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-#if !PORTABLE
-using System;
-using System.IO;
-
-using Org.BouncyCastle.Utilities;
-
-namespace Org.BouncyCastle.Asn1.Utilities
-{
-    public sealed class Dump
-    {
-        private Dump()
-        {
-        }
-
-        public static void Main(string[] args)
-        {
-            FileStream fIn = File.OpenRead(args[0]);
-            Asn1InputStream bIn = new Asn1InputStream(fIn);
-
-			Asn1Object obj;
-			while ((obj = bIn.ReadObject()) != null)
-            {
-                Console.WriteLine(Asn1Dump.DumpAsString(obj));
-            }
-
-            Platform.Dispose(bIn);
-        }
-    }
-}
-#endif
diff --git a/crypto/src/asn1/x9/ECNamedCurveTable.cs b/crypto/src/asn1/x9/ECNamedCurveTable.cs
index f0d70272b..9243c341e 100644
--- a/crypto/src/asn1/x9/ECNamedCurveTable.cs
+++ b/crypto/src/asn1/x9/ECNamedCurveTable.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.Anssi;
 using Org.BouncyCastle.Asn1.CryptoPro;
@@ -7,23 +7,14 @@ using Org.BouncyCastle.Asn1.GM;
 using Org.BouncyCastle.Asn1.Nist;
 using Org.BouncyCastle.Asn1.Sec;
 using Org.BouncyCastle.Asn1.TeleTrust;
-using Org.BouncyCastle.Utilities;
-using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Asn1.X9
 {
-    /**
-     * A general class that reads all X9.62 style EC curve tables.
-     */
+    /// <summary>A unified elliptic curve registry of the various standard-specific registries.</summary>
     public class ECNamedCurveTable
     {
-        /**
-         * return a X9ECParameters object representing the passed in named
-         * curve. The routine returns null if the curve is not present.
-         *
-         * @param name the name of the curve requested
-         * @return an X9ECParameters object or null if the curve is not available.
-         */
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParameters GetByName(string name)
         {
             X9ECParameters ecP = X962NamedCurves.GetByName(name);
@@ -45,7 +36,7 @@ namespace Org.BouncyCastle.Asn1.X9
             }
             if (ecP == null)
             {
-                ecP = ECGost3410NamedCurves.GetByNameX9(name);
+                ecP = ECGost3410NamedCurves.GetByName(name);
             }
             if (ecP == null)
             {
@@ -54,6 +45,12 @@ namespace Org.BouncyCastle.Asn1.X9
             return ecP;
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given name.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParametersHolder GetByNameLazy(string name)
         {
             X9ECParametersHolder holder = X962NamedCurves.GetByNameLazy(name);
@@ -84,6 +81,76 @@ namespace Org.BouncyCastle.Asn1.X9
             return holder;
         }
 
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
+        public static X9ECParameters GetByOid(DerObjectIdentifier oid)
+        {
+            X9ECParameters ecP = X962NamedCurves.GetByOid(oid);
+            if (ecP == null)
+            {
+                ecP = SecNamedCurves.GetByOid(oid);
+            }
+
+            // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
+
+            if (ecP == null)
+            {
+                ecP = TeleTrusTNamedCurves.GetByOid(oid);
+            }
+            if (ecP == null)
+            {
+                ecP = AnssiNamedCurves.GetByOid(oid);
+            }
+            if (ecP == null)
+            {
+                ecP = ECGost3410NamedCurves.GetByOid(oid);
+            }
+            if (ecP == null)
+            {
+                ecP = GMNamedCurves.GetByOid(oid);
+            }
+            return ecP;
+        }
+
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
+        public static X9ECParametersHolder GetByOidLazy(DerObjectIdentifier oid)
+        {
+            X9ECParametersHolder holder = X962NamedCurves.GetByOidLazy(oid);
+            if (null == holder)
+            {
+                holder = SecNamedCurves.GetByOidLazy(oid);
+            }
+
+            // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
+
+            if (null == holder)
+            {
+                holder = TeleTrusTNamedCurves.GetByOidLazy(oid);
+            }
+            if (null == holder)
+            {
+                holder = AnssiNamedCurves.GetByOidLazy(oid);
+            }
+            if (null == holder)
+            {
+                holder = ECGost3410NamedCurves.GetByOidLazy(oid);
+            }
+            if (null == holder)
+            {
+                holder = GMNamedCurves.GetByOidLazy(oid);
+            }
+            return holder;
+        }
+
+        /// <summary>Look up the name of the curve with the given <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static string GetName(DerObjectIdentifier oid)
         {
             string name = X962NamedCurves.GetName(oid);
@@ -114,12 +181,8 @@ namespace Org.BouncyCastle.Asn1.X9
             return name;
         }
 
-        /**
-         * return the object identifier signified by the passed in name. Null
-         * if there is no object identifier associated with name.
-         *
-         * @return the object identifier associated with name, if present.
-         */
+        /// <summary>Look up the <see cref="DerObjectIdentifier">OID</see> of the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
         public static DerObjectIdentifier GetOid(string name)
         {
             DerObjectIdentifier oid = X962NamedCurves.GetOid(name);
@@ -150,89 +213,20 @@ namespace Org.BouncyCastle.Asn1.X9
             return oid;
         }
 
-        /**
-         * return a X9ECParameters object representing the passed in named
-         * curve.
-         *
-         * @param oid the object id of the curve requested
-         * @return an X9ECParameters object or null if the curve is not available.
-         */
-        public static X9ECParameters GetByOid(DerObjectIdentifier oid)
-        {
-            X9ECParameters ecP = X962NamedCurves.GetByOid(oid);
-            if (ecP == null)
-            {
-                ecP = SecNamedCurves.GetByOid(oid);
-            }
-
-            // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
-
-            if (ecP == null)
-            {
-                ecP = TeleTrusTNamedCurves.GetByOid(oid);
-            }
-            if (ecP == null)
-            {
-                ecP = AnssiNamedCurves.GetByOid(oid);
-            }
-            if (ecP == null)
-            {
-                ecP = ECGost3410NamedCurves.GetByOidX9(oid);
-            }
-            if (ecP == null)
-            {
-                ecP = GMNamedCurves.GetByOid(oid);
-            }
-            return ecP;
-        }
-
-        public static X9ECParametersHolder GetByOidLazy(DerObjectIdentifier oid)
-        {
-            X9ECParametersHolder holder = X962NamedCurves.GetByOidLazy(oid);
-            if (null == holder)
-            {
-                holder = SecNamedCurves.GetByOidLazy(oid);
-            }
-
-            // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
-
-            if (null == holder)
-            {
-                holder = TeleTrusTNamedCurves.GetByOidLazy(oid);
-            }
-            if (null == holder)
-            {
-                holder = AnssiNamedCurves.GetByOidLazy(oid);
-            }
-            if (null == holder)
-            {
-                holder = ECGost3410NamedCurves.GetByOidLazy(oid);
-            }
-            if (null == holder)
-            {
-                holder = GMNamedCurves.GetByOidLazy(oid);
-            }
-            return holder;
-        }
-
-        /**
-         * return an enumeration of the names of the available curves.
-         *
-         * @return an enumeration of the names of the available curves.
-         */
-        public static IEnumerable Names
+        /// <summary>Enumerate the available curve names in all the registries.</summary>
+        public static IEnumerable<string> Names
         {
             get
             {
-                IList v = Platform.CreateArrayList();
-                CollectionUtilities.AddRange(v, X962NamedCurves.Names);
-                CollectionUtilities.AddRange(v, SecNamedCurves.Names);
-                CollectionUtilities.AddRange(v, NistNamedCurves.Names);
-                CollectionUtilities.AddRange(v, TeleTrusTNamedCurves.Names);
-                CollectionUtilities.AddRange(v, AnssiNamedCurves.Names);
-                CollectionUtilities.AddRange(v, ECGost3410NamedCurves.Names);
-                CollectionUtilities.AddRange(v, GMNamedCurves.Names);
-                return v;
+                var result = new List<string>();
+                result.AddRange(X962NamedCurves.Names);
+                result.AddRange(SecNamedCurves.Names);
+                result.AddRange(NistNamedCurves.Names);
+                result.AddRange(TeleTrusTNamedCurves.Names);
+                result.AddRange(AnssiNamedCurves.Names);
+                result.AddRange(ECGost3410NamedCurves.Names);
+                result.AddRange(GMNamedCurves.Names);
+                return result;
             }
         }
     }
diff --git a/crypto/src/asn1/x9/X962NamedCurves.cs b/crypto/src/asn1/x9/X962NamedCurves.cs
index 4fd3c8d1e..e0fb625f9 100644
--- a/crypto/src/asn1/x9/X962NamedCurves.cs
+++ b/crypto/src/asn1/x9/X962NamedCurves.cs
@@ -1,24 +1,17 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Math.EC;
 using Org.BouncyCastle.Math.EC.Multiplier;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Asn1.X9
 {
-    /**
-     * table of the current named curves defined in X.962 EC-DSA.
-     */
-    public sealed class X962NamedCurves
+    /// <summary>Elliptic curve registry for the curves defined in X.962 EC-DSA.</summary>
+    public static class X962NamedCurves
     {
-        private X962NamedCurves()
-        {
-        }
-
         private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding)
         {
             X9ECPoint G = new X9ECPoint(curve, Hex.DecodeStrict(encoding));
@@ -253,9 +246,6 @@ namespace Org.BouncyCastle.Asn1.X9
             }
         }
 
-        /*
-         * F2m Curves
-         */
         internal class C2pnb163v1Holder
             : X9ECParametersHolder
         {
@@ -768,17 +758,16 @@ namespace Org.BouncyCastle.Asn1.X9
             }
         }
 
+        private static readonly Dictionary<string, DerObjectIdentifier> objIds =
+            new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
+        private static readonly Dictionary<DerObjectIdentifier, X9ECParametersHolder> curves =
+            new Dictionary<DerObjectIdentifier, X9ECParametersHolder>();
+        private static readonly Dictionary<DerObjectIdentifier, string> names =
+            new Dictionary<DerObjectIdentifier, string>();
 
-        private static readonly IDictionary objIds = Platform.CreateHashtable();
-        private static readonly IDictionary curves = Platform.CreateHashtable();
-        private static readonly IDictionary names = Platform.CreateHashtable();
-
-        private static void DefineCurve(
-            string					name,
-            DerObjectIdentifier		oid,
-            X9ECParametersHolder	holder)
+        private static void DefineCurve(string name, DerObjectIdentifier oid, X9ECParametersHolder holder)
         {
-            objIds.Add(Platform.ToUpperInvariant(name), oid);
+            objIds.Add(name, oid);
             names.Add(oid, name);
             curves.Add(oid, holder);
         }
@@ -810,63 +799,64 @@ namespace Org.BouncyCastle.Asn1.X9
             DefineCurve("c2tnb431r1", X9ObjectIdentifiers.C2Tnb431r1, C2tnb431r1Holder.Instance);
         }
 
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParameters GetByName(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
             return oid == null ? null : GetByOid(oid);
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given name.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParametersHolder GetByNameLazy(string name)
         {
             DerObjectIdentifier oid = GetOid(name);
             return oid == null ? null : GetByOidLazy(oid);
         }
 
-        /**
-         * return the X9ECParameters object for the named curve represented by
-         * the passed in object identifier. Null if the curve isn't present.
-         *
-         * @param oid an object identifier representing a named curve, if present.
-         */
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParameters GetByOid(DerObjectIdentifier oid)
         {
-            X9ECParametersHolder holder = GetByOidLazy(oid);
-            return holder == null ? null : holder.Parameters;
+            return GetByOidLazy(oid)?.Parameters;
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParametersHolder GetByOidLazy(DerObjectIdentifier oid)
         {
-            return (X9ECParametersHolder)curves[oid];
+            return curves.TryGetValue(oid, out var holder) ? holder : null;
         }
 
-        /**
-         * return the object identifier signified by the passed in name. Null
-         * if there is no object identifier associated with name.
-         *
-         * @return the object identifier associated with name, if present.
-         */
-        public static DerObjectIdentifier GetOid(
-            string name)
+        /// <summary>Look up the name of the curve with the given <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
+        public static string GetName(DerObjectIdentifier oid)
         {
-            return (DerObjectIdentifier)objIds[Platform.ToUpperInvariant(name)];
+            return names.TryGetValue(oid, out var name) ? name : null;
         }
 
-        /**
-         * return the named curve name represented by the given object identifier.
-         */
-        public static string GetName(
-            DerObjectIdentifier oid)
+        /// <summary>Look up the <see cref="DerObjectIdentifier">OID</see> of the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
+        public static DerObjectIdentifier GetOid(string name)
         {
-            return (string)names[oid];
+            return objIds.TryGetValue(name, out var oid) ? oid : null;
         }
 
-        /**
-         * returns an enumeration containing the name strings for curves
-         * contained in this structure.
-         */
-        public static IEnumerable Names
+        /// <summary>Enumerate the available curve names in this registry.</summary>
+        public static IEnumerable<string> Names
         {
-            get { return new EnumerableProxy(names.Values); }
+            get { return CollectionUtilities.Proxy(objIds.Keys); }
         }
     }
 }
diff --git a/crypto/src/bcpg/ArmoredOutputStream.cs b/crypto/src/bcpg/ArmoredOutputStream.cs
index 97bcbde51..919325a73 100644
--- a/crypto/src/bcpg/ArmoredOutputStream.cs
+++ b/crypto/src/bcpg/ArmoredOutputStream.cs
@@ -103,7 +103,7 @@ namespace Org.BouncyCastle.Bcpg
         private static readonly string    footerStart = "-----END PGP ";
         private static readonly string    footerTail = "-----";
 
-        private static readonly string Version = "BCPG C# v" + AssemblyInfo.Version;
+        private static readonly string Version = "BCPG C# v" + typeof(ArmoredOutputStream).Assembly.GetName().Version;
 
         private readonly IDictionary headers;
 
diff --git a/crypto/src/bcpg/UnsupportedPacketVersionException.cs b/crypto/src/bcpg/UnsupportedPacketVersionException.cs
index 447d75286..d59404f7a 100644
--- a/crypto/src/bcpg/UnsupportedPacketVersionException.cs
+++ b/crypto/src/bcpg/UnsupportedPacketVersionException.cs
@@ -1,13 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Bcpg
 {
+    [Serializable]
     public class UnsupportedPacketVersionException
         : Exception
     {
-        public UnsupportedPacketVersionException(string msg)
-            : base(msg)
-        {
-        }
+		public UnsupportedPacketVersionException()
+			: base()
+		{
+		}
+
+		public UnsupportedPacketVersionException(string message)
+			: base(message)
+		{
+		}
+
+		public UnsupportedPacketVersionException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected UnsupportedPacketVersionException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
     }
 }
diff --git a/crypto/src/cmp/CmpException.cs b/crypto/src/cmp/CmpException.cs
index 6594e8f2a..6d3271a20 100644
--- a/crypto/src/cmp/CmpException.cs
+++ b/crypto/src/cmp/CmpException.cs
@@ -1,11 +1,14 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Cmp
 {
+    [Serializable]
     public class CmpException
         : Exception
     {
         public CmpException()
+            : base()
         {
         }
 
@@ -18,5 +21,10 @@ namespace Org.BouncyCastle.Cmp
             : base(message, innerException)
         {
         }
+
+        protected CmpException(SerializationInfo info, StreamingContext context)
+            : base(info, context)
+        {
+        }
     }
 }
diff --git a/crypto/src/cms/CMSAttributeTableGenerationException.cs b/crypto/src/cms/CMSAttributeTableGenerationException.cs
index 692be2804..977d60e5c 100644
--- a/crypto/src/cms/CMSAttributeTableGenerationException.cs
+++ b/crypto/src/cms/CMSAttributeTableGenerationException.cs
@@ -1,28 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Cms
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class CmsAttributeTableGenerationException
 		: CmsException
 	{
-		public CmsAttributeTableGenerationException()
-		{
-		}
+        public CmsAttributeTableGenerationException()
+            : base()
+        {
+        }
 
-		public CmsAttributeTableGenerationException(
-			string name)
-			: base(name)
-		{
-		}
+        public CmsAttributeTableGenerationException(string message)
+            : base(message)
+        {
+        }
 
-		public CmsAttributeTableGenerationException(
-			string		name,
-			Exception	e)
-			: base(name, e)
-		{
-		}
+        public CmsAttributeTableGenerationException(string message, Exception innerException)
+            : base(message, innerException)
+        {
+        }
+
+        protected CmsAttributeTableGenerationException(SerializationInfo info, StreamingContext context)
+            : base(info, context)
+        {
+        }
 	}
 }
diff --git a/crypto/src/cms/CMSException.cs b/crypto/src/cms/CMSException.cs
index 83de3f00e..eab32f916 100644
--- a/crypto/src/cms/CMSException.cs
+++ b/crypto/src/cms/CMSException.cs
@@ -1,27 +1,29 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Cms
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class CmsException
 		: Exception
 	{
 		public CmsException()
+			: base()
 		{
 		}
 
-		public CmsException(
-			string msg)
-			: base(msg)
+		public CmsException(string message)
+			: base(message)
 		{
 		}
 
-		public CmsException(
-			string		msg,
-			Exception	e)
-			: base(msg, e)
+		public CmsException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected CmsException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/cms/CMSStreamException.cs b/crypto/src/cms/CMSStreamException.cs
index c3b0f9621..42ae409f7 100644
--- a/crypto/src/cms/CMSStreamException.cs
+++ b/crypto/src/cms/CMSStreamException.cs
@@ -1,29 +1,31 @@
 using System;
 using System.IO;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Cms
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class CmsStreamException
         : IOException
     {
 		public CmsStreamException()
+			: base()
 		{
 		}
 
-		public CmsStreamException(
-			string name)
-			: base(name)
-        {
-        }
+		public CmsStreamException(string message)
+			: base(message)
+		{
+		}
 
-		public CmsStreamException(
-			string		name,
-			Exception	e)
-			: base(name, e)
-        {
-        }
-    }
+		public CmsStreamException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected CmsStreamException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
diff --git a/crypto/src/crmf/CrmfException.cs b/crypto/src/crmf/CrmfException.cs
index 5ae13a0eb..9b1597400 100644
--- a/crypto/src/crmf/CrmfException.cs
+++ b/crypto/src/crmf/CrmfException.cs
@@ -1,22 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Crmf
 {
-    public class CrmfException
+	[Serializable]
+	public class CrmfException
         : Exception
     {
-        public CrmfException()
-        {
-        }
+		public CrmfException()
+			: base()
+		{
+		}
 
-        public CrmfException(string message)
-            : base(message)
-        {
-        }
+		public CrmfException(string message)
+			: base(message)
+		{
+		}
 
-        public CrmfException(string message, Exception innerException)
-            : base(message, innerException)
-        {
-        }
-    }
+		public CrmfException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected CrmfException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
diff --git a/crypto/src/crypto/CryptoException.cs b/crypto/src/crypto/CryptoException.cs
index c5ee938c7..e40cfbc04 100644
--- a/crypto/src/crypto/CryptoException.cs
+++ b/crypto/src/crypto/CryptoException.cs
@@ -1,28 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Crypto
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class CryptoException
 		: Exception
     {
-        public CryptoException()
-        {
-        }
+		public CryptoException()
+			: base()
+		{
+		}
 
-		public CryptoException(
-            string message)
+		public CryptoException(string message)
 			: base(message)
-        {
-        }
+		{
+		}
 
-		public CryptoException(
-            string		message,
-            Exception	exception)
-			: base(message, exception)
-        {
-        }
-    }
+		public CryptoException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected CryptoException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
diff --git a/crypto/src/crypto/DataLengthException.cs b/crypto/src/crypto/DataLengthException.cs
index 5dde879d1..909639144 100644
--- a/crypto/src/crypto/DataLengthException.cs
+++ b/crypto/src/crypto/DataLengthException.cs
@@ -1,42 +1,35 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Crypto
 {
-    /**
-     * this exception is thrown if a buffer that is meant to have output
-     * copied into it turns out to be too short, or if we've been given
-     * insufficient input. In general this exception will Get thrown rather
-     * than an ArrayOutOfBounds exception.
-     */
-#if !PORTABLE
-    [Serializable]
-#endif
+	/// <summary>This exception is thrown if a buffer that is meant to have output copied into it turns out to be too
+	/// short, or if we've been given insufficient input.</summary>
+	/// <remarks>
+	/// In general this exception will get thrown rather than an <see cref="IndexOutOfRangeException"/>.
+	/// </remarks>
+	[Serializable]
     public class DataLengthException
 		: CryptoException
 	{
-        /**
-        * base constructor.
-		*/
-        public DataLengthException()
-        {
-        }
+		public DataLengthException()
+			: base()
+		{
+		}
 
-		/**
-         * create a DataLengthException with the given message.
-         *
-         * @param message the message to be carried with the exception.
-         */
-        public DataLengthException(
-            string message)
+		public DataLengthException(string message)
 			: base(message)
-        {
+		{
+		}
+
+		public DataLengthException(string message, Exception innerException)
+			: base(message, innerException)
+		{
 		}
 
-		public DataLengthException(
-            string		message,
-            Exception	exception)
-			: base(message, exception)
-        {
-        }
+		protected DataLengthException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/crypto/InvalidCipherTextException.cs b/crypto/src/crypto/InvalidCipherTextException.cs
index 760ef3206..13ac86763 100644
--- a/crypto/src/crypto/InvalidCipherTextException.cs
+++ b/crypto/src/crypto/InvalidCipherTextException.cs
@@ -1,40 +1,31 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Crypto
 {
-    /**
-     * this exception is thrown whenever we find something we don't expect in a
-     * message.
-     */
-#if !PORTABLE
+	 /// <summary>This exception is thrown whenever we find something we don't expect in a message.</summary>
     [Serializable]
-#endif
     public class InvalidCipherTextException
 		: CryptoException
     {
-		/**
-		* base constructor.
-		*/
-        public InvalidCipherTextException()
-        {
-        }
+		public InvalidCipherTextException()
+			: base()
+		{
+		}
 
-		/**
-         * create a InvalidCipherTextException with the given message.
-         *
-         * @param message the message to be carried with the exception.
-         */
-        public InvalidCipherTextException(
-            string message)
+		public InvalidCipherTextException(string message)
 			: base(message)
-        {
-        }
+		{
+		}
 
-		public InvalidCipherTextException(
-            string		message,
-            Exception	exception)
-			: base(message, exception)
-        {
-        }
-    }
+		public InvalidCipherTextException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected InvalidCipherTextException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
diff --git a/crypto/src/crypto/MaxBytesExceededException.cs b/crypto/src/crypto/MaxBytesExceededException.cs
index 032901c1d..b83b16fd4 100644
--- a/crypto/src/crypto/MaxBytesExceededException.cs
+++ b/crypto/src/crypto/MaxBytesExceededException.cs
@@ -1,31 +1,32 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Crypto
 {
-	/// <summary>
-	/// This exception is thrown whenever a cipher requires a change of key, iv
-	/// or similar after x amount of bytes enciphered
+	/// <summary>This exception is thrown whenever a cipher requires a change of key, IV or similar after x amount of
+	/// bytes enciphered.
 	/// </summary>
-#if !PORTABLE
     [Serializable]
-#endif
     public class MaxBytesExceededException
 		: CryptoException
 	{
 		public MaxBytesExceededException()
+			: base()
 		{
 		}
 
-		public MaxBytesExceededException(
-			string message)
+		public MaxBytesExceededException(string message)
 			: base(message)
 		{
 		}
 
-		public MaxBytesExceededException(
-			string		message,
-			Exception	e)
-			: base(message, e)
+		public MaxBytesExceededException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected MaxBytesExceededException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/crypto/OutputLengthException.cs b/crypto/src/crypto/OutputLengthException.cs
index 5f091f2ec..c8b2718f2 100644
--- a/crypto/src/crypto/OutputLengthException.cs
+++ b/crypto/src/crypto/OutputLengthException.cs
@@ -1,28 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Crypto
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class OutputLengthException
         : DataLengthException
     {
-        public OutputLengthException()
-        {
-        }
+		public OutputLengthException()
+			: base()
+		{
+		}
 
-        public OutputLengthException(
-            string message)
-            : base(message)
-        {
-        }
+		public OutputLengthException(string message)
+			: base(message)
+		{
+		}
 
-        public OutputLengthException(
-            string message,
-            Exception exception)
-            : base(message, exception)
-        {
-        }
-    }
+		public OutputLengthException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected OutputLengthException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
diff --git a/crypto/src/crypto/ec/CustomNamedCurves.cs b/crypto/src/crypto/ec/CustomNamedCurves.cs
index 166c0ad75..b1b97551c 100644
--- a/crypto/src/crypto/ec/CustomNamedCurves.cs
+++ b/crypto/src/crypto/ec/CustomNamedCurves.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.GM;
@@ -7,23 +7,18 @@ using Org.BouncyCastle.Asn1.Sec;
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Math.EC;
-using Org.BouncyCastle.Math.EC.Custom.Djb;
 using Org.BouncyCastle.Math.EC.Custom.GM;
 using Org.BouncyCastle.Math.EC.Custom.Sec;
 using Org.BouncyCastle.Math.EC.Endo;
 using Org.BouncyCastle.Math.EC.Multiplier;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Crypto.EC
 {
-    public sealed class CustomNamedCurves
+    /// <summary>Elliptic curve registry for various customized curve implementations.</summary>
+    public static class CustomNamedCurves
     {
-        private CustomNamedCurves()
-        {
-        }
-
         private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding)
         {
             X9ECPoint G = new X9ECPoint(curve, Hex.DecodeStrict(encoding));
@@ -41,45 +36,6 @@ namespace Org.BouncyCastle.Crypto.EC
             return c.Configure().SetEndomorphism(new GlvTypeBEndomorphism(c, p)).Create();
         }
 
-        /*
-         * curve25519
-         */
-        internal class Curve25519Holder
-            : X9ECParametersHolder
-        {
-            private Curve25519Holder() {}
-
-            internal static readonly X9ECParametersHolder Instance = new Curve25519Holder();
-
-            protected override ECCurve CreateCurve()
-            {
-                return ConfigureCurve(new Curve25519());
-            }
-
-            protected override X9ECParameters CreateParameters()
-            {
-                byte[] S = null;
-                ECCurve curve = Curve;
-
-                /*
-                 * NOTE: Curve25519 was specified in Montgomery form. Rewriting in Weierstrass form
-                 * involves substitution of variables, so the base-point x coordinate is 9 + (486662 / 3).
-                 * 
-                 * The Curve25519 paper doesn't say which of the two possible y values the base
-                 * point has. The choice here is guided by language in the Ed25519 paper.
-                 * 
-                 * (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14) 
-                 */
-                X9ECPoint G = ConfigureBasepoint(curve,
-                    "042AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9");
-
-                return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S);
-            }
-        }
-
-        /*
-         * secp128r1
-         */
         internal class SecP128R1Holder
             : X9ECParametersHolder
         {
@@ -102,9 +58,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * secp160k1
-         */
         internal class SecP160K1Holder
             : X9ECParametersHolder
         {
@@ -140,9 +93,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * secp160r1
-         */
         internal class SecP160R1Holder
             : X9ECParametersHolder
         {
@@ -165,9 +115,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * secp160r2
-         */
         internal class SecP160R2Holder
             : X9ECParametersHolder
         {
@@ -190,9 +137,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * secp192k1
-         */
         internal class SecP192K1Holder
             : X9ECParametersHolder
         {
@@ -228,9 +172,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         }
 
-        /*
-         * secp192r1
-         */
         internal class SecP192R1Holder
             : X9ECParametersHolder
         {
@@ -253,9 +194,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         }
 
-        /*
-         * secp224k1
-         */
         internal class SecP224K1Holder
             : X9ECParametersHolder
         {
@@ -291,9 +229,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         }
 
-        /*
-         * secp224r1
-         */
         internal class SecP224R1Holder
             : X9ECParametersHolder
         {
@@ -316,9 +251,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         }
 
-        /*
-         * secp256k1
-         */
         internal class SecP256K1Holder
             : X9ECParametersHolder
         {
@@ -354,9 +286,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         }
 
-        /*
-         * secp256r1
-         */
         internal class SecP256R1Holder
             : X9ECParametersHolder
         {
@@ -379,9 +308,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         }
 
-        /*
-         * secp384r1
-         */
         internal class SecP384R1Holder
             : X9ECParametersHolder
         {
@@ -405,9 +331,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         }
 
-        /*
-         * secp521r1
-         */
         internal class SecP521R1Holder
             : X9ECParametersHolder
         {
@@ -431,9 +354,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         }
 
-        /*
-         * sect113r1
-         */
         internal class SecT113R1Holder
             : X9ECParametersHolder
         {
@@ -456,9 +376,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect113r2
-         */
         internal class SecT113R2Holder
             : X9ECParametersHolder
         {
@@ -481,9 +398,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect131r1
-         */
         internal class SecT131R1Holder
             : X9ECParametersHolder
         {
@@ -506,9 +420,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect131r2
-         */
         internal class SecT131R2Holder
             : X9ECParametersHolder
         {
@@ -531,9 +442,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect163k1
-         */
         internal class SecT163K1Holder
             : X9ECParametersHolder
         {
@@ -556,9 +464,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect163r1
-         */
         internal class SecT163R1Holder
             : X9ECParametersHolder
         {
@@ -581,9 +486,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect163r2
-         */
         internal class SecT163R2Holder
             : X9ECParametersHolder
         {
@@ -606,9 +508,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect193r1
-         */
         internal class SecT193R1Holder
             : X9ECParametersHolder
         {
@@ -631,9 +530,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect193r2
-         */
         internal class SecT193R2Holder
             : X9ECParametersHolder
         {
@@ -656,9 +552,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect233k1
-         */
         internal class SecT233K1Holder
             : X9ECParametersHolder
         {
@@ -681,9 +574,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect233r1
-         */
         internal class SecT233R1Holder
             : X9ECParametersHolder
         {
@@ -706,9 +596,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect239k1
-         */
         internal class SecT239K1Holder
             : X9ECParametersHolder
         {
@@ -731,9 +618,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect283k1
-         */
         internal class SecT283K1Holder
             : X9ECParametersHolder
         {
@@ -757,9 +641,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect283r1
-         */
         internal class SecT283R1Holder
             : X9ECParametersHolder
         {
@@ -783,9 +664,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect409k1
-         */
         internal class SecT409K1Holder
             : X9ECParametersHolder
         {
@@ -809,9 +687,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect409r1
-         */
         internal class SecT409R1Holder
             : X9ECParametersHolder
         {
@@ -835,9 +710,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect571k1
-         */
         internal class SecT571K1Holder
             : X9ECParametersHolder
         {
@@ -861,9 +733,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sect571r1
-         */
         internal class SecT571R1Holder
             : X9ECParametersHolder
         {
@@ -887,9 +756,6 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         };
 
-        /*
-         * sm2p256v1
-         */
         internal class SM2P256V1Holder
             : X9ECParametersHolder
         {
@@ -912,81 +778,66 @@ namespace Org.BouncyCastle.Crypto.EC
             }
         }
 
+        private static readonly Dictionary<string, DerObjectIdentifier> objIds =
+            new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
+        private static readonly Dictionary<DerObjectIdentifier, X9ECParametersHolder> curves =
+            new Dictionary<DerObjectIdentifier, X9ECParametersHolder>();
+        private static readonly Dictionary<DerObjectIdentifier, string> names =
+            new Dictionary<DerObjectIdentifier, string>();
 
-        private static readonly IDictionary nameToCurve = Platform.CreateHashtable();
-        private static readonly IDictionary nameToOid = Platform.CreateHashtable();
-        private static readonly IDictionary oidToCurve = Platform.CreateHashtable();
-        private static readonly IDictionary oidToName = Platform.CreateHashtable();
-        private static readonly IList names = Platform.CreateArrayList();
-
-        private static void DefineCurve(string name, X9ECParametersHolder holder)
+        private static void DefineCurve(string name, DerObjectIdentifier oid, X9ECParametersHolder holder)
         {
-            names.Add(name);
-            name = Platform.ToUpperInvariant(name);
-            nameToCurve.Add(name, holder);
-        }
-
-        private static void DefineCurveWithOid(string name, DerObjectIdentifier oid, X9ECParametersHolder holder)
-        {
-            names.Add(name);
-            oidToName.Add(oid, name);
-            oidToCurve.Add(oid, holder);
-            name = Platform.ToUpperInvariant(name);
-            nameToOid.Add(name, oid);
-            nameToCurve.Add(name, holder);
+            objIds.Add(name, oid);
+            names.Add(oid, name);
+            curves.Add(oid, holder);
         }
 
         private static void DefineCurveAlias(string name, DerObjectIdentifier oid)
         {
-            object curve = oidToCurve[oid];
-            if (curve == null)
+            if (!curves.ContainsKey(oid))
                 throw new InvalidOperationException();
 
-            name = Platform.ToUpperInvariant(name);
-            nameToOid.Add(name, oid);
-            nameToCurve.Add(name, curve);
+            objIds.Add(name, oid);
         }
 
         static CustomNamedCurves()
         {
-            DefineCurve("curve25519", Curve25519Holder.Instance);
-
-            //DefineCurveWithOid("secp112r1", SecObjectIdentifiers.SecP112r1, SecP112R1Holder.Instance);
-            //DefineCurveWithOid("secp112r2", SecObjectIdentifiers.SecP112r2, SecP112R2Holder.Instance);
-            DefineCurveWithOid("secp128r1", SecObjectIdentifiers.SecP128r1, SecP128R1Holder.Instance);
-            //DefineCurveWithOid("secp128r2", SecObjectIdentifiers.SecP128r2, SecP128R2Holder.Instance);
-            DefineCurveWithOid("secp160k1", SecObjectIdentifiers.SecP160k1, SecP160K1Holder.Instance);
-            DefineCurveWithOid("secp160r1", SecObjectIdentifiers.SecP160r1, SecP160R1Holder.Instance);
-            DefineCurveWithOid("secp160r2", SecObjectIdentifiers.SecP160r2, SecP160R2Holder.Instance);
-            DefineCurveWithOid("secp192k1", SecObjectIdentifiers.SecP192k1, SecP192K1Holder.Instance);
-            DefineCurveWithOid("secp192r1", SecObjectIdentifiers.SecP192r1, SecP192R1Holder.Instance);
-            DefineCurveWithOid("secp224k1", SecObjectIdentifiers.SecP224k1, SecP224K1Holder.Instance);
-            DefineCurveWithOid("secp224r1", SecObjectIdentifiers.SecP224r1, SecP224R1Holder.Instance);
-            DefineCurveWithOid("secp256k1", SecObjectIdentifiers.SecP256k1, SecP256K1Holder.Instance);
-            DefineCurveWithOid("secp256r1", SecObjectIdentifiers.SecP256r1, SecP256R1Holder.Instance);
-            DefineCurveWithOid("secp384r1", SecObjectIdentifiers.SecP384r1, SecP384R1Holder.Instance);
-            DefineCurveWithOid("secp521r1", SecObjectIdentifiers.SecP521r1, SecP521R1Holder.Instance);
-
-            DefineCurveWithOid("sect113r1", SecObjectIdentifiers.SecT113r1, SecT113R1Holder.Instance);
-            DefineCurveWithOid("sect113r2", SecObjectIdentifiers.SecT113r2, SecT113R2Holder.Instance);
-            DefineCurveWithOid("sect131r1", SecObjectIdentifiers.SecT131r1, SecT131R1Holder.Instance);
-            DefineCurveWithOid("sect131r2", SecObjectIdentifiers.SecT131r2, SecT131R2Holder.Instance);
-            DefineCurveWithOid("sect163k1", SecObjectIdentifiers.SecT163k1, SecT163K1Holder.Instance);
-            DefineCurveWithOid("sect163r1", SecObjectIdentifiers.SecT163r1, SecT163R1Holder.Instance);
-            DefineCurveWithOid("sect163r2", SecObjectIdentifiers.SecT163r2, SecT163R2Holder.Instance);
-            DefineCurveWithOid("sect193r1", SecObjectIdentifiers.SecT193r1, SecT193R1Holder.Instance);
-            DefineCurveWithOid("sect193r2", SecObjectIdentifiers.SecT193r2, SecT193R2Holder.Instance);
-            DefineCurveWithOid("sect233k1", SecObjectIdentifiers.SecT233k1, SecT233K1Holder.Instance);
-            DefineCurveWithOid("sect233r1", SecObjectIdentifiers.SecT233r1, SecT233R1Holder.Instance);
-            DefineCurveWithOid("sect239k1", SecObjectIdentifiers.SecT239k1, SecT239K1Holder.Instance);
-            DefineCurveWithOid("sect283k1", SecObjectIdentifiers.SecT283k1, SecT283K1Holder.Instance);
-            DefineCurveWithOid("sect283r1", SecObjectIdentifiers.SecT283r1, SecT283R1Holder.Instance);
-            DefineCurveWithOid("sect409k1", SecObjectIdentifiers.SecT409k1, SecT409K1Holder.Instance);
-            DefineCurveWithOid("sect409r1", SecObjectIdentifiers.SecT409r1, SecT409R1Holder.Instance);
-            DefineCurveWithOid("sect571k1", SecObjectIdentifiers.SecT571k1, SecT571K1Holder.Instance);
-            DefineCurveWithOid("sect571r1", SecObjectIdentifiers.SecT571r1, SecT571R1Holder.Instance);
-
-            DefineCurveWithOid("sm2p256v1", GMObjectIdentifiers.sm2p256v1, SM2P256V1Holder.Instance);
+            //DefineCurve("secp112r1", SecObjectIdentifiers.SecP112r1, SecP112R1Holder.Instance);
+            //DefineCurve("secp112r2", SecObjectIdentifiers.SecP112r2, SecP112R2Holder.Instance);
+            DefineCurve("secp128r1", SecObjectIdentifiers.SecP128r1, SecP128R1Holder.Instance);
+            //DefineCurve("secp128r2", SecObjectIdentifiers.SecP128r2, SecP128R2Holder.Instance);
+            DefineCurve("secp160k1", SecObjectIdentifiers.SecP160k1, SecP160K1Holder.Instance);
+            DefineCurve("secp160r1", SecObjectIdentifiers.SecP160r1, SecP160R1Holder.Instance);
+            DefineCurve("secp160r2", SecObjectIdentifiers.SecP160r2, SecP160R2Holder.Instance);
+            DefineCurve("secp192k1", SecObjectIdentifiers.SecP192k1, SecP192K1Holder.Instance);
+            DefineCurve("secp192r1", SecObjectIdentifiers.SecP192r1, SecP192R1Holder.Instance);
+            DefineCurve("secp224k1", SecObjectIdentifiers.SecP224k1, SecP224K1Holder.Instance);
+            DefineCurve("secp224r1", SecObjectIdentifiers.SecP224r1, SecP224R1Holder.Instance);
+            DefineCurve("secp256k1", SecObjectIdentifiers.SecP256k1, SecP256K1Holder.Instance);
+            DefineCurve("secp256r1", SecObjectIdentifiers.SecP256r1, SecP256R1Holder.Instance);
+            DefineCurve("secp384r1", SecObjectIdentifiers.SecP384r1, SecP384R1Holder.Instance);
+            DefineCurve("secp521r1", SecObjectIdentifiers.SecP521r1, SecP521R1Holder.Instance);
+
+            DefineCurve("sect113r1", SecObjectIdentifiers.SecT113r1, SecT113R1Holder.Instance);
+            DefineCurve("sect113r2", SecObjectIdentifiers.SecT113r2, SecT113R2Holder.Instance);
+            DefineCurve("sect131r1", SecObjectIdentifiers.SecT131r1, SecT131R1Holder.Instance);
+            DefineCurve("sect131r2", SecObjectIdentifiers.SecT131r2, SecT131R2Holder.Instance);
+            DefineCurve("sect163k1", SecObjectIdentifiers.SecT163k1, SecT163K1Holder.Instance);
+            DefineCurve("sect163r1", SecObjectIdentifiers.SecT163r1, SecT163R1Holder.Instance);
+            DefineCurve("sect163r2", SecObjectIdentifiers.SecT163r2, SecT163R2Holder.Instance);
+            DefineCurve("sect193r1", SecObjectIdentifiers.SecT193r1, SecT193R1Holder.Instance);
+            DefineCurve("sect193r2", SecObjectIdentifiers.SecT193r2, SecT193R2Holder.Instance);
+            DefineCurve("sect233k1", SecObjectIdentifiers.SecT233k1, SecT233K1Holder.Instance);
+            DefineCurve("sect233r1", SecObjectIdentifiers.SecT233r1, SecT233R1Holder.Instance);
+            DefineCurve("sect239k1", SecObjectIdentifiers.SecT239k1, SecT239K1Holder.Instance);
+            DefineCurve("sect283k1", SecObjectIdentifiers.SecT283k1, SecT283K1Holder.Instance);
+            DefineCurve("sect283r1", SecObjectIdentifiers.SecT283r1, SecT283R1Holder.Instance);
+            DefineCurve("sect409k1", SecObjectIdentifiers.SecT409k1, SecT409K1Holder.Instance);
+            DefineCurve("sect409r1", SecObjectIdentifiers.SecT409r1, SecT409R1Holder.Instance);
+            DefineCurve("sect571k1", SecObjectIdentifiers.SecT571k1, SecT571K1Holder.Instance);
+            DefineCurve("sect571r1", SecObjectIdentifiers.SecT571r1, SecT571R1Holder.Instance);
+
+            DefineCurve("sm2p256v1", GMObjectIdentifiers.sm2p256v1, SM2P256V1Holder.Instance);
 
             DefineCurveAlias("B-163", SecObjectIdentifiers.SecT163r2);
             DefineCurveAlias("B-233", SecObjectIdentifiers.SecT233r1);
@@ -1007,60 +858,64 @@ namespace Org.BouncyCastle.Crypto.EC
             DefineCurveAlias("P-521", SecObjectIdentifiers.SecP521r1);
         }
 
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParameters GetByName(string name)
         {
-            X9ECParametersHolder holder = GetByNameLazy(name);
-            return holder == null ? null : holder.Parameters;
+            DerObjectIdentifier oid = GetOid(name);
+            return oid == null ? null : GetByOid(oid);
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given name.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="name">The name of the curve.</param>
         public static X9ECParametersHolder GetByNameLazy(string name)
         {
-            return (X9ECParametersHolder)nameToCurve[Platform.ToUpperInvariant(name)];
+            DerObjectIdentifier oid = GetOid(name);
+            return oid == null ? null : GetByOidLazy(oid);
         }
 
-        /**
-         * return the X9ECParameters object for the named curve represented by
-         * the passed in object identifier. Null if the curve isn't present.
-         *
-         * @param oid an object identifier representing a named curve, if present.
-         */
+        /// <summary>Look up the <see cref="X9ECParameters"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParameters GetByOid(DerObjectIdentifier oid)
         {
-            X9ECParametersHolder holder = GetByOidLazy(oid);
-            return holder == null ? null : holder.Parameters;
+            return GetByOidLazy(oid)?.Parameters;
         }
 
+        /// <summary>Look up an <see cref="X9ECParametersHolder"/> for the curve with the given
+        /// <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <remarks>
+        /// Allows accessing the <see cref="ECCurve">curve</see> without necessarily triggering the creation of the
+        /// full <see cref="X9ECParameters"/>.
+        /// </remarks>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
         public static X9ECParametersHolder GetByOidLazy(DerObjectIdentifier oid)
         {
-            return (X9ECParametersHolder)oidToCurve[oid];
+            return curves.TryGetValue(oid, out var holder) ? holder : null;
         }
 
-        /**
-         * return the object identifier signified by the passed in name. Null
-         * if there is no object identifier associated with name.
-         *
-         * @return the object identifier associated with name, if present.
-         */
-        public static DerObjectIdentifier GetOid(string name)
+        /// <summary>Look up the name of the curve with the given <see cref="DerObjectIdentifier">OID</see>.</summary>
+        /// <param name="oid">The <see cref="DerObjectIdentifier">OID</see> for the curve.</param>
+        public static string GetName(DerObjectIdentifier oid)
         {
-            return (DerObjectIdentifier)nameToOid[Platform.ToUpperInvariant(name)];
+            return names.TryGetValue(oid, out var name) ? name : null;
         }
 
-        /**
-         * return the named curve name represented by the given object identifier.
-         */
-        public static string GetName(DerObjectIdentifier oid)
+        /// <summary>Look up the <see cref="DerObjectIdentifier">OID</see> of the curve with the given name.</summary>
+        /// <param name="name">The name of the curve.</param>
+        public static DerObjectIdentifier GetOid(string name)
         {
-            return (string)oidToName[oid];
+            return objIds.TryGetValue(name, out var oid) ? oid : null;
         }
 
-        /**
-         * returns an enumeration containing the name strings for curves
-         * contained in this structure.
-         */
-        public static IEnumerable Names
+        /// <summary>Enumerate the available curve names in this registry.</summary>
+        public static IEnumerable<string> Names
         {
-            get { return new EnumerableProxy(names); }
+            get { return CollectionUtilities.Proxy(objIds.Keys); }
         }
     }
 }
diff --git a/crypto/src/math/ec/custom/djb/Curve25519.cs b/crypto/src/math/ec/custom/djb/Curve25519.cs
deleted file mode 100644
index 380be7252..000000000
--- a/crypto/src/math/ec/custom/djb/Curve25519.cs
+++ /dev/null
@@ -1,171 +0,0 @@
-using System;
-
-using Org.BouncyCastle.Math.Raw;
-using Org.BouncyCastle.Security;
-using Org.BouncyCastle.Utilities.Encoders;
-
-namespace Org.BouncyCastle.Math.EC.Custom.Djb
-{
-    internal class Curve25519
-        : AbstractFpCurve
-    {
-        public static readonly BigInteger q = Curve25519FieldElement.Q;
-
-        private static readonly BigInteger C_a = new BigInteger(1, Hex.DecodeStrict("2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144"));
-        private static readonly BigInteger C_b = new BigInteger(1, Hex.DecodeStrict("7B425ED097B425ED097B425ED097B425ED097B425ED097B4260B5E9C7710C864"));
-
-        private const int CURVE25519_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED;
-        private const int CURVE25519_FE_INTS = 8;
-        private static readonly ECFieldElement[] CURVE25519_AFFINE_ZS = new ECFieldElement[] {
-            new Curve25519FieldElement(BigInteger.One), new Curve25519FieldElement(C_a) }; 
-        protected readonly Curve25519Point m_infinity;
-
-        public Curve25519()
-            : base(q)
-        {
-            this.m_infinity = new Curve25519Point(this, null, null);
-
-            this.m_a = FromBigInteger(C_a);
-            this.m_b = FromBigInteger(C_b);
-            this.m_order = new BigInteger(1, Hex.DecodeStrict("1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED"));
-            this.m_cofactor = BigInteger.ValueOf(8);
-            this.m_coord = CURVE25519_DEFAULT_COORDS;
-        }
-
-        protected override ECCurve CloneCurve()
-        {
-            return new Curve25519();
-        }
-
-        public override bool SupportsCoordinateSystem(int coord)
-        {
-            switch (coord)
-            {
-            case COORD_JACOBIAN_MODIFIED:
-                return true;
-            default:
-                return false;
-            }
-        }
-
-        public virtual BigInteger Q
-        {
-            get { return q; }
-        }
-
-        public override ECPoint Infinity
-        {
-            get { return m_infinity; }
-        }
-
-        public override int FieldSize
-        {
-            get { return q.BitLength; }
-        }
-
-        public override ECFieldElement FromBigInteger(BigInteger x)
-        {
-            return new Curve25519FieldElement(x);
-        }
-
-        protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y)
-        {
-            return new Curve25519Point(this, x, y);
-        }
-
-        protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
-        {
-            return new Curve25519Point(this, x, y, zs);
-        }
-
-        public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
-        {
-            uint[] table = new uint[len * CURVE25519_FE_INTS * 2];
-            {
-                int pos = 0;
-                for (int i = 0; i < len; ++i)
-                {
-                    ECPoint p = points[off + i];
-                    Nat256.Copy(((Curve25519FieldElement)p.RawXCoord).x, 0, table, pos); pos += CURVE25519_FE_INTS;
-                    Nat256.Copy(((Curve25519FieldElement)p.RawYCoord).x, 0, table, pos); pos += CURVE25519_FE_INTS;
-                }
-            }
-
-            return new Curve25519LookupTable(this, table, len);
-        }
-
-        public override ECFieldElement RandomFieldElement(SecureRandom r)
-        {
-            uint[] x = Nat256.Create();
-            Curve25519Field.Random(r, x);
-            return new Curve25519FieldElement(x);
-        }
-
-        public override ECFieldElement RandomFieldElementMult(SecureRandom r)
-        {
-            uint[] x = Nat256.Create();
-            Curve25519Field.RandomMult(r, x);
-            return new Curve25519FieldElement(x);
-        }
-
-        private class Curve25519LookupTable
-            : AbstractECLookupTable
-        {
-            private readonly Curve25519 m_outer;
-            private readonly uint[] m_table;
-            private readonly int m_size;
-
-            internal Curve25519LookupTable(Curve25519 outer, uint[] table, int size)
-            {
-                this.m_outer = outer;
-                this.m_table = table;
-                this.m_size = size;
-            }
-
-            public override int Size
-            {
-                get { return m_size; }
-            }
-
-            public override ECPoint Lookup(int index)
-            {
-                uint[] x = Nat256.Create(), y = Nat256.Create();
-                int pos = 0;
-
-                for (int i = 0; i < m_size; ++i)
-                {
-                    uint MASK = (uint)(((i ^ index) - 1) >> 31);
-
-                    for (int j = 0; j < CURVE25519_FE_INTS; ++j)
-                    {
-                        x[j] ^= m_table[pos + j] & MASK;
-                        y[j] ^= m_table[pos + CURVE25519_FE_INTS + j] & MASK;
-                    }
-
-                    pos += (CURVE25519_FE_INTS * 2);
-                }
-
-                return CreatePoint(x, y);
-            }
-
-            public override ECPoint LookupVar(int index)
-            {
-                uint[] x = Nat256.Create(), y = Nat256.Create();
-                int pos = index * CURVE25519_FE_INTS * 2;
-
-                for (int j = 0; j < CURVE25519_FE_INTS; ++j)
-                {
-                    x[j] = m_table[pos + j];
-                    y[j] = m_table[pos + CURVE25519_FE_INTS + j];
-                }
-
-                return CreatePoint(x, y);
-            }
-
-            private ECPoint CreatePoint(uint[] x, uint[] y)
-            {
-                return m_outer.CreateRawPoint(new Curve25519FieldElement(x), new Curve25519FieldElement(y), CURVE25519_AFFINE_ZS);
-            }
-        }
-    }
-}
diff --git a/crypto/src/math/ec/custom/djb/Curve25519Field.cs b/crypto/src/math/ec/custom/djb/Curve25519Field.cs
deleted file mode 100644
index 31416249d..000000000
--- a/crypto/src/math/ec/custom/djb/Curve25519Field.cs
+++ /dev/null
@@ -1,292 +0,0 @@
-using System;
-using System.Diagnostics;
-
-using Org.BouncyCastle.Crypto.Utilities;
-using Org.BouncyCastle.Math.Raw;
-using Org.BouncyCastle.Security;
-
-namespace Org.BouncyCastle.Math.EC.Custom.Djb
-{
-    internal class Curve25519Field
-    {
-        // 2^255 - 19
-        internal static readonly uint[] P = new uint[]{ 0xFFFFFFED, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-            0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF };
-        private const uint P7 = 0x7FFFFFFF;
-        private static readonly uint[] PExt = new uint[]{ 0x00000169, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-            0x00000000, 0x00000000, 0x00000000, 0xFFFFFFED, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-            0xFFFFFFFF, 0x3FFFFFFF };
-        private const uint PInv = 0x13;
-
-        public static void Add(uint[] x, uint[] y, uint[] z)
-        {
-            Nat256.Add(x, y, z);
-            if (Nat256.Gte(z, P))
-            {
-                SubPFrom(z);
-            }
-        }
-
-        public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
-        {
-            Nat.Add(16, xx, yy, zz);
-            if (Nat.Gte(16, zz, PExt))
-            {
-                SubPExtFrom(zz);
-            }
-        }
-
-        public static void AddOne(uint[] x, uint[] z)
-        {
-            Nat.Inc(8, x, z);
-            if (Nat256.Gte(z, P))
-            {
-                SubPFrom(z);
-            }
-        }
-
-        public static uint[] FromBigInteger(BigInteger x)
-        {
-            uint[] z = Nat.FromBigInteger(256, x);
-            while (Nat256.Gte(z, P))
-            {
-                Nat256.SubFrom(P, z);
-            }
-            return z;
-        }
-
-        public static void Half(uint[] x, uint[] z)
-        {
-            if ((x[0] & 1) == 0)
-            {
-                Nat.ShiftDownBit(8, x, 0, z);
-            }
-            else
-            {
-                Nat256.Add(x, P, z);
-                Nat.ShiftDownBit(8, z, 0);
-            }
-        }
-
-        public static void Inv(uint[] x, uint[] z)
-        {
-            Mod.CheckedModOddInverse(P, x, z);
-        }
-
-        public static int IsZero(uint[] x)
-        {
-            uint d = 0;
-            for (int i = 0; i < 8; ++i)
-            {
-                d |= x[i];
-            }
-            d = (d >> 1) | (d & 1);
-            return ((int)d - 1) >> 31;
-        }
-
-        public static void Multiply(uint[] x, uint[] y, uint[] z)
-        {
-            uint[] tt = Nat256.CreateExt();
-            Nat256.Mul(x, y, tt);
-            Reduce(tt, z);
-        }
-
-        public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
-        {
-            Nat256.MulAddTo(x, y, zz);
-            if (Nat.Gte(16, zz, PExt))
-            {
-                SubPExtFrom(zz);
-            }
-        }
-
-        public static void Negate(uint[] x, uint[] z)
-        {
-            if (0 != IsZero(x))
-            {
-                Nat256.Sub(P, P, z);
-            }
-            else
-            {
-                Nat256.Sub(P, x, z);
-            }
-        }
-
-        public static void Random(SecureRandom r, uint[] z)
-        {
-            byte[] bb = new byte[8 * 4];
-            do
-            {
-                r.NextBytes(bb);
-                Pack.LE_To_UInt32(bb, 0, z, 0, 8);
-                z[7] &= P7;
-            }
-            while (0 == Nat.LessThan(8, z, P));
-        }
-
-        public static void RandomMult(SecureRandom r, uint[] z)
-        {
-            do
-            {
-                Random(r, z);
-            }
-            while (0 != IsZero(z));
-        }
-
-        public static void Reduce(uint[] xx, uint[] z)
-        {
-            Debug.Assert(xx[15] >> 30 == 0);
-
-            uint xx07 = xx[7];
-            Nat.ShiftUpBit(8, xx, 8, xx07, z, 0);
-            uint c = Nat256.MulByWordAddTo(PInv, xx, z) << 1;
-            uint z7 = z[7];
-            c += (z7 >> 31) - (xx07 >> 31);
-            z7 &= P7;
-            z7 += Nat.AddWordTo(7, c * PInv, z);
-            z[7] = z7;
-            if (z7 >= P7 && Nat256.Gte(z, P))
-            {
-                SubPFrom(z);
-            }
-        }
-
-        public static void Reduce27(uint x, uint[] z)
-        {
-            Debug.Assert(x >> 26 == 0);
-
-            uint z7 = z[7];
-            uint c = (x << 1 | z7 >> 31);
-            z7 &= P7;
-            z7 += Nat.AddWordTo(7, c * PInv, z);
-            z[7] = z7;
-            if (z7 >= P7 && Nat256.Gte(z, P))
-            {
-                SubPFrom(z);
-            }
-        }
-
-        public static void Square(uint[] x, uint[] z)
-        {
-            uint[] tt = Nat256.CreateExt();
-            Nat256.Square(x, tt);
-            Reduce(tt, z);
-        }
-
-        public static void SquareN(uint[] x, int n, uint[] z)
-        {
-            Debug.Assert(n > 0);
-
-            uint[] tt = Nat256.CreateExt();
-            Nat256.Square(x, tt);
-            Reduce(tt, z);
-
-            while (--n > 0)
-            {
-                Nat256.Square(z, tt);
-                Reduce(tt, z);
-            }
-        }
-
-        public static void Subtract(uint[] x, uint[] y, uint[] z)
-        {
-            int c = Nat256.Sub(x, y, z);
-            if (c != 0)
-            {
-                AddPTo(z);
-            }
-        }
-
-        public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
-        {
-            int c = Nat.Sub(16, xx, yy, zz);
-            if (c != 0)
-            {
-                AddPExtTo(zz);
-            }
-        }
-
-        public static void Twice(uint[] x, uint[] z)
-        {
-            Nat.ShiftUpBit(8, x, 0, z);
-            if (Nat256.Gte(z, P))
-            {
-                SubPFrom(z);
-            }
-        }
-
-        private static uint AddPTo(uint[] z)
-        {
-            long c = (long)z[0] - PInv;
-            z[0] = (uint)c;
-            c >>= 32;
-            if (c != 0)
-            {
-                c = Nat.DecAt(7, z, 1);
-            }
-            c += (long)z[7] + (P7 + 1);
-            z[7] = (uint)c;
-            c >>= 32;
-            return (uint)c;
-        }
-
-        private static uint AddPExtTo(uint[] zz)
-        {
-            long c = (long)zz[0] + PExt[0];
-            zz[0] = (uint)c;
-            c >>= 32;
-            if (c != 0)
-            {
-                c = Nat.IncAt(8, zz, 1);
-            }
-            c += (long)zz[8] - PInv;
-            zz[8] = (uint)c;
-            c >>= 32;
-            if (c != 0)
-            {
-                c = Nat.DecAt(15, zz, 9);
-            }
-            c += (long)zz[15] + (PExt[15] + 1);
-            zz[15] = (uint)c;
-            c >>= 32;
-            return (uint)c;
-        }
-
-        private static int SubPFrom(uint[] z)
-        {
-            long c = (long)z[0] + PInv;
-            z[0] = (uint)c;
-            c >>= 32;
-            if (c != 0)
-            {
-                c = Nat.IncAt(7, z, 1);
-            }
-            c += (long)z[7] - (P7 + 1);
-            z[7] = (uint)c;
-            c >>= 32;
-            return (int)c;
-        }
-
-        private static int SubPExtFrom(uint[] zz)
-        {
-            long c = (long)zz[0] - PExt[0];
-            zz[0] = (uint)c;
-            c >>= 32;
-            if (c != 0)
-            {
-                c = Nat.DecAt(8, zz, 1);
-            }
-            c += (long)zz[8] + PInv;
-            zz[8] = (uint)c;
-            c >>= 32;
-            if (c != 0)
-            {
-                c = Nat.IncAt(15, zz, 9);
-            }
-            c += (long)zz[15] - (PExt[15] + 1);
-            zz[15] = (uint)c;
-            c >>= 32;
-            return (int)c;
-        }
-    }
-}
diff --git a/crypto/src/math/ec/custom/djb/Curve25519FieldElement.cs b/crypto/src/math/ec/custom/djb/Curve25519FieldElement.cs
deleted file mode 100644
index a5509841d..000000000
--- a/crypto/src/math/ec/custom/djb/Curve25519FieldElement.cs
+++ /dev/null
@@ -1,233 +0,0 @@
-using System;
-
-using Org.BouncyCastle.Math.Raw;
-using Org.BouncyCastle.Utilities;
-
-namespace Org.BouncyCastle.Math.EC.Custom.Djb
-{
-    internal class Curve25519FieldElement
-        : AbstractFpFieldElement
-    {
-        public static readonly BigInteger Q = Nat256.ToBigInteger(Curve25519Field.P);
-
-        // Calculated as ECConstants.TWO.modPow(Q.shiftRight(2), Q)
-        private static readonly uint[] PRECOMP_POW2 = new uint[]{ 0x4a0ea0b0, 0xc4ee1b27, 0xad2fe478, 0x2f431806,
-            0x3dfbd7a7, 0x2b4d0099, 0x4fc1df0b, 0x2b832480 };
-
-        protected internal readonly uint[] x;
-
-        public Curve25519FieldElement(BigInteger x)
-        {
-            if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
-                throw new ArgumentException("value invalid for Curve25519FieldElement", "x");
-
-            this.x = Curve25519Field.FromBigInteger(x);
-        }
-
-        public Curve25519FieldElement()
-        {
-            this.x = Nat256.Create();
-        }
-
-        protected internal Curve25519FieldElement(uint[] x)
-        {
-            this.x = x;
-        }
-
-        public override bool IsZero
-        {
-            get { return Nat256.IsZero(x); }
-        }
-
-        public override bool IsOne
-        {
-            get { return Nat256.IsOne(x); }
-        }
-
-        public override bool TestBitZero()
-        {
-            return Nat256.GetBit(x, 0) == 1;
-        }
-
-        public override BigInteger ToBigInteger()
-        {
-            return Nat256.ToBigInteger(x);
-        }
-
-        public override string FieldName
-        {
-            get { return "Curve25519Field"; }
-        }
-
-        public override int FieldSize
-        {
-            get { return Q.BitLength; }
-        }
-
-        public override ECFieldElement Add(ECFieldElement b)
-        {
-            uint[] z = Nat256.Create();
-            Curve25519Field.Add(x, ((Curve25519FieldElement)b).x, z);
-            return new Curve25519FieldElement(z);
-        }
-
-        public override ECFieldElement AddOne()
-        {
-            uint[] z = Nat256.Create();
-            Curve25519Field.AddOne(x, z);
-            return new Curve25519FieldElement(z);
-        }
-
-        public override ECFieldElement Subtract(ECFieldElement b)
-        {
-            uint[] z = Nat256.Create();
-            Curve25519Field.Subtract(x, ((Curve25519FieldElement)b).x, z);
-            return new Curve25519FieldElement(z);
-        }
-
-        public override ECFieldElement Multiply(ECFieldElement b)
-        {
-            uint[] z = Nat256.Create();
-            Curve25519Field.Multiply(x, ((Curve25519FieldElement)b).x, z);
-            return new Curve25519FieldElement(z);
-        }
-
-        public override ECFieldElement Divide(ECFieldElement b)
-        {
-            //return Multiply(b.Invert());
-            uint[] z = Nat256.Create();
-            Curve25519Field.Inv(((Curve25519FieldElement)b).x, z);
-            Curve25519Field.Multiply(z, x, z);
-            return new Curve25519FieldElement(z);
-        }
-
-        public override ECFieldElement Negate()
-        {
-            uint[] z = Nat256.Create();
-            Curve25519Field.Negate(x, z);
-            return new Curve25519FieldElement(z);
-        }
-
-        public override ECFieldElement Square()
-        {
-            uint[] z = Nat256.Create();
-            Curve25519Field.Square(x, z);
-            return new Curve25519FieldElement(z);
-        }
-
-        public override ECFieldElement Invert()
-        {
-            //return new Curve25519FieldElement(ToBigInteger().ModInverse(Q));
-            uint[] z = Nat256.Create();
-            Curve25519Field.Inv(x, z);
-            return new Curve25519FieldElement(z);
-        }
-
-        /**
-         * return a sqrt root - the routine verifies that the calculation returns the right value - if
-         * none exists it returns null.
-         */
-        public override ECFieldElement Sqrt()
-        {
-            /*
-             * Q == 8m + 5, so we use Pocklington's method for this case.
-             *
-             * First, raise this element to the exponent 2^252 - 2^1 (i.e. m + 1)
-             * 
-             * Breaking up the exponent's binary representation into "repunits", we get:
-             * { 251 1s } { 1 0s }
-             * 
-             * Therefore we need an addition chain containing 251 (the lengths of the repunits)
-             * We use: 1, 2, 3, 4, 7, 11, 15, 30, 60, 120, 131, [251]
-             */
-
-            uint[] x1 = this.x;
-            if (Nat256.IsZero(x1) || Nat256.IsOne(x1))
-                return this;
-
-            uint[] x2 = Nat256.Create();
-            Curve25519Field.Square(x1, x2);
-            Curve25519Field.Multiply(x2, x1, x2);
-            uint[] x3 = x2;
-            Curve25519Field.Square(x2, x3);
-            Curve25519Field.Multiply(x3, x1, x3);
-            uint[] x4 = Nat256.Create();
-            Curve25519Field.Square(x3, x4);
-            Curve25519Field.Multiply(x4, x1, x4);
-            uint[] x7 = Nat256.Create();
-            Curve25519Field.SquareN(x4, 3, x7);
-            Curve25519Field.Multiply(x7, x3, x7);
-            uint[] x11 = x3;
-            Curve25519Field.SquareN(x7, 4, x11);
-            Curve25519Field.Multiply(x11, x4, x11);
-            uint[] x15 = x7;
-            Curve25519Field.SquareN(x11, 4, x15);
-            Curve25519Field.Multiply(x15, x4, x15);
-            uint[] x30 = x4;
-            Curve25519Field.SquareN(x15, 15, x30);
-            Curve25519Field.Multiply(x30, x15, x30);
-            uint[] x60 = x15;
-            Curve25519Field.SquareN(x30, 30, x60);
-            Curve25519Field.Multiply(x60, x30, x60);
-            uint[] x120 = x30;
-            Curve25519Field.SquareN(x60, 60, x120);
-            Curve25519Field.Multiply(x120, x60, x120);
-            uint[] x131 = x60;
-            Curve25519Field.SquareN(x120, 11, x131);
-            Curve25519Field.Multiply(x131, x11, x131);
-            uint[] x251 = x11;
-            Curve25519Field.SquareN(x131, 120, x251);
-            Curve25519Field.Multiply(x251, x120, x251);
-
-            uint[] t1 = x251;
-            Curve25519Field.Square(t1, t1);
-
-            uint[] t2 = x120;
-            Curve25519Field.Square(t1, t2);
-
-            if (Nat256.Eq(x1, t2))
-            {
-                return new Curve25519FieldElement(t1);
-            }
-
-            /*
-             * If the first guess is incorrect, we multiply by a precomputed power of 2 to get the second guess,
-             * which is ((4x)^(m + 1))/2 mod Q
-             */
-            Curve25519Field.Multiply(t1, PRECOMP_POW2, t1);
-
-            Curve25519Field.Square(t1, t2);
-
-            if (Nat256.Eq(x1, t2))
-            {
-                return new Curve25519FieldElement(t1);
-            }
-
-            return null;
-        }
-
-        public override bool Equals(object obj)
-        {
-            return Equals(obj as Curve25519FieldElement);
-        }
-
-        public override bool Equals(ECFieldElement other)
-        {
-            return Equals(other as Curve25519FieldElement);
-        }
-
-        public virtual bool Equals(Curve25519FieldElement other)
-        {
-            if (this == other)
-                return true;
-            if (null == other)
-                return false;
-            return Nat256.Eq(x, other.x);
-        }
-
-        public override int GetHashCode()
-        {
-            return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8);
-        }
-    }
-}
diff --git a/crypto/src/math/ec/custom/djb/Curve25519Point.cs b/crypto/src/math/ec/custom/djb/Curve25519Point.cs
deleted file mode 100644
index f61e28af8..000000000
--- a/crypto/src/math/ec/custom/djb/Curve25519Point.cs
+++ /dev/null
@@ -1,287 +0,0 @@
-using System;
-
-using Org.BouncyCastle.Math.Raw;
-
-namespace Org.BouncyCastle.Math.EC.Custom.Djb
-{
-    internal class Curve25519Point
-        : AbstractFpPoint
-    {
-        internal Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
-            : base(curve, x, y)
-        {
-        }
-
-        internal Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
-            : base(curve, x, y, zs)
-        {
-        }
-
-        protected override ECPoint Detach()
-        {
-            return new Curve25519Point(null, AffineXCoord, AffineYCoord);
-        }
-
-        public override ECFieldElement GetZCoord(int index)
-        {
-            if (index == 1)
-            {
-                return GetJacobianModifiedW();
-            }
-
-            return base.GetZCoord(index);
-        }
-
-        public override ECPoint Add(ECPoint b)
-        {
-            if (this.IsInfinity)
-                return b;
-            if (b.IsInfinity)
-                return this;
-            if (this == b)
-                return Twice();
-
-            ECCurve curve = this.Curve;
-
-            Curve25519FieldElement X1 = (Curve25519FieldElement)this.RawXCoord, Y1 = (Curve25519FieldElement)this.RawYCoord,
-                Z1 = (Curve25519FieldElement)this.RawZCoords[0];
-            Curve25519FieldElement X2 = (Curve25519FieldElement)b.RawXCoord, Y2 = (Curve25519FieldElement)b.RawYCoord,
-                Z2 = (Curve25519FieldElement)b.RawZCoords[0];
-
-            uint c;
-            uint[] tt1 = Nat256.CreateExt();
-            uint[] t2 = Nat256.Create();
-            uint[] t3 = Nat256.Create();
-            uint[] t4 = Nat256.Create();
-
-            bool Z1IsOne = Z1.IsOne;
-            uint[] U2, S2;
-            if (Z1IsOne)
-            {
-                U2 = X2.x;
-                S2 = Y2.x;
-            }
-            else
-            {
-                S2 = t3;
-                Curve25519Field.Square(Z1.x, S2);
-
-                U2 = t2;
-                Curve25519Field.Multiply(S2, X2.x, U2);
-
-                Curve25519Field.Multiply(S2, Z1.x, S2);
-                Curve25519Field.Multiply(S2, Y2.x, S2);
-            }
-
-            bool Z2IsOne = Z2.IsOne;
-            uint[] U1, S1;
-            if (Z2IsOne)
-            {
-                U1 = X1.x;
-                S1 = Y1.x;
-            }
-            else
-            {
-                S1 = t4;
-                Curve25519Field.Square(Z2.x, S1);
-
-                U1 = tt1;
-                Curve25519Field.Multiply(S1, X1.x, U1);
-
-                Curve25519Field.Multiply(S1, Z2.x, S1);
-                Curve25519Field.Multiply(S1, Y1.x, S1);
-            }
-
-            uint[] H = Nat256.Create();
-            Curve25519Field.Subtract(U1, U2, H);
-
-            uint[] R = t2;
-            Curve25519Field.Subtract(S1, S2, R);
-
-            // Check if b == this or b == -this
-            if (Nat256.IsZero(H))
-            {
-                if (Nat256.IsZero(R))
-                {
-                    // this == b, i.e. this must be doubled
-                    return this.Twice();
-                }
-
-                // this == -b, i.e. the result is the point at infinity
-                return curve.Infinity;
-            }
-
-            uint[] HSquared = Nat256.Create();
-            Curve25519Field.Square(H, HSquared);
-
-            uint[] G = Nat256.Create();
-            Curve25519Field.Multiply(HSquared, H, G);
-
-            uint[] V = t3;
-            Curve25519Field.Multiply(HSquared, U1, V);
-
-            Curve25519Field.Negate(G, G);
-            Nat256.Mul(S1, G, tt1);
-
-            c = Nat256.AddBothTo(V, V, G);
-            Curve25519Field.Reduce27(c, G);
-
-            Curve25519FieldElement X3 = new Curve25519FieldElement(t4);
-            Curve25519Field.Square(R, X3.x);
-            Curve25519Field.Subtract(X3.x, G, X3.x);
-
-            Curve25519FieldElement Y3 = new Curve25519FieldElement(G);
-            Curve25519Field.Subtract(V, X3.x, Y3.x);
-            Curve25519Field.MultiplyAddToExt(Y3.x, R, tt1);
-            Curve25519Field.Reduce(tt1, Y3.x);
-
-            Curve25519FieldElement Z3 = new Curve25519FieldElement(H);
-            if (!Z1IsOne)
-            {
-                Curve25519Field.Multiply(Z3.x, Z1.x, Z3.x);
-            }
-            if (!Z2IsOne)
-            {
-                Curve25519Field.Multiply(Z3.x, Z2.x, Z3.x);
-            }
-
-            uint[] Z3Squared = (Z1IsOne && Z2IsOne) ? HSquared : null;
-
-            // TODO If the result will only be used in a subsequent addition, we don't need W3
-            Curve25519FieldElement W3 = CalculateJacobianModifiedW((Curve25519FieldElement)Z3, Z3Squared);
-
-            ECFieldElement[] zs = new ECFieldElement[] { Z3, W3 };
-
-            return new Curve25519Point(curve, X3, Y3, zs);
-        }
-
-        public override ECPoint Twice()
-        {
-            if (this.IsInfinity)
-                return this;
-
-            ECCurve curve = this.Curve;
-
-            ECFieldElement Y1 = this.RawYCoord;
-            if (Y1.IsZero)
-                return curve.Infinity;
-
-            return TwiceJacobianModified(true);
-        }
-
-        public override ECPoint TwicePlus(ECPoint b)
-        {
-            if (this == b)
-                return ThreeTimes();
-            if (this.IsInfinity)
-                return b;
-            if (b.IsInfinity)
-                return Twice();
-
-            ECFieldElement Y1 = this.RawYCoord;
-            if (Y1.IsZero)
-                return b;
-
-            return TwiceJacobianModified(false).Add(b);
-        }
-
-        public override ECPoint ThreeTimes()
-        {
-            if (this.IsInfinity || this.RawYCoord.IsZero)
-                return this;
-
-            return TwiceJacobianModified(false).Add(this);
-        }
-
-        public override ECPoint Negate()
-        {
-            if (IsInfinity)
-                return this;
-
-            return new Curve25519Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords);
-        }
-
-        protected virtual Curve25519FieldElement CalculateJacobianModifiedW(Curve25519FieldElement Z, uint[] ZSquared)
-        {
-            Curve25519FieldElement a4 = (Curve25519FieldElement)this.Curve.A;
-            if (Z.IsOne)
-                return a4;
-
-            Curve25519FieldElement W = new Curve25519FieldElement();
-            if (ZSquared == null)
-            {
-                ZSquared = W.x;
-                Curve25519Field.Square(Z.x, ZSquared);
-            }
-            Curve25519Field.Square(ZSquared, W.x);
-            Curve25519Field.Multiply(W.x, a4.x, W.x);
-            return W;
-        }
-
-        protected virtual Curve25519FieldElement GetJacobianModifiedW()
-        {
-            ECFieldElement[] ZZ = this.RawZCoords;
-            Curve25519FieldElement W = (Curve25519FieldElement)ZZ[1];
-            if (W == null)
-            {
-                // NOTE: Rarely, TwicePlus will result in the need for a lazy W1 calculation here
-                ZZ[1] = W = CalculateJacobianModifiedW((Curve25519FieldElement)ZZ[0], null);
-            }
-            return W;
-        }
-
-        protected virtual Curve25519Point TwiceJacobianModified(bool calculateW)
-        {
-            Curve25519FieldElement X1 = (Curve25519FieldElement)this.RawXCoord, Y1 = (Curve25519FieldElement)this.RawYCoord,
-                Z1 = (Curve25519FieldElement)this.RawZCoords[0], W1 = GetJacobianModifiedW();
-
-            uint c;
-
-            uint[] M = Nat256.Create();
-            Curve25519Field.Square(X1.x, M);
-            c = Nat256.AddBothTo(M, M, M);
-            c += Nat256.AddTo(W1.x, M);
-            Curve25519Field.Reduce27(c, M);
-
-            uint[] _2Y1 = Nat256.Create();
-            Curve25519Field.Twice(Y1.x, _2Y1);
-
-            uint[] _2Y1Squared = Nat256.Create();
-            Curve25519Field.Multiply(_2Y1, Y1.x, _2Y1Squared);
-
-            uint[] S = Nat256.Create();
-            Curve25519Field.Multiply(_2Y1Squared, X1.x, S);
-            Curve25519Field.Twice(S, S);
-
-            uint[] _8T = Nat256.Create();
-            Curve25519Field.Square(_2Y1Squared, _8T);
-            Curve25519Field.Twice(_8T, _8T);
-
-            Curve25519FieldElement X3 = new Curve25519FieldElement(_2Y1Squared);
-            Curve25519Field.Square(M, X3.x);
-            Curve25519Field.Subtract(X3.x, S, X3.x);
-            Curve25519Field.Subtract(X3.x, S, X3.x);
-
-            Curve25519FieldElement Y3 = new Curve25519FieldElement(S);
-            Curve25519Field.Subtract(S, X3.x, Y3.x);
-            Curve25519Field.Multiply(Y3.x, M, Y3.x);
-            Curve25519Field.Subtract(Y3.x, _8T, Y3.x);
-
-            Curve25519FieldElement Z3 = new Curve25519FieldElement(_2Y1);
-            if (!Nat256.IsOne(Z1.x))
-            {
-                Curve25519Field.Multiply(Z3.x, Z1.x, Z3.x);
-            }
-
-            Curve25519FieldElement W3 = null;
-            if (calculateW)
-            {
-                W3 = new Curve25519FieldElement(_8T);
-                Curve25519Field.Multiply(W3.x, W1.x, W3.x);
-                Curve25519Field.Twice(W3.x, W3.x);
-            }
-
-            return new Curve25519Point(this.Curve, X3, Y3, new ECFieldElement[] { Z3, W3 });
-        }
-    }
-}
diff --git a/crypto/src/math/ec/multiplier/FixedPointUtilities.cs b/crypto/src/math/ec/multiplier/FixedPointUtilities.cs
index 88f178e24..fd158fae9 100644
--- a/crypto/src/math/ec/multiplier/FixedPointUtilities.cs
+++ b/crypto/src/math/ec/multiplier/FixedPointUtilities.cs
@@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Math.EC.Multiplier
 
             public PreCompInfo Precompute(PreCompInfo existing)
             {
-                FixedPointPreCompInfo existingFP = (existing is FixedPointPreCompInfo) ? (FixedPointPreCompInfo)existing : null;
+                FixedPointPreCompInfo existingFP = existing as FixedPointPreCompInfo;
 
                 ECCurve c = m_p.Curve;
                 int bits = FixedPointUtilities.GetCombSize(c);
diff --git a/crypto/src/math/ec/multiplier/WTauNafMultiplier.cs b/crypto/src/math/ec/multiplier/WTauNafMultiplier.cs
index 4dce54440..8e50a161d 100644
--- a/crypto/src/math/ec/multiplier/WTauNafMultiplier.cs
+++ b/crypto/src/math/ec/multiplier/WTauNafMultiplier.cs
@@ -24,10 +24,10 @@ namespace Org.BouncyCastle.Math.EC.Multiplier
         */
         protected override ECPoint MultiplyPositive(ECPoint point, BigInteger k)
         {
-            if (!(point is AbstractF2mPoint))
+            AbstractF2mPoint p = point as AbstractF2mPoint;
+            if (p == null)
                 throw new ArgumentException("Only AbstractF2mPoint can be used in WTauNafMultiplier");
 
-            AbstractF2mPoint p = (AbstractF2mPoint)point;
             AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve;
             int m = curve.FieldSize;
             sbyte a = (sbyte)curve.A.ToBigInteger().IntValue;
diff --git a/crypto/src/ocsp/OCSPException.cs b/crypto/src/ocsp/OCSPException.cs
index 5ec11fbf7..c575660c5 100644
--- a/crypto/src/ocsp/OCSPException.cs
+++ b/crypto/src/ocsp/OCSPException.cs
@@ -1,27 +1,29 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Ocsp
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class OcspException
 		: Exception
 	{
 		public OcspException()
+			: base()
 		{
 		}
 
-		public OcspException(
-			string message)
+		public OcspException(string message)
 			: base(message)
 		{
 		}
 
-		public OcspException(
-			string		message,
-			Exception	e)
-			: base(message, e)
+		public OcspException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected OcspException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/openpgp/PgpDataValidationException.cs b/crypto/src/openpgp/PgpDataValidationException.cs
index cec5c9b68..7718ab26c 100644
--- a/crypto/src/openpgp/PgpDataValidationException.cs
+++ b/crypto/src/openpgp/PgpDataValidationException.cs
@@ -1,18 +1,31 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Bcpg.OpenPgp
 {
-	/// <remarks>
-	/// Thrown if the IV at the start of a data stream indicates the wrong key is being used.
-	/// </remarks>
-#if !PORTABLE
+	/// <summary>Thrown if the IV at the start of a data stream indicates the wrong key is being used.</summary>
     [Serializable]
-#endif
     public class PgpDataValidationException
         : PgpException
 	{
-		public PgpDataValidationException() : base() {}
-		public PgpDataValidationException(string message) : base(message) {}
-		public PgpDataValidationException(string message, Exception exception) : base(message, exception) {}
+		public PgpDataValidationException()
+			: base()
+		{
+		}
+
+		public PgpDataValidationException(string message)
+			: base(message)
+		{
+		}
+
+		public PgpDataValidationException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected PgpDataValidationException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/openpgp/PgpException.cs b/crypto/src/openpgp/PgpException.cs
index dc0f3482b..cb5ea3569 100644
--- a/crypto/src/openpgp/PgpException.cs
+++ b/crypto/src/openpgp/PgpException.cs
@@ -1,16 +1,31 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Bcpg.OpenPgp
 {
-	/// <remarks>Generic exception class for PGP encoding/decoding problems.</remarks>
-#if !PORTABLE
+	/// <summary>Generic exception class for PGP encoding/decoding problems.</summary>
     [Serializable]
-#endif
     public class PgpException
 		: Exception
 	{
-		public PgpException() : base() {}
-		public PgpException(string message) : base(message) {}
-		public PgpException(string message, Exception exception) : base(message, exception) {}
+		public PgpException()
+			: base()
+		{
+		}
+
+		public PgpException(string message)
+			: base(message)
+		{
+		}
+
+		public PgpException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected PgpException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/openpgp/PgpKeyValidationException.cs b/crypto/src/openpgp/PgpKeyValidationException.cs
index df6abefe8..655c0a766 100644
--- a/crypto/src/openpgp/PgpKeyValidationException.cs
+++ b/crypto/src/openpgp/PgpKeyValidationException.cs
@@ -1,18 +1,31 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Bcpg.OpenPgp
 {
-	/// <remarks>
-	/// Thrown if the key checksum is invalid.
-	/// </remarks>
-#if !PORTABLE
+	/// <summary>Thrown if the key checksum is invalid.</summary>
     [Serializable]
-#endif
     public class PgpKeyValidationException
 		: PgpException
 	{
-		public PgpKeyValidationException() : base() {}
-		public PgpKeyValidationException(string message) : base(message) {}
-		public PgpKeyValidationException(string message, Exception exception) : base(message, exception) {}
+		public PgpKeyValidationException()
+			: base()
+		{
+		}
+
+		public PgpKeyValidationException(string message)
+			: base(message)
+		{
+		}
+
+		public PgpKeyValidationException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected PgpKeyValidationException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/openssl/EncryptionException.cs b/crypto/src/openssl/EncryptionException.cs
index c17eb99c4..414f8f68b 100644
--- a/crypto/src/openssl/EncryptionException.cs
+++ b/crypto/src/openssl/EncryptionException.cs
@@ -1,24 +1,30 @@
 using System;
 using System.IO;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class EncryptionException
 		: IOException
 	{
-		public EncryptionException(
-			string message)
+		public EncryptionException()
+			: base()
+		{
+		}
+
+		public EncryptionException(string message)
 			: base(message)
 		{
 		}
 
-		public EncryptionException(
-			string		message,
-			Exception	exception)
-			: base(message, exception)
+		public EncryptionException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected EncryptionException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/openssl/PEMException.cs b/crypto/src/openssl/PEMException.cs
index 3d51d799e..c4314b498 100644
--- a/crypto/src/openssl/PEMException.cs
+++ b/crypto/src/openssl/PEMException.cs
@@ -1,24 +1,30 @@
 using System;
 using System.IO;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.OpenSsl
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class PemException
 		: IOException
 	{
-		public PemException(
-			string message)
+		public PemException()
+			: base()
+		{
+		}
+
+		public PemException(string message)
 			: base(message)
 		{
 		}
 
-		public PemException(
-			string		message,
-			Exception	exception)
-			: base(message, exception)
+		public PemException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected PemException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/openssl/PasswordException.cs b/crypto/src/openssl/PasswordException.cs
index c920cc7a8..d056bb9b0 100644
--- a/crypto/src/openssl/PasswordException.cs
+++ b/crypto/src/openssl/PasswordException.cs
@@ -1,24 +1,30 @@
 using System;
 using System.IO;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class PasswordException
 		: IOException
 	{
-		public PasswordException(
-			string message)
+		public PasswordException()
+			: base()
+		{
+		}
+
+		public PasswordException(string message)
 			: base(message)
 		{
 		}
 
-		public PasswordException(
-			string		message,
-			Exception	exception)
-			: base(message, exception)
+		public PasswordException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected PasswordException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/pkcs/PkcsException.cs b/crypto/src/pkcs/PkcsException.cs
index 7a69ff736..ba296882c 100644
--- a/crypto/src/pkcs/PkcsException.cs
+++ b/crypto/src/pkcs/PkcsException.cs
@@ -1,21 +1,31 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Pkcs
 {
-    /// <summary>
-    /// Base exception for PKCS related issues.
-    /// </summary>
-    public class PkcsException
+	/// <summary>Base exception for PKCS related issues.</summary>
+	[Serializable]
+	public class PkcsException
         : Exception
     {
-        public PkcsException(string message)
-            : base(message)
-        {
-        }
+		public PkcsException()
+			: base()
+		{
+		}
 
-        public PkcsException(string message, Exception underlying)
-            : base(message, underlying)
-        {
-        }
-    }
+		public PkcsException(string message)
+			: base(message)
+		{
+		}
+
+		public PkcsException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected PkcsException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
diff --git a/crypto/src/pkcs/PkcsIOException.cs b/crypto/src/pkcs/PkcsIOException.cs
index 889b0fcb0..4523ac286 100644
--- a/crypto/src/pkcs/PkcsIOException.cs
+++ b/crypto/src/pkcs/PkcsIOException.cs
@@ -1,19 +1,32 @@
 using System;
 using System.IO;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Pkcs
 {
-    /// <summary>
-    /// Base exception for parsing related issues in the PKCS namespace.
-    /// </summary>
-    public class PkcsIOException: IOException
+	/// <summary>Base exception for parsing related issues in the PKCS namespace.</summary>
+	[Serializable]
+	public class PkcsIOException
+		: IOException
     {
-        public PkcsIOException(string message) : base(message)
-        {
-        }
+		public PkcsIOException()
+			: base()
+		{
+		}
 
-        public PkcsIOException(string message, Exception underlying) : base(message, underlying)
-        {
-        }
-    }
+		public PkcsIOException(string message)
+			: base(message)
+		{
+		}
+
+		public PkcsIOException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected PkcsIOException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
diff --git a/crypto/src/pkix/PkixCertPathBuilderException.cs b/crypto/src/pkix/PkixCertPathBuilderException.cs
index 46845d287..81c833459 100644
--- a/crypto/src/pkix/PkixCertPathBuilderException.cs
+++ b/crypto/src/pkix/PkixCertPathBuilderException.cs
@@ -1,22 +1,32 @@
 using System;
+using System.Runtime.Serialization;
 
 using Org.BouncyCastle.Security;
 
 namespace Org.BouncyCastle.Pkix
 {
-	/// <summary>
-	/// Summary description for PkixCertPathBuilderException.
-	/// </summary>
-#if !PORTABLE
     [Serializable]
-#endif
-    public class PkixCertPathBuilderException : GeneralSecurityException
+    public class PkixCertPathBuilderException
+		: GeneralSecurityException
 	{
-		public PkixCertPathBuilderException() : base() { }
-		
-		public PkixCertPathBuilderException(string message) : base(message)	{ }  
+		public PkixCertPathBuilderException()
+			: base()
+		{
+		}
 
-		public PkixCertPathBuilderException(string message, Exception exception) : base(message, exception) { }
-		
+		public PkixCertPathBuilderException(string message)
+			: base(message)
+		{
+		}
+
+		public PkixCertPathBuilderException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected PkixCertPathBuilderException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/pkix/PkixCertPathValidator.cs b/crypto/src/pkix/PkixCertPathValidator.cs
index 64039f9f1..a45102894 100644
--- a/crypto/src/pkix/PkixCertPathValidator.cs
+++ b/crypto/src/pkix/PkixCertPathValidator.cs
@@ -61,7 +61,7 @@ namespace Org.BouncyCastle.Pkix
             int n = certs.Count;
 
             if (certs.Count == 0)
-                throw new PkixCertPathValidatorException("Certification path is empty.", null, certPath, 0);
+                throw new PkixCertPathValidatorException("Certification path is empty.", null, 0);
 
 			//
             // (b)
@@ -84,13 +84,13 @@ namespace Org.BouncyCastle.Pkix
 					paramsPkix.GetTrustAnchors());
 
                 if (trust == null)
-                    throw new PkixCertPathValidatorException("Trust anchor for certification path not found.", null, certPath, -1);
+                    throw new PkixCertPathValidatorException("Trust anchor for certification path not found.", null, -1);
 
                 CheckCertificate(trust.TrustedCert);
             }
             catch (Exception e)
             {
-                throw new PkixCertPathValidatorException(e.Message, e.InnerException, certPath, certs.Count - 1);
+                throw new PkixCertPathValidatorException(e.Message, e.InnerException, certs.Count - 1);
             }
 
             //
@@ -192,8 +192,7 @@ namespace Org.BouncyCastle.Pkix
             }
             catch (ArgumentException ex)
             {
-                throw new PkixCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", ex, certPath,
-                        -1);
+                throw new PkixCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", ex, -1);
             }
 
             AlgorithmIdentifier workingAlgId = null;
@@ -204,7 +203,7 @@ namespace Org.BouncyCastle.Pkix
             catch (PkixCertPathValidatorException e)
             {
                 throw new PkixCertPathValidatorException(
-                        "Algorithm identifier of public key of trust anchor could not be read.", e, certPath, -1);
+                        "Algorithm identifier of public key of trust anchor could not be read.", e, -1);
             }
 
 //			DerObjectIdentifier workingPublicKeyAlgorithm = workingAlgId.Algorithm;
@@ -223,7 +222,7 @@ namespace Org.BouncyCastle.Pkix
             if (certConstraints != null && !certConstraints.Match((X509Certificate)certs[0]))
             {
                 throw new PkixCertPathValidatorException(
-					"Target certificate in certification path does not match targetConstraints.", null, certPath, 0);
+					"Target certificate in certification path does not match targetConstraints.", null, 0);
             }
 
             //
@@ -262,7 +261,7 @@ namespace Org.BouncyCastle.Pkix
                 }
                 catch (Exception e)
                 {
-                    throw new PkixCertPathValidatorException(e.Message, e.InnerException, certPath, index);
+                    throw new PkixCertPathValidatorException(e.Message, e.InnerException, index);
                 }
 
                 //
@@ -294,7 +293,7 @@ namespace Org.BouncyCastle.Pkix
                             continue;
 
                         throw new PkixCertPathValidatorException(
-							"Version 1 certificates can't be used as CA ones.", null, certPath, index);
+							"Version 1 certificates can't be used as CA ones.", null, index);
                     }
 
                     Rfc3280CertPathUtilities.PrepareNextCertA(certPath, index);
@@ -369,7 +368,7 @@ namespace Org.BouncyCastle.Pkix
                     }
                     catch (PkixCertPathValidatorException e)
                     {
-                        throw new PkixCertPathValidatorException("Next working key could not be retrieved.", e, certPath, index);
+                        throw new PkixCertPathValidatorException("Next working key could not be retrieved.", e, index);
                     }
 
                     workingAlgId = PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(workingPublicKey);
@@ -430,7 +429,7 @@ namespace Org.BouncyCastle.Pkix
 				return new PkixCertPathValidatorResult(trust, intersection, cert.GetPublicKey());
 			}
 
-			throw new PkixCertPathValidatorException("Path processing failed on policy.", null, certPath, index);
+			throw new PkixCertPathValidatorException("Path processing failed on policy.", null, index);
         }
 
         internal static void CheckCertificate(X509Certificate cert)
diff --git a/crypto/src/pkix/PkixCertPathValidatorException.cs b/crypto/src/pkix/PkixCertPathValidatorException.cs
index 143cdd832..effb60569 100644
--- a/crypto/src/pkix/PkixCertPathValidatorException.cs
+++ b/crypto/src/pkix/PkixCertPathValidatorException.cs
@@ -1,4 +1,6 @@
 using System;
+using System.Runtime.Serialization;
+
 using Org.BouncyCastle.Security;
 
 namespace Org.BouncyCastle.Pkix
@@ -27,38 +29,25 @@ namespace Org.BouncyCastle.Pkix
 	 *
 	 * @see CertPathValidator
 	 **/
-#if !PORTABLE
     [Serializable]
-#endif
     public class PkixCertPathValidatorException
         : GeneralSecurityException
 	{
-		private Exception cause;
-		private PkixCertPath certPath;
-		private int index = -1;
+		private readonly int m_index = -1;
 
-		public PkixCertPathValidatorException() : base() { }
+		public PkixCertPathValidatorException()
+			: base()
+		{
+		}
 
-		/// <summary>
-		/// Creates a <code>PkixCertPathValidatorException</code> with the given detail
-		/// message. A detail message is a <code>String</code> that describes this
-		/// particular exception. 
-		/// </summary>
-		/// <param name="message">the detail message</param>
-		public PkixCertPathValidatorException(string message) : base(message) { }
+		public PkixCertPathValidatorException(string message)
+			: base(message)
+		{
+		}
 
-		/// <summary>
-		/// Creates a <code>PkixCertPathValidatorException</code> with the specified
-		/// detail message and cause.
-		/// </summary>
-		/// <param name="message">the detail message</param>
-		/// <param name="cause">the cause (which is saved for later retrieval by the
-		/// {@link #getCause getCause()} method). (A <code>null</code>
-		/// value is permitted, and indicates that the cause is
-		/// nonexistent or unknown.)</param>
-		public PkixCertPathValidatorException(string message, Exception cause) : base(message)
+		public PkixCertPathValidatorException(string message, Exception innerException)
+			: base(message, innerException)
 		{
-			this.cause = cause;
 		}
 
 		/// <summary>
@@ -66,156 +55,32 @@ namespace Org.BouncyCastle.Pkix
 		/// detail message, cause, certification path, and index.
 		/// </summary>
 		/// <param name="message">the detail message (or <code>null</code> if none)</param>
-		/// <param name="cause">the cause (or <code>null</code> if none)</param>
-		/// <param name="certPath">the certification path that was in the process of being
-		/// validated when the error was encountered</param>
+		/// <param name="innerException">the cause (or <code>null</code> if none)</param>
 		/// <param name="index">the index of the certificate in the certification path that</param>																																																																																   * 
-		public PkixCertPathValidatorException(
-			string			message,
-			Exception		cause,
-			PkixCertPath	certPath,
-			int				index)
-			: base(message)
+		public PkixCertPathValidatorException(string message, Exception innerException, int index)
+			: base(message, innerException)
 		{
-			if (certPath == null && index != -1)
-			{
-				throw new ArgumentNullException(
-					"certPath = null and index != -1");
-			}
-			if (index < -1
-				|| (certPath != null && index >= certPath.Certificates.Count))
-			{
-				throw new IndexOutOfRangeException(
-					" index < -1 or out of bound of certPath.getCertificates()");
-			}
+			if (index < -1)
+				throw new ArgumentException("cannot be < -1", nameof(index));
 
-			this.cause = cause;
-			this.certPath = certPath;
-			this.index = index;
+			m_index = index;
 		}
 
-		//
-		// Prints a stack trace to a <code>PrintWriter</code>, including the
-		// backtrace of the cause, if any.
-		// 
-		// @param pw
-		//            the <code>PrintWriter</code> to use for output
-		//
-		//		public void printStackTrace(PrintWriter pw)
-		//		{
-		//			super.printStackTrace(pw);
-		//			if (getCause() != null)
-		//			{
-		//				getCause().printStackTrace(pw);
-		//			}
-		//	}
-		//}
-
-
-		//	/**
-		//	 * Creates a <code>CertPathValidatorException</code> that wraps the
-		//	 * specified throwable. This allows any exception to be converted into a
-		//	 * <code>CertPathValidatorException</code>, while retaining information
-		//	 * about the wrapped exception, which may be useful for debugging. The
-		//	 * detail message is set to (<code>cause==null ? null : cause.toString()
-		//	 * </code>)
-		//	 * (which typically contains the class and detail message of cause).
-		//	 * 
-		//	 * @param cause
-		//	 *            the cause (which is saved for later retrieval by the
-		//	 *            {@link #getCause getCause()} method). (A <code>null</code>
-		//	 *            value is permitted, and indicates that the cause is
-		//	 *            nonexistent or unknown.)
-		//	 */
-		//	public PkixCertPathValidatorException(Throwable cause)
-		//	{
-		//		this.cause = cause;
-		//	}
-		//
-
-		/// <summary>
-		/// Returns the detail message for this <code>CertPathValidatorException</code>.
-		/// </summary>
-		/// <returns>the detail message, or <code>null</code> if neither the message nor cause were specified</returns>
-		public override string Message
+		protected PkixCertPathValidatorException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
-			get
-			{
-				string message = base.Message;
-
-				if (message != null)
-				{
-					return message;
-				}
-
-				if (cause != null)
-				{
-					return cause.Message;
-				}
-
-				return null;
-			}
 		}
 
-	/**
-	 * Returns the certification path that was being validated when the
-	 * exception was thrown.
-	 * 
-	 * @return the <code>CertPath</code> that was being validated when the
-	 *         exception was thrown (or <code>null</code> if not specified)
-	 */
-		public PkixCertPath CertPath
+		/// <summary> eturns the index of the certificate in the certification path that caused the exception to be
+		/// thrown.</summary>
+		/// <remarks>
+		/// Note that the list of certificates in a <see cref="PkixCertPath"/> is zero based. If no index has been set,
+		/// -1 is returned.
+		/// </remarks>
+		/// <returns>The index that has been set, or -1 if none has been set.</returns>
+		public int Index
 		{
-			get { return certPath; }
+			get { return m_index; }
 		}
-
-	/**
-	 * Returns the index of the certificate in the certification path that
-	 * caused the exception to be thrown. Note that the list of certificates in
-	 * a <code>CertPath</code> is zero based. If no index has been set, -1 is
-	 * returned.
-	 * 
-	 * @return the index that has been set, or -1 if none has been set
-	 */
-	public int Index
-	{
-        get { return index; }
-	}
-
-//	/**
-//	 * Returns the cause of this <code>CertPathValidatorException</code> or
-//	 * <code>null</code> if the cause is nonexistent or unknown.
-//	 * 
-//	 * @return the cause of this throwable or <code>null</code> if the cause
-//	 *         is nonexistent or unknown.
-//	 */
-//	public Throwable getCause()
-//	{
-//		return cause;
-//	}
-//
-//	/**
-//	 * Returns a string describing this exception, including a description of
-//	 * the internal (wrapped) cause if there is one.
-//	 * 
-//	 * @return a string representation of this
-//	 *         <code>CertPathValidatorException</code>
-//	 */
-//	public String toString()
-//	{
-//		StringBuffer sb = new StringBuffer();
-//		String s = getMessage();
-//		if (s != null)
-//		{
-//			sb.append(s);
-//		}
-//		if (getIndex() >= 0)
-//		{
-//			sb.append("index in certpath: ").append(getIndex()).append('\n');
-//			sb.append(getCertPath());
-//		}
-//		return sb.toString();
-//	}
-
 	}
 }
diff --git a/crypto/src/pkix/PkixNameConstraintValidatorException.cs b/crypto/src/pkix/PkixNameConstraintValidatorException.cs
index d0882ca96..c67123506 100644
--- a/crypto/src/pkix/PkixNameConstraintValidatorException.cs
+++ b/crypto/src/pkix/PkixNameConstraintValidatorException.cs
@@ -1,16 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Pkix
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class PkixNameConstraintValidatorException
         : Exception
     {
-        public PkixNameConstraintValidatorException(string msg)
-            : base(msg)
-        {
-        }
+		public PkixNameConstraintValidatorException()
+			: base()
+		{
+		}
+
+		public PkixNameConstraintValidatorException(string message)
+			: base(message)
+		{
+		}
+
+		public PkixNameConstraintValidatorException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected PkixNameConstraintValidatorException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
     }
 }
diff --git a/crypto/src/pkix/Rfc3280CertPathUtilities.cs b/crypto/src/pkix/Rfc3280CertPathUtilities.cs
index d6594f4ad..9001ba1d1 100644
--- a/crypto/src/pkix/Rfc3280CertPathUtilities.cs
+++ b/crypto/src/pkix/Rfc3280CertPathUtilities.cs
@@ -254,7 +254,7 @@ namespace Org.BouncyCastle.Pkix
 				catch (Exception e)
 				{
 					throw new PkixCertPathValidatorException(
-						"Exception extracting subject name when checking subtrees.", e, certPath, index);
+						"Exception extracting subject name when checking subtrees.", e, index);
 				}
 
 				try
@@ -265,7 +265,7 @@ namespace Org.BouncyCastle.Pkix
 				catch (PkixNameConstraintValidatorException e)
 				{
 					throw new PkixCertPathValidatorException(
-						"Subtree check for certificate subject failed.", e, certPath, index);
+						"Subtree check for certificate subject failed.", e, index);
 				}
 
 				GeneralNames altName = null;
@@ -277,7 +277,7 @@ namespace Org.BouncyCastle.Pkix
 				catch (Exception e)
 				{
 					throw new PkixCertPathValidatorException(
-						"Subject alternative name extension could not be decoded.", e, certPath, index);
+						"Subject alternative name extension could not be decoded.", e, index);
 				}
 
 				IList emails = X509Name.GetInstance(dns).GetValueList(X509Name.EmailAddress);
@@ -292,7 +292,7 @@ namespace Org.BouncyCastle.Pkix
 					catch (PkixNameConstraintValidatorException ex)
 					{
 						throw new PkixCertPathValidatorException(
-							"Subtree check for certificate subject alternative email failed.", ex, certPath, index);
+							"Subtree check for certificate subject alternative email failed.", ex, index);
 					}
 				}
 				if (altName != null)
@@ -305,7 +305,7 @@ namespace Org.BouncyCastle.Pkix
 					catch (Exception e)
 					{
 						throw new PkixCertPathValidatorException(
-							"Subject alternative name contents could not be decoded.", e, certPath, index);
+							"Subject alternative name contents could not be decoded.", e, index);
 					}
 					foreach (GeneralName genName in genNames)
 					{
@@ -317,7 +317,7 @@ namespace Org.BouncyCastle.Pkix
 						catch (PkixNameConstraintValidatorException e)
 						{
 							throw new PkixCertPathValidatorException(
-								"Subtree check for certificate subject alternative name failed.", e, certPath, index);
+								"Subtree check for certificate subject alternative name failed.", e, index);
 						}
 					}
 				}
@@ -344,7 +344,7 @@ namespace Org.BouncyCastle.Pkix
 			catch (Exception ex)
 			{
 				throw new PkixCertPathValidatorException(
-					"Policy mappings extension could not be decoded.", ex, certPath, index);
+					"Policy mappings extension could not be decoded.", ex, index);
 			}
 			if (pm != null)
 			{
@@ -364,16 +364,16 @@ namespace Org.BouncyCastle.Pkix
 					catch (Exception e)
 					{
 						throw new PkixCertPathValidatorException(
-							"Policy mappings extension contents could not be decoded.", e, certPath, index);
+							"Policy mappings extension contents could not be decoded.", e, index);
 					}
 
 					if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(issuerDomainPolicy.Id))
 						throw new PkixCertPathValidatorException(
-							"IssuerDomainPolicy is anyPolicy", null, certPath, index);
+							"IssuerDomainPolicy is anyPolicy", null, index);
 
 					if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(subjectDomainPolicy.Id))
 						throw new PkixCertPathValidatorException(
-							"SubjectDomainPolicy is anyPolicy,", null, certPath, index);
+							"SubjectDomainPolicy is anyPolicy,", null, index);
 				}
 			}
 		}
@@ -405,7 +405,7 @@ namespace Org.BouncyCastle.Pkix
 			catch (Exception e)
 			{
 				throw new PkixCertPathValidatorException(
-					"Could not read certificate policies extension from certificate.", e, certPath, index);
+					"Could not read certificate policies extension from certificate.", e, index);
 			}
 			if (certPolicies != null && validPolicyTree != null)
 			{
@@ -431,7 +431,7 @@ namespace Org.BouncyCastle.Pkix
 						catch (PkixCertPathValidatorException ex)
 						{
 							throw new PkixCertPathValidatorException(
-								"Policy qualifier info set could not be build.", ex, certPath, index);
+								"Policy qualifier info set could not be build.", ex, index);
 						}
 
 						bool match = PkixCertPathValidatorUtilities.ProcessCertD1i(i, policyNodes, pOid, pq);
@@ -1238,7 +1238,7 @@ namespace Org.BouncyCastle.Pkix
 			catch (Exception ex)
 			{
 				throw new PkixCertPathValidatorException(
-					"Policy mappings extension could not be decoded.", ex, certPath, index);
+					"Policy mappings extension could not be decoded.", ex, index);
 			}
 			PkixPolicyNode _validPolicyTree = validPolicyTree;
 			if (pm != null)
@@ -1310,7 +1310,7 @@ namespace Org.BouncyCastle.Pkix
 									catch (Exception e)
 									{
 										throw new PkixCertPathValidatorException(
-											"Certificate policies extension could not be decoded.", e, certPath, index);
+											"Certificate policies extension could not be decoded.", e, index);
 									}
 
 									foreach (Asn1Encodable ae in policies)
@@ -1323,7 +1323,7 @@ namespace Org.BouncyCastle.Pkix
 										catch (Exception ex)
 										{
 											throw new PkixCertPathValidatorException(
-												"Policy information could not be decoded.", ex, certPath, index);
+												"Policy information could not be decoded.", ex, index);
 										}
 										if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(pinfo.PolicyIdentifier.Id))
 										{
@@ -1335,8 +1335,7 @@ namespace Org.BouncyCastle.Pkix
 											catch (PkixCertPathValidatorException ex)
 											{
 												throw new PkixCertPathValidatorException(
-													"Policy qualifier info set could not be decoded.", ex, certPath,
-													index);
+													"Policy qualifier info set could not be decoded.", ex, index);
 											}
 											break;
 										}
@@ -1503,7 +1502,7 @@ namespace Org.BouncyCastle.Pkix
 			if (explicitPolicy <= 0 && validPolicyTree == null)
 			{
 				throw new PkixCertPathValidatorException(
-					"No valid policy tree found when one expected.", null, certPath, index);
+					"No valid policy tree found when one expected.", null, index);
 			}
 		}
 
@@ -1528,7 +1527,7 @@ namespace Org.BouncyCastle.Pkix
 			}
 			catch (GeneralSecurityException e)
 			{
-				throw new PkixCertPathValidatorException("Could not validate certificate signature.", e, certPath, index);
+				throw new PkixCertPathValidatorException("Could not validate certificate signature.", e, index);
 			}
 
 			try
@@ -1540,15 +1539,15 @@ namespace Org.BouncyCastle.Pkix
 			}
 			catch (CertificateExpiredException e)
 			{
-				throw new PkixCertPathValidatorException("Could not validate certificate: " + e.Message, e, certPath, index);
+				throw new PkixCertPathValidatorException("Could not validate certificate: " + e.Message, e, index);
 			}
 			catch (CertificateNotYetValidException e)
 			{
-				throw new PkixCertPathValidatorException("Could not validate certificate: " + e.Message, e, certPath, index);
+				throw new PkixCertPathValidatorException("Could not validate certificate: " + e.Message, e, index);
 			}
 			catch (Exception e)
 			{
-				throw new PkixCertPathValidatorException("Could not validate time of certificate.", e, certPath, index);
+				throw new PkixCertPathValidatorException("Could not validate time of certificate.", e, index);
 			}
 
 			//
@@ -1568,7 +1567,7 @@ namespace Org.BouncyCastle.Pkix
 					{
 						cause = e;
 					}
-					throw new PkixCertPathValidatorException(e.Message, cause, certPath, index);
+					throw new PkixCertPathValidatorException(e.Message, cause, index);
 				}
 			}
 
@@ -1579,8 +1578,7 @@ namespace Org.BouncyCastle.Pkix
 			if (!issuer.Equivalent(workingIssuerName, true))
 			{
 				throw new PkixCertPathValidatorException("IssuerName(" + issuer
-					+ ") does not match SubjectName(" + workingIssuerName + ") of signing certificate.", null,
-					certPath, index);
+					+ ") does not match SubjectName(" + workingIssuerName + ") of signing certificate.", null, index);
 			}
 		}
 
@@ -1603,7 +1601,7 @@ namespace Org.BouncyCastle.Pkix
 			catch (Exception e)
 			{
 				throw new PkixCertPathValidatorException(
-					"Policy constraints extension cannot be decoded.", e, certPath, index);
+					"Policy constraints extension cannot be decoded.", e, index);
 			}
 
 			int tmpInt;
@@ -1630,7 +1628,7 @@ namespace Org.BouncyCastle.Pkix
 					catch (ArgumentException e)
 					{
 						throw new PkixCertPathValidatorException(
-							"Policy constraints extension contents cannot be decoded.", e, certPath, index);
+							"Policy constraints extension contents cannot be decoded.", e, index);
 					}
 				}
 			}
@@ -1657,8 +1655,7 @@ namespace Org.BouncyCastle.Pkix
 			}
 			catch (Exception e)
 			{
-				throw new PkixCertPathValidatorException(
-					"Policy constraints extension cannot be decoded.", e, certPath, index);
+				throw new PkixCertPathValidatorException("Policy constraints extension cannot be decoded.", e, index);
 			}
 
 			int tmpInt;
@@ -1685,7 +1682,7 @@ namespace Org.BouncyCastle.Pkix
 					catch (ArgumentException e)
 					{
 						throw new PkixCertPathValidatorException(
-							"Policy constraints extension contents cannot be decoded.", e, certPath, index);
+							"Policy constraints extension contents cannot be decoded.", e, index);
 					}
 				}
 			}
@@ -1717,7 +1714,7 @@ namespace Org.BouncyCastle.Pkix
 			catch (Exception e)
 			{
 				throw new PkixCertPathValidatorException(
-					"Name constraints extension could not be decoded.", e, certPath, index);
+					"Name constraints extension could not be decoded.", e, index);
 			}
 			if (nc != null)
 			{
@@ -1734,7 +1731,7 @@ namespace Org.BouncyCastle.Pkix
 					catch (Exception ex)
 					{
 						throw new PkixCertPathValidatorException(
-							"Permitted subtrees cannot be build from name constraints extension.", ex, certPath, index);
+							"Permitted subtrees cannot be build from name constraints extension.", ex, index);
 					}
 				}
 
@@ -1756,7 +1753,7 @@ namespace Org.BouncyCastle.Pkix
 					catch (Exception ex)
 					{
 						throw new PkixCertPathValidatorException(
-							"Excluded subtrees cannot be build from name constraints extension.", ex, certPath, index);
+							"Excluded subtrees cannot be build from name constraints extension.", ex, index);
 					}
 				}
 			}
@@ -1782,8 +1779,7 @@ namespace Org.BouncyCastle.Pkix
 			}
 			catch (Exception e)
 			{
-				throw new PkixCertPathValidatorException(
-					"Inhibit any-policy extension cannot be decoded.", e, certPath, index);
+				throw new PkixCertPathValidatorException("Inhibit any-policy extension cannot be decoded.", e, index);
 			}
 
 			if (iap != null)
@@ -1814,8 +1810,7 @@ namespace Org.BouncyCastle.Pkix
 			}
 			catch (Exception e)
 			{
-				throw new PkixCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
-					index);
+				throw new PkixCertPathValidatorException("Basic constraints extension cannot be decoded.", e, index);
 			}
 			if (bc != null)
 			{
@@ -1843,7 +1838,7 @@ namespace Org.BouncyCastle.Pkix
 			{
 				if (maxPathLength <= 0)
 				{
-					throw new PkixCertPathValidatorException("Max path length not greater than zero", null, certPath, index);
+					throw new PkixCertPathValidatorException("Max path length not greater than zero", null, index);
 				}
 
 				return maxPathLength - 1;
@@ -1871,8 +1866,7 @@ namespace Org.BouncyCastle.Pkix
 			}
 			catch (Exception e)
 			{
-				throw new PkixCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
-					index);
+				throw new PkixCertPathValidatorException("Basic constraints extension cannot be decoded.", e, index);
 			}
 			if (bc != null)
 			{
@@ -1907,8 +1901,7 @@ namespace Org.BouncyCastle.Pkix
 			if ((_usage != null) && !_usage[Rfc3280CertPathUtilities.KEY_CERT_SIGN])
 			{
 				throw new PkixCertPathValidatorException(
-					"Issuer certificate keyusage extension is critical and does not permit key signing.", null,
-					certPath, index);
+					"Issuer certificate keyusage extension is critical and does not permit key signing.", null, index);
 			}
 		}
 
@@ -1934,13 +1927,12 @@ namespace Org.BouncyCastle.Pkix
 				}
 				catch (PkixCertPathValidatorException e)
 				{
-					throw new PkixCertPathValidatorException(e.Message, e.InnerException, certPath, index);
+					throw new PkixCertPathValidatorException(e.Message, e.InnerException, index);
 				}
 			}
 			if (!criticalExtensions.IsEmpty)
 			{
-				throw new PkixCertPathValidatorException("Certificate has unsupported critical extension.", null, certPath,
-					index);
+				throw new PkixCertPathValidatorException("Certificate has unsupported critical extension.", null, index);
 			}
 		}
 
@@ -2046,7 +2038,7 @@ namespace Org.BouncyCastle.Pkix
 			}
 			catch (Exception e)
 			{
-				throw new PkixCertPathValidatorException("Policy constraints could not be decoded.", e, certPath, index);
+				throw new PkixCertPathValidatorException("Policy constraints could not be decoded.", e, index);
 			}
 
 			if (pc != null)
@@ -2066,8 +2058,7 @@ namespace Org.BouncyCastle.Pkix
 							catch (Exception e)
 							{
 								throw new PkixCertPathValidatorException(
-									"Policy constraints requireExplicitPolicy field could not be decoded.", e, certPath,
-									index);
+									"Policy constraints requireExplicitPolicy field could not be decoded.", e, index);
 							}
 							if (tmpInt == 0)
 							{
@@ -2099,15 +2090,14 @@ namespace Org.BouncyCastle.Pkix
 				}
 				catch (PkixCertPathValidatorException e)
 				{
-					throw new PkixCertPathValidatorException("Additional certificate path checker failed.", e, certPath,
-						index);
+					throw new PkixCertPathValidatorException("Additional certificate path checker failed.", e, index);
 				}
 			}
 
 			if (!criticalExtensions.IsEmpty)
 			{
 				throw new PkixCertPathValidatorException("Certificate has unsupported critical extension",
-					null, certPath, index);
+					null, index);
 			}
 		}
 
@@ -2135,19 +2125,18 @@ namespace Org.BouncyCastle.Pkix
 				if (paramsPKIX.IsExplicitPolicyRequired)
 				{
 					throw new PkixCertPathValidatorException(
-						"Explicit policy requested but none available.", null, certPath, index);
+						"Explicit policy requested but none available.", null, index);
 				}
 				intersection = null;
 			}
-			else if (PkixCertPathValidatorUtilities.IsAnyPolicy(userInitialPolicySet)) // (g)
-				// (ii)
+			else if (PkixCertPathValidatorUtilities.IsAnyPolicy(userInitialPolicySet)) // (g) (ii)
 			{
 				if (paramsPKIX.IsExplicitPolicyRequired)
 				{
 					if (acceptablePolicies.IsEmpty)
 					{
 						throw new PkixCertPathValidatorException(
-							"Explicit policy requested but none available.", null, certPath, index);
+							"Explicit policy requested but none available.", null, index);
 					}
 					else
 					{
@@ -2420,7 +2409,7 @@ namespace Org.BouncyCastle.Pkix
 			catch (Exception e)
 			{
 				throw new PkixCertPathValidatorException("Could not read certificate policies extension from certificate.",
-					e, certPath, index);
+					e, index);
 			}
 			if (certPolicies == null)
 			{
diff --git a/crypto/src/pqc/crypto/lms/LMSException.cs b/crypto/src/pqc/crypto/lms/LMSException.cs
index 5f8f7b9d9..c9c286b7f 100644
--- a/crypto/src/pqc/crypto/lms/LMSException.cs
+++ b/crypto/src/pqc/crypto/lms/LMSException.cs
@@ -1,22 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
+    [Serializable]
     public class LMSException
         : Exception
     {
-        public LMSException()
-        {
-        }
+		public LMSException()
+			: base()
+		{
+		}
 
-        public LMSException(string message)
-            : base(message)
-        {
-        }
+		public LMSException(string message)
+			: base(message)
+		{
+		}
 
-        public LMSException(string message, Exception cause)
-            : base(message, cause)
-        {
-        }
-    }
-}
\ No newline at end of file
+		public LMSException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected LMSException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
+}
diff --git a/crypto/src/security/GeneralSecurityException.cs b/crypto/src/security/GeneralSecurityException.cs
index c1131f04b..02b1f6c57 100644
--- a/crypto/src/security/GeneralSecurityException.cs
+++ b/crypto/src/security/GeneralSecurityException.cs
@@ -1,10 +1,9 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class GeneralSecurityException
 		: Exception
 	{
@@ -13,16 +12,18 @@ namespace Org.BouncyCastle.Security
 		{
 		}
 
-		public GeneralSecurityException(
-			string message)
+		public GeneralSecurityException(string message)
 			: base(message)
 		{
 		}
 
-		public GeneralSecurityException(
-			string		message,
-			Exception	exception)
-			: base(message, exception)
+		public GeneralSecurityException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected GeneralSecurityException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/security/InvalidKeyException.cs b/crypto/src/security/InvalidKeyException.cs
index e9cfa75fd..73a59fbb8 100644
--- a/crypto/src/security/InvalidKeyException.cs
+++ b/crypto/src/security/InvalidKeyException.cs
@@ -1,14 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security
 {
-#if !PORTABLE
     [Serializable]
-#endif
-    public class InvalidKeyException : KeyException
+    public class InvalidKeyException
+		: KeyException
 	{
-		public InvalidKeyException() : base() { }
-		public InvalidKeyException(string message) : base(message) { }
-		public InvalidKeyException(string message, Exception exception) : base(message, exception) { }
+		public InvalidKeyException()
+			: base()
+		{
+		}
+
+		public InvalidKeyException(string message)
+			: base(message)
+		{
+		}
+
+		public InvalidKeyException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected InvalidKeyException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/security/InvalidParameterException.cs b/crypto/src/security/InvalidParameterException.cs
index 27b2ea411..fb27a3688 100644
--- a/crypto/src/security/InvalidParameterException.cs
+++ b/crypto/src/security/InvalidParameterException.cs
@@ -1,14 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security
 {
-#if !PORTABLE
     [Serializable]
-#endif
-    public class InvalidParameterException : KeyException
+    public class InvalidParameterException
+		: KeyException
 	{
-		public InvalidParameterException() : base() { }
-		public InvalidParameterException(string message) : base(message) { }
-		public InvalidParameterException(string message, Exception exception) : base(message, exception) { }
+		public InvalidParameterException()
+			: base()
+		{
+		}
+
+		public InvalidParameterException(string message)
+			: base(message)
+		{
+		}
+
+		public InvalidParameterException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected InvalidParameterException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/security/KeyException.cs b/crypto/src/security/KeyException.cs
index 57ce6862b..1ad1b0c49 100644
--- a/crypto/src/security/KeyException.cs
+++ b/crypto/src/security/KeyException.cs
@@ -1,14 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security
 {
-#if !PORTABLE
     [Serializable]
-#endif
-    public class KeyException : GeneralSecurityException
+    public class KeyException
+		: GeneralSecurityException
 	{
-		public KeyException() : base() { }
-		public KeyException(string message) : base(message) { }
-		public KeyException(string message, Exception exception) : base(message, exception) { }
+		public KeyException()
+			: base()
+		{
+		}
+
+		public KeyException(string message)
+			: base(message)
+		{
+		}
+
+		public KeyException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected KeyException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs
index a8c4d94d0..93f8a2260 100644
--- a/crypto/src/security/PrivateKeyFactory.cs
+++ b/crypto/src/security/PrivateKeyFactory.cs
@@ -135,7 +135,7 @@ namespace Org.BouncyCastle.Security
                 Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(
                     algID.Parameters.ToAsn1Object());
 
-                X9ECParameters ecP = ECGost3410NamedCurves.GetByOidX9(gostParams.PublicKeyParamSet);
+                X9ECParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);
 
                 if (ecP == null)
                     throw new ArgumentException("Unrecognized curve OID for GostR3410x2001 private key");
@@ -198,7 +198,7 @@ namespace Org.BouncyCastle.Security
                 if (p is Asn1Sequence && (Asn1Sequence.GetInstance(p).Count == 2 || Asn1Sequence.GetInstance(p).Count == 3))
                 {
 
-                    X9ECParameters ecP = ECGost3410NamedCurves.GetByOidX9(gostParams.PublicKeyParamSet);
+                    X9ECParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);
 
                     ecSpec = new ECGost3410Parameters(
                         new ECNamedDomainParameters(
diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs
index 10b2aacdc..65baf003c 100644
--- a/crypto/src/security/PublicKeyFactory.cs
+++ b/crypto/src/security/PublicKeyFactory.cs
@@ -162,7 +162,7 @@ namespace Org.BouncyCastle.Security
                 Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);
                 DerObjectIdentifier publicKeyParamSet = gostParams.PublicKeyParamSet;
 
-                X9ECParameters ecP = ECGost3410NamedCurves.GetByOidX9(publicKeyParamSet);
+                X9ECParameters ecP = ECGost3410NamedCurves.GetByOid(publicKeyParamSet);
                 if (ecP == null)
                     return null;
 
@@ -238,7 +238,7 @@ namespace Org.BouncyCastle.Security
                 DerObjectIdentifier publicKeyParamSet = gostParams.PublicKeyParamSet;
 
                 ECGost3410Parameters ecDomainParameters =new ECGost3410Parameters(
-                    new ECNamedDomainParameters(publicKeyParamSet, ECGost3410NamedCurves.GetByOidX9(publicKeyParamSet)),
+                    new ECNamedDomainParameters(publicKeyParamSet, ECGost3410NamedCurves.GetByOid(publicKeyParamSet)),
                     publicKeyParamSet,
                     gostParams.DigestParamSet,
                     gostParams.EncryptionParamSet);
diff --git a/crypto/src/security/SecurityUtilityException.cs b/crypto/src/security/SecurityUtilityException.cs
index d3f97c1a3..f10a7fbc5 100644
--- a/crypto/src/security/SecurityUtilityException.cs
+++ b/crypto/src/security/SecurityUtilityException.cs
@@ -1,36 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class SecurityUtilityException
 		: Exception
     {
-        /**
-        * base constructor.
-        */
-        public SecurityUtilityException()
-        {
-        }
+		public SecurityUtilityException()
+			: base()
+		{
+		}
 
-		/**
-         * create a SecurityUtilityException with the given message.
-         *
-         * @param message the message to be carried with the exception.
-         */
-        public SecurityUtilityException(
-            string message)
+		public SecurityUtilityException(string message)
 			: base(message)
-        {
-        }
+		{
+		}
 
-		public SecurityUtilityException(
-            string		message,
-            Exception	exception)
-			: base(message, exception)
-        {
-        }
-    }
+		public SecurityUtilityException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected SecurityUtilityException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
diff --git a/crypto/src/security/SignatureException.cs b/crypto/src/security/SignatureException.cs
index deaa23432..4bddc3d51 100644
--- a/crypto/src/security/SignatureException.cs
+++ b/crypto/src/security/SignatureException.cs
@@ -1,14 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security
 {
-#if !PORTABLE
     [Serializable]
-#endif
-    public class SignatureException : GeneralSecurityException
+    public class SignatureException
+		: GeneralSecurityException
 	{
-		public SignatureException() : base() { }
-		public SignatureException(string message) : base(message) { }
-		public SignatureException(string message, Exception exception) : base(message, exception) { }
+		public SignatureException()
+			: base()
+		{
+		}
+
+		public SignatureException(string message)
+			: base(message)
+		{
+		}
+
+		public SignatureException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected SignatureException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/security/cert/CertificateEncodingException.cs b/crypto/src/security/cert/CertificateEncodingException.cs
index 20c965630..5c902dfd1 100644
--- a/crypto/src/security/cert/CertificateEncodingException.cs
+++ b/crypto/src/security/cert/CertificateEncodingException.cs
@@ -1,14 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security.Certificates
 {
-#if !PORTABLE
     [Serializable]
-#endif
-    public class CertificateEncodingException : CertificateException
+    public class CertificateEncodingException
+		: CertificateException
 	{
-		public CertificateEncodingException() : base() { }
-		public CertificateEncodingException(string msg) : base(msg) { }
-		public CertificateEncodingException(string msg, Exception e) : base(msg, e) { }
+		public CertificateEncodingException()
+			: base()
+		{
+		}
+
+		public CertificateEncodingException(string message)
+			: base(message)
+		{
+		}
+
+		public CertificateEncodingException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected CertificateEncodingException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/security/cert/CertificateException.cs b/crypto/src/security/cert/CertificateException.cs
index c8819b710..5214675ab 100644
--- a/crypto/src/security/cert/CertificateException.cs
+++ b/crypto/src/security/cert/CertificateException.cs
@@ -1,14 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security.Certificates
 {
-#if !PORTABLE
     [Serializable]
-#endif
-    public class CertificateException : GeneralSecurityException
+    public class CertificateException
+		: GeneralSecurityException
 	{
-		public CertificateException() : base() { }
-		public CertificateException(string message) : base(message) { }
-		public CertificateException(string message, Exception exception) : base(message, exception) { }
+		public CertificateException()
+			: base()
+		{
+		}
+
+		public CertificateException(string message)
+			: base(message)
+		{
+		}
+
+		public CertificateException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected CertificateException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/security/cert/CertificateExpiredException.cs b/crypto/src/security/cert/CertificateExpiredException.cs
index 1d12ba7e9..25cb054bf 100644
--- a/crypto/src/security/cert/CertificateExpiredException.cs
+++ b/crypto/src/security/cert/CertificateExpiredException.cs
@@ -1,14 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security.Certificates
 {
-#if !PORTABLE
     [Serializable]
-#endif
-    public class CertificateExpiredException : CertificateException
+    public class CertificateExpiredException
+		: CertificateException
 	{
-		public CertificateExpiredException() : base() { }
-		public CertificateExpiredException(string message) : base(message) { }
-		public CertificateExpiredException(string message, Exception exception) : base(message, exception) { }
+		public CertificateExpiredException()
+			: base()
+		{
+		}
+
+		public CertificateExpiredException(string message)
+			: base(message)
+		{
+		}
+
+		public CertificateExpiredException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected CertificateExpiredException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/security/cert/CertificateNotYetValidException.cs b/crypto/src/security/cert/CertificateNotYetValidException.cs
index 8de806673..1ea3d0b97 100644
--- a/crypto/src/security/cert/CertificateNotYetValidException.cs
+++ b/crypto/src/security/cert/CertificateNotYetValidException.cs
@@ -1,14 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security.Certificates
 {
-#if !PORTABLE
     [Serializable]
-#endif
-    public class CertificateNotYetValidException : CertificateException
+    public class CertificateNotYetValidException
+		: CertificateException
 	{
-		public CertificateNotYetValidException() : base() { }
-		public CertificateNotYetValidException(string message) : base(message) { }
-		public CertificateNotYetValidException(string message, Exception exception) : base(message, exception) { }
+		public CertificateNotYetValidException()
+			: base()
+		{
+		}
+
+		public CertificateNotYetValidException(string message)
+			: base(message)
+		{
+		}
+
+		public CertificateNotYetValidException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected CertificateNotYetValidException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/security/cert/CertificateParsingException.cs b/crypto/src/security/cert/CertificateParsingException.cs
index 1e0a3f47a..244f3b614 100644
--- a/crypto/src/security/cert/CertificateParsingException.cs
+++ b/crypto/src/security/cert/CertificateParsingException.cs
@@ -1,14 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security.Certificates
 {
-#if !PORTABLE
     [Serializable]
-#endif
-    public class CertificateParsingException : CertificateException
+    public class CertificateParsingException
+		: CertificateException
 	{
-		public CertificateParsingException() : base() { }
-		public CertificateParsingException(string message) : base(message) { }
-		public CertificateParsingException(string message, Exception exception) : base(message, exception) { }
+		public CertificateParsingException()
+			: base()
+		{
+		}
+
+		public CertificateParsingException(string message)
+			: base(message)
+		{
+		}
+
+		public CertificateParsingException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected CertificateParsingException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/security/cert/CrlException.cs b/crypto/src/security/cert/CrlException.cs
index 4f71bea5f..9475f74de 100644
--- a/crypto/src/security/cert/CrlException.cs
+++ b/crypto/src/security/cert/CrlException.cs
@@ -1,14 +1,30 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Security.Certificates
 {
-#if !PORTABLE
     [Serializable]
-#endif
-    public class CrlException : GeneralSecurityException
+    public class CrlException
+		: GeneralSecurityException
 	{
-		public CrlException() : base() { }
-		public CrlException(string msg) : base(msg) {}
-		public CrlException(string msg, Exception e) : base(msg, e) {}
+		public CrlException()
+			: base()
+		{
+		}
+
+		public CrlException(string message)
+			: base(message)
+		{
+		}
+
+		public CrlException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected CrlException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
 	}
 }
diff --git a/crypto/src/tls/TlsException.cs b/crypto/src/tls/TlsException.cs
index c6d7a1916..9c6d74bf4 100644
--- a/crypto/src/tls/TlsException.cs
+++ b/crypto/src/tls/TlsException.cs
@@ -1,24 +1,31 @@
 using System;
 using System.IO;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Tls
 {
-    public class TlsException
+	[Serializable]
+	public class TlsException
         : IOException
     {
-        public TlsException()
-            : base()
-        {
-        }
+		public TlsException()
+			: base()
+		{
+		}
 
-        public TlsException(string message)
-            : base(message)
-        {
-        }
+		public TlsException(string message)
+			: base(message)
+		{
+		}
 
-        public TlsException(string message, Exception cause)
-            : base(message, cause)
-        {
-        }
-    }
+		public TlsException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected TlsException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
diff --git a/crypto/src/tls/TlsFatalAlert.cs b/crypto/src/tls/TlsFatalAlert.cs
index 9f0ea8f30..511fa9fb1 100644
--- a/crypto/src/tls/TlsFatalAlert.cs
+++ b/crypto/src/tls/TlsFatalAlert.cs
@@ -1,7 +1,9 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Tls
 {
+    [Serializable]
     public class TlsFatalAlert
         : TlsException
     {
@@ -38,6 +40,11 @@ namespace Org.BouncyCastle.Tls
             this.m_alertDescription = alertDescription;
         }
 
+        protected TlsFatalAlert(SerializationInfo info, StreamingContext context)
+            : base(info, context)
+        {
+        }
+
         public virtual short AlertDescription
         {
             get { return m_alertDescription; }
diff --git a/crypto/src/tls/TlsFatalAlertReceived.cs b/crypto/src/tls/TlsFatalAlertReceived.cs
index 0bf6cff38..adf71d5b9 100644
--- a/crypto/src/tls/TlsFatalAlertReceived.cs
+++ b/crypto/src/tls/TlsFatalAlertReceived.cs
@@ -1,7 +1,9 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Tls
 {
+    [Serializable]
     public class TlsFatalAlertReceived
         : TlsException
     {
@@ -13,6 +15,11 @@ namespace Org.BouncyCastle.Tls
             this.m_alertDescription = alertDescription;
         }
 
+        protected TlsFatalAlertReceived(SerializationInfo info, StreamingContext context)
+            : base(info, context)
+        {
+        }
+
         public virtual short AlertDescription
         {
             get { return m_alertDescription; }
diff --git a/crypto/src/tls/TlsNoCloseNotifyException.cs b/crypto/src/tls/TlsNoCloseNotifyException.cs
index 8fdfbbfc4..b0314a406 100644
--- a/crypto/src/tls/TlsNoCloseNotifyException.cs
+++ b/crypto/src/tls/TlsNoCloseNotifyException.cs
@@ -1,5 +1,6 @@
 using System;
 using System.IO;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Tls
 {
@@ -10,6 +11,7 @@ namespace Org.BouncyCastle.Tls
     /// malicious). It may be possible to check for truncation via some property of a higher level protocol
     /// built upon TLS, e.g.the Content-Length header for HTTPS.
     /// </remarks>
+    [Serializable]
     public class TlsNoCloseNotifyException
         : EndOfStreamException
     {
@@ -17,5 +19,10 @@ namespace Org.BouncyCastle.Tls
             : base("No close_notify alert received before connection closed")
         {
         }
-    }
+
+		protected TlsNoCloseNotifyException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
diff --git a/crypto/src/tls/TlsTimeoutException.cs b/crypto/src/tls/TlsTimeoutException.cs
index ce2e1ac63..669352f54 100644
--- a/crypto/src/tls/TlsTimeoutException.cs
+++ b/crypto/src/tls/TlsTimeoutException.cs
@@ -1,24 +1,31 @@
 using System;
 using System.IO;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Tls
 {
-    public class TlsTimeoutException
+	[Serializable]
+	public class TlsTimeoutException
         : IOException
     {
-        public TlsTimeoutException()
-            : base()
-        {
-        }
+		public TlsTimeoutException()
+			: base()
+		{
+		}
 
-        public TlsTimeoutException(string message)
-            : base(message)
-        {
-        }
+		public TlsTimeoutException(string message)
+			: base(message)
+		{
+		}
 
-        public TlsTimeoutException(string message, Exception cause)
-            : base(message, cause)
-        {
-        }
-    }
+		public TlsTimeoutException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected TlsTimeoutException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
diff --git a/crypto/src/tls/crypto/TlsCryptoException.cs b/crypto/src/tls/crypto/TlsCryptoException.cs
index 83c3ef791..9498ddf3a 100644
--- a/crypto/src/tls/crypto/TlsCryptoException.cs
+++ b/crypto/src/tls/crypto/TlsCryptoException.cs
@@ -1,19 +1,31 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Tls.Crypto
 {
-    /// <summary>Basic exception class for crypto services to pass back a cause.</summary>
-    public class TlsCryptoException
+	/// <summary>Basic exception class for crypto services to pass back a cause.</summary>
+	[Serializable]
+	public class TlsCryptoException
         : TlsException
     {
-        public TlsCryptoException(string msg)
-            : base(msg)
-        {
-        }
+		public TlsCryptoException()
+			: base()
+		{
+		}
 
-        public TlsCryptoException(string msg, Exception cause)
-            : base(msg, cause)
-        {
-        }
-    }
+		public TlsCryptoException(string message)
+			: base(message)
+		{
+		}
+
+		public TlsCryptoException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected TlsCryptoException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
diff --git a/crypto/src/tsp/TSPException.cs b/crypto/src/tsp/TSPException.cs
index 0213490d9..2fe7fdc90 100644
--- a/crypto/src/tsp/TSPException.cs
+++ b/crypto/src/tsp/TSPException.cs
@@ -1,27 +1,29 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Tsp
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class TspException
 		: Exception
 	{
 		public TspException()
+			: base()
 		{
 		}
 
-		public TspException(
-			string message)
+		public TspException(string message)
 			: base(message)
 		{
 		}
 
-		public TspException(
-			string		message,
-			Exception	e)
-			: base(message, e)
+		public TspException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected TspException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/tsp/TSPValidationException.cs b/crypto/src/tsp/TSPValidationException.cs
index 066a398e4..eb5181f2e 100644
--- a/crypto/src/tsp/TSPValidationException.cs
+++ b/crypto/src/tsp/TSPValidationException.cs
@@ -1,4 +1,5 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Tsp
 {
@@ -8,34 +9,30 @@ namespace Org.BouncyCastle.Tsp
 	 * If a failure code is associated with the exception it can be retrieved using
 	 * the getFailureCode() method.</p>
 	 */
-#if !PORTABLE
     [Serializable]
-#endif
     public class TspValidationException
 		: TspException
 	{
 		private int failureCode;
 
-		public TspValidationException(
-			string message)
+		public TspValidationException(string message)
 			: base(message)
 		{
 			this.failureCode = -1;
 		}
 
-		public TspValidationException(
-			string	message,
-			int		failureCode)
+		public TspValidationException(string message, int failureCode)
 			: base(message)
 		{
 			this.failureCode = failureCode;
 		}
 
-		/**
-		 * Return the failure code associated with this exception - if one is set.
-		 *
-		 * @return the failure code if set, -1 otherwise.
-		 */
+		protected TspValidationException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+
+		/// <returns>The failure code associated with this exception, if one is set.</returns>
 		public int FailureCode
 		{
 			get { return failureCode; }
diff --git a/crypto/src/util/Enums.cs b/crypto/src/util/Enums.cs
index c369511d4..fb685e2a7 100644
--- a/crypto/src/util/Enums.cs
+++ b/crypto/src/util/Enums.cs
@@ -1,20 +1,15 @@
 using System;
 
-#if PORTABLE
-using System.Collections;
-using System.Reflection;
-#endif
-
 using Org.BouncyCastle.Utilities.Date;
 
 namespace Org.BouncyCastle.Utilities
 {
     internal abstract class Enums
     {
-        internal static Enum GetEnumValue(System.Type enumType, string s)
+        internal static Enum GetEnumValue(Type enumType, string s)
         {
-            if (!IsEnumType(enumType))
-                throw new ArgumentException("Not an enumeration type", "enumType");
+            if (!enumType.IsEnum)
+                throw new ArgumentException("Not an enumeration type", nameof(enumType));
 
             // We only want to parse single named constants
             if (s.Length > 0 && char.IsLetter(s[0]) && s.IndexOf(',') < 0)
@@ -28,28 +23,19 @@ namespace Org.BouncyCastle.Utilities
             throw new ArgumentException();
         }
 
-        internal static Array GetEnumValues(System.Type enumType)
+        internal static Array GetEnumValues(Type enumType)
         {
-            if (!IsEnumType(enumType))
-                throw new ArgumentException("Not an enumeration type", "enumType");
+            if (!enumType.IsEnum)
+                throw new ArgumentException("Not an enumeration type", nameof(enumType));
 
             return Enum.GetValues(enumType);
         }
 
-        internal static Enum GetArbitraryValue(System.Type enumType)
+        internal static Enum GetArbitraryValue(Type enumType)
         {
             Array values = GetEnumValues(enumType);
             int pos = (int)(DateTimeUtilities.CurrentUnixMs() & int.MaxValue) % values.Length;
             return (Enum)values.GetValue(pos);
         }
-
-        internal static bool IsEnumType(System.Type t)
-        {
-#if NEW_REFLECTION
-            return t.GetTypeInfo().IsEnum;
-#else
-            return t.IsEnum;
-#endif
-        }
     }
 }
diff --git a/crypto/src/util/MemoableResetException.cs b/crypto/src/util/MemoableResetException.cs
index 99554f6c2..8a4deb142 100644
--- a/crypto/src/util/MemoableResetException.cs
+++ b/crypto/src/util/MemoableResetException.cs
@@ -1,27 +1,38 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Utilities
 {
-    /**
+	/**
      * Exception to be thrown on a failure to reset an object implementing Memoable.
      * <p>
      * The exception extends InvalidCastException to enable users to have a single handling case,
      * only introducing specific handling of this one if required.
      * </p>
      */
-    public class MemoableResetException
+	[Serializable]
+	public class MemoableResetException
         : InvalidCastException
     {
-        /**
-         * Basic Constructor.
-         *
-         * @param msg message to be associated with this exception.
-         */
-        public MemoableResetException(string msg)
-            : base(msg)
-        {
-        }
-    }
+		public MemoableResetException()
+			: base()
+		{
+		}
 
+		public MemoableResetException(string message)
+			: base(message)
+		{
+		}
+
+		public MemoableResetException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected MemoableResetException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+	}
 }
 
diff --git a/crypto/src/util/Platform.cs b/crypto/src/util/Platform.cs
index cb96adc8b..f0b2406a5 100644
--- a/crypto/src/util/Platform.cs
+++ b/crypto/src/util/Platform.cs
@@ -1,7 +1,5 @@
 using System;
 using System.Globalization;
-using System.IO;
-using System.Text;
 
 #if PORTABLE
 using System.Collections.Generic;
@@ -17,22 +15,10 @@ namespace Org.BouncyCastle.Utilities
 
         internal static bool EqualsIgnoreCase(string a, string b)
         {
-#if PORTABLE
             return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
-#else
-            return ToUpperInvariant(a) == ToUpperInvariant(b);
-#endif
         }
 
-#if PORTABLE && !DOTNET
-        internal static string GetEnvironmentVariable(
-            string variable)
-        {
-            return null;
-        }
-#else
-        internal static string GetEnvironmentVariable(
-            string variable)
+        internal static string GetEnvironmentVariable(string variable)
         {
             try
             {
@@ -45,7 +31,6 @@ namespace Org.BouncyCastle.Utilities
                 return null;
             }
         }
-#endif
 
         internal static Exception CreateNotImplementedException(
             string message)
@@ -140,39 +125,20 @@ namespace Org.BouncyCastle.Utilities
 
         internal static string ToLowerInvariant(string s)
         {
-#if PORTABLE
             return s.ToLowerInvariant();
-#else
-            return s.ToLower(CultureInfo.InvariantCulture);
-#endif
         }
 
         internal static string ToUpperInvariant(string s)
         {
-#if PORTABLE
             return s.ToUpperInvariant();
-#else
-            return s.ToUpper(CultureInfo.InvariantCulture);
-#endif
         }
 
         internal static readonly string NewLine = Environment.NewLine;
 
-#if PORTABLE
         internal static void Dispose(IDisposable d)
         {
             d.Dispose();
         }
-#else
-        internal static void Dispose(Stream s)
-        {
-            s.Close();
-        }
-        internal static void Dispose(TextWriter t)
-        {
-            t.Close();
-        }
-#endif
 
         internal static int IndexOf(string source, string value)
         {
diff --git a/crypto/src/util/TypeExtensions.cs b/crypto/src/util/TypeExtensions.cs
deleted file mode 100644
index e2aeae4dc..000000000
--- a/crypto/src/util/TypeExtensions.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-#if NEW_REFLECTION
-
-using System;
-using System.Reflection;
-
-namespace Org.BouncyCastle
-{
-    internal static class TypeExtensions
-    {
-        public static bool IsInstanceOfType(this Type type, object instance)
-        {
-            return instance != null && type.GetTypeInfo().IsAssignableFrom(instance.GetType().GetTypeInfo());
-        }
-    }
-}
-
-#endif
diff --git a/crypto/src/util/collections/CollectionUtilities.cs b/crypto/src/util/collections/CollectionUtilities.cs
index e0c79bdf4..37551e5b3 100644
--- a/crypto/src/util/collections/CollectionUtilities.cs
+++ b/crypto/src/util/collections/CollectionUtilities.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.Text;
 
 namespace Org.BouncyCastle.Utilities.Collections
@@ -14,14 +15,14 @@ namespace Org.BouncyCastle.Utilities.Collections
             }
         }
 
-        public static bool CheckElementsAreOfType(IEnumerable e, Type t)
+        public static IEnumerable Proxy(IEnumerable e)
         {
-            foreach (object o in e)
-            {
-                if (!t.IsInstanceOfType(o))
-                    return false;
-            }
-            return true;
+            return new EnumerableProxy(e);
+        }
+
+        public static IEnumerable<T> Proxy<T>(IEnumerable<T> e)
+        {
+            return new EnumerableProxy<T>(e);
         }
 
         public static IDictionary ReadOnly(IDictionary d)
diff --git a/crypto/src/util/collections/EnumerableProxy.cs b/crypto/src/util/collections/EnumerableProxy.cs
index 9eec4af21..196b4d9df 100644
--- a/crypto/src/util/collections/EnumerableProxy.cs
+++ b/crypto/src/util/collections/EnumerableProxy.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections;
+using System.Collections.Generic;
 
 namespace Org.BouncyCastle.Utilities.Collections
 {
@@ -22,4 +23,28 @@ namespace Org.BouncyCastle.Utilities.Collections
 			return inner.GetEnumerator();
 		}
 	}
+
+	internal sealed class EnumerableProxy<T>
+		: IEnumerable<T>
+	{
+		private readonly IEnumerable<T> m_inner;
+
+		internal EnumerableProxy(IEnumerable<T> inner)
+		{
+			if (inner == null)
+				throw new ArgumentNullException("inner");
+
+			m_inner = inner;
+		}
+
+		IEnumerator IEnumerable.GetEnumerator()
+		{
+			return m_inner.GetEnumerator();
+		}
+
+		IEnumerator<T> IEnumerable<T>.GetEnumerator()
+		{
+			return m_inner.GetEnumerator();
+		}
+	}
 }
diff --git a/crypto/src/util/io/StreamOverflowException.cs b/crypto/src/util/io/StreamOverflowException.cs
index 7e100e7b5..a36919780 100644
--- a/crypto/src/util/io/StreamOverflowException.cs
+++ b/crypto/src/util/io/StreamOverflowException.cs
@@ -1,11 +1,10 @@
 using System;
 using System.IO;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Utilities.IO
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class StreamOverflowException
 		: IOException
 	{
@@ -14,16 +13,18 @@ namespace Org.BouncyCastle.Utilities.IO
 		{
 		}
 
-		public StreamOverflowException(
-			string message)
+		public StreamOverflowException(string message)
 			: base(message)
 		{
 		}
 
-		public StreamOverflowException(
-			string		message,
-			Exception	exception)
-			: base(message, exception)
+		public StreamOverflowException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected StreamOverflowException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/util/io/pem/PemGenerationException.cs b/crypto/src/util/io/pem/PemGenerationException.cs
index a49dda0e7..b7f30672e 100644
--- a/crypto/src/util/io/pem/PemGenerationException.cs
+++ b/crypto/src/util/io/pem/PemGenerationException.cs
@@ -1,10 +1,9 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.Utilities.IO.Pem
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class PemGenerationException
 		: Exception
 	{
@@ -13,16 +12,18 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 		{
 		}
 
-		public PemGenerationException(
-			string message)
+		public PemGenerationException(string message)
 			: base(message)
 		{
 		}
 
-		public PemGenerationException(
-			string		message,
-			Exception	exception)
-			: base(message, exception)
+		public PemGenerationException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected PemGenerationException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/x509/store/NoSuchStoreException.cs b/crypto/src/x509/store/NoSuchStoreException.cs
index bf6bdf76c..3acac536f 100644
--- a/crypto/src/x509/store/NoSuchStoreException.cs
+++ b/crypto/src/x509/store/NoSuchStoreException.cs
@@ -1,27 +1,29 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.X509.Store
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class NoSuchStoreException
 		: X509StoreException
 	{
 		public NoSuchStoreException()
+			: base()
 		{
 		}
 
-		public NoSuchStoreException(
-			string message)
+		public NoSuchStoreException(string message)
 			: base(message)
 		{
 		}
 
-		public NoSuchStoreException(
-			string		message,
-			Exception	e)
-			: base(message, e)
+		public NoSuchStoreException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected NoSuchStoreException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/src/x509/store/X509StoreException.cs b/crypto/src/x509/store/X509StoreException.cs
index f697c116a..0ad32c2ef 100644
--- a/crypto/src/x509/store/X509StoreException.cs
+++ b/crypto/src/x509/store/X509StoreException.cs
@@ -1,27 +1,29 @@
 using System;
+using System.Runtime.Serialization;
 
 namespace Org.BouncyCastle.X509.Store
 {
-#if !PORTABLE
     [Serializable]
-#endif
     public class X509StoreException
 		: Exception
 	{
 		public X509StoreException()
+			: base()
 		{
 		}
 
-		public X509StoreException(
-			string message)
+		public X509StoreException(string message)
 			: base(message)
 		{
 		}
 
-		public X509StoreException(
-			string		message,
-			Exception	e)
-			: base(message, e)
+		public X509StoreException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+		protected X509StoreException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
 		{
 		}
 	}
diff --git a/crypto/test/src/crypto/test/ECGOST3410_2012Test.cs b/crypto/test/src/crypto/test/ECGOST3410_2012Test.cs
index 0e7e90611..7e0a84cbe 100644
--- a/crypto/test/src/crypto/test/ECGOST3410_2012Test.cs
+++ b/crypto/test/src/crypto/test/ECGOST3410_2012Test.cs
@@ -30,7 +30,7 @@ namespace Org.BouncyCastle.Crypto.Tests
         public SimpleTestResult EncodeRecodePublicKey()
         {
             DerObjectIdentifier oid = ECGost3410NamedCurves.GetOid("Tc26-Gost-3410-12-512-paramSetA");
-            ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOidX9(oid));
+            ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOid(oid));
             ECGost3410Parameters gostParams = new ECGost3410Parameters(ecp, oid, RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512, null);
             ECKeyGenerationParameters paramameters = new ECKeyGenerationParameters(gostParams, new SecureRandom());
             ECKeyPairGenerator engine = new ECKeyPairGenerator();
@@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Crypto.Tests
         private SimpleTestResult EncodeRecodePrivateKey()
         {
             DerObjectIdentifier oid = ECGost3410NamedCurves.GetOid("Tc26-Gost-3410-12-512-paramSetA");
-            ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOidX9(oid));
+            ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOid(oid));
             ECGost3410Parameters gostParams = new ECGost3410Parameters(ecp, oid, RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512, null);
             ECKeyGenerationParameters parameters = new ECKeyGenerationParameters(gostParams, new SecureRandom());
             ECKeyPairGenerator engine = new ECKeyPairGenerator();
@@ -338,7 +338,7 @@ namespace Org.BouncyCastle.Crypto.Tests
         public SimpleTestResult EncodeDecodePrivateLW(string oidStr, DerObjectIdentifier digest)
         {
             DerObjectIdentifier oid = ECGost3410NamedCurves.GetOid(oidStr);
-            ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOidX9(oid));
+            ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOid(oid));
             ECGost3410Parameters gostParams = new ECGost3410Parameters(ecp, oid, digest, null);
             ECKeyGenerationParameters parameters = new ECKeyGenerationParameters(gostParams, new SecureRandom());
             ECKeyPairGenerator engine = new ECKeyPairGenerator();
@@ -421,7 +421,7 @@ namespace Org.BouncyCastle.Crypto.Tests
         public SimpleTestResult EncodeDecodePublicLW(string oidStr, DerObjectIdentifier digest)
         {
             DerObjectIdentifier oid = ECGost3410NamedCurves.GetOid(oidStr);
-            ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOidX9(oid));
+            ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOid(oid));
             ECGost3410Parameters gostParams = new ECGost3410Parameters(ecp, oid, digest, null);
             ECKeyGenerationParameters parameters = new ECKeyGenerationParameters(gostParams, new SecureRandom());
             ECKeyPairGenerator engine = new ECKeyPairGenerator();
diff --git a/crypto/test/src/crypto/test/ECTest.cs b/crypto/test/src/crypto/test/ECTest.cs
index 18abb8df1..58dc75e2f 100644
--- a/crypto/test/src/crypto/test/ECTest.cs
+++ b/crypto/test/src/crypto/test/ECTest.cs
@@ -745,8 +745,19 @@ namespace Org.BouncyCastle.Crypto.Tests
         {
             SecureRandom random = new SecureRandom();
 
-            X9ECParameters x9 = CustomNamedCurves.GetByName("curve25519");
-            ECDomainParameters ec = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());
+            // "curve25519" in short Weierstrass form
+            BigInteger q = BigInteger.One.ShiftLeft(255).Subtract(BigInteger.ValueOf(19));
+            BigInteger a = new BigInteger(1, Hex.DecodeStrict("2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144"));
+            BigInteger b = new BigInteger(1, Hex.DecodeStrict("7B425ED097B425ED097B425ED097B425ED097B425ED097B4260B5E9C7710C864"));
+            BigInteger n = new BigInteger(1, Hex.DecodeStrict("1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED"));
+            BigInteger h = BigInteger.ValueOf(8);
+
+            ECCurve curve = new FpCurve(q, a, b, n, h);
+            X9ECPoint G = new X9ECPoint(curve,
+                Hex.DecodeStrict("042AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9"));
+
+            X9ECParameters x9 = new X9ECParameters(curve, G, n, h);
+            ECDomainParameters ec = new ECDomainParameters(x9);
 
             ECKeyPairGenerator kpg = new ECKeyPairGenerator();
             kpg.Init(new ECKeyGenerationParameters(ec, random));
diff --git a/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs b/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs
index e36947b11..059416427 100644
--- a/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs
+++ b/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs
@@ -1,17 +1,13 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.Text;
 
 using NUnit.Framework;
 
 using Org.BouncyCastle.Asn1;
-using Org.BouncyCastle.Asn1.Sec;
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Crypto.EC;
-using Org.BouncyCastle.Math;
-using Org.BouncyCastle.Math.EC;
 using Org.BouncyCastle.Security;
-using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Date;
 
@@ -98,6 +94,8 @@ namespace Org.BouncyCastle.Math.EC.Tests
                     Console.WriteLine(sb.ToString());
                 }
             }
+
+            Console.Out.Flush();
         }
 
         private double RandMult(SecureRandom random, ECPoint g, BigInteger n)
@@ -175,12 +173,12 @@ namespace Org.BouncyCastle.Math.EC.Tests
         [Test, Explicit]
         public void TestMultiply()
         {
-            ArrayList nameList = new ArrayList();
-            CollectionUtilities.AddRange(nameList, ECNamedCurveTable.Names);
-            CollectionUtilities.AddRange(nameList, CustomNamedCurves.Names);
+            var names = new List<string>();
+            names.AddRange(ECNamedCurveTable.Names);
+            names.AddRange(CustomNamedCurves.Names);
+
+            names.Sort();
 
-            string[] names = (string[])nameList.ToArray(typeof(string));
-            Array.Sort(names);
             ISet oids = new HashSet();
             foreach (string name in names)
             {
diff --git a/crypto/test/src/math/ec/test/ECPointTest.cs b/crypto/test/src/math/ec/test/ECPointTest.cs
index f3fc6e592..4e3fc5832 100644
--- a/crypto/test/src/math/ec/test/ECPointTest.cs
+++ b/crypto/test/src/math/ec/test/ECPointTest.cs
@@ -1,11 +1,10 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using NUnit.Framework;
 
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Crypto.EC;
-using Org.BouncyCastle.Math.EC.Multiplier;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
@@ -535,9 +534,9 @@ namespace Org.BouncyCastle.Math.EC.Tests
         [Test]
         public void TestAddSubtractMultiplyTwiceEncoding()
         {
-            ArrayList names = new ArrayList();
-            CollectionUtilities.AddRange(names, ECNamedCurveTable.Names);
-            CollectionUtilities.AddRange(names, CustomNamedCurves.Names);
+            var names = new List<string>();
+            names.AddRange(ECNamedCurveTable.Names);
+            names.AddRange(CustomNamedCurves.Names);
 
             ISet uniqNames = new HashSet(names);
 
diff --git a/crypto/test/src/math/ec/test/FixedPointTest.cs b/crypto/test/src/math/ec/test/FixedPointTest.cs
index 83e5fab8f..433f956da 100644
--- a/crypto/test/src/math/ec/test/FixedPointTest.cs
+++ b/crypto/test/src/math/ec/test/FixedPointTest.cs
@@ -1,5 +1,5 @@
 using System;
-using System.Collections;
+using System.Collections.Generic;
 
 using NUnit.Framework;
 
@@ -23,9 +23,9 @@ namespace Org.BouncyCastle.Math.EC.Tests
         {
             FixedPointCombMultiplier M = new FixedPointCombMultiplier();
 
-            ArrayList names = new ArrayList();
-            CollectionUtilities.AddRange(names, ECNamedCurveTable.Names);
-            CollectionUtilities.AddRange(names, CustomNamedCurves.Names);
+            var names = new List<string>();
+            names.AddRange(ECNamedCurveTable.Names);
+            names.AddRange(CustomNamedCurves.Names);
 
             ISet uniqNames = new HashSet(names);
 
@@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Math.EC.Tests
                 X9ECParameters x9A = ECNamedCurveTable.GetByName(name);
                 X9ECParameters x9B = CustomNamedCurves.GetByName(name);
 
-                X9ECParameters x9 = x9B != null ? x9B : x9A;
+                X9ECParameters x9 = x9B ?? x9A;
 
                 for (int i = 0; i < TestsPerCurve; ++i)
                 {
diff --git a/crypto/test/src/pqc/crypto/lms/HSSTests.cs b/crypto/test/src/pqc/crypto/lms/HSSTests.cs
index 6918da102..d97038d3b 100644
--- a/crypto/test/src/pqc/crypto/lms/HSSTests.cs
+++ b/crypto/test/src/pqc/crypto/lms/HSSTests.cs
@@ -470,7 +470,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                 byte[] hssPubEnc = null;
                 MemoryStream fixedESBuffer = new MemoryStream();
                 IList sigVectors = new ArrayList();
-                int d = 0, j = 0;
+                int d = 0;
 
                 string line;
                 while ((line = sr.ReadLine()) != null)
diff --git a/crypto/test/src/pqc/crypto/lms/LMSTests.cs b/crypto/test/src/pqc/crypto/lms/LMSTests.cs
index 4b5d6206f..dbc541674 100644
--- a/crypto/test/src/pqc/crypto/lms/LMSTests.cs
+++ b/crypto/test/src/pqc/crypto/lms/LMSTests.cs
@@ -158,20 +158,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                 ctx.Update((byte)1);
                 Assert.Fail("Digest reuse after signature taken.");
             }
-            catch (NullReferenceException npe)
+            catch (NullReferenceException)
             {
-                Assert.True(true);
+                // Expected
             }
-
         }
-            
-        public void Main(string[] args)
-        {
-            TestCoefFunc();
-            TestPrivateKeyRound();
-            TestLMS();
-            TestContextSingleUse();
-        }
-
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/test/src/util/test/SimpleTest.cs b/crypto/test/src/util/test/SimpleTest.cs
index fc88be103..1695164e5 100644
--- a/crypto/test/src/util/test/SimpleTest.cs
+++ b/crypto/test/src/util/test/SimpleTest.cs
@@ -108,7 +108,7 @@ namespace Org.BouncyCastle.Utilities.Test
             }
             catch (TestFailedException e)
             {
-                return e.GetResult();
+                return e.Result;
             }
             catch (Exception e)
             {
diff --git a/crypto/test/src/util/test/TestFailedException.cs b/crypto/test/src/util/test/TestFailedException.cs
index 215e1fd20..2ea66087d 100644
--- a/crypto/test/src/util/test/TestFailedException.cs
+++ b/crypto/test/src/util/test/TestFailedException.cs
@@ -2,23 +2,20 @@ using System;
 
 namespace Org.BouncyCastle.Utilities.Test
 {
-#if !PORTABLE
-    [Serializable]
-#endif
     public class TestFailedException
         : Exception
     {
-        private ITestResult _result;
+        private readonly ITestResult m_result;
 
-        public TestFailedException(
-            ITestResult result)
+        public TestFailedException(ITestResult result)
+            : base()
         {
-            _result = result;
+            m_result = result;
         }
 
-        public ITestResult GetResult()
+        public ITestResult Result
         {
-            return _result;
+            get { return m_result; }
         }
     }
 }