2
0
Эх сурвалжийг харах

Commiting files that were not commited on previous commit

olegkap_cp 12 жил өмнө
parent
commit
6dc8840e45

+ 1 - 1
Renci.SshClient/Renci.SshNet/ScpClient.NET.cs

@@ -17,7 +17,7 @@ namespace Renci.SshNet
     /// </summary>
     public partial class ScpClient
     {
-        private Regex _rootPath = new Regex(@"^(/|[A-Z][:])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+        private static Regex _rootPath = new Regex(@"^(/|[A-Z][:])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
         /// <summary>
         /// Uploads the specified file or directory to the remote host.
         /// </summary>

+ 62 - 80
Renci.SshClient/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.cs

@@ -19,37 +19,9 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 
         private int _rounds;
 
-        private uint[,] _encryptionKey;
-        /// <summary>
-        /// Gets the encryption key.
-        /// </summary>
-        protected uint[,] EncryptionKey
-        {
-            get
-            {
-                if (this._encryptionKey == null)
-                {
-                    this._encryptionKey = this.GenerateWorkingKey(true, this.Key);
-                }
-                return this._encryptionKey;
-            }
-        }
+        private uint[] _encryptionKey;
 
-        private uint[,] _decryptionKey;
-        /// <summary>
-        /// Gets the encryption key.
-        /// </summary>
-        protected uint[,] DecryptionKey
-        {
-            get
-            {
-                if (this._decryptionKey == null)
-                {
-                    this._decryptionKey = this.GenerateWorkingKey(false, this.Key);
-                }
-                return this._decryptionKey;
-            }
-        }
+        private uint[] _decryptionKey;
 
         private uint C0, C1, C2, C3;
 
@@ -634,9 +606,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
                 throw new IndexOutOfRangeException("output buffer too short");
             }
 
+            if (this._encryptionKey == null)
+            {
+                this._encryptionKey = this.GenerateWorkingKey(true, this.Key);
+            }
+
             this.UnPackBlock(inputBuffer, inputOffset);
 
-            this.EncryptBlock(this.EncryptionKey);
+            this.EncryptBlock(this._encryptionKey);
 
             this.PackBlock(outputBuffer, outputOffset);
 
@@ -674,16 +651,21 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
                 throw new IndexOutOfRangeException("output buffer too short");
             }
 
+            if (this._decryptionKey == null)
+            {
+                this._decryptionKey = this.GenerateWorkingKey(false, this.Key);
+            }
+
             this.UnPackBlock(inputBuffer, inputOffset);
 
-            this.DecryptBlock(this.DecryptionKey);
+            this.DecryptBlock(this._decryptionKey);
 
             this.PackBlock(outputBuffer, outputOffset);
 
             return this.BlockSize;
         }
 
-        private uint[,] GenerateWorkingKey(bool isEncryption, byte[] key)
+        private uint[] GenerateWorkingKey(bool isEncryption, byte[] key)
         {
             int KC = key.Length / 4;  // key length in words
 
@@ -691,7 +673,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
                 throw new ArgumentException("Key length not 128/192/256 bits.");
 
             _rounds = KC + 6;  // This is not always true for the generalized Rijndael that allows larger block sizes
-            uint[,] W = new uint[_rounds + 1, 4];   // 4 words in a block
+            uint[] W = new uint[(_rounds + 1) *  4];   // 4 words in a block
 
             //
             // copy the key into the round key array
@@ -701,7 +683,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 
             for (int i = 0; i < key.Length; t++)
             {
-                W[t >> 2, t & 3] = LittleEndianToUInt32(key, i);
+                W[(t >> 2) * 4 + (t & 3)] = LittleEndianToUInt32(key, i);
                 i += 4;
             }
 
@@ -712,7 +694,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
             int k = (_rounds + 1) << 2;
             for (int i = KC; (i < k); i++)
             {
-                uint temp = W[(i - 1) >> 2, (i - 1) & 3];
+                uint temp = W[((i - 1) >> 2) * 4 + ((i - 1) & 3)];
                 if ((i % KC) == 0)
                 {
                     temp = SubWord(Shift(temp, 8)) ^ rcon[(i / KC) - 1];
@@ -722,7 +704,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
                     temp = SubWord(temp);
                 }
 
-                W[i >> 2, i & 3] = W[(i - KC) >> 2, (i - KC) & 3] ^ temp;
+                W[(i >> 2) * 4 + (i & 3)] = W[((i - KC) >> 2) * 4 + ((i - KC) & 3)] ^ temp;
             }
 
             if (!isEncryption)
@@ -731,7 +713,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
                 {
                     for (int i = 0; i < 4; i++)
                     {
-                        W[j, i] = InvMcol(W[j, i]);
+                        W[j * 4 + i] = InvMcol(W[j * 4 + i]);
                     }
                 }
             }
@@ -783,74 +765,74 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
             UInt32ToLittleEndian(C3, bytes, off + 12);
         }
 
-        private void EncryptBlock(uint[,] KW)
+        private void EncryptBlock(uint[] KW)
         {
             int r;
             uint r0, r1, r2, r3;
 
-            C0 ^= KW[0, 0];
-            C1 ^= KW[0, 1];
-            C2 ^= KW[0, 2];
-            C3 ^= KW[0, 3];
+            C0 ^= KW[0 * 4 + 0];
+            C1 ^= KW[0 * 4 + 1];
+            C2 ^= KW[0 * 4 + 2];
+            C3 ^= KW[0 * 4 + 3];
 
             for (r = 1; r < _rounds - 1; )
             {
-                r0 = T0[C0 & 255] ^ T1[(C1 >> 8) & 255] ^ T2[(C2 >> 16) & 255] ^ T3[C3 >> 24] ^ KW[r, 0];
-                r1 = T0[C1 & 255] ^ T1[(C2 >> 8) & 255] ^ T2[(C3 >> 16) & 255] ^ T3[C0 >> 24] ^ KW[r, 1];
-                r2 = T0[C2 & 255] ^ T1[(C3 >> 8) & 255] ^ T2[(C0 >> 16) & 255] ^ T3[C1 >> 24] ^ KW[r, 2];
-                r3 = T0[C3 & 255] ^ T1[(C0 >> 8) & 255] ^ T2[(C1 >> 16) & 255] ^ T3[C2 >> 24] ^ KW[r++, 3];
-                C0 = T0[r0 & 255] ^ T1[(r1 >> 8) & 255] ^ T2[(r2 >> 16) & 255] ^ T3[r3 >> 24] ^ KW[r, 0];
-                C1 = T0[r1 & 255] ^ T1[(r2 >> 8) & 255] ^ T2[(r3 >> 16) & 255] ^ T3[r0 >> 24] ^ KW[r, 1];
-                C2 = T0[r2 & 255] ^ T1[(r3 >> 8) & 255] ^ T2[(r0 >> 16) & 255] ^ T3[r1 >> 24] ^ KW[r, 2];
-                C3 = T0[r3 & 255] ^ T1[(r0 >> 8) & 255] ^ T2[(r1 >> 16) & 255] ^ T3[r2 >> 24] ^ KW[r++, 3];
+                r0 = T0[C0 & 255] ^ T1[(C1 >> 8) & 255] ^ T2[(C2 >> 16) & 255] ^ T3[C3 >> 24] ^ KW[r * 4 + 0];
+                r1 = T0[C1 & 255] ^ T1[(C2 >> 8) & 255] ^ T2[(C3 >> 16) & 255] ^ T3[C0 >> 24] ^ KW[r * 4 + 1];
+                r2 = T0[C2 & 255] ^ T1[(C3 >> 8) & 255] ^ T2[(C0 >> 16) & 255] ^ T3[C1 >> 24] ^ KW[r * 4 + 2];
+                r3 = T0[C3 & 255] ^ T1[(C0 >> 8) & 255] ^ T2[(C1 >> 16) & 255] ^ T3[C2 >> 24] ^ KW[r++ * 4 + 3];
+                C0 = T0[r0 & 255] ^ T1[(r1 >> 8) & 255] ^ T2[(r2 >> 16) & 255] ^ T3[r3 >> 24] ^ KW[r * 4 + 0];
+                C1 = T0[r1 & 255] ^ T1[(r2 >> 8) & 255] ^ T2[(r3 >> 16) & 255] ^ T3[r0 >> 24] ^ KW[r * 4 + 1];
+                C2 = T0[r2 & 255] ^ T1[(r3 >> 8) & 255] ^ T2[(r0 >> 16) & 255] ^ T3[r1 >> 24] ^ KW[r * 4 + 2];
+                C3 = T0[r3 & 255] ^ T1[(r0 >> 8) & 255] ^ T2[(r1 >> 16) & 255] ^ T3[r2 >> 24] ^ KW[r++ * 4 + 3];
             }
 
-            r0 = T0[C0 & 255] ^ T1[(C1 >> 8) & 255] ^ T2[(C2 >> 16) & 255] ^ T3[C3 >> 24] ^ KW[r, 0];
-            r1 = T0[C1 & 255] ^ T1[(C2 >> 8) & 255] ^ T2[(C3 >> 16) & 255] ^ T3[C0 >> 24] ^ KW[r, 1];
-            r2 = T0[C2 & 255] ^ T1[(C3 >> 8) & 255] ^ T2[(C0 >> 16) & 255] ^ T3[C1 >> 24] ^ KW[r, 2];
-            r3 = T0[C3 & 255] ^ T1[(C0 >> 8) & 255] ^ T2[(C1 >> 16) & 255] ^ T3[C2 >> 24] ^ KW[r++, 3];
+            r0 = T0[C0 & 255] ^ T1[(C1 >> 8) & 255] ^ T2[(C2 >> 16) & 255] ^ T3[C3 >> 24] ^ KW[r * 4 + 0];
+            r1 = T0[C1 & 255] ^ T1[(C2 >> 8) & 255] ^ T2[(C3 >> 16) & 255] ^ T3[C0 >> 24] ^ KW[r * 4 + 1];
+            r2 = T0[C2 & 255] ^ T1[(C3 >> 8) & 255] ^ T2[(C0 >> 16) & 255] ^ T3[C1 >> 24] ^ KW[r * 4 + 2];
+            r3 = T0[C3 & 255] ^ T1[(C0 >> 8) & 255] ^ T2[(C1 >> 16) & 255] ^ T3[C2 >> 24] ^ KW[r++ * 4 + 3];
 
             // the final round's table is a simple function of S so we don't use a whole other four tables for it
 
-            C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[r3 >> 24]) << 24) ^ KW[r, 0];
-            C1 = (uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[r0 >> 24]) << 24) ^ KW[r, 1];
-            C2 = (uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[r1 >> 24]) << 24) ^ KW[r, 2];
-            C3 = (uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[r2 >> 24]) << 24) ^ KW[r, 3];
+            C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[r3 >> 24]) << 24) ^ KW[r * 4 + 0];
+            C1 = (uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[r0 >> 24]) << 24) ^ KW[r * 4 + 1];
+            C2 = (uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[r1 >> 24]) << 24) ^ KW[r * 4 + 2];
+            C3 = (uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[r2 >> 24]) << 24) ^ KW[r * 4 + 3];
         }
 
-        private void DecryptBlock(uint[,] KW)
+        private void DecryptBlock(uint[] KW)
         {
             int r;
             uint r0, r1, r2, r3;
 
-            C0 ^= KW[_rounds, 0];
-            C1 ^= KW[_rounds, 1];
-            C2 ^= KW[_rounds, 2];
-            C3 ^= KW[_rounds, 3];
+            C0 ^= KW[_rounds * 4 + 0];
+            C1 ^= KW[_rounds * 4 + 1];
+            C2 ^= KW[_rounds * 4 + 2];
+            C3 ^= KW[_rounds * 4 + 3];
 
             for (r = _rounds - 1; r > 1; )
             {
-                r0 = Tinv0[C0 & 255] ^ Tinv1[(C3 >> 8) & 255] ^ Tinv2[(C2 >> 16) & 255] ^ Tinv3[C1 >> 24] ^ KW[r, 0];
-                r1 = Tinv0[C1 & 255] ^ Tinv1[(C0 >> 8) & 255] ^ Tinv2[(C3 >> 16) & 255] ^ Tinv3[C2 >> 24] ^ KW[r, 1];
-                r2 = Tinv0[C2 & 255] ^ Tinv1[(C1 >> 8) & 255] ^ Tinv2[(C0 >> 16) & 255] ^ Tinv3[C3 >> 24] ^ KW[r, 2];
-                r3 = Tinv0[C3 & 255] ^ Tinv1[(C2 >> 8) & 255] ^ Tinv2[(C1 >> 16) & 255] ^ Tinv3[C0 >> 24] ^ KW[r--, 3];
-                C0 = Tinv0[r0 & 255] ^ Tinv1[(r3 >> 8) & 255] ^ Tinv2[(r2 >> 16) & 255] ^ Tinv3[r1 >> 24] ^ KW[r, 0];
-                C1 = Tinv0[r1 & 255] ^ Tinv1[(r0 >> 8) & 255] ^ Tinv2[(r3 >> 16) & 255] ^ Tinv3[r2 >> 24] ^ KW[r, 1];
-                C2 = Tinv0[r2 & 255] ^ Tinv1[(r1 >> 8) & 255] ^ Tinv2[(r0 >> 16) & 255] ^ Tinv3[r3 >> 24] ^ KW[r, 2];
-                C3 = Tinv0[r3 & 255] ^ Tinv1[(r2 >> 8) & 255] ^ Tinv2[(r1 >> 16) & 255] ^ Tinv3[r0 >> 24] ^ KW[r--, 3];
+                r0 = Tinv0[C0 & 255] ^ Tinv1[(C3 >> 8) & 255] ^ Tinv2[(C2 >> 16) & 255] ^ Tinv3[C1 >> 24] ^ KW[r * 4 + 0];
+                r1 = Tinv0[C1 & 255] ^ Tinv1[(C0 >> 8) & 255] ^ Tinv2[(C3 >> 16) & 255] ^ Tinv3[C2 >> 24] ^ KW[r * 4 + 1];
+                r2 = Tinv0[C2 & 255] ^ Tinv1[(C1 >> 8) & 255] ^ Tinv2[(C0 >> 16) & 255] ^ Tinv3[C3 >> 24] ^ KW[r * 4 + 2];
+                r3 = Tinv0[C3 & 255] ^ Tinv1[(C2 >> 8) & 255] ^ Tinv2[(C1 >> 16) & 255] ^ Tinv3[C0 >> 24] ^ KW[r-- * 4 + 3];
+                C0 = Tinv0[r0 & 255] ^ Tinv1[(r3 >> 8) & 255] ^ Tinv2[(r2 >> 16) & 255] ^ Tinv3[r1 >> 24] ^ KW[r * 4 + 0];
+                C1 = Tinv0[r1 & 255] ^ Tinv1[(r0 >> 8) & 255] ^ Tinv2[(r3 >> 16) & 255] ^ Tinv3[r2 >> 24] ^ KW[r * 4 + 1];
+                C2 = Tinv0[r2 & 255] ^ Tinv1[(r1 >> 8) & 255] ^ Tinv2[(r0 >> 16) & 255] ^ Tinv3[r3 >> 24] ^ KW[r * 4 + 2];
+                C3 = Tinv0[r3 & 255] ^ Tinv1[(r2 >> 8) & 255] ^ Tinv2[(r1 >> 16) & 255] ^ Tinv3[r0 >> 24] ^ KW[r-- * 4 + 3];
             }
 
-            r0 = Tinv0[C0 & 255] ^ Tinv1[(C3 >> 8) & 255] ^ Tinv2[(C2 >> 16) & 255] ^ Tinv3[C1 >> 24] ^ KW[r, 0];
-            r1 = Tinv0[C1 & 255] ^ Tinv1[(C0 >> 8) & 255] ^ Tinv2[(C3 >> 16) & 255] ^ Tinv3[C2 >> 24] ^ KW[r, 1];
-            r2 = Tinv0[C2 & 255] ^ Tinv1[(C1 >> 8) & 255] ^ Tinv2[(C0 >> 16) & 255] ^ Tinv3[C3 >> 24] ^ KW[r, 2];
-            r3 = Tinv0[C3 & 255] ^ Tinv1[(C2 >> 8) & 255] ^ Tinv2[(C1 >> 16) & 255] ^ Tinv3[C0 >> 24] ^ KW[r, 3];
+            r0 = Tinv0[C0 & 255] ^ Tinv1[(C3 >> 8) & 255] ^ Tinv2[(C2 >> 16) & 255] ^ Tinv3[C1 >> 24] ^ KW[r * 4 + 0];
+            r1 = Tinv0[C1 & 255] ^ Tinv1[(C0 >> 8) & 255] ^ Tinv2[(C3 >> 16) & 255] ^ Tinv3[C2 >> 24] ^ KW[r * 4 + 1];
+            r2 = Tinv0[C2 & 255] ^ Tinv1[(C1 >> 8) & 255] ^ Tinv2[(C0 >> 16) & 255] ^ Tinv3[C3 >> 24] ^ KW[r * 4 + 2];
+            r3 = Tinv0[C3 & 255] ^ Tinv1[(C2 >> 8) & 255] ^ Tinv2[(C1 >> 16) & 255] ^ Tinv3[C0 >> 24] ^ KW[r * 4 + 3];
 
             // the final round's table is a simple function of Si so we don't use a whole other four tables for it
 
-            C0 = (uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[r1 >> 24]) << 24) ^ KW[0, 0];
-            C1 = (uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)Si[r2 >> 24]) << 24) ^ KW[0, 1];
-            C2 = (uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)Si[r3 >> 24]) << 24) ^ KW[0, 2];
-            C3 = (uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ (((uint)Si[r0 >> 24]) << 24) ^ KW[0, 3];
+            C0 = (uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[r1 >> 24]) << 24) ^ KW[0 * 4 + 0];
+            C1 = (uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)Si[r2 >> 24]) << 24) ^ KW[0 * 4 + 1];
+            C2 = (uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)Si[r3 >> 24]) << 24) ^ KW[0 * 4 + 2];
+            C3 = (uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ (((uint)Si[r0 >> 24]) << 24) ^ KW[0 * 4 + 3];
         }
     }
 }

+ 44 - 41
Renci.SshClient/Renci.SshNet/Security/Cryptography/Ciphers/Arc4Cipher.cs

@@ -8,23 +8,43 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
     /// <summary>
     /// Implements ARCH4 cipher algorithm
     /// </summary>
