summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Hook <dgh@cryptoworkshop.com>2022-07-13 06:26:52 +1000
committerDavid Hook <dgh@cryptoworkshop.com>2022-07-13 06:26:52 +1000
commit098d19d9eda97fe8569e07e7901b0d1b3c2898ba (patch)
tree92911e7a58b9956a0e5d499bcc37df3fdcbd585d
parentinitial Haraka install (diff)
parentRefactoring in Picnic (diff)
downloadBouncyCastle.NET-ed25519-098d19d9eda97fe8569e07e7901b0d1b3c2898ba.tar.xz
Merge remote-tracking branch 'refs/remotes/origin/master'
-rw-r--r--crypto/src/asn1/nist/NISTNamedCurves.cs8
-rw-r--r--crypto/src/asn1/x9/ECNamedCurveTable.cs8
-rw-r--r--crypto/src/crypto/prng/SP800SecureRandom.cs16
-rw-r--r--crypto/src/crypto/prng/X931Rng.cs21
-rw-r--r--crypto/src/crypto/prng/X931SecureRandom.cs16
-rw-r--r--crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs17
-rw-r--r--crypto/src/crypto/prng/drbg/DrbgUtilities.cs5
-rw-r--r--crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs11
-rw-r--r--crypto/src/crypto/prng/drbg/HashSP800Drbg.cs7
-rw-r--r--crypto/src/crypto/prng/drbg/ISP80090Drbg.cs2
-rw-r--r--crypto/src/pkix/PkixCertPathValidatorUtilities.cs18
-rw-r--r--crypto/src/pqc/crypto/picnic/PicnicEngine.cs460
-rw-r--r--crypto/src/pqc/crypto/picnic/Utils.cs67
-rw-r--r--crypto/src/pqc/crypto/sike/SIKEEngine.cs37
-rw-r--r--crypto/src/tls/AbstractTlsClient.cs4
-rw-r--r--crypto/src/tls/CertificateRequest.cs8
-rw-r--r--crypto/src/tls/CertificateStatus.cs2
-rw-r--r--crypto/src/tls/CertificateUrl.cs4
-rw-r--r--crypto/src/tls/DefaultTlsDHGroupVerifier.cs2
-rw-r--r--crypto/src/tls/DefaultTlsSrpConfigVerifier.cs2
-rw-r--r--crypto/src/tls/OcspStatusRequest.cs4
-rw-r--r--crypto/src/tls/ServerNameList.cs4
-rw-r--r--crypto/src/tls/TlsClient.cs5
-rw-r--r--crypto/src/tls/TlsExtensionsUtilities.cs8
-rw-r--r--crypto/src/tls/TlsServer.cs2
-rw-r--r--crypto/src/tls/crypto/TlsCrypto.cs2
-rw-r--r--crypto/src/util/date/DateTimeUtilities.cs4
-rw-r--r--crypto/src/x509/extension/X509ExtensionUtil.cs85
-rw-r--r--crypto/test/src/crypto/prng/test/CtrDrbgTest.cs6
-rw-r--r--crypto/test/src/crypto/prng/test/HMacDrbgTest.cs4
-rw-r--r--crypto/test/src/crypto/prng/test/HashDrbgTest.cs4
-rw-r--r--crypto/test/src/crypto/test/DSATest.cs6
-rw-r--r--crypto/test/src/crypto/test/GOST3410Test.cs64
-rw-r--r--crypto/test/src/crypto/test/OAEPTest.cs10
-rw-r--r--crypto/test/src/crypto/test/PSSBlindTest.cs10
-rw-r--r--crypto/test/src/crypto/test/PSSTest.cs10
-rw-r--r--crypto/test/src/crypto/test/RC2WrapTest.cs10
-rw-r--r--crypto/test/src/pqc/crypto/lms/HSSTests.cs13
-rw-r--r--crypto/test/src/pqc/crypto/test/NistSecureRandom.cs21
-rw-r--r--crypto/test/src/test/BlockCipherTest.cs17
-rw-r--r--crypto/test/src/test/DESedeTest.cs29
-rw-r--r--crypto/test/src/test/DSATest.cs11
-rw-r--r--crypto/test/src/test/PSSTest.cs13
-rw-r--r--crypto/test/src/test/RSATest.cs17
-rw-r--r--crypto/test/src/util/test/FixedSecureRandom.cs25
45 files changed, 492 insertions, 607 deletions
diff --git a/crypto/src/asn1/nist/NISTNamedCurves.cs b/crypto/src/asn1/nist/NISTNamedCurves.cs
index b9307c879..fe39cc56c 100644
--- a/crypto/src/asn1/nist/NISTNamedCurves.cs
+++ b/crypto/src/asn1/nist/NISTNamedCurves.cs
@@ -55,8 +55,8 @@ namespace Org.BouncyCastle.Asn1.Nist
 
         /// <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"/>.
+        /// Allows accessing the <see cref="Math.EC.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)
@@ -76,8 +76,8 @@ namespace Org.BouncyCastle.Asn1.Nist
         /// <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"/>.
+        /// Allows accessing the <see cref="Math.EC.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)
diff --git a/crypto/src/asn1/x9/ECNamedCurveTable.cs b/crypto/src/asn1/x9/ECNamedCurveTable.cs
index 9243c341e..073b2f221 100644
--- a/crypto/src/asn1/x9/ECNamedCurveTable.cs
+++ b/crypto/src/asn1/x9/ECNamedCurveTable.cs
@@ -47,8 +47,8 @@ namespace Org.BouncyCastle.Asn1.X9
 
         /// <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"/>.
+        /// Allows accessing the <see cref="Math.EC.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)
@@ -116,8 +116,8 @@ namespace Org.BouncyCastle.Asn1.X9
         /// <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"/>.
+        /// Allows accessing the <see cref="Math.EC.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)
diff --git a/crypto/src/crypto/prng/SP800SecureRandom.cs b/crypto/src/crypto/prng/SP800SecureRandom.cs
index 30c838c1b..2e1484125 100644
--- a/crypto/src/crypto/prng/SP800SecureRandom.cs
+++ b/crypto/src/crypto/prng/SP800SecureRandom.cs
@@ -49,6 +49,11 @@ namespace Org.BouncyCastle.Crypto.Prng
 
         public override void NextBytes(byte[] bytes)
         {
+            NextBytes(bytes, 0, bytes.Length);
+        }
+
+        public override void NextBytes(byte[] buf, int off, int len)
+        {
             lock (this)
             {
                 if (mDrbg == null)
@@ -57,21 +62,14 @@ namespace Org.BouncyCastle.Crypto.Prng
                 }
 
                 // check if a reseed is required...
-                if (mDrbg.Generate(bytes, null, mPredictionResistant) < 0)
+                if (mDrbg.Generate(buf, off, len, null, mPredictionResistant) < 0)
                 {
                     mDrbg.Reseed(null);
-                    mDrbg.Generate(bytes, null, mPredictionResistant);
+                    mDrbg.Generate(buf, off, len, null, mPredictionResistant);
                 }
             }
         }
 
-        public override void NextBytes(byte[] buf, int off, int len)
-        {
-            byte[] bytes = new byte[len];
-            NextBytes(bytes);
-            Array.Copy(bytes, 0, buf, off, len);
-        }
-
         public override byte[] GenerateSeed(int numBytes)
         {
             return EntropyUtilities.GenerateSeed(mEntropySource, numBytes);
diff --git a/crypto/src/crypto/prng/X931Rng.cs b/crypto/src/crypto/prng/X931Rng.cs
index 2bd8e0c6b..53c982c25 100644
--- a/crypto/src/crypto/prng/X931Rng.cs
+++ b/crypto/src/crypto/prng/X931Rng.cs
@@ -46,14 +46,14 @@ namespace Org.BouncyCastle.Crypto.Prng
          *
          * @return number of bits generated, -1 if a reseed required.
          */
-        internal int Generate(byte[] output, bool predictionResistant)
+        internal int Generate(byte[] output, int outputOff, int outputLen,  bool predictionResistant)
         {
             if (mR.Length == 8) // 64 bit block size
             {
                 if (mReseedCounter > BLOCK64_RESEED_MAX)
                     return -1;
 
-                if (IsTooLarge(output, BLOCK64_MAX_BITS_REQUEST / 8))
+                if (outputLen > BLOCK64_MAX_BITS_REQUEST / 8)
                     throw new ArgumentException("Number of bits per request limited to " + BLOCK64_MAX_BITS_REQUEST, "output");
             }
             else
@@ -61,7 +61,7 @@ namespace Org.BouncyCastle.Crypto.Prng
                 if (mReseedCounter > BLOCK128_RESEED_MAX)
                     return -1;
 
-                if (IsTooLarge(output, BLOCK128_MAX_BITS_REQUEST / 8))
+                if (outputLen > BLOCK128_MAX_BITS_REQUEST / 8)
                     throw new ArgumentException("Number of bits per request limited to " + BLOCK128_MAX_BITS_REQUEST, "output");
             }
 
@@ -72,7 +72,7 @@ namespace Org.BouncyCastle.Crypto.Prng
                     throw new InvalidOperationException("Insufficient entropy returned");
             }
 
-            int m = output.Length / mR.Length;
+            int m = outputLen / mR.Length;
 
             for (int i = 0; i < m; i++)
             {
@@ -80,12 +80,12 @@ namespace Org.BouncyCastle.Crypto.Prng
                 Process(mR, mI, mV);
                 Process(mV, mR, mI);
 
-                Array.Copy(mR, 0, output, i * mR.Length, mR.Length);
+                Array.Copy(mR, 0, output, outputOff + i * mR.Length, mR.Length);
 
                 Increment(mDT);
             }
 
-            int bytesToCopy = (output.Length - m * mR.Length);
+            int bytesToCopy = (outputLen - m * mR.Length);
 
             if (bytesToCopy > 0)
             {
@@ -93,14 +93,14 @@ namespace Org.BouncyCastle.Crypto.Prng
                 Process(mR, mI, mV);
                 Process(mV, mR, mI);
 
-                Array.Copy(mR, 0, output, m * mR.Length, bytesToCopy);
+                Array.Copy(mR, 0, output, outputOff + m * mR.Length, bytesToCopy);
 
                 Increment(mDT);
             }
 
             mReseedCounter++;
 
-            return output.Length;
+            return outputLen * 8;
         }
 
         /**
@@ -137,10 +137,5 @@ namespace Org.BouncyCastle.Crypto.Prng
                     break;
             }
         }
-
-        private static bool IsTooLarge(byte[] bytes, int maxBytes)
-        {
-            return bytes != null && bytes.Length > maxBytes;
-        }
     }
 }
diff --git a/crypto/src/crypto/prng/X931SecureRandom.cs b/crypto/src/crypto/prng/X931SecureRandom.cs
index d2e4849c5..1402e5c31 100644
--- a/crypto/src/crypto/prng/X931SecureRandom.cs
+++ b/crypto/src/crypto/prng/X931SecureRandom.cs
@@ -44,24 +44,22 @@ namespace Org.BouncyCastle.Crypto.Prng
 
         public override void NextBytes(byte[] bytes)
         {
+            NextBytes(bytes, 0, bytes.Length);
+        }
+
+        public override void NextBytes(byte[] buf, int off, int len)
+        {
             lock (this)
             {
                 // check if a reseed is required...
-                if (mDrbg.Generate(bytes, mPredictionResistant) < 0)
+                if (mDrbg.Generate(buf, off, len, mPredictionResistant) < 0)
                 {
                     mDrbg.Reseed();
-                    mDrbg.Generate(bytes, mPredictionResistant);
+                    mDrbg.Generate(buf, off, len, mPredictionResistant);
                 }
             }
         }
 
-        public override void NextBytes(byte[] buf, int off, int len)
-        {
-            byte[] bytes = new byte[len];
-            NextBytes(bytes);
-            Array.Copy(bytes, 0, buf, off, len);
-        }
-
         public override byte[] GenerateSeed(int numBytes)
         {
             return EntropyUtilities.GenerateSeed(mDrbg.EntropySource, numBytes);
diff --git a/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs b/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs
index 5715a915e..a7b1326c3 100644
--- a/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs
+++ b/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs
@@ -331,14 +331,15 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 	     *
 	     * @return number of bits generated, -1 if a reseed required.
 	     */
-	    public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant)
+	    public int Generate(byte[] output, int outputOff, int outputLen, byte[] additionalInput,
+			bool predictionResistant)
 	    {
 	        if (mIsTdea)
 	        {
 	            if (mReseedCounter > TDEA_RESEED_MAX)
 	                return -1;
 
-                if (DrbgUtilities.IsTooLarge(output, TDEA_MAX_BITS_REQUEST / 8))
+                if (outputLen > TDEA_MAX_BITS_REQUEST / 8)
 	                throw new ArgumentException("Number of bits per request limited to " + TDEA_MAX_BITS_REQUEST, "output");
 	        }
 	        else
@@ -346,7 +347,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 	            if (mReseedCounter > AES_RESEED_MAX)
 	                return -1;
 
-                if (DrbgUtilities.IsTooLarge(output, AES_MAX_BITS_REQUEST / 8))
+                if (outputLen > AES_MAX_BITS_REQUEST / 8)
 	                throw new ArgumentException("Number of bits per request limited to " + AES_MAX_BITS_REQUEST, "output");
 	        }
 
@@ -370,11 +371,9 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 
             mEngine.Init(true, new KeyParameter(ExpandKey(mKey)));
 
-            for (int i = 0; i <= output.Length / tmp.Length; i++)
+            for (int i = 0, limit = outputLen / tmp.Length; i <= limit; i++)
 	        {
-				int bytesToCopy = ((output.Length - i * tmp.Length) > tmp.Length)
-					? tmp.Length
-	                : (output.Length - i * mV.Length);
+				int bytesToCopy = System.Math.Min(tmp.Length, outputLen - i * tmp.Length);
 
                 if (bytesToCopy != 0)
 	            {
@@ -382,7 +381,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 
                     mEngine.ProcessBlock(mV, 0, tmp, 0);
 
-                    Array.Copy(tmp, 0, output, i * tmp.Length, bytesToCopy);
+                    Array.Copy(tmp, 0, output, outputOff + i * tmp.Length, bytesToCopy);
 	            }
 	        }
 
@@ -390,7 +389,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 
             mReseedCounter++;
 
-            return output.Length * 8;
+            return outputLen * 8;
 	    }
 
 	    /**
diff --git a/crypto/src/crypto/prng/drbg/DrbgUtilities.cs b/crypto/src/crypto/prng/drbg/DrbgUtilities.cs
index b1f2f29be..58baaf5d9 100644
--- a/crypto/src/crypto/prng/drbg/DrbgUtilities.cs
+++ b/crypto/src/crypto/prng/drbg/DrbgUtilities.cs
@@ -95,10 +95,5 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 
             return temp;
 	    }
-
-        internal static bool IsTooLarge(byte[] bytes, int maxBytes)
-	    {
-	        return bytes != null && bytes.Length > maxBytes;
-	    }
 	}
 }
diff --git a/crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs b/crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs
index 78331705e..0ec0e8b71 100644
--- a/crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs
+++ b/crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs
@@ -104,9 +104,10 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 	     *
 	     * @return number of bits generated, -1 if a reseed required.
 	     */
-	    public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant)
+	    public int Generate(byte[] output, int outputOff, int outputLen, byte[] additionalInput,
+			bool predictionResistant)
 	    {
-	        int numberOfBits = output.Length * 8;
+	        int numberOfBits = outputLen * 8;
 
             if (numberOfBits > MAX_BITS_REQUEST)
 	            throw new ArgumentException("Number of bits per request limited to " + MAX_BITS_REQUEST, "output");
@@ -129,9 +130,9 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 	        }
 
             // 3.
