summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-10-05 15:44:48 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-10-05 15:44:48 +0700
commit7699428eb4416a52ae9a529c133839b2fd989903 (patch)
tree64bf393583c98549253b5edd6c67695d70c8f091
parentBigInteger in-place conversions (diff)
downloadBouncyCastle.NET-ed25519-7699428eb4416a52ae9a529c133839b2fd989903.tar.xz
Various span usages
-rw-r--r--crypto/src/crypto/agreement/srp/SRP6Utilities.cs117
-rw-r--r--crypto/src/crypto/signers/HMacDsaKCalculator.cs50
-rw-r--r--crypto/src/crypto/signers/X931Signer.cs18
-rw-r--r--crypto/src/openpgp/PgpPublicKey.cs12
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs2
-rw-r--r--crypto/src/util/Arrays.cs18
6 files changed, 143 insertions, 74 deletions
diff --git a/crypto/src/crypto/agreement/srp/SRP6Utilities.cs b/crypto/src/crypto/agreement/srp/SRP6Utilities.cs
index ef6d8f24c..2176a7100 100644
--- a/crypto/src/crypto/agreement/srp/SRP6Utilities.cs
+++ b/crypto/src/crypto/agreement/srp/SRP6Utilities.cs
@@ -20,7 +20,10 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
 
 		public static BigInteger CalculateX(IDigest digest, BigInteger N, byte[] salt, byte[] identity, byte[] password)
 	    {
-	        byte[] output = new byte[digest.GetDigestSize()];
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            return CalculateX(digest, N, salt.AsSpan(), identity.AsSpan(), password.AsSpan());
+#else
+            byte[] output = new byte[digest.GetDigestSize()];
 
 	        digest.BlockUpdate(identity, 0, identity.Length);
 	        digest.Update((byte)':');
@@ -32,9 +35,29 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
 	        digest.DoFinal(output, 0);
 
 	        return new BigInteger(1, output);
+#endif
 	    }
 