-    public class Arc4Cipher : StreamCipher
+    public sealed class Arc4Cipher : StreamCipher
     {
+        private readonly static int STATE_LENGTH = 256;
+
+        /// <summary>
+        ///  Holds the state of the RC4 engine
+        /// </summary>
+        private byte[] _engineState;
+
+        private int _x;
+
+        private int _y;
+
+        private byte[] _workingKey;
+
+        /// <summary>
+        /// Gets the minimum data size.
+        /// </summary>
+        /// <value>
+        /// The minimum data size.
+        /// </value>
         public override byte MinimumSize
         {
             get { return 0; }
         }
 
         /// <summary>
-        /// Initializes a new instance of the <see cref="Arc4Cipher"/> class.
+        /// Initializes a new instance of the <see cref="Arc4Cipher" /> class.
         /// </summary>
         /// <param name="key">The key.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
+        /// <param name="dischargeFirstBytes">if set to <c>true</c> will disharged first 1536 bytes.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="key" /> is null.</exception>
         public Arc4Cipher(byte[] key, bool dischargeFirstBytes)
             : base(key)
         {
-            workingKey = key;
-            SetKey(workingKey);
+            this._workingKey = key;
+            SetKey(this._workingKey);
             //   The first 1536 bytes of keystream
             //   generated by the cipher MUST be discarded, and the first byte of the
             //   first encrypted packet MUST be encrypted using the 1537th byte of
@@ -95,18 +115,6 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
             return output;
         }
 
-        private readonly static int STATE_LENGTH = 256;
-
-        /*
-        * variables to hold the state of the RC4 engine
-        * during encryption and decryption
-        */
-
-        private byte[] engineState;
-        private int x;
-        private int y;
-        private byte[] workingKey;
-
         private int ProcessBytes(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
         {
             if ((inputOffset + inputCount) > inputBuffer.Length)
@@ -121,45 +129,41 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 
             for (int i = 0; i < inputCount; i++)
             {
-                x = (x + 1) & 0xff;
-                y = (engineState[x] + y) & 0xff;
+                this._x = (this._x + 1) & 0xff;
+                this._y = (this._engineState[this._x] + this._y) & 0xff;
 
                 // swap
-                byte tmp = engineState[x];
-                engineState[x] = engineState[y];
-                engineState[y] = tmp;
+                byte tmp = this._engineState[this._x];
+                this._engineState[this._x] = this._engineState[this._y];
+                this._engineState[this._y] = tmp;
 
                 // xor
-                outputBuffer[i + outputOffset] = (byte)(inputBuffer[i + inputOffset] ^ engineState[(engineState[x] + engineState[y]) & 0xff]);
+                outputBuffer[i + outputOffset] = (byte)(inputBuffer[i + inputOffset] ^ this._engineState[(this._engineState[this._x] + this._engineState[this._y]) & 0xff]);
             }
             return inputCount;
         }
 
-        public void Reset()
+        private void Reset()
         {
-            SetKey(workingKey);
+            SetKey(this._workingKey);
         }
 
-        // Private implementation
-
         private void SetKey(byte[] keyBytes)
         {
-            workingKey = keyBytes;
-
-            // System.out.println("the key length is ; "+ workingKey.Length);
+            this._workingKey = keyBytes;
 
-            x = 0;
-            y = 0;
+            this._x = 0;
+            this._y = 0;
 
-            if (engineState == null)
+            if (this._engineState == null)
             {
-                engineState = new byte[STATE_LENGTH];
+                this._engineState = new byte[STATE_LENGTH];
             }
 
             // reset the state of the engine
-            for (int i = 0; i < STATE_LENGTH; i++)
+            for (byte i = 0; i < STATE_LENGTH; i++)
             {
-                engineState[i] = (byte)i;
+                this._engineState[i] = i;
             }
 
             int i1 = 0;
@@ -167,14 +171,13 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 
             for (int i = 0; i < STATE_LENGTH; i++)
             {
-                i2 = ((keyBytes[i1] & 0xff) + engineState[i] + i2) & 0xff;
+                i2 = ((keyBytes[i1] & 0xff) + this._engineState[i] + i2) & 0xff;
                 // do the byte-swap inline
-                byte tmp = engineState[i];
-                engineState[i] = engineState[i2];
-                engineState[i2] = tmp;
+                byte tmp = this._engineState[i];
+                this._engineState[i] = this._engineState[i2];
+                this._engineState[i2] = tmp;
                 i1 = (i1 + 1) % keyBytes.Length;
             }
         }
-
     }
 }

+ 9 - 4
Renci.SshClient/Renci.SshNet/Security/Cryptography/Ciphers/BlowfishCipher.cs

@@ -8,7 +8,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 	/// <summary>
     /// Blowfish cipher implementation.
     /// </summary>
-	public class BlowfishCipher : BlockCipher
+	public sealed class BlowfishCipher : BlockCipher
 	{
 		#region Static reference tables
 
@@ -297,9 +297,15 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 
 		private static readonly int _pSize = _rounds + 2;
 
-		private readonly uint[] _s0, _s1, _s2, _s3;     // the s-boxes
+        /// <summary>
+        /// The s-boxes
+        /// </summary>
+		private readonly uint[] _s0, _s1, _s2, _s3;
 
-		private readonly uint[] _p;                  // the p-array
+        /// <summary>
+        /// The p-array
+        /// </summary>
+		private readonly uint[] _p;
 
 		/// <summary>
 		/// Initializes a new instance of the <see cref="BlowfishCipher"/> class.
@@ -509,6 +515,5 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 				xl = table[s];
 			}
 		}
-
 	}
 }

+ 42 - 42
Renci.SshClient/Renci.SshNet/Security/Cryptography/Ciphers/CastCipher.cs

@@ -8,13 +8,21 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
     /// <summary>
     /// Implements CAST cipher algorithm
     /// </summary>