-	        byte[] rv = new byte[output.Length];
+	        byte[] rv = new byte[outputLen];
 
-            int m = output.Length / mV.Length;
+            int m = outputLen / mV.Length;
 
             mHMac.Init(new KeyParameter(mK));
 
@@ -155,7 +156,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 
 	        mReseedCounter++;
 
-	        Array.Copy(rv, 0, output, 0, output.Length);
+	        Array.Copy(rv, 0, output, outputOff, outputLen);
 
             return numberOfBits;
 	    }
diff --git a/crypto/src/crypto/prng/drbg/HashSP800Drbg.cs b/crypto/src/crypto/prng/drbg/HashSP800Drbg.cs
index 506517aae..accc65ec3 100644
--- a/crypto/src/crypto/prng/drbg/HashSP800Drbg.cs
+++ b/crypto/src/crypto/prng/drbg/HashSP800Drbg.cs
@@ -101,7 +101,8 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 	     *
 	     * @return number of bits generated, -1 if a reseed required.
 	     */
-	    public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant)
+	    public int Generate(byte[] output, int outputOff, int outputLen, byte[] additionalInput,
+			bool predictionResistant)
 	    {
 	        // 1. If reseed_counter > reseed_interval, then return an indication that a
 	        // reseed is required.
@@ -116,7 +117,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 	        // 6. reseed_counter = reseed_counter + 1.
 	        // 7. Return SUCCESS, returned_bits, and the new values of V, C, and
 	        // reseed_counter for the new_working_state.
-	        int numberOfBits = output.Length * 8;
+	        int numberOfBits = outputLen * 8;
 
 	        if (numberOfBits > MAX_BITS_REQUEST)
 	            throw new ArgumentException("Number of bits per request limited to " + MAX_BITS_REQUEST, "output");
@@ -166,7 +167,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 
 	        mReseedCounter++;
 
-	        Array.Copy(rv, 0, output, 0, output.Length);
+	        Array.Copy(rv, 0, output, outputOff, outputLen);
 
 	        return numberOfBits;
 	    }
diff --git a/crypto/src/crypto/prng/drbg/ISP80090Drbg.cs b/crypto/src/crypto/prng/drbg/ISP80090Drbg.cs
index 0e398209e..78cbcd92f 100644
--- a/crypto/src/crypto/prng/drbg/ISP80090Drbg.cs
+++ b/crypto/src/crypto/prng/drbg/ISP80090Drbg.cs
@@ -23,7 +23,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
 	     *
 	     * @return number of bits generated, -1 if a reseed required.
 	     */
-	    int Generate(byte[] output, byte[] additionalInput, bool predictionResistant);
+	    int Generate(byte[] output, int outputOff, int outputLen, byte[] additionalInput, bool predictionResistant);
 
 	    /**
 	     * Reseed the DRBG.
diff --git a/crypto/src/pkix/PkixCertPathValidatorUtilities.cs b/crypto/src/pkix/PkixCertPathValidatorUtilities.cs
index fccd0b3c5..2514f1df2 100644
--- a/crypto/src/pkix/PkixCertPathValidatorUtilities.cs
+++ b/crypto/src/pkix/PkixCertPathValidatorUtilities.cs
@@ -1042,23 +1042,9 @@ namespace Org.BouncyCastle.Pkix
 			return certs;
 		}
 
-		/// <summary>
-		/// Extract the value of the given extension, if it exists.
-		/// </summary>
-		/// <param name="ext">The extension object.</param>
-		/// <param name="oid">The object identifier to obtain.</param>
-		/// <returns>Asn1Object</returns>
-		/// <exception cref="Exception">if the extension cannot be read.</exception>
-		internal static Asn1Object GetExtensionValue(
-			IX509Extension		ext,
-			DerObjectIdentifier	oid)
+		internal static Asn1Object GetExtensionValue(IX509Extension extensions, DerObjectIdentifier oid)
 		{
-			Asn1OctetString bytes = ext.GetExtensionValue(oid);
-
-			if (bytes == null)
-				return null;
-
-			return X509ExtensionUtilities.FromExtensionValue(bytes);
+			return X509ExtensionUtilities.FromExtensionValue(extensions, oid);
 		}
 	}
 }
diff --git a/crypto/src/pqc/crypto/picnic/PicnicEngine.cs b/crypto/src/pqc/crypto/picnic/PicnicEngine.cs
index da6a9215c..605a27764 100644
--- a/crypto/src/pqc/crypto/picnic/PicnicEngine.cs
+++ b/crypto/src/pqc/crypto/picnic/PicnicEngine.cs
@@ -1,4 +1,5 @@
 using System;
+
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Digests;
 using Org.BouncyCastle.Crypto.Utilities;
@@ -270,46 +271,37 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             seedSizeBytes = Utils.NumBytes(2 * pqSecurityLevel);
             stateSizeWords = (stateSizeBits + WORD_SIZE_BITS - 1) / WORD_SIZE_BITS;
 
-
-
             switch (parameters)
             {
-                case 1:
-                case 3:
-                case 5:
-                case 7:
-                case 8:
-                case 9:
-                case 10:
-                case 11:
-                case 12:
-                    transform = TRANSFORM_FS;
-                    break;
-                case 2:
-                case 4:
-                case 6:
-                    transform = TRANSFORM_UR;
-                    break;
-                default:
-                    transform = TRANSFORM_INVALID;
-                    break;
+            case 1:
+            case 3:
+            case 5:
+            case 7:
+            case 8:
+            case 9:
+            case 10:
+            case 11:
+            case 12:
+                transform = TRANSFORM_FS;
+                break;
+            case 2:
+            case 4:
+            case 6:
+                transform = TRANSFORM_UR;
+                break;
+            default:
+                transform = TRANSFORM_INVALID;
+                break;
             }
 
-
             if (transform == 1)
             {
                 UnruhGWithoutInputBytes = seedSizeBytes + andSizeBytes;
                 UnruhGWithInputBytes = UnruhGWithoutInputBytes + stateSizeBytes;
             }
 
-            if (stateSizeBits == 128 || stateSizeBits == 129)
-            {
-                digest = new ShakeDigest(128);
-            }
-            else
-            {
-                digest = new ShakeDigest(256);
-            }
+            int shakeSize = (stateSizeBits == 128 || stateSizeBits == 129) ? 128 : 256;
+            digest = new ShakeDigest(shakeSize);
         }
 
         public bool crypto_sign_open(byte[] m, byte[] sm, byte[] pk)
@@ -317,7 +309,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             uint sigLen = Pack.LE_To_UInt32(sm, 0);
             byte[] m_from_sm = Arrays.CopyOfRange(sm, 4, 4 + m.Length);
             int ret = picnic_verify(pk, m_from_sm, sm, sigLen);
-            System.Array.Copy(sm, 4, m, 0, m.Length);
+            Array.Copy(sm, 4, m, 0, m.Length);
             return ret != -1;
         }
 
@@ -337,7 +329,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                 Signature2 sig = new Signature2(this);
                 DeserializeSignature2(sig, signature, sigLen, message.Length + 4);
 
-
                 return verify_picnic3(sig, ciphertext, plaintext, message);
             }
             else
@@ -410,24 +401,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                 // create ordered array of commitments with order computed based on the challenge
                 // check commitments of the two opened views
                 int challenge = GetChallenge(received_challengebits, i);
-                Commit(proofs[i].seed1, 0, view1s[i],  AS[i]
-                [challenge])
-
-                ;
-                Commit(proofs[i].seed2, 0, view2s[i],  AS[i]
-                [ (challenge
-
-                +1) % 3]);
-                System.Array.Copy(proofs[i].view3Commitment, 0,  AS[i]
-                [ (challenge
-
-                +2) % 3], 0, digestSizeBytes);
+                Commit(proofs[i].seed1, 0, view1s[i],  AS[i][challenge]);
+                Commit(proofs[i].seed2, 0, view2s[i],  AS[i][(challenge + 1) % 3]);
+                Array.Copy(proofs[i].view3Commitment, 0,  AS[i][(challenge + 2) % 3], 0, digestSizeBytes);
                 if (transform == TRANSFORM_UR)
                 {
                     G(challenge, proofs[i].seed1, 0, view1s[i], gs[i][challenge]);
                     G((challenge + 1) % 3, proofs[i].seed2, 0, view2s[i], gs[i][(challenge + 1) % 3]);
                     int view3UnruhLength = (challenge == 0) ? UnruhGWithInputBytes : UnruhGWithoutInputBytes;
-                    System.Array.Copy(proofs[i].view3UnruhG, 0, gs[i][(challenge + 2) % 3], 0, view3UnruhLength);
+                    Array.Copy(proofs[i].view3UnruhG, 0, gs[i][(challenge + 2) % 3], 0, view3UnruhLength);
                 }
 
                 viewOutputs[i][challenge] = view1s[i].outputShare;
@@ -439,9 +421,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
 
             computed_challengebits = new byte[Utils.NumBytes(2 * numMPCRounds)];
 
-            H3(pubKey, plaintext, viewOutputs, 
-                AS, computed_challengebits, sig.salt,
-            message, gs);
+            H3(pubKey, plaintext, viewOutputs, AS, computed_challengebits, sig.salt, message, gs);
 
             if (!SubarrayEquals(received_challengebits, computed_challengebits, Utils.NumBytes(2 * numMPCRounds)))
             {
@@ -455,7 +435,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
         void VerifyProof(Signature.Proof proof, View view1, View view2, int challenge, byte[] salt, 
             uint roundNumber, byte[] tmp, uint[] plaintext, Tape tape)
         {
-            System.Array.Copy(proof.communicatedBits, 0, view2.communicatedBits, 0, andSizeBytes);
+            Array.Copy(proof.communicatedBits, 0, view2.communicatedBits, 0, andSizeBytes);
             tape.pos = 0;
 
 //        Console.Error.Write("tmp: " + Hex.toHexString(tmp));
@@ -463,66 +443,71 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             bool status = false;
             switch (challenge)
             {
-                case 0:
-                    // in this case, both views' inputs are derivable from the input share
-                    status = CreateRandomTape(proof.seed1, 0, salt, roundNumber,
-                        0, tmp, stateSizeBytes + andSizeBytes);
+            case 0:
+            {
+                // in this case, both views' inputs are derivable from the input share
+                status = CreateRandomTape(proof.seed1, 0, salt, roundNumber,
+                    0, tmp, stateSizeBytes + andSizeBytes);
 
-                    Pack.LE_To_UInt32(tmp, 0, view1.inputShare); //todo check
-                    System.Array.Copy(tmp, stateSizeBytes, tape.tapes[0], 0, andSizeBytes);
+                Pack.LE_To_UInt32(tmp, 0, view1.inputShare); //todo check
+                Array.Copy(tmp, stateSizeBytes, tape.tapes[0], 0, andSizeBytes);
 
-                    status = status && CreateRandomTape(proof.seed2, 0, salt, roundNumber,
-                        1, tmp, stateSizeBytes + andSizeBytes);
-
-                    if (!status)
-                    {
-                        break;
-                    }
-
-                    Pack.LE_To_UInt32(tmp, 0, view2.inputShare); //todo check
-                    System.Array.Copy(tmp, stateSizeBytes, tape.tapes[1], 0, andSizeBytes);
+                status = status && CreateRandomTape(proof.seed2, 0, salt, roundNumber,
+                    1, tmp, stateSizeBytes + andSizeBytes);
 
+                if (!status)
+                {
                     break;
+                }
 
-                case 1:
-                    // in this case view2's input share was already given to us explicitly as
-                    // it is not computable from the seed. We just need to compute view1's input from
-                    // its seed
-                    status = CreateRandomTape(proof.seed1, 0, salt, roundNumber,
-                        1, tmp, stateSizeBytes + andSizeBytes);
-
-                    Pack.LE_To_UInt32(tmp, 0, view1.inputShare); //todo check
-                    System.Array.Copy(tmp, stateSizeBytes, tape.tapes[0], 0, andSizeBytes);
-                    status = status && CreateRandomTape(proof.seed2, 0, salt, roundNumber,
-                        2, tape.tapes[1], andSizeBytes);
-                    if (!status)
-                    {
-                        break;
-                    }
-
-                    System.Array.Copy(proof.inputShare, 0, view2.inputShare, 0, stateSizeBytes);
-                    break;
+                Pack.LE_To_UInt32(tmp, 0, view2.inputShare); //todo check
+                Array.Copy(tmp, stateSizeBytes, tape.tapes[1], 0, andSizeBytes);
 
-                case 2:
-                    // in this case view1's input share was already given to us explicitly as
-                    // it is not computable from the seed. We just need to compute view2's input from
-                    // its seed
-                    status = CreateRandomTape(proof.seed1, 0, salt, roundNumber, 2, tape.tapes[0], andSizeBytes);
-                    System.Array.Copy(proof.inputShare, 0, view1.inputShare, 0, stateSizeBytes);
-                    status = status && CreateRandomTape(proof.seed2, 0, salt, roundNumber, 0, tmp,
-                        (stateSizeBytes + andSizeBytes));
-                    if (!status)
-                    {
-                        break;
-                    }
+                break;
+            }
+            case 1:
+            {
+                // in this case view2's input share was already given to us explicitly as
+                // it is not computable from the seed. We just need to compute view1's input from
+                // its seed
+                status = CreateRandomTape(proof.seed1, 0, salt, roundNumber,
+                    1, tmp, stateSizeBytes + andSizeBytes);
 
-                    Pack.LE_To_UInt32(tmp, 0, view2.inputShare); //todo check
-                    System.Array.Copy(tmp, stateSizeBytes, tape.tapes[1], 0, andSizeBytes);
+                Pack.LE_To_UInt32(tmp, 0, view1.inputShare); //todo check
+                Array.Copy(tmp, stateSizeBytes, tape.tapes[0], 0, andSizeBytes);
+                status = status && CreateRandomTape(proof.seed2, 0, salt, roundNumber,
+                    2, tape.tapes[1], andSizeBytes);
+                if (!status)
+                {
                     break;
+                }
 
-                default:
-                    Console.Error.Write("Invalid Challenge!");
+                Array.Copy(proof.inputShare, 0, view2.inputShare, 0, stateSizeBytes);
+                break;
+            }
+            case 2:
+            {
+                // in this case view1's input share was already given to us explicitly as
+                // it is not computable from the seed. We just need to compute view2's input from
+                // its seed
+                status = CreateRandomTape(proof.seed1, 0, salt, roundNumber, 2, tape.tapes[0], andSizeBytes);
+                Array.Copy(proof.inputShare, 0, view1.inputShare, 0, stateSizeBytes);
+                status = status && CreateRandomTape(proof.seed2, 0, salt, roundNumber, 0, tmp,
+                    (stateSizeBytes + andSizeBytes));
+                if (!status)
+                {
                     break;
+                }
+
+                Pack.LE_To_UInt32(tmp, 0, view2.inputShare); //todo check
+                Array.Copy(tmp, stateSizeBytes, tape.tapes[1], 0, andSizeBytes);
+                break;
+            }
+            default:
+            {
+                Console.Error.Write("Invalid Challenge!");
+                break;
+            }
             }
 
             if (!status)
@@ -536,12 +521,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             Pack.UInt32_To_LE(view1.inputShare, view_bytes, 0);
             Arrays.Fill(view_bytes, stateSizeBytes, view_bytes.Length,
                 (byte) 0); //todo have correct size: reduce view.inputshare by /4
-            ZeroTrailingBits(view_bytes, stateSizeBits);
+            Utils.ZeroTrailingBits(view_bytes, stateSizeBits);
             Pack.LE_To_UInt32(view_bytes, 0, view1.inputShare);
 
             Pack.UInt32_To_LE(view2.inputShare, view_bytes, 0);
             Arrays.Fill(view_bytes, stateSizeBytes, view_bytes.Length, (byte) 0);
-            ZeroTrailingBits(view_bytes, stateSizeBits);
+            Utils.ZeroTrailingBits(view_bytes, stateSizeBits);
 
             Pack.LE_To_UInt32(view_bytes, 0, view2.inputShare);
 
@@ -551,7 +536,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
 
         void mpc_LowMC_verify(View view1, View view2, Tape tapes, uint[] tmp, uint[] plaintext,  int challenge)
         {
-
             Utils.Fill(tmp, 0, tmp.Length, 0);
 
             mpc_xor_constant_verify(tmp, plaintext, 0, stateSizeWords, challenge);
@@ -588,13 +572,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                 mpc_xor(tmp, tmp, stateSizeWords, 2);
             }
 
-            System.Array.Copy(tmp, 2 * stateSizeWords, view1.outputShare, 0, stateSizeWords);
-            System.Array.Copy(tmp, 3 * stateSizeWords, view2.outputShare, 0, stateSizeWords);
+            Array.Copy(tmp, 2 * stateSizeWords, view1.outputShare, 0, stateSizeWords);
+            Array.Copy(tmp, 3 * stateSizeWords, view2.outputShare, 0, stateSizeWords);
         }
 
         void mpc_substitution_verify(uint[] state, Tape rand, View view1, View view2)
         {
-
             uint[] a = new uint[2];
             uint[] b = new uint[2];
             uint[] c = new uint[2];
@@ -606,7 +589,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             int stateOffset;
             for (int i = 0; i < numSboxes * 3; i += 3)
             {
-
                 for (int j = 0; j < 2; j++)
                 {
                     stateOffset = ((2 + j) * stateSizeWords) * 32;
@@ -691,7 +673,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                 return -1;
             }
 
-            System.Array.Copy(sigBytes, sigBytesOffset, challengeBits, 0, Utils.NumBytes(2 * numMPCRounds));
+            Array.Copy(sigBytes, sigBytesOffset, challengeBits, 0, Utils.NumBytes(2 * numMPCRounds));
             sigBytesOffset += Utils.NumBytes(2 * numMPCRounds);
 
             if (!IsChallengeValid(challengeBits))
@@ -699,32 +681,31 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                 return -1;
             }
 
-            System.Array.Copy(sigBytes, sigBytesOffset, sig.salt, 0, saltSizeBytes);
+            Array.Copy(sigBytes, sigBytesOffset, sig.salt, 0, saltSizeBytes);
             sigBytesOffset += saltSizeBytes;
 
             for (int i = 0; i < numMPCRounds; i++)
             {
-
                 int challenge = GetChallenge(challengeBits, i);
 
-                System.Array.Copy(sigBytes, sigBytesOffset, proofs[i].view3Commitment, 0, digestSizeBytes);
+                Array.Copy(sigBytes, sigBytesOffset, proofs[i].view3Commitment, 0, digestSizeBytes);
 
                 sigBytesOffset += digestSizeBytes;
 
                 if (transform == TRANSFORM_UR)
                 {
                     int view3UnruhLength = (challenge == 0) ? UnruhGWithInputBytes : UnruhGWithoutInputBytes;
-                    System.Array.Copy(sigBytes, sigBytesOffset, proofs[i].view3UnruhG, 0, view3UnruhLength);
+                    Array.Copy(sigBytes, sigBytesOffset, proofs[i].view3UnruhG, 0, view3UnruhLength);
                     sigBytesOffset += view3UnruhLength;
                 }
 
-                System.Array.Copy(sigBytes, sigBytesOffset, proofs[i].communicatedBits, 0, andSizeBytes);
+                Array.Copy(sigBytes, sigBytesOffset, proofs[i].communicatedBits, 0, andSizeBytes);
                 sigBytesOffset += andSizeBytes;
 
-                System.Array.Copy(sigBytes, sigBytesOffset, proofs[i].seed1, 0, seedSizeBytes);
+                Array.Copy(sigBytes, sigBytesOffset, proofs[i].seed1, 0, seedSizeBytes);
                 sigBytesOffset += seedSizeBytes;
 
-                System.Array.Copy(sigBytes, sigBytesOffset, proofs[i].seed2, 0, seedSizeBytes);
+                Array.Copy(sigBytes, sigBytesOffset, proofs[i].seed2, 0, seedSizeBytes);
                 sigBytesOffset += seedSizeBytes;
 
                 if (challenge == 1 || challenge == 2)
@@ -783,8 +764,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
 
         private  uint picnic_read_public_key(byte[] ciphertext, byte[] plaintext, byte[] pk)
         {
-            System.Array.Copy(pk, 1, ciphertext, 0, stateSizeBytes);
-            System.Array.Copy(pk, 1 + stateSizeBytes, plaintext, 0, stateSizeBytes);
+            Array.Copy(pk, 1, ciphertext, 0, stateSizeBytes);
+            Array.Copy(pk, 1 + stateSizeBytes, plaintext, 0, stateSizeBytes);
             return 0;
         }
 
@@ -866,8 +847,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                  * random tape. */
                 CreateRandomTapes(tapes[t], seeds[t].GetLeaves(), seeds[t].GetLeavesOffset(), sig.salt, t);
 