-		public static BigInteger GeneratePrivateValue(IDigest digest, BigInteger N, BigInteger g, SecureRandom random)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public static BigInteger CalculateX(IDigest digest, BigInteger N, ReadOnlySpan<byte> salt,
+            ReadOnlySpan<byte> identity, ReadOnlySpan<byte> password)
+        {
+            Span<byte> output = stackalloc byte[digest.GetDigestSize()];
+
+            digest.BlockUpdate(identity);
+            digest.Update((byte)':');
+            digest.BlockUpdate(password);
+            digest.DoFinal(output);
+
+            digest.BlockUpdate(salt);
+            digest.BlockUpdate(output);
+            digest.DoFinal(output);
+
+            return new BigInteger(1, output);
+        }
+#endif
+
+        public static BigInteger GeneratePrivateValue(IDigest digest, BigInteger N, BigInteger g, SecureRandom random)
 	    {
 			int minBits = System.Math.Min(256, N.BitLength / 2);
 	        BigInteger min = BigInteger.One.ShiftLeft(minBits - 1);
@@ -95,59 +118,83 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
          */
         public static BigInteger CalculateKey(IDigest digest, BigInteger N, BigInteger S)
         {
-            int padLength = (N.BitLength + 7) / 8;
-            byte[] _S = GetPadded(S, padLength);
-            digest.BlockUpdate(_S, 0, _S.Length);
+            int paddedLength = (N.BitLength + 7) / 8;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            Span<byte> bytes = stackalloc byte[paddedLength];
+            BigIntegers.AsUnsignedByteArray(S, bytes);
+            digest.BlockUpdate(bytes);
+
+            Span<byte> output = stackalloc byte[digest.GetDigestSize()];
+            digest.DoFinal(output);
+#else
+            byte[] bytes = new byte[paddedLength];
+            BigIntegers.AsUnsignedByteArray(S, bytes, 0, bytes.Length);
+	        digest.BlockUpdate(bytes, 0, bytes.Length);
 
             byte[] output = new byte[digest.GetDigestSize()];
             digest.DoFinal(output, 0);
+#endif
+
             return new BigInteger(1, output);
         }
 
         private static BigInteger HashPaddedTriplet(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2, BigInteger n3)
         {
-            int padLength = (N.BitLength + 7) / 8;
-
-            byte[] n1_bytes = GetPadded(n1, padLength);
-            byte[] n2_bytes = GetPadded(n2, padLength);
-            byte[] n3_bytes = GetPadded(n3, padLength);
-
-            digest.BlockUpdate(n1_bytes, 0, n1_bytes.Length);
-            digest.BlockUpdate(n2_bytes, 0, n2_bytes.Length);
-            digest.BlockUpdate(n3_bytes, 0, n3_bytes.Length);
+            int paddedLength = (N.BitLength + 7) / 8;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            Span<byte> bytes = stackalloc byte[paddedLength];
+            BigIntegers.AsUnsignedByteArray(n1, bytes);
+            digest.BlockUpdate(bytes);
+            BigIntegers.AsUnsignedByteArray(n2, bytes);
+            digest.BlockUpdate(bytes);
+            BigIntegers.AsUnsignedByteArray(n3, bytes);
+            digest.BlockUpdate(bytes);
+
+            Span<byte> output = stackalloc byte[digest.GetDigestSize()];
+            digest.DoFinal(output);
+#else
+            byte[] bytes = new byte[paddedLength];
+            BigIntegers.AsUnsignedByteArray(n1, bytes, 0, bytes.Length);
+	        digest.BlockUpdate(bytes, 0, bytes.Length);
+            BigIntegers.AsUnsignedByteArray(n2, bytes, 0, bytes.Length);
+	        digest.BlockUpdate(bytes, 0, bytes.Length);
+            BigIntegers.AsUnsignedByteArray(n3, bytes, 0, bytes.Length);
+	        digest.BlockUpdate(bytes, 0, bytes.Length);
 
             byte[] output = new byte[digest.GetDigestSize()];
             digest.DoFinal(output, 0);
+#endif
 
             return new BigInteger(1, output);
         }
 
         private static BigInteger HashPaddedPair(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2)
 		{
-	    	int padLength = (N.BitLength + 7) / 8;
-
-	    	byte[] n1_bytes = GetPadded(n1, padLength);
-	    	byte[] n2_bytes = GetPadded(n2, padLength);
-
-	        digest.BlockUpdate(n1_bytes, 0, n1_bytes.Length);
-	        digest.BlockUpdate(n2_bytes, 0, n2_bytes.Length);
+	    	int paddedLength = (N.BitLength + 7) / 8;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            Span<byte> bytes = stackalloc byte[paddedLength];
+            BigIntegers.AsUnsignedByteArray(n1, bytes);
+            digest.BlockUpdate(bytes);
+            BigIntegers.AsUnsignedByteArray(n2, bytes);
+            digest.BlockUpdate(bytes);
+
+            Span<byte> output = stackalloc byte[digest.GetDigestSize()];
+            digest.DoFinal(output);
+#else
+            byte[] bytes = new byte[paddedLength];
+            BigIntegers.AsUnsignedByteArray(n1, bytes, 0, bytes.Length);
+	        digest.BlockUpdate(bytes, 0, bytes.Length);
+            BigIntegers.AsUnsignedByteArray(n2, bytes, 0, bytes.Length);
+	        digest.BlockUpdate(bytes, 0, bytes.Length);
 
 	        byte[] output = new byte[digest.GetDigestSize()];
 	        digest.DoFinal(output, 0);
+#endif
 
-	        return new BigInteger(1, output);
-		}
-
-		private static byte[] GetPadded(BigInteger n, int length)
-		{
-			byte[] bs = BigIntegers.AsUnsignedByteArray(n);
-			if (bs.Length < length)
-			{
-				byte[] tmp = new byte[length];
-				Array.Copy(bs, 0, tmp, length - bs.Length, bs.Length);
-				bs = tmp;
-			}
-			return bs;
-		}
+            return new BigInteger(1, output);
+        }
 	}
 }