-    public class CastCipher : BlockCipher
+    public sealed class CastCipher : BlockCipher
     {
         internal static readonly int MAX_ROUNDS = 16;
+
         internal static readonly int RED_ROUNDS = 12;
 
-        private int[] _kr = new int[17];        // the rotating round key
-        private uint[] _km = new uint[17];        // the masking round key
+        /// <summary>
+        /// The rotating round key
+        /// </summary>
+        private int[] _kr = new int[17];
+
+        /// <summary>
+        /// The masking round key
+        /// </summary>
+        private uint[] _km = new uint[17];
 
         private int _rounds = MAX_ROUNDS;
 
@@ -381,12 +389,10 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 
         #endregion
 
-        /*
-        * Creates the subkeys using the same nomenclature
-        * as described in RFC2144.
-        *
-        * See section 2.4
-        */
+        /// <summary>
+        /// Sets the subkeys using the same nomenclatureas described in RFC2144.
+        /// </summary>
+        /// <param name="key">The key.</param>
         private void SetKey(byte[] key)
         {
             /*
@@ -559,15 +565,13 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
             this._kr[16] = (int)((S5[x[0xE]] ^ S6[x[0xF]] ^ S7[x[0x1]] ^ S8[x[0x0]] ^ S8[x[0xD]]) & 0x1f);
         }
 
-        /**
-        * The first of the three processing functions for the
-        * encryption and decryption.
-        *
-        * @param D            the input to be processed
-        * @param Kmi        the mask to be used from Km[n]
-        * @param Kri        the rotation value to be used
-        *
-        */
+        /// <summary>
+        /// The first of the three processing functions for the encryption and decryption.
+        /// </summary>
+        /// <param name="D">The input to be processed.</param>
+        /// <param name="Kmi">The mask to be used from Km[n].</param>
+        /// <param name="Kri">The rotation value to be used.</param>
+        /// <returns></returns>
         private static uint F1(uint D, uint Kmi, int Kri)
         {
             uint I = Kmi + D;
@@ -575,15 +579,13 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
             return ((S1[(I >> 24) & 0xff] ^ S2[(I >> 16) & 0xff]) - S3[(I >> 8) & 0xff]) + S4[I & 0xff];
         }
 
-        /**
-        * The second of the three processing functions for the
-        * encryption and decryption.
-        *
-        * @param D            the input to be processed
-        * @param Kmi        the mask to be used from Km[n]
-        * @param Kri        the rotation value to be used
-        *
-        */
+        /// <summary>
+        /// The second of the three processing functions for the encryption and decryption.
+        /// </summary>
+        /// <param name="D">The input to be processed.</param>
+        /// <param name="Kmi">The mask to be used from Km[n].</param>
+        /// <param name="Kri">The rotation value to be used.</param>
+        /// <returns></returns>
         private static uint F2(uint D, uint Kmi, int Kri)
         {
             uint I = Kmi ^ D;
@@ -591,15 +593,13 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
             return ((S1[(I >> 24) & 0xff] - S2[(I >> 16) & 0xff]) + S3[(I >> 8) & 0xff]) ^ S4[I & 0xff];
         }
 
-        /**
-        * The third of the three processing functions for the
-        * encryption and decryption.
-        *
-        * @param D            the input to be processed
-        * @param Kmi        the mask to be used from Km[n]
-        * @param Kri        the rotation value to be used
-        *
-        */
+        /// <summary>
+        /// The third of the three processing functions for the encryption and decryption.
+        /// </summary>
+        /// <param name="D">The input to be processed.</param>
+        /// <param name="Kmi">The mask to be used from Km[n].</param>
+        /// <param name="Kri">The rotation value to be used.</param>
+        /// <returns></returns>
         private static uint F3(uint D, uint Kmi, int Kri)
         {
             uint I = Kmi - D;
@@ -607,12 +607,12 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
             return ((S1[(I >> 24) & 0xff] + S2[(I >> 16) & 0xff]) ^ S3[(I >> 8) & 0xff]) - S4[I & 0xff];
         }
 
-        /**
-        * Does the 16 rounds to encrypt the block.
-        *
-        * @param L0    the LH-32bits of the plaintext block
-        * @param R0    the RH-32bits of the plaintext block
-        */
+        /// <summary>
+        /// Does the 16 rounds to encrypt the block.
+        /// </summary>
+        /// <param name="L0">The LH-32bits of the plaintext block.</param>
+        /// <param name="R0">The RH-32bits of the plaintext block.</param>
+        /// <param name="result">The result.</param>
         private void CastEncipher(uint L0, uint R0, uint[] result)
         {
             uint Lp = L0;        // the previous value, equiv to L[i-1]

+ 140 - 75
Renci.SshClient/Renci.SshNet/Security/Cryptography/Ciphers/SerpentCipher.cs

@@ -8,9 +8,10 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 	/// <summary>
 	/// Implements Serpent cipher algorithm.
 	/// </summary>
-	public class SerpentCipher : BlockCipher
+	public sealed class SerpentCipher : BlockCipher
 	{
 		private static readonly int ROUNDS = 32;
+
 		private static readonly int PHI = unchecked((int)0x9E3779B9);       // (Sqrt(5) - 1) * 2**31
 
 		private int[] _workingKey;
@@ -321,23 +322,23 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			return w;
 		}
 
-		private int RotateLeft(int x, int bits)
+		private static int RotateLeft(int x, int bits)
 		{
 			return ((x << bits) | (int)((uint)x >> (32 - bits)));
 		}
 
-		private int RotateRight(int x, int bits)
+        private static int RotateRight(int x, int bits)
 		{
 			return ((int)((uint)x >> bits) | (x << (32 - bits)));
 		}
 
-		private int BytesToWord(byte[] src, int srcOff)
+        private static int BytesToWord(byte[] src, int srcOff)
 		{
 			return (((src[srcOff] & 0xff) << 24) | ((src[srcOff + 1] & 0xff) << 16) |
 			((src[srcOff + 2] & 0xff) << 8) | ((src[srcOff + 3] & 0xff)));
 		}
 
-		private void WordToBytes(int word, byte[] dst, int dstOff)
+        private static void WordToBytes(int word, byte[] dst, int dstOff)
 		{
 			dst[dstOff + 3] = (byte)(word);
 			dst[dstOff + 2] = (byte)((uint)word >> 8);
@@ -369,10 +370,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 		/* We hereby give permission for information in this file to be */
 		/* used freely subject only to acknowledgement of its origin.    */
 
-		/**
-		* S0 - { 3, 8,15, 1,10, 6, 5,11,14,13, 4, 2, 7, 0, 9,12 } - 15 terms.
-		*/
-		private void Sb0(int a, int b, int c, int d)
+        /// <summary>
+        /// S0 - { 3, 8,15, 1,10, 6, 5,11,14,13, 4, 2, 7, 0, 9,12 } - 15 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Sb0(int a, int b, int c, int d)
 		{
 			int t1 = a ^ d;
 			int t3 = c ^ t1;
@@ -385,10 +390,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x0 = t12 ^ (~t7);
 		}
 
-		/**
-		* InvSO - {13, 3,11, 0,10, 6, 5,12, 1,14, 4, 7,15, 9, 8, 2 } - 15 terms.
-		*/
-		private void Ib0(int a, int b, int c, int d)
+        /// <summary>
+        /// InvSO - {13, 3,11, 0,10, 6, 5,12, 1,14, 4, 7,15, 9, 8, 2 } - 15 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Ib0(int a, int b, int c, int d)
 		{
 			int t1 = ~a;
 			int t2 = a ^ b;
@@ -401,10 +410,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x0 = this._x3 ^ (t5 ^ t8);
 		}
 
-		/**
-		* S1 - {15,12, 2, 7, 9, 0, 5,10, 1,11,14, 8, 6,13, 3, 4 } - 14 terms.
-		*/
-		private void Sb1(int a, int b, int c, int d)
+        /// <summary>
+        /// S1 - {15,12, 2, 7, 9, 0, 5,10, 1,11,14, 8, 6,13, 3, 4 } - 14 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Sb1(int a, int b, int c, int d)
 		{
 			int t2 = b ^ (~a);
 			int t5 = c ^ (a | t2);
@@ -417,10 +430,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x0 = t5 ^ (t8 & t11);
 		}
 
-		/**
-		* InvS1 - { 5, 8, 2,14,15, 6,12, 3,11, 4, 7, 9, 1,13,10, 0 } - 14 steps.
-		*/
-		private void Ib1(int a, int b, int c, int d)
+        /// <summary>
+        /// InvS1 - { 5, 8, 2,14,15, 6,12, 3,11, 4, 7, 9, 1,13,10, 0 } - 14 steps.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Ib1(int a, int b, int c, int d)
 		{
 			int t1 = b ^ d;
 			int t3 = a ^ (b & t1);
@@ -435,10 +452,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x2 = t4 ^ (t10 | t11);
 		}
 
-		/**
-		* S2 - { 8, 6, 7, 9, 3,12,10,15,13, 1,14, 4, 0,11, 5, 2 } - 16 terms.
-		*/
-		private void Sb2(int a, int b, int c, int d)
+        /// <summary>
+        /// S2 - { 8, 6, 7, 9, 3,12,10,15,13, 1,14, 4, 0,11, 5, 2 } - 16 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Sb2(int a, int b, int c, int d)
 		{
 			int t1 = ~a;
 			int t2 = b ^ d;
@@ -452,10 +473,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x1 = (t2 ^ this._x3) ^ (this._x2 ^ (d | t1));
 		}
 
-		/**
-		* InvS2 - {12, 9,15, 4,11,14, 1, 2, 0, 3, 6,13, 5, 8,10, 7 } - 16 steps.
-		*/
-		private void Ib2(int a, int b, int c, int d)
+        /// <summary>
+        /// InvS2 - {12, 9,15, 4,11,14, 1, 2, 0, 3, 6,13, 5, 8,10, 7 } - 16 steps.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Ib2(int a, int b, int c, int d)
 		{
 			int t1 = b ^ d;
 			int t2 = ~t1;
@@ -473,10 +498,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x2 = (d & t11) ^ (t3 ^ t12);
 		}
 
-		/**
-		* S3 - { 0,15,11, 8,12, 9, 6, 3,13, 1, 2, 4,10, 7, 5,14 } - 16 terms.
-		*/
-		private void Sb3(int a, int b, int c, int d)
+        /// <summary>
+        /// S3 - { 0,15,11, 8,12, 9, 6, 3,13, 1, 2, 4,10, 7, 5,14 } - 16 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Sb3(int a, int b, int c, int d)
 		{
 			int t1 = a ^ b;
 			int t2 = a & c;
@@ -494,10 +523,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x3 = (b | d) ^ (t4 ^ t12);
 		}
 
-		/**
-		* InvS3 - { 0, 9,10, 7,11,14, 6,13, 3, 5,12, 2, 4, 8,15, 1 } - 15 terms
-		*/
-		private void Ib3(int a, int b, int c, int d)
+        /// <summary>
+        /// InvS3 - { 0, 9,10, 7,11,14, 6,13, 3, 5,12, 2, 4, 8,15, 1 } - 15 terms
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Ib3(int a, int b, int c, int d)
 		{
 			int t1 = a | b;
 			int t2 = b ^ c;
@@ -515,10 +548,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x1 = this._x3 ^ (this._x0 ^ t11);
 		}
 
-		/**
-		* S4 - { 1,15, 8, 3,12, 0,11, 6, 2, 5, 4,10, 9,14, 7,13 } - 15 terms.
-		*/
-		private void Sb4(int a, int b, int c, int d)
+        /// <summary>
+        /// S4 - { 1,15, 8, 3,12, 0,11, 6, 2, 5, 4,10, 9,14, 7,13 } - 15 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Sb4(int a, int b, int c, int d)
 		{
 			int t1 = a ^ d;
 			int t2 = d & t1;
@@ -535,10 +572,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x1 = (a ^ t3) ^ (t10 & this._x2);
 		}
 
-		/**
-		* InvS4 - { 5, 0, 8, 3,10, 9, 7,14, 2,12,11, 6, 4,15,13, 1 } - 15 terms.
-		*/
-		private void Ib4(int a, int b, int c, int d)
+        /// <summary>
+        /// InvS4 - { 5, 0, 8, 3,10, 9, 7,14, 2,12,11, 6, 4,15,13, 1 } - 15 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Ib4(int a, int b, int c, int d)
 		{
 			int t1 = c | d;
 			int t2 = a & t1;
@@ -555,10 +596,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x2 = (t3 & t11) ^ (this._x1 ^ t7);
 		}
 
-		/**
-		* S5 - {15, 5, 2,11, 4,10, 9,12, 0, 3,14, 8,13, 6, 7, 1 } - 16 terms.
-		*/
-		private void Sb5(int a, int b, int c, int d)
+        /// <summary>
+        /// S5 - {15, 5, 2,11, 4,10, 9,12, 0, 3,14, 8,13, 6, 7, 1 } - 16 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Sb5(int a, int b, int c, int d)
 		{
 			int t1 = ~a;
 			int t2 = a ^ b;
@@ -576,10 +621,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x3 = (b ^ t7) ^ (this._x1 & t12);
 		}
 
-		/**
-		* InvS5 - { 8,15, 2, 9, 4, 1,13,14,11, 6, 5, 3, 7,12,10, 0 } - 16 terms.
-		*/
-		private void Ib5(int a, int b, int c, int d)
+        /// <summary>
+        /// InvS5 - { 8,15, 2, 9, 4, 1,13,14,11, 6, 5, 3, 7,12,10, 0 } - 16 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Ib5(int a, int b, int c, int d)
 		{
 			int t1 = ~c;
 			int t2 = b & t1;
@@ -596,10 +645,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x2 = (b & t10) ^ (t4 | (a ^ c));
 		}
 
-		/**
-		* S6 - { 7, 2,12, 5, 8, 4, 6,11,14, 9, 1,15,13, 3,10, 0 } - 15 terms.
-		*/
-		private void Sb6(int a, int b, int c, int d)
+        /// <summary>
+        /// S6 - { 7, 2,12, 5, 8, 4, 6,11,14, 9, 1,15,13, 3,10, 0 } - 15 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Sb6(int a, int b, int c, int d)
 		{
 			int t1 = ~a;
 			int t2 = a ^ d;
@@ -616,10 +669,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x3 = (~t5) ^ (t3 & t11);
 		}
 
-		/**
-		* InvS6 - {15,10, 1,13, 5, 3, 6, 0, 4, 9,14, 7, 2,12, 8,11 } - 15 terms.
-		*/
-		private void Ib6(int a, int b, int c, int d)
+        /// <summary>
+        /// InvS6 - {15,10, 1,13, 5, 3, 6, 0, 4, 9,14, 7, 2,12, 8,11 } - 15 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Ib6(int a, int b, int c, int d)
 		{
 			int t1 = ~a;
 			int t2 = a ^ b;
@@ -636,10 +693,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x2 = (d & t1) ^ (t3 ^ t11);
 		}
 
-		/**
-		* S7 - { 1,13,15, 0,14, 8, 2,11, 7, 4,12,10, 9, 3, 5, 6 } - 16 terms.
-		*/
-		private void Sb7(int a, int b, int c, int d)
+        /// <summary>
+        /// S7 - { 1,13,15, 0,14, 8, 2,11, 7, 4,12,10, 9, 3, 5, 6 } - 16 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Sb7(int a, int b, int c, int d)
 		{
 			int t1 = b ^ c;
 			int t2 = c & t1;
@@ -657,10 +718,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x0 = (~t11) ^ (this._x3 & this._x2);
 		}
 
-		/**
-		* InvS7 - { 3, 0, 6,13, 9,14,15, 8, 5,12,11, 7,10, 1, 4, 2 } - 17 terms.
-		*/
-		private void Ib7(int a, int b, int c, int d)
+        /// <summary>
+        /// InvS7 - { 3, 0, 6,13, 9,14,15, 8, 5,12,11, 7,10, 1, 4, 2 } - 17 terms.
+        /// </summary>
+        /// <param name="a">A.</param>
+        /// <param name="b">The b.</param>
+        /// <param name="c">The c.</param>
+        /// <param name="d">The d.</param>
+        private void Ib7(int a, int b, int c, int d)
 		{
 			int t3 = c | (a & b);
 			int t4 = d & (a | b);
@@ -673,9 +738,9 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x2 = (t3 ^ this._x1) ^ (this._x0 ^ (a & this._x3));
 		}
 
-		/**
-		* Apply the linear transformation to the register set.
-		*/
+        /// <summary>
+        /// Apply the linear transformation to the register set.
+        /// </summary>
 		private void LT()
 		{
 			int x0 = RotateLeft(this._x0, 13);
@@ -689,9 +754,9 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x2 = RotateLeft(x2 ^ this._x3 ^ (this._x1 << 7), 22);
 		}
 
-		/**
-		* Apply the inverse of the linear transformation to the register set.
-		*/
+        /// <summary>
+        /// Apply the inverse of the linear transformation to the register set.
+        /// </summary>
 		private void InverseLT()
 		{
 			int x2 = RotateRight(this._x2, 22) ^ this._x3 ^ (this._x1 << 7);

+ 5 - 1
Renci.SshClient/Renci.SshNet/Security/Cryptography/Ciphers/TripleDesCipher.cs

@@ -8,14 +8,18 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
     /// <summary>
     /// Implements 3DES cipher algorithm.
     /// </summary>
-    public class TripleDesCipher : DesCipher
+    public sealed class TripleDesCipher : DesCipher
     {
         private int[] _encryptionKey1;
+
         private int[] _encryptionKey2;
+
         private int[] _encryptionKey3;
 
         private int[] _decryptionKey1;
+
         private int[] _decryptionKey2;
+
         private int[] _decryptionKey3;
 
         /// <summary>

+ 476 - 473
Renci.SshClient/Renci.SshNet/Security/Cryptography/Ciphers/TwofishCipher.cs

@@ -5,150 +5,150 @@ using System.Text;
 
 namespace Renci.SshNet.Security.Cryptography.Ciphers
 {
-	/// <summary>
-	/// Implements Twofish cipher algorithm
-	/// </summary>
-	public class TwofishCipher : BlockCipher
-	{
-		/// <summary>
-		/// Initializes a new instance of the <see cref="TwofishCipher"/> class.
-		/// </summary>
-		/// <param name="key">The key.</param>
-		/// <param name="mode">The mode.</param>
-		/// <param name="padding">The padding.</param>
-		/// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
-		/// <exception cref="ArgumentException">Keysize is not valid for this algorithm.</exception>
-		public TwofishCipher(byte[] key, CipherMode mode, CipherPadding padding)
-			: base(key, 16, mode, padding)
-		{
-			var keySize = key.Length * 8;
-
-			if (!(keySize == 128 || keySize == 192 || keySize == 256))
-				throw new ArgumentException(string.Format("KeySize '{0}' is not valid for this algorithm.", keySize));
-
-			//  TODO:   Refactor this algorithm
-
-			// calculate the MDS matrix
-			int[] m1 = new int[2];
-			int[] mX = new int[2];
-			int[] mY = new int[2];
-			int j;
-
-			for (int i = 0; i < MAX_KEY_BITS; i++)
-			{
-				j = P[0, i] & 0xff;
-				m1[0] = j;
-				mX[0] = Mx_X(j) & 0xff;
-				mY[0] = Mx_Y(j) & 0xff;
-
-				j = P[1, i] & 0xff;
-				m1[1] = j;
-				mX[1] = Mx_X(j) & 0xff;
-				mY[1] = Mx_Y(j) & 0xff;
-
-				gMDS0[i] = m1[P_00] | mX[P_00] << 8 | mY[P_00] << 16 | mY[P_00] << 24;
-
-				gMDS1[i] = mY[P_10] | mY[P_10] << 8 | mX[P_10] << 16 | m1[P_10] << 24;
-
-				gMDS2[i] = mX[P_20] | mY[P_20] << 8 | m1[P_20] << 16 | mY[P_20] << 24;
-
-				gMDS3[i] = mX[P_30] | m1[P_30] << 8 | mY[P_30] << 16 | mX[P_30] << 24;
-			}
-
-			this.k64Cnt = key.Length / 8; // pre-padded ?
-			this.SetKey(key);
-		}
-
-		/// <summary>
-		/// Encrypts the specified region of the input byte array and copies the encrypted data to the specified region of the output byte array.
-		/// </summary>
-		/// <param name="inputBuffer">The input data to encrypt.</param>
-		/// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
-		/// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
-		/// <param name="outputBuffer">The output to which to write encrypted data.</param>
-		/// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
-		/// <returns>
-		/// The number of bytes encrypted.
-		/// </returns>
-		public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
-		{
-			int x0 = BytesTo32Bits(inputBuffer, inputOffset) ^ gSubKeys[INPUT_WHITEN];
-			int x1 = BytesTo32Bits(inputBuffer, inputOffset + 4) ^ gSubKeys[INPUT_WHITEN + 1];
-			int x2 = BytesTo32Bits(inputBuffer, inputOffset + 8) ^ gSubKeys[INPUT_WHITEN + 2];
-			int x3 = BytesTo32Bits(inputBuffer, inputOffset + 12) ^ gSubKeys[INPUT_WHITEN + 3];
-
-			int k = ROUND_SUBKEYS;
-			int t0, t1;
-			for (int r = 0; r < ROUNDS; r += 2)
-			{
-				t0 = Fe32_0(x0);
-				t1 = Fe32_3(x1);
-				x2 ^= t0 + t1 + gSubKeys[k++];
-				x2 = (int)((uint)x2 >> 1) | x2 << 31;
-				x3 = (x3 << 1 | (int)((uint)x3 >> 31)) ^ (t0 + 2 * t1 + gSubKeys[k++]);
-
-				t0 = Fe32_0(x2);
-				t1 = Fe32_3(x3);
-				x0 ^= t0 + t1 + gSubKeys[k++];
-				x0 = (int)((uint)x0 >> 1) | x0 << 31;
-				x1 = (x1 << 1 | (int)((uint)x1 >> 31)) ^ (t0 + 2 * t1 + gSubKeys[k++]);
-			}
-
-			Bits32ToBytes(x2 ^ gSubKeys[OUTPUT_WHITEN], outputBuffer, outputOffset);
-			Bits32ToBytes(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], outputBuffer, outputOffset + 4);
-			Bits32ToBytes(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], outputBuffer, outputOffset + 8);
-			Bits32ToBytes(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], outputBuffer, outputOffset + 12);
-
-			return this.BlockSize;
-		}
-
-		/// <summary>
-		/// Decrypts the specified region of the input byte array and copies the decrypted data to the specified region of the output byte array.
-		/// </summary>
-		/// <param name="inputBuffer">The input data to decrypt.</param>
-		/// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
-		/// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
-		/// <param name="outputBuffer">The output to which to write decrypted data.</param>
-		/// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
-		/// <returns>
-		/// The number of bytes decrypted.
-		/// </returns>
-		public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
-		{
-			int x2 = BytesTo32Bits(inputBuffer, inputOffset) ^ gSubKeys[OUTPUT_WHITEN];
-			int x3 = BytesTo32Bits(inputBuffer, inputOffset + 4) ^ gSubKeys[OUTPUT_WHITEN + 1];
-			int x0 = BytesTo32Bits(inputBuffer, inputOffset + 8) ^ gSubKeys[OUTPUT_WHITEN + 2];
-			int x1 = BytesTo32Bits(inputBuffer, inputOffset + 12) ^ gSubKeys[OUTPUT_WHITEN + 3];
-
-			int k = ROUND_SUBKEYS + 2 * ROUNDS - 1;
-			int t0, t1;
-			for (int r = 0; r < ROUNDS; r += 2)
-			{
-				t0 = Fe32_0(x2);
-				t1 = Fe32_3(x3);
-				x1 ^= t0 + 2 * t1 + gSubKeys[k--];
-				x0 = (x0 << 1 | (int)((uint)x0 >> 31)) ^ (t0 + t1 + gSubKeys[k--]);
-				x1 = (int)((uint)x1 >> 1) | x1 << 31;
-
-				t0 = Fe32_0(x0);
-				t1 = Fe32_3(x1);
-				x3 ^= t0 + 2 * t1 + gSubKeys[k--];
-				x2 = (x2 << 1 | (int)((uint)x2 >> 31)) ^ (t0 + t1 + gSubKeys[k--]);
-				x3 = (int)((uint)x3 >> 1) | x3 << 31;
-			}
-
-			Bits32ToBytes(x0 ^ gSubKeys[INPUT_WHITEN], outputBuffer, outputOffset);
-			Bits32ToBytes(x1 ^ gSubKeys[INPUT_WHITEN + 1], outputBuffer, outputOffset + 4);
-			Bits32ToBytes(x2 ^ gSubKeys[INPUT_WHITEN + 2], outputBuffer, outputOffset + 8);
-			Bits32ToBytes(x3 ^ gSubKeys[INPUT_WHITEN + 3], outputBuffer, outputOffset + 12);
-
-			return this.BlockSize;
-		}
-
-		#region Static Definition Tables
-
-		private static readonly byte[,] P =  {
-		{  // p0
+    /// <summary>
+    /// Implements Twofish cipher algorithm
+    /// </summary>
+    public sealed class TwofishCipher : BlockCipher
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TwofishCipher"/> class.
+        /// </summary>
+        /// <param name="key">The key.</param>
+        /// <param name="mode">The mode.</param>
+        /// <param name="padding">The padding.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
+        /// <exception cref="ArgumentException">Keysize is not valid for this algorithm.</exception>
+        public TwofishCipher(byte[] key, CipherMode mode, CipherPadding padding)
+            : base(key, 16, mode, padding)
+        {
+            var keySize = key.Length * 8;
+
+            if (!(keySize == 128 || keySize == 192 || keySize == 256))
+                throw new ArgumentException(string.Format("KeySize '{0}' is not valid for this algorithm.", keySize));
+
+            //  TODO:   Refactor this algorithm
+
+            // calculate the MDS matrix
+            int[] m1 = new int[2];
+            int[] mX = new int[2];
+            int[] mY = new int[2];
+            int j;
+
+            for (int i = 0; i < MAX_KEY_BITS; i++)
+            {
+                j = P[0 + i] & 0xff;
+                m1[0] = j;
+                mX[0] = Mx_X(j) & 0xff;
+                mY[0] = Mx_Y(j) & 0xff;
+
+                j = P[(1 * 256) + i] & 0xff;
+                m1[1] = j;
+                mX[1] = Mx_X(j) & 0xff;
+                mY[1] = Mx_Y(j) & 0xff;
+
+                gMDS0[i] = m1[P_00] | mX[P_00] << 8 | mY[P_00] << 16 | mY[P_00] << 24;
+
+                gMDS1[i] = mY[P_10] | mY[P_10] << 8 | mX[P_10] << 16 | m1[P_10] << 24;
+
+                gMDS2[i] = mX[P_20] | mY[P_20] << 8 | m1[P_20] << 16 | mY[P_20] << 24;
+
+                gMDS3[i] = mX[P_30] | m1[P_30] << 8 | mY[P_30] << 16 | mX[P_30] << 24;
+            }
+
+            this.k64Cnt = key.Length / 8; // pre-padded ?
+            this.SetKey(key);
+        }
+
+        /// <summary>
+        /// Encrypts the specified region of the input byte array and copies the encrypted data to the specified region of the output byte array.
+        /// </summary>
+        /// <param name="inputBuffer">The input data to encrypt.</param>
+        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
+        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
+        /// <param name="outputBuffer">The output to which to write encrypted data.</param>
+        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
+        /// <returns>
+        /// The number of bytes encrypted.
+        /// </returns>
+        public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+        {
+            int x0 = BytesTo32Bits(inputBuffer, inputOffset) ^ gSubKeys[INPUT_WHITEN];
+            int x1 = BytesTo32Bits(inputBuffer, inputOffset + 4) ^ gSubKeys[INPUT_WHITEN + 1];
+            int x2 = BytesTo32Bits(inputBuffer, inputOffset + 8) ^ gSubKeys[INPUT_WHITEN + 2];
+            int x3 = BytesTo32Bits(inputBuffer, inputOffset + 12) ^ gSubKeys[INPUT_WHITEN + 3];
+
+            int k = ROUND_SUBKEYS;
+            int t0, t1;
+            for (int r = 0; r < ROUNDS; r += 2)
+            {
+                t0 = Fe32_0(gSBox, x0);
+                t1 = Fe32_3(gSBox, x1);
+                x2 ^= t0 + t1 + gSubKeys[k++];
+                x2 = (int)((uint)x2 >> 1) | x2 << 31;
+                x3 = (x3 << 1 | (int)((uint)x3 >> 31)) ^ (t0 + 2 * t1 + gSubKeys[k++]);
+
+                t0 = Fe32_0(gSBox, x2);
+                t1 = Fe32_3(gSBox, x3);
+                x0 ^= t0 + t1 + gSubKeys[k++];
+                x0 = (int)((uint)x0 >> 1) | x0 << 31;
+                x1 = (x1 << 1 | (int)((uint)x1 >> 31)) ^ (t0 + 2 * t1 + gSubKeys[k++]);
+            }
+
+            Bits32ToBytes(x2 ^ gSubKeys[OUTPUT_WHITEN], outputBuffer, outputOffset);
+            Bits32ToBytes(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], outputBuffer, outputOffset + 4);
+            Bits32ToBytes(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], outputBuffer, outputOffset + 8);
+            Bits32ToBytes(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], outputBuffer, outputOffset + 12);
+
+            return this.BlockSize;
+        }
+
+        /// <summary>
+        /// Decrypts the specified region of the input byte array and copies the decrypted data to the specified region of the output byte array.
+        /// </summary>
+        /// <param name="inputBuffer">The input data to decrypt.</param>
+        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
+        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
+        /// <param name="outputBuffer">The output to which to write decrypted data.</param>
+        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
+        /// <returns>
+        /// The number of bytes decrypted.
+        /// </returns>
+        public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+        {
+            int x2 = BytesTo32Bits(inputBuffer, inputOffset) ^ gSubKeys[OUTPUT_WHITEN];
+            int x3 = BytesTo32Bits(inputBuffer, inputOffset + 4) ^ gSubKeys[OUTPUT_WHITEN + 1];
+            int x0 = BytesTo32Bits(inputBuffer, inputOffset + 8) ^ gSubKeys[OUTPUT_WHITEN + 2];
+            int x1 = BytesTo32Bits(inputBuffer, inputOffset + 12) ^ gSubKeys[OUTPUT_WHITEN + 3];
+
+            int k = ROUND_SUBKEYS + 2 * ROUNDS - 1;
+            int t0, t1;
+            for (int r = 0; r < ROUNDS; r += 2)
+            {
+                t0 = Fe32_0(gSBox, x2);
+                t1 = Fe32_3(gSBox, x3);
+                x1 ^= t0 + 2 * t1 + gSubKeys[k--];
+                x0 = (x0 << 1 | (int)((uint)x0 >> 31)) ^ (t0 + t1 + gSubKeys[k--]);
+                x1 = (int)((uint)x1 >> 1) | x1 << 31;
+
+                t0 = Fe32_0(gSBox, x0);
+                t1 = Fe32_3(gSBox, x1);
+                x3 ^= t0 + 2 * t1 + gSubKeys[k--];
+                x2 = (x2 << 1 | (int)((uint)x2 >> 31)) ^ (t0 + t1 + gSubKeys[k--]);
+                x3 = (int)((uint)x3 >> 1) | x3 << 31;
+            }
+
+            Bits32ToBytes(x0 ^ gSubKeys[INPUT_WHITEN], outputBuffer, outputOffset);
+            Bits32ToBytes(x1 ^ gSubKeys[INPUT_WHITEN + 1], outputBuffer, outputOffset + 4);
+            Bits32ToBytes(x2 ^ gSubKeys[INPUT_WHITEN + 2], outputBuffer, outputOffset + 8);
+            Bits32ToBytes(x3 ^ gSubKeys[INPUT_WHITEN + 3], outputBuffer, outputOffset + 12);
+
+            return this.BlockSize;
+        }
+
+        #region Static Definition Tables
+
+        private static readonly byte[] P =  {
+        //{  // p0
 			(byte) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8,
 			(byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76,
 			(byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78,
@@ -212,8 +212,9 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			(byte) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0,
 			(byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00,
 			(byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42,
-			(byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0 },
-		{  // p1
+			(byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0,
+        //                                    },
+        //{  // p1
 			(byte) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4,
 			(byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8,
 			(byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B,
@@ -277,338 +278,340 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			(byte) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4,
 			(byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2,
 			(byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56,
-			(byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91  }
+			(byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91
+                                            //}
 		};
 
-		#endregion
+        #endregion
 
-		/**
+        /**
 		* Define the fixed p0/p1 permutations used in keyed S-box lookup.
 		* By changing the following constant definitions, the S-boxes will
 		* automatically Get changed in the Twofish engine.
 		*/
-		private const int P_00 = 1;
-		private const int P_01 = 0;
-		private const int P_02 = 0;
-		private const int P_03 = P_01 ^ 1;
-		private const int P_04 = 1;
-
-		private const int P_10 = 0;
-		private const int P_11 = 0;
-		private const int P_12 = 1;
-		private const int P_13 = P_11 ^ 1;
-		private const int P_14 = 0;
-
-		private const int P_20 = 1;
-		private const int P_21 = 1;
-		private const int P_22 = 0;
-		private const int P_23 = P_21 ^ 1;
-		private const int P_24 = 0;
-
-		private const int P_30 = 0;
-		private const int P_31 = 1;
-		private const int P_32 = 1;
-		private const int P_33 = P_31 ^ 1;
-		private const int P_34 = 1;
-
-		/* Primitive polynomial for GF(256) */
-		private const int GF256_FDBK = 0x169;
-		private const int GF256_FDBK_2 = GF256_FDBK / 2;
-		private const int GF256_FDBK_4 = GF256_FDBK / 4;
-
-		private const int RS_GF_FDBK = 0x14D; // field generator
-
-		//====================================
-		// Useful constants
-		//====================================
-
-		private const int ROUNDS = 16;
-		private const int MAX_ROUNDS = 16;  // bytes = 128 bits
-		private const int MAX_KEY_BITS = 256;
-
-		private const int INPUT_WHITEN = 0;
-		private const int OUTPUT_WHITEN = INPUT_WHITEN + 16 / 4; // 4
-		private const int ROUND_SUBKEYS = OUTPUT_WHITEN + 16 / 4;// 8
-
-		private const int TOTAL_SUBKEYS = ROUND_SUBKEYS + 2 * MAX_ROUNDS;// 40
-
-		private const int SK_STEP = 0x02020202;
-		private const int SK_BUMP = 0x01010101;
-		private const int SK_ROTL = 9;
-
-		private int[] gMDS0 = new int[MAX_KEY_BITS];
-		private int[] gMDS1 = new int[MAX_KEY_BITS];
-		private int[] gMDS2 = new int[MAX_KEY_BITS];
-		private int[] gMDS3 = new int[MAX_KEY_BITS];
-
-		/**
-		* gSubKeys[] and gSBox[] are eventually used in the
-		* encryption and decryption methods.
-		*/
-		private int[] gSubKeys;
-		private int[] gSBox;
-
-		private int k64Cnt;
-
-		private void SetKey(byte[] key)
-		{
-			int[] k32e = new int[MAX_KEY_BITS / 64]; // 4
-			int[] k32o = new int[MAX_KEY_BITS / 64]; // 4
-
-			int[] sBoxKeys = new int[MAX_KEY_BITS / 64]; // 4
-			gSubKeys = new int[TOTAL_SUBKEYS];
-
-			if (k64Cnt < 1)
-			{
-				throw new ArgumentException("Key size less than 64 bits");
-			}
-
-			if (k64Cnt > 4)
-			{
-				throw new ArgumentException("Key size larger than 256 bits");
-			}
-
-			/*
-			* k64Cnt is the number of 8 byte blocks (64 chunks)
-			* that are in the input key.  The input key is a
-			* maximum of 32 bytes ( 256 bits ), so the range
-			* for k64Cnt is 1..4
-			*/
-			for (int i = 0, p = 0; i < k64Cnt; i++)
-			{
-				p = i * 8;
-
-				k32e[i] = BytesTo32Bits(key, p);
-				k32o[i] = BytesTo32Bits(key, p + 4);
-
-				sBoxKeys[k64Cnt - 1 - i] = RS_MDS_Encode(k32e[i], k32o[i]);
-			}
-
-			int q, A, B;
-			for (int i = 0; i < TOTAL_SUBKEYS / 2; i++)
-			{
-				q = i * SK_STEP;
-				A = F32(q, k32e);
-				B = F32(q + SK_BUMP, k32o);
-				B = B << 8 | (int)((uint)B >> 24);
-				A += B;
-				gSubKeys[i * 2] = A;
-				A += B;
-				gSubKeys[i * 2 + 1] = A << SK_ROTL | (int)((uint)A >> (32 - SK_ROTL));
-			}
-
-			/*
-			* fully expand the table for speed
-			*/
-			int k0 = sBoxKeys[0];
-			int k1 = sBoxKeys[1];
-			int k2 = sBoxKeys[2];
-			int k3 = sBoxKeys[3];
-			int b0, b1, b2, b3;
-			gSBox = new int[4 * MAX_KEY_BITS];
-			for (int i = 0; i < MAX_KEY_BITS; i++)
-			{
-				b0 = b1 = b2 = b3 = i;
-				switch (k64Cnt & 3)
-				{
-					case 1:
-						gSBox[i * 2] = gMDS0[(P[P_01, b0] & 0xff) ^ M_b0(k0)];
-						gSBox[i * 2 + 1] = gMDS1[(P[P_11, b1] & 0xff) ^ M_b1(k0)];
-						gSBox[i * 2 + 0x200] = gMDS2[(P[P_21, b2] & 0xff) ^ M_b2(k0)];
-						gSBox[i * 2 + 0x201] = gMDS3[(P[P_31, b3] & 0xff) ^ M_b3(k0)];
-						break;
-					case 0: /* 256 bits of key */
-						b0 = (P[P_04, b0] & 0xff) ^ M_b0(k3);
-						b1 = (P[P_14, b1] & 0xff) ^ M_b1(k3);
-						b2 = (P[P_24, b2] & 0xff) ^ M_b2(k3);
-						b3 = (P[P_34, b3] & 0xff) ^ M_b3(k3);
-						goto case 3;
-					case 3:
-						b0 = (P[P_03, b0] & 0xff) ^ M_b0(k2);
-						b1 = (P[P_13, b1] & 0xff) ^ M_b1(k2);
-						b2 = (P[P_23, b2] & 0xff) ^ M_b2(k2);
-						b3 = (P[P_33, b3] & 0xff) ^ M_b3(k2);
-						goto case 2;
-					case 2:
-						gSBox[i * 2] = gMDS0[(P[P_01, (P[P_02, b0] & 0xff) ^ M_b0(k1)] & 0xff) ^ M_b0(k0)];
-						gSBox[i * 2 + 1] = gMDS1[(P[P_11, (P[P_12, b1] & 0xff) ^ M_b1(k1)] & 0xff) ^ M_b1(k0)];
-						gSBox[i * 2 + 0x200] = gMDS2[(P[P_21, (P[P_22, b2] & 0xff) ^ M_b2(k1)] & 0xff) ^ M_b2(k0)];
-						gSBox[i * 2 + 0x201] = gMDS3[(P[P_31, (P[P_32, b3] & 0xff) ^ M_b3(k1)] & 0xff) ^ M_b3(k0)];
-						break;
-				}
-			}
-
-			/*
-			* the function exits having setup the gSBox with the
-			* input key material.
-			*/
-		}
-
-		/*
-		* TODO:  This can be optimised and made cleaner by combining
-		* the functionality in this function and applying it appropriately
-		* to the creation of the subkeys during key setup.
-		*/
-		private int F32(int x, int[] k32)
-		{
-			int b0 = M_b0(x);
-			int b1 = M_b1(x);
-			int b2 = M_b2(x);
-			int b3 = M_b3(x);
-			int k0 = k32[0];
-			int k1 = k32[1];
-			int k2 = k32[2];
-			int k3 = k32[3];
-
-			int result = 0;
-			switch (k64Cnt & 3)
-			{
-				case 1:
-					result = gMDS0[(P[P_01, b0] & 0xff) ^ M_b0(k0)] ^
-							 gMDS1[(P[P_11, b1] & 0xff) ^ M_b1(k0)] ^
-							 gMDS2[(P[P_21, b2] & 0xff) ^ M_b2(k0)] ^
-							 gMDS3[(P[P_31, b3] & 0xff) ^ M_b3(k0)];
-					break;
-				case 0: /* 256 bits of key */
-					b0 = (P[P_04, b0] & 0xff) ^ M_b0(k3);
-					b1 = (P[P_14, b1] & 0xff) ^ M_b1(k3);
-					b2 = (P[P_24, b2] & 0xff) ^ M_b2(k3);
-					b3 = (P[P_34, b3] & 0xff) ^ M_b3(k3);
-					goto case 3;
-				case 3:
-					b0 = (P[P_03, b0] & 0xff) ^ M_b0(k2);
-					b1 = (P[P_13, b1] & 0xff) ^ M_b1(k2);
-					b2 = (P[P_23, b2] & 0xff) ^ M_b2(k2);
-					b3 = (P[P_33, b3] & 0xff) ^ M_b3(k2);
-					goto case 2;
-				case 2:
-					result =
-					gMDS0[(P[P_01, (P[P_02, b0] & 0xff) ^ M_b0(k1)] & 0xff) ^ M_b0(k0)] ^
-					gMDS1[(P[P_11, (P[P_12, b1] & 0xff) ^ M_b1(k1)] & 0xff) ^ M_b1(k0)] ^
-					gMDS2[(P[P_21, (P[P_22, b2] & 0xff) ^ M_b2(k1)] & 0xff) ^ M_b2(k0)] ^
-					gMDS3[(P[P_31, (P[P_32, b3] & 0xff) ^ M_b3(k1)] & 0xff) ^ M_b3(k0)];
-					break;
-			}
-			return result;
-		}
-
-		/**
-		* Use (12, 8) Reed-Solomon code over GF(256) to produce
-		* a key S-box 32-bit entity from 2 key material 32-bit
-		* entities.
-		*
-		* @param    k0 first 32-bit entity
-		* @param    k1 second 32-bit entity
-		* @return     Remainder polynomial Generated using RS code
-		*/
-		private int RS_MDS_Encode(int k0, int k1)
-		{
-			int r = k1;
-			for (int i = 0; i < 4; i++) // shift 1 byte at a time
-			{
-				r = RS_rem(r);
-			}
-			r ^= k0;
-			for (int i = 0; i < 4; i++)
-			{
-				r = RS_rem(r);
-			}
-
-			return r;
-		}
-
-		/**
-		* Reed-Solomon code parameters: (12,8) reversible code:
-		* <p>
-		* <pre>
-		* G(x) = x^4 + (a+1/a)x^3 + ax^2 + (a+1/a)x + 1
-		* </pre>
-		* where a = primitive root of field generator 0x14D
-		* </p>
-		*/
-		private int RS_rem(int x)
-		{
-			int b = (int)(((uint)x >> 24) & 0xff);
-			int g2 = ((b << 1) ^
-					((b & 0x80) != 0 ? RS_GF_FDBK : 0)) & 0xff;
-			int g3 = ((int)((uint)b >> 1) ^
-					((b & 0x01) != 0 ? (int)((uint)RS_GF_FDBK >> 1) : 0)) ^ g2;
-			return ((x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b);
-		}
-
-		private int LFSR1(int x)
-		{
-			return (x >> 1) ^
-					(((x & 0x01) != 0) ? GF256_FDBK_2 : 0);
-		}
-
-		private int LFSR2(int x)
-		{
-			return (x >> 2) ^
-					(((x & 0x02) != 0) ? GF256_FDBK_2 : 0) ^
-					(((x & 0x01) != 0) ? GF256_FDBK_4 : 0);
-		}
-
-		private int Mx_X(int x)
-		{
-			return x ^ LFSR2(x);
-		} // 5B
-
-		private int Mx_Y(int x)
-		{
-			return x ^ LFSR1(x) ^ LFSR2(x);
-		} // EF
-
-		private int M_b0(int x)
-		{
-			return x & 0xff;
-		}
-
-		private int M_b1(int x)
-		{
-			return (int)((uint)x >> 8) & 0xff;
-		}
-
-		private int M_b2(int x)
-		{
-			return (int)((uint)x >> 16) & 0xff;
-		}
-
-		private int M_b3(int x)
-		{
-			return (int)((uint)x >> 24) & 0xff;
-		}
-
-		private int Fe32_0(int x)
-		{
-			return gSBox[0x000 + 2 * (x & 0xff)] ^
-				gSBox[0x001 + 2 * ((int)((uint)x >> 8) & 0xff)] ^
-				gSBox[0x200 + 2 * ((int)((uint)x >> 16) & 0xff)] ^
-				gSBox[0x201 + 2 * ((int)((uint)x >> 24) & 0xff)];
-		}
-
-		private int Fe32_3(int x)
-		{
-			return gSBox[0x000 + 2 * ((int)((uint)x >> 24) & 0xff)] ^
-				gSBox[0x001 + 2 * (x & 0xff)] ^
-				gSBox[0x200 + 2 * ((int)((uint)x >> 8) & 0xff)] ^
-				gSBox[0x201 + 2 * ((int)((uint)x >> 16) & 0xff)];
-		}
-
-		private int BytesTo32Bits(byte[] b, int p)
-		{
-			return ((b[p] & 0xff)) |
-				((b[p + 1] & 0xff) << 8) |
-				((b[p + 2] & 0xff) << 16) |
-				((b[p + 3] & 0xff) << 24);
-		}
-
-		private void Bits32ToBytes(int inData, byte[] b, int offset)
-		{
-			b[offset] = (byte)inData;
-			b[offset + 1] = (byte)(inData >> 8);
-			b[offset + 2] = (byte)(inData >> 16);
-			b[offset + 3] = (byte)(inData >> 24);
-		}
-	}
+        private const int P_00 = 1;
+        private const int P_01 = 0;
+        private const int P_02 = 0;
+        private const int P_03 = P_01 ^ 1;
+        private const int P_04 = 1;
+
+        private const int P_10 = 0;
+        private const int P_11 = 0;
+        private const int P_12 = 1;
+        private const int P_13 = P_11 ^ 1;
+        private const int P_14 = 0;
+
+        private const int P_20 = 1;
+        private const int P_21 = 1;
+        private const int P_22 = 0;
+        private const int P_23 = P_21 ^ 1;
+        private const int P_24 = 0;
+
+        private const int P_30 = 0;
+        private const int P_31 = 1;
+        private const int P_32 = 1;
+        private const int P_33 = P_31 ^ 1;
+        private const int P_34 = 1;
+
+        /* Primitive polynomial for GF(256) */
+        private const int GF256_FDBK = 0x169;
+        private const int GF256_FDBK_2 = GF256_FDBK / 2;
+        private const int GF256_FDBK_4 = GF256_FDBK / 4;
+
+        private const int RS_GF_FDBK = 0x14D; // field generator
+
+        //====================================
+        // Useful constants
+        //====================================
+
+        private const int ROUNDS = 16;
+        private const int MAX_ROUNDS = 16;  // bytes = 128 bits
+        private const int MAX_KEY_BITS = 256;
+
+        private const int INPUT_WHITEN = 0;
+        private const int OUTPUT_WHITEN = INPUT_WHITEN + 16 / 4; // 4
+        private const int ROUND_SUBKEYS = OUTPUT_WHITEN + 16 / 4;// 8
+
+        private const int TOTAL_SUBKEYS = ROUND_SUBKEYS + 2 * MAX_ROUNDS;// 40
+
+        private const int SK_STEP = 0x02020202;
+        private const int SK_BUMP = 0x01010101;
+        private const int SK_ROTL = 9;
+
+        private int[] gMDS0 = new int[MAX_KEY_BITS];
+        private int[] gMDS1 = new int[MAX_KEY_BITS];
+        private int[] gMDS2 = new int[MAX_KEY_BITS];
+        private int[] gMDS3 = new int[MAX_KEY_BITS];
+
+        /**
+        * gSubKeys[] and gSBox[] are eventually used in the
+        * encryption and decryption methods.
+        */
+        private int[] gSubKeys;
+        private int[] gSBox;
+
+        private int k64Cnt;
+
+        private void SetKey(byte[] key)
+        {
+            int[] k32e = new int[MAX_KEY_BITS / 64]; // 4
+            int[] k32o = new int[MAX_KEY_BITS / 64]; // 4
+
+            int[] sBoxKeys = new int[MAX_KEY_BITS / 64]; // 4
+            gSubKeys = new int[TOTAL_SUBKEYS];
+
+            if (k64Cnt < 1)
+            {
+                throw new ArgumentException("Key size less than 64 bits");
+            }
+
+            if (k64Cnt > 4)
+            {
+                throw new ArgumentException("Key size larger than 256 bits");
+            }
+
+            /*
+            * k64Cnt is the number of 8 byte blocks (64 chunks)
+            * that are in the input key.  The input key is a
+            * maximum of 32 bytes ( 256 bits ), so the range
+            * for k64Cnt is 1..4
+            */
+            for (int i = 0, p = 0; i < k64Cnt; i++)
+            {
+                p = i * 8;
+
+                k32e[i] = BytesTo32Bits(key, p);
+                k32o[i] = BytesTo32Bits(key, p + 4);
+
+                sBoxKeys[k64Cnt - 1 - i] = RS_MDS_Encode(k32e[i], k32o[i]);
+            }
+
+            int q, A, B;
+            for (int i = 0; i < TOTAL_SUBKEYS / 2; i++)
+            {
+                q = i * SK_STEP;
+                A = F32(q, k32e);
+                B = F32(q + SK_BUMP, k32o);
+                B = B << 8 | (int)((uint)B >> 24);
+                A += B;
+                gSubKeys[i * 2] = A;
+                A += B;
+                gSubKeys[i * 2 + 1] = A << SK_ROTL | (int)((uint)A >> (32 - SK_ROTL));
+            }
+
+            /*
+            * fully expand the table for speed
+            */
+            int k0 = sBoxKeys[0];
+            int k1 = sBoxKeys[1];
+            int k2 = sBoxKeys[2];
+            int k3 = sBoxKeys[3];
+            int b0, b1, b2, b3;
+            gSBox = new int[4 * MAX_KEY_BITS];
+            for (int i = 0; i < MAX_KEY_BITS; i++)
+            {
+                b0 = b1 = b2 = b3 = i;
+                switch (k64Cnt & 3)
+                {
+                    case 1:
+                        gSBox[i * 2] = gMDS0[(P[P_01 * 256 + b0] & 0xff) ^ M_b0(k0)];
+                        gSBox[i * 2 + 1] = gMDS1[(P[P_11 * 256 + b1] & 0xff) ^ M_b1(k0)];
+                        gSBox[i * 2 + 0x200] = gMDS2[(P[P_21 * 256 + b2] & 0xff) ^ M_b2(k0)];
+                        gSBox[i * 2 + 0x201] = gMDS3[(P[P_31 * 256 + b3] & 0xff) ^ M_b3(k0)];
+                        break;
+                    case 0: /* 256 bits of key */
+                        b0 = (P[P_04 * 256 + b0] & 0xff) ^ M_b0(k3);
+                        b1 = (P[P_14 * 256 + b1] & 0xff) ^ M_b1(k3);
+                        b2 = (P[P_24 * 256 + b2] & 0xff) ^ M_b2(k3);
+                        b3 = (P[P_34 * 256 + b3] & 0xff) ^ M_b3(k3);
+                        goto case 3;
+                    case 3:
+                        b0 = (P[P_03 * 256 + b0] & 0xff) ^ M_b0(k2);
+                        b1 = (P[P_13 * 256 + b1] & 0xff) ^ M_b1(k2);
+                        b2 = (P[P_23 * 256 + b2] & 0xff) ^ M_b2(k2);
+                        b3 = (P[P_33 * 256 + b3] & 0xff) ^ M_b3(k2);
+                        goto case 2;
+                    case 2:
+                        gSBox[i * 2] = gMDS0[(P[P_01 * 256 + (P[P_02 * 256 + b0] & 0xff) ^ M_b0(k1)] & 0xff) ^ M_b0(k0)];
+                        gSBox[i * 2 + 1] = gMDS1[(P[P_11 * 256 + (P[P_12 * 256 + b1] & 0xff) ^ M_b1(k1)] & 0xff) ^ M_b1(k0)];
+                        gSBox[i * 2 + 0x200] = gMDS2[(P[P_21 * 256 + (P[P_22 * 256 + b2] & 0xff) ^ M_b2(k1)] & 0xff) ^ M_b2(k0)];
+                        gSBox[i * 2 + 0x201] = gMDS3[(P[P_31 * 256 + (P[P_32 * 256 + b3] & 0xff) ^ M_b3(k1)] & 0xff) ^ M_b3(k0)];
+                        break;
+                }
+            }
+
+            /*
+            * the function exits having setup the gSBox with the
+            * input key material.
+            */
+        }
+
+        /*
+        * TODO:  This can be optimised and made cleaner by combining
+        * the functionality in this function and applying it appropriately
+        * to the creation of the subkeys during key setup.
+        */
+        private int F32(int x, int[] k32)
+        {
+            int b0 = M_b0(x);
+            int b1 = M_b1(x);
+            int b2 = M_b2(x);
+            int b3 = M_b3(x);
+            int k0 = k32[0];
+            int k1 = k32[1];
+            int k2 = k32[2];
+            int k3 = k32[3];
+
+            int result = 0;
+            switch (k64Cnt & 3)
+            {
+                case 1:
+                    result = gMDS0[(P[P_01 * 256 + b0] & 0xff) ^ M_b0(k0)] ^
+                             gMDS1[(P[P_11 * 256 + b1] & 0xff) ^ M_b1(k0)] ^
+                             gMDS2[(P[P_21 * 256 + b2] & 0xff) ^ M_b2(k0)] ^
+                             gMDS3[(P[P_31 * 256 + b3] & 0xff) ^ M_b3(k0)];
+                    break;
+                case 0: /* 256 bits of key */
+                    b0 = (P[P_04 * 256 + b0] & 0xff) ^ M_b0(k3);
+                    b1 = (P[P_14 * 256 + b1] & 0xff) ^ M_b1(k3);
+                    b2 = (P[P_24 * 256 + b2] & 0xff) ^ M_b2(k3);
+                    b3 = (P[P_34 * 256 + b3] & 0xff) ^ M_b3(k3);
+                    goto case 3;
+                case 3:
+                    b0 = (P[P_03 * 256 + b0] & 0xff) ^ M_b0(k2);
+                    b1 = (P[P_13 * 256 + b1] & 0xff) ^ M_b1(k2);
+                    b2 = (P[P_23 * 256 + b2] & 0xff) ^ M_b2(k2);
+                    b3 = (P[P_33 * 256 + b3] & 0xff) ^ M_b3(k2);
+                    goto case 2;
+                case 2:
+                    result =
+                    gMDS0[(P[P_01 * 256 + (P[P_02 * 256 + b0] & 0xff) ^ M_b0(k1)] & 0xff) ^ M_b0(k0)] ^
+                    gMDS1[(P[P_11 * 256 + (P[P_12 * 256 + b1] & 0xff) ^ M_b1(k1)] & 0xff) ^ M_b1(k0)] ^
+                    gMDS2[(P[P_21 * 256 + (P[P_22 * 256 + b2] & 0xff) ^ M_b2(k1)] & 0xff) ^ M_b2(k0)] ^
+                    gMDS3[(P[P_31 * 256 + (P[P_32 * 256 + b3] & 0xff) ^ M_b3(k1)] & 0xff) ^ M_b3(k0)];
+                    break;
+            }
+            return result;
+        }
+
+        /**
+        * Use (12, 8) Reed-Solomon code over GF(256) to produce
+        * a key S-box 32-bit entity from 2 key material 32-bit
+        * entities.
+        *
+        * @param    k0 first 32-bit entity
+        * @param    k1 second 32-bit entity
+        * @return     Remainder polynomial Generated using RS code
+        */
+        private static int RS_MDS_Encode(int k0, int k1)
+        {
+            int r = k1;
+            // shift 1 byte at a time
+            r = RS_rem(r);
+            r = RS_rem(r);
+            r = RS_rem(r);
+            r = RS_rem(r);
+            r ^= k0;
+            r = RS_rem(r);
+            r = RS_rem(r);
+            r = RS_rem(r);
+            r = RS_rem(r);
+
+            return r;
+        }
+
+        /**
+        * Reed-Solomon code parameters: (12,8) reversible code:
+        * <p>
+        * <pre>
+        * G(x) = x^4 + (a+1/a)x^3 + ax^2 + (a+1/a)x + 1
+        * </pre>
+        * where a = primitive root of field generator 0x14D
+        * </p>
+        */
+        private static int RS_rem(int x)
+        {
+            int b = (int)(((uint)x >> 24) & 0xff);
+            int g2 = ((b << 1) ^
+                    ((b & 0x80) != 0 ? RS_GF_FDBK : 0)) & 0xff;
+            int g3 = ((int)((uint)b >> 1) ^
+                    ((b & 0x01) != 0 ? (int)((uint)RS_GF_FDBK >> 1) : 0)) ^ g2;
+            return ((x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b);
+        }
+
+        private static int LFSR1(int x)
+        {
+            return (x >> 1) ^
+                    (((x & 0x01) != 0) ? GF256_FDBK_2 : 0);
+        }
+
+        private static int LFSR2(int x)
+        {
+            return (x >> 2) ^
+                    (((x & 0x02) != 0) ? GF256_FDBK_2 : 0) ^
+                    (((x & 0x01) != 0) ? GF256_FDBK_4 : 0);
+        }
+
+        private static int Mx_X(int x)
+        {
+            return x ^ LFSR2(x);
+        } // 5B
+
+        private static int Mx_Y(int x)
+        {
+            return x ^ LFSR1(x) ^ LFSR2(x);
+        } // EF
+
+        private static int M_b0(int x)
+        {
+            return x & 0xff;
+        }
+
+        private static int M_b1(int x)
+        {
+            return (int)((uint)x >> 8) & 0xff;
+        }
+
+        private static int M_b2(int x)
+        {
+            return (int)((uint)x >> 16) & 0xff;
+        }
+
+        private static int M_b3(int x)
+        {
+            return (int)((uint)x >> 24) & 0xff;
+        }
+
+        private static int Fe32_0(int[] gSBox1, int x)
+        {
+            return gSBox1[0x000 + 2 * (x & 0xff)] ^
+                gSBox1[0x001 + 2 * ((int)((uint)x >> 8) & 0xff)] ^
+                gSBox1[0x200 + 2 * ((int)((uint)x >> 16) & 0xff)] ^
+                gSBox1[0x201 + 2 * ((int)((uint)x >> 24) & 0xff)];
+        }
+
+        private static int Fe32_3(int[] gSBox1, int x)
+        {
+            return gSBox1[0x000 + 2 * ((int)((uint)x >> 24) & 0xff)] ^
+                gSBox1[0x001 + 2 * (x & 0xff)] ^
+                gSBox1[0x200 + 2 * ((int)((uint)x >> 8) & 0xff)] ^
+                gSBox1[0x201 + 2 * ((int)((uint)x >> 16) & 0xff)];
+        }
+
+        private static int BytesTo32Bits(byte[] b, int p)
+        {
+            return ((b[p] & 0xff)) |
+                ((b[p + 1] & 0xff) << 8) |
+                ((b[p + 2] & 0xff) << 16) |
+                ((b[p + 3] & 0xff) << 24);
+        }
+
+        private static void Bits32ToBytes(int inData, byte[] b, int offset)
+        {
+            b[offset] = (byte)inData;
+            b[offset + 1] = (byte)(inData >> 8);
+            b[offset + 2] = (byte)(inData >> 16);
+            b[offset + 3] = (byte)(inData >> 24);
+        }
+    }
 }

+ 12 - 10
Renci.SshClient/Renci.SshNet/Security/Cryptography/Hashes/MD5Hash.cs

@@ -9,7 +9,7 @@ namespace Renci.SshNet.Security.Cryptography
     /// <summary>
     /// MD5 algorithm implementation
     /// </summary>
-    public class MD5Hash : HashAlgorithm
+    public sealed class MD5Hash : HashAlgorithm
     {
         private byte[] _buffer = new byte[4];
         private int _bufferOffset;
@@ -170,9 +170,13 @@ namespace Renci.SshNet.Security.Cryptography
 
         private void InternalInitialize()
         {
+            var i = 0;
             this._byteCount = 0;
             this._bufferOffset = 0;
-            Array.Clear(this._buffer, 0, this._buffer.Length);
+            for (i = 0; i < 4; i++)
+            {
+                this._buffer[i] = 0;
+            }
 
             H1 = unchecked((int)0x67452301);
             H2 = unchecked((int)0xefcdab89);
@@ -180,8 +184,7 @@ namespace Renci.SshNet.Security.Cryptography
             H4 = unchecked((int)0x10325476);
 
             this._offset = 0;
-
-            for (int i = 0; i != this._hashValue.Length; i++)
+            for (i = 0; i != this._hashValue.Length; i++)
             {
                 this._hashValue[i] = 0;
             }
@@ -254,7 +257,7 @@ namespace Renci.SshNet.Security.Cryptography
         /*
         * rotate int x left n bits.
         */
-        private int RotateLeft(int x, int n)
+        private static int RotateLeft(int x, int n)
         {
             return (x << n) | (int)((uint)x >> (32 - n));
         }
@@ -262,22 +265,22 @@ namespace Renci.SshNet.Security.Cryptography
         /*
         * F, G, H and I are the basic MD5 functions.
         */
-        private int F(int u, int v, int w)
+        private static int F(int u, int v, int w)
         {
             return (u & v) | (~u & w);
         }
 
-        private int G(int u, int v, int w)
+        private static int G(int u, int v, int w)
         {
             return (u & w) | (v & ~w);
         }
 
-        private int H(int u, int v, int w)
+        private static int H(int u, int v, int w)
         {
             return u ^ v ^ w;
         }
 
-        private int K(int u, int v, int w)
+        private static int K(int u, int v, int w)
         {
             return v ^ (u | ~w);
         }
@@ -383,6 +386,5 @@ namespace Renci.SshNet.Security.Cryptography
                 this._hashValue[i] = 0;
             }
         }
-
     }
 }

+ 194 - 185
Renci.SshClient/Renci.SshNet/Security/Cryptography/Hashes/RIPEMD160Hash.cs

@@ -9,7 +9,7 @@ namespace Renci.SshNet.Security.Cryptography
     /// <summary>
     /// 
     /// </summary>
-    public class RIPEMD160Hash : HashAlgorithm
+    public sealed class RIPEMD160Hash : HashAlgorithm
     {
         private const int DIGEST_SIZE = 20;
 
@@ -85,7 +85,7 @@ namespace Renci.SshNet.Security.Cryptography
             //
             // fill the current word
             //
-            while ((_bufferOffset != 0) && (cbSize > 0))
+            while ((this._bufferOffset != 0) && (cbSize > 0))
             {
                 this.Update(array[ibStart]);
                 ibStart++;
@@ -95,13 +95,13 @@ namespace Renci.SshNet.Security.Cryptography
             //
             // process whole words.
             //
-            while (cbSize > _buffer.Length)
+            while (cbSize > this._buffer.Length)
             {
                 this.ProcessWord(array, ibStart);
 
-                ibStart += _buffer.Length;
-                cbSize -= _buffer.Length;
-                _byteCount += _buffer.Length;
+                ibStart += this._buffer.Length;
+                cbSize -= this._buffer.Length;
+                this._byteCount += this._buffer.Length;
             }
 
             //
@@ -119,7 +119,7 @@ namespace Renci.SshNet.Security.Cryptography
         protected override byte[] HashFinal()
         {
             var output = new byte[DIGEST_SIZE];
-            long bitLength = (_byteCount << 3);
+            long bitLength = (this._byteCount << 3);
 
             //
             // add the pad bytes.
@@ -142,11 +142,17 @@ namespace Renci.SshNet.Security.Cryptography
             return output;
         }
 
+        /// <summary>
+        /// Initializes an implementation of the <see cref="T:System.Security.Cryptography.HashAlgorithm" /> class.
+        /// </summary>
         public override void Initialize()
         {
             this.InternalInitialize();
         }
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RIPEMD160Hash" /> class.
+        /// </summary>
         public RIPEMD160Hash()
         {
             this._buffer = new byte[4];
@@ -155,10 +161,10 @@ namespace Renci.SshNet.Security.Cryptography
 
         private void ProcessWord(byte[] input, int inOff)
         {
-            X[_offset++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8)
+            this.X[this._offset++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8)
                 | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24);
 
-            if (_offset == 16)
+            if (this._offset == 16)
             {
                 ProcessBlock();
             }
@@ -166,13 +172,13 @@ namespace Renci.SshNet.Security.Cryptography
 
         private void ProcessLength(long bitLength)
         {
-            if (_offset > 14)
+            if (this._offset > 14)
             {
                 ProcessBlock();
             }
 
-            X[14] = (int)(bitLength & 0xffffffff);
-            X[15] = (int)((ulong)bitLength >> 32);
+            this.X[14] = (int)(bitLength & 0xffffffff);
+            this.X[15] = (int)((ulong)bitLength >> 32);
         }
 
         private void UnpackWord(int word, byte[] outBytes, int outOff)
@@ -185,15 +191,15 @@ namespace Renci.SshNet.Security.Cryptography
 
         private void Update(byte input)
         {
-            _buffer[_bufferOffset++] = input;
+            this._buffer[this._bufferOffset++] = input;
 
-            if (_bufferOffset == _buffer.Length)
+            if (this._bufferOffset == this._buffer.Length)
             {
-                ProcessWord(_buffer, 0);
-                _bufferOffset = 0;
+                ProcessWord(this._buffer, 0);
+                this._bufferOffset = 0;
             }
 
-            _byteCount++;
+            this._byteCount++;
         }
 
         /// <summary>
@@ -201,9 +207,12 @@ namespace Renci.SshNet.Security.Cryptography
         /// </summary>
         private void InternalInitialize()
         {
-            _byteCount = 0;
-            _bufferOffset = 0;
-            Array.Clear(_buffer, 0, _buffer.Length);
+            this._byteCount = 0;
+            this._bufferOffset = 0;
+            for (int i = 0; i < _buffer.Length; i++)
+            {
+                this._buffer[i] = 0;
+            }
 
             H0 = unchecked((int)0x67452301);
             H1 = unchecked((int)0xefcdab89);
@@ -211,11 +220,11 @@ namespace Renci.SshNet.Security.Cryptography
             H3 = unchecked((int)0x10325476);
             H4 = unchecked((int)0xc3d2e1f0);
 
-            _offset = 0;
+            this._offset = 0;
 
             for (int i = 0; i != X.Length; i++)
             {
-                X[i] = 0;
+                this.X[i] = 0;
             }
         }
 
@@ -302,196 +311,196 @@ namespace Renci.SshNet.Security.Cryptography
             // Rounds 1 - 16
             //
             // left
-            a = RL(a + F1(b, c, d) + X[0], 11) + e; c = RL(c, 10);
-            e = RL(e + F1(a, b, c) + X[1], 14) + d; b = RL(b, 10);
-            d = RL(d + F1(e, a, b) + X[2], 15) + c; a = RL(a, 10);
-            c = RL(c + F1(d, e, a) + X[3], 12) + b; e = RL(e, 10);
-            b = RL(b + F1(c, d, e) + X[4], 5) + a; d = RL(d, 10);
-            a = RL(a + F1(b, c, d) + X[5], 8) + e; c = RL(c, 10);
-            e = RL(e + F1(a, b, c) + X[6], 7) + d; b = RL(b, 10);
-            d = RL(d + F1(e, a, b) + X[7], 9) + c; a = RL(a, 10);
-            c = RL(c + F1(d, e, a) + X[8], 11) + b; e = RL(e, 10);
-            b = RL(b + F1(c, d, e) + X[9], 13) + a; d = RL(d, 10);
-            a = RL(a + F1(b, c, d) + X[10], 14) + e; c = RL(c, 10);
-            e = RL(e + F1(a, b, c) + X[11], 15) + d; b = RL(b, 10);
-            d = RL(d + F1(e, a, b) + X[12], 6) + c; a = RL(a, 10);
-            c = RL(c + F1(d, e, a) + X[13], 7) + b; e = RL(e, 10);
-            b = RL(b + F1(c, d, e) + X[14], 9) + a; d = RL(d, 10);
-            a = RL(a + F1(b, c, d) + X[15], 8) + e; c = RL(c, 10);
+            a = RL(a + F1(b, c, d) + this.X[0], 11) + e; c = RL(c, 10);
+            e = RL(e + F1(a, b, c) + this.X[1], 14) + d; b = RL(b, 10);
+            d = RL(d + F1(e, a, b) + this.X[2], 15) + c; a = RL(a, 10);
+            c = RL(c + F1(d, e, a) + this.X[3], 12) + b; e = RL(e, 10);
+            b = RL(b + F1(c, d, e) + this.X[4], 5) + a; d = RL(d, 10);
+            a = RL(a + F1(b, c, d) + this.X[5], 8) + e; c = RL(c, 10);
+            e = RL(e + F1(a, b, c) + this.X[6], 7) + d; b = RL(b, 10);
+            d = RL(d + F1(e, a, b) + this.X[7], 9) + c; a = RL(a, 10);
+            c = RL(c + F1(d, e, a) + this.X[8], 11) + b; e = RL(e, 10);
+            b = RL(b + F1(c, d, e) + this.X[9], 13) + a; d = RL(d, 10);
+            a = RL(a + F1(b, c, d) + this.X[10], 14) + e; c = RL(c, 10);
+            e = RL(e + F1(a, b, c) + this.X[11], 15) + d; b = RL(b, 10);
+            d = RL(d + F1(e, a, b) + this.X[12], 6) + c; a = RL(a, 10);
+            c = RL(c + F1(d, e, a) + this.X[13], 7) + b; e = RL(e, 10);
+            b = RL(b + F1(c, d, e) + this.X[14], 9) + a; d = RL(d, 10);
+            a = RL(a + F1(b, c, d) + this.X[15], 8) + e; c = RL(c, 10);
 
             // right
-            aa = RL(aa + F5(bb, cc, dd) + X[5] + unchecked((int)0x50a28be6), 8) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F5(aa, bb, cc) + X[14] + unchecked((int)0x50a28be6), 9) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F5(ee, aa, bb) + X[7] + unchecked((int)0x50a28be6), 9) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F5(dd, ee, aa) + X[0] + unchecked((int)0x50a28be6), 11) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F5(cc, dd, ee) + X[9] + unchecked((int)0x50a28be6), 13) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F5(bb, cc, dd) + X[2] + unchecked((int)0x50a28be6), 15) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F5(aa, bb, cc) + X[11] + unchecked((int)0x50a28be6), 15) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F5(ee, aa, bb) + X[4] + unchecked((int)0x50a28be6), 5) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F5(dd, ee, aa) + X[13] + unchecked((int)0x50a28be6), 7) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F5(cc, dd, ee) + X[6] + unchecked((int)0x50a28be6), 7) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F5(bb, cc, dd) + X[15] + unchecked((int)0x50a28be6), 8) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F5(aa, bb, cc) + X[8] + unchecked((int)0x50a28be6), 11) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F5(ee, aa, bb) + X[1] + unchecked((int)0x50a28be6), 14) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F5(dd, ee, aa) + X[10] + unchecked((int)0x50a28be6), 14) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F5(cc, dd, ee) + X[3] + unchecked((int)0x50a28be6), 12) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F5(bb, cc, dd) + X[12] + unchecked((int)0x50a28be6), 6) + ee; cc = RL(cc, 10);
+            aa = RL(aa + F5(bb, cc, dd) + this.X[5] + unchecked((int)0x50a28be6), 8) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F5(aa, bb, cc) + this.X[14] + unchecked((int)0x50a28be6), 9) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F5(ee, aa, bb) + this.X[7] + unchecked((int)0x50a28be6), 9) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F5(dd, ee, aa) + this.X[0] + unchecked((int)0x50a28be6), 11) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F5(cc, dd, ee) + this.X[9] + unchecked((int)0x50a28be6), 13) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F5(bb, cc, dd) + this.X[2] + unchecked((int)0x50a28be6), 15) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F5(aa, bb, cc) + this.X[11] + unchecked((int)0x50a28be6), 15) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F5(ee, aa, bb) + this.X[4] + unchecked((int)0x50a28be6), 5) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F5(dd, ee, aa) + this.X[13] + unchecked((int)0x50a28be6), 7) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F5(cc, dd, ee) + this.X[6] + unchecked((int)0x50a28be6), 7) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F5(bb, cc, dd) + this.X[15] + unchecked((int)0x50a28be6), 8) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F5(aa, bb, cc) + this.X[8] + unchecked((int)0x50a28be6), 11) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F5(ee, aa, bb) + this.X[1] + unchecked((int)0x50a28be6), 14) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F5(dd, ee, aa) + this.X[10] + unchecked((int)0x50a28be6), 14) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F5(cc, dd, ee) + this.X[3] + unchecked((int)0x50a28be6), 12) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F5(bb, cc, dd) + this.X[12] + unchecked((int)0x50a28be6), 6) + ee; cc = RL(cc, 10);
 
             //
             // Rounds 16-31
             //
             // left