-
-
                 if (!Contains(sig.challengeC, numOpenedRounds, t))
                 {
                     /* We're given iSeed, have expanded the seeds, compute aux from scratch so we can comnpte Com[t] */
@@ -884,8 +863,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                 {
                     /* We're given all seeds and aux bits, except for the unopened
                      * party, we get their commitment */
-                     uint unopened = sig.challengeP[IndexOf(sig.challengeC, numOpenedRounds, t)];
-
+                    uint unopened = sig.challengeP[IndexOf(sig.challengeC, numOpenedRounds, t)];
 
                     for (uint j = 0; j < last; j++)
                     {
@@ -900,9 +878,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                         commit(C[t][last], seeds[t].GetLeaf(last), sig.proofs[t].aux, sig.salt, t, last);
                     }
 
-                    System.Array.Copy(sig.proofs[t].C, 0, C[t][unopened], 0, digestSizeBytes);
+                    Array.Copy(sig.proofs[t].C, 0, C[t][unopened], 0, digestSizeBytes);
                 }
-
             }
 
             /* Commit to the commitments */
@@ -919,7 +896,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                 if (Contains(sig.challengeC, numOpenedRounds, (uint)t))
                 {
                     /* 2. When t is in C, we have everything we need to re-compute the view, as an honest signer would.
-                     * We simulate the MPC with one fewer party; the unopned party's values are all set to zero. */
+                     * We simulate the MPC with one fewer party; the unopened party's values are all set to zero. */
                     uint unopened = sig.challengeP[IndexOf(sig.challengeC, numOpenedRounds, t)];
 
                     int tapeLengthBytes = 2 * andSizeBytes;
@@ -929,13 +906,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                         tapes[t].SetAuxBits(sig.proofs[t].aux);
                     }
                     
-                    System.Array.Copy(sig.proofs[t].msgs, 0, msgs[t].msgs[unopened], 0, andSizeBytes);
+                    Array.Copy(sig.proofs[t].msgs, 0, msgs[t].msgs[unopened], 0, andSizeBytes);
 
                     Arrays.Fill(tapes[t].tapes[unopened], (byte) 0);
                     msgs[t].unopened =  (int) unopened;
 
                     byte[] input_bytes = new byte[stateSizeWords * 4];
-                    System.Array.Copy(sig.proofs[t].input, 0, input_bytes, 0, sig.proofs[t].input.Length);
+                    Array.Copy(sig.proofs[t].input, 0, input_bytes, 0, sig.proofs[t].input.Length);
 
                     uint[] temp = new uint[stateSizeWords];
                     Pack.LE_To_UInt32(input_bytes, 0, temp, 0, stateSizeWords);
@@ -992,10 +969,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                 return -1;
             }
 
-            System.Array.Copy(sigBytes, sigBytesOffset, sig.challengeHash, 0, digestSizeBytes);
+            Array.Copy(sigBytes, sigBytesOffset, sig.challengeHash, 0, digestSizeBytes);
             sigBytesOffset += digestSizeBytes;
 
-            System.Array.Copy(sigBytes, sigBytesOffset, sig.salt, 0, saltSizeBytes);
+            Array.Copy(sigBytes, sigBytesOffset, sig.salt, 0, saltSizeBytes);
             sigBytesOffset += saltSizeBytes;
 
             ExpandChallengeHash(sig.challengeHash, sig.challengeC, sig.challengeP);
@@ -1042,12 +1019,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             }
 
             sig.iSeedInfo = new byte[sig.iSeedInfoLen];
-            System.Array.Copy(sigBytes, sigBytesOffset, sig.iSeedInfo, 0, sig.iSeedInfoLen);
+            Array.Copy(sigBytes, sigBytesOffset, sig.iSeedInfo, 0, sig.iSeedInfoLen);
             sigBytesOffset += sig.iSeedInfoLen;
 //        Console.Error.Write("iSeedInfo: " + Hex.toHexString(sig.iSeedInfo));
 
             sig.cvInfo = new byte[sig.cvInfoLen];
-            System.Array.Copy(sigBytes, sigBytesOffset, sig.cvInfo, 0, sig.cvInfoLen);
+            Array.Copy(sigBytes, sigBytesOffset, sig.cvInfo, 0, sig.cvInfoLen);
             sigBytesOffset += sig.cvInfoLen;
 
             /* Read the proofs */
@@ -1058,13 +1035,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                     sig.proofs[t] = new Signature2.Proof2(this);
                     sig.proofs[t].seedInfoLen = seedInfoLen;
                     sig.proofs[t].seedInfo = new byte[sig.proofs[t].seedInfoLen];
-                    System.Array.Copy(sigBytes, sigBytesOffset, sig.proofs[t].seedInfo, 0, sig.proofs[t].seedInfoLen);
+                    Array.Copy(sigBytes, sigBytesOffset, sig.proofs[t].seedInfo, 0, sig.proofs[t].seedInfoLen);
                     sigBytesOffset += sig.proofs[t].seedInfoLen;
 
                     uint P_t = sig.challengeP[IndexOf(sig.challengeC, numOpenedRounds, t)];
                     if (P_t != (numMPCParties - 1))
                     {
-                        System.Array.Copy(sigBytes, sigBytesOffset, sig.proofs[t].aux, 0, andSizeBytes);
+                        Array.Copy(sigBytes, sigBytesOffset, sig.proofs[t].aux, 0, andSizeBytes);
                         sigBytesOffset += andSizeBytes;
                         if (!ArePaddingBitsZero(sig.proofs[t].aux, 3 * numRounds * numSboxes))
                         {
@@ -1073,11 +1050,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                         }
                     }
 
-                    System.Array.Copy(sigBytes, sigBytesOffset, sig.proofs[t].input, 0, stateSizeBytes);
+                    Array.Copy(sigBytes, sigBytesOffset, sig.proofs[t].input, 0, stateSizeBytes);
                     sigBytesOffset += stateSizeBytes;
 
                     int msgsByteLength = andSizeBytes;
-                    System.Array.Copy(sigBytes, sigBytesOffset, sig.proofs[t].msgs, 0, msgsByteLength);
+                    Array.Copy(sigBytes, sigBytesOffset, sig.proofs[t].msgs, 0, msgsByteLength);
                     sigBytesOffset += msgsByteLength;
                     int msgsBitLength = 3 * numRounds * numSboxes;
                     if (!ArePaddingBitsZero(sig.proofs[t].msgs, msgsBitLength))
@@ -1086,7 +1063,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                         return -1;
                     }
 
-                    System.Array.Copy(sigBytes, sigBytesOffset, sig.proofs[t].C, 0, digestSizeBytes);
+                    Array.Copy(sigBytes, sigBytesOffset, sig.proofs[t].C, 0, digestSizeBytes);
                     sigBytesOffset += digestSizeBytes;
                 }
             }
@@ -1112,7 +1089,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
         public void crypto_sign(byte[] sm, byte[] m, byte[] sk)
         {
             picnic_sign(sk, m, sm);
-            System.Array.Copy(m, 0, sm, 4, m.Length);
+            Array.Copy(m, 0, sm, 4, m.Length);
             sm = Arrays.CopyOfRange(sm, 0, signatureLength);
         }
 
@@ -1121,11 +1098,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             //todo unify conversion
 
             byte[] data_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
-            System.Array.Copy(sk, 1, data_bytes, 0, stateSizeBytes);
+            Array.Copy(sk, 1, data_bytes, 0, stateSizeBytes);
             byte[] ciphertext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
-            System.Array.Copy(sk, 1 + stateSizeBytes, ciphertext_bytes, 0, stateSizeBytes);
+            Array.Copy(sk, 1 + stateSizeBytes, ciphertext_bytes, 0, stateSizeBytes);
             byte[] plaintext_bytes = new byte[PICNIC_MAX_LOWMC_BLOCK_SIZE];
-            System.Array.Copy(sk, 1 + 2 * stateSizeBytes, plaintext_bytes, 0, stateSizeBytes);
+            Array.Copy(sk, 1 + 2 * stateSizeBytes, plaintext_bytes, 0, stateSizeBytes);
             uint[] data = new uint[stateSizeWords];
             uint[] ciphertext = new uint[stateSizeWords];
             uint[] plaintext = new uint[stateSizeWords];
@@ -1134,7 +1111,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             Pack.LE_To_UInt32(plaintext_bytes, 0, plaintext);
             Pack.LE_To_UInt32(ciphertext_bytes, 0, ciphertext);
 