diff --git a/crypto/src/crypto/signers/HMacDsaKCalculator.cs b/crypto/src/crypto/signers/HMacDsaKCalculator.cs
index 2641f58b6..25e36530c 100644
--- a/crypto/src/crypto/signers/HMacDsaKCalculator.cs
+++ b/crypto/src/crypto/signers/HMacDsaKCalculator.cs
@@ -46,55 +46,55 @@ namespace Org.BouncyCastle.Crypto.Signers
         {
             this.n = n;
 
-            Arrays.Fill(V, (byte)0x01);
-            Arrays.Fill(K, (byte)0);
-
-            int size = BigIntegers.GetUnsignedByteLength(n);
-            byte[] x = new byte[size];
-            byte[] dVal = BigIntegers.AsUnsignedByteArray(d);
-
-            Array.Copy(dVal, 0, x, x.Length - dVal.Length, dVal.Length);
-
-            byte[] m = new byte[size];
+            Arrays.Fill(V, 0x01);
+            Arrays.Fill(K, 0);
 
             BigInteger mInt = BitsToInt(message);
-
             if (mInt.CompareTo(n) >= 0)
             {
                 mInt = mInt.Subtract(n);
             }
 
-            byte[] mVal = BigIntegers.AsUnsignedByteArray(mInt);
+            int size = BigIntegers.GetUnsignedByteLength(n);
 
-            Array.Copy(mVal, 0, m, m.Length - mVal.Length, mVal.Length);
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            Span<byte> xm = stackalloc byte[size * 2];
+            BigIntegers.AsUnsignedByteArray(d, xm[..size]);
+            BigIntegers.AsUnsignedByteArray(mInt, xm[size..]);
+#else
+            byte[] x = BigIntegers.AsUnsignedByteArray(size, d);
+            byte[] m = BigIntegers.AsUnsignedByteArray(size, mInt);
+#endif
 
             hMac.Init(new KeyParameter(K));
 
             hMac.BlockUpdate(V, 0, V.Length);
-            hMac.Update((byte)0x00);
+            hMac.Update(0x00);
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            hMac.BlockUpdate(xm);
+#else
             hMac.BlockUpdate(x, 0, x.Length);
             hMac.BlockUpdate(m, 0, m.Length);
+#endif
             InitAdditionalInput0(hMac);
-
             hMac.DoFinal(K, 0);
 
             hMac.Init(new KeyParameter(K));
-
             hMac.BlockUpdate(V, 0, V.Length);
-
             hMac.DoFinal(V, 0);
 
             hMac.BlockUpdate(V, 0, V.Length);
-            hMac.Update((byte)0x01);
+            hMac.Update(0x01);
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            hMac.BlockUpdate(xm);
+#else
             hMac.BlockUpdate(x, 0, x.Length);
             hMac.BlockUpdate(m, 0, m.Length);
-
+#endif
             hMac.DoFinal(K, 0);
 
             hMac.Init(new KeyParameter(K));
-
             hMac.BlockUpdate(V, 0, V.Length);
-
             hMac.DoFinal(V, 0);
         }
 
@@ -109,7 +109,6 @@ namespace Org.BouncyCastle.Crypto.Signers
                 while (tOff < t.Length)
                 {
                     hMac.BlockUpdate(V, 0, V.Length);
-
                     hMac.DoFinal(V, 0);
 
                     int len = System.Math.Min(t.Length - tOff, V.Length);
@@ -120,19 +119,14 @@ namespace Org.BouncyCastle.Crypto.Signers
                 BigInteger k = BitsToInt(t);
 
                 if (k.SignValue > 0 && k.CompareTo(n) < 0)
-                {
                     return k;
-                }
 
                 hMac.BlockUpdate(V, 0, V.Length);
-                hMac.Update((byte)0x00);
-
+                hMac.Update(0x00);
                 hMac.DoFinal(K, 0);
 
                 hMac.Init(new KeyParameter(K));
-
                 hMac.BlockUpdate(V, 0, V.Length);
-
                 hMac.DoFinal(V, 0);
             }
         }