-            e = RL(e + F2(a, b, c) + X[7] + unchecked((int)0x5a827999), 7) + d; b = RL(b, 10);
-            d = RL(d + F2(e, a, b) + X[4] + unchecked((int)0x5a827999), 6) + c; a = RL(a, 10);
-            c = RL(c + F2(d, e, a) + X[13] + unchecked((int)0x5a827999), 8) + b; e = RL(e, 10);
-            b = RL(b + F2(c, d, e) + X[1] + unchecked((int)0x5a827999), 13) + a; d = RL(d, 10);
-            a = RL(a + F2(b, c, d) + X[10] + unchecked((int)0x5a827999), 11) + e; c = RL(c, 10);
-            e = RL(e + F2(a, b, c) + X[6] + unchecked((int)0x5a827999), 9) + d; b = RL(b, 10);
-            d = RL(d + F2(e, a, b) + X[15] + unchecked((int)0x5a827999), 7) + c; a = RL(a, 10);
-            c = RL(c + F2(d, e, a) + X[3] + unchecked((int)0x5a827999), 15) + b; e = RL(e, 10);
-            b = RL(b + F2(c, d, e) + X[12] + unchecked((int)0x5a827999), 7) + a; d = RL(d, 10);
-            a = RL(a + F2(b, c, d) + X[0] + unchecked((int)0x5a827999), 12) + e; c = RL(c, 10);
-            e = RL(e + F2(a, b, c) + X[9] + unchecked((int)0x5a827999), 15) + d; b = RL(b, 10);
-            d = RL(d + F2(e, a, b) + X[5] + unchecked((int)0x5a827999), 9) + c; a = RL(a, 10);
-            c = RL(c + F2(d, e, a) + X[2] + unchecked((int)0x5a827999), 11) + b; e = RL(e, 10);
-            b = RL(b + F2(c, d, e) + X[14] + unchecked((int)0x5a827999), 7) + a; d = RL(d, 10);
-            a = RL(a + F2(b, c, d) + X[11] + unchecked((int)0x5a827999), 13) + e; c = RL(c, 10);
-            e = RL(e + F2(a, b, c) + X[8] + unchecked((int)0x5a827999), 12) + d; b = RL(b, 10);
+            e = RL(e + F2(a, b, c) + this.X[7] + unchecked((int)0x5a827999), 7) + d; b = RL(b, 10);
+            d = RL(d + F2(e, a, b) + this.X[4] + unchecked((int)0x5a827999), 6) + c; a = RL(a, 10);
+            c = RL(c + F2(d, e, a) + this.X[13] + unchecked((int)0x5a827999), 8) + b; e = RL(e, 10);
+            b = RL(b + F2(c, d, e) + this.X[1] + unchecked((int)0x5a827999), 13) + a; d = RL(d, 10);
+            a = RL(a + F2(b, c, d) + this.X[10] + unchecked((int)0x5a827999), 11) + e; c = RL(c, 10);
+            e = RL(e + F2(a, b, c) + this.X[6] + unchecked((int)0x5a827999), 9) + d; b = RL(b, 10);
+            d = RL(d + F2(e, a, b) + this.X[15] + unchecked((int)0x5a827999), 7) + c; a = RL(a, 10);
+            c = RL(c + F2(d, e, a) + this.X[3] + unchecked((int)0x5a827999), 15) + b; e = RL(e, 10);
+            b = RL(b + F2(c, d, e) + this.X[12] + unchecked((int)0x5a827999), 7) + a; d = RL(d, 10);
+            a = RL(a + F2(b, c, d) + this.X[0] + unchecked((int)0x5a827999), 12) + e; c = RL(c, 10);
+            e = RL(e + F2(a, b, c) + this.X[9] + unchecked((int)0x5a827999), 15) + d; b = RL(b, 10);
+            d = RL(d + F2(e, a, b) + this.X[5] + unchecked((int)0x5a827999), 9) + c; a = RL(a, 10);
+            c = RL(c + F2(d, e, a) + this.X[2] + unchecked((int)0x5a827999), 11) + b; e = RL(e, 10);
+            b = RL(b + F2(c, d, e) + this.X[14] + unchecked((int)0x5a827999), 7) + a; d = RL(d, 10);
+            a = RL(a + F2(b, c, d) + this.X[11] + unchecked((int)0x5a827999), 13) + e; c = RL(c, 10);
+            e = RL(e + F2(a, b, c) + this.X[8] + unchecked((int)0x5a827999), 12) + d; b = RL(b, 10);
 
             // right