-
             if (!is_picnic3(parameters))
             {
                 Signature sig = new Signature(this);
@@ -1187,10 +1163,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
 
             int sigByteIndex = sigOffset;
 
-            System.Array.Copy(challengeBits, 0, sigBytes, sigByteIndex, Utils.NumBytes(2 * numMPCRounds));
+            Array.Copy(challengeBits, 0, sigBytes, sigByteIndex, Utils.NumBytes(2 * numMPCRounds));
             sigByteIndex += Utils.NumBytes(2 * numMPCRounds);
 
-            System.Array.Copy(sig.salt, 0, sigBytes, sigByteIndex, saltSizeBytes);
+            Array.Copy(sig.salt, 0, sigBytes, sigByteIndex, saltSizeBytes);
 
             sigByteIndex += saltSizeBytes;
 
@@ -1198,23 +1174,23 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             {
                 int challenge = GetChallenge(challengeBits, i);
 
-                System.Array.Copy(proofs[i].view3Commitment, 0, sigBytes, sigByteIndex, digestSizeBytes);
+                Array.Copy(proofs[i].view3Commitment, 0, sigBytes, sigByteIndex, digestSizeBytes);
                 sigByteIndex += digestSizeBytes;
 
                 if (transform == TRANSFORM_UR)
                 {
                     int view3UnruhLength = (challenge == 0) ? UnruhGWithInputBytes : UnruhGWithoutInputBytes;
-                    System.Array.Copy(proofs[i].view3UnruhG, 0, sigBytes, sigByteIndex, view3UnruhLength);
+                    Array.Copy(proofs[i].view3UnruhG, 0, sigBytes, sigByteIndex, view3UnruhLength);
                     sigByteIndex += view3UnruhLength;
                 }
 
-                System.Array.Copy(proofs[i].communicatedBits, 0, sigBytes, sigByteIndex, andSizeBytes);
+                Array.Copy(proofs[i].communicatedBits, 0, sigBytes, sigByteIndex, andSizeBytes);
                 sigByteIndex += andSizeBytes;
 
-                System.Array.Copy(proofs[i].seed1, 0, sigBytes, sigByteIndex, seedSizeBytes);
+                Array.Copy(proofs[i].seed1, 0, sigBytes, sigByteIndex, seedSizeBytes);
                 sigByteIndex += seedSizeBytes;
 
-                System.Array.Copy(proofs[i].seed2, 0, sigBytes, sigByteIndex, seedSizeBytes);
+                Array.Copy(proofs[i].seed2, 0, sigBytes, sigByteIndex, seedSizeBytes);
                 sigByteIndex += seedSizeBytes;
 
                 if (challenge == 1 || challenge == 2)
@@ -1235,7 +1211,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
 
         private int SerializeSignature2(Signature2 sig, byte[] sigBytes, int sigOffset)
         {
-
             /* Compute the number of bytes required for the signature */
             int bytesRequired = digestSizeBytes + saltSizeBytes; /* challenge and salt */
 
@@ -1266,16 +1241,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             }
 
             int sigByteIndex = sigOffset;
-            System.Array.Copy(sig.challengeHash, 0, sigBytes, sigByteIndex, digestSizeBytes);
+            Array.Copy(sig.challengeHash, 0, sigBytes, sigByteIndex, digestSizeBytes);
             sigByteIndex += digestSizeBytes;
 
-            System.Array.Copy(sig.salt, 0, sigBytes, sigByteIndex, saltSizeBytes);
+            Array.Copy(sig.salt, 0, sigBytes, sigByteIndex, saltSizeBytes);
             sigByteIndex += saltSizeBytes;
 
-            System.Array.Copy(sig.iSeedInfo, 0, sigBytes, sigByteIndex, sig.iSeedInfoLen);
+            Array.Copy(sig.iSeedInfo, 0, sigBytes, sigByteIndex, sig.iSeedInfoLen);
             sigByteIndex += sig.iSeedInfoLen;
 
-            System.Array.Copy(sig.cvInfo, 0, sigBytes, sigByteIndex, sig.cvInfoLen);
+            Array.Copy(sig.cvInfo, 0, sigBytes, sigByteIndex, sig.cvInfoLen);
             sigByteIndex += sig.cvInfoLen;
 
             /* Write the proofs */
@@ -1283,24 +1258,24 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             {
                 if (Contains(sig.challengeC, numOpenedRounds, t))
                 {
-                    System.Array.Copy(sig.proofs[t].seedInfo, 0, sigBytes, sigByteIndex, sig.proofs[t].seedInfoLen);
+                    Array.Copy(sig.proofs[t].seedInfo, 0, sigBytes, sigByteIndex, sig.proofs[t].seedInfoLen);
                     sigByteIndex += sig.proofs[t].seedInfoLen;
 
-                     uint P_t = sig.challengeP[IndexOf(sig.challengeC, numOpenedRounds, t)];
+                    uint P_t = sig.challengeP[IndexOf(sig.challengeC, numOpenedRounds, t)];
 
                     if (P_t != (numMPCParties - 1))
                     {
-                        System.Array.Copy(sig.proofs[t].aux, 0, sigBytes, sigByteIndex, andSizeBytes);
+                        Array.Copy(sig.proofs[t].aux, 0, sigBytes, sigByteIndex, andSizeBytes);
                         sigByteIndex += andSizeBytes;
                     }
 
-                    System.Array.Copy(sig.proofs[t].input, 0, sigBytes, sigByteIndex, stateSizeBytes);
+                    Array.Copy(sig.proofs[t].input, 0, sigBytes, sigByteIndex, stateSizeBytes);
                     sigByteIndex += stateSizeBytes;
 
-                    System.Array.Copy(sig.proofs[t].msgs, 0, sigBytes, sigByteIndex, andSizeBytes);
+                    Array.Copy(sig.proofs[t].msgs, 0, sigBytes, sigByteIndex, andSizeBytes);
                     sigByteIndex += andSizeBytes;
 
-                    System.Array.Copy(sig.proofs[t].C, 0, sigBytes, sigByteIndex, digestSizeBytes);
+                    Array.Copy(sig.proofs[t].C, 0, sigBytes, sigByteIndex, digestSizeBytes);
                     sigByteIndex += digestSizeBytes;
                 }
             }
@@ -1318,7 +1293,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             {
                 views[i] = new View[3];
             }
-            
+
             byte[][][] AS = new byte[numMPCRounds][][]; // numMPCRounds, numMPCParties, digestSizeBytes
             for (int i = 0; i < numMPCRounds; i++)
             {
@@ -1328,7 +1303,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                     AS[i][j] = new byte[digestSizeBytes];
                 }
             }
-            
+
             byte[][][] gs = new byte[numMPCRounds][][]; // numMPCRounds, 3, UnruhGWithInputBytes
             for (int i = 0; i < numMPCRounds; i++)
             {
@@ -1338,13 +1313,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                     gs[i][j] = new byte[UnruhGWithInputBytes];
                 }
             }
-            
-            
+
+
             /* Compute seeds for all parallel iterations */
             byte[] seeds = ComputeSeeds(privateKey, pubKey, plaintext, message);
             int seedLen = numMPCParties * seedSizeBytes;
 
-            System.Array.Copy(seeds, (seedLen) * (numMPCRounds), sig.salt, 0, saltSizeBytes);
+            Array.Copy(seeds, (seedLen) * (numMPCRounds), sig.salt, 0, saltSizeBytes);
 
             //Allocate a random tape (re-used per parallel iteration), and a temporary buffer
             Tape tape = new Tape(this);
@@ -1368,10 +1343,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                         return -1;
                     }
 
-                    System.Array.Copy(tmp, 0, view_byte, 0, stateSizeBytes);
-                    ZeroTrailingBits(view_byte, stateSizeBits);
+                    Array.Copy(tmp, 0, view_byte, 0, stateSizeBytes);
+                    Utils.ZeroTrailingBits(view_byte, stateSizeBits);
                     Pack.LE_To_UInt32(view_byte, 0, views[k][j].inputShare);
-                    System.Array.Copy(tmp, stateSizeBytes, tape.tapes[j], 0, andSizeBytes);
+                    Array.Copy(tmp, stateSizeBytes, tape.tapes[j], 0, andSizeBytes);
                 }
 
                 // Now set third party's wires. The random bits are from the seed, the input is
@@ -1439,7 +1414,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                 (transform != TRANSFORM_UR) ? null : gs[i]); //todo check if
             }
 
-
             return 0;
         }
 
@@ -1449,18 +1423,18 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
         {
             if (challenge == 0)
             {
-                System.Array.Copy(seeds, seedsOffset + 0 * seedSizeBytes, proof.seed1, 0, seedSizeBytes);
-                System.Array.Copy(seeds, seedsOffset + 1 * seedSizeBytes, proof.seed2, 0, seedSizeBytes);
+                Array.Copy(seeds, seedsOffset + 0 * seedSizeBytes, proof.seed1, 0, seedSizeBytes);
+                Array.Copy(seeds, seedsOffset + 1 * seedSizeBytes, proof.seed2, 0, seedSizeBytes);
             }
             else if (challenge == 1)
             {
-                System.Array.Copy(seeds, seedsOffset + 1 * seedSizeBytes, proof.seed1, 0, seedSizeBytes);
-                System.Array.Copy(seeds, seedsOffset + 2 * seedSizeBytes, proof.seed2, 0, seedSizeBytes);
+                Array.Copy(seeds, seedsOffset + 1 * seedSizeBytes, proof.seed1, 0, seedSizeBytes);
+                Array.Copy(seeds, seedsOffset + 2 * seedSizeBytes, proof.seed2, 0, seedSizeBytes);
             }
             else if (challenge == 2)
             {
-                System.Array.Copy(seeds, seedsOffset + 2 * seedSizeBytes, proof.seed1, 0, seedSizeBytes);
-                System.Array.Copy(seeds, seedsOffset + 0 * seedSizeBytes, proof.seed2, 0, seedSizeBytes);
+                Array.Copy(seeds, seedsOffset + 2 * seedSizeBytes, proof.seed1, 0, seedSizeBytes);
+                Array.Copy(seeds, seedsOffset + 0 * seedSizeBytes, proof.seed2, 0, seedSizeBytes);
             }
             else
             {
@@ -1469,16 +1443,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
 
             if (challenge == 1 || challenge == 2)
             {
-                System.Array.Copy(views[2].inputShare, 0, proof.inputShare, 0, stateSizeBytes);
+                Array.Copy(views[2].inputShare, 0, proof.inputShare, 0, stateSizeBytes);
             }
 
-            System.Array.Copy(views[(challenge + 1) % 3].communicatedBits, 0, proof.communicatedBits, 0, andSizeBytes);
+            Array.Copy(views[(challenge + 1) % 3].communicatedBits, 0, proof.communicatedBits, 0, andSizeBytes);
 
-            System.Array.Copy(commitments[(challenge + 2) % 3], 0, proof.view3Commitment, 0, digestSizeBytes);
+            Array.Copy(commitments[(challenge + 2) % 3], 0, proof.view3Commitment, 0, digestSizeBytes);
             if (transform == TRANSFORM_UR)
             {
                 int view3UnruhLength = (challenge == 0) ? UnruhGWithInputBytes : UnruhGWithoutInputBytes;
-                System.Array.Copy(gs[(challenge + 2) % 3], 0, proof.view3UnruhG, 0, view3UnruhLength);
+                Array.Copy(gs[(challenge + 2) % 3], 0, proof.view3UnruhG, 0, view3UnruhLength);
             }
         }
 
@@ -1652,7 +1626,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
 
             for (int i = 0; i < 3; i++)
             {
-                System.Array.Copy(slab, (3 + i) * stateSizeWords, views[i].outputShare, 0, stateSizeWords);
+                Array.Copy(slab, (3 + i) * stateSizeWords, views[i].outputShare, 0, stateSizeWords);
             }
         }
 
@@ -1730,7 +1704,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             rand.pos++;
         }
 
-
         private void mpc_xor(uint[] state, uint[] input, int len, int players)
         {
             for (int player = 0; player < players; player++)
@@ -1743,7 +1716,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             }
         }
 
-
         private void mpc_matrix_mul(uint[] output, int outputOffset, uint[] state, int stateOffset,
             uint[] matrix, int matrixOffset, int players)
         {
@@ -1764,7 +1736,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             }
         }
 
-
         private bool CreateRandomTape(byte[] seed, int seedOffset, byte[] salt,  uint roundNumber, uint playerNumber,
             byte[] tape, int tapeLen)
         {
@@ -1807,9 +1778,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             return allSeeds;
         }
 
-
-
-
         private void sign_picnic3(uint[] privateKey, uint[] pubKey, uint[] plaintext, byte[] message, Signature2 sig)
         {
             byte[] saltAndRoot = new byte[saltSizeBytes + seedSizeBytes];
@@ -1924,7 +1892,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             sig.cvInfo = treeCv.OpenMerkleTree(missingLeaves, (uint)missingLeavesSize, cvInfoLen);
             sig.cvInfoLen = cvInfoLen[0];
 
-            /* Reveal iSeeds for unopned rounds, those in {0..T-1} \ ChallengeC. */
+            /* Reveal iSeeds for unopened rounds, those in {0..T-1} \ ChallengeC. */
             sig.iSeedInfo = new byte[numMPCRounds * seedSizeBytes];
             sig.iSeedInfoLen = iSeedsTree.RevealSeeds(sig.challengeC, (uint)numOpenedRounds,
                 sig.iSeedInfo, numMPCRounds * seedSizeBytes);
@@ -1934,7 +1902,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             sig.proofs = new Signature2.Proof2[numMPCRounds];
             for (uint t = 0; t < numMPCRounds; t++)
             {
-                if (Contains(sig.challengeC, numOpenedRounds, (uint)t))
+                if (Contains(sig.challengeC, numOpenedRounds, t))
                 {
                     sig.proofs[t] = new Signature2.Proof2(this);
                     int P_index = IndexOf(sig.challengeC, numOpenedRounds, t);
@@ -1951,34 +1919,23 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                         GetAuxBits(sig.proofs[t].aux, tapes[t]);
                     }
 
-                    System.Array.Copy(inputs[t], 0, sig.proofs[t].input, 0, stateSizeBytes);
-                    System.Array.Copy(msgs[t].msgs[sig.challengeP[P_index]], 0, sig.proofs[t].msgs, 0, andSizeBytes);
-                    System.Array.Copy(C[t][sig.challengeP[P_index]], 0, sig.proofs[t].C, 0, digestSizeBytes);
+                    Array.Copy(inputs[t], 0, sig.proofs[t].input, 0, stateSizeBytes);
+                    Array.Copy(msgs[t].msgs[sig.challengeP[P_index]], 0, sig.proofs[t].msgs, 0, andSizeBytes);
+                    Array.Copy(C[t][sig.challengeP[P_index]], 0, sig.proofs[t].C, 0, digestSizeBytes);
                 }
             }
-
         }
 
-        static int IndexOf(uint[] list, int len, uint value)
+        private static int IndexOf(uint[] list, int len, uint value)
         {
-            for (int i = 0; i < len; i++)
-            {
-                if (list[i] == value)
-                {
-                    return i;
-                }
-            }
-
-            return -1;
+            return Array.IndexOf(list, value, 0, len);
         }
 
-
-
         private uint[] GetMissingLeavesList(uint[] challengeC)
         {
             uint missingLeavesSize = (uint)(numMPCRounds - numOpenedRounds);
             uint[] missingLeaves = new uint[missingLeavesSize];
-             uint pos = 0;
+            uint pos = 0;
 
             for (int i = 0; i < numMPCRounds; i++)
             {
@@ -2055,8 +2012,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             return position + 1;
         }
 
-
-
         private void ExpandChallengeHash(byte[] challengeHash, uint[] challengeC, uint[] challengeP)
         {
             // Populate C
@@ -2065,7 +2020,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             uint[] chunks = new uint[digestSizeBytes * 8 / System.Math.Min(bitsPerChunkC, bitsPerChunkP)];
             byte[] h = new byte[MAX_DIGEST_SIZE];
 
-            System.Array.Copy(challengeHash, 0, h, 0, digestSizeBytes);
+            Array.Copy(challengeHash, 0, h, 0, digestSizeBytes);
 
             uint countC = 0;
             while (countC < numOpenedRounds)
@@ -2137,8 +2092,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             digest.DoFinal(digest_arr, 0, digestSizeBytes);
         }
 
-
-
         private int SimulateOnline(uint[] maskedKey, Tape tape, uint[] tmp_shares,
             Msg msg, uint[] plaintext, uint[] pubKey)
         {
@@ -2169,7 +2122,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
                 xor_array(state, roundKey, state, 0, stateSizeWords); // state += roundKey
             }
 
-            if (!(SubarrayEquals(state, pubKey, stateSizeWords)))
+            if (!SubarrayEquals(state, pubKey, stateSizeWords))
             {
                 ret = -1;
             }
@@ -2335,15 +2288,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
 
         private void GetAuxBits(byte[] output, Tape tape)
         {
-            int last = numMPCParties - 1;
-            int pos = 0;
-            int n = stateSizeBits;
+            var lastTape = tape.tapes[numMPCParties - 1];
+            int n = stateSizeBits, pos = 0, tapePos = 0;
 
             for (int j = 0; j < numRounds; j++)
             {
+                tapePos += n;
+
                 for (int i = 0; i < n; i++)
                 {
-                    Utils.SetBit(output, pos++, Utils.GetBit(tape.tapes[last], n + n * 2 * j + i));
+                    Utils.SetBit(output, pos++, Utils.GetBit(lastTape, tapePos++));
                 }
             }
         }
@@ -2389,13 +2343,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
 
         static bool is_picnic3(int parameters)
         {
-            if (parameters == 7 /*Picnic3_L1*/ ||
-                parameters == 8 /*Picnic3_L3*/ ||
-                parameters == 9 /*Picnic3_L5*/ )
-            {
-                return true;
-            }
-            return false;
+            return parameters == 7 /*Picnic3_L1*/ ||
+                   parameters == 8 /*Picnic3_L3*/ ||
+                   parameters == 9 /*Picnic3_L5*/ ;
         }
 
         //todo return int;
@@ -2421,9 +2371,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             }
 
             buf[0] = (byte) parameters;