diff --git a/crypto/src/crypto/signers/X931Signer.cs b/crypto/src/crypto/signers/X931Signer.cs
index 6c0aa9427..278410f2a 100644
--- a/crypto/src/crypto/signers/X931Signer.cs
+++ b/crypto/src/crypto/signers/X931Signer.cs
@@ -3,6 +3,7 @@
 using Org.BouncyCastle.Crypto.Parameters;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Zlib;
 
 namespace Org.BouncyCastle.Crypto.Signers
 {
@@ -82,12 +83,6 @@ namespace Org.BouncyCastle.Crypto.Signers
             Reset();
         }
 
-        /// <summary> clear possible sensitive data</summary>
-        private void ClearBlock(byte[] block)
-        {
-            Array.Clear(block, 0, block.Length);
-        }
-
         public virtual void Update(byte b)
         {
             digest.Update(b);
@@ -115,7 +110,7 @@ namespace Org.BouncyCastle.Crypto.Signers
             CreateSignatureBlock();
 
             BigInteger t = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length));
-            ClearBlock(block);
+            Arrays.Fill(block, 0x00);
 
             t = t.Min(kParam.Modulus.Subtract(t));
 
@@ -183,12 +178,17 @@ namespace Org.BouncyCastle.Crypto.Signers
 
             CreateSignatureBlock();
 
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            Span<byte> fBlock = stackalloc byte[block.Length];
+            BigIntegers.AsUnsignedByteArray(f, fBlock);
+#else
             byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f);
+#endif
 
             bool rv = Arrays.ConstantTimeAreEqual(block, fBlock);
 
-            ClearBlock(block);
-            ClearBlock(fBlock);
+            Arrays.Fill(block, 0x00);
+            Arrays.Fill<byte>(fBlock, 0x00);
 
             return rv;
         }
diff --git a/crypto/src/openpgp/PgpPublicKey.cs b/crypto/src/openpgp/PgpPublicKey.cs
index 09c8b9743..6d5f35018 100644
--- a/crypto/src/openpgp/PgpPublicKey.cs
+++ b/crypto/src/openpgp/PgpPublicKey.cs
@@ -507,7 +507,17 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
         {
             ECPublicBcpgKey ecK = (ECPublicBcpgKey)publicPk.Key;
             X9ECParameters x9 = ECKeyPairGenerator.FindECCurveByOid(ecK.CurveOid);
-            ECPoint q = x9.Curve.DecodePoint(BigIntegers.AsUnsignedByteArray(ecK.EncodedPoint));
+            BigInteger encodedPoint = ecK.EncodedPoint;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            int encodingLength = BigIntegers.GetUnsignedByteLength(encodedPoint);
+            Span<byte> encoding = stackalloc byte[encodingLength];
+            BigIntegers.AsUnsignedByteArray(encodedPoint, encoding);
+            ECPoint q = x9.Curve.DecodePoint(encoding);
+#else
+            ECPoint q = x9.Curve.DecodePoint(BigIntegers.AsUnsignedByteArray(encodedPoint));
+#endif
+
             return new ECPublicKeyParameters(algorithm, q, ecK.CurveOid);
         }
 
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs b/crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs
index faf6b4576..6a947c23b 100644
--- a/crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs
@@ -24,7 +24,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
 
         private static int GetValueLength(DHParameters dh)
         {
-            return (dh.P.BitLength + 7) / 8;
+            return BigIntegers.GetUnsignedByteLength(dh.P);
         }
 
         public static BcTlsSecret CalculateDHAgreement(BcTlsCrypto crypto, DHPrivateKeyParameters privateKey,
diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs
index c2ba9c3e1..e8dd02148 100644
--- a/crypto/src/util/Arrays.cs
+++ b/crypto/src/util/Arrays.cs
@@ -620,6 +620,24 @@ namespace Org.BouncyCastle.Utilities
             }
         }
 
+        public static void Fill<T>(T[] ts, T t)
+        {
+            for (int i = 0; i < ts.Length; ++i)
+            {
+                ts[i] = t;
+            }
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public static void Fill<T>(Span<T> ts, T t)
+        {
+            for (int i = 0; i < ts.Length; ++i)
+            {
+                ts[i] = t;
+            }
+        }
+#endif
+
         public static byte[] CopyOf(byte[] data, int newLength)
         {
             byte[] tmp = new byte[newLength];