-            ee = RL(ee + F4(aa, bb, cc) + X[6] + unchecked((int)0x5c4dd124), 9) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F4(ee, aa, bb) + X[11] + unchecked((int)0x5c4dd124), 13) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F4(dd, ee, aa) + X[3] + unchecked((int)0x5c4dd124), 15) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F4(cc, dd, ee) + X[7] + unchecked((int)0x5c4dd124), 7) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F4(bb, cc, dd) + X[0] + unchecked((int)0x5c4dd124), 12) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F4(aa, bb, cc) + X[13] + unchecked((int)0x5c4dd124), 8) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F4(ee, aa, bb) + X[5] + unchecked((int)0x5c4dd124), 9) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F4(dd, ee, aa) + X[10] + unchecked((int)0x5c4dd124), 11) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F4(cc, dd, ee) + X[14] + unchecked((int)0x5c4dd124), 7) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F4(bb, cc, dd) + X[15] + unchecked((int)0x5c4dd124), 7) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F4(aa, bb, cc) + X[8] + unchecked((int)0x5c4dd124), 12) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F4(ee, aa, bb) + X[12] + unchecked((int)0x5c4dd124), 7) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F4(dd, ee, aa) + X[4] + unchecked((int)0x5c4dd124), 6) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F4(cc, dd, ee) + X[9] + unchecked((int)0x5c4dd124), 15) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F4(bb, cc, dd) + X[1] + unchecked((int)0x5c4dd124), 13) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F4(aa, bb, cc) + X[2] + unchecked((int)0x5c4dd124), 11) + dd; bb = RL(bb, 10);
+            ee = RL(ee + F4(aa, bb, cc) + this.X[6] + unchecked((int)0x5c4dd124), 9) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F4(ee, aa, bb) + this.X[11] + unchecked((int)0x5c4dd124), 13) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F4(dd, ee, aa) + this.X[3] + unchecked((int)0x5c4dd124), 15) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F4(cc, dd, ee) + this.X[7] + unchecked((int)0x5c4dd124), 7) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F4(bb, cc, dd) + this.X[0] + unchecked((int)0x5c4dd124), 12) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F4(aa, bb, cc) + this.X[13] + unchecked((int)0x5c4dd124), 8) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F4(ee, aa, bb) + this.X[5] + unchecked((int)0x5c4dd124), 9) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F4(dd, ee, aa) + this.X[10] + unchecked((int)0x5c4dd124), 11) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F4(cc, dd, ee) + this.X[14] + unchecked((int)0x5c4dd124), 7) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F4(bb, cc, dd) + this.X[15] + unchecked((int)0x5c4dd124), 7) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F4(aa, bb, cc) + this.X[8] + unchecked((int)0x5c4dd124), 12) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F4(ee, aa, bb) + this.X[12] + unchecked((int)0x5c4dd124), 7) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F4(dd, ee, aa) + this.X[4] + unchecked((int)0x5c4dd124), 6) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F4(cc, dd, ee) + this.X[9] + unchecked((int)0x5c4dd124), 15) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F4(bb, cc, dd) + this.X[1] + unchecked((int)0x5c4dd124), 13) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F4(aa, bb, cc) + this.X[2] + unchecked((int)0x5c4dd124), 11) + dd; bb = RL(bb, 10);
 
             //
             // Rounds 32-47
             //
             // left
-            d = RL(d + F3(e, a, b) + X[3] + unchecked((int)0x6ed9eba1), 11) + c; a = RL(a, 10);
-            c = RL(c + F3(d, e, a) + X[10] + unchecked((int)0x6ed9eba1), 13) + b; e = RL(e, 10);
-            b = RL(b + F3(c, d, e) + X[14] + unchecked((int)0x6ed9eba1), 6) + a; d = RL(d, 10);
-            a = RL(a + F3(b, c, d) + X[4] + unchecked((int)0x6ed9eba1), 7) + e; c = RL(c, 10);
-            e = RL(e + F3(a, b, c) + X[9] + unchecked((int)0x6ed9eba1), 14) + d; b = RL(b, 10);
-            d = RL(d + F3(e, a, b) + X[15] + unchecked((int)0x6ed9eba1), 9) + c; a = RL(a, 10);
-            c = RL(c + F3(d, e, a) + X[8] + unchecked((int)0x6ed9eba1), 13) + b; e = RL(e, 10);
-            b = RL(b + F3(c, d, e) + X[1] + unchecked((int)0x6ed9eba1), 15) + a; d = RL(d, 10);
-            a = RL(a + F3(b, c, d) + X[2] + unchecked((int)0x6ed9eba1), 14) + e; c = RL(c, 10);
-            e = RL(e + F3(a, b, c) + X[7] + unchecked((int)0x6ed9eba1), 8) + d; b = RL(b, 10);
-            d = RL(d + F3(e, a, b) + X[0] + unchecked((int)0x6ed9eba1), 13) + c; a = RL(a, 10);
-            c = RL(c + F3(d, e, a) + X[6] + unchecked((int)0x6ed9eba1), 6) + b; e = RL(e, 10);
-            b = RL(b + F3(c, d, e) + X[13] + unchecked((int)0x6ed9eba1), 5) + a; d = RL(d, 10);
-            a = RL(a + F3(b, c, d) + X[11] + unchecked((int)0x6ed9eba1), 12) + e; c = RL(c, 10);
-            e = RL(e + F3(a, b, c) + X[5] + unchecked((int)0x6ed9eba1), 7) + d; b = RL(b, 10);
-            d = RL(d + F3(e, a, b) + X[12] + unchecked((int)0x6ed9eba1), 5) + c; a = RL(a, 10);
+            d = RL(d + F3(e, a, b) + this.X[3] + unchecked((int)0x6ed9eba1), 11) + c; a = RL(a, 10);
+            c = RL(c + F3(d, e, a) + this.X[10] + unchecked((int)0x6ed9eba1), 13) + b; e = RL(e, 10);
+            b = RL(b + F3(c, d, e) + this.X[14] + unchecked((int)0x6ed9eba1), 6) + a; d = RL(d, 10);
+            a = RL(a + F3(b, c, d) + this.X[4] + unchecked((int)0x6ed9eba1), 7) + e; c = RL(c, 10);
+            e = RL(e + F3(a, b, c) + this.X[9] + unchecked((int)0x6ed9eba1), 14) + d; b = RL(b, 10);
+            d = RL(d + F3(e, a, b) + this.X[15] + unchecked((int)0x6ed9eba1), 9) + c; a = RL(a, 10);
+            c = RL(c + F3(d, e, a) + this.X[8] + unchecked((int)0x6ed9eba1), 13) + b; e = RL(e, 10);
+            b = RL(b + F3(c, d, e) + this.X[1] + unchecked((int)0x6ed9eba1), 15) + a; d = RL(d, 10);
+            a = RL(a + F3(b, c, d) + this.X[2] + unchecked((int)0x6ed9eba1), 14) + e; c = RL(c, 10);
+            e = RL(e + F3(a, b, c) + this.X[7] + unchecked((int)0x6ed9eba1), 8) + d; b = RL(b, 10);
+            d = RL(d + F3(e, a, b) + this.X[0] + unchecked((int)0x6ed9eba1), 13) + c; a = RL(a, 10);
+            c = RL(c + F3(d, e, a) + this.X[6] + unchecked((int)0x6ed9eba1), 6) + b; e = RL(e, 10);
+            b = RL(b + F3(c, d, e) + this.X[13] + unchecked((int)0x6ed9eba1), 5) + a; d = RL(d, 10);
+            a = RL(a + F3(b, c, d) + this.X[11] + unchecked((int)0x6ed9eba1), 12) + e; c = RL(c, 10);
+            e = RL(e + F3(a, b, c) + this.X[5] + unchecked((int)0x6ed9eba1), 7) + d; b = RL(b, 10);
+            d = RL(d + F3(e, a, b) + this.X[12] + unchecked((int)0x6ed9eba1), 5) + c; a = RL(a, 10);
 
             // right
-            dd = RL(dd + F3(ee, aa, bb) + X[15] + unchecked((int)0x6d703ef3), 9) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F3(dd, ee, aa) + X[5] + unchecked((int)0x6d703ef3), 7) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F3(cc, dd, ee) + X[1] + unchecked((int)0x6d703ef3), 15) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F3(bb, cc, dd) + X[3] + unchecked((int)0x6d703ef3), 11) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F3(aa, bb, cc) + X[7] + unchecked((int)0x6d703ef3), 8) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F3(ee, aa, bb) + X[14] + unchecked((int)0x6d703ef3), 6) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F3(dd, ee, aa) + X[6] + unchecked((int)0x6d703ef3), 6) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F3(cc, dd, ee) + X[9] + unchecked((int)0x6d703ef3), 14) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F3(bb, cc, dd) + X[11] + unchecked((int)0x6d703ef3), 12) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F3(aa, bb, cc) + X[8] + unchecked((int)0x6d703ef3), 13) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F3(ee, aa, bb) + X[12] + unchecked((int)0x6d703ef3), 5) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F3(dd, ee, aa) + X[2] + unchecked((int)0x6d703ef3), 14) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F3(cc, dd, ee) + X[10] + unchecked((int)0x6d703ef3), 13) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F3(bb, cc, dd) + X[0] + unchecked((int)0x6d703ef3), 13) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F3(aa, bb, cc) + X[4] + unchecked((int)0x6d703ef3), 7) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F3(ee, aa, bb) + X[13] + unchecked((int)0x6d703ef3), 5) + cc; aa = RL(aa, 10);
+            dd = RL(dd + F3(ee, aa, bb) + this.X[15] + unchecked((int)0x6d703ef3), 9) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F3(dd, ee, aa) + this.X[5] + unchecked((int)0x6d703ef3), 7) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F3(cc, dd, ee) + this.X[1] + unchecked((int)0x6d703ef3), 15) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F3(bb, cc, dd) + this.X[3] + unchecked((int)0x6d703ef3), 11) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F3(aa, bb, cc) + this.X[7] + unchecked((int)0x6d703ef3), 8) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F3(ee, aa, bb) + this.X[14] + unchecked((int)0x6d703ef3), 6) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F3(dd, ee, aa) + this.X[6] + unchecked((int)0x6d703ef3), 6) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F3(cc, dd, ee) + this.X[9] + unchecked((int)0x6d703ef3), 14) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F3(bb, cc, dd) + this.X[11] + unchecked((int)0x6d703ef3), 12) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F3(aa, bb, cc) + this.X[8] + unchecked((int)0x6d703ef3), 13) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F3(ee, aa, bb) + this.X[12] + unchecked((int)0x6d703ef3), 5) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F3(dd, ee, aa) + this.X[2] + unchecked((int)0x6d703ef3), 14) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F3(cc, dd, ee) + this.X[10] + unchecked((int)0x6d703ef3), 13) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F3(bb, cc, dd) + this.X[0] + unchecked((int)0x6d703ef3), 13) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F3(aa, bb, cc) + this.X[4] + unchecked((int)0x6d703ef3), 7) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F3(ee, aa, bb) + this.X[13] + unchecked((int)0x6d703ef3), 5) + cc; aa = RL(aa, 10);
 
             //
             // Rounds 48-63
             //
             // left
-            c = RL(c + F4(d, e, a) + X[1] + unchecked((int)0x8f1bbcdc), 11) + b; e = RL(e, 10);
-            b = RL(b + F4(c, d, e) + X[9] + unchecked((int)0x8f1bbcdc), 12) + a; d = RL(d, 10);
-            a = RL(a + F4(b, c, d) + X[11] + unchecked((int)0x8f1bbcdc), 14) + e; c = RL(c, 10);
-            e = RL(e + F4(a, b, c) + X[10] + unchecked((int)0x8f1bbcdc), 15) + d; b = RL(b, 10);
-            d = RL(d + F4(e, a, b) + X[0] + unchecked((int)0x8f1bbcdc), 14) + c; a = RL(a, 10);
-            c = RL(c + F4(d, e, a) + X[8] + unchecked((int)0x8f1bbcdc), 15) + b; e = RL(e, 10);
-            b = RL(b + F4(c, d, e) + X[12] + unchecked((int)0x8f1bbcdc), 9) + a; d = RL(d, 10);
-            a = RL(a + F4(b, c, d) + X[4] + unchecked((int)0x8f1bbcdc), 8) + e; c = RL(c, 10);
-            e = RL(e + F4(a, b, c) + X[13] + unchecked((int)0x8f1bbcdc), 9) + d; b = RL(b, 10);
-            d = RL(d + F4(e, a, b) + X[3] + unchecked((int)0x8f1bbcdc), 14) + c; a = RL(a, 10);
-            c = RL(c + F4(d, e, a) + X[7] + unchecked((int)0x8f1bbcdc), 5) + b; e = RL(e, 10);
-            b = RL(b + F4(c, d, e) + X[15] + unchecked((int)0x8f1bbcdc), 6) + a; d = RL(d, 10);
-            a = RL(a + F4(b, c, d) + X[14] + unchecked((int)0x8f1bbcdc), 8) + e; c = RL(c, 10);
-            e = RL(e + F4(a, b, c) + X[5] + unchecked((int)0x8f1bbcdc), 6) + d; b = RL(b, 10);
-            d = RL(d + F4(e, a, b) + X[6] + unchecked((int)0x8f1bbcdc), 5) + c; a = RL(a, 10);
-            c = RL(c + F4(d, e, a) + X[2] + unchecked((int)0x8f1bbcdc), 12) + b; e = RL(e, 10);
+            c = RL(c + F4(d, e, a) + this.X[1] + unchecked((int)0x8f1bbcdc), 11) + b; e = RL(e, 10);
+            b = RL(b + F4(c, d, e) + this.X[9] + unchecked((int)0x8f1bbcdc), 12) + a; d = RL(d, 10);
+            a = RL(a + F4(b, c, d) + this.X[11] + unchecked((int)0x8f1bbcdc), 14) + e; c = RL(c, 10);
+            e = RL(e + F4(a, b, c) + this.X[10] + unchecked((int)0x8f1bbcdc), 15) + d; b = RL(b, 10);
+            d = RL(d + F4(e, a, b) + this.X[0] + unchecked((int)0x8f1bbcdc), 14) + c; a = RL(a, 10);
+            c = RL(c + F4(d, e, a) + this.X[8] + unchecked((int)0x8f1bbcdc), 15) + b; e = RL(e, 10);
+            b = RL(b + F4(c, d, e) + this.X[12] + unchecked((int)0x8f1bbcdc), 9) + a; d = RL(d, 10);
+            a = RL(a + F4(b, c, d) + this.X[4] + unchecked((int)0x8f1bbcdc), 8) + e; c = RL(c, 10);
+            e = RL(e + F4(a, b, c) + this.X[13] + unchecked((int)0x8f1bbcdc), 9) + d; b = RL(b, 10);
+            d = RL(d + F4(e, a, b) + this.X[3] + unchecked((int)0x8f1bbcdc), 14) + c; a = RL(a, 10);
+            c = RL(c + F4(d, e, a) + this.X[7] + unchecked((int)0x8f1bbcdc), 5) + b; e = RL(e, 10);
+            b = RL(b + F4(c, d, e) + this.X[15] + unchecked((int)0x8f1bbcdc), 6) + a; d = RL(d, 10);
+            a = RL(a + F4(b, c, d) + this.X[14] + unchecked((int)0x8f1bbcdc), 8) + e; c = RL(c, 10);
+            e = RL(e + F4(a, b, c) + this.X[5] + unchecked((int)0x8f1bbcdc), 6) + d; b = RL(b, 10);
+            d = RL(d + F4(e, a, b) + this.X[6] + unchecked((int)0x8f1bbcdc), 5) + c; a = RL(a, 10);
+            c = RL(c + F4(d, e, a) + this.X[2] + unchecked((int)0x8f1bbcdc), 12) + b; e = RL(e, 10);
 
             // right
-            cc = RL(cc + F2(dd, ee, aa) + X[8] + unchecked((int)0x7a6d76e9), 15) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F2(cc, dd, ee) + X[6] + unchecked((int)0x7a6d76e9), 5) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F2(bb, cc, dd) + X[4] + unchecked((int)0x7a6d76e9), 8) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F2(aa, bb, cc) + X[1] + unchecked((int)0x7a6d76e9), 11) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F2(ee, aa, bb) + X[3] + unchecked((int)0x7a6d76e9), 14) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F2(dd, ee, aa) + X[11] + unchecked((int)0x7a6d76e9), 14) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F2(cc, dd, ee) + X[15] + unchecked((int)0x7a6d76e9), 6) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F2(bb, cc, dd) + X[0] + unchecked((int)0x7a6d76e9), 14) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F2(aa, bb, cc) + X[5] + unchecked((int)0x7a6d76e9), 6) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F2(ee, aa, bb) + X[12] + unchecked((int)0x7a6d76e9), 9) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F2(dd, ee, aa) + X[2] + unchecked((int)0x7a6d76e9), 12) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F2(cc, dd, ee) + X[13] + unchecked((int)0x7a6d76e9), 9) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F2(bb, cc, dd) + X[9] + unchecked((int)0x7a6d76e9), 12) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F2(aa, bb, cc) + X[7] + unchecked((int)0x7a6d76e9), 5) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F2(ee, aa, bb) + X[10] + unchecked((int)0x7a6d76e9), 15) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F2(dd, ee, aa) + X[14] + unchecked((int)0x7a6d76e9), 8) + bb; ee = RL(ee, 10);
+            cc = RL(cc + F2(dd, ee, aa) + this.X[8] + unchecked((int)0x7a6d76e9), 15) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F2(cc, dd, ee) + this.X[6] + unchecked((int)0x7a6d76e9), 5) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F2(bb, cc, dd) + this.X[4] + unchecked((int)0x7a6d76e9), 8) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F2(aa, bb, cc) + this.X[1] + unchecked((int)0x7a6d76e9), 11) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F2(ee, aa, bb) + this.X[3] + unchecked((int)0x7a6d76e9), 14) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F2(dd, ee, aa) + this.X[11] + unchecked((int)0x7a6d76e9), 14) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F2(cc, dd, ee) + this.X[15] + unchecked((int)0x7a6d76e9), 6) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F2(bb, cc, dd) + this.X[0] + unchecked((int)0x7a6d76e9), 14) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F2(aa, bb, cc) + this.X[5] + unchecked((int)0x7a6d76e9), 6) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F2(ee, aa, bb) + this.X[12] + unchecked((int)0x7a6d76e9), 9) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F2(dd, ee, aa) + this.X[2] + unchecked((int)0x7a6d76e9), 12) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F2(cc, dd, ee) + this.X[13] + unchecked((int)0x7a6d76e9), 9) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F2(bb, cc, dd) + this.X[9] + unchecked((int)0x7a6d76e9), 12) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F2(aa, bb, cc) + this.X[7] + unchecked((int)0x7a6d76e9), 5) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F2(ee, aa, bb) + this.X[10] + unchecked((int)0x7a6d76e9), 15) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F2(dd, ee, aa) + this.X[14] + unchecked((int)0x7a6d76e9), 8) + bb; ee = RL(ee, 10);
 
             //
             // Rounds 64-79
             //
             // left
-            b = RL(b + F5(c, d, e) + X[4] + unchecked((int)0xa953fd4e), 9) + a; d = RL(d, 10);
-            a = RL(a + F5(b, c, d) + X[0] + unchecked((int)0xa953fd4e), 15) + e; c = RL(c, 10);
-            e = RL(e + F5(a, b, c) + X[5] + unchecked((int)0xa953fd4e), 5) + d; b = RL(b, 10);
-            d = RL(d + F5(e, a, b) + X[9] + unchecked((int)0xa953fd4e), 11) + c; a = RL(a, 10);
-            c = RL(c + F5(d, e, a) + X[7] + unchecked((int)0xa953fd4e), 6) + b; e = RL(e, 10);
-            b = RL(b + F5(c, d, e) + X[12] + unchecked((int)0xa953fd4e), 8) + a; d = RL(d, 10);
-            a = RL(a + F5(b, c, d) + X[2] + unchecked((int)0xa953fd4e), 13) + e; c = RL(c, 10);
-            e = RL(e + F5(a, b, c) + X[10] + unchecked((int)0xa953fd4e), 12) + d; b = RL(b, 10);
-            d = RL(d + F5(e, a, b) + X[14] + unchecked((int)0xa953fd4e), 5) + c; a = RL(a, 10);
-            c = RL(c + F5(d, e, a) + X[1] + unchecked((int)0xa953fd4e), 12) + b; e = RL(e, 10);
-            b = RL(b + F5(c, d, e) + X[3] + unchecked((int)0xa953fd4e), 13) + a; d = RL(d, 10);
-            a = RL(a + F5(b, c, d) + X[8] + unchecked((int)0xa953fd4e), 14) + e; c = RL(c, 10);
-            e = RL(e + F5(a, b, c) + X[11] + unchecked((int)0xa953fd4e), 11) + d; b = RL(b, 10);
-            d = RL(d + F5(e, a, b) + X[6] + unchecked((int)0xa953fd4e), 8) + c; a = RL(a, 10);
-            c = RL(c + F5(d, e, a) + X[15] + unchecked((int)0xa953fd4e), 5) + b; e = RL(e, 10);
-            b = RL(b + F5(c, d, e) + X[13] + unchecked((int)0xa953fd4e), 6) + a; d = RL(d, 10);
+            b = RL(b + F5(c, d, e) + this.X[4] + unchecked((int)0xa953fd4e), 9) + a; d = RL(d, 10);
+            a = RL(a + F5(b, c, d) + this.X[0] + unchecked((int)0xa953fd4e), 15) + e; c = RL(c, 10);
+            e = RL(e + F5(a, b, c) + this.X[5] + unchecked((int)0xa953fd4e), 5) + d; b = RL(b, 10);
+            d = RL(d + F5(e, a, b) + this.X[9] + unchecked((int)0xa953fd4e), 11) + c; a = RL(a, 10);
+            c = RL(c + F5(d, e, a) + this.X[7] + unchecked((int)0xa953fd4e), 6) + b; e = RL(e, 10);
+            b = RL(b + F5(c, d, e) + this.X[12] + unchecked((int)0xa953fd4e), 8) + a; d = RL(d, 10);
+            a = RL(a + F5(b, c, d) + this.X[2] + unchecked((int)0xa953fd4e), 13) + e; c = RL(c, 10);
+            e = RL(e + F5(a, b, c) + this.X[10] + unchecked((int)0xa953fd4e), 12) + d; b = RL(b, 10);
+            d = RL(d + F5(e, a, b) + this.X[14] + unchecked((int)0xa953fd4e), 5) + c; a = RL(a, 10);
+            c = RL(c + F5(d, e, a) + this.X[1] + unchecked((int)0xa953fd4e), 12) + b; e = RL(e, 10);
+            b = RL(b + F5(c, d, e) + this.X[3] + unchecked((int)0xa953fd4e), 13) + a; d = RL(d, 10);
+            a = RL(a + F5(b, c, d) + this.X[8] + unchecked((int)0xa953fd4e), 14) + e; c = RL(c, 10);
+            e = RL(e + F5(a, b, c) + this.X[11] + unchecked((int)0xa953fd4e), 11) + d; b = RL(b, 10);
+            d = RL(d + F5(e, a, b) + this.X[6] + unchecked((int)0xa953fd4e), 8) + c; a = RL(a, 10);
+            c = RL(c + F5(d, e, a) + this.X[15] + unchecked((int)0xa953fd4e), 5) + b; e = RL(e, 10);
+            b = RL(b + F5(c, d, e) + this.X[13] + unchecked((int)0xa953fd4e), 6) + a; d = RL(d, 10);
 
             // right
-            bb = RL(bb + F1(cc, dd, ee) + X[12], 8) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F1(bb, cc, dd) + X[15], 5) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F1(aa, bb, cc) + X[10], 12) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F1(ee, aa, bb) + X[4], 9) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F1(dd, ee, aa) + X[1], 12) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F1(cc, dd, ee) + X[5], 5) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F1(bb, cc, dd) + X[8], 14) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F1(aa, bb, cc) + X[7], 6) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F1(ee, aa, bb) + X[6], 8) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F1(dd, ee, aa) + X[2], 13) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F1(cc, dd, ee) + X[13], 6) + aa; dd = RL(dd, 10);
-            aa = RL(aa + F1(bb, cc, dd) + X[14], 5) + ee; cc = RL(cc, 10);
-            ee = RL(ee + F1(aa, bb, cc) + X[0], 15) + dd; bb = RL(bb, 10);
-            dd = RL(dd + F1(ee, aa, bb) + X[3], 13) + cc; aa = RL(aa, 10);
-            cc = RL(cc + F1(dd, ee, aa) + X[9], 11) + bb; ee = RL(ee, 10);
-            bb = RL(bb + F1(cc, dd, ee) + X[11], 11) + aa; dd = RL(dd, 10);
+            bb = RL(bb + F1(cc, dd, ee) + this.X[12], 8) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F1(bb, cc, dd) + this.X[15], 5) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F1(aa, bb, cc) + this.X[10], 12) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F1(ee, aa, bb) + this.X[4], 9) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F1(dd, ee, aa) + this.X[1], 12) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F1(cc, dd, ee) + this.X[5], 5) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F1(bb, cc, dd) + this.X[8], 14) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F1(aa, bb, cc) + this.X[7], 6) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F1(ee, aa, bb) + this.X[6], 8) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F1(dd, ee, aa) + this.X[2], 13) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F1(cc, dd, ee) + this.X[13], 6) + aa; dd = RL(dd, 10);
+            aa = RL(aa + F1(bb, cc, dd) + this.X[14], 5) + ee; cc = RL(cc, 10);
+            ee = RL(ee + F1(aa, bb, cc) + this.X[0], 15) + dd; bb = RL(bb, 10);
+            dd = RL(dd + F1(ee, aa, bb) + this.X[3], 13) + cc; aa = RL(aa, 10);
+            cc = RL(cc + F1(dd, ee, aa) + this.X[9], 11) + bb; ee = RL(ee, 10);
+            bb = RL(bb + F1(cc, dd, ee) + this.X[11], 11) + aa; dd = RL(dd, 10);
 
             dd += c + H1;
             H1 = H2 + d + ee;
@@ -503,10 +512,10 @@ namespace Renci.SshNet.Security.Cryptography
             //
             // reset the offset and clean out the word buffer.
             //
-            _offset = 0;
-            for (int i = 0; i != X.Length; i++)
+            this._offset = 0;
+            for (int i = 0; i < X.Length; i++)
             {
-                X[i] = 0;
+                this.X[i] = 0;
             }
         }
     }

+ 264 - 77
Renci.SshClient/Renci.SshNet/Security/Cryptography/Hashes/SHA1Hash.cs

@@ -6,7 +6,7 @@ namespace Renci.SshNet.Security.Cryptography
 	/// <summary>
 	/// SHA1 algorithm implementation
 	/// </summary>
-	public class SHA1Hash : HashAlgorithm
+	public sealed class SHA1Hash : HashAlgorithm
 	{
 		private const int DIGEST_SIZE = 20;
 
@@ -159,17 +159,17 @@ namespace Renci.SshNet.Security.Cryptography
 				this.ProcessBlock();
 			}
 
-			_hashValue[14] = (uint)((ulong)bitLength >> 32);
-			_hashValue[15] = (uint)((ulong)bitLength);
+			this._hashValue[14] = (uint)((ulong)bitLength >> 32);
+            this._hashValue[15] = (uint)((ulong)bitLength);
 
 
 			this.ProcessBlock();
 
-			UInt32_To__BE(H1, output, 0);
-			UInt32_To__BE(H2, output, 0 + 4);
-			UInt32_To__BE(H3, output, 0 + 8);
-			UInt32_To__BE(H4, output, 0 + 12);
-			UInt32_To__BE(H5, output, 0 + 16);
+            UInt32ToBigEndian(H1, output, 0);
+            UInt32ToBigEndian(H2, output, 4);
+            UInt32ToBigEndian(H3, output, 8);
+            UInt32ToBigEndian(H4, output, 12);
+            UInt32ToBigEndian(H5, output, 16);
 
             this.Initialize();
 
@@ -186,9 +186,13 @@ namespace Renci.SshNet.Security.Cryptography
 
         private void InternalInitialize()
         {
+            var i = 0;
             this._byteCount = 0;
             this._bufferOffset = 0;
-            Array.Clear(this._buffer, 0, this._buffer.Length);
+            for (i = 0; i < 4; i++)
+            {
+                this._buffer[i] = 0;
+            }
 
             H1 = 0x67452301;
             H2 = 0xefcdab89;
@@ -197,7 +201,10 @@ namespace Renci.SshNet.Security.Cryptography
             H5 = 0xc3d2e1f0;
 
             this._offset = 0;
-            Array.Clear(_hashValue, 0, _hashValue.Length);
+            for (i = 0; i != this._hashValue.Length; i++)
+            {
+                this._hashValue[i] = 0;
+            }
         }
 
 		private void Update(byte input)
@@ -215,7 +222,7 @@ namespace Renci.SshNet.Security.Cryptography
 
 		private void ProcessWord(byte[] input, int inOff)
 		{
-			_hashValue[this._offset] = BE_To__UInt32(input, inOff);
+            this._hashValue[this._offset] = BigEndianToUInt32(input, inOff);
 
 			if (++this._offset == 16)
 			{
@@ -263,94 +270,272 @@ namespace Renci.SshNet.Security.Cryptography
 			//
 			int idx = 0;
 
-			for (int j = 0; j < 4; j++)
-			{
-				// E = rotateLeft(A, 5) + F(B, C, D) + E + X[idx++] + Y1
-				// B = rotateLeft(B, 30)
-				E += (A << 5 | (A >> 27)) + F(B, C, D) + _hashValue[idx++] + Y1;
-				B = B << 30 | (B >> 2);
+            // E = rotateLeft(A, 5) + F(B, C, D) + E + X[idx++] + Y1
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + F(B, C, D) + _hashValue[idx++] + Y1;
+            B = B << 30 | (B >> 2);
 
-				D += (E << 5 | (E >> 27)) + F(A, B, C) + _hashValue[idx++] + Y1;
-				A = A << 30 | (A >> 2);
+            D += (E << 5 | (E >> 27)) + F(A, B, C) + _hashValue[idx++] + Y1;
+            A = A << 30 | (A >> 2);
 
-				C += (D << 5 | (D >> 27)) + F(E, A, B) + _hashValue[idx++] + Y1;
-				E = E << 30 | (E >> 2);
+            C += (D << 5 | (D >> 27)) + F(E, A, B) + _hashValue[idx++] + Y1;
+            E = E << 30 | (E >> 2);
 
-				B += (C << 5 | (C >> 27)) + F(D, E, A) + _hashValue[idx++] + Y1;
-				D = D << 30 | (D >> 2);
+            B += (C << 5 | (C >> 27)) + F(D, E, A) + _hashValue[idx++] + Y1;
+            D = D << 30 | (D >> 2);
 
-				A += (B << 5 | (B >> 27)) + F(C, D, E) + _hashValue[idx++] + Y1;
-				C = C << 30 | (C >> 2);
-			}
+            A += (B << 5 | (B >> 27)) + F(C, D, E) + _hashValue[idx++] + Y1;
+            C = C << 30 | (C >> 2);
+            // E = rotateLeft(A, 5) + F(B, C, D) + E + X[idx++] + Y1
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + F(B, C, D) + _hashValue[idx++] + Y1;
+            B = B << 30 | (B >> 2);
+
+            D += (E << 5 | (E >> 27)) + F(A, B, C) + _hashValue[idx++] + Y1;
+            A = A << 30 | (A >> 2);
+
+            C += (D << 5 | (D >> 27)) + F(E, A, B) + _hashValue[idx++] + Y1;
+            E = E << 30 | (E >> 2);
+
+            B += (C << 5 | (C >> 27)) + F(D, E, A) + _hashValue[idx++] + Y1;
+            D = D << 30 | (D >> 2);
+
+            A += (B << 5 | (B >> 27)) + F(C, D, E) + _hashValue[idx++] + Y1;
+            C = C << 30 | (C >> 2);
+            // E = rotateLeft(A, 5) + F(B, C, D) + E + X[idx++] + Y1
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + F(B, C, D) + _hashValue[idx++] + Y1;
+            B = B << 30 | (B >> 2);
+
+            D += (E << 5 | (E >> 27)) + F(A, B, C) + _hashValue[idx++] + Y1;
+            A = A << 30 | (A >> 2);
+
+            C += (D << 5 | (D >> 27)) + F(E, A, B) + _hashValue[idx++] + Y1;
+            E = E << 30 | (E >> 2);
 
+            B += (C << 5 | (C >> 27)) + F(D, E, A) + _hashValue[idx++] + Y1;
+            D = D << 30 | (D >> 2);
+
+            A += (B << 5 | (B >> 27)) + F(C, D, E) + _hashValue[idx++] + Y1;
+            C = C << 30 | (C >> 2);
+            // E = rotateLeft(A, 5) + F(B, C, D) + E + X[idx++] + Y1
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + F(B, C, D) + _hashValue[idx++] + Y1;
+            B = B << 30 | (B >> 2);
+
+            D += (E << 5 | (E >> 27)) + F(A, B, C) + _hashValue[idx++] + Y1;
+            A = A << 30 | (A >> 2);
+
+            C += (D << 5 | (D >> 27)) + F(E, A, B) + _hashValue[idx++] + Y1;
+            E = E << 30 | (E >> 2);
+
+            B += (C << 5 | (C >> 27)) + F(D, E, A) + _hashValue[idx++] + Y1;
+            D = D << 30 | (D >> 2);
+
+            A += (B << 5 | (B >> 27)) + F(C, D, E) + _hashValue[idx++] + Y1;
+            C = C << 30 | (C >> 2);
 			//
 			// round 2
 			//
-			for (int j = 0; j < 4; j++)
-			{
-				// E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y2
-				// B = rotateLeft(B, 30)
-				E += (A << 5 | (A >> 27)) + H(B, C, D) + _hashValue[idx++] + Y2;
-				B = B << 30 | (B >> 2);
+            // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y2
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + H(B, C, D) + _hashValue[idx++] + Y2;
+            B = B << 30 | (B >> 2);
 
-				D += (E << 5 | (E >> 27)) + H(A, B, C) + _hashValue[idx++] + Y2;
-				A = A << 30 | (A >> 2);
+            D += (E << 5 | (E >> 27)) + H(A, B, C) + _hashValue[idx++] + Y2;
+            A = A << 30 | (A >> 2);
 
-				C += (D << 5 | (D >> 27)) + H(E, A, B) + _hashValue[idx++] + Y2;
-				E = E << 30 | (E >> 2);
+            C += (D << 5 | (D >> 27)) + H(E, A, B) + _hashValue[idx++] + Y2;
+            E = E << 30 | (E >> 2);
 
-				B += (C << 5 | (C >> 27)) + H(D, E, A) + _hashValue[idx++] + Y2;
-				D = D << 30 | (D >> 2);
+            B += (C << 5 | (C >> 27)) + H(D, E, A) + _hashValue[idx++] + Y2;
+            D = D << 30 | (D >> 2);
 
-				A += (B << 5 | (B >> 27)) + H(C, D, E) + _hashValue[idx++] + Y2;
-				C = C << 30 | (C >> 2);
-			}
+            A += (B << 5 | (B >> 27)) + H(C, D, E) + _hashValue[idx++] + Y2;
+            C = C << 30 | (C >> 2);
+            // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y2
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + H(B, C, D) + _hashValue[idx++] + Y2;
+            B = B << 30 | (B >> 2);
+
+            D += (E << 5 | (E >> 27)) + H(A, B, C) + _hashValue[idx++] + Y2;
+            A = A << 30 | (A >> 2);
+
+            C += (D << 5 | (D >> 27)) + H(E, A, B) + _hashValue[idx++] + Y2;
+            E = E << 30 | (E >> 2);
+
+            B += (C << 5 | (C >> 27)) + H(D, E, A) + _hashValue[idx++] + Y2;
+            D = D << 30 | (D >> 2);
+
+            A += (B << 5 | (B >> 27)) + H(C, D, E) + _hashValue[idx++] + Y2;
+            C = C << 30 | (C >> 2);
+            // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y2
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + H(B, C, D) + _hashValue[idx++] + Y2;
+            B = B << 30 | (B >> 2);
+
+            D += (E << 5 | (E >> 27)) + H(A, B, C) + _hashValue[idx++] + Y2;
+            A = A << 30 | (A >> 2);
+
+            C += (D << 5 | (D >> 27)) + H(E, A, B) + _hashValue[idx++] + Y2;
+            E = E << 30 | (E >> 2);
+
+            B += (C << 5 | (C >> 27)) + H(D, E, A) + _hashValue[idx++] + Y2;
+            D = D << 30 | (D >> 2);
+
+            A += (B << 5 | (B >> 27)) + H(C, D, E) + _hashValue[idx++] + Y2;
+            C = C << 30 | (C >> 2);
+            // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y2
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + H(B, C, D) + _hashValue[idx++] + Y2;
+            B = B << 30 | (B >> 2);
+
+            D += (E << 5 | (E >> 27)) + H(A, B, C) + _hashValue[idx++] + Y2;
+            A = A << 30 | (A >> 2);
+
+            C += (D << 5 | (D >> 27)) + H(E, A, B) + _hashValue[idx++] + Y2;
+            E = E << 30 | (E >> 2);
+
+            B += (C << 5 | (C >> 27)) + H(D, E, A) + _hashValue[idx++] + Y2;
+            D = D << 30 | (D >> 2);
+
+            A += (B << 5 | (B >> 27)) + H(C, D, E) + _hashValue[idx++] + Y2;
+            C = C << 30 | (C >> 2);
 
 			//
 			// round 3
-			//
-			for (int j = 0; j < 4; j++)
-			{
-				// E = rotateLeft(A, 5) + G(B, C, D) + E + X[idx++] + Y3
-				// B = rotateLeft(B, 30)
-				E += (A << 5 | (A >> 27)) + G(B, C, D) + _hashValue[idx++] + Y3;
-				B = B << 30 | (B >> 2);
+            // E = rotateLeft(A, 5) + G(B, C, D) + E + X[idx++] + Y3
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + G(B, C, D) + _hashValue[idx++] + Y3;
+            B = B << 30 | (B >> 2);
 
-				D += (E << 5 | (E >> 27)) + G(A, B, C) + _hashValue[idx++] + Y3;
-				A = A << 30 | (A >> 2);
+            D += (E << 5 | (E >> 27)) + G(A, B, C) + _hashValue[idx++] + Y3;
+            A = A << 30 | (A >> 2);
 
-				C += (D << 5 | (D >> 27)) + G(E, A, B) + _hashValue[idx++] + Y3;
-				E = E << 30 | (E >> 2);
+            C += (D << 5 | (D >> 27)) + G(E, A, B) + _hashValue[idx++] + Y3;
+            E = E << 30 | (E >> 2);
 
-				B += (C << 5 | (C >> 27)) + G(D, E, A) + _hashValue[idx++] + Y3;
-				D = D << 30 | (D >> 2);
+            B += (C << 5 | (C >> 27)) + G(D, E, A) + _hashValue[idx++] + Y3;
+            D = D << 30 | (D >> 2);
 
-				A += (B << 5 | (B >> 27)) + G(C, D, E) + _hashValue[idx++] + Y3;
-				C = C << 30 | (C >> 2);
-			}
+            A += (B << 5 | (B >> 27)) + G(C, D, E) + _hashValue[idx++] + Y3;
+            C = C << 30 | (C >> 2);
+            // E = rotateLeft(A, 5) + G(B, C, D) + E + X[idx++] + Y3
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + G(B, C, D) + _hashValue[idx++] + Y3;
+            B = B << 30 | (B >> 2);
 
-			//
+            D += (E << 5 | (E >> 27)) + G(A, B, C) + _hashValue[idx++] + Y3;
+            A = A << 30 | (A >> 2);
+
+            C += (D << 5 | (D >> 27)) + G(E, A, B) + _hashValue[idx++] + Y3;
+            E = E << 30 | (E >> 2);
+
+            B += (C << 5 | (C >> 27)) + G(D, E, A) + _hashValue[idx++] + Y3;
+            D = D << 30 | (D >> 2);
+
+            A += (B << 5 | (B >> 27)) + G(C, D, E) + _hashValue[idx++] + Y3;
+            C = C << 30 | (C >> 2);
+            // E = rotateLeft(A, 5) + G(B, C, D) + E + X[idx++] + Y3
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + G(B, C, D) + _hashValue[idx++] + Y3;
+            B = B << 30 | (B >> 2);
+
+            D += (E << 5 | (E >> 27)) + G(A, B, C) + _hashValue[idx++] + Y3;
+            A = A << 30 | (A >> 2);
+
+            C += (D << 5 | (D >> 27)) + G(E, A, B) + _hashValue[idx++] + Y3;
+            E = E << 30 | (E >> 2);
+
+            B += (C << 5 | (C >> 27)) + G(D, E, A) + _hashValue[idx++] + Y3;
+            D = D << 30 | (D >> 2);
+
+            A += (B << 5 | (B >> 27)) + G(C, D, E) + _hashValue[idx++] + Y3;
+            C = C << 30 | (C >> 2);
+            // E = rotateLeft(A, 5) + G(B, C, D) + E + X[idx++] + Y3
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + G(B, C, D) + _hashValue[idx++] + Y3;
+            B = B << 30 | (B >> 2);
+
+            D += (E << 5 | (E >> 27)) + G(A, B, C) + _hashValue[idx++] + Y3;
+            A = A << 30 | (A >> 2);
+
+            C += (D << 5 | (D >> 27)) + G(E, A, B) + _hashValue[idx++] + Y3;
+            E = E << 30 | (E >> 2);
+
+            B += (C << 5 | (C >> 27)) + G(D, E, A) + _hashValue[idx++] + Y3;
+            D = D << 30 | (D >> 2);
+
+            A += (B << 5 | (B >> 27)) + G(C, D, E) + _hashValue[idx++] + Y3;
+            C = C << 30 | (C >> 2);
+
+            //
 			// round 4
 			//
-			for (int j = 0; j < 4; j++)
-			{
-				// E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y4
-				// B = rotateLeft(B, 30)
-				E += (A << 5 | (A >> 27)) + H(B, C, D) + _hashValue[idx++] + Y4;
-				B = B << 30 | (B >> 2);
+            // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y4
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + H(B, C, D) + _hashValue[idx++] + Y4;
+            B = B << 30 | (B >> 2);
 
-				D += (E << 5 | (E >> 27)) + H(A, B, C) + _hashValue[idx++] + Y4;
-				A = A << 30 | (A >> 2);
+            D += (E << 5 | (E >> 27)) + H(A, B, C) + _hashValue[idx++] + Y4;
+            A = A << 30 | (A >> 2);
 
-				C += (D << 5 | (D >> 27)) + H(E, A, B) + _hashValue[idx++] + Y4;
-				E = E << 30 | (E >> 2);
+            C += (D << 5 | (D >> 27)) + H(E, A, B) + _hashValue[idx++] + Y4;
+            E = E << 30 | (E >> 2);
 
-				B += (C << 5 | (C >> 27)) + H(D, E, A) + _hashValue[idx++] + Y4;
-				D = D << 30 | (D >> 2);
+            B += (C << 5 | (C >> 27)) + H(D, E, A) + _hashValue[idx++] + Y4;
+            D = D << 30 | (D >> 2);
 
-				A += (B << 5 | (B >> 27)) + H(C, D, E) + _hashValue[idx++] + Y4;
-				C = C << 30 | (C >> 2);
-			}
+            A += (B << 5 | (B >> 27)) + H(C, D, E) + _hashValue[idx++] + Y4;
+            C = C << 30 | (C >> 2);
+            // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y4
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + H(B, C, D) + _hashValue[idx++] + Y4;
+            B = B << 30 | (B >> 2);
+
+            D += (E << 5 | (E >> 27)) + H(A, B, C) + _hashValue[idx++] + Y4;
+            A = A << 30 | (A >> 2);
+
+            C += (D << 5 | (D >> 27)) + H(E, A, B) + _hashValue[idx++] + Y4;
+            E = E << 30 | (E >> 2);
+
+            B += (C << 5 | (C >> 27)) + H(D, E, A) + _hashValue[idx++] + Y4;
+            D = D << 30 | (D >> 2);
+
+            A += (B << 5 | (B >> 27)) + H(C, D, E) + _hashValue[idx++] + Y4;
+            C = C << 30 | (C >> 2);
+            // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y4
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + H(B, C, D) + _hashValue[idx++] + Y4;
+            B = B << 30 | (B >> 2);
+
+            D += (E << 5 | (E >> 27)) + H(A, B, C) + _hashValue[idx++] + Y4;
+            A = A << 30 | (A >> 2);
+
+            C += (D << 5 | (D >> 27)) + H(E, A, B) + _hashValue[idx++] + Y4;
+            E = E << 30 | (E >> 2);
+
+            B += (C << 5 | (C >> 27)) + H(D, E, A) + _hashValue[idx++] + Y4;
+            D = D << 30 | (D >> 2);
+
+            A += (B << 5 | (B >> 27)) + H(C, D, E) + _hashValue[idx++] + Y4;
+            C = C << 30 | (C >> 2);
+            // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y4
+            // B = rotateLeft(B, 30)
+            E += (A << 5 | (A >> 27)) + H(B, C, D) + _hashValue[idx++] + Y4;
+            B = B << 30 | (B >> 2);
+
+            D += (E << 5 | (E >> 27)) + H(A, B, C) + _hashValue[idx++] + Y4;
+            A = A << 30 | (A >> 2);
+
+            C += (D << 5 | (D >> 27)) + H(E, A, B) + _hashValue[idx++] + Y4;
+            E = E << 30 | (E >> 2);
+
+            B += (C << 5 | (C >> 27)) + H(D, E, A) + _hashValue[idx++] + Y4;
+            D = D << 30 | (D >> 2);
+
+            A += (B << 5 | (B >> 27)) + H(C, D, E) + _hashValue[idx++] + Y4;
+            C = C << 30 | (C >> 2);
 
 			H1 += A;
 			H2 += B;
@@ -362,10 +547,13 @@ namespace Renci.SshNet.Security.Cryptography
 			// reset start of the buffer.
 			//
 			this._offset = 0;
-			Array.Clear(_hashValue, 0, 16);
+            for (int i = 0; i < this._hashValue.Length; i++)
+            {
+                this._hashValue[i] = 0;
+            }
 		}
 
-		private static uint BE_To__UInt32(byte[] bs, int off)
+        private static uint BigEndianToUInt32(byte[] bs, int off)
 		{
 			uint n = (uint)bs[off] << 24;
 			n |= (uint)bs[++off] << 16;
@@ -374,8 +562,7 @@ namespace Renci.SshNet.Security.Cryptography
 			return n;
 		}
 
-		private static void UInt32_To__BE
-			(uint n, byte[] bs, int off)
+        private static void UInt32ToBigEndian(uint n, byte[] bs, int off)
 		{
 			bs[off] = (byte)(n >> 24);
 			bs[++off] = (byte)(n >> 16);

+ 15 - 8
Renci.SshClient/Renci.SshNet/Security/Cryptography/Hashes/SHA256Hash.cs

@@ -186,7 +186,10 @@ namespace Renci.SshNet.Security.Cryptography
         {
             this._byteCount = 0;
             this._bufferOffset = 0;
-            Array.Clear(this._buffer, 0, this._buffer.Length);
+            for (int i = 0; i < this._buffer.Length; i++)
+            {
+                this._buffer[i] = 0;
+            }
 
             H1 = 0x6a09e667;
             H2 = 0xbb67ae85;
@@ -198,7 +201,10 @@ namespace Renci.SshNet.Security.Cryptography
             H8 = 0x5be0cd19;
 
             this._offset = 0;
-            Array.Clear(X, 0, X.Length);
+            for (int i = 0; i < this.X.Length; i++)
+            {
+                this.X[i] = 0;
+            }
         }
 
 		private void Update(byte input)
@@ -339,7 +345,10 @@ namespace Renci.SshNet.Security.Cryptography
 			// reset the offset and clean out the word buffer.
 			//
 			this._offset = 0;
-			Array.Clear(X, 0, 16);
+            for (int i = 0; i < this.X.Length; i++)
+            {
+                this.X[i] = 0;
+            }
 		}
 
 		private static uint Sum1Ch(uint x, uint y, uint z)
@@ -366,10 +375,9 @@ namespace Renci.SshNet.Security.Cryptography
 			return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10);
 		}
 
-		/* SHA-256 Constants
-		* (represent the first 32 bits of the fractional parts of the
-		* cube roots of the first sixty-four prime numbers)
-		*/
+        /// <summary>
+        /// The SHA-256 Constants (represent the first 32 bits of the fractional parts of the cube roots of the first sixty-four prime numbers)
+        /// </summary>
 		private static readonly uint[] K = {
 			0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
 			0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
@@ -388,6 +396,5 @@ namespace Renci.SshNet.Security.Cryptography
 			0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
 			0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
 		};
-
 	}
 }

+ 8 - 2
Renci.SshClient/Renci.SshNet/Security/Cryptography/Hashes/SHA2HashBase.cs

@@ -102,7 +102,10 @@ namespace Renci.SshNet.Security.Cryptography
             }
 
             this._offset = 0;
-            Array.Clear(X, 0, X.Length);
+            for (int i = 0; i < this.X.Length; i++)
+            {
+                this.X[i] = 0;
+            }
         }
 
         protected void Finish()
@@ -242,7 +245,10 @@ namespace Renci.SshNet.Security.Cryptography
             // reset the offset and clean out the word buffer.
             //
             this._offset = 0;
-            Array.Clear(X, 0, 16);
+            for (int i = 0; i < this.X.Length; i++)
+            {
+                this.X[i] = 0;
+            }
         }
 
         /// <summary>