-            System.Array.Copy(data, 0, buf, 1, stateSizeBytes);
-            System.Array.Copy(ciphertext, 0, buf, 1 + stateSizeBytes, stateSizeBytes);
-            System.Array.Copy(plaintext, 0, buf, 1 + 2 * stateSizeBytes, stateSizeBytes);
+            Array.Copy(data, 0, buf, 1, stateSizeBytes);
+            Array.Copy(ciphertext, 0, buf, 1 + stateSizeBytes, stateSizeBytes);
+            Array.Copy(plaintext, 0, buf, 1 + 2 * stateSizeBytes, stateSizeBytes);
             return bytesRequired;
         }
 
@@ -2437,8 +2387,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             }
 
             buf[0] = (byte) parameters;
-            System.Array.Copy(ciphertext, 0, buf, 1, stateSizeBytes);
-            System.Array.Copy(plaintext, 0, buf, 1 + stateSizeBytes, stateSizeBytes);
+            Array.Copy(ciphertext, 0, buf, 1, stateSizeBytes);
+            Array.Copy(plaintext, 0, buf, 1 + stateSizeBytes, stateSizeBytes);
             return bytesRequired;
 
         }
@@ -2450,30 +2400,18 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             uint[] data = new uint[data_bytes.Length / 4];
             uint[] plaintext = new uint[plaintext_bytes.Length / 4];
             uint[] ciphertext = new uint[ciphertext_bytes.Length / 4];
-            byte[] temp = new byte[stateSizeBytes];
 
             // generate a private key
-            random.NextBytes(temp);
-            ZeroTrailingBits(temp, stateSizeBits);
-            System.Array.Copy(temp, 0, data_bytes, 0, temp.Length);
-
-            for (int i = 0; i < data.Length; i++)
-            {
-                data[i] = Pack.LE_To_UInt32(data_bytes, i * 4);
-            }
-
+            random.NextBytes(data_bytes, 0, stateSizeBytes);
+            Utils.ZeroTrailingBits(data_bytes, stateSizeBits);
+            Pack.LE_To_UInt32(data_bytes, 0, data);
 
             // generate a plaintext block
-            random.NextBytes(temp);
-            ZeroTrailingBits(temp, stateSizeBits);
-            System.Array.Copy(temp, 0, plaintext_bytes, 0, temp.Length);
-
-            for (int i = 0; i < plaintext.Length; i++)
-            {
-                plaintext[i] = Pack.LE_To_UInt32(plaintext_bytes, i * 4);
-            }
+            random.NextBytes(plaintext_bytes, 0, stateSizeBytes);
+            Utils.ZeroTrailingBits(plaintext_bytes, stateSizeBits);
+            Pack.LE_To_UInt32(plaintext_bytes, 0, plaintext);
 
-            // computer ciphertext
+            // compute ciphertext
             LowMCEnc(plaintext, ciphertext, data);
 
             //copy back to byte array
@@ -2482,15 +2420,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             Pack.UInt32_To_LE(ciphertext, ciphertext_bytes, 0);
         }
 
-
         private void LowMCEnc(uint[] plaintext, uint[] output, uint[] key)
         {
             uint[] roundKey = new uint[LOWMC_MAX_WORDS];
 
-            if (plaintext != (output))
+            if (plaintext != output)
             {
                 /* output will hold the intermediate state */
-                System.Array.Copy(plaintext, 0, output, 0, stateSizeWords);
+                Array.Copy(plaintext, 0, output, 0, stateSizeWords);
             }
 
             KMatricesWithPointer current = LowmcConstants.Instance.KMatrix(this, 0);
@@ -2514,7 +2451,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             }
         }
 
-
         private void Substitution(uint[] state)
         {
             for (int i = 0; i < numSboxes * 3; i += 3)
@@ -2551,47 +2487,35 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             matrix_mul_offset(output, 0, state, 0, matrix, matrixOffset);
         }
 
-        protected void matrix_mul_offset(uint[] output, int outputOffset,
-            uint[] state, int stateOffset,
-            uint[] matrix, int matrixOffset)
+        protected void matrix_mul_offset(uint[] output, int outputOffset, uint[] state, int stateOffset, uint[] matrix,
+            int matrixOffset)
         {
             // Use temp to correctly handle the case when state = output
-            uint prod;
             uint[] temp = new uint[LOWMC_MAX_WORDS];
             temp[stateSizeWords - 1] = 0;
             int wholeWords = stateSizeBits / WORD_SIZE_BITS;
 
             for (int i = 0; i < stateSizeBits; i++)
             {
-                prod = 0;
+                uint prod = 0;
                 for (int j = 0; j < wholeWords; j++)
                 {
                     int index = i * stateSizeWords + j;
-                    prod ^= (state[j + stateOffset] & matrix[matrixOffset + index]);
+                    prod ^= state[j + stateOffset] & matrix[matrixOffset + index];
                 }
 
                 for (int j = wholeWords * WORD_SIZE_BITS; j < stateSizeBits; j++)
                 {
                     int index = i * stateSizeWords * WORD_SIZE_BITS + j;
-                    uint bit = (Utils.GetBitFromWordArray(state, j + stateOffset * 32) &
-                               Utils.GetBitFromWordArray(matrix, matrixOffset * 32 + index));
+                    uint bit = Utils.GetBitFromWordArray(state, stateOffset * 32 + j)
+                             & Utils.GetBitFromWordArray(matrix, matrixOffset * 32 + index);
                     prod ^= bit;
                 }
 
-                Utils.SetBit(temp, i, (int)Utils.Parity32(prod));
-
+                Utils.SetBit(temp, i, Utils.Parity32(prod));
             }
 
-            System.Array.Copy(temp, 0, output, outputOffset, stateSizeWords);
-        }
-
-        private void ZeroTrailingBits(byte[] data, int bitLength)
-        {
-            int byteLength = Utils.NumBytes(bitLength);
-            for (int i = bitLength; i < byteLength * 8; i++)
-            {
-                Utils.SetBit(data, i, (byte) 0);
-            }
+            Array.Copy(temp, 0, output, outputOffset, stateSizeWords);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/picnic/Utils.cs b/crypto/src/pqc/crypto/picnic/Utils.cs
index d80e32431..8e0bdc6ff 100644
--- a/crypto/src/pqc/crypto/picnic/Utils.cs
+++ b/crypto/src/pqc/crypto/picnic/Utils.cs
@@ -1,23 +1,20 @@
-
-using Org.BouncyCastle.Crypto.Utilities;
-
 namespace Org.BouncyCastle.Pqc.Crypto.Picnic
 {
-    public class Utils
+    internal static class Utils
     {
-        protected internal static void Fill(uint[] buf, int from, int to, uint b)
+        internal static void Fill(uint[] buf, int from, int to, uint b)
         {
             for (int i = from; i < to; ++i)
             {
                 buf[i] = b;
             }
         }
-        protected internal static int NumBytes(int numBits)
+        internal static int NumBytes(int numBits)
         {
-            return (numBits == 0) ? 0 : ((numBits - 1) / 8 + 1);
+            return (numBits + 7) >> 3;
         }
 
-        protected internal static uint ceil_log2(uint x)
+        internal static uint ceil_log2(uint x)
         {
             if (x == 0)
             {
@@ -62,8 +59,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             return n;
         }
 
-
-        protected static int Parity(byte[] data, int len)
+        internal static int Parity(byte[] data, int len)
         {
             byte x = data[0];
 
@@ -84,7 +80,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             return y & 1;
         }
 
-        protected internal static uint Parity16(uint x)
+        internal static uint Parity16(uint x)
         {
             uint y = x ^ (x >> 1);
 
@@ -94,7 +90,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
             return y & 1;
         }
 
-        protected internal static uint Parity32(uint x)
+        internal static uint Parity32(uint x)
         {
             /* Compute parity of x using code from Section 5-2 of
              * H.S. Warren, *Hacker's Delight*, Pearson Education, 2003.
@@ -110,44 +106,57 @@ namespace Org.BouncyCastle.Pqc.Crypto.Picnic
 
 
         /* Set a specific bit in a byte array to a given value */
-        protected internal static void SetBitInWordArray(uint[] array, int bitNumber, uint val)
+        internal static void SetBitInWordArray(uint[] array, int bitNumber, uint val)
         {
-            SetBit(array, bitNumber, (int)val);
+            SetBit(array, bitNumber, val);
         }
 
         /* Get one bit from a 32-bit int array */
-        protected internal static uint GetBitFromWordArray(uint[] array, int bitNumber)
+        internal static uint GetBitFromWordArray(uint[] array, int bitNumber)
         {
             return GetBit(array, bitNumber);
         }
 
         /* Get one bit from a byte array */
-        internal protected static byte GetBit(byte[] array, int bitNumber)
+        internal static byte GetBit(byte[] array, int bitNumber)
         {
-            return (byte) ((array[bitNumber / 8] >> (7 - (bitNumber % 8))) & 0x01);
+            int arrayPos = bitNumber >> 3, bitPos = (bitNumber & 7) ^ 7;
+            return (byte)((array[arrayPos] >> bitPos) & 1);
         }
 
         /* Get one bit from a byte array */
-        internal protected static uint GetBit(uint[] array, int bitNumber)
+        internal static uint GetBit(uint[] array, int bitNumber)
+        {
+            int arrayPos = bitNumber >> 5, bitPos = (bitNumber & 31) ^ 7;
+            return (array[arrayPos] >> bitPos) & 1;
+        }
+
+        internal static void SetBit(byte[] array, int bitNumber, byte val)
         {
-            uint temp = Pack.LE_To_UInt32(Pack.UInt32_To_BE(array[bitNumber / 32]), 0);
-            return ((temp >> (31 - (bitNumber % 32))) & 0x01);
+            int arrayPos = bitNumber >> 3, bitPos = (bitNumber & 7) ^ 7;
+            uint t = array[arrayPos];
+            t &= ~(1U << bitPos);
+            t |= (uint)val << bitPos;
+            array[arrayPos] = (byte)t;
         }
 
         /* Set a specific bit in a int array to a given value */
-        internal protected static void SetBit(uint[] bytes, int bitNumber, int val)
+        internal static void SetBit(uint[] array, int bitNumber, uint val)
         {
-            uint temp = Pack.LE_To_UInt32(Pack.UInt32_To_BE(bytes[bitNumber / 32]), 0);
-            int x = (((int)temp & ~(1 << (31 - (bitNumber % 32)))) | (val << (31 - (bitNumber % 32))));
-            bytes[bitNumber / 32] = Pack.LE_To_UInt32(Pack.UInt32_To_BE((uint)x), 0);
-//        bytes[bitNumber / 32]  = ((bytes[bitNumber/4 >> 3]
-//                        & ~(1 << (31 - (bitNumber % 32)))) | (val << (31 - (bitNumber % 32))));
+            int arrayPos = bitNumber >> 5, bitPos = (bitNumber & 31) ^ 7;
+            uint t = array[arrayPos];
+            t &= ~(1U << bitPos);
+            t |= val << bitPos;
+            array[arrayPos] = t;
         }
 
-        internal protected static void SetBit(byte[] bytes, int bitNumber, byte val)
+        internal static void ZeroTrailingBits(byte[] data, int bitLength)
         {
-            bytes[bitNumber / 8] = (byte) ((bytes[bitNumber >> 3]
-                                            & ~(1 << (7 - (bitNumber % 8)))) | (val << (7 - (bitNumber % 8))));
+            int partial = bitLength & 7;
+            if (partial != 0)
+            {
+                data[bitLength >> 3] &= (byte)(0xFF00 >> partial);
+            }
         }
     }
 }
diff --git a/crypto/src/pqc/crypto/sike/SIKEEngine.cs b/crypto/src/pqc/crypto/sike/SIKEEngine.cs
index 38a162978..58c04b459 100644
--- a/crypto/src/pqc/crypto/sike/SIKEEngine.cs
+++ b/crypto/src/pqc/crypto/sike/SIKEEngine.cs
@@ -72,46 +72,37 @@ public class SIKEEngine
     //          public key pk (CRYPTO_PUBLICKEYBYTES bytes)
     public int crypto_kem_keypair(byte[] pk, byte[] sk, SecureRandom random)
     {
-        byte[] s = new byte[param.MSG_BYTES];
-        random.NextBytes(s);
-
-
+        random.NextBytes(sk, 0, (int)param.MSG_BYTES);
 
         if (isCompressed)
         {
             // Generation of Alice's secret key
             // Outputs random value in [0, 2^eA - 1]
 
-            byte[] random_digits = new byte[param.SECRETKEY_A_BYTES];
-            random.NextBytes(random_digits);
-            random_digits[0] &= 0xFE;                            // Make private scalar even
-            random_digits[param.SECRETKEY_A_BYTES-1] &= (byte) param.MASK_ALICE;    // Masking last byte
-
-            System.Array.Copy(s, 0, sk, 0, param.MSG_BYTES);
-            System.Array.Copy(random_digits, 0, sk, param.MSG_BYTES, param.SECRETKEY_A_BYTES);
-            //
+            random.NextBytes(sk, (int)param.MSG_BYTES, (int)param.SECRETKEY_A_BYTES);
+            sk[param.MSG_BYTES] &= 0xFE;                                                    // Make private scalar even
+            sk[param.MSG_BYTES + param.SECRETKEY_A_BYTES - 1] &= (byte)param.MASK_ALICE;    // Masking last
 
             sidhCompressed.EphemeralKeyGeneration_A_extended(sk, pk);
-            System.Array.Copy(pk, 0, sk, param.MSG_BYTES + param.SECRETKEY_A_BYTES, param.CRYPTO_PUBLICKEYBYTES);
 
+            // Append public key pk to secret key sk
+            System.Array.Copy(pk, 0, sk, param.MSG_BYTES + param.SECRETKEY_A_BYTES, param.CRYPTO_PUBLICKEYBYTES);
         }
         else
         {
             // Generation of Bob's secret key
             // Outputs random value in [0, 2^Floor(Log(2, oB)) - 1]
             // todo/org: SIDH.random_mod_order_B(sk, random);
-            byte[] random_digits = new byte[param.SECRETKEY_B_BYTES];
-            random.NextBytes(random_digits);
-            random_digits[param.SECRETKEY_B_BYTES-1] &= (byte)param.MASK_BOB;
 
-            System.Array.Copy(s, 0, sk, 0, param.MSG_BYTES);
-            System.Array.Copy(random_digits, 0, sk, param.MSG_BYTES, param.SECRETKEY_B_BYTES);
+            random.NextBytes(sk, (int)param.MSG_BYTES, (int)param.SECRETKEY_B_BYTES);
+            sk[param.MSG_BYTES + param.SECRETKEY_B_BYTES - 1] &= (byte)param.MASK_BOB;
 
             sidh.EphemeralKeyGeneration_B(sk, pk);
+
+            // Append public key pk to secret key sk
             System.Array.Copy(pk, 0, sk, param.MSG_BYTES + param.SECRETKEY_B_BYTES, param.CRYPTO_PUBLICKEYBYTES);
 
         }
-        // Append public key pk to secret key sk
 
         return 0;
     }
@@ -130,9 +121,7 @@ public class SIKEEngine
             byte[] temp = new byte[param.CRYPTO_CIPHERTEXTBYTES + param.MSG_BYTES];
 
             // Generate ephemeralsk <- G(m||pk) mod oB
-            byte[] tmp = new byte[param.MSG_BYTES];
-            random.NextBytes(tmp);
-            System.Array.Copy(tmp, 0, temp, 0, param.MSG_BYTES);
+            random.NextBytes(temp, 0, (int)param.MSG_BYTES);
             System.Array.Copy(pk, 0, temp, param.MSG_BYTES, param.CRYPTO_PUBLICKEYBYTES);
 
             IXof digest = new ShakeDigest(256);
@@ -180,9 +169,7 @@ public class SIKEEngine
             byte[] temp = new byte[param.CRYPTO_CIPHERTEXTBYTES + param.MSG_BYTES];
 
             // Generate ephemeralsk <- G(m||pk) mod oA
-            byte[] tmp = new byte[param.MSG_BYTES]; // todo: is there a simplier way to do this?
-            random.NextBytes(tmp);
-            System.Array.Copy(tmp, 0, temp, 0, param.MSG_BYTES);
+            random.NextBytes(temp, 0, (int)param.MSG_BYTES);
             System.Array.Copy(pk, 0, temp, param.MSG_BYTES, param.CRYPTO_PUBLICKEYBYTES);
 
             IXof digest = new ShakeDigest(256);
diff --git a/crypto/src/tls/AbstractTlsClient.cs b/crypto/src/tls/AbstractTlsClient.cs
index cf4e1d565..8bfd828f1 100644
--- a/crypto/src/tls/AbstractTlsClient.cs
+++ b/crypto/src/tls/AbstractTlsClient.cs
@@ -114,7 +114,7 @@ namespace Org.BouncyCastle.Tls
             return new CertificateStatusRequest(CertificateStatusType.ocsp, new OcspStatusRequest(null, null));
         }
 
-        /// <returns>an <see cref="IList"/> of <see cref="CertificateStatusRequestItemV2"/> (or null).</returns>
+        /// <returns>an <see cref="IList{T}"/> of <see cref="CertificateStatusRequestItemV2"/> (or null).</returns>
         protected virtual IList<CertificateStatusRequestItemV2> GetMultiCertStatusRequest()
         {
             return null;
@@ -130,7 +130,7 @@ namespace Org.BouncyCastle.Tls
         /// <param name="namedGroupRoles">The <see cref="NamedGroupRole">named group roles</see> for which there should
         /// be at least one supported group. By default this is inferred from the offered cipher suites and signature
         /// algorithms.</param>
-        /// <returns>an <see cref="IList"/> of <see cref="Int32"/>. See <see cref="NamedGroup"/> for group constants.
+        /// <returns>an <see cref="IList{T}"/> of <see cref="Int32"/>. See <see cref="NamedGroup"/> for group constants.
         /// </returns>
         protected virtual IList<int> GetSupportedGroups(IList<int> namedGroupRoles)
         {
diff --git a/crypto/src/tls/CertificateRequest.cs b/crypto/src/tls/CertificateRequest.cs
index d2bbe57c1..5eefb25f0 100644
--- a/crypto/src/tls/CertificateRequest.cs
+++ b/crypto/src/tls/CertificateRequest.cs
@@ -54,7 +54,7 @@ namespace Org.BouncyCastle.Tls
 
         /// <param name="certificateTypes">see <see cref="ClientCertificateType"/> for valid constants.</param>
         /// <param name="supportedSignatureAlgorithms"></param>
-        /// <param name="certificateAuthorities">an <see cref="IList"/> of <see cref="X509Name"/>.</param>
+        /// <param name="certificateAuthorities">an <see cref="IList{T}"/> of <see cref="X509Name"/>.</param>
         public CertificateRequest(short[] certificateTypes,
             IList<SignatureAndHashAlgorithm> supportedSignatureAlgorithms, IList<X509Name> certificateAuthorities)
             : this(null, certificateTypes, supportedSignatureAlgorithms, null, certificateAuthorities)
@@ -108,21 +108,21 @@ namespace Org.BouncyCastle.Tls
             get { return m_certificateTypes; }
         }
 
-        /// <returns>an <see cref="IList"/> of <see cref="SignatureAndHashAlgorithm"/> (or null before TLS 1.2).
+        /// <returns>an <see cref="IList{T}"/> of <see cref="SignatureAndHashAlgorithm"/> (or null before TLS 1.2).
         /// </returns>
         public IList<SignatureAndHashAlgorithm> SupportedSignatureAlgorithms
         {
             get { return m_supportedSignatureAlgorithms; }
         }
 
-        /// <returns>an optional <see cref="IList"/> of <see cref="SignatureAndHashAlgorithm"/>. May be non-null from
+        /// <returns>an optional <see cref="IList{T}"/> of <see cref="SignatureAndHashAlgorithm"/>. May be non-null from
         /// TLS 1.3 onwards.</returns>
         public IList<SignatureAndHashAlgorithm> SupportedSignatureAlgorithmsCert
         {
             get { return m_supportedSignatureAlgorithmsCert; }
         }
 
-        /// <returns>an <see cref="IList"/> of <see cref="X509Name"/>.</returns>
+        /// <returns>an <see cref="IList{T}"/> of <see cref="X509Name"/>.</returns>
         public IList<X509Name> CertificateAuthorities
         {
             get { return m_certificateAuthorities; }
diff --git a/crypto/src/tls/CertificateStatus.cs b/crypto/src/tls/CertificateStatus.cs
index 7ff11f729..1efa10020 100644
--- a/crypto/src/tls/CertificateStatus.cs
+++ b/crypto/src/tls/CertificateStatus.cs
@@ -42,7 +42,7 @@ namespace Org.BouncyCastle.Tls
             }
         }
 
-        /// <summary>an <see cref="IList"/> of (possibly null) <see cref="Asn1.Ocsp.OcspResponse"/>.</summary>
+        /// <summary>an <see cref="IList{T}"/> of (possibly null) <see cref="Asn1.Ocsp.OcspResponse"/>.</summary>
         public IList<OcspResponse> OcspResponseList
         {
             get
diff --git a/crypto/src/tls/CertificateUrl.cs b/crypto/src/tls/CertificateUrl.cs
index e14446d6f..822745e4e 100644
--- a/crypto/src/tls/CertificateUrl.cs
+++ b/crypto/src/tls/CertificateUrl.cs
@@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Tls
         private readonly IList<UrlAndHash> m_urlAndHashList;
 
         /// <param name="type">see <see cref="CertChainType"/> for valid constants.</param>
-        /// <param name="urlAndHashList">an <see cref="IList"/> of <see cref="UrlAndHash"/>.</param>
+        /// <param name="urlAndHashList">an <see cref="IList{T}"/> of <see cref="UrlAndHash"/>.</param>
         public CertificateUrl(short type, IList<UrlAndHash> urlAndHashList)
         {
             if (!CertChainType.IsValid(type))
@@ -35,7 +35,7 @@ namespace Org.BouncyCastle.Tls
             get { return m_type; }
         }
 
-        /// <returns>an <see cref="IList"/> of <see cref="UrlAndHash"/>.</returns>
+        /// <returns>an <see cref="IList{T}"/> of <see cref="UrlAndHash"/>.</returns>
         public IList<UrlAndHash> UrlAndHashList
         {
             get { return m_urlAndHashList; }
diff --git a/crypto/src/tls/DefaultTlsDHGroupVerifier.cs b/crypto/src/tls/DefaultTlsDHGroupVerifier.cs
index 9aa3a23b4..b36e13b84 100644
--- a/crypto/src/tls/DefaultTlsDHGroupVerifier.cs
+++ b/crypto/src/tls/DefaultTlsDHGroupVerifier.cs
@@ -60,7 +60,7 @@ namespace Org.BouncyCastle.Tls
 
         /// <summary>Accept named groups and a custom set of group parameters, subject to a minimum bitlength for 'P'.
         /// </summary>
-        /// <param name="groups">a <see cref="IList">list</see> of acceptable <see cref="DHGroup"/>s.</param>
+        /// <param name="groups">a <see cref="IList{T}">list</see> of acceptable <see cref="DHGroup"/>s.</param>
         /// <param name="minimumPrimeBits">the minimum bitlength of 'P'.</param>
         public DefaultTlsDHGroupVerifier(IList<DHGroup> groups, int minimumPrimeBits)
         {
diff --git a/crypto/src/tls/DefaultTlsSrpConfigVerifier.cs b/crypto/src/tls/DefaultTlsSrpConfigVerifier.cs
index 30b107ed2..d12e60261 100644
--- a/crypto/src/tls/DefaultTlsSrpConfigVerifier.cs
+++ b/crypto/src/tls/DefaultTlsSrpConfigVerifier.cs
@@ -32,7 +32,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <summary>Specify a custom set of acceptable group parameters.</summary>
-        /// <param name="groups">an <see cref="IList"/> of acceptable <see cref="Srp6Group"/>.</param>
+        /// <param name="groups">an <see cref="IList{T}"/> of acceptable <see cref="Srp6Group"/>.</param>
         public DefaultTlsSrpConfigVerifier(IList<Srp6Group> groups)
         {
             this.m_groups = new List<Srp6Group>(groups);
diff --git a/crypto/src/tls/OcspStatusRequest.cs b/crypto/src/tls/OcspStatusRequest.cs
index a1688efcb..4eaa176d9 100644
--- a/crypto/src/tls/OcspStatusRequest.cs
+++ b/crypto/src/tls/OcspStatusRequest.cs
@@ -15,7 +15,7 @@ namespace Org.BouncyCastle.Tls
         private readonly IList<ResponderID> m_responderIDList;
         private readonly X509Extensions m_requestExtensions;
 
-        /// <param name="responderIDList">an <see cref="IList"/> of <see cref="ResponderID"/>, specifying the list of
+        /// <param name="responderIDList">an <see cref="IList{T}"/> of <see cref="ResponderID"/>, specifying the list of
         /// trusted OCSP responders. An empty list has the special meaning that the responders are implicitly known to
         /// the server - e.g., by prior arrangement.</param>
         /// <param name="requestExtensions">OCSP request extensions. A null value means that there are no extensions.
@@ -26,7 +26,7 @@ namespace Org.BouncyCastle.Tls
             this.m_requestExtensions = requestExtensions;
         }
 
-        /// <returns>an <see cref="IList"/> of <see cref="ResponderID"/>.</returns>
+        /// <returns>an <see cref="IList{T}"/> of <see cref="ResponderID"/>.</returns>
         public IList<ResponderID> ResponderIDList
         {
             get { return m_responderIDList; }
diff --git a/crypto/src/tls/ServerNameList.cs b/crypto/src/tls/ServerNameList.cs
index 248cf2f7f..743dacfe8 100644
--- a/crypto/src/tls/ServerNameList.cs
+++ b/crypto/src/tls/ServerNameList.cs
@@ -11,7 +11,7 @@ namespace Org.BouncyCastle.Tls
     {
         private readonly IList<ServerName> m_serverNameList;
 
-        /// <param name="serverNameList">an <see cref="IList"/> of <see cref="ServerName"/>.</param>
+        /// <param name="serverNameList">an <see cref="IList{T}"/> of <see cref="ServerName"/>.</param>
         public ServerNameList(IList<ServerName> serverNameList)
         {
             if (null == serverNameList)
@@ -20,7 +20,7 @@ namespace Org.BouncyCastle.Tls
             this.m_serverNameList = serverNameList;
         }
 
-        /// <returns>an <see cref="IList"/> of <see cref="ServerName"/>.</returns>
+        /// <returns>an <see cref="IList{T}"/> of <see cref="ServerName"/>.</returns>
         public IList<ServerName> ServerNames
         {
             get { return m_serverNameList; }
diff --git a/crypto/src/tls/TlsClient.cs b/crypto/src/tls/TlsClient.cs
index 368161c32..d93799aaf 100644
--- a/crypto/src/tls/TlsClient.cs
+++ b/crypto/src/tls/TlsClient.cs
@@ -20,7 +20,7 @@ namespace Org.BouncyCastle.Tls
 
         /// <summary>Return the <see cref="TlsPskExternal">external PSKs</see> to offer in the ClientHello.</summary>
         /// <remarks>This will only be called when TLS 1.3 or higher is amongst the offered protocol versions.</remarks>
-        /// <returns>an <see cref="IList"/> of <see cref="TlsPskExternal"/> instances, or null if none should be
+        /// <returns>an <see cref="IList{T}"/> of <see cref="TlsPskExternal"/> instances, or null if none should be
         /// offered.</returns>
         IList<TlsPskExternal> GetExternalPsks();
 
@@ -36,7 +36,8 @@ namespace Org.BouncyCastle.Tls
         /// Groups that were not included in the supported_groups extension (by <see cref="GetClientExtensions"/> will
         /// be ignored. The protocol will then add a suitable key_share extension to the ClientHello extensions.
         /// </remarks>
-        /// <returns>an <see cref="IList"/> of <see cref="NamedGroup">named group</see> values, possibly empty or null.
+        /// <returns>an <see cref="IList{T}"/> of <see cref="NamedGroup">named group</see> values, possibly empty or
+        /// null.
         /// </returns>
         IList<int> GetEarlyKeyShareGroups();
 
diff --git a/crypto/src/tls/TlsExtensionsUtilities.cs b/crypto/src/tls/TlsExtensionsUtilities.cs
index 6ad22f1e4..5a97e1efc 100644
--- a/crypto/src/tls/TlsExtensionsUtilities.cs
+++ b/crypto/src/tls/TlsExtensionsUtilities.cs
@@ -16,7 +16,7 @@ namespace Org.BouncyCastle.Tls
         }
 
         /// <param name="extensions">(Int32 -> byte[])</param>
-        /// <param name="protocolNameList">an <see cref="IList"/> of <see cref="ProtocolName"/>.</param>
+        /// <param name="protocolNameList">an <see cref="IList{T}"/> of <see cref="ProtocolName"/>.</param>
         /// <exception cref="IOException"/>
         public static void AddAlpnExtensionClient(IDictionary<int, byte[]> extensions,
             IList<ProtocolName> protocolNameList)
@@ -270,7 +270,7 @@ namespace Org.BouncyCastle.Tls
             extensions[ExtensionType.trusted_ca_keys] = CreateTrustedCAKeysExtensionServer();
         }
 
-        /// <returns>an <see cref="IList"/> of <see cref="ProtocolName"/>.</returns>
+        /// <returns>an <see cref="IList{T}"/> of <see cref="ProtocolName"/>.</returns>
         /// <exception cref="IOException"/>
         public static IList<ProtocolName> GetAlpnExtensionClient(IDictionary<int, byte[]> extensions)
         {
@@ -550,7 +550,7 @@ namespace Org.BouncyCastle.Tls
             return extensionData == null ? false : ReadTrustedCAKeysExtensionServer(extensionData);
         }
 
-        /// <param name="protocolNameList">an <see cref="IList"/> of <see cref="ProtocolName"/>.</param>
+        /// <param name="protocolNameList">an <see cref="IList{T}"/> of <see cref="ProtocolName"/>.</param>
         /// <exception cref="IOException"/>
         public static byte[] CreateAlpnExtensionClient(IList<ProtocolName> protocolNameList)
         {
@@ -966,7 +966,7 @@ namespace Org.BouncyCastle.Tls
             return true;
         }
 
-        /// <returns>an <see cref="IList"/> of <see cref="ProtocolName"/>.</returns>
+        /// <returns>an <see cref="IList{T}"/> of <see cref="ProtocolName"/>.</returns>
         /// <exception cref="IOException"/>
         public static IList<ProtocolName> ReadAlpnExtensionClient(byte[] extensionData)
         {
diff --git a/crypto/src/tls/TlsServer.cs b/crypto/src/tls/TlsServer.cs
index 9d8ae966d..153427266 100644
--- a/crypto/src/tls/TlsServer.cs
+++ b/crypto/src/tls/TlsServer.cs
@@ -29,7 +29,7 @@ namespace Org.BouncyCastle.Tls
         /// Note that this will only be called when TLS 1.3 or higher is amongst the offered protocol versions, and one
         /// or more PSKs are actually offered.
         /// </remarks>
-        /// <param name="identities">an <see cref="IList"/> of <see cref="PskIdentity"/> instances.</param>
+        /// <param name="identities">an <see cref="IList{T}"/> of <see cref="PskIdentity"/> instances.</param>
         /// <returns>The <see cref="TlsPskExternal"/> corresponding to the selected identity, or null to not select
         /// any.</returns>
         TlsPskExternal GetExternalPsk(IList<PskIdentity> identities);
diff --git a/crypto/src/tls/crypto/TlsCrypto.cs b/crypto/src/tls/crypto/TlsCrypto.cs
index a99be8612..c9d00cbb0 100644
--- a/crypto/src/tls/crypto/TlsCrypto.cs
+++ b/crypto/src/tls/crypto/TlsCrypto.cs
@@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Tls.Crypto
         /// <summary>Return true if this TlsCrypto would use a stream verifier for any of the passed in algorithms.
         /// </summary>
         /// <remarks>This method is only relevant to handshakes negotiating (D)TLS 1.2.</remarks>
-        /// <param name="signatureAndHashAlgorithms">A <see cref="IList">list</see> of
+        /// <param name="signatureAndHashAlgorithms">A <see cref="IList{T}">list</see> of
         /// <see cref="SignatureAndHashAlgorithm"/> values.</param>
         /// <returns>true if this instance would use a stream verifier for any of the passed in algorithms, otherwise
         /// false.</returns>
diff --git a/crypto/src/util/date/DateTimeUtilities.cs b/crypto/src/util/date/DateTimeUtilities.cs
index 311ad5d37..72e5123a2 100644
--- a/crypto/src/util/date/DateTimeUtilities.cs
+++ b/crypto/src/util/date/DateTimeUtilities.cs
@@ -4,7 +4,7 @@ namespace Org.BouncyCastle.Utilities.Date
 {
 	public class DateTimeUtilities
 	{
-		public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1);
+		public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
 
 		private DateTimeUtilities()
 		{
@@ -33,7 +33,7 @@ namespace Org.BouncyCastle.Utilities.Date
 		public static DateTime UnixMsToDateTime(
 			long unixMs)
 		{
-			return new DateTime(unixMs * TimeSpan.TicksPerMillisecond + UnixEpoch.Ticks);
+			return new DateTime(unixMs * TimeSpan.TicksPerMillisecond + UnixEpoch.Ticks, DateTimeKind.Utc);
 		}
 
 		/// <summary>
diff --git a/crypto/src/x509/extension/X509ExtensionUtil.cs b/crypto/src/x509/extension/X509ExtensionUtil.cs
index b751658e1..e1f925b08 100644
--- a/crypto/src/x509/extension/X509ExtensionUtil.cs
+++ b/crypto/src/x509/extension/X509ExtensionUtil.cs
@@ -1,88 +1,25 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-
 using Org.BouncyCastle.Asn1;
-using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Security.Certificates;
 
 namespace Org.BouncyCastle.X509.Extension
 {
 	public class X509ExtensionUtilities
 	{
-		public static Asn1Object FromExtensionValue(
-			Asn1OctetString extensionValue)
+		public static Asn1Object FromExtensionValue(Asn1OctetString extensionValue)
 		{
 			return Asn1Object.FromByteArray(extensionValue.GetOctets());
 		}
 
-		public static IList<IList<object>> GetIssuerAlternativeNames(X509Certificate cert)
-		{
-			Asn1OctetString extVal = cert.GetExtensionValue(X509Extensions.IssuerAlternativeName);
-
-			return GetAlternativeName(extVal);
-		}
-
-		public static IList<IList<object>> GetSubjectAlternativeNames(X509Certificate cert)
+		/// <summary>
+		/// Extract the value of the given extension, if it exists.
+		/// </summary>
+		/// <param name="extensions">The extensions object.</param>
+		/// <param name="oid">The object identifier to obtain.</param>
+		/// <returns>Asn1Object</returns>
+		/// <exception cref="Exception">if the extension cannot be read.</exception>
+		public static Asn1Object FromExtensionValue(IX509Extension extensions, DerObjectIdentifier oid)
 		{
-			Asn1OctetString extVal = cert.GetExtensionValue(X509Extensions.SubjectAlternativeName);
-
-			return GetAlternativeName(extVal);
-		}
-
-		private static IList<IList<object>> GetAlternativeName(
-			Asn1OctetString extVal)
-		{
-			var result = new List<IList<object>>();
-
-			if (extVal != null)
-			{
-				try
-				{
-					Asn1Sequence seq = Asn1Sequence.GetInstance(FromExtensionValue(extVal));
-
-					foreach (Asn1Encodable primName in seq)
-					{
-						GeneralName genName = GeneralName.GetInstance(primName);
-
-						var list = new List<object>(2);
-						list.Add(genName.TagNo);
-
-						switch (genName.TagNo)
-						{
-						case GeneralName.EdiPartyName:
-						case GeneralName.X400Address:
-						case GeneralName.OtherName:
-							list.Add(genName.Name.ToAsn1Object());
-							break;
-						case GeneralName.DirectoryName:
-							list.Add(X509Name.GetInstance(genName.Name).ToString());
-							break;
-						case GeneralName.DnsName:
-						case GeneralName.Rfc822Name:
-						case GeneralName.UniformResourceIdentifier:
-							list.Add(((IAsn1String)genName.Name).GetString());
-							break;
-						case GeneralName.RegisteredID:
-							list.Add(DerObjectIdentifier.GetInstance(genName.Name).Id);
-							break;
-						case GeneralName.IPAddress:
-							list.Add(Asn1OctetString.GetInstance(genName.Name).GetOctets());
-							break;
-						default:
-							throw new IOException("Bad tag number: " + genName.TagNo);
-						}
-
-						result.Add(list);
-					}
-				}
-				catch (Exception e)
-				{
-					throw new CertificateParsingException(e.Message);
-				}
-			}
-
-			return result;
+			Asn1OctetString extensionValue = extensions.GetExtensionValue(oid);
+			return extensionValue == null ? null : FromExtensionValue(extensionValue);	
 		}
 	}
 }
diff --git a/crypto/test/src/crypto/prng/test/CtrDrbgTest.cs b/crypto/test/src/crypto/prng/test/CtrDrbgTest.cs
index 1fd051294..2471bba8c 100644
--- a/crypto/test/src/crypto/prng/test/CtrDrbgTest.cs
+++ b/crypto/test/src/crypto/prng/test/CtrDrbgTest.cs
@@ -340,7 +340,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Test
 
                 output = new byte[tv.GetExpectedValue(0).Length];
 
-                d.Generate(output, tv.GetAdditionalInput(0), tv.PredictionResistance);
+                d.Generate(output, 0, output.Length, tv.GetAdditionalInput(0), tv.PredictionResistance);
 
                 byte[] expected = tv.GetExpectedValue(0);
 
@@ -351,7 +351,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Test
 
                 output = new byte[tv.GetExpectedValue(0).Length];
 
-                d.Generate(output, tv.GetAdditionalInput(1), tv.PredictionResistance);
+                d.Generate(output, 0, output.Length, tv.GetAdditionalInput(1), tv.PredictionResistance);
 
                 expected = tv.GetExpectedValue(1);
                 if (!AreEqual(expected, output))
@@ -368,7 +368,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Test
 
             output = new byte[tv.GetExpectedValue(0).Length];
 
-            drbg.Generate(output, tv.GetAdditionalInput(0), tv.PredictionResistance);
+            drbg.Generate(output, 0, output.Length, tv.GetAdditionalInput(0), tv.PredictionResistance);
 
             // Exception tests
             try
diff --git a/crypto/test/src/crypto/prng/test/HMacDrbgTest.cs b/crypto/test/src/crypto/prng/test/HMacDrbgTest.cs
index f523cc4d7..9e2ae7b90 100644
--- a/crypto/test/src/crypto/prng/test/HMacDrbgTest.cs
+++ b/crypto/test/src/crypto/prng/test/HMacDrbgTest.cs
@@ -414,7 +414,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Test
 
                 byte[] output = new byte[tv.GetExpectedValue(0).Length];
 
-                d.Generate(output, tv.GetAdditionalInput(0), tv.PredictionResistance);
+                d.Generate(output, 0, output.Length, tv.GetAdditionalInput(0), tv.PredictionResistance);
 
                 byte[] expected = tv.GetExpectedValue(0);
 
@@ -425,7 +425,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Test
 
                 output = new byte[tv.GetExpectedValue(0).Length];
 
-                d.Generate(output, tv.GetAdditionalInput(1), tv.PredictionResistance);
+                d.Generate(output, 0, output.Length, tv.GetAdditionalInput(1), tv.PredictionResistance);
 
                 expected = tv.GetExpectedValue(1);
                 if (!AreEqual(expected, output))
diff --git a/crypto/test/src/crypto/prng/test/HashDrbgTest.cs b/crypto/test/src/crypto/prng/test/HashDrbgTest.cs
index e043f03da..29929c613 100644
--- a/crypto/test/src/crypto/prng/test/HashDrbgTest.cs
+++ b/crypto/test/src/crypto/prng/test/HashDrbgTest.cs
@@ -356,7 +356,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Test
 
                 byte[] output = new byte[tv.GetExpectedValue(0).Length];
 
-                d.Generate(output, tv.GetAdditionalInput(0), tv.PredictionResistance);
+                d.Generate(output, 0, output.Length, tv.GetAdditionalInput(0), tv.PredictionResistance);
 
                 byte[] expected = tv.GetExpectedValue(0);
 
@@ -367,7 +367,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Test
 
                 output = new byte[tv.GetExpectedValue(0).Length];
 
-                d.Generate(output, tv.GetAdditionalInput(1), tv.PredictionResistance);
+                d.Generate(output, 0, output.Length, tv.GetAdditionalInput(1), tv.PredictionResistance);
 
                 expected = tv.GetExpectedValue(1);
                 if (!AreEqual(expected, output))
diff --git a/crypto/test/src/crypto/test/DSATest.cs b/crypto/test/src/crypto/test/DSATest.cs
index b81ef511f..f9f601ed8 100644
--- a/crypto/test/src/crypto/test/DSATest.cs
+++ b/crypto/test/src/crypto/test/DSATest.cs
@@ -592,16 +592,16 @@ namespace Org.BouncyCastle.Crypto.Tests
             {
             }
 
-            public override void NextBytes(byte[] bytes)
+            public override void NextBytes(byte[] buf, int off, int len)
             {
                 if (first)
                 {
-                    base.NextBytes(bytes);
+                    base.NextBytes(buf, off, len);
                     first = false;
                 }
                 else
                 {
-                    bytes[bytes.Length - 1] = 2;
+                    buf[off + len - 1] = 2;
                 }
             }
         }
diff --git a/crypto/test/src/crypto/test/GOST3410Test.cs b/crypto/test/src/crypto/test/GOST3410Test.cs
index 93c234ca1..130fdaf92 100644
--- a/crypto/test/src/crypto/test/GOST3410Test.cs
+++ b/crypto/test/src/crypto/test/GOST3410Test.cs
@@ -239,7 +239,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 				get { return "Gost3410-TEST1-1024"; }
 			}
 
-			private class SecureRandomImpl1 : SecureRandom
+			private class SecureRandomImpl1 : SecureRandomImpl
 			{
 				bool firstInt = true;
 
@@ -266,7 +266,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom init_random = new SecureRandomImpl1();
 
-			private class SecureRandomImpl2 : SecureRandom
+			private class SecureRandomImpl2 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -291,7 +291,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom random = new SecureRandomImpl2();
 
-			private class SecureRandomImpl3 : SecureRandom
+			private class SecureRandomImpl3 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -386,7 +386,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 				get { return "Gost3410-TEST2-1024"; }
 			}
 
-			private class SecureRandomImpl4 : SecureRandom
+			private class SecureRandomImpl4 : SecureRandomImpl
 			{
 				bool firstLong = true;
 
@@ -413,7 +413,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom init_random = new SecureRandomImpl4();
 
-			private class SecureRandomImpl5 : SecureRandom
+			private class SecureRandomImpl5 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -438,7 +438,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom random = new SecureRandomImpl5();
 
-			private class SecureRandomImpl6 : SecureRandom
+			private class SecureRandomImpl6 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -533,7 +533,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 				get { return "Gost3410-AParam"; }
 			}
 
-			private class SecureRandomImpl7 : SecureRandom
+			private class SecureRandomImpl7 : SecureRandomImpl
 			{
 				bool firstLong = true;
 
@@ -560,7 +560,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom init_random = new SecureRandomImpl7();
 
-			private class SecureRandomImpl8 : SecureRandom
+			private class SecureRandomImpl8 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -585,7 +585,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom random = new SecureRandomImpl8();
 
-			private class SecureRandomImpl9 : SecureRandom
+			private class SecureRandomImpl9 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -680,7 +680,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 				get { return "Gost3410-BParam"; }
 			}
 
-			private class SecureRandomImpl10 : SecureRandom
+			private class SecureRandomImpl10 : SecureRandomImpl
 			{
 				bool firstLong = true;
 
@@ -706,7 +706,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom init_random = new SecureRandomImpl10();
 
-			private class SecureRandomImpl11 : SecureRandom
+			private class SecureRandomImpl11 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -731,7 +731,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom random = new SecureRandomImpl11();
 
-			private class SecureRandomImpl12 : SecureRandom
+			private class SecureRandomImpl12 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -826,7 +826,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 				get { return "Gost3410-CParam"; }
 			}
 
-			private class SecureRandomImpl13 : SecureRandom
+			private class SecureRandomImpl13 : SecureRandomImpl
 			{
 				bool firstLong = true;
 
@@ -852,7 +852,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom init_random = new SecureRandomImpl13();
 
-			private class SecureRandomImpl14 : SecureRandom
+			private class SecureRandomImpl14 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -877,7 +877,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom random = new SecureRandomImpl14();
 
-			private class SecureRandomImpl15 : SecureRandom
+			private class SecureRandomImpl15 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -972,7 +972,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 				get { return "Gost3410-DParam"; }
 			}
 
-			private class SecureRandomImpl16 : SecureRandom
+			private class SecureRandomImpl16 : SecureRandomImpl
 			{
 				bool firstLong = true;
 
@@ -999,7 +999,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom init_random = new SecureRandomImpl16();
 
-			private class SecureRandomImpl17 : SecureRandom
+			private class SecureRandomImpl17 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -1024,7 +1024,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom random = new SecureRandomImpl17();
 
-			private class SecureRandomImpl18 : SecureRandom
+			private class SecureRandomImpl18 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -1119,7 +1119,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 				get { return "Gost3410-AExParam"; }
 			}
 
-			private class SecureRandomImpl19 : SecureRandom
+			private class SecureRandomImpl19 : SecureRandomImpl
 			{
 				bool firstLong = true;
 
@@ -1145,7 +1145,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom init_random = new SecureRandomImpl19();
 
-			private class SecureRandomImpl20 : SecureRandom
+			private class SecureRandomImpl20 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -1170,7 +1170,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom random = new SecureRandomImpl20();
 
-			private class SecureRandomImpl21 : SecureRandom
+			private class SecureRandomImpl21 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -1265,7 +1265,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 				get { return "Gost3410-BExParam"; }
 			}
 
-			private class SecureRandomImpl22 : SecureRandom
+			private class SecureRandomImpl22 : SecureRandomImpl
 			{
 				bool firstLong = true;
 
@@ -1291,7 +1291,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom init_random = new SecureRandomImpl22();
 
-			private class SecureRandomImpl23 : SecureRandom
+			private class SecureRandomImpl23 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -1316,7 +1316,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom random = new SecureRandomImpl23();
 
-			private class SecureRandomImpl24 : SecureRandom
+			private class SecureRandomImpl24 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -1411,7 +1411,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 				get { return "Gost3410-CExParam"; }
 			}
 
-			private class SecureRandomImpl25 : SecureRandom
+			private class SecureRandomImpl25 : SecureRandomImpl
 			{
 				bool firstLong = true;
 
@@ -1437,7 +1437,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom init_random = new SecureRandomImpl25();
 
-			private class SecureRandomImpl26 : SecureRandom
+			private class SecureRandomImpl26 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -1462,7 +1462,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 			};
 			SecureRandom random = new SecureRandomImpl26();
 
-			private class SecureRandomImpl27 : SecureRandom
+			private class SecureRandomImpl27 : SecureRandomImpl
 			{
 				public override void NextBytes(byte[] bytes)
 				{
@@ -1591,5 +1591,15 @@ namespace Org.BouncyCastle.Crypto.Tests
 
 			Assert.AreEqual(Name + ": Okay", resultText);
 		}
+
+		internal class SecureRandomImpl : SecureRandom
+		{
+			public override void NextBytes(byte[] buf, int off, int len)
+			{
+				byte[] bytes = new byte[len];
+				NextBytes(bytes);
+				bytes.CopyTo(buf, off);
+			}
+		}
 	}
 }
diff --git a/crypto/test/src/crypto/test/OAEPTest.cs b/crypto/test/src/crypto/test/OAEPTest.cs
index 37faff740..b2cbde8b3 100644
--- a/crypto/test/src/crypto/test/OAEPTest.cs
+++ b/crypto/test/src/crypto/test/OAEPTest.cs
@@ -293,10 +293,14 @@ namespace Org.BouncyCastle.Crypto.Tests
                 this.seed = seed;
             }
 
-            public override void NextBytes(
-                byte[] bytes)
+            public override void NextBytes(byte[] buf)
             {
-                Array.Copy(seed, 0, bytes, 0, bytes.Length);
+                NextBytes(buf, 0, buf.Length);
+            }
+
+            public override void NextBytes(byte[] buf, int off, int len)
+            {
+                Array.Copy(seed, 0, buf, off, len);
             }
         }
 
diff --git a/crypto/test/src/crypto/test/PSSBlindTest.cs b/crypto/test/src/crypto/test/PSSBlindTest.cs
index 0abb8d87d..1cd74bb70 100644
--- a/crypto/test/src/crypto/test/PSSBlindTest.cs
+++ b/crypto/test/src/crypto/test/PSSBlindTest.cs
@@ -36,10 +36,14 @@ namespace Org.BouncyCastle.Crypto.Tests
 				this.vals = vals;
 			}
 
-			public override void NextBytes(
-				byte[] bytes)
+			public override void NextBytes(byte[] buf)
 			{
-				Array.Copy(vals, 0, bytes, 0, vals.Length);
+				NextBytes(buf, 0, buf.Length);
+			}
+
+			public override void NextBytes(byte[] buf, int off, int len)
+			{
+				Array.Copy(vals, 0, buf, off, len);
 			}
 		}
 
diff --git a/crypto/test/src/crypto/test/PSSTest.cs b/crypto/test/src/crypto/test/PSSTest.cs
index 6375269a4..aeaf85a53 100644
--- a/crypto/test/src/crypto/test/PSSTest.cs
+++ b/crypto/test/src/crypto/test/PSSTest.cs
@@ -32,10 +32,14 @@ namespace Org.BouncyCastle.Crypto.Tests
 				this.vals = vals;
 			}
 
-			public override void NextBytes(
-				byte[] bytes)
+			public override void NextBytes(byte[] buf)
 			{
-				Array.Copy(vals, 0, bytes, 0, vals.Length);
+				NextBytes(buf, 0, buf.Length);
+			}
+
+			public override void NextBytes(byte[] buf, int off, int len)
+			{
+				Array.Copy(vals, 0, buf, off, len);
 			}
 		}
 
diff --git a/crypto/test/src/crypto/test/RC2WrapTest.cs b/crypto/test/src/crypto/test/RC2WrapTest.cs
index 9471ba6c9..7d98ee9af 100644
--- a/crypto/test/src/crypto/test/RC2WrapTest.cs
+++ b/crypto/test/src/crypto/test/RC2WrapTest.cs
@@ -22,10 +22,14 @@ namespace Org.BouncyCastle.Crypto.Tests
 		private class RFCRandom
 			: SecureRandom
 		{
-			public override void NextBytes(
-				byte[] nextBytes)
+			public override void NextBytes(byte[] buf)
 			{
-				Array.Copy(Hex.Decode("4845cce7fd1250"), 0, nextBytes, 0, nextBytes.Length);
+				NextBytes(buf, 0, buf.Length);
+			}
+
+			public override void NextBytes(byte[] buf, int off, int len)
+			{
+				Array.Copy(Hex.Decode("4845cce7fd1250"), 0, buf, off, len);
 			}
 		}
 
diff --git a/crypto/test/src/pqc/crypto/lms/HSSTests.cs b/crypto/test/src/pqc/crypto/lms/HSSTests.cs
index 0d01e5d1f..2045f7693 100644
--- a/crypto/test/src/pqc/crypto/lms/HSSTests.cs
+++ b/crypto/test/src/pqc/crypto/lms/HSSTests.cs
@@ -731,15 +731,20 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         class HSSSecureRandom
             : SecureRandom
         {
-            public override void NextBytes(byte[] bytes)
+            public override void NextBytes(byte[] buf)
             {
-                for (int t = 0; t < bytes.Length; t++)
+                NextBytes(buf, 0, buf.Length);
+            }
+
+            public override void NextBytes(byte[] buf, int off, int len)
+            {
+                for (int t = 0; t < len; t++)
                 {
-                    bytes[t] = 1;
+                    buf[off + t] = 1;
                 }
             }
         }
-        
+
         [Test]
         public void TestSignUnitExhaustion()
         {
diff --git a/crypto/test/src/pqc/crypto/test/NistSecureRandom.cs b/crypto/test/src/pqc/crypto/test/NistSecureRandom.cs
index 0ca8dd990..aac73c4ee 100644
--- a/crypto/test/src/pqc/crypto/test/NistSecureRandom.cs
+++ b/crypto/test/src/pqc/crypto/test/NistSecureRandom.cs
@@ -69,14 +69,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests
             reseed_counuter = 1;
         }
 
-        public override void NextBytes(byte[] x)
+        public override void NextBytes(byte[] buf)
+        {
+            NextBytes(buf, 0, buf.Length);
+        }
+
+        public override void NextBytes(byte[] buf, int off, int len)
         {
             byte[] block = new byte[16];
             int i = 0;
 
-            int xlen = x.Length;
-
-            while (xlen > 0)
+            while (len > 0)
             {
                 for (int j = 15; j >= 0; j--)
                 {
@@ -93,16 +96,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests
 
                 AES256_ECB(key, v, block, 0);
 
-                if (xlen > 15)
+                if (len > 15)
                 {
-                    Array.Copy(block, 0, x, i, block.Length);
+                    Array.Copy(block, 0, buf, off + i, block.Length);
                     i += 16;
-                    xlen -= 16;
+                    len -= 16;
                 }
                 else
                 {
-                    Array.Copy(block, 0, x, i, xlen);
-                    xlen = 0;
+                    Array.Copy(block, 0, buf, off + i, len);
+                    len = 0;
                 }
             }
 
diff --git a/crypto/test/src/test/BlockCipherTest.cs b/crypto/test/src/test/BlockCipherTest.cs
index b57d62d94..d0e5e20b3 100644
--- a/crypto/test/src/test/BlockCipherTest.cs
+++ b/crypto/test/src/test/BlockCipherTest.cs
@@ -402,18 +402,21 @@ namespace Org.BouncyCastle.Tests
                     (byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f
             };
 
-            public override void NextBytes(
-                byte[] bytes)
+            public override void NextBytes(byte[] buf)
             {
-                int offset = 0;
+                NextBytes(buf, 0, buf.Length);
+            }
 
-                while ((offset + seed.Length) < bytes.Length)
+            public override void NextBytes(byte[] buf, int off, int len)
+            {
+                int pos = 0;
+                while ((pos + seed.Length) < len)
                 {
-                    Array.Copy(seed, 0, bytes, offset, seed.Length);
-                    offset += seed.Length;
+                    Array.Copy(seed, 0, buf, off + pos, seed.Length);
+                    pos += seed.Length;
                 }
 
-                Array.Copy(seed, 0, bytes, offset, bytes.Length- offset);
+                Array.Copy(seed, 0, buf, off + pos, len - pos);
             }
         }
 
diff --git a/crypto/test/src/test/DESedeTest.cs b/crypto/test/src/test/DESedeTest.cs
index 04d8725ae..39d55e424 100644
--- a/crypto/test/src/test/DESedeTest.cs
+++ b/crypto/test/src/test/DESedeTest.cs
@@ -46,25 +46,28 @@ namespace Org.BouncyCastle.Tests
             : SecureRandom
         {
             private byte[] seed =
-        {
-            (byte)0xaa, (byte)0xfd, (byte)0x12, (byte)0xf6, (byte)0x59,
-            (byte)0xca, (byte)0xe6, (byte)0x34, (byte)0x89, (byte)0xb4,
-            (byte)0x79, (byte)0xe5, (byte)0x07, (byte)0x6d, (byte)0xde,
-            (byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f
-        };
+            {
+                (byte)0xaa, (byte)0xfd, (byte)0x12, (byte)0xf6, (byte)0x59,
+                (byte)0xca, (byte)0xe6, (byte)0x34, (byte)0x89, (byte)0xb4,
+                (byte)0x79, (byte)0xe5, (byte)0x07, (byte)0x6d, (byte)0xde,
+                (byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f
+            };
 
-            public override void NextBytes(
-                byte[] bytes)
+            public override void NextBytes(byte[] buf)
             {
-                int offset = 0;
+                NextBytes(buf, 0, buf.Length);
+            }
 
-                while ((offset + seed.Length) < bytes.Length)
+            public override void NextBytes(byte[] buf, int off, int len)
+            {
+                int pos = 0;
+                while ((pos + seed.Length) < len)
                 {
-                    Array.Copy(seed, 0, bytes, offset, seed.Length);
-                    offset += seed.Length;
+                    Array.Copy(seed, 0, buf, off + pos, seed.Length);
+                    pos += seed.Length;
                 }
 
-                Array.Copy(seed, 0, bytes, offset, bytes.Length - offset);
+                Array.Copy(seed, 0, buf, off + pos, len - pos);
             }
         }
 
diff --git a/crypto/test/src/test/DSATest.cs b/crypto/test/src/test/DSATest.cs
index b4868c52f..95b46c2bf 100644
--- a/crypto/test/src/test/DSATest.cs
+++ b/crypto/test/src/test/DSATest.cs
@@ -829,16 +829,21 @@ namespace Org.BouncyCastle.Tests
             {
             }
 
-            public override void NextBytes(byte[] bytes)
+            public override void NextBytes(byte[] buf)
+            {
+                NextBytes(buf, 0, buf.Length);
+            }
+
+            public override void NextBytes(byte[] buf, int off, int len)
             {
                 if (first)
                 {
-                    base.NextBytes(bytes);
+                    base.NextBytes(buf, off, len);
                     first = false;
                 }
                 else
                 {
-                    bytes[bytes.Length - 1] = 2;
+                    buf[off + len - 1] = 2;
                 }
             }
         }
diff --git a/crypto/test/src/test/PSSTest.cs b/crypto/test/src/test/PSSTest.cs
index ab8f0f690..fa6f54e31 100644
--- a/crypto/test/src/test/PSSTest.cs
+++ b/crypto/test/src/test/PSSTest.cs
@@ -33,10 +33,17 @@ namespace Org.BouncyCastle.Tests
 				this.vals = vals;
 			}
 
-			public override void NextBytes(
-				byte[] bytes)
+			public override void NextBytes(byte[] buf)
 			{
-				vals.CopyTo(bytes, 0);
+				NextBytes(buf, 0, buf.Length);
+			}
+
+			public override void NextBytes(byte[] buf, int off, int len)
+			{
+				if (vals.Length > len)
+					throw new InvalidOperationException();
+
+				vals.CopyTo(buf, off);
 			}
 		}
 
diff --git a/crypto/test/src/test/RSATest.cs b/crypto/test/src/test/RSATest.cs
index 267472d91..94c1fb816 100644
--- a/crypto/test/src/test/RSATest.cs
+++ b/crypto/test/src/test/RSATest.cs
@@ -39,18 +39,21 @@ namespace Org.BouncyCastle.Tests
 				(byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f
 			};
 
-			public override void NextBytes(
-				byte[] bytes)
+			public override void NextBytes(byte[] buf)
 			{
-				int offset = 0;
+				NextBytes(buf, 0, buf.Length);
+			}
 
-				while ((offset + seed.Length) < bytes.Length)
+			public override void NextBytes(byte[] buf, int off, int len)
+			{
+				int pos = 0;
+				while ((pos + seed.Length) < len)
 				{
-					seed.CopyTo(bytes, offset);
-					offset += seed.Length;
+					seed.CopyTo(buf, off + pos);
+					pos += seed.Length;
 				}
 
-				Array.Copy(seed, 0, bytes, offset, bytes.Length - offset);
+				Array.Copy(seed, 0, buf, off + pos, len - pos);
 			}
 		}
 
diff --git a/crypto/test/src/util/test/FixedSecureRandom.cs b/crypto/test/src/util/test/FixedSecureRandom.cs
index 682b3eefa..be5b25347 100644
--- a/crypto/test/src/util/test/FixedSecureRandom.cs
+++ b/crypto/test/src/util/test/FixedSecureRandom.cs
@@ -211,21 +211,15 @@ namespace Org.BouncyCastle.Utilities.Test
 
         public override byte[] GenerateSeed(int numBytes)
         {
-            return SecureRandom.GetNextBytes(this, numBytes);
+            return GetNextBytes(this, numBytes);
         }
 
-        public override void NextBytes(
-			byte[] buf)
+        public override void NextBytes(byte[] buf)
 		{
-			Array.Copy(_data, _index, buf, 0, buf.Length);
-
-			_index += buf.Length;
+            NextBytes(buf, 0, buf.Length);
 		}
 
-		public override void NextBytes(
-			byte[]	buf,
-			int		off,
-			int		len)
+		public override void NextBytes(byte[] buf, int off, int len)
 		{
 			Array.Copy(_data, _index, buf, off, len);
 
@@ -243,11 +237,16 @@ namespace Org.BouncyCastle.Utilities.Test
             byte[] data = Hex.Decode("01020304ffffffff0506070811111111");
             int    index = 0;
 
-            public override void NextBytes(byte[] bytes)
+            public override void NextBytes(byte[] buf)
+            {
+                NextBytes(buf, 0, buf.Length);
+            }
+
+            public override void NextBytes(byte[] buf, int off, int len)
             {
-                Array.Copy(data, index, bytes, 0, bytes.Length);
+                Array.Copy(data, index, buf, off, len);
 
-                index += bytes.Length;
+                index += len;
             }
